]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/SerialDxe/SerialIo.c
Return EFI_WRITE_PROTECTED when setting KEKDefault, PKDefault, dbDefault, dbxDefault...
[mirror_edk2.git] / EmbeddedPkg / SerialDxe / SerialIo.c
index 9543f1d1ec1519f4edfcf30f5c329fc98c5987d8..288f353cba8d86281cac735977396d2c863812c2 100644 (file)
@@ -1,14 +1,15 @@
 /** @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.\r
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+  Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>\r
   \r
-  All rights reserved. This program and the accompanying materials\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
   http://opensource.org/licenses/bsd-license.php\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
@@ -42,21 +68,73 @@ SerialReset (
   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
@@ -64,7 +142,7 @@ SerialReset (
   @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
@@ -85,7 +163,60 @@ SerialSetAttributes (
   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
@@ -107,12 +238,12 @@ SerialSetControl (
   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
@@ -128,13 +259,7 @@ SerialGetControl (
   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
@@ -162,12 +287,17 @@ SerialWrite (
   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
@@ -188,24 +318,28 @@ SerialRead (
   OUT VOID                   *Buffer\r
   )\r
 {\r
-  UINTN Count;\r
-  \r
-  Count = SerialPortRead (Buffer, *BufferSize);\r
-  *BufferSize = Count;\r
-  return (Count == 0) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
-}\r
+  UINTN Count = 0;\r
 \r
+  if (SerialPortPoll()) {\r
+    Count = SerialPortRead (Buffer, *BufferSize);\r
+  }\r
 \r
-EFI_HANDLE  gHandle = NULL;\r
+  if (Count != *BufferSize) {\r
+    *BufferSize = Count;\r
+    return EFI_TIMEOUT;\r
+  }\r
+\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
@@ -222,29 +356,6 @@ EFI_SERIAL_IO_PROTOCOL gSerialIoTemplate = {
   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
-    { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, 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
@@ -266,7 +377,6 @@ SerialDxeInitialize (
 {\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