[NTOS]: Some more ARM build and linker fixes, moving some of the new x86 C code into ARM. This should really be shared later.

[NTOS]: Totally broke thread context switching on ARM for now. It's a Good Thing.

svn path=/trunk/; revision=49781
This commit is contained in:
Sir Richard 2010-11-24 17:49:52 +00:00
parent a19af9c7cb
commit ae6d759f4c
4 changed files with 260 additions and 1 deletions

View file

@ -57,6 +57,15 @@ KeFlushCurrentTb(VOID)
KeFlushTb();
}
VOID
FASTCALL
KeZeroPages(IN PVOID Address,
IN ULONG Size)
{
/* Not using XMMI in this routine */
RtlZeroMemory(Address, Size);
}
VOID
NTAPI
KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)

View file

@ -13,6 +13,10 @@
TEXTAREA
NESTED_ENTRY KiSwapContext
PROLOG_END KiSwapContext
// BUSTEDDDD
b .
//
// a1 = Old Thread
// a2 = New Thread
@ -104,3 +108,19 @@
b .
ENTRY_END KiThreadStartup
NESTED_ENTRY KiSwitchThreads
PROLOG_END KiSwitchThreads
// BUSTEDDDD
b .
ENTRY_END KiSwitchThreads
NESTED_ENTRY KiSwapContextInternal
PROLOG_END KiSwapContextInternal
// BUSTEDDDD
b .
ENTRY_END KiSwapContextInternal

View file

