|
|
1.1 root 1:
2: #include "givit.h"
3:
4:
5: //
6: // These two globals are used to contain the values
7: // passed back from ClearCommError. They are trash
8: // because we really don't care what went wrong. We
9: // just want the debugger to go on.
10: //
11: DWORD TrashErr;
12: COMSTAT TrashStat;
13:
14: ULONG DbgKdpPacketExpected; // ID for expected incoming packet
15: ULONG DbgKdpNextPacketToSend; // ID for Next packet to send
16:
17: //
18: // ValidUnaccessedPacket is used to control if the DbgKdpPacket
19: // contains valid but unaccessed packet.
20: //
21:
22: BOOLEAN ValidUnaccessedPacket = FALSE;
23: UCHAR DbgKdpPacket[PACKET_MAX_SIZE];
24: KD_PACKET PacketHeader;
25:
26: #define CONTROL_C 3
27:
28:
29: extern BOOLEAN KdResync;
30:
31: //
32: // Private prototypes to allow printing error messages without tripping
33: // over the 'C' runtimes.
34: //
35:
36: VOID
37: StartupCtrlCHandler(
38: ULONG
39: );
40:
41: VOID
42: PrintErrorMessage(
43: IN PUCHAR Message,
44: IN USHORT Value1,
45: IN USHORT Value2,
46: IN USHORT Value3
47: );
48:
49: VOID
50: PrivateUstoa(
51: IN PUCHAR Buffer,
52: IN USHORT Value
53: );
54:
55: VOID
56: PutString(
57: IN PUCHAR Message
58: );
59:
60: UCHAR DbgKdpBreakinPacket[1] = {
61: BREAKIN_PACKET_BYTE
62: };
63:
64: UCHAR DbgKdpPacketTrailingByte[1] = {
65: PACKET_TRAILING_BYTE
66: };
67:
68: VOID
69: DbgKdpWriteControlPacket(
70: IN USHORT PacketType,
71: IN ULONG PacketId OPTIONAL
72: )
73:
74: /*++
75:
76: Routine Description:
77:
78: This function writes a control packet to target machine.
79:
80: N.B. a CONTROL Packet header is sent with the following information:
81: PacketLeader - indicates it's a control packet
82: PacketType - indicates the type of the control packet
83: ByteCount - aways zero to indicate no data following the header
84: PacketId - Valid ONLY for PACKET_TYPE_KD_ACKNOWLEDGE to indicate
85: which packet is acknowledged.
86:
87: Arguments:
88:
89: PacketType - Supplies the type of the control packet.
90:
91: PacketId - Supplies the PacketId. Used by Acknowledge packet only.
92:
93: Return Value:
94:
95: None.
96:
97: --*/
98: {
99:
100: DWORD BytesWritten;
101: BOOL rc;
102: KD_PACKET Packet;
103:
104: assert( PacketType < PACKET_TYPE_MAX );
105:
106: Packet.PacketLeader = CONTROL_PACKET_LEADER;
107: Packet.ByteCount = 0;
108: Packet.PacketType = PacketType;
109: if ( PacketId ) {
110: Packet.PacketId = PacketId;
111: }
112:
113: do {
114:
115: //
116: // Write the control packet header
117: //
118:
119: rc = WriteFile(
120: DbgKdpComPort,
121: &Packet,
122: sizeof(Packet),
123: &BytesWritten,
124: &WriteOverlapped
125: );
126:
127: if (!rc) {
128:
129: if (GetLastError() == ERROR_IO_PENDING) {
130:
131: rc = GetOverlappedResult(
132: DbgKdpComPort,
133: &WriteOverlapped,
134: &BytesWritten,
135: TRUE
136: );
137:
138: } else {
139:
140: //
141: // Device could be locked up. Clear it just in case.
142: //
143:
144: ClearCommError(
145: DbgKdpComPort,
146: &TrashErr,
147: &TrashStat
148: );
149:
150: }
151:
152: }
153:
154: } while ( (!rc) || BytesWritten != sizeof(Packet) );
155: }
156:
157: ULONG
158: DbgKdpComputeChecksum (
159: IN PUCHAR Buffer,
160: IN ULONG Length
161: )
162:
163: /*++
164:
165: Routine Description:
166:
167: This routine computes the checksum for the string passed in.
168:
169: Arguments:
170:
171: Buffer - Supplies a pointer to the string.
172:
173: Length - Supplies the length of the string.
174:
175: Return Value:
176:
177: A ULONG is return as the checksum for the input string.
178:
179: --*/
180:
181: {
182:
183: ULONG Checksum = 0;
184:
185: while (Length > 0) {
186: Checksum = Checksum + (ULONG)*Buffer++;
187: Length--;
188: }
189: return Checksum;
190: }
191:
192: VOID
193: DbgKdpSynchronizeTarget (
194: VOID
195: )
196:
197: /*++
198:
199: Routine Description:
200:
201: This routine keeps on sending reset packet to target until reset packet
202: is acknowledged by a reset packet from target.
203:
204: N.B. This routine is intended to be used by kernel debugger at startup
205: time (ONLY) to get packet control variables on both target and host
206: back in synchronization. Also, reset request will cause kernel to
207: reset its control variables AND resend us its previous packet (with
208: the new packet id).
209:
210: Arguments:
211:
212: None.
213:
214: Return Value:
215:
216: None.
217:
218: --*/
219:
220: {
221:
222: USHORT Index;
223: UCHAR DataByte, PreviousDataByte;
224: USHORT PacketType = 0;
225: ULONG TimeoutCount = 0;
226: COMMTIMEOUTS CommTimeouts;
227: COMMTIMEOUTS OldTimeouts;
228: DWORD BytesRead;
229: BOOL rc;
230:
231: //
232: // Get the old time out values and hold them.
233: // We then set a new total timeout value of
234: // five seconds on the read. (In millisecond intervals.
235: //
236:
237: GetCommTimeouts(
238: DbgKdpComPort,
239: &OldTimeouts
240: );
241:
242: CommTimeouts = OldTimeouts;
243: CommTimeouts.ReadIntervalTimeout = 0;
244: CommTimeouts.ReadTotalTimeoutMultiplier = 0;
245: CommTimeouts.ReadTotalTimeoutConstant = 500;
246:
247: SetCommTimeouts(
248: DbgKdpComPort,
249: &CommTimeouts
250: );
251:
252: while (TRUE) {
253: Timeout:
254: DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESET, 0L);
255:
256: //
257: // Read packet leader
258: //
259:
260: Index = 0;
261: do {
262:
263: //
264: // Check user input for control_c. If user types control_c,
265: // we will send a breakin packet to the target. Hopefully,
266: // target will send us a StateChange packet and
267: //
268:
269:
270: //
271: // if we don't get response from kernel in 3 seconds we
272: // will resend the reset packet if user does not type ctrl_c.
273: // Otherwise, we send breakin character and wait for data again.
274: //
275:
276: rc = ReadFile(
277: DbgKdpComPort,
278: &DataByte,
279: 1,
280: &BytesRead,
281: &ReadOverlapped
282: );
283:
284: if (!rc) {
285:
286: if (GetLastError() == ERROR_IO_PENDING) {
287:
288: rc = GetOverlappedResult(
289: DbgKdpComPort,
290: &ReadOverlapped,
291: &BytesRead,
292: TRUE
293: );
294:
295: } else {
296:
297: //
298: // Device could be locked up. Clear it just in case.
299: //
300:
301: ClearCommError(
302: DbgKdpComPort,
303: &TrashErr,
304: &TrashStat
305: );
306:
307: }
308:
309: }
310:
311: if ((!rc) || (BytesRead != 1)) {
312: TimeoutCount++;
313:
314: //
315: // if we have been waiting for 3 seconds, resend RESYNC packet
316: //
317:
318: if (TimeoutCount != 6) {
319: continue;
320: }
321: TimeoutCount = 0;
322: goto Timeout;
323: }
324:
325: if (rc && BytesRead == 1 &&
326: ( DataByte == PACKET_LEADER_BYTE ||
327: DataByte == CONTROL_PACKET_LEADER_BYTE)
328: ) {
329: if ( Index == 0 ) {
330: PreviousDataByte = DataByte;
331: Index++;
332: } else if ( DataByte == PreviousDataByte ) {
333: Index++;
334: } else {
335: PreviousDataByte = DataByte;
336: Index = 1;
337: }
338: } else {
339: Index = 0;
340: }
341: } while ( Index < 4 );
342:
343: if (DataByte == CONTROL_PACKET_LEADER_BYTE) {
344:
345: //
346: // Read 2 byte Packet type
347: //
348:
349: rc = ReadFile(
350: DbgKdpComPort,
351: &PacketType,
352: sizeof(PacketType),
353: &BytesRead,
354: &ReadOverlapped
355: );
356:
357: if (!rc) {
358:
359: if (GetLastError() == ERROR_IO_PENDING) {
360:
361: rc = GetOverlappedResult(
362: DbgKdpComPort,
363: &ReadOverlapped,
364: &BytesRead,
365: TRUE
366: );
367:
368: } else {
369:
370: //
371: // Device could be locked up. Clear it just in case.
372: //
373:
374: ClearCommError(
375: DbgKdpComPort,
376: &TrashErr,
377: &TrashStat
378: );
379:
380: }
381:
382: }
383:
384: if (rc && BytesRead == sizeof(PacketType) &&
385: PacketType == PACKET_TYPE_KD_RESET ) {
386: DbgKdpPacketExpected = INITIAL_PACKET_ID;
387: DbgKdpNextPacketToSend = INITIAL_PACKET_ID;
388: SetCommTimeouts(
389: DbgKdpComPort,
390: &OldTimeouts
391: );
392: return;
393: }
394: }
395:
396: //
397: // If we receive Data Packet leader, it means target has not
398: // receive our reset packet. So we loop back and send it again.
399: // N.B. We need to wait until target finishes sending the packet.
400: // Otherwise, we may be sending the reset packet while the target
401: // is sending the packet. This might cause target loss the reset
402: // packet.
403: //
404:
405: while (DataByte != PACKET_TRAILING_BYTE) {
406:
407: rc = ReadFile(
408: DbgKdpComPort,
409: &DataByte,
410: 1,
411: &BytesRead,
412: &ReadOverlapped
413: );
414:
415: if (!rc) {
416:
417: if (GetLastError() == ERROR_IO_PENDING) {
418:
419: rc = GetOverlappedResult(
420: DbgKdpComPort,
421: &ReadOverlapped,
422: &BytesRead,
423: TRUE
424: );
425:
426: } else {
427:
428: //
429: // Device could be locked up. Clear it just in case.
430: //
431:
432: ClearCommError(
433: DbgKdpComPort,
434: &TrashErr,
435: &TrashStat
436: );
437:
438: }
439:
440: }
441:
442: if (BytesRead != 1) {
443: break;
444: }
445: }
446: }
447: }
448:
449:
450: VOID
451: DbgKdSendBreakIn(
452: VOID
453: )
454:
455: /*++
456:
457: Routine Description:
458:
459: Send a breakin packet to the target, unless some other packet
460: is already being transmitted, in which case do nothing.
461:
462: --*/
463:
464: {
465: DWORD BytesWritten;
466: BOOL rc;
467:
468: do {
469: rc = WriteFile(
470: DbgKdpComPort,
471: &DbgKdpBreakinPacket[0],
472: sizeof(DbgKdpBreakinPacket),
473: &BytesWritten,
474: &WriteOverlapped
475: );
476:
477: if (!rc) {
478:
479: if (GetLastError() == ERROR_IO_PENDING) {
480:
481: rc = GetOverlappedResult(
482: DbgKdpComPort,
483: &WriteOverlapped,
484: &BytesWritten,
485: TRUE
486: );
487:
488: } else {
489:
490: //
491: // Device could be locked up. Clear it just in case.
492: //
493:
494: ClearCommError(
495: DbgKdpComPort,
496: &TrashErr,
497: &TrashStat
498: );
499:
500: }
501:
502: }
503:
504: } while ((!rc) || (BytesWritten != sizeof(DbgKdpBreakinPacket)));
505: }
506: VOID
507: DbgKdpWritePacket(
508: IN PVOID PacketData,
509: IN USHORT PacketDataLength,
510: IN USHORT PacketType,
511: IN PVOID MorePacketData OPTIONAL,
512: IN USHORT MorePacketDataLength OPTIONAL
513: )
514: {
515: DWORD BytesWritten;
516: BOOL rc;
517: KD_PACKET Packet;
518: USHORT TotalBytesToWrite;
519: BOOLEAN Received;
520:
521: assert( PacketType < PACKET_TYPE_MAX );
522: if ( MorePacketData ) {
523: TotalBytesToWrite = PacketDataLength + MorePacketDataLength;
524: Packet.Checksum = DbgKdpComputeChecksum(
525: MorePacketData,
526: MorePacketDataLength
527: );
528: }
529: else {
530: TotalBytesToWrite = PacketDataLength;
531: Packet.Checksum = 0;
532: }
533: Packet.Checksum += DbgKdpComputeChecksum(
534: PacketData,
535: PacketDataLength
536: );
537: Packet.PacketLeader = PACKET_LEADER;
538: Packet.ByteCount = TotalBytesToWrite;
539: Packet.PacketType = PacketType;
540: ResendPacket:
541: Packet.PacketId = DbgKdpNextPacketToSend;
542:
543: //
544: // Write the packet header
545: //
546:
547: rc = WriteFile(
548: DbgKdpComPort,
549: &Packet,
550: sizeof(Packet),
551: &BytesWritten,
552: &WriteOverlapped
553: );
554:
555: if (!rc) {
556:
557: if (GetLastError() == ERROR_IO_PENDING) {
558:
559: rc = GetOverlappedResult(
560: DbgKdpComPort,
561: &WriteOverlapped,
562: &BytesWritten,
563: TRUE
564: );
565:
566: } else {
567:
568: //
569: // Device could be locked up. Clear it just in case.
570: //
571:
572: ClearCommError(
573: DbgKdpComPort,
574: &TrashErr,
575: &TrashStat
576: );
577:
578: }
579:
580: }
581:
582: if ( (!rc) || BytesWritten != sizeof(Packet) ){
583:
584: //
585: // an error occured writing the header, so write it again
586: //
587:
588: goto ResendPacket;
589: }
590:
591: //
592: // Write the primary packet data
593: //
594:
595: rc = WriteFile(
596: DbgKdpComPort,
597: PacketData,
598: PacketDataLength,
599: &BytesWritten,
600: &WriteOverlapped
601: );
602:
603: if (!rc) {
604:
605: if (GetLastError() == ERROR_IO_PENDING) {
606:
607: rc = GetOverlappedResult(
608: DbgKdpComPort,
609: &WriteOverlapped,
610: &BytesWritten,
611: TRUE
612: );
613:
614: } else {
615:
616: //
617: // Device could be locked up. Clear it just in case.
618: //
619:
620: ClearCommError(
621: DbgKdpComPort,
622: &TrashErr,
623: &TrashStat
624: );
625:
626: }
627:
628: }
629:
630: if ( (!rc) || BytesWritten != PacketDataLength ){
631:
632: //
633: // an error occured writing the primary packet data,
634: // so write it again
635: //
636:
637: goto ResendPacket;
638: }
639:
640: //
641: // If secondary packet data was specified (WriteMemory, SetContext...)
642: // then write it as well.
643: //
644:
645: if ( MorePacketData ) {
646:
647: rc = WriteFile(
648: DbgKdpComPort,
649: MorePacketData,
650: MorePacketDataLength,
651: &BytesWritten,
652: &WriteOverlapped
653: );
654: if (!rc) {
655:
656: if (GetLastError() == ERROR_IO_PENDING) {
657:
658: rc = GetOverlappedResult(
659: DbgKdpComPort,
660: &WriteOverlapped,
661: &BytesWritten,
662: TRUE
663: );
664:
665: } else {
666:
667: //
668: // Device could be locked up. Clear it just in case.
669: //
670:
671: ClearCommError(
672: DbgKdpComPort,
673: &TrashErr,
674: &TrashStat
675: );
676:
677: }
678:
679: }
680:
681: if ( (!rc) || BytesWritten != MorePacketDataLength ){
682:
683: //
684: // an error occured writing the secondary packet data,
685: // so write it again
686: //
687:
688: goto ResendPacket;
689: }
690: }
691:
692: //
693: // Output a packet trailing byte
694: //
695:
696: do {
697: rc = WriteFile(
698: DbgKdpComPort,
699: &DbgKdpPacketTrailingByte[0],
700: sizeof(DbgKdpPacketTrailingByte),
701: &BytesWritten,
702: &WriteOverlapped
703: );
704:
705: if (!rc) {
706:
707: if (GetLastError() == ERROR_IO_PENDING) {
708:
709: rc = GetOverlappedResult(
710: DbgKdpComPort,
711: &WriteOverlapped,
712: &BytesWritten,
713: TRUE
714: );
715:
716: } else {
717:
718: //
719: // Device could be locked up. Clear it just in case.
720: //
721:
722: ClearCommError(
723: DbgKdpComPort,
724: &TrashErr,
725: &TrashStat
726: );
727:
728: }
729:
730: }
731:
732: } while ((!rc) || (BytesWritten != sizeof(DbgKdpPacketTrailingByte)));
733:
734: //
735: // Wait for ACK
736: //
737:
738: Received = DbgKdpWaitForPacket(
739: PACKET_TYPE_KD_ACKNOWLEDGE,
740: NULL
741: );
742:
743: if ( Received == FALSE ) {
744: goto ResendPacket;
745: }
746: }
747:
748: BOOLEAN
749: DbgKdpReadPacketLeader(
750: IN ULONG PacketType,
751: OUT PULONG PacketLeader
752: )
753: {
754: DWORD BytesRead;
755: BOOL rc;
756: USHORT Index;
757: UCHAR DataByte, PreviousDataByte;
758:
759: Index = 0;
760: do {
761: if (KdResync) {
762: KdResync = FALSE;
763: DbgKdpSynchronizeTarget();
764: }
765: rc = ReadFile(
766: DbgKdpComPort,
767: &DataByte,
768: 1,
769: &BytesRead,
770: &ReadOverlapped
771: );
772:
773: if (!rc) {
774:
775: if (GetLastError() == ERROR_IO_PENDING) {
776:
777: rc = GetOverlappedResult(
778: DbgKdpComPort,
779: &ReadOverlapped,
780: &BytesRead,
781: TRUE
782: );
783:
784: } else {
785:
786: //
787: // Device could be locked up. Clear it just in case.
788: //
789:
790: ClearCommError(
791: DbgKdpComPort,
792: &TrashErr,
793: &TrashStat
794: );
795:
796: }
797:
798: }
799:
800: if (rc && BytesRead == 1 &&
801: ( DataByte == PACKET_LEADER_BYTE ||
802: DataByte == CONTROL_PACKET_LEADER_BYTE)
803: ) {
804: if ( Index == 0 ) {
805: PreviousDataByte = DataByte;
806: Index++;
807: } else if ( DataByte == PreviousDataByte ) {
808: Index++;
809: } else {
810: PreviousDataByte = DataByte;
811: Index = 1;
812: }
813: } else {
814: Index = 0;
815: if (BytesRead == 0) {
816: return(FALSE);
817: }
818: }
819: } while ( Index < 2 );
820:
821: if ( DataByte != CONTROL_PACKET_LEADER_BYTE ) {
822: *PacketLeader = PACKET_LEADER;
823: } else {
824: *PacketLeader = CONTROL_PACKET_LEADER;
825: }
826: return TRUE;
827: }
828: BOOLEAN
829: DbgKdpWaitForPacket(
830: IN USHORT PacketType,
831: OUT PVOID Packet
832: )
833: {
834: PDBGKD_DEBUG_IO IoMessage;
835: DWORD BytesRead;
836: BOOL rc;
837: UCHAR DataByte;
838: ULONG Checksum;
839: ULONG SyncBit;
840:
841:
842: if (PacketType != PACKET_TYPE_KD_ACKNOWLEDGE) {
843: if (ValidUnaccessedPacket) {
844: goto ReadBuffered;
845: }
846: }
847:
848: //
849: // First read a packet leader
850: //
851:
852: WaitForPacketLeader:
853:
854: ValidUnaccessedPacket = FALSE;
855:
856: if (!DbgKdpReadPacketLeader(PacketType, &PacketHeader.PacketLeader)) {
857: return FALSE;
858: }
859:
860: //
861: // Read packetLeader ONLY read two Packet Leader bytes. This do loop
862: // filters out the remaining leader byte.
863: //
864:
865: do {
866: rc = ReadFile(
867: DbgKdpComPort,
868: &DataByte,
869: 1,
870: &BytesRead,
871: &ReadOverlapped
872: );
873:
874: if (!rc) {
875:
876: if (GetLastError() == ERROR_IO_PENDING) {
877:
878: rc = GetOverlappedResult(
879: DbgKdpComPort,
880: &ReadOverlapped,
881: &BytesRead,
882: TRUE
883: );
884:
885: } else {
886:
887: //
888: // Device could be locked up. Clear it just in case.
889: //
890:
891: ClearCommError(
892: DbgKdpComPort,
893: &TrashErr,
894: &TrashStat
895: );
896:
897: }
898:
899: }
900:
901: if ((rc) && BytesRead == 1) {
902: if (DataByte == PACKET_LEADER_BYTE ||
903: DataByte == CONTROL_PACKET_LEADER_BYTE) {
904: continue;
905: } else {
906: *(PUCHAR)&PacketHeader.PacketType = DataByte;
907: break;
908: }
909: } else {
910: goto WaitForPacketLeader;
911: }
912: }while (TRUE);
913:
914: //
915: // Now we have valid packet leader. Read rest of the packet type.
916: //
917:
918: rc = ReadFile(
919: DbgKdpComPort,
920: ((PUCHAR)&PacketHeader.PacketType) + 1,
921: sizeof(PacketHeader.PacketType) - 1,
922: &BytesRead,
923: &ReadOverlapped
924: );
925:
926: if (!rc) {
927:
928: if (GetLastError() == ERROR_IO_PENDING) {
929:
930: rc = GetOverlappedResult(
931: DbgKdpComPort,
932: &ReadOverlapped,
933: &BytesRead,
934: TRUE
935: );
936:
937: } else {
938:
939: //
940: // Device could be locked up. Clear it just in case.
941: //
942:
943: ClearCommError(
944: DbgKdpComPort,
945: &TrashErr,
946: &TrashStat
947: );
948:
949: }
950:
951: }
952:
953: if ((!rc) || BytesRead != sizeof(PacketHeader.PacketType) - 1) {
954: //
955: // If we cannot read the packet type and if the packet leader
956: // indicates this is a data packet, we need to ask for resend.
957: // Otherwise we simply ignore the incomplete packet.
958: //
959:
960: if (PacketHeader.PacketLeader == PACKET_LEADER) {
961: DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
962: }
963: goto WaitForPacketLeader;
964: }
965:
966: //
967: // Check the Packet type.
968: //
969:
970: if (PacketHeader.PacketType >= PACKET_TYPE_MAX ) {
971: if (PacketHeader.PacketLeader == PACKET_LEADER) {
972: DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
973: }
974: goto WaitForPacketLeader;
975: }
976:
977: //
978: // Read ByteCount
979: //
980:
981: rc = ReadFile(
982: DbgKdpComPort,
983: &PacketHeader.ByteCount,
984: sizeof(PacketHeader.ByteCount),
985: &BytesRead,
986: &ReadOverlapped
987: );
988:
989: if (!rc) {
990:
991: if (GetLastError() == ERROR_IO_PENDING) {
992:
993: rc = GetOverlappedResult(
994: DbgKdpComPort,
995: &ReadOverlapped,
996: &BytesRead,
997: TRUE
998: );
999:
1000: } else {
1001:
1002: //
1003: // Device could be locked up. Clear it just in case.
1004: //
1005:
1006: ClearCommError(
1007: DbgKdpComPort,
1008: &TrashErr,
1009: &TrashStat
1010: );
1011:
1012: }
1013:
1014: }
1015:
1016: if ((!rc) || BytesRead != sizeof(PacketHeader.ByteCount)) {
1017: //
1018: // If we cannot read the packet type and if the packet leader
1019: // indicates this is a data packet, we need to ask for resend.
1020: // Otherwise we simply ignore the incomplete packet.
1021: //
1022:
1023: if (PacketHeader.PacketLeader == PACKET_LEADER) {
1024: DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
1025: }
1026: goto WaitForPacketLeader;
1027: }
1028:
1029: //
1030: // Check ByteCount
1031: //
1032:
1033: if (PacketHeader.ByteCount > PACKET_MAX_SIZE ) {
1034: if (PacketHeader.PacketLeader == PACKET_LEADER) {
1035: DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
1036: }
1037: goto WaitForPacketLeader;
1038: }
1039:
1040: //
1041: // Read Packet Id
1042: //
1043:
1044: rc = ReadFile(
1045: DbgKdpComPort,
1046: &PacketHeader.PacketId,
1047: sizeof(PacketHeader.PacketId),
1048: &BytesRead,
1049: &ReadOverlapped
1050: );
1051:
1052: if (!rc) {
1053:
1054: if (GetLastError() == ERROR_IO_PENDING) {
1055:
1056: rc = GetOverlappedResult(
1057: DbgKdpComPort,
1058: &ReadOverlapped,
1059: &BytesRead,
1060: TRUE
1061: );
1062:
1063: } else {
1064:
1065: //
1066: // Device could be locked up. Clear it just in case.
1067: //
1068:
1069: ClearCommError(
1070: DbgKdpComPort,
1071: &TrashErr,
1072: &TrashStat
1073: );
1074:
1075: }
1076:
1077: }
1078:
1079: if ((!rc) || BytesRead != sizeof(PacketHeader.PacketId)) {
1080: //
1081: // If we cannot read the packet Id and if the packet leader
1082: // indicates this is a data packet, we need to ask for resend.
1083: // Otherwise we simply ignore the incomplete packet.
1084: //
1085:
1086: if (PacketHeader.PacketLeader == PACKET_LEADER) {
1087: DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
1088: }
1089: goto WaitForPacketLeader;
1090: }
1091:
1092: if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER ) {
1093: if (PacketHeader.PacketType == PACKET_TYPE_KD_ACKNOWLEDGE ) {
1094:
1095: //
1096: // If we received an expected ACK packet and we are not
1097: // waiting for any new packet, update outgoing packet id
1098: // and return. If we are NOT waiting for ACK packet
1099: // we will keep on waiting. If the ACK packet
1100: // is not for the packet we send, ignore it and keep on waiting.
1101: //
1102:
1103: if (PacketHeader.PacketId != DbgKdpNextPacketToSend) {
1104: goto WaitForPacketLeader;
1105: } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
1106: DbgKdpNextPacketToSend ^= 1;
1107: return TRUE;
1108: } else {
1109: goto WaitForPacketLeader;
1110: }
1111: } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESET) {
1112:
1113: //
1114: // if we received Reset packet, reset the packet control variables
1115: // and resend earlier packet.
1116: //
1117:
1118: DbgKdpNextPacketToSend = INITIAL_PACKET_ID;
1119: DbgKdpPacketExpected = INITIAL_PACKET_ID;
1120: DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESET, 0L);
1121: return FALSE;
1122: } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESEND) {
1123: return FALSE;
1124: } else {
1125:
1126: //
1127: // Invalid packet header, ignore it.
1128: //
1129:
1130: goto WaitForPacketLeader;
1131: }
1132:
1133: //
1134: // The packet header is for data packet (not control packet).
1135: //
1136:
1137: } else {
1138:
1139: //
1140: // Read Packet Checksum. (for Data Packet Only).
1141: //
1142:
1143: rc = ReadFile(
1144: DbgKdpComPort,
1145: &PacketHeader.Checksum,
1146: sizeof(PacketHeader.Checksum),
1147: &BytesRead,
1148: &ReadOverlapped
1149: );
1150:
1151: if (!rc) {
1152:
1153: if (GetLastError() == ERROR_IO_PENDING) {
1154:
1155: rc = GetOverlappedResult(
1156: DbgKdpComPort,
1157: &ReadOverlapped,
1158: &BytesRead,
1159: TRUE
1160: );
1161:
1162: } else {
1163:
1164: //
1165: // Device could be locked up. Clear it just in case.
1166: //
1167:
1168: ClearCommError(
1169: DbgKdpComPort,
1170: &TrashErr,
1171: &TrashStat
1172: );
1173:
1174: }
1175:
1176: }
1177:
1178: if ((!rc) || BytesRead != sizeof(PacketHeader.Checksum)) {
1179: DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
1180: goto WaitForPacketLeader;
1181: }
1182:
1183: if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
1184:
1185: //
1186: // if we are waiting for ACK packet ONLY
1187: // and we receive a data packet header, check if the packet id
1188: // is what we expected. If yes, assume the acknowledge is lost (but
1189: // sent), ask sender to resend and return with PACKET_RECEIVED.
1190: //
1191:
1192: if (PacketHeader.PacketId == DbgKdpPacketExpected) {
1193: DbgKdpNextPacketToSend ^= 1;
1194: } else {
1195: DbgKdpWriteControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
1196: PacketHeader.PacketId
1197: );
1198: goto WaitForPacketLeader;
1199: }
1200: }
1201: }
1202:
1203: //
1204: // we are waiting for data packet and we received the packet header
1205: // for data packet. Perform the following checkings to make sure
1206: // it is the packet we are waiting for.
1207: //
1208:
1209: if ((PacketHeader.PacketId & ~SYNC_PACKET_ID) != INITIAL_PACKET_ID &&
1210: (PacketHeader.PacketId & ~SYNC_PACKET_ID) != (INITIAL_PACKET_ID ^ 1)) {
1211: goto AskForResend;
1212: }
1213:
1214: rc = ReadFile(
1215: DbgKdpComPort,
1216: DbgKdpPacket,
1217: PacketHeader.ByteCount,
1218: &BytesRead,
1219: &ReadOverlapped
1220: );
1221:
1222: if (!rc) {
1223:
1224: if (GetLastError() == ERROR_IO_PENDING) {
1225:
1226: rc = GetOverlappedResult(
1227: DbgKdpComPort,
1228: &ReadOverlapped,
1229: &BytesRead,
1230: TRUE
1231: );
1232:
1233: } else {
1234:
1235: //
1236: // Device could be locked up. Clear it just in case.
1237: //
1238:
1239: ClearCommError(
1240: DbgKdpComPort,
1241: &TrashErr,
1242: &TrashStat
1243: );
1244:
1245: }
1246:
1247: }
1248:
1249: if ( (!rc) || BytesRead != PacketHeader.ByteCount ) {
1250: goto AskForResend;
1251: }
1252:
1253: //
1254: // Make sure the next byte is packet trailing byte
1255: //
1256:
1257: rc = ReadFile(
1258: DbgKdpComPort,
1259: &DataByte,
1260: sizeof(DataByte),
1261: &BytesRead,
1262: &ReadOverlapped
1263: );
1264:
1265: if (!rc) {
1266:
1267: if (GetLastError() == ERROR_IO_PENDING) {
1268:
1269: rc = GetOverlappedResult(
1270: DbgKdpComPort,
1271: &ReadOverlapped,
1272: &BytesRead,
1273: TRUE
1274: );
1275:
1276: } else {
1277:
1278: //
1279: // Device could be locked up. Clear it just in case.
1280: //
1281:
1282: ClearCommError(
1283: DbgKdpComPort,
1284: &TrashErr,
1285: &TrashStat
1286: );
1287:
1288: }
1289:
1290: }
1291:
1292: if ( (!rc) || BytesRead != sizeof(DataByte) ||
1293: DataByte != PACKET_TRAILING_BYTE ) {
1294: goto AskForResend;
1295: }
1296:
1297: //
1298: // Make sure the checksum is valid.
1299: //
1300:
1301: Checksum = DbgKdpComputeChecksum(DbgKdpPacket, PacketHeader.ByteCount);
1302: if (Checksum != PacketHeader.Checksum) {
1303: goto AskForResend;
1304: }
1305:
1306: //
1307: // We have a valid data packet. If the packetid is bad, we just
1308: // ack the packet to the sender will step ahead. If packetid is bad
1309: // but SYNC_PACKET_ID bit is set, we sync up. If packetid is good,
1310: // or SYNC_PACKET_ID is set, we take the packet.
1311: //
1312:
1313:
1314: SyncBit = PacketHeader.PacketId & SYNC_PACKET_ID;
1315: PacketHeader.PacketId = PacketHeader.PacketId & ~SYNC_PACKET_ID;
1316:
1317: //
1318: // Ack the packet. SYNC_PACKET_ID bit will ALWAYS be OFF.
1319: //
1320:
1321: DbgKdpWriteControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE,
1322: PacketHeader.PacketId
1323: );
1324:
1325: //
1326: // Check the incoming packet Id.
1327: //
1328:
1329: if ((PacketHeader.PacketId != DbgKdpPacketExpected) &&
1330: (SyncBit != SYNC_PACKET_ID)) {
1331:
1332: goto WaitForPacketLeader;
1333:
1334: } else {
1335:
1336: if (SyncBit == SYNC_PACKET_ID) {
1337:
1338: //
1339: // We know SyncBit is set, so reset Expected Ids
1340: //
1341:
1342:
1343: DbgKdpPacketExpected = PacketHeader.PacketId;
1344: DbgKdpNextPacketToSend = INITIAL_PACKET_ID;
1345:
1346: }
1347: DbgKdpPacketExpected ^= 1;
1348:
1349: }
1350:
1351: //
1352: // If this is an internal packet. IO, or Resend, then
1353: // handle it.
1354: //
1355:
1356: if (PacketHeader.PacketType == PACKET_TYPE_KD_DEBUG_IO) {
1357: IoMessage = (PDBGKD_DEBUG_IO)DbgKdpPacket;
1358:
1359: if (IoMessage->ApiNumber == DbgKdPrintStringApi) {
1360: DbgKdpPrint(
1361: IoMessage->Processor,
1362: (PUCHAR)(IoMessage+1),
1363: (SHORT)IoMessage->u.PrintString.LengthOfString
1364: );
1365: } else {
1366: DbgKdpHandlePromptString(IoMessage);
1367: }
1368: if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
1369: return TRUE;
1370: }
1371: goto WaitForPacketLeader;
1372: }
1373:
1374: if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
1375: ValidUnaccessedPacket = TRUE;
1376: return TRUE;
1377: }
1378: ReadBuffered:
1379:
1380: //
1381: // Check PacketType is what we are waiting for.
1382: //
1383:
1384: if (PacketType != PacketHeader.PacketType) {
1385: goto WaitForPacketLeader;
1386: }
1387: *(PVOID *)Packet = &DbgKdpPacket;
1388: ValidUnaccessedPacket = FALSE;
1389: return TRUE;
1390:
1391: AskForResend:
1392:
1393: DbgKdpWriteControlPacket(PACKET_TYPE_KD_RESEND, 0L);
1394: if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) {
1395: return TRUE;
1396: }
1397: goto WaitForPacketLeader;
1398: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.