diff --git a/reactos/ntoskrnl/ke/i386/irq.c b/reactos/ntoskrnl/ke/i386/irq.c index 3f04393e4be..3309d80f022 100644 --- a/reactos/ntoskrnl/ke/i386/irq.c +++ b/reactos/ntoskrnl/ke/i386/irq.c @@ -24,6 +24,9 @@ #define NDEBUG #include +extern ULONG KiInterruptTemplate[KINTERRUPT_DISPATCH_CODES]; +extern PULONG KiInterruptTemplateObject; + /* GLOBALS *****************************************************************/ /* Interrupt handler list */ @@ -245,7 +248,6 @@ KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe) * At this point we have interrupts disabled, nothing has been done to * the PIC. */ - KeGetCurrentPrcb()->InterruptCount++; /* @@ -302,9 +304,9 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject) PISR_TABLE CurrentIsr; BOOLEAN Result; - DPRINT("KeConnectInterrupt()\n"); Vector = InterruptObject->Vector; + DPRINT1("KeConnectInterrupt(): %lx\n", Vector); if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS) return FALSE; @@ -437,10 +439,13 @@ KeInitializeInterrupt(PKINTERRUPT Interrupt, CHAR ProcessorNumber, BOOLEAN FloatingSave) { + ULONG i; + PULONG DispatchCode = &Interrupt->DispatchCode[0], Patch = DispatchCode; + /* Set the Interrupt Header */ Interrupt->Type = InterruptObject; Interrupt->Size = sizeof(KINTERRUPT); - + /* Check if we got a spinlock */ if (SpinLock) { @@ -452,7 +457,7 @@ KeInitializeInterrupt(PKINTERRUPT Interrupt, KeInitializeSpinLock(&Interrupt->SpinLock); Interrupt->ActualLock = &Interrupt->SpinLock; } - + /* Set the other settings */ Interrupt->ServiceRoutine = ServiceRoutine; Interrupt->ServiceContext = ServiceContext; @@ -463,7 +468,22 @@ KeInitializeInterrupt(PKINTERRUPT Interrupt, Interrupt->ShareVector = ShareVector; Interrupt->Number = ProcessorNumber; Interrupt->FloatingSave = FloatingSave; - + + /* Loop the template in memory */ + for (i = 0; i < KINTERRUPT_DISPATCH_CODES; i++) + { + /* Copy the dispatch code */ + *DispatchCode++ = KiInterruptTemplate[i]; + } + + /* Jump to the last 4 bytes */ + Patch = (PULONG)((ULONG_PTR)Patch + + ((ULONG_PTR)&KiInterruptTemplateObject - + (ULONG_PTR)KiInterruptTemplate) - 4); + + /* Apply the patch */ + *Patch = PtrToUlong(Interrupt); + /* Disconnect it at first */ Interrupt->Connected = FALSE; } diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index f6e073adf30..bc62f7a8a73 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -56,6 +56,10 @@ GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */ .globl _NtRaiseException@12 .globl _NtContinue@8 +/* Interrupt template entrypoints */ +.globl _KiInterruptTemplate +.globl _KiInterruptTemplateObject + /* We implement the following trap exit points: */ .globl _KiServiceExit /* Exit from syscall */ .globl _KiServiceExit2 /* Exit from syscall with complete frame*/ @@ -1295,7 +1299,7 @@ _KiSystemFatalException: ret .endfunc -/* INTERRUPT HANDLERS ********************************************************/ +/* UNEXPECTED INTERRUPT HANDLERS **********************************************/ .globl _KiStartUnexpected _KiStartUnexpected: @@ -1346,3 +1350,20 @@ _KiUnexpectedInterrupt: /* Bugcheck with invalid interrupt code */ push 0x12 call _KeBugCheck@4 + +/* INTERRUPT HANDLERS ********************************************************/ + +.func KiInterruptTemplate +_KiInterruptTemplate: + + /* Enter interrupt trap */ + INT_PROLOG kit, DoPushFakeErrorCode +.endfunc + +_KiInterruptTemplate2ndDispatch: + /* Dummy code, will be replaced by the address of the KINTERRUPT */ + mov edi, 0 + +_KiInterruptTemplateObject: + /* Dummy jump, will be replaced by the actual jump */ + jmp _KeSynchronizeExecution@12