]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ArmPlatformPkg / MemoryInitPei / MemoryInitPeiLib.c
1 /** @file
2
3 Copyright (c) 2011-2015, ARM Limited. All rights reserved.
4
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PiPei.h>
10
11 #include <Library/ArmMmuLib.h>
12 #include <Library/ArmPlatformLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/HobLib.h>
15 #include <Library/MemoryAllocationLib.h>
16 #include <Library/PcdLib.h>
17
18 VOID
19 BuildMemoryTypeInformationHob (
20 VOID
21 );
22
23 STATIC
24 VOID
25 InitMmu (
26 IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable
27 )
28 {
29 VOID *TranslationTableBase;
30 UINTN TranslationTableSize;
31 RETURN_STATUS Status;
32
33 // Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
34 // DRAM (even at the top of DRAM as it is the first permanent memory allocation)
35 Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
36 if (EFI_ERROR (Status)) {
37 DEBUG ((DEBUG_ERROR, "Error: Failed to enable MMU\n"));
38 }
39 }
40
41 /*++
42
43 Routine Description:
44
45
46
47 Arguments:
48
49 FileHandle - Handle of the file being invoked.
50 PeiServices - Describes the list of possible PEI Services.
51
52 Returns:
53
54 Status - EFI_SUCCESS if the boot mode could be set
55
56 --*/
57 EFI_STATUS
58 EFIAPI
59 MemoryPeim (
60 IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
61 IN UINT64 UefiMemorySize
62 )
63 {
64 ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
65 EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
66 UINT64 ResourceLength;
67 EFI_PEI_HOB_POINTERS NextHob;
68 EFI_PHYSICAL_ADDRESS FdTop;
69 EFI_PHYSICAL_ADDRESS SystemMemoryTop;
70 EFI_PHYSICAL_ADDRESS ResourceTop;
71 BOOLEAN Found;
72
73 // Get Virtual Memory Map from the Platform Library
74 ArmPlatformGetVirtualMemoryMap (&MemoryTable);
75
76 // Ensure PcdSystemMemorySize has been set
77 ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
78
79 //
80 // Now, the permanent memory has been installed, we can call AllocatePages()
81 //
82 ResourceAttributes = (
83 EFI_RESOURCE_ATTRIBUTE_PRESENT |
84 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
85 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
86 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
87 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
88 EFI_RESOURCE_ATTRIBUTE_TESTED
89 );
90
91 //
92 // Check if the resource for the main system memory has been declared
93 //
94 Found = FALSE;
95 NextHob.Raw = GetHobList ();
96 while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
97 if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
98 (PcdGet64 (PcdSystemMemoryBase) >= NextHob.ResourceDescriptor->PhysicalStart) &&
99 (NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength <= PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize)))
100 {
101 Found = TRUE;
102 break;
103 }
104
105 NextHob.Raw = GET_NEXT_HOB (NextHob);
106 }
107
108 if (!Found) {
109 // Reserved the memory space occupied by the firmware volume
110 BuildResourceDescriptorHob (
111 EFI_RESOURCE_SYSTEM_MEMORY,
112 ResourceAttributes,
113 PcdGet64 (PcdSystemMemoryBase),
114 PcdGet64 (PcdSystemMemorySize)
115 );
116 }
117
118 //
119 // Reserved the memory space occupied by the firmware volume
120 //
121
122 SystemMemoryTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemoryBase) + (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemorySize);
123 FdTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFdBaseAddress) + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFdSize);
124
125 // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE
126 // core to overwrite this area we must create a memory allocation HOB for the region,
127 // but this only works if we split off the underlying resource descriptor as well.
128 if ((PcdGet64 (PcdFdBaseAddress) >= PcdGet64 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) {
129 Found = FALSE;
130
131 // Search for System Memory Hob that contains the firmware
132 NextHob.Raw = GetHobList ();
133 while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
134 if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
135 (PcdGet64 (PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) &&
136 (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
137 {
138 ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
139 ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
140 ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
141
142 if (PcdGet64 (PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) {
143 if (SystemMemoryTop != FdTop) {
144 // Create the System Memory HOB for the firmware
145 BuildResourceDescriptorHob (
146 EFI_RESOURCE_SYSTEM_MEMORY,
147 ResourceAttributes,
148 PcdGet64 (PcdFdBaseAddress),
149 PcdGet32 (PcdFdSize)
150 );
151
152 // Top of the FD is system memory available for UEFI
153 NextHob.ResourceDescriptor->PhysicalStart += PcdGet32 (PcdFdSize);
154 NextHob.ResourceDescriptor->ResourceLength -= PcdGet32 (PcdFdSize);
155 }
156 } else {
157 // Create the System Memory HOB for the firmware
158 BuildResourceDescriptorHob (
159 EFI_RESOURCE_SYSTEM_MEMORY,
160 ResourceAttributes,
161 PcdGet64 (PcdFdBaseAddress),
162 PcdGet32 (PcdFdSize)
163 );
164
165 // Update the HOB
166 NextHob.ResourceDescriptor->ResourceLength = PcdGet64 (PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart;
167
168 // If there is some memory available on the top of the FD then create a HOB
169 if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) {
170 // Create the System Memory HOB for the remaining region (top of the FD)
171 BuildResourceDescriptorHob (
172 EFI_RESOURCE_SYSTEM_MEMORY,
173 ResourceAttributes,
174 FdTop,
175 ResourceTop - FdTop
176 );
177 }
178 }
179
180 // Mark the memory covering the Firmware Device as boot services data
181 BuildMemoryAllocationHob (
182 PcdGet64 (PcdFdBaseAddress),
183 PcdGet32 (PcdFdSize),
184 EfiBootServicesData
185 );
186
187 Found = TRUE;
188 break;
189 }
190
191 NextHob.Raw = GET_NEXT_HOB (NextHob);
192 }
193
194 ASSERT (Found);
195 }
196
197 // Build Memory Allocation Hob
198 InitMmu (MemoryTable);
199
200 if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
201 // Optional feature that helps prevent EFI memory map fragmentation.
202 BuildMemoryTypeInformationHob ();
203 }
204
205 return EFI_SUCCESS;
206 }