/** Write the specified number of bytes to 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 actually written. @param[in] Buffer The buffer of data to write. @retval EFI_SUCCESS The data were written successfully. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_TIMEOUT The write operation was stopped due to timeout. **/ EFI_STATUS EFIAPI SerialWrite ( IN EFI_SERIAL_IO_PROTOCOL *This, IN OUT UINTN *BufferSize, IN VOID *Buffer ) { DEBUG_PORT_HANDLE Handle; Handle = GetDebugPortHandle (); if ((mSerialIoMode.ControlMask & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) != 0) { if (*BufferSize == 0) { return EFI_SUCCESS; } if ((mLoopbackBuffer & SERIAL_PORT_LOOPBACK_BUFFER_FULL) != 0) { *BufferSize = 0; return EFI_TIMEOUT; } mLoopbackBuffer = SERIAL_PORT_LOOPBACK_BUFFER_FULL | *(UINT8 *)Buffer; *BufferSize = 1; } else { *BufferSize = DebugPortWriteBuffer (Handle, Buffer, *BufferSize); } return EFI_SUCCESS; }
/** Get ControlBits. @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL. @param[out] Control Control signals of the serial device. @retval EFI_SUCCESS Get Control signals successfully. **/ EFI_STATUS EFIAPI SerialGetControl ( IN EFI_SERIAL_IO_PROTOCOL *This, OUT UINT32 *Control ) { DEBUG_PORT_HANDLE Handle; Handle = GetDebugPortHandle (); // // Always assume the output buffer is empty and the Debug Communication Library can process // more write requests. // *Control = mSerialIoMode.ControlMask | EFI_SERIAL_OUTPUT_BUFFER_EMPTY; // // Check to see if the Terminal FIFO is empty and // check to see if the input buffer in the Debug Communication Library is empty // if (!IsDebugTermianlFifoEmpty (&mSerialFifoForTerminal) || DebugPortPollBuffer (Handle)) { *Control &= ~EFI_SERIAL_INPUT_BUFFER_EMPTY; } return EFI_SUCCESS; }
/** Write the specified number of bytes to 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 actually written. @param[in] Buffer The buffer of data to write. @retval EFI_SUCCESS The data were written successfully. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_TIMEOUT The write operation was stopped due to timeout. **/ EFI_STATUS EFIAPI SerialWrite ( IN EFI_SERIAL_IO_PROTOCOL *This, IN OUT UINTN *BufferSize, IN VOID *Buffer ) { DEBUG_PORT_HANDLE Handle; BOOLEAN DebugTimerInterruptState; EFI_TPL Tpl; // // 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 (); if ((mSerialIoMode.ControlMask & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) != 0) { if (*BufferSize == 0) { return EFI_SUCCESS; } if ((mLoopbackBuffer & SERIAL_PORT_LOOPBACK_BUFFER_FULL) != 0) { *BufferSize = 0; return EFI_TIMEOUT; } mLoopbackBuffer = SERIAL_PORT_LOOPBACK_BUFFER_FULL | *(UINT8 *)Buffer; *BufferSize = 1; } else { *BufferSize = DebugPortWriteBuffer (Handle, Buffer, *BufferSize); } // // Restore Debug Timer interrupt // SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState); // // Restore to original TPL // gBS->RestoreTPL (Tpl); return EFI_SUCCESS; }
/** Get ControlBits. @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL. @param[out] Control Control signals of the serial device. @retval EFI_SUCCESS Get Control signals successfully. **/ EFI_STATUS EFIAPI SerialGetControl ( IN EFI_SERIAL_IO_PROTOCOL *This, OUT UINT32 *Control ) { DEBUG_PORT_HANDLE Handle; BOOLEAN DebugTimerInterruptState; EFI_TPL Tpl; // // 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 (); // // Always assume the output buffer is empty and the Debug Communication Library can process // more write requests. // *Control = mSerialIoMode.ControlMask | EFI_SERIAL_OUTPUT_BUFFER_EMPTY; // // Check to see if the Terminal FIFO is empty and // check to see if the input buffer in the Debug Communication Library is empty // if (!IsDebugTermianlFifoEmpty (&mSerialFifoForTerminal) || DebugPortPollBuffer (Handle)) { *Control &= ~EFI_SERIAL_INPUT_BUFFER_EMPTY; } // // 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 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; }