Replaced non CRLF line endings with CRLF

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

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Agyeman <prince.agye...@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..a840c68247 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

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to