Do not use the "LoaderBlock->u.I386.CommonDataArea;" hack to use FreeLdr's DbgPrint function inside KDCOM, for the simple reason that while it works when KDCOM just initializes, the memory area where FreeLdr's DbgPrint function is, gets erased when ReactOS is running. As a result, all attempts to call the DbgPrint function when tracing something in KDCOM at the end of life of ReactOS, just fails lamentably (it hangs).
We therefore cannot rely on external code to provide us with DbgPrint. Instead, implement a very simple DbgPrint function inside KDCOM, as done by KDGDB.
The KD serial port serving for debugging KDCOM is chosen dynamically amongst the other free COM ports.

This needs to be also fixed in KDVM.

[KDGDB]
Instead of hardcoding the KD serial port number serving for debugging KDGDB, determine it dynamically amongst the other free COM ports.

svn path=/trunk/; revision=70405
This commit is contained in:
Hermès Bélusca-Maïto 2015-12-20 16:21:59 +00:00
parent 38814b24c9
commit 716992c8c7
5 changed files with 163 additions and 70 deletions

View file

@ -10,12 +10,10 @@
#include <cportlib/cportlib.h>
#include <arc/arc.h>
#include <stdio.h>
#include <stdlib.h>
#include <ndk/halfuncs.h>
#define NDEBUG
#include <debug.h>
/* Serial debug connection */
#define DEFAULT_DEBUG_PORT 2 /* COM2 */
#define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
@ -36,11 +34,52 @@ const ULONG BaseArray[] = {0, 0xF1012000};
#error Unknown architecture
#endif
#define MAX_COM_PORTS (sizeof(BaseArray) / sizeof(BaseArray[0]) - 1)
/* GLOBALS ********************************************************************/
CPPORT KdComPort;
ULONG KdComPortIrq = 0; // Not used at the moment.
#ifdef KDDEBUG
CPPORT KdDebugComPort;
ULONG KdDebugComPortIrq = 0; // Not used at the moment.
#endif
/* DEBUGGING ******************************************************************/
#ifdef KDDEBUG
ULONG KdpDbgPrint(const char *Format, ...)
{
va_list ap;
int Length;
char* ptr;
CHAR Buffer[512];
va_start(ap, Format);
Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
va_end(ap);
/* Check if we went past the buffer */
if (Length == -1)
{
/* Terminate it if we went over-board */
Buffer[sizeof(Buffer) - 1] = '\n';
/* Put maximum */
Length = sizeof(Buffer);
}
ptr = Buffer;
while (Length--)
{
if (*ptr == '\n')
CpPutByte(&KdDebugComPort, '\r');
CpPutByte(&KdDebugComPort, *ptr++);
}
return 0;
}
#endif
/* FUNCTIONS ******************************************************************/
@ -83,7 +122,7 @@ KdpPortInitialize(IN ULONG ComPortNumber,
KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber);
Status = CpInitialize(&KdDebugComPort,
Status = CpInitialize(&KdComPort,
UlongToPtr(BaseArray[ComPortNumber]),
ComPortBaudRate);
if (!NT_SUCCESS(Status))
@ -92,7 +131,7 @@ KdpPortInitialize(IN ULONG ComPortNumber,
}
else
{
KdComPortInUse = KdDebugComPort.Address;
KdComPortInUse = KdComPort.Address;
return STATUS_SUCCESS;
}
}
@ -113,13 +152,9 @@ KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
PCHAR CommandLine, PortString, BaudString, IrqString;
ULONG Value;
/* Check if e have a LoaderBlock */
/* Check if we have a LoaderBlock */
if (LoaderBlock)
{
/* HACK */
KdpDbgPrint = LoaderBlock->u.I386.CommonDataArea;
KDDBGPRINT("KdDebuggerInitialize0\n");
/* Get the Command Line */
CommandLine = LoaderBlock->LoadOptions;
@ -191,11 +226,37 @@ KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
{
/* Read and set it */
Value = atol(IrqString + 1);
if (Value) KdDebugComPortIrq = Value;
if (Value) KdComPortIrq = Value;
}
}
}
#ifdef KDDEBUG
/*
* Try to find a free COM port and use it as the KD debugging port.
* NOTE: Inspired by reactos/boot/freeldr/freeldr/comm/rs232.c, Rs232PortInitialize(...)
*/
{
/*
* Start enumerating COM ports from the last one to the first one,
* and break when we find a valid port.
* If we reach the first element of the list, the invalid COM port,
* then it means that no valid port was found.
*/
ULONG ComPort;
for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
{
/* Check if the port exist; skip the KD port */
if ((ComPort != ComPortNumber) && CpDoesPortExist(UlongToPtr(BaseArray[ComPort])))
break;
}
if (ComPort != 0)
CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE);
}
#endif
KDDBGPRINT("KdDebuggerInitialize0\n");
/* Initialize the port */
return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
}
@ -219,21 +280,28 @@ NTAPI
KdpSendByte(IN UCHAR Byte)
{
/* Send the byte */
CpPutByte(&KdDebugComPort, Byte);
CpPutByte(&KdComPort, Byte);
}
KDP_STATUS
NTAPI
KdpPollByte(OUT PUCHAR OutByte)
{
USHORT Status;
/* Poll the byte */
if (CpGetByte(&KdDebugComPort, OutByte, FALSE, FALSE) == CP_GET_SUCCESS)
Status = CpGetByte(&KdComPort, OutByte, FALSE, FALSE);
switch (Status)
{
return KDP_PACKET_RECEIVED;
}
else
{
return KDP_PACKET_TIMEOUT;
case CP_GET_SUCCESS:
return KDP_PACKET_RECEIVED;
case CP_GET_NODATA:
return KDP_PACKET_TIMEOUT;
case CP_GET_ERROR:
default:
return KDP_PACKET_RESEND;
}
}
@ -241,14 +309,21 @@ KDP_STATUS
NTAPI
KdpReceiveByte(OUT PUCHAR OutByte)
{
USHORT Status;
/* Get the byte */
if (CpGetByte(&KdDebugComPort, OutByte, TRUE, FALSE) == CP_GET_SUCCESS)
Status = CpGetByte(&KdComPort, OutByte, TRUE, FALSE);
switch (Status)
{
return KDP_PACKET_RECEIVED;
}
else
{
return KDP_PACKET_TIMEOUT;
case CP_GET_SUCCESS:
return KDP_PACKET_RECEIVED;
case CP_GET_NODATA:
return KDP_PACKET_TIMEOUT;
case CP_GET_ERROR:
default:
return KDP_PACKET_RESEND;
}
}

