2008-11-17 18:29:00 -05:00
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2008-03-05 09:52:00 -05:00
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
|
// Microsoft Research Singularity
|
2008-03-05 09:52:00 -05:00
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
// debug.cpp: runtime support for debugging
|
2008-03-05 09:52:00 -05:00
|
|
|
|
//
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
#ifndef IN
|
2008-03-05 09:52:00 -05:00
|
|
|
|
#define IN
|
2008-11-17 18:29:00 -05:00
|
|
|
|
#endif
|
|
|
|
|
#ifndef OUT
|
2008-03-05 09:52:00 -05:00
|
|
|
|
#define OUT
|
2008-11-17 18:29:00 -05:00
|
|
|
|
#endif
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
// Define the maximum number of retries for packet sends.
|
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
|
#define BD_MAXIMUM_RETRIES 20
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
// Define packet waiting status codes.
|
|
|
|
|
//
|
|
|
|
|
#define BD_PACKET_RECEIVED 0
|
|
|
|
|
#define BD_PACKET_TIMEOUT 1
|
|
|
|
|
#define BD_PACKET_RESEND 2
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
typedef struct _STRING {
|
|
|
|
|
UINT16 Length;
|
|
|
|
|
UINT16 MaximumLength;
|
|
|
|
|
PUINT8 Buffer;
|
|
|
|
|
} STRING, *PSTRING;
|
|
|
|
|
|
|
|
|
|
//======================================================================
|
|
|
|
|
// Selected structs and defines used by the KD protocol
|
2008-03-05 09:52:00 -05:00
|
|
|
|
//
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//
|
|
|
|
|
// If the packet type is PACKET_TYPE_KD_DEBUG_IO, then
|
|
|
|
|
// the format of the packet data is as follows:
|
|
|
|
|
//
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
#define DbgKdPrintStringApi 0x00003230L
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//
|
|
|
|
|
// For get string, the Null terminated prompt string
|
|
|
|
|
// immediately follows the message. The LengthOfStringRead
|
|
|
|
|
// field initially contains the maximum number of characters
|
|
|
|
|
// to read. Upon reply, this contains the number of bytes actually
|
|
|
|
|
// read. The data read immediately follows the message.
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
typedef struct _DBGKD_DEBUG_IO {
|
|
|
|
|
UINT32 ApiNumber;
|
|
|
|
|
UINT16 ProcessorLevel;
|
|
|
|
|
UINT16 Processor;
|
|
|
|
|
UINT32 LengthOfString;
|
|
|
|
|
UINT32 LengthOfStringRead;
|
|
|
|
|
} DBGKD_DEBUG_IO, *PDBGKD_DEBUG_IO;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//
|
|
|
|
|
// DbgKd APIs are for the portable kernel debugger
|
|
|
|
|
//
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//
|
|
|
|
|
// KD_PACKETS are the low level data format used in KD. All packets
|
|
|
|
|
// begin with a packet leader, byte count, packet type. The sequence
|
|
|
|
|
// for accepting a packet is:
|
|
|
|
|
//
|
|
|
|
|
// - read 4 bytes to get packet leader. If read times out (10 seconds)
|
|
|
|
|
// with a short read, or if packet leader is incorrect, then retry
|
|
|
|
|
// the read.
|
|
|
|
|
//
|
|
|
|
|
// - next read 2 byte packet type. If read times out (10 seconds) with
|
|
|
|
|
// a short read, or if packet type is bad, then start again looking
|
|
|
|
|
// for a packet leader.
|
|
|
|
|
//
|
|
|
|
|
// - next read 4 byte packet Id. If read times out (10 seconds)
|
|
|
|
|
// with a short read, or if packet Id is not what we expect, then
|
|
|
|
|
// ask for resend and restart again looking for a packet leader.
|
|
|
|
|
//
|
|
|
|
|
// - next read 2 byte count. If read times out (10 seconds) with
|
|
|
|
|
// a short read, or if byte count is greater than PACKET_MAX_SIZE,
|
|
|
|
|
// then start again looking for a packet leader.
|
|
|
|
|
//
|
|
|
|
|
// - next read 4 byte packet data checksum.
|
|
|
|
|
//
|
|
|
|
|
// - The packet data immediately follows the packet. There should be
|
|
|
|
|
// ByteCount bytes following the packet header. Read the packet
|
|
|
|
|
// data, if read times out (10 seconds) then start again looking for
|
|
|
|
|
// a packet leader.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
typedef struct _KD_PACKET {
|
|
|
|
|
UINT32 PacketLeader;
|
|
|
|
|
UINT16 PacketType;
|
|
|
|
|
UINT16 ByteCount;
|
|
|
|
|
UINT32 PacketId;
|
|
|
|
|
UINT32 Checksum;
|
|
|
|
|
} KD_PACKET, *PKD_PACKET;
|
|
|
|
|
|
|
|
|
|
#define PACKET_MAX_SIZE 4000
|
|
|
|
|
#define INITIAL_PACKET_ID 0x80800000 // Don't use 0
|
|
|
|
|
#define SYNC_PACKET_ID 0x00000800 // Or in with INITIAL_PACKET_ID
|
|
|
|
|
// to force a packet ID reset.
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Packet lead in sequence
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#define PACKET_LEADER 0x30303030 //0x77000077
|
|
|
|
|
#define PACKET_LEADER_BYTE 0x30
|
|
|
|
|
|
|
|
|
|
#define CONTROL_PACKET_LEADER 0x69696969
|
|
|
|
|
#define CONTROL_PACKET_LEADER_BYTE 0x69
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Packet Trailing Byte
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#define PACKET_TRAILING_BYTE 0xAA
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Packet Types
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#define PACKET_TYPE_KD_DEBUG_IO 3
|
|
|
|
|
#define PACKET_TYPE_KD_ACKNOWLEDGE 4 // Packet-control type
|
|
|
|
|
#define PACKET_TYPE_KD_RESEND 5 // Packet-control type
|
|
|
|
|
#define PACKET_TYPE_KD_RESET 6 // Packet-control type
|
|
|
|
|
#define PACKET_TYPE_MAX 12
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Status Constants for reading data from comport
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#define DBGKD_64BIT_PROTOCOL_VERSION2 6
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Communication functions (comio.c)
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
UINT32
|
|
|
|
|
BdComputeChecksum(
|
|
|
|
|
IN PUINT8 Buffer,
|
|
|
|
|
IN UINT32 Length
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
UINT16
|
|
|
|
|
BdReceivePacketLeader(
|
|
|
|
|
IN UINT32 PacketType,
|
|
|
|
|
OUT PUINT32 PacketLeader
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void
|
|
|
|
|
BdSendControlPacket(
|
|
|
|
|
IN UINT16 PacketType,
|
|
|
|
|
IN UINT32 PacketId
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
UINT32
|
|
|
|
|
BdReceivePacket(
|
|
|
|
|
IN UINT32 ExpectedPacketType,
|
|
|
|
|
OUT PSTRING MessageHeader,
|
|
|
|
|
OUT PSTRING MessageData,
|
|
|
|
|
OUT PUINT32 DataLength
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void
|
|
|
|
|
BdSendPacket(
|
|
|
|
|
IN UINT32 PacketType,
|
|
|
|
|
IN PSTRING MessageHeader,
|
|
|
|
|
IN PSTRING MessageData
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
UINT32
|
|
|
|
|
BdReceiveString(
|
|
|
|
|
OUT PUINT8 Destination,
|
|
|
|
|
IN UINT32 Length
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void
|
|
|
|
|
BdSendString(
|
|
|
|
|
IN PUINT8 Source,
|
|
|
|
|
IN UINT32 Length
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void
|
|
|
|
|
BdSendControlPacket(
|
|
|
|
|
IN UINT16 PacketType,
|
|
|
|
|
IN UINT32 PacketId
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Debugger enabled and present.
|
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
|
static BOOL BdDebuggerNotPresent = 0;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
// Next packet id to send and next packet id to expect.
|
|
|
|
|
//
|
|
|
|
|
static UINT32 BdPacketIdExpected;
|
|
|
|
|
static UINT32 BdNextPacketIdToSend;
|
|
|
|
|
|
|
|
|
|
// Number of retries and the retry count.
|
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
|
static UINT32 BdNumberRetries = BD_MAXIMUM_RETRIES;
|
|
|
|
|
static UINT32 BdRetryCount = BD_MAXIMUM_RETRIES;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
UINT32
|
|
|
|
|
BdComputeChecksum(
|
|
|
|
|
IN PUINT8 Buffer,
|
|
|
|
|
IN UINT32 Length
|
|
|
|
|
)
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//++
|
|
|
|
|
//
|
|
|
|
|
//Routine Description:
|
|
|
|
|
//
|
|
|
|
|
// This routine computes the checksum of the specified buffer.
|
|
|
|
|
//
|
|
|
|
|
//Arguments:
|
|
|
|
|
//
|
|
|
|
|
// Buffer - Supplies a pointer to the buffer.
|
|
|
|
|
//
|
|
|
|
|
// Length - Supplies the length of the buffer.
|
|
|
|
|
//
|
|
|
|
|
//Return Value:
|
|
|
|
|
//
|
|
|
|
|
// A UINT32 is return as the checksum for the input string.
|
|
|
|
|
//
|
|
|
|
|
//--
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
UINT32 Checksum = 0;
|
|
|
|
|
|
|
|
|
|
while (Length > 0) {
|
|
|
|
|
Checksum = Checksum + (UINT32)*Buffer++;
|
|
|
|
|
Length--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Checksum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
UINT16
|
|
|
|
|
BdReceivePacketLeader(
|
|
|
|
|
IN UINT32 /* PacketType */,
|
|
|
|
|
OUT PUINT32 PacketLeader
|
|
|
|
|
)
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//++
|
|
|
|
|
//
|
|
|
|
|
//Routine Description:
|
|
|
|
|
//
|
|
|
|
|
// This routine waits for a packet header leader.
|
|
|
|
|
//
|
|
|
|
|
//Arguments:
|
|
|
|
|
//
|
|
|
|
|
// PacketType - supplies the type of packet we are expecting.
|
|
|
|
|
//
|
|
|
|
|
// PacketLeader - supplies a pointer to a ulong variable to receive
|
|
|
|
|
// packet leader bytes.
|
|
|
|
|
//
|
|
|
|
|
//Return Value:
|
|
|
|
|
//
|
|
|
|
|
// BD_PACKET_RESEND - if resend is required.
|
|
|
|
|
// BD_PAKCET_TIMEOUT - if timeout.
|
|
|
|
|
// BD_PACKET_RECEIVED - if packet received.
|
|
|
|
|
//
|
|
|
|
|
//--
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
UINT8 Input, PreviousByte = 0;
|
|
|
|
|
UINT32 PacketId = 0;
|
|
|
|
|
UINT32 Index;
|
|
|
|
|
UINT32 ReturnCode;
|
|
|
|
|
|
|
|
|
|
// NOTE - With all the interrupts being off, it is very hard
|
|
|
|
|
// to implement the actual timeout code. (Maybe, by reading the CMOS.)
|
|
|
|
|
// Here we use a loop count to wait about 3 seconds. The CpGetByte
|
|
|
|
|
// will return with error code = CP_GET_NODATA if it cannot find data
|
|
|
|
|
// byte within 1 second. Kernel debugger's timeout period is 5 seconds.
|
|
|
|
|
//
|
|
|
|
|
Index = 0;
|
|
|
|
|
do {
|
|
|
|
|
ReturnCode = BdPortGetByte(&Input);
|
|
|
|
|
if (ReturnCode == CP_GET_NODATA) {
|
|
|
|
|
return BD_PACKET_TIMEOUT;
|
|
|
|
|
} else if (ReturnCode == CP_GET_ERROR) {
|
|
|
|
|
Index = 0;
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
} else { // if (ReturnCode == CP_GET_SUCCESS)
|
|
|
|
|
if ( Input == PACKET_LEADER_BYTE ||
|
|
|
|
|
Input == CONTROL_PACKET_LEADER_BYTE ) {
|
|
|
|
|
if ( Index == 0 ) {
|
|
|
|
|
PreviousByte = Input;
|
|
|
|
|
Index++;
|
|
|
|
|
} else if (Input == PreviousByte ) {
|
|
|
|
|
Index++;
|
|
|
|
|
} else {
|
|
|
|
|
PreviousByte = Input;
|
|
|
|
|
Index = 1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
Index = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while ( Index < 4 );
|
|
|
|
|
|
|
|
|
|
// return the packet leader and FALSE to indicate no resend is needed.
|
|
|
|
|
//
|
|
|
|
|
if ( Input == PACKET_LEADER_BYTE ) {
|
|
|
|
|
*PacketLeader = PACKET_LEADER;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
*PacketLeader = CONTROL_PACKET_LEADER;
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
BdDebuggerNotPresent = 0;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
return BD_PACKET_RECEIVED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void
|
|
|
|
|
BdSendControlPacket(
|
|
|
|
|
IN UINT16 PacketType,
|
|
|
|
|
IN UINT32 PacketId
|
|
|
|
|
)
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//++
|
|
|
|
|
//
|
|
|
|
|
//Routine Description:
|
|
|
|
|
//
|
|
|
|
|
// This routine sends a control packet to the host machine that is running the
|
|
|
|
|
// kernel debugger and waits for an ACK.
|
|
|
|
|
//
|
|
|
|
|
//Arguments:
|
|
|
|
|
//
|
|
|
|
|
// PacketType - Supplies the type of packet to send.
|
|
|
|
|
//
|
|
|
|
|
// PacketId - Supplies packet id, optionally.
|
|
|
|
|
//
|
|
|
|
|
//Return Value:
|
|
|
|
|
//
|
|
|
|
|
// None.
|
|
|
|
|
//
|
|
|
|
|
//--
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
KD_PACKET PacketHeader;
|
|
|
|
|
|
|
|
|
|
// Initialize and send the packet header.
|
|
|
|
|
//
|
|
|
|
|
PacketHeader.PacketLeader = CONTROL_PACKET_LEADER;
|
|
|
|
|
if (PacketId != 0) {
|
|
|
|
|
PacketHeader.PacketId = PacketId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PacketHeader.ByteCount = 0;
|
|
|
|
|
PacketHeader.Checksum = 0;
|
|
|
|
|
PacketHeader.PacketType = PacketType;
|
|
|
|
|
BdSendString((PUINT8)&PacketHeader, sizeof(KD_PACKET));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
UINT32
|
|
|
|
|
BdReceivePacket(
|
|
|
|
|
IN UINT32 PacketType,
|
|
|
|
|
OUT PSTRING MessageHeader,
|
|
|
|
|
OUT PSTRING MessageData,
|
|
|
|
|
OUT PUINT32 DataLength
|
|
|
|
|
)
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//++
|
|
|
|
|
//
|
|
|
|
|
//Routine Description:
|
|
|
|
|
//
|
|
|
|
|
// This routine receives a packet from the host machine that is running
|
|
|
|
|
// the kernel debugger UI. This routine is ALWAYS called after packet being
|
|
|
|
|
// sent by caller. It first waits for ACK packet for the packet sent and
|
|
|
|
|
// then waits for the packet desired.
|
|
|
|
|
//
|
|
|
|
|
// N.B. If caller is BdrintString, the parameter PacketType is
|
|
|
|
|
// PACKET_TYPE_KD_ACKNOWLEDGE. In this case, this routine will return
|
|
|
|
|
// right after the ack packet is received.
|
|
|
|
|
//
|
|
|
|
|
//Arguments:
|
|
|
|
|
//
|
|
|
|
|
// PacketType - Supplies the type of packet that is excepted.
|
|
|
|
|
//
|
|
|
|
|
// MessageHeader - Supplies a pointer to a string descriptor for the input
|
|
|
|
|
// message.
|
|
|
|
|
//
|
|
|
|
|
// MessageData - Supplies a pointer to a string descriptor for the input data.
|
|
|
|
|
//
|
|
|
|
|
// DataLength - Supplies pointer to UINT32 to receive length of recv. data.
|
|
|
|
|
//
|
|
|
|
|
//Return Value:
|
|
|
|
|
//
|
|
|
|
|
// BD_PACKET_RESEND - if resend is required.
|
|
|
|
|
// BD_PAKCET_TIMEOUT - if timeout.
|
|
|
|
|
// BD_PACKET_RECEIVED - if packet received.
|
|
|
|
|
//
|
|
|
|
|
//--
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
UINT8 Input;
|
|
|
|
|
UINT32 MessageLength;
|
|
|
|
|
KD_PACKET PacketHeader;
|
|
|
|
|
UINT32 ReturnCode;
|
|
|
|
|
UINT32 Checksum;
|
|
|
|
|
|
|
|
|
|
WaitForPacketLeader:
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read Packet Leader
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
ReturnCode = BdReceivePacketLeader(PacketType, &PacketHeader.PacketLeader);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// If we can successfully read packet leader, it has high possibility that
|
|
|
|
|
// kernel debugger is alive. So reset count.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if (ReturnCode != BD_PACKET_TIMEOUT) {
|
|
|
|
|
BdNumberRetries = BdRetryCount;
|
|
|
|
|
}
|
|
|
|
|
if (ReturnCode != BD_PACKET_RECEIVED) {
|
|
|
|
|
return ReturnCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read packet type.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
ReturnCode = BdReceiveString((PUINT8)&PacketHeader.PacketType,
|
|
|
|
|
sizeof(PacketHeader.PacketType));
|
|
|
|
|
|
|
|
|
|
if (ReturnCode == CP_GET_NODATA) {
|
|
|
|
|
return BD_PACKET_TIMEOUT;
|
|
|
|
|
|
|
|
|
|
} else if (ReturnCode == CP_GET_ERROR) {
|
|
|
|
|
if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) {
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// If read error and it is for a control packet, simply
|
|
|
|
|
// pretend that we have not seen this packet. Hopefully
|
|
|
|
|
// we will receive the packet we desire which automatically acks
|
|
|
|
|
// the packet we just sent.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// if read error while reading data packet, we have to ask
|
|
|
|
|
// kernel debugger to resend us the packet.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// if the packet we received is a resend request, we return true and
|
|
|
|
|
// let caller resend the packet.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if ( PacketHeader.PacketLeader == CONTROL_PACKET_LEADER &&
|
|
|
|
|
PacketHeader.PacketType == PACKET_TYPE_KD_RESEND ) {
|
|
|
|
|
return BD_PACKET_RESEND;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read data length.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
ReturnCode = BdReceiveString((PUINT8)&PacketHeader.ByteCount,
|
|
|
|
|
sizeof(PacketHeader.ByteCount));
|
|
|
|
|
|
|
|
|
|
if (ReturnCode == CP_GET_NODATA) {
|
|
|
|
|
return BD_PACKET_TIMEOUT;
|
|
|
|
|
} else if (ReturnCode == CP_GET_ERROR) {
|
|
|
|
|
if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) {
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
} else {
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read Packet Id.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
ReturnCode = BdReceiveString((PUINT8)&PacketHeader.PacketId,
|
|
|
|
|
sizeof(PacketHeader.PacketId));
|
|
|
|
|
|
|
|
|
|
if (ReturnCode == CP_GET_NODATA) {
|
|
|
|
|
return BD_PACKET_TIMEOUT;
|
|
|
|
|
} else if (ReturnCode == CP_GET_ERROR) {
|
|
|
|
|
if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) {
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
} else {
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read packet checksum.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
ReturnCode = BdReceiveString((PUINT8)&PacketHeader.Checksum,
|
|
|
|
|
sizeof(PacketHeader.Checksum));
|
|
|
|
|
|
|
|
|
|
if (ReturnCode == CP_GET_NODATA) {
|
|
|
|
|
return BD_PACKET_TIMEOUT;
|
|
|
|
|
|
|
|
|
|
} else if (ReturnCode == CP_GET_ERROR) {
|
|
|
|
|
if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) {
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
} else {
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// A complete packet header is received. Check its validity and
|
|
|
|
|
// perform appropriate action depending on packet type.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER ) {
|
|
|
|
|
if (PacketHeader.PacketType == PACKET_TYPE_KD_ACKNOWLEDGE ) {
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// If we received an expected ACK packet and we are not
|
|
|
|
|
// waiting for any new packet, update outgoing packet id
|
|
|
|
|
// and return. If we are NOT waiting for ACK packet
|
|
|
|
|
// we will keep on waiting. If the ACK packet
|
|
|
|
|
// is not for the packet we send, ignore it and keep on waiting.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if (PacketHeader.PacketId !=
|
|
|
|
|
(BdNextPacketIdToSend & ~SYNC_PACKET_ID)) {
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
|
|
|
|
|
} else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
|
|
|
|
|
BdNextPacketIdToSend ^= 1;
|
|
|
|
|
return BD_PACKET_RECEIVED;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESET) {
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// if we received Reset packet, reset the packet control variables
|
|
|
|
|
// and resend earlier packet.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
BdNextPacketIdToSend = INITIAL_PACKET_ID;
|
|
|
|
|
BdPacketIdExpected = INITIAL_PACKET_ID;
|
|
|
|
|
BdSendControlPacket(PACKET_TYPE_KD_RESET, 0L);
|
|
|
|
|
return BD_PACKET_RESEND;
|
|
|
|
|
|
|
|
|
|
} else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESEND) {
|
|
|
|
|
return BD_PACKET_RESEND;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Invalid packet header, ignore it.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// The packet header is for data packet (not control packet).
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
} else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// if we are waiting for ACK packet ONLY
|
|
|
|
|
// and we receive a data packet header, check if the packet id
|
|
|
|
|
// is what we expected. If yes, assume the acknowledge is lost (but
|
|
|
|
|
// sent), ask sender to resend and return with PACKET_RECEIVED.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if (PacketHeader.PacketId == BdPacketIdExpected) {
|
|
|
|
|
BdSendControlPacket(PACKET_TYPE_KD_RESEND, 0L);
|
|
|
|
|
BdNextPacketIdToSend ^= 1;
|
|
|
|
|
return BD_PACKET_RECEIVED;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
BdSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
|
|
|
|
|
PacketHeader.PacketId);
|
|
|
|
|
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// we are waiting for data packet and we received the packet header
|
|
|
|
|
// for data packet. Perform the following checks to make sure
|
|
|
|
|
// it is the packet we are waiting for.
|
|
|
|
|
//
|
|
|
|
|
// Check ByteCount received is valid
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
MessageLength = MessageHeader->MaximumLength;
|
|
|
|
|
if ((PacketHeader.ByteCount > (UINT16)PACKET_MAX_SIZE) ||
|
|
|
|
|
(PacketHeader.ByteCount < (UINT16)MessageLength)) {
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*DataLength = PacketHeader.ByteCount - MessageLength;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read the message header.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
ReturnCode = BdReceiveString(MessageHeader->Buffer, MessageLength);
|
|
|
|
|
if (ReturnCode != CP_GET_SUCCESS) {
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MessageHeader->Length = (UINT16)MessageLength;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read the message data.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
ReturnCode = BdReceiveString(MessageData->Buffer, *DataLength);
|
|
|
|
|
if (ReturnCode != CP_GET_SUCCESS) {
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MessageData->Length = (UINT16)*DataLength;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read packet trailing byte
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
ReturnCode = BdPortGetByte(&Input);
|
|
|
|
|
if (ReturnCode != CP_GET_SUCCESS || Input != PACKET_TRAILING_BYTE) {
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Check PacketType is what we are waiting for.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if (PacketType != PacketHeader.PacketType) {
|
|
|
|
|
BdSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
|
|
|
|
|
PacketHeader.PacketId
|
|
|
|
|
);
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Check PacketId is valid.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if (PacketHeader.PacketId == INITIAL_PACKET_ID ||
|
|
|
|
|
PacketHeader.PacketId == (INITIAL_PACKET_ID ^ 1)) {
|
|
|
|
|
if (PacketHeader.PacketId != BdPacketIdExpected) {
|
|
|
|
|
BdSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
|
|
|
|
|
PacketHeader.PacketId
|
|
|
|
|
);
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Check checksum is valid.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
Checksum = BdComputeChecksum(MessageHeader->Buffer,
|
|
|
|
|
MessageHeader->Length);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Checksum += BdComputeChecksum(MessageData->Buffer,
|
|
|
|
|
MessageData->Length);
|
|
|
|
|
|
|
|
|
|
if (Checksum != PacketHeader.Checksum) {
|
|
|
|
|
goto SendResendPacket;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Send Acknowledge byte and the Id of the packet received.
|
|
|
|
|
// Then, update the ExpectId for next incoming packet.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
BdSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
|
|
|
|
|
PacketHeader.PacketId);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// We have successfully received the packet so update the
|
|
|
|
|
// packet control variables and return success.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
BdPacketIdExpected ^= 1;
|
|
|
|
|
return BD_PACKET_RECEIVED;
|
|
|
|
|
|
|
|
|
|
SendResendPacket:
|
|
|
|
|
BdSendControlPacket(PACKET_TYPE_KD_RESEND, 0L);
|
|
|
|
|
goto WaitForPacketLeader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void
|
|
|
|
|
BdSendPacket(
|
|
|
|
|
IN UINT32 PacketType,
|
|
|
|
|
IN PSTRING MessageHeader,
|
|
|
|
|
IN PSTRING MessageData
|
|
|
|
|
)
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//++
|
|
|
|
|
//
|
|
|
|
|
//Routine Description:
|
|
|
|
|
//
|
|
|
|
|
// This routine sends a packet to the host machine that is running the
|
|
|
|
|
// kernel debugger and waits for an ACK.
|
|
|
|
|
//
|
|
|
|
|
//Arguments:
|
|
|
|
|
//
|
|
|
|
|
// PacketType - Supplies the type of packet to send.
|
|
|
|
|
//
|
|
|
|
|
// MessageHeader - Supplies a pointer to a string descriptor that describes
|
|
|
|
|
// the message information.
|
|
|
|
|
//
|
|
|
|
|
// MessageData - Supplies a pointer to a string descriptor that describes
|
|
|
|
|
// the optional message data.
|
|
|
|
|
//
|
|
|
|
|
//Return Value:
|
|
|
|
|
//
|
|
|
|
|
// None.
|
|
|
|
|
//
|
|
|
|
|
//--
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
KD_PACKET PacketHeader;
|
|
|
|
|
UINT32 MessageDataLength;
|
|
|
|
|
UINT32 ReturnCode;
|
|
|
|
|
PDBGKD_DEBUG_IO DebugIo;
|
|
|
|
|
|
|
|
|
|
if (MessageData != NULL) {
|
|
|
|
|
MessageDataLength = MessageData->Length;
|
|
|
|
|
PacketHeader.Checksum = BdComputeChecksum(MessageData->Buffer,
|
|
|
|
|
MessageData->Length);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
MessageDataLength = 0;
|
|
|
|
|
PacketHeader.Checksum = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PacketHeader.Checksum += BdComputeChecksum(MessageHeader->Buffer,
|
|
|
|
|
MessageHeader->Length);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Initialize and send the packet header.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
PacketHeader.PacketLeader = PACKET_LEADER;
|
|
|
|
|
PacketHeader.ByteCount = (UINT16)(MessageHeader->Length + MessageDataLength);
|
|
|
|
|
PacketHeader.PacketType = (UINT16)PacketType;
|
|
|
|
|
BdNumberRetries = BdRetryCount;
|
|
|
|
|
do {
|
|
|
|
|
if (BdNumberRetries == 0) {
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// If the packet is not for reporting exception, we give up
|
|
|
|
|
// and declare debugger not present.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if (PacketType == PACKET_TYPE_KD_DEBUG_IO) {
|
|
|
|
|
DebugIo = (PDBGKD_DEBUG_IO)MessageHeader->Buffer;
|
|
|
|
|
if (DebugIo->ApiNumber == DbgKdPrintStringApi) {
|
2008-11-17 18:29:00 -05:00
|
|
|
|
BdDebuggerNotPresent = 1;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
BdNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID;
|
|
|
|
|
BdPacketIdExpected = INITIAL_PACKET_ID;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Setting PacketId has to be in the do loop in case Packet Id was
|
|
|
|
|
// reset.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
PacketHeader.PacketId = BdNextPacketIdToSend;
|
|
|
|
|
BdSendString((PUINT8)&PacketHeader, sizeof(KD_PACKET));
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Output message header.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
BdSendString(MessageHeader->Buffer, MessageHeader->Length);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Output message data.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if ( MessageDataLength ) {
|
|
|
|
|
BdSendString(MessageData->Buffer, MessageData->Length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Output a packet trailing byte
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
BdPortPutByte(PACKET_TRAILING_BYTE);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Wait for the Ack Packet
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
ReturnCode = BdReceivePacket(PACKET_TYPE_KD_ACKNOWLEDGE,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
if (ReturnCode == BD_PACKET_TIMEOUT) {
|
|
|
|
|
BdNumberRetries--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} while (ReturnCode != BD_PACKET_RECEIVED);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Reset Sync bit in packet id. The packet we sent may have Sync bit set
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
BdNextPacketIdToSend &= ~SYNC_PACKET_ID;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Since we are able to talk to debugger, the retrycount is set to
|
|
|
|
|
// maximum value.
|
|
|
|
|
//
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
BdRetryCount = BD_MAXIMUM_RETRIES;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
UINT32
|
|
|
|
|
BdReceiveString(
|
|
|
|
|
OUT PUINT8 Destination,
|
|
|
|
|
IN UINT32 Length
|
|
|
|
|
)
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//++
|
|
|
|
|
//
|
|
|
|
|
//Routine Description:
|
|
|
|
|
//
|
|
|
|
|
// This routine reads a string from the kernel debugger port.
|
|
|
|
|
//
|
|
|
|
|
//Arguments:
|
|
|
|
|
//
|
|
|
|
|
// Destination - Supplies a pointer to the input string.
|
|
|
|
|
//
|
|
|
|
|
// Length - Supplies the length of the string to be read.
|
|
|
|
|
//
|
|
|
|
|
//Return Value:
|
|
|
|
|
//
|
|
|
|
|
// CP_GET_SUCCESS is returned if string is successfully read from the
|
|
|
|
|
// kernel debugger line.
|
|
|
|
|
// CP_GET_ERROR is returned if error encountered during reading.
|
|
|
|
|
// CP_GET_NODATA is returned if timeout.
|
|
|
|
|
//
|
|
|
|
|
//--
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
UINT8 Input;
|
|
|
|
|
UINT32 ReturnCode;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read bytes until either an error is encountered or the entire string
|
|
|
|
|
// has been read.
|
|
|
|
|
//
|
|
|
|
|
while (Length > 0) {
|
|
|
|
|
ReturnCode = BdPortGetByte(&Input);
|
|
|
|
|
if (ReturnCode != CP_GET_SUCCESS) {
|
|
|
|
|
return ReturnCode;
|
|
|
|
|
} else {
|
|
|
|
|
*Destination++ = Input;
|
|
|
|
|
Length -= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CP_GET_SUCCESS;
|
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
|
|
2008-03-05 09:52:00 -05:00
|
|
|
|
static
|
|
|
|
|
void
|
|
|
|
|
BdSendString(
|
|
|
|
|
IN PUINT8 Source,
|
|
|
|
|
IN UINT32 Length
|
|
|
|
|
)
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//++
|
|
|
|
|
//
|
|
|
|
|
//Routine Description:
|
|
|
|
|
//
|
|
|
|
|
// This routine writes a string to the kernel debugger port.
|
|
|
|
|
//
|
|
|
|
|
//Arguments:
|
|
|
|
|
//
|
|
|
|
|
// Source - Supplies a pointer to the output string.
|
|
|
|
|
//
|
|
|
|
|
// Length - Supplies the length of the string to be written.
|
|
|
|
|
//
|
|
|
|
|
//Return Value:
|
|
|
|
|
//
|
|
|
|
|
// None.
|
|
|
|
|
//
|
|
|
|
|
//--
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
UINT8 Output;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Write bytes to the kernel debugger port.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
while (Length > 0) {
|
|
|
|
|
Output = *Source++;
|
|
|
|
|
BdPortPutByte(Output);
|
|
|
|
|
Length -= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BdPrintString(char *Output, UINT Length)
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
//++
|
|
|
|
|
//
|
|
|
|
|
//Routine Description:
|
|
|
|
|
//
|
|
|
|
|
// This routine prints a string.
|
|
|
|
|
//
|
|
|
|
|
//Arguments:
|
|
|
|
|
//
|
|
|
|
|
// Output - Supplies a pointer to a string descriptor for the output string.
|
|
|
|
|
//
|
|
|
|
|
//--
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
STRING MessageData;
|
|
|
|
|
STRING MessageHeader;
|
|
|
|
|
DBGKD_DEBUG_IO DebugIo;
|
|
|
|
|
|
|
|
|
|
if (BdDebuggerNotPresent) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the total message length is greater than the maximum packet size,
|
|
|
|
|
// then truncate the output string.
|
|
|
|
|
//
|
|
|
|
|
if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) {
|
|
|
|
|
Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Construct the print string message and message descriptor.
|
|
|
|
|
//
|
|
|
|
|
DebugIo.ApiNumber = DbgKdPrintStringApi;
|
|
|
|
|
DebugIo.ProcessorLevel = 0;
|
|
|
|
|
DebugIo.Processor = 0;
|
|
|
|
|
DebugIo.LengthOfString = Length;
|
|
|
|
|
MessageHeader.Length = sizeof(DBGKD_DEBUG_IO);
|
|
|
|
|
MessageHeader.Buffer = (PUINT8)&DebugIo;
|
|
|
|
|
|
|
|
|
|
// Construct the print string data and data descriptor.
|
|
|
|
|
//
|
|
|
|
|
MessageData.Length = (UINT16)Length;
|
|
|
|
|
MessageData.Buffer = (PUINT8)Output;
|
|
|
|
|
|
|
|
|
|
// Send packet to the kernel debugger on the host machine.
|
|
|
|
|
//
|
|
|
|
|
BdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &MessageHeader, &MessageData);
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
bool BdInitDebugger(bool present)
|
2008-03-05 09:52:00 -05:00
|
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
|
// Configure debugger state based on presence of transport layer.
|
2008-03-05 09:52:00 -05:00
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
|
if (present) {
|
|
|
|
|
BdDebuggerNotPresent = 0;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
|
|
// Initialize the ID for the NEXT packet to send and the Expect
|
|
|
|
|
// ID of next incoming packet.
|
|
|
|
|
//
|
|
|
|
|
BdNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID;
|
|
|
|
|
BdPacketIdExpected = INITIAL_PACKET_ID;
|
|
|
|
|
|
|
|
|
|
// Number of retries and the retry count.
|
|
|
|
|
//
|
|
|
|
|
BdNumberRetries = 5;
|
|
|
|
|
BdRetryCount = 5;
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
return 1;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
}
|
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
|
BdDebuggerNotPresent = 1;
|
|
|
|
|
return 0;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
}
|