- 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
This commit is contained in:
Timo Kreuzer 2011-09-11 09:34:50 +00:00
parent 2aa7014184
commit 1b9f1974ad
3 changed files with 56 additions and 28 deletions

View file

@ -502,9 +502,12 @@ HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
/* Save the old IRQL */ /* Save the old IRQL */
OldIrql = ApicGetCurrentIrql(); OldIrql = ApicGetCurrentIrql();
/* Set APC_LEVEL */ /* Raise to APC_LEVEL */
ApicSetCurrentIrql(APC_LEVEL); ApicSetCurrentIrql(APC_LEVEL);
/* End the interrupt */
ApicSendEOI();
/* Kernel or user APC? */ /* Kernel or user APC? */
if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode; if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode; else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
@ -520,9 +523,6 @@ HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
/* Restore the old IRQL */ /* Restore the old IRQL */
ApicSetCurrentIrql(OldIrql); ApicSetCurrentIrql(OldIrql);
/* End the interrupt */
ApicSendEOI();
/* Exit the interrupt */ /* Exit the interrupt */
KiEoiHelper(TrapFrame); KiEoiHelper(TrapFrame);
} }
@ -533,25 +533,30 @@ DECLSPEC_NORETURN
FASTCALL FASTCALL
HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame) HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{ {
KIRQL OldIrql = ApicGetCurrentIrql(); KIRQL OldIrql;
ASSERT(ApicGetCurrentIrql() < DISPATCH_LEVEL);
ASSERT(OldIrql < DISPATCH_LEVEL);
ASSERT(ApicGetProcessorIrql() == DISPATCH_LEVEL); ASSERT(ApicGetProcessorIrql() == DISPATCH_LEVEL);
/* Enter trap */ /* Enter trap */
KiEnterInterruptTrap(TrapFrame); KiEnterInterruptTrap(TrapFrame);
/* Save the old IRQL */
OldIrql = ApicGetCurrentIrql();
/* Raise to DISPATCH_LEVEL */
ApicSetCurrentIrql(DISPATCH_LEVEL); ApicSetCurrentIrql(DISPATCH_LEVEL);
/* End the interrupt */
ApicSendEOI();
/* Enable interrupts and call the kernel's DPC interrupt handler */ /* Enable interrupts and call the kernel's DPC interrupt handler */
_enable(); _enable();
KiDispatchInterrupt(); KiDispatchInterrupt();
_disable(); _disable();
/* Restore the old IRQL */
ApicSetCurrentIrql(OldIrql); ApicSetCurrentIrql(OldIrql);
ApicSendEOI();
/* Exit the interrupt */ /* Exit the interrupt */
KiEoiHelper(TrapFrame); KiEoiHelper(TrapFrame);
} }
@ -604,20 +609,41 @@ HalEnableSystemInterrupt(
ASSERT(Irql <= HIGH_LEVEL); ASSERT(Irql <= HIGH_LEVEL);
ASSERT((IrqlToTpr(Irql) & 0xF0) == (Vector & 0xF0)); ASSERT((IrqlToTpr(Irql) & 0xF0) == (Vector & 0xF0));
/* Get the irq for this vector */
Index = HalpVectorToIndex[Vector]; Index = HalpVectorToIndex[Vector];
/* Read lower dword of redirection entry */ /* Check if its valid */
ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index); if (Index == 0xff)
{
/* Interrupt is not in use */
return FALSE;
}
ReDirReg.Vector = Vector; /* Read the redirection entry */
ReDirReg.DeliveryMode = APIC_MT_LowestPriority; ReDirReg = ApicReadIORedirectionEntry(Index);
ReDirReg.DestinationMode = APIC_DM_Logical;
ReDirReg.Destination |= ApicLogicalId(Prcb->Number); /* Check if the interrupt was unused */
ReDirReg.TriggerMode = 1 - InterruptMode; 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; ReDirReg.Mask = FALSE;
/* Write back lower dword */ /* Write back the entry */
IOApicWrite(IOAPIC_REDTBL + 2 * Irql, ReDirReg.Long0); ApicWriteIORedirectionEntry(Index, ReDirReg);
return TRUE; return TRUE;
} }

