mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 04:20:46 +00:00
[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:
parent
a19af9c7cb
commit
ae6d759f4c
4 changed files with 260 additions and 1 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue