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; //patch-s from Broadcom for csp#529767 reason:FALSE file=ripisr_cp.c line=342 code=-1/0xffffffff tastk=RIP_H TS=48744870/FN=4873 //reviewed by yuan /* Dumping Camera registers. MobC00180667 */ { int i = 0; unsigned int camera_addr_base = 0x08440000; // Receiver Status reg set printk("\n Dumping Camera registers\n"); for(i = 0; i < 8; i ++) { printk("Addr: 0x%x Value: 0x%x\n", camera_addr_base, readl(io_p2v(camera_addr_base))); camera_addr_base += 4; } camera_addr_base = 0x08440080; // Debug register set for(i = 0; i < 9; i ++) { printk("Addr: 0x%x Value: 0x%x\n", camera_addr_base, readl(io_p2v(camera_addr_base))); camera_addr_base += 4; } camera_addr_base = 0x08440100; // Channel information set for(i = 0; i < 12; i ++) { printk("Addr: 0x%x Value: 0x%x\n", camera_addr_base, readl(io_p2v(camera_addr_base))); camera_addr_base += 4; } camera_addr_base = 0x08440400; // Ping pong buffer management printk("Addr: 0x%x Value: 0x%x\n", camera_addr_base, readl(io_p2v(camera_addr_base))); } /* End of Camera register dump */ //patch-e from Broadcom for csp#529767 reason:FALSE file=ripisr_cp.c line=342 code=-1/0xffffffff tastk=RIP_H TS=48744870/FN=4873 if( BCMLOG_CPCRASH_MTD == BCMLOG_GetCpCrashDumpDevice() ) { /* we kill AP when CP crashes */ IPC_DEBUG(DBG_INFO, "Crashing AP now...\n\n"); abort(); } else { ProcessCPCrashedDump(work); } IPC_ProcessEvents(); }else { IPC_ProcessEvents(); #ifdef CONFIG_HAS_WAKELOCK wake_unlock(&ipc_wake_lock); #endif // CONFIG_HAS_WAKELOCK } }
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 } }
/** * 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; mm_segment_t oldfs; struct timespec ts; struct rtc_time tm; char assertFileName[CP_CRASH_DUMP_MAX_LEN]; extern void abort(void); // need to tell kernel that pointers from within the // kernel address space are valid (needed to do // file ops from kernel) oldfs = get_fs(); set_fs (KERNEL_DS); if( BCMLOG_CPCRASH_SDCARD == BCMLOG_GetCpCrashDumpDevice() ) { // get current time getnstimeofday(&ts); rtc_time_to_tm(ts.tv_sec, &tm); snprintf(assertFileName, CP_CRASH_DUMP_MAX_LEN, "%s%s%d_%02d_%02d_%02d_%02d_%02d%s", CP_CRASH_DUMP_DIR, CP_CRASH_DUMP_BASE_FILE_NAME, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, CP_CRASH_DUMP_FILE_EXT ); sdDumpFile = filp_open( assertFileName, O_WRONLY|O_TRUNC|O_LARGEFILE|O_CREAT, 666); if ( IS_ERR(sdDumpFile) ) { IPC_DEBUG(DBG_ERROR,"failed to open sdDumpFile %s\n", assertFileName); sdDumpFile = NULL; } else { IPC_DEBUG(DBG_ERROR,"sdDumpFile %s opened OK\n",assertFileName); } } // 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_ERROR,"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_INFO, "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 } 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( ); if ( sdDumpFile ) { filp_close( sdDumpFile ,NULL ); } set_fs (oldfs); sys_sync(); IPC_DEBUG(DBG_ERROR,"CP crash dump complete\n"); if (BCMLOG_CPCRASH_MTD != BCMLOG_GetCpCrashDumpDevice()) abort(); #ifdef CONFIG_BRCM_KPANIC_UI_IND else lcdc_disp_img(IMG_INDEX_END_DUMP); //parameter 1: Draw the Kpanic Dump complete picture #endif }