public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Fixed CorebootModulePkg and CorebootPayloadPkg incorrect line endings
@ 2019-04-04 15:32 Agyeman, Prince
  2019-04-04 15:32 ` [PATCH v2 1/2] CorebootModulePkg: Fix non - CRLF " Agyeman, Prince
  2019-04-04 15:32 ` [PATCH v2 2/2] CorebootPayloadPkg: " Agyeman, Prince
  0 siblings, 2 replies; 4+ messages in thread
From: Agyeman, Prince @ 2019-04-04 15:32 UTC (permalink / raw)
  To: devel

Resending to new mailing list
Fixed files with incorrect line endings in CorebootModulePkg to pass PatchCheck.py
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1658

v1 : fixed CRLF line endings
v2:  Removed trailing white spaces

Agyeman (2):
  CorebootModulePkg: Fix non - CRLF line endings
  CorebootPayloadPkg: Fix non - CRLF line endings

 CorebootModulePkg/Include/Coreboot.h          |   32 +-
 .../BaseSerialPortLib16550.c                  | 2178 ++++++++---------
 .../SataControllerDxe/SataController.h        | 1082 ++++----
 CorebootModulePkg/SecCore/Ia32/Stack.S        |  138 +-
 .../PlatformHookLib/PlatformHookLib.inf       |   18 +-
 5 files changed, 1724 insertions(+), 1724 deletions(-)

-- 
2.19.1.windows.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/2] CorebootModulePkg: Fix non - CRLF line endings
  2019-04-04 15:32 [PATCH v2 0/2] Fixed CorebootModulePkg and CorebootPayloadPkg incorrect line endings Agyeman, Prince
