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?rev=53673&r1=53672&r2=53673&view=diff
==============================================================================
--- 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?rev=53673&r1=53672&r2=53673&view=diff
==============================================================================
--- 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.S?rev=53673&r1=53672&r2=53673&view=diff
==============================================================================
--- 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=53673&r1=53672&r2=53673&view=diff
==============================================================================
--- 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_apic.c?rev=53673&r1=53672&r2=53673&view=diff
==============================================================================
--- 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 ([email protected])
- * UPDATE HISTORY:
- *              11/06/98: Created
+ * PROGRAMMER:    Timo Kreuzer ([email protected])
  */
 
 /* 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


Reply via email to