Author: sginsberg Date: Sun Oct 11 22:16:45 2009 New Revision: 43380
URL: http://svn.reactos.org/svn/reactos?rev=43380&view=rev Log: - Stub out DbgKdWriteVirtualMemoryApi, DbgKdReadPhysicalMemoryApi, DbgKdWritePhysicalMemoryApi, DbgKdWriteBreakPointExApi, DbgKdRestoreBreakPointExApi, DbgKdSearchMemoryApi and DbgKdFillMemoryApi cases more properly. - Fail on physical memory write like we do for read too. - Don't handle OldVlm1/2 as they appear to be deprecated and unhandled in Windows. - Implement HalHaltSystem to halt execution in a portable way. Default to xHalHaltSystem, a simple infinite loop, if we get called before HAL has initialized. Use this in KiBugCheckDebugBreak and the system shutdown handler instead of x86/AMD64/ARM intrinsics. - Don't try to halt the CPU if KeBugCheck has been called 3 times or more -- if this happens, something has gone very wrong, and we shouldn't try to do anything special. Just loop infinitely. - Fix KiBugCheckDebugBreak -- it shouldn't halt execution when called for the first chance as bugcheck callbacks have not been invoked at this point (nor has the BSOD been displayed). Use SEH to protect against a crash instead of checking KdDebuggerNotPresent as the debugger, if it is present, *could* disconnect while the trap is being handled. Also, don't halt execution if the debugger handled the breakpoint, just break again. - Don't call MmMapIoSpace from HalpReboot! The reboot might take place at elevated IRQL (as high as HIGH_LEVEL if called from KeBugCheck), and thus can't use any Mm support routines. Use a PTE from the reserved HAL region and map it ourselves instead as done in the BIOS call code. - Acquire the display ownership in HalReturnToFirmware in case the caller hasn't done so (as done in the KD reboot routine, for example). - Just include ntndk.h in hal.h instead of including 6 NDK headers (which turns into more than half of the NDK anyway since those headers include other NDK headers). - Crashing and rebooting from KD now works properly.
Modified: trunk/reactos/hal/halx86/generic/halinit.c trunk/reactos/hal/halx86/generic/processor.c trunk/reactos/hal/halx86/generic/reboot.c trunk/reactos/hal/halx86/include/hal.h trunk/reactos/hal/halx86/include/halp.h trunk/reactos/ntoskrnl/ex/shutdown.c trunk/reactos/ntoskrnl/fstub/halstub.c trunk/reactos/ntoskrnl/include/internal/hal.h trunk/reactos/ntoskrnl/kd64/kdapi.c trunk/reactos/ntoskrnl/ke/bug.c
Modified: trunk/reactos/hal/halx86/generic/halinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/halinit.... ============================================================================== --- trunk/reactos/hal/halx86/generic/halinit.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/generic/halinit.c [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -110,6 +110,7 @@ HalGetDmaAdapter = HalpGetDmaAdapter; HalGetInterruptTranslator = NULL; // FIXME: TODO HalResetDisplay = HalpBiosDisplayReset; + HalHaltSystem = HaliHaltSystem;
/* Initialize the hardware lock (CMOS) */ KeInitializeSpinLock(&HalpSystemHardwareLock);
Modified: trunk/reactos/hal/halx86/generic/processor.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/processo... ============================================================================== --- trunk/reactos/hal/halx86/generic/processor.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/generic/processor.c [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -14,6 +14,17 @@
LONG HalpActiveProcessors; KAFFINITY HalpDefaultInterruptAffinity; + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +HaliHaltSystem(VOID) +{ + /* Disable interrupts and halt the CPU */ + _disable(); + __halt(); +}
/* FUNCTIONS *****************************************************************/
Modified: trunk/reactos/hal/halx86/generic/reboot.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/reboot.c... ============================================================================== --- trunk/reactos/hal/halx86/generic/reboot.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/generic/reboot.c [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -13,9 +13,11 @@ #define NDEBUG #include <debug.h>
+#define GetPteAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 12) << 2) + 0xC0000000) + /* PRIVATE FUNCTIONS *********************************************************/
-static VOID +VOID NTAPI HalpWriteResetCommand(VOID) { @@ -23,17 +25,29 @@ WRITE_PORT_UCHAR((PUCHAR)0x64, 0xFE); };
-static VOID +VOID NTAPI HalpReboot(VOID) { UCHAR Data; - PVOID HalpZeroPageMapping; - PHYSICAL_ADDRESS Null = {{0, 0}}; + PVOID ZeroPageMapping; + PHARDWARE_PTE Pte; + + /* Get a PTE in the HAL reserved region */ + ZeroPageMapping = (PVOID)(0xFFC00000 + PAGE_SIZE); + Pte = GetPteAddress(ZeroPageMapping); + + /* Make it valid and map it to the first physical page */ + Pte->Valid = 1; + Pte->Write = 1; + Pte->Owner = 1; + Pte->PageFrameNumber = 0; + + /* Flush the TLB by resetting CR3 */ + __writecr3(__readcr3());
/* Enable warm reboot */ - HalpZeroPageMapping = MmMapIoSpace(Null, PAGE_SIZE, MmNonCached); - ((PUSHORT)HalpZeroPageMapping)[0x239] = 0x1234; + ((PUSHORT)ZeroPageMapping)[0x239] = 0x1234;
/* FIXME: Lock CMOS Access */
@@ -79,12 +93,15 @@ NTAPI HalReturnToFirmware(IN FIRMWARE_REENTRY Action) { - /* Check the kind of action this is */ + /* Check what kind of action this is */ switch (Action) { /* All recognized actions */ case HalHaltRoutine: case HalRebootRoutine: + + /* Acquire the display */ + InbvAcquireDisplayOwnership();
/* Call the internal reboot function */ HalpReboot();
Modified: trunk/reactos/hal/halx86/include/hal.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/hal.h?re... ============================================================================== --- trunk/reactos/hal/halx86/include/hal.h [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/include/hal.h [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -25,12 +25,7 @@ #include <bugcodes.h> #include <ntdddisk.h> #include <arc/arc.h> -#include <iotypes.h> -#include <kefuncs.h> -#include <halfuncs.h> -#include <iofuncs.h> -#include <ldrtypes.h> -#include <obfuncs.h> +#include <ntndk.h>
/* Internal kernel headers */ #include "internal/pci.h"
Modified: trunk/reactos/hal/halx86/include/halp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/halp.h?r... ============================================================================== --- trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -164,6 +164,15 @@ VOID );
+// +// Processor Halt Routine +// +VOID +NTAPI +HaliHaltSystem( + VOID +); + #ifdef _M_AMD64 #define KfLowerIrql KeLowerIrql #ifndef CONFIG_SMP
Modified: trunk/reactos/ntoskrnl/ex/shutdown.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/shutdown.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ex/shutdown.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ex/shutdown.c [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -30,13 +30,7 @@ while (TRUE) { KeRaiseIrql(SYNCH_LEVEL, &OldIrql); -#if defined(_M_IX86) || defined(_M_AMD64) - __halt(); -#elif defined(_M_ARM) - KeArmHaltProcessor(); -#else - HalProcessorIdle(); -#endif + HalHaltSystem(); } }
Modified: trunk/reactos/ntoskrnl/fstub/halstub.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/fstub/halstub.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/fstub/halstub.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/fstub/halstub.c [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -51,7 +51,7 @@ (pHalSetWakeAlarm)NULL, (pHalTranslateBusAddress)NULL, (pHalAssignSlotResources)NULL, - (pHalHaltSystem)NULL, + xHalHaltSystem, (pHalFindBusAddressTranslation)NULL, (pHalResetDisplay)NULL, (pHalAllocateMapRegisters)NULL, @@ -66,5 +66,10 @@
/* FUNCTIONS *****************************************************************/
- -/* EOF */ +VOID +NTAPI +xHalHaltSystem(VOID) +{ + /* Halt execution */ + while (TRUE); +}
Modified: trunk/reactos/ntoskrnl/include/internal/hal.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/h... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/hal.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/hal.h [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -46,6 +46,13 @@ IN ULONG SectorsPerTrack, IN ULONG NumberOfHeads, IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer); + +VOID +NTAPI +xHalHaltSystem( + VOID +); +
// // Various offsets in the boot record
Modified: trunk/reactos/ntoskrnl/kd64/kdapi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdapi.c?rev=4... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -66,6 +66,28 @@
VOID NTAPI +KdpSearchMemory(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + /* FIXME: STUB */ + KdpDprintf("KdpSearchMemory called\n"); + while (TRUE); +} + +VOID +NTAPI +KdpFillMemory(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + /* FIXME: STUB */ + KdpDprintf("KdpFillMemory called\n"); + while (TRUE); +} + +VOID +NTAPI KdpWriteBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State, IN PSTRING Data, IN PCONTEXT Context) @@ -97,6 +119,62 @@ &Header, NULL, &KdpContext); +} + +VOID +NTAPI +KdpRestoreBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + PDBGKD_RESTORE_BREAKPOINT RestoreBp = &State->u.RestoreBreakPoint; + STRING Header; + + /* Fill out the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + ASSERT(Data->Length == 0); + + /* Get the version block */ + if (KdpDeleteBreakpoint(RestoreBp->BreakPointHandle)) + { + /* We're all good */ + State->ReturnStatus = STATUS_SUCCESS; + } + else + { + /* We failed */ + State->ReturnStatus = STATUS_UNSUCCESSFUL; + } + + /* Send the packet */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + NULL, + &KdpContext); +} + +NTSTATUS +NTAPI +KdpWriteBreakPointEx(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + /* FIXME: STUB */ + KdpDprintf("KdpWriteBreakPointEx called\n"); + while (TRUE); + return STATUS_UNSUCCESSFUL; +} + +VOID +NTAPI +KdpRestoreBreakPointEx(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + /* FIXME: STUB */ + KdpDprintf("KdpRestoreBreakPointEx called\n"); + while (TRUE); }
VOID @@ -236,6 +314,71 @@
VOID NTAPI +KdpWriteVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + /* FIXME: STUB */ + KdpDprintf("KdpWriteVirtualMemory called for Address: %p Length %x\n", + (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress, + State->u.ReadMemory.TransferCount); + while (TRUE); +} + +VOID +NTAPI +KdpReadPhysicalmemory(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + STRING Header; + + /* FIXME: STUB */ + KdpDprintf("KdpWritePhysicalMemory called for Address %I64x Length: %x\n", + State->u.ReadMemory.TargetBaseAddress, + State->u.ReadMemory.TransferCount); + + /* Setup an empty message, with failure */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + Data->Length = 0; + State->ReturnStatus = STATUS_UNSUCCESSFUL; + + /* Send it */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + Data, + &KdpContext); +} + +VOID +NTAPI +KdpWritePhysicalmemory(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + STRING Header; + + /* FIXME: STUB */ + KdpDprintf("KdpWritePhysicalMemory called for Address %I64x Length: %x\n", + State->u.ReadMemory.TargetBaseAddress, + State->u.ReadMemory.TransferCount); + + /* Setup an empty message, with failure */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + Data->Length = 0; + State->ReturnStatus = STATUS_UNSUCCESSFUL; + + /* Send it */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + Data, + &KdpContext); +} + +VOID +NTAPI KdpReadControlSpace(IN PDBGKD_MANIPULATE_STATE64 State, IN PSTRING Data, IN PCONTEXT Context) @@ -302,39 +445,6 @@ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Header, Data, - &KdpContext); -} - -VOID -NTAPI -KdpRestoreBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State, - IN PSTRING Data, - IN PCONTEXT Context) -{ - PDBGKD_RESTORE_BREAKPOINT RestoreBp = &State->u.RestoreBreakPoint; - STRING Header; - - /* Fill out the header */ - Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); - Header.Buffer = (PCHAR)State; - ASSERT(Data->Length == 0); - - /* Get the version block */ - if (KdpDeleteBreakpoint(RestoreBp->BreakPointHandle)) - { - /* We're all good */ - State->ReturnStatus = STATUS_SUCCESS; - } - else - { - /* We failed */ - State->ReturnStatus = STATUS_UNSUCCESSFUL; - } - - /* Send the packet */ - KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, - &Header, - NULL, &KdpContext); }
@@ -788,9 +898,8 @@
case DbgKdWriteVirtualMemoryApi:
- /* FIXME: TODO */ - KdpDprintf("DbgKdWriteVirtualMemoryApi called\n"); - while (TRUE); + /* Write virtual memory */ + KdpWriteVirtualMemory(&ManipulateState, &Data, Context); break;
case DbgKdGetContextApi: @@ -866,22 +975,17 @@ /* Return an error */ return ContinueError; } - break;
case DbgKdReadPhysicalMemoryApi:
- /* FIXME: TODO */ - KdpDprintf("DbgKdReadPhysicalMemoryApi called for address %I64X\n", - ManipulateState.u.ReadMemory.TargetBaseAddress); - goto Hack; - while (TRUE); + /* Read physical memory */ + KdpReadPhysicalmemory(&ManipulateState, &Data, Context); break;
case DbgKdWritePhysicalMemoryApi:
- /* FIXME: TODO */ - KdpDprintf("DbgKdWritePhysicalMemoryApi called\n"); - while (TRUE); + /* Write physical memory */ + KdpWritePhysicalmemory(&ManipulateState, &Data, Context); break;
case DbgKdQuerySpecialCallsApi: @@ -939,16 +1043,20 @@
case DbgKdWriteBreakPointExApi:
- /* FIXME: TODO */ - KdpDprintf("DbgKdWriteBreakPointExApi called\n"); - while (TRUE); + /* Write the breakpoint and check if it failed */ + if (!NT_SUCCESS(KdpWriteBreakPointEx(&ManipulateState, + &Data, + Context))) + { + /* Return an error */ + return ContinueError; + } break;
case DbgKdRestoreBreakPointExApi:
- /* FIXME: TODO */ - KdpDprintf("DbgKdRestoreBreakPointExApi called\n"); - while (TRUE); + /* Restore the breakpoint */ + KdpRestoreBreakPointEx(&ManipulateState, &Data, Context); break;
case DbgKdCauseBugCheckApi: @@ -983,25 +1091,10 @@ KdpWriteMachineSpecificRegister(&ManipulateState, &Data, Context); break;
- case OldVlm1: - - /* FIXME: TODO */ - KdpDprintf("OldVlm1 called\n"); - while (TRUE); - break; - - case OldVlm2: - - /* FIXME: TODO */ - KdpDprintf("OldVlm2 called\n"); - while (TRUE); - break; - case DbgKdSearchMemoryApi:
- /* FIXME: TODO */ - KdpDprintf("DbgKdSearchMemoryApi called\n"); - while (TRUE); + /* Search memory */ + KdpSearchMemory(&ManipulateState, &Data, Context); break;
case DbgKdGetBusDataApi: @@ -1030,9 +1123,8 @@
case DbgKdFillMemoryApi:
- /* FIXME: TODO */ - KdpDprintf("DbgKdFillMemoryApi called\n"); - while (TRUE); + /* Fill memory */ + KdpFillMemory(&ManipulateState, &Data, Context); break;
case DbgKdQueryMemoryApi: @@ -1052,9 +1144,7 @@ default:
/* Setup an empty message, with failure */ - KdpDprintf("Received unknown API Number %lx\n", ManipulateState.ApiNumber); - while (TRUE); -Hack: + KdpDprintf("Received Unhandled API %lx\n", ManipulateState.ApiNumber); Data.Length = 0; ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;
Modified: trunk/reactos/ntoskrnl/ke/bug.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/bug.c?rev=43380... ============================================================================== --- trunk/reactos/ntoskrnl/ke/bug.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/bug.c [iso-8859-1] Sun Oct 11 22:16:45 2009 @@ -546,21 +546,29 @@ } }
-DECLSPEC_NORETURN VOID NTAPI KiBugCheckDebugBreak(IN ULONG StatusCode) { - /* If KDBG isn't connected, freeze the CPU, otherwise, break */ -#if defined(_M_IX86) || defined(_M_AMD64) - if (KdDebuggerNotPresent) for (;;) __halt(); -#elif defined(_M_ARM) - if (KdDebuggerNotPresent) for (;;) KeArmHaltProcessor(); -#else -#error -#endif - DbgBreakPointWithStatus(StatusCode); - while (TRUE); + /* + * Wrap this in SEH so we don't crash if + * there is no debugger or if it disconnected + */ +DoBreak: + _SEH2_TRY + { + /* Breakpoint */ + DbgBreakPointWithStatus(StatusCode); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* No debugger, halt the CPU */ + HalHaltSystem(); + } + _SEH2_END; + + /* Break again if this wasn't first try */ + if (StatusCode != DBG_STATUS_BUGCHECK_FIRST) goto DoBreak; }
PCHAR @@ -1175,14 +1183,8 @@ } else if (KeBugCheckOwnerRecursionCount > 2) { - /* Halt the CPU */ -#if defined(_M_IX86) || defined(_M_AMD64) - for (;;) __halt(); -#elif defined(_M_ARM) - for (;;) KeArmHaltProcessor(); -#else -#error -#endif + /* Halt execution */ + while (TRUE); } }
@@ -1201,6 +1203,9 @@
/* Attempt to break in the debugger (otherwise halt CPU) */ KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND); + + /* Shouldn't get here */ + while (TRUE); }
/* PUBLIC FUNCTIONS **********************************************************/ @@ -1421,7 +1426,7 @@ } }
- /* Bugcheck */ + /* Break in the debugger */ KiBugCheckDebugBreak(DBG_STATUS_FATAL); }