/** Initialize and publish TPM items in ACPI table. @retval EFI_SUCCESS The TCG ACPI table is published successfully. @retval Others The TCG ACPI table is not published. **/ EFI_STATUS PublishAcpiTable ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; EFI_ACPI_DESCRIPTION_HEADER *Table; UINTN TableSize; Status = GetSectionFromFv ( &gEfiCallerIdGuid, EFI_SECTION_RAW, 0, (VOID **) &Table, &TableSize ); ASSERT_EFI_ERROR (Status); // // Measure to PCR[0] with event EV_POST_CODE ACPI DATA // TpmMeasureAndLogData( 0, EV_POST_CODE, EV_POSTCODE_INFO_ACPI_DATA, ACPI_DATA_LEN, Table, TableSize ); ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l')); CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId) ); mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS)); ASSERT (mTcgNvs != NULL); // // Publish the TPM ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); TableKey = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
/** Install TCG ACPI Table when ACPI Table Protocol is available. A system's firmware uses an ACPI table to identify the system's TCG capabilities to the Post-Boot environment. The information in this ACPI table is not guaranteed to be valid until the Host Platform transitions from pre-boot state to post-boot state. @param[in] Event Event whose notification function is being invoked @param[in] Context Pointer to the notification function's context **/ VOID EFIAPI InstallAcpiTable ( IN EFI_EVENT Event, IN VOID* Context ) { UINTN TableKey; EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINT8 Checksum; Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable); if (EFI_ERROR (Status)) { return; } if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) { // // The ACPI table must be checksumed before calling the InstallAcpiTable() // service of the ACPI table protocol to install it. // Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate)); mTcgClientAcpiTemplate.Header.Checksum = Checksum; Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate), &TableKey ); } else { // // The ACPI table must be checksumed before calling the InstallAcpiTable() // service of the ACPI table protocol to install it. // Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate)); mTcgServerAcpiTemplate.Header.Checksum = Checksum; Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate), &TableKey ); } ASSERT_EFI_ERROR (Status); }
/** Publish TPM2 ACPI table @retval EFI_SUCCESS The TPM2 ACPI table is published successfully. @retval Others The TPM2 ACPI table is not published. **/ EFI_STATUS PublishTpm2 ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; UINT64 OemTableId; // // Measure to PCR[0] with event EV_POST_CODE ACPI DATA // TpmMeasureAndLogData( 0, EV_POST_CODE, EV_POSTCODE_INFO_ACPI_DATA, ACPI_DATA_LEN, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate) ); CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId)); OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); mTpm2AcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTpm2AcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTpm2AcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); // // Construct ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate), &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
/** Initialize and publish TPM items in ACPI table. @retval EFI_SUCCESS The TCG ACPI table is published successfully. @retval Others The TCG ACPI table is not published. **/ EFI_STATUS PublishAcpiTable ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; EFI_ACPI_DESCRIPTION_HEADER *Table; UINTN TableSize; Status = GetSectionFromFv ( &gEfiCallerIdGuid, EFI_SECTION_RAW, 0, (VOID **) &Table, &TableSize ); ASSERT_EFI_ERROR (Status); ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'c', 'g', 'T', 'a', 'b', 'l', 'e')); mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS)); ASSERT (mTcgNvs != NULL); // // Publish the TPM ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); TableKey = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
STATIC VOID EFIAPI InstallAcpiTable ( IN EFI_EVENT Event, IN VOID* Context ) { UINTN TableKey; EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable); if (EFI_ERROR (Status)) { return; } Status = AcpiTable->InstallAcpiTable (AcpiTable, mSsdt, mSsdtSize, &TableKey); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_WARN, "%a: failed to install SSDT table for eMMC - %r\n", __FUNCTION__, Status)); } }
/** Publish and remove the iSCSI Boot Firmware Table according to the iSCSI session status. **/ VOID IScsiPublishIbft ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINT8 *Heap; UINT8 Checksum; UINTN Index; EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; EFI_ACPI_DESCRIPTION_HEADER *Rsdt; Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol); if (EFI_ERROR (Status)) { return ; } // // Find ACPI table RSD_PTR from system table // for (Index = 0, Rsdp = NULL; Index < gST->NumberOfTableEntries; Index++) { if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi20TableGuid) || CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi10TableGuid) || CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpiTableGuid) ) { // // A match was found. // Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) gST->ConfigurationTable[Index].VendorTable; break; } } if (Rsdp == NULL) { return ; } else { Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress; } if (mIbftInstalled) { Status = AcpiTableProtocol->UninstallAcpiTable ( AcpiTableProtocol, mTableKey ); if (EFI_ERROR (Status)) { return ; } mIbftInstalled = FALSE; } // // Get all iSCSI private protocols. // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiCallerIdGuid, NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR (Status)) { return ; } // // Allocate 4k bytes to hold the ACPI table. // Table = AllocateZeroPool (IBFT_MAX_SIZE); if (Table == NULL) { return ; } Heap = (UINT8 *) Table + IBFT_HEAP_OFFSET; // // Fill in the various section of the iSCSI Boot Firmware Table. // IScsiInitIbfTableHeader (Table, Rsdt->OemId, &Rsdt->OemTableId); IScsiInitControlSection (Table, HandleCount); IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]); IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer); Checksum = CalculateCheckSum8((UINT8 *)Table, Table->Length); Table->Checksum = Checksum; FreePool (HandleBuffer); // // Install or update the iBFT table. // Status = AcpiTableProtocol->InstallAcpiTable ( AcpiTableProtocol, Table, Table->Length, &mTableKey ); if (EFI_ERROR(Status)) { return; } mIbftInstalled = TRUE; FreePool (Table); }
EFI_STATUS AcpiPlatformEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; INTN Instance; EFI_ACPI_COMMON_HEADER *CurrentTable; UINTN TableHandle; UINT32 FvStatus; UINTN Size; EFI_ACPI_TABLE_VERSION Version; QNC_DEVICE_ENABLES QNCDeviceEnables; EFI_HANDLE Handle; UINTN Index; PCI_DEVICE_INFO *PciDeviceInfo; EFI_ACPI_HANDLE PciRootHandle; BOOLEAN UpdatePRT; BOOLEAN UpdatePRW; PCI_DEVICE_SETTING *mConfigData; Instance = 0; TableHandle = 0; CurrentTable = NULL; mConfigData = NULL; QNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables); // // Initialize the EFI Driver Library // ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512); Status = gBS->AllocatePool ( EfiACPIMemoryNVS, sizeof (EFI_GLOBAL_NVS_AREA), (VOID**)&mGlobalNvsArea.Area ); Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gEfiGlobalNvsAreaProtocolGuid, EFI_NATIVE_INTERFACE, &mGlobalNvsArea ); ASSERT_EFI_ERROR (Status); if (!EFI_ERROR (Status)) { SetMem ( mGlobalNvsArea.Area, sizeof (EFI_GLOBAL_NVS_AREA), 0 ); } // // Initialize the data. Eventually, this will be controlled by setup options. // mGlobalNvsArea.Area->HpetEnable = PcdGetBool (PcdHpetEnable); mGlobalNvsArea.Area->Pm1blkIoBaseAddress = PcdGet16(PcdPm1blkIoBaseAddress); mGlobalNvsArea.Area->PmbaIoBaseAddress = PcdGet16(PcdPmbaIoBaseAddress); mGlobalNvsArea.Area->Gpe0blkIoBaseAddress = PcdGet16(PcdGpe0blkIoBaseAddress); mGlobalNvsArea.Area->GbaIoBaseAddress = PcdGet16(PcdGbaIoBaseAddress); mGlobalNvsArea.Area->SmbaIoBaseAddress = PcdGet16(PcdSmbaIoBaseAddress); mGlobalNvsArea.Area->SpiDmaIoBaseAddress = PcdGet16(PcdSpiDmaIoBaseAddress); mGlobalNvsArea.Area->WdtbaIoBaseAddress = PcdGet16(PcdWdtbaIoBaseAddress); mGlobalNvsArea.Area->HpetBaseAddress = (UINT32)PcdGet64(PcdHpetBaseAddress); mGlobalNvsArea.Area->HpetSize = (UINT32)PcdGet64(PcdHpetSize); mGlobalNvsArea.Area->PciExpressBaseAddress= (UINT32)PcdGet64(PcdPciExpressBaseAddress); mGlobalNvsArea.Area->PciExpressSize = (UINT32)PcdGet64(PcdPciExpressSize); mGlobalNvsArea.Area->RcbaMmioBaseAddress = (UINT32)PcdGet64(PcdRcbaMmioBaseAddress); mGlobalNvsArea.Area->RcbaMmioSize = (UINT32)PcdGet64(PcdRcbaMmioSize); mGlobalNvsArea.Area->IoApicBaseAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress); mGlobalNvsArea.Area->IoApicSize = (UINT32)PcdGet64(PcdIoApicSize); mGlobalNvsArea.Area->TpmPresent = (UINT32)(FALSE); // // Find the AcpiTable protocol // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Initialize MADT table // Status = MadtTableInitialize (&CurrentTable, &Size); ASSERT_EFI_ERROR (Status); // // Perform any table specific updates. // AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version); // // Update the check sum // It needs to be zeroed before the checksum calculation // ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0; ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length); // // Add the table // TableHandle = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, CurrentTable, CurrentTable->Length, &TableHandle ); ASSERT_EFI_ERROR (Status); CurrentTable = NULL; // // Init Pci Device PRT PRW information structure from PCD // mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING)); ASSERT_EFI_ERROR (mConfigData); InitPciDeviceInfoStructure (mConfigData); // // Get the Acpi SDT protocol for manipulation on acpi table // Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt); ASSERT_EFI_ERROR (Status); // // Locate the firmware volume protocol // Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Read tables from the storage file. // while (Status == EFI_SUCCESS) { Status = FwVol->ReadSection ( FwVol, (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), EFI_SECTION_RAW, Instance, (VOID**)&CurrentTable, &Size, &FvStatus ); if (!EFI_ERROR(Status)) { // // Perform any table specific updates. // AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version); // // Update the check sum // It needs to be zeroed before the checksum calculation // ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0; ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length); // // Add the table // TableHandle = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, CurrentTable, ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length, &TableHandle ); if (EFI_ERROR(Status)) { return EFI_ABORTED; } // // If this table is the DSDT table, then update the _PRT and _PRW based on // the settings from pcds // if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) { // // Create the root handle for DSDT table // Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle); ASSERT_EFI_ERROR (Status); PciRootHandle = NULL; PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle); ASSERT (PciRootHandle != NULL); PciDeviceInfo = NULL; for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) { PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]); // // Check whether this is a valid item // if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) { //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress)); UpdatePRT = FALSE; UpdatePRW = FALSE; SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW); // // Check whether there is any valid pci routing item // if (UpdatePRT) { // // Update the pci routing information // //DEBUG ((EFI_D_ERROR, "Update _PRT\n")); SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo); } // // Check whether there is any valid pci routing item // if (UpdatePRW) { // // Update the pci wakeup information // //DEBUG ((EFI_D_ERROR, "Update _PRW\n")); SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo); } } } Status = mAcpiSdt->Close (PciRootHandle); ASSERT_EFI_ERROR (Status); // // Mark the root handle as modified , let SDT protocol recaculate the checksum // ((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE; Status = mAcpiSdt->Close (mDsdtHandle); ASSERT_EFI_ERROR (Status); } // // Increment the instance // Instance++; CurrentTable = NULL; } } gBS->FreePool (mConfigData); return EFI_SUCCESS; }
/** Publish and remove the iSCSI Boot Firmware Table according to the iSCSI session status. **/ VOID IScsiPublishIbft ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINT8 *Heap; UINT8 Checksum; EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; EFI_ACPI_DESCRIPTION_HEADER *Rsdt; EFI_ACPI_DESCRIPTION_HEADER *Xsdt; Rsdt = NULL; Xsdt = NULL; Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol); if (EFI_ERROR (Status)) { return ; } // // Find ACPI table RSD_PTR from system table // Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **) &Rsdp); if (EFI_ERROR (Status)) { Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **) &Rsdp); } if (EFI_ERROR (Status) || (Rsdp == NULL)) { return ; } else if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION && Rsdp->XsdtAddress != 0) { Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress; } else if (Rsdp->RsdtAddress != 0) { Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress; } if ((Xsdt == NULL) && (Rsdt == NULL)) { return ; } if (mIbftInstalled) { Status = AcpiTableProtocol->UninstallAcpiTable ( AcpiTableProtocol, mTableKey ); if (EFI_ERROR (Status)) { return ; } mIbftInstalled = FALSE; } // // Get all iSCSI private protocols. // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiCallerIdGuid, NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR (Status)) { return ; } // // Allocate 4k bytes to hold the ACPI table. // Table = AllocateZeroPool (IBFT_MAX_SIZE); if (Table == NULL) { return ; } Heap = (UINT8 *) Table + IBFT_HEAP_OFFSET; // // Fill in the various section of the iSCSI Boot Firmware Table. // if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) { IScsiInitIbfTableHeader (Table, Xsdt->OemId, &Xsdt->OemTableId); } else { IScsiInitIbfTableHeader (Table, Rsdt->OemId, &Rsdt->OemTableId); } IScsiInitControlSection (Table, HandleCount); IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]); IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer); Checksum = CalculateCheckSum8((UINT8 *)Table, Table->Length); Table->Checksum = Checksum; FreePool (HandleBuffer); // // Install or update the iBFT table. // Status = AcpiTableProtocol->InstallAcpiTable ( AcpiTableProtocol, Table, Table->Length, &mTableKey ); if (EFI_ERROR(Status)) { return; } mIbftInstalled = TRUE; FreePool (Table); }
EFI_STATUS PublishAcpiTablesFromFv ( VOID ) { EFI_STATUS Status; EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; EFI_ACPI_COMMON_HEADER *CurrentTable; UINT32 FvStatus; UINTN Size; EFI_ACPI_TABLE_VERSION Version; UINTN TableHandle; INTN Instance; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; Instance = 0; TableHandle = 0; CurrentTable = NULL; FwVol = NULL; // // Find the AcpiTable protocol // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Locate the firmware volume protocol // Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Read tables from the storage file. // while (Status == EFI_SUCCESS) { Status = FwVol->ReadSection ( FwVol, &gEfiCallerIdGuid, EFI_SECTION_RAW, Instance, (VOID**)&CurrentTable, &Size, &FvStatus ); if (!EFI_ERROR(Status)) { // // Perform any table specific updates. // AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version); // // Add the table // TableHandle = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, CurrentTable, ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length, &TableHandle ); if (EFI_ERROR(Status)) { return EFI_ABORTED; } // // Increment the instance // Instance++; CurrentTable = NULL; } } // // Finished // return EFI_SUCCESS; }
/** Entrypoint of Acpi Platform driver. @param ImageHandle @param SystemTable @return EFI_SUCCESS @return EFI_LOAD_ERROR @return EFI_OUT_OF_RESOURCES **/ EFI_STATUS EFIAPI AcpiPlatformEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; INTN Instance; EFI_ACPI_COMMON_HEADER *CurrentTable; UINTN TableHandle; UINT32 FvStatus; UINTN TableSize; UINTN Size; Instance = 0; CurrentTable = NULL; TableHandle = 0; // // Find the AcpiTable protocol // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Locate the firmware volume protocol // Status = LocateFvInstanceWithTables (&FwVol); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // // Read tables from the storage file. // while (Status == EFI_SUCCESS) { Status = FwVol->ReadSection ( FwVol, (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), EFI_SECTION_RAW, Instance, (VOID**) &CurrentTable, &Size, &FvStatus ); if (!EFI_ERROR(Status)) { // // Add the table // TableHandle = 0; TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length; ASSERT (Size >= TableSize); // // Checksum ACPI table // AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize); // // Install ACPI table // Status = AcpiTable->InstallAcpiTable ( AcpiTable, CurrentTable, TableSize, &TableHandle ); // // Free memory allocated by ReadSection // gBS->FreePool (CurrentTable); if (EFI_ERROR(Status)) { return EFI_ABORTED; } // // Increment the instance // Instance++; CurrentTable = NULL; } } // // The driver does not require to be kept loaded. // return EFI_REQUEST_UNLOAD_IMAGE; }
/** Install ACPI Firmware Performance Data Table (FPDT). @return Status code. **/ EFI_STATUS InstallFirmwarePerformanceDataTable ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; UINTN Size; UINT8 *SmmBootRecordCommBuffer; EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader; SMM_BOOT_RECORD_COMMUNICATE *SmmCommData; UINTN CommSize; UINTN BootPerformanceDataSize; UINT8 *BootPerformanceData; EFI_SMM_COMMUNICATION_PROTOCOL *Communication; FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable; // // Get AcpiTable Protocol. // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol); if (EFI_ERROR (Status)) { return Status; } // // Collect boot records from SMM drivers. // SmmBootRecordCommBuffer = NULL; SmmCommData = NULL; Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &Communication); if (!EFI_ERROR (Status)) { // // Initialize communicate buffer // SmmBootRecordCommBuffer = AllocateZeroPool (SMM_BOOT_RECORD_COMM_SIZE); ASSERT (SmmBootRecordCommBuffer != NULL); SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER*)SmmBootRecordCommBuffer; SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)SmmCommBufferHeader->Data; ZeroMem((UINT8*)SmmCommData, sizeof(SMM_BOOT_RECORD_COMMUNICATE)); CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gEfiFirmwarePerformanceGuid); SmmCommBufferHeader->MessageLength = sizeof(SMM_BOOT_RECORD_COMMUNICATE); CommSize = SMM_BOOT_RECORD_COMM_SIZE; // // Get the size of boot records. // SmmCommData->Function = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE; SmmCommData->BootRecordData = NULL; Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); if (!EFI_ERROR (SmmCommData->ReturnStatus) && SmmCommData->BootRecordSize != 0) { // // Get all boot records // SmmCommData->Function = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA; SmmCommData->BootRecordData = AllocateZeroPool(SmmCommData->BootRecordSize); ASSERT (SmmCommData->BootRecordData != NULL); Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(SmmCommData->ReturnStatus); } } // // Prepare memory for Boot Performance table. // Boot Performance table includes BasicBoot record, and one or more appended Boot Records. // BootPerformanceDataSize = sizeof (BOOT_PERFORMANCE_TABLE) + mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize); if (SmmCommData != NULL) { BootPerformanceDataSize += SmmCommData->BootRecordSize; } // // Try to allocate the same runtime buffer as last time boot. // ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable)); Size = sizeof (PerformanceVariable); Status = gRT->GetVariable ( EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, &gEfiFirmwarePerformanceGuid, NULL, &Size, &PerformanceVariable ); if (!EFI_ERROR (Status)) { Status = gBS->AllocatePages ( AllocateAddress, EfiReservedMemoryType, EFI_SIZE_TO_PAGES (BootPerformanceDataSize), &PerformanceVariable.BootPerformanceTablePointer ); if (!EFI_ERROR (Status)) { mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) (UINTN) PerformanceVariable.BootPerformanceTablePointer; } } if (mAcpiBootPerformanceTable == NULL) { // // Fail to allocate at specified address, continue to allocate at any address. // mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) FpdtAllocateReservedMemoryBelow4G (BootPerformanceDataSize); } DEBUG ((EFI_D_INFO, "FPDT: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable)); if (mAcpiBootPerformanceTable == NULL) { if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) { FreePool (SmmCommData->BootRecordData); } if (SmmBootRecordCommBuffer != NULL) { FreePool (SmmBootRecordCommBuffer); } if (mAcpiS3PerformanceTable != NULL) { FreePages (mAcpiS3PerformanceTable, EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE))); } return EFI_OUT_OF_RESOURCES; } // // Prepare Boot Performance Table. // BootPerformanceData = (UINT8 *) mAcpiBootPerformanceTable; // // Fill Basic Boot record to Boot Performance Table. // CopyMem (mAcpiBootPerformanceTable, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate)); BootPerformanceData = BootPerformanceData + mAcpiBootPerformanceTable->Header.Length; // // Fill Boot records from boot drivers. // CopyMem (BootPerformanceData, mBootRecordBuffer, mBootRecordSize); mAcpiBootPerformanceTable->Header.Length += mBootRecordSize; BootPerformanceData = BootPerformanceData + mBootRecordSize; if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) { // // Fill Boot records from SMM drivers. // CopyMem (BootPerformanceData, SmmCommData->BootRecordData, SmmCommData->BootRecordSize); FreePool (SmmCommData->BootRecordData); mAcpiBootPerformanceTable->Header.Length = (UINT32) (mAcpiBootPerformanceTable->Header.Length + SmmCommData->BootRecordSize); BootPerformanceData = BootPerformanceData + SmmCommData->BootRecordSize; } if (SmmBootRecordCommBuffer != NULL) { FreePool (SmmBootRecordCommBuffer); } // // Save Boot Performance Table address to Variable for use in S4 resume. // PerformanceVariable.BootPerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiBootPerformanceTable; // // Update Boot Performance Table Pointer in template. // mFirmwarePerformanceTableTemplate.BootPointerRecord.BootPerformanceTablePointer = (UINT64) (UINTN) mAcpiBootPerformanceTable; // // Save S3 Performance Table address to Variable for use in S4 resume. // PerformanceVariable.S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable; // // Update S3 Performance Table Pointer in template. // mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) (UINTN) mAcpiS3PerformanceTable; // // Save Runtime Performance Table pointers to Variable. // Status = gRT->SetVariable ( EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, &gEfiFirmwarePerformanceGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof (PerformanceVariable), &PerformanceVariable ); ASSERT_EFI_ERROR (Status); // // Publish Firmware Performance Data Table. // FpdtAcpiTableChecksum ((UINT8 *) &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length); Status = AcpiTableProtocol->InstallAcpiTable ( AcpiTableProtocol, &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length, &mFirmwarePerformanceTableTemplateKey ); if (EFI_ERROR (Status)) { FreePages (mAcpiBootPerformanceTable, EFI_SIZE_TO_PAGES (BootPerformanceDataSize)); if (mAcpiS3PerformanceTable != NULL) { FreePages (mAcpiS3PerformanceTable, EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE))); } mAcpiBootPerformanceTable = NULL; mAcpiS3PerformanceTable = NULL; return Status; } // // Free temp Boot record, and update Boot Record to point to Basic Boot performance table. // if (mBootRecordBuffer != NULL) { FreePool (mBootRecordBuffer); } mBootRecordBuffer = (UINT8 *) mAcpiBootPerformanceTable; mBootRecordSize = mAcpiBootPerformanceTable->Header.Length; mBootRecordMaxSize = mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize); return EFI_SUCCESS; }
/** Entrypoint of Acpi Platform driver. @param ImageHandle @param SystemTable @return EFI_SUCCESS @return EFI_LOAD_ERROR @return EFI_OUT_OF_RESOURCES **/ EFI_STATUS EFIAPI AcpiPlatformEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; #ifdef VBOX VOID *VBoxTables[10]; #else EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; #endif INTN Instance; EFI_ACPI_COMMON_HEADER *CurrentTable; UINTN TableHandle; #ifndef VBOX UINT32 FvStatus; #endif UINTN TableSize; UINTN Size; Instance = 0; CurrentTable = NULL; TableHandle = 0; // // Find the AcpiTable protocol // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); if (EFI_ERROR (Status)) { return EFI_ABORTED; } #ifdef VBOX // // VBOX already has tables prepared in memory - just reuse them. // FillSysTablesInfo(VBoxTables, sizeof(VBoxTables)/sizeof(VBoxTables[0])); #else // // // Locate the firmware volume protocol // Status = LocateFvInstanceWithTables (&FwVol); if (EFI_ERROR (Status)) { return EFI_ABORTED; } #endif // // Read tables from the storage file. // while (Status == EFI_SUCCESS) { #ifdef VBOX CurrentTable = (EFI_ACPI_COMMON_HEADER *)VBoxTables[Instance]; Status = (CurrentTable == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS; if (CurrentTable) { Size = CurrentTable->Length; DEBUG((EFI_D_ERROR, "adding %p %d\n", CurrentTable, Size)); } else Size = 0; // Just to shut up the compiler. #else Status = FwVol->ReadSection ( FwVol, (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), EFI_SECTION_RAW, Instance, (VOID**) &CurrentTable, &Size, &FvStatus ); #endif if (!EFI_ERROR(Status)) { // // Add the table // TableHandle = 0; TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length; #ifdef VBOX DEBUG((DEBUG_INFO, "Size:%d, TableSize:%d\n", Size, TableSize)); #endif ASSERT (Size >= TableSize); // // Checksum ACPI table // AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize); // // Install ACPI table // Status = AcpiTable->InstallAcpiTable ( AcpiTable, CurrentTable, TableSize, &TableHandle ); #ifndef VBOX /* In case we're reading ACPI tables from memory we haven't allocated this memory, so it isn't required to free it */ // // Free memory allocated by ReadSection // gBS->FreePool (CurrentTable); if (EFI_ERROR(Status)) { return EFI_ABORTED; } #endif // // Increment the instance // Instance++; CurrentTable = NULL; } } return EFI_SUCCESS; }
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; } }
/** Publish TPM2 ACPI table @retval EFI_SUCCESS The TPM2 ACPI table is published successfully. @retval Others The TPM2 ACPI table is not published. **/ EFI_STATUS PublishTpm2 ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; UINT64 OemTableId; EFI_TPM2_ACPI_CONTROL_AREA *ControlArea; PTP_INTERFACE_TYPE InterfaceType; // // Measure to PCR[0] with event EV_POST_CODE ACPI DATA // TpmMeasureAndLogData( 0, EV_POST_CODE, EV_POSTCODE_INFO_ACPI_DATA, ACPI_DATA_LEN, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate) ); InterfaceType = GetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress)); switch (InterfaceType) { case PtpInterfaceCrb: mTpm2AcpiTemplate.StartMethod = EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE; mTpm2AcpiTemplate.AddressOfControlArea = PcdGet64 (PcdTpmBaseAddress) + 0x40; ControlArea = (EFI_TPM2_ACPI_CONTROL_AREA *)(UINTN)mTpm2AcpiTemplate.AddressOfControlArea; ControlArea->CommandSize = 0xF80; ControlArea->ResponseSize = 0xF80; ControlArea->Command = PcdGet64 (PcdTpmBaseAddress) + 0x80; ControlArea->Response = PcdGet64 (PcdTpmBaseAddress) + 0x80; break; case PtpInterfaceFifo: case PtpInterfaceTis: break; default: DEBUG((EFI_D_ERROR, "TPM2 InterfaceType get error! %d\n", InterfaceType)); break; } CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId)); OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); mTpm2AcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTpm2AcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTpm2AcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); // // Construct ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate), &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
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); }
/** Install TCG ACPI Table when ACPI Table Protocol is available. A system's firmware uses an ACPI table to identify the system's TCG capabilities to the Post-Boot environment. The information in this ACPI table is not guaranteed to be valid until the Host Platform transitions from pre-boot state to post-boot state. @param[in] Event Event whose notification function is being invoked @param[in] Context Pointer to the notification function's context **/ VOID EFIAPI InstallAcpiTable ( IN EFI_EVENT Event, IN VOID* Context ) { UINTN TableKey; EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINT8 Checksum; UINT64 OemTableId; Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable); if (EFI_ERROR (Status)) { return; } if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) { CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId)); OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); mTcgClientAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTcgClientAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTcgClientAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); // // The ACPI table must be checksumed before calling the InstallAcpiTable() // service of the ACPI table protocol to install it. // Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate)); mTcgClientAcpiTemplate.Header.Checksum = Checksum; Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate), &TableKey ); } else { CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId)); OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); mTcgServerAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTcgServerAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTcgServerAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); // // The ACPI table must be checksumed before calling the InstallAcpiTable() // service of the ACPI table protocol to install it. // Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate)); mTcgServerAcpiTemplate.Header.Checksum = Checksum; mTcgServerAcpiTemplate.BaseAddress.Address = PcdGet64 (PcdTpmBaseAddress); Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate), &TableKey ); } if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure")); } }
VOID EFIAPI InvokeAmdInitLate ( IN EFI_EVENT Event, IN VOID *Context ) /*++ Routine Description: Invoke AmdinitLate entry point. This function gets called each time the EFI_EVENT_SIGNAL_READY_TO_BOOT gets signaled Arguments & Return Values: Standard event handling function prototype --*/ { AMD_INTERFACE_PARAMS AmdInterfaceParams; AGESA_STATUS AgesaStatus; AMD_DXE_INIT_LATE_PROTOCOL AmdInitLateProtocol; AMD_AGESA_DXE_PROTOCOL *AmdAgesaDxe; EFI_HANDLE Handle; UINTN TableBufferLength; UINT8 *TableBufferPtr; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; EFI_STATUS Status; // // Prepare for AmdInitLate // ZeroMem (&AmdInterfaceParams, sizeof (AMD_INTERFACE_PARAMS)); AmdInterfaceParams.StdHeader.ImageBasePtr = 0; AmdInterfaceParams.StdHeader.HeapStatus = HEAP_SYSTEM_MEM; AmdInterfaceParams.AllocationMethod = PostMemDram; AmdInterfaceParams.AgesaFunctionName = AMD_INIT_LATE; AgesaStatus = AmdCreateStruct (&AmdInterfaceParams); ((AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr)->StdHeader = AmdInterfaceParams.StdHeader; OemCustomizeInitLate (gBS, (AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr); AgesaStatus = AmdInitLate ((AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr); OemHookAfterInitLate (gBS, (AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr); if ((AgesaStatus == AGESA_CRITICAL) || (AgesaStatus == AGESA_FATAL)) { return; } mAgesaDxePrivate->LateParamsPtr = (AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr; // // Now Install the AmdDxeInitLateProtocol which helps notify any consumer // which is depending upon it. // AmdInitLateProtocol.Revision = AGESA_DXE_INIT_LATE_REV; Handle = NULL; gBS->InstallProtocolInterface ( &Handle, &gAmdDxeInitLateProtocolGuid, EFI_NATIVE_INTERFACE, &AmdInitLateProtocol ); // // Install the AMD_AGESA_DXE_PROTOCOL to notify OEM to override default value // Handle = NULL; gBS->InstallProtocolInterface ( &Handle, &gAmdAgesaDxeProtocolGuid, EFI_NATIVE_INTERFACE, &mAgesaDxePrivate->CpuInterface ); //Publish ACPI TABLES. (UINT8*)TableBufferPtr = NULL; TableKey = NULL; AcpiTable = NULL; AmdAgesaDxe = NULL; //By default PCD is set to FALSE. Before Enabling PCD make sure to disable publishing of ACPI Tables by IBVs to avoid conflict. if (PcdGetBool (PcdPublishAgesaAcpiTable)) { Status = gBS->LocateProtocol ( &gAcpiTableProtocolGuid, NULL, &AcpiTable ); ASSERT_EFI_ERROR (Status); //-PSTATE TableBufferLength = 0; mAgesaDxePrivate->CpuInterface.CreateProcessorTables (AmdAgesaDxe, AcpiPstateType, &TableBufferLength, &TableBufferPtr); //First get the buffer size needed for the table. if (TableBufferLength != 0 ) { TableBufferPtr = AllocateZeroPool (TableBufferLength); mAgesaDxePrivate->CpuInterface.CreateProcessorTables (AmdAgesaDxe, AcpiPstateType, &TableBufferLength, &TableBufferPtr); Status = AcpiTable->InstallAcpiTable (AcpiTable, TableBufferPtr, TableBufferLength, &TableKey); FreePool (TableBufferPtr); } //-Crat TableBufferLength = 0; mAgesaDxePrivate->CpuInterface.CreateProcessorTables (AmdAgesaDxe, AcpiCratType, &TableBufferLength, &TableBufferPtr); //First get the buffer size needed for the table. if (TableBufferLength != 0 ) { TableBufferPtr = AllocateZeroPool (TableBufferLength); mAgesaDxePrivate->CpuInterface.CreateProcessorTables (AmdAgesaDxe, AcpiCratType, &TableBufferLength, &TableBufferPtr); Status = AcpiTable->InstallAcpiTable (AcpiTable, TableBufferPtr, TableBufferLength, &TableKey); FreePool (TableBufferPtr); } //-Cdit TableBufferLength = 0; mAgesaDxePrivate->CpuInterface.CreateProcessorTables (AmdAgesaDxe, AcpiCditType, &TableBufferLength, &TableBufferPtr); //First get the buffer size needed for the table. if (TableBufferLength != 0 ) { TableBufferPtr = AllocateZeroPool (TableBufferLength); mAgesaDxePrivate->CpuInterface.CreateProcessorTables (AmdAgesaDxe, AcpiCditType, &TableBufferLength, &TableBufferPtr); Status = AcpiTable->InstallAcpiTable (AcpiTable, TableBufferPtr, TableBufferLength, &TableKey); FreePool (TableBufferPtr); } } return; }
/** Entrypoint of Acpi Platform driver. @param ImageHandle @param SystemTable @return EFI_SUCCESS @return EFI_LOAD_ERROR @return EFI_OUT_OF_RESOURCES **/ EFI_STATUS EFIAPI AcpiPlatformEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; // INTN Instance; // EFI_ACPI_COMMON_HEADER *CurrentTable; EFI_ACPI_COMMON_HEADER *oldDSDT; UINTN TableHandle; UINTN TableSize; // UINTN Size; #if READTABLES UINTN Index; CHAR16* FileName; #if LIP EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; #endif VOID *FileBuffer; // VOID** TmpHandler; UINT64 FileSize; UINTN BufferSize; // UINTN Key; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_FILE_INFO *Info; EFI_FILE_HANDLE Root = NULL; EFI_FILE_HANDLE ThisFile = NULL; #endif EFI_PHYSICAL_ADDRESS *Acpi20; EFI_PEI_HOB_POINTERS GuidHob; EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; // EFI_ACPI_DESCRIPTION_HEADER *Rsdt, *Xsdt; // EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt; EFI_ACPI_DESCRIPTION_HEADER *Table; SIGNAT Signature; // EFI_ACPI_TABLE_INSTANCE *AcpiInstance; Msg = NULL; Status = gBS->LocateProtocol(&gMsgLogProtocolGuid, NULL, (VOID **) &Msg); if (!EFI_ERROR(Status) && (Msg != NULL)) { msgCursor = Msg->Cursor; BootLog("MsgLog Protocol installed in AcpiPlatform\n"); } // // Find the AcpiTable protocol // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); if (EFI_ERROR (Status)) { return EFI_ABORTED; } #if DEBUG_ACPI AcpiInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS(AcpiTable); DBG(L"Rsdp1 %x\n", AcpiInstance->Rsdp1); DBG(L"Rsdp3 %x\n", AcpiInstance->Rsdp3); DBG(L"Rsdt1 %x\n", AcpiInstance->Rsdt1); DBG(L"Rsdt3 %x\n", AcpiInstance->Rsdt3); DBG(L"Xsdt %x\n", AcpiInstance->Xsdt); DBG(L"Fadt1 %x\n", AcpiInstance->Fadt1); DBG(L"Fadt3 %x\n", AcpiInstance->Fadt3); #endif // Instance = 0; // CurrentTable = NULL; TableHandle = 0; GuidHob.Raw = GetFirstGuidHob (&gEfiAcpiTableGuid); if (GuidHob.Raw == NULL) { GuidHob.Raw = GetFirstGuidHob (&gEfiAcpi10TableGuid); if (GuidHob.Raw == NULL) { return EFI_ABORTED; } //Slice: TODO if we found only Acpi1.0 we need to convert it to Acpi2.0 // like I did in Chameleon } Acpi20 = GET_GUID_HOB_DATA (GuidHob.Guid); if (Acpi20 == NULL) { return EFI_ABORTED; } Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)*Acpi20; DBG(L"Rsdp @ %x\n", (UINTN)Rsdp); DBG(L"Rsdt @ %x\n", (UINTN)(Rsdp->RsdtAddress)); DBG(L"Xsdt @ %x\n", (UINTN)(Rsdp->XsdtAddress)); InstallLegacyTables(AcpiTable, Rsdp); // DBG(L"LegacyTables installed\n"); oldDSDT = (EFI_ACPI_COMMON_HEADER*)(UINTN)Fadt->Dsdt; DBG(L"Fadt @ %x\n", (UINTN)Fadt); DBG(L"oldDSDT @ %x\n", (UINTN)oldDSDT); #if READTABLES #if LIP // Looking for a volume from what we boot /* TODO - look for a volume we want to boot System it is possible if we fix in BdsBoot.c gRT->SetVariable ( L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof (UINT16), &Option->BootCurrent ); gRT->GetVariable ( L"BootNext", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, &BootNext ); and extract DevicePath from BootNext - first available :( In Gui.efi we can repeat this patch with DSDT.aml loaded from another place */ Status = gBS->HandleProtocol ( ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID*)&LoadedImage ); if (EFI_ERROR (Status)) { return EFI_ABORTED; } Status = gBS->HandleProtocol ( LoadedImage->DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID *) &Volume ); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // DBG(L"Volume found\n"); // // Open the root directory of the volume // if (!EFI_ERROR (Status)) { Status = Volume->OpenVolume (Volume, &Root); } #else //Multiple FS protocols EFI_HANDLE *mFs = NULL; UINTN mFsCount = 0; // mFsInfo[] array entries must match mFs[] handles EFI_FILE_SYSTEM_INFO **mFsInfo = NULL; gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &mFsCount, &mFs); mFsInfo = AllocateZeroPool (mFsCount * sizeof (EFI_FILE_SYSTEM_INFO *)); if (mFsInfo == NULL) { // If we can't do this then we can't support file system entries mFsCount = 0; } else { // Loop through all the file system structures and cache the file system info data for (Index =0; Index < mFsCount; Index++) { Status = gBS->HandleProtocol (mFs[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Volume); if (!EFI_ERROR (Status)) { Status = Volume->OpenVolume (Volume, &Root); if (!EFI_ERROR (Status)) { // Get information about the volume /* Size = 0; Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]); if (Status == EFI_BUFFER_TOO_SMALL) { mFsInfo[Index] = AllocatePool (Size); Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]); } */ // Root->Close (Root); break; //I will stop at first volume //TODO try to find DSDT in all volumes } } } } #endif FileName = AllocateZeroPool(32); //Should be enough // // Read tables from the first volume. // for (Index=0; Index<NUM_TABLES; Index++) { StrCpyS(FileName, 32, ACPInames[Index]); // DBG(L"File probe %s\n", FileName); Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { continue; } /* Get right size we need to allocate */ Status = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { continue; } DBG(L"Buffer size %d\n", BufferSize); // DBG(L"GetInfo success!\n"); Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info); if (EFI_ERROR (Status)) { // DBG(L"No pool!\n"); continue; } Status = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); FileSize = Info->FileSize; // DBG(L"FileSize = %d!\n", FileSize); gBS->FreePool (Info); //Slice - this is the problem. // FileBuffer = AllocatePool(FileSize); Status = gBS->AllocatePool (EfiBootServicesData, FileSize, (VOID **) &FileBuffer); if (EFI_ERROR (Status)) { // DBG(L"No pool for FileBuffer size %d!\n", FileSize); continue; } /* Status = gBS->AllocatePages ( AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES(FileSize), FileBuffer ); if (EFI_ERROR (Status)) { // DBG(L"No pool for FileBuffer size %d!\n", FileSize); continue; } */ //should use ACPI memory // Status=gBS->AllocatePages(AllocateMaxAddress, // EfiACPIReclaimMemory,RoundPage(FileSize)/EFI_PAGE_SIZE, FileBuffer); DBG(L"FileBuffer @ %x\n", (UINTN)FileBuffer); Status = ThisFile->Read (ThisFile, &FileSize, FileBuffer); //(VOID**)& // DBG(L"FileRead status=%x\n", Status); if (!EFI_ERROR(Status)) { // // Add the table // // TableHandle = 0; if (ThisFile != NULL) { ThisFile->Close (ThisFile); //close file before use buffer?! Flush?! } // DBG(L"FileRead success: %c%c%c%c\n", // ((CHAR8*)FileBuffer)[0], ((CHAR8*)FileBuffer)[1], ((CHAR8*)FileBuffer)[2], ((CHAR8*)FileBuffer)[3]); TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) FileBuffer)->Length; //ASSERT (BufferSize >= TableSize); DBG(L"Table size=%d\n", TableSize); if (FileSize < TableSize) { //Data incorrect. What TODO? Quick fix // ((EFI_ACPI_DESCRIPTION_HEADER *) FileBuffer)->Length = FileSize; // TableSize = FileSize; DBG(L"Table size > file size :(\n"); continue; //do nothing with broken table } // // Checksum ACPI table // AcpiPlatformChecksum ((UINT8*)FileBuffer, TableSize); if ((Index==0) && oldDSDT) { //DSDT always at index 0 if (((EFI_ACPI_DESCRIPTION_HEADER *) oldDSDT)->Length > TableSize) { CopyMem(oldDSDT, FileBuffer, TableSize); DBG(L"New DSDT copied to old place\n"); } } // // Install ACPI table // //TmpHandler = &FileBuffer; Status = AcpiTable->InstallAcpiTable ( AcpiTable, FileBuffer, TableSize, &TableHandle ); DBG(L"Table install status=%x\n", Status); if (EFI_ERROR(Status)) { continue; } // DBG(L"Table installed #%d\n", Index); // // Increment the instance // // Instance++; //for a what? FileBuffer = NULL; } else if (oldDSDT && (Index==0)) { //if new DSDT not found then install legacy one Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(Fadt->Dsdt)); TableSize = Table->Length; Signature.Sign = Table->Signature; DBG(L"Install legacy table: %c%c%c%c\n", Signature.ASign[0], Signature.ASign[1], Signature.ASign[2], Signature.ASign[3]); Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableHandle ); } } if (Root != NULL) { Root->Close (Root); } #else //just install legacy tables if (oldDSDT) { //if new DSDT not found then install legacy one Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(Fadt->Dsdt)); TableSize = Table->Length; Signature.Sign = Table->Signature; DBG(L"Install legacy table: %c%c%c%c\n", Signature.ASign[0], Signature.ASign[1], Signature.ASign[2], Signature.ASign[3]); /*Status = */AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableHandle ); } #endif #if DEBUG_ACPI==2 gBS->Stall(5000000); #endif return EFI_SUCCESS; }