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 <cportlib/cportlib.h>
#include <arc/arc.h> #include <arc/arc.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ndk/halfuncs.h> #include <ndk/halfuncs.h>
#define NDEBUG
#include <debug.h>
/* Serial debug connection */ /* Serial debug connection */
#define DEFAULT_DEBUG_PORT 2 /* COM2 */ #define DEFAULT_DEBUG_PORT 2 /* COM2 */
#define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */ #define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
@ -36,11 +34,52 @@ const ULONG BaseArray[] = {0, 0xF1012000};
#error Unknown architecture #error Unknown architecture
#endif #endif
#define MAX_COM_PORTS (sizeof(BaseArray) / sizeof(BaseArray[0]) - 1)
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
CPPORT KdComPort;
ULONG KdComPortIrq = 0; // Not used at the moment.
#ifdef KDDEBUG
CPPORT KdDebugComPort; 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 ******************************************************************/ /* FUNCTIONS ******************************************************************/
@ -83,7 +122,7 @@ KdpPortInitialize(IN ULONG ComPortNumber,
KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber); KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber);
Status = CpInitialize(&KdDebugComPort, Status = CpInitialize(&KdComPort,
UlongToPtr(BaseArray[ComPortNumber]), UlongToPtr(BaseArray[ComPortNumber]),
ComPortBaudRate); ComPortBaudRate);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -92,7 +131,7 @@ KdpPortInitialize(IN ULONG ComPortNumber,
} }
else else
{ {
KdComPortInUse = KdDebugComPort.Address; KdComPortInUse = KdComPort.Address;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
@ -113,13 +152,9 @@ KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
PCHAR CommandLine, PortString, BaudString, IrqString; PCHAR CommandLine, PortString, BaudString, IrqString;
ULONG Value; ULONG Value;
/* Check if e have a LoaderBlock */ /* Check if we have a LoaderBlock */
if (LoaderBlock) if (LoaderBlock)
{ {
/* HACK */
KdpDbgPrint = LoaderBlock->u.I386.CommonDataArea;
KDDBGPRINT("KdDebuggerInitialize0\n");
/* Get the Command Line */ /* Get the Command Line */
CommandLine = LoaderBlock->LoadOptions; CommandLine = LoaderBlock->LoadOptions;
@ -191,11 +226,37 @@ KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
{ {
/* Read and set it */ /* Read and set it */
Value = atol(IrqString + 1); 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 */ /* Initialize the port */
return KdpPortInitialize(ComPortNumber, ComPortBaudRate); return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
} }
@ -219,21 +280,28 @@ NTAPI
KdpSendByte(IN UCHAR Byte) KdpSendByte(IN UCHAR Byte)
{ {
/* Send the byte */ /* Send the byte */
CpPutByte(&KdDebugComPort, Byte); CpPutByte(&KdComPort, Byte);
} }
KDP_STATUS KDP_STATUS
NTAPI NTAPI
KdpPollByte(OUT PUCHAR OutByte) KdpPollByte(OUT PUCHAR OutByte)
{ {
USHORT Status;
/* Poll the byte */ /* Poll the byte */
if (CpGetByte(&KdDebugComPort, OutByte, FALSE, FALSE) == CP_GET_SUCCESS) Status = CpGetByte(&KdComPort, OutByte, FALSE, FALSE);
switch (Status)
{ {
case CP_GET_SUCCESS:
return KDP_PACKET_RECEIVED; return KDP_PACKET_RECEIVED;
}
else case CP_GET_NODATA:
{
return KDP_PACKET_TIMEOUT; return KDP_PACKET_TIMEOUT;
case CP_GET_ERROR:
default:
return KDP_PACKET_RESEND;
} }
} }
@ -241,14 +309,21 @@ KDP_STATUS
NTAPI NTAPI
KdpReceiveByte(OUT PUCHAR OutByte) KdpReceiveByte(OUT PUCHAR OutByte)
{ {
USHORT Status;
/* Get the byte */ /* Get the byte */
if (CpGetByte(&KdDebugComPort, OutByte, TRUE, FALSE) == CP_GET_SUCCESS) Status = CpGetByte(&KdComPort, OutByte, TRUE, FALSE);
switch (Status)
{ {
case CP_GET_SUCCESS:
return KDP_PACKET_RECEIVED; return KDP_PACKET_RECEIVED;
}
else case CP_GET_NODATA:
{
return KDP_PACKET_TIMEOUT; return KDP_PACKET_TIMEOUT;
case CP_GET_ERROR:
default:
return KDP_PACKET_RESEND;
} }
} }

View file

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

View file

@ -13,14 +13,12 @@
#include <ntifs.h> #include <ntifs.h>
#include <windbgkd.h> #include <windbgkd.h>
//#define KDDEBUG /* uncomment to enable debugging this dll */ // #define KDDEBUG /* uncomment to enable debugging this dll */
typedef ULONG (*PFNDBGPRNT)(const char *Format, ...);
extern PFNDBGPRNT KdpDbgPrint;
#ifndef KDDEBUG #ifndef KDDEBUG
#define KDDBGPRINT(...) #define KDDBGPRINT(...)
#else #else
extern ULONG KdpDbgPrint(const char* Format, ...);
#define KDDBGPRINT KdpDbgPrint #define KDDBGPRINT KdpDbgPrint
#endif #endif

View file

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

View file

@ -32,6 +32,8 @@ const ULONG BaseArray[] = {0, 0xF1012000};
#error Unknown architecture #error Unknown architecture
#endif #endif
#define MAX_COM_PORTS (sizeof(BaseArray) / sizeof(BaseArray[0]) - 1)
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
CPPORT KdComPort; CPPORT KdComPort;
@ -40,6 +42,42 @@ ULONG KdComPortIrq = 0; // Not used at the moment.
CPPORT KdDebugComPort; CPPORT KdDebugComPort;
#endif #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 ******************************************************************/ /* FUNCTIONS ******************************************************************/
@ -190,8 +228,27 @@ KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
} }
#ifdef KDDEBUG #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 #endif
/* Initialize the port */ /* Initialize the port */
@ -273,34 +330,4 @@ KdpPollBreakIn(VOID)
return KdPacketTimedOut; 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 */ /* EOF */