static int debugfs_make_kernel_panic(void *data, u64 val)
{
#if defined(CONFIG_ARCH_SC8810) || defined(CONFIG_ARCH_SC8825)
	if (val > 0) cp_abort();
#endif
	return 0;
}
Exemplo n.º 2
0
void ipcs_intr_workqueue_process(struct work_struct *work)
{
    static int first = 1;
    if (first)
    {
        first = 0;
        set_user_nice(current, -16);
    }


   if(IpcCPCrashCheck())
   {
		cp_crashed  = 1;
		if( BCMLOG_CPCRASH_MTD == BCMLOG_GetCpCrashDumpDevice() )
		{
		/* we kill AP when CP crashes */
			IPC_DEBUG(DBG_INFO, "Crashing AP now...\n\n");
#if defined(CONFIG_SEC_DEBUG)
    			cp_abort();
#else
    			abort();
#endif
		} else 
		{
		schedule_work(&g_ipc_info.cp_crash_dump_wq);
	}

		IPC_ProcessEvents();
	}else
	{
       IPC_ProcessEvents();  
#ifdef CONFIG_HAS_WAKELOCK 
       wake_unlock(&ipc_wake_lock);
#endif // CONFIG_HAS_WAKELOCK
   }
}
Exemplo n.º 3
0
/*************************************************
*
*   Worker thread to dump CP crash log information.
*
*
*****************************************************/
void ProcessCPCrashedDump(struct work_struct *work)
{
	char crashReason[40] = { 0 };
	char crashFile[40] = { 0 };
	char crashThread[40] = { 0 };
	char outString[512] = { 0 };
	IPC_U32 *Dump;
	void __iomem *DumpVAddr;
	int cpReset = SmLocalControl.SmControl->CrashCode ==
	    IPC_CP_SILENT_RESET_READY;

#ifdef CONFIG_CDEBUGGER
	if (ramdump_enable
#ifdef CONFIG_BRCM_CP_CRASH_DUMP_EMMC
	    && ap_triggered == 0
#endif
	    ) {
		BCMLOG_SetCpCrashLogDevice(BCMLOG_OUTDEV_NONE);
		/* we kill AP when CP crashes */
		IPC_DEBUG(DBG_ERROR, "Crashing AP for ramdump ...\n\n");
		abort();
	}
#endif
	if ((BCMLOG_OUTDEV_PANIC == BCMLOG_GetCpCrashLogDevice() ||
	     (BCMLOG_OUTDEV_RNDIS == BCMLOG_GetCpCrashLogDevice() && !cpReset))
#ifdef CONFIG_BRCM_CP_CRASH_DUMP_EMMC
	    && !ap_triggered
#endif
	    ) {

#ifdef CONFIG_CRASH_DUMP_START_UI_DISPLAY
		if (!dump_start_ui_on) {
			display_crash_dump_start_ui();
			dump_start_ui_on = 1;
			msleep(100);
		}
#endif

		/* we kill AP when CP crashes */
		IPC_DEBUG(DBG_ERROR, "Crashing AP now ...\n\n");
		abort();
	}
#ifdef CONFIG_CRASH_DUMP_START_UI_DISPLAY
	if ((BCMLOG_OUTDEV_SDCARD == BCMLOG_GetCpCrashLogDevice())
	    && cp_crashed == 1 && !cpReset) {
		if (!dump_start_ui_on) {
			display_crash_dump_start_ui();
			dump_start_ui_on = 1;
		}
	}
#endif

	IPC_Dump();

	RpcDbgDumpHistoryLogging(0, 0);

#if defined(CONFIG_BRCM_CP_CRASH_DUMP) \
	|| defined(CONFIG_BRCM_CP_CRASH_DUMP_EMMC) \
	|| defined(CONFIG_BCM_AP_PANIC_ON_CPCRASH)
	while (SmLocalControl.SmControl->CrashDump == NULL)
		; /* No op */
#endif

	/* **NOTE** for now, continue doing simple dump out IPC_DEBUG so there
	 * is some indication of CP crash in console
	 * (in case user not running MTT) */
	Dump = (void *)SmLocalControl.SmControl->CrashDump;

	IPC_DEBUG(DBG_ERROR, "ioremap_nocache\n");
	DumpVAddr = ioremap_nocache((UInt32)Dump,
				    sizeof(struct T_CRASH_SUMMARY));
	if (NULL == DumpVAddr) {
		IPC_DEBUG(DBG_ERROR, "VirtualAlloc failed\n");
		goto cleanUp;
	}

	IPC_DEBUG(DBG_ERROR, "Crash Summary Virtual Addr: 0x%08X\n",
		  (unsigned int)DumpVAddr);

	dumped_crash_summary_ptr = (struct T_CRASH_SUMMARY *)DumpVAddr;

	IPC_DEBUG(DBG_ERROR, "===== COMMS_PROCESSOR crash summary =====\r\n");

	if (dumped_crash_summary_ptr->link_signature) {
		GetStringFromPA((UInt32)
				dumped_crash_summary_ptr->link_signature,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->project_version) {
		GetStringFromPA((UInt32)
				dumped_crash_summary_ptr->project_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->DSP_version) {
		GetStringFromPA((UInt32)dumped_crash_summary_ptr->DSP_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->FW_version) {
		GetStringFromPA((UInt32)dumped_crash_summary_ptr->FW_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->decoder_version) {
		GetStringFromPA((UInt32)
				dumped_crash_summary_ptr->decoder_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	GetStringFromPA((UInt32)dumped_crash_summary_ptr->reason, crashReason,
			40);

	GetStringFromPA((UInt32)dumped_crash_summary_ptr->file, crashFile, 40);

	GetStringFromPA((UInt32)dumped_crash_summary_ptr->thread, crashThread,
			40);

	IPC_DEBUG(DBG_ERROR, "%s f=%s l=%d v=%d/0x%x t=%s TS=%d\r\n",
		  crashReason,
		  crashFile,
		  dumped_crash_summary_ptr->line,
		  dumped_crash_summary_ptr->value,
		  dumped_crash_summary_ptr->value,
		  crashThread, dumped_crash_summary_ptr->time);

	/* notify clients about CP reset */
	if (cpReset
#ifdef CONFIG_BRCM_CP_CRASH_DUMP_EMMC
	    && !ap_triggered
#endif
	    )
		HandleCPResetStart();


#ifndef CONFIG_BCM_AP_PANIC_ON_CPCRASH
	/* done with "simple" dump, so now pull the full assert
	 * log from CP and dump out to MTT */
	DUMP_CP_assert_log();
#endif

cleanUp:

	if (NULL != DumpVAddr)
		iounmap(DumpVAddr);

	/* crash dump is done, so trigger CP reset */
	if (cpReset
#ifdef CONFIG_BRCM_CP_CRASH_DUMP_EMMC
	    && !ap_triggered
#endif
	    ) {
		IPC_DEBUG(DBG_INFO, "waiting for clients to ack...\n");
		while (!cp_reset_clients_acked)
			msleep(300);
		cp_reset_clients_acked = 0;

		IPC_DEBUG(DBG_INFO, "starting cp_reset thread\n");
		kthread_run(HandleRestartCP, 0, "cp_reset");
	}
#ifdef CONFIG_HAS_WAKELOCK
	else
		wake_unlock(&ipc_wake_lock);
#endif

#ifdef CONFIG_BCM_AP_PANIC_ON_CPCRASH
	IPC_DEBUG(DBG_ERROR, "CP crashed, crashing AP now..\n");

#ifdef CONFIG_SEC_DEBUG
	cp_abort();
#else
	abort();
#endif /* CONFIG_SEC_DEBUG */

#endif /* CONFIG_AP_PANIC_ON_CPCRASH */

}
/**	
*   Worker thread to dump CP crash log information.
*
*
********************************************************************************/
void ProcessCPCrashedDump(struct work_struct *work)
{ 
    char crashReason[40]={0};
    char crashFile[40]={0};
    char crashThread[40]={0}; 
    char outString[512]={0};
    IPC_U32 *Dump;
    void __iomem *DumpVAddr;

	static int done=0;
	done ++;
	if (done != 1)
	{
		printk(KERN_CRIT "%s call %d times\n", __func__, done); 
		return;
	}

#if defined(CONFIG_BRCM_CP_CRASH_DUMP) || defined(CONFIG_BRCM_AP_PANIC_ON_CPCRASH)
	while (SmLocalControl.SmControl->CrashDump == NULL);
#endif

#ifdef CONFIG_BRCM_KPANIC_UI_IND
	if (!lcdc_showing_dump())
		//only CP crash would enter here, AP crash does not trigger CP crash
		lcdc_disp_img(IMG_INDEX_CP_DUMP);  //parameter 2: Draw CP crash
#endif

    // **NOTE** for now, continue doing simple dump out IPC_DEBUG so there
    // is some indication of CP crash in console (in case user not running MTT)
    Dump = (void*)SmLocalControl.SmControl->CrashDump;

    IPC_DEBUG(DBG_ERROR, "[ipc]: IPCCrash: ProcessCPCrashedDump: ioremap_nocache\n");
    DumpVAddr = ioremap_nocache((UInt32)Dump,  sizeof(T_CRASH_SUMMARY));
    if(NULL == DumpVAddr)
    {
        IPC_DEBUG(DBG_ERROR, "[ipc]: IPCCrash: VirtualAlloc failed\n");
        goto cleanUp;    
    }
    
    IPC_DEBUG(DBG_ERROR, "[ipc]: IPCCrash: Crash Summary Virtual Addr: 0x%08X\n",(unsigned int)DumpVAddr);
    
    dumped_crash_summary_ptr = (T_CRASH_SUMMARY *)DumpVAddr;
    
    IPC_DEBUG(DBG_ERROR, "===== COMMS_PROCESSOR crash summary =====\r\n" );            
    
    if(dumped_crash_summary_ptr->link_signature)
    { 
        GetStringFromPA((UInt32)dumped_crash_summary_ptr->link_signature, outString, 128);
        IPC_DEBUG(DBG_ERROR,"%s\r\n", outString);
    }   
    
    if(dumped_crash_summary_ptr->project_version) 
    {
        GetStringFromPA((UInt32)dumped_crash_summary_ptr->project_version, outString, 128);
        IPC_DEBUG(DBG_ERROR,"%s\r\n", outString);
    } 

    if(dumped_crash_summary_ptr->DSP_version) 
    {
        GetStringFromPA((UInt32)dumped_crash_summary_ptr->DSP_version, outString, 128);  
        IPC_DEBUG(DBG_ERROR,"%s\r\n", outString);
    }

    if(dumped_crash_summary_ptr->FW_version) 
    {
        GetStringFromPA((UInt32)dumped_crash_summary_ptr->FW_version, outString, 128);
        IPC_DEBUG(DBG_ERROR,"%s\r\n", outString);
    }

    if(dumped_crash_summary_ptr->decoder_version) 
    {
        GetStringFromPA((UInt32)dumped_crash_summary_ptr->decoder_version, outString, 128);
        IPC_DEBUG(DBG_ERROR,"%s\r\n", outString);
    }
    
    GetStringFromPA((UInt32)dumped_crash_summary_ptr->reason, crashReason, 40);  
        
    GetStringFromPA((UInt32)dumped_crash_summary_ptr->file, crashFile, 40);    
       
    GetStringFromPA((UInt32)dumped_crash_summary_ptr->thread, crashThread, 40);
            
    IPC_DEBUG(DBG_ERROR,"%s f=%s l=%d v=%d/0x%x t=%s TS=%d\r\n",
        crashReason,
        crashFile,
        dumped_crash_summary_ptr->line,
        dumped_crash_summary_ptr->value,
        dumped_crash_summary_ptr->value,
        crashThread,
        dumped_crash_summary_ptr->time
        );
    
#ifndef CONFIG_BRCM_AP_PANIC_ON_CPCRASH
    // done with "simple" dump, so now pull the full assert 
    // log from CP and dump out to MTT
    DUMP_CP_assert_log();
#endif
    
cleanUp:       
    
    if(NULL != DumpVAddr)
    {
        iounmap(DumpVAddr);
    }
#ifdef CONFIG_HAS_WAKELOCK
    wake_unlock(&ipc_wake_lock);
#endif

#ifdef CONFIG_BRCM_AP_PANIC_ON_CPCRASH
    IPC_DEBUG (DBG_ERROR, "CP crashed, crashing AP now..\n");

#if defined(CONFIG_SEC_DEBUG)
    cp_abort();
#else
    abort();
#endif

#endif
    
}
/*************************************************
*
*   Worker thread to dump CP crash log information.
*
*
*****************************************************/
void ProcessCPCrashedDump(struct work_struct *work)
{
	char crashReason[40] = { 0 };
	char crashFile[40] = { 0 };
	char crashThread[40] = { 0 };
	char outString[512] = { 0 };
	IPC_U32 *Dump;
	void __iomem *DumpVAddr;
	int cpReset = SmLocalControl.SmControl->CrashCode ==
	    IPC_CP_SILENT_RESET_READY;
	RpcDbgDumpHistoryLogging(0, 0);
#ifdef CONFIG_KONA_SECURE_MEMC
	u32 *memc_handle;

	/* this is where any type of cp crash gets handled.
	 * there could be a scenerio of silent-reboot of cp.
	 * or there could be abrupt crash of cp.
	 * either ap would be alive or ap will crash itself.
	 * we protect cp area from following masters.
	 * > ap
	 * > mm
	 * > fabric
	 * in the event of ap/cp crash we need to give an ap
	 * access back to the cp area for the dump.
	 * and in the case of silent cp reset, ap will
	 * be alive, in that case we grant an access to ap.
	 * so that ap can load cp images and can take dump
	 * if required.
	 * and when cp comes up successfully and sync up with ap,
	 * we revoke the access for ap somwhere in HandleRestartCP.
	 */

	memc_handle = get_secure_memc_handle();
	if (!memc_handle)
		pr_err("Failed to get secure memc handle\n");
	if (do_grant_region_access(memc_handle, AP))
		pr_err("Failed to grant access for AP\n");
#endif

#ifdef CONFIG_FB_BRCM_CP_CRASH_DUMP_IMAGE_SUPPORT
if (!crash_dump_ui_on && !cpReset) {
	if (ramdump_enable)
		kona_display_crash_image(CP_RAM_DUMP_START);
	else
		kona_display_crash_image(CP_CRASH_DUMP_START);
	crash_dump_ui_on = 1;
	}
#endif

#ifndef CONFIG_BCM_AP_PANIC_ON_CPCRASH
#ifdef CONFIG_CDEBUGGER
	if (ramdump_enable
#ifdef CONFIG_APANIC_ON_MMC
		&& ap_triggered == 0
#endif
		&& !cpReset
		) {
		/* we kill AP when CP crashes */
		IPC_DEBUG(DBG_ERROR, "Crashing AP for Ramdump ...\n\n");
		abort();
	}
#endif
	if ((BCMLOG_OUTDEV_PANIC == BCMLOG_GetCpCrashLogDevice() ||
		BCMLOG_OUTDEV_NONE == BCMLOG_GetCpCrashLogDevice() ||
		BCMLOG_OUTDEV_STM == BCMLOG_GetCpCrashLogDevice()) &&
			!cpReset
#ifdef CONFIG_APANIC_ON_MMC
		&& !ap_triggered
#endif
		) {
		/* we kill AP when CP crashes */
		IPC_DEBUG(DBG_ERROR, "Crashing AP now ...\n\n");
		abort();
	}
#endif // CONFIG_BCM_AP_PANIC_ON_CPCRASH

	IPC_Dump();


#if defined(CONFIG_BRCM_CP_CRASH_DUMP_EMMC) \
	|| defined(CONFIG_BCM_AP_PANIC_ON_CPCRASH)
	while (SmLocalControl.SmControl->CrashDump == NULL)
		; /* No op */
#endif

	/* **NOTE** for now, continue doing simple dump out IPC_DEBUG so there
	 * is some indication of CP crash in console
	 * (in case user not running MTT) */
	Dump = (void *)SmLocalControl.SmControl->CrashDump;

	IPC_DEBUG(DBG_ERROR, "ioremap\n");

	DumpVAddr = plat_ioremap_ns((unsigned long __force)
			get_vaddr(IPC_CP_CRASH_SUMMARY_AREA),
			IPC_CP_CRASH_SUMMARY_AREA_SZ, (phys_addr_t)Dump);

	if (!DumpVAddr) {
		IPC_DEBUG(DBG_ERROR,
			"ioremap failed in ProcessCPCrashedDump\n");
		goto cleanUp;
	}
	IPC_DEBUG(DBG_ERROR, "Crash Summary Virtual Addr: 0x%08X\n",
		  (unsigned int)DumpVAddr);

	dumped_crash_summary_ptr = (struct T_CRASH_SUMMARY *)DumpVAddr;

	IPC_DEBUG(DBG_ERROR, "===== COMMS_PROCESSOR crash summary =====\r\n");

	if (dumped_crash_summary_ptr->link_signature) {
		GetStringFromPA((UInt32)
				dumped_crash_summary_ptr->link_signature,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->project_version) {
		GetStringFromPA((UInt32)
				dumped_crash_summary_ptr->project_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->DSP_version) {
		GetStringFromPA((UInt32)dumped_crash_summary_ptr->DSP_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->FW_version) {
		GetStringFromPA((UInt32)dumped_crash_summary_ptr->FW_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->decoder_version) {
		GetStringFromPA((UInt32)
				dumped_crash_summary_ptr->decoder_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	GetStringFromPA((UInt32)dumped_crash_summary_ptr->reason, crashReason,
			40);

	GetStringFromPA((UInt32)dumped_crash_summary_ptr->file, crashFile, 40);

	GetStringFromPA((UInt32)dumped_crash_summary_ptr->thread, crashThread,
			40);

	IPC_DEBUG(DBG_ERROR, "%s f=%s l=%d v=%d/0x%x t=%s TS=%d\r\n",
		  crashReason,
		  crashFile,
		  dumped_crash_summary_ptr->line,
		  dumped_crash_summary_ptr->value,
		  dumped_crash_summary_ptr->value,
		  crashThread, dumped_crash_summary_ptr->time);

	/* notify clients about CP reset */
	if (cpReset
#ifdef CONFIG_BRCM_CP_CRASH_DUMP_EMMC
	    && !ap_triggered
#endif
	    )
		HandleCPResetStart();

#ifndef CONFIG_BCM_AP_PANIC_ON_CPCRASH
	/* done with "simple" dump, so now pull the full assert
	 * log from CP and dump out to MTT */
	DUMP_CP_assert_log();
#endif

cleanUp:

	if (DumpVAddr)
		plat_iounmap_ns(get_vaddr(IPC_CP_CRASH_SUMMARY_AREA),
				free_size_ipc(IPC_CP_CRASH_SUMMARY_AREA_SZ));

	/* crash dump is done, so trigger CP reset */
	if (cpReset
#ifdef CONFIG_BRCM_CP_CRASH_DUMP_EMMC
	    && !ap_triggered
#endif
	    ) {
		IPC_DEBUG(DBG_INFO, "waiting for clients to ack...\n");
		while (!cp_reset_clients_acked)
			msleep(300);
		cp_reset_clients_acked = 0;

		IPC_DEBUG(DBG_INFO, "starting cp_reset thread\n");
		kthread_run(HandleRestartCP, 0, "cp_reset");
	}
#ifdef CONFIG_HAS_WAKELOCK
	else
		wake_unlock(&ipc_wake_lock);
#endif

#ifdef CONFIG_BCM_AP_PANIC_ON_CPCRASH

#ifdef CONFIG_SEC_DEBUG
	cp_abort();
#endif /* CONFIG_SEC_DEBUG */

#endif /* CONFIG_AP_PANIC_ON_CPCRASH */

}
/******************************************************************
*   Utility function to retrieve full crash log from CP via simple
*   handshake protocol.
*
*
********************************************************************/
void DUMP_CP_assert_log(void)
{
	UInt32 t0, t1, i, size, retryCount;
	UInt8 *p;
	UInt32 packetCount = 0;
	void __iomem *AssertLogVAddr = NULL;
	struct file *sdDumpFile = NULL;

	/* put logging driver into crash dump mode; messages will be sent
	 * straight out to MTT via RNDIS (or dump file) instead of buffering
	 * in RING buffer (flood of crash dump info overloads ring buffer
	 * otherwise,and we lose a lot of crash dump info)
	 * NOTE: crash dump is put into SD by default; if SD file fails to open,
	 * then we'll try sending it out RNDIS */

	BCMLOG_StartCpCrashDump(sdDumpFile);

	retryCount = 0;
	t0 = TIMER_GetValue();
	while (1) {
		t1 = TIMER_GetValue();

		/* signal to CP that we're ready to receive crash log... */
		SmLocalControl.SmControl->CrashCode = IPC_AP_CLEAR_TO_SEND;

		/* wait for CP to "dump"; CrashCode field will be
		 * set to physical address of current assert buf */
		while (SmLocalControl.SmControl->CrashCode ==
		       IPC_AP_CLEAR_TO_SEND) {
			for (i = 0; i < 256; i++)
				;
			if (TIMER_GetValue() - t1 > TICKS_ONE_SECOND * 20)
				break;
		}

		/* check for time out */
		if (SmLocalControl.SmControl->CrashCode ==
			IPC_AP_CLEAR_TO_SEND) {
			if (retryCount < MAX_CP_DUMP_RETRIES) {
				retryCount++;
				IPC_DEBUG(DBG_TRACE,
					  "timeout %d, trying again...\n",
					  (int)retryCount);
				continue;
			} else {
				/* no response from CP, so get out of here */
				IPC_DEBUG(DBG_ERROR,
					  "Abort --- max retries %d reached\n",
					  (int)retryCount);
				break;
			}
		}
		/* reset retry counter */
		retryCount = 0;

		/* get virtual address of CP assert buffer */
		AssertLogVAddr = ioremap_nocache((UInt32)
						 (SmLocalControl.SmControl->
						  CrashCode), ASSERT_BUF_SIZE);
		if (NULL == AssertLogVAddr) {
			IPC_DEBUG(DBG_ERROR,
				  "ioremap_nocache failed in DUMP_CP_assert_log\n");
			break;
		}

		p = (UInt8 *) AssertLogVAddr;

		/* number of bytes in assert buffer */
		size = (p[0] << 8) + p[1];

		/* size of 0 means CP is done dumping assert log */
		if (size == 0) {
			IPC_DEBUG(DBG_ERROR,
				  "assert log size 0, exiting, packetCount:0x%x\n",
				  (int)packetCount);
			iounmap(AssertLogVAddr);
			AssertLogVAddr = NULL;
			break;
		}
		/* sanity check for too beaucoup... */
		if (size > ASSERT_BUF_SIZE - 2) {
			IPC_DEBUG(DBG_ERROR,
				  "Abort --- improper size [%08x]=%d\n",
				  SmLocalControl.SmControl->CrashCode,
				  (int)size);
			iounmap(AssertLogVAddr);
			AssertLogVAddr = NULL;
			break;
		}
		/* send packet out to log (MTT via RNDIS or crash dump file) */
		BCMLOG_HandleCpCrashDumpData((const char *)(p + 2), size);

		packetCount++;
		iounmap(AssertLogVAddr);
		AssertLogVAddr = NULL;

#if 0
		/* **FIXME** this is Nucleus timeout code - do we want
		 * something similar for Android? Maybe if we get to the
		 * point of restarting CP with restarting AP
		 */
		if (TIMER_GetValue() - t0 > TICKS_ONE_SECOND * 10 * 60) {
			IPC_DEBUG(DBG_ERROR,
				  "Abort --- CP assertion log too long\n");
			break;
		}
#endif
	}

	RpcDbgDumpHistoryLogging(2, 1);

	IPC_DEBUG(DBG_ERROR, "Starting CP RAM dump - do not power down...\n");

	/* dump all CP memory to log */
	DUMP_CPMemoryByList(dumped_crash_summary_ptr->mem_dump);

	IPC_DEBUG(DBG_ERROR, "CP RAM dump complete\n");
	/* resume normal logging activities... */
	BCMLOG_EndCpCrashDump();

#ifdef CONFIG_FB_BRCM_CP_CRASH_DUMP_IMAGE_SUPPORT
	rhea_display_crash_image(CP_CRASH_DUMP_END);
#endif

	if (BCMLOG_OUTDEV_SDCARD == BCMLOG_GetCpCrashLogDevice())
		sys_sync();

	IPC_DEBUG(DBG_ERROR, "CP crash dump complete\n");

#ifdef CONFIG_BCM_AP_PANIC_ON_CPCRASH
		if ((BCMLOG_OUTDEV_SDCARD == BCMLOG_GetCpCrashLogDevice())
			&& cp_crashed == 1)
		#ifdef CONFIG_SEC_DEBUG
			cp_abort();
		#else
			abort();
		#endif /* CONFIG_SEC_DEBUG */
#endif

}
/*************************************************
*
*   Worker thread to dump CP crash log information.
*
*
*****************************************************/
void ProcessCPCrashedDump(struct work_struct *work)
{
	char crashReason[40] = { 0 };
	char crashFile[40] = { 0 };
	char crashThread[40] = { 0 };
	char outString[512] = { 0 };
	IPC_U32 *Dump;
	void __iomem *DumpVAddr;

#ifdef CONFIG_FB_BRCM_CP_CRASH_DUMP_IMAGE_SUPPORT
	rhea_display_crash_image(CP_CRASH_DUMP_START);
#endif

#ifdef CONFIG_BCM_AP_PANIC_ON_CPCRASH
	if (BCMLOG_OUTDEV_SDCARD == BCMLOG_GetCpCrashLogDevice()
#ifdef CONFIG_CDEBUGGER
		&& ramdump_enable == 1
#endif
#ifdef CONFIG_APANIC_ON_MMC
		&& ap_triggered == 0
#endif
		) {
		/* we kill AP when CP crashes */
		IPC_DEBUG(DBG_ERROR, "Crashing AP for Ramdump ...\n\n");
		#ifdef CONFIG_SEC_DEBUG
			cp_abort();
		#else
		abort();
		#endif /* CONFIG_SEC_DEBUG */
	}
	if ((BCMLOG_OUTDEV_NONE == BCMLOG_GetCpCrashLogDevice() ||
		BCMLOG_OUTDEV_PANIC == BCMLOG_GetCpCrashLogDevice() ||
		BCMLOG_OUTDEV_STM == BCMLOG_GetCpCrashLogDevice() ||
		BCMLOG_OUTDEV_RNDIS == BCMLOG_GetCpCrashLogDevice())
#ifdef CONFIG_APANIC_ON_MMC
		&& ap_triggered == 0
#endif
	    ) {
		/* we kill AP when CP crashes */
		IPC_DEBUG(DBG_ERROR, "Crashing AP now ...\n\n");
		#ifdef CONFIG_SEC_DEBUG
			cp_abort();
		#else
		abort();
		#endif /* CONFIG_SEC_DEBUG */
	}
#endif
	/* check for CP Reset here? Assuming CP Reset is just signified by
	a different crash code
	*/
	if (SmLocalControl.SmControl->CrashCode ==
			IPC_CP_SILENT_RESET_READY) {
		HandleCPResetStart();
		return;
	}

	IPC_Dump();

	RpcDbgDumpHistoryLogging(0, 0);

#if defined(CONFIG_BRCM_CP_CRASH_DUMP) \
	|| defined(CONFIG_BRCM_CP_CRASH_DUMP_EMMC) \
	|| defined(CONFIG_BCM_AP_PANIC_ON_CPCRASH)
	while (SmLocalControl.SmControl->CrashDump == NULL)
		; /* No op */
#endif

	/* **NOTE** for now, continue doing simple dump out IPC_DEBUG so there
	 * is some indication of CP crash in console
	 * (in case user not running MTT) */
	Dump = (void *)SmLocalControl.SmControl->CrashDump;

	IPC_DEBUG(DBG_ERROR, "ioremap_nocache\n");
	DumpVAddr = ioremap_nocache((UInt32) Dump,
				    sizeof(struct T_CRASH_SUMMARY));
	if (NULL == DumpVAddr) {
		IPC_DEBUG(DBG_ERROR, "VirtualAlloc failed\n");
		goto cleanUp;
	}

	IPC_DEBUG(DBG_ERROR, "Crash Summary Virtual Addr: 0x%08X\n",
		  (unsigned int)DumpVAddr);

	dumped_crash_summary_ptr = (struct T_CRASH_SUMMARY *)DumpVAddr;

	IPC_DEBUG(DBG_ERROR, "===== COMMS_PROCESSOR crash summary =====\r\n");

	if (dumped_crash_summary_ptr->link_signature) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->
				link_signature, outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->project_version) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->
				project_version, outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->DSP_version) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->DSP_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->FW_version) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->FW_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->decoder_version) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->
				decoder_version, outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	GetStringFromPA((UInt32) dumped_crash_summary_ptr->reason, crashReason,
			40);

	GetStringFromPA((UInt32) dumped_crash_summary_ptr->file, crashFile, 40);

	GetStringFromPA((UInt32) dumped_crash_summary_ptr->thread, crashThread,
			40);

	IPC_DEBUG(DBG_ERROR, "%s f=%s l=%d v=%d/0x%x t=%s TS=%d\r\n",
		  crashReason,
		  crashFile,
		  dumped_crash_summary_ptr->line,
		  dumped_crash_summary_ptr->value,
		  dumped_crash_summary_ptr->value,
		  crashThread, dumped_crash_summary_ptr->time);

#ifndef CONFIG_BCM_AP_PANIC_ON_CPCRASH
	/* done with "simple" dump, so now pull the full assert
	 * log from CP and dump out to MTT */
	DUMP_CP_assert_log();
#endif

cleanUp:

	if (NULL != DumpVAddr)
		iounmap(DumpVAddr);

#ifdef CONFIG_HAS_WAKELOCK
	wake_unlock(&ipc_wake_lock);
#endif

#ifdef CONFIG_BCM_AP_PANIC_ON_CPCRASH

#ifdef CONFIG_SEC_DEBUG
	cp_abort();
#endif /* CONFIG_SEC_DEBUG */

#endif /* CONFIG_AP_PANIC_ON_CPCRASH */

}