xbox-kernel/private/ntos/kdlite/kdlite.c
2020-09-30 17:17:25 +02:00

388 lines
8.0 KiB
C

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
kdlite.c
Abstract:
This module implements the Xbox lite kernel debugger.
--*/
#include "kdlitep.h"
//
// Stores whether or not the debugger is enabled. The debugger is only enabled
// if a super I/O controller is present.
//
DECLSPEC_STICKY BOOLEAN KdDebuggerEnabled;
//
// Hardwired to TRUE, since a real debugger is never really present.
//
BOOLEAN KdDebuggerNotPresent = TRUE;
//
// Local support.
//
VOID
KdpConfigureSerialPort(
VOID
);
VOID
KdpInitializeLoadedModuleList(
VOID
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, KdpConfigureSerialPort)
#endif
VOID
KdpConfigureSerialPort(
VOID
)
/*++
Routine Description:
This routine configures the serial port for the desired baud rate and port
options.
Arguments:
None.
Return Value:
None.
--*/
{
ULONG DivisorLatch;
DivisorLatch = CLOCK_RATE / KDLITE_DEBUG_BAUD_RATE;
_outp(KDLITE_DEBUG_BASE_ADDRESS + COM_LCR, 0x83);
_outp(KDLITE_DEBUG_BASE_ADDRESS + COM_DLM, (UCHAR)(DivisorLatch >> 8));
_outp(KDLITE_DEBUG_BASE_ADDRESS + COM_DLL, (UCHAR)(DivisorLatch));
_outp(KDLITE_DEBUG_BASE_ADDRESS + COM_LCR, 0x03);
_outp(KDLITE_DEBUG_BASE_ADDRESS + COM_MCR, MC_DTRRTS);
_outp(KDLITE_DEBUG_BASE_ADDRESS + COM_IEN, 0);
}
VOID
KdpPrintString(
IN PSTRING String
)
/*++
Routine Description:
This routine prints out the supplied string to the serial port.
Arguments:
String - Specifies the string to be printed to the serial port.
Return Value:
None.
--*/
{
BOOLEAN Restore;
ULONG Length;
PUCHAR Buffer;
//
// If the debugger isn't enabled, don't do anything.
//
if (!KdDebuggerEnabled) {
return;
}
//
// Write out each character to the serial port. Synchronize by disabling
// interrupts.
//
Restore = KiDisableInterrupts();
Length = String->Length;
Buffer = String->Buffer;
while (Length > 0) {
while (!(_inp(KDLITE_DEBUG_BASE_ADDRESS + COM_LSR) & COM_OUTRDY));
_outp(KDLITE_DEBUG_BASE_ADDRESS + COM_DAT, *Buffer);
Length--;
Buffer++;
}
KiRestoreInterrupts(Restore);
}
BOOLEAN
KdpTrap(
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT ContextRecord,
IN BOOLEAN SecondChance
)
/*++
Routine Description:
This routine is called whenever a exception is dispatched.
Arguments:
TrapFrame - Supplies a pointer to a trap frame that describes the
trap.
ExceptionFrame - Supplies a pointer to a exception frame that describes
the trap.
ExceptionRecord - Supplies a pointer to an exception record that
describes the exception.
ContextRecord - Supplies the context at the time of the exception.
SecondChance - Supplies a boolean value that determines whether this is
the second chance (TRUE) that the exception has been raised.
Return Value:
A value of TRUE is returned if the exception is handled. Otherwise a
value of FALSE is returned.
--*/
{
BOOLEAN Handled = FALSE;
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
(ExceptionRecord->NumberParameters > 0) &&
((ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_LOAD_SYMBOLS)||
(ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_UNLOAD_SYMBOLS)||
(ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_LOAD_XESECTION)||
(ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_UNLOAD_XESECTION)||
(ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_KDPRINT)||
(ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_PRINT))) {
if ((ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_KDPRINT)||
(ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_PRINT)) {
KdpPrintString((PSTRING)ExceptionRecord->ExceptionInformation[1]);
ContextRecord->Eax = STATUS_SUCCESS;
}
ContextRecord->Eip++;
Handled = TRUE;
}
return Handled;
}
VOID
KdInitSystem(
BOOLEAN InitializingSystem
)
/*++
Routine Description:
This routine initializes the lite kernel debugger.
Arguments:
InitializingSystem - Supplies a boolean value that determines whether we're
called in the context of system initialization or bugcheck code.
Return Value:
None.
--*/
{
if (InitializingSystem) {
//
// If the kernel is cold-booting, then determine whether or not a super
// I/O controller is attached to the system so that we know whether or
// not to output debug spew through the serial port.
//
if (!KeHasQuickBooted) {
HalPulseHardwareMonitorPin();
KdDebuggerEnabled = HalInitializeSuperIo();
if (KdDebuggerEnabled) {
KdpConfigureSerialPort();
}
}
//
// Set the debug routine to point at our trap handler.
//
KiDebugRoutine = KdpTrap;
#ifdef DEVKIT
//
// For DEVKIT builds of this library, we still need to initialize the
// module list so that the debug monitor will continue to function.
//
KdpInitializeLoadedModuleList();
#endif
}
}
#ifdef DEVKIT
//
// The following code and data are present for DEVKIT builds to enable testing
// of the lite kernel debugger on a DEVKIT platform. None of this code is used
// by a retail build of the system.
//
//
// Set to TRUE if the are any breakpoints that need to be applied to pages that
// are not inpaged. Always FALSE since this implementation never applies
// breakpoints.
//
BOOLEAN KdpOweBreakpoint;
//
// Static loader data table entry for XBOXKRNL.EXE.
//
LDR_DATA_TABLE_ENTRY KdpNtosDataTableEntry;
//
// List of modules that have been loaded.
//
INITIALIZED_LIST_ENTRY(KdLoadedModuleList);
VOID
KdpInitializeLoadedModuleList(
VOID
)
/*++
Routine Description:
This routine initializes the static loader data table entry for the kernel
and attaches it to the loaded module list.
Arguments:
None.
Return Value:
None.
--*/
{
//
// Initialize the loader data table entry for XBOXKRNL.EXE and attach it
// to the loaded module list.
//
KdpNtosDataTableEntry.DllBase = PsNtosImageBase;
KdpNtosDataTableEntry.SizeOfImage =
RtlImageNtHeader(PsNtosImageBase)->OptionalHeader.SizeOfImage;
KdpNtosDataTableEntry.LoadedImports = (PVOID)MAXULONG_PTR;
RtlInitUnicodeString(&KdpNtosDataTableEntry.FullDllName, L"xboxkrnl.exe");
RtlInitUnicodeString(&KdpNtosDataTableEntry.BaseDllName, L"xboxkrnl.exe");
InsertTailList(&KdLoadedModuleList, &KdpNtosDataTableEntry.InLoadOrderLinks);
}
BOOLEAN
KdPollBreakIn(
VOID
)
/*++
Routine Description:
This routine checks if a breakin packet is pending.
Arguments:
None.
Return Value:
Returns FALSE to indicate that no breakin packet is pending.
--*/
{
return FALSE;
}
VOID
KdSetOwedBreakpoints(
VOID
)
/*++
Routine Description:
This routine is called by the page fault handler to store pending
breakpoints for pages that may have been just made valid.
Arguments:
None.
Return Value:
None.
--*/
{
//
// This routine should never be called because this implementation never
// applies breakpoints and never sets KdpOweBreakpoint to TRUE.
//
KeBugCheck(0);
}
VOID
KdDeleteAllBreakpoints(
VOID
)
/*++
Routine Description:
This routine is called to delete all breakpoints from the system.
Arguments:
None.
Return Value:
None.
--*/
{
NOTHING;
}
#endif