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