HalpDispatchInterrupt
};
+/* Handlers for pending software interrupts when we already have a trap frame*/
+PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2[3] =
+{
+ (PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY)KiUnexpectedInterrupt,
+ HalpApcInterrupt2ndEntry,
+ HalpDispatchInterrupt2ndEntry
+};
+
+
USHORT HalpEisaELCR;
/* FUNCTIONS ******************************************************************/
/* Check for pending software interrupts and compare with current IRQL */
PendingIrql = SWInterruptLookUpTable[Pcr->IRR];
-
- /* NOTE: We can do better! We need to support "jumping" a frame for nested cases! */
- if (PendingIrql > OldIrql) SWInterruptHandlerTable[PendingIrql]();
+ if (PendingIrql > OldIrql) HalpNestedTrap(PendingIrql);
}
/* INTERRUPT DISMISSAL FUNCTIONS **********************************************/
/* Check for pending software interrupts and compare with current IRQL */
PendingIrql = SWInterruptLookUpTable[Pcr->IRR];
- if (PendingIrql > OldIrql) SWInterruptHandlerTable[PendingIrql]();
+ if (PendingIrql > OldIrql) HalpNestedTrap(PendingIrql);
}
/* SOFTWARE INTERRUPT TRAPS ***************************************************/
VOID
-FASTCALL
-HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
+FORCEINLINE
+DECLSPEC_NORETURN
+_HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
KIRQL CurrentIrql;
PKPCR Pcr = KeGetPcr();
- /* Set up a fake INT Stack */
- TrapFrame->EFlags = __readeflags();
- TrapFrame->SegCs = KGDT_R0_CODE;
- TrapFrame->Eip = TrapFrame->Eax;
-
- /* Build the trap frame */
- KiEnterInterruptTrap(TrapFrame);
-
/* Save the current IRQL and update it */
CurrentIrql = Pcr->Irql;
Pcr->Irql = APC_LEVEL;
-
+
/* Remove DPC from IRR */
Pcr->IRR &= ~(1 << APC_LEVEL);
-
+
/* Enable interrupts and call the kernel's APC interrupt handler */
_enable();
KiDeliverApc(((KiUserTrap(TrapFrame)) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) ?
- UserMode : KernelMode,
- NULL,
- TrapFrame);
+ UserMode : KernelMode,
+ NULL,
+ TrapFrame);
/* Disable interrupts and end the interrupt */
_disable();
+ Pcr->VdmAlert = (ULONG_PTR)TrapFrame;
HalpEndSoftwareInterrupt(CurrentIrql);
-
+
/* Exit the interrupt */
- KiEoiHelper(TrapFrame);
+ KiEoiHelper(TrapFrame);
}
VOID
FASTCALL
-HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
+DECLSPEC_NORETURN
+HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
+{
+ /* Do the work */
+ _HalpApcInterruptHandler(TrapFrame);
+}
+
+VOID
+FASTCALL
+DECLSPEC_NORETURN
+HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
- KIRQL CurrentIrql;
- PKPCR Pcr = KeGetPcr();
-
/* Set up a fake INT Stack */
TrapFrame->EFlags = __readeflags();
TrapFrame->SegCs = KGDT_R0_CODE;
/* Build the trap frame */
KiEnterInterruptTrap(TrapFrame);
+ /* Do the work */
+ _HalpApcInterruptHandler(TrapFrame);
+}
+
+VOID
+FORCEINLINE
+DECLSPEC_NORETURN
+_HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
+{
+ KIRQL CurrentIrql;
+ PKPCR Pcr = KeGetPcr();
+
/* Save the current IRQL and update it */
CurrentIrql = Pcr->Irql;
Pcr->Irql = DISPATCH_LEVEL;
/* Disable interrupts and end the interrupt */
_disable();
+ Pcr->VdmAlert = (ULONG_PTR)TrapFrame;
HalpEndSoftwareInterrupt(CurrentIrql);
/* Exit the interrupt */
- KiEoiHelper(TrapFrame);
+ KiEoiHelper(TrapFrame);
+}
+
+VOID
+FASTCALL
+DECLSPEC_NORETURN
+HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
+{
+ /* Do the work */
+ _HalpDispatchInterruptHandler(TrapFrame);
+}
+
+VOID
+FASTCALL
+DECLSPEC_NORETURN
+HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
+{
+ /* Set up a fake INT Stack */
+ TrapFrame->EFlags = __readeflags();
+ TrapFrame->SegCs = KGDT_R0_CODE;
+ TrapFrame->Eip = TrapFrame->Eax;
+
+ /* Build the trap frame */
+ KiEnterInterruptTrap(TrapFrame);
+
+ /* Do the work */
+ _HalpDispatchInterruptHandler(TrapFrame);
}
KiTrap(HalpApcInterrupt, KI_SOFTWARE_TRAP);
ULONG Prefix;
} HAL_BIOS_FRAME, *PHAL_BIOS_FRAME;
+typedef
+VOID
+(*PHAL_SW_INTERRUPT_HANDLER)(
+ VOID
+);
+
+typedef
+FASTCALL
+VOID
+(*PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY)(
+ IN PKTRAP_FRAME TrapFrame
+);
+
#define HAL_APC_REQUEST 0
#define HAL_DPC_REQUEST 1
);
}
+//
+// Nested Trap Trampoline
+//
+VOID
+DECLSPEC_NORETURN
+FORCEINLINE
+HalpNestedTrap(IN KIRQL PendingIrql)
+{
+ /* Use the second interrupt handler table */
+ extern PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2[3];
+ __asm__ __volatile__
+ (
+ "movl %c[t], %%ecx\n"
+ "jmp *%0\n"
+ :
+ : "im"(SWInterruptHandlerTable2[PendingIrql]),
+ [t] "i"(&PCR->VdmAlert)
+ : "%esp"
+ );
+ UNREACHABLE;
+}
+
//
// Commonly stated as being 1.19318MHz
//
};
} PIC_MASK, *PPIC_MASK;
-typedef
-VOID
-(*PHAL_SW_INTERRUPT_HANDLER)(
- VOID
-);
-
typedef
BOOLEAN
__attribute__((regparm(3)))
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
VOID HalpApcInterrupt(VOID);
VOID HalpDispatchInterrupt(VOID);
+VOID FASTCALL HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
+VOID FASTCALL HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
/* timer.c */
VOID NTAPI HalpInitializeClock(VOID);