void DumpExcInfoX(TArmExcInfo& a) { DumpExcInfo(a); NThread* nthread = NCurrentThread(); if (nthread == NULL) Kern::Printf("No current thread"); else { DThread* thread = Kern::NThreadToDThread(NCurrentThread()); if (thread) { TFullName thread_name; thread->TraceAppendFullName(thread_name, EFalse); Kern::Printf("Thread full name=%S", &thread_name); Kern::Printf("Thread ID=%d, KernCSLocked=%d",TheCurrentThread->iId,NKern::KernelLocked()); } else Kern::Printf("Thread N/A, KernCSLocked=%d",NKern::KernelLocked()); } }
void NKern::CancelUserModeCallbacks() { // Call any queued callbacks with the EUserModeCallbackCancel reason code, in the current // thread. TUserModeCallback* listHead = (TUserModeCallback*)__e32_atomic_swp_ord_ptr(&NCurrentThread()->iUserModeCallbacks, NULL); while (listHead) { TUserModeCallback* callback = listHead; listHead = listHead->iNext; callback->iNext = KUserModeCallbackUnqueued; __e32_memory_barrier(); callback->iFunc(callback, EUserModeCallbackCancel); } }
void NKern::CancelUserModeCallbacks() { // Call any queued callbacks with the EUserModeCallbackCancel reason code, in the current // thread. NThreadBase* thread = NCurrentThread(); NKern::Lock(); TUserModeCallback* listHead = thread->iUserModeCallbacks; thread->iUserModeCallbacks = NULL; NKern::Unlock(); while (listHead != NULL) { TUserModeCallback* callback = listHead; listHead = listHead->iNext; callback->iNext = KUserModeCallbackUnqueued; callback->iFunc(callback, EUserModeCallbackCancel); } }
EXPORT_C void NKern::ThreadGetUserContext(NThread* aThread, TAny* aContext, TUint32& aAvailMask) { CHECK_PRECONDITIONS(MASK_INTERRUPTS_ENABLED|MASK_NOT_ISR|MASK_NOT_IDFC, "NKern::ThreadGetUserContext"); TUint32* sp; TUint32* stackTop; TX86RegSet* regSet = (TX86RegSet*)aContext; TInt delta; NKern::Lock(); NThread* currentThread = NCurrentThread(); DEBUGPRINT(" NCurrentThread()=0x%x, aThread=0x%x", currentThread, aThread); switch (NKern::CurrentContext()) { case NKern::EThread: DEBUGPRINT(" CurrentContext=NKern::EThread"); break; case NKern::EIDFC: DEBUGPRINT(" CurrentContext=NKern::EIDFC"); break; case NKern::EInterrupt: DEBUGPRINT(" CurrentContext=NKern::EInterrupt"); break; default: DEBUGPRINT(" CurrentContext= Unknown"); break; } DEBUGPRINT(" Attributes (iSpare2)=0x%x", aThread->iSpare2); DEBUGPRINT(" iExtraContext=0x%x, iExtraContextSize=0x%x", aThread->iExtraContext, aThread->iExtraContextSize); DEBUGPRINT(" iSuspendCount=%d", aThread->iSuspendCount); DEBUGPRINT(" X86_IrqStack=%x", X86_IrqStack); TBool isCurrentThread = (currentThread == aThread); sp = (TUint32*)aThread->iSavedSP; stackTop = (TUint32*)((TUint32)aThread->iStackBase+(TUint32)aThread->iStackSize); delta = stackTop - sp; // number of words on the supervisor stack DEBUGPRINT(" Stack Top=iStackBase+iStackSize=0x%x iSavedSP=0x%x, delta=0x%x", stackTop, sp, delta); DEBUGPRINT(" iUserContextType (iSpare3)=0x%x", aThread->iSpare3); DEBUGPRINT(" NThreadState:"); switch(aThread->iSpare1) { case NThreadBase::EReady: DEBUGPRINT(" EReady"); break; case NThreadBase::ESuspended: DEBUGPRINT(" ESuspended"); break; case NThreadBase::EWaitFastSemaphore: DEBUGPRINT(" EWaitFastSemaphore"); break; case NThreadBase::ESleep: DEBUGPRINT(" ESleep"); break; case NThreadBase::EBlocked: DEBUGPRINT(" EBlocked"); break; case NThreadBase::EDead: DEBUGPRINT(" EDead"); break; case NThreadBase::EWaitDfc: DEBUGPRINT(" EWaitDfc"); break; default: DEBUGPRINT(" *Unknown"); } if (aAvailMask) { DEBUGPRINT(" Setting Stack-Saved Registers"); // Hack while ThreadSetUserContext is not implemented if (0 == aThread->iSpare3) { // Context when interrupted by user if (aAvailMask & 1<<13) stackTop[-1] = regSet->iSs; if (aAvailMask & 1<<4) stackTop[-2] = regSet->iEsp; if (aAvailMask & 1<<14) { DEBUGPRINT(" Setting EFLAGS to %x", regSet->iEflags); stackTop[-3] = regSet->iEflags; } if (aAvailMask & 1<<8) stackTop[-4] = regSet->iCs; if (aAvailMask & 1<<15) stackTop[-5] = regSet->iEip; if (aAvailMask & 1<<9) stackTop[-8] = regSet->iDs; if (aAvailMask & 1<<0) stackTop[-9] = regSet->iEax; if (aAvailMask & 1<<2) stackTop[-10] = regSet->iEcx; if (aAvailMask & 1<<5) stackTop[-16] = regSet->iEbp; if (aAvailMask & 1<<7) stackTop[-17] = regSet->iEdi; if (aAvailMask & 1<<6) stackTop[-18] = regSet->iEsi; } else { if (aAvailMask & 1<<13) stackTop[-1] = regSet->iSs; if (aAvailMask & 1<<4) stackTop[-2] = regSet->iEsp; if (aAvailMask & 1<<14) { stackTop[-3] = regSet->iEflags; DEBUGPRINT(" Setting EFLAGS to %x", regSet->iEflags); } if (aAvailMask & 1<<8) stackTop[-4] = regSet->iCs; if (aAvailMask & 1<<15) stackTop[-5] = regSet->iEip; /* -6 and -7 are not used since they are the vector number and the error code, * which are 3 and 0 resp. for breakpoints. */ /* The following are from the push instructions in __X86VectorExc */ if (aAvailMask & 1<<9) stackTop[-8] = regSet->iDs; if (aAvailMask & 1<<10) stackTop[-9] = regSet->iEs; if (aAvailMask & 1<<11) stackTop[-10] = regSet->iFs; if (aAvailMask & 1<<12) stackTop[-11] = regSet->iGs; if (aAvailMask & 1<<5) stackTop[-12] = regSet->iEbp; if (aAvailMask & 1<<7) stackTop[-13] = regSet->iEdi; if (aAvailMask & 1<<6) stackTop[-14] = regSet->iEsi; if (aAvailMask & 1<<1) stackTop[-15] = regSet->iEbx; if (aAvailMask & 1<<2) stackTop[-16] = regSet->iEcx; if (aAvailMask & 1<<3) stackTop[-17] = regSet->iEdx; if (aAvailMask & 1<<0) stackTop[-18] = regSet->iEax; } DEBUGPRINT("stack from stack top, after changes " ); if (delta < 128) { delta = -delta; } else { delta = -128; } for ( ; delta < 0; delta++) { DEBUGPRINT("stackTop[%d]=%x", delta, stackTop[delta]); } } else { memclr(aContext, sizeof(TX86RegSet)); if (isCurrentThread) { // Not yet supported DEBUGPRINT(" NThread::GetContext() : Don't know how to obtain context for current thread\n Use TSS?"); } else { DEBUGPRINT("stack from stack top " ); if (delta < 128) { delta = -delta; } else { delta = -128; } for( ; delta < 0; delta++) { DEBUGPRINT("stackTop[%d]=%x", delta, stackTop[delta]); } if (0 == aThread->iSpare3) { // Context when interrupted by user regSet->iSs = stackTop[-1]; aAvailMask |= 1<<13; regSet->iEsp = stackTop[-2]; aAvailMask |= 1<<4; regSet->iEflags = stackTop[-3]; aAvailMask |= 1<<14; regSet->iCs = stackTop[-4]; aAvailMask |= 1<<8; regSet->iEip = stackTop[-5]; aAvailMask |= 1<<15; regSet->iDs = stackTop[-8]; aAvailMask |= 1<<9; regSet->iEax = stackTop[-9]; aAvailMask |= 1<<0; regSet->iEcx = stackTop[-10]; aAvailMask |= 1<<2; regSet->iEbp = stackTop[-16]; aAvailMask |= 1<<5; regSet->iEdi = stackTop[-17]; aAvailMask |= 1<<7; regSet->iEsi = stackTop[-18]; aAvailMask |= 1<<6; } else { // Now populate the TX86RegSet with the contents of the stack /* * The first 5 are from the comments at the start of __X86VectorExc : * [ESP+0] = vector number * [ESP+4] = error code (filled with 0 for exceptions without error codes) * [ESP+8] = return EIP * [ESP+12] = return CS * [ESP+16] = return EFLAGS * [ESP+20] = return ESP if privilege change occurred * [ESP+24] = return SS if privilege change occurred */ regSet->iSs = stackTop[-1]; aAvailMask |= 1<<13; regSet->iEsp = stackTop[-2]; aAvailMask |= 1<<4; regSet->iEflags = stackTop[-3]; aAvailMask |= 1<<14; regSet->iCs = stackTop[-4]; aAvailMask |= 1<<8; regSet->iEip = stackTop[-5]; aAvailMask |= 1<<15; /* -6 and -7 are not used since they are the vector number and the error code, * which for a breakpoint are 3 and 0 resp. */ /* The following are from the push instructions in __X86VectorExc */ regSet->iDs = stackTop[-8]; aAvailMask |= 1<<9; regSet->iEs = stackTop[-9]; aAvailMask |= 1<<10; regSet->iFs = stackTop[-10]; aAvailMask |= 1<<11; regSet->iGs = stackTop[-11]; aAvailMask |= 1<<12; regSet->iEbp = stackTop[-12]; aAvailMask |= 1<<5; regSet->iEdi = stackTop[-13]; aAvailMask |= 1<<7; regSet->iEsi = stackTop[-14]; aAvailMask |= 1<<6; regSet->iEbx = stackTop[-15]; aAvailMask |= 1<<1; regSet->iEcx = stackTop[-16]; aAvailMask |= 1<<2; regSet->iEdx = stackTop[-17]; aAvailMask |= 1<<3; regSet->iEax = stackTop[-18]; aAvailMask |= 1<<0; } // else if (0 == aThread->iSpare3) } // else if (isCurrentThread) } // else if (aAvailMask) NKern::Unlock(); }