Exemple #1
0
/**
  Publish Memory Type Information.

  @param   None

  @retval  EFI_SUCCESS     Success.
  @retval  Others          Errors have occurred.
**/
EFI_STATUS
EFIAPI
PublishMemoryTypeInfo (
  void
  )
{
  EFI_STATUS                      Status;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
  UINTN                           DataSize;
  EFI_MEMORY_TYPE_INFORMATION     MemoryData[EfiMaxMemoryType + 1];

  Status = PeiServicesLocatePpi (
             &gEfiPeiReadOnlyVariable2PpiGuid,
             0,
             NULL,
             &Variable
             );
  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n", Status));
    DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
    //
    // Build the default GUID'd HOB for DXE
    //
    BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) );

    return Status;
  }

  DataSize = sizeof (MemoryData);
  //
  // This variable is saved in BDS stage. Now read it back
  //
  Status = Variable->GetVariable (
                       Variable,
                       EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
                       &gEfiMemoryTypeInformationGuid,
                       NULL,
                       &DataSize,
                       &MemoryData
                       );
  if (EFI_ERROR (Status)) {
    //
    // build default
    //
    DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
    BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) );
  } else {
    //
    // Build the GUID'd HOB for DXE from variable
    //
    DEBUG((EFI_D_ERROR, "Build Hob from variable \n"));
    BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, MemoryData, DataSize);
  }

  return Status;
}
/**
  Worker function to get CPU_FEATURES_DATA pointer.

  @return Pointer to CPU_FEATURES_DATA.
**/
CPU_FEATURES_DATA *
GetCpuFeaturesData (
  VOID
  )
{
  CPU_FEATURES_DATA       *CpuInitData;
  EFI_HOB_GUID_TYPE       *GuidHob;
  VOID                    *DataInHob;
  UINT64                  Data64;

  CpuInitData = NULL;
  GuidHob = GetFirstGuidHob (&mRegisterCpuFeaturesHobGuid);
  if (GuidHob != NULL) {
    DataInHob = GET_GUID_HOB_DATA (GuidHob);
    CpuInitData = (CPU_FEATURES_DATA *) (*(UINTN *) DataInHob);
    ASSERT (CpuInitData != NULL);
  } else {
    CpuInitData = AllocateZeroPool (sizeof (CPU_FEATURES_DATA));
    ASSERT (CpuInitData != NULL);
    //
    // Build location of CPU MP DATA buffer in HOB
    //
    Data64 = (UINT64) (UINTN) CpuInitData;
    BuildGuidDataHob (
      &mRegisterCpuFeaturesHobGuid,
      (VOID *) &Data64,
      sizeof (UINT64)
      );
  }

  return CpuInitData;
}
Exemple #3
0
// May want to put this into a library so you only need the PCD setings if you are using the feature?
VOID
BuildMemoryTypeInformationHob (
  VOID
  )
{
  EFI_MEMORY_TYPE_INFORMATION   Info[10];

  Info[0].Type          = EfiACPIReclaimMemory;
  Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
  Info[1].Type          = EfiACPIMemoryNVS;
  Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
  Info[2].Type          = EfiReservedMemoryType;
  Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
  Info[3].Type          = EfiRuntimeServicesData;
  Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
  Info[4].Type          = EfiRuntimeServicesCode;
  Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
  Info[5].Type          = EfiBootServicesCode;
  Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
  Info[6].Type          = EfiBootServicesData;
  Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
  Info[7].Type          = EfiLoaderCode;
  Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
  Info[8].Type          = EfiLoaderData;
  Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);

  // Terminator for the list
  Info[9].Type          = EfiMaxMemoryType;
  Info[9].NumberOfPages = 0;


  BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
}
/**
  This service register TPM2 device.

  @param Tpm2Device  TPM2 device

  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
  @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.
  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
**/
EFI_STATUS
EFIAPI
Tpm2RegisterTpm2DeviceLib (
  IN TPM2_DEVICE_INTERFACE   *Tpm2Device
  )
{
  TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;

  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &Tpm2Device->ProviderGuid)){
    DEBUG ((EFI_D_ERROR, "WARNING: Tpm2RegisterTpm2DeviceLib - does not support %g registration\n", &Tpm2Device->ProviderGuid));
    return EFI_UNSUPPORTED;
  }

  Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
  if (Tpm2DeviceInterface != NULL) {
    //
    // In PEI phase, there will be shadow driver dispatched again.
    //
    DEBUG ((EFI_D_INFO, "Tpm2RegisterTpm2DeviceLib - Override\n"));
    CopyMem (Tpm2DeviceInterface, Tpm2Device, sizeof(*Tpm2Device));
    return EFI_SUCCESS;
  } else {
    Tpm2Device = BuildGuidDataHob (&mInternalTpm2DeviceInterfaceGuid, Tpm2Device, sizeof(*Tpm2Device));
    if (Tpm2Device != NULL) {
      return EFI_SUCCESS;
    } else {
      return EFI_OUT_OF_RESOURCES;
    }
  }
}
Exemple #5
0
/**
  Entry point of the notification callback function itself within the PEIM.
  It is to get SEC performance data and build HOB to convey the SEC performance
  data to DXE phase.

  @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 Status of the notification.
          The status code returned from this function is ignored.
**/
EFI_STATUS
EFIAPI
SecPerformancePpiCallBack (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  EFI_STATUS                    Status;
  PEI_SEC_PERFORMANCE_PPI       *SecPerf;
  FIRMWARE_SEC_PERFORMANCE      Performance;

  SecPerf = (PEI_SEC_PERFORMANCE_PPI *) Ppi;
  Status = SecPerf->GetPerformance ((CONST EFI_PEI_SERVICES **) PeiServices, SecPerf, &Performance);
  if (!EFI_ERROR (Status)) {
    BuildGuidDataHob (
      &gEfiFirmwarePerformanceGuid,
      &Performance,
      sizeof (FIRMWARE_SEC_PERFORMANCE)
    );
    DEBUG ((DEBUG_INFO, "FPDT: SEC Performance Hob ResetEnd = %ld\n", Performance.ResetEnd));
  }

  return Status;
}
Exemple #6
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
InitializeCpuPeim (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS              Status;
  ARM_MP_CORE_INFO_PPI    *ArmMpCoreInfoPpi;
  UINTN                   ArmCoreCount;
  ARM_CORE_INFO           *ArmCoreInfoTable;

  // Enable program flow prediction, if supported.
  ArmEnableBranchPrediction ();

  // Publish the CPU memory and io spaces sizes
  BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));

  // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
  Status = PeiServicesLocatePpi (&gArmMpCoreInfoPpiGuid, 0, NULL, (VOID**)&ArmMpCoreInfoPpi);
  if (!EFI_ERROR(Status)) {
    // Build the MP Core Info Table
    ArmCoreCount = 0;
    Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
    if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) {
      // Build MPCore Info HOB
      BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);
    }
  }

  return EFI_SUCCESS;
}
/**
  Process FSP HOB list

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

**/
VOID
ProcessFspHobList (
  IN VOID                 *FspHobList
  )
{
  EFI_PEI_HOB_POINTERS  FspHob;

  FspHob.Raw = FspHobList;

  //
  // Add all the HOBs from FSP binary to FSP wrapper
  //
  while (!END_OF_HOB_LIST (FspHob)) {
    if (FspHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
      //
      // Skip FSP binary creates PcdDataBaseHobGuid
      //
      if (!CompareGuid(&FspHob.Guid->Name, &gPcdDataBaseHobGuid)) { 
        BuildGuidDataHob (
          &FspHob.Guid->Name,
          GET_GUID_HOB_DATA(FspHob),
          GET_GUID_HOB_DATA_SIZE(FspHob)
        );
      }
    }
    FspHob.Raw = GET_NEXT_HOB (FspHob);
  }
}
Exemple #8
0
VOID
MemMapInitialization (
  VOID
  )
{
  //
  // Create Memory Type Information HOB
  //
  BuildGuidDataHob (
    &gEfiMemoryTypeInformationGuid,
    mDefaultMemoryTypeInformation,
    sizeof(mDefaultMemoryTypeInformation)
    );

  //
  // Add PCI IO Port space available for PCI resource allocations.
  //
  BuildResourceDescriptorHob (
    EFI_RESOURCE_IO,
    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
    0xC000,
    0x4000
    );

  //
  // Video memory + Legacy BIOS region
  //
  AddIoMemoryRangeHob (0x0A0000, BASE_1MB);

  if (!mXen) {
    UINT32  TopOfLowRam;
    TopOfLowRam = GetSystemMemorySizeBelow4gb ();

    //
    // address       purpose   size
    // ------------  --------  -------------------------
    // max(top, 2g)  PCI MMIO  0xFC000000 - max(top, 2g)
    // 0xFC000000    gap                           44 MB
    // 0xFEC00000    IO-APIC                        4 KB
    // 0xFEC01000    gap                         1020 KB
    // 0xFED00000    HPET                           1 KB
    // 0xFED00400    gap                          111 KB
    // 0xFED1C000    gap (PIIX4) / RCRB (ICH9)     16 KB
    // 0xFED20000    gap                          896 KB
    // 0xFEE00000    LAPIC                          1 MB
    //
    AddIoMemoryRangeHob (TopOfLowRam < BASE_2GB ?
                         BASE_2GB : TopOfLowRam, 0xFC000000);
    AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
    AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
      AddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);
    }
    AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);
  }
}
Exemple #9
0
VOID
SetPlatformBootMode (
  IN CONST EFI_PEI_SERVICES             **PeiServices,
  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
  )
{
  EFI_PLATFORM_SETUP_ID       PlatformSetupId;

  ZeroMem(&PlatformSetupId, sizeof (EFI_PLATFORM_SETUP_ID));

  CopyMem (&PlatformSetupId.SetupGuid,
           &gEfiNormalSetupGuid,
           sizeof (EFI_GUID));

  if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {
    //
    // Recovery mode
    //
    CopyMem (&PlatformSetupId.SetupName,
             SAFE_SETUP_NAME,
             StrSize (SAFE_SETUP_NAME));
    PlatformSetupId.PlatformBootMode = PLATFORM_RECOVERY_MODE;
  } else if (CheckIfSafeMode(PeiServices, PlatformInfoHob)) {
    //
    // Safe mode also called config mode or maintenace mode.
    //
    CopyMem (&PlatformSetupId.SetupName,
             SAFE_SETUP_NAME,
             StrSize (SAFE_SETUP_NAME));
    PlatformSetupId.PlatformBootMode = PLATFORM_SAFE_MODE;

  } else if(0) { // else if (CheckIfManufacturingMode(PeiServices)) {
    //
    // Manufacturing mode
    //
    CopyMem (&PlatformSetupId.SetupName,
             MANUFACTURE_SETUP_NAME,
             StrSize (MANUFACTURE_SETUP_NAME));
    PlatformSetupId.PlatformBootMode = PLATFORM_MANUFACTURING_MODE;

  } else {
    //
    // Default to normal mode.
    //
    CopyMem (&PlatformSetupId.SetupName,
             &NORMAL_SETUP_NAME,
             StrSize (NORMAL_SETUP_NAME));
    PlatformSetupId.PlatformBootMode = PLATFORM_NORMAL_MODE;
  }

  BuildGuidDataHob (
    &gEfiPlatformBootModeGuid,
    &PlatformSetupId,
    sizeof (EFI_PLATFORM_SETUP_ID)
    );
  return;
}
/**
  This service register Hash.

  @param HashInterface  Hash interface

  @retval EFI_SUCCESS          This hash interface is registered successfully.
  @retval EFI_UNSUPPORTED      System does not support register this interface.
  @retval EFI_ALREADY_STARTED  System already register this interface.
**/
EFI_STATUS
EFIAPI
RegisterHashInterfaceLib (
  IN HASH_INTERFACE   *HashInterface
  )
{
  UINTN              Index;
  HASH_INTERFACE_HOB *HashInterfaceHob;
  HASH_INTERFACE_HOB LocalHashInterfaceHob;
  UINT32             HashMask;
  UINT32             BiosSupportedHashMask;
  EFI_STATUS         Status;

  //
  // Check allow
  //
  HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
  if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
    return EFI_UNSUPPORTED;
  }

  HashInterfaceHob = InternalGetHashInterface ();
  if (HashInterfaceHob == NULL) {
    ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
    HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
    if (HashInterfaceHob == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {
    return EFI_OUT_OF_RESOURCES;
  }
  BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
  Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask);
  ASSERT_EFI_ERROR (Status);

  //
  // Check duplication
  //
  for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
    if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
      //
      // In PEI phase, there will be shadow driver dispatched again.
      //
      DEBUG ((EFI_D_INFO, "RegisterHashInterfaceLib - Override\n"));
      CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface));
      return EFI_SUCCESS;
    }
  }

  CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));
  HashInterfaceHob->HashInterfaceCount ++;
  
  return EFI_SUCCESS;
}
Exemple #11
0
VOID
EFIAPI
BuildPeCoffLoaderHob (
  VOID
  )
{
  VOID  *Ptr;      
  
  Ptr = &gPeCoffProtocol;
  BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));  
}
/**
  This function creates hash interface hob.

  @param Identifier    Identifier to create hash interface hob.

  @retval hash interface hob.
**/
HASH_INTERFACE_HOB *
InternalCreateHashInterfaceHob (
  EFI_GUID      *Identifier
  )
{
  HASH_INTERFACE_HOB LocalHashInterfaceHob;

  ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
  CopyGuid (&LocalHashInterfaceHob.Identifier, Identifier);
  return BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
}
Exemple #13
0
VOID
EFIAPI
BuildExtractSectionHob (
  IN  EFI_GUID                                  *Guid,
  IN  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER   SectionGetInfo,
  IN  EXTRACT_GUIDED_SECTION_DECODE_HANDLER     SectionExtraction
  )
{
  EXTRACT_SECTION_DATA Data;
  
  Data.SectionGetInfo    = SectionGetInfo;
  Data.SectionExtraction = SectionExtraction;
  BuildGuidDataHob (Guid, &Data, sizeof (Data));
}
/**
  Get the pointer to Mailbox from IDT entry and build the Mailbox into GUIDed Hob
  after memory is ready.

  @return Pointer to Mailbox.

**/
DEBUG_AGENT_MAILBOX *
BuildMailboxHob (
    VOID
)
{
    DEBUG_AGENT_MAILBOX       *Mailbox;

    Mailbox = (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry ();

    return BuildGuidDataHob (
               &gEfiDebugAgentGuid,
               Mailbox,
               sizeof (DEBUG_AGENT_MAILBOX)
           );
}
EFI_STATUS
EFIAPI
PeimInitializeWinNtThunkPPIToProtocolPeim (
  IN EFI_FFS_FILE_HEADER       *FfsHeader,
  IN EFI_PEI_SERVICES          **PeiServices
  )
/*++

Routine Description:

  Perform a call-back into the SEC simulator to get NT Stuff

Arguments:

  PeiServices - General purpose services available to every PEIM.
    
Returns:

  None

--*/
// TODO:    FfsHeader - add argument and description to function comment
{
  EFI_STATUS              Status;
  EFI_PEI_PPI_DESCRIPTOR  *PpiDescriptor;
  PEI_NT_THUNK_PPI        *PeiNtService;
  VOID                    *Ptr;

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

  Status = (**PeiServices).LocatePpi (
                            (const EFI_PEI_SERVICES **)PeiServices,
                            &gPeiNtThunkPpiGuid,  // GUID
                            0,                    // INSTANCE
                            &PpiDescriptor,       // EFI_PEI_PPI_DESCRIPTOR
                            (VOID**)&PeiNtService         // PPI
                            );
  ASSERT_EFI_ERROR (Status);

  Ptr = PeiNtService->NtThunk ();

  BuildGuidDataHob (
    &gEfiWinNtThunkProtocolGuid,         // Guid
    &Ptr,                                // Buffer
    sizeof (VOID *)                      // Sizeof Buffer
    );
  return Status;
}
/**
  Save the pointer to CPU MP Data structure.

  @param[in] CpuMpData  The pointer to CPU MP Data structure will be saved.
**/
VOID
SaveCpuMpData (
  IN CPU_MP_DATA   *CpuMpData
  )
{
  UINT64           Data64;
  //
  // Build location of CPU MP DATA buffer in HOB
  //
  Data64 = (UINT64) (UINTN) CpuMpData;
  BuildGuidDataHob (
    &mCpuInitMpLibHobGuid,
    (VOID *) &Data64,
    sizeof (UINT64)
    );
}
Exemple #17
0
VOID
MemMapInitialization (
  EFI_PHYSICAL_ADDRESS  TopOfMemory
  )
{
  //
  // Create Memory Type Information HOB
  //
  BuildGuidDataHob (
    &gEfiMemoryTypeInformationGuid,
    mDefaultMemoryTypeInformation,
    sizeof(mDefaultMemoryTypeInformation)
    );

  //
  // Add PCI IO Port space available for PCI resource allocations.
  //
  BuildResourceDescriptorHob (
    EFI_RESOURCE_IO,
    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
    0xC000,
    0x4000
    );

  //
  // Video memory + Legacy BIOS region
  //
  AddIoMemoryRangeHob (0x0A0000, BASE_1MB);

  //
  // address       purpose   size
  // ------------  --------  -------------------------
  // max(top, 2g)  PCI MMIO  0xFC000000 - max(top, 2g)
  // 0xFC000000    gap                           44 MB
  // 0xFEC00000    IO-APIC                        4 KB
  // 0xFEC01000    gap                         1020 KB
  // 0xFED00000    HPET                           1 KB
  // 0xFED00400    gap                         1023 KB
  // 0xFEE00000    LAPIC                          1 MB
  //
  AddIoMemoryRangeHob (TopOfMemory < BASE_2GB ? BASE_2GB : TopOfMemory, 0xFC000000);
  AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
  AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
  AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);
}
/**
  The constructor reads variable and sets HOB

  @param  FileHandle   The handle of FFS header the loaded driver.
  @param  PeiServices  The pointer to the PEI services.

  @retval EFI_SUCCESS  The constructor always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
PeiDebugPrintHobLibConstructor (
  IN EFI_PEI_FILE_HANDLE        FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS                      Status;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
  UINTN                           Size;
  UINT64                          GlobalErrorLevel;
  UINT32                          HobErrorLevel;

  Status = PeiServicesLocatePpi (
             &gEfiPeiReadOnlyVariable2PpiGuid,
             0,
             NULL,
             (VOID **)&Variable
             );
  if (!EFI_ERROR (Status)) {
    Size = sizeof (GlobalErrorLevel);
    Status = Variable->GetVariable (
                         Variable,
                         DEBUG_MASK_VARIABLE_NAME,
                         &gEfiGenericVariableGuid,
                         NULL,
                         &Size,
                         &GlobalErrorLevel
                         );
    if (!EFI_ERROR (Status)) {
      //
      // Build the GUID'ed HOB for DXE
      //
      HobErrorLevel = (UINT32)GlobalErrorLevel;
      BuildGuidDataHob (
        &gEfiGenericVariableGuid,
        &HobErrorLevel,
        sizeof (HobErrorLevel)
        );
    }
  }

  return EFI_SUCCESS;
}
RETURN_STATUS
EFIAPI
ExtractGuidedSectionLibConstructor (
  VOID
  )
{
  PRE_PI_EXTRACT_GUIDED_SECTION_DATA  SavedData;
  GUID                                HobGuid = PRE_PI_EXTRACT_GUIDED_SECTION_DATA_GUID;

  //
  // Allocate global pool space to store the registered handler and its guid value.
  //
  SavedData.ExtractHandlerGuidTable = (GUID *)AllocatePool(PcdGet32(PcdMaximumGuidedExtractHandler) * sizeof(GUID));
  if (SavedData.ExtractHandlerGuidTable == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }
  
  SavedData.ExtractDecodeHandlerTable  = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *)AllocatePool(PcdGet32(PcdMaximumGuidedExtractHandler) * sizeof(EXTRACT_GUIDED_SECTION_DECODE_HANDLER));
  if (SavedData.ExtractDecodeHandlerTable == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  SavedData.ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *)AllocatePool(PcdGet32(PcdMaximumGuidedExtractHandler) * sizeof(EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER));
  if (SavedData.ExtractGetInfoHandlerTable == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }
  
  //
  // the initialized number is Zero.
  //
  SavedData.NumberOfExtractHandler = 0;
  
  BuildGuidDataHob(&HobGuid, &SavedData, sizeof(SavedData));
  
  return RETURN_SUCCESS;
}
Exemple #20
0
VOID
MemMapInitialization (
  EFI_PHYSICAL_ADDRESS  TopOfMemory
  )
{
  EFI_PHYSICAL_ADDRESS RsdPtr;
  EFI_PHYSICAL_ADDRESS AcpiTables;
  //
  // Create Memory Type Information HOB
  //
  BuildGuidDataHob (
    &gEfiMemoryTypeInformationGuid,
    mDefaultMemoryTypeInformation,
    sizeof(mDefaultMemoryTypeInformation)
    );

  //
  // Add PCI IO Port space available for PCI resource allocations.
  //
  BuildResourceDescriptorHob (
    EFI_RESOURCE_IO,
    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
    0xC000,
    0x4000
    );

  //
  // Add PCI MMIO space available to PCI resource allocations
  //
  if (TopOfMemory < BASE_2GB) {
    AddIoMemoryBaseSizeHob (BASE_2GB, 0xFC000000 - BASE_2GB);
  } else {
    AddIoMemoryBaseSizeHob (TopOfMemory, 0xFC000000 - TopOfMemory);
  }

  //
  // Local APIC range
  //
  AddIoMemoryBaseSizeHob (0xFEC80000, SIZE_512KB);

  //
  // I/O APIC range
  //
  AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_512KB);

  //
  // Video memory + Legacy BIOS region
  // This includes ACPI floating pointer region.
  //
  AddIoMemoryRangeHob (0x0A0000, BASE_1MB);


  //
  // Add ACPI memory, provided by VBox
  //
  RsdPtr = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr();
  ASSERT(RsdPtr != 0);
  AcpiTables = (EFI_PHYSICAL_ADDRESS)*(UINT32*)((UINTN)RsdPtr + 16) & ~0xfff;
  ASSERT(AcpiTables != 0);

  // ACPI tables 64 K
  AddRomMemoryBaseSizeHob(AcpiTables, 0x10000);
}
Exemple #21
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;
}
Exemple #22
0
VOID
XenMemMapInitialization (
  VOID
  )
{
  EFI_E820_ENTRY64 *E820Map;
  UINT32 E820EntriesCount;
  EFI_STATUS Status;

  DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));

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

  //
  // Add PCI IO Port space available for PCI resource allocations.
  //
  BuildResourceDescriptorHob (
    EFI_RESOURCE_IO,
    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
    0xC000,
    0x4000
    );

  //
  // Video memory + Legacy BIOS region
  //
  AddIoMemoryRangeHob (0x0A0000, BASE_1MB);

  //
  // Parse RAM in E820 map
  //
  Status = XenGetE820Map(&E820Map, &E820EntriesCount);

  ASSERT_EFI_ERROR (Status);

  if (E820EntriesCount > 0) {
    EFI_E820_ENTRY64 *Entry;
    UINT32 Loop;

    for (Loop = 0; Loop < E820EntriesCount; Loop++) {
      Entry = E820Map + Loop;

      //
      // Only care about RAM
      //
      if (Entry->Type != EfiAcpiAddressRangeMemory) {
        continue;
      }

      if (Entry->BaseAddr >= BASE_4GB) {
        AddUntestedMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);
      } else {
        AddMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);
      }

      MtrrSetMemoryAttribute (Entry->BaseAddr, Entry->Length, CacheWriteBack);
    }
  }
}
Exemple #23
0
/**
   Main entry point to last PEIM. 

   This function finds DXE Core in the firmware volume and transfer the control to
   DXE core.
    
   @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              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;
  EFI_FV_FILE_INFO                          DxeCoreFileInfo;
  EFI_PHYSICAL_ADDRESS                      DxeCoreAddress;
  UINT64                                    DxeCoreSize;
  EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;
  EFI_BOOT_MODE                             BootMode;
  EFI_PEI_FILE_HANDLE                       FileHandle;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI           *Variable;
  EFI_PEI_LOAD_FILE_PPI                     *LoadFile;
  UINTN                                     Instance;
  UINT32                                    AuthenticationState;
  UINTN                                     DataSize;
  EFI_PEI_S3_RESUME2_PPI                    *S3Resume;
  EFI_PEI_RECOVERY_MODULE_PPI               *PeiRecovery;
  EFI_MEMORY_TYPE_INFORMATION               MemoryData[EfiMaxMemoryType + 1];

  //
  // if in S3 Resume, restore configure
  //
  BootMode = GetBootModeHob ();

  if (BootMode == BOOT_ON_S3_RESUME) {
    Status = PeiServicesLocatePpi (
               &gEfiPeiS3Resume2PpiGuid,
               0,
               NULL,
               (VOID **) &S3Resume
               );
    if (EFI_ERROR (Status)) {
      //
      // Report Status code that S3Resume PPI can not be found
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND)
        );
    }
    ASSERT_EFI_ERROR (Status);
    
    Status = S3Resume->S3RestoreConfig2 (S3Resume);
    ASSERT_EFI_ERROR (Status);
  } else if (BootMode == BOOT_IN_RECOVERY_MODE) {
    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN));
    Status = PeiServicesLocatePpi (
               &gEfiPeiRecoveryModulePpiGuid,
               0,
               NULL,
               (VOID **) &PeiRecovery
               );

    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status));
      //
      // Report Status code the failure of locating Recovery PPI 
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)
        );
      CpuDeadLoop ();
    }

    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD));
    Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
      //
      // Report Status code that recovery image can not be found
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE)
        );
      CpuDeadLoop ();
    }
    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START));
    //
    // Now should have a HOB with the DXE core
    //
  }

  if (GetFirstGuidHob ((CONST EFI_GUID *)&gEfiMemoryTypeInformationGuid) == NULL) {
    //
    // Don't build GuidHob if GuidHob has been installed.
    //
    Status = PeiServicesLocatePpi (
               &gEfiPeiReadOnlyVariable2PpiGuid,
               0,
               NULL,
               (VOID **)&Variable
               );
    if (!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)) {
        //
        // Build the GUID'd HOB for DXE
        //
        BuildGuidDataHob (
          &gEfiMemoryTypeInformationGuid,
          MemoryData,
          DataSize
          );
      }
    }
  }

  //
  // Look in all the FVs present in PEI and find the DXE Core FileHandle
  //
  FileHandle = DxeIplFindDxeCore ();

  //
  // Load the DXE Core from a Firmware Volume.
  //
  Instance = 0;
  do {
    Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **) &LoadFile);
    //
    // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.
    //
    ASSERT_EFI_ERROR (Status);

    Status = LoadFile->LoadFile (
                         LoadFile,
                         FileHandle,
                         &DxeCoreAddress,
                         &DxeCoreSize,
                         &DxeCoreEntryPoint,
                         &AuthenticationState
                         );
  } while (EFI_ERROR (Status));

  //
  // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.
  //
  Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo);
  ASSERT_EFI_ERROR (Status);

  //
  // Add HOB for the DXE Core
  //
  BuildModuleHob (
    &DxeCoreFileInfo.FileName,
    DxeCoreAddress,
    ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE),
    DxeCoreEntryPoint
    );

  //
  // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
  //
  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT));

  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));

  //
  // Transfer control to the DXE Core
  // The hand off state is simply a pointer to the HOB list
  //
  HandOffToDxeCore (DxeCoreEntryPoint, HobList);
  //
  // If we get here, then the DXE Core returned.  This is an error
  // DxeCore should not return.
  //
  ASSERT (FALSE);
  CpuDeadLoop ();

  return EFI_OUT_OF_RESOURCES;
}
/**
  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;
  }
}
Exemple #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, HighMemorySize;
  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;

  LowMemorySize = 0;
  HighMemorySize = 0;

  Status = CbParseMemoryInfo (&LowMemorySize, &HighMemorySize);
  if (EFI_ERROR(Status))
    return Status;

  DEBUG((EFI_D_ERROR, "LowMemorySize: 0x%lx.\n", LowMemorySize));
  DEBUG((EFI_D_ERROR, "HighMemorySize: 0x%lx.\n", HighMemorySize));

  ASSERT (LowMemorySize > 0);

  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
    ),
    (EFI_PHYSICAL_ADDRESS)(0),
    (UINT64)(0xA0000)
    );


  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)
    );

   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
    ),
    (EFI_PHYSICAL_ADDRESS)(0x100000),
    (UINT64) (LowMemorySize - 0x100000)
    );

  if (HighMemorySize > 0) {
    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
    ),
    (EFI_PHYSICAL_ADDRESS)(0x100000000ULL),
    HighMemorySize
    );
  }

  //
  // 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));
    PcdSet32 (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);
  }

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

  //
  // Mask off all legacy 8259 interrupt sources
  //
  IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
  IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE,  0xFF);

  return EFI_SUCCESS;
}
Exemple #26
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;
}
/**
  Registers handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and EXTRACT_GUIDED_SECTION_DECODE_HANDLER
  for a specific GUID section type.

  Registers the handlers specified by GetInfoHandler and DecodeHandler with the GUID specified by SectionGuid.
  If the GUID value specified by SectionGuid has already been registered, then return RETURN_ALREADY_STARTED.
  If there are not enough resources available to register the handlers  then RETURN_OUT_OF_RESOURCES is returned.
  
  If SectionGuid is NULL, then ASSERT().
  If GetInfoHandler is NULL, then ASSERT().
  If DecodeHandler is NULL, then ASSERT().

  @param[in]  SectionGuid    A pointer to the GUID associated with the the handlers
                             of the GUIDed section type being registered.
  @param[in]  GetInfoHandler The pointer to a function that examines a GUIDed section and returns the
                             size of the decoded buffer and the size of an optional scratch buffer
                             required to actually decode the data in a GUIDed section.
  @param[in]  DecodeHandler  The pointer to a function that decodes a GUIDed section into a caller
                             allocated output buffer. 

  @retval  RETURN_SUCCESS           The handlers were registered.
  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources available to register the handlers.

**/
RETURN_STATUS
EFIAPI
ExtractGuidedSectionRegisterHandlers (
  IN CONST  GUID                                     *SectionGuid,
  IN        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  GetInfoHandler,
  IN        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    DecodeHandler
  )
{
  EFI_STATUS Status;
  UINT32     Index;
  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

  //
  // Check input parameter
  //
  ASSERT (SectionGuid != NULL);
  ASSERT (GetInfoHandler != NULL);
  ASSERT (DecodeHandler != NULL);



  //
  // Get the registered handler information
  //
  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Search the match registered GetInfo handler for the input guided section.
  //
  ASSERT (HandlerInfo != NULL);
  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {
      //
      // If the guided handler has been registered before, only update its handler.
      //
      HandlerInfo->ExtractDecodeHandlerTable [Index] = DecodeHandler;
      HandlerInfo->ExtractGetInfoHandlerTable [Index] = GetInfoHandler;
      return RETURN_SUCCESS;
    }
  }

  //
  // Check the global table is enough to contain new Handler.
  //
  if (HandlerInfo->NumberOfExtractHandler >= PcdGet32 (PcdMaximumGuidedExtractHandler)) {
    return RETURN_OUT_OF_RESOURCES;
  }
  
  //
  // Register new Handler and guid value.
  //
  CopyGuid (HandlerInfo->ExtractHandlerGuidTable + HandlerInfo->NumberOfExtractHandler, SectionGuid);
  HandlerInfo->ExtractDecodeHandlerTable [HandlerInfo->NumberOfExtractHandler] = DecodeHandler;
  HandlerInfo->ExtractGetInfoHandlerTable [HandlerInfo->NumberOfExtractHandler++] = GetInfoHandler;

  //
  // Build the Guided Section GUID HOB to record the GUID itself.
  // Then the content of the GUIDed HOB will be the same as the GUID value itself.
  //
  BuildGuidDataHob (
    (EFI_GUID *) SectionGuid,
    (VOID *) SectionGuid,
    sizeof (GUID)
    );

  return RETURN_SUCCESS;
}
/**
 *---------------------------------------------------------------------------------------
 *  PlatInitPeiEntryPoint
 *
 *  Description:
 *    Entry point of the PlatInit PEI module.
 *
 *  Control flow:
 *    Query platform parameters via ISCP.
 *
 *  Parameters:
 *    @param[in]      FfsHeader            EFI_PEI_FILE_HANDLE
 *    @param[in]      **PeiServices        Pointer to the PEI Services Table.
 *
 *    @return         EFI_STATUS
 *
 *---------------------------------------------------------------------------------------
 */
