701 lines
22 KiB
C
701 lines
22 KiB
C
/** @file
|
|
Override ACPI Tables for L05 Feature
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2019, 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 "AcpiOverride.h"
|
|
|
|
EFI_ACPI_SUPPORT_PROTOCOL *mAcpiSupport = NULL;
|
|
EFI_ACPI_SET_ACPI_TABLE mOrgSetAcpiTable = NULL;
|
|
EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol = NULL;
|
|
EFI_ACPI_TABLE_INSTALL_ACPI_TABLE mOrgInstallAcpiTable = NULL;
|
|
|
|
PREFERRED_PM_PROFILE_CONVERT_TABLE mPreferredPmProfileConvertTable[] = {
|
|
// SmbiosType03Type, PreferredPmProfile
|
|
{MiscChassisTypeOther, EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED },
|
|
{MiscChassisTypeUnknown, EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED },
|
|
{MiscChassisTypeDeskTop, EFI_ACPI_6_1_PM_PROFILE_DESKTOP },
|
|
{MiscChassisTypeLowProfileDesktop, EFI_ACPI_6_1_PM_PROFILE_DESKTOP },
|
|
{MiscChassisTypePizzaBox, EFI_ACPI_6_1_PM_PROFILE_DESKTOP },
|
|
{MiscChassisTypeMiniTower, EFI_ACPI_6_1_PM_PROFILE_DESKTOP },
|
|
{MiscChassisTypeTower, EFI_ACPI_6_1_PM_PROFILE_DESKTOP },
|
|
{MiscChassisTypePortable, EFI_ACPI_6_1_PM_PROFILE_MOBILE },
|
|
{MiscChassisTypeLapTop, EFI_ACPI_6_1_PM_PROFILE_MOBILE },
|
|
{MiscChassisTypeNotebook, EFI_ACPI_6_1_PM_PROFILE_MOBILE },
|
|
{MiscChassisTypeHandHeld, EFI_ACPI_6_1_PM_PROFILE_MOBILE },
|
|
{MiscChassisTypeDockingStation, EFI_ACPI_6_1_PM_PROFILE_WORKSTATION },
|
|
{MiscChassisTypeAllInOne, EFI_ACPI_6_1_PM_PROFILE_DESKTOP },
|
|
{MiscChassisTypeSubNotebook, EFI_ACPI_6_1_PM_PROFILE_MOBILE },
|
|
{MiscChassisTypeSpaceSaving, EFI_ACPI_6_1_PM_PROFILE_DESKTOP },
|
|
{MiscChassisTypeLunchBox, EFI_ACPI_6_1_PM_PROFILE_DESKTOP },
|
|
{MiscChassisTypeMainServerChassis, EFI_ACPI_6_1_PM_PROFILE_ENTERPRISE_SERVER },
|
|
{MiscChassisTypeExpansionChassis, EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED },
|
|
{MiscChassisTypeSubChassis, EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED },
|
|
{MiscChassisTypeBusExpansionChassis, EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED },
|
|
{MiscChassisTypePeripheralChassis, EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED },
|
|
{MiscChassisTypeRaidChassis, EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED },
|
|
{MiscChassisTypeRackMountChassis, EFI_ACPI_6_1_PM_PROFILE_ENTERPRISE_SERVER },
|
|
{MiscChassisTypeSealedCasePc, EFI_ACPI_6_1_PM_PROFILE_DESKTOP },
|
|
{MiscChassisMultiSystemChassis, EFI_ACPI_6_1_PM_PROFILE_SOHO_SERVER },
|
|
{MiscChassisCompactPCI, EFI_ACPI_6_1_PM_PROFILE_APPLIANCE_PC },
|
|
{MiscChassisAdvancedTCA, EFI_ACPI_6_1_PM_PROFILE_PERFORMANCE_SERVER},
|
|
{MiscChassisBlade, EFI_ACPI_6_1_PM_PROFILE_PERFORMANCE_SERVER},
|
|
{MiscChassisBladeEnclosure, EFI_ACPI_6_1_PM_PROFILE_PERFORMANCE_SERVER},
|
|
{MiscChassisTablet, EFI_ACPI_6_1_PM_PROFILE_TABLET },
|
|
{MiscChassisConvertible, EFI_ACPI_6_1_PM_PROFILE_MOBILE },
|
|
{MiscChassisDetachable, EFI_ACPI_6_1_PM_PROFILE_TABLET }
|
|
};
|
|
|
|
UINTN mPreferredPmProfileConvertTableCount = sizeof (mPreferredPmProfileConvertTable) / sizeof (PREFERRED_PM_PROFILE_CONVERT_TABLE);
|
|
|
|
/**
|
|
Override PS2 Keyboard HID or PS2 Touch Pad HID, CID on DSDT Table.
|
|
|
|
@param DsdtTable The pointer to the DSDT table.
|
|
|
|
@retval EFI_SUCCESS Return Success by Default. The return status will not be referenced.
|
|
**/
|
|
EFI_STATUS
|
|
L05UpdateHidCidInDsdtTable (
|
|
IN EFI_ACPI_DESCRIPTION_HEADER *DsdtTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *DsdtPointer;
|
|
UINT64 *Signature;
|
|
UINT32 *Signature32;
|
|
UINT64 OldKeyBoardHid;
|
|
UINT64 NewKeyBoardHid;
|
|
UINT64 OldTouchPadHid;
|
|
UINT64 NewTouchPadHid;
|
|
UINT16 NewTouchPadCid;
|
|
UINT8 OffsetCid;
|
|
UINT8 CidId[2];
|
|
BOOLEAN UpdateKeyBoardHid;
|
|
BOOLEAN UpdateTouchPadHid;
|
|
BOOLEAN UpdateTouchPadCid;
|
|
|
|
Status = EFI_SUCCESS;
|
|
DsdtPointer = NULL;
|
|
Signature = NULL;
|
|
Signature32 = NULL;
|
|
OldKeyBoardHid = 0;
|
|
NewKeyBoardHid = 0;
|
|
OldTouchPadHid = 0;
|
|
NewTouchPadHid = 0;
|
|
NewTouchPadCid = 0;
|
|
OffsetCid = 0;
|
|
UpdateKeyBoardHid = FALSE;
|
|
UpdateTouchPadHid = FALSE;
|
|
UpdateTouchPadCid = FALSE;
|
|
|
|
//
|
|
// Get new Hardware ID & Compatible ID for Keyboard and determine update it or not
|
|
//
|
|
Status = OemSvcUpdatePs2KeyBoardHid (
|
|
&OldKeyBoardHid,
|
|
&NewKeyBoardHid
|
|
);
|
|
|
|
switch (Status) {
|
|
|
|
case EFI_MEDIA_CHANGED:
|
|
UpdateKeyBoardHid = TRUE;
|
|
break;
|
|
|
|
case EFI_UNSUPPORTED:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get new Hardware ID & Compatible ID for Touch Pad and determine update it or not
|
|
//
|
|
Status = OemSvcUpdatePs2TouchPadHidCid (
|
|
&OldTouchPadHid,
|
|
&NewTouchPadHid,
|
|
&NewTouchPadCid,
|
|
&OffsetCid
|
|
);
|
|
|
|
switch (Status) {
|
|
|
|
case EFI_MEDIA_CHANGED:
|
|
|
|
UpdateTouchPadHid = TRUE;
|
|
|
|
if (OffsetCid != 0x00) {
|
|
|
|
UpdateTouchPadCid = TRUE;
|
|
CidId[0] = (UINT8) ((NewTouchPadCid) & 0xFF);
|
|
CidId[1] = (UINT8) ((NewTouchPadCid >> 8) & 0xFF);
|
|
NewTouchPadCid = (UINT16) (CidId[0] << 8) + CidId[1];
|
|
}
|
|
|
|
break;
|
|
|
|
case EFI_UNSUPPORTED:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Do not execute this function until OemSvc be porting as above
|
|
//
|
|
if (!UpdateKeyBoardHid && !UpdateTouchPadHid) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Set new Hardware ID & Compatible ID for Keyboard or Touch Pad
|
|
//
|
|
for (DsdtPointer = (UINT8 *) ((UINTN) DsdtTable + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
|
|
DsdtPointer <= (UINT8 *) ((UINTN) DsdtTable + (UINTN) (DsdtTable->Length));
|
|
DsdtPointer++) {
|
|
|
|
Signature = (UINT64 *) DsdtPointer;
|
|
Signature32 = (UINT32 *) DsdtPointer;
|
|
|
|
//
|
|
// Update Keyboard HID
|
|
//
|
|
if (UpdateKeyBoardHid) {
|
|
|
|
if (*Signature == OldKeyBoardHid) {
|
|
|
|
*Signature = NewKeyBoardHid;
|
|
UpdateKeyBoardHid = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Touch Pad HID
|
|
//
|
|
if (UpdateTouchPadHid) {
|
|
|
|
if (*Signature == OldTouchPadHid) {
|
|
|
|
*Signature = NewTouchPadHid;
|
|
UpdateTouchPadHid = FALSE;
|
|
}
|
|
|
|
//
|
|
// Update Touch Pad CID
|
|
//
|
|
if (!UpdateTouchPadCid) {
|
|
continue;
|
|
}
|
|
|
|
switch (*Signature32) {
|
|
|
|
case (SIGNATURE_32 ('P', 'S', '2', 'M')) :
|
|
* (UINT16 *) (DsdtPointer + OffsetCid) = NewTouchPadCid;
|
|
UpdateTouchPadCid = FALSE;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// End the for loop previously if all HID or CID be updated.
|
|
//
|
|
if (!UpdateKeyBoardHid && !UpdateTouchPadHid && !UpdateTouchPadCid) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Convert FADT "Preferred_PM_Profile" vlaue from SMBIOS Type 3 Offset 05h Type.
|
|
|
|
@param SmbiosType03Type SMBIOS Type 3 Offset 05h Type.
|
|
|
|
@retval PreferredPmProfile Return convert "Preferred_PM_Profile" value.
|
|
**/
|
|
UINT8
|
|
L05PreferredPmProfileConvert (
|
|
IN UINT8 SmbiosType03Type
|
|
)
|
|
{
|
|
UINT8 PreferredPmProfile;
|
|
UINTN Index;
|
|
|
|
PreferredPmProfile = EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED;
|
|
|
|
for (Index = 0; Index < mPreferredPmProfileConvertTableCount; Index++) {
|
|
if (mPreferredPmProfileConvertTable[Index].SmbiosType03Type == SmbiosType03Type) {
|
|
PreferredPmProfile = mPreferredPmProfileConvertTable[Index].PreferredPmProfile;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return PreferredPmProfile;
|
|
}
|
|
|
|
/**
|
|
Override ACPI Table for L05 requirement.
|
|
|
|
@param Table The pointer to the new table to add or update.
|
|
@param Version Indicates to which version(s) of ACPI the table should be added.
|
|
|
|
@retval EFI_SUCCESS This ACPI Table be overrided.
|
|
@retval EFI_ALREADY_STARTED This ACPI Table do not be overrided.
|
|
@retval EFI_UNSUPPORTED This ACPI Table need be removed.
|
|
@retval EFI_INVALID_PARAMETER This ACPI Table can't be NULL before modified data.
|
|
**/
|
|
EFI_STATUS
|
|
L05ModifyAcpiTable (
|
|
IN OUT VOID *Table,
|
|
IN OUT EFI_ACPI_TABLE_VERSION *Version
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
|
|
UINT64 OemId;
|
|
UINT64 OemTableId;
|
|
EFI_L05_DXE_SLP_20_PROTOCOL *L05Slp20Ptr;
|
|
UINT8 L05Type03Type;
|
|
EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer;
|
|
|
|
if (Table == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
|
|
Status = EFI_UNSUPPORTED;
|
|
OemId = EFI_L05_ACPI_OEM_ID;
|
|
OemTableId = EFI_L05_ACPI_OEM_TABLE_ID;
|
|
L05Slp20Ptr = NULL;
|
|
FadtPointer = NULL;
|
|
|
|
switch (TableHeader->Signature) {
|
|
|
|
case EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE: // "FACS"
|
|
case 0:
|
|
case SIGNATURE_32('S', 'C', 'T', 'T'): // "SCTT"
|
|
case EFI_ACPI_5_0_PLATFORM_BINARY_TABLE_SIGNATURE: // "WPBT"
|
|
|
|
//
|
|
// Ignore to modify the table when:
|
|
//
|
|
// 1. The signature is "FACS"
|
|
//
|
|
// 2. The signature is 0 or "SCTT":
|
|
// Regard it as a dummy table.
|
|
// Actually, UEFI SCT - ACPI test calls InstallAcpiTable () with a dummmy table - all fields are zero except Checksum and Length.
|
|
// In order to pass No. 5.16.1.1.5 Test in UEFI 2.3.1 Self Certification Test (SCT) Case Specification Ver.1.2, Set.17.1.1 InstallAcpiTable (),
|
|
// feature should not modify the content of the table and should leave all of the necessary actions to Core code.
|
|
//
|
|
// 3. The signature is "WPBT":
|
|
// Computrace binary will generate this table, do not modify.
|
|
//
|
|
return EFI_ALREADY_STARTED;
|
|
break;
|
|
|
|
case EFI_ACPI_5_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
|
|
|
|
//
|
|
// Provide a hook for updating PS2 Keyboard HID or PS2 Touch Pad HID, CID if Project need.
|
|
//
|
|
L05UpdateHidCidInDsdtTable (TableHeader);
|
|
break;
|
|
|
|
case EFI_ACPI_5_0_SOFTWARE_LICENSING_TABLE_SIGNATURE:
|
|
|
|
//
|
|
// By L05 OA Requirement 009, Section 1.1
|
|
// Feature must not install SLIC Table if no valid Marker injected in BIOS.
|
|
//
|
|
Status = gBS->LocateProtocol (&gEfiL05DxeSlp20ProtocolGuid, NULL, &L05Slp20Ptr);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
if (!L05Slp20Ptr->IsValidMarker (Table)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
|
|
|
|
FadtPointer = (EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
|
|
|
|
//
|
|
// By L05 Minimum BIOS Spec V1.37 3.3.7 ACPI Table
|
|
// ACPI FADT "Preferred_PM_Profile" field need to be customized for Lenovo PCs.
|
|
// The field should be synchronized with SMBIOS Type 3 offset 5.
|
|
//
|
|
L05Type03Type = PcdGet8 (PcdL05Type03Type);
|
|
FadtPointer->PreferredPmProfile = L05PreferredPmProfileConvert (L05Type03Type);
|
|
break;
|
|
|
|
default:
|
|
|
|
//
|
|
// Do Nothing.
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Call OemSvc for project modify ACPI table
|
|
//
|
|
Status = OemSvcAcpiTableUpdate (Table);
|
|
|
|
switch (Status) {
|
|
|
|
case EFI_MEDIA_CHANGED:
|
|
break;
|
|
|
|
case EFI_UNSUPPORTED:
|
|
default:
|
|
|
|
//
|
|
// By L05 Minimum BIOS Spec V1.26 3.4.8 ACPI Table
|
|
// All of ACPI tables OEM information field need to be customized.
|
|
//
|
|
CopyMem (&TableHeader->OemId, &OemId, sizeof (TableHeader->OemId));
|
|
CopyMem (&TableHeader->OemTableId, &OemTableId, sizeof (UINT64));
|
|
TableHeader->OemRevision = PcdGet32 (PcdL05AcpiTableOemRevision);
|
|
break;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Used to add, remove, or update ACPI tables after be overrided by L05 feature.
|
|
|
|
@param This A pointer to the EFI_ACPI_SUPPORT_PROTOCOL instance.
|
|
@param Table The pointer to the new table to add or update.
|
|
@param Checksum If TRUE, indicates that the checksum should be
|
|
calculated for this table.
|
|
@param Version Indicates to which version(s) of ACPI the table should be added.
|
|
@param Handle The pointer to the handle of the table to remove or update.
|
|
|
|
@retval EFI_SUCCESS The function completed successfully.
|
|
@retval EFI_INVALID_PARAMETER *Handle was zero and Table was NULL.
|
|
@retval EFI_ABORTED Could not complete the desired action.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
L05SetAcpiTableHook (
|
|
IN EFI_ACPI_SUPPORT_PROTOCOL *This,
|
|
IN VOID *Table OPTIONAL,
|
|
IN BOOLEAN Checksum,
|
|
IN EFI_ACPI_TABLE_VERSION Version,
|
|
IN OUT UINTN *Handle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = L05ModifyAcpiTable (Table, &Version);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
|
|
//
|
|
// Force to calculate checksum if ACPI Table be modified
|
|
//
|
|
Checksum = TRUE;
|
|
}
|
|
|
|
if (Status == EFI_UNSUPPORTED) {
|
|
|
|
//
|
|
// Do not install ACPI table if status is not Success
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
return mOrgSetAcpiTable (This, Table, Checksum, Version, Handle);
|
|
}
|
|
|
|
/**
|
|
Installs an ACPI table into the RSDT/XSDT after be overrided by L05 feature.
|
|
|
|
@param This Protocol instance pointer.
|
|
@param AcpiTableBuffer A pointer to a buffer containing the ACPI table to be installed.
|
|
@param AcpiTableBufferSize Specifies the size, in bytes, of the AcpiTableBuffer buffer.
|
|
@param TableKey Reurns a key to refer to the ACPI table.
|
|
|
|
@retval EFI_SUCCESS The table was successfully inserted.
|
|
@retval EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize
|
|
and the size field embedded in the ACPI table pointed to by AcpiTableBuffer
|
|
are not in sync.
|
|
@retval EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
|
|
@retval EFI_ACCESS_DENIED The table signature matches a table already
|
|
present in the system and platform policy
|
|
does not allow duplicate tables of this type.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
L05InstallAcpiTableHook (
|
|
IN EFI_ACPI_TABLE_PROTOCOL *This,
|
|
IN VOID *AcpiTableBuffer,
|
|
IN UINTN AcpiTableBufferSize,
|
|
OUT UINTN *TableKey
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = L05ModifyAcpiTable (AcpiTableBuffer, 0);
|
|
|
|
if (Status == EFI_UNSUPPORTED) {
|
|
|
|
//
|
|
// Do not install ACPI table if status is not Success
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
return mOrgInstallAcpiTable (This, AcpiTableBuffer, AcpiTableBufferSize, TableKey);
|
|
}
|
|
|
|
/**
|
|
This main operation for override ACPI Tables
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
**/
|
|
EFI_STATUS
|
|
AcpiOverrideCore (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_ACPI_DESCRIPTION_HEADER *Table;
|
|
EFI_ACPI_TABLE_VERSION Version;
|
|
ACPI_TABLE_INFO *AcpiTableInfo;
|
|
UINTN NumberOfTable;
|
|
UINTN Handle;
|
|
UINTN Index;
|
|
|
|
Status = EFI_SUCCESS;
|
|
Table = NULL;
|
|
Version = 0;
|
|
AcpiTableInfo = NULL;
|
|
NumberOfTable = 0;
|
|
Handle = 0;
|
|
Index = 0;
|
|
|
|
//
|
|
// 1. Hook origin SetAcpiTable & InstallAcpiTable function
|
|
//
|
|
mOrgSetAcpiTable = mAcpiSupport->SetAcpiTable;
|
|
mAcpiSupport->SetAcpiTable = L05SetAcpiTableHook;
|
|
|
|
mOrgInstallAcpiTable = mAcpiTableProtocol->InstallAcpiTable;
|
|
mAcpiTableProtocol->InstallAcpiTable = L05InstallAcpiTableHook;
|
|
|
|
//
|
|
// 2. Calculate total tables
|
|
//
|
|
while (TRUE) {
|
|
Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, NumberOfTable, &Table, &Version, &Handle);
|
|
|
|
if (Status == EFI_NOT_FOUND) {
|
|
break;
|
|
}
|
|
|
|
NumberOfTable++;
|
|
|
|
if (Table != NULL) {
|
|
gBS->FreePool (Table);
|
|
Table = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// 3. Get all table data
|
|
//
|
|
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (ACPI_TABLE_INFO) * NumberOfTable, (VOID **) &AcpiTableInfo);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
for (Index = 0; Index < NumberOfTable; Index++) {
|
|
Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) &Table, &Version, &Handle);
|
|
|
|
if (Status == EFI_NOT_FOUND) {
|
|
break;
|
|
}
|
|
|
|
AcpiTableInfo[Index].Table = Table;
|
|
AcpiTableInfo[Index].Version = Version;
|
|
AcpiTableInfo[Index].Handle = Handle;
|
|
}
|
|
|
|
//
|
|
// 4. Re-Set exist ACPI Table from last table for L05 feature requirement
|
|
//
|
|
for (Index = 0; Index < NumberOfTable; Index++) {
|
|
Table = AcpiTableInfo[Index].Table;
|
|
Version = AcpiTableInfo[Index].Version;
|
|
Handle = AcpiTableInfo[Index].Handle;
|
|
|
|
Status = L05ModifyAcpiTable (Table, &Version);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
mOrgSetAcpiTable (mAcpiSupport, Table, TRUE, Version, &Handle);
|
|
}
|
|
|
|
if (Status == EFI_UNSUPPORTED) {
|
|
mOrgSetAcpiTable (mAcpiSupport, NULL, TRUE, Version, &Handle);
|
|
}
|
|
|
|
if (Table != NULL) {
|
|
gBS->FreePool (Table);
|
|
Table = NULL;
|
|
}
|
|
}
|
|
|
|
if (AcpiTableInfo != NULL) {
|
|
gBS->FreePool (AcpiTableInfo);
|
|
Table = NULL;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This is the event callback function for make sure ACPI Support Protocol and
|
|
ACPI Table Protocol is ready for override ACPI Tables
|
|
|
|
@param Event Pointer to this event
|
|
@param Context Event hanlder private data
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
AcpiOverrideCallBack (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = gBS->LocateProtocol (&gEfiAcpiSupportProtocolGuid, NULL, &mAcpiSupport);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, &mAcpiTableProtocol);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// There is no necessary to trigger this callback function again in any case.
|
|
//
|
|
gBS->CloseEvent (Event);
|
|
|
|
AcpiOverrideCore ();
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Callback from checkpoint H2O_DXE_CP_UPDATE_ACPI_DESC_HDR_DATA for L05 update OEM Table ID information
|
|
|
|
@param[in] Event The Event this notify function registered to.
|
|
@param[in] Handle The handle associated with a previously registered checkpoint handler.
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
L05DxeCpUpdateAcpiDescHdrCallback (
|
|
IN EFI_EVENT Event,
|
|
IN H2O_CP_HANDLE Handle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
H2O_DXE_CP_UPDATE_ACPI_DESC_HDR_DATA *DxeCpUpdateAcpiDescHdrData;
|
|
EFI_GUID DxeCpUpdateAcpiDescHdrGuid;
|
|
|
|
//
|
|
// Get checkpoint data by H2OCpLookup() if need use checkpoint data in callback function
|
|
//
|
|
Status = H2OCpLookup (Handle, (VOID **) &DxeCpUpdateAcpiDescHdrData, &DxeCpUpdateAcpiDescHdrGuid);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Data Not Found: %x (%r)\n", Handle, Status));
|
|
DEBUG_CP ((DEBUG_ERROR, " %a\n", __FUNCTION__));
|
|
return;
|
|
}
|
|
|
|
DxeCpUpdateAcpiDescHdrData->Status = H2O_CP_TASK_UPDATE;
|
|
Status = L05ModifyAcpiTable ((VOID *) DxeCpUpdateAcpiDescHdrData->AcpiTableHeader, NULL);
|
|
|
|
DEBUG_CP ((DEBUG_INFO, "Checkpoint Data Updated: %g\n", &DxeCpUpdateAcpiDescHdrGuid));
|
|
DEBUG_CP ((DEBUG_INFO, " %a\n", __FUNCTION__));
|
|
}
|
|
|
|
/**
|
|
This is the declaration of an EFI image entry point. This entry point is
|
|
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
|
|
both device drivers and bus drivers.
|
|
|
|
@param ImageHandle The firmware allocated handle for the UEFI image.
|
|
@param SystemTable A pointer to the EFI System Table.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
AcpiOverrideDriverEntryPoint (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
VOID *Registration;
|
|
|
|
Status = EFI_SUCCESS;
|
|
Registration = NULL;
|
|
|
|
//
|
|
// Register Event for override ACPI Tables.
|
|
//
|
|
EfiCreateProtocolNotifyEvent (
|
|
&gPublishAcpiTableDoneProtocolGuid,
|
|
TPL_CALLBACK,
|
|
AcpiOverrideCallBack,
|
|
NULL,
|
|
&Registration
|
|
);
|
|
|
|
if (PcdGetBool (PcdH2ODxeCpUpdateAcpiDescHdrSupported)) {
|
|
H2O_CP_HANDLE CpHandle;
|
|
|
|
Status = H2OCpRegisterHandler (
|
|
&gH2ODxeCpUpdateAcpiDescHdrGuid,
|
|
L05DxeCpUpdateAcpiDescHdrCallback,
|
|
H2O_CP_MEDIUM,
|
|
&CpHandle
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2ODxeCpUpdateAcpiDescHdrGuid, Status));
|
|
return Status;
|
|
}
|
|
|
|
DEBUG_CP ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2ODxeCpUpdateAcpiDescHdrGuid, Status));
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|