////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: halkd1394.cpp: runtime support for debugging over 1394. // // For more information see: // \nt\base\ntos\kd64 // \nt\base\boot\kdcom // \nt\base\boot\kd1394 // \nt\base\boot\kdusb2 // \nt\sdktools\debuggers\ntsd64 // // Note: Kernel Only // #include "hal.h" #include "halkd.h" #include "halkd1394.h" // // Debugger Debugging // #define KDDBG if (0) kdprintf #define KDDBG2 if (0) kdprintf ///////////////////////////////////////////////////////// Debugger Structures. // // These structures are accessed directly by the host using RDMA. // #define DEBUG_BUS1394_MAX_PACKET_SIZE 4000 #define DEBUG_1394_MAJOR_VERSION 0x1 #define DEBUG_1394_MINOR_VERSION 0x0 #define DEBUG_1394_CONFIG_TAG 0xBABABABA struct DEBUG_1394_SEND_PACKET { UINT32 TransferStatus; UINT32 PacketHeader[4]; UINT32 Length; UCHAR Packet[DEBUG_BUS1394_MAX_PACKET_SIZE]; UCHAR Padding[72]; }; STATIC_ASSERT(sizeof(DEBUG_1394_SEND_PACKET) == 4096); struct DEBUG_1394_RECEIVE_PACKET { UINT32 TransferStatus; UINT32 Length; UCHAR Packet[DEBUG_BUS1394_MAX_PACKET_SIZE]; UCHAR Padding[88]; }; STATIC_ASSERT(sizeof(DEBUG_1394_RECEIVE_PACKET) == 4096); // exists on target, host reads it to match for id. struct DEBUG_1394_CONFIG { UINT32 Tag; UINT16 MajorVersion; UINT16 MinorVersion; UINT32 Id; UINT32 BusPresent; UINT64 SendPacket; UINT64 ReceivePacket; }; STATIC_ASSERT(sizeof(DEBUG_1394_CONFIG) == 32); struct DEBUG_1394_DATA { // POHCI_REGISTER_MAP BaseAddress; // our OHCI register map UINT32 CromBuffer[248]; // our config ROM - must be 1k aligned DEBUG_1394_CONFIG Config; // our config for this session DEBUG_1394_SEND_PACKET SendPacket; // our send packet (isoch packet) DEBUG_1394_RECEIVE_PACKET ReceivePacket; // our receive packet }; STATIC_ASSERT(sizeof(DEBUG_1394_DATA) == 1024 + 4096 + 4096); STATIC_ASSERT(sizeof(DEBUG_1394_DATA) <= 3 * 4096); // we allocate 12KB in boot. ////////////////////////////////////////////////////////////////////////////// // #define TIMEOUT_COUNT 1024*500 #define MAX_REGISTER_READS 400000 // // Global Data Structures // static DEBUG_1394_DATA * Kd1394Data; static volatile OHCI_REGISTER_MAP * KdRegisters; // static ULONG_PTR MmGetPhysicalAddress(PVOID pv) { return (ULONG_PTR)pv; } // ?? need to look into this static UINT32 Dbg1394_StallExecution(UINT32 LoopCount) { volatile UINT32 b = 1; for (volatile UINT32 k = 0; k < LoopCount; k++) { for (volatile UINT32 i = 1; i < 100000; i++) { #ifdef ISA_IX86 __asm pause; #endif b = b * (i>>k); } } return b; } // Exchange byte pairs 0:3 and 1:2 of Source and returns the resulting ULONG. static inline UINT32 Dbg1394_ByteSwap(UINT32 Source) { return (((Source) << (8 * 3)) | ((Source & 0x0000FF00) << (8 * 1)) | ((Source & 0x00FF0000) >> (8 * 1)) | ((Source) >> (8 * 3))); } // Derive the 16 bit CRC as defined by IEEE 1212 clause 8.1.5. // (ISO/IEC 13213) First edition 1994-10-05. // data - UINT32 data to derive CRC from. // check - check value. static UINT32 Dbg1394_Crc16(UINT32 data, UINT32 check) { UINT32 next = check; for (INT32 shift = 28; shift >= 0; shift -= 4) { UINT32 sum = ((next >> 12) ^ (data >> shift)) & 0xf; next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum); } return (next & 0xFFFF); } // Calculate a CRC for the pointer to the Quadlet data. // Quadlet - Pointer to data to CRC // length - length of data to CRC static UINT16 Dbg1394_CalculateCrc(UINT32 *Quadlet, UINT32 length) { UINT32 temp = 0; for (UINT32 index = 0; index < length; index++) { temp = Dbg1394_Crc16(Quadlet[index], temp); } return (UINT16)temp; } ////////////////////////////////////////////////// Initialize the controller! // bool Kdp1394Init(UINT16 Channel, ULONG_PTR Base, ULONG_PTR BufferAddr32, UINT32 BufferSize32) { if (Base == 0 || BufferAddr32 == 0 || BufferSize32 < sizeof(DEBUG_1394_DATA)) { return false; } // Note: Kd1394Data must be in the low 32-bits of address space due to // limits on valid 1394 DMA addresses. It must also be contiguous. Kd1394Data = (DEBUG_1394_DATA *)BufferAddr32; memset(Kd1394Data, 0, sizeof(*Kd1394Data)); // get our base address KdRegisters = (volatile OHCI_REGISTER_MAP *)Base; // initialize our config info for host debugger to read. Kd1394Data->Config.Tag = DEBUG_1394_CONFIG_TAG; Kd1394Data->Config.MajorVersion = DEBUG_1394_MAJOR_VERSION; Kd1394Data->Config.MinorVersion = DEBUG_1394_MINOR_VERSION; Kd1394Data->Config.Id = (Channel < 0x100) ? Channel : 0; Kd1394Data->Config.BusPresent = false; Kd1394Data->Config.SendPacket = MmGetPhysicalAddress(&Kd1394Data->SendPacket); Kd1394Data->Config.ReceivePacket = MmGetPhysicalAddress(&Kd1394Data->ReceivePacket); // get our version UINT32 ulVersion = KdRegisters->Version.all; UCHAR MajorVersion = (UCHAR)(ulVersion >> 16); // make sure we have a valid version if (MajorVersion != 1) { // INVESTIGATE kdprintf("1394: MajorVersion != 1\n"); return false; } // soft reset to initialize the controller HC_CONTROL_REGISTER HCControl; HCControl.all = 0; HCControl.SoftReset = true; KdRegisters->HCControlSet.all = HCControl.all; // wait until reset complete - ?? UINT32 retry = 1000; // ?? do { HCControl.all = KdRegisters->HCControlSet.all; Dbg1394_StallExecution(1); } while ((HCControl.SoftReset) && (--retry)); if (retry == 0) { kdprintf("1394: Reset failed\n"); return false; } // enable link to phy communication. HCControl.all = 0; HCControl.Lps = true; KdRegisters->HCControlSet.all = HCControl.all; Dbg1394_StallExecution(20); // initialize HCControl register // send data in little-endian order (i.e. do byte swap). HCControl.all = 0; HCControl.NoByteSwapData = true; KdRegisters->HCControlClear.all = HCControl.all; // enable posted writes. HCControl.all = 0; HCControl.PostedWriteEnable = true; KdRegisters->HCControlSet.all = HCControl.all; // setup the link control LINK_CONTROL_REGISTER LinkControl; LinkControl.all = 0; LinkControl.CycleTimerEnable = true; LinkControl.CycleMaster = true; LinkControl.RcvPhyPkt = true; LinkControl.RcvSelfId = true; KdRegisters->LinkControlClear.all = LinkControl.all; LinkControl.all = 0; LinkControl.CycleTimerEnable = true; LinkControl.CycleMaster = true; KdRegisters->LinkControlSet.all = LinkControl.all; // set the bus number (hardcoded to 0x3FF) - ??? what about node id?? NODE_ID_REGISTER NodeId; NodeId.all = 0; NodeId.BusId = (UINT16)0x3FF; KdRegisters->NodeId.all = NodeId.all; // do something with the crom... // 0xf0000404 - bus id register Kd1394Data->CromBuffer[1] = 0x31333934; // 0xf0000408 - bus options register BUS_OPTIONS_REGISTER BusOptions; BusOptions.all = Dbg1394_ByteSwap(KdRegisters->BusOptions.all); BusOptions.Pmc = false; BusOptions.Bmc = false; BusOptions.Isc = false; BusOptions.Cmc = false; BusOptions.Irmc = false; BusOptions.g = 1; Kd1394Data->CromBuffer[2] = Dbg1394_ByteSwap(BusOptions.all); // 0xf000040c - global unique id hi Kd1394Data->CromBuffer[3] = KdRegisters->GuidHi; // 0xf0000410 - global unique id lo Kd1394Data->CromBuffer[4] = KdRegisters->GuidLo; // 0xf0000400 - config ROM header - set last to calculate CRC! CONFIG_ROM_INFO ConfigRomHeader; ConfigRomHeader.all = 0; ConfigRomHeader.CRI_Info_Length = 4; ConfigRomHeader.CRI_CRC_Length = 4; ConfigRomHeader.CRI_CRC_Value = Dbg1394_CalculateCrc(&Kd1394Data->CromBuffer[1], ConfigRomHeader.CRI_CRC_Length); Kd1394Data->CromBuffer[0] = ConfigRomHeader.all; Kd1394Data->CromBuffer[6] = 0xC083000C; // 0xf0000418 - node capabilities Kd1394Data->CromBuffer[7] = 0xF2500003; // 0xf000041C - module vendor id // KD's state machine looks for 1c w/ 50f2, 1d w/ 02, then 1e w/ address. Kd1394Data->CromBuffer[8] = 0xF250001C; // 0xf0000420 - extended key (for KD) Kd1394Data->CromBuffer[9] = 0x0200001D; // 0xf0000424 - debug key (for KD) // 0xf0000428 - debug value (for KD) IMMEDIATE_ENTRY CromEntry; CromEntry.all = (UINT32)MmGetPhysicalAddress(&Kd1394Data->Config); CromEntry.IE_Key = 0x1E; Kd1394Data->CromBuffer[10] = Dbg1394_ByteSwap(CromEntry.all); // 0xf0000414 - root directory header - set last to calculate CRC! DIRECTORY_INFO DirectoryInfo; DirectoryInfo.all = 0; DirectoryInfo.DI_Length = 5; DirectoryInfo.DI_CRC = Dbg1394_CalculateCrc(&Kd1394Data->CromBuffer[6], DirectoryInfo.DI_Length); Kd1394Data->CromBuffer[5] = Dbg1394_ByteSwap(DirectoryInfo.all); // write the first few registers KdRegisters->ConfigRomHeader.all = Kd1394Data->CromBuffer[0]; KdRegisters->BusId = Kd1394Data->CromBuffer[1]; KdRegisters->BusOptions.all = Kd1394Data->CromBuffer[2]; KdRegisters->GuidHi = Kd1394Data->CromBuffer[3]; KdRegisters->GuidLo = Kd1394Data->CromBuffer[4]; // set our crom KdRegisters->ConfigRomMap = (UINT32)MmGetPhysicalAddress(&Kd1394Data->CromBuffer); // disable all interrupts. wdm driver will enable them later - ?? KdRegisters->IntMaskClear.all = 0xFFFFFFFF; // enable the link HCControl.all = 0; HCControl.LinkEnable = true; KdRegisters->HCControlSet.all = HCControl.all; Dbg1394_StallExecution(1000); // enable access filters to all nodes KdRegisters->AsynchReqFilterLoSet = 0xFFFFFFFF; KdRegisters->AsynchReqFilterHiSet = 0xFFFFFFFF; KdRegisters->PhyReqFilterHiSet = 0xFFFFFFFF; KdRegisters->PhyReqFilterLoSet = 0xFFFFFFFF; // hard reset on the bus (so KD will look for us) PHY_CONTROL_REGISTER PhyControl; PhyControl.all = 0; PhyControl.RdReg = true; PhyControl.RegAddr = 1; KdRegisters->PhyControl.all = PhyControl.all; retry = MAX_REGISTER_READS; do { PhyControl.all = KdRegisters->PhyControl.all; } while ((!PhyControl.RdDone) && --retry); if (retry == 0) { kdprintf("1394: Read on bus failed\n"); return false; } UCHAR Data = ((UCHAR)PhyControl.RdData | PHY_INITIATE_BUS_RESET); PhyControl.all = 0; PhyControl.WrReg = true; PhyControl.RegAddr = 1; PhyControl.WrData = Data; KDDBG2("1394: Writing to PhyControl=%08x\n", PhyControl.all); KdRegisters->PhyControl.all = PhyControl.all; retry = MAX_REGISTER_READS; do { PhyControl.all = KdRegisters->PhyControl.all; } while (PhyControl.WrReg && --retry); if (retry == 0) { kdprintf("1394: Hard reset on bus failed\n"); return false; } kdprintf("1394: Init Succeeded\n"); return true; } static void Dbg1394_EnablePhysicalAccess() { // see if ohci1394 is being loaded... HC_CONTROL_REGISTER HCControl; HCControl.all = KdRegisters->HCControlSet.all; if (!HCControl.LinkEnable || !HCControl.Lps || HCControl.SoftReset) { KDDBG("1394: EnablePhysicalAccess HCControl=%08x!\n", HCControl.all); return; } // if the bus reset interrupt is not cleared, we have to clear it... INT_EVENT_MASK_REGISTER IntEvent; IntEvent.all = KdRegisters->IntEventSet.all; if (IntEvent.BusReset) { KDDBG("1394: EnablePhysicalAccess IntEvent =%08x!\n", IntEvent.all); IntEvent.all = 0; IntEvent.BusReset = 1; KdRegisters->IntEventClear.all = IntEvent.all; } // we might need to re-enable physical access. If so, do it. KdRegisters->AsynchReqFilterHiSet = 0xFFFFFFFF; KdRegisters->AsynchReqFilterLoSet = 0xFFFFFFFF; KdRegisters->PhyReqFilterHiSet = 0xFFFFFFFF; KdRegisters->PhyReqFilterLoSet = 0xFFFFFFFF; } static KDP_STATUS Dbg1394_ReadPacket( OUT PKD_PACKET PacketHeader, OUT PSTRING MessageHeader, OUT PSTRING MessageData, bool Wait ) // KDP_PACKET_RESEND - if resend is required. = 2 = CP_GET_ERROR // KDP_PACKET_TIMEOUT - if timeout. = 1 = CP_GET_NODATA // KDP_PACKET_RECEIVED - if packet received. = 0 = CP_GET_SUCCESS { UINT32 timeoutLimit = 0; do { // make sure our link is enabled.. Dbg1394_EnablePhysicalAccess(); KdpSpin(); if (Kd1394Data->ReceivePacket.TransferStatus == STATUS_PENDING) { KdDebuggerNotPresent = false; memcpy(PacketHeader, &Kd1394Data->ReceivePacket.Packet[0], sizeof(KD_PACKET)); // make sure we have a valid PacketHeader if (Kd1394Data->ReceivePacket.Length < sizeof(KD_PACKET)) { // short packet, we are done... Kd1394Data->ReceivePacket.TransferStatus = STATUS_SUCCESS; return(KDP_PACKET_RESEND); } if (MessageHeader) { memcpy(MessageHeader->Buffer, &Kd1394Data->ReceivePacket.Packet[sizeof(KD_PACKET)], MessageHeader->MaximumLength); if (Kd1394Data->ReceivePacket.Length <= (UINT16)(sizeof(KD_PACKET)+MessageHeader->MaximumLength)) { Kd1394Data->ReceivePacket.TransferStatus = STATUS_SUCCESS; return(KDP_PACKET_RECEIVED); } if (MessageData) { memcpy(MessageData->Buffer, &Kd1394Data->ReceivePacket.Packet[sizeof(KD_PACKET) + MessageHeader->MaximumLength], Kd1394Data->ReceivePacket.Length - (sizeof(KD_PACKET) + MessageHeader->MaximumLength)); } } Kd1394Data->ReceivePacket.TransferStatus = STATUS_SUCCESS; return(KDP_PACKET_RECEIVED); } timeoutLimit++; if (Wait == false) { return(KDP_PACKET_RESEND); } } while (timeoutLimit <= TIMEOUT_COUNT); return(KDP_PACKET_TIMEOUT); } // // Send a control packet to the host machine that is running the // kernel debugger and wait for an ACK. // // PacketType - Supplies the type of packet to send. // static void KdpSendControlPacket(IN UINT16 PacketType) { KD_PACKET PacketHeader; // // Initialize and send the packet header. // PacketHeader.PacketLeader = CONTROL_PACKET_LEADER; PacketHeader.PacketId = 0; PacketHeader.ByteCount = 0; PacketHeader.Checksum = 0; PacketHeader.PacketType = PacketType; // setup our send packet memset(&Kd1394Data->SendPacket, 0, sizeof(DEBUG_1394_SEND_PACKET)); Kd1394Data->SendPacket.Length = 0; memcpy(&Kd1394Data->SendPacket.PacketHeader[0], &PacketHeader, sizeof(KD_PACKET)); Kd1394Data->SendPacket.TransferStatus = STATUS_PENDING; } KDP_STATUS Kdp1394ReceivePacket( IN UINT32 PacketType, OUT PSTRING MessageHeader, OUT PSTRING MessageData, OUT UINT32 * DataLength, IN OUT PKD_CONTEXT KdContext ) // 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 KdPrintString, 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. // KdContext - Supplies a pointer to the kernel debugger context. // // Return Value: // KDP_PACKET_RESEND - if resend is required. = 2 = CP_GET_ERROR // KDP_PACKET_TIMEOUT - if timeout. = 1 = CP_GET_NODATA // KDP_PACKET_RECEIVED - if packet received. = 0 = CP_GET_SUCCESS { UINT32 MessageLength; KD_PACKET PacketHeader; KDP_STATUS ReturnCode; UINT32 Checksum; KDDBG2("Kdp1394ReceivePacket\n"); // this dispatch gets called with PacketType != PACKET_TYPE_KD_POLL_BREAKIN for // the number of times specified in KdCompNumberRetries (??). WaitForPacketLeader: // read in our packet, if available... ReturnCode = Dbg1394_ReadPacket(&PacketHeader, MessageHeader, MessageData, true); // // If we can successfully read packet leader, it has high possibility that // kernel debugger is alive. So reset count. // if (ReturnCode != KDP_PACKET_TIMEOUT) { KdCompNumberRetries = KdCompRetryCount; } if (ReturnCode != KDP_PACKET_RECEIVED) { // see if it's a breakin packet... if ((PacketHeader.PacketLeader & 0xFF) == BREAKIN_PACKET_BYTE) { KdContext->KdpControlCPending = true; return(KDP_PACKET_RESEND); } return(ReturnCode); } // // 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(KDP_PACKET_RESEND); } // // 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; MessageData->Length = (UINT16)*DataLength; MessageHeader->Length = (UINT16)MessageLength; // // Check PacketType is what we are waiting for. // if (PacketType != PacketHeader.PacketType) { goto SendResendPacket; } // // Check checksum is valid. // Checksum = KdpComputeChecksum(MessageHeader->Buffer, MessageHeader->Length); Checksum += KdpComputeChecksum(MessageData->Buffer, MessageData->Length); if (Checksum != PacketHeader.Checksum) { goto SendResendPacket; } return(KDP_PACKET_RECEIVED); SendResendPacket: KdpSendControlPacket(PACKET_TYPE_KD_RESEND); goto WaitForPacketLeader; } void Kdp1394SendPacket( IN UINT32 PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData OPTIONAL, IN OUT PKD_CONTEXT KdContext ) // 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. // KdContext - Supplies a pointer to the kernel debugger context. // // Return Value: // None. { KD_PACKET PacketHeader; UINT32 MessageDataLength; UINT32 ReturnCode; bool bException = false; KDDBG2("Kdp1394SendPacket\n"); PacketHeader.Checksum = 0; if (MessageData != NULL) { MessageDataLength = MessageData->Length; PacketHeader.Checksum = KdpComputeChecksum(MessageData->Buffer, MessageData->Length); } else { MessageDataLength = 0; PacketHeader.Checksum = 0; } PacketHeader.Checksum += KdpComputeChecksum(MessageHeader->Buffer, MessageHeader->Length); // // Initialize and send the packet header. // PacketHeader.PacketLeader = PACKET_LEADER; PacketHeader.ByteCount = (UINT16)(MessageHeader->Length + MessageDataLength); PacketHeader.PacketType = (UINT16)PacketType; PacketHeader.PacketId = KdPacketId; KdPacketId++; KdCompNumberRetries = KdCompRetryCount; // setup our send packet memset(&Kd1394Data->SendPacket, 0, sizeof(DEBUG_1394_SEND_PACKET)); Kd1394Data->SendPacket.Length = 0; // copy our packet header... memcpy(&Kd1394Data->SendPacket.PacketHeader[0], &PacketHeader, sizeof(KD_PACKET)); // setup our message header if (MessageHeader) { memcpy(&Kd1394Data->SendPacket.Packet[0], MessageHeader->Buffer, MessageHeader->Length); Kd1394Data->SendPacket.Length += MessageHeader->Length; } // setup our message data if (MessageData != NULL) { memcpy(&Kd1394Data->SendPacket.Packet[Kd1394Data->SendPacket.Length], MessageData->Buffer, MessageData->Length); Kd1394Data->SendPacket.Length += MessageData->Length; } Kd1394Data->SendPacket.TransferStatus = STATUS_PENDING; // // We sync on first STATE_CHANGE64 message like NT. If this // is the first such message, drain receive pipe as nothing // said before this instant is interesting (and any buffered // packets may interact badly with SendWaitContinue). // if (PacketType == PACKET_TYPE_KD_STATE_CHANGE64 /* && !KdStateChange64Sent*/) { // need to do this to fix pre-logging (eventually). #if 0 UCHAR uDummy; uint32 dwDrained = 0; KdCompNextPacketIdToSend |= SYNC_PACKET_ID; KdStateChange64Sent = true; while (KdCompGetByte(&uDummy) == CP_GET_SUCCESS) { dwDrained++; } #endif // 0 } do { KDDBG2("LOOP %d/%d [SendPacket=%p %08x %08x %08x %02x %02x %02x %02x]\n", KdCompNumberRetries, KdCompRetryCount, &Kd1394Data->SendPacket, Kd1394Data->SendPacket.TransferStatus, *(UINT32*)&Kd1394Data->SendPacket.PacketHeader, Kd1394Data->SendPacket.Length, Kd1394Data->SendPacket.Packet[0], Kd1394Data->SendPacket.Packet[1], Kd1394Data->SendPacket.Packet[2], Kd1394Data->SendPacket.Packet[3]); // make sure our link is enabled.. Dbg1394_EnablePhysicalAccess(); if (KdCompNumberRetries == 0) { // // If the packet is not for reporting exception, we give up // and declare debugger not present. // if (PacketType == PACKET_TYPE_KD_DEBUG_IO) { PDBGKD_DEBUG_IO DebugIo = (PDBGKD_DEBUG_IO)MessageHeader->Buffer; if (DebugIo->ApiNumber == DbgKdPrintStringApi) { KdDebuggerNotPresent = true; Kd1394Data->SendPacket.TransferStatus = STATUS_SUCCESS; return; } } else if (PacketType == PACKET_TYPE_KD_STATE_CHANGE64) { PDBGKD_ANY_WAIT_STATE_CHANGE StateChange = (PDBGKD_ANY_WAIT_STATE_CHANGE)MessageHeader->Buffer; if (StateChange->NewState == DbgKdLoadSymbolsStateChange) { KdDebuggerNotPresent = true; Kd1394Data->SendPacket.TransferStatus = STATUS_SUCCESS; return; } } else if (PacketType == PACKET_TYPE_KD_FILE_IO) { PDBGKD_FILE_IO FileIo = (PDBGKD_FILE_IO)MessageHeader->Buffer; if (FileIo->ApiNumber == DbgKdCreateFileApi) { KdDebuggerNotPresent = true; Kd1394Data->SendPacket.TransferStatus = STATUS_SUCCESS; return; } } else { bException = true; } } ReturnCode = KDP_PACKET_TIMEOUT; { UINT32 count = 0; volatile NTSTATUS *pStatus; pStatus = &Kd1394Data->ReceivePacket.TransferStatus; // // now sit here and poll for a response from the host machine // do { // make sure our link is enabled.. Dbg1394_EnablePhysicalAccess(); KdpSpin(); // // while in this loop check if the host has submitted a new request. // If they did, abort processing of the current request. // count++; if (Kd1394Data->SendPacket.TransferStatus != STATUS_PENDING) { ReturnCode = KDP_PACKET_RECEIVED; break; } if ((*pStatus == STATUS_PENDING) && (!bException)) { ReturnCode = KDP_PACKET_RECEIVED; break; } } while (count < TIMEOUT_COUNT); } if (ReturnCode == KDP_PACKET_TIMEOUT) { KdCompNumberRetries--; } } while (ReturnCode != KDP_PACKET_RECEIVED); // // Since we are able to talk to debugger, the retrycount is set to // maximum value. // KdCompRetryCount = KdContext->KdpDefaultRetries; } // Returns true if a breakin packet is pending. // A packet is present if: There is a valid character which matches BREAK_CHAR. bool Kdp1394PollBreakIn(void) { KDDBG2("Kdp1394PollBreakIn\n"); // make sure our link is enabled.. Dbg1394_EnablePhysicalAccess(); // let's peak into our receive packet and see if it's a breakin if ((Kd1394Data->ReceivePacket.TransferStatus == STATUS_PENDING) && (Kd1394Data->ReceivePacket.Packet[0] == BREAKIN_PACKET_BYTE)) { KdDebuggerNotPresent = false; // we have a breakin packet Kd1394Data->ReceivePacket.TransferStatus = STATUS_SUCCESS; return true; } return false; } // ///////////////////////////////////////////////////////////////// End of File.