GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <neoverse_n1.h>
#include <cpu_macros.S>
#include <platform_def.h>
.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 * N1SDP_MAX_CLUSTERS_PER_CHIP + ClusterId) *
* N1SDP_MAX_CPUS_PER_CLUSTER * N1SDP_MAX_PE_PER_CPU) +
* (CPUId * N1SDP_MAX_PE_PER_CPU) + ThreadId
*
* which can be simplified as:
*
* (((ChipId * N1SDP_MAX_CLUSTERS_PER_CHIP + ClusterId) *
* N1SDP_MAX_CPUS_PER_CLUSTER + CPUId) * N1SDP_MAX_PE_PER_CPU) +
* ThreadId
* ------------------------------------------------------
*/
func plat_arm_calc_core_pos
mov x4, x0
/*
* The MT bit in MPIDR is always set for n1sdp 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, #N1SDP_MAX_CLUSTERS_PER_CHIP
madd x2, x3, x4, x2
mov x4, #N1SDP_MAX_CPUS_PER_CLUSTER
madd x1, x2, x4, x1
mov x4, #N1SDP_MAX_PE_PER_CPU
madd x0, x1, x4, 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
jump_if_cpu_midr NEOVERSE_N1_MIDR, N1
ret
/* -----------------------------------------------------
* Disable CPU power down bit in power control register
* -----------------------------------------------------
*/
N1:
mrs x0, NEOVERSE_N1_CPUPWRCTLR_EL1
bic x0, x0, #NEOVERSE_N1_CORE_PWRDN_EN_MASK
msr NEOVERSE_N1_CPUPWRCTLR_EL1, x0
isb
ret
endfunc plat_reset_handler
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/tbbr/tbbr_img_def.h>
/dts-v1/;
/ {
dtb-registry {
compatible = "fconf,dyn_cfg-dtb_registry";
tb_fw-config {
load-address = <0x0 0x4001300>;
max-size = <0x200>;
id = <TB_FW_CONFIG_ID>;
};
tos_fw-config {
load-address = <0x0 0x4001600>;
max-size = <0x1000>;
id = <TOS_FW_CONFIG_ID>;
};
nt_fw-config {
load-address = <0x0 0xFEF00000>;
max-size = <0x0100000>;
id = <NT_FW_CONFIG_ID>;
};
};
};
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/dts-v1/;
/ {
/* compatible string */
compatible = "arm,n1sdp";
/*
* Place holder for platform-info node with default values.
* The values will be set to the correct values during
* the BL2 stage of boot.
*/
platform-info {
multichip-mode = <0x0>;
secondary-chip-count = <0x0>;
local-ddr-size = <0x0>;
remote-ddr-size = <0x0>;
};
};
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2022 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>;
/*
* BL32 image details needed by SPMC
*
* Note:
* binary_size: size of BL32 + TOS_FW_CONFIG
*/
attribute {
spmc_id = <0x8000>;
maj_ver = <0x1>;
min_ver = <0x0>;
exec_state = <0x0>;
load_address = <0x0 0x08000000>;
entrypoint = <0x0 0x08000000>;
binary_size = <0x2000000>;
};
};
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2022, 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>;
};
};
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLAT_MACROS_S
#define PLAT_MACROS_S
#include <css_macros.S>
/* ---------------------------------------------
* 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 */
@@ -0,0 +1,251 @@
/*
* Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLATFORM_DEF_H
#define PLATFORM_DEF_H
#include <plat/arm/board/common/v2m_def.h>
#include <plat/arm/common/arm_def.h>
#include <plat/arm/css/common/css_def.h>
/* UART related constants */
#define PLAT_ARM_BOOT_UART_BASE 0x2A400000
#define PLAT_ARM_BOOT_UART_CLK_IN_HZ 50000000
/* IOFPGA UART0 */
#define PLAT_ARM_RUN_UART_BASE 0x1C090000
#define PLAT_ARM_RUN_UART_CLK_IN_HZ 24000000
#define PLAT_ARM_SP_MIN_RUN_UART_BASE 0x2A410000
#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ 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)
#define MAX_IO_DEVICES U(3)
#define MAX_IO_HANDLES U(4)
#define PLAT_ARM_FLASH_IMAGE_BASE 0x18200000
#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE 0x00800000
#define PLAT_ARM_NVM_BASE 0x18200000
#define PLAT_ARM_NVM_SIZE 0x00800000
#if defined NS_BL1U_BASE
# undef NS_BL1U_BASE
# define NS_BL1U_BASE (PLAT_ARM_NVM_BASE + UL(0x00800000))
#endif
/* Non-volatile counters */
#define SOC_TRUSTED_NVCTR_BASE 0x7fe70000
#define TFW_NVCTR_BASE (SOC_TRUSTED_NVCTR_BASE)
#define TFW_NVCTR_SIZE U(4)
#define NTFW_CTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0004)
#define NTFW_CTR_SIZE U(4)
/* N1SDP remote chip at 4 TB offset */
#define PLAT_ARM_REMOTE_CHIP_OFFSET (ULL(1) << 42)
#define N1SDP_REMOTE_DRAM1_BASE ARM_DRAM1_BASE + \
PLAT_ARM_REMOTE_CHIP_OFFSET
#define N1SDP_REMOTE_DRAM1_SIZE ARM_DRAM1_SIZE
#define N1SDP_REMOTE_DRAM2_BASE PLAT_ARM_DRAM2_BASE + \
PLAT_ARM_REMOTE_CHIP_OFFSET
#define N1SDP_REMOTE_DRAM2_SIZE PLAT_ARM_DRAM2_SIZE
/*
* 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. 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.
*/
#ifdef __aarch64__
#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)
#endif
#if CSS_USE_SCMI_SDS_DRIVER
#define N1SDP_SCMI_PAYLOAD_BASE 0x45400000
#else
#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE 0x45400000
#endif
/*
* Trusted SRAM in N1SDP is 512 KB but only the bottom 384 KB
* is used for trusted board boot flow. The top 128 KB is used
* to load AP-BL1 image.
*/
#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00060000 /* 384 KB */
/*
* 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 U(0)
# define PLAT_ARM_MAX_ROMLIB_RO_SIZE U(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 0x22000
#else
# define PLAT_ARM_MAX_BL2_SIZE 0x14000
#endif
#define PLAT_ARM_MAX_BL31_SIZE UL(0x40000)
#define PLAT_ARM_SPMC_BASE U(0x08000000)
#define PLAT_ARM_SPMC_SIZE UL(0x02000000) /* 32 MB */
/*******************************************************************************
* N1SDP topology related constants
******************************************************************************/
#define N1SDP_MAX_CPUS_PER_CLUSTER U(2)
#define PLAT_ARM_CLUSTER_COUNT U(2)
#define PLAT_N1SDP_CHIP_COUNT U(2)
#define N1SDP_MAX_CLUSTERS_PER_CHIP U(2)
#define N1SDP_MAX_PE_PER_CPU U(1)
#define PLATFORM_CORE_COUNT (PLAT_N1SDP_CHIP_COUNT * \
PLAT_ARM_CLUSTER_COUNT * \
N1SDP_MAX_CPUS_PER_CLUSTER * \
N1SDP_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.
*/
#ifdef IMAGE_BL1
# define PLAT_ARM_MMAP_ENTRIES U(6)
# define MAX_XLAT_TABLES U(5)
#endif
#ifdef IMAGE_BL2
# define PLAT_ARM_MMAP_ENTRIES U(11)
# define MAX_XLAT_TABLES U(10)
#endif
#ifdef IMAGE_BL31
# define PLAT_ARM_MMAP_ENTRIES U(12)
# define MAX_XLAT_TABLES U(12)
#endif
/*
* 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 PLAT_ARM_NSTIMER_FRAME_ID 0
#define PLAT_CSS_MHU_BASE 0x45000000
#define PLAT_MAX_PWR_LVL 2
#define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \
CSS_IRQ_MHU
#define PLAT_ARM_G0_IRQS ARM_G0_IRQS
#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 N1SDP_DEVICE_BASE ULL(0x08000000)
#define N1SDP_DEVICE_SIZE ULL(0x48000000)
#define N1SDP_REMOTE_DEVICE_BASE N1SDP_DEVICE_BASE + \
PLAT_ARM_REMOTE_CHIP_OFFSET
#define N1SDP_REMOTE_DEVICE_SIZE N1SDP_DEVICE_SIZE
/* Real base is 0x0. Changed to load BL1 at this address */
# define PLAT_ARM_TRUSTED_ROM_BASE 0x04060000
# define PLAT_ARM_TRUSTED_ROM_SIZE 0x00020000 /* 128KB */
#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)
#define N1SDP_MAP_REMOTE_DEVICE MAP_REGION_FLAT( \
N1SDP_REMOTE_DEVICE_BASE, \
N1SDP_REMOTE_DEVICE_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
#define N1SDP_MAP_REMOTE_DRAM1 MAP_REGION_FLAT( \
N1SDP_REMOTE_DRAM1_BASE, \
N1SDP_REMOTE_DRAM1_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
#define N1SDP_MAP_REMOTE_DRAM2 MAP_REGION_FLAT( \
N1SDP_REMOTE_DRAM2_BASE, \
N1SDP_REMOTE_DRAM2_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
/* GIC related constants */
#define PLAT_ARM_GICD_BASE 0x30000000
#define PLAT_ARM_GICC_BASE 0x2C000000
#define PLAT_ARM_GICR_BASE 0x300C0000
/* Platform ID address */
#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET)
/* Secure Watchdog Constants */
#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 */
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat/arm/common/plat_arm.h>
/*******************************************************************************
* Perform any BL1 specific platform actions.
******************************************************************************/
void soc_css_init_nic400(void)
{
}
void soc_css_init_pcie(void)
{
}
@@ -0,0 +1,89 @@
/*
* Copyright (c) 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 "n1sdp_def.h"
#include <plat/arm/common/plat_arm.h>
struct n1sdp_plat_info {
bool multichip_mode;
uint8_t secondary_count;
uint8_t local_ddr_size;
uint8_t remote_ddr_size;
} __packed;
/*
* 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.
*/
void dmc_ecc_setup(uint8_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");
/* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG);
mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG);
/* Enable ECC in DMCs */
mmio_setbits_32(N1SDP_DMC0_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN);
mmio_setbits_32(N1SDP_DMC1_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN);
/* Set DMCs to READY state */
mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
}
void bl2_platform_setup(void)
{
int ret;
struct n1sdp_plat_info plat_info;
ret = sds_init();
if (ret != SDS_OK) {
ERROR("SDS initialization failed\n");
panic();
}
ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
N1SDP_SDS_PLATFORM_INFO_OFFSET,
&plat_info,
N1SDP_SDS_PLATFORM_INFO_SIZE,
SDS_ACCESS_MODE_NON_CACHED);
if (ret != SDS_OK) {
ERROR("Error getting platform info from SDS\n");
panic();
}
/* Validate plat_info SDS */
if ((plat_info.local_ddr_size == 0)
|| (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
|| (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
|| (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT)) {
ERROR("platform info SDS is corrupted\n");
panic();
}
dmc_ecc_setup(plat_info.local_ddr_size);
arm_bl2_platform_setup();
}
@@ -0,0 +1,161 @@
/*
* Copyright (c) 2018-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 <drivers/arm/gic600_multichip.h>
#include <lib/mmio.h>
#include <lib/utils.h>
#include <plat/arm/common/plat_arm.h>
#include "n1sdp_def.h"
#include <platform_def.h>
/*
* Platform information structure stored in SDS.
* This structure holds information about platform's DDR
* size which will be used to zero out the memory before
* enabling the ECC capability as well as information
* about multichip setup
* - multichip mode
* - secondary_count
* - Local DDR size in GB, DDR memory in master board
* - Remote DDR size in GB, DDR memory in secondary board
*/
struct n1sdp_plat_info {
bool multichip_mode;
uint8_t secondary_count;
uint8_t local_ddr_size;
uint8_t remote_ddr_size;
} __packed;
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,
.db_preserve_mask = 0xfffffffe,
.db_modify_mask = 0x1,
.ring_doorbell = &mhu_ring_doorbell
};
static struct gic600_multichip_data n1sdp_multichip_data __init = {
.rt_owner_base = PLAT_ARM_GICD_BASE,
.rt_owner = 0,
.chip_count = 1,
.chip_addrs = {
PLAT_ARM_GICD_BASE >> 16,
PLAT_ARM_GICD_BASE >> 16
},
.spi_ids = {
{PLAT_ARM_GICD_BASE, 32, 479},
{PLAT_ARM_GICD_BASE, 512, 959}
}
};
static uintptr_t n1sdp_multichip_gicr_frames[3] = {
PLAT_ARM_GICR_BASE,
PLAT_ARM_GICR_BASE + PLAT_ARM_REMOTE_CHIP_OFFSET,
0
};
scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
return &n1sdp_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);
}
/*
* 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. Local DDR memory is zeroed out during BL2
* stage. If remote chip is connected, it's DDR memory is zeroed out here.
*/
void remote_dmc_ecc_setup(uint8_t remote_ddr_size)
{
uint64_t remote_dram2_size;
remote_dram2_size = (remote_ddr_size * 1024UL * 1024UL * 1024UL) -
N1SDP_REMOTE_DRAM1_SIZE;
/* multichip setup */
INFO("Zeroing remote DDR memories\n");
zero_normalmem((void *)N1SDP_REMOTE_DRAM1_BASE,
N1SDP_REMOTE_DRAM1_SIZE);
flush_dcache_range(N1SDP_REMOTE_DRAM1_BASE, N1SDP_REMOTE_DRAM1_SIZE);
zero_normalmem((void *)N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size);
flush_dcache_range(N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size);
INFO("Enabling ECC on remote DMCs\n");
/* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG,
N1SDP_DMC_MEMC_CMD_CONFIG);
mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG,
N1SDP_DMC_MEMC_CMD_CONFIG);
/* Enable ECC in DMCs */
mmio_setbits_32(N1SDP_REMOTE_DMC0_ERR0CTLR0_REG,
N1SDP_DMC_ERR0CTLR0_ECC_EN);
mmio_setbits_32(N1SDP_REMOTE_DMC1_ERR0CTLR0_REG,
N1SDP_DMC_ERR0CTLR0_ECC_EN);
/* Set DMCs to READY state */
mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
}
void n1sdp_bl31_multichip_setup(void)
{
plat_arm_override_gicr_frames(n1sdp_multichip_gicr_frames);
gic600_multichip_init(&n1sdp_multichip_data);
}
void bl31_platform_setup(void)
{
int ret;
struct n1sdp_plat_info plat_info;
ret = sds_init();
if (ret != SDS_OK) {
ERROR("SDS initialization failed\n");
panic();
}
ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
N1SDP_SDS_PLATFORM_INFO_OFFSET,
&plat_info,
N1SDP_SDS_PLATFORM_INFO_SIZE,
SDS_ACCESS_MODE_NON_CACHED);
if (ret != SDS_OK) {
ERROR("Error getting platform info from SDS\n");
panic();
}
/* Validate plat_info SDS */
if ((plat_info.local_ddr_size == 0)
|| (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
|| (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
|| (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT)) {
ERROR("platform info SDS is corrupted\n");
panic();
}
if (plat_info.multichip_mode) {
n1sdp_multichip_data.chip_count = plat_info.secondary_count + 1;
n1sdp_bl31_multichip_setup();
}
arm_bl31_platform_setup();
/* Check if remote memory is present */
if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0))
remote_dmc_ecc_setup(plat_info.remote_ddr_size);
}
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2018-2022, Arm Limited. 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 Platform information defines */
#define N1SDP_SDS_PLATFORM_INFO_STRUCT_ID 8
#define N1SDP_SDS_PLATFORM_INFO_OFFSET 0
#define N1SDP_SDS_PLATFORM_INFO_SIZE 4
#define N1SDP_MAX_DDR_CAPACITY_GB 64
#define N1SDP_MAX_SECONDARY_COUNT 16
/* DMC memory command registers */
#define N1SDP_DMC0_MEMC_CMD_REG 0x4E000008
#define N1SDP_DMC1_MEMC_CMD_REG 0x4E100008
/* DMC ERR0CTLR0 registers */
#define N1SDP_DMC0_ERR0CTLR0_REG 0x4E000708
#define N1SDP_DMC1_ERR0CTLR0_REG 0x4E100708
/* Remote DMC memory command registers */
#define N1SDP_REMOTE_DMC0_MEMC_CMD_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\
N1SDP_DMC0_MEMC_CMD_REG
#define N1SDP_REMOTE_DMC1_MEMC_CMD_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\
N1SDP_DMC1_MEMC_CMD_REG
/* Remote DMC ERR0CTLR0 registers */
#define N1SDP_REMOTE_DMC0_ERR0CTLR0_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\
N1SDP_DMC0_ERR0CTLR0_REG
#define N1SDP_REMOTE_DMC1_ERR0CTLR0_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\
N1SDP_DMC1_ERR0CTLR0_REG
/* DMC memory commands */
#define N1SDP_DMC_MEMC_CMD_CONFIG 0
#define N1SDP_DMC_MEMC_CMD_READY 3
/* DMC ECC enable bit in ERR0CTLR0 register */
#define N1SDP_DMC_ERR0CTLR0_ECC_EN 0x1
#endif /* N1SDP_DEF_H */
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat/arm/common/plat_arm.h>
/*
* n1sdp error handler
*/
void __dead2 plat_arm_error_handler(int err)
{
while (true) {
wfi();
}
}
@@ -0,0 +1,143 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/arm/css/sds.h>
#include <libfdt.h>
#include <plat/common/platform.h>
#include "n1sdp_def.h"
#include <plat/arm/common/plat_arm.h>
/*
* Platform information structure stored in SDS.
* This structure holds information about platform's DDR
* size which will be used to zero out the memory before
* enabling the ECC capability as well as information
* about multichip setup
* - multichip mode
* - secondary_count
* - Local DDR size in GB, DDR memory in master board
* - Remote DDR size in GB, DDR memory in secondary board
*/
struct n1sdp_plat_info {
bool multichip_mode;
uint8_t secondary_count;
uint8_t local_ddr_size;
uint8_t remote_ddr_size;
} __packed;
/*******************************************************************************
* This function inserts Platform information via device tree nodes as,
* platform-info {
* multichip-mode = <0x0>;
* secondary-chip-count = <0x0>;
* local-ddr-size = <0x0>;
* remote-ddr-size = <0x0>;
* };
******************************************************************************/
static int plat_n1sdp_append_config_node(struct n1sdp_plat_info *plat_info)
{
bl_mem_params_node_t *mem_params;
void *fdt;
int nodeoffset, err;
mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
if (mem_params == NULL) {
ERROR("NT_FW CONFIG base address is NULL\n");
return -1;
}
fdt = (void *)(mem_params->image_info.image_base);
/* Check the validity of the fdt */
if (fdt_check_header(fdt) != 0) {
ERROR("Invalid NT_FW_CONFIG DTB passed\n");
return -1;
}
nodeoffset = fdt_subnode_offset(fdt, 0, "platform-info");
if (nodeoffset < 0) {
ERROR("NT_FW_CONFIG: Failed to get platform-info node offset\n");
return -1;
}
err = fdt_setprop_u32(fdt, nodeoffset, "multichip-mode",
plat_info->multichip_mode);
if (err < 0) {
ERROR("NT_FW_CONFIG: Failed to set multichip-mode\n");
return -1;
}
err = fdt_setprop_u32(fdt, nodeoffset, "secondary-chip-count",
plat_info->secondary_count);
if (err < 0) {
ERROR("NT_FW_CONFIG: Failed to set secondary-chip-count\n");
return -1;
}
err = fdt_setprop_u32(fdt, nodeoffset, "local-ddr-size",
plat_info->local_ddr_size);
if (err < 0) {
ERROR("NT_FW_CONFIG: Failed to set local-ddr-size\n");
return -1;
}
err = fdt_setprop_u32(fdt, nodeoffset, "remote-ddr-size",
plat_info->remote_ddr_size);
if (err < 0) {
ERROR("NT_FW_CONFIG: Failed to set remote-ddr-size\n");
return -1;
}
flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
return 0;
}
/*******************************************************************************
* This function returns the list of executable images.
******************************************************************************/
bl_params_t *plat_get_next_bl_params(void)
{
int ret;
struct n1sdp_plat_info plat_info;
ret = sds_init();
if (ret != SDS_OK) {
ERROR("SDS initialization failed. ret:%d\n", ret);
panic();
}
ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
N1SDP_SDS_PLATFORM_INFO_OFFSET,
&plat_info,
N1SDP_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 > N1SDP_MAX_DDR_CAPACITY_GB)
|| (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
|| (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT)
){
ERROR("platform info SDS is corrupted\n");
panic();
}
ret = plat_n1sdp_append_config_node(&plat_info);
if (ret != 0) {
panic();
}
return arm_get_next_bl_params();
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* For N1SDP which support 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)
{
}
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <drivers/arm/sbsa.h>
#include <plat/arm/common/plat_arm.h>
#include "n1sdp_def.h"
/*
* Table of regions to map using the MMU.
* Replace or extend the below regions as required
*/
#if IMAGE_BL1
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
N1SDP_MAP_DEVICE,
N1SDP_MAP_NS_SRAM,
ARM_MAP_DRAM1,
{0}
};
#endif
#if IMAGE_BL2
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
N1SDP_MAP_DEVICE,
N1SDP_MAP_NS_SRAM,
ARM_MAP_DRAM1,
ARM_MAP_DRAM2,
#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,
N1SDP_MAP_DEVICE,
N1SDP_MAP_NS_SRAM,
N1SDP_MAP_REMOTE_DEVICE,
N1SDP_MAP_REMOTE_DRAM1,
N1SDP_MAP_REMOTE_DRAM2,
{0}
};
#endif
#if TRUSTED_BOARD_BOOT
int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
{
assert(heap_addr != NULL);
assert(heap_size != NULL);
return arm_get_mbedtls_heap(heap_addr, heap_size);
}
#endif
void 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);
}
@@ -0,0 +1,12 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* TZC programming is currently not done.
*/
void plat_arm_security_setup(void)
{
}
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat/arm/common/plat_arm.h>
/* Topology */
typedef struct n1sdp_topology {
const unsigned char *power_tree;
unsigned int plat_cluster_core_count;
} n1sdp_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 n1sdp_pd_tree_desc[] = {
PLAT_N1SDP_CHIP_COUNT,
PLAT_ARM_CLUSTER_COUNT,
PLAT_ARM_CLUSTER_COUNT,
N1SDP_MAX_CPUS_PER_CLUSTER,
N1SDP_MAX_CPUS_PER_CLUSTER,
N1SDP_MAX_CPUS_PER_CLUSTER,
N1SDP_MAX_CPUS_PER_CLUSTER
};
/* Topology configuration for n1sdp */
const n1sdp_topology_t n1sdp_topology = {
.power_tree = n1sdp_pd_tree_desc,
.plat_cluster_core_count = N1SDP_MAX_CPUS_PER_CLUSTER
};
/*******************************************************************************
* This function returns the topology tree information.
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
return n1sdp_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 n1sdp_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, 4, 5, 6, 7};
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <plat/arm/common/plat_arm.h>
/*
* 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)
{
*nv_ctr = N1SDP_FW_NVCTR_VAL;
return 0;
}
/*
* Store a new non-volatile counter value. By default on ARM development
* platforms, the non-volatile counters are RO and cannot be modified. We expect
* the values in the certificates to always match the RO values so that this
* function is never called.
*
* Return: 0 = success, Otherwise = error
*/
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
return 1;
}
/*
* 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);
}
@@ -0,0 +1,111 @@
#
# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
N1SDP_BASE := plat/arm/board/n1sdp
INTERCONNECT_SOURCES := ${N1SDP_BASE}/n1sdp_interconnect.c
PLAT_INCLUDES := -I${N1SDP_BASE}/include
N1SDP_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S
# GIC-600 configuration
GICV3_SUPPORT_GIC600 := 1
GICV3_IMPL_GIC600_MULTICHIP := 1
# 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 \
PLAT_BL_COMMON_SOURCES := ${N1SDP_BASE}/n1sdp_plat.c \
${N1SDP_BASE}/aarch64/n1sdp_helper.S
BL1_SOURCES := ${N1SDP_CPU_SOURCES} \
${INTERCONNECT_SOURCES} \
${N1SDP_BASE}/n1sdp_err.c \
${N1SDP_BASE}/n1sdp_trusted_boot.c \
${N1SDP_BASE}/n1sdp_bl1_setup.c \
drivers/arm/sbsa/sbsa.c
BL2_SOURCES := ${N1SDP_BASE}/n1sdp_security.c \
${N1SDP_BASE}/n1sdp_err.c \
${N1SDP_BASE}/n1sdp_trusted_boot.c \
lib/utils/mem_region.c \
${N1SDP_BASE}/n1sdp_bl2_setup.c \
${N1SDP_BASE}/n1sdp_image_load.c \
drivers/arm/css/sds/sds.c
BL31_SOURCES := ${N1SDP_CPU_SOURCES} \
${INTERCONNECT_SOURCES} \
${N1SDP_GIC_SOURCES} \
${N1SDP_BASE}/n1sdp_bl31_setup.c \
${N1SDP_BASE}/n1sdp_topology.c \
${N1SDP_BASE}/n1sdp_security.c \
drivers/arm/css/sds/sds.c
FDT_SOURCES += fdts/${PLAT}-single-chip.dts \
fdts/${PLAT}-multi-chip.dts \
${N1SDP_BASE}/fdts/n1sdp_fw_config.dts \
${N1SDP_BASE}/fdts/n1sdp_tb_fw_config.dts \
${N1SDP_BASE}/fdts/n1sdp_nt_fw_config.dts
FW_CONFIG := ${BUILD_PLAT}/fdts/n1sdp_fw_config.dtb
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/n1sdp_tb_fw_config.dtb
NT_FW_CONFIG := ${BUILD_PLAT}/fdts/n1sdp_nt_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}))
# 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}))
N1SDP_SPMC_MANIFEST_DTS := ${N1SDP_BASE}/fdts/${PLAT}_optee_spmc_manifest.dts
FDT_SOURCES += ${N1SDP_SPMC_MANIFEST_DTS}
N1SDP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_optee_spmc_manifest.dtb
# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${N1SDP_TOS_FW_CONFIG},--tos-fw-config,${N1SDP_TOS_FW_CONFIG}))
# Setting to 0 as no NVCTR in N1SDP
N1SDP_FW_NVCTR_VAL := 0
TFW_NVCTR_VAL := ${N1SDP_FW_NVCTR_VAL}
NTFW_NVCTR_VAL := ${N1SDP_FW_NVCTR_VAL}
# Add N1SDP_FW_NVCTR_VAL
$(eval $(call add_define,N1SDP_FW_NVCTR_VAL))
# TF-A not required to load the SCP Images
override CSS_LOAD_SCP_IMAGES := 0
override NEED_BL2U := no
# 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
# Enable the flag since N1SDP has a system level cache
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