Author: tkreuzer Date: Sat Sep 10 15:55:15 2011 New Revision: 53673
URL: http://svn.reactos.org/svn/reactos?rev=53673&view=rev Log: [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
Modified: trunk/reactos/hal/halx86/amd64/halinit.c trunk/reactos/hal/halx86/amd64/stubs.c trunk/reactos/hal/halx86/amd64/systimer.S trunk/reactos/hal/halx86/apic/apic.c trunk/reactos/hal/halx86/apic/halinit_apic.c
Modified: trunk/reactos/hal/halx86/amd64/halinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/amd64/halinit.c?... ============================================================================== --- trunk/reactos/hal/halx86/amd64/halinit.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/amd64/halinit.c [iso-8859-1] Sat Sep 10 15:55:15 2011 @@ -21,6 +21,23 @@ /* 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 @@
}
-VOID -INIT_FUNCTION -HalpInitializeClock(VOID) -{ -}
-VOID -HalpCalibrateStallExecution() -{ -} - -VOID -HalpInitializePICs(IN BOOLEAN EnableInterrupts) -{ -}
Modified: trunk/reactos/hal/halx86/amd64/stubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/amd64/stubs.c?re... ============================================================================== --- trunk/reactos/hal/halx86/amd64/stubs.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/amd64/stubs.c [iso-8859-1] Sat Sep 10 15:55:15 2011 @@ -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; -}
Modified: trunk/reactos/hal/halx86/amd64/systimer.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/amd64/systimer.S... ============================================================================== --- trunk/reactos/hal/halx86/amd64/systimer.S [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/amd64/systimer.S [iso-8859-1] Sat Sep 10 15:55:15 2011 @@ -23,70 +23,6 @@
.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
Modified: trunk/reactos/hal/halx86/apic/apic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/apic.c?rev=... ============================================================================== --- trunk/reactos/hal/halx86/apic/apic.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/apic/apic.c [iso-8859-1] Sat Sep 10 15:55:15 2011 @@ -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 @@ *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN) = Value; }
+VOID +FORCEINLINE +ApicSendEOI(void) +{ + //ApicWrite(APIC_EOI, 0); + HackEoi(); +} + KIRQL FORCEINLINE ApicGetProcessorIrql(VOID) @@ -113,24 +123,27 @@ 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 @@ FASTCALL HalpVectorToIrql(UCHAR Vector) { - return TprToIrql(Vector >> 2); + return TprToIrql(Vector); }
UCHAR @@ -248,6 +261,9 @@ SpIntRegister.SoftwareEnable = 1; 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 @@ ReDirReg.Destination = ApicRead(APIC_ID); IOApicWrite(IOAPIC_REDTBL + 2 * APIC_CLOCK_INDEX, ReDirReg.Long0);
+ ApicSendEOI(); }
VOID @@ -447,14 +464,22 @@
/* 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; @@ -466,11 +491,40 @@ 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,9 +534,12 @@ HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame) { KIRQL OldIrql = ApicGetCurrentIrql(); -__debugbreak(); + ASSERT(OldIrql < DISPATCH_LEVEL); ASSERT(ApicGetProcessorIrql() == DISPATCH_LEVEL); + + /* Enter trap */ + KiEnterInterruptTrap(TrapFrame);
ApicSetCurrentIrql(DISPATCH_LEVEL);
@@ -493,12 +550,19 @@
ApicSetCurrentIrql(OldIrql);
- ApicWrite(APIC_EOI, 0); + ApicSendEOI();
/* Exit the interrupt */ KiEoiHelper(TrapFrame); } #endif + +VOID +NTAPI +HalpSendEOI(VOID) +{ + ApicSendEOI(); +}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -580,14 +644,6 @@ 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 @@ 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);
Modified: trunk/reactos/hal/halx86/apic/halinit_apic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/halinit_api... ============================================================================== --- trunk/reactos/hal/halx86/apic/halinit_apic.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/apic/halinit_apic.c [iso-8859-1] Sat Sep 10 15:55:15 2011 @@ -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 @@ HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock) {
+ /* Enable clock interrupt handler */ + HalpEnableInterruptHandler(IDT_INTERNAL, + 0, + APIC_CLOCK_VECTOR, + CLOCK2_LEVEL, + HalpClockInterrupt, + Latched); }
VOID