Browse Source
The EL3 runtime firmware has been running from internal trusted SRAM space on the Morello platform. Due to unavailability of tag support for the internal trusted SRAM this becomes a problem if we enable capability pointers in BL31. To support capability pointers in BL31 it has to be run from the main DDR memory space. This patch updates the Morello platform configuration such that BL31 is loaded and run from DDR space. Signed-off-by: Manoj Kumar <manoj.kumar3@arm.com> Change-Id: I16d4d757fb6f58c364f5133236d50fc06845e0b4pull/1986/head
Manoj Kumar
2 years ago
4 changed files with 227 additions and 223 deletions
@ -1,27 +1,226 @@ |
|||
/*
|
|||
* Copyright (c) 2021, Arm Limited. All rights reserved. |
|||
* Copyright (c) 2021-2022, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <common/debug.h> |
|||
#include <drivers/arm/css/sds.h> |
|||
#include <lib/mmio.h> |
|||
#include <lib/utils.h> |
|||
#include <plat/arm/common/plat_arm.h> |
|||
|
|||
void bl2_platform_setup(void) |
|||
{ |
|||
#include "morello_def.h" |
|||
#include <platform_def.h> |
|||
|
|||
#ifdef TARGET_PLATFORM_FVP |
|||
/*
|
|||
* Platform information structure stored in SDS. |
|||
* This structure holds information about platform's DDR |
|||
* size |
|||
* - Local DDR size in bytes, DDR memory in main board |
|||
*/ |
|||
struct morello_plat_info { |
|||
uint64_t local_ddr_size; |
|||
} __packed; |
|||
#else |
|||
/*
|
|||
* Platform information structure stored in SDS. |
|||
* This structure holds information about platform's DDR |
|||
* size which is an information about multichip setup |
|||
* - Local DDR size in bytes, DDR memory in main board |
|||
* - Remote DDR size in bytes, DDR memory in remote board |
|||
* - remote_chip_count |
|||
* - multichip mode |
|||
* - scc configuration |
|||
*/ |
|||
struct morello_plat_info { |
|||
uint64_t local_ddr_size; |
|||
uint64_t remote_ddr_size; |
|||
uint8_t remote_chip_count; |
|||
bool multichip_mode; |
|||
uint32_t scc_config; |
|||
} __packed; |
|||
#endif |
|||
|
|||
/* 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); |
|||
|
|||
#ifdef TARGET_PLATFORM_SOC |
|||
/*
|
|||
* Morello 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 DMC-Bing. |
|||
* Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF during BL2 stage, |
|||
* as BL33 binary cannot be copied to DDR memory before enabling ECC. |
|||
* Rest of the DDR memory space is zeroed out during BL31 stage. |
|||
*/ |
|||
/*
|
|||
* Morello 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 DMC-Bing. 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. |
|||
*/ |
|||
|
|||
static void dmc_ecc_setup(struct morello_plat_info *plat_info) |
|||
{ |
|||
uint64_t dram2_size; |
|||
uint32_t val; |
|||
uint64_t tag_mem_base; |
|||
uint64_t usable_mem_size; |
|||
|
|||
INFO("Total DIMM size: %uGB\n", |
|||
(uint32_t)(plat_info->local_ddr_size / 0x40000000)); |
|||
|
|||
assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE); |
|||
dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE; |
|||
|
|||
INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n"); |
|||
zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE); |
|||
flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE); |
|||
|
|||
INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n", |
|||
ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size); |
|||
zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size); |
|||
flush_dcache_range(ARM_DRAM2_BASE, dram2_size); |
|||
|
|||
/* Clear previous ECC errors while zeroing out the memory */ |
|||
val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG); |
|||
mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val); |
|||
|
|||
val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG); |
|||
mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val); |
|||
|
|||
/* Set DMCs to CONFIG state before writing ERR0CTLR0 register */ |
|||
mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG); |
|||
mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG); |
|||
|
|||
while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) & |
|||
MORELLO_DMC_MEMC_STATUS_MASK) != |
|||
MORELLO_DMC_MEMC_CMD_CONFIG) { |
|||
continue; |
|||
} |
|||
|
|||
while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) & |
|||
MORELLO_DMC_MEMC_STATUS_MASK) != |
|||
MORELLO_DMC_MEMC_CMD_CONFIG) { |
|||
continue; |
|||
} |
|||
|
|||
/* Configure Bing client/server mode based on SCC configuration */ |
|||
if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) { |
|||
INFO("Configuring DMC Bing in client mode\n"); |
|||
usable_mem_size = plat_info->local_ddr_size - |
|||
(plat_info->local_ddr_size / 128ULL); |
|||
|
|||
/* Linear DDR address */ |
|||
tag_mem_base = usable_mem_size; |
|||
tag_mem_base = tag_mem_base / 4; |
|||
|
|||
/* Reverse translation */ |
|||
if (tag_mem_base < ARM_DRAM1_BASE) { |
|||
tag_mem_base += ARM_DRAM1_BASE; |
|||
} else { |
|||
tag_mem_base = tag_mem_base - ARM_DRAM1_BASE + |
|||
ARM_DRAM2_BASE; |
|||
} |
|||
|
|||
mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1); |
|||
mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1); |
|||
mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1); |
|||
mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1); |
|||
|
|||
if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) { |
|||
mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2); |
|||
mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2); |
|||
INFO("C1 Tag Cache Enabled\n"); |
|||
} |
|||
|
|||
if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) { |
|||
mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4); |
|||
mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4); |
|||
INFO("C2 Tag Cache Enabled\n"); |
|||
} |
|||
|
|||
mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL, |
|||
(uint32_t)tag_mem_base); |
|||
mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL, |
|||
(uint32_t)tag_mem_base); |
|||
mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2, |
|||
(uint32_t)(tag_mem_base >> 32)); |
|||
mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2, |
|||
(uint32_t)(tag_mem_base >> 32)); |
|||
|
|||
mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL, |
|||
MORELLO_DMC_MEM_ACCESS_DIS); |
|||
mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL, |
|||
MORELLO_DMC_MEM_ACCESS_DIS); |
|||
|
|||
INFO("Tag base set to 0x%lx\n", tag_mem_base); |
|||
plat_info->local_ddr_size = usable_mem_size; |
|||
} else { |
|||
INFO("Configuring DMC Bing in server mode\n"); |
|||
mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0); |
|||
mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0); |
|||
} |
|||
|
|||
INFO("Enabling ECC on DMCs\n"); |
|||
/* Enable ECC in DMCs */ |
|||
mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG, |
|||
MORELLO_DMC_ERR0CTLR0_ECC_EN); |
|||
mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG, |
|||
MORELLO_DMC_ERR0CTLR0_ECC_EN); |
|||
|
|||
/* Set DMCs to READY state */ |
|||
mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY); |
|||
mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY); |
|||
|
|||
while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) & |
|||
MORELLO_DMC_MEMC_STATUS_MASK) != |
|||
MORELLO_DMC_MEMC_CMD_READY) { |
|||
continue; |
|||
} |
|||
|
|||
while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) & |
|||
MORELLO_DMC_MEMC_STATUS_MASK) != |
|||
MORELLO_DMC_MEMC_CMD_READY) { |
|||
continue; |
|||
} |
|||
} |
|||
#endif |
|||
|
|||
void bl2_platform_setup(void) |
|||
{ |
|||
int ret; |
|||
struct morello_plat_info plat_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 */ |
|||
#ifdef TARGET_PLATFORM_FVP |
|||
if (plat_info.local_ddr_size == 0U) { |
|||
#else |
|||
if ((plat_info.local_ddr_size == 0U) |
|||
|| (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY) |
|||
|| (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY) |
|||
|| (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT) |
|||
) { |
|||
#endif |
|||
ERROR("platform info SDS is corrupted\n"); |
|||
panic(); |
|||
} |
|||
|
|||
#ifdef TARGET_PLATFORM_SOC |
|||
dmc_ecc_setup(&plat_info); |
|||
#endif |
|||
arm_bl2_platform_setup(); |
|||
} |
|||
|
Loading…
Reference in new issue