mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:45:50 +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();
|
KeFlushTb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KeZeroPages(IN PVOID Address,
|
||||||
|
IN ULONG Size)
|
||||||
|
{
|
||||||
|
/* Not using XMMI in this routine */
|
||||||
|
RtlZeroMemory(Address, Size);
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
|
KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
TEXTAREA
|
TEXTAREA
|
||||||
NESTED_ENTRY KiSwapContext
|
NESTED_ENTRY KiSwapContext
|
||||||
PROLOG_END KiSwapContext
|
PROLOG_END KiSwapContext
|
||||||
|
|
||||||
|
// BUSTEDDDD
|
||||||
|
b .
|
||||||
|
|
||||||
//
|
//
|
||||||
// a1 = Old Thread
|
// a1 = Old Thread
|
||||||
// a2 = New Thread
|
// a2 = New Thread
|
||||||
|
@ -104,3 +108,19 @@
|
||||||
b .
|
b .
|
||||||
|
|
||||||
ENTRY_END KiThreadStartup
|
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 ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
typedef struct _KSWITCHFRAME
|
||||||
|
{
|
||||||
|
PVOID ExceptionList;
|
||||||
|
BOOLEAN ApcBypassDisable;
|
||||||
|
PVOID RetAddr;
|
||||||
|
} KSWITCHFRAME, *PKSWITCHFRAME;
|
||||||
|
|
||||||
typedef struct _KUINIT_FRAME
|
typedef struct _KUINIT_FRAME
|
||||||
{
|
{
|
||||||
KEXCEPTION_FRAME CtxSwitchFrame;
|
KEXCEPTION_FRAME CtxSwitchFrame;
|
||||||
|
@ -32,6 +39,15 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KiThreadStartup(VOID);
|
KiThreadStartup(VOID);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KiSwitchThreads(
|
||||||
|
IN PKTHREAD OldThread,
|
||||||
|
IN PKTHREAD NewThread
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME: THIS IS TOTALLY BUSTED NOW */
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KiInitializeContextThread(IN PKTHREAD Thread,
|
KiInitializeContextThread(IN PKTHREAD Thread,
|
||||||
|
@ -131,3 +147,217 @@ KiInitializeContextThread(IN PKTHREAD Thread,
|
||||||
//
|
//
|
||||||
Thread->KernelStack = (PVOID)CtxSwitchFrame;
|
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)
|
@ FASTCALL ExInterlockedAddLargeStatistic(ptr long)
|
||||||
#endif
|
#endif
|
||||||
@ stdcall ExInterlockedAddUlong(ptr long ptr)
|
@ stdcall ExInterlockedAddUlong(ptr long ptr)
|
||||||
#ifndef __x86_64__
|
#ifdef __x86__
|
||||||
@ FASTCALL ExInterlockedCompareExchange64(ptr ptr ptr ptr)
|
@ FASTCALL ExInterlockedCompareExchange64(ptr ptr ptr ptr)
|
||||||
@ stdcall ExInterlockedDecrementLong(ptr ptr)
|
@ stdcall ExInterlockedDecrementLong(ptr ptr)
|
||||||
@ stdcall ExInterlockedExchangeUlong(ptr long ptr)
|
@ stdcall ExInterlockedExchangeUlong(ptr long ptr)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue