From 716992c8c7ea3bd506d25481936a90aba92d69df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 20 Dec 2015 16:21:59 +0000 Subject: [PATCH] [KDCOM] 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 --- reactos/drivers/base/kdcom/kdcom.c | 125 ++++++++++++++++++++------ reactos/drivers/base/kdcom/kddll.c | 4 - reactos/drivers/base/kdcom/kddll.h | 10 +-- reactos/drivers/base/kdcom/kdserial.c | 3 - reactos/drivers/base/kdgdb/kdcom.c | 91 ++++++++++++------- 5 files changed, 163 insertions(+), 70 deletions(-) diff --git a/reactos/drivers/base/kdcom/kdcom.c b/reactos/drivers/base/kdcom/kdcom.c index ddf3a5ac8ea..d7892c1670f 100644 --- a/reactos/drivers/base/kdcom/kdcom.c +++ b/reactos/drivers/base/kdcom/kdcom.c @@ -10,12 +10,10 @@ #include #include +#include #include #include -#define NDEBUG -#include - /* 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; } } diff --git a/reactos/drivers/base/kdcom/kddll.c b/reactos/drivers/base/kdcom/kddll.c index 9827a507867..a26a4414285 100644 --- a/reactos/drivers/base/kdcom/kddll.c +++ b/reactos/drivers/base/kdcom/kddll.c @@ -8,12 +8,8 @@ #include "kddll.h" -#define NDEBUG -#include - /* GLOBALS ********************************************************************/ -PFNDBGPRNT KdpDbgPrint = NULL; ULONG CurrentPacketId = INITIAL_PACKET_ID | SYNC_PACKET_ID; ULONG RemotePacketId = INITIAL_PACKET_ID; diff --git a/reactos/drivers/base/kdcom/kddll.h b/reactos/drivers/base/kdcom/kddll.h index 8179477703f..03bdad9fcf0 100644 --- a/reactos/drivers/base/kdcom/kddll.h +++ b/reactos/drivers/base/kdcom/kddll.h @@ -13,22 +13,20 @@ #include #include -//#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 diff --git a/reactos/drivers/base/kdcom/kdserial.c b/reactos/drivers/base/kdcom/kdserial.c index 87e8f28f4fd..274f7c354be 100644 --- a/reactos/drivers/base/kdcom/kdserial.c +++ b/reactos/drivers/base/kdcom/kdserial.c @@ -8,9 +8,6 @@ #include "kddll.h" -#define NDEBUG -#include - /* FUNCTIONS ******************************************************************/ /****************************************************************************** diff --git a/reactos/drivers/base/kdgdb/kdcom.c b/reactos/drivers/base/kdgdb/kdcom.c index 5c792289556..be9e634e012 100644 --- a/reactos/drivers/base/kdgdb/kdcom.c +++ b/reactos/drivers/base/kdgdb/kdcom.c @@ -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 */