2 Memory Detection for Virtual Machines.
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
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.
20 // The package level header files this module uses
25 // The Library classes this module consumes
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>
40 GetSystemMemorySizeBelow4gb (
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.
56 Cmos0x34
= (UINT8
) CmosRead8 (0x34);
57 Cmos0x35
= (UINT8
) CmosRead8 (0x35);
59 return (((UINTN
)((Cmos0x35
<< 8) + Cmos0x34
) << 16) + SIZE_16MB
);
65 GetSystemMemorySizeAbove4gb (
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
80 for (CmosIndex
= 0x5d; CmosIndex
>= 0x5b; CmosIndex
--) {
81 Size
= (UINT32
) (Size
<< 8) + (UINT32
) CmosRead8 (CmosIndex
);
84 return LShiftU64 (Size
, 16);
88 Publish PEI core memory
90 @return EFI_SUCCESS The PEIM initialized successfully.
99 EFI_PHYSICAL_ADDRESS MemoryBase
;
101 UINT64 LowerMemorySize
;
103 if (mBootMode
== BOOT_ON_S3_RESUME
) {
104 MemoryBase
= PcdGet32 (PcdS3AcpiReservedMemoryBase
);
105 MemorySize
= PcdGet32 (PcdS3AcpiReservedMemorySize
);
107 LowerMemorySize
= GetSystemMemorySizeBelow4gb ();
110 // Determine the range of memory to use during PEI
112 MemoryBase
= PcdGet32 (PcdOvmfDxeMemFvBase
) + PcdGet32 (PcdOvmfDxeMemFvSize
);
113 MemorySize
= LowerMemorySize
- MemoryBase
;
114 if (MemorySize
> SIZE_64MB
) {
115 MemoryBase
= LowerMemorySize
- SIZE_64MB
;
116 MemorySize
= SIZE_64MB
;
121 // Publish this memory to the PEI Core
123 Status
= PublishSystemMemory(MemoryBase
, MemorySize
);
124 ASSERT_EFI_ERROR (Status
);
131 Peform Memory Detection for QEMU / KVM
140 UINT64 LowerMemorySize
;
141 UINT64 UpperMemorySize
;
143 DEBUG ((EFI_D_INFO
, "%a called\n", __FUNCTION__
));
146 // Determine total memory size available
148 LowerMemorySize
= GetSystemMemorySizeBelow4gb ();
149 UpperMemorySize
= GetSystemMemorySizeAbove4gb ();
151 if (mBootMode
!= BOOT_ON_S3_RESUME
) {
153 // Create memory HOBs
155 AddMemoryRangeHob (BASE_1MB
, LowerMemorySize
);
156 AddMemoryRangeHob (0, BASE_512KB
+ BASE_128KB
);
159 MtrrSetMemoryAttribute (BASE_1MB
, LowerMemorySize
- BASE_1MB
, CacheWriteBack
);
161 MtrrSetMemoryAttribute (0, BASE_512KB
+ BASE_128KB
, CacheWriteBack
);
163 if (UpperMemorySize
!= 0) {
164 if (mBootMode
!= BOOT_ON_S3_RESUME
) {
165 AddUntestedMemoryBaseSizeHob (BASE_4GB
, UpperMemorySize
);
168 MtrrSetMemoryAttribute (BASE_4GB
, UpperMemorySize
, CacheWriteBack
);
173 Publish system RAM and reserve memory regions
177 InitializeRamRegions (
182 QemuInitializeRam ();
184 XenPublishRamRegions ();
187 if (mS3Supported
&& mBootMode
!= BOOT_ON_S3_RESUME
) {
189 // This is the memory range that will be used for PEI on S3 resume
191 BuildMemoryAllocationHob (
192 (EFI_PHYSICAL_ADDRESS
)(UINTN
) PcdGet32 (PcdS3AcpiReservedMemoryBase
),
193 (UINT64
)(UINTN
) PcdGet32 (PcdS3AcpiReservedMemorySize
),
198 // Cover the initial RAM area used as stack and temporary PEI heap.
200 // This is reserved as ACPI NVS so it can be used on S3 resume.
202 BuildMemoryAllocationHob (
203 PcdGet32 (PcdOvmfSecPeiTempRamBase
),
204 PcdGet32 (PcdOvmfSecPeiTempRamSize
),
209 // SEC stores its table of GUIDed section handlers here.
211 BuildMemoryAllocationHob (
212 PcdGet64 (PcdGuidedExtractHandlerTableAddress
),
213 PcdGet32 (PcdGuidedExtractHandlerTableSize
),
219 // Reserve the initial page tables built by the reset vector code.
221 // Since this memory range will be used by the Reset Vector on S3
222 // resume, it must be reserved as ACPI NVS.
224 BuildMemoryAllocationHob (
225 (EFI_PHYSICAL_ADDRESS
)(UINTN
) PcdGet32 (PcdOvmfSecPageTablesBase
),
226 (UINT64
)(UINTN
) PcdGet32 (PcdOvmfSecPageTablesSize
),
232 if (mBootMode
!= BOOT_ON_S3_RESUME
) {
234 // Reserve the lock box storage area
236 // Since this memory range will be used on S3 resume, it must be
237 // reserved as ACPI NVS.
239 // If S3 is unsupported, then various drivers might still write to the
240 // LockBox area. We ought to prevent DXE from serving allocation requests
241 // such that they would overlap the LockBox storage.
244 (VOID
*)(UINTN
) PcdGet32 (PcdOvmfLockBoxStorageBase
),
245 (UINTN
) PcdGet32 (PcdOvmfLockBoxStorageSize
)
247 BuildMemoryAllocationHob (
248 (EFI_PHYSICAL_ADDRESS
)(UINTN
) PcdGet32 (PcdOvmfLockBoxStorageBase
),
249 (UINT64
)(UINTN
) PcdGet32 (PcdOvmfLockBoxStorageSize
),
250 mS3Supported
? EfiACPIMemoryNVS
: EfiBootServicesData