mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
- Part 2 of 2: Implement KiDispatchInterrupt in assembly since it's 1) Perf-critical 2) Requires us to switch the stack to the DPC stack, which is unsafe (and impossible, unless inlining) in C.
svn path=/trunk/; revision=23889
This commit is contained in:
parent
0f9c7bdf03
commit
252a2d1598
3 changed files with 80 additions and 52 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
Loading…
Reference in a new issue