/** @file * * Copyright (c) 2011-2015, ARM Limited. All rights reserved. * Copyright (c) 2017, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * **/ #include #include #include #include #include #include VOID BuildMemoryTypeInformationHob ( VOID ); STATIC VOID InitMmu ( IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable ) { VOID *TranslationTableBase; UINTN TranslationTableSize; RETURN_STATUS Status; Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Error: Failed to enable MMU\n")); } } /*++ Routine Description: Remove the reserved region from a System Memory Hob that covers it. Arguments: FileHandle - Handle of the file being invoked. PeiServices - Describes the list of possible PEI Services. --*/ STATIC VOID ReserveMemoryRegion ( IN EFI_PHYSICAL_ADDRESS ReservedRegionBase, IN UINT32 ReservedRegionSize ) { EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; EFI_PHYSICAL_ADDRESS ReservedRegionTop; EFI_PHYSICAL_ADDRESS ResourceTop; EFI_PEI_HOB_POINTERS NextHob; UINT64 ResourceLength; ReservedRegionTop = ReservedRegionBase + ReservedRegionSize; // // Search for System Memory Hob that covers the reserved region, // and punch a hole in it // for (NextHob.Raw = GetHobList (); NextHob.Raw != NULL; NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) { if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) && (ReservedRegionBase >= NextHob.ResourceDescriptor->PhysicalStart) && (ReservedRegionTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength)) { ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute; ResourceLength = NextHob.ResourceDescriptor->ResourceLength; ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength; if (ReservedRegionBase == NextHob.ResourceDescriptor->PhysicalStart) { // // This region starts right at the start of the reserved region, so we // can simply move its start pointer and reduce its length by the same // value // NextHob.ResourceDescriptor->PhysicalStart += ReservedRegionSize; NextHob.ResourceDescriptor->ResourceLength -= ReservedRegionSize; } else if ((NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength) == ReservedRegionTop) { // // This region ends right at the end of the reserved region, so we // can simply reduce its length by the size of the region. // NextHob.ResourceDescriptor->ResourceLength -= ReservedRegionSize; } else { // // This region covers the reserved region. So split it into two regions, // each one touching the reserved region at either end, but not covering // it. // NextHob.ResourceDescriptor->ResourceLength = ReservedRegionBase - NextHob.ResourceDescriptor->PhysicalStart; // Create the System Memory HOB for the remaining region (top of the FD) BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, ReservedRegionTop, ResourceTop - ReservedRegionTop); } // // Reserve the memory space. // BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_RESERVED, 0, ReservedRegionBase, ReservedRegionSize); break; } NextHob.Raw = GET_NEXT_HOB (NextHob); } } /*++ 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 ) { ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable; // Get Virtual Memory Map from the Platform Library ArmPlatformGetVirtualMemoryMap (&MemoryTable); // Reserve memory region for ARM-TF ReserveMemoryRegion ( (EFI_PHYSICAL_ADDRESS)FixedPcdGet64 (PcdArmTFRegionBase), FixedPcdGet32 (PcdArmTFRegionSize) ); // Reserve additional memory region (e.g. for PEI stack) ReserveMemoryRegion ( (EFI_PHYSICAL_ADDRESS)FixedPcdGet64 (PcdAuxiliaryReservedRegionBase), FixedPcdGet32 (PcdAuxiliaryReservedRegionSize) ); // Reserve memory region for OP-TEE ReserveMemoryRegion ( (EFI_PHYSICAL_ADDRESS)FixedPcdGet64 (PcdOpTeeRegionBase), FixedPcdGet32 (PcdOpTeeRegionSize) ); // Build Memory Allocation Hob InitMmu (MemoryTable); if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { // Optional feature that helps prevent EFI memory map fragmentation. BuildMemoryTypeInformationHob (); } return EFI_SUCCESS; }