static void decode_exception(glite_delegation_ctx *ctx, struct SOAP_ENV__Detail *detail, const char *method) { char *message; if (!detail) return; #if _GSOAP_VERSION >= 0x020700 #define SET_EXCEPTION(exc) \ message = ((struct _delegation__ ## exc *)detail->fault)->msg; \ if (!message) \ message = #exc " received from the service"; \ glite_delegation_set_error(ctx, "%s: %s", method, message); \ ctx->error = 1; #else #define SET_EXCEPTION(exc) \ message = ((struct _delegation__ ## exc *)detail->value)->msg; \ if (!message) \ message = #exc " received from the service"; \ glite_delegation_set_error(ctx, "%s: %s", method, message); \ ctx->error = 1; #endif switch (detail->__type) { case SOAP_TYPE__delegation__DelegationException: SET_EXCEPTION(DelegationException); break; default: /* Let the generic error decoding handle this */ break; } #undef SET_EXCEPTION }
//***************************************************************************** // //***************************************************************************** void R4300_Exception_Break() { DAEDALUS_ASSERT( gExceptionVector == u32(~0), "Exception vector already set" ); DAEDALUS_ASSERT( gExceptionPC == u32(~0), "Exception PC already set" ); SET_EXCEPTION( CAUSE_EXCMASK, EXC_BREAK ); gExceptionVector = E_VEC; gExceptionPC = gCPUState.CurrentPC; gExceptionWasDelay = gCPUState.Delay == EXEC_DELAY; gCPUState.AddJob( CPU_CHECK_EXCEPTIONS ); }
//***************************************************************************** // //***************************************************************************** void R4300_Exception_CopUnusuable() { DAEDALUS_ASSERT( gExceptionVector == u32(~0), "Exception vector already set" ); DAEDALUS_ASSERT( gExceptionPC == u32(~0), "Exception PC already set" ); // XXXX check we're not inside exception handler before snuffing CAUSE reg? SET_EXCEPTION( (CAUSE_EXCMASK|CAUSE_CEMASK), (EXC_CPU|SR_CU0) ); //gCPUState.CPUControl[C0_CAUSE]._u32 &= 0xCFFFFFFF; //gCPUState.CPUControl[C0_CAUSE]._u32 |= SR_CU0; gExceptionVector = E_VEC; gExceptionPC = gCPUState.CurrentPC; gExceptionWasDelay = gCPUState.Delay == EXEC_DELAY; gCPUState.AddJob( CPU_CHECK_EXCEPTIONS ); }
//***************************************************************************** // //***************************************************************************** void R4300_Exception_TLB( u32 virtual_address, u32 exception_code, u32 exception_vector ) { DAEDALUS_ASSERT( gExceptionVector == u32(~0), "Exception vector already set" ); DAEDALUS_ASSERT( gExceptionPC == u32(~0), "Exception PC already set" ); gCPUState.CPUControl[C0_BADVADDR]._u32 = virtual_address; gCPUState.CPUControl[C0_CONTEXT]._u32 &= 0xFF800000; // Mask off bottom 23 bits gCPUState.CPUControl[C0_CONTEXT]._u32 |= ((virtual_address >> 13) << 4); gCPUState.CPUControl[C0_ENTRYHI]._u32 &= 0x00001FFF; // Mask off the top bit 13-31 gCPUState.CPUControl[C0_ENTRYHI]._u32 |= (virtual_address & 0xFFFFE000); SET_EXCEPTION( CAUSE_EXCMASK, exception_code ); gExceptionVector = exception_vector; gExceptionPC = gCPUState.CurrentPC; gExceptionWasDelay = gCPUState.Delay == EXEC_DELAY; gCPUState.AddJob( CPU_CHECK_EXCEPTIONS ); }
//***************************************************************************** // //***************************************************************************** void R4300_Handle_Interrupt() { #ifdef DAEDALUS_ENABLE_ASSERTS bool mi_interrupt_set( (Memory_MI_GetRegister(MI_INTR_MASK_REG) & Memory_MI_GetRegister(MI_INTR_REG)) != 0 ); bool cause_int_3_set( (gCPUState.CPUControl[C0_CAUSE]._u32 & CAUSE_IP3) != 0 ); DAEDALUS_ASSERT( mi_interrupt_set == cause_int_3_set, "CAUSE_IP3 inconsistant with MI_INTR_REG (%08x)", Memory_MI_GetRegister(MI_INTR_MASK_REG) & Memory_MI_GetRegister(MI_INTR_REG) ); #endif if( (gCPUState.CPUControl[C0_SR]._u32 & (SR_EXL | SR_ERL | SR_IE)) == SR_IE ) // Ensure ERL/EXL are "0" and IE is "1" { if(gCPUState.CPUControl[C0_SR]._u32 & gCPUState.CPUControl[C0_CAUSE]._u32 & CAUSE_IPMASK) // Are interrupts pending/wanted? { #ifdef DAEDALUS_PROFILE_EXECUTION gNumInterrupts++; #endif SET_EXCEPTION( CAUSE_EXCMASK, EXC_INT ); R4300_JumpToInterruptVector( E_VEC ); } } }