mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +00:00
[HAL/APIC]
- Implement HalpApcInterruptHandler, fix HalpDispatchInterruptHandler - Insert a read to the APIC version register in ApicGetCurrentIrql(). This fixes inconsistencies between the internal APIC state and register reads/writes. - Remove old hacks in ApicGetCurrentIrql() and ApicSetCurrentIrql - Fix HalpVectorToIrql() - read/write cr8 for the value of the TPR on amd64 builds - Fix amd64 build svn path=/trunk/; revision=53673
This commit is contained in:
parent
ac09e360bb
commit
459b5c212e
5 changed files with 113 additions and 204 deletions
|
@ -20,6 +20,23 @@ BOOLEAN HalpPciLockSettings;
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpInitProcessor(
|
||||
IN ULONG ProcessorNumber,
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
DPRINT1("ApicInitializeProcessor(%ld)\n", ProcessorNumber);
|
||||
|
||||
/* Initialize the local APIC for this cpu */
|
||||
ApicInitializeLocalApic(ProcessorNumber);
|
||||
|
||||
/* Initialize the timer */
|
||||
//ApicInitializeTimer(ProcessorNumber);
|
||||
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
|
@ -32,18 +49,4 @@ HalpInitPhase1(VOID)
|
|||
|
||||
}
|
||||
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
HalpInitializeClock(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpCalibrateStallExecution()
|
||||
{
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpInitializePICs(IN BOOLEAN EnableInterrupts)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -14,99 +14,8 @@
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
LARGE_INTEGER HalpPerformanceFrequency;
|
||||
//LARGE_INTEGER HalpPerformanceFrequency;
|
||||
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
HalClearSoftwareInterrupt(
|
||||
IN KIRQL Irql)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
HalRequestSoftwareInterrupt(
|
||||
IN KIRQL Irql)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalBeginSystemInterrupt(
|
||||
IN KIRQL Irql,
|
||||
IN UCHAR Vector,
|
||||
OUT PKIRQL OldIrql)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalEnableSystemInterrupt(
|
||||
IN UCHAR Vector,
|
||||
IN KIRQL Irql,
|
||||
IN KINTERRUPT_MODE InterruptMode)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalDisableSystemInterrupt(
|
||||
IN UCHAR Vector,
|
||||
IN KIRQL Irql)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalEndSystemInterrupt(
|
||||
IN KIRQL OldIrql,
|
||||
IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
LARGE_INTEGER
|
||||
NTAPI
|
||||
KeQueryPerformanceCounter(
|
||||
OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
|
||||
{
|
||||
LARGE_INTEGER Result;
|
||||
|
||||
// ASSERT(HalpPerformanceFrequency.QuadPart != 0);
|
||||
|
||||
/* Does the caller want the frequency? */
|
||||
if (PerformanceFrequency)
|
||||
{
|
||||
/* Return value */
|
||||
*PerformanceFrequency = HalpPerformanceFrequency;
|
||||
}
|
||||
|
||||
Result.QuadPart = __rdtsc();
|
||||
return Result;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalCalibratePerformanceCounter(IN volatile PLONG Count,
|
||||
IN ULONGLONG NewCount)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
HalSetTimeIncrement(IN ULONG Increment)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,70 +23,6 @@ MsgUnimplemented:
|
|||
|
||||
.code64
|
||||
|
||||
PUBLIC HalpCalibrateStallExecution@0
|
||||
HalpCalibrateStallExecution@0:
|
||||
|
||||
|
||||
PUBLIC HalpProfileInterrupt
|
||||
HalpProfileInterrupt:
|
||||
|
||||
|
||||
PUBLIC KeStallExecutionProcessor
|
||||
KeStallExecutionProcessor:
|
||||
|
||||
/* Get the number of microseconds required */
|
||||
jecxz Done
|
||||
|
||||
/* Multiply by the stall factor */
|
||||
mov eax, gs:[PcStallScaleFactor]
|
||||
mul ecx
|
||||
|
||||
/* Align to 16 bytes */
|
||||
.align 16
|
||||
|
||||
/* Jump to subtraction loop */
|
||||
jmp SubtractLoop
|
||||
|
||||
/* Align to 16 bytes */
|
||||
.align 16
|
||||
|
||||
/* Subtract one count */
|
||||
SubtractLoop:
|
||||
sub eax, 1
|
||||
jnz SubtractLoop
|
||||
|
||||
Done:
|
||||
/* Return */
|
||||
ret 4
|
||||
|
||||
|
||||
PUBLIC HalpQuery8254Counter
|
||||
HalpQuery8254Counter:
|
||||
|
||||
/* Save EFLAGS and disable interrupts */
|
||||
pushfq
|
||||
cli
|
||||
|
||||
/* Set timer data */
|
||||
mov al, 0
|
||||
out HEX(43), al
|
||||
jmp $+2
|
||||
|
||||
/* Read current timer */
|
||||
in al, HEX(40)
|
||||
jmp $+2
|
||||
movzx ecx, al
|
||||
in al, HEX(40)
|
||||
mov ch, al
|
||||
|
||||
/* Return it and restore interrupt state */
|
||||
mov eax, ecx
|
||||
popfq
|
||||
ret
|
||||
|
||||
PUBLIC HalpClockInterrupt
|
||||
HalpClockInterrupt:
|
||||
UNIMPLEMENTED _HalpClockInterrupt
|
||||
iret
|
||||
|
||||
END
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
#include <debug.h>
|
||||
|
||||
#include "apic.h"
|
||||
void HackEoi(void);
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
ULONG ApicVersion;
|
||||
UCHAR HalpVectorToIndex[256];
|
||||
|
||||
#ifndef _M_AMD64
|
||||
|
@ -101,6 +103,14 @@ IOApicWrite(UCHAR Register, ULONG Value)
|
|||
*(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN) = Value;
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
ApicSendEOI(void)
|
||||
{
|
||||
//ApicWrite(APIC_EOI, 0);
|
||||
HackEoi();
|
||||
}
|
||||
|
||||
KIRQL
|
||||
FORCEINLINE
|
||||
ApicGetProcessorIrql(VOID)
|
||||
|
@ -113,24 +123,27 @@ KIRQL
|
|||
FORCEINLINE
|
||||
ApicGetCurrentIrql(VOID)
|
||||
{
|
||||
// HACK: This won't work with amd64, where cr8 is modified directly, but
|
||||
// VBox is broken and returns a wrong value when using a vmmcall after a
|
||||
// page table modification.
|
||||
return KeGetPcr()->Irql;
|
||||
#ifdef _M_AMD64
|
||||
return (KIRQL)__readcr8();
|
||||
#else
|
||||
// HACK: some magic to Sync VBox's APIC registers
|
||||
ApicRead(APIC_VER);
|
||||
|
||||
/* Read the TPR and convert it to an IRQL */
|
||||
return TprToIrql(ApicRead(APIC_TPR));
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
ApicSetCurrentIrql(KIRQL Irql)
|
||||
{
|
||||
#ifdef _M_AMD64
|
||||
__writecr8(Irql);
|
||||
#else
|
||||
/* Convert IRQL and write the TPR */
|
||||
ApicWrite(APIC_TPR, IrqlToTpr(Irql));
|
||||
|
||||
/* HACK: Keep PCR field in sync, s.a. */
|
||||
KeGetPcr()->Irql = Irql;
|
||||
#endif
|
||||
}
|
||||
|
||||
UCHAR
|
||||
|
@ -150,7 +163,7 @@ KIRQL
|
|||
FASTCALL
|
||||
HalpVectorToIrql(UCHAR Vector)
|
||||
{
|
||||
return TprToIrql(Vector >> 2);
|
||||
return TprToIrql(Vector);
|
||||
}
|
||||
|
||||
UCHAR
|
||||
|
@ -249,6 +262,9 @@ ApicInitializeLocalApic(ULONG Cpu)
|
|||
SpIntRegister.FocusCPUCoreChecking = 0;
|
||||
ApicWrite(APIC_SIVR, SpIntRegister.Long);
|
||||
|
||||
/* Read the version and save it globally */
|
||||
if (Cpu == 0) ApicVersion = ApicRead(APIC_VER);
|
||||
|
||||
/* Set the mode to flat (max 8 CPUs supported!) */
|
||||
ApicWrite(APIC_DFR, APIC_DF_Flat);
|
||||
|
||||
|
@ -430,6 +446,7 @@ ApicInitializeIOApic(VOID)
|
|||
ReDirReg.Destination = ApicRead(APIC_ID);
|
||||
IOApicWrite(IOAPIC_REDTBL + 2 * APIC_CLOCK_INDEX, ReDirReg.Long0);
|
||||
|
||||
ApicSendEOI();
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -447,15 +464,23 @@ HalpInitializePICs(IN BOOLEAN EnableInterrupts)
|
|||
|
||||
/* Initialize the I/O APIC */
|
||||
ApicInitializeIOApic();
|
||||
ApicWrite(APIC_EOI, 0);
|
||||
|
||||
/* Register interrupt handlers */
|
||||
/* Manually reserve some vectors */
|
||||
HalpVectorToIndex[APIC_CLOCK_VECTOR] = 8;
|
||||
HalpVectorToIndex[APC_VECTOR] = 99;
|
||||
HalpVectorToIndex[DISPATCH_VECTOR] = 99;
|
||||
|
||||
/* Set interrupt handlers in the IDT */
|
||||
KeRegisterInterruptHandler(APIC_CLOCK_VECTOR, HalpClockInterrupt);
|
||||
#ifndef _M_AMD64
|
||||
KeRegisterInterruptHandler(APC_VECTOR, HalpApcInterrupt);
|
||||
KeRegisterInterruptHandler(DPC_VECTOR, HalpDispatchInterrupt);
|
||||
KeRegisterInterruptHandler(DISPATCH_VECTOR, HalpDispatchInterrupt);
|
||||
#endif
|
||||
|
||||
/* Register the vectors for APC and dispatch interrupts */
|
||||
HalpRegisterVector(IDT_INTERNAL, 0, APC_VECTOR, APC_LEVEL);
|
||||
HalpRegisterVector(IDT_INTERNAL, 0, DISPATCH_VECTOR, DISPATCH_LEVEL);
|
||||
|
||||
/* Restore interrupt state */
|
||||
if (EnableInterrupts) EFlags |= EFLAGS_INTERRUPT_MASK;
|
||||
__writeeflags(EFlags);
|
||||
|
@ -466,11 +491,40 @@ DECLSPEC_NORETURN
|
|||
FASTCALL
|
||||
HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
KPROCESSOR_MODE ProcessorMode;
|
||||
KIRQL OldIrql;
|
||||
ASSERT(ApicGetCurrentIrql() < APC_LEVEL);
|
||||
ASSERT(ApicGetProcessorIrql() == APC_LEVEL);
|
||||
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
/* Enter trap */
|
||||
KiEnterInterruptTrap(TrapFrame);
|
||||
|
||||
/* Save the old IRQL */
|
||||
OldIrql = ApicGetCurrentIrql();
|
||||
|
||||
/* Set APC_LEVEL */
|
||||
ApicSetCurrentIrql(APC_LEVEL);
|
||||
|
||||
/* Kernel or user APC? */
|
||||
if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
|
||||
else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
|
||||
else ProcessorMode = KernelMode;
|
||||
|
||||
/* Enable interrupts and call the kernel's APC interrupt handler */
|
||||
_enable();
|
||||
KiDeliverApc(ProcessorMode, NULL, TrapFrame);
|
||||
|
||||
/* Disable interrupts */
|
||||
_disable();
|
||||
|
||||
/* Restore the old IRQL */
|
||||
ApicSetCurrentIrql(OldIrql);
|
||||
|
||||
/* End the interrupt */
|
||||
ApicSendEOI();
|
||||
|
||||
/* Exit the interrupt */
|
||||
KiEoiHelper(TrapFrame);
|
||||
}
|
||||
|
||||
#ifndef _M_AMD64
|
||||
|
@ -480,10 +534,13 @@ FASTCALL
|
|||
HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
KIRQL OldIrql = ApicGetCurrentIrql();
|
||||
__debugbreak();
|
||||
|
||||
ASSERT(OldIrql < DISPATCH_LEVEL);
|
||||
ASSERT(ApicGetProcessorIrql() == DISPATCH_LEVEL);
|
||||
|
||||
/* Enter trap */
|
||||
KiEnterInterruptTrap(TrapFrame);
|
||||
|
||||
ApicSetCurrentIrql(DISPATCH_LEVEL);
|
||||
|
||||
/* Enable interrupts and call the kernel's DPC interrupt handler */
|
||||
|
@ -493,13 +550,20 @@ __debugbreak();
|
|||
|
||||
ApicSetCurrentIrql(OldIrql);
|
||||
|
||||
ApicWrite(APIC_EOI, 0);
|
||||
ApicSendEOI();
|
||||
|
||||
/* Exit the interrupt */
|
||||
KiEoiHelper(TrapFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpSendEOI(VOID)
|
||||
{
|
||||
ApicSendEOI();
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
VOID
|
||||
|
@ -580,14 +644,6 @@ HalDisableSystemInterrupt(
|
|||
IOApicWrite(IOAPIC_REDTBL + 2 * Irql, ReDirReg.Long0);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpSendEOI(VOID)
|
||||
{
|
||||
/* Write 0 to the EndOfInterruptRegister */
|
||||
ApicWrite(APIC_EOI, 0);
|
||||
}
|
||||
|
||||
#ifndef _M_AMD64
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
|
@ -609,19 +665,14 @@ HalBeginSystemInterrupt(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void HackEoi(void);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalEndSystemInterrupt(
|
||||
IN KIRQL OldIrql,
|
||||
IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Write 0 to the EndOfInterruptRegister */
|
||||
//ApicWrite(APIC_EOI, 0);
|
||||
|
||||
// HACK!
|
||||
HackEoi();
|
||||
/* Send an EOI */
|
||||
ApicSendEOI();
|
||||
|
||||
/* Restore the old IRQL */
|
||||
ApicSetCurrentIrql(OldIrql);
|
||||
|
|
|
@ -4,9 +4,7 @@
|
|||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/halinit.c
|
||||
* PURPOSE: Initalize the x86 hal
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
* UPDATE HISTORY:
|
||||
* 11/06/98: Created
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -14,12 +12,17 @@
|
|||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#include "apic.h"
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ApicInitializeLocalApic(ULONG Cpu);
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
const USHORT HalpBuildType = HAL_BUILD_TYPE;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
|
@ -39,6 +42,13 @@ VOID
|
|||
HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
|
||||
/* Enable clock interrupt handler */
|
||||
HalpEnableInterruptHandler(IDT_INTERNAL,
|
||||
0,
|
||||
APIC_CLOCK_VECTOR,
|
||||
CLOCK2_LEVEL,
|
||||
HalpClockInterrupt,
|
||||
Latched);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
Loading…
Reference in a new issue