mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[KDROSDBG]
In fact, the kdcom used for KDBG (in GCC builds) is really a thin layer atop of CPORTLIB. Remove extra code (remove also the KD_PORT_INFORMATION type) and replace it with calls to CPORTLIB functions. Next step is to put all that thing into KDBG directly, as helper functions. Then, if one wants to make a really kdcom (as we have for MSVC builds), one has to refactor all KDBG. svn path=/branches/kd++/; revision=58964
This commit is contained in:
parent
a23361e756
commit
cbdc727f61
9 changed files with 339 additions and 482 deletions
|
@ -17,8 +17,7 @@
|
||||||
#define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
|
#define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
|
||||||
#define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
|
#define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
|
||||||
|
|
||||||
#define DEFAULT_BAUD_RATE 19200
|
#define DEFAULT_BAUD_RATE 19200
|
||||||
|
|
||||||
|
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
||||||
|
|
|
@ -10,27 +10,20 @@
|
||||||
|
|
||||||
#define NOEXTAPI
|
#define NOEXTAPI
|
||||||
#include <ntifs.h>
|
#include <ntifs.h>
|
||||||
#include <halfuncs.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <arc/arc.h>
|
#include <arc/arc.h>
|
||||||
|
#include <halfuncs.h>
|
||||||
#include <windbgkd.h>
|
#include <windbgkd.h>
|
||||||
#include <kddll.h>
|
#include <ioaccess.h> /* port intrinsics */
|
||||||
#include <ioaccess.h>
|
#include <cportlib/cportlib.h>
|
||||||
#include <arm/peripherals/pl011.h>
|
#include <arm/peripherals/pl011.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
typedef struct _KD_PORT_INFORMATION
|
CPPORT DefaultPort = {0, 0, 0};
|
||||||
{
|
|
||||||
ULONG ComPort;
|
|
||||||
ULONG BaudRate;
|
|
||||||
ULONG BaseAddress;
|
|
||||||
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
|
|
||||||
|
|
||||||
KD_PORT_INFORMATION DefaultPort = {0, 0, 0};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// We need to build this in the configuration root and use KeFindConfigurationEntry
|
// We need to build this in the configuration root and use KeFindConfigurationEntry
|
||||||
|
@ -42,42 +35,41 @@ KD_PORT_INFORMATION DefaultPort = {0, 0, 0};
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortInitializeEx(IN PKD_PORT_INFORMATION PortInformation,
|
KdPortInitializeEx(IN PCPPORT PortInformation,
|
||||||
IN ULONG Unknown1,
|
IN ULONG ComPortNumber)
|
||||||
IN ULONG Unknown2)
|
|
||||||
{
|
{
|
||||||
ULONG Divider, Remainder, Fraction;
|
ULONG Divider, Remainder, Fraction;
|
||||||
ULONG Baudrate = PortInformation->BaudRate;
|
ULONG Baudrate = PortInformation->BaudRate;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Calculate baudrate clock divider and remainder
|
// Calculate baudrate clock divider and remainder
|
||||||
//
|
//
|
||||||
Divider = HACK / (16 * Baudrate);
|
Divider = HACK / (16 * Baudrate);
|
||||||
Remainder = HACK % (16 * Baudrate);
|
Remainder = HACK % (16 * Baudrate);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Calculate the fractional part
|
// Calculate the fractional part
|
||||||
//
|
//
|
||||||
Fraction = (8 * Remainder / Baudrate) >> 1;
|
Fraction = (8 * Remainder / Baudrate) >> 1;
|
||||||
Fraction += (8 * Remainder / Baudrate) & 1;
|
Fraction += (8 * Remainder / Baudrate) & 1;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable interrupts
|
// Disable interrupts
|
||||||
//
|
//
|
||||||
WRITE_REGISTER_ULONG(UART_PL011_CR, 0);
|
WRITE_REGISTER_ULONG(UART_PL011_CR, 0);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set the baud rate
|
// Set the baud rate
|
||||||
//
|
//
|
||||||
WRITE_REGISTER_ULONG(UART_PL011_IBRD, Divider);
|
WRITE_REGISTER_ULONG(UART_PL011_IBRD, Divider);
|
||||||
WRITE_REGISTER_ULONG(UART_PL011_FBRD, Fraction);
|
WRITE_REGISTER_ULONG(UART_PL011_FBRD, Fraction);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set 8 bits for data, 1 stop bit, no parity, FIFO enabled
|
// Set 8 bits for data, 1 stop bit, no parity, FIFO enabled
|
||||||
//
|
//
|
||||||
WRITE_REGISTER_ULONG(UART_PL011_LCRH,
|
WRITE_REGISTER_ULONG(UART_PL011_LCRH,
|
||||||
UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN);
|
UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Clear and enable FIFO
|
// Clear and enable FIFO
|
||||||
//
|
//
|
||||||
|
@ -85,7 +77,7 @@ KdPortInitializeEx(IN PKD_PORT_INFORMATION PortInformation,
|
||||||
UART_PL011_CR_UARTEN |
|
UART_PL011_CR_UARTEN |
|
||||||
UART_PL011_CR_TXE |
|
UART_PL011_CR_TXE |
|
||||||
UART_PL011_CR_RXE);
|
UART_PL011_CR_RXE);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Done
|
// Done
|
||||||
//
|
//
|
||||||
|
@ -94,7 +86,7 @@ KdPortInitializeEx(IN PKD_PORT_INFORMATION PortInformation,
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortGetByteEx(IN PKD_PORT_INFORMATION PortInformation,
|
KdPortGetByteEx(IN PCPPORT PortInformation,
|
||||||
OUT PUCHAR ByteReceived)
|
OUT PUCHAR ByteReceived)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -104,7 +96,7 @@ KdPortGetByteEx(IN PKD_PORT_INFORMATION PortInformation,
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortPutByteEx(IN PKD_PORT_INFORMATION PortInformation,
|
KdPortPutByteEx(IN PCPPORT PortInformation,
|
||||||
IN UCHAR ByteToSend)
|
IN UCHAR ByteToSend)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|
|
@ -11,26 +11,18 @@
|
||||||
|
|
||||||
#define NOEXTAPI
|
#define NOEXTAPI
|
||||||
#include <ntifs.h>
|
#include <ntifs.h>
|
||||||
#include <halfuncs.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <arc/arc.h>
|
#include <arc/arc.h>
|
||||||
|
#include <halfuncs.h>
|
||||||
#include <windbgkd.h>
|
#include <windbgkd.h>
|
||||||
#include <kddll.h>
|
|
||||||
#include <ioaccess.h> /* port intrinsics */
|
#include <ioaccess.h> /* port intrinsics */
|
||||||
#include <cportlib/cportlib.h>
|
#include <cportlib/cportlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct _KD_PORT_INFORMATION
|
#define DEFAULT_BAUD_RATE 19200
|
||||||
{
|
|
||||||
ULONG ComPort;
|
|
||||||
ULONG BaudRate;
|
|
||||||
ULONG BaseAddress;
|
|
||||||
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
|
|
||||||
|
|
||||||
#define DEFAULT_BAUD_RATE 19200
|
|
||||||
|
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
||||||
|
@ -44,57 +36,11 @@ const ULONG BaseArray[] = {0, 0xF1012000};
|
||||||
#error Unknown architecture
|
#error Unknown architecture
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* MACROS *******************************************************************/
|
/* STATIC VARIABLES ***********************************************************/
|
||||||
|
|
||||||
#define SER_RBR(x) ((PUCHAR)(x)+0)
|
// static CPPORT DefaultPort = {0, 0, 0};
|
||||||
#define SER_THR(x) ((PUCHAR)(x)+0)
|
|
||||||
#define SER_DLL(x) ((PUCHAR)(x)+0)
|
|
||||||
#define SER_IER(x) ((PUCHAR)(x)+1)
|
|
||||||
#define SR_IER_ERDA 0x01
|
|
||||||
#define SR_IER_ETHRE 0x02
|
|
||||||
#define SR_IER_ERLSI 0x04
|
|
||||||
#define SR_IER_EMS 0x08
|
|
||||||
#define SR_IER_ALL 0x0F
|
|
||||||
#define SER_DLM(x) ((PUCHAR)(x)+1)
|
|
||||||
#define SER_IIR(x) ((PUCHAR)(x)+2)
|
|
||||||
#define SER_FCR(x) ((PUCHAR)(x)+2)
|
|
||||||
#define SR_FCR_ENABLE_FIFO 0x01
|
|
||||||
#define SR_FCR_CLEAR_RCVR 0x02
|
|
||||||
#define SR_FCR_CLEAR_XMIT 0x04
|
|
||||||
#define SER_LCR(x) ((PUCHAR)(x)+3)
|
|
||||||
#define SR_LCR_CS5 0x00
|
|
||||||
#define SR_LCR_CS6 0x01
|
|
||||||
#define SR_LCR_CS7 0x02
|
|
||||||
#define SR_LCR_CS8 0x03
|
|
||||||
#define SR_LCR_ST1 0x00
|
|
||||||
#define SR_LCR_ST2 0x04
|
|
||||||
#define SR_LCR_PNO 0x00
|
|
||||||
#define SR_LCR_POD 0x08
|
|
||||||
#define SR_LCR_PEV 0x18
|
|
||||||
#define SR_LCR_PMK 0x28
|
|
||||||
#define SR_LCR_PSP 0x38
|
|
||||||
#define SR_LCR_BRK 0x40
|
|
||||||
#define SR_LCR_DLAB 0x80
|
|
||||||
#define SER_MCR(x) ((PUCHAR)(x)+4)
|
|
||||||
#define SR_MCR_DTR 0x01
|
|
||||||
#define SR_MCR_RTS 0x02
|
|
||||||
#define SR_MCR_OUT1 0x04
|
|
||||||
#define SR_MCR_OUT2 0x08
|
|
||||||
#define SR_MCR_LOOP 0x10
|
|
||||||
#define SER_LSR(x) ((PUCHAR)(x)+5)
|
|
||||||
#define SR_LSR_DR 0x01
|
|
||||||
#define SR_LSR_TBE 0x20
|
|
||||||
#define SER_MSR(x) ((PUCHAR)(x)+6)
|
|
||||||
#define SR_MSR_CTS 0x10
|
|
||||||
#define SR_MSR_DSR 0x20
|
|
||||||
#define SER_SCR(x) ((PUCHAR)(x)+7)
|
|
||||||
|
|
||||||
|
/* The COM port must only be initialized once! */
|
||||||
/* STATIC VARIABLES *********************************************************/
|
|
||||||
|
|
||||||
// static KD_PORT_INFORMATION DefaultPort = { 0, 0, 0 };
|
|
||||||
|
|
||||||
/* The com port must only be initialized once! */
|
|
||||||
// static BOOLEAN PortInitialized = FALSE;
|
// static BOOLEAN PortInitialized = FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,14 +49,11 @@ const ULONG BaseArray[] = {0, 0xF1012000};
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortInitializeEx(
|
KdPortInitializeEx(
|
||||||
IN PKD_PORT_INFORMATION PortInformation,
|
IN PCPPORT PortInformation,
|
||||||
IN ULONG Unknown1,
|
IN ULONG ComPortNumber)
|
||||||
IN ULONG Unknown2)
|
|
||||||
{
|
{
|
||||||
ULONG ComPortBase;
|
NTSTATUS Status;
|
||||||
CHAR buffer[80];
|
CHAR buffer[80];
|
||||||
ULONG divisor;
|
|
||||||
UCHAR lcr;
|
|
||||||
|
|
||||||
#if 0 // Deactivated because never used in fact (was in KdPortInitialize but we use KdPortInitializeEx)
|
#if 0 // Deactivated because never used in fact (was in KdPortInitialize but we use KdPortInitializeEx)
|
||||||
/*
|
/*
|
||||||
|
@ -122,7 +65,7 @@ KdPortInitializeEx(
|
||||||
{
|
{
|
||||||
DefaultPort.BaudRate = PortInformation->BaudRate;
|
DefaultPort.BaudRate = PortInformation->BaudRate;
|
||||||
|
|
||||||
if (PortInformation->ComPort == 0)
|
if (ComPortNumber == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Start enumerating COM ports from the last one to the first one,
|
* Start enumerating COM ports from the last one to the first one,
|
||||||
|
@ -134,12 +77,12 @@ KdPortInitializeEx(
|
||||||
{
|
{
|
||||||
if (CpDoesPortExist(UlongToPtr(BaseArray[i])))
|
if (CpDoesPortExist(UlongToPtr(BaseArray[i])))
|
||||||
{
|
{
|
||||||
PortInformation->BaseAddress = DefaultPort.BaseAddress = BaseArray[i];
|
PortInformation->Address = DefaultPort.Address = BaseArray[i];
|
||||||
PortInformation->ComPort = DefaultPort.ComPort = i;
|
ComPortNumber = (ULONG)i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == 0)
|
if (ComPortNumber == 0)
|
||||||
{
|
{
|
||||||
sprintf(buffer,
|
sprintf(buffer,
|
||||||
"\nKernel Debugger: No COM port found!\n\n");
|
"\nKernel Debugger: No COM port found!\n\n");
|
||||||
|
@ -155,108 +98,54 @@ KdPortInitializeEx(
|
||||||
/*
|
/*
|
||||||
* Initialize the port
|
* Initialize the port
|
||||||
*/
|
*/
|
||||||
|
Status = CpInitialize(PortInformation,
|
||||||
if (PortInformation->BaudRate == 0)
|
(ComPortNumber == 0 ? PortInformation->Address
|
||||||
PortInformation->BaudRate = DEFAULT_BAUD_RATE;
|
: UlongToPtr(BaseArray[ComPortNumber])),
|
||||||
|
(PortInformation->BaudRate == 0 ? DEFAULT_BAUD_RATE
|
||||||
if (PortInformation->ComPort != 0)
|
: PortInformation->BaudRate));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (!CpDoesPortExist(UlongToPtr(BaseArray[PortInformation->ComPort])))
|
sprintf(buffer,
|
||||||
{
|
"\nKernel Debugger: Serial port not found!\n\n");
|
||||||
sprintf(buffer,
|
HalDisplayString(buffer);
|
||||||
"\nKernel Debugger: Serial port not found!\n\n");
|
return FALSE;
|
||||||
HalDisplayString(buffer);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComPortBase = BaseArray[PortInformation->ComPort];
|
|
||||||
PortInformation->BaseAddress = ComPortBase;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ComPortBase = PortInformation->BaseAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ComPortBase == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
sprintf(buffer,
|
/* Print message to blue screen */
|
||||||
"\nSerial port COM%ld found at 0x%lx\n",
|
sprintf(buffer,
|
||||||
PortInformation->ComPort,
|
"\nKernel Debugger: Serial port found: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
|
||||||
ComPortBase);
|
ComPortNumber,
|
||||||
HalDisplayString(buffer);
|
PortInformation->Address,
|
||||||
#endif /* NDEBUG */
|
PortInformation->BaudRate);
|
||||||
|
HalDisplayString(buffer);
|
||||||
/* set baud rate and data format (8N1) */
|
|
||||||
|
|
||||||
/* turn on DTR and RTS */
|
|
||||||
WRITE_PORT_UCHAR(SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS);
|
|
||||||
|
|
||||||
/* set DLAB */
|
|
||||||
lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase)) | SR_LCR_DLAB;
|
|
||||||
WRITE_PORT_UCHAR(SER_LCR(ComPortBase), lcr);
|
|
||||||
|
|
||||||
/* set baud rate */
|
|
||||||
divisor = 115200 / PortInformation->BaudRate;
|
|
||||||
WRITE_PORT_UCHAR(SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff));
|
|
||||||
WRITE_PORT_UCHAR(SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff));
|
|
||||||
|
|
||||||
/* reset DLAB and set 8N1 format */
|
|
||||||
WRITE_PORT_UCHAR(SER_LCR(ComPortBase),
|
|
||||||
SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
|
|
||||||
|
|
||||||
/* read junk out of the RBR */
|
|
||||||
lcr = READ_PORT_UCHAR(SER_RBR(ComPortBase));
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
/* print message to blue screen */
|
|
||||||
sprintf(buffer,
|
|
||||||
"\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
|
|
||||||
PortInformation->ComPort,
|
|
||||||
ComPortBase,
|
|
||||||
PortInformation->BaudRate);
|
|
||||||
|
|
||||||
HalDisplayString(buffer);
|
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* set global info */
|
/* Set global info */
|
||||||
KdComPortInUse = (PUCHAR)DefaultPort.BaseAddress;
|
KdComPortInUse = DefaultPort.Address;
|
||||||
#endif
|
#endif
|
||||||
|
return TRUE;
|
||||||
return TRUE;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortGetByteEx(
|
KdPortGetByteEx(
|
||||||
IN PKD_PORT_INFORMATION PortInformation,
|
IN PCPPORT PortInformation,
|
||||||
OUT PUCHAR ByteReceived)
|
OUT PUCHAR ByteReceived)
|
||||||
{
|
{
|
||||||
PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
|
return (CpGetByte(PortInformation, ByteReceived, FALSE) == CP_GET_SUCCESS);
|
||||||
|
|
||||||
if ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR))
|
|
||||||
{
|
|
||||||
*ByteReceived = READ_PORT_UCHAR(SER_RBR(ComPortBase));
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortPutByteEx(
|
KdPortPutByteEx(
|
||||||
IN PKD_PORT_INFORMATION PortInformation,
|
IN PCPPORT PortInformation,
|
||||||
IN UCHAR ByteToSend)
|
IN UCHAR ByteToSend)
|
||||||
{
|
{
|
||||||
PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
|
CpPutByte(PortInformation, ByteToSend);
|
||||||
|
|
||||||
while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
|
|
||||||
;
|
|
||||||
|
|
||||||
WRITE_PORT_UCHAR(SER_THR(ComPortBase), ByteToSend);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -8,6 +8,6 @@
|
||||||
8 stdcall KdSendPacket(long ptr ptr ptr)
|
8 stdcall KdSendPacket(long ptr ptr ptr)
|
||||||
|
|
||||||
; Legacy KD
|
; Legacy KD
|
||||||
@ stdcall KdPortInitializeEx(ptr long long)
|
@ stdcall KdPortInitializeEx(ptr long)
|
||||||
@ stdcall KdPortGetByteEx(ptr ptr)
|
@ stdcall KdPortGetByteEx(ptr ptr)
|
||||||
@ stdcall KdPortPutByteEx(ptr long)
|
@ stdcall KdPortPutByteEx(ptr long)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cportlib/cportlib.h>
|
||||||
|
|
||||||
#ifdef _M_PPC
|
#ifdef _M_PPC
|
||||||
#define KdDebuggerEnabled _KdDebuggerEnabled
|
#define KdDebuggerEnabled _KdDebuggerEnabled
|
||||||
#define KdDebuggerNotPresent _KdDebuggerNotPresent
|
#define KdDebuggerNotPresent _KdDebuggerNotPresent
|
||||||
|
@ -8,15 +10,8 @@
|
||||||
//
|
//
|
||||||
// Kernel Debugger Port Definition
|
// Kernel Debugger Port Definition
|
||||||
//
|
//
|
||||||
typedef struct _KD_PORT_INFORMATION
|
|
||||||
{
|
|
||||||
ULONG ComPort;
|
|
||||||
ULONG BaudRate;
|
|
||||||
ULONG BaseAddress;
|
|
||||||
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
|
|
||||||
|
|
||||||
struct _KD_DISPATCH_TABLE;
|
struct _KD_DISPATCH_TABLE;
|
||||||
extern KD_PORT_INFORMATION GdbPortInfo;
|
extern CPPORT GdbPortInfo;
|
||||||
extern BOOLEAN _KdDebuggerEnabled;
|
extern BOOLEAN _KdDebuggerEnabled;
|
||||||
extern BOOLEAN _KdDebuggerNotPresent;
|
extern BOOLEAN _KdDebuggerNotPresent;
|
||||||
extern BOOLEAN KdBreakAfterSymbolLoad;
|
extern BOOLEAN KdBreakAfterSymbolLoad;
|
||||||
|
@ -26,21 +21,20 @@ extern BOOLEAN KdIgnoreUmExceptions;
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortInitializeEx(
|
KdPortInitializeEx(
|
||||||
PKD_PORT_INFORMATION PortInformation,
|
PCPPORT PortInformation,
|
||||||
ULONG Unknown1,
|
ULONG ComPortNumber
|
||||||
ULONG Unknown2
|
|
||||||
);
|
);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortGetByteEx(
|
KdPortGetByteEx(
|
||||||
PKD_PORT_INFORMATION PortInformation,
|
PCPPORT PortInformation,
|
||||||
PUCHAR ByteReceived);
|
PUCHAR ByteReceived);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortPutByteEx(
|
KdPortPutByteEx(
|
||||||
PKD_PORT_INFORMATION PortInformation,
|
PCPPORT PortInformation,
|
||||||
UCHAR ByteToSend
|
UCHAR ByteToSend
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -340,7 +334,8 @@ extern ULONG KdpPortIrq;
|
||||||
extern ULONG KdpPort;
|
extern ULONG KdpPort;
|
||||||
|
|
||||||
/* Port Information for the Serial Native Mode */
|
/* Port Information for the Serial Native Mode */
|
||||||
extern KD_PORT_INFORMATION SerialPortInfo;
|
extern ULONG SerialPortNumber;
|
||||||
|
extern CPPORT SerialPortInfo;
|
||||||
|
|
||||||
/* Init Functions for Native Providers */
|
/* Init Functions for Native Providers */
|
||||||
extern PKDP_INIT_ROUTINE InitRoutines[KdMax];
|
extern PKDP_INIT_ROUTINE InitRoutines[KdMax];
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
/* VARIABLES ***************************************************************/
|
/* VARIABLES ***************************************************************/
|
||||||
|
|
||||||
KD_PORT_INFORMATION PortInfo = {DEFAULT_DEBUG_PORT, DEFAULT_DEBUG_BAUD_RATE, 0};
|
ULONG PortNumber = DEFAULT_DEBUG_PORT;
|
||||||
|
CPPORT PortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||||
ULONG KdpPortIrq;
|
ULONG KdpPortIrq;
|
||||||
#ifdef AUTO_ENABLE_BOCHS
|
#ifdef AUTO_ENABLE_BOCHS
|
||||||
KDP_DEBUG_MODE KdpDebugMode = {{{.Bochs=TRUE}}};
|
KDP_DEBUG_MODE KdpDebugMode = {{{.Bochs=TRUE}}};
|
||||||
|
@ -68,7 +69,7 @@ KdpGetDebugMode(PCHAR Currentp2)
|
||||||
KdpDebugMode.Serial = TRUE;
|
KdpDebugMode.Serial = TRUE;
|
||||||
|
|
||||||
/* Set the port to use */
|
/* Set the port to use */
|
||||||
SerialPortInfo.ComPort = Value;
|
SerialPortNumber = Value;
|
||||||
KdpPort = Value;
|
KdpPort = Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,8 +79,8 @@ KdpGetDebugMode(PCHAR Currentp2)
|
||||||
if (Value)
|
if (Value)
|
||||||
{
|
{
|
||||||
KdpDebugMode.Serial = TRUE;
|
KdpDebugMode.Serial = TRUE;
|
||||||
SerialPortInfo.BaseAddress = Value;
|
SerialPortInfo.Address = UlongToPtr(Value);
|
||||||
SerialPortInfo.ComPort = 0;
|
SerialPortNumber = 0;
|
||||||
KdpPort = 0;
|
KdpPort = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@ HANDLE KdpLogFileHandle;
|
||||||
ANSI_STRING KdpLogFileName = RTL_CONSTANT_STRING("\\SystemRoot\\debug.log");
|
ANSI_STRING KdpLogFileName = RTL_CONSTANT_STRING("\\SystemRoot\\debug.log");
|
||||||
|
|
||||||
KSPIN_LOCK KdpSerialSpinLock;
|
KSPIN_LOCK KdpSerialSpinLock;
|
||||||
KD_PORT_INFORMATION SerialPortInfo = { DEFAULT_DEBUG_PORT, DEFAULT_DEBUG_BAUD_RATE, 0 };
|
ULONG SerialPortNumber = DEFAULT_DEBUG_PORT;
|
||||||
|
CPPORT SerialPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||||
|
|
||||||
/* Current Port in use. FIXME: Do we support more then one? */
|
/* Current Port in use. FIXME: Do we support more then one? */
|
||||||
ULONG KdpPort;
|
ULONG KdpPort;
|
||||||
|
@ -358,12 +359,12 @@ KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable,
|
||||||
DispatchTable->KdpPrintRoutine = KdpSerialDebugPrint;
|
DispatchTable->KdpPrintRoutine = KdpSerialDebugPrint;
|
||||||
|
|
||||||
/* Initialize the Port */
|
/* Initialize the Port */
|
||||||
if (!KdPortInitializeEx(&SerialPortInfo, 0, 0))
|
if (!KdPortInitializeEx(&SerialPortInfo, SerialPortNumber))
|
||||||
{
|
{
|
||||||
KdpDebugMode.Serial = FALSE;
|
KdpDebugMode.Serial = FALSE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
KdComPortInUse = (PUCHAR)(ULONG_PTR)SerialPortInfo.BaseAddress;
|
KdComPortInUse = SerialPortInfo.Address;
|
||||||
|
|
||||||
/* Initialize spinlock */
|
/* Initialize spinlock */
|
||||||
KeInitializeSpinLock(&KdpSerialSpinLock);
|
KeInitializeSpinLock(&KdpSerialSpinLock);
|
||||||
|
|
|
@ -44,7 +44,8 @@ static FAST_MUTEX GspLock;
|
||||||
extern LIST_ENTRY PsActiveProcessHead;
|
extern LIST_ENTRY PsActiveProcessHead;
|
||||||
|
|
||||||
/* FIXME hardcoded for COM2, 115200 baud */
|
/* FIXME hardcoded for COM2, 115200 baud */
|
||||||
KD_PORT_INFORMATION GdbPortInfo = { 2, 115200, 0 };
|
ULONG GdbPortNumber = DEFAULT_DEBUG_PORT;
|
||||||
|
CPPORT GdbPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||||
|
|
||||||
static CHAR GspInBuffer[1000];
|
static CHAR GspInBuffer[1000];
|
||||||
static CHAR GspOutBuffer[1000];
|
static CHAR GspOutBuffer[1000];
|
||||||
|
@ -126,9 +127,7 @@ GdbGetChar(VOID)
|
||||||
{
|
{
|
||||||
UCHAR Value;
|
UCHAR Value;
|
||||||
|
|
||||||
while (!KdPortGetByteEx(&GdbPortInfo, &Value))
|
while (!KdPortGetByteEx(&GdbPortInfo, &Value)) ;
|
||||||
;
|
|
||||||
|
|
||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +144,7 @@ GspGetPacket()
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
/* wait around for the start character, ignore all other characters */
|
/* wait around for the start character, ignore all other characters */
|
||||||
while ((ch = GdbGetChar()) != '$')
|
while ((ch = GdbGetChar()) != '$') ;
|
||||||
;
|
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
Checksum = 0;
|
Checksum = 0;
|
||||||
|
@ -784,7 +782,6 @@ GspQuery(PCHAR Request)
|
||||||
}
|
}
|
||||||
else if (strncmp(Request, "Rcmd,", 5) == 0)
|
else if (strncmp(Request, "Rcmd,", 5) == 0)
|
||||||
{
|
{
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -943,12 +940,14 @@ GspFindSwBreakpoint(ULONG_PTR Address, PULONG PIndex)
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
|
||||||
for (Index = 0; Index < GspSwBreakpointCount; Index++)
|
for (Index = 0; Index < GspSwBreakpointCount; Index++)
|
||||||
|
{
|
||||||
if (GspSwBreakpoints[Index].Address == Address)
|
if (GspSwBreakpoints[Index].Address == Address)
|
||||||
{
|
{
|
||||||
if (PIndex)
|
if (PIndex)
|
||||||
*PIndex = Index;
|
*PIndex = Index;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1569,7 +1568,7 @@ KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable, ULONG BootPhase)
|
||||||
WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
|
WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
|
||||||
|
|
||||||
/* Initialize the Port */
|
/* Initialize the Port */
|
||||||
KdPortInitializeEx(&GdbPortInfo, 0, 0);
|
KdPortInitializeEx(&GdbPortInfo, GdbPortNumber);
|
||||||
}
|
}
|
||||||
else if (BootPhase == 1)
|
else if (BootPhase == 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,12 +88,8 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
|
|
||||||
/* at least NUMREGBYTES*2 are needed for register packets */
|
|
||||||
#define BUFMAX 1000
|
|
||||||
|
|
||||||
static BOOLEAN GspInitialized;
|
static BOOLEAN GspInitialized;
|
||||||
|
|
||||||
static BOOLEAN GspRemoteDebug;
|
static BOOLEAN GspRemoteDebug;
|
||||||
|
|
||||||
static CONST CHAR HexChars[]="0123456789abcdef";
|
static CONST CHAR HexChars[]="0123456789abcdef";
|
||||||
|
@ -107,25 +103,32 @@ static FAST_MUTEX GspLock;
|
||||||
extern LIST_ENTRY PsActiveProcessHead;
|
extern LIST_ENTRY PsActiveProcessHead;
|
||||||
|
|
||||||
/* FIXME hardcoded for COM2, 115200 baud */
|
/* FIXME hardcoded for COM2, 115200 baud */
|
||||||
KD_PORT_INFORMATION GdbPortInfo = { 2, 115200, 0 };
|
ULONG GdbPortNumber = DEFAULT_DEBUG_PORT;
|
||||||
|
CPPORT GdbPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
||||||
|
|
||||||
|
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
|
||||||
|
/* at least NUMREGBYTES*2 are needed for register packets */
|
||||||
|
#define BUFMAX 1000
|
||||||
|
static CHAR GspInBuffer[BUFMAX];
|
||||||
|
static CHAR GspOutBuffer[BUFMAX];
|
||||||
|
|
||||||
/* Number of Registers. */
|
/* Number of Registers. */
|
||||||
#define NUMREGS 16
|
#define NUMREGS 16
|
||||||
|
|
||||||
enum REGISTER_NAMES
|
enum REGISTER_NAMES
|
||||||
{
|
{
|
||||||
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
|
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
|
||||||
PC /* also known as eip */,
|
PC /* also known as eip */,
|
||||||
PS /* also known as eflags */,
|
PS /* also known as eflags */,
|
||||||
CS, SS, DS, ES, FS, GS
|
CS, SS, DS, ES, FS, GS
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _CPU_REGISTER
|
typedef struct _CPU_REGISTER
|
||||||
{
|
{
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
ULONG OffsetInTF;
|
ULONG OffsetInTF;
|
||||||
ULONG OffsetInContext;
|
ULONG OffsetInContext;
|
||||||
BOOLEAN SetInContext;
|
BOOLEAN SetInContext;
|
||||||
} CPU_REGISTER, *PCPU_REGISTER;
|
} CPU_REGISTER, *PCPU_REGISTER;
|
||||||
|
|
||||||
static CPU_REGISTER GspRegisters[NUMREGS] =
|
static CPU_REGISTER GspRegisters[NUMREGS] =
|
||||||
|
@ -134,54 +137,45 @@ static CPU_REGISTER GspRegisters[NUMREGS] =
|
||||||
|
|
||||||
static PCHAR GspThreadStates[DeferredReady+1] =
|
static PCHAR GspThreadStates[DeferredReady+1] =
|
||||||
{
|
{
|
||||||
"Initialized",
|
"Initialized",
|
||||||
"Ready",
|
"Ready",
|
||||||
"Running",
|
"Running",
|
||||||
"Standby",
|
"Standby",
|
||||||
"Terminated",
|
"Terminated",
|
||||||
"Waiting",
|
"Waiting",
|
||||||
"Transition",
|
"Transition",
|
||||||
"DeferredReady"
|
"DeferredReady"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
HexValue(CHAR ch)
|
HexValue(CHAR ch)
|
||||||
{
|
{
|
||||||
if ((ch >= '0') && (ch <= '9'))
|
if ((ch >= '0') && (ch <= '9'))
|
||||||
{
|
return (ch - '0');
|
||||||
return (ch - '0');
|
|
||||||
}
|
|
||||||
if ((ch >= 'a') && (ch <= 'f'))
|
|
||||||
{
|
|
||||||
return (ch - 'a' + 10);
|
|
||||||
}
|
|
||||||
if ((ch >= 'A') && (ch <= 'F'))
|
|
||||||
{
|
|
||||||
return (ch - 'A' + 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
if ((ch >= 'a') && (ch <= 'f'))
|
||||||
|
return (ch - 'a' + 10);
|
||||||
|
|
||||||
|
if ((ch >= 'A') && (ch <= 'F'))
|
||||||
|
return (ch - 'A' + 10);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CHAR GspInBuffer[BUFMAX];
|
|
||||||
static CHAR GspOutBuffer[BUFMAX];
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GdbPutChar(UCHAR Value)
|
GdbPutChar(UCHAR Value)
|
||||||
{
|
{
|
||||||
KdPortPutByteEx(&GdbPortInfo, Value);
|
KdPortPutByteEx(&GdbPortInfo, Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
UCHAR
|
UCHAR
|
||||||
GdbGetChar(VOID)
|
GdbGetChar(VOID)
|
||||||
{
|
{
|
||||||
UCHAR Value;
|
UCHAR Value;
|
||||||
|
|
||||||
while (!KdPortGetByteEx(&GdbPortInfo, &Value))
|
while (!KdPortGetByteEx(&GdbPortInfo, &Value)) ;
|
||||||
;
|
return Value;
|
||||||
|
|
||||||
return Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* scan for the sequence $<data>#<Checksum> */
|
/* scan for the sequence $<data>#<Checksum> */
|
||||||
|
@ -189,57 +183,53 @@ GdbGetChar(VOID)
|
||||||
PCHAR
|
PCHAR
|
||||||
GspGetPacket()
|
GspGetPacket()
|
||||||
{
|
{
|
||||||
PCHAR Buffer = &GspInBuffer[0];
|
PCHAR Buffer = &GspInBuffer[0];
|
||||||
CHAR Checksum;
|
CHAR Checksum;
|
||||||
CHAR XmitChecksum;
|
CHAR XmitChecksum;
|
||||||
ULONG Count;
|
ULONG Count;
|
||||||
CHAR ch;
|
CHAR ch;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
/* wait around for the start character, ignore all other characters */
|
/* wait around for the start character, ignore all other characters */
|
||||||
while ((ch = GdbGetChar ()) != '$')
|
while ((ch = GdbGetChar ()) != '$') ;
|
||||||
;
|
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
Checksum = 0;
|
Checksum = 0;
|
||||||
XmitChecksum = -1;
|
XmitChecksum = -1;
|
||||||
Count = 0;
|
Count = 0;
|
||||||
|
|
||||||
/* now, read until a # or end of Buffer is found */
|
/* now, read until a # or end of Buffer is found */
|
||||||
while (Count < BUFMAX)
|
while (Count < BUFMAX)
|
||||||
{
|
{
|
||||||
ch = GdbGetChar();
|
ch = GdbGetChar();
|
||||||
if (ch == '$')
|
if (ch == '$')
|
||||||
{
|
goto retry;
|
||||||
goto retry;
|
|
||||||
}
|
if (ch == '#')
|
||||||
if (ch == '#')
|
break;
|
||||||
{
|
|
||||||
break;
|
Checksum = Checksum + ch;
|
||||||
}
|
Buffer[Count] = ch;
|
||||||
Checksum = Checksum + ch;
|
Count = Count + 1;
|
||||||
Buffer[Count] = ch;
|
|
||||||
Count = Count + 1;
|
|
||||||
}
|
}
|
||||||
Buffer[Count] = 0;
|
Buffer[Count] = 0;
|
||||||
|
|
||||||
if (ch == '#')
|
if (ch == '#')
|
||||||
{
|
{
|
||||||
ch = GdbGetChar();
|
ch = GdbGetChar();
|
||||||
XmitChecksum = (CHAR)(HexValue(ch) << 4);
|
XmitChecksum = (CHAR)(HexValue(ch) << 4);
|
||||||
ch = GdbGetChar();
|
ch = GdbGetChar();
|
||||||
XmitChecksum += (CHAR)(HexValue(ch));
|
XmitChecksum += (CHAR)(HexValue(ch));
|
||||||
|
|
||||||
if (Checksum != XmitChecksum)
|
if (Checksum != XmitChecksum)
|
||||||
{
|
{
|
||||||
GdbPutChar('-'); /* failed checksum */
|
GdbPutChar('-'); /* failed checksum */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GdbPutChar('+'); /* successful transfer */
|
GdbPutChar('+'); /* successful transfer */
|
||||||
|
return &Buffer[0];
|
||||||
return &Buffer[0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,54 +240,54 @@ GspGetPacket()
|
||||||
VOID
|
VOID
|
||||||
GspPutPacket(PCHAR Buffer)
|
GspPutPacket(PCHAR Buffer)
|
||||||
{
|
{
|
||||||
CHAR Checksum;
|
CHAR Checksum;
|
||||||
LONG Count;
|
LONG Count;
|
||||||
CHAR ch;
|
CHAR ch;
|
||||||
|
|
||||||
/* $<packet info>#<Checksum>. */
|
/* $<packet info>#<Checksum>. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
GdbPutChar('$');
|
GdbPutChar('$');
|
||||||
Checksum = 0;
|
Checksum = 0;
|
||||||
Count = 0;
|
Count = 0;
|
||||||
|
|
||||||
while ((ch = Buffer[Count]))
|
while ((ch = Buffer[Count]))
|
||||||
{
|
{
|
||||||
GdbPutChar(ch);
|
GdbPutChar(ch);
|
||||||
Checksum += ch;
|
Checksum += ch;
|
||||||
Count += 1;
|
Count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
GdbPutChar('#');
|
GdbPutChar('#');
|
||||||
GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
|
GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
|
||||||
GdbPutChar(HexChars[Checksum & 0xf]);
|
GdbPutChar(HexChars[Checksum & 0xf]);
|
||||||
}
|
}
|
||||||
while (GdbGetChar() != '+');
|
while (GdbGetChar() != '+');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GspPutPacketNoWait(PCHAR Buffer)
|
GspPutPacketNoWait(PCHAR Buffer)
|
||||||
{
|
{
|
||||||
CHAR Checksum;
|
CHAR Checksum;
|
||||||
LONG Count;
|
LONG Count;
|
||||||
CHAR ch;
|
CHAR ch;
|
||||||
|
|
||||||
/* $<packet info>#<Checksum>. */
|
/* $<packet info>#<Checksum>. */
|
||||||
GdbPutChar('$');
|
GdbPutChar('$');
|
||||||
Checksum = 0;
|
Checksum = 0;
|
||||||
Count = 0;
|
Count = 0;
|
||||||
|
|
||||||
while ((ch = Buffer[Count]))
|
while ((ch = Buffer[Count]))
|
||||||
{
|
{
|
||||||
GdbPutChar(ch);
|
GdbPutChar(ch);
|
||||||
Checksum += ch;
|
Checksum += ch;
|
||||||
Count += 1;
|
Count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
GdbPutChar('#');
|
GdbPutChar('#');
|
||||||
GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
|
GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
|
||||||
GdbPutChar(HexChars[Checksum & 0xf]);
|
GdbPutChar(HexChars[Checksum & 0xf]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an
|
/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an
|
||||||
|
@ -308,19 +298,33 @@ static volatile void *GspAccessLocation = NULL;
|
||||||
static CHAR
|
static CHAR
|
||||||
GspReadMemSafe(PCHAR Address)
|
GspReadMemSafe(PCHAR Address)
|
||||||
{
|
{
|
||||||
CHAR ch;
|
CHAR ch;
|
||||||
|
|
||||||
if (NULL == Address)
|
if (NULL == Address)
|
||||||
{
|
{
|
||||||
GspMemoryError = TRUE;
|
GspMemoryError = TRUE;
|
||||||
return '\0';
|
return '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
GspAccessLocation = Address;
|
GspAccessLocation = Address;
|
||||||
ch = *Address;
|
ch = *Address;
|
||||||
GspAccessLocation = NULL;
|
GspAccessLocation = NULL;
|
||||||
|
|
||||||
return ch;
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CHAR
|
||||||
|
GspWriteMemSafeGetContent(PVOID Context, ULONG Offset)
|
||||||
|
{
|
||||||
|
ASSERT(0 == Offset);
|
||||||
|
return *((PCHAR) Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GspWriteMemSafe(PCHAR Address,
|
||||||
|
CHAR Ch)
|
||||||
|
{
|
||||||
|
GspWriteMem(Address, 1, TRUE, GspWriteMemSafeGetContent, &Ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the memory pointed to by Address into hex, placing result in Buffer */
|
/* Convert the memory pointed to by Address into hex, placing result in Buffer */
|
||||||
|
@ -329,131 +333,110 @@ GspReadMemSafe(PCHAR Address)
|
||||||
a fault; if FALSE treat a fault like any other fault in the stub. */
|
a fault; if FALSE treat a fault like any other fault in the stub. */
|
||||||
static PCHAR
|
static PCHAR
|
||||||
GspMem2Hex(PCHAR Address,
|
GspMem2Hex(PCHAR Address,
|
||||||
PCHAR Buffer,
|
PCHAR Buffer,
|
||||||
LONG Count,
|
LONG Count,
|
||||||
BOOLEAN MayFault)
|
BOOLEAN MayFault)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
CHAR ch;
|
CHAR ch;
|
||||||
|
|
||||||
for (i = 0; i < (ULONG) Count; i++)
|
for (i = 0; i < (ULONG) Count; i++)
|
||||||
{
|
{
|
||||||
if (MayFault)
|
if (MayFault)
|
||||||
{
|
{
|
||||||
ch = GspReadMemSafe(Address);
|
ch = GspReadMemSafe(Address);
|
||||||
if (GspMemoryError)
|
if (GspMemoryError)
|
||||||
{
|
return Buffer;
|
||||||
return Buffer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ch = *Address;
|
ch = *Address;
|
||||||
}
|
}
|
||||||
*Buffer++ = HexChars[(ch >> 4) & 0xf];
|
*Buffer++ = HexChars[(ch >> 4) & 0xf];
|
||||||
*Buffer++ = HexChars[ch & 0xf];
|
*Buffer++ = HexChars[ch & 0xf];
|
||||||
Address++;
|
Address++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*Buffer = 0;
|
*Buffer = 0;
|
||||||
return Buffer;
|
return Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG
|
static ULONG
|
||||||
GspWriteMem(PCHAR Address,
|
GspWriteMem(PCHAR Address,
|
||||||
ULONG Count,
|
ULONG Count,
|
||||||
BOOLEAN MayFault,
|
BOOLEAN MayFault,
|
||||||
CHAR (*GetContent)(PVOID Context, ULONG Offset),
|
CHAR (*GetContent)(PVOID Context, ULONG Offset),
|
||||||
PVOID Context)
|
PVOID Context)
|
||||||
{
|
{
|
||||||
PCHAR Current;
|
PCHAR Current;
|
||||||
PCHAR Page;
|
PCHAR Page;
|
||||||
ULONG CountInPage;
|
ULONG CountInPage;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
CHAR ch;
|
CHAR ch;
|
||||||
ULONG OldProt = 0;
|
ULONG OldProt = 0;
|
||||||
|
|
||||||
Current = Address;
|
Current = Address;
|
||||||
while (Current < Address + Count)
|
while (Current < Address + Count)
|
||||||
{
|
{
|
||||||
Page = (PCHAR)PAGE_ROUND_DOWN(Current);
|
Page = (PCHAR)PAGE_ROUND_DOWN(Current);
|
||||||
if (Address + Count <= Page + PAGE_SIZE)
|
if (Address + Count <= Page + PAGE_SIZE)
|
||||||
{
|
{
|
||||||
/* Fits in this page */
|
/* Fits in this page */
|
||||||
CountInPage = Count;
|
CountInPage = Count;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Flows into next page, handle only current page in this iteration */
|
/* Flows into next page, handle only current page in this iteration */
|
||||||
CountInPage = PAGE_SIZE - (Address - Page);
|
CountInPage = PAGE_SIZE - (Address - Page);
|
||||||
}
|
}
|
||||||
if (MayFault)
|
if (MayFault)
|
||||||
{
|
{
|
||||||
OldProt = MmGetPageProtect(NULL, Address);
|
OldProt = MmGetPageProtect(NULL, Address);
|
||||||
MmSetPageProtect(NULL, Address, PAGE_EXECUTE_READWRITE);
|
MmSetPageProtect(NULL, Address, PAGE_EXECUTE_READWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < CountInPage && ! GspMemoryError; i++)
|
for (i = 0; i < CountInPage && ! GspMemoryError; i++)
|
||||||
{
|
{
|
||||||
ch = (*GetContent)(Context, Current - Address);
|
ch = (*GetContent)(Context, Current - Address);
|
||||||
|
|
||||||
if (MayFault)
|
if (MayFault)
|
||||||
{
|
GspAccessLocation = Current;
|
||||||
GspAccessLocation = Current;
|
|
||||||
}
|
*Current = ch;
|
||||||
*Current = ch;
|
|
||||||
if (MayFault)
|
if (MayFault)
|
||||||
{
|
GspAccessLocation = NULL;
|
||||||
GspAccessLocation = NULL;
|
|
||||||
}
|
Current++;
|
||||||
Current++;
|
|
||||||
}
|
}
|
||||||
if (MayFault)
|
if (MayFault)
|
||||||
{
|
{
|
||||||
MmSetPageProtect(NULL, Page, OldProt);
|
MmSetPageProtect(NULL, Page, OldProt);
|
||||||
if (GspMemoryError)
|
if (GspMemoryError)
|
||||||
{
|
return Current - Address;
|
||||||
return Current - Address;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Current - Address;
|
return Current - Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CHAR
|
static CHAR
|
||||||
GspHex2MemGetContent(PVOID Context, ULONG Offset)
|
GspHex2MemGetContent(PVOID Context, ULONG Offset)
|
||||||
{
|
{
|
||||||
return (CHAR)((HexValue(*((PCHAR) Context + 2 * Offset)) << 4) +
|
return (CHAR)((HexValue(*((PCHAR) Context + 2 * Offset)) << 4) +
|
||||||
HexValue(*((PCHAR) Context + 2 * Offset + 1)));
|
HexValue(*((PCHAR) Context + 2 * Offset + 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the hex array pointed to by Buffer into binary to be placed at Address */
|
/* Convert the hex array pointed to by Buffer into binary to be placed at Address */
|
||||||
/* Return a pointer to the character AFTER the last byte read from Buffer */
|
/* Return a pointer to the character AFTER the last byte read from Buffer */
|
||||||
static PCHAR
|
static PCHAR
|
||||||
GspHex2Mem(PCHAR Buffer,
|
GspHex2Mem(PCHAR Buffer,
|
||||||
PCHAR Address,
|
PCHAR Address,
|
||||||
ULONG Count,
|
ULONG Count,
|
||||||
BOOLEAN MayFault)
|
BOOLEAN MayFault)
|
||||||
{
|
{
|
||||||
Count = GspWriteMem(Address, Count, MayFault, GspHex2MemGetContent, Buffer);
|
Count = GspWriteMem(Address, Count, MayFault, GspHex2MemGetContent, Buffer);
|
||||||
|
return Buffer + 2 * Count;
|
||||||
return Buffer + 2 * Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CHAR
|
|
||||||
GspWriteMemSafeGetContent(PVOID Context, ULONG Offset)
|
|
||||||
{
|
|
||||||
ASSERT(0 == Offset);
|
|
||||||
|
|
||||||
return *((PCHAR) Context);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
GspWriteMemSafe(PCHAR Address,
|
|
||||||
CHAR Ch)
|
|
||||||
{
|
|
||||||
GspWriteMem(Address, 1, TRUE, GspWriteMemSafeGetContent, &Ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -462,33 +445,38 @@ GspWriteMemSafe(PCHAR Address,
|
||||||
ULONG
|
ULONG
|
||||||
GspComputeSignal(NTSTATUS ExceptionCode)
|
GspComputeSignal(NTSTATUS ExceptionCode)
|
||||||
{
|
{
|
||||||
ULONG SigVal;
|
ULONG SigVal;
|
||||||
|
|
||||||
switch (ExceptionCode)
|
switch (ExceptionCode)
|
||||||
{
|
{
|
||||||
case STATUS_INTEGER_DIVIDE_BY_ZERO:
|
case STATUS_INTEGER_DIVIDE_BY_ZERO:
|
||||||
SigVal = 8; /* divide by zero */
|
SigVal = 8; /* divide by zero */
|
||||||
break;
|
break;
|
||||||
case STATUS_SINGLE_STEP:
|
|
||||||
case STATUS_BREAKPOINT:
|
case STATUS_SINGLE_STEP:
|
||||||
SigVal = 5; /* breakpoint */
|
case STATUS_BREAKPOINT:
|
||||||
break;
|
SigVal = 5; /* breakpoint */
|
||||||
case STATUS_INTEGER_OVERFLOW:
|
break;
|
||||||
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
|
||||||
SigVal = 16; /* bound instruction */
|
case STATUS_INTEGER_OVERFLOW:
|
||||||
break;
|
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
||||||
case STATUS_ILLEGAL_INSTRUCTION:
|
SigVal = 16; /* bound instruction */
|
||||||
SigVal = 4; /* Invalid opcode */
|
break;
|
||||||
break;
|
|
||||||
case STATUS_STACK_OVERFLOW:
|
case STATUS_ILLEGAL_INSTRUCTION:
|
||||||
case STATUS_DATATYPE_MISALIGNMENT:
|
SigVal = 4; /* Invalid opcode */
|
||||||
case STATUS_ACCESS_VIOLATION:
|
break;
|
||||||
SigVal = 11; /* access violation */
|
|
||||||
break;
|
case STATUS_STACK_OVERFLOW:
|
||||||
default:
|
case STATUS_DATATYPE_MISALIGNMENT:
|
||||||
SigVal = 7; /* "software generated" */
|
case STATUS_ACCESS_VIOLATION:
|
||||||
|
SigVal = 11; /* access violation */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SigVal = 7; /* "software generated" */
|
||||||
}
|
}
|
||||||
return SigVal;
|
return SigVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1626,43 +1614,39 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
GspBreakIn(PKINTERRUPT Interrupt,
|
GspBreakIn(PKINTERRUPT Interrupt,
|
||||||
PVOID ServiceContext)
|
PVOID ServiceContext)
|
||||||
{
|
{
|
||||||
PKTRAP_FRAME TrapFrame;
|
PKTRAP_FRAME TrapFrame;
|
||||||
BOOLEAN DoBreakIn;
|
BOOLEAN DoBreakIn;
|
||||||
CONTEXT Context;
|
CONTEXT Context;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
UCHAR Value;
|
UCHAR Value;
|
||||||
|
|
||||||
DPRINT("Break In\n");
|
DPRINT("Break In\n");
|
||||||
|
|
||||||
DoBreakIn = FALSE;
|
DoBreakIn = FALSE;
|
||||||
while (KdPortGetByteEx(&GdbPortInfo, &Value))
|
while (KdPortGetByteEx(&GdbPortInfo, &Value))
|
||||||
{
|
{
|
||||||
if (Value == 0x03)
|
if (Value == 0x03)
|
||||||
{
|
DoBreakIn = TRUE;
|
||||||
DoBreakIn = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DoBreakIn)
|
if (!DoBreakIn)
|
||||||
{
|
return TRUE;
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||||||
|
|
||||||
TrapFrame = PsGetCurrentThread()->Tcb.TrapFrame;
|
TrapFrame = PsGetCurrentThread()->Tcb.TrapFrame;
|
||||||
|
|
||||||
KeTrapFrameToContext(TrapFrame, NULL, &Context);
|
KeTrapFrameToContext(TrapFrame, NULL, &Context);
|
||||||
|
|
||||||
KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
|
KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
|
||||||
|
|
||||||
KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags, KernelMode);
|
KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags, KernelMode);
|
||||||
|
|
||||||
KeLowerIrql(OldIrql);
|
KeLowerIrql(OldIrql);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -1677,39 +1661,36 @@ NTAPI
|
||||||
KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable,
|
KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable,
|
||||||
ULONG BootPhase)
|
ULONG BootPhase)
|
||||||
{
|
{
|
||||||
if (!KdDebuggerEnabled || !KdpDebugMode.Gdb)
|
if (!KdDebuggerEnabled || !KdpDebugMode.Gdb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (BootPhase == 0)
|
||||||
{
|
{
|
||||||
return;
|
ExInitializeFastMutex(&GspLock);
|
||||||
|
|
||||||
|
/* Write out the functions that we support for now */
|
||||||
|
WrapperTable->KdpInitRoutine = KdpGdbStubInit;
|
||||||
|
WrapperTable->KdpPrintRoutine = KdpGdbDebugPrint;
|
||||||
|
WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
|
||||||
|
|
||||||
|
/* Initialize the Port */
|
||||||
|
KdPortInitializeEx(&GdbPortInfo, GdbPortNumber);
|
||||||
|
// KdpPort = GdbPortInfo.ComPort;
|
||||||
}
|
}
|
||||||
|
else if (BootPhase == 1)
|
||||||
if (BootPhase == 0)
|
|
||||||
{
|
{
|
||||||
ExInitializeFastMutex(&GspLock);
|
GspInitialized = TRUE;
|
||||||
|
|
||||||
/* Write out the functions that we support for now */
|
GspRunThread = NULL;
|
||||||
WrapperTable->KdpInitRoutine = KdpGdbStubInit;
|
GspDbgThread = NULL;
|
||||||
WrapperTable->KdpPrintRoutine = KdpGdbDebugPrint;
|
GspEnumThread = NULL;
|
||||||
WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
|
|
||||||
|
|
||||||
/* Initialize the Port */
|
HalDisplayString("Waiting for GDB to attach\n");
|
||||||
KdPortInitializeEx(&GdbPortInfo, 0, 0);
|
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
|
||||||
|
|
||||||
KdpPort = GdbPortInfo.ComPort;
|
|
||||||
}
|
}
|
||||||
else if (BootPhase == 1)
|
else if (BootPhase == 2)
|
||||||
{
|
{
|
||||||
GspInitialized = TRUE;
|
HalDisplayString("\n GDB debugging enabled\n\n");
|
||||||
|
|
||||||
GspRunThread = NULL;
|
|
||||||
GspDbgThread = NULL;
|
|
||||||
GspEnumThread = NULL;
|
|
||||||
|
|
||||||
HalDisplayString("Waiting for GDB to attach\n");
|
|
||||||
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
|
|
||||||
}
|
|
||||||
else if (BootPhase == 2)
|
|
||||||
{
|
|
||||||
HalDisplayString("\n GDB debugging enabled\n\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue