/** @file
  Serial driver for PCI or SIO UARTS.

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 "Serial.h"

//
// ISA Serial Driver Global Variables
//

EFI_DRIVER_BINDING_PROTOCOL gSerialControllerDriver = {
  SerialControllerDriverSupported,
  SerialControllerDriverStart,
  SerialControllerDriverStop,
  0xa,
  NULL,
  NULL
};

CONTROLLER_DEVICE_PATH mControllerDevicePathTemplate = {
  {
    HARDWARE_DEVICE_PATH,
    HW_CONTROLLER_DP,
    {
      (UINT8) (sizeof (CONTROLLER_DEVICE_PATH)),
      (UINT8) ((sizeof (CONTROLLER_DEVICE_PATH)) >> 8)
    }
  },
  0
};

SERIAL_DEV  gSerialDevTemplate = {
  SERIAL_DEV_SIGNATURE,
  NULL,
  {
    SERIAL_IO_INTERFACE_REVISION,
    SerialReset,
    SerialSetAttributes,
    SerialSetControl,
    SerialGetControl,
    SerialWrite,
    SerialRead,
    NULL
  },                                       // SerialIo
  {
    SERIAL_PORT_SUPPORT_CONTROL_MASK,
    SERIAL_PORT_DEFAULT_TIMEOUT,
    0,
    16,
    0,
    0,
    0
  },                                       // SerialMode
  NULL,                                    // DevicePath
  NULL,                                    // ParentDevicePath
  {
    {
      MESSAGING_DEVICE_PATH,
      MSG_UART_DP,
      {
        (UINT8) (sizeof (UART_DEVICE_PATH)),
        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
      }
    },
    0, 0, 0, 0, 0
  },                                       // UartDevicePath
  0,                                       // BaseAddress
  FALSE,                                   // MmioAccess
  1,                                       // RegisterStride
  0,                                       // ClockRate
  16,                                      // ReceiveFifoDepth
  { 0, 0 },                                // Receive;
  16,                                      // TransmitFifoDepth
  { 0, 0 },                                // Transmit;
  FALSE,                                   // SoftwareLoopbackEnable;
  FALSE,                                   // HardwareFlowControl;
  NULL,                                    // *ControllerNameTable;
  FALSE,                                   // ContainsControllerNode;
  0,                                       // Instance;
  NULL                                     // *PciDeviceInfo;
};

/**
  Check the device path node whether it's the Flow Control node or not.

  @param[in] FlowControl    The device path node to be checked.
  
  @retval TRUE              It's the Flow Control node.
  @retval FALSE             It's not.

**/
BOOLEAN
IsUartFlowControlDevicePathNode (
  IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl
  )
{
  return (BOOLEAN) (
           (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&
           (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&
           (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))
           );
}

/**
  The user Entry Point for module PciSioSerial. The user code starts with this function.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  
  @param[in] SystemTable    A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
InitializePciSioSerial (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS              Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gSerialControllerDriver,
             ImageHandle,
             &gPciSioSerialComponentName,
             &gPciSioSerialComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Initialize UART default setting in gSerialDevTempate
  //
  gSerialDevTemplate.SerialMode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
  gSerialDevTemplate.SerialMode.DataBits = PcdGet8 (PcdUartDefaultDataBits);
  gSerialDevTemplate.SerialMode.Parity   = PcdGet8 (PcdUartDefaultParity);
  gSerialDevTemplate.SerialMode.StopBits = PcdGet8 (PcdUartDefaultStopBits);
  gSerialDevTemplate.UartDevicePath.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
  gSerialDevTemplate.UartDevicePath.DataBits = PcdGet8 (PcdUartDefaultDataBits);
  gSerialDevTemplate.UartDevicePath.Parity   = PcdGet8 (PcdUartDefaultParity);
  gSerialDevTemplate.UartDevicePath.StopBits = PcdGet8 (PcdUartDefaultStopBits);
  gSerialDevTemplate.ClockRate = PcdGet32 (PcdSerialClockRate);

  return Status;
}

/**
  Return whether the controller is a SIO serial controller.

  @param  Controller   The controller handle.

  @retval EFI_SUCCESS  The controller is a SIO serial controller.
  @retval others       The controller is not a SIO serial controller.
**/
EFI_STATUS
IsSioSerialController (
  EFI_HANDLE               Controller
  )
{
  EFI_STATUS               Status;
  EFI_SIO_PROTOCOL         *Sio;
  EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  ACPI_HID_DEVICE_PATH     *Acpi;

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSioProtocolGuid,
                  (VOID **) &Sio,
                  gSerialControllerDriver.DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (!EFI_ERROR (Status)) {
    //
    // Close the I/O Abstraction(s) used to perform the supported test
    //
    gBS->CloseProtocol (
           Controller,
           &gEfiSioProtocolGuid,
           gSerialControllerDriver.DriverBindingHandle,
           Controller
           );

    Status = gBS->OpenProtocol (
      Controller,
      &gEfiDevicePathProtocolGuid,
      (VOID **) &DevicePath,
      gSerialControllerDriver.DriverBindingHandle,
      Controller,
      EFI_OPEN_PROTOCOL_BY_DRIVER
      );
    ASSERT (Status != EFI_ALREADY_STARTED);

    if (!EFI_ERROR (Status)) {
      do {
        Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;
        DevicePath = NextDevicePathNode (DevicePath);
      } while (!IsDevicePathEnd (DevicePath));

      if (DevicePathType (Acpi) != ACPI_DEVICE_PATH ||
          (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP) ||
          Acpi->HID != EISA_PNP_ID (0x501)
          ) {
        Status = EFI_UNSUPPORTED;
      }
    }

    //
    // Close protocol, don't use device path protocol in the Support() function
    //
    gBS->CloseProtocol (
      Controller,
      &gEfiDevicePathProtocolGuid,
      gSerialControllerDriver.DriverBindingHandle,
      Controller
      );
  }
  return Status;
}

/**
  Return whether the controller is a PCI serial controller.

  @param  Controller   The controller handle.

  @retval EFI_SUCCESS  The controller is a PCI serial controller.
  @retval others       The controller is not a PCI serial controller.
**/
EFI_STATUS
IsPciSerialController (
  EFI_HANDLE               Controller
  )
{
  EFI_STATUS               Status;
  EFI_PCI_IO_PROTOCOL      *PciIo;
  EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  PCI_TYPE00               Pci;
  PCI_SERIAL_PARAMETER     *PciSerialParameter;

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
    Controller,
    &gEfiPciIoProtocolGuid,
    (VOID **) &PciIo,
    gSerialControllerDriver.DriverBindingHandle,
    Controller,
    EFI_OPEN_PROTOCOL_BY_DRIVER
    );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (!EFI_ERROR (Status)) {
    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (Pci), &Pci);
    if (!EFI_ERROR (Status)) {
      if (!IS_PCI_16550_SERIAL (&Pci)) {
        for (PciSerialParameter = (PCI_SERIAL_PARAMETER *) PcdGetPtr (PcdPciSerialParameters)
             ; PciSerialParameter->VendorId != 0xFFFF
             ; PciSerialParameter++
             ) {
          if ((Pci.Hdr.VendorId == PciSerialParameter->VendorId) &&
              (Pci.Hdr.DeviceId == PciSerialParameter->DeviceId)
              ) {
            break;
          }
        }
        if (PciSerialParameter->VendorId == 0xFFFF) {
          Status = EFI_UNSUPPORTED;
        } else {
          Status = EFI_SUCCESS;
        }
      }
    }

    //
    // Close the I/O Abstraction(s) used to perform the supported test
    //
    gBS->CloseProtocol (
      Controller,
      &gEfiPciIoProtocolGuid,
      gSerialControllerDriver.DriverBindingHandle,
      Controller
      );
  }
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open the EFI Device Path protocol needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
    Controller,
    &gEfiDevicePathProtocolGuid,
    (VOID **) &DevicePath,
    gSerialControllerDriver.DriverBindingHandle,
    Controller,
    EFI_OPEN_PROTOCOL_BY_DRIVER
    );
  ASSERT (Status != EFI_ALREADY_STARTED);

  //
  // Close protocol, don't use device path protocol in the Support() function
  //
  gBS->CloseProtocol (
    Controller,
    &gEfiDevicePathProtocolGuid,
    gSerialControllerDriver.DriverBindingHandle,
    Controller
    );

  return Status;
}

/**
  Check to see if this driver supports the given controller

  @param  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param  Controller           The handle of the controller to test.
  @param  RemainingDevicePath  A pointer to the remaining portion of a device path.

  @return EFI_SUCCESS          This driver can support the given controller

**/
EFI_STATUS
EFIAPI
SerialControllerDriverSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )

{
  EFI_STATUS                                Status;
  UART_DEVICE_PATH                          *Uart;
  UART_FLOW_CONTROL_DEVICE_PATH             *FlowControl;

  //
  // Test RemainingDevicePath
  //
  if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
    Status = EFI_UNSUPPORTED;

    Uart = SkipControllerDevicePathNode (RemainingDevicePath, NULL, NULL);
    if (DevicePathType (Uart) != MESSAGING_DEVICE_PATH ||
        DevicePathSubType (Uart) != MSG_UART_DP ||
        DevicePathNodeLength (Uart) != sizeof (UART_DEVICE_PATH)
        ) {
      return EFI_UNSUPPORTED;
    }

    //
    // Do a rough check because Clock Rate is unknown until DriverBindingStart()
    //
    if (!VerifyUartParameters (0, Uart->BaudRate, Uart->DataBits, Uart->Parity, Uart->StopBits, NULL, NULL)) {
      return EFI_UNSUPPORTED;
    }

    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);
    if (IsUartFlowControlDevicePathNode (FlowControl)) {
      //
      // If the second node is Flow Control Node,
      //   return error when it request other than hardware flow control.
      //
      if ((ReadUnaligned32 (&FlowControl->FlowControlMap) & ~UART_FLOW_CONTROL_HARDWARE) != 0) {
        return EFI_UNSUPPORTED;
      }
    }
  }

  Status = IsSioSerialController (Controller);
  if (EFI_ERROR (Status)) {
    Status = IsPciSerialController (Controller);
  }
  return Status;  
}

/**
  Create the child serial device instance.

  @param Controller           The parent controller handle.
  @param Uart                 Pointer to the UART device path node in RemainingDevicePath,
                              or NULL if RemainingDevicePath is NULL.
  @param ParentDevicePath     Pointer to the parent device path.
  @param CreateControllerNode TRUE to create the controller node.
  @param Instance             Instance number of the serial device.
                              The value will be set to the controller node
                              if CreateControllerNode is TRUE.
  @param ParentIo             A union type pointer to either Sio or PciIo.
  @param PciSerialParameter   The PCI serial parameter to be used by current serial device.
                              NULL for SIO serial device.
  @param PciDeviceInfo        The PCI device info for the current serial device.
                              NULL for SIO serial device.

  @retval EFI_SUCCESS         The serial device was created successfully.
  @retval others              The serial device wasn't created.
**/
EFI_STATUS
CreateSerialDevice (
  IN EFI_HANDLE                     Controller,
  IN UART_DEVICE_PATH               *Uart,
  IN EFI_DEVICE_PATH_PROTOCOL       *ParentDevicePath,
  IN BOOLEAN                        CreateControllerNode,
  IN UINT32                         Instance,
  IN PARENT_IO_PROTOCOL_PTR         ParentIo,
  IN PCI_SERIAL_PARAMETER           *PciSerialParameter, OPTIONAL
  IN PCI_DEVICE_INFO                *PciDeviceInfo       OPTIONAL
  )
{
  EFI_STATUS                                 Status;
  SERIAL_DEV                                 *SerialDevice;
  UINT8                                      BarIndex;
  UINT64                                     Offset;
  UART_FLOW_CONTROL_DEVICE_PATH              *FlowControl;
  UINT32                                     FlowControlMap;
  ACPI_RESOURCE_HEADER_PTR                   Resources;
  EFI_ACPI_IO_PORT_DESCRIPTOR                *Io;
  EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *FixedIo;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR          *AddressSpace;
  EFI_DEVICE_PATH_PROTOCOL                   *TempDevicePath;

  BarIndex = 0;
  Offset = 0;
  FlowControl = NULL;
  FlowControlMap = 0;

  //
  // Initialize the serial device instance
  //
  SerialDevice = AllocateCopyPool (sizeof (SERIAL_DEV), &gSerialDevTemplate);
  ASSERT (SerialDevice != NULL);

  SerialDevice->SerialIo.Mode    = &(SerialDevice->SerialMode);
  SerialDevice->ParentDevicePath = ParentDevicePath;
  SerialDevice->PciDeviceInfo    = PciDeviceInfo;
  SerialDevice->Instance         = Instance;

  if (Uart != NULL) {
    CopyMem (&SerialDevice->UartDevicePath, Uart, sizeof (UART_DEVICE_PATH));
    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);
    if (IsUartFlowControlDevicePathNode (FlowControl)) {
      FlowControlMap = ReadUnaligned32 (&FlowControl->FlowControlMap);
    } else {
      FlowControl = NULL;
    }
  }

  //
  // For PCI serial device, use the information from PCD
  //
  if (PciSerialParameter != NULL) {
    BarIndex = (PciSerialParameter->BarIndex == MAX_UINT8) ? 0 : PciSerialParameter->BarIndex;
    Offset = PciSerialParameter->Offset;
    if (PciSerialParameter->RegisterStride != 0) {
      SerialDevice->RegisterStride = PciSerialParameter->RegisterStride;
    }
    if (PciSerialParameter->ClockRate != 0) {
      SerialDevice->ClockRate = PciSerialParameter->ClockRate;
    }
    if (PciSerialParameter->ReceiveFifoDepth != 0) {
      SerialDevice->ReceiveFifoDepth = PciSerialParameter->ReceiveFifoDepth;
    }
    if (PciSerialParameter->TransmitFifoDepth != 0) {
      SerialDevice->TransmitFifoDepth = PciSerialParameter->TransmitFifoDepth;
    }
  }

  //
  // Pass NULL ActualBaudRate to VerifyUartParameters to disallow baudrate degrade.
  // DriverBindingStart() shouldn't create a handle with different UART device path.
  //
  if (!VerifyUartParameters (SerialDevice->ClockRate, SerialDevice->UartDevicePath.BaudRate, SerialDevice->UartDevicePath.DataBits,
                            SerialDevice->UartDevicePath.Parity, SerialDevice->UartDevicePath.StopBits, NULL, NULL
                            )) {
    Status = EFI_INVALID_PARAMETER;
    goto CreateError;
  }

  if (PciSerialParameter == NULL) {
    Status = ParentIo.Sio->GetResources (ParentIo.Sio, &Resources);
  } else {
    Status = ParentIo.PciIo->GetBarAttributes (ParentIo.PciIo, BarIndex, NULL, (VOID **) &Resources);
  }

  if (!EFI_ERROR (Status)) {
    //
    // Get the base address information from ACPI resource descriptor.
    // ACPI_IO_PORT_DESCRIPTOR and ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR are returned from Sio;
    // ACPI_ADDRESS_SPACE_DESCRIPTOR is returned from PciIo.
    //
    while ((Resources.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) && (SerialDevice->BaseAddress == 0)) {
      switch (Resources.SmallHeader->Byte) {
      case ACPI_IO_PORT_DESCRIPTOR:
        Io = (EFI_ACPI_IO_PORT_DESCRIPTOR *) Resources.SmallHeader;
        if (Io->Length != 0) {
          SerialDevice->BaseAddress = Io->BaseAddressMin;
        }
        break;

      case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR:
        FixedIo = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *) Resources.SmallHeader;
        if (FixedIo->Length != 0) {
          SerialDevice->BaseAddress = FixedIo->BaseAddress;
        }
        break;

      case ACPI_ADDRESS_SPACE_DESCRIPTOR:
        AddressSpace = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Resources.SmallHeader;
        if (AddressSpace->AddrLen != 0) {
          if (AddressSpace->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
            SerialDevice->MmioAccess = TRUE;
          }
          SerialDevice->BaseAddress = AddressSpace->AddrRangeMin + Offset;
        }
        break;
      }

      if (Resources.SmallHeader->Bits.Type == 0) {
        Resources.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) Resources.SmallHeader
                                                                + Resources.SmallHeader->Bits.Length
                                                                + sizeof (*Resources.SmallHeader));
      } else {
        Resources.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) Resources.LargeHeader
                                                                + Resources.LargeHeader->Length
                                                                + sizeof (*Resources.LargeHeader));
      }
    }
  }

  if (SerialDevice->BaseAddress == 0) {
    Status = EFI_INVALID_PARAMETER;
    goto CreateError;
  }

  SerialDevice->HardwareFlowControl = (BOOLEAN) (FlowControlMap == UART_FLOW_CONTROL_HARDWARE);

  //
  // Report status code the serial present
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_P_PC_PRESENCE_DETECT | EFI_PERIPHERAL_SERIAL_PORT,
    SerialDevice->ParentDevicePath
    );

  if (!SerialPresent (SerialDevice)) {
    Status = EFI_DEVICE_ERROR;
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE,
      EFI_P_EC_NOT_DETECTED | EFI_PERIPHERAL_SERIAL_PORT,
      SerialDevice->ParentDevicePath
      );
    goto CreateError;
  }

  //
  // 1. Append Controller device path node.
  //
  if (CreateControllerNode) {
    mControllerDevicePathTemplate.ControllerNumber = SerialDevice->Instance;
    SerialDevice->DevicePath = AppendDevicePathNode (
                                 SerialDevice->ParentDevicePath,
                                 (EFI_DEVICE_PATH_PROTOCOL *) &mControllerDevicePathTemplate
                                 );
    SerialDevice->ContainsControllerNode = TRUE;
  }

  //
  // 2. Append UART device path node.
  //    The Uart setings are zero here.
  //    SetAttribute() will update them to match the default setings.
  //
  TempDevicePath = SerialDevice->DevicePath;
  if (TempDevicePath != NULL) {
    SerialDevice->DevicePath = AppendDevicePathNode (
                                 TempDevicePath,
                                 (EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath
                                 );
    FreePool (TempDevicePath);
  } else {
    SerialDevice->DevicePath = AppendDevicePathNode (
                                 SerialDevice->ParentDevicePath,
                                 (EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath
                                 );
  }
  //
  // 3. Append the Flow Control device path node.
  //    Only produce the Flow Control node when remaining device path has it
  //
  if (FlowControl != NULL) {
    TempDevicePath = SerialDevice->DevicePath;
    if (TempDevicePath != NULL) {
      SerialDevice->DevicePath = AppendDevicePathNode (
                                   TempDevicePath,
                                   (EFI_DEVICE_PATH_PROTOCOL *) FlowControl
                                   );
      FreePool (TempDevicePath);
    }
  }
  ASSERT (SerialDevice->DevicePath != NULL);

  //
  // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
  //
  SerialDevice->SerialMode.BaudRate = SerialDevice->UartDevicePath.BaudRate;
  SerialDevice->SerialMode.DataBits = SerialDevice->UartDevicePath.DataBits;
  SerialDevice->SerialMode.Parity   = SerialDevice->UartDevicePath.Parity;
  SerialDevice->SerialMode.StopBits = SerialDevice->UartDevicePath.StopBits;

  //
  // Issue a reset to initialize the COM port
  //
  Status = SerialDevice->SerialIo.Reset (&SerialDevice->SerialIo);
  if (EFI_ERROR (Status)) {
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE,
      EFI_P_EC_CONTROLLER_ERROR | EFI_PERIPHERAL_SERIAL_PORT,
      SerialDevice->DevicePath
      );
    goto CreateError;
  }

  AddName (SerialDevice, Instance);
  //
  // Install protocol interfaces for the serial device.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &SerialDevice->Handle,
                  &gEfiDevicePathProtocolGuid, SerialDevice->DevicePath,
                  &gEfiSerialIoProtocolGuid, &SerialDevice->SerialIo,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto CreateError;
  }
  //
  // Open For Child Device
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  PciSerialParameter != NULL ? &gEfiPciIoProtocolGuid : &gEfiSioProtocolGuid,
                  (VOID **) &ParentIo,
                  gSerialControllerDriver.DriverBindingHandle,
                  SerialDevice->Handle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );

  if (EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
           &SerialDevice->Handle,
           &gEfiDevicePathProtocolGuid, SerialDevice->DevicePath,
           &gEfiSerialIoProtocolGuid, &SerialDevice->SerialIo,
           NULL
           );
  }

