1a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel/** @file 2a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* 3a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* Copyright (c) 2011-2014, ARM Limited. All rights reserved. 4a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* Copyright (c) 2014, Linaro Limited. All rights reserved. 5a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* 6a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* This program and the accompanying materials 7a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* are licensed and made available under the terms and conditions of the BSD License 8a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* which accompanies this distribution. The full text of the license may be found at 9a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* http://opensource.org/licenses/bsd-license.php 10a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* 11a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel* 14a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel**/ 15a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 16a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel#include <PiPei.h> 17a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 18a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel#include <Library/ArmPlatformLib.h> 19a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel#include <Library/DebugLib.h> 20a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel#include <Library/HobLib.h> 21a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel#include <Library/MemoryAllocationLib.h> 22a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel#include <Library/PcdLib.h> 23e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel#include <Library/CacheMaintenanceLib.h> 24a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 25a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard BiesheuvelVOID 26a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard BiesheuvelBuildMemoryTypeInformationHob ( 27a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel VOID 28a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel ); 29a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 30a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard BiesheuvelVOID 31a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard BiesheuvelInitMmu ( 32a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel VOID 33a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel ) 34a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel{ 35a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable; 36a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel VOID *TranslationTableBase; 37a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel UINTN TranslationTableSize; 38a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel RETURN_STATUS Status; 39a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 40a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel // Get Virtual Memory Map from the Platform Library 41a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel ArmPlatformGetVirtualMemoryMap (&MemoryTable); 42a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 43a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in 44a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel // DRAM (even at the top of DRAM as it is the first permanent memory allocation) 45a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize); 46a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel if (EFI_ERROR (Status)) { 47a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n")); 48a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel } 49a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel} 50a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 51a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard BiesheuvelEFI_STATUS 52a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard BiesheuvelEFIAPI 53a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard BiesheuvelMemoryPeim ( 54a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, 55a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel IN UINT64 UefiMemorySize 56a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel ) 57a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel{ 58a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; 5972daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel UINT64 SystemMemoryTop; 60a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 61a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel // Ensure PcdSystemMemorySize has been set 62a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel ASSERT (PcdGet64 (PcdSystemMemorySize) != 0); 63a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 64a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel // 65a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel // Now, the permanent memory has been installed, we can call AllocatePages() 66a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel // 67a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel ResourceAttributes = ( 68a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel EFI_RESOURCE_ATTRIBUTE_PRESENT | 69a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 70a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | 71a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | 72a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | 73a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | 74a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel EFI_RESOURCE_ATTRIBUTE_TESTED 75a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel ); 76a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 7772daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel SystemMemoryTop = PcdGet64 (PcdSystemMemoryBase) + 7872daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel PcdGet64 (PcdSystemMemorySize); 7972daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel 8072daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel if (SystemMemoryTop - 1 > MAX_ADDRESS) { 8172daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel BuildResourceDescriptorHob ( 8272daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel EFI_RESOURCE_SYSTEM_MEMORY, 8372daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel ResourceAttributes, 8472daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel PcdGet64 (PcdSystemMemoryBase), 8572daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel (UINT64)MAX_ADDRESS - PcdGet64 (PcdSystemMemoryBase) + 1 8672daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel ); 8772daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel BuildResourceDescriptorHob ( 8872daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel EFI_RESOURCE_SYSTEM_MEMORY, 8972daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel ResourceAttributes, 9072daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel (UINT64)MAX_ADDRESS + 1, 9172daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel SystemMemoryTop - MAX_ADDRESS - 1 9272daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel ); 9372daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel } else { 9472daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel BuildResourceDescriptorHob ( 9572daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel EFI_RESOURCE_SYSTEM_MEMORY, 9672daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel ResourceAttributes, 9772daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel PcdGet64 (PcdSystemMemoryBase), 9872daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel PcdGet64 (PcdSystemMemorySize) 9972daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel ); 10072daeed8cfbbbf801c88412cf31cfef61ef59b6cArd Biesheuvel } 101a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 102e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel // 103e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel // When running under virtualization, the PI/UEFI memory region may be 104e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel // clean but not invalidated in system caches or in lower level caches 105e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel // on other CPUs. So invalidate the region by virtual address, to ensure 106e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel // that the contents we put there with the caches and MMU off will still 107e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel // be visible after turning them on. 108e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel // 109e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel InvalidateDataCacheRange ((VOID*)(UINTN)UefiMemoryBase, UefiMemorySize); 110e1d529909966027d2d6a2b0095dcb7a8b0886fa5Ard Biesheuvel 111a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel // Build Memory Allocation Hob 112a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel InitMmu (); 113a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 114a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { 115a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel // Optional feature that helps prevent EFI memory map fragmentation. 116a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel BuildMemoryTypeInformationHob (); 117a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel } 118a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel 119a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel return EFI_SUCCESS; 120a1bcf5c3d00474b8e3ed84c22624127ab548fd04Ard Biesheuvel} 121