View file

@ -5,7 +5,7 @@
#define ZERO_VECTOR 0x00 // IRQL 00 #define ZERO_VECTOR 0x00 // IRQL 00
#define APC_VECTOR 0x3D // IRQL 01 #define APC_VECTOR 0x3D // IRQL 01
#define APIC_SPURIOUS_VECTOR 0x3f #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_GENERIC_VECTOR 0xC1 // IRQL 27
#define APIC_CLOCK_VECTOR 0xD1 // IRQL 28 #define APIC_CLOCK_VECTOR 0xD1 // IRQL 28
#define APIC_SYNCH_VECTOR 0xD1 // IRQL 28 #define APIC_SYNCH_VECTOR 0xD1 // IRQL 28
@ -22,7 +22,7 @@
#define ZERO_VECTOR 0x00 // IRQL 00 #define ZERO_VECTOR 0x00 // IRQL 00
#define APIC_SPURIOUS_VECTOR 0x1f #define APIC_SPURIOUS_VECTOR 0x1f
#define APC_VECTOR 0x3D // IRQL 01 #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_GENERIC_VECTOR 0xC1 // IRQL 27
#define APIC_CLOCK_VECTOR 0xD1 // IRQL 28 #define APIC_CLOCK_VECTOR 0xD1 // IRQL 28
#define APIC_SYNCH_VECTOR 0xD1 // IRQL 28 #define APIC_SYNCH_VECTOR 0xD1 // IRQL 28

View file

@ -36,13 +36,8 @@ RtcClockRateToIncrement(UCHAR Rate)
VOID VOID
RtcSetClockRate(UCHAR ClockRate) RtcSetClockRate(UCHAR ClockRate)
{ {
ULONG_PTR EFlags;
UCHAR RegisterA; UCHAR RegisterA;
/* Disable interrupts */
EFlags = __readeflags();
_disable();
/* Update the global values */ /* Update the global values */
HalpCurrentRate = ClockRate; HalpCurrentRate = ClockRate;
HalpCurrentTimeIncrement = RtcClockRateToIncrement(ClockRate); HalpCurrentTimeIncrement = RtcClockRateToIncrement(ClockRate);
@ -64,9 +59,6 @@ RtcSetClockRate(UCHAR ClockRate)
/* Release CMOS lock */ /* Release CMOS lock */
HalpReleaseCmosSpinLock(); HalpReleaseCmosSpinLock();
/* Restore interrupts if they were previously enabled */
__writeeflags(EFlags);
} }
@ -75,7 +67,13 @@ NTAPI
INIT_FUNCTION INIT_FUNCTION
HalpInitializeClock(VOID) HalpInitializeClock(VOID)
{ {
ULONG_PTR EFlags;
UCHAR RegisterB; UCHAR RegisterB;
/* Save EFlags and disable interrupts */
EFlags = __readeflags();
_disable();
// TODO: disable NMI // TODO: disable NMI
/* Acquire CMOS lock */ /* Acquire CMOS lock */
@ -91,10 +89,14 @@ HalpInitializeClock(VOID)
/* Set initial rate */ /* Set initial rate */
RtcSetClockRate(HalpCurrentRate); RtcSetClockRate(HalpCurrentRate);
/* Restore interrupt state */
__writeeflags(EFlags);
/* Notify the kernel about the maximum and minimum increment */ /* Notify the kernel about the maximum and minimum increment */
KeSetTimeIncrement(RtcClockRateToIncrement(RtcMaximumClockRate), KeSetTimeIncrement(RtcClockRateToIncrement(RtcMaximumClockRate),
RtcClockRateToIncrement(RtcMinimumClockRate)); RtcClockRateToIncrement(RtcMinimumClockRate));
DPRINT1("Clock initialized\n"); DPRINT1("Clock initialized\n");
} }