sc7180 platform support

Adding support for QTI CHIP SC7180 on ATF

Change-Id: I0d82d3a378036003fbd0bc4784f61464bb76ea82
Signed-off-by: Saurabh Gorecha <sgorecha@codeaurora.org>
Co-authored-by: Maulik Shah <mkshah@codeaurora.org>
This commit is contained in:
Saurabh Gorecha 2020-04-22 21:31:24 +05:30
parent 4108abb4a0
commit 5bd9c17d02
30 changed files with 2778 additions and 0 deletions

View File

@ -228,6 +228,15 @@ QEMU platform port
:F: docs/plat/qemu.rst
:F: plat/qemu/
QTI platform port
^^^^^^^^^^^^^^^^^
:M: Saurabh Gorecha <sgorecha@codeaurora.org>
:G: `sgorecha`_
:M: Debasish Mandal <dmandal@codeaurora.org>
:M: QTI TF Maintainers <qti.trustedfirmware.maintainers@codeaurora.org>
:F: docs/plat/qti.rst
:F: plat/qti/
Raspberry Pi 3 platform port
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:M: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
@ -356,6 +365,7 @@ TLK/Trusty secure payloads
.. _remi-triplefault: https://github.com/repk
.. _rockchip-linux: https://github.com/rockchip-linux
.. _sandrine-bailleux-arm: https://github.com/sandrine-bailleux-arm
.. _sgorecha: https://github.com/sgorecha
.. _shawnguo2: https://github.com/shawnguo2
.. _sivadur: https://github.com/sivadur
.. _smaeul: https://github.com/smaeul

View File

@ -27,6 +27,7 @@ Platform Ports
poplar
qemu
qemu-sbsa
qti
rpi3
rpi4
rcar-gen3

41
docs/plat/qti.rst Normal file
View File

@ -0,0 +1,41 @@
Qualcomm Technologies, Inc.
===========================
Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QTI SC7180.
Boot Trace
-------------
Bootrom --> BL1/BL2 --> BL31 --> BL33 --> Linux kernel
BL1/2 and BL33 can currently be supplied from Coreboot + Depthcharge
How to build
------------
Code Locations
~~~~~~~~~~~~~~
- Trusted Firmware-A:
`link <https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git>`__
Build Procedure
~~~~~~~~~~~~~~~
QTI SoC expects TF-A's BL31 to get integrated with other boot software
Coreboot, so only bl31.elf need to get build from the TF-A repository.
The build command looks like
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sc7180 COREBOOT=1
update value of CROSS_COMPILE argument with your cross-compilation toolchain.
Additional QTISECLIB_PATH=<path to qtiseclib> can be added in build command.
if QTISECLIB_PATH is not added in build command stub implementation of qtiseclib
is picked. qtiseclib with stub implementation doesn't boot device. This was
added to satisfy compilation.
QTISELIB for SC7180 is available at
`link <https://review.coreboot.org/cgit/qc_blobs.git/plain/sc7180/qtiseclib/libqtisec.a>`__