CreateError:
  if (EFI_ERROR (Status)) {
    if (SerialDevice->DevicePath != NULL) {
      FreePool (SerialDevice->DevicePath);
    }
    if (SerialDevice->ControllerNameTable != NULL) {
      FreeUnicodeStringTable (SerialDevice->ControllerNameTable);
    }
    FreePool (SerialDevice);
  }
  return Status;
}

/**
  Returns an array of pointers containing all the child serial device pointers.

  @param Controller      The parent controller handle.
  @param IoProtocolGuid  The protocol GUID, either equals to gEfiSioProtocolGuid
                         or equals to gEfiPciIoProtocolGuid.
  @param Count           Count of the serial devices.

  @return  An array of pointers containing all the child serial device pointers.
**/
SERIAL_DEV **
GetChildSerialDevices (
  IN EFI_HANDLE                       Controller,
  IN EFI_GUID                         *IoProtocolGuid,
  OUT UINTN                           *Count
  )
{
  EFI_STATUS                                 Status;
  UINTN                                      Index;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY        *OpenInfoBuffer;
  UINTN                                      EntryCount;
  SERIAL_DEV                                 **SerialDevices;
  EFI_SERIAL_IO_PROTOCOL                     *SerialIo;
  BOOLEAN                                    OpenByDriver;

  *Count = 0;
  //
  // If the SerialIo instance specified by RemainingDevicePath is already created,
  // update the attributes/control.
  //
  Status = gBS->OpenProtocolInformation (
    Controller,
    IoProtocolGuid,
    &OpenInfoBuffer,
    &EntryCount
    );
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  SerialDevices = AllocatePool (EntryCount * sizeof (SERIAL_DEV *));
  ASSERT (SerialDevices != NULL);

  *Count = 0;
  OpenByDriver = FALSE;
  for (Index = 0; Index < EntryCount; Index++) {
    if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
      Status = gBS->OpenProtocol (
        OpenInfoBuffer[Index].ControllerHandle,
        &gEfiSerialIoProtocolGuid,
        (VOID **) &SerialIo,
        gSerialControllerDriver.DriverBindingHandle,
        Controller,
        EFI_OPEN_PROTOCOL_GET_PROTOCOL
        );
      if (!EFI_ERROR (Status)) {
        SerialDevices[(*Count)++] = SERIAL_DEV_FROM_THIS (SerialIo);
      }
    }


    if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
      ASSERT (OpenInfoBuffer[Index].AgentHandle == gSerialControllerDriver.DriverBindingHandle);
      OpenByDriver = TRUE;
    }
  }
  if (OpenInfoBuffer != NULL) {
    FreePool (OpenInfoBuffer);
  }

  ASSERT ((*Count == 0) || (OpenByDriver));

  return SerialDevices;
}

