[HALX86] Disable Lazy IRQL in APIC HAL (#3609)
authorJustin Miller <justinmiller100@gmail.com>
Tue, 4 May 2021 01:29:50 +0000 (18:29 -0700)
committerGitHub <noreply@github.com>
Tue, 4 May 2021 01:29:50 +0000 (04:29 +0300)
Lazy IRQL feature has issues with interrupt delivery on VirtualBox, so disable it for now.
For the feature description, see commit d28eae967a04320931241f06c88c801aa86397bd

Meanwhile, merge and clean up APIC headers a bit

hal/halx86/CMakeLists.txt
hal/halx86/apic/apic.c
hal/halx86/apic/apic.h [deleted file]
hal/halx86/apic/apictimer.c
hal/halx86/apic/halaacpi.rc [new file with mode: 0644]
hal/halx86/apic/halinit.c
hal/halx86/apic/tsc.c
hal/halx86/include/apic.h
hal/halx86/smp/halmacpi.rc [new file with mode: 0644]

index abb3c1d..0b1b18b 100644 (file)
@@ -60,14 +60,11 @@ if(ARCH STREQUAL "i386")
     # hal
     add_hal(hal SOURCES pic/halpic.rc COMPONENTS generic legacy up pic)
     add_hal(halacpi SOURCES acpi/halacpi.rc COMPONENTS generic acpi up pic)
-    add_hal(halaacpi SOURCES acpi/halacpi.rc COMPONENTS generic acpi up apic)
+    add_hal(halaacpi SOURCES apic/halaacpi.rc COMPONENTS generic acpi up apic)
     add_hal(halxbox SOURCES xbox/halxbox.rc COMPONENTS xbox up)
     add_hal(halpc98 SOURCES pc98/halpc98.rc COMPONENTS pc98 up)
 
-    #add_hal(halmps SOURCES up/halup.rc COMPONENTS generic legacy smp pic)
     #add_hal(halmacpi SOURCES acpi/halacpi.rc COMPONENTS generic acpi smp pic)
-    #add_hal(halmapic SOURCES acpi/halacpi.rc COMPONENTS generic legacy smp apic)
-    #add_hal(halmaacpi SOURCES acpi/halacpi.rc COMPONENTS generic acpi smp apic)
 
 elseif(ARCH STREQUAL "amd64")
 
@@ -75,6 +72,7 @@ elseif(ARCH STREQUAL "amd64")
         amd64/x86bios.c)
 
     add_hal(hal SOURCES ${HAL_SOURCE} COMPONENTS generic acpi up apic)
+    #add_hal(halmacpi SOURCES acpi/halacpi.rc COMPONENTS generic acpi smp pic)
     target_link_libraries(hal fast486)
 
 endif()
index 54dbbf0..4c98e13 100644 (file)
 /* INCLUDES *******************************************************************/
 
 #include <hal.h>
+#include <apic.h>
 #define NDEBUG
 #include <debug.h>
 
-#include "apic.h"
 void __cdecl HackEoi(void);
 
 #ifndef _M_AMD64
-#define APIC_LAZY_IRQL
+//#define APIC_LAZY_IRQL //FIXME: Disabled due to bug.
 #endif
 
 /* GLOBALS ********************************************************************/
@@ -263,10 +263,10 @@ ApicInitializeLocalApic(ULONG Cpu)
     LVT_REGISTER LvtEntry;
 
     /* Enable the APIC if it wasn't yet */
-    BaseRegister.Long = __readmsr(MSR_APIC_BASE);
+    BaseRegister.LongLong = __readmsr(MSR_APIC_BASE);
     BaseRegister.Enable = 1;
     BaseRegister.BootStrapCPUCore = (Cpu == 0);
-    __writemsr(MSR_APIC_BASE, BaseRegister.Long);
+    __writemsr(MSR_APIC_BASE, BaseRegister.LongLong);
 
     /* Set spurious vector and SoftwareEnable to 1 */
     SpIntRegister.Long = ApicRead(APIC_SIVR);
