diff options
author | Sheetal Tigadoli <sheetal.tigadoli@broadcom.com> | 2019-08-02 10:01:38 +0530 |
---|---|---|
committer | Jerome Forissier <jerome@forissier.org> | 2019-11-25 14:59:05 +0100 |
commit | e605fbdfd7a0a046e686222e857192bc97c070fd (patch) | |
tree | a3744dcbca2a7c64195a731cc71ee63d1dcae208 | |
parent | 15542a729763fbe326f0479e0263d9f57e6a3364 (diff) |
pta: bcm: Add PTA to handle Broadcom error logs
Add PTA to handle Broadcom error logs.
The PTA supports following ops:
- Obtaining error logs
- Obtaining crash dumps and
- Loading firmware into secure ddr memory region
Signed-off-by: Sheetal Tigadoli <sheetal.tigadoli@broadcom.com>
Reviewed-by: Jerome Forissier <jerome@forissier.org>
-rw-r--r-- | core/arch/arm/plat-bcm/conf.mk | 4 | ||||
-rw-r--r-- | core/arch/arm/plat-bcm/main.c | 3 | ||||
-rw-r--r-- | core/pta/bcm/elog.c | 232 | ||||
-rw-r--r-- | core/pta/bcm/sub.mk | 1 |
4 files changed, 240 insertions, 0 deletions
diff --git a/core/arch/arm/plat-bcm/conf.mk b/core/arch/arm/plat-bcm/conf.mk index f2b814b9..170c9459 100644 --- a/core/arch/arm/plat-bcm/conf.mk +++ b/core/arch/arm/plat-bcm/conf.mk @@ -28,11 +28,15 @@ $(call force,CFG_BCM_HWRNG,y) $(call force,CFG_BCM_SOTP,y) $(call force,CFG_BCM_GPIO,y) CFG_BNXT_FW ?= y +CFG_BCM_ELOG_DUMP ?= y endif CFG_BCM_ELOG_AP_UART_LOG_BASE ?= 0x8f110000 CFG_BCM_ELOG_AP_UART_LOG_SIZE ?= 0x10000 +CFG_BCM_ELOG_BASE ?= 0x8f120000 +CFG_BCM_ELOG_SIZE ?= 0x100000 + ifeq ($(DEBUG),1) platform-cflags += -gdwarf-2 platform-aflags += -gdwarf-2 diff --git a/core/arch/arm/plat-bcm/main.c b/core/arch/arm/plat-bcm/main.c index cf3b66a0..dd0dac26 100644 --- a/core/arch/arm/plat-bcm/main.c +++ b/core/arch/arm/plat-bcm/main.c @@ -64,6 +64,9 @@ register_phys_mem(MEM_AREA_RAM_SEC, BCM_DRAM0_SEC_BASE, BCM_DRAM0_SEC_SIZE); register_phys_mem(MEM_AREA_IO_NSEC, CFG_BCM_ELOG_AP_UART_LOG_BASE, CFG_BCM_ELOG_AP_UART_LOG_SIZE); #endif +#ifdef CFG_BCM_ELOG_BASE +register_phys_mem(MEM_AREA_RAM_NSEC, CFG_BCM_ELOG_BASE, CFG_BCM_ELOG_SIZE); +#endif const struct thread_handlers *generic_boot_get_handlers(void) { diff --git a/core/pta/bcm/elog.c b/core/pta/bcm/elog.c new file mode 100644 index 00000000..f53f56c8 --- /dev/null +++ b/core/pta/bcm/elog.c @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright 2019 Broadcom. + */ + +#include <drivers/bcm/bnxt.h> +#include <io.h> +#include <kernel/pseudo_ta.h> +#include <mm/core_memprot.h> +#include <mm/core_mmu.h> +#include <string.h> +#include <trace.h> + +#define ELOG_SERVICE_UUID \ + { 0x6272636D, 0x2019, 0x0701, \ + { 0x42, 0x43, 0x4D, 0x5F, 0x45, 0x4C, 0x4F, 0x47 } } + +#define ELOG_TA_NAME "pta_bcm_elog.ta" + +#define BCM_NITRO_FW_LOAD_ADDR 0x8ae00000 +#define BCM_NITRO_CRASH_DUMP_BASE_ADDR 0x8b000000 + +/* Default ELOG buffer size 1MB */ +#define DEFAULT_ELOG_BUFFER_SIZE 0x100000 + +/* + * Get Error log memory dump + * + * [out] memref[0]: Destination + * [in] value[1].a: Offset + */ +#define PTA_BCM_ELOG_CMD_GET_ELOG_MEM 1 + +/* + * Get nitro crash_dump memory + * + * [out] memref[0]: Destination + * [in] value[1].a: Offset + */ +#define PTA_BCM_ELOG_CMD_GET_NITRO_CRASH_DUMP 2 + +/* + * Load nitro firmware memory + * + * [in] memref[0]: Nitro f/w image data + * [in] value[1].a: Offset for loading f/w image + * [in] value[2].a: Firmware image size + */ +#define PTA_BCM_ELOG_CMD_LOAD_NITRO_FW 3 + +#define BCM_ELOG_GLOBAL_METADATA_SIG 0x45524c47 + +#define MAX_NITRO_CRASH_DUMP_MEM_SIZE 0x2000000 +#define MAX_NITRO_FW_LOAD_MEM_SIZE 0x200000 + +/* Load Nitro fw image to SEC DDR memory */ +static TEE_Result pta_elog_load_nitro_fw(uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + TEE_Result res = TEE_SUCCESS; + paddr_t src_paddr = BCM_NITRO_FW_LOAD_ADDR + BNXT_IMG_SECMEM_OFFSET; + vaddr_t src_vaddr = 0; + uint32_t offset = 0, sz = 0; + char *buf = NULL; + uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_NONE); + + if (exp_param_types != param_types) { + EMSG("Invalid Param types"); + return TEE_ERROR_BAD_PARAMETERS; + } + + /* Check if firmware file size exceeds reserved memory size */ + if (params[2].value.a > MAX_NITRO_FW_LOAD_MEM_SIZE) { + EMSG("Invalid access"); + return TEE_ERROR_EXCESS_DATA; + } + + offset = params[1].value.a; + + /* + * Check if offset is within memory range reserved for nitro firmware + * minus default size of buffer + */ + if (offset > MAX_NITRO_FW_LOAD_MEM_SIZE - DEFAULT_ELOG_BUFFER_SIZE) { + EMSG("Invalid access"); + return TEE_ERROR_ACCESS_DENIED; + } + + src_vaddr = (vaddr_t)phys_to_virt((uintptr_t)src_paddr + offset, + MEM_AREA_RAM_SEC); + + buf = params[0].memref.buffer; + sz = params[0].memref.size; + + memcpy((char *)src_vaddr, buf, sz); + + cache_op_inner(DCACHE_AREA_CLEAN, (void *)src_vaddr, sz); + + return res; +} + +static uint32_t get_dump_data(vaddr_t src, TEE_Param params[TEE_NUM_PARAMS]) +{ + char *buf = NULL; + uint32_t sz = 0; + + buf = params[0].memref.buffer; + sz = params[0].memref.size; + + /* + * If request size exceeds default buf size + * override request size to default DEFAULT_ELOG_BUFFER_SIZE + */ + if (sz > DEFAULT_ELOG_BUFFER_SIZE) + sz = DEFAULT_ELOG_BUFFER_SIZE; + + DMSG("buf %p sz 0x%x", buf, sz); + + memcpy(buf, (char *)src, sz); + + params[0].memref.size = sz; + + return sz; +} + +/* Copy nitro crash dump data */ +static TEE_Result pta_elog_nitro_crash_dump(uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + TEE_Result res = TEE_SUCCESS; + paddr_t src_paddr = BCM_NITRO_CRASH_DUMP_BASE_ADDR; + vaddr_t src_vaddr = 0; + uint32_t offset = 0; + uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE); + + if (exp_param_types != param_types) { + EMSG("Invalid Param types"); + return TEE_ERROR_BAD_PARAMETERS; + } + + offset = params[1].value.a; + + /* + * Check if offset is within memory range reserved for nitro crash dump + * minus default size of buffer + */ + if (offset > MAX_NITRO_CRASH_DUMP_MEM_SIZE - DEFAULT_ELOG_BUFFER_SIZE) { + EMSG("Invalid access"); + return TEE_ERROR_ACCESS_DENIED; + } + + src_vaddr = (vaddr_t)phys_to_virt((uintptr_t)src_paddr + offset, + MEM_AREA_RAM_SEC); + + /* TODO : check if NITRO_CRASH_DUMP is available */ + + cache_op_inner(DCACHE_AREA_INVALIDATE, + (void *)src_vaddr, DEFAULT_ELOG_BUFFER_SIZE); + + get_dump_data(src_vaddr, params); + + return res; +} + +/* Copy soc error log data */ +static TEE_Result pta_elog_dump(uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + TEE_Result res = TEE_SUCCESS; + paddr_t src_paddr = CFG_BCM_ELOG_BASE; + vaddr_t src_vaddr = 0; + uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE); + + if (exp_param_types != param_types) { + EMSG("Invalid Param types"); + return TEE_ERROR_BAD_PARAMETERS; + } + + src_vaddr = (vaddr_t)phys_to_virt(src_paddr, MEM_AREA_RAM_NSEC); + + /* Validate if Error logs are present */ + if ((*(uint32_t *)src_vaddr) != BCM_ELOG_GLOBAL_METADATA_SIG) { + EMSG("Elog Not setup"); + return TEE_ERROR_NOT_SUPPORTED; + } + + get_dump_data(src_vaddr, params); + + return res; +} + +static TEE_Result invoke_command(void *session_context __unused, + uint32_t cmd_id, + uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + TEE_Result res = TEE_SUCCESS; + + DMSG("command entry point[%d] for \"%s\"", cmd_id, ELOG_TA_NAME); + + switch (cmd_id) { + case PTA_BCM_ELOG_CMD_GET_ELOG_MEM: + res = pta_elog_dump(param_types, params); + break; + case PTA_BCM_ELOG_CMD_GET_NITRO_CRASH_DUMP: + res = pta_elog_nitro_crash_dump(param_types, params); + break; + case PTA_BCM_ELOG_CMD_LOAD_NITRO_FW: + res = pta_elog_load_nitro_fw(param_types, params); + break; + default: + EMSG("cmd: %d Not supported %s", cmd_id, ELOG_TA_NAME); + res = TEE_ERROR_NOT_SUPPORTED; + break; + } + + return res; +} + +pseudo_ta_register(.uuid = ELOG_SERVICE_UUID, + .name = ELOG_TA_NAME, + .flags = PTA_DEFAULT_FLAGS, + .invoke_command_entry_point = invoke_command); diff --git a/core/pta/bcm/sub.mk b/core/pta/bcm/sub.mk index ab8c04d4..63a29cb5 100644 --- a/core/pta/bcm/sub.mk +++ b/core/pta/bcm/sub.mk @@ -3,3 +3,4 @@ srcs-$(CFG_SP805_WDT) += wdt.c srcs-$(CFG_BCM_HWRNG) += hwrng.c srcs-$(CFG_BCM_SOTP) += sotp.c srcs-$(CFG_BCM_GPIO) += gpio.c +srcs-$(CFG_BCM_ELOG_DUMP) += elog.c |