[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:
Hermès Bélusca-Maïto 2013-05-07 00:14:36 +00:00
parent a23361e756
commit cbdc727f61
9 changed files with 339 additions and 482 deletions

View file

@ -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};

View file

@ -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)
{ {
// //

View file

@ -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 */

View file

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

View file

@ -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];

View file

@ -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;
} }
} }

View file

@ -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);

View file

@ -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)
{ {

View file

@ -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");
} }
} }