diff --git a/hal/halx86/apic/apic.h b/hal/halx86/apic/apic.h
deleted file mode 100644 (file)
index edabaa3..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-
-#pragma once
-
-#ifdef _M_AMD64
-#define IOAPIC_BASE 0xFFFFFFFFFFFE1000ULL // checkme
-#define ZERO_VECTOR          0x00 // IRQL 00
-#define APC_VECTOR           0x3D // IRQL 01
-#define APIC_SPURIOUS_VECTOR 0x3f
-#define DISPATCH_VECTOR      0x41 // IRQL 02
-#define APIC_GENERIC_VECTOR  0xC1 // IRQL 27
-#define APIC_CLOCK_VECTOR    0xD1 // IRQL 28
-#define APIC_SYNCH_VECTOR    0xD1 // IRQL 28
-#define APIC_IPI_VECTOR      0xE1 // IRQL 29
-#define APIC_ERROR_VECTOR    0xE3
-#define POWERFAIL_VECTOR     0xEF // IRQL 30
-#define APIC_PROFILE_VECTOR  0xFD // IRQL 31
-#define APIC_NMI_VECTOR      0xFF
-#define IrqlToTpr(Irql) (Irql << 4)
-#define IrqlToSoftVector(Irql) ((Irql << 4)|0xf)
-#define TprToIrql(Tpr) ((KIRQL)(Tpr >> 4))
-#define CLOCK2_LEVEL CLOCK_LEVEL
-#else
-#define IOAPIC_BASE 0xFFFE1000 // checkme
-#define ZERO_VECTOR          0x00 // IRQL 00
-#define APIC_SPURIOUS_VECTOR 0x1f
-#define APC_VECTOR           0x3D // IRQL 01
-#define DISPATCH_VECTOR      0x41 // IRQL 02
-#define APIC_GENERIC_VECTOR  0xC1 // IRQL 27
-#define APIC_CLOCK_VECTOR    0xD1 // IRQL 28
-#define APIC_SYNCH_VECTOR    0xD1 // IRQL 28
-#define APIC_IPI_VECTOR      0xE1 // IRQL 29
-#define APIC_ERROR_VECTOR    0xE3
-#define POWERFAIL_VECTOR     0xEF // IRQL 30
-#define APIC_PROFILE_VECTOR  0xFD // IRQL 31
-#define APIC_NMI_VECTOR      0xFF
-#define IrqlToTpr(Irql) (HalpIRQLtoTPR[Irql])
-#define IrqlToSoftVector(Irql) IrqlToTpr(Irql)
-#define TprToIrql(Tpr)  (HalVectorToIRQL[Tpr >> 4])
-#endif
-
-#define MSR_APIC_BASE 0x0000001B
-#define IOAPIC_PHYS_BASE 0xFEC00000
-#define APIC_CLOCK_INDEX 8
-
-#define ApicLogicalId(Cpu) ((UCHAR)(1<< Cpu))
-
-/* APIC Register Address Map */
-#define APIC_ID       0x0020 /* Local APIC ID Register (R/W) */
-#define APIC_VER      0x0030 /* Local APIC Version Register (R) */
-#define APIC_TPR      0x0080 /* Task Priority Register (R/W) */
-#define APIC_APR      0x0090 /* Arbitration Priority Register (R) */
-#define APIC_PPR      0x00A0 /* Processor Priority Register (R) */
-#define APIC_EOI      0x00B0 /* EOI Register (W) */
-#define APIC_RRR      0x00C0 /* Remote Read Register () */
-#define APIC_LDR      0x00D0 /* Logical Destination Register (R/W) */
-#define APIC_DFR      0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */
-#define APIC_SIVR     0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */
-#define APIC_ISR      0x0100 /* Interrupt Service Register 0-255 (R) */
-#define APIC_TMR      0x0180 /* Trigger Mode Register 0-255 (R) */
-#define APIC_IRR      0x0200 /* Interrupt Request Register 0-255 (r) */
-#define APIC_ESR      0x0280 /* Error Status Register (R) */
-#define APIC_ICR0     0x0300 /* Interrupt Command Register 0-31 (R/W) */
-#define APIC_ICR1     0x0310 /* Interrupt Command Register 32-63 (R/W) */
-#define APIC_TMRLVTR  0x0320 /* Timer Local Vector Table (R/W) */
-#define        APIC_THRMLVTR 0x0330 /* Thermal Local Vector Table */
-#define APIC_PCLVTR   0x0340 /* Performance Counter Local Vector Table (R/W) */
-#define APIC_LINT0    0x0350 /* LINT0 Local Vector Table (R/W) */
-#define APIC_LINT1    0x0360 /* LINT1 Local Vector Table (R/W) */
-#define APIC_ERRLVTR  0x0370 /* Error Local Vector Table (R/W) */
-#define APIC_TICR     0x0380 /* Initial Count Register for Timer (R/W) */
-#define APIC_TCCR     0x0390 /* Current Count Register for Timer (R) */
-#define APIC_TDCR     0x03E0 /* Timer Divide Configuration Register (R/W) */
-#define APIC_EAFR     0x0400 /* extended APIC Feature register (R/W) */
-#define APIC_EACR     0x0410 /* Extended APIC Control Register (R/W) */
-#define APIC_SEOI     0x0420 /* Specific End Of Interrupt Register (W) */
-#define APIC_EXT0LVTR 0x0500 /* Extended Interrupt 0 Local Vector Table */
-#define APIC_EXT1LVTR 0x0510 /* Extended Interrupt 1 Local Vector Table */
-#define APIC_EXT2LVTR 0x0520 /* Extended Interrupt 2 Local Vector Table */
-#define APIC_EXT3LVTR 0x0530 /* Extended Interrupt 3 Local Vector Table */
-
-enum
-{
-    APIC_MT_Fixed = 0,
-    APIC_MT_LowestPriority = 1,
-    APIC_MT_SMI = 2,
-    APIC_MT_RemoteRead = 3,
-    APIC_MT_NMI = 4,
-    APIC_MT_INIT = 5,
-    APIC_MT_Startup = 6,
-    APIC_MT_ExtInt = 7,
-};
-
-enum
-{
-    APIC_TGM_Edge,
-    APIC_TGM_Level
-};
-
-enum
-{
-    APIC_DM_Physical,
-    APIC_DM_Logical
-};
-
-enum
-{
-    APIC_DSH_Destination,
-    APIC_DSH_Self,
-    APIC_DSH_AllIncludingSelf,
-    APIC_DSH_AllExclusingSelf
-};
-
-enum
-{
-    APIC_DF_Flat = 0xFFFFFFFF,
-    APIC_DF_Cluster = 0x0FFFFFFF
-};
-
-enum
-{
-    TIMER_DV_DivideBy2 = 0,
-    TIMER_DV_DivideBy4 = 1,
-    TIMER_DV_DivideBy8 = 2,
-    TIMER_DV_DivideBy16 = 3,
-    TIMER_DV_DivideBy32 = 8,
-    TIMER_DV_DivideBy64 = 9,
-    TIMER_DV_DivideBy128 = 10,
-    TIMER_DV_DivideBy1 = 11,
-};
-
-
-typedef union _APIC_BASE_ADRESS_REGISTER
-{
-    ULONG64 Long;
-    struct
-    {
-        ULONG64 Reserved1:8;
-        ULONG64 BootStrapCPUCore:1;
-        ULONG64 Reserved2:2;
-        ULONG64 Enable:1;
-        ULONG64 BaseAddress:40;
-        ULONG64 ReservedMBZ:12;
-    };
-} APIC_BASE_ADRESS_REGISTER;
-
-typedef union _APIC_SPURIOUS_INERRUPT_REGISTER
-{
-    ULONG Long;
-    struct
-    {
-        ULONG Vector:8;
-        ULONG SoftwareEnable:1;
-        ULONG FocusCPUCoreChecking:1;
-        ULONG ReservedMBZ:22;
-    };
-} APIC_SPURIOUS_INERRUPT_REGISTER;
-
-typedef union
-{
-    ULONG Long;
-    struct
-    {
-        ULONG Version:8;
-        ULONG ReservedMBZ:8;
-        ULONG MaxLVT:8;
-        ULONG ReservedMBZ1:7;
-        ULONG ExtRegSpacePresent:1;
-    };
-} APIC_VERSION_REGISTER;
-
-typedef union
-{
-    ULONG Long;
-    struct
-    {
-        ULONG Version:1;
-        ULONG SEOIEnable:1;
-        ULONG ExtApicIdEnable:1;
-        ULONG ReservedMBZ:29;
-    };
-} APIC_EXTENDED_CONTROL_REGISTER;
-
-typedef union _APIC_COMMAND_REGISTER
-{
-    ULONGLONG LongLong;
-    struct
-    {
-        ULONG Long0;
-        ULONG Long1;
-    };
-    struct
-    {
-        ULONGLONG Vector:8;
-        ULONGLONG MessageType:3;
-        ULONGLONG DestinationMode:1;
-        ULONGLONG DeliveryStatus:1;
-        ULONGLONG ReservedMBZ:1;
-        ULONGLONG Level:1;
-        ULONGLONG TriggerMode:1;
-        ULONGLONG RemoteReadStatus:2;
-        ULONGLONG DestinationShortHand:2;
-        ULONGLONG Reserved2MBZ:36;
-        ULONGLONG Destination:8;
-    };
-} APIC_COMMAND_REGISTER;
-
-typedef union
-{
-    ULONG Long;
-    struct
-    {
-        ULONG Vector:8;
-        ULONG MessageType:3;
-        ULONG ReservedMBZ:1;
-        ULONG DeliveryStatus:1;
-        ULONG Reserved1MBZ:1;
-        ULONG RemoteIRR:1;
-        ULONG TriggerMode:1;
-        ULONG Mask:1;
-        ULONG TimerMode:1;
-        ULONG Reserved2MBZ:13;
-    };
-} LVT_REGISTER;
-
-
-enum
-{
-    IOAPIC_IOREGSEL = 0x00,
-    IOAPIC_IOWIN    = 0x10
-};
-
-enum
-{
-    IOAPIC_ID  = 0x00,
-    IOAPIC_VER = 0x01,
-    IOAPIC_ARB = 0x02,
-    IOAPIC_REDTBL = 0x10
-};
-
-typedef union _IOAPIC_REDIRECTION_REGISTER
-{
-    ULONGLONG LongLong;
-    struct
-    {
-        ULONG Long0;
-        ULONG Long1;
-    };
-    struct
-    {
-        ULONGLONG Vector:8;
-        ULONGLONG DeliveryMode:3;
-        ULONGLONG DestinationMode:1;
-        ULONGLONG DeliveryStatus:1;
-        ULONGLONG Polarity:1;
-        ULONGLONG RemoteIRR:1;
-        ULONGLONG TriggerMode:1;
-        ULONGLONG Mask:1;
-        ULONGLONG Reserved:39;
-        ULONGLONG Destination:8;
-    };
-} IOAPIC_REDIRECTION_REGISTER;
-
-FORCEINLINE
-ULONG
-ApicRead(ULONG Offset)
-{
-    return *(volatile ULONG *)(APIC_BASE + Offset);
-}
-
-FORCEINLINE
-VOID
-ApicWrite(ULONG Offset, ULONG Value)
-{
-    *(volatile ULONG *)(APIC_BASE + Offset) = Value;
-}
-
-VOID
-NTAPI
-ApicInitializeTimer(ULONG Cpu);
-
-VOID
-NTAPI
-HalInitializeProfiling(VOID);
-
-VOID __cdecl ApicSpuriousService(VOID);
-
index 5fe9305..1a152e2 100644 (file)
@@ -9,11 +9,10 @@
 /* INCLUDES ******************************************************************/
 
 #include <hal.h>
+#include <apic.h>
 #define NDEBUG
 #include <debug.h>
 
-#include "apic.h"
-
 extern LARGE_INTEGER HalpCpuClockFrequency;
 
 /* HAL profiling variables */
diff --git a/hal/halx86/apic/halaacpi.rc b/hal/halx86/apic/halaacpi.rc
new file mode 100644 (file)
index 0000000..8d7142e
--- /dev/null
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION  "X86 Uniprocessor Hardware Abstraction Layer"
+#define REACTOS_STR_INTERNAL_NAME     "halaacpi"
+#define REACTOS_STR_ORIGINAL_FILENAME "halaacpi.dll"
+#include <reactos/version.rc>
index 0ade0fd..504f568 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * PROJECT:     ReactOS Hardware Abstraction Layer
  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
- * PURPOSE:     Initialize the x86 HAL
+ * PURPOSE:     Initialize the APIC HAL
  * COPYRIGHT:   Copyright 2011 Timo Kreuzer <timo.kreuzer@reactos.org>
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <hal.h>
+#include <apic.h>
 #define NDEBUG
 #include <debug.h>
-#include "apic.h"
 
 VOID
 NTAPI
@@ -36,7 +36,6 @@ HalpInitProcessor(
 
     /* Initialize the timer */
     //ApicInitializeTimer(ProcessorNumber);
-
 }
 
 VOID
index a9b79ee..ce06b2f 100644 (file)
@@ -9,11 +9,10 @@
 /* INCLUDES ******************************************************************/
 
 #include <hal.h>
+#include "tsc.h"
 #define NDEBUG
 #include <debug.h>
 
-#include "tsc.h"
-
 LARGE_INTEGER HalpCpuClockFrequency = {{INITIAL_STALL_COUNT * 1000000}};
 
 UCHAR TscCalibrationPhase;
index 315af0a..fe82a14 100644 (file)
 /*
- *
+ * PROJECT:     ReactOS Kernel
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Header file for APIC hal
+ * COPYRIGHT:   Copyright 2011 Timo Kreuzer <timo.kreuzer@reactos.org>
+ *              Copyright 2021 Justin Miller <justinmiller100@gmail.com>
  */
 
 #pragma once
 
 #ifdef _M_AMD64
-#define APIC_DEFAULT_BASE     0xfffffffffee00000ULL;
+    #define LOCAL_APIC_BASE 0xFFFFFFFFFFFE0000ULL
+    #define IOAPIC_BASE 0xFFFFFFFFFFFE1000ULL
+    #define APIC_SPURIOUS_VECTOR 0x3f 
+    #define IrqlToTpr(Irql) (Irql << 4)
+    #define IrqlToSoftVector(Irql) ((Irql << 4)|0xf)
+    #define TprToIrql(Tpr) ((KIRQL)(Tpr >> 4))
+    #define CLOCK2_LEVEL CLOCK_LEVEL
 #else
-#define APIC_DEFAULT_BASE     0xFEE00000    /* Default Local APIC Base Register Address */
+    #define LOCAL_APIC_BASE  0xFFFE0000
+    #define IOAPIC_BASE 0xFFFE1000
+    #define APIC_SPURIOUS_VECTOR 0x1f
+    #define IrqlToTpr(Irql) (HalpIRQLtoTPR[Irql])
+    #define IrqlToSoftVector(Irql) IrqlToTpr(Irql)
+    #define TprToIrql(Tpr)  (HalVectorToIRQL[Tpr >> 4])
 #endif
 