View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLAT_MACROS_S__
#define __PLAT_MACROS_S__
#include <drivers/arm/gic_common.h>
#include <drivers/arm/gicv2.h>
#include <drivers/arm/gicv3.h>
#include <platform_def.h>
.section .rodata.gic_reg_name, "aS"
/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
gicc_regs:
.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
/* Applicable only to GICv3 with SRE enabled */
icc_regs:
.asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
/* Registers common to both GICv2 and GICv3 */
gicd_pend_reg:
.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
" Offset:\t\t\tvalue\n"
newline:
.asciz "\n"
spacer:
.asciz ":\t\t0x"
/** Macro : plat_crash_print_regs
* This macro allows the crash reporting routine to print GIC registers
* in case of an unhandled exception in BL31. This aids in debugging and
* this macro can be defined to be empty in case GIC register reporting is
* not desired.
* The below required platform porting macro
* prints out relevant GIC registers whenever an
* unhandled exception is taken in BL31.
* Clobbers: x0 - x10, x26, x27, sp
* ---------------------------------------------
*/
.macro plat_crash_print_regs
print_gic_regs:
ldr x26, =QTI_GICD_BASE
ldr x27, =QTI_GICC_BASE
/* Check for GICv3 system register access */
mrs x7, id_aa64pfr0_el1
ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
cmp x7, #1
b.ne print_gicv2
/* Check for SRE enable */
mrs x8, ICC_SRE_EL3
tst x8, #ICC_SRE_SRE_BIT
b.eq print_gicv2
/* Load the icc reg list to x6 */
adr x6, icc_regs
/* Load the icc regs to gp regs used by str_in_crash_buf_print */
mrs x8, ICC_HPPIR0_EL1
mrs x9, ICC_HPPIR1_EL1
mrs x10, ICC_CTLR_EL3
/* Store to the crash buf and print to console */
bl str_in_crash_buf_print
b print_gic_common
print_gicv2:
/* Load the gicc reg list to x6 */
adr x6, gicc_regs
/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
ldr w8, [x27, #GICC_HPPIR]
ldr w9, [x27, #GICC_AHPPIR]
ldr w10, [x27, #GICC_CTLR]
/* Store to the crash buf and print to console */
bl str_in_crash_buf_print
print_gic_common:
/* Print the GICD_ISPENDR regs */
add x7, x26, #GICD_ISPENDR
adr x4, gicd_pend_reg
bl asm_print_str
gicd_ispendr_loop:
sub x4, x7, x26
cmp x4, #0x280
b.eq exit_print_gic_regs
bl asm_print_hex
adr x4, spacer
bl asm_print_str
ldr x4, [x7], #8
bl asm_print_hex
adr x4, newline
bl asm_print_str
b gicd_ispendr_loop
exit_print_gic_regs:
.endm
#endif /* __PLAT_MACROS_S__ */

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTI_BOARD_DEF_H
#define QTI_BOARD_DEF_H
/*
* Required platform porting definitions common to all ARM
* development platforms
*/
/* Size of cacheable stacks */
#define PLATFORM_STACK_SIZE 0x1000
/*
* PLAT_QTI_MMAP_ENTRIES depends on the number of entries in the
* plat_qti_mmap array defined for each BL stage.
*/
#define PLAT_QTI_MMAP_ENTRIES 12
/*
* Platform specific page table and MMU setup constants
*/
#define MAX_XLAT_TABLES 12
#endif /* QTI_BOARD_DEF_H */

View File

@ -0,0 +1,16 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTI_CPU_H
#define QTI_CPU_H
/* KRYO-4xx Gold MIDR */
#define QTI_KRYO4_GOLD_MIDR 0x517F804D
/* KRYO-4xx Silver MIDR */
#define QTI_KRYO4_SILVER_MIDR 0x517F805D
#endif /* QTI_CPU_H */

View File

@ -0,0 +1,12 @@
/*
* Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTI_INTERRUPT_SVC_H
#define QTI_INTERRUPT_SVC_H
int qti_interrupt_svc_init(void);
#endif /* QTI_INTERRUPT_SVC_H */

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTI_PLAT_H
#define QTI_PLAT_H
#include <stdint.h>
#include <common/bl_common.h>
#include <lib/cassert.h>
#include <lib/el3_runtime/cpu_data.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
/*
* Utility functions common to QTI platforms
*/
int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
unsigned int attr);
int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
/*
* Utility functions common to ARM standard platforms
*/
void qti_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,
uintptr_t coh_start, uintptr_t coh_limit);
/*
* Mandatory functions required in ARM standard platforms
*/
void plat_qti_gic_driver_init(void);
void plat_qti_gic_init(void);
void plat_qti_gic_cpuif_enable(void);
void plat_qti_gic_cpuif_disable(void);
void plat_qti_gic_pcpu_init(void);
/*
* Optional functions required in ARM standard platforms
*/
unsigned int plat_qti_core_pos_by_mpidr(u_register_t mpidr);
unsigned int plat_qti_my_cluster_pos(void);
void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr);
#endif /* QTI_PLAT_H */

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTI_UART_CONSOLE_H
#define QTI_UART_CONSOLE_H
#include <drivers/console.h>
#ifndef __ASSEMBLER__
int qti_console_uart_register(console_t *console, uintptr_t uart_base_addr);
#endif /* __ASSEMBLER__ */
#endif /* QTI_UART_CONSOLE_H */

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <drivers/arm/gicv2.h>
#include <drivers/arm/gicv3.h>
#include <drivers/console.h>
#include <platform_def.h>
.globl plat_my_core_pos
.globl plat_qti_core_pos_by_mpidr
.globl plat_reset_handler
.globl plat_panic_handler
/* -----------------------------------------------------
* unsigned int plat_qti_core_pos_by_mpidr(uint64_t mpidr)
* Helper function to calculate the core position.
* With this function:
* CorePos = (ClusterId * 4) + CoreId
* - In ARM v8 (MPIDR_EL1[24]=0)
* ClusterId = MPIDR_EL1[15:8]
* CoreId = MPIDR_EL1[7:0]
* - In ARM v8.1 (MPIDR_EL1[24]=1)
* ClusterId = MPIDR_EL1[23:15]
* CoreId = MPIDR_EL1[15:8]
* Clobbers: x0 & x1.
* -----------------------------------------------------
*/
func plat_qti_core_pos_by_mpidr
mrs x1, mpidr_el1
tst x1, #MPIDR_MT_MASK
beq plat_qti_core_pos_by_mpidr_no_mt
/* Right shift mpidr by one affinity level when MT=1. */
lsr x0, x0, #MPIDR_AFFINITY_BITS
plat_qti_core_pos_by_mpidr_no_mt:
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
add x0, x1, x0, LSR #6
ret
endfunc plat_qti_core_pos_by_mpidr
/* --------------------------------------------------------------------
* void plat_panic_handler(void)
* calls SDI and reset system
* --------------------------------------------------------------------
*/
func plat_panic_handler
msr spsel, #0
bl plat_set_my_stack
b qtiseclib_panic
endfunc plat_panic_handler
/* -----------------------------------------------------
* unsigned int plat_my_core_pos(void)
* This function uses the plat_qti_calc_core_pos()
* definition to get the index of the calling CPU
* Clobbers: x0 & x1.
* -----------------------------------------------------
*/
func plat_my_core_pos
mrs x0, mpidr_el1
b plat_qti_core_pos_by_mpidr
endfunc plat_my_core_pos
func plat_reset_handler
/* save the lr */
mov x18, x30
/* Serialize CPUSS boot setup. Multi core enter simultaneously. */
ldr x0, =g_qti_cpuss_boot_lock
bl spin_lock
/* pass cold boot status. */
ldr w0, g_qti_bl31_cold_booted
/* Execuete CPUSS boot set up on every core. */
bl qtiseclib_cpuss_reset_asm
ldr x0, =g_qti_cpuss_boot_lock
bl spin_unlock
ret x18
endfunc plat_reset_handler

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <cpu_macros.S>
#include <plat_macros.S>
#include <qti_cpu.h>
.p2align 3
/* -------------------------------------------------
* The CPU Ops reset function for Kryo-3 Gold
* -------------------------------------------------
*/
func qti_kryo4_gold_reset_func
#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
adr x0, wa_cve_2017_5715_bpiall_vbar
msr vbar_el3, x0
isb
#endif
mov x19, x30
bl qtiseclib_kryo4_gold_reset_asm
ret x19
endfunc qti_kryo4_gold_reset_func
/* ----------------------------------------------------
* The CPU Ops core power down function for Kryo-3 Gold
* ----------------------------------------------------
*/
func qti_kryo4_gold_core_pwr_dwn
ret
endfunc qti_kryo4_gold_core_pwr_dwn
/* -------------------------------------------------------
* The CPU Ops cluster power down function for Kryo-3 Gold
* -------------------------------------------------------
*/
func qti_kryo4_gold_cluster_pwr_dwn
ret
endfunc qti_kryo4_gold_cluster_pwr_dwn
#if REPORT_ERRATA
/*
* Errata printing function for Kryo4 Gold. Must follow AAPCS.
*/
func qti_kryo4_gold_errata_report
/* TODO : Need to add support. Required only for debug bl31 image.*/
ret
endfunc qti_kryo4_gold_errata_report
#endif
/* ---------------------------------------------
* This function provides kryo4_gold specific
* register information for crash reporting.
* It needs to return with x6 pointing to
* a list of register names in ASCII and
* x8 - x15 having values of registers to be
* reported.
* ---------------------------------------------
*/
.section .rodata.qti_kryo4_gold_regs, "aS"
qti_kryo4_gold_regs: /* The ASCII list of register names to be reported */
.asciz ""
func qti_kryo4_gold_cpu_reg_dump
adr x6, qti_kryo4_gold_regs
ret
endfunc qti_kryo4_gold_cpu_reg_dump
declare_cpu_ops qti_kryo4_gold, QTI_KRYO4_GOLD_MIDR, \
qti_kryo4_gold_reset_func, \
qti_kryo4_gold_core_pwr_dwn, \
qti_kryo4_gold_cluster_pwr_dwn

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <cpu_macros.S>
#include <plat_macros.S>
#include <qti_cpu.h>
.p2align 3
/* -------------------------------------------------
* The CPU Ops reset function for Kryo-3 Silver
* -------------------------------------------------
*/
func qti_kryo4_silver_reset_func
mov x19, x30
bl qtiseclib_kryo4_silver_reset_asm
ret x19
endfunc qti_kryo4_silver_reset_func
/* ------------------------------------------------------
* The CPU Ops core power down function for Kryo-3 Silver
* ------------------------------------------------------
*/
func qti_kryo4_silver_core_pwr_dwn
ret
endfunc qti_kryo4_silver_core_pwr_dwn
/* ---------------------------------------------------------
* The CPU Ops cluster power down function for Kryo-3 Silver
* ---------------------------------------------------------
*/
func qti_kryo4_silver_cluster_pwr_dwn
ret
endfunc qti_kryo4_silver_cluster_pwr_dwn
#if REPORT_ERRATA
/*
* Errata printing function for Kryo4 Silver. Must follow AAPCS.
*/
func qti_kryo4_silver_errata_report
/* TODO : Need to add support. Required only for debug bl31 image.*/
ret
endfunc qti_kryo4_silver_errata_report
#endif
/* ---------------------------------------------
* This function provides kryo4_silver specific
* register information for crash reporting.
* It needs to return with x6 pointing to
* a list of register names in ASCII and
* x8 - x15 having values of registers to be
* reported.
* ---------------------------------------------
*/
.section .rodata.qti_kryo4_silver_regs, "aS"
qti_kryo4_silver_regs: /* The ASCII list of register names to be reported */
.asciz ""
func qti_kryo4_silver_cpu_reg_dump
adr x6, qti_kryo4_silver_regs
ret
endfunc qti_kryo4_silver_cpu_reg_dump
declare_cpu_ops qti_kryo4_silver, QTI_KRYO4_SILVER_MIDR, \
qti_kryo4_silver_reset_func, \
qti_kryo4_silver_core_pwr_dwn, \
qti_kryo4_silver_cluster_pwr_dwn

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
#include <console_macros.S>
#include <platform_def.h>
#include <qti_uart_console.h>
/*
* This driver implements console logging into a ring buffer.
*/
.globl qti_console_uart_register
/* -----------------------------------------------
* int qti_console_uart_register(console_t *console,
* uintptr_t uart_base_addr)
* Registers uart console instance.
* In: x0 - pointer to empty console_t struct
* x1 - start address of uart block.
* Out: x0 - 1 to indicate success
* Clobber list: x0, x1, x14
* -----------------------------------------------
*/
func qti_console_uart_register
str x1, [x0, #CONSOLE_T_BASE] /* Save UART base. */
finish_console_register uart putc=1, flush=1
endfunc qti_console_uart_register
/* -----------------------------------------------
* int qti_console_uart_puts(int c, console_t *console)
* Writes a character to the UART console.
* The character must be preserved in x0.
* In: x0 - character to be stored
* x1 - pointer to console_t struct
* Clobber list: x1, x2
* -----------------------------------------------
*/
func console_uart_putc
/* set x1 = UART base. */
ldr x1, [x1, #CONSOLE_T_BASE]
/* Loop until M_GENI_CMD_ACTIVE bit not clear. */
1: ldr w2, [x1, #GENI_STATUS_REG]
and w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
cmp w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
b.eq 1b
/* Transmit data. */
cmp w0, #0xA
b.ne 3f
/* Add '\r' when input char is '\n' */
mov w2, #0x1
mov w0, #0xD
str w2, [x1, #UART_TX_TRANS_LEN_REG]
mov w2, #GENI_M_CMD_TX
str w2, [x1, #GENI_M_CMD0_REG]
str w0, [x1, #GENI_TX_FIFOn_REG]
mov w0, #0xA
/* Loop until M_GENI_CMD_ACTIVE bit not clear. */
2: ldr w2, [x1, #GENI_STATUS_REG]
and w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
cmp w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
b.eq 2b
/* Transmit i/p data. */
3: mov w2, #0x1
str w2, [x1, #UART_TX_TRANS_LEN_REG]
mov w2, #GENI_M_CMD_TX
str w2, [x1, #GENI_M_CMD0_REG]
str w0, [x1, #GENI_TX_FIFOn_REG]
ret
endfunc console_uart_putc
/* -----------------------------------------------
* int qti_console_uart_flush(console_t *console)
* In: x0 - pointer to console_t struct
* Out: x0 - 0 for success
* Clobber list: x0, x1
* -----------------------------------------------
*/
func console_uart_flush
/* set x0 = UART base. */
ldr x0, [x0, #CONSOLE_T_BASE]
/* Loop until M_GENI_CMD_ACTIVE bit not clear. */
1: ldr w1, [x0, #GENI_STATUS_REG]
and w1, w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
cmp w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
b.eq 1b
mov w0, #0
ret
endfunc console_uart_flush

View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <bl31/bl31.h>
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/console.h>
#include <drivers/generic_delay_timer.h>
#include <lib/bl_aux_params/bl_aux_params.h>
#include <lib/coreboot.h>
#include <lib/spinlock.h>
#include <platform.h>
#include <qti_interrupt_svc.h>
#include <qti_plat.h>
#include <qti_uart_console.h>
#include <qtiseclib_interface.h>
/*
* Placeholder variables for copying the arguments that have been passed to
* BL31 from BL2.
*/
static entry_point_info_t bl33_image_ep_info;
/*
* Variable to hold counter frequency for the CPU's generic timer. In this
* platform coreboot image configure counter frequency for boot core before
* reaching TF-A.
*/
static uint64_t g_qti_cpu_cntfrq;
/*
* Lock variable to serialize cpuss reset execution.
*/
spinlock_t g_qti_cpuss_boot_lock __attribute__ ((section("tzfw_coherent_mem"),
aligned(CACHE_WRITEBACK_GRANULE))) = {0x0};
/*
* Variable to hold bl31 cold boot status. Default value 0x0 means yet to boot.
* Any other value means cold booted.
*/
uint32_t g_qti_bl31_cold_booted __attribute__ ((section("tzfw_coherent_mem"))) = 0x0;
/*******************************************************************************
* Perform any BL31 early platform setup common to ARM standard 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 bl31_early_platform_setup(u_register_t from_bl2,
u_register_t plat_params_from_bl2)
{
g_qti_cpu_cntfrq = read_cntfrq_el0();
bl_aux_params_parse(plat_params_from_bl2, NULL);
#if COREBOOT
if (coreboot_serial.baseaddr != 0) {
static console_t g_qti_console_uart;
qti_console_uart_register(&g_qti_console_uart,
coreboot_serial.baseaddr);
}
#endif
/*
* Tell BL31 where the non-trusted software image
* is located and the entry state information
*/
bl31_params_parse_helper(from_bl2, NULL, &bl33_image_ep_info);
}
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(arg0, arg1);
}
/*******************************************************************************
* Perform the very early platform specific architectural setup here. At the
* moment this only intializes the mmu in a quick and dirty way.
******************************************************************************/
void bl31_plat_arch_setup(void)
{
qti_setup_page_tables(BL_CODE_BASE,
BL_COHERENT_RAM_END - BL_CODE_BASE,
BL_CODE_BASE,
BL_CODE_END,
BL_RO_DATA_BASE,
BL_RO_DATA_END,
BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
enable_mmu_el3(0);
}
/*******************************************************************************
* Perform any BL31 platform setup common to ARM standard platforms
******************************************************************************/
void bl31_platform_setup(void)
{
generic_delay_timer_init();
/* Initialize the GIC driver, CPU and distributor interfaces */
plat_qti_gic_driver_init();
plat_qti_gic_init();
qti_interrupt_svc_init();
qtiseclib_bl31_platform_setup();
/* set boot state to cold boot complete. */
g_qti_bl31_cold_booted = 0x1;
}
/*******************************************************************************
* 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)
{
/* QTI platform don't have BL32 implementation. */
assert(type == NON_SECURE);
assert(bl33_image_ep_info.h.type == PARAM_EP);
assert(bl33_image_ep_info.h.attr == NON_SECURE);
/*
* None of the images on the platforms can have 0x0
* as the entrypoint.
*/
if (bl33_image_ep_info.pc) {
return &bl33_image_ep_info;
} else {
return NULL;
}
}
/*******************************************************************************
* This function is used by the architecture setup code to retrieve the counter
* frequency for the CPU's generic timer. This value will be programmed into the
* CNTFRQ_EL0 register. In Arm standard platforms, it returns the base frequency
* of the system counter, which is retrieved from the first entry in the
* frequency modes table. This will be used later in warm boot (psci_arch_setup)
* of CPUs to set when CPU frequency.
******************************************************************************/
unsigned int plat_get_syscnt_freq2(void)
{
assert(g_qti_cpu_cntfrq != 0);
return g_qti_cpu_cntfrq;
}

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <common/debug.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <platform_def.h>
#include <qti_plat.h>
#include <qtiseclib_interface.h>
/*
* Table of regions for various BL stages to map using the MMU.
* This doesn't include TZRAM as the 'mem_layout' argument passed to
* qti_configure_mmu_elx() will give the available subset of that,
*/
const mmap_region_t plat_qti_mmap[] = {
MAP_REGION_FLAT(QTI_DEVICE_BASE, QTI_DEVICE_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(QTI_AOP_CMD_DB_BASE, QTI_AOP_CMD_DB_SIZE,
MT_NS | MT_RO | MT_EXECUTE_NEVER),
{0}
};
CASSERT(ARRAY_SIZE(plat_qti_mmap) <= MAX_MMAP_REGIONS, assert_max_mmap_regions);
bool qti_is_overlap_atf_rg(unsigned long long addr, size_t size)
{
if (addr > addr + size
|| (BL31_BASE < addr + size && BL31_LIMIT > addr)) {
return true;
}
return false;
}
/*
* unsigned int plat_qti_my_cluster_pos(void)
* definition to get the cluster index of the calling CPU.
* - In ARM v8 (MPIDR_EL1[24]=0)
* ClusterId = MPIDR_EL1[15:8]
* - In ARM v8.1 & Later version (MPIDR_EL1[24]=1)
* ClusterId = MPIDR_EL1[23:15]
*/
unsigned int plat_qti_my_cluster_pos(void)
{
unsigned int mpidr, cluster_id;
mpidr = read_mpidr_el1();
if ((mpidr & MPIDR_MT_MASK) == 0) { /* MT not supported */
cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
} else { /* MT supported */
cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
}
assert(cluster_id < PLAT_CLUSTER_COUNT);
return cluster_id;
}
/*
* 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 qti_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,
uintptr_t coh_start, uintptr_t coh_limit)
{
/*
* 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);
/* 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);
/* Now (re-)map the platform-specific memory regions */
mmap_add(plat_qti_mmap);
/* Create the page tables to reflect the above mappings */
init_xlat_tables();
}
static inline void qti_align_mem_region(uintptr_t addr, size_t size,
uintptr_t *aligned_addr,
size_t *aligned_size)
{
*aligned_addr = round_down(addr, PAGE_SIZE);
*aligned_size = round_up(addr - *aligned_addr + size, PAGE_SIZE);
}
int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
unsigned int attr)
{
uintptr_t aligned_pa;
size_t aligned_size;
qti_align_mem_region(base_pa, size, &aligned_pa, &aligned_size);
if (qti_is_overlap_atf_rg(base_pa, size)) {
/* Memory shouldn't overlap with TF-A range. */
return -EPERM;
}
return mmap_add_dynamic_region(aligned_pa, aligned_pa, aligned_size,
attr);
}
int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
{
qti_align_mem_region(base_va, size, &base_va, &size);
return mmap_remove_dynamic_region(base_va, size);
}

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/bl_common.h>
#include <drivers/arm/gicv3.h>
#include <platform.h>
#include <platform_def.h>
#include <qti_plat.h>
#include <qtiseclib_defs.h>
#include <qtiseclib_defs_plat.h>
/* The GICv3 driver only needs to be initialized in EL3 */
static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
/* Array of interrupts to be configured by the gic driver */
static const interrupt_prop_t qti_interrupt_props[] = {
INTR_PROP_DESC(QTISECLIB_INT_ID_CPU_WAKEUP_SGI,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_RESET_SGI, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_SEC_WDOG_BARK, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_NON_SEC_WDOG_BITE,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_LEVEL),
INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_XPU_SEC, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_XPU_NON_SEC, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
#ifdef QTISECLIB_INT_ID_A1_NOC_ERROR
INTR_PROP_DESC(QTISECLIB_INT_ID_A1_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
#endif
INTR_PROP_DESC(QTISECLIB_INT_ID_A2_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_CONFIG_NOC_ERROR,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_DC_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_MEM_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_SYSTEM_NOC_ERROR,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(QTISECLIB_INT_ID_MMSS_NOC_ERROR,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
};
const gicv3_driver_data_t qti_gic_data = {
.gicd_base = QTI_GICD_BASE,
.gicr_base = QTI_GICR_BASE,
.interrupt_props = qti_interrupt_props,
.interrupt_props_num = ARRAY_SIZE(qti_interrupt_props),
.rdistif_num = PLATFORM_CORE_COUNT,
.rdistif_base_addrs = rdistif_base_addrs,
.mpidr_to_core_pos = plat_qti_core_pos_by_mpidr
};
void plat_qti_gic_driver_init(void)
{
/*
* 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.
*/
gicv3_driver_init(&qti_gic_data);
}
/******************************************************************************
* ARM common helper to initialize the GIC. Only invoked by BL31
*****************************************************************************/
void plat_qti_gic_init(void)
{
unsigned int i;
gicv3_distif_init();
gicv3_rdistif_init(plat_my_core_pos());
gicv3_cpuif_enable(plat_my_core_pos());
/* Route secure spi interrupt to ANY. */
for (i = 0; i < ARRAY_SIZE(qti_interrupt_props); i++) {
unsigned int int_id = qti_interrupt_props[i].intr_num;
if (plat_ic_is_spi(int_id)) {
gicv3_set_spi_routing(int_id, GICV3_IRM_ANY, 0x0);
}
}
}
void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t target)
{
gicv3_set_spi_routing(id, irm, target);
}
/******************************************************************************
* ARM common helper to enable the GIC CPU interface
*****************************************************************************/
void plat_qti_gic_cpuif_enable(void)
{
gicv3_cpuif_enable(plat_my_core_pos());
}
/******************************************************************************
* ARM common helper to disable the GIC CPU interface
*****************************************************************************/
void plat_qti_gic_cpuif_disable(void)
{
gicv3_cpuif_disable(plat_my_core_pos());
}
/******************************************************************************
* ARM common helper to initialize the per-CPU redistributor interface in GICv3
*****************************************************************************/
void plat_qti_gic_pcpu_init(void)
{
gicv3_rdistif_init(plat_my_core_pos());
}
/******************************************************************************
* ARM common helpers to power GIC redistributor interface
*****************************************************************************/
void plat_qti_gic_redistif_on(void)
{
gicv3_rdistif_on(plat_my_core_pos());
}
void plat_qti_gic_redistif_off(void)
{
gicv3_rdistif_off(plat_my_core_pos());
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <stdint.h>
#include <arch_helpers.h>
#include <bl31/interrupt_mgmt.h>
#include <drivers/arm/gic_common.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <platform.h>
#include <qti_interrupt_svc.h>
#include <qtiseclib_interface.h>
#define QTI_INTR_INVALID_INT_NUM 0xFFFFFFFFU
/*
* Top-level EL3 interrupt handler.
*/
static uint64_t qti_el3_interrupt_handler(uint32_t id, uint32_t flags,
void *handle, void *cookie)
{
uint32_t irq = QTI_INTR_INVALID_INT_NUM;
/*
* EL3 non-interruptible. Interrupt shouldn't occur when we are at
* EL3 / Secure.
*/
assert(handle != cm_get_context(SECURE));
irq = plat_ic_acknowledge_interrupt();
qtiseclib_invoke_isr(irq, handle);
/* End of Interrupt. */
if (irq < 1022U) {
plat_ic_end_of_interrupt(irq);
}
return (uint64_t) handle;
}
int qti_interrupt_svc_init(void)
{
int ret;
uint64_t flags = 0U;
/*
* Route EL3 interrupts to EL3 when in Non-secure.
* Note: EL3 won't have interrupt enable
* & we don't have S-EL1 support.
*/
set_interrupt_rm_flag(flags, NON_SECURE);
/* Register handler for EL3 interrupts */
ret = register_interrupt_type_handler(INTR_TYPE_EL3,
qti_el3_interrupt_handler, flags);
assert(ret == 0);
return ret;
}

View File

@ -0,0 +1,274 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <arch_helpers.h>
#include <bl31/bl31.h>
#include <common/debug.h>
#include <lib/psci/psci.h>
#include <platform.h>
#include <platform_def.h>
#include <qti_cpu.h>
#include <qti_plat.h>
#include <qtiseclib_cb_interface.h>
#include <qtiseclib_defs_plat.h>
#include <qtiseclib_interface.h>
#define QTI_LOCAL_PSTATE_WIDTH 4
#define QTI_LOCAL_PSTATE_MASK ((1 << QTI_LOCAL_PSTATE_WIDTH) - 1)
/* Make composite power state parameter till level 0 */
#define qti_make_pwrstate_lvl0(lvl0_state, type) \
(((lvl0_state) << PSTATE_ID_SHIFT) | ((type) << PSTATE_TYPE_SHIFT))
/* Make composite power state parameter till level 1 */
#define qti_make_pwrstate_lvl1(lvl1_state, lvl0_state, type) \
(((lvl1_state) << QTI_LOCAL_PSTATE_WIDTH) | \
qti_make_pwrstate_lvl0(lvl0_state, type))
/* Make composite power state parameter till level 2 */
#define qti_make_pwrstate_lvl2(lvl2_state, lvl1_state, lvl0_state, type) \
(((lvl2_state) << (QTI_LOCAL_PSTATE_WIDTH * 2)) | \
qti_make_pwrstate_lvl1(lvl1_state, lvl0_state, type))
/* Make composite power state parameter till level 3 */
#define qti_make_pwrstate_lvl3(lvl3_state, lvl2_state, lvl1_state, lvl0_state, type) \
(((lvl3_state) << (QTI_LOCAL_PSTATE_WIDTH * 3)) | \
qti_make_pwrstate_lvl2(lvl2_state, lvl1_state, lvl0_state, type))
/* QTI_CORE_PWRDN_EN_MASK happens to be same across all CPUs */
#define QTI_CORE_PWRDN_EN_MASK 1
/* cpu power control happens to be same across all CPUs */
_DEFINE_SYSREG_WRITE_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7)
_DEFINE_SYSREG_READ_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7)
const unsigned int qti_pm_idle_states[] = {
qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_OFF,
PSTATE_TYPE_POWERDOWN),
qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_DEEPOFF,
PSTATE_TYPE_POWERDOWN),
qti_make_pwrstate_lvl1(QTI_LOCAL_STATE_DEEPOFF,
QTI_LOCAL_STATE_DEEPOFF,
PSTATE_TYPE_POWERDOWN),
qti_make_pwrstate_lvl2(QTI_LOCAL_STATE_OFF,
QTI_LOCAL_STATE_DEEPOFF,
QTI_LOCAL_STATE_DEEPOFF,
PSTATE_TYPE_POWERDOWN),
qti_make_pwrstate_lvl3(QTI_LOCAL_STATE_OFF,
QTI_LOCAL_STATE_DEEPOFF,
QTI_LOCAL_STATE_DEEPOFF,
QTI_LOCAL_STATE_DEEPOFF,
PSTATE_TYPE_POWERDOWN),
0,
};
/*******************************************************************************
* QTI standard platform handler called to check the validity of the power
* state parameter. The power state parameter has to be a composite power
* state.
******************************************************************************/
int qti_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
unsigned int state_id;
int i;
assert(req_state);
/*
* Currently we are using a linear search for finding the matching
* entry in the idle power state array. This can be made a binary
* search if the number of entries justify the additional complexity.
*/
for (i = 0; !!qti_pm_idle_states[i]; i++) {
if (power_state == qti_pm_idle_states[i])
break;
}
/* Return error if entry not found in the idle state array */
if (!qti_pm_idle_states[i])
return PSCI_E_INVALID_PARAMS;
i = 0;
state_id = psci_get_pstate_id(power_state);
/* Parse the State ID and populate the state info parameter */
while (state_id) {
req_state->pwr_domain_state[i++] = state_id &
QTI_LOCAL_PSTATE_MASK;
state_id >>= QTI_LOCAL_PSTATE_WIDTH;
}
return PSCI_E_SUCCESS;
}
/*******************************************************************************
* PLATFORM FUNCTIONS
******************************************************************************/
static void qti_set_cpupwrctlr_val(void)
{
unsigned long val;
val = read_cpu_pwrctrl_val();
val |= QTI_CORE_PWRDN_EN_MASK;
write_cpu_pwrctrl_val(val);
isb();
}
/**
* CPU power on function - ideally we want a wrapper since this function is
* target specific. But to unblock teams.
*/
static int qti_cpu_power_on(u_register_t mpidr)
{
int core_pos = plat_core_pos_by_mpidr(mpidr);
/* If not valid mpidr, return error */
if (core_pos < 0 || core_pos >= QTISECLIB_PLAT_CORE_COUNT) {
return PSCI_E_INVALID_PARAMS;
}
return qtiseclib_psci_node_power_on(mpidr);
}
static bool is_cpu_off(const psci_power_state_t *target_state)
{
if ((target_state->pwr_domain_state[QTI_PWR_LVL0] ==
QTI_LOCAL_STATE_OFF) ||
(target_state->pwr_domain_state[QTI_PWR_LVL0] ==
QTI_LOCAL_STATE_DEEPOFF)) {
return true;
} else {
return false;
}
}
static void qti_cpu_power_on_finish(const psci_power_state_t *target_state)
{
const uint8_t *pwr_states =
(const uint8_t *)target_state->pwr_domain_state;
qtiseclib_psci_node_on_finish(pwr_states);
if (is_cpu_off(target_state)) {
plat_qti_gic_cpuif_enable();
}
}
static void qti_cpu_standby(plat_local_state_t cpu_state)
{
}
static void qti_node_power_off(const psci_power_state_t *target_state)
{
qtiseclib_psci_node_power_off((const uint8_t *)
target_state->pwr_domain_state);
if (is_cpu_off(target_state)) {
plat_qti_gic_cpuif_disable();
qti_set_cpupwrctlr_val();
}
}
static void qti_node_suspend(const psci_power_state_t *target_state)
{
qtiseclib_psci_node_suspend((const uint8_t *)target_state->
pwr_domain_state);
if (is_cpu_off(target_state)) {
plat_qti_gic_cpuif_disable();
qti_set_cpupwrctlr_val();
}
}
static void qti_node_suspend_finish(const psci_power_state_t *target_state)
{
const uint8_t *pwr_states =
(const uint8_t *)target_state->pwr_domain_state;
qtiseclib_psci_node_suspend_finish(pwr_states);
if (is_cpu_off(target_state)) {
plat_qti_gic_cpuif_enable();
}
}
__dead2 void qti_domain_power_down_wfi(const psci_power_state_t *target_state)
{
/* For now just do WFI - add any target specific handling if needed */
psci_power_down_wfi();
/* We should never reach here */
}
__dead2 void qti_system_off(void)
{
qtiseclib_psci_system_off();
}
__dead2 void qti_system_reset(void)
{
qtiseclib_psci_system_reset();
}
void qti_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
int i = 0;
unsigned int state_id, power_state;
int size = ARRAY_SIZE(qti_pm_idle_states);
/*
* Find deepest state.
* The arm_pm_idle_states[] array has last element by default 0,
* so the real deepest state is second last element of that array.
*/
power_state = qti_pm_idle_states[size - 2];
state_id = psci_get_pstate_id(power_state);
/* Parse the State ID and populate the state info parameter */
while (state_id) {
req_state->pwr_domain_state[i++] =
state_id & QTI_LOCAL_PSTATE_MASK;
state_id >>= QTI_LOCAL_PSTATE_WIDTH;
}
}
/*
* Structure containing platform specific PSCI operations. Common
* PSCI layer will use this.
*/
const plat_psci_ops_t plat_qti_psci_pm_ops = {
.pwr_domain_on = qti_cpu_power_on,
.pwr_domain_on_finish = qti_cpu_power_on_finish,
.cpu_standby = qti_cpu_standby,
.pwr_domain_off = qti_node_power_off,
.pwr_domain_suspend = qti_node_suspend,
.pwr_domain_suspend_finish = qti_node_suspend_finish,
.pwr_domain_pwr_down_wfi = qti_domain_power_down_wfi,
.system_off = qti_system_off,
.system_reset = qti_system_reset,
.get_node_hw_state = NULL,
.translate_power_state_by_mpidr = NULL,
.get_sys_suspend_power_state = qti_get_sys_suspend_power_state,
.validate_power_state = qti_validate_power_state,
};
/**
* The QTI Standard platform definition of platform porting API
* `plat_setup_psci_ops`.
*/
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
int err;
err = qtiseclib_psci_init((uintptr_t)bl31_warm_entrypoint);
if (err == PSCI_E_SUCCESS) {
*psci_ops = &plat_qti_psci_pm_ops;
}
return err;
}

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <stdint.h>
#include <platform.h>
#include <platform_def.h>
#include <qtiseclib_interface.h>
u_register_t plat_get_stack_protector_canary(void)
{
u_register_t random = 0x0;
/* get random data , the below API doesn't return random = 0 in success
* case */
qtiseclib_prng_get_data((uint8_t *) &random, sizeof(random));
assert(0x0 != random);
return random;
}

View File

@ -0,0 +1,333 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <context.h>
#include <lib/coreboot.h>
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <smccc_helpers.h>
#include <tools_share/uuid.h>
#include <qti_plat.h>
#include <qti_secure_io_cfg.h>
#include <qtiseclib_interface.h>
/*
* SIP service - SMC function IDs for SiP Service queries
*
*/
#define QTI_SIP_SVC_CALL_COUNT_ID U(0x0200ff00)
#define QTI_SIP_SVC_UID_ID U(0x0200ff01)
/* 0x8200ff02 is reserved */
#define QTI_SIP_SVC_VERSION_ID U(0x0200ff03)
/*
* Syscall's to allow Non Secure world accessing peripheral/IO memory
* those are secure/proteced BUT not required to be secure.
*/
#define QTI_SIP_SVC_SECURE_IO_READ_ID U(0x02000501)
#define QTI_SIP_SVC_SECURE_IO_WRITE_ID U(0x02000502)
/*
* Syscall's to assigns a list of intermediate PAs from a
* source Virtual Machine (VM) to a destination VM.
*/
#define QTI_SIP_SVC_MEM_ASSIGN_ID U(0x02000C16)
#define QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID U(0x1)
#define QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID U(0x2)
#define QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID U(0x1117)
#define QTI_SIP_SVC_CALL_COUNT U(0x3)
#define QTI_SIP_SVC_VERSION_MAJOR U(0x0)
#define QTI_SIP_SVC_VERSION_MINOR U(0x0)
#define QTI_VM_LAST U(44)
#define SIZE4K U(0x1000)
#define QTI_VM_MAX_LIST_SIZE U(0x20)
#define FUNCID_OEN_NUM_MASK ((FUNCID_OEN_MASK << FUNCID_OEN_SHIFT)\
|(FUNCID_NUM_MASK << FUNCID_NUM_SHIFT))
enum {
QTI_SIP_SUCCESS = 0,
QTI_SIP_NOT_SUPPORTED = -1,
QTI_SIP_PREEMPTED = -2,
QTI_SIP_INVALID_PARAM = -3,
};
/* QTI SiP Service UUID */
DEFINE_SVC_UUID2(qti_sip_svc_uid,
0x43864748, 0x217f, 0x41ad, 0xaa, 0x5a,
0xba, 0xe7, 0x0f, 0xa5, 0x52, 0xaf);
static bool qti_is_secure_io_access_allowed(u_register_t addr)
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(qti_secure_io_allowed_regs); i++) {
if ((uintptr_t) addr == qti_secure_io_allowed_regs[i]) {
return true;
}
}
return false;
}
bool qti_mem_assign_validate_param(memprot_info_t *mem_info,
u_register_t u_num_mappings,
uint32_t *source_vm_list,
u_register_t src_vm_list_cnt,
memprot_dst_vm_perm_info_t *dest_vm_list,
u_register_t dst_vm_list_cnt)
{
int i;
if (!source_vm_list || !dest_vm_list || !mem_info
|| (src_vm_list_cnt == 0)
|| (src_vm_list_cnt >= QTI_VM_LAST) || (dst_vm_list_cnt == 0)
|| (dst_vm_list_cnt >= QTI_VM_LAST) || (u_num_mappings == 0)
|| u_num_mappings > QTI_VM_MAX_LIST_SIZE) {
return false;
}
for (i = 0; i < u_num_mappings; i++) {
if ((mem_info[i].mem_addr & (SIZE4K - 1))
|| (mem_info[i].mem_size & (SIZE4K - 1))) {
return false;
}
if ((mem_info[i].mem_addr + mem_info[i].mem_size) <
mem_info[i].mem_addr) {
return false;
}
if (coreboot_get_memory_type(mem_info[i].mem_addr) !=
CB_MEM_RAM) {
return false;
}
if (coreboot_get_memory_type
(mem_info[i].mem_addr + mem_info[i].mem_size) !=
CB_MEM_RAM) {
return false;
}
}
for (i = 0; i < src_vm_list_cnt; i++) {
if (source_vm_list[i] >= QTI_VM_LAST) {
return false;
}
}
for (i = 0; i < dst_vm_list_cnt; i++) {
if (dest_vm_list[i].dst_vm >= QTI_VM_LAST) {
return false;
}
}
return true;
}
static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc,
u_register_t x1,
u_register_t x2,
u_register_t x3, u_register_t x4)
{
uintptr_t dyn_map_start = 0, dyn_map_end = 0;
size_t dyn_map_size = 0;
u_register_t x6, x7;
int ret = QTI_SIP_NOT_SUPPORTED;
u_register_t x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5);
if (smc_cc == SMC_32) {
x5 = (uint32_t) x5;
}
/* Validate input arg count & retrieve arg3-6 from NS Buffer. */
if ((x1 != QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID) || (x5 == 0x0)) {
goto unmap_return;
}
/* Map NS Buffer. */
dyn_map_start = x5;
dyn_map_size =
(smc_cc ==
SMC_32) ? (sizeof(uint32_t) * 4) : (sizeof(uint64_t) * 4);
if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size,
(MT_NS | MT_RO_DATA)) != 0) {
goto unmap_return;
}
/* Retrieve indirect args. */
if (smc_cc == SMC_32) {
x6 = *((uint32_t *) x5 + 1);
x7 = *((uint32_t *) x5 + 2);
x5 = *(uint32_t *) x5;
} else {
x6 = *((uint64_t *) x5 + 1);
x7 = *((uint64_t *) x5 + 2);
x5 = *(uint64_t *) x5;
}
/* Un-Map NS Buffer. */
if (qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size) != 0) {
goto unmap_return;
}
/*
* Map NS Buffers.
* arg0,2,4 points to buffers & arg1,3,5 hold sizes.
* MAP api's fail to map if it's already mapped. Let's
* find lowest start & highest end address, then map once.
*/
dyn_map_start = MIN(x2, x4);
dyn_map_start = MIN(dyn_map_start, x6);
dyn_map_end = MAX((x2 + x3), (x4 + x5));
dyn_map_end = MAX(dyn_map_end, (x6 + x7));
dyn_map_size = dyn_map_end - dyn_map_start;
if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size,
(MT_NS | MT_RO_DATA)) != 0) {
goto unmap_return;
}
memprot_info_t *mem_info_p = (memprot_info_t *) x2;
uint32_t u_num_mappings = x3 / sizeof(memprot_info_t);
uint32_t *source_vm_list_p = (uint32_t *) x4;
uint32_t src_vm_list_cnt = x5 / sizeof(uint32_t);
memprot_dst_vm_perm_info_t *dest_vm_list_p =
(memprot_dst_vm_perm_info_t *) x6;
uint32_t dst_vm_list_cnt =
x7 / sizeof(memprot_dst_vm_perm_info_t);
if (qti_mem_assign_validate_param(mem_info_p, u_num_mappings,
source_vm_list_p, src_vm_list_cnt,
dest_vm_list_p,
dst_vm_list_cnt) != true) {
goto unmap_return;
}
memprot_info_t mem_info[QTI_VM_MAX_LIST_SIZE];
/* Populating the arguments */
for (int i = 0; i < u_num_mappings; i++) {
mem_info[i].mem_addr = mem_info_p[i].mem_addr;
mem_info[i].mem_size = mem_info_p[i].mem_size;
}
memprot_dst_vm_perm_info_t dest_vm_list[QTI_VM_LAST];
for (int i = 0; i < dst_vm_list_cnt; i++) {
dest_vm_list[i].dst_vm = dest_vm_list_p[i].dst_vm;
dest_vm_list[i].dst_vm_perm =
dest_vm_list_p[i].dst_vm_perm;
dest_vm_list[i].ctx = dest_vm_list_p[i].ctx;
dest_vm_list[i].ctx_size = dest_vm_list_p[i].ctx_size;
}
uint32_t source_vm_list[QTI_VM_LAST];
for (int i = 0; i < src_vm_list_cnt; i++) {
source_vm_list[i] = source_vm_list_p[i];
}
/* Un-Map NS Buffers. */
if (qti_mmap_remove_dynamic_region(dyn_map_start,
dyn_map_size) != 0) {
goto unmap_return;
}
/* Invoke API lib api. */
ret = qtiseclib_mem_assign(mem_info, u_num_mappings,
source_vm_list, src_vm_list_cnt,
dest_vm_list, dst_vm_list_cnt);
if (ret == 0) {
SMC_RET2(handle, QTI_SIP_SUCCESS, ret);
}
unmap_return:
/* Un-Map NS Buffers if mapped */
if (dyn_map_start && dyn_map_size) {
qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size);
}
SMC_RET2(handle, QTI_SIP_INVALID_PARAM, ret);
}
/*
* This function handles QTI specific syscalls. Currently only SiP calls are present.
* Both FAST & YIELD type call land here.
*/
static uintptr_t qti_sip_handler(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *cookie, void *handle, u_register_t flags)
{
uint32_t l_smc_fid = smc_fid & FUNCID_OEN_NUM_MASK;
if (GET_SMC_CC(smc_fid) == SMC_32) {
x1 = (uint32_t) x1;
x2 = (uint32_t) x2;
x3 = (uint32_t) x3;
x4 = (uint32_t) x4;
}
switch (l_smc_fid) {
case QTI_SIP_SVC_CALL_COUNT_ID:
{
SMC_RET1(handle, QTI_SIP_SVC_CALL_COUNT);
break;
}
case QTI_SIP_SVC_UID_ID:
{
/* Return UID to the caller */
SMC_UUID_RET(handle, qti_sip_svc_uid);
break;
}
case QTI_SIP_SVC_VERSION_ID:
{
/* Return the version of current implementation */
SMC_RET2(handle, QTI_SIP_SVC_VERSION_MAJOR,
QTI_SIP_SVC_VERSION_MINOR);
break;
}
case QTI_SIP_SVC_SECURE_IO_READ_ID:
{
if ((x1 == QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID) &&
qti_is_secure_io_access_allowed(x2)) {
SMC_RET2(handle, QTI_SIP_SUCCESS,
*((volatile uint32_t *)x2));
}
SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
break;
}
case QTI_SIP_SVC_SECURE_IO_WRITE_ID:
{
if ((x1 == QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID) &&
qti_is_secure_io_access_allowed(x2)) {
*((volatile uint32_t *)x2) = x3;
SMC_RET1(handle, QTI_SIP_SUCCESS);
}
SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
break;
}
case QTI_SIP_SVC_MEM_ASSIGN_ID:
{
return qti_sip_mem_assign(handle, GET_SMC_CC(smc_fid),
x1, x2, x3, x4);
break;
}
default:
{
SMC_RET1(handle, QTI_SIP_NOT_SUPPORTED);
}
}
return (uintptr_t) handle;
}
/* Define a runtime service descriptor for both fast & yield SiP calls */
DECLARE_RT_SVC(qti_sip_fast_svc, OEN_SIP_START,
OEN_SIP_END, SMC_TYPE_FAST, NULL, qti_sip_handler);
DECLARE_RT_SVC(qti_sip_yield_svc, OEN_SIP_START,
OEN_SIP_END, SMC_TYPE_YIELD, NULL, qti_sip_handler);

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <platform_def.h>
#include <qti_plat.h>
/* The QTI power domain tree descriptor */
const unsigned char qti_power_domain_tree_desc[] = {
/* One domain to represent PDC */
PLAT_PDC_COUNT,
/* One domain to represent RSC */
PLAT_RSC_COUNT,
/* There is one top-level FCM cluster */
PLAT_CLUSTER_COUNT,
/* No. of cores in the FCM cluster */
PLAT_CLUSTER0_CORE_COUNT
};
/*******************************************************************************
* This function returns the ARM default topology tree information.
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
return qti_power_domain_tree_desc;
}
/** Function: plat_core_pos_by_mpidr
* 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)
{
int core_linear_index = plat_qti_core_pos_by_mpidr(mpidr);
if (core_linear_index < PLATFORM_CORE_COUNT) {
return core_linear_index;
} else {
return -1;
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTISECLIB_CB_INTERFACE_H
#define QTISECLIB_CB_INTERFACE_H
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <qtiseclib_defs.h>
/* Standard Library API's */
void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len);
#define QTISECLIB_CB_ERROR(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_ERROR, __VA_ARGS__)
#define QTISECLIB_CB_NOTICE(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_NOTICE, __VA_ARGS__)
#define QTISECLIB_CB_WARN(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_WARNING, __VA_ARGS__)
#define QTISECLIB_CB_INFO(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_INFO, __VA_ARGS__)
void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...);
void qtiseclib_cb_spin_lock(qtiseclib_cb_spinlock_t *lock);
void qtiseclib_cb_spin_unlock(qtiseclib_cb_spinlock_t *lock);
unsigned int qtiseclib_cb_plat_my_core_pos(void);
int qtiseclib_cb_plat_core_pos_by_mpidr(u_register_t mpidr);
unsigned int qtiseclib_cb_plat_my_cluster_pos(void);
/* GIC platform wrappers */
void qtiseclib_cb_gic_pcpu_init(void);
void qtiseclib_cb_ic_raise_sgi(int sgi_num, u_register_t target);
void qtiseclib_cb_set_spi_routing(unsigned int id, unsigned int irm,
u_register_t target);
/* Crash reporting api's wrappers */
void qtiseclib_cb_switch_console_to_crash_state(void);
void qtiseclib_cb_udelay(uint32_t usec);
#if QTI_SDI_BUILD
int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa,
size_t size,
qtiseclib_mmap_attr_t attr);
void qtiseclib_cb_flush_dcache_all(void);
void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *ns_ctx);
#endif
#endif /* QTISECLIB_CB_INTERFACE_H */

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTISECLIB_DEFS_H
#define QTISECLIB_DEFS_H
#include <stdint.h>
#ifndef u_register_t
typedef uintptr_t u_register_t;
#endif
/*
* Different Log Level supported in qtiseclib.
* TODO: Currently no filtering done on QTISECLIB logs.
*/
#define QTISECLIB_LOG_LEVEL_NONE 0
#define QTISECLIB_LOG_LEVEL_ERROR 10
#define QTISECLIB_LOG_LEVEL_NOTICE 20
#define QTISECLIB_LOG_LEVEL_WARNING 30
#define QTISECLIB_LOG_LEVEL_INFO 40
#define QTISECLIB_LOG_LEVEL_VERBOSE 50
#define QTI_GICV3_IRM_PE 0
#define QTI_GICV3_IRM_ANY 1
/* Common interrupt number/ID defs. */
#define QTISECLIB_INT_ID_RESET_SGI (0xf)
#define QTISECLIB_INT_ID_CPU_WAKEUP_SGI (0x8)
#define QTISECLIB_INT_INVALID_INT_NUM (0xFFFFFFFFU)
typedef struct qtiseclib_cb_spinlock {
volatile uint32_t lock;
} qtiseclib_cb_spinlock_t;
#if QTI_SDI_BUILD
/* External CPU Dump Structure - 64 bit EL */
typedef struct {
uint64_t x0;
uint64_t x1;
uint64_t x2;
uint64_t x3;
uint64_t x4;
uint64_t x5;
uint64_t x6;
uint64_t x7;
uint64_t x8;
uint64_t x9;
uint64_t x10;
uint64_t x11;
uint64_t x12;
uint64_t x13;
uint64_t x14;
uint64_t x15;
uint64_t x16;
uint64_t x17;
uint64_t x18;
uint64_t x19;
uint64_t x20;
uint64_t x21;
uint64_t x22;
uint64_t x23;
uint64_t x24;
uint64_t x25;
uint64_t x26;
uint64_t x27;
uint64_t x28;
uint64_t x29;
uint64_t x30;
uint64_t pc;
uint64_t currentEL;
uint64_t sp_el3;
uint64_t elr_el3;
uint64_t spsr_el3;
uint64_t sp_el2;
uint64_t elr_el2;
uint64_t spsr_el2;
uint64_t sp_el1;
uint64_t elr_el1;
uint64_t spsr_el1;
uint64_t sp_el0;
uint64_t __reserved1;
uint64_t __reserved2;
uint64_t __reserved3;
uint64_t __reserved4;
uint64_t __reserved5;
uint64_t __reserved6;
uint64_t __reserved7;
uint64_t __reserved8;
} qtiseclib_dbg_a64_ctxt_regs_type;
typedef enum qtiseclib_mmap_attr_s {
QTISECLIB_MAP_NS_RO_XN_DATA = 1,
QTISECLIB_MAP_RW_XN_NC_DATA = 2,
QTISECLIB_MAP_RW_XN_DATA = 3,
} qtiseclib_mmap_attr_t;
#endif /* QTI_SDI_BUILD */
#endif /* QTISECLIB_DEFS_H */

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTISECLIB_INTERFACE_H
#define QTISECLIB_INTERFACE_H
#include <stdbool.h>
#include <stdint.h>
#include <qtiseclib_defs.h>
typedef struct memprot_ipa_info_s {
uint64_t mem_addr;
uint64_t mem_size;
} memprot_info_t;
typedef struct memprot_dst_vm_perm_info_s {
uint32_t dst_vm;
uint32_t dst_vm_perm;
uint64_t ctx;
uint32_t ctx_size;
} memprot_dst_vm_perm_info_t;
/*
* QTISECLIB Published API's.
*/
/*
* Assembly API's
*/
/*
* CPUSS common reset handler for all CPU wake up (both cold & warm boot).
* Executes on all core. This API assume serialization across CPU
* already taken care before invoking.
*
* Clobbers: x0 - x17, x30
*/
void qtiseclib_cpuss_reset_asm(uint32_t bl31_cold_boot_state);
/*
* Execute CPU (Kryo4 gold) specific reset handler / system initialization.
* This takes care of executing required CPU errata's.
*
* Clobbers: x0 - x16
*/
void qtiseclib_kryo4_gold_reset_asm(void);
/*
* Execute CPU (Kryo4 silver) specific reset handler / system initialization.
* This takes care of executing required CPU errata's.
*
* Clobbers: x0 - x16
*/
void qtiseclib_kryo4_silver_reset_asm(void);
/*
* C Api's
*/
void qtiseclib_bl31_platform_setup(void);
void qtiseclib_invoke_isr(uint32_t irq, void *handle);
void qtiseclib_panic(void);
int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len);
int qtiseclib_mem_assign(const memprot_info_t *mem_info,
uint32_t mem_info_list_cnt,
const uint32_t *source_vm_list,
uint32_t src_vm_list_cnt,
const memprot_dst_vm_perm_info_t *dest_vm_list,
uint32_t dst_vm_list_cnt);
int qtiseclib_psci_init(uintptr_t warmboot_entry);
int qtiseclib_psci_node_power_on(u_register_t mpidr);
void qtiseclib_psci_node_on_finish(const uint8_t *states);
void qtiseclib_psci_cpu_standby(uint8_t pwr_state);
void qtiseclib_psci_node_power_off(const uint8_t *states);
void qtiseclib_psci_node_suspend(const uint8_t *states);
void qtiseclib_psci_node_suspend_finish(const uint8_t *states);
__attribute__ ((noreturn))
void qtiseclib_psci_system_off(void);
__attribute__ ((noreturn))
void qtiseclib_psci_system_reset(void);
void qtiseclib_disable_cluster_coherency(uint8_t state);
#endif /* QTISECLIB_INTERFACE_H */

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTISECLIB_DEFS_PLAT_H
#define QTISECLIB_DEFS_PLAT_H
#define QTISECLIB_PLAT_CLUSTER_COUNT 1
#define QTISECLIB_PLAT_CORE_COUNT 8
#define BL31_BASE 0x80b00000
#define BL31_SIZE 0x00100000
/*----------------------------------------------------------------------------*/
/* AOP CMD DB address space for mapping */
/*----------------------------------------------------------------------------*/
#define QTI_AOP_CMD_DB_BASE 0x80820000
#define QTI_AOP_CMD_DB_SIZE 0x00020000
/* Chipset specific secure interrupt number/ID defs. */
#define QTISECLIB_INT_ID_SEC_WDOG_BARK (0x204)
#define QTISECLIB_INT_ID_NON_SEC_WDOG_BITE (0x21)
#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC (0xE6)
#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC (0xE7)
#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC (0xE8)
#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC (0xE9)
#define QTISECLIB_INT_ID_XPU_SEC (0xE3)
#define QTISECLIB_INT_ID_XPU_NON_SEC (0xE4)
#define QTISECLIB_INT_ID_A2_NOC_ERROR (0x194)
#define QTISECLIB_INT_ID_CONFIG_NOC_ERROR (0xE2)
#define QTISECLIB_INT_ID_DC_NOC_ERROR (0x122)
#define QTISECLIB_INT_ID_MEM_NOC_ERROR (0x6C)
#define QTISECLIB_INT_ID_SYSTEM_NOC_ERROR (0xC6)
#define QTISECLIB_INT_ID_MMSS_NOC_ERROR (0xBA)
#endif /* QTISECLIB_DEFS_PLAT_H */

