Author: tkreuzer
Date: Tue Jan 20 20:53:48 2009
New Revision: 38985
URL:
http://svn.reactos.org/svn/reactos?rev=38985&view=rev
Log:
kdcom: Implement KdpReceivePacketLeader that tries to get a packet leader and starts over
as soon as a single byte is wrong. Use it instead of the old code in KdReceivePacket.
Implement more of KdReceivePacket, handling the actual packets. Make use of
CurrentPacketId that gets xored with 1 when sending acks and initialized on a reset. Not
handling this correctly made WinDbg wait for more packets, although it sent an ack packet
already.
Only return KdPacketReceived on an ack packet, when we requested one. Stuff starts to work
now. WinDbg connects then reports "Assertion 'Data->Length == 0' failed at
ntoskrnl\kd64\kdapi.c line 310".
Modified:
branches/ros-amd64-bringup/reactos/drivers/base/kdcom/i386/kdbg.c
Modified: branches/ros-amd64-bringup/reactos/drivers/base/kdcom/i386/kdbg.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drive…
==============================================================================
--- branches/ros-amd64-bringup/reactos/drivers/base/kdcom/i386/kdbg.c [iso-8859-1]
(original)
+++ branches/ros-amd64-bringup/reactos/drivers/base/kdcom/i386/kdbg.c [iso-8859-1] Tue Jan
20 20:53:48 2009
@@ -563,17 +563,48 @@
Ret = KdPortGetByteEx(&DefaultPort, &ByteBuffer[i]);
TimeOut = FALSE; // FIXME timeout after 10 Sec
}
- while (!Ret | TimeOut);
+ while (!Ret || TimeOut);
if (TimeOut)
{
return KdPacketTimedOut;
}
- FrLdrDbgPrint("Received byte: %x\n", ByteBuffer[i]);
+// 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
@@ -713,8 +744,8 @@
}
/******************************************************************************
- * \name KdDebuggerInitialize0
- * \brief Phase 0 initialization.
+ * \name KdDebuggerInitialize1
+ * \brief Phase 1 initialization.
* \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
* \return Status
*/
@@ -852,16 +883,17 @@
OUT PULONG DataLength,
IN OUT PKD_CONTEXT Context)
{
- UCHAR BreakIn = 0;
+ 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, &BreakIn))
- {
- if (BreakIn == BREAKIN_PACKET_BYTE)
+ if (KdPortGetByteEx(&DefaultPort, &Byte))
+ {
+ if (Byte == BREAKIN_PACKET_BYTE)
{
return KdPacketReceived;
}
@@ -871,12 +903,11 @@
for (;;)
{
+ FrLdrDbgPrint("KdReceivePacket 0\n");
+
/* Step 1 - Read PacketLeader */
- RcvCode = KdpReceiveBuffer(&Packet.PacketLeader, sizeof(ULONG));
- if ( (RcvCode != KdPacketReceived) ||
- ((Packet.PacketLeader != BREAKIN_PACKET) &&
- (Packet.PacketLeader != PACKET_LEADER) &&
- (Packet.PacketLeader != CONTROL_PACKET_LEADER)) )
+ RcvCode = KdpReceivePacketLeader(&Packet.PacketLeader);
+ if (RcvCode != KdPacketReceived)
{
/* Couldn't read a correct packet leader. Start over. */
continue;
@@ -886,7 +917,7 @@
/* Step 2 - Read PacketType */
RcvCode = KdpReceiveBuffer(&Packet.PacketType, sizeof(USHORT));
- if (RcvCode != KdPacketReceived) // FIXME: check PacketType
+ if (RcvCode != KdPacketReceived)
{
/* Didn't receive a PacketType or PacketType is bad. Start over. */
continue;
@@ -937,8 +968,12 @@
switch (Packet.PacketType)
{
case PACKET_TYPE_KD_ACKNOWLEDGE:
- /* Remote acknowledges the last packet */
- return KdPacketReceived;
+ if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
+ {
+ /* Remote acknowledges the last packet */
+ return KdPacketReceived;
+ }
+ continue;
case PACKET_TYPE_KD_RESEND:
/* Remote wants us to resend the last packet */
@@ -946,7 +981,8 @@
case PACKET_TYPE_KD_RESET:
FrLdrDbgPrint("KdReceivePacket - got a reset packet\n");
- KdpSendControlPacket(PACKET_TYPE_KD_RESET, INITIAL_PACKET_ID);
+ KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0);
+ CurrentPacketId = INITIAL_PACKET_ID;
return KdPacketNeedsResend;
default:
@@ -955,6 +991,110 @@
}
}
+ /* 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 && Packet.ByteCount > MessageHeader->Length)
+ {
+ FrLdrDbgPrint("KdReceivePacket - got normal PacketType 2b\n");
+ /* Calculate the length of the message data */
+ MessageData->Length = Packet.ByteCount - MessageHeader->Length;
+
+ /* 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)
+ {
+ // Send PACKET_TYPE_KD_RESEND
+ 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, CurrentPacketId);
+ CurrentPacketId ^= 1;
+
+FrLdrDbgPrint("KdReceivePacket - all ok\n");
+
+ return KdPacketReceived;
+
}