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/k... ============================================================================== --- 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/k... ============================================================================== --- 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=44877... ============================================================================== --- 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?rev... ============================================================================== --- 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