/** Entry point for Acpi platform driver. @param[in] ImageHandle A handle for the image that is initializing this driver. @param[in] SystemTable A pointer to the EFI system table. @retval EFI_SUCCESS Driver initialized successfully. @retval EFI_LOAD_ERROR Failed to Initialize or has been loaded. @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. **/ EFI_STATUS EFIAPI AcpiPlatformEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_STATUS AcpiStatus; EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol; INTN Instance; EFI_ACPI_COMMON_HEADER *CurrentTable; UINTN TableHandle; UINT32 FvStatus; UINT32 Size; EFI_EVENT Event; EFI_ACPI_TABLE_VERSION TableVersion; UINTN VarSize; UINTN SysCfgSize; EFI_HANDLE Handle; EFI_PS2_POLICY_PROTOCOL *Ps2Policy; EFI_PEI_HOB_POINTERS GuidHob; UINT8 PortData; EFI_MP_SERVICES_PROTOCOL *MpService; UINTN MaximumNumberOfCPUs; UINTN NumberOfEnabledCPUs; UINT32 Data32; PCH_STEPPING pchStepping; mFirstNotify = FALSE; TableVersion = EFI_ACPI_TABLE_VERSION_2_0; Instance = 0; CurrentTable = NULL; TableHandle = 0; Data32 = 0; // // Update HOB variable for PCI resource information. // Get the HOB list. If it is not present, then ASSERT. // GuidHob.Raw = GetHobList (); if (GuidHob.Raw != NULL) { if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) { mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid); } } // // Search for the Memory Configuration GUID HOB. If it is not present, then // there's nothing we can do. It may not exist on the update path. // VarSize = sizeof(SYSTEM_CONFIGURATION); Status = gRT->GetVariable( L"Setup", &mSystemConfigurationGuid, NULL, &VarSize, &mSystemConfiguration ); ASSERT_EFI_ERROR (Status); // // Find the AcpiSupport protocol. // Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0); ASSERT_EFI_ERROR (Status); // // Locate the firmware volume protocol. // Status = LocateSupportProtocol (&gEfiFirmwareVolumeProtocolGuid, (VOID **) &FwVol, 1); ASSERT_EFI_ERROR (Status); // // Read the current system configuration variable store. // SysCfgSize = sizeof(SYSTEM_CONFIGURATION); Status = gRT->GetVariable ( L"Setup", &gEfiNormalSetupGuid, NULL, &SysCfgSize, &mSystemConfig ); Status = EFI_SUCCESS; Instance = 0; // // TBD: Need re-design based on the ValleyTrail platform. // Status = gBS->LocateProtocol ( &gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpService ); if (EFI_ERROR (Status)) { return Status; } // // Determine the number of processors. // MpService->GetNumberOfProcessors ( MpService, &MaximumNumberOfCPUs, &NumberOfEnabledCPUs ); // // Allocate and initialize the NVS area for SMM and ASL communication. // Status = gBS->AllocatePool ( EfiACPIMemoryNVS, sizeof (EFI_GLOBAL_NVS_AREA), (void **)&mGlobalNvsArea.Area ); ASSERT_EFI_ERROR (Status); gBS->SetMem ( mGlobalNvsArea.Area, sizeof (EFI_GLOBAL_NVS_AREA), 0 ); DEBUG((EFI_D_ERROR, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea.Area)); // // Update global NVS area for ASL and SMM init code to use. // mGlobalNvsArea.Area->ApicEnable = 1; mGlobalNvsArea.Area->EmaEnable = 0; mGlobalNvsArea.Area->NumberOfBatteries = 1; mGlobalNvsArea.Area->BatteryCapacity0 = 100; mGlobalNvsArea.Area->BatteryStatus0 = 84; mGlobalNvsArea.Area->OnboardCom = 1; mGlobalNvsArea.Area->IdeMode = 0; mGlobalNvsArea.Area->PowerState = 0; mGlobalNvsArea.Area->LogicalProcessorCount = (UINT8)NumberOfEnabledCPUs; mGlobalNvsArea.Area->PassiveThermalTripPoint = mSystemConfiguration.PassiveThermalTripPoint; mGlobalNvsArea.Area->PassiveTc1Value = mSystemConfiguration.PassiveTc1Value; mGlobalNvsArea.Area->PassiveTc2Value = mSystemConfiguration.PassiveTc2Value; mGlobalNvsArea.Area->PassiveTspValue = mSystemConfiguration.PassiveTspValue; mGlobalNvsArea.Area->CriticalThermalTripPoint = mSystemConfiguration.CriticalThermalTripPoint; mGlobalNvsArea.Area->IgdPanelType = mSystemConfiguration.IgdFlatPanel; mGlobalNvsArea.Area->IgdPanelScaling = mSystemConfiguration.PanelScaling; mGlobalNvsArea.Area->IgdSciSmiMode = 0; mGlobalNvsArea.Area->IgdTvFormat = 0; mGlobalNvsArea.Area->IgdTvMinor = 0; mGlobalNvsArea.Area->IgdSscConfig = 1; mGlobalNvsArea.Area->IgdBiaConfig = mSystemConfiguration.IgdLcdIBia; mGlobalNvsArea.Area->IgdBlcConfig = mSystemConfiguration.IgdLcdIGmchBlc; mGlobalNvsArea.Area->IgdDvmtMemSize = mSystemConfiguration.IgdDvmt50TotalAlloc; mGlobalNvsArea.Area->IgdPAVP = mSystemConfiguration.PavpMode; mGlobalNvsArea.Area->AlsEnable = mSystemConfiguration.AlsEnable; mGlobalNvsArea.Area->BacklightControlSupport = 2; mGlobalNvsArea.Area->BrightnessPercentage = 100; mGlobalNvsArea.Area->IgdState = 1; mGlobalNvsArea.Area->LidState = 1; mGlobalNvsArea.Area->DeviceId1 = 0x80000100 ; mGlobalNvsArea.Area->DeviceId2 = 0x80000400 ; mGlobalNvsArea.Area->DeviceId3 = 0x80000200 ; mGlobalNvsArea.Area->DeviceId4 = 0x04; mGlobalNvsArea.Area->DeviceId5 = 0x05; mGlobalNvsArea.Area->NumberOfValidDeviceId = 4 ; mGlobalNvsArea.Area->CurrentDeviceList = 0x0F ; mGlobalNvsArea.Area->PreviousDeviceList = 0x0F ; mGlobalNvsArea.Area->UartSelection = mSystemConfiguration.UartInterface; mGlobalNvsArea.Area->PcuUart1Enable = mSystemConfiguration.PcuUart1; mGlobalNvsArea.Area->NativePCIESupport = 1; // // Update BootMode: 0:ACPI mode; 1:PCI mode // mGlobalNvsArea.Area->LpssSccMode = mSystemConfiguration.LpssPciModeEnabled; if (mSystemConfiguration.LpssMipiHsi == 0) { mGlobalNvsArea.Area->MipiHsiAddr = 0; mGlobalNvsArea.Area->MipiHsiLen = 0; mGlobalNvsArea.Area->MipiHsi1Addr = 0; mGlobalNvsArea.Area->MipiHsi1Len = 0; } // // Platform Flavor // mGlobalNvsArea.Area->PlatformFlavor = mPlatformInfo->PlatformFlavor; // // Update the Platform id // mGlobalNvsArea.Area->BoardID = mPlatformInfo->BoardId; // // Update the Board Revision // mGlobalNvsArea.Area->FabID = mPlatformInfo->BoardRev; // // Update SOC Stepping // mGlobalNvsArea.Area->SocStepping = (UINT8)(PchStepping()); mGlobalNvsArea.Area->OtgMode = mSystemConfiguration.PchUsbOtg; pchStepping = PchStepping(); if (mSystemConfiguration.UsbAutoMode == 1) { // // Auto mode is enabled. // if (PchA0 == pchStepping) { // // For A0, EHCI is enabled as default. // mSystemConfiguration.PchUsb20 = 1; mSystemConfiguration.PchUsb30Mode = 0; mSystemConfiguration.UsbXhciSupport = 0; DEBUG ((EFI_D_INFO, "EHCI is enabled as default. SOC 0x%x\n", pchStepping)); } else { // // For A1 and later, XHCI is enabled as default. // mSystemConfiguration.PchUsb20 = 0; mSystemConfiguration.PchUsb30Mode = 1; mSystemConfiguration.UsbXhciSupport = 1; DEBUG ((EFI_D_INFO, "XHCI is enabled as default. SOC 0x%x\n", pchStepping)); } } mGlobalNvsArea.Area->XhciMode = mSystemConfiguration.PchUsb30Mode; mGlobalNvsArea.Area->Stepping = mPlatformInfo->IchRevision; // // Override invalid Pre-Boot Driver and XhciMode combination. // if ((mSystemConfiguration.UsbXhciSupport == 0) && (mSystemConfiguration.PchUsb30Mode == 3)) { mGlobalNvsArea.Area->XhciMode = 2; } if ((mSystemConfiguration.UsbXhciSupport == 1) && (mSystemConfiguration.PchUsb30Mode == 2)) { mGlobalNvsArea.Area->XhciMode = 3; } DEBUG ((EFI_D_ERROR, "ACPI NVS XHCI:0x%x\n", mGlobalNvsArea.Area->XhciMode)); mGlobalNvsArea.Area->PmicEnable = GLOBAL_NVS_DEVICE_DISABLE; mGlobalNvsArea.Area->BatteryChargingSolution = GLOBAL_NVS_DEVICE_DISABLE; mGlobalNvsArea.Area->ISPDevSel = mSystemConfiguration.ISPDevSel; mGlobalNvsArea.Area->LpeEnable = mSystemConfiguration.Lpe; if (mSystemConfiguration.ISPEn == 0) { mGlobalNvsArea.Area->ISPDevSel = GLOBAL_NVS_DEVICE_DISABLE; } mGlobalNvsArea.Area->WittEnable = mSystemConfiguration.WittEnable; mGlobalNvsArea.Area->UtsEnable = mSystemConfiguration.UtsEnable; mGlobalNvsArea.Area->SarEnable = mSystemConfiguration.SAR1; mGlobalNvsArea.Area->ReservedO = 1; SettingI2CTouchAddress(); mGlobalNvsArea.Area->IdleReserve= mSystemConfiguration.IdleReserve; // // Read BMBOUND and store it in GlobalNVS to pass into ASL. // // BUGBUG: code was moved into silicon reference code. // if (mSystemConfiguration.eMMCBootMode== 1) { // // Auto detect mode. // DEBUG ((EFI_D_ERROR, "Auto detect mode------------start\n")); // // Silicon Steppings. // switch (PchStepping()) { case PchA0: // A0/A1 case PchA1: DEBUG ((EFI_D_ERROR, "SOC A0/A1: eMMC 4.41 Configuration\n")); mSystemConfiguration.LpsseMMCEnabled = 1; mSystemConfiguration.LpsseMMC45Enabled = 0; break; case PchB0: // B0 and later. default: DEBUG ((EFI_D_ERROR, "SOC B0 and later: eMMC 4.5 Configuration\n")); mSystemConfiguration.LpsseMMCEnabled = 0; mSystemConfiguration.LpsseMMC45Enabled = 1; break; } } else if (mSystemConfiguration.eMMCBootMode == 2) { // // eMMC 4.41 // DEBUG ((EFI_D_ERROR, "Force to eMMC 4.41 Configuration\n")); mSystemConfiguration.LpsseMMCEnabled = 1; mSystemConfiguration.LpsseMMC45Enabled = 0; } else if (mSystemConfiguration.eMMCBootMode == 3) { // // eMMC 4.5 // DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 Configuration\n")); mSystemConfiguration.LpsseMMCEnabled = 0; mSystemConfiguration.LpsseMMC45Enabled = 1; } else { // // Disable eMMC controllers. // DEBUG ((EFI_D_ERROR, "Disable eMMC controllers\n")); mSystemConfiguration.LpsseMMCEnabled = 0; mSystemConfiguration.LpsseMMC45Enabled = 0; } mGlobalNvsArea.Area->emmcVersion = 0; if (mSystemConfiguration.LpsseMMCEnabled) { DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 0\n")); mGlobalNvsArea.Area->emmcVersion = 0; } if (mSystemConfiguration.LpsseMMC45Enabled) { DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 1\n")); mGlobalNvsArea.Area->emmcVersion = 1; } mGlobalNvsArea.Area->SdCardRemovable = mSystemConfiguration.SdCardRemovable; // // Microsoft IOT // if ((mSystemConfiguration.LpssHsuart0FlowControlEnabled == 1) && \ (mSystemConfiguration.LpssPwm0Enabled == 0) && \ (mSystemConfiguration.LpssPwm1Enabled == 0)) { mGlobalNvsArea.Area->MicrosoftIoT = GLOBAL_NVS_DEVICE_ENABLE; DEBUG ((EFI_D_ERROR, "JP1 is set to be MSFT IOT configuration.\n")); } else { mGlobalNvsArea.Area->MicrosoftIoT = GLOBAL_NVS_DEVICE_DISABLE; DEBUG ((EFI_D_ERROR, "JP1 is not set to be MSFT IOT configuration.\n")); } // // SIO related option. // Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (void **)&mCpuIo); ASSERT_EFI_ERROR (Status); mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_DISABLE; mGlobalNvsArea.Area->DockedSioPresent = GLOBAL_NVS_DEVICE_DISABLE; if (mGlobalNvsArea.Area->DockedSioPresent != GLOBAL_NVS_DEVICE_ENABLE) { // // Check ID for SIO WPCN381U. // Status = mCpuIo->Io.Read ( mCpuIo, EfiCpuIoWidthUint8, WPCN381U_CONFIG_INDEX, 1, &PortData ); ASSERT_EFI_ERROR (Status); if (PortData != 0xFF) { PortData = 0x20; Status = mCpuIo->Io.Write ( mCpuIo, EfiCpuIoWidthUint8, WPCN381U_CONFIG_INDEX, 1, &PortData ); ASSERT_EFI_ERROR (Status); Status = mCpuIo->Io.Read ( mCpuIo, EfiCpuIoWidthUint8, WPCN381U_CONFIG_DATA, 1, &PortData ); ASSERT_EFI_ERROR (Status); if ((PortData == WPCN381U_CHIP_ID) || (PortData == WDCP376_CHIP_ID)) { mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_ENABLE; mGlobalNvsArea.Area->OnboardCom = GLOBAL_NVS_DEVICE_ENABLE; mGlobalNvsArea.Area->OnboardComCir = GLOBAL_NVS_DEVICE_DISABLE; } } } // // Get Ps2 policy to set. Will be use if present. // Status = gBS->LocateProtocol ( &gEfiPs2PolicyProtocolGuid, NULL, (VOID **)&Ps2Policy ); if (!EFI_ERROR (Status)) { Status = Ps2Policy->Ps2InitHardware (ImageHandle); } mGlobalNvsArea.Area->SDIOMode = mSystemConfiguration.LpssSdioMode; Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiGlobalNvsAreaProtocolGuid, &mGlobalNvsArea, NULL ); // // Read tables from the storage file. // while (!EFI_ERROR (Status)) { CurrentTable = NULL; Status = FwVol->ReadSection ( FwVol, &gEfiAcpiTableStorageGuid, EFI_SECTION_RAW, Instance, (VOID **) &CurrentTable, (UINTN *) &Size, &FvStatus ); if (!EFI_ERROR (Status)) { // // Allow platform specific code to reject the table or update it. // AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable); if (!EFI_ERROR (AcpiStatus)) { // // Perform any table specific updates. // AcpiStatus = PlatformUpdateTables (CurrentTable); if (!EFI_ERROR (AcpiStatus)) { // // Add the table. // TableHandle = 0; AcpiStatus = AcpiSupport->SetAcpiTable ( AcpiSupport, CurrentTable, TRUE, TableVersion, &TableHandle ); ASSERT_EFI_ERROR (AcpiStatus); } } // // Increment the instance. // Instance++; } } Status = EfiCreateEventReadyToBootEx ( TPL_NOTIFY, OnReadyToBoot, NULL, &Event ); // // Finished. // return EFI_SUCCESS; }
VOID EFIAPI fTPMAcpiEvent ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; UINTN TableHandle; TPM2_CONTROL_AREA *Tpm2ControlArea; UINT8 *Tpm2AcpiDataPtr; UINT32 *Memory32Fixed; EFI_ACPI_TABLE_VERSION Version; EFI_PHYSICAL_ADDRESS PspBar1Addr; gBS->CloseEvent (Event); // // Locate ACPISupport table. Bail if absent // Status = gBS->LocateProtocol ( &gEfiAcpiSupportGuid, NULL, &AcpiSupport); if (EFI_ERROR (Status)) { return; } if (GetPspBar1Addr (&PspBar1Addr)) { return; } Tpm2ControlArea = (TPM2_CONTROL_AREA *) (UINTN) PspBar1Addr; // Update the TPM ACPI Table for ControlArea location Tpm2AcpiTable.ControlArea = (EFI_PHYSICAL_ADDRESS) Tpm2ControlArea + 0x10; // // Install the ACPI Table // PSP_DEBUG ("\tInstall ACPI TPM2 Table\n"); TableHandle = 0; //(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) Version = 0x3E; Status = AcpiSupport->SetAcpiTable ( AcpiSupport, &Tpm2AcpiTable, TRUE, Version, &TableHandle ); if (EFI_ERROR (Status)) { return; } PSP_DEBUG ("\tUpdate _CRS Object with actual value\n"); //Update _CRS Object with actual value for (Tpm2AcpiDataPtr = ((UINT8 *)fTPMAmlData + sizeof (EFI_ACPI_DESCRIPTION_HEADER)); Tpm2AcpiDataPtr <= ((UINT8 *)fTPMAmlData + ((EFI_ACPI_DESCRIPTION_HEADER *)fTPMAmlData)->Length); Tpm2AcpiDataPtr++ ) { Memory32Fixed = (UINT32 *)Tpm2AcpiDataPtr; switch (*Memory32Fixed) { //TPM2.0 Command Buffer allocate by BIOS, should be updated during POST //Memory32Fixed (ReadWrite, 0xBBBBBBBB, 0x100000) case 0xBBBBBBBB: *Memory32Fixed = (UINT32) (Tpm2ControlArea->CommandAddress); PSP_DEBUG ("Tpm2ControlArea->CommandAddress %x\n", Tpm2ControlArea->CommandAddress); Tpm2AcpiDataPtr += (sizeof (UINT32) - 1); break; //TPM2.0 Response Buffer allocate by BIOS, should be updated during POST //Memory32Fixed (ReadWrite, 0xCCCCCCCC, 0x100000) case 0xCCCCCCCC: *Memory32Fixed = (UINT32) (Tpm2ControlArea->ResponseAddress); PSP_DEBUG ("Tpm2ControlArea->ResponseAddress %x\n", Tpm2ControlArea->ResponseAddress); Tpm2AcpiDataPtr += (sizeof (UINT32) - 1); break; default: break; } } PSP_DEBUG ("\tInstall Tpm SSDT table\n"); TableHandle = 0; AcpiSupport->SetAcpiTable ( AcpiSupport, fTPMAmlData, TRUE, Version, &TableHandle ); if (EFI_ERROR (Status)) { return; } PSP_DEBUG ("PublishTables ACPI table\n"); Status = AcpiSupport->PublishTables (AcpiSupport, Version); if (EFI_ERROR (Status)) { return; } PSP_DEBUG ("fTPMAcpiEvent exit\n"); }
/** Routine Description: GC_TODO: Add function description. Arguments: Event - GC_TODO: add argument description Context - GC_TODO: add argument description Returns: GC_TODO: add return values **/ STATIC VOID EFIAPI OnReadyToBoot ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; EFI_ACPI_TABLE_VERSION TableVersion; EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save; SYSTEM_CONFIGURATION SetupVarBuffer; UINTN VariableSize; EFI_PLATFORM_CPU_INFO *PlatformCpuInfoPtr = NULL; EFI_PLATFORM_CPU_INFO PlatformCpuInfo; EFI_PEI_HOB_POINTERS GuidHob; if (mFirstNotify) { return; } mFirstNotify = TRUE; // // To avoid compiler warning of "C4701: potentially uninitialized local variable 'PlatformCpuInfo' used". // PlatformCpuInfo.CpuVersion.FullCpuId = 0; // // Get Platform CPU Info HOB. // PlatformCpuInfoPtr = NULL; ZeroMem (&PlatformCpuInfo, sizeof(EFI_PLATFORM_CPU_INFO)); VariableSize = sizeof(EFI_PLATFORM_CPU_INFO); Status = gRT->GetVariable( EfiPlatformCpuInfoVariable, &gEfiVlv2VariableGuid, NULL, &VariableSize, PlatformCpuInfoPtr ); if (EFI_ERROR(Status)) { GuidHob.Raw = GetHobList (); if (GuidHob.Raw != NULL) { if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformCpuInfoGuid, GuidHob.Raw)) != NULL) { PlatformCpuInfoPtr = GET_GUID_HOB_DATA (GuidHob.Guid); } } } if ((PlatformCpuInfoPtr != NULL)) { CopyMem(&PlatformCpuInfo, PlatformCpuInfoPtr, sizeof(EFI_PLATFORM_CPU_INFO)); } // // Update the ACPI parameter blocks finally. // VariableSize = sizeof (SYSTEM_CONFIGURATION); Status = gRT->GetVariable ( L"Setup", &mSystemConfigurationGuid, NULL, &VariableSize, &SetupVarBuffer ); ASSERT_EFI_ERROR (Status); // // Find the AcpiSupport protocol. // Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0); ASSERT_EFI_ERROR (Status); TableVersion = EFI_ACPI_TABLE_VERSION_2_0; // // Publish ACPI 1.0 or 2.0 Tables. // Status = AcpiSupport->PublishTables ( AcpiSupport, TableVersion ); ASSERT_EFI_ERROR (Status); // // S3 script save. // Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **) &AcpiS3Save); if (!EFI_ERROR (Status)) { AcpiS3Save->S3Save (AcpiS3Save, NULL); } }
EFI_STATUS AmdFchWheaInitEntryEinj ( VOID ) { EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; EFI_STATUS Status; INTN Index; UINTN Handle; EFI_ACPI_TABLE_VERSION Version; EFI_ACPI_DESCRIPTION_HEADER *Table; EFI_ACPI_DESCRIPTION_HEADER *NewTable; Status = gBS->LocateProtocol ( &gEfiAcpiSupportGuid, NULL, &AcpiSupport ); if (EFI_ERROR (Status)) { return Status; } // // Search EINJ table // Index = 0; Handle = 0; do { Table = NULL; Status = AcpiSupport->GetAcpiTable ( AcpiSupport, Index, &Table, &Version, &Handle ); if (EFI_ERROR (Status)) { break; } // // Check Signture and update EINJ table // if (Table->Signature == 0x4A4E4945) { // // allocate memory for new Table // Status = gBS->AllocatePool ( EfiReservedMemoryType, MAX_EINJ_SIZE, &NewTable ); if (Status != EFI_SUCCESS) { return Status; } EfiZeroMem (NewTable, MAX_EINJ_SIZE); // // Copy Table // EfiCopyMem (NewTable, Table, Table->Length); // // Update new table // AmdFchUpdateEinj (NewTable); if (!EFI_ERROR (Status)) { // Patch EINJ table here and save table back. // // Remove previous table // gBS->FreePool (Table); Table = NULL; Status = AcpiSupport->SetAcpiTable ( AcpiSupport, Table, TRUE, Version, &Handle ); // // Add new table // Handle = 0; Status = AcpiSupport->SetAcpiTable ( AcpiSupport, NewTable, TRUE, Version, &Handle ); gBS->FreePool (NewTable); return Status; } gBS->FreePool (NewTable); } gBS->FreePool (Table); Index++; } while (TRUE); return Status; }
VOID IScsiPublishIbft ( IN VOID ) /*++ Routine Description: Publish and remove the iSCSI Boot Firmware Table according to the iSCSI session status. Arguments: None. Returns: None. --*/ { EFI_STATUS Status; UINTN TableHandle; EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table; EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; EFI_ACPI_DESCRIPTION_HEADER *Rsdt; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINT8 *Heap; UINTN Index; INTN TableIndex; EFI_ACPI_TABLE_VERSION Version; UINT32 Signature; Status = gBS->LocateProtocol (&gEfiAcpiSupportGuid, NULL, &AcpiSupport); if (EFI_ERROR (Status)) { return ; } // // Find ACPI table RSD_PTR from system table // for (Index = 0, Rsdp = NULL; Index < gST->NumberOfTableEntries; Index++) { if (EfiCompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi30TableGuid) || EfiCompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi20TableGuid) || EfiCompareGuid (&(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; } // // Try to remove the old iSCSI Boot Firmware Table. // for (TableIndex = 0;; TableIndex++) { Status = AcpiSupport->GetAcpiTable ( AcpiSupport, TableIndex, &Table, &Version, &TableHandle ); if (EFI_ERROR (Status)) { break; } Signature = Table->Signature; NetFreePool (Table); if (Signature == EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE) { // // Remove the table. // Status = AcpiSupport->SetAcpiTable ( AcpiSupport, NULL, FALSE, Version, &TableHandle ); if (EFI_ERROR (Status)) { return ; } break; } } // // Get all iSCSI private protocols. // Status = gBS->LocateHandleBuffer ( ByProtocol, &mIScsiPrivateGuid, NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR (Status)) { return ; } // // Allocate 4k bytes to hold the ACPI table. // Table = NetAllocatePool (IBFT_MAX_SIZE); if (Table == NULL) { return ; } Heap = (CHAR8 *) 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); NetFreePool (HandleBuffer); TableHandle = 0; // // Install or update the iBFT table. // Status = AcpiSupport->SetAcpiTable ( AcpiSupport, Table, TRUE, EFI_ACPI_TABLE_VERSION_3_0, &TableHandle ); if (!EFI_ERROR (Status)) { AcpiSupport->PublishTables (AcpiSupport, EFI_ACPI_TABLE_VERSION_3_0); } NetFreePool (Table); }
VOID EFIAPI FchAcpiInstall2Notify ( IN EFI_EVENT Event, IN VOID *Context ) { UINT8 *Temp; UINT8 *AmdAcpiDataTree; UINTN Index; UINTN TableHandle; EFI_STATUS Status; EFI_HANDLE Handle; EFI_ACPI_DESCRIPTION_HEADER *Table; EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt; EFI_ACPI_TABLE_VERSION Version; EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; FCH_ACPI_PROTOCOL *FchAcpiProtocol; EFI_PCI_IO_PROTOCOL *PciIo; Status = EFI_SUCCESS; AmdAcpiDataTree = NULL; Status = gBS->LocateProtocol ( &gEfiPciIoProtocolGuid, NULL, &PciIo ); if (EFI_ERROR (Status)) { return; } Status = gBS->LocateProtocol ( &gFchAcpiProtocolGuid, NULL, &FchAcpiProtocol ); if (!EFI_ERROR (Status)) { return; } Status = gBS->LocateProtocol ( &gEfiAcpiSupportGuid, NULL, &AcpiSupport ); if (EFI_ERROR (Status)) { return; } Index = 0; TableHandle = 0; do { Table = NULL; Status = AcpiSupport->GetAcpiTable ( AcpiSupport, Index, &Table, &Version, &TableHandle ); if (EFI_ERROR (Status)) { break; } // // Check Signture and update DSDT table // if (Table->Signature == EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) { Status = AmdBuildAcpiDsdtTree ((EFI_ACPI_DESCRIPTION_HEADER *)Table, &AmdAcpiDataTree); if (EFI_ERROR (Status)) { return; } Status = gBS->AllocatePool ( EfiBootServicesData, 0x01, &Temp ); ASSERT_EFI_ERROR (Status); *Temp = FCH_ACPI_FIELD_INFO_END; Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (FCH_ACPI_PROTOCOL), &FchAcpiProtocol ); ASSERT_EFI_ERROR (Status); FchAcpiProtocol->Revision = FCH_ACPI_PROTOCOL_REV; FchAcpiProtocol->FchAcpiGetIntDevPathName = AmdFchGetIntDevPath; FchAcpiProtocol->FchAcpiAddDataField = AmdFchDataDxeAddItem; FchAcpiProtocol->FchAcpiEnableGpio = AmdFchAcpiEnableGpio; FchAcpiProtocol->FchAcpiEnableAsf = AmdFchAcpiEnableAsf; FchAcpiProtocol->FchAcpiTool.FindNextSig = FchFindNextSig; FchAcpiProtocol->FchAcpiTool.UpdateAcpiName = UpdateAcpiName; FchAcpiProtocol->FchAcpiTool.GetPkgLength = FchAcpiPkgLength; FchAcpiProtocol->FchAcpiData.DataLength = sizeof (AMD_FCH_COMMON_DATA); FchAcpiProtocol->FchAcpiData.AcpiInfoLength = 0x01; FchAcpiProtocol->FchAcpiData.FchData = mFchCommonData; FchAcpiProtocol->FchAcpiData.AcpiFieldNames = Temp; Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gFchAcpiProtocolGuid, EFI_NATIVE_INTERFACE, FchAcpiProtocol ); if (EFI_ERROR (Status)) { return; } } // // Check Signture and update FADT table // if (Table->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) { Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)Table; mFchCommonData->SciInterrupt = Fadt->SciInt; } gBS->FreePool (Table); Index++; } while (TRUE); }
/** *--------------------------------------------------------------------------------------- * * AddApeiTables * * Description: * Event Callback that adds the APEI Tables to OS. * * Parameters: * @param[in] Event * @param[in] *Context * * @retval EFI_SUCCESS Error record has been added to BERT table * EFI_UNSUPPORTED ErrorType passed in is unsupported * EFI_OUT_OF_RESOURCES Could not allocate memory * EFI_VOLUME_FULL Cannot add one more error record * *--------------------------------------------------------------------------------------- **/ VOID AddApeiTables ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status = EFI_SUCCESS; EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupportProtocol = NULL; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo = NULL; UINTN BertTblHandle; UINTN EinjTblHandle; UINT32 Value32; // UINTN ErstTblHandle; BertTblHandle = 0; EinjTblHandle = 0; //ErstTblHandle = 0; // Local ACPI Protocol Status = gBS->LocateProtocol ( &gAcpiSupportGuid, NULL, &AcpiSupportProtocol ); if (EFI_ERROR (Status)) { return; } //Add BERT table to the ACPI aware OS Status = AcpiSupportProtocol->SetAcpiTable ( AcpiSupportProtocol, // IN EFI_ACPI_SUPPORT_PROTOCOL *This mApeiInterface->ApeiPrivData->ApeiBertTbl, // IN VOID *Table OPTIONAL TRUE, // IN BOOLEAN Checksum EFI_ACPI_TABLE_VERSION_ALL, // IN EFI_ACPI_TABLE_VERSION Version &BertTblHandle // IN OUT UINTN *TableHandle ); ASSERT_EFI_ERROR (Status); // Locate PCI Root Bridge Protocol Status = gBS->LocateProtocol ( &gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID**) &PciRootBridgeIo ); if (EFI_ERROR (Status)) { return; } // Check to see if ECC is enabled before adding EINJ table PciRootBridgeIo->Pci.Read ( PciRootBridgeIo, EfiPciWidthUint32, EFI_PCI_ADDRESS (0, 0x18, 0x3, 0x44), 1, &Value32 ); if (Value32 & (1 << 22)) { // //Add EINJ table to the ACPI aware OS // Status = AcpiSupportProtocol->SetAcpiTable ( AcpiSupportProtocol, // IN EFI_ACPI_SUPPORT_PROTOCOL *This mApeiInterface->ApeiPrivData->ApeiEinjTbl, // IN VOID *Table OPTIONAL TRUE, // IN BOOLEAN Checksum EFI_ACPI_TABLE_VERSION_ALL, // IN EFI_ACPI_TABLE_VERSION Version &EinjTblHandle // IN OUT UINTN *TableHandle ); ASSERT_EFI_ERROR (Status); } // Uncomment code below to publish ERST Table to OS //Add ERST table //Status = AcpiSupportProtocol->SetAcpiTable ( // AcpiSupportProtocol, // IN EFI_ACPI_SUPPORT_PROTOCOL *This // mApeiInterface->ApeiPrivData->ApeiErstTbl, // IN VOID *Table OPTIONAL // TRUE, // IN BOOLEAN Checksum // EFI_ACPI_TABLE_VERSION_ALL, // IN EFI_ACPI_TABLE_VERSION Version // &ErstTblHandle // IN OUT UINTN *TableHandle // ); // //ASSERT_EFI_ERROR (Status); // Close the APEI ready2boot event gBS->CloseEvent (mEvtApeiReadyToBoot); return; }
EFI_STATUS EFIAPI AmdRasApeiDxeDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status = EFI_SUCCESS; EFI_HANDLE Handle = NULL; EFI_HANDLE hEinj = NULL; AMD_RAS_APEI_PROTOCOL *AmdRasApeiProtocol; BOOLEAN InSmm; EFI_SMM_BASE_PROTOCOL *SmmBase = NULL; EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath = NULL; EFI_DEVICE_PATH_PROTOCOL *NewFilePath = NULL; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage = NULL; EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch = NULL; EFI_SMM_SW_DISPATCH_CONTEXT SwContext; EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupportProtocol = NULL; EFI_HANDLE SwHandle = NULL; EFI_HANDLE hNewHandle = NULL; UINTN BufferSize; UINTN HestTblHandle; UINT64 Address64; UINT32 Value32; // // Initialize Local Variables // InSmm = FALSE; BufferSize = 0; HestTblHandle = 0; // // Initialize Global Variables // EfiInitializeApei (ImageHandle, SystemTable); // Locate SMM Base Protocol Status = gBS->LocateProtocol ( &gEfiSmmBaseProtocolGuid, // IN EFI_GUID Published unique identifier of requested protocol GUID to locate NULL, // IN VOID* Published unique identifier of requested protocol GUID &SmmBase // OUT VOID** Returns address of pointer for SMM Base protocol interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; // Error detected while trying to locate SMM Base Protocol } // Save the SMM Base system table pointer SmmBase->GetSmstLocation (SmmBase, &gSmst); // Determine if we are in SMM or not SmmBase->InSmm (SmmBase, &InSmm); if (!InSmm) { // Query image handle to see if it supports a requested protocol and then get an address of the protocol image to be loaded Status = gBS->HandleProtocol ( ImageHandle, // Handle of requested protocol &gEfiLoadedImageProtocolGuid, // Published unique identifier of requested protocol GUID (VOID*)&LoadedImage // Returns address of pointer for requested protocol interface of the image ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; // Error detected while trying to query LoadImage protocol } // Query device handle of loaded image to see if it supports a requested protocol and then get an address of the prototocl device path Status = gBS->HandleProtocol ( LoadedImage->DeviceHandle, // Handle of requested protocol &gEfiDevicePathProtocolGuid, // Published unique identifier of requested protocol GUID (VOID*) &ImageDevicePath // Returns address of pointer for requested protocol interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } // Add this image's device path to the loaded image device path image and return // a pointer to the new file path. NewFilePath = AddDevicePath ( ImageDevicePath, // IN EFI_DEVICE_PATH_PROTOCOL* LoadedImage->FilePath // IN EFI_DEVICE_PATH_PROTOCOL* Device Path Image to add ); //Load the image in System Management RAM; it will automatically generate an SMI. Status = SmmBase->Register ( SmmBase, // IN *This Addreess of pointer for SMM Base protocol interface) NewFilePath, // IN EFI_DEVICE_PATH_PROTOCOL NULL, // IN SourceBuffer OPTIONAL 0, // IN SourceSize OPTIONAL &hEinj, // OUT *ImageHandle FALSE // IN LegacyIA32Binary OPTIONAL ); // Free up residual heap memory if not equal to NULL if (NewFilePath) { gBS->FreePool (NewFilePath); } if (EFI_ERROR (Status)) { switch (EFIERR (Status)) { case EFI_LOAD_ERROR: break; case EFI_INVALID_PARAMETER: break; case EFI_UNSUPPORTED: break; default: ; } return Status; } } else { // We are in SMM... // Allocate Memory for type Runtime Services Data - APEI Module Private Data Status = gBS->AllocatePool (EfiRuntimeServicesData, sizeof (APEI_DRIVER_PRIVATE_DATA), &mApeiPrivData); if (EFI_ERROR (Status)) { return Status; } // Allocate Memory for type Runtime Services Data - APEI Interface Status = gBS->AllocatePool (EfiRuntimeServicesData, sizeof (AMD_APEI_INTERFACE), &mApeiInterface); if (EFI_ERROR (Status)) { return Status; } // Locate SW SMM Dispatch Protocol Status = gBS->LocateProtocol ( &gEfiSmmSwDispatchProtocolGuid, // IN EFI_GUID Published unique identifier of requested protocol GUID to locate NULL, // IN VOID* Published unique identifier of requested protocol GUID &SwDispatch // OUT VOID** Returns address of pointer for SMM Base protocol interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } SwContext.SwSmiInputValue = EINJ_BEGIN_INJ_CMD; // Register EINJ SMM callback handler. Status = SwDispatch->Register ( SwDispatch, // IN *This ApeiEinjSwSmiHandler, // IN EFI SW SMM Dispatcher Callback Entry Point Address &SwContext, // IN SwContext &SwHandle // IN OUT SwHandle ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } SwContext.SwSmiInputValue = ERST_EXECUTE_OPERATION_CMD; // Register ERST SMM callback handler. Status = SwDispatch->Register ( SwDispatch, ApeiErstSwSmiHandler, &SwContext, &SwHandle ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } // Allocate Memory for the the AMD_RAS_APEI_PROTOCOL protocol. Status = gBS->AllocatePool ( EfiBootServicesData, // IN EFI_MEMORY_TYPE PoolType sizeof (AMD_RAS_APEI_PROTOCOL), // IN UINTN Size &AmdRasApeiProtocol // OUT VOID **Buffer ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_OUT_OF_RESOURCES; // Error detected while trying to locate SMM Base Protocol } EfiCommonLibZeroMem (AmdRasApeiProtocol, sizeof (AMD_RAS_APEI_PROTOCOL)); // Initialize BERT ApeiBertInit (); // Initialize HEST ApeiHestInit (); // Determine if we have ECC error enable bits set Address64 = mCfgMmioBase | ((0x18 << 15) | (3 << 12) | 0x44); //F3:44 MC4_NB_CFG Value32 = RasSmmReadMem32 (Address64); if (Value32 & (1 << 22)) { //Initialize EINJ if ECC is Enabled ApeiEinjInit (); } // Initialize ERST ApeiErstInit (); AmdRasApeiProtocol->AmdApeiInterface = mApeiInterface; mApeiInterface->ApeiPrivData = mApeiPrivData; AmdRasApeiProtocol->AddBootErrorRecordEntry = 0; AmdRasApeiProtocol->AddHestErrorSourceEntry = 0; Status = gBS->InstallProtocolInterface ( &Handle, // IN OUT EFI_HANDLE &gAmdRasApeiProtocolGuid, // IN EFI_GUID EFI_NATIVE_INTERFACE, // IN EFI_INITERFACE_TYPE AmdRasApeiProtocol // IN VOID* Interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } } // End-- if(!InSmm) // // Do more non-SMM configuration // if (!InSmm) { Status = gBS->LocateProtocol ( &gAmdRasApeiProtocolGuid, NULL, &AmdRasApeiProtocol ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } mApeiInterface = AmdRasApeiProtocol->AmdApeiInterface; mApeiPrivData = mApeiInterface->ApeiPrivData; // Initialize function pointers to protocol interfaces AmdRasApeiProtocol->AddBootErrorRecordEntry = &AddBertErrorRecord; AmdRasApeiProtocol->AddHestErrorSourceEntry = &AddHestErrorRecord; // // Find the protocol that was installed during SMM phase and reinstall it during // Non-SMM phase as well. // // Get the buffer size for the EFI_HANDLE BufferSize = sizeof (EFI_HANDLE); // Returns an array of handles that support a specified protocol. Status = gBS->LocateHandle ( ByProtocol, // IN EFI_LOCATE_SEARCH_TYPE SearchType &gAmdRasApeiProtocolGuid, // IN EFI_GUID *Protocol OPTIONAL NULL, // IN VOID *SearchKey OPTIONAL &BufferSize, // IN OUT UINTN BufferSize &hNewHandle // OUT EFI_HANDLE *Buffer ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } // Queries a handle to determine if it supports a specified protocol. Status = gBS->HandleProtocol ( hNewHandle, // IN EFI_HANDLE Handle &gAmdRasApeiProtocolGuid, // IN EFI_GUID *Protocol (VOID **) &AmdRasApeiProtocol // OUT VOID *NewInterface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } // Local ACPI Protocol Status = gBS->LocateProtocol ( &gAcpiSupportGuid, NULL, (VOID **) &AcpiSupportProtocol ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate ACPI Support Protocol } //Add HEST table to the ACPI aware OS Status = AcpiSupportProtocol->SetAcpiTable ( AcpiSupportProtocol, // IN EFI_ACPI_SUPPORT_PROTOCOL *This mApeiInterface->ApeiPrivData->ApeiHestTbl, // IN VOID *Table OPTIONAL TRUE, // IN BOOLEAN Checksum EFI_ACPI_TABLE_VERSION_ALL, // IN EFI_ACPI_TABLE_VERSION Version &HestTblHandle // IN OUT UINTN *TableHandle ); ASSERT_EFI_ERROR (Status); // Reinstalls a protocol interface on a device handle. Status = gBS->ReinstallProtocolInterface ( hNewHandle, // IN EFI_HANDLE Handle &gAmdRasApeiProtocolGuid, // IN EFI_GUID *Protocol AmdRasApeiProtocol, // IN VOID *OldInterface AmdRasApeiProtocol // IN VOID *NewInterface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } // Create a callback event to be executed at ReadyToBoot to publish APEI tables to OS. Status = gBS->CreateEventEx ( EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_NOTIFY, AddApeiTables, NULL, &gEfiEventReadyToBootGuid, &mEvtApeiReadyToBoot ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_OUT_OF_RESOURCES; // Error detected while trying to locate SMM Base Protocol } } 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); }
EFI_STATUS Main( VOID ) { EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupportProtocol; EFI_LEGACY_BIOS_PROTOCOL *LegacyBiosProtocol; UINT64 Handel = 0; UINTN DataSize = 0; EFI_TPL OldTpl; EFI_STATUS Status = EFI_UNSUPPORTED; Rsdp20Tbl_t *RsdpTable = 0; Rsdp20Tbl_t *LegacyRsdpTable = 0; RsdtTbl_t *RsdtTable = 0; XsdtTbl_t *XsdtTable = 0; SlicTbl_t *SlicTable = 0; AcpiTbl_t *AcpiTable = 0; VOID *LegacyAddress = 0; UINT8 SlpString[0x20] = { 0 }; UINTN i = 0; //=========================================================================// // code starts // //=========================================================================// SlicTable = (SlicTbl_t *)SLIC; //=========================================================================// // add Marker and Public Key to empty SLIC // //=========================================================================// DataSize = sizeof(Marker_t); if (RS->GetVariable(OaMarkerName, &OaMarkerGuid, 0, &DataSize, &SlicTable->Marker) != EFI_SUCCESS || DataSize != sizeof(Marker_t)) { return EFI_NOT_FOUND; } DataSize = sizeof(PublicKey_t); if (RS->GetVariable(OaPublicKeyName, &OaPublicKeyGuid, 0, &DataSize, &SlicTable->PublicKey) != EFI_SUCCESS || DataSize != sizeof(PublicKey_t)) { return EFI_NOT_FOUND; } //=========================================================================// // copy OemId, OemTableId from Marker to SLIC ACPI header // //=========================================================================// BS->CopyMem(SlicTable->Header.OemId, SlicTable->Marker.OemId, 6); BS->CopyMem(SlicTable->Header.OemTableId, SlicTable->Marker.OemTableId, 8); //=========================================================================// // add SLIC to ACPI tables // //=========================================================================// if(BS->LocateProtocol(&AcpiProtocolGuid, NULL, (VOID **) &AcpiSupportProtocol) == EFI_SUCCESS) { Status = AcpiSupportProtocol->SetAcpiTable(AcpiSupportProtocol, (VOID *)SLIC, TRUE, EFI_ACPI_TABLE_VERSION_1_0B|EFI_ACPI_TABLE_VERSION_2_0|EFI_ACPI_TABLE_VERSION_3_0, &Handel); } if (Status != EFI_SUCCESS) { return Status; } #if SLP_INJECT == 1 //=========================================================================// // add SLP 1.0 string to legacy region // //=========================================================================// DataSize = sizeof(SlpString); if (RS->GetVariable(OaSlpName, &OaSlpGuid, 0, &DataSize, SlpString) == EFI_SUCCESS) { if (BS->LocateProtocol(&LegacyBiosGuid, NULL, (VOID **)&LegacyBiosProtocol) == EFI_SUCCESS) { if (LegacyBiosProtocol->GetLegacyRegion(LegacyBiosProtocol, sizeof(SlpString), 1, 2, &LegacyAddress) == EFI_SUCCESS) { Status = LegacyBiosProtocol->CopyLegacyRegion(LegacyBiosProtocol, DataSize, LegacyAddress, SlpString); } } } #endif //=========================================================================// // find ACPI tables // //=========================================================================// OldTpl = BS->RaiseTPL(TPL_HIGH_LEVEL); Status = GetSystemConfigurationTable (&EfiAcpi20TableGuid, (VOID **)&RsdpTable); if (EFI_ERROR (Status)) { Status = GetSystemConfigurationTable (&EfiAcpiTableGuid, (VOID **)&RsdpTable); } if (Status == EFI_SUCCESS) { if (RsdpTable->Revision == 0) { RsdtTable = (RsdtTbl_t *) RsdpTable->RSDTAddress; } else if (RsdpTable->Revision == 2) { RsdtTable = (RsdtTbl_t *) RsdpTable->RSDTAddress; XsdtTable = (XsdtTbl_t *) RsdpTable->XSDTAddress; } else { return EFI_UNSUPPORTED; } } else { return EFI_NOT_FOUND; } //=========================================================================// // copy SLIC OemId, OemTableId to RSDP, RSDT, XSDT // //=========================================================================// #if PATCH_TABLES == 1 DataSize = (RsdtTable->Header.Length - sizeof(AcpiHeader_t)) << 2; for(i = 0 ; i < DataSize; i++) { AcpiTable = (AcpiTbl_t *) RsdtTable->Entry[i]; if (AcpiTable != NULL) { if (CompareMem(AcpiTable->Header.OemId, RsdtTable->Header.OemId, 6) == 0 && CompareMem(AcpiTable->Header.OemTableId, RsdtTable->Header.OemTableId, 8) == 0) { BS->CopyMem(AcpiTable->Header.OemId, SlicTable->Header.OemId, 6); BS->CopyMem(AcpiTable->Header.OemTableId, SlicTable->Header.OemTableId, 8); AcpiTable->Header.Checksum = 0; AcpiTable->Header.Checksum = ComputeChecksum((UINT8 *) AcpiTable, AcpiTable->Header.Length); } } } #endif BS->CopyMem(RsdtTable->Header.OemId, SlicTable->Header.OemId, 6); BS->CopyMem(RsdtTable->Header.OemTableId, SlicTable->Header.OemTableId, 8); RsdtTable->Header.Checksum = 0; RsdtTable->Header.Checksum = ComputeChecksum((UINT8 *) RsdtTable, RsdtTable->Header.Length); BS->CopyMem(RsdpTable->OemId, SlicTable->Header.OemId, 6); RsdpTable->Checksum = 0; RsdpTable->Checksum = ComputeChecksum((UINT8 *) RsdpTable, 0x14); if(RsdpTable->Revision == 2) { #if PATCH_TABLES == 1 DataSize = (XsdtTable->Header.Length - sizeof(AcpiHeader_t)) << 3; for(i = 0 ; i < DataSize; i++) { AcpiTable = (AcpiTbl_t *) (XsdtTable->Entry[i] & 0xFFFFFFFF); if (AcpiTable != NULL) { if (CompareMem(AcpiTable->Header.OemId, XsdtTable->Header.OemId, 6) == 0 && CompareMem(AcpiTable->Header.OemTableId, XsdtTable->Header.OemTableId, 8) == 0) { BS->CopyMem(AcpiTable->Header.OemId, SlicTable->Header.OemId, 6); BS->CopyMem(AcpiTable->Header.OemTableId, SlicTable->Header.OemTableId, 8); AcpiTable->Header.Checksum = 0; AcpiTable->Header.Checksum = ComputeChecksum((UINT8 *) AcpiTable, AcpiTable->Header.Length); } } } #endif RsdpTable->ExtendedChecksum = 0; RsdpTable->ExtendedChecksum = ComputeChecksum((UINT8 *) RsdpTable, RsdpTable->Length); BS->CopyMem(XsdtTable->Header.OemId, SlicTable->Header.OemId, 6); BS->CopyMem(XsdtTable->Header.OemTableId, SlicTable->Header.OemTableId, 8); XsdtTable->Header.Checksum = 0; XsdtTable->Header.Checksum = ComputeChecksum((UINT8 *) XsdtTable, XsdtTable->Header.Length); } //=========================================================================// // copy OemId to RSDP in legacy region // //=========================================================================// LegacyRsdpTable = (Rsdp20Tbl_t *) FindAcpiRsdPtr(); if (LegacyRsdpTable != NULL && LegacyUnlock() == EFI_SUCCESS) { BS->CopyMem(LegacyRsdpTable->OemId, SlicTable->Header.OemId, 6); LegacyRsdpTable->RSDTAddress = RsdpTable->RSDTAddress; LegacyRsdpTable->Checksum = 0; LegacyRsdpTable->Checksum = ComputeChecksum((UINT8 *) LegacyRsdpTable, 0x14); if(LegacyRsdpTable->Revision == 2) { LegacyRsdpTable->XSDTAddress = RsdpTable->XSDTAddress; LegacyRsdpTable->ExtendedChecksum = 0; LegacyRsdpTable->ExtendedChecksum = ComputeChecksum((UINT8 *) LegacyRsdpTable, LegacyRsdpTable->Length); } LegacyLock(); } BS->RestoreTPL(OldTpl); return Status; }