Fix warnings generated by GCC.
[edk2.git] / DuetPkg / DxeIpl / HobGeneration.c
blob224d6a710e9a2fae3f18b266a8a9c56c6cf91965
1 /** @file
3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 Module Name:
13 HobGeneration.c
15 Abstract:
17 Revision History:
19 **/
20 #include "DxeIpl.h"
21 #include "HobGeneration.h"
22 #include "PpisNeededByDxeCore.h"
23 #include "FlashLayout.h"
24 #include "Debug.h"
26 #define EFI_DXE_FILE_GUID \
27 { 0xb1644c1a, 0xc16a, 0x4c5b, {0x88, 0xde, 0xea, 0xfb, 0xa9, 0x7e, 0x74, 0xd8 }}
29 #define CPUID_EXTENDED_ADD_SIZE 0x80000008
31 HOB_TEMPLATE gHobTemplate = {
32 { // Phit
33 { // Header
34 EFI_HOB_TYPE_HANDOFF, // HobType
35 sizeof (EFI_HOB_HANDOFF_INFO_TABLE), // HobLength
36 0 // Reserved
38 EFI_HOB_HANDOFF_TABLE_VERSION, // Version
39 BOOT_WITH_FULL_CONFIGURATION, // BootMode
40 0, // EfiMemoryTop
41 0, // EfiMemoryBottom
42 0, // EfiFreeMemoryTop
43 0, // EfiFreeMemoryBottom
44 0 // EfiEndOfHobList
45 },
46 { // Bfv
48 EFI_HOB_TYPE_FV, // HobType
49 sizeof (EFI_HOB_FIRMWARE_VOLUME), // HobLength
50 0 // Reserved
52 0, // BaseAddress
53 0 // Length
55 { // BfvResource
57 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
58 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
59 0 // Reserved
62 0 // Owner Guid
64 EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType
65 (EFI_RESOURCE_ATTRIBUTE_PRESENT |
66 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
67 EFI_RESOURCE_ATTRIBUTE_TESTED |
68 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute
69 0, // PhysicalStart
70 0 // ResourceLength
72 { // Cpu
73 { // Header
74 EFI_HOB_TYPE_CPU, // HobType
75 sizeof (EFI_HOB_CPU), // HobLength
76 0 // Reserved
78 52, // SizeOfMemorySpace - Architecture Max
79 16, // SizeOfIoSpace,
81 0, 0, 0, 0, 0, 0 // Reserved[6]
84 { // Stack HOB
85 { // header
86 EFI_HOB_TYPE_MEMORY_ALLOCATION, // Hob type
87 sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK), // Hob size
88 0 // reserved
91 EFI_HOB_MEMORY_ALLOC_STACK_GUID,
92 0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
93 0x0, // UINT64 MemoryLength;
94 EfiBootServicesData, // EFI_MEMORY_TYPE MemoryType;
95 {0, 0, 0, 0} // Reserved Reserved[4];
98 { // MemoryAllocation for HOB's & Images
100 EFI_HOB_TYPE_MEMORY_ALLOCATION, // HobType
101 sizeof (EFI_HOB_MEMORY_ALLOCATION), // HobLength
102 0 // Reserved
106 0, //EFI_HOB_MEMORY_ALLOC_MODULE_GUID // Name
108 0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
109 0x0, // UINT64 MemoryLength;
110 EfiBootServicesData, // EFI_MEMORY_TYPE MemoryType;
112 0, 0, 0, 0 // Reserved Reserved[4];
116 { // MemoryFreeUnder1MB for unused memory that DXE core will claim
118 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
119 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
120 0 // Reserved
123 0 // Owner Guid
125 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType
126 (EFI_RESOURCE_ATTRIBUTE_PRESENT |
127 EFI_RESOURCE_ATTRIBUTE_TESTED |
128 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
129 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
130 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
131 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
132 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE),
133 0x0, // PhysicalStart
134 0 // ResourceLength
136 { // MemoryFreeAbove1MB for unused memory that DXE core will claim
138 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
139 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
140 0 // Reserved
143 0 // Owner Guid
145 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType
146 (EFI_RESOURCE_ATTRIBUTE_PRESENT |
147 EFI_RESOURCE_ATTRIBUTE_TESTED |
148 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
149 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
150 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
151 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
152 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE),
153 0x0, // PhysicalStart
154 0 // ResourceLength
156 { // MemoryFreeAbove4GB for unused memory that DXE core will claim
158 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
159 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
160 0 // Reserved
163 0 // Owner Guid
165 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType
166 (EFI_RESOURCE_ATTRIBUTE_PRESENT |
167 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
168 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
169 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
170 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
171 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE),
172 0x0, // PhysicalStart
173 0 // ResourceLength
175 { // Memory Allocation Module for DxeCore
176 { // header
177 EFI_HOB_TYPE_MEMORY_ALLOCATION, // Hob type
178 sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE), // Hob size
179 0 // reserved
182 EFI_HOB_MEMORY_ALLOC_MODULE_GUID,
183 0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
184 0x0, // UINT64 MemoryLength;
185 EfiBootServicesCode, // EFI_MEMORY_TYPE MemoryType;
187 0, 0, 0, 0 // UINT8 Reserved[4];
190 EFI_DXE_FILE_GUID,
191 0x0 // EFI_PHYSICAL_ADDRESS of EntryPoint;
193 { // MemoryDxeCore
195 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
196 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
197 0 // Reserved
200 0 // Owner Guid
202 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType
203 (EFI_RESOURCE_ATTRIBUTE_PRESENT |
204 // EFI_RESOURCE_ATTRIBUTE_TESTED | // Do not mark as TESTED, or DxeCore will find it and use it before check Allocation
205 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
206 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
207 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
208 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
209 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE),
210 0x0, // PhysicalStart
211 0 // ResourceLength
213 { // Memory Map Hints to reduce fragmentation in the memory map
216 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
217 sizeof (MEMORY_TYPE_INFORMATION_HOB), // Hob size
218 0, // reserved
220 EFI_MEMORY_TYPE_INFORMATION_GUID
224 EfiACPIReclaimMemory,
225 0x80
226 }, // 0x80 pages = 512k for ASL
228 EfiACPIMemoryNVS,
229 0x100
230 }, // 0x100 pages = 1024k for S3, SMM, etc
232 EfiReservedMemoryType,
233 0x04
234 }, // 16k for BIOS Reserved
236 EfiRuntimeServicesData,
237 0x100
240 EfiRuntimeServicesCode,
241 0x100
244 EfiBootServicesCode,
245 0x200
248 EfiBootServicesData,
249 0x200
252 EfiLoaderCode,
253 0x100
256 EfiLoaderData,
257 0x100
260 EfiMaxMemoryType,
265 { // Pointer to ACPI Table
268 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
269 sizeof (TABLE_HOB), // Hob size
270 0 // reserved
272 EFI_ACPI_TABLE_GUID
276 { // Pointer to ACPI20 Table
279 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
280 sizeof (TABLE_HOB), // Hob size
281 0 // reserved
283 EFI_ACPI_20_TABLE_GUID
287 { // Pointer to SMBIOS Table
290 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
291 sizeof (TABLE_HOB), // Hob size
292 0 // reserved
294 SMBIOS_TABLE_GUID
298 { // Pointer to MPS Table
301 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
302 sizeof (TABLE_HOB), // Hob size
303 0, // reserved
305 EFI_MPS_TABLE_GUID
310 { // Pointer to FlushInstructionCache
311 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
312 sizeof (PROTOCOL_HOB), // Hob size
313 0, // reserved
314 EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID,
315 NULL
317 { // Pointer to TransferControl
318 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
319 sizeof (PROTOCOL_HOB), // Hob size
320 0, // reserved
321 EFI_PEI_TRANSFER_CONTROL_GUID,
322 NULL
324 { // Pointer to PeCoffLoader
325 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
326 sizeof (PROTOCOL_HOB), // Hob size
327 0, // reserved
328 EFI_PEI_PE_COFF_LOADER_GUID,
329 NULL
331 { // Pointer to EfiDecompress
332 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
333 sizeof (PROTOCOL_HOB), // Hob size
334 0, // reserved
335 EFI_DECOMPRESS_PROTOCOL_GUID,
336 NULL
338 { // Pointer to TianoDecompress
339 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
340 sizeof (PROTOCOL_HOB), // Hob size
341 0, // reserved
342 EFI_TIANO_DECOMPRESS_PROTOCOL_GUID,
343 NULL
346 { // Pointer to ReportStatusCode
349 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
350 sizeof (PROTOCOL_HOB), // Hob size
351 0 // reserved
353 EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID
355 NULL
357 { // EFILDR Memory Descriptor
360 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
361 sizeof (MEMORY_DESC_HOB), // Hob size
362 0 // reserved
364 EFI_LDR_MEMORY_DESCRIPTOR_GUID
367 NULL
369 { // Pci Express Base Address Hob
372 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
373 sizeof (PCI_EXPRESS_BASE_HOB), // Hob size
374 0 // reserved
376 EFI_PCI_EXPRESS_BASE_ADDRESS_GUID
384 { // Acpi Description Hob
387 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
388 sizeof (ACPI_DESCRIPTION_HOB), // Hob size
389 0 // reserved
391 EFI_ACPI_DESCRIPTION_GUID
399 { // NV Storage FV Resource
401 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
402 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
403 0 // Reserved
406 0 // Owner Guid
408 EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType
409 (EFI_RESOURCE_ATTRIBUTE_PRESENT |
410 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
411 EFI_RESOURCE_ATTRIBUTE_TESTED |
412 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute
413 0, // PhysicalStart (Fixed later)
414 NV_STORAGE_FVB_SIZE // ResourceLength
416 { // FVB holding NV Storage
419 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
420 sizeof (FVB_HOB),
423 EFI_FLASH_MAP_HOB_GUID
426 {0, 0, 0}, // Reserved[3]
427 EFI_FLASH_AREA_GUID_DEFINED, // AreaType
428 EFI_SYSTEM_NV_DATA_FV_GUID , // AreaTypeGuid
432 EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
433 0, // SubAreaData.Reserved
434 0, // SubAreaData.Base (Fixed later)
435 NV_STORAGE_FVB_SIZE, // SubAreaData.Length
436 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
439 0, // VolumeSignature (Fixed later)
440 NV_STORAGE_FILE_PATH, // Mapped file without padding
441 // TotalFVBSize = FileSize + PaddingSize = multiple of BLOCK_SIZE
442 NV_STORAGE_SIZE + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH,
443 // ActuralSize
444 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
447 { // NV Storage Hob
450 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
451 sizeof (FVB_HOB), // Hob size
452 0 // reserved
454 EFI_FLASH_MAP_HOB_GUID
457 {0, 0, 0}, // Reserved[3]
458 EFI_FLASH_AREA_EFI_VARIABLES, // AreaType
459 { 0 }, // AreaTypeGuid
463 EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
464 0, // SubAreaData.Reserved
465 0, // SubAreaData.Base (Fixed later)
466 NV_STORAGE_SIZE, // SubAreaData.Length
467 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
471 NV_STORAGE_FILE_PATH,
472 NV_STORAGE_SIZE,
476 { // NV Ftw FV Resource
478 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
479 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
480 0 // Reserved
483 0 // Owner Guid
485 EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType
486 (EFI_RESOURCE_ATTRIBUTE_PRESENT |
487 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
488 EFI_RESOURCE_ATTRIBUTE_TESTED |
489 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute
490 0, // PhysicalStart (Fixed later)
491 NV_FTW_FVB_SIZE // ResourceLength
493 { // FVB holding FTW spaces including Working & Spare space
496 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
497 sizeof (FVB_HOB),
500 EFI_FLASH_MAP_HOB_GUID
503 {0, 0, 0}, // Reserved[3]
504 EFI_FLASH_AREA_GUID_DEFINED, // AreaType
505 EFI_SYSTEM_NV_DATA_FV_GUID, // AreaTypeGuid
509 EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
510 0, // SubAreaData.Reserved
511 0, // SubAreaData.Base (Fixed later)
512 NV_FTW_FVB_SIZE, // SubAreaData.Length
513 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
517 L"", // Empty String indicates using memory
522 { // NV Ftw working Hob
525 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
526 sizeof (FVB_HOB), // Hob size
527 0 // reserved
529 EFI_FLASH_MAP_HOB_GUID
532 {0, 0, 0}, // Reserved[3]
533 EFI_FLASH_AREA_FTW_STATE, // AreaType
534 { 0 }, // AreaTypeGuid
538 EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
539 0, // SubAreaData.Reserved
540 0, // SubAreaData.Base (Fixed later)
541 NV_FTW_WORKING_SIZE, // SubAreaData.Length
542 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
545 0, // VolumeSignature
546 L"",
551 { // NV Ftw spare Hob
554 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
555 sizeof (FVB_HOB), // Hob size
556 0 // reserved
558 EFI_FLASH_MAP_HOB_GUID
561 {0, 0, 0}, // Reserved[3]
562 EFI_FLASH_AREA_FTW_BACKUP, // AreaType
563 { 0 }, // AreaTypeGuid
567 EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
568 0, // SubAreaData.Reserved
569 0, // SubAreaData.Base (Fixed later)
570 NV_FTW_SPARE_SIZE, // SubAreaData.Length
571 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
575 L"",
580 { // EndOfHobList
581 EFI_HOB_TYPE_END_OF_HOB_LIST, // HobType
582 sizeof (EFI_HOB_GENERIC_HEADER), // HobLength
583 0 // Reserved
587 HOB_TEMPLATE *gHob = &gHobTemplate;
589 VOID *
590 PrepareHobMemory (
591 IN UINTN NumberOfMemoryMapEntries,
592 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
594 /*++
595 Description:
596 Update the Hob filling MemoryFreeUnder1MB, MemoryAbove1MB, MemoryAbove4GB
598 Arguments:
599 NumberOfMemoryMapEntries - Count of Memory Descriptors
600 EfiMemoryDescriptor - Point to the buffer containing NumberOfMemoryMapEntries Memory Descriptors
602 Return:
603 VOID * : The end address of MemoryAbove1MB (or the top free memory under 4GB)
604 --*/
606 UINTN Index;
609 // Prepare Low Memory
610 // 0x18 pages is 72 KB.
612 gHob->MemoryFreeUnder1MB.ResourceLength = EFI_MEMORY_BELOW_1MB_END - EFI_MEMORY_BELOW_1MB_START;
613 gHob->MemoryFreeUnder1MB.PhysicalStart = EFI_MEMORY_BELOW_1MB_START;
616 // Prepare High Memory
617 // Assume Memory Map is ordered from low to high
619 gHob->MemoryAbove1MB.PhysicalStart = 0;
620 gHob->MemoryAbove1MB.ResourceLength = 0;
621 gHob->MemoryAbove4GB.PhysicalStart = 0;
622 gHob->MemoryAbove4GB.ResourceLength = 0;
624 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
626 // Skip regions below 1MB
628 if (EfiMemoryDescriptor[Index].PhysicalStart < 0x100000) {
629 continue;
632 // Process regions above 1MB
634 if (EfiMemoryDescriptor[Index].PhysicalStart >= 0x100000) {
635 if (EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) {
636 if (gHob->MemoryAbove1MB.PhysicalStart == 0) {
637 gHob->MemoryAbove1MB.PhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;
638 gHob->MemoryAbove1MB.ResourceLength = LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);
639 } else if (gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength == EfiMemoryDescriptor[Index].PhysicalStart) {
640 gHob->MemoryAbove1MB.ResourceLength += LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);
643 if ((EfiMemoryDescriptor[Index].Type == EfiReservedMemoryType) ||
644 (EfiMemoryDescriptor[Index].Type >= EfiACPIReclaimMemory) ) {
645 continue;
647 if ((EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesCode) ||
648 (EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesData)) {
649 break;
653 // Process region above 4GB
655 if (EfiMemoryDescriptor[Index].PhysicalStart >= 0x100000000LL) {
656 if (EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) {
657 if (gHob->MemoryAbove4GB.PhysicalStart == 0) {
658 gHob->MemoryAbove4GB.PhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;
659 gHob->MemoryAbove4GB.ResourceLength = LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);
661 if (gHob->MemoryAbove4GB.PhysicalStart + gHob->MemoryAbove4GB.ResourceLength ==
662 EfiMemoryDescriptor[Index].PhysicalStart) {
663 gHob->MemoryAbove4GB.ResourceLength += LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);
669 if (gHob->MemoryAbove4GB.ResourceLength == 0) {
671 // If there is no memory above 4GB then change the resource descriptor HOB
672 // into another type. I'm doing this as it's unclear if a resource
673 // descriptor HOB of length zero is valid. Spec does not say it's illegal,
674 // but code in EDK does not seem to handle this case.
676 gHob->MemoryAbove4GB.Header.HobType = EFI_HOB_TYPE_UNUSED;
679 return (VOID *)(UINTN)(gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength);
682 VOID *
683 PrepareHobStack (
684 IN VOID *StackTop
687 gHob->Stack.AllocDescriptor.MemoryLength = EFI_MEMORY_STACK_PAGE_NUM * EFI_PAGE_SIZE;
688 gHob->Stack.AllocDescriptor.MemoryBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)StackTop - gHob->Stack.AllocDescriptor.MemoryLength;
690 return (VOID *)(UINTN)gHob->Stack.AllocDescriptor.MemoryBaseAddress;
693 VOID *
694 PrepareHobMemoryDescriptor (
695 VOID *MemoryDescriptorTop,
696 UINTN MemDescCount,
697 EFI_MEMORY_DESCRIPTOR *MemDesc
700 gHob->MemoryDescriptor.MemDescCount = MemDescCount;
701 gHob->MemoryDescriptor.MemDesc = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryDescriptorTop - MemDescCount * sizeof(EFI_MEMORY_DESCRIPTOR));
703 // Make MemoryDescriptor.MemDesc page aligned
705 gHob->MemoryDescriptor.MemDesc = (EFI_MEMORY_DESCRIPTOR *)((UINTN) gHob->MemoryDescriptor.MemDesc & ~EFI_PAGE_MASK);
707 CopyMem (gHob->MemoryDescriptor.MemDesc, MemDesc, MemDescCount * sizeof(EFI_MEMORY_DESCRIPTOR));
709 return gHob->MemoryDescriptor.MemDesc;
712 VOID
713 PrepareHobBfv (
714 VOID *Bfv,
715 UINTN BfvLength
718 //UINTN BfvLengthPageSize;
721 // Calculate BFV location at top of the memory region.
722 // This is like a RAM Disk. Align to page boundry.
724 //BfvLengthPageSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (BfvLength));
726 gHob->Bfv.BaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Bfv;
727 gHob->Bfv.Length = BfvLength;
730 // Resource descriptor for the FV
732 gHob->BfvResource.PhysicalStart = gHob->Bfv.BaseAddress;
733 gHob->BfvResource.ResourceLength = gHob->Bfv.Length;
736 VOID
737 PrepareHobDxeCore (
738 VOID *DxeCoreEntryPoint,
739 EFI_PHYSICAL_ADDRESS DxeCoreImageBase,
740 UINT64 DxeCoreLength
743 gHob->DxeCore.MemoryAllocationHeader.MemoryBaseAddress = DxeCoreImageBase;
744 gHob->DxeCore.MemoryAllocationHeader.MemoryLength = DxeCoreLength;
745 gHob->DxeCore.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)DxeCoreEntryPoint;
748 gHob->MemoryDxeCore.PhysicalStart = DxeCoreImageBase;
749 gHob->MemoryDxeCore.ResourceLength = DxeCoreLength;
752 VOID *
753 PrepareHobNvStorage (
754 VOID *NvStorageTop
757 Initialize Block-Aligned Firmware Block.
759 Variable:
760 +-------------------+
761 | FV_Header |
762 +-------------------+
764 |VAR_STORAGE(0x4000)|
766 +-------------------+
767 FTW:
768 +-------------------+
769 | FV_Header |
770 +-------------------+
772 | Working(0x2000) |
774 +-------------------+
776 | Spare(0x10000) |
778 +-------------------+
781 STATIC VARIABLE_STORE_HEADER VarStoreHeader = {
782 VARIABLE_STORE_SIGNATURE,
783 0xffffffff, // will be fixed in Variable driver
784 VARIABLE_STORE_FORMATTED,
785 VARIABLE_STORE_HEALTHY,
790 STATIC EFI_FIRMWARE_VOLUME_HEADER NvStorageFvbHeader = {
793 }, // ZeroVector[16]
794 EFI_SYSTEM_NV_DATA_FV_GUID,
795 NV_STORAGE_FVB_SIZE,
796 EFI_FVH_SIGNATURE,
797 EFI_FVB_READ_ENABLED_CAP |
798 EFI_FVB_READ_STATUS |
799 EFI_FVB_WRITE_ENABLED_CAP |
800 EFI_FVB_WRITE_STATUS |
801 EFI_FVB_ERASE_POLARITY,
802 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH,
803 0, // CheckSum
804 0, // ExtHeaderOffset
807 }, // Reserved[1]
808 1, // Revision
811 NV_STORAGE_FVB_BLOCK_NUM,
812 FV_BLOCK_SIZE,
817 STATIC EFI_FV_BLOCK_MAP_ENTRY BlockMapEntryEnd = {0, 0};
819 EFI_PHYSICAL_ADDRESS StorageFvbBase;
820 EFI_PHYSICAL_ADDRESS FtwFvbBase;
822 UINT16 *Ptr;
823 UINT16 Checksum;
827 // Use first 16-byte Reset Vector of FVB to store extra information
828 // UINT32 Offset 0 stores the volume signature
829 // UINT8 Offset 4 : should init the Variable Store Header if non-zero
831 gHob->NvStorageFvb.FvbInfo.VolumeId = *(UINT32 *) (UINTN) (NV_STORAGE_STATE);
832 gHob->NvStorage. FvbInfo.VolumeId = *(UINT32 *) (UINTN) (NV_STORAGE_STATE);
835 // *(NV_STORAGE_STATE + 4):
836 // 2 - Size error
837 // 1 - File not exist
838 // 0 - File exist with correct size
840 if (*(UINT8 *) (UINTN) (NV_STORAGE_STATE + 4) == 2) {
841 ClearScreen ();
842 PrintString ("Error: Size of Efivar.bin should be 16k!\n");
843 CpuDeadLoop();
846 if (*(UINT8 *) (UINTN) (NV_STORAGE_STATE + 4) != 0) {
848 // Efivar.bin doesn't exist
849 // 1. Init variable storage header to valid header
851 CopyMem (
852 (VOID *) (UINTN) NV_STORAGE_START,
853 &VarStoreHeader,
854 sizeof (VARIABLE_STORE_HEADER)
857 // 2. set all bits in variable storage body to 1
859 SetMem (
860 (VOID *) (UINTN) (NV_STORAGE_START + sizeof (VARIABLE_STORE_HEADER)),
861 NV_STORAGE_SIZE - sizeof (VARIABLE_STORE_HEADER),
862 0xff
867 // Relocate variable storage
869 // 1. Init FVB Header to valid header: First 0x48 bytes
870 // In real platform, these fields are fixed by tools
873 Checksum = 0;
874 for (
875 Ptr = (UINT16 *) &NvStorageFvbHeader;
876 Ptr < (UINT16 *) ((UINTN) (UINT8 *) &NvStorageFvbHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER));
877 ++Ptr
879 Checksum = (UINT16) (Checksum + (*Ptr));
881 NvStorageFvbHeader.Checksum = (UINT16) (0x10000 - Checksum);
882 StorageFvbBase = (EFI_PHYSICAL_ADDRESS)(((UINTN)NvStorageTop - NV_STORAGE_FVB_SIZE - NV_FTW_FVB_SIZE) & ~EFI_PAGE_MASK);
883 CopyMem ((VOID *) (UINTN) StorageFvbBase, &NvStorageFvbHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
884 CopyMem (
885 (VOID *) (UINTN) (StorageFvbBase + sizeof (EFI_FIRMWARE_VOLUME_HEADER)),
886 &BlockMapEntryEnd,
887 sizeof (EFI_FV_BLOCK_MAP_ENTRY)
891 // 2. Relocate variable data
893 CopyMem (
894 (VOID *) (UINTN) (StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH),
895 (VOID *) (UINTN) NV_STORAGE_START,
896 NV_STORAGE_SIZE
900 // 3. Set the remaining memory to 0xff
902 SetMem (
903 (VOID *) (UINTN) (StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH + NV_STORAGE_SIZE),
904 NV_STORAGE_FVB_SIZE - NV_STORAGE_SIZE - EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH,
905 0xff
909 // Create the FVB holding NV Storage in memory
911 gHob->NvStorageFvResource.PhysicalStart =
912 gHob->NvStorageFvb.FvbInfo.Entries[0].Base = StorageFvbBase;
914 // Create the NV Storage Hob
916 gHob->NvStorage.FvbInfo.Entries[0].Base = StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH;
919 // Create the FVB holding FTW spaces
921 FtwFvbBase = (EFI_PHYSICAL_ADDRESS)((UINTN) StorageFvbBase + NV_STORAGE_FVB_SIZE);
922 gHob->NvFtwFvResource.PhysicalStart =
923 gHob->NvFtwFvb.FvbInfo.Entries[0].Base = FtwFvbBase;
925 // Put FTW Working in front
927 gHob->NvFtwWorking.FvbInfo.Entries[0].Base = FtwFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH;
930 // Put FTW Spare area after FTW Working area
932 gHob->NvFtwSpare.FvbInfo.Entries[0].Base =
933 (EFI_PHYSICAL_ADDRESS)((UINTN) FtwFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH + NV_FTW_WORKING_SIZE);
935 return (VOID *)(UINTN)StorageFvbBase;
938 VOID
939 PrepareHobPhit (
940 VOID *MemoryTop,
941 VOID *FreeMemoryTop
944 gHob->Phit.EfiMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryTop;
945 gHob->Phit.EfiMemoryBottom = gHob->Phit.EfiMemoryTop - CONSUMED_MEMORY;
946 gHob->Phit.EfiFreeMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)FreeMemoryTop;
947 gHob->Phit.EfiFreeMemoryBottom = gHob->Phit.EfiMemoryBottom + sizeof(HOB_TEMPLATE);
949 CopyMem ((VOID *)(UINTN)gHob->Phit.EfiMemoryBottom, gHob, sizeof(HOB_TEMPLATE));
950 gHob = (HOB_TEMPLATE *)(UINTN)gHob->Phit.EfiMemoryBottom;
952 gHob->Phit.EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)&gHob->EndOfHobList;
955 VOID
956 PrepareHobCpu (
957 VOID
960 EFI_CPUID_REGISTER Reg;
961 UINT8 CpuMemoryAddrBitNumber;
964 // Create a CPU hand-off information
966 CpuMemoryAddrBitNumber = 36;
967 AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &Reg.RegEax, &Reg.RegEbx, &Reg.RegEcx, &Reg.RegEdx);
969 if (Reg.RegEax >= CPUID_EXTENDED_ADD_SIZE) {
970 AsmCpuid (CPUID_EXTENDED_ADD_SIZE, &Reg.RegEax, &Reg.RegEbx, &Reg.RegEcx, &Reg.RegEdx);
971 CpuMemoryAddrBitNumber = (UINT8)(UINTN)(Reg.RegEax & 0xFF);
974 gHob->Cpu.SizeOfMemorySpace = CpuMemoryAddrBitNumber;
977 VOID
978 CompleteHobGeneration (
979 VOID
982 gHob->MemoryAllocation.AllocDescriptor.MemoryBaseAddress = gHob->Phit.EfiFreeMemoryTop;
984 // Reserve all the memory under Stack above FreeMemoryTop as allocated
986 gHob->MemoryAllocation.AllocDescriptor.MemoryLength = gHob->Stack.AllocDescriptor.MemoryBaseAddress - gHob->Phit.EfiFreeMemoryTop;
989 // adjust Above1MB ResourceLength
991 if (gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength > gHob->Phit.EfiMemoryTop) {
992 gHob->MemoryAbove1MB.ResourceLength = gHob->Phit.EfiMemoryTop - gHob->MemoryAbove1MB.PhysicalStart;