/** Perform a call-back into the SEC simulator to get address of the Firmware Hub @param FfsHeader Ffs Header availible to every PEIM @param PeiServices General purpose services available to every PEIM. @retval EFI_SUCCESS Platform PEI FVs were initialized successfully. **/ EFI_STATUS PeiFvInitialization ( VOID ) { DEBUG ((EFI_D_ERROR, "Platform PEI Firmware Volume Initialization\n")); DEBUG ( (EFI_D_ERROR, "Firmware Volume HOB: 0x%x 0x%x\n", PcdGet32 (PcdOvmfMemFvBase), PcdGet32 (PcdOvmfMemFvSize) ) ); BuildFvHob (PcdGet32 (PcdOvmfMemFvBase), PcdGet32 (PcdOvmfMemFvSize)); // // Create a memory allocation HOB. // BuildMemoryAllocationHob ( PcdGet32 (PcdOvmfMemFvBase), PcdGet32 (PcdOvmfMemFvSize), EfiBootServicesData ); return EFI_SUCCESS; }
/** Install FvInfo PPI and create fv hobs for remained fvs **/ VOID CbPeiReportRemainedFvs ( VOID ) { UINT8* TempPtr; UINT8* EndPtr; TempPtr = (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase); EndPtr = (UINT8* )(UINTN) (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize)); for (;TempPtr < EndPtr;) { if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)) { if (TempPtr != (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase)) { // Skip the PEI FV DEBUG((EFI_D_ERROR, "Found one valid fv : 0x%lx.\n", TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength)); PeiServicesInstallFvInfoPpi ( NULL, (VOID *) (UINTN) TempPtr, (UINT32) (UINTN) ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength, NULL, NULL ); BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN) TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength); } } TempPtr += ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength; } }
/** Publish PEI & DXE (Decompressed) Memory based FVs to let PEI and DXE know about them. @retval EFI_SUCCESS Platform PEI FVs were initialized successfully. **/ EFI_STATUS PeiFvInitialization ( VOID ) { DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n")); // // Create a memory allocation HOB for the PEI FV. // // Allocate as ACPI NVS is S3 is supported // BuildMemoryAllocationHob ( PcdGet32 (PcdOvmfPeiMemFvBase), PcdGet32 (PcdOvmfPeiMemFvSize), mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData ); // // Let DXE know about the DXE FV // BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize)); // // Create a memory allocation HOB for the DXE FV. // BuildMemoryAllocationHob ( PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize), EfiBootServicesData ); // // Let PEI know about the DXE FV so it can find the DXE Core // PeiServicesInstallFvInfoPpi ( NULL, (VOID *)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize), NULL, NULL ); return EFI_SUCCESS; }
VOID EFIAPI BuildFvHobs ( IN EFI_PHYSICAL_ADDRESS PhysicalStart, IN UINT64 NumberOfBytes, IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute ) { EFI_RESOURCE_ATTRIBUTE_TYPE Resource; BuildFvHob (PhysicalStart, NumberOfBytes); if (ResourceAttribute == NULL) { Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE); } else { Resource = *ResourceAttribute; } BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes); }
VOID CEntryPoint ( IN VOID *MemoryBase, IN UINTN MemorySize, IN VOID *StackBase, IN UINTN StackSize ) { VOID *HobBase; // Build a basic HOB list HobBase = (VOID *)(UINTN)(FixedPcdGet32(PcdEmbeddedFdBaseAddress) + FixedPcdGet32(PcdEmbeddedFdSize)); CreateHobList (MemoryBase, MemorySize, HobBase, StackBase); //Set up Pin muxing. PadConfiguration (); // Set up system clocking ClockInit (); // Enable program flow prediction, if supported. ArmEnableBranchPrediction (); // Initialize CPU cache InitCache ((UINT32)MemoryBase, (UINT32)MemorySize); // Add memory allocation hob for relocated FD BuildMemoryAllocationHob (FixedPcdGet32(PcdEmbeddedFdBaseAddress), FixedPcdGet32(PcdEmbeddedFdSize), EfiBootServicesData); // Add the FVs to the hob list BuildFvHob (PcdGet32(PcdFlashFvMainBase), PcdGet32(PcdFlashFvMainSize)); // Start talking UartInit (); InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL); SaveAndSetDebugTimerInterrupt (TRUE); DEBUG ((EFI_D_ERROR, "UART Enabled\n")); // Start up a free running timer so that the timer lib will work TimerInit (); // SEC phase needs to run library constructors by hand. ExtractGuidedSectionLibConstructor (); LzmaDecompressLibConstructor (); // Build HOBs to pass up our version of stuff the DXE Core needs to save space BuildPeCoffLoaderHob (); BuildExtractSectionHob ( &gLzmaCustomDecompressGuid, LzmaGuidedSectionGetInfo, LzmaGuidedSectionExtraction ); // Assume the FV that contains the SEC (our code) also contains a compressed FV. DecompressFirstFv (); // Load the DXE Core and transfer control to it LoadDxeCoreFromFv (NULL, 0); // DXE Core should always load and never return ASSERT (FALSE); }
EFI_STATUS EFIAPI PeimInitializeWinNtFwh ( IN EFI_FFS_FILE_HEADER *FfsHeader, IN EFI_PEI_SERVICES **PeiServices ) /*++ Routine Description: Perform a call-back into the SEC simulator to get address of the Firmware Hub Arguments: FfsHeader - Ffs Header available to every PEIM PeiServices - General purpose services available to every PEIM. Returns: None --*/ { EFI_STATUS Status; EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; NT_FWH_PPI *FwhPpi; EFI_PHYSICAL_ADDRESS FdBase; EFI_FIRMWARE_VOLUME_HEADER *FvHeader; UINT64 FdSize; UINTN Index; DEBUG ((EFI_D_ERROR, "NT 32 Firmware Volume PEIM Loaded\n")); // // Get the Fwh Information PPI // Status = (**PeiServices).LocatePpi ( (const EFI_PEI_SERVICES **)PeiServices, &gNtFwhPpiGuid, // GUID 0, // INSTANCE &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR (VOID**)&FwhPpi // PPI ); ASSERT_EFI_ERROR (Status); Index = 0; do { // // Get information about all the FD's in the system // Status = FwhPpi->NtFwh (Index, &FdBase, &FdSize); if (!EFI_ERROR (Status)) { // // Assume the FD starts with an FV header // FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FdBase; // // Make an FV Hob for the first FV in the FD // BuildFvHob (FdBase, FvHeader->FvLength); if (Index == 0) { // // Assume the first FD was produced by the NT32.DSC // All these strange offests are needed to keep in // sync with the FlashMap and NT32.dsc file // BuildResourceDescriptorHob ( EFI_RESOURCE_FIRMWARE_DEVICE, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), FdBase, ( FvHeader->FvLength + PcdGet32 (PcdFlashNvStorageVariableSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + PcdGet32 (PcdFlashNvStorageFtwSpareSize) + PcdGet32 (PcdWinNtFlashNvStorageEventLogSize) ) ); // // Hard code the address of the spare block and variable services. // Assume it's a hard coded offset from FV0 in FD0. // FdSize = PcdGet32 (PcdFlashNvStorageVariableSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + PcdGet32 (PcdFlashNvStorageFtwSpareSize) + PcdGet32 (PcdWinNtFlashNvStorageEventLogSize); BuildFvHob (FdBase + PcdGet32 (PcdWinNtFlashNvStorageVariableBase), FdSize); } else { // // For other FD's just map them in. // BuildResourceDescriptorHob ( EFI_RESOURCE_FIRMWARE_DEVICE, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), FdBase, FdSize ); } } Index++; } while (!EFI_ERROR (Status)); return Status; }
/** This function will be called when MRC is done. @param PeiServices General purpose services available to every PEIM. @param NotifyDescriptor Information about the notify event.. @param Ppi The notify context. @retval EFI_SUCCESS If the function completed successfully. **/ EFI_STATUS EFIAPI MemoryDiscoveredPpiNotifyCallback ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; UINT64 MemoryLength; EFI_SMRAM_DESCRIPTOR *SmramDescriptor; UINTN NumSmramRegions; UINT32 RmuMainBaseAddress; UINT32 RegData32; UINT8 CpuAddressWidth; UINT32 RegEax; MTRR_SETTINGS MtrrSettings; EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices; UINT8 MorControl; UINTN DataSize; DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n")); NumSmramRegions = 0; SmramDescriptor = NULL; RmuMainBaseAddress = 0; PERF_START (NULL, "SetCache", NULL, 0); InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions); ASSERT (SmramDescriptor != NULL); ASSERT (RmuMainBaseAddress != 0); MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000; Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); // // Get current MTRR settings // MtrrGetAllMtrrs (&MtrrSettings); // // Set all DRAM cachability to CacheWriteBack // Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0, MemoryLength, CacheWriteBack); ASSERT_EFI_ERROR (Status); // // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE // Workaround to make default SMRAM UnCachable // Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0x30000, SIZE_64KB, CacheUncacheable); ASSERT_EFI_ERROR (Status); // // Set new MTRR settings // MtrrSetAllMtrrs (&MtrrSettings); PERF_END (NULL, "SetCache", NULL, 0); // // Get necessary PPI // Status = PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, // GUID 0, // INSTANCE NULL, // EFI_PEI_PPI_DESCRIPTOR (VOID **)&VariableServices // PPI ); ASSERT_EFI_ERROR (Status); // // Detect MOR request by the OS. // MorControl = 0; DataSize = sizeof (MorControl); Status = VariableServices->GetVariable ( VariableServices, MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, &gEfiMemoryOverwriteControlDataGuid, NULL, &DataSize, &MorControl ); // // If OS requested a memory overwrite perform it now for Embedded SRAM // if (MOR_CLEAR_MEMORY_VALUE (MorControl)) { DEBUG ((EFI_D_INFO, "Clear Embedded SRAM per MOR request.\n")); if (PcdGet32 (PcdESramMemorySize) > 0) { if (PcdGet32 (PcdEsramStage1Base) == 0) { // // ZeroMem() generates an ASSERT() if Buffer parameter is NULL. // Clear byte at 0 and start clear operation at address 1. // *(UINT8 *)(0) = 0; ZeroMem ((VOID *)1, (UINTN)PcdGet32 (PcdESramMemorySize) - 1); } else { ZeroMem ( (VOID *)(UINTN)PcdGet32 (PcdEsramStage1Base), (UINTN)PcdGet32 (PcdESramMemorySize) ); } } } // // Install PeiReset for PeiResetSystem service // Status = PeiServicesInstallPpi (&mPpiList[0]); ASSERT_EFI_ERROR (Status); // // Do QNC initialization after MRC // PeiQNCPostMemInit (); Status = PeiServicesInstallPpi (&mPpiStall[0]); ASSERT_EFI_ERROR (Status); // // Set E000/F000 Routing // RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC); RegData32 |= (BIT2|BIT1); QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32); if (BootMode == BOOT_IN_RECOVERY_MODE) { // Do nothing here. A generic RecoveryModule will handle it. } else if (BootMode == BOOT_ON_S3_RESUME) { return EFI_SUCCESS; } else { PeiServicesInstallFvInfoPpi ( NULL, (VOID *) (UINTN) PcdGet32 (PcdFlashFvMainBase), PcdGet32 (PcdFlashFvMainSize), NULL, NULL ); // // Publish the FVMAIN FV so the DXE Phase can dispatch drivers from this FV // and produce Load File Protocols for UEFI Applications in this FV. // BuildFvHob ( PcdGet32 (PcdFlashFvMainBase), PcdGet32 (PcdFlashFvMainSize) ); // // Publish the Payload FV so the DXE Phase can dispatch drivers from this FV // and produce Load File Protocols for UEFI Applications in this FV. // BuildFvHob ( PcdGet32 (PcdFlashFvPayloadBase), PcdGet32 (PcdFlashFvPayloadSize) ); } // // Build flash HOB, it's going to be used by GCD and E820 building // Map full SPI flash decode range (regardless of smaller SPI flash parts installed) // BuildResourceDescriptorHob ( EFI_RESOURCE_FIRMWARE_DEVICE, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), (SIZE_4GB - SIZE_8MB), SIZE_8MB ); // // Create a CPU hand-off information // CpuAddressWidth = 32; AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) { AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL); CpuAddressWidth = (UINT8) (RegEax & 0xFF); } DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth)); BuildCpuHob (CpuAddressWidth, 16); ASSERT_EFI_ERROR (Status); return Status; }