EFI_STATUS
EFIAPI
PlatInitPeiEntryPoint (
  IN       EFI_PEI_FILE_HANDLE      FfsHeader,
  IN       CONST EFI_PEI_SERVICES   **PeiServices
  )
{
  EFI_STATUS                  Status = EFI_SUCCESS;
  AMD_MEMORY_RANGE_DESCRIPTOR IscpMemDescriptor = {0};
  ISCP_FUSE_INFO              IscpFuseInfo = {0};
  ISCP_CPU_RESET_INFO         CpuResetInfo = {0};
#if DO_XGBE == 1
  ISCP_MAC_INFO               MacAddrInfo = {0};
  UINT64                      MacAddr0, MacAddr1;
#endif
  UINTN                       CpuCoreCount, CpuMap, CpuMapSize;
  UINTN                       Index, CoreNum;
  UINT32                      *CpuIdReg = (UINT32 *)FixedPcdGet32 (PcdCpuIdRegister);

  DEBUG ((EFI_D_ERROR, "PlatInit PEIM Loaded\n"));

  // CPUID
  PcdSet32 (PcdSocCpuId, *CpuIdReg);
  DEBUG ((EFI_D_ERROR, "SocCpuId = 0x%X\n", PcdGet32 (PcdSocCpuId)));

  // Update core count based on PCD option
  if (mAmdCoreCount > PcdGet32 (PcdSocCoreCount)) {
    mAmdCoreCount = PcdGet32 (PcdSocCoreCount);
  }

  if (FixedPcdGetBool (PcdIscpSupport)) {
    Status = PeiServicesLocatePpi (&gPeiIscpPpiGuid, 0, NULL, (VOID**)&PeiIscpPpi);
    ASSERT_EFI_ERROR (Status);

    // Get fuse information from ISCP
    Status = PeiIscpPpi->ExecuteFuseTransaction (PeiServices, &IscpFuseInfo);
    ASSERT_EFI_ERROR (Status);

    CpuMap = IscpFuseInfo.SocConfiguration.CpuMap;
    CpuCoreCount = IscpFuseInfo.SocConfiguration.CpuCoreCount;
    CpuMapSize = sizeof (IscpFuseInfo.SocConfiguration.CpuMap) * 8;

    ASSERT (CpuMap != 0);
    ASSERT (CpuCoreCount != 0);
    ASSERT (CpuCoreCount <= CpuMapSize);

    // Update core count based on fusing
    if (mAmdCoreCount > CpuCoreCount) {
      mAmdCoreCount = CpuCoreCount;
    }
  }

  //
  // Update per-core information from ISCP
  //
  if (!FixedPcdGetBool (PcdIscpSupport)) {
    DEBUG ((EFI_D_ERROR, "Warning: Could not get CPU info via ISCP, using default values.\n"));
  } else {
    //
    // Walk CPU map to enumerate active cores
    //
    for (CoreNum = 0, Index = 0; CoreNum < CpuMapSize && Index < mAmdCoreCount; ++CoreNum) {
      if (CpuMap & 1) {
        CpuResetInfo.CoreNum = CoreNum;
        Status = PeiIscpPpi->ExecuteCpuRetrieveIdTransaction (
                   PeiServices, &CpuResetInfo );
        ASSERT_EFI_ERROR (Status);
        ASSERT (CpuResetInfo.CoreStatus.Status != CPU_CORE_DISABLED);
        ASSERT (CpuResetInfo.CoreStatus.Status != CPU_CORE_UNDEFINED);

        mAmdMpCoreInfoTable[Index].ClusterId = CpuResetInfo.CoreStatus.ClusterId;
        mAmdMpCoreInfoTable[Index].CoreId = CpuResetInfo.CoreStatus.CoreId;

        DEBUG ((EFI_D_ERROR, "Core[%d]: ClusterId = %d   CoreId = %d\n",
          Index, mAmdMpCoreInfoTable[Index].ClusterId,
          mAmdMpCoreInfoTable[Index].CoreId));

        // Next core in Table
        ++Index;
      }
      // Next core in Map
      CpuMap >>= 1;
    }

    // Update core count based on CPU map
    if (mAmdCoreCount > Index) {
      mAmdCoreCount = Index;
    }
  }

  // Update SocCoreCount on Dynamic PCD
  if (PcdGet32 (PcdSocCoreCount) != mAmdCoreCount) {
    PcdSet32 (PcdSocCoreCount, mAmdCoreCount);
  }

  DEBUG ((EFI_D_ERROR, "SocCoreCount = %d\n", PcdGet32 (PcdSocCoreCount)));

  // Build AmdMpCoreInfo HOB
  BuildGuidDataHob (&gAmdStyxMpCoreInfoGuid, mAmdMpCoreInfoTable, sizeof (ARM_CORE_INFO) * mAmdCoreCount);

  // Get SystemMemorySize from ISCP
  IscpMemDescriptor.Size0 = 0;
  if (FixedPcdGetBool (PcdIscpSupport)) {
    Status = PeiIscpPpi->ExecuteMemoryTransaction (PeiServices, &IscpMemDescriptor);
    ASSERT_EFI_ERROR (Status);

    // Update SystemMemorySize on Dynamic PCD
    if (IscpMemDescriptor.Size0) {
      PcdSet64 (PcdSystemMemorySize, IscpMemDescriptor.Size0);
    }
  }
  if (IscpMemDescriptor.Size0 == 0) {
    DEBUG ((EFI_D_ERROR, "Warning: Could not get SystemMemorySize via ISCP, using default value.\n"));
  }

  DEBUG ((EFI_D_ERROR, "SystemMemorySize = %ld\n", PcdGet64 (PcdSystemMemorySize)));

#if DO_XGBE == 1
  // Get MAC Address from ISCP
  if (FixedPcdGetBool (PcdIscpSupport)) {
    Status = PeiIscpPpi->ExecuteGetMacAddressTransaction (
               PeiServices, &MacAddrInfo );
    ASSERT_EFI_ERROR (Status);

    MacAddr0 = MacAddr1 = 0;
    for (Index = 0; Index < 6; ++Index) {
      MacAddr0 |= (UINT64)MacAddrInfo.MacAddress0[Index] << (Index * 8);
      MacAddr1 |= (UINT64)MacAddrInfo.MacAddress1[Index] << (Index * 8);
    }
    PcdSet64 (PcdEthMacA, MacAddr0);
    PcdSet64 (PcdEthMacB, MacAddr1);
  }

  DEBUG ((EFI_D_ERROR, "EthMacA = 0x%lX\n", PcdGet64 (PcdEthMacA)));
  DEBUG ((EFI_D_ERROR, "EthMacB = 0x%lX\n", PcdGet64 (PcdEthMacB)));
#endif

  // Let other PEI modules know we're done!
  Status = (*PeiServices)->InstallPpi (PeiServices, &mPlatInitPpiDescriptor);
  ASSERT_EFI_ERROR (Status);

  return Status;
}
/**
  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;
}
Exemple #30
0
VOID
MemMapInitialization (
  VOID
  )
{
  //
  // Create Memory Type Information HOB
  //
  BuildGuidDataHob (
    &gEfiMemoryTypeInformationGuid,
    mDefaultMemoryTypeInformation,
    sizeof(mDefaultMemoryTypeInformation)
    );

  //
  // Add PCI IO Port space available for PCI resource allocations.
  //
  BuildResourceDescriptorHob (
    EFI_RESOURCE_IO,
    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
    PcdGet64 (PcdPciIoBase),
    PcdGet64 (PcdPciIoSize)
    );

  //
  // Video memory + Legacy BIOS region
  //
  AddIoMemoryRangeHob (0x0A0000, BASE_1MB);

  if (!mXen) {
    UINT32  TopOfLowRam;
    UINT64  PciExBarBase;
    UINT32  PciBase;
    UINT32  PciSize;

    TopOfLowRam = GetSystemMemorySizeBelow4gb ();
    PciExBarBase = 0;
    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
      //
      // The MMCONFIG area is expected to fall between the top of low RAM and
      // the base of the 32-bit PCI host aperture.
      //
      PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);
      ASSERT (TopOfLowRam <= PciExBarBase);
      ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
      PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
    } else {
      PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;
    }

    //
    // address       purpose   size
    // ------------  --------  -------------------------
    // max(top, 2g)  PCI MMIO  0xFC000000 - max(top, 2g)
    // 0xFC000000    gap                           44 MB
    // 0xFEC00000    IO-APIC                        4 KB
    // 0xFEC01000    gap                         1020 KB
    // 0xFED00000    HPET                           1 KB
    // 0xFED00400    gap                          111 KB
    // 0xFED1C000    gap (PIIX4) / RCRB (ICH9)     16 KB
    // 0xFED20000    gap                          896 KB
    // 0xFEE00000    LAPIC                          1 MB
    //
    PciSize = 0xFC000000 - PciBase;
    AddIoMemoryBaseSizeHob (PciBase, PciSize);
    PcdSet64 (PcdPciMmio32Base, PciBase);
    PcdSet64 (PcdPciMmio32Size, PciSize);
    AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
    AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
      AddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);
      //
      // Note: there should be an
      //
      //   AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
      //
      // call below, just like the one above for RCBA. However, Linux insists
      // that the MMCONFIG area be marked in the E820 or UEFI memory map as
      // "reserved memory" -- Linux does not content itself with a simple gap
      // in the memory map wherever the MCFG ACPI table points to.
      //
      // This appears to be a safety measure. The PCI Firmware Specification
      // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can
      // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory
      // [...]". (Emphasis added here.)
      //
      // Normally we add memory resource descriptor HOBs in
      // QemuInitializeRam(), and pre-allocate from those with memory
      // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area
      // is most definitely not RAM; so, as an exception, cover it with
      // uncacheable reserved memory right here.
      //
      AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
      BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,
        EfiReservedMemoryType);
    }
    AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);
  }
}