Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <[email protected]>
Cc: Eric Dong <[email protected]>
---
 .../Csm/LegacyBiosDxe/LegacyBiosDxe.inf            |   1 +
 .../Csm/LegacyBiosDxe/LegacyBiosInterface.h        |   2 +
 .../Csm/LegacyBiosDxe/LegacySio.c                  | 222 ++++++++++++++++++++-
 3 files changed, 224 insertions(+), 1 deletion(-)

diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf 
b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
index 9090c91..430b7fa 100644
--- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
+++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
@@ -134,6 +134,7 @@ [Protocols]
   gEfiLegacyRegion2ProtocolGuid                 ## CONSUMES
   gEfiLegacyBiosProtocolGuid                    ## PRODUCES
   gEfiSerialIoProtocolGuid                      ## CONSUMES
+  gEfiSioProtocolGuid                           ## CONSUMES
 
 [Pcd]
   gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion  ## 
CONSUMES
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h 
b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h
index 3869e06..bbd074b 100644
--- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h
+++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h
@@ -20,6 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include <FrameworkDxe.h>
 #include <IndustryStandard/Pci.h>
 #include <IndustryStandard/SmBios.h>
+#include <IndustryStandard/Acpi10.h>
 
 #include <Guid/SmBios.h>
 #include <Guid/Acpi.h>
@@ -45,6 +46,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include <Protocol/Legacy8259.h>
 #include <Protocol/PciRootBridgeIo.h>
 #include <Protocol/SerialIo.h>
+#include <Protocol/SuperIo.h>
 
 #include <Library/BaseLib.h>
 #include <Library/DebugLib.h>
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacySio.c 
b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacySio.c
index a27a477..c853377 100644
--- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacySio.c
+++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacySio.c
@@ -17,6 +17,223 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 
 #include "LegacyBiosInterface.h"
 