-/* APIC Register Address Map */
-#define APIC_ID      0x0020 /* Local APIC ID Register (R/W) */
-#define APIC_VER     0x0030 /* Local APIC Version Register (R) */
-#define APIC_TPR     0x0080 /* Task Priority Register (R/W) */
-#define APIC_APR     0x0090 /* Arbitration Priority Register (R) */
-#define APIC_PPR     0x00A0 /* Processor Priority Register (R) */
-#define APIC_EOI     0x00B0 /* EOI Register (W) */
-#define APIC_LDR     0x00D0 /* Logical Destination Register (R/W) */
-#define APIC_DFR     0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */
-#define APIC_SIVR    0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */
-#define APIC_ISR     0x0100 /* Interrupt Service Register 0-255 (R) */
-#define APIC_TMR     0x0180 /* Trigger Mode Register 0-255 (R) */
-#define APIC_IRR     0x0200 /* Interrupt Request Register 0-255 (r) */
-#define APIC_ESR     0x0280 /* Error Status Register (R) */
-#define APIC_ICR0    0x0300 /* Interrupt Command Register 0-31 (R/W) */
-#define APIC_ICR1    0x0310 /* Interrupt Command Register 32-63 (R/W) */
-#define APIC_LVTT    0x0320 /* Local Vector Table (Timer) (R/W) */
-#define        APIC_LVTTHMR 0x0330
-#define APIC_LVTPC   0x0340 /* Performance Counter LVT (R/W) */
-#define APIC_LINT0   0x0350 /* Local Vector Table (LINT0) (R/W) */
-#define APIC_LINT1   0x0360 /* Local Vector Table (LINT1) (R/W) */
-#define APIC_LVT3    0x0370 /* Local Vector Table (Error) (R/W) */
-#define APIC_ICRT    0x0380 /* Initial Count Register for Timer (R/W) */
-#define APIC_CCRT    0x0390 /* Current Count Register for Timer (R) */
-#define APIC_TDCR    0x03E0 /* Timer Divide Configuration Register (R/W) */
-
-#define APIC_ID_MASK           (0xF << 24)
-#define GET_APIC_ID(x)         (((x) & APIC_ID_MASK) >> 24)
-#define        GET_APIC_LOGICAL_ID(x)  (((x)>>24)&0xFF)
-#define APIC_VER_MASK          0xFF00FF
-#define GET_APIC_VERSION(x)    ((x) & 0xFF)
-#define GET_APIC_MAXLVT(x)     (((x) >> 16) & 0xFF)
-
-#define APIC_TPR_PRI       0xFF
-#define APIC_TPR_INT       0xF0
-#define APIC_TPR_SUB       0xF
-#define APIC_TPR_MAX       0xFF           /* Maximum priority */
-#define APIC_TPR_MIN       0x20           /* Minimum priority */
-
-#define APIC_LDR_MASK      (0xFF << 24)
-
-#define APIC_SIVR_ENABLE   (0x1 << 8)
-#define APIC_SIVR_FOCUS    (0x1 << 9)
-
-#define APIC_ESR_MASK      (0xFE << 0)    /* Error Mask */
-
-#define APIC_ICR0_VECTOR   (0xFF << 0)    /* Vector */
-#define APIC_ICR0_DM       (0x7 << 8)     /* Delivery Mode */
-#define APIC_ICR0_DESTM    (0x1 << 11)    /* Destination Mode */
-#define APIC_ICR0_DS       (0x1 << 12)    /* Delivery Status */
-#define APIC_ICR0_LEVEL    (0x1 << 14)    /* Level */
-#define APIC_ICR0_TM       (0x1 << 15)    /* Trigger Mode */
-#define APIC_ICR0_DESTS    (0x3 << 18)    /* Destination Shorthand */
-
-/* Delivery Modes */
-#define APIC_DM_FIXED    (0x0 << 8)
-#define APIC_DM_LOWEST    (0x1 << 8)
-#define APIC_DM_SMI       (0x2 << 8)
-#define APIC_DM_REMRD     (0x3 << 8)
-#define APIC_DM_NMI       (0x4 << 8)
-#define APIC_DM_INIT      (0x5 << 8)
-#define APIC_DM_STARTUP   (0x6 << 8)
-#define APIC_DM_EXTINT   (0x7 << 8)
-#define GET_APIC_DELIVERY_MODE(x)      (((x) >> 8) & 0x7)
-#define SET_APIC_DELIVERY_MODE(x,y)    (((x) & ~0x700) | ((y) << 8))
-
-/* Destination Shorthand values */
-#define APIC_ICR0_DESTS_FIELD          (0x0 << 0)
-#define APIC_ICR0_DESTS_SELF           (0x1 << 18)
-#define APIC_ICR0_DESTS_ALL            (0x2 << 18)
-#define APIC_ICR0_DESTS_ALL_BUT_SELF   (0x3 << 18)
-
-#define APIC_ICR0_LEVEL_DEASSERT (0x0 << 14) /* Deassert level */
-#define APIC_ICR0_LEVEL_ASSERT   (0x1 << 14) /* Assert level */
-
-#define GET_APIC_DEST_FIELD(x)   (((x) >> 24) & 0xFF)
-#define SET_APIC_DEST_FIELD(x)   (((x) & 0xFF) << 24)
-
-#define GET_APIC_TIMER_BASE(x)   (((x) >> 18) & 0x3)
-#define SET_APIC_TIMER_BASE(x)   ((x) << 18)
-#define APIC_TIMER_BASE_CLKIN    0x0
-#define APIC_TIMER_BASE_TMBASE   0x1
-#define APIC_TIMER_BASE_DIV      0x2
-
-#define APIC_LVT_VECTOR                  (0xFF << 0)   /* Vector */
-#define APIC_LVT_DS                      (0x1 << 12)   /* Delivery Status */
-#define APIC_LVT_REMOTE_IRR              (0x1 << 14)   /* Remote IRR */
-#define APIC_LVT_LEVEL_TRIGGER           (0x1 << 15)   /* Lvel Triggered */
-#define APIC_LVT_MASKED                          (0x1 << 16)   /* Mask */
-#define APIC_LVT_PERIODIC                (0x1 << 17)   /* Timer Mode */
-
-#define APIC_LVT3_DM        (0x7 << 8)
-#define APIC_LVT3_IIPP      (0x1 << 13)
-#define APIC_LVT3_TM        (0x1 << 15)
-#define APIC_LVT3_MASKED    (0x1 << 16)
-#define APIC_LVT3_OS        (0x1 << 17)
-
-#define APIC_TDCR_TMBASE   (0x1 << 2)
-#define APIC_TDCR_MASK     0x0F
-#define APIC_TDCR_2        0x00
-#define APIC_TDCR_4        0x01
-#define APIC_TDCR_8        0x02
-#define APIC_TDCR_16       0x03
-#define APIC_TDCR_32       0x08
-#define APIC_TDCR_64       0x09
-#define APIC_TDCR_128      0x0A
-#define APIC_TDCR_1        0x0B
-
-#define APIC_TARGET_SELF         0x100
-#define APIC_TARGET_ALL          0x200
-#define APIC_TARGET_ALL_BUT_SELF 0x300
-
-#define APIC_INTEGRATED(version) (version & 0xF0)
-
-typedef enum {
-  amPIC = 0,    /* IMCR and PIC compatibility mode */
-  amVWIRE       /* Virtual Wire compatibility mode */
-} APIC_MODE;
-
-#ifdef CONFIG_SMP
-#define MAX_CPU   32
-#else
-#define MAX_CPU          1
-#endif
+/* 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.
+   Then write the data to I/O port 23h. The power-on default value is zero,
+   which connects the NMI and 8259 INTR lines directly to the BSP.
+   Writing a value of 01h forces the NMI and 8259 INTR signals to pass through the APIC.
+*/
+#define IMCR_ADDRESS_PORT  (PUCHAR)0x0022
+#define IMCR_DATA_PORT     (PUCHAR)0x0023
+#define IMCR_SELECT        0x70
+#define IMCR_PIC_DIRECT    0x00
+#define IMCR_PIC_VIA_APIC  0x01
+
+#define ZERO_VECTOR          0x00 // IRQL 00
+#define APC_VECTOR           0x3D // IRQL 01
+#define DISPATCH_VECTOR      0x41 // IRQL 02
+#define APIC_GENERIC_VECTOR  0xC1 // IRQL 27
+#define APIC_CLOCK_VECTOR    0xD1 // IRQL 28
+#define APIC_SYNCH_VECTOR    0xD1 // IRQL 28
+#define APIC_IPI_VECTOR      0xE1 // IRQL 29
+#define APIC_ERROR_VECTOR    0xE3
+#define POWERFAIL_VECTOR     0xEF // IRQL 30
+#define APIC_PROFILE_VECTOR  0xFD // IRQL 31
+#define APIC_PERF_VECTOR     0xFE
+#define APIC_NMI_VECTOR      0xFF
 
