Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357/* * COPYRIGHT: GPL, see COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/base/kddll/kdcom.c * PURPOSE: COM port functions for the kernel debugger. * 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>
/* Serial debug connection */#if defined(SARCH_PC98)#define DEFAULT_DEBUG_PORT 2 /* COM2 */#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};#elseconst ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};#endif#elif defined(_M_PPC)const ULONG BaseArray[] = {0, 0x800003F8};#elif defined(_M_MIPS)const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};#elif defined(_M_ARM)const ULONG BaseArray[] = {0, 0xF1012000};#else#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 KDDEBUGCPPORT KdDebugComPort;#endif
/* DEBUGGING ******************************************************************/
#ifdef KDDEBUGULONG 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 ******************************************************************/
NTSTATUSNTAPIKdD0Transition(VOID){ return STATUS_SUCCESS;}
NTSTATUSNTAPIKdD3Transition(VOID){ return STATUS_SUCCESS;}
NTSTATUSNTAPIKdSave(IN BOOLEAN SleepTransition){ /* Nothing to do on COM ports */ return STATUS_SUCCESS;}
NTSTATUSNTAPIKdRestore(IN BOOLEAN SleepTransition){ /* Nothing to do on COM ports */ return STATUS_SUCCESS;}
NTSTATUSNTAPIKdpPortInitialize(IN ULONG ComPortNumber, IN ULONG ComPortBaudRate){ NTSTATUS Status;
KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber);
Status = CpInitialize(&KdComPort, UlongToPtr(BaseArray[ComPortNumber]), ComPortBaudRate); if (!NT_SUCCESS(Status)) { return STATUS_INVALID_PARAMETER; } else { KdComPortInUse = KdComPort.Address; return STATUS_SUCCESS; }}
/****************************************************************************** * \name KdDebuggerInitialize0 * \brief Phase 0 initialization. * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL. * \return Status */NTSTATUSNTAPIKdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL){ ULONG ComPortNumber = DEFAULT_DEBUG_PORT; ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
PCHAR CommandLine, PortString, BaudString, IrqString; ULONG Value;
/* Check if we have a LoaderBlock */ if (LoaderBlock) { /* Get the Command Line */ CommandLine = LoaderBlock->LoadOptions;
/* Upcase it */ _strupr(CommandLine);
/* Get the port and baud rate */ PortString = strstr(CommandLine, "DEBUGPORT"); BaudString = strstr(CommandLine, "BAUDRATE"); IrqString = strstr(CommandLine, "IRQ");
/* Check if we got the /DEBUGPORT parameter */ if (PortString) { /* Move past the actual string, to reach the port*/ PortString += strlen("DEBUGPORT");
/* Now get past any spaces and skip the equal sign */ while (*PortString == ' ') PortString++; PortString++;
/* Do we have a serial port? */ if (strncmp(PortString, "COM", 3) != 0) { return STATUS_INVALID_PARAMETER; }
/* Check for a valid Serial Port */ PortString += 3; Value = atol(PortString); if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0])) { return STATUS_INVALID_PARAMETER; }
/* Set the port to use */ ComPortNumber = Value; }
/* Check if we got a baud rate */ if (BaudString) { /* Move past the actual string, to reach the rate */ BaudString += strlen("BAUDRATE");
/* Now get past any spaces */ while (*BaudString == ' ') BaudString++;
/* And make sure we have a rate */ if (*BaudString) { /* Read and set it */ Value = atol(BaudString + 1); if (Value) ComPortBaudRate = Value; } }
/* Check Serial Port Settings [IRQ] */ if (IrqString) { /* Move past the actual string, to reach the rate */ IrqString += strlen("IRQ");
/* Now get past any spaces */ while (*IrqString == ' ') IrqString++;
/* And make sure we have an IRQ */ if (*IrqString) { /* Read and set it */ Value = atol(IrqString + 1); 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);}
/****************************************************************************** * \name KdDebuggerInitialize1 * \brief Phase 1 initialization. * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL. * \return Status */NTSTATUSNTAPIKdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL){ return STATUS_SUCCESS;}
VOIDNTAPIKdpSendByte(IN UCHAR Byte){ /* Send the byte */ CpPutByte(&KdComPort, Byte);}
KDP_STATUSNTAPIKdpPollByte(OUT PUCHAR OutByte){ USHORT Status;
/* Poll the byte */ Status = CpGetByte(&KdComPort, OutByte, FALSE, FALSE); switch (Status) { 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; }}
KDP_STATUSNTAPIKdpReceiveByte(OUT PUCHAR OutByte){ USHORT Status;
/* Get the byte */ Status = CpGetByte(&KdComPort, OutByte, TRUE, FALSE); switch (Status) { 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; }}
KDP_STATUSNTAPIKdpPollBreakIn(VOID){ KDP_STATUS KdStatus; UCHAR Byte;
KdStatus = KdpPollByte(&Byte); if ((KdStatus == KDP_PACKET_RECEIVED) && (Byte == BREAKIN_PACKET_BYTE)) { return KDP_PACKET_RECEIVED; } return KDP_PACKET_TIMEOUT;}
/* EOF */