diff --git a/hal/halx86/apic/apic.c b/hal/halx86/apic/apic.c index 0c563c335d5..8ab184e917c 100644 --- a/hal/halx86/apic/apic.c +++ b/hal/halx86/apic/apic.c @@ -528,10 +528,12 @@ HalpInitializePICs(IN BOOLEAN EnableInterrupts) HalpVectorToIndex[APC_VECTOR] = APIC_RESERVED_VECTOR; HalpVectorToIndex[DISPATCH_VECTOR] = APIC_RESERVED_VECTOR; HalpVectorToIndex[APIC_CLOCK_VECTOR] = 8; + HalpVectorToIndex[CLOCK_IPI_VECTOR] = APIC_RESERVED_VECTOR; HalpVectorToIndex[APIC_SPURIOUS_VECTOR] = APIC_RESERVED_VECTOR; /* Set interrupt handlers in the IDT */ KeRegisterInterruptHandler(APIC_CLOCK_VECTOR, HalpClockInterrupt); + KeRegisterInterruptHandler(CLOCK_IPI_VECTOR, HalpClockIpi); #ifndef _M_AMD64 KeRegisterInterruptHandler(APC_VECTOR, HalpApcInterrupt); KeRegisterInterruptHandler(DISPATCH_VECTOR, HalpDispatchInterrupt); diff --git a/hal/halx86/apic/apicp.h b/hal/halx86/apic/apicp.h index e723a4f0696..e794fa9131b 100644 --- a/hal/halx86/apic/apicp.h +++ b/hal/halx86/apic/apicp.h @@ -43,6 +43,7 @@ #define APIC_GENERIC_VECTOR 0xC1 // IRQL 27 #define APIC_CLOCK_VECTOR 0xD1 // IRQL 28 #define APIC_SYNCH_VECTOR 0xD1 // IRQL 28 + #define CLOCK_IPI_VECTOR 0xD2 // IRQL 28 #define APIC_IPI_VECTOR 0xE1 // IRQL 29 #define APIC_ERROR_VECTOR 0xE3 #define POWERFAIL_VECTOR 0xEF // IRQL 30 diff --git a/hal/halx86/apic/apictrap.S b/hal/halx86/apic/apictrap.S index 381f5492023..e62ffc0b471 100644 --- a/hal/halx86/apic/apictrap.S +++ b/hal/halx86/apic/apictrap.S @@ -16,6 +16,7 @@ .code TRAP_ENTRY HalpClockInterrupt, (TF_VOLATILES OR TF_SEND_EOI) +TRAP_ENTRY HalpClockIpi, (TF_VOLATILES OR TF_SEND_EOI) TRAP_ENTRY HalpProfileInterrupt, (TF_VOLATILES OR TF_SEND_EOI) PUBLIC ApicSpuriousService @@ -28,6 +29,7 @@ ApicSpuriousService: .code TRAP_ENTRY HalpClockInterrupt, KI_PUSH_FAKE_ERROR_CODE +TRAP_ENTRY HalpClockIpi, KI_PUSH_FAKE_ERROR_CODE TRAP_ENTRY HalpProfileInterrupt, KI_PUSH_FAKE_ERROR_CODE TRAP_ENTRY HalpTrap0D, 0 TRAP_ENTRY HalpApcInterrupt, KI_PUSH_FAKE_ERROR_CODE diff --git a/hal/halx86/apic/rtctimer.c b/hal/halx86/apic/rtctimer.c index 50b50248366..30058baebdd 100644 --- a/hal/halx86/apic/rtctimer.c +++ b/hal/halx86/apic/rtctimer.c @@ -13,6 +13,7 @@ #include #include "apicp.h" +#include #define NDEBUG #include @@ -182,10 +183,40 @@ HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame) HalpSetClockRate = FALSE; } + /* Send the clock IPI to all other CPUs */ + HalpBroadcastClockIpi(CLOCK_IPI_VECTOR); + /* Update the system time -- on x86 the kernel will exit this trap */ KeUpdateSystemTime(TrapFrame, LastIncrement, Irql); } +VOID +FASTCALL +HalpClockIpiHandler(IN PKTRAP_FRAME TrapFrame) +{ + KIRQL Irql; + + /* Enter trap */ + KiEnterInterruptTrap(TrapFrame); +#ifdef _M_AMD64 + /* This is for debugging */ + TrapFrame->ErrorCode = 0xc10c4; +#endif + + /* Start the interrupt */ + if (!HalBeginSystemInterrupt(CLOCK_LEVEL, CLOCK_IPI_VECTOR, &Irql)) + { + /* Spurious, just end the interrupt */ + KiEoiHelper(TrapFrame); + } + + /* Call the kernel to update runtimes */ + KeUpdateRunTime(TrapFrame, Irql); + + /* End the interrupt */ + KiEndInterrupt(Irql, TrapFrame); +} + ULONG NTAPI HalSetTimeIncrement(IN ULONG Increment) diff --git a/hal/halx86/generic/up.c b/hal/halx86/generic/up.c index 9e42e6f786b..6ea91e32edd 100644 --- a/hal/halx86/generic/up.c +++ b/hal/halx86/generic/up.c @@ -40,6 +40,14 @@ HalpSetupProcessorsTable( NOTHING; } +VOID +FASTCALL +HalpBroadcastClockIpi( + _In_ UCHAR Vector) +{ + NOTHING; +} + #ifdef _M_AMD64 VOID diff --git a/hal/halx86/include/halp.h b/hal/halx86/include/halp.h index 72e09fdb28f..c1ee6a67cae 100644 --- a/hal/halx86/include/halp.h +++ b/hal/halx86/include/halp.h @@ -235,6 +235,7 @@ extern BOOLEAN HalpProfilingStopped; /* timer.c */ CODE_SEG("INIT") VOID NTAPI HalpInitializeClock(VOID); VOID __cdecl HalpClockInterrupt(VOID); +VOID __cdecl HalpClockIpi(VOID); VOID __cdecl HalpProfileInterrupt(VOID); typedef struct _HALP_ROLLOVER @@ -513,6 +514,12 @@ KeUpdateSystemTime( IN KIRQL OldIrql ); +VOID +NTAPI +KeUpdateRunTime( + _In_ PKTRAP_FRAME TrapFrame, + _In_ KIRQL Irql); + CODE_SEG("INIT") VOID NTAPI diff --git a/hal/halx86/include/smp.h b/hal/halx86/include/smp.h index 3b98c788ab9..7efa12afc39 100644 --- a/hal/halx86/include/smp.h +++ b/hal/halx86/include/smp.h @@ -42,6 +42,11 @@ HalpSetupProcessorsTable( VOID HalpPrintApicTables(VOID); +VOID +FASTCALL +HalpBroadcastClockIpi( + _In_ UCHAR Vector); + /* APIC specific functions inside apic/apicsmp.c */ VOID diff --git a/hal/halx86/smp/smp.c b/hal/halx86/smp/smp.c index 780de6ab53a..433e65470ed 100644 --- a/hal/halx86/smp/smp.c +++ b/hal/halx86/smp/smp.c @@ -33,3 +33,12 @@ HalpSetupProcessorsTable( CurrentPrcb = KeGetCurrentPrcb(); HalpProcessorIdentity[NTProcessorNumber].ProcessorPrcb = CurrentPrcb; } + +VOID +FASTCALL +HalpBroadcastClockIpi( + _In_ UCHAR Vector) +{ + /* Send a clock IPI to all processors */ + HalpBroadcastIpiSpecifyVector(Vector, FALSE); +}