View File

@ -0,0 +1,187 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <arch.h>
#include <arch_helpers.h>
#include <bl31/bl31.h>
#include <context.h>
#include <drivers/arm/gicv3.h>
#include <drivers/delay_timer.h>
#include <lib/coreboot.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/spinlock.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <platform.h>
#include <qti_plat.h>
#include <qtiseclib_cb_interface.h>
void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len)
{
return memcpy(dst, src, len);
}
/* Printing logs below or equal LOG_LEVEL from QTISECLIB. */
void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...)
{
if (loglvl <= LOG_LEVEL) {
va_list argp;
static spinlock_t qti_log_lock;
uint64_t uptime = read_cntpct_el0();
va_start(argp, fmt);
spin_lock(&qti_log_lock);
printf("QTISECLIB [%x%08x]",
(uint32_t) ((uptime >> 32) & 0xFFFFFFFF),
(uint32_t) (uptime & 0xFFFFFFFF));
vprintf(fmt, argp);
putchar('\n');
spin_unlock(&qti_log_lock);
va_end(argp);
}
}
void qtiseclib_cb_spin_lock(qtiseclib_cb_spinlock_t *lock)
{
spin_lock((spinlock_t *) lock);
}
void qtiseclib_cb_spin_unlock(qtiseclib_cb_spinlock_t *lock)
{
spin_unlock((spinlock_t *) lock);
}
unsigned int qtiseclib_cb_plat_my_core_pos(void)
{
return plat_my_core_pos();
}
int qtiseclib_cb_plat_core_pos_by_mpidr(u_register_t mpidr)
{
return plat_core_pos_by_mpidr(mpidr);
}
unsigned int qtiseclib_cb_plat_my_cluster_pos(void)
{
return plat_qti_my_cluster_pos();
}
/* GIC platform functions */
void qtiseclib_cb_gic_pcpu_init(void)
{
plat_qti_gic_pcpu_init();
}
void qtiseclib_cb_ic_raise_sgi(int sgi_num, u_register_t target)
{
plat_ic_raise_el3_sgi(sgi_num, target);
}
void qtiseclib_cb_set_spi_routing(unsigned int id, unsigned int irm,
u_register_t target)
{
assert(QTI_GICV3_IRM_PE == GICV3_IRM_PE);
assert(QTI_GICV3_IRM_ANY == GICV3_IRM_ANY);
gic_set_spi_routing(id, irm, target);
}
/* Crash reporting api's wrappers */
void qtiseclib_cb_switch_console_to_crash_state(void)
{
console_switch_state(CONSOLE_FLAG_CRASH);
}
void qtiseclib_cb_udelay(uint32_t usec)
{
udelay(usec);
}
#if QTI_SDI_BUILD
void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *qti_ns_ctx)
{
void *ctx;
ctx = cm_get_context(NON_SECURE);
qti_ns_ctx->spsr_el3 =
read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3);
qti_ns_ctx->elr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_ELR_EL3);
qti_ns_ctx->spsr_el1 =
read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SPSR_EL1);
qti_ns_ctx->elr_el1 =
read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_ELR_EL1);
qti_ns_ctx->sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SP_EL1);
qti_ns_ctx->x0 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0);
qti_ns_ctx->x1 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1);
qti_ns_ctx->x2 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2);
qti_ns_ctx->x3 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3);
qti_ns_ctx->x4 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X4);
qti_ns_ctx->x5 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X5);
qti_ns_ctx->x6 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X6);
qti_ns_ctx->x7 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X7);
qti_ns_ctx->x8 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X8);
qti_ns_ctx->x9 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X9);
qti_ns_ctx->x10 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X10);
qti_ns_ctx->x11 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X11);
qti_ns_ctx->x12 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X12);
qti_ns_ctx->x13 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X13);
qti_ns_ctx->x14 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X14);
qti_ns_ctx->x15 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X15);
qti_ns_ctx->x16 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X16);
qti_ns_ctx->x17 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X17);
qti_ns_ctx->x18 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X18);
qti_ns_ctx->x19 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X19);
qti_ns_ctx->x20 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X20);
qti_ns_ctx->x21 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X21);
qti_ns_ctx->x22 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X22);
qti_ns_ctx->x23 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X23);
qti_ns_ctx->x24 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X24);
qti_ns_ctx->x25 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X25);
qti_ns_ctx->x26 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X26);
qti_ns_ctx->x27 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X27);
qti_ns_ctx->x28 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X28);
qti_ns_ctx->x29 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X29);
qti_ns_ctx->x30 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_LR);
qti_ns_ctx->sp_el0 =
read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_SP_EL0);
}
void qtiseclib_cb_flush_dcache_all(void)
{
dcsw_op_all(DCCISW);
}
int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa,
size_t size,
qtiseclib_mmap_attr_t attr)
{
unsigned int l_attr = 0;
if (attr == QTISECLIB_MAP_NS_RO_XN_DATA) {
l_attr = MT_NS | MT_RO | MT_EXECUTE_NEVER;
} else if (attr == QTISECLIB_MAP_RW_XN_NC_DATA) {
l_attr = MT_RW | MT_NON_CACHEABLE | MT_EXECUTE_NEVER;
} else if (attr == QTISECLIB_MAP_RW_XN_DATA) {
l_attr = MT_RW | MT_EXECUTE_NEVER;
}
return qti_mmap_add_dynamic_region(base_pa, size, l_attr);
}
int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
{
return qti_mmap_remove_dynamic_region(base_va, size);
}
#endif

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdbool.h>
#include <stdint.h>
#include <common/debug.h>
#include <qtiseclib_defs.h>
#include <qtiseclib_interface.h>
/*
* This file contains dummy implementation of QTISECLIB Published API's.
* which will be used to compile PLATFORM successfully when
* qtiseclib is not available
*/
/*
* CPUSS common reset handler for all CPU wake up (both cold & warm boot).
* Executes on all core. This API assume serialization across CPU
* already taken care before invoking.
*
* Clobbers: x0 - x17, x30
*/
void qtiseclib_cpuss_reset_asm(uint32_t bl31_cold_boot_state)
{
}
/*
* Execute CPU (Kryo4 gold) specific reset handler / system initialization.
* This takes care of executing required CPU errata's.
*
* Clobbers: x0 - x16
*/
void qtiseclib_kryo4_gold_reset_asm(void)
{
}
/*
* Execute CPU (Kryo4 silver) specific reset handler / system initialization.
* This takes care of executing required CPU errata's.
*
* Clobbers: x0 - x16
*/
void qtiseclib_kryo4_silver_reset_asm(void)
{
}
/*
* C Api's
*/
void qtiseclib_bl31_platform_setup(void)
{
ERROR("Please use QTISECLIB_PATH while building TF-A\n");
ERROR("Please refer docs/plat/qti.rst for more details.\n");
panic();
}
void qtiseclib_invoke_isr(uint32_t irq, void *handle)
{
}
void qtiseclib_panic(void)
{
}
int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len)
{
/* fill dummy data to avoid assert and print
* stub implementation in setup call
*/
for (int i = 0; i < out_len; i++) {
out[i] = 0x11;
}
return 0;
}
int
qtiseclib_mem_assign(const memprot_info_t *mem_info,
uint32_t mem_info_list_cnt,
const uint32_t *source_vm_list,
uint32_t src_vm_list_cnt,
const memprot_dst_vm_perm_info_t *dest_vm_list,
uint32_t dst_vm_list_cnt)
{
return 0;
}
int qtiseclib_psci_init(uintptr_t warmboot_entry)
{
return 0;
}
int qtiseclib_psci_node_power_on(u_register_t mpidr)
{
return 0;
}
void qtiseclib_psci_node_on_finish(const uint8_t *states)
{
}
void qtiseclib_psci_cpu_standby(uint8_t pwr_state)
{
}
void qtiseclib_psci_node_power_off(const uint8_t *states)
{
}
void qtiseclib_psci_node_suspend(const uint8_t *states)
{
}
void qtiseclib_psci_node_suspend_finish(const uint8_t *states)
{
}
void qtiseclib_psci_system_off(void)
{
while (1) {
};
}
void qtiseclib_psci_system_reset(void)
{
while (1) {
};
}
void qtiseclib_disable_cluster_coherency(uint8_t state)
{
}

View File

@ -0,0 +1,176 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLATFORM_DEF_H
#define PLATFORM_DEF_H
/* Enable the dynamic translation tables library. */
#define PLAT_XLAT_TABLES_DYNAMIC 1
#include <common_def.h>
#include <qti_board_def.h>
#include <qtiseclib_defs_plat.h>
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*
* MPIDR_PRIMARY_CPU
* You just need to have the correct core_affinity_val i.e. [7:0]
* and cluster_affinity_val i.e. [15:8]
* the other bits will be ignored
*/
/*----------------------------------------------------------------------------*/
#define MPIDR_PRIMARY_CPU 0x0000
/*----------------------------------------------------------------------------*/
#define QTI_PWR_LVL0 MPIDR_AFFLVL0
#define QTI_PWR_LVL1 MPIDR_AFFLVL1
#define QTI_PWR_LVL2 MPIDR_AFFLVL2
#define QTI_PWR_LVL3 MPIDR_AFFLVL3
/*
* Macros for local power states encoded by State-ID field
* within the power-state parameter.
*/
/* Local power state for power domains in Run state. */
#define QTI_LOCAL_STATE_RUN 0
/*
* Local power state for clock-gating. Valid only for CPU and not cluster power
* domains
*/
#define QTI_LOCAL_STATE_STB 1
/*
* Local power state for retention. Valid for CPU and cluster power
* domains
*/
#define QTI_LOCAL_STATE_RET 2
/*
* Local power state for OFF/power down. Valid for CPU, cluster, RSC and PDC
* power domains
*/
#define QTI_LOCAL_STATE_OFF 3
/*
* Local power state for DEEPOFF/power rail down. Valid for CPU, cluster and RSC
* power domains
*/
#define QTI_LOCAL_STATE_DEEPOFF 4
/*
* 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 QTI_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 QTI_LOCAL_STATE_DEEPOFF
/******************************************************************************
* Required platform porting definitions common to all ARM standard platforms
*****************************************************************************/
/*
* Platform specific page table and MMU setup constants.
*/
#define MAX_MMAP_REGIONS (PLAT_QTI_MMAP_ENTRIES)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 36)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 36)
#define ARM_CACHE_WRITEBACK_SHIFT 6
/*
* 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 << ARM_CACHE_WRITEBACK_SHIFT)
/*
* One cache line needed for bakery locks on ARM platforms
*/
#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
/*----------------------------------------------------------------------------*/
/* PSCI power domain topology definitions */
/*----------------------------------------------------------------------------*/
/* One domain each to represent RSC and PDC level */
#define PLAT_PDC_COUNT 1
#define PLAT_RSC_COUNT 1
/* There is one top-level FCM cluster */
#define PLAT_CLUSTER_COUNT 1
/* No. of cores in the FCM cluster */
#define PLAT_CLUSTER0_CORE_COUNT 8
#define PLATFORM_CORE_COUNT (PLAT_CLUSTER0_CORE_COUNT)
#define PLAT_NUM_PWR_DOMAINS (PLAT_PDC_COUNT +\
PLAT_RSC_COUNT +\
PLAT_CLUSTER_COUNT +\
PLATFORM_CORE_COUNT)
#define PLAT_MAX_PWR_LVL 3
/*****************************************************************************/
/* Memory mapped Generic timer interfaces */
/*****************************************************************************/
/*----------------------------------------------------------------------------*/
/* GIC-600 constants */
/*----------------------------------------------------------------------------*/
#define BASE_GICD_BASE 0x17A00000
#define BASE_GICR_BASE 0x17A60000
#define BASE_GICC_BASE 0x0
#define BASE_GICH_BASE 0x0
#define BASE_GICV_BASE 0x0
#define QTI_GICD_BASE BASE_GICD_BASE
#define QTI_GICR_BASE BASE_GICR_BASE
#define QTI_GICC_BASE BASE_GICC_BASE
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* UART related constants. */
/*----------------------------------------------------------------------------*/
/* BASE ADDRESS OF DIFFERENT REGISTER SPACES IN HW */
#define GENI4_CFG 0x0
#define GENI4_IMAGE_REGS 0x100
#define GENI4_DATA 0x600
/* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */
#define GENI_STATUS_REG (GENI4_CFG + 0x00000040)
#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK (0x1)
#define UART_TX_TRANS_LEN_REG (GENI4_IMAGE_REGS + 0x00000170)
/* MASTER/TX ENGINE REGISTERS */
#define GENI_M_CMD0_REG (GENI4_DATA + 0x00000000)
/* FIFO, STATUS REGISTERS AND MASKS */
#define GENI_TX_FIFOn_REG (GENI4_DATA + 0x00000100)
#define GENI_M_CMD_TX (0x08000000)
/*----------------------------------------------------------------------------*/
/* Device address space for mapping. Excluding starting 4K */
/*----------------------------------------------------------------------------*/
#define QTI_DEVICE_BASE 0x1000
#define QTI_DEVICE_SIZE (0x80000000 - QTI_DEVICE_BASE)
/*******************************************************************************
* BL31 specific defines.
******************************************************************************/
/*
* Put BL31 at DDR as per memory map. BL31_BASE is calculated using the
* current BL31 debug size plus a little space for growth.
*/
#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
#endif /* PLATFORM_DEF_H */

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QTI_SECURE_IO_CFG_H
#define QTI_SECURE_IO_CFG_H
#include <stdint.h>
/*
* List of peripheral/IO memory areas that are protected from
* non-secure world but not required to be secure.
*/
#define APPS_SMMU_TBU_PWR_STATUS 0x15002204
#define APPS_SMMU_CUSTOM_CFG 0x15002300
#define APPS_SMMU_STATS_SYNC_INV_TBU_ACK 0x150025DC
#define APPS_SMMU_SAFE_SEC_CFG 0x15002648
#define APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR 0x15002670
static const uintptr_t qti_secure_io_allowed_regs[] = {
APPS_SMMU_TBU_PWR_STATUS,
APPS_SMMU_CUSTOM_CFG,
APPS_SMMU_STATS_SYNC_INV_TBU_ACK,
APPS_SMMU_SAFE_SEC_CFG,
APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR,
};
#endif /* QTI_SECURE_IO_CFG_H */

