Merge trunk head (r43756)
[reactos.git] / reactos / hal / halx86 / mp / apic.c
index 80c1184..8c438f2 100644 (file)
@@ -68,7 +68,7 @@ typedef struct _COMMON_AREA_INFO
 #include <poppack.h>
 #endif
 
-CHAR *APstart, *APend;
+extern CHAR *APstart, *APend;
 
 #define BIOS_AREA      0x0
 #define COMMON_AREA    0x2000
@@ -223,72 +223,6 @@ VOID APICDisable(VOID)
   APICWrite(APIC_SIVR, tmp);
 }
 
-
-__inline ULONG _APICRead(ULONG Offset)
-{
-   PULONG p;
-
-   p = (PULONG)((ULONG)APICBase + Offset);
-   return *p;
-}
-
-#if 0
-__inline VOID APICWrite(ULONG Offset,
-                     ULONG Value)
-{
-   PULONG p;
-
-   p = (PULONG)((ULONG)APICBase + Offset);
-
-   *p = Value;
-}
-#else
-__inline VOID APICWrite(ULONG Offset,
-                     ULONG Value)
-{
-   PULONG p;
-   ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
-
-   lastregw[CPU] = Offset;
-   lastvalw[CPU] = Value;
-
-   p = (PULONG)((ULONG)APICBase + Offset);
-
-   *p = Value;
-}
-#endif
-
-
-#if 0
-__inline ULONG APICRead(ULONG Offset)
-{
-   PULONG p;
-
-   p = (PULONG)((ULONG)APICBase + Offset);
-   return *p;
-}
-#else
-__inline ULONG APICRead(ULONG Offset)
-{
-   PULONG p;
-   ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
-
-   lastregr[CPU] = Offset;
-   lastvalr[CPU] = 0;
-
-   p = (PULONG)((ULONG)APICBase + Offset);
-
-   lastvalr[CPU] = *p;
-   return lastvalr[CPU];
-}
-#endif
-
-__inline VOID APICSendEOI(VOID)
-{
-  // Send the EOI
-  APICWrite(APIC_EOI, 0);
-}
-
 static VOID APICDumpBit(ULONG base)
 {
        ULONG v, i, j;
@@ -316,8 +250,7 @@ VOID APICDump(VOID)
 {
   ULONG v, ver, maxlvt;
   ULONG r1, r2, w1, w2;
-  ULONG CPU = ThisCPU();;
-
+  ULONG CPU = ThisCPU();
 
 
   r1 = lastregr[CPU];
@@ -418,7 +351,8 @@ VOID APICDump(VOID)
 BOOLEAN VerifyLocalAPIC(VOID)
 {
    SIZE_T reg0, reg1;
-   ULONG l, h;
+   LARGE_INTEGER MsrValue;
+
    /* The version register is read-only in a real APIC */
    reg0 = APICRead(APIC_VER);
    DPRINT1("Getting VERSION: %x\n", reg0);
@@ -465,14 +399,14 @@ BOOLEAN VerifyLocalAPIC(VOID)
       return FALSE;
    }
 
-   Ke386Rdmsr(0x1b /*MSR_IA32_APICBASE*/, l, h);
+   MsrValue.QuadPart = __readmsr(0x1B /*MSR_IA32_APICBASE*/);
 
-   if (!(l & /*MSR_IA32_APICBASE_ENABLE*/(1<<11))) 
+   if (!(MsrValue.LowPart & /*MSR_IA32_APICBASE_ENABLE*/(1<<11))) 
    {
       DPRINT1("Local APIC disabled by BIOS -- reenabling.\n");
-      l &= ~/*MSR_IA32_APICBASE_BASE*/(1<<11);
-      l |= /*MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE*/(1<<11)|0xfee00000;
-      Ke386Wrmsr(0x1b/*MSR_IA32_APICBASE*/, l, h);
+      MsrValue.LowPart &= ~/*MSR_IA32_APICBASE_BASE*/(1<<11);
+      MsrValue.LowPart |= /*MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE*/(1<<11)|0xfee00000;
+      __writemsr(0x1B /*MSR_IA32_APICBASE*/, MsrValue.HighPart);
    }
 
     
@@ -486,7 +420,7 @@ VOID APICSendIPI(ULONG Target, ULONG Mode)
    ULONG tmp, i, flags;
 
    /* save flags and disable interrupts */
-   Ke386SaveFlags(flags);
+   flags = __readeflags();
    _disable();
 
    /* Wait up to 100ms for the APIC to become ready */
@@ -542,7 +476,7 @@ VOID APICSendIPI(ULONG Target, ULONG Mode)
    {
       DPRINT1("CPU(%d) Current IPI was not delivered after 100ms.\n", ThisCPU());
    }
-   Ke386RestoreFlags(flags);
+   __writeeflags(flags);
 }
 #endif
 
@@ -775,6 +709,9 @@ VOID
 MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
                           PKTRAP_FRAME TrapFrame)
 {
+#ifdef _M_AMD64
+    UNIMPLEMENTED;
+#else
    TrapFrame->SegGs     = (USHORT)IrqTrapFrame->Gs;
    TrapFrame->SegFs     = (USHORT)IrqTrapFrame->Fs;
    TrapFrame->SegEs     = (USHORT)IrqTrapFrame->Es;
@@ -790,6 +727,7 @@ MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
    TrapFrame->Eip    = IrqTrapFrame->Eip;
    TrapFrame->SegCs     = IrqTrapFrame->Cs;
    TrapFrame->EFlags = IrqTrapFrame->Eflags;
+#endif
 }
 
 VOID
