3e69d923d4215a4f79793b88dfb1de75ca1de25f
[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/ResourcePublicationLib.h>
34 #include <Guid/MemoryTypeInformation.h>
35 #include <Ppi/MasterBootMode.h>
36 #include <IndustryStandard/Pci22.h>
37
38 #include "Platform.h"
39 #include "Cmos.h"
40
41 EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
42 { EfiACPIMemoryNVS, 0x004 },
43 { EfiACPIReclaimMemory, 0x008 },
44 { EfiReservedMemoryType, 0x004 },
45 { EfiRuntimeServicesData, 0x024 },
46 { EfiRuntimeServicesCode, 0x030 },
47 { EfiBootServicesCode, 0x180 },
48 { EfiBootServicesData, 0xF00 },
49 { EfiMaxMemoryType, 0x000 }
50 };
51
52
53 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
54 {
55 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
56 &gEfiPeiMasterBootModePpiGuid,
57 NULL
58 }
59 };
60
61
62 EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
63
64
65 VOID
66 AddIoMemoryBaseSizeHob (
67 EFI_PHYSICAL_ADDRESS MemoryBase,
68 UINT64 MemorySize
69 )
70 {
71 BuildResourceDescriptorHob (
72 EFI_RESOURCE_MEMORY_MAPPED_IO,
73 EFI_RESOURCE_ATTRIBUTE_PRESENT |
74 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
75 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
76 EFI_RESOURCE_ATTRIBUTE_TESTED,
77 MemoryBase,
78 MemorySize
79 );
80 }
81
82 VOID
83 AddReservedMemoryBaseSizeHob (
84 EFI_PHYSICAL_ADDRESS MemoryBase,
85 UINT64 MemorySize
86 )
87 {
88 BuildResourceDescriptorHob (
89 EFI_RESOURCE_MEMORY_RESERVED,
90 EFI_RESOURCE_ATTRIBUTE_PRESENT |
91 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
92 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
93 EFI_RESOURCE_ATTRIBUTE_TESTED,
94 MemoryBase,
95 MemorySize
96 );
97 }
98
99 VOID
100 AddIoMemoryRangeHob (
101 EFI_PHYSICAL_ADDRESS MemoryBase,
102 EFI_PHYSICAL_ADDRESS MemoryLimit
103 )
104 {
105 AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
106 }
107
108
109 VOID
110 AddMemoryBaseSizeHob (
111 EFI_PHYSICAL_ADDRESS MemoryBase,
112 UINT64 MemorySize
113 )
114 {
115 BuildResourceDescriptorHob (
116 EFI_RESOURCE_SYSTEM_MEMORY,
117 EFI_RESOURCE_ATTRIBUTE_PRESENT |
118 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
119 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
120 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
121 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
122 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
123 EFI_RESOURCE_ATTRIBUTE_TESTED,
124 MemoryBase,
125 MemorySize
126 );
127 }
128
129
130 VOID
131 AddMemoryRangeHob (
132 EFI_PHYSICAL_ADDRESS MemoryBase,
133 EFI_PHYSICAL_ADDRESS MemoryLimit
134 )
135 {
136 AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
137 }
138
139
140 VOID
141 AddUntestedMemoryBaseSizeHob (
142 EFI_PHYSICAL_ADDRESS MemoryBase,
143 UINT64 MemorySize
144 )
145 {
146 BuildResourceDescriptorHob (
147 EFI_RESOURCE_SYSTEM_MEMORY,
148 EFI_RESOURCE_ATTRIBUTE_PRESENT |
149 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
150 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
151 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
152 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
153 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,
154 MemoryBase,
155 MemorySize
156 );
157 }
158
159
160 VOID
161 AddUntestedMemoryRangeHob (
162 EFI_PHYSICAL_ADDRESS MemoryBase,
163 EFI_PHYSICAL_ADDRESS MemoryLimit
164 )
165 {
166 AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
167 }
168
169 VOID
170 MemMapInitialization (
171 VOID
172 )
173 {
174 //
175 // Create Memory Type Information HOB
176 //
177 BuildGuidDataHob (
178 &gEfiMemoryTypeInformationGuid,
179 mDefaultMemoryTypeInformation,
180 sizeof(mDefaultMemoryTypeInformation)
181 );
182
183 //
184 // Add PCI IO Port space available for PCI resource allocations.
185 //
186 BuildResourceDescriptorHob (
187 EFI_RESOURCE_IO,
188 EFI_RESOURCE_ATTRIBUTE_PRESENT |
189 EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
190 0xC000,
191 0x4000
192 );
193
194 //
195 // Video memory + Legacy BIOS region
196 //
197 AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
198
199 if (!mXen) {
200 UINT32 TopOfLowRam;
201 TopOfLowRam = GetSystemMemorySizeBelow4gb ();
202
203 //
204 // address purpose size
205 // ------------ -------- -------------------------
206 // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g)
207 // 0xFC000000 gap 44 MB
208 // 0xFEC00000 IO-APIC 4 KB
209 // 0xFEC01000 gap 1020 KB
210 // 0xFED00000 HPET 1 KB
211 // 0xFED00400 gap 1023 KB
212 // 0xFEE00000 LAPIC 1 MB
213 //
214 AddIoMemoryRangeHob (TopOfLowRam < BASE_2GB ?
215 BASE_2GB : TopOfLowRam, 0xFC000000);
216 AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
217 AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
218 AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);
219 }
220 }
221
222
223 VOID
224 MiscInitialization (
225 VOID
226 )
227 {
228 //
229 // Disable A20 Mask
230 //
231 IoOr8 (0x92, BIT1);
232
233 //
234 // Build the CPU hob with 36-bit addressing and 16-bits of IO space.
235 //
236 BuildCpuHob (36, 16);
237
238 //
239 // If PMREGMISC/PMIOSE is set, assume the ACPI PMBA has been configured (for
240 // example by Xen) and skip the setup here. This matches the logic in
241 // AcpiTimerLibConstructor ().
242 //
243 if ((PciRead8 (PCI_LIB_ADDRESS (0, 1, 3, 0x80)) & 0x01) == 0) {
244 //
245 // The PEI phase should be exited with fully accessibe PIIX4 IO space:
246 // 1. set PMBA
247 //
248 PciAndThenOr32 (
249 PCI_LIB_ADDRESS (0, 1, 3, 0x40),
250 (UINT32) ~0xFFC0,
251 PcdGet16 (PcdAcpiPmBaseAddress)
252 );
253
254 //
255 // 2. set PCICMD/IOSE
256 //
257 PciOr8 (
258 PCI_LIB_ADDRESS (0, 1, 3, PCI_COMMAND_OFFSET),
259 EFI_PCI_COMMAND_IO_SPACE
260 );
261
262 //
263 // 3. set PMREGMISC/PMIOSE
264 //
265 PciOr8 (PCI_LIB_ADDRESS (0, 1, 3, 0x80), 0x01);
266 }
267 }
268
269
270 VOID
271 BootModeInitialization (
272 VOID
273 )
274 {
275 EFI_STATUS Status;
276
277 if (CmosRead8 (0xF) == 0xFE) {
278 mBootMode = BOOT_ON_S3_RESUME;
279 }
280
281 Status = PeiServicesSetBootMode (mBootMode);
282 ASSERT_EFI_ERROR (Status);
283
284 Status = PeiServicesInstallPpi (mPpiBootMode);
285 ASSERT_EFI_ERROR (Status);
286 }
287
288
289 VOID
290 ReserveEmuVariableNvStore (
291 )
292 {
293 EFI_PHYSICAL_ADDRESS VariableStore;
294
295 //
296 // Allocate storage for NV variables early on so it will be
297 // at a consistent address. Since VM memory is preserved
298 // across reboots, this allows the NV variable storage to survive
299 // a VM reboot.
300 //
301 VariableStore =
302 (EFI_PHYSICAL_ADDRESS)(UINTN)
303 AllocateAlignedRuntimePages (
304 EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)),
305 PcdGet32 (PcdFlashNvStorageFtwSpareSize)
306 );
307 DEBUG ((EFI_D_INFO,
308 "Reserved variable store memory: 0x%lX; size: %dkb\n",
309 VariableStore,
310 (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
311 ));
312 PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore);
313 }
314
315
316 VOID
317 DebugDumpCmos (
318 VOID
319 )
320 {
321 UINTN Loop;
322
323 DEBUG ((EFI_D_INFO, "CMOS:\n"));
324
325 for (Loop = 0; Loop < 0x80; Loop++) {
326 if ((Loop % 0x10) == 0) {
327 DEBUG ((EFI_D_INFO, "%02x:", Loop));
328 }
329 DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
330 if ((Loop % 0x10) == 0xf) {
331 DEBUG ((EFI_D_INFO, "\n"));
332 }
333 }
334 }
335
336
337 /**
338 Perform Platform PEI initialization.
339
340 @param FileHandle Handle of the file being invoked.
341 @param PeiServices Describes the list of possible PEI Services.
342
343 @return EFI_SUCCESS The PEIM initialized successfully.
344
345 **/
346 EFI_STATUS
347 EFIAPI
348 InitializePlatform (
349 IN EFI_PEI_FILE_HANDLE FileHandle,
350 IN CONST EFI_PEI_SERVICES **PeiServices
351 )
352 {
353 DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
354
355 DebugDumpCmos ();
356
357 XenDetect ();
358
359 BootModeInitialization ();
360
361 PublishPeiMemory ();
362
363 InitializeRamRegions ();
364
365 if (mXen) {
366 DEBUG ((EFI_D_INFO, "Xen was detected\n"));
367 InitializeXen ();
368 }
369
370 ReserveEmuVariableNvStore ();
371
372 PeiFvInitialization ();
373
374 MemMapInitialization ();
375
376 MiscInitialization ();
377
378 return EFI_SUCCESS;
379 }