diff --git a/docs/plat/ti-k3.rst b/docs/plat/ti-k3.rst new file mode 100644 index 000000000..6515c644d --- /dev/null +++ b/docs/plat/ti-k3.rst @@ -0,0 +1,55 @@ +Trusted Firmware-A for Texas Instruments K3 SoCs +================================================ + +Trusted Firmware-A (TF-A) implements the EL3 firmware layer for Texas Instruments K3 SoCs. + +Boot Flow +--------- + +R5(U-Boot) --> TF-A BL31 --> BL32(OP-TEE) --> TF-A BL31 --> BL33(U-Boot) --> Linux + \ + Optional direct to Linux boot + \ + --> BL33(Linux) + +Texas Instruments K3 SoCs contain an R5 processor used as the boot master, it +loads the needed images for A53 startup, because of this we do not need BL1 or +BL2 TF-A stages. + +Build Instructions +------------------ + +https://github.com/ARM-software/arm-trusted-firmware.git + +TF-A: + +.. code:: shell + + make CROSS_COMPILE=aarch64-linux-gnu- PLAT=k3 SPD=opteed all + +OP-TEE: + +.. code:: shell + + make ARCH=arm CROSS_COMPILE64=aarch64-linux-gnu- PLATFORM=k3 CFG_ARM64_core=y all + +R5 U-Boot: + +.. code:: shell + + make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- am65x_evm_r5_defconfig + make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- SYSFW= + +A53 U-Boot: + +.. code:: shell + + make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- am65x_evm_a53_defconfig + make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF= TEE= + +Deploy Images +------------- + +.. code:: shell + + cp tiboot3.bin tispl.bin u-boot.img /sdcard/boot/ diff --git a/maintainers.rst b/maintainers.rst index 81c30c073..96ff0e06d 100644 --- a/maintainers.rst +++ b/maintainers.rst @@ -132,6 +132,16 @@ Files: - plat/rockchip/\* +Texas Instruments platform sub-maintainer +----------------------------------------- + +Andrew F. Davis (afd@ti.com, `glneo`_) + +Files: + +- docs/plat/ti-k3.rst +- plat/ti/\* + UniPhier platform sub-maintainer -------------------------------- @@ -167,6 +177,7 @@ Etienne Carriere (etienne.carriere@linaro.org, `etienne-lms`_) .. _masahir0y: https://github.com/masahir0y .. _mtk09422: https://github.com/mtk09422 .. _TonyXie06: https://github.com/TonyXie06 +.. _glneo: https://github.com/glneo .. _sivadur: https://github.com/sivadur .. _rockchip-linux: https://github.com/rockchip-linux .. _etienne-lms: https://github.com/etienne-lms diff --git a/plat/ti/k3/board/generic/board.mk b/plat/ti/k3/board/generic/board.mk new file mode 100644 index 000000000..a34221454 --- /dev/null +++ b/plat/ti/k3/board/generic/board.mk @@ -0,0 +1,17 @@ +# +# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BL32_BASE ?= 0x9e800000 +$(eval $(call add_define,BL32_BASE)) + +PRELOADED_BL33_BASE ?= 0x80080000 +$(eval $(call add_define,PRELOADED_BL33_BASE)) + +K3_HW_CONFIG_BASE ?= 0x82000000 +$(eval $(call add_define,K3_HW_CONFIG_BASE)) + +PLAT_INCLUDES += \ + -Iplat/ti/k3/board/generic/include \ diff --git a/plat/ti/k3/board/generic/include/board_def.h b/plat/ti/k3/board/generic/include/board_def.h new file mode 100644 index 000000000..4c59c758c --- /dev/null +++ b/plat/ti/k3/board/generic/include/board_def.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __BOARD_DEF_H__ +#define __BOARD_DEF_H__ + +/* The ports must be in order and contiguous */ +#define K3_CLUSTER0_CORE_COUNT 2 +#define K3_CLUSTER0_MSMC_PORT 0 + +#define K3_CLUSTER1_CORE_COUNT 2 +#define K3_CLUSTER1_MSMC_PORT 1 + +#define K3_CLUSTER2_CORE_COUNT 2 +#define K3_CLUSTER2_MSMC_PORT 2 + +#define K3_CLUSTER3_CORE_COUNT 2 +#define K3_CLUSTER3_MSMC_PORT 3 + +/* + * This RAM will be used for the bootloader including code, bss, and stacks. + * It may need to be increased if BL31 grows in size. + */ +#define SEC_SRAM_BASE 0x70000000 /* Base of MSMC SRAM */ +#define SEC_SRAM_SIZE 0x00020000 /* 128k */ + +#define PLAT_MAX_OFF_STATE 2 +#define PLAT_MAX_RET_STATE 1 + +#endif /* __BOARD_DEF_H__ */ diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c new file mode 100644 index 000000000..ca7d214a1 --- /dev/null +++ b/plat/ti/k3/common/k3_bl31_setup.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Table of regions to map using the MMU */ +const mmap_region_t plat_arm_mmap[] = { + MAP_REGION_FLAT(SHARED_RAM_BASE, SHARED_RAM_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(K3_GICD_BASE, K3_GICD_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(K3_GICR_BASE, K3_GICR_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + { /* sentinel */ } +}; + +/* + * Placeholder variables for maintaining information about the next image(s) + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/******************************************************************************* + * Gets SPSR for BL33 entry + ******************************************************************************/ +static uint32_t k3_get_spsr_for_bl33_entry(void) +{ + unsigned long el_status; + unsigned int mode; + uint32_t spsr; + + /* Figure out what mode we enter the non-secure world in */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + mode = (el_status) ? MODE_EL2 : MODE_EL1; + + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} + +/******************************************************************************* + * Perform any BL3-1 early platform setup, such as console init and deciding on + * memory layout. + ******************************************************************************/ +void bl31_early_platform_setup(bl31_params_t *from_bl2, + void *plat_params_from_bl2) +{ + /* There are no parameters from BL2 if BL31 is a reset vector */ + assert(from_bl2 == NULL); + assert(plat_params_from_bl2 == NULL); + + bl31_console_setup(); + +#ifdef BL32_BASE + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); +#endif + + /* Populate entry point information for BL33 */ + SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0); + bl33_image_ep_info.pc = PRELOADED_BL33_BASE; + bl33_image_ep_info.spsr = k3_get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +#ifdef K3_HW_CONFIG_BASE + /* + * According to the file ``Documentation/arm64/booting.txt`` of the + * Linux kernel tree, Linux expects the physical address of the device + * tree blob (DTB) in x0, while x1-x3 are reserved for future use and + * must be 0. + */ + bl33_image_ep_info.args.arg0 = (u_register_t)K3_HW_CONFIG_BASE; + bl33_image_ep_info.args.arg1 = 0U; + bl33_image_ep_info.args.arg2 = 0U; + bl33_image_ep_info.args.arg3 = 0U; +#endif +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + bl31_early_platform_setup((void *)arg0, (void *)arg1); +} + +void bl31_plat_arch_setup(void) +{ + arm_setup_page_tables(BL31_BASE, + BL31_END - BL31_BASE, + BL_CODE_BASE, + BL_CODE_END, + BL_RO_DATA_BASE, + BL_RO_DATA_END); + enable_mmu_el3(0); +} + +void bl31_platform_setup(void) +{ + k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE); + k3_gic_init(); +} + +void platform_mem_init(void) +{ + /* Do nothing for now... */ +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return SYS_COUNTER_FREQ_IN_TICKS; +} + +/* + * Empty function to prevent the console from being uninitialized after BL33 is + * started and allow us to see messages from BL31. + */ +void bl31_plat_runtime_setup(void) +{ +} + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image + * for the security state specified. BL3-3 corresponds to the non-secure + * image type while BL3-2 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; + /* + * None of the images on the ARM development platforms can have 0x0 + * as the entrypoint + */ + if (next_image_info->pc) + return next_image_info; + + NOTICE("Requested nonexistent image\n"); + return NULL; +} diff --git a/plat/ti/k3/common/k3_console.c b/plat/ti/k3/common/k3_console.c new file mode 100644 index 000000000..ff3ca61ce --- /dev/null +++ b/plat/ti/k3/common/k3_console.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +void bl31_console_setup(void) +{ + static console_16550_t console; + + /* Initialize the console to provide early debug support */ + console_16550_register(K3_USART_BASE_ADDRESS, K3_USART_CLK_SPEED, + K3_USART_BAUD, &console); +} diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c new file mode 100644 index 000000000..3253130f6 --- /dev/null +++ b/plat/ti/k3/common/k3_gicv3.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +/* The GICv3 driver only needs to be initialized in EL3 */ +uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static const interrupt_prop_t k3_interrupt_props[] = { + PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S), + PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0) +}; + +static unsigned int k3_mpidr_to_core_pos(unsigned long mpidr) +{ + return (unsigned int)plat_core_pos_by_mpidr(mpidr); +} + +gicv3_driver_data_t k3_gic_data = { + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .interrupt_props = k3_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(k3_interrupt_props), + .mpidr_to_core_pos = k3_mpidr_to_core_pos, +}; + +void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base) +{ + /* + * The GICv3 driver is initialized in EL3 and does not need + * to be initialized again in SEL1. This is because the S-EL1 + * can use GIC system registers to manage interrupts and does + * not need GIC interface base addresses to be configured. + */ + k3_gic_data.gicd_base = gicd_base; + k3_gic_data.gicr_base = gicr_base; + gicv3_driver_init(&k3_gic_data); +} + +void k3_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void k3_gic_cpuif_enable(void) +{ + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void k3_gic_cpuif_disable(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +void k3_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); +} diff --git a/plat/ti/k3/common/k3_helpers.S b/plat/ti/k3/common/k3_helpers.S new file mode 100644 index 000000000..c95e9c367 --- /dev/null +++ b/plat/ti/k3/common/k3_helpers.S @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#define K3_BOOT_REASON_COLD_RESET 0x1 + + /* ------------------------------------------------------------------ + * uintptr_t plat_get_my_entrypoint(void) + * ------------------------------------------------------------------ + * + * This function is called with the called with the MMU and caches + * disabled (SCTLR_EL3.M = 0 and SCTLR_EL3.C = 0). The function is + * responsible for distinguishing between a warm and cold reset for the + * current CPU using platform-specific means. If it's a warm reset, + * then it returns the warm reset entrypoint point provided to + * plat_setup_psci_ops() during BL31 initialization. If it's a cold + * reset then this function must return zero. + * + * This function does not follow the Procedure Call Standard used by + * the Application Binary Interface for the ARM 64-bit architecture. + * The caller should not assume that callee saved registers are + * preserved across a call to this function. + */ + .globl plat_get_my_entrypoint +func plat_get_my_entrypoint + ldr x0, k3_boot_reason_data_store + cmp x0, #K3_BOOT_REASON_COLD_RESET + + /* We ONLY support cold boot at this point */ + bne plat_unsupported_boot + mov x0, #0 + ret + + /* + * We self manage our boot reason. + * At load time, we have just a default reason - which is cold reset + */ +k3_boot_reason_data_store: + .word K3_BOOT_REASON_COLD_RESET + +plat_unsupported_boot: + b plat_unsupported_boot + +endfunc plat_get_my_entrypoint + + /* ------------------------------------------------------------------ + * unsigned int plat_my_core_pos(void) + * ------------------------------------------------------------------ + * + * This function returns the index of the calling CPU which is used as a + * CPU-specific linear index into blocks of memory (for example while + * allocating per-CPU stacks). This function will be invoked very early + * in the initialization sequence which mandates that this function + * should be implemented in assembly and should not rely on the + * avalability of a C runtime environment. This function can clobber x0 + * - x8 and must preserve x9 - x29. + * + * This function plays a crucial role in the power domain topology + * framework in PSCI and details of this can be found in Power Domain + * Topology Design. + */ + .globl plat_my_core_pos +func plat_my_core_pos + mrs x0, MPIDR_EL1 + + and x1, x0, #MPIDR_CLUSTER_MASK + lsr x1, x1, #MPIDR_AFF1_SHIFT + and x0, x0, #MPIDR_CPU_MASK + +#if K3_CLUSTER1_MSMC_PORT != UNUSED + cmp x1, #K3_CLUSTER0_MSMC_PORT + b.eq out + add x0, x0, #K3_CLUSTER0_CORE_COUNT +#if K3_CLUSTER2_MSMC_PORT != UNUSED + cmp x1, #K3_CLUSTER1_MSMC_PORT + b.eq out + add x0, x0, #K3_CLUSTER1_CORE_COUNT +#if K3_CLUSTER3_MSMC_PORT != UNUSED + cmp x1, #K3_CLUSTER2_MSMC_PORT + b.eq out + add x0, x0, #K3_CLUSTER2_CORE_COUNT +#endif /* K3_CLUSTER3_MSMC_PORT != UNUSED */ +#endif /* K3_CLUSTER2_MSMC_PORT != UNUSED */ +#endif /* K3_CLUSTER1_MSMC_PORT != UNUSED */ + +out: + ret +endfunc plat_my_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 + * --------------------------------------------- + */ +func plat_crash_console_init + mov_imm x0, CRASH_CONSOLE_BASE + mov_imm x1, CRASH_CONSOLE_CLK + mov_imm x2, CRASH_CONSOLE_BAUD_RATE + mov w3, #0x0 + b console_core_init + +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(void) + * 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, CRASH_CONSOLE_BASE + b console_core_putc +endfunc plat_crash_console_putc diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c new file mode 100644 index 000000000..91602c8c1 --- /dev/null +++ b/plat/ti/k3/common/k3_psci.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#define STUB() ERROR("stub %s called\n", __func__) + +uintptr_t k3_sec_entrypoint; + +static void k3_cpu_standby(plat_local_state_t cpu_state) +{ + /* + * Enter standby state + * dsb is good practice before using wfi to enter low power states + */ + dsb(); + wfi(); +} + +static int k3_pwr_domain_on(u_register_t mpidr) +{ + sev(); + + /* TODO: Indicate to System firmware about powering up */ + + return PSCI_E_SUCCESS; +} + +void k3_pwr_domain_off(const psci_power_state_t *target_state) +{ + /* Prevent interrupts from spuriously waking up this cpu */ + k3_gic_cpuif_disable(); + + /* TODO: Indicate to System firmware about powering down */ +} + +void k3_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* TODO: Indicate to System firmware about completion */ + + k3_gic_pcpu_init(); + k3_gic_cpuif_enable(); +} + +static void __dead2 k3_system_reset(void) +{ + /* TODO: Indicate to System firmware about system reset */ + STUB(); + + while (true) + wfi(); +} + +static int k3_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + /* TODO: perform the proper validation */ + + return PSCI_E_SUCCESS; +} + +static int k3_validate_ns_entrypoint(uintptr_t entrypoint) +{ + /* TODO: perform the proper validation */ + + return PSCI_E_SUCCESS; +} + +static const plat_psci_ops_t k3_plat_psci_ops = { + .cpu_standby = k3_cpu_standby, + .pwr_domain_on = k3_pwr_domain_on, + .pwr_domain_off = k3_pwr_domain_off, + .pwr_domain_on_finish = k3_pwr_domain_on_finish, + .system_reset = k3_system_reset, + .validate_power_state = k3_validate_power_state, + .validate_ns_entrypoint = k3_validate_ns_entrypoint +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + k3_sec_entrypoint = sec_entrypoint; + + *psci_ops = &k3_plat_psci_ops; + + return 0; +} diff --git a/plat/ti/k3/common/k3_topology.c b/plat/ti/k3/common/k3_topology.c new file mode 100644 index 000000000..a77c8f34c --- /dev/null +++ b/plat/ti/k3/common/k3_topology.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/* The power domain tree descriptor */ +static unsigned char power_domain_tree_desc[] = { + PLATFORM_CLUSTER_COUNT, + K3_CLUSTER0_CORE_COUNT, +#if K3_CLUSTER1_MSMC_PORT != UNUSED + K3_CLUSTER1_CORE_COUNT, +#endif /* K3_CLUSTER1_MSMC_PORT != UNUSED */ +#if K3_CLUSTER2_MSMC_PORT != UNUSED + K3_CLUSTER2_CORE_COUNT, +#endif /* K3_CLUSTER2_MSMC_PORT != UNUSED */ +#if K3_CLUSTER3_MSMC_PORT != UNUSED + K3_CLUSTER3_CORE_COUNT, +#endif /* K3_CLUSTER3_MSMC_PORT != UNUSED */ +}; + +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return power_domain_tree_desc; +} + +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int cpu_id; + + mpidr &= MPIDR_AFFINITY_MASK; + + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) + return -1; + + cpu_id = MPIDR_AFFLVL0_VAL(mpidr); + + switch (MPIDR_AFFLVL1_VAL(mpidr)) { + case K3_CLUSTER0_MSMC_PORT: + if (cpu_id < K3_CLUSTER0_CORE_COUNT) + return cpu_id; + return -1; +#if K3_CLUSTER1_MSMC_PORT != UNUSED + case K3_CLUSTER1_MSMC_PORT: + if (cpu_id < K3_CLUSTER1_CORE_COUNT) + return K3_CLUSTER0_CORE_COUNT + cpu_id; + return -1; +#endif /* K3_CLUSTER1_MSMC_PORT != UNUSED */ +#if K3_CLUSTER2_MSMC_PORT != UNUSED + case K3_CLUSTER2_MSMC_PORT: + if (cpu_id < K3_CLUSTER2_CORE_COUNT) + return K3_CLUSTER0_CORE_COUNT + + K3_CLUSTER1_CORE_COUNT + cpu_id; + return -1; +#endif /* K3_CLUSTER2_MSMC_PORT != UNUSED */ +#if K3_CLUSTER3_MSMC_PORT != UNUSED + case K3_CLUSTER3_MSMC_PORT: + if (cpu_id < K3_CLUSTER3_CORE_COUNT) + return K3_CLUSTER0_CORE_COUNT + + K3_CLUSTER1_CORE_COUNT + + K3_CLUSTER2_CORE_COUNT + cpu_id; + return -1; +#endif /* K3_CLUSTER3_MSMC_PORT != UNUSED */ + default: + return -1; + } +} diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk new file mode 100644 index 000000000..bf2a73fbb --- /dev/null +++ b/plat/ti/k3/common/plat_common.mk @@ -0,0 +1,67 @@ +# +# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# We don't use BL1 or BL2, so BL31 is the first image to execute +RESET_TO_BL31 := 1 +# Only one core starts up at first +COLD_BOOT_SINGLE_CPU := 1 +# We can choose where a core starts executing +PROGRAMMABLE_RESET_ADDRESS:= 1 + +# System coherency is managed in hardware +HW_ASSISTED_COHERENCY := 1 +USE_COHERENT_MEM := 0 + +ERROR_DEPRECATED := 1 +ENABLE_PLAT_COMPAT := 0 + +# A53 erratum for SoC. (enable them all) +ERRATA_A53_826319 := 1 +ERRATA_A53_835769 := 1 +ERRATA_A53_836870 := 1 +ERRATA_A53_843419 := 1 +ERRATA_A53_855873 := 1 + +MULTI_CONSOLE_API := 1 +TI_16550_MDR_QUIRK := 1 +$(eval $(call add_define,TI_16550_MDR_QUIRK)) + +# Libraries +include lib/xlat_tables_v2/xlat_tables.mk + +PLAT_INCLUDES += \ + -I${PLAT_PATH}/include \ + -Iinclude/plat/arm/common/ \ + -Iinclude/plat/arm/common/aarch64/ \ + +K3_CONSOLE_SOURCES += \ + drivers/console/aarch64/console.S \ + drivers/ti/uart/aarch64/16550_console.S \ + ${PLAT_PATH}/common/k3_console.c \ + +K3_GIC_SOURCES += \ + drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/v3/gicv3_helpers.c \ + plat/common/plat_gicv3.c \ + ${PLAT_PATH}/common/k3_gicv3.c \ + +K3_PSCI_SOURCES += \ + plat/common/plat_psci_common.c \ + ${PLAT_PATH}/common/k3_psci.c \ + +PLAT_BL_COMMON_SOURCES += \ + plat/arm/common/arm_common.c \ + lib/cpus/aarch64/cortex_a53.S \ + ${XLAT_TABLES_LIB_SRCS} \ + ${K3_CONSOLE_SOURCES} \ + +BL31_SOURCES += \ + ${PLAT_PATH}/common/k3_bl31_setup.c \ + ${PLAT_PATH}/common/k3_helpers.S \ + ${PLAT_PATH}/common/k3_topology.c \ + ${K3_GIC_SOURCES} \ + ${K3_PSCI_SOURCES} \ diff --git a/plat/ti/k3/include/k3_console.h b/plat/ti/k3/include/k3_console.h new file mode 100644 index 000000000..5b01a31f2 --- /dev/null +++ b/plat/ti/k3/include/k3_console.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __K3_CONSOLE_H__ +#define __K3_CONSOLE_H__ + +void bl31_console_setup(void); + +#endif /* __K3_CONSOLE_H__ */ diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h new file mode 100644 index 000000000..bbf5bf9fe --- /dev/null +++ b/plat/ti/k3/include/k3_gicv3.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __K3_GICV3_H__ +#define __K3_GICV3_H__ + +void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base); +void k3_gic_init(void); +void k3_gic_cpuif_enable(void); +void k3_gic_cpuif_disable(void); +void k3_gic_pcpu_init(void); + +#endif /* __K3_GICV3_H__ */ diff --git a/plat/ti/k3/include/plat_macros.S b/plat/ti/k3/include/plat_macros.S new file mode 100644 index 000000000..96d1cd20d --- /dev/null +++ b/plat/ti/k3/include/plat_macros.S @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2017-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 platform registers + * whenever an unhandled exception is taken in + * BL31. + * --------------------------------------------- + */ + .macro plat_crash_print_regs + /* STUB */ + .endm + +#endif /* __PLAT_MACROS_S__ */ diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h new file mode 100644 index 000000000..8856af2ca --- /dev/null +++ b/plat/ti/k3/include/platform_def.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLATFORM_DEF_H__ +#define __PLATFORM_DEF_H__ + +#include +#include +#include + +/******************************************************************************* + * Generic platform constants + ******************************************************************************/ + +/* Size of cacheable stack */ +#if IMAGE_BL31 +#define PLATFORM_STACK_SIZE 0x800 +#else +#define PLATFORM_STACK_SIZE 0x1000 +#endif + +#define PLATFORM_SYSTEM_COUNT 1 +#define PLATFORM_CORE_COUNT (K3_CLUSTER0_CORE_COUNT + \ + K3_CLUSTER1_CORE_COUNT + \ + K3_CLUSTER2_CORE_COUNT + \ + K3_CLUSTER3_CORE_COUNT) + +#define PLATFORM_CLUSTER_COUNT ((K3_CLUSTER0_MSMC_PORT != UNUSED) + \ + (K3_CLUSTER1_MSMC_PORT != UNUSED) + \ + (K3_CLUSTER2_MSMC_PORT != UNUSED) + \ + (K3_CLUSTER3_MSMC_PORT != UNUSED)) + +#define UNUSED -1 + +#if !defined(K3_CLUSTER1_CORE_COUNT) || !defined(K3_CLUSTER1_MSMC_PORT) +#define K3_CLUSTER1_CORE_COUNT 0 +#define K3_CLUSTER1_MSMC_PORT UNUSED +#endif + +#if !defined(K3_CLUSTER2_CORE_COUNT) || !defined(K3_CLUSTER2_MSMC_PORT) +#define K3_CLUSTER2_CORE_COUNT 0 +#define K3_CLUSTER2_MSMC_PORT UNUSED +#endif + +#if !defined(K3_CLUSTER3_CORE_COUNT) || !defined(K3_CLUSTER3_MSMC_PORT) +#define K3_CLUSTER3_CORE_COUNT 0 +#define K3_CLUSTER3_MSMC_PORT UNUSED +#endif + +#if K3_CLUSTER0_MSMC_PORT == UNUSED +#error "ARM cluster 0 must be used" +#endif + +#if ((K3_CLUSTER1_MSMC_PORT == UNUSED) && (K3_CLUSTER1_CORE_COUNT != 0)) || \ + ((K3_CLUSTER2_MSMC_PORT == UNUSED) && (K3_CLUSTER2_CORE_COUNT != 0)) || \ + ((K3_CLUSTER3_MSMC_PORT == UNUSED) && (K3_CLUSTER3_CORE_COUNT != 0)) +#error "Unused ports must have 0 ARM cores" +#endif + +#define PLATFORM_CLUSTER_OFFSET K3_CLUSTER0_MSMC_PORT + +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 + +/******************************************************************************* + * Memory layout constants + ******************************************************************************/ + +/* + * ARM-TF lives in SRAM, partition it here + */ + +#define SHARED_RAM_BASE BL31_LIMIT +#define SHARED_RAM_SIZE 0x00001000 + +/* + * BL3-1 specific defines. + * + * Put BL3-1 at the base of the Trusted SRAM, before SHARED_RAM. + */ +#define BL31_BASE SEC_SRAM_BASE +#define BL31_SIZE (SEC_SRAM_SIZE - SHARED_RAM_SIZE) +#define BL31_LIMIT (BL31_BASE + BL31_SIZE) +#define BL31_PROGBITS_LIMIT BL31_LIMIT + +/* + * Defines the maximum number of translation tables that are allocated by the + * translation table library code. To minimize the amount of runtime memory + * used, choose the smallest value needed to map the required virtual addresses + * for each BL stage. + */ +#define MAX_XLAT_TABLES 8 + +/* + * Defines the maximum number of regions that are allocated by the translation + * table library code. A region consists of physical base address, virtual base + * address, size and attributes (Device/Memory, RO/RW, Secure/Non-Secure), as + * defined in the `mmap_region_t` structure. The platform defines the regions + * that should be mapped. Then, the translation table library will create the + * corresponding tables and descriptors at runtime. To minimize the amount of + * runtime memory used, choose the smallest value needed to register the + * required regions for each BL stage. + */ +#define MAX_MMAP_REGIONS 8 + +/* + * Defines the total size of the address space in bytes. For example, for a 32 + * bit address space, this value should be `(1ull << 32)`. + */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32) + +/* + * 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_SHIFT 6 +#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) + +/* Platform default console definitions */ +#ifndef K3_USART_BASE_ADDRESS +#define K3_USART_BASE_ADDRESS 0x02800000 +#endif + +/* USART has a default size for address space */ +#define K3_USART_SIZE 0x1000 + +#ifndef K3_USART_CLK_SPEED +#define K3_USART_CLK_SPEED 48000000 +#endif + +#ifndef K3_USART_BAUD +#define K3_USART_BAUD 115200 +#endif + +/* Crash console defaults */ +#define CRASH_CONSOLE_BASE K3_USART_BASE_ADDRESS +#define CRASH_CONSOLE_CLK K3_USART_CLK_SPEED +#define CRASH_CONSOLE_BAUD_RATE K3_USART_BAUD + +/* Timer frequency */ +#ifndef SYS_COUNTER_FREQ_IN_TICKS +#define SYS_COUNTER_FREQ_IN_TICKS 200000000 +#endif + +/* Interrupt numbers */ +#define ARM_IRQ_SEC_PHY_TIMER 29 + +#define ARM_IRQ_SEC_SGI_0 8 +#define ARM_IRQ_SEC_SGI_1 9 +#define ARM_IRQ_SEC_SGI_2 10 +#define ARM_IRQ_SEC_SGI_3 11 +#define ARM_IRQ_SEC_SGI_4 12 +#define ARM_IRQ_SEC_SGI_5 13 +#define ARM_IRQ_SEC_SGI_6 14 +#define ARM_IRQ_SEC_SGI_7 15 + +/* + * Define properties of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLAT_ARM_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE) + +#define PLAT_ARM_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE) + +#define K3_GICD_BASE 0x01800000 +#define K3_GICD_SIZE 0x10000 +#define K3_GICR_BASE 0x01880000 +#define K3_GICR_SIZE 0x100000 + +#endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/ti/k3/platform.mk b/plat/ti/k3/platform.mk new file mode 100644 index 000000000..65d5cc2a4 --- /dev/null +++ b/plat/ti/k3/platform.mk @@ -0,0 +1,14 @@ +# +# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_PATH := plat/ti/k3 +TARGET_BOARD ?= generic + +include ${PLAT_PATH}/common/plat_common.mk +include ${PLAT_PATH}/board/${TARGET_BOARD}/board.mk + +# modify BUILD_PLAT to point to board specific build directory +BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_BOARD}/${BUILD_TYPE} diff --git a/readme.rst b/readme.rst index 94b1e6383..3738c97dd 100644 --- a/readme.rst +++ b/readme.rst @@ -183,6 +183,7 @@ This release also contains the following platform support: - Raspberry Pi 3 board - RockChip RK3328, RK3368 and RK3399 SoCs - Socionext UniPhier SoC family +- Texas Instruments K3 SoCs - Xilinx Zynq UltraScale + MPSoC Still to come