reactos/drivers/base/kdcom/kdcom.c

267 lines
6.3 KiB
C
Raw Normal View History

/*
* 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@ewactos.org)
*/
#include "kddll.h"
#include <cportlib/cportlib.h>
#include <stdlib.h>
/* Serial debug connection */
#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
#if defined(_M_IX86) || defined(_M_AMD64)
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
#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
/* GLOBALS ********************************************************************/
CPPORT KdDebugComPort;
ULONG KdDebugComPortIrq = 0; // Not used at the moment.
/* FUNCTIONS ******************************************************************/
NTSTATUS
NTAPI
KdD0Transition(VOID)
{
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
KdD3Transition(VOID)
{
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
KdSave(IN BOOLEAN SleepTransition)
{
/* Nothing to do on COM ports */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
KdRestore(IN BOOLEAN SleepTransition)
{
/* Nothing to do on COM ports */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
KdpPortInitialize(IN ULONG ComPortNumber,
IN ULONG ComPortBaudRate)
{
NTSTATUS Status;
KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber);
Status = CpInitialize(&KdDebugComPort,
UlongToPtr(BaseArray[ComPortNumber]),
ComPortBaudRate);
if (!NT_SUCCESS(Status))
{
return STATUS_INVALID_PARAMETER;
}
else
{
KdComPortInUse = KdDebugComPort.Address;
return STATUS_SUCCESS;
}
}
/******************************************************************************
* \name KdDebuggerInitialize0
* \brief Phase 0 initialization.
* \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
* \return Status
*/
NTSTATUS
NTAPI
KdDebuggerInitialize0(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 e have a LoaderBlock */
if (LoaderBlock)
{
/* HACK */
KdpDbgPrint = LoaderBlock->u.I386.CommonDataArea;
KDDBGPRINT("KdDebuggerInitialize0\n");
/* 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) KdDebugComPortIrq = Value;
}
}
}
/* 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
*/
NTSTATUS
NTAPI
KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
{
return STATUS_SUCCESS;
}
VOID
NTAPI
KdpSendByte(IN UCHAR Byte)
{
/* Send the byte */
CpPutByte(&KdDebugComPort, Byte);
}
KDP_STATUS
NTAPI
KdpPollByte(OUT PUCHAR OutByte)
{
/* Poll the byte */
if (CpGetByte(&KdDebugComPort, OutByte, FALSE) == CP_GET_SUCCESS)
{
return KDP_PACKET_RECEIVED;
}
else
{
return KDP_PACKET_TIMEOUT;
}
}
KDP_STATUS
NTAPI
KdpReceiveByte(OUT PUCHAR OutByte)
{
/* Get the byte */
if (CpGetByte(&KdDebugComPort, OutByte, TRUE) == CP_GET_SUCCESS)
{
return KDP_PACKET_RECEIVED;
}
else
{
return KDP_PACKET_TIMEOUT;
}
}
KDP_STATUS
NTAPI
KdpPollBreakIn(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 */