/** @file\r
Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system \r
- running GDB. One consle for error information and another console for user input/output.\r
+ running GDB. One console for error information and another console for user input/output.\r
\r
- Basic packet format is $packet-data#checksum. So every comand has 4 bytes of overhead: $, \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
\r
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+ Copyright (c) 2013, 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
#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
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
/**\r
- Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, \r
+ Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,\r
data buts, and stop bits on a serial device.\r
\r
@param This Protocol instance pointer.\r
@param BaudRate The requested baud rate. A BaudRate value of 0 will use the the\r
device's default interface speed.\r
- @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the\r
+ @param ReceiveFifoDepth The requested depth of the FIFO on the receive side of the\r
serial interface. A ReceiveFifoDepth value of 0 will use\r
- the device's dfault FIFO depth.\r
+ the device's default FIFO depth.\r
@param Timeout The requested time out for a single character in microseconds.\r
This timeout applies to both the transmit and receive side of the\r
interface. A Timeout value of 0 will use the device's default time\r
@param Parity The type of parity to use on this serial device. A Parity value of\r
DefaultParity will use the device's default parity value.\r
@param DataBits The number of data bits to use on the serial device. A DataBits\r
- vaule of 0 will use the device's default data bit setting.\r
+ value of 0 will use the device's default data bit setting.\r
@param StopBits The number of stop bits to use on this serial device. A StopBits\r
value of DefaultStopBits will use the device's default number of\r
stop bits.\r
IN EFI_STOP_BITS_TYPE StopBits\r
)\r
{\r
- return EFI_UNSUPPORTED;\r
+ EFI_STATUS Status;\r
+ EFI_TPL Tpl;\r
+\r
+ Status = SerialPortSetAttributes (&BaudRate, &ReceiveFifoDepth, &Timeout, &Parity, &DataBits, &StopBits);\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->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
- Retrieves the status of thecontrol bits on a serial device\r
+ Retrieves the status of the control bits on a serial device\r
\r
@param This Protocol instance pointer.\r
@param Control A pointer to return the current Control signals from the serial device.\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
UINTN Count;\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
- Writes data to a serial device.\r
+ Reads data from a serial device.\r
\r
@param This Protocol instance pointer.\r
@param BufferSize On input, the size of the Buffer. On output, the amount of\r
)\r
{\r
UINTN Count = 0;\r
- \r
+\r
if (SerialPortPoll()) {\r
Count = SerialPortRead (Buffer, *BufferSize);\r
- *BufferSize = Count;\r
}\r
- return (Count == 0) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
-}\r
\r
+ if (Count != *BufferSize) {\r
+ *BufferSize = Count;\r
+ return EFI_TIMEOUT;\r
+ }\r
\r
-EFI_HANDLE gHandle = NULL;\r
+ return EFI_SUCCESS;\r
+}\r
\r
// \r
-// Template used to initailize the GDB Serial IO protocols\r
+// Template used to initialize the GDB Serial IO protocols\r
//\r
EFI_SERIAL_IO_MODE gSerialIoMode = {\r
0, // ControlMask\r
0, // Timeout\r
FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate\r
- 1, // RceiveFifoDepth\r
+ 1, // ReceiveFifoDepth\r
FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits\r
FixedPcdGet8 (PcdUartDefaultParity), // Parity\r
FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits\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