/*
 * @brief Trigger AEE exception red screen.
 * @param
 *     dump_flag   [in] what info need show in EE.

 * @return
 *     none.
 */
void eemcs_aed(unsigned int dump_flag, char *aed_str)
{
	#define AED_STR_LEN		(512)
	int *ex_log_addr = NULL;
	int ex_log_len = 0;
	int *md_img_addr = NULL;
	int md_img_len = 0;
	int info_str_len = 0;
	char buff[AED_STR_LEN];
	char img_inf[MD_INFO_STR_LEN]="";
	
	eemcs_get_md_info_str(img_inf);
	info_str_len = strlen(aed_str);
	info_str_len += strlen(img_inf);

	if(info_str_len > AED_STR_LEN){
		buff[AED_STR_LEN-1] = '\0'; // Cut string length to AED_STR_LEN
	}

	snprintf(buff, AED_STR_LEN, "\n%s%s\n", aed_str, img_inf);

	if(dump_flag & CCCI_AED_DUMP_EX_MEM){
		ex_log_addr = (int *)g_except_inst.expt_info_mem;
		ex_log_len = MD_EX_MEM_SIZE;
		
		DBGLOG(EXPT, DBG, "");
		DBGLOG(EXPT, DBG, "Dump MD Exception share memory");
		eemcs_mem_dump(g_except_inst.expt_info_mem, MD_EX_MEM_SIZE);
	}

	#if defined (CONFIG_MTK_AEE_FEATURE) && defined (ENABLE_AEE_MD_EE)
	aed_md_exception_api(ex_log_addr, ex_log_len, md_img_addr, md_img_len, buff, DB_OPT_FTRACE);
	#endif
}
/*
 * @brief dump ee info to string and send to eemcs_aed
 * @param
 *     debug_info    [in] debug info get from MD_EX_REC_OK msg, 
 *                        parse by eemcs_md_exception_data_parse.
 *   
 * @return
 *     none.
 */
