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