Author: ros-arm-bringup
Date: Sat Jan 2 05:48:22 2010
New Revision: 44877
URL:
http://svn.reactos.org/svn/reactos?rev=44877&view=rev
Log:
NMI Support Patch 12:
[NTOS]: Implement KeRegisterNMICallback.
[NTOS]: Call and implement KiHandleNMI to call all registered NMI callbacks and
potentially resume from the NMI if handled.
Modified:
trunk/reactos/ntoskrnl/include/internal/ke.h
trunk/reactos/ntoskrnl/include/internal/ke_x.h
trunk/reactos/ntoskrnl/ke/bug.c
trunk/reactos/ntoskrnl/ke/i386/trap.s
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Sat Jan 2 05:48:22 2010
@@ -63,6 +63,14 @@
PKDEFERRED_ROUTINE Routine;
PVOID Context;
} DPC_QUEUE_ENTRY, *PDPC_QUEUE_ENTRY;
+
+typedef struct _KNMI_HANDLER_CALLBACK
+{
+ struct _KNMI_HANDLER_CALLBACK* Next;
+ PNMI_CALLBACK Callback;
+ PVOID Context;
+ PVOID Handle;
+} KNMI_HANDLER_CALLBACK, *PKNMI_HANDLER_CALLBACK;
typedef PCHAR
(NTAPI *PKE_BUGCHECK_UNICODE_TO_ANSI)(
Modified: trunk/reactos/ntoskrnl/include/internal/ke_x.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke_x.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke_x.h [iso-8859-1] Sat Jan 2 05:48:22 2010
@@ -1758,3 +1758,18 @@
GuardedMutex->SpecialApcDisable = Thread->SpecialApcDisable;
return TRUE;
}
+
+
+FORCEINLINE
+VOID
+KiAcquireNmiListLock(OUT PKIRQL OldIrql)
+{
+ KeAcquireSpinLock(&KiNmiCallbackListLock, OldIrql);
+}
+
+FORCEINLINE
+VOID
+KiReleaseNmiListLock(IN KIRQL OldIrql)
+{
+ KeReleaseSpinLock(&KiNmiCallbackListLock, OldIrql);
+}
Modified: trunk/reactos/ntoskrnl/ke/bug.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/bug.c?rev=4487…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/bug.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/bug.c [iso-8859-1] Sat Jan 2 05:48:22 2010
@@ -28,6 +28,8 @@
ULONG KiHardwareTrigger;
PUNICODE_STRING KiBugCheckDriver;
ULONG_PTR KiBugCheckData[5];
+PKNMI_HANDLER_CALLBACK KiNmiCallbackListHead;
+KSPIN_LOCK KiNmiCallbackListLock;
/* Bugzilla Reporting */
UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion;
@@ -1208,6 +1210,32 @@
while (TRUE);
}
+BOOLEAN
+NTAPI
+KiHandleNmi(VOID)
+{
+ BOOLEAN Handled = FALSE;
+ PKNMI_HANDLER_CALLBACK NmiData;
+
+ //
+ // Parse the list of callbacks
+ //
+ NmiData = KiNmiCallbackListHead;
+ while (NmiData)
+ {
+ //
+ // Save if this callback has handled it -- all it takes is one
+ //
+ Handled |= NmiData->Callback(NmiData->Context, Handled);
+ NmiData = NmiData->Next;
+ }
+
+ //
+ // Has anyone handled this?
+ //
+ return Handled;
+}
+
/* PUBLIC FUNCTIONS **********************************************************/
/*
@@ -1278,17 +1306,6 @@
/* Lower IRQL and return */
KeLowerIrql(OldIrql);
return Status;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-KeDeregisterNmiCallback(PVOID Handle)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
}
/*
@@ -1362,15 +1379,58 @@
}
/*
- * @unimplemented
+ * @implemented
*/
PVOID
NTAPI
KeRegisterNmiCallback(IN PNMI_CALLBACK CallbackRoutine,
IN PVOID Context)
{
+ KIRQL OldIrql;
+ PKNMI_HANDLER_CALLBACK NmiData, Next;
+ ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+
+ //
+ // Allocate NMI callback data
+ //
+ NmiData = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(KNMI_HANDLER_CALLBACK),
+ 'IMNK');
+ if (!NmiData) return NULL;
+
+ //
+ // Fill in the information
+ //
+ NmiData->Callback = CallbackRoutine;
+ NmiData->Context = Context;
+ NmiData->Handle = NmiData;
+
+ //
+ // Insert it into NMI callback list
+ //
+ KiAcquireNmiListLock(&OldIrql);
+ NmiData->Next = KiNmiCallbackListHead;
+ Next = InterlockedCompareExchangePointer(&KiNmiCallbackListHead,
+ NmiData,
+ NmiData->Next);
+ ASSERT(Next == NmiData->Next);
+ KiReleaseNmiListLock(OldIrql);
+
+ //
+ // Return the opaque "handle"
+ //
+ return NmiData->Handle;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+KeDeregisterNmiCallback(PVOID Handle)
+{
UNIMPLEMENTED;
- return NULL;
+ return STATUS_UNSUCCESSFUL;
}
/*
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] Sat Jan 2 05:48:22 2010
@@ -881,8 +881,11 @@
stdCall _KiSaveProcessorState, ebp, 0 // Save to KPRCB CONTEXT
//
- // BUGBUG: Call Registered NMI handlers
+ // Call Registered NMI handlers
//
+ stdCall _KiHandleNmi // Call NMI handlers
+ or al, al // Check if any handled it
+ jne 1f // Resume from NMI
//
// Call the platform driver for NMI handling (panic, etc)
@@ -897,6 +900,7 @@
// In certain situations, nested NMIs can corrupt the TSS, making us lose
// the original context. If this happens, we have no choice but to panic.
//
+1:
mov eax, PCR[KPCR_TSS] // Get current TSS
cmp word ptr [eax], KGDT_NMI_TSS // Check who its points to
je 2f // Back to the NMI TSS crash