/**
  Start to management the controller passed in

  @param  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param  Controller           The handle of the controller to test.
  @param  RemainingDevicePath  A pointer to the remaining portion of a device path.

  @return EFI_SUCCESS   Driver is started successfully
**/
EFI_STATUS
EFIAPI
SerialControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                                 Status;
  UINTN                                      Index;
  EFI_DEVICE_PATH_PROTOCOL                   *ParentDevicePath;
  EFI_DEVICE_PATH_PROTOCOL                   *Node;
  EFI_SERIAL_IO_PROTOCOL                     *SerialIo;
  UINT32                                     ControllerNumber;
  UART_DEVICE_PATH                           *Uart;
  UART_FLOW_CONTROL_DEVICE_PATH              *FlowControl;
  UINT32                                     Control;
  PARENT_IO_PROTOCOL_PTR                     ParentIo;
  ACPI_HID_DEVICE_PATH                       *Acpi;
  EFI_GUID                                   *IoProtocolGuid;
  PCI_SERIAL_PARAMETER                       *PciSerialParameter;
  PCI_SERIAL_PARAMETER                       DefaultPciSerialParameter;
  PCI_TYPE00                                 Pci;
  UINT32                                     PciSerialCount;
  SERIAL_DEV                                 **SerialDevices;
  UINTN                                      SerialDeviceCount;
  PCI_DEVICE_INFO                            *PciDeviceInfo;
  UINT64                                     Supports;
  BOOLEAN                                    ContainsControllerNode;

  //
  // Get the Parent Device Path
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }
  //
  // Report status code enable the serial
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_P_PC_ENABLE | EFI_PERIPHERAL_SERIAL_PORT,
    ParentDevicePath
    );

  //
  // Grab the IO abstraction we need to get any work done
  //
  IoProtocolGuid = &gEfiSioProtocolGuid;
  Status = gBS->OpenProtocol (
                  Controller,
                  IoProtocolGuid,
                  (VOID **) &ParentIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    IoProtocolGuid = &gEfiPciIoProtocolGuid;
    Status = gBS->OpenProtocol (
                    Controller,
                    IoProtocolGuid,
                    (VOID **) &ParentIo,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_BY_DRIVER
                    );
  }
  ASSERT (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED);

  //
  // Do nothing for END device path node
  //
  if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
    return EFI_SUCCESS;
  }

  ControllerNumber = 0;
  ContainsControllerNode = FALSE;
  SerialDevices = GetChildSerialDevices (Controller, IoProtocolGuid, &SerialDeviceCount);

  if (SerialDeviceCount != 0) {
    if (RemainingDevicePath == NULL) {
      //
      // If the SerialIo instance is already created, NULL as RemainingDevicePath is treated
      // as to create the same SerialIo instance.
      //
      return EFI_SUCCESS;
    } else {
      //
      // Update the attributes/control of the SerialIo instance specified by RemainingDevicePath.
      //
      Uart = (UART_DEVICE_PATH *) SkipControllerDevicePathNode (RemainingDevicePath, &ContainsControllerNode, &ControllerNumber);
      for (Index = 0; Index < SerialDeviceCount; Index++) {
        ASSERT ((SerialDevices != NULL) && (SerialDevices[Index] != NULL));
        if ((!SerialDevices[Index]->ContainsControllerNode && !ContainsControllerNode) ||
            (SerialDevices[Index]->ContainsControllerNode && ContainsControllerNode && SerialDevices[Index]->Instance == ControllerNumber)
            ) {
          SerialIo = &SerialDevices[Index]->SerialIo;
          Status = EFI_INVALID_PARAMETER;
          //
          // Pass NULL ActualBaudRate to VerifyUartParameters to disallow baudrate degrade.
          // DriverBindingStart() shouldn't create a handle with different UART device path.
          //
          if (VerifyUartParameters (SerialDevices[Index]->ClockRate, Uart->BaudRate, Uart->DataBits,
                                    (EFI_PARITY_TYPE) Uart->Parity, (EFI_STOP_BITS_TYPE) Uart->StopBits, NULL, NULL)) {
            Status = SerialIo->SetAttributes (
                                 SerialIo,
                                 Uart->BaudRate,
                                 SerialIo->Mode->ReceiveFifoDepth,
                                 SerialIo->Mode->Timeout,
                                 (EFI_PARITY_TYPE) Uart->Parity,
                                 Uart->DataBits,
                                 (EFI_STOP_BITS_TYPE) Uart->StopBits
                                 );
          }
          FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);
          if (!EFI_ERROR (Status) && IsUartFlowControlDevicePathNode (FlowControl)) {
            Status = SerialIo->GetControl (SerialIo, &Control);
            if (!EFI_ERROR (Status)) {
              if (ReadUnaligned32 (&FlowControl->FlowControlMap) == UART_FLOW_CONTROL_HARDWARE) {
                Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
              } else {
                Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
              }
              //
              // Clear the bits that are not allowed to pass to SetControl
              //
              Control &= (EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |
                          EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
                          EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);
              Status = SerialIo->SetControl (SerialIo, Control);
            }
          }
          break;
        }
      }
      if (Index != SerialDeviceCount) {
        //
        // Directly return if the SerialIo instance specified by RemainingDevicePath is found and updated.
        // Otherwise continue to create the instance specified by RemainingDevicePath.
        //
        if (SerialDevices != NULL) {
          FreePool (SerialDevices);
        }
        return Status;
      }
    }
  }

  if (RemainingDevicePath != NULL) {
    Uart = (UART_DEVICE_PATH *) SkipControllerDevicePathNode (RemainingDevicePath, &ContainsControllerNode, &ControllerNumber);
  } else {
    Uart = NULL;
  }

  PciDeviceInfo = NULL;
  if (IoProtocolGuid == &gEfiSioProtocolGuid) {
    Status = EFI_NOT_FOUND;
    if (RemainingDevicePath == NULL || !ContainsControllerNode) {
      Node = ParentDevicePath;
      do {
        Acpi = (ACPI_HID_DEVICE_PATH *) Node;
        Node = NextDevicePathNode (Node);
      } while (!IsDevicePathEnd (Node));
      Status = CreateSerialDevice (Controller, Uart, ParentDevicePath, FALSE, Acpi->UID, ParentIo, NULL, NULL);
      DEBUG ((EFI_D_INFO, "PciSioSerial: Create SIO child serial device - %r\n", Status));
    }
  } else {
    Status = ParentIo.PciIo->Pci.Read (ParentIo.PciIo, EfiPciIoWidthUint8, 0, sizeof (Pci), &Pci);
    if (!EFI_ERROR (Status)) {
      //
      // PcdPciSerialParameters takes the higher priority.
      //
      PciSerialCount = 0;
      for (PciSerialParameter = PcdGetPtr (PcdPciSerialParameters); PciSerialParameter->VendorId != 0xFFFF; PciSerialParameter++) {
        if ((PciSerialParameter->VendorId == Pci.Hdr.VendorId) &&
            (PciSerialParameter->DeviceId == Pci.Hdr.DeviceId)
            ) {
          PciSerialCount++;
        }
      }

      if (SerialDeviceCount == 0) {
        //
        // Enable the IO & MEM decoding when creating the first child.
        // Restore the PCI attributes when all children is destroyed (PciDeviceInfo->ChildCount == 0).
        //
        PciDeviceInfo = AllocatePool (sizeof (PCI_DEVICE_INFO));
        ASSERT (PciDeviceInfo != NULL);
        PciDeviceInfo->ChildCount = 0;
        PciDeviceInfo->PciIo = ParentIo.PciIo;
        Status = ParentIo.PciIo->Attributes (
          ParentIo.PciIo,
          EfiPciIoAttributeOperationGet,
          0,
          &PciDeviceInfo->PciAttributes
          );

        if (!EFI_ERROR (Status)) {
          Status = ParentIo.PciIo->Attributes (
            ParentIo.PciIo,
            EfiPciIoAttributeOperationSupported,
            0,
            &Supports
            );
          if (!EFI_ERROR (Status)) {
            Supports &= (UINT64)(EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY);
            Status = ParentIo.PciIo->Attributes (
              ParentIo.PciIo,
              EfiPciIoAttributeOperationEnable,
              Supports,
              NULL
              );
          }
        }
      } else {
        //
        // Re-use the PciDeviceInfo stored in existing children.
        //
        ASSERT ((SerialDevices != NULL) && (SerialDevices[0] != NULL));
        PciDeviceInfo = SerialDevices[0]->PciDeviceInfo;
        ASSERT (PciDeviceInfo != NULL);
      }

      Status = EFI_NOT_FOUND;
      if (PciSerialCount <= 1) {
        //
        // PCI serial device contains only one UART
        //
        if (RemainingDevicePath == NULL || !ContainsControllerNode) {
          //
          // This PCI serial device is matched by class code in Supported()
          //
          if (PciSerialCount == 0) {
            DefaultPciSerialParameter.VendorId = Pci.Hdr.VendorId;
            DefaultPciSerialParameter.DeviceId = Pci.Hdr.DeviceId;
            DefaultPciSerialParameter.BarIndex = 0;
            DefaultPciSerialParameter.Offset = 0;
            DefaultPciSerialParameter.RegisterStride = 0;
            DefaultPciSerialParameter.ClockRate = 0;
            PciSerialParameter = &DefaultPciSerialParameter;
          } else if (PciSerialCount == 1) {
            PciSerialParameter = PcdGetPtr (PcdPciSerialParameters);
          }

          Status = CreateSerialDevice (Controller, Uart, ParentDevicePath, FALSE, 0, ParentIo, PciSerialParameter, PciDeviceInfo);
          DEBUG ((EFI_D_INFO, "PciSioSerial: Create PCI child serial device (single) - %r\n", Status));
          if (!EFI_ERROR (Status)) {
            PciDeviceInfo->ChildCount++;
          }
        }
      } else {
        //
        // PCI serial device contains multiple UARTs
        //
        if (RemainingDevicePath == NULL || ContainsControllerNode) {
          PciSerialCount = 0;
          for (PciSerialParameter = PcdGetPtr (PcdPciSerialParameters); PciSerialParameter->VendorId != 0xFFFF; PciSerialParameter++) {
            if ((PciSerialParameter->VendorId == Pci.Hdr.VendorId) &&
                (PciSerialParameter->DeviceId == Pci.Hdr.DeviceId) &&
                ((RemainingDevicePath == NULL) || (ControllerNumber == PciSerialCount))
                ) {
              //
              // Create controller node when PCI serial device contains multiple UARTs
              //
              Status = CreateSerialDevice (Controller, Uart, ParentDevicePath, TRUE, PciSerialCount, ParentIo, PciSerialParameter, PciDeviceInfo);
              PciSerialCount++;
              DEBUG ((EFI_D_INFO, "PciSioSerial: Create PCI child serial device (multiple) - %r\n", Status));
              if (!EFI_ERROR (Status)) {
                PciDeviceInfo->ChildCount++;
              }
            }
          }
        }
      }
    }
  }

  if (SerialDevices != NULL) {
    FreePool (SerialDevices);
  }

  //
  // For multiple PCI serial devices, set Status to SUCCESS if one child is created successfully
  //
  if ((PciDeviceInfo != NULL) && (PciDeviceInfo->ChildCount != 0)) {
    Status = EFI_SUCCESS;
  }

  if (EFI_ERROR (Status) && (SerialDeviceCount == 0)) {
    if (PciDeviceInfo != NULL) {
      Status = ParentIo.PciIo->Attributes (
        ParentIo.PciIo,
        EfiPciIoAttributeOperationSet,
        PciDeviceInfo->PciAttributes,
        NULL
        );
      ASSERT_EFI_ERROR (Status);
      FreePool (PciDeviceInfo);
    }
    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    gBS->CloseProtocol (
           Controller,
           IoProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
  }

  return Status;
}

