Exemple #1
0
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());
		}
	}
Exemple #2
0
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);
		}
	}
Exemple #3
0
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);
		}
	}
Exemple #4
0
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();
	}