-/*
- * Local APIC timer IRQ vector is on a different priority level,
- * to work around the 'lost local interrupt if more than 2 IRQ
- * sources per level' errata.
- */
-#define LOCAL_TIMER_VECTOR         0xEF
-
-#define IPI_VECTOR                 0xFB
-#define ERROR_VECTOR               0xFE
-#define SPURIOUS_VECTOR                    0xFF  /* Must be 0xXF */
-
-/* CPU flags */
-#define CPU_USABLE   0x01  /* 1 if the CPU is usable (ie. can be used) */
-#define CPU_ENABLED  0x02  /* 1 if the CPU is enabled */
-#define CPU_BSP      0x04  /* 1 if the CPU is the bootstrap processor */
-#define CPU_TSC      0x08  /* 1 if the CPU has a time stamp counter */
-
-typedef struct _CPU_INFO
-{
-   UCHAR    Flags;            /* CPU flags */
-   UCHAR    APICId;           /* Local APIC ID */
-   UCHAR    APICVersion;      /* Local APIC version */
-//   UCHAR    MaxLVT;           /* Number of LVT registers */
-   ULONG    BusSpeed;         /* BUS speed */
-   ULONG    CoreSpeed;        /* Core speed */
-   UCHAR    Padding[16-12];   /* Padding to 16-byte */
-} CPU_INFO, *PCPU_INFO;
-
-extern ULONG CPUCount;                 /* Total number of CPUs */
-extern ULONG BootCPU;                  /* Bootstrap processor */
-extern ULONG OnlineCPUs;               /* Bitmask of online CPUs */
-extern CPU_INFO CPUMap[MAX_CPU];       /* Map of all CPUs in the system */
-extern PULONG APICBase;                        /* Virtual address of local APIC */
-extern ULONG lastregr[MAX_CPU];                /* For debugging */
-extern ULONG lastvalr[MAX_CPU];
-extern ULONG lastregw[MAX_CPU];
-extern ULONG lastvalw[MAX_CPU];
-
-/* Prototypes */
-VOID APICSendIPI(ULONG Target, ULONG Mode);
-VOID APICSetup(VOID);
-VOID HaliInitBSP(VOID);
-VOID APICSyncArbIDs(VOID);
-VOID APICCalibrateTimer(ULONG CPU);
-VOID HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack);
-
-static __inline ULONG _APICRead(ULONG Offset)
-{
-    PULONG p;
-
-    p = (PULONG)((ULONG_PTR)APICBase + Offset);
-    return *p;
-}
-
-#if 0
-static __inline VOID APICWrite(ULONG Offset,
-                               ULONG Value)
+/* APIC Register Address Map */
+#define APIC_ID       0x0020 /* Local APIC ID Register (R/W) */
+#define APIC_VER      0x0030 /* Local APIC Version Register (R) */
+#define APIC_TPR      0x0080 /* Task Priority Register (R/W) */
+#define APIC_APR      0x0090 /* Arbitration Priority Register (R) */
+#define APIC_PPR      0x00A0 /* Processor Priority Register (R) */
+#define APIC_EOI      0x00B0 /* EOI Register (W) */
+#define APIC_RRR      0x00C0 /* Remote Read Register () */
+#define APIC_LDR      0x00D0 /* Logical Destination Register (R/W) */
+#define APIC_DFR      0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */
+#define APIC_SIVR     0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */
+#define APIC_ISR      0x0100 /* Interrupt Service Register 0-255 (R) */
+#define APIC_TMR      0x0180 /* Trigger Mode Register 0-255 (R) */
+#define APIC_IRR      0x0200 /* Interrupt Request Register 0-255 (r) */
+#define APIC_ESR      0x0280 /* Error Status Register (R) */
+#define APIC_ICR0     0x0300 /* Interrupt Command Register 0-31 (R/W) */
+#define APIC_ICR1     0x0310 /* Interrupt Command Register 32-63 (R/W) */
+#define APIC_TMRLVTR  0x0320 /* Timer Local Vector Table (R/W) */
+#define        APIC_THRMLVTR 0x0330 /* Thermal Local Vector Table */
+#define APIC_PCLVTR   0x0340 /* Performance Counter Local Vector Table (R/W) */
+#define APIC_LINT0    0x0350 /* LINT0 Local Vector Table (R/W) */
+#define APIC_LINT1    0x0360 /* LINT1 Local Vector Table (R/W) */
+#define APIC_ERRLVTR  0x0370 /* Error Local Vector Table (R/W) */
+#define APIC_TICR     0x0380 /* Initial Count Register for Timer (R/W) */
+#define APIC_TCCR     0x0390 /* Current Count Register for Timer (R) */
+#define APIC_TDCR     0x03E0 /* Timer Divide Configuration Register (R/W) */
+#define APIC_EAFR     0x0400 /* extended APIC Feature register (R/W) */
+#define APIC_EACR     0x0410 /* Extended APIC Control Register (R/W) */
+#define APIC_SEOI     0x0420 /* Specific End Of Interrupt Register (W) */
+#define APIC_EXT0LVTR 0x0500 /* Extended Interrupt 0 Local Vector Table */
+#define APIC_EXT1LVTR 0x0510 /* Extended Interrupt 1 Local Vector Table */
+#define APIC_EXT2LVTR 0x0520 /* Extended Interrupt 2 Local Vector Table */
+#define APIC_EXT3LVTR 0x0530 /* Extended Interrupt 3 Local Vector Table */
+
+#define MSR_APIC_BASE 0x0000001B
+#define IOAPIC_PHYS_BASE 0xFEC00000
+#define APIC_CLOCK_INDEX 8
+#define ApicLogicalId(Cpu) ((UCHAR)(1<< Cpu))
+
+/* Message Type */
+enum
 {
-    PULONG p;
-
-    p = (PULONG)((ULONG_PTR)APICBase + Offset);
-
-    *p = Value;
-}
-#else
-static __inline VOID APICWrite(ULONG Offset,
-                               ULONG Value)
+    APIC_MT_Fixed = 0,
+    APIC_MT_LowestPriority = 1,
+    APIC_MT_SMI = 2,
+    APIC_MT_RemoteRead = 3,
+    APIC_MT_NMI = 4,
+    APIC_MT_INIT = 5,
+    APIC_MT_Startup = 6,
+    APIC_MT_ExtInt = 7,
+};
+
+/* Trigger Mode */
+enum
 {
-    PULONG p;
-    ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
-
-    lastregw[CPU] = Offset;
-    lastvalw[CPU] = Value;
-
-    p = (PULONG)((ULONG_PTR)APICBase + Offset);
+    APIC_TGM_Edge,
+    APIC_TGM_Level
+};
 
-    *p = Value;
-}
-#endif
-
-#if 0 
-static __inline ULONG APICRead(ULONG Offset)
+/* Delivery Mode */
+enum
 {
-    PULONG p;
+    APIC_DM_Physical,
+    APIC_DM_Logical
+};
 
-    p = (PULONG)((ULONG_PTR)APICBase + Offset);
-    return *p;
-}
-#else
-static __inline ULONG APICRead(ULONG Offset)
+/* Destination Short Hand */
+enum
 {
-    PULONG p;
-    ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
-
-    lastregr[CPU] = Offset;
-    lastvalr[CPU] = 0;
+    APIC_DSH_Destination,
+    APIC_DSH_Self,
+    APIC_DSH_AllIncludingSelf,
+    APIC_DSH_AllExclusingSelf
+};
+
+/* Write Constants */
+enum
+{
+    APIC_DF_Flat = 0xFFFFFFFF,
+    APIC_DF_Cluster = 0x0FFFFFFF
+};
 
-    p = (PULONG)((ULONG_PTR)APICBase + Offset);
+/* Timer Constants */
+enum
+{
+    TIMER_DV_DivideBy2 = 0,
+    TIMER_DV_DivideBy4 = 1,
+    TIMER_DV_DivideBy8 = 2,
+    TIMER_DV_DivideBy16 = 3,
+    TIMER_DV_DivideBy32 = 8,
+    TIMER_DV_DivideBy64 = 9,
+    TIMER_DV_DivideBy128 = 10,
+    TIMER_DV_DivideBy1 = 11,
+};
+
+#include <pshpack1.h>
+typedef union _APIC_BASE_ADRESS_REGISTER
+{
+    UINT64 LongLong;
+    struct
+    {
+        UINT64 Reserved1:8;
+        UINT64 BootStrapCPUCore:1;
+        UINT64 Reserved2:2;
+        UINT64 Enable:1;
+        UINT64 BaseAddress:40;
+        UINT64 ReservedMBZ:12;
+    };
+} APIC_BASE_ADRESS_REGISTER;
+
+typedef union _APIC_SPURIOUS_INERRUPT_REGISTER
+{
+    UINT32 Long;
+    struct
+    {
+        UINT32 Vector:8;
+        UINT32 SoftwareEnable:1;
+        UINT32 FocusCPUCoreChecking:1;
+        UINT32 ReservedMBZ:22;
+    };
+} APIC_SPURIOUS_INERRUPT_REGISTER;
+
+typedef union _APIC_VERSION_REGISTER
+{
+    UINT32 Long;
+    struct
+    {
+        UINT32 Version:8;
+        UINT32 ReservedMBZ:8;
+        UINT32 MaxLVT:8;
+        UINT32 ReservedMBZ1:7;
+        UINT32 ExtRegSpacePresent:1;
+    };
+} APIC_VERSION_REGISTER;
+
+typedef union _APIC_EXTENDED_CONTROL_REGISTER
+{
+    UINT32 Long;
+    struct
+    {
+        UINT32 Version:1;
+        UINT32 SEOIEnable:1;
+        UINT32 ExtApicIdEnable:1;
+        UINT32 ReservedMBZ:29;
+    };
+} APIC_EXTENDED_CONTROL_REGISTER;
+
+typedef union _APIC_COMMAND_REGISTER
+{
+    UINT64 LongLong;
+    struct
+    {
+        UINT32 Long0;
+        UINT32 Long1;
+    };
+    struct
+    {
+        UINT64 Vector:8;
+        UINT64 MessageType:3;
+        UINT64 DestinationMode:1;
+        UINT64 DeliveryStatus:1;
+        UINT64 ReservedMBZ:1;
+        UINT64 Level:1;
+        UINT64 TriggerMode:1;
+        UINT64 RemoteReadStatus:2;
+        UINT64 DestinationShortHand:2;
+        UINT64 Reserved2MBZ:36;
+        UINT64 Destination:8;
+    };
+} APIC_COMMAND_REGISTER;
+
+typedef union _LVT_REGISTER
+{
+    UINT32 Long;
+    struct
+    {
+        UINT32 Vector:8;
+        UINT32 MessageType:3;
+        UINT32 ReservedMBZ:1;
+        UINT32 DeliveryStatus:1;
+        UINT32 Reserved1MBZ:1;
+        UINT32 RemoteIRR:1;
+        UINT32 TriggerMode:1;
+        UINT32 Mask:1;
+        UINT32 TimerMode:1;
+        UINT32 Reserved2MBZ:13;
+    };
+} LVT_REGISTER;
+
+/* IOAPIC offsets */
+enum
+{
+    IOAPIC_IOREGSEL = 0x00,
+    IOAPIC_IOWIN    = 0x10
+};
 
-    lastvalr[CPU] = *p;
-    return lastvalr[CPU];
-}
-#endif
+/* IOAPIC Constants */
+enum
+{
+    IOAPIC_ID  = 0x00,
+    IOAPIC_VER = 0x01,
+    IOAPIC_ARB = 0x02,
+    IOAPIC_REDTBL = 0x10
+};
 
-static __inline ULONG ThisCPU(VOID)
+typedef union _IOAPIC_REDIRECTION_REGISTER
 {
-    return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
+    UINT64 LongLong;
+    struct
+    {
+        UINT32 Long0;
+        UINT32 Long1;
+    };
+    struct
+    {
+        UINT64 Vector:8;
+        UINT64 DeliveryMode:3;
+        UINT64 DestinationMode:1;
+        UINT64 DeliveryStatus:1;
+        UINT64 Polarity:1;
+        UINT64 RemoteIRR:1;
+        UINT64 TriggerMode:1;
+        UINT64 Mask:1;
+        UINT64 Reserved:39;
+        UINT64 Destination:8;
+    };
+} IOAPIC_REDIRECTION_REGISTER;
+#include <poppack.h>
+
+FORCEINLINE
+ULONG
+ApicRead(ULONG Offset)
+{
+    return *(volatile ULONG *)(APIC_BASE + Offset);
 }
 
-static __inline VOID APICSendEOI(VOID)
+FORCEINLINE
+VOID
+ApicWrite(ULONG Offset, ULONG Value)
 {
-    // Send the EOI
-    APICWrite(APIC_EOI, 0);
+    *(volatile ULONG *)(APIC_BASE + Offset) = Value;
 }
 
-/* EOF */
+VOID
+NTAPI
+ApicInitializeTimer(ULONG Cpu);
+
+VOID
+NTAPI
+HalInitializeProfiling(VOID);
+
+VOID
+NTAPI
+HalpInitApicInfo(IN PLOADER_PARAMETER_BLOCK KeLoaderBlock); 
+
+VOID __cdecl ApicSpuriousService(VOID);
diff --git a/hal/halx86/smp/halmacpi.rc b/hal/halx86/smp/halmacpi.rc
new file mode 100644 (file)
index 0000000..883ed5c
--- /dev/null
@@ -0,0 +1,9 @@
+#define REACTOS_VERSION_DLL
+#ifdef _M_AMD64
+#define REACTOS_STR_FILE_DESCRIPTION  "X64 Multiprocessor Hardware Abstraction Layer"
+#else
+#define REACTOS_STR_FILE_DESCRIPTION  "X86 Multiprocessor Hardware Abstraction Layer"
+#endif
+#define REACTOS_STR_INTERNAL_NAME     "halmacpi"
+#define REACTOS_STR_ORIGINAL_FILENAME "halmacpi.dll"
+#include <reactos/version.rc>