Ejemplo n.º 1
0
/**
  Call FspInit API.

  @param[in] FspHeader FSP header pointer.
**/
VOID
PeiFspInit (
  IN FSP_INFO_HEADER *FspHeader
  )
{
  FSP_INIT_PARAMS           FspInitParams;
  FSP_INIT_RT_COMMON_BUFFER FspRtBuffer;
  UINT8                     FspUpdRgn[FixedPcdGet32 (PcdMaxUpdRegionSize)];
  UINT32                    UpdRegionSize;
  EFI_BOOT_MODE             BootMode;
  UINT64                    StackSize;
  EFI_PHYSICAL_ADDRESS      StackBase;
  EFI_STATUS                Status;

  DEBUG ((DEBUG_INFO, "PeiFspInit enter\n"));

  PeiServicesGetBootMode (&BootMode);
  DEBUG ((DEBUG_INFO, "BootMode - 0x%x\n", BootMode));

  GetStackInfo (BootMode, FALSE, &StackBase, &StackSize);
  DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase));
  DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize));

  ZeroMem (&FspRtBuffer, sizeof(FspRtBuffer));
  FspRtBuffer.StackTop = (UINT32 *)(UINTN)(StackBase + StackSize);

  FspRtBuffer.BootMode = BootMode;

  /* Platform override any UPD configs */
  UpdRegionSize = GetUpdRegionSize();
  DEBUG ((DEBUG_INFO, "UpdRegionSize - 0x%x\n", UpdRegionSize));
  DEBUG ((DEBUG_INFO, "sizeof(FspUpdRgn) - 0x%x\n", sizeof(FspUpdRgn)));
  ASSERT(sizeof(FspUpdRgn) >= UpdRegionSize);
  ZeroMem (FspUpdRgn, UpdRegionSize);
  FspRtBuffer.UpdDataRgnPtr = UpdateFspUpdConfigs (FspUpdRgn);
  FspRtBuffer.BootLoaderTolumSize = 0;

  ZeroMem (&FspInitParams, sizeof(FspInitParams));
  FspInitParams.NvsBufferPtr = GetNvsBuffer ();
  DEBUG ((DEBUG_INFO, "NvsBufferPtr - 0x%x\n", FspInitParams.NvsBufferPtr));
  FspInitParams.RtBufferPtr  = (VOID *)&FspRtBuffer;
  FspInitParams.ContinuationFunc = (CONTINUATION_PROC)ContinuationFunc;

  SaveSecContext (GetPeiServicesTablePointer ());

  DEBUG ((DEBUG_INFO, "FspInitParams      - 0x%x\n", &FspInitParams));
  DEBUG ((DEBUG_INFO, "  NvsBufferPtr     - 0x%x\n", FspInitParams.NvsBufferPtr));
  DEBUG ((DEBUG_INFO, "  RtBufferPtr      - 0x%x\n", FspInitParams.RtBufferPtr));
  DEBUG ((DEBUG_INFO, "    StackTop       - 0x%x\n", FspRtBuffer.StackTop));
  DEBUG ((DEBUG_INFO, "    BootMode       - 0x%x\n", FspRtBuffer.BootMode));
  DEBUG ((DEBUG_INFO, "    UpdDataRgnPtr  - 0x%x\n", FspRtBuffer.UpdDataRgnPtr));
  DEBUG ((DEBUG_INFO, "  ContinuationFunc - 0x%x\n", FspInitParams.ContinuationFunc));

  Status = CallFspInit (FspHeader, &FspInitParams);
  //
  // Should never return
  //
  DEBUG((DEBUG_ERROR, "FSP Init failed, status: 0x%x\n", Status));
  CpuDeadLoop ();
}
Ejemplo n.º 2
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.º 3
0
/**
  Do FSP initialization.

  @return FSP initialization status.
**/
EFI_STATUS
FspsWrapperInit (
  VOID
  )
{
  EFI_STATUS           Status;
  EFI_BOOT_MODE        BootMode;

  //
  // Register MemoryDiscovered Nofity to run FspSiliconInit
  //
  Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc);
  ASSERT_EFI_ERROR (Status);
      
  //
  // Register EndOfPei Notify for S3 to run FSP NotifyPhase
  //
  PeiServicesGetBootMode (&BootMode);
  if (BootMode == BOOT_ON_S3_RESUME) {
    Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
    ASSERT_EFI_ERROR (Status);
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 4
0
/**
  Get system memory from HOB.

  @param[in,out] LowMemoryLength   less than 4G memory length
  @param[in,out] HighMemoryLength  greater than 4G memory length
**/
VOID
EFIAPI
FspGetSystemMemorySize (
  IN OUT UINT64              *LowMemoryLength,
  IN OUT UINT64              *HighMemoryLength
  )
{
  EFI_STATUS                  Status;
  EFI_BOOT_MODE               BootMode;
  EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;
  EFI_PEI_HOB_POINTERS        Hob;

  ResourceAttribute = (
                       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
                       );

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

  if (BootMode != BOOT_ON_S3_RESUME) {
    ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_TESTED;
  }

  *HighMemoryLength = 0;
  *LowMemoryLength  = SIZE_1MB;
  //
  // Get the HOB list for processing
  //
  Hob.Raw = GetHobList ();

  //
  // Collect memory ranges
  //
  while (!END_OF_HOB_LIST (Hob)) {
    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
      if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
          ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) &&
           (Hob.ResourceDescriptor->ResourceAttribute == ResourceAttribute))) {
        //
        // Need memory above 1MB to be collected here
        //
        if (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB &&
            Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) BASE_4GB) {
          *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
        } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) BASE_4GB) {
          *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
        }
      }
    }
    Hob.Raw = GET_NEXT_HOB (Hob);
  }
}
Ejemplo n.º 5
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.º 6
0
/**
  This is the entrypoint of PEIM

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

  @retval EFI_SUCCESS if it completed successfully.
**/
EFI_STATUS
EFIAPI
FspPeiEntryPoint (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  FSP_INFO_HEADER      *FspHeader;
  EFI_STATUS           Status;
  FSP_INIT_DONE_PPI    *FspInitDone;
  VOID                 *FspHobList;
  EFI_BOOT_MODE        BootMode;

  DEBUG ((DEBUG_INFO, "FspPeiEntryPoint\n"));

  Status = PeiServicesLocatePpi (
             &gFspInitDonePpiGuid,
             0,
             NULL,
             (VOID **) &FspInitDone
             );
  if (EFI_ERROR (Status)) {
    //
    // 1st entry
    //
    DEBUG ((DEBUG_INFO, "1st entry\n"));
    FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase));
    DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", FspHeader));
    if (FspHeader == NULL) {
      return EFI_DEVICE_ERROR;
    }

    SecFspInit (FspHeader);

    //
    // Never return here
    //
    CpuDeadLoop ();
  } else {
    //
    // 2nd entry
    //
    DEBUG ((DEBUG_INFO, "2nd entry\n"));
    Status = FspInitDone->GetFspHobList (PeiServices, FspInitDone, &FspHobList);
    DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
    FspHobProcess (FspHobList);

    PeiServicesGetBootMode (&BootMode);
    if (BootMode == BOOT_ON_S3_RESUME) {
      Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
      ASSERT_EFI_ERROR (Status);
    }
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 7
0
/**
  Get the Boot Mode from the HOB list.

  This function returns the system boot mode information from the 
  PHIT HOB in HOB list.

  @param  VOID

  @return The Boot Mode.

**/
EFI_BOOT_MODE
EFIAPI
GetBootModeHob (
  VOID
  )
{
  EFI_STATUS             Status;
  EFI_BOOT_MODE          BootMode;

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

  return BootMode;
}
Ejemplo n.º 8
0
/**
  Do FSP initialization based on FspApi version 1.

  @param[in] FspHeader FSP header pointer.

  @return FSP initialization status.
**/
EFI_STATUS
PeiFspInitV1 (
  IN FSP_INFO_HEADER *FspHeader
  )
{
  EFI_STATUS           Status;
  FSP_INIT_DONE_PPI    *FspInitDone;
  VOID                 *FspHobList;
  EFI_BOOT_MODE        BootMode;
  
  Status = PeiServicesLocatePpi (
             &gFspInitDonePpiGuid,
             0,
             NULL,
             (VOID **) &FspInitDone
             );
  if (EFI_ERROR (Status)) {
    //
    // 1st entry
    //
    DEBUG ((DEBUG_INFO, "1st entry\n"));

    PeiFspInit (FspHeader);
    //
    // Never return here, for FspApi version 1.
    //
    CpuDeadLoop ();
  } else {
    //
    // 2nd entry for FspApi version 1 only.
    //
    DEBUG ((DEBUG_INFO, "2nd entry\n"));

    Status = FspInitDone->GetFspHobList (GetPeiServicesTablePointer (), FspInitDone, &FspHobList);
    ASSERT_EFI_ERROR (Status);
    DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
    FspHobProcess (FspHobList);
    
    //
    // Register EndOfPei Notify for S3 to run FspNotifyPhase
    //
    PeiServicesGetBootMode (&BootMode);
    if (BootMode == BOOT_ON_S3_RESUME) {
      Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
      ASSERT_EFI_ERROR (Status);
    }
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 9
0
/**
  Notify function on End Of PEI PPI.

  On S3 boot, this function will restore wakeup buffer data.
  On normal boot, this function will flag wakeup buffer to be un-used type.

  @param[in]  PeiServices        The pointer to the PEI Services Table.
  @param[in]  NotifyDescriptor   Address of the notification descriptor data structure.
  @param[in]  Ppi                Address of the PPI that was installed.

  @retval EFI_SUCCESS        When everything is OK.
**/
EFI_STATUS
EFIAPI
CpuMpEndOfPeiCallback (
  IN EFI_PEI_SERVICES             **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR    *NotifyDescriptor,
  IN VOID                         *Ppi
  )
{
  EFI_STATUS                Status;
  EFI_BOOT_MODE             BootMode;
  CPU_MP_DATA               *CpuMpData;
  EFI_PEI_HOB_POINTERS      Hob;
  EFI_HOB_MEMORY_ALLOCATION *MemoryHob;

  DEBUG ((DEBUG_INFO, "PeiMpInitLib: CpuMpEndOfPeiCallback () invoked\n"));

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

  CpuMpData = GetCpuMpData ();
  if (BootMode != BOOT_ON_S3_RESUME) {
    //
    // Get the HOB list for processing
    //
    Hob.Raw = GetHobList ();
    //
    // Collect memory ranges
    //
    while (!END_OF_HOB_LIST (Hob)) {
      if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
        MemoryHob = Hob.MemoryAllocation;
        if (MemoryHob->AllocDescriptor.MemoryBaseAddress == CpuMpData->WakeupBuffer) {
          //
          // Flag this HOB type to un-used
          //
          GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED;
          break;
        }
      }
      Hob.Raw = GET_NEXT_HOB (Hob);
    }
  } else {
    CpuMpData->SaveRestoreFlag = TRUE;
    RestoreWakeupBuffer (CpuMpData);
  }
  return EFI_SUCCESS;
}
/**
  Initializes the Intel VTd PMR PEIM.

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

  @retval EFI_SUCCESS            Usb bot driver is successfully initialized.
  @retval EFI_OUT_OF_RESOURCES   Can't initialize the driver.

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

  DEBUG ((DEBUG_INFO, "IntelVTdPmrInitialize\n"));

  if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) {
    return EFI_UNSUPPORTED;
  }

  DmaBufferInfo = BuildGuidHob (&mDmaBufferInfoGuid, sizeof(DMA_BUFFER_INFO));
  ASSERT(DmaBufferInfo != NULL);
  if (DmaBufferInfo == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  ZeroMem (DmaBufferInfo, sizeof(DMA_BUFFER_INFO));

  PeiServicesGetBootMode (&BootMode);

  if (BootMode == BOOT_ON_S3_RESUME) {
    DmaBufferInfo->DmaBufferSize = PcdGet32 (PcdVTdPeiDmaBufferSizeS3);
  } else {
    DmaBufferInfo->DmaBufferSize = PcdGet32 (PcdVTdPeiDmaBufferSize);
  }

  Status = PeiServicesNotifyPpi (&mVTdInfoNotifyDesc);
  ASSERT_EFI_ERROR (Status);

  //
  // Register EndOfPei Notify for S3
  //
  if (BootMode == BOOT_ON_S3_RESUME) {
    Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
    ASSERT_EFI_ERROR (Status);
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 11
0
/**
  BIOS process FspBobList for Memory Resource Descriptor.

  @param[in] FspHobList  Pointer to the HOB data structure produced by FSP.

  @return If platform process the FSP hob list successfully.
**/
EFI_STATUS
EFIAPI
FspHobProcessForMemoryResource (
  IN VOID                 *FspHobList
  )
{
  EFI_PEI_HOB_POINTERS Hob;
  UINT64               LowMemorySize;
  UINT64               FspMemorySize;
  EFI_PHYSICAL_ADDRESS FspMemoryBase;
  UINT64               PeiMemSize;
  EFI_PHYSICAL_ADDRESS PeiMemBase;
  UINT64               S3PeiMemSize;
  EFI_PHYSICAL_ADDRESS S3PeiMemBase;
  BOOLEAN              FoundFspMemHob;
  EFI_STATUS           Status;
  EFI_BOOT_MODE        BootMode;
  PEI_CAPSULE_PPI      *Capsule;
  VOID                 *CapsuleBuffer;
  UINTN                CapsuleBufferLength;
  UINT64               RequiredMemSize;
  EFI_PEI_SERVICES     **PeiServices;

  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();

  PeiServicesGetBootMode (&BootMode);

  PeiMemBase = 0;
  LowMemorySize = 0;
  FspMemorySize = 0;
  FspMemoryBase = 0;
  FoundFspMemHob = FALSE;

  //
  // Parse the hob list from fsp
  // Report all the resource hob except the memory between 1M and 4G
  //
  Hob.Raw = (UINT8 *)(UINTN)FspHobList;
  DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));

  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {
    DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
        (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) {
      DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
      DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));
      DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));
      DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
    }

    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)  // Found the low memory length below 4G
        && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
        && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) {
        LowMemorySize += Hob.ResourceDescriptor->ResourceLength;
      Hob.Raw = GET_NEXT_HOB (Hob);
      continue;
    }

    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)  // Found the low memory length below 4G
        && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
        && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)
        && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) {
      FoundFspMemHob = TRUE;
      FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart;
      FspMemorySize = Hob.ResourceDescriptor->ResourceLength;
      DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize));
    }

    //
    // Report the resource hob
    //
    BuildResourceDescriptorHob (
      Hob.ResourceDescriptor->ResourceType,
      Hob.ResourceDescriptor->ResourceAttribute,
      Hob.ResourceDescriptor->PhysicalStart,
      Hob.ResourceDescriptor->ResourceLength
      );

    Hob.Raw = GET_NEXT_HOB (Hob);
  }

  if (!FoundFspMemHob) {
    DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));
    //ASSERT(FALSE);
  }

  DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize));
  DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));
  DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));

  if (BootMode == BOOT_ON_S3_RESUME) {
    BuildResourceDescriptorHob (
      EFI_RESOURCE_SYSTEM_MEMORY,
      (
         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
      ),
      BASE_1MB,
      LowMemorySize
      );

    S3PeiMemBase = 0;
    S3PeiMemSize = 0;
    Status = GetS3MemoryInfo (&S3PeiMemBase, &S3PeiMemSize);
    ASSERT_EFI_ERROR (Status);
    DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));

    //
    // Make sure Stack and PeiMemory are not overlap
    //

    Status = PeiServicesInstallPeiMemory (
               S3PeiMemBase,
               S3PeiMemSize
               );
    ASSERT_EFI_ERROR (Status);
  } else {
    PeiMemSize = GetPeiMemSize (PeiServices, BootMode);
    DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));

    //
    // Capsule mode
    //
    Capsule = NULL;
    CapsuleBuffer = NULL;
    CapsuleBufferLength = 0;
    if (BootMode == BOOT_ON_FLASH_UPDATE) {
      Status = PeiServicesLocatePpi (
                 &gPeiCapsulePpiGuid,
                 0,
                 NULL,
                 (VOID **) &Capsule
                 );
      ASSERT_EFI_ERROR (Status);

      if (Status == EFI_SUCCESS) {
        //
        // Make sure Stack and CapsuleBuffer are not overlap
        //
        CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;
        CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize);
        //
        // Call the Capsule PPI Coalesce function to coalesce the capsule data.
        //
        Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength);
      }
    }

    RequiredMemSize = RetrieveRequiredMemorySize (PeiServices);
    DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));

    //
    // Report the main memory
    //
    BuildResourceDescriptorHob (
      EFI_RESOURCE_SYSTEM_MEMORY,
      (
         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
      ),
      BASE_1MB,
      LowMemorySize
      );

    //
    // Make sure Stack and CapsuleBuffer are not overlap
    //

    //
    // Install efi memory
    //
    PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;
    Status = PeiServicesInstallPeiMemory (
               PeiMemBase,
               PeiMemSize - RequiredMemSize
               );
    ASSERT_EFI_ERROR (Status);

    if (Capsule != NULL) {
      Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
    }
  }

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

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

  @retval EFI_SUCCESS    PPI successfully installed.

**/
EFI_STATUS
EFIAPI
NvmExpressPeimEntry (
  IN EFI_PEI_FILE_HANDLE    FileHandle,
  IN CONST EFI_PEI_SERVICES **PeiServices
  )
{
  EFI_STATUS                               Status;
  EFI_BOOT_MODE                            BootMode;
  EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI    *NvmeHcPpi;
  UINT8                                    Controller;
  UINTN                                    MmioBase;
  UINTN                                    DevicePathLength;
  EFI_DEVICE_PATH_PROTOCOL                 *DevicePath;
  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
  EFI_PHYSICAL_ADDRESS                     DeviceAddress;

  DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__));

  //
  // Get the current boot mode.
  //
  Status = PeiServicesGetBootMode (&BootMode);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Fail to get the current boot mode.\n", __FUNCTION__));
    return Status;
  }

  //
  // Locate the NVME host controller PPI
  //
  Status = PeiServicesLocatePpi (
             &gEdkiiPeiNvmExpressHostControllerPpiGuid,
             0,
             NULL,
             (VOID **) &NvmeHcPpi
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Fail to locate NvmeHostControllerPpi.\n", __FUNCTION__));
    return EFI_UNSUPPORTED;
  }

  Controller = 0;
  MmioBase   = 0;
  while (TRUE) {
    Status = NvmeHcPpi->GetNvmeHcMmioBar (
                          NvmeHcPpi,
                          Controller,
                          &MmioBase
                          );
    //
    // When status is error, meant no controller is found
    //
    if (EFI_ERROR (Status)) {
      break;
    }

    Status = NvmeHcPpi->GetNvmeHcDevicePath (
                          NvmeHcPpi,
                          Controller,
                          &DevicePathLength,
                          &DevicePath
                          );
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR, "%a: Fail to allocate get the device path for Controller %d.\n",
        __FUNCTION__, Controller
        ));
      return Status;
    }

    //
    // Check validity of the device path of the NVM Express controller.
    //
    Status = NvmeIsHcDevicePathValid (DevicePath, DevicePathLength);
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR, "%a: The device path is invalid for Controller %d.\n",
        __FUNCTION__, Controller
        ));
      Controller++;
      continue;
    }

    //
    // For S3 resume performance consideration, not all NVM Express controllers
    // will be initialized. The driver consumes the content within
    // S3StorageDeviceInitList LockBox to see if a controller will be skipped
    // during S3 resume.
    //
    if ((BootMode == BOOT_ON_S3_RESUME) &&
        (NvmeS3SkipThisController (DevicePath, DevicePathLength))) {
      DEBUG ((
        DEBUG_ERROR, "%a: Controller %d is skipped during S3.\n",
        __FUNCTION__, Controller
        ));
      Controller++;
      continue;
    }

    //
    // Memory allocation for controller private data
    //
    Private = AllocateZeroPool (sizeof (PEI_NVME_CONTROLLER_PRIVATE_DATA));
    if (Private == NULL) {
      DEBUG ((
        DEBUG_ERROR, "%a: Fail to allocate private data for Controller %d.\n",
        __FUNCTION__, Controller
        ));
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Memory allocation for transfer-related data
    //
    Status = IoMmuAllocateBuffer (
               NVME_MEM_MAX_PAGES,
               &Private->Buffer,
               &DeviceAddress,
               &Private->BufferMapping
               );
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR, "%a: Fail to allocate DMA buffers for Controller %d.\n",
        __FUNCTION__, Controller
        ));
      return Status;
    }
    ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Private->Buffer));
    DEBUG ((DEBUG_INFO, "%a: DMA buffer base at 0x%x\n", __FUNCTION__, Private->Buffer));

    //
    // Initialize controller private data
    //
    Private->Signature        = NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE;
    Private->MmioBase         = MmioBase;
    Private->DevicePathLength = DevicePathLength;
    Private->DevicePath       = DevicePath;

    //
    // Initialize the NVME controller
    //
    Status = NvmeControllerInit (Private);
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: Controller initialization fail for Controller %d with Status - %r.\n",
        __FUNCTION__, Controller, Status
        ));
      NvmeFreeDmaResource (Private);
      Controller++;
      continue;
    }

    //
    // Enumerate the NVME namespaces on the controller
    //
    Status = NvmeDiscoverNamespaces (Private);
    if (EFI_ERROR (Status)) {
      //
      // No active namespace was found on the controller
      //
      DEBUG ((
        DEBUG_ERROR,
        "%a: Namespaces discovery fail for Controller %d with Status - %r.\n",
        __FUNCTION__, Controller, Status
        ));
      NvmeFreeDmaResource (Private);
      Controller++;
      continue;
    }

    Private->BlkIoPpi.GetNumberOfBlockDevices  = NvmeBlockIoPeimGetDeviceNo;
    Private->BlkIoPpi.GetBlockDeviceMediaInfo  = NvmeBlockIoPeimGetMediaInfo;
    Private->BlkIoPpi.ReadBlocks               = NvmeBlockIoPeimReadBlocks;
    CopyMem (
      &Private->BlkIoPpiList,
      &mNvmeBlkIoPpiListTemplate,
      sizeof (EFI_PEI_PPI_DESCRIPTOR)
      );
    Private->BlkIoPpiList.Ppi                  = &Private->BlkIoPpi;

    Private->BlkIo2Ppi.Revision                = EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;
    Private->BlkIo2Ppi.GetNumberOfBlockDevices = NvmeBlockIoPeimGetDeviceNo2;
    Private->BlkIo2Ppi.GetBlockDeviceMediaInfo = NvmeBlockIoPeimGetMediaInfo2;
    Private->BlkIo2Ppi.ReadBlocks              = NvmeBlockIoPeimReadBlocks2;
    CopyMem (
      &Private->BlkIo2PpiList,
      &mNvmeBlkIo2PpiListTemplate,
      sizeof (EFI_PEI_PPI_DESCRIPTOR)
      );
    Private->BlkIo2PpiList.Ppi                 = &Private->BlkIo2Ppi;
    PeiServicesInstallPpi (&Private->BlkIoPpiList);

    //
    // Check if the NVME controller supports the Security Receive/Send commands
    //
    if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) {
      DEBUG ((
        DEBUG_INFO,
        "%a: Security Security Command PPI will be produced for Controller %d.\n",
        __FUNCTION__, Controller
        ));
      Private->StorageSecurityPpi.Revision           = EDKII_STORAGE_SECURITY_PPI_REVISION;
      Private->StorageSecurityPpi.GetNumberofDevices = NvmeStorageSecurityGetDeviceNo;
      Private->StorageSecurityPpi.GetDevicePath      = NvmeStorageSecurityGetDevicePath;
      Private->StorageSecurityPpi.ReceiveData        = NvmeStorageSecurityReceiveData;
      Private->StorageSecurityPpi.SendData           = NvmeStorageSecuritySendData;
      CopyMem (
        &Private->StorageSecurityPpiList,
        &mNvmeStorageSecurityPpiListTemplate,
        sizeof (EFI_PEI_PPI_DESCRIPTOR)
        );
      Private->StorageSecurityPpiList.Ppi            = &Private->StorageSecurityPpi;
      PeiServicesInstallPpi (&Private->StorageSecurityPpiList);
    }

    CopyMem (
      &Private->EndOfPeiNotifyList,
      &mNvmeEndOfPeiNotifyListTemplate,
      sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)
      );
    PeiServicesNotifyPpi  (&Private->EndOfPeiNotifyList);

    DEBUG ((
      DEBUG_INFO, "%a: Controller %d has been successfully initialized.\n",
      __FUNCTION__, Controller
      ));
    Controller++;
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 13
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 (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
        DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
        return EFI_UNSUPPORTED;
    }

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

    //
    // 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) {
        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;
        }

        if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {
            Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);
            if (EFI_ERROR (Status) ) {
                return Status;
            }
        }

        //
        // TpmSelfTest is optional on S3 path, skip it to save S3 time
        //
        if (BootMode != BOOT_ON_S3_RESUME) {
            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.º 14
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.º 15
0
/**
  Main entry for Firmware Performance Data Table PEIM.

  This routine is to register report status code listener for FPDT.

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

  @retval EFI_SUCCESS Report status code listener is registered successfully.

**/
EFI_STATUS
EFIAPI
FirmwarePerformancePeiEntryPoint (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS               Status;
  EFI_BOOT_MODE            BootMode;
  EFI_PEI_RSC_HANDLER_PPI  *RscHandler;
  PEI_SEC_PERFORMANCE_PPI  *SecPerf;
  FIRMWARE_SEC_PERFORMANCE Performance;

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

  if (BootMode == BOOT_ON_S3_RESUME) {
    if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {
      //
      // S3 resume - register status code listener for OS wake vector.
      //
      Status = PeiServicesLocatePpi (
                 &gEfiPeiRscHandlerPpiGuid,
                 0,
                 NULL,
                 (VOID **) &RscHandler
                 );
      ASSERT_EFI_ERROR (Status);

      Status = RscHandler->Register (FpdtStatusCodeListenerPei);
      ASSERT_EFI_ERROR (Status);
    }
  } else {
    //
    // Normal boot - build Hob for SEC performance data.
    //
    Status = PeiServicesLocatePpi (
               &gPeiSecPerformancePpiGuid,
               0,
               NULL,
               (VOID **) &SecPerf
               );
    if (!EFI_ERROR (Status)) {
      Status = SecPerf->GetPerformance (PeiServices, SecPerf, &Performance);
    }
    if (!EFI_ERROR (Status)) {
      BuildGuidDataHob (
        &gEfiFirmwarePerformanceGuid,
        &Performance,
        sizeof (FIRMWARE_SEC_PERFORMANCE)
      );
      DEBUG ((EFI_D_INFO, "FPDT: SEC Performance Hob ResetEnd = %ld\n", Performance.ResetEnd));
    } else {
      //
      // SEC performance PPI is not installed or fail to get performance data
      // from SEC Performance PPI.
      //
      DEBUG ((EFI_D_ERROR, "FPDT: WARNING: SEC Performance PPI not installed or failed!\n"));
    }
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 16
0
EFI_STATUS
EFIAPI
PeimInitializeWinNtAutoScan (
  IN       EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES          **PeiServices
  )
/*++

Routine Description:
  Perform a call-back into the SEC simulator to get a memory value

Arguments:
  FfsHeader   - General purpose data available to every PEIM
  PeiServices - General purpose services available to every PEIM.
    
Returns:
  None

--*/
{
  EFI_STATUS                            Status;
  EFI_PEI_PPI_DESCRIPTOR                *PpiDescriptor;
  PEI_NT_AUTOSCAN_PPI                   *PeiNtService;
  UINT64                                MemorySize;
  EFI_PHYSICAL_ADDRESS                  MemoryBase;
  UINTN                                 Index;
  EFI_RESOURCE_ATTRIBUTE_TYPE           Attributes;
  UINT64                                PeiMemorySize;
  EFI_PHYSICAL_ADDRESS                  PeiMemoryBase;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI       *Variable;
  UINTN                                 DataSize;
  EFI_MEMORY_TYPE_INFORMATION           MemoryData [EfiMaxMemoryType + 1];
  UINT64                                SmramMemorySize;
  EFI_PHYSICAL_ADDRESS                  SmramMemoryBase;
  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK        *SmramHobDescriptorBlock;
  PEI_CAPSULE_PPI                       *Capsule;
  VOID                                  *CapsuleBuffer;
  UINTN                                 CapsuleBufferLength;
  EFI_BOOT_MODE                         BootMode;
  EFI_WIN_NT_MEMORY_LAYOUT              *MemoryLayout;
  UINTN                                 MaxSystemMemoryCount;

  DEBUG ((EFI_D_ERROR, "NT 32 Autoscan PEIM Loaded\n"));

  //
  // Get the PEI NT Autoscan PPI
  //
  Status = PeiServicesLocatePpi (
             &gPeiNtAutoScanPpiGuid, // GUID
             0,                      // INSTANCE
             &PpiDescriptor,         // EFI_PEI_PPI_DESCRIPTOR
             (VOID**)&PeiNtService           // PPI
             );
  ASSERT_EFI_ERROR (Status);

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

  DEBUG ((EFI_D_ERROR, "BootMode - %x\n", BootMode));

  if (FeaturePcdGet (PcdWinNtCapsuleEnable)) {
    MaxSystemMemoryCount = GetMaxSystemMemoryCount();
    MemoryLayout = BuildGuidHob (
                     &gEfiWinNtMemoryLayoutGuid,
                     sizeof (EFI_WIN_NT_MEMORY_LAYOUT) + sizeof (EFI_WIN_NT_MEMORY_DESCRIPTOR) * (MaxSystemMemoryCount - 1)
                     );
    ASSERT (MemoryLayout != NULL);
    MemoryLayout->NumberOfRegions = 0;
  
    Capsule = NULL;
    CapsuleBuffer = NULL;
    CapsuleBufferLength = 0;
    if (BootMode == BOOT_ON_FLASH_UPDATE) {
      Status = PeiServicesLocatePpi (&gPeiCapsulePpiGuid, 0, NULL, (VOID**) &Capsule);
      ASSERT_EFI_ERROR (Status);
    }
  }

  Index = 0;
  SmramMemorySize = 0;
  SmramMemoryBase = 0;
  do {
    Status = PeiNtService->NtAutoScan (Index, &MemoryBase, &MemorySize);
    DEBUG ((EFI_D_ERROR, "NtAutoScan(%d) Status - %r\n", Index, Status));
    if (!EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "NtAutoScan(%d) Base - 0x%lx\n", Index, MemoryBase));
      DEBUG ((EFI_D_ERROR, "NtAutoScan(%d) Size - 0x%lx\n", Index, MemorySize));

      if (FeaturePcdGet (PcdWinNtCapsuleEnable)) {
        if (MemoryLayout->NumberOfRegions < MaxSystemMemoryCount) {
          MemoryLayout->Descriptor[MemoryLayout->NumberOfRegions].Base = MemoryBase;
          MemoryLayout->Descriptor[MemoryLayout->NumberOfRegions].Size = MemorySize;
          MemoryLayout->NumberOfRegions ++;
        }
      }

      Attributes =
        (
          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
        );

      if (Index == 0) {
        //
        // Register the memory with the PEI Core
        //

        if (FeaturePcdGet(PcdWinNtSmmEnable)) {
          //
          // SMRAM
          //
          SmramMemorySize = PcdGet64(PcdWinNtSmramSize);
          SmramMemoryBase = MemoryBase + MemorySize - SmramMemorySize;
          DEBUG ((EFI_D_ERROR, "SmramMemoryBase - 0x%lx\n", SmramMemoryBase));
          DEBUG ((EFI_D_ERROR, "SmramMemorySize - 0x%lx\n", SmramMemorySize));

          MemorySize      = MemorySize - SmramMemorySize;
        }

        PeiMemoryBase = MemoryBase;
        PeiMemorySize = MemorySize;

        if (FeaturePcdGet(PcdWinNtCapsuleEnable)) {
          //
          // Capsule
          //
          if (Capsule != NULL) {
            CapsuleBufferLength = ((UINTN) PeiMemorySize / 2);
            PeiMemorySize       = CapsuleBufferLength;
            CapsuleBuffer = (VOID*) (UINTN) (PeiMemoryBase + CapsuleBufferLength);
          }
        }

        Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED;
      }
      
      BuildResourceDescriptorHob (
        EFI_RESOURCE_SYSTEM_MEMORY,
        Attributes,
        MemoryBase,
        MemorySize
        );
      DEBUG ((EFI_D_ERROR, "ResourceHob - 0x%lx - 0x%lx\n", MemoryBase, MemorySize));
    }
    Index++;
  } while (!EFI_ERROR (Status));

  if (FeaturePcdGet(PcdWinNtCapsuleEnable)) {
    if (Capsule != NULL) {
      //
      // Call the Capsule PPI Coalesce function to coalesce the capsule data.
      //
      Status = Capsule->Coalesce (
                          (EFI_PEI_SERVICES**) PeiServices,
                          &CapsuleBuffer,
                          &CapsuleBufferLength
                          );
      DEBUG ((EFI_D_ERROR, "CoalesceStatus - %r\n", Status));
      DEBUG ((EFI_D_ERROR, "CapsuleBuffer - %x\n", CapsuleBuffer));
      DEBUG ((EFI_D_ERROR, "CapsuleBufferLength - %x\n", CapsuleBufferLength));
      
      //
      // If it failed, then NULL out our capsule PPI pointer so that the capsule
      // HOB does not get created below.
      //
      if (Status != EFI_SUCCESS) {
        Capsule = NULL;
      }
    }
  }

  Status = PeiServicesInstallPeiMemory (PeiMemoryBase, PeiMemorySize);
  ASSERT_EFI_ERROR (Status);

  if (FeaturePcdGet(PcdWinNtCapsuleEnable)) {
    //
    // If we found the capsule PPI (and we didn't have errors), then
    // call the capsule PEIM to allocate memory for the capsule.
    //
    if (Capsule != NULL) {
      Status = Capsule->CreateState((EFI_PEI_SERVICES **)PeiServices, CapsuleBuffer, CapsuleBufferLength);
    }
  }

  //
  // Build the CPU hob with 52-bit addressing and 16-bits of IO space.
  //
  BuildCpuHob (52, 16);

  //
  // Build GUIDed Hob that contains the Memory Type Information array
  //
  Status = PeiServicesLocatePpi (
             &gEfiPeiReadOnlyVariable2PpiGuid,
             0,
             NULL,
             (VOID **)&Variable
             );
  ASSERT_EFI_ERROR (Status);

  DataSize = sizeof (MemoryData);
  Status = Variable->GetVariable (
                       Variable,
                       EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
                       &gEfiMemoryTypeInformationGuid,
                       NULL,
                       &DataSize,
                       &MemoryData
                       );
  if (EFI_ERROR (Status) || !ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) {
    //
    // Create Memory Type Information HOB
    //
    BuildGuidDataHob (
      &gEfiMemoryTypeInformationGuid,
      mDefaultMemoryTypeInformation,
      sizeof(mDefaultMemoryTypeInformation)
      );
  } else {
    //
    // Create Memory Type Information HOB
    //
    BuildGuidDataHob (
      &gEfiMemoryTypeInformationGuid,
      MemoryData,
      DataSize
      );
  }

  if (FeaturePcdGet(PcdWinNtSmmEnable)) {
    //
    // BuildSmramHob
    //
    if ((SmramMemoryBase != 0) && (SmramMemorySize != 0)) {
      SmramHobDescriptorBlock = BuildGuidHob (
                                  &gEfiSmmPeiSmramMemoryReserveGuid,
                                  sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + sizeof (EFI_SMRAM_DESCRIPTOR)
                                  );
      ASSERT (SmramHobDescriptorBlock != NULL);
      SmramHobDescriptorBlock->NumberOfSmmReservedRegions = 1;

      SmramHobDescriptorBlock->Descriptor[0].PhysicalStart = SmramMemoryBase;
      SmramHobDescriptorBlock->Descriptor[0].CpuStart      = SmramMemoryBase;
      SmramHobDescriptorBlock->Descriptor[0].PhysicalSize  = SmramMemorySize;
      SmramHobDescriptorBlock->Descriptor[0].RegionState   = EFI_SMRAM_CLOSED;
    }
  }

  return Status;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
/**
  This function will be called when MRC is done.

  @param  PeiServices General purpose services available to every PEIM.

  @param  NotifyDescriptor Information about the notify event..

  @param  Ppi The notify context.

  @retval EFI_SUCCESS If the function completed successfully.
**/
EFI_STATUS
EFIAPI
MemoryDiscoveredPpiNotifyCallback (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  EFI_STATUS                            Status;
  EFI_BOOT_MODE                         BootMode;
  UINT64                                MemoryLength;
  UINT64                                MemoryLengthUc;
  UINT64                                MaxMemoryLength;
  UINT64                                MemOverflow;
  EFI_SMRAM_DESCRIPTOR                  *SmramDescriptor;
  UINTN                                 NumSmramRegions;
  UINT64                                EnlargedMemoryLength;
  UINT32                                RmuMainBaseAddress;
  UINTN                                 Index;
  MTRR_SETTINGS                         MtrrSetting;
  UINT32                                RegData32;
  EFI_PHYSICAL_ADDRESS                  NewBuffer;
  UINT8                                 CpuAddressWidth;
  EFI_CPUID_REGISTER                    FeatureInfo;
  
  DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n"));

  NumSmramRegions = 0;
  SmramDescriptor = NULL;
  RmuMainBaseAddress = 0;

  PERF_START (NULL, "SetCache", NULL, 0);

  InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions);
  ASSERT (SmramDescriptor != NULL);
  ASSERT (RmuMainBaseAddress != 0);

  MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000;
  EnlargedMemoryLength = MemoryLength;

  if (NumSmramRegions > 0) {
	  //
	  // Find the TSEG
	  //
	  for (Index = 0; Index < NumSmramRegions; Index ++) {
	    if ((SmramDescriptor[Index].PhysicalStart) == EnlargedMemoryLength) {
	      if (SmramDescriptor[Index].RegionState & EFI_CACHEABLE) {
	        //
	        // Enlarge memory length to include TSEG size
	        //
	        EnlargedMemoryLength += (SmramDescriptor[Index].PhysicalSize);
	      }
	    }
	  }
	}

  //
  // Check if a UC region is present
  //
  MaxMemoryLength = EnlargedMemoryLength;
  // Round up to nearest 256MB
  MemOverflow = (MemoryLength & 0x0fffffff);
  if (MemOverflow != 0) {
    MaxMemoryLength = MemoryLength + (0x10000000 - MemOverflow);
  }


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

  ZeroMem (&MtrrSetting, sizeof(MTRR_SETTINGS));
  (**PeiServices).CopyMem ((VOID *)&MtrrSetting.Fixed,(VOID *)&mFixedMtrrTable, sizeof(MTRR_FIXED_SETTINGS) );
  //
  // Cache the flash area to improve the boot performance in PEI phase
  //
  MtrrSetting.Variables.Mtrr[0].Base = (QUARK_BOOTROM_BASE_ADDRESS | CacheWriteBack);  
  MtrrSetting.Variables.Mtrr[0].Mask = (((~(QUARK_BOOTROM_SIZE_BYTES - 1)) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED);
  
  MtrrSetting.Variables.Mtrr[1].Base = CacheWriteBack;  
  MtrrSetting.Variables.Mtrr[1].Mask = ((~(MaxMemoryLength - 1)) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED;

  Index = 2;
  while (MaxMemoryLength != MemoryLength) {
    MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - MemoryLength);

    //Status = MtrrSetMemoryAttribute (MaxMemoryLength - MemoryLengthUc, MemoryLengthUc, CacheUncacheable);
    //ASSERT_EFI_ERROR (Status);
    
    MtrrSetting.Variables.Mtrr[Index].Base = ((MaxMemoryLength - MemoryLengthUc) & MTRR_LIB_CACHE_VALID_ADDRESS) | CacheUncacheable;
    MtrrSetting.Variables.Mtrr[Index].Mask= ((~(MemoryLengthUc   - 1)) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED;      
    MaxMemoryLength -= MemoryLengthUc;
    Index++;
  }

  AsmInvd ();
 
  MtrrSetting.MtrrDefType = MTRR_LIB_CACHE_MTRR_ENABLED | MTRR_LIB_CACHE_FIXED_MTRR_ENABLED;
  MtrrSetAllMtrrs(&MtrrSetting);

  PERF_END (NULL, "SetCache", NULL, 0);

  //
  // Install PeiReset for PeiResetSystem service
  //
  Status = PeiServicesInstallPpi (&mPpiList[0]);
  ASSERT_EFI_ERROR (Status);

  //
  // Do QNC initialization after MRC
  //
  PeiQNCPostMemInit ();

  Status = PeiServicesInstallPpi (&mPpiStall[0]);
  ASSERT_EFI_ERROR (Status);

  //
  // Set E000/F000 Routing
  //
  RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
  RegData32 |= (BIT2|BIT1);
  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32);

  if (BootMode == BOOT_IN_RECOVERY_MODE) {
  PeiServicesInstallFvInfoPpi (
    NULL,
    (VOID *) (UINTN) PcdGet32 (PcdFlashFvRecovery2Base),
    PcdGet32 (PcdFlashFvRecovery2Size),
    NULL,
    NULL
    );
    Status = PeimInitializeRecovery (PeiServices);
    ASSERT_EFI_ERROR (Status);

  } else if (BootMode == BOOT_ON_S3_RESUME) {
    return EFI_SUCCESS;

  } else {
    //
    // Allocate the memory so that it gets preserved into DXE
    //
    Status = PeiServicesAllocatePages (
              EfiBootServicesData,
              EFI_SIZE_TO_PAGES (PcdGet32 (PcdFvSecurityHeaderSize) + PcdGet32 (PcdFlashFvMainSize)),
              &NewBuffer
              );

    //
    // Copy the compressed main Firmware Volume to memory for faster processing later
    //
    CopyMem ((VOID *) (UINTN) NewBuffer, (VOID *) (UINTN) (PcdGet32 (PcdFlashFvMainBase) - PcdGet32 (PcdFvSecurityHeaderSize)), (PcdGet32 (PcdFvSecurityHeaderSize) +PcdGet32 (PcdFlashFvMainSize)));

    PeiServicesInstallFvInfoPpi (
      NULL,
      (VOID *) (UINTN) (NewBuffer + PcdGet32 (PcdFvSecurityHeaderSize)),
      PcdGet32 (PcdFlashFvMainSize),
      NULL,
      NULL
      );
  }

  //
  // Build flash HOB, it's going to be used by GCD and E820 building
  // Map full SPI flash decode range (regardless of smaller SPI flash parts installed)
  //
  BuildResourceDescriptorHob (
    EFI_RESOURCE_FIRMWARE_DEVICE,
    (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    (SIZE_4GB - SIZE_8MB),
    SIZE_8MB
    );

  //
  // Create a CPU hand-off information
  //
  CpuAddressWidth = 32;
  AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, NULL, NULL, NULL);
  if (FeatureInfo.RegEax >= EFI_CPUID_VIR_PHY_ADDRESS_SIZE) {
    AsmCpuid (EFI_CPUID_VIR_PHY_ADDRESS_SIZE, &FeatureInfo.RegEax, NULL, NULL, NULL);
    CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF);
  }
  DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth));

  BuildCpuHob (CpuAddressWidth, 16);

  ASSERT_EFI_ERROR (Status);

  return Status;
}
Ejemplo n.º 19
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;
    TPM_PCRINDEX                      PcrIndex;
    BOOLEAN                           S3ErrorReport;

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

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

    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
        //
        Status = Tpm2RequestUseTpm ();
        if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_ERROR, "TPM2 not detected!\n"));
            goto Done;
        }

        S3ErrorReport = FALSE;
        if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {
            if (BootMode == BOOT_ON_S3_RESUME) {
                Status = Tpm2Startup (TPM_SU_STATE);
                if (EFI_ERROR (Status) ) {
                    Status = Tpm2Startup (TPM_SU_CLEAR);
                    if (!EFI_ERROR(Status)) {
                        S3ErrorReport = TRUE;
                    }
                }
            } else {
                Status = Tpm2Startup (TPM_SU_CLEAR);
            }
            if (EFI_ERROR (Status) ) {
                goto Done;
            }
        }

        //
        // Update Tpm2HashMask according to PCR bank.
        //
        SyncPcrAllocationsAndPcrMask ();

        if (S3ErrorReport) {
            //
            // The system firmware that resumes from S3 MUST deal with a
            // TPM2_Startup error appropriately.
            // For example, issue a TPM2_Startup(TPM_SU_CLEAR) command and
            // configuring the device securely by taking actions like extending a
            // separator with an error digest (0x01) into PCRs 0 through 7.
            //
            for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
                Status = MeasureSeparatorEventWithError (PcrIndex);
                if (EFI_ERROR (Status)) {
                    DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured. Error!\n"));
                }
            }
        }

        //
        // 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)) {
                    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, "TPM2 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.º 20