/**
  Disconnect this driver with the controller, uninstall related protocol instance

  @param  This                  A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param  Controller            The handle of the controller to test.
  @param  NumberOfChildren      Number of child device.
  @param  ChildHandleBuffer     A pointer to the remaining portion of a device path.

  @retval EFI_SUCCESS           Operation successfully
  @retval EFI_DEVICE_ERROR      Cannot stop the driver successfully

**/
EFI_STATUS
EFIAPI
SerialControllerDriverStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN  EFI_HANDLE                     Controller,
  IN  UINTN                          NumberOfChildren,
  IN  EFI_HANDLE                     *ChildHandleBuffer
  )

{
  EFI_STATUS                          Status;
  UINTN                               Index;
  BOOLEAN                             AllChildrenStopped;
  EFI_SERIAL_IO_PROTOCOL              *SerialIo;
  SERIAL_DEV                          *SerialDevice;
  VOID                                *IoProtocol;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
  PCI_DEVICE_INFO                     *PciDeviceInfo;

  PciDeviceInfo = NULL;

  Status = gBS->HandleProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &DevicePath
                  );

  //
  // Report the status code disable the serial
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_P_PC_DISABLE | EFI_PERIPHERAL_SERIAL_PORT,
    DevicePath
    );

  if (NumberOfChildren == 0) {
    //
    // Close the bus driver
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiPciIoProtocolGuid,
                    &IoProtocol,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                    );
    gBS->CloseProtocol (
           Controller,
           !EFI_ERROR (Status) ? &gEfiPciIoProtocolGuid : &gEfiSioProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );

    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    return EFI_SUCCESS;
  }

  AllChildrenStopped = TRUE;

  for (Index = 0; Index < NumberOfChildren; Index++) {

    Status = gBS->OpenProtocol (
                    ChildHandleBuffer[Index],
                    &gEfiSerialIoProtocolGuid,
                    (VOID **) &SerialIo,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {

      SerialDevice = SERIAL_DEV_FROM_THIS (SerialIo);
      ASSERT ((PciDeviceInfo == NULL) || (PciDeviceInfo == SerialDevice->PciDeviceInfo));
      PciDeviceInfo = SerialDevice->PciDeviceInfo;

      Status = gBS->CloseProtocol (
                      Controller,
                      PciDeviceInfo != NULL ? &gEfiPciIoProtocolGuid : &gEfiSioProtocolGuid,
                      This->DriverBindingHandle,
                      ChildHandleBuffer[Index]
                      );

      Status = gBS->UninstallMultipleProtocolInterfaces (
                      ChildHandleBuffer[Index],
                      &gEfiDevicePathProtocolGuid, SerialDevice->DevicePath,
                      &gEfiSerialIoProtocolGuid,   &SerialDevice->SerialIo,
                      NULL
                      );
      if (EFI_ERROR (Status)) {
        gBS->OpenProtocol (
               Controller,
               PciDeviceInfo != NULL ? &gEfiPciIoProtocolGuid : &gEfiSioProtocolGuid,
               &IoProtocol,
               This->DriverBindingHandle,
               ChildHandleBuffer[Index],
               EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
               );
      } else {
        FreePool (SerialDevice->DevicePath);
        FreeUnicodeStringTable (SerialDevice->ControllerNameTable);
        FreePool (SerialDevice);

        if (PciDeviceInfo != NULL) {
          ASSERT (PciDeviceInfo->ChildCount != 0);
          PciDeviceInfo->ChildCount--;
        }
      }
    }

    if (EFI_ERROR (Status)) {
      AllChildrenStopped = FALSE;
    }
  }

  if (!AllChildrenStopped) {
    return EFI_DEVICE_ERROR;
  } else {
    //
    // If all children are destroyed, restore the PCI attributes.
    //
    if ((PciDeviceInfo != NULL) && (PciDeviceInfo->ChildCount == 0)) {
      ASSERT (PciDeviceInfo->PciIo != NULL);
      Status = PciDeviceInfo->PciIo->Attributes (
        PciDeviceInfo->PciIo,
        EfiPciIoAttributeOperationSet,
        PciDeviceInfo->PciAttributes,
        NULL
        );
      ASSERT_EFI_ERROR (Status);
      FreePool (PciDeviceInfo);
    }
    return EFI_SUCCESS;
  }
}