@@ -837,12 +775,12 @@ VOID APICSetupLVTT(ULONG ClockTicks)
    tmp = GET_APIC_VERSION(APICRead(APIC_VER));
    if (!APIC_INTEGRATED(tmp))
    {
-      tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+      tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;
    }
    else
    {
       /* Periodic timer */
-      tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+      tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;
    }
    APICWrite(APIC_LVTT, tmp);
 
@@ -864,7 +802,7 @@ APICCalibrateTimer(ULONG CPU)
 
    APICSetupLVTT(1000000000);
 
-   TSCPresent = ((PKIPCR)KeGetPcr())->PrcbData.FeatureBits & KF_RDTSC ? TRUE : FALSE;
+   TSCPresent = KeGetCurrentPrcb()->FeatureBits & KF_RDTSC ? TRUE : FALSE;
 
    /*
     * The timer chip counts down to zero. Let's wait
@@ -889,11 +827,11 @@ APICCalibrateTimer(ULONG CPU)
    if (TSCPresent)
    {
       t2.QuadPart = (LONGLONG)__rdtsc();
-      CPUMap[CPU].CoreSpeed = (HZ * (t2.QuadPart - t1.QuadPart));
+      CPUMap[CPU].CoreSpeed = (HZ * (ULONG)(t2.QuadPart - t1.QuadPart));
       DPRINT("CPU clock speed is %ld.%04ld MHz.\n",
             CPUMap[CPU].CoreSpeed/1000000,
             CPUMap[CPU].CoreSpeed%1000000);
-      ((PKIPCR)KeGetPcr())->PrcbData.MHz = CPUMap[CPU].CoreSpeed/1000000;
+      KeGetCurrentPrcb()->MHz = CPUMap[CPU].CoreSpeed/1000000;
    }
 
    CPUMap[CPU].BusSpeed = (HZ * (long)(tt1 - tt2) * APIC_DIVISOR);
@@ -909,8 +847,25 @@ APICCalibrateTimer(ULONG CPU)
 }
 
 VOID 
-SetInterruptGate(ULONG index, ULONG address)
+SetInterruptGate(ULONG index, ULONG_PTR address)
 {
+#ifdef _M_AMD64
+  KIDTENTRY64 *idt;
+
+  idt = &KeGetPcr()->IdtBase[index];
+
+  idt->OffsetLow = address & 0xffff;
+  idt->Selector = KGDT_64_R0_CODE;
+  idt->IstIndex = 0;
+  idt->Reserved0 = 0;
+  idt->Type = 0x0e;
+  idt->Dpl = 0;
+  idt->Present = 1;
+  idt->OffsetMiddle = (address >> 16) & 0xffff;
+  idt->OffsetHigh = address >> 32;
+  idt->Reserved1 = 0;
+  idt->Alignment = 0;
+#else
   KIDTENTRY *idt;
   KIDT_ACCESS Access;
 
@@ -922,10 +877,11 @@ SetInterruptGate(ULONG index, ULONG address)
   Access.SegmentType = I386_INTERRUPT_GATE;
   
   idt = (KIDTENTRY*)((ULONG)KeGetPcr()->IDT + index * sizeof(KIDTENTRY));
-  idt->Offset = address & 0xffff;
+  idt->Offset = (USHORT)(address & 0xffff);
   idt->Selector = KGDT_R0_CODE;
   idt->Access = Access.Value;
-  idt->ExtendedOffset = address >> 16;
+  idt->ExtendedOffset = (USHORT)(address >> 16);
+#endif
 }
 
 VOID HaliInitBSP(VOID)
@@ -946,13 +902,13 @@ VOID HaliInitBSP(VOID)
    BSPInitialized = TRUE;
 
    /* Setup interrupt handlers */
