From 1b9f1974ad3dc8e014a9c9a565910d875710c764 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 11 Sep 2011 09:34:50 +0000 Subject: [PATCH] [HAL] - End the interrupt in HalpApcInterruptHandler and HalpDispatchInterruptHandler before calling the kernel, otherwise we would be stuck at high processor irql - Improve HalEnableSystemInterrupt - disable interrupts in HalpInitializeClock => APIC hal boots to desktop! svn path=/trunk/; revision=53685 --- reactos/hal/halx86/apic/apic.c | 62 +++++++++++++++++++++--------- reactos/hal/halx86/apic/apic.h | 4 +- reactos/hal/halx86/apic/rtctimer.c | 18 +++++---- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/reactos/hal/halx86/apic/apic.c b/reactos/hal/halx86/apic/apic.c index ff51e742dab..339cfa3c2d2 100644 --- a/reactos/hal/halx86/apic/apic.c +++ b/reactos/hal/halx86/apic/apic.c @@ -502,9 +502,12 @@ HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame) /* Save the old IRQL */ OldIrql = ApicGetCurrentIrql(); - /* Set APC_LEVEL */ + /* Raise to APC_LEVEL */ ApicSetCurrentIrql(APC_LEVEL); + /* End the interrupt */ + ApicSendEOI(); + /* Kernel or user APC? */ if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode; else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode; @@ -520,9 +523,6 @@ HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame) /* Restore the old IRQL */ ApicSetCurrentIrql(OldIrql); - /* End the interrupt */ - ApicSendEOI(); - /* Exit the interrupt */ KiEoiHelper(TrapFrame); } @@ -533,25 +533,30 @@ DECLSPEC_NORETURN FASTCALL HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame) { - KIRQL OldIrql = ApicGetCurrentIrql(); - - ASSERT(OldIrql < DISPATCH_LEVEL); + KIRQL OldIrql; + ASSERT(ApicGetCurrentIrql() < DISPATCH_LEVEL); ASSERT(ApicGetProcessorIrql() == DISPATCH_LEVEL); /* Enter trap */ KiEnterInterruptTrap(TrapFrame); + /* Save the old IRQL */ + OldIrql = ApicGetCurrentIrql(); + + /* Raise to DISPATCH_LEVEL */ ApicSetCurrentIrql(DISPATCH_LEVEL); + /* End the interrupt */ + ApicSendEOI(); + /* Enable interrupts and call the kernel's DPC interrupt handler */ _enable(); KiDispatchInterrupt(); _disable(); + /* Restore the old IRQL */ ApicSetCurrentIrql(OldIrql); - ApicSendEOI(); - /* Exit the interrupt */ KiEoiHelper(TrapFrame); } @@ -604,20 +609,41 @@ HalEnableSystemInterrupt( ASSERT(Irql <= HIGH_LEVEL); ASSERT((IrqlToTpr(Irql) & 0xF0) == (Vector & 0xF0)); + /* Get the irq for this vector */ Index = HalpVectorToIndex[Vector]; - /* Read lower dword of redirection entry */ - ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index); + /* Check if its valid */ + if (Index == 0xff) + { + /* Interrupt is not in use */ + return FALSE; + } - ReDirReg.Vector = Vector; - ReDirReg.DeliveryMode = APIC_MT_LowestPriority; - ReDirReg.DestinationMode = APIC_DM_Logical; - ReDirReg.Destination |= ApicLogicalId(Prcb->Number); - ReDirReg.TriggerMode = 1 - InterruptMode; + /* Read the redirection entry */ + ReDirReg = ApicReadIORedirectionEntry(Index); + + /* Check if the interrupt was unused */ + if (ReDirReg.Vector != Vector) + { + ReDirReg.Vector = Vector; + ReDirReg.DeliveryMode = APIC_MT_LowestPriority; + ReDirReg.DestinationMode = APIC_DM_Logical; + ReDirReg.Destination = 0; + ReDirReg.TriggerMode = 1 - InterruptMode; + } + + /* Check if the destination is logical */ + if (ReDirReg.DestinationMode = APIC_DM_Logical) + { + /* Set the bit for this cpu */ + ReDirReg.Destination |= ApicLogicalId(Prcb->Number); + } + + /* Now unmask it */ ReDirReg.Mask = FALSE; - /* Write back lower dword */ - IOApicWrite(IOAPIC_REDTBL + 2 * Irql, ReDirReg.Long0); + /* Write back the entry */ + ApicWriteIORedirectionEntry(Index, ReDirReg); return TRUE; } diff --git a/reactos/hal/halx86/apic/apic.h b/reactos/hal/halx86/apic/apic.h index c6a43e0c38e..7657e6a8f9e 100644 --- a/reactos/hal/halx86/apic/apic.h +++ b/reactos/hal/halx86/apic/apic.h @@ -5,7 +5,7 @@ #define ZERO_VECTOR 0x00 // IRQL 00 #define APC_VECTOR 0x3D // IRQL 01 #define APIC_SPURIOUS_VECTOR 0x3f -#define DPC_VECTOR 0x41 // IRQL 02 +#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 @@ -22,7 +22,7 @@ #define ZERO_VECTOR 0x00 // IRQL 00 #define APIC_SPURIOUS_VECTOR 0x1f #define APC_VECTOR 0x3D // IRQL 01 -#define DPC_VECTOR 0x41 // IRQL 02 +#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 diff --git a/reactos/hal/halx86/apic/rtctimer.c b/reactos/hal/halx86/apic/rtctimer.c index 31296530590..9fe1e5d0faa 100644 --- a/reactos/hal/halx86/apic/rtctimer.c +++ b/reactos/hal/halx86/apic/rtctimer.c @@ -36,13 +36,8 @@ RtcClockRateToIncrement(UCHAR Rate) VOID RtcSetClockRate(UCHAR ClockRate) { - ULONG_PTR EFlags; UCHAR RegisterA; - /* Disable interrupts */ - EFlags = __readeflags(); - _disable(); - /* Update the global values */ HalpCurrentRate = ClockRate; HalpCurrentTimeIncrement = RtcClockRateToIncrement(ClockRate); @@ -64,9 +59,6 @@ RtcSetClockRate(UCHAR ClockRate) /* Release CMOS lock */ HalpReleaseCmosSpinLock(); - - /* Restore interrupts if they were previously enabled */ - __writeeflags(EFlags); } @@ -75,7 +67,13 @@ NTAPI INIT_FUNCTION HalpInitializeClock(VOID) { + ULONG_PTR EFlags; UCHAR RegisterB; + + /* Save EFlags and disable interrupts */ + EFlags = __readeflags(); + _disable(); + // TODO: disable NMI /* Acquire CMOS lock */ @@ -91,10 +89,14 @@ HalpInitializeClock(VOID) /* Set initial rate */ RtcSetClockRate(HalpCurrentRate); + /* Restore interrupt state */ + __writeeflags(EFlags); + /* Notify the kernel about the maximum and minimum increment */ KeSetTimeIncrement(RtcClockRateToIncrement(RtcMaximumClockRate), RtcClockRateToIncrement(RtcMinimumClockRate)); + DPRINT1("Clock initialized\n"); }