From: Manoj Kumar Date: Fri, 21 Jun 2019 16:07:13 +0000 (+0100) Subject: n1sdp: add code for DDR ECC enablement and BL33 copy to DDR X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=de8bc83ee9401acdab20fd8ae1f9cb9bf7ef7829;p=project%2Fbcm63xx%2Fatf.git n1sdp: add code for DDR ECC enablement and BL33 copy to DDR N1SDP platform supports RDIMMs with ECC capability. To use the ECC capability, the entire DDR memory space has to be zeroed out before enabling the ECC bits in DMC620. Zeroing out several gigabytes of memory from SCP is quite time consuming so functions are added that zeros out the DDR memory from application processor which is much faster compared to SCP. BL33 binary cannot be copied to DDR memory before enabling ECC so this is also done by TF-A from IOFPGA-DDR3 memory to main DDR4 memory after ECC is enabled. Original PLAT_PHY_ADDR_SPACE_SIZE was limited to 36-bits with which the entire DDR space cannot be accessed as DRAM2 starts in base 0x8080000000. So these macros are redefined for all ARM platforms. Change-Id: If09524fb65b421b7a368b1b9fc52c49f2ddb7846 Signed-off-by: Manoj Kumar --- diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 69a9959a..ead1a8b3 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -311,19 +311,6 @@ * Required platform porting definitions common to all ARM standard platforms *****************************************************************************/ -/* - * We need to access DRAM2 from BL2 for PSCI_MEM_PROTECT for - * AArch64 builds - */ -#ifdef AARCH64 -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) -#else -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) -#endif - - /* * This macro defines the deepest retention state possible. A higher state * id will represent an invalid or a power down state. diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 2313ab0c..207cd31d 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -256,4 +256,15 @@ #define PLAT_SP_PRI PLAT_RAS_PRI +/* + * 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) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h index 1b21c79d..b3b36726 100644 --- a/plat/arm/board/fvp_ve/include/platform_def.h +++ b/plat/arm/board/fvp_ve/include/platform_def.h @@ -328,4 +328,15 @@ #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) +/* + * 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) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + #endif /* PLATFORM_H */ diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index e096e33e..d693c26a 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -288,4 +288,15 @@ /* System power domain level */ #define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +/* + * 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) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index 0964f568..ff583a90 100644 --- a/plat/arm/board/n1sdp/include/platform_def.h +++ b/plat/arm/board/n1sdp/include/platform_def.h @@ -25,7 +25,22 @@ #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(0x780000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0xF80000000) + +/* + * N1SDP platform supports RDIMMs with ECC capability. To use the ECC + * capability, the entire DDR memory space has to be zeroed out before + * enabling the ECC bits in DMC620. The access the complete DDR memory + * space the physical & virtual address space limits are extended to + * 40-bits. + */ +#ifndef AARCH32 +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 40) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 40) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif #if CSS_USE_SCMI_SDS_DRIVER #define N1SDP_SCMI_PAYLOAD_BASE 0x45400000 @@ -55,8 +70,8 @@ * 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 3 -#define MAX_XLAT_TABLES 4 +#define PLAT_ARM_MMAP_ENTRIES 6 +#define MAX_XLAT_TABLES 7 #define PLATFORM_STACK_SIZE 0x400 @@ -73,13 +88,18 @@ #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) -#define N1SDP_DEVICE_BASE (0x20000000) -#define N1SDP_DEVICE_SIZE (0x30000000) +#define N1SDP_DEVICE_BASE (0x08000000) +#define N1SDP_DEVICE_SIZE (0x48000000) #define N1SDP_MAP_DEVICE MAP_REGION_FLAT( \ N1SDP_DEVICE_BASE, \ N1SDP_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 0x30000000 #define PLAT_ARM_GICC_BASE 0x2C000000 diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index 18a0deab..a831b89f 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -8,8 +8,35 @@ #include #include +#include +#include +#include +#include #include +#include "n1sdp_def.h" + +/* + * Memory information structure stored in SDS. + * This structure holds the total DDR memory size which will be + * used when zeroing out the entire DDR memory before enabling + * the ECC capability in DMCs. + */ +struct n1sdp_mem_info { + uint32_t ddr_size_gb; +}; + +/* + * 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 n1sdp_bl33_info { + uint32_t bl33_src_addr; + uint32_t bl33_dst_addr; + uint32_t bl33_size; +}; + static scmi_channel_plat_info_t n1sdp_scmi_plat_info = { .scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE, .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, @@ -27,3 +54,95 @@ const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { return css_scmi_override_pm_ops(ops); } + +/* + * N1SDP platform supports RDIMMs with ECC capability. To use the ECC + * capability, the entire DDR memory space has to be zeroed out before + * enabling the ECC bits in DMC620. Zeroing out several gigabytes of + * memory from SCP is quite time consuming so the following function + * is added to zero out the DDR memory from application processor which is + * much faster compared to SCP. BL33 binary cannot be copied to DDR memory + * before enabling ECC so copy_bl33 function is added to copy BL33 binary + * from IOFPGA-DDR3 memory to main DDR4 memory. + */ + +void dmc_ecc_setup(uint32_t ddr_size_gb) +{ + uint64_t dram2_size; + + dram2_size = (ddr_size_gb * 1024UL * 1024UL * 1024UL) - + ARM_DRAM1_SIZE; + + INFO("Zeroing DDR memories\n"); + zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE); + flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE); + zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size); + flush_dcache_range(ARM_DRAM2_BASE, dram2_size); + + INFO("Enabling ECC on DMCs\n"); + mmio_setbits_32(N1SDP_DMC0_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN); + mmio_setbits_32(N1SDP_DMC1_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN); +} + +void copy_bl33(uint32_t src, uint32_t dst, uint32_t size) +{ + uint32_t i; + + INFO("Copying BL33 to DDR memory\n"); + for (i = 0; i < size; i = i + 8) + mmio_write_64((dst + i), mmio_read_64(src + i)); + + for (i = 0; i < size; i = i + 8) { + if (mmio_read_64(src + i) != mmio_read_64(dst + i)) { + ERROR("Copy failed!\n"); + panic(); + } + } +} + +void bl31_platform_setup(void) +{ + int ret; + struct n1sdp_mem_info mem_info; + struct n1sdp_bl33_info bl33_info; + + arm_bl31_platform_setup(); + + ret = sds_init(); + if (ret != SDS_OK) { + ERROR("SDS initialization failed\n"); + panic(); + } + + ret = sds_struct_read(N1SDP_SDS_MEM_INFO_STRUCT_ID, + N1SDP_SDS_MEM_INFO_OFFSET, + &mem_info, + N1SDP_SDS_MEM_INFO_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) { + ERROR("Error getting memory info from SDS\n"); + panic(); + } + dmc_ecc_setup(mem_info.ddr_size_gb); + + ret = sds_struct_read(N1SDP_SDS_BL33_INFO_STRUCT_ID, + N1SDP_SDS_BL33_INFO_OFFSET, + &bl33_info, + N1SDP_SDS_BL33_INFO_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) { + ERROR("Error getting BL33 info from SDS\n"); + panic(); + } + copy_bl33(bl33_info.bl33_src_addr, + bl33_info.bl33_dst_addr, + bl33_info.bl33_size); + /* + * Pass DDR memory size info to BL33. This method is followed as + * currently there is no BL1/BL2 involved in boot flow of N1SDP. + * When TBBR is implemented for N1SDP, this method should be removed + * and DDR memory size shoule be passed to BL33 using NT_FW_CONFIG + * passing mechanism. + */ + mmio_write_32(N1SDP_DDR_MEM_INFO_BASE, mem_info.ddr_size_gb); +} diff --git a/plat/arm/board/n1sdp/n1sdp_def.h b/plat/arm/board/n1sdp/n1sdp_def.h new file mode 100644 index 00000000..b7f7213d --- /dev/null +++ b/plat/arm/board/n1sdp/n1sdp_def.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef N1SDP_DEF_H +#define N1SDP_DEF_H + +/* Non-secure SRAM MMU mapping */ +#define N1SDP_NS_SRAM_BASE (0x06000000) +#define N1SDP_NS_SRAM_SIZE (0x00010000) +#define N1SDP_MAP_NS_SRAM MAP_REGION_FLAT( \ + N1SDP_NS_SRAM_BASE, \ + N1SDP_NS_SRAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* SDS memory information defines */ +#define N1SDP_SDS_MEM_INFO_STRUCT_ID 8 +#define N1SDP_SDS_MEM_INFO_OFFSET 0 +#define N1SDP_SDS_MEM_INFO_SIZE 4 + +/* SDS BL33 image information defines */ +#define N1SDP_SDS_BL33_INFO_STRUCT_ID 9 +#define N1SDP_SDS_BL33_INFO_OFFSET 0 +#define N1SDP_SDS_BL33_INFO_SIZE 12 + +/* DMC ERR0CTLR0 registers */ +#define N1SDP_DMC0_ERR0CTLR0_REG 0x4E000708 +#define N1SDP_DMC1_ERR0CTLR0_REG 0x4E100708 + +/* DMC ECC enable bit in ERR0CTLR0 register */ +#define N1SDP_DMC_ERR0CTLR0_ECC_EN 0x1 + +/* Base address of non-secure SRAM where DDR memory size will be filled */ +#define N1SDP_DDR_MEM_INFO_BASE 0x06008000 + +#endif /* N1SDP_DEF_H */ diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c index f36f9e25..a32ca725 100644 --- a/plat/arm/board/n1sdp/n1sdp_plat.c +++ b/plat/arm/board/n1sdp/n1sdp_plat.c @@ -12,6 +12,8 @@ #include #include +#include "n1sdp_def.h" + /* * Table of regions to map using the MMU. * Replace or extend the below regions as required @@ -20,6 +22,9 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, N1SDP_MAP_DEVICE, + N1SDP_MAP_NS_SRAM, + ARM_MAP_DRAM1, + ARM_MAP_DRAM2, {0} }; diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index d0c34c8f..986bd70a 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -32,7 +32,8 @@ BL31_SOURCES := ${N1SDP_CPU_SOURCES} \ ${N1SDP_GIC_SOURCES} \ ${N1SDP_BASE}/n1sdp_bl31_setup.c \ ${N1SDP_BASE}/n1sdp_topology.c \ - ${N1SDP_BASE}/n1sdp_security.c + ${N1SDP_BASE}/n1sdp_security.c \ + drivers/arm/css/sds/sds.c # TF-A not required to load the SCP Images diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h index 3b3ade0c..c62cda85 100644 --- a/plat/arm/board/rde1edge/include/platform_def.h +++ b/plat/arm/board/rde1edge/include/platform_def.h @@ -26,4 +26,15 @@ #define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL3 +/* + * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes + */ +#ifndef AARCH32 +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + #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 8480c08f..2c7b8bda 100644 --- a/plat/arm/board/rdn1edge/include/platform_def.h +++ b/plat/arm/board/rdn1edge/include/platform_def.h @@ -27,4 +27,15 @@ #define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 +/* + * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes + */ +#ifndef AARCH32 +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + #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 ec51c9e0..883403bb 100644 --- a/plat/arm/board/sgi575/include/platform_def.h +++ b/plat/arm/board/sgi575/include/platform_def.h @@ -27,4 +27,15 @@ #define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 +/* + * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes + */ +#ifndef AARCH32 +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h index 8a3431b1..3e1fdd12 100644 --- a/plat/arm/board/sgm775/include/platform_def.h +++ b/plat/arm/board/sgm775/include/platform_def.h @@ -12,4 +12,15 @@ #define PLAT_MAX_CPUS_PER_CLUSTER 8 #define PLAT_MAX_PE_PER_CPU 1 +/* + * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes + */ +#ifndef AARCH32 +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + #endif /* PLATFORM_DEF_H */