View file

@ -8,12 +8,8 @@
#include "kddll.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
PFNDBGPRNT KdpDbgPrint = NULL;
ULONG CurrentPacketId = INITIAL_PACKET_ID | SYNC_PACKET_ID;
ULONG RemotePacketId = INITIAL_PACKET_ID;

View file

@ -13,22 +13,20 @@
#include <ntifs.h>
#include <windbgkd.h>
//#define KDDEBUG /* uncomment to enable debugging this dll */
typedef ULONG (*PFNDBGPRNT)(const char *Format, ...);
extern PFNDBGPRNT KdpDbgPrint;
// #define KDDEBUG /* uncomment to enable debugging this dll */
#ifndef KDDEBUG
#define KDDBGPRINT(...)
#else
extern ULONG KdpDbgPrint(const char* Format, ...);
#define KDDBGPRINT KdpDbgPrint
#endif
typedef enum
{
KDP_PACKET_RECEIVED = 0,
KDP_PACKET_TIMEOUT = 1,
KDP_PACKET_RESEND = 2
KDP_PACKET_TIMEOUT = 1,
KDP_PACKET_RESEND = 2
} KDP_STATUS;
VOID

View file

@ -8,9 +8,6 @@
#include "kddll.h"
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ******************************************************************/
/******************************************************************************

View file

@ -32,6 +32,8 @@ const ULONG BaseArray[] = {0, 0xF1012000};
#error Unknown architecture
#endif
#define MAX_COM_PORTS (sizeof(BaseArray) / sizeof(BaseArray[0]) - 1)
/* GLOBALS ********************************************************************/
CPPORT KdComPort;
@ -40,6 +42,42 @@ ULONG KdComPortIrq = 0; // Not used at the moment.
CPPORT KdDebugComPort;
#endif
/* DEBUGGING ******************************************************************/
#ifdef KDDEBUG
ULONG KdpDbgPrint(const char *Format, ...)
{
va_list ap;
int Length;
char* ptr;
CHAR Buffer[512];
va_start(ap, Format);
Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
va_end(ap);
/* Check if we went past the buffer */
if (Length == -1)
{
/* Terminate it if we went over-board */
Buffer[sizeof(Buffer) - 1] = '\n';
/* Put maximum */
Length = sizeof(Buffer);
}
ptr = Buffer;
while (Length--)
{
if (*ptr == '\n')
CpPutByte(&KdDebugComPort, '\r');
CpPutByte(&KdDebugComPort, *ptr++);
}
return 0;
}
#endif
/* FUNCTIONS ******************************************************************/
@ -190,8 +228,27 @@ KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
}
#ifdef KDDEBUG
/* Use DEBUGPORT=COM1 if you want to debug KDGDB, as we use COM2 for debugging it */
CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[2]), DEFAULT_BAUD_RATE);
/*
* Try to find a free COM port and use it as the KD debugging port.
* NOTE: Inspired by reactos/boot/freeldr/freeldr/comm/rs232.c, Rs232PortInitialize(...)
*/
{
/*
* Start enumerating COM ports from the last one to the first one,
* and break when we find a valid port.
* If we reach the first element of the list, the invalid COM port,
* then it means that no valid port was found.
*/
ULONG ComPort;
for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
{
/* Check if the port exist; skip the KD port */
if ((ComPort != ComPortNumber) && CpDoesPortExist(UlongToPtr(BaseArray[ComPort])))
break;
}
if (ComPort != 0)
CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE);
}
#endif
/* Initialize the port */
@ -273,34 +330,4 @@ KdpPollBreakIn(VOID)
return KdPacketTimedOut;
}
#ifdef KDDEBUG
ULONG KdpDbgPrint(const char* Format, ...)
{
va_list ap;
static CHAR Buffer[512];
char* ptr;
int Length;
va_start(ap, Format);
Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
va_end(ap);
/* Check if we went past the buffer */
if (Length == -1)
{
/* Terminate it if we went over-board */
Buffer[sizeof(Buffer) - 1] = '\n';
/* Put maximum */
Length = sizeof(Buffer);
}
ptr = Buffer;
while (Length--)
CpPutByte(&KdDebugComPort, *ptr++);
return 0;
}
#endif
/* EOF */