mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[HAL:APIC] Code fixes
* Fix some broken code * Add some ASSERTs * Use ApicWriteIORedirectionEntry where appropriate * Use KeQueryInterruptHandler/KeRegisterInterruptHandler to save/restore the old handler instead of saving the KIDTENTRY * Move HalpProfileInterruptHandler to apictimer.c and implement it * Use READ/WRITE_REGISTER macros * Add some symbolic names
This commit is contained in:
parent
ee514e954b
commit
b7a149fcec
5 changed files with 40 additions and 32 deletions
|
@ -94,8 +94,9 @@ ULONG
|
|||
IOApicRead(UCHAR Register)
|
||||
{
|
||||
/* Select the register, then do the read */
|
||||
*(volatile UCHAR *)(IOAPIC_BASE + IOAPIC_IOREGSEL) = Register;
|
||||
return *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN);
|
||||
ASSERT(Register <= 0x3F);
|
||||
WRITE_REGISTER_ULONG((PULONG)(IOAPIC_BASE + IOAPIC_IOREGSEL), Register);
|
||||
return READ_REGISTER_ULONG((PULONG)(IOAPIC_BASE + IOAPIC_IOWIN));
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
|
@ -103,8 +104,9 @@ VOID
|
|||
IOApicWrite(UCHAR Register, ULONG Value)
|
||||
{
|
||||
/* Select the register, then do the write */
|
||||
*(volatile UCHAR *)(IOAPIC_BASE + IOAPIC_IOREGSEL) = Register;
|
||||
*(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN) = Value;
|
||||
ASSERT(Register <= 0x3F);
|
||||
WRITE_REGISTER_ULONG((PULONG)(IOAPIC_BASE + IOAPIC_IOREGSEL), Register);
|
||||
WRITE_REGISTER_ULONG((PULONG)(IOAPIC_BASE + IOAPIC_IOWIN), Value);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
|
@ -113,6 +115,7 @@ ApicWriteIORedirectionEntry(
|
|||
UCHAR Index,
|
||||
IOAPIC_REDIRECTION_REGISTER ReDirReg)
|
||||
{
|
||||
ASSERT(Index < APIC_MAX_IRQ);
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * Index + 1, ReDirReg.Long1);
|
||||
}
|
||||
|
@ -124,6 +127,7 @@ ApicReadIORedirectionEntry(
|
|||
{
|
||||
IOAPIC_REDIRECTION_REGISTER ReDirReg;
|
||||
|
||||
ASSERT(Index < APIC_MAX_IRQ);
|
||||
ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index);
|
||||
ReDirReg.Long1 = IOApicRead(IOAPIC_REDTBL + 2 * Index + 1);
|
||||
|
||||
|
@ -344,7 +348,7 @@ HalpAllocateSystemInterrupt(
|
|||
Vector = IrqlToTpr(Irql) & 0xF0;
|
||||
|
||||
/* Find an empty vector */
|
||||
while (HalpVectorToIndex[Vector] != 0xFF)
|
||||
while (HalpVectorToIndex[Vector] != APIC_FREE_VECTOR)
|
||||
{
|
||||
Vector++;
|
||||
|
||||
|
@ -372,8 +376,7 @@ HalpAllocateSystemInterrupt(
|
|||
ReDirReg.Destination = 0;
|
||||
|
||||
/* Initialize entry */
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * Irq, ReDirReg.Long0);
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * Irq + 1, ReDirReg.Long1);
|
||||
ApicWriteIORedirectionEntry(Irq, ReDirReg);
|
||||
|
||||
return Vector;
|
||||
}
|
||||
|
@ -410,17 +413,16 @@ ApicInitializeIOApic(VOID)
|
|||
ReDirReg.Destination = 0;
|
||||
|
||||
/* Loop all table entries */
|
||||
for (Index = 0; Index < 24; Index++)
|
||||
for (Index = 0; Index < APIC_MAX_IRQ; Index++)
|
||||
{
|
||||
/* Initialize entry */
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * Index + 1, ReDirReg.Long1);
|
||||
ApicWriteIORedirectionEntry(Index, ReDirReg);
|
||||
}
|
||||
|
||||
/* Init the vactor to index table */
|
||||
for (Vector = 0; Vector <= 255; Vector++)
|
||||
{
|
||||
HalpVectorToIndex[Vector] = 0xFF;
|
||||
HalpVectorToIndex[Vector] = APIC_FREE_VECTOR;
|
||||
}
|
||||
|
||||
// HACK: Allocate all IRQs, should rather do that on demand
|
||||
|
@ -437,7 +439,7 @@ ApicInitializeIOApic(VOID)
|
|||
ReDirReg.TriggerMode = APIC_TGM_Edge;
|
||||
ReDirReg.Mask = 0;
|
||||
ReDirReg.Destination = ApicRead(APIC_ID);
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * APIC_CLOCK_INDEX, ReDirReg.Long0);
|
||||
ApicWriteIORedirectionEntry(APIC_CLOCK_INDEX, ReDirReg);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -457,9 +459,10 @@ HalpInitializePICs(IN BOOLEAN EnableInterrupts)
|
|||
ApicInitializeIOApic();
|
||||
|
||||
/* Manually reserve some vectors */
|
||||
HalpVectorToIndex[APC_VECTOR] = APIC_RESERVED_VECTOR;
|
||||
HalpVectorToIndex[DISPATCH_VECTOR] = APIC_RESERVED_VECTOR;
|
||||
HalpVectorToIndex[APIC_CLOCK_VECTOR] = 8;
|
||||
HalpVectorToIndex[APC_VECTOR] = 99;
|
||||
HalpVectorToIndex[DISPATCH_VECTOR] = 99;
|
||||
HalpVectorToIndex[APIC_SPURIOUS_VECTOR] = APIC_RESERVED_VECTOR;
|
||||
|
||||
/* Set interrupt handlers in the IDT */
|
||||
KeRegisterInterruptHandler(APIC_CLOCK_VECTOR, HalpClockInterrupt);
|
||||
|
@ -669,7 +672,7 @@ HalDisableSystemInterrupt(
|
|||
ReDirReg.Mask = 1;
|
||||
|
||||
/* Write back lower dword */
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * Irql, ReDirReg.Long0);
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
|
||||
}
|
||||
|
||||
#ifndef _M_AMD64
|
||||
|
@ -704,8 +707,8 @@ HalBeginSystemInterrupt(
|
|||
/* Get the irq for this vector */
|
||||
Index = HalpVectorToIndex[Vector];
|
||||
|
||||
/* Check if its valid */
|
||||
if (Index != 0xff)
|
||||
/* Check if it's valid */
|
||||
if (Index < APIC_MAX_IRQ)
|
||||
{
|
||||
/* Read the I/O redirection entry */
|
||||
RedirReg = ApicReadIORedirectionEntry(Index);
|
||||
|
@ -715,6 +718,9 @@ HalBeginSystemInterrupt(
|
|||
}
|
||||
else
|
||||
{
|
||||
/* This should be a reserved vector! */
|
||||
ASSERT(Index == APIC_RESERVED_VECTOR);
|
||||
|
||||
/* Re-request the interrupt to be handled later */
|
||||
ApicRequestInterrupt(Vector, APIC_TGM_Edge);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
#define TprToIrql(Tpr) (HalVectorToIRQL[Tpr >> 4])
|
||||
#endif
|
||||
|
||||
#define APIC_MAX_IRQ 24
|
||||
#define APIC_FREE_VECTOR 0xFF
|
||||
#define APIC_RESERVED_VECTOR 0xFE
|
||||
|
||||
/* The IMCR is supported by two read/writable or write-only I/O ports,
|
||||
22h and 23h, which receive address and data respectively.
|
||||
To access the IMCR, write a value of 70h to I/O port 22h, which selects the IMCR.
|
||||
|
@ -284,14 +288,14 @@ FORCEINLINE
|
|||
ULONG
|
||||
ApicRead(ULONG Offset)
|
||||
{
|
||||
return *(volatile ULONG *)(APIC_BASE + Offset);
|
||||
return READ_REGISTER_ULONG((PULONG)(APIC_BASE + Offset));
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ApicWrite(ULONG Offset, ULONG Value)
|
||||
{
|
||||
*(volatile ULONG *)(APIC_BASE + Offset) = Value;
|
||||
WRITE_REGISTER_ULONG((PULONG)(APIC_BASE + Offset), Value);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
|
@ -61,6 +61,13 @@ ApicInitializeTimer(ULONG Cpu)
|
|||
// KeSetTimeIncrement
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
HalpProfileInterruptHandler(_In_ PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
KeProfileInterruptWithSource(TrapFrame, ProfileTime);
|
||||
}
|
||||
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
|
|
|
@ -167,13 +167,6 @@ HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
KeUpdateSystemTime(TrapFrame, LastIncrement, Irql);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
HalSetTimeIncrement(IN ULONG Increment)
|
||||
|
|
|
@ -55,8 +55,7 @@ NTAPI
|
|||
HalpInitializeTsc(VOID)
|
||||
{
|
||||
ULONG_PTR Flags;
|
||||
KIDTENTRY OldIdtEntry, *IdtPointer;
|
||||
PKPCR Pcr = KeGetPcr();
|
||||
PVOID PreviousHandler;
|
||||
UCHAR RegisterA, RegisterB;
|
||||
|
||||
/* Check if the CPU supports RDTSC */
|
||||
|
@ -79,8 +78,7 @@ HalpInitializeTsc(VOID)
|
|||
HalpWriteCmos(RTC_REGISTER_A, RegisterA);
|
||||
|
||||
/* Save old IDT entry */
|
||||
IdtPointer = KiGetIdtEntry(Pcr, HalpRtcClockVector);
|
||||
OldIdtEntry = *IdtPointer;
|
||||
PreviousHandler = KeQueryInterruptHandler(HalpRtcClockVector);
|
||||
|
||||
/* Set the calibration ISR */
|
||||
KeRegisterInterruptHandler(HalpRtcClockVector, TscCalibrationISR);
|
||||
|
@ -105,8 +103,8 @@ HalpInitializeTsc(VOID)
|
|||
/* Disable the timer interrupt */
|
||||
HalDisableSystemInterrupt(HalpRtcClockVector, CLOCK_LEVEL);
|
||||
|
||||
/* Restore old IDT entry */
|
||||
*IdtPointer = OldIdtEntry;
|
||||
/* Restore the previous handler */
|
||||
KeRegisterInterruptHandler(HalpRtcClockVector, PreviousHandler);
|
||||
|
||||
/* Calculate an average, using simplified linear regression */
|
||||
HalpCpuClockFrequency.QuadPart = DoLinearRegression(NUM_SAMPLES - 1,
|
||||
|
|
Loading…
Reference in a new issue