]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/PlatformPei/Platform.c
OvmfPkg: Add PCD for Host Bridge dev. ID (PcdOvmfHostBridgePciDevId)
[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 PmRegMisc;
236
237 //
238 // Disable A20 Mask
239 //
240 IoOr8 (0x92, BIT1);
241
242 //
243 // Build the CPU hob with 36-bit addressing and 16-bits of IO space.
244 //
245 BuildCpuHob (36, 16);
246
247 //
248 // Query Host Bridge DID to determine platform type and save to PCD
249 //
250 HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
251 switch (HostBridgeDevId) {
252 case INTEL_82441_DEVICE_ID:
253 PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
254 Pmba = POWER_MGMT_REGISTER_PIIX4 (0x40);
255 PmRegMisc = POWER_MGMT_REGISTER_PIIX4 (0x80);
256 break;
257 case INTEL_Q35_MCH_DEVICE_ID:
258 PmCmd = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);
259 Pmba = POWER_MGMT_REGISTER_Q35 (0x40);
260 PmRegMisc = POWER_MGMT_REGISTER_Q35 (0x80);
261 break;
262 default:
263 DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
264 __FUNCTION__, HostBridgeDevId));
265 ASSERT (FALSE);
266 return;
267 }
268 PcdSet16 (PcdOvmfHostBridgePciDevId, HostBridgeDevId);
269
270 //
271 // If PMREGMISC/PMIOSE is set, assume the ACPI PMBA has been configured (for
272 // example by Xen) and skip the setup here. This matches the logic in
273 // AcpiTimerLibConstructor ().
274 //
275 if ((PciRead8 (PmRegMisc) & 0x01) == 0) {
276 //
277 // The PEI phase should be exited with fully accessibe PIIX4 IO space:
278 // 1. set PMBA
279 //
280 PciAndThenOr32 (Pmba, (UINT32) ~0xFFC0, PcdGet16 (PcdAcpiPmBaseAddress));
281
282 //
283 // 2. set PCICMD/IOSE
284 //
285 PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);
286
287 //
288 // 3. set PMREGMISC/PMIOSE
289 //
290 PciOr8 (PmRegMisc, 0x01);
291 }
292 }
293
294
295 VOID
296 BootModeInitialization (
297 VOID
298 )
299 {
300 EFI_STATUS Status;
301
302 if (CmosRead8 (0xF) == 0xFE) {
303 mBootMode = BOOT_ON_S3_RESUME;
304 }
305
306 Status = PeiServicesSetBootMode (mBootMode);
307 ASSERT_EFI_ERROR (Status);
308
309 Status = PeiServicesInstallPpi (mPpiBootMode);
310 ASSERT_EFI_ERROR (Status);
311 }
312
313
314 VOID
315 ReserveEmuVariableNvStore (
316 )
317 {
318 EFI_PHYSICAL_ADDRESS VariableStore;
319
320 //
321 // Allocate storage for NV variables early on so it will be
322 // at a consistent address. Since VM memory is preserved
323 // across reboots, this allows the NV variable storage to survive
324 // a VM reboot.
325 //
326 VariableStore =
327 (EFI_PHYSICAL_ADDRESS)(UINTN)
328 AllocateAlignedRuntimePages (
329 EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)),
330 PcdGet32 (PcdFlashNvStorageFtwSpareSize)
331 );
332 DEBUG ((EFI_D_INFO,
333 "Reserved variable store memory: 0x%lX; size: %dkb\n",
334 VariableStore,
335 (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
336 ));
337 PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore);
338 }
339
340
341 VOID
342 DebugDumpCmos (
343 VOID
344 )
345 {
346 UINTN Loop;
347
348 DEBUG ((EFI_D_INFO, "CMOS:\n"));
349
350 for (Loop = 0; Loop < 0x80; Loop++) {
351 if ((Loop % 0x10) == 0) {
352 DEBUG ((EFI_D_INFO, "%02x:", Loop));
353 }
354 DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
355 if ((Loop % 0x10) == 0xf) {
356 DEBUG ((EFI_D_INFO, "\n"));
357 }
358 }
359 }
360
361
362 /**
363 Perform Platform PEI initialization.
364
365 @param FileHandle Handle of the file being invoked.
366 @param PeiServices Describes the list of possible PEI Services.
367
368 @return EFI_SUCCESS The PEIM initialized successfully.
369
370 **/
371 EFI_STATUS
372 EFIAPI
373 InitializePlatform (
374 IN EFI_PEI_FILE_HANDLE FileHandle,
375 IN CONST EFI_PEI_SERVICES **PeiServices
376 )
377 {
378 DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
379
380 DebugDumpCmos ();
381
382 XenDetect ();
383
384 if (QemuFwCfgS3Enabled ()) {
385 DEBUG ((EFI_D_INFO, "S3 support was detected on QEMU\n"));
386 mS3Supported = TRUE;
387 }
388
389 BootModeInitialization ();
390
391 PublishPeiMemory ();
392
393 InitializeRamRegions ();
394
395 if (mXen) {
396 DEBUG ((EFI_D_INFO, "Xen was detected\n"));
397 InitializeXen ();
398 }
399
400 if (mBootMode != BOOT_ON_S3_RESUME) {
401 ReserveEmuVariableNvStore ();
402
403 PeiFvInitialization ();
404
405 MemMapInitialization ();
406 }
407
408 MiscInitialization ();
409
410 return EFI_SUCCESS;
411 }