/** @file\r
- Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system \r
+ Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system\r
running GDB. One console for error information and another console for user input/output.\r
- \r
+\r
Basic packet format is $packet-data#checksum. So every command has 4 bytes of overhead: $,\r
- #, 0, 0. The 0 and 0 are the ascii characters for the checksum. \r
- \r
+ #, 0, 0. The 0 and 0 are the ascii characters for the checksum.\r
\r
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
- \r
+ Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
+\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/SerialPortLib.h>\r
+#include <Library/SerialPortExtLib.h>\r
#include <Library/PcdLib.h>\r
\r
#include <Protocol/SerialIo.h>\r
\r
+typedef struct {\r
+ VENDOR_DEVICE_PATH Guid;\r
+ UART_DEVICE_PATH Uart;\r
+ EFI_DEVICE_PATH_PROTOCOL End;\r
+} SIMPLE_TEXT_OUT_DEVICE_PATH;\r
+\r
+SIMPLE_TEXT_OUT_DEVICE_PATH mDevicePath = {\r
+ {\r
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} },\r
+ EFI_CALLER_ID_GUID // Use the drivers GUID\r
+ },\r
+ {\r
+ { MESSAGING_DEVICE_PATH, MSG_UART_DP, { sizeof (UART_DEVICE_PATH), 0} },\r
+ 0, // Reserved\r
+ FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate\r
+ FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits\r
+ FixedPcdGet8 (PcdUartDefaultParity), // Parity (N)\r
+ FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits\r
+ },\r
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }\r
+};\r
+\r
+EFI_HANDLE gHandle = NULL;\r
+\r
/**\r
Reset the serial device.\r
\r
@param This Protocol instance pointer.\r
- \r
+\r
@retval EFI_SUCCESS The device was reset.\r
@retval EFI_DEVICE_ERROR The serial device could not be reset.\r
\r
IN EFI_SERIAL_IO_PROTOCOL *This\r
)\r
{\r
- SerialPortInitialize ();\r
- return EFI_SUCCESS;\r
+ EFI_STATUS Status;\r
+ EFI_TPL Tpl;\r
+\r
+ Status = SerialPortInitialize ();\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Set the Serial I/O mode and update the device path\r
+ //\r
+\r
+ Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ //\r
+ // Set the Serial I/O mode\r
+ //\r
+ This->Mode->ReceiveFifoDepth = 0;\r
+ This->Mode->Timeout = 1000000;\r
+ This->Mode->BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
+ This->Mode->DataBits = (UINT32)PcdGet8 (PcdUartDefaultDataBits);\r
+ This->Mode->Parity = (UINT32)PcdGet8 (PcdUartDefaultParity);\r
+ This->Mode->StopBits = (UINT32)PcdGet8 (PcdUartDefaultStopBits);\r
+\r
+ //\r
+ // Check if the device path has actually changed\r
+ //\r
+ if (mDevicePath.Uart.BaudRate == This->Mode->BaudRate &&\r
+ mDevicePath.Uart.DataBits == (UINT8)This->Mode->DataBits &&\r
+ mDevicePath.Uart.Parity == (UINT8)This->Mode->Parity &&\r
+ mDevicePath.Uart.StopBits == (UINT8)This->Mode->StopBits\r
+ ) {\r
+ gBS->RestoreTPL (Tpl);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Update the device path\r
+ //\r
+ mDevicePath.Uart.BaudRate = This->Mode->BaudRate;\r
+ mDevicePath.Uart.DataBits = (UINT8)This->Mode->DataBits;\r
+ mDevicePath.Uart.Parity = (UINT8)This->Mode->Parity;\r
+ mDevicePath.Uart.StopBits = (UINT8)This->Mode->StopBits;\r
+\r
+ Status = gBS->ReinstallProtocolInterface (\r
+ gHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &mDevicePath,\r
+ &mDevicePath\r
+ );\r
+\r
+ gBS->RestoreTPL (Tpl);\r
+\r
+ return Status;\r
}\r
\r
\r
IN EFI_STOP_BITS_TYPE StopBits\r
)\r
{\r
- return EFI_UNSUPPORTED;\r
+ RETURN_STATUS ReturnStatus;\r
+ EFI_STATUS Status;\r
+ EFI_TPL Tpl;\r
+\r
+ ReturnStatus = SerialPortSetAttributes (&BaudRate, &ReceiveFifoDepth, &Timeout, &Parity, &DataBits, &StopBits);\r
+ if (RETURN_ERROR (ReturnStatus)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Set the Serial I/O mode and update the device path\r
+ //\r
+\r
+ Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ //\r
+ // Set the Serial I/O mode\r
+ //\r
+ This->Mode->BaudRate = BaudRate;\r
+ This->Mode->ReceiveFifoDepth = ReceiveFifoDepth;\r
+ This->Mode->Timeout = Timeout;\r
+ This->Mode->Parity = (UINT32)Parity;\r
+ This->Mode->DataBits = (UINT32)DataBits;\r
+ This->Mode->StopBits = (UINT32)StopBits;\r
+\r
+ //\r
+ // Check if the device path has actually changed\r
+ //\r
+ if (mDevicePath.Uart.BaudRate == BaudRate &&\r
+ mDevicePath.Uart.Parity == (UINT8)Parity &&\r
+ mDevicePath.Uart.DataBits == DataBits &&\r
+ mDevicePath.Uart.StopBits == (UINT8)StopBits\r
+ ) {\r
+ gBS->RestoreTPL (Tpl);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Update the device path\r
+ //\r
+ mDevicePath.Uart.BaudRate = BaudRate;\r
+ mDevicePath.Uart.DataBits = DataBits;\r
+ mDevicePath.Uart.Parity = (UINT8) Parity;\r
+ mDevicePath.Uart.StopBits = (UINT8) StopBits;\r
+\r
+ Status = gBS->ReinstallProtocolInterface (\r
+ gHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &mDevicePath,\r
+ &mDevicePath\r
+ );\r
+\r
+ gBS->RestoreTPL (Tpl);\r
+\r
+ return Status;\r
}\r
\r
\r
IN UINT32 Control\r
)\r
{\r
- return EFI_UNSUPPORTED;\r
+ return SerialPortSetControl(Control);\r
}\r
\r
\r
\r
@param This Protocol instance pointer.\r
@param Control A pointer to return the current Control signals from the serial device.\r
- \r
+\r
@retval EFI_SUCCESS The control bits were read from the serial device.\r
@retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
\r
OUT UINT32 *Control\r
)\r
{\r
- if (SerialPortPoll ()) {\r
- // If a character is pending don't set EFI_SERIAL_INPUT_BUFFER_EMPTY\r
- *Control = EFI_SERIAL_OUTPUT_BUFFER_EMPTY;\r
- } else {\r
- *Control = EFI_SERIAL_INPUT_BUFFER_EMPTY | EFI_SERIAL_OUTPUT_BUFFER_EMPTY;\r
- }\r
- return EFI_SUCCESS;\r
+ return SerialPortGetControl(Control);\r
}\r
\r
\r
)\r
{\r
UINTN Count;\r
- \r
+\r
Count = SerialPortWrite (Buffer, *BufferSize);\r
- *BufferSize = Count;\r
- return (Count == 0) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
+\r
+ if (Count != *BufferSize) {\r
+ *BufferSize = Count;\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r
return EFI_SUCCESS;\r
}\r
\r
-\r
-EFI_HANDLE gHandle = NULL;\r
-\r
-// \r
+//\r
// Template used to initialize the GDB Serial IO protocols\r
//\r
EFI_SERIAL_IO_MODE gSerialIoMode = {\r
SerialRead,\r
&gSerialIoMode\r
};\r
- \r
-typedef struct {\r
- VENDOR_DEVICE_PATH Guid;\r
- UART_DEVICE_PATH Uart;\r
- EFI_DEVICE_PATH_PROTOCOL End;\r
-} SIMPLE_TEXT_OUT_DEVICE_PATH;\r
-\r
-SIMPLE_TEXT_OUT_DEVICE_PATH mDevicePath = {\r
- {\r
- { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH), 0},\r
- EFI_CALLER_ID_GUID // Use the drivers GUID\r
- },\r
- {\r
- { MESSAGING_DEVICE_PATH, MSG_UART_DP, sizeof (UART_DEVICE_PATH), 0},\r
- 0, // Reserved\r
- FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate\r
- FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits\r
- FixedPcdGet8 (PcdUartDefaultParity), // Parity (N)\r
- FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits\r
- },\r
- { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}\r
-};\r
-\r
\r
/**\r
Initialize the state information for the Serial Io Protocol\r
{\r
EFI_STATUS Status;\r
\r
-\r
// Make a new handle with Serial IO protocol and its device path on it.\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
- &gHandle, \r
+ &gHandle,\r
&gEfiSerialIoProtocolGuid, &gSerialIoTemplate,\r
- &gEfiDevicePathProtocolGuid, &mDevicePath, \r
+ &gEfiDevicePathProtocolGuid, &mDevicePath,\r
NULL\r
);\r
ASSERT_EFI_ERROR (Status);\r
- \r
+\r
return Status;\r
}\r
\r