diff --git a/reactos/hal/hal/hal.c b/reactos/hal/hal/hal.c index 05400bf04bf..23ccbf835bf 100644 --- a/reactos/hal/hal/hal.c +++ b/reactos/hal/hal/hal.c @@ -446,6 +446,13 @@ HalRequestSoftwareInterrupt( UNIMPLEMENTED; } +VOID FASTCALL +HalClearSoftwareInterrupt( + IN KIRQL Request) +{ + UNIMPLEMENTED; +} + VOID NTAPI diff --git a/reactos/hal/hal/hal.def b/reactos/hal/hal/hal.def index 0e4c035630e..d6b38061a42 100644 --- a/reactos/hal/hal/hal.def +++ b/reactos/hal/hal/hal.def @@ -15,7 +15,7 @@ HalAllocateCrashDumpRegisters@8 HalAssignSlotResources@32 HalBeginSystemInterrupt@12 HalCalibratePerformanceCounter@4 -;@HalClearSoftwareInterrupt@4 +@HalClearSoftwareInterrupt@4 HalDisableSystemInterrupt@8 HalDisplayString@4 HalEnableSystemInterrupt@12 diff --git a/reactos/hal/halx86/generic/irql.c b/reactos/hal/halx86/generic/irql.c index fd55e42c1f7..f54f646d7fd 100644 --- a/reactos/hal/halx86/generic/irql.c +++ b/reactos/hal/halx86/generic/irql.c @@ -422,4 +422,23 @@ HalRequestSoftwareInterrupt( } } +VOID FASTCALL +HalClearSoftwareInterrupt( + IN KIRQL Request) +{ + switch (Request) + { + case APC_LEVEL: + ((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = FALSE; + break; + + case DISPATCH_LEVEL: + ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE; + break; + + default: + KEBUGCHECK(0); + } +} + /* EOF */ diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 5fbcd49b081..802b2d6582f 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -147,6 +147,7 @@ Author: #define KPCR_TSS 0x40 #define KPCR_SET_MEMBER 0x48 #define KPCR_NUMBER 0x51 +#define KPCR_PRCB_DATA 0x120 #define KPCR_CURRENT_THREAD 0x124 #define KPCR_PRCB_NEXT_THREAD 0x128 #define KPCR_PRCB_IDLE_THREAD 0x12C diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index b76e4d3689d..4f0fc71b9c2 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -472,6 +472,7 @@ BugCheckDpc: * *--*/ .globl @KiSwapContext@8 +.func @KiSwapContext@8, @KiSwapContext@8 @KiSwapContext@8: /* Note, we CANNOT touch ebp */ @@ -511,6 +512,130 @@ BugCheckDpc: /* Clean stack */ add esp, 4 * 4 ret +.endfunc + +.globl @KiIdleLoop@0 +.func @KiIdleLoop@0, @KiIdleLoop@0 +@KiIdleLoop@0: + + /* Jump into mainline code */ + jmp MainLoop + +CpuIdle: + /* Call the CPU's idle function */ +#if 0 + lea ecx, [ebx+KPCR_PRCB_POWER_STATE_IDLE_FUNCTION] + call [ecx] +#else + sti + hlt +#endif + +MainLoop: + /* Cycle interrupts for 1 cycle */ + sti + nop + nop + cli + + /* Check if we have to deliver DPCs, timers, or deferred threads */ + mov eax, [ebx+KPCR_PRCB_DPC_QUEUE_DEPTH] + or eax, [ebx+KPCR_PRCB_TIMER_REQUEST] +#ifdef CONFIG_SMP + or eax, [ebx+KPCR_PRCB_DEFERRED_READY_LIST_HEAD] +#endif + jz CheckSchedule + + /* Handle the above */ + lea ecx, [ebx+KPCR_PRCB_DATA] + call @KiRetireDpcList@4 + +CheckSchedule: + /* Check if a next thread is queued */ + cmp dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0 +#ifdef CONFIG_SMP + jz NoNextThread +#else + jz CpuIdle +#endif + +#ifdef CONFIG_SMP + /* There is, raise IRQL to synch level */ + mov ecx, SYNCH_LEVEL + call @KfRaiseIrql@4 +#endif + sti + + /* Set the current thread to ready */ + mov edi, [ebx+KPCR_CURRENT_THREAD] +#ifdef CONFIG_SMP + mov [edi+KTHREAD_STATE], Ready + + /* Acquire the PRCB Lock */ + lock bts [ebx+KPCR_PRCB_PRCB_LOCK], 0 + jnb CheckNext + lea ecx, [ebx+KPCR_PRCB_PRCB_LOCK] + call @KefAcquireSpinLockAtDpcLevel@4 +#endif + +CheckNext: + /* Check if the next thread is the current */ + mov esi, [ebx+KPCR_PRCB_NEXT_THREAD] +#ifdef CONFIG_SMP + cmp esi, edi + jz SameThread +#endif + + /* Clear the next thread and set this one instead */ + and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0 + mov [ebx+KPCR_CURRENT_THREAD], esi + + /* Set the thread as running */ + mov byte ptr [esi+KTHREAD_STATE], Running + +#ifdef CONFIG_SMP + /* Disable the idle scheduler and release the PRCB lock */ + and byte ptr [ebx+KPCR_PRCB_IDLE_SCHEDULE], 0 + and [ebx+KPCR_PRCB_PRCB_LOCK], 0 +#endif + +SwapContext: + /* Swap context at APC_LEVEL */ + mov ecx, APC_LEVEL + call @KiSwapContextInternal@0 + +#ifdef CONFIG_SMP + /* Lower to DPC level */ + mov ecx, DISPATCH_LEVEL + call @KfLowerIrql@4 +#endif + jmp MainLoop + +#ifdef CONFIG_SMP +SameThread: + /* Clear the next thread, and put the thready as ready after lock release */ + and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0 + and dword ptr [ebx+KPCR_PRCB_PRCB_LOCK], 0 + and byte ptr [edi+KTHREAD_STATE], Ready + jmp MainLoop + +NoNextThread: + /* Check if the idle scheduler is enabled */ + cmp byte ptr [ebx+KPCR_PRCB_IDLE_SCHEDULE], 0 + jz CpuIdle + + /* It is, so call the scheduler */ + lea ecx, [ebx+KPCR_PRCBDATA] + call @KiIdleSchedule@4 + test eax, eax + + /* Get new thread pointers and either swap or idle loop again */ + mov esi, eax + mov edi, [ebx+KPCR_PRCB_IDLE_THREAD] + jnz SwapContext + jmp MainLoop +#endif +.endfunc .globl _Ki386AdjustEsp0@4 .func Ki386AdjustEsp0@4 diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 30f4e239246..ce341471dfd 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -292,7 +292,6 @@ debug.c - idle.c job.c kill.c notify.c diff --git a/reactos/ntoskrnl/ps/idle.c b/reactos/ntoskrnl/ps/idle.c deleted file mode 100644 index e46a744435c..00000000000 --- a/reactos/ntoskrnl/ps/idle.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ps/idle.c - * PURPOSE: Using idle time - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * David Welch (welch@cwcom.net) - */ - -/* INCLUDES *****************************************************************/ - -#include -#define NDEBUG -#include - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, PsInitIdleThread) -#endif - -/* FUNCTIONS *****************************************************************/ - -/** System idle thread procedure - * - */ -VOID STDCALL -PsIdleThreadMain(PVOID Context) -{ - KIRQL oldlvl; - - PKPRCB Prcb = KeGetCurrentPrcb(); - - for(;;) - { - if (Prcb->DpcData[0].DpcQueueDepth > 0) - { - KeRaiseIrql(DISPATCH_LEVEL,&oldlvl); - KiDispatchInterrupt(); - KeLowerIrql(oldlvl); - } - - NtYieldExecution(); - - Ke386HaltProcessor(); - } -} - -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ -NTSTATUS -NTAPI -PsInitializeIdleOrFirstThread(PEPROCESS Process, - PETHREAD* ThreadPtr, - PKSTART_ROUTINE StartRoutine, - KPROCESSOR_MODE AccessMode, - BOOLEAN First) -{ - PETHREAD Thread; - PVOID KernelStack; - - Thread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); - RtlZeroMemory(Thread, sizeof(ETHREAD)); - Thread->ThreadsProcess = Process; - if (First) - { - KernelStack = P0BootStack; - } - else - { - KernelStack = (PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) + - KERNEL_STACK_SIZE); - } - KeInitializeThread(&Process->Pcb, - &Thread->Tcb, - PspSystemThreadStartup, - StartRoutine, - NULL, - NULL, - NULL, - KernelStack); - InitializeListHead(&Thread->IrpList); - *ThreadPtr = Thread; - return STATUS_SUCCESS; -} - -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ -VOID -INIT_FUNCTION -NTAPI -PsInitIdleThread(VOID) -{ - PETHREAD IdleThread; - KIRQL oldIrql; - - PsInitializeIdleOrFirstThread(PsIdleProcess, - &IdleThread, - PsIdleThreadMain, - KernelMode, - FALSE); - - oldIrql = KiAcquireDispatcherLock (); - KiReadyThread(&IdleThread->Tcb); - KiReleaseDispatcherLock(oldIrql); - - KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; - KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); - KeSetAffinityThread(&IdleThread->Tcb, 1 << 0); -} diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index df6d3c287ff..b4d71c0ee6d 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -64,6 +64,74 @@ NTSTATUS STDCALL INIT_FUNCTION PspLookupKernelUserEntryPoints(VOID); /* FUNCTIONS ***************************************************************/ +VOID +FASTCALL +KiIdleLoop(VOID); + +/* FUNCTIONS *****************************************************************/ + +/* + * HACK-O-RAMA + * Antique vestigial code left alive for the sole purpose of First/Idle Thread + * creation until I can merge my fix for properly creating them. + */ +VOID +INIT_FUNCTION +NTAPI +PsInitHackThread(VOID) +{ + PETHREAD IdleThread; + KIRQL oldIrql; + + IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); + RtlZeroMemory(IdleThread, sizeof(ETHREAD)); + IdleThread->ThreadsProcess = PsIdleProcess; + KeInitializeThread(&PsIdleProcess->Pcb, + &IdleThread->Tcb, + PspSystemThreadStartup, + (PVOID)KiIdleLoop, + NULL, + NULL, + NULL, + P0BootStack); + InitializeListHead(&IdleThread->IrpList); + + oldIrql = KiAcquireDispatcherLock (); + KiReadyThread(&IdleThread->Tcb); + KiReleaseDispatcherLock(oldIrql); + + KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; + KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); + KeSetAffinityThread(&IdleThread->Tcb, 1 << 0); +} + +/* + * HACK-O-RAMA + * Antique vestigial code left alive for the sole purpose of First/Idle Thread + * creation until I can merge my fix for properly creating them. + */ +VOID +INIT_FUNCTION +NTAPI +PsInitHackThread2(IN PETHREAD *Hack) +{ + PETHREAD IdleThread; + + IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); + RtlZeroMemory(IdleThread, sizeof(ETHREAD)); + IdleThread->ThreadsProcess = PsInitialSystemProcess; + KeInitializeThread(&PsInitialSystemProcess->Pcb, + &IdleThread->Tcb, + PspSystemThreadStartup, + NULL, + NULL, + NULL, + NULL, + P0BootStack); + InitializeListHead(&IdleThread->IrpList); + *Hack = IdleThread; +} + VOID INIT_FUNCTION NTAPI @@ -72,7 +140,7 @@ PiInitProcessManager(VOID) PsInitJobManagment(); PsInitProcessManagment(); PsInitThreadManagment(); - PsInitIdleThread(); + PsInitHackThread(); } VOID @@ -115,7 +183,7 @@ PsInitThreadManagment(VOID) ObjectTypeInitializer.DeleteProcedure = PspDeleteThread; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsThreadType); - PsInitializeIdleOrFirstThread(PsInitialSystemProcess, &FirstThread, NULL, KernelMode, TRUE); + PsInitHackThread2(&FirstThread); FirstThread->Tcb.State = Running; FirstThread->Tcb.FreezeCount = 0; FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */