/** Read the Attach/Break-in symbols from the debug port. @param[in] Handle Pointer to Debug Port handle. @param[out] BreakSymbol Returned break symbol. @retval EFI_SUCCESS Read the symbol in BreakSymbol. @retval EFI_NOT_FOUND No read the break symbol. **/ EFI_STATUS DebugReadBreakSymbol ( IN DEBUG_PORT_HANDLE Handle, OUT UINT8 *BreakSymbol ) { EFI_STATUS Status; UINT8 Data; Status = DebugTerminalFifoRemove (&mSerialFifoForDebug, &Data); if (Status != EFI_SUCCESS) { if (!DebugPortPollBuffer (Handle)) { // // No data in Debug Port buffer. // return EFI_NOT_FOUND; } else { // // Read one character from Debug Port. // DebugPortReadBuffer (Handle, &Data, 1, 0); if ((Data != DEBUG_STARTING_SYMBOL_ATTACH) && (Data != DEBUG_STARTING_SYMBOL_BREAK)) { // // If the data is not Break symbol, add it into Terminal FIFO // DebugTerminalFifoAdd (&mSerialFifoForTerminal, Data); return EFI_NOT_FOUND; } } } *BreakSymbol = Data; return EFI_SUCCESS; }
/** Read the Attach/Break-in symbols. @param[in] Handle Pointer to Debug Port handle. @param[out] BreakSymbol Returned break symbol. @retval EFI_SUCCESS Read the symbol in BreakSymbol. @retval EFI_NOT_FOUND No read the break symbol. **/ EFI_STATUS DebugReadBreakSymbol ( IN DEBUG_PORT_HANDLE Handle, OUT UINT8 *BreakSymbol ) { EFI_STATUS Status; UINT8 Data8; // // Read break symbol from debug FIFO firstly // Status = DebugTerminalFifoRemove (&mSerialFifoForDebug, &Data8); if (Status == EFI_SUCCESS) { *BreakSymbol = Data8; return EFI_SUCCESS; } else { // // Read Break symbol from debug port // return DebugReadBreakFromDebugPort (Handle, BreakSymbol); } }
/** Read the specified number of bytes from serial device. @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL. @param[in, out] BufferSize On input the size of Buffer, on output the amount of data returned in buffer. @param[out] Buffer The buffer to return the data into. @retval EFI_SUCCESS The data were read successfully. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_TIMEOUT The read operation was stopped due to timeout. **/ EFI_STATUS EFIAPI SerialRead ( IN EFI_SERIAL_IO_PROTOCOL *This, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { EFI_STATUS Status; UINTN Index; UINT8 *Uint8Buffer; BOOLEAN DebugTimerInterruptState; EFI_TPL Tpl; DEBUG_PORT_HANDLE Handle; DEBUG_PACKET_HEADER DebugHeader; UINT8 *Data8; // // Raise TPL to prevent recursion from EFI timer interrupts // Tpl = gBS->RaiseTPL (TPL_NOTIFY); // // Save and disable Debug Timer interrupt to avoid it to access Debug Port // DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE); Handle = GetDebugPortHandle (); Data8 = (UINT8 *) &DebugHeader; Uint8Buffer = (UINT8 *)Buffer; if ((mSerialIoMode.ControlMask & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) != 0) { if ((mLoopbackBuffer & SERIAL_PORT_LOOPBACK_BUFFER_FULL) == 0) { return EFI_TIMEOUT; } *Uint8Buffer = (UINT8)(mLoopbackBuffer & 0xff); mLoopbackBuffer = 0; *BufferSize = 1; } else { for (Index = 0; Index < *BufferSize; Index++) { // // Read input character from terminal FIFO firstly // Status = DebugTerminalFifoRemove (&mSerialFifoForTerminal, Data8); if (Status == EFI_SUCCESS) { *Uint8Buffer = *Data8; Uint8Buffer ++; continue; } // // Read the input character from Debug Port // if (!DebugPortPollBuffer (Handle)) { break; } DebugPortReadBuffer (Handle, Data8, 1, 0); if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) { // // Add the debug symbol into Debug FIFO // DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Terminal Timer attach symbol received %x", *Data8); DebugTerminalFifoAdd (&mSerialFifoForDebug, *Data8); } else if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) { Status = ReadRemainingBreakPacket (Handle, &DebugHeader); if (Status == EFI_SUCCESS) { DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Terminal Timer break symbol received %x", DebugHeader.Command); DebugTerminalFifoAdd (&mSerialFifoForDebug, DebugHeader.Command); } if (Status == EFI_TIMEOUT) { continue; } } else { *Uint8Buffer = *Data8; Uint8Buffer ++; } } *BufferSize = (UINTN)Uint8Buffer - (UINTN)Buffer; } // // Restore Debug Timer interrupt // SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState); // // Restore to original TPL // gBS->RestoreTPL (Tpl); return EFI_SUCCESS; }
/** Read the specified number of bytes from serial device. @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL. @param[in, out] BufferSize On input the size of Buffer, on output the amount of data returned in buffer. @param[out] Buffer The buffer to return the data into. @retval EFI_SUCCESS The data were read successfully. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_TIMEOUT The read operation was stopped due to timeout. **/ EFI_STATUS EFIAPI SerialRead ( IN EFI_SERIAL_IO_PROTOCOL *This, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { EFI_STATUS Status; UINTN Index; UINT8 *Uint8Buffer; BOOLEAN OldInterruptState; DEBUG_PORT_HANDLE Handle; UINT8 Data; Handle = GetDebugPortHandle (); // // Save and disable Debug Timer interrupt to avoid it to access Debug Port // OldInterruptState = SaveAndSetDebugTimerInterrupt (FALSE); Uint8Buffer = (UINT8 *)Buffer; if ((mSerialIoMode.ControlMask & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) != 0) { if ((mLoopbackBuffer & SERIAL_PORT_LOOPBACK_BUFFER_FULL) == 0) { return EFI_TIMEOUT; } *Uint8Buffer = (UINT8)(mLoopbackBuffer & 0xff); mLoopbackBuffer = 0; *BufferSize = 1; } else { for (Index = 0; Index < *BufferSize; Index++) { // // Read input character from terminal FIFO firstly // Status = DebugTerminalFifoRemove (&mSerialFifoForTerminal, &Data); if (Status == EFI_SUCCESS) { *Uint8Buffer = Data; Uint8Buffer ++; continue; } // // Read the input character from Debug Port // if (!DebugPortPollBuffer (Handle)) { break; } DebugPortReadBuffer (Handle, &Data, 1, 0); if (Data== DEBUG_STARTING_SYMBOL_ATTACH || Data == DEBUG_STARTING_SYMBOL_BREAK) { // // Add the debug symbol into Debug FIFO // DebugTerminalFifoAdd (&mSerialFifoForDebug, Data); } else { *Uint8Buffer = Data; Uint8Buffer ++; } } *BufferSize = (UINTN)Uint8Buffer - (UINTN)Buffer; } // // Restore Debug Timer interrupt // SaveAndSetDebugTimerInterrupt (OldInterruptState); return EFI_SUCCESS; }