Browse Source

fix(morello): move BL31 to run from DRAM space

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: I16d4d757fb6f58c364f5133236d50fc06845e0b4
pull/1986/head
Manoj Kumar 2 years ago
parent
commit
05330a49cd
  1. 221
      plat/arm/board/morello/morello_bl2_setup.c
  2. 210
      plat/arm/board/morello/morello_bl31_setup.c
  3. 15
      plat/arm/board/morello/morello_plat.c
  4. 4
      plat/arm/board/morello/platform.mk

221
plat/arm/board/morello/morello_bl2_setup.c

@ -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();
}

210
plat/arm/board/morello/morello_bl31_setup.c

@ -1,54 +1,16 @@
/*
* Copyright (c) 2020-2021, Arm Limited. All rights reserved.
* Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <drivers/arm/css/css_mhu_doorbell.h>
#include <drivers/arm/css/scmi.h>
#include <drivers/arm/css/sds.h>
#include <lib/cassert.h>
#include <lib/utils.h>
#include <plat/arm/common/plat_arm.h>
#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);
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,
@ -67,177 +29,7 @@ const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
return css_scmi_override_pm_ops(ops);
}
#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 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 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 bl31_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();
}
arm_bl31_platform_setup();
#ifdef TARGET_PLATFORM_SOC
dmc_ecc_setup(&plat_info);
#endif
}

15
plat/arm/board/morello/morello_plat.c

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021, Arm Limited. All rights reserved.
* Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -15,7 +15,7 @@
* Table of regions to map using the MMU.
* Replace or extend the below regions as required
*/
#if IMAGE_BL1 || IMAGE_BL31
#if IMAGE_BL1
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
MORELLO_MAP_DEVICE,
@ -25,12 +25,23 @@ const mmap_region_t plat_arm_mmap[] = {
{0}
};
#endif
#if IMAGE_BL31
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
MORELLO_MAP_DEVICE,
MORELLO_MAP_NS_SRAM,
{0}
};
#endif
#if IMAGE_BL2
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
MORELLO_MAP_DEVICE,
MORELLO_MAP_NS_SRAM,
ARM_MAP_DRAM1,
ARM_MAP_DRAM2,
#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
ARM_MAP_BL1_RW,
#endif

4
plat/arm/board/morello/platform.mk

@ -1,5 +1,5 @@
#
# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -83,6 +83,8 @@ override CTX_INCLUDE_AARCH32_REGS := 0
override ARM_PLAT_MT := 1
override ARM_BL31_IN_DRAM := 1
# Errata workarounds:
ERRATA_N1_1868343 := 1

Loading…
Cancel
Save