mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:25:52 +00:00
[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
This commit is contained in:
parent
2aa7014184
commit
1b9f1974ad
3 changed files with 56 additions and 28 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue