]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/PlatformPei/MemDetect.c
OvmfPkg: implement LockBoxLib
[mirror_edk2.git] / OvmfPkg / PlatformPei / MemDetect.c
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
13 Module 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
39 UINT32
40 GetSystemMemorySizeBelow4gb (
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
63 STATIC
64 UINT64
65 GetSystemMemorySizeAbove4gb (
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 **/
93 EFI_STATUS
94 PublishPeiMemory (
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
120 //
121 // Publish this memory to the PEI Core
122 //
123 Status = PublishSystemMemory(MemoryBase, MemorySize);
124 ASSERT_EFI_ERROR (Status);
125
126 return Status;
127 }
128
129
130 /**
131 Peform Memory Detection for QEMU / KVM
132
133 **/
134 STATIC
135 VOID
136 QemuInitializeRam (
137 VOID
138 )
139 {
140 UINT64 LowerMemorySize;
141 UINT64 UpperMemorySize;
142
143 DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__));
144
145 //
146 // Determine total memory size available
147 //
148 LowerMemorySize = GetSystemMemorySizeBelow4gb ();
149 UpperMemorySize = GetSystemMemorySizeAbove4gb ();
150
151 if (mBootMode != BOOT_ON_S3_RESUME) {
152 //
153 // Create memory HOBs
154 //
155 AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
156 AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
157 }
158
159 MtrrSetMemoryAttribute (BASE_1MB, LowerMemorySize - BASE_1MB, CacheWriteBack);
160
161 MtrrSetMemoryAttribute (0, BASE_512KB + BASE_128KB, CacheWriteBack);
162
163 if (UpperMemorySize != 0) {
164 if (mBootMode != BOOT_ON_S3_RESUME) {
165 AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
166 }
167
168 MtrrSetMemoryAttribute (BASE_4GB, UpperMemorySize, CacheWriteBack);
169 }
170 }
171
172 /**
173 Publish system RAM and reserve memory regions
174
175 **/
176 VOID
177 InitializeRamRegions (
178 VOID
179 )
180 {
181 if (!mXen) {
182 QemuInitializeRam ();
183 } else {
184 XenPublishRamRegions ();
185 }
186
187 if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
188 //
189 // This is the memory range that will be used for PEI on S3 resume
190 //
191 BuildMemoryAllocationHob (
192 (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdS3AcpiReservedMemoryBase),
193 (UINT64)(UINTN) PcdGet32 (PcdS3AcpiReservedMemorySize),
194 EfiACPIMemoryNVS
195 );
196
197 //
198 // Cover the initial RAM area used as stack and temporary PEI heap.
199 //
200 // This is reserved as ACPI NVS so it can be used on S3 resume.
201 //
202 BuildMemoryAllocationHob (
203 PcdGet32 (PcdOvmfSecPeiTempRamBase),
204 PcdGet32 (PcdOvmfSecPeiTempRamSize),
205 EfiACPIMemoryNVS
206 );
207
208 #ifdef MDE_CPU_X64
209 //
210 // Reserve the initial page tables built by the reset vector code.
211 //
212 // Since this memory range will be used by the Reset Vector on S3
213 // resume, it must be reserved as ACPI NVS.
214 //
215 BuildMemoryAllocationHob (
216 (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecPageTablesBase),
217 (UINT64)(UINTN) PcdGet32 (PcdOvmfSecPageTablesSize),
218 EfiACPIMemoryNVS
219 );
220 #endif
221
222 //
223 // Reserve the lock box storage area
224 //
225 // Since this memory range will be used on S3 resume, it must be
226 // reserved as ACPI NVS.
227 //
228 ZeroMem (
229 (VOID*)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
230 (UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize)
231 );
232 BuildMemoryAllocationHob (
233 (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
234 (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize),
235 EfiACPIMemoryNVS
236 );
237 }
238 }