@ 2019-04-04 15:32 ` Agyeman, Prince
  2019-04-09 22:59   ` Ma, Maurice
  2019-04-04 15:32 ` [PATCH v2 2/2] CorebootPayloadPkg: " Agyeman, Prince
  1 sibling, 1 reply; 4+ messages in thread
From: Agyeman, Prince @ 2019-04-04 15:32 UTC (permalink / raw)
  To: devel; +Cc: Maurice Ma, Benjamin You

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1658

Replaced non CRLF line endings with CRLF

Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Agyeman <prince.agyeman@intel.com>
---
 CorebootModulePkg/Include/Coreboot.h          |   32 +-
 .../BaseSerialPortLib16550.c                  | 2178 ++++++++---------
 .../SataControllerDxe/SataController.h        | 1082 ++++----
 CorebootModulePkg/SecCore/Ia32/Stack.S        |  138 +-
 4 files changed, 1715 insertions(+), 1715 deletions(-)

diff --git a/CorebootModulePkg/Include/Coreboot.h b/CorebootModulePkg/Include/Coreboot.h
index 784e0b128a..b622e6f17e 100644
--- a/CorebootModulePkg/Include/Coreboot.h
+++ b/CorebootModulePkg/Include/Coreboot.h
@@ -80,7 +80,7 @@ struct imd_root {
   UINT32 max_entries;
   UINT32 num_entries;
   UINT32 flags;
-  UINT32 entry_align;
+  UINT32 entry_align;
   UINT32 max_offset;
   struct imd_entry entries[0];
 };
@@ -165,21 +165,21 @@ struct cb_serial {
   UINT32 type;
   UINT32 baseaddr;
   UINT32 baud;
-  UINT32 regwidth;
-
-  // Crystal or input frequency to the chip containing the UART.
-  // Provide the board specific details to allow the payload to
-  // initialize the chip containing the UART and make independent
-  // decisions as to which dividers to select and their values
-  // to eventually arrive at the desired console baud-rate.
-  UINT32 input_hertz;
-
-  // UART PCI address: bus, device, function
-  // 1 << 31 - Valid bit, PCI UART in use
-  // Bus << 20
-  // Device << 15
-  // Function << 12
-  UINT32 uart_pci_addr;
+  UINT32 regwidth;
+
+  // Crystal or input frequency to the chip containing the UART.
+  // Provide the board specific details to allow the payload to
+  // initialize the chip containing the UART and make independent
+  // decisions as to which dividers to select and their values
+  // to eventually arrive at the desired console baud-rate.
+  UINT32 input_hertz;
+
+  // UART PCI address: bus, device, function
+  // 1 << 31 - Valid bit, PCI UART in use
+  // Bus << 20
+  // Device << 15
+  // Function << 12
+  UINT32 uart_pci_addr;
 };
 
 #define CB_TAG_CONSOLE       0x00010
diff --git a/CorebootModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c b/CorebootModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c
index a5e1755a44..804b948906 100644
--- a/CorebootModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c
+++ b/CorebootModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c
@@ -1,1095 +1,1095 @@
-/** @file
-  16550 UART Serial Port library functions
-
-  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
-  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include <Base.h>
-#include <IndustryStandard/Pci.h>
-#include <Library/SerialPortLib.h>
-#include <Library/PcdLib.h>
-#include <Library/IoLib.h>
-#include <Library/PciLib.h>
-#include <Library/PlatformHookLib.h>
-#include <Library/BaseLib.h>
-
-//
+/** @file
+  16550 UART Serial Port library functions
+
+  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/SerialPortLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/PlatformHookLib.h>
+#include <Library/BaseLib.h>
+
+//
 // PCI Definitions.
-//
-#define PCI_BRIDGE_32_BIT_IO_SPACE              0x01
-
-//
-// 16550 UART register offsets and bitfields
-//
-#define R_UART_RXBUF          0
-#define R_UART_TXBUF          0
-#define R_UART_BAUD_LOW       0
-#define R_UART_BAUD_HIGH      1
-#define R_UART_FCR            2
-#define   B_UART_FCR_FIFOE    BIT0
-#define   B_UART_FCR_FIFO64   BIT5
-#define R_UART_LCR            3
-#define   B_UART_LCR_DLAB     BIT7
-#define R_UART_MCR            4
-#define   B_UART_MCR_DTRC     BIT0
-#define   B_UART_MCR_RTS      BIT1
-#define R_UART_LSR            5
-#define   B_UART_LSR_RXRDY    BIT0
-#define   B_UART_LSR_TXRDY    BIT5
-#define   B_UART_LSR_TEMT     BIT6
-#define R_UART_MSR            6
-#define   B_UART_MSR_CTS      BIT4
-#define   B_UART_MSR_DSR      BIT5
-#define   B_UART_MSR_RI       BIT6
-#define   B_UART_MSR_DCD      BIT7
-
-//
-// 4-byte structure for each PCI node in PcdSerialPciDeviceInfo
-//
-typedef struct {
-  UINT8   Device;
-  UINT8   Function;
-  UINT16  PowerManagementStatusAndControlRegister;
-} PCI_UART_DEVICE_INFO;
-
-/**
-  Read an 8-bit 16550 register.  If PcdSerialUseMmio is TRUE, then the value is read from
-  MMIO space.  If PcdSerialUseMmio is FALSE, then the value is read from I/O space.  The
-  parameter Offset is added to the base address of the 16550 registers that is specified
-  by PcdSerialRegisterBase.
-
-  @param  Base    The base address register of UART device.
-  @param  Offset  The offset of the 16550 register to read.
-
-  @return The value read from the 16550 register.
-
-**/
-UINT8
-SerialPortReadRegister (
-  UINTN  Base,
-  UINTN  Offset
-  )
-{
-  if (PcdGetBool (PcdSerialUseMmio)) {
-    return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride));
-  } else {
-    return IoRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride));
-  }
-}
-
-/**
-  Write an 8-bit 16550 register.  If PcdSerialUseMmio is TRUE, then the value is written to
-  MMIO space.  If PcdSerialUseMmio is FALSE, then the value is written to I/O space.  The
-  parameter Offset is added to the base address of the 16550 registers that is specified
-  by PcdSerialRegisterBase.
-
-  @param  Base    The base address register of UART device.
-  @param  Offset  The offset of the 16550 register to write.
-  @param  Value   The value to write to the 16550 register specified by Offset.
-
-  @return The value written to the 16550 register.
-
-**/
-UINT8
-SerialPortWriteRegister (
-  UINTN  Base,
-  UINTN  Offset,
-  UINT8  Value
-  )
-{
-  if (PcdGetBool (PcdSerialUseMmio)) {
-    return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value);
-  } else {
-    return IoWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value);
-  }
-}
-
-/**
-  Update the value of an 16-bit PCI configuration register in a PCI device.  If the
-  PCI Configuration register specified by PciAddress is already programmed with a
-  non-zero value, then return the current value.  Otherwise update the PCI configuration
-  register specified by PciAddress with the value specified by Value and return the
-  value programmed into the PCI configuration register.  All values must be masked
-  using the bitmask specified by Mask.
-
-  @param  PciAddress  PCI Library address of the PCI Configuration register to update.
-  @param  Value       The value to program into the PCI Configuration Register.
-  @param  Mask        Bitmask of the bits to check and update in the PCI configuration register.
-
-**/
-UINT16
-SerialPortLibUpdatePciRegister16 (
-  UINTN   PciAddress,
-  UINT16  Value,
-  UINT16  Mask
-  )
-{
-  UINT16  CurrentValue;
-
-  CurrentValue = PciRead16 (PciAddress) & Mask;
-  if (CurrentValue != 0) {
-    return CurrentValue;
-  }
-  return PciWrite16 (PciAddress, Value & Mask);
-}
-
-/**
-  Update the value of an 32-bit PCI configuration register in a PCI device.  If the
-  PCI Configuration register specified by PciAddress is already programmed with a
-  non-zero value, then return the current value.  Otherwise update the PCI configuration
-  register specified by PciAddress with the value specified by Value and return the
-  value programmed into the PCI configuration register.  All values must be masked
-  using the bitmask specified by Mask.
-
-  @param  PciAddress  PCI Library address of the PCI Configuration register to update.
-  @param  Value       The value to program into the PCI Configuration Register.
-  @param  Mask        Bitmask of the bits to check and update in the PCI configuration register.
-
-  @return  The Secondary bus number that is actually programed into the PCI to PCI Bridge device.
-
-**/
-UINT32
-SerialPortLibUpdatePciRegister32 (
-  UINTN   PciAddress,
-  UINT32  Value,
-  UINT32  Mask
-  )
-{
-  UINT32  CurrentValue;
-
-  CurrentValue = PciRead32 (PciAddress) & Mask;
-  if (CurrentValue != 0) {
-    return CurrentValue;
-  }
-  return PciWrite32 (PciAddress, Value & Mask);
-}
-
-/**
-  Retrieve the I/O or MMIO base address register for the PCI UART device.
-
-  This function assumes Root Bus Numer is Zero, and enables I/O and MMIO in PCI UART
-  Device if they are not already enabled.
-
-  @return  The base address register of the UART device.
-
-**/
-UINTN
-GetSerialRegisterBase (
-  VOID
-  )
-{
-  UINTN                 PciLibAddress;
-  UINTN                 BusNumber;
-  UINTN                 SubordinateBusNumber;
-  UINT32                ParentIoBase;
-  UINT32                ParentIoLimit;
-  UINT16                ParentMemoryBase;
-  UINT16                ParentMemoryLimit;
-  UINT32                IoBase;
-  UINT32                IoLimit;
-  UINT16                MemoryBase;
-  UINT16                MemoryLimit;
-  UINTN                 SerialRegisterBase;
-  UINTN                 BarIndex;
-  UINT32                RegisterBaseMask;
-  PCI_UART_DEVICE_INFO  *DeviceInfo;
-
-  //
-  // Get PCI Device Info
-  //
-  DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr (PcdSerialPciDeviceInfo);
-
-  //
-  // If PCI Device Info is empty, then assume fixed address UART and return PcdSerialRegisterBase
-  //
-  if (DeviceInfo->Device == 0xff) {
-    return (UINTN)PcdGet64 (PcdSerialRegisterBase);
-  }
-
-  //
-  // Assume PCI Bus 0 I/O window is 0-64KB and MMIO windows is 0-4GB
-  //
-  ParentMemoryBase  = 0 >> 16;
-  ParentMemoryLimit = 0xfff00000 >> 16;
-  ParentIoBase      = 0 >> 12;
-  ParentIoLimit     = 0xf000 >> 12;
-
-  //
-  // Enable I/O and MMIO in PCI Bridge
-  // Assume Root Bus Numer is Zero.
-  //
-  for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) {
-    //
-    // Compute PCI Lib Address to PCI to PCI Bridge
-    //
-    PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0);
-
-    //
-    // Retrieve and verify the bus numbers in the PCI to PCI Bridge
-    //
-    BusNumber            = PciRead8 (PciLibAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
-    SubordinateBusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
-    if (BusNumber == 0 || BusNumber > SubordinateBusNumber) {
-      return 0;
-    }
-
-    //
-    // Retrieve and verify the I/O or MMIO decode window in the PCI to PCI Bridge
-    //
-    if (PcdGetBool (PcdSerialUseMmio)) {
-      MemoryLimit = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xfff0;
-      MemoryBase  = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase))  & 0xfff0;
-
-      //
-      // If PCI Bridge MMIO window is disabled, then return 0
-      //
-      if (MemoryLimit < MemoryBase) {
-        return 0;
-      }
-
-      //
-      // If PCI Bridge MMIO window is not in the address range decoded by the parent PCI Bridge, then return 0
-      //
-      if (MemoryBase < ParentMemoryBase || MemoryBase > ParentMemoryLimit || MemoryLimit > ParentMemoryLimit) {
-        return 0;
-      }
-      ParentMemoryBase  = MemoryBase;
-      ParentMemoryLimit = MemoryLimit;
-    } else {
-      IoLimit = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
-      if ((IoLimit & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) {
-        IoLimit = IoLimit >> 4;
-      } else {
-        IoLimit = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimitUpper16)) << 4) | (IoLimit >> 4);
-      }
-      IoBase = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
-      if ((IoBase & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) {
-        IoBase = IoBase >> 4;
-      } else {
-        IoBase = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16)) << 4) | (IoBase >> 4);
-      }
-
-      //
-      // If PCI Bridge I/O window is disabled, then return 0
-      //
-      if (IoLimit < IoBase) {
-        return 0;
-      }
-
-      //
-      // If PCI Bridge I/O window is not in the address range decoded by the parent PCI Bridge, then return 0
-      //
-      if (IoBase < ParentIoBase || IoBase > ParentIoLimit || IoLimit > ParentIoLimit) {
-        return 0;
-      }
-      ParentIoBase  = IoBase;
-      ParentIoLimit = IoLimit;
-    }
-  }
-
-  //
-  // Compute PCI Lib Address to PCI UART
-  //
-  PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0);
-
-  //
-  // Find the first IO or MMIO BAR
-  //
-  RegisterBaseMask = 0xFFFFFFF0;
-  for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex ++) {
-    SerialRegisterBase = PciRead32 (PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4);
-    if (PcdGetBool (PcdSerialUseMmio) && ((SerialRegisterBase & BIT0) == 0)) {
-      //
-      // MMIO BAR is found
-      //
-      RegisterBaseMask = 0xFFFFFFF0;
-      break;
-    }
-
-    if ((!PcdGetBool (PcdSerialUseMmio)) && ((SerialRegisterBase & BIT0) != 0)) {
-      //
-      // IO BAR is found
-      //
-      RegisterBaseMask = 0xFFFFFFF8;
-      break;
-    }
-  }
-
-  //
-  // MMIO or IO BAR is not found.
-  //
-  if (BarIndex == PCI_MAX_BAR) {
-    return 0;
-  }
-
-  //
-  // Program UART BAR
-  //
-  SerialRegisterBase = SerialPortLibUpdatePciRegister32 (
-                         PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4,
-                         (UINT32)PcdGet64 (PcdSerialRegisterBase),
-                         RegisterBaseMask
-                         );
-
-  //
-  // Verify that the UART BAR is in the address range decoded by the parent PCI Bridge
-  //
-  if (PcdGetBool (PcdSerialUseMmio)) {
-    if (((SerialRegisterBase >> 16) & 0xfff0) < ParentMemoryBase || ((SerialRegisterBase >> 16) & 0xfff0) > ParentMemoryLimit) {
-      return 0;
-    }
-  } else {
-    if ((SerialRegisterBase >> 12) < ParentIoBase || (SerialRegisterBase >> 12) > ParentIoLimit) {
-      return 0;
-    }
-  }
-
-  //
-  // Enable I/O and MMIO in PCI UART Device if they are not already enabled
-  //
-  PciOr16 (
-    PciLibAddress + PCI_COMMAND_OFFSET,
-    PcdGetBool (PcdSerialUseMmio) ? EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE
-    );
-
-  //
-  // Force D0 state if a Power Management and Status Register is specified
-  //
-  if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) {
-    if ((PciRead16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) {
-      PciAnd16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1));
-      //
-      // If PCI UART was not in D0, then make sure FIFOs are enabled, but do not reset FIFOs
-      //
-      SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64)));
-    }
-  }
-
-  //
-  // Get PCI Device Info
-  //
-  DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr (PcdSerialPciDeviceInfo);
-
-  //
-  // Enable I/O or MMIO in PCI Bridge
-  // Assume Root Bus Numer is Zero.
-  //
-  for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) {
-    //
-    // Compute PCI Lib Address to PCI to PCI Bridge
-    //
-    PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0);
-
-    //
-    // Enable the I/O or MMIO decode windows in the PCI to PCI Bridge
-    //
-    PciOr16 (
-      PciLibAddress + PCI_COMMAND_OFFSET,
-      PcdGetBool (PcdSerialUseMmio) ? EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE
-      );
-
-    //
-    // Force D0 state if a Power Management and Status Register is specified
-    //
-    if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) {
-      if ((PciRead16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) {
-        PciAnd16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1));
-      }
-    }
-
-    BusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
-  }
-
-  return SerialRegisterBase;
-}
-
-/**
-  Return whether the hardware flow control signal allows writing.
-
-  @param  SerialRegisterBase The base address register of UART device.
-
-  @retval TRUE  The serial port is writable.
-  @retval FALSE The serial port is not writable.
-**/
-BOOLEAN
-SerialPortWritable (
-  UINTN  SerialRegisterBase
-  )
-{
-  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
-    if (PcdGetBool (PcdSerialDetectCable)) {
-      //
-      // Wait for both DSR and CTS to be set
-      //   DSR is set if a cable is connected.
-      //   CTS is set if it is ok to transmit data
-      //
-      //   DSR  CTS  Description                               Action
-      //   ===  ===  ========================================  ========
-      //    0    0   No cable connected.                       Wait
-      //    0    1   No cable connected.                       Wait
-      //    1    0   Cable connected, but not clear to send.   Wait
-      //    1    1   Cable connected, and clear to send.       Transmit
-      //
-      return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) == (B_UART_MSR_DSR | B_UART_MSR_CTS));
-    } else {
-      //
-      // Wait for both DSR and CTS to be set OR for DSR to be clear.
-      //   DSR is set if a cable is connected.
-      //   CTS is set if it is ok to transmit data
-      //
-      //   DSR  CTS  Description                               Action
-      //   ===  ===  ========================================  ========
-      //    0    0   No cable connected.                       Transmit
-      //    0    1   No cable connected.                       Transmit
-      //    1    0   Cable connected, but not clear to send.   Wait
+//
+#define PCI_BRIDGE_32_BIT_IO_SPACE              0x01
+
+//
+// 16550 UART register offsets and bitfields
+//
+#define R_UART_RXBUF          0
+#define R_UART_TXBUF          0
+#define R_UART_BAUD_LOW       0
+#define R_UART_BAUD_HIGH      1
+#define R_UART_FCR            2
+#define   B_UART_FCR_FIFOE    BIT0
+#define   B_UART_FCR_FIFO64   BIT5
+#define R_UART_LCR            3
+#define   B_UART_LCR_DLAB     BIT7
+#define R_UART_MCR            4
+#define   B_UART_MCR_DTRC     BIT0
+#define   B_UART_MCR_RTS      BIT1
+#define R_UART_LSR            5
+#define   B_UART_LSR_RXRDY    BIT0
+#define   B_UART_LSR_TXRDY    BIT5
+#define   B_UART_LSR_TEMT     BIT6
+#define R_UART_MSR            6
+#define   B_UART_MSR_CTS      BIT4
+#define   B_UART_MSR_DSR      BIT5
+#define   B_UART_MSR_RI       BIT6
+#define   B_UART_MSR_DCD      BIT7
+
+//
+// 4-byte structure for each PCI node in PcdSerialPciDeviceInfo
+//
+typedef struct {
+  UINT8   Device;
+  UINT8   Function;
+  UINT16  PowerManagementStatusAndControlRegister;
+} PCI_UART_DEVICE_INFO;
+
+/**
+  Read an 8-bit 16550 register.  If PcdSerialUseMmio is TRUE, then the value is read from
+  MMIO space.  If PcdSerialUseMmio is FALSE, then the value is read from I/O space.  The
+  parameter Offset is added to the base address of the 16550 registers that is specified
+  by PcdSerialRegisterBase.
+
+  @param  Base    The base address register of UART device.
+  @param  Offset  The offset of the 16550 register to read.
+
+  @return The value read from the 16550 register.
+
+**/
+UINT8
+SerialPortReadRegister (
+  UINTN  Base,
+  UINTN  Offset
+  )
+{
+  if (PcdGetBool (PcdSerialUseMmio)) {
+    return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride));
+  } else {
+    return IoRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride));
+  }
+}
+
+/**
+  Write an 8-bit 16550 register.  If PcdSerialUseMmio is TRUE, then the value is written to
+  MMIO space.  If PcdSerialUseMmio is FALSE, then the value is written to I/O space.  The
+  parameter Offset is added to the base address of the 16550 registers that is specified
+  by PcdSerialRegisterBase.
+
+  @param  Base    The base address register of UART device.
+  @param  Offset  The offset of the 16550 register to write.
+  @param  Value   The value to write to the 16550 register specified by Offset.
+
+  @return The value written to the 16550 register.
+
+**/
+UINT8
+SerialPortWriteRegister (
+  UINTN  Base,
+  UINTN  Offset,
+  UINT8  Value
+  )
+{
+  if (PcdGetBool (PcdSerialUseMmio)) {
+    return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value);
+  } else {
+    return IoWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value);
+  }
+}
+
+/**
+  Update the value of an 16-bit PCI configuration register in a PCI device.  If the
+  PCI Configuration register specified by PciAddress is already programmed with a
+  non-zero value, then return the current value.  Otherwise update the PCI configuration
+  register specified by PciAddress with the value specified by Value and return the
+  value programmed into the PCI configuration register.  All values must be masked
+  using the bitmask specified by Mask.
+
+  @param  PciAddress  PCI Library address of the PCI Configuration register to update.
+  @param  Value       The value to program into the PCI Configuration Register.
+  @param  Mask        Bitmask of the bits to check and update in the PCI configuration register.
+
+**/
+UINT16
+SerialPortLibUpdatePciRegister16 (
+  UINTN   PciAddress,
+  UINT16  Value,
+  UINT16  Mask
+  )
+{
+  UINT16  CurrentValue;
+
+  CurrentValue = PciRead16 (PciAddress) & Mask;
+  if (CurrentValue != 0) {
+    return CurrentValue;
+  }
+  return PciWrite16 (PciAddress, Value & Mask);
+}
+
+/**
+  Update the value of an 32-bit PCI configuration register in a PCI device.  If the
+  PCI Configuration register specified by PciAddress is already programmed with a
+  non-zero value, then return the current value.  Otherwise update the PCI configuration
+  register specified by PciAddress with the value specified by Value and return the
+  value programmed into the PCI configuration register.  All values must be masked
+  using the bitmask specified by Mask.
+
+  @param  PciAddress  PCI Library address of the PCI Configuration register to update.
+  @param  Value       The value to program into the PCI Configuration Register.
+  @param  Mask        Bitmask of the bits to check and update in the PCI configuration register.
+
+  @return  The Secondary bus number that is actually programed into the PCI to PCI Bridge device.
+
+**/
+UINT32
+SerialPortLibUpdatePciRegister32 (
+  UINTN   PciAddress,
+  UINT32  Value,
+  UINT32  Mask
+  )
+{
+  UINT32  CurrentValue;
+
+  CurrentValue = PciRead32 (PciAddress) & Mask;
+  if (CurrentValue != 0) {
+    return CurrentValue;
+  }
+  return PciWrite32 (PciAddress, Value & Mask);
+}
+
+/**
+  Retrieve the I/O or MMIO base address register for the PCI UART device.
+
+  This function assumes Root Bus Numer is Zero, and enables I/O and MMIO in PCI UART
+  Device if they are not already enabled.
+
+  @return  The base address register of the UART device.
+
+**/
+UINTN
+GetSerialRegisterBase (
+  VOID
+  )
+{
+  UINTN                 PciLibAddress;
+  UINTN                 BusNumber;
+  UINTN                 SubordinateBusNumber;
+  UINT32                ParentIoBase;
+  UINT32                ParentIoLimit;
+  UINT16                ParentMemoryBase;
+  UINT16                ParentMemoryLimit;
+  UINT32                IoBase;
+  UINT32                IoLimit;
+  UINT16                MemoryBase;
+  UINT16                MemoryLimit;
+  UINTN                 SerialRegisterBase;
+  UINTN                 BarIndex;
+  UINT32                RegisterBaseMask;
+  PCI_UART_DEVICE_INFO  *DeviceInfo;
+
+  //
+  // Get PCI Device Info
+  //
+  DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr (PcdSerialPciDeviceInfo);
+
+  //
+  // If PCI Device Info is empty, then assume fixed address UART and return PcdSerialRegisterBase
+  //
+  if (DeviceInfo->Device == 0xff) {
+    return (UINTN)PcdGet64 (PcdSerialRegisterBase);
+  }
+
+  //
+  // Assume PCI Bus 0 I/O window is 0-64KB and MMIO windows is 0-4GB
+  //
+  ParentMemoryBase  = 0 >> 16;
+  ParentMemoryLimit = 0xfff00000 >> 16;
+  ParentIoBase      = 0 >> 12;
+  ParentIoLimit     = 0xf000 >> 12;
+
+  //
+  // Enable I/O and MMIO in PCI Bridge
+  // Assume Root Bus Numer is Zero.
+  //
+  for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) {
+    //
+    // Compute PCI Lib Address to PCI to PCI Bridge
+    //
+    PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0);
+
+    //
+    // Retrieve and verify the bus numbers in the PCI to PCI Bridge
+    //
+    BusNumber            = PciRead8 (PciLibAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+    SubordinateBusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+    if (BusNumber == 0 || BusNumber > SubordinateBusNumber) {
+      return 0;
+    }
+
+    //
+    // Retrieve and verify the I/O or MMIO decode window in the PCI to PCI Bridge
+    //
+    if (PcdGetBool (PcdSerialUseMmio)) {
+      MemoryLimit = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xfff0;
+      MemoryBase  = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase))  & 0xfff0;
+
+      //
+      // If PCI Bridge MMIO window is disabled, then return 0
+      //
+      if (MemoryLimit < MemoryBase) {
+        return 0;
+      }
+
+      //
+      // If PCI Bridge MMIO window is not in the address range decoded by the parent PCI Bridge, then return 0
+      //
+      if (MemoryBase < ParentMemoryBase || MemoryBase > ParentMemoryLimit || MemoryLimit > ParentMemoryLimit) {
+        return 0;
+      }
+      ParentMemoryBase  = MemoryBase;
+      ParentMemoryLimit = MemoryLimit;
+    } else {
+      IoLimit = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
+      if ((IoLimit & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) {
+        IoLimit = IoLimit >> 4;
+      } else {
+        IoLimit = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimitUpper16)) << 4) | (IoLimit >> 4);
+      }
+      IoBase = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
+      if ((IoBase & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) {
+        IoBase = IoBase >> 4;
+      } else {
+        IoBase = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16)) << 4) | (IoBase >> 4);
+      }
+
+      //
+      // If PCI Bridge I/O window is disabled, then return 0
+      //
+      if (IoLimit < IoBase) {
+        return 0;
+      }
+
+      //
+      // If PCI Bridge I/O window is not in the address range decoded by the parent PCI Bridge, then return 0
+      //
+      if (IoBase < ParentIoBase || IoBase > ParentIoLimit || IoLimit > ParentIoLimit) {
+        return 0;
+      }
+      ParentIoBase  = IoBase;
+      ParentIoLimit = IoLimit;
+    }
+  }
+
+  //
+  // Compute PCI Lib Address to PCI UART
+  //
+  PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0);
+
+  //
+  // Find the first IO or MMIO BAR
+  //
+  RegisterBaseMask = 0xFFFFFFF0;
+  for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex ++) {
+    SerialRegisterBase = PciRead32 (PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4);
+    if (PcdGetBool (PcdSerialUseMmio) && ((SerialRegisterBase & BIT0) == 0)) {
+      //
+      // MMIO BAR is found
+      //
+      RegisterBaseMask = 0xFFFFFFF0;
+      break;
+    }
+
+    if ((!PcdGetBool (PcdSerialUseMmio)) && ((SerialRegisterBase & BIT0) != 0)) {
+      //
+      // IO BAR is found
+      //
+      RegisterBaseMask = 0xFFFFFFF8;
+      break;
+    }
+  }
+
+  //
+  // MMIO or IO BAR is not found.
+  //
+  if (BarIndex == PCI_MAX_BAR) {
+    return 0;
+  }
+
+  //
+  // Program UART BAR
+  //
+  SerialRegisterBase = SerialPortLibUpdatePciRegister32 (
+                         PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4,
+                         (UINT32)PcdGet64 (PcdSerialRegisterBase),
+                         RegisterBaseMask
+                         );
+
+  //
+  // Verify that the UART BAR is in the address range decoded by the parent PCI Bridge
+  //
+  if (PcdGetBool (PcdSerialUseMmio)) {
+    if (((SerialRegisterBase >> 16) & 0xfff0) < ParentMemoryBase || ((SerialRegisterBase >> 16) & 0xfff0) > ParentMemoryLimit) {
+      return 0;
+    }
+  } else {
+    if ((SerialRegisterBase >> 12) < ParentIoBase || (SerialRegisterBase >> 12) > ParentIoLimit) {
+      return 0;
+    }
+  }
+
+  //
+  // Enable I/O and MMIO in PCI UART Device if they are not already enabled
+  //
+  PciOr16 (
+    PciLibAddress + PCI_COMMAND_OFFSET,
+    PcdGetBool (PcdSerialUseMmio) ? EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE
+    );
+
+  //
+  // Force D0 state if a Power Management and Status Register is specified
+  //
+  if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) {
+    if ((PciRead16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) {
+      PciAnd16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1));
+      //
+      // If PCI UART was not in D0, then make sure FIFOs are enabled, but do not reset FIFOs
+      //
+      SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64)));
+    }
+  }
+
+  //
+  // Get PCI Device Info
+  //
+  DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr (PcdSerialPciDeviceInfo);
+
+  //
+  // Enable I/O or MMIO in PCI Bridge
+  // Assume Root Bus Numer is Zero.
+  //
+  for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) {
+    //
+    // Compute PCI Lib Address to PCI to PCI Bridge
+    //
+    PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0);
+
+    //
+    // Enable the I/O or MMIO decode windows in the PCI to PCI Bridge
+    //
+    PciOr16 (
+      PciLibAddress + PCI_COMMAND_OFFSET,
+      PcdGetBool (PcdSerialUseMmio) ? EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE
+      );
+
+    //
+    // Force D0 state if a Power Management and Status Register is specified
+    //
+    if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) {
+      if ((PciRead16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) {
+        PciAnd16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1));
+      }
+    }
+
+    BusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  }
+
+  return SerialRegisterBase;
+}
+
+/**
+  Return whether the hardware flow control signal allows writing.
+
+  @param  SerialRegisterBase The base address register of UART device.
+
+  @retval TRUE  The serial port is writable.
+  @retval FALSE The serial port is not writable.
+**/
+BOOLEAN
+SerialPortWritable (
+  UINTN  SerialRegisterBase
+  )
+{
+  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+    if (PcdGetBool (PcdSerialDetectCable)) {
+      //
+      // Wait for both DSR and CTS to be set
+      //   DSR is set if a cable is connected.
+      //   CTS is set if it is ok to transmit data
+      //
+      //   DSR  CTS  Description                               Action
+      //   ===  ===  ========================================  ========
+      //    0    0   No cable connected.                       Wait
+      //    0    1   No cable connected.                       Wait
+      //    1    0   Cable connected, but not clear to send.   Wait
       //    1    1   Cable connected, and clear to send.       Transmit
-      //
-      return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) != (B_UART_MSR_DSR));
-    }
-  }
-
-  return TRUE;
-}
-
-/**
-  Initialize the serial device hardware.
-
-  If no initialization is required, then return RETURN_SUCCESS.
-  If the serial device was successfully initialized, then return RETURN_SUCCESS.
-  If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.
-
-  @retval RETURN_SUCCESS        The serial device was initialized.
-  @retval RETURN_DEVICE_ERROR   The serial device could not be initialized.
-
-**/
-RETURN_STATUS
-EFIAPI
-SerialPortInitialize (
-  VOID
-  )
-{
-  RETURN_STATUS  Status;
-  UINTN          SerialRegisterBase;
-  UINT32         Divisor;
-  UINT32         CurrentDivisor;
-  BOOLEAN        Initialized;
-
-  //
-  // Perform platform specific initialization required to enable use of the 16550 device
-  // at the location specified by PcdSerialUseMmio and PcdSerialRegisterBase.
-  //
-  Status = PlatformHookSerialPortInitialize ();
-  if (RETURN_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Calculate divisor for baud generator
-  //    Ref_Clk_Rate / Baud_Rate / 16
-  //
-  Divisor = PcdGet32 (PcdSerialClockRate) / (PcdGet32 (PcdSerialBaudRate) * 16);
-  if ((PcdGet32 (PcdSerialClockRate) % (PcdGet32 (PcdSerialBaudRate) * 16)) >= PcdGet32 (PcdSerialBaudRate) * 8) {
-    Divisor++;
-  }
-
-  //
-  // Get the base address of the serial port in either I/O or MMIO space
-  //
-  SerialRegisterBase = GetSerialRegisterBase ();
-  if (SerialRegisterBase ==0) {
-    return RETURN_DEVICE_ERROR;
-  }
-
-  //
-  // See if the serial port is already initialized
-  //
-  Initialized = TRUE;
-  if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F) != (PcdGet8 (PcdSerialLineControl) & 0x3F)) {
-    Initialized = FALSE;
-  }
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) | B_UART_LCR_DLAB));
-  CurrentDivisor =  SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH) << 8;
-  CurrentDivisor |= (UINT32) SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW);
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & ~B_UART_LCR_DLAB));
-  if (CurrentDivisor != Divisor) {
-    Initialized = FALSE;
-  }
-  if (Initialized) {
-    return RETURN_SUCCESS;
-  }
-
-  //
-  // Wait for the serial port to be ready.
-  // Verify that both the transmit FIFO and the shift register are empty.
-  //
-  while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY));
-
-  //
-  // Configure baud rate
-  //
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB);
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8));
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff));
-
-  //
-  // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
-  // Strip reserved bits from PcdSerialLineControl
-  //
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F));
-
-  //
-  // Enable and reset FIFOs
-  // Strip reserved bits from PcdSerialFifoControl
-  //
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00);
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64)));
-
-  //
-  // Set RTS and DTR in Modem Control Register(MCR)
-  //
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR,
-                   EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY);
-
-  return RETURN_SUCCESS;
-}
-
-/**
-  Write data from buffer to serial device.
-
-  Writes NumberOfBytes data bytes from Buffer to the serial device.
-  The number of bytes actually written to the serial device is returned.
-  If the return value is less than NumberOfBytes, then the write operation failed.
-
-  If Buffer is NULL, then ASSERT().
-
-  If NumberOfBytes is zero, then return 0.
-
-  @param  Buffer           Pointer to the data buffer to be written.
-  @param  NumberOfBytes    Number of bytes to written to the serial device.
-
-  @retval 0                NumberOfBytes is 0.
-  @retval >0               The number of bytes written to the serial device.
-                           If this value is less than NumberOfBytes, then the write operation failed.
-
-**/
-UINTN
-EFIAPI
-SerialPortWrite (
-  IN UINT8     *Buffer,
-  IN UINTN     NumberOfBytes
-  )
-{
-  UINTN  SerialRegisterBase;
-  UINTN  Result;
-  UINTN  Index;
-  UINTN  FifoSize;
-
-  if (Buffer == NULL) {
-    return 0;
-  }
-
-  SerialRegisterBase = GetSerialRegisterBase ();
-  if (SerialRegisterBase ==0) {
-    return 0;
-  }
-
-  if (NumberOfBytes == 0) {
-    //
-    // Flush the hardware
-    //
-
-    //
-    // Wait for both the transmit FIFO and shift register empty.
-    //
-    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY));
-
-    //
-    // Wait for the hardware flow control signal
-    //
-    while (!SerialPortWritable (SerialRegisterBase));
-    return 0;
-  }
-
-  //
-  // Compute the maximum size of the Tx FIFO
-  //
-  FifoSize = 1;
-  if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) != 0) {
-    if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) == 0) {
-      FifoSize = 16;
-    } else {
-      FifoSize = PcdGet32 (PcdSerialExtendedTxFifoSize);
-    }
-  }
-
-  Result = NumberOfBytes;
-  while (NumberOfBytes != 0) {
-    //
-    // Wait for the serial port to be ready, to make sure both the transmit FIFO
-    // and shift register empty.
-    //
-    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_TEMT) == 0);
-
-    //
-    // Fill then entire Tx FIFO
-    //
-    for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) {
-      //
-      // Wait for the hardware flow control signal
-      //
-      while (!SerialPortWritable (SerialRegisterBase));
-
-      //
-      // Write byte to the transmit buffer.
-      //
-      SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buffer);
-    }
-  }
-  return Result;
-}
-
-/**
-  Reads data from a serial device into a buffer.
-
-  @param  Buffer           Pointer to the data buffer to store the data read from the serial device.
-  @param  NumberOfBytes    Number of bytes to read from the serial device.
-
-  @retval 0                NumberOfBytes is 0.
-  @retval >0               The number of bytes read from the serial device.
-                           If this value is less than NumberOfBytes, then the read operation failed.
-
-**/
-UINTN
-EFIAPI
-SerialPortRead (
-  OUT UINT8     *Buffer,
-  IN  UINTN     NumberOfBytes
-  )
-{
-  UINTN  SerialRegisterBase;
-  UINTN  Result;
-  UINT8  Mcr;
-
-  if (NULL == Buffer) {
-    return 0;
-  }
-
-  SerialRegisterBase = GetSerialRegisterBase ();
-  if (SerialRegisterBase ==0) {
-    return 0;
-  }
-
-  Mcr = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS);
-
-  for (Result = 0; NumberOfBytes-- != 0; Result++, Buffer++) {
-    //
-    // Wait for the serial port to have some data.
-    //
-    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) == 0) {
-      if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
-        //
-        // Set RTS to let the peer send some data
-        //
-        SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(Mcr | B_UART_MCR_RTS));
-      }
-    }
-    if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
-      //
-      // Clear RTS to prevent peer from sending data
-      //
-      SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr);
-    }
-
-    //
-    // Read byte from the receive buffer.
-    //
-    *Buffer = SerialPortReadRegister (SerialRegisterBase, R_UART_RXBUF);
-  }
-
-  return Result;
-}
-
-
-/**
-  Polls a serial device to see if there is any data waiting to be read.
-
+      //
+      return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) == (B_UART_MSR_DSR | B_UART_MSR_CTS));
+    } else {
+      //
+      // Wait for both DSR and CTS to be set OR for DSR to be clear.
+      //   DSR is set if a cable is connected.
+      //   CTS is set if it is ok to transmit data
+      //
+      //   DSR  CTS  Description                               Action
+      //   ===  ===  ========================================  ========
+      //    0    0   No cable connected.                       Transmit
+      //    0    1   No cable connected.                       Transmit
+      //    1    0   Cable connected, but not clear to send.   Wait
+      //    1    1   Cable connected, and clear to send.       Transmit
+      //
+      return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) != (B_UART_MSR_DSR));
+    }
+  }
+
+  return TRUE;
+}
+
+/**
+  Initialize the serial device hardware.
+
+  If no initialization is required, then return RETURN_SUCCESS.
+  If the serial device was successfully initialized, then return RETURN_SUCCESS.
+  If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.
+
+  @retval RETURN_SUCCESS        The serial device was initialized.
+  @retval RETURN_DEVICE_ERROR   The serial device could not be initialized.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+  VOID
+  )
+{
+  RETURN_STATUS  Status;
+  UINTN          SerialRegisterBase;
+  UINT32         Divisor;
+  UINT32         CurrentDivisor;
+  BOOLEAN        Initialized;
+
+  //
+  // Perform platform specific initialization required to enable use of the 16550 device
+  // at the location specified by PcdSerialUseMmio and PcdSerialRegisterBase.
+  //
+  Status = PlatformHookSerialPortInitialize ();
+  if (RETURN_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Calculate divisor for baud generator
+  //    Ref_Clk_Rate / Baud_Rate / 16
+  //
+  Divisor = PcdGet32 (PcdSerialClockRate) / (PcdGet32 (PcdSerialBaudRate) * 16);
+  if ((PcdGet32 (PcdSerialClockRate) % (PcdGet32 (PcdSerialBaudRate) * 16)) >= PcdGet32 (PcdSerialBaudRate) * 8) {
+    Divisor++;
+  }
+
+  //
+  // Get the base address of the serial port in either I/O or MMIO space
+  //
+  SerialRegisterBase = GetSerialRegisterBase ();
+  if (SerialRegisterBase ==0) {
+    return RETURN_DEVICE_ERROR;
+  }
+
+  //
+  // See if the serial port is already initialized
+  //
+  Initialized = TRUE;
+  if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F) != (PcdGet8 (PcdSerialLineControl) & 0x3F)) {
+    Initialized = FALSE;
+  }
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) | B_UART_LCR_DLAB));
+  CurrentDivisor =  SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH) << 8;
+  CurrentDivisor |= (UINT32) SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW);
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & ~B_UART_LCR_DLAB));
+  if (CurrentDivisor != Divisor) {
+    Initialized = FALSE;
+  }
+  if (Initialized) {
+    return RETURN_SUCCESS;
+  }
+
+  //
+  // Wait for the serial port to be ready.
+  // Verify that both the transmit FIFO and the shift register are empty.
+  //
+  while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY));
+
+  //
+  // Configure baud rate
+  //
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB);
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8));
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff));
+
+  //
+  // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
+  // Strip reserved bits from PcdSerialLineControl
+  //
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F));
+
+  //
+  // Enable and reset FIFOs
+  // Strip reserved bits from PcdSerialFifoControl
+  //
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00);
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64)));
+
+  //
+  // Set RTS and DTR in Modem Control Register(MCR)
+  //
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR,
+                   EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Write data from buffer to serial device.
+
+  Writes NumberOfBytes data bytes from Buffer to the serial device.
+  The number of bytes actually written to the serial device is returned.
+  If the return value is less than NumberOfBytes, then the write operation failed.
+
+  If Buffer is NULL, then ASSERT().
+
+  If NumberOfBytes is zero, then return 0.
+
+  @param  Buffer           Pointer to the data buffer to be written.
+  @param  NumberOfBytes    Number of bytes to written to the serial device.
+
+  @retval 0                NumberOfBytes is 0.
+  @retval >0               The number of bytes written to the serial device.
+                           If this value is less than NumberOfBytes, then the write operation failed.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+  )
+{
+  UINTN  SerialRegisterBase;
+  UINTN  Result;
+  UINTN  Index;
+  UINTN  FifoSize;
+
+  if (Buffer == NULL) {
+    return 0;
+  }
+
+  SerialRegisterBase = GetSerialRegisterBase ();
+  if (SerialRegisterBase ==0) {
+    return 0;
+  }
+
+  if (NumberOfBytes == 0) {
+    //
+    // Flush the hardware
+    //
+
+    //
+    // Wait for both the transmit FIFO and shift register empty.
+    //
+    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY));
+
+    //
+    // Wait for the hardware flow control signal
+    //
+    while (!SerialPortWritable (SerialRegisterBase));
+    return 0;
+  }
+
+  //
+  // Compute the maximum size of the Tx FIFO
+  //
+  FifoSize = 1;
+  if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) != 0) {
+    if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) == 0) {
+      FifoSize = 16;
+    } else {
+      FifoSize = PcdGet32 (PcdSerialExtendedTxFifoSize);
+    }
+  }
+
+  Result = NumberOfBytes;
+  while (NumberOfBytes != 0) {
+    //
+    // Wait for the serial port to be ready, to make sure both the transmit FIFO
+    // and shift register empty.
+    //
+    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_TEMT) == 0);
+
+    //
+    // Fill then entire Tx FIFO
+    //
+    for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) {
+      //
+      // Wait for the hardware flow control signal
+      //
+      while (!SerialPortWritable (SerialRegisterBase));
+
+      //
+      // Write byte to the transmit buffer.
+      //
+      SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buffer);
+    }
+  }
+  return Result;
+}
+
+/**
+  Reads data from a serial device into a buffer.
+
+  @param  Buffer           Pointer to the data buffer to store the data read from the serial device.
+  @param  NumberOfBytes    Number of bytes to read from the serial device.
+
+  @retval 0                NumberOfBytes is 0.
+  @retval >0               The number of bytes read from the serial device.
+                           If this value is less than NumberOfBytes, then the read operation failed.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+  )
+{
+  UINTN  SerialRegisterBase;
+  UINTN  Result;
+  UINT8  Mcr;
+
+  if (NULL == Buffer) {
+    return 0;
+  }
+
+  SerialRegisterBase = GetSerialRegisterBase ();
+  if (SerialRegisterBase ==0) {
+    return 0;
+  }
+
+  Mcr = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS);
+
+  for (Result = 0; NumberOfBytes-- != 0; Result++, Buffer++) {
+    //
+    // Wait for the serial port to have some data.
+    //
+    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) == 0) {
+      if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+        //
+        // Set RTS to let the peer send some data
+        //
+        SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(Mcr | B_UART_MCR_RTS));
+      }
+    }
+    if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+      //
+      // Clear RTS to prevent peer from sending data
+      //
+      SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr);
+    }
+
+    //
+    // Read byte from the receive buffer.
+    //
+    *Buffer = SerialPortReadRegister (SerialRegisterBase, R_UART_RXBUF);
+  }
+
+  return Result;
+}
+
+
+/**
+  Polls a serial device to see if there is any data waiting to be read.
+
   Polls a serial device to see if there is any data waiting to be read.
-  If there is data waiting to be read from the serial device, then TRUE is returned.
-  If there is no data waiting to be read from the serial device, then FALSE is returned.
-
-  @retval TRUE             Data is waiting to be read from the serial device.
-  @retval FALSE            There is no data waiting to be read from the serial device.
-
-**/
-BOOLEAN
-EFIAPI
-SerialPortPoll (
-  VOID
-  )
-{
-  UINTN  SerialRegisterBase;
-
-  SerialRegisterBase = GetSerialRegisterBase ();
-  if (SerialRegisterBase ==0) {
-    return FALSE;
-  }
-
-  //
-  // Read the serial port status
-  //
-  if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) != 0) {
-    if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
-      //
-      // Clear RTS to prevent peer from sending data
-      //
-      SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS));
-    }
-    return TRUE;
-  }
-
-  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
-    //
-    // Set RTS to let the peer send some data
-    //
-    SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) | B_UART_MCR_RTS));
-  }
-
-  return FALSE;
-}
-
-/**
-  Sets the control bits on a serial device.
-
-  @param Control                Sets the bits of Control that are settable.
-
-  @retval RETURN_SUCCESS        The new control bits were set on the serial device.
-  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
-  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
-
-**/
-RETURN_STATUS
-EFIAPI
-SerialPortSetControl (
-  IN UINT32 Control
-  )
-{
-  UINTN SerialRegisterBase;
-  UINT8 Mcr;
-
-  //
-  // First determine the parameter is invalid.
-  //
-  if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |
-                    EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) {
-    return RETURN_UNSUPPORTED;
-  }
-
-  SerialRegisterBase = GetSerialRegisterBase ();
-  if (SerialRegisterBase ==0) {
-    return RETURN_UNSUPPORTED;
-  }
-
-  //
-  // Read the Modem Control Register.
-  //
-  Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
-  Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS));
-
-  if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) {
-    Mcr |= B_UART_MCR_DTRC;
-  }
-
-  if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) {
-    Mcr |= B_UART_MCR_RTS;
-  }
-
-  //
-  // Write the Modem Control Register.
-  //
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr);
-
-  return RETURN_SUCCESS;
-}
-
-/**
-  Retrieve the status of the control bits on a serial device.
-
-  @param Control                A pointer to return the current control signals from the serial device.
-
-  @retval RETURN_SUCCESS        The control bits were read from the serial device.
-  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
-  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
-
-**/
-RETURN_STATUS
-EFIAPI
-SerialPortGetControl (
-  OUT UINT32 *Control
-  )
-{
-  UINTN SerialRegisterBase;
-  UINT8 Msr;
-  UINT8 Mcr;
-  UINT8 Lsr;
-
-  SerialRegisterBase = GetSerialRegisterBase ();
-  if (SerialRegisterBase ==0) {
-    return RETURN_UNSUPPORTED;
-  }
-
-  *Control = 0;
-
-  //
-  // Read the Modem Status Register.
-  //
-  Msr = SerialPortReadRegister (SerialRegisterBase, R_UART_MSR);
-
-  if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) {
-    *Control |= EFI_SERIAL_CLEAR_TO_SEND;
-  }
-
-  if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) {
-    *Control |= EFI_SERIAL_DATA_SET_READY;
-  }
-
-  if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) {
-    *Control |= EFI_SERIAL_RING_INDICATE;
-  }
-
-  if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) {
-    *Control |= EFI_SERIAL_CARRIER_DETECT;
-  }
-
-  //
-  // Read the Modem Control Register.
-  //
-  Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
-
-  if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) {
-    *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
-  }
-
-  if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) {
-    *Control |= EFI_SERIAL_REQUEST_TO_SEND;
-  }
-
-  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
-    *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
-  }
-
-  //
-  // Read the Line Status Register.
-  //
-  Lsr = SerialPortReadRegister (SerialRegisterBase, R_UART_LSR);
-
-  if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) == (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) {
-    *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
-  }
-
-  if ((Lsr & B_UART_LSR_RXRDY) == 0) {
-    *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
-  }
-
-  return RETURN_SUCCESS;
-}
-
-/**
+  If there is data waiting to be read from the serial device, then TRUE is returned.
+  If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+  @retval TRUE             Data is waiting to be read from the serial device.
+  @retval FALSE            There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+  VOID
+  )
+{
+  UINTN  SerialRegisterBase;
+
+  SerialRegisterBase = GetSerialRegisterBase ();
+  if (SerialRegisterBase ==0) {
+    return FALSE;
+  }
+
+  //
+  // Read the serial port status
+  //
+  if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) != 0) {
+    if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+      //
+      // Clear RTS to prevent peer from sending data
+      //
+      SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS));
+    }
+    return TRUE;
+  }
+
+  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+    //
+    // Set RTS to let the peer send some data
+    //
+    SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) | B_UART_MCR_RTS));
+  }
+
+  return FALSE;
+}
+
+/**
+  Sets the control bits on a serial device.
+
+  @param Control                Sets the bits of Control that are settable.
+
+  @retval RETURN_SUCCESS        The new control bits were set on the serial device.
+  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
+  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+  IN UINT32 Control
+  )
+{
+  UINTN SerialRegisterBase;
+  UINT8 Mcr;
+
+  //
+  // First determine the parameter is invalid.
+  //
+  if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |
+                    EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  SerialRegisterBase = GetSerialRegisterBase ();
+  if (SerialRegisterBase ==0) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  //
+  // Read the Modem Control Register.
+  //
+  Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
+  Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS));
+
+  if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) {
+    Mcr |= B_UART_MCR_DTRC;
+  }
+
+  if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) {
+    Mcr |= B_UART_MCR_RTS;
+  }
+
+  //
+  // Write the Modem Control Register.
+  //
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Retrieve the status of the control bits on a serial device.
+
+  @param Control                A pointer to return the current control signals from the serial device.
+
+  @retval RETURN_SUCCESS        The control bits were read from the serial device.
+  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
+  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+  OUT UINT32 *Control
+  )
+{
+  UINTN SerialRegisterBase;
+  UINT8 Msr;
+  UINT8 Mcr;
+  UINT8 Lsr;
+
+  SerialRegisterBase = GetSerialRegisterBase ();
+  if (SerialRegisterBase ==0) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  *Control = 0;
+
+  //
+  // Read the Modem Status Register.
+  //
+  Msr = SerialPortReadRegister (SerialRegisterBase, R_UART_MSR);
+
+  if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) {
+    *Control |= EFI_SERIAL_CLEAR_TO_SEND;
+  }
+
+  if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) {
+    *Control |= EFI_SERIAL_DATA_SET_READY;
+  }
+
+  if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) {
+    *Control |= EFI_SERIAL_RING_INDICATE;
+  }
+
+  if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) {
+    *Control |= EFI_SERIAL_CARRIER_DETECT;
+  }
+
+  //
+  // Read the Modem Control Register.
+  //
+  Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
+
+  if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) {
+    *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
+  }
+
+  if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) {
+    *Control |= EFI_SERIAL_REQUEST_TO_SEND;
+  }
+
+  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
+    *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+  }
+
+  //
+  // Read the Line Status Register.
+  //
+  Lsr = SerialPortReadRegister (SerialRegisterBase, R_UART_LSR);
+
+  if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) == (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) {
+    *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
+  }
+
+  if ((Lsr & B_UART_LSR_RXRDY) == 0) {
+    *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
   Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,
-  data bits, and stop bits on a serial device.
-
-  @param BaudRate           The requested baud rate. A BaudRate value of 0 will use the
-                            device's default interface speed.
-                            On output, the value actually set.
+  data bits, and stop bits on a serial device.
+
+  @param BaudRate           The requested baud rate. A BaudRate value of 0 will use the
+                            device's default interface speed.
+                            On output, the value actually set.
   @param ReceiveFifoDepth   The requested depth of the FIFO on the receive side of the
-                            serial interface. A ReceiveFifoDepth value of 0 will use
-                            the device's default FIFO depth.
-                            On output, the value actually set.
-  @param Timeout            The requested time out for a single character in microseconds.
-                            This timeout applies to both the transmit and receive side of the
-                            interface. A Timeout value of 0 will use the device's default time
-                            out value.
-                            On output, the value actually set.
-  @param Parity             The type of parity to use on this serial device. A Parity value of
-                            DefaultParity will use the device's default parity value.
-                            On output, the value actually set.
-  @param DataBits           The number of data bits to use on the serial device. A DataBits
+                            serial interface. A ReceiveFifoDepth value of 0 will use
+                            the device's default FIFO depth.
+                            On output, the value actually set.
+  @param Timeout            The requested time out for a single character in microseconds.
+                            This timeout applies to both the transmit and receive side of the
+                            interface. A Timeout value of 0 will use the device's default time
+                            out value.
+                            On output, the value actually set.
+  @param Parity             The type of parity to use on this serial device. A Parity value of
+                            DefaultParity will use the device's default parity value.
+                            On output, the value actually set.
+  @param DataBits           The number of data bits to use on the serial device. A DataBits
                             value of 0 will use the device's default data bit setting.
-                            On output, the value actually set.
-  @param StopBits           The number of stop bits to use on this serial device. A StopBits
-                            value of DefaultStopBits will use the device's default number of
-                            stop bits.
-                            On output, the value actually set.
-
-  @retval RETURN_SUCCESS            The new attributes were set on the serial device.
-  @retval RETURN_UNSUPPORTED        The serial device does not support this operation.
-  @retval RETURN_INVALID_PARAMETER  One or more of the attributes has an unsupported value.
-  @retval RETURN_DEVICE_ERROR       The serial device is not functioning correctly.
-
-**/
-RETURN_STATUS
-EFIAPI
-SerialPortSetAttributes (
-  IN OUT UINT64             *BaudRate,
-  IN OUT UINT32             *ReceiveFifoDepth,
-  IN OUT UINT32             *Timeout,
-  IN OUT EFI_PARITY_TYPE    *Parity,
-  IN OUT UINT8              *DataBits,
-  IN OUT EFI_STOP_BITS_TYPE *StopBits
-  )
-{
-  UINTN     SerialRegisterBase;
-  UINT32    SerialBaudRate;
-  UINTN     Divisor;
-  UINT8     Lcr;
-  UINT8     LcrData;
-  UINT8     LcrParity;
-  UINT8     LcrStop;
-
-  SerialRegisterBase = GetSerialRegisterBase ();
-  if (SerialRegisterBase ==0) {
-    return RETURN_UNSUPPORTED;
-  }
-
-  //
-  // Check for default settings and fill in actual values.
-  //
-  if (*BaudRate == 0) {
-    *BaudRate = PcdGet32 (PcdSerialBaudRate);
-  }
-  SerialBaudRate = (UINT32) *BaudRate;
-
-  if (*DataBits == 0) {
-    LcrData = (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3);
-    *DataBits = LcrData + 5;
-  } else {
-    if ((*DataBits < 5) || (*DataBits > 8)) {
-      return RETURN_INVALID_PARAMETER;
-    }
-    //
-    // Map 5..8 to 0..3
-    //
-    LcrData = (UINT8) (*DataBits - (UINT8) 5);
-  }
-
-  if (*Parity == DefaultParity) {
-    LcrParity = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7);
-    switch (LcrParity) {
-      case 0:
-        *Parity = NoParity;
-        break;
-
-      case 3:
-        *Parity = EvenParity;
-        break;
-
-      case 1:
-        *Parity = OddParity;
-        break;
-
-      case 7:
-        *Parity = SpaceParity;
-        break;
-
-      case 5:
-        *Parity = MarkParity;
-        break;
-
-      default:
-        break;
-    }
-  } else {
-    switch (*Parity) {
-      case NoParity:
-        LcrParity = 0;
-        break;
-
-      case EvenParity:
-        LcrParity = 3;
-        break;
-
-      case OddParity:
-        LcrParity = 1;
-        break;
-
-      case SpaceParity:
-        LcrParity = 7;
-        break;
-
-      case MarkParity:
-        LcrParity = 5;
-        break;
-
-      default:
-        return RETURN_INVALID_PARAMETER;
-    }
-  }
-
-  if (*StopBits == DefaultStopBits) {
-    LcrStop = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1);
-    switch (LcrStop) {
-      case 0:
-        *StopBits = OneStopBit;
-        break;
-
-      case 1:
-        if (*DataBits == 5) {
-          *StopBits = OneFiveStopBits;
-        } else {
-          *StopBits = TwoStopBits;
-        }
-        break;
-
-      default:
-        break;
-    }
-  } else {
-    switch (*StopBits) {
-      case OneStopBit:
-        LcrStop = 0;
-        break;
-
-      case OneFiveStopBits:
-      case TwoStopBits:
-        LcrStop = 1;
-        break;
-
-      default:
-        return RETURN_INVALID_PARAMETER;
-    }
-  }
-
-  //
-  // Calculate divisor for baud generator
-  //    Ref_Clk_Rate / Baud_Rate / 16
-  //
-  Divisor = PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16);
-  if ((PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >= SerialBaudRate * 8) {
-    Divisor++;
-  }
-
-  //
-  // Configure baud rate
-  //
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB);
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8));
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff));
-
-  //
-  // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
-  // Strip reserved bits from line control value
-  //
-  Lcr = (UINT8) ((LcrParity << 3) | (LcrStop << 2) | LcrData);
-  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8) (Lcr & 0x3F));
-
-  return RETURN_SUCCESS;
-}
-
+                            On output, the value actually set.
+  @param StopBits           The number of stop bits to use on this serial device. A StopBits
+                            value of DefaultStopBits will use the device's default number of
+                            stop bits.
+                            On output, the value actually set.
+
+  @retval RETURN_SUCCESS            The new attributes were set on the serial device.
+  @retval RETURN_UNSUPPORTED        The serial device does not support this operation.
+  @retval RETURN_INVALID_PARAMETER  One or more of the attributes has an unsupported value.
+  @retval RETURN_DEVICE_ERROR       The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+  IN OUT UINT64             *BaudRate,
+  IN OUT UINT32             *ReceiveFifoDepth,
+  IN OUT UINT32             *Timeout,
+  IN OUT EFI_PARITY_TYPE    *Parity,
+  IN OUT UINT8              *DataBits,
+  IN OUT EFI_STOP_BITS_TYPE *StopBits
+  )
+{
+  UINTN     SerialRegisterBase;
+  UINT32    SerialBaudRate;
+  UINTN     Divisor;
+  UINT8     Lcr;
+  UINT8     LcrData;
+  UINT8     LcrParity;
+  UINT8     LcrStop;
+
+  SerialRegisterBase = GetSerialRegisterBase ();
+  if (SerialRegisterBase ==0) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  //
+  // Check for default settings and fill in actual values.
+  //
+  if (*BaudRate == 0) {
+    *BaudRate = PcdGet32 (PcdSerialBaudRate);
+  }
+  SerialBaudRate = (UINT32) *BaudRate;
+
+  if (*DataBits == 0) {
+    LcrData = (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3);
+    *DataBits = LcrData + 5;
+  } else {
+    if ((*DataBits < 5) || (*DataBits > 8)) {
+      return RETURN_INVALID_PARAMETER;
+    }
+    //
+    // Map 5..8 to 0..3
+    //
+    LcrData = (UINT8) (*DataBits - (UINT8) 5);
+  }
+
+  if (*Parity == DefaultParity) {
+    LcrParity = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7);
+    switch (LcrParity) {
+      case 0:
+        *Parity = NoParity;
+        break;
+
+      case 3:
+        *Parity = EvenParity;
+        break;
+
+      case 1:
+        *Parity = OddParity;
+        break;
+
+      case 7:
+        *Parity = SpaceParity;
+        break;
+
+      case 5:
+        *Parity = MarkParity;
+        break;
+
+      default:
+        break;
+    }
+  } else {
+    switch (*Parity) {
+      case NoParity:
+        LcrParity = 0;
+        break;
+
+      case EvenParity:
+        LcrParity = 3;
+        break;
+
+      case OddParity:
+        LcrParity = 1;
+        break;
+
+      case SpaceParity:
+        LcrParity = 7;
+        break;
+
+      case MarkParity:
+        LcrParity = 5;
+        break;
+
+      default:
+        return RETURN_INVALID_PARAMETER;
+    }
+  }
+
+  if (*StopBits == DefaultStopBits) {
+    LcrStop = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1);
+    switch (LcrStop) {
+      case 0:
+        *StopBits = OneStopBit;
+        break;
+
+      case 1:
+        if (*DataBits == 5) {
+          *StopBits = OneFiveStopBits;
+        } else {
+          *StopBits = TwoStopBits;
+        }
+        break;
+
+      default:
+        break;
+    }
+  } else {
+    switch (*StopBits) {
+      case OneStopBit:
+        LcrStop = 0;
+        break;
+
+      case OneFiveStopBits:
+      case TwoStopBits:
+        LcrStop = 1;
+        break;
+
+      default:
+        return RETURN_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Calculate divisor for baud generator
+  //    Ref_Clk_Rate / Baud_Rate / 16
+  //
+  Divisor = PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16);
+  if ((PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >= SerialBaudRate * 8) {
+    Divisor++;
+  }
+
+  //
+  // Configure baud rate
+  //
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB);
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8));
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff));
+
+  //
+  // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
+  // Strip reserved bits from line control value
+  //
+  Lcr = (UINT8) ((LcrParity << 3) | (LcrStop << 2) | LcrData);
+  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8) (Lcr & 0x3F));
+
+  return RETURN_SUCCESS;
+}
+
diff --git a/CorebootModulePkg/SataControllerDxe/SataController.h b/CorebootModulePkg/SataControllerDxe/SataController.h
index 1ef4555615..d13ab889d9 100644
--- a/CorebootModulePkg/SataControllerDxe/SataController.h
+++ b/CorebootModulePkg/SataControllerDxe/SataController.h
@@ -1,542 +1,542 @@
-/** @file
-  Header file for Sata Controller driver.
-
-  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef _SATA_CONTROLLER_H_
-#define _SATA_CONTROLLER_H_
-
-#include <Uefi.h>
-#include <Protocol/ComponentName.h>
-#include <Protocol/DriverBinding.h>
-#include <Protocol/PciIo.h>
-#include <Protocol/IdeControllerInit.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiLib.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <IndustryStandard/Pci.h>
-
-//
-// Global Variables definitions
-//
-extern EFI_DRIVER_BINDING_PROTOCOL  gSataControllerDriverBinding;
-extern EFI_COMPONENT_NAME_PROTOCOL  gSataControllerComponentName;
-extern EFI_COMPONENT_NAME2_PROTOCOL gSataControllerComponentName2;
-
-#define AHCI_BAR_INDEX 0x05
-#define R_AHCI_CAP 0x0
-#define   B_AHCI_CAP_NPS (BIT4 | BIT3 | BIT2 | BIT1 | BIT0) // Number of Ports
-#define   B_AHCI_CAP_SPM BIT17 // Supports Port Multiplier
-
-///
-/// AHCI each channel can have up to 1 device
-///
-#define AHCI_MAX_DEVICES 0x01
-
-///
-/// AHCI each channel can have 15 devices in the presence of a multiplier
-///
-#define AHCI_MULTI_MAX_DEVICES 0x0F
-
-///
-/// IDE supports 2 channel max
-///
-#define IDE_MAX_CHANNEL 0x02
-
-///
-/// IDE supports 2 devices max
-///
-#define IDE_MAX_DEVICES 0x02
-
-#define SATA_ENUMER_ALL FALSE
-
-//
-// Sata Controller driver private data structure
-//
-
-#define SATA_CONTROLLER_SIGNATURE SIGNATURE_32('S','A','T','A')
-
-typedef struct _EFI_SATA_CONTROLLER_PRIVATE_DATA {
-  //
-  // Standard signature used to identify Sata Controller private data
-  //
-  UINT32                            Signature;
-
-  //
-  // Protocol instance of IDE_CONTROLLER_INIT produced by this driver
-  //
-  EFI_IDE_CONTROLLER_INIT_PROTOCOL  IdeInit;
-
-  //
-  // Copy of protocol pointers used by this driver
-  //
-  EFI_PCI_IO_PROTOCOL               *PciIo;
-
-  //
-  // The number of devices that are supported by this channel
-  //
-  UINT8                             DeviceCount;
-
-  //
+/** @file
+  Header file for Sata Controller driver.
+
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SATA_CONTROLLER_H_
+#define _SATA_CONTROLLER_H_
+
+#include <Uefi.h>
+#include <Protocol/ComponentName.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/IdeControllerInit.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <IndustryStandard/Pci.h>
+
+//
+// Global Variables definitions
+//
+extern EFI_DRIVER_BINDING_PROTOCOL  gSataControllerDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL  gSataControllerComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gSataControllerComponentName2;
+
+#define AHCI_BAR_INDEX 0x05
+#define R_AHCI_CAP 0x0
+#define   B_AHCI_CAP_NPS (BIT4 | BIT3 | BIT2 | BIT1 | BIT0) // Number of Ports
+#define   B_AHCI_CAP_SPM BIT17 // Supports Port Multiplier
+
+///
+/// AHCI each channel can have up to 1 device
+///
+#define AHCI_MAX_DEVICES 0x01
+
+///
+/// AHCI each channel can have 15 devices in the presence of a multiplier
+///
+#define AHCI_MULTI_MAX_DEVICES 0x0F
+
+///
+/// IDE supports 2 channel max
+///
+#define IDE_MAX_CHANNEL 0x02
+
+///
+/// IDE supports 2 devices max
+///
+#define IDE_MAX_DEVICES 0x02
+
+#define SATA_ENUMER_ALL FALSE
+
+//
+// Sata Controller driver private data structure
+//
+
+#define SATA_CONTROLLER_SIGNATURE SIGNATURE_32('S','A','T','A')
+
+typedef struct _EFI_SATA_CONTROLLER_PRIVATE_DATA {
+  //
+  // Standard signature used to identify Sata Controller private data
+  //
+  UINT32                            Signature;
+
+  //
+  // Protocol instance of IDE_CONTROLLER_INIT produced by this driver
+  //
+  EFI_IDE_CONTROLLER_INIT_PROTOCOL  IdeInit;
+
+  //
+  // Copy of protocol pointers used by this driver
+  //
+  EFI_PCI_IO_PROTOCOL               *PciIo;
+
+  //
+  // The number of devices that are supported by this channel
+  //
+  UINT8                             DeviceCount;
+
+  //
   // The highest disqualified mode for each attached device,
-  // From ATA/ATAPI spec, if a mode is not supported,
-  // the modes higher than it is also not supported
-  //
-  EFI_ATA_COLLECTIVE_MODE           *DisqualifiedModes;
-
-  //
-  // A copy of EFI_IDENTIFY_DATA data for each attached SATA device and its flag
-  //
-  EFI_IDENTIFY_DATA                 *IdentifyData;
-  BOOLEAN                           *IdentifyValid;
-} EFI_SATA_CONTROLLER_PRIVATE_DATA;
-
-#define SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS(a) CR(a, EFI_SATA_CONTROLLER_PRIVATE_DATA, IdeInit, SATA_CONTROLLER_SIGNATURE)
-
-//
-// Driver binding functions declaration
-//
-/**
-  Supported function of Driver Binding protocol for this driver.
-  Test to see if this driver supports ControllerHandle.
-
-  @param This                   Protocol instance pointer.
-  @param Controller             Handle of device to test.
-  @param RemainingDevicePath    A pointer to the device path. Should be ignored by
-                                device driver.
-
-  @retval EFI_SUCCESS           This driver supports this device.
-  @retval EFI_ALREADY_STARTED   This driver is already running on this device.
-  @retval other                 This driver does not support this device.
-
-**/
-EFI_STATUS
-EFIAPI
-SataControllerSupported (
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
-  IN EFI_HANDLE                     Controller,
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
-  )
-;
-
-/**
-  This routine is called right after the .Supported() called and 
-  Start this driver on ControllerHandle.
-
-  @param This                   Protocol instance pointer.
-  @param Controller             Handle of device to bind driver to.
-  @param RemainingDevicePath    A pointer to the device path. Should be ignored by
-                                device driver.
-
-  @retval EFI_SUCCESS           This driver is added to this device.
-  @retval EFI_ALREADY_STARTED   This driver is already running on this device.
-  @retval other                 Some error occurs when binding this driver to this device.
-
-**/
-EFI_STATUS
-EFIAPI
-SataControllerStart (
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
-  IN EFI_HANDLE                     Controller,
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
-  )
-;
-
-/**
-  Stop this driver on ControllerHandle.
-
-  @param This               Protocol instance pointer.
-  @param Controller         Handle of device to stop driver on.
-  @param NumberOfChildren   Not used.
-  @param ChildHandleBuffer  Not used.
-
-  @retval EFI_SUCCESS   This driver is removed from this device.
-  @retval other         Some error occurs when removing this driver from this device.
-
-**/
-EFI_STATUS
-EFIAPI
-SataControllerStop (
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
-  IN EFI_HANDLE                     Controller,
-  IN UINTN                          NumberOfChildren,
-  IN EFI_HANDLE                     *ChildHandleBuffer
-  )
-;
-
-//
-// IDE controller init functions declaration
-//
-/**
-  Returns the information about the specified IDE channel.
-  
-  This function can be used to obtain information about a particular IDE channel.
-  The driver entity uses this information during the enumeration process. 
-  
-  If Enabled is set to FALSE, the driver entity will not scan the channel. Note 
-  that it will not prevent an operating system driver from scanning the channel.
-  
-  For most of today's controllers, MaxDevices will either be 1 or 2. For SATA 
-  controllers, this value will always be 1. SATA configurations can contain SATA 
-  port multipliers. SATA port multipliers behave like SATA bridges and can support
-  up to 16 devices on the other side. If a SATA port out of the IDE controller 
-  is connected to a port multiplier, MaxDevices will be set to the number of SATA 
-  devices that the port multiplier supports. Because today's port multipliers 
-  support up to fifteen SATA devices, this number can be as large as fifteen. The IDE  
-  bus driver is required to scan for the presence of port multipliers behind an SATA 
-  controller and enumerate up to MaxDevices number of devices behind the port 
-  multiplier.    
-  
-  In this context, the devices behind a port multiplier constitute a channel.  
-  
-  @param[in]  This         The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
-  @param[in]  Channel      Zero-based channel number.
-  @param[out] Enabled      TRUE if this channel is enabled.  Disabled channels 
-                           are not scanned to see if any devices are present.
-  @param[out] MaxDevices   The maximum number of IDE devices that the bus driver
-                           can expect on this channel.  For the ATA/ATAPI 
-                           specification, version 6, this number will either be 
-                           one or two. For Serial ATA (SATA) configurations with a 
-                           port multiplier, this number can be as large as fifteen.
-
-  @retval EFI_SUCCESS             Information was returned without any errors.
-  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
-
-**/
-EFI_STATUS
-EFIAPI
-IdeInitGetChannelInfo (
-  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
-  IN UINT8                              Channel,
-  OUT BOOLEAN                           *Enabled,
-  OUT UINT8                             *MaxDevices
-  )
-;
-
-/**
-  The notifications from the driver entity that it is about to enter a certain
-  phase of the IDE channel enumeration process.
-  
-  This function can be used to notify the IDE controller driver to perform 
-  specific actions, including any chipset-specific initialization, so that the 
-  chipset is ready to enter the next phase. Seven notification points are defined 
-  at this time. 
-  
-  More synchronization points may be added as required in the future.  
-
-  @param[in] This      The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
-  @param[in] Phase     The phase during enumeration.
-  @param[in] Channel   Zero-based channel number.
-
-  @retval EFI_SUCCESS             The notification was accepted without any errors.
-  @retval EFI_UNSUPPORTED         Phase is not supported.
-  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
-  @retval EFI_NOT_READY           This phase cannot be entered at this time; for 
-                                  example, an attempt was made to enter a Phase 
-                                  without having entered one or more previous 
-                                  Phase.
-
-**/
-EFI_STATUS
-EFIAPI
-IdeInitNotifyPhase (
-  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
-  IN EFI_IDE_CONTROLLER_ENUM_PHASE      Phase,
-  IN UINT8                              Channel
-  )
-;
-
-/**
-  Submits the device information to the IDE controller driver.
-
-  This function is used by the driver entity to pass detailed information about 
-  a particular device to the IDE controller driver. The driver entity obtains 
-  this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData
-  is the pointer to the response data buffer. The IdentifyData buffer is owned 
-  by the driver entity, and the IDE controller driver must make a local copy 
-  of the entire buffer or parts of the buffer as needed. The original IdentifyData 
-  buffer pointer may not be valid when
-  
-    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or
-    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point.
-    
-  The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to 
-  compute the optimum mode for the device. These fields are not limited to the 
-  timing information. For example, an implementation of the IDE controller driver 
-  may examine the vendor and type/mode field to match known bad drives.  
-  
-  The driver entity may submit drive information in any order, as long as it 
-  submits information for all the devices belonging to the enumeration group 
-  before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device
-  in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
-  should be called with IdentifyData set to NULL.  The IDE controller driver may 
-  not have any other mechanism to know whether a device is present or not. Therefore, 
-  setting IdentifyData to NULL does not constitute an error condition. 
-  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a 
-  given (Channel, Device) pair.  
-    
-  @param[in] This           A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
-  @param[in] Channel        Zero-based channel number.
-  @param[in] Device         Zero-based device number on the Channel.
-  @param[in] IdentifyData   The device's response to the ATA IDENTIFY_DEVICE command.
-
-  @retval EFI_SUCCESS             The information was accepted without any errors.
-  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
-  @retval EFI_INVALID_PARAMETER   Device is invalid.
-
-**/
-EFI_STATUS
-EFIAPI
-IdeInitSubmitData (
-  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
-  IN UINT8                              Channel,
-  IN UINT8                              Device,
-  IN EFI_IDENTIFY_DATA                  *IdentifyData
-  )
-;
-
-/**
-  Disqualifies specific modes for an IDE device.
-
-  This function allows the driver entity or other drivers (such as platform 
-  drivers) to reject certain timing modes and request the IDE controller driver
-  to recalculate modes. This function allows the driver entity and the IDE 
-  controller driver to negotiate the timings on a per-device basis. This function 
-  is useful in the case of drives that lie about their capabilities. An example 
-  is when the IDE device fails to accept the timing modes that are calculated 
-  by the IDE controller driver based on the response to the Identify Drive command.
-
-  If the driver entity does not want to limit the ATA timing modes and leave that 
-  decision to the IDE controller driver, it can either not call this function for 
-  the given device or call this function and set the Valid flag to FALSE for all 
-  modes that are listed in EFI_ATA_COLLECTIVE_MODE.
-  
-  The driver entity may disqualify modes for a device in any order and any number 
-  of times.
-  
-  This function can be called multiple times to invalidate multiple modes of the 
-  same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI 
-  specification for more information on PIO modes.  
-  
-  For Serial ATA (SATA) controllers, this member function can be used to disqualify
-  a higher transfer rate mode on a given channel. For example, a platform driver
-  may inform the IDE controller driver to not use second-generation (Gen2) speeds 
-  for a certain SATA drive.
-  
-  @param[in] This       The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
-  @param[in] Channel    The zero-based channel number.
-  @param[in] Device     The zero-based device number on the Channel.
-  @param[in] BadModes   The modes that the device does not support and that
-                        should be disqualified.
-
-  @retval EFI_SUCCESS             The modes were accepted without any errors.
-  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
-  @retval EFI_INVALID_PARAMETER   Device is invalid.
-  @retval EFI_INVALID_PARAMETER   IdentifyData is NULL.
-                                
-**/
-EFI_STATUS
-EFIAPI
-IdeInitDisqualifyMode (
-  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
-  IN UINT8                              Channel,
-  IN UINT8                              Device,
-  IN EFI_ATA_COLLECTIVE_MODE            *BadModes
-  )
-;
-
-/**
-  Returns the information about the optimum modes for the specified IDE device.
-
-  This function is used by the driver entity to obtain the optimum ATA modes for
-  a specific device.  The IDE controller driver takes into account the following 
-  while calculating the mode:
-    - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
-    - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()
-
-  The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() 
-  for all the devices that belong to an enumeration group before calling 
-  EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group.  
-  
-  The IDE controller driver will use controller- and possibly platform-specific 
-  algorithms to arrive at SupportedModes.  The IDE controller may base its 
-  decision on user preferences and other considerations as well. This function 
-  may be called multiple times because the driver entity may renegotiate the mode 
-  with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().
-    
-  The driver entity may collect timing information for various devices in any 
-  order. The driver entity is responsible for making sure that all the dependencies
-  are satisfied. For example, the SupportedModes information for device A that 
-  was previously returned may become stale after a call to 
-  EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.
-  
-  The buffer SupportedModes is allocated by the callee because the caller does 
-  not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE 
-  is defined in a way that allows for future extensibility and can be of variable 
-  length. This memory pool should be deallocated by the caller when it is no 
-  longer necessary.  
-  
-  The IDE controller driver for a Serial ATA (SATA) controller can use this 
-  member function to force a lower speed (first-generation [Gen1] speeds on a 
-  second-generation [Gen2]-capable hardware).  The IDE controller driver can 
-  also allow the driver entity to stay with the speed that has been negotiated 
-  by the physical layer.
-  
-  @param[in]  This             The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
-  @param[in]  Channel          A zero-based channel number.
-  @param[in]  Device           A zero-based device number on the Channel.
-  @param[out] SupportedModes   The optimum modes for the device.
-
-  @retval EFI_SUCCESS             SupportedModes was returned.
-  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
-  @retval EFI_INVALID_PARAMETER   Device is invalid. 
-  @retval EFI_INVALID_PARAMETER   SupportedModes is NULL.
-  @retval EFI_NOT_READY           Modes cannot be calculated due to a lack of 
-                                  data.  This error may happen if 
-                                  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() 
-                                  and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData() 
-                                  were not called for at least one drive in the 
-                                  same enumeration group.
-
-**/
-EFI_STATUS
-EFIAPI
-IdeInitCalculateMode (
-  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
-  IN UINT8                              Channel,
-  IN UINT8                              Device,
-  OUT EFI_ATA_COLLECTIVE_MODE           **SupportedModes
-  )
-;
-
-/**
-  Commands the IDE controller driver to program the IDE controller hardware
-  so that the specified device can operate at the specified mode.
-
-  This function is used by the driver entity to instruct the IDE controller 
-  driver to program the IDE controller hardware to the specified modes. This 
-  function can be called only once for a particular device. For a Serial ATA 
-  (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-
-  specific programming may be required.
-
-  @param[in] This      Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
-  @param[in] Channel   Zero-based channel number.
-  @param[in] Device    Zero-based device number on the Channel.
-  @param[in] Modes     The modes to set.
-
-  @retval EFI_SUCCESS             The command was accepted without any errors.
-  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
-  @retval EFI_INVALID_PARAMETER   Device is invalid.
-  @retval EFI_NOT_READY           Modes cannot be set at this time due to lack of data.
-  @retval EFI_DEVICE_ERROR        Modes cannot be set due to hardware failure.
-                                  The driver entity should not use this device.
-
-**/
-EFI_STATUS
-EFIAPI
-IdeInitSetTiming (
-  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
-  IN UINT8                              Channel,
-  IN UINT8                              Device,
-  IN EFI_ATA_COLLECTIVE_MODE            *Modes
-  )
-;
-
-//
-// Forward reference declaration
-//
-/**
-  Retrieves a Unicode string that is the user readable name of the UEFI Driver.
-
-  @param This           A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param Language       A pointer to a three character ISO 639-2 language identifier.
-                        This is the language of the driver name that that the caller
-                        is requesting, and it must match one of the languages specified
-                        in SupportedLanguages.  The number of languages supported by a
-                        driver is up to the driver writer.
-  @param DriverName     A pointer to the Unicode string to return.  This Unicode string
-                        is the name of the driver specified by This in the language
-                        specified by Language.
-
-  @retval EFI_SUCCESS           The Unicode string for the Driver specified by This
-                                and the language specified by Language was returned
-                                in DriverName.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER DriverName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support the
-                                language specified by Language.
-**/
-EFI_STATUS
-EFIAPI
-SataControllerComponentNameGetDriverName (
-  IN EFI_COMPONENT_NAME_PROTOCOL    *This,
-  IN CHAR8                          *Language,
-  OUT CHAR16                        **DriverName
-  )
-;
-
-/**
-  Retrieves a Unicode string that is the user readable name of the controller
-  that is being managed by an UEFI Driver.
-
-  @param This                   A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param ControllerHandle       The handle of a controller that the driver specified by
-                                This is managing.  This handle specifies the controller
-                                whose name is to be returned.
-  @param OPTIONAL   ChildHandle The handle of the child controller to retrieve the name
-                                of.  This is an optional parameter that may be NULL.  It
-                                will be NULL for device drivers.  It will also be NULL
-                                for a bus drivers that wish to retrieve the name of the
-                                bus controller.  It will not be NULL for a bus driver
-                                that wishes to retrieve the name of a child controller.
-  @param Language               A pointer to a three character ISO 639-2 language
-                                identifier.  This is the language of the controller name
-                                that that the caller is requesting, and it must match one
-                                of the languages specified in SupportedLanguages.  The
-                                number of languages supported by a driver is up to the
-                                driver writer.
-  @param ControllerName         A pointer to the Unicode string to return.  This Unicode
-                                string is the name of the controller specified by
-                                ControllerHandle and ChildHandle in the language
-                                specified by Language from the point of view of the
-                                driver specified by This.
-
-  @retval EFI_SUCCESS           The Unicode string for the user readable name in the
-                                language specified by Language for the driver
-                                specified by This was returned in DriverName.
-  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
-                                EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
-                                managing the controller specified by
-                                ControllerHandle and ChildHandle.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support the
-                                language specified by Language.
-**/
-EFI_STATUS
-EFIAPI
-SataControllerComponentNameGetControllerName (
-  IN EFI_COMPONENT_NAME_PROTOCOL    *This,
-  IN EFI_HANDLE                     ControllerHandle,
-  IN EFI_HANDLE                     ChildHandle OPTIONAL,
-  IN CHAR8                          *Language,
-  OUT CHAR16                        **ControllerName
-  )
-;
-
-#endif
+  // From ATA/ATAPI spec, if a mode is not supported,
+  // the modes higher than it is also not supported
+  //
+  EFI_ATA_COLLECTIVE_MODE           *DisqualifiedModes;
+
+  //
+  // A copy of EFI_IDENTIFY_DATA data for each attached SATA device and its flag
+  //
+  EFI_IDENTIFY_DATA                 *IdentifyData;
+  BOOLEAN                           *IdentifyValid;
+} EFI_SATA_CONTROLLER_PRIVATE_DATA;
+
+#define SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS(a) CR(a, EFI_SATA_CONTROLLER_PRIVATE_DATA, IdeInit, SATA_CONTROLLER_SIGNATURE)
+
+//
+// Driver binding functions declaration
+//
+/**
+  Supported function of Driver Binding protocol for this driver.
+  Test to see if this driver supports ControllerHandle.
+
+  @param This                   Protocol instance pointer.
+  @param Controller             Handle of device to test.
+  @param RemainingDevicePath    A pointer to the device path. Should be ignored by
+                                device driver.
+
+  @retval EFI_SUCCESS           This driver supports this device.
+  @retval EFI_ALREADY_STARTED   This driver is already running on this device.
+  @retval other                 This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+SataControllerSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+;
+
+/**
+  This routine is called right after the .Supported() called and
+  Start this driver on ControllerHandle.
+
+  @param This                   Protocol instance pointer.
+  @param Controller             Handle of device to bind driver to.
+  @param RemainingDevicePath    A pointer to the device path. Should be ignored by
+                                device driver.
+
+  @retval EFI_SUCCESS           This driver is added to this device.
+  @retval EFI_ALREADY_STARTED   This driver is already running on this device.
+  @retval other                 Some error occurs when binding this driver to this device.
+
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+;
+
+/**
+  Stop this driver on ControllerHandle.
+
+  @param This               Protocol instance pointer.
+  @param Controller         Handle of device to stop driver on.
+  @param NumberOfChildren   Not used.
+  @param ChildHandleBuffer  Not used.
+
+  @retval EFI_SUCCESS   This driver is removed from this device.
+  @retval other         Some error occurs when removing this driver from this device.
+
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN UINTN                          NumberOfChildren,
+  IN EFI_HANDLE                     *ChildHandleBuffer
+  )
+;
+
+//
+// IDE controller init functions declaration
+//
+/**
+  Returns the information about the specified IDE channel.
+
+  This function can be used to obtain information about a particular IDE channel.
+  The driver entity uses this information during the enumeration process.
+
+  If Enabled is set to FALSE, the driver entity will not scan the channel. Note
+  that it will not prevent an operating system driver from scanning the channel.
+
+  For most of today's controllers, MaxDevices will either be 1 or 2. For SATA
+  controllers, this value will always be 1. SATA configurations can contain SATA
+  port multipliers. SATA port multipliers behave like SATA bridges and can support
+  up to 16 devices on the other side. If a SATA port out of the IDE controller
+  is connected to a port multiplier, MaxDevices will be set to the number of SATA
+  devices that the port multiplier supports. Because today's port multipliers
+  support up to fifteen SATA devices, this number can be as large as fifteen. The IDE
+  bus driver is required to scan for the presence of port multipliers behind an SATA
+  controller and enumerate up to MaxDevices number of devices behind the port
+  multiplier.
+
+  In this context, the devices behind a port multiplier constitute a channel.
+
+  @param[in]  This         The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+  @param[in]  Channel      Zero-based channel number.
+  @param[out] Enabled      TRUE if this channel is enabled.  Disabled channels
+                           are not scanned to see if any devices are present.
+  @param[out] MaxDevices   The maximum number of IDE devices that the bus driver
+                           can expect on this channel.  For the ATA/ATAPI
+                           specification, version 6, this number will either be
+                           one or two. For Serial ATA (SATA) configurations with a
+                           port multiplier, this number can be as large as fifteen.
+
+  @retval EFI_SUCCESS             Information was returned without any errors.
+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
+
+**/
+EFI_STATUS
+EFIAPI
+IdeInitGetChannelInfo (
+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
+  IN UINT8                              Channel,
+  OUT BOOLEAN                           *Enabled,
+  OUT UINT8                             *MaxDevices
+  )
+;
+
+/**
+  The notifications from the driver entity that it is about to enter a certain
+  phase of the IDE channel enumeration process.
+
+  This function can be used to notify the IDE controller driver to perform
+  specific actions, including any chipset-specific initialization, so that the
+  chipset is ready to enter the next phase. Seven notification points are defined
+  at this time.
+
+  More synchronization points may be added as required in the future.
+
+  @param[in] This      The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+  @param[in] Phase     The phase during enumeration.
+  @param[in] Channel   Zero-based channel number.
+
+  @retval EFI_SUCCESS             The notification was accepted without any errors.
+  @retval EFI_UNSUPPORTED         Phase is not supported.
+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
+  @retval EFI_NOT_READY           This phase cannot be entered at this time; for
+                                  example, an attempt was made to enter a Phase
+                                  without having entered one or more previous
+                                  Phase.
+
+**/
+EFI_STATUS
+EFIAPI
+IdeInitNotifyPhase (
+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
+  IN EFI_IDE_CONTROLLER_ENUM_PHASE      Phase,
+  IN UINT8                              Channel
+  )
+;
+
+/**
+  Submits the device information to the IDE controller driver.
+
+  This function is used by the driver entity to pass detailed information about
+  a particular device to the IDE controller driver. The driver entity obtains
+  this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData
+  is the pointer to the response data buffer. The IdentifyData buffer is owned
+  by the driver entity, and the IDE controller driver must make a local copy
+  of the entire buffer or parts of the buffer as needed. The original IdentifyData
+  buffer pointer may not be valid when
+
+    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or
+    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point.
+
+  The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to
+  compute the optimum mode for the device. These fields are not limited to the
+  timing information. For example, an implementation of the IDE controller driver
+  may examine the vendor and type/mode field to match known bad drives.
+
+  The driver entity may submit drive information in any order, as long as it
+  submits information for all the devices belonging to the enumeration group
+  before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device
+  in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
+  should be called with IdentifyData set to NULL.  The IDE controller driver may
+  not have any other mechanism to know whether a device is present or not. Therefore,
+  setting IdentifyData to NULL does not constitute an error condition.
+  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a
+  given (Channel, Device) pair.
+
+  @param[in] This           A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+  @param[in] Channel        Zero-based channel number.
+  @param[in] Device         Zero-based device number on the Channel.
+  @param[in] IdentifyData   The device's response to the ATA IDENTIFY_DEVICE command.
+
+  @retval EFI_SUCCESS             The information was accepted without any errors.
+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
+  @retval EFI_INVALID_PARAMETER   Device is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSubmitData (
+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
+  IN UINT8                              Channel,
+  IN UINT8                              Device,
+  IN EFI_IDENTIFY_DATA                  *IdentifyData
+  )
+;
+
+/**
+  Disqualifies specific modes for an IDE device.
+
+  This function allows the driver entity or other drivers (such as platform
+  drivers) to reject certain timing modes and request the IDE controller driver
+  to recalculate modes. This function allows the driver entity and the IDE
+  controller driver to negotiate the timings on a per-device basis. This function
+  is useful in the case of drives that lie about their capabilities. An example
+  is when the IDE device fails to accept the timing modes that are calculated
+  by the IDE controller driver based on the response to the Identify Drive command.
+
+  If the driver entity does not want to limit the ATA timing modes and leave that
+  decision to the IDE controller driver, it can either not call this function for
+  the given device or call this function and set the Valid flag to FALSE for all
+  modes that are listed in EFI_ATA_COLLECTIVE_MODE.
+
+  The driver entity may disqualify modes for a device in any order and any number
+  of times.
+
+  This function can be called multiple times to invalidate multiple modes of the
+  same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI
+  specification for more information on PIO modes.
+
+  For Serial ATA (SATA) controllers, this member function can be used to disqualify
+  a higher transfer rate mode on a given channel. For example, a platform driver
+  may inform the IDE controller driver to not use second-generation (Gen2) speeds
+  for a certain SATA drive.
+
+  @param[in] This       The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+  @param[in] Channel    The zero-based channel number.
+  @param[in] Device     The zero-based device number on the Channel.
+  @param[in] BadModes   The modes that the device does not support and that
+                        should be disqualified.
+
+  @retval EFI_SUCCESS             The modes were accepted without any errors.
+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
+  @retval EFI_INVALID_PARAMETER   Device is invalid.
+  @retval EFI_INVALID_PARAMETER   IdentifyData is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+IdeInitDisqualifyMode (
+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
+  IN UINT8                              Channel,
+  IN UINT8                              Device,
+  IN EFI_ATA_COLLECTIVE_MODE            *BadModes
+  )
+;
+
+/**
+  Returns the information about the optimum modes for the specified IDE device.
+
+  This function is used by the driver entity to obtain the optimum ATA modes for
+  a specific device.  The IDE controller driver takes into account the following
+  while calculating the mode:
+    - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
+    - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()
+
+  The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
+  for all the devices that belong to an enumeration group before calling
+  EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group.
+
+  The IDE controller driver will use controller- and possibly platform-specific
+  algorithms to arrive at SupportedModes.  The IDE controller may base its
+  decision on user preferences and other considerations as well. This function
+  may be called multiple times because the driver entity may renegotiate the mode
+  with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().
+
+  The driver entity may collect timing information for various devices in any
+  order. The driver entity is responsible for making sure that all the dependencies
+  are satisfied. For example, the SupportedModes information for device A that
+  was previously returned may become stale after a call to
+  EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.
+
+  The buffer SupportedModes is allocated by the callee because the caller does
+  not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE
+  is defined in a way that allows for future extensibility and can be of variable
+  length. This memory pool should be deallocated by the caller when it is no
+  longer necessary.
+
+  The IDE controller driver for a Serial ATA (SATA) controller can use this
+  member function to force a lower speed (first-generation [Gen1] speeds on a
+  second-generation [Gen2]-capable hardware).  The IDE controller driver can
+  also allow the driver entity to stay with the speed that has been negotiated
+  by the physical layer.
+
+  @param[in]  This             The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+  @param[in]  Channel          A zero-based channel number.
+  @param[in]  Device           A zero-based device number on the Channel.
+  @param[out] SupportedModes   The optimum modes for the device.
+
+  @retval EFI_SUCCESS             SupportedModes was returned.
+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
+  @retval EFI_INVALID_PARAMETER   Device is invalid.
+  @retval EFI_INVALID_PARAMETER   SupportedModes is NULL.
+  @retval EFI_NOT_READY           Modes cannot be calculated due to a lack of
+                                  data.  This error may happen if
+                                  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
+                                  and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData()
+                                  were not called for at least one drive in the
+                                  same enumeration group.
+
+**/
+EFI_STATUS
+EFIAPI
+IdeInitCalculateMode (
+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
+  IN UINT8                              Channel,
+  IN UINT8                              Device,
+  OUT EFI_ATA_COLLECTIVE_MODE           **SupportedModes
+  )
+;
+
+/**
+  Commands the IDE controller driver to program the IDE controller hardware
+  so that the specified device can operate at the specified mode.
+
+  This function is used by the driver entity to instruct the IDE controller
+  driver to program the IDE controller hardware to the specified modes. This
+  function can be called only once for a particular device. For a Serial ATA
+  (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-
+  specific programming may be required.
+
+  @param[in] This      Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+  @param[in] Channel   Zero-based channel number.
+  @param[in] Device    Zero-based device number on the Channel.
+  @param[in] Modes     The modes to set.
+
+  @retval EFI_SUCCESS             The command was accepted without any errors.
+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
+  @retval EFI_INVALID_PARAMETER   Device is invalid.
+  @retval EFI_NOT_READY           Modes cannot be set at this time due to lack of data.
+  @retval EFI_DEVICE_ERROR        Modes cannot be set due to hardware failure.
+                                  The driver entity should not use this device.
+
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSetTiming (
+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
+  IN UINT8                              Channel,
+  IN UINT8                              Device,
+  IN EFI_ATA_COLLECTIVE_MODE            *Modes
+  )
+;
+
+//
+// Forward reference declaration
+//
+/**
+  Retrieves a Unicode string that is the user readable name of the UEFI Driver.
+
+  @param This           A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param Language       A pointer to a three character ISO 639-2 language identifier.
+                        This is the language of the driver name that that the caller
+                        is requesting, and it must match one of the languages specified
+                        in SupportedLanguages.  The number of languages supported by a
+                        driver is up to the driver writer.
+  @param DriverName     A pointer to the Unicode string to return.  This Unicode string
+                        is the name of the driver specified by This in the language
+                        specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by This
+                                and the language specified by Language was returned
+                                in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the
+                                language specified by Language.
+**/
+EFI_STATUS
+EFIAPI
+SataControllerComponentNameGetDriverName (
+  IN EFI_COMPONENT_NAME_PROTOCOL    *This,
+  IN CHAR8                          *Language,
+  OUT CHAR16                        **DriverName
+  )
+;
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by an UEFI Driver.
+
+  @param This                   A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param ControllerHandle       The handle of a controller that the driver specified by
+                                This is managing.  This handle specifies the controller
+                                whose name is to be returned.
+  @param OPTIONAL   ChildHandle The handle of the child controller to retrieve the name
+                                of.  This is an optional parameter that may be NULL.  It
+                                will be NULL for device drivers.  It will also be NULL
+                                for a bus drivers that wish to retrieve the name of the
+                                bus controller.  It will not be NULL for a bus driver
+                                that wishes to retrieve the name of a child controller.
+  @param Language               A pointer to a three character ISO 639-2 language
+                                identifier.  This is the language of the controller name
+                                that that the caller is requesting, and it must match one
+                                of the languages specified in SupportedLanguages.  The
+                                number of languages supported by a driver is up to the
+                                driver writer.
+  @param ControllerName         A pointer to the Unicode string to return.  This Unicode
+                                string is the name of the controller specified by
+                                ControllerHandle and ChildHandle in the language
+                                specified by Language from the point of view of the
+                                driver specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in the
+                                language specified by Language for the driver
+                                specified by This was returned in DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the
+                                language specified by Language.
+**/
+EFI_STATUS
+EFIAPI
+SataControllerComponentNameGetControllerName (
+  IN EFI_COMPONENT_NAME_PROTOCOL    *This,
+  IN EFI_HANDLE                     ControllerHandle,
+  IN EFI_HANDLE                     ChildHandle OPTIONAL,
+  IN CHAR8                          *Language,
+  OUT CHAR16                        **ControllerName
+  )
+;
+
+#endif
diff --git a/CorebootModulePkg/SecCore/Ia32/Stack.S b/CorebootModulePkg/SecCore/Ia32/Stack.S
index 6a8e0e4b15..1900a8c54a 100644
--- a/CorebootModulePkg/SecCore/Ia32/Stack.S
+++ b/CorebootModulePkg/SecCore/Ia32/Stack.S
@@ -1,78 +1,78 @@
-#------------------------------------------------------------------------------
-#
-# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution.  The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php.
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-# Abstract:
-#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Abstract:
+#
 #   Switch the stack from temporary memory to permanent memory.
-#
-#------------------------------------------------------------------------------
-
-
-#------------------------------------------------------------------------------
-# VOID
-# EFIAPI
-# SecSwitchStack (
-#   UINT32   TemporaryMemoryBase,
-#   UINT32   PermenentMemoryBase
-#   )#
-#------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX (SecSwitchStack)
-ASM_PFX(SecSwitchStack):
-    #
-    # Save standard registers so they can be used to change stack
-    #
-    pushl %eax
-    pushl %ebx
-    pushl %ecx
-    pushl %edx
-
-    #
-    # !!CAUTION!! this function address's is pushed into stack after
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# SecSwitchStack (
+#   UINT32   TemporaryMemoryBase,
+#   UINT32   PermenentMemoryBase
+#   )#
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX (SecSwitchStack)
+ASM_PFX(SecSwitchStack):
+    #
+    # Save standard registers so they can be used to change stack
+    #
+    pushl %eax
+    pushl %ebx
+    pushl %ecx
+    pushl %edx
+
+    #
+    # !!CAUTION!! this function address's is pushed into stack after
     # migration of whole temporary memory, so need save it to permanent
-    # memory at first!
-    #
-    movl  20(%esp), %ebx         # Save the first parameter
-    movl  24(%esp), %ecx         # Save the second parameter
-
-    #
+    # memory at first!
+    #
+    movl  20(%esp), %ebx         # Save the first parameter
+    movl  24(%esp), %ecx         # Save the second parameter
+
+    #
     # Save this function's return address into permanent memory at first.
     # Then, Fixup the esp point to permanent memory
-    #
-    movl  %esp, %eax
-    subl  %ebx, %eax
-    addl  %ecx, %eax
+    #
+    movl  %esp, %eax
+    subl  %ebx, %eax
+    addl  %ecx, %eax
     movl  0(%esp), %edx          # copy pushed register's value to permanent memory
-    movl  %edx, 0(%eax)
-    movl  4(%esp), %edx
-    movl  %edx, 4(%eax)
-    movl  8(%esp), %edx
-    movl  %edx, 8(%eax)
-    movl  12(%esp), %edx
-    movl  %edx, 12(%eax)
+    movl  %edx, 0(%eax)
+    movl  4(%esp), %edx
+    movl  %edx, 4(%eax)
+    movl  8(%esp), %edx
+    movl  %edx, 8(%eax)
+    movl  12(%esp), %edx
+    movl  %edx, 12(%eax)
     movl  16(%esp), %edx        # Update this function's return address into permanent memory
-    movl  %edx, 16(%eax)
+    movl  %edx, 16(%eax)
     movl  %eax, %esp            # From now, esp is pointed to permanent memory
-
-    #
+
+    #
     # Fixup the ebp point to permanent memory
-    #
-    movl  %ebp, %eax
-    subl  %ebx, %eax
-    addl  %ecx, %eax
+    #
+    movl  %ebp, %eax
+    subl  %ebx, %eax
+    addl  %ecx, %eax
     movl  %eax, %ebp            # From now, ebp is pointed to permanent memory
-
-    popl  %edx
-    popl  %ecx
-    popl  %ebx
-    popl  %eax
-    ret
-
-
+
+    popl  %edx
+    popl  %ecx
+    popl  %ebx
+    popl  %eax
+    ret
+
+
-- 
2.19.1.windows.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] CorebootPayloadPkg: Fix non - CRLF line endings
  2019-04-04 15:32 [PATCH v2 0/2] Fixed CorebootModulePkg and CorebootPayloadPkg incorrect line endings Agyeman, Prince
  2019-04-04 15:32 ` [PATCH v2 1/2] CorebootModulePkg: Fix non - CRLF " Agyeman, Prince
