diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 45d47d1612a..56f3ee013c2 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -298,8 +298,8 @@ KeReadStateThread(IN PKTHREAD Thread); BOOLEAN FASTCALL KiSwapContext( - IN PKTHREAD CurrentThread, - IN PKTHREAD NewThread + IN KIRQL WaitIrql, + IN PKTHREAD CurrentThread ); VOID diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 7b4446a543b..9895cae3f27 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -534,7 +534,7 @@ KiQuantumEnd(VOID) Thread->WaitIrql = APC_LEVEL; /* Swap threads */ - KiSwapContext(Thread, NextThread); + KiSwapContext(APC_LEVEL, Thread); /* Lower IRQL back to DISPATCH_LEVEL */ KeLowerIrql(DISPATCH_LEVEL); diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 1ae3aaf18bc..9a9c95f4db1 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -13,70 +13,20 @@ #include .intel_syntax noprefix -#define Ready 1 -#define Running 2 -#define WrDispatchInt 0x1F - /* FUNCTIONS ****************************************************************/ -/*++ - * KiSwapContextInternal - * - * The KiSwapContextInternal routine switches context to another thread. - * - * Params: - * ESI - Pointer to the KTHREAD to which the caller wishes to - * switch to. - * EDI - Pointer to the KTHREAD to which the caller wishes to - * switch from. - * - * Returns: - * None. - * - * Remarks: - * Absolutely all registers except ESP can be trampled here for maximum code flexibility. - * - *--*/ .globl @KiSwapContextInternal@0 .func @KiSwapContextInternal@0, @KiSwapContextInternal@0 @KiSwapContextInternal@0: - /* Set APC Bypass Disable and old thread pointer */ - mov edx, edi - or dl, cl - /* Build switch frame */ sub esp, 2 * 4 mov ecx, esp - call @KiSwapContextEntry@8 - mov ecx, 0xB00BFACA - jmp $ + jmp @KiSwapContextEntry@8 .endfunc -/*++ - * KiSwapContext - * - * The KiSwapContext routine switches context to another thread. - * - * Params: - * TargetThread - Pointer to the KTHREAD to which the caller wishes to - * switch to. - * - * Returns: - * The WaitStatus of the Target Thread. - * - * Remarks: - * This is a wrapper around KiSwapContextInternal which will save all the - * non-volatile registers so that the Internal function can use all of - * them. It will also save the old current thread and set the new one. - * - * The calling thread does not return after KiSwapContextInternal until - * another thread switches to IT. - * - *--*/ .globl @KiSwapContext@8 .func @KiSwapContext@8, @KiSwapContext@8 @KiSwapContext@8: - /* Save 4 registers */ sub esp, 4 * 4 @@ -86,17 +36,8 @@ mov [esp+4], edi mov [esp+0], ebp - /* Get the current KPCR */ - mov ebx, fs:[KPCR_SELF] - - /* Get the Current Thread */ - mov edi, ecx - - /* Get the New Thread */ - mov esi, edx - /* Get the wait IRQL */ - movzx ecx, byte ptr [edi+KTHREAD_WAIT_IRQL] + or dl, cl /* Do the swap with the registers correctly setup */ call @KiSwapContextInternal@0 @@ -112,10 +53,21 @@ ret .endfunc +.globl @KiSwitchThreads@8 +.func @KiSwitchThreads@8, @KiSwitchThreads@8 +@KiSwitchThreads@8: + /* Load the new kernel stack and switch OS to new thread */ + mov esp, edx + call @KiSwapContextExit@8 + + /* Now we're on the new thread. Return to the caller to restore registers */ + add esp, 2 * 4 + ret +.endfunc + .globl @KiRetireDpcListInDpcStack@8 .func @KiRetireDpcListInDpcStack@8, @KiRetireDpcListInDpcStack@8 @KiRetireDpcListInDpcStack@8: - /* Switch stacks and retire DPCs */ mov eax, esp mov esp, edx @@ -140,20 +92,6 @@ _Ki386SetupAndExitToV86Mode@4: jmp $ .endfunc -.globl @KiSwitchThreads@8 -.func @KiSwitchThreads@8, @KiSwitchThreads@8 -@KiSwitchThreads@8: - - /* Load the new kernel stack and switch OS to new thread */ - mov esp, [edx+KTHREAD_KERNEL_STACK] - mov edx, esp - call @KiSwapContextExit@8 - - /* Now we're on the new thread. Return to the caller to restore registers */ - add esp, 2 * 4 - ret -.endfunc - .globl @Ki386BiosCallReturnAddress@4 @Ki386BiosCallReturnAddress@4: diff --git a/reactos/ntoskrnl/ke/i386/thrdini.c b/reactos/ntoskrnl/ke/i386/thrdini.c index 338a10cb293..b90ae664d96 100644 --- a/reactos/ntoskrnl/ke/i386/thrdini.c +++ b/reactos/ntoskrnl/ke/i386/thrdini.c @@ -309,7 +309,7 @@ KiIdleLoop(VOID) NewThread->State = Running; /* Switch away from the idle thread */ - KiSwapContext(OldThread, NewThread); + KiSwapContext(APC_LEVEL, OldThread); /* We are back in the idle thread -- disable interrupts again */ _enable(); @@ -416,9 +416,6 @@ KiSwapContextEntry(IN PKSWITCHFRAME SwitchFrame, PKTHREAD OldThread, NewThread; ULONG Cr0, NewCr0; - /* Switch threads, check for APC disable */ - ASSERT(OldThreadAndApcFlag &~ 1); - /* Save APC bypass disable */ SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3; SwitchFrame->ExceptionList = Pcr->NtTib.ExceptionList; @@ -451,7 +448,7 @@ KiSwapContextEntry(IN PKSWITCHFRAME SwitchFrame, /* Now enable interrupts and do the switch */ _enable(); - KiSwitchThreads(OldThread, NewThread); + KiSwitchThreads(OldThread, NewThread->KernelStack); } VOID @@ -509,8 +506,8 @@ KiDispatchInterrupt(VOID) /* Make the old thread ready */ KxQueueReadyThread(OldThread, Prcb); - /* Swap to the new thread. FIXME: APC Bypass */ - KiSwapContext(OldThread, NewThread); + /* Swap to the new thread */ + KiSwapContext(APC_LEVEL, OldThread); } } diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c index 040073cdb09..d100c3b8900 100644 --- a/reactos/ntoskrnl/ke/thrdschd.c +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -387,7 +387,7 @@ KiSwapThread(IN PKTHREAD CurrentThread, WaitIrql = CurrentThread->WaitIrql; /* Swap contexts */ - ApcState = KiSwapContext(CurrentThread, NextThread); + ApcState = KiSwapContext(WaitIrql, CurrentThread); /* Get the wait status */ WaitStatus = CurrentThread->WaitStatus; @@ -754,7 +754,7 @@ NtYieldExecution(VOID) ASSERT(OldIrql <= DISPATCH_LEVEL); /* Swap to new thread */ - KiSwapContext(Thread, NextThread); + KiSwapContext(APC_LEVEL, Thread); Status = STATUS_SUCCESS; } else diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index a4737b0b7fa..3fc51062ba4 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -249,7 +249,7 @@ KiExitDispatcher(IN KIRQL OldIrql) Thread->WaitIrql = OldIrql; /* Swap threads and check if APCs were pending */ - PendingApc = KiSwapContext(Thread, NextThread); + PendingApc = KiSwapContext(OldIrql, Thread); if (PendingApc) { /* Lower only to APC */