Example #1
0
/**
  Check if XD and BTS features are supported by all processors.

**/
VOID
CheckProcessorFeature (
  VOID
  )
{
  EFI_STATUS                        Status;
  EFI_MP_SERVICES_PROTOCOL          *MpServices;

  Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices);
  ASSERT_EFI_ERROR (Status);

  //
  // First detect if XD and BTS are supported
  //
  mXdSupported  = TRUE;
  mBtsSupported = TRUE;

  //
  // Check if XD and BTS are supported on all processors.
  //
  CheckFeatureSupported ();

  //
  //Check on other processors if BSP supports this
  //
  if (mXdSupported || mBtsSupported) {
    MpServices->StartupAllAPs (
                  MpServices,
                  (EFI_AP_PROCEDURE) CheckFeatureSupported,
                  TRUE,
                  NULL,
                  0,
                  NULL,
                  NULL
                  );
  }
}
Example #2
0
/**
  The module Entry Point of the CPU SMM driver.

  @param  ImageHandle    The firmware allocated handle for the EFI image.
  @param  SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS    The entry point is executed successfully.
  @retval Other          Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
PiCpuSmmEntry (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                 Status;
  EFI_MP_SERVICES_PROTOCOL   *MpServices;
  UINTN                      NumberOfEnabledProcessors;
  UINTN                      Index;
  VOID                       *Buffer;
  UINTN                      BufferPages;
  UINTN                      TileCodeSize;
  UINTN                      TileDataSize;
  UINTN                      TileSize;
  UINT8                      *Stacks;
  VOID                       *Registration;
  UINT32                     RegEax;
  UINT32                     RegEdx;
  UINTN                      FamilyId;
  UINTN                      ModelId;
  UINT32                     Cr3;

  //
  // Initialize Debug Agent to support source level debug in SMM code
  //
  InitializeDebugAgent (DEBUG_AGENT_INIT_SMM, NULL, NULL);

  //
  // Report the start of CPU SMM initialization.
  //
  REPORT_STATUS_CODE (
    EFI_PROGRESS_CODE,
    EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT
    );

  //
  // Fix segment address of the long-mode-switch jump
  //
  if (sizeof (UINTN) == sizeof (UINT64)) {
    gSmmJmpAddr.Segment = LONG_MODE_CODE_SEGMENT;
  }

  //
  // Find out SMRR Base and SMRR Size
  //
  FindSmramInfo (&mCpuHotPlugData.SmrrBase, &mCpuHotPlugData.SmrrSize);

  //
  // Get MP Services Protocol
  //
  Status = SystemTable->BootServices->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices);
  ASSERT_EFI_ERROR (Status);

  //
  // Use MP Services Protocol to retrieve the number of processors and number of enabled processors
  //
  Status = MpServices->GetNumberOfProcessors (MpServices, &mNumberOfCpus, &NumberOfEnabledProcessors);
  ASSERT_EFI_ERROR (Status);
  ASSERT (mNumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));

  //
  // If support CPU hot plug, PcdCpuSmmEnableBspElection should be set to TRUE.
  // A constant BSP index makes no sense because it may be hot removed.
  //
  DEBUG_CODE (
    if (FeaturePcdGet (PcdCpuHotPlugSupport)) {

      ASSERT (FeaturePcdGet (PcdCpuSmmEnableBspElection));
    }
  );
Example #3
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;
}
Example #4
0
/**
  This function will update any runtime platform specific information.
  This currently includes:
    Setting OEM table values, ID, table ID, creator ID and creator revision.
    Enabling the proper processor entries in the APIC tables.

  @param[in]  Table       The table to update.

  @retval  EFI_SUCCESS    The function completed successfully.

**/
EFI_STATUS
PlatformUpdateTables (
  IN OUT EFI_ACPI_COMMON_HEADER  *Table
  )
{
  EFI_ACPI_DESCRIPTION_HEADER                                 *TableHeader;
  UINT8                                                       *CurrPtr;
  UINT8                                                       *EndPtr;
  ACPI_APIC_STRUCTURE_PTR                                     *ApicPtr;
  UINT8                                                       CurrProcessor;
  EFI_STATUS                                                  Status;
  EFI_MP_SERVICES_PROTOCOL                                    *MpService;
  UINTN                                                       MaximumNumberOfCPUs;
  UINTN                                                       NumberOfEnabledCPUs;
  UINTN                                                       BufferSize;
  ACPI_APIC_STRUCTURE_PTR                                     *ProcessorLocalApicEntry;
  UINTN                                                       BspIndex;
  EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE                          *AsfEntry;
  EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER            *HpetTbl;
  UINT64                                                      OemIdValue;
  UINT8                                                       Index;
  EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE                   *Facp;
  EFI_ACPI_OSFR_TABLE                                         *OsfrTable;
  EFI_ACPI_OSFR_OCUR_OBJECT                                   *pOcurObject;
  EFI_ACPI_OSFR_OCUR_OBJECT                                   OcurObject = {{0xB46F133D, 0x235F, 0x4634, 0x9F, 0x03, 0xB1, 0xC0, 0x1C, 0x54, 0x78, 0x5B}, 0, 0, 0, 0, 0};
  CHAR16                                                      *OcurMfgStringBuffer = NULL;
  CHAR16                                                      *OcurModelStringBuffer = NULL;
  UINT8                                                       *OcurRefDataBlockBuffer = NULL;
  UINTN                                                       OcurMfgStringBufferSize;
  UINTN                                                       OcurModelStringBufferSize;
  UINTN                                                       OcurRefDataBlockBufferSize;
#if defined (IDCC2_SUPPORTED) && IDCC2_SUPPORTED
  EFI_ACPI_ASPT_TABLE                                         *pSpttTable;
#endif
  UINT16                                                      NumberOfHpets;
  UINT16                                                      HpetCapIdValue;
  UINT32                                                      HpetBlockID;
  UINTN                                                       LocalApicCounter;
  EFI_PROCESSOR_INFORMATION                                   ProcessorInfoBuffer;
  UINT8                                                       TempVal;
  EFI_ACPI_3_0_IO_APIC_STRUCTURE                              *IOApicType;
  EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER         *APICTableHeader;

  CurrPtr                 = NULL;
  EndPtr                  = NULL;
  ApicPtr                 = NULL;
  LocalApicCounter        = 0;
  CurrProcessor           = 0;
  ProcessorLocalApicEntry = NULL;


 if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
    TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
    //
    // Update the OEMID.
    //
    OemIdValue = mPlatformInfo->AcpiOemId;

    *(UINT32 *)(TableHeader->OemId)     = (UINT32)OemIdValue;
    *(UINT16 *)(TableHeader->OemId + 4) = *(UINT16*)(((UINT8 *)&OemIdValue) + 4);

    if ((Table->Signature != EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) {
    //
    // Update the OEM Table ID.
    //
      TableHeader->OemTableId = mPlatformInfo->AcpiOemTableId;
    }

    //
    // Update the OEM Table ID.
    //
    TableHeader->OemRevision = EFI_ACPI_OEM_REVISION;

    //
    // Update the creator ID.
    //
    TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;

    //
    // Update the creator revision.
    //
    TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
  }

  //
  // Complete this function.
  //
  //
  // Locate the MP services protocol.
  //
  //
  // Find the MP Protocol. This is an MP platform, so MP protocol must be
  // there.
  //
  Status = gBS->LocateProtocol (
                  &gEfiMpServiceProtocolGuid,
                  NULL,
                  (VOID **) &MpService
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Determine the number of processors.
  //
  MpService->GetNumberOfProcessors (
              MpService,
              &MaximumNumberOfCPUs,
              &NumberOfEnabledCPUs
              );

  ASSERT (MaximumNumberOfCPUs <= MAX_CPU_NUM && NumberOfEnabledCPUs >= 1);


  //
  // Assign a invalid intial value for update.
  //
  //
  // Update the processors in the APIC table.
  //
  switch (Table->Signature) {
    case EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE:
      //
      // Update the table if ASF is enabled. Otherwise, return error so caller will not install.
      //
      if (mSystemConfig.Asf == 1) {
        return  EFI_UNSUPPORTED;
      }
      AsfEntry = (EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE *) Table;
      TempVal = (mNumberSmbusAddress < ASF_ADDR_DEVICE_ARRAY_LENGTH)? mNumberSmbusAddress : ASF_ADDR_DEVICE_ARRAY_LENGTH;
      for (Index = 0; Index < TempVal; Index++) {
        AsfEntry->AsfAddr.FixedSmbusAddresses[Index] = mSmbusRsvdAddresses[Index];
      }
      break;

    case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:

      Status = MpService->WhoAmI (
                            MpService,
                            &BspIndex
                            );

      //
      // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled.
      //
      APICTableHeader = (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table;
      APICTableHeader->Flags |= EFI_ACPI_3_0_PCAT_COMPAT;

      CurrPtr = (UINT8 *) &((EFI_ACPI_DESCRIPTION_HEADER *) Table)[1];
      CurrPtr = CurrPtr + 8;

      //
      // Size of Local APIC Address & Flag.
      //
      EndPtr  = (UINT8 *) Table;
      EndPtr  = EndPtr + Table->Length;
      while (CurrPtr < EndPtr) {
        ApicPtr = (ACPI_APIC_STRUCTURE_PTR *) CurrPtr;
        switch (ApicPtr->AcpiApicCommon.Type) {
          case EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC:
            //
            // ESS override
            // Fix for Ordering of MADT to be maintained as it is in MADT table.
            //
            // Update processor enabled or disabled and keep the local APIC
            // order in MADT intact.
            //
            // Sanity check to make sure proc-id is not arbitrary.
            //
            DEBUG ((EFI_D_ERROR, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", \
            ApicPtr->AcpiLocalApic.AcpiProcessorId, MaximumNumberOfCPUs));
            if(ApicPtr->AcpiLocalApic.AcpiProcessorId > MaximumNumberOfCPUs) {
              ApicPtr->AcpiLocalApic.AcpiProcessorId = (UINT8)MaximumNumberOfCPUs;
            }

            BufferSize                    = 0;
            ApicPtr->AcpiLocalApic.Flags  = 0;

            for (CurrProcessor = 0; CurrProcessor < MaximumNumberOfCPUs; CurrProcessor++) {
              Status = MpService->GetProcessorInfo (
                                    MpService,
                                    CurrProcessor,
                                    &ProcessorInfoBuffer
                                    );

              if (Status == EFI_SUCCESS && ProcessorInfoBuffer.ProcessorId == ApicPtr->AcpiLocalApic.ApicId) {
                //
                // Check to see whether or not a processor (or thread) is enabled.
                //
                if ((BspIndex == CurrProcessor) || ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0)) {
                  //
                  // Go on and check if Hyper Threading is enabled. If HT not enabled
                  // hide this thread from OS by not setting the flag to 1.  This is the
                  // software way to disable Hyper Threading.  Basically we just hide it
                  // from the OS.
                  //
                  ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_1_0_LOCAL_APIC_ENABLED;


                  if(ProcessorInfoBuffer.Location.Thread != 0) {
                    ApicPtr->AcpiLocalApic.Flags = 0;
                  }

                  AppendCpuMapTableEntry (&(ApicPtr->AcpiLocalApic));
                }
                break;
              }
            }

            //
            // If no APIC-ID match, the cpu may not be populated.
            //
            break;

          case EFI_ACPI_3_0_IO_APIC:

            IOApicType = (EFI_ACPI_3_0_IO_APIC_STRUCTURE *)CurrPtr;
            IOApicType->IoApicId = 0x02;
            //
            // IO APIC entries can be patched here.
            //
            break;
        }

        CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
      }
      break;

    case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:

       Facp = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
       Facp->Flags &= (UINT32)(~(3<<2));

      break;

    case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
      //
      // Patch the memory resource.
      //
      PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER *) Table);
      break;

    case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
      //
      // Gv3 support
      //
      // TBD: Need re-design based on the ValleyTrail platform.
      //
      break;

    case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
      //
      // Adjust HPET Table to correct the Base Address.
      //
      // Enable HPET always as Hpet.asi always indicates that Hpet is enabled.
      //
      MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN);


      HpetTbl = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table;
      HpetTbl->BaseAddressLower32Bit.Address = HPET_BASE_ADDRESS;
      HpetTbl->EventTimerBlockId = *((UINT32*)(UINTN)HPET_BASE_ADDRESS);

      HpetCapIdValue = *(UINT16 *)(UINTN)(HPET_BASE_ADDRESS);
      NumberOfHpets = HpetCapIdValue & B_PCH_PCH_HPET_GCID_NT;  // Bits [8:12] contains the number of Hpets
      HpetBlockID = EFI_ACPI_EVENT_TIMER_BLOCK_ID;

      if((NumberOfHpets) && (NumberOfHpets & B_PCH_PCH_HPET_GCID_NT)) {
        HpetBlockID |= (NumberOfHpets);
      }
      HpetTbl->EventTimerBlockId = HpetBlockID;

      break;

    case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
      //
      // Update MCFG base and end bus number.
      //
      ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].BaseAddress
        = mPlatformInfo->PciData.PciExpressBase;
      ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].EndBusNumber
        = (UINT8)RShiftU64 (mPlatformInfo->PciData.PciExpressSize, 20) - 1;
      break;


    case EFI_ACPI_OSFR_TABLE_SIGNATURE:
      //
      // Get size of OSFR variable.
      //
      OcurMfgStringBufferSize = 0;
      Status = gRT->GetVariable (
                      gACPIOSFRMfgStringVariableName,
                      &gACPIOSFRMfgStringVariableGuid,
                      NULL,
                      &OcurMfgStringBufferSize,
                      NULL
                      );
      if (Status != EFI_BUFFER_TOO_SMALL) {
        //
        // Variable must not be present on the system.
        //
        return EFI_UNSUPPORTED;
      }

      //
      // Allocate memory for variable data.
      //
      OcurMfgStringBuffer = AllocatePool (OcurMfgStringBufferSize);
      Status = gRT->GetVariable (
                      gACPIOSFRMfgStringVariableName,
                      &gACPIOSFRMfgStringVariableGuid,
                      NULL,
                      &OcurMfgStringBufferSize,
                      OcurMfgStringBuffer
                      );
      if (!EFI_ERROR (Status)) {
        OcurModelStringBufferSize = 0;
        Status = gRT->GetVariable (
                        gACPIOSFRModelStringVariableName,
                        &gACPIOSFRModelStringVariableGuid,
                        NULL,
                        &OcurModelStringBufferSize,
                        NULL
                        );
        if (Status != EFI_BUFFER_TOO_SMALL) {
          //
          // Variable must not be present on the system.
          //
          return EFI_UNSUPPORTED;
        }

        //
        // Allocate memory for variable data.
        //
        OcurModelStringBuffer = AllocatePool (OcurModelStringBufferSize);
        Status = gRT->GetVariable (
                        gACPIOSFRModelStringVariableName,
                        &gACPIOSFRModelStringVariableGuid,
                        NULL,
                        &OcurModelStringBufferSize,
                        OcurModelStringBuffer
                        );
        if (!EFI_ERROR (Status)) {
          OcurRefDataBlockBufferSize = 0;
          Status = gRT->GetVariable (
                          gACPIOSFRRefDataBlockVariableName,
                          &gACPIOSFRRefDataBlockVariableGuid,
                          NULL,
                          &OcurRefDataBlockBufferSize,
                          NULL
                          );
          if (Status == EFI_BUFFER_TOO_SMALL) {
            //
            // Allocate memory for variable data.
            //
            OcurRefDataBlockBuffer = AllocatePool (OcurRefDataBlockBufferSize);
            Status = gRT->GetVariable (
                            gACPIOSFRRefDataBlockVariableName,
                            &gACPIOSFRRefDataBlockVariableGuid,
                            NULL,
                            &OcurRefDataBlockBufferSize,
                            OcurRefDataBlockBuffer
                            );
          }
          OsfrTable = (EFI_ACPI_OSFR_TABLE *) Table;
          //
          // Currently only one object is defined: OCUR_OSFR_TABLE.
          //
          OsfrTable->ObjectCount = 1;
          //
          // Initialize table length to fixed portion of the ACPI OSFR table.
          //
          OsfrTable->Header.Length = sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION);
          *(UINT32 *)((UINTN) OsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION)) = \
            (UINT32) (sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + sizeof (UINT32));
          pOcurObject = (EFI_ACPI_OSFR_OCUR_OBJECT *)((UINTN) OsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + \
            sizeof (UINT32));
          CopyMem (pOcurObject, &OcurObject, sizeof (EFI_ACPI_OSFR_OCUR_OBJECT));
          pOcurObject->ManufacturerNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \
            sizeof (EFI_ACPI_OSFR_OCUR_OBJECT));
          pOcurObject->ModelNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \
            sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize);
          if (OcurRefDataBlockBufferSize > 0) {
            pOcurObject->MicrosoftReferenceOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \
              sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + OcurModelStringBufferSize);
          }
          CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT)), OcurMfgStringBuffer, \
            OcurMfgStringBufferSize);
          CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize), \
            OcurModelStringBuffer, OcurModelStringBufferSize);
          if (OcurRefDataBlockBufferSize > 0) {
            CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + \
            OcurModelStringBufferSize),OcurRefDataBlockBuffer, OcurRefDataBlockBufferSize);
          }
          OsfrTable->Header.Length += (UINT32)(OcurMfgStringBufferSize + OcurModelStringBufferSize + OcurRefDataBlockBufferSize);
          OsfrTable->Header.Length += sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + sizeof (UINT32);
        }
      }
      gBS->FreePool (OcurMfgStringBuffer);
      gBS->FreePool (OcurModelStringBuffer);
      gBS->FreePool (OcurRefDataBlockBuffer);
      break;
    default:
      break;
  }

  //
  //
  // Update the hardware signature in the FACS structure.
  //
  //
  // Locate the SPCR table and update based on current settings.
  // The user may change CR settings via setup or other methods.
  // The SPCR table must match.
  //
  return EFI_SUCCESS;
}
Example #5
0
File: TcgDxe.c Project: OznOg/edk2
/**
  Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
  Caller is responsible to free LocationBuf.

  @param[out] LocationBuf          Returns Processor Location Buffer.
  @param[out] Num                  Returns processor number.

  @retval EFI_SUCCESS              Operation completed successfully.
  @retval EFI_UNSUPPORTED       MpService protocol not found.

**/
EFI_STATUS
GetProcessorsCpuLocation (
    OUT  EFI_CPU_PHYSICAL_LOCATION   **LocationBuf,
    OUT  UINTN                       *Num
  )
{
  EFI_STATUS                        Status;
  EFI_MP_SERVICES_PROTOCOL          *MpProtocol;
  UINTN                             ProcessorNum;
  UINTN                             EnabledProcessorNum;
  EFI_PROCESSOR_INFORMATION         ProcessorInfo;
  EFI_CPU_PHYSICAL_LOCATION         *ProcessorLocBuf;
  UINTN                             Index;

  Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol);
  if (EFI_ERROR (Status)) {
    //
    // MP protocol is not installed
    //
    return EFI_UNSUPPORTED;
  }

  Status = MpProtocol->GetNumberOfProcessors(
                         MpProtocol,
                         &ProcessorNum,
                         &EnabledProcessorNum
                         );
  if (EFI_ERROR(Status)){
    return Status;
  }

  Status = gBS->AllocatePool(
                  EfiBootServicesData,
                  sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
                  (VOID **) &ProcessorLocBuf
                  );
  if (EFI_ERROR(Status)){
    return Status;
  }

  //
  // Get each processor Location info
  //
  for (Index = 0; Index < ProcessorNum; Index++) {
    Status = MpProtocol->GetProcessorInfo(
                           MpProtocol,
                           Index,
                           &ProcessorInfo
                           );
    if (EFI_ERROR(Status)){
      FreePool(ProcessorLocBuf);
      return Status;
    }

    //
    // Get all Processor Location info & measure
    //
    CopyMem(
      &ProcessorLocBuf[Index],
      &ProcessorInfo.Location,
      sizeof(EFI_CPU_PHYSICAL_LOCATION)
      );
  }

  *LocationBuf = ProcessorLocBuf;
  *Num = ProcessorNum;

  return Status;
}
Example #6
0
VOID
ApicTableUpdate (
  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader,
  IN OUT   EFI_ACPI_TABLE_VERSION       *Version
  )
/*++

  Routine Description:

    Update the processors information in the APIC table

  Arguments:

    Table   - The table to be set
    Version - Version to publish

  Returns:

    None

--*/
{
  EFI_STATUS                 Status;
  EFI_MP_SERVICES_PROTOCOL   *MpService;
  UINT8                      *CurrPtr;
  UINT8                      *EndPtr;
  UINT8                      CurrIoApic;
  UINT8                      CurrProcessor;
  UINTN                      NumberOfCPUs;
  UINTN                      NumberOfEnabledCPUs;
  UINTN                      BufferSize;
  EFI_PROCESSOR_INFORMATION  MpContext;
  ACPI_APIC_STRUCTURE_PTR    *ApicPtr;  

  CurrIoApic    = 0;
  CurrProcessor = 0;
  //
  // Find the MP Protocol. This is an MP platform, so MP protocol must be
  // there.
  //
  Status = gBS->LocateProtocol (
                   &gEfiMpServiceProtocolGuid,
                   NULL,
                  (VOID**)&MpService
                   );
  if (EFI_ERROR (Status)) {
    //
    // Failed to get MP information, doesn't publish the invalid table
    //
    *Version = EFI_ACPI_TABLE_VERSION_NONE;
    return;
  }

  //
  // Determine the number of processors
  //
  MpService->GetNumberOfProcessors (
              MpService,
              &NumberOfCPUs,
              &NumberOfEnabledCPUs
              );

  CurrPtr = (UINT8*) &(TableHeader[1]);
  CurrPtr = CurrPtr + 8; // Size of Local APIC Address & Flag
  EndPtr  = (UINT8*) TableHeader;
  EndPtr  = EndPtr + TableHeader->Length;

  while (CurrPtr < EndPtr) {
  
    ApicPtr = (ACPI_APIC_STRUCTURE_PTR*) CurrPtr;
    switch (ApicPtr->AcpiApicCommon.Type) {

      case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC:
        BufferSize = sizeof (EFI_PROCESSOR_INFORMATION);
        ApicPtr->AcpiLocalApic.Flags = 0;
        ApicPtr->AcpiLocalApic.ApicId = 0;
        Status = MpService->GetProcessorInfo (
                              MpService,
                              CurrProcessor,
                              &MpContext
                              );

        if (!EFI_ERROR (Status)) {
          if (MpContext.StatusFlag & PROCESSOR_ENABLED_BIT) {
            ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_3_0_LOCAL_APIC_ENABLED;
          }
          ApicPtr->AcpiLocalApic.ApicId = (UINT8)MpContext.ProcessorId;
        }
        CurrProcessor++;
        break;

      case EFI_ACPI_1_0_IO_APIC:
        //
        // IO APIC entries can be patched here
        //
        if (CurrIoApic == 0) {
          //
          // Update SOC internel IOAPIC base
          //
          ApicPtr->AcpiIoApic.IoApicId      =  PcdGet8 (PcdIoApicSettingIoApicId);
          ApicPtr->AcpiIoApic.IoApicAddress =  (UINT32)FixedPcdGet64(PcdIoApicBaseAddress);
          ApicPtr->AcpiIoApic.GlobalSystemInterruptBase = 0;
        } else {
          //
          // Porting is required to update other IOAPIC entries if available
          //
          ASSERT (0);
        }
        CurrIoApic++;
        break;
          
      default:
        break;
      };
    CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
  }
}
Example #7
0
EFI_STATUS 
EFIAPI
PpmPolicyEntry(
  IN EFI_HANDLE ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
)
{
  EFI_MP_SERVICES_PROTOCOL *MpService;
  EFI_CPUID_REGISTER        Cpuid01 = { 0, 0, 0, 0};
  EFI_HANDLE                Handle;
  EFI_STATUS                Status;
  UINTN                     CpuCount;
  UINT64                    MaxRatio;
  UINT8                     CPUMobileFeature;

  PCH_STEPPING              Stepping;


  gBS = SystemTable->BootServices;
  pBS = SystemTable->BootServices;
  pRS = SystemTable->RuntimeServices;

  //
  // Set PPM policy structure to known value
  //
  gBS->SetMem (&mDxePlatformPpmPolicy, sizeof(PPM_PLATFORM_POLICY_PROTOCOL), 0);

  //
  // Find the MpService Protocol
  //
  Status = pBS->LocateProtocol (&gEfiMpServiceProtocolGuid,
                                NULL,
                                (void **)&MpService
                               );
  ASSERT_EFI_ERROR (Status);

  //
  // Get processor count from MP service.
  //
  Status = MpService->GetNumberOfProcessors (MpService, &CpuCount, NULL);
  ASSERT_EFI_ERROR (Status);

  //
  // Store the CPUID for use by SETUP items.
  //
  AsmCpuid (EFI_CPUID_VERSION_INFO, &Cpuid01.RegEax, &Cpuid01.RegEbx, &Cpuid01.RegEcx, &Cpuid01.RegEdx);
  MaxRatio = ((RShiftU64 (AsmReadMsr64(EFI_MSR_IA32_PLATFORM_ID), 8)) & 0x1F);


  mDxePlatformPpmPolicy.Revision                       = PPM_PLATFORM_POLICY_PROTOCOL_REVISION_4;

  //Read CPU Mobile feature from PLATFORM_ID_MSR MSR(0x17) NOTFB_I_AM_NOT_MOBILE_FUSE_CLIAMC00H Bit 28
  //Bit Description: { Disables Mobile features 0 = I am NOT a mobile part 1 = I am a mobile part (default)"}
  CPUMobileFeature = ((RShiftU64 (AsmReadMsr64(EFI_MSR_IA32_PLATFORM_ID), 28)) & 0x1);

  if (!EFI_ERROR(Status)) {
    if (CPUMobileFeature == 1){//CPU mobile feature
      mDxePlatformPpmPolicy.FunctionEnables.EnableGv       = ICH_DEVICE_ENABLE;
      mDxePlatformPpmPolicy.FunctionEnables.EnableCx       = ICH_DEVICE_ENABLE;
      mDxePlatformPpmPolicy.FunctionEnables.EnableCxe      = ICH_DEVICE_DISABLE;
      mDxePlatformPpmPolicy.FunctionEnables.EnableTm       = ICH_DEVICE_ENABLE;
      //MaxC7
      mDxePlatformPpmPolicy.FunctionEnables.EnableC7       = ICH_DEVICE_ENABLE;
      mDxePlatformPpmPolicy.FunctionEnables.EnableC6       = ICH_DEVICE_ENABLE;
      mDxePlatformPpmPolicy.FunctionEnables.EnableC4       = ICH_DEVICE_ENABLE;
       
      
    }else{//CPU desktop feature
       mDxePlatformPpmPolicy.FunctionEnables.EnableGv       = ICH_DEVICE_DISABLE;
       mDxePlatformPpmPolicy.FunctionEnables.EnableCx       = ICH_DEVICE_DISABLE;
       mDxePlatformPpmPolicy.FunctionEnables.EnableCxe      = ICH_DEVICE_DISABLE;
       mDxePlatformPpmPolicy.FunctionEnables.EnableTm       = ICH_DEVICE_DISABLE;
       mDxePlatformPpmPolicy.FunctionEnables.EnableC4       = ICH_DEVICE_DISABLE;
       mDxePlatformPpmPolicy.FunctionEnables.EnableC6       = ICH_DEVICE_DISABLE;
       mDxePlatformPpmPolicy.FunctionEnables.EnableC7       = ICH_DEVICE_DISABLE;
    }


    mDxePlatformPpmPolicy.FunctionEnables.EnableProcHot  = ICH_DEVICE_ENABLE;
    mDxePlatformPpmPolicy.FunctionEnables.TStatesEnable  = ICH_DEVICE_ENABLE;

    
    Stepping = PchStepping();
    if (Stepping < PchB3) {
      // If SoC is B0~B2 Stepping, disable the Turbo
      mDxePlatformPpmPolicy.FunctionEnables.EnableTurboMode= ICH_DEVICE_DISABLE;
    } else {
      mDxePlatformPpmPolicy.FunctionEnables.EnableTurboMode= ICH_DEVICE_ENABLE;
    }
    
    mDxePlatformPpmPolicy.FunctionEnables.EnableTm      = ICH_DEVICE_ENABLE;

    mDxePlatformPpmPolicy.FunctionEnables.EnableCMP      = ICH_DEVICE_ENABLE;

  } else {
    mDxePlatformPpmPolicy.FunctionEnables.EnableGv       = ICH_DEVICE_ENABLE;
    mDxePlatformPpmPolicy.FunctionEnables.EnableCx       = ICH_DEVICE_ENABLE;
    mDxePlatformPpmPolicy.FunctionEnables.EnableCxe      = ICH_DEVICE_ENABLE;
    mDxePlatformPpmPolicy.FunctionEnables.EnableTm      = ICH_DEVICE_ENABLE;
    mDxePlatformPpmPolicy.FunctionEnables.EnableProcHot  = ICH_DEVICE_ENABLE;
    mDxePlatformPpmPolicy.FunctionEnables.EnableCMP       = ICH_DEVICE_DISABLE;
    mDxePlatformPpmPolicy.FunctionEnables.TStatesEnable  = ICH_DEVICE_ENABLE;
    mDxePlatformPpmPolicy.FunctionEnables.EnableTurboMode= ICH_DEVICE_ENABLE;
    mDxePlatformPpmPolicy.FunctionEnables.EnableC4       = ICH_DEVICE_ENABLE;
    mDxePlatformPpmPolicy.FunctionEnables.EnableC6       = ICH_DEVICE_ENABLE;
  }



  mDxePlatformPpmPolicy.S3RestoreMsrSwSmiNumber                       = S3_RESTORE_MSR_SW_SMI;

  Handle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (
                                                  &Handle,
                                                  &gPpmPlatformPolicyProtocolGuid,
                                                  &mDxePlatformPpmPolicy,
                                                  NULL
                                                  );

  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}
Example #8
0
/**
   The entry function of the CpuS3Data driver.

   Allocate and initialize all fields of the ACPI_CPU_DATA structure except the
   MTRR settings.  Register an event notification on gEfiEndOfDxeEventGroupGuid
   to capture the ACPI_CPU_DATA MTRR settings.  The PcdCpuS3DataAddress is set
   to the address that ACPI_CPU_DATA is allocated at.

   @param[in] ImageHandle  The firmware allocated handle for the EFI image.
   @param[in] SystemTable  A pointer to the EFI System Table.

   @retval EFI_SUCCESS     The entry point is executed successfully.
   @retval EFI_UNSUPPORTED Do not support ACPI S3.
   @retval other           Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
CpuS3DataInitialize (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                 Status;
  ACPI_CPU_DATA_EX           *AcpiCpuDataEx;
  ACPI_CPU_DATA              *AcpiCpuData;
  EFI_MP_SERVICES_PROTOCOL   *MpServices;
  UINTN                      NumberOfCpus;
  UINTN                      NumberOfEnabledProcessors;
  VOID                       *Stack;
  UINTN                      TableSize;
  CPU_REGISTER_TABLE         *RegisterTable;
  UINTN                      Index;
  EFI_PROCESSOR_INFORMATION  ProcessorInfoBuffer;
  UINTN                      GdtSize;
  UINTN                      IdtSize;
  VOID                       *Gdt;
  VOID                       *Idt;
  EFI_EVENT                  Event;
  ACPI_CPU_DATA              *OldAcpiCpuData;

  if (!PcdGetBool (PcdAcpiS3Enable)) {
    return EFI_UNSUPPORTED;
  }

  //
  // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure
  //
  OldAcpiCpuData = (ACPI_CPU_DATA *) (UINTN) PcdGet64 (PcdCpuS3DataAddress);

  AcpiCpuDataEx = AllocateZeroPages (sizeof (ACPI_CPU_DATA_EX));
  ASSERT (AcpiCpuDataEx != NULL);
  AcpiCpuData = &AcpiCpuDataEx->AcpiCpuData;

  //
  // Get MP Services Protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiMpServiceProtocolGuid,
                  NULL,
                  (VOID **)&MpServices
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Get the number of CPUs
  //
  Status = MpServices->GetNumberOfProcessors (
                         MpServices,
                         &NumberOfCpus,
                         &NumberOfEnabledProcessors
                         );
  ASSERT_EFI_ERROR (Status);
  AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;

  //
  // Initialize ACPI_CPU_DATA fields
  //
  AcpiCpuData->StackSize                 = PcdGet32 (PcdCpuApStackSize);
  AcpiCpuData->ApMachineCheckHandlerBase = 0;
  AcpiCpuData->ApMachineCheckHandlerSize = 0;
  AcpiCpuData->GdtrProfile  = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->GdtrProfile;
  AcpiCpuData->IdtrProfile  = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->IdtrProfile;
  AcpiCpuData->MtrrTable    = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->MtrrTable;

  //
  // Allocate stack space for all CPUs.
  // Use ACPI NVS memory type because this data will be directly used by APs
  // in S3 resume phase in long mode. Also during S3 resume, the stack buffer
  // will only be used as scratch space. i.e. we won't read anything from it
  // before we write to it, in PiSmmCpuDxeSmm.
  //
  Stack = AllocateAcpiNvsMemory (NumberOfCpus * AcpiCpuData->StackSize);
  ASSERT (Stack != NULL);
  AcpiCpuData->StackAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Stack;

  //
  // Get the boot processor's GDT and IDT
  //
  AsmReadGdtr (&AcpiCpuDataEx->GdtrProfile);
  AsmReadIdtr (&AcpiCpuDataEx->IdtrProfile);

  //
  // Allocate GDT and IDT and copy current GDT and IDT contents
  //
  GdtSize = AcpiCpuDataEx->GdtrProfile.Limit + 1;
  IdtSize = AcpiCpuDataEx->IdtrProfile.Limit + 1;
  Gdt = AllocateZeroPages (GdtSize + IdtSize);
  ASSERT (Gdt != NULL);
  Idt = (VOID *)((UINTN)Gdt + GdtSize);
  CopyMem (Gdt, (VOID *)AcpiCpuDataEx->GdtrProfile.Base, GdtSize);
  CopyMem (Idt, (VOID *)AcpiCpuDataEx->IdtrProfile.Base, IdtSize);
  AcpiCpuDataEx->GdtrProfile.Base = (UINTN)Gdt;
  AcpiCpuDataEx->IdtrProfile.Base = (UINTN)Idt;

  if (OldAcpiCpuData != NULL) {
    AcpiCpuData->RegisterTable           = OldAcpiCpuData->RegisterTable;
    AcpiCpuData->PreSmmInitRegisterTable = OldAcpiCpuData->PreSmmInitRegisterTable;
    AcpiCpuData->ApLocation              = OldAcpiCpuData->ApLocation;
    CopyMem (&AcpiCpuData->CpuStatus, &OldAcpiCpuData->CpuStatus, sizeof (CPU_STATUS_INFORMATION));
  } else {
    //
    // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs
    //
    TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);
    RegisterTable = (CPU_REGISTER_TABLE *)AllocateZeroPages (TableSize);
    ASSERT (RegisterTable != NULL);

    for (Index = 0; Index < NumberOfCpus; Index++) {
      Status = MpServices->GetProcessorInfo (
                           MpServices,
                           Index,
                           &ProcessorInfoBuffer
                           );
      ASSERT_EFI_ERROR (Status);

      RegisterTable[Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;
      RegisterTable[Index].TableLength        = 0;
      RegisterTable[Index].AllocatedSize      = 0;
      RegisterTable[Index].RegisterTableEntry = 0;

      RegisterTable[NumberOfCpus + Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;
      RegisterTable[NumberOfCpus + Index].TableLength        = 0;
      RegisterTable[NumberOfCpus + Index].AllocatedSize      = 0;
      RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;
    }
    AcpiCpuData->RegisterTable           = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;
    AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);
  }

  //
  // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure
  //
  Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);
  ASSERT_EFI_ERROR (Status);

  //
  // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event.
  // The notification function allocates StartupVector and saves MTRRs for ACPI_CPU_DATA
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  CpuS3DataOnEndOfDxe,
                  AcpiCpuData,
                  &gEfiEndOfDxeEventGroupGuid,
                  &Event
                  );
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}
Example #9
0
/**
 *  AgesaRunFcnOnAp
 *
 * Description
 *    Call the host environment interface to provide a user hook opportunity.
 *
 *  @param[in]      ApicIdOfCore
 *  @param[in,out]  LaunchApParams
 *
 * @return   The AGESA Status returned from the callout.
 *
 */
