]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/PlatformPei/Platform.c
OvmfPkg: consolidate POWER_MGMT_REGISTER_PIIX4() on "I440FxPiix4.h" macros
[mirror_edk2.git] / OvmfPkg / PlatformPei / Platform.c
1 /**@file
2 Platform PEI driver
3
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
6
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 //
18 // The package level header files this module uses
19 //
20 #include <PiPei.h>
21
22 //
23 // The Library classes this module consumes
24 //
25 #include <Library/DebugLib.h>
26 #include <Library/HobLib.h>
27 #include <Library/IoLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/PcdLib.h>
30 #include <Library/PciLib.h>
31 #include <Library/PeimEntryPoint.h>
32 #include <Library/PeiServicesLib.h>
33 #include <Library/QemuFwCfgLib.h>
34 #include <Library/ResourcePublicationLib.h>
35 #include <Guid/MemoryTypeInformation.h>
36 #include <Ppi/MasterBootMode.h>
37 #include <IndustryStandard/Pci22.h>
38 #include <OvmfPlatforms.h>
39
40 #include "Platform.h"
41 #include "Cmos.h"
42
43 EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
44 { EfiACPIMemoryNVS, 0x004 },
45 { EfiACPIReclaimMemory, 0x008 },
46 { EfiReservedMemoryType, 0x004 },
47 { EfiRuntimeServicesData, 0x024 },
48 { EfiRuntimeServicesCode, 0x030 },
49 { EfiBootServicesCode, 0x180 },
50 { EfiBootServicesData, 0xF00 },
51 { EfiMaxMemoryType, 0x000 }
52 };
53
54
55 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
56 {
57 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
58 &gEfiPeiMasterBootModePpiGuid,
59 NULL
60 }
61 };
62
63
64 EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
65
66 BOOLEAN mS3Supported = FALSE;
67
68
69 VOID
70 AddIoMemoryBaseSizeHob (
71 EFI_PHYSICAL_ADDRESS MemoryBase,
72 UINT64 MemorySize
73 )
74 {
75 BuildResourceDescriptorHob (
76 EFI_RESOURCE_MEMORY_MAPPED_IO,
77 EFI_RESOURCE_ATTRIBUTE_PRESENT |
78 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
79 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
80 EFI_RESOURCE_ATTRIBUTE_TESTED,
81 MemoryBase,
82 MemorySize
83 );
84 }
85
86 VOID
87 AddReservedMemoryBaseSizeHob (
88 EFI_PHYSICAL_ADDRESS MemoryBase,
89 UINT64 MemorySize
90 )
91 {
92 BuildResourceDescriptorHob (
93 EFI_RESOURCE_MEMORY_RESERVED,
94 EFI_RESOURCE_ATTRIBUTE_PRESENT |
95 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
96 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
97 EFI_RESOURCE_ATTRIBUTE_TESTED,
98 MemoryBase,
99 MemorySize
100 );
101 }
102
103 VOID
104 AddIoMemoryRangeHob (
105 EFI_PHYSICAL_ADDRESS MemoryBase,
106 EFI_PHYSICAL_ADDRESS MemoryLimit
107 )
108 {
109 AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
110 }
111
112
113 VOID
114 AddMemoryBaseSizeHob (
115 EFI_PHYSICAL_ADDRESS MemoryBase,
116 UINT64 MemorySize
117 )
118 {
119 BuildResourceDescriptorHob (
120 EFI_RESOURCE_SYSTEM_MEMORY,
121 EFI_RESOURCE_ATTRIBUTE_PRESENT |
122 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
123 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
124 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
125 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
126 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
127 EFI_RESOURCE_ATTRIBUTE_TESTED,
128 MemoryBase,
129 MemorySize
130 );
131 }
132
133
134 VOID
135 AddMemoryRangeHob (
136 EFI_PHYSICAL_ADDRESS MemoryBase,
137 EFI_PHYSICAL_ADDRESS MemoryLimit
138 )
139 {
140 AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
141 }
142
143
144 VOID
145 AddUntestedMemoryBaseSizeHob (
146 EFI_PHYSICAL_ADDRESS MemoryBase,
147 UINT64 MemorySize
148 )
149 {
150 BuildResourceDescriptorHob (
151 EFI_RESOURCE_SYSTEM_MEMORY,
152 EFI_RESOURCE_ATTRIBUTE_PRESENT |
153 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
154 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
155 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
156 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
157 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,
158 MemoryBase,
159 MemorySize
160 );
161 }
162
163
164 VOID
165 AddUntestedMemoryRangeHob (
166 EFI_PHYSICAL_ADDRESS MemoryBase,
167 EFI_PHYSICAL_ADDRESS MemoryLimit
168 )
169 {
170 AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
171 }
172
173 VOID
174 MemMapInitialization (
175 VOID
176 )
177 {
178 //
179 // Create Memory Type Information HOB
180 //
181 BuildGuidDataHob (
182 &gEfiMemoryTypeInformationGuid,
183 mDefaultMemoryTypeInformation,
184 sizeof(mDefaultMemoryTypeInformation)
185 );
186
187 //
188 // Add PCI IO Port space available for PCI resource allocations.
189 //
190 BuildResourceDescriptorHob (
191 EFI_RESOURCE_IO,
192 EFI_RESOURCE_ATTRIBUTE_PRESENT |
193 EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
194 0xC000,
195 0x4000
196 );
197
198 //
199 // Video memory + Legacy BIOS region
200 //
201 AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
202
203 if (!mXen) {
204 UINT32 TopOfLowRam;
205 TopOfLowRam = GetSystemMemorySizeBelow4gb ();
206
207 //
208 // address purpose size
209 // ------------ -------- -------------------------
210 // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g)
211 // 0xFC000000 gap 44 MB
212 // 0xFEC00000 IO-APIC 4 KB
213 // 0xFEC01000 gap 1020 KB
214 // 0xFED00000 HPET 1 KB
215 // 0xFED00400 gap 1023 KB
216 // 0xFEE00000 LAPIC 1 MB
217 //
218 AddIoMemoryRangeHob (TopOfLowRam < BASE_2GB ?
219 BASE_2GB : TopOfLowRam, 0xFC000000);
220 AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
221 AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
222 AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);
223 }
224 }
225
226
227 VOID
228 MiscInitialization (
229 VOID
230 )
231 {
232 UINT16 HostBridgeDevId;
233 UINTN PmCmd;
234 UINTN Pmba;
235 UINTN AcpiCtlReg;
236 UINT8 AcpiEnBit;
237
238 //
239 // Disable A20 Mask
240 //
241 IoOr8 (0x92, BIT1);
242
243 //
244 // Build the CPU hob with 36-bit addressing and 16-bits of IO space.
245 //
246 BuildCpuHob (36, 16);
247
248 //
249 // Query Host Bridge DID to determine platform type and save to PCD
250 //
251 HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
252 switch (HostBridgeDevId) {
253 case INTEL_82441_DEVICE_ID:
254 PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
255 Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
256 AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
257 AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;
258 break;
259 case INTEL_Q35_MCH_DEVICE_ID:
260 PmCmd = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);
261 Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
262 AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
263 AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN;
264 break;
265 default:
266 DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
267 __FUNCTION__, HostBridgeDevId));
268 ASSERT (FALSE);
269 return;
270 }
271 PcdSet16 (PcdOvmfHostBridgePciDevId, HostBridgeDevId);
272
273 //
274 // If the appropriate IOspace enable bit is set, assume the ACPI PMBA
275 // has been configured (e.g., by Xen) and skip the setup here.
276 // This matches the logic in AcpiTimerLibConstructor ().
277 //
278 if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
279 //
280 // The PEI phase should be exited with fully accessibe ACPI PM IO space:
281 // 1. set PMBA
282 //
283 PciAndThenOr32 (Pmba, (UINT32) ~0xFFC0, PcdGet16 (PcdAcpiPmBaseAddress));
284
285 //
286 // 2. set PCICMD/IOSE
287 //
288 PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);
289
290 //
291 // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN)
292 //
293 PciOr8 (AcpiCtlReg, AcpiEnBit);
294 }
295 }
296
297
298 VOID
299 BootModeInitialization (
300 VOID
301 )
302 {
303 EFI_STATUS Status;
304
305 if (CmosRead8 (0xF) == 0xFE) {
306 mBootMode = BOOT_ON_S3_RESUME;
307 }
308
309 Status = PeiServicesSetBootMode (mBootMode);
310 ASSERT_EFI_ERROR (Status);
311
312 Status = PeiServicesInstallPpi (mPpiBootMode);
313 ASSERT_EFI_ERROR (Status);
314 }
315
316
317 VOID
318 ReserveEmuVariableNvStore (
319 )
320 {
321 EFI_PHYSICAL_ADDRESS VariableStore;
322
323 //
324 // Allocate storage for NV variables early on so it will be
325 // at a consistent address. Since VM memory is preserved
326 // across reboots, this allows the NV variable storage to survive
327 // a VM reboot.
328 //
329 VariableStore =
330 (EFI_PHYSICAL_ADDRESS)(UINTN)
331 AllocateAlignedRuntimePages (
332 EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)),
333 PcdGet32 (PcdFlashNvStorageFtwSpareSize)
334 );
335 DEBUG ((EFI_D_INFO,
336 "Reserved variable store memory: 0x%lX; size: %dkb\n",
337 VariableStore,
338 (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
339 ));
340 PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore);
341 }
342
343
344 VOID
345 DebugDumpCmos (
346 VOID
347 )
348 {
349 UINTN Loop;
350
351 DEBUG ((EFI_D_INFO, "CMOS:\n"));
352
353 for (Loop = 0; Loop < 0x80; Loop++) {
354 if ((Loop % 0x10) == 0) {
355 DEBUG ((EFI_D_INFO, "%02x:", Loop));
356 }
357 DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
358 if ((Loop % 0x10) == 0xf) {
359 DEBUG ((EFI_D_INFO, "\n"));
360 }
361 }
362 }
363
364
365 /**
366 Perform Platform PEI initialization.
367
368 @param FileHandle Handle of the file being invoked.
369 @param PeiServices Describes the list of possible PEI Services.
370
371 @return EFI_SUCCESS The PEIM initialized successfully.
372
373 **/
374 EFI_STATUS
375 EFIAPI
376 InitializePlatform (
377 IN EFI_PEI_FILE_HANDLE FileHandle,
378 IN CONST EFI_PEI_SERVICES **PeiServices
379 )
380 {
381 DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
382
383 DebugDumpCmos ();
384
385 XenDetect ();
386
387 if (QemuFwCfgS3Enabled ()) {
388 DEBUG ((EFI_D_INFO, "S3 support was detected on QEMU\n"));
389 mS3Supported = TRUE;
390 }
391
392 BootModeInitialization ();
393
394 PublishPeiMemory ();
395
396 InitializeRamRegions ();
397
398 if (mXen) {
399 DEBUG ((EFI_D_INFO, "Xen was detected\n"));
400 InitializeXen ();
401 }
402
403 if (mBootMode != BOOT_ON_S3_RESUME) {
404 ReserveEmuVariableNvStore ();
405
406 PeiFvInitialization ();
407
408 MemMapInitialization ();
409 }
410
411 MiscInitialization ();
412
413 return EFI_SUCCESS;
414 }