diff options
88 files changed, 4550 insertions, 244 deletions
@@ -373,6 +373,11 @@ ifneq ($(MULTI_CONSOLE_API), 0) endif endif +#For now, BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is 1. +ifeq ($(BL2_AT_EL3)-$(BL2_IN_XIP_MEM),0-1) +$(error "BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is enabled") +endif + ################################################################################ # Process platform overrideable behaviour ################################################################################ @@ -518,6 +523,7 @@ $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call assert_boolean,USE_TBBR_DEFS)) $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY)) $(eval $(call assert_boolean,BL2_AT_EL3)) +$(eval $(call assert_boolean,BL2_IN_XIP_MEM)) $(eval $(call assert_numeric,ARM_ARCH_MAJOR)) $(eval $(call assert_numeric,ARM_ARCH_MINOR)) @@ -564,6 +570,7 @@ $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,USE_TBBR_DEFS)) $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY)) $(eval $(call add_define,BL2_AT_EL3)) +$(eval $(call add_define,BL2_IN_XIP_MEM)) # Define the EL3_PAYLOAD_BASE flag only if it is provided. ifdef EL3_PAYLOAD_BASE diff --git a/acknowledgements.rst b/acknowledgements.rst index 59f569ed..9b81b6c5 100644 --- a/acknowledgements.rst +++ b/acknowledgements.rst @@ -12,5 +12,7 @@ Socionext Inc. Xilinx, Inc. +NXP Semiconductors + Individuals ----------- diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c index 49e4e8e2..25be5770 100644 --- a/bl1/bl1_fwu.c +++ b/bl1/bl1_fwu.c @@ -24,12 +24,12 @@ * Function declarations. */ static int bl1_fwu_image_copy(unsigned int image_id, - uintptr_t image_addr, + uintptr_t image_src, unsigned int block_size, unsigned int image_size, unsigned int flags); static int bl1_fwu_image_auth(unsigned int image_id, - uintptr_t image_addr, + uintptr_t image_src, unsigned int image_size, unsigned int flags); static int bl1_fwu_image_execute(unsigned int image_id, @@ -50,7 +50,7 @@ __dead2 static void bl1_fwu_done(void *client_cookie, void *reserved); static unsigned int sec_exec_image_id = INVALID_IMAGE_ID; /* Authentication status of each image. */ -extern unsigned int auth_img_flags[]; +extern unsigned int auth_img_flags[MAX_NUMBER_IDS]; /******************************************************************************* * Top level handler for servicing FWU SMCs. diff --git a/bl1/tbbr/tbbr_img_desc.c b/bl1/tbbr/tbbr_img_desc.c index f2ed1a1c..44f58d3f 100644 --- a/bl1/tbbr/tbbr_img_desc.c +++ b/bl1/tbbr/tbbr_img_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,7 @@ #include <bl1.h> #include <bl_common.h> #include <platform_def.h> +#include <tbbr/tbbr_img_desc.h> image_desc_t bl1_tbbr_image_descs[] = { { diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S index 3728643c..0f91edc9 100644 --- a/bl2/bl2_el3.ld.S +++ b/bl2/bl2_el3.ld.S @@ -12,15 +12,26 @@ OUTPUT_ARCH(PLATFORM_LINKER_ARCH) ENTRY(bl2_entrypoint) MEMORY { +#if BL2_IN_XIP_MEM + ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE + RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE +#else RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE +#endif } SECTIONS { +#if BL2_IN_XIP_MEM + . = BL2_RO_BASE; + ASSERT(. == ALIGN(PAGE_SIZE), + "BL2_RO_BASE address is not aligned on a page boundary.") +#else . = BL2_BASE; ASSERT(. == ALIGN(PAGE_SIZE), "BL2_BASE address is not aligned on a page boundary.") +#endif #if SEPARATE_CODE_AND_RODATA .text . : { @@ -33,7 +44,11 @@ SECTIONS *(.vectors) . = NEXT(PAGE_SIZE); __TEXT_END__ = .; +#if BL2_IN_XIP_MEM + } >ROM +#else } >RAM +#endif .rodata . : { __RODATA_START__ = .; @@ -56,7 +71,11 @@ SECTIONS . = NEXT(PAGE_SIZE); __RODATA_END__ = .; +#if BL2_IN_XIP_MEM + } >ROM +#else } >RAM +#endif ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE, "Resident part of BL2 has exceeded its limit.") @@ -95,12 +114,22 @@ SECTIONS . = NEXT(PAGE_SIZE); __RO_END__ = .; +#if BL2_IN_XIP_MEM + } >ROM +#else } >RAM #endif +#endif ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__, "cpu_ops not defined for this platform.") +#if BL2_IN_XIP_MEM + . = BL2_RW_BASE; + ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE), + "BL2_RW_BASE address is not aligned on a page boundary.") +#endif + /* * Define a linker symbol to mark start of the RW memory area for this * image. @@ -113,10 +142,14 @@ SECTIONS * section can be placed independently of the main .data section. */ .data . : { - __DATA_START__ = .; + __DATA_RAM_START__ = .; *(.data*) - __DATA_END__ = .; + __DATA_RAM_END__ = .; +#if BL2_IN_XIP_MEM + } >RAM AT>ROM +#else } >RAM +#endif stacks (NOLOAD) : { __STACKS_START__ = .; @@ -174,12 +207,32 @@ SECTIONS __RW_END__ = .; __BL2_END__ = .; +#if BL2_IN_XIP_MEM + __BL2_RAM_START__ = ADDR(.data); + __BL2_RAM_END__ = .; + + __DATA_ROM_START__ = LOADADDR(.data); + __DATA_SIZE__ = SIZEOF(.data); + + /* + * The .data section is the last PROGBITS section so its end marks the end + * of BL2's RO content in XIP memory.. + */ + __BL2_ROM_END__ = __DATA_ROM_START__ + __DATA_SIZE__; + ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT, + "BL2's RO content has exceeded its limit.") +#endif __BSS_SIZE__ = SIZEOF(.bss); + #if USE_COHERENT_MEM __COHERENT_RAM_UNALIGNED_SIZE__ = __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__; #endif +#if BL2_IN_XIP_MEM + ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.") +#else ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.") +#endif } diff --git a/bl2/bl2_image_load.c b/bl2/bl2_image_load.c index d5d28a54..d22e9ce4 100644 --- a/bl2/bl2_image_load.c +++ b/bl2/bl2_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -182,7 +182,7 @@ static int load_bl33(bl31_params_t *bl2_to_bl31_params) * This function loads SCP_BL2/BL3x images and returns the ep_info for * the next executable image. ******************************************************************************/ -entry_point_info_t *bl2_load_images(void) +struct entry_point_info *bl2_load_images(void) { bl31_params_t *bl2_to_bl31_params; entry_point_info_t *bl31_ep_info; diff --git a/bl2/bl2_image_load_v2.c b/bl2/bl2_image_load_v2.c index d95c6b28..0f40785d 100644 --- a/bl2/bl2_image_load_v2.c +++ b/bl2/bl2_image_load_v2.c @@ -21,7 +21,7 @@ * This function loads SCP_BL2/BL3x images and returns the ep_info for * the next executable image. ******************************************************************************/ -entry_point_info_t *bl2_load_images(void) +struct entry_point_info *bl2_load_images(void) { bl_params_t *bl2_to_next_bl_params; bl_load_info_t *bl2_load_info; diff --git a/bl2/bl2_private.h b/bl2/bl2_private.h index 50295d67..f93a179d 100644 --- a/bl2/bl2_private.h +++ b/bl2/bl2_private.h @@ -7,6 +7,20 @@ #ifndef __BL2_PRIVATE_H__ #define __BL2_PRIVATE_H__ +#if BL2_IN_XIP_MEM +/******************************************************************************* + * Declarations of linker defined symbols which will tell us where BL2 lives + * in Trusted ROM and RAM + ******************************************************************************/ +extern uintptr_t __BL2_ROM_END__; +#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__) + +extern uintptr_t __BL2_RAM_START__; +extern uintptr_t __BL2_RAM_END__; +#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__) +#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__) +#endif + /****************************************** * Forward declarations *****************************************/ diff --git a/bl32/tsp/tsp_private.h b/bl32/tsp/tsp_private.h index b11570cc..dd65a5fb 100644 --- a/bl32/tsp/tsp_private.h +++ b/bl32/tsp/tsp_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -62,7 +62,7 @@ CASSERT(TSP_ARGS_SIZE == sizeof(tsp_args_t), assert_sp_args_size_mismatch); void tsp_get_magic(uint64_t args[4]); -tsp_args_t *tsp_cpu_resume_main(uint64_t arg0, +tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl, uint64_t arg1, uint64_t arg2, uint64_t arg3, @@ -106,7 +106,47 @@ extern work_statistics_t tsp_stats[PLATFORM_CORE_COUNT]; /* Vector table of jumps */ extern tsp_vectors_t tsp_vector_table; +/* functions */ +int32_t tsp_common_int_handler(void); +int32_t tsp_handle_preemption(void); + +tsp_args_t *tsp_abort_smc_handler(uint64_t func, + uint64_t arg1, + uint64_t arg2, + uint64_t arg3, + uint64_t arg4, + uint64_t arg5, + uint64_t arg6, + uint64_t arg7); + +tsp_args_t *tsp_smc_handler(uint64_t func, + uint64_t arg1, + uint64_t arg2, + uint64_t arg3, + uint64_t arg4, + uint64_t arg5, + uint64_t arg6, + uint64_t arg7); + +tsp_args_t *tsp_system_reset_main(uint64_t arg0, + uint64_t arg1, + uint64_t arg2, + uint64_t arg3, + uint64_t arg4, + uint64_t arg5, + uint64_t arg6, + uint64_t arg7); + +tsp_args_t *tsp_system_off_main(uint64_t arg0, + uint64_t arg1, + uint64_t arg2, + uint64_t arg3, + uint64_t arg4, + uint64_t arg5, + uint64_t arg6, + uint64_t arg7); +uint64_t tsp_main(void); #endif /* __ASSEMBLY__ */ #endif /* __TSP_PRIVATE_H__ */ diff --git a/docs/plat/ls1043a.rst b/docs/plat/ls1043a.rst new file mode 100644 index 00000000..0d604aae --- /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/docs/porting-guide.rst b/docs/porting-guide.rst index ff5bb122..12e135f7 100644 --- a/docs/porting-guide.rst +++ b/docs/porting-guide.rst @@ -217,11 +217,37 @@ platform port to define additional platform porting constants in - **#define : BL2\_BASE** Defines the base address in secure RAM where BL1 loads the BL2 binary image. - Must be aligned on a page-size boundary. + Must be aligned on a page-size boundary. This constant is not applicable + when BL2_IN_XIP_MEM is set to '1'. - **#define : BL2\_LIMIT** Defines the maximum address in secure RAM that the BL2 image can occupy. + This constant is not applicable when BL2_IN_XIP_MEM is set to '1'. + +- **#define : BL2\_RO\_BASE** + + Defines the base address in secure XIP memory where BL2 RO section originally + lives. Must be aligned on a page-size boundary. This constant is only needed + when BL2_IN_XIP_MEM is set to '1'. + +- **#define : BL2\_RO\_LIMIT** + + Defines the maximum address in secure XIP memory that BL2's actual content + (i.e. excluding any data section allocated at runtime) can occupy. This + constant is only needed when BL2_IN_XIP_MEM is set to '1'. + +- **#define : BL2\_RW\_BASE** + + Defines the base address in secure RAM where BL2's read-write data will live + at runtime. Must be aligned on a page-size boundary. This constant is only + needed when BL2_IN_XIP_MEM is set to '1'. + +- **#define : BL2\_RW\_LIMIT** + + Defines the maximum address in secure RAM that BL2's read-write data can + occupy at runtime. This constant is only needed when BL2_IN_XIP_MEM is set + to '1'. - **#define : BL31\_BASE** diff --git a/docs/user-guide.rst b/docs/user-guide.rst index 57948554..f8bc4be5 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -246,6 +246,12 @@ Common build options - ``BL2_AT_EL3``: This is an optional build option that enables the use of BL2 at EL3 execution level. +- ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place + (XIP) memory, like BL1. In these use-cases, it is necessary to initialize + the RW sections in RAM, while leaving the RO sections in place. This option + enable this use-case. For now, this option is only supported when BL2_AT_EL3 + is set to '1'. + - ``BL31``: This is an optional build option which specifies the path to BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not be built. @@ -783,6 +789,12 @@ Arm FVP platform specific build options HW_CONFIG blob instead of the DTS file. This option is useful to override the default HW_CONFIG selected by the build system. +ARM JUNO platform specific build options +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- ``JUNO_TZMP1`` : Boolean option to configure Juno to be used for TrustZone + Media Protection (TZ-MP1). Default value of this flag is 0. + Debugging options ~~~~~~~~~~~~~~~~~ diff --git a/drivers/arm/tzc/tzc_dmc500.c b/drivers/arm/tzc/tzc_dmc500.c index 7350b2ce..8b618e6d 100644 --- a/drivers/arm/tzc/tzc_dmc500.c +++ b/drivers/arm/tzc/tzc_dmc500.c @@ -25,6 +25,7 @@ /* Pointer to the tzc_dmc500_driver_data structure populated by the platform */ static const tzc_dmc500_driver_data_t *g_driver_data; +static unsigned int g_sys_if_count; #define verify_region_attr(region, attr) \ ((g_conf_regions[(region)].sec_attr == \ @@ -88,7 +89,7 @@ void tzc_dmc500_config_complete(void) for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) { assert(DMC_INST_BASE_ADDR(dmc_inst)); - for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++) + for (sys_if = 0; sys_if < g_sys_if_count; sys_if++) _tzc_dmc500_write_flush_control( DMC_INST_SI_BASE(dmc_inst, sys_if)); } @@ -119,7 +120,7 @@ int tzc_dmc500_verify_complete(void) for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) { assert(DMC_INST_BASE_ADDR(dmc_inst)); - for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; + for (sys_if = 0; sys_if < g_sys_if_count; sys_if++) { attr = _tzc_dmc500_read_region_attr_0( DMC_INST_SI_BASE(dmc_inst, sys_if), @@ -154,7 +155,7 @@ void tzc_dmc500_configure_region0(tzc_region_attributes_t sec_attr, /* Configure region_0 in all DMC instances */ for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) { assert(DMC_INST_BASE_ADDR(dmc_inst)); - for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++) + for (sys_if = 0; sys_if < g_sys_if_count; sys_if++) _tzc_dmc500_configure_region0( DMC_INST_SI_BASE(dmc_inst, sys_if), sec_attr, nsaid_permissions); @@ -195,7 +196,7 @@ void tzc_dmc500_configure_region(int region_no, for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) { assert(DMC_INST_BASE_ADDR(dmc_inst)); - for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++) + for (sys_if = 0; sys_if < g_sys_if_count; sys_if++) _tzc_dmc500_configure_region( DMC_INST_SI_BASE(dmc_inst, sys_if), TZC_DMC500_REGION_ATTR_F_EN_MASK, @@ -272,4 +273,13 @@ void tzc_dmc500_driver_init(const tzc_dmc500_driver_data_t *plat_driver_data) /* Validates the information passed by platform */ validate_plat_driver_data(plat_driver_data); g_driver_data = plat_driver_data; + + /* Check valid system interface count */ + assert(g_driver_data->sys_if_count <= MAX_SYS_IF_COUNT); + + g_sys_if_count = g_driver_data->sys_if_count; + + /* If interface count is not present then assume max */ + if (g_sys_if_count == 0U) + g_sys_if_count = MAX_SYS_IF_COUNT; } diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c index 1cea60b2..eb537b66 100644 --- a/drivers/auth/auth_mod.c +++ b/drivers/auth/auth_mod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -30,7 +30,7 @@ /* Pointer to CoT */ extern const auth_img_desc_t *const cot_desc_ptr; -extern unsigned int auth_img_flags[]; +extern unsigned int auth_img_flags[MAX_NUMBER_IDS]; static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a, const auth_param_type_desc_t *b) diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c index 3b3e3ac4..4cd05506 100644 --- a/drivers/auth/crypto_mod.c +++ b/drivers/auth/crypto_mod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,6 @@ #include <debug.h> /* Variable exported by the crypto library through REGISTER_CRYPTO_LIB() */ -extern const crypto_lib_desc_t crypto_lib_desc; /* * The crypto module is responsible for verifying digital signatures and hashes. diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c index 205c2432..c048d005 100644 --- a/drivers/auth/mbedtls/mbedtls_common.c +++ b/drivers/auth/mbedtls/mbedtls_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,6 +10,7 @@ #include <mbedtls/memory_buffer_alloc.h> #include <mbedtls/platform.h> #include <mbedtls_config.h> +#include <mbedtls_common.h> /* * mbed TLS heap diff --git a/include/bl2/bl2.h b/include/bl2/bl2.h index f2bd07ef..89ff06ea 100644 --- a/include/bl2/bl2.h +++ b/include/bl2/bl2.h @@ -7,9 +7,6 @@ #ifndef BL2_H__ #define BL2_H__ -struct entry_point_info; - void bl2_main(void); -struct entry_point_info *bl2_load_images(void); #endif /* BL2_H__ */ diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S index 4ebf77bb..d5f527aa 100644 --- a/include/common/aarch64/el3_common_macros.S +++ b/include/common/aarch64/el3_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -278,8 +278,8 @@ * an earlier boot loader stage. * ------------------------------------------------------------- */ - adr x0, __RW_START__ - adr x1, __RW_END__ + ldr x0, =__RW_START__ + ldr x1, =__RW_END__ sub x1, x1, x0 bl inv_dcache_range #endif @@ -294,7 +294,7 @@ bl zeromem #endif -#ifdef IMAGE_BL1 +#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_IN_XIP_MEM) ldr x0, =__DATA_RAM_START__ ldr x1, =__DATA_ROM_START__ ldr x2, =__DATA_SIZE__ diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h index 060198bc..273abbea 100644 --- a/include/common/tbbr/tbbr_img_def.h +++ b/include/common/tbbr/tbbr_img_def.h @@ -75,4 +75,7 @@ /* NT_FW_CONFIG */ #define NT_FW_CONFIG_ID 27 +/* Define size of the array */ +#define MAX_NUMBER_IDS 28 + #endif /* __TBBR_IMG_DEF_H__ */ diff --git a/include/drivers/arm/tzc_dmc500.h b/include/drivers/arm/tzc_dmc500.h index 2606d1be..ff58a279 100644 --- a/include/drivers/arm/tzc_dmc500.h +++ b/include/drivers/arm/tzc_dmc500.h @@ -130,6 +130,7 @@ typedef struct tzc_dmc500_driver_data { uintptr_t dmc_base[MAX_DMC_COUNT]; int dmc_count; + unsigned int sys_if_count; } tzc_dmc500_driver_data_t; void tzc_dmc500_driver_init(const tzc_dmc500_driver_data_t *plat_driver_data); diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h index bd650980..bb3b8f90 100644 --- a/include/drivers/auth/auth_mod.h +++ b/include/drivers/auth/auth_mod.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,6 +12,7 @@ #include <auth_common.h> #include <cot_def.h> #include <img_parser_mod.h> +#include <tbbr_img_def.h> /* * Image flags @@ -41,7 +42,10 @@ int auth_mod_verify_img(unsigned int img_id, #define REGISTER_COT(_cot) \ const auth_img_desc_t *const cot_desc_ptr = \ (const auth_img_desc_t *const)&_cot[0]; \ - unsigned int auth_img_flags[sizeof(_cot)/sizeof(_cot[0])] + unsigned int auth_img_flags[MAX_NUMBER_IDS] + +extern const auth_img_desc_t *const cot_desc_ptr; +extern unsigned int auth_img_flags[MAX_NUMBER_IDS]; #endif /* TRUSTED_BOARD_BOOT */ diff --git a/include/drivers/auth/crypto_mod.h b/include/drivers/auth/crypto_mod.h index 08884ab2..f9b44d1c 100644 --- a/include/drivers/auth/crypto_mod.h +++ b/include/drivers/auth/crypto_mod.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,7 +43,7 @@ typedef struct crypto_lib_desc_s { void crypto_mod_init(void); int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len, void *sig_ptr, unsigned int sig_len, - void *sig_alg, unsigned int sig_alg_len, + void *sig_alg_ptr, unsigned int sig_alg_len, void *pk_ptr, unsigned int pk_len); int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len, void *digest_info_ptr, unsigned int digest_info_len); @@ -57,4 +57,6 @@ int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len, .verify_hash = _verify_hash \ } +extern const crypto_lib_desc_t crypto_lib_desc; + #endif /* __CRYPTO_MOD_H__ */ diff --git a/include/drivers/auth/img_parser_mod.h b/include/drivers/auth/img_parser_mod.h index 347ed621..eaf3e6e7 100644 --- a/include/drivers/auth/img_parser_mod.h +++ b/include/drivers/auth/img_parser_mod.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -44,10 +44,10 @@ typedef struct img_parser_lib_desc_s { /* Exported functions */ void img_parser_init(void); int img_parser_check_integrity(img_type_t img_type, - void *img, unsigned int img_len); + void *img_ptr, unsigned int img_len); int img_parser_get_auth_param(img_type_t img_type, const auth_param_type_desc_t *type_desc, - void *img, unsigned int img_len, + void *img_ptr, unsigned int img_len, void **param_ptr, unsigned int *param_len); /* Macro to register an image parser library */ diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S index 8f0a74f0..bfe2449e 100644 --- a/include/lib/cpus/aarch64/cpu_macros.S +++ b/include/lib/cpus/aarch64/cpu_macros.S @@ -230,6 +230,7 @@ CPU_OPS_SIZE = . /* Check whether errata applies */ mov x0, \_rev_var + /* Shall clobber: x0-x7 */ bl check_errata_\_id .ifeq \_chosen diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index b0db8f08..f79450ce 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -11,6 +11,7 @@ #include <cassert.h> #include <cpu_data.h> #include <stdint.h> +#include <tzc_common.h> #include <utils_def.h> /******************************************************************************* @@ -21,6 +22,43 @@ struct meminfo; struct image_info; struct bl_params; +typedef struct arm_tzc_regions_info { + unsigned long long base; + unsigned long long end; + tzc_region_attributes_t sec_attr; + unsigned int nsaid_permissions; +} arm_tzc_regions_info_t; + +/******************************************************************************* + * Default mapping definition of the TrustZone Controller for ARM standard + * platforms. + * Configure: + * - Region 0 with no access; + * - Region 1 with secure access only; + * - the remaining DRAM regions access from the given Non-Secure masters. + ******************************************************************************/ +#if ENABLE_SPM +#define ARM_TZC_REGIONS_DEF \ + {ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \ + TZC_REGION_S_RDWR, 0}, \ + {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \ + PLAT_ARM_TZC_NS_DEV_ACCESS}, \ + {ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \ + PLAT_ARM_TZC_NS_DEV_ACCESS}, \ + {ARM_SP_IMAGE_NS_BUF_BASE, (ARM_SP_IMAGE_NS_BUF_BASE + \ + ARM_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE, \ + PLAT_ARM_TZC_NS_DEV_ACCESS} + +#else +#define ARM_TZC_REGIONS_DEF \ + {ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \ + TZC_REGION_S_RDWR, 0}, \ + {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \ + PLAT_ARM_TZC_NS_DEV_ACCESS}, \ + {ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \ + PLAT_ARM_TZC_NS_DEV_ACCESS} +#endif + #define ARM_CASSERT_MMAP \ CASSERT((ARRAY_SIZE(plat_arm_mmap) + ARM_BL_REGIONS) \ <= MAX_MMAP_REGIONS, \ @@ -110,9 +148,10 @@ void arm_setup_page_tables(uintptr_t total_base, void arm_io_setup(void); /* Security utility functions */ -void arm_tzc400_setup(void); +void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions); struct tzc_dmc500_driver_data; -void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data); +void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data, + const arm_tzc_regions_info_t *tzc_regions); /* Systimer utility function */ void arm_configure_sys_timer(void); diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h index 84923b9a..827d416f 100644 --- a/include/plat/common/common_def.h +++ b/include/plat/common/common_def.h @@ -78,9 +78,19 @@ #define BL1_CODE_END BL_CODE_END #define BL1_RO_DATA_BASE BL_RO_DATA_BASE #define BL1_RO_DATA_END round_up(BL1_ROM_END, PAGE_SIZE) +#if BL2_IN_XIP_MEM +#define BL2_CODE_END BL_CODE_END +#define BL2_RO_DATA_BASE BL_RO_DATA_BASE +#define BL2_RO_DATA_END round_up(BL2_ROM_END, PAGE_SIZE) +#endif /* BL2_IN_XIP_MEM */ #else #define BL_RO_DATA_BASE 0 #define BL_RO_DATA_END 0 #define BL1_CODE_END round_up(BL1_ROM_END, PAGE_SIZE) +#if BL2_IN_XIP_MEM +#define BL2_RO_DATA_BASE 0 +#define BL2_RO_DATA_END 0 +#define BL2_CODE_END round_up(BL2_ROM_END, PAGE_SIZE) +#endif /* BL2_IN_XIP_MEM */ #endif /* SEPARATE_CODE_AND_RODATA */ #endif /* __COMMON_DEF_H__ */ diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S index 3e480bc1..3a23e025 100644 --- a/lib/cpus/aarch64/cortex_a53.S +++ b/lib/cpus/aarch64/cortex_a53.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +9,7 @@ #include <cortex_a53.h> #include <cpu_macros.S> #include <debug.h> +#include <errata_report.h> #include <plat_macros.S> #if A53_DISABLE_NON_TEMPORAL_HINT @@ -144,8 +145,23 @@ endfunc check_errata_855873 * This workaround is statically enabled at build time. */ func check_errata_835769 - mov x1, #0x04 - b cpu_rev_var_ls + cmp x0, #0x04 + b.hi errata_not_applies + /* + * Fix potentially available for revisions r0p2, r0p3 and r0p4. + * If r0p2, r0p3 or r0p4; check for fix in REVIDR, else exit. + */ + cmp x0, #0x01 + mov x0, #ERRATA_APPLIES + b.ls exit_check_errata_835769 + /* Load REVIDR. */ + mrs x1, revidr_el1 + /* If REVIDR[7] is set (fix exists) set ERRATA_NOT_APPLIES, else exit. */ + tbz x1, #7, exit_check_errata_835769 +errata_not_applies: + mov x0, #ERRATA_NOT_APPLIES +exit_check_errata_835769: + ret endfunc check_errata_835769 /* @@ -154,8 +170,22 @@ endfunc check_errata_835769 * This workaround is statically enabled at build time. */ func check_errata_843419 - mov x1, #0x04 - b cpu_rev_var_ls + mov x1, #ERRATA_APPLIES + mov x2, #ERRATA_NOT_APPLIES + cmp x0, #0x04 + csel x0, x1, x2, ls + /* + * Fix potentially available for revision r0p4. + * If r0p4 check for fix in REVIDR, else exit. + */ + b.ne exit_check_errata_843419 + /* Load REVIDR. */ + mrs x3, revidr_el1 + /* If REVIDR[8] is set (fix exists) set ERRATA_NOT_APPLIES, else exit. */ + tbz x3, #8, exit_check_errata_843419 + mov x0, x2 +exit_check_errata_843419: + ret endfunc check_errata_843419 /* ------------------------------------------------- diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S index 5a9226d8..9f13ed2c 100644 --- a/lib/cpus/aarch64/cpu_helpers.S +++ b/lib/cpus/aarch64/cpu_helpers.S @@ -198,6 +198,8 @@ endfunc cpu_get_rev_var * Compare the CPU's revision-variant (x0) with a given value (x1), for errata * application purposes. If the revision-variant is less than or same as a given * value, indicates that errata applies; otherwise not. + * + * Shall clobber: x0-x3 */ .globl cpu_rev_var_ls func cpu_rev_var_ls @@ -212,6 +214,8 @@ endfunc cpu_rev_var_ls * Compare the CPU's revision-variant (x0) with a given value (x1), for errata * application purposes. If the revision-variant is higher than or same as a * given value, indicates that errata applies; otherwise not. + * + * Shall clobber: x0-x3 */ .globl cpu_rev_var_hs func cpu_rev_var_hs diff --git a/lib/xlat_tables_v2/xlat_tables_internal.c b/lib/xlat_tables_v2/xlat_tables_internal.c index 653260ce..522b167d 100644 --- a/lib/xlat_tables_v2/xlat_tables_internal.c +++ b/lib/xlat_tables_v2/xlat_tables_internal.c @@ -735,7 +735,8 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, const mmap_region_t *mm) void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm) { mmap_region_t *mm_cursor = ctx->mmap; - mmap_region_t *mm_last = mm_cursor + ctx->mmap_num; + const mmap_region_t *mm_end = ctx->mmap + ctx->mmap_num; + mmap_region_t *mm_last; unsigned long long end_pa = mm->base_pa + mm->size - 1; uintptr_t end_va = mm->base_va + mm->size - 1; int ret; @@ -786,6 +787,21 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm) && (mm_cursor->size < mm->size)) ++mm_cursor; + /* + * Find the last entry marker in the mmap + */ + mm_last = ctx->mmap; + while ((mm_last->size != 0U) && (mm_last < mm_end)) { + ++mm_last; + } + + /* + * Check if we have enough space in the memory mapping table. + * This shouldn't happen as we have checked in mmap_add_region_check + * that there is free space. + */ + assert(mm_last->size == 0U); + /* Make room for new region by moving other regions up by one place */ memmove(mm_cursor + 1, mm_cursor, (uintptr_t)mm_last - (uintptr_t)mm_cursor); @@ -795,7 +811,7 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm) * This shouldn't happen as we have checked in mmap_add_region_check * that there is free space. */ - assert(mm_last->size == 0); + assert(mm_end->size == 0U); *mm_cursor = *mm; diff --git a/maintainers.rst b/maintainers.rst index 77b851e9..2217cbe0 100644 --- a/maintainers.rst +++ b/maintainers.rst @@ -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 diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 751f8343..77eb157c 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -30,6 +30,10 @@ BASE_COMMIT := origin/master # Execute BL2 at EL3 BL2_AT_EL3 := 0 +# BL2 image is stored in XIP memory, for now, this option is only supported +# when BL2_AT_EL3 is 1. +BL2_IN_XIP_MEM := 0 + # By default, consider that the platform may release several CPUs out of reset. # The platform Makefile is free to override this value. COLD_BOOT_SINGLE_CPU := 0 diff --git a/plat/arm/board/fvp/aarch32/fvp_helpers.S b/plat/arm/board/fvp/aarch32/fvp_helpers.S index 143972d2..5d885469 100644 --- a/plat/arm/board/fvp/aarch32/fvp_helpers.S +++ b/plat/arm/board/fvp/aarch32/fvp_helpers.S @@ -104,15 +104,20 @@ func plat_is_my_cpu_primary bx lr endfunc plat_is_my_cpu_primary - /* ----------------------------------------------------- + /* --------------------------------------------------------------------- * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) * * Function to calculate the core position on FVP. * - * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER) + + * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU) + * (CPUId * FVP_MAX_PE_PER_CPU) + * ThreadId - * ----------------------------------------------------- + * + * which can be simplified as: + * + * ((ClusterId * FVP_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_MAX_PE_PER_CPU) + * + ThreadId + * --------------------------------------------------------------------- */ func plat_arm_calc_core_pos mov r3, r0 @@ -125,14 +130,15 @@ func plat_arm_calc_core_pos lsleq r3, r0, #MPIDR_AFFINITY_BITS /* Extract individual affinity fields from MPIDR */ - mov r2, #FVP_MAX_PE_PER_CPU ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS - mla r0, r1, r2, r0 - - mov r1, #FVP_MAX_CPUS_PER_CLUSTER ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS - mla r0, r1, r2, r0 + + /* Compute linear position */ + mov r3, #FVP_MAX_CPUS_PER_CLUSTER + mla r1, r2, r3, r1 + mov r3, #FVP_MAX_PE_PER_CPU + mla r0, r1, r3, r0 bx lr endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/fvp/fvp_private.h b/plat/arm/board/fvp/fvp_private.h index c5cd07d1..16f10a22 100644 --- a/plat/arm/board/fvp/fvp_private.h +++ b/plat/arm/board/fvp/fvp_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,6 +18,7 @@ void fvp_config_setup(void); void fvp_interconnect_init(void); void fvp_interconnect_enable(void); void fvp_interconnect_disable(void); +void tsp_early_platform_setup(void); #endif /* __FVP_PRIVATE_H__ */ diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c index 4559865b..a6c92278 100644 --- a/plat/arm/board/fvp/fvp_security.c +++ b/plat/arm/board/fvp/fvp_security.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,5 +22,5 @@ void plat_arm_security_setup(void) */ if (get_arm_config()->flags & ARM_CONFIG_HAS_TZC) - arm_tzc400_setup(); + arm_tzc400_setup(NULL); } diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 2e2fdd7a..b4223987 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -110,12 +110,14 @@ */ #if TRUSTED_BOARD_BOOT #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA -# define PLAT_ARM_MAX_BL2_SIZE 0x1F000 +# define PLAT_ARM_MAX_BL2_SIZE 0x20000 +#elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA +# define PLAT_ARM_MAX_BL2_SIZE 0x1D000 #else -# define PLAT_ARM_MAX_BL2_SIZE 0x1B000 +# define PLAT_ARM_MAX_BL2_SIZE 0x1C000 #endif #else -# define PLAT_ARM_MAX_BL2_SIZE 0xD000 +# define PLAT_ARM_MAX_BL2_SIZE 0xE000 #endif /* diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c index ce4239bf..b6cfe781 100644 --- a/plat/arm/board/juno/juno_security.c +++ b/plat/arm/board/juno/juno_security.c @@ -1,15 +1,80 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <debug.h> #include <mmio.h> #include <nic_400.h> #include <plat_arm.h> #include <soc_css.h> + #include "juno_def.h" +#include "juno_tzmp1_def.h" + +#ifdef JUNO_TZMP1 +/* + * Protect buffer for VPU/GPU/DPU memory usage with hardware protection + * enabled. Propose 224MB video output, 96 MB video input and 32MB video + * private. + * + * Ind Memory Range Caption S_ATTR NS_ATTR + * 1 0x080000000 - 0x0E7FFFFFF ARM_NS_DRAM1 NONE RDWR | MEDIA_RW + * 2 0x0E8000000 - 0x0F5FFFFFF JUNO_MEDIA_TZC_PROT_DRAM1 NONE MEDIA_RW | AP_WR + * 3 0x0F6000000 - 0x0FBFFFFFF JUNO_VPU_TZC_PROT_DRAM1 RDWR VPU_PROT_RW + * 4 0x0FC000000 - 0x0FDFFFFFF JUNO_VPU_TZC_PRIV_DRAM1 RDWR VPU_PRIV_RW + * 5 0x0FE000000 - 0x0FEFFFFFF JUNO_AP_TZC_SHARE_DRAM1 NONE RDWR | MEDIA_RW + * 6 0x0FF000000 - 0x0FFFFFFFF ARM_AP_TZC_DRAM1 RDWR NONE + * 7 0x880000000 - 0x9FFFFFFFF ARM_DRAM2 NONE RDWR | MEDIA_RW + * + * Memory regions are neighbored to save limited TZC regions. Calculation + * started from ARM_TZC_SHARE_DRAM1 since it is known and fixed for both + * protected-enabled and protected-disabled settings. + * + * Video private buffer aheads of ARM_TZC_SHARE_DRAM1 + */ + +static const arm_tzc_regions_info_t juno_tzmp1_tzc_regions[] = { + {ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END, TZC_REGION_S_RDWR, 0}, + {JUNO_NS_DRAM1_PT1_BASE, JUNO_NS_DRAM1_PT1_END, + TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS}, + {JUNO_MEDIA_TZC_PROT_DRAM1_BASE, JUNO_MEDIA_TZC_PROT_DRAM1_END, + TZC_REGION_S_NONE, JUNO_MEDIA_TZC_PROT_ACCESS}, + {JUNO_VPU_TZC_PROT_DRAM1_BASE, JUNO_VPU_TZC_PROT_DRAM1_END, + TZC_REGION_S_RDWR, JUNO_VPU_TZC_PROT_ACCESS}, + {JUNO_VPU_TZC_PRIV_DRAM1_BASE, JUNO_VPU_TZC_PRIV_DRAM1_END, + TZC_REGION_S_RDWR, JUNO_VPU_TZC_PRIV_ACCESS}, + {JUNO_AP_TZC_SHARE_DRAM1_BASE, JUNO_AP_TZC_SHARE_DRAM1_END, + TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS}, + {ARM_DRAM2_BASE, ARM_DRAM2_END, + TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS}, + {}, +}; + +/******************************************************************************* + * Program dp650 to configure NSAID value for protected mode. + ******************************************************************************/ +static void init_dp650(void) +{ + mmio_write_32(DP650_BASE + DP650_PROT_NSAID_OFFSET, + DP650_PROT_NSAID_CONFIG); +} + +/******************************************************************************* + * Program v550 to configure NSAID value for protected mode. + ******************************************************************************/ +static void init_v550(void) +{ + /* + * bits[31:28] is for PRIVATE, + * bits[27:24] is for OUTBUF, + * bits[23:20] is for PROTECTED. + */ + mmio_write_32(V550_BASE + V550_PROTCTRL_OFFSET, V550_PROTCTRL_CONFIG); +} +#endif /* JUNO_TZMP1 */ /******************************************************************************* * Set up the MMU-401 SSD tables. The power-on configuration has all stream IDs @@ -59,11 +124,23 @@ void plat_arm_security_setup(void) /* Initialize debug configuration */ init_debug_cfg(); /* Initialize the TrustZone Controller */ - arm_tzc400_setup(); +#ifdef JUNO_TZMP1 + arm_tzc400_setup(juno_tzmp1_tzc_regions); + INFO("TZC protected shared memory base address for TZMP usecase: %p\n", + (void *)JUNO_AP_TZC_SHARE_DRAM1_BASE); + INFO("TZC protected shared memory end address for TZMP usecase: %p\n", + (void *)JUNO_AP_TZC_SHARE_DRAM1_END); +#else + arm_tzc400_setup(NULL); +#endif /* Do ARM CSS internal NIC setup */ css_init_nic400(); /* Do ARM CSS SoC security setup */ soc_css_security_setup(); /* Initialize the SMMU SSD tables */ init_mmu401(); +#ifdef JUNO_TZMP1 + init_dp650(); + init_v550(); +#endif } diff --git a/plat/arm/board/juno/juno_tzmp1_def.h b/plat/arm/board/juno/juno_tzmp1_def.h new file mode 100644 index 00000000..7055f76a --- /dev/null +++ b/plat/arm/board/juno/juno_tzmp1_def.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __JUNO_TZMP1_DEF_H__ +#define __JUNO_TZMP1_DEF_H__ + +#include <plat_arm.h> + +/* + * Public memory regions for both protected and non-protected mode + * + * OPTEE shared memory 0xFEE00000 - 0xFEFFFFFF + */ +#define JUNO_AP_TZC_SHARE_DRAM1_SIZE ULL(0x02000000) +#define JUNO_AP_TZC_SHARE_DRAM1_BASE (ARM_AP_TZC_DRAM1_BASE - \ + JUNO_AP_TZC_SHARE_DRAM1_SIZE) +#define JUNO_AP_TZC_SHARE_DRAM1_END (ARM_AP_TZC_DRAM1_BASE - 1) + +/* ARM_MEDIA_FEATURES for MEDIA GPU Protect Mode Test */ +#define JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE 8 /* GPU/DPU protected, VPU outbuf */ +#define JUNO_TZC400_NSAID_FPGA_VIDEO_PROTECTED 7 /* VPU protected */ +#define JUNO_TZC400_NSAID_FPGA_VIDEO_PRIVATE 10 /* VPU private (firmware) */ + +#define JUNO_VPU_TZC_PRIV_DRAM1_SIZE ULL(0x02000000) +#define JUNO_VPU_TZC_PRIV_DRAM1_BASE (JUNO_AP_TZC_SHARE_DRAM1_BASE - \ + JUNO_VPU_TZC_PRIV_DRAM1_SIZE) +#define JUNO_VPU_TZC_PRIV_DRAM1_END (JUNO_AP_TZC_SHARE_DRAM1_BASE - 1) + +/* Video input protected buffer follows upper item */ +#define JUNO_VPU_TZC_PROT_DRAM1_SIZE ULL(0x06000000) +#define JUNO_VPU_TZC_PROT_DRAM1_BASE (JUNO_VPU_TZC_PRIV_DRAM1_BASE - \ + JUNO_VPU_TZC_PROT_DRAM1_SIZE) +#define JUNO_VPU_TZC_PROT_DRAM1_END (JUNO_VPU_TZC_PRIV_DRAM1_BASE - 1) + +/* Video, graphics and display shares same NSAID and same protected buffer */ +#define JUNO_MEDIA_TZC_PROT_DRAM1_SIZE ULL(0x0e000000) +#define JUNO_MEDIA_TZC_PROT_DRAM1_BASE (JUNO_VPU_TZC_PROT_DRAM1_BASE - \ + JUNO_MEDIA_TZC_PROT_DRAM1_SIZE) +#define JUNO_MEDIA_TZC_PROT_DRAM1_END (JUNO_VPU_TZC_PROT_DRAM1_BASE - 1) + +/* Rest of DRAM1 are Non-Secure public buffer */ +#define JUNO_NS_DRAM1_PT1_BASE ARM_DRAM1_BASE +#define JUNO_NS_DRAM1_PT1_END (JUNO_MEDIA_TZC_PROT_DRAM1_BASE - 1) +#define JUNO_NS_DRAM1_PT1_SIZE (JUNO_NS_DRAM1_PT1_END - \ + JUNO_NS_DRAM1_PT1_BASE + 1) + +/* TZC filter flags */ +#define JUNO_MEDIA_TZC_NS_DEV_ACCESS (PLAT_ARM_TZC_NS_DEV_ACCESS | \ + TZC_REGION_ACCESS_RD(JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE)) + +/* VPU / GPU /DPU protected access */ +#define JUNO_MEDIA_TZC_PROT_ACCESS \ + (TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE) | \ + TZC_REGION_ACCESS_WR(TZC400_NSAID_AP)) + +#define JUNO_VPU_TZC_PROT_ACCESS \ + (TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_VIDEO_PROTECTED)) + +#define JUNO_VPU_TZC_PRIV_ACCESS \ + (TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_VIDEO_PRIVATE)) + +/******************************************************************************* + * Mali-DP650 related constants + ******************************************************************************/ +/* Base address of DP650 */ +#define DP650_BASE 0x6f200000 +/* offset to PROT_NSAID register */ +#define DP650_PROT_NSAID_OFFSET 0x10004 +/* config to PROT_NSAID register */ +#define DP650_PROT_NSAID_CONFIG 0x08008888 + +/******************************************************************************* + * Mali-V550 related constants + ******************************************************************************/ +/* Base address of V550 */ +#define V550_BASE 0x6f030000 +/* offset to PROTCTRL register */ +#define V550_PROTCTRL_OFFSET 0x0040 +/* config to PROTCTRL register */ +#define V550_PROTCTRL_CONFIG 0xa8700000 + +#endif /* __JUNO_TZMP1_DEF_H__ */ diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 656fc14c..3ab99ef3 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -31,6 +31,13 @@ JUNO_AARCH32_EL3_RUNTIME := 0 $(eval $(call assert_boolean,JUNO_AARCH32_EL3_RUNTIME)) $(eval $(call add_define,JUNO_AARCH32_EL3_RUNTIME)) +# Flag to enable support for TZMP1 on JUNO +JUNO_TZMP1 := 0 +$(eval $(call assert_boolean,JUNO_TZMP1)) +ifeq (${JUNO_TZMP1}, 1) +$(eval $(call add_define,JUNO_TZMP1)) +endif + ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1) # Include BL32 in FIP NEED_BL32 := yes diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c index 1305934c..f2be4779 100644 --- a/plat/arm/common/arm_bl1_fwu.c +++ b/plat/arm/common/arm_bl1_fwu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +9,7 @@ #include <debug.h> #include <errno.h> #include <plat_arm.h> +#include <platform.h> #include <platform_def.h> #include <tbbr_img_desc.h> #include <utils.h> @@ -19,7 +20,7 @@ typedef struct bl1_mem_info { unsigned int mem_size; } bl1_mem_info_t; -bl1_mem_info_t fwu_addr_map_secure[] = { +static bl1_mem_info_t fwu_addr_map_secure[] = { { .mem_base = ARM_SHARED_RAM_BASE, .mem_size = ARM_SHARED_RAM_SIZE @@ -29,7 +30,7 @@ bl1_mem_info_t fwu_addr_map_secure[] = { } }; -bl1_mem_info_t fwu_addr_map_non_secure[] = { +static bl1_mem_info_t fwu_addr_map_non_secure[] = { { .mem_base = ARM_NS_DRAM1_BASE, .mem_size = ARM_NS_DRAM1_SIZE diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index cfcbf2a2..9ba51a3e 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <arm_dyn_cfg_helpers.h> #include <assert.h> #include <desc_image_load.h> #include <fdt_wrappers.h> diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c index 6b706be9..a32736c3 100644 --- a/plat/arm/common/arm_tzc400.c +++ b/plat/arm/common/arm_tzc400.c @@ -18,16 +18,20 @@ /******************************************************************************* * Initialize the TrustZone Controller for ARM standard platforms. - * Configure: - * - Region 0 with no access; - * - Region 1 with secure access only; - * - the remaining DRAM regions access from the given Non-Secure masters. - * * When booting an EL3 payload, this is simplified: we configure region 0 with * secure access only and do not enable any other region. ******************************************************************************/ -void arm_tzc400_setup(void) +void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) { +#ifndef EL3_PAYLOAD_BASE + int region_index = 1; + const arm_tzc_regions_info_t *p; + const arm_tzc_regions_info_t init_tzc_regions[] = { + ARM_TZC_REGIONS_DEF, + {0} + }; +#endif + INFO("Configuring TrustZone Controller\n"); tzc400_init(PLAT_ARM_TZC_BASE); @@ -36,42 +40,22 @@ void arm_tzc400_setup(void) tzc400_disable_filters(); #ifndef EL3_PAYLOAD_BASE + if (tzc_regions == NULL) + p = init_tzc_regions; + else + p = tzc_regions; /* Region 0 set to no access by default */ tzc400_configure_region0(TZC_REGION_S_NONE, 0); - /* Region 1 set to cover Secure part of DRAM */ - tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 1, - ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, - TZC_REGION_S_RDWR, - 0); - - /* Region 2 set to cover Non-Secure access to 1st DRAM address range. - * Apply the same configuration to given filters in the TZC. */ - tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 2, - ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, - ARM_TZC_NS_DRAM_S_ACCESS, - PLAT_ARM_TZC_NS_DEV_ACCESS); - - /* Region 3 set to cover Non-Secure access to 2nd DRAM address range */ - tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 3, - ARM_DRAM2_BASE, ARM_DRAM2_END, - ARM_TZC_NS_DRAM_S_ACCESS, - PLAT_ARM_TZC_NS_DEV_ACCESS); - -#if ENABLE_SPM - /* - * Region 4 set to cover Non-Secure access to the communication buffer - * shared with the Secure world. - */ - tzc400_configure_region(PLAT_ARM_TZC_FILTERS, - 4, - ARM_SP_IMAGE_NS_BUF_BASE, - (ARM_SP_IMAGE_NS_BUF_BASE + - ARM_SP_IMAGE_NS_BUF_SIZE) - 1, - TZC_REGION_S_NONE, - PLAT_ARM_TZC_NS_DEV_ACCESS); -#endif + /* Rest Regions set according to tzc_regions array */ + for (; p->base != 0ULL; p++) { + tzc400_configure_region(PLAT_ARM_TZC_FILTERS, region_index, + p->base, p->end, p->sec_attr, p->nsaid_permissions); + region_index++; + } + + INFO("Total %d regions set.\n", region_index); #else /* if defined(EL3_PAYLOAD_BASE) */ @@ -92,5 +76,5 @@ void arm_tzc400_setup(void) void plat_arm_security_setup(void) { - arm_tzc400_setup(); + arm_tzc400_setup(NULL); } diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c index 8e41391f..89c502cc 100644 --- a/plat/arm/common/arm_tzc_dmc500.c +++ b/plat/arm/common/arm_tzc_dmc500.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,15 +12,21 @@ /******************************************************************************* * Initialize the DMC500-TrustZone Controller for ARM standard platforms. - * Configure both the interfaces on Region 0 with no access, Region 1 with - * secure access only, and the remaining DRAM regions access from the - * given Non-Secure masters. - * * When booting an EL3 payload, this is simplified: we configure region 0 with * secure access only and do not enable any other region. ******************************************************************************/ -void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data) +void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data, + const arm_tzc_regions_info_t *tzc_regions) { +#ifndef EL3_PAYLOAD_BASE + int region_index = 1; + const arm_tzc_regions_info_t *p; + const arm_tzc_regions_info_t init_tzc_regions[] = { + ARM_TZC_REGIONS_DEF, + {0} + }; +#endif + assert(plat_driver_data); INFO("Configuring DMC-500 TZ Settings\n"); @@ -28,28 +34,23 @@ void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data) tzc_dmc500_driver_init(plat_driver_data); #ifndef EL3_PAYLOAD_BASE + if (tzc_regions == NULL) + p = init_tzc_regions; + else + p = tzc_regions; + /* Region 0 set to no access by default */ tzc_dmc500_configure_region0(TZC_REGION_S_NONE, 0); - /* Region 1 set to cover Secure part of DRAM */ - tzc_dmc500_configure_region(1, ARM_AP_TZC_DRAM1_BASE, - ARM_EL3_TZC_DRAM1_END, - TZC_REGION_S_RDWR, - 0); + /* Rest Regions set according to tzc_regions array */ + for (; p->base != 0ULL; p++) { + tzc_dmc500_configure_region(region_index, p->base, p->end, + p->sec_attr, p->nsaid_permissions); + region_index++; + } - /* Region 2 set to cover Non-Secure access to 1st DRAM address range.*/ - tzc_dmc500_configure_region(2, - ARM_NS_DRAM1_BASE, - ARM_NS_DRAM1_END, - ARM_TZC_NS_DRAM_S_ACCESS, - PLAT_ARM_TZC_NS_DEV_ACCESS); + INFO("Total %d regions set.\n", region_index); - /* Region 3 set to cover Non-Secure access to 2nd DRAM address range */ - tzc_dmc500_configure_region(3, - ARM_DRAM2_BASE, - ARM_DRAM2_END, - ARM_TZC_NS_DRAM_S_ACCESS, - PLAT_ARM_TZC_NS_DEV_ACCESS); #else /* Allow secure access only to DRAM for EL3 payloads */ tzc_dmc500_configure_region0(TZC_REGION_S_RDWR, 0); diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c index 5f674969..c0ed4874 100644 --- a/plat/arm/css/drivers/scp/css_pm_scmi.c +++ b/plat/arm/css/drivers/scp/css_pm_scmi.c @@ -77,7 +77,7 @@ ARM_INSTANTIATE_LOCK; * Helper function to suspend a CPU power domain and its parent power domains * if applicable. */ -void css_scp_suspend(const psci_power_state_t *target_state) +void css_scp_suspend(const struct psci_power_state *target_state) { int lvl, ret; uint32_t scmi_pwr_state = 0; diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/plat/arm/css/drivers/scp/css_pm_scpi.c index 545c3fbe..23fd80ee 100644 --- a/plat/arm/css/drivers/scp/css_pm_scpi.c +++ b/plat/arm/css/drivers/scp/css_pm_scpi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,7 +19,7 @@ /* * Helper function to inform power down state to SCP. */ -void css_scp_suspend(const psci_power_state_t *target_state) +void css_scp_suspend(const struct psci_power_state *target_state) { uint32_t cluster_state = scpi_power_on; uint32_t system_state = scpi_power_on; diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c index a78bb1e9..a3fc607b 100644 --- a/plat/hisilicon/hikey/hikey_bl2_setup.c +++ b/plat/hisilicon/hikey/hikey_bl2_setup.c @@ -304,15 +304,13 @@ void bl2_platform_setup(void) hikey_gpio_init(); hikey_pmussi_init(); hikey_hi6553_init(); + /* Clear SRAM since it'll be used by MCU right now. */ + memset((void *)SRAM_BASE, 0, SRAM_SIZE); dsb(); - hikey_ddr_init(); + hikey_ddr_init(DDR_FREQ_800M); hikey_security_setup(); - /* Clear SRAM since it'll be used by MCU right now. */ - memset((void *)SRAM_BASE, 0, SRAM_SIZE); - clean_dcache_range(SRAM_BASE, SRAM_SIZE); - hikey_boardid_init(); init_acpu_dvfs(); hikey_rtc_init(); @@ -321,6 +319,9 @@ void bl2_platform_setup(void) hikey_mmc_pll_init(); + /* Clean SRAM before MCU used */ + clean_dcache_range(SRAM_BASE, SRAM_SIZE); + reset_dwmmc_clk(); memset(¶ms, 0, sizeof(dw_mmc_params_t)); params.reg_base = DWMMC0_BASE; diff --git a/plat/hisilicon/hikey/hikey_ddr.c b/plat/hisilicon/hikey/hikey_ddr.c index ab572eb1..43cece00 100644 --- a/plat/hisilicon/hikey/hikey_ddr.c +++ b/plat/hisilicon/hikey/hikey_ddr.c @@ -5,17 +5,16 @@ */ #include <arch_helpers.h> +#include <assert.h> #include <debug.h> #include <errno.h> #include <hi6220.h> #include <hi6553.h> +#include <hisi_sram_map.h> #include <mmio.h> #include <sp804_delay_timer.h> -enum { - DDR_FREQ_533M = 0, - DDR_FREQ_800M, -}; +#include "hikey_private.h" static void init_pll(void) { @@ -24,7 +23,6 @@ static void init_pll(void) data = mmio_read_32((0xf7032000 + 0x000)); data |= 0x1; mmio_write_32((0xf7032000 + 0x000), data); - dsb(); do { data = mmio_read_32((0xf7032000 + 0x000)); } while (!(data & (1 << 28))); @@ -33,22 +31,45 @@ static void init_pll(void) data &= ~0x007; data |= 0x004; mmio_write_32((0xf7800000 + 0x000), data); - dsb(); do { data = mmio_read_32((0xf7800000 + 0x014)); data &= 0x007; } while (data != 0x004); mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101); - data = mmio_read_32(PERI_SC_PERIPH_STAT1); + dsb(); + isb(); + udelay(10); + mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2001); + dsb(); + isb(); + udelay(10); + mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2201); + dsb(); + isb(); + udelay(10); mmio_write_32(0xf7032000 + 0x02c, 0x5110103e); + dsb(); + isb(); + udelay(10); data = mmio_read_32(0xf7032000 + 0x050); data |= 1 << 28; mmio_write_32(0xf7032000 + 0x050, data); + dsb(); + isb(); + udelay(10); mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101); - mdelay(1); - data = mmio_read_32(PERI_SC_PERIPH_STAT1); - NOTICE("syspll frequency:%dHz\n", data); + dsb(); + isb(); + udelay(10); + mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2001); + dsb(); + isb(); + udelay(10); + mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2201); + dsb(); + isb(); + udelay(10); } static void init_freq(void) @@ -215,7 +236,7 @@ int cat_533mhz_800mhz(void) data = mmio_read_32((0xf712c000 + 0x1c8)); data &= 0xfffff0f0; - data |= 0x100f0f; + data |= 0x100f01; mmio_write_32((0xf712c000 + 0x1c8), data); for (i = 0; i < 0x20; i++) { @@ -244,7 +265,7 @@ int cat_533mhz_800mhz(void) } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); - if (!(data & 0x400)) { + if ((data & 0x400) == 0) { mdelay(10); return 0; } @@ -489,7 +510,334 @@ static void ddrx_wdet(void) INFO("wdet rbs av fail\n"); } -static void set_ddrc_533mhz(void) +void set_ddrc_150mhz(void) +{ + unsigned int data; + + mmio_write_32((0xf7032000 + 0x580), 0x1); + mmio_write_32((0xf7032000 + 0x5a8), 0x7); + data = mmio_read_32((0xf7032000 + 0x104)); + data &= 0xfffffcff; + mmio_write_32((0xf7032000 + 0x104), data); + + mmio_write_32((0xf7030000 + 0x050), 0x31); + mmio_write_32((0xf7030000 + 0x240), 0x5ffff); + mmio_write_32((0xf7030000 + 0x344), 0xf5ff); + mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f); + mmio_write_32((0xf712c000 + 0x00c), 0xf0f); + mmio_write_32((0xf712c000 + 0x018), 0x7); + mmio_write_32((0xf712c000 + 0x090), 0x7200000); + mmio_write_32((0xf712c000 + 0x258), 0x720); + mmio_write_32((0xf712c000 + 0x2d8), 0x720); + mmio_write_32((0xf712c000 + 0x358), 0x720); + mmio_write_32((0xf712c000 + 0x3d8), 0x720); + mmio_write_32((0xf712c000 + 0x018), 0x7); + mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f); + mmio_write_32((0xf712c000 + 0x0b4), 0xf); + mmio_write_32((0xf712c000 + 0x088), 0x3fff801); + mmio_write_32((0xf712c000 + 0x070), 0x8940000); + + data = mmio_read_32((0xf712c000 + 0x078)); + data |= 4; + mmio_write_32((0xf712c000 + 0x078), data); + mmio_write_32((0xf712c000 + 0x01c), 0x8000080); + data = mmio_read_32((0xf712c000 + 0x020)); + data &= 0xfffffffe; + mmio_write_32((0xf712c000 + 0x020), data); + mmio_write_32((0xf712c000 + 0x1d4), 0xc0000); + mmio_write_32((0xf712c000 + 0x010), 0x500000f); + mmio_write_32((0xf712c000 + 0x014), 0x10); + data = mmio_read_32((0xf712c000 + 0x1e4)); + data &= 0xffffff00; + mmio_write_32((0xf712c000 + 0x1e4), data); + mmio_write_32((0xf712c000 + 0x030), 0x30c82355); + mmio_write_32((0xf712c000 + 0x034), 0x62112bb); + mmio_write_32((0xf712c000 + 0x038), 0x20041022); + mmio_write_32((0xf712c000 + 0x03c), 0x63177497); + mmio_write_32((0xf712c000 + 0x040), 0x3008407); + mmio_write_32((0xf712c000 + 0x064), 0x10483); + mmio_write_32((0xf712c000 + 0x068), 0xff0a0000); + data = mmio_read_32((0xf712c000 + 0x070)); + data &= 0xffff0000; + data |= 0x184; + mmio_write_32((0xf712c000 + 0x070), data); + data = mmio_read_32((0xf712c000 + 0x048)); + data &= 0xbfffffff; + mmio_write_32((0xf712c000 + 0x048), data); + data = mmio_read_32((0xf712c000 + 0x020)); + data &= ~0x10; + mmio_write_32((0xf712c000 + 0x020), data); + data = mmio_read_32((0xf712c000 + 0x080)); + data &= ~0x2000; + mmio_write_32((0xf712c000 + 0x080), data); + mmio_write_32((0xf712c000 + 0x270), 0x3); + mmio_write_32((0xf712c000 + 0x2f0), 0x3); + mmio_write_32((0xf712c000 + 0x370), 0x3); + mmio_write_32((0xf712c000 + 0x3f0), 0x3); + mmio_write_32((0xf712c000 + 0x048), 0x90420880); + + mmio_write_32((0xf7128000 + 0x040), 0x0); + mmio_write_32((0xf712c000 + 0x004), 0x146d); + mmio_write_32((0xf7128000 + 0x050), 0x100123); + mmio_write_32((0xf7128000 + 0x060), 0x133); + mmio_write_32((0xf7128000 + 0x064), 0x133); + mmio_write_32((0xf7128000 + 0x200), 0xa1000); + + mmio_write_32((0xf7128000 + 0x100), 0xb3290d08); + mmio_write_32((0xf7128000 + 0x104), 0x9621821); + mmio_write_32((0xf7128000 + 0x108), 0x45009023); + mmio_write_32((0xf7128000 + 0x10c), 0xaf44c145); + mmio_write_32((0xf7128000 + 0x110), 0x10b00000); + mmio_write_32((0xf7128000 + 0x114), 0x11080806); + mmio_write_32((0xf7128000 + 0x118), 0x44); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 8) { + NOTICE("fail to init ddr3 rank0\n"); + return; + } + + data = mmio_read_32((0xf712c000 + 0x048)); + data |= 1; + mmio_write_32((0xf712c000 + 0x048), data); + mmio_write_32((0xf712c000 + 0x004), 0x21); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 0x8) + NOTICE("ddr3 rank1 init failure\n"); + else + INFO("ddr3 rank1 init pass\n"); + + data = mmio_read_32((0xf712c000 + 0x048)); + data &= ~0xf; + mmio_write_32((0xf712c000 + 0x048), data); + INFO("succeed to set ddrc 150mhz\n"); +} + +void set_ddrc_266mhz(void) +{ + unsigned int data; + + mmio_write_32((0xf7032000 + 0x580), 0x3); + mmio_write_32((0xf7032000 + 0x5a8), 0x1003); + data = mmio_read_32((0xf7032000 + 0x104)); + data &= 0xfffffcff; + mmio_write_32((0xf7032000 + 0x104), data); + + mmio_write_32((0xf7030000 + 0x050), 0x31); + mmio_write_32((0xf7030000 + 0x240), 0x5ffff); + mmio_write_32((0xf7030000 + 0x344), 0xf5ff); + mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f); + mmio_write_32((0xf712c000 + 0x00c), 0xf0f); + mmio_write_32((0xf712c000 + 0x018), 0x7); + mmio_write_32((0xf712c000 + 0x090), 0x7200000); + mmio_write_32((0xf712c000 + 0x258), 0x720); + mmio_write_32((0xf712c000 + 0x2d8), 0x720); + mmio_write_32((0xf712c000 + 0x358), 0x720); + mmio_write_32((0xf712c000 + 0x3d8), 0x720); + mmio_write_32((0xf712c000 + 0x018), 0x7); + mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f); + mmio_write_32((0xf712c000 + 0x0b4), 0xf); + mmio_write_32((0xf712c000 + 0x088), 0x3fff801); + mmio_write_32((0xf712c000 + 0x070), 0x8940000); + + data = mmio_read_32((0xf712c000 + 0x078)); + data |= 4; + mmio_write_32((0xf712c000 + 0x078), data); + mmio_write_32((0xf712c000 + 0x01c), 0x8000080); + data = mmio_read_32((0xf712c000 + 0x020)); + data &= 0xfffffffe; + mmio_write_32((0xf712c000 + 0x020), data); + mmio_write_32((0xf712c000 + 0x1d4), 0xc0000); + mmio_write_32((0xf712c000 + 0x010), 0x500000f); + mmio_write_32((0xf712c000 + 0x014), 0x10); + data = mmio_read_32((0xf712c000 + 0x1e4)); + data &= 0xffffff00; + mmio_write_32((0xf712c000 + 0x1e4), data); + mmio_write_32((0xf712c000 + 0x030), 0x510d4455); + mmio_write_32((0xf712c000 + 0x034), 0x8391ebb); + mmio_write_32((0xf712c000 + 0x038), 0x2005103c); + mmio_write_32((0xf712c000 + 0x03c), 0x6329950b); + mmio_write_32((0xf712c000 + 0x040), 0x300858c); + mmio_write_32((0xf712c000 + 0x064), 0x10483); + mmio_write_32((0xf712c000 + 0x068), 0xff0a0000); + data = mmio_read_32((0xf712c000 + 0x070)); + data &= 0xffff0000; + data |= 0x184; + mmio_write_32((0xf712c000 + 0x070), data); + data = mmio_read_32((0xf712c000 + 0x048)); + data &= 0xbfffffff; + mmio_write_32((0xf712c000 + 0x048), data); + data = mmio_read_32((0xf712c000 + 0x020)); + data &= ~0x10; + mmio_write_32((0xf712c000 + 0x020), data); + data = mmio_read_32((0xf712c000 + 0x080)); + data &= ~0x2000; + mmio_write_32((0xf712c000 + 0x080), data); + mmio_write_32((0xf712c000 + 0x270), 0x3); + mmio_write_32((0xf712c000 + 0x2f0), 0x3); + mmio_write_32((0xf712c000 + 0x370), 0x3); + mmio_write_32((0xf712c000 + 0x3f0), 0x3); + mmio_write_32((0xf712c000 + 0x048), 0x90420880); + + mmio_write_32((0xf7128000 + 0x040), 0x0); + mmio_write_32((0xf712c000 + 0x004), 0x146d); + mmio_write_32((0xf7128000 + 0x050), 0x100123); + mmio_write_32((0xf7128000 + 0x060), 0x133); + mmio_write_32((0xf7128000 + 0x064), 0x133); + mmio_write_32((0xf7128000 + 0x200), 0xa1000); + + mmio_write_32((0xf7128000 + 0x100), 0xb441d50d); + mmio_write_32((0xf7128000 + 0x104), 0xf721839); + mmio_write_32((0xf7128000 + 0x108), 0x5500f03f); + mmio_write_32((0xf7128000 + 0x10c), 0xaf486145); + mmio_write_32((0xf7128000 + 0x110), 0x10b00000); + mmio_write_32((0xf7128000 + 0x114), 0x12080d06); + mmio_write_32((0xf7128000 + 0x118), 0x44); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 8) { + NOTICE("fail to init ddr3 rank0\n"); + return; + } + + data = mmio_read_32((0xf712c000 + 0x048)); + data |= 1; + mmio_write_32((0xf712c000 + 0x048), data); + mmio_write_32((0xf712c000 + 0x004), 0x21); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 0x8) + NOTICE("ddr3 rank1 init failure\n"); + else + INFO("ddr3 rank1 init pass\n"); + + data = mmio_read_32((0xf712c000 + 0x048)); + data &= ~0xf; + mmio_write_32((0xf712c000 + 0x048), data); + INFO("succeed to set ddrc 266mhz\n"); +} + +void set_ddrc_400mhz(void) +{ + unsigned int data; + + mmio_write_32((0xf7032000 + 0x580), 0x2); + mmio_write_32((0xf7032000 + 0x5a8), 0x1003); + data = mmio_read_32((0xf7032000 + 0x104)); + data &= 0xfffffcff; + mmio_write_32((0xf7032000 + 0x104), data); + + mmio_write_32((0xf7030000 + 0x050), 0x31); + mmio_write_32((0xf7030000 + 0x240), 0x5ffff); + mmio_write_32((0xf7030000 + 0x344), 0xf5ff); + mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f); + mmio_write_32((0xf712c000 + 0x00c), 0xf0f); + mmio_write_32((0xf712c000 + 0x018), 0x7); + mmio_write_32((0xf712c000 + 0x090), 0x7200000); + mmio_write_32((0xf712c000 + 0x258), 0x720); + mmio_write_32((0xf712c000 + 0x2d8), 0x720); + mmio_write_32((0xf712c000 + 0x358), 0x720); + mmio_write_32((0xf712c000 + 0x3d8), 0x720); + mmio_write_32((0xf712c000 + 0x018), 0x7); + mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f); + mmio_write_32((0xf712c000 + 0x0b4), 0xf); + mmio_write_32((0xf712c000 + 0x088), 0x3fff801); + mmio_write_32((0xf712c000 + 0x070), 0x8940000); + + data = mmio_read_32((0xf712c000 + 0x078)); + data |= 4; + mmio_write_32((0xf712c000 + 0x078), data); + mmio_write_32((0xf712c000 + 0x01c), 0x8000080); + data = mmio_read_32((0xf712c000 + 0x020)); + data &= 0xfffffffe; + mmio_write_32((0xf712c000 + 0x020), data); + mmio_write_32((0xf712c000 + 0x1d4), 0xc0000); + mmio_write_32((0xf712c000 + 0x010), 0x500000f); + mmio_write_32((0xf712c000 + 0x014), 0x10); + data = mmio_read_32((0xf712c000 + 0x1e4)); + data &= 0xffffff00; + mmio_write_32((0xf712c000 + 0x1e4), data); + mmio_write_32((0xf712c000 + 0x030), 0x75525655); + mmio_write_32((0xf712c000 + 0x034), 0xa552abb); + mmio_write_32((0xf712c000 + 0x038), 0x20071059); + mmio_write_32((0xf712c000 + 0x03c), 0x633e8591); + mmio_write_32((0xf712c000 + 0x040), 0x3008691); + mmio_write_32((0xf712c000 + 0x064), 0x10483); + mmio_write_32((0xf712c000 + 0x068), 0xff0a0000); + data = mmio_read_32((0xf712c000 + 0x070)); + data &= 0xffff0000; + data |= 0x184; + mmio_write_32((0xf712c000 + 0x070), data); + data = mmio_read_32((0xf712c000 + 0x048)); + data &= 0xbfffffff; + mmio_write_32((0xf712c000 + 0x048), data); + data = mmio_read_32((0xf712c000 + 0x020)); + data &= ~0x10; + mmio_write_32((0xf712c000 + 0x020), data); + data = mmio_read_32((0xf712c000 + 0x080)); + data &= ~0x2000; + mmio_write_32((0xf712c000 + 0x080), data); + mmio_write_32((0xf712c000 + 0x270), 0x3); + mmio_write_32((0xf712c000 + 0x2f0), 0x3); + mmio_write_32((0xf712c000 + 0x370), 0x3); + mmio_write_32((0xf712c000 + 0x3f0), 0x3); + mmio_write_32((0xf712c000 + 0x048), 0x90420880); + + mmio_write_32((0xf7128000 + 0x040), 0x0); + mmio_write_32((0xf712c000 + 0x004), 0x146d); + mmio_write_32((0xf7128000 + 0x050), 0x100123); + mmio_write_32((0xf7128000 + 0x060), 0x133); + mmio_write_32((0xf7128000 + 0x064), 0x133); + mmio_write_32((0xf7128000 + 0x200), 0xa1000); + + mmio_write_32((0xf7128000 + 0x100), 0xb55a9d12); + mmio_write_32((0xf7128000 + 0x104), 0x17721855); + mmio_write_32((0xf7128000 + 0x108), 0x7501505f); + mmio_write_32((0xf7128000 + 0x10c), 0xaf4ca245); + mmio_write_32((0xf7128000 + 0x110), 0x10b00000); + mmio_write_32((0xf7128000 + 0x114), 0x13081306); + mmio_write_32((0xf7128000 + 0x118), 0x44); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 8) { + NOTICE("fail to init ddr3 rank0\n"); + return; + } + + data = mmio_read_32((0xf712c000 + 0x048)); + data |= 1; + mmio_write_32((0xf712c000 + 0x048), data); + mmio_write_32((0xf712c000 + 0x004), 0x21); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 0x8) + NOTICE("ddr3 rank1 init failure\n"); + else + INFO("ddr3 rank1 init pass\n"); + + data = mmio_read_32((0xf712c000 + 0x048)); + data &= ~0xf; + mmio_write_32((0xf712c000 + 0x048), data); + INFO("succeed to set ddrc 400mhz\n"); +} + +void set_ddrc_533mhz(void) { unsigned int data; @@ -503,6 +851,7 @@ static void set_ddrc_533mhz(void) mmio_write_32((0xf7030000 + 0x240), 0x5ffff); mmio_write_32((0xf7030000 + 0x344), 0xf5ff); mmio_write_32((0xf712c000 + 0x00c), 0x400); + mmio_write_32((0xf712c000 + 0x00c), 0x400); mmio_write_32((0xf712c000 + 0x018), 0x7); mmio_write_32((0xf712c000 + 0x090), 0x6400000); mmio_write_32((0xf712c000 + 0x258), 0x640); @@ -564,10 +913,53 @@ static void set_ddrc_533mhz(void) NOTICE("failed to init lpddr3 rank0 dram phy\n"); return; } - NOTICE("succeed to init lpddr3 rank0 dram phy\n"); + cat_533mhz_800mhz(); + + mmio_write_32((0xf712c000 + 0x004), 0xf1); + mmio_write_32((0xf7128000 + 0x050), 0x100123); + mmio_write_32((0xf7128000 + 0x060), 0x133); + mmio_write_32((0xf7128000 + 0x064), 0x133); + mmio_write_32((0xf7128000 + 0x200), 0xa1000); + + mmio_write_32((0xf7128000 + 0x100), 0xb77b6718); + mmio_write_32((0xf7128000 + 0x104), 0x1e82a071); + mmio_write_32((0xf7128000 + 0x108), 0x9501c07e); + mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255); + mmio_write_32((0xf7128000 + 0x110), 0x10b00000); + mmio_write_32((0xf7128000 + 0x114), 0x13181908); + mmio_write_32((0xf7128000 + 0x118), 0x44); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 0x7fe) { + NOTICE("fail to init ddr3 rank0\n"); + return; + } + ddrx_rdet(); + ddrx_wdet(); + + data = mmio_read_32((0xf712c000 + 0x048)); + data |= 1; + mmio_write_32((0xf712c000 + 0x048), data); + mmio_write_32((0xf712c000 + 0x004), 0x21); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 0x7fe) + NOTICE("ddr3 rank1 init failure\n"); + else + INFO("ddr3 rank1 init pass\n"); + + data = mmio_read_32((0xf712c000 + 0x048)); + data &= ~0xf; + mmio_write_32((0xf712c000 + 0x048), data); + INFO("succeed to set ddrc 533mhz\n"); } -static void set_ddrc_800mhz(void) +void set_ddrc_800mhz(void) { unsigned int data; @@ -581,6 +973,7 @@ static void set_ddrc_800mhz(void) mmio_write_32((0xf7030000 + 0x240), 0x5ffff); mmio_write_32((0xf7030000 + 0x344), 0xf5ff); mmio_write_32((0xf712c000 + 0x00c), 0x400); + mmio_write_32((0xf712c000 + 0x00c), 0x400); mmio_write_32((0xf712c000 + 0x018), 0x7); mmio_write_32((0xf712c000 + 0x090), 0x5400000); mmio_write_32((0xf712c000 + 0x258), 0x540); @@ -642,9 +1035,53 @@ static void set_ddrc_800mhz(void) WARN("failed to init lpddr3 rank0 dram phy\n"); return; } + cat_533mhz_800mhz(); + + mmio_write_32((0xf712c000 + 0x004), 0xf1); + mmio_write_32((0xf7128000 + 0x050), 0x100023); + mmio_write_32((0xf7128000 + 0x060), 0x133); + mmio_write_32((0xf7128000 + 0x064), 0x133); + mmio_write_32((0xf7128000 + 0x200), 0xa1000); + + mmio_write_32((0xf7128000 + 0x100), 0x755a9d12); + mmio_write_32((0xf7128000 + 0x104), 0x1753b055); + mmio_write_32((0xf7128000 + 0x108), 0x7401505f); + mmio_write_32((0xf7128000 + 0x10c), 0x578ca244); + mmio_write_32((0xf7128000 + 0x110), 0x10700000); + mmio_write_32((0xf7128000 + 0x114), 0x13141306); + mmio_write_32((0xf7128000 + 0x118), 0x44); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 0x7fe) { + NOTICE("fail to init ddr3 rank0\n"); + return; + } + ddrx_rdet(); + ddrx_wdet(); + + data = mmio_read_32((0xf712c000 + 0x048)); + data |= 1; + mmio_write_32((0xf712c000 + 0x048), data); + mmio_write_32((0xf712c000 + 0x004), 0x21); + do { + data = mmio_read_32((0xf712c000 + 0x004)); + } while (data & 1); + + data = mmio_read_32((0xf712c000 + 0x008)); + if (data & 0x7fe) + NOTICE("ddr3 rank1 init failure\n"); + else + INFO("ddr3 rank1 init pass\n"); + + data = mmio_read_32((0xf712c000 + 0x048)); + data &= ~0xf; + mmio_write_32((0xf712c000 + 0x048), data); + INFO("succeed to set ddrc 800mhz\n"); } -static void ddrc_common_init(int ddr800) +static void ddrc_common_init(int freq) { unsigned int data; @@ -653,11 +1090,10 @@ static void ddrc_common_init(int ddr800) mmio_write_32((0xf7120000 + 0x104), 0x71040004); mmio_write_32((0xf7121400 + 0x104), 0xf); mmio_write_32((0xf7121800 + 0x104), 0xf); - mmio_write_32((0xf7121800 + 0x104), 0xf); mmio_write_32((0xf7121c00 + 0x104), 0xf); mmio_write_32((0xf7122000 + 0x104), 0xf); mmio_write_32((0xf7128000 + 0x02c), 0x6); - mmio_write_32((0xf7128000 + 0x020), 0x1); + mmio_write_32((0xf7128000 + 0x020), 0x30003); mmio_write_32((0xf7128000 + 0x028), 0x310201); mmio_write_32((0xf712c000 + 0x1e4), 0xfe007600); mmio_write_32((0xf7128000 + 0x01c), 0xaf001); @@ -668,10 +1104,10 @@ static void ddrc_common_init(int ddr800) mmio_write_32((0xf7128000 + 0x280), data); mmio_write_32((0xf7128000 + 0x244), 0x3); - if (ddr800) - mmio_write_32((0xf7128000 + 0x240), 167 * 400000 / 1024); + if (freq == DDR_FREQ_800M) + mmio_write_32((0xf7128000 + 0x240), 167 * (freq / 2) / 1024); else - mmio_write_32((0xf7128000 + 0x240), 167 * 533000 / 1024); + mmio_write_32((0xf7128000 + 0x240), 167 * freq / 1024); data = mmio_read_32((0xf712c000 + 0x080)); data &= 0xffff; @@ -702,20 +1138,24 @@ static int dienum_det_and_rowcol_cfg(void) mmio_write_32((0xf7128000 + 0x064), 0x132); mmio_write_32((0xf7120000 + 0x100), 0x1600); mmio_write_32((0xf7120000 + 0x104), 0x71040004); + mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x40000000); break; case 0x1c: mmio_write_32((0xf7128000 + 0x060), 0x142); mmio_write_32((0xf7128000 + 0x064), 0x142); mmio_write_32((0xf7120000 + 0x100), 0x1700); mmio_write_32((0xf7120000 + 0x104), 0x71040004); + mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000); break; case 0x58: mmio_write_32((0xf7128000 + 0x060), 0x133); mmio_write_32((0xf7128000 + 0x064), 0x133); mmio_write_32((0xf7120000 + 0x100), 0x1700); mmio_write_32((0xf7120000 + 0x104), 0x71040004); + mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000); break; default: + mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000); break; } if (!data) @@ -772,73 +1212,114 @@ static int detect_ddr_chip_info(void) return data; } -int lpddr3_freq_init(int freq) +void ddr_phy_reset(void) { - unsigned int data; + mmio_write_32(0xf7030340, 0xa000); + mmio_write_32(0xf7030344, 0xa000); +} - if (freq == DDR_FREQ_800M) { - set_ddrc_800mhz(); - INFO("%s, set ddrc 800mhz\n", __func__); - } else { - set_ddrc_533mhz(); - INFO("%s, set ddrc 533mhz\n", __func__); +void lpddrx_save_ddl_para_bypass(uint32_t *ddr_ddl_para, unsigned int index) +{ + uint32_t value; + uint32_t cnt = index; + uint32_t i; + + for (i = 0; i < 4; i++) { + value = mmio_read_32(0xf712c000 + 0x22c + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x23c + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x240 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x640 + i * 0x80); + ddr_ddl_para[cnt++] = value; } +} - mmio_write_32((0xf712c000 + 0x004), 0xf1); - if (freq == DDR_FREQ_800M) - mmio_write_32((0xf7128000 + 0x050), 0x100023); - else - mmio_write_32((0xf7128000 + 0x050), 0x100123); - mmio_write_32((0xf7128000 + 0x060), 0x133); - mmio_write_32((0xf7128000 + 0x064), 0x133); - mmio_write_32((0xf7128000 + 0x200), 0xa1000); - - if (freq == DDR_FREQ_800M) { - mmio_write_32((0xf7128000 + 0x100), 0x755a9d12); - mmio_write_32((0xf7128000 + 0x104), 0x1753b055); - mmio_write_32((0xf7128000 + 0x108), 0x7401505f); - mmio_write_32((0xf7128000 + 0x10c), 0x578ca244); - mmio_write_32((0xf7128000 + 0x110), 0x10700000); - mmio_write_32((0xf7128000 + 0x114), 0x13141306); - } else { - mmio_write_32((0xf7128000 + 0x100), 0xb77b6718); - mmio_write_32((0xf7128000 + 0x104), 0x1e82a071); - mmio_write_32((0xf7128000 + 0x108), 0x9501c07e); - mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255); - mmio_write_32((0xf7128000 + 0x110), 0x10b00000); - mmio_write_32((0xf7128000 + 0x114), 0x13181908); +void lpddrx_save_ddl_para_mission(uint32_t *ddr_ddl_para, unsigned int index) +{ + uint32_t value; + uint32_t cnt = index; + uint32_t i; + + value = mmio_read_32(0xf712c000 + 0x140); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x144); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x148); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x14c); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x150); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x1d4); + ddr_ddl_para[cnt++] = value; + for (i = 0; i < 4; i++) { + value = mmio_read_32(0xf712c000 + 0x210 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x214 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x218 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x21c + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x220 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x224 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x228 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x22c + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x230 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x234 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x238 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x23c + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x240 + i * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x640 + i * 0x80); + ddr_ddl_para[cnt++] = value; } - mmio_write_32((0xf7128000 + 0x118), 0x44); - do { - data = mmio_read_32((0xf712c000 + 0x004)); - } while (data & 1); + value = mmio_read_32(0xf712c000 + 0x168); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x24c + 0 * 0x80); + ddr_ddl_para[cnt++] = value; + value = mmio_read_32(0xf712c000 + 0x24c + 2 * 0x80); + ddr_ddl_para[cnt++] = value; +} - data = mmio_read_32((0xf712c000 + 0x008)); - if (data & 0x7fe) { - NOTICE("fail to init ddr3 rank0\n"); - return -EFAULT; +int lpddr3_freq_init(int freq) +{ + set_ddrc_150mhz(); + lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR, 0); + if (freq > DDR_FREQ_150M) { + ddr_phy_reset(); + set_ddrc_266mhz(); + lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR, + 16); + } + if (freq > DDR_FREQ_266M) { + ddr_phy_reset(); + set_ddrc_400mhz(); + lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR, + 16 * 2); + } + if (freq > DDR_FREQ_400M) { + ddr_phy_reset(); + set_ddrc_533mhz(); + lpddrx_save_ddl_para_mission((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR, + 16 * 3); + } + if (freq > DDR_FREQ_533M) { + ddr_phy_reset(); + set_ddrc_800mhz(); + lpddrx_save_ddl_para_mission((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR, + 16 * 3 + 61); } - INFO("init ddr3 rank0\n"); - ddrx_rdet(); - ddrx_wdet(); - - data = mmio_read_32((0xf712c000 + 0x048)); - data |= 1; - mmio_write_32((0xf712c000 + 0x048), data); - mmio_write_32((0xf712c000 + 0x004), 0x21); - do { - data = mmio_read_32((0xf712c000 + 0x004)); - } while (data & 1); - - data = mmio_read_32((0xf712c000 + 0x008)); - if (data & 0x7fe) - NOTICE("ddr3 rank1 init failure\n"); - else - INFO("ddr3 rank1 init pass\n"); - - data = mmio_read_32((0xf712c000 + 0x048)); - data &= ~0xf; - mmio_write_32((0xf712c000 + 0x048), data); return 0; } @@ -855,7 +1336,7 @@ static void init_ddr(int freq) data |= 1; mmio_write_32((0xf7032000 + 0x010), data); - udelay(100); + udelay(300); do { data = mmio_read_32((0xf7032000 + 0x030)); data &= 3 << 28; @@ -923,38 +1404,40 @@ static void init_ddrc_qos(void) mmio_write_32((0xf7124000 + 0x0d0), 0x3020100); } -static void ddr_phy_reset(void) -{ - mmio_write_32(0xf7030340, 0xa000); - mmio_write_32(0xf7030344, 0xa000); -} - -void hikey_ddr_init(void) +void hikey_ddr_init(unsigned int ddr_freq) { uint32_t data; + assert((ddr_freq == DDR_FREQ_150M) || (ddr_freq == DDR_FREQ_266M) || + (ddr_freq == DDR_FREQ_400M) || (ddr_freq == DDR_FREQ_533M) || + (ddr_freq == DDR_FREQ_800M)); init_pll(); init_freq(); - /* - * Init DDR with 533MHz. Otherwise, DDR initialization - * may fail on 800MHz on some boards. - */ - ddr_phy_reset(); - init_ddr(DDR_FREQ_533M); - /* Init DDR with 800MHz. */ - ddr_phy_reset(); - init_ddr(DDR_FREQ_800M); - + init_ddr(ddr_freq); - ddrc_common_init(1); + ddrc_common_init(ddr_freq); dienum_det_and_rowcol_cfg(); detect_ddr_chip_info(); - data = mmio_read_32(0xf7032000 + 0x010); - data &= ~0x1; - mmio_write_32(0xf7032000 + 0x010, data); - data = mmio_read_32(0xf7032000 + 0x010); + if ((ddr_freq == DDR_FREQ_400M) || (ddr_freq == DDR_FREQ_800M)) { + data = mmio_read_32(0xf7032000 + 0x010); + data &= ~0x1; + mmio_write_32(0xf7032000 + 0x010, data); + } else if ((ddr_freq == DDR_FREQ_266M) || (ddr_freq == DDR_FREQ_533M)) { + data = mmio_read_32(0xf7032000 + 0x030); + data &= ~0x1; + mmio_write_32(0xf7032000 + 0x030, data); + } else { + data = mmio_read_32(0xf7032000 + 0x010); + data &= ~0x1; + mmio_write_32(0xf7032000 + 0x010, data); + data = mmio_read_32(0xf7032000 + 0x030); + data &= ~0x1; + mmio_write_32(0xf7032000 + 0x030, data); + } + dsb(); + isb(); /* * Test memory access. Do not use address 0x0 because the compiler diff --git a/plat/hisilicon/hikey/hikey_private.h b/plat/hisilicon/hikey/hikey_private.h index 7654921d..e6d109a6 100644 --- a/plat/hisilicon/hikey/hikey_private.h +++ b/plat/hisilicon/hikey/hikey_private.h @@ -12,6 +12,14 @@ #define RANDOM_MAX 0x7fffffffffffffff #define RANDOM_MAGIC 0x9a4dbeaf +enum { + DDR_FREQ_150M = 150 * 1000, + DDR_FREQ_266M = 266 * 1000, + DDR_FREQ_400M = 400 * 1000, + DDR_FREQ_533M = 533 * 1000, + DDR_FREQ_800M = 800 * 1000 +}; + struct random_serial_num { uint64_t magic; uint64_t data; @@ -34,7 +42,7 @@ void hikey_init_mmu_el3(unsigned long total_base, unsigned long coh_start, unsigned long coh_limit); -void hikey_ddr_init(void); +void hikey_ddr_init(unsigned int ddr_freq); void hikey_io_setup(void); void hikey_sp804_init(void); 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 00000000..80524fc2 --- /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 <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 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 00000000..10151294 --- /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 <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__ */ 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 00000000..6ed7bc00 --- /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 00000000..8163dc16 --- /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 00000000..0e1cae60 --- /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 <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__ */ 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 00000000..0039f2d3 --- /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 00000000..e82a1fb8 --- /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 <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; +} 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 00000000..b529aa50 --- /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 <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); +} 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 00000000..3473d988 --- /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 <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(); +} diff --git a/plat/layerscape/board/ls1043/ls1043_err.c b/plat/layerscape/board/ls1043/ls1043_err.c new file mode 100644 index 00000000..e4a2cae4 --- /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 <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(); +} diff --git a/plat/layerscape/board/ls1043/ls1043_psci.c b/plat/layerscape/board/ls1043/ls1043_psci.c new file mode 100644 index 00000000..1c83df43 --- /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 <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, brr; + + assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT); + core_mask = 1 << core_pos; + + /* 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 00000000..18ae56e5 --- /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 00000000..50f463b9 --- /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 <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(); +} diff --git a/plat/layerscape/board/ls1043/ls1043_topology.c b/plat/layerscape/board/ls1043/ls1043_topology.c new file mode 100644 index 00000000..12d2830f --- /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 <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); +} diff --git a/plat/layerscape/board/ls1043/ls_gic.c b/plat/layerscape/board/ls1043/ls_gic.c new file mode 100644 index 00000000..3986153a --- /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 <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; + } +} diff --git a/plat/layerscape/board/ls1043/platform.mk b/plat/layerscape/board/ls1043/platform.mk new file mode 100644 index 00000000..163d25e8 --- /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 00000000..4fc019c8 --- /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 00000000..39414271 --- /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 00000000..a96e3901 --- /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 <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) diff --git a/plat/layerscape/common/aarch64/ls_console.S b/plat/layerscape/common/aarch64/ls_console.S new file mode 100644 index 00000000..5c87465e --- /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 <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 diff --git a/plat/layerscape/common/aarch64/ls_helpers.S b/plat/layerscape/common/aarch64/ls_helpers.S new file mode 100644 index 00000000..7d71f482 --- /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 <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 diff --git a/plat/layerscape/common/include/fsl_csu.h b/plat/layerscape/common/include/fsl_csu.h new file mode 100644 index 00000000..680911ef --- /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 00000000..503a01df --- /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 <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__ */ diff --git a/plat/layerscape/common/include/plat_ls.h b/plat/layerscape/common/include/plat_ls.h new file mode 100644 index 00000000..9d5ec145 --- /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 <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__ */ diff --git a/plat/layerscape/common/include/soc.h b/plat/layerscape/common/include/soc.h new file mode 100644 index 00000000..72c10cf9 --- /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 <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__ */ diff --git a/plat/layerscape/common/include/tzc380.h b/plat/layerscape/common/include/tzc380.h new file mode 100644 index 00000000..788c0ed1 --- /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 00000000..43f74507 --- /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 <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 +} diff --git a/plat/layerscape/common/ls_bl2_setup.c b/plat/layerscape/common/ls_bl2_setup.c new file mode 100644 index 00000000..6e6ad6eb --- /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 <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); +} diff --git a/plat/layerscape/common/ls_bl31_setup.c b/plat/layerscape/common/ls_bl31_setup.c new file mode 100644 index 00000000..3016f58e --- /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 <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(); +} diff --git a/plat/layerscape/common/ls_common.c b/plat/layerscape/common/ls_common.c new file mode 100644 index 00000000..abf6525b --- /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 <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; +} diff --git a/plat/layerscape/common/ls_common.mk b/plat/layerscape/common/ls_common.mk new file mode 100644 index 00000000..1a80e9f2 --- /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 00000000..909bec2f --- /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 <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(); +} diff --git a/plat/layerscape/common/ls_io_storage.c b/plat/layerscape/common/ls_io_storage.c new file mode 100644 index 00000000..74023663 --- /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 <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; +} diff --git a/plat/layerscape/common/ls_timer.c b/plat/layerscape/common/ls_timer.c new file mode 100644 index 00000000..25b5e630 --- /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 <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); +} diff --git a/plat/layerscape/common/ls_topology.c b/plat/layerscape/common/ls_topology.c new file mode 100644 index 00000000..5b76087d --- /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 00000000..b9f32ac3 --- /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 <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; +} diff --git a/plat/layerscape/common/ns_access.c b/plat/layerscape/common/ns_access.c new file mode 100644 index 00000000..e1daaed9 --- /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 <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)); +} diff --git a/plat/layerscape/common/tsp/ls_tsp.mk b/plat/layerscape/common/tsp/ls_tsp.mk new file mode 100644 index 00000000..7cb97819 --- /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 00000000..82ac965c --- /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 <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); +} diff --git a/plat/layerscape/common/tsp/platform_tsp.h b/plat/layerscape/common/tsp/platform_tsp.h new file mode 100644 index 00000000..b1c96cbb --- /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__ */ diff --git a/services/spd/tspd/tspd_private.h b/services/spd/tspd/tspd_private.h index 8fadb7a5..a63daff1 100644 --- a/services/spd/tspd/tspd_private.h +++ b/services/spd/tspd/tspd_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -206,7 +206,7 @@ extern const spd_pm_ops_t tspd_pm; /******************************************************************************* * Forward declarations ******************************************************************************/ -struct tsp_vectors; +typedef struct tsp_vectors tsp_vectors_t; /******************************************************************************* * Function & Data prototypes @@ -215,14 +215,26 @@ uint64_t tspd_enter_sp(uint64_t *c_rt_ctx); void __dead2 tspd_exit_sp(uint64_t c_rt_ctx, uint64_t ret); uint64_t tspd_synchronous_sp_entry(tsp_context_t *tsp_ctx); void __dead2 tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret); -void tspd_init_tsp_ep_state(struct entry_point_info *tsp_ep, +void tspd_init_tsp_ep_state(struct entry_point_info *tsp_entry_point, uint32_t rw, uint64_t pc, tsp_context_t *tsp_ctx); int tspd_abort_preempted_smc(tsp_context_t *tsp_ctx); +uint64_t tspd_smc_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags); + +int32_t tspd_setup(void); +uint64_t tspd_handle_sp_preemption(void *handle); + extern tsp_context_t tspd_sp_context[TSPD_CORE_COUNT]; -extern struct tsp_vectors *tsp_vectors; +extern tsp_vectors_t *tsp_vectors; #endif /*__ASSEMBLY__*/ #endif /* __TSPD_PRIVATE_H__ */ |