Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

kdcomio.c File Reference

#include "kdp.h"

Go to the source code of this file.

Functions

ULONG KdpComputeChecksum (IN PUCHAR Buffer, IN ULONG Length)
ULONG KdpReceiveString (OUT PCHAR Destination, IN ULONG Length)
VOID KdpSendString (IN PCHAR Source, IN ULONG Length)
VOID KdpSendControlPacket (IN USHORT PacketType, IN ULONG PacketId OPTIONAL)
USHORT KdpReceivePacketLeader (IN ULONG PacketType, OUT PULONG PacketLeader)
ULONG KdpReceivePacket (IN ULONG PacketType, OUT PSTRING MessageHeader, OUT PSTRING MessageData, OUT PULONG DataLength)
VOID KdpSendPacket (IN ULONG PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData OPTIONAL)


Function Documentation

ULONG KdpComputeChecksum IN PUCHAR  Buffer,
IN ULONG  Length
 

Referenced by KdpReceivePacket(), and KdpSendPacket().

ULONG KdpReceivePacket IN ULONG  PacketType,
OUT PSTRING  MessageHeader,
OUT PSTRING  MessageData,
OUT PULONG  DataLength
 

Definition at line 343 of file 4/kdcomio.c.

References CP_GET_ERROR, CP_GET_NODATA, CP_GET_SUCCESS, KDP_PACKET_RECEIVED, KDP_PACKET_RESEND, KDP_PACKET_TIMEOUT, KdpComputeChecksum(), KdpNextPacketIdToSend, KdpNumberRetries, KdPortGetByte(), KdpPacketIdExpected, KdpReceivePacketLeader(), KdpReceiveString(), KdpRetryCount, KdpSendControlPacket(), L, and USHORT.

Referenced by KdpPromptString(), KdpSendPacket(), and KdpSendWaitContinue().

00352 : 00353 00354 This routine receives a packet from the host machine that is running 00355 the kernel debugger UI. This routine is ALWAYS called after packet being 00356 sent by caller. It first waits for ACK packet for the packet sent and 00357 then waits for the packet desired. 00358 00359 N.B. If caller is KdPrintString, the parameter PacketType is 00360 PACKET_TYPE_KD_ACKNOWLEDGE. In this case, this routine will return 00361 right after the ack packet is received. 00362 00363 Arguments: 00364 00365 PacketType - Supplies the type of packet that is excepted. 00366 00367 MessageHeader - Supplies a pointer to a string descriptor for the input 00368 message. 00369 00370 MessageData - Supplies a pointer to a string descriptor for the input data. 00371 00372 DataLength - Supplies pointer to ULONG to receive length of recv. data. 00373 00374 Return Value: 00375 00376 KDP_PACKET_RESEND - if resend is required. 00377 KDP_PAKCET_TIMEOUT - if timeout. 00378 KDP_PACKET_RECEIVED - if packet received. 00379 00380 --*/ 00381 00382 { 00383 00384 UCHAR Input; 00385 ULONG MessageLength; 00386 KD_PACKET PacketHeader; 00387 ULONG ReturnCode; 00388 ULONG Checksum; 00389 00390 WaitForPacketLeader: 00391 00392 // 00393 // Read Packet Leader 00394 // 00395 00396 ReturnCode = KdpReceivePacketLeader(PacketType, &PacketHeader.PacketLeader); 00397 00398 // 00399 // If we can successfully read packet leader, it has high possibility that 00400 // kernel debugger is alive. So reset count. 00401 // 00402 00403 if (ReturnCode != KDP_PACKET_TIMEOUT) { 00404 KdpNumberRetries = KdpRetryCount; 00405 } 00406 if (ReturnCode != KDP_PACKET_RECEIVED) { 00407 return ReturnCode; 00408 } 00409 00410 // 00411 // Read packet type. 00412 // 00413 00414 ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.PacketType, 00415 sizeof(PacketHeader.PacketType)); 00416 if (ReturnCode == CP_GET_NODATA) { 00417 return KDP_PACKET_TIMEOUT; 00418 } else if (ReturnCode == CP_GET_ERROR) { 00419 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { 00420 00421 // 00422 // If read error and it is for a control packet, simply 00423 // preptend that we have not seen this packet. Hopefully 00424 // we will receive the packet we desire which automatically acks 00425 // the packet we just sent. 00426 // 00427 00428 goto WaitForPacketLeader; 00429 } else { 00430 00431 // 00432 // if read error while reading data packet, we have to ask 00433 // kernel debugger to resend us the packet. 00434 // 00435 00436 goto SendResendPacket; 00437 } 00438 } 00439 00440 // 00441 // if the packet we received is a resend request, we return true and 00442 // let caller resend the packet. 00443 // 00444 00445 if ( PacketHeader.PacketLeader == CONTROL_PACKET_LEADER && 00446 PacketHeader.PacketType == PACKET_TYPE_KD_RESEND ) { 00447 return KDP_PACKET_RESEND; 00448 } 00449 00450 // 00451 // Read data length. 00452 // 00453 00454 ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.ByteCount, 00455 sizeof(PacketHeader.ByteCount)); 00456 if (ReturnCode == CP_GET_NODATA) { 00457 return KDP_PACKET_TIMEOUT; 00458 } else if (ReturnCode == CP_GET_ERROR) { 00459 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { 00460 goto WaitForPacketLeader; 00461 } else { 00462 goto SendResendPacket; 00463 } 00464 } 00465 00466 // 00467 // Read Packet Id. 00468 // 00469 00470 ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.PacketId, 00471 sizeof(PacketHeader.PacketId)); 00472 00473 if (ReturnCode == CP_GET_NODATA) { 00474 return KDP_PACKET_TIMEOUT; 00475 } else if (ReturnCode == CP_GET_ERROR) { 00476 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { 00477 goto WaitForPacketLeader; 00478 } else { 00479 goto SendResendPacket; 00480 } 00481 } 00482 00483 // 00484 // Read packet checksum. 00485 // 00486 00487 ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.Checksum, 00488 sizeof(PacketHeader.Checksum)); 00489 if (ReturnCode == CP_GET_NODATA) { 00490 return KDP_PACKET_TIMEOUT; 00491 } else if (ReturnCode == CP_GET_ERROR) { 00492 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { 00493 goto WaitForPacketLeader; 00494 } else { 00495 goto SendResendPacket; 00496 } 00497 } 00498 00499 // 00500 // A complete packet header is received. Check its validity and 00501 // perform appropriate action depending on packet type. 00502 // 00503 00504 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER ) { 00505 if (PacketHeader.PacketType == PACKET_TYPE_KD_ACKNOWLEDGE ) { 00506 00507 // 00508 // If we received an expected ACK packet and we are not 00509 // waiting for any new packet, update outgoing packet id 00510 // and return. If we are NOT waiting for ACK packet 00511 // we will keep on waiting. If the ACK packet 00512 // is not for the packet we send, ignore it and keep on waiting. 00513 // 00514 00515 if (PacketHeader.PacketId != 00516 (KdpNextPacketIdToSend & ~SYNC_PACKET_ID)) { 00517 goto WaitForPacketLeader; 00518 } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) { 00519 KdpNextPacketIdToSend ^= 1; 00520 return KDP_PACKET_RECEIVED; 00521 } else { 00522 goto WaitForPacketLeader; 00523 } 00524 } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESET) { 00525 00526 // 00527 // if we received Reset packet, reset the packet control variables 00528 // and resend earlier packet. 00529 // 00530 00531 KdpNextPacketIdToSend = INITIAL_PACKET_ID; 00532 KdpPacketIdExpected = INITIAL_PACKET_ID; 00533 KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0L); 00534 return KDP_PACKET_RESEND; 00535 } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESEND) { 00536 return KDP_PACKET_RESEND; 00537 } else { 00538 00539 // 00540 // Invalid packet header, ignore it. 00541 // 00542 00543 goto WaitForPacketLeader; 00544 } 00545 00546 // 00547 // The packet header is for data packet (not control packet). 00548 // 00549 00550 } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) { 00551 00552 // 00553 // if we are waiting for ACK packet ONLY 00554 // and we receive a data packet header, check if the packet id 00555 // is what we expected. If yes, assume the acknowledge is lost (but 00556 // sent), ask sender to resend and return with PACKET_RECEIVED. 00557 // 00558 00559 if (PacketHeader.PacketId == KdpPacketIdExpected) { 00560 KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0L); 00561 KdpNextPacketIdToSend ^= 1; 00562 return KDP_PACKET_RECEIVED; 00563 } else { 00564 KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, 00565 PacketHeader.PacketId 00566 ); 00567 goto WaitForPacketLeader; 00568 } 00569 } 00570 00571 // 00572 // we are waiting for data packet and we received the packet header 00573 // for data packet. Perform the following checkings to make sure 00574 // it is the packet we are waiting for. 00575 // 00576 00577 // 00578 // Check ByteCount received is valid 00579 // 00580 00581 MessageLength = MessageHeader->MaximumLength; 00582 if ((PacketHeader.ByteCount > (USHORT)PACKET_MAX_SIZE) || 00583 (PacketHeader.ByteCount < (USHORT)MessageLength)) { 00584 goto SendResendPacket; 00585 } 00586 *DataLength = PacketHeader.ByteCount - MessageLength; 00587 00588 // 00589 // Read the message header. 00590 // 00591 00592 ReturnCode = KdpReceiveString(MessageHeader->Buffer, MessageLength); 00593 if (ReturnCode != CP_GET_SUCCESS) { 00594 goto SendResendPacket; 00595 } 00596 MessageHeader->Length = (USHORT)MessageLength; 00597 00598 // 00599 // Read the message data. 00600 // 00601 00602 ReturnCode = KdpReceiveString(MessageData->Buffer, *DataLength); 00603 if (ReturnCode != CP_GET_SUCCESS) { 00604 goto SendResendPacket; 00605 } 00606 MessageData->Length = (USHORT)*DataLength; 00607 00608 // 00609 // Read packet trailing byte 00610 // 00611 00612 ReturnCode = KdPortGetByte(&Input); 00613 if (ReturnCode != CP_GET_SUCCESS || Input != PACKET_TRAILING_BYTE) { 00614 goto SendResendPacket; 00615 } 00616 00617 // 00618 // Check PacketType is what we are waiting for. 00619 // 00620 00621 if (PacketType != PacketHeader.PacketType) { 00622 KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, 00623 PacketHeader.PacketId 00624 ); 00625 goto WaitForPacketLeader; 00626 } 00627 00628 // 00629 // Check PacketId is valid. 00630 // 00631 00632 if (PacketHeader.PacketId == INITIAL_PACKET_ID || 00633 PacketHeader.PacketId == (INITIAL_PACKET_ID ^ 1)) { 00634 if (PacketHeader.PacketId != KdpPacketIdExpected) { 00635 KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, 00636 PacketHeader.PacketId 00637 ); 00638 goto WaitForPacketLeader; 00639 } 00640 } else { 00641 goto SendResendPacket; 00642 } 00643 00644 // 00645 // Check checksum is valid. 00646 // 00647 00648 Checksum = KdpComputeChecksum( 00649 MessageHeader->Buffer, 00650 MessageHeader->Length 00651 ); 00652 00653 Checksum += KdpComputeChecksum( 00654 MessageData->Buffer, 00655 MessageData->Length 00656 ); 00657 if (Checksum != PacketHeader.Checksum) { 00658 goto SendResendPacket; 00659 } 00660 00661 // 00662 // Send Acknowledge byte and the Id of the packet received. 00663 // Then, update the ExpectId for next incoming packet. 00664 // 00665 00666 KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, 00667 PacketHeader.PacketId 00668 ); 00669 00670 // 00671 // We have successfully received the packet so update the 00672 // packet control variables and return sucess. 00673 // 00674 00675 KdpPacketIdExpected ^= 1; 00676 return KDP_PACKET_RECEIVED; 00677 00678 SendResendPacket: 00679 KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0L); 00680 goto WaitForPacketLeader; 00681 }

USHORT KdpReceivePacketLeader IN ULONG  PacketType,
OUT PULONG  PacketLeader
 

Definition at line 95 of file 4/kdcomio.c.

References CP_GET_ERROR, CP_GET_NODATA, FALSE, Index, KdDebuggerNotPresent, KDP_PACKET_RECEIVED, KDP_PACKET_RESEND, KDP_PACKET_TIMEOUT, KdpControlCPending, KdPortGetByte(), and TRUE.

Referenced by KdpReceivePacket().

00102 : 00103 00104 This routine waits for a packet header leader. 00105 00106 Arguments: 00107 00108 PacketType - supplies the type of packet we are expecting. 00109 00110 PacketLeader - supplies a pointer to a ulong variable to receive 00111 packet leader bytes. 00112 00113 Return Value: 00114 00115 KDP_PACKET_RESEND - if resend is required. 00116 KDP_PAKCET_TIMEOUT - if timeout. 00117 KDP_PACKET_RECEIVED - if packet received. 00118 00119 --*/ 00120 00121 { 00122 00123 UCHAR Input, PreviousByte = 0; 00124 ULONG PacketId = 0; 00125 ULONG Index; 00126 ULONG ReturnCode; 00127 BOOLEAN BreakinDetected = FALSE; 00128 00129 // 00130 // NOTE - With all the interrupts being off, it is very hard 00131 // to implement the actual timeout code. (Maybe, by reading the CMOS.) 00132 // Here we use a loop count to wait about 3 seconds. The CpGetByte 00133 // will return with error code = CP_GET_NODATA if it cannot find data 00134 // byte within 1 second. Kernel debugger's timeout period is 5 seconds. 00135 // 00136 00137 Index = 0; 00138 do { 00139 ReturnCode = KdPortGetByte(&Input); 00140 if (ReturnCode == CP_GET_NODATA) { 00141 if (BreakinDetected) { 00142 KdpControlCPending = TRUE; 00143 return KDP_PACKET_RESEND; 00144 } else { 00145 return KDP_PACKET_TIMEOUT; 00146 } 00147 } else if (ReturnCode == CP_GET_ERROR) { 00148 Index = 0; 00149 continue; 00150 } else { // if (ReturnCode == CP_GET_SUCCESS) 00151 if ( Input == PACKET_LEADER_BYTE || 00152 Input == CONTROL_PACKET_LEADER_BYTE ) { 00153 if ( Index == 0 ) { 00154 PreviousByte = Input; 00155 Index++; 00156 } else if (Input == PreviousByte ) { 00157 Index++; 00158 } else { 00159 PreviousByte = Input; 00160 Index = 1; 00161 } 00162 } else { 00163 00164 // 00165 // If we detect breakin character, we need to verify it 00166 // validity. (It is possible that we missed a packet leader 00167 // and the breakin character is simply a data byte in the 00168 // packet.) 00169 // Since kernel debugger send out breakin character ONLY 00170 // when it is waiting for State Change packet. The breakin 00171 // character should not be followed by any other character 00172 // except packet leader byte. 00173 // 00174 00175 if ( Input == BREAKIN_PACKET_BYTE ) { 00176 BreakinDetected = TRUE; 00177 } else { 00178 00179 // 00180 // The following statement is ABSOLUTELY necessary. 00181 // 00182 00183 BreakinDetected = FALSE; 00184 } 00185 Index = 0; 00186 } 00187 } 00188 } while ( Index < 4 ); 00189 00190 if (BreakinDetected) { 00191 KdpControlCPending = TRUE; 00192 } 00193 00194 // 00195 // return the packet leader and FALSE to indicate no resend is needed. 00196 // 00197 00198 if ( Input == PACKET_LEADER_BYTE ) { 00199 *PacketLeader = PACKET_LEADER; 00200 } else { 00201 *PacketLeader = CONTROL_PACKET_LEADER; 00202 } 00203 00204 KdDebuggerNotPresent = FALSE; 00205 SharedUserData->KdDebuggerEnabled |= 0x00000002; 00206 return KDP_PACKET_RECEIVED; 00207 }

ULONG KdpReceiveString OUT PCHAR  Destination,
IN ULONG  Length
 

Referenced by KdpReceivePacket().

VOID KdpSendControlPacket IN USHORT  PacketType,
IN ULONG PacketId  OPTIONAL
 

Referenced by KdpReceivePacket().

VOID KdpSendPacket IN ULONG  PacketType,
IN PSTRING  MessageHeader,
IN PSTRING MessageData  OPTIONAL
 

Definition at line 684 of file 4/kdcomio.c.

References KdDebuggerNotPresent, KDP_PACKET_RECEIVED, KDP_PACKET_TIMEOUT, KdpComputeChecksum(), KdpDefaultRetries, KdpNextPacketIdToSend, KdpNumberRetries, KdPortPutByte(), KdpPacketIdExpected, KdpReceivePacket(), KdpRetryCount, KdpSendString(), MAXIMUM_RETRIES, NULL, TRUE, and USHORT.

Referenced by KdpCheckLowMemory(), KdpGetBusData(), KdpGetContext(), KdpGetVersion(), KdpNotSupported(), KdpPrintString(), KdpPromptString(), KdpReadControlSpace(), KdpReadIoSpace(), KdpReadIoSpaceExtended(), KdpReadMachineSpecificRegister(), KdpReadPhysicalMemory(), KdpReadVirtualMemory(), KdpReadVirtualMemory64(), KdpRestoreBreakpoint(), KdpRestoreBreakPointEx(), KdpSearchMemory(), KdpSendWaitContinue(), KdpSetBusData(), KdpSetContext(), KdpWriteBreakpoint(), KdpWriteBreakPointEx(), KdpWriteControlSpace(), KdpWriteIoSpace(), KdpWriteIoSpaceExtended(), KdpWriteMachineSpecificRegister(), KdpWritePhysicalMemory(), KdpWriteVirtualMemory(), and KdpWriteVirtualMemory64().

00692 : 00693 00694 This routine sends a packet to the host machine that is running the 00695 kernel debugger and waits for an ACK. 00696 00697 Arguments: 00698 00699 PacketType - Supplies the type of packet to send. 00700 00701 MessageHeader - Supplies a pointer to a string descriptor that describes 00702 the message information. 00703 00704 MessageData - Supplies a pointer to a string descriptor that describes 00705 the optional message data. 00706 00707 Return Value: 00708 00709 None. 00710 00711 --*/ 00712 00713 { 00714 00715 KD_PACKET PacketHeader; 00716 ULONG MessageDataLength; 00717 ULONG ReturnCode; 00718 PDBGKD_DEBUG_IO DebugIo; 00719 PDBGKD_WAIT_STATE_CHANGE64 StateChange; 00720 00721 if ( ARGUMENT_PRESENT(MessageData) ) { 00722 MessageDataLength = MessageData->Length; 00723 PacketHeader.Checksum = KdpComputeChecksum( 00724 MessageData->Buffer, 00725 MessageData->Length 00726 ); 00727 } else { 00728 MessageDataLength = 0; 00729 PacketHeader.Checksum = 0; 00730 } 00731 00732 PacketHeader.Checksum += KdpComputeChecksum ( 00733 MessageHeader->Buffer, 00734 MessageHeader->Length 00735 ); 00736 00737 // 00738 // Initialize and send the packet header. 00739 // 00740 00741 PacketHeader.PacketLeader = PACKET_LEADER; 00742 PacketHeader.ByteCount = (USHORT)(MessageHeader->Length + MessageDataLength); 00743 PacketHeader.PacketType = (USHORT)PacketType; 00744 KdpNumberRetries = KdpRetryCount; 00745 do { 00746 if (KdpNumberRetries == 0) { 00747 00748 // 00749 // If the packet is not for reporting exception, we give up 00750 // and declare debugger not present. 00751 // 00752 00753 if (PacketType == PACKET_TYPE_KD_DEBUG_IO) { 00754 DebugIo = (PDBGKD_DEBUG_IO)MessageHeader->Buffer; 00755 if (DebugIo->ApiNumber == DbgKdPrintStringApi) { 00756 KdDebuggerNotPresent = TRUE; 00757 SharedUserData->KdDebuggerEnabled &= ~0x00000002; 00758 KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID; 00759 KdpPacketIdExpected = INITIAL_PACKET_ID; 00760 return; 00761 } 00762 } else if (PacketType == PACKET_TYPE_KD_STATE_CHANGE64) { 00763 StateChange = (PDBGKD_WAIT_STATE_CHANGE64)MessageHeader->Buffer; 00764 if (StateChange->NewState == DbgKdLoadSymbolsStateChange) { 00765 KdDebuggerNotPresent = TRUE; 00766 SharedUserData->KdDebuggerEnabled &= ~0x00000002; 00767 KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID; 00768 KdpPacketIdExpected = INITIAL_PACKET_ID; 00769 return; 00770 } 00771 } 00772 } 00773 00774 // 00775 // Setting PacketId has to be in the do loop in case Packet Id was 00776 // reset. 00777 // 00778 00779 PacketHeader.PacketId = KdpNextPacketIdToSend; 00780 KdpSendString((PCHAR)&PacketHeader, sizeof(KD_PACKET)); 00781 00782 // 00783 // Output message header. 00784 // 00785 00786 KdpSendString(MessageHeader->Buffer, MessageHeader->Length); 00787 00788 // 00789 // Output message data. 00790 // 00791 00792 if ( MessageDataLength ) { 00793 KdpSendString(MessageData->Buffer, MessageData->Length); 00794 } 00795 00796 // 00797 // Output a packet trailing byte 00798 // 00799 00800 KdPortPutByte(PACKET_TRAILING_BYTE); 00801 00802 // 00803 // Wait for the Ack Packet 00804 // 00805 00806 ReturnCode = KdpReceivePacket( 00807 PACKET_TYPE_KD_ACKNOWLEDGE, 00808 NULL, 00809 NULL, 00810 NULL 00811 ); 00812 if (ReturnCode == KDP_PACKET_TIMEOUT) { 00813 KdpNumberRetries--; 00814 } 00815 } while (ReturnCode != KDP_PACKET_RECEIVED); 00816 00817 // 00818 // Reset Sync bit in packet id. The packet we sent may have Sync bit set 00819 // 00820 00821 KdpNextPacketIdToSend &= ~SYNC_PACKET_ID; 00822 00823 // 00824 // Since we are able to talk to debugger, the retrycount is set to 00825 // maximum value. 00826 // 00827 00828 KdpRetryCount = KdpDefaultRetries ; 00829 } }

VOID KdpSendString IN PCHAR  Source,
IN ULONG  Length
 

Referenced by KdpSendControlPacket(), and KdpSendPacket().


Generated on Sat May 15 19:44:25 2004 for test by doxygen 1.3.7