424 lines
15 KiB
C
424 lines
15 KiB
C
/** @file
|
|
Old ISA ACPI Protocol Implementation
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2019 - 2020, 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 "IsaAcpi.h"
|
|
#include "OldIsaAcpi.h"
|
|
|
|
STATIC H2O_OLD_ISA_PROTOCOL mOldIsaProtocols[] = {
|
|
{ EISA_PNP_ID (0x303), &gEfiIsaPnp303DeviceProtocolGuid, NULL, 0 },
|
|
{ EISA_PNP_ID (0x401), &gEfiIsaPnp401DeviceProtocolGuid, NULL, 0 },
|
|
{ EISA_PNP_ID (0x501), &gEfiIsaPnp501DeviceProtocolGuid, NULL, 0 },
|
|
{ EISA_PNP_ID (0x510), &gEfiIsaPnp510DeviceProtocolGuid, NULL, 0 },
|
|
{ EISA_PNP_ID (0x604), &gEfiIsaPnp604DeviceProtocolGuid, NULL, 0 },
|
|
{ EISA_PNP_ID (0xB02F), &gEfiIsaPnpB02fDeviceProtocolGuid, NULL, 0 },
|
|
{ EISA_PNP_ID (0xF03), &gEfiIsaPnpF03DeviceProtocolGuid, NULL, 0 }
|
|
};
|
|
|
|
/**
|
|
Sets the power state of ISA device.
|
|
|
|
This services sets the power state of the ISA device to the power state specified by On.
|
|
TRUE denotes on, FALSE denotes off. If the power state is successfully set on the ISA device,
|
|
then EFI_SUCCESS is returned.
|
|
|
|
@param[in] This The pointer to the H2O_ISA_DEVICE_PROTOCOL instance.
|
|
@param[in] On TRUE denotes on, FALSE denotes off.
|
|
|
|
@retval EFI_SUCCESS Successfully set the power state of the ISA device.
|
|
@retval Other The device could not be placed in the requested power state.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
IsaDeviceSetPower (
|
|
IN H2O_ISA_DEVICE_PROTOCOL *This,
|
|
IN BOOLEAN On
|
|
)
|
|
{
|
|
H2O_ISA_DEVICE_CONTEXT *Context;
|
|
H2O_OLD_ISA_DEVICE *Device;
|
|
|
|
Context = H2O_ISA_DEVICE_CONTEXT_FROM_PROTOCOL (This);
|
|
Device = H2O_OLD_ISA_DEVICE_FROM_CONTEXT (Context);
|
|
|
|
return Device->FunctionPtr->SetPower (On);
|
|
}
|
|
|
|
/**
|
|
Retrieves the current set of resources associated with ISA device.
|
|
|
|
Retrieves the set of I/O, MMIO, DMA, and interrupt resources that is about to
|
|
be assigned to the ISA device. These resources are returned in DeviceResource.
|
|
|
|
@param[in] This The pointer to the H2O_ISA_DEVICE_PROTOCOL instance.
|
|
@param[out] DeviceResource The pointer to the current resource that is about to
|
|
be assigned to ISA device.
|
|
The caller is responsible for freeing the buffer that
|
|
is allocated by callee.
|
|
|
|
@retval EFI_SUCCESS Successfully retrieved the current resource list.
|
|
@retval EFI_NOT_FOUND The resource list could not be retrieved.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
IsaDeviceGetCurrentResource (
|
|
IN H2O_ISA_DEVICE_PROTOCOL *This,
|
|
OUT H2O_ISA_DEVICE_RESOURCE **DeviceResource
|
|
)
|
|
{
|
|
H2O_ISA_DEVICE_CONTEXT *Context;
|
|
H2O_OLD_ISA_DEVICE *Device;
|
|
H2O_ISA_DEVICE_RESOURCE *TempDeviceResource;
|
|
EFI_STATUS Status;
|
|
|
|
Context = H2O_ISA_DEVICE_CONTEXT_FROM_PROTOCOL (This);
|
|
Device = H2O_OLD_ISA_DEVICE_FROM_CONTEXT (Context);
|
|
|
|
Status = Device->FunctionPtr->GetCurrentResource (&TempDeviceResource);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
(*DeviceResource) = AllocateCopyPool (sizeof (H2O_ISA_DEVICE_RESOURCE), TempDeviceResource);
|
|
if ((*DeviceResource) == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Retrieves the set of possible resources that may be assigned to ISA device
|
|
with SetResource().
|
|
|
|
Retrieves the possible sets of I/O, MMIO, DMA, and interrupt resources for the
|
|
ISA device. The sets are returned in DeviceResource.
|
|
|
|
TODO: If IsaBusDxe needs the possible resource in the future, this function must
|
|
be implemented to support that.
|
|
|
|
@param[in] This The pointer to the H2O_ISA_DEVICE_PROTOCOL instance.
|
|
@param[out] DeviceResource The pointer to the returned list of resource lists.
|
|
|
|
@retval EFI_UNSUPPORTED This service is currently not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
IsaDeviceGetPossibleResource (
|
|
IN H2O_ISA_DEVICE_PROTOCOL *This,
|
|
OUT H2O_ISA_DEVICE_RESOURCE **DeviceResource,
|
|
OUT UINT32 *Uid
|
|
)
|
|
{
|
|
H2O_ISA_DEVICE_CONTEXT *Context;
|
|
H2O_OLD_ISA_DEVICE *Device;
|
|
|
|
Context = H2O_ISA_DEVICE_CONTEXT_FROM_PROTOCOL (This);
|
|
Device = H2O_OLD_ISA_DEVICE_FROM_CONTEXT (Context);
|
|
|
|
return Device->FunctionPtr->GetPossibleResource (DeviceResource, Uid);
|
|
}
|
|
|
|
/**
|
|
Assigns resources to ISA device.
|
|
|
|
Assigns the I/O, MMIO, DMA, and interrupt resources specified by DeviceResource
|
|
to the ISA device.
|
|
|
|
@param[in] This The pointer to the H2O_ISA_DEVICE_PROTOCOL instance.
|
|
@param[in] DeviceResource The pointer to a resources list that must be one of the
|
|
resource lists returned by GetPosResource() for the
|
|
ISA device.
|
|
|
|
@retval EFI_SUCCESS Successfully set resources on the ISA device.
|
|
@retval Other The resources could not be set for the ISA device.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
IsaDeviceSetResource (
|
|
IN H2O_ISA_DEVICE_PROTOCOL *This,
|
|
IN H2O_ISA_DEVICE_RESOURCE *DeviceResource
|
|
)
|
|
{
|
|
H2O_ISA_DEVICE_CONTEXT *Context;
|
|
H2O_OLD_ISA_DEVICE *Device;
|
|
|
|
Context = H2O_ISA_DEVICE_CONTEXT_FROM_PROTOCOL (This);
|
|
Device = H2O_OLD_ISA_DEVICE_FROM_CONTEXT (Context);
|
|
|
|
return Device->FunctionPtr->SetResource (DeviceResource);
|
|
}
|
|
|
|
/**
|
|
Enables or disables ISA device.
|
|
|
|
@param[in] This The pointer to the H2O_ISA_DEVICE_PROTOCOL instance.
|
|
@param[in] Enable TRUE to enable the ISA device. FALSE to disable the ISA device.
|
|
|
|
@retval EFI_SUCCESS Successfully enabled/disabled the ISA device.
|
|
@retval Other The ISA device could not be placed in the requested state.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
IsaDeviceEnableDevice (
|
|
IN H2O_ISA_DEVICE_PROTOCOL *This,
|
|
IN BOOLEAN Enable
|
|
)
|
|
{
|
|
H2O_ISA_DEVICE_CONTEXT *Context;
|
|
H2O_OLD_ISA_DEVICE *Device;
|
|
|
|
Context = H2O_ISA_DEVICE_CONTEXT_FROM_PROTOCOL (This);
|
|
Device = H2O_OLD_ISA_DEVICE_FROM_CONTEXT (Context);
|
|
|
|
return Device->FunctionPtr->EnableDevice (Enable);
|
|
}
|
|
|
|
/**
|
|
Retrieves the device information that is associated with ISA device.
|
|
|
|
@param[in] This The pointer to the H2O_ISA_DEVICE_PROTOCOL instance.
|
|
@param[out] DeviceInfo The device information associated with ISA device.
|
|
The caller is responsible for freeing the buffer that
|
|
is allocated by callee.
|
|
|
|
@retval EFI_SUCCESS Successfully retrieved the device information.
|
|
@retval Other The device information could not be retrieved.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
IsaDeviceGetDeviceInfo (
|
|
IN H2O_ISA_DEVICE_PROTOCOL *This,
|
|
OUT H2O_ISA_DEVICE_INFO **DeviceInfo
|
|
)
|
|
{
|
|
H2O_ISA_DEVICE_CONTEXT *Context;
|
|
|
|
if (DeviceInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Context = H2O_ISA_DEVICE_CONTEXT_FROM_PROTOCOL (This);
|
|
(*DeviceInfo) = (H2O_ISA_DEVICE_INFO *) AllocateCopyPool (sizeof (H2O_ISA_DEVICE_INFO), &Context->DeviceInfo);
|
|
|
|
if (*DeviceInfo == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Set UID field in device information associated with ISA device.
|
|
|
|
This function would check ChipInstance, ConfigPort and DeviceInstance in device
|
|
information. If they matches this device, the UID would be updated
|
|
|
|
@param[in] This The pointer to the H2O_ISA_DEVICE_PROTOCOL instance.
|
|
@param[in] DeviceInfo The pointer to device information associated with ISA device.
|
|
|
|
@retval EFI_SUCCESS Successfully retrieved the device information.
|
|
@retval Other The UID could not be updated.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
IsaDeviceSetUid (
|
|
IN H2O_ISA_DEVICE_PROTOCOL *This,
|
|
IN H2O_ISA_DEVICE_INFO *DeviceInfo
|
|
)
|
|
{
|
|
H2O_ISA_DEVICE_CONTEXT *Context;
|
|
|
|
if (DeviceInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Context = H2O_ISA_DEVICE_CONTEXT_FROM_PROTOCOL (This);
|
|
|
|
if (DeviceInfo->ChipInstance != Context->DeviceInfo.ChipInstance ||
|
|
DeviceInfo->ConfigPort != Context->DeviceInfo.ConfigPort ||
|
|
DeviceInfo->DeviceInstance != Context->DeviceInfo.DeviceInstance ||
|
|
DeviceInfo->Hid != Context->DeviceInfo.Hid
|
|
)
|
|
{
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Context->DeviceInfo.Uid = DeviceInfo->Uid;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Publish old-policy ISA devices.
|
|
|
|
Term "old-policy" means the old interface associated with gEfiIsaPnpXXXDeviceProtocolGuid
|
|
which is about to be obsolete. This function would convert its interface to a new one.
|
|
|
|
@retval EFI_SUCCESS Successfully publishes old-policy ISA devices.
|
|
@retval Other The old-policy ISA devices could not be published.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
PublishOldPolicyIsaDevices (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN ProtocolIndex;
|
|
EFI_HANDLE *HandleBuffer;
|
|
UINTN HandleBufferCount;
|
|
UINTN HandleIndex;
|
|
H2O_OLD_ISA_DEVICE *Devices;
|
|
EFI_ISA_DEVICE_RESOURCE *DeviceResource;
|
|
UINT32 Uid;
|
|
|
|
for (ProtocolIndex = 0; ProtocolIndex < sizeof (mOldIsaProtocols) / sizeof (H2O_OLD_ISA_PROTOCOL); ProtocolIndex++) {
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
mOldIsaProtocols[ProtocolIndex].Guid,
|
|
NULL,
|
|
&HandleBufferCount,
|
|
&HandleBuffer
|
|
);
|
|
if (Status == EFI_NOT_FOUND) {
|
|
continue;
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((EFI_D_ERROR, "PublishOldPolicyIsaDevices() - Failed to locate handle buffer: %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
Devices = AllocateZeroPool (HandleBufferCount * sizeof (H2O_OLD_ISA_DEVICE));
|
|
if (Devices == NULL) {
|
|
DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
|
|
FreePool (HandleBuffer);
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
for (HandleIndex = 0; HandleIndex < HandleBufferCount; HandleIndex++) {
|
|
Status = gBS->HandleProtocol (
|
|
HandleBuffer[HandleIndex],
|
|
mOldIsaProtocols[ProtocolIndex].Guid,
|
|
(VOID**) &Devices[HandleIndex].FunctionPtr
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((EFI_D_ERROR, "PublishOldPolicyIsaDevices() - Failed to get protocol from handle: %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
DeviceResource = NULL;
|
|
Uid = MAX_AVAILABLE_UID;
|
|
Status = Devices[HandleIndex].FunctionPtr->GetPossibleResource (&DeviceResource, &Uid);
|
|
ASSERT_EFI_ERROR (Status);
|
|
if (DeviceResource == NULL || Uid > MAX_AVAILABLE_UID) {
|
|
DEBUG ((EFI_D_WARN, "PublishOldPolicyIsaDevices() - Failed to get possible resource from device"));
|
|
continue;
|
|
}
|
|
|
|
if (DeviceResource->DmaChannel == NULL_ID) {
|
|
continue;
|
|
}
|
|
|
|
Devices[HandleIndex].Signature = H2O_OLD_ISA_DEVICE_SIGNATURE;
|
|
|
|
Devices[HandleIndex].DeviceContext.Signature = H2O_ISA_DEVICE_CONTEXT_SIGNATURE;
|
|
|
|
Devices[HandleIndex].DeviceContext.DeviceProtocol.Size = sizeof (H2O_ISA_DEVICE_PROTOCOL);
|
|
Devices[HandleIndex].DeviceContext.DeviceProtocol.SetPower = IsaDeviceSetPower;
|
|
Devices[HandleIndex].DeviceContext.DeviceProtocol.GetCurrentResource = IsaDeviceGetCurrentResource;
|
|
Devices[HandleIndex].DeviceContext.DeviceProtocol.GetPossibleResource = IsaDeviceGetPossibleResource;
|
|
Devices[HandleIndex].DeviceContext.DeviceProtocol.SetResource = IsaDeviceSetResource;
|
|
Devices[HandleIndex].DeviceContext.DeviceProtocol.EnableDevice = IsaDeviceEnableDevice;
|
|
Devices[HandleIndex].DeviceContext.DeviceProtocol.GetDeviceInfo = IsaDeviceGetDeviceInfo;
|
|
Devices[HandleIndex].DeviceContext.DeviceProtocol.SetUid = IsaDeviceSetUid;
|
|
|
|
Devices[HandleIndex].DeviceContext.DeviceInfo.IsDeviceExist = TRUE;
|
|
Devices[HandleIndex].DeviceContext.DeviceInfo.Hid = mOldIsaProtocols[ProtocolIndex].Hid;
|
|
Devices[HandleIndex].DeviceContext.DeviceInfo.Uid = 0xFFFF; // force auto-config
|
|
|
|
Devices[HandleIndex].DeviceContext.DeviceResource.IoPort = DeviceResource->IoPort;
|
|
Devices[HandleIndex].DeviceContext.DeviceResource.IrqNumber = DeviceResource->IrqNumber;
|
|
Devices[HandleIndex].DeviceContext.DeviceResource.DmaChannel = DeviceResource->DmaChannel;
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&Devices[HandleIndex].DeviceContext.Handle,
|
|
&gH2OIsaDeviceProtocolGuid,
|
|
&Devices[HandleIndex].DeviceContext.DeviceProtocol,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((EFI_D_ERROR, "PublishOldPolicyIsaDevices() - Failed to install protocol interface: %r\n", Status));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
mOldIsaProtocols[ProtocolIndex].Devices = Devices;
|
|
mOldIsaProtocols[ProtocolIndex].DeviceCount = HandleBufferCount;
|
|
|
|
FreePool (HandleBuffer);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Revoke old-policy ISA devices.
|
|
|
|
Term "old-policy" means the old interface associated with gEfiIsaPnpXXXDeviceProtocolGuid
|
|
which is about to be obsolete. This function would uninstall protocol interface for all
|
|
old-policy ISA devices and free new interfaces created by PublishOldPolicyIsaDevices().
|
|
This function should be called only when error happens.
|
|
|
|
@retval EFI_SUCCESS Successfully revokes old-policy ISA devices.
|
|
@retval Other The old-policy ISA devices could not be revoked.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RevokeOldPolicyIsaDevices (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN ProtocolIndex;
|
|
H2O_OLD_ISA_DEVICE *Devices;
|
|
UINTN DeviceCount;
|
|
UINTN DeviceIndex;
|
|
|
|
for (ProtocolIndex = 0; ProtocolIndex < sizeof (mOldIsaProtocols) / sizeof (H2O_OLD_ISA_PROTOCOL); ProtocolIndex++) {
|
|
Devices = mOldIsaProtocols[ProtocolIndex].Devices;
|
|
DeviceCount = mOldIsaProtocols[ProtocolIndex].DeviceCount;
|
|
|
|
if (Devices != NULL) {
|
|
for (DeviceIndex = 0; DeviceIndex < DeviceCount; DeviceIndex ++) {
|
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
|
Devices[DeviceIndex].DeviceContext.Handle,
|
|
&gH2OIsaDeviceProtocolGuid,
|
|
&Devices[DeviceIndex].DeviceContext.DeviceProtocol,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((EFI_D_ERROR, "RevokeOldPolicyIsaDevices() - Failed to uninstall protocol interface: %r\n", Status));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
FreePool (mOldIsaProtocols[ProtocolIndex].Devices);
|
|
mOldIsaProtocols[ProtocolIndex].Devices = NULL;
|
|
mOldIsaProtocols[ProtocolIndex].DeviceCount = 0;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|