1 /* 2 * COPYRIGHT: GPL, see COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: drivers/base/kddll/gdb_receive.c 5 * PURPOSE: Base functions for the kernel debugger. 6 */ 7 8 #include "kdgdb.h" 9 10 /* GLOBALS ********************************************************************/ 11 CHAR gdb_input[0x1000]; 12 13 /* GLOBAL FUNCTIONS ***********************************************************/ 14 char 15 hex_value(char ch) 16 { 17 if ((ch >= '0') && (ch <= '9')) 18 return (ch - '0'); 19 20 if ((ch >= 'a') && (ch <= 'f')) 21 return (ch - 'a' + 10); 22 23 if ((ch >= 'A') && (ch <= 'F')) 24 return (ch - 'A' + 10); 25 26 return -1; 27 } 28 29 KDSTATUS 30 NTAPI 31 gdb_receive_packet(_Inout_ PKD_CONTEXT KdContext) 32 { 33 UCHAR* ByteBuffer; 34 UCHAR Byte; 35 KDSTATUS Status; 36 CHAR CheckSum, ReceivedCheckSum; 37 38 do 39 { 40 Status = KdpReceiveByte(&Byte); 41 if (Status != KdPacketReceived) 42 return Status; 43 } while (Byte != '$'); 44 45 get_packet: 46 CheckSum = 0; 47 ByteBuffer = (UCHAR*)gdb_input; 48 49 while (TRUE) 50 { 51 /* Try to get a byte from the port */ 52 Status = KdpReceiveByte(&Byte); 53 if (Status != KdPacketReceived) 54 return Status; 55 56 if (Byte == '#') 57 { 58 *ByteBuffer = '\0'; 59 break; 60 } 61 CheckSum += (CHAR)Byte; 62 63 /* See if we should escape */ 64 if (Byte == 0x7d) 65 { 66 Status = KdpReceiveByte(&Byte); 67 if (Status != KdPacketReceived) 68 return Status; 69 CheckSum += (CHAR)Byte; 70 Byte ^= 0x20; 71 } 72 *ByteBuffer++ = Byte; 73 } 74 75 /* Get Check sum (two bytes) */ 76 Status = KdpReceiveByte(&Byte); 77 if (Status != KdPacketReceived) 78 goto end; 79 ReceivedCheckSum = hex_value(Byte) << 4; 80 81 Status = KdpReceiveByte(&Byte); 82 if (Status != KdPacketReceived) 83 goto end; 84 ReceivedCheckSum += hex_value(Byte); 85 86 end: 87 if (ReceivedCheckSum != CheckSum) 88 { 89 /* Do not acknowledge to GDB */ 90 KDDBGPRINT("Check sums don't match!"); 91 KdpSendByte('-'); 92 return KdPacketNeedsResend; 93 } 94 95 /* Ensure there is nothing left in the pipe */ 96 while (KdpPollByte(&Byte) == KdPacketReceived) 97 { 98 switch (Byte) 99 { 100 case '$': 101 KDDBGPRINT("Received new packet just after %s.\n", gdb_input); 102 goto get_packet; 103 case 0x03: 104 KdContext->KdpControlCPending = TRUE; 105 break; 106 } 107 } 108 109 /* Acknowledge */ 110 KdpSendByte('+'); 111 112 return KdPacketReceived; 113 } 114