summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp')
-rw-r--r--src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
index b870cb0c7..1615ac7ab 100644
--- a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
@@ -56,6 +56,14 @@ RTCPUSET g_rtMpNtCpuSet;
PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
/** KeFlushQueuedDpcs, introduced in XP. */
PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
+/** HalRequestIpi, introduced in ??. */
+PFNHALREQUESTIPI g_pfnrtNtHalRequestIpi;
+/** HalSendSoftwareInterrupt */
+PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt;
+/** SendIpi handler based on Windows version */
+PFNRTSENDIPI g_pfnrtSendIpi;
+/** KeIpiGenericCall - Windows Server 2003+ only */
+PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall;
/** Offset of the _KPRCB::QuantumEnd field. 0 if not found. */
uint32_t g_offrtNtPbQuantumEnd;
@@ -82,6 +90,9 @@ int rtR0InitNative(void)
#ifdef IPRT_TARGET_NT4
g_pfnrtNtExSetTimerResolution = NULL;
g_pfnrtNtKeFlushQueuedDpcs = NULL;
+ g_pfnrtNtHalRequestIpi = NULL;
+ g_pfnrtNtHalSendSoftwareInterrupt = NULL;
+ g_pfnrtKeIpiGenericCall = NULL;
#else
/*
* Initialize the function pointers.
@@ -92,6 +103,15 @@ int rtR0InitNative(void)
RtlInitUnicodeString(&RoutineName, L"KeFlushQueuedDpcs");
g_pfnrtNtKeFlushQueuedDpcs = (PFNMYKEFLUSHQUEUEDDPCS)MmGetSystemRoutineAddress(&RoutineName);
+
+ RtlInitUnicodeString(&RoutineName, L"HalRequestIpi");
+ g_pfnrtNtHalRequestIpi = (PFNHALREQUESTIPI)MmGetSystemRoutineAddress(&RoutineName);
+
+ RtlInitUnicodeString(&RoutineName, L"HalSendSoftwareInterrupt");
+ g_pfnrtNtHalSendSoftwareInterrupt = (PFNHALSENDSOFTWAREINTERRUPT)MmGetSystemRoutineAddress(&RoutineName);
+
+ RtlInitUnicodeString(&RoutineName, L"KeIpiGenericCall");
+ g_pfnrtKeIpiGenericCall = (PFNRTKEIPIGENERICCALL)MmGetSystemRoutineAddress(&RoutineName);
#endif
/*
@@ -102,6 +122,25 @@ int rtR0InitNative(void)
ULONG BuildNumber = 0;
BOOLEAN fChecked = PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, NULL);
+ g_pfnrtSendIpi = rtMpSendIpiDummy;
+#ifndef IPRT_TARGET_NT4
+ if ( g_pfnrtNtHalRequestIpi
+ && MajorVersion == 6
+ && MinorVersion == 0)
+ {
+ /* Vista or Windows Server 2008 */
+ g_pfnrtSendIpi = rtMpSendIpiVista;
+ }
+ else
+ if ( g_pfnrtNtHalSendSoftwareInterrupt
+ && MajorVersion == 6
+ && MinorVersion == 1)
+ {
+ /* Windows 7 or Windows Server 2008 R2 */
+ g_pfnrtSendIpi = rtMpSendIpiWin7;
+ }
+ /* Windows XP should send always send an IPI -> VERIFY */
+#endif
KIRQL OldIrql;
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); /* make sure we stay on the same cpu */