@ -14,6 +14,13 @@
/* GLOBALS ********************************************************************/
typedef struct _KSWITCHFRAME
{
PVOID ExceptionList;
BOOLEAN ApcBypassDisable;
PVOID RetAddr;
} KSWITCHFRAME, *PKSWITCHFRAME;
typedef struct _KUINIT_FRAME
{
KEXCEPTION_FRAME CtxSwitchFrame;
@ -32,6 +39,15 @@ VOID
NTAPI
KiThreadStartup(VOID);
VOID
FASTCALL
KiSwitchThreads(
IN PKTHREAD OldThread,
IN PKTHREAD NewThread
);
/* FIXME: THIS IS TOTALLY BUSTED NOW */
VOID
NTAPI
KiInitializeContextThread(IN PKTHREAD Thread,
@ -131,3 +147,217 @@ KiInitializeContextThread(IN PKTHREAD Thread,
//
Thread->KernelStack = (PVOID)CtxSwitchFrame;
}
VOID
FASTCALL
KiIdleLoop(VOID)
{
PKPRCB Prcb = KeGetCurrentPrcb();
PKTHREAD OldThread, NewThread;
/* Initialize the idle loop: disable interrupts */
_enable();
YieldProcessor();
YieldProcessor();
_disable();
/* Now loop forever */
while (TRUE)
{
/* Check for pending timers, pending DPCs, or pending ready threads */
if ((Prcb->DpcData[0].DpcQueueDepth) ||
(Prcb->TimerRequest) ||
(Prcb->DeferredReadyListHead.Next))
{
/* Quiesce the DPC software interrupt */
HalClearSoftwareInterrupt(DISPATCH_LEVEL);
/* Handle it */
KiRetireDpcList(Prcb);
}
/* Check if a new thread is scheduled for execution */
if (Prcb->NextThread)
{
/* Enable interupts */
_enable();
/* Capture current thread data */
OldThread = Prcb->CurrentThread;
NewThread = Prcb->NextThread;
/* Set new thread data */
Prcb->NextThread = NULL;
Prcb->CurrentThread = NewThread;
/* The thread is now running */
NewThread->State = Running;
/* Switch away from the idle thread */
KiSwapContext(APC_LEVEL, OldThread);
/* We are back in the idle thread -- disable interrupts again */
_enable();
YieldProcessor();
YieldProcessor();
_disable();
}
else
{
/* Continue staying idle. Note the HAL returns with interrupts on */
Prcb->PowerState.IdleFunction(&Prcb->PowerState);
}
}
}
BOOLEAN
FASTCALL
KiSwapContextExit(IN PKTHREAD OldThread,
IN PKSWITCHFRAME SwitchFrame)
{
PKIPCR Pcr = (PKIPCR)KeGetPcr();
PKPROCESS OldProcess, NewProcess;
PKTHREAD NewThread;
ARM_TTB_REGISTER TtbRegister;
/* We are on the new thread stack now */
NewThread = Pcr->PrcbData.CurrentThread;
/* Now we are the new thread. Check if it's in a new process */
OldProcess = OldThread->ApcState.Process;
NewProcess = NewThread->ApcState.Process;
if (OldProcess != NewProcess)
{
TtbRegister.AsUlong = NewProcess->DirectoryTableBase[0];
ASSERT(TtbRegister.Reserved == 0);
KeArmTranslationTableRegisterSet(TtbRegister);
}
/* Increase thread context switches */
NewThread->ContextSwitches++;
/* Load data from switch frame */
Pcr->NtTib.ExceptionList = SwitchFrame->ExceptionList;
/* DPCs shouldn't be active */
if (Pcr->PrcbData.DpcRoutineActive)
{
/* Crash the machine */
KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC,
(ULONG_PTR)OldThread,
(ULONG_PTR)NewThread,
(ULONG_PTR)OldThread->InitialStack,
0);
}
/* Kernel APCs may be pending */
if (NewThread->ApcState.KernelApcPending)
{
/* Are APCs enabled? */
if (!NewThread->SpecialApcDisable)
{
/* Request APC delivery */
if (SwitchFrame->ApcBypassDisable) HalRequestSoftwareInterrupt(APC_LEVEL);
return TRUE;
}
}
/* Return */
return FALSE;
}
VOID
FASTCALL
KiSwapContextEntry(IN PKSWITCHFRAME SwitchFrame,
IN ULONG_PTR OldThreadAndApcFlag)
{
PKIPCR Pcr = (PKIPCR)KeGetPcr();
PKTHREAD OldThread, NewThread;
/* Save APC bypass disable */
SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3;
SwitchFrame->ExceptionList = Pcr->NtTib.ExceptionList;
/* Increase context switch count and check if tracing is enabled */
Pcr->ContextSwitches++;
if (Pcr->PerfGlobalGroupMask)
{
/* We don't support this yet on x86 either */
DPRINT1("WMI Tracing not supported\n");
ASSERT(FALSE);
}
/* Get thread pointers */
OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3);
NewThread = Pcr->PrcbData.CurrentThread;
/* Get the old thread and set its kernel stack */
OldThread->KernelStack = SwitchFrame;
/* Do the switch */
KiSwitchThreads(OldThread, NewThread->KernelStack);
}
VOID
NTAPI
KiDispatchInterrupt(VOID)
{
PKIPCR Pcr = (PKIPCR)KeGetPcr();
PKPRCB Prcb = &Pcr->PrcbData;
PVOID OldHandler;
PKTHREAD NewThread, OldThread;
/* Disable interrupts */
_disable();
/* Check for pending timers, pending DPCs, or pending ready threads */
if ((Prcb->DpcData[0].DpcQueueDepth) ||
(Prcb->TimerRequest) ||
(Prcb->DeferredReadyListHead.Next))
{
/* Switch to safe execution context */
OldHandler = Pcr->NtTib.ExceptionList;
Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
/* Retire DPCs while under the DPC stack */
//KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack);
// FIXME!!! //
KiRetireDpcList(Prcb);
/* Restore context */
Pcr->NtTib.ExceptionList = OldHandler;
}
/* Re-enable interrupts */
_enable();
/* Check for quantum end */
if (Prcb->QuantumEnd)
{
/* Handle quantum end */
Prcb->QuantumEnd = FALSE;
KiQuantumEnd();
}
else if (Prcb->NextThread)
{
/* Capture current thread data */
OldThread = Prcb->CurrentThread;
NewThread = Prcb->NextThread;
/* Set new thread data */
Prcb->NextThread = NULL;
Prcb->CurrentThread = NewThread;
/* The thread is now running */
NewThread->State = Running;
OldThread->WaitReason = WrDispatchInt;
/* Make the old thread ready */
KxQueueReadyThread(OldThread, Prcb);
/* Swap to the new thread */
KiSwapContext(APC_LEVEL, OldThread);
}
}
/* EOF */

View file

@ -112,7 +112,7 @@
@ FASTCALL ExInterlockedAddLargeStatistic(ptr long)
#endif
@ stdcall ExInterlockedAddUlong(ptr long ptr)
#ifndef __x86_64__
#ifdef __x86__
@ FASTCALL ExInterlockedCompareExchange64(ptr ptr ptr ptr)
@ stdcall ExInterlockedDecrementLong(ptr ptr)
@ stdcall ExInterlockedExchangeUlong(ptr long ptr)