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_SET_MEMBER 0x48
|
||||||
#define KPCR_NUMBER 0x51
|
#define KPCR_NUMBER 0x51
|
||||||
#define KPCR_CURRENT_THREAD 0x124
|
#define KPCR_CURRENT_THREAD 0x124
|
||||||
|
#define KPCR_PRCB_NEXT_THREAD 0x128
|
||||||
#define KPCR_PRCB_IDLE_THREAD 0x12C
|
#define KPCR_PRCB_IDLE_THREAD 0x12C
|
||||||
#define KPCR_PROCESSOR_NUMBER 0x130
|
#define KPCR_PROCESSOR_NUMBER 0x130
|
||||||
#define KPCR_PRCB_SET_MEMBER 0x134
|
#define KPCR_PRCB_SET_MEMBER 0x134
|
||||||
|
@ -165,12 +166,15 @@ Author:
|
||||||
#define KPCR_SYSTEM_CALLS 0x6B8
|
#define KPCR_SYSTEM_CALLS 0x6B8
|
||||||
#define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C
|
#define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C
|
||||||
#define KPCR_PRCB_DPC_COUNT 0xA50
|
#define KPCR_PRCB_DPC_COUNT 0xA50
|
||||||
|
#define KPCR_PRCB_DPC_STACK 0xA68
|
||||||
#define KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH 0xA6C
|
#define KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH 0xA6C
|
||||||
#define KPCR_PRCB_DPC_REQUEST_RATE 0xA70
|
#define KPCR_PRCB_DPC_REQUEST_RATE 0xA70
|
||||||
#define KPCR_PRCB_DPC_INTERRUPT_REQUESTED 0xA78
|
#define KPCR_PRCB_DPC_INTERRUPT_REQUESTED 0xA78
|
||||||
#define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0xA7A
|
#define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0xA7A
|
||||||
#define KPCR_PRCB_DPC_LAST_COUNT 0xA80
|
#define KPCR_PRCB_DPC_LAST_COUNT 0xA80
|
||||||
|
#define KPCR_PRCB_TIMER_REQUEST 0xA88
|
||||||
#define KPCR_PRCB_QUANTUM_END 0xAA1
|
#define KPCR_PRCB_QUANTUM_END 0xAA1
|
||||||
|
#define KPCR_PRCB_DEFERRED_READY_LIST_HEAD 0xC10
|
||||||
|
|
||||||
//
|
//
|
||||||
// KINTERRUPT Offsets
|
// KINTERRUPT Offsets
|
||||||
|
|
|
@ -441,9 +441,22 @@ KeFlushQueuedDpcs(VOID)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Request an interrupt if needed */
|
/* Check if this is an UP machine */
|
||||||
DPRINT1("%s - FIXME!!!\n", __FUNCTION__);
|
if (KeActiveProcessors == 1)
|
||||||
if (KeGetCurrentPrcb()->DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
{
|
||||||
|
/* 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;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -56,6 +56,7 @@ GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */
|
||||||
.globl _NtRaiseException@12
|
.globl _NtRaiseException@12
|
||||||
.globl _NtContinue@8
|
.globl _NtContinue@8
|
||||||
.globl _KiCoprocessorError@0
|
.globl _KiCoprocessorError@0
|
||||||
|
.globl _KiDispatchInterrupt@0
|
||||||
|
|
||||||
/* Interrupt template entrypoints */
|
/* Interrupt template entrypoints */
|
||||||
.globl _KiInterruptTemplate
|
.globl _KiInterruptTemplate
|
||||||
|
@ -1558,6 +1559,65 @@ _KiUnexpectedInterrupt:
|
||||||
|
|
||||||
/* INTERRUPT HANDLERS ********************************************************/
|
/* 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
|
.func KiInterruptTemplate
|
||||||
_KiInterruptTemplate:
|
_KiInterruptTemplate:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue