GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
+106
@@ -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__ */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Defines used to retrieve QTI SOC Version
|
||||
*/
|
||||
#define JEDEC_QTI_BKID U(0x0)
|
||||
#define JEDEC_QTI_MFID U(0x70)
|
||||
#define QTI_SOC_CONTINUATION_SHIFT U(24)
|
||||
#define QTI_SOC_IDENTIFICATION_SHIFT U(16)
|
||||
|
||||
/* 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 */
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2021, 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
|
||||
|
||||
/* KRYO-6xx Gold MIDR */
|
||||
#define QTI_KRYO6_GOLD_MIDR 0x412FD410
|
||||
|
||||
/* KRYO-6xx Silver MIDR */
|
||||
#define QTI_KRYO6_SILVER_MIDR 0x412FD050
|
||||
|
||||
#endif /* QTI_CPU_H */
|
||||
+12
@@ -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 */
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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
|
||||
);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
void qti_pmic_prepare_reset(void);
|
||||
void qti_pmic_prepare_shutdown(void);
|
||||
|
||||
typedef struct chip_id_info {
|
||||
uint16_t jtag_id;
|
||||
uint16_t chipinfo_id;
|
||||
} chip_id_info_t;
|
||||
|
||||
#endif /* QTI_PLAT_H */
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef QTI_RNG_H
|
||||
#define QTI_RNG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int qti_rng_get_data(uint8_t *out, uint32_t out_len);
|
||||
|
||||
#endif /* QTI_RNG_H */
|
||||
@@ -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 */
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Google LLC. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SPMI_ARB_H
|
||||
#define SPMI_ARB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* WARNING: This driver does not arbitrate access with the kernel. These APIs
|
||||
* must only be called when the kernel is known to be quiesced (such as before
|
||||
* boot or while the system is shutting down).
|
||||
******************************************************************************/
|
||||
|
||||
/* 32-bit addresses combine (U)SID, PID and register address. */
|
||||
|
||||
int spmi_arb_read8(uint32_t addr);
|
||||
int spmi_arb_write8(uint32_t addr, uint8_t data);
|
||||
|
||||
#endif /* SPMI_ARB_H */
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
/* pass cold boot status. */
|
||||
ldr w0, g_qti_bl31_cold_booted
|
||||
/* Execuete CPUSS boot set up on every core. */
|
||||
bl qtiseclib_cpuss_reset_asm
|
||||
|
||||
ret x18
|
||||
endfunc plat_reset_handler
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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
|
||||
mov x30, x19
|
||||
b cortex_a76_reset_func
|
||||
|
||||
endfunc qti_kryo4_gold_reset_func
|
||||
|
||||
/* -------------------------------------------------------
|
||||
* 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_wa qti_kryo4_gold, QTI_KRYO4_GOLD_MIDR, \
|
||||
qti_kryo4_gold_reset_func, \
|
||||
CPU_NO_EXTRA1_FUNC, \
|
||||
cortex_a76_disable_wa_cve_2018_3639, \
|
||||
cortex_a76_core_pwr_dwn, \
|
||||
qti_kryo4_gold_cluster_pwr_dwn
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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
|
||||
mov x30, x19
|
||||
b cortex_a55_reset_func
|
||||
|
||||
endfunc qti_kryo4_silver_reset_func
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
* 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, \
|
||||
cortex_a55_core_pwr_dwn, \
|
||||
qti_kryo4_silver_cluster_pwr_dwn
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2018-2021, 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_kryo6_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_kryo6_gold_reset_asm
|
||||
mov x30, x19
|
||||
b cortex_a78_reset_func
|
||||
|
||||
endfunc qti_kryo6_gold_reset_func
|
||||
|
||||
/* -------------------------------------------------------
|
||||
* The CPU Ops cluster power down function for Kryo-3 Gold
|
||||
* -------------------------------------------------------
|
||||
*/
|
||||
func qti_kryo6_gold_cluster_pwr_dwn
|
||||
ret
|
||||
endfunc qti_kryo6_gold_cluster_pwr_dwn
|
||||
|
||||
#if REPORT_ERRATA
|
||||
/*
|
||||
* Errata printing function for Kryo4 Gold. Must follow AAPCS.
|
||||
*/
|
||||
func qti_kryo6_gold_errata_report
|
||||
/* TODO : Need to add support. Required only for debug bl31 image.*/
|
||||
ret
|
||||
endfunc qti_kryo6_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_kryo6_gold_regs: /* The ASCII list of register names to be reported */
|
||||
.asciz ""
|
||||
|
||||
func qti_kryo6_gold_cpu_reg_dump
|
||||
adr x6, qti_kryo6_gold_regs
|
||||
ret
|
||||
endfunc qti_kryo6_gold_cpu_reg_dump
|
||||
|
||||
declare_cpu_ops qti_kryo6_gold, QTI_KRYO6_GOLD_MIDR, \
|
||||
qti_kryo6_gold_reset_func, \
|
||||
cortex_a78_core_pwr_dwn, \
|
||||
qti_kryo6_gold_cluster_pwr_dwn
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2018-2021, 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_kryo6_silver_reset_func
|
||||
mov x19, x30
|
||||
|
||||
bl qtiseclib_kryo6_silver_reset_asm
|
||||
mov x30, x19
|
||||
b cortex_a55_reset_func
|
||||
|
||||
endfunc qti_kryo6_silver_reset_func
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
* The CPU Ops cluster power down function for Kryo-3 Silver
|
||||
* ---------------------------------------------------------
|
||||
*/
|
||||
func qti_kryo6_silver_cluster_pwr_dwn
|
||||
ret
|
||||
endfunc qti_kryo6_silver_cluster_pwr_dwn
|
||||
|
||||
#if REPORT_ERRATA
|
||||
/*
|
||||
* Errata printing function for Kryo4 Silver. Must follow AAPCS.
|
||||
*/
|
||||
func qti_kryo6_silver_errata_report
|
||||
/* TODO : Need to add support. Required only for debug bl31 image.*/
|
||||
ret
|
||||
endfunc qti_kryo6_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_kryo6_silver_regs: /* The ASCII list of register names to be reported */
|
||||
.asciz ""
|
||||
|
||||
func qti_kryo6_silver_cpu_reg_dump
|
||||
adr x6, qti_kryo6_silver_regs
|
||||
ret
|
||||
endfunc qti_kryo6_silver_cpu_reg_dump
|
||||
|
||||
|
||||
declare_cpu_ops qti_kryo6_silver, QTI_KRYO6_SILVER_MIDR, \
|
||||
qti_kryo6_silver_reset_func, \
|
||||
cortex_a55_core_pwr_dwn, \
|
||||
qti_kryo6_silver_cluster_pwr_dwn
|
||||
+102
@@ -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
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Google LLC. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <drivers/delay_timer.h>
|
||||
|
||||
#include <qti_plat.h>
|
||||
#include <spmi_arb.h>
|
||||
|
||||
/*
|
||||
* This driver implements PON support for PM8998-compatible PMICs. This can
|
||||
* include other part numbers like PM6150.
|
||||
*/
|
||||
|
||||
#define RESET_TYPE_WARM_RESET 1
|
||||
#define RESET_TYPE_SHUTDOWN 4
|
||||
|
||||
#define S2_RESET_EN BIT(7)
|
||||
|
||||
static void configure_ps_hold(uint32_t reset_type)
|
||||
{
|
||||
/* QTI recommends disabling reset for 10 cycles before reconfiguring. */
|
||||
spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, 0);
|
||||
mdelay(1);
|
||||
|
||||
spmi_arb_write8(PON_PS_HOLD_RESET_CTL, reset_type);
|
||||
spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, S2_RESET_EN);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
void qti_pmic_prepare_reset(void)
|
||||
{
|
||||
configure_ps_hold(RESET_TYPE_WARM_RESET);
|
||||
}
|
||||
|
||||
void qti_pmic_prepare_shutdown(void)
|
||||
{
|
||||
configure_ps_hold(RESET_TYPE_SHUTDOWN);
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*******************************************************************************
|
||||
* 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(
|
||||
BL31_START,
|
||||
BL31_END-BL31_START,
|
||||
BL_CODE_BASE,
|
||||
BL_CODE_END,
|
||||
BL_RO_DATA_BASE,
|
||||
BL_RO_DATA_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;
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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/mmio.h>
|
||||
#include <lib/smccc.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <services/arm_arch_svc.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <qti_map_chipinfo.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
|
||||
)
|
||||
{
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns soc version which mainly consist of below fields
|
||||
*
|
||||
* soc_version[30:24] = JEP-106 continuation code for the SiP
|
||||
* soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
|
||||
* soc_version[0:15] = Implementation defined SoC ID
|
||||
*/
|
||||
int32_t plat_get_soc_version(void)
|
||||
{
|
||||
int i = 0;
|
||||
/* Variant other than in mapped g_map_jtag_chipinfo_id variable will have
|
||||
* default chipinfo id as 0xFFFF
|
||||
*/
|
||||
uint32_t soc_version = (QTI_DEFAULT_CHIPINFO_ID & QTI_SOC_VERSION_MASK);
|
||||
uint32_t jep106az_code = (JEDEC_QTI_BKID << QTI_SOC_CONTINUATION_SHIFT)
|
||||
| (JEDEC_QTI_MFID << QTI_SOC_IDENTIFICATION_SHIFT);
|
||||
uint32_t jtag_id = mmio_read_32(QTI_JTAG_ID_REG);
|
||||
uint32_t jtag_id_val = (jtag_id >> QTI_JTAG_ID_SHIFT)
|
||||
& QTI_SOC_VERSION_MASK;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_map_jtag_chipinfo_id); i++) {
|
||||
if (g_map_jtag_chipinfo_id[i].jtag_id == jtag_id_val)
|
||||
soc_version = g_map_jtag_chipinfo_id[i].chipinfo_id
|
||||
& QTI_SOC_VERSION_MASK;
|
||||
}
|
||||
return (int32_t)(jep106az_code | (soc_version));
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns soc revision in below format
|
||||
*
|
||||
* soc_revision[0:30] = SOC revision of specific SOC
|
||||
*/
|
||||
int32_t plat_get_soc_revision(void)
|
||||
{
|
||||
return mmio_read_32(QTI_SOC_REVISION_REG) & QTI_SOC_REVISION_MASK;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* plat_is_smccc_feature_available() - This function checks whether SMCCC feature
|
||||
* is availabile for the platform or not.
|
||||
* @fid: SMCCC function id
|
||||
*
|
||||
* Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
|
||||
* SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
|
||||
*****************************************************************************/
|
||||
int32_t plat_is_smccc_feature_available(u_register_t fid)
|
||||
{
|
||||
switch (fid) {
|
||||
case SMCCC_ARCH_SOC_ID:
|
||||
return SMC_ARCH_CALL_SUCCESS;
|
||||
default:
|
||||
return SMC_ARCH_CALL_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2018-2021, 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),
|
||||
#ifdef QTISECLIB_INT_ID_LPASS_AGNOC_ERROR
|
||||
INTR_PROP_DESC(QTISECLIB_INT_ID_LPASS_AGNOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
|
||||
INTR_GROUP0,
|
||||
GIC_INTR_CFG_EDGE),
|
||||
#endif
|
||||
#ifdef QTISECLIB_INT_ID_NSP_NOC_ERROR
|
||||
INTR_PROP_DESC(QTISECLIB_INT_ID_NSP_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
|
||||
INTR_GROUP0,
|
||||
GIC_INTR_CFG_EDGE),
|
||||
#endif
|
||||
};
|
||||
|
||||
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());
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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);
|
||||
set_interrupt_rm_flag(flags, SECURE);
|
||||
|
||||
/* Register handler for EL3 interrupts */
|
||||
ret = register_interrupt_type_handler(INTR_TYPE_EL3,
|
||||
qti_el3_interrupt_handler, flags);
|
||||
assert(ret == 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* 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 <drivers/delay_timer.h>
|
||||
#include <lib/mmio.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 */
|
||||
}
|
||||
|
||||
static __dead2 void assert_ps_hold(void)
|
||||
{
|
||||
mmio_write_32(QTI_PS_HOLD_REG, 0);
|
||||
mdelay(1000);
|
||||
|
||||
/* Should be dead before reaching this. */
|
||||
panic();
|
||||
}
|
||||
|
||||
__dead2 void qti_system_off(void)
|
||||
{
|
||||
qti_pmic_prepare_shutdown();
|
||||
assert_ps_hold();
|
||||
}
|
||||
|
||||
__dead2 void qti_system_reset(void)
|
||||
{
|
||||
qti_pmic_prepare_reset();
|
||||
assert_ps_hold();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <stddef.h>
|
||||
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <qti_rng.h>
|
||||
#include <qti_rng_io.h>
|
||||
|
||||
int qti_rng_get_data(uint8_t *out, uint32_t out_len)
|
||||
{
|
||||
uint32_t tmp_rndm = 0;
|
||||
uint32_t bytes_left = out_len;
|
||||
int i = 0;
|
||||
|
||||
if (NULL == out || 0 == out_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* RNG HW initialized at previous boot image.
|
||||
* RNG clocks are expected to be ON.
|
||||
*/
|
||||
|
||||
do {
|
||||
/* There is no data to read */
|
||||
if ((mmio_read_32(SEC_PRNG_STATUS) &
|
||||
SEC_PRNG_STATUS_DATA_AVAIL_BMSK) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((tmp_rndm = mmio_read_32(SEC_PRNG_DATA_OUT)) == 0) {
|
||||
;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
*out = (uint8_t) (tmp_rndm >> (8 * i));
|
||||
|
||||
out++;
|
||||
bytes_left--;
|
||||
|
||||
if (bytes_left == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while (bytes_left != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020, 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 <qti_rng.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 on success
|
||||
*/
|
||||
qti_rng_get_data((uint8_t *) &random, sizeof(random));
|
||||
assert(random != 0x0);
|
||||
|
||||
return random;
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* 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)
|
||||
#define QTI_SIP_SVC_AVAILABLE_ID U(0x02000601)
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
static bool qti_check_syscall_availability(u_register_t smc_fid)
|
||||
{
|
||||
switch (smc_fid) {
|
||||
case QTI_SIP_SVC_CALL_COUNT_ID:
|
||||
case QTI_SIP_SVC_UID_ID:
|
||||
case QTI_SIP_SVC_VERSION_ID:
|
||||
case QTI_SIP_SVC_AVAILABLE_ID:
|
||||
case QTI_SIP_SVC_SECURE_IO_READ_ID:
|
||||
case QTI_SIP_SVC_SECURE_IO_WRITE_ID:
|
||||
case QTI_SIP_SVC_MEM_ASSIGN_ID:
|
||||
return true;
|
||||
default:
|
||||
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) {
|
||||
ERROR("vm count is 0 or more then QTI_VM_LAST or empty list\n");
|
||||
ERROR("source_vm_list %p dest_vm_list %p mem_info %p src_vm_list_cnt %u dst_vm_list_cnt %u u_num_mappings %u\n",
|
||||
source_vm_list, dest_vm_list, mem_info,
|
||||
(unsigned int)src_vm_list_cnt,
|
||||
(unsigned int)dst_vm_list_cnt,
|
||||
(unsigned int)u_num_mappings);
|
||||
return false;
|
||||
}
|
||||
for (i = 0; i < u_num_mappings; i++) {
|
||||
if ((mem_info[i].mem_addr & (SIZE4K - 1))
|
||||
|| (mem_info[i].mem_size == 0)
|
||||
|| (mem_info[i].mem_size & (SIZE4K - 1))) {
|
||||
ERROR("mem_info passed buffer 0x%x or size 0x%x is not 4k aligned\n",
|
||||
(unsigned int)mem_info[i].mem_addr,
|
||||
(unsigned int)mem_info[i].mem_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((mem_info[i].mem_addr + mem_info[i].mem_size) <
|
||||
mem_info[i].mem_addr) {
|
||||
ERROR("overflow in mem_addr 0x%x add mem_size 0x%x\n",
|
||||
(unsigned int)mem_info[i].mem_addr,
|
||||
(unsigned int)mem_info[i].mem_size);
|
||||
return false;
|
||||
}
|
||||
coreboot_memory_t mem_type = coreboot_get_memory_type(
|
||||
mem_info[i].mem_addr,
|
||||
mem_info[i].mem_size);
|
||||
if (mem_type != CB_MEM_RAM && mem_type != CB_MEM_RESERVED) {
|
||||
ERROR("memory region not in CB MEM RAM or RESERVED area: region start 0x%x size 0x%x\n",
|
||||
(unsigned int)mem_info[i].mem_addr,
|
||||
(unsigned int)mem_info[i].mem_size);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < src_vm_list_cnt; i++) {
|
||||
if (source_vm_list[i] >= QTI_VM_LAST) {
|
||||
ERROR("source_vm_list[%d] 0x%x is more then QTI_VM_LAST\n",
|
||||
i, (unsigned int)source_vm_list[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < dst_vm_list_cnt; i++) {
|
||||
if (dest_vm_list[i].dst_vm >= QTI_VM_LAST) {
|
||||
ERROR("dest_vm_list[%d] 0x%x is more then QTI_VM_LAST\n",
|
||||
i, (unsigned int)dest_vm_list[i].dst_vm);
|
||||
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)) {
|
||||
ERROR("invalid mem_assign param id or no mapping info\n");
|
||||
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) {
|
||||
ERROR("map failed for params NS Buffer %x %x\n",
|
||||
(unsigned int)dyn_map_start, (unsigned int)dyn_map_size);
|
||||
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) {
|
||||
ERROR("unmap failed for params NS Buffer %x %x\n",
|
||||
(unsigned int)dyn_map_start, (unsigned int)dyn_map_size);
|
||||
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) {
|
||||
ERROR("map failed for params NS Buffer2 %x %x\n",
|
||||
(unsigned int)dyn_map_start, (unsigned int)dyn_map_size);
|
||||
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) {
|
||||
ERROR("Param validation failed\n");
|
||||
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) {
|
||||
ERROR("unmap failed for params NS Buffer %x %x\n",
|
||||
(unsigned int)dyn_map_start, (unsigned int)dyn_map_size);
|
||||
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_AVAILABLE_ID:
|
||||
{
|
||||
if (x1 != 1) {
|
||||
SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
|
||||
}
|
||||
if (qti_check_syscall_availability(x2) == true) {
|
||||
SMC_RET2(handle, QTI_SIP_SUCCESS, 1);
|
||||
} else {
|
||||
SMC_RET2(handle, QTI_SIP_SUCCESS, 0);
|
||||
}
|
||||
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);
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Google LLC. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <spmi_arb.h>
|
||||
|
||||
#define REG_APID_MAP(apid) (0x0C440900U + sizeof(uint32_t) * apid)
|
||||
#define NUM_APID ((0x1100U - 0x900U) / sizeof(uint32_t))
|
||||
|
||||
#define PPID_MASK (0xfffU << 8)
|
||||
|
||||
#define REG_ARB_CMD(apid) (0x0C600000U + 0x10000U * apid)
|
||||
/* These are opcodes specific to this SPMI arbitrator, *not* SPMI commands. */
|
||||
#define OPC_EXT_WRITEL 0
|
||||
#define OPC_EXT_READL 1
|
||||
|
||||
#define REG_ARB_STATUS(apid) (0x0C600008U + 0x10000U * apid)
|
||||
#define ARB_STATUS_DONE BIT(0)
|
||||
#define ARB_STATUS_FAILURE BIT(1)
|
||||
#define ARB_STATUS_DENIED BIT(2)
|
||||
#define ARB_STATUS_DROPPED BIT(3)
|
||||
|
||||
/* Fake status to report driver errors. */
|
||||
#define ARB_FAKE_STATUS_TIMEOUT BIT(8)
|
||||
|
||||
#define REG_ARB_RDATA0(apid) (0x0C600018U + 0x10000U * apid)
|
||||
#define REG_ARB_WDATA0(apid) (0x0C600010U + 0x10000U * apid)
|
||||
|
||||
static int addr_to_apid(uint32_t addr)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0U; i < NUM_APID; i++) {
|
||||
uint32_t reg = mmio_read_32(REG_APID_MAP(i));
|
||||
if ((reg != 0U) && ((addr & PPID_MASK) == (reg & PPID_MASK))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int wait_for_done(uint16_t apid)
|
||||
{
|
||||
unsigned int timeout = 100;
|
||||
|
||||
while (timeout-- != 0U) {
|
||||
uint32_t status = mmio_read_32(REG_ARB_STATUS(apid));
|
||||
if ((status & ARB_STATUS_DONE) != 0U) {
|
||||
if ((status & ARB_STATUS_FAILURE) != 0U ||
|
||||
(status & ARB_STATUS_DENIED) != 0U ||
|
||||
(status & ARB_STATUS_DROPPED) != 0U) {
|
||||
return status & 0xff;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
mdelay(1);
|
||||
}
|
||||
ERROR("SPMI_ARB timeout!\n");
|
||||
return ARB_FAKE_STATUS_TIMEOUT;
|
||||
}
|
||||
|
||||
static void arb_command(uint16_t apid, uint8_t opcode, uint32_t addr,
|
||||
uint8_t bytes)
|
||||
{
|
||||
mmio_write_32(REG_ARB_CMD(apid), (uint32_t)opcode << 27 |
|
||||
(addr & 0xff) << 4 | (bytes - 1));
|
||||
}
|
||||
|
||||
int spmi_arb_read8(uint32_t addr)
|
||||
{
|
||||
int apid = addr_to_apid(addr);
|
||||
|
||||
if (apid < 0) {
|
||||
return apid;
|
||||
}
|
||||
|
||||
arb_command(apid, OPC_EXT_READL, addr, 1);
|
||||
|
||||
int ret = wait_for_done(apid);
|
||||
if (ret != 0) {
|
||||
ERROR("SPMI_ARB read error [0x%x]: 0x%x\n", addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return mmio_read_32(REG_ARB_RDATA0(apid)) & 0xff;
|
||||
}
|
||||
|
||||
int spmi_arb_write8(uint32_t addr, uint8_t data)
|
||||
{
|
||||
int apid = addr_to_apid(addr);
|
||||
|
||||
if (apid < 0) {
|
||||
return apid;
|
||||
}
|
||||
|
||||
mmio_write_32(REG_ARB_WDATA0(apid), data);
|
||||
arb_command(apid, OPC_EXT_WRITEL, addr, 1);
|
||||
|
||||
int ret = wait_for_done(apid);
|
||||
if (ret != 0) {
|
||||
ERROR("SPMI_ARB write error [0x%x] = 0x%x: 0x%x\n",
|
||||
addr, data, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
|
||||
#include <msm8916_mmap.h>
|
||||
|
||||
#define APCS_TCM_START_ADDR 0x10
|
||||
#define APCS_TCM_REDIRECT_EN_0 BIT_32(0)
|
||||
|
||||
.globl plat_crash_console_init
|
||||
.globl plat_crash_console_putc
|
||||
.globl plat_crash_console_flush
|
||||
.globl plat_panic_handler
|
||||
.globl plat_my_core_pos
|
||||
.globl plat_get_my_entrypoint
|
||||
.globl plat_reset_handler
|
||||
.globl platform_mem_init
|
||||
.globl msm8916_entry_point
|
||||
|
||||
/* -------------------------------------------------
|
||||
* int plat_crash_console_init(void)
|
||||
* Initialize the crash console.
|
||||
* Out: x0 - 1 on success, 0 on error
|
||||
* Clobber list : x0 - x4
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_init
|
||||
mov x1, #BLSP_UART2_BASE
|
||||
|
||||
/*
|
||||
* If the non-secure world has been actively using the UART there might
|
||||
* be still some characters left to be sent in the FIFO. In that case,
|
||||
* resetting the transmitter too early might cause all output to become
|
||||
* corrupted. To avoid that, try to flush (wait until FIFO empty) first.
|
||||
*/
|
||||
mov x4, lr
|
||||
bl console_uartdm_core_flush
|
||||
mov lr, x4
|
||||
|
||||
mov x0, #1
|
||||
b console_uartdm_core_init
|
||||
endfunc plat_crash_console_init
|
||||
|
||||
/* -------------------------------------------------
|
||||
* int plat_crash_console_putc(int c)
|
||||
* Print a character on the crash console.
|
||||
* In : w0 - character to be printed
|
||||
* Out: w0 - printed character on success
|
||||
* Clobber list : x1, x2
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_putc
|
||||
mov x1, #BLSP_UART2_BASE
|
||||
b console_uartdm_core_putc
|
||||
endfunc plat_crash_console_putc
|
||||
|
||||
/* -------------------------------------------------
|
||||
* void plat_crash_console_flush(void)
|
||||
* Force a write of all buffered data that has not
|
||||
* been output.
|
||||
* Clobber list : x1, x2
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_flush
|
||||
mov x1, #BLSP_UART2_BASE
|
||||
b console_uartdm_core_flush
|
||||
endfunc plat_crash_console_flush
|
||||
|
||||
/* -------------------------------------------------
|
||||
* void plat_panic_handler(void) __dead
|
||||
* Called when an unrecoverable error occurs.
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func plat_panic_handler
|
||||
/* Try to shutdown/reset */
|
||||
mov_imm x0, MPM_PS_HOLD
|
||||
str wzr, [x0]
|
||||
1: b 1b
|
||||
endfunc plat_panic_handler
|
||||
|
||||
/* -------------------------------------------------
|
||||
* unsigned int plat_my_core_pos(void)
|
||||
* Out: x0 - index of the calling CPU
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func plat_my_core_pos
|
||||
/* There is just a single cluster so this is very simple */
|
||||
mrs x0, mpidr_el1
|
||||
and x0, x0, #MPIDR_CPU_MASK
|
||||
ret
|
||||
endfunc plat_my_core_pos
|
||||
|
||||
/* -------------------------------------------------
|
||||
* uintptr_t plat_get_my_entrypoint(void)
|
||||
* Distinguish cold and warm boot and return warm boot
|
||||
* entry address if available.
|
||||
* Out: x0 - warm boot entry point or 0 on cold boot
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func plat_get_my_entrypoint
|
||||
ldr x0, msm8916_entry_point
|
||||
ret
|
||||
endfunc plat_get_my_entrypoint
|
||||
|
||||
/* -------------------------------------------------
|
||||
* void plat_reset_handler(void)
|
||||
* Perform additional initialization after reset.
|
||||
* Clobber list : x0 - x18, x30
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func plat_reset_handler
|
||||
/*
|
||||
* Check if the CPU is running at the correct address.
|
||||
* During cold boot the CPU enters here at the wrong address
|
||||
* using the "boot remapper". (It remaps the BL31_BASE to
|
||||
* the CPU reset address 0x0).
|
||||
*/
|
||||
mov x0, #BL31_BASE
|
||||
adr x1, bl31_entrypoint
|
||||
cmp x0, x1
|
||||
b.ne _remapped_cold_boot
|
||||
/* Already running at correct address, just return directly */
|
||||
ret
|
||||
|
||||
_remapped_cold_boot:
|
||||
/*
|
||||
* The previous boot stage seems to use the L2 cache as TCM.
|
||||
* Disable the TCM redirect before enabling caches to avoid
|
||||
* strange crashes.
|
||||
*/
|
||||
mov x2, #APCS_CFG
|
||||
ldr w3, [x2, #APCS_TCM_START_ADDR]
|
||||
and w3, w3, #~APCS_TCM_REDIRECT_EN_0
|
||||
str w3, [x2, #APCS_TCM_START_ADDR]
|
||||
|
||||
/* Enter BL31 again at the real address */
|
||||
br x0
|
||||
endfunc plat_reset_handler
|
||||
|
||||
/* -------------------------------------------------
|
||||
* void platform_mem_init(void)
|
||||
* Performs additional memory initialization early
|
||||
* in the boot process.
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func platform_mem_init
|
||||
/* Nothing to do here, all memory is already initialized */
|
||||
ret
|
||||
endfunc platform_mem_init
|
||||
|
||||
.data
|
||||
.align 3
|
||||
|
||||
/* -------------------------------------------------
|
||||
* Warm boot entry point for CPU. Set by PSCI code.
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
msm8916_entry_point:
|
||||
.quad 0
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* Based on aarch64/skeleton_console.S:
|
||||
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <asm_macros.S>
|
||||
#include <console_macros.S>
|
||||
|
||||
/* UART DM registers */
|
||||
#define UART_DM_DMEN 0x03c /* DMA / data packing */
|
||||
#define UART_DM_SR 0x0a4 /* status register */
|
||||
#define UART_DM_CR 0x0a8 /* command register */
|
||||
#define UART_DM_TF 0x100 /* transmit FIFO */
|
||||
|
||||
#define UART_DM_DMEN_TX_SC BIT_32(4) /* TX single character mode */
|
||||
|
||||
#define UART_DM_SR_TXRDY_BIT 2 /* TX FIFO has space */
|
||||
#define UART_DM_SR_TXEMT_BIT 3 /* TX FIFO is empty */
|
||||
|
||||
#define UART_DM_CR_RESET_RX (U(0x01) << 4) /* reset receiver */
|
||||
#define UART_DM_CR_RESET_TX (U(0x02) << 4) /* reset transmitter */
|
||||
#define UART_DM_CR_TX_ENABLE BIT_32(2) /* enable transmitter */
|
||||
|
||||
.globl console_uartdm_register
|
||||
.globl console_uartdm_core_init
|
||||
.globl console_uartdm_putc
|
||||
.globl console_uartdm_core_putc
|
||||
.globl console_uartdm_flush
|
||||
.globl console_uartdm_core_flush
|
||||
|
||||
/* -----------------------------------------------------------
|
||||
* int console_uartdm_register(console_t *console,
|
||||
* uintptr_t base_addr)
|
||||
* Function to initialize and register the console. The caller
|
||||
* needs to pass an empty console_t structure in which *MUST*
|
||||
* be allocated in persistent memory (e.g. a global or static
|
||||
* local variable, *NOT* on the stack).
|
||||
* In : x0 - pointer to empty console_t structure
|
||||
* x1 - base address
|
||||
* Out: x0 - 1 on success, 0 on error
|
||||
* Clobber list : x0 - x7
|
||||
* -----------------------------------------------------------
|
||||
*/
|
||||
func console_uartdm_register
|
||||
str x1, [x0, #CONSOLE_T_BASE]
|
||||
mov x7, lr
|
||||
bl console_uartdm_core_init
|
||||
mov lr, x7
|
||||
|
||||
/* Register the new console */
|
||||
finish_console_register uartdm putc=1, flush=1
|
||||
endfunc console_uartdm_register
|
||||
|
||||
/* -----------------------------------------------------------
|
||||
* void console_uartdm_core_init(unused, uintptr_t base_addr)
|
||||
* Function to initialize the console.
|
||||
* In : x0 - unused
|
||||
* x1 - base address
|
||||
* Out: void
|
||||
* Clobber list : x1, x2, x3
|
||||
* -----------------------------------------------------------
|
||||
*/
|
||||
func console_uartdm_core_init
|
||||
/* Reset receiver */
|
||||
mov w3, #UART_DM_CR_RESET_RX
|
||||
str w3, [x1, #UART_DM_CR]
|
||||
|
||||
/* Reset transmitter */
|
||||
mov w3, #UART_DM_CR_RESET_TX
|
||||
str w3, [x1, #UART_DM_CR]
|
||||
|
||||
/*
|
||||
* Disable BAM/DMA modes but enable single-character mode for TX.
|
||||
* The single character mode allows simplifying the putc implementation
|
||||
* since characters can be written directly to the FIFO instead of
|
||||
* having to initiate a new transfer and waiting for its completion.
|
||||
*/
|
||||
mov w3, #UART_DM_DMEN_TX_SC
|
||||
str w3, [x1, #UART_DM_DMEN]
|
||||
|
||||
/* Enable transmitter */
|
||||
mov w3, #UART_DM_CR_TX_ENABLE
|
||||
str w3, [x1, #UART_DM_CR]
|
||||
|
||||
ret
|
||||
endfunc console_uartdm_core_init
|
||||
|
||||
/* -----------------------------------------------------------
|
||||
* int console_uartdm_putc(int c, console_t *console)
|
||||
* Function to output a character over the console.
|
||||
* In : w0 - character to be printed
|
||||
* x1 - pointer to console_t struct
|
||||
* Out: w0 - printed character on success, < 0 on error.
|
||||
* Clobber list : x0, x1, x2
|
||||
* -----------------------------------------------------------
|
||||
*/
|
||||
func console_uartdm_putc
|
||||
ldr x1, [x1, #CONSOLE_T_BASE]
|
||||
b console_uartdm_core_putc
|
||||
endfunc console_uartdm_putc
|
||||
|
||||
/* -----------------------------------------------------------
|
||||
* int console_uartdm_core_putc(int c, uintptr_t base_addr)
|
||||
* Function to output a character over the console.
|
||||
* In : w0 - character to be printed
|
||||
* x1 - base address
|
||||
* Out: w0 - printed character on success, < 0 on error.
|
||||
* Clobber list : x2
|
||||
* -----------------------------------------------------------
|
||||
*/
|
||||
func console_uartdm_core_putc
|
||||
1: /* Loop until TX FIFO has space */
|
||||
ldr w2, [x1, #UART_DM_SR]
|
||||
tbz w2, #UART_DM_SR_TXRDY_BIT, 1b
|
||||
|
||||
/* Write character to FIFO */
|
||||
str w0, [x1, #UART_DM_TF]
|
||||
ret
|
||||
endfunc console_uartdm_core_putc
|
||||
|
||||
/* -----------------------------------------------------------
|
||||
* void console_uartdm_flush(console_t *console)
|
||||
* Function to force a write of all buffered data
|
||||
* that has not been output.
|
||||
* In : x0 - pointer to console_t struct
|
||||
* Out: void
|
||||
* Clobber list : x0, x1, x2, x3, x4, x5
|
||||
* -----------------------------------------------------------
|
||||
*/
|
||||
func console_uartdm_flush
|
||||
ldr x1, [x0, #CONSOLE_T_BASE]
|
||||
b console_uartdm_core_flush
|
||||
endfunc console_uartdm_flush
|
||||
|
||||
/* -----------------------------------------------------------
|
||||
* void console_uartdm_core_flush(unused, uintptr_t base_addr)
|
||||
* Function to force a write of all buffered data
|
||||
* that has not been output.
|
||||
* In : x0 - unused
|
||||
* x1 - base address
|
||||
* Out: void
|
||||
* Clobber list : x2
|
||||
* -----------------------------------------------------------
|
||||
*/
|
||||
func console_uartdm_core_flush
|
||||
1: /* Loop until TX FIFO is empty */
|
||||
ldr w2, [x1, #UART_DM_SR]
|
||||
tbz w2, #UART_DM_SR_TXEMT_BIT, 1b
|
||||
ret
|
||||
endfunc console_uartdm_core_flush
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MSM8916_MMAP_H
|
||||
#define MSM8916_MMAP_H
|
||||
|
||||
#define PCNOC_BASE 0x00000000
|
||||
#define PCNOC_SIZE 0x8000000 /* 128 MiB */
|
||||
#define APCS_BASE 0x0b000000
|
||||
#define APCS_SIZE 0x800000 /* 8 MiB */
|
||||
|
||||
#define MPM_BASE (PCNOC_BASE + 0x04a0000)
|
||||
#define MPM_PS_HOLD (MPM_BASE + 0xb000)
|
||||
|
||||
#define TLMM_BASE (PCNOC_BASE + 0x1000000)
|
||||
#define TLMM_GPIO_CFG(n) (TLMM_BASE + ((n) * 0x1000))
|
||||
|
||||
#define GCC_BASE (PCNOC_BASE + 0x1800000)
|
||||
|
||||
#define APPS_SMMU_BASE (PCNOC_BASE + 0x1e00000)
|
||||
#define APPS_SMMU_QCOM (APPS_SMMU_BASE + 0xf0000)
|
||||
|
||||
#define BLSP_UART1_BASE (PCNOC_BASE + 0x78af000)
|
||||
#define BLSP_UART2_BASE (PCNOC_BASE + 0x78b0000)
|
||||
|
||||
#define APCS_QGIC2_BASE (APCS_BASE + 0x00000)
|
||||
#define APCS_QGIC2_GICD (APCS_QGIC2_BASE + 0x0000)
|
||||
#define APCS_QGIC2_GICC (APCS_QGIC2_BASE + 0x2000)
|
||||
#define APCS_BANKED_ACS (APCS_BASE + 0x08000)
|
||||
#define APCS_BANKED_SAW2 (APCS_BASE + 0x09000)
|
||||
#define APCS_CFG (APCS_BASE + 0x10000)
|
||||
#define APCS_GLB (APCS_BASE + 0x11000)
|
||||
#define APCS_L2_SAW2 (APCS_BASE + 0x12000)
|
||||
#define APCS_QTMR (APCS_BASE + 0x20000)
|
||||
#define APCS_ALIAS_ACS(cpu) (APCS_BASE + 0x88000 + ((cpu) * 0x10000))
|
||||
#define APCS_ALIAS_SAW2(cpu) (APCS_BASE + 0x89000 + ((cpu) * 0x10000))
|
||||
|
||||
#endif /* MSM8916_MMAP_H */
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLAT_MACROS_S
|
||||
#define PLAT_MACROS_S
|
||||
|
||||
#include <arm_macros.S>
|
||||
|
||||
#include <msm8916_mmap.h>
|
||||
|
||||
/* ---------------------------------------------
|
||||
* The below required platform porting macro
|
||||
* prints out relevant GIC registers whenever
|
||||
* an unhandled exception is taken in BL31.
|
||||
* Clobbers: x0 - x10, x16, x17, sp
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
.macro plat_crash_print_regs
|
||||
mov_imm x16, APCS_QGIC2_GICD
|
||||
mov_imm x17, APCS_QGIC2_GICC
|
||||
arm_print_gic_regs
|
||||
.endm
|
||||
|
||||
#endif /* PLAT_MACROS_S */
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef PLATFORM_DEF_H
|
||||
#define PLATFORM_DEF_H
|
||||
|
||||
#include <plat/common/common_def.h>
|
||||
|
||||
/*
|
||||
* There is at least 1 MiB available for BL31. However, at the moment the
|
||||
* "msm8916_entry_point" variable in the data section is read through the
|
||||
* 64 KiB region of the "boot remapper" after reset. For simplicity, limit
|
||||
* the end of the data section (BL31_PROGBITS_LIMIT) to 64 KiB for now and
|
||||
* the overall limit to 128 KiB. This could be increased if needed by placing
|
||||
* the "msm8916_entry_point" variable explicitly in the first 64 KiB of BL31.
|
||||
*/
|
||||
#define BL31_LIMIT (BL31_BASE + 0x20000) /* 128 KiB */
|
||||
#define BL31_PROGBITS_LIMIT (BL31_BASE + 0x10000) /* 64 KiB */
|
||||
|
||||
#define CACHE_WRITEBACK_GRANULE U(64)
|
||||
#define PLATFORM_STACK_SIZE U(0x1000)
|
||||
|
||||
/* CPU topology: single cluster with 4 cores */
|
||||
#define PLATFORM_CLUSTER_COUNT U(1)
|
||||
#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
|
||||
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
|
||||
PLATFORM_MAX_CPUS_PER_CLUSTER)
|
||||
|
||||
/* Power management */
|
||||
#define PLATFORM_SYSTEM_COUNT U(1)
|
||||
#define PLAT_NUM_PWR_DOMAINS (PLATFORM_SYSTEM_COUNT + \
|
||||
PLATFORM_CLUSTER_COUNT + \
|
||||
PLATFORM_CORE_COUNT)
|
||||
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
|
||||
#define PLAT_MAX_RET_STATE U(2)
|
||||
#define PLAT_MAX_OFF_STATE U(3)
|
||||
|
||||
/* Translation tables */
|
||||
#define MAX_MMAP_REGIONS 8
|
||||
#define MAX_XLAT_TABLES 4
|
||||
|
||||
#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
|
||||
#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
|
||||
|
||||
/* Timer frequency */
|
||||
#define PLAT_SYSCNT_FREQ 19200000
|
||||
|
||||
/*
|
||||
* The Qualcomm QGIC2 implementation seems to have PIDR0-4 and PIDR4-7
|
||||
* erroneously swapped for some reason. PIDR2 is actually at 0xFD8.
|
||||
* Override the address in <drivers/arm/gicv2.h> to avoid a failing assert().
|
||||
*/
|
||||
#define GICD_PIDR2_GICV2 U(0xFD8)
|
||||
|
||||
#endif /* PLATFORM_DEF_H */
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef UARTDM_CONSOLE_H
|
||||
#define UARTDM_CONSOLE_H
|
||||
|
||||
int console_uartdm_register(console_t *console, uintptr_t base_addr);
|
||||
|
||||
#endif /* UARTDM_CONSOLE_H */
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <arch.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/xlat_tables/xlat_mmu_helpers.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include "msm8916_gicv2.h"
|
||||
#include <msm8916_mmap.h>
|
||||
#include <platform_def.h>
|
||||
#include <uartdm_console.h>
|
||||
|
||||
static const mmap_region_t msm8916_mmap[] = {
|
||||
MAP_REGION_FLAT(PCNOC_BASE, PCNOC_SIZE,
|
||||
MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
|
||||
MAP_REGION_FLAT(APCS_BASE, APCS_SIZE,
|
||||
MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
|
||||
{},
|
||||
};
|
||||
|
||||
static struct {
|
||||
entry_point_info_t bl32;
|
||||
entry_point_info_t bl33;
|
||||
} image_ep_info = {
|
||||
/* BL32 entry point */
|
||||
SET_STATIC_PARAM_HEAD(bl32, PARAM_EP, VERSION_1,
|
||||
entry_point_info_t, SECURE),
|
||||
.bl32.pc = BL32_BASE,
|
||||
|
||||
/* BL33 entry point */
|
||||
SET_STATIC_PARAM_HEAD(bl33, PARAM_EP, VERSION_1,
|
||||
entry_point_info_t, NON_SECURE),
|
||||
.bl33.pc = PRELOADED_BL33_BASE,
|
||||
.bl33.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
|
||||
};
|
||||
|
||||
static console_t console;
|
||||
|
||||
unsigned int plat_get_syscnt_freq2(void)
|
||||
{
|
||||
return PLAT_SYSCNT_FREQ;
|
||||
}
|
||||
|
||||
#define CLK_ENABLE BIT_32(0)
|
||||
#define CLK_OFF BIT_32(31)
|
||||
|
||||
#define GPIO_BLSP_UART2_TX 4
|
||||
#define GPIO_BLSP_UART2_RX 5
|
||||
#define GPIO_CFG_FUNC_BLSP_UART2 (U(0x2) << 2)
|
||||
#define GPIO_CFG_DRV_STRENGTH_16MA (U(0x7) << 6)
|
||||
|
||||
#define GCC_BLSP1_AHB_CBCR (GCC_BASE + 0x01008)
|
||||
#define GCC_BLSP1_UART2_APPS_CBCR (GCC_BASE + 0x0302c)
|
||||
#define GCC_APCS_CLOCK_BRANCH_ENA_VOTE (GCC_BASE + 0x45004)
|
||||
#define BLSP1_AHB_CLK_ENA BIT_32(10)
|
||||
|
||||
/*
|
||||
* The previous boot stage seems to disable most of the UART setup before exit
|
||||
* so it must be enabled here again before the UART console can be used.
|
||||
*/
|
||||
static void msm8916_enable_blsp_uart2(void)
|
||||
{
|
||||
/* Route GPIOs to BLSP UART2 */
|
||||
mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_TX),
|
||||
GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA);
|
||||
mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_RX),
|
||||
GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA);
|
||||
|
||||
/* Enable AHB clock */
|
||||
mmio_setbits_32(GCC_APCS_CLOCK_BRANCH_ENA_VOTE, BLSP1_AHB_CLK_ENA);
|
||||
while (mmio_read_32(GCC_BLSP1_AHB_CBCR) & CLK_OFF)
|
||||
;
|
||||
|
||||
/* Enable BLSP UART2 clock */
|
||||
mmio_setbits_32(GCC_BLSP1_UART2_APPS_CBCR, CLK_ENABLE);
|
||||
while (mmio_read_32(GCC_BLSP1_UART2_APPS_CBCR) & CLK_OFF)
|
||||
;
|
||||
}
|
||||
|
||||
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
||||
u_register_t arg2, u_register_t arg3)
|
||||
{
|
||||
/* Initialize the debug console as early as possible */
|
||||
msm8916_enable_blsp_uart2();
|
||||
console_uartdm_register(&console, BLSP_UART2_BASE);
|
||||
}
|
||||
|
||||
void bl31_plat_arch_setup(void)
|
||||
{
|
||||
mmap_add_region(BL31_BASE, BL31_BASE, BL31_END - BL31_BASE,
|
||||
MT_RW_DATA | MT_SECURE);
|
||||
mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
|
||||
BL_CODE_END - BL_CODE_BASE,
|
||||
MT_CODE | MT_SECURE);
|
||||
mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
|
||||
BL_RO_DATA_END - BL_RO_DATA_BASE,
|
||||
MT_RO_DATA | MT_SECURE);
|
||||
mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
|
||||
BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
|
||||
MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER);
|
||||
|
||||
mmap_add(msm8916_mmap);
|
||||
init_xlat_tables();
|
||||
enable_mmu_el3(0);
|
||||
}
|
||||
|
||||
static void msm8916_configure_timer(void)
|
||||
{
|
||||
/* Set timer frequency */
|
||||
mmio_write_32(APCS_QTMR + CNTCTLBASE_CNTFRQ, plat_get_syscnt_freq2());
|
||||
|
||||
/* Make frame 0 available to non-secure world */
|
||||
mmio_write_32(APCS_QTMR + CNTNSAR, BIT_32(CNTNSAR_NS_SHIFT(0)));
|
||||
mmio_write_32(APCS_QTMR + CNTACR_BASE(0),
|
||||
BIT_32(CNTACR_RPCT_SHIFT) | BIT_32(CNTACR_RVCT_SHIFT) |
|
||||
BIT_32(CNTACR_RFRQ_SHIFT) | BIT_32(CNTACR_RVOFF_SHIFT) |
|
||||
BIT_32(CNTACR_RWVT_SHIFT) | BIT_32(CNTACR_RWPT_SHIFT));
|
||||
}
|
||||
|
||||
/*
|
||||
* The APCS register regions always start with a SECURE register that should
|
||||
* be cleared to 0 to only allow secure access. Since BL31 handles most of
|
||||
* the CPU power management, most of them can be cleared to secure access only.
|
||||
*/
|
||||
#define APCS_GLB_SECURE_STS_NS BIT_32(0)
|
||||
#define APCS_GLB_SECURE_PWR_NS BIT_32(1)
|
||||
#define APCS_BOOT_START_ADDR_SEC (APCS_CFG + 0x04)
|
||||
#define REMAP_EN BIT_32(0)
|
||||
#define APCS_AA64NAA32_REG (APCS_CFG + 0x0c)
|
||||
|
||||
static void msm8916_configure_cpu_pm(void)
|
||||
{
|
||||
unsigned int cpu;
|
||||
|
||||
/* Disallow non-secure access to boot remapper / TCM registers */
|
||||
mmio_write_32(APCS_CFG, 0);
|
||||
|
||||
/*
|
||||
* Disallow non-secure access to power management registers.
|
||||
* However, allow STS and PWR since those also seem to control access
|
||||
* to CPU frequency related registers (e.g. APCS_CMD_RCGR). If these
|
||||
* bits are not set, CPU frequency control fails in the non-secure world.
|
||||
*/
|
||||
mmio_write_32(APCS_GLB, APCS_GLB_SECURE_STS_NS | APCS_GLB_SECURE_PWR_NS);
|
||||
|
||||
/* Disallow non-secure access to L2 SAW2 */
|
||||
mmio_write_32(APCS_L2_SAW2, 0);
|
||||
|
||||
/* Disallow non-secure access to CPU ACS and SAW2 */
|
||||
for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
|
||||
mmio_write_32(APCS_ALIAS_ACS(cpu), 0);
|
||||
mmio_write_32(APCS_ALIAS_SAW2(cpu), 0);
|
||||
}
|
||||
|
||||
/* Make sure all further warm boots end up in BL31 and aarch64 state */
|
||||
CASSERT((BL31_BASE & 0xffff) == 0, assert_bl31_base_64k_aligned);
|
||||
mmio_write_32(APCS_BOOT_START_ADDR_SEC, BL31_BASE | REMAP_EN);
|
||||
mmio_write_32(APCS_AA64NAA32_REG, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* MSM8916 has a special "interrupt aggregation logic" in the APPS SMMU,
|
||||
* which allows routing context bank interrupts to one of 3 interrupt numbers
|
||||
* ("TZ/HYP/NS"). Route all interrupts to the non-secure interrupt number
|
||||
* by default to avoid special setup on the non-secure side.
|
||||
*/
|
||||
#define GCC_SMMU_CFG_CBCR (GCC_BASE + 0x12038)
|
||||
#define GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE (GCC_BASE + 0x4500c)
|
||||
#define SMMU_CFG_CLK_ENA BIT_32(12)
|
||||
#define APPS_SMMU_INTR_SEL_NS (APPS_SMMU_QCOM + 0x2000)
|
||||
#define APPS_SMMU_INTR_SEL_NS_EN_ALL U(0xffffffff)
|
||||
|
||||
static void msm8916_configure_smmu(void)
|
||||
{
|
||||
/* Enable SMMU configuration clock to enable register access */
|
||||
mmio_setbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
|
||||
while (mmio_read_32(GCC_SMMU_CFG_CBCR) & CLK_OFF)
|
||||
;
|
||||
|
||||
/* Route all context bank interrupts to non-secure interrupt */
|
||||
mmio_write_32(APPS_SMMU_INTR_SEL_NS, APPS_SMMU_INTR_SEL_NS_EN_ALL);
|
||||
|
||||
/* Disable configuration clock again */
|
||||
mmio_clrbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
|
||||
}
|
||||
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
INFO("BL31: Platform setup start\n");
|
||||
generic_delay_timer_init();
|
||||
msm8916_configure_timer();
|
||||
msm8916_gicv2_init();
|
||||
msm8916_configure_cpu_pm();
|
||||
msm8916_configure_smmu();
|
||||
INFO("BL31: Platform setup done\n");
|
||||
}
|
||||
|
||||
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case SECURE:
|
||||
return &image_ep_info.bl32;
|
||||
case NON_SECURE:
|
||||
return &image_ep_info.bl33;
|
||||
default:
|
||||
assert(sec_state_is_valid(type));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <msm8916_mmap.h>
|
||||
#include "msm8916_pm.h"
|
||||
|
||||
#define CPU_PWR_CTL 0x4
|
||||
#define APC_PWR_GATE_CTL 0x14
|
||||
|
||||
#define CPU_PWR_CTL_CLAMP BIT_32(0)
|
||||
#define CPU_PWR_CTL_CORE_MEM_CLAMP BIT_32(1)
|
||||
#define CPU_PWR_CTL_L1_RST_DIS BIT_32(2)
|
||||
#define CPU_PWR_CTL_CORE_MEM_HS BIT_32(3)
|
||||
#define CPU_PWR_CTL_CORE_RST BIT_32(4)
|
||||
#define CPU_PWR_CTL_COREPOR_RST BIT_32(5)
|
||||
#define CPU_PWR_CTL_GATE_CLK BIT_32(6)
|
||||
#define CPU_PWR_CTL_CORE_PWRD_UP BIT_32(7)
|
||||
|
||||
#define APC_PWR_GATE_CTL_GHDS_EN BIT_32(0)
|
||||
#define APC_PWR_GATE_CTL_GHDS_CNT(cnt) ((cnt) << 24)
|
||||
|
||||
/* Boot a secondary CPU core for the first time. */
|
||||
void msm8916_cpu_boot(unsigned int core)
|
||||
{
|
||||
uintptr_t acs = APCS_ALIAS_ACS(core);
|
||||
uint32_t pwr_ctl;
|
||||
|
||||
pwr_ctl = CPU_PWR_CTL_CLAMP | CPU_PWR_CTL_CORE_MEM_CLAMP |
|
||||
CPU_PWR_CTL_CORE_RST | CPU_PWR_CTL_COREPOR_RST;
|
||||
mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl);
|
||||
dsb();
|
||||
|
||||
mmio_write_32(acs + APC_PWR_GATE_CTL, APC_PWR_GATE_CTL_GHDS_EN |
|
||||
APC_PWR_GATE_CTL_GHDS_CNT(16));
|
||||
dsb();
|
||||
udelay(2);
|
||||
|
||||
pwr_ctl &= ~CPU_PWR_CTL_CORE_MEM_CLAMP;
|
||||
mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl);
|
||||
dsb();
|
||||
|
||||
pwr_ctl |= CPU_PWR_CTL_CORE_MEM_HS;
|
||||
mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl);
|
||||
dsb();
|
||||
udelay(2);
|
||||
|
||||
pwr_ctl &= ~CPU_PWR_CTL_CLAMP;
|
||||
mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl);
|
||||
dsb();
|
||||
udelay(2);
|
||||
|
||||
pwr_ctl &= ~(CPU_PWR_CTL_CORE_RST | CPU_PWR_CTL_COREPOR_RST);
|
||||
mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl);
|
||||
dsb();
|
||||
|
||||
pwr_ctl |= CPU_PWR_CTL_CORE_PWRD_UP;
|
||||
mmio_write_32(acs + CPU_PWR_CTL, pwr_ctl);
|
||||
dsb();
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/arm/gicv2.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include "msm8916_gicv2.h"
|
||||
#include <msm8916_mmap.h>
|
||||
|
||||
#define IRQ_SEC_SGI_0 8
|
||||
#define IRQ_SEC_SGI_1 9
|
||||
#define IRQ_SEC_SGI_2 10
|
||||
#define IRQ_SEC_SGI_3 11
|
||||
#define IRQ_SEC_SGI_4 12
|
||||
#define IRQ_SEC_SGI_5 13
|
||||
#define IRQ_SEC_SGI_6 14
|
||||
#define IRQ_SEC_SGI_7 15
|
||||
|
||||
#define IRQ_SEC_PHY_TIMER (16 + 2) /* PPI #2 */
|
||||
|
||||
static const interrupt_prop_t msm8916_interrupt_props[] = {
|
||||
INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
|
||||
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
|
||||
INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,
|
||||
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
|
||||
INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,
|
||||
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
|
||||
INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,
|
||||
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
|
||||
INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,
|
||||
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
|
||||
INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,
|
||||
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
|
||||
INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,
|
||||
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
|
||||
INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,
|
||||
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
|
||||
INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,
|
||||
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
|
||||
};
|
||||
|
||||
static const gicv2_driver_data_t msm8916_gic_data = {
|
||||
.gicd_base = APCS_QGIC2_GICD,
|
||||
.gicc_base = APCS_QGIC2_GICC,
|
||||
.interrupt_props = msm8916_interrupt_props,
|
||||
.interrupt_props_num = ARRAY_SIZE(msm8916_interrupt_props),
|
||||
};
|
||||
|
||||
void msm8916_gicv2_init(void)
|
||||
{
|
||||
gicv2_driver_init(&msm8916_gic_data);
|
||||
gicv2_distif_init();
|
||||
gicv2_pcpu_distif_init();
|
||||
gicv2_cpuif_enable();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MSM8916_GICV2_H
|
||||
#define MSM8916_GICV2_H
|
||||
|
||||
void msm8916_gicv2_init(void);
|
||||
|
||||
#endif /* MSM8916_GICV2_H */
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/arm/gicv2.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/psci/psci.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include <msm8916_mmap.h>
|
||||
#include "msm8916_pm.h"
|
||||
|
||||
static int msm8916_pwr_domain_on(u_register_t mpidr)
|
||||
{
|
||||
unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
|
||||
|
||||
VERBOSE("PSCI: Booting CPU %d\n", core);
|
||||
msm8916_cpu_boot(core);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
static void msm8916_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
gicv2_pcpu_distif_init();
|
||||
gicv2_cpuif_enable();
|
||||
}
|
||||
|
||||
static void __dead2 msm8916_system_reset(void)
|
||||
{
|
||||
mmio_write_32(MPM_PS_HOLD, 0);
|
||||
mdelay(1000);
|
||||
|
||||
ERROR("PSCI: System reset failed\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
static const plat_psci_ops_t msm8916_psci_ops = {
|
||||
.pwr_domain_on = msm8916_pwr_domain_on,
|
||||
.pwr_domain_on_finish = msm8916_pwr_domain_on_finish,
|
||||
.system_off = msm8916_system_reset,
|
||||
.system_reset = msm8916_system_reset,
|
||||
};
|
||||
|
||||
/* Defined and used in msm8916_helpers.S */
|
||||
extern uintptr_t msm8916_entry_point;
|
||||
|
||||
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||
const plat_psci_ops_t **psci_ops)
|
||||
{
|
||||
msm8916_entry_point = sec_entrypoint;
|
||||
*psci_ops = &msm8916_psci_ops;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MSM8916_PM_H
|
||||
#define MSM8916_PM_H
|
||||
|
||||
void msm8916_cpu_boot(unsigned int core);
|
||||
|
||||
#endif /* MSM8916_PM_H */
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
static const unsigned char plat_power_domain_tree_desc[PLAT_MAX_PWR_LVL + 1] = {
|
||||
PLATFORM_SYSTEM_COUNT,
|
||||
PLATFORM_CLUSTER_COUNT,
|
||||
PLATFORM_MAX_CPUS_PER_CLUSTER,
|
||||
};
|
||||
|
||||
int plat_core_pos_by_mpidr(u_register_t mpidr)
|
||||
{
|
||||
unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
|
||||
|
||||
if (MPIDR_AFFLVL3_VAL(mpidr) > 0 ||
|
||||
MPIDR_AFFLVL2_VAL(mpidr) > 0 ||
|
||||
MPIDR_AFFLVL1_VAL(mpidr) > 0 ||
|
||||
core >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return core;
|
||||
}
|
||||
|
||||
const unsigned char *plat_get_power_domain_tree_desc(void)
|
||||
{
|
||||
return plat_power_domain_tree_desc;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#
|
||||
# Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
include drivers/arm/gic/v2/gicv2.mk
|
||||
include lib/xlat_tables_v2/xlat_tables.mk
|
||||
|
||||
PLAT_BL_COMMON_SOURCES := ${XLAT_TABLES_LIB_SRCS}
|
||||
|
||||
PLAT_INCLUDES := -Iinclude/plat/arm/common/${ARCH} \
|
||||
-Iplat/qti/msm8916/include
|
||||
|
||||
BL31_SOURCES += ${GICV2_SOURCES} \
|
||||
drivers/delay_timer/delay_timer.c \
|
||||
drivers/delay_timer/generic_delay_timer.c \
|
||||
lib/cpus/${ARCH}/cortex_a53.S \
|
||||
plat/common/plat_gicv2.c \
|
||||
plat/common/plat_psci_common.c \
|
||||
plat/qti/msm8916/msm8916_bl31_setup.c \
|
||||
plat/qti/msm8916/msm8916_cpu_boot.c \
|
||||
plat/qti/msm8916/msm8916_gicv2.c \
|
||||
plat/qti/msm8916/msm8916_pm.c \
|
||||
plat/qti/msm8916/msm8916_topology.c \
|
||||
plat/qti/msm8916/${ARCH}/msm8916_helpers.S \
|
||||
plat/qti/msm8916/${ARCH}/uartdm_console.S
|
||||
|
||||
# Only BL31 is supported at the moment and is entered on a single CPU
|
||||
RESET_TO_BL31 := 1
|
||||
COLD_BOOT_SINGLE_CPU := 1
|
||||
|
||||
# Build config flags
|
||||
# ------------------
|
||||
BL31_BASE ?= 0x86500000
|
||||
BL32_BASE ?= 0x86000000
|
||||
PRELOADED_BL33_BASE ?= 0x8f600000
|
||||
|
||||
# Have different sections for code and rodata
|
||||
SEPARATE_CODE_AND_RODATA := 1
|
||||
|
||||
# Single cluster
|
||||
WARMBOOT_ENABLE_DCACHE_EARLY := 1
|
||||
|
||||
# Disable features unsupported in ARMv8.0
|
||||
ENABLE_AMU := 0
|
||||
ENABLE_SPE_FOR_LOWER_ELS := 0
|
||||
ENABLE_SVE_FOR_NS := 0
|
||||
|
||||
# MSM8916 uses ARM Cortex-A53 r0p0 so likely all the errata apply
|
||||
ERRATA_A53_819472 := 1
|
||||
ERRATA_A53_824069 := 1
|
||||
ERRATA_A53_826319 := 1
|
||||
ERRATA_A53_827319 := 1
|
||||
ERRATA_A53_835769 := 1
|
||||
ERRATA_A53_836870 := 1
|
||||
ERRATA_A53_843419 := 1
|
||||
ERRATA_A53_855873 := 0 # Workaround works only for >= r0p3
|
||||
ERRATA_A53_1530924 := 1
|
||||
|
||||
$(eval $(call add_define,BL31_BASE))
|
||||
$(eval $(call add_define,BL32_BASE))
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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);
|
||||
int qtiseclib_cb_strcmp(const char *s1, const char *s2);
|
||||
void *qtiseclib_cb_memset(void *s, int c, size_t n);
|
||||
void *qtiseclib_cb_memmove(void *dest, const void *src, size_t n);
|
||||
|
||||
#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);
|
||||
|
||||
void qtiseclib_cb_console_flush(void);
|
||||
|
||||
#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 */
|
||||
+104
@@ -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 */
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2021, 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 (Kryo46 gold) specific reset handler / system initialization.
|
||||
* This takes care of executing required CPU errata's.
|
||||
*
|
||||
* Clobbers: x0 - x16
|
||||
*/
|
||||
void qtiseclib_kryo6_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);
|
||||
|
||||
/*
|
||||
* Execute CPU (Kryo6 silver) specific reset handler / system initialization.
|
||||
* This takes care of executing required CPU errata's.
|
||||
*
|
||||
* Clobbers: x0 - x16
|
||||
*/
|
||||
void qtiseclib_kryo6_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_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);
|
||||
void qtiseclib_disable_cluster_coherency(uint8_t state);
|
||||
|
||||
#endif /* QTISECLIB_INTERFACE_H */
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
/* 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 */
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2021, 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 0xC0000000
|
||||
#define BL31_SIZE 0x00100000
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* AOP CMD DB address space for mapping */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define QTI_AOP_CMD_DB_BASE 0x80860000
|
||||
#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)
|
||||
|
||||
//NOC INterrupt
|
||||
#define QTISECLIB_INT_ID_A1_NOC_ERROR (0xC9)
|
||||
#define QTISECLIB_INT_ID_A2_NOC_ERROR (0xEA)
|
||||
#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 (0xC8)
|
||||
#define QTISECLIB_INT_ID_MMSS_NOC_ERROR (0xBA)
|
||||
#define QTISECLIB_INT_ID_LPASS_AGNOC_ERROR (0x143)
|
||||
#define QTISECLIB_INT_ID_NSP_NOC_ERROR (0x1CE)
|
||||
|
||||
#endif /* __QTISECLIB_DEFS_PLAT_H__ */
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
int qtiseclib_cb_strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
return strcmp(s1, s2);
|
||||
}
|
||||
|
||||
void *qtiseclib_cb_memset(void *s, int c, size_t n)
|
||||
{
|
||||
return memset(s, c, n);
|
||||
}
|
||||
|
||||
void *qtiseclib_cb_memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
return memmove(dest, src, n);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
void qtiseclib_cb_console_flush(void)
|
||||
{
|
||||
return console_flush();
|
||||
}
|
||||
|
||||
#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);
|
||||
if (ctx) {
|
||||
/* nothing to be done w/o ns context */
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute CPU (Kryo4 gold) specific reset handler / system initialization.
|
||||
* This takes care of executing required CPU errata's.
|
||||
*
|
||||
* Clobbers: x0 - x16
|
||||
*/
|
||||
void qtiseclib_kryo6_gold_reset_asm(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void qtiseclib_kryo6_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_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_disable_cluster_coherency(uint8_t state)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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)
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* AOSS registers */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define QTI_PS_HOLD_REG 0x0C264000
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* AOP CMD DB address space for mapping */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define QTI_AOP_CMD_DB_BASE 0x80820000
|
||||
#define QTI_AOP_CMD_DB_SIZE 0x00020000
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* SOC hw version register */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define QTI_SOC_VERSION_MASK U(0xFFFF)
|
||||
#define QTI_SOC_REVISION_REG 0x1FC8000
|
||||
#define QTI_SOC_REVISION_MASK U(0xFFFF)
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* LC PON register offsets */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define PON_PS_HOLD_RESET_CTL 0x85a
|
||||
#define PON_PS_HOLD_RESET_CTL2 0x85b
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* PLATFORM_DEF_H */
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef QTI_MAP_CHIPINFO_H
|
||||
#define QTI_MAP_CHIPINFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <qti_plat.h>
|
||||
|
||||
#define QTI_JTAG_ID_REG 0x786130
|
||||
#define QTI_SOC_VERSION_MASK U(0xFFFF)
|
||||
#define QTI_SOC_REVISION_REG 0x1FC8000
|
||||
#define QTI_SOC_REVISION_MASK U(0xFFFF)
|
||||
#define QTI_JTAG_ID_SHIFT 12
|
||||
#define QTI_JTAG_ID_SC7180 U(0x012C)
|
||||
#define QTI_JTAG_ID_SC7180P U(0x0195)
|
||||
#define QTI_CHIPINFO_ID_SC7180 U(0x01A9)
|
||||
#define QTI_CHIPINFO_ID_SC7180P U(0x01EF)
|
||||
#define QTI_DEFAULT_CHIPINFO_ID U(0xFFFF)
|
||||
|
||||
static const chip_id_info_t g_map_jtag_chipinfo_id[] = {
|
||||
{QTI_JTAG_ID_SC7180, QTI_CHIPINFO_ID_SC7180},
|
||||
{QTI_JTAG_ID_SC7180P, QTI_CHIPINFO_ID_SC7180P},
|
||||
};
|
||||
#endif /* QTI_MAP_CHIPINFO_H */
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef QTI_RNG_IO_H
|
||||
#define QTI_RNG_IO_H
|
||||
|
||||
#define SEC_PRNG_STATUS 0x00791004
|
||||
#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK 0x1
|
||||
#define SEC_PRNG_DATA_OUT 0x00791000
|
||||
|
||||
|
||||
#endif /* QTI_RNG_IO_H */
|
||||
|
||||
+30
@@ -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 */
|
||||
@@ -0,0 +1,128 @@
|
||||
#
|
||||
# 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 := 0
|
||||
WARMBOOT_ENABLE_DCACHE_EARLY := 1
|
||||
HW_ASSISTED_COHERENCY := 1
|
||||
|
||||
# Disable the PSCI platform compatibility layer
|
||||
ENABLE_PLAT_COMPAT := 0
|
||||
|
||||
#Enable errata for cortex_a55 and cortex_a76
|
||||
ERRATA_A55_1530923 := 1
|
||||
ERRATA_A76_1165522 := 1
|
||||
|
||||
# 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/pm_ps_hold.c \
|
||||
$(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)/common/src/qti_rng.c \
|
||||
$(QTI_PLAT_PATH)/common/src/spmi_arb.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_SUPPORT_GIC600 := 1
|
||||
# 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} \
|
||||
|
||||
CPU_SOURCES := lib/cpus/aarch64/cortex_a76.S \
|
||||
lib/cpus/aarch64/cortex_a55.S \
|
||||
|
||||
BL31_SOURCES += ${QTI_BL31_SOURCES} \
|
||||
${PSCI_SOURCES} \
|
||||
${GIC_SOURCES} \
|
||||
${TIMER_SOURCES} \
|
||||
${CPU_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
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2018-2021, 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)
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* AOSS registers */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define QTI_PS_HOLD_REG 0x0C264000
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* AOP CMD DB address space for mapping */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define QTI_AOP_CMD_DB_BASE 0x80860000
|
||||
#define QTI_AOP_CMD_DB_SIZE 0x00020000
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* SOC hw version register */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define QTI_SOC_VERSION_MASK U(0xFFFF)
|
||||
#define QTI_SOC_REVISION_REG 0x1FC8000
|
||||
#define QTI_SOC_REVISION_MASK U(0xFFFF)
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* LC PON register offsets */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define PON_PS_HOLD_RESET_CTL 0x852
|
||||
#define PON_PS_HOLD_RESET_CTL2 0x853
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* PLATFORM_DEF_H */
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef QTI_MAP_CHIPINFO_H
|
||||
#define QTI_MAP_CHIPINFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <qti_plat.h>
|
||||
|
||||
#define QTI_JTAG_ID_REG 0x786130
|
||||
#define QTI_JTAG_ID_SHIFT 12
|
||||
#define QTI_JTAG_ID_SC7280 U(0x0193)
|
||||
#define QTI_JTAG_ID_SC7280P U(0x01EB)
|
||||
#define QTI_JTAG_ID_SC8270 U(0x01E3)
|
||||
#define QTI_JTAG_ID_SC8270P U(0x020A)
|
||||
#define QTI_JTAG_ID_SC7270P U(0x0215)
|
||||
#define QTI_CHIPINFO_ID_SC7280 U(0x01E7)
|
||||
#define QTI_CHIPINFO_ID_SC7280P U(0x0222)
|
||||
#define QTI_CHIPINFO_ID_SC8270 U(0x0229)
|
||||
#define QTI_CHIPINFO_ID_SC8270P U(0x0233)
|
||||
#define QTI_CHIPINFO_ID_SC7270P U(0x0237)
|
||||
#define QTI_DEFAULT_CHIPINFO_ID U(0xFFFF)
|
||||
|
||||
static const chip_id_info_t g_map_jtag_chipinfo_id[] = {
|
||||
{QTI_JTAG_ID_SC7280, QTI_CHIPINFO_ID_SC7280},
|
||||
{QTI_JTAG_ID_SC7280P, QTI_CHIPINFO_ID_SC7280P},
|
||||
{QTI_JTAG_ID_SC8270, QTI_CHIPINFO_ID_SC8270},
|
||||
{QTI_JTAG_ID_SC8270P, QTI_CHIPINFO_ID_SC8270P},
|
||||
{QTI_JTAG_ID_SC7270P, QTI_CHIPINFO_ID_SC7270P},
|
||||
};
|
||||
#endif /* QTI_MAP_CHIPINFO_H */
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef QTI_RNG_IO_H
|
||||
#define QTI_RNG_IO_H
|
||||
|
||||
#define SEC_PRNG_STATUS 0x10D1004
|
||||
#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK 0x1
|
||||
#define SEC_PRNG_DATA_OUT 0x10D1000
|
||||
|
||||
|
||||
#endif /* QTI_RNG_IO_H */
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, 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 */
|
||||
@@ -0,0 +1,130 @@
|
||||
#
|
||||
# Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
|
||||
# Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
# Make for SC7280 QTI platform.
|
||||
|
||||
QTI_PLAT_PATH := plat/qti
|
||||
CHIPSET := ${PLAT}
|
||||
|
||||
# Turn On Separate code & data.
|
||||
SEPARATE_CODE_AND_RODATA := 1
|
||||
USE_COHERENT_MEM := 0
|
||||
WARMBOOT_ENABLE_DCACHE_EARLY := 1
|
||||
HW_ASSISTED_COHERENCY := 1
|
||||
|
||||
#Enable errata configs for cortex_a78 and cortex_a55
|
||||
ERRATA_A55_1530923 := 1
|
||||
ERRATA_A78_1941498 := 1
|
||||
ERRATA_A78_1951500 := 1
|
||||
ERRATA_A78_2132060 := 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 sc7280 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_kryo6_silver.S \
|
||||
$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo6_gold.S \
|
||||
$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S \
|
||||
$(QTI_PLAT_PATH)/common/src/pm_ps_hold.c \
|
||||
$(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)/common/src/qti_rng.c \
|
||||
$(QTI_PLAT_PATH)/common/src/spmi_arb.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_SUPPORT_GIC600 := 1
|
||||
# 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} \
|
||||
|
||||
CPU_SOURCES := lib/cpus/aarch64/cortex_a78.S \
|
||||
lib/cpus/aarch64/cortex_a55.S \
|
||||
|
||||
BL31_SOURCES += ${QTI_BL31_SOURCES} \
|
||||
${PSCI_SOURCES} \
|
||||
${GIC_SOURCES} \
|
||||
${TIMER_SOURCES} \
|
||||
${CPU_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
|
||||
|
||||
Reference in New Issue
Block a user