- 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.

svn path=/trunk/; revision=43380
This commit is contained in:
Stefan Ginsberg 2009-10-11 20:16:45 +00:00
parent d00f6c4b5c
commit 31c45b85d7
10 changed files with 251 additions and 117 deletions

View file

@ -110,6 +110,7 @@ HalInitSystem(IN ULONG BootPhase,
HalGetDmaAdapter = HalpGetDmaAdapter;
HalGetInterruptTranslator = NULL; // FIXME: TODO
HalResetDisplay = HalpBiosDisplayReset;
HalHaltSystem = HaliHaltSystem;
/* Initialize the hardware lock (CMOS) */
KeInitializeSpinLock(&HalpSystemHardwareLock);

View file

@ -15,6 +15,17 @@
LONG HalpActiveProcessors;
KAFFINITY HalpDefaultInterruptAffinity;
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
HaliHaltSystem(VOID)
{
/* Disable interrupts and halt the CPU */
_disable();
__halt();
}
/* FUNCTIONS *****************************************************************/
/*

View file

@ -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 @@ HalpWriteResetCommand(VOID)
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,13 +93,16 @@ VOID
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();

View file

@ -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"

View file

@ -164,6 +164,15 @@ HalpTrap06(
VOID
);
//
// Processor Halt Routine
//
VOID
NTAPI
HaliHaltSystem(
VOID
);
#ifdef _M_AMD64
#define KfLowerIrql KeLowerIrql
#ifndef CONFIG_SMP

View file

@ -30,13 +30,7 @@ KiHaltProcessorDpcRoutine(IN PKDPC Dpc,
while (TRUE)
{
KeRaiseIrql(SYNCH_LEVEL, &OldIrql);
#if defined(_M_IX86) || defined(_M_AMD64)
__halt();
#elif defined(_M_ARM)
KeArmHaltProcessor();
#else
HalProcessorIdle();
#endif
HalHaltSystem();
}
}

View file

@ -51,7 +51,7 @@ HAL_PRIVATE_DISPATCH HalPrivateDispatchTable =
(pHalSetWakeAlarm)NULL,
(pHalTranslateBusAddress)NULL,
(pHalAssignSlotResources)NULL,
(pHalHaltSystem)NULL,
xHalHaltSystem,
(pHalFindBusAddressTranslation)NULL,
(pHalResetDisplay)NULL,
(pHalAllocateMapRegisters)NULL,
@ -66,5 +66,10 @@ HAL_PRIVATE_DISPATCH HalPrivateDispatchTable =
/* FUNCTIONS *****************************************************************/
/* EOF */
VOID
NTAPI
xHalHaltSystem(VOID)
{
/* Halt execution */
while (TRUE);
}

View file

@ -47,6 +47,13 @@ xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
IN ULONG NumberOfHeads,
IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer);
VOID
NTAPI
xHalHaltSystem(
VOID
);
//
// Various offsets in the boot record
//

View file

@ -64,6 +64,28 @@ KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State,
&KdpContext);
}
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,
@ -99,6 +121,62 @@ KdpWriteBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
&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
NTAPI
DumpTraceData(IN PSTRING TraceData)
@ -234,6 +312,71 @@ KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
&KdpContext);
}
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,
@ -305,39 +448,6 @@ KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
&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);
}
VOID
NTAPI
KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State,
@ -788,9 +898,8 @@ SendPacket:
case DbgKdWriteVirtualMemoryApi:
/* FIXME: TODO */
KdpDprintf("DbgKdWriteVirtualMemoryApi called\n");
while (TRUE);
/* Write virtual memory */
KdpWriteVirtualMemory(&ManipulateState, &Data, Context);
break;
case DbgKdGetContextApi:
@ -866,22 +975,17 @@ SendPacket:
/* 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 @@ SendPacket:
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 @@ SendPacket:
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 @@ SendPacket:
case DbgKdFillMemoryApi:
/* FIXME: TODO */
KdpDprintf("DbgKdFillMemoryApi called\n");
while (TRUE);
/* Fill memory */
KdpFillMemory(&ManipulateState, &Data, Context);
break;
case DbgKdQueryMemoryApi:
@ -1052,9 +1144,7 @@ SendPacket:
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;

View file

@ -546,21 +546,29 @@ KiDoBugCheckCallbacks(VOID)
}
}
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 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
}
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 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
/* 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 @@ KeEnterKernelDebugger(VOID)
}
}
/* Bugcheck */
/* Break in the debugger */
KiBugCheckDebugBreak(DBG_STATUS_FATAL);
}