revert the changes to the old kdcom

svn path=/branches/ros-amd64-bringup/; revision=46430
This commit is contained in:
Timo Kreuzer 2010-03-25 05:12:42 +00:00
parent 0750573b4e
commit 82569185be

View file

@ -5,7 +5,6 @@
* PURPOSE: Serial i/o functions for the kernel debugger.
* PROGRAMMER: Alex Ionescu
* Hervé Poussineau
* Timo Kreuzer
*/
/* INCLUDES *****************************************************************/
@ -16,7 +15,6 @@
#define NDEBUG
#include <halfuncs.h>
#include <stdio.h>
#include <stdlib.h>
#include <debug.h>
#include "arc/arc.h"
#include "windbgkd.h"
@ -27,7 +25,7 @@ typedef struct _KD_PORT_INFORMATION
{
ULONG ComPort;
ULONG BaudRate;
ULONG_PTR BaseAddress;
ULONG BaseAddress;
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
BOOLEAN
@ -55,12 +53,6 @@ KdPortPutByteEx(
IN PKD_PORT_INFORMATION PortInformation,
IN UCHAR ByteToSend);
/* 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
#ifdef _M_IX86
@ -71,8 +63,6 @@ const ULONG BaseArray[2] = {0, 0x800003f8};
const ULONG BaseArray[3] = {0, 0x80006000, 0x80007000};
#elif defined(_M_ARM)
const ULONG BaseArray[2] = {0, 0xF1012000};
#elif defined(_M_AMD64)
const ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
#else
#error Unknown architecture
#endif
@ -125,8 +115,6 @@ const ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
/* GLOBAL VARIABLES *********************************************************/
ULONG CurrentPacketId = INITIAL_PACKET_ID;
/* STATIC VARIABLES *********************************************************/
static KD_PORT_INFORMATION DefaultPort = { 0, 0, 0 };
@ -134,18 +122,12 @@ static KD_PORT_INFORMATION DefaultPort = { 0, 0, 0 };
/* The com port must only be initialized once! */
static BOOLEAN PortInitialized = FALSE;
ULONG KdpPort;
ULONG KdpPortIrq;
// HACK!!!
typedef ULONG (*DBGRNT)(const char *Format, ...);
DBGRNT FrLdrDbgPrint = 0;
/* STATIC FUNCTIONS *********************************************************/
static BOOLEAN
KdpDoesComPortExist(
IN ULONG_PTR BaseAddress)
IN ULONG BaseAddress)
{
BOOLEAN found;
UCHAR mcr;
@ -205,14 +187,6 @@ KdpDoesComPortExist(
/* FUNCTIONS ****************************************************************/
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
return STATUS_SUCCESS;
}
/* HAL.KdPortInitialize */
BOOLEAN
NTAPI
@ -272,7 +246,7 @@ KdPortInitializeEx(
IN ULONG Unknown1,
IN ULONG Unknown2)
{
ULONG_PTR ComPortBase;
ULONG ComPortBase;
CHAR buffer[80];
ULONG divisor;
UCHAR lcr;
@ -493,270 +467,25 @@ KdPortEnableInterrupts(VOID)
return TRUE;
}
/* NEW INTERNAL FUNCTIONS ****************************************************/
/******************************************************************************
* \name KdpCalculateChecksum
* \brief Calculates the checksum for the packet data.
* \param Buffer Pointer to the packet data.
* \param Length Length of data in bytes.
* \return The calculated checksum.
* \sa http://www.vista-xp.co.uk/forums/technical-reference-library/2540-basics-debugging.html
*/
ULONG
NTAPI
KdpCalculateChecksum(
IN PVOID Buffer,
IN ULONG Length)
{
ULONG i, Checksum = 0;
for (i = 0; i < Length; i++)
{
Checksum += ((PUCHAR)Buffer)[i];
}
return Checksum;
}
/******************************************************************************
* \name KdpSendBuffer
* \brief Sends a buffer of data to the KD port.
* \param Buffer Pointer to the data.
* \param Size Size of data in bytes.
*/
VOID
NTAPI
KdpSendBuffer(
IN PVOID Buffer,
IN ULONG Size)
{
INT i;
for (i = 0; i < Size; i++)
{
KdPortPutByteEx(&DefaultPort, ((PUCHAR)Buffer)[i]);
}
}
/******************************************************************************
* \name KdpReceiveBuffer
* \brief Recieves data from the KD port and fills a buffer.
* \param Buffer Pointer to a buffer that receives the data.
* \param Size Size of data to receive in bytes.
* \return KdPacketReceived if successful.
* KdPacketTimedOut if the receice timed out (10 seconds).
* \todo Handle timeout.
*/
KDSTATUS
NTAPI
KdpReceiveBuffer(
OUT PVOID Buffer,
IN ULONG Size)
{
ULONG i;
PUCHAR ByteBuffer = Buffer;
BOOLEAN Ret, TimeOut;
for (i = 0; i < Size; i++)
{
do
{
Ret = KdPortGetByteEx(&DefaultPort, &ByteBuffer[i]);
TimeOut = FALSE; // FIXME timeout after 10 Sec
}
while (!Ret || TimeOut);
if (TimeOut)
{
return KdPacketTimedOut;
}
// FrLdrDbgPrint("Received byte: %x\n", ByteBuffer[i]);
}
return KdPacketReceived;
}
KDSTATUS
NTAPI
KdpReceivePacketLeader(
OUT PULONG PacketLeader)
{
UCHAR Byte, PrevByte;
ULONG i, Temp;
KDSTATUS RcvCode;
Temp = 0;
PrevByte = 0;
for (i = 0; i < 4; i++)
{
RcvCode = KdpReceiveBuffer(&Byte, sizeof(UCHAR));
Temp = (Temp << 8) | Byte;
if ( (RcvCode != KdPacketReceived) ||
((Byte != PACKET_LEADER_BYTE) &&
(Byte != CONTROL_PACKET_LEADER_BYTE)) ||
(PrevByte != 0 && Byte != PrevByte) )
{
return KdPacketNeedsResend;
}
PrevByte = Byte;
}
*PacketLeader = Temp;
return KdPacketReceived;
}
VOID
NTAPI
KdpSendControlPacket(
IN USHORT PacketType,
IN ULONG PacketId OPTIONAL)
{
KD_PACKET Packet;
Packet.PacketLeader = CONTROL_PACKET_LEADER;
Packet.PacketId = PacketId;
Packet.ByteCount = 0;
Packet.Checksum = 0;
Packet.PacketType = PacketType;
KdpSendBuffer(&Packet, sizeof(KD_PACKET));
}
/* NEW PUBLIC FUNCTIONS ******************************************************/
/******************************************************************************
* \name KdDebuggerInitialize0
* \brief Phase 0 initialization.
* \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
* \return Status
/*
* @unimplemented
*/
NTSTATUS
NTAPI
KdDebuggerInitialize0(
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
{
ULONG Value;
PCHAR CommandLine, Port, BaudRate, Irq;
/* Apply default values */
KdpPortIrq = 0;
DefaultPort.ComPort = DEFAULT_DEBUG_PORT;
DefaultPort.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
/* Check if e have a LoaderBlock */
if (LoaderBlock)
{
/* Get the Command Line */
CommandLine = LoaderBlock->LoadOptions;
/* Upcase it */
_strupr(CommandLine);
/* Get the port and baud rate */
Port = strstr(CommandLine, "DEBUGPORT");
BaudRate = strstr(CommandLine, "BAUDRATE");
Irq = strstr(CommandLine, "IRQ");
/* Check if we got the /DEBUGPORT parameter */
if (Port)
{
/* Move past the actual string, to reach the port*/
Port += strlen("DEBUGPORT");
/* Now get past any spaces and skip the equal sign */
while (*Port == ' ') Port++;
Port++;
/* Do we have a serial port? */
if (strncmp(Port, "COM", 3) != 0)
{
return STATUS_INVALID_PARAMETER;
}
/* Gheck for a valid Serial Port */
Port += 3;
Value = atol(Port);
if (Value > 4)
{
return STATUS_INVALID_PARAMETER;
}
/* Set the port to use */
DefaultPort.ComPort = Value;
}
/* Check if we got a baud rate */
if (BaudRate)
{
/* Move past the actual string, to reach the rate */
BaudRate += strlen("BAUDRATE");
/* Now get past any spaces */
while (*BaudRate == ' ') BaudRate++;
/* And make sure we have a rate */
if (*BaudRate)
{
/* Read and set it */
Value = atol(BaudRate + 1);
if (Value) DefaultPort.BaudRate = Value;
}
}
/* Check Serial Port Settings [IRQ] */
if (Irq)
{
/* Move past the actual string, to reach the rate */
Irq += strlen("IRQ");
/* Now get past any spaces */
while (*Irq == ' ') Irq++;
/* And make sure we have an IRQ */
if (*Irq)
{
/* Read and set it */
Value = atol(Irq + 1);
if (Value) KdpPortIrq = Value;
}
}
}
// HACK use com1 for FrLdrDbg, com2 for WinDbg
DefaultPort.ComPort = 2;
/* Get base address */
DefaultPort.BaseAddress = BaseArray[DefaultPort.ComPort];
/* Check if the COM port does exist */
if (!KdpDoesComPortExist(DefaultPort.BaseAddress))
{
return STATUS_INVALID_PARAMETER;
}
/* Initialize the port */
KdPortInitializeEx(&DefaultPort, 0, 0);
PortInitialized = TRUE;
return STATUS_SUCCESS;
return STATUS_NOT_IMPLEMENTED;
}
/******************************************************************************
* \name KdDebuggerInitialize1
* \brief Phase 1 initialization.
* \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
* \return Status
/*
* @unimplemented
*/
NTSTATUS
NTAPI
KdDebuggerInitialize1(
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
{
// HACK: misuse this function to get a pointer to FrLdrDbgPrint
FrLdrDbgPrint = (PVOID)LoaderBlock;
return STATUS_NOT_IMPLEMENTED;
}
@ -795,86 +524,12 @@ KdSendPacket(
IN PSTRING MessageData,
IN OUT PKD_CONTEXT Context)
{
KD_PACKET Packet;
KDSTATUS RcvCode;
for (;;)
{
/* Initialize a KD_PACKET */
Packet.PacketLeader = PACKET_LEADER;
Packet.PacketType = PacketType;
Packet.ByteCount = MessageHeader->Length;
Packet.Checksum = KdpCalculateChecksum(MessageHeader->Buffer,
MessageHeader->Length);
/* If we have message data, add it to the packet */
if (MessageData)
{
Packet.ByteCount += MessageData->Length;
Packet.Checksum += KdpCalculateChecksum(MessageData->Buffer,
MessageData->Length);
}
/* Set the packet id */
Packet.PacketId = CurrentPacketId;
/* Send the packet header to the KD port */
KdpSendBuffer(&Packet, sizeof(KD_PACKET));
/* Send the message header */
KdpSendBuffer(MessageHeader->Buffer, MessageHeader->Length);
/* If we have meesage data, also send it */
if (MessageData)
{
KdpSendBuffer(MessageData->Buffer, MessageData->Length);
}
/* Finalize with a trailing byte */
KdPortPutByte(PACKET_TRAILING_BYTE);
/* Wait for acknowledge */
RcvCode = KdReceivePacket(PACKET_TYPE_KD_ACKNOWLEDGE,
NULL,
NULL,
0,
NULL);
/* Did we succeed? */
if (RcvCode == KdPacketReceived)
{
CurrentPacketId &= ~SYNC_PACKET_ID;
break;
}
/* PACKET_TYPE_KD_DEBUG_IO is allowed to instantly timeout */
if (PacketType == PACKET_TYPE_KD_DEBUG_IO)
{
/* No response, silently fail. */
// return;
}
/* Packet timed out, send it again */
}
UNIMPLEMENTED;
return;
}
/******************************************************************************
* \name KdReceivePacket
* \brief Receive a packet from the KD port.
* \param [in] PacketType Describes the type of the packet to receive.
* This can be one of the PACKET_TYPE_ constants.
* \param [out] MessageHeader Pointer to a STRING structure for the header.
* \param [out] MessageData Pointer to a STRING structure for the data.
* \return KdPacketReceived if successful, KdPacketTimedOut if the receive
* timed out, KdPacketNeedsResend to signal that the last packet needs
* to be sent again.
* \note If PacketType is PACKET_TYPE_KD_POLL_BREAKIN, the function doesn't
* wait for any data, but returns KdPacketTimedOut instantly if no breakin
* packet byte is received.
* \sa http://www.nynaeve.net/?p=169
/*
* @unimplemented
*/
KDSTATUS
NTAPI
@ -885,215 +540,8 @@ KdReceivePacket(
OUT PULONG DataLength,
IN OUT PKD_CONTEXT Context)
{
UCHAR Byte = 0;
KDSTATUS RcvCode;
KD_PACKET Packet;
ULONG Checksum;
/* Special handling for breakin packet */
if(PacketType == PACKET_TYPE_KD_POLL_BREAKIN)
{
if (KdPortGetByteEx(&DefaultPort, &Byte))
{
if (Byte == BREAKIN_PACKET_BYTE)
{
return KdPacketReceived;
}
}
return KdPacketTimedOut;
}
for (;;)
{
/* Step 1 - Read PacketLeader */
RcvCode = KdpReceivePacketLeader(&Packet.PacketLeader);
if (RcvCode != KdPacketReceived)
{
/* Couldn't read a correct packet leader. Start over. */
continue;
}
/* Step 2 - Read PacketType */
RcvCode = KdpReceiveBuffer(&Packet.PacketType, sizeof(USHORT));
if (RcvCode != KdPacketReceived)
{
/* Didn't receive a PacketType or PacketType is bad. Start over. */
continue;
}
/* Step 3 - Read ByteCount */
RcvCode = KdpReceiveBuffer(&Packet.ByteCount, sizeof(USHORT));
if (RcvCode != KdPacketReceived || Packet.ByteCount > PACKET_MAX_SIZE)
{
/* Didn't receive ByteCount or it's too big. Start over. */
continue;
}
/* Step 4 - Read PacketId */
RcvCode = KdpReceiveBuffer(&Packet.PacketId, sizeof(ULONG));
if (RcvCode != KdPacketReceived)
{
/* Didn't receive PacketId. Start over. */
continue;
}
/*
if (Packet.PacketId != ExpectedPacketId)
{
// Ask for a resend!
continue;
}
*/
/* Step 5 - Read Checksum */
RcvCode = KdpReceiveBuffer(&Packet.Checksum, sizeof(ULONG));
if (RcvCode != KdPacketReceived)
{
/* Didn't receive Checksum. Start over. */
continue;
}
/* Step 6 - Handle control packets */
if (Packet.PacketLeader == CONTROL_PACKET_LEADER)
{
switch (Packet.PacketType)
{
case PACKET_TYPE_KD_ACKNOWLEDGE:
if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
{
/* Remote acknowledges the last packet */
CurrentPacketId ^= 1;
return KdPacketReceived;
}
/* That's not what we were waiting for, start over. */
continue;
case PACKET_TYPE_KD_RESET:
FrLdrDbgPrint("KdReceivePacket - got a reset packet\n");
KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0);
CurrentPacketId = INITIAL_PACKET_ID;
/* Fall through */
case PACKET_TYPE_KD_RESEND:
/* Remote wants us to resend the last packet */
return KdPacketNeedsResend;
default:
FrLdrDbgPrint("KdReceivePacket - got unknown control packet\n");
return KdPacketNeedsResend;
}
}
/* Did we wait for an ack packet? */
if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
{
/* We received something different, start over */
continue;
}
/* Did we get the right packet type? */
if (PacketType != Packet.PacketType)
{
/* We received something different, start over */
continue;
}
/* Get size of the message header */
switch (Packet.PacketType)
{
case PACKET_TYPE_KD_STATE_CHANGE64:
MessageHeader->Length = sizeof(DBGKD_WAIT_STATE_CHANGE64);
break;
case PACKET_TYPE_KD_STATE_MANIPULATE:
MessageHeader->Length = sizeof(DBGKD_MANIPULATE_STATE64);
break;
case PACKET_TYPE_KD_DEBUG_IO:
MessageHeader->Length = sizeof(DBGKD_DEBUG_IO);
break;
default:
FrLdrDbgPrint("KdReceivePacket - unknown PacketType\n");
return KdPacketNeedsResend;
}
//FrLdrDbgPrint("KdReceivePacket - got normal PacketType\n");
/* Packet smaller than expected? */
if (MessageHeader->Length > Packet.ByteCount)
{
FrLdrDbgPrint("KdReceivePacket - too few data (%d) for type %d\n",
Packet.ByteCount, MessageHeader->Length);
MessageHeader->Length = Packet.ByteCount;
}
//FrLdrDbgPrint("KdReceivePacket - got normal PacketType, Buffer = %p\n", MessageHeader->Buffer);
/* Receive the message header data */
RcvCode = KdpReceiveBuffer(MessageHeader->Buffer,
MessageHeader->Length);
if (RcvCode != KdPacketReceived)
{
/* Didn't receive data. Start over. */
FrLdrDbgPrint("KdReceivePacket - Didn't receive message header data. Start over\n");
continue;
}
//FrLdrDbgPrint("KdReceivePacket - got normal PacketType 3\n");
/* Calculate checksum for the header data */
Checksum = KdpCalculateChecksum(MessageHeader->Buffer,
MessageHeader->Length);
/* Shall we receive messsage data? */
if (MessageData)
{
/* Calculate the length of the message data */
MessageData->Length = Packet.ByteCount - MessageHeader->Length;
/* Do we have data? */
if (MessageData->Length)
{
FrLdrDbgPrint("KdReceivePacket - got data\n");
/* Receive the message data */
RcvCode = KdpReceiveBuffer(MessageData->Buffer,
MessageData->Length);
if (RcvCode != KdPacketReceived)
{
/* Didn't receive data. Start over. */
FrLdrDbgPrint("KdReceivePacket - Didn't receive message data. Start over\n");
continue;
}
/* Add cheksum for message data */
Checksum += KdpCalculateChecksum(MessageData->Buffer,
MessageData->Length);
}
}
/* Compare checksum */
if (Packet.Checksum != Checksum)
{
KdpSendControlPacket(PACKET_TYPE_KD_RESEND, CurrentPacketId);
FrLdrDbgPrint("KdReceivePacket - wrong cheksum, got %x, calculated %x\n",
Packet.Checksum, Checksum);
continue;
}
/* We must receive a PACKET_TRAILING_BYTE now */
RcvCode = KdpReceiveBuffer(&Byte, sizeof(UCHAR));
/* Acknowledge the received packet */
KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, Packet.PacketId);
//FrLdrDbgPrint("KdReceivePacket - all ok\n");
return KdPacketReceived;
}
return KdPacketReceived;
UNIMPLEMENTED;
return 0;
}
/* EOF */