\r
#include "LegacyBiosInterface.h"\r
\r
+/**\r
+ Collect EFI Info about legacy devices through Super IO interface.\r
+\r
+ @param SioPtr Pointer to SIO data.\r
+\r
+ @retval EFI_SUCCESS When SIO data is got successfully.\r
+ @retval EFI_NOT_FOUND When ISA IO interface is absent.\r
+\r
+**/\r
+EFI_STATUS\r
+LegacyBiosBuildSioDataFromSio (\r
+ IN DEVICE_PRODUCER_DATA_HEADER *SioPtr\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ DEVICE_PRODUCER_SERIAL *SioSerial;\r
+ DEVICE_PRODUCER_PARALLEL *SioParallel;\r
+ DEVICE_PRODUCER_FLOPPY *SioFloppy;\r
+ UINTN HandleCount;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN Index;\r
+ UINTN ChildIndex;\r
+ EFI_SIO_PROTOCOL *Sio;\r
+ ACPI_RESOURCE_HEADER_PTR Resources;\r
+ EFI_ACPI_IO_PORT_DESCRIPTOR *IoResource;\r
+ EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *FixedIoResource;\r
+ EFI_ACPI_DMA_DESCRIPTOR *DmaResource;\r
+ EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR *IrqResource;\r
+ UINT16 Address;\r
+ UINT8 Dma;\r
+ UINT8 Irq;\r
+ UINTN EntryCount;\r
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ ACPI_HID_DEVICE_PATH *Acpi;\r
+\r
+ //\r
+ // Get the list of ISA controllers in the system\r
+ //\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiSioProtocolGuid,\r
+ NULL,\r
+ &HandleCount,\r
+ &HandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ //\r
+ // Collect legacy information from each of the ISA controllers in the system\r
+ //\r
+ for (Index = 0; Index < HandleCount; Index++) {\r
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSioProtocolGuid, (VOID **) &Sio);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ Address = MAX_UINT16;\r
+ Dma = MAX_UINT8;\r
+ Irq = MAX_UINT8;\r
+ Status = Sio->GetResources (Sio, &Resources);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Get the base address information from ACPI resource descriptor.\r
+ //\r
+ while (Resources.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) {\r
+ switch (Resources.SmallHeader->Byte) {\r
+ case ACPI_IO_PORT_DESCRIPTOR:\r
+ IoResource = (EFI_ACPI_IO_PORT_DESCRIPTOR *) Resources.SmallHeader;\r
+ Address = IoResource->BaseAddressMin;\r
+ break;\r
+\r
+ case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR:\r
+ FixedIoResource = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *) Resources.SmallHeader;\r
+ Address = FixedIoResource->BaseAddress;\r
+ break;\r
+\r
+ case ACPI_DMA_DESCRIPTOR:\r
+ DmaResource = (EFI_ACPI_DMA_DESCRIPTOR *) Resources.SmallHeader;\r
+ Dma = (UINT8) LowBitSet32 (DmaResource->ChannelMask);\r
+ break;\r
+\r
+ case ACPI_IRQ_DESCRIPTOR:\r
+ case ACPI_IRQ_NOFLAG_DESCRIPTOR:\r
+ IrqResource = (EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR *) Resources.SmallHeader;\r
+ Irq = (UINT8) LowBitSet32 (IrqResource->Mask);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ if (Resources.SmallHeader->Bits.Type == 0) {\r
+ Resources.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) Resources.SmallHeader\r
+ + Resources.SmallHeader->Bits.Length\r
+ + sizeof (*Resources.SmallHeader));\r
+ } else {\r
+ Resources.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) Resources.LargeHeader\r
+ + Resources.LargeHeader->Length\r
+ + sizeof (*Resources.LargeHeader));\r
+ }\r
+ }\r
+ }\r
+\r
+ DEBUG ((EFI_D_INFO, "LegacySio: Address/Dma/Irq = %x/%d/%d\n", Address, Dma, Irq));\r
+\r
+ DevicePath = DevicePathFromHandle (HandleBuffer[Index]);\r
+ if (DevicePath == NULL) {\r
+ continue;\r
+ }\r
+\r
+ Acpi = NULL;\r
+ while (!IsDevicePathEnd (DevicePath)) {\r
+ Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ }\r
+\r
+ if ((Acpi == NULL) || (DevicePathType (Acpi) != ACPI_DEVICE_PATH) ||\r
+ ((DevicePathSubType (Acpi) != ACPI_DP) && (DevicePathSubType (Acpi) != ACPI_EXTENDED_DP))\r
+ ) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // See if this is an ISA serial port\r
+ //\r
+ // Ignore DMA resource since it is always returned NULL\r
+ //\r
+ if (Acpi->HID == EISA_PNP_ID (0x500) || Acpi->HID == EISA_PNP_ID (0x501)) {\r
+\r
+ if (Acpi->UID < 4 && Address != MAX_UINT16 && Irq != MAX_UINT8) {\r
+ //\r
+ // Get the handle of the child device that has opened the Super I/O Protocol\r
+ //\r
+ Status = gBS->OpenProtocolInformation (\r
+ HandleBuffer[Index],\r
+ &gEfiSioProtocolGuid,\r
+ &OpenInfoBuffer,\r
+ &EntryCount\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+ for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) {\r
+ if ((OpenInfoBuffer[ChildIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
+ Status = gBS->HandleProtocol (OpenInfoBuffer[ChildIndex].ControllerHandle, &gEfiSerialIoProtocolGuid, (VOID **) &SerialIo);\r
+ if (!EFI_ERROR (Status)) {\r
+ SioSerial = &SioPtr->Serial[Acpi->UID];\r
+ SioSerial->Address = Address;\r
+ SioSerial->Irq = Irq;\r
+ SioSerial->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ FreePool (OpenInfoBuffer);\r
+ }\r
+ }\r
+ //\r
+ // See if this is an ISA parallel port\r
+ //\r
+ // Ignore DMA resource since it is always returned NULL, port\r
+ // only used in output mode.\r
+ //\r
+ if (Acpi->HID == EISA_PNP_ID (0x400) || Acpi->HID == EISA_PNP_ID (0x401)) {\r
+ if (Acpi->UID < 3 && Address != MAX_UINT16 && Irq != MAX_UINT8 && Dma != MAX_UINT8) {\r
+ SioParallel = &SioPtr->Parallel[Acpi->UID];\r
+ SioParallel->Address = Address;\r
+ SioParallel->Irq = Irq;\r
+ SioParallel->Dma = Dma;\r
+ SioParallel->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY;\r
+ }\r
+ }\r
+ //\r
+ // See if this is an ISA floppy controller\r
+ //\r
+ if (Acpi->HID == EISA_PNP_ID (0x604)) {\r
+ if (Address != MAX_UINT16 && Irq != MAX_UINT8 && Dma != MAX_UINT8) {\r
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);\r
+ if (!EFI_ERROR (Status)) {\r
+ SioFloppy = &SioPtr->Floppy;\r
+ SioFloppy->Address = Address;\r
+ SioFloppy->Irq = Irq;\r
+ SioFloppy->Dma = Dma;\r
+ SioFloppy->NumberOfFloppy++;\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // See if this is a mouse\r
+ // Always set mouse found so USB hot plug will work\r
+ //\r
+ // Ignore lower byte of HID. Pnp0fxx is any type of mouse.\r
+ //\r
+ // Hid = ResourceList->Device.HID & 0xff00ffff;\r
+ // PnpId = EISA_PNP_ID(0x0f00);\r
+ // if (Hid == PnpId) {\r
+ // if (ResourceList->Device.UID == 1) {\r
+ // Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer);\r
+ // if (!EFI_ERROR (Status)) {\r
+ //\r
+ SioPtr->MousePresent = 0x01;\r
+ //\r
+ // }\r
+ // }\r
+ // }\r
+ //\r
+ }\r
+\r
+ FreePool (HandleBuffer);\r
+ return EFI_SUCCESS;\r
+\r
+}\r
\r
/**\r
Collect EFI Info about legacy devices through ISA IO interface.\r
gBS->ConnectController (IsaBusController, NULL, NULL, TRUE);\r
}\r
\r
- LegacyBiosBuildSioDataFromIsaIo (SioPtr);\r
+ Status = LegacyBiosBuildSioDataFromIsaIo (SioPtr);\r
+ if (EFI_ERROR (Status)) {\r
+ LegacyBiosBuildSioDataFromSio (SioPtr);\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r