@ 2019-04-04 15:32 ` Agyeman, Prince
  1 sibling, 0 replies; 4+ messages in thread
From: Agyeman, Prince @ 2019-04-04 15:32 UTC (permalink / raw)
  To: devel; +Cc: Maurice Ma, Benjamin You

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1658
Replaced non CRLF line endings with CRLF

Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Agyeman <prince.agyeman@intel.com>
---
 .../PlatformHookLib/PlatformHookLib.inf        | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf b/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf
index 3230105901..c16911fe96 100644
--- a/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf
+++ b/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf
@@ -19,7 +19,7 @@
   MODULE_TYPE                    = BASE
   VERSION_STRING                 = 1.0
   LIBRARY_CLASS                  = PlatformHookLib
-  CONSTRUCTOR                    = PlatformHookSerialPortInitialize
+  CONSTRUCTOR                    = PlatformHookSerialPortInitialize
 
 [Sources]
   PlatformHookLib.c
@@ -27,7 +27,7 @@
 [LibraryClasses]
   CbParseLib
   PcdLib
-  PciLib
+  PciLib
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -35,10 +35,10 @@
   CorebootModulePkg/CorebootModulePkg.dec
 
 [Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio         ## PRODUCES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase    ## PRODUCES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate        ## PRODUCES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride  ## PRODUCES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate       ## PRODUCES
-  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate         ## PRODUCES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters   ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio         ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase    ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate        ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride  ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate       ## PRODUCES
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate         ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters   ## PRODUCES
-- 
2.19.1.windows.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 1/2] CorebootModulePkg: Fix non - CRLF line endings
  2019-04-04 15:32 ` [PATCH v2 1/2] CorebootModulePkg: Fix non - CRLF " Agyeman, Prince
