/** @file Source code file for Platform Init Pre-Memory PEI module Copyright (c) 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License that accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include EFI_STATUS EFIAPI PlatformInitPreMem ( IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ); EFI_STATUS EFIAPI MemoryDiscoveredPpiNotifyCallback ( IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ); EFI_STATUS EFIAPI GetPlatformMemorySize ( IN EFI_PEI_SERVICES **PeiServices, IN PEI_PLATFORM_MEMORY_SIZE_PPI *This, IN OUT UINT64 *MemorySize ); /** This function checks the memory range in PEI. @param PeiServices Pointer to PEI Services. @param This Pei memory test PPI pointer. @param BeginAddress Beginning of the memory address to be checked. @param MemoryLength Bytes of memory range to be checked. @param Operation Type of memory check operation to be performed. @param ErrorAddress Return the address of the error memory address. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory. **/ EFI_STATUS EFIAPI BaseMemoryTest ( IN EFI_PEI_SERVICES **PeiServices, IN PEI_BASE_MEMORY_TEST_PPI *This, IN EFI_PHYSICAL_ADDRESS BeginAddress, IN UINT64 MemoryLength, IN PEI_MEMORY_TEST_OP Operation, OUT EFI_PHYSICAL_ADDRESS *ErrorAddress ); static EFI_PEI_NOTIFY_DESCRIPTOR mPreMemNotifyList = { (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiPeiReadOnlyVariable2PpiGuid, (EFI_PEIM_NOTIFY_ENTRY_POINT) PlatformInitPreMem }; static EFI_PEI_NOTIFY_DESCRIPTOR mMemDiscoveredNotifyList = { (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiPeiMemoryDiscoveredPpiGuid, (EFI_PEIM_NOTIFY_ENTRY_POINT) MemoryDiscoveredPpiNotifyCallback }; GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiPeiBootInRecoveryModePpiGuid, NULL }; GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mPpiBootMode = { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiPeiMasterBootModePpiGuid, NULL }; static PEI_BASE_MEMORY_TEST_PPI mPeiBaseMemoryTestPpi = { BaseMemoryTest }; static PEI_PLATFORM_MEMORY_SIZE_PPI mMemoryMemorySizePpi = { GetPlatformMemorySize }; static EFI_PEI_PPI_DESCRIPTOR mMemPpiList[] = { { EFI_PEI_PPI_DESCRIPTOR_PPI, &gPeiBaseMemoryTestPpiGuid, &mPeiBaseMemoryTestPpi }, { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gPeiPlatformMemorySizePpiGuid, &mMemoryMemorySizePpi }, }; /// /// Memory Reserved should be between 125% to 150% of the Current required memory /// otherwise BdsMisc.c would do a reset to make it 125% to avoid s4 resume issues. /// GLOBAL_REMOVE_IF_UNREFERENCED EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { { EfiACPIReclaimMemory, FixedPcdGet32 (PcdPlatformEfiAcpiReclaimMemorySize) }, // ASL { EfiACPIMemoryNVS, FixedPcdGet32 (PcdPlatformEfiAcpiNvsMemorySize) }, // ACPI NVS (including S3 related) { EfiReservedMemoryType, FixedPcdGet32 (PcdPlatformEfiReservedMemorySize) }, // BIOS Reserved (including S3 related) { EfiRuntimeServicesData, FixedPcdGet32 (PcdPlatformEfiRtDataMemorySize) }, // Runtime Service Data { EfiRuntimeServicesCode, FixedPcdGet32 (PcdPlatformEfiRtCodeMemorySize) }, // Runtime Service Code { EfiMaxMemoryType, 0 } }; VOID BuildMemoryTypeInformation ( VOID ) { EFI_STATUS Status; EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices; UINTN DataSize; EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; // // Locate system configuration variable // Status = PeiServicesLocatePpi( &gEfiPeiReadOnlyVariable2PpiGuid, // GUID 0, // INSTANCE NULL, // EFI_PEI_PPI_DESCRIPTOR (VOID **) &VariableServices // PPI ); ASSERT_EFI_ERROR(Status); DataSize = sizeof (MemoryData); Status = VariableServices->GetVariable ( VariableServices, EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, &gEfiMemoryTypeInformationGuid, NULL, &DataSize, &MemoryData ); if (EFI_ERROR(Status)) { DataSize = sizeof (mDefaultMemoryTypeInformation); CopyMem(MemoryData, mDefaultMemoryTypeInformation, DataSize); } /// /// Build the GUID'd HOB for DXE /// BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, MemoryData, DataSize ); } EFI_STATUS EFIAPI GetPlatformMemorySize ( IN EFI_PEI_SERVICES **PeiServices, IN PEI_PLATFORM_MEMORY_SIZE_PPI *This, IN OUT UINT64 *MemorySize ) { EFI_STATUS Status; EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; UINTN DataSize; EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; UINTN Index; EFI_BOOT_MODE BootMode; UINTN IndexNumber; #define PEI_MIN_MEMORY_SIZE (EFI_PHYSICAL_ADDRESS) ((320 * 0x100000)) *MemorySize = PEI_MIN_MEMORY_SIZE; Status = PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&Variable ); ASSERT_EFI_ERROR (Status); Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); DataSize = sizeof (MemoryData); Status = Variable->GetVariable ( Variable, EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, &gEfiMemoryTypeInformationGuid, NULL, &DataSize, &MemoryData ); IndexNumber = sizeof (mDefaultMemoryTypeInformation) / sizeof (EFI_MEMORY_TYPE_INFORMATION); // // Accumulate maximum amount of memory needed // DEBUG((EFI_D_ERROR, "PEI_MIN_MEMORY_SIZE:%dKB \n", DivU64x32(*MemorySize,1024))); DEBUG((EFI_D_ERROR, "IndexNumber:%d MemoryDataNumber%d \n", IndexNumber,DataSize/ sizeof (EFI_MEMORY_TYPE_INFORMATION))); if (EFI_ERROR (Status)) { // // Start with minimum memory // for (Index = 0; Index < IndexNumber; Index++) { DEBUG((EFI_D_ERROR, "Index[%d].Type = %d .NumberOfPages=0x%x\n", Index,mDefaultMemoryTypeInformation[Index].Type,mDefaultMemoryTypeInformation[Index].NumberOfPages)); *MemorySize += mDefaultMemoryTypeInformation[Index].NumberOfPages * EFI_PAGE_SIZE; } DEBUG((EFI_D_ERROR, "No memory type, Total platform memory:%dKB \n", DivU64x32(*MemorySize,1024))); } else { // // Start with at least 0x200 pages of memory for the DXE Core and the DXE Stack // for (Index = 0; Index < IndexNumber; Index++) { DEBUG((EFI_D_ERROR, "Index[%d].Type = %d .NumberOfPages=0x%x\n", Index,MemoryData[Index].Type,MemoryData[Index].NumberOfPages)); *MemorySize += MemoryData[Index].NumberOfPages * EFI_PAGE_SIZE; } DEBUG((EFI_D_ERROR, "has memory type, Total platform memory:%dKB \n", DivU64x32(*MemorySize,1024))); } return EFI_SUCCESS; } /** This function checks the memory range in PEI. @param PeiServices Pointer to PEI Services. @param This Pei memory test PPI pointer. @param BeginAddress Beginning of the memory address to be checked. @param MemoryLength Bytes of memory range to be checked. @param Operation Type of memory check operation to be performed. @param ErrorAddress Return the address of the error memory address. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory. **/ EFI_STATUS EFIAPI BaseMemoryTest ( IN EFI_PEI_SERVICES **PeiServices, IN PEI_BASE_MEMORY_TEST_PPI *This, IN EFI_PHYSICAL_ADDRESS BeginAddress, IN UINT64 MemoryLength, IN PEI_MEMORY_TEST_OP Operation, OUT EFI_PHYSICAL_ADDRESS *ErrorAddress ) { UINT32 TestPattern; UINT32 SpanSize; EFI_PHYSICAL_ADDRESS TempAddress; #define MEMORY_TEST_PATTERN 0x5A5A5A5A #define MEMORY_TEST_COVER_SPAN 0x40000 TestPattern = MEMORY_TEST_PATTERN; SpanSize = 0; // // Make sure we don't try and test anything above the max physical address range // ASSERT (BeginAddress + MemoryLength < MAX_ADDRESS); switch (Operation) { case Extensive: SpanSize = 0x4; break; case Sparse: case Quick: SpanSize = MEMORY_TEST_COVER_SPAN; break; case Ignore: goto Done; break; } // // Write the test pattern into memory range // TempAddress = BeginAddress; while (TempAddress < BeginAddress + MemoryLength) { (*(UINT32 *) (UINTN) TempAddress) = TestPattern; TempAddress += SpanSize; } // // Read pattern from memory and compare it // TempAddress = BeginAddress; while (TempAddress < BeginAddress + MemoryLength) { if ((*(UINT32 *) (UINTN) TempAddress) != TestPattern) { *ErrorAddress = TempAddress; return EFI_DEVICE_ERROR; } TempAddress += SpanSize; } Done: return EFI_SUCCESS; } /** Set Cache Mtrr. **/ VOID SetCacheMtrr ( VOID ) { EFI_STATUS Status; EFI_PEI_HOB_POINTERS Hob; MTRR_SETTINGS MtrrSetting; UINT64 MemoryBase; UINT64 MemoryLength; UINT64 LowMemoryLength; UINT64 HighMemoryLength; EFI_BOOT_MODE BootMode; EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute; UINT64 CacheMemoryLength; /// /// Reset all MTRR setting. /// ZeroMem(&MtrrSetting, sizeof(MTRR_SETTINGS)); /// /// Cache the Flash area as WP to boost performance /// Status = MtrrSetMemoryAttributeInMtrrSettings ( &MtrrSetting, (UINTN) PcdGet32 (PcdFlashAreaBaseAddress), (UINTN) PcdGet32 (PcdFlashAreaSize), CacheWriteProtected ); ASSERT_EFI_ERROR (Status); /// /// Update MTRR setting from MTRR buffer for Flash Region to be WP to boost performance /// MtrrSetAllMtrrs (&MtrrSetting); /// /// Set low to 1 MB. Since 1MB cacheability will always be set /// until override by CSM. /// Initialize high memory to 0. /// LowMemoryLength = 0x100000; HighMemoryLength = 0; ResourceAttribute = ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ); Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); if (BootMode != BOOT_ON_S3_RESUME) { ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_TESTED; } Status = PeiServicesGetHobList ((VOID **) &Hob.Raw); while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) || ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) && (Hob.ResourceDescriptor->ResourceAttribute == ResourceAttribute)) ) { if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000000ULL) { HighMemoryLength += Hob.ResourceDescriptor->ResourceLength; } else if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) { LowMemoryLength += Hob.ResourceDescriptor->ResourceLength; } } } Hob.Raw = GET_NEXT_HOB (Hob); } DEBUG ((DEBUG_INFO, "Memory Length (Below 4GB) = %lx.\n", LowMemoryLength)); DEBUG ((DEBUG_INFO, "Memory Length (Above 4GB) = %lx.\n", HighMemoryLength)); /// /// Assume size of main memory is multiple of 256MB /// MemoryLength = (LowMemoryLength + 0xFFFFFFF) & 0xF0000000; MemoryBase = 0; CacheMemoryLength = MemoryLength; /// /// Programming MTRRs to avoid override SPI region with UC when MAX TOLUD Length >= 3.5GB /// if (MemoryLength > 0xDC000000) { CacheMemoryLength = 0xC0000000; Status = MtrrSetMemoryAttributeInMtrrSettings ( &MtrrSetting, MemoryBase, CacheMemoryLength, CacheWriteBack ); ASSERT_EFI_ERROR (Status); MemoryBase = 0xC0000000; CacheMemoryLength = MemoryLength - 0xC0000000; if (MemoryLength > 0xE0000000) { CacheMemoryLength = 0x20000000; Status = MtrrSetMemoryAttributeInMtrrSettings ( &MtrrSetting, MemoryBase, CacheMemoryLength, CacheWriteBack ); ASSERT_EFI_ERROR (Status); MemoryBase = 0xE0000000; CacheMemoryLength = MemoryLength - 0xE0000000; } } Status = MtrrSetMemoryAttributeInMtrrSettings ( &MtrrSetting, MemoryBase, CacheMemoryLength, CacheWriteBack ); ASSERT_EFI_ERROR (Status); if (LowMemoryLength != MemoryLength) { MemoryBase = LowMemoryLength; MemoryLength -= LowMemoryLength; Status = MtrrSetMemoryAttributeInMtrrSettings ( &MtrrSetting, MemoryBase, MemoryLength, CacheUncacheable ); ASSERT_EFI_ERROR (Status); } /// /// VGA-MMIO - 0xA0000 to 0xC0000 to be UC /// Status = MtrrSetMemoryAttributeInMtrrSettings ( &MtrrSetting, 0xA0000, 0x20000, CacheUncacheable ); ASSERT_EFI_ERROR (Status); /// /// Update MTRR setting from MTRR buffer /// MtrrSetAllMtrrs (&MtrrSetting); return ; } VOID ReportCpuHob ( VOID ) { UINT8 PhysicalAddressBits; UINT32 RegEax; 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); } VOID ReportPreMemFv ( VOID ) { if (!PcdGetBool(PcdFspWrapperBootMode)) { DEBUG ((DEBUG_INFO, "Install FlashFvFspM - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspMBase), PcdGet32 (PcdFlashFvFspMSize))); PeiServicesInstallFvInfo2Ppi ( &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvFspMBase))->FileSystemGuid), (VOID *) (UINTN) PcdGet32 (PcdFlashFvFspMBase), PcdGet32 (PcdFlashFvFspMSize), NULL, NULL, 0 ); } DEBUG ((DEBUG_INFO, "Install FlashFvSecurity - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvSecurityBase), PcdGet32 (PcdFlashFvSecuritySize))); PeiServicesInstallFvInfo2Ppi ( &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvSecurityBase))->FileSystemGuid), (VOID *) (UINTN) PcdGet32 (PcdFlashFvSecurityBase), PcdGet32 (PcdFlashFvSecuritySize), NULL, NULL, 0 ); DEBUG ((DEBUG_INFO, "Install FlashFvAdvanced - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvAdvancedBase), PcdGet32 (PcdFlashFvAdvancedSize))); PeiServicesInstallFvInfo2Ppi ( &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvAdvancedBase))->FileSystemGuid), (VOID *) (UINTN) PcdGet32 (PcdFlashFvAdvancedBase), PcdGet32 (PcdFlashFvAdvancedSize), NULL, NULL, 0 ); } VOID ReportPostMemFv ( VOID ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); /// /// Build HOB for DXE /// if (BootMode == BOOT_IN_RECOVERY_MODE) { /// /// Prepare the recovery service /// } else { DEBUG ((DEBUG_INFO, "Install FlashFvPostMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvPostMemoryBase), PcdGet32 (PcdFlashFvPostMemorySize))); PeiServicesInstallFvInfo2Ppi ( &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvPostMemoryBase))->FileSystemGuid), (VOID *) (UINTN) PcdGet32 (PcdFlashFvPostMemoryBase), PcdGet32 (PcdFlashFvPostMemorySize), NULL, NULL, 0 ); if (!PcdGetBool(PcdFspWrapperBootMode)) { DEBUG ((DEBUG_INFO, "Install FlashFvFspS - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspSBase), PcdGet32 (PcdFlashFvFspSSize))); PeiServicesInstallFvInfo2Ppi ( &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvFspSBase))->FileSystemGuid), (VOID *) (UINTN) PcdGet32 (PcdFlashFvFspSBase), PcdGet32 (PcdFlashFvFspSSize), NULL, NULL, 0 ); DEBUG ((DEBUG_INFO, "Install FlashFvFspU - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspUBase), PcdGet32 (PcdFlashFvFspUSize))); PeiServicesInstallFvInfo2Ppi ( &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvFspUBase))->FileSystemGuid), (VOID *) (UINTN) PcdGet32 (PcdFlashFvFspUBase), PcdGet32 (PcdFlashFvFspUSize), NULL, NULL, 0 ); } DEBUG ((DEBUG_INFO, "Install FlashFvUefiBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvUefiBootBase), PcdGet32 (PcdFlashFvUefiBootSize))); PeiServicesInstallFvInfo2Ppi ( &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvUefiBootBase))->FileSystemGuid), (VOID *) (UINTN) PcdGet32 (PcdFlashFvUefiBootBase), PcdGet32 (PcdFlashFvUefiBootSize), NULL, NULL, 0 ); DEBUG ((DEBUG_INFO, "Install FlashFvOsBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvOsBootBase), PcdGet32 (PcdFlashFvOsBootSize))); PeiServicesInstallFvInfo2Ppi ( &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvOsBootBase))->FileSystemGuid), (VOID *) (UINTN) PcdGet32 (PcdFlashFvOsBootBase), PcdGet32 (PcdFlashFvOsBootSize), NULL, NULL, 0 ); } // // Report resource HOB for flash FV // BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), (UINTN) PcdGet32 (PcdFlashAreaBaseAddress), (UINTN) PcdGet32 (PcdFlashAreaSize) ); BuildMemoryAllocationHob ( (UINTN) PcdGet32 (PcdFlashAreaBaseAddress), (UINTN) PcdGet32 (PcdFlashAreaSize), EfiMemoryMappedIO ); } /** Install Firmware Volume Hob's once there is main memory @param[in] PeiServices General purpose services available to every PEIM. @param[in] NotifyDescriptor Notify that this module published. @param[in] Ppi PPI that was installed. @retval EFI_SUCCESS The function completed successfully. **/ EFI_STATUS EFIAPI MemoryDiscoveredPpiNotifyCallback ( IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; Status = BoardInitAfterMemoryInit (); ASSERT_EFI_ERROR (Status); Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); SetCacheMtrr (); ReportCpuHob (); TestPointMemoryDiscoveredMtrrFunctional (); TestPointMemoryDiscoveredMemoryResourceFunctional (); /// /// If S3 resume, then we are done /// if (BootMode == BOOT_ON_S3_RESUME) { return EFI_SUCCESS; } ReportPostMemFv (); TestPointMemoryDiscoveredFvInfoFunctional (); TestPointMemoryDiscoveredDmaProtectionEnabled (); if (PcdGetBool (PcdStopAfterMemInit)) { CpuDeadLoop (); } return Status; } /** This function handles PlatformInit task after PeiReadOnlyVariable2 PPI produced @param[in] PeiServices Pointer to PEI Services Table. @param[in] NotifyDesc Pointer to the descriptor for the Notification event that caused this function to execute. @param[in] Ppi Pointer to the PPI data associated with this function. @retval EFI_SUCCESS The function completes successfully @retval others **/ EFI_STATUS EFIAPI PlatformInitPreMem ( IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; // // Start board detection // BoardDetect (); BoardDebugInit (); TestPointDebugInitDone (); if (PcdGetBool (PcdStopAfterDebugInit)) { CpuDeadLoop (); } BootMode = BoardBootModeDetect (); Status = PeiServicesSetBootMode (BootMode); ASSERT_EFI_ERROR (Status); if (BootMode == BOOT_IN_RECOVERY_MODE) { Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode); } /// /// Signal possible dependent modules that there has been a /// final boot mode determination, it is used to build BIST /// Hob for Dxe use. /// Status = PeiServicesInstallPpi (&mPpiBootMode); ASSERT_EFI_ERROR (Status); BuildMemoryTypeInformation (); if (!PcdGetBool(PcdFspWrapperBootMode)) { Status = PeiServicesInstallPpi (mMemPpiList); ASSERT_EFI_ERROR (Status); } Status = BoardInitBeforeMemoryInit (); ASSERT_EFI_ERROR (Status); return Status; } /** Platform Init before memory PEI module entry point @param[in] FileHandle Not used. @param[in] PeiServices General purpose services available to every PEIM. @retval EFI_SUCCESS The function completes successfully @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database **/ EFI_STATUS EFIAPI PlatformInitPreMemEntryPoint ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; ReportPreMemFv (); /// /// Performing PlatformInitPreMem after PeiReadOnlyVariable2 PPI produced /// Status = PeiServicesNotifyPpi (&mPreMemNotifyList); /// /// After code reorangized, memorycallback will run because the PPI is already /// installed when code run to here, it is supposed that the InstallEfiMemory is /// done before. /// Status = PeiServicesNotifyPpi (&mMemDiscoveredNotifyList); return Status; }