VOID EFIAPI FchAcpiReadyToBootInit ( IN EFI_EVENT Event, IN VOID *Context ) { UINTN Index; INTN Instance; UINTN Size; UINTN NumberOfHandles; UINTN TableHandle; UINTN TableSize; UINT32 FvStatus; EFI_STATUS Status; EFI_HANDLE *HandleBuffer; EFI_HANDLE Handle; EFI_FV_FILETYPE FileType; EFI_FV_FILE_ATTRIBUTES Attributes; EFI_ACPI_COMMON_HEADER *CurrentTable; EFI_ACPI_DESCRIPTION_HEADER *FchAcpiBlockPtr = NULL; EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; FCH_ACPI_PROTOCOL *FchAcpiProtocol; EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol = NULL; Status = gBS->LocateProtocol ( &gEfiAcpiTableProtocolGuid, NULL, &AcpiTableProtocol ); if (EFI_ERROR (Status)) { return; } Status = gBS->LocateProtocol ( &gFchAcpiProtocolGuid, NULL, &FchAcpiProtocol ); if (EFI_ERROR (Status)) { return; } FvStatus = 0; // // Locate protocol. // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiFirmwareVolumeProtocolGuid, NULL, &NumberOfHandles, &HandleBuffer ); if (EFI_ERROR (Status)) { return; } // // Looking for FV with FCH ACPI Data Block file // for (Index = 0; Index < NumberOfHandles; Index++) { // // Get the protocol on this handle // This should not fail because of LocateHandleBuffer // Status = gBS->HandleProtocol ( HandleBuffer[Index], &gEfiFirmwareVolumeProtocolGuid, (VOID**) &FwVol ); ASSERT_EFI_ERROR (Status); // // See if it has the ACPI storage file // Size = 0; FvStatus = 0; Status = FwVol->ReadFile ( FwVol, &gAmdFchAcpiGuid, NULL, &Size, &FileType, &Attributes, &FvStatus ); // // If we found it, then we are done // if (Status == EFI_SUCCESS) { break; } } // // Read tables from the storage file. // Instance = 0; CurrentTable = NULL; while (Status == EFI_SUCCESS) { Status = FwVol->ReadSection ( FwVol, &gAmdFchAcpiGuid, EFI_SECTION_RAW, Instance, &CurrentTable, &Size, &FvStatus ); if (!EFI_ERROR (Status)) { // // Check the table ID to modify the table // if (((EFI_ACPI_DESCRIPTION_HEADER*) CurrentTable)->OemTableId == EFI_SIGNATURE_64 ('F', 'C', 'H', 'A', 'C', 'P', 'I', 0)) { FchAcpiBlockPtr = (EFI_ACPI_DESCRIPTION_HEADER*) CurrentTable; Status = FchUpdateAcpiDataTable (FchAcpiProtocol, &FchAcpiBlockPtr); TableHandle = 0; TableSize = FchAcpiBlockPtr->Length; // // Install ACPI table // Status = AcpiTableProtocol->InstallAcpiTable ( AcpiTableProtocol, FchAcpiBlockPtr, TableSize, &TableHandle ); // // Free memory allocated by ReadSection // gBS->FreePool (FchAcpiBlockPtr); if (EFI_ERROR (Status)) { return; } } // // Increment the instance // Instance++; CurrentTable = NULL; } } // // Our exit status is determined by the success of the previous operations // If the protocol was found, Instance already points to it. // // // Free any allocated buffers // gBS->FreePool (HandleBuffer); Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gFchAcpiTableInstallGuid, EFI_NATIVE_INTERFACE, NULL ); if (EFI_ERROR (Status)) { return; } }
VOID EFIAPI FchD3ColdAcpiInstallNotify ( IN EFI_EVENT Event, IN VOID *Context ) { UINTN Index; INTN Instance; UINTN Size; UINTN NumberOfHandles; UINTN TableHandle; UINTN TableSize; UINT32 FvStatus; BOOLEAN HwReducedAcpi; EFI_STATUS Status; EFI_HANDLE *HandleBuffer; EFI_FV_FILETYPE FileType; EFI_FV_FILE_ATTRIBUTES Attributes; EFI_ACPI_COMMON_HEADER *CurrentTable; EFI_ACPI_DESCRIPTION_HEADER *FchD3ColdAcpiBlockPtr = NULL; EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; FCH_ACPI_PROTOCOL *FchAcpiProtocol; FCH_INIT_PROTOCOL *FchInitProtocol; EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol = NULL; EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport = NULL; EFI_ACPI_DESCRIPTION_HEADER *Table; EFI_ACPI_TABLE_VERSION Version; EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt; Status = gBS->LocateProtocol ( &gEfiAcpiTableProtocolGuid, NULL, &AcpiTableProtocol ); if (EFI_ERROR (Status)) { return; } Status = gBS->LocateProtocol ( &gFchAcpiProtocolGuid, NULL, &FchAcpiProtocol ); if (EFI_ERROR (Status)) { return; } Status = gBS->LocateProtocol ( &gFchInitProtocolGuid, NULL, &FchInitProtocol ); if (EFI_ERROR (Status)) { return; } HwReducedAcpi = FchInitProtocol->FchPolicy.Misc.FchCsSupport.FchCsHwReduced; FvStatus = 0; // // Locate protocol. // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiFirmwareVolumeProtocolGuid, NULL, &NumberOfHandles, &HandleBuffer ); if (EFI_ERROR (Status)) { return; } // // Looking for FV with FCH ACPI Data Block file // for (Index = 0; Index < NumberOfHandles; Index++) { // // Get the protocol on this handle // This should not fail because of LocateHandleBuffer // Status = gBS->HandleProtocol ( HandleBuffer[Index], &gEfiFirmwareVolumeProtocolGuid, (VOID**) &FwVol ); ASSERT_EFI_ERROR (Status); // // See if it has the ACPI storage file // Size = 0; FvStatus = 0; Status = FwVol->ReadFile ( FwVol, &gAmdFchD3ColdAcpiGuid, NULL, &Size, &FileType, &Attributes, &FvStatus ); // // If we found it, then we are done // if (Status == EFI_SUCCESS) { break; } } // // Read tables from the storage file. // Instance = 0; CurrentTable = NULL; while (Status == EFI_SUCCESS) { Status = FwVol->ReadSection ( FwVol, &gAmdFchD3ColdAcpiGuid, EFI_SECTION_RAW, Instance, &CurrentTable, &Size, &FvStatus ); if (!EFI_ERROR (Status)) { // // Check the table ID to modify the table // if (((EFI_ACPI_DESCRIPTION_HEADER*) CurrentTable)->OemTableId == EFI_SIGNATURE_64 ('F', 'C', 'H', 'C', 'S', 'D', '3', 0)) { FchD3ColdAcpiBlockPtr = (EFI_ACPI_DESCRIPTION_HEADER*) CurrentTable; Status = FchD3ColdUpdateAcpiTable (FchAcpiProtocol, &FchD3ColdAcpiBlockPtr); TableHandle = 0; TableSize = FchD3ColdAcpiBlockPtr->Length; // // Install ACPI table // Status = AcpiTableProtocol->InstallAcpiTable ( AcpiTableProtocol, FchD3ColdAcpiBlockPtr, TableSize, &TableHandle ); // // Free memory allocated by ReadSection // gBS->FreePool (CurrentTable); if (EFI_ERROR (Status)) { return; } } // // Increment the instance // Instance++; CurrentTable = NULL; } } // // Our exit status is determined by the success of the previous operations // If the protocol was found, Instance already points to it. // // // Free any allocated buffers // gBS->FreePool (HandleBuffer); //set FACP Status = gBS->LocateProtocol ( &gEfiAcpiSupportGuid, NULL, &AcpiSupport ); if (EFI_ERROR (Status)) { return; } // modify FADT to add HW_REDUCED_ACPI and LOW_POWER_S0_IDLE_CAPABLE flag // // Search FADT table // Index = 0; TableHandle = 0; do { Table = NULL; Status = AcpiSupport->GetAcpiTable ( AcpiSupport, Index, &Table, &Version, &TableHandle ); if (EFI_ERROR (Status)) { break; } // // Check Signture and update FADT table // if ((Table->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) && (Table->Revision == 0x05 )) { Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)Table; Fadt->Flags |= LOW_POWER_S0_IDLE_CAPABLE; if (HwReducedAcpi) { Fadt->Flags |= HW_REDUCED_ACPI; } Status = AcpiSupport->SetAcpiTable ( AcpiSupport, Table, TRUE, (EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0 | EFI_ACPI_TABLE_VERSION_4_0 | EFI_ACPI_TABLE_VERSION_5_0), &TableHandle ); } gBS->FreePool (Table); Index++; } while (TRUE); }