Author: tkreuzer
Date: Sat Sep 10 15:55:15 2011
New Revision: 53673
URL:
http://svn.reactos.org/svn/reactos?rev=53673&view=rev
Log:
[HAL/APIC]
- Implement HalpApcInterruptHandler, fix HalpDispatchInterruptHandler
- Insert a read to the APIC version register in ApicGetCurrentIrql(). This fixes
inconsistencies between the internal APIC state and register reads/writes.
- Remove old hacks in ApicGetCurrentIrql() and ApicSetCurrentIrql
- Fix HalpVectorToIrql()
- read/write cr8 for the value of the TPR on amd64 builds
- Fix amd64 build
Modified:
trunk/reactos/hal/halx86/amd64/halinit.c
trunk/reactos/hal/halx86/amd64/stubs.c
trunk/reactos/hal/halx86/amd64/systimer.S
trunk/reactos/hal/halx86/apic/apic.c
trunk/reactos/hal/halx86/apic/halinit_apic.c
Modified: trunk/reactos/hal/halx86/amd64/halinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/amd64/halinit.c…
==============================================================================
--- trunk/reactos/hal/halx86/amd64/halinit.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/amd64/halinit.c [iso-8859-1] Sat Sep 10 15:55:15 2011
@@ -21,6 +21,23 @@
/* FUNCTIONS *****************************************************************/
VOID
+NTAPI
+HalpInitProcessor(
+ IN ULONG ProcessorNumber,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ DPRINT1("ApicInitializeProcessor(%ld)\n", ProcessorNumber);
+
+ /* Initialize the local APIC for this cpu */
+ ApicInitializeLocalApic(ProcessorNumber);
+
+ /* Initialize the timer */
+ //ApicInitializeTimer(ProcessorNumber);
+
+}
+
+
+VOID
HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
@@ -32,18 +49,4 @@
}
-VOID
-INIT_FUNCTION
-HalpInitializeClock(VOID)
-{
-}
-VOID
-HalpCalibrateStallExecution()
-{
-}
-
-VOID
-HalpInitializePICs(IN BOOLEAN EnableInterrupts)
-{
-}
Modified: trunk/reactos/hal/halx86/amd64/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/amd64/stubs.c?r…
==============================================================================
--- trunk/reactos/hal/halx86/amd64/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/amd64/stubs.c [iso-8859-1] Sat Sep 10 15:55:15 2011
@@ -14,99 +14,8 @@
/* GLOBALS ********************************************************************/
-LARGE_INTEGER HalpPerformanceFrequency;
+//LARGE_INTEGER HalpPerformanceFrequency;
/* FUNCTIONS ******************************************************************/
-VOID
-FASTCALL
-HalClearSoftwareInterrupt(
- IN KIRQL Irql)
-{
- UNIMPLEMENTED;
-}
-
-VOID
-FASTCALL
-HalRequestSoftwareInterrupt(
- IN KIRQL Irql)
-{
- UNIMPLEMENTED;
-}
-
-BOOLEAN
-NTAPI
-HalBeginSystemInterrupt(
- IN KIRQL Irql,
- IN UCHAR Vector,
- OUT PKIRQL OldIrql)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-BOOLEAN
-NTAPI
-HalEnableSystemInterrupt(
- IN UCHAR Vector,
- IN KIRQL Irql,
- IN KINTERRUPT_MODE InterruptMode)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-VOID
-NTAPI
-HalDisableSystemInterrupt(
- IN UCHAR Vector,
- IN KIRQL Irql)
-{
- UNIMPLEMENTED;
-}
-
-VOID
-NTAPI
-HalEndSystemInterrupt(
- IN KIRQL OldIrql,
- IN PKTRAP_FRAME TrapFrame)
-{
- UNIMPLEMENTED;
-}
-
-LARGE_INTEGER
-NTAPI
-KeQueryPerformanceCounter(
- OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
-{
- LARGE_INTEGER Result;
-
-// ASSERT(HalpPerformanceFrequency.QuadPart != 0);
-
- /* Does the caller want the frequency? */
- if (PerformanceFrequency)
- {
- /* Return value */
- *PerformanceFrequency = HalpPerformanceFrequency;
- }
-
- Result.QuadPart = __rdtsc();
- return Result;
-}
-
-VOID
-NTAPI
-HalCalibratePerformanceCounter(IN volatile PLONG Count,
- IN ULONGLONG NewCount)
-{
- UNIMPLEMENTED;
-}
-
-ULONG
-NTAPI
-HalSetTimeIncrement(IN ULONG Increment)
-{
- UNIMPLEMENTED;
- return 0;
-}
Modified: trunk/reactos/hal/halx86/amd64/systimer.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/amd64/systimer.…
==============================================================================
--- trunk/reactos/hal/halx86/amd64/systimer.S [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/amd64/systimer.S [iso-8859-1] Sat Sep 10 15:55:15 2011
@@ -23,70 +23,6 @@
.code64
-PUBLIC HalpCalibrateStallExecution@0
-HalpCalibrateStallExecution@0:
-PUBLIC HalpProfileInterrupt
-HalpProfileInterrupt:
-
-
-PUBLIC KeStallExecutionProcessor
-KeStallExecutionProcessor:
-
- /* Get the number of microseconds required */
- jecxz Done
-
- /* Multiply by the stall factor */
- mov eax, gs:[PcStallScaleFactor]
- mul ecx
-
- /* Align to 16 bytes */
- .align 16
-
- /* Jump to subtraction loop */
- jmp SubtractLoop
-
- /* Align to 16 bytes */
- .align 16
-
- /* Subtract one count */
-SubtractLoop:
- sub eax, 1
- jnz SubtractLoop
-
-Done:
- /* Return */
- ret 4
-
-
-PUBLIC HalpQuery8254Counter
-HalpQuery8254Counter:
-
- /* Save EFLAGS and disable interrupts */
- pushfq
- cli
-
- /* Set timer data */
- mov al, 0
- out HEX(43), al
- jmp $+2
-
- /* Read current timer */
- in al, HEX(40)
- jmp $+2
- movzx ecx, al
- in al, HEX(40)
- mov ch, al
-
- /* Return it and restore interrupt state */
- mov eax, ecx
- popfq
- ret
-
-PUBLIC HalpClockInterrupt
-HalpClockInterrupt:
- UNIMPLEMENTED _HalpClockInterrupt
- iret
-
END
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] Sat Sep 10 15:55:15 2011
@@ -16,9 +16,11 @@
#include <debug.h>
#include "apic.h"
+void HackEoi(void);
/* GLOBALS ********************************************************************/
+ULONG ApicVersion;
UCHAR HalpVectorToIndex[256];
#ifndef _M_AMD64
@@ -101,6 +103,14 @@
*(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN) = Value;
}
+VOID
+FORCEINLINE
+ApicSendEOI(void)
+{
+ //ApicWrite(APIC_EOI, 0);
+ HackEoi();
+}
+
KIRQL
FORCEINLINE
ApicGetProcessorIrql(VOID)
@@ -113,24 +123,27 @@
FORCEINLINE
ApicGetCurrentIrql(VOID)
{
- // HACK: This won't work with amd64, where cr8 is modified directly, but
- // VBox is broken and returns a wrong value when using a vmmcall after a
- // page table modification.
- return KeGetPcr()->Irql;
+#ifdef _M_AMD64
+ return (KIRQL)__readcr8();
+#else
+ // HACK: some magic to Sync VBox's APIC registers
+ ApicRead(APIC_VER);
/* Read the TPR and convert it to an IRQL */
return TprToIrql(ApicRead(APIC_TPR));
+#endif
}
VOID
FORCEINLINE
ApicSetCurrentIrql(KIRQL Irql)
{
+#ifdef _M_AMD64
+ __writecr8(Irql);
+#else
/* Convert IRQL and write the TPR */
ApicWrite(APIC_TPR, IrqlToTpr(Irql));
-
- /* HACK: Keep PCR field in sync, s.a. */
- KeGetPcr()->Irql = Irql;
+#endif
}
UCHAR
@@ -150,7 +163,7 @@
FASTCALL
HalpVectorToIrql(UCHAR Vector)
{
- return TprToIrql(Vector >> 2);
+ return TprToIrql(Vector);
}
UCHAR
@@ -248,6 +261,9 @@
SpIntRegister.SoftwareEnable = 1;
SpIntRegister.FocusCPUCoreChecking = 0;
ApicWrite(APIC_SIVR, SpIntRegister.Long);
+
+ /* Read the version and save it globally */
+ if (Cpu == 0) ApicVersion = ApicRead(APIC_VER);
/* Set the mode to flat (max 8 CPUs supported!) */
ApicWrite(APIC_DFR, APIC_DF_Flat);
@@ -430,6 +446,7 @@
ReDirReg.Destination = ApicRead(APIC_ID);
IOApicWrite(IOAPIC_REDTBL + 2 * APIC_CLOCK_INDEX, ReDirReg.Long0);
+ ApicSendEOI();
}
VOID
@@ -447,14 +464,22 @@
/* Initialize the I/O APIC */
ApicInitializeIOApic();
- ApicWrite(APIC_EOI, 0);
-
- /* Register interrupt handlers */
+
+ /* Manually reserve some vectors */
+ HalpVectorToIndex[APIC_CLOCK_VECTOR] = 8;
+ HalpVectorToIndex[APC_VECTOR] = 99;
+ HalpVectorToIndex[DISPATCH_VECTOR] = 99;
+
+ /* Set interrupt handlers in the IDT */
KeRegisterInterruptHandler(APIC_CLOCK_VECTOR, HalpClockInterrupt);
#ifndef _M_AMD64
KeRegisterInterruptHandler(APC_VECTOR, HalpApcInterrupt);
- KeRegisterInterruptHandler(DPC_VECTOR, HalpDispatchInterrupt);
+ KeRegisterInterruptHandler(DISPATCH_VECTOR, HalpDispatchInterrupt);
#endif
+
+ /* Register the vectors for APC and dispatch interrupts */
+ HalpRegisterVector(IDT_INTERNAL, 0, APC_VECTOR, APC_LEVEL);
+ HalpRegisterVector(IDT_INTERNAL, 0, DISPATCH_VECTOR, DISPATCH_LEVEL);
/* Restore interrupt state */
if (EnableInterrupts) EFlags |= EFLAGS_INTERRUPT_MASK;
@@ -466,11 +491,40 @@
FASTCALL
HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
+ KPROCESSOR_MODE ProcessorMode;
+ KIRQL OldIrql;
ASSERT(ApicGetCurrentIrql() < APC_LEVEL);
ASSERT(ApicGetProcessorIrql() == APC_LEVEL);
- UNIMPLEMENTED;
- ASSERT(FALSE);
+ /* Enter trap */
+ KiEnterInterruptTrap(TrapFrame);
+
+ /* Save the old IRQL */
+ OldIrql = ApicGetCurrentIrql();
+
+ /* Set APC_LEVEL */
+ ApicSetCurrentIrql(APC_LEVEL);
+
+ /* Kernel or user APC? */
+ if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
+ else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
+ else ProcessorMode = KernelMode;
+
+ /* Enable interrupts and call the kernel's APC interrupt handler */
+ _enable();
+ KiDeliverApc(ProcessorMode, NULL, TrapFrame);
+
+ /* Disable interrupts */
+ _disable();
+
+ /* Restore the old IRQL */
+ ApicSetCurrentIrql(OldIrql);
+
+ /* End the interrupt */
+ ApicSendEOI();
+
+ /* Exit the interrupt */
+ KiEoiHelper(TrapFrame);
}
#ifndef _M_AMD64
@@ -480,9 +534,12 @@
HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
KIRQL OldIrql = ApicGetCurrentIrql();
-__debugbreak();
+
ASSERT(OldIrql < DISPATCH_LEVEL);
ASSERT(ApicGetProcessorIrql() == DISPATCH_LEVEL);
+
+ /* Enter trap */
+ KiEnterInterruptTrap(TrapFrame);
ApicSetCurrentIrql(DISPATCH_LEVEL);
@@ -493,12 +550,19 @@
ApicSetCurrentIrql(OldIrql);
- ApicWrite(APIC_EOI, 0);
+ ApicSendEOI();
/* Exit the interrupt */
KiEoiHelper(TrapFrame);
}
#endif
+
+VOID
+NTAPI
+HalpSendEOI(VOID)
+{
+ ApicSendEOI();
+}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -580,14 +644,6 @@
IOApicWrite(IOAPIC_REDTBL + 2 * Irql, ReDirReg.Long0);
}
-VOID
-NTAPI
-HalpSendEOI(VOID)
-{
- /* Write 0 to the EndOfInterruptRegister */
- ApicWrite(APIC_EOI, 0);
-}
-
#ifndef _M_AMD64
BOOLEAN
NTAPI
@@ -609,19 +665,14 @@
return TRUE;
}
-void HackEoi(void);
-
VOID
NTAPI
HalEndSystemInterrupt(
IN KIRQL OldIrql,
IN PKTRAP_FRAME TrapFrame)
{
- /* Write 0 to the EndOfInterruptRegister */
- //ApicWrite(APIC_EOI, 0);
-
- // HACK!
- HackEoi();
+ /* Send an EOI */
+ ApicSendEOI();
/* Restore the old IRQL */
ApicSetCurrentIrql(OldIrql);
Modified: trunk/reactos/hal/halx86/apic/halinit_apic.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/halinit_ap…
==============================================================================
--- trunk/reactos/hal/halx86/apic/halinit_apic.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/apic/halinit_apic.c [iso-8859-1] Sat Sep 10 15:55:15 2011
@@ -4,9 +4,7 @@
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/halinit.c
* PURPOSE: Initalize the x86 hal
- * PROGRAMMER: David Welch (welch(a)cwcom.net)
- * UPDATE HISTORY:
- * 11/06/98: Created
+ * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
*/
/* INCLUDES *****************************************************************/
@@ -14,12 +12,17 @@
#include <hal.h>
#define NDEBUG
#include <debug.h>
+#include "apic.h"
VOID
NTAPI
ApicInitializeLocalApic(ULONG Cpu);
-/* FUNCTIONS ***************************************************************/
+/* GLOBALS ******************************************************************/
+
+const USHORT HalpBuildType = HAL_BUILD_TYPE;
+
+/* FUNCTIONS ****************************************************************/
VOID
NTAPI
@@ -39,6 +42,13 @@
HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
+ /* Enable clock interrupt handler */
+ HalpEnableInterruptHandler(IDT_INTERNAL,
+ 0,
+ APIC_CLOCK_VECTOR,
+ CLOCK2_LEVEL,
+ HalpClockInterrupt,
+ Latched);
}
VOID