-   SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG)MpsTimerInterrupt);
-   SetInterruptGate(ERROR_VECTOR, (ULONG)MpsErrorInterrupt);
-   SetInterruptGate(SPURIOUS_VECTOR, (ULONG)MpsSpuriousInterrupt);
+   SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG_PTR)MpsTimerInterrupt);
+   SetInterruptGate(ERROR_VECTOR, (ULONG_PTR)MpsErrorInterrupt);
+   SetInterruptGate(SPURIOUS_VECTOR, (ULONG_PTR)MpsSpuriousInterrupt);
 #ifdef CONFIG_SMP
-   SetInterruptGate(IPI_VECTOR, (ULONG)MpsIpiInterrupt);
+   SetInterruptGate(IPI_VECTOR, (ULONG_PTR)MpsIpiInterrupt);
 #endif
-   DPRINT("APIC is mapped at 0x%X\n", APICBase);
+   DPRINT1("APIC is mapped at 0x%p\n", (PVOID)APICBase);
 
    if (VerifyLocalAPIC()) 
    {
@@ -960,7 +916,7 @@ VOID HaliInitBSP(VOID)
    } 
    else 
    {
-      DPRINT("No APIC found\n");
+      DPRINT1("No APIC found\n");
       ASSERT(FALSE);
    }
 
@@ -979,18 +935,18 @@ VOID HaliInitBSP(VOID)
    CommonBase = (PULONG)COMMON_AREA;
  
    /* Copy bootstrap code to common area */
-   memcpy((PVOID)((ULONG)CommonBase + PAGE_SIZE),
+   memcpy((PVOID)((ULONG_PTR)CommonBase + PAGE_SIZE),
          &APstart,
-         (ULONG)&APend - (ULONG)&APstart + 1);
+         (ULONG_PTR)&APend - (ULONG_PTR)&APstart + 1);
 
    /* Set shutdown code */
    CMOS_WRITE(0xF, 0xA);
 
    /* Set warm reset vector */
-   ps = (PUSHORT)((ULONG)BIOSBase + 0x467);
+   ps = (PUSHORT)((ULONG_PTR)BIOSBase + 0x467);
    *ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
  
-   ps = (PUSHORT)((ULONG)BIOSBase + 0x469);
+   ps = (PUSHORT)((ULONG_PTR)BIOSBase + 0x469);
    *ps = (COMMON_AREA + PAGE_SIZE) >> 4;
 #endif