/** Based on memory base, size and type, build resource descripter HOB. @param Base Memory base address. @param Size Memory size. @param Type Memory type. @param Param A pointer to CB_MEM_INFO. @retval EFI_SUCCESS if it completed successfully. **/ EFI_STATUS CbMemInfoCallback ( UINT64 Base, UINT64 Size, UINT32 Type, VOID *Param ) { CB_MEM_INFO *MemInfo; UINTN Attribue; Attribue = 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; if ((Base < 0x100000) && ((Base + Size) > 0x100000)) { Size -= (0x100000 - Base); Base = 0x100000; } MemInfo = (CB_MEM_INFO *)Param; if (Base >= 0x100000) { if (Type == CB_MEM_RAM) { if (Base < 0x100000000ULL) { MemInfo->UsableLowMemTop = (UINT32)(Base + Size); } else { Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED; } BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, Attribue, (EFI_PHYSICAL_ADDRESS)Base, Size ); } else if (Type == CB_MEM_TABLE) { BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_RESERVED, Attribue, (EFI_PHYSICAL_ADDRESS)Base, Size ); MemInfo->SystemLowMemTop = ((UINT32)(Base + Size) + 0x0FFFFFFF) & 0xF0000000; } else if (Type == CB_MEM_RESERVED) { if ((MemInfo->SystemLowMemTop == 0) || (Base < MemInfo->SystemLowMemTop)) { BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_RESERVED, Attribue, (EFI_PHYSICAL_ADDRESS)Base, Size ); } } } return EFI_SUCCESS; }
VOID CreateHobList ( IN VOID *MemoryBegin, IN UINTN MemoryLength, IN VOID *HobBase, IN VOID *StackBase ) { EFI_HOB_HANDOFF_INFO_TABLE *Hob; EFI_RESOURCE_ATTRIBUTE_TYPE Attributes; Hob = HobConstructor (MemoryBegin,MemoryLength,HobBase,StackBase); SetHobList (Hob); BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize)); Attributes =( 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 ); BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attributes, (UINTN)MemoryBegin, MemoryLength); BuildStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)StackBase, ((UINTN)MemoryBegin + MemoryLength) - (UINTN)StackBase); if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { // Optional feature that helps prevent EFI memory map fragmentation. BuildMemoryTypeInformationHob (); } }
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); } }
EFI_STATUS EFIAPI MemoryPeim ( IN EFI_PHYSICAL_ADDRESS MemoryBase, IN UINT64 MemorySize ) { EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; UINT64 Base,Size; // // For now we simply declare the IMA memory given to us, we will // do things a bit more smartly when I understand UEFI memory // management a bit better. // // Now, the permanent memory has been installed, we can call AllocatePages() // ResourceAttributes = ( 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_RESOURCE_ATTRIBUTE_TESTED ); // TODO, use device-tree DEBUG((DEBUG_INIT, "System Memory Hob: %lx, %lx\n", MemoryBase, MemorySize)); BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, MemoryBase, MemorySize); // Reserve ourselves (TODO: reserve map in DT ?) Base = PcdGet64(PcdFdBaseAddress) & ~(EFI_PAGE_SIZE - 1); Size = ((PcdGet64(PcdFdBaseAddress) + PcdGet64(PcdFdSize)) + (EFI_PAGE_SIZE - 1)) & ~(EFI_PAGE_SIZE - 1); DEBUG((DEBUG_INIT, "Reserve Hob: %lx, %lx\n", Base, Size)); BuildMemoryAllocationHob (Base, Size, EfiBootServicesData); // Initialize MMU InitMmu (); if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { // Optional feature that helps prevent EFI memory map fragmentation. BuildMemoryTypeInformationHob (); } return EFI_SUCCESS; }
VOID AddReservedMemoryBaseSizeHob ( EFI_PHYSICAL_ADDRESS MemoryBase, UINT64 MemorySize ) { BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_RESERVED, EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_TESTED, MemoryBase, MemorySize ); }
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); }
VOID AddUntestedMemoryBaseSizeHob ( EFI_PHYSICAL_ADDRESS MemoryBase, UINT64 MemorySize ) { 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, MemoryBase, MemorySize ); }
/** Create memory mapped io resource hob. @param MmioBase Base address of the memory mapped io range @param MmioSize Length of the memory mapped io range **/ VOID BuildMemoryMappedIoRangeHob ( EFI_PHYSICAL_ADDRESS MmioBase, UINT64 MmioSize ) { BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_TESTED), MmioBase, MmioSize ); BuildMemoryAllocationHob ( MmioBase, MmioSize, EfiMemoryMappedIO ); }
VOID AddReservedMemoryBaseSizeHob ( EFI_PHYSICAL_ADDRESS MemoryBase, UINT64 MemorySize, BOOLEAN Cacheable ) { BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_RESERVED, EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | (Cacheable ? EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE : 0 ) | EFI_RESOURCE_ATTRIBUTE_TESTED, MemoryBase, MemorySize ); }
VOID AddRomMemoryBaseSizeHob ( EFI_PHYSICAL_ADDRESS MemoryBase, UINT64 MemorySize ) { STATIC EFI_RESOURCE_ATTRIBUTE_TYPE Attributes = ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE ); BuildResourceDescriptorHob ( EFI_RESOURCE_FIRMWARE_DEVICE, Attributes, MemoryBase, MemorySize ); DEBUG ((DEBUG_INFO, "ROM HOB: at 0x%llx size 0x%llx\n", MemoryBase, MemorySize)); }
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); }
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; }
/** Return the Virtual Memory Map of your platform This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- Virtual Memory mapping. This array must be ended by a zero-filled entry **/ VOID ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap ) { ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; UINTN Index = 0; ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; UINT32 SysId; BOOLEAN HasSparseMemory; EFI_VIRTUAL_ADDRESS SparseMemoryBase; UINT64 SparseMemorySize; ASSERT (VirtualMemoryMap != NULL); // The FVP model has Sparse memory SysId = MmioRead32 (ARM_VE_SYS_ID_REG); if (SysId != ARM_RTSM_SYS_ID) { HasSparseMemory = TRUE; ResourceAttributes = 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_RESOURCE_ATTRIBUTE_TESTED; // Declared the additional DRAM from 2GB to 4GB SparseMemoryBase = 0x0880000000; SparseMemorySize = SIZE_2GB; BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, SparseMemoryBase, SparseMemorySize); } else { HasSparseMemory = FALSE; } VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); if (VirtualMemoryTable == NULL) { return; } if (FeaturePcdGet(PcdCacheEnable) == TRUE) { CacheAttributes = DDR_ATTRIBUTES_CACHED; } else { CacheAttributes = DDR_ATTRIBUTES_UNCACHED; } // ReMap (Either NOR Flash or DRAM) VirtualMemoryTable[Index].PhysicalBase = ARM_VE_REMAP_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_REMAP_BASE; VirtualMemoryTable[Index].Length = ARM_VE_REMAP_SZ; if (FeaturePcdGet(PcdNorFlashRemapping) == FALSE) { // Map the NOR Flash as Secure Memory if (FeaturePcdGet(PcdCacheEnable) == TRUE) { VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED; } else { VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_UNCACHED; } } else { // DRAM mapping VirtualMemoryTable[Index].Attributes = CacheAttributes; } // DDR VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_DRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_DRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_DRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; // CPU peripherals. TRM. Manual says not all of them are implemented. VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_ON_CHIP_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_ON_CHIP_PERIPH_BASE; VirtualMemoryTable[Index].Length = ARM_VE_ON_CHIP_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SMB CS0-CS1 - NOR Flash 1 & 2 VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_NOR0_SZ + ARM_VE_SMB_NOR1_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SMB CS2 - SRAM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_SRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; // Peripheral CS2 and CS3 VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].Length = 2 * ARM_VE_SMB_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Map sparse memory region if present if (HasSparseMemory) { VirtualMemoryTable[++Index].PhysicalBase = SparseMemoryBase; VirtualMemoryTable[Index].VirtualBase = SparseMemoryBase; VirtualMemoryTable[Index].Length = SparseMemorySize; VirtualMemoryTable[Index].Attributes = CacheAttributes; } // End of Table VirtualMemoryTable[++Index].PhysicalBase = 0; VirtualMemoryTable[Index].VirtualBase = 0; VirtualMemoryTable[Index].Length = 0; VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; *VirtualMemoryMap = VirtualMemoryTable; }
/** 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; UINT64 MemoryLengthUc; UINT64 MaxMemoryLength; UINT64 MemOverflow; EFI_SMRAM_DESCRIPTOR *SmramDescriptor; UINTN NumSmramRegions; UINT64 EnlargedMemoryLength; UINT32 RmuMainBaseAddress; UINTN Index; MTRR_SETTINGS MtrrSetting; UINT32 RegData32; EFI_PHYSICAL_ADDRESS NewBuffer; UINT8 CpuAddressWidth; EFI_CPUID_REGISTER FeatureInfo; 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; EnlargedMemoryLength = MemoryLength; if (NumSmramRegions > 0) { // // Find the TSEG // for (Index = 0; Index < NumSmramRegions; Index ++) { if ((SmramDescriptor[Index].PhysicalStart) == EnlargedMemoryLength) { if (SmramDescriptor[Index].RegionState & EFI_CACHEABLE) { // // Enlarge memory length to include TSEG size // EnlargedMemoryLength += (SmramDescriptor[Index].PhysicalSize); } } } } // // Check if a UC region is present // MaxMemoryLength = EnlargedMemoryLength; // Round up to nearest 256MB MemOverflow = (MemoryLength & 0x0fffffff); if (MemOverflow != 0) { MaxMemoryLength = MemoryLength + (0x10000000 - MemOverflow); } Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); ZeroMem (&MtrrSetting, sizeof(MTRR_SETTINGS)); (**PeiServices).CopyMem ((VOID *)&MtrrSetting.Fixed,(VOID *)&mFixedMtrrTable, sizeof(MTRR_FIXED_SETTINGS) ); // // Cache the flash area to improve the boot performance in PEI phase // MtrrSetting.Variables.Mtrr[0].Base = (QUARK_BOOTROM_BASE_ADDRESS | CacheWriteBack); MtrrSetting.Variables.Mtrr[0].Mask = (((~(QUARK_BOOTROM_SIZE_BYTES - 1)) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED); MtrrSetting.Variables.Mtrr[1].Base = CacheWriteBack; MtrrSetting.Variables.Mtrr[1].Mask = ((~(MaxMemoryLength - 1)) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED; Index = 2; while (MaxMemoryLength != MemoryLength) { MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - MemoryLength); //Status = MtrrSetMemoryAttribute (MaxMemoryLength - MemoryLengthUc, MemoryLengthUc, CacheUncacheable); //ASSERT_EFI_ERROR (Status); MtrrSetting.Variables.Mtrr[Index].Base = ((MaxMemoryLength - MemoryLengthUc) & MTRR_LIB_CACHE_VALID_ADDRESS) | CacheUncacheable; MtrrSetting.Variables.Mtrr[Index].Mask= ((~(MemoryLengthUc - 1)) & MTRR_LIB_CACHE_VALID_ADDRESS) | MTRR_LIB_CACHE_MTRR_ENABLED; MaxMemoryLength -= MemoryLengthUc; Index++; } AsmInvd (); MtrrSetting.MtrrDefType = MTRR_LIB_CACHE_MTRR_ENABLED | MTRR_LIB_CACHE_FIXED_MTRR_ENABLED; MtrrSetAllMtrrs(&MtrrSetting); PERF_END (NULL, "SetCache", NULL, 0); // // 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) { PeiServicesInstallFvInfoPpi ( NULL, (VOID *) (UINTN) PcdGet32 (PcdFlashFvRecovery2Base), PcdGet32 (PcdFlashFvRecovery2Size), NULL, NULL ); Status = PeimInitializeRecovery (PeiServices); ASSERT_EFI_ERROR (Status); } else if (BootMode == BOOT_ON_S3_RESUME) { return EFI_SUCCESS; } else { // // Allocate the memory so that it gets preserved into DXE // Status = PeiServicesAllocatePages ( EfiBootServicesData, EFI_SIZE_TO_PAGES (PcdGet32 (PcdFvSecurityHeaderSize) + PcdGet32 (PcdFlashFvMainSize)), &NewBuffer ); // // Copy the compressed main Firmware Volume to memory for faster processing later // CopyMem ((VOID *) (UINTN) NewBuffer, (VOID *) (UINTN) (PcdGet32 (PcdFlashFvMainBase) - PcdGet32 (PcdFvSecurityHeaderSize)), (PcdGet32 (PcdFvSecurityHeaderSize) +PcdGet32 (PcdFlashFvMainSize))); PeiServicesInstallFvInfoPpi ( NULL, (VOID *) (UINTN) (NewBuffer + PcdGet32 (PcdFvSecurityHeaderSize)), PcdGet32 (PcdFlashFvMainSize), NULL, NULL ); } // // 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 (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, NULL, NULL, NULL); if (FeatureInfo.RegEax >= EFI_CPUID_VIR_PHY_ADDRESS_SIZE) { AsmCpuid (EFI_CPUID_VIR_PHY_ADDRESS_SIZE, &FeatureInfo.RegEax, NULL, NULL, NULL); CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF); } DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth)); BuildCpuHob (CpuAddressWidth, 16); ASSERT_EFI_ERROR (Status); return Status; }
EFI_STATUS EFIAPI PeimInitializeUnixAutoScan ( 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_UNIX_AUTOSCAN_PPI *PeiUnixService; UINT64 MemorySize; EFI_PHYSICAL_ADDRESS MemoryBase; UINTN Index; EFI_RESOURCE_ATTRIBUTE_TYPE Attributes; DEBUG ((EFI_D_ERROR, "Unix Autoscan PEIM Loaded\n")); // // Get the PEI UNIX Autoscan PPI // Status = PeiServicesLocatePpi ( &gPeiUnixAutoScanPpiGuid, // GUID 0, // INSTANCE &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR (VOID **)&PeiUnixService // PPI ); ASSERT_EFI_ERROR (Status); Index = 0; do { Status = PeiUnixService->UnixAutoScan (Index, &MemoryBase, &MemorySize); if (!EFI_ERROR (Status)) { 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 // Status = PeiServicesInstallPeiMemory (MemoryBase, MemorySize); ASSERT_EFI_ERROR (Status); Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED; } BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, Attributes, MemoryBase, MemorySize ); } Index++; } while (!EFI_ERROR (Status)); // // Build the CPU hob with 36-bit addressing and 16-bits of IO space. // BuildCpuHob (36, 16); return Status; }
/** 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_CPUID_REGISTER FeatureInfo; UINT8 CpuAddressWidth; UINT32 RootComplexBar; UINT32 PmcBase; UINT32 IoBase; UINT32 IlbBase; UINT32 SpiBase; UINT32 MphyBase; UINT32 PunitBase; // // Pulish memory type info // PublishMemoryTypeInfo (); RootComplexBar = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_RCBA) & B_PCH_LPC_RCBA_BAR; DEBUG ((EFI_D_INFO, "RootComplexBar : 0x%x\n", RootComplexBar)); ASSERT (RootComplexBar != 0 && RootComplexBar != B_PCH_LPC_RCBA_BAR); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), RootComplexBar, 0x1000 ); PmcBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR; DEBUG ((EFI_D_INFO, "PmcBase : 0x%x\n", PmcBase)); ASSERT (PmcBase != 0 && PmcBase != B_PCH_LPC_PMC_BASE_BAR); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), PmcBase, 0x1000 ); IoBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR; DEBUG ((EFI_D_INFO, "IoBase : 0x%x\n", IoBase)); ASSERT (IoBase != 0 && IoBase != B_PCH_LPC_IO_BASE_BAR); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), IoBase, 0x40000 ); IlbBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ILB_BASE) & B_PCH_LPC_ILB_BASE_BAR; DEBUG ((EFI_D_INFO, "IlbBase : 0x%x\n", IlbBase)); ASSERT (IlbBase != 0 && IlbBase != B_PCH_LPC_ILB_BASE_BAR); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), IlbBase, 0x2000 ); SpiBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_SPI_BASE) & B_PCH_LPC_SPI_BASE_BAR; DEBUG ((EFI_D_INFO, "SpiBase : 0x%x\n", SpiBase)); ASSERT (SpiBase != 0 && SpiBase != B_PCH_LPC_SPI_BASE_BAR); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), SpiBase, 0x1000 ); MphyBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_MPHY_BASE) & B_PCH_LPC_MPHY_BASE_BAR; DEBUG ((EFI_D_INFO, "MphyBase : 0x%x\n", MphyBase)); ASSERT (MphyBase != 0 && MphyBase != B_PCH_LPC_MPHY_BASE_BAR); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), MphyBase, 0x100000 ); PunitBase = MmPci32 (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PUNIT_BASE) & B_PCH_LPC_PUNIT_BASE_BAR; DEBUG ((EFI_D_INFO, "PunitBase : 0x%x\n", PunitBase)); ASSERT (PunitBase != 0 && PunitBase != B_PCH_LPC_PUNIT_BASE_BAR); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), PunitBase, 0x1000 ); // // Local APIC // DEBUG ((EFI_D_INFO, "LOCAL_APIC_ADDRESS : 0x%x\n", LOCAL_APIC_ADDRESS)); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), LOCAL_APIC_ADDRESS, 0x1000 ); // // IO APIC // DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS : 0x%x\n", IO_APIC_ADDRESS)); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), IO_APIC_ADDRESS, 0x1000 ); // // Adding the PCIE Express area to the E820 memory table as type 2 memory. // BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), ((UINTN)PcdGet64(PcdPciExpressBaseAddress)), //PlatformInfo->PciData.PciExpressBase, 0x10000000 //PlatformInfo->PciData.PciExpressSize ); // // Adding the Flashpart to the E820 memory table as type 2 memory. // DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", PcdGet32(PcdFlashAreaBaseAddress))); BuildResourceDescriptorHob ( EFI_RESOURCE_FIRMWARE_DEVICE, (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), PcdGet32(PcdFlashAreaBaseAddress), PcdGet32(PcdFlashAreaSize) ); // // Create a CPU hand-off information // CpuAddressWidth = 32; AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx); if (FeatureInfo.RegEax >= EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE) { AsmCpuid (EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx); CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF); } BuildCpuHob(CpuAddressWidth, 16); return EFI_SUCCESS; }
/** 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; }
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; UINT32 PciBase; TopOfLowRam = GetSystemMemorySizeBelow4gb (); if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) { // // A 3GB base will always fall into Q35's 32-bit PCI host aperture, // regardless of the Q35 MMCONFIG BAR. Correspondingly, QEMU never lets // the RAM below 4 GB exceed it. // PciBase = BASE_2GB + BASE_1GB; ASSERT (TopOfLowRam <= PciBase); } 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 // AddIoMemoryRangeHob (PciBase, 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); } }
/** 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; }
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); } }
/*++ 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 MemoryPeim ( IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, IN UINT64 UefiMemorySize ) { EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; UINT64 ResourceLength; EFI_PEI_HOB_POINTERS NextHob; EFI_PHYSICAL_ADDRESS FdTop; EFI_PHYSICAL_ADDRESS SystemMemoryTop; EFI_PHYSICAL_ADDRESS ResourceTop; BOOLEAN Found; // Ensure PcdSystemMemorySize has been set ASSERT (PcdGet32 (PcdSystemMemorySize) != 0); // // Now, the permanent memory has been installed, we can call AllocatePages() // ResourceAttributes = ( 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_RESOURCE_ATTRIBUTE_TESTED ); // Reserved the memory space occupied by the firmware volume BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, PcdGet32 (PcdSystemMemoryBase), PcdGet32 (PcdSystemMemorySize) ); SystemMemoryTop = PcdGet32 (PcdSystemMemoryBase) + PcdGet32 (PcdSystemMemorySize); FdTop = PcdGet32(PcdFdBaseAddress) + PcdGet32(PcdFdSize); // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE // core to overwrite this area we must mark the region with the attribute non-present if ((PcdGet32 (PcdFdBaseAddress) >= PcdGet32 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) { Found = FALSE; // Search for System Memory Hob that contains the firmware NextHob.Raw = GetHobList (); while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) { if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) && (PcdGet32(PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) && (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength)) { ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute; ResourceLength = NextHob.ResourceDescriptor->ResourceLength; ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength; if (PcdGet32(PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) { if (SystemMemoryTop == FdTop) { NextHob.ResourceDescriptor->ResourceAttribute = ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT; } else { // Create the System Memory HOB for the firmware with the non-present attribute BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT, PcdGet32(PcdFdBaseAddress), PcdGet32(PcdFdSize)); // Top of the FD is system memory available for UEFI NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdFdSize); NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdFdSize); } } else { // Create the System Memory HOB for the firmware with the non-present attribute BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT, PcdGet32(PcdFdBaseAddress), PcdGet32(PcdFdSize)); // Update the HOB NextHob.ResourceDescriptor->ResourceLength = PcdGet32(PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart; // If there is some memory available on the top of the FD then create a HOB if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) { // Create the System Memory HOB for the remaining region (top of the FD) BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, FdTop, ResourceTop - FdTop); } } Found = TRUE; break; } NextHob.Raw = GET_NEXT_HOB (NextHob); } ASSERT(Found); } // Build Memory Allocation Hob InitMmu (); if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { // Optional feature that helps prevent EFI memory map fragmentation. BuildMemoryTypeInformationHob (); } return EFI_SUCCESS; }
/** Return the Virtual Memory Map of your platform This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- Virtual Memory mapping. This array must be ended by a zero-filled entry **/ VOID ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap ) { ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; UINTN Index = 0; ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; ASSERT (VirtualMemoryMap != NULL); VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); if (VirtualMemoryTable == NULL) { return; } if (FeaturePcdGet(PcdCacheEnable) == TRUE) { CacheAttributes = DDR_ATTRIBUTES_CACHED; } else { CacheAttributes = DDR_ATTRIBUTES_UNCACHED; } #ifdef ARM_BIGLITTLE_TC2 // Secure NOR0 Flash VirtualMemoryTable[Index].PhysicalBase = ARM_VE_SEC_NOR0_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SEC_NOR0_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SEC_NOR0_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Secure RAM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SEC_RAM0_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SEC_RAM0_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SEC_RAM0_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; #endif // SMB CS0 - NOR0 Flash VirtualMemoryTable[Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].Length = SIZE_256KB * 255; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Environment Variables region VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255); VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255); VirtualMemoryTable[Index].Length = SIZE_64KB * 4; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SMB CS1 or CS4 - NOR1 Flash VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR1_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR1_BASE; VirtualMemoryTable[Index].Length = SIZE_256KB * 255; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Environment Variables region VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR1_BASE + (SIZE_256KB * 255); VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR1_BASE + (SIZE_256KB * 255); VirtualMemoryTable[Index].Length = SIZE_64KB * 4; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SMB CS3 or CS1 - PSRAM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_SRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; // Motherboard peripherals VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; #ifdef ARM_BIGLITTLE_TC2 // Non-secure ROM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_TC2_NON_SECURE_ROM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_TC2_NON_SECURE_ROM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_TC2_NON_SECURE_ROM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; #endif // OnChip peripherals VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_ONCHIP_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_ONCHIP_PERIPH_BASE; VirtualMemoryTable[Index].Length = ARM_VE_ONCHIP_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SCC Region VirtualMemoryTable[++Index].PhysicalBase = ARM_CTA15A7_SCC_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_CTA15A7_SCC_BASE; VirtualMemoryTable[Index].Length = SIZE_64KB; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; #ifdef ARM_BIGLITTLE_TC2 // TC2 OnChip non-secure SRAM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_TC2_NON_SECURE_SRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_TC2_NON_SECURE_SRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_TC2_NON_SECURE_SRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; #endif #ifndef ARM_BIGLITTLE_TC2 // Workaround for SRAM bug in RTSM if (PcdGet64 (PcdSystemMemoryBase) != 0x80000000) { VirtualMemoryTable[++Index].PhysicalBase = 0x80000000; VirtualMemoryTable[Index].VirtualBase = 0x80000000; VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemoryBase) - 0x80000000; VirtualMemoryTable[Index].Attributes = CacheAttributes; } #endif // DDR VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize); VirtualMemoryTable[Index].Attributes = CacheAttributes; // Detect if it is a 1GB or 2GB Test Chip // [16:19]: 0=1GB TC2, 1=2GB TC2 if (MmioRead32(ARM_VE_SYS_PROCID0_REG) & (0xF << 16)) { DEBUG((EFI_D_ERROR,"Info: 2GB Test Chip 2 detected.\n")); 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_RESOURCE_ATTRIBUTE_TESTED, PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize), SIZE_1GB ); // Map the additional 1GB into the MMU VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize); VirtualMemoryTable[Index].Length = SIZE_1GB; VirtualMemoryTable[Index].Attributes = CacheAttributes; } // End of Table VirtualMemoryTable[++Index].PhysicalBase = 0; VirtualMemoryTable[Index].VirtualBase = 0; VirtualMemoryTable[Index].Length = 0; VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); *VirtualMemoryMap = VirtualMemoryTable; }
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); }
/** BIOS process FspBobList for Memory Resource Descriptor. @param[in] FspHobList Pointer to the HOB data structure produced by FSP. @return If platform process the FSP hob list successfully. **/ EFI_STATUS EFIAPI FspHobProcessForMemoryResource ( IN VOID *FspHobList ) { EFI_PEI_HOB_POINTERS Hob; UINT64 LowMemorySize; UINT64 FspMemorySize; EFI_PHYSICAL_ADDRESS FspMemoryBase; UINT64 PeiMemSize; EFI_PHYSICAL_ADDRESS PeiMemBase; UINT64 S3PeiMemSize; EFI_PHYSICAL_ADDRESS S3PeiMemBase; BOOLEAN FoundFspMemHob; EFI_STATUS Status; EFI_BOOT_MODE BootMode; PEI_CAPSULE_PPI *Capsule; VOID *CapsuleBuffer; UINTN CapsuleBufferLength; UINT64 RequiredMemSize; EFI_PEI_SERVICES **PeiServices; PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (); PeiServicesGetBootMode (&BootMode); PeiMemBase = 0; LowMemorySize = 0; FspMemorySize = 0; FspMemoryBase = 0; FoundFspMemHob = FALSE; // // Parse the hob list from fsp // Report all the resource hob except the memory between 1M and 4G // Hob.Raw = (UINT8 *)(UINTN)FspHobList; DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) { DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType)); if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) { DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart)); DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength)); DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner)); } if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) { LowMemorySize += Hob.ResourceDescriptor->ResourceLength; Hob.Raw = GET_NEXT_HOB (Hob); continue; } if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB) && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) { FoundFspMemHob = TRUE; FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart; FspMemorySize = Hob.ResourceDescriptor->ResourceLength; DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize)); } // // Report the resource hob // BuildResourceDescriptorHob ( Hob.ResourceDescriptor->ResourceType, Hob.ResourceDescriptor->ResourceAttribute, Hob.ResourceDescriptor->PhysicalStart, Hob.ResourceDescriptor->ResourceLength ); Hob.Raw = GET_NEXT_HOB (Hob); } if (!FoundFspMemHob) { DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n")); //ASSERT(FALSE); } DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize)); DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase)); DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize)); if (BootMode == BOOT_ON_S3_RESUME) { 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 ), BASE_1MB, LowMemorySize ); S3PeiMemBase = 0; S3PeiMemSize = 0; Status = GetS3MemoryInfo (&S3PeiMemBase, &S3PeiMemSize); ASSERT_EFI_ERROR (Status); DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize)); // // Make sure Stack and PeiMemory are not overlap // Status = PeiServicesInstallPeiMemory ( S3PeiMemBase, S3PeiMemSize ); ASSERT_EFI_ERROR (Status); } else { PeiMemSize = GetPeiMemSize (PeiServices, BootMode); DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize)); // // Capsule mode // Capsule = NULL; CapsuleBuffer = NULL; CapsuleBufferLength = 0; if (BootMode == BOOT_ON_FLASH_UPDATE) { Status = PeiServicesLocatePpi ( &gPeiCapsulePpiGuid, 0, NULL, (VOID **) &Capsule ); ASSERT_EFI_ERROR (Status); if (Status == EFI_SUCCESS) { // // Make sure Stack and CapsuleBuffer are not overlap // CapsuleBuffer = (VOID *)(UINTN)BASE_1MB; CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize); // // Call the Capsule PPI Coalesce function to coalesce the capsule data. // Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength); } } RequiredMemSize = RetrieveRequiredMemorySize (PeiServices); DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize)); // // Report the main memory // 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 ), BASE_1MB, LowMemorySize ); // // Make sure Stack and CapsuleBuffer are not overlap // // // Install efi memory // PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize; Status = PeiServicesInstallPeiMemory ( PeiMemBase, PeiMemSize - RequiredMemSize ); ASSERT_EFI_ERROR (Status); if (Capsule != NULL) { Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength); } } return EFI_SUCCESS; }
/** Returns the Virtual Memory Map of the platform. This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-Virtual Memory mapping. This array must be ended by a zero-filled entry. **/ VOID ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap ) { UINTN Index; ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; ResourceAttributes = 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_RESOURCE_ATTRIBUTE_TESTED; BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, FixedPcdGet64 (PcdDramBlock2Base), FixedPcdGet64 (PcdDramBlock2Size)); ASSERT (VirtualMemoryMap != NULL); Index = 0; VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); if (VirtualMemoryTable == NULL) { return; } // Expansion AXI - SMC Chip Select 0 (NOR Flash) VirtualMemoryTable[Index].PhysicalBase = SGI_EXP_SMC_CS0_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_SMC_CS0_BASE; VirtualMemoryTable[Index].Length = SIZE_64MB; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - SMC Chip Select 1 (NOR Flash) VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_SMC_CS1_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_SMC_CS1_BASE; VirtualMemoryTable[Index].Length = SIZE_64MB; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - SMSC 91X (Ethernet) VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_SMSC91X_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_SMSC91X_BASE; VirtualMemoryTable[Index].Length = SGI_EXP_SMSC91X_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - System Peripherals VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_SYS_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_SYS_PERIPH_BASE; VirtualMemoryTable[Index].Length = SGI_EXP_SYS_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Sub System Peripherals - Generic Watchdog VirtualMemoryTable[++Index].PhysicalBase = SGI_SUBSYS_GENERIC_WDOG_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_SUBSYS_GENERIC_WDOG_BASE; VirtualMemoryTable[Index].Length = SGI_SUBSYS_GENERIC_WDOG_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Sub System Peripherals - GIC-600 VirtualMemoryTable[++Index].PhysicalBase = SGI_SUBSYS_GENERIC_GIC_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_SUBSYS_GENERIC_GIC_BASE; VirtualMemoryTable[Index].Length = SGI_SUBSYS_GENERIC_GIC_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - Platform Peripherals - HDLCD1 VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_PLAT_PERIPH_HDLCD1_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_PLAT_PERIPH_HDLCD1_BASE; VirtualMemoryTable[Index].Length = SGI_EXP_PLAT_PERIPH_HDLCD1_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - Platform Peripherals - UART1 VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_PLAT_PERIPH_UART1_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_PLAT_PERIPH_UART1_BASE; VirtualMemoryTable[Index].Length = SGI_EXP_PLAT_PERIPH_UART1_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // DDR - (2GB - 16MB) VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize); VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; // DDR - Second Block VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdDramBlock2Base); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdDramBlock2Base); VirtualMemoryTable[Index].Length = PcdGet64 (PcdDramBlock2Size); VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; // PCI Configuration Space VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdPciExpressBaseAddress); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdPciExpressBaseAddress); VirtualMemoryTable[Index].Length = (FixedPcdGet32 (PcdPciBusMax) - FixedPcdGet32 (PcdPciBusMin) + 1) * SIZE_1MB; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // MM Memory Space VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdMmBufferBase); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdMmBufferBase); VirtualMemoryTable[Index].Length = PcdGet64 (PcdMmBufferSize); VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED; // End of Table VirtualMemoryTable[++Index].PhysicalBase = 0; VirtualMemoryTable[Index].VirtualBase = 0; VirtualMemoryTable[Index].Length = 0; VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; ASSERT ((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); *VirtualMemoryMap = VirtualMemoryTable; }
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; }
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); } } }
/** 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; }
EFI_STATUS EFIAPI MemoryPeim ( IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, IN UINT64 UefiMemorySize ) { EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; UINT64 SystemMemoryTop; // Ensure PcdSystemMemorySize has been set ASSERT (PcdGet64 (PcdSystemMemorySize) != 0); // // Now, the permanent memory has been installed, we can call AllocatePages() // ResourceAttributes = ( 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_RESOURCE_ATTRIBUTE_TESTED ); SystemMemoryTop = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize); if (SystemMemoryTop - 1 > MAX_ADDRESS) { BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, PcdGet64 (PcdSystemMemoryBase), (UINT64)MAX_ADDRESS - PcdGet64 (PcdSystemMemoryBase) + 1 ); BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, (UINT64)MAX_ADDRESS + 1, SystemMemoryTop - MAX_ADDRESS - 1 ); } else { BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, PcdGet64 (PcdSystemMemoryBase), PcdGet64 (PcdSystemMemorySize) ); } // // When running under virtualization, the PI/UEFI memory region may be // clean but not invalidated in system caches or in lower level caches // on other CPUs. So invalidate the region by virtual address, to ensure // that the contents we put there with the caches and MMU off will still // be visible after turning them on. // InvalidateDataCacheRange ((VOID*)(UINTN)UefiMemoryBase, UefiMemorySize); // Build Memory Allocation Hob InitMmu (); if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { // Optional feature that helps prevent EFI memory map fragmentation. BuildMemoryTypeInformationHob (); } return EFI_SUCCESS; }
/** This function installs memory. @param MemoryMap Array of memory ranges in the system @param NumRanges Number of entries in the MemoryMap array @param FspReservedArea Address of the FSP reserved area @param ReservedBytes Size of the FSP reserved area @param MrcData Memory data to save for S3 **/ VOID BuildHobs ( IN PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE *MemoryMap, IN UINT8 NumRanges, IN EFI_PHYSICAL_ADDRESS FspReservedArea, IN UINT64 ReservedBytes, IN MRC_PARAMS *MrcData ) { UINT8 Index; EFI_RESOURCE_ATTRIBUTE_TYPE Attribute; // // Build the descriptor for the FSP reserved area // BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, // MemoryType, ( 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 ), FspReservedArea, // MemoryBegin ReservedBytes // MemoryLength ); // // Install physical memory descriptor hobs for each memory range. // for (Index = 0; Index < NumRanges; Index++) { Attribute = 0; if (MemoryMap[Index].Type == DualChannelDdrMainMemory) { // // This is Main Memory range, give it to EFI // DEBUG((EFI_D_INFO, "0x%08lx - 0x%08lx: %atested memory\n", MemoryMap[Index].PhysicalAddress, MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength, (Index == 0) ? "Partially " : "Un")); BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, // MemoryType, ( 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 ), MemoryMap[Index].PhysicalAddress, // MemoryBegin MemoryMap[Index].RangeLength // MemoryLength ); } else { if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) || (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)) { DEBUG((EFI_D_ERROR, "0x%08lx - 0x%08lx: SMM\n", MemoryMap[Index].PhysicalAddress, MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength)); } if ((MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable) || (MemoryMap[Index].Type == DualChannelDdrGraphicsMemoryNonCacheable)) { DEBUG((EFI_D_ERROR, "0x%08lx - 0x%08lx: uncached\n", MemoryMap[Index].PhysicalAddress, MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength)); Attribute |= EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE; } if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) || (MemoryMap[Index].Type == DualChannelDdrGraphicsMemoryCacheable)) { // // TSEG and HSEG can be used with a write-back(WB) cache policy; however, // the specification requires that the TSEG and HSEG space be cached only // inside of the SMI handler. when using HSEG or TSEG an IA-32 processor // does not automatically write back and invalidate its cache before entering // SMM or before existing SMM therefore any MTRR defined for the active TSEG // or HSEG must be set to un-cacheable(UC) outside of SMM. // DEBUG((EFI_D_ERROR, "0x%08lx - 0x%08lx: Reserved, cached with write-back\n", MemoryMap[Index].PhysicalAddress, MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength)); Attribute |= EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE; } if ((MemoryMap[Index].Type == DualChannelDdrBiosReservedMemory) || (MemoryMap[Index].Type == DualChannelDdrFspReservedMemory) || (MemoryMap[Index].Type == DualChannelDdrGraphicsReservedMemory) || (MemoryMap[Index].Type == DualChannelDdrRmuReservedMemory)) { DEBUG((EFI_D_ERROR, "0x%08lx - 0x%08lx: Reserved, cached with write-back\n", MemoryMap[Index].PhysicalAddress, MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength)); Attribute |= EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE; } // // Make sure non-system memory is marked as reserved // BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_RESERVED, // MemoryType, Attribute, // MemoryAttribute MemoryMap[Index].PhysicalAddress, // MemoryBegin MemoryMap[Index].RangeLength // MemoryLength ); } } // // FSP BOOTLOADER TOLUM HOB // for (Index = 0; Index < NumRanges; Index++) { if (MemoryMap[Index].Type == DualChannelDdrBiosReservedMemory) { BuildResourceDescriptorWithOwnerHob ( EFI_RESOURCE_MEMORY_RESERVED, // MemoryType, ( 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 ), MemoryMap[Index].PhysicalAddress, MemoryMap[Index].RangeLength, &gFspBootLoaderTolumHobGuid ); } } // // FSP Reserved Memory // for (Index = 0; Index < NumRanges; Index++) { if (MemoryMap[Index].Type == DualChannelDdrFspReservedMemory) { BuildResourceDescriptorWithOwnerHob( 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 ), MemoryMap[Index].PhysicalAddress, MemoryMap[Index].RangeLength, &gFspReservedMemoryResourceHobGuid ); } } // // Save the MRC data for S3 // DEBUG ((EFI_D_INFO, "SaveConfig.\n")); BuildGuidDataHob ( &gFspNonVolatileStorageHobGuid, (VOID *) &MrcData->timings, ((sizeof (MrcData->timings) + 0x7) & (~0x7)) ); }