mirror of
https://github.com/physwizz/a155-U-u1.git
synced 2025-09-16 03:59:21 +00:00
898 lines
28 KiB
C
898 lines
28 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>
|
|
#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
|
|
#include <mt-plat/aee.h>
|
|
#endif
|
|
#include <soc/mediatek/emi.h>
|
|
#include "mdee_dumper_v3.h"
|
|
#include "ccci_config.h"
|
|
#include "ccci_common_config.h"
|
|
#include "ccci_fsm_sys.h"
|
|
#include "ccci_platform.h"
|
|
#include "md_sys1_platform.h"
|
|
#include "modem_sys.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
|
|
|
|
static void ccci_aed_v3(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_dump_addr = NULL;
|
|
int md_dump_len = 0;
|
|
int info_str_len = 0;
|
|
char *buff; /*[AED_STR_LEN]; */
|
|
#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
|
|
char buf_fail[] = "Fail alloc mem for exception\n";
|
|
#endif
|
|
char *img_inf = NULL;
|
|
struct mdee_dumper_v3 *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_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
|
|
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;
|
|
#endif
|
|
|
|
buff = kmalloc(AED_STR_LEN, GFP_ATOMIC);
|
|
if (buff == NULL) {
|
|
CCCI_ERROR_LOG(md_id, FSM, "Fail alloc Mem for buff!\n");
|
|
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';
|
|
scnprintf(buff, AED_STR_LEN, "md%d:%s%s%s",
|
|
md_id + 1, aed_str, mdee->ex_start_time, img_inf);
|
|
memset(mdee->ex_start_time, 0x0, sizeof(mdee->ex_start_time));
|
|
/* 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_REG | DUMP_FLAG_CCIF,
|
|
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 (md && md->hw_info && md->hw_info->md_l2sram_base) {
|
|
md_dump_addr = md->hw_info->md_l2sram_base;
|
|
md_dump_len = MD_L2SRAM_SIZE_V3;
|
|
}
|
|
}
|
|
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 (buff == NULL) {
|
|
fsm_sys_mdee_info_notify(aed_str);
|
|
#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
|
|
if (md_dump_len)
|
|
md_cd_lock_modem_clock_src(1);
|
|
if (md_dbg_dump_flag & (1U << MD_DBG_DUMP_SMEM))
|
|
aed_md_exception_api(ex_log_addr, ex_log_len,
|
|
md_dump_addr, md_dump_len, buf_fail, db_opt);
|
|
else
|
|
aed_md_exception_api(NULL, 0, md_dump_addr,
|
|
md_dump_len, buf_fail, db_opt);
|
|
if (md_dump_len)
|
|
md_cd_lock_modem_clock_src(0);
|
|
#endif
|
|
} else {
|
|
fsm_sys_mdee_info_notify(aed_str);
|
|
#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
|
|
if (md_dump_len)
|
|
md_cd_lock_modem_clock_src(1);
|
|
if (md_dbg_dump_flag & (1 << MD_DBG_DUMP_SMEM))
|
|
aed_md_exception_api(ex_log_addr, ex_log_len,
|
|
md_dump_addr, md_dump_len, buff, db_opt);
|
|
else
|
|
aed_md_exception_api(NULL, 0, md_dump_addr,
|
|
md_dump_len, buff, db_opt);
|
|
if (md_dump_len)
|
|
md_cd_lock_modem_clock_src(0);
|
|
#endif
|
|
kfree(buff);
|
|
}
|
|
CCCI_ERROR_LOG(md_id, FSM, "%s end!\n", __func__);
|
|
}
|
|
|
|
static char mdee_more_inf_str[MD_EE_CASE_WDT + 1][64] = {
|
|
"",
|
|
"\nOnly SWINT case\n",
|
|
"\nOnly EX case\n",
|
|
"\n[Others] MD long time no response\n",
|
|
"\n[Others] MD watchdog timeout interrupt\n"
|
|
};
|
|
|
|
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 = NULL;
|
|
char *ex_info_temp = NULL;
|
|
|
|
switch (debug_info->type) {
|
|
case MD_EX_CLASS_ASSET:
|
|
/* assert: file name+line number+code*3 */
|
|
scnprintf(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->dump_assert.file_name,
|
|
debug_info->dump_assert.line_num,
|
|
debug_info->dump_assert.parameters[0],
|
|
debug_info->dump_assert.parameters[1],
|
|
debug_info->dump_assert.parameters[2]);
|
|
|
|
CCCI_ERROR_LOG(md_id, FSM, "filename = %s\n",
|
|
debug_info->dump_assert.file_name);
|
|
CCCI_ERROR_LOG(md_id, FSM, "line = %d\n",
|
|
debug_info->dump_assert.line_num);
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"assert para0 = 0x%08x, para1 = 0x%08x, para2 = 0x%08x\n",
|
|
debug_info->dump_assert.parameters[0],
|
|
debug_info->dump_assert.parameters[1],
|
|
debug_info->dump_assert.parameters[2]);
|
|
break;
|
|
case MD_EX_CLASS_FATAL:
|
|
/* fatal: */
|
|
scnprintf(ex_info, EE_BUF_LEN_UMOLY,
|
|
"(%s)%s\n[%s] err_code1:0x%08X err_code2:0x%08X err_code3:0x%08X\n%s%s\n%s\n",
|
|
debug_info->core_name,
|
|
debug_info->dump_fatal.err_sec, debug_info->name,
|
|
debug_info->dump_fatal.err_code1,
|
|
debug_info->dump_fatal.err_code2,
|
|
debug_info->dump_fatal.err_code3,
|
|
debug_info->dump_fatal.offender,
|
|
debug_info->dump_fatal.ExStr,
|
|
debug_info->dump_fatal.fatal_fname);
|
|
|
|
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;
|
|
}
|
|
scnprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%s", ex_info);
|
|
if (debug_info->dump_fatal.err_code1 == 0x3104) {
|
|
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;
|
|
}
|
|
scnprintf(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);
|
|
memset(mdee->ex_mpu_string, 0x0,
|
|
sizeof(mdee->ex_mpu_string));
|
|
}
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"fatal error code 1,2,3 = [0x%08X, 0x%08X, 0x%08X]%s\n",
|
|
debug_info->dump_fatal.err_code1,
|
|
debug_info->dump_fatal.err_code2,
|
|
debug_info->dump_fatal.err_code3,
|
|
debug_info->dump_fatal.offender);
|
|
kfree(ex_info_temp);
|
|
break;
|
|
case MD_EX_CLASS_CUSTOM:
|
|
/* fatal: */
|
|
scnprintf(ex_info, EE_BUF_LEN_UMOLY,
|
|
"(%s)%s\n[%s] err_code1:0x%08X err_code2:0x%08X err_code3:0x%08X\n%s%s\n%s\nP1:0x%08X\nP2:0x%08X\nP3:0x%08X\n",
|
|
debug_info->core_name,
|
|
debug_info->dump_fatal.err_sec, debug_info->name,
|
|
debug_info->ex_type,
|
|
debug_info->dump_fatal.error_address,
|
|
debug_info->dump_fatal.error_pc,
|
|
debug_info->dump_fatal.offender,
|
|
debug_info->dump_fatal.ExStr,
|
|
debug_info->dump_fatal.fatal_fname,
|
|
debug_info->dump_fatal.err_code1,
|
|
debug_info->dump_fatal.err_code2,
|
|
debug_info->dump_fatal.err_code3);
|
|
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"fatal custom error code 1,2,3 = [0x%08X, 0x%08X, 0x%08X]%s\n",
|
|
debug_info->dump_fatal.err_code1,
|
|
debug_info->dump_fatal.err_code2,
|
|
debug_info->dump_fatal.err_code3,
|
|
debug_info->dump_fatal.offender);
|
|
break;
|
|
default:
|
|
scnprintf(ex_info, EE_BUF_LEN_UMOLY, "%s\n[%s]\n",
|
|
debug_info->core_name, debug_info->name);
|
|
break;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
static void mdee_info_dump_v3(struct ccci_fsm_ee *mdee)
|
|
{
|
|
int md_id = mdee->md_id;
|
|
char *ex_info; /* aed api par4 */
|
|
char *ex_info_temp = NULL;
|
|
int db_opt = (DB_OPT_DEFAULT | DB_OPT_FTRACE); /* aed api par5 */
|
|
int dump_flag = 0;
|
|
char *i_bit_ex_info = NULL;
|
|
char buf_fail[] = "Fail alloc mem for exception\n";
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
struct mdee_dumper_v3 *dumper = mdee->dumper_obj;
|
|
struct debug_info_t *debug_info = &dumper->debug_info;
|
|
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 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;
|
|
|
|
ex_info = kmalloc(AED_STR_LEN, 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 = kzalloc(AED_STR_LEN, GFP_ATOMIC);
|
|
if (ex_info_temp == NULL) {
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"Fail alloc Mem for ex_info_temp!\n");
|
|
goto err_exit;
|
|
}
|
|
|
|
switch (dumper->more_info) {
|
|
case MD_EE_CASE_ONLY_EX:
|
|
case MD_EE_CASE_ONLY_SWINT:
|
|
mdee_output_debug_info_to_buf(mdee, debug_info, ex_info);
|
|
scnprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%s", ex_info);
|
|
scnprintf(ex_info, EE_BUF_LEN_UMOLY, "%s%s", ex_info_temp,
|
|
mdee_more_inf_str[dumper->more_info]);
|
|
break;
|
|
case MD_EE_CASE_NO_RESPONSE:
|
|
/* use strncpy, otherwise if this happens after a MD EE,
|
|
* the former EE info will be printed out
|
|
*/
|
|
db_opt |= (unsigned int)DB_OPT_FTRACE;
|
|
/* fall through */
|
|
case MD_EE_CASE_WDT:
|
|
if (scnprintf(ex_info, EE_BUF_LEN_UMOLY, "%s",
|
|
mdee_more_inf_str[dumper->more_info]) < 0)
|
|
ex_info[0] = 0;
|
|
break;
|
|
default:
|
|
mdee_output_debug_info_to_buf(mdee, debug_info, ex_info);
|
|
break;
|
|
}
|
|
|
|
if (debug_info->ELM_status != NULL) {
|
|
scnprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%s", ex_info);
|
|
scnprintf(ex_info, EE_BUF_LEN_UMOLY, "%s%s", ex_info_temp,
|
|
debug_info->ELM_status);/* ELM status */
|
|
}
|
|
|
|
CCCI_MEM_LOG_TAG(md_id, FSM, "Dump MD EX log, 0x%x, 0x%x\n",
|
|
dumper->more_info, debug_info->par_data_source);
|
|
if (debug_info->par_data_source == MD_EE_DATA_IN_GPD) {
|
|
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)) {
|
|
dump_flag = CCCI_AED_DUMP_EX_MEM;
|
|
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);
|
|
if (md && md->hw_info && md->hw_info->md_l2sram_base) {
|
|
md_cd_lock_modem_clock_src(1);
|
|
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
md->hw_info->md_l2sram_base, MD_L2SRAM_SIZE_V3);
|
|
|
|
md_cd_lock_modem_clock_src(0);
|
|
}
|
|
}
|
|
|
|
err_exit:
|
|
/* update here to maintain handshake stage info
|
|
* during exception handling
|
|
*/
|
|
if (debug_info->ex_type == CC_C2K_EXCEPTION)
|
|
CCCI_NORMAL_LOG(md_id, FSM, "C2K EE, No need trigger DB\n");
|
|
else if (ex_info == NULL)
|
|
ccci_aed_v3(mdee, dump_flag, buf_fail, db_opt);
|
|
else
|
|
ccci_aed_v3(mdee, dump_flag, ex_info, db_opt);
|
|
|
|
kfree(ex_info);
|
|
kfree(ex_info_temp);
|
|
kfree(i_bit_ex_info);
|
|
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
static struct ex_overview_t *md_ee_get_buf_ptr(struct ccci_fsm_ee *mdee,
|
|
u8 *buf_type)
|
|
{
|
|
unsigned int ccif_sram[CCCI_EE_SIZE_CCIF_SRAM/sizeof(unsigned int)]
|
|
= { 0 };
|
|
struct mdee_dumper_v3 *dumper = mdee->dumper_obj;
|
|
struct ccci_smem_region *mdss_dbg =
|
|
ccci_md_get_smem_by_user_id(mdee->md_id,
|
|
SMEM_USER_RAW_MDSS_DBG);
|
|
struct ex_overview_t *tar_ptr = NULL;
|
|
|
|
if (mdee->md_id == MD_SYS1)
|
|
ccci_md_dump_info(mdee->md_id, DUMP_FLAG_CCIF, ccif_sram, 0);
|
|
if (((dumper->more_info == MD_EE_CASE_NORMAL)
|
|
&& (mdee->ee_info_flag&MD_EE_DUMP_IN_GPD))
|
|
|| ((mdee->md_id == MD_SYS1)
|
|
&& (ccif_sram[1] < 0x208)
|
|
&& (ccif_sram[1] >= 0x200))) {
|
|
*buf_type = MD_EE_DATA_IN_GPD;
|
|
tar_ptr = (struct ex_overview_t *)dumper->ex_pl_info;
|
|
CCCI_NORMAL_LOG(mdee->md_id, FSM,
|
|
"parsing data from: GPD %p, %p\n",
|
|
tar_ptr, dumper->ex_pl_info);
|
|
} else {
|
|
tar_ptr = (struct ex_overview_t *)mdss_dbg->base_ap_view_vir;
|
|
*buf_type = MD_EE_DATA_IN_SMEM;
|
|
}
|
|
return tar_ptr;
|
|
|
|
}
|
|
|
|
static int mdee_set_core_name(int md_id, char *core_name,
|
|
struct ex_overview_t *ex_overview)
|
|
{
|
|
int core_id;
|
|
u8 temp_sys_inf_1, temp_sys_inf_2;
|
|
struct ex_brief_maininfo *brief_info = NULL;
|
|
char core_name_temp[MD_CORE_NAME_DEBUG];
|
|
|
|
for (core_id = 0; core_id < ex_overview->core_num; core_id++) {
|
|
if (ex_overview->main_reson[core_id].is_offender) {
|
|
strmncopy(ex_overview->main_reson[core_id].core_name,
|
|
core_name,
|
|
sizeof(ex_overview->main_reson[core_id].core_name) + 1,
|
|
MD_CORE_NAME_DEBUG);
|
|
break; /* just show one core name */
|
|
}
|
|
}
|
|
|
|
if (core_id == 0) {
|
|
brief_info = &ex_overview->ex_info;
|
|
temp_sys_inf_1 = brief_info->system_info1;
|
|
temp_sys_inf_2 = brief_info->system_info2;
|
|
if (scnprintf(core_name_temp,
|
|
MD_CORE_NAME_DEBUG, "%s", core_name) < 0)
|
|
core_name_temp[0] = 0;
|
|
scnprintf(core_name, MD_CORE_NAME_DEBUG,
|
|
"%s_core%d,vpe%d,tc%d(VPE%d)", core_name_temp,
|
|
(temp_sys_inf_1>>1), (temp_sys_inf_1&0x1),
|
|
temp_sys_inf_2, temp_sys_inf_1);
|
|
}
|
|
CCCI_NORMAL_LOG(md_id, FSM,
|
|
"brief_info: core_name = %s", core_name);
|
|
return core_id;
|
|
}
|
|
|
|
static char *ee_type_str_v3_23h[] = {
|
|
[INTERRUPT_EXCEPTION] = "Fatal error(INTERRUPT)",
|
|
[TLB_MOD_EXCEPTION] = "Fatal error(TLB_MOD)",
|
|
[TLB_MISS_LOAD_EXCEPTION] = "Fatal error(TLB_MISS_LOAD)",
|
|
[TLB_MISS_STORE_EXCEPTION] = "Fatal error(TLB_MISS_STORE)",
|
|
[ADDRESS_ERROR_LOAD_EXCEPTION] = "Fatal error(ADDRESS_ERROR_LOAD)",
|
|
[ADDRESS_ERROR_STORE_EXCEPTION] = "Fatal error(ADDRESS_ERROR_STORE)",
|
|
[INSTR_BUS_ERROR] = "Fatal error(INSTR_BUS_ERROR)",
|
|
[DATA_BUS_ERROR] = "Fatal error(DATA_BUS_ERROR)",
|
|
[SYSTEM_CALL_EXCEPTION] = "Fatal error(SYSTEM_CALL)",
|
|
[BREAKPOINT_EXCEPTION] = "Fatal error(BREAKPOINT)",
|
|
[RESERVED_INSTRUCTION_EXCEPTION] = "Fatal error(RESERVED_INSTRUCTION)",
|
|
[COPROCESSORS_UNUSABLE_EXCEPTION] =
|
|
"Fatal error(COPROCESSORS_UNUSABLE)",
|
|
[INTEGER_OVERFLOW_EXCEPTION] = "Fatal error(INTEGER_OVERFLOW)",
|
|
[TRAP_EXCEPTION] = "Fatal error(TRAP)",
|
|
[MSA_FLOATING_POINT_EXCEPTION] = "Fatal error(MSA_FLOATING_POINT)",
|
|
[FLOATING_POINT_EXCEPTION] = "Fatal error(FLOATING_POINT)",
|
|
[COPROCESSOR_2_IS_1_EXCEPTION] = "Fatal error(COPROCESSOR_2_IS_1)",
|
|
[COR_EXTEND_UNUSABLE_EXCEPTION] = "Fatal error(COR_EXTEND_UNUSABLE)",
|
|
[COPROCESSOR_2_EXCEPTION] = "Fatal error(COPROCESSOR_2)",
|
|
[TLB_READ_INHIBIT_EXCEPTION] = "Fatal error(TLB_READ_INHIBIT)",
|
|
[TLB_EXECUTE_INHIBIT_EXCEPTION] = "Fatal error(TLB_EXECUTE_INHIBIT)",
|
|
[MSA_UNUSABLE_EXCEPTION] = "Fatal error(MSA_UNUSABLE)",
|
|
[MDMX_EXCEPTION] = "Fatal error(MDMX)",
|
|
[WATCH_EXCEPTION] = "Fatal error(WATCH)",
|
|
[MCHECK_EXCEPTION] = "Fatal error(MCHECK)",
|
|
[THREAD_EXCEPTION] = "Fatal error(THREAD)",
|
|
[DSP_UNUSABLE_EXCEPTION] = "Fatal error(DSP_UNUSABLE)",
|
|
[RESERVED_27_EXCEPTION] = "Fatal error(RESERVED_27)",
|
|
[RESERVED_28_EXCEPTION] = "Fatal error(RESERVED_28)",
|
|
[MPU_NOT_ALLOW] = "Fatal error(MPU_NOT_ALLOW)",
|
|
[CACHE_ERROR_EXCEPTION_DBG_MODE] = "Fatal error(CACHE_ERROR_DBG_MODE)",
|
|
[RESERVED_31_EXCEPTION] = "Fatal error(RESERVED_31)",
|
|
[NMI_EXCEPTION] = "Fatal error(NMI)",
|
|
[CACHE_ERROR_EXCEPTION] = "Fatal error(CACHE_ERROR)",
|
|
[TLB_REFILL_LOAD_EXCEPTION] = "Fatal error(TLB_REFILL_LOAD)",
|
|
[TLB_REFILL_STORE_EXCEPTION] = "Fatal error(TLB_REFILL_STORE)"
|
|
};
|
|
|
|
static char *ee_type_str_v3_30s[] = {
|
|
/*[STACKACCESS_EXCEPTION - 0x30] = */"Fatal error(STACKACCESS)",
|
|
/*[SYS_FATALERR_EXT_TASK_EXCEPTION - 0x30] = */"Fatal error(task)",
|
|
/*[SYS_FATALERR_EXT_BUF_EXCEPTION - 0x30] = */"Fatal error(buf)"
|
|
};
|
|
|
|
static char *ee_type_str_v3_50s[] = {
|
|
/*[ASSERT_FAIL_EXCEPTION - 0x50] = */"ASSERT",
|
|
/*[ASSERT_DUMP_EXTENDED_RECORD - 0x50] = */"ASSERT",
|
|
/*[ASSERT_FAIL_NATIVE - 0x50] = */"ASSERT",
|
|
/*[ASSERT_CUSTOM_ADDR - 0x50] = */"Fatal error(ASSERT_CUSTOM_ADDR)",
|
|
/*[ASSERT_CUSTOM_MODID - 0x50] = */"Fatal error(ASSERT_CUSTOM_MODID)"
|
|
};
|
|
|
|
static char *ee_type_str_v3_60s[] = {
|
|
/*[CC_INVALID_EXCEPTION - 0x60] = */"CC_INVALID",
|
|
/*[CC_CS_EXCEPTION- 0x60] = */"Fatal error (CC_CS)",
|
|
/*[CC_MD32_EXCEPTION- 0x60] = */"Fatal error (CC_MD32)",
|
|
/*[CC_C2K_EXCEPTION- 0x60] = */"Fatal error (CC_C2K)",
|
|
/*[CC_VOLTE_EXCEPTION- 0x60] = */"Fatal error (CC_VOLTE)",
|
|
/*[CC_USIP_EXCEPTION- 0x60] = */"Fatal error (CC_USIP)",
|
|
/*[CC_SCQ_EXCEPTION- 0x60] = */"Fatal error (CC_SCQ)",
|
|
};
|
|
|
|
static char *ee_err_sec_str[] = {
|
|
"",
|
|
"BRP_LTE_ROCODE",
|
|
"BRP_FDD_ROCODE",
|
|
"FEC_TX_C2K_ROCODE",
|
|
"FEC_TX_WCDMA_ROCODE",
|
|
"FEC_TX_LTE_ROCODE",
|
|
"FEC_RX_C2K_ROCODE",
|
|
"FEC_RX_WCDMA_ROCODE",
|
|
"SCQ16_LTE_ROCODE",
|
|
"SCQ16_FDD_ROCODE",
|
|
"SCQ16_TDD_ROCODE",
|
|
"SCQ16_C2K_ROCODE",
|
|
"RAKE_FDD_ROCODE",
|
|
"RAKE_C2K_ROCODE",
|
|
};
|
|
|
|
static void md_ee_set_exp_type(struct ex_brief_maininfo *brief_info,
|
|
int core_id, char **ex_str)
|
|
{
|
|
u32 exp_type = brief_info->ex_type;
|
|
|
|
if (core_id == 0) {
|
|
if (exp_type < TLB_REFILL_MAX_NUM)
|
|
*ex_str = ee_type_str_v3_23h[exp_type];
|
|
else if ((exp_type < SYS_FATALERR_MAX_NUM)
|
|
&& (exp_type >= STACKACCESS_EXCEPTION))
|
|
*ex_str = ee_type_str_v3_30s[exp_type -
|
|
STACKACCESS_EXCEPTION];
|
|
else if ((exp_type < ASSERT_FAIL_MAX_NUM)
|
|
&& (exp_type >= ASSERT_FAIL_EXCEPTION))
|
|
*ex_str = ee_type_str_v3_50s[exp_type -
|
|
ASSERT_FAIL_EXCEPTION];
|
|
else if ((exp_type < CC_EXCEPTION_MAX_NUM)
|
|
&& (exp_type >= CC_INVALID_EXCEPTION))
|
|
*ex_str = ee_type_str_v3_60s[exp_type -
|
|
CC_INVALID_EXCEPTION];
|
|
else if (exp_type == EMI_MPU_VIOLATION_EXCEPTION)
|
|
*ex_str = "Fatal error (rmpu violation)";
|
|
else
|
|
*ex_str = "INVALID_EXCEPTION_TYPE";
|
|
} else {
|
|
if (brief_info->maincontent_type == MD_EX_CLASS_ASSET)
|
|
*ex_str = "ASSERT";
|
|
else if (brief_info->maincontent_type == MD_EX_CLASS_FATAL)
|
|
*ex_str = "Fatal error";
|
|
else
|
|
*ex_str = "INVALID_EXCEPTION_TYPE";
|
|
}
|
|
|
|
}
|
|
|
|
static void md_ee_set_assert_para(struct ex_assert_v3 *assert_src,
|
|
struct dump_info_assert *assert_tar)
|
|
{
|
|
/* 1. assert file name */
|
|
strmncopy(assert_src->filepath, assert_tar->file_name,
|
|
sizeof(assert_src->filepath), sizeof(assert_tar->file_name));
|
|
/* 2. assert line number */
|
|
assert_tar->line_num = assert_src->line_number;
|
|
/* 3. assert parameters */
|
|
assert_tar->parameters[0] = assert_src->para1;
|
|
assert_tar->parameters[1] = assert_src->para2;
|
|
assert_tar->parameters[2] = assert_src->para3;
|
|
}
|
|
|
|
static void md_ee_set_fatal_para(struct ex_fatal_v3 *fatal_src,
|
|
struct dump_info_fatal *fata_tar, unsigned int ex_type)
|
|
{
|
|
char temp_str[32] = { 0 };
|
|
char *fatal_fname_prefix = "MD Offending File:";
|
|
unsigned int string_len = 0;
|
|
|
|
/* 1. offender string */
|
|
if ((fatal_src->offender[0] != 0xCC)
|
|
&& (fatal_src->offender[0] != 0)) {
|
|
strmncopy(fatal_src->offender, temp_str,
|
|
sizeof(fatal_src->offender), sizeof(temp_str));
|
|
scnprintf(fata_tar->offender, sizeof(fata_tar->offender),
|
|
"MD Offender:%s\n", temp_str);
|
|
CCCI_NORMAL_LOG(-1, FSM, "offender: %s\n",
|
|
fata_tar->offender);
|
|
} else
|
|
fata_tar->offender[0] = '\0';
|
|
/* 2. error code of fatal error */
|
|
fata_tar->err_code1 = fatal_src->code1;
|
|
fata_tar->err_code2 = fatal_src->code2;
|
|
fata_tar->err_code3 = fatal_src->code3;
|
|
/* 3. cadefa support */
|
|
if (fatal_src->is_cadefa_supported == 0x01)
|
|
fata_tar->ExStr = "CaDeFa Supported\n";
|
|
else
|
|
fata_tar->ExStr = "";
|
|
/*4. file name support*/
|
|
if (ex_type == MD_EX_CLASS_CUSTOM)
|
|
fatal_fname_prefix = "Original Offending File: ";
|
|
if (fatal_src->is_filename_supported == 0x01) {
|
|
scnprintf(fata_tar->fatal_fname, EX_BRIEF_FATALERR_SIZE,
|
|
"%s%s", fatal_fname_prefix, fatal_src->filename);
|
|
|
|
string_len = strlen(fatal_fname_prefix) +
|
|
EX_BRIEF_FATALERR_SIZE -
|
|
sizeof(struct ex_fatal_v3) + 1;
|
|
if (string_len > EX_BRIEF_FATALERR_SIZE)
|
|
CCCI_NORMAL_LOG(-1, FSM,
|
|
"fata fname length should be ajdustment %d > %d\n",
|
|
string_len, EX_BRIEF_FATALERR_SIZE);
|
|
CCCI_NORMAL_LOG(-1, FSM, "%s\n", fata_tar->fatal_fname);
|
|
} else
|
|
fata_tar->fatal_fname[0] = '\0';
|
|
/* 5. error section */
|
|
if (fatal_src->error_section < ARRAY_SIZE(ee_err_sec_str))
|
|
fata_tar->err_sec =
|
|
ee_err_sec_str[fatal_src->error_section];
|
|
else
|
|
fata_tar->err_sec = "";
|
|
fata_tar->error_address = fatal_src->error_address;
|
|
fata_tar->error_pc = fatal_src->error_pc;
|
|
|
|
}
|
|
|
|
static void mdee_info_prepare_v3(struct ccci_fsm_ee *mdee)
|
|
{
|
|
struct ex_overview_t *ex_overview = NULL;
|
|
struct ex_brief_maininfo *brief_info = NULL;
|
|
struct mdee_dumper_v3 *dumper = mdee->dumper_obj;
|
|
struct debug_info_t *debug_info = &dumper->debug_info;
|
|
int md_id = mdee->md_id;
|
|
int core_id = 0;
|
|
|
|
CCCI_NORMAL_LOG(md_id, FSM,
|
|
"%s, ee_case(0x%x)\n", __func__, dumper->more_info);
|
|
|
|
memset(debug_info, 0, sizeof(struct debug_info_t));
|
|
if (dumper->more_info == MD_EE_CASE_NO_RESPONSE
|
|
|| dumper->more_info == MD_EE_CASE_WDT)
|
|
return;
|
|
/* mem of parsing */
|
|
ex_overview = md_ee_get_buf_ptr(mdee, &debug_info->par_data_source);
|
|
/* version: 0xABxxyyyy:
|
|
* xx rule version for AP parsing,
|
|
* yyyy for md parsing
|
|
*/
|
|
if ((ex_overview->overview_verno&0xFFFF0000) != 0xAB000000
|
|
|| ex_overview->core_num > MD_CORE_TOTAL_NUM) {
|
|
debug_info->type = MD_EX_CLASS_INVALID;
|
|
scnprintf(debug_info->core_name, sizeof(debug_info->core_name),
|
|
"%s", "MCU_core0,vpe0,tc0(VPE0)");
|
|
|
|
debug_info->name = "INVALID_EXCEPTION_TYPE";
|
|
return;
|
|
}
|
|
/* core_name */
|
|
core_id = mdee_set_core_name(md_id,
|
|
debug_info->core_name, ex_overview);
|
|
/* ======== exception type ========= */
|
|
brief_info = &ex_overview->ex_info;
|
|
debug_info->type = brief_info->maincontent_type;
|
|
debug_info->ex_type = brief_info->ex_type;
|
|
md_ee_set_exp_type(brief_info, core_id, &debug_info->name);
|
|
/* ======== exception parameters ========= */
|
|
switch (debug_info->type) {
|
|
case MD_EX_CLASS_ASSET:
|
|
md_ee_set_assert_para(&brief_info->info.assert,
|
|
&debug_info->dump_assert);
|
|
break;
|
|
case MD_EX_CLASS_FATAL:
|
|
case MD_EX_CLASS_CUSTOM:
|
|
md_ee_set_fatal_para(&brief_info->info.fatalerr,
|
|
&debug_info->dump_fatal, debug_info->type);
|
|
break;
|
|
}
|
|
/* ======== ELM status ========= */
|
|
switch (brief_info->elm_status) {
|
|
case 0xFF:
|
|
debug_info->ELM_status = "\nno ELM info\n";
|
|
break;
|
|
case 0xAE:
|
|
debug_info->ELM_status = "\nELM rlat:FAIL\n";
|
|
break;
|
|
case 0xBE:
|
|
debug_info->ELM_status = "\nELM wlat:FAIL\n";
|
|
break;
|
|
case 0xDE:
|
|
debug_info->ELM_status = "\nELM r/wlat:PASS\n";
|
|
break;
|
|
default:
|
|
debug_info->ELM_status = "";
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
static void mdee_dumper_v3_set_ee_pkg(struct ccci_fsm_ee *mdee,
|
|
char *data, int len)
|
|
{
|
|
struct mdee_dumper_v3 *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 md_HS1_Fail_dump(int md_id, char *ex_info, unsigned int len)
|
|
{
|
|
unsigned int reg_value[2] = { 0 };
|
|
unsigned int ccif_sram[CCCI_EE_SIZE_CCIF_SRAM/sizeof(unsigned int)]
|
|
= { 0 };
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
ccci_md_dump_info(md_id,
|
|
DUMP_MD_BOOTUP_STATUS, reg_value, 2);
|
|
ccci_md_dump_info(md_id,
|
|
DUMP_FLAG_CCIF, ccif_sram, 0);
|
|
|
|
CCCI_MEM_LOG_TAG(md_id, FSM,
|
|
"md_boot_stats0 /1 / bootuptrace:0x%X / 0x%X / 0x%X\n",
|
|
reg_value[0], reg_value[1], ccif_sram[0]);
|
|
if ((reg_value[0] == 0) && (ccif_sram[0] == 0)) {
|
|
scnprintf(ex_info, len,
|
|
"\n[Others] MD_BOOT_UP_FAIL(HS%d - MD poweron failed)\n"
|
|
"boot_status0: 0x%x\nboot_status1: 0x%x\n"
|
|
"MD Offender:DVFS\n",
|
|
0, reg_value[0], reg_value[1]);
|
|
|
|
} else if (((reg_value[0] == 0x5443000C) ||
|
|
(reg_value[0] == 0) ||
|
|
(reg_value[0] >= 0x53310000 &&
|
|
reg_value[0] <= 0x533100FF)) &&
|
|
(md->hw_info->plat_val->md_gen >= 6295)) {
|
|
scnprintf(ex_info, len,
|
|
"\n[Others] MD_BOOT_UP_FAIL(HS%d)\n",
|
|
1);
|
|
ccci_md_dump_info(md_id,
|
|
DUMP_FLAG_REG, NULL, 0);
|
|
msleep(10000);
|
|
ccci_md_dump_info(md_id,
|
|
DUMP_FLAG_REG, NULL, 0);
|
|
} else if (((reg_value[0] == 0x54430007) ||
|
|
(reg_value[0] == 0) ||
|
|
(reg_value[0] >= 0x53310000 &&
|
|
reg_value[0] <= 0x533100FF)) &&
|
|
(md->hw_info->plat_val->md_gen < 6295)) {
|
|
scnprintf(ex_info, len,
|
|
"\n[Others] MD_BOOT_UP_FAIL(HS%d)\n",
|
|
1);
|
|
ccci_md_dump_info(md_id,
|
|
DUMP_FLAG_REG, NULL, 0);
|
|
msleep(10000);
|
|
ccci_md_dump_info(md_id,
|
|
DUMP_FLAG_REG, NULL, 0);
|
|
} else {
|
|
/* ((reg_value[0] >= 0x54430001 &&
|
|
* reg_value[0] <= 0x54430006) ||
|
|
* (reg_value[0] >= 0x53310100 &&
|
|
* reg_value[0] <= 0x5331FFFF))
|
|
* or else
|
|
*/
|
|
scnprintf(ex_info, len,
|
|
"\n[Others] MD_BOOT_UP_FAIL(HS%d - MD bootrom failed)\n"
|
|
"boot_status0: 0x%x\nboot_status1: 0x%x\n"
|
|
"MD Offender:BOOTROM\n",
|
|
0, reg_value[0], reg_value[1]);
|
|
}
|
|
|
|
}
|
|
|
|
static void mdee_dumper_v3_dump_ee_info(struct ccci_fsm_ee *mdee,
|
|
enum MDEE_DUMP_LEVEL level, int more_info)
|
|
{
|
|
struct mdee_dumper_v3 *dumper = mdee->dumper_obj;
|
|
int md_id = mdee->md_id;
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(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;
|
|
|
|
dumper->more_info = more_info;
|
|
if (level == MDEE_DUMP_LEVEL_BOOT_FAIL) {
|
|
if (md_state == BOOT_WAITING_FOR_HS1) {
|
|
md_HS1_Fail_dump(mdee->md_id, ex_info, EE_BUF_LEN);
|
|
/* Handshake 1 fail */
|
|
ccci_aed_v3(mdee,
|
|
CCCI_AED_DUMP_CCIF_REG | CCCI_AED_DUMP_EX_MEM,
|
|
ex_info, DB_OPT_DEFAULT | DB_OPT_FTRACE);
|
|
} else if (md_state == BOOT_WAITING_FOR_HS2) {
|
|
scnprintf(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 & (1U << 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);
|
|
if (md && md->hw_info && md->hw_info->md_l2sram_base) {
|
|
md_cd_lock_modem_clock_src(1);
|
|
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
md->hw_info->md_l2sram_base, MD_L2SRAM_SIZE_V3);
|
|
|
|
md_cd_lock_modem_clock_src(0);
|
|
}
|
|
}
|
|
|
|
ccci_aed_v3(mdee,
|
|
CCCI_AED_DUMP_CCIF_REG | CCCI_AED_DUMP_EX_MEM,
|
|
ex_info, DB_OPT_DEFAULT | DB_OPT_FTRACE);
|
|
}
|
|
} else if (level == MDEE_DUMP_LEVEL_STAGE1) {
|
|
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);
|
|
if (md && md->hw_info && md->hw_info->md_l2sram_base) {
|
|
md_cd_lock_modem_clock_src(1);
|
|
|
|
ccci_util_mem_dump(md_id, CCCI_DUMP_MEM_DUMP,
|
|
md->hw_info->md_l2sram_base, MD_L2SRAM_SIZE_V3);
|
|
|
|
md_cd_lock_modem_clock_src(0);
|
|
}
|
|
}
|
|
/*dump md register on no response EE*/
|
|
if (more_info == MD_EE_CASE_NO_RESPONSE)
|
|
per_md_data->md_dbg_dump_flag = MD_DBG_DUMP_ALL;
|
|
} else if (level == MDEE_DUMP_LEVEL_STAGE2) {
|
|
mdee_info_prepare_v3(mdee);
|
|
mdee_info_dump_v3(mdee);
|
|
}
|
|
}
|
|
|
|
static struct md_ee_ops mdee_ops_v3 = {
|
|
.dump_ee_info = &mdee_dumper_v3_dump_ee_info,
|
|
.set_ee_pkg = &mdee_dumper_v3_set_ee_pkg,
|
|
};
|
|
|
|
#if IS_ENABLED(CONFIG_MTK_EMI)
|
|
static void mdee_dumper_v3_emimpu_callback(
|
|
const char *vio_msg)
|
|
{
|
|
int has_write = 0;
|
|
int md_state;
|
|
struct ccci_fsm_ctl *ctl = fsm_get_entity_by_md_id(0);
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(0);
|
|
|
|
if (vio_msg)
|
|
CCCI_NORMAL_LOG(0, FSM,
|
|
"%s: %s\n", __func__, vio_msg);
|
|
else {
|
|
CCCI_ERROR_LOG(0, FSM,
|
|
"%s: msg is null\n", __func__);
|
|
return;
|
|
}
|
|
|
|
if (md) {
|
|
md_state = ccci_fsm_get_md_state(md->index);
|
|
if (md_state != INVALID && md_state != GATED &&
|
|
md_state != WAITING_TO_STOP) {
|
|
if (md->ops->dump_info)
|
|
md->ops->dump_info(md, DUMP_FLAG_REG, NULL, 0);
|
|
}
|
|
}
|
|
|
|
if (ctl) {
|
|
memset(ctl->ee_ctl.ex_mpu_string, 0x0,
|
|
sizeof(ctl->ee_ctl.ex_mpu_string));
|
|
has_write = scnprintf(&ctl->ee_ctl.ex_mpu_string[0],
|
|
MD_EX_MPU_STR_LEN,
|
|
"%s\n", vio_msg);
|
|
if (has_write <= 0)
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
int mdee_dumper_v3_alloc(struct ccci_fsm_ee *mdee)
|
|
{
|
|
struct mdee_dumper_v3 *dumper = NULL;
|
|
int md_id = mdee->md_id;
|
|
#if IS_ENABLED(CONFIG_MTK_EMI)
|
|
if (mtk_emimpu_md_handling_register(
|
|
&mdee_dumper_v3_emimpu_callback))
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s: mtk_emimpu_md_handling_register fail\n",
|
|
__func__);
|
|
#endif
|
|
/* Allocate port_proxy obj and set all member zero */
|
|
dumper = kzalloc(sizeof(struct mdee_dumper_v3), GFP_KERNEL);
|
|
if (dumper == NULL) {
|
|
CCCI_ERROR_LOG(md_id, FSM,
|
|
"%s:alloc mdee_parser_v3 fail\n", __func__);
|
|
return -1;
|
|
}
|
|
mdee->dumper_obj = dumper;
|
|
mdee->ops = &mdee_ops_v3;
|
|
return 0;
|
|
}
|
|
|