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; }
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 } }
/************************************************* * * 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 */ }