📄 excep.c
字号:
s = cause_names[ ((UINT32)context->cp0_cause & M_CauseExcCode) >> S_CauseExcCode ]; } if( msg == NULL ) { if (context == &ejtag_context) { printf( "EJTAG" ); } else { if( s ) printf("%s", s); else printf("Unknown exception code : 0x%02x", ((UINT32)context->cp0_cause & M_CauseExcCode) >> S_CauseExcCode ); } printf( " *\n" ); } /* CP0 registers */ sys_cp0_printreg_all( context ); printf( "\n" ); if( sys_fpu && (UINT32)context->cp0_status & M_StatusCU1 ) { regs = (UINT64 *)&context->fpr0; for(i=0; i<32; i++) { if( (UINT32)context->cp0_status & M_StatusFR ) { /* All 32 floating point registers are 64 bit wide */ j = ((i & 1) << 4) + (i >> 1); reg64 = regs[j]; printf("f%-2d:0x%08x%08x%s", j, HI32(reg64), LO32(reg64), (i & 1) == 1 ? "\n" : " "); } else { j = ((i & 3) << 3) + (i >> 2); printf("f%-2d:0x%08x%s", j, (UINT32)regs[j], (i & 3) == 3 ? "\n" : " "); } } printf( "\n" ); } shadowset = ( (UINT32)context->cp0_status & (M_StatusBEV | M_StatusERL) ) ? ((UINT32)context->cp0_srsctl & M_SRSCtlCSS) >> S_SRSCtlCSS : ((UINT32)context->cp0_srsctl & M_SRSCtlPSS) >> S_SRSCtlPSS; if( shadowset != 0 ) printf( "* Register set %d *\n", shadowset ); regs = (UINT64 *)&context->reg0; for(i=0; i<REG_NAMES_COUNT; i++) { if( sys_64bit ) { j = ((i & 1) << 4) + (i >> 1); reg64 = regs[j]; printf("$%2d(%s):0x%08x%08x%s", j, reg_names[j], HI32(reg64), LO32(reg64), (i & 1) == 1 ? "\n" : " "); } else { j = ((i & 3) << 3) + (i >> 2); printf("$%2d(%s):0x%08x%s", j, reg_names[j], (UINT32)regs[j], (i & 3) == 3 ? "\n" : " "); } }}/************************************************************************ * * EXCEP_run_default_esr_handler * Description : * ------------- * Runs default exception handler. * Called by North Bridge Interrupt handlers (init_core.c) * to print out context and possibly continue (go.c). * * Return values : * --------------- * None - may not return * ************************************************************************/voidEXCEP_run_default_esr_handler( void ){ if( table.default_exception.handler == NULL ) { /* No default ESR has been registered, so call our own */ default_handler( NULL, NULL ); /* (never returns). */ } table.default_exception.handler();}/************************************************************************ * * exception_sr * Description : * ------------- * * This function implements the exception handler, which gets called * by the first-level exception handler. According to the parameter * 'exc_code', any user registered exception handler for the asserted * exception, will be called from this function. * * Parameters : * ------------ * * exc_code the exception code from the 5-bit ExcCode-field in * the CP0-status register. * * Return values : * --------------- * * None * ************************************************************************/void exception_sr( UINT32 exc_code, UINT32 exc_vector_offs, t_gdb_regs *p_exc_context, UINT32 exc_return_flag ){ t_EXCEP_handler *reg_esr; bool default_handling; t_EXCEP_handler int_esr; /* First check for NMI and CacheErr */ if (exc_vector_offs == SYS_NMI_RAM_VECTOR_OFS) { /* EXCEP_nmi is cleared by SYSCON_write(SYSCON_BOARD_NMI_ACK_ID) */ EXCEP_nmi = TRUE; default_handler( NULL, p_exc_context ); return; /* default_handler never returns */ } if (exc_vector_offs == SYS_CACHEERR_RAM_VECTOR_OFS) { cacheerr_handler( p_exc_context ); return; /* cacheerr_handler never returns */ } if( exc_code < MAX_EXCEPTIONS ) { reg_esr = &table.exception[exc_code]; default_handling = (reg_esr->handler == NULL); } else default_handling = TRUE; if( exc_return_flag ) { /* A registered exception handler was invoked for this * exception, but it called EXCEP_return(). * This means that it does not want to handle the exception, * so we must handle it. * * Case 1 : If the exception handler was the ESR registered * for interrupts, we assume an application has * registered an ESR for the interrupt exception. * So, we call the ESR, which is used by YAMON * for handling interrupt exceptions, i.e. * interrupt_sr(). * * Case 2 : If the exception handler was a specific one, * other than interrupt, we try default handling. * * Case 3 : If the exception handler was the default ESR, * we must call default_handler(). */ if( exc_return_flag != 1) { /* nested calls to EXCEP_return() */ default_handler( NULL, p_exc_context ); return; /* default_handler never returns */ } if( exc_code == EX_INT ) { /* Case 1 */ interrupt_sr(); return; } else if( !default_handling ) { /* Case 2 */ default_handling = TRUE; } else { /* Case 3 */ default_handler( NULL, p_exc_context ); return; /* default_handler never returns */ } } if( default_handling ) { /* Either EXCEP_return() was called (se above), or * there is no registered ESR for the specific exception. * Check if there is a registered default ESR. */ reg_esr = &table.default_exception; if( reg_esr->handler == NULL ) { /* No default ESR has been registered, so call our own */ default_handler( NULL, p_exc_context ); return; /* default_handler never returns */ } } if( reg_esr->raw ) EXCEP_exc_handler_jump( reg_esr->handler ); else reg_esr->handler();}/************************************************************************ * * exception_ejtag * Description : * ------------- * This function implements the ejtag exception handler, called from * the low-level ejtag exception handler. A user registered exception * handler for the specific exception will be called from this function. * A user registered default ESR handler will NOT be called, since there * is no way to distinguish an ejtag exception. * * Parameters : * ------------ * none * * Return values : * --------------- * None ************************************************************************/void exception_ejtag( t_gdb_regs *p_exc_context, UINT32 exc_return_flag ){ t_EXCEP_handler *reg_esr; reg_esr = &table.ejtag; if( exc_return_flag || reg_esr->handler == NULL ) { default_handler( NULL, p_exc_context ); return; /* default_handler never returns */ } if( reg_esr->raw ) EXCEP_exc_handler_jump( reg_esr->handler ); else reg_esr->handler();}/************************************************************************ * Implementation : Static functions ************************************************************************//************************************************************************ * * interrupt_sr * Description : * ------------- * * This function implements the CPU interrupt handler, which is * registered for the interrupt exception. * * Return values : * --------------- * * None * ************************************************************************/static void interrupt_sr( void ){ UINT32 h, index; UINT32 int_pending; t_EXCEP_int_handler_list *table_interrupt; t_INT_handler *int_handler; t_gdb_regs *p_context; /* Determine the pending interrupts based on CAUSE register IP field * masked with STATUS register IM (Interrupt mask) field. */ p_context = EXCEP_get_context_ptr(); int_pending = ((p_context->cp0_cause & M_CauseIP) >> S_CauseIP) & ((p_context->cp0_status & M_StatusIM) >> S_StatusIM); /* validate 'int_pending' */ if(int_pending <= (M_CauseIP >> S_CauseIP) ) { /* Handle the 8 possible interrupts: 0..7 */ /* do call handlers for all pending interrupts */ for (; int_pending; int_pending ^= 1 << index) { /* Handle the interrupts in a sequence, 7..0 */ index = byte2msbit[int_pending]; /* Now, use the derived index to call into the * handler table (index = interrupt line). */ table_interrupt = &table.interrupt[index]; if( table_interrupt->list_size == 0 ) { /* No registered handler, so use default */ if( table.default_int.handler ) { /* A default handler has been registered, so call it */ table.default_int.handler(table.default_int.data); } else { /* No default handler has been registered, so call our own */ default_handler( "Unregistered CPU interrupt occurred", NULL ); return; /* default_handler never returns */ } } else { /* For one int. line, more handlers may be registered */ for( h=0; h < INT_HANDLERS_PER_LINE; h++) { int_handler = &table_interrupt->int_handler[h]; if( int_handler->handler != NULL) (*int_handler->handler)(int_handler->data); } } } } else { /* Should not happen */ while(1); }}/************************************************************************ * * controller_sr * Description : * ------------- * * This function implements the generic interrupt handler for the * interrupt controller. It gets called by the second-level * interrupt handler (interrupt_sr), when the HW-INT-line of * the interrupt controller is asserted. * * Return values : * --------------- * * None * ************************************************************************/static void controller_sr( void *data ) /* Data pointer set during registration (NULL) */{ UINT32 pending, mask, int_set; UINT32 h, j, index; char msg[80]; /* get the pending controller interrupts */ while( (pending = arch_excep_pending()) != 0) { mask = pending; /* handle the max. int. sources in rounds of 8 */ j = 0; while( j<MAX_IC ) { /* select this round's max. 8 int. sources */ int_set = (pending & 0x000000ff); /* check for any set */ for (; int_set; int_set ^= 1 << (index & 7)) { /* Handle the interrupts in a sequence, 7..0 */ index = byte2msbit[int_set] + j; /* index == interrupt line */ /* Now, use the derived index to call into the * handler table. */ if( table.controller[index].list_size == 0 ) { /* No registered handler, so use default */ if( table.default_ctrl.handler ) { /* A default handler has been registered, so call it */ table.default_ctrl.handler(table.default_int.data); } else { /* No default handler has been registered, so call our own */ sprintf( msg, "Unregistered interrupt controller event occurred," " mask = 0x%08x", mask ); default_handler( msg, NULL ); return; /* default_handler never returns */ } } else { for( h=0; h < CTRL_HANDLERS_PER_LINE; h++) { /* For one int. line, more handlers may be registered */ if(table.controller[index].ctrl_handler[h].handler != NULL) { /* call the handlers in sequence */ (*table.controller[index].ctrl_handler[h].handler) (table.controller[index].ctrl_handler[h].data); } } } /* Issue End Of Interrupt (EOI) */ arch_excep_eoi(index); } pending /= 256; j += 8; } }}/************************************************************************ * * default_handler * Description : * ------------- * * Default exception handler * ************************************************************************/static voiddefault_handler( char *msg, t_gdb_regs *p_context ){ /* Print context */ EXCEP_print_context( p_context, msg, FALSE, TRUE ); /* Take a breath */ sys_wait_ms(1000); /* re-initialize shell context and enter shell prompt */ shell_reenter( FALSE );}/************************************************************************ * * cacheerr_handler * Description : * ------------- * * CacheErr exception handler * ************************************************************************/static voidcacheerr_handler( t_gdb_regs *p_context ){ /* Change modified context->C0_config to its unmodified value */ p_context->cp0_config = (INT64)EXCEP_C0_Config_cacheerr; /* Display error type */ DISP_STR( "CacheErr" ); /* Print context */ EXCEP_cacheerr = TRUE; EXCEP_print_context( p_context, NULL, FALSE, FALSE ); EXCEP_cacheerr = FALSE; /* Take a breath */ sys_wait_ms(1000); /* re-initialize shell context and enter shell prompt */ shell_reenter( TRUE );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -