Merge pull request #1403 from glneo/for-upstream-k3
TI K3 platform support
This commit is contained in:
commit
3caa841d9c
|
@ -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=<path to 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=<path> TEE=<path>
|
||||
|
||||
Deploy Images
|
||||
-------------
|
||||
|
||||
.. code:: shell
|
||||
|
||||
cp tiboot3.bin tispl.bin u-boot.img /sdcard/boot/
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
|
@ -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__ */
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <debug.h>
|
||||
#include <k3_console.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform_def.h>
|
||||
#include <k3_gicv3.h>
|
||||
#include <string.h>
|
||||
|
||||
/* 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;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <console.h>
|
||||
#include <k3_console.h>
|
||||
#include <platform_def.h>
|
||||
#include <uart_16550.h>
|
||||
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <bl_common.h>
|
||||
#include <gicv3.h>
|
||||
#include <interrupt_props.h>
|
||||
#include <k3_gicv3.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <utils.h>
|
||||
|
||||
/* 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());
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2017-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>
|
||||
|
||||
#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
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <k3_gicv3.h>
|
||||
#include <psci.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <psci.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
|
@ -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} \
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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 <arch.h>
|
||||
#include <board_def.h>
|
||||
#include <common_def.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* 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__ */
|
|
@ -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}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue