2010-01-21 12:51:13 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS HAL
|
|
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
|
|
* PURPOSE: HAL PIC Management and Control Code
|
|
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
|
|
|
#include <hal.h>
|
2020-07-25 13:31:02 +00:00
|
|
|
|
2010-01-21 12:51:13 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2016-05-10 15:03:56 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
|
|
|
|
IN PKTRAP_FRAME TrapFrame);
|
|
|
|
|
2010-01-21 12:51:13 +00:00
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
|
2010-03-03 21:56:52 +00:00
|
|
|
#ifndef _MINIHAL_
|
2010-01-24 23:30:43 +00:00
|
|
|
/*
|
|
|
|
* This table basically keeps track of level vs edge triggered interrupts.
|
|
|
|
* Windows has 250+ entries, but it seems stupid to replicate that since the PIC
|
|
|
|
* can't actually have that many.
|
|
|
|
*
|
|
|
|
* When a level interrupt is registered, the respective pointer in this table is
|
|
|
|
* modified to point to a dimiss routine for level interrupts instead.
|
|
|
|
*
|
|
|
|
* The other thing this table does is special case IRQ7, IRQ13 and IRQ15:
|
|
|
|
*
|
|
|
|
* - If an IRQ line is deasserted before it is acknowledged due to a noise spike
|
|
|
|
* generated by an expansion device (since the IRQ line is low during the 1st
|
|
|
|
* acknowledge bus cycle), the i8259 will keep the line low for at least 100ns
|
|
|
|
* When the spike passes, a pull-up resistor will return the IRQ line to high.
|
|
|
|
* Since the PIC requires the input be high until the first acknowledge, the
|
|
|
|
* i8259 knows that this was a spurious interrupt, and on the second interrupt
|
|
|
|
* acknowledge cycle, it reports this to the CPU. Since no valid interrupt has
|
|
|
|
* actually happened Intel hardcoded the chip to report IRQ7 on the master PIC
|
|
|
|
* and IRQ15 on the slave PIC (IR7 either way).
|
|
|
|
*
|
|
|
|
* "ISA System Architecture", 3rd Edition, states that these cases should be
|
|
|
|
* handled by reading the respective Interrupt Service Request (ISR) bits from
|
|
|
|
* the affected PIC, and validate whether or not IR7 is set. If it isn't, then
|
|
|
|
* the interrupt is spurious and should be ignored.
|
|
|
|
*
|
|
|
|
* Note that for a spurious IRQ15, we DO have to send an EOI to the master for
|
|
|
|
* IRQ2 since the line was asserted by the slave when it received the spurious
|
|
|
|
* IRQ15!
|
|
|
|
*
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
* - When the 80287/80387 math co-processor generates an FPU/NPX trap, this is
|
2010-01-24 23:30:43 +00:00
|
|
|
* connected to IRQ13, so we have to clear the busy latch on the NPX port.
|
|
|
|
*/
|
|
|
|
PHAL_DISMISS_INTERRUPT HalpSpecialDismissTable[16] =
|
|
|
|
{
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrq07,
|
2020-07-25 13:31:02 +00:00
|
|
|
#if defined(SARCH_PC98)
|
|
|
|
HalpDismissIrq08,
|
|
|
|
#else
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
#endif
|
2010-01-24 23:30:43 +00:00
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrqGeneric,
|
2020-07-25 13:31:02 +00:00
|
|
|
#if defined(SARCH_PC98)
|
2010-01-24 23:30:43 +00:00
|
|
|
HalpDismissIrqGeneric,
|
2020-07-25 13:31:02 +00:00
|
|
|
#else
|
2010-01-24 23:30:43 +00:00
|
|
|
HalpDismissIrq13,
|
2020-07-25 13:31:02 +00:00
|
|
|
#endif
|
2010-01-24 23:30:43 +00:00
|
|
|
HalpDismissIrqGeneric,
|
|
|
|
HalpDismissIrq15
|
|
|
|
};
|
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/*
|
|
|
|
* These are the level IRQ dismissal functions that get copied in the table
|
|
|
|
* above if the given IRQ is actually level triggered.
|
|
|
|
*/
|
|
|
|
PHAL_DISMISS_INTERRUPT HalpSpecialDismissLevelTable[16] =
|
|
|
|
{
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrq07Level,
|
2020-07-25 13:31:02 +00:00
|
|
|
#if defined(SARCH_PC98)
|
|
|
|
HalpDismissIrq08Level,
|
|
|
|
#else
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
#endif
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrqLevel,
|
2020-07-25 13:31:02 +00:00
|
|
|
#if defined(SARCH_PC98)
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrqLevel,
|
2020-07-25 13:31:02 +00:00
|
|
|
#else
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrq13Level,
|
2020-07-25 13:31:02 +00:00
|
|
|
#endif
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrqLevel,
|
|
|
|
HalpDismissIrq15Level
|
|
|
|
};
|
|
|
|
|
2010-01-24 23:19:40 +00:00
|
|
|
/* This table contains the static x86 PIC mapping between IRQLs and IRQs */
|
2020-07-25 13:31:02 +00:00
|
|
|
extern ULONG KiI8259MaskTable[32];
|
2010-01-24 23:19:40 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* This table indicates which IRQs, if pending, can preempt a given IRQL level */
|
2020-07-25 13:31:02 +00:00
|
|
|
extern ULONG FindHigherIrqlMask[32];
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
|
2010-01-25 01:20:43 +00:00
|
|
|
/* Denotes minimum required IRQL before we can process pending SW interrupts */
|
|
|
|
KIRQL SWInterruptLookUpTable[8] =
|
|
|
|
{
|
|
|
|
PASSIVE_LEVEL, /* IRR 0 */
|
|
|
|
PASSIVE_LEVEL, /* IRR 1 */
|
|
|
|
APC_LEVEL, /* IRR 2 */
|
|
|
|
APC_LEVEL, /* IRR 3 */
|
|
|
|
DISPATCH_LEVEL, /* IRR 4 */
|
|
|
|
DISPATCH_LEVEL, /* IRR 5 */
|
|
|
|
DISPATCH_LEVEL, /* IRR 6 */
|
|
|
|
DISPATCH_LEVEL /* IRR 7 */
|
|
|
|
};
|
|
|
|
|
2010-06-02 13:59:47 +00:00
|
|
|
#if defined(__GNUC__)
|
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
#define HalpDelayedHardwareInterrupt(x) \
|
2015-09-15 10:35:49 +00:00
|
|
|
VOID __cdecl HalpHardwareInterrupt##x(VOID); \
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
VOID \
|
2015-09-15 10:35:49 +00:00
|
|
|
__cdecl \
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpHardwareInterrupt##x(VOID) \
|
|
|
|
{ \
|
|
|
|
asm volatile ("int $%c0\n"::"i"(PRIMARY_VECTOR_BASE + x)); \
|
|
|
|
}
|
|
|
|
|
2010-06-02 13:59:47 +00:00
|
|
|
#elif defined(_MSC_VER)
|
|
|
|
|
|
|
|
#define HalpDelayedHardwareInterrupt(x) \
|
2015-09-15 10:35:49 +00:00
|
|
|
VOID __cdecl HalpHardwareInterrupt##x(VOID); \
|
2010-06-02 13:59:47 +00:00
|
|
|
VOID \
|
2015-09-15 10:35:49 +00:00
|
|
|
__cdecl \
|
2010-06-02 13:59:47 +00:00
|
|
|
HalpHardwareInterrupt##x(VOID) \
|
|
|
|
{ \
|
|
|
|
__asm \
|
|
|
|
{ \
|
|
|
|
int PRIMARY_VECTOR_BASE + x \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
#error Unsupported compiler
|
|
|
|
#endif
|
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Pending/delayed hardware interrupt handlers */
|
|
|
|
HalpDelayedHardwareInterrupt(0);
|
|
|
|
HalpDelayedHardwareInterrupt(1);
|
|
|
|
HalpDelayedHardwareInterrupt(2);
|
|
|
|
HalpDelayedHardwareInterrupt(3);
|
|
|
|
HalpDelayedHardwareInterrupt(4);
|
|
|
|
HalpDelayedHardwareInterrupt(5);
|
|
|
|
HalpDelayedHardwareInterrupt(6);
|
|
|
|
HalpDelayedHardwareInterrupt(7);
|
|
|
|
HalpDelayedHardwareInterrupt(8);
|
|
|
|
HalpDelayedHardwareInterrupt(9);
|
|
|
|
HalpDelayedHardwareInterrupt(10);
|
|
|
|
HalpDelayedHardwareInterrupt(11);
|
|
|
|
HalpDelayedHardwareInterrupt(12);
|
|
|
|
HalpDelayedHardwareInterrupt(13);
|
|
|
|
HalpDelayedHardwareInterrupt(14);
|
|
|
|
HalpDelayedHardwareInterrupt(15);
|
|
|
|
|
|
|
|
/* Handlers for pending interrupts */
|
|
|
|
PHAL_SW_INTERRUPT_HANDLER SWInterruptHandlerTable[20] =
|
2010-01-25 01:20:43 +00:00
|
|
|
{
|
2015-09-15 10:35:49 +00:00
|
|
|
(PHAL_SW_INTERRUPT_HANDLER)KiUnexpectedInterrupt,
|
2010-01-25 01:20:43 +00:00
|
|
|
HalpApcInterrupt,
|
2018-02-18 11:50:54 +00:00
|
|
|
HalpDispatchInterrupt,
|
2015-09-15 10:35:49 +00:00
|
|
|
(PHAL_SW_INTERRUPT_HANDLER)KiUnexpectedInterrupt,
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpHardwareInterrupt0,
|
|
|
|
HalpHardwareInterrupt1,
|
|
|
|
HalpHardwareInterrupt2,
|
|
|
|
HalpHardwareInterrupt3,
|
|
|
|
HalpHardwareInterrupt4,
|
|
|
|
HalpHardwareInterrupt5,
|
|
|
|
HalpHardwareInterrupt6,
|
|
|
|
HalpHardwareInterrupt7,
|
|
|
|
HalpHardwareInterrupt8,
|
|
|
|
HalpHardwareInterrupt9,
|
|
|
|
HalpHardwareInterrupt10,
|
|
|
|
HalpHardwareInterrupt11,
|
|
|
|
HalpHardwareInterrupt12,
|
|
|
|
HalpHardwareInterrupt13,
|
|
|
|
HalpHardwareInterrupt14,
|
|
|
|
HalpHardwareInterrupt15
|
2010-01-25 01:20:43 +00:00
|
|
|
};
|
|
|
|
|
2010-01-28 20:45:45 +00:00
|
|
|
/* Handlers for pending software interrupts when we already have a trap frame*/
|
|
|
|
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2[3] =
|
|
|
|
{
|
2018-05-18 04:51:00 +00:00
|
|
|
(PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY)(PVOID)KiUnexpectedInterrupt,
|
2010-01-28 20:45:45 +00:00
|
|
|
HalpApcInterrupt2ndEntry,
|
|
|
|
HalpDispatchInterrupt2ndEntry
|
|
|
|
};
|
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
LONG HalpEisaELCR;
|
2010-01-21 12:51:13 +00:00
|
|
|
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
HalpInitializePICs(IN BOOLEAN EnableInterrupts)
|
|
|
|
{
|
|
|
|
ULONG EFlags;
|
|
|
|
EISA_ELCR Elcr;
|
|
|
|
ULONG i, j;
|
2020-07-25 13:31:02 +00:00
|
|
|
BOOLEAN ElcrFound;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-21 12:51:13 +00:00
|
|
|
/* Save EFlags and disable interrupts */
|
|
|
|
EFlags = __readeflags();
|
|
|
|
_disable();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2017-12-17 08:51:37 +00:00
|
|
|
/* Initialize and mask the PIC */
|
|
|
|
HalpInitializeLegacyPICs();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-21 12:51:13 +00:00
|
|
|
/* Read EISA Edge/Level Register for master and slave */
|
|
|
|
Elcr.Bits = (__inbyte(EISA_ELCR_SLAVE) << 8) | __inbyte(EISA_ELCR_MASTER);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2020-07-25 13:31:02 +00:00
|
|
|
#if defined(SARCH_PC98)
|
|
|
|
/* Force defaults when ELCR is not supported */
|
|
|
|
if (Elcr.Bits == 0xFFFF)
|
|
|
|
{
|
|
|
|
Elcr.Master.Irq0Level = 0;
|
|
|
|
Elcr.Master.Irq1Level = 0;
|
|
|
|
Elcr.Master.Irq7Level = 0;
|
|
|
|
Elcr.Slave.Irq8Level = 0;
|
|
|
|
}
|
|
|
|
ElcrFound = TRUE;
|
|
|
|
#else
|
2010-01-21 12:51:13 +00:00
|
|
|
/* IRQs 0, 1, 2, 8, and 13 are system-reserved and must be edge */
|
2020-07-25 13:31:02 +00:00
|
|
|
ElcrFound = (!(Elcr.Master.Irq0Level) && !(Elcr.Master.Irq1Level) && !(Elcr.Master.Irq2Level) &&
|
|
|
|
!(Elcr.Slave.Irq8Level) && !(Elcr.Slave.Irq13Level));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (ElcrFound)
|
2010-01-21 12:51:13 +00:00
|
|
|
{
|
|
|
|
/* ELCR is as it's supposed to be, save it */
|
|
|
|
HalpEisaELCR = Elcr.Bits;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-21 12:51:13 +00:00
|
|
|
/* Scan for level interrupts */
|
|
|
|
for (i = 1, j = 0; j < 16; i <<= 1, j++)
|
|
|
|
{
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
if (HalpEisaELCR & i)
|
|
|
|
{
|
|
|
|
/* Switch handler to level */
|
|
|
|
SWInterruptHandlerTable[j + 4] = HalpHardwareInterruptLevel;
|
|
|
|
|
|
|
|
/* Switch dismiss to level */
|
|
|
|
HalpSpecialDismissTable[j] = HalpSpecialDismissLevelTable[j];
|
|
|
|
}
|
2010-01-21 12:51:13 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2020-07-25 13:31:02 +00:00
|
|
|
/* Report cascade IRQ usage */
|
2011-09-10 18:58:01 +00:00
|
|
|
HalpRegisterVector(IDT_INTERNAL,
|
2020-07-25 13:31:02 +00:00
|
|
|
PRIMARY_VECTOR_BASE + PIC_CASCADE_IRQ,
|
|
|
|
PRIMARY_VECTOR_BASE + PIC_CASCADE_IRQ,
|
2011-09-10 18:58:01 +00:00
|
|
|
HIGH_LEVEL);
|
|
|
|
|
2010-01-21 12:51:13 +00:00
|
|
|
/* Restore interrupt state */
|
|
|
|
if (EnableInterrupts) EFlags |= EFLAGS_INTERRUPT_MASK;
|
|
|
|
__writeeflags(EFlags);
|
|
|
|
}
|
|
|
|
|
2011-09-05 15:20:07 +00:00
|
|
|
UCHAR
|
|
|
|
FASTCALL
|
|
|
|
HalpIrqToVector(UCHAR Irq)
|
|
|
|
{
|
|
|
|
return (PRIMARY_VECTOR_BASE + Irq);
|
|
|
|
}
|
|
|
|
|
|
|
|
UCHAR
|
|
|
|
FASTCALL
|
|
|
|
HalpVectorToIrq(UCHAR Vector)
|
|
|
|
{
|
|
|
|
return (Vector - PRIMARY_VECTOR_BASE);
|
|
|
|
}
|
|
|
|
|
|
|
|
KIRQL
|
|
|
|
FASTCALL
|
|
|
|
HalpVectorToIrql(UCHAR Vector)
|
|
|
|
{
|
|
|
|
return (PROFILE_LEVEL - (Vector - PRIMARY_VECTOR_BASE));
|
|
|
|
}
|
|
|
|
|
2010-01-24 23:14:08 +00:00
|
|
|
/* IRQL MANAGEMENT ************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
KIRQL
|
|
|
|
NTAPI
|
|
|
|
KeGetCurrentIrql(VOID)
|
|
|
|
{
|
|
|
|
/* Return the IRQL */
|
|
|
|
return KeGetPcr()->Irql;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
KIRQL
|
|
|
|
NTAPI
|
|
|
|
KeRaiseIrqlToDpcLevel(VOID)
|
|
|
|
{
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
KIRQL CurrentIrql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:14:08 +00:00
|
|
|
/* Save and update IRQL */
|
|
|
|
CurrentIrql = Pcr->Irql;
|
|
|
|
Pcr->Irql = DISPATCH_LEVEL;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-06-02 13:59:47 +00:00
|
|
|
#if DBG
|
2010-01-24 23:14:08 +00:00
|
|
|
/* Validate correct raise */
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
if (CurrentIrql > DISPATCH_LEVEL) KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
|
2010-01-24 23:14:08 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Return the previous value */
|
|
|
|
return CurrentIrql;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
KIRQL
|
|
|
|
NTAPI
|
|
|
|
KeRaiseIrqlToSynchLevel(VOID)
|
|
|
|
{
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
KIRQL CurrentIrql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:14:08 +00:00
|
|
|
/* Save and update IRQL */
|
|
|
|
CurrentIrql = Pcr->Irql;
|
|
|
|
Pcr->Irql = SYNCH_LEVEL;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-06-02 13:59:47 +00:00
|
|
|
#if DBG
|
2010-01-24 23:14:08 +00:00
|
|
|
/* Validate correct raise */
|
|
|
|
if (CurrentIrql > SYNCH_LEVEL)
|
|
|
|
{
|
|
|
|
/* Crash system */
|
|
|
|
KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL,
|
|
|
|
CurrentIrql,
|
|
|
|
SYNCH_LEVEL,
|
|
|
|
0,
|
|
|
|
1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Return the previous value */
|
|
|
|
return CurrentIrql;
|
|
|
|
}
|
|
|
|
|
2010-01-24 23:19:40 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
KIRQL
|
|
|
|
FASTCALL
|
|
|
|
KfRaiseIrql(IN KIRQL NewIrql)
|
|
|
|
{
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
KIRQL CurrentIrql;
|
|
|
|
|
|
|
|
/* Read current IRQL */
|
|
|
|
CurrentIrql = Pcr->Irql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-06-02 13:59:47 +00:00
|
|
|
#if DBG
|
2010-01-24 23:19:40 +00:00
|
|
|
/* Validate correct raise */
|
|
|
|
if (CurrentIrql > NewIrql)
|
|
|
|
{
|
|
|
|
/* Crash system */
|
|
|
|
Pcr->Irql = PASSIVE_LEVEL;
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
|
2010-01-24 23:19:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
|
|
|
|
/* Set new IRQL */
|
|
|
|
Pcr->Irql = NewIrql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:19:40 +00:00
|
|
|
/* Return old IRQL */
|
|
|
|
return CurrentIrql;
|
|
|
|
}
|
2010-01-24 23:14:08 +00:00
|
|
|
|
2010-01-25 01:20:43 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
KfLowerIrql(IN KIRQL OldIrql)
|
|
|
|
{
|
|
|
|
ULONG EFlags;
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
ULONG PendingIrql, PendingIrqlMask;
|
2010-01-25 01:20:43 +00:00
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
PIC_MASK Mask;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-06-02 13:59:47 +00:00
|
|
|
#if DBG
|
2010-01-25 01:20:43 +00:00
|
|
|
/* Validate correct lower */
|
|
|
|
if (OldIrql > Pcr->Irql)
|
|
|
|
{
|
|
|
|
/* Crash system */
|
|
|
|
Pcr->Irql = HIGH_LEVEL;
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
|
2010-01-25 01:20:43 +00:00
|
|
|
}
|
|
|
|
#endif
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-25 01:20:43 +00:00
|
|
|
/* Save EFlags and disable interrupts */
|
|
|
|
EFlags = __readeflags();
|
|
|
|
_disable();
|
|
|
|
|
|
|
|
/* Set old IRQL */
|
|
|
|
Pcr->Irql = OldIrql;
|
2011-11-18 18:53:41 +00:00
|
|
|
|
2012-03-26 14:51:03 +00:00
|
|
|
/* Check for pending software interrupts and compare with current IRQL */
|
|
|
|
PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
|
|
|
|
if (PendingIrqlMask)
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
{
|
2012-03-26 14:51:03 +00:00
|
|
|
/* Check if pending IRQL affects hardware state */
|
|
|
|
BitScanReverse(&PendingIrql, PendingIrqlMask);
|
|
|
|
if (PendingIrql > DISPATCH_LEVEL)
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
{
|
2012-03-26 14:51:03 +00:00
|
|
|
/* Set new PIC mask */
|
|
|
|
Mask.Both = Pcr->IDR & 0xFFFF;
|
|
|
|
__outbyte(PIC1_DATA_PORT, Mask.Master);
|
|
|
|
__outbyte(PIC2_DATA_PORT, Mask.Slave);
|
2011-11-18 18:53:41 +00:00
|
|
|
|
2012-03-26 14:51:03 +00:00
|
|
|
/* Clear IRR bit */
|
|
|
|
Pcr->IRR ^= (1 << PendingIrql);
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
}
|
2012-03-26 14:51:03 +00:00
|
|
|
|
|
|
|
/* Now handle pending interrupt */
|
|
|
|
SWInterruptHandlerTable[PendingIrql]();
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
}
|
2010-01-25 01:20:43 +00:00
|
|
|
|
|
|
|
/* Restore interrupt state */
|
|
|
|
__writeeflags(EFlags);
|
|
|
|
}
|
|
|
|
|
2010-01-24 23:14:08 +00:00
|
|
|
/* SOFTWARE INTERRUPTS ********************************************************/
|
|
|
|
|
2010-01-25 01:26:53 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
HalRequestSoftwareInterrupt(IN KIRQL Irql)
|
|
|
|
{
|
|
|
|
ULONG EFlags;
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
KIRQL PendingIrql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-25 01:26:53 +00:00
|
|
|
/* Save EFlags and disable interrupts */
|
|
|
|
EFlags = __readeflags();
|
|
|
|
_disable();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-25 01:26:53 +00:00
|
|
|
/* Mask out the requested bit */
|
|
|
|
Pcr->IRR |= (1 << Irql);
|
|
|
|
|
|
|
|
/* Check for pending software interrupts and compare with current IRQL */
|
|
|
|
PendingIrql = SWInterruptLookUpTable[Pcr->IRR & 3];
|
|
|
|
if (PendingIrql > Pcr->Irql) SWInterruptHandlerTable[PendingIrql]();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-25 01:26:53 +00:00
|
|
|
/* Restore interrupt state */
|
|
|
|
__writeeflags(EFlags);
|
|
|
|
}
|
|
|
|
|
2010-01-24 23:14:08 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
HalClearSoftwareInterrupt(IN KIRQL Irql)
|
|
|
|
{
|
|
|
|
/* Mask out the requested bit */
|
|
|
|
KeGetPcr()->IRR &= ~(1 << Irql);
|
|
|
|
}
|
2010-01-24 23:21:36 +00:00
|
|
|
|
2016-05-10 15:03:56 +00:00
|
|
|
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY
|
2018-02-11 10:33:16 +00:00
|
|
|
FASTCALL
|
2016-05-10 15:03:56 +00:00
|
|
|
HalpEndSoftwareInterrupt2(IN KIRQL OldIrql,
|
|
|
|
IN PKTRAP_FRAME TrapFrame)
|
2010-01-25 01:51:47 +00:00
|
|
|
{
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
|
2010-01-25 01:51:47 +00:00
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
PIC_MASK Mask;
|
|
|
|
|
2016-05-10 15:03:56 +00:00
|
|
|
UNREFERENCED_PARAMETER(TrapFrame);
|
|
|
|
|
2010-01-25 01:51:47 +00:00
|
|
|
/* Set old IRQL */
|
|
|
|
Pcr->Irql = OldIrql;
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
|
|
|
|
/* Loop checking for pending interrupts */
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
/* Check for pending software interrupts and compare with current IRQL */
|
|
|
|
PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
|
2016-05-10 15:03:56 +00:00
|
|
|
if (!PendingIrqlMask) return NULL;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Check for in-service delayed interrupt */
|
2016-05-10 15:03:56 +00:00
|
|
|
if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Check if pending IRQL affects hardware state */
|
|
|
|
BitScanReverse(&PendingIrql, PendingIrqlMask);
|
|
|
|
if (PendingIrql > DISPATCH_LEVEL)
|
|
|
|
{
|
|
|
|
/* Set new PIC mask */
|
2011-11-21 12:04:16 +00:00
|
|
|
Mask.Both = Pcr->IDR & 0xFFFF;
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
__outbyte(PIC1_DATA_PORT, Mask.Master);
|
|
|
|
__outbyte(PIC2_DATA_PORT, Mask.Slave);
|
|
|
|
|
|
|
|
/* Set active bit otherwise, and clear it from IRR */
|
|
|
|
PendingIrqMask = (1 << PendingIrql);
|
|
|
|
Pcr->IrrActive |= PendingIrqMask;
|
|
|
|
Pcr->IRR ^= PendingIrqMask;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Handle delayed hardware interrupt */
|
|
|
|
SWInterruptHandlerTable[PendingIrql]();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Handling complete */
|
|
|
|
Pcr->IrrActive ^= PendingIrqMask;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No need to loop checking for hardware interrupts */
|
2016-05-10 15:03:56 +00:00
|
|
|
return SWInterruptHandlerTable2[PendingIrql];
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
}
|
|
|
|
}
|
2016-05-10 15:03:56 +00:00
|
|
|
|
|
|
|
return NULL;
|
2010-01-25 01:51:47 +00:00
|
|
|
}
|
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* EDGE INTERRUPT DISMISSAL FUNCTIONS *****************************************/
|
2010-01-24 23:30:43 +00:00
|
|
|
|
|
|
|
FORCEINLINE
|
2014-05-04 09:39:44 +00:00
|
|
|
BOOLEAN
|
2010-01-24 23:30:43 +00:00
|
|
|
_HalpDismissIrqGeneric(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
PIC_MASK Mask;
|
|
|
|
KIRQL CurrentIrql;
|
|
|
|
I8259_OCW2 Ocw2;
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
|
|
|
|
/* First save current IRQL and compare it to the requested one */
|
|
|
|
CurrentIrql = Pcr->Irql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Check if this interrupt is really allowed to happen */
|
|
|
|
if (Irql > CurrentIrql)
|
|
|
|
{
|
|
|
|
/* Set the new IRQL and return the current one */
|
|
|
|
Pcr->Irql = Irql;
|
|
|
|
*OldIrql = CurrentIrql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Prepare OCW2 for EOI */
|
|
|
|
Ocw2.Bits = 0;
|
|
|
|
Ocw2.EoiMode = SpecificEoi;
|
2010-01-24 23:30:43 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Check which PIC needs the EOI */
|
2015-08-29 14:04:57 +00:00
|
|
|
if (Irq >= 8)
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
{
|
2020-07-25 13:31:02 +00:00
|
|
|
#if defined(SARCH_PC98)
|
|
|
|
I8259_OCW3 Ocw3;
|
|
|
|
I8259_ISR Isr;
|
|
|
|
|
|
|
|
/* Send the EOI for the IRQ */
|
|
|
|
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
|
|
|
|
|
|
|
|
/* Request the ISR */
|
|
|
|
Ocw3.Bits = 0;
|
|
|
|
Ocw3.Sbo = 1;
|
|
|
|
Ocw3.ReadRequest = ReadIsr;
|
|
|
|
__outbyte(PIC2_CONTROL_PORT, Ocw3.Bits);
|
|
|
|
|
|
|
|
/* Read the ISR */
|
|
|
|
Isr.Bits = __inbyte(PIC2_CONTROL_PORT);
|
|
|
|
|
|
|
|
/* Check if the interrupt serviced was the only one from the slave PIC */
|
|
|
|
if (Isr.Bits == 0)
|
|
|
|
{
|
|
|
|
/* If ISR is empty, send the EOI for cascade IRQ on the master PIC */
|
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
|
|
|
}
|
|
|
|
#else
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Send the EOI for the IRQ */
|
2011-11-21 12:04:16 +00:00
|
|
|
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2020-07-25 13:31:02 +00:00
|
|
|
/* Send the EOI for cascade IRQ on the master PIC */
|
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
|
|
|
#endif
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Send the EOI for the IRQ */
|
2020-07-25 13:31:02 +00:00
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | (Irq & 0xFF));
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
}
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Enable interrupts and return success */
|
|
|
|
_enable();
|
|
|
|
return TRUE;
|
|
|
|
}
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Update the IRR so that we deliver this interrupt when the IRQL is proper */
|
|
|
|
Pcr->IRR |= (1 << (Irq + 4));
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Set new PIC mask to real IRQL level, since the optimization is lost now */
|
2011-11-21 12:04:16 +00:00
|
|
|
Mask.Both = (KiI8259MaskTable[CurrentIrql] | Pcr->IDR) & 0xFFFF;
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
__outbyte(PIC1_DATA_PORT, Mask.Master);
|
|
|
|
__outbyte(PIC2_DATA_PORT, Mask.Slave);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Now lie and say this was spurious */
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-01-24 23:30:43 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
BOOLEAN
|
2015-09-15 23:03:42 +00:00
|
|
|
NTAPI
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrqGeneric(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
/* Run the inline code */
|
|
|
|
return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
2015-09-15 23:03:42 +00:00
|
|
|
NTAPI
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrq15(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
I8259_OCW3 Ocw3;
|
|
|
|
I8259_OCW2 Ocw2;
|
|
|
|
I8259_ISR Isr;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Request the ISR */
|
|
|
|
Ocw3.Bits = 0;
|
|
|
|
Ocw3.Sbo = 1; /* This encodes an OCW3 vs. an OCW2 */
|
|
|
|
Ocw3.ReadRequest = ReadIsr;
|
|
|
|
__outbyte(PIC2_CONTROL_PORT, Ocw3.Bits);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Read the ISR */
|
|
|
|
Isr.Bits = __inbyte(PIC2_CONTROL_PORT);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Is IRQ15 really active (this is IR7) */
|
|
|
|
if (Isr.Irq7 == FALSE)
|
|
|
|
{
|
2020-07-25 13:31:02 +00:00
|
|
|
/* It isn't, so we have to EOI cascade IRQ */
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
Ocw2.Bits = 0;
|
|
|
|
Ocw2.EoiMode = SpecificEoi;
|
2020-07-25 13:31:02 +00:00
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* And now fail since this was spurious */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do normal interrupt dismiss */
|
|
|
|
return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
2015-09-15 23:03:42 +00:00
|
|
|
NTAPI
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrq13(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
/* Clear the FPU busy latch */
|
|
|
|
__outbyte(0xF0, 0);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Do normal interrupt dismiss */
|
|
|
|
return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
|
|
|
|
}
|
|
|
|
|
2020-07-25 13:31:02 +00:00
|
|
|
#if defined(SARCH_PC98)
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
HalpDismissIrq08(
|
|
|
|
_In_ KIRQL Irql,
|
|
|
|
_In_ ULONG Irq,
|
|
|
|
_Out_ PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
/* Clear the FPU busy latch */
|
|
|
|
__outbyte(CPU_IO_o_FPU_BUSY_LATCH, 0);
|
|
|
|
|
|
|
|
/* Do normal interrupt dismiss */
|
|
|
|
return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
BOOLEAN
|
2015-09-15 23:03:42 +00:00
|
|
|
NTAPI
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrq07(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
I8259_OCW3 Ocw3;
|
|
|
|
I8259_ISR Isr;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Request the ISR */
|
|
|
|
Ocw3.Bits = 0;
|
|
|
|
Ocw3.Sbo = 1;
|
|
|
|
Ocw3.ReadRequest = ReadIsr;
|
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw3.Bits);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Read the ISR */
|
|
|
|
Isr.Bits = __inbyte(PIC1_CONTROL_PORT);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Is IRQ 7 really active? If it isn't, this is spurious so fail */
|
|
|
|
if (Isr.Irq7 == FALSE) return FALSE;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Do normal interrupt dismiss */
|
|
|
|
return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* LEVEL INTERRUPT DISMISSAL FUNCTIONS ****************************************/
|
|
|
|
|
|
|
|
FORCEINLINE
|
2014-05-04 09:39:44 +00:00
|
|
|
BOOLEAN
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
_HalpDismissIrqLevel(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
PIC_MASK Mask;
|
|
|
|
KIRQL CurrentIrql;
|
|
|
|
I8259_OCW2 Ocw2;
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
|
|
|
|
/* Update the PIC */
|
2011-11-21 12:04:16 +00:00
|
|
|
Mask.Both = (KiI8259MaskTable[Irql] | Pcr->IDR) & 0xFFFF;
|
2010-01-24 23:30:43 +00:00
|
|
|
__outbyte(PIC1_DATA_PORT, Mask.Master);
|
|
|
|
__outbyte(PIC2_DATA_PORT, Mask.Slave);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Update the IRR so that we clear this interrupt when the IRQL is proper */
|
|
|
|
Pcr->IRR |= (1 << (Irq + 4));
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Save current IRQL */
|
|
|
|
CurrentIrql = Pcr->Irql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Prepare OCW2 for EOI */
|
|
|
|
Ocw2.Bits = 0;
|
|
|
|
Ocw2.EoiMode = SpecificEoi;
|
|
|
|
|
|
|
|
/* Check which PIC needs the EOI */
|
2015-08-29 14:09:57 +00:00
|
|
|
if (Irq >= 8)
|
2010-01-24 23:30:43 +00:00
|
|
|
{
|
2020-07-25 13:31:02 +00:00
|
|
|
#if defined(SARCH_PC98)
|
|
|
|
I8259_OCW3 Ocw3;
|
|
|
|
I8259_ISR Isr;
|
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Send the EOI for the IRQ */
|
2011-11-21 12:04:16 +00:00
|
|
|
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
|
2020-07-25 13:31:02 +00:00
|
|
|
/* Request the ISR */
|
|
|
|
Ocw3.Bits = 0;
|
|
|
|
Ocw3.Sbo = 1;
|
|
|
|
Ocw3.ReadRequest = ReadIsr;
|
|
|
|
__outbyte(PIC2_CONTROL_PORT, Ocw3.Bits);
|
|
|
|
|
|
|
|
/* Read the ISR */
|
|
|
|
Isr.Bits = __inbyte(PIC2_CONTROL_PORT);
|
|
|
|
|
|
|
|
/* Check if the interrupt serviced was the only one from the slave PIC */
|
|
|
|
if (Isr.Bits == 0)
|
|
|
|
{
|
|
|
|
/* If ISR is empty, send the EOI for cascade IRQ on the master PIC */
|
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
/* Send the EOI for the IRQ */
|
|
|
|
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
|
|
|
|
|
|
|
|
/* Send the EOI for cascade IRQ on the master PIC */
|
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
|
|
|
#endif
|
2010-01-24 23:30:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Send the EOI for the IRQ */
|
2011-11-21 12:04:16 +00:00
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | (Irq & 0xFF));
|
2010-01-24 23:30:43 +00:00
|
|
|
}
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
|
|
|
|
/* Check if this interrupt should be allowed to happen */
|
|
|
|
if (Irql > CurrentIrql)
|
|
|
|
{
|
|
|
|
/* Set the new IRQL and return the current one */
|
|
|
|
Pcr->Irql = Irql;
|
|
|
|
*OldIrql = CurrentIrql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Enable interrupts and return success */
|
|
|
|
_enable();
|
|
|
|
return TRUE;
|
|
|
|
}
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Now lie and say this was spurious */
|
|
|
|
return FALSE;
|
2010-01-24 23:30:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
2015-09-15 23:03:42 +00:00
|
|
|
NTAPI
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrqLevel(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
2010-01-24 23:30:43 +00:00
|
|
|
{
|
|
|
|
/* Run the inline code */
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
|
2010-01-24 23:30:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
2015-09-15 23:03:42 +00:00
|
|
|
NTAPI
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrq15Level(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
2010-01-24 23:30:43 +00:00
|
|
|
{
|
|
|
|
I8259_OCW3 Ocw3;
|
|
|
|
I8259_OCW2 Ocw2;
|
|
|
|
I8259_ISR Isr;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Request the ISR */
|
|
|
|
Ocw3.Bits = 0;
|
|
|
|
Ocw3.Sbo = 1; /* This encodes an OCW3 vs. an OCW2 */
|
|
|
|
Ocw3.ReadRequest = ReadIsr;
|
|
|
|
__outbyte(PIC2_CONTROL_PORT, Ocw3.Bits);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Read the ISR */
|
|
|
|
Isr.Bits = __inbyte(PIC2_CONTROL_PORT);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Is IRQ15 really active (this is IR7) */
|
|
|
|
if (Isr.Irq7 == FALSE)
|
|
|
|
{
|
2020-07-25 13:31:02 +00:00
|
|
|
/* It isn't, so we have to EOI cascade IRQ */
|
2010-01-24 23:30:43 +00:00
|
|
|
Ocw2.Bits = 0;
|
|
|
|
Ocw2.EoiMode = SpecificEoi;
|
2020-07-25 13:31:02 +00:00
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* And now fail since this was spurious */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do normal interrupt dismiss */
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
|
2010-01-24 23:30:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
2015-09-15 23:03:42 +00:00
|
|
|
NTAPI
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrq13Level(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
2010-01-24 23:30:43 +00:00
|
|
|
{
|
|
|
|
/* Clear the FPU busy latch */
|
|
|
|
__outbyte(0xF0, 0);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Do normal interrupt dismiss */
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
|
2010-01-24 23:30:43 +00:00
|
|
|
}
|
|
|
|
|
2020-07-25 13:31:02 +00:00
|
|
|
#if defined(SARCH_PC98)
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
HalpDismissIrq08Level(
|
|
|
|
_In_ KIRQL Irql,
|
|
|
|
_In_ ULONG Irq,
|
|
|
|
_Out_ PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
/* Clear the FPU busy latch */
|
|
|
|
__outbyte(CPU_IO_o_FPU_BUSY_LATCH, 0);
|
|
|
|
|
|
|
|
/* Do normal interrupt dismiss */
|
|
|
|
return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
BOOLEAN
|
2015-09-15 23:03:42 +00:00
|
|
|
NTAPI
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDismissIrq07Level(IN KIRQL Irql,
|
|
|
|
IN ULONG Irq,
|
|
|
|
OUT PKIRQL OldIrql)
|
2010-01-24 23:30:43 +00:00
|
|
|
{
|
|
|
|
I8259_OCW3 Ocw3;
|
|
|
|
I8259_ISR Isr;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Request the ISR */
|
|
|
|
Ocw3.Bits = 0;
|
|
|
|
Ocw3.Sbo = 1;
|
|
|
|
Ocw3.ReadRequest = ReadIsr;
|
|
|
|
__outbyte(PIC1_CONTROL_PORT, Ocw3.Bits);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Read the ISR */
|
|
|
|
Isr.Bits = __inbyte(PIC1_CONTROL_PORT);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Is IRQ 7 really active? If it isn't, this is spurious so fail */
|
|
|
|
if (Isr.Irq7 == FALSE) return FALSE;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Do normal interrupt dismiss */
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
|
|
|
|
}
|
|
|
|
|
2018-02-18 11:51:16 +00:00
|
|
|
PHAL_SW_INTERRUPT_HANDLER
|
2015-09-15 10:35:49 +00:00
|
|
|
__cdecl
|
2018-02-18 11:51:16 +00:00
|
|
|
HalpHardwareInterruptLevel2(VOID)
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
{
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
ULONG PendingIrqlMask, PendingIrql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Check for pending software interrupts and compare with current IRQL */
|
|
|
|
PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[Pcr->Irql];
|
|
|
|
if (PendingIrqlMask)
|
|
|
|
{
|
|
|
|
/* Check for in-service delayed interrupt */
|
2018-02-18 11:51:16 +00:00
|
|
|
if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Check if pending IRQL affects hardware state */
|
|
|
|
BitScanReverse(&PendingIrql, PendingIrqlMask);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Clear IRR bit */
|
|
|
|
Pcr->IRR ^= (1 << PendingIrql);
|
|
|
|
|
|
|
|
/* Now handle pending interrupt */
|
2018-02-18 11:51:16 +00:00
|
|
|
return SWInterruptHandlerTable[PendingIrql];
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
}
|
2018-02-18 11:51:16 +00:00
|
|
|
|
|
|
|
return NULL;
|
2010-01-24 23:30:43 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* SYSTEM INTERRUPTS **********************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
HalEnableSystemInterrupt(IN ULONG Vector,
|
2010-01-24 23:21:36 +00:00
|
|
|
IN KIRQL Irql,
|
|
|
|
IN KINTERRUPT_MODE InterruptMode)
|
|
|
|
{
|
|
|
|
ULONG Irq;
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
PIC_MASK PicMask;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Validate the IRQ */
|
|
|
|
Irq = Vector - PRIMARY_VECTOR_BASE;
|
|
|
|
if (Irq >= CLOCK2_LEVEL) return FALSE;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Check for level interrupt */
|
|
|
|
if (InterruptMode == LevelSensitive)
|
2010-01-24 23:21:36 +00:00
|
|
|
{
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Switch handler to level */
|
|
|
|
SWInterruptHandlerTable[Irq + 4] = HalpHardwareInterruptLevel;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Switch dismiss to level */
|
|
|
|
HalpSpecialDismissTable[Irq] = HalpSpecialDismissLevelTable[Irq];
|
2010-01-24 23:21:36 +00:00
|
|
|
}
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Disable interrupts */
|
|
|
|
_disable();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Update software IDR */
|
|
|
|
Pcr->IDR &= ~(1 << Irq);
|
|
|
|
|
|
|
|
/* Set new PIC mask */
|
2011-11-21 12:04:16 +00:00
|
|
|
PicMask.Both = (KiI8259MaskTable[Pcr->Irql] | Pcr->IDR) & 0xFFFF;
|
2010-01-24 23:21:36 +00:00
|
|
|
__outbyte(PIC1_DATA_PORT, PicMask.Master);
|
|
|
|
__outbyte(PIC2_DATA_PORT, PicMask.Slave);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Enable interrupts and exit */
|
|
|
|
_enable();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
NTAPI
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
HalDisableSystemInterrupt(IN ULONG Vector,
|
2010-01-24 23:21:36 +00:00
|
|
|
IN KIRQL Irql)
|
|
|
|
{
|
|
|
|
ULONG IrqMask;
|
|
|
|
PIC_MASK PicMask;
|
|
|
|
|
|
|
|
/* Compute new combined IRQ mask */
|
|
|
|
IrqMask = 1 << (Vector - PRIMARY_VECTOR_BASE);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Disable interrupts */
|
|
|
|
_disable();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Update software IDR */
|
|
|
|
KeGetPcr()->IDR |= IrqMask;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Read current interrupt mask */
|
|
|
|
PicMask.Master = __inbyte(PIC1_DATA_PORT);
|
|
|
|
PicMask.Slave = __inbyte(PIC2_DATA_PORT);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Add the new disabled interrupt */
|
|
|
|
PicMask.Both |= IrqMask;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Write new interrupt mask */
|
|
|
|
__outbyte(PIC1_DATA_PORT, PicMask.Master);
|
|
|
|
__outbyte(PIC2_DATA_PORT, PicMask.Slave);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:21:36 +00:00
|
|
|
/* Bring interrupts back */
|
|
|
|
_enable();
|
|
|
|
}
|
2010-01-24 23:30:43 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
HalBeginSystemInterrupt(IN KIRQL Irql,
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
IN ULONG Vector,
|
2010-01-24 23:30:43 +00:00
|
|
|
OUT PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
ULONG Irq;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-24 23:30:43 +00:00
|
|
|
/* Get the IRQ and call the proper routine to handle it */
|
|
|
|
Irq = Vector - PRIMARY_VECTOR_BASE;
|
|
|
|
return HalpSpecialDismissTable[Irq](Irql, Irq, OldIrql);
|
|
|
|
}
|
2010-01-25 01:51:47 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2018-02-18 11:49:24 +00:00
|
|
|
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY
|
|
|
|
FASTCALL
|
|
|
|
HalEndSystemInterrupt2(IN KIRQL OldIrql,
|
|
|
|
IN PKTRAP_FRAME TrapFrame)
|
2010-01-25 01:51:47 +00:00
|
|
|
{
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
|
2010-01-25 01:51:47 +00:00
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
PIC_MASK Mask;
|
|
|
|
|
|
|
|
/* Set old IRQL */
|
|
|
|
Pcr->Irql = OldIrql;
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
|
2010-01-25 01:51:47 +00:00
|
|
|
/* Check for pending software interrupts and compare with current IRQL */
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
|
|
|
|
if (PendingIrqlMask)
|
|
|
|
{
|
|
|
|
/* Check for in-service delayed interrupt */
|
2018-02-18 11:49:24 +00:00
|
|
|
if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Loop checking for pending interrupts */
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
/* Check if pending IRQL affects hardware state */
|
|
|
|
BitScanReverse(&PendingIrql, PendingIrqlMask);
|
|
|
|
if (PendingIrql > DISPATCH_LEVEL)
|
|
|
|
{
|
|
|
|
/* Set new PIC mask */
|
2011-11-21 12:04:16 +00:00
|
|
|
Mask.Both = Pcr->IDR & 0xFFFF;
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
__outbyte(PIC1_DATA_PORT, Mask.Master);
|
|
|
|
__outbyte(PIC2_DATA_PORT, Mask.Slave);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Now check if this specific interrupt is already in-service */
|
|
|
|
PendingIrqMask = (1 << PendingIrql);
|
2018-02-18 11:49:24 +00:00
|
|
|
if (Pcr->IrrActive & PendingIrqMask) return NULL;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Set active bit otherwise, and clear it from IRR */
|
|
|
|
Pcr->IrrActive |= PendingIrqMask;
|
|
|
|
Pcr->IRR ^= PendingIrqMask;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Handle delayed hardware interrupt */
|
|
|
|
SWInterruptHandlerTable[PendingIrql]();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Handling complete */
|
|
|
|
Pcr->IrrActive ^= PendingIrqMask;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Check if there's still interrupts pending */
|
|
|
|
PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[Pcr->Irql];
|
|
|
|
if (!PendingIrqlMask) break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Now handle pending software interrupt */
|
2018-02-18 11:49:24 +00:00
|
|
|
return SWInterruptHandlerTable2[PendingIrql];
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-02-18 11:49:24 +00:00
|
|
|
|
|
|
|
return NULL;
|
2010-01-25 01:51:47 +00:00
|
|
|
}
|
2010-01-25 03:00:01 +00:00
|
|
|
|
|
|
|
/* SOFTWARE INTERRUPT TRAPS ***************************************************/
|
|
|
|
|
2010-01-28 20:45:45 +00:00
|
|
|
FORCEINLINE
|
|
|
|
DECLSPEC_NORETURN
|
2015-09-13 20:37:28 +00:00
|
|
|
VOID
|
2010-01-28 20:45:45 +00:00
|
|
|
_HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
2010-01-25 03:00:01 +00:00
|
|
|
{
|
|
|
|
KIRQL CurrentIrql;
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-25 03:00:01 +00:00
|
|
|
/* Save the current IRQL and update it */
|
|
|
|
CurrentIrql = Pcr->Irql;
|
|
|
|
Pcr->Irql = APC_LEVEL;
|
2010-01-28 20:45:45 +00:00
|
|
|
|
2010-01-25 03:00:01 +00:00
|
|
|
/* Remove DPC from IRR */
|
|
|
|
Pcr->IRR &= ~(1 << APC_LEVEL);
|
2010-01-28 20:45:45 +00:00
|
|
|
|
2010-01-25 03:00:01 +00:00
|
|
|
/* Enable interrupts and call the kernel's APC interrupt handler */
|
|
|
|
_enable();
|
|
|
|
KiDeliverApc(((KiUserTrap(TrapFrame)) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) ?
|
2010-01-28 20:45:45 +00:00
|
|
|
UserMode : KernelMode,
|
|
|
|
NULL,
|
|
|
|
TrapFrame);
|
2010-01-25 03:00:01 +00:00
|
|
|
|
|
|
|
/* Disable interrupts and end the interrupt */
|
|
|
|
_disable();
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpEndSoftwareInterrupt(CurrentIrql, TrapFrame);
|
2010-01-28 20:45:45 +00:00
|
|
|
|
2010-01-25 03:00:01 +00:00
|
|
|
/* Exit the interrupt */
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
KiEoiHelper(TrapFrame);
|
2010-01-25 03:00:01 +00:00
|
|
|
}
|
|
|
|
|
2010-01-28 20:45:45 +00:00
|
|
|
DECLSPEC_NORETURN
|
2015-09-13 20:37:28 +00:00
|
|
|
VOID
|
2010-08-01 16:27:48 +00:00
|
|
|
FASTCALL
|
2010-01-28 20:45:45 +00:00
|
|
|
HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
|
|
|
|
{
|
|
|
|
/* Do the work */
|
|
|
|
_HalpApcInterruptHandler(TrapFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
DECLSPEC_NORETURN
|
2015-09-13 20:37:28 +00:00
|
|
|
VOID
|
2010-08-01 16:27:48 +00:00
|
|
|
FASTCALL
|
2010-01-28 20:45:45 +00:00
|
|
|
HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
2010-01-25 03:00:01 +00:00
|
|
|
{
|
|
|
|
/* Set up a fake INT Stack */
|
|
|
|
TrapFrame->EFlags = __readeflags();
|
|
|
|
TrapFrame->SegCs = KGDT_R0_CODE;
|
|
|
|
TrapFrame->Eip = TrapFrame->Eax;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-25 03:00:01 +00:00
|
|
|
/* Build the trap frame */
|
|
|
|
KiEnterInterruptTrap(TrapFrame);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-28 20:45:45 +00:00
|
|
|
/* Do the work */
|
|
|
|
_HalpApcInterruptHandler(TrapFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
FORCEINLINE
|
2014-05-04 09:39:44 +00:00
|
|
|
KIRQL
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
_HalpDispatchInterruptHandler(VOID)
|
2010-01-28 20:45:45 +00:00
|
|
|
{
|
|
|
|
KIRQL CurrentIrql;
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-25 03:00:01 +00:00
|
|
|
/* Save the current IRQL and update it */
|
|
|
|
CurrentIrql = Pcr->Irql;
|
|
|
|
Pcr->Irql = DISPATCH_LEVEL;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-25 03:00:01 +00:00
|
|
|
/* Remove DPC from IRR */
|
|
|
|
Pcr->IRR &= ~(1 << DISPATCH_LEVEL);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-25 03:00:01 +00:00
|
|
|
/* Enable interrupts and call the kernel's DPC interrupt handler */
|
|
|
|
_enable();
|
|
|
|
KiDispatchInterrupt();
|
|
|
|
_disable();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Return IRQL */
|
|
|
|
return CurrentIrql;
|
2010-01-28 20:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DECLSPEC_NORETURN
|
2015-09-13 20:37:28 +00:00
|
|
|
VOID
|
2010-08-01 16:27:48 +00:00
|
|
|
FASTCALL
|
2010-01-28 20:45:45 +00:00
|
|
|
HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
|
|
|
|
{
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
KIRQL CurrentIrql;
|
2012-02-08 18:29:08 +00:00
|
|
|
|
2010-01-28 20:45:45 +00:00
|
|
|
/* Do the work */
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
CurrentIrql = _HalpDispatchInterruptHandler();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* End the interrupt */
|
|
|
|
HalpEndSoftwareInterrupt(CurrentIrql, TrapFrame);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Exit the interrupt */
|
|
|
|
KiEoiHelper(TrapFrame);
|
2010-01-28 20:45:45 +00:00
|
|
|
}
|
|
|
|
|
2018-02-18 11:50:54 +00:00
|
|
|
PHAL_SW_INTERRUPT_HANDLER
|
2015-09-15 10:35:49 +00:00
|
|
|
__cdecl
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
HalpDispatchInterrupt2(VOID)
|
|
|
|
{
|
|
|
|
ULONG PendingIrqlMask, PendingIrql;
|
|
|
|
KIRQL OldIrql;
|
|
|
|
PIC_MASK Mask;
|
|
|
|
PKPCR Pcr = KeGetPcr();
|
|
|
|
|
|
|
|
/* Do the work */
|
|
|
|
OldIrql = _HalpDispatchInterruptHandler();
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Restore IRQL */
|
|
|
|
Pcr->Irql = OldIrql;
|
|
|
|
|
|
|
|
/* Check for pending software interrupts and compare with current IRQL */
|
|
|
|
PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
|
|
|
|
if (PendingIrqlMask)
|
|
|
|
{
|
|
|
|
/* Check if pending IRQL affects hardware state */
|
|
|
|
BitScanReverse(&PendingIrql, PendingIrqlMask);
|
|
|
|
if (PendingIrql > DISPATCH_LEVEL)
|
|
|
|
{
|
|
|
|
/* Set new PIC mask */
|
2011-11-21 12:04:16 +00:00
|
|
|
Mask.Both = Pcr->IDR & 0xFFFF;
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
__outbyte(PIC1_DATA_PORT, Mask.Master);
|
|
|
|
__outbyte(PIC2_DATA_PORT, Mask.Slave);
|
2012-02-08 18:29:08 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Clear IRR bit */
|
|
|
|
Pcr->IRR ^= (1 << PendingIrql);
|
|
|
|
}
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
/* Now handle pending interrupt */
|
2018-02-18 11:50:54 +00:00
|
|
|
return SWInterruptHandlerTable[PendingIrql];
|
[HAL]: Rewrite IRQL handling. Alex's original code (lately translated to C) was a copy of the MicroChannel (MCA), Checked-Build HAL, an unexplained choice considering MCA is not supported or even available anymore. Windows, on machines with a PIC, uses a mechanism called Lazy IRQL, in which the PIC is only programmed "lazily", meaning that lowering and raising the IRQL does not actually change the interrupt mask. Therefore, lower priority interrupts will still come in at high IRQL. At this point, the HAL will detect this, only now mask the PICs, and lie that the lower interrupt was "spurious", while setting a pending bit. When the IRQL is lowered, the bit is detected, and a software/delayed "INT" is done with the correct IRQ vector number. More details are available in the typical resources.
[HAL]: Implement support for Level interrupts, which are used by certain EISA cards, and more particularly, all PCI hardware. Level interrupts were not previously handled correctly, being treated as edge/latched interrupts instead.
[NTOS/HAL]: Remove VDM Alert KPCR hack (which was buggy). Now the PKTRAP_FRAME is passed as a parameter to HalpEndSoftwareInterrupt/HalEndSystemInterrupt. This also removes the HalpNestedTrap ASM hack, since the call can now be done in C.
[PERF]: On real machines, writing the PIC mask is a relatively expensive I/O operation, and IRQL lower/raise can happen hundreds of times a second. Lazy IRQL provides an important optimization.
[PERF]: Correctly handling level interrupts as level interrupts allows for faster, and more efficient, IRQ handling.
svn path=/trunk/; revision=45320
2010-01-29 21:10:33 +00:00
|
|
|
}
|
2018-02-18 11:50:54 +00:00
|
|
|
|
|
|
|
return NULL;
|
2010-01-25 03:00:01 +00:00
|
|
|
}
|
2010-01-26 16:31:32 +00:00
|
|
|
|
2021-06-05 13:41:49 +00:00
|
|
|
ULONG
|
|
|
|
NTAPI
|
|
|
|
HalpGetRootInterruptVector(IN ULONG BusInterruptLevel,
|
|
|
|
IN ULONG BusInterruptVector,
|
|
|
|
OUT PKIRQL Irql,
|
|
|
|
OUT PKAFFINITY Affinity)
|
|
|
|
{
|
|
|
|
UCHAR SystemVector;
|
|
|
|
|
|
|
|
/* Validate the IRQ */
|
|
|
|
if (BusInterruptLevel > 23)
|
|
|
|
{
|
|
|
|
/* Invalid vector */
|
|
|
|
DPRINT1("IRQ %lx is too high!\n", BusInterruptLevel);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the system vector */
|
|
|
|
SystemVector = HalpIrqToVector((UCHAR)BusInterruptLevel);
|
|
|
|
|
|
|
|
/* Return the IRQL and affinity */
|
|
|
|
*Irql = HalpVectorToIrql(SystemVector);
|
|
|
|
*Affinity = HalpDefaultInterruptAffinity;
|
|
|
|
ASSERT(HalpDefaultInterruptAffinity);
|
2021-09-13 01:33:14 +00:00
|
|
|
|
2021-06-05 13:41:49 +00:00
|
|
|
/* Return the vector */
|
|
|
|
return SystemVector;
|
|
|
|
}
|
|
|
|
|
2020-07-25 13:31:02 +00:00
|
|
|
#else /* _MINIHAL_ */
|
2010-03-03 21:56:52 +00:00
|
|
|
|
|
|
|
KIRQL
|
|
|
|
NTAPI
|
|
|
|
KeGetCurrentIrql(VOID)
|
|
|
|
{
|
|
|
|
return PASSIVE_LEVEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
KfLowerIrql(
|
|
|
|
IN KIRQL OldIrql)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
KIRQL
|
|
|
|
FASTCALL
|
|
|
|
KfRaiseIrql(
|
|
|
|
IN KIRQL NewIrql)
|
|
|
|
{
|
|
|
|
return NewIrql;
|
|
|
|
}
|
|
|
|
|
2020-07-25 13:31:02 +00:00
|
|
|
#endif /* !_MINIHAL_ */
|