/*
* PROJECT: ReactOS HAL
* LICENSE: BSD - See COPYING.ARM in the top level directory
- * FILE: hal/halx86/generic/pic.c
+ * FILE: hal/halx86/up/pic.c
* PURPOSE: HAL PIC Management and Control Code
* PROGRAMMERS: ReactOS Portable Systems Group
*/
#define NDEBUG
#include <debug.h>
+VOID
+NTAPI
+HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
+ IN PKTRAP_FRAME TrapFrame);
+
/* GLOBALS ********************************************************************/
#ifndef _MINIHAL_
/* This table contains the static x86 PIC mapping between IRQLs and IRQs */
ULONG KiI8259MaskTable[32] =
{
-#if defined(__GNUC__) && \
- (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)
+#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && _MSC_VER >= 1900)
/*
* It Device IRQLs only start at 4 or higher, so these are just software
* IRQLs that don't really change anything on the hardware
/* This table indicates which IRQs, if pending, can preempt a given IRQL level */
ULONG FindHigherIrqlMask[32] =
{
-#if defined(__GNUC__) && \
- (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)
+#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && _MSC_VER >= 1900)
/*
* Software IRQLs, at these levels all hardware interrupts can preempt.
* Each higher IRQL simply enables which software IRQL can preempt the
* so it will always preempt until we reach PROFILE_LEVEL.
*/
0b00000000000000000001011111110000, /* IRQL 20 */
- 0b00000000000000000001001111110000, /* IRQL 20 */
+ 0b00000000000000000001001111110000, /* IRQL 21 */
0b00000000000000000001000111110000, /* IRQL 22 */
0b00000000000000000001000011110000, /* IRQL 23 */
0b00000000000000000001000001110000, /* IRQL 24 */
#if defined(__GNUC__)
#define HalpDelayedHardwareInterrupt(x) \
- VOID HalpHardwareInterrupt##x(VOID); \
+ VOID __cdecl HalpHardwareInterrupt##x(VOID); \
VOID \
+ __cdecl \
HalpHardwareInterrupt##x(VOID) \
{ \
asm volatile ("int $%c0\n"::"i"(PRIMARY_VECTOR_BASE + x)); \
#elif defined(_MSC_VER)
#define HalpDelayedHardwareInterrupt(x) \
- VOID HalpHardwareInterrupt##x(VOID); \
+ VOID __cdecl HalpHardwareInterrupt##x(VOID); \
VOID \
+ __cdecl \
HalpHardwareInterrupt##x(VOID) \
{ \
__asm \
/* Handlers for pending interrupts */
PHAL_SW_INTERRUPT_HANDLER SWInterruptHandlerTable[20] =
{
- KiUnexpectedInterrupt,
+ (PHAL_SW_INTERRUPT_HANDLER)KiUnexpectedInterrupt,
HalpApcInterrupt,
HalpDispatchInterrupt2,
- KiUnexpectedInterrupt,
+ (PHAL_SW_INTERRUPT_HANDLER)KiUnexpectedInterrupt,
HalpHardwareInterrupt0,
HalpHardwareInterrupt1,
HalpHardwareInterrupt2,
HalpInitializePICs(IN BOOLEAN EnableInterrupts)
{
ULONG EFlags;
- I8259_ICW1 Icw1;
- I8259_ICW2 Icw2;
- I8259_ICW3 Icw3;
- I8259_ICW4 Icw4;
EISA_ELCR Elcr;
ULONG i, j;
EFlags = __readeflags();
_disable();
- /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
- Icw1.NeedIcw4 = TRUE;
- Icw1.InterruptMode = EdgeTriggered;
- Icw1.OperatingMode = Cascade;
- Icw1.Interval = Interval8;
- Icw1.Init = TRUE;
- Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
- __outbyte(PIC1_CONTROL_PORT, Icw1.Bits);
-
- /* Set interrupt vector base */
- Icw2.Bits = PRIMARY_VECTOR_BASE;
- __outbyte(PIC1_DATA_PORT, Icw2.Bits);
-
- /* Connect slave to IRQ 2 */
- Icw3.Bits = 0;
- Icw3.SlaveIrq2 = TRUE;
- __outbyte(PIC1_DATA_PORT, Icw3.Bits);
-
- /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
- Icw4.Reserved = 0;
- Icw4.SystemMode = New8086Mode;
- Icw4.EoiMode = NormalEoi;
- Icw4.BufferedMode = NonBuffered;
- Icw4.SpecialFullyNestedMode = FALSE;
- __outbyte(PIC1_DATA_PORT, Icw4.Bits);
-
- /* Mask all interrupts */
- __outbyte(PIC1_DATA_PORT, 0xFF);
-
- /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
- Icw1.NeedIcw4 = TRUE;
- Icw1.InterruptMode = EdgeTriggered;
- Icw1.OperatingMode = Cascade;
- Icw1.Interval = Interval8;
- Icw1.Init = TRUE;
- Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
- __outbyte(PIC2_CONTROL_PORT, Icw1.Bits);
-
- /* Set interrupt vector base */
- Icw2.Bits = PRIMARY_VECTOR_BASE + 8;
- __outbyte(PIC2_DATA_PORT, Icw2.Bits);
-
- /* Slave ID */
- Icw3.Bits = 0;
- Icw3.SlaveId = 2;
- __outbyte(PIC2_DATA_PORT, Icw3.Bits);
-
- /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
- Icw4.Reserved = 0;
- Icw4.SystemMode = New8086Mode;
- Icw4.EoiMode = NormalEoi;
- Icw4.BufferedMode = NonBuffered;
- Icw4.SpecialFullyNestedMode = FALSE;
- __outbyte(PIC2_DATA_PORT, Icw4.Bits);
-
- /* Mask all interrupts */
- __outbyte(PIC2_DATA_PORT, 0xFF);
+ /* Initialize and mask the PIC */
+ HalpInitializeLegacyPICs();
/* Read EISA Edge/Level Register for master and slave */
Elcr.Bits = (__inbyte(EISA_ELCR_SLAVE) << 8) | __inbyte(EISA_ELCR_MASTER);
KeGetPcr()->IRR &= ~(1 << Irql);
}
-VOID
-NTAPI
-HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
- IN PKTRAP_FRAME TrapFrame)
+PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY
+FASTCALL
+HalpEndSoftwareInterrupt2(IN KIRQL OldIrql,
+ IN PKTRAP_FRAME TrapFrame)
{
ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
PKPCR Pcr = KeGetPcr();
PIC_MASK Mask;
+ UNREFERENCED_PARAMETER(TrapFrame);
+
/* Set old IRQL */
Pcr->Irql = OldIrql;
{
/* Check for pending software interrupts and compare with current IRQL */
PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
- if (!PendingIrqlMask) return;
+ if (!PendingIrqlMask) return NULL;
/* Check for in-service delayed interrupt */
- if (Pcr->IrrActive & 0xFFFFFFF0) return;
+ if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
/* Check if pending IRQL affects hardware state */
BitScanReverse(&PendingIrql, PendingIrqlMask);
else
{
/* No need to loop checking for hardware interrupts */
- SWInterruptHandlerTable2[PendingIrql](TrapFrame);
+ return SWInterruptHandlerTable2[PendingIrql];
}
}
+
+ return NULL;
}
/* EDGE INTERRUPT DISMISSAL FUNCTIONS *****************************************/
-BOOLEAN
FORCEINLINE
+BOOLEAN
_HalpDismissIrqGeneric(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
Ocw2.EoiMode = SpecificEoi;
/* Check which PIC needs the EOI */
- if (Irq > 8)
+ if (Irq >= 8)
{
/* Send the EOI for the IRQ */
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
}
BOOLEAN
-REGISTERCALL
+NTAPI
HalpDismissIrqGeneric(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
}
BOOLEAN
-REGISTERCALL
+NTAPI
HalpDismissIrq15(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
BOOLEAN
-REGISTERCALL
+NTAPI
HalpDismissIrq13(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
}
BOOLEAN
-REGISTERCALL
+NTAPI
HalpDismissIrq07(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
/* LEVEL INTERRUPT DISMISSAL FUNCTIONS ****************************************/
-BOOLEAN
FORCEINLINE
+BOOLEAN
_HalpDismissIrqLevel(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
Ocw2.EoiMode = SpecificEoi;
/* Check which PIC needs the EOI */
- if (Irq > 8)
+ if (Irq >= 8)
{
/* Send the EOI for the IRQ */
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
}
BOOLEAN
-REGISTERCALL
+NTAPI
HalpDismissIrqLevel(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
}
BOOLEAN
-REGISTERCALL
+NTAPI
HalpDismissIrq15Level(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
}
BOOLEAN
-REGISTERCALL
+NTAPI
HalpDismissIrq13Level(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
}
BOOLEAN
-REGISTERCALL
+NTAPI
HalpDismissIrq07Level(IN KIRQL Irql,
IN ULONG Irq,
OUT PKIRQL OldIrql)
}
VOID
+__cdecl
HalpHardwareInterruptLevel(VOID)
{
PKPCR Pcr = KeGetPcr();
{
/* Now handle pending software interrupt */
SWInterruptHandlerTable2[PendingIrql](TrapFrame);
+ UNREACHABLE;
}
}
}
/* SOFTWARE INTERRUPT TRAPS ***************************************************/
-VOID
FORCEINLINE
DECLSPEC_NORETURN
+VOID
_HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
KIRQL CurrentIrql;
KiEoiHelper(TrapFrame);
}
-VOID
DECLSPEC_NORETURN
+VOID
FASTCALL
HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
{
_HalpApcInterruptHandler(TrapFrame);
}
-VOID
DECLSPEC_NORETURN
+VOID
FASTCALL
HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
_HalpApcInterruptHandler(TrapFrame);
}
-KIRQL
FORCEINLINE
+KIRQL
_HalpDispatchInterruptHandler(VOID)
{
KIRQL CurrentIrql;
return CurrentIrql;
}
-VOID
DECLSPEC_NORETURN
+VOID
FASTCALL
HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
{
}
VOID
+__cdecl
HalpDispatchInterrupt2(VOID)
{
ULONG PendingIrqlMask, PendingIrql;