/** @file * * Copyright (c) 2011-2015, ARM Limited. All rights reserved. * Copyright (c) 2017, ARM Limited. All rights reserved. * * This program and the accompanying materials * are licensed and made available under the terms and conditions of the BSD License * which accompanies this distribution. The full text of the license may be found at * http://opensource.org/licenses/bsd-license.php * * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. * **/ #include #include #include #include #include #include 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: 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; EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; UINT64 ResourceLength; EFI_PEI_HOB_POINTERS NextHob; EFI_PHYSICAL_ADDRESS SecureTop; EFI_PHYSICAL_ADDRESS ResourceTop; // Get Virtual Memory Map from the Platform Library ArmPlatformGetVirtualMemoryMap (&MemoryTable); SecureTop = (EFI_PHYSICAL_ADDRESS)FixedPcdGet64 (PcdSecureRegionBase) + FixedPcdGet32 (PcdSecureRegionSize); // // Search for System Memory Hob that covers the secure firmware, // 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) && (FixedPcdGet64 (PcdSecureRegionBase) >= NextHob.ResourceDescriptor->PhysicalStart) && (SecureTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength)) { ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute; ResourceLength = NextHob.ResourceDescriptor->ResourceLength; ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength; if (FixedPcdGet64 (PcdSecureRegionBase) == 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 += FixedPcdGet32 (PcdSecureRegionSize); NextHob.ResourceDescriptor->ResourceLength -= FixedPcdGet32 (PcdSecureRegionSize); } else if ((NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength) == SecureTop) { // // 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 -= FixedPcdGet32 (PcdSecureRegionSize); } 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 = FixedPcdGet64 (PcdSecureRegionBase) - NextHob.ResourceDescriptor->PhysicalStart; // Create the System Memory HOB for the remaining region (top of the FD) BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, SecureTop, ResourceTop - SecureTop); } // // Reserve the memory space occupied by the secure firmware // BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_RESERVED, 0, FixedPcdGet64 (PcdSecureRegionBase), FixedPcdGet32 (PcdSecureRegionSize)); break; } NextHob.Raw = GET_NEXT_HOB (NextHob); } // Build Memory Allocation Hob InitMmu (MemoryTable); if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { // Optional feature that helps prevent EFI memory map fragmentation. BuildMemoryTypeInformationHob (); } return EFI_SUCCESS; }