Migrate HL subsystem to C++
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/x86/cpu.c
|
||||
* FILE: xtoskrnl/hl/x86/cpu.cc
|
||||
* DESCRIPTION: HAL x86 (i686/AMD64) processor support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
@@ -21,13 +21,13 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HlInitializeProcessor(VOID)
|
||||
HL::Cpu::InitializeProcessor(VOID)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
KAFFINITY Affinity;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KeGetCurrentProcessorBlock();
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Set initial stall factor, CPU number and mask interrupts */
|
||||
ProcessorBlock->StallScaleFactor = INITIAL_STALL_FACTOR;
|
||||
@@ -37,11 +37,11 @@ HlInitializeProcessor(VOID)
|
||||
Affinity = (KAFFINITY) 1 << ProcessorBlock->CpuNumber;
|
||||
|
||||
/* Apply affinity to a set of processors */
|
||||
HlpActiveProcessors |= Affinity;
|
||||
ActiveProcessors |= Affinity;
|
||||
|
||||
/* Initialize APIC for this processor */
|
||||
HlpInitializePic();
|
||||
Pic::InitializePic();
|
||||
|
||||
/* Set the APIC running level */
|
||||
HlSetRunLevel(KeGetCurrentProcessorBlock()->RunLevel);
|
||||
HL::RunLevel::SetRunLevel(KeGetCurrentProcessorBlock()->RunLevel);
|
||||
}
|
@@ -1,100 +1,14 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/x86/pic.c
|
||||
* FILE: xtoskrnl/hl/x86/pic.cc
|
||||
* DESCRIPTION: Programmable Interrupt Controller (PIC) for x86 (i686/AMD64) support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Clears all errors on the APIC.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HlClearApicErrors(VOID)
|
||||
{
|
||||
/* Clear APIC errors */
|
||||
HlWriteApicRegister(APIC_ESR, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads from the APIC register.
|
||||
*
|
||||
* @param Register
|
||||
* Supplies the APIC register to read from.
|
||||
*
|
||||
* @return This routine returns the value read from the APIC register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
ULONGLONG
|
||||
HlReadApicRegister(IN APIC_REGISTER Register)
|
||||
{
|
||||
if(HlpApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* Read from x2APIC MSR */
|
||||
return ArReadModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read from xAPIC */
|
||||
return HlReadRegister32((PULONG)(APIC_BASE + (Register << 4)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals to the APIC that handling an interrupt is complete.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HlSendEoi(VOID)
|
||||
{
|
||||
/* Send APIC EOI */
|
||||
HlWriteApicRegister(APIC_EOI, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to the APIC register.
|
||||
*
|
||||
* @param Register
|
||||
* Supplies the APIC register to write to.
|
||||
*
|
||||
* @param Value
|
||||
* Supplies the value to write to the APIC register.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
HlWriteApicRegister(IN APIC_REGISTER Register,
|
||||
IN ULONGLONG Value)
|
||||
{
|
||||
if(HlpApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* Write to x2APIC MSR */
|
||||
ArWriteModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register), Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write to xAPIC */
|
||||
HlWriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the x2APIC extension is supported by the processor.
|
||||
*
|
||||
@@ -107,7 +21,7 @@ HlWriteApicRegister(IN APIC_REGISTER Register,
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
HlpCheckX2ApicSupport(VOID)
|
||||
HL::Pic::CheckX2ApicSupport(VOID)
|
||||
{
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
|
||||
@@ -133,6 +47,21 @@ HlpCheckX2ApicSupport(VOID)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all errors on the APIC.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Pic::ClearApicErrors(VOID)
|
||||
{
|
||||
/* Clear APIC errors */
|
||||
WriteApicRegister(APIC_ESR, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the local APIC ID of the current processor.
|
||||
*
|
||||
@@ -142,15 +71,15 @@ HlpCheckX2ApicSupport(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
HlpGetCpuApicId(VOID)
|
||||
HL::Pic::GetCpuApicId(VOID)
|
||||
{
|
||||
ULONG ApicId;
|
||||
|
||||
/* Read APIC ID register */
|
||||
ApicId = HlReadApicRegister(APIC_ID);
|
||||
ApicId = ReadApicRegister(APIC_ID);
|
||||
|
||||
/* Return logical CPU ID depending on current APIC mode */
|
||||
return (HlpApicMode == APIC_MODE_COMPAT) ? ((ApicId & 0xFFFFFFFF) >> APIC_XAPIC_LDR_SHIFT) : ApicId;
|
||||
return (ApicMode == APIC_MODE_COMPAT) ? ((ApicId & 0xFFFFFFFF) >> APIC_XAPIC_LDR_SHIFT) : ApicId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,7 +91,7 @@ HlpGetCpuApicId(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
HlpHandleApicSpuriousService(VOID)
|
||||
HL::Pic::HandleApicSpuriousService(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -175,7 +104,7 @@ HlpHandleApicSpuriousService(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
HlpHandlePicSpuriousService(VOID)
|
||||
HL::Pic::HandlePicSpuriousService(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -188,7 +117,7 @@ HlpHandlePicSpuriousService(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HlpInitializeApic(VOID)
|
||||
HL::Pic::InitializeApic(VOID)
|
||||
{
|
||||
APIC_SPURIOUS_REGISTER SpuriousRegister;
|
||||
APIC_BASE_REGISTER BaseRegister;
|
||||
@@ -196,49 +125,49 @@ HlpInitializeApic(VOID)
|
||||
ULONG CpuNumber;
|
||||
|
||||
/* Determine APIC mode (xAPIC compatibility or x2APIC) */
|
||||
if(HlpCheckX2ApicSupport())
|
||||
if(CheckX2ApicSupport())
|
||||
{
|
||||
/* Enable x2APIC mode */
|
||||
HlpApicMode = APIC_MODE_X2APIC;
|
||||
ApicMode = APIC_MODE_X2APIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Fall back to xAPIC compatibility mode */
|
||||
HlpApicMode = APIC_MODE_COMPAT;
|
||||
ApicMode = APIC_MODE_COMPAT;
|
||||
}
|
||||
|
||||
/* Get current processor number */
|
||||
CpuNumber = KeGetCurrentProcessorNumber();
|
||||
CpuNumber = KE::Processor::GetCurrentProcessorNumber();
|
||||
|
||||
/* Enable the APIC */
|
||||
BaseRegister.LongLong = ArReadModelSpecificRegister(APIC_LAPIC_MSR_BASE);
|
||||
BaseRegister.LongLong = AR::CpuFunc::ReadModelSpecificRegister(APIC_LAPIC_MSR_BASE);
|
||||
BaseRegister.Enable = 1;
|
||||
BaseRegister.ExtendedMode = (HlpApicMode == APIC_MODE_X2APIC);
|
||||
BaseRegister.ExtendedMode = (ApicMode == APIC_MODE_X2APIC);
|
||||
BaseRegister.BootStrapProcessor = (CpuNumber == 0) ? 1 : 0;
|
||||
ArWriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong);
|
||||
AR::CpuFunc::WriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong);
|
||||
|
||||
/* Mask all interrupts by raising Task Priority Register (TPR) */
|
||||
HlWriteApicRegister(APIC_TPR, 0xFF);
|
||||
WriteApicRegister(APIC_TPR, 0xFF);
|
||||
|
||||
/* Perform initialization specific to xAPIC compatibility mode */
|
||||
if(HlpApicMode == APIC_MODE_COMPAT)
|
||||
if(ApicMode == APIC_MODE_COMPAT)
|
||||
{
|
||||
/* Use Flat Model for destination format (not supported in x2APIC) */
|
||||
HlWriteApicRegister(APIC_DFR, APIC_DF_FLAT);
|
||||
WriteApicRegister(APIC_DFR, APIC_DF_FLAT);
|
||||
|
||||
/* Set the logical APIC ID for this processor (read-only in x2APIC) */
|
||||
HlWriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24);
|
||||
WriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24);
|
||||
}
|
||||
|
||||
/* Configure the spurious interrupt vector */
|
||||
SpuriousRegister.Long = HlReadApicRegister(APIC_SIVR);
|
||||
SpuriousRegister.Long = ReadApicRegister(APIC_SIVR);
|
||||
SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS;
|
||||
SpuriousRegister.SoftwareEnable = 1;
|
||||
SpuriousRegister.CoreChecking = 0;
|
||||
HlWriteApicRegister(APIC_SIVR, SpuriousRegister.Long);
|
||||
WriteApicRegister(APIC_SIVR, SpuriousRegister.Long);
|
||||
|
||||
/* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */
|
||||
HlWriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR);
|
||||
WriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR);
|
||||
|
||||
/* Program the APIC timer for periodic mode */
|
||||
LvtRegister.Long = 0;
|
||||
@@ -247,7 +176,7 @@ HlpInitializeApic(VOID)
|
||||
LvtRegister.TimerMode = 1;
|
||||
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||
LvtRegister.Vector = APIC_VECTOR_PROFILE;
|
||||
HlWriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
|
||||
WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
|
||||
|
||||
/* Configure the performance counter overflow */
|
||||
LvtRegister.Long = 0;
|
||||
@@ -256,7 +185,7 @@ HlpInitializeApic(VOID)
|
||||
LvtRegister.TimerMode = 0;
|
||||
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||
LvtRegister.Vector = APIC_VECTOR_PERF;
|
||||
HlWriteApicRegister(APIC_PCLVTR, LvtRegister.Long);
|
||||
WriteApicRegister(APIC_PCLVTR, LvtRegister.Long);
|
||||
|
||||
/* Configure the LINT0 pin */
|
||||
LvtRegister.Long = 0;
|
||||
@@ -265,7 +194,7 @@ HlpInitializeApic(VOID)
|
||||
LvtRegister.TimerMode = 0;
|
||||
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||
LvtRegister.Vector = APIC_VECTOR_SPURIOUS;
|
||||
HlWriteApicRegister(APIC_LINT0, LvtRegister.Long);
|
||||
WriteApicRegister(APIC_LINT0, LvtRegister.Long);
|
||||
|
||||
/* Configure the LINT1 pin */
|
||||
LvtRegister.Long = 0;
|
||||
@@ -274,17 +203,17 @@ HlpInitializeApic(VOID)
|
||||
LvtRegister.TimerMode = 0;
|
||||
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||
LvtRegister.Vector = APIC_VECTOR_NMI;
|
||||
HlWriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
||||
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
||||
|
||||
/* Register interrupt handlers */
|
||||
KeSetInterruptHandler(APIC_VECTOR_SPURIOUS, HlpHandleApicSpuriousService);
|
||||
KeSetInterruptHandler(PIC1_VECTOR_SPURIOUS, HlpHandlePicSpuriousService);
|
||||
KE::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService);
|
||||
KE::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService);
|
||||
|
||||
/* Clear any pre-existing errors */
|
||||
HlWriteApicRegister(APIC_ESR, 0);
|
||||
WriteApicRegister(APIC_ESR, 0);
|
||||
|
||||
/* Re-enable all interrupts by lowering the Task Priority Register */
|
||||
HlWriteApicRegister(APIC_TPR, 0x00);
|
||||
WriteApicRegister(APIC_TPR, 0x00);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,7 +225,7 @@ HlpInitializeApic(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HlpInitializeLegacyPic(VOID)
|
||||
HL::Pic::InitializeLegacyPic(VOID)
|
||||
{
|
||||
PIC_I8259_ICW1 Icw1;
|
||||
PIC_I8259_ICW2 Icw2;
|
||||
@@ -310,16 +239,16 @@ HlpInitializeLegacyPic(VOID)
|
||||
Icw1.Interval = Interval8;
|
||||
Icw1.NeedIcw4 = TRUE;
|
||||
Icw1.OperatingMode = Cascade;
|
||||
HlIoPortOutByte(PIC1_CONTROL_PORT, Icw1.Bits);
|
||||
HL::IoPort::WritePort8(PIC1_CONTROL_PORT, Icw1.Bits);
|
||||
|
||||
/* Initialize ICW2 for PIC1 port */
|
||||
Icw2.Bits = 0x00;
|
||||
HlIoPortOutByte(PIC1_DATA_PORT, Icw2.Bits);
|
||||
HL::IoPort::WritePort8(PIC1_DATA_PORT, Icw2.Bits);
|
||||
|
||||
/* Initialize ICW3 for PIC1 port */
|
||||
Icw3.Bits = 0;
|
||||
Icw3.SlaveIrq2 = TRUE;
|
||||
HlIoPortOutByte(PIC1_DATA_PORT, Icw3.Bits);
|
||||
HL::IoPort::WritePort8(PIC1_DATA_PORT, Icw3.Bits);
|
||||
|
||||
/* Initialize ICW4 for PIC1 port */
|
||||
Icw4.BufferedMode = NonBuffered;
|
||||
@@ -327,10 +256,10 @@ HlpInitializeLegacyPic(VOID)
|
||||
Icw4.Reserved = 0;
|
||||
Icw4.SpecialFullyNestedMode = FALSE;
|
||||
Icw4.SystemMode = New8086Mode;
|
||||
HlIoPortOutByte(PIC1_DATA_PORT, Icw4.Bits);
|
||||
HL::IoPort::WritePort8(PIC1_DATA_PORT, Icw4.Bits);
|
||||
|
||||
/* Mask all interrupts on PIC1 port */
|
||||
HlIoPortOutByte(PIC1_DATA_PORT, 0xFF);
|
||||
HL::IoPort::WritePort8(PIC1_DATA_PORT, 0xFF);
|
||||
|
||||
/* Initialize ICW1 for PIC2 port */
|
||||
Icw1.Init = TRUE;
|
||||
@@ -339,16 +268,16 @@ HlpInitializeLegacyPic(VOID)
|
||||
Icw1.Interval = Interval8;
|
||||
Icw1.NeedIcw4 = TRUE;
|
||||
Icw1.OperatingMode = Cascade;
|
||||
HlIoPortOutByte(PIC2_CONTROL_PORT, Icw1.Bits);
|
||||
HL::IoPort::WritePort8(PIC2_CONTROL_PORT, Icw1.Bits);
|
||||
|
||||
/* Initialize ICW2 for PIC2 port */
|
||||
Icw2.Bits = 0x08;
|
||||
HlIoPortOutByte(PIC2_DATA_PORT, Icw2.Bits);
|
||||
HL::IoPort::WritePort8(PIC2_DATA_PORT, Icw2.Bits);
|
||||
|
||||
/* Initialize ICW3 for PIC2 port */
|
||||
Icw3.Bits = 0;
|
||||
Icw3.SlaveId = 2;
|
||||
HlIoPortOutByte(PIC2_DATA_PORT, Icw3.Bits);
|
||||
HL::IoPort::WritePort8(PIC2_DATA_PORT, Icw3.Bits);
|
||||
|
||||
/* Initialize ICW4 for PIC2 port */
|
||||
Icw4.BufferedMode = NonBuffered;
|
||||
@@ -356,10 +285,10 @@ HlpInitializeLegacyPic(VOID)
|
||||
Icw4.Reserved = 0;
|
||||
Icw4.SpecialFullyNestedMode = FALSE;
|
||||
Icw4.SystemMode = New8086Mode;
|
||||
HlIoPortOutByte(PIC2_DATA_PORT, Icw4.Bits);
|
||||
HL::IoPort::WritePort8(PIC2_DATA_PORT, Icw4.Bits);
|
||||
|
||||
/* Mask all interrupts on PIC2 port */
|
||||
HlIoPortOutByte(PIC2_DATA_PORT, 0xFF);
|
||||
HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,13 +302,54 @@ HlpInitializeLegacyPic(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HlpInitializePic(VOID)
|
||||
HL::Pic::InitializePic(VOID)
|
||||
{
|
||||
/* Initialize APIC */
|
||||
HlpInitializeApic();
|
||||
InitializeApic();
|
||||
|
||||
/* Initialize legacy PIC */
|
||||
HlpInitializeLegacyPic();
|
||||
InitializeLegacyPic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads from the APIC register.
|
||||
*
|
||||
* @param Register
|
||||
* Supplies the APIC register to read from.
|
||||
*
|
||||
* @return This routine returns the value read from the APIC register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
ULONGLONG
|
||||
HL::Pic::ReadApicRegister(IN APIC_REGISTER Register)
|
||||
{
|
||||
if(ApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* Read from x2APIC MSR */
|
||||
return AR::CpuFunc::ReadModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read from xAPIC */
|
||||
return IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals to the APIC that handling an interrupt is complete.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Pic::SendEoi(VOID)
|
||||
{
|
||||
/* Send APIC EOI */
|
||||
WriteApicRegister(APIC_EOI, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,19 +367,49 @@ HlpInitializePic(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HlpSendIpi(ULONG ApicId,
|
||||
ULONG Vector)
|
||||
HL::Pic::SendIpi(ULONG ApicId,
|
||||
ULONG Vector)
|
||||
{
|
||||
/* Check current APIC mode */
|
||||
if(HlpApicMode == APIC_MODE_X2APIC)
|
||||
if(ApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* Send IPI using x2APIC mode */
|
||||
HlWriteApicRegister(APIC_ICR0, ((ULONGLONG)ApicId << 32) | Vector);
|
||||
WriteApicRegister(APIC_ICR0, ((ULONGLONG)ApicId << 32) | Vector);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send IPI using xAPIC compatibility mode */
|
||||
HlWriteApicRegister(APIC_ICR1, ApicId << 24);
|
||||
HlWriteApicRegister(APIC_ICR0, Vector);
|
||||
WriteApicRegister(APIC_ICR1, ApicId << 24);
|
||||
WriteApicRegister(APIC_ICR0, Vector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to the APIC register.
|
||||
*
|
||||
* @param Register
|
||||
* Supplies the APIC register to write to.
|
||||
*
|
||||
* @param Value
|
||||
* Supplies the value to write to the APIC register.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
HL::Pic::WriteApicRegister(IN APIC_REGISTER Register,
|
||||
IN ULONGLONG Value)
|
||||
{
|
||||
if(ApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* Write to x2APIC MSR */
|
||||
AR::CpuFunc::WriteModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register), Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write to xAPIC */
|
||||
IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user