AGESA_STATUS
AgesaRunFcnOnAp (
  IN       UINTN               ApicIdOfCore,
  IN       AP_EXE_PARAMS       *LaunchApParams
  )
{
  AGESA_STATUS              AgesaStatus;
  EFI_STATUS             Status;
  EFI_MP_SERVICES_PROTOCOL *MpServices;
  UINTN                  CpuData_Index;
  UINTN                     NumberOfEnabledCPUs;
  UINTN                     BufferSize;
  EFI_MP_PROC_CONTEXT      ApCoreData;

  AgesaStatus = AGESA_ERROR;
  RelatedBlockLength = LaunchApParams->RelatedBlockLength;
  RelatedDataBlock = LaunchApParams->RelatedDataBlock;
  FunctionNumber = LaunchApParams->FunctionNumber;


  Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, &MpServices);

  if (EFI_ERROR (Status)) {
    return AgesaStatus;
  }

  Status = MpServices->GetGeneralMPInfo (
                MpServices,
                0,
                0,
                &NumberOfEnabledCPUs,
                0,
                0
                );

  if (EFI_ERROR (Status)) {
    return AgesaStatus;
  }

  for (CpuData_Index = 0; CpuData_Index < NumberOfEnabledCPUs; CpuData_Index++) {
    Status = MpServices->GetProcessorContext (
                                    MpServices,
                                    CpuData_Index,
                                    &BufferSize,
                                    &ApCoreData);

    if ( ApCoreData.ApicID == (UINT32) ApicIdOfCore ) {
      break;
    }
  }

  Status = MpServices->StartupThisAP (
           MpServices,
           (EFI_AP_PROCEDURE) AgesaLaunchApForGivenTask,
           CpuData_Index,
           NULL,
           0,
           NULL
           );

  if (!EFI_ERROR (Status))  {
    AgesaStatus = AGESA_SUCCESS;
  }

  return AgesaStatus;
}