1028 lines
32 KiB
C
1028 lines
32 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2015 MediaTek Inc.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/rtc.h>
|
|
#include <linux/timer.h>
|
|
#include "ccci_config.h"
|
|
#include "ccci_common_config.h"
|
|
#if defined(CONFIG_MTK_AEE_FEATURE)
|
|
#include <mt-plat/aee.h>
|
|
#endif
|
|
#ifdef ENABLE_EMI_PROTECTION
|
|
#include <mach/emi_mpu.h>
|
|
#endif
|
|
#include "mdee_dumper_v2.h"
|
|
|
|
#ifndef DB_OPT_DEFAULT
|
|
#define DB_OPT_DEFAULT (0) /* Dummy macro define to avoid build error */
|
|
#endif
|
|
|
|
#ifndef DB_OPT_FTRACE
|
|
#define DB_OPT_FTRACE (0) /* Dummy macro define to avoid build error */
|
|
#endif
|
|
|
|
int __weak Is_MD_EMI_voilation(void)
|
|
{
|
|
CCCI_ERROR_LOG(-1, FSM,
|
|
"%s:weak function\n", __func__);
|
|
return 1;
|
|
}
|
|
|
|
static void ccci_aed_v2(struct ccci_fsm_ee *mdee, unsigned int dump_flag,
|
|
char *aed_str, int db_opt)
|
|
{
|
|
void *ex_log_addr = NULL;
|
|
int ex_log_len = 0;
|
|
void *md_img_addr = NULL;
|
|
int md_img_len = 0;
|
|
int info_str_len = 0;
|
|
char *buff; /*[AED_STR_LEN]; */
|
|
#if defined(CONFIG_MTK_AEE_FEATURE)
|
|
char buf_fail[] = "Fail alloc mem for exception\n";
|
|
#endif
|
|
char *img_inf;
|
|
struct mdee_dumper_v2 *dumper = mdee->dumper_obj;
|
|
int md_id = mdee->md_id;
|
|
struct ccci_smem_region *mdss_dbg =
|
|
ccci_md_get_smem_by_user_id(mdee->md_id,
|
|
SMEM_USER_RAW_MDSS_DBG);
|
|
struct ccci_mem_layout *mem_layout = ccci_md_get_mem(mdee->md_id);
|
|
struct ccci_per_md *per_md_data = ccci_get_per_md_data(mdee->md_id);
|
|
int md_dbg_dump_flag = per_md_data->md_dbg_dump_flag;
|
|
int ret = 0;
|
|
|
|
if (!mem_layout) {
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s:ccci_md_get_mem fail\n", __func__);
|
|
return;
|
|
}
|
|
buff = kmalloc(AED_STR_LEN, GFP_ATOMIC);
|
|
if (buff == NULL) {
|
|
CCCI_ERROR_LOG(md_id, FSM, "Fail alloc Mem for buff, %d!\n",
|
|
md_dbg_dump_flag);
|
|
goto err_exit1;
|
|
}
|
|
img_inf = ccci_get_md_info_str(md_id);
|
|
if (img_inf == NULL)
|
|
img_inf = "";
|
|
info_str_len = strlen(aed_str);
|
|
info_str_len += strlen(img_inf);
|
|
|
|
if (info_str_len > AED_STR_LEN)
|
|
/* Cut string length to AED_STR_LEN */
|
|
buff[AED_STR_LEN - 1] = '\0';
|
|
|
|
ret = snprintf(buff, AED_STR_LEN, "md%d:%s%s",
|
|
md_id + 1, aed_str, img_inf);
|
|
if (ret < 0 || ret >= AED_STR_LEN)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret = %d\n", __func__, __LINE__, ret);
|
|
/* MD ID must sync with aee_dump_ccci_debug_info() */
|
|
err_exit1:
|
|
if (dump_flag & CCCI_AED_DUMP_CCIF_REG) {
|
|
ex_log_addr = mdss_dbg->base_ap_view_vir;
|
|
ex_log_len = mdss_dbg->size;
|
|
ccci_md_dump_info(mdee->md_id,
|
|
DUMP_FLAG_CCIF | DUMP_FLAG_CCIF_REG,
|
|
mdss_dbg->base_ap_view_vir + CCCI_EE_OFFSET_CCIF_SRAM,
|
|
CCCI_EE_SIZE_CCIF_SRAM);
|
|
}
|
|
if (dump_flag & CCCI_AED_DUMP_EX_MEM) {
|
|
ex_log_addr = mdss_dbg->base_ap_view_vir;
|
|
ex_log_len = mdss_dbg->size;
|
|
}
|
|
if (dump_flag & CCCI_AED_DUMP_EX_PKT) {
|
|
ex_log_addr = (void *)dumper->ex_pl_info;
|
|
ex_log_len = MD_HS1_FAIL_DUMP_SIZE;
|
|
}
|
|
if (dump_flag & CCCI_AED_DUMP_MD_IMG_MEM) {
|
|
md_img_addr = (void *)mem_layout->md_bank0.base_ap_view_vir;
|
|
md_img_len = MD_IMG_DUMP_SIZE;
|
|
}
|
|
if (buff == NULL) {
|
|
#if defined(CONFIG_MTK_AEE_FEATURE)
|
|
if (md_dbg_dump_flag & (1 << MD_DBG_DUMP_SMEM))
|
|
aed_md_exception_api(ex_log_addr, ex_log_len,
|
|
md_img_addr, md_img_len, buf_fail, db_opt);
|
|
else
|
|
aed_md_exception_api(NULL, 0, md_img_addr, md_img_len,
|
|
buf_fail, db_opt);
|
|
#endif
|
|
} else {
|
|
#if defined(CONFIG_MTK_AEE_FEATURE)
|
|
if (md_dbg_dump_flag & (1 << MD_DBG_DUMP_SMEM))
|
|
aed_md_exception_api(ex_log_addr, ex_log_len,
|
|
md_img_addr, md_img_len, buff, db_opt);
|
|
else
|
|
aed_md_exception_api(NULL, 0, md_img_addr, md_img_len,
|
|
buff, db_opt);
|
|
#endif
|
|
kfree(buff);
|
|
}
|
|
}
|
|
|
|
static void mdee_output_debug_info_to_buf(struct ccci_fsm_ee *mdee,
|
|
struct debug_info_t *debug_info, char *ex_info)
|
|
{
|
|
int md_id = mdee->md_id;
|
|
struct ccci_mem_layout *mem_layout;
|
|
char *ex_info_temp = NULL;
|
|
int ret = 0;
|
|
int val = 0;
|
|
|
|
switch (debug_info->type) {
|
|
case MD_EX_DUMP_ASSERT:
|
|
CCCI_ERROR_LOG(md_id, FSM, "filename = %s\n",
|
|
debug_info->assert.file_name);
|
|
CCCI_ERROR_LOG(md_id, FSM, "line = %d\n",
|
|
debug_info->assert.line_num);
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"para0 = %d, para1 = %d, para2 = %d\n",
|
|
debug_info->assert.parameters[0],
|
|
debug_info->assert.parameters[1],
|
|
debug_info->assert.parameters[2]);
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY,
|
|
"%s\n[%s] file:%s line:%d\np1:0x%08x\np2:0x%08x\np3:0x%08x\n\n",
|
|
debug_info->core_name,
|
|
debug_info->name,
|
|
debug_info->assert.file_name,
|
|
debug_info->assert.line_num,
|
|
debug_info->assert.parameters[0],
|
|
debug_info->assert.parameters[1],
|
|
debug_info->assert.parameters[2]);
|
|
break;
|
|
case MD_EX_DUMP_3P_EX:
|
|
case MD_EX_CC_C2K_EXCEPTION:
|
|
CCCI_ERROR_LOG(md_id, FSM, "fatal error code 1 = 0x%08X\n",
|
|
debug_info->fatal_error.err_code1);
|
|
CCCI_ERROR_LOG(md_id, FSM, "fatal error code 2 = 0x%08X\n",
|
|
debug_info->fatal_error.err_code2);
|
|
CCCI_ERROR_LOG(md_id, FSM, "fatal error code 3 = 0x%08X\n",
|
|
debug_info->fatal_error.err_code3);
|
|
CCCI_ERROR_LOG(md_id, FSM, "fatal error offender %s\n",
|
|
debug_info->fatal_error.offender);
|
|
if (debug_info->fatal_error.offender[0] != '\0') {
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY,
|
|
"%s\n[%s] err_code1:0x%08X err_code2:0x%08X erro_code3:0x%08X\nMD Offender:%s\n%s",
|
|
debug_info->core_name, debug_info->name,
|
|
debug_info->fatal_error.err_code1,
|
|
debug_info->fatal_error.err_code2,
|
|
debug_info->fatal_error.err_code3,
|
|
debug_info->fatal_error.offender,
|
|
debug_info->fatal_error.ExStr);
|
|
} else {
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY,
|
|
"%s\n[%s] err_code1:0x%08X err_code2:0x%08X err_code3:0x%08X\n%s\n",
|
|
debug_info->core_name, debug_info->name,
|
|
debug_info->fatal_error.err_code1,
|
|
debug_info->fatal_error.err_code2,
|
|
debug_info->fatal_error.err_code3,
|
|
debug_info->fatal_error.ExStr);
|
|
}
|
|
if (debug_info->fatal_error.err_code1 == 0x3104) {
|
|
ex_info_temp = kmalloc(EE_BUF_LEN_UMOLY, GFP_ATOMIC);
|
|
if (ex_info_temp == NULL) {
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"Fail alloc Mem for ex_info_temp!\n");
|
|
break;
|
|
}
|
|
val = snprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%s", ex_info);
|
|
if (val < 0 || val >= EE_BUF_LEN_UMOLY) {
|
|
CCCI_ERROR_LOG(-1, FSM,
|
|
"%s-%d;snprintf fail,val = %d\n",
|
|
__func__, __LINE__, val);
|
|
kfree(ex_info_temp);
|
|
return;
|
|
}
|
|
mem_layout = ccci_md_get_mem(mdee->md_id);
|
|
if (mem_layout == NULL) {
|
|
CCCI_ERROR_LOG(-1, FSM, "ccci_md_get_mem fail\n");
|
|
kfree(ex_info_temp);
|
|
return;
|
|
}
|
|
val = snprintf(ex_info, EE_BUF_LEN_UMOLY,
|
|
"%s%s, MD base = 0x%08X\n\n", ex_info_temp,
|
|
mdee->ex_mpu_string,
|
|
(unsigned int)mem_layout->md_bank0.base_ap_view_phy);
|
|
if (val < 0 || val >= EE_BUF_LEN_UMOLY) {
|
|
CCCI_ERROR_LOG(-1, FSM,
|
|
"%s-%d;snprintf fail,val = %d\n",
|
|
__func__, __LINE__, val);
|
|
kfree(ex_info_temp);
|
|
return;
|
|
}
|
|
memset(mdee->ex_mpu_string, 0x0,
|
|
sizeof(mdee->ex_mpu_string));
|
|
kfree(ex_info_temp);
|
|
}
|
|
break;
|
|
case MD_EX_DUMP_2P_EX:
|
|
CCCI_ERROR_LOG(md_id, FSM, "fatal error code 1 = 0x%08X\n\n",
|
|
debug_info->fatal_error.err_code1);
|
|
CCCI_ERROR_LOG(md_id, FSM, "fatal error code 2 = 0x%08X\n\n",
|
|
debug_info->fatal_error.err_code2);
|
|
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY,
|
|
"%s\n[%s] err_code1:0x%08X err_code2:0x%08X\n\n",
|
|
debug_info->core_name, debug_info->name,
|
|
debug_info->fatal_error.err_code1,
|
|
debug_info->fatal_error.err_code2);
|
|
break;
|
|
case MD_EX_DUMP_EMI_CHECK:
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"md_emi_check: 0x%08X, 0x%08X, %02d, 0x%08X\n\n",
|
|
debug_info->data.data0, debug_info->data.data1,
|
|
debug_info->data.channel, debug_info->data.reserved);
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY,
|
|
"%s\n[emi_chk] 0x%08X, 0x%08X, %02d, 0x%08X\n\n",
|
|
debug_info->core_name, debug_info->data.data0,
|
|
debug_info->data.data1,
|
|
debug_info->data.channel, debug_info->data.reserved);
|
|
break;
|
|
case MD_EX_DUMP_UNKNOWN:
|
|
default: /* Only display exception name */
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s\n[%s]\n",
|
|
debug_info->core_name, debug_info->name);
|
|
break;
|
|
}
|
|
if (ret < 0 || ret >= EE_BUF_LEN_UMOLY)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d,type=%d\n",
|
|
__func__, __LINE__, ret, debug_info->type);
|
|
}
|
|
|
|
static void mdee_info_dump_v2(struct ccci_fsm_ee *mdee)
|
|
{
|
|
char *ex_info; /*[EE_BUF_LEN] = ""; */
|
|
/*[EE_BUF_LEN] = "\n[Others] May I-Bit dis too long\n";*/
|
|
char *i_bit_ex_info = NULL;
|
|
char buf_fail[] = "Fail alloc mem for exception\n";
|
|
int db_opt = (DB_OPT_DEFAULT | DB_OPT_FTRACE);
|
|
int dump_flag = 0;
|
|
int core_id;
|
|
char *ex_info_temp = NULL;/*[EE_BUF_LEN] = "";*/
|
|
char *ex_info_buf = NULL;
|
|
struct debug_info_t *debug_info = NULL;
|
|
unsigned char c;
|
|
struct mdee_dumper_v2 *dumper = mdee->dumper_obj;
|
|
int md_id = mdee->md_id;
|
|
struct ex_PL_log *ex_pl_info = (struct ex_PL_log *)dumper->ex_pl_info;
|
|
int md_state = ccci_fsm_get_md_state(mdee->md_id);
|
|
struct ccci_smem_region *mdccci_dbg =
|
|
ccci_md_get_smem_by_user_id(mdee->md_id,
|
|
SMEM_USER_RAW_MDCCCI_DBG);
|
|
struct ccci_smem_region *mdss_dbg =
|
|
ccci_md_get_smem_by_user_id(mdee->md_id,
|
|
SMEM_USER_RAW_MDSS_DBG);
|
|
struct rtc_time tm;
|
|
struct timeval tv = { 0 };
|
|
struct timeval tv_android = { 0 };
|
|
struct rtc_time tm_android;
|
|
struct ccci_per_md *per_md_data =
|
|
ccci_get_per_md_data(mdee->md_id);
|
|
int md_dbg_dump_flag = per_md_data->md_dbg_dump_flag;
|
|
int ret = 0;
|
|
int val = 0;
|
|
|
|
ex_info = kmalloc(EE_BUF_LEN_UMOLY, GFP_ATOMIC);
|
|
if (ex_info == NULL) {
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"Fail alloc Mem for ex_info!\n");
|
|
goto err_exit;
|
|
}
|
|
ex_info_temp = kmalloc(EE_BUF_LEN_UMOLY, GFP_ATOMIC);
|
|
if (ex_info_temp == NULL) {
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"Fail alloc Mem for ex_info_temp!\n");
|
|
goto err_exit;
|
|
}
|
|
ex_info_buf = kzalloc(EE_BUF_LEN_UMOLY, GFP_ATOMIC);
|
|
if (ex_info_buf == NULL) {
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"Fail alloc Mem for ex_info_buf!\n");
|
|
goto err_exit;
|
|
}
|
|
|
|
do_gettimeofday(&tv);
|
|
tv_android = tv;
|
|
rtc_time_to_tm(tv.tv_sec, &tm);
|
|
tv_android.tv_sec -= sys_tz.tz_minuteswest * 60;
|
|
rtc_time_to_tm(tv_android.tv_sec, &tm_android);
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"Sync:%d%02d%02d %02d:%02d:%02d.%u(%02d:%02d:%02d.%03d(TZone))\n",
|
|
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
|
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
|
(unsigned int)tv.tv_usec,
|
|
tm_android.tm_hour, tm_android.tm_min,
|
|
tm_android.tm_sec, (unsigned int)tv_android.tv_usec);
|
|
for (core_id = 0; core_id < dumper->ex_core_num; core_id++) {
|
|
if (core_id == 1)
|
|
ret = snprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%s", ex_info);
|
|
else if (core_id > 1) {
|
|
ret = snprintf(ex_info_buf, EE_BUF_LEN_UMOLY, "%smd%d:%s",
|
|
ex_info_temp, md_id + 1, ex_info);
|
|
val = snprintf(ex_info_temp, EE_BUF_LEN_UMOLY,
|
|
"%s", ex_info_buf);
|
|
}
|
|
if (val < 0 || val >= EE_BUF_LEN_UMOLY ||
|
|
ret < 0 || ret >= EE_BUF_LEN_UMOLY)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,val=%d,ret=%d,core_id=%d\n",
|
|
__func__, __LINE__, val, ret, core_id);
|
|
debug_info = &dumper->debug_info[core_id];
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"exception type(%d):%s\n", debug_info->type,
|
|
debug_info->name ? : "Unknown");
|
|
mdee_output_debug_info_to_buf(mdee, debug_info, ex_info);
|
|
ccci_event_log("md%d %s\n", md_id+1, ex_info);
|
|
}
|
|
if (dumper->ex_core_num > 1) {
|
|
CCCI_NORMAL_LOG(md_id, FSM,
|
|
"%s+++++++%s", ex_info_temp, ex_info);
|
|
ret = snprintf(ex_info_buf, EE_BUF_LEN_UMOLY,
|
|
"%smd%d:%s", ex_info_temp, md_id + 1, ex_info);
|
|
val = snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s", ex_info_buf);
|
|
if (val < 0 || val >= EE_BUF_LEN_UMOLY)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,val=%d\n",
|
|
__func__, __LINE__, val);
|
|
|
|
debug_info = &dumper->debug_info[0];
|
|
} else if (dumper->ex_core_num == 0)
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY, "\n");
|
|
if (ret < 0 || ret >= EE_BUF_LEN_UMOLY)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d,ex_core_num=%d\n",
|
|
__func__, __LINE__, ret, dumper->ex_core_num);
|
|
/* Add additional info */
|
|
ret = snprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%s", ex_info);
|
|
if (ret < 0 || ret >= EE_BUF_LEN_UMOLY)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d\n",
|
|
__func__, __LINE__, ret);
|
|
switch (dumper->more_info) {
|
|
case MD_EE_CASE_ONLY_SWINT:
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s%s",
|
|
ex_info_temp, "\nOnly SWINT case\n");
|
|
break;
|
|
case MD_EE_CASE_ONLY_EX:
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s%s",
|
|
ex_info_temp, "\nOnly EX case\n");
|
|
break;
|
|
case MD_EE_CASE_NO_RESPONSE:
|
|
/* use strcpy, otherwise if this happens after a MD EE,
|
|
* the former EE info will be printed out
|
|
*/
|
|
strncpy(ex_info, "\n[Others] MD long time no response\n",
|
|
EE_BUF_LEN_UMOLY);
|
|
db_opt |= DB_OPT_FTRACE;
|
|
break;
|
|
case MD_EE_CASE_WDT:
|
|
strncpy(ex_info, "\n[Others] MD watchdog timeout interrupt\n",
|
|
EE_BUF_LEN_UMOLY);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (ret < 0 || ret >= EE_BUF_LEN_UMOLY)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d,more_info=%d\n",
|
|
__func__, __LINE__, ret, dumper->more_info);
|
|
|
|
/* get ELM_status field from MD side */
|
|
ret = snprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%s", ex_info);
|
|
if (ret < 0 || ret >= EE_BUF_LEN_UMOLY)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d\n",
|
|
__func__, __LINE__, ret);
|
|
c = ex_pl_info->envinfo.ELM_status;
|
|
CCCI_NORMAL_LOG(md_id, FSM, "ELM_status: %x\n", c);
|
|
switch (c) {
|
|
case 0xFF:
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s%s", ex_info_temp,
|
|
"\nno ELM info\n");
|
|
break;
|
|
case 0xAE:
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s%s", ex_info_temp,
|
|
"\nELM rlat:FAIL\n");
|
|
break;
|
|
case 0xBE:
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s%s", ex_info_temp,
|
|
"\nELM wlat:FAIL\n");
|
|
break;
|
|
case 0xDE:
|
|
ret = snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s%s", ex_info_temp,
|
|
"\nELM r/wlat:PASS\n");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (ret < 0 || ret >= EE_BUF_LEN_UMOLY)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d,c=%d\n",
|
|
__func__, __LINE__, ret, c);
|
|
|
|
/* Dump MD EE info */
|
|
CCCI_MEM_LOG_TAG(md_id, FSM,
|
|
"Dump MD EX log, 0x%x, 0x%x\n", dumper->more_info,
|
|
(unsigned int)md_state);
|
|
if (dumper->more_info == MD_EE_CASE_NORMAL
|
|
&& md_state == BOOT_WAITING_FOR_HS1) {
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
dumper->ex_pl_info, MD_HS1_FAIL_DUMP_SIZE);
|
|
/* MD will not fill in share memory
|
|
* before we send runtime data
|
|
*/
|
|
dump_flag = CCCI_AED_DUMP_EX_PKT;
|
|
} else if (md_dbg_dump_flag & (1 << MD_DBG_DUMP_SMEM)) {
|
|
CCCI_MEM_LOG_TAG(md_id, FSM,
|
|
"Dump MD exp smem_mdccci_debug_log\n");
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
mdccci_dbg->base_ap_view_vir, mdccci_dbg->size);
|
|
CCCI_MEM_LOG_TAG(md_id, FSM,
|
|
"Dump MD exp smem_mdss_debug_log\n");
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
mdss_dbg->base_ap_view_vir, 512);
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
(mdss_dbg->base_ap_view_vir + 6 * 1024), 2048);
|
|
/*
|
|
* otherwise always dump whole share memory,
|
|
* as MD will fill debug log into
|
|
* its 2nd 1K region after bootup
|
|
*/
|
|
dump_flag = CCCI_AED_DUMP_EX_MEM;
|
|
if (dumper->more_info == MD_EE_CASE_NO_RESPONSE)
|
|
dump_flag |= CCCI_AED_DUMP_CCIF_REG;
|
|
}
|
|
|
|
err_exit:
|
|
|
|
/* update here to maintain handshake stage
|
|
* info during exception handling
|
|
*/
|
|
if (debug_info && debug_info->type == MD_EX_TYPE_C2K_ERROR)
|
|
CCCI_NORMAL_LOG(md_id, FSM, "C2K EE, No need trigger DB\n");
|
|
else if (debug_info && (debug_info->type == MD_EX_DUMP_EMI_CHECK)
|
|
&& (Is_MD_EMI_voilation() == 0))
|
|
CCCI_NORMAL_LOG(md_id, FSM,
|
|
"Not MD EMI violation, No need trigger DB\n");
|
|
else if (ex_info == NULL)
|
|
ccci_aed_v2(mdee, dump_flag, buf_fail, db_opt);
|
|
else
|
|
ccci_aed_v2(mdee, dump_flag, ex_info, db_opt);
|
|
|
|
|
|
kfree(ex_info);
|
|
kfree(ex_info_temp);
|
|
kfree(ex_info_buf);
|
|
kfree(i_bit_ex_info);
|
|
}
|
|
|
|
static char mdee_plstr[MD_EX_PL_FATALE_TOTAL + MD_EX_OTHER_CORE_EXCEPTIN -
|
|
MD_EX_CC_INVALID_EXCEPTION][32] = {
|
|
"INVALID",
|
|
"Fatal error (undefine)",
|
|
"Fatal error (swi)",
|
|
"Fatal error (prefetch abort)",
|
|
"Fatal error (data abort)",
|
|
"Fatal error (stack)",
|
|
"Fatal error (task)",
|
|
"Fatal error (buff)",
|
|
"Fatal error (CC invalid)",
|
|
"Fatal error (CC PCore)",
|
|
"Fatal error (CC L1Core)",
|
|
"Fatal error (CC CS)",
|
|
"Fatal error (CC MD32)",
|
|
"Fatal error (CC C2K)",
|
|
"Fatal error (CC spc)"
|
|
};
|
|
|
|
static void strmncopy(char *src, char *dst, int src_len, int dst_len)
|
|
{
|
|
int temp_m, temp_n, temp_i;
|
|
|
|
temp_m = src_len - 1;
|
|
temp_n = dst_len - 1;
|
|
temp_n = (temp_m > temp_n) ? temp_n : temp_m;
|
|
for (temp_i = 0; temp_i < temp_n; temp_i++) {
|
|
dst[temp_i] = src[temp_i];
|
|
if (dst[temp_i] == 0x00)
|
|
break;
|
|
}
|
|
CCCI_DEBUG_LOG(-1, FSM, "copy str(%d) %s\n", temp_i, dst);
|
|
}
|
|
|
|
static int mdee_pl_core_parse(int md_id, struct debug_info_t *debug_info,
|
|
struct ex_PL_log *ex_PLloginfo)
|
|
{
|
|
int ee_type = 0;
|
|
int ee_case = 0;
|
|
|
|
ee_type = ex_PLloginfo->header.ex_type;
|
|
debug_info->type = ee_type;
|
|
ee_case = ee_type;
|
|
CCCI_ERROR_LOG(md_id, FSM, "PL ex type(0x%x)\n", ee_type);
|
|
switch (ee_type) {
|
|
case MD_EX_PL_INVALID:
|
|
debug_info->name = "INVALID";
|
|
break;
|
|
case MD_EX_CC_INVALID_EXCEPTION:
|
|
/* Fall through */
|
|
case MD_EX_CC_PCORE_EXCEPTION:
|
|
/* Fall through */
|
|
case MD_EX_CC_L1CORE_EXCEPTION:
|
|
/* Fall through */
|
|
case MD_EX_CC_CS_EXCEPTION:
|
|
/* Fall through */
|
|
case MD_EX_CC_MD32_EXCEPTION:
|
|
/* Fall through */
|
|
case MD_EX_CC_C2K_EXCEPTION:
|
|
/* Fall through */
|
|
case MD_EX_CC_ARM7_EXCEPTION:
|
|
/*
|
|
* md1:(MCU_PCORE)
|
|
* [Fatal error (CC xxx)]
|
|
* err_code1:0x00000xx err_code2:0x00xxx err_code3:0xxxx
|
|
* Offender:
|
|
*/
|
|
ee_type = ee_type - MD_EX_CC_INVALID_EXCEPTION
|
|
+ MD_EX_PL_FATALE_TOTAL;
|
|
/* Fall through */
|
|
case MD_EX_PL_UNDEF:
|
|
/* Fall through */
|
|
case MD_EX_PL_SWI:
|
|
/* Fall through */
|
|
case MD_EX_PL_PREF_ABT:
|
|
/* Fall through */
|
|
case MD_EX_PL_DATA_ABT:
|
|
/* Fall through */
|
|
case MD_EX_PL_STACKACCESS:
|
|
/* Fall through */
|
|
case MD_EX_PL_FATALERR_TASK:
|
|
/* Fall through */
|
|
case MD_EX_PL_FATALERR_BUF:
|
|
/* all offender is zero,
|
|
* goto from tail of function, reparser.
|
|
*/
|
|
/* the only one case: none offender, c2k ee */
|
|
if (ee_type ==
|
|
(MD_EX_CC_C2K_EXCEPTION
|
|
- MD_EX_CC_INVALID_EXCEPTION +
|
|
MD_EX_PL_FATALE_TOTAL))
|
|
debug_info->type = MD_EX_CC_C2K_EXCEPTION;
|
|
else
|
|
debug_info->type = MD_EX_DUMP_3P_EX;
|
|
debug_info->name = mdee_plstr[ee_type];
|
|
if (ex_PLloginfo->content.fatalerr.ex_analy.owner[0] != 0xCC) {
|
|
strmncopy(ex_PLloginfo->content.fatalerr.ex_analy.owner,
|
|
debug_info->fatal_error.offender,
|
|
sizeof(ex_PLloginfo->content.fatalerr.ex_analy.owner),
|
|
sizeof(debug_info->fatal_error.offender));
|
|
CCCI_NORMAL_LOG(md_id, FSM, "offender: %s\n",
|
|
debug_info->fatal_error.offender);
|
|
}
|
|
debug_info->fatal_error.err_code1 =
|
|
ex_PLloginfo->content.fatalerr.error_code.code1;
|
|
debug_info->fatal_error.err_code2 =
|
|
ex_PLloginfo->content.fatalerr.error_code.code2;
|
|
debug_info->fatal_error.err_code3 =
|
|
ex_PLloginfo->content.fatalerr.error_code.code3;
|
|
if (ex_PLloginfo->content.fatalerr.ex_analy.is_cadefa_sup
|
|
== 0x01)
|
|
debug_info->fatal_error.ExStr = "CaDeFa Supported\n";
|
|
else
|
|
debug_info->fatal_error.ExStr = "";
|
|
break;
|
|
case MD_EX_PL_ASSERT_FAIL:
|
|
/* Fall through */
|
|
case MD_EX_PL_ASSERT_DUMP:
|
|
/* Fall through */
|
|
case MD_EX_PL_ASSERT_NATIVE:
|
|
debug_info->type = MD_EX_DUMP_ASSERT;/* = MD_EX_TYPE_ASSERT; */
|
|
debug_info->name = "ASSERT";
|
|
CCCI_DEBUG_LOG(md_id, FSM, "p filename1(%s)\n",
|
|
ex_PLloginfo->content.assert.filepath);
|
|
strmncopy(ex_PLloginfo->content.assert.filepath,
|
|
debug_info->assert.file_name,
|
|
sizeof(ex_PLloginfo->content.assert.filepath),
|
|
sizeof(debug_info->assert.file_name));
|
|
CCCI_DEBUG_LOG(md_id, FSM,
|
|
"p filename2:(%s)\n", debug_info->assert.file_name);
|
|
debug_info->assert.line_num =
|
|
ex_PLloginfo->content.assert.linenumber;
|
|
debug_info->assert.parameters[0] =
|
|
ex_PLloginfo->content.assert.para[0];
|
|
debug_info->assert.parameters[1] =
|
|
ex_PLloginfo->content.assert.para[1];
|
|
debug_info->assert.parameters[2] =
|
|
ex_PLloginfo->content.assert.para[2];
|
|
break;
|
|
|
|
case EMI_MPU_VIOLATION:
|
|
debug_info->type = MD_EX_DUMP_EMI_CHECK;
|
|
ee_case = MD_EX_TYPE_EMI_CHECK;
|
|
debug_info->name = "Fatal error (rmpu violation)";
|
|
debug_info->fatal_error.err_code1 =
|
|
ex_PLloginfo->content.fatalerr.error_code.code1;
|
|
debug_info->fatal_error.err_code2 =
|
|
ex_PLloginfo->content.fatalerr.error_code.code2;
|
|
debug_info->fatal_error.err_code3 =
|
|
ex_PLloginfo->content.fatalerr.error_code.code3;
|
|
debug_info->fatal_error.ExStr = "EMI MPU VIOLATION\n";
|
|
break;
|
|
default:
|
|
debug_info->name = "UNKNOWN Exception";
|
|
break;
|
|
}
|
|
debug_info->ext_mem = ex_PLloginfo;
|
|
debug_info->ext_size = sizeof(struct ex_PL_log);
|
|
|
|
return ee_case;
|
|
}
|
|
|
|
|
|
static int mdee_cs_core_parse(int md_id, struct debug_info_t *debug_info,
|
|
struct ex_cs_log *ex_csLogInfo)
|
|
{
|
|
int ee_type = 0;
|
|
int ee_case = 0;
|
|
|
|
ee_type = ex_csLogInfo->except_type;
|
|
CCCI_ERROR_LOG(md_id, FSM, "cs ex type(0x%x)\n", ee_type);
|
|
switch (ee_type) {
|
|
case CS_EXCEPTION_ASSERTION:
|
|
debug_info->type = MD_EX_DUMP_ASSERT;
|
|
ee_case = MD_EX_TYPE_ASSERT;
|
|
|
|
debug_info->name = "ASSERT";
|
|
strmncopy(ex_csLogInfo->except_content.assert.file_name,
|
|
debug_info->assert.file_name,
|
|
sizeof(ex_csLogInfo->except_content.assert.file_name),
|
|
sizeof(debug_info->assert.file_name));
|
|
debug_info->assert.line_num =
|
|
ex_csLogInfo->except_content.assert.line_num;
|
|
debug_info->assert.parameters[0] =
|
|
ex_csLogInfo->except_content.assert.para1;
|
|
debug_info->assert.parameters[1] =
|
|
ex_csLogInfo->except_content.assert.para2;
|
|
debug_info->assert.parameters[2] =
|
|
ex_csLogInfo->except_content.assert.para3;
|
|
break;
|
|
case CS_EXCEPTION_FATAL_ERROR:
|
|
debug_info->type = MD_EX_DUMP_2P_EX;
|
|
ee_case = MD_EX_TYPE_FATALERR_TASK;
|
|
|
|
debug_info->name = "Fatal error";
|
|
debug_info->fatal_error.err_code1 =
|
|
ex_csLogInfo->except_content.fatalerr.error_code1;
|
|
debug_info->fatal_error.err_code2 =
|
|
ex_csLogInfo->except_content.fatalerr.error_code2;
|
|
break;
|
|
case CS_EXCEPTION_CTI_EVENT:
|
|
debug_info->name = "CC CTI Exception";
|
|
break;
|
|
case CS_EXCEPTION_UNKNOWN:
|
|
default:
|
|
debug_info->name = "UNKNOWN Exception";
|
|
break;
|
|
}
|
|
debug_info->ext_mem = ex_csLogInfo;
|
|
debug_info->ext_size = sizeof(struct ex_cs_log);
|
|
return ee_case;
|
|
}
|
|
|
|
static int mdee_md32_core_parse(int md_id, struct debug_info_t *debug_info,
|
|
struct ex_md32_log *ex_md32LogInfo)
|
|
{
|
|
int ee_type = 0;
|
|
int ee_case = 0;
|
|
char core_name_temp[MD_CORE_NAME_DEBUG];
|
|
int ret = 0;
|
|
|
|
ee_type = ex_md32LogInfo->except_type;
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"md32 ex type(0x%x), name: %s\n", ee_type,
|
|
ex_md32LogInfo->except_content.assert.file_name);
|
|
ret = snprintf(core_name_temp,
|
|
MD_CORE_NAME_DEBUG, "%s", debug_info->core_name);
|
|
if (ret < 0 || ret >= MD_CORE_NAME_DEBUG)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d\n",
|
|
__func__, __LINE__, ret);
|
|
switch (ex_md32LogInfo->md32_active_mode) {
|
|
case 1:
|
|
ret = snprintf(debug_info->core_name, MD_CORE_NAME_DEBUG, "%s%s",
|
|
core_name_temp, MD32_FDD_ROCODE);
|
|
break;
|
|
case 2:
|
|
ret = snprintf(debug_info->core_name, MD_CORE_NAME_DEBUG, "%s%s",
|
|
core_name_temp, MD32_TDD_ROCODE);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (ret < 0 || ret >= MD_CORE_NAME_DEBUG)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d,mode=%d\n",
|
|
__func__, __LINE__, ret, ex_md32LogInfo->md32_active_mode);
|
|
switch (ee_type) {
|
|
case CMIF_MD32_EX_ASSERT_LINE:
|
|
/* Fall through */
|
|
case CMIF_MD32_EX_ASSERT_EXT:
|
|
debug_info->type = MD_EX_DUMP_ASSERT;
|
|
ee_case = MD_EX_TYPE_ASSERT;
|
|
debug_info->name = "ASSERT";
|
|
strmncopy(ex_md32LogInfo->except_content.assert.file_name,
|
|
debug_info->assert.file_name,
|
|
sizeof(ex_md32LogInfo->except_content.assert.file_name),
|
|
sizeof(debug_info->assert.file_name));
|
|
debug_info->assert.line_num =
|
|
ex_md32LogInfo->except_content.assert.line_num;
|
|
debug_info->assert.parameters[0] =
|
|
ex_md32LogInfo->except_content.assert.ex_code[0];
|
|
debug_info->assert.parameters[1] =
|
|
ex_md32LogInfo->except_content.assert.ex_code[1];
|
|
debug_info->assert.parameters[2] =
|
|
ex_md32LogInfo->except_content.assert.ex_code[2];
|
|
break;
|
|
case CMIF_MD32_EX_FATAL_ERROR:
|
|
/* Fall through */
|
|
case CMIF_MD32_EX_FATAL_ERROR_EXT:
|
|
debug_info->type = MD_EX_DUMP_2P_EX;
|
|
ee_case = MD_EX_TYPE_FATALERR_TASK;
|
|
|
|
debug_info->name = "Fatal error";
|
|
debug_info->fatal_error.err_code1 =
|
|
ex_md32LogInfo->except_content.fatalerr.ex_code[0];
|
|
debug_info->fatal_error.err_code2 =
|
|
ex_md32LogInfo->except_content.fatalerr.ex_code[1];
|
|
break;
|
|
case CS_EXCEPTION_CTI_EVENT:
|
|
/* Fall through */
|
|
case CS_EXCEPTION_UNKNOWN:
|
|
default:
|
|
debug_info->name = "UNKNOWN Exception";
|
|
break;
|
|
}
|
|
debug_info->ext_mem = ex_md32LogInfo;
|
|
debug_info->ext_size = sizeof(struct ex_md32_log);
|
|
|
|
return ee_case;
|
|
}
|
|
|
|
static void mdee_set_core_name(int md_id, struct debug_info_t *debug_info,
|
|
char *core_name)
|
|
{
|
|
unsigned int temp_i;
|
|
/* (core name):
|
|
* PCORE/L1CORE/CS_ICC/CS_IMC/CS_MPC/MD32_BRP/MD32_DFE/MD32_RAKE
|
|
*/
|
|
debug_info->core_name[0] = '(';
|
|
for (temp_i = 1; temp_i < MD_CORE_NAME_LEN; temp_i++) {
|
|
debug_info->core_name[temp_i] = core_name[temp_i - 1];
|
|
if (debug_info->core_name[temp_i] == '\0')
|
|
break;
|
|
}
|
|
debug_info->core_name[temp_i++] = ')';
|
|
debug_info->core_name[temp_i] = '\0';
|
|
}
|
|
|
|
static void mdee_info_prepare_v2(struct ccci_fsm_ee *mdee)
|
|
{
|
|
struct ex_overview_t *ex_overview;
|
|
int ee_case = 0;
|
|
struct mdee_dumper_v2 *dumper = mdee->dumper_obj;
|
|
int md_id = mdee->md_id;
|
|
struct debug_info_t *debug_info = NULL;
|
|
int core_id;
|
|
/* number of offender core: need parse */
|
|
unsigned char off_core_num = 0;
|
|
int ret = 0;
|
|
|
|
struct ex_PL_log *ex_pl_info = (struct ex_PL_log *)dumper->ex_pl_info;
|
|
struct ex_PL_log *ex_PLloginfo;
|
|
struct ex_cs_log *ex_csLogInfo;
|
|
struct ex_md32_log *ex_md32LogInfo;
|
|
struct ccci_smem_region *mdss_dbg =
|
|
ccci_md_get_smem_by_user_id(mdee->md_id, SMEM_USER_RAW_MDSS_DBG);
|
|
|
|
CCCI_NORMAL_LOG(md_id, FSM,
|
|
"ccci_md_exp_change, ee_case(0x%x)\n", dumper->more_info);
|
|
|
|
if ((dumper->more_info == MD_EE_CASE_NORMAL)
|
|
&& (ccci_fsm_get_md_state(mdee->md_id)
|
|
== BOOT_WAITING_FOR_HS1)) {
|
|
debug_info = &dumper->debug_info[0];
|
|
ex_PLloginfo = ex_pl_info;
|
|
off_core_num++;
|
|
ret = snprintf(debug_info->core_name,
|
|
MD_CORE_NAME_DEBUG, "(MCU_PCORE)");
|
|
if (ret < 0 || ret >= MD_CORE_NAME_DEBUG)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d\n",
|
|
__func__, __LINE__, ret);
|
|
ee_case = mdee_pl_core_parse(md_id,
|
|
debug_info, ex_PLloginfo);
|
|
mdee->ex_type = ee_case;
|
|
dumper->ex_core_num = off_core_num;
|
|
CCCI_NORMAL_LOG(md_id, FSM, "core_ex_num(%d/%d)\n",
|
|
off_core_num, dumper->ex_core_num);
|
|
return;
|
|
}
|
|
|
|
ex_overview = (struct ex_overview_t *) mdss_dbg->base_ap_view_vir;
|
|
for (core_id = 0; core_id < MD_CORE_NUM; core_id++) {
|
|
CCCI_DEBUG_LOG(md_id, FSM,
|
|
"core_id(%x/%x): offset=%x, if_offender=%d, %s\n",
|
|
(core_id + 1),
|
|
ex_overview->core_num,
|
|
ex_overview->main_reson[core_id].core_offset,
|
|
ex_overview->main_reson[core_id].is_offender,
|
|
ex_overview->main_reson[core_id].core_name);
|
|
if (ex_overview->main_reson[core_id].is_offender == 0)
|
|
continue;
|
|
debug_info = &dumper->debug_info[off_core_num];
|
|
memset(debug_info, 0, sizeof(struct debug_info_t));
|
|
|
|
off_core_num++;
|
|
mdee_set_core_name(md_id, debug_info,
|
|
ex_overview->main_reson[core_id].core_name);
|
|
CCCI_NORMAL_LOG(md_id, FSM,
|
|
"core_id(0x%x/%d), %s\n",
|
|
core_id, off_core_num,
|
|
debug_info->core_name);
|
|
ex_pl_info->envinfo.ELM_status = 0;
|
|
switch (core_id) {
|
|
case MD_PCORE:
|
|
case MD_L1CORE:
|
|
ex_PLloginfo =
|
|
(struct ex_PL_log *) ((char *)ex_overview +
|
|
ex_overview->main_reson[core_id].core_offset);
|
|
ex_pl_info->envinfo.ELM_status =
|
|
ex_PLloginfo->envinfo.ELM_status;
|
|
ee_case = mdee_pl_core_parse(md_id,
|
|
debug_info, ex_PLloginfo);
|
|
break;
|
|
case MD_CS_ICC:
|
|
/* Fall through */
|
|
case MD_CS_IMC:
|
|
/* Fall through */
|
|
case MD_CS_MPC:
|
|
ex_csLogInfo =
|
|
(struct ex_cs_log *) ((char *)ex_overview +
|
|
ex_overview->main_reson[core_id].core_offset);
|
|
ee_case = mdee_cs_core_parse(md_id,
|
|
debug_info, ex_csLogInfo);
|
|
break;
|
|
case MD_MD32_DFE:
|
|
/* Fall through */
|
|
case MD_MD32_BRP:
|
|
/* Fall through */
|
|
case MD_MD32_RAKE:
|
|
ex_md32LogInfo =
|
|
(struct ex_md32_log *) ((char *)ex_overview +
|
|
ex_overview->main_reson[core_id].core_offset);
|
|
ee_case = mdee_md32_core_parse(md_id,
|
|
debug_info, ex_md32LogInfo);
|
|
break;
|
|
default:
|
|
ee_case = 0;
|
|
break;
|
|
}
|
|
if (off_core_num == 1) {
|
|
mdee->ex_type = ee_case;
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"set ee_type=%d\n", mdee->ex_type);
|
|
}
|
|
}
|
|
|
|
if (off_core_num == 0) {
|
|
debug_info = &dumper->debug_info[0];
|
|
ex_PLloginfo = (struct ex_PL_log *) ((char *)ex_overview +
|
|
ex_overview->main_reson[MD_PCORE].core_offset);
|
|
ex_pl_info->envinfo.ELM_status =
|
|
ex_PLloginfo->envinfo.ELM_status;
|
|
off_core_num++;
|
|
core_id = MD_CORE_NUM;
|
|
ret = snprintf(debug_info->core_name,
|
|
MD_CORE_NAME_DEBUG, "(MCU_PCORE)");
|
|
if (ret < 0 || ret >= MD_CORE_NAME_DEBUG)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d\n",
|
|
__func__, __LINE__, ret);
|
|
ee_case = mdee_pl_core_parse(md_id,
|
|
debug_info, ex_PLloginfo);
|
|
mdee->ex_type = ee_case;
|
|
}
|
|
|
|
dumper->ex_core_num = off_core_num;
|
|
CCCI_ERROR_LOG(md_id, FSM, "core_ex_num(%d/%d) ee_type=%d\n",
|
|
off_core_num, dumper->ex_core_num, mdee->ex_type);
|
|
}
|
|
|
|
static void mdee_dumper_v2_set_ee_pkg(struct ccci_fsm_ee *mdee,
|
|
char *data, int len)
|
|
{
|
|
struct mdee_dumper_v2 *dumper = mdee->dumper_obj;
|
|
int cpy_len =
|
|
len > MD_HS1_FAIL_DUMP_SIZE ? MD_HS1_FAIL_DUMP_SIZE : len;
|
|
|
|
memcpy(dumper->ex_pl_info, data, cpy_len);
|
|
}
|
|
|
|
static void mdee_dumper_v2_dump_ee_info(struct ccci_fsm_ee *mdee,
|
|
enum MDEE_DUMP_LEVEL level, int more_info)
|
|
{
|
|
struct mdee_dumper_v2 *dumper = mdee->dumper_obj;
|
|
int md_id = mdee->md_id;
|
|
struct ccci_smem_region *mdccci_dbg =
|
|
ccci_md_get_smem_by_user_id(mdee->md_id,
|
|
SMEM_USER_RAW_MDCCCI_DBG);
|
|
struct ccci_smem_region *mdss_dbg =
|
|
ccci_md_get_smem_by_user_id(mdee->md_id,
|
|
SMEM_USER_RAW_MDSS_DBG);
|
|
int md_state = ccci_fsm_get_md_state(mdee->md_id);
|
|
char ex_info[EE_BUF_LEN] = {0};
|
|
struct ccci_per_md *per_md_data =
|
|
ccci_get_per_md_data(mdee->md_id);
|
|
int md_dbg_dump_flag = per_md_data->md_dbg_dump_flag;
|
|
int ret = 0;
|
|
|
|
dumper->more_info = more_info;
|
|
if (level == MDEE_DUMP_LEVEL_BOOT_FAIL) {
|
|
if (md_state == BOOT_WAITING_FOR_HS1) {
|
|
ret = snprintf(ex_info, EE_BUF_LEN,
|
|
"\n[Others] MD_BOOT_UP_FAIL(HS%d)\n", 1);
|
|
/* Handshake 1 fail */
|
|
ccci_aed_v2(mdee,
|
|
CCCI_AED_DUMP_CCIF_REG
|
|
| CCCI_AED_DUMP_MD_IMG_MEM
|
|
| CCCI_AED_DUMP_EX_MEM,
|
|
ex_info, DB_OPT_DEFAULT);
|
|
} else if (md_state == BOOT_WAITING_FOR_HS2) {
|
|
ret = snprintf(ex_info, EE_BUF_LEN,
|
|
"\n[Others] MD_BOOT_UP_FAIL(HS%d)\n", 2);
|
|
/* Handshake 2 fail */
|
|
CCCI_MEM_LOG_TAG(md_id, FSM, "Dump MD EX log\n");
|
|
if (md_dbg_dump_flag & (1 << MD_DBG_DUMP_SMEM)) {
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
mdccci_dbg->base_ap_view_vir,
|
|
mdccci_dbg->size);
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
mdss_dbg->base_ap_view_vir,
|
|
mdss_dbg->size);
|
|
}
|
|
|
|
ccci_aed_v2(mdee,
|
|
CCCI_AED_DUMP_CCIF_REG
|
|
| CCCI_AED_DUMP_EX_MEM,
|
|
ex_info, DB_OPT_FTRACE);
|
|
}
|
|
if (ret < 0 || ret >= EE_BUF_LEN)
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s-%d:snprintf fail,ret=%d,md_state=%d\n",
|
|
__func__, __LINE__, ret, md_state);
|
|
} else if (level == MDEE_DUMP_LEVEL_STAGE1) {
|
|
if (md_dbg_dump_flag & (1 << MD_DBG_DUMP_SMEM)) {
|
|
CCCI_MEM_LOG_TAG(md_id, FSM,
|
|
"Dump MD exp smem_mdccci_debug_log\n");
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
mdccci_dbg->base_ap_view_vir, mdccci_dbg->size);
|
|
CCCI_MEM_LOG_TAG(md_id, FSM,
|
|
"Dump MD exp smem_mdss_debug_log\n");
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
mdss_dbg->base_ap_view_vir, 512);
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
(mdss_dbg->base_ap_view_vir + 6 * 1024), 2048);
|
|
}
|
|
} else if (level == MDEE_DUMP_LEVEL_STAGE2) {
|
|
mdee_info_prepare_v2(mdee);
|
|
mdee_info_dump_v2(mdee);
|
|
}
|
|
}
|
|
|
|
static struct md_ee_ops mdee_ops_v2 = {
|
|
.dump_ee_info = &mdee_dumper_v2_dump_ee_info,
|
|
.set_ee_pkg = &mdee_dumper_v2_set_ee_pkg,
|
|
};
|
|
int mdee_dumper_v2_alloc(struct ccci_fsm_ee *mdee)
|
|
{
|
|
struct mdee_dumper_v2 *dumper;
|
|
int md_id = mdee->md_id;
|
|
|
|
/* Allocate port_proxy obj and set all member zero */
|
|
dumper = kzalloc(sizeof(struct mdee_dumper_v2), GFP_KERNEL);
|
|
if (dumper == NULL) {
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s:alloc mdee_parser_v2 fail\n", __func__);
|
|
return -1;
|
|
}
|
|
mdee->dumper_obj = dumper;
|
|
mdee->ops = &mdee_ops_v2;
|
|
return 0;
|
|
}
|
|
|