Beispiel #1
0
/**
  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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
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");

}
Beispiel #4
0
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;
}
/**
 *---------------------------------------------------------------------------------------
 *
 *  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;
}
Beispiel #7
0
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);


}
Beispiel #8
0
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;
}