[HALX86] Implement the clock IPI handler

This commit is contained in:
Timo Kreuzer 2024-02-24 12:05:12 +02:00
parent d1c118b371
commit 79aaee6aac
8 changed files with 65 additions and 0 deletions

View file

@ -528,10 +528,12 @@ HalpInitializePICs(IN BOOLEAN EnableInterrupts)
HalpVectorToIndex[APC_VECTOR] = APIC_RESERVED_VECTOR; HalpVectorToIndex[APC_VECTOR] = APIC_RESERVED_VECTOR;
HalpVectorToIndex[DISPATCH_VECTOR] = APIC_RESERVED_VECTOR; HalpVectorToIndex[DISPATCH_VECTOR] = APIC_RESERVED_VECTOR;
HalpVectorToIndex[APIC_CLOCK_VECTOR] = 8; HalpVectorToIndex[APIC_CLOCK_VECTOR] = 8;
HalpVectorToIndex[CLOCK_IPI_VECTOR] = APIC_RESERVED_VECTOR;
HalpVectorToIndex[APIC_SPURIOUS_VECTOR] = APIC_RESERVED_VECTOR; HalpVectorToIndex[APIC_SPURIOUS_VECTOR] = APIC_RESERVED_VECTOR;
/* Set interrupt handlers in the IDT */ /* Set interrupt handlers in the IDT */
KeRegisterInterruptHandler(APIC_CLOCK_VECTOR, HalpClockInterrupt); KeRegisterInterruptHandler(APIC_CLOCK_VECTOR, HalpClockInterrupt);
KeRegisterInterruptHandler(CLOCK_IPI_VECTOR, HalpClockIpi);
#ifndef _M_AMD64 #ifndef _M_AMD64
KeRegisterInterruptHandler(APC_VECTOR, HalpApcInterrupt); KeRegisterInterruptHandler(APC_VECTOR, HalpApcInterrupt);
KeRegisterInterruptHandler(DISPATCH_VECTOR, HalpDispatchInterrupt); KeRegisterInterruptHandler(DISPATCH_VECTOR, HalpDispatchInterrupt);

View file

@ -43,6 +43,7 @@
#define APIC_GENERIC_VECTOR 0xC1 // IRQL 27 #define APIC_GENERIC_VECTOR 0xC1 // IRQL 27
#define APIC_CLOCK_VECTOR 0xD1 // IRQL 28 #define APIC_CLOCK_VECTOR 0xD1 // IRQL 28
#define APIC_SYNCH_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_IPI_VECTOR 0xE1 // IRQL 29
#define APIC_ERROR_VECTOR 0xE3 #define APIC_ERROR_VECTOR 0xE3
#define POWERFAIL_VECTOR 0xEF // IRQL 30 #define POWERFAIL_VECTOR 0xEF // IRQL 30

View file

@ -16,6 +16,7 @@
.code .code
TRAP_ENTRY HalpClockInterrupt, (TF_VOLATILES OR TF_SEND_EOI) 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) TRAP_ENTRY HalpProfileInterrupt, (TF_VOLATILES OR TF_SEND_EOI)
PUBLIC ApicSpuriousService PUBLIC ApicSpuriousService
@ -28,6 +29,7 @@ ApicSpuriousService:
.code .code
TRAP_ENTRY HalpClockInterrupt, KI_PUSH_FAKE_ERROR_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 HalpProfileInterrupt, KI_PUSH_FAKE_ERROR_CODE
TRAP_ENTRY HalpTrap0D, 0 TRAP_ENTRY HalpTrap0D, 0
TRAP_ENTRY HalpApcInterrupt, KI_PUSH_FAKE_ERROR_CODE TRAP_ENTRY HalpApcInterrupt, KI_PUSH_FAKE_ERROR_CODE

View file

@ -13,6 +13,7 @@
#include <hal.h> #include <hal.h>
#include "apicp.h" #include "apicp.h"
#include <smp.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
@ -182,10 +183,40 @@ HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame)
HalpSetClockRate = FALSE; 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 */ /* Update the system time -- on x86 the kernel will exit this trap */
KeUpdateSystemTime(TrapFrame, LastIncrement, Irql); 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 ULONG
NTAPI NTAPI
HalSetTimeIncrement(IN ULONG Increment) HalSetTimeIncrement(IN ULONG Increment)

View file

@ -40,6 +40,14 @@ HalpSetupProcessorsTable(
NOTHING; NOTHING;
} }
VOID
FASTCALL
HalpBroadcastClockIpi(
_In_ UCHAR Vector)
{
NOTHING;
}
#ifdef _M_AMD64 #ifdef _M_AMD64
VOID VOID

View file

@ -235,6 +235,7 @@ extern BOOLEAN HalpProfilingStopped;
/* timer.c */ /* timer.c */
CODE_SEG("INIT") VOID NTAPI HalpInitializeClock(VOID); CODE_SEG("INIT") VOID NTAPI HalpInitializeClock(VOID);
VOID __cdecl HalpClockInterrupt(VOID); VOID __cdecl HalpClockInterrupt(VOID);
VOID __cdecl HalpClockIpi(VOID);
VOID __cdecl HalpProfileInterrupt(VOID); VOID __cdecl HalpProfileInterrupt(VOID);
typedef struct _HALP_ROLLOVER typedef struct _HALP_ROLLOVER
@ -513,6 +514,12 @@ KeUpdateSystemTime(
IN KIRQL OldIrql IN KIRQL OldIrql
); );
VOID
NTAPI
KeUpdateRunTime(
_In_ PKTRAP_FRAME TrapFrame,
_In_ KIRQL Irql);
CODE_SEG("INIT") CODE_SEG("INIT")
VOID VOID
NTAPI NTAPI

View file

@ -42,6 +42,11 @@ HalpSetupProcessorsTable(
VOID VOID
HalpPrintApicTables(VOID); HalpPrintApicTables(VOID);
VOID
FASTCALL
HalpBroadcastClockIpi(
_In_ UCHAR Vector);
/* APIC specific functions inside apic/apicsmp.c */ /* APIC specific functions inside apic/apicsmp.c */
VOID VOID

View file

@ -33,3 +33,12 @@ HalpSetupProcessorsTable(
CurrentPrcb = KeGetCurrentPrcb(); CurrentPrcb = KeGetCurrentPrcb();
HalpProcessorIdentity[NTProcessorNumber].ProcessorPrcb = CurrentPrcb; HalpProcessorIdentity[NTProcessorNumber].ProcessorPrcb = CurrentPrcb;
} }
VOID
FASTCALL
HalpBroadcastClockIpi(
_In_ UCHAR Vector)
{
/* Send a clock IPI to all processors */
HalpBroadcastIpiSpecifyVector(Vector, FALSE);
}