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