]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/DxeIpl/HobGeneration.c
Patch to remove STATIC modifier. This is on longer recommended by EFI Framework codin...
[mirror_edk2.git] / DuetPkg / DxeIpl / HobGeneration.c
CommitLineData
18b84857 1/** @file\r
ca162103 2\r
3Copyright (c) 2006 - 2007, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 HobGeneration.c\r
14\r
15Abstract:\r
16\r
17Revision History:\r
18\r
18b84857 19**/\r
ca162103 20#include "DxeIpl.h"\r
21#include "HobGeneration.h"\r
22#include "PpisNeededByDxeCore.h"\r
23#include "FlashLayout.h"\r
24#include "Debug.h"\r
25\r
26#define EFI_DXE_FILE_GUID \\r
27 { 0xb1644c1a, 0xc16a, 0x4c5b, 0x88, 0xde, 0xea, 0xfb, 0xa9, 0x7e, 0x74, 0xd8 }\r
28\r
29#define CPUID_EXTENDED_ADD_SIZE 0x80000008\r
30\r
31HOB_TEMPLATE gHobTemplate = {\r
32 { // Phit\r
33 { // Header\r
34 EFI_HOB_TYPE_HANDOFF, // HobType\r
35 sizeof (EFI_HOB_HANDOFF_INFO_TABLE), // HobLength\r
36 0 // Reserved\r
37 },\r
38 EFI_HOB_HANDOFF_TABLE_VERSION, // Version\r
39 BOOT_WITH_FULL_CONFIGURATION, // BootMode\r
40 0, // EfiMemoryTop\r
41 0, // EfiMemoryBottom\r
42 0, // EfiFreeMemoryTop\r
43 0, // EfiFreeMemoryBottom\r
44 0 // EfiEndOfHobList\r
45 }, \r
46 { // Bfv\r
47 {\r
48 EFI_HOB_TYPE_FV, // HobType\r
49 sizeof (EFI_HOB_FIRMWARE_VOLUME), // HobLength\r
50 0 // Reserved\r
51 },\r
52 0, // BaseAddress\r
53 0 // Length\r
54 },\r
55 { // BfvResource\r
56 {\r
57 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType\r
58 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength\r
59 0 // Reserved\r
60 },\r
61 {\r
62 0 // Owner Guid\r
63 },\r
64 EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType\r
65 (EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
66 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
67 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
68 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute\r
69 0, // PhysicalStart\r
70 0 // ResourceLength\r
71 },\r
72 { // Cpu\r
73 { // Header\r
74 EFI_HOB_TYPE_CPU, // HobType\r
75 sizeof (EFI_HOB_CPU), // HobLength\r
76 0 // Reserved\r
77 },\r
78 52, // SizeOfMemorySpace - Architecture Max\r
79 16, // SizeOfIoSpace,\r
80 {\r
81 0, 0, 0, 0, 0, 0 // Reserved[6]\r
82 }\r
83 },\r
84 { // Stack HOB\r
85 { // header\r
86 EFI_HOB_TYPE_MEMORY_ALLOCATION, // Hob type\r
87 sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK), // Hob size\r
88 0 // reserved\r
89 },\r
90 {\r
91 EFI_HOB_MEMORY_ALLOC_STACK_GUID,\r
92 0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress;\r
93 0x0, // UINT64 MemoryLength;\r
94 EfiBootServicesData, // EFI_MEMORY_TYPE MemoryType; \r
95 0, 0, 0, 0 // Reserved Reserved[4]; \r
96 }\r
97 },\r
98 { // MemoryAllocation for HOB's & Images\r
99 {\r
100 EFI_HOB_TYPE_MEMORY_ALLOCATION, // HobType\r
101 sizeof (EFI_HOB_MEMORY_ALLOCATION), // HobLength\r
102 0 // Reserved\r
103 },\r
104 {\r
105 {\r
106 0, //EFI_HOB_MEMORY_ALLOC_MODULE_GUID // Name\r
107 },\r
108 0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress;\r
109 0x0, // UINT64 MemoryLength;\r
110 EfiBootServicesData, // EFI_MEMORY_TYPE MemoryType; \r
111 {\r
112 0, 0, 0, 0 // Reserved Reserved[4]; \r
113 }\r
114 }\r
115 },\r
116 { // MemoryFreeUnder1MB for unused memory that DXE core will claim\r
117 {\r
118 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType\r
119 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength\r
120 0 // Reserved\r
121 },\r
122 {\r
123 0 // Owner Guid\r
124 },\r
125 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType\r
126 (EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
127 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
128 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
129 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | \r
130 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | \r
131 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | \r
132 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), \r
133 0x0, // PhysicalStart\r
134 0 // ResourceLength\r
135 },\r
136 { // MemoryFreeAbove1MB for unused memory that DXE core will claim\r
137 {\r
138 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType\r
139 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength\r
140 0 // Reserved\r
141 },\r
142 {\r
143 0 // Owner Guid\r
144 },\r
145 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType\r
146 (EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
147 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
148 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
149 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | \r
150 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | \r
151 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | \r
152 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), \r
153 0x0, // PhysicalStart\r
154 0 // ResourceLength\r
155 },\r
156 { // MemoryFreeAbove4GB for unused memory that DXE core will claim\r
157 {\r
158 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType\r
159 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength\r
160 0 // Reserved\r
161 },\r
162 {\r
163 0 // Owner Guid\r
164 },\r
165 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType\r
166 (EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
167 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
168 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | \r
169 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | \r
170 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | \r
171 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), \r
172 0x0, // PhysicalStart\r
173 0 // ResourceLength\r
174 },\r
175 { // Memory Allocation Module for DxeCore\r
176 { // header\r
177 EFI_HOB_TYPE_MEMORY_ALLOCATION, // Hob type\r
178 sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE), // Hob size\r
179 0 // reserved\r
180 },\r
181 {\r
182 EFI_HOB_MEMORY_ALLOC_MODULE_GUID,\r
183 0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress;\r
184 0x0, // UINT64 MemoryLength;\r
185 EfiBootServicesCode, // EFI_MEMORY_TYPE MemoryType; \r
186 {\r
187 0, 0, 0, 0 // UINT8 Reserved[4]; \r
188 },\r
189 },\r
190 EFI_DXE_FILE_GUID,\r
191 0x0 // EFI_PHYSICAL_ADDRESS of EntryPoint;\r
192 },\r
193 { // Memory Map Hints to reduce fragmentation in the memory map\r
194 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
195 sizeof (MEMORY_TYPE_INFORMATION_HOB), // Hob size\r
196 0, // reserved\r
197 EFI_MEMORY_TYPE_INFORMATION_GUID,\r
198 {\r
199 {\r
200 EfiACPIReclaimMemory,\r
201 0x80\r
202 }, // 0x80 pages = 512k for ASL\r
203 {\r
204 EfiACPIMemoryNVS,\r
205 0x100\r
206 }, // 0x100 pages = 1024k for S3, SMM, etc\r
207 {\r
208 EfiReservedMemoryType,\r
209 0x04\r
210 }, // 16k for BIOS Reserved\r
211 {\r
212 EfiRuntimeServicesData,\r
213 0x100\r
214 },\r
215 {\r
216 EfiRuntimeServicesCode,\r
217 0x100\r
218 },\r
219 {\r
220 EfiBootServicesCode,\r
221 0x200\r
222 },\r
223 {\r
224 EfiBootServicesData,\r
225 0x200\r
226 },\r
227 {\r
228 EfiLoaderCode,\r
229 0x100\r
230 },\r
231 {\r
232 EfiLoaderData,\r
233 0x100\r
234 },\r
235 {\r
236 EfiMaxMemoryType,\r
237 0\r
238 }\r
239 }\r
240 },\r
241 { // Pointer to ACPI Table\r
242 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
243 sizeof (TABLE_HOB), // Hob size\r
244 0, // reserved\r
245 EFI_ACPI_TABLE_GUID,\r
246 0\r
247 },\r
248 { // Pointer to ACPI20 Table\r
249 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
250 sizeof (TABLE_HOB), // Hob size\r
251 0, // reserved\r
252 EFI_ACPI_20_TABLE_GUID,\r
253 0\r
254 },\r
255 { // Pointer to SMBIOS Table\r
256 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
257 sizeof (TABLE_HOB), // Hob size\r
258 0, // reserved\r
259 EFI_SMBIOS_TABLE_GUID,\r
260 0\r
261 },\r
262 { // Pointer to MPS Table\r
263 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
264 sizeof (TABLE_HOB), // Hob size\r
265 0, // reserved\r
266 EFI_MPS_TABLE_GUID,\r
267 0\r
268 },\r
269 /**\r
270 { // Pointer to FlushInstructionCache\r
271 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
272 sizeof (PROTOCOL_HOB), // Hob size\r
273 0, // reserved\r
274 EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID,\r
275 NULL\r
276 },\r
277 { // Pointer to TransferControl\r
278 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
279 sizeof (PROTOCOL_HOB), // Hob size\r
280 0, // reserved\r
281 EFI_PEI_TRANSFER_CONTROL_GUID,\r
282 NULL\r
283 },\r
284 { // Pointer to PeCoffLoader\r
285 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
286 sizeof (PROTOCOL_HOB), // Hob size\r
287 0, // reserved\r
288 EFI_PEI_PE_COFF_LOADER_GUID,\r
289 NULL\r
290 },\r
291 { // Pointer to EfiDecompress\r
292 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
293 sizeof (PROTOCOL_HOB), // Hob size\r
294 0, // reserved\r
295 EFI_DECOMPRESS_PROTOCOL_GUID,\r
296 NULL\r
297 },\r
298 { // Pointer to TianoDecompress\r
299 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
300 sizeof (PROTOCOL_HOB), // Hob size\r
301 0, // reserved\r
302 EFI_TIANO_DECOMPRESS_PROTOCOL_GUID,\r
303 NULL\r
304 },\r
305 **/\r
306 { // Pointer to ReportStatusCode\r
307 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
308 sizeof (PROTOCOL_HOB), // Hob size\r
309 0, // reserved\r
310 EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID,\r
311 NULL\r
312 },\r
313 { // EFILDR Memory Descriptor\r
314 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
315 sizeof (MEMORY_DESC_HOB), // Hob size\r
316 0, // reserved\r
317 EFI_LDR_MEMORY_DESCRIPTOR_GUID,\r
318 0,\r
319 NULL\r
320 },\r
321 { // Pci Express Base Address Hob\r
322 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
323 sizeof (PCI_EXPRESS_BASE_HOB), // Hob size\r
324 0, // reserved\r
325 EFI_PCI_EXPRESS_BASE_ADDRESS_GUID,\r
326 {\r
327 0,\r
328 0,\r
329 0,\r
330 }\r
331 },\r
332 { // Acpi Description Hob\r
333 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
334 sizeof (ACPI_DESCRIPTION_HOB), // Hob size\r
335 0, // reserved\r
336 EFI_ACPI_DESCRIPTION_GUID,\r
337 {\r
338 0,\r
339 }\r
340 },\r
341 { // NV Storage FV Resource\r
342 {\r
343 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType\r
344 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength\r
345 0 // Reserved\r
346 },\r
347 {\r
348 0 // Owner Guid\r
349 },\r
350 EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType\r
351 (EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
352 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
353 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
354 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute\r
355 0, // PhysicalStart (Fixed later)\r
356 NV_STORAGE_FVB_SIZE // ResourceLength\r
357 },\r
358 { // FVB holding NV Storage\r
359 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
360 sizeof (FVB_HOB),\r
361 0,\r
362 EFI_FLASH_MAP_HOB_GUID,\r
363 {\r
364 0, 0, 0, // Reserved[3]\r
365 EFI_FLASH_AREA_GUID_DEFINED, // AreaType\r
366 EFI_SYSTEM_NV_DATA_HOB_GUID, // AreaTypeGuid\r
367 1,\r
368 {\r
369 EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes\r
370 0, // SubAreaData.Reserved\r
371 0, // SubAreaData.Base (Fixed later)\r
372 NV_STORAGE_FVB_SIZE, // SubAreaData.Length\r
373 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem\r
374 }, \r
375 0, // VolumeSignature (Fixed later)\r
376 NV_STORAGE_FILE_PATH, // Mapped file without padding\r
377 // TotalFVBSize = FileSize + PaddingSize = multiple of BLOCK_SIZE\r
378 NV_STORAGE_SIZE + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH,\r
379 // ActuralSize\r
380 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH\r
381 }\r
382 },\r
383 { // NV Storage Hob\r
384 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
385 sizeof (FVB_HOB), // Hob size\r
386 0, // reserved\r
387 EFI_FLASH_MAP_HOB_GUID,\r
388 {\r
389 0, 0, 0, // Reserved[3]\r
390 EFI_FLASH_AREA_EFI_VARIABLES, // AreaType\r
391 { 0 }, // AreaTypeGuid\r
392 1,\r
393 {\r
394 EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes\r
395 0, // SubAreaData.Reserved\r
396 0, // SubAreaData.Base (Fixed later)\r
397 NV_STORAGE_SIZE, // SubAreaData.Length\r
398 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem\r
399 }, \r
400 0,\r
401 NV_STORAGE_FILE_PATH,\r
402 NV_STORAGE_SIZE,\r
403 0\r
404 }\r
405 },\r
406 { // FVB holding FTW spaces including Working & Spare space\r
407 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
408 sizeof (FVB_HOB),\r
409 0,\r
410 EFI_FLASH_MAP_HOB_GUID,\r
411 {\r
412 0, 0, 0, // Reserved[3]\r
413 EFI_FLASH_AREA_GUID_DEFINED, // AreaType\r
414 EFI_SYSTEM_NV_DATA_HOB_GUID, // AreaTypeGuid\r
415 1,\r
416 {\r
417 EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes\r
418 0, // SubAreaData.Reserved\r
419 0, // SubAreaData.Base (Fixed later)\r
420 NV_FTW_FVB_SIZE, // SubAreaData.Length\r
421 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem\r
422 }, \r
423 0,\r
424 L"", // Empty String indicates using memory\r
425 0,\r
426 0\r
427 }\r
428 },\r
429 { // NV Ftw working Hob\r
430 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
431 sizeof (FVB_HOB), // Hob size\r
432 0, // reserved\r
433 EFI_FLASH_MAP_HOB_GUID,\r
434 {\r
435 0, 0, 0, // Reserved[3]\r
436 EFI_FLASH_AREA_FTW_STATE, // AreaType\r
437 { 0 }, // AreaTypeGuid\r
438 1,\r
439 {\r
440 EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes\r
441 0, // SubAreaData.Reserved\r
442 0, // SubAreaData.Base (Fixed later)\r
443 NV_FTW_WORKING_SIZE, // SubAreaData.Length\r
444 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem\r
445 }, \r
446 0, // VolumeSignature\r
447 L"",\r
448 0,\r
449 0\r
450 }\r
451 },\r
452 { // NV Ftw spare Hob\r
453 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type\r
454 sizeof (FVB_HOB), // Hob size\r
455 0, // reserved\r
456 EFI_FLASH_MAP_HOB_GUID,\r
457 {\r
458 0, 0, 0, // Reserved[3]\r
459 EFI_FLASH_AREA_FTW_BACKUP, // AreaType\r
460 { 0 }, // AreaTypeGuid\r
461 1,\r
462 {\r
463 EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes\r
464 0, // SubAreaData.Reserved\r
465 0, // SubAreaData.Base (Fixed later)\r
466 NV_FTW_SPARE_SIZE, // SubAreaData.Length\r
467 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem\r
468 }, \r
469 0,\r
470 L"",\r
471 0,\r
472 0\r
473 }\r
474 },\r
475 { // EndOfHobList\r
476 EFI_HOB_TYPE_END_OF_HOB_LIST, // HobType\r
477 sizeof (EFI_HOB_GENERIC_HEADER), // HobLength\r
478 0 // Reserved\r
479 }\r
480};\r
481\r
482HOB_TEMPLATE *gHob = &gHobTemplate;\r
483\r
484VOID *\r
485PrepareHobMemory (\r
486 IN UINTN NumberOfMemoryMapEntries,\r
487 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor\r
488 )\r
489/*++\r
490Description:\r
491 Update the Hob filling MemoryFreeUnder1MB, MemoryAbove1MB, MemoryAbove4GB\r
492\r
493Arguments:\r
494 NumberOfMemoryMapEntries - Count of Memory Descriptors\r
495 EfiMemoryDescriptor - Point to the buffer containing NumberOfMemoryMapEntries Memory Descriptors\r
496\r
497Return:\r
498 VOID * : The end address of MemoryAbove1MB (or the top free memory under 4GB)\r
499--*/\r
500{\r
501 UINTN Index;\r
502\r
503 //\r
504 // Prepare Low Memory\r
505 // 0x18 pages is 72 KB.\r
506 //\r
507 gHob->MemoryFreeUnder1MB.ResourceLength = EFI_MEMORY_BELOW_1MB_END - EFI_MEMORY_BELOW_1MB_START;\r
508 gHob->MemoryFreeUnder1MB.PhysicalStart = EFI_MEMORY_BELOW_1MB_START;\r
509\r
510 //\r
511 // Prepare High Memory\r
512 // Assume Memory Map is ordered from low to high\r
513 //\r
514 gHob->MemoryAbove1MB.PhysicalStart = 0;\r
515 gHob->MemoryAbove1MB.ResourceLength = 0;\r
516 gHob->MemoryAbove4GB.PhysicalStart = 0;\r
517 gHob->MemoryAbove4GB.ResourceLength = 0;\r
518\r
519 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {\r
520 //\r
521 // Skip regions below 1MB\r
522 //\r
523 if (EfiMemoryDescriptor[Index].PhysicalStart < 0x100000) {\r
524 continue;\r
525 }\r
526 //\r
527 // Process regions above 1MB\r
528 //\r
529 if (EfiMemoryDescriptor[Index].PhysicalStart >= 0x100000) {\r
530 if (EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) {\r
531 if (gHob->MemoryAbove1MB.PhysicalStart == 0) {\r
532 gHob->MemoryAbove1MB.PhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;\r
533 gHob->MemoryAbove1MB.ResourceLength = LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);\r
534 } else if (gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength == EfiMemoryDescriptor[Index].PhysicalStart) {\r
535 gHob->MemoryAbove1MB.ResourceLength += LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);\r
536 }\r
537 }\r
538 if ((EfiMemoryDescriptor[Index].Type == EfiReservedMemoryType) ||\r
539 (EfiMemoryDescriptor[Index].Type >= EfiACPIReclaimMemory) ) {\r
540 continue;\r
541 }\r
542 if ((EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesCode) ||\r
543 (EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesData)) {\r
544 break;\r
545 }\r
546 }\r
547 //\r
548 // Process region above 4GB\r
549 //\r
f40bbc08 550 if (EfiMemoryDescriptor[Index].PhysicalStart >= 0x100000000LL) {\r
ca162103 551 if (EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) {\r
552 if (gHob->MemoryAbove4GB.PhysicalStart == 0) {\r
553 gHob->MemoryAbove4GB.PhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;\r
554 gHob->MemoryAbove4GB.ResourceLength = LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);\r
555 }\r
556 if (gHob->MemoryAbove4GB.PhysicalStart + gHob->MemoryAbove4GB.ResourceLength == \r
557 EfiMemoryDescriptor[Index].PhysicalStart) {\r
558 gHob->MemoryAbove4GB.ResourceLength += LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);\r
559 }\r
560 }\r
561 }\r
562 }\r
563\r
564 if (gHob->MemoryAbove4GB.ResourceLength == 0) {\r
565 //\r
566 // If there is no memory above 4GB then change the resource descriptor HOB\r
567 // into another type. I'm doing this as it's unclear if a resource\r
568 // descriptor HOB of length zero is valid. Spec does not say it's illegal,\r
569 // but code in EDK does not seem to handle this case.\r
570 //\r
571 gHob->MemoryAbove4GB.Header.HobType = EFI_HOB_TYPE_UNUSED;\r
572 }\r
573\r
574 return (VOID *)(UINTN)(gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength);\r
575}\r
576\r
577VOID *\r
578PrepareHobStack (\r
579 IN VOID *StackTop\r
580 )\r
581{\r
582 gHob->Stack.AllocDescriptor.MemoryLength = EFI_MEMORY_STACK_PAGE_NUM * EFI_PAGE_SIZE;\r
583 gHob->Stack.AllocDescriptor.MemoryBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)StackTop - gHob->Stack.AllocDescriptor.MemoryLength;\r
584\r
585 return (VOID *)(UINTN)gHob->Stack.AllocDescriptor.MemoryBaseAddress;\r
586}\r
587\r
588VOID *\r
589PrepareHobMemoryDescriptor (\r
590 VOID *MemoryDescriptorTop,\r
591 UINTN MemDescCount,\r
592 EFI_MEMORY_DESCRIPTOR *MemDesc\r
593 )\r
594{\r
595 gHob->MemoryDescriptor.MemDescCount = MemDescCount;\r
596 gHob->MemoryDescriptor.MemDesc = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryDescriptorTop - MemDescCount * sizeof(EFI_MEMORY_DESCRIPTOR));\r
597 //\r
598 // Make MemoryDescriptor.MemDesc page aligned\r
599 //\r
600 gHob->MemoryDescriptor.MemDesc = (EFI_MEMORY_DESCRIPTOR *)((UINTN) gHob->MemoryDescriptor.MemDesc & ~EFI_PAGE_MASK);\r
601\r
602 CopyMem (gHob->MemoryDescriptor.MemDesc, MemDesc, MemDescCount * sizeof(EFI_MEMORY_DESCRIPTOR));\r
603\r
604 return gHob->MemoryDescriptor.MemDesc;\r
605}\r
606\r
607VOID\r
608PrepareHobBfv (\r
609 VOID *Bfv,\r
610 UINTN BfvLength\r
611 )\r
612{\r
613 UINTN BfvLengthPageSize;\r
614\r
615 //\r
616 // Calculate BFV location at top of the memory region.\r
617 // This is like a RAM Disk. Align to page boundry.\r
618 //\r
619 BfvLengthPageSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (BfvLength));\r
620 \r
621 gHob->Bfv.BaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Bfv;\r
622 gHob->Bfv.Length = BfvLength;\r
623\r
624 //\r
625 // Resource descriptor for the FV\r
626 //\r
627 gHob->BfvResource.PhysicalStart = gHob->Bfv.BaseAddress;\r
628 gHob->BfvResource.ResourceLength = gHob->Bfv.Length;\r
629}\r
630\r
631VOID\r
632PrepareHobDxeCore (\r
633 VOID *DxeCoreEntryPoint,\r
634 EFI_PHYSICAL_ADDRESS DxeCoreImageBase,\r
635 UINT64 DxeCoreLength\r
636 )\r
637{\r
638 gHob->DxeCore.MemoryAllocationHeader.MemoryBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)DxeCoreImageBase;\r
639 gHob->DxeCore.MemoryAllocationHeader.MemoryLength = DxeCoreLength;\r
640 gHob->DxeCore.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)DxeCoreEntryPoint;\r
641}\r
642\r
643VOID *\r
644PrepareHobNvStorage (\r
645 VOID *NvStorageTop\r
646 )\r
647/*\r
648 Initialize Block-Aligned Firmware Block.\r
649\r
650 Variable:\r
651 +-------------------+\r
652 | FV_Header |\r
653 +-------------------+\r
654 | |\r
655 |VAR_STORAGE(0x4000)|\r
656 | |\r
657 +-------------------+\r
658 FTW:\r
659 +-------------------+\r
660 | FV_Header |\r
661 +-------------------+\r
662 | |\r
663 | Working(0x2000) |\r
664 | |\r
665 +-------------------+\r
666 | |\r
667 | Spare(0x10000) |\r
668 | |\r
669 +-------------------+\r
670*/\r
671{\r
e56dd2ce 672 STATIC VARIABLE_STORE_HEADER VarStoreHeader = {\r
ca162103 673 VARIABLE_STORE_SIGNATURE,\r
674 0xffffffff, // will be fixed in Variable driver\r
675 VARIABLE_STORE_FORMATTED,\r
676 VARIABLE_STORE_HEALTHY,\r
677 0,\r
678 0\r
679 };\r
680 \r
e56dd2ce 681 STATIC EFI_FIRMWARE_VOLUME_HEADER NvStorageFvbHeader = {\r
ca162103 682 {\r
683 0,\r
684 }, // ZeroVector[16]\r
685 EFI_SYSTEM_NV_DATA_FV_GUID,\r
686 NV_STORAGE_FVB_SIZE,\r
687 EFI_FVH_SIGNATURE,\r
688 EFI_FVB_READ_ENABLED_CAP |\r
689 EFI_FVB_READ_STATUS |\r
690 EFI_FVB_WRITE_ENABLED_CAP |\r
691 EFI_FVB_WRITE_STATUS |\r
692 EFI_FVB_ERASE_POLARITY,\r
693 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH,\r
694 0, // CheckSum\r
695 0, // ExtHeaderOffset\r
696 {\r
697 0,\r
698 }, // Reserved[1]\r
699 1, // Revision\r
700 {\r
701 {\r
702 NV_STORAGE_FVB_BLOCK_NUM,\r
703 FV_BLOCK_SIZE,\r
704 }\r
705 }\r
706 };\r
707\r
e56dd2ce 708 STATIC EFI_FV_BLOCK_MAP_ENTRY BlockMapEntryEnd = {0, 0};\r
ca162103 709\r
710 EFI_PHYSICAL_ADDRESS StorageFvbBase;\r
711 EFI_PHYSICAL_ADDRESS FtwFvbBase;\r
712\r
713 UINT16 *Ptr;\r
714 UINT16 Checksum;\r
715\r
716\r
717 //\r
718 // Use first 16-byte Reset Vector of FVB to store extra information\r
719 // UINT32 Offset 0 stores the volume signature\r
720 // UINT8 Offset 4 : should init the Variable Store Header if non-zero\r
721 //\r
722 gHob->NvStorageFvb.FvbInfo.VolumeId = *(UINT32 *) (UINTN) (NV_STORAGE_STATE);\r
723 gHob->NvStorage. FvbInfo.VolumeId = *(UINT32 *) (UINTN) (NV_STORAGE_STATE);\r
724\r
725 //\r
726 // *(NV_STORAGE_STATE + 4):\r
727 // 2 - Size error\r
728 // 1 - File not exist\r
729 // 0 - File exist with correct size\r
730 //\r
731 if (*(UINT8 *) (UINTN) (NV_STORAGE_STATE + 4) == 2) {\r
732 ClearScreen ();\r
733 PrintString ("Error: Size of Efivar.bin should be 16k!\n");\r
734 CpuDeadLoop();\r
735 }\r
736 \r
737 if (*(UINT8 *) (UINTN) (NV_STORAGE_STATE + 4) != 0) {\r
738 //\r
739 // Efivar.bin doesn't exist\r
740 // 1. Init variable storage header to valid header\r
741 //\r
742 CopyMem (\r
743 (VOID *) (UINTN) NV_STORAGE_START,\r
744 &VarStoreHeader,\r
745 sizeof (VARIABLE_STORE_HEADER)\r
746 );\r
747 //\r
748 // 2. set all bits in variable storage body to 1\r
749 //\r
750 SetMem (\r
751 (VOID *) (UINTN) (NV_STORAGE_START + sizeof (VARIABLE_STORE_HEADER)),\r
752 NV_STORAGE_SIZE - sizeof (VARIABLE_STORE_HEADER),\r
753 0xff\r
754 );\r
755 }\r
756\r
757 //\r
758 // Relocate variable storage\r
759 // \r
760 // 1. Init FVB Header to valid header: First 0x48 bytes\r
761 // In real platform, these fields are fixed by tools\r
762 //\r
763 //\r
764 Checksum = 0;\r
765 for (\r
766 Ptr = (UINT16 *) &NvStorageFvbHeader; \r
767 Ptr < (UINT16 *) ((UINTN) (UINT8 *) &NvStorageFvbHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
768 ++Ptr\r
769 ) {\r
770 Checksum = (UINT16) (Checksum + (*Ptr));\r
771 }\r
772 NvStorageFvbHeader.Checksum = (UINT16) (0x10000 - Checksum);\r
773 StorageFvbBase = (EFI_PHYSICAL_ADDRESS)(((UINTN)NvStorageTop - NV_STORAGE_FVB_SIZE - NV_FTW_FVB_SIZE) & ~EFI_PAGE_MASK);\r
774 CopyMem ((VOID *) (UINTN) StorageFvbBase, &NvStorageFvbHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
775 CopyMem (\r
776 (VOID *) (UINTN) (StorageFvbBase + sizeof (EFI_FIRMWARE_VOLUME_HEADER)),\r
777 &BlockMapEntryEnd,\r
778 sizeof (EFI_FV_BLOCK_MAP_ENTRY)\r
779 );\r
780 \r
781 //\r
782 // 2. Relocate variable data\r
783 //\r
784 CopyMem (\r
785 (VOID *) (UINTN) (StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH),\r
786 (VOID *) (UINTN) NV_STORAGE_START,\r
787 NV_STORAGE_SIZE\r
788 );\r
789\r
790 //\r
791 // 3. Set the remaining memory to 0xff\r
792 //\r
793 SetMem (\r
794 (VOID *) (UINTN) (StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH + NV_STORAGE_SIZE),\r
795 NV_STORAGE_FVB_SIZE - NV_STORAGE_SIZE - EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH,\r
796 0xff\r
797 );\r
798\r
799 //\r
800 // Create the FVB holding NV Storage in memory\r
801 //\r
802 gHob->NvStorageFvResource.PhysicalStart =\r
803 gHob->NvStorageFvb.FvbInfo.Entries[0].Base = StorageFvbBase;\r
804 //\r
805 // Create the NV Storage Hob\r
806 //\r
807 gHob->NvStorage.FvbInfo.Entries[0].Base = StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH;\r
808\r
809 //\r
810 // Create the FVB holding FTW spaces\r
811 //\r
812 FtwFvbBase = (EFI_PHYSICAL_ADDRESS)((UINTN) StorageFvbBase + NV_STORAGE_FVB_SIZE);\r
813 gHob->NvFtwFvb.FvbInfo.Entries[0].Base = FtwFvbBase;\r
814 //\r
815 // Put FTW Working in front\r
816 //\r
817 gHob->NvFtwWorking.FvbInfo.Entries[0].Base = FtwFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH;\r
818\r
819 //\r
820 // Put FTW Spare area after FTW Working area\r
821 //\r
822 gHob->NvFtwSpare.FvbInfo.Entries[0].Base = \r
823 (EFI_PHYSICAL_ADDRESS)((UINTN) FtwFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH + NV_FTW_WORKING_SIZE);\r
824 \r
825 return (VOID *)(UINTN)StorageFvbBase;\r
826}\r
827\r
828VOID\r
829PrepareHobPhit (\r
830 VOID *MemoryTop,\r
831 VOID *FreeMemoryTop\r
832 )\r
833{\r
834 gHob->Phit.EfiMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryTop;\r
835 gHob->Phit.EfiMemoryBottom = gHob->Phit.EfiMemoryTop - CONSUMED_MEMORY;\r
836 gHob->Phit.EfiFreeMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)FreeMemoryTop;\r
837 gHob->Phit.EfiFreeMemoryBottom = gHob->Phit.EfiMemoryBottom + sizeof(HOB_TEMPLATE);\r
838\r
839 CopyMem ((VOID *)(UINTN)gHob->Phit.EfiMemoryBottom, gHob, sizeof(HOB_TEMPLATE));\r
840 gHob = (HOB_TEMPLATE *)(UINTN)gHob->Phit.EfiMemoryBottom;\r
841\r
842 gHob->Phit.EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)&gHob->EndOfHobList;\r
843}\r
844\r
845VOID\r
846PrepareHobCpu (\r
847 VOID\r
848 )\r
849{\r
850 EFI_CPUID_REGISTER Reg;\r
851 UINT8 CpuMemoryAddrBitNumber;\r
852\r
853 //\r
854 // Create a CPU hand-off information\r
855 //\r
856 CpuMemoryAddrBitNumber = 36;\r
857 AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &Reg.RegEax, &Reg.RegEbx, &Reg.RegEcx, &Reg.RegEdx);\r
858\r
859 if (Reg.RegEax >= CPUID_EXTENDED_ADD_SIZE) {\r
860 AsmCpuid (CPUID_EXTENDED_ADD_SIZE, &Reg.RegEax, &Reg.RegEbx, &Reg.RegEcx, &Reg.RegEdx);\r
861 CpuMemoryAddrBitNumber = (UINT8)(UINTN)(Reg.RegEax & 0xFF);\r
862 }\r
863 \r
864 gHob->Cpu.SizeOfMemorySpace = CpuMemoryAddrBitNumber;\r
865}\r
866\r
867VOID\r
868CompleteHobGeneration (\r
869 VOID\r
870 )\r
871{\r
872 gHob->MemoryAllocation.AllocDescriptor.MemoryBaseAddress = gHob->Phit.EfiFreeMemoryTop;\r
873 //\r
874 // Reserve all the memory under Stack above FreeMemoryTop as allocated\r
875 //\r
876 gHob->MemoryAllocation.AllocDescriptor.MemoryLength = gHob->Stack.AllocDescriptor.MemoryBaseAddress - gHob->Phit.EfiFreeMemoryTop;\r
877\r
878 //\r
879 // adjust Above1MB ResourceLength\r
880 //\r
881 if (gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength > gHob->Phit.EfiMemoryTop) {\r
882 gHob->MemoryAbove1MB.ResourceLength = gHob->Phit.EfiMemoryTop - gHob->MemoryAbove1MB.PhysicalStart;\r
883 }\r
884}\r
885\r