|
|
//----------------------------------------------------------------------------
//
// KD hard-line communication support.
//
// Copyright (C) Microsoft Corporation, 1999-2001.
//
//----------------------------------------------------------------------------
#ifndef __DBGKDTRANS_HPP__
#define __DBGKDTRANS_HPP__
#define PACKET_MAX_MANIP_SIZE \
(PACKET_MAX_SIZE + sizeof(DBGKD_MANIPULATE_STATE64) - \ sizeof(DBGKD_MANIPULATE_STATE32) + sizeof(KD_PACKET))
enum { DBGKD_WRITE_PACKET, DBGKD_WRITE_RESEND, };
enum { DBGKD_WAIT_PACKET, DBGKD_WAIT_ACK, DBGKD_WAIT_RESYNC, DBGKD_WAIT_FAILED, DBGKD_WAIT_RESEND, DBGKD_WAIT_AGAIN, };
enum { DBGKD_TRANSPORT_COM, DBGKD_TRANSPORT_1394, DBGKD_TRANSPORT_COUNT };
void InitKdFileAssoc(void); void ParseKdFileAssoc(void);
class DbgKdTransport : public ParameterStringParser { public: //
// DbgKdTransport.
//
void Restart(void);
// Base implementation displays general information and
// packets/bytes read/written. It should be invoked
// before derived operations.
virtual void OutputInfo(void); // Base implementation creates events for overlapped operations.
virtual HRESULT Initialize(void); // Base implementation cleans up events.
virtual void Uninitialize(void); virtual BOOL Read(IN PVOID Buffer, IN ULONG SizeOfBuffer, IN PULONG BytesRead) = 0; virtual BOOL Write(IN PVOID Buffer, IN ULONG SizeOfBuffer, IN PULONG BytesWritten) = 0;
// Base implementation does nothing.
virtual void CycleSpeed(void);
virtual HRESULT ReadTargetPhysicalMemory(IN ULONG64 MemoryOffset, IN PVOID Buffer, IN ULONG SizeofBuffer, IN PULONG BytesRead);
// This routine keeps on sending reset packet to target until reset packet
// is acknowledged by a reset packet from target.
//
// N.B. This routine is intended to be used by kernel debugger at startup
// time (ONLY) to get packet control variables on both target and host
// back in synchronization. Also, reset request will cause kernel to
// reset its control variables AND resend us its previous packet (with
// the new packet id).
virtual VOID Synchronize(VOID) = 0;
virtual ULONG ReadPacketContents(IN USHORT PacketType) = 0; virtual ULONG WritePacketContents(IN KD_PACKET* Packet, IN PVOID PacketData, IN USHORT PacketDataLength, IN PVOID MorePacketData OPTIONAL, IN USHORT MorePacketDataLength OPTIONAL, IN BOOL NoAck) = 0;
ULONG HandleDebugIo(PDBGKD_DEBUG_IO Packet); ULONG HandleTraceIo(PDBGKD_TRACE_IO Packet); ULONG HandleControlRequest(PDBGKD_CONTROL_REQUEST Packet); ULONG HandleFileIo(PDBGKD_FILE_IO Packet); ULONG WaitForPacket(IN USHORT PacketType, OUT PVOID Packet);
VOID WriteBreakInPacket(VOID); VOID WriteControlPacket(IN USHORT PacketType, IN ULONG PacketId OPTIONAL); VOID WriteDataPacket(IN PVOID PacketData, IN USHORT PacketDataLength, IN USHORT PacketType, IN PVOID MorePacketData OPTIONAL, IN USHORT MorePacketDataLength OPTIONAL, IN BOOL NoAck);
inline VOID WritePacket(IN PVOID PacketData, IN USHORT PacketDataLength, IN USHORT PacketType, IN PVOID MorePacketData OPTIONAL, IN USHORT MorePacketDataLength OPTIONAL) { WriteDataPacket(PacketData, PacketDataLength, PacketType, MorePacketData, MorePacketDataLength, FALSE); } inline VOID WriteAsyncPacket(IN PVOID PacketData, IN USHORT PacketDataLength, IN USHORT PacketType, IN PVOID MorePacketData OPTIONAL, IN USHORT MorePacketDataLength OPTIONAL) { WriteDataPacket(PacketData, PacketDataLength, PacketType, MorePacketData, MorePacketDataLength, TRUE); }
ULONG ComputeChecksum(IN PUCHAR Buffer, IN ULONG Length);
// This save/restore isn't particularly elegant
// but we need something like it. We receive a state change
// without knowing what kind of machine we're talking to.
// We have to send/receive a GetVersion packet to get that
// information, but we need to keep the original packet
// information around while we do so.
void SaveReadPacket(void) { memcpy(s_SavedPacket, s_Packet, sizeof(s_Packet)); s_SavedPacketHeader = s_PacketHeader; } void RestoreReadPacket(void) { memcpy(s_Packet, s_SavedPacket, sizeof(s_Packet)); s_PacketHeader = s_SavedPacketHeader; }
ULONG m_Index; HANDLE m_Handle; BOOL m_DirectPhysicalMemory; ULONG m_InvPacketRetryLimit; BOOL m_AckWrites;
//
// This overlapped structure will be used for all serial read
// operations. We only need one structure since the code is
// designed so that no more than one serial read operation is
// outstanding at any one time.
//
OVERLAPPED m_ReadOverlapped;
//
// This overlapped structure will be used for all serial write
// operations. We only need one structure since the code is
// designed so that no more than one serial write operation is
// outstanding at any one time.
//
OVERLAPPED m_WriteOverlapped;
ULONG m_PacketsRead; ULONG64 m_BytesRead; ULONG m_PacketsWritten; ULONG64 m_BytesWritten; // ID for expected incoming packet.
ULONG m_PacketExpected; // ID for Next packet to send.
ULONG m_NextPacketToSend;
// Thread ID for thread in WaitStateChange. Normally
// multithreaded access to the transport is prevented by
// the engine lock, but the engine lock is suspended
// while WaitStateChange is doing its WaitPacketForever.
// During that time other threads must be forcibly
// prevented from using the kernel connection.
ULONG m_WaitingThread;
BOOL m_AllowInitialBreak; BOOL m_Resync; BOOL m_BreakIn; BOOL m_SyncBreakIn; BOOL m_ValidUnaccessedPacket; static UCHAR s_BreakinPacket[1]; static UCHAR s_PacketTrailingByte[1]; static UCHAR s_PacketLeader[4];
static UCHAR s_Packet[PACKET_MAX_MANIP_SIZE]; static KD_PACKET s_PacketHeader;
static UCHAR s_SavedPacket[PACKET_MAX_MANIP_SIZE]; static KD_PACKET s_SavedPacketHeader; };
class DbgKdComTransport : public DbgKdTransport { public: DbgKdComTransport(void);
// ParameterStringParser.
virtual ULONG GetNumberParameters(void); virtual void GetParameter(ULONG Index, PSTR Name, PSTR Value); virtual void ResetParameters(void); virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
// DbgKdTransport.
virtual HRESULT Initialize(void); virtual void Uninitialize(void);
virtual BOOL Read(IN PVOID Buffer, IN ULONG SizeOfBuffer, IN PULONG BytesRead); virtual BOOL Write(IN PVOID Buffer, IN ULONG SizeOfBuffer, IN PULONG BytesWritten); virtual void CycleSpeed(void);
virtual VOID Synchronize(VOID);
virtual ULONG ReadPacketContents(IN USHORT PacketType); virtual ULONG WritePacketContents(IN KD_PACKET* Packet, IN PVOID PacketData, IN USHORT PacketDataLength, IN PVOID MorePacketData OPTIONAL, IN USHORT MorePacketDataLength OPTIONAL, IN BOOL NoAck);
//
// DbgKdComTransport.
//
ULONG ReadPacketLeader(IN ULONG PacketType, OUT PULONG PacketLeader); void CheckComStatus(void); DWORD SelectNewBaudRate(DWORD NewRate);
char m_PortName[MAX_PARAM_VALUE + 8]; ULONG m_BaudRate; BOOL m_Modem; ULONG m_Timeout;
// Used to carrier detection.
DWORD m_ComEvent;
//
// This overlapped structure will be used for all event operations.
// We only need one structure since the code is designed so that no more
// than one serial event operation is outstanding at any one time.
//
OVERLAPPED m_EventOverlapped; };
enum { DBGKD_1394_OPERATION_MODE_DEBUG, DBGKD_1394_OPERATION_RAW_MEMORY_ACCESS };
class DbgKd1394Transport : public DbgKdTransport { public: DbgKd1394Transport(void);
// ParameterStringParser.
virtual ULONG GetNumberParameters(void); virtual void GetParameter(ULONG Index, PSTR Name, PSTR Value); virtual void ResetParameters(void); virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
// DbgKdTransport.
virtual HRESULT Initialize(void); virtual void Uninitialize(void);
virtual BOOL Read(IN PVOID Buffer, IN ULONG SizeOfBuffer, IN PULONG BytesRead); virtual BOOL Write(IN PVOID Buffer, IN ULONG SizeOfBuffer, IN PULONG BytesWritten);
virtual HRESULT ReadTargetPhysicalMemory(IN ULONG64 MemoryOffset, IN PVOID Buffer, IN ULONG SizeofBuffer, IN PULONG BytesRead);
virtual VOID Synchronize(VOID);
virtual ULONG ReadPacketContents(IN USHORT PacketType); virtual ULONG WritePacketContents(IN KD_PACKET* Packet, IN PVOID PacketData, IN USHORT PacketDataLength, IN PVOID MorePacketData OPTIONAL, IN USHORT MorePacketDataLength OPTIONAL, IN BOOL NoAck);
// DbgKd1394Transport.
BOOL SwitchVirtualDebuggerDriverMode(IN ULONG NewMode);
ULONG m_Channel; ULONG m_OperationMode;
UCHAR m_TxPacket[PACKET_MAX_MANIP_SIZE]; };
extern DbgKdTransport* g_DbgKdTransport;
HRESULT DbgKdConnectAndInitialize(PCSTR Options);
VOID DbgKdpHandlePromptString( IN PDBGKD_DEBUG_IO IoMessage );
VOID DbgKdpPrint( IN ULONG Processor, IN PCSTR String, IN USHORT StringLength, IN ULONG Mask );
VOID DbgKdpPrintTrace( IN ULONG Processor, IN PUCHAR Data, IN USHORT DataLength, IN ULONG Mask );
#endif // #ifndef __DBGKDTRANS_HPP__
|