summaryrefslogtreecommitdiff
path: root/CorebootModulePkg/PciSioSerialDxe/Serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'CorebootModulePkg/PciSioSerialDxe/Serial.c')
-rw-r--r--CorebootModulePkg/PciSioSerialDxe/Serial.c1248
1 files changed, 0 insertions, 1248 deletions
diff --git a/CorebootModulePkg/PciSioSerialDxe/Serial.c b/CorebootModulePkg/PciSioSerialDxe/Serial.c
deleted file mode 100644
index 2f1a9a000b..0000000000
--- a/CorebootModulePkg/PciSioSerialDxe/Serial.c
+++ /dev/null
@@ -1,1248 +0,0 @@
-/** @file
- Serial driver for PCI or SIO UARTS.
-
-Copyright (c) 2006 - 2015, 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 == PCI_BAR_ALL) ? 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 the SerialIo instance specified by RemainingDevicePath is already created,
- // update the attributes/control.
- //
- if ((SerialDeviceCount != 0) && (RemainingDevicePath != NULL)) {
- 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;
- }
-}