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