diff --git a/hal/halx86/acpi/busemul.c b/hal/halx86/acpi/busemul.c index e26600a984b..eb45c450e36 100644 --- a/hal/halx86/acpi/busemul.c +++ b/hal/halx86/acpi/busemul.c @@ -85,20 +85,6 @@ HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, return TRUE; } -ULONG -NTAPI -HalpGetSystemInterruptVector_Acpi(IN ULONG BusNumber, - IN ULONG BusInterruptLevel, - IN ULONG BusInterruptVector, - OUT PKIRQL Irql, - OUT PKAFFINITY Affinity) -{ - UCHAR Vector = IRQ2VECTOR((UCHAR)BusInterruptLevel); - *Irql = VECTOR2IRQL(Vector); - *Affinity = 0xFFFFFFFF; - return Vector; -} - BOOLEAN NTAPI HalpFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress, @@ -254,11 +240,10 @@ HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType, OUT PKAFFINITY Affinity) { /* Call the system bus translator */ - return HalpGetSystemInterruptVector_Acpi(BusNumber, - BusInterruptLevel, - BusInterruptVector, - Irql, - Affinity); + return HalpGetRootInterruptVector(BusInterruptLevel, + BusInterruptVector, + Irql, + Affinity); } /* diff --git a/hal/halx86/apic/apic.c b/hal/halx86/apic/apic.c index 25bd4e4b4c3..eae012d61b2 100644 --- a/hal/halx86/apic/apic.c +++ b/hal/halx86/apic/apic.c @@ -4,9 +4,11 @@ * FILE: hal/halx86/apic/apic.c * PURPOSE: HAL APIC Management and Control Code * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) - * REFERENCES: http://www.joseflores.com/docs/ExploringIrql.html + * REFERENCES: https://web.archive.org/web/20190407074221/http://www.joseflores.com/docs/ExploringIrql.html * http://www.codeproject.com/KB/system/soviet_kernel_hack.aspx * http://bbs.unixmap.net/thread-2022-1-1.html + * https://www.codemachine.com/article_interruptdispatching.html + * https://www.osronline.com/article.cfm%5Earticle=211.htm */ /* INCLUDES *******************************************************************/ @@ -17,7 +19,7 @@ #include #ifndef _M_AMD64 -//#define APIC_LAZY_IRQL //FIXME: Disabled due to bug. +#define APIC_LAZY_IRQL #endif /* GLOBALS ********************************************************************/ @@ -329,30 +331,13 @@ ApicInitializeLocalApic(ULONG Cpu) UCHAR NTAPI HalpAllocateSystemInterrupt( - IN UCHAR Irq, - IN KIRQL Irql) + _In_ UCHAR Irq, + _In_ UCHAR Vector) { IOAPIC_REDIRECTION_REGISTER ReDirReg; - IN UCHAR Vector; - /* Start with lowest vector */ - Vector = IrqlToTpr(Irql) & 0xF0; - - /* Find an empty vector */ - while (HalpVectorToIndex[Vector] != APIC_FREE_VECTOR) - { - Vector++; - - /* Check if we went over the edge */ - if (TprToIrql(Vector) > Irql) - { - /* Nothing free, return failure */ - return 0; - } - } - - /* Save irq in the table */ - HalpVectorToIndex[Vector] = Irq; + ASSERT(Irq < 24); + ASSERT(HalpVectorToIndex[Vector] == APIC_FREE_VECTOR); /* Setup a redirection entry */ ReDirReg.Vector = Vector; @@ -369,6 +354,68 @@ HalpAllocateSystemInterrupt( /* Initialize entry */ ApicWriteIORedirectionEntry(Irq, ReDirReg); + /* Save irq in the table */ + HalpVectorToIndex[Vector] = Irq; + + return Vector; +} + +ULONG +NTAPI +HalpGetRootInterruptVector( + _In_ ULONG BusInterruptLevel, + _In_ ULONG BusInterruptVector, + _Out_ PKIRQL OutIrql, + _Out_ PKAFFINITY OutAffinity) +{ + UCHAR Vector; + KIRQL Irql; + + /* Get the vector currently registered */ + Vector = HalpIrqToVector(BusInterruptLevel); + + /* Check if it's used */ + if (Vector != 0xFF) + { + /* Calculate IRQL */ + NT_ASSERT(HalpVectorToIndex[Vector] == BusInterruptLevel); + *OutIrql = HalpVectorToIrql(Vector); + } + else + { + ULONG Offset; + + /* Outer loop to find alternative slots, when all IRQLs are in use */ + for (Offset = 0; Offset < 15; Offset++) + { + /* Loop allowed IRQL range */ + for (Irql = CLOCK_LEVEL - 1; Irql >= CMCI_LEVEL; Irql--) + { + /* Calculate the vactor */ + Vector = IrqlToTpr(Irql) + Offset; + + /* Check if the vector is free */ + if (HalpVectorToIrq(Vector) == APIC_FREE_VECTOR) + { + /* Found one, allocate the interrupt */ + Vector = HalpAllocateSystemInterrupt(BusInterruptLevel, Vector); + *OutIrql = Irql; + goto Exit; + } + } + } + + DPRINT1("Failed to get an interrupt vector for IRQ %lu\n", BusInterruptLevel); + *OutAffinity = 0; + *OutIrql = 0; + return 0; + } + +Exit: + + *OutAffinity = HalpDefaultInterruptAffinity; + ASSERT(HalpDefaultInterruptAffinity); + return Vector; } @@ -416,13 +463,6 @@ ApicInitializeIOApic(VOID) HalpVectorToIndex[Vector] = APIC_FREE_VECTOR; } - // HACK: Allocate all IRQs, should rather do that on demand - for (Index = 0; Index <= 15; Index++) - { - /* Map the IRQs to IRQLs like with the PIC */ - HalpAllocateSystemInterrupt(Index, 27 - Index); - } - /* Enable the timer interrupt */ ReDirReg.Vector = APIC_CLOCK_VECTOR; ReDirReg.DeliveryMode = APIC_MT_Fixed; diff --git a/hal/halx86/apic/apicp.h b/hal/halx86/apic/apicp.h index d3e1ece84aa..bd06a3a0cf6 100644 --- a/hal/halx86/apic/apicp.h +++ b/hal/halx86/apic/apicp.h @@ -11,7 +11,23 @@ #ifdef _M_AMD64 #define LOCAL_APIC_BASE 0xFFFFFFFFFFFE0000ULL #define IOAPIC_BASE 0xFFFFFFFFFFFE1000ULL - #define APIC_SPURIOUS_VECTOR 0x3f + + /* Vectors */ + #define APC_VECTOR 0x1F // IRQL 01 (APC_LEVEL) - KiApcInterrupt + #define DISPATCH_VECTOR 0x2F // IRQL 02 (DISPATCH_LEVEL) - KiDpcInterrupt + #define CMCI_VECTOR 0x35 // IRQL 05 (CMCI_LEVEL) - HalpInterruptCmciService + #define APIC_CLOCK_VECTOR 0xD1 // IRQL 13 (CLOCK_LEVEL), IRQ 8 - HalpTimerClockInterrupt + #define CLOCK_IPI_VECTOR 0xD2 // IRQL 13 (CLOCK_LEVEL) - HalpTimerClockIpiRoutine + #define REBOOT_VECTOR 0xD7 // IRQL 15 (PROFILE_LEVEL) - HalpInterruptRebootService + #define STUB_VECTOR 0xD8 // IRQL 15 (PROFILE_LEVEL) - HalpInterruptStubService + #define APIC_SPURIOUS_VECTOR 0xDF // IRQL 13 (CLOCK_LEVEL) - HalpInterruptSpuriousService + #define APIC_IPI_VECTOR 0xE1 // IRQL 14 (IPI_LEVEL) - KiIpiInterrupt + #define APIC_ERROR_VECTOR 0xE2 // IRQL 14 (IPI_LEVEL) - HalpInterruptLocalErrorService + #define POWERFAIL_VECTOR 0xE3 // IRQL 14 (POWER_LEVEL) : HalpInterruptDeferredRecoveryService + #define APIC_PROFILE_VECTOR 0xFD // IRQL 15 (PROFILE_LEVEL) - HalpTimerProfileInterrupt + #define APIC_PERF_VECTOR 0xFE // IRQL 15 (PROFILE_LEVEL) - HalpPerfInterrupt + #define APIC_NMI_VECTOR 0xFF + #define IrqlToTpr(Irql) (Irql << 4) #define IrqlToSoftVector(Irql) ((Irql << 4)|0xf) #define TprToIrql(Tpr) ((KIRQL)(Tpr >> 4)) @@ -19,7 +35,21 @@ #else #define LOCAL_APIC_BASE 0xFFFE0000 #define IOAPIC_BASE 0xFFFE1000 + + /* Vectors */ #define APIC_SPURIOUS_VECTOR 0x1f + #define APC_VECTOR 0x3D // IRQL 01 + #define DISPATCH_VECTOR 0x41 // IRQL 02 + #define APIC_GENERIC_VECTOR 0xC1 // IRQL 27 + #define APIC_CLOCK_VECTOR 0xD1 // IRQL 28 + #define APIC_SYNCH_VECTOR 0xD1 // IRQL 28 + #define APIC_IPI_VECTOR 0xE1 // IRQL 29 + #define APIC_ERROR_VECTOR 0xE3 + #define POWERFAIL_VECTOR 0xEF // IRQL 30 + #define APIC_PROFILE_VECTOR 0xFD // IRQL 31 + #define APIC_PERF_VECTOR 0xFE + #define APIC_NMI_VECTOR 0xFF + #define IrqlToTpr(Irql) (HalpIRQLtoTPR[Irql]) #define IrqlToSoftVector(Irql) IrqlToTpr(Irql) #define TprToIrql(Tpr) (HalVectorToIRQL[Tpr >> 4]) @@ -42,18 +72,6 @@ #define IMCR_PIC_DIRECT 0x00 #define IMCR_PIC_VIA_APIC 0x01 -#define ZERO_VECTOR 0x00 // IRQL 00 -#define APC_VECTOR 0x3D // IRQL 01 -#define DISPATCH_VECTOR 0x41 // IRQL 02 -#define APIC_GENERIC_VECTOR 0xC1 // IRQL 27 -#define APIC_CLOCK_VECTOR 0xD1 // IRQL 28 -#define APIC_SYNCH_VECTOR 0xD1 // IRQL 28 -#define APIC_IPI_VECTOR 0xE1 // IRQL 29 -#define APIC_ERROR_VECTOR 0xE3 -#define POWERFAIL_VECTOR 0xEF // IRQL 30 -#define APIC_PROFILE_VECTOR 0xFD // IRQL 31 -#define APIC_PERF_VECTOR 0xFE -#define APIC_NMI_VECTOR 0xFF /* APIC Register Address Map */ #define APIC_ID 0x0020 /* Local APIC ID Register (R/W) */ diff --git a/hal/halx86/include/bus.h b/hal/halx86/include/bus.h index 443d649fc9c..75a106a4328 100644 --- a/hal/halx86/include/bus.h +++ b/hal/halx86/include/bus.h @@ -400,13 +400,11 @@ HalpAssignPCISlotResources( ULONG NTAPI -HalpGetSystemInterruptVector_Acpi( - ULONG BusNumber, - ULONG BusInterruptLevel, - ULONG BusInterruptVector, - PKIRQL Irql, - PKAFFINITY Affinity -); +HalpGetRootInterruptVector( + _In_ ULONG BusInterruptLevel, + _In_ ULONG BusInterruptVector, + _Out_ PKIRQL Irql, + _Out_ PKAFFINITY Affinity); ULONG NTAPI diff --git a/hal/halx86/legacy/bus/sysbus.c b/hal/halx86/legacy/bus/sysbus.c index baaecee51e8..56d286c3464 100644 --- a/hal/halx86/legacy/bus/sysbus.c +++ b/hal/halx86/legacy/bus/sysbus.c @@ -110,35 +110,6 @@ HalpTranslateSystemBusAddress(IN PBUS_HANDLER BusHandler, return FALSE; } -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); - - /* Return the vector */ - return SystemVector; -} - ULONG NTAPI HalpGetSystemInterruptVector(IN PBUS_HANDLER BusHandler, diff --git a/hal/halx86/pic/pic.c b/hal/halx86/pic/pic.c index f46a72bc80f..e0b46ce7056 100644 --- a/hal/halx86/pic/pic.c +++ b/hal/halx86/pic/pic.c @@ -1233,6 +1233,35 @@ HalpDispatchInterrupt2(VOID) return NULL; } +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); + + /* Return the vector */ + return SystemVector; +} + #else /* _MINIHAL_ */ KIRQL