/** Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI. @param PeiServices The pointer to the PEI Services Table. @param StructureSize The pointer to the variable describing size of the input buffer. @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2. @retval EFI_SUCCESS The data was successfully returned. @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to hold the record is returned in StructureSize. **/ EFI_STATUS EFIAPI SecPlatformInformation2 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN OUT UINT64 *StructureSize, OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2 ) { EFI_HOB_GUID_TYPE *GuidHob; VOID *DataInHob; UINTN DataSize; GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformation2PpiGuid); if (GuidHob == NULL) { *StructureSize = 0; return EFI_SUCCESS; } DataInHob = GET_GUID_HOB_DATA (GuidHob); DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); // // return the information from BistHob // if ((*StructureSize) < (UINT64) DataSize) { *StructureSize = (UINT64) DataSize; return EFI_BUFFER_TOO_SMALL; } *StructureSize = (UINT64) DataSize; CopyMem (PlatformInformationRecord2, DataInHob, DataSize); return EFI_SUCCESS; }
// // Initialization // EFI_STATUS EFIAPI InitializePnvDxe ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { VOID *Hob; VOID *DeviceTreeBase; EFI_STATUS Status; // // Recover the DeviceTree HOB and install it in the configuration table // Hob = GetFirstGuidHob(&gFdtHobGuid); if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) { DEBUG ((EFI_D_ERROR, "%a: No FDT HOB found\n", __FUNCTION__)); return EFI_NOT_FOUND; } DeviceTreeBase = (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob); if (fdt_check_header (DeviceTreeBase) != 0) { DEBUG ((EFI_D_ERROR, "%a: DTB Invalid @ 0x%p\n", __FUNCTION__, DeviceTreeBase)); return EFI_NOT_FOUND; } Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DeviceTreeBase); ASSERT_EFI_ERROR (Status); DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, DeviceTreeBase)); return EFI_SUCCESS; }
EFI_STATUS PlatformHobCreateFromFsp ( IN CONST EFI_PEI_SERVICES **PeiServices, VOID *HobList ) { VOID *HobData; VOID *NewHobData; UINTN DataSize; // // Other hob, todo: put this into FspWrapPlatformLib // if ((HobList = GetNextGuidHob (&gEfiMemoryConfigDataGuid, HobList)) != NULL) { HobData = GET_GUID_HOB_DATA (HobList); DataSize = GET_GUID_HOB_DATA_SIZE(HobList); DEBUG((EFI_D_ERROR, "gEfiMemoryConfigDataGuid Hob found: 0x%x.\n", DataSize)); NewHobData = BuildGuidHob (&gEfiMemoryConfigDataGuid, DataSize); (*PeiServices)->CopyMem ( NewHobData, HobData, DataSize ); } return EFI_SUCCESS; }
/** Worker function to parse CPU BIST information from Guided HOB. @param[out] StructureSize Pointer to the variable describing size of the input buffer. @param[out] StructureBuffer Pointer to the buffer save CPU BIST information. @retval EFI_SUCCESS The data was successfully returned. @retval EFI_BUFFER_TOO_SMALL The buffer was too small. **/ EFI_STATUS GetBistFromHob ( IN OUT UINT64 *StructureSize, IN OUT VOID *StructureBuffer ) { EFI_HOB_GUID_TYPE *GuidHob; VOID *DataInHob; UINTN DataSize; GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); if (GuidHob == NULL) { *StructureSize = 0; return EFI_SUCCESS; } DataInHob = GET_GUID_HOB_DATA (GuidHob); DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); // // return the information from BistHob // if ((*StructureSize) < (UINT64) DataSize) { *StructureSize = (UINT64) DataSize; return EFI_BUFFER_TOO_SMALL; } *StructureSize = (UINT64) DataSize; CopyMem (StructureBuffer, DataInHob, DataSize); 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); } }
// // Return list of cores in the system // EFI_STATUS PrePeiCoreGetMpCoreInfo ( OUT UINTN *ArmCoreCount, OUT ARM_CORE_INFO **ArmCoreInfoTable ) { EFI_PEI_HOB_POINTERS Hob; if (ArmIsMpCore()) { // Iterate through the HOBs and find if there is ARM PROCESSOR ENTRY HOB for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { // Check for Correct HOB type if ((GET_HOB_TYPE (Hob)) == EFI_HOB_TYPE_GUID_EXTENSION) { // Check for correct GUID type if (CompareGuid(&(Hob.Guid->Name), &gAmdStyxMpCoreInfoGuid)) { *ArmCoreInfoTable = (ARM_CORE_INFO *) GET_GUID_HOB_DATA(Hob); *ArmCoreCount = GET_GUID_HOB_DATA_SIZE(Hob)/sizeof(ARM_CORE_INFO); return EFI_SUCCESS; } } } } return EFI_UNSUPPORTED; }
UINT64 GetPciExpressBaseAddressForRootBridge ( IN UINTN HostBridgeNumber, IN UINTN RootBridgeNumber ) /*++ Routine Description: This routine is to get PciExpress Base Address for this RootBridge Arguments: HostBridgeNumber - The number of HostBridge RootBridgeNumber - The number of RootBridge Returns: UINT64 - PciExpressBaseAddress for this HostBridge and RootBridge --*/ { EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION *PciExpressBaseAddressInfo; UINTN BufferSize; UINT32 Index; UINT32 Number; EFI_PEI_HOB_POINTERS GuidHob; // // Get PciExpressAddressInfo Hob // PciExpressBaseAddressInfo = NULL; BufferSize = 0; GuidHob.Raw = GetFirstGuidHob (&gEfiPciExpressBaseAddressGuid); if (GuidHob.Raw != NULL) { PciExpressBaseAddressInfo = GET_GUID_HOB_DATA (GuidHob.Guid); BufferSize = GET_GUID_HOB_DATA_SIZE (GuidHob.Guid); } else { return 0; } // // Search the PciExpress Base Address in the Hob for current RootBridge // Number = (UINT32)(BufferSize / sizeof(EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION)); for (Index = 0; Index < Number; Index++) { if ((PciExpressBaseAddressInfo[Index].HostBridgeNumber == HostBridgeNumber) && (PciExpressBaseAddressInfo[Index].RootBridgeNumber == RootBridgeNumber)) { return PciExpressBaseAddressInfo[Index].PciExpressBaseAddress; } } // // Do not find the PciExpress Base Address in the Hob // return 0; }
/** Program hardware of Serial port @return RETURN_NOT_FOUND if no PL011 base address could be found Otherwise, result of PL011UartInitializePort () is returned **/ RETURN_STATUS EFIAPI FdtPL011SerialPortLibInitialize ( VOID ) { VOID *Hob; CONST UINT64 *UartBase; UINT64 BaudRate; UINT32 ReceiveFifoDepth; EFI_PARITY_TYPE Parity; UINT8 DataBits; EFI_STOP_BITS_TYPE StopBits; Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid); if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof *UartBase) { return RETURN_NOT_FOUND; } UartBase = GET_GUID_HOB_DATA (Hob); mSerialBaseAddress = (UINTN)*UartBase; if (mSerialBaseAddress == 0) { return RETURN_NOT_FOUND; } BaudRate = (UINTN)PcdGet64 (PcdUartDefaultBaudRate); ReceiveFifoDepth = 0; // Use the default value for Fifo depth Parity = (EFI_PARITY_TYPE)PcdGet8 (PcdUartDefaultParity); DataBits = PcdGet8 (PcdUartDefaultDataBits); StopBits = (EFI_STOP_BITS_TYPE) PcdGet8 (PcdUartDefaultStopBits); return PL011UartInitializePort ( mSerialBaseAddress, FixedPcdGet32 (PL011UartClkInHz), &BaudRate, &ReceiveFifoDepth, &Parity, &DataBits, &StopBits ); }
void GetTempRamStack ( VOID **TempRamStackPtr, uint16_t *DataSize ) { EFI_GUID FspBootloaderTemporaryMemoryHobGuid = FSP_BOOTLOADER_TEMPORARY_MEMORY_HOB_GUID; uint8_t *GuidHob; EFI_HOB_GENERIC_HEADER *GuidHobHdr; GuidHob = GetFirstGuidHob(&FspBootloaderTemporaryMemoryHobGuid); if (!GuidHob) { *TempRamStackPtr = 0; *DataSize = 0; } else { *TempRamStackPtr = GET_GUID_HOB_DATA (GuidHob); GuidHobHdr = (EFI_HOB_GENERIC_HEADER *)GuidHob; *DataSize = GET_GUID_HOB_DATA_SIZE (GuidHobHdr); } }
void GetFspNVStorageMemory ( VOID **FspNVStorageHob, uint16_t *DataSize ) { EFI_GUID FspNVStorageHobGuid = FSP_NON_VOLATILE_STORAGE_HOB_GUID; uint8_t *GuidHob; EFI_HOB_GENERIC_HEADER *GuidHobHdr; GuidHob = GetFirstGuidHob(&FspNVStorageHobGuid); if (!GuidHob) { *FspNVStorageHob = 0; *DataSize = 0; } else { *FspNVStorageHob = GET_GUID_HOB_DATA (GuidHob); GuidHobHdr = (EFI_HOB_GENERIC_HEADER *)GuidHob; *DataSize = GET_GUID_HOB_DATA_SIZE (GuidHobHdr); } }
/** Returns the debug print error level mask for the current module. @return Debug print error level mask for the current module. **/ UINT32 EFIAPI GetDebugPrintErrorLevel ( VOID ) { EFI_STATUS Status; EFI_TPL CurrentTpl; UINTN Size; UINTN GlobalErrorLevel; VOID *Hob; // // If the constructor has not been executed yet, then just return the PCD value. // This case should only occur if debug print is generated by a library // constructor for this module // if (mSystemTable == NULL) { return PcdGet32 (PcdDebugPrintErrorLevel); } // // Check to see if an attempt has been made to retrieve the global debug print // error level mask. Since this library instance stores the global debug print // error level mask in an EFI Variable, the EFI Variable should only be accessed // once to reduce the overhead of reading the EFI Variable on every debug print // if (!mGlobalErrorLevelInitialized) { // // Make sure the TPL Level is low enough for EFI Variable Services to be called // CurrentTpl = mSystemTable->BootServices->RaiseTPL (TPL_HIGH_LEVEL); mSystemTable->BootServices->RestoreTPL (CurrentTpl); if (CurrentTpl <= TPL_CALLBACK) { // // Attempt to retrieve the global debug print error level mask from the // EFI Variable // Size = sizeof (GlobalErrorLevel); Status = mSystemTable->RuntimeServices->GetVariable ( DEBUG_MASK_VARIABLE_NAME, &gEfiGenericVariableGuid, NULL, &Size, &GlobalErrorLevel ); if (Status != EFI_NOT_AVAILABLE_YET) { // // If EFI Variable Services are available, then set a flag so the EFI // Variable will not be read again by this module. // mGlobalErrorLevelInitialized = TRUE; if (!EFI_ERROR (Status)) { // // If the EFI Varible exists, then set this module's module's mask to // the global debug print error level mask value. // mDebugPrintErrorLevel = (UINT32)GlobalErrorLevel; } } else { // // If variable services are not yet availible optionally get the global // debug print error level mask from a HOB. // Hob = GetFirstGuidHob (&gEfiGenericVariableGuid); if (Hob != NULL) { if (GET_GUID_HOB_DATA_SIZE (Hob) == sizeof (UINT32)) { mDebugPrintErrorLevel = *(UINT32 *)GET_GUID_HOB_DATA (Hob); mGlobalErrorLevelInitialized = TRUE; } } } } } // // Return the current mask value for this module. // return mDebugPrintErrorLevel; }
/** This routine adjust the memory information for different memory type and save them into the variables for next boot. **/ VOID BdsSetMemoryTypeInformationVariable ( VOID ) { EFI_STATUS Status; EFI_MEMORY_TYPE_INFORMATION *PreviousMemoryTypeInformation; EFI_MEMORY_TYPE_INFORMATION *CurrentMemoryTypeInformation; UINTN VariableSize; UINTN Index; UINTN Index1; UINT32 Previous; UINT32 Current; UINT32 Next; EFI_HOB_GUID_TYPE *GuidHob; BOOLEAN MemoryTypeInformationModified; BOOLEAN MemoryTypeInformationVariableExists; EFI_BOOT_MODE BootMode; MemoryTypeInformationModified = FALSE; MemoryTypeInformationVariableExists = FALSE; BootMode = GetBootModeHob (); // // In BOOT_IN_RECOVERY_MODE, Variable region is not reliable. // if (BootMode == BOOT_IN_RECOVERY_MODE) { return; } // // Only check the the Memory Type Information variable in the boot mode // other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type // Information is not valid in this boot mode. // if (BootMode != BOOT_WITH_DEFAULT_SETTINGS) { VariableSize = 0; Status = gRT->GetVariable ( EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, &gEfiMemoryTypeInformationGuid, NULL, &VariableSize, NULL ); if (Status == EFI_BUFFER_TOO_SMALL) { MemoryTypeInformationVariableExists = TRUE; } } // // Retrieve the current memory usage statistics. If they are not found, then // no adjustments can be made to the Memory Type Information variable. // Status = EfiGetSystemConfigurationTable ( &gEfiMemoryTypeInformationGuid, (VOID **) &CurrentMemoryTypeInformation ); if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) { return; } // // Get the Memory Type Information settings from Hob if they exist, // PEI is responsible for getting them from variable and build a Hob to save them. // If the previous Memory Type Information is not available, then set defaults // GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid); if (GuidHob == NULL) { // // If Platform has not built Memory Type Info into the Hob, just return. // return; } PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob); VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob); // // Use a heuristic to adjust the Memory Type Information for the next boot // // DEBUG ((EFI_D_INFO, "Memory Previous Current Next \n")); // DEBUG ((EFI_D_INFO, " Type Pages Pages Pages \n")); // DEBUG ((EFI_D_INFO, "====== ======== ======== ========\n")); for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) { if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) { break; } } if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) { continue; } // // Previous is the number of pages pre-allocated // Current is the number of pages actually needed // Previous = PreviousMemoryTypeInformation[Index].NumberOfPages; Current = CurrentMemoryTypeInformation[Index1].NumberOfPages; Next = Previous; // // Inconsistent Memory Reserved across bootings may lead to S4 fail // Write next varible to 125% * current when the pre-allocated memory is: // 1. More than 150% of needed memory and boot mode is BOOT_WITH_DEFAULT_SETTING // 2. Less than the needed memory // if (Current < Previous) { if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { Next = Current + (Current >> 2); } else if (!MemoryTypeInformationVariableExists) { Next = MAX (Current + (Current >> 2), Previous); }
EFI_STATUS EFIAPI SaveMemoryConfigEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: This is the standard EFI driver point that detects whether there is a MemoryConfigurationData HOB and, if so, saves its data to nvRAM. Arguments: ImageHandle - Handle for the image of this driver SystemTable - Pointer to the EFI System Table Returns: EFI_SUCCESS - if the data is successfully saved or there was no data EFI_NOT_FOUND - if the HOB list could not be located. EFI_UNLOAD_IMAGE - It is not success --*/ { EFI_STATUS Status; VOID *HobList; EFI_HOB_GUID_TYPE *GuidHob; VOID *HobData; VOID *VariableData; UINTN DataSize; UINTN BufferSize; DataSize = 0; VariableData = NULL; GuidHob = NULL; HobList = NULL; HobData = NULL; Status = EFI_UNSUPPORTED; // // Get the HOB list. If it is not present, then ASSERT. // HobList = GetHobList (); ASSERT (HobList != NULL); // // Search for the Memory Configuration GUID HOB. If it is not present, then // there's nothing we can do. It may not exist on the update path. // GuidHob = GetNextGuidHob (&gEfiMemoryConfigDataGuid, HobList); if (GuidHob != NULL) { HobData = GET_GUID_HOB_DATA (GuidHob); DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); // // Use the HOB to save Memory Configuration Data // BufferSize = DataSize; VariableData = AllocatePool (BufferSize); ASSERT (VariableData != NULL); Status = gRT->GetVariable ( EFI_MEMORY_CONFIG_DATA_NAME, &gEfiMemoryConfigDataGuid, NULL, &BufferSize, VariableData ); if (Status == EFI_BUFFER_TOO_SMALL) { (gBS->FreePool)(VariableData); VariableData = AllocatePool (BufferSize); ASSERT (VariableData != NULL); Status = gRT->GetVariable ( EFI_MEMORY_CONFIG_DATA_NAME, &gEfiMemoryConfigDataGuid, NULL, &BufferSize, VariableData ); } if ( (EFI_ERROR(Status)) || BufferSize != DataSize || 0 != CompareMem (HobData, VariableData, DataSize)) { if (Status != EFI_SUCCESS){ Status = gRT->SetVariable ( EFI_MEMORY_CONFIG_DATA_NAME, &gEfiMemoryConfigDataGuid, (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), DataSize, HobData ); } ASSERT((Status == EFI_SUCCESS) || (Status == EFI_OUT_OF_RESOURCES)); DEBUG((EFI_D_INFO, "Restored Size is 0x%x\n", DataSize)); } (gBS->FreePool)(VariableData); } // // This driver does not produce any protocol services, so always unload it. // return Status; }
/** This routine is a notification function for legacy boot or exit boot service event. It will adjust the memory information for different memory type and save them into the variables for next boot. @param Event The event that triggered this notification function. @param Context Pointer to the notification functions context. **/ VOID EFIAPI BdsSetMemoryTypeInformationVariable ( EFI_EVENT Event, VOID *Context ) { EFI_STATUS Status; EFI_MEMORY_TYPE_INFORMATION *PreviousMemoryTypeInformation; EFI_MEMORY_TYPE_INFORMATION *CurrentMemoryTypeInformation; UINTN VariableSize; BOOLEAN UpdateRequired; UINTN Index; UINTN Index1; UINT32 Previous; UINT32 Current; UINT32 Next; EFI_HOB_GUID_TYPE *GuidHob; UpdateRequired = FALSE; // // Retrieve the current memory usage statistics. If they are not found, then // no adjustments can be made to the Memory Type Information variable. // Status = EfiGetSystemConfigurationTable ( &gEfiMemoryTypeInformationGuid, (VOID **) &CurrentMemoryTypeInformation ); if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) { return; } // // Get the Memory Type Information settings from Hob if they exist, // PEI is responsible for getting them from variable and build a Hob to save them. // If the previous Memory Type Information is not available, then set defaults // GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid); if (GuidHob == NULL) { // // If Platform has not built Memory Type Info into the Hob, just return. // return; } PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob); VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob); // // Use a heuristic to adjust the Memory Type Information for the next boot // for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { Current = 0; for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) { if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) { Current = CurrentMemoryTypeInformation[Index1].NumberOfPages; break; } } if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) { continue; } Previous = PreviousMemoryTypeInformation[Index].NumberOfPages; // // Write next variable to 125% * current and Inconsistent Memory Reserved across bootings may lead to S4 fail // if (Current > Previous) { Next = Current + (Current >> 2); } else {