VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/PlatformPei/MemDetect.c@ 58803

Last change on this file since 58803 was 58460, checked in by vboxsync, 9 years ago

EFI/Firmware: Merged in changes from ../UDK2014.SP1/.

  • Property svn:eol-style set to native
File size: 7.9 KB
Line 
1/**@file
2 Memory Detection for Virtual Machines.
3
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13Module Name:
14
15 MemDetect.c
16
17**/
18
19//
20// The package level header files this module uses
21//
22#include <PiPei.h>
23
24//
25// The Library classes this module consumes
26//
27#include <Library/BaseMemoryLib.h>
28#include <Library/DebugLib.h>
29#include <Library/HobLib.h>
30#include <Library/IoLib.h>
31#include <Library/PcdLib.h>
32#include <Library/PeimEntryPoint.h>
33#include <Library/ResourcePublicationLib.h>
34#include <Library/MtrrLib.h>
35
36#include "Platform.h"
37#include "Cmos.h"
38
39UINT32
40GetSystemMemorySizeBelow4gb (
41 VOID
42 )
43{
44 UINT8 Cmos0x34;
45 UINT8 Cmos0x35;
46
47 //
48 // CMOS 0x34/0x35 specifies the system memory above 16 MB.
49 // * CMOS(0x35) is the high byte
50 // * CMOS(0x34) is the low byte
51 // * The size is specified in 64kb chunks
52 // * Since this is memory above 16MB, the 16MB must be added
53 // into the calculation to get the total memory size.
54 //
55
56 Cmos0x34 = (UINT8) CmosRead8 (0x34);
57 Cmos0x35 = (UINT8) CmosRead8 (0x35);
58
59 return (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
60}
61
62
63STATIC
64UINT64
65GetSystemMemorySizeAbove4gb (
66 )
67{
68 UINT32 Size;
69 UINTN CmosIndex;
70
71 //
72 // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
73 // * CMOS(0x5d) is the most significant size byte
74 // * CMOS(0x5c) is the middle size byte
75 // * CMOS(0x5b) is the least significant size byte
76 // * The size is specified in 64kb chunks
77 //
78
79 Size = 0;
80 for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
81 Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);
82 }
83
84 return LShiftU64 (Size, 16);
85}
86
87/**
88 Publish PEI core memory
89
90 @return EFI_SUCCESS The PEIM initialized successfully.
91
92**/
93EFI_STATUS
94PublishPeiMemory (
95 VOID
96 )
97{
98 EFI_STATUS Status;
99 EFI_PHYSICAL_ADDRESS MemoryBase;
100 UINT64 MemorySize;
101 UINT64 LowerMemorySize;
102
103 if (mBootMode == BOOT_ON_S3_RESUME) {
104 MemoryBase = PcdGet32 (PcdS3AcpiReservedMemoryBase);
105 MemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);
106 } else {
107 LowerMemorySize = GetSystemMemorySizeBelow4gb ();
108
109 //
110 // Determine the range of memory to use during PEI
111 //
112 MemoryBase = PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);
113 MemorySize = LowerMemorySize - MemoryBase;
114 if (MemorySize > SIZE_64MB) {
115 MemoryBase = LowerMemorySize - SIZE_64MB;
116 MemorySize = SIZE_64MB;
117 }
118 }
119#ifdef VBOX
120 MemorySize -= BASE_64KB; /* Reserves 64KB for ACPI tables. */
121#endif
122
123 //
124 // Publish this memory to the PEI Core
125 //
126 Status = PublishSystemMemory(MemoryBase, MemorySize);
127 ASSERT_EFI_ERROR (Status);
128
129 return Status;
130}
131
132
133#ifndef VBOX
134/**
135 Peform Memory Detection for QEMU / KVM
136
137**/
138STATIC
139VOID
140QemuInitializeRam (
141 VOID
142 )
143{
144 UINT64 LowerMemorySize;
145 UINT64 UpperMemorySize;
146
147 DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__));
148
149 //
150 // Determine total memory size available
151 //
152 LowerMemorySize = GetSystemMemorySizeBelow4gb ();
153 UpperMemorySize = GetSystemMemorySizeAbove4gb ();
154
155 if (mBootMode != BOOT_ON_S3_RESUME) {
156 //
157 // Create memory HOBs
158 //
159 AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
160 AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
161 }
162
163 MtrrSetMemoryAttribute (BASE_1MB, LowerMemorySize - BASE_1MB, CacheWriteBack);
164
165 MtrrSetMemoryAttribute (0, BASE_512KB + BASE_128KB, CacheWriteBack);
166
167 if (UpperMemorySize != 0) {
168 if (mBootMode != BOOT_ON_S3_RESUME) {
169 AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
170 }
171
172 MtrrSetMemoryAttribute (BASE_4GB, UpperMemorySize, CacheWriteBack);
173 }
174}
175#else
176VOID
177VBoxInitializeRam (
178 VOID
179 )
180{
181 UINT64 LowerMemorySize;
182 UINT64 UpperMemorySize;
183 EFI_PHYSICAL_ADDRESS MemoryBase;
184 UINT64 MemorySize;
185
186 DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__));
187
188 //
189 // Determine total memory size available
190 //
191 LowerMemorySize = GetSystemMemorySizeBelow4gb ();
192 UpperMemorySize = GetSystemMemorySizeAbove4gb ();
193
194 if (mBootMode == BOOT_ON_S3_RESUME) {
195 MemoryBase = PcdGet32 (PcdS3AcpiReservedMemoryBase);
196 MemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);
197 } else {
198 LowerMemorySize = GetSystemMemorySizeBelow4gb ();
199
200 //
201 // Determine the range of memory to use during PEI
202 //
203 MemoryBase = PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);
204 MemorySize = LowerMemorySize - MemoryBase;
205 if (MemorySize > SIZE_64MB) {
206 MemoryBase = LowerMemorySize - SIZE_64MB;
207 MemorySize = SIZE_64MB;
208 }
209 }
210 MemorySize -= BASE_64KB; /* Reserves 64KB for ACPI tables. */
211
212 //
213 // Create memory HOBs
214 //
215 AddMemoryBaseSizeHob (MemoryBase, MemorySize);
216 AddMemoryRangeHob (BASE_1MB, MemoryBase);
217 MtrrSetMemoryAttribute (BASE_1MB, MemoryBase + MemorySize - BASE_1MB, CacheWriteBack);
218 AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
219 MtrrSetMemoryAttribute (0, BASE_512KB + BASE_128KB, CacheWriteBack);
220
221 if (UpperMemorySize != 0) {
222 AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
223
224 MtrrSetMemoryAttribute (BASE_4GB, UpperMemorySize, CacheWriteBack);
225 }
226}
227#endif
228
229/**
230 Publish system RAM and reserve memory regions
231
232**/
233VOID
234InitializeRamRegions (
235 VOID
236 )
237{
238#ifndef VBOX
239 if (!mXen) {
240 QemuInitializeRam ();
241 } else {
242 XenPublishRamRegions ();
243 }
244#else
245 VBoxInitializeRam();
246#endif
247
248 if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
249 //
250 // This is the memory range that will be used for PEI on S3 resume
251 //
252 BuildMemoryAllocationHob (
253 (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdS3AcpiReservedMemoryBase),
254 (UINT64)(UINTN) PcdGet32 (PcdS3AcpiReservedMemorySize),
255 EfiACPIMemoryNVS
256 );
257
258 //
259 // Cover the initial RAM area used as stack and temporary PEI heap.
260 //
261 // This is reserved as ACPI NVS so it can be used on S3 resume.
262 //
263 BuildMemoryAllocationHob (
264 PcdGet32 (PcdOvmfSecPeiTempRamBase),
265 PcdGet32 (PcdOvmfSecPeiTempRamSize),
266 EfiACPIMemoryNVS
267 );
268
269 //
270 // SEC stores its table of GUIDed section handlers here.
271 //
272 BuildMemoryAllocationHob (
273 PcdGet64 (PcdGuidedExtractHandlerTableAddress),
274 PcdGet32 (PcdGuidedExtractHandlerTableSize),
275 EfiACPIMemoryNVS
276 );
277
278#ifdef MDE_CPU_X64
279 //
280 // Reserve the initial page tables built by the reset vector code.
281 //
282 // Since this memory range will be used by the Reset Vector on S3
283 // resume, it must be reserved as ACPI NVS.
284 //
285 BuildMemoryAllocationHob (
286 (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecPageTablesBase),
287 (UINT64)(UINTN) PcdGet32 (PcdOvmfSecPageTablesSize),
288 EfiACPIMemoryNVS
289 );
290#endif
291 }
292
293 if (mBootMode != BOOT_ON_S3_RESUME) {
294 //
295 // Reserve the lock box storage area
296 //
297 // Since this memory range will be used on S3 resume, it must be
298 // reserved as ACPI NVS.
299 //
300 // If S3 is unsupported, then various drivers might still write to the
301 // LockBox area. We ought to prevent DXE from serving allocation requests
302 // such that they would overlap the LockBox storage.
303 //
304 ZeroMem (
305 (VOID*)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
306 (UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize)
307 );
308 BuildMemoryAllocationHob (
309 (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
310 (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize),
311 mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
312 );
313 }
314}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette