Ejemplo n.º 1
0
/*++

Routine Description:



Arguments:

  FileHandle  - Handle of the file being invoked.
  PeiServices - Describes the list of possible PEI Services.

Returns:

  Status -  EFI_SUCCESS if the boot mode could be set

--*/
EFI_STATUS
EFIAPI
InitializePlatformPeim (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS                    Status;
  EFI_BOOT_MODE                 BootMode;

  DEBUG ((EFI_D_LOAD | EFI_D_INFO, "Platform PEIM Loaded\n"));

  Status = PeiServicesSetBootMode (ArmPlatformGetBootMode ());
  ASSERT_EFI_ERROR (Status);

  PlatformPeim ();

  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);

  Status = PeiServicesInstallPpi (&mPpiListBootMode);
  ASSERT_EFI_ERROR (Status);

  if (BootMode == BOOT_IN_RECOVERY_MODE) {
    Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode);
    ASSERT_EFI_ERROR (Status);
  }

  return Status;
}
Ejemplo n.º 2
0
/**
  Install FSP notification.

  @param[in] NotificationCode  FSP notification code

  @retval EFI_SUCCESS            Notify FSP successfully
  @retval EFI_INVALID_PARAMETER  NotificationCode is invalid

**/
EFI_STATUS
EFIAPI
FspNotificationHandler (
  IN  UINT32     NotificationCode
  )
{
  EFI_STATUS                Status;

  Status   = EFI_SUCCESS;

  switch (NotificationCode) {
  case EnumInitPhaseAfterPciEnumeration:
    //
    // Do POST PCI initialization if needed
    //
    DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n"));
    PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi);
    break;

  case EnumInitPhaseReadyToBoot:
    //
    // Ready To Boot
    //
    DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n"));
    PeiServicesInstallPpi (&mPeiReadyToBootPpi);
    break;

  default:
    Status = EFI_INVALID_PARAMETER;
    break;
  }

  return Status;
}
Ejemplo n.º 3
0
Archivo: Pcd.c Proyecto: iderzh/edk2
/**
  Main entry for PCD PEIM driver.
  
  This routine initialize the PCD database for PEI phase and install PCD_PPI/EFI_PEI_PCD_PPI.

  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services.

  @return Status of install PCD_PPI

**/
EFI_STATUS
EFIAPI
PcdPeimInit (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS Status;

  BuildPcdDatabase (FileHandle);

  //
  // Install PCD_PPI and EFI_PEI_PCD_PPI.
  //
  Status = PeiServicesInstallPpi (&mPpiList[0]);
  ASSERT_EFI_ERROR (Status);

  //
  // Install GET_PCD_INFO_PPI and EFI_GET_PCD_INFO_PPI.
  //
  Status = PeiServicesInstallPpi (&mPpiList2[0]);
  ASSERT_EFI_ERROR (Status);

  return Status;
}
Ejemplo n.º 4
0
/**
  Entry point of DXE IPL PEIM.
  
  This function installs DXE IPL PPI and Decompress PPI.  It also reloads
  itself to memory on non-S3 resume boot path.

  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services.

  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.
  @retval Others      Some error occurs during the execution of this function. 

**/
EFI_STATUS
EFIAPI
PeimInitializeDxeIpl (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS                                Status;
  EFI_BOOT_MODE                             BootMode;
  EFI_GUID                                  *ExtractHandlerGuidTable;
  UINTN                                     ExtractHandlerNumber;
  EFI_PEI_PPI_DESCRIPTOR                    *GuidPpi;
  
  BootMode = GetBootModeHob ();

  if (BootMode != BOOT_ON_S3_RESUME) {
    Status = PeiServicesRegisterForShadow (FileHandle);
    if (Status == EFI_SUCCESS) {
      //
      // EFI_SUCESS means it is the first time to call register for shadow. 
      // 
      return Status;
    }
    
    //
    // Ensure that DXE IPL is shadowed to permanent memory.
    //
    ASSERT (Status == EFI_ALREADY_STARTED);
     
    //
    // Get custom extract guided section method guid list 
    //
    ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
    
    //
    // Install custom extraction guid PPI
    //
    if (ExtractHandlerNumber > 0) {
      GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
      ASSERT (GuidPpi != NULL);
      while (ExtractHandlerNumber-- > 0) {
        GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
        GuidPpi->Ppi   = (VOID *) &mCustomGuidedSectionExtractionPpi;
        GuidPpi->Guid  = &ExtractHandlerGuidTable[ExtractHandlerNumber];
        Status = PeiServicesInstallPpi (GuidPpi++);
        ASSERT_EFI_ERROR(Status);
      }
    }
    
  }
  
  //
  // Install DxeIpl and Decompress PPIs.
  //
  Status = PeiServicesInstallPpi (mPpiList);
  ASSERT_EFI_ERROR(Status);

  return Status;
}
Ejemplo n.º 5
0
/**
  Jump to OS waking vector.
  The function will install boot script done PPI, report S3 resume status code, and then jump to OS waking vector.

  @param  AcpiS3Context                 a pointer to a structure of ACPI_S3_CONTEXT
  @param  PeiS3ResumeState              a pointer to a structure of PEI_S3_RESUME_STATE
**/
VOID
EFIAPI
S3ResumeBootOs (
  IN ACPI_S3_CONTEXT                *AcpiS3Context,
  IN PEI_S3_RESUME_STATE            *PeiS3ResumeState
  )
{
  EFI_STATUS                                    Status;
  EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE  *Facs;
  ASM_TRANSFER_CONTROL                          AsmTransferControl;
  UINTN                                         TempStackTop;
  UINTN                                         TempStack[0x10];

  //
  // Restore IDT
  //
  AsmWriteIdtr (&PeiS3ResumeState->Idtr);

  //
  // Install BootScriptDonePpi
  //
  Status = PeiServicesInstallPpi (&mPpiListPostScriptTable);
  ASSERT_EFI_ERROR (Status);

  //
  // Get ACPI Table Address
  //
  Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable));

  if ((Facs == NULL) ||
      (Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
      ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)) ) {
    CpuDeadLoop ();
    return ;
  }

  //
  // report status code on S3 resume
  //
  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE);

  //
  // Install EndOfPeiPpi
  //
  Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable);
  ASSERT_EFI_ERROR (Status);

  PERF_CODE (
    WriteToOsS3PerformanceData ();
    );
Ejemplo n.º 6
0
/**
  The Entry point of the CPU I/O PEIM

  This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi.

  @param[in]  FileHandle   Pointer to image file handle.
  @param[in]  PeiServices  Pointer to PEI Services Table

  @retval EFI_SUCCESS  CPU I/O PPI successfully installed

**/
EFI_STATUS
EFIAPI
CpuIoInitialize (
  IN EFI_PEI_FILE_HANDLE     FileHandle,
  IN CONST EFI_PEI_SERVICES  **PeiServices
  )
{
  EFI_STATUS  Status;

  //
  // Register so it will be automatically shadowed to memory
  //
  Status = PeiServicesRegisterForShadow (FileHandle);

  //
  // Make CpuIo pointer in PeiService table point to gCpuIoPpi
  //
  (*((EFI_PEI_SERVICES **)PeiServices))->CpuIo = &gCpuIoPpi;

  if (Status == EFI_ALREADY_STARTED) {
    //
    // Shadow completed and running from memory
    //
    DEBUG ((EFI_D_INFO, "CpuIO PPI has been loaded into memory.  Reinstalled PPI=0x%x\n", &gCpuIoPpi));
  } else {
    Status = PeiServicesInstallPpi (&gPpiList);
    ASSERT_EFI_ERROR (Status);
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 7
0
/**
   Transfers control to DxeCore.

   This function performs a CPU architecture specific operations to execute
   the entry point of DxeCore with the parameters of HobList.
   It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.

   @param DxeCoreEntryPoint         The entry point of DxeCore.
   @param HobList                   The start of HobList passed to DxeCore.

**/
VOID
HandOffToDxeCore (
  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
  IN EFI_PEI_HOB_POINTERS   HobList
  )
{
  VOID                *BaseOfStack;
  VOID                *TopOfStack;
  EFI_STATUS          Status;
  UINTN               PageTables;

  //
  // Allocate 128KB for the Stack
  //
  BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
  ASSERT (BaseOfStack != NULL);

  //
  // Compute the top of the stack we were allocated. Pre-allocate a UINTN
  // for safety.
  //
  TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
  TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);

  PageTables = 0;
  if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
    //
    // Create page table and save PageMapLevel4 to CR3
    //
    PageTables = CreateIdentityMappingPageTables ();
  }
  
  //
  // End of PEI phase signal
  //
  Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
  ASSERT_EFI_ERROR (Status);

  if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
    AsmWriteCr3 (PageTables);
  }

  //
  // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
  //    
  UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE);

  //
  // Transfer the control to the entry point of DxeCore.
  //
  SwitchStack (
    (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
    HobList.Raw,
    NULL,
    TopOfStack
    );
}
Ejemplo n.º 8
0
/**
  Entry point of this module.

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return Status.

**/
EFI_STATUS
EFIAPI
PeimEntryMA (
  IN       EFI_PEI_FILE_HANDLE      FileHandle,
  IN CONST EFI_PEI_SERVICES         **PeiServices
  )
{
  EFI_STATUS                        Status;
  EFI_BOOT_MODE                     BootMode;
  TIS_TPM_HANDLE                    TpmHandle;

  if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
    return EFI_UNSUPPORTED;
  }

  Status = (**PeiServices).RegisterForShadow(FileHandle);
  if (Status == EFI_ALREADY_STARTED) {
    mImageInMemory = TRUE;
  } else if (Status == EFI_NOT_FOUND) {
    ASSERT_EFI_ERROR (Status);
  }

  if (!mImageInMemory) {
    //
    // Initialize TPM device
    //
    Status = PeiServicesGetBootMode (&BootMode);
    ASSERT_EFI_ERROR (Status);

    TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
    Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
      return Status;
    }

    Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);
    if (EFI_ERROR (Status) ) {
      return Status;
    }
    Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
    ASSERT_EFI_ERROR (Status);
  }

  if (mImageInMemory) {
    Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return Status;
}
Ejemplo n.º 9
0
/**
  Provide the functionality of the variable services.

  @param  FileHandle   Handle of the file being invoked.
                       Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().
  @param  PeiServices  General purpose services available to every PEIM.

  @retval EFI_SUCCESS  If the interface could be successfully installed
  @retval Others       Returned from PeiServicesInstallPpi()
**/
EFI_STATUS
EFIAPI
PeimInitializeVariableServices (
    IN       EFI_PEI_FILE_HANDLE       FileHandle,
    IN CONST EFI_PEI_SERVICES          **PeiServices
)
{
    return PeiServicesInstallPpi (&mPpiListVariable);
}
Ejemplo n.º 10
0
/**
  Entry point of this module.

  It installs lock physical presence PPI.

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return                 Status of install lock physical presence PPI.

**/
EFI_STATUS
EFIAPI
PeimEntry (
  IN       EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES          **PeiServices
  )
{
  return PeiServicesInstallPpi (&mLockPhysicalPresencePpiList);
}
Ejemplo n.º 11
0
/**
   This function installs the PPIs that require permanent memory.

   @param  PeiServices      Indirect reference to the PEI Services Table.
   @param  NotifyDescriptor Address of the notification descriptor data structure.
   @param  Ppi              Address of the PPI that was installed.

   @return EFI_SUCCESS      The PPIs were installed successfully.
   @return Others           Some error occurs during the execution of this function.

**/
EFI_STATUS
EFIAPI
InstallIplPermanentMemoryPpis (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  EFI_STATUS                    Status;
  EFI_GUID                      *ExtractHandlerGuidTable;
  UINTN                         ExtractHandlerNumber;
  EFI_PEI_PPI_DESCRIPTOR        *GuidPpi;

  //
  // Get custom extract guided section method guid list
  //
  ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);

  //
  // Install custom guided section extraction PPI
  //
  if (ExtractHandlerNumber > 0) {
    GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
    ASSERT (GuidPpi != NULL);
    while (ExtractHandlerNumber-- > 0) {
      GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
      GuidPpi->Ppi   = (VOID *) &mCustomGuidedSectionExtractionPpi;
      GuidPpi->Guid  = &ExtractHandlerGuidTable[ExtractHandlerNumber];
      Status = PeiServicesInstallPpi (GuidPpi++);
      ASSERT_EFI_ERROR(Status);
    }
  }

  //
  // Install Decompress PPI.
  //
  Status = PeiServicesInstallPpi (&mDecompressPpiList);
  ASSERT_EFI_ERROR(Status);

  return Status;
}
Ejemplo n.º 12
0
VOID
BootModeInitialization (
  )
{
  EFI_STATUS Status;

  Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
  ASSERT_EFI_ERROR (Status);

  Status = PeiServicesInstallPpi (mPpiBootMode);
  ASSERT_EFI_ERROR (Status);
}
Ejemplo n.º 13
0
/**
  Entry point of DXE IPL PEIM.

  This function installs DXE IPL PPI and Decompress PPI.  It also reloads
  itself to memory on non-S3 resume boot path.

  @param[in] FileHandle  Handle of the file being invoked.
  @param[in] PeiServices Describes the list of possible PEI Services.

  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.
  @retval Others      Some error occurs during the execution of this function.

**/
EFI_STATUS
EFIAPI
PeimInitializeDxeIpl (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS                                Status;
  EFI_GUID                                  *ExtractHandlerGuidTable;
  UINTN                                     ExtractHandlerNumber;
  EFI_PEI_PPI_DESCRIPTOR                    *GuidPpi;

  //
  // Get custom extract guided section method guid list
  //
  ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);

  //
  // Install custom extraction guid PPI
  //
  if (ExtractHandlerNumber > 0) {
    GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
    ASSERT (GuidPpi != NULL);
    while (ExtractHandlerNumber-- > 0) {
      GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
      GuidPpi->Ppi   = (VOID *) &mCustomGuidedSectionExtractionPpi;
      GuidPpi->Guid  = &ExtractHandlerGuidTable[ExtractHandlerNumber];
      Status = PeiServicesInstallPpi (GuidPpi++);
      ASSERT_EFI_ERROR(Status);
    }
  }

  //
  // Install DxeIpl and Decompress PPIs.
  //
  Status = PeiServicesInstallPpi (mPpiList);
  ASSERT_EFI_ERROR(Status);

  return Status;
}
Ejemplo n.º 14
0
/**
   Main entry point to last PEIM.

   This function finds DXE Core in the firmware volume and transfer the control to
   DXE core.

   @param[in] This          Entry point for DXE IPL PPI.
   @param[in] PeiServices   General purpose services available to every PEIM.
   @param[in] HobList       Address to the Pei HOB list.

   @return EFI_SUCCESS              DXE core was successfully loaded.
   @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.

**/
EFI_STATUS
EFIAPI
DxeLoadCore (
  IN CONST EFI_DXE_IPL_PPI *This,
  IN EFI_PEI_SERVICES      **PeiServices,
  IN EFI_PEI_HOB_POINTERS  HobList
  )
{
  EFI_STATUS   Status;

  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList));

  //
  // End of PEI phase signal
  //
  Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
  ASSERT_EFI_ERROR (Status);

  //
  // Give control back to BootLoader after FspInit
  //
  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));
  FspInitDone ();

  //
  // BootLoader called FSP again through NotifyPhase
  //
  FspWaitForNotify ();


  //
  // Give control back to the boot loader framework caller
  //
  DEBUG ((DEBUG_INFO | DEBUG_INIT,   "============= PEIM FSP is Completed =============\n\n"));

  SetFspApiReturnStatus(EFI_SUCCESS);

  SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_RDYBOOT_EXIT);

  Pei2LoaderSwitchStack();

  //
  // Should not come here
  //
  while (TRUE) {
    DEBUG ((DEBUG_ERROR, "No FSP API should be called after FSP is DONE!\n"));
    SetFspApiReturnStatus(EFI_UNSUPPORTED);
    Pei2LoaderSwitchStack();
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 15
0
EFI_STATUS
EFIAPI
BoardDetectionCallback (
  IN CONST EFI_PEI_SERVICES     **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  EFI_STATUS   Status;
  VOID         *Instance;
  
  DEBUG ((EFI_D_INFO, "Detecting Galileo ...\n"));
  //
  // Check if board detection is finished.
  //
  Status = PeiServicesLocatePpi (
             &gBoardDetectedPpiGuid,
             0,
             NULL,
             &Instance
             );
  if (!EFI_ERROR(Status)) {
    return EFI_SUCCESS;
  }

  //
  // In most real platform, here should be the code to detect board type.
  // 
  // For galileo, we only support build time board selection, so use PCD to do the fake detection.
  //
  if (PcdGet16(PcdPlatformType) != Galileo) {
    return EFI_UNSUPPORTED;
  }
  DEBUG ((EFI_D_INFO, "Detected Galileo!\n"));

  Status = PcdSet64S (PcdBoardInitPreMem, (UINT64)(UINTN)BoarInitPreMem);
  ASSERT_EFI_ERROR(Status);
  Status = PcdSet64S (PcdBoardInitPostMem, (UINT64)(UINTN)BoarInitPostMem);
  ASSERT_EFI_ERROR(Status);

  Status = PcdSet32S (PcdPciExpPerstResumeWellGpio, PCIEXP_PERST_RESUMEWELL_GPIO);
  ASSERT_EFI_ERROR(Status);
  Status = PcdSet32S (PcdFlashUpdateLedResumeWellGpio, GALILEO_FLASH_UPDATE_LED_RESUMEWELL_GPIO);
  ASSERT_EFI_ERROR(Status);

  Status = PeiServicesInstallPpi(&mDetectedPpi);
  ASSERT_EFI_ERROR(Status);
  return Status;
}
Ejemplo n.º 16
0
/**
  Module's entry function.
  This routine will install EFI_PEI_PCI_CFG2_PPI.

  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services.

  @return Whether success to install service.
**/
EFI_STATUS
EFIAPI
PeimInitializePciCfg (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS            Status;

  (**(EFI_PEI_SERVICES **)PeiServices).PciCfg = &gPciCfg2Ppi;
  Status = PeiServicesInstallPpi (&gPciCfg2PpiList);
  ASSERT_EFI_ERROR (Status);

  return Status;
}
Ejemplo n.º 17
0
/**
  Entry Point for PI SMM communication PEIM.

  @param  FileHandle              Handle of the file being invoked.
  @param  PeiServices             Pointer to PEI Services table.

  @retval EFI_SUCEESS     
  @return Others          Some error occurs.
**/
EFI_STATUS
EFIAPI
PiSmmCommunicationPeiEntryPoint (
  IN EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES    **PeiServices
  )
{
  EFI_STATUS                      Status;
  PEI_SMM_ACCESS_PPI              *SmmAccess;
  EFI_BOOT_MODE                   BootMode;
  UINTN                           Index;

  BootMode = GetBootModeHob ();
  if (BootMode != BOOT_ON_S3_RESUME) {
    return EFI_UNSUPPORTED;
  }

  Status = PeiServicesLocatePpi (
             &gPeiSmmAccessPpiGuid,
             0,
             NULL,
             (VOID **)&SmmAccess
             );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_STARTED;
  }

  //
  // Check SMRAM locked, it should be done before SMRAM lock.
  //
  if (SmmAccess->LockState) {
    DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei LockState - %x\n", (UINTN)SmmAccess->LockState));
    return EFI_ACCESS_DENIED;
  }

  //
  // Open all SMRAM
  //
  for (Index = 0; !EFI_ERROR (Status); Index++) {
    Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
  }

  InitCommunicationContext ();

  PeiServicesInstallPpi (&mPpiList);

  return RETURN_SUCCESS;
}
Ejemplo n.º 18
0
/**
   Transfers control to DxeCore.

   This function performs a CPU architecture specific operations to execute
   the entry point of DxeCore with the parameters of HobList.
   It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.

   @param DxeCoreEntryPoint         The entry point of DxeCore.
   @param HobList                   The start of HobList passed to DxeCore.

**/
VOID
HandOffToDxeCore (
  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
  IN EFI_PEI_HOB_POINTERS   HobList
  )
{
  VOID                *BaseOfStack;
  VOID                *TopOfStack;
  EFI_STATUS          Status;

  //
  // Allocate 128KB for the Stack
  //
  BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
  ASSERT (BaseOfStack != NULL);

  if (PcdGetBool (PcdSetNxForStack)) {
    Status = ArmSetMemoryRegionNoExec ((UINTN)BaseOfStack, STACK_SIZE);
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Compute the top of the stack we were allocated. Pre-allocate a UINTN
  // for safety.
  //
  TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
  TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);

  //
  // End of PEI phase singal
  //
  Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
  ASSERT_EFI_ERROR (Status);

  //
  // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
  //    
  UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE);

  SwitchStack (
    (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
    HobList.Raw,
    NULL,
    TopOfStack
    );
}
Ejemplo n.º 19
0
VOID
BootModeInitialization (
  VOID
  )
{
  EFI_STATUS    Status;

  if (CmosRead8 (0xF) == 0xFE) {
    mBootMode = BOOT_ON_S3_RESUME;
  }

  Status = PeiServicesSetBootMode (mBootMode);
  ASSERT_EFI_ERROR (Status);

  Status = PeiServicesInstallPpi (mPpiBootMode);
  ASSERT_EFI_ERROR (Status);
}
Ejemplo n.º 20
0
/**
   Transfers control to DxeCore.

   This function performs a CPU architecture specific operations to execute
   the entry point of DxeCore with the parameters of HobList.
   It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.

   @param DxeCoreEntryPoint         The entry point of DxeCore.
   @param HobList                   The start of HobList passed to DxeCore.

**/
VOID
HandOffToDxeCore (
  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
  IN EFI_PEI_HOB_POINTERS   HobList
  )
{
  VOID                            *BaseOfStack;
  VOID                            *TopOfStack;
  EFI_STATUS                      Status;
  //
  //
  // Allocate 128KB for the Stack
  //
  BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
  ASSERT (BaseOfStack != NULL);

  //
  // Compute the top of the stack we were allocated. Pre-allocate a UINTN
  // for safety.
  //
  TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
  TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);

  //
  // End of PEI phase signal
  //
  Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
  ASSERT_EFI_ERROR (Status);

  //
  // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
  //    
  UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE);

  DEBUG ((EFI_D_INFO, "DXE Core new stack at %x, stack pointer at %x\n", BaseOfStack, TopOfStack));

  //
  // Transfer the control to the entry point of DxeCore.
  //
  SwitchStack (
    (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
    HobList.Raw,
    NULL,
    TopOfStack
    );
}
Ejemplo n.º 21
0
/**

   This function waits for FSP notify.

   @param This          Entry point for DXE IPL PPI.
   @param PeiServices   General purpose services available to every PEIM.
   @param HobList       Address to the Pei HOB list.

   @return EFI_SUCCESS              This function never returns.

**/
EFI_STATUS
EFIAPI
WaitForNotify (
  IN CONST EFI_DXE_IPL_PPI *This,
  IN EFI_PEI_SERVICES      **PeiServices,
  IN EFI_PEI_HOB_POINTERS  HobList
  )
{
  EFI_STATUS   Status;

  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList));

  //
  // End of PEI phase signal
  //
  Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
  ASSERT_EFI_ERROR (Status);

  //
  // Give control back to BootLoader after FspSiliconInit
  //
  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));
  FspSiliconInitDone2 (EFI_SUCCESS);

  //
  // BootLoader called FSP again through NotifyPhase
  //
  FspWaitForNotify ();

  if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
    //
    // Should not come here
    //
    while (TRUE) {
      DEBUG ((DEBUG_ERROR, "No FSP API should be called after FSP is DONE!\n"));
      SetFspApiReturnStatus (EFI_UNSUPPORTED);
      Pei2LoaderSwitchStack ();
    }
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 22
0
/**
  The Entry point of the CPU PEIM

  This function is the Entry point of the CPU PEIM which will install the CachePpi and 
  BuildBISTHob notifier. And also the function will deal with the relocation to memory when 
  permanent memory is ready
 
  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services. 
                          
  @retval EFI_SUCCESS   CachePpi and BIST hob build notification is installed
                        successfully.

**/
EFI_STATUS
EFIAPI
CpuPeimInit (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
	EFI_STATUS  Status;

  //
  // Report Status Code to indicate the start of CPU PEIM
  //
  REPORT_STATUS_CODE (
    EFI_PROGRESS_CODE,
    EFI_COMPUTING_UNIT_HOST_PROCESSOR + EFI_CU_HP_PC_POWER_ON_INIT
    );

  //
  // Install PPIs
  //
  Status = PeiServicesInstallPpi(&mPpiList[0]);
  ASSERT_EFI_ERROR (Status);

  //
  // Register for PPI Notifications
  //
  Status = PeiServicesNotifyPpi (&mNotifyList[0]);
  ASSERT_EFI_ERROR (Status);

  //
  // Report Status Code to indicate the start of CPU PEI initialization
  //
  REPORT_STATUS_CODE (
    EFI_PROGRESS_CODE,
    EFI_COMPUTING_UNIT_HOST_PROCESSOR + EFI_CU_PC_INIT_BEGIN
    );
   
  InitXMM ();
  
  return Status;
}
Ejemplo n.º 23
0
Archivo: Image.c Proyecto: B-Rich/edk2
/**

  Install Pei Load File PPI.


  @param PrivateData     - Pointer to PEI_CORE_INSTANCE.
  @param OldCoreData     - Pointer to PEI_CORE_INSTANCE.

**/
VOID
InitializeImageServices (
  IN  PEI_CORE_INSTANCE   *PrivateData,
  IN  PEI_CORE_INSTANCE   *OldCoreData
  )
{
  if (OldCoreData == NULL) {
    //
    // The first time we are XIP (running from FLASH). We need to remember the
    // FLASH address so we can reinstall the memory version that runs faster
    //
    PrivateData->XipLoadFile = &gPpiLoadFilePpiList;
    PeiServicesInstallPpi (PrivateData->XipLoadFile);
  } else {
    //
    // 2nd time we are running from memory so replace the XIP version with the
    // new memory version.
    //
    PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList);
  }
}
Ejemplo n.º 24
0
/**
  FSP notify phase PEI module entry point

  @param[in]  FileHandle           Not used.
  @param[in]  PeiServices          General purpose services available to every PEIM.

  @retval     EFI_SUCCESS          The function completes successfully
  @retval     EFI_OUT_OF_RESOURCES Insufficient resources to create database
**/
EFI_STATUS
FspNotifyPhasePeimEntryPoint (
  IN       EFI_PEI_FILE_HANDLE    FileHandle,
  IN CONST EFI_PEI_SERVICES       **PeiServices
  )
{
  EFI_STATUS                      Status;
  VOID                            *OldDxeIplPpi;
  EFI_PEI_PPI_DESCRIPTOR          *OldDescriptor;

  DEBUG ((DEBUG_INFO | DEBUG_INIT, "The entry of FspNotificationPeim\n"));

  if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
    //
    // Locate old DXE IPL PPI
    //
    Status = PeiServicesLocatePpi (
              &gEfiDxeIplPpiGuid,
              0,
              &OldDescriptor,
              &OldDxeIplPpi
              );
    ASSERT_EFI_ERROR (Status);

    //
    // Re-install the DXE IPL PPI to wait for notify
    //
    Status = PeiServicesReInstallPpi (OldDescriptor, &mInstallDxeIplPpi);
    ASSERT_EFI_ERROR (Status);
  } else {
    Status = PeiServicesInstallPpi (&gFspReadyForNotifyPhasePpi);
    ASSERT_EFI_ERROR (Status);
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 25
0
/**
  This is the entrypoint of PEIM

  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services.

  @retval EFI_SUCCESS if it completed successfully.
**/
EFI_STATUS
EFIAPI
CbPeiEntryPoint (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS           Status;
  UINT64               LowMemorySize;
  UINT64               PeiMemSize = SIZE_64MB;   // 64 MB
  EFI_PHYSICAL_ADDRESS PeiMemBase = 0;
  UINT32               RegEax;
  UINT8                PhysicalAddressBits;
  VOID*                pCbHeader;
  VOID*                pAcpiTable;
  UINT32               AcpiTableSize;
  VOID*                pSmbiosTable;
  UINT32               SmbiosTableSize;
  SYSTEM_TABLE_INFO*   pSystemTableInfo;
  FRAME_BUFFER_INFO    FbInfo;
  FRAME_BUFFER_INFO*   pFbInfo;
  ACPI_BOARD_INFO*     pAcpiBoardInfo;
  UINTN                PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;
  UINTN                PmEvtBase;
  UINTN                PmGpeEnBase;
  CB_MEM_INFO          CbMemInfo;

  //
  // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED  
  // is intentionally omitted to prevent erasing of the coreboot header  
  // record before it is processed by CbParseMemoryInfo.
  //
  BuildResourceDescriptorHob (
    EFI_RESOURCE_SYSTEM_MEMORY,
    (
    EFI_RESOURCE_ATTRIBUTE_PRESENT |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    // Lower 640KB, except for first 4KB where the lower coreboot pointer ("LBIO") resides
    (EFI_PHYSICAL_ADDRESS)(0 + 0x1000),
    (UINT64)(0xA0000 - 0x1000)
    );


  BuildResourceDescriptorHob (
    EFI_RESOURCE_MEMORY_RESERVED,
    (
    EFI_RESOURCE_ATTRIBUTE_PRESENT |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_TESTED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0xA0000),
    (UINT64)(0x60000)
    );

  ZeroMem (&CbMemInfo, sizeof(CbMemInfo));
  Status = CbParseMemoryInfo (CbMemInfoCallback, (VOID *)&CbMemInfo);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  LowMemorySize = CbMemInfo.UsableLowMemTop;
  DEBUG ((EFI_D_INFO, "Low memory 0x%lx\n", LowMemorySize));
  DEBUG ((EFI_D_INFO, "SystemLowMemTop 0x%x\n", CbMemInfo.SystemLowMemTop));

  //
  // Should be 64k aligned
  //
  PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));

  DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));
  DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize));

  Status = PeiServicesInstallPeiMemory (
         PeiMemBase,
         PeiMemSize
         );
  ASSERT_EFI_ERROR (Status);

  //
  // Set cache on the physical memory
  //
  MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);
  MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);

  //
  // Create Memory Type Information HOB
  //
  BuildGuidDataHob (
    &gEfiMemoryTypeInformationGuid,
    mDefaultMemoryTypeInformation,
    sizeof(mDefaultMemoryTypeInformation)
    );

  //
  // Create Fv hob
  //
  CbPeiReportRemainedFvs ();

  BuildMemoryAllocationHob (
    PcdGet32 (PcdPayloadFdMemBase),
    PcdGet32 (PcdPayloadFdMemSize),
    EfiBootServicesData
    );

  //
  // Build CPU memory space and IO space hob
  //
  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
  if (RegEax >= 0x80000008) {
    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
    PhysicalAddressBits = (UINT8) RegEax;
  } else {
    PhysicalAddressBits  = 36;
  }
  //
  // Create a CPU hand-off information
  //
  BuildCpuHob (PhysicalAddressBits, 16);

  //
  // Report Local APIC range
  //
  BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);

  //
  // Boot mode
  //
  Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
  ASSERT_EFI_ERROR (Status);

  Status = PeiServicesInstallPpi (mPpiBootMode);
  ASSERT_EFI_ERROR (Status);

   //
  // Set pcd to save the upper coreboot header in case the dxecore will
  // erase 0~4k memory
  //
  pCbHeader = NULL;
  if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)
    && ((UINTN)pCbHeader > BASE_4KB)) {
    DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader));
    Status = PcdSet32S (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Create guid hob for system tables like acpi table and smbios table
  //
  pAcpiTable = NULL;
  AcpiTableSize = 0;
  pSmbiosTable = NULL;
  SmbiosTableSize = 0;
  Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);
  if (EFI_ERROR (Status)) {
    // ACPI table is oblidgible
    DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));
    ASSERT (FALSE);
  }
  CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);

  pSystemTableInfo = NULL;
  pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));
  ASSERT (pSystemTableInfo != NULL);
  pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;
  pSystemTableInfo->AcpiTableSize = AcpiTableSize;
  pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;
  pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;
  DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));
  DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));
  DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));

  //
  // Create guid hob for acpi board information
  //
  Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue, &PmEvtBase, &PmGpeEnBase);
  ASSERT_EFI_ERROR (Status);
  pAcpiBoardInfo = NULL;
  pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));
  ASSERT (pAcpiBoardInfo != NULL);
  pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;
  pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;
  pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;
  pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;
  pAcpiBoardInfo->PmEvtBase = (UINT64)PmEvtBase;
  pAcpiBoardInfo->PmGpeEnBase = (UINT64)PmGpeEnBase;
  DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));

  //
  // Create guid hob for frame buffer information
  //
  ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));
  Status = CbParseFbInfo (&FbInfo);
  if (!EFI_ERROR (Status)) {
    pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));
    ASSERT (pSystemTableInfo != NULL);
    CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));
    DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));
  }

  //
  // Parse platform specific information from coreboot. 
  //
  Status = CbParsePlatformInfo ();
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Error when parsing platform info, Status = %r\n", Status));
    return Status;
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 26
0
/**
  Initialize debug agent.

  This function is used to set up debug environment for SEC and PEI phase.

  If InitFlag is DEBUG_AGENT_INIT_PREMEM_SEC, it will overirde IDT table entries
  and initialize debug port. It will enable interrupt to support break-in feature.
  It will set up debug agent Mailbox in cache-as-ramfrom. It will be called before
  physical memory is ready.
  If InitFlag is DEBUG_AGENT_INIT_POSTMEM_SEC, debug agent will build one GUIDed
  HOB to copy debug agent Mailbox. It will be called after physical memory is ready.

  This function is used to set up debug environment to support source level debugging.
  If certain Debug Agent Library instance has to save some private data in the stack,
  this function must work on the mode that doesn't return to the caller, then
  the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one
  function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is
  responsible to invoke the passing-in function at the end of InitializeDebugAgent().

  If the parameter Function is not NULL, Debug Agent Library instance will invoke it by
  passing in the Context to be its parameter.

  If Function() is NULL, Debug Agent Library instance will return after setup debug
  environment.

  @param[in] InitFlag     Init flag is used to decide the initialize process.
  @param[in] Context      Context needed according to InitFlag; it was optional.
  @param[in] Function     Continue function called by debug agent library; it was
                          optional.

**/
VOID
EFIAPI
InitializeDebugAgent (
  IN UINT32                InitFlag,
  IN VOID                  *Context, OPTIONAL
  IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL
  )
{
  DEBUG_AGENT_MAILBOX              *Mailbox;
  DEBUG_AGENT_MAILBOX              *NewMailbox;
  DEBUG_AGENT_MAILBOX              MailboxInStack;
  DEBUG_AGENT_PHASE2_CONTEXT       Phase2Context;
  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  *DebugAgentContext;
  EFI_STATUS                       Status;
  IA32_DESCRIPTOR                  *Ia32Idtr;
  IA32_IDT_ENTRY                   *Ia32IdtEntry;
  UINT64                           DebugPortHandle;
  UINT64                           MailboxLocation;
  UINT64                           *MailboxLocationPointer;
  EFI_PHYSICAL_ADDRESS             Address;
  UINT32                           DebugTimerFrequency;
  BOOLEAN                          CpuInterruptState;

  //
  // Disable interrupts and save current interrupt state
  //
  CpuInterruptState = SaveAndDisableInterrupts();

  switch (InitFlag) {

  case DEBUG_AGENT_INIT_PREMEM_SEC:

    InitializeDebugIdt ();

    MailboxLocation = (UINT64)(UINTN)&MailboxInStack;
    Mailbox = &MailboxInStack;
    ZeroMem ((VOID *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
    //
    // Get and save debug port handle and set the length of memory block.
    //
    SetLocationSavedMailboxPointerInIdtEntry (&MailboxLocation);
    //
    // Force error message could be printed during the first shakehand between Target/HOST.
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DEBUG_AGENT_ERROR);
    //
    // Save init arch type when debug agent initialized
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL);
    //
    // Initialize Debug Timer hardware and save its frequency
    //
    InitializeDebugTimer (&DebugTimerFrequency, TRUE);
    UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);

    Phase2Context.InitFlag = InitFlag;
    Phase2Context.Context  = Context;
    Phase2Context.Function = Function;
    DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);
    //
    // If reaches here, it means Debug Port initialization failed.
    //
    DEBUG ((EFI_D_ERROR, "Debug Agent: Debug port initialization failed.\n"));

    break;

  case DEBUG_AGENT_INIT_POSTMEM_SEC:
    Mailbox = GetMailboxPointer ();
    //
    // Memory has been ready
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
    if (IsHostAttached ()) {
      //
      // Trigger one software interrupt to inform HOST
      //
      TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
    }
    //
    // Install Vector Handoff Info PPI to persist vectors used by Debug Agent
    //
    Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n"));
      CpuDeadLoop ();
    }
    //
    // Fix up Debug Port handle address and mailbox address
    //
    DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *) Context;
    if (DebugAgentContext != NULL) {
      DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset);
      UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
      Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->StackMigrateOffset);
      MailboxLocation = (UINT64)(UINTN)Mailbox;
      //
      // Build mailbox location in HOB and fix-up its address
      //
      MailboxLocationPointer = BuildGuidDataHob (
                                 &gEfiDebugAgentGuid,
                                 &MailboxLocation,
                                 sizeof (UINT64)
                                 );
      MailboxLocationPointer = (UINT64 *) ((UINTN) MailboxLocationPointer + DebugAgentContext->HeapMigrateOffset);
    } else {
      //
      // DebugAgentContext is NULL. Then, Mailbox can directly be copied into memory.
      // Allocate ACPI NVS memory for new Mailbox and Debug Port Handle buffer
      //
      Status = PeiServicesAllocatePages (
                 EfiACPIMemoryNVS,
                 EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)),
                 &Address
                 );
      if (EFI_ERROR (Status)) {
        DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to allocate pages!\n"));
        CpuDeadLoop ();
      }
      NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;
      //
      // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox
      // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core
      // reallocates the HOB.
      //
      CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
      CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize));
      UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));
      MailboxLocation = (UINT64)(UINTN)NewMailbox;
      //
      // Build mailbox location in HOB
      //
      MailboxLocationPointer = BuildGuidDataHob (
                                 &gEfiDebugAgentGuid,
                                 &MailboxLocation,
                                 sizeof (UINT64)
                                 );
    }
    //
    // Update IDT entry to save the location saved mailbox pointer
    //
    SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);
    break;

  case DEBUG_AGENT_INIT_PEI:
    if (Context == NULL) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
      CpuDeadLoop ();
    }
    //
    // Check if Debug Agent has initialized before
    //
    if (IsDebugAgentInitialzed()) {
      DEBUG ((EFI_D_WARN, "Debug Agent: It has already initialized in SEC Core!\n"));
      break;
    }
    //
    // Install Vector Handoff Info PPI to persist vectors used by Debug Agent
    //
    Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n"));
      CpuDeadLoop ();
    }
    //
    // Set up IDT entries
    //
    InitializeDebugIdt ();
    //
    // Build mailbox in HOB and setup Mailbox Set In Pei flag
    //
    Mailbox = AllocateZeroPool (sizeof (DEBUG_AGENT_MAILBOX));
    if (Mailbox == NULL) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to allocate memory!\n"));
      CpuDeadLoop ();
    } else {
      MailboxLocation = (UINT64)(UINTN)Mailbox;
      MailboxLocationPointer = BuildGuidDataHob (
                                 &gEfiDebugAgentGuid,
                                 &MailboxLocation,
                                 sizeof (UINT64)
                                 );
      //
      // Initialize Debug Timer hardware and save its frequency
      //
      InitializeDebugTimer (&DebugTimerFrequency, TRUE);
      UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);
      //
      // Update IDT entry to save the location pointer saved mailbox pointer
      //
      SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);
    }
    //
    // Save init arch type when debug agent initialized
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL);
    //
    // Register for a callback once memory has been initialized.
    // If memery has been ready, the callback funtion will be invoked immediately
    //
    Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to register memory discovered callback function!\n"));
      CpuDeadLoop ();
    }
    //
    // Set HOB check flag if memory has not been ready yet
    //
    if (GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY) == 0) {
      SetDebugFlag (DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB, 1);
    }

    Phase2Context.InitFlag = InitFlag;
    Phase2Context.Context  = Context;
    Phase2Context.Function = Function;
    DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);

    FindAndReportModuleImageInfo (4);

    break;

  case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:
    if (Context == NULL) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
      CpuDeadLoop ();
    } else {
      Ia32Idtr =  (IA32_DESCRIPTOR *) Context;
      Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
      MailboxLocationPointer = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +
                                         (UINT32) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
      Mailbox = (DEBUG_AGENT_MAILBOX *) (UINTN)(*MailboxLocationPointer);
      //
      // Mailbox should valid and setup before executing thunk code
      //
      VerifyMailboxChecksum (Mailbox);

      DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)Mailbox->DebugPortHandle, NULL);
      UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
      //
      // Set up IDT entries
      //
      InitializeDebugIdt ();
      //
      // Update IDT entry to save location pointer saved the mailbox pointer
      //
      SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);

      FindAndReportModuleImageInfo (4);
    }
    break;

  default:
    //
    // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this
    // Debug Agent library instance.
    //
    DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));
    CpuDeadLoop ();
    break;
  }

  if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) {
    //
    // Restore CPU Interrupt state and keep debug timer interrupt state as is
    // in DEBUG_AGENT_INIT_POSTMEM_SEC case
    //
    SetInterruptState (CpuInterruptState);
  } else {
    //
    // Enable Debug Timer interrupt
    //
    SaveAndSetDebugTimerInterrupt (TRUE);
    //
    // Enable CPU interrupts so debug timer interrupts can be delivered
    //
    EnableInterrupts ();
  }
  //
  // If Function is not NULL, invoke it always whatever debug agent was initialized sucesssfully or not.
  //
  if (Function != NULL) {
    Function (Context);
  }
  //
  // Set return status for DEBUG_AGENT_INIT_PEI
  //
  if (InitFlag == DEBUG_AGENT_INIT_PEI && Context != NULL) {
    *(EFI_STATUS *)Context = EFI_SUCCESS;
  }
}
Ejemplo n.º 27
0
/**
  Entry point of this module.

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return Status.

**/
EFI_STATUS
EFIAPI
PeimEntryMA (
  IN       EFI_PEI_FILE_HANDLE      FileHandle,
  IN CONST EFI_PEI_SERVICES         **PeiServices
  )
{
  EFI_STATUS                        Status;
  EFI_STATUS                        Status2;
  EFI_BOOT_MODE                     BootMode;

  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
    DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
    return EFI_UNSUPPORTED;
  }

  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
    DEBUG ((EFI_D_ERROR, "TPM error!\n"));
    return EFI_DEVICE_ERROR;
  }

  //
  // Initialize TPM device
  //
  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);

  //
  // In S3 path, skip shadow logic. no measurement is required
  //
  if (BootMode != BOOT_ON_S3_RESUME) {
    Status = (**PeiServices).RegisterForShadow(FileHandle);
    if (Status == EFI_ALREADY_STARTED) {
      mImageInMemory = TRUE;
    } else if (Status == EFI_NOT_FOUND) {
      ASSERT_EFI_ERROR (Status);
    }
  }

  if (!mImageInMemory) {
    Status = Tpm12RequestUseTpm ();
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
      goto Done;
    }

    if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {
      if (BootMode == BOOT_ON_S3_RESUME) {
        Status = Tpm12Startup (TPM_ST_STATE);
      } else {
        Status = Tpm12Startup (TPM_ST_CLEAR);
      }
      if (EFI_ERROR (Status) ) {
        goto Done;
      }
    }

    //
    // TpmSelfTest is optional on S3 path, skip it to save S3 time
    //
    if (BootMode != BOOT_ON_S3_RESUME) {
      Status = Tpm12ContinueSelfTest ();
      if (EFI_ERROR (Status)) {
        goto Done;
      }
    }

    //
    // Only intall TpmInitializedPpi on success
    //
    Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
    ASSERT_EFI_ERROR (Status);
  }

  if (mImageInMemory) {
    Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
    return Status;
  }

Done:
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "TPM error! Build Hob\n"));
    BuildGuidHob (&gTpmErrorHobGuid,0);
    REPORT_STATUS_CODE (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
      );
  }
  //
  // Always intall TpmInitializationDonePpi no matter success or fail.
  // Other driver can know TPM initialization state by TpmInitializedPpi.
  //
  Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
  ASSERT_EFI_ERROR (Status2);

  return Status;
}
Ejemplo n.º 28
0
Archivo: CpuBist.c Proyecto: OznOg/edk2
/**
  Collects BIST data from PPI.

  This function collects BIST data from Sec Platform Information2 PPI
  or SEC Platform Information PPI.

  @param PeiServices         Pointer to PEI Services Table
  @param PeiCpuMpData        Pointer to PEI CPU MP Data

**/
VOID
CollectBistDataFromPpi (
  IN CONST EFI_PEI_SERVICES             **PeiServices,
  IN PEI_CPU_MP_DATA                    *PeiCpuMpData
  )
{
  EFI_STATUS                            Status;
  EFI_PEI_PPI_DESCRIPTOR                *SecInformationDescriptor;
  EFI_SEC_PLATFORM_INFORMATION_RECORD2  *SecPlatformInformation2;
  EFI_SEC_PLATFORM_INFORMATION_RECORD   *SecPlatformInformation;
  UINTN                                 NumberOfData;
  EFI_SEC_PLATFORM_INFORMATION_CPU      *CpuInstance;
  EFI_SEC_PLATFORM_INFORMATION_CPU      BspCpuInstance;
  UINTN                                 ProcessorNumber;
  UINTN                                 CpuIndex;
  PEI_CPU_DATA                          *CpuData;

  SecPlatformInformation2 = NULL;
  SecPlatformInformation  = NULL;
  NumberOfData            = 0;
  CpuInstance             = NULL;

  //
  // Get BIST information from Sec Platform Information2 Ppi firstly
  //
  Status = GetBistInfoFromPpi (
             PeiServices,
             &gEfiSecPlatformInformation2PpiGuid,
             &SecInformationDescriptor,
             (VOID *) &SecPlatformInformation2
             );
  if (Status == EFI_SUCCESS) {
    //
    // Sec Platform Information2 PPI includes BSP/APs' BIST information
    //
    NumberOfData = SecPlatformInformation2->NumberOfCpus;
    CpuInstance  = SecPlatformInformation2->CpuInstance;
  } else {
    //
    // Otherwise, get BIST information from Sec Platform Information Ppi
    //
    Status = GetBistInfoFromPpi (
               PeiServices,
               &gEfiSecPlatformInformationPpiGuid,
               &SecInformationDescriptor,
               (VOID *) &SecPlatformInformation
               );
    if (Status == EFI_SUCCESS) {
      NumberOfData = 1;
      //
      // SEC Platform Information only includes BSP's BIST information
      // and does not have BSP's APIC ID
      //
      BspCpuInstance.CpuLocation = GetInitialApicId ();
      BspCpuInstance.InfoRecord.IA32HealthFlags.Uint32  = SecPlatformInformation->IA32HealthFlags.Uint32;
      CpuInstance = &BspCpuInstance;
    } else {
      DEBUG ((EFI_D_INFO, "Does not find any stored CPU BIST information from PPI!\n"));
    }
  }
  for (ProcessorNumber = 0; ProcessorNumber < PeiCpuMpData->CpuCount; ProcessorNumber ++) {
    CpuData = &PeiCpuMpData->CpuData[ProcessorNumber];
    for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex ++) {
      ASSERT (CpuInstance != NULL);
      if (CpuData->ApicId == CpuInstance[CpuIndex].CpuLocation) {
        //
        // Update processor's BIST data if it is already stored before
        //
        CpuData->Health = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;
      }
    }
    if (CpuData->Health.Uint32 == 0) {
      CpuData->CpuHealthy = TRUE;
    } else {
      CpuData->CpuHealthy = FALSE;
      //
      // Report Status Code that self test is failed
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
        (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
        );
    }
    DEBUG ((EFI_D_INFO, "  APICID - 0x%08x, BIST - 0x%08x\n",
            PeiCpuMpData->CpuData[ProcessorNumber].ApicId,
            PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32
            ));
  }

  if (SecPlatformInformation2 != NULL && NumberOfData < PeiCpuMpData->CpuCount) {
    //
    // Reinstall SecPlatformInformation2 PPI to include new BIST inforamtion
    //
    Status = PeiServicesReInstallPpi (
               SecInformationDescriptor,
               &mPeiSecPlatformInformation2Ppi
               );
    ASSERT_EFI_ERROR (Status);
  } else {
    //
    // Install SecPlatformInformation2 PPI to include new BIST inforamtion
    //
    Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi);
    ASSERT_EFI_ERROR(Status);
  }
}
Ejemplo n.º 29
0
/**
  Installs the Device Recovery Module PPI, Initialize BlockIo Ppi
  installation notification

  @param  FileHandle            The file handle of the image.
  @param  PeiServices           General purpose services available to every PEIM.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_OUT_OF_RESOURCES  There is not enough system memory.

**/
EFI_STATUS
EFIAPI
CdExpressPeimEntry (
    IN EFI_PEI_FILE_HANDLE       FileHandle,
    IN CONST EFI_PEI_SERVICES    **PeiServices
)
{
    EFI_STATUS                  Status;
    PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData;

    if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
        return EFI_SUCCESS;
    }

    PrivateData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*PrivateData)));
    if (PrivateData == NULL) {
        return EFI_OUT_OF_RESOURCES;
    }

    //
    // Initialize Private Data (to zero, as is required by subsequent operations)
    //
    ZeroMem (PrivateData, sizeof (*PrivateData));
    PrivateData->Signature    = PEI_CD_EXPRESS_PRIVATE_DATA_SIGNATURE;

    PrivateData->BlockBuffer  = AllocatePages (EFI_SIZE_TO_PAGES (PEI_CD_BLOCK_SIZE));
    if (PrivateData->BlockBuffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
    }

    PrivateData->CapsuleCount = 0;
    Status = UpdateBlocksAndVolumes (PrivateData, TRUE);
    Status = UpdateBlocksAndVolumes (PrivateData, FALSE);

    //
    // Installs Ppi
    //
    PrivateData->DeviceRecoveryPpi.GetNumberRecoveryCapsules  = GetNumberRecoveryCapsules;
    PrivateData->DeviceRecoveryPpi.GetRecoveryCapsuleInfo     = GetRecoveryCapsuleInfo;
    PrivateData->DeviceRecoveryPpi.LoadRecoveryCapsule        = LoadRecoveryCapsule;

    PrivateData->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
    PrivateData->PpiDescriptor.Guid  = &gEfiPeiDeviceRecoveryModulePpiGuid;
    PrivateData->PpiDescriptor.Ppi   = &PrivateData->DeviceRecoveryPpi;

    Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor);
    if (EFI_ERROR (Status)) {
        return EFI_OUT_OF_RESOURCES;
    }
    //
    // PrivateData is allocated now, set it to the module variable
    //
    mPrivateData = PrivateData;

    //
    // Installs Block Io Ppi notification function
    //
    PrivateData->NotifyDescriptor.Flags =
        (
            EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
        );
    PrivateData->NotifyDescriptor.Guid    = &gEfiPeiVirtualBlockIoPpiGuid;
    PrivateData->NotifyDescriptor.Notify  = BlockIoNotifyEntry;

    PrivateData->NotifyDescriptor2.Flags =
        (
            EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
            EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
        );
    PrivateData->NotifyDescriptor2.Guid    = &gEfiPeiVirtualBlockIo2PpiGuid;
    PrivateData->NotifyDescriptor2.Notify  = BlockIoNotifyEntry;

    return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor);

}
Ejemplo n.º 30
0
/**
  Entry point of this module.

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return Status.

**/
EFI_STATUS
EFIAPI
PeimEntryMA (
  IN       EFI_PEI_FILE_HANDLE      FileHandle,
  IN CONST EFI_PEI_SERVICES         **PeiServices
  )
{
  EFI_STATUS                        Status;
  EFI_BOOT_MODE                     BootMode;

  if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
      CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
    DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));
    return EFI_UNSUPPORTED;
  }

  //
  // Update for Performance optimization
  //
  Status = Tpm2RequestUseTpm ();
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
    return Status;
  }

  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);

  //
  // In S3 path, skip shadow logic. no measurement is required
  //
  if (BootMode != BOOT_ON_S3_RESUME) {
    Status = (**PeiServices).RegisterForShadow(FileHandle);
    if (Status == EFI_ALREADY_STARTED) {
      mImageInMemory = TRUE;
      mFileHandle = FileHandle;
    } else if (Status == EFI_NOT_FOUND) {
      ASSERT_EFI_ERROR (Status);
    }
  }

  if (!mImageInMemory) {
    //
    // Initialize TPM device
    //
    if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {
      if (BootMode == BOOT_ON_S3_RESUME) {
        Status = Tpm2Startup (TPM_SU_STATE);
        if (EFI_ERROR (Status) ) {
          Status = Tpm2Startup (TPM_SU_CLEAR);
        }
      } else {
        Status = Tpm2Startup (TPM_SU_CLEAR);
      }
      if (EFI_ERROR (Status) ) {
        return Status;
      }
    }

    //
    // TpmSelfTest is optional on S3 path, skip it to save S3 time
    //
    if (BootMode != BOOT_ON_S3_RESUME) {
      if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) {
        Status = Tpm2SelfTest (NO);
        if (EFI_ERROR (Status)) {
          return Status;
        }
      }
    }

    Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
    ASSERT_EFI_ERROR (Status);
  }

  if (mImageInMemory) {
    Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return Status;
}