116
plat/qti/sc7180/platform.mk Normal file
View File

@ -0,0 +1,116 @@
#
# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# Make for SC7180 QTI platform.
QTI_PLAT_PATH := plat/qti
CHIPSET := ${PLAT}
# Turn On Separate code & data.
SEPARATE_CODE_AND_RODATA := 1
USE_COHERENT_MEM := 1
WARMBOOT_ENABLE_DCACHE_EARLY := 1
# Disable the PSCI platform compatibility layer
ENABLE_PLAT_COMPAT := 0
# Enable PSCI v1.0 extended state ID format
PSCI_EXTENDED_STATE_ID := 1
ARM_RECOM_STATE_ID_ENC := 1
COLD_BOOT_SINGLE_CPU := 1
PROGRAMMABLE_RESET_ADDRESS := 1
RESET_TO_BL31 := 0
MULTI_CONSOLE_API := 1
QTI_SDI_BUILD := 0
$(eval $(call assert_boolean,QTI_SDI_BUILD))
$(eval $(call add_define,QTI_SDI_BUILD))
#disable CTX_INCLUDE_AARCH32_REGS to support sc7180 gold cores
override CTX_INCLUDE_AARCH32_REGS := 0
WORKAROUND_CVE_2017_5715 := 0
DYNAMIC_WORKAROUND_CVE_2018_3639 := 1
# Enable stack protector.
ENABLE_STACK_PROTECTOR := strong
QTI_EXTERNAL_INCLUDES := -I${QTI_PLAT_PATH}/${CHIPSET}/inc \
-I${QTI_PLAT_PATH}/common/inc \
-I${QTI_PLAT_PATH}/common/inc/$(ARCH) \
-I${QTI_PLAT_PATH}/qtiseclib/inc \
-I${QTI_PLAT_PATH}/qtiseclib/inc/${CHIPSET} \
QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \
$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_silver.S \
$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_gold.S \
$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S \
$(QTI_PLAT_PATH)/common/src/qti_stack_protector.c \
$(QTI_PLAT_PATH)/common/src/qti_common.c \
$(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c \
$(QTI_PLAT_PATH)/common/src/qti_gic_v3.c \
$(QTI_PLAT_PATH)/common/src/qti_interrupt_svc.c \
$(QTI_PLAT_PATH)/common/src/qti_syscall.c \
$(QTI_PLAT_PATH)/common/src/qti_topology.c \
$(QTI_PLAT_PATH)/common/src/qti_pm.c \
$(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c \
PLAT_INCLUDES := -Iinclude/plat/common/ \
PLAT_INCLUDES += ${QTI_EXTERNAL_INCLUDES}
include lib/xlat_tables_v2/xlat_tables.mk
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \
plat/common/aarch64/crash_console_helpers.S \
common/desc_image_load.c \
lib/bl_aux_params/bl_aux_params.c \
include lib/coreboot/coreboot.mk
#PSCI Sources.
PSCI_SOURCES := plat/common/plat_psci_common.c \
# GIC-600 configuration
GICV3_IMPL := GIC600
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
#Timer sources
TIMER_SOURCES := drivers/delay_timer/generic_delay_timer.c \
drivers/delay_timer/delay_timer.c \
#GIC sources.
GIC_SOURCES := plat/common/plat_gicv3.c \
${GICV3_SOURCES} \
BL31_SOURCES += ${QTI_BL31_SOURCES} \
${PSCI_SOURCES} \
${GIC_SOURCES} \
${TIMER_SOURCES} \
LIB_QTI_PATH := ${QTI_PLAT_PATH}/qtiseclib/lib/${CHIPSET}
# Override this on the command line to point to the qtiseclib library which
# will be available in coreboot.org
QTISECLIB_PATH ?=
ifeq ($(QTISECLIB_PATH),)
# if No lib then use stub implementation for qtiseclib interface
$(warning QTISECLIB_PATH is not provided while building, using stub implementation. \
Please refer docs/plat/qti.rst for more details \
THIS FIRMWARE WILL NOT BOOT!)
BL31_SOURCES += plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
else
# use library provided by QTISECLIB_PATH
LDFLAGS += -L $(dir $(QTISECLIB_PATH))
LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(QTISECLIB_PATH)))
endif