/** 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; }
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; }