mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[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 d28eae967a
Meanwhile, merge and clean up APIC headers a bit
This commit is contained in:
parent
239266640f
commit
0d9020634a
9 changed files with 311 additions and 532 deletions
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -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 */
|
||||
|
|
5
hal/halx86/apic/halaacpi.rc
Normal file
5
hal/halx86/apic/halaacpi.rc
Normal file
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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@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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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 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 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 MSR_APIC_BASE 0x0000001B
|
||||
#define IOAPIC_PHYS_BASE 0xFEC00000
|
||||
#define APIC_CLOCK_INDEX 8
|
||||
#define ApicLogicalId(Cpu) ((UCHAR)(1<< Cpu))
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
* 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
|
||||
/* Message Type */
|
||||
enum
|
||||
{
|
||||
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;
|
||||
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,
|
||||
};
|
||||
|
||||
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)
|
||||
/* Trigger Mode */
|
||||
enum
|
||||
{
|
||||
PULONG p;
|
||||
APIC_TGM_Edge,
|
||||
APIC_TGM_Level
|
||||
};
|
||||
|
||||
p = (PULONG)((ULONG_PTR)APICBase + Offset);
|
||||
return *p;
|
||||
/* Delivery Mode */
|
||||
enum
|
||||
{
|
||||
APIC_DM_Physical,
|
||||
APIC_DM_Logical
|
||||
};
|
||||
|
||||
/* Destination Short Hand */
|
||||
enum
|
||||
{
|
||||
APIC_DSH_Destination,
|
||||
APIC_DSH_Self,
|
||||
APIC_DSH_AllIncludingSelf,
|
||||
APIC_DSH_AllExclusingSelf
|
||||
};
|
||||
|
||||
/* Write Constants */
|
||||
enum
|
||||
{
|
||||
APIC_DF_Flat = 0xFFFFFFFF,
|
||||
APIC_DF_Cluster = 0x0FFFFFFF
|
||||
};
|
||||
|
||||
/* 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
|
||||
};
|
||||
|
||||
/* IOAPIC Constants */
|
||||
enum
|
||||
{
|
||||
IOAPIC_ID = 0x00,
|
||||
IOAPIC_VER = 0x01,
|
||||
IOAPIC_ARB = 0x02,
|
||||
IOAPIC_REDTBL = 0x10
|
||||
};
|
||||
|
||||
typedef union _IOAPIC_REDIRECTION_REGISTER
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static __inline VOID APICWrite(ULONG Offset,
|
||||
ULONG Value)
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ApicWrite(ULONG Offset, ULONG Value)
|
||||
{
|
||||
PULONG p;
|
||||
|
||||
p = (PULONG)((ULONG_PTR)APICBase + Offset);
|
||||
|
||||
*p = Value;
|
||||
}
|
||||
#else
|
||||
static __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_PTR)APICBase + Offset);
|
||||
|
||||
*p = Value;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static __inline ULONG APICRead(ULONG Offset)
|
||||
{
|
||||
PULONG p;
|
||||
|
||||
p = (PULONG)((ULONG_PTR)APICBase + Offset);
|
||||
return *p;
|
||||
}
|
||||
#else
|
||||
static __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_PTR)APICBase + Offset);
|
||||
|
||||
lastvalr[CPU] = *p;
|
||||
return lastvalr[CPU];
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline ULONG ThisCPU(VOID)
|
||||
{
|
||||
return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
|
||||
*(volatile ULONG *)(APIC_BASE + Offset) = Value;
|
||||
}
|
||||
|
||||
static __inline VOID APICSendEOI(VOID)
|
||||
{
|
||||
// Send the EOI
|
||||
APICWrite(APIC_EOI, 0);
|
||||
}
|
||||
VOID
|
||||
NTAPI
|
||||
ApicInitializeTimer(ULONG Cpu);
|
||||
|
||||
/* EOF */
|
||||
VOID
|
||||
NTAPI
|
||||
HalInitializeProfiling(VOID);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpInitApicInfo(IN PLOADER_PARAMETER_BLOCK KeLoaderBlock);
|
||||
|
||||
VOID __cdecl ApicSpuriousService(VOID);
|
||||
|
|
9
hal/halx86/smp/halmacpi.rc
Normal file
9
hal/halx86/smp/halmacpi.rc
Normal file
|
@ -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>
|
Loading…
Reference in a new issue