- 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 */
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;
}

View file

@ -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

View file

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