]> git.proxmox.com Git - mirror_edk2.git/blob - SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/SerialIo.c
SourceLevelDebugPkg/DebugAgent: Fix various typos
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DxeDebugAgent / SerialIo.c
1 /** @file
2 Install Serial IO Protocol that layers on top of a Debug Communication Library instance.
3
4 Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "DxeDebugAgentLib.h"
10
11 //
12 // Serial I/O Protocol Interface definitions.
13 //
14
15 /**
16 Reset serial device.
17
18 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
19
20 @retval EFI_SUCCESS Reset successfully.
21
22 **/
23 EFI_STATUS
24 EFIAPI
25 SerialReset (
26 IN EFI_SERIAL_IO_PROTOCOL *This
27 );
28
29 /**
30 Set new attributes to a serial device.
31
32 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
33 @param[in] BaudRate The baudrate of the serial device.
34 @param[in] ReceiveFifoDepth The depth of receive FIFO buffer.
35 @param[in] Timeout The request timeout for a single char.
36 @param[in] Parity The type of parity used in serial device.
37 @param[in] DataBits Number of databits used in serial device.
38 @param[in] StopBits Number of stopbits used in serial device.
39
40 @retval EFI_SUCCESS The new attributes were set.
41 @retval EFI_INVALID_PARAMETER One or more attributes have an unsupported value.
42 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly (no return).
43
44 **/
45 EFI_STATUS
46 EFIAPI
47 SerialSetAttributes (
48 IN EFI_SERIAL_IO_PROTOCOL *This,
49 IN UINT64 BaudRate,
50 IN UINT32 ReceiveFifoDepth,
51 IN UINT32 Timeout,
52 IN EFI_PARITY_TYPE Parity,
53 IN UINT8 DataBits,
54 IN EFI_STOP_BITS_TYPE StopBits
55 );
56
57 /**
58 Set Control Bits.
59
60 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
61 @param[in] Control Control bits that can be settable.
62
63 @retval EFI_SUCCESS New Control bits were set successfully.
64 @retval EFI_UNSUPPORTED The Control bits wanted to set are not supported.
65
66 **/
67 EFI_STATUS
68 EFIAPI
69 SerialSetControl (
70 IN EFI_SERIAL_IO_PROTOCOL *This,
71 IN UINT32 Control
72 );
73
74 /**
75 Get ControlBits.
76
77 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
78 @param[out] Control Control signals of the serial device.
79
80 @retval EFI_SUCCESS Get Control signals successfully.
81
82 **/
83 EFI_STATUS
84 EFIAPI
85 SerialGetControl (
86 IN EFI_SERIAL_IO_PROTOCOL *This,
87 OUT UINT32 *Control
88 );
89
90 /**
91 Write the specified number of bytes to serial device.
92
93 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
94 @param[in, out] BufferSize On input the size of Buffer, on output the amount of
95 data actually written.
96 @param[in] Buffer The buffer of data to write.
97
98 @retval EFI_SUCCESS The data were written successfully.
99 @retval EFI_DEVICE_ERROR The device reported an error.
100 @retval EFI_TIMEOUT The write operation was stopped due to timeout.
101
102 **/
103 EFI_STATUS
104 EFIAPI
105 SerialWrite (
106 IN EFI_SERIAL_IO_PROTOCOL *This,
107 IN OUT UINTN *BufferSize,
108 IN VOID *Buffer
109 );
110
111 /**
112 Read the specified number of bytes from serial device.
113
114 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
115 @param[in, out] BufferSize On input the size of Buffer, on output the amount of
116 data returned in buffer.
117 @param[out] Buffer The buffer to return the data into.
118
119 @retval EFI_SUCCESS The data were read successfully.
120 @retval EFI_DEVICE_ERROR The device reported an error.
121 @retval EFI_TIMEOUT The read operation was stopped due to timeout.
122
123 **/
124 EFI_STATUS
125 EFIAPI
126 SerialRead (
127 IN EFI_SERIAL_IO_PROTOCOL *This,
128 IN OUT UINTN *BufferSize,
129 OUT VOID *Buffer
130 );
131
132 //
133 // Serial Driver Defaults
134 //
135 #define SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH 1
136 #define SERIAL_PORT_DEFAULT_TIMEOUT 1000000
137 #define SERIAL_PORT_DEFAULT_CONTROL_MASK 0
138 #define SERIAL_PORT_LOOPBACK_BUFFER_FULL BIT8
139
140 //
141 // EFI_SERIAL_IO_MODE instance
142 //
143 EFI_SERIAL_IO_MODE mSerialIoMode = {
144 SERIAL_PORT_DEFAULT_CONTROL_MASK,
145 SERIAL_PORT_DEFAULT_TIMEOUT,
146 0, // default BaudRate
147 SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH,
148 0, // default DataBits
149 0, // default Parity
150 0 // default StopBits
151 };
152
153 //
154 // EFI_SERIAL_IO_PROTOCOL instance
155 //
156 EFI_SERIAL_IO_PROTOCOL mSerialIo = {
157 SERIAL_IO_INTERFACE_REVISION,
158 SerialReset,
159 SerialSetAttributes,
160 SerialSetControl,
161 SerialGetControl,
162 SerialWrite,
163 SerialRead,
164 &mSerialIoMode
165 };
166
167 //
168 // Serial IO Device Path definition
169 //
170 typedef struct {
171 VENDOR_DEVICE_PATH VendorDevicePath;
172 UART_DEVICE_PATH UartDevicePath;
173 EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
174 } SERIAL_IO_DEVICE_PATH;
175
176 //
177 // Serial IO Device Patch instance
178 //
179 SERIAL_IO_DEVICE_PATH mSerialIoDevicePath = {
180 {
181 {
182 HARDWARE_DEVICE_PATH,
183 HW_VENDOR_DP,
184 {
185 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
186 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
187 }
188 },
189 EFI_DEBUG_AGENT_GUID,
190 },
191 {
192 {
193 MESSAGING_DEVICE_PATH,
194 MSG_UART_DP,
195 {
196 (UINT8) (sizeof (UART_DEVICE_PATH)),
197 (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
198 }
199 },
200 0,
201 0, // default BaudRate
202 0, // default DataBits
203 0, // default Parity
204 0, // default StopBits
205 },
206 {
207 END_DEVICE_PATH_TYPE,
208 END_ENTIRE_DEVICE_PATH_SUBTYPE,
209 {
210 END_DEVICE_PATH_LENGTH,
211 0
212 }
213 }
214 };
215
216 #define DEBGU_SERIAL_IO_FIFO_DEPTH 10
217 //
218 // Data buffer for Terminal input character and Debug Symbols.
219 // The depth is DEBGU_SERIAL_IO_FIFO_DEPTH.
220 // Fields:
221 // First UINT8: The index of the first data in array Data[].
222 // Last UINT8: The index, which you can put a new data into array Data[].
223 // Surplus UINT8: Identify how many data you can put into array Data[].
224 // Data[] UINT8: An array, which used to store data.
225 //
226 typedef struct {
227 UINT8 First;
228 UINT8 Last;
229 UINT8 Surplus;
230 UINT8 Data[DEBGU_SERIAL_IO_FIFO_DEPTH];
231 } DEBUG_SERIAL_FIFO;
232
233 //
234 // Global Variables
235 //
236 EFI_HANDLE mSerialIoHandle = NULL;
237 UINTN mLoopbackBuffer = 0;
238 DEBUG_SERIAL_FIFO mSerialFifoForTerminal = {0, 0, DEBGU_SERIAL_IO_FIFO_DEPTH, { 0 }};
239 DEBUG_SERIAL_FIFO mSerialFifoForDebug = {0, 0, DEBGU_SERIAL_IO_FIFO_DEPTH, { 0 }};
240
241 /**
242 Detect whether specific FIFO is empty or not.
243
244 @param[in] Fifo A pointer to the Data Structure DEBUG_SERIAL_FIFO.
245
246 @return whether specific FIFO is empty or not.
247
248 **/
249 BOOLEAN
250 IsDebugTermianlFifoEmpty (
251 IN DEBUG_SERIAL_FIFO *Fifo
252 )
253 {
254 if (Fifo->Surplus == DEBGU_SERIAL_IO_FIFO_DEPTH) {
255 return TRUE;
256 }
257
258 return FALSE;
259 }
260
261 /**
262 Detect whether specific FIFO is full or not.
263
264 @param[in] Fifo A pointer to the Data Structure DEBUG_SERIAL_FIFO.
265
266 @return whether specific FIFO is full or not.
267
268 **/
269 BOOLEAN
270 IsDebugTerminalFifoFull (
271 IN DEBUG_SERIAL_FIFO *Fifo
272 )
273
274 {
275 if (Fifo->Surplus == 0) {
276 return TRUE;
277 }
278
279 return FALSE;
280 }
281
282 /**
283 Add data to specific FIFO.
284
285 @param[in] Fifo A pointer to the Data Structure DEBUG_SERIAL_FIFO.
286 @param[in] Data The data added to FIFO.
287
288 @retval EFI_SUCCESS Add data to specific FIFO successfully.
289 @retval EFI_OUT_OF_RESOURCE Failed to add data because FIFO is already full.
290
291 **/
292 EFI_STATUS
293 DebugTerminalFifoAdd (
294 IN DEBUG_SERIAL_FIFO *Fifo,
295 IN UINT8 Data
296 )
297
298 {
299 //
300 // if FIFO full can not add data
301 //
302 if (IsDebugTerminalFifoFull (Fifo)) {
303 return EFI_OUT_OF_RESOURCES;
304 }
305 //
306 // FIFO is not full can add data
307 //
308 Fifo->Data[Fifo->Last] = Data;
309 Fifo->Surplus--;
310 Fifo->Last++;
311 if (Fifo->Last == DEBGU_SERIAL_IO_FIFO_DEPTH) {
312 Fifo->Last = 0;
313 }
314
315 return EFI_SUCCESS;
316 }
317
318 /**
319 Remove data from specific FIFO.
320
321 @param[in] Fifo A pointer to the Data Structure DEBUG_SERIAL_FIFO.
322 @param[out] Data The data removed from FIFO.
323
324 @retval EFI_SUCCESS Remove data from specific FIFO successfully.
325 @retval EFI_OUT_OF_RESOURCE Failed to remove data because FIFO is empty.
326
327 **/
328 EFI_STATUS
329 DebugTerminalFifoRemove (
330 IN DEBUG_SERIAL_FIFO *Fifo,
331 OUT UINT8 *Data
332 )
333 {
334 //
335 // if FIFO is empty, no data can remove
336 //
337 if (IsDebugTermianlFifoEmpty (Fifo)) {
338 return EFI_OUT_OF_RESOURCES;
339 }
340 //
341 // FIFO is not empty, can remove data
342 //
343 *Data = Fifo->Data[Fifo->First];
344 Fifo->Surplus++;
345 Fifo->First++;
346 if (Fifo->First == DEBGU_SERIAL_IO_FIFO_DEPTH) {
347 Fifo->First = 0;
348 }
349
350 return EFI_SUCCESS;
351 }
352
353 /**
354 Install EFI Serial IO protocol based on Debug Communication Library.
355
356 **/
357 VOID
358 InstallSerialIo (
359 VOID
360 )
361 {
362 EFI_STATUS Status;
363
364 Status = gBS->InstallMultipleProtocolInterfaces (
365 &mSerialIoHandle,
366 &gEfiDevicePathProtocolGuid, &mSerialIoDevicePath,
367 &gEfiSerialIoProtocolGuid, &mSerialIo,
368 NULL
369 );
370 if (EFI_ERROR (Status)) {
371 DEBUG ((EFI_D_ERROR, "Debug Agent: Failed to install EFI Serial IO Protocol on Debug Port!\n"));
372 }
373 }
374
375 /**
376 Reset serial device.
377
378 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
379
380 @retval EFI_SUCCESS Reset successfully.
381
382 **/
383 EFI_STATUS
384 EFIAPI
385 SerialReset (
386 IN EFI_SERIAL_IO_PROTOCOL *This
387 )
388 {
389 mSerialIoMode.ControlMask = SERIAL_PORT_DEFAULT_CONTROL_MASK;
390 mLoopbackBuffer = 0;
391 //
392 // Not reset serial device hardware indeed.
393 //
394 return EFI_SUCCESS;
395 }
396
397 /**
398 Set new attributes to a serial device.
399
400 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
401 @param[in] BaudRate The baudrate of the serial device.
402 @param[in] ReceiveFifoDepth The depth of receive FIFO buffer.
403 @param[in] Timeout The request timeout for a single char.
404 @param[in] Parity The type of parity used in serial device.
405 @param[in] DataBits Number of databits used in serial device.
406 @param[in] StopBits Number of stopbits used in serial device.
407
408 @retval EFI_SUCCESS The new attributes were set.
409 @retval EFI_INVALID_PARAMETER One or more attributes have an unsupported value.
410 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly (no return).
411
412 **/
413 EFI_STATUS
414 EFIAPI
415 SerialSetAttributes (
416 IN EFI_SERIAL_IO_PROTOCOL *This,
417 IN UINT64 BaudRate,
418 IN UINT32 ReceiveFifoDepth,
419 IN UINT32 Timeout,
420 IN EFI_PARITY_TYPE Parity,
421 IN UINT8 DataBits,
422 IN EFI_STOP_BITS_TYPE StopBits
423 )
424 {
425 //
426 // The Debug Communication Library CAN NOT change communications parameters (if it has)
427 // actually. Because it also has no any idea on what parameters are based on, we cannot
428 // check the input parameters (like BaudRate, Parity, DataBits and StopBits).
429 //
430
431 //
432 // Update the Timeout value in the mode structure based on the request.
433 // The Debug Communication Library can not support a timeout on writes, but the timeout on
434 // reads can be provided by this module.
435 //
436 if (Timeout == 0) {
437 mSerialIoMode.Timeout = SERIAL_PORT_DEFAULT_TIMEOUT;
438 } else {
439 mSerialIoMode.Timeout = Timeout;
440 }
441
442 //
443 // Update the ReceiveFifoDepth value in the mode structure based on the request.
444 // This module assumes that the Debug Communication Library uses a FIFO depth of
445 // SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH. The Debug Communication Library may actually be
446 // using a larger FIFO, but there is no way to tell.
447 //
448 if (ReceiveFifoDepth == 0 || ReceiveFifoDepth >= SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH) {
449 mSerialIoMode.ReceiveFifoDepth = SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH;
450 } else {
451 return EFI_INVALID_PARAMETER;
452 }
453
454 return EFI_SUCCESS;
455 }
456
457 /**
458 Set Control Bits.
459
460 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
461 @param[in] Control Control bits that can be settable.
462
463 @retval EFI_SUCCESS New Control bits were set successfully.
464 @retval EFI_UNSUPPORTED The Control bits wanted to set are not supported.
465
466 **/
467 EFI_STATUS
468 EFIAPI
469 SerialSetControl (
470 IN EFI_SERIAL_IO_PROTOCOL *This,
471 IN UINT32 Control
472 )
473 {
474 //
475 // The only control bit supported by this module is software loopback.
476 // If any other bit is set, then return an error
477 //
478 if ((Control & (~EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE)) != 0) {
479 return EFI_UNSUPPORTED;
480 }
481 mSerialIoMode.ControlMask = Control;
482 return EFI_SUCCESS;
483 }
484
485 /**
486 Get ControlBits.
487
488 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
489 @param[out] Control Control signals of the serial device.
490
491 @retval EFI_SUCCESS Get Control signals successfully.
492
493 **/
494 EFI_STATUS
495 EFIAPI
496 SerialGetControl (
497 IN EFI_SERIAL_IO_PROTOCOL *This,
498 OUT UINT32 *Control
499 )
500 {
501 DEBUG_PORT_HANDLE Handle;
502 BOOLEAN DebugTimerInterruptState;
503 EFI_TPL Tpl;
504
505 //
506 // Raise TPL to prevent recursion from EFI timer interrupts
507 //
508 Tpl = gBS->RaiseTPL (TPL_NOTIFY);
509
510 //
511 // Save and disable Debug Timer interrupt to avoid it to access Debug Port
512 //
513 DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);
514 Handle = GetDebugPortHandle ();
515
516 //
517 // Always assume the output buffer is empty and the Debug Communication Library can process
518 // more write requests.
519 //
520 *Control = mSerialIoMode.ControlMask | EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
521
522 //
523 // Check to see if the Terminal FIFO is empty and
524 // check to see if the input buffer in the Debug Communication Library is empty
525 //
526 if (!IsDebugTermianlFifoEmpty (&mSerialFifoForTerminal) || DebugPortPollBuffer (Handle)) {
527 *Control &= ~EFI_SERIAL_INPUT_BUFFER_EMPTY;
528 }
529
530 //
531 // Restore Debug Timer interrupt
532 //
533 SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);
534
535 //
536 // Restore to original TPL
537 //
538 gBS->RestoreTPL (Tpl);
539
540 return EFI_SUCCESS;
541 }
542
543 /**
544 Write the specified number of bytes to serial device.
545
546 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
547 @param[in, out] BufferSize On input the size of Buffer, on output the amount of
548 data actually written.
549 @param[in] Buffer The buffer of data to write.
550
551 @retval EFI_SUCCESS The data were written successfully.
552 @retval EFI_DEVICE_ERROR The device reported an error.
553 @retval EFI_TIMEOUT The write operation was stopped due to timeout.
554
555 **/
556 EFI_STATUS
557 EFIAPI
558 SerialWrite (
559 IN EFI_SERIAL_IO_PROTOCOL *This,
560 IN OUT UINTN *BufferSize,
561 IN VOID *Buffer
562 )
563 {
564 DEBUG_PORT_HANDLE Handle;
565 BOOLEAN DebugTimerInterruptState;
566 EFI_TPL Tpl;
567
568 //
569 // Raise TPL to prevent recursion from EFI timer interrupts
570 //
571 Tpl = gBS->RaiseTPL (TPL_NOTIFY);
572
573 //
574 // Save and disable Debug Timer interrupt to avoid it to access Debug Port
575 //
576 DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);
577 Handle = GetDebugPortHandle ();
578
579 if ((mSerialIoMode.ControlMask & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) != 0) {
580 if (*BufferSize == 0) {
581 return EFI_SUCCESS;
582 }
583 if ((mLoopbackBuffer & SERIAL_PORT_LOOPBACK_BUFFER_FULL) != 0) {
584 *BufferSize = 0;
585 return EFI_TIMEOUT;
586 }
587 mLoopbackBuffer = SERIAL_PORT_LOOPBACK_BUFFER_FULL | *(UINT8 *)Buffer;
588 *BufferSize = 1;
589 } else {
590 *BufferSize = DebugPortWriteBuffer (Handle, Buffer, *BufferSize);
591 }
592
593 //
594 // Restore Debug Timer interrupt
595 //
596 SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);
597
598 //
599 // Restore to original TPL
600 //
601 gBS->RestoreTPL (Tpl);
602
603 return EFI_SUCCESS;
604 }
605
606 /**
607 Read the specified number of bytes from serial device.
608
609 @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL.
610 @param[in, out] BufferSize On input the size of Buffer, on output the amount of
611 data returned in buffer.
612 @param[out] Buffer The buffer to return the data into.
613
614 @retval EFI_SUCCESS The data were read successfully.
615 @retval EFI_DEVICE_ERROR The device reported an error.
616 @retval EFI_TIMEOUT The read operation was stopped due to timeout.
617
618 **/
619 EFI_STATUS
620 EFIAPI
621 SerialRead (
622 IN EFI_SERIAL_IO_PROTOCOL *This,
623 IN OUT UINTN *BufferSize,
624 OUT VOID *Buffer
625 )
626 {
627 EFI_STATUS Status;
628 UINTN Index;
629 UINT8 *Uint8Buffer;
630 BOOLEAN DebugTimerInterruptState;
631 EFI_TPL Tpl;
632 DEBUG_PORT_HANDLE Handle;
633 DEBUG_PACKET_HEADER DebugHeader;
634 UINT8 *Data8;
635
636 //
637 // Raise TPL to prevent recursion from EFI timer interrupts
638 //
639 Tpl = gBS->RaiseTPL (TPL_NOTIFY);
640
641 //
642 // Save and disable Debug Timer interrupt to avoid it to access Debug Port
643 //
644 DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);
645 Handle = GetDebugPortHandle ();
646
647 Data8 = (UINT8 *) &DebugHeader;
648 Uint8Buffer = (UINT8 *)Buffer;
649 if ((mSerialIoMode.ControlMask & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) != 0) {
650 if ((mLoopbackBuffer & SERIAL_PORT_LOOPBACK_BUFFER_FULL) == 0) {
651 return EFI_TIMEOUT;
652 }
653 *Uint8Buffer = (UINT8)(mLoopbackBuffer & 0xff);
654 mLoopbackBuffer = 0;
655 *BufferSize = 1;
656 } else {
657 for (Index = 0; Index < *BufferSize; Index++) {
658 //
659 // Read input character from terminal FIFO firstly
660 //
661 Status = DebugTerminalFifoRemove (&mSerialFifoForTerminal, Data8);
662 if (Status == EFI_SUCCESS) {
663 *Uint8Buffer = *Data8;
664 Uint8Buffer ++;
665 continue;
666 }
667 //
668 // Read the input character from Debug Port
669 //
670 if (!DebugPortPollBuffer (Handle)) {
671 break;
672 }
673 DebugAgentReadBuffer (Handle, Data8, 1, 0);
674
675 if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) {
676 //
677 // Add the debug symbol into Debug FIFO
678 //
679 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Terminal Timer attach symbol received %x", *Data8);
680 DebugTerminalFifoAdd (&mSerialFifoForDebug, *Data8);
681 } else if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) {
682 Status = ReadRemainingBreakPacket (Handle, &DebugHeader);
683 if (Status == EFI_SUCCESS) {
684 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Terminal Timer break symbol received %x", DebugHeader.Command);
685 DebugTerminalFifoAdd (&mSerialFifoForDebug, DebugHeader.Command);
686 }
687 if (Status == EFI_TIMEOUT) {
688 continue;
689 }
690 } else {
691 *Uint8Buffer = *Data8;
692 Uint8Buffer ++;
693 }
694 }
695 *BufferSize = (UINTN)Uint8Buffer - (UINTN)Buffer;
696 }
697
698 //
699 // Restore Debug Timer interrupt
700 //
701 SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);
702
703 //
704 // Restore to original TPL
705 //
706 gBS->RestoreTPL (Tpl);
707
708 return EFI_SUCCESS;
709 }
710
711 /**
712 Read the Attach/Break-in symbols from the debug port.
713
714 @param[in] Handle Pointer to Debug Port handle.
715 @param[out] BreakSymbol Returned break symbol.
716
717 @retval EFI_SUCCESS Read the symbol in BreakSymbol.
718 @retval EFI_NOT_FOUND No read the break symbol.
719
720 **/
721 EFI_STATUS
722 DebugReadBreakFromDebugPort (
723 IN DEBUG_PORT_HANDLE Handle,
724 OUT UINT8 *BreakSymbol
725 )
726 {
727 EFI_STATUS Status;
728 DEBUG_PACKET_HEADER DebugHeader;
729 UINT8 *Data8;
730
731 *BreakSymbol = 0;
732 //
733 // If Debug Port buffer has data, read it till it was break symbol or Debug Port buffer empty.
734 //
735 Data8 = (UINT8 *) &DebugHeader;
736 while (TRUE) {
737 //
738 // If start symbol is not received
739 //
740 if (!DebugPortPollBuffer (Handle)) {
741 //
742 // If no data in Debug Port, exit
743 //
744 break;
745 }
746 //
747 // Try to read the start symbol
748 //
749 DebugAgentReadBuffer (Handle, Data8, 1, 0);
750 if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) {
751 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer attach symbol received %x", *Data8);
752 *BreakSymbol = *Data8;
753 return EFI_SUCCESS;
754 }
755 if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) {
756 Status = ReadRemainingBreakPacket (Handle, &DebugHeader);
757 if (Status == EFI_SUCCESS) {
758 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer break symbol received %x", DebugHeader.Command);
759 *BreakSymbol = DebugHeader.Command;
760 return EFI_SUCCESS;
761 }
762 if (Status == EFI_TIMEOUT) {
763 break;
764 }
765 } else {
766 //
767 // Add to Terminal FIFO
768 //
769 DebugTerminalFifoAdd (&mSerialFifoForTerminal, *Data8);
770 }
771 }
772
773 return EFI_NOT_FOUND;
774 }
775
776 /**
777 Read the Attach/Break-in symbols.
778
779 @param[in] Handle Pointer to Debug Port handle.
780 @param[out] BreakSymbol Returned break symbol.
781
782 @retval EFI_SUCCESS Read the symbol in BreakSymbol.
783 @retval EFI_NOT_FOUND No read the break symbol.
784
785 **/
786 EFI_STATUS
787 DebugReadBreakSymbol (
788 IN DEBUG_PORT_HANDLE Handle,
789 OUT UINT8 *BreakSymbol
790 )
791 {
792 EFI_STATUS Status;
793 UINT8 Data8;
794
795 //
796 // Read break symbol from debug FIFO firstly
797 //
798 Status = DebugTerminalFifoRemove (&mSerialFifoForDebug, &Data8);
799 if (Status == EFI_SUCCESS) {
800 *BreakSymbol = Data8;
801 return EFI_SUCCESS;
802 } else {
803 //
804 // Read Break symbol from debug port
805 //
806 return DebugReadBreakFromDebugPort (Handle, BreakSymbol);
807 }
808 }