+/**
+  Collect EFI Info about legacy devices through Super IO interface.
+
+  @param  SioPtr       Pointer to SIO data.
+
+  @retval EFI_SUCCESS   When SIO data is got successfully.
+  @retval EFI_NOT_FOUND When ISA IO interface is absent.
+
+**/
+EFI_STATUS
+LegacyBiosBuildSioDataFromSio (
+  IN DEVICE_PRODUCER_DATA_HEADER             *SioPtr
+  )
+{
+  EFI_STATUS                                 Status;
+  DEVICE_PRODUCER_SERIAL                     *SioSerial;
+  DEVICE_PRODUCER_PARALLEL                   *SioParallel;
+  DEVICE_PRODUCER_FLOPPY                     *SioFloppy;
+  UINTN                                      HandleCount;
+  EFI_HANDLE                                 *HandleBuffer;
+  UINTN                                      Index;
+  UINTN                                      ChildIndex;
+  EFI_SIO_PROTOCOL                           *Sio;
+  ACPI_RESOURCE_HEADER_PTR                   Resources;
+  EFI_ACPI_IO_PORT_DESCRIPTOR                *IoResource;
+  EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *FixedIoResource;
+  EFI_ACPI_DMA_DESCRIPTOR                    *DmaResource;
+  EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR             *IrqResource;
+  UINT16                                     Address;
+  UINT8                                      Dma;
+  UINT8                                      Irq;
+  UINTN                                      EntryCount;
+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY        *OpenInfoBuffer;
+  EFI_BLOCK_IO_PROTOCOL                      *BlockIo;
+  EFI_SERIAL_IO_PROTOCOL                     *SerialIo;
+  EFI_DEVICE_PATH_PROTOCOL                   *DevicePath;
+  ACPI_HID_DEVICE_PATH                       *Acpi;
+
+  //
+  // Get the list of ISA controllers in the system
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiSioProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+  //
+  // Collect legacy information from each of the ISA controllers in the system
+  //
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSioProtocolGuid, 
(VOID **) &Sio);
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    Address = MAX_UINT16;
+    Dma     = MAX_UINT8;
+    Irq     = MAX_UINT8;
+    Status = Sio->GetResources (Sio, &Resources);
+    if (!EFI_ERROR (Status)) {
+      //
+      // Get the base address information from ACPI resource descriptor.
+      //
+      while (Resources.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) {
+        switch (Resources.SmallHeader->Byte) {
+        case ACPI_IO_PORT_DESCRIPTOR:
+          IoResource = (EFI_ACPI_IO_PORT_DESCRIPTOR *) Resources.SmallHeader;
+          Address = IoResource->BaseAddressMin;
+          break;
+
+        case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR:
+          FixedIoResource = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *) 
Resources.SmallHeader;
+          Address = FixedIoResource->BaseAddress;
+          break;
+
+        case ACPI_DMA_DESCRIPTOR:
+          DmaResource = (EFI_ACPI_DMA_DESCRIPTOR *) Resources.SmallHeader;
+          Dma = (UINT8) LowBitSet32 (DmaResource->ChannelMask);
+          break;
+
+        case ACPI_IRQ_DESCRIPTOR:
+        case ACPI_IRQ_NOFLAG_DESCRIPTOR:
+          IrqResource = (EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR *) 
Resources.SmallHeader;
+          Irq = (UINT8) LowBitSet32 (IrqResource->Mask);
+          break;
+
+        default:
+          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));
+        }
+      }
+    }
+
+    DEBUG ((EFI_D_INFO, "LegacySio: Address/Dma/Irq = %x/%d/%d\n", Address, 
Dma, Irq));
+
+    DevicePath = DevicePathFromHandle (HandleBuffer[Index]);
+    if (DevicePath == NULL) {
+      continue;
+    }
+
+    Acpi = NULL;
+    while (!IsDevicePathEnd (DevicePath)) {
+      Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;
+      DevicePath = NextDevicePathNode (DevicePath);
+    }
+
+    if ((Acpi == NULL) || (DevicePathType (Acpi) != ACPI_DEVICE_PATH) ||
+        ((DevicePathSubType (Acpi) != ACPI_DP) && (DevicePathSubType (Acpi) != 
ACPI_EXTENDED_DP))
+        ) {
+      continue;
+    }
+
+    //
+    // See if this is an ISA serial port
+    //
+    // Ignore DMA resource since it is always returned NULL
+    //
+    if (Acpi->HID == EISA_PNP_ID (0x500) || Acpi->HID == EISA_PNP_ID (0x501)) {
+
+      if (Acpi->UID < 4 && Address != MAX_UINT16 && Irq != MAX_UINT8) {
+        //
+        // Get the handle of the child device that has opened the Super I/O 
Protocol
+        //
+        Status = gBS->OpenProtocolInformation (
+                        HandleBuffer[Index],
+                        &gEfiSioProtocolGuid,
+                        &OpenInfoBuffer,
+                        &EntryCount
+                        );
+        if (EFI_ERROR (Status)) {
+          continue;
+        }
+        for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) {
+          if ((OpenInfoBuffer[ChildIndex].Attributes & 
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
+            Status = gBS->HandleProtocol 
(OpenInfoBuffer[ChildIndex].ControllerHandle, &gEfiSerialIoProtocolGuid, (VOID 
**) &SerialIo);
+            if (!EFI_ERROR (Status)) {
+              SioSerial           = &SioPtr->Serial[Acpi->UID];
+              SioSerial->Address  = Address;
+              SioSerial->Irq      = Irq;
+              SioSerial->Mode     = DEVICE_SERIAL_MODE_NORMAL | 
DEVICE_SERIAL_MODE_DUPLEX_HALF;
+              break;
+            }
+          }
+        }
+
+        FreePool (OpenInfoBuffer);
+      }
+    }
+    //
+    // See if this is an ISA parallel port
+    //
+    // Ignore DMA resource since it is always returned NULL, port
+    // only used in output mode.
+    //
+    if (Acpi->HID == EISA_PNP_ID (0x400) || Acpi->HID == EISA_PNP_ID (0x401)) {
+      if (Acpi->UID < 3 && Address != MAX_UINT16 && Irq != MAX_UINT8 && Dma != 
MAX_UINT8) {
+        SioParallel           = &SioPtr->Parallel[Acpi->UID];
+        SioParallel->Address  = Address;
+        SioParallel->Irq      = Irq;
+        SioParallel->Dma      = Dma;
+        SioParallel->Mode     = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY;
+      }
+    }
+    //
+    // See if this is an ISA floppy controller
+    //
+    if (Acpi->HID == EISA_PNP_ID (0x604)) {
+      if (Address != MAX_UINT16 && Irq != MAX_UINT8 && Dma != MAX_UINT8) {
+        Status = gBS->HandleProtocol (HandleBuffer[Index], 
&gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
+        if (!EFI_ERROR (Status)) {
+          SioFloppy           = &SioPtr->Floppy;
+          SioFloppy->Address  = Address;
+          SioFloppy->Irq      = Irq;
+          SioFloppy->Dma      = Dma;
+          SioFloppy->NumberOfFloppy++;
+        }
+      }
+    }
+    //
+    // See if this is a mouse
+    // Always set mouse found so USB hot plug will work
+    //
+    // Ignore lower byte of HID. Pnp0fxx is any type of mouse.
+    //
+    //    Hid = ResourceList->Device.HID & 0xff00ffff;
+    //    PnpId = EISA_PNP_ID(0x0f00);
+    //    if (Hid == PnpId) {
+    //      if (ResourceList->Device.UID == 1) {
+    //        Status = gBS->HandleProtocol (HandleBuffer[Index], 
&gEfiSimplePointerProtocolGuid, &SimplePointer);
+    //      if (!EFI_ERROR (Status)) {
+    //
+    SioPtr->MousePresent = 0x01;
+    //
+    //        }
+    //      }
+    //    }
+    //
+  }
+
+  FreePool (HandleBuffer);
+  return EFI_SUCCESS;
+
+}
 
 /**
   Collect EFI Info about legacy devices through ISA IO interface.
@@ -258,7 +475,10 @@ LegacyBiosBuildSioData (
     gBS->ConnectController (IsaBusController, NULL, NULL, TRUE);
   }
 
-  LegacyBiosBuildSioDataFromIsaIo (SioPtr);
+  Status = LegacyBiosBuildSioDataFromIsaIo (SioPtr);
+  if (EFI_ERROR (Status)) {
+    LegacyBiosBuildSioDataFromSio (SioPtr);
+  }
 
   return EFI_SUCCESS;
 }
-- 
2.8.3.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to