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");
}