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
	}
}
示例#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
   }
}
/**	
*   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

}