diff --git a/docs/plat/ls1043a.rst b/docs/plat/ls1043a.rst new file mode 100644 index 0000000..0d604aa --- /dev/null +++ b/docs/plat/ls1043a.rst @@ -0,0 +1,91 @@ +Description +=========== + +The QorIQ® LS1043A processor is NXP's first quad-core, 64-bit Arm®-based +processor for embedded networking. The LS1023A (two core version) and the +LS1043A (four core version) deliver greater than 10 Gbps of performance +in a flexible I/O package supporting fanless designs. This SoC is a +purpose-built solution for small-form-factor networking and industrial +applications with BOM optimizations for economic low layer PCB, lower cost +power supply and single clock design. The new 0.9V versions of the LS1043A +and LS1023A deliver addition power savings for applications such as Wireless +LAN and to Power over Ethernet systems. + +LS1043ARDB Specification: +------------------------- +Memory subsystem: + * 2GByte DDR4 SDRAM (32bit bus) + * 128 Mbyte NOR flash single-chip memory + * 512 Mbyte NAND flash + * 16 Mbyte high-speed SPI flash + * SD connector to interface with the SD memory card + +Ethernet: + * XFI 10G port + * QSGMII with 4x 1G ports + * Two RGMII ports + +PCIe: + * PCIe2 (Lanes C) to mini-PCIe slot + * PCIe3 (Lanes D) to PCIe slot + +USB 3.0: two super speed USB 3.0 type A ports + +UART: supports two UARTs up to 115200 bps for console + +More information are listed in `ls1043`_. + +Boot Sequence +============= + + +Bootrom --> TF-A BL1 --> TF-A BL2 --> TF-A BL1 --> TF-A BL31 +--> BL32(Tee OS) --> TF-A BL31 --> BL33(u-boot) --> Linux kernel + + +How to build +============ + +Build Procedure +--------------- + +- Prepare AARCH64 toolchain. + +- Build u-boot and OPTee firstly, and get binary images: u-boot.bin and tee.bin + +- Build TF-A for Nor boot + + Build bl1: + + .. code:: shell + + CROSS_COMPILE=aarch64-linux-gnu- make PLAT=ls1043 bl1 + + Build fip: + + .. code:: shell + + CROSS_COMPILE=aarch64-linux-gnu- make PLAT=ls1043 fip \ + BL33=u-boot.bin NEED_BL32=yes BL32=tee.bin SPD=opteed + +Deploy TF-A Images +----------------- + +- Deploy TF-A images on Nor flash Alt Bank. + + .. code:: shell + + => tftp 82000000 bl1.bin + => pro off all;era 64100000 +$filesize;cp.b 82000000 64100000 $filesize + + => tftp 82000000 fip.bin + => pro off all;era 64120000 +$filesize;cp.b 82000000 64120000 $filesize + + Then change to Alt bank and boot up TF-A: + + .. code:: shell + + => cpld reset altbank + + +.. _ls1043: https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/qoriq-layerscape-arm-processors/qoriq-layerscape-1043a-and-1023a-multicore-communications-processors:LS1043A?lang_cd=en diff --git a/maintainers.rst b/maintainers.rst index 77b851e..2217cbe 100644 --- a/maintainers.rst +++ b/maintainers.rst @@ -83,6 +83,15 @@ - plat/mediatek/\* +NXP QorIQ Layerscape platform sub-maintainer +-------------------------------------- +Jiafei Pan (jiafei.pan@nxp.com, `qoriq-open-source`_) + +Files: + +- docs/plat/ls1043a.rst +- plat/layerscape/\* + Raspberry Pi 3 platform sub-maintainer -------------------------------------- @@ -141,3 +150,4 @@ .. _sivadur: https://github.com/sivadur .. _rockchip-linux: https://github.com/rockchip-linux .. _etienne-lms: https://github.com/etienne-lms +.. _qoriq-open-source: https://github.com/qoriq-open-source diff --git a/plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S b/plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S new file mode 100644 index 0000000..80524fc --- /dev/null +++ b/plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl plat_reset_handler + .globl plat_my_core_pos + .globl platform_mem_init + +func plat_my_core_pos + mrs x0, mpidr_el1 + and x1, x0, #MPIDR_CPU_MASK //reserve the last 8 bits + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #4 //4 cores + ret +endfunc plat_my_core_pos + +func platform_mem_init + mov x29, x30 + bl inv_dcache_range + +//SDRAM_CFG + ldr w0, =0x1080000 + ldr w1, =0x0c000c45 + str w1, [x0, #0x110] +//CS0_BNDS + ldr w1, =0x7f000000 + str w1, [x0, #0x000] +//CS0_CONFIG + ldr w1, =0x22030480 + str w1, [x0, #0x080] +//TIMING_CFG_0 + ldr w1, =0x18005591 + str w1, [x0, #0x104] +//TIMING_CFG_1 + ldr w1, =0x428cb4bb + str w1, [x0, #0x108] +//TIMING_CFG_2 + ldr w1, =0x11c14800 + str w1, [x0, #0x10C] +//TIMING_CFG_3 + ldr w1, =0x00100c01 + str w1, [x0, #0x100] +//TIMING_CFG_4 + ldr w1, =0x02000000 + str w1, [x0, #0x160] +//TIMING_CFG_5 + ldr w1, =0x00144003 + str w1, [x0, #0x164] +//TIMING_CFG_7 + ldr w1, =0x00003013 + str w1, [x0, #0x16C] +//TIMING_CFG_8 + ldr w1, =0x00561102 + str w1, [x0, #0x250] +//SDRAM_CFG_2 + ldr w1, =0x00114000 + str w1, [x0, #0x114] +//SDRAM_MODE + ldr w1, =0x10020103 + str w1, [x0, #0x118] +//SDRAM_MODE_2 + ldr w1, =0x0 + str w1, [x0, #0x11C] +//SDRAM_INTERVAL + ldr w1, =0x18066018 + str w1, [x0, #0x124] +//DDR_WRLVL_CNTL + ldr w1, =0x07f675c6 + str w1, [x0, #0x174] +//DDR_WRLVL_CNTL_2 + ldr w1, =0x00080907 + str w1, [x0, #0x190] +//DDR_WRLVL_CNTL_3 + ldr w1, =0x0 + str w1, [x0, #0x194] +//DDR_CDR1 + ldr w1, =0x00000480 + str w1, [x0, #0xB28] +//DDR_CDR2 + ldr w1, =0x81a10000 + str w1, [x0, #0xB2C] +//SDRAM_CLK_CNTL + ldr w1, =0x00000003 + str w1, [x0, #0x130] +//DDR_ZQ_CNTL + ldr w1, =0x0507098a + str w1, [x0, #0x170] +//SDRAM_MODE_9 + ldr w1, =0x00050000 + str w1, [x0, #0x220] +//SDRAM_MODE_10 + ldr w1, =0x00000004 + str w1, [x0, #0x224] +//CS0_CONFIG_2 + ldr w1, =0x0 + str w1, [x0, #0x0C0] +//SDRAM_CFG + ldr w1, =0x08000cc5 + str w1, [x0, #0x110] + + mov w3,#0 + ldr w4,=0xffffff01 +z_loop: +delay_loop1: + sub w4, w4, #1 + cmp w4, #0 + b.gt delay_loop1 + + ldr w1, [x0, #0x114] + add w3, w3, #1 + cmp w1, #0 //'\n' + b.eq 1f + cmp w3, #20 + b.gt 1f + b z_loop + +1: + ldr w4,=0xffffff02 +delay_loop2: + sub w4, w4, #1 + cmp w4, #0 + b.gt delay_loop2 + + ldr w1, =0x00000000 + str w1, [x0] + + ret x29 +endfunc platform_mem_init + +func apply_platform_errata + /*TODO if needed*/ + ret +endfunc apply_platform_errata + +func plat_reset_handler + mov x29, x30 + bl apply_platform_errata + + mov x30, x29 + ret +endfunc plat_reset_handler diff --git a/plat/layerscape/board/ls1043/include/ls_def.h b/plat/layerscape/board/ls1043/include/ls_def.h new file mode 100644 index 0000000..1015129 --- /dev/null +++ b/plat/layerscape/board/ls1043/include/ls_def.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __LS_DEF_H__ +#define __LS_DEF_H__ + +#include +#include +#include +#include +#include +#include + + +/****************************************************************************** + * Definitions common to all ARM standard platforms + *****************************************************************************/ +/* Special value used to verify platform parameters from BL2 to BL31 */ +#define LS_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + +#define LS_CACHE_WRITEBACK_SHIFT 6 + +/* + * Macros mapping the MPIDR Affinity levels to Layerscape Platform Power levels. The + * power levels have a 1:1 mapping with the MPIDR affinity levels. + */ +#define LS_PWR_LVL0 MPIDR_AFFLVL0 +#define LS_PWR_LVL1 MPIDR_AFFLVL1 +#define LS_PWR_LVL2 MPIDR_AFFLVL2 + +/* + * Macros for local power states in Layerscape platforms encoded by State-ID field + * within the power-state parameter. + */ +/* Local power state for power domains in Run state. */ +#define LS_LOCAL_STATE_RUN 0 +/* Local power state for retention. Valid only for CPU power domains */ +#define LS_LOCAL_STATE_RET 1 +/* + * Local power state for OFF/power-down. Valid for CPU and cluster power + * domains + */ +#define LS_LOCAL_STATE_OFF 2 + +#define LS_MAP_NS_DRAM MAP_REGION_FLAT( \ + (LS_NS_DRAM_BASE), \ + LS_DRAM1_SIZE, \ + MT_DEVICE | MT_RW | MT_NS) + +#define LS_MAP_TSP_SEC_MEM MAP_REGION_FLAT( \ + TSP_SEC_MEM_BASE, \ + TSP_SEC_MEM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + + +#define LS_MAP_FLASH0_RW MAP_REGION_FLAT(PLAT_LS_FLASH_BASE,\ + PLAT_LS_FLASH_SIZE, \ + MT_DEVICE | MT_RW) + +#define LS_MAP_CCSR MAP_REGION_FLAT(PLAT_LS_CCSR_BASE, \ + PLAT_LS_CCSR_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + + +#define LS_MAP_CONSOLE MAP_REGION_FLAT(PLAT_LS1043_DUART1_BASE, \ + PLAT_LS1043_DUART_SIZE, \ + MT_DEVICE | MT_RW | MT_NS) + +/* + * The number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU. + */ +/****************************************************************************** + * Required platform porting definitions common to all ARM standard platforms + *****************************************************************************/ + +#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32) + +/* + * This macro defines the deepest retention state possible. A higher state + * id will represent an invalid or a power down state. + */ +#define PLAT_MAX_RET_STATE LS_LOCAL_STATE_RET + +/* + * This macro defines the deepest power down states possible. Any state ID + * higher than this is invalid. + */ +#define PLAT_MAX_OFF_STATE LS_LOCAL_STATE_OFF + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_GRANULE (1 << LS_CACHE_WRITEBACK_SHIFT) + +/* + * One cache line needed for bakery locks on Layerscape platforms + */ +#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE) + +#endif /* __LS_DEF_H__ */ diff --git a/plat/layerscape/board/ls1043/include/ns_access.h b/plat/layerscape/board/ls1043/include/ns_access.h new file mode 100644 index 0000000..6ed7bc0 --- /dev/null +++ b/plat/layerscape/board/ls1043/include/ns_access.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __FSL_NS_ACCESS_H_ +#define __FSL_NS_ACCESS_H_ + +#include "fsl_csu.h" + +enum csu_cslx_ind { + CSU_CSLX_PCIE2_IO = 0, + CSU_CSLX_PCIE1_IO, + CSU_CSLX_MG2TPR_IP, + CSU_CSLX_IFC_MEM, + CSU_CSLX_OCRAM, + CSU_CSLX_GIC, + CSU_CSLX_PCIE1, + CSU_CSLX_OCRAM2, + CSU_CSLX_QSPI_MEM, + CSU_CSLX_PCIE2, + CSU_CSLX_SATA, + CSU_CSLX_USB1, + CSU_CSLX_QM_BM_SWPORTAL, + CSU_CSLX_PCIE3 = 16, + CSU_CSLX_PCIE3_IO, + CSU_CSLX_USB3 = 20, + CSU_CSLX_USB2, + CSU_CSLX_PFE = 23, + CSU_CSLX_SERDES = 32, + CSU_CSLX_QDMA, + CSU_CSLX_LPUART2, + CSU_CSLX_LPUART1, + CSU_CSLX_LPUART4, + CSU_CSLX_LPUART3, + CSU_CSLX_LPUART6, + CSU_CSLX_LPUART5, + CSU_CSLX_DSPI1 = 41, + CSU_CSLX_QSPI, + CSU_CSLX_ESDHC, + CSU_CSLX_IFC = 45, + CSU_CSLX_I2C1, + CSU_CSLX_USB_2, + CSU_CSLX_I2C3 = 48, + CSU_CSLX_I2C2, + CSU_CSLX_DUART2 = 50, + CSU_CSLX_DUART1, + CSU_CSLX_WDT2, + CSU_CSLX_WDT1, + CSU_CSLX_EDMA, + CSU_CSLX_SYS_CNT, + CSU_CSLX_DMA_MUX2, + CSU_CSLX_DMA_MUX1, + CSU_CSLX_DDR, + CSU_CSLX_QUICC, + CSU_CSLX_DCFG_CCU_RCPM = 60, + CSU_CSLX_SECURE_BOOTROM, + CSU_CSLX_SFP, + CSU_CSLX_TMU, + CSU_CSLX_SECURE_MONITOR, + CSU_CSLX_SCFG, + CSU_CSLX_FM = 66, + CSU_CSLX_SEC5_5, + CSU_CSLX_BM, + CSU_CSLX_QM, + CSU_CSLX_GPIO2 = 70, + CSU_CSLX_GPIO1, + CSU_CSLX_GPIO4, + CSU_CSLX_GPIO3, + CSU_CSLX_PLATFORM_CONT, + CSU_CSLX_CSU, + CSU_CSLX_IIC4 = 77, + CSU_CSLX_WDT4, + CSU_CSLX_WDT3, + CSU_CSLX_ESDHC2 = 80, + CSU_CSLX_WDT5 = 81, + CSU_CSLX_SAI2, + CSU_CSLX_SAI1, + CSU_CSLX_SAI4, + CSU_CSLX_SAI3, + CSU_CSLX_FTM2 = 86, + CSU_CSLX_FTM1, + CSU_CSLX_FTM4, + CSU_CSLX_FTM3, + CSU_CSLX_FTM6 = 90, + CSU_CSLX_FTM5, + CSU_CSLX_FTM8, + CSU_CSLX_FTM7, + CSU_CSLX_DSCR = 121, +}; + +static struct csu_ns_dev ns_dev[] = { + {CSU_CSLX_PCIE2_IO, CSU_ALL_RW}, + {CSU_CSLX_PCIE1_IO, CSU_ALL_RW}, + {CSU_CSLX_MG2TPR_IP, CSU_ALL_RW}, + {CSU_CSLX_IFC_MEM, CSU_ALL_RW}, + {CSU_CSLX_OCRAM, CSU_ALL_RW}, + {CSU_CSLX_GIC, CSU_ALL_RW}, + {CSU_CSLX_PCIE1, CSU_ALL_RW}, + {CSU_CSLX_OCRAM2, CSU_ALL_RW}, + {CSU_CSLX_QSPI_MEM, CSU_ALL_RW}, + {CSU_CSLX_PCIE2, CSU_ALL_RW}, + {CSU_CSLX_SATA, CSU_ALL_RW}, + {CSU_CSLX_USB1, CSU_ALL_RW}, + {CSU_CSLX_QM_BM_SWPORTAL, CSU_ALL_RW}, + {CSU_CSLX_PCIE3, CSU_ALL_RW}, + {CSU_CSLX_PCIE3_IO, CSU_ALL_RW}, + {CSU_CSLX_USB3, CSU_ALL_RW}, + {CSU_CSLX_USB2, CSU_ALL_RW}, + {CSU_CSLX_PFE, CSU_ALL_RW}, + {CSU_CSLX_SERDES, CSU_ALL_RW}, + {CSU_CSLX_QDMA, CSU_ALL_RW}, + {CSU_CSLX_LPUART2, CSU_ALL_RW}, + {CSU_CSLX_LPUART1, CSU_ALL_RW}, + {CSU_CSLX_LPUART4, CSU_ALL_RW}, + {CSU_CSLX_LPUART3, CSU_ALL_RW}, + {CSU_CSLX_LPUART6, CSU_ALL_RW}, + {CSU_CSLX_LPUART5, CSU_ALL_RW}, + {CSU_CSLX_DSPI1, CSU_ALL_RW}, + {CSU_CSLX_QSPI, CSU_ALL_RW}, + {CSU_CSLX_ESDHC, CSU_ALL_RW}, + {CSU_CSLX_IFC, CSU_ALL_RW}, + {CSU_CSLX_I2C1, CSU_ALL_RW}, + {CSU_CSLX_USB_2, CSU_ALL_RW}, + {CSU_CSLX_I2C3, CSU_ALL_RW}, + {CSU_CSLX_I2C2, CSU_ALL_RW}, + {CSU_CSLX_DUART2, CSU_ALL_RW}, + {CSU_CSLX_DUART1, CSU_ALL_RW}, + {CSU_CSLX_WDT2, CSU_ALL_RW}, + {CSU_CSLX_WDT1, CSU_ALL_RW}, + {CSU_CSLX_EDMA, CSU_ALL_RW}, + {CSU_CSLX_SYS_CNT, CSU_ALL_RW}, + {CSU_CSLX_DMA_MUX2, CSU_ALL_RW}, + {CSU_CSLX_DMA_MUX1, CSU_ALL_RW}, + {CSU_CSLX_DDR, CSU_ALL_RW}, + {CSU_CSLX_QUICC, CSU_ALL_RW}, + {CSU_CSLX_DCFG_CCU_RCPM, CSU_ALL_RW}, + {CSU_CSLX_SECURE_BOOTROM, CSU_ALL_RW}, + {CSU_CSLX_SFP, CSU_ALL_RW}, + {CSU_CSLX_TMU, CSU_ALL_RW}, + {CSU_CSLX_SECURE_MONITOR, CSU_ALL_RW}, + {CSU_CSLX_SCFG, CSU_ALL_RW}, + {CSU_CSLX_FM, CSU_ALL_RW}, + {CSU_CSLX_SEC5_5, CSU_ALL_RW}, + {CSU_CSLX_BM, CSU_ALL_RW}, + {CSU_CSLX_QM, CSU_ALL_RW}, + {CSU_CSLX_GPIO2, CSU_ALL_RW}, + {CSU_CSLX_GPIO1, CSU_ALL_RW}, + {CSU_CSLX_GPIO4, CSU_ALL_RW}, + {CSU_CSLX_GPIO3, CSU_ALL_RW}, + {CSU_CSLX_PLATFORM_CONT, CSU_ALL_RW}, + {CSU_CSLX_CSU, CSU_ALL_RW}, + {CSU_CSLX_IIC4, CSU_ALL_RW}, + {CSU_CSLX_WDT4, CSU_ALL_RW}, + {CSU_CSLX_WDT3, CSU_ALL_RW}, + {CSU_CSLX_ESDHC2, CSU_ALL_RW}, + {CSU_CSLX_WDT5, CSU_ALL_RW}, + {CSU_CSLX_SAI2, CSU_ALL_RW}, + {CSU_CSLX_SAI1, CSU_ALL_RW}, + {CSU_CSLX_SAI4, CSU_ALL_RW}, + {CSU_CSLX_SAI3, CSU_ALL_RW}, + {CSU_CSLX_FTM2, CSU_ALL_RW}, + {CSU_CSLX_FTM1, CSU_ALL_RW}, + {CSU_CSLX_FTM4, CSU_ALL_RW}, + {CSU_CSLX_FTM3, CSU_ALL_RW}, + {CSU_CSLX_FTM6, CSU_ALL_RW}, + {CSU_CSLX_FTM5, CSU_ALL_RW}, + {CSU_CSLX_FTM8, CSU_ALL_RW}, + {CSU_CSLX_FTM7, CSU_ALL_RW}, + {CSU_CSLX_DSCR, CSU_ALL_RW}, +}; + +#endif diff --git a/plat/layerscape/board/ls1043/include/plat_macros.S b/plat/layerscape/board/ls1043/include/plat_macros.S new file mode 100644 index 0000000..8163dc1 --- /dev/null +++ b/plat/layerscape/board/ls1043/include/plat_macros.S @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLAT_MACROS_S__ +#define __PLAT_MACROS_S__ + + /* --------------------------------------------- + * The below required platform porting macro + * prints out relevant GIC and CCI registers + * whenever an unhandled exception is taken in + * BL31. + * Clobbers: x0 - x10, x16, x17, sp + * --------------------------------------------- + */ + .macro plat_crash_print_regs + .endm + +#endif /* __PLAT_MACROS_S__ */ diff --git a/plat/layerscape/board/ls1043/include/platform_def.h b/plat/layerscape/board/ls1043/include/platform_def.h new file mode 100644 index 0000000..0e1cae6 --- /dev/null +++ b/plat/layerscape/board/ls1043/include/platform_def.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLATFORM_DEF_H__ +#define __PLATFORM_DEF_H__ + +#include +#include +#include +#include "ls_def.h" + +#define FIRMWARE_WELCOME_STR_LS1043 "Welcome to LS1043 BL1 Phase\n" +#define FIRMWARE_WELCOME_STR_LS1043_BL2 "Welcome to LS1043 BL2 Phase\n" +#define FIRMWARE_WELCOME_STR_LS1043_BL31 "Welcome to LS1043 BL31 Phase\n" +#define FIRMWARE_WELCOME_STR_LS1043_BL32 "Welcome to LS1043 BL32 Phase, TSP\n" + +/* Required platform porting definitions */ +#define PLAT_PRIMARY_CPU 0x0 +#define PLAT_MAX_PWR_LVL LS_PWR_LVL1 +#define PLATFORM_CORE_COUNT 4 +#define COUNTER_FREQUENCY 25000000 /* 25MHz */ + +/* + * Required LS standard platform porting definitions + */ +#define PLAT_LS_CLUSTER_COUNT 1 +#define PLAT_LS1043_CCI_CLUSTER0_SL_IFACE_IX 4 +#define LS1043_CLUSTER_COUNT 1 +#define LS1043_MAX_CPUS_PER_CLUSTER 4 + +#define LS_DRAM1_BASE 0x80000000 +#define LS_DRAM2_BASE 0x880000000 +#define LS_DRAM2_SIZE 0x780000000 /* 30G */ +#define LS_DRAM1_SIZE 0x80000000 /* 2G */ +#define LS_NS_DRAM_BASE LS_DRAM1_BASE +/* 64M Secure Memory, in fact there a 2M non-secure hole on top of it */ +#define LS_SECURE_DRAM_SIZE (64 * 1024 * 1024) +#define LS_SECURE_DRAM_BASE (LS_NS_DRAM_BASE + LS_DRAM1_SIZE - \ + LS_SECURE_DRAM_SIZE) +#define LS_NS_DRAM_SIZE (LS_DRAM1_SIZE - LS_SECURE_DRAM_SIZE) + +/* + * By default, BL2 is in DDR memory. + * If LS_BL2_IN_OCRAM is defined, BL2 will in OCRAM + */ +/* #define LS_BL2_IN_OCRAM */ + +#ifndef LS_BL2_IN_OCRAM +/* + * on top of SECURE memory is 2M non-secure hole for OPTee, + * 1M secure memory below this hole will be used for BL2. + */ +#define LS_BL2_DDR_BASE (LS_SECURE_DRAM_BASE + \ + LS_SECURE_DRAM_SIZE \ + - 3 * 1024 * 1024) +#endif + +#define PLAT_LS_CCSR_BASE 0x1000000 +#define PLAT_LS_CCSR_SIZE 0xF000000 + +/* Flash base address, currently ROM is not used for TF-A images on LS platforms */ +#define PLAT_LS_TRUSTED_ROM_BASE 0x60100000 +#define PLAT_LS_TRUSTED_ROM_SIZE 0x20000000 /* Flash size */ +#define PLAT_LS_FLASH_SIZE 0x20000000 +#define PLAT_LS_FLASH_BASE 0x60000000 + +#define LS_SRAM_BASE 0x10000000 +#define LS_SRAM_LIMIT 0x10020000 /* 128K */ +#define LS_SRAM_SHARED_SIZE 0x1000 /* 4K */ +#define LS_SRAM_SIZE (LS_SRAM_LIMIT - LS_SRAM_BASE) +#define LS_BL_RAM_BASE (LS_SRAM_BASE + LS_SRAM_SHARED_SIZE) + +#define PLAT_LS_FIP_MAX_SIZE 0x4000000 + +/* Memory Layout */ + +#define BL1_RO_BASE PLAT_LS_TRUSTED_ROM_BASE +#define BL1_RO_LIMIT (PLAT_LS_TRUSTED_ROM_BASE \ + + PLAT_LS_TRUSTED_ROM_SIZE) +#define PLAT_LS_FIP_BASE 0x60120000 + +#ifdef LS_BL2_IN_OCRAM +/* BL2 is in OCRAM */ +#define PLAT_LS_MAX_BL1_RW_SIZE (52 * 1024) /* 52K */ +#define PLAT_LS_MAX_BL31_SIZE (64 * 1024) /* 64K */ +#define PLAT_LS_MAX_BL2_SIZE (44 * 1024) /* 44K */ +/* Reserve memory in OCRAM for BL31 Text and ROData segment */ +#define BL31_TEXT_RODATA_SIZE (32 * 1024) /* 32K */ +#else /* LS_BL2_IN_OCRAM */ +/* BL2 in DDR */ +#define PLAT_LS_MAX_BL1_RW_SIZE (64 * 1024) /* 64K */ +#define PLAT_LS_MAX_BL31_SIZE (64 * 1024) /* 64K */ +#define PLAT_LS_MAX_BL2_SIZE (1 * 1024 * 1024) /* 1M */ +#endif /* LS_BL2_IN_OCRAM */ +/* + * Put BL31 at the start of OCRAM. + */ +#define BL31_BASE LS_SRAM_BASE +#define BL31_LIMIT (LS_SRAM_BASE + PLAT_LS_MAX_BL31_SIZE) + +#ifdef LS_BL2_IN_OCRAM +/* + * BL2 follow BL31 Text and ROData region. + */ +#define BL2_BASE (BL31_BASE + BL31_TEXT_RODATA_SIZE) +#define BL2_LIMIT (BL2_BASE + PLAT_LS_MAX_BL2_SIZE) + +#else +/* + * BL2 in DDR memory. + */ +#define BL2_BASE LS_BL2_DDR_BASE +#define BL2_LIMIT (BL2_BASE + PLAT_LS_MAX_BL2_SIZE) + +#endif + +/* + * Put BL1 RW at the top of the Trusted SRAM. + */ +#ifdef LS_BL2_IN_OCRAM +#define BL1_RW_BASE BL2_LIMIT +#else +#define BL1_RW_BASE BL31_LIMIT +#endif +#define BL1_RW_LIMIT LS_SRAM_LIMIT + +/* Put BL32 in secure memory */ +#define BL32_BASE LS_SECURE_DRAM_BASE +#define BL32_LIMIT (LS_SECURE_DRAM_BASE + LS_SECURE_DRAM_SIZE) +/* BL33 memory region */ +#define BL33_BASE 0x82000000 +#define BL33_LIMIT (LS_NS_DRAM_BASE + LS_NS_DRAM_SIZE) + +/******************************************************************************* + * BL32 specific defines. + ******************************************************************************/ +/* + * On ARM standard platforms, the TSP can execute from Trusted SRAM, + * Trusted DRAM (if available) or the DRAM region secured by the TrustZone + * controller. + */ + +#define TSP_SEC_MEM_BASE BL32_BASE +#define TSP_SEC_MEM_SIZE (BL32_LIMIT - BL32_BASE) + +/* + * ID of the secure physical generic timer interrupt used by the TSP. + */ +#define TSP_IRQ_SEC_PHY_TIMER 29 + + +/* + * GIC related constants + */ +#define PLAT_LS1043_CCI_BASE 0x01180000 +#define GICD_BASE 0x01401000 +#define GICC_BASE 0x01402000 +#define GICD_BASE_64K 0x01410000 +#define GICC_BASE_64K 0x01420000 + +#define DCFG_CCSR_SVR 0x1ee00a4 +#define REV1_0 0x10 +#define REV1_1 0x11 +#define GIC_ADDR_BIT 31 +#define SCFG_GIC400_ALIGN 0x1570188 + +/* UART related definition */ + +#define PLAT_LS1043_DUART1_BASE 0x021c0000 +#define PLAT_LS1043_DUART2_BASE 0x021d0000 +#define PLAT_LS1043_DUART_SIZE 0x10000 + +#define PLAT_LS1043_UART_BASE 0x21c0500 +#define PLAT_LS1043_UART2_BASE 0x21c0600 +#define PLAT_LS1043_UART_CLOCK 400000000 +#define PLAT_LS1043_UART_BAUDRATE 115200 +/* Define UART to be used by TF-A log */ +#define LS_TF_UART_BASE PLAT_LS1043_UART_BASE +#define LS_TF_UART_CLOCK PLAT_LS1043_UART_CLOCK +#define LS_TF_UART_BAUDRATE PLAT_LS1043_UART_BAUDRATE + +#define LS1043_SYS_CNTCTL_BASE 0x2B00000 + +#define CONFIG_SYS_IMMR 0x01000000 +#define CONFIG_SYS_FSL_CSU_ADDR (CONFIG_SYS_IMMR + 0x00510000) + +/* Size of cacheable stacks */ +#if defined(IMAGE_BL1) +#define PLATFORM_STACK_SIZE 0x440 +#define MAX_MMAP_REGIONS 6 +#define MAX_XLAT_TABLES 4 +#elif defined(IMAGE_BL2) +#define PLATFORM_STACK_SIZE 0x400 +#define MAX_MMAP_REGIONS 8 +#define MAX_XLAT_TABLES 6 +#elif defined(IMAGE_BL31) +#define PLATFORM_STACK_SIZE 0x400 +#define MAX_MMAP_REGIONS 8 +#define MAX_XLAT_TABLES 4 +#elif defined(IMAGE_BL32) +#define PLATFORM_STACK_SIZE 0x440 +#define MAX_MMAP_REGIONS 8 +#define MAX_XLAT_TABLES 9 +#endif + +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +#endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/layerscape/board/ls1043/include/soc_tzasc.h b/plat/layerscape/board/ls1043/include/soc_tzasc.h new file mode 100644 index 0000000..0039f2d --- /dev/null +++ b/plat/layerscape/board/ls1043/include/soc_tzasc.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _SOC_TZASC_H_ +#define _SOC_TZASC_H_ + +#include "tzc380.h" + +#define MAX_NUM_TZC_REGION 3 + +/* TZASC related constants */ +#define TZASC_CONFIGURATION_REG 0x000 +#define TZASC_SECURITY_INV_REG 0x034 +#define TZASC_SECURITY_INV_EN 0x1 +#define TZASC_REGIONS_REG 0x100 +/* As region address should address atleast 32KB memory. */ +#define TZASC_REGION_LOWADDR_MASK 0xFFFF8000 +#define TZASC_REGION_LOWADDR_OFFSET 0x0 +#define TZASC_REGION_HIGHADDR_OFFSET 0x4 +#define TZASC_REGION_ATTR_OFFSET 0x8 +#define TZASC_REGION_ENABLED 1 +#define TZASC_REGION_DISABLED 0 +#define TZASC_REGION_SIZE_32KB 0xE +#define TZASC_REGION_SIZE_64KB 0xF +#define TZASC_REGION_SIZE_128KB 0x10 +#define TZASC_REGION_SIZE_256KB 0x11 +#define TZASC_REGION_SIZE_512KB 0x12 +#define TZASC_REGION_SIZE_1MB 0x13 +#define TZASC_REGION_SIZE_2MB 0x14 +#define TZASC_REGION_SIZE_4MB 0x15 +#define TZASC_REGION_SIZE_8MB 0x16 +#define TZASC_REGION_SIZE_16MB 0x17 +#define TZASC_REGION_SIZE_32MB 0x18 +#define TZASC_REGION_SIZE_64MB 0x19 +#define TZASC_REGION_SIZE_128MB 0x1A +#define TZASC_REGION_SIZE_256MB 0x1B +#define TZASC_REGION_SIZE_512MB 0x1C +#define TZASC_REGION_SIZE_1GB 0x1D +#define TZASC_REGION_SIZE_2GB 0x1E +#define TZASC_REGION_SIZE_4GB 0x1F +#define TZASC_REGION_SIZE_8GB 0x20 +#define TZASC_REGION_SIZE_16GB 0x21 +#define TZASC_REGION_SIZE_32GB 0x22 +#define TZASC_REGION_SECURITY_SR (1 << 3) +#define TZASC_REGION_SECURITY_SW (1 << 2) +#define TZASC_REGION_SECURITY_SRW (TZASC_REGION_SECURITY_SR| \ + TZASC_REGION_SECURITY_SW) +#define TZASC_REGION_SECURITY_NSR (1 << 1) +#define TZASC_REGION_SECURITY_NSW 1 +#define TZASC_REGION_SECURITY_NSRW (TZASC_REGION_SECURITY_NSR| \ + TZASC_REGION_SECURITY_NSW) + +#define CSU_SEC_ACCESS_REG_OFFSET 0x21C +#define TZASC_BYPASS_MUX_DISABLE 0x4 +#define CCI_TERMINATE_BARRIER_TX 0x8 +#define CONFIG_SYS_FSL_TZASC_ADDR 0x1500000 + +/* List of MAX_NUM_TZC_REGION TZC regions' boundaries and configurations. */ + +static const struct tzc380_reg tzc380_reg_list[] = { + { + TZASC_REGION_SECURITY_NSRW, /* .secure attr */ + 0x0, /* .enabled */ + 0x0, /* .lowaddr */ + 0x0, /* .highaddr */ + 0x0, /* .size */ + 0x0, /* .submask */ + }, + { + TZASC_REGION_SECURITY_SRW, + TZASC_REGION_ENABLED, + 0xFC000000, + 0x0, + TZASC_REGION_SIZE_64MB, + 0x80, /* Disable region 7 */ + }, + /* reserve 2M non-scure memory for OPTEE public memory */ + { + TZASC_REGION_SECURITY_SRW, + TZASC_REGION_ENABLED, + 0xFF800000, + 0x0, + TZASC_REGION_SIZE_8MB, + 0xC0, /* Disable region 6 & 7 */ + }, + + {} +}; + +#endif /* _SOC_TZASC_H_ */ diff --git a/plat/layerscape/board/ls1043/ls1043_bl1_setup.c b/plat/layerscape/board/ls1043/ls1043_bl1_setup.c new file mode 100644 index 0000000..e82a1fb --- /dev/null +++ b/plat/layerscape/board/ls1043/ls1043_bl1_setup.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include "plat_ls.h" + +static const int cci_map[] = { + PLAT_LS1043_CCI_CLUSTER0_SL_IFACE_IX +}; + +void bl1_platform_setup(void) +{ + NOTICE(FIRMWARE_WELCOME_STR_LS1043); + + ls_bl1_platform_setup(); + + /* + * Initialize system level generic timer for Layerscape Socs. + */ + ls_delay_timer_init(); + + /* TODO: remove these DDR code */ + VERBOSE("CS0_BNDS = %x\n", mmio_read_32(0x1080000 + 0x000)); + mmio_write_32(0x1080000 + 0x000, 0x7f000000); + VERBOSE("CS0_BNDS = %x\n", mmio_read_32(0x1080000 + 0x000)); +} + +/******************************************************************************* + * Perform any BL1 specific platform actions. + ******************************************************************************/ +void bl1_early_platform_setup(void) +{ + ls_bl1_early_platform_setup(); + + /* + * Initialize Interconnect for this cluster during cold boot. + * No need for locks as no other CPU is active. + */ + cci_init(PLAT_LS1043_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); + + /* + * Enable coherency in Interconnect for the primary CPU's cluster. + */ + cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); + +} + +unsigned int bl1_plat_get_next_image_id(void) +{ + return BL2_IMAGE_ID; +} diff --git a/plat/layerscape/board/ls1043/ls1043_bl2_setup.c b/plat/layerscape/board/ls1043/ls1043_bl2_setup.c new file mode 100644 index 0000000..b529aa5 --- /dev/null +++ b/plat/layerscape/board/ls1043/ls1043_bl2_setup.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include "plat_ls.h" + +void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + ls_bl2_early_platform_setup((meminfo_t *)arg1); + + /* + * Initialize system level generic timer for Layerscape Socs. + */ + ls_delay_timer_init(); +} + +void bl2_platform_setup(void) +{ + NOTICE(FIRMWARE_WELCOME_STR_LS1043_BL2); +} diff --git a/plat/layerscape/board/ls1043/ls1043_bl31_setup.c b/plat/layerscape/board/ls1043/ls1043_bl31_setup.c new file mode 100644 index 0000000..3473d98 --- /dev/null +++ b/plat/layerscape/board/ls1043/ls1043_bl31_setup.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include "plat_ls.h" +#include "fsl_csu.h" + +/* slave interfaces according to the RM */ +static const int cci_map[] = { + 4, +}; + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ +#ifdef LS_BL2_IN_OCRAM + unsigned long romem_base = (unsigned long)(&__TEXT_START__); + unsigned long romem_size = (unsigned long)(&__RODATA_END__) + - romem_base; + + /* Check the Text and RO-Data region size */ + if (romem_size > BL31_TEXT_RODATA_SIZE) { + ERROR("BL31 Text and RO-Data region size exceed reserved memory size\n"); + panic(); + } +#endif + + /* + * Initialize system level generic timer for Layerscape Socs. + */ + ls_delay_timer_init(); + + ls_bl31_early_platform_setup((void *)arg0, (void *)arg3); + + /* + * Initialize the correct interconnect for this cluster during cold + * boot. No need for locks as no other CPU is active. + */ + cci_init(PLAT_LS1043_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); + + /* + * Enable coherency in interconnect for the primary CPU's cluster. + * Earlier bootloader stages might already do this (e.g. Trusted + * Firmware's BL1 does it) but we can't assume so. There is no harm in + * executing this code twice anyway. + */ + cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); + + /* Init CSU to enable non-secure access to peripherals */ + enable_layerscape_ns_access(); +} diff --git a/plat/layerscape/board/ls1043/ls1043_err.c b/plat/layerscape/board/ls1043/ls1043_err.c new file mode 100644 index 0000000..e4a2cae --- /dev/null +++ b/plat/layerscape/board/ls1043/ls1043_err.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +/* + * Error handler + */ +void plat_error_handler(int err) +{ + switch (err) { + case -ENOENT: + case -EAUTH: + /* ToDo */ + break; + default: + /* Unexpected error */ + break; + } + + /* Loop until the watchdog resets the system */ + for (;;) + wfi(); +} diff --git a/plat/layerscape/board/ls1043/ls1043_psci.c b/plat/layerscape/board/ls1043/ls1043_psci.c new file mode 100644 index 0000000..a41e79e --- /dev/null +++ b/plat/layerscape/board/ls1043/ls1043_psci.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "platform_def.h" + +#define LS_SCFG_BASE 0x01570000 +/* register to store warm boot entry, big endian, higher 32bit */ +#define LS_SCFG_SCRATCHRW0_OFFSET 0x600 +/* register to store warm boot entry, big endian, lower 32bit */ +#define LS_SCFG_SCRATCHRW1_OFFSET 0x604 +#define LS_SCFG_COREBCR_OFFSET 0x680 + +#define LS_DCFG_BASE 0x01EE0000 +#define LS_DCFG_RSTCR_OFFSET 0x0B0 +#define LS_DCFG_RSTRQMR1_OFFSET 0x0C0 +#define LS_DCFG_BRR_OFFSET 0x0E4 + +#define LS_SCFG_CORE0_SFT_RST_OFFSET 0x130 +#define LS_SCFG_CORE1_SFT_RST_OFFSET 0x134 +#define LS_SCFG_CORE2_SFT_RST_OFFSET 0x138 +#define LS_SCFG_CORE3_SFT_RST_OFFSET 0x13C + +#define LS_SCFG_CORESRENCR_OFFSET 0x204 + +#define LS_SCFG_RVBAR0_0_OFFSET 0x220 +#define LS_SCFG_RVBAR0_1_OFFSET 0x224 + +#define LS_SCFG_RVBAR1_0_OFFSET 0x228 +#define LS_SCFG_RVBAR1_1_OFFSET 0x22C + +#define LS_SCFG_RVBAR2_0_OFFSET 0x230 +#define LS_SCFG_RVBAR2_1_OFFSET 0x234 + +#define LS_SCFG_RVBAR3_0_OFFSET 0x238 +#define LS_SCFG_RVBAR3_1_OFFSET 0x23C + +/* the entry for core warm boot */ +static uintptr_t warmboot_entry; + +/* warm reset single core */ +static void ls1043_reset_core(int core_pos) +{ + assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT); + + /* set 0 in RVBAR, boot from bootrom at 0x0 */ + mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_0_OFFSET + core_pos * 8, + 0); + mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_1_OFFSET + core_pos * 8, + 0); + + dsb(); + /* enable core soft reset */ + mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORESRENCR_OFFSET, + htobe32(1 << 31)); + dsb(); + isb(); + /* reset core */ + mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORE0_SFT_RST_OFFSET + + core_pos * 4, htobe32(1 << 31)); + mdelay(10); +} + +static void __dead2 ls1043_system_reset(void) +{ + /* clear reset request mask bits */ + mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTRQMR1_OFFSET, 0); + + /* set reset request bit */ + mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTCR_OFFSET, + htobe32((uint32_t)0x2)); + + /* system will reset; if fail, enter wfi */ + dsb(); + isb(); + wfi(); + + panic(); +} + + +static int ls1043_pwr_domain_on(u_register_t mpidr) +{ + int core_pos = plat_core_pos_by_mpidr(mpidr); + uint32_t core_mask = 1 << core_pos; + uint32_t brr; + + assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT); + + /* set warm boot entry */ + mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW0_OFFSET, + htobe32((uint32_t)(warmboot_entry >> 32))); + + mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW1_OFFSET, + htobe32((uint32_t)warmboot_entry)); + + dsb(); + + brr = be32toh(mmio_read_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET)); + if (brr & core_mask) { + /* core has been released, must reset it to restart */ + ls1043_reset_core(core_pos); + + /* set bit in core boot control register to enable boot */ + mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET, + htobe32(core_mask)); + + } else { + /* set bit in core boot control register to enable boot */ + mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET, + htobe32(core_mask)); + + /* release core */ + mmio_write_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET, + htobe32(brr | core_mask)); + } + + mdelay(20); + + /* wake core in case it is in wfe */ + dsb(); + isb(); + sev(); + + return PSCI_E_SUCCESS; +} + +static void ls1043_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* Per cpu gic distributor setup */ + gicv2_pcpu_distif_init(); + + /* Enable the gic CPU interface */ + gicv2_cpuif_enable(); +} + +static void ls1043_pwr_domain_off(const psci_power_state_t *target_state) +{ + /* Disable the gic CPU interface */ + gicv2_cpuif_disable(); +} + +static plat_psci_ops_t ls1043_psci_pm_ops = { + .system_reset = ls1043_system_reset, + .pwr_domain_on = ls1043_pwr_domain_on, + .pwr_domain_on_finish = ls1043_pwr_domain_on_finish, + .pwr_domain_off = ls1043_pwr_domain_off, +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + warmboot_entry = sec_entrypoint; + *psci_ops = &ls1043_psci_pm_ops; + return 0; +} diff --git a/plat/layerscape/board/ls1043/ls1043_security.c b/plat/layerscape/board/ls1043/ls1043_security.c new file mode 100644 index 0000000..18ae56e --- /dev/null +++ b/plat/layerscape/board/ls1043/ls1043_security.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "plat_ls.h" + +/* + * We assume that all security programming is done by the primary core. + */ +void plat_ls_security_setup(void) +{ + tzc380_setup(); +} diff --git a/plat/layerscape/board/ls1043/ls1043_stack_protector.c b/plat/layerscape/board/ls1043/ls1043_stack_protector.c new file mode 100644 index 0000000..50f463b --- /dev/null +++ b/plat/layerscape/board/ls1043/ls1043_stack_protector.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL) + +u_register_t plat_get_stack_protector_canary(void) +{ + /* + * Ideally, a random number should be returned instead of the + * combination of a timer's value and a compile-time constant. As the + * FVP does not have any random number generator, this is better than + * nothing but not necessarily really secure. + */ + return RANDOM_CANARY_VALUE ^ read_cntpct_el0(); +} diff --git a/plat/layerscape/board/ls1043/ls1043_topology.c b/plat/layerscape/board/ls1043/ls1043_topology.c new file mode 100644 index 0000000..12d2830 --- /dev/null +++ b/plat/layerscape/board/ls1043/ls1043_topology.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include "plat_ls.h" +#include "platform_def.h" + +unsigned char ls1043_power_domain_tree_desc[LS1043_CLUSTER_COUNT + 1]; + + +CASSERT(LS1043_CLUSTER_COUNT && LS1043_CLUSTER_COUNT <= 256, + assert_invalid_ls1043_cluster_count); + +/******************************************************************************* + * This function dynamically constructs the topology according to + * LS1043_CLUSTER_COUNT and returns it. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + int i; + + ls1043_power_domain_tree_desc[0] = LS1043_CLUSTER_COUNT; + + for (i = 0; i < LS1043_CLUSTER_COUNT; i++) + ls1043_power_domain_tree_desc[i + 1] = + LS1043_MAX_CPUS_PER_CLUSTER; + + return ls1043_power_domain_tree_desc; +} + +/******************************************************************************* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + ******************************************************************************/ +unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr) +{ + return LS1043_MAX_CPUS_PER_CLUSTER; +} + +/******************************************************************************* + * This function implements a part of the critical interface between the psci + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + ******************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + if (ls_check_mpidr(mpidr) == -1) + return -1; + + return plat_ls_calc_core_pos(mpidr); +} diff --git a/plat/layerscape/board/ls1043/ls_gic.c b/plat/layerscape/board/ls1043/ls_gic.c new file mode 100644 index 0000000..3986153 --- /dev/null +++ b/plat/layerscape/board/ls1043/ls_gic.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include "platform_def.h" +#include "soc.h" + +/* + * Get GIC offset + * For LS1043a rev1.0, GIC base address align with 4k. + * For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT] + * is set, GIC base address align with 4K, or else align + * with 64k. + */ +void get_gic_offset(uint32_t *gicc_base, uint32_t *gicd_base) +{ + + uint32_t *ccsr_svr = (uint32_t *)DCFG_CCSR_SVR; + uint32_t *gic_align = (uint32_t *)SCFG_GIC400_ALIGN; + uint32_t val; + uint32_t soc_dev_id; + + val = be32toh(mmio_read_32((uintptr_t)ccsr_svr)); + soc_dev_id = val & (SVR_WO_E << 8); + + if ((soc_dev_id == (SVR_LS1043A << 8) || + soc_dev_id == (SVR_LS1043AE << 8)) && + ((val & 0xff) == REV1_1)) { + val = be32toh(mmio_read_32((uintptr_t)gic_align)); + if (val & (1 << GIC_ADDR_BIT)) { + *gicc_base = GICC_BASE; + *gicd_base = GICD_BASE; + } else { + *gicc_base = GICC_BASE_64K; + *gicd_base = GICD_BASE_64K; + } + } else { + *gicc_base = GICC_BASE; + *gicd_base = GICD_BASE; + } +} diff --git a/plat/layerscape/board/ls1043/platform.mk b/plat/layerscape/board/ls1043/platform.mk new file mode 100644 index 0000000..163d25e --- /dev/null +++ b/plat/layerscape/board/ls1043/platform.mk @@ -0,0 +1,80 @@ +# +# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# indicate the reset vector address can be programmed +PROGRAMMABLE_RESET_ADDRESS := 1 +USE_COHERENT_MEM := 0 +RESET_TO_BL31 := 0 +ENABLE_STACK_PROTECTOR := 0 +LS1043_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c \ + plat/layerscape/board/ls1043/ls_gic.c + + +LS1043_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c + +LS1043_SECURITY_SOURCES := plat/layerscape/common/ls_tzc380.c \ + plat/layerscape/board/ls1043/ls1043_security.c + +PLAT_INCLUDES := -Iplat/layerscape/board/ls1043/include \ + -Iinclude/plat/arm/common \ + -Iplat/layerscape/common/include \ + -Iinclude/drivers/arm \ + -Iinclude/lib \ + -Iinclude/drivers/io + + +PLAT_BL_COMMON_SOURCES := drivers/console/aarch64/console.S \ + plat/layerscape/common/aarch64/ls_console.S + +LS1043_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S + +LS1043_CPU_LIBS += lib/cpus/aarch64/cortex_a53.S + +BL1_SOURCES += plat/layerscape/board/ls1043/ls1043_bl1_setup.c \ + plat/layerscape/board/ls1043/ls1043_err.c \ + drivers/delay_timer/delay_timer.c \ + +BL1_SOURCES += plat/layerscape/board/ls1043/${ARCH}/ls1043_helpers.S \ + ${LS1043_CPU_LIBS} \ + ${LS1043_INTERCONNECT_SOURCES} \ + $(LS1043_SECURITY_SOURCES) + + +BL2_SOURCES += drivers/delay_timer/delay_timer.c \ + plat/layerscape/board/ls1043/ls1043_bl2_setup.c \ + plat/layerscape/board/ls1043/ls1043_err.c \ + ${LS1043_SECURITY_SOURCES} + + +BL31_SOURCES += plat/layerscape/board/ls1043/ls1043_bl31_setup.c \ + plat/layerscape/board/ls1043/ls1043_topology.c \ + plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S \ + plat/layerscape/board/ls1043/ls1043_psci.c \ + drivers/delay_timer/delay_timer.c \ + ${LS1043_CPU_LIBS} \ + ${LS1043_GIC_SOURCES} \ + ${LS1043_INTERCONNECT_SOURCES} \ + ${LS1043_SECURITY_SOURCES} + +# Disable the PSCI platform compatibility layer +ENABLE_PLAT_COMPAT := 0 +MULTI_CONSOLE_API := 1 + +# Enable workarounds for selected Cortex-A53 erratas. +ERRATA_A53_855873 := 1 + +ifneq (${ENABLE_STACK_PROTECTOR},0) +PLAT_BL_COMMON_SOURCES += plat/layerscape/board/ls1043/ls1043_stack_protector.c +endif + +ifeq (${ARCH},aarch32) + NEED_BL32 := yes +endif + +include plat/layerscape/common/ls_common.mk diff --git a/plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c b/plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c new file mode 100644 index 0000000..4fc019c --- /dev/null +++ b/plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "plat_ls.h" + +void tsp_early_platform_setup(void) +{ + ls_tsp_early_platform_setup(); + + /*Todo: Initialize the platform config for future decision making */ +} diff --git a/plat/layerscape/board/ls1043/tsp/tsp-ls1043.mk b/plat/layerscape/board/ls1043/tsp/tsp-ls1043.mk new file mode 100644 index 0000000..3941427 --- /dev/null +++ b/plat/layerscape/board/ls1043/tsp/tsp-ls1043.mk @@ -0,0 +1,12 @@ +# +# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# TSP source files specific to FVP platform +BL32_SOURCES += plat/layerscape/board/ls1043/ls1043_topology.c \ + plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c \ + ${LS1043_GIC_SOURCES} + +include plat/layerscape/common/tsp/ls_tsp.mk diff --git a/plat/layerscape/common/aarch64/ls_bl2_mem_params_desc.c b/plat/layerscape/common/aarch64/ls_bl2_mem_params_desc.c new file mode 100644 index 0000000..a96e390 --- /dev/null +++ b/plat/layerscape/common/aarch64/ls_bl2_mem_params_desc.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +/******************************************************************************* + * Following descriptor provides BL image/ep information that gets used + * by BL2 to load the images and also subset of this information is + * passed to next BL image. The image loading sequence is managed by + * populating the images in required loading order. The image execution + * sequence is managed by populating the `next_handoff_image_id` with + * the next executable image id. + ******************************************************************************/ +static bl_mem_params_node_t bl2_mem_params_descs[] = { +#ifdef EL3_PAYLOAD_BASE + /* Fill EL3 payload related information (BL31 is EL3 payload)*/ + { + .image_id = BL31_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + .ep_info.pc = EL3_PAYLOAD_BASE, + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_PLAT_SETUP | + IMAGE_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + +#else /* EL3_PAYLOAD_BASE */ + + /* Fill BL31 related information */ + { + .image_id = BL31_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + .ep_info.pc = BL31_BASE, + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), +#if DEBUG + .ep_info.args.arg1 = LS_BL31_PLAT_PARAM_VAL, +#endif + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP), + .image_info.image_base = BL31_BASE, + .image_info.image_max_size = (BL31_LIMIT - BL31_BASE), + +# ifdef BL32_BASE + .next_handoff_image_id = BL32_IMAGE_ID, +# else + .next_handoff_image_id = BL33_IMAGE_ID, +# endif + }, +# ifdef BL32_BASE + /* Fill BL32 related information */ + { + .image_id = BL32_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, SECURE | EXECUTABLE), + .ep_info.pc = BL32_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = BL32_BASE, + .image_info.image_max_size = (BL32_LIMIT - BL32_BASE), + + .next_handoff_image_id = BL33_IMAGE_ID, + }, +# endif /* BL32_BASE */ + + /* Fill BL33 related information */ + { + .image_id = BL33_IMAGE_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE), +# ifdef PRELOADED_BL33_BASE + .ep_info.pc = PRELOADED_BL33_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), +# else + .ep_info.pc = BL33_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = BL33_BASE, + .image_info.image_max_size = LS_NS_DRAM_SIZE, +# endif /* PRELOADED_BL33_BASE */ + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +#endif /* EL3_PAYLOAD_BASE */ +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/layerscape/common/aarch64/ls_console.S b/plat/layerscape/common/aarch64/ls_console.S new file mode 100644 index 0000000..5c87465 --- /dev/null +++ b/plat/layerscape/common/aarch64/ls_console.S @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include "ls_16550.h" + + /* + * "core" functions are low-level implementations that don't require + * writable memory and are thus safe to call in BL1 crash context. + */ + .globl console_ls_16550_core_init + .globl console_ls_16550_core_putc + .globl console_ls_16550_core_getc + + .globl console_ls_16550_putc + .globl console_ls_16550_getc + .globl console_ls_16550_flush + + /* ----------------------------------------------- + * int console_ls_16550_core_init(uintptr_t base_addr, + * unsigned int uart_clk, unsigned int baud_rate) + * Function to initialize the console without a + * C Runtime to print debug information. This + * function will be accessed by console_init and + * crash reporting. + * In: x0 - console base address + * w1 - Uart clock in Hz + * w2 - Baud rate + * Out: return 1 on success, 0 on error + * Clobber list : x1, x2, x3 + * ----------------------------------------------- + */ +func console_ls_16550_core_init + /* Check the input base address */ + cbz x0, init_fail + /* Check baud rate and uart clock for sanity */ + cbz w1, init_fail + cbz w2, init_fail + + /* Program the baudrate */ + /* Divisor = Uart clock / (16 * baudrate) */ + lsl w2, w2, #4 + udiv w2, w1, w2 + and w1, w2, #0xff /* w1 = DLL */ + lsr w2, w2, #8 + and w2, w2, #0xff /* w2 = DLLM */ + ldrb w3, [x0, #UARTLCR] + orr w3, w3, #UARTLCR_DLAB + strb w3, [x0, #UARTLCR] /* enable DLL, DLLM programming */ + strb w1, [x0, #UARTDLL] /* program DLL */ + strb w2, [x0, #UARTDLLM] /* program DLLM */ + mov w2, #~UARTLCR_DLAB + and w3, w3, w2 + strb w3, [x0, #UARTLCR] /* disable DLL, DLLM programming */ + + /* 8n1 */ + mov w3, #3 + strb w3, [x0, #UARTLCR] + /* no interrupt */ + mov w3, #0 + strb w3, [x0, #UARTIER] + /* enable fifo, DMA */ + mov w3, #(UARTFCR_FIFOEN |UARTFCR_TXCLR | UARTFCR_RXCLR) + strb w3, [x0, #UARTFCR] + /* DTR + RTS */ + mov w3, #3 + str w3, [x0, #UARTMCR] + mov w0, #1 + ret +init_fail: + mov w0, #0 + ret +endfunc console_ls_16550_core_init + +#if MULTI_CONSOLE_API + .globl console_ls_16550_register + + /* ----------------------------------------------- + * int console_ls_16550_register(console_ls_16550_t *console, + * uintptr_t base, uint32_t clk, uint32_t baud) + * Function to initialize and register a new 16550 + * console. Storage passed in for the console struct + * *must* be persistent (i.e. not from the stack). + * In: x0 - UART register base address + * w1 - UART clock in Hz + * w2 - Baud rate + * x3 - pointer to empty console_ls_16550_t struct + * Out: return 1 on success, 0 on error + * Clobber list : x0, x1, x2, x6, x7, x14 + * ----------------------------------------------- + */ +func console_ls_16550_register + mov x7, x30 + mov x6, x3 + cbz x6, register_fail + str x0, [x6, #CONSOLE_T_16550_BASE] + + bl console_ls_16550_core_init + cbz x0, register_fail + + mov x0, x6 + mov x30, x7 + finish_console_register ls_16550 + +register_fail: + ret x7 +endfunc console_ls_16550_register +#else + .globl console_core_init + .globl console_core_putc + .globl console_core_getc + .globl console_core_flush + .equ console_core_init,console_ls_16550_core_init + .equ console_core_putc,console_ls_16550_core_putc + .equ console_core_getc,console_ls_16550_core_getc + .equ console_core_flush,console_ls_16550_core_flush +#endif + + /* -------------------------------------------------------- + * int console_ls_16550_core_putc(int c, uintptr_t base_addr) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - console base address + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_ls_16550_core_putc +#if ENABLE_ASSERTIONS + cmp x1, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ + + /* Prepend '\r' to '\n' */ + cmp w0, #0xA //'\n' + b.ne 2f + /* Check if the transmit FIFO is full */ +1: ldrb w2, [x1, #UARTLSR] + and w2, w2, #UARTLSR_THRE /* #(UARTLSR_TEMT | UARTLSR_THRE)*/ + cmp w2, #(UARTLSR_THRE) + b.ne 1b + mov w2, #0xD /* '\r' */ + strb w2, [x1, #UARTTX] + ldrb w2, [x1, #UARTFCR] + orr w2, w2, #UARTFCR_TXCLR + + /* Check if the transmit FIFO is full */ +2: ldrb w2, [x1, #UARTLSR] + and w2, w2, #(UARTLSR_THRE) + cmp w2, #(UARTLSR_THRE) + b.ne 2b + strb w0, [x1, #UARTTX] + ret +endfunc console_ls_16550_core_putc + + /* -------------------------------------------------------- + * int console_16550_putc(int c, console_ls_16550_t *console) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - pointer to console_t structure + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_ls_16550_putc +#if ENABLE_ASSERTIONS + cmp x1, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ + ldr x1, [x1, #CONSOLE_T_16550_BASE] + b console_ls_16550_core_putc +endfunc console_ls_16550_putc + + /* --------------------------------------------- + * int console_ls_16550_core_getc(uintptr_t base_addr) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 on if no character is available. + * In : x0 - console base address + * Out : w0 - character if available, else -1 + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_ls_16550_core_getc +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ + + /* Check if the receive FIFO is empty */ +1: ldrb w1, [x0, #UARTLSR] + tbz w1, #UARTLSR_RDR, 1b + ldrb w0, [x0, #UARTRX] + ret +no_char: + mov w0, #ERROR_NO_PENDING_CHAR + ret +endfunc console_ls_16550_core_getc + + /* --------------------------------------------- + * int console_ls_16550_getc(console_ls_16550_t *console) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 on if no character is available. + * In : x0 - pointer to console_t structure + * Out : w0 - character if available, else -1 + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_ls_16550_getc +#if ENABLE_ASSERTIONS + cmp x1, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ + ldr x0, [x0, #CONSOLE_T_16550_BASE] + b console_ls_16550_core_getc +endfunc console_ls_16550_getc + + /* --------------------------------------------- + * int console_ls_16550_core_flush(uintptr_t base_addr) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - console base address + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_ls_16550_core_flush +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ + + /* Loop until the transmit FIFO is empty */ +1: ldrb w1, [x0, #UARTLSR] + and w1, w1, #(UARTLSR_TEMT | UARTLSR_THRE) + cmp w1, #(UARTLSR_TEMT | UARTLSR_THRE) + b.ne 1b + + mov w0, #0 + ret +endfunc console_ls_16550_core_flush + + /* --------------------------------------------- + * int console_ls_16550_flush(console_ls_16550_t *console) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - pointer to console_t structure + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_ls_16550_flush +#if ENABLE_ASSERTIONS + cmp x0, #0 + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ + ldr x0, [x0, #CONSOLE_T_16550_BASE] + b console_ls_16550_core_flush +endfunc console_ls_16550_flush diff --git a/plat/layerscape/common/aarch64/ls_helpers.S b/plat/layerscape/common/aarch64/ls_helpers.S new file mode 100644 index 0000000..7d71f48 --- /dev/null +++ b/plat/layerscape/common/aarch64/ls_helpers.S @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .weak plat_my_core_pos + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl plat_crash_console_flush + .weak platform_mem_init + .globl plat_ls_calc_core_pos + + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void) + * This function uses the plat_ls_calc_core_pos() + * definition to get the index of the calling CPU. + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_ls_calc_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_ls_calc_core_pos(u_register_t mpidr) + * Helper function to calculate the core position. + * With this function: CorePos = (ClusterId * 4) + + * CoreId + * ----------------------------------------------------- + */ +func plat_ls_calc_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret +endfunc plat_ls_calc_core_pos + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * Function to initialize the crash console + * without a C Runtime to print crash report. + * Clobber list : x0 - x4 + * --------------------------------------------- + */ + +#if MULTI_CONSOLE_API + /* ----------------------------------------------------- + * int plat_crash_console_init(void) + * Use normal console by default. Switch it to crash + * mode so serial consoles become active again. + * NOTE: This default implementation will only work for + * crashes that occur after a normal console (marked + * valid for the crash state) has been registered with + * the console framework. To debug crashes that occur + * earlier, the platform has to override these functions + * with an implementation that initializes a console + * driver with hardcoded parameters. See + * docs/porting-guide.rst for more information. + * ----------------------------------------------------- + */ +func plat_crash_console_init +#if defined(IMAGE_BL1) + /* + * BL1 code can possibly crash so early that the data segment is not yet + * accessible. Don't risk undefined behavior by trying to run the normal + * console framework. Platforms that want to debug BL1 will need to + * override this with custom functions that can run from registers only. + */ + mov x0, #0 + ret +#else /* IMAGE_BL1 */ + mov x3, x30 + mov x0, #CONSOLE_FLAG_CRASH + bl console_switch_state + mov x0, #1 + ret x3 +#endif +endfunc plat_crash_console_init + + /* ----------------------------------------------------- + * void plat_crash_console_putc(int character) + * Output through the normal console by default. + * ----------------------------------------------------- + */ +func plat_crash_console_putc + b console_putc +endfunc plat_crash_console_putc + + /* ----------------------------------------------------- + * void plat_crash_console_flush(void) + * Flush normal console by default. + * ----------------------------------------------------- + */ +func plat_crash_console_flush + b console_flush +endfunc plat_crash_console_flush + +#else /* MULTI_CONSOLE_API */ + + /* ----------------------------------------------------- + * In the old API these are all no-op stubs that need to + * be overridden by the platform to be useful. + * ----------------------------------------------------- + */ +func plat_crash_console_init + mov_imm x0, PLAT_LS1043_UART_BASE + mov_imm x1, PLAT_LS1043_UART_CLOCK + mov_imm x2, PLAT_LS1043_UART_BAUDRATE + b console_core_init +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(int c) + * Function to print a character on the crash + * console without a C Runtime. + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_putc + mov_imm x1, PLAT_LS1043_UART_BASE + b console_core_putc +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * int plat_crash_console_flush() + * Function to force a write of all buffered + * data that hasn't been output. + * Out : return -1 on error else return 0. + * Clobber list : r0 - r1 + * --------------------------------------------- + */ +func plat_crash_console_flush + mov_imm x1, PLAT_LS1043_UART_BASE + b console_core_flush +endfunc plat_crash_console_flush +#endif + /* --------------------------------------------------------------------- + * We don't need to carry out any memory initialization on LS + * platforms. The Secure SRAM is accessible straight away. + * --------------------------------------------------------------------- + */ +func platform_mem_init + ret +endfunc platform_mem_init diff --git a/plat/layerscape/common/include/fsl_csu.h b/plat/layerscape/common/include/fsl_csu.h new file mode 100644 index 0000000..680911e --- /dev/null +++ b/plat/layerscape/common/include/fsl_csu.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __FSL_CSU_H__ +#define __FSL_CSU_H__ + +enum csu_cslx_access { + CSU_NS_SUP_R = 0x08, + CSU_NS_SUP_W = 0x80, + CSU_NS_SUP_RW = 0x88, + CSU_NS_USER_R = 0x04, + CSU_NS_USER_W = 0x40, + CSU_NS_USER_RW = 0x44, + CSU_S_SUP_R = 0x02, + CSU_S_SUP_W = 0x20, + CSU_S_SUP_RW = 0x22, + CSU_S_USER_R = 0x01, + CSU_S_USER_W = 0x10, + CSU_S_USER_RW = 0x11, + CSU_ALL_RW = 0xff, +}; + +struct csu_ns_dev { + uintptr_t ind; + uint32_t val; +}; + +void enable_layerscape_ns_access(void); + +#endif diff --git a/plat/layerscape/common/include/ls_16550.h b/plat/layerscape/common/include/ls_16550.h new file mode 100644 index 0000000..503a01d --- /dev/null +++ b/plat/layerscape/common/include/ls_16550.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __LS_16550_H__ +#define __LS_16550_H__ + +#include + +/* UART16550 Registers */ +#define UARTTX 0x0 +#define UARTRX 0x0 +#define UARTDLL 0x0 +#define UARTIER 0x1 +#define UARTDLLM 0x1 +#define UARTFCR 0x2 +#define UARTLCR 0x3 +#define UARTLSR 0x5 +#define UARTMCR 0x4 + +/* FIFO Control Register bits */ +#define UARTFCR_FIFOMD_16450 (0 << 6) +#define UARTFCR_FIFOMD_16550 (1 << 6) +#define UARTFCR_RXTRIG_1 (0 << 6) +#define UARTFCR_RXTRIG_4 (1 << 6) +#define UARTFCR_RXTRIG_8 (2 << 6) +#define UARTFCR_RXTRIG_16 (3 << 6) +#define UARTFCR_TXTRIG_1 (0 << 4) +#define UARTFCR_TXTRIG_4 (1 << 4) +#define UARTFCR_TXTRIG_8 (2 << 4) +#define UARTFCR_TXTRIG_16 (3 << 4) +#define UARTFCR_DMAEN (1 << 3) /* Enable DMA mode */ +#define UARTFCR_TXCLR (1 << 2) /* Clear contents of Tx FIFO */ +#define UARTFCR_RXCLR (1 << 1) /* Clear contents of Rx FIFO */ +#define UARTFCR_FIFOEN (1 << 0) /* Enable the Tx/Rx FIFO */ +#define UARTFCR_64FIFO (1 << 5) + +/* Line Control Register bits */ +#define UARTLCR_DLAB (1 << 7) /* Divisor Latch Access */ +#define UARTLCR_SETB (1 << 6) /* Set BREAK Condition */ +#define UARTLCR_SETP (1 << 5) /* Set Parity to LCR[4] */ +#define UARTLCR_EVEN (1 << 4) /* Even Parity Format */ +#define UARTLCR_PAR (1 << 3) /* Parity */ +#define UARTLCR_STOP (1 << 2) /* Stop Bit */ +#define UARTLCR_WORDSZ_5 0 /* Word Length of 5 */ +#define UARTLCR_WORDSZ_6 1 /* Word Length of 6 */ +#define UARTLCR_WORDSZ_7 2 /* Word Length of 7 */ +#define UARTLCR_WORDSZ_8 3 /* Word Length of 8 */ + +/* Line Status Register bits */ +#define UARTLSR_RXFIFOEMT (1 << 9) /* Rx Fifo Empty */ +#define UARTLSR_TXFIFOFULL (1 << 8) /* Tx Fifo Full */ +#define UARTLSR_RXFIFOERR (1 << 7) /* Rx Fifo Error */ +#define UARTLSR_TEMT (1 << 6) /* Tx Shift Register Empty */ +#define UARTLSR_THRE (1 << 5) /* Tx Holding Register Empty */ +#define UARTLSR_BRK (1 << 4) /* Break Condition Detected */ +#define UARTLSR_FERR (1 << 3) /* Framing Error */ +#define UARTLSR_PERR (1 << 3) /* Parity Error */ +#define UARTLSR_OVRF (1 << 2) /* Rx Overrun Error */ +#define UARTLSR_RDR (1 << 2) /* Rx Data Ready */ + +#define CONSOLE_T_16550_BASE CONSOLE_T_DRVDATA + +#ifndef __ASSEMBLY__ + +#include + +typedef struct { + console_t console; + uintptr_t base; +} console_ls_16550_t; + +/* + * Initialize a new 16550 console instance and register it with the console + * framework. The |console| pointer must point to storage that will be valid + * for the lifetime of the console, such as a global or static local variable. + * Its contents will be reinitialized from scratch. + */ +int console_ls_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, + console_ls_16550_t *console); + +#endif /*__ASSEMBLY__*/ + +#endif /* __LS_16550_H__ */ diff --git a/plat/layerscape/common/include/plat_ls.h b/plat/layerscape/common/include/plat_ls.h new file mode 100644 index 0000000..9d5ec14 --- /dev/null +++ b/plat/layerscape/common/include/plat_ls.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLAT_LS_H__ +#define __PLAT_LS_H__ + +#include +#include + +/* BL1 utility functions */ +void ls_bl1_platform_setup(void); +void ls_bl1_early_platform_setup(void); + +/* BL2 utility functions */ +void ls_bl2_early_platform_setup(meminfo_t *mem_layout); +uint32_t ls_get_spsr_for_bl32_entry(void); +uint32_t ls_get_spsr_for_bl33_entry(void); + +/* BL3 utility functions */ +void ls_bl31_early_platform_setup(void *from_bl2, + void *plat_params_from_bl2); + +/* IO storage utility functions */ +void plat_ls_io_setup(void); + + +void ls_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit +#if USE_COHERENT_MEM + , uintptr_t coh_start, + uintptr_t coh_limit +#endif +); + +/* PSCI utility functions */ +int ls_check_mpidr(u_register_t mpidr); + +/* Security utility functions */ +int tzc380_setup(void); + +/* Timer utility functions */ +uint64_t ls_get_timer(uint64_t start); +void ls_delay_timer_init(void); + +/* TSP utility functions */ +void ls_tsp_early_platform_setup(void); + +/* Helper functions */ +unsigned int plat_ls_calc_core_pos(u_register_t mpidr); + +/* others */ +unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr); + +#endif /* __PLAT_LS_H__ */ diff --git a/plat/layerscape/common/include/soc.h b/plat/layerscape/common/include/soc.h new file mode 100644 index 0000000..72c10cf --- /dev/null +++ b/plat/layerscape/common/include/soc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __LAYERSCAPE_SOC_H__ +#define __LAYERSCAPE_SOC_H__ + +#include + +#define SVR_WO_E 0xFFFFFE +#define SVR_LS1043A 0x879204 +#define SVR_LS1043AE 0x879200 + +void get_gic_offset(uint32_t *gicc_base, uint32_t *gicd_base); + +#endif /* __LAYERSCAPE_SOC_H__ */ diff --git a/plat/layerscape/common/include/tzc380.h b/plat/layerscape/common/include/tzc380.h new file mode 100644 index 0000000..788c0ed --- /dev/null +++ b/plat/layerscape/common/include/tzc380.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __TZC380_H__ +#define __TZC380_H__ + +struct tzc380_reg { + unsigned int secure; + unsigned int enabled; + unsigned int low_addr; + unsigned int high_addr; + unsigned int size; + unsigned int sub_mask; +}; + +#endif /* __TZC380_H__ */ diff --git a/plat/layerscape/common/ls_bl1_setup.c b/plat/layerscape/common/ls_bl1_setup.c new file mode 100644 index 0000000..43f7450 --- /dev/null +++ b/plat/layerscape/common/ls_bl1_setup.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "ls_16550.h" +#include "plat_ls.h" +#include "../../../bl1/bl1_private.h" + +/* Data structure which holds the extents of the trusted SRAM for BL1*/ +static meminfo_t bl1_tzram_layout; + +meminfo_t *bl1_plat_sec_mem_layout(void) +{ + return &bl1_tzram_layout; +} + +/******************************************************************************* + * BL1 specific platform actions shared between ARM standard platforms. + ******************************************************************************/ +void ls_bl1_early_platform_setup(void) +{ + static console_ls_16550_t console; + +#if !LS1043_DISABLE_TRUSTED_WDOG + /* TODO: Enable watchdog */ + +#endif + + /* Initialize the console to provide early debug support */ + console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK, + LS_TF_UART_BAUDRATE, &console); + + /* Allow BL1 to see the whole Trusted RAM */ + bl1_tzram_layout.total_base = LS_SRAM_BASE; + bl1_tzram_layout.total_size = LS_SRAM_SIZE; +} + +/****************************************************************************** + * Perform the very early platform specific architecture setup shared between + * ARM standard platforms. This only does basic initialization. Later + * architectural setup (bl1_arch_setup()) does not do anything platform + * specific. + *****************************************************************************/ +void ls_bl1_plat_arch_setup(void) +{ + ls_setup_page_tables(bl1_tzram_layout.total_base, + bl1_tzram_layout.total_size, + BL_CODE_BASE, + BL1_CODE_END, + BL1_RO_DATA_BASE, + BL1_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + VERBOSE("After setup the page tables\n"); +#ifdef AARCH32 + enable_mmu_secure(0); +#else + enable_mmu_el3(0); +#endif /* AARCH32 */ + VERBOSE("After MMU enabled\n"); +} + +void bl1_plat_arch_setup(void) +{ + ls_bl1_plat_arch_setup(); +} + +/* + * Perform the platform specific architecture setup shared between + * ARM standard platforms. + */ +void ls_bl1_platform_setup(void) +{ + /* Initialise the IO layer and register platform IO devices */ + plat_ls_io_setup(); +} + +void bl1_plat_prepare_exit(entry_point_info_t *ep_info) +{ +#if !LS1043_DISABLE_TRUSTED_WDOG + /*TODO: Disable watchdog before leaving BL1 */ +#endif +} diff --git a/plat/layerscape/common/ls_bl2_setup.c b/plat/layerscape/common/ls_bl2_setup.c new file mode 100644 index 0000000..6e6ad6e --- /dev/null +++ b/plat/layerscape/common/ls_bl2_setup.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include "ls_16550.h" +#include "plat_ls.h" +#include "ls_def.h" + +/* Data structure which holds the extents of the trusted SRAM for BL2 */ +static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); + +/******************************************************************************* + * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 + * in x0. This memory layout is sitting at the base of the free trusted SRAM. + * Copy it to a safe location before its reclaimed by later BL2 functionality. + ******************************************************************************/ +void ls_bl2_early_platform_setup(meminfo_t *mem_layout) +{ + static console_ls_16550_t console; + + /* Initialize the console to provide early debug support */ + console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK, + LS_TF_UART_BAUDRATE, &console); + + /* Setup the BL2 memory layout */ + bl2_tzram_layout = *mem_layout; + + /* Initialise the IO layer and register platform IO devices */ + plat_ls_io_setup(); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only initializes the mmu in a quick and dirty way. + ******************************************************************************/ +void ls_bl2_plat_arch_setup(void) +{ + ls_setup_page_tables(bl2_tzram_layout.total_base, + bl2_tzram_layout.total_size, + BL_CODE_BASE, + BL_CODE_END, + BL_RO_DATA_BASE, + BL_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + +#ifdef AARCH32 + enable_mmu_secure(0); +#else + enable_mmu_el1(0); +#endif +} + +void bl2_plat_arch_setup(void) +{ + ls_bl2_plat_arch_setup(); +} + +int ls_bl2_handle_post_image_load(unsigned int image_id) +{ + int err = 0; + bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); + + assert(bl_mem_params); + + switch (image_id) { +#ifdef AARCH64 + case BL32_IMAGE_ID: + bl_mem_params->ep_info.spsr = ls_get_spsr_for_bl32_entry(); + break; +#endif + + case BL33_IMAGE_ID: + /* BL33 expects to receive the primary CPU MPID (through r0) */ + bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); + bl_mem_params->ep_info.spsr = ls_get_spsr_for_bl33_entry(); + break; + } + + return err; +} + +/******************************************************************************* + * This function can be used by the platforms to update/use image + * information for given `image_id`. + ******************************************************************************/ +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + return ls_bl2_handle_post_image_load(image_id); +} diff --git a/plat/layerscape/common/ls_bl31_setup.c b/plat/layerscape/common/ls_bl31_setup.c new file mode 100644 index 0000000..3016f58 --- /dev/null +++ b/plat/layerscape/common/ls_bl31_setup.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include "ls_16550.h" +#include "plat_ls.h" +#include "soc.h" + +#define BL31_END (uintptr_t)(&__BL31_END__) + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL31 from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +const unsigned int g0_interrupt_array1[] = { + 9 +}; + +gicv2_driver_data_t ls_gic_data = { + .gicd_base = GICD_BASE, + .gicc_base = GICC_BASE, + .g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array1), + .g0_interrupt_array = g0_interrupt_array1, +}; + + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for the + * security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + assert(sec_state_is_valid(type)); + next_image_info = (type == NON_SECURE) + ? &bl33_image_ep_info : &bl32_image_ep_info; + + if (next_image_info->pc) + return next_image_info; + else + return NULL; +} + +/******************************************************************************* + * Perform any BL31 early platform setup common to Layerscape platforms. + * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 + * in BL2 & S-EL3 in BL1) before they are lost (potentially). This needs to be + * done before the MMU is initialized so that the memory layout can be used + * while creating page tables. BL2 has flushed this information to memory, so + * we are guaranteed to pick up good data. + ******************************************************************************/ +void ls_bl31_early_platform_setup(void *from_bl2, + void *plat_params_from_bl2) +{ + static console_ls_16550_t console; + + /* Initialize the console to provide early debug support */ + console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK, + LS_TF_UART_BAUDRATE, &console); +#if RESET_TO_BL31 + /* There are no parameters from BL2 if BL31 is a reset vector */ + assert(from_bl2 == NULL); + assert(plat_params_from_bl2 == NULL); + +#ifdef BL32_BASE + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, + PARAM_EP, + VERSION_1, + 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = ls_get_spsr_for_bl32_entry(); +#endif /* BL32_BASE */ + + /* Populate entry point information for BL33 */ + SET_PARAM_HEAD(&bl33_image_ep_info, + PARAM_EP, + VERSION_1, + 0); + /* + * Tell BL31 where the non-trusted software image + * is located and the entry state information + */ + bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + + bl33_image_ep_info.spsr = ls_get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +#else /* RESET_TO_BL31 */ + + /* + * In debug builds, we pass a special value in 'plat_params_from_bl2' + * to verify platform parameters from BL2 to BL31. + * In release builds, it's not used. + */ + assert(((unsigned long long)plat_params_from_bl2) == + LS_BL31_PLAT_PARAM_VAL); + + /* + * Check params passed from BL2 should not be NULL, + */ + bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; + + assert(params_from_bl2 != NULL); + assert(params_from_bl2->h.type == PARAM_BL_PARAMS); + assert(params_from_bl2->h.version >= VERSION_2); + + bl_params_node_t *bl_params = params_from_bl2->head; + + /* + * Copy BL33 and BL32 (if present), entry point information. + * They are stored in Secure RAM, in BL2's address space. + */ + while (bl_params) { + if (bl_params->image_id == BL32_IMAGE_ID) + bl32_image_ep_info = *bl_params->ep_info; + + if (bl_params->image_id == BL33_IMAGE_ID) + bl33_image_ep_info = *bl_params->ep_info; + + bl_params = bl_params->next_params_info; + } + + if (bl33_image_ep_info.pc == 0) + panic(); + +#endif /* RESET_TO_BL31 */ +} + +/******************************************************************************* + * Perform any BL31 platform setup common to Layerscape platforms + ******************************************************************************/ +void ls_bl31_platform_setup(void) +{ + uint32_t gicc_base, gicd_base; + + NOTICE(FIRMWARE_WELCOME_STR_LS1043_BL31); + /* Initialize the GIC driver, cpu and distributor interfaces */ + get_gic_offset(&gicc_base, &gicd_base); + ls_gic_data.gicd_base = (uintptr_t)gicd_base; + ls_gic_data.gicc_base = (uintptr_t)gicc_base; + gicv2_driver_init(&ls_gic_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + +#if RESET_TO_BL31 + /* + * Do initial security configuration to allow DRAM/device access + * (if earlier BL has not already done so). + */ + plat_ls_security_setup(); + +#endif /* RESET_TO_BL31 */ + + /* Enable and initialize the System level generic timer */ + mmio_write_32(LS1043_SYS_CNTCTL_BASE + CNTCR_OFF, + CNTCR_FCREQ(0) | CNTCR_EN); + + VERBOSE("Leave arm_bl31_platform_setup\n"); +} + +/******************************************************************************* + * Perform any BL31 platform runtime setup prior to BL31 exit common to Layerscape + * platforms + ******************************************************************************/ +void ls_bl31_plat_runtime_setup(void) +{ + static console_ls_16550_t console; + + /* Initialize the runtime console */ + console_ls_16550_register(PLAT_LS1043_UART_BASE, PLAT_LS1043_UART_CLOCK, + PLAT_LS1043_UART_BAUDRATE, &console); +} + +void bl31_platform_setup(void) +{ + ls_bl31_platform_setup(); +} + +void bl31_plat_runtime_setup(void) +{ + ls_bl31_plat_runtime_setup(); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup shared between + * Layerscape platforms. This only does basic initialization. Later + * architectural setup (bl31_arch_setup()) does not do anything platform + * specific. + ******************************************************************************/ +void ls_bl31_plat_arch_setup(void) +{ + ls_setup_page_tables(BL31_BASE, + BL31_END - BL31_BASE, + BL_CODE_BASE, + BL_CODE_END, + BL_RO_DATA_BASE, + BL_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + enable_mmu_el3(0); +} + +void bl31_plat_arch_setup(void) +{ + ls_bl31_plat_arch_setup(); +} diff --git a/plat/layerscape/common/ls_common.c b/plat/layerscape/common/ls_common.c new file mode 100644 index 0000000..abf6525 --- /dev/null +++ b/plat/layerscape/common/ls_common.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include +#include +#include "platform_def.h" + +const mmap_region_t *plat_ls_get_mmap(void); + +/* + * Table of memory regions for various BL stages to map using the MMU. + * This doesn't include Trusted SRAM as ls_setup_page_tables() already + * takes care of mapping it. + * + * The flash needs to be mapped as writable in order to erase the FIP's Table of + * Contents in case of unrecoverable error (see plat_error_handler()). + */ +#ifdef IMAGE_BL1 +const mmap_region_t plat_ls_mmap[] = { + LS_MAP_FLASH0_RW, + LS_MAP_NS_DRAM, + LS_MAP_CCSR, + {0} +}; +#endif +#ifdef IMAGE_BL2 +const mmap_region_t plat_ls_mmap[] = { + LS_MAP_FLASH0_RW, + LS_MAP_CCSR, + LS_MAP_NS_DRAM, + LS_MAP_TSP_SEC_MEM, + {0} +}; +#endif +#ifdef IMAGE_BL31 +const mmap_region_t plat_ls_mmap[] = { + LS_MAP_CCSR, + LS_MAP_FLASH0_RW, + LS_MAP_NS_DRAM, + LS_MAP_TSP_SEC_MEM, + {0} +}; +#endif +#ifdef IMAGE_BL32 +const mmap_region_t plat_ls_mmap[] = { + LS_MAP_CCSR, + LS_MAP_FLASH0_RW, + LS_MAP_TSP_SEC_MEM, + {0} +}; +#endif +/* + * Set up the page tables for the generic and platform-specific memory regions. + * The extents of the generic memory regions are specified by the function + * arguments and consist of: + * - Trusted SRAM seen by the BL image; + * - Code section; + * - Read-only data section; + * - Coherent memory region, if applicable. + */ +void ls_setup_page_tables(uintptr_t total_base, + size_t total_size, + uintptr_t code_start, + uintptr_t code_limit, + uintptr_t rodata_start, + uintptr_t rodata_limit +#if USE_COHERENT_MEM + , + uintptr_t coh_start, + uintptr_t coh_limit +#endif + ) +{ + /* Now (re-)map the platform-specific memory regions */ + mmap_add(plat_ls_get_mmap()); + /* + * Map the Trusted SRAM with appropriate memory attributes. + * Subsequent mappings will adjust the attributes for specific regions. + */ + VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n", + (void *) total_base, (void *) (total_base + total_size)); + mmap_add_region(total_base, total_base, + total_size, + MT_MEMORY | MT_RW | MT_SECURE); + + /* Re-map the code section */ + VERBOSE("Code region: %p - %p\n", + (void *) code_start, (void *) code_limit); + mmap_add_region(code_start, code_start, + code_limit - code_start, + MT_CODE | MT_SECURE); + + /* Re-map the read-only data section */ + VERBOSE("Read-only data region: %p - %p\n", + (void *) rodata_start, (void *) rodata_limit); + mmap_add_region(rodata_start, rodata_start, + rodata_limit - rodata_start, + MT_RO_DATA | MT_SECURE); + +#if USE_COHERENT_MEM + /* Re-map the coherent memory region */ + VERBOSE("Coherent region: %p - %p\n", + (void *) coh_start, (void *) coh_limit); + mmap_add_region(coh_start, coh_start, + coh_limit - coh_start, + MT_DEVICE | MT_RW | MT_SECURE); +#endif + + /* Create the page tables to reflect the above mappings */ + init_xlat_tables(); +} + +uintptr_t plat_get_ns_image_entrypoint(void) +{ +#ifdef PRELOADED_BL33_BASE + return PRELOADED_BL33_BASE; +#else + return LS_NS_DRAM_BASE; +#endif +} + +/******************************************************************************* + * Gets SPSR for BL32 entry + ******************************************************************************/ +uint32_t ls_get_spsr_for_bl32_entry(void) +{ + /* + * The Secure Payload Dispatcher service is responsible for + * setting the SPSR prior to entry into the BL32 image. + */ + return 0; +} + +/******************************************************************************* + * Gets SPSR for BL33 entry + ******************************************************************************/ +#ifndef AARCH32 +uint32_t ls_get_spsr_for_bl33_entry(void) +{ + unsigned int mode; + uint32_t spsr; + + /* Figure out what mode we enter the non-secure world in */ + mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} +#else +/******************************************************************************* + * Gets SPSR for BL33 entry + ******************************************************************************/ +uint32_t ls_get_spsr_for_bl33_entry(void) +{ + unsigned int hyp_status, mode, spsr; + + hyp_status = GET_VIRT_EXT(read_id_pfr1()); + + mode = (hyp_status) ? MODE32_hyp : MODE32_svc; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1, + SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS); + return spsr; +} +#endif /* AARCH32 */ + +/******************************************************************************* + * Returns Layerscape platform specific memory map regions. + ******************************************************************************/ +const mmap_region_t *plat_ls_get_mmap(void) +{ + return plat_ls_mmap; +} + + +unsigned int plat_get_syscnt_freq2(void) +{ + unsigned int counter_base_frequency; + + counter_base_frequency = COUNTER_FREQUENCY; + + return counter_base_frequency; +} diff --git a/plat/layerscape/common/ls_common.mk b/plat/layerscape/common/ls_common.mk new file mode 100644 index 0000000..1a80e9f --- /dev/null +++ b/plat/layerscape/common/ls_common.mk @@ -0,0 +1,62 @@ +# +# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + + +# Process LS1043_DISABLE_TRUSTED_WDOG flag +# TODO:Temparally disabled it on development phase, not implemented yet +LS1043_DISABLE_TRUSTED_WDOG := 1 + +# On Layerscape platforms, separate the code and read-only data sections to allow +# mapping the former as executable and the latter as execute-never. +SEPARATE_CODE_AND_RODATA := 1 + +# Enable new version of image loading on Layerscape platforms +LOAD_IMAGE_V2 := 1 + +# Use generic OID definition (tbbr_oid.h) +USE_TBBR_DEFS := 1 + + +COLD_BOOT_SINGLE_CPU := 1 + +PLAT_INCLUDES += -Iinclude/common/tbbr + +PLAT_BL_COMMON_SOURCES += plat/layerscape/common/${ARCH}/ls_helpers.S \ + plat/layerscape/common/ls_common.c + +include lib/xlat_tables_v2/xlat_tables.mk + +PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} + +BL1_SOURCES += \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + plat/layerscape/common/ls_timer.c \ + plat/layerscape/common/ls_bl1_setup.c \ + plat/layerscape/common/ls_io_storage.c + +BL2_SOURCES += drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + plat/layerscape/common/ls_timer.c \ + plat/layerscape/common/ls_bl2_setup.c \ + plat/layerscape/common/ls_io_storage.c +BL2_SOURCES += plat/layerscape/common/${ARCH}/ls_bl2_mem_params_desc.c +BL2_SOURCES += plat/layerscape/common/ls_image_load.c \ + common/desc_image_load.c + +BL31_SOURCES += plat/layerscape/common/ls_bl31_setup.c \ + plat/layerscape/common/ls_timer.c \ + plat/layerscape/common/ls_topology.c \ + plat/layerscape/common/ns_access.c \ + plat/common/plat_psci_common.c +# Verify build config +# ------------------- + +ifneq (${LOAD_IMAGE_V2}, 1) + $(error Error: Layerscape needs LOAD_IMAGE_V2=1) +endif diff --git a/plat/layerscape/common/ls_image_load.c b/plat/layerscape/common/ls_image_load.c new file mode 100644 index 0000000..909bec2 --- /dev/null +++ b/plat/layerscape/common/ls_image_load.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "ls_def.h" + +/******************************************************************************* + * This function flushes the data structures so that they are visible + * in memory for the next BL image. + ******************************************************************************/ +void plat_flush_next_bl_params(void) +{ + flush_bl_params_desc(); +} + +/******************************************************************************* + * This function returns the list of loadable images. + ******************************************************************************/ +bl_load_info_t *plat_get_bl_image_load_info(void) +{ + return get_bl_load_info_from_mem_params_desc(); +} + +/******************************************************************************* + * This function returns the list of executable images. + ******************************************************************************/ +bl_params_t *plat_get_next_bl_params(void) +{ + return get_next_bl_params_from_mem_params_desc(); +} diff --git a/plat/layerscape/common/ls_io_storage.c b/plat/layerscape/common/ls_io_storage.c new file mode 100644 index 0000000..7402366 --- /dev/null +++ b/plat/layerscape/common/ls_io_storage.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include +#include +#include +#include "platform_def.h" + +/* IO devices */ +static const io_dev_connector_t *fip_dev_con; +static uintptr_t fip_dev_handle; +static const io_dev_connector_t *memmap_dev_con; +static uintptr_t memmap_dev_handle; + +static const io_block_spec_t fip_block_spec = { + .offset = PLAT_LS_FIP_BASE, + .length = PLAT_LS_FIP_MAX_SIZE +}; + +static const io_uuid_spec_t bl2_uuid_spec = { + .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, +}; + +static const io_uuid_spec_t bl31_uuid_spec = { + .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, +}; + +static const io_uuid_spec_t bl32_uuid_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32, +}; + +static const io_uuid_spec_t bl33_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, +}; + +static int open_fip(const uintptr_t spec); +static int open_memmap(const uintptr_t spec); + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +static const struct plat_io_policy policies[] = { + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, + [BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl2_uuid_spec, + open_fip + }, + [BL31_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl31_uuid_spec, + open_fip + }, + [BL32_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl32_uuid_spec, + open_fip + }, + [BL33_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl33_uuid_spec, + open_fip + }, +}; + +static int open_fip(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + /* See if a Firmware Image Package is available */ + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + if (result == 0) { + result = io_open(fip_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using FIP\n"); + io_close(local_image_handle); + } + } + return result; +} + + +static int open_memmap(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); + if (result == 0) { + result = io_open(memmap_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using Memmap\n"); + io_close(local_image_handle); + } + } + return result; +} + + +void ls_io_setup(void) +{ + int io_result; + + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == 0); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); + assert(io_result == 0); + + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &memmap_dev_handle); + assert(io_result == 0); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + +void plat_ls_io_setup(void) +{ + ls_io_setup(); +} + +int plat_ls_get_alt_image_source( + unsigned int image_id __unused, + uintptr_t *dev_handle __unused, + uintptr_t *image_spec __unused) +{ + /* By default do not try an alternative */ + return -ENOENT; +} + +/* + * Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy. + */ +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result; + const struct plat_io_policy *policy; + + assert(image_id < ARRAY_SIZE(policies)); + + policy = &policies[image_id]; + result = policy->check(policy->image_spec); + if (result == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } else { + VERBOSE("Trying alternative IO\n"); + result = plat_ls_get_alt_image_source(image_id, dev_handle, + image_spec); + } + + return result; +} diff --git a/plat/layerscape/common/ls_timer.c b/plat/layerscape/common/ls_timer.c new file mode 100644 index 0000000..25b5e63 --- /dev/null +++ b/plat/layerscape/common/ls_timer.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#define TIMER_BASE_ADDR 0x02B00000 + +uint64_t ls_get_timer(uint64_t start) +{ + return read_cntpct_el0() * 1000 / read_cntfrq_el0() - start; +} + +static uint32_t ls_timeus_get_value(void) +{ + /* + * Generic delay timer implementation expects the timer to be a down + * counter. We apply bitwise NOT operator to the tick values returned + * by read_cntpct_el0() to simulate the down counter. The value is + * clipped from 64 to 32 bits. + */ + return (uint32_t)(~read_cntpct_el0()); +} + +static const timer_ops_t ls_timer_ops = { + .get_timer_value = ls_timeus_get_value, + .clk_mult = 1, + .clk_div = 25, +}; + + +/* + * Initialise the nxp layerscape on-chip free rolling us counter as the delay + * timer. + */ +void ls_delay_timer_init(void) +{ + uintptr_t cntcr = TIMER_BASE_ADDR; + + mmio_write_32(cntcr, 0x1); + + timer_init(&ls_timer_ops); +} diff --git a/plat/layerscape/common/ls_topology.c b/plat/layerscape/common/ls_topology.c new file mode 100644 index 0000000..5b76087 --- /dev/null +++ b/plat/layerscape/common/ls_topology.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "plat_ls.h" + +/******************************************************************************* + * This function validates an MPIDR by checking whether it falls within the + * acceptable bounds. An error code (-1) is returned if an incorrect mpidr + * is passed. + ******************************************************************************/ +int ls_check_mpidr(u_register_t mpidr) +{ + unsigned int cluster_id, cpu_id; + uint64_t valid_mask; + + valid_mask = ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK); + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + + mpidr &= MPIDR_AFFINITY_MASK; + if (mpidr & valid_mask) + return -1; + + if (cluster_id >= PLAT_LS_CLUSTER_COUNT) + return -1; + + /* + * Validate cpu_id by checking whether it represents a CPU in + * one of the two clusters present on the platform. + */ + if (cpu_id >= plat_ls_get_cluster_core_count(mpidr)) + return -1; + + + return 0; +} diff --git a/plat/layerscape/common/ls_tzc380.c b/plat/layerscape/common/ls_tzc380.c new file mode 100644 index 0000000..b9f32ac --- /dev/null +++ b/plat/layerscape/common/ls_tzc380.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include "platform_def.h" +#include "soc_tzasc.h" + +int tzc380_set_region(unsigned int tzasc_base, unsigned int region_id, + unsigned int enabled, unsigned int low_addr, + unsigned int high_addr, unsigned int size, + unsigned int security, unsigned int subreg_disable_mask) +{ + unsigned int reg; + unsigned int reg_base; + unsigned int attr_value; + + reg_base = (tzasc_base + TZASC_REGIONS_REG + (region_id << 4)); + + if (region_id == 0) { + reg = (reg_base + TZASC_REGION_ATTR_OFFSET); + mmio_write_32((uintptr_t)reg, ((security & 0xF) << 28)); + } else { + reg = reg_base + TZASC_REGION_LOWADDR_OFFSET; + mmio_write_32((uintptr_t)reg, + (low_addr & TZASC_REGION_LOWADDR_MASK)); + + reg = reg_base + TZASC_REGION_HIGHADDR_OFFSET; + mmio_write_32((uintptr_t)reg, high_addr); + + reg = reg_base + TZASC_REGION_ATTR_OFFSET; + attr_value = ((security & 0xF) << 28) | + ((subreg_disable_mask & 0xFF) << 8) | + ((size & 0x3F) << 1) | (enabled & 0x1); + mmio_write_32((uintptr_t)reg, attr_value); + + } + return 0; +} + +int tzc380_setup(void) +{ + int reg_id = 0; + + INFO("Configuring TZASC-380\n"); + + /* + * Configure CCI control override register to terminate all barrier + * transactions + */ + mmio_write_32(PLAT_LS1043_CCI_BASE, CCI_TERMINATE_BARRIER_TX); + + /* Configure CSU secure access register to disable TZASC bypass mux */ + mmio_write_32((uintptr_t)(CONFIG_SYS_FSL_CSU_ADDR + + CSU_SEC_ACCESS_REG_OFFSET), + bswap32(TZASC_BYPASS_MUX_DISABLE)); + + for (reg_id = 0; reg_id < MAX_NUM_TZC_REGION; reg_id++) { + tzc380_set_region(CONFIG_SYS_FSL_TZASC_ADDR, + reg_id, + tzc380_reg_list[reg_id].enabled, + tzc380_reg_list[reg_id].low_addr, + tzc380_reg_list[reg_id].high_addr, + tzc380_reg_list[reg_id].size, + tzc380_reg_list[reg_id].secure, + tzc380_reg_list[reg_id].sub_mask); + } + + return 0; +} diff --git a/plat/layerscape/common/ns_access.c b/plat/layerscape/common/ns_access.c new file mode 100644 index 0000000..e1daaed --- /dev/null +++ b/plat/layerscape/common/ns_access.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include "ns_access.h" +#include "platform_def.h" + +static void enable_devices_ns_access(struct csu_ns_dev *ns_dev, uint32_t num) +{ + uint32_t *base = (uint32_t *)CONFIG_SYS_FSL_CSU_ADDR; + uint32_t *reg; + uint32_t val; + int i; + + for (i = 0; i < num; i++) { + reg = base + ns_dev[i].ind / 2; + val = be32toh(mmio_read_32((uintptr_t)reg)); + if (ns_dev[i].ind % 2 == 0) { + val &= 0x0000ffff; + val |= ns_dev[i].val << 16; + } else { + val &= 0xffff0000; + val |= ns_dev[i].val; + } + mmio_write_32((uintptr_t)reg, htobe32(val)); + } +} + +void enable_layerscape_ns_access(void) +{ + enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev)); +} diff --git a/plat/layerscape/common/tsp/ls_tsp.mk b/plat/layerscape/common/tsp/ls_tsp.mk new file mode 100644 index 0000000..7cb9781 --- /dev/null +++ b/plat/layerscape/common/tsp/ls_tsp.mk @@ -0,0 +1,10 @@ +# +# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# TSP source files common to ARM standard platforms +BL32_SOURCES += plat/layerscape/common/ls_topology.c \ + plat/layerscape/common/tsp/ls_tsp_setup.c \ + plat/common/aarch64/platform_mp_stack.S diff --git a/plat/layerscape/common/tsp/ls_tsp_setup.c b/plat/layerscape/common/tsp/ls_tsp_setup.c new file mode 100644 index 0000000..82ac965 --- /dev/null +++ b/plat/layerscape/common/tsp/ls_tsp_setup.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include "ls_16550.h" +#include "plat_ls.h" +#include "soc.h" + +#define BL32_END (unsigned long)(&__BL32_END__) + +const unsigned int g0_interrupt_array1[] = { + 9 +}; + +gicv2_driver_data_t ls_gic_data = { + .gicd_base = GICD_BASE, + .gicc_base = GICC_BASE, + .g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array1), + .g0_interrupt_array = g0_interrupt_array1, +}; + +/******************************************************************************* + * Initialize the UART + ******************************************************************************/ +void ls_tsp_early_platform_setup(void) +{ + static console_ls_16550_t console; + /* + * Initialize a different console than already in use to display + * messages from TSP + */ + console_ls_16550_register(PLAT_LS1043_UART2_BASE, PLAT_LS1043_UART_CLOCK, + PLAT_LS1043_UART_BAUDRATE, &console); + NOTICE(FIRMWARE_WELCOME_STR_LS1043_BL32); +} + +/******************************************************************************* + * Perform platform specific setup placeholder + ******************************************************************************/ +void tsp_platform_setup(void) +{ + uint32_t gicc_base, gicd_base; + + /* Initialize the GIC driver, cpu and distributor interfaces */ + get_gic_offset(&gicc_base, &gicd_base); + ls_gic_data.gicd_base = (uintptr_t)gicd_base; + ls_gic_data.gicc_base = (uintptr_t)gicc_base; + gicv2_driver_init(&ls_gic_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the MMU + ******************************************************************************/ +void tsp_plat_arch_setup(void) +{ + ls_setup_page_tables(BL32_BASE, + (BL32_END - BL32_BASE), + BL_CODE_BASE, + BL_CODE_END, + BL_RO_DATA_BASE, + BL_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END +#endif + ); + enable_mmu_el1(0); +} diff --git a/plat/layerscape/common/tsp/platform_tsp.h b/plat/layerscape/common/tsp/platform_tsp.h new file mode 100644 index 0000000..b1c96cb --- /dev/null +++ b/plat/layerscape/common/tsp/platform_tsp.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLATFORM_TSP_H__ +#define __PLATFORM_TSP_H__ + +/******************************************************************************* + * Mandatory TSP functions (only if platform contains a TSP) + ******************************************************************************/ +void tsp_early_platform_setup(void); +void tsp_plat_arch_setup(void); +void tsp_platform_setup(void); + +#endif /* __PLATFORM_TSP_H__ */