0
/**
  This function will be called when MRC is done.

  @param  PeiServices General purpose services available to every PEIM.

  @param  NotifyDescriptor Information about the notify event..

  @param  Ppi The notify context.

  @retval EFI_SUCCESS If the function completed successfully.
**/
EFI_STATUS
EFIAPI
MemoryDiscoveredPpiNotifyCallback (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  EFI_STATUS                            Status;
  EFI_BOOT_MODE                         BootMode;
  UINT64                                MemoryLength;
  EFI_SMRAM_DESCRIPTOR                  *SmramDescriptor;
  UINTN                                 NumSmramRegions;
  UINT32                                RmuMainBaseAddress;
  UINT32                                RegData32;
  UINT8                                 CpuAddressWidth;
  UINT32                                RegEax;
  MTRR_SETTINGS                         MtrrSettings;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI       *VariableServices;
  UINT8                                 MorControl;
  UINTN                                 DataSize;

  DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n"));

  NumSmramRegions = 0;
  SmramDescriptor = NULL;
  RmuMainBaseAddress = 0;

  PERF_START (NULL, "SetCache", NULL, 0);

  InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions);
  ASSERT (SmramDescriptor != NULL);
  ASSERT (RmuMainBaseAddress != 0);

  MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000;

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

  //
  // Get current MTRR settings
  //
  MtrrGetAllMtrrs (&MtrrSettings);

  //
  // Set all DRAM cachability to CacheWriteBack
  //
  Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0, MemoryLength, CacheWriteBack);
  ASSERT_EFI_ERROR (Status);

  //
  // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
  //             Workaround to make default SMRAM UnCachable
  //
  Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0x30000, SIZE_64KB, CacheUncacheable);
  ASSERT_EFI_ERROR (Status);

  //
  // Set new MTRR settings
  //
  MtrrSetAllMtrrs (&MtrrSettings);

  PERF_END (NULL, "SetCache", NULL, 0);

  //
  // Get necessary PPI
  //
  Status = PeiServicesLocatePpi (
             &gEfiPeiReadOnlyVariable2PpiGuid,           // GUID
             0,                                          // INSTANCE
             NULL,                                       // EFI_PEI_PPI_DESCRIPTOR
             (VOID **)&VariableServices                  // PPI
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Detect MOR request by the OS.
  //
  MorControl = 0;
  DataSize = sizeof (MorControl);
  Status = VariableServices->GetVariable (
                               VariableServices,
                               MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
                               &gEfiMemoryOverwriteControlDataGuid,
                               NULL,
                               &DataSize,
                               &MorControl
                               );
  //
  // If OS requested a memory overwrite perform it now for Embedded SRAM
  //
  if (MOR_CLEAR_MEMORY_VALUE (MorControl)) {
    DEBUG ((EFI_D_INFO, "Clear Embedded SRAM per MOR request.\n"));
    if (PcdGet32 (PcdESramMemorySize) > 0) {
      if (PcdGet32 (PcdEsramStage1Base) == 0) {
        //
        // ZeroMem() generates an ASSERT() if Buffer parameter is NULL.
        // Clear byte at 0 and start clear operation at address 1.
        //
        *(UINT8 *)(0) = 0;
        ZeroMem ((VOID *)1, (UINTN)PcdGet32 (PcdESramMemorySize) - 1);
      } else {
        ZeroMem (
          (VOID *)(UINTN)PcdGet32 (PcdEsramStage1Base),
          (UINTN)PcdGet32 (PcdESramMemorySize)
          );
      }
    }
  }

  //
  // Install PeiReset for PeiResetSystem service
  //
  Status = PeiServicesInstallPpi (&mPpiList[0]);
  ASSERT_EFI_ERROR (Status);

  //
  // Do QNC initialization after MRC
  //
  PeiQNCPostMemInit ();

  Status = PeiServicesInstallPpi (&mPpiStall[0]);
  ASSERT_EFI_ERROR (Status);

  //
  // Set E000/F000 Routing
  //
  RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
  RegData32 |= (BIT2|BIT1);
  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32);

  if (BootMode == BOOT_IN_RECOVERY_MODE) {
    // Do nothing here. A generic RecoveryModule will handle it.
  } else if (BootMode == BOOT_ON_S3_RESUME) {
    return EFI_SUCCESS;
  } else {
    PeiServicesInstallFvInfoPpi (
      NULL,
      (VOID *) (UINTN) PcdGet32 (PcdFlashFvMainBase),
      PcdGet32 (PcdFlashFvMainSize),
      NULL,
      NULL
      );

    //
    // Publish the FVMAIN FV so the DXE Phase can dispatch drivers from this FV
    // and produce Load File Protocols for UEFI Applications in this FV.
    //
    BuildFvHob (
      PcdGet32 (PcdFlashFvMainBase),
      PcdGet32 (PcdFlashFvMainSize)
      );

    //
    // Publish the Payload FV so the DXE Phase can dispatch drivers from this FV
    // and produce Load File Protocols for UEFI Applications in this FV.
    //
    BuildFvHob (
      PcdGet32 (PcdFlashFvPayloadBase),
      PcdGet32 (PcdFlashFvPayloadSize)
      );
  }

  //
  // Build flash HOB, it's going to be used by GCD and E820 building
  // Map full SPI flash decode range (regardless of smaller SPI flash parts installed)
  //
  BuildResourceDescriptorHob (
    EFI_RESOURCE_FIRMWARE_DEVICE,
    (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    (SIZE_4GB - SIZE_8MB),
    SIZE_8MB
    );

  //
  // Create a CPU hand-off information
  //
  CpuAddressWidth = 32;
  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
  if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
    AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
    CpuAddressWidth = (UINT8) (RegEax & 0xFF);
  }
  DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth));

  BuildCpuHob (CpuAddressWidth, 16);

  ASSERT_EFI_ERROR (Status);

  return Status;
}
Ejemplo n.º 21
0
/**
  The user code starts with this function.

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

  @retval EFI_SUCCESS            The driver is successfully initialized.
  @retval Others                 Can't initialize the driver.

**/
EFI_STATUS
EFIAPI
InitializeSdMmcHcPeim (
  IN EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES    **PeiServices
  )
{
  EFI_BOOT_MODE                BootMode;
  EFI_STATUS                   Status;
  UINT16                       Bus;
  UINT16                       Device;
  UINT16                       Function;
  UINT32                       Size;
  UINT64                       MmioSize;
  UINT8                        SubClass;
  UINT8                        BaseClass;
  UINT8                        SlotInfo;
  UINT8                        SlotNum;
  UINT8                        FirstBar;
  UINT8                        Index;
  UINT8                        Slot;
  UINT32                       BarAddr;
  SD_MMC_HC_PEI_PRIVATE_DATA   *Private;

  //
  // Shadow this PEIM to run from memory
  //
  if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
    return EFI_SUCCESS;
  }

  Status = PeiServicesGetBootMode (&BootMode);
  ///
  /// We do not expose this in S3 boot path, because it is only for recovery.
  ///
  if (BootMode == BOOT_ON_S3_RESUME) {
    return EFI_SUCCESS;
  }

  Private = (SD_MMC_HC_PEI_PRIVATE_DATA *) AllocateZeroPool (sizeof (SD_MMC_HC_PEI_PRIVATE_DATA));
  if (Private == NULL) {
    DEBUG ((EFI_D_ERROR, "Failed to allocate memory for SD_MMC_HC_PEI_PRIVATE_DATA! \n"));
    return EFI_OUT_OF_RESOURCES;
  }

  Private->Signature              = SD_MMC_HC_PEI_SIGNATURE;
  Private->SdMmcHostControllerPpi = mSdMmcHostControllerPpi;
  Private->PpiList                = mPpiList;
  Private->PpiList.Ppi            = &Private->SdMmcHostControllerPpi;

  BarAddr = PcdGet32 (PcdSdMmcPciHostControllerMmioBase);
  for (Bus = 0; Bus < 256; Bus++) {
    for (Device = 0; Device < 32; Device++) {
      for (Function = 0; Function < 8; Function++) {
        SubClass  = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0A));
        BaseClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0B));

        if ((SubClass == PCI_SUBCLASS_SD_HOST_CONTROLLER) && (BaseClass == PCI_CLASS_SYSTEM_PERIPHERAL)) {
          //
          // Get the SD/MMC Pci host controller's Slot Info.
          //
          SlotInfo = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, SD_MMC_HC_PEI_SLOT_OFFSET));
          FirstBar = (*(SD_MMC_HC_PEI_SLOT_INFO*)&SlotInfo).FirstBar;
          SlotNum  = (*(SD_MMC_HC_PEI_SLOT_INFO*)&SlotInfo).SlotNum + 1;
          ASSERT ((FirstBar + SlotNum) < MAX_SD_MMC_SLOTS);

          for (Index = 0, Slot = FirstBar; Slot < (FirstBar + SlotNum); Index++, Slot++) {
            //
            // Get the SD/MMC Pci host controller's MMIO region size.
            //
            PciAnd16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (UINT16)~(EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
            PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot), 0xFFFFFFFF);
            Size = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot));

            switch (Size & 0x07) {
              case 0x0:
                //
                // Memory space: anywhere in 32 bit address space
                //
                MmioSize = (~(Size & 0xFFFFFFF0)) + 1;
                break;
              case 0x4:
                //
                // Memory space: anywhere in 64 bit address space
                //
                MmioSize = Size & 0xFFFFFFF0;
                PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4), 0xFFFFFFFF);
                Size = PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4));      
                //
                // Fix the length to support some spefic 64 bit BAR
                //
                Size |= ((UINT32)(-1) << HighBitSet32 (Size));
                //
                // Calculate the size of 64bit bar
                //
                MmioSize  |= LShiftU64 ((UINT64) Size, 32);
                MmioSize  = (~(MmioSize)) + 1;
                //
                // Clean the high 32bits of this 64bit BAR to 0 as we only allow a 32bit BAR.
                //
                PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot + 4), 0);
                break;
              default:
                //
                // Unknown BAR type
                //
                ASSERT (FALSE);
                continue;
            };
            //
            // Assign resource to the SdMmc Pci host controller's MMIO BAR.
            // Enable the SdMmc Pci host controller by setting BME and MSE bits of PCI_CMD register.
            //
            PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot), BarAddr);
            PciOr16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
            //
            // Record the allocated Mmio base address.
            //
            Private->MmioBar[Private->TotalSdMmcHcs].SlotNum++;
            Private->MmioBar[Private->TotalSdMmcHcs].MmioBarAddr[Index] = BarAddr;
            BarAddr += (UINT32)MmioSize;
          }
          Private->TotalSdMmcHcs++;
          ASSERT (Private->TotalSdMmcHcs < MAX_SD_MMC_HCS);
        }
      }
    }
  }

  ///
  /// Install SdMmc Host Controller PPI
  ///
  Status = PeiServicesInstallPpi (&Private->PpiList);

  ASSERT_EFI_ERROR (Status);
  return Status;
}
Ejemplo n.º 22
0
/**
  This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration.

  @param  SetupTpmDevice  TpmDevice configuration in setup driver

  @return TpmDevice configuration
**/
UINT8
DetectTpmDevice (
  IN UINT8 SetupTpmDevice
  )
{
  EFI_STATUS                        Status;
  EFI_BOOT_MODE                     BootMode;
  TCG2_DEVICE_DETECTION             Tcg2DeviceDetection;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *VariablePpi;
  UINTN                             Size;

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

  //
  // In S3, we rely on normal boot Detection, because we save to ReadOnly Variable in normal boot.
  //
  if (BootMode == BOOT_ON_S3_RESUME) {
    DEBUG ((EFI_D_INFO, "DetectTpmDevice: S3 mode\n"));

    Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);
    ASSERT_EFI_ERROR (Status);

    Size = sizeof(TCG2_DEVICE_DETECTION);
    ZeroMem (&Tcg2DeviceDetection, sizeof(Tcg2DeviceDetection));
    Status = VariablePpi->GetVariable (
                            VariablePpi,
                            TCG2_DEVICE_DETECTION_NAME,
                            &gTcg2ConfigFormSetGuid,
                            NULL,
                            &Size,
                            &Tcg2DeviceDetection
                            );
    if (!EFI_ERROR (Status) &&
        (Tcg2DeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) &&
        (Tcg2DeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX)) {
      DEBUG ((EFI_D_ERROR, "TpmDevice from DeviceDetection: %x\n", Tcg2DeviceDetection.TpmDeviceDetected));
      return Tcg2DeviceDetection.TpmDeviceDetected;
    }
  }

  DEBUG ((EFI_D_INFO, "DetectTpmDevice:\n"));

  // dTPM available and not disabled by setup
  // We need check if it is TPM1.2 or TPM2.0
  // So try TPM1.2 command at first

  Status = Tpm12RequestUseTpm ();
  if (EFI_ERROR (Status)) {
    //
    // dTPM not available
    //
    return TPM_DEVICE_NULL;
  }

  if (BootMode == BOOT_ON_S3_RESUME) {
    Status = Tpm12Startup (TPM_ST_STATE);
  } else {
    Status = Tpm12Startup (TPM_ST_CLEAR);
  }
  if (EFI_ERROR (Status)) {
    return TPM_DEVICE_2_0_DTPM;
  }

  // NO initialization needed again.
  Status = PcdSet8S (PcdTpmInitializationPolicy, 0);
  ASSERT_EFI_ERROR (Status);
  return TPM_DEVICE_1_2;
}