alder_lake_bios/Insyde/InsydeModulePkg/Csm/LegacyBiosDxe/LegacySio.c

220 lines
7.2 KiB
C

/** @file
Collect Sio information from Native EFI Drivers.
Sio is floppy, parallel, serial, ... hardware
;******************************************************************************
;* Copyright (c) 2012, Insyde Software Corporation. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "LegacyBiosInterface.h"
/**
Collect EFI Info about legacy devices.
@param Private Legacy BIOS Instance data
@retval EFI_SUCCESS It should always work.
**/
EFI_STATUS
LegacyBiosBuildSioData (
IN LEGACY_BIOS_INSTANCE *Private
)
{
EFI_STATUS Status;
DEVICE_PRODUCER_DATA_HEADER *SioPtr;
DEVICE_PRODUCER_SERIAL *Sio1Ptr;
DEVICE_PRODUCER_PARALLEL *Sio2Ptr;
DEVICE_PRODUCER_FLOPPY *Sio3Ptr;
EFI_HANDLE IsaBusController;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
UINTN Index;
UINTN ResourceIndex;
UINTN ChildIndex;
EFI_ISA_IO_PROTOCOL *IsaIo;
EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
EFI_ISA_ACPI_RESOURCE *IoResource;
EFI_ISA_ACPI_RESOURCE *DmaResource;
EFI_ISA_ACPI_RESOURCE *InterruptResource;
UINTN EntryCount;
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
//
// Get the pointer to the SIO data structure
//
SioPtr = &Private->IntThunk->EfiToLegacy16BootTable.SioData;
//
// Zero the data in the SIO data structure
//
gBS->SetMem (SioPtr, sizeof (DEVICE_PRODUCER_DATA_HEADER), 0);
//
// Find the ISA Bus Controller used for legacy
//
Status = Private->LegacyBiosPlatform->GetPlatformHandle (
Private->LegacyBiosPlatform,
EfiGetPlatformIsaBusHandle,
0,
&HandleBuffer,
&HandleCount,
NULL
);
IsaBusController = HandleBuffer[0];
if (!EFI_ERROR (Status)) {
//
// Force ISA Bus Controller to produce all ISA devices
//
gBS->ConnectController (IsaBusController, NULL, NULL, TRUE);
}
//
// Get the list of ISA controllers in the system
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiIsaIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
//
// Collect legacy information from each of the ISA controllers in the system
//
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo);
if (EFI_ERROR (Status)) {
continue;
}
ResourceList = IsaIo->ResourceList;
if (ResourceList == NULL) {
continue;
}
//
// Collect the resource types neededto fill in the SIO data structure
//
IoResource = NULL;
DmaResource = NULL;
InterruptResource = NULL;
for (ResourceIndex = 0;
ResourceList->ResourceItem[ResourceIndex].Type != EfiIsaAcpiResourceEndOfList;
ResourceIndex++
) {
switch (ResourceList->ResourceItem[ResourceIndex].Type) {
case EfiIsaAcpiResourceIo:
IoResource = &ResourceList->ResourceItem[ResourceIndex];
break;
case EfiIsaAcpiResourceMemory:
break;
case EfiIsaAcpiResourceDma:
DmaResource = &ResourceList->ResourceItem[ResourceIndex];
break;
case EfiIsaAcpiResourceInterrupt:
InterruptResource = &ResourceList->ResourceItem[ResourceIndex];
break;
default:
break;
}
}
//
// See if this is an ISA serial port
//
// Ignore DMA resource since it is always returned NULL
//
if (ResourceList->Device.HID == EISA_PNP_ID (0x500) || ResourceList->Device.HID == EISA_PNP_ID (0x501)) {
if (ResourceList->Device.UID <= 3 &&
IoResource != NULL &&
InterruptResource != NULL
) {
//
// Get the handle of the child device that has opened the ISA I/O Protocol
//
Status = gBS->OpenProtocolInformation (
HandleBuffer[Index],
&gEfiIsaIoProtocolGuid,
&OpenInfoBuffer,
&EntryCount
);
if (EFI_ERROR (Status)) {
continue;
}
//
// We want resource for legacy even if no 32-bit driver installed
//
for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) {
Sio1Ptr = &SioPtr->Serial[ResourceList->Device.UID];
Sio1Ptr->Address = (UINT16) IoResource->StartRange;
Sio1Ptr->Irq = (UINT8) InterruptResource->StartRange;
Sio1Ptr->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF;
}
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 (ResourceList->Device.HID == EISA_PNP_ID (0x400) || ResourceList->Device.HID == EISA_PNP_ID (0x401)) {
if (ResourceList->Device.UID <= 2 &&
IoResource != NULL &&
InterruptResource != NULL
) {
Sio2Ptr = &SioPtr->Parallel[ResourceList->Device.UID];
Sio2Ptr->Address = (UINT16) IoResource->StartRange;
Sio2Ptr->Irq = (UINT8) InterruptResource->StartRange;
Sio2Ptr->Dma = (DmaResource != NULL) ? (UINT8) DmaResource->StartRange : 0;
Sio2Ptr->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY;
}
}
//
// See if this is an ISA floppy controller
//
if (ResourceList->Device.HID == EISA_PNP_ID (0x604)) {
if (IoResource != NULL && InterruptResource != NULL && DmaResource != NULL) {
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
if (!EFI_ERROR (Status)) {
Sio3Ptr = &SioPtr->Floppy;
Sio3Ptr->Address = (UINT16) IoResource->StartRange;
Sio3Ptr->Irq = (UINT8) InterruptResource->StartRange;
Sio3Ptr->Dma = (UINT8) DmaResource->StartRange;
Sio3Ptr->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.
//
SioPtr->MousePresent = 0x01;
}
FreePool (HandleBuffer);
return EFI_SUCCESS;
}