xref: /reactos/drivers/base/kdcom/kdserial.c (revision c2c66aff)
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)21 KdpSendBuffer(
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)43 KdpReceiveBuffer(
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)75 KdpReceivePacketLeader(
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