Author: tkreuzer Date: Sun Sep 11 09:34:50 2011 New Revision: 53685
URL: http://svn.reactos.org/svn/reactos?rev=53685&view=rev Log: [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!
Modified: trunk/reactos/hal/halx86/apic/apic.c trunk/reactos/hal/halx86/apic/apic.h trunk/reactos/hal/halx86/apic/rtctimer.c
Modified: trunk/reactos/hal/halx86/apic/apic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/apic.c?rev=... ============================================================================== --- trunk/reactos/hal/halx86/apic/apic.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/apic/apic.c [iso-8859-1] Sun Sep 11 09:34:50 2011 @@ -502,8 +502,11 @@ /* 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; @@ -520,37 +523,39 @@ /* Restore the old IRQL */ ApicSetCurrentIrql(OldIrql);
+ /* Exit the interrupt */ + KiEoiHelper(TrapFrame); +} + +#ifndef _M_AMD64 +VOID +DECLSPEC_NORETURN +FASTCALL +HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame) +{ + 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(); - - /* Exit the interrupt */ - KiEoiHelper(TrapFrame); -} - -#ifndef _M_AMD64 -VOID -DECLSPEC_NORETURN -FASTCALL -HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame) -{ - KIRQL OldIrql = ApicGetCurrentIrql(); - - ASSERT(OldIrql < DISPATCH_LEVEL); - ASSERT(ApicGetProcessorIrql() == DISPATCH_LEVEL); - - /* Enter trap */ - KiEnterInterruptTrap(TrapFrame); - - ApicSetCurrentIrql(DISPATCH_LEVEL);
/* 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 @@ 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); - - ReDirReg.Vector = Vector; - ReDirReg.DeliveryMode = APIC_MT_LowestPriority; - ReDirReg.DestinationMode = APIC_DM_Logical; - ReDirReg.Destination |= ApicLogicalId(Prcb->Number); - ReDirReg.TriggerMode = 1 - InterruptMode; + /* Check if its valid */ + if (Index == 0xff) + { + /* Interrupt is not in use */ + return FALSE; + } + + /* 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; }
Modified: trunk/reactos/hal/halx86/apic/apic.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/apic.h?rev=... ============================================================================== --- trunk/reactos/hal/halx86/apic/apic.h [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/apic/apic.h [iso-8859-1] Sun Sep 11 09:34:50 2011 @@ -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
Modified: trunk/reactos/hal/halx86/apic/rtctimer.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/rtctimer.c?... ============================================================================== --- trunk/reactos/hal/halx86/apic/rtctimer.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/apic/rtctimer.c [iso-8859-1] Sun Sep 11 09:34:50 2011 @@ -36,12 +36,7 @@ VOID RtcSetClockRate(UCHAR ClockRate) { - ULONG_PTR EFlags; UCHAR RegisterA; - - /* Disable interrupts */ - EFlags = __readeflags(); - _disable();
/* Update the global values */ HalpCurrentRate = ClockRate; @@ -64,9 +59,6 @@
/* Release CMOS lock */ HalpReleaseCmosSpinLock(); - - /* Restore interrupts if they were previously enabled */ - __writeeflags(EFlags); }
@@ -75,7 +67,13 @@ INIT_FUNCTION HalpInitializeClock(VOID) { + ULONG_PTR EFlags; UCHAR RegisterB; + + /* Save EFlags and disable interrupts */ + EFlags = __readeflags(); + _disable(); + // TODO: disable NMI
/* Acquire CMOS lock */ @@ -91,9 +89,13 @@ /* 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"); }