TianoCore EDK2 master
Loading...
Searching...
No Matches
SerialIo.c
Go to the documentation of this file.
1
15#include <GdbStubInternal.h>
16
17//
18// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c
19// here we need to wait for the periodic callback to do this.
20//
21BOOLEAN gCtrlCBreakFlag = FALSE;
22
23//
24// If the periodic callback is called while we are processing an F packet we need
25// to let the callback know to not read from the serial stream as it could steal
26// characters from the F response packet
27//
28BOOLEAN gProcessingFPacket = FALSE;
29
38VOID
40 IN UINTN ErrNo
41 )
42{
43 // See D.10.5 of gdb.pdf
44 // This should look like a break message. Should look like SIGINT
45
46 /* TODO: Make sure if we should do anything with ErrNo */
47 // Turn on the global Ctrl-C flag.
48 gCtrlCBreakFlag = TRUE;
49}
50
61INTN
63 IN CHAR8 *Packet,
64 OUT UINTN *ErrNo
65 )
66{
67 INTN RetCode;
68
69 if (Packet[0] != 'F') {
70 // A valid response would be an F packet
71 return -1;
72 }
73
74 RetCode = AsciiStrHexToUintn (&Packet[1]);
75
76 // Find 1st comma
77 for ( ; *Packet != '\0' && *Packet != ','; Packet++) {
78 }
79
80 if (*Packet == '\0') {
81 *ErrNo = 0;
82 return RetCode;
83 }
84
85 *ErrNo = AsciiStrHexToUintn (++Packet);
86
87 // Find 2nd comma
88 for ( ; *Packet != '\0' && *Packet != ','; Packet++) {
89 }
90
91 if (*Packet == '\0') {
92 return RetCode;
93 }
94
95 if (*(++Packet) == 'C') {
96 GdbCtrlCBreakMessage (*ErrNo);
97 }
98
99 return RetCode;
100}
101
114INTN
116 IN INTN FileDescriptor,
117 OUT VOID *Buffer,
118 IN UINTN Count
119 )
120{
121 CHAR8 Packet[128];
122 UINTN Size;
123 INTN RetCode;
124 UINTN ErrNo;
125 BOOLEAN ReceiveDone = FALSE;
126
127 // Send:
128 // "Fread,XX,YYYYYYYY,XX
129 //
130 // XX - FileDescriptor in ASCII
131 // YYYYYYYY - Buffer address in ASCII
132 // XX - Count in ASCII
133 // SS - check sum
134 //
135 Size = AsciiSPrint (Packet, sizeof (Packet), "Fread,%x,%x,%x", FileDescriptor, Buffer, Count);
136 // Packet array is too small if you got this ASSERT
137 ASSERT (Size < sizeof (Packet));
138
139 gProcessingFPacket = TRUE;
140 SendPacket (Packet);
141 Print ((CHAR16 *)L"Packet sent..\n");
142
143 do {
144 // Reply:
145 ReceivePacket (Packet, sizeof (Packet));
146 Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);
147
148 // Process GDB commands
149 switch (Packet[0]) {
150 // Write memory command.
151 // M addr,length:XX...
152 case 'M':
153 WriteToMemory (Packet);
154 break;
155
156 // Fretcode, errno, Ctrl-C flag
157 // retcode - Count read
158 case 'F':
159 // Once target receives F reply packet that means the previous
160 // transactions are finished.
161 ReceiveDone = TRUE;
162 break;
163
164 // Send empty buffer
165 default:
167 break;
168 }
169 } while (ReceiveDone == FALSE);
170
171 RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
172 Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);
173
174 if (ErrNo > 0) {
175 // Send error to the host if there is any.
176 SendError ((UINT8)ErrNo);
177 }
178
179 gProcessingFPacket = FALSE;
180
181 return RetCode;
182}
183
196INTN
198 IN INTN FileDescriptor,
199 OUT CONST VOID *Buffer,
200 IN UINTN Count
201 )
202{
203 CHAR8 Packet[128];
204 UINTN Size;
205 INTN RetCode;
206 UINTN ErrNo;
207 BOOLEAN ReceiveDone = FALSE;
208
209 // Send:
210 // #Fwrite,XX,YYYYYYYY,XX$SS
211 //
212 // XX - FileDescriptor in ASCII
213 // YYYYYYYY - Buffer address in ASCII
214 // XX - Count in ASCII
215 // SS - check sum
216 //
217 Size = AsciiSPrint (Packet, sizeof (Packet), "Fwrite,%x,%x,%x", FileDescriptor, Buffer, Count);
218 // Packet array is too small if you got this ASSERT
219 ASSERT (Size < sizeof (Packet));
220
221 SendPacket (Packet);
222 Print ((CHAR16 *)L"Packet sent..\n");
223
224 do {
225 // Reply:
226 ReceivePacket (Packet, sizeof (Packet));
227 Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);
228
229 // Process GDB commands
230 switch (Packet[0]) {
231 // Read memory command.
232 // m addr,length.
233 case 'm':
234 ReadFromMemory (Packet);
235 break;
236
237 // Fretcode, errno, Ctrl-C flag
238 // retcode - Count read
239 case 'F':
240 // Once target receives F reply packet that means the previous
241 // transactions are finished.
242 ReceiveDone = TRUE;
243 break;
244
245 // Send empty buffer
246 default:
248 break;
249 }
250 } while (ReceiveDone == FALSE);
251
252 RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
253 Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);
254
255 // Send error to the host if there is any.
256 if (ErrNo > 0) {
257 SendError ((UINT8)ErrNo);
258 }
259
260 return RetCode;
261}
262
273EFIAPI
276 )
277{
278 return EFI_SUCCESS;
279}
280
308EFIAPI
311 IN UINT64 BaudRate,
312 IN UINT32 ReceiveFifoDepth,
313 IN UINT32 Timeout,
314 IN EFI_PARITY_TYPE Parity,
315 IN UINT8 DataBits,
316 IN EFI_STOP_BITS_TYPE StopBits
317 )
318{
319 return EFI_UNSUPPORTED;
320}
321
334EFIAPI
337 IN UINT32 Control
338 )
339{
340 return EFI_UNSUPPORTED;
341}
342
354EFIAPI
357 OUT UINT32 *Control
358 )
359{
360 return EFI_UNSUPPORTED;
361}
362
377EFIAPI
380 IN OUT UINTN *BufferSize,
381 IN VOID *Buffer
382 )
383{
384 GDB_SERIAL_DEV *SerialDev;
385 UINTN Return;
386
387 SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);
388
389 Return = GdbWrite (SerialDev->OutFileDescriptor, Buffer, *BufferSize);
390 if (Return == (UINTN)-1) {
391 return EFI_DEVICE_ERROR;
392 }
393
394 if (Return != *BufferSize) {
395 *BufferSize = Return;
396 }
397
398 return EFI_SUCCESS;
399}
400
415EFIAPI
418 IN OUT UINTN *BufferSize,
419 OUT VOID *Buffer
420 )
421{
422 GDB_SERIAL_DEV *SerialDev;
423 UINTN Return;
424
425 SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);
426
427 Return = GdbRead (SerialDev->InFileDescriptor, Buffer, *BufferSize);
428 if (Return == (UINTN)-1) {
429 return EFI_DEVICE_ERROR;
430 }
431
432 if (Return != *BufferSize) {
433 *BufferSize = Return;
434 }
435
436 return EFI_SUCCESS;
437}
438
439//
440// Template used to initialize the GDB Serial IO protocols
441//
442GDB_SERIAL_DEV gdbSerialDevTemplate = {
443 GDB_SERIAL_DEV_SIGNATURE,
444 NULL,
445
446 { // SerialIo
447 SERIAL_IO_INTERFACE_REVISION,
454 NULL
455 },
456 { // SerialMode
457 0, // ControlMask
458 0, // Timeout
459 0, // BaudRate
460 1, // ReceiveFifoDepth
461 0, // DataBits
462 0, // Parity
463 0 // StopBits
464 },
465 {
466 {
467 {
470 {
471 (UINT8)(sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)),
472 (UINT8)((sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)) >> 8)
473 },
474 },
475 EFI_SERIAL_IO_PROTOCOL_GUID
476 },
477 0,
478 {
479 END_DEVICE_PATH_TYPE,
480 END_ENTIRE_DEVICE_PATH_SUBTYPE,
481 {
482 (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
483 (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL) >> 8)
484 }
485 },
486 },
487 GDB_STDIN,
488 GDB_STDOUT
489};
490
497VOID
499 VOID
500 )
501{
502 EFI_STATUS Status;
503 GDB_SERIAL_DEV *StdOutSerialDev;
504 GDB_SERIAL_DEV *StdErrSerialDev;
505
506 // Use the template to make a copy of the Serial Console private data structure.
507 StdOutSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
508 ASSERT (StdOutSerialDev != NULL);
509
510 // Fixup pointer after the copy
511 StdOutSerialDev->SerialIo.Mode = &StdOutSerialDev->SerialMode;
512
513 StdErrSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
514 ASSERT (StdErrSerialDev != NULL);
515
516 // Fixup pointer and modify stuff that is different for StdError
517 StdErrSerialDev->SerialIo.Mode = &StdErrSerialDev->SerialMode;
518 StdErrSerialDev->DevicePath.Index = 1;
519 StdErrSerialDev->OutFileDescriptor = GDB_STDERR;
520
521 // Make a new handle with Serial IO protocol and its device path on it.
522 Status = gBS->InstallMultipleProtocolInterfaces (
523 &StdOutSerialDev->Handle,
524 &gEfiSerialIoProtocolGuid,
525 &StdOutSerialDev->SerialIo,
526 &gEfiDevicePathProtocolGuid,
527 &StdOutSerialDev->DevicePath,
528 NULL
529 );
530 ASSERT_EFI_ERROR (Status);
531
532 // Make a new handle with Serial IO protocol and its device path on it.
533 Status = gBS->InstallMultipleProtocolInterfaces (
534 &StdErrSerialDev->Handle,
535 &gEfiSerialIoProtocolGuid,
536 &StdErrSerialDev->SerialIo,
537 &gEfiDevicePathProtocolGuid,
538 &StdErrSerialDev->DevicePath,
539 NULL
540 );
541 ASSERT_EFI_ERROR (Status);
542}
UINT64 UINTN
INT64 INTN
UINTN EFIAPI AsciiStrHexToUintn(IN CONST CHAR8 *String)
Definition: String.c:1104
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define HW_VENDOR_DP
Definition: DevicePath.h:133
VOID GdbInitializeSerialConsole(VOID)
Definition: SerialIo.c:498
EFI_STATUS EFIAPI GdbSerialGetControl(IN EFI_SERIAL_IO_PROTOCOL *This, OUT UINT32 *Control)
Definition: SerialIo.c:355
VOID GdbCtrlCBreakMessage(IN UINTN ErrNo)
Definition: SerialIo.c:39
EFI_STATUS EFIAPI GdbSerialRead(IN EFI_SERIAL_IO_PROTOCOL *This, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
Definition: SerialIo.c:416
INTN GdbParseFReplyPacket(IN CHAR8 *Packet, OUT UINTN *ErrNo)
Definition: SerialIo.c:62
EFI_STATUS EFIAPI GdbSerialReset(IN EFI_SERIAL_IO_PROTOCOL *This)
Definition: SerialIo.c:274
EFI_STATUS EFIAPI GdbSerialWrite(IN EFI_SERIAL_IO_PROTOCOL *This, IN OUT UINTN *BufferSize, IN VOID *Buffer)
Definition: SerialIo.c:378
EFI_STATUS EFIAPI GdbSerialSetAttributes(IN EFI_SERIAL_IO_PROTOCOL *This, IN UINT64 BaudRate, IN UINT32 ReceiveFifoDepth, IN UINT32 Timeout, IN EFI_PARITY_TYPE Parity, IN UINT8 DataBits, IN EFI_STOP_BITS_TYPE StopBits)
Definition: SerialIo.c:309
INTN GdbWrite(IN INTN FileDescriptor, OUT CONST VOID *Buffer, IN UINTN Count)
Definition: SerialIo.c:197
EFI_STATUS EFIAPI GdbSerialSetControl(IN EFI_SERIAL_IO_PROTOCOL *This, IN UINT32 Control)
Definition: SerialIo.c:335
INTN GdbRead(IN INTN FileDescriptor, OUT VOID *Buffer, IN UINTN Count)
Definition: SerialIo.c:115
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
VOID EFIAPI WriteToMemory(IN CHAR8 *PacketData)
Definition: GdbStub.c:640
VOID EFIAPI ReadFromMemory(CHAR8 *PacketData)
Definition: GdbStub.c:593
VOID EFIAPI SendNotSupported(VOID)
Definition: GdbStub.c:466
UINTN SendPacket(IN CHAR8 *PacketData)
Definition: GdbStub.c:270
UINTN ReceivePacket(OUT CHAR8 *PacketData, IN UINTN PacketDataSize)
Definition: GdbStub.c:327
VOID EFIAPI SendError(IN UINT8 ErrorNum)
Definition: GdbStub.c:436
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
EFI_STOP_BITS_TYPE
Definition: SerialIo.h:53
EFI_PARITY_TYPE
Definition: SerialIo.h:41
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
Definition: UefiLibPrint.c:113
EFI_SERIAL_IO_MODE * Mode
Definition: SerialIo.h:295