layerscape: Initial TF-A support for LS1043ardb

This patch introduce TF-A support for NXP's ls1043a platform.
more details information of ls1043a chip and ls1043ardb board
can be found at docs/plat/ls1043a.rst.

Boot sequence on ls1043a is: bootrom loads bl1 firstly, then bl1
loads bl2, bl2 will load bl31, bl32 and bl33, bl31 will boot
bl32(tee os) and bl33(u-boot or uefi), bl33 boot Linux kernel.

Now TF-A on ls1043ardb platform has the following features in this patch:
	* Support boot from Nor flash.
	* TF-A can boot bl33 which runs in el2 of non-secure world.
	* TF-A boot OPTee OS.
	* Support PSCI

Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com>
Signed-off-by: Chenyin.Ha <Chenyin.Ha@nxp.com>
Signed-off-by: Chenhui Zhao <chenhui.zhao@nxp.com>
Signed-off-by: jiaheng.fan <jiaheng.fan@nxp.com>
Signed-off-by: Wen He <wen.he_1@nxp.com>
This commit is contained in:
Jiafei Pan 2018-03-02 07:23:30 +00:00
parent 93883a2931
commit 33d4af47b0
42 changed files with 3361 additions and 0 deletions

91
docs/plat/ls1043a.rst Normal file
View File

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

View File

@ -83,6 +83,15 @@ Files:
- 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 @@ Etienne Carriere (etienne.carriere@linaro.org, `etienne-lms`_)
.. _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

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <platform_def.h>
.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

View File

@ -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 <arch.h>
#include <common_def.h>
#include <platform_def.h>
#include <tbbr_img_def.h>
#include <utils_def.h>
#include <xlat_tables_defs.h>
/******************************************************************************
* 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__ */

View File

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

View File

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

View File

@ -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 <common_def.h>
#include <tzc400.h>
#include <utils.h>
#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__ */

View File

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

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <cci.h>
#include <debug.h>
#include <mmio.h>
#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;
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mmio.h>
#include <debug.h>
#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);
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <cci.h>
#include <debug.h>
#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();
}

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <debug.h>
#include <errno.h>
#include <stdint.h>
/*
* 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();
}

View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <debug.h>
#include <errno.h>
#include <assert.h>
#include <platform.h>
#include <psci.h>
#include <mmio.h>
#include <sys/endian.h>
#include <gicv2.h>
#include <delay_timer.h>
#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;
}

View File

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

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <stdint.h>
#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();
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <cassert.h>
#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);
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mmio.h>
#include <debug.h>
#include <endian.h>
#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;
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bl_common.h>
#include <desc_image_load.h>
#include <platform.h>
#include <platform_def.h>
#include <debug.h>
#include <ls_def.h>
/*******************************************************************************
* 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)

View File

@ -0,0 +1,268 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <console_macros.S>
#include <assert_macros.S>
#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

View File

@ -0,0 +1,150 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
#include <console.h>
#include <platform_def.h>
.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

View File

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

View File

@ -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 <console.h>
/* 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 <types.h>
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__ */

View File

@ -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 <sys/types.h>
#include <cpu_data.h>
/* 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__ */

View File

@ -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 <stdint.h>
#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__ */

View File

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

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <debug.h>
#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
}

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <bl_common.h>
#include <desc_image_load.h>
#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);
}

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <console.h>
#include <mmio.h>
#include <gicv2.h>
#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();
}

View File

@ -0,0 +1,199 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <xlat_tables_v2.h>
#include <assert.h>
#include <debug.h>
#include <mmio.h>
#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;
}

View File

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

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <desc_image_load.h>
#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();
}

View File

@ -0,0 +1,175 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <debug.h>
#include <firmware_image_package.h>
#include <io_driver.h>
#include <io_fip.h>
#include <io_memmap.h>
#include <io_storage.h>
#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;
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mmio.h>
#include <delay_timer.h>
#include <arch_helpers.h>
#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);
}

View File

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

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <debug.h>
#include <mmio.h>
#include <endian.h>
#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;
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mmio.h>
#include <endian.h>
#include <debug.h>
#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));
}

View File

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

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <gicv2.h>
#include <debug.h>
#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);
}

View File

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