diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index f76279bf86c..a7c1b54e957 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -148,6 +148,7 @@ Author: #define KPCR_SET_MEMBER 0x48 #define KPCR_NUMBER 0x51 #define KPCR_CURRENT_THREAD 0x124 +#define KPCR_PRCB_NEXT_THREAD 0x128 #define KPCR_PRCB_IDLE_THREAD 0x12C #define KPCR_PROCESSOR_NUMBER 0x130 #define KPCR_PRCB_SET_MEMBER 0x134 @@ -165,12 +166,15 @@ Author: #define KPCR_SYSTEM_CALLS 0x6B8 #define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C #define KPCR_PRCB_DPC_COUNT 0xA50 +#define KPCR_PRCB_DPC_STACK 0xA68 #define KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH 0xA6C #define KPCR_PRCB_DPC_REQUEST_RATE 0xA70 #define KPCR_PRCB_DPC_INTERRUPT_REQUESTED 0xA78 #define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0xA7A #define KPCR_PRCB_DPC_LAST_COUNT 0xA80 +#define KPCR_PRCB_TIMER_REQUEST 0xA88 #define KPCR_PRCB_QUANTUM_END 0xAA1 +#define KPCR_PRCB_DEFERRED_READY_LIST_HEAD 0xC10 // // KINTERRUPT Offsets diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 1e251da4e90..9500adba101 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -441,9 +441,22 @@ KeFlushQueuedDpcs(VOID) { PAGED_CODE(); - /* Request an interrupt if needed */ - DPRINT1("%s - FIXME!!!\n", __FUNCTION__); - if (KeGetCurrentPrcb()->DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + /* Check if this is an UP machine */ + if (KeActiveProcessors == 1) + { + /* Check if there are DPCs on either queues */ + if ((KeGetCurrentPrcb()->DpcData[DPC_NORMAL].DpcQueueDepth) || + (KeGetCurrentPrcb()->DpcData[DPC_THREADED].DpcQueueDepth)) + { + /* Request an interrupt */ + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + } + } + else + { + /* FIXME: SMP support required */ + ASSERT(FALSE); + } } /* @@ -483,53 +496,4 @@ KeSetTargetProcessorDpc(IN PKDPC Dpc, Dpc->Number = Number + MAXIMUM_PROCESSORS; } -/* - * @implemented - */ -VOID -NTAPI -KiDispatchInterrupt(VOID) -{ - PKIPCR Pcr = (PKIPCR)KeGetPcr(); - PVOID ExceptionList; - - /* Disable interrupts */ - Ke386DisableInterrupts(); - - /* Check if we have to deliver DPCs, timers, or deferred threads */ - if ((Pcr->PrcbData.DpcData[DPC_NORMAL].DpcQueueDepth) || - (Pcr->PrcbData.TimerRequest) || - (Pcr->PrcbData.DeferredReadyListHead.Next)) - { - /* Save the exception list and clear it */ - ExceptionList = Pcr->NtTib.ExceptionList; - Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END; - - /* FIXME: Switch to DPC Stack */ - - /* Deliver DPCs */ - KiRetireDpcList(Pcr->Prcb); - - /* FIXME: Restore stack */ - - /* Restore exception list */ - Pcr->NtTib.ExceptionList = ExceptionList; - } - - /* Re-enable interrupts */ - Ke386EnableInterrupts(); - - /* Check if we have quantum end */ - if (Pcr->PrcbData.QuantumEnd) - { - /* Process it */ - Pcr->PrcbData.QuantumEnd = FALSE; - KiQuantumEnd(); - } - else if (Pcr->PrcbData.NextThread) - { - /* FIXME: Schedule new thread */ - } -} - /* EOF */ diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 115d83bcbea..d312ed5438e 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -56,6 +56,7 @@ GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */ .globl _NtRaiseException@12 .globl _NtContinue@8 .globl _KiCoprocessorError@0 +.globl _KiDispatchInterrupt@0 /* Interrupt template entrypoints */ .globl _KiInterruptTemplate @@ -1558,6 +1559,65 @@ _KiUnexpectedInterrupt: /* INTERRUPT HANDLERS ********************************************************/ +.func KiDispatchInterrupt@0 +_KiDispatchInterrupt@0: + + /* Get the PCR and disable interrupts */ + mov ebx, [fs:KPCR_SELF] + 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] + or eax, [ebx+KPCR_PRCB_DEFERRED_READY_LIST_HEAD] + jz CheckQuantum + + /* Save stack pointer and exception list, then clear it */ + push ebp + push dword ptr [ebx+KPCR_EXCEPTION_LIST] + mov dword ptr [ebx+KPCR_EXCEPTION_LIST], -1 + + /* Save the stack and switch to the DPC Stack */ + mov edx, esp + //mov esp, [ebx+KPCR_PRCB_DPC_STACK] + push edx + + /* Deliver DPCs */ + mov ecx, [ebx+KPCR_PRCB] + call @KiRetireDpcList@4 + + /* Restore stack and exception list */ + pop esp + pop dword ptr [ebx] + pop ebp + +CheckQuantum: + + /* Re-enable interrupts */ + sti + + /* Check if we have quantum end */ + cmp byte ptr [ebx+KPCR_PRCB_QUANTUM_END], 0 + jnz QuantumEnd + + /* Check if we have a thread to swap to */ + cmp byte ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0 + jz Return + + /* FIXME: Schedule new thread */ + int 3 + +Return: + /* All done */ + ret + +QuantumEnd: + /* Disable quantum end and process it */ + mov byte ptr [ebx+KPCR_PRCB_QUANTUM_END], 0 + call _KiQuantumEnd@0 + ret +.endfunc + .func KiInterruptTemplate _KiInterruptTemplate: