diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66d735c8421..37c001f54d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -213,6 +213,7 @@ jobs: make_commands: | _make PLATFORM=qcom-kodiak _make PLATFORM=qcom-lemans + _make PLATFORM=qcom-lemans CFG_QCOM_DIAG_LOG=y CFG_QFPROM_PROGRAMMING=y CFG_QCOM_QFPROM_FUSEPROV=y _make PLATFORM=qcom-ipq96xx _make PLATFORM=qcom-ipq52xx - name: arm rockchip diff --git a/core/arch/arm/plat-qcom/bobcat/arch_config.h b/core/arch/arm/plat-qcom/bobcat/arch_config.h index 5f44142225a..937d7ae5a97 100644 --- a/core/arch/arm/plat-qcom/bobcat/arch_config.h +++ b/core/arch/arm/plat-qcom/bobcat/arch_config.h @@ -6,9 +6,10 @@ #ifndef ARCH_CONFIG_H #define ARCH_CONFIG_H -/* - * Arch specific configs will be added here in future as more - * drivers/services are enabled for bobcat arch. - */ +#define IMEM_DIAG_OFFSET UL(0x730) +#define DIAG_SIZE UL(0x6000) +#define DIAG_BASE UL(0x8608000) +#define DIAG_LOG_START_INFO (IMEM_BASE + IMEM_DIAG_OFFSET) +#define TCSR_BOOT_MISC_DETECT UL(0x195C100) #endif /* ARCH_CONFIG_H */ diff --git a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk index 562d5ed3389..4a226d28b40 100644 --- a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk +++ b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target.mk @@ -1,6 +1,8 @@ $(call force,CFG_TEE_CORE_NB_CORE,4) CFG_NUM_THREADS ?= 4 +CFG_QCOM_DIAG_LOG ?= $(CFG_TEE_CORE_DEBUG) + CFG_TZDRAM_START ?= 0x87D80000 CFG_TZDRAM_SIZE ?= 0x280000 CFG_TEE_RAM_VA_SIZE ?= 0x280000 diff --git a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h index d0e5595a19e..17008a0a0d0 100644 --- a/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h +++ b/core/arch/arm/plat-qcom/bobcat/ipq52xx/target_config.h @@ -17,4 +17,7 @@ #define GICC_BASE UL(0xB002000) #define GICD_PIDR2 UL(0xFD8) +#define IMEM_BASE UL(0x8600000) +#define IMEM_SIZE UL(0x18000) + #endif /* TARGET_CONFIG_H */ diff --git a/core/arch/arm/plat-qcom/bobcat/ipq96xx/target.mk b/core/arch/arm/plat-qcom/bobcat/ipq96xx/target.mk index 087fbd5baae..b170b60a783 100644 --- a/core/arch/arm/plat-qcom/bobcat/ipq96xx/target.mk +++ b/core/arch/arm/plat-qcom/bobcat/ipq96xx/target.mk @@ -4,6 +4,8 @@ CFG_NUM_THREADS ?= 5 $(call force,CFG_ARM_GICV3,y) +CFG_QCOM_DIAG_LOG ?= $(CFG_TEE_CORE_DEBUG) + CFG_TZDRAM_START ?= 0x8A680000 CFG_TZDRAM_SIZE ?= 0x280000 CFG_TEE_RAM_VA_SIZE ?= 0x280000 diff --git a/core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h b/core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h index 5e914c9b240..b3eb10732b8 100644 --- a/core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h +++ b/core/arch/arm/plat-qcom/bobcat/ipq96xx/target_config.h @@ -16,4 +16,7 @@ #define GICD_BASE UL(0xF200000) #define GICR_BASE UL(0xF240000) +#define IMEM_BASE UL(0x8600000) +#define IMEM_SIZE UL(0x20000) + #endif /* TARGET_CONFIG_H */ diff --git a/core/arch/arm/plat-qcom/conf.mk b/core/arch/arm/plat-qcom/conf.mk index 6a0808b543e..2218d0b9cd1 100644 --- a/core/arch/arm/plat-qcom/conf.mk +++ b/core/arch/arm/plat-qcom/conf.mk @@ -2,6 +2,13 @@ PLATFORM_FLAVOR ?= kodiak +# The default value CFG_INSECURE ?= y is assigned in mk/config.mk. +# But mk/config.mk is included after $(platform-dir)/conf.mk from +# core/core.mk. +# Since we are making decision based on CFG_INSECURE in this file +# so we need to set it early here also. +CFG_INSECURE ?= y + $(call force,CFG_GIC,y) $(call force,CFG_SECURE_TIME_SOURCE_CNTPCT,y) $(call force,CFG_ARM64_core,y) diff --git a/core/arch/arm/plat-qcom/diag_log.c b/core/arch/arm/plat-qcom/diag_log.c new file mode 100644 index 00000000000..d042ef3948b --- /dev/null +++ b/core/arch/arm/plat-qcom/diag_log.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "diag_log.h" + +register_phys_mem_pgdir(MEM_AREA_IO_SEC, DIAG_BASE, DIAG_SIZE); +register_phys_mem_pgdir(MEM_AREA_IO_SEC, + (DIAG_LOG_START_INFO & ~SMALL_PAGE_MASK), + SMALL_PAGE_SIZE); +register_phys_mem_pgdir(MEM_AREA_IO_SEC, + (TCSR_BOOT_MISC_DETECT & ~SMALL_PAGE_MASK), + SMALL_PAGE_SIZE); + +#define DIAG_VERSION_V1 1 +#define DIAG_MAGIC_INIT 0x47414944 +#define DIAG_MAGIC_FAILED 0xDEADBEEF +#define DIAG_MAGIC_DLOAD 0xD15AB1ED +#define DLOAD_MAGIC_COOKIE 0x10 + +struct diag_hdr { + uint32_t version; + uint32_t magic; +}; + +struct diag_conf { + uint32_t buf_offset; + uint32_t buf_size; +}; + +struct circ_wo_buf { + uint32_t wrap; + uint32_t head; + uint8_t buf[]; +}; + +struct diag { + struct diag_hdr hdr; + struct diag_conf conf; + struct circ_wo_buf wo_cbuf; +}; + +static struct diag *global_diag; + +static struct diag *get_diag_region(void) +{ + struct diag *diag = NULL; + uint32_t *tcsr_reg = NULL; + + tcsr_reg = phys_to_virt(TCSR_BOOT_MISC_DETECT, MEM_AREA_IO_SEC, + sizeof(uint32_t)); + diag = phys_to_virt(DIAG_BASE, MEM_AREA_IO_SEC, DIAG_SIZE); + + if (!tcsr_reg || !diag) { + EMSG("DIAG: Failed to map regions"); + return NULL; + } + + if (io_read32((vaddr_t)tcsr_reg) == DLOAD_MAGIC_COOKIE) { + diag->hdr.magic = DIAG_MAGIC_DLOAD; + dsb(); + return NULL; + } + + return diag; +} + +void qcom_diag_log_init(void) +{ + struct diag *diag = NULL; + uint32_t *diag_info_addr = NULL; + + if (!IS_ENABLED(CFG_QCOM_DIAG_LOG)) { + IMSG("DIAG: Feature not available"); + return; + } + + diag = get_diag_region(); + if (!diag) + return; + + memset(diag, 0, DIAG_SIZE); + + diag->hdr.version = DIAG_VERSION_V1; + diag->hdr.magic = DIAG_MAGIC_INIT; + diag->conf.buf_offset = offsetof(struct diag, wo_cbuf.buf); + diag->conf.buf_size = ROUNDDOWN2(DIAG_SIZE - diag->conf.buf_offset, 16); + + if (diag->conf.buf_offset >= DIAG_SIZE || diag->conf.buf_size == 0) { + EMSG("DIAG: Invalid buffer configuration (offset=%u, size=%u)", + diag->conf.buf_offset, diag->conf.buf_size); + diag->hdr.magic = DIAG_MAGIC_FAILED; + return; + } + + diag_info_addr = phys_to_virt(DIAG_LOG_START_INFO, MEM_AREA_IO_SEC, + 2 * sizeof(uint32_t)); + if (diag_info_addr) { + io_write32((vaddr_t)&diag_info_addr[0], DIAG_BASE); + io_write32((vaddr_t)&diag_info_addr[1], DIAG_SIZE); + } + + dsb(); + + global_diag = diag; +} + +void qcom_diag_log_puts(const char *str) +{ + struct diag *diag = global_diag; + const char *p = NULL; + + if (!diag || !str) + return; + + for (p = str; *p; p++) { + diag->wo_cbuf.buf[diag->wo_cbuf.head++] = *p; + if (diag->wo_cbuf.head >= diag->conf.buf_size) { + diag->wo_cbuf.head = 0; + if (diag->wo_cbuf.wrap < UINT32_MAX) + diag->wo_cbuf.wrap++; + } + } +} diff --git a/core/arch/arm/plat-qcom/diag_log.h b/core/arch/arm/plat-qcom/diag_log.h new file mode 100644 index 00000000000..609f0977e7b --- /dev/null +++ b/core/arch/arm/plat-qcom/diag_log.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __DIAG_LOG_H +#define __DIAG_LOG_H + +#include +#include +#include +#include + +void qcom_diag_log_init(void); +void qcom_diag_log_puts(const char *str); + +#endif /* __DIAG_LOG_H */ diff --git a/core/arch/arm/plat-qcom/hoya/arch_config.h b/core/arch/arm/plat-qcom/hoya/arch_config.h index b0459613b85..8848825cb41 100644 --- a/core/arch/arm/plat-qcom/hoya/arch_config.h +++ b/core/arch/arm/plat-qcom/hoya/arch_config.h @@ -25,4 +25,10 @@ #define TCSR_MUTEX_BASE UL(0x01F40000) #define TCSR_MUTEX_SIZE UL(0x40000) +#define IMEM_DIAG_OFFSET UL(0x720) +#define DIAG_SIZE UL(0x3000) +#define DIAG_BASE (IMEM_BASE + IMEM_SIZE - DIAG_SIZE) +#define DIAG_LOG_START_INFO (IMEM_BASE + IMEM_DIAG_OFFSET) +#define TCSR_BOOT_MISC_DETECT UL(0x1FD3000) + #endif /* ARCH_CONFIG_H */ diff --git a/core/arch/arm/plat-qcom/hoya/kodiak/target.mk b/core/arch/arm/plat-qcom/hoya/kodiak/target.mk index 3f090c09b3b..b22ebfd0d5f 100644 --- a/core/arch/arm/plat-qcom/hoya/kodiak/target.mk +++ b/core/arch/arm/plat-qcom/hoya/kodiak/target.mk @@ -1,16 +1,21 @@ CFG_DRIVERS_CLK ?= y CFG_DRIVERS_QCOM_CLK ?= y -CFG_QCOM_QFPROM_FUSEPROV ?= $(if $(filter y,$(CFG_INSECURE)),n,y) +CFG_QCOM_DIAG_LOG ?= $(CFG_TEE_CORE_DEBUG) -_qcom_fuseprov_deps = $(if $(filter y,$(CFG_QCOM_QFPROM_FUSEPROV)),y,n) -CFG_QCOM_CMD_DB ?= $(_qcom_fuseprov_deps) -CFG_QCOM_RPMH_CLIENT ?= $(_qcom_fuseprov_deps) -CFG_QCOM_QFPROM ?= $(_qcom_fuseprov_deps) +ifneq ($(CFG_INSECURE),y) +CFG_QCOM_QFPROM_FUSEPROV ?= y +endif -CFG_QCOM_PAS_PTA ?= y +ifeq ($(CFG_QCOM_QFPROM_FUSEPROV),y) +$(call force,CFG_QCOM_CMD_DB,y) +$(call force,CFG_QCOM_RPMH_CLIENT,y) +$(call force,CFG_QCOM_QFPROM,y) # Kodiak requires MX voltage rail workaround for QFPROM fuse blowing $(call force,CFG_QFPROM_MX_RAIL_WA,y) +endif + +CFG_QCOM_PAS_PTA ?= y ifeq ($(CFG_QCOM_PAS_PTA),y) # Increase late mappings to cover all PAS resources diff --git a/core/arch/arm/plat-qcom/hoya/kodiak/target_config.h b/core/arch/arm/plat-qcom/hoya/kodiak/target_config.h index 4696716ed0f..77354f49ecb 100644 --- a/core/arch/arm/plat-qcom/hoya/kodiak/target_config.h +++ b/core/arch/arm/plat-qcom/hoya/kodiak/target_config.h @@ -26,6 +26,10 @@ #define GENI_UART_REG_BASE UL(0x994000) +/* IMEM and Diagnostic buffer */ +#define IMEM_BASE UL(0x14680000) +#define IMEM_SIZE UL(0x19000) + #define WPSS_BASE UL(0x8a00000) #define WPSS_SIZE UL(0x200000) #define TURING_BASE UL(0x09800000) diff --git a/core/arch/arm/plat-qcom/hoya/lemans/target.mk b/core/arch/arm/plat-qcom/hoya/lemans/target.mk index fba5dc6c003..c339ac0e5e3 100644 --- a/core/arch/arm/plat-qcom/hoya/lemans/target.mk +++ b/core/arch/arm/plat-qcom/hoya/lemans/target.mk @@ -1,9 +1,14 @@ CFG_DRIVERS_CLK ?= y CFG_DRIVERS_QCOM_CLK ?= y -CFG_QCOM_QFPROM_FUSEPROV ?= $(if $(filter y,$(CFG_INSECURE)),n,y) +CFG_QCOM_DIAG_LOG ?= $(CFG_TEE_CORE_DEBUG) -_qcom_fuseprov_deps = $(if $(filter y,$(CFG_QCOM_QFPROM_FUSEPROV)),y,n) -CFG_QCOM_CMD_DB ?= $(_qcom_fuseprov_deps) -CFG_QCOM_RPMH_CLIENT ?= $(_qcom_fuseprov_deps) -CFG_QCOM_QFPROM ?= $(_qcom_fuseprov_deps) +ifneq ($(CFG_INSECURE),y) +CFG_QCOM_QFPROM_FUSEPROV ?= y +endif + +ifeq ($(CFG_QCOM_QFPROM_FUSEPROV),y) +$(call force,CFG_QCOM_CMD_DB,y) +$(call force,CFG_QCOM_RPMH_CLIENT,y) +$(call force,CFG_QCOM_QFPROM,y) +endif diff --git a/core/arch/arm/plat-qcom/hoya/lemans/target_config.h b/core/arch/arm/plat-qcom/hoya/lemans/target_config.h index 6431bfa21f0..fda23747871 100644 --- a/core/arch/arm/plat-qcom/hoya/lemans/target_config.h +++ b/core/arch/arm/plat-qcom/hoya/lemans/target_config.h @@ -26,4 +26,8 @@ #define GENI_UART_REG_BASE UL(0xa8c000) +/* IMEM and Diagnostic buffer */ +#define IMEM_BASE UL(0x14680000) +#define IMEM_SIZE UL(0x32000) + #endif /* TARGET_CONFIG_H */ diff --git a/core/arch/arm/plat-qcom/main.c b/core/arch/arm/plat-qcom/main.c index ed7a94e186e..30e35df7eeb 100644 --- a/core/arch/arm/plat-qcom/main.c +++ b/core/arch/arm/plat-qcom/main.c @@ -11,6 +11,8 @@ #include #include +#include "diag_log.h" + /* * Register the physical memory area for peripherals etc. Here we are * registering the UART console. @@ -32,6 +34,16 @@ register_ddr(DRAM1_BASE, DRAM1_SIZE); static struct qcom_geni_uart_data console_data; +void plat_trace_ext_puts(const char *str) +{ + qcom_diag_log_puts(str); +} + +void plat_trace_init(void) +{ + qcom_diag_log_init(); +} + void plat_console_init(void) { qcom_geni_uart_init(&console_data, GENI_UART_REG_BASE); diff --git a/core/arch/arm/plat-qcom/sub.mk b/core/arch/arm/plat-qcom/sub.mk index 81c0195fd80..894944c10d4 100644 --- a/core/arch/arm/plat-qcom/sub.mk +++ b/core/arch/arm/plat-qcom/sub.mk @@ -3,5 +3,6 @@ global-incdirs-y += $(QCOM_ARCH_FAMILY) global-incdirs-y += $(QCOM_ARCH_FAMILY)/$(PLATFORM_FLAVOR) srcs-y += main.c -$(eval $(call cfg-depends-all,CFG_QCOM_QFPROM_FUSEPROV,CFG_QCOM_QFPROM)) subdirs-$(CFG_QCOM_QFPROM_FUSEPROV) += provision + +srcs-y += diag_log.c diff --git a/core/drivers/qcom/sub.mk b/core/drivers/qcom/sub.mk index b7a931564c7..41d17c06cea 100644 --- a/core/drivers/qcom/sub.mk +++ b/core/drivers/qcom/sub.mk @@ -7,8 +7,6 @@ srcs-$(CFG_QCOM_RAMBLUR_PIMEM_V3) += ramblur/ramblur_pimem_v3.c srcs-$(CFG_QCOM_PRNG) += prng/prng.c -$(eval $(call cfg-depends-all,CFG_QCOM_QFPROM,CFG_QCOM_CMD_DB CFG_QCOM_RPMH_CLIENT)) -$(eval $(call cfg-depends-all,CFG_QCOM_RPMH_CLIENT,CFG_QCOM_CMD_DB)) subdirs-$(CFG_QCOM_CMD_DB) += cmd_db subdirs-$(CFG_QCOM_RPMH_CLIENT) += rpmh subdirs-$(CFG_QCOM_QFPROM) += qfprom