Merge changes I1ecbe5a1,Ib5945c37,Ic6b79648 into integration

* changes:
  plat/arm: Add platform support for Morello
  fdts: add device tree sources for morello platform
  lib/cpus: add support for Morello Rainier CPUs
This commit is contained in:
Manish Pandey 2020-09-29 12:17:21 +00:00 committed by TrustedFirmware Code Review
commit 609115a627
15 changed files with 1057 additions and 0 deletions

View File

@ -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
--------------

133
fdts/morello-fvp.dts Normal file
View File

@ -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 = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
};
ethernet@1d100000 {
compatible = "smsc,lan91c111";
reg = <0x0 0x1d100000 0x0 0x10000>;
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
};
kmi@1c150000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x0 0x1c150000 0x0 0x1000>;
interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
clock-names = "KMIREFCLK", "apb_pclk";
};
kmi@1c160000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x0 0x1c160000 0x0 0x1000>;
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
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 = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
};

106
fdts/morello.dtsi Normal file
View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
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 = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
spe-pmu {
compatible = "arm,statistical-profiling-extension-v1";
interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH>;
};
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
};
mailbox: mhu@45000000 {
compatible = "arm,mhu-doorbell", "arm,primecell";
reg = <0x0 0x45000000 0x0 0x1000>;
interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>;
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 = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
clock-names = "uartclk", "apb_pclk";
status = "okay";
};
};

View File

@ -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 <lib/utils_def.h>
/* 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 */

218
lib/cpus/aarch64/rainier.S Normal file
View File

@ -0,0 +1,218 @@
/*
* Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <context.h>
#include <cpu_macros.S>
#include <cpuamu.h>
#include <rainier.h>
/* 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

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <cpu_macros.S>
#include <rainier.h>
#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 * 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

View File

@ -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 <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 */

View File

@ -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 <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 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 */

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2020, 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 <plat/arm/common/plat_arm.h>
#include "morello_def.h"
#include <platform_def.h>
/*
* 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);
}

View File

@ -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 */

View File

@ -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)
{
}

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat/arm/common/plat_arm.h>
#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}
};

View File

@ -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)
{
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <lib/cassert.h>
#include <plat/arm/common/plat_arm.h>
/* 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};

View File

@ -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