void eemcs_ee_info_dump(DEBUG_INFO_T *debug_info, char* except_info_addr)
{
	char ex_info[EE_BUF_LEN]="";
	char i_bit_ex_info[EE_BUF_LEN]="\nMay I-Bit dis too long\n";
	
	struct rtc_time		tm;
	struct timeval		tv = {0};
	struct timeval		tv_android = {0};
	struct rtc_time		tm_android;

	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);
	DBGLOG(EXPT, DBG, "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);

	DBGLOG(EXPT, DBG, "exception type(%d):%s\n",debug_info->type,debug_info->name?:"Unknown");

	switch(debug_info->type)
	{
		case MD_EX_TYPE_ASSERT_DUMP:
		case MD_EX_TYPE_ASSERT:
			DBGLOG(EXPT, DBG, "filename = %s\n", debug_info->assert.file_name);
			DBGLOG(EXPT, DBG, "line = %d\n", debug_info->assert.line_num);
			DBGLOG(EXPT, DBG, "para0 = %d, para1 = %d, para2 = %d\n", 
					debug_info->assert.parameters[0],
					debug_info->assert.parameters[1],
					debug_info->assert.parameters[2]);
			snprintf(ex_info,EE_BUF_LEN,"\n[%s] file:%s line:%d\np1:0x%08x\np2:0x%08x\np3:0x%08x\n",
					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_TYPE_FATALERR_BUF:
		case MD_EX_TYPE_FATALERR_TASK:
			DBGLOG(EXPT, DBG, "fatal error code 1 = %d\n", debug_info->fatal_error.err_code1);
			DBGLOG(EXPT, DBG, "fatal error code 2 = %d\n", debug_info->fatal_error.err_code2);
			snprintf(ex_info,EE_BUF_LEN,"\n[%s] err_code1:%d err_code2:%d\n", debug_info->name, 
					debug_info->fatal_error.err_code1, debug_info->fatal_error.err_code2);
			break;
		case MD_EX_TYPE_EMI_CHECK:
			DBGLOG(EXPT, ERR, "md_emi_check: %08X, %08X, %02d, %08X\n", 
					debug_info->data.data0, debug_info->data.data1,
					debug_info->data.channel, debug_info->data.reserved);
			snprintf(ex_info,EE_BUF_LEN,"\n[emi_chk] %08X, %08X, %02d, %08X\n", 
					debug_info->data.data0, debug_info->data.data1,
					debug_info->data.channel, debug_info->data.reserved);
			break;
		case DSP_EX_TYPE_ASSERT:
			DBGLOG(EXPT, DBG, "filename = %s\n", debug_info->dsp_assert.file_name);
			DBGLOG(EXPT, DBG, "line = %d\n", debug_info->dsp_assert.line_num);
			DBGLOG(EXPT, DBG, "exec unit = %s\n", debug_info->dsp_assert.execution_unit);
			DBGLOG(EXPT, DBG, "para0 = %d, para1 = %d, para2 = %d\n", 
					debug_info->dsp_assert.parameters[0],
					debug_info->dsp_assert.parameters[1],
					debug_info->dsp_assert.parameters[2]);
			snprintf(ex_info,EE_BUF_LEN,"\n[%s] file:%s line:%d\nexec:%s\np1:%d\np2:%d\np3:%d\n",
					debug_info->name, debug_info->assert.file_name, debug_info->assert.line_num,
					debug_info->dsp_assert.execution_unit, 
					debug_info->dsp_assert.parameters[0],
					debug_info->dsp_assert.parameters[1],
					debug_info->dsp_assert.parameters[2]);
			break;
		case DSP_EX_TYPE_EXCEPTION:
			DBGLOG(EXPT, DBG, "exec unit = %s, code1:0x%08x\n", debug_info->dsp_exception.execution_unit,
					debug_info->dsp_exception.code1);
			snprintf(ex_info,EE_BUF_LEN,"\n[%s] exec:%s code1:0x%08x\n",
					debug_info->name, debug_info->dsp_exception.execution_unit,
					debug_info->dsp_exception.code1);
			break;
		case DSP_EX_FATAL_ERROR:
			DBGLOG(EXPT, DBG, "exec unit = %s\n", debug_info->dsp_fatal_err.execution_unit);
			DBGLOG(EXPT, DBG, "err_code0 = 0x%08x, err_code1 = 0x%08x\n", 
					debug_info->dsp_fatal_err.err_code[0],
					debug_info->dsp_fatal_err.err_code[1]);

			snprintf(ex_info,EE_BUF_LEN,"\n[%s] exec:%s err_code1:0x%08x err_code2:0x%08x\n",
					debug_info->name, debug_info->dsp_fatal_err.execution_unit, 
					debug_info->dsp_fatal_err.err_code[0],
					debug_info->dsp_fatal_err.err_code[1]);
			break;
		default: // Only display exception name
			snprintf(ex_info,EE_BUF_LEN,"\n[%s]\n", debug_info->name);
			break;
	}

	// Add additional info
	switch(debug_info->more_info)
	{
		case MD_EE_CASE_ONLY_EX:
			strcat(ex_info, "\nTime out case\n");
			break;
			
		case MD_EE_CASE_ONLY_EX_OK:
			strcat(ex_info, "\nOnly EX_OK case\n");
			break;
		case MD_EE_CASE_AP_MASK_I_BIT_TOO_LONG:
			strcat(i_bit_ex_info, ex_info);
			strcpy(ex_info, i_bit_ex_info);
			break;
		case MD_EE_CASE_TX_TRG:
		case MD_EE_CASE_ISR_TRG:
			//strcat(ex_info, "\nMay I-Bit dis too long\n");
			break;

		case MD_EE_CASE_NO_RESPONSE:
			strcat(ex_info, "\nMD long time no response\n");
			break;
			
		default:
			break;
	}

// TODO:    DUMP function
	// Dump Exception share memory
	DBGLOG(EXPT, DBG, "\n\n");
	DBGLOG(EXPT, DBG, "Dump MD Exception share memory\n");
	eemcs_mem_dump((int*)except_info_addr, MD_EX_LOG_SIZE);

	eemcs_aed(except_info_addr, MD_EX_LOG_SIZE, ex_info);
}