* PROJECT: ReactOS kernel
* FILE: drivers/base/kddll/kdcom.c
* PURPOSE: COM port functions for the kernel debugger.
- * PROGRAMMER: Timo Kreuzer (timo.kreuzer@ewactos.org)
+ * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include "kddll.h"
#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 */
+#if defined(SARCH_PC98)
#define DEFAULT_DEBUG_PORT 2 /* COM2 */
-#define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
-#define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
-#define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
-
-#define DEFAULT_BAUD_RATE 19200
+#define DEFAULT_DEBUG_COM1_IRQ 4
+#define DEFAULT_DEBUG_COM2_IRQ 5
+#define DEFAULT_DEBUG_BAUD_RATE 9600
+#define DEFAULT_BAUD_RATE 9600
+#else
+#define DEFAULT_DEBUG_PORT 2 /* COM2 */
+#define DEFAULT_DEBUG_COM1_IRQ 4
+#define DEFAULT_DEBUG_COM2_IRQ 3
+#define DEFAULT_DEBUG_BAUD_RATE 115200
+#define DEFAULT_BAUD_RATE 19200
+#endif
#if defined(_M_IX86) || defined(_M_AMD64)
+#if defined(SARCH_PC98)
+const ULONG BaseArray[] = {0, 0x30, 0x238};
+#else
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+#endif
#elif defined(_M_PPC)
const ULONG BaseArray[] = {0, 0x800003F8};
#elif defined(_M_MIPS)
#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 ******************************************************************/
KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber);
- Status = CpInitialize(&KdDebugComPort,
+ Status = CpInitialize(&KdComPort,
UlongToPtr(BaseArray[ComPortNumber]),
ComPortBaudRate);
if (!NT_SUCCESS(Status))
}
else
{
- KdComPortInUse = KdDebugComPort.Address;
+ KdComPortInUse = KdComPort.Address;
return STATUS_SUCCESS;
}
}
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;
{
/* 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);
}
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)
- {
- return KDP_PACKET_RECEIVED;
- }
- else
+ Status = CpGetByte(&KdComPort, OutByte, FALSE, FALSE);
+ switch (Status)
{
- 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;
}
}
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;
}
}