//---------------------------------------------------------------------------- // // 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__