@ 2019-04-09 22:59   ` Ma, Maurice
  0 siblings, 0 replies; 4+ messages in thread
From: Ma, Maurice @ 2019-04-09 22:59 UTC (permalink / raw)
  To: Agyeman, Prince, devel@edk2.groups.io; +Cc: You, Benjamin

This patch series looks good to me.
Reviewed-by: Maurice Ma <maurice.ma@intel.com>

Regards,
Maurice

> -----Original Message-----
> From: Agyeman, Prince
> Sent: Thursday, April 4, 2019 8:32
> To: devel@edk2.groups.io
> Cc: Ma, Maurice <maurice.ma@intel.com>; You, Benjamin
> <benjamin.you@intel.com>
> Subject: [PATCH v2 1/2] CorebootModulePkg: Fix non - CRLF line endings
> 
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1658
> 
> Replaced non CRLF line endings with CRLF
> 
> Cc: Maurice Ma <maurice.ma@intel.com>
> Cc: Benjamin You <benjamin.you@intel.com>
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Agyeman <prince.agyeman@intel.com>
> ---
>  CorebootModulePkg/Include/Coreboot.h          |   32 +-
>  .../BaseSerialPortLib16550.c                  | 2178 ++++++++---------
>  .../SataControllerDxe/SataController.h        | 1082 ++++----
>  CorebootModulePkg/SecCore/Ia32/Stack.S        |  138 +-
>  4 files changed, 1715 insertions(+), 1715 deletions(-)
> 
> diff --git a/CorebootModulePkg/Include/Coreboot.h
> b/CorebootModulePkg/Include/Coreboot.h
> index 784e0b128a..b622e6f17e 100644
> --- a/CorebootModulePkg/Include/Coreboot.h
> +++ b/CorebootModulePkg/Include/Coreboot.h
> @@ -80,7 +80,7 @@ struct imd_root {
>    UINT32 max_entries;
>    UINT32 num_entries;
>    UINT32 flags;
> -  UINT32 entry_align;
> +  UINT32 entry_align;
>    UINT32 max_offset;
>    struct imd_entry entries[0];
>  };
> @@ -165,21 +165,21 @@ struct cb_serial {
>    UINT32 type;
>    UINT32 baseaddr;
>    UINT32 baud;
> -  UINT32 regwidth;
> -
> -  // Crystal or input frequency to the chip containing the UART.
> -  // Provide the board specific details to allow the payload to
> -  // initialize the chip containing the UART and make independent
> -  // decisions as to which dividers to select and their values
> -  // to eventually arrive at the desired console baud-rate.
> -  UINT32 input_hertz;
> -
> -  // UART PCI address: bus, device, function
> -  // 1 << 31 - Valid bit, PCI UART in use
> -  // Bus << 20
> -  // Device << 15
> -  // Function << 12
> -  UINT32 uart_pci_addr;
> +  UINT32 regwidth;
> +
> +  // Crystal or input frequency to the chip containing the UART.
> +  // Provide the board specific details to allow the payload to
> +  // initialize the chip containing the UART and make independent
> +  // decisions as to which dividers to select and their values
> +  // to eventually arrive at the desired console baud-rate.
> +  UINT32 input_hertz;
> +
> +  // UART PCI address: bus, device, function
> +  // 1 << 31 - Valid bit, PCI UART in use
> +  // Bus << 20
> +  // Device << 15
> +  // Function << 12
> +  UINT32 uart_pci_addr;
>  };
> 
>  #define CB_TAG_CONSOLE       0x00010
> diff --git
> a/CorebootModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib165
> 50.c
> b/CorebootModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib165
> 50.c
> index a5e1755a44..804b948906 100644
> ---
> a/CorebootModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib165
> 50.c
> +++
> b/CorebootModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib165
> 50.c
> @@ -1,1095 +1,1095 @@
> -/** @file
> -  16550 UART Serial Port library functions
> -
> -  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
> -  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> -  This program and the accompanying materials
> -  are licensed and made available under the terms and conditions of the BSD
> License
> -  which accompanies this distribution.  The full text of the license may be
> found at
> -  http://opensource.org/licenses/bsd-license.php
> -
> -  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> -  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> -
> -**/
> -
> -#include <Base.h>
> -#include <IndustryStandard/Pci.h>
> -#include <Library/SerialPortLib.h>
> -#include <Library/PcdLib.h>
> -#include <Library/IoLib.h>
> -#include <Library/PciLib.h>
> -#include <Library/PlatformHookLib.h>
> -#include <Library/BaseLib.h>
> -
> -//
> +/** @file
> +  16550 UART Serial Port library functions
> +
> +  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
> +  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD
> License
> +  which accompanies this distribution.  The full text of the license may be
> found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <Base.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Library/SerialPortLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PlatformHookLib.h>
> +#include <Library/BaseLib.h>
> +
> +//
>  // PCI Definitions.
> -//
> -#define PCI_BRIDGE_32_BIT_IO_SPACE              0x01
> -
> -//
> -// 16550 UART register offsets and bitfields
> -//
> -#define R_UART_RXBUF          0
> -#define R_UART_TXBUF          0
> -#define R_UART_BAUD_LOW       0
> -#define R_UART_BAUD_HIGH      1
> -#define R_UART_FCR            2
> -#define   B_UART_FCR_FIFOE    BIT0
> -#define   B_UART_FCR_FIFO64   BIT5
> -#define R_UART_LCR            3
> -#define   B_UART_LCR_DLAB     BIT7
> -#define R_UART_MCR            4
> -#define   B_UART_MCR_DTRC     BIT0
> -#define   B_UART_MCR_RTS      BIT1
> -#define R_UART_LSR            5
> -#define   B_UART_LSR_RXRDY    BIT0
> -#define   B_UART_LSR_TXRDY    BIT5
> -#define   B_UART_LSR_TEMT     BIT6
> -#define R_UART_MSR            6
> -#define   B_UART_MSR_CTS      BIT4
> -#define   B_UART_MSR_DSR      BIT5
> -#define   B_UART_MSR_RI       BIT6
> -#define   B_UART_MSR_DCD      BIT7
> -
> -//
> -// 4-byte structure for each PCI node in PcdSerialPciDeviceInfo
> -//
> -typedef struct {
> -  UINT8   Device;
> -  UINT8   Function;
> -  UINT16  PowerManagementStatusAndControlRegister;
> -} PCI_UART_DEVICE_INFO;
> -
> -/**
> -  Read an 8-bit 16550 register.  If PcdSerialUseMmio is TRUE, then the value
> is read from
> -  MMIO space.  If PcdSerialUseMmio is FALSE, then the value is read from
> I/O space.  The
> -  parameter Offset is added to the base address of the 16550 registers that is
> specified
> -  by PcdSerialRegisterBase.
> -
> -  @param  Base    The base address register of UART device.
> -  @param  Offset  The offset of the 16550 register to read.
> -
> -  @return The value read from the 16550 register.
> -
> -**/
> -UINT8
> -SerialPortReadRegister (
> -  UINTN  Base,
> -  UINTN  Offset
> -  )
> -{
> -  if (PcdGetBool (PcdSerialUseMmio)) {
> -    return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride));
> -  } else {
> -    return IoRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride));
> -  }
> -}
> -
> -/**
> -  Write an 8-bit 16550 register.  If PcdSerialUseMmio is TRUE, then the value
> is written to
> -  MMIO space.  If PcdSerialUseMmio is FALSE, then the value is written to
> I/O space.  The
> -  parameter Offset is added to the base address of the 16550 registers that is
> specified
> -  by PcdSerialRegisterBase.
> -
> -  @param  Base    The base address register of UART device.
> -  @param  Offset  The offset of the 16550 register to write.
> -  @param  Value   The value to write to the 16550 register specified by Offset.
> -
> -  @return The value written to the 16550 register.
> -
> -**/
> -UINT8
> -SerialPortWriteRegister (
> -  UINTN  Base,
> -  UINTN  Offset,
> -  UINT8  Value
> -  )
> -{
> -  if (PcdGetBool (PcdSerialUseMmio)) {
> -    return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride),
> Value);
> -  } else {
> -    return IoWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride),
> Value);
> -  }
> -}
> -
> -/**
> -  Update the value of an 16-bit PCI configuration register in a PCI device.  If
> the
> -  PCI Configuration register specified by PciAddress is already programmed
> with a
> -  non-zero value, then return the current value.  Otherwise update the PCI
> configuration
> -  register specified by PciAddress with the value specified by Value and
> return the
> -  value programmed into the PCI configuration register.  All values must be
> masked
> -  using the bitmask specified by Mask.
> -
> -  @param  PciAddress  PCI Library address of the PCI Configuration register
> to update.
> -  @param  Value       The value to program into the PCI Configuration Register.
> -  @param  Mask        Bitmask of the bits to check and update in the PCI
> configuration register.
> -
> -**/
> -UINT16
> -SerialPortLibUpdatePciRegister16 (
> -  UINTN   PciAddress,
> -  UINT16  Value,
> -  UINT16  Mask
> -  )
> -{
> -  UINT16  CurrentValue;
> -
> -  CurrentValue = PciRead16 (PciAddress) & Mask;
> -  if (CurrentValue != 0) {
> -    return CurrentValue;
> -  }
> -  return PciWrite16 (PciAddress, Value & Mask);
> -}
> -
> -/**
> -  Update the value of an 32-bit PCI configuration register in a PCI device.  If
> the
> -  PCI Configuration register specified by PciAddress is already programmed
> with a
> -  non-zero value, then return the current value.  Otherwise update the PCI
> configuration
> -  register specified by PciAddress with the value specified by Value and
> return the
> -  value programmed into the PCI configuration register.  All values must be
> masked
> -  using the bitmask specified by Mask.
> -
> -  @param  PciAddress  PCI Library address of the PCI Configuration register
> to update.
> -  @param  Value       The value to program into the PCI Configuration Register.
> -  @param  Mask        Bitmask of the bits to check and update in the PCI
> configuration register.
> -
> -  @return  The Secondary bus number that is actually programed into the PCI
> to PCI Bridge device.
> -
> -**/
> -UINT32
> -SerialPortLibUpdatePciRegister32 (
> -  UINTN   PciAddress,
> -  UINT32  Value,
> -  UINT32  Mask
> -  )
> -{
> -  UINT32  CurrentValue;
> -
> -  CurrentValue = PciRead32 (PciAddress) & Mask;
> -  if (CurrentValue != 0) {
> -    return CurrentValue;
> -  }
> -  return PciWrite32 (PciAddress, Value & Mask);
> -}
> -
> -/**
> -  Retrieve the I/O or MMIO base address register for the PCI UART device.
> -
> -  This function assumes Root Bus Numer is Zero, and enables I/O and MMIO
> in PCI UART
> -  Device if they are not already enabled.
> -
> -  @return  The base address register of the UART device.
> -
> -**/
> -UINTN
> -GetSerialRegisterBase (
> -  VOID
> -  )
> -{
> -  UINTN                 PciLibAddress;
> -  UINTN                 BusNumber;
> -  UINTN                 SubordinateBusNumber;
> -  UINT32                ParentIoBase;
> -  UINT32                ParentIoLimit;
> -  UINT16                ParentMemoryBase;
> -  UINT16                ParentMemoryLimit;
> -  UINT32                IoBase;
> -  UINT32                IoLimit;
> -  UINT16                MemoryBase;
> -  UINT16                MemoryLimit;
> -  UINTN                 SerialRegisterBase;
> -  UINTN                 BarIndex;
> -  UINT32                RegisterBaseMask;
> -  PCI_UART_DEVICE_INFO  *DeviceInfo;
> -
> -  //
> -  // Get PCI Device Info
> -  //
> -  DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr
> (PcdSerialPciDeviceInfo);
> -
> -  //
> -  // If PCI Device Info is empty, then assume fixed address UART and return
> PcdSerialRegisterBase
> -  //
> -  if (DeviceInfo->Device == 0xff) {
> -    return (UINTN)PcdGet64 (PcdSerialRegisterBase);
> -  }
> -
> -  //
> -  // Assume PCI Bus 0 I/O window is 0-64KB and MMIO windows is 0-4GB
> -  //
> -  ParentMemoryBase  = 0 >> 16;
> -  ParentMemoryLimit = 0xfff00000 >> 16;
> -  ParentIoBase      = 0 >> 12;
> -  ParentIoLimit     = 0xf000 >> 12;
> -
> -  //
> -  // Enable I/O and MMIO in PCI Bridge
> -  // Assume Root Bus Numer is Zero.
> -  //
> -  for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) {
> -    //
> -    // Compute PCI Lib Address to PCI to PCI Bridge
> -    //
> -    PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device,
> DeviceInfo->Function, 0);
> -
> -    //
> -    // Retrieve and verify the bus numbers in the PCI to PCI Bridge
> -    //
> -    BusNumber            = PciRead8 (PciLibAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> -    SubordinateBusNumber = PciRead8 (PciLibAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> -    if (BusNumber == 0 || BusNumber > SubordinateBusNumber) {
> -      return 0;
> -    }
> -
> -    //
> -    // Retrieve and verify the I/O or MMIO decode window in the PCI to PCI
> Bridge
> -    //
> -    if (PcdGetBool (PcdSerialUseMmio)) {
> -      MemoryLimit = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryLimit)) & 0xfff0;
> -      MemoryBase  = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase))  & 0xfff0;
> -
> -      //
> -      // If PCI Bridge MMIO window is disabled, then return 0
> -      //
> -      if (MemoryLimit < MemoryBase) {
> -        return 0;
> -      }
> -
> -      //
> -      // If PCI Bridge MMIO window is not in the address range decoded by the
> parent PCI Bridge, then return 0
> -      //
> -      if (MemoryBase < ParentMemoryBase || MemoryBase >
> ParentMemoryLimit || MemoryLimit > ParentMemoryLimit) {
> -        return 0;
> -      }
> -      ParentMemoryBase  = MemoryBase;
> -      ParentMemoryLimit = MemoryLimit;
> -    } else {
> -      IoLimit = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoLimit));
> -      if ((IoLimit & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) {
> -        IoLimit = IoLimit >> 4;
> -      } else {
> -        IoLimit = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoLimitUpper16)) << 4) | (IoLimit >> 4);
> -      }
> -      IoBase = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase));
> -      if ((IoBase & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) {
> -        IoBase = IoBase >> 4;
> -      } else {
> -        IoBase = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBaseUpper16)) << 4) | (IoBase >> 4);
> -      }
> -
> -      //
> -      // If PCI Bridge I/O window is disabled, then return 0
> -      //
> -      if (IoLimit < IoBase) {
> -        return 0;
> -      }
> -
> -      //
> -      // If PCI Bridge I/O window is not in the address range decoded by the
> parent PCI Bridge, then return 0
> -      //
> -      if (IoBase < ParentIoBase || IoBase > ParentIoLimit || IoLimit >
> ParentIoLimit) {
> -        return 0;
> -      }
> -      ParentIoBase  = IoBase;
> -      ParentIoLimit = IoLimit;
> -    }
> -  }
> -
> -  //
> -  // Compute PCI Lib Address to PCI UART
> -  //
> -  PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device,
> DeviceInfo->Function, 0);
> -
> -  //
> -  // Find the first IO or MMIO BAR
> -  //
> -  RegisterBaseMask = 0xFFFFFFF0;
> -  for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex ++) {
> -    SerialRegisterBase = PciRead32 (PciLibAddress +
> PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4);
> -    if (PcdGetBool (PcdSerialUseMmio) && ((SerialRegisterBase & BIT0) == 0))
> {
> -      //
> -      // MMIO BAR is found
> -      //
> -      RegisterBaseMask = 0xFFFFFFF0;
> -      break;
> -    }
> -
> -    if ((!PcdGetBool (PcdSerialUseMmio)) && ((SerialRegisterBase & BIT0) !=
> 0)) {
> -      //
> -      // IO BAR is found
> -      //
> -      RegisterBaseMask = 0xFFFFFFF8;
> -      break;
> -    }
> -  }
> -
> -  //
> -  // MMIO or IO BAR is not found.
> -  //
> -  if (BarIndex == PCI_MAX_BAR) {
> -    return 0;
> -  }
> -
> -  //
> -  // Program UART BAR
> -  //
> -  SerialRegisterBase = SerialPortLibUpdatePciRegister32 (
> -                         PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4,
> -                         (UINT32)PcdGet64 (PcdSerialRegisterBase),
> -                         RegisterBaseMask
> -                         );
> -
> -  //
> -  // Verify that the UART BAR is in the address range decoded by the parent
> PCI Bridge
> -  //
> -  if (PcdGetBool (PcdSerialUseMmio)) {
> -    if (((SerialRegisterBase >> 16) & 0xfff0) < ParentMemoryBase ||
> ((SerialRegisterBase >> 16) & 0xfff0) > ParentMemoryLimit) {
> -      return 0;
> -    }
> -  } else {
> -    if ((SerialRegisterBase >> 12) < ParentIoBase || (SerialRegisterBase >> 12) >
> ParentIoLimit) {
> -      return 0;
> -    }
> -  }
> -
> -  //
> -  // Enable I/O and MMIO in PCI UART Device if they are not already enabled
> -  //
> -  PciOr16 (
> -    PciLibAddress + PCI_COMMAND_OFFSET,
> -    PcdGetBool (PcdSerialUseMmio) ?
> EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE
> -    );
> -
> -  //
> -  // Force D0 state if a Power Management and Status Register is specified
> -  //
> -  if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) {
> -    if ((PciRead16 (PciLibAddress + DeviceInfo-
> >PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) {
> -      PciAnd16 (PciLibAddress + DeviceInfo-
> >PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1));
> -      //
> -      // If PCI UART was not in D0, then make sure FIFOs are enabled, but do
> not reset FIFOs
> -      //
> -      SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR,
> (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE |
> B_UART_FCR_FIFO64)));
> -    }
> -  }
> -
> -  //
> -  // Get PCI Device Info
> -  //
> -  DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr
> (PcdSerialPciDeviceInfo);
> -
> -  //
> -  // Enable I/O or MMIO in PCI Bridge
> -  // Assume Root Bus Numer is Zero.
> -  //
> -  for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) {
> -    //
> -    // Compute PCI Lib Address to PCI to PCI Bridge
> -    //
> -    PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device,
> DeviceInfo->Function, 0);
> -
> -    //
> -    // Enable the I/O or MMIO decode windows in the PCI to PCI Bridge
> -    //
> -    PciOr16 (
> -      PciLibAddress + PCI_COMMAND_OFFSET,
> -      PcdGetBool (PcdSerialUseMmio) ?
> EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE
> -      );
> -
> -    //
> -    // Force D0 state if a Power Management and Status Register is specified
> -    //
> -    if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) {
> -      if ((PciRead16 (PciLibAddress + DeviceInfo-
> >PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) {
> -        PciAnd16 (PciLibAddress + DeviceInfo-
> >PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1));
> -      }
> -    }
> -
> -    BusNumber = PciRead8 (PciLibAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> -  }
> -
> -  return SerialRegisterBase;
> -}
> -
> -/**
> -  Return whether the hardware flow control signal allows writing.
> -
> -  @param  SerialRegisterBase The base address register of UART device.
> -
> -  @retval TRUE  The serial port is writable.
> -  @retval FALSE The serial port is not writable.
> -**/
> -BOOLEAN
> -SerialPortWritable (
> -  UINTN  SerialRegisterBase
> -  )
> -{
> -  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> -    if (PcdGetBool (PcdSerialDetectCable)) {
> -      //
> -      // Wait for both DSR and CTS to be set
> -      //   DSR is set if a cable is connected.
> -      //   CTS is set if it is ok to transmit data
> -      //
> -      //   DSR  CTS  Description                               Action
> -      //   ===  ===  ========================================
> ========
> -      //    0    0   No cable connected.                       Wait
> -      //    0    1   No cable connected.                       Wait
> -      //    1    0   Cable connected, but not clear to send.   Wait
> -      //    1    1   Cable connected, and clear to send.       Transmit
> -      //
> -      return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase,
> R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) ==
> (B_UART_MSR_DSR | B_UART_MSR_CTS));
> -    } else {
> -      //
> -      // Wait for both DSR and CTS to be set OR for DSR to be clear.
> -      //   DSR is set if a cable is connected.
> -      //   CTS is set if it is ok to transmit data
> -      //
> -      //   DSR  CTS  Description                               Action
> -      //   ===  ===  ========================================
> ========
> -      //    0    0   No cable connected.                       Transmit
> -      //    0    1   No cable connected.                       Transmit
> -      //    1    0   Cable connected, but not clear to send.   Wait
> +//
> +#define PCI_BRIDGE_32_BIT_IO_SPACE              0x01
> +
> +//
> +// 16550 UART register offsets and bitfields
> +//
> +#define R_UART_RXBUF          0
> +#define R_UART_TXBUF          0
> +#define R_UART_BAUD_LOW       0
> +#define R_UART_BAUD_HIGH      1
> +#define R_UART_FCR            2
> +#define   B_UART_FCR_FIFOE    BIT0
> +#define   B_UART_FCR_FIFO64   BIT5
> +#define R_UART_LCR            3
> +#define   B_UART_LCR_DLAB     BIT7
> +#define R_UART_MCR            4
> +#define   B_UART_MCR_DTRC     BIT0
> +#define   B_UART_MCR_RTS      BIT1
> +#define R_UART_LSR            5
> +#define   B_UART_LSR_RXRDY    BIT0
> +#define   B_UART_LSR_TXRDY    BIT5
> +#define   B_UART_LSR_TEMT     BIT6
> +#define R_UART_MSR            6
> +#define   B_UART_MSR_CTS      BIT4
> +#define   B_UART_MSR_DSR      BIT5
> +#define   B_UART_MSR_RI       BIT6
> +#define   B_UART_MSR_DCD      BIT7
> +
> +//
> +// 4-byte structure for each PCI node in PcdSerialPciDeviceInfo
> +//
> +typedef struct {
> +  UINT8   Device;
> +  UINT8   Function;
> +  UINT16  PowerManagementStatusAndControlRegister;
> +} PCI_UART_DEVICE_INFO;
> +
> +/**
> +  Read an 8-bit 16550 register.  If PcdSerialUseMmio is TRUE, then the value
> is read from
> +  MMIO space.  If PcdSerialUseMmio is FALSE, then the value is read from
> I/O space.  The
> +  parameter Offset is added to the base address of the 16550 registers that
> is specified
> +  by PcdSerialRegisterBase.
> +
> +  @param  Base    The base address register of UART device.
> +  @param  Offset  The offset of the 16550 register to read.
> +
> +  @return The value read from the 16550 register.
> +
> +**/
> +UINT8
> +SerialPortReadRegister (
> +  UINTN  Base,
> +  UINTN  Offset
> +  )
> +{
> +  if (PcdGetBool (PcdSerialUseMmio)) {
> +    return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride));
> +  } else {
> +    return IoRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride));
> +  }
> +}
> +
> +/**
> +  Write an 8-bit 16550 register.  If PcdSerialUseMmio is TRUE, then the value
> is written to
> +  MMIO space.  If PcdSerialUseMmio is FALSE, then the value is written to
> I/O space.  The
> +  parameter Offset is added to the base address of the 16550 registers that
> is specified
> +  by PcdSerialRegisterBase.
> +
> +  @param  Base    The base address register of UART device.
> +  @param  Offset  The offset of the 16550 register to write.
> +  @param  Value   The value to write to the 16550 register specified by
> Offset.
> +
> +  @return The value written to the 16550 register.
> +
> +**/
> +UINT8
> +SerialPortWriteRegister (
> +  UINTN  Base,
> +  UINTN  Offset,
> +  UINT8  Value
> +  )
> +{
> +  if (PcdGetBool (PcdSerialUseMmio)) {
> +    return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride),
> Value);
> +  } else {
> +    return IoWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride),
> Value);
> +  }
> +}
> +
> +/**
> +  Update the value of an 16-bit PCI configuration register in a PCI device.  If
> the
> +  PCI Configuration register specified by PciAddress is already programmed
> with a
> +  non-zero value, then return the current value.  Otherwise update the PCI
> configuration
> +  register specified by PciAddress with the value specified by Value and
> return the
> +  value programmed into the PCI configuration register.  All values must be
> masked
> +  using the bitmask specified by Mask.
> +
> +  @param  PciAddress  PCI Library address of the PCI Configuration register
> to update.
> +  @param  Value       The value to program into the PCI Configuration
> Register.
> +  @param  Mask        Bitmask of the bits to check and update in the PCI
> configuration register.
> +
> +**/
> +UINT16
> +SerialPortLibUpdatePciRegister16 (
> +  UINTN   PciAddress,
> +  UINT16  Value,
> +  UINT16  Mask
> +  )
> +{
> +  UINT16  CurrentValue;
> +
> +  CurrentValue = PciRead16 (PciAddress) & Mask;
> +  if (CurrentValue != 0) {
> +    return CurrentValue;
> +  }
> +  return PciWrite16 (PciAddress, Value & Mask);
> +}
> +
> +/**
> +  Update the value of an 32-bit PCI configuration register in a PCI device.  If
> the
> +  PCI Configuration register specified by PciAddress is already programmed
> with a
> +  non-zero value, then return the current value.  Otherwise update the PCI
> configuration
> +  register specified by PciAddress with the value specified by Value and
> return the
> +  value programmed into the PCI configuration register.  All values must be
> masked
> +  using the bitmask specified by Mask.
> +
> +  @param  PciAddress  PCI Library address of the PCI Configuration register
> to update.
> +  @param  Value       The value to program into the PCI Configuration
> Register.
> +  @param  Mask        Bitmask of the bits to check and update in the PCI
> configuration register.
> +
> +  @return  The Secondary bus number that is actually programed into the
> PCI to PCI Bridge device.
> +
> +**/
> +UINT32
> +SerialPortLibUpdatePciRegister32 (
> +  UINTN   PciAddress,
> +  UINT32  Value,
> +  UINT32  Mask
> +  )
> +{
> +  UINT32  CurrentValue;
> +
> +  CurrentValue = PciRead32 (PciAddress) & Mask;
> +  if (CurrentValue != 0) {
> +    return CurrentValue;
> +  }
> +  return PciWrite32 (PciAddress, Value & Mask);
> +}
> +
> +/**
> +  Retrieve the I/O or MMIO base address register for the PCI UART device.
> +
> +  This function assumes Root Bus Numer is Zero, and enables I/O and MMIO
> in PCI UART
> +  Device if they are not already enabled.
> +
> +  @return  The base address register of the UART device.
> +
> +**/
> +UINTN
> +GetSerialRegisterBase (
> +  VOID
> +  )
> +{
> +  UINTN                 PciLibAddress;
> +  UINTN                 BusNumber;
> +  UINTN                 SubordinateBusNumber;
> +  UINT32                ParentIoBase;
> +  UINT32                ParentIoLimit;
> +  UINT16                ParentMemoryBase;
> +  UINT16                ParentMemoryLimit;
> +  UINT32                IoBase;
> +  UINT32                IoLimit;
> +  UINT16                MemoryBase;
> +  UINT16                MemoryLimit;
> +  UINTN                 SerialRegisterBase;
> +  UINTN                 BarIndex;
> +  UINT32                RegisterBaseMask;
> +  PCI_UART_DEVICE_INFO  *DeviceInfo;
> +
> +  //
> +  // Get PCI Device Info
> +  //
> +  DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr
> (PcdSerialPciDeviceInfo);
> +
> +  //
> +  // If PCI Device Info is empty, then assume fixed address UART and return
> PcdSerialRegisterBase
> +  //
> +  if (DeviceInfo->Device == 0xff) {
> +    return (UINTN)PcdGet64 (PcdSerialRegisterBase);
> +  }
> +
> +  //
> +  // Assume PCI Bus 0 I/O window is 0-64KB and MMIO windows is 0-4GB
> +  //
> +  ParentMemoryBase  = 0 >> 16;
> +  ParentMemoryLimit = 0xfff00000 >> 16;
> +  ParentIoBase      = 0 >> 12;
> +  ParentIoLimit     = 0xf000 >> 12;
> +
> +  //
> +  // Enable I/O and MMIO in PCI Bridge
> +  // Assume Root Bus Numer is Zero.
> +  //
> +  for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) {
> +    //
> +    // Compute PCI Lib Address to PCI to PCI Bridge
> +    //
> +    PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device,
> DeviceInfo->Function, 0);
> +
> +    //
> +    // Retrieve and verify the bus numbers in the PCI to PCI Bridge
> +    //
> +    BusNumber            = PciRead8 (PciLibAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +    SubordinateBusNumber = PciRead8 (PciLibAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> +    if (BusNumber == 0 || BusNumber > SubordinateBusNumber) {
> +      return 0;
> +    }
> +
> +    //
> +    // Retrieve and verify the I/O or MMIO decode window in the PCI to PCI
> Bridge
> +    //
> +    if (PcdGetBool (PcdSerialUseMmio)) {
> +      MemoryLimit = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryLimit)) & 0xfff0;
> +      MemoryBase  = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase))  & 0xfff0;
> +
> +      //
> +      // If PCI Bridge MMIO window is disabled, then return 0
> +      //
> +      if (MemoryLimit < MemoryBase) {
> +        return 0;
> +      }
> +
> +      //
> +      // If PCI Bridge MMIO window is not in the address range decoded by
> the parent PCI Bridge, then return 0
> +      //
> +      if (MemoryBase < ParentMemoryBase || MemoryBase >
> ParentMemoryLimit || MemoryLimit > ParentMemoryLimit) {
> +        return 0;
> +      }
> +      ParentMemoryBase  = MemoryBase;
> +      ParentMemoryLimit = MemoryLimit;
> +    } else {
> +      IoLimit = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoLimit));
> +      if ((IoLimit & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) {
> +        IoLimit = IoLimit >> 4;
> +      } else {
> +        IoLimit = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoLimitUpper16)) << 4) | (IoLimit >> 4);
> +      }
> +      IoBase = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase));
> +      if ((IoBase & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) {
> +        IoBase = IoBase >> 4;
> +      } else {
> +        IoBase = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBaseUpper16)) << 4) | (IoBase >> 4);
> +      }
> +
> +      //
> +      // If PCI Bridge I/O window is disabled, then return 0
> +      //
> +      if (IoLimit < IoBase) {
> +        return 0;
> +      }
> +
> +      //
> +      // If PCI Bridge I/O window is not in the address range decoded by the
> parent PCI Bridge, then return 0
> +      //
> +      if (IoBase < ParentIoBase || IoBase > ParentIoLimit || IoLimit >
> ParentIoLimit) {
> +        return 0;
> +      }
> +      ParentIoBase  = IoBase;
> +      ParentIoLimit = IoLimit;
> +    }
> +  }
> +
> +  //
> +  // Compute PCI Lib Address to PCI UART
> +  //
> +  PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device,
> DeviceInfo->Function, 0);
> +
> +  //
> +  // Find the first IO or MMIO BAR
> +  //
> +  RegisterBaseMask = 0xFFFFFFF0;
> +  for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex ++) {
> +    SerialRegisterBase = PciRead32 (PciLibAddress +
> PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4);
> +    if (PcdGetBool (PcdSerialUseMmio) && ((SerialRegisterBase & BIT0) == 0))
> {
> +      //
> +      // MMIO BAR is found
> +      //
> +      RegisterBaseMask = 0xFFFFFFF0;
> +      break;
> +    }
> +
> +    if ((!PcdGetBool (PcdSerialUseMmio)) && ((SerialRegisterBase & BIT0) !=
> 0)) {
> +      //
> +      // IO BAR is found
> +      //
> +      RegisterBaseMask = 0xFFFFFFF8;
> +      break;
> +    }
> +  }
> +
> +  //
> +  // MMIO or IO BAR is not found.
> +  //
> +  if (BarIndex == PCI_MAX_BAR) {
> +    return 0;
> +  }
> +
> +  //
> +  // Program UART BAR
> +  //
> +  SerialRegisterBase = SerialPortLibUpdatePciRegister32 (
> +                         PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex *
> 4,
> +                         (UINT32)PcdGet64 (PcdSerialRegisterBase),
> +                         RegisterBaseMask
> +                         );
> +
> +  //
> +  // Verify that the UART BAR is in the address range decoded by the parent
> PCI Bridge
> +  //
> +  if (PcdGetBool (PcdSerialUseMmio)) {
> +    if (((SerialRegisterBase >> 16) & 0xfff0) < ParentMemoryBase ||
> ((SerialRegisterBase >> 16) & 0xfff0) > ParentMemoryLimit) {
> +      return 0;
> +    }
> +  } else {
> +    if ((SerialRegisterBase >> 12) < ParentIoBase || (SerialRegisterBase >>
> 12) > ParentIoLimit) {
> +      return 0;
> +    }
> +  }
> +
> +  //
> +  // Enable I/O and MMIO in PCI UART Device if they are not already enabled
> +  //
> +  PciOr16 (
> +    PciLibAddress + PCI_COMMAND_OFFSET,
> +    PcdGetBool (PcdSerialUseMmio) ?
> EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE
> +    );
> +
> +  //
> +  // Force D0 state if a Power Management and Status Register is specified
> +  //
> +  if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) {
> +    if ((PciRead16 (PciLibAddress + DeviceInfo-
> >PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) {
> +      PciAnd16 (PciLibAddress + DeviceInfo-
> >PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1));
> +      //
> +      // If PCI UART was not in D0, then make sure FIFOs are enabled, but do
> not reset FIFOs
> +      //
> +      SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR,
> (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE |
> B_UART_FCR_FIFO64)));
> +    }
> +  }
> +
> +  //
> +  // Get PCI Device Info
> +  //
> +  DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr
> (PcdSerialPciDeviceInfo);
> +
> +  //
> +  // Enable I/O or MMIO in PCI Bridge
> +  // Assume Root Bus Numer is Zero.
> +  //
> +  for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) {
> +    //
> +    // Compute PCI Lib Address to PCI to PCI Bridge
> +    //
> +    PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device,
> DeviceInfo->Function, 0);
> +
> +    //
> +    // Enable the I/O or MMIO decode windows in the PCI to PCI Bridge
> +    //
> +    PciOr16 (
> +      PciLibAddress + PCI_COMMAND_OFFSET,
> +      PcdGetBool (PcdSerialUseMmio) ?
> EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE
> +      );
> +
> +    //
> +    // Force D0 state if a Power Management and Status Register is specified
> +    //
> +    if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) {
> +      if ((PciRead16 (PciLibAddress + DeviceInfo-
> >PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) {
> +        PciAnd16 (PciLibAddress + DeviceInfo-
> >PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1));
> +      }
> +    }
> +
> +    BusNumber = PciRead8 (PciLibAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  }
> +
> +  return SerialRegisterBase;
> +}
> +
> +/**
> +  Return whether the hardware flow control signal allows writing.
> +
> +  @param  SerialRegisterBase The base address register of UART device.
> +
> +  @retval TRUE  The serial port is writable.
> +  @retval FALSE The serial port is not writable.
> +**/
> +BOOLEAN
> +SerialPortWritable (
> +  UINTN  SerialRegisterBase
> +  )
> +{
> +  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> +    if (PcdGetBool (PcdSerialDetectCable)) {
> +      //
> +      // Wait for both DSR and CTS to be set
> +      //   DSR is set if a cable is connected.
> +      //   CTS is set if it is ok to transmit data
> +      //
> +      //   DSR  CTS  Description                               Action
> +      //   ===  ===  ========================================
> ========
> +      //    0    0   No cable connected.                       Wait
> +      //    0    1   No cable connected.                       Wait
> +      //    1    0   Cable connected, but not clear to send.   Wait
>        //    1    1   Cable connected, and clear to send.       Transmit
> -      //
> -      return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase,
> R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) !=
> (B_UART_MSR_DSR));
> -    }
> -  }
> -
> -  return TRUE;
> -}
> -
> -/**
> -  Initialize the serial device hardware.
> -
> -  If no initialization is required, then return RETURN_SUCCESS.
> -  If the serial device was successfully initialized, then return
> RETURN_SUCCESS.
> -  If the serial device could not be initialized, then return
> RETURN_DEVICE_ERROR.
> -
> -  @retval RETURN_SUCCESS        The serial device was initialized.
> -  @retval RETURN_DEVICE_ERROR   The serial device could not be initialized.
> -
> -**/
> -RETURN_STATUS
> -EFIAPI
> -SerialPortInitialize (
> -  VOID
> -  )
> -{
> -  RETURN_STATUS  Status;
> -  UINTN          SerialRegisterBase;
> -  UINT32         Divisor;
> -  UINT32         CurrentDivisor;
> -  BOOLEAN        Initialized;
> -
> -  //
> -  // Perform platform specific initialization required to enable use of the
> 16550 device
> -  // at the location specified by PcdSerialUseMmio and PcdSerialRegisterBase.
> -  //
> -  Status = PlatformHookSerialPortInitialize ();
> -  if (RETURN_ERROR (Status)) {
> -    return Status;
> -  }
> -
> -  //
> -  // Calculate divisor for baud generator
> -  //    Ref_Clk_Rate / Baud_Rate / 16
> -  //
> -  Divisor = PcdGet32 (PcdSerialClockRate) / (PcdGet32 (PcdSerialBaudRate) *
> 16);
> -  if ((PcdGet32 (PcdSerialClockRate) % (PcdGet32 (PcdSerialBaudRate) *
> 16)) >= PcdGet32 (PcdSerialBaudRate) * 8) {
> -    Divisor++;
> -  }
> -
> -  //
> -  // Get the base address of the serial port in either I/O or MMIO space
> -  //
> -  SerialRegisterBase = GetSerialRegisterBase ();
> -  if (SerialRegisterBase ==0) {
> -    return RETURN_DEVICE_ERROR;
> -  }
> -
> -  //
> -  // See if the serial port is already initialized
> -  //
> -  Initialized = TRUE;
> -  if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F) !=
> (PcdGet8 (PcdSerialLineControl) & 0x3F)) {
> -    Initialized = FALSE;
> -  }
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) |
> B_UART_LCR_DLAB));
> -  CurrentDivisor =  SerialPortReadRegister (SerialRegisterBase,
> R_UART_BAUD_HIGH) << 8;
> -  CurrentDivisor |= (UINT32) SerialPortReadRegister (SerialRegisterBase,
> R_UART_BAUD_LOW);
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) &
> ~B_UART_LCR_DLAB));
> -  if (CurrentDivisor != Divisor) {
> -    Initialized = FALSE;
> -  }
> -  if (Initialized) {
> -    return RETURN_SUCCESS;
> -  }
> -
> -  //
> -  // Wait for the serial port to be ready.
> -  // Verify that both the transmit FIFO and the shift register are empty.
> -  //
> -  while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT |
> B_UART_LSR_TXRDY));
> -
> -  //
> -  // Configure baud rate
> -  //
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> B_UART_LCR_DLAB);
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)
> (Divisor >> 8));
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)
> (Divisor & 0xff));
> -
> -  //
> -  // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
> -  // Strip reserved bits from PcdSerialLineControl
> -  //
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F));
> -
> -  //
> -  // Enable and reset FIFOs
> -  // Strip reserved bits from PcdSerialFifoControl
> -  //
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00);
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR,
> (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE |
> B_UART_FCR_FIFO64)));
> -
> -  //
> -  // Set RTS and DTR in Modem Control Register(MCR)
> -  //
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR,
> -                   EFI_SERIAL_REQUEST_TO_SEND |
> EFI_SERIAL_DATA_TERMINAL_READY);
> -
> -  return RETURN_SUCCESS;
> -}
> -
> -/**
> -  Write data from buffer to serial device.
> -
> -  Writes NumberOfBytes data bytes from Buffer to the serial device.
> -  The number of bytes actually written to the serial device is returned.
> -  If the return value is less than NumberOfBytes, then the write operation
> failed.
> -
> -  If Buffer is NULL, then ASSERT().
> -
> -  If NumberOfBytes is zero, then return 0.
> -
> -  @param  Buffer           Pointer to the data buffer to be written.
> -  @param  NumberOfBytes    Number of bytes to written to the serial device.
> -
> -  @retval 0                NumberOfBytes is 0.
> -  @retval >0               The number of bytes written to the serial device.
> -                           If this value is less than NumberOfBytes, then the write
> operation failed.
> -
> -**/
> -UINTN
> -EFIAPI
> -SerialPortWrite (
> -  IN UINT8     *Buffer,
> -  IN UINTN     NumberOfBytes
> -  )
> -{
> -  UINTN  SerialRegisterBase;
> -  UINTN  Result;
> -  UINTN  Index;
> -  UINTN  FifoSize;
> -
> -  if (Buffer == NULL) {
> -    return 0;
> -  }
> -
> -  SerialRegisterBase = GetSerialRegisterBase ();
> -  if (SerialRegisterBase ==0) {
> -    return 0;
> -  }
> -
> -  if (NumberOfBytes == 0) {
> -    //
> -    // Flush the hardware
> -    //
> -
> -    //
> -    // Wait for both the transmit FIFO and shift register empty.
> -    //
> -    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT |
> B_UART_LSR_TXRDY));
> -
> -    //
> -    // Wait for the hardware flow control signal
> -    //
> -    while (!SerialPortWritable (SerialRegisterBase));
> -    return 0;
> -  }
> -
> -  //
> -  // Compute the maximum size of the Tx FIFO
> -  //
> -  FifoSize = 1;
> -  if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) != 0) {
> -    if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) == 0) {
> -      FifoSize = 16;
> -    } else {
> -      FifoSize = PcdGet32 (PcdSerialExtendedTxFifoSize);
> -    }
> -  }
> -
> -  Result = NumberOfBytes;
> -  while (NumberOfBytes != 0) {
> -    //
> -    // Wait for the serial port to be ready, to make sure both the transmit FIFO
> -    // and shift register empty.
> -    //
> -    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> B_UART_LSR_TEMT) == 0);
> -
> -    //
> -    // Fill then entire Tx FIFO
> -    //
> -    for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++,
> NumberOfBytes--, Buffer++) {
> -      //
> -      // Wait for the hardware flow control signal
> -      //
> -      while (!SerialPortWritable (SerialRegisterBase));
> -
> -      //
> -      // Write byte to the transmit buffer.
> -      //
> -      SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buffer);
> -    }
> -  }
> -  return Result;
> -}
> -
> -/**
> -  Reads data from a serial device into a buffer.
> -
> -  @param  Buffer           Pointer to the data buffer to store the data read from
> the serial device.
> -  @param  NumberOfBytes    Number of bytes to read from the serial device.
> -
> -  @retval 0                NumberOfBytes is 0.
> -  @retval >0               The number of bytes read from the serial device.
> -                           If this value is less than NumberOfBytes, then the read
> operation failed.
> -
> -**/
> -UINTN
> -EFIAPI
> -SerialPortRead (
> -  OUT UINT8     *Buffer,
> -  IN  UINTN     NumberOfBytes
> -  )
> -{
> -  UINTN  SerialRegisterBase;
> -  UINTN  Result;
> -  UINT8  Mcr;
> -
> -  if (NULL == Buffer) {
> -    return 0;
> -  }
> -
> -  SerialRegisterBase = GetSerialRegisterBase ();
> -  if (SerialRegisterBase ==0) {
> -    return 0;
> -  }
> -
> -  Mcr = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR)
> & ~B_UART_MCR_RTS);
> -
> -  for (Result = 0; NumberOfBytes-- != 0; Result++, Buffer++) {
> -    //
> -    // Wait for the serial port to have some data.
> -    //
> -    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> B_UART_LSR_RXRDY) == 0) {
> -      if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> -        //
> -        // Set RTS to let the peer send some data
> -        //
> -        SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(Mcr
> | B_UART_MCR_RTS));
> -      }
> -    }
> -    if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> -      //
> -      // Clear RTS to prevent peer from sending data
> -      //
> -      SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr);
> -    }
> -
> -    //
> -    // Read byte from the receive buffer.
> -    //
> -    *Buffer = SerialPortReadRegister (SerialRegisterBase, R_UART_RXBUF);
> -  }
> -
> -  return Result;
> -}
> -
> -
> -/**
> -  Polls a serial device to see if there is any data waiting to be read.
> -
> +      //
> +      return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase,
> R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) ==
> (B_UART_MSR_DSR | B_UART_MSR_CTS));
> +    } else {
> +      //
> +      // Wait for both DSR and CTS to be set OR for DSR to be clear.
> +      //   DSR is set if a cable is connected.
> +      //   CTS is set if it is ok to transmit data
> +      //
> +      //   DSR  CTS  Description                               Action
> +      //   ===  ===  ========================================
> ========
> +      //    0    0   No cable connected.                       Transmit
> +      //    0    1   No cable connected.                       Transmit
> +      //    1    0   Cable connected, but not clear to send.   Wait
> +      //    1    1   Cable connected, and clear to send.       Transmit
> +      //
> +      return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase,
> R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) !=
> (B_UART_MSR_DSR));
> +    }
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> +  Initialize the serial device hardware.
> +
> +  If no initialization is required, then return RETURN_SUCCESS.
> +  If the serial device was successfully initialized, then return
> RETURN_SUCCESS.
> +  If the serial device could not be initialized, then return
> RETURN_DEVICE_ERROR.
> +
> +  @retval RETURN_SUCCESS        The serial device was initialized.
> +  @retval RETURN_DEVICE_ERROR   The serial device could not be initialized.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortInitialize (
> +  VOID
> +  )
> +{
> +  RETURN_STATUS  Status;
> +  UINTN          SerialRegisterBase;
> +  UINT32         Divisor;
> +  UINT32         CurrentDivisor;
> +  BOOLEAN        Initialized;
> +
> +  //
> +  // Perform platform specific initialization required to enable use of the
> 16550 device
> +  // at the location specified by PcdSerialUseMmio and
> PcdSerialRegisterBase.
> +  //
> +  Status = PlatformHookSerialPortInitialize ();
> +  if (RETURN_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Calculate divisor for baud generator
> +  //    Ref_Clk_Rate / Baud_Rate / 16
> +  //
> +  Divisor = PcdGet32 (PcdSerialClockRate) / (PcdGet32 (PcdSerialBaudRate) *
> 16);
> +  if ((PcdGet32 (PcdSerialClockRate) % (PcdGet32 (PcdSerialBaudRate) *
> 16)) >= PcdGet32 (PcdSerialBaudRate) * 8) {
> +    Divisor++;
> +  }
> +
> +  //
> +  // Get the base address of the serial port in either I/O or MMIO space
> +  //
> +  SerialRegisterBase = GetSerialRegisterBase ();
> +  if (SerialRegisterBase ==0) {
> +    return RETURN_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // See if the serial port is already initialized
> +  //
> +  Initialized = TRUE;
> +  if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F) !=
> (PcdGet8 (PcdSerialLineControl) & 0x3F)) {
> +    Initialized = FALSE;
> +  }
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) |
> B_UART_LCR_DLAB));
> +  CurrentDivisor =  SerialPortReadRegister (SerialRegisterBase,
> R_UART_BAUD_HIGH) << 8;
> +  CurrentDivisor |= (UINT32) SerialPortReadRegister (SerialRegisterBase,
> R_UART_BAUD_LOW);
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) &
> ~B_UART_LCR_DLAB));
> +  if (CurrentDivisor != Divisor) {
> +    Initialized = FALSE;
> +  }
> +  if (Initialized) {
> +    return RETURN_SUCCESS;
> +  }
> +
> +  //
> +  // Wait for the serial port to be ready.
> +  // Verify that both the transmit FIFO and the shift register are empty.
> +  //
> +  while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT |
> B_UART_LSR_TXRDY));
> +
> +  //
> +  // Configure baud rate
> +  //
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> B_UART_LCR_DLAB);
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)
> (Divisor >> 8));
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)
> (Divisor & 0xff));
> +
> +  //
> +  // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
> +  // Strip reserved bits from PcdSerialLineControl
> +  //
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F));
> +
> +  //
> +  // Enable and reset FIFOs
> +  // Strip reserved bits from PcdSerialFifoControl
> +  //
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00);
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR,
> (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE |
> B_UART_FCR_FIFO64)));
> +
> +  //
> +  // Set RTS and DTR in Modem Control Register(MCR)
> +  //
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR,
> +                   EFI_SERIAL_REQUEST_TO_SEND |
> EFI_SERIAL_DATA_TERMINAL_READY);
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Write data from buffer to serial device.
> +
> +  Writes NumberOfBytes data bytes from Buffer to the serial device.
> +  The number of bytes actually written to the serial device is returned.
> +  If the return value is less than NumberOfBytes, then the write operation
> failed.
> +
> +  If Buffer is NULL, then ASSERT().
> +
> +  If NumberOfBytes is zero, then return 0.
> +
> +  @param  Buffer           Pointer to the data buffer to be written.
> +  @param  NumberOfBytes    Number of bytes to written to the serial device.
> +
> +  @retval 0                NumberOfBytes is 0.
> +  @retval >0               The number of bytes written to the serial device.
> +                           If this value is less than NumberOfBytes, then the write
> operation failed.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortWrite (
> +  IN UINT8     *Buffer,
> +  IN UINTN     NumberOfBytes
> +  )
> +{
> +  UINTN  SerialRegisterBase;
> +  UINTN  Result;
> +  UINTN  Index;
> +  UINTN  FifoSize;
> +
> +  if (Buffer == NULL) {
> +    return 0;
> +  }
> +
> +  SerialRegisterBase = GetSerialRegisterBase ();
> +  if (SerialRegisterBase ==0) {
> +    return 0;
> +  }
> +
> +  if (NumberOfBytes == 0) {
> +    //
> +    // Flush the hardware
> +    //
> +
> +    //
> +    // Wait for both the transmit FIFO and shift register empty.
> +    //
> +    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT |
> B_UART_LSR_TXRDY));
> +
> +    //
> +    // Wait for the hardware flow control signal
> +    //
> +    while (!SerialPortWritable (SerialRegisterBase));
> +    return 0;
> +  }
> +
> +  //
> +  // Compute the maximum size of the Tx FIFO
> +  //
> +  FifoSize = 1;
> +  if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) != 0) {
> +    if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) == 0) {
> +      FifoSize = 16;
> +    } else {
> +      FifoSize = PcdGet32 (PcdSerialExtendedTxFifoSize);
> +    }
> +  }
> +
> +  Result = NumberOfBytes;
> +  while (NumberOfBytes != 0) {
> +    //
> +    // Wait for the serial port to be ready, to make sure both the transmit
> FIFO
> +    // and shift register empty.
> +    //
> +    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> B_UART_LSR_TEMT) == 0);
> +
> +    //
> +    // Fill then entire Tx FIFO
> +    //
> +    for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++,
> NumberOfBytes--, Buffer++) {
> +      //
> +      // Wait for the hardware flow control signal
> +      //
> +      while (!SerialPortWritable (SerialRegisterBase));
> +
> +      //
> +      // Write byte to the transmit buffer.
> +      //
> +      SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buffer);
> +    }
> +  }
> +  return Result;
> +}
> +
> +/**
> +  Reads data from a serial device into a buffer.
> +
> +  @param  Buffer           Pointer to the data buffer to store the data read from
> the serial device.
> +  @param  NumberOfBytes    Number of bytes to read from the serial device.
> +
> +  @retval 0                NumberOfBytes is 0.
> +  @retval >0               The number of bytes read from the serial device.
> +                           If this value is less than NumberOfBytes, then the read
> operation failed.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortRead (
> +  OUT UINT8     *Buffer,
> +  IN  UINTN     NumberOfBytes
> +  )
> +{
> +  UINTN  SerialRegisterBase;
> +  UINTN  Result;
> +  UINT8  Mcr;
> +
> +  if (NULL == Buffer) {
> +    return 0;
> +  }
> +
> +  SerialRegisterBase = GetSerialRegisterBase ();
> +  if (SerialRegisterBase ==0) {
> +    return 0;
> +  }
> +
> +  Mcr = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR)
> & ~B_UART_MCR_RTS);
> +
> +  for (Result = 0; NumberOfBytes-- != 0; Result++, Buffer++) {
> +    //
> +    // Wait for the serial port to have some data.
> +    //
> +    while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> B_UART_LSR_RXRDY) == 0) {
> +      if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> +        //
> +        // Set RTS to let the peer send some data
> +        //
> +        SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR,
> (UINT8)(Mcr | B_UART_MCR_RTS));
> +      }
> +    }
> +    if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> +      //
> +      // Clear RTS to prevent peer from sending data
> +      //
> +      SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr);
> +    }
> +
> +    //
> +    // Read byte from the receive buffer.
> +    //
> +    *Buffer = SerialPortReadRegister (SerialRegisterBase, R_UART_RXBUF);
> +  }
> +
> +  return Result;
> +}
> +
> +
> +/**
> +  Polls a serial device to see if there is any data waiting to be read.
> +
>    Polls a serial device to see if there is any data waiting to be read.
> -  If there is data waiting to be read from the serial device, then TRUE is
> returned.
> -  If there is no data waiting to be read from the serial device, then FALSE is
> returned.
> -
> -  @retval TRUE             Data is waiting to be read from the serial device.
> -  @retval FALSE            There is no data waiting to be read from the serial
> device.
> -
> -**/
> -BOOLEAN
> -EFIAPI
> -SerialPortPoll (
> -  VOID
> -  )
> -{
> -  UINTN  SerialRegisterBase;
> -
> -  SerialRegisterBase = GetSerialRegisterBase ();
> -  if (SerialRegisterBase ==0) {
> -    return FALSE;
> -  }
> -
> -  //
> -  // Read the serial port status
> -  //
> -  if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> B_UART_LSR_RXRDY) != 0) {
> -    if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> -      //
> -      // Clear RTS to prevent peer from sending data
> -      //
> -      SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR,
> (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) &
> ~B_UART_MCR_RTS));
> -    }
> -    return TRUE;
> -  }
> -
> -  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> -    //
> -    // Set RTS to let the peer send some data
> -    //
> -    SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR,
> (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) |
> B_UART_MCR_RTS));
> -  }
> -
> -  return FALSE;
> -}
> -
> -/**
> -  Sets the control bits on a serial device.
> -
> -  @param Control                Sets the bits of Control that are settable.
> -
> -  @retval RETURN_SUCCESS        The new control bits were set on the serial
> device.
> -  @retval RETURN_UNSUPPORTED    The serial device does not support this
> operation.
> -  @retval RETURN_DEVICE_ERROR   The serial device is not functioning
> correctly.
> -
> -**/
> -RETURN_STATUS
> -EFIAPI
> -SerialPortSetControl (
> -  IN UINT32 Control
> -  )
> -{
> -  UINTN SerialRegisterBase;
> -  UINT8 Mcr;
> -
> -  //
> -  // First determine the parameter is invalid.
> -  //
> -  if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND |
> EFI_SERIAL_DATA_TERMINAL_READY |
> -                    EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) {
> -    return RETURN_UNSUPPORTED;
> -  }
> -
> -  SerialRegisterBase = GetSerialRegisterBase ();
> -  if (SerialRegisterBase ==0) {
> -    return RETURN_UNSUPPORTED;
> -  }
> -
> -  //
> -  // Read the Modem Control Register.
> -  //
> -  Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
> -  Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS));
> -
> -  if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) ==
> EFI_SERIAL_DATA_TERMINAL_READY) {
> -    Mcr |= B_UART_MCR_DTRC;
> -  }
> -
> -  if ((Control & EFI_SERIAL_REQUEST_TO_SEND) ==
> EFI_SERIAL_REQUEST_TO_SEND) {
> -    Mcr |= B_UART_MCR_RTS;
> -  }
> -
> -  //
> -  // Write the Modem Control Register.
> -  //
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr);
> -
> -  return RETURN_SUCCESS;
> -}
> -
> -/**
> -  Retrieve the status of the control bits on a serial device.
> -
> -  @param Control                A pointer to return the current control signals from
> the serial device.
> -
> -  @retval RETURN_SUCCESS        The control bits were read from the serial
> device.
> -  @retval RETURN_UNSUPPORTED    The serial device does not support this
> operation.
> -  @retval RETURN_DEVICE_ERROR   The serial device is not functioning
> correctly.
> -
> -**/
> -RETURN_STATUS
> -EFIAPI
> -SerialPortGetControl (
> -  OUT UINT32 *Control
> -  )
> -{
> -  UINTN SerialRegisterBase;
> -  UINT8 Msr;
> -  UINT8 Mcr;
> -  UINT8 Lsr;
> -
> -  SerialRegisterBase = GetSerialRegisterBase ();
> -  if (SerialRegisterBase ==0) {
> -    return RETURN_UNSUPPORTED;
> -  }
> -
> -  *Control = 0;
> -
> -  //
> -  // Read the Modem Status Register.
> -  //
> -  Msr = SerialPortReadRegister (SerialRegisterBase, R_UART_MSR);
> -
> -  if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) {
> -    *Control |= EFI_SERIAL_CLEAR_TO_SEND;
> -  }
> -
> -  if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) {
> -    *Control |= EFI_SERIAL_DATA_SET_READY;
> -  }
> -
> -  if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) {
> -    *Control |= EFI_SERIAL_RING_INDICATE;
> -  }
> -
> -  if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) {
> -    *Control |= EFI_SERIAL_CARRIER_DETECT;
> -  }
> -
> -  //
> -  // Read the Modem Control Register.
> -  //
> -  Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
> -
> -  if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) {
> -    *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
> -  }
> -
> -  if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) {
> -    *Control |= EFI_SERIAL_REQUEST_TO_SEND;
> -  }
> -
> -  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> -    *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
> -  }
> -
> -  //
> -  // Read the Line Status Register.
> -  //
> -  Lsr = SerialPortReadRegister (SerialRegisterBase, R_UART_LSR);
> -
> -  if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) ==
> (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) {
> -    *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
> -  }
> -
> -  if ((Lsr & B_UART_LSR_RXRDY) == 0) {
> -    *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
> -  }
> -
> -  return RETURN_SUCCESS;
> -}
> -
> -/**
> +  If there is data waiting to be read from the serial device, then TRUE is
> returned.
> +  If there is no data waiting to be read from the serial device, then FALSE is
> returned.
> +
> +  @retval TRUE             Data is waiting to be read from the serial device.
> +  @retval FALSE            There is no data waiting to be read from the serial
> device.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +SerialPortPoll (
> +  VOID
> +  )
> +{
> +  UINTN  SerialRegisterBase;
> +
> +  SerialRegisterBase = GetSerialRegisterBase ();
> +  if (SerialRegisterBase ==0) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // Read the serial port status
> +  //
> +  if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) &
> B_UART_LSR_RXRDY) != 0) {
> +    if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> +      //
> +      // Clear RTS to prevent peer from sending data
> +      //
> +      SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR,
> (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) &
> ~B_UART_MCR_RTS));
> +    }
> +    return TRUE;
> +  }
> +
> +  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> +    //
> +    // Set RTS to let the peer send some data
> +    //
> +    SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR,
> (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) |
> B_UART_MCR_RTS));
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Sets the control bits on a serial device.
> +
> +  @param Control                Sets the bits of Control that are settable.
> +
> +  @retval RETURN_SUCCESS        The new control bits were set on the serial
> device.
> +  @retval RETURN_UNSUPPORTED    The serial device does not support this
> operation.
> +  @retval RETURN_DEVICE_ERROR   The serial device is not functioning
> correctly.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortSetControl (
> +  IN UINT32 Control
> +  )
> +{
> +  UINTN SerialRegisterBase;
> +  UINT8 Mcr;
> +
> +  //
> +  // First determine the parameter is invalid.
> +  //
> +  if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND |
> EFI_SERIAL_DATA_TERMINAL_READY |
> +                    EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) {
> +    return RETURN_UNSUPPORTED;
> +  }
> +
> +  SerialRegisterBase = GetSerialRegisterBase ();
> +  if (SerialRegisterBase ==0) {
> +    return RETURN_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Read the Modem Control Register.
> +  //
> +  Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
> +  Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS));
> +
> +  if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) ==
> EFI_SERIAL_DATA_TERMINAL_READY) {
> +    Mcr |= B_UART_MCR_DTRC;
> +  }
> +
> +  if ((Control & EFI_SERIAL_REQUEST_TO_SEND) ==
> EFI_SERIAL_REQUEST_TO_SEND) {
> +    Mcr |= B_UART_MCR_RTS;
> +  }
> +
> +  //
> +  // Write the Modem Control Register.
> +  //
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr);
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Retrieve the status of the control bits on a serial device.
> +
> +  @param Control                A pointer to return the current control signals
> from the serial device.
> +
> +  @retval RETURN_SUCCESS        The control bits were read from the serial
> device.
> +  @retval RETURN_UNSUPPORTED    The serial device does not support this
> operation.
> +  @retval RETURN_DEVICE_ERROR   The serial device is not functioning
> correctly.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortGetControl (
> +  OUT UINT32 *Control
> +  )
> +{
> +  UINTN SerialRegisterBase;
> +  UINT8 Msr;
> +  UINT8 Mcr;
> +  UINT8 Lsr;
> +
> +  SerialRegisterBase = GetSerialRegisterBase ();
> +  if (SerialRegisterBase ==0) {
> +    return RETURN_UNSUPPORTED;
> +  }
> +
> +  *Control = 0;
> +
> +  //
> +  // Read the Modem Status Register.
> +  //
> +  Msr = SerialPortReadRegister (SerialRegisterBase, R_UART_MSR);
> +
> +  if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) {
> +    *Control |= EFI_SERIAL_CLEAR_TO_SEND;
> +  }
> +
> +  if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) {
> +    *Control |= EFI_SERIAL_DATA_SET_READY;
> +  }
> +
> +  if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) {
> +    *Control |= EFI_SERIAL_RING_INDICATE;
> +  }
> +
> +  if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) {
> +    *Control |= EFI_SERIAL_CARRIER_DETECT;
> +  }
> +
> +  //
> +  // Read the Modem Control Register.
> +  //
> +  Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR);
> +
> +  if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) {
> +    *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
> +  }
> +
> +  if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) {
> +    *Control |= EFI_SERIAL_REQUEST_TO_SEND;
> +  }
> +
> +  if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
> +    *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
> +  }
> +
> +  //
> +  // Read the Line Status Register.
> +  //
> +  Lsr = SerialPortReadRegister (SerialRegisterBase, R_UART_LSR);
> +
> +  if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) ==
> (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) {
> +    *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
> +  }
> +
> +  if ((Lsr & B_UART_LSR_RXRDY) == 0) {
> +    *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
>    Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,
> -  data bits, and stop bits on a serial device.
> -
> -  @param BaudRate           The requested baud rate. A BaudRate value of 0
> will use the
> -                            device's default interface speed.
> -                            On output, the value actually set.
> +  data bits, and stop bits on a serial device.
> +
> +  @param BaudRate           The requested baud rate. A BaudRate value of 0
> will use the
> +                            device's default interface speed.
> +                            On output, the value actually set.
>    @param ReceiveFifoDepth   The requested depth of the FIFO on the
> receive side of the
> -                            serial interface. A ReceiveFifoDepth value of 0 will use
> -                            the device's default FIFO depth.
> -                            On output, the value actually set.
> -  @param Timeout            The requested time out for a single character in
> microseconds.
> -                            This timeout applies to both the transmit and receive side of
> the
> -                            interface. A Timeout value of 0 will use the device's default
> time
> -                            out value.
> -                            On output, the value actually set.
> -  @param Parity             The type of parity to use on this serial device. A Parity
> value of
> -                            DefaultParity will use the device's default parity value.
> -                            On output, the value actually set.
> -  @param DataBits           The number of data bits to use on the serial device.
> A DataBits
> +                            serial interface. A ReceiveFifoDepth value of 0 will use
> +                            the device's default FIFO depth.
> +                            On output, the value actually set.
> +  @param Timeout            The requested time out for a single character in
> microseconds.
> +                            This timeout applies to both the transmit and receive side of
> the
> +                            interface. A Timeout value of 0 will use the device's default
> time
> +                            out value.
> +                            On output, the value actually set.
> +  @param Parity             The type of parity to use on this serial device. A Parity
> value of
> +                            DefaultParity will use the device's default parity value.
> +                            On output, the value actually set.
> +  @param DataBits           The number of data bits to use on the serial device.
> A DataBits
>                              value of 0 will use the device's default data bit setting.
> -                            On output, the value actually set.
> -  @param StopBits           The number of stop bits to use on this serial device.
> A StopBits
> -                            value of DefaultStopBits will use the device's default number
> of
> -                            stop bits.
> -                            On output, the value actually set.
> -
> -  @retval RETURN_SUCCESS            The new attributes were set on the serial
> device.
> -  @retval RETURN_UNSUPPORTED        The serial device does not support
> this operation.
> -  @retval RETURN_INVALID_PARAMETER  One or more of the attributes has
> an unsupported value.
> -  @retval RETURN_DEVICE_ERROR       The serial device is not functioning
> correctly.
> -
> -**/
> -RETURN_STATUS
> -EFIAPI
> -SerialPortSetAttributes (
> -  IN OUT UINT64             *BaudRate,
> -  IN OUT UINT32             *ReceiveFifoDepth,
> -  IN OUT UINT32             *Timeout,
> -  IN OUT EFI_PARITY_TYPE    *Parity,
> -  IN OUT UINT8              *DataBits,
> -  IN OUT EFI_STOP_BITS_TYPE *StopBits
> -  )
> -{
> -  UINTN     SerialRegisterBase;
> -  UINT32    SerialBaudRate;
> -  UINTN     Divisor;
> -  UINT8     Lcr;
> -  UINT8     LcrData;
> -  UINT8     LcrParity;
> -  UINT8     LcrStop;
> -
> -  SerialRegisterBase = GetSerialRegisterBase ();
> -  if (SerialRegisterBase ==0) {
> -    return RETURN_UNSUPPORTED;
> -  }
> -
> -  //
> -  // Check for default settings and fill in actual values.
> -  //
> -  if (*BaudRate == 0) {
> -    *BaudRate = PcdGet32 (PcdSerialBaudRate);
> -  }
> -  SerialBaudRate = (UINT32) *BaudRate;
> -
> -  if (*DataBits == 0) {
> -    LcrData = (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3);
> -    *DataBits = LcrData + 5;
> -  } else {
> -    if ((*DataBits < 5) || (*DataBits > 8)) {
> -      return RETURN_INVALID_PARAMETER;
> -    }
> -    //
> -    // Map 5..8 to 0..3
> -    //
> -    LcrData = (UINT8) (*DataBits - (UINT8) 5);
> -  }
> -
> -  if (*Parity == DefaultParity) {
> -    LcrParity = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7);
> -    switch (LcrParity) {
> -      case 0:
> -        *Parity = NoParity;
> -        break;
> -
> -      case 3:
> -        *Parity = EvenParity;
> -        break;
> -
> -      case 1:
> -        *Parity = OddParity;
> -        break;
> -
> -      case 7:
> -        *Parity = SpaceParity;
> -        break;
> -
> -      case 5:
> -        *Parity = MarkParity;
> -        break;
> -
> -      default:
> -        break;
> -    }
> -  } else {
> -    switch (*Parity) {
> -      case NoParity:
> -        LcrParity = 0;
> -        break;
> -
> -      case EvenParity:
> -        LcrParity = 3;
> -        break;
> -
> -      case OddParity:
> -        LcrParity = 1;
> -        break;
> -
> -      case SpaceParity:
> -        LcrParity = 7;
> -        break;
> -
> -      case MarkParity:
> -        LcrParity = 5;
> -        break;
> -
> -      default:
> -        return RETURN_INVALID_PARAMETER;
> -    }
> -  }
> -
> -  if (*StopBits == DefaultStopBits) {
> -    LcrStop = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1);
> -    switch (LcrStop) {
> -      case 0:
> -        *StopBits = OneStopBit;
> -        break;
> -
> -      case 1:
> -        if (*DataBits == 5) {
> -          *StopBits = OneFiveStopBits;
> -        } else {
> -          *StopBits = TwoStopBits;
> -        }
> -        break;
> -
> -      default:
> -        break;
> -    }
> -  } else {
> -    switch (*StopBits) {
> -      case OneStopBit:
> -        LcrStop = 0;
> -        break;
> -
> -      case OneFiveStopBits:
> -      case TwoStopBits:
> -        LcrStop = 1;
> -        break;
> -
> -      default:
> -        return RETURN_INVALID_PARAMETER;
> -    }
> -  }
> -
> -  //
> -  // Calculate divisor for baud generator
> -  //    Ref_Clk_Rate / Baud_Rate / 16
> -  //
> -  Divisor = PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16);
> -  if ((PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >=
> SerialBaudRate * 8) {
> -    Divisor++;
> -  }
> -
> -  //
> -  // Configure baud rate
> -  //
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> B_UART_LCR_DLAB);
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)
> (Divisor >> 8));
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)
> (Divisor & 0xff));
> -
> -  //
> -  // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
> -  // Strip reserved bits from line control value
> -  //
> -  Lcr = (UINT8) ((LcrParity << 3) | (LcrStop << 2) | LcrData);
> -  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8) (Lcr &
> 0x3F));
> -
> -  return RETURN_SUCCESS;
> -}
> -
> +                            On output, the value actually set.
> +  @param StopBits           The number of stop bits to use on this serial device.
> A StopBits
> +                            value of DefaultStopBits will use the device's default number
> of
> +                            stop bits.
> +                            On output, the value actually set.
> +
> +  @retval RETURN_SUCCESS            The new attributes were set on the serial
> device.
> +  @retval RETURN_UNSUPPORTED        The serial device does not support
> this operation.
> +  @retval RETURN_INVALID_PARAMETER  One or more of the attributes has
> an unsupported value.
> +  @retval RETURN_DEVICE_ERROR       The serial device is not functioning
> correctly.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortSetAttributes (
> +  IN OUT UINT64             *BaudRate,
> +  IN OUT UINT32             *ReceiveFifoDepth,
> +  IN OUT UINT32             *Timeout,
> +  IN OUT EFI_PARITY_TYPE    *Parity,
> +  IN OUT UINT8              *DataBits,
> +  IN OUT EFI_STOP_BITS_TYPE *StopBits
> +  )
> +{
> +  UINTN     SerialRegisterBase;
> +  UINT32    SerialBaudRate;
> +  UINTN     Divisor;
> +  UINT8     Lcr;
> +  UINT8     LcrData;
> +  UINT8     LcrParity;
> +  UINT8     LcrStop;
> +
> +  SerialRegisterBase = GetSerialRegisterBase ();
> +  if (SerialRegisterBase ==0) {
> +    return RETURN_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Check for default settings and fill in actual values.
> +  //
> +  if (*BaudRate == 0) {
> +    *BaudRate = PcdGet32 (PcdSerialBaudRate);
> +  }
> +  SerialBaudRate = (UINT32) *BaudRate;
> +
> +  if (*DataBits == 0) {
> +    LcrData = (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3);
> +    *DataBits = LcrData + 5;
> +  } else {
> +    if ((*DataBits < 5) || (*DataBits > 8)) {
> +      return RETURN_INVALID_PARAMETER;
> +    }
> +    //
> +    // Map 5..8 to 0..3
> +    //
> +    LcrData = (UINT8) (*DataBits - (UINT8) 5);
> +  }
> +
> +  if (*Parity == DefaultParity) {
> +    LcrParity = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7);
> +    switch (LcrParity) {
> +      case 0:
> +        *Parity = NoParity;
> +        break;
> +
> +      case 3:
> +        *Parity = EvenParity;
> +        break;
> +
> +      case 1:
> +        *Parity = OddParity;
> +        break;
> +
> +      case 7:
> +        *Parity = SpaceParity;
> +        break;
> +
> +      case 5:
> +        *Parity = MarkParity;
> +        break;
> +
> +      default:
> +        break;
> +    }
> +  } else {
> +    switch (*Parity) {
> +      case NoParity:
> +        LcrParity = 0;
> +        break;
> +
> +      case EvenParity:
> +        LcrParity = 3;
> +        break;
> +
> +      case OddParity:
> +        LcrParity = 1;
> +        break;
> +
> +      case SpaceParity:
> +        LcrParity = 7;
> +        break;
> +
> +      case MarkParity:
> +        LcrParity = 5;
> +        break;
> +
> +      default:
> +        return RETURN_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  if (*StopBits == DefaultStopBits) {
> +    LcrStop = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1);
> +    switch (LcrStop) {
> +      case 0:
> +        *StopBits = OneStopBit;
> +        break;
> +
> +      case 1:
> +        if (*DataBits == 5) {
> +          *StopBits = OneFiveStopBits;
> +        } else {
> +          *StopBits = TwoStopBits;
> +        }
> +        break;
> +
> +      default:
> +        break;
> +    }
> +  } else {
> +    switch (*StopBits) {
> +      case OneStopBit:
> +        LcrStop = 0;
> +        break;
> +
> +      case OneFiveStopBits:
> +      case TwoStopBits:
> +        LcrStop = 1;
> +        break;
> +
> +      default:
> +        return RETURN_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  //
> +  // Calculate divisor for baud generator
> +  //    Ref_Clk_Rate / Baud_Rate / 16
> +  //
> +  Divisor = PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16);
> +  if ((PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >=
> SerialBaudRate * 8) {
> +    Divisor++;
> +  }
> +
> +  //
> +  // Configure baud rate
> +  //
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,
> B_UART_LCR_DLAB);
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)
> (Divisor >> 8));
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)
> (Divisor & 0xff));
> +
> +  //
> +  // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
> +  // Strip reserved bits from line control value
> +  //
> +  Lcr = (UINT8) ((LcrParity << 3) | (LcrStop << 2) | LcrData);
> +  SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8) (Lcr &
> 0x3F));
> +
> +  return RETURN_SUCCESS;
> +}
> +
> diff --git a/CorebootModulePkg/SataControllerDxe/SataController.h
> b/CorebootModulePkg/SataControllerDxe/SataController.h
> index 1ef4555615..d13ab889d9 100644
> --- a/CorebootModulePkg/SataControllerDxe/SataController.h
> +++ b/CorebootModulePkg/SataControllerDxe/SataController.h
> @@ -1,542 +1,542 @@
> -/** @file
> -  Header file for Sata Controller driver.
> -
> -  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
> -  This program and the accompanying materials
> -  are licensed and made available under the terms and conditions of the BSD
> License
> -  which accompanies this distribution.  The full text of the license may be
> found at
> -  http://opensource.org/licenses/bsd-license.php
> -
> -  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> -  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> -
> -**/
> -
> -#ifndef _SATA_CONTROLLER_H_
> -#define _SATA_CONTROLLER_H_
> -
> -#include <Uefi.h>
> -#include <Protocol/ComponentName.h>
> -#include <Protocol/DriverBinding.h>
> -#include <Protocol/PciIo.h>
> -#include <Protocol/IdeControllerInit.h>
> -#include <Library/UefiDriverEntryPoint.h>
> -#include <Library/DebugLib.h>
> -#include <Library/UefiLib.h>
> -#include <Library/BaseLib.h>
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/MemoryAllocationLib.h>
> -#include <Library/UefiBootServicesTableLib.h>
> -#include <IndustryStandard/Pci.h>
> -
> -//
> -// Global Variables definitions
> -//
> -extern EFI_DRIVER_BINDING_PROTOCOL  gSataControllerDriverBinding;
> -extern EFI_COMPONENT_NAME_PROTOCOL
> gSataControllerComponentName;
> -extern EFI_COMPONENT_NAME2_PROTOCOL
> gSataControllerComponentName2;
> -
> -#define AHCI_BAR_INDEX 0x05
> -#define R_AHCI_CAP 0x0
> -#define   B_AHCI_CAP_NPS (BIT4 | BIT3 | BIT2 | BIT1 | BIT0) // Number of
> Ports
> -#define   B_AHCI_CAP_SPM BIT17 // Supports Port Multiplier
> -
> -///
> -/// AHCI each channel can have up to 1 device
> -///
> -#define AHCI_MAX_DEVICES 0x01
> -
> -///
> -/// AHCI each channel can have 15 devices in the presence of a multiplier
> -///
> -#define AHCI_MULTI_MAX_DEVICES 0x0F
> -
> -///
> -/// IDE supports 2 channel max
> -///
> -#define IDE_MAX_CHANNEL 0x02
> -
> -///
> -/// IDE supports 2 devices max
> -///
> -#define IDE_MAX_DEVICES 0x02
> -
> -#define SATA_ENUMER_ALL FALSE
> -
> -//
> -// Sata Controller driver private data structure
> -//
> -
> -#define SATA_CONTROLLER_SIGNATURE SIGNATURE_32('S','A','T','A')
> -
> -typedef struct _EFI_SATA_CONTROLLER_PRIVATE_DATA {
> -  //
> -  // Standard signature used to identify Sata Controller private data
> -  //
> -  UINT32                            Signature;
> -
> -  //
> -  // Protocol instance of IDE_CONTROLLER_INIT produced by this driver
> -  //
> -  EFI_IDE_CONTROLLER_INIT_PROTOCOL  IdeInit;
> -
> -  //
> -  // Copy of protocol pointers used by this driver
> -  //
> -  EFI_PCI_IO_PROTOCOL               *PciIo;
> -
> -  //
> -  // The number of devices that are supported by this channel
> -  //
> -  UINT8                             DeviceCount;
> -
> -  //
> +/** @file
> +  Header file for Sata Controller driver.
> +
> +  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD
> License
> +  which accompanies this distribution.  The full text of the license may be
> found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef _SATA_CONTROLLER_H_
> +#define _SATA_CONTROLLER_H_
> +
> +#include <Uefi.h>
> +#include <Protocol/ComponentName.h>
> +#include <Protocol/DriverBinding.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/IdeControllerInit.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <IndustryStandard/Pci.h>
> +
> +//
> +// Global Variables definitions
> +//
> +extern EFI_DRIVER_BINDING_PROTOCOL  gSataControllerDriverBinding;
> +extern EFI_COMPONENT_NAME_PROTOCOL
> gSataControllerComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL
> gSataControllerComponentName2;
> +
> +#define AHCI_BAR_INDEX 0x05
> +#define R_AHCI_CAP 0x0
> +#define   B_AHCI_CAP_NPS (BIT4 | BIT3 | BIT2 | BIT1 | BIT0) // Number of
> Ports
> +#define   B_AHCI_CAP_SPM BIT17 // Supports Port Multiplier
> +
> +///
> +/// AHCI each channel can have up to 1 device
> +///
> +#define AHCI_MAX_DEVICES 0x01
> +
> +///
> +/// AHCI each channel can have 15 devices in the presence of a multiplier
> +///
> +#define AHCI_MULTI_MAX_DEVICES 0x0F
> +
> +///
> +/// IDE supports 2 channel max
> +///
> +#define IDE_MAX_CHANNEL 0x02
> +
> +///
> +/// IDE supports 2 devices max
> +///
> +#define IDE_MAX_DEVICES 0x02
> +
> +#define SATA_ENUMER_ALL FALSE
> +
> +//
> +// Sata Controller driver private data structure
> +//
> +
> +#define SATA_CONTROLLER_SIGNATURE SIGNATURE_32('S','A','T','A')
> +
> +typedef struct _EFI_SATA_CONTROLLER_PRIVATE_DATA {
> +  //
> +  // Standard signature used to identify Sata Controller private data
> +  //
> +  UINT32                            Signature;
> +
> +  //
> +  // Protocol instance of IDE_CONTROLLER_INIT produced by this driver
> +  //
> +  EFI_IDE_CONTROLLER_INIT_PROTOCOL  IdeInit;
> +
> +  //
> +  // Copy of protocol pointers used by this driver
> +  //
> +  EFI_PCI_IO_PROTOCOL               *PciIo;
> +
> +  //
> +  // The number of devices that are supported by this channel
> +  //
> +  UINT8                             DeviceCount;
> +
> +  //
>    // The highest disqualified mode for each attached device,
> -  // From ATA/ATAPI spec, if a mode is not supported,
> -  // the modes higher than it is also not supported
> -  //
> -  EFI_ATA_COLLECTIVE_MODE           *DisqualifiedModes;
> -
> -  //
> -  // A copy of EFI_IDENTIFY_DATA data for each attached SATA device and its
> flag
> -  //
> -  EFI_IDENTIFY_DATA                 *IdentifyData;
> -  BOOLEAN                           *IdentifyValid;
> -} EFI_SATA_CONTROLLER_PRIVATE_DATA;
> -
> -#define SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS(a) CR(a,
> EFI_SATA_CONTROLLER_PRIVATE_DATA, IdeInit,
> SATA_CONTROLLER_SIGNATURE)
> -
> -//
> -// Driver binding functions declaration
> -//
> -/**
> -  Supported function of Driver Binding protocol for this driver.
> -  Test to see if this driver supports ControllerHandle.
> -
> -  @param This                   Protocol instance pointer.
> -  @param Controller             Handle of device to test.
> -  @param RemainingDevicePath    A pointer to the device path. Should be
> ignored by
> -                                device driver.
> -
> -  @retval EFI_SUCCESS           This driver supports this device.
> -  @retval EFI_ALREADY_STARTED   This driver is already running on this
> device.
> -  @retval other                 This driver does not support this device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SataControllerSupported (
> -  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> -  IN EFI_HANDLE                     Controller,
> -  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> -  )
> -;
> -
> -/**
> -  This routine is called right after the .Supported() called and
> -  Start this driver on ControllerHandle.
> -
> -  @param This                   Protocol instance pointer.
> -  @param Controller             Handle of device to bind driver to.
> -  @param RemainingDevicePath    A pointer to the device path. Should be
> ignored by
> -                                device driver.
> -
> -  @retval EFI_SUCCESS           This driver is added to this device.
> -  @retval EFI_ALREADY_STARTED   This driver is already running on this
> device.
> -  @retval other                 Some error occurs when binding this driver to this
> device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SataControllerStart (
> -  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> -  IN EFI_HANDLE                     Controller,
> -  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> -  )
> -;
> -
> -/**
> -  Stop this driver on ControllerHandle.
> -
> -  @param This               Protocol instance pointer.
> -  @param Controller         Handle of device to stop driver on.
> -  @param NumberOfChildren   Not used.
> -  @param ChildHandleBuffer  Not used.
> -
> -  @retval EFI_SUCCESS   This driver is removed from this device.
> -  @retval other         Some error occurs when removing this driver from this
> device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SataControllerStop (
> -  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> -  IN EFI_HANDLE                     Controller,
> -  IN UINTN                          NumberOfChildren,
> -  IN EFI_HANDLE                     *ChildHandleBuffer
> -  )
> -;
> -
> -//
> -// IDE controller init functions declaration
> -//
> -/**
> -  Returns the information about the specified IDE channel.
> -
> -  This function can be used to obtain information about a particular IDE
> channel.
> -  The driver entity uses this information during the enumeration process.
> -
> -  If Enabled is set to FALSE, the driver entity will not scan the channel. Note
> -  that it will not prevent an operating system driver from scanning the
> channel.
> -
> -  For most of today's controllers, MaxDevices will either be 1 or 2. For SATA
> -  controllers, this value will always be 1. SATA configurations can contain
> SATA
> -  port multipliers. SATA port multipliers behave like SATA bridges and can
> support
> -  up to 16 devices on the other side. If a SATA port out of the IDE controller
> -  is connected to a port multiplier, MaxDevices will be set to the number of
> SATA
> -  devices that the port multiplier supports. Because today's port multipliers
> -  support up to fifteen SATA devices, this number can be as large as fifteen.
> The IDE
> -  bus driver is required to scan for the presence of port multipliers behind an
> SATA
> -  controller and enumerate up to MaxDevices number of devices behind the
> port
> -  multiplier.
> -
> -  In this context, the devices behind a port multiplier constitute a channel.
> -
> -  @param[in]  This         The pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> -  @param[in]  Channel      Zero-based channel number.
> -  @param[out] Enabled      TRUE if this channel is enabled.  Disabled channels
> -                           are not scanned to see if any devices are present.
> -  @param[out] MaxDevices   The maximum number of IDE devices that the
> bus driver
> -                           can expect on this channel.  For the ATA/ATAPI
> -                           specification, version 6, this number will either be
> -                           one or two. For Serial ATA (SATA) configurations with a
> -                           port multiplier, this number can be as large as fifteen.
> -
> -  @retval EFI_SUCCESS             Information was returned without any errors.
> -  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -IdeInitGetChannelInfo (
> -  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> -  IN UINT8                              Channel,
> -  OUT BOOLEAN                           *Enabled,
> -  OUT UINT8                             *MaxDevices
> -  )
> -;
> -
> -/**
> -  The notifications from the driver entity that it is about to enter a certain
> -  phase of the IDE channel enumeration process.
> -
> -  This function can be used to notify the IDE controller driver to perform
> -  specific actions, including any chipset-specific initialization, so that the
> -  chipset is ready to enter the next phase. Seven notification points are
> defined
> -  at this time.
> -
> -  More synchronization points may be added as required in the future.
> -
> -  @param[in] This      The pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> -  @param[in] Phase     The phase during enumeration.
> -  @param[in] Channel   Zero-based channel number.
> -
> -  @retval EFI_SUCCESS             The notification was accepted without any
> errors.
> -  @retval EFI_UNSUPPORTED         Phase is not supported.
> -  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> -  @retval EFI_NOT_READY           This phase cannot be entered at this time;
> for
> -                                  example, an attempt was made to enter a Phase
> -                                  without having entered one or more previous
> -                                  Phase.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -IdeInitNotifyPhase (
> -  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> -  IN EFI_IDE_CONTROLLER_ENUM_PHASE      Phase,
> -  IN UINT8                              Channel
> -  )
> -;
> -
> -/**
> -  Submits the device information to the IDE controller driver.
> -
> -  This function is used by the driver entity to pass detailed information about
> -  a particular device to the IDE controller driver. The driver entity obtains
> -  this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command.
> IdentifyData
> -  is the pointer to the response data buffer. The IdentifyData buffer is
> owned
> -  by the driver entity, and the IDE controller driver must make a local copy
> -  of the entire buffer or parts of the buffer as needed. The original
> IdentifyData
> -  buffer pointer may not be valid when
> -
> -    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or
> -    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a
> later point.
> -
> -  The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA
> to
> -  compute the optimum mode for the device. These fields are not limited to
> the
> -  timing information. For example, an implementation of the IDE controller
> driver
> -  may examine the vendor and type/mode field to match known bad drives.
> -
> -  The driver entity may submit drive information in any order, as long as it
> -  submits information for all the devices belonging to the enumeration group
> -  before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called
> for any device
> -  in that enumeration group. If a device is absent,
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
> -  should be called with IdentifyData set to NULL.  The IDE controller driver
> may
> -  not have any other mechanism to know whether a device is present or not.
> Therefore,
> -  setting IdentifyData to NULL does not constitute an error condition.
> -  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only
> once for a
> -  given (Channel, Device) pair.
> -
> -  @param[in] This           A pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> -  @param[in] Channel        Zero-based channel number.
> -  @param[in] Device         Zero-based device number on the Channel.
> -  @param[in] IdentifyData   The device's response to the ATA
> IDENTIFY_DEVICE command.
> -
> -  @retval EFI_SUCCESS             The information was accepted without any
> errors.
> -  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> -  @retval EFI_INVALID_PARAMETER   Device is invalid.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -IdeInitSubmitData (
> -  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> -  IN UINT8                              Channel,
> -  IN UINT8                              Device,
> -  IN EFI_IDENTIFY_DATA                  *IdentifyData
> -  )
> -;
> -
> -/**
> -  Disqualifies specific modes for an IDE device.
> -
> -  This function allows the driver entity or other drivers (such as platform
> -  drivers) to reject certain timing modes and request the IDE controller driver
> -  to recalculate modes. This function allows the driver entity and the IDE
> -  controller driver to negotiate the timings on a per-device basis. This
> function
> -  is useful in the case of drives that lie about their capabilities. An example
> -  is when the IDE device fails to accept the timing modes that are calculated
> -  by the IDE controller driver based on the response to the Identify Drive
> command.
> -
> -  If the driver entity does not want to limit the ATA timing modes and leave
> that
> -  decision to the IDE controller driver, it can either not call this function for
> -  the given device or call this function and set the Valid flag to FALSE for all
> -  modes that are listed in EFI_ATA_COLLECTIVE_MODE.
> -
> -  The driver entity may disqualify modes for a device in any order and any
> number
> -  of times.
> -
> -  This function can be called multiple times to invalidate multiple modes of
> the
> -  same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the
> ATA/ATAPI
> -  specification for more information on PIO modes.
> -
> -  For Serial ATA (SATA) controllers, this member function can be used to
> disqualify
> -  a higher transfer rate mode on a given channel. For example, a platform
> driver
> -  may inform the IDE controller driver to not use second-generation (Gen2)
> speeds
> -  for a certain SATA drive.
> -
> -  @param[in] This       The pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> -  @param[in] Channel    The zero-based channel number.
> -  @param[in] Device     The zero-based device number on the Channel.
> -  @param[in] BadModes   The modes that the device does not support and
> that
> -                        should be disqualified.
> -
> -  @retval EFI_SUCCESS             The modes were accepted without any errors.
> -  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> -  @retval EFI_INVALID_PARAMETER   Device is invalid.
> -  @retval EFI_INVALID_PARAMETER   IdentifyData is NULL.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -IdeInitDisqualifyMode (
> -  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> -  IN UINT8                              Channel,
> -  IN UINT8                              Device,
> -  IN EFI_ATA_COLLECTIVE_MODE            *BadModes
> -  )
> -;
> -
> -/**
> -  Returns the information about the optimum modes for the specified IDE
> device.
> -
> -  This function is used by the driver entity to obtain the optimum ATA modes
> for
> -  a specific device.  The IDE controller driver takes into account the following
> -  while calculating the mode:
> -    - The IdentifyData inputs to
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
> -    - The BadModes inputs to
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()
> -
> -  The driver entity is required to call
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
> -  for all the devices that belong to an enumeration group before calling
> -  EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in
> the same group.
> -
> -  The IDE controller driver will use controller- and possibly platform-specific
> -  algorithms to arrive at SupportedModes.  The IDE controller may base its
> -  decision on user preferences and other considerations as well. This
> function
> -  may be called multiple times because the driver entity may renegotiate the
> mode
> -  with the IDE controller driver using
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().
> -
> -  The driver entity may collect timing information for various devices in any
> -  order. The driver entity is responsible for making sure that all the
> dependencies
> -  are satisfied. For example, the SupportedModes information for device A
> that
> -  was previously returned may become stale after a call to
> -  EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.
> -
> -  The buffer SupportedModes is allocated by the callee because the caller
> does
> -  not necessarily know the size of the buffer. The type
> EFI_ATA_COLLECTIVE_MODE
> -  is defined in a way that allows for future extensibility and can be of variable
> -  length. This memory pool should be deallocated by the caller when it is no
> -  longer necessary.
> -
> -  The IDE controller driver for a Serial ATA (SATA) controller can use this
> -  member function to force a lower speed (first-generation [Gen1] speeds
> on a
> -  second-generation [Gen2]-capable hardware).  The IDE controller driver
> can
> -  also allow the driver entity to stay with the speed that has been negotiated
> -  by the physical layer.
> -
> -  @param[in]  This             The pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> -  @param[in]  Channel          A zero-based channel number.
> -  @param[in]  Device           A zero-based device number on the Channel.
> -  @param[out] SupportedModes   The optimum modes for the device.
> -
> -  @retval EFI_SUCCESS             SupportedModes was returned.
> -  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> -  @retval EFI_INVALID_PARAMETER   Device is invalid.
> -  @retval EFI_INVALID_PARAMETER   SupportedModes is NULL.
> -  @retval EFI_NOT_READY           Modes cannot be calculated due to a lack of
> -                                  data.  This error may happen if
> -                                  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
> -                                  and
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData()
> -                                  were not called for at least one drive in the
> -                                  same enumeration group.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -IdeInitCalculateMode (
> -  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> -  IN UINT8                              Channel,
> -  IN UINT8                              Device,
> -  OUT EFI_ATA_COLLECTIVE_MODE           **SupportedModes
> -  )
> -;
> -
> -/**
> -  Commands the IDE controller driver to program the IDE controller hardware
> -  so that the specified device can operate at the specified mode.
> -
> -  This function is used by the driver entity to instruct the IDE controller
> -  driver to program the IDE controller hardware to the specified modes. This
> -  function can be called only once for a particular device. For a Serial ATA
> -  (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-
> -  specific programming may be required.
> -
> -  @param[in] This      Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL
> instance.
> -  @param[in] Channel   Zero-based channel number.
> -  @param[in] Device    Zero-based device number on the Channel.
> -  @param[in] Modes     The modes to set.
> -
> -  @retval EFI_SUCCESS             The command was accepted without any errors.
> -  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> -  @retval EFI_INVALID_PARAMETER   Device is invalid.
> -  @retval EFI_NOT_READY           Modes cannot be set at this time due to lack
> of data.
> -  @retval EFI_DEVICE_ERROR        Modes cannot be set due to hardware
> failure.
> -                                  The driver entity should not use this device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -IdeInitSetTiming (
> -  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> -  IN UINT8                              Channel,
> -  IN UINT8                              Device,
> -  IN EFI_ATA_COLLECTIVE_MODE            *Modes
> -  )
> -;
> -
> -//
> -// Forward reference declaration
> -//
> -/**
> -  Retrieves a Unicode string that is the user readable name of the UEFI Driver.
> -
> -  @param This           A pointer to the EFI_COMPONENT_NAME_PROTOCOL
> instance.
> -  @param Language       A pointer to a three character ISO 639-2 language
> identifier.
> -                        This is the language of the driver name that that the caller
> -                        is requesting, and it must match one of the languages specified
> -                        in SupportedLanguages.  The number of languages supported by
> a
> -                        driver is up to the driver writer.
> -  @param DriverName     A pointer to the Unicode string to return.  This
> Unicode string
> -                        is the name of the driver specified by This in the language
> -                        specified by Language.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> This
> -                                and the language specified by Language was returned
> -                                in DriverName.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support the
> -                                language specified by Language.
> -**/
> -EFI_STATUS
> -EFIAPI
> -SataControllerComponentNameGetDriverName (
> -  IN EFI_COMPONENT_NAME_PROTOCOL    *This,
> -  IN CHAR8                          *Language,
> -  OUT CHAR16                        **DriverName
> -  )
> -;
> -
> -/**
> -  Retrieves a Unicode string that is the user readable name of the controller
> -  that is being managed by an UEFI Driver.
> -
> -  @param This                   A pointer to the
> EFI_COMPONENT_NAME_PROTOCOL instance.
> -  @param ControllerHandle       The handle of a controller that the driver
> specified by
> -                                This is managing.  This handle specifies the controller
> -                                whose name is to be returned.
> -  @param OPTIONAL   ChildHandle The handle of the child controller to
> retrieve the name
> -                                of.  This is an optional parameter that may be NULL.  It
> -                                will be NULL for device drivers.  It will also be NULL
> -                                for a bus drivers that wish to retrieve the name of the
> -                                bus controller.  It will not be NULL for a bus driver
> -                                that wishes to retrieve the name of a child controller.
> -  @param Language               A pointer to a three character ISO 639-2 language
> -                                identifier.  This is the language of the controller name
> -                                that that the caller is requesting, and it must match one
> -                                of the languages specified in SupportedLanguages.  The
> -                                number of languages supported by a driver is up to the
> -                                driver writer.
> -  @param ControllerName         A pointer to the Unicode string to return.
> This Unicode
> -                                string is the name of the controller specified by
> -                                ControllerHandle and ChildHandle in the language
> -                                specified by Language from the point of view of the
> -                                driver specified by This.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in the
> -                                language specified by Language for the driver
> -                                specified by This was returned in DriverName.
> -  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
> EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> -                                EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> -                                managing the controller specified by
> -                                ControllerHandle and ChildHandle.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support the
> -                                language specified by Language.
> -**/
> -EFI_STATUS
> -EFIAPI
> -SataControllerComponentNameGetControllerName (
> -  IN EFI_COMPONENT_NAME_PROTOCOL    *This,
> -  IN EFI_HANDLE                     ControllerHandle,
> -  IN EFI_HANDLE                     ChildHandle OPTIONAL,
> -  IN CHAR8                          *Language,
> -  OUT CHAR16                        **ControllerName
> -  )
> -;
> -
> -#endif
> +  // From ATA/ATAPI spec, if a mode is not supported,
> +  // the modes higher than it is also not supported
> +  //
> +  EFI_ATA_COLLECTIVE_MODE           *DisqualifiedModes;
> +
> +  //
> +  // A copy of EFI_IDENTIFY_DATA data for each attached SATA device and
> its flag
> +  //
> +  EFI_IDENTIFY_DATA                 *IdentifyData;
> +  BOOLEAN                           *IdentifyValid;
> +} EFI_SATA_CONTROLLER_PRIVATE_DATA;
> +
> +#define SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS(a) CR(a,
> EFI_SATA_CONTROLLER_PRIVATE_DATA, IdeInit,
> SATA_CONTROLLER_SIGNATURE)
> +
> +//
> +// Driver binding functions declaration
> +//
> +/**
> +  Supported function of Driver Binding protocol for this driver.
> +  Test to see if this driver supports ControllerHandle.
> +
> +  @param This                   Protocol instance pointer.
> +  @param Controller             Handle of device to test.
> +  @param RemainingDevicePath    A pointer to the device path. Should be
> ignored by
> +                                device driver.
> +
> +  @retval EFI_SUCCESS           This driver supports this device.
> +  @retval EFI_ALREADY_STARTED   This driver is already running on this
> device.
> +  @retval other                 This driver does not support this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SataControllerSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  )
> +;
> +
> +/**
> +  This routine is called right after the .Supported() called and
> +  Start this driver on ControllerHandle.
> +
> +  @param This                   Protocol instance pointer.
> +  @param Controller             Handle of device to bind driver to.
> +  @param RemainingDevicePath    A pointer to the device path. Should be
> ignored by
> +                                device driver.
> +
> +  @retval EFI_SUCCESS           This driver is added to this device.
> +  @retval EFI_ALREADY_STARTED   This driver is already running on this
> device.
> +  @retval other                 Some error occurs when binding this driver to this
> device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SataControllerStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  )
> +;
> +
> +/**
> +  Stop this driver on ControllerHandle.
> +
> +  @param This               Protocol instance pointer.
> +  @param Controller         Handle of device to stop driver on.
> +  @param NumberOfChildren   Not used.
> +  @param ChildHandleBuffer  Not used.
> +
> +  @retval EFI_SUCCESS   This driver is removed from this device.
> +  @retval other         Some error occurs when removing this driver from this
> device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SataControllerStop (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN UINTN                          NumberOfChildren,
> +  IN EFI_HANDLE                     *ChildHandleBuffer
> +  )
> +;
> +
> +//
> +// IDE controller init functions declaration
> +//
> +/**
> +  Returns the information about the specified IDE channel.
> +
> +  This function can be used to obtain information about a particular IDE
> channel.
> +  The driver entity uses this information during the enumeration process.
> +
> +  If Enabled is set to FALSE, the driver entity will not scan the channel. Note
> +  that it will not prevent an operating system driver from scanning the
> channel.
> +
> +  For most of today's controllers, MaxDevices will either be 1 or 2. For SATA
> +  controllers, this value will always be 1. SATA configurations can contain
> SATA
> +  port multipliers. SATA port multipliers behave like SATA bridges and can
> support
> +  up to 16 devices on the other side. If a SATA port out of the IDE controller
> +  is connected to a port multiplier, MaxDevices will be set to the number of
> SATA
> +  devices that the port multiplier supports. Because today's port multipliers
> +  support up to fifteen SATA devices, this number can be as large as fifteen.
> The IDE
> +  bus driver is required to scan for the presence of port multipliers behind an
> SATA
> +  controller and enumerate up to MaxDevices number of devices behind the
> port
> +  multiplier.
> +
> +  In this context, the devices behind a port multiplier constitute a channel.
> +
> +  @param[in]  This         The pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> +  @param[in]  Channel      Zero-based channel number.
> +  @param[out] Enabled      TRUE if this channel is enabled.  Disabled channels
> +                           are not scanned to see if any devices are present.
> +  @param[out] MaxDevices   The maximum number of IDE devices that the
> bus driver
> +                           can expect on this channel.  For the ATA/ATAPI
> +                           specification, version 6, this number will either be
> +                           one or two. For Serial ATA (SATA) configurations with a
> +                           port multiplier, this number can be as large as fifteen.
> +
> +  @retval EFI_SUCCESS             Information was returned without any errors.
> +  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IdeInitGetChannelInfo (
> +  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> +  IN UINT8                              Channel,
> +  OUT BOOLEAN                           *Enabled,
> +  OUT UINT8                             *MaxDevices
> +  )
> +;
> +
> +/**
> +  The notifications from the driver entity that it is about to enter a certain
> +  phase of the IDE channel enumeration process.
> +
> +  This function can be used to notify the IDE controller driver to perform
> +  specific actions, including any chipset-specific initialization, so that the
> +  chipset is ready to enter the next phase. Seven notification points are
> defined
> +  at this time.
> +
> +  More synchronization points may be added as required in the future.
> +
> +  @param[in] This      The pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> +  @param[in] Phase     The phase during enumeration.
> +  @param[in] Channel   Zero-based channel number.
> +
> +  @retval EFI_SUCCESS             The notification was accepted without any
> errors.
> +  @retval EFI_UNSUPPORTED         Phase is not supported.
> +  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> +  @retval EFI_NOT_READY           This phase cannot be entered at this time;
> for
> +                                  example, an attempt was made to enter a Phase
> +                                  without having entered one or more previous
> +                                  Phase.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IdeInitNotifyPhase (
> +  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> +  IN EFI_IDE_CONTROLLER_ENUM_PHASE      Phase,
> +  IN UINT8                              Channel
> +  )
> +;
> +
> +/**
> +  Submits the device information to the IDE controller driver.
> +
> +  This function is used by the driver entity to pass detailed information about
> +  a particular device to the IDE controller driver. The driver entity obtains
> +  this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command.
> IdentifyData
> +  is the pointer to the response data buffer. The IdentifyData buffer is
> owned
> +  by the driver entity, and the IDE controller driver must make a local copy
> +  of the entire buffer or parts of the buffer as needed. The original
> IdentifyData
> +  buffer pointer may not be valid when
> +
> +    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or
> +    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a
> later point.
> +
> +  The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA
> to
> +  compute the optimum mode for the device. These fields are not limited to
> the
> +  timing information. For example, an implementation of the IDE controller
> driver
> +  may examine the vendor and type/mode field to match known bad drives.
> +
> +  The driver entity may submit drive information in any order, as long as it
> +  submits information for all the devices belonging to the enumeration
> group
> +  before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called
> for any device
> +  in that enumeration group. If a device is absent,
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
> +  should be called with IdentifyData set to NULL.  The IDE controller driver
> may
> +  not have any other mechanism to know whether a device is present or not.
> Therefore,
> +  setting IdentifyData to NULL does not constitute an error condition.
> +  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only
> once for a
> +  given (Channel, Device) pair.
> +
> +  @param[in] This           A pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> +  @param[in] Channel        Zero-based channel number.
> +  @param[in] Device         Zero-based device number on the Channel.
> +  @param[in] IdentifyData   The device's response to the ATA
> IDENTIFY_DEVICE command.
> +
> +  @retval EFI_SUCCESS             The information was accepted without any
> errors.
> +  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> +  @retval EFI_INVALID_PARAMETER   Device is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IdeInitSubmitData (
> +  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> +  IN UINT8                              Channel,
> +  IN UINT8                              Device,
> +  IN EFI_IDENTIFY_DATA                  *IdentifyData
> +  )
> +;
> +
> +/**
> +  Disqualifies specific modes for an IDE device.
> +
> +  This function allows the driver entity or other drivers (such as platform
> +  drivers) to reject certain timing modes and request the IDE controller
> driver
> +  to recalculate modes. This function allows the driver entity and the IDE
> +  controller driver to negotiate the timings on a per-device basis. This
> function
> +  is useful in the case of drives that lie about their capabilities. An example
> +  is when the IDE device fails to accept the timing modes that are calculated
> +  by the IDE controller driver based on the response to the Identify Drive
> command.
> +
> +  If the driver entity does not want to limit the ATA timing modes and leave
> that
> +  decision to the IDE controller driver, it can either not call this function for
> +  the given device or call this function and set the Valid flag to FALSE for all
> +  modes that are listed in EFI_ATA_COLLECTIVE_MODE.
> +
> +  The driver entity may disqualify modes for a device in any order and any
> number
> +  of times.
> +
> +  This function can be called multiple times to invalidate multiple modes of
> the
> +  same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the
> ATA/ATAPI
> +  specification for more information on PIO modes.
> +
> +  For Serial ATA (SATA) controllers, this member function can be used to
> disqualify
> +  a higher transfer rate mode on a given channel. For example, a platform
> driver
> +  may inform the IDE controller driver to not use second-generation (Gen2)
> speeds
> +  for a certain SATA drive.
> +
> +  @param[in] This       The pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> +  @param[in] Channel    The zero-based channel number.
> +  @param[in] Device     The zero-based device number on the Channel.
> +  @param[in] BadModes   The modes that the device does not support and
> that
> +                        should be disqualified.
> +
> +  @retval EFI_SUCCESS             The modes were accepted without any errors.
> +  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> +  @retval EFI_INVALID_PARAMETER   Device is invalid.
> +  @retval EFI_INVALID_PARAMETER   IdentifyData is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IdeInitDisqualifyMode (
> +  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> +  IN UINT8                              Channel,
> +  IN UINT8                              Device,
> +  IN EFI_ATA_COLLECTIVE_MODE            *BadModes
> +  )
> +;
> +
> +/**
> +  Returns the information about the optimum modes for the specified IDE
> device.
> +
> +  This function is used by the driver entity to obtain the optimum ATA
> modes for
> +  a specific device.  The IDE controller driver takes into account the following
> +  while calculating the mode:
> +    - The IdentifyData inputs to
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
> +    - The BadModes inputs to
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()
> +
> +  The driver entity is required to call
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
> +  for all the devices that belong to an enumeration group before calling
> +  EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in
> the same group.
> +
> +  The IDE controller driver will use controller- and possibly platform-specific
> +  algorithms to arrive at SupportedModes.  The IDE controller may base its
> +  decision on user preferences and other considerations as well. This
> function
> +  may be called multiple times because the driver entity may renegotiate
> the mode
> +  with the IDE controller driver using
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().
> +
> +  The driver entity may collect timing information for various devices in any
> +  order. The driver entity is responsible for making sure that all the
> dependencies
> +  are satisfied. For example, the SupportedModes information for device A
> that
> +  was previously returned may become stale after a call to
> +  EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.
> +
> +  The buffer SupportedModes is allocated by the callee because the caller
> does
> +  not necessarily know the size of the buffer. The type
> EFI_ATA_COLLECTIVE_MODE
> +  is defined in a way that allows for future extensibility and can be of
> variable
> +  length. This memory pool should be deallocated by the caller when it is no
> +  longer necessary.
> +
> +  The IDE controller driver for a Serial ATA (SATA) controller can use this
> +  member function to force a lower speed (first-generation [Gen1] speeds
> on a
> +  second-generation [Gen2]-capable hardware).  The IDE controller driver
> can
> +  also allow the driver entity to stay with the speed that has been
> negotiated
> +  by the physical layer.
> +
> +  @param[in]  This             The pointer to the
> EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
> +  @param[in]  Channel          A zero-based channel number.
> +  @param[in]  Device           A zero-based device number on the Channel.
> +  @param[out] SupportedModes   The optimum modes for the device.
> +
> +  @retval EFI_SUCCESS             SupportedModes was returned.
> +  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> +  @retval EFI_INVALID_PARAMETER   Device is invalid.
> +  @retval EFI_INVALID_PARAMETER   SupportedModes is NULL.
> +  @retval EFI_NOT_READY           Modes cannot be calculated due to a lack of
> +                                  data.  This error may happen if
> +                                  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
> +                                  and
> EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData()
> +                                  were not called for at least one drive in the
> +                                  same enumeration group.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IdeInitCalculateMode (
> +  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> +  IN UINT8                              Channel,
> +  IN UINT8                              Device,
> +  OUT EFI_ATA_COLLECTIVE_MODE           **SupportedModes
> +  )
> +;
> +
> +/**
> +  Commands the IDE controller driver to program the IDE controller
> hardware
> +  so that the specified device can operate at the specified mode.
> +
> +  This function is used by the driver entity to instruct the IDE controller
> +  driver to program the IDE controller hardware to the specified modes. This
> +  function can be called only once for a particular device. For a Serial ATA
> +  (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-
> +  specific programming may be required.
> +
> +  @param[in] This      Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL
> instance.
> +  @param[in] Channel   Zero-based channel number.
> +  @param[in] Device    Zero-based device number on the Channel.
> +  @param[in] Modes     The modes to set.
> +
> +  @retval EFI_SUCCESS             The command was accepted without any
> errors.
> +  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >=
> ChannelCount).
> +  @retval EFI_INVALID_PARAMETER   Device is invalid.
> +  @retval EFI_NOT_READY           Modes cannot be set at this time due to lack
> of data.
> +  @retval EFI_DEVICE_ERROR        Modes cannot be set due to hardware
> failure.
> +                                  The driver entity should not use this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IdeInitSetTiming (
> +  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
> +  IN UINT8                              Channel,
> +  IN UINT8                              Device,
> +  IN EFI_ATA_COLLECTIVE_MODE            *Modes
> +  )
> +;
> +
> +//
> +// Forward reference declaration
> +//
> +/**
> +  Retrieves a Unicode string that is the user readable name of the UEFI
> Driver.
> +
> +  @param This           A pointer to the EFI_COMPONENT_NAME_PROTOCOL
> instance.
> +  @param Language       A pointer to a three character ISO 639-2 language
> identifier.
> +                        This is the language of the driver name that that the caller
> +                        is requesting, and it must match one of the languages specified
> +                        in SupportedLanguages.  The number of languages supported
> by a
> +                        driver is up to the driver writer.
> +  @param DriverName     A pointer to the Unicode string to return.  This
> Unicode string
> +                        is the name of the driver specified by This in the language
> +                        specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> This
> +                                and the language specified by Language was returned
> +                                in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support the
> +                                language specified by Language.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SataControllerComponentNameGetDriverName (
> +  IN EFI_COMPONENT_NAME_PROTOCOL    *This,
> +  IN CHAR8                          *Language,
> +  OUT CHAR16                        **DriverName
> +  )
> +;
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by an UEFI Driver.
> +
> +  @param This                   A pointer to the
> EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param ControllerHandle       The handle of a controller that the driver
> specified by
> +                                This is managing.  This handle specifies the controller
> +                                whose name is to be returned.
> +  @param OPTIONAL   ChildHandle The handle of the child controller to
> retrieve the name
> +                                of.  This is an optional parameter that may be NULL.  It
> +                                will be NULL for device drivers.  It will also be NULL
> +                                for a bus drivers that wish to retrieve the name of the
> +                                bus controller.  It will not be NULL for a bus driver
> +                                that wishes to retrieve the name of a child controller.
> +  @param Language               A pointer to a three character ISO 639-2 language
> +                                identifier.  This is the language of the controller name
> +                                that that the caller is requesting, and it must match one
> +                                of the languages specified in SupportedLanguages.  The
> +                                number of languages supported by a driver is up to the
> +                                driver writer.
> +  @param ControllerName         A pointer to the Unicode string to return.
> This Unicode
> +                                string is the name of the controller specified by
> +                                ControllerHandle and ChildHandle in the language
> +                                specified by Language from the point of view of the
> +                                driver specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in the
> +                                language specified by Language for the driver
> +                                specified by This was returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
> EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support the
> +                                language specified by Language.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SataControllerComponentNameGetControllerName (
> +  IN EFI_COMPONENT_NAME_PROTOCOL    *This,
> +  IN EFI_HANDLE                     ControllerHandle,
> +  IN EFI_HANDLE                     ChildHandle OPTIONAL,
> +  IN CHAR8                          *Language,
> +  OUT CHAR16                        **ControllerName
> +  )
> +;
> +
> +#endif
> diff --git a/CorebootModulePkg/SecCore/Ia32/Stack.S
> b/CorebootModulePkg/SecCore/Ia32/Stack.S
> index 6a8e0e4b15..1900a8c54a 100644
> --- a/CorebootModulePkg/SecCore/Ia32/Stack.S
> +++ b/CorebootModulePkg/SecCore/Ia32/Stack.S
> @@ -1,78 +1,78 @@
> -#------------------------------------------------------------------------------
> -#
> -# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
> -# This program and the accompanying materials
> -# are licensed and made available under the terms and conditions of the
> BSD License
> -# which accompanies this distribution.  The full text of the license may be
> found at
> -# http://opensource.org/licenses/bsd-license.php.
> -#
> -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> -#
> -# Abstract:
> -#
> +#------------------------------------------------------------------------------
> +#
> +# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions of the
> BSD License
> +# which accompanies this distribution.  The full text of the license may be
> found at
> +# http://opensource.org/licenses/bsd-license.php.
> +#
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +#
> +# Abstract:
> +#
>  #   Switch the stack from temporary memory to permanent memory.
> -#
> -#------------------------------------------------------------------------------
> -
> -
> -#------------------------------------------------------------------------------
> -# VOID
> -# EFIAPI
> -# SecSwitchStack (
> -#   UINT32   TemporaryMemoryBase,
> -#   UINT32   PermenentMemoryBase
> -#   )#
> -#------------------------------------------------------------------------------
> -ASM_GLOBAL ASM_PFX (SecSwitchStack)
> -ASM_PFX(SecSwitchStack):
> -    #
> -    # Save standard registers so they can be used to change stack
> -    #
> -    pushl %eax
> -    pushl %ebx
> -    pushl %ecx
> -    pushl %edx
> -
> -    #
> -    # !!CAUTION!! this function address's is pushed into stack after
> +#
> +#------------------------------------------------------------------------------
> +
> +
> +#------------------------------------------------------------------------------
> +# VOID
> +# EFIAPI
> +# SecSwitchStack (
> +#   UINT32   TemporaryMemoryBase,
> +#   UINT32   PermenentMemoryBase
> +#   )#
> +#------------------------------------------------------------------------------
> +ASM_GLOBAL ASM_PFX (SecSwitchStack)
> +ASM_PFX(SecSwitchStack):
> +    #
> +    # Save standard registers so they can be used to change stack
> +    #
> +    pushl %eax
> +    pushl %ebx
> +    pushl %ecx
> +    pushl %edx
> +
> +    #
> +    # !!CAUTION!! this function address's is pushed into stack after
>      # migration of whole temporary memory, so need save it to permanent
> -    # memory at first!
> -    #
> -    movl  20(%esp), %ebx         # Save the first parameter
> -    movl  24(%esp), %ecx         # Save the second parameter
> -
> -    #
> +    # memory at first!
> +    #
> +    movl  20(%esp), %ebx         # Save the first parameter
> +    movl  24(%esp), %ecx         # Save the second parameter
> +
> +    #
>      # Save this function's return address into permanent memory at first.
>      # Then, Fixup the esp point to permanent memory
> -    #
> -    movl  %esp, %eax
> -    subl  %ebx, %eax
> -    addl  %ecx, %eax
> +    #
> +    movl  %esp, %eax
> +    subl  %ebx, %eax
> +    addl  %ecx, %eax
>      movl  0(%esp), %edx          # copy pushed register's value to permanent
> memory
> -    movl  %edx, 0(%eax)
> -    movl  4(%esp), %edx
> -    movl  %edx, 4(%eax)
> -    movl  8(%esp), %edx
> -    movl  %edx, 8(%eax)
> -    movl  12(%esp), %edx
> -    movl  %edx, 12(%eax)
> +    movl  %edx, 0(%eax)
> +    movl  4(%esp), %edx
> +    movl  %edx, 4(%eax)
> +    movl  8(%esp), %edx
> +    movl  %edx, 8(%eax)
> +    movl  12(%esp), %edx
> +    movl  %edx, 12(%eax)
>      movl  16(%esp), %edx        # Update this function's return address into
> permanent memory
> -    movl  %edx, 16(%eax)
> +    movl  %edx, 16(%eax)
>      movl  %eax, %esp            # From now, esp is pointed to permanent memory
> -
> -    #
> +
> +    #
>      # Fixup the ebp point to permanent memory
> -    #
> -    movl  %ebp, %eax
> -    subl  %ebx, %eax
> -    addl  %ecx, %eax
> +    #
> +    movl  %ebp, %eax
> +    subl  %ebx, %eax
> +    addl  %ecx, %eax
>      movl  %eax, %ebp            # From now, ebp is pointed to permanent
> memory
> -
> -    popl  %edx
> -    popl  %ecx
> -    popl  %ebx
> -    popl  %eax
> -    ret
> -
> -
> +
> +    popl  %edx
> +    popl  %ecx
> +    popl  %ebx
> +    popl  %eax
> +    ret
> +
> +
> --
> 2.19.1.windows.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-04-09 22:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-04-04 15:32 [PATCH v2 0/2] Fixed CorebootModulePkg and CorebootPayloadPkg incorrect line endings Agyeman, Prince
2019-04-04 15:32 ` [PATCH v2 1/2] CorebootModulePkg: Fix non - CRLF " Agyeman, Prince
2019-04-09 22:59   ` Ma, Maurice
2019-04-04 15:32 ` [PATCH v2 2/2] CorebootPayloadPkg: " Agyeman, Prince

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox