https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0d9020634a02d972a1bec…
commit 0d9020634a02d972a1bec2674e9e206a0c200868
Author: Justin Miller <justinmiller100(a)gmail.com>
AuthorDate: Mon May 3 18:29:50 2021 -0700
Commit: GitHub <noreply(a)github.com>
CommitDate: Tue May 4 04:29:50 2021 +0300
[HALX86] Disable Lazy IRQL in APIC HAL (#3609)
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 | 6 +-
hal/halx86/apic/apic.c | 8 +-
hal/halx86/apic/apic.h | 286 -------------------------
hal/halx86/apic/apictimer.c | 3 +-
hal/halx86/apic/halaacpi.rc | 5 +
hal/halx86/apic/halinit.c | 5 +-
hal/halx86/apic/tsc.c | 3 +-
hal/halx86/include/apic.h | 512 ++++++++++++++++++++++++--------------------
hal/halx86/smp/halmacpi.rc | 9 +
9 files changed, 308 insertions(+), 529 deletions(-)
diff --git a/hal/halx86/CMakeLists.txt b/hal/halx86/CMakeLists.txt
index abb3c1dd469..0b1b18be370 100644
--- a/hal/halx86/CMakeLists.txt
+++ b/hal/halx86/CMakeLists.txt
@@ -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()
diff --git a/hal/halx86/apic/apic.c b/hal/halx86/apic/apic.c
index 54dbbf01f0a..4c98e13bdf9 100644
--- a/hal/halx86/apic/apic.c
+++ b/hal/halx86/apic/apic.c
@@ -12,14 +12,14 @@
/* 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
index edabaa3b9db..00000000000
--- a/hal/halx86/apic/apic.h
+++ /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);
-
diff --git a/hal/halx86/apic/apictimer.c b/hal/halx86/apic/apictimer.c
index 5fe93056605..1a152e2d410 100644
--- a/hal/halx86/apic/apictimer.c
+++ b/hal/halx86/apic/apictimer.c
@@ -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
index 00000000000..8d7142e80a2
--- /dev/null
+++ b/hal/halx86/apic/halaacpi.rc
@@ -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>
diff --git a/hal/halx86/apic/halinit.c b/hal/halx86/apic/halinit.c
index 0ade0fda11c..504f568dbb1 100644
--- a/hal/halx86/apic/halinit.c
+++ b/hal/halx86/apic/halinit.c
@@ -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(a)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
diff --git a/hal/halx86/apic/tsc.c b/hal/halx86/apic/tsc.c
index a9b79eea233..ce06b2f6d8e 100644
--- a/hal/halx86/apic/tsc.c
+++ b/hal/halx86/apic/tsc.c
@@ -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;
diff --git a/hal/halx86/include/apic.h b/hal/halx86/include/apic.h
index 315af0a6b3e..fe82a1425d8 100644
--- a/hal/halx86/include/apic.h
+++ b/hal/halx86/include/apic.h
@@ -1,253 +1,309 @@
/*
- *
+ * 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(a)reactos.org>
+ * Copyright 2021 Justin Miller <justinmiller100(a)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
index 00000000000..883ed5cdbad
--- /dev/null
+++ b/hal/halx86/smp/halmacpi.rc
@@ -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>