1 /* 2 * COPYRIGHT: GPL, see COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: drivers/base/kddll/kdserial.c 5 * PURPOSE: Serial communication functions for the kernel debugger. 6 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) 7 */ 8 9 #include "kddll.h" 10 11 /* FUNCTIONS ******************************************************************/ 12 13 /****************************************************************************** 14 * \name KdpSendBuffer 15 * \brief Sends a buffer of data to the serial KD port. 16 * \param Buffer Pointer to the data. 17 * \param Size Size of data in bytes. 18 */ 19 VOID 20 NTAPI KdpSendBuffer(IN PVOID Buffer,IN ULONG Size)21KdpSendBuffer( 22 IN PVOID Buffer, 23 IN ULONG Size) 24 { 25 PUCHAR ByteBuffer = Buffer; 26 27 while (Size-- > 0) 28 { 29 KdpSendByte(*ByteBuffer++); 30 } 31 } 32 33 /****************************************************************************** 34 * \name KdpReceiveBuffer 35 * \brief Receives data from the KD port and fills a buffer. 36 * \param Buffer Pointer to a buffer that receives the data. 37 * \param Size Size of data to receive in bytes. 38 * \return KDP_PACKET_RECEIVED if successful. 39 * KDP_PACKET_TIMEOUT if the receive timed out. 40 */ 41 KDP_STATUS 42 NTAPI KdpReceiveBuffer(OUT PVOID Buffer,IN ULONG Size)43KdpReceiveBuffer( 44 OUT PVOID Buffer, 45 IN ULONG Size) 46 { 47 PUCHAR ByteBuffer = Buffer; 48 UCHAR Byte; 49 KDP_STATUS Status; 50 51 while (Size-- > 0) 52 { 53 /* Try to get a byte from the port */ 54 Status = KdpReceiveByte(&Byte); 55 if (Status != KDP_PACKET_RECEIVED) 56 return Status; 57 58 *ByteBuffer++ = Byte; 59 } 60 61 return KDP_PACKET_RECEIVED; 62 } 63 64 65 /****************************************************************************** 66 * \name KdpReceivePacketLeader 67 * \brief Receives a packet leader from the KD port. 68 * \param PacketLeader Pointer to an ULONG that receives the packet leader. 69 * \return KDP_PACKET_RECEIVED if successful. 70 * KDP_PACKET_TIMEOUT if the receive timed out. 71 * KDP_PACKET_RESEND if a breakin byte was detected. 72 */ 73 KDP_STATUS 74 NTAPI KdpReceivePacketLeader(OUT PULONG PacketLeader)75KdpReceivePacketLeader( 76 OUT PULONG PacketLeader) 77 { 78 UCHAR Index = 0, Byte, Buffer[4]; 79 KDP_STATUS KdStatus; 80 81 /* Set first character to 0 */ 82 Buffer[0] = 0; 83 84 do 85 { 86 /* Receive a single byte */ 87 KdStatus = KdpReceiveByte(&Byte); 88 89 /* Check for timeout */ 90 if (KdStatus == KDP_PACKET_TIMEOUT) 91 { 92 /* Check if we already got a breakin byte */ 93 if (Buffer[0] == BREAKIN_PACKET_BYTE) 94 { 95 return KDP_PACKET_RESEND; 96 } 97 98 /* Report timeout */ 99 return KDP_PACKET_TIMEOUT; 100 } 101 102 /* Check if we received a byte */ 103 if (KdStatus == KDP_PACKET_RECEIVED) 104 { 105 /* Check if this is a valid packet leader byte */ 106 if (Byte == PACKET_LEADER_BYTE || 107 Byte == CONTROL_PACKET_LEADER_BYTE) 108 { 109 /* Check if we match the first byte */ 110 if (Byte != Buffer[0]) 111 { 112 /* No, this is the new byte 0! */ 113 Index = 0; 114 } 115 116 /* Store the byte in the buffer */ 117 Buffer[Index] = Byte; 118 119 /* Continue with next byte */ 120 Index++; 121 continue; 122 } 123 124 /* Check for breakin byte */ 125 if (Byte == BREAKIN_PACKET_BYTE) 126 { 127 KDDBGPRINT("BREAKIN_PACKET_BYTE\n"); 128 Index = 0; 129 Buffer[0] = Byte; 130 continue; 131 } 132 } 133 134 /* Restart */ 135 Index = 0; 136 Buffer[0] = 0; 137 } 138 while (Index < 4); 139 140 /* Enable the debugger */ 141 KD_DEBUGGER_NOT_PRESENT = FALSE; 142 SharedUserData->KdDebuggerEnabled |= 0x00000002; 143 144 /* Return the received packet leader */ 145 *PacketLeader = *(PULONG)Buffer; 146 147 return KDP_PACKET_RECEIVED; 148 } 149 150 /* EOF */ 151