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.
21 #include "HobGeneration.h"
22 #include "PpisNeededByDxeCore.h"
23 #include "FlashLayout.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
= {
34 EFI_HOB_TYPE_HANDOFF
, // HobType
35 sizeof (EFI_HOB_HANDOFF_INFO_TABLE
), // HobLength
38 EFI_HOB_HANDOFF_TABLE_VERSION
, // Version
39 BOOT_WITH_FULL_CONFIGURATION
, // BootMode
42 0, // EfiFreeMemoryTop
43 0, // EfiFreeMemoryBottom
48 EFI_HOB_TYPE_FV
, // HobType
49 sizeof (EFI_HOB_FIRMWARE_VOLUME
), // HobLength
57 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, // HobType
58 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR
), // HobLength
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
74 EFI_HOB_TYPE_CPU
, // HobType
75 sizeof (EFI_HOB_CPU
), // HobLength
78 52, // SizeOfMemorySpace - Architecture Max
81 0, 0, 0, 0, 0, 0 // Reserved[6]
86 EFI_HOB_TYPE_MEMORY_ALLOCATION
, // Hob type
87 sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK
), // Hob size
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
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
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
136 { // MemoryFreeAbove1MB for unused memory that DXE core will claim
138 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, // HobType
139 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR
), // HobLength
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
156 { // MemoryFreeAbove4GB for unused memory that DXE core will claim
158 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, // HobType
159 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR
), // HobLength
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
175 { // Memory Allocation Module for DxeCore
177 EFI_HOB_TYPE_MEMORY_ALLOCATION
, // Hob type
178 sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE
), // Hob size
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];
191 0x0 // EFI_PHYSICAL_ADDRESS of EntryPoint;
193 { // Memory Map Hints to reduce fragmentation in the memory map
196 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
197 sizeof (MEMORY_TYPE_INFORMATION_HOB
), // Hob size
200 EFI_MEMORY_TYPE_INFORMATION_GUID
204 EfiACPIReclaimMemory
,
206 }, // 0x80 pages = 512k for ASL
210 }, // 0x100 pages = 1024k for S3, SMM, etc
212 EfiReservedMemoryType
,
214 }, // 16k for BIOS Reserved
216 EfiRuntimeServicesData
,
220 EfiRuntimeServicesCode
,
245 { // Pointer to ACPI Table
248 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
249 sizeof (TABLE_HOB
), // Hob size
256 { // Pointer to ACPI20 Table
259 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
260 sizeof (TABLE_HOB
), // Hob size
263 EFI_ACPI_20_TABLE_GUID
267 { // Pointer to SMBIOS Table
270 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
271 sizeof (TABLE_HOB
), // Hob size
274 EFI_SMBIOS_TABLE_GUID
278 { // Pointer to MPS Table
281 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
282 sizeof (TABLE_HOB
), // Hob size
290 { // Pointer to FlushInstructionCache
291 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
292 sizeof (PROTOCOL_HOB), // Hob size
294 EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID,
297 { // Pointer to TransferControl
298 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
299 sizeof (PROTOCOL_HOB), // Hob size
301 EFI_PEI_TRANSFER_CONTROL_GUID,
304 { // Pointer to PeCoffLoader
305 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
306 sizeof (PROTOCOL_HOB), // Hob size
308 EFI_PEI_PE_COFF_LOADER_GUID,
311 { // Pointer to EfiDecompress
312 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
313 sizeof (PROTOCOL_HOB), // Hob size
315 EFI_DECOMPRESS_PROTOCOL_GUID,
318 { // Pointer to TianoDecompress
319 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
320 sizeof (PROTOCOL_HOB), // Hob size
322 EFI_TIANO_DECOMPRESS_PROTOCOL_GUID,
326 { // Pointer to ReportStatusCode
329 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
330 sizeof (PROTOCOL_HOB
), // Hob size
333 EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID
337 { // EFILDR Memory Descriptor
340 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
341 sizeof (MEMORY_DESC_HOB
), // Hob size
344 EFI_LDR_MEMORY_DESCRIPTOR_GUID
349 { // Pci Express Base Address Hob
352 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
353 sizeof (PCI_EXPRESS_BASE_HOB
), // Hob size
356 EFI_PCI_EXPRESS_BASE_ADDRESS_GUID
364 { // Acpi Description Hob
367 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
368 sizeof (ACPI_DESCRIPTION_HOB
), // Hob size
371 EFI_ACPI_DESCRIPTION_GUID
379 { // NV Storage FV Resource
381 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, // HobType
382 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR
), // HobLength
388 EFI_RESOURCE_FIRMWARE_DEVICE
, // ResourceType
389 (EFI_RESOURCE_ATTRIBUTE_PRESENT
|
390 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
391 EFI_RESOURCE_ATTRIBUTE_TESTED
|
392 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
), // ResourceAttribute
393 0, // PhysicalStart (Fixed later)
394 NV_STORAGE_FVB_SIZE
// ResourceLength
396 { // FVB holding NV Storage
399 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
403 EFI_FLASH_MAP_HOB_GUID
406 {0, 0, 0}, // Reserved[3]
407 EFI_FLASH_AREA_GUID_DEFINED
, // AreaType
408 EFI_SYSTEM_NV_DATA_HOB_GUID
, // AreaTypeGuid
412 EFI_FLASH_AREA_FV
| EFI_FLASH_AREA_MEMMAPPED_FV
, // SubAreaData.Attributes
413 0, // SubAreaData.Reserved
414 0, // SubAreaData.Base (Fixed later)
415 NV_STORAGE_FVB_SIZE
, // SubAreaData.Length
416 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
419 0, // VolumeSignature (Fixed later)
420 NV_STORAGE_FILE_PATH
, // Mapped file without padding
421 // TotalFVBSize = FileSize + PaddingSize = multiple of BLOCK_SIZE
422 NV_STORAGE_SIZE
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
,
424 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
430 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
431 sizeof (FVB_HOB
), // Hob size
434 EFI_FLASH_MAP_HOB_GUID
437 {0, 0, 0}, // Reserved[3]
438 EFI_FLASH_AREA_EFI_VARIABLES
, // AreaType
439 { 0 }, // AreaTypeGuid
443 EFI_FLASH_AREA_SUBFV
| EFI_FLASH_AREA_MEMMAPPED_FV
, // SubAreaData.Attributes
444 0, // SubAreaData.Reserved
445 0, // SubAreaData.Base (Fixed later)
446 NV_STORAGE_SIZE
, // SubAreaData.Length
447 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
451 NV_STORAGE_FILE_PATH
,
456 { // FVB holding FTW spaces including Working & Spare space
459 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
463 EFI_FLASH_MAP_HOB_GUID
466 {0, 0, 0}, // Reserved[3]
467 EFI_FLASH_AREA_GUID_DEFINED
, // AreaType
468 EFI_SYSTEM_NV_DATA_HOB_GUID
, // AreaTypeGuid
472 EFI_FLASH_AREA_FV
| EFI_FLASH_AREA_MEMMAPPED_FV
, // SubAreaData.Attributes
473 0, // SubAreaData.Reserved
474 0, // SubAreaData.Base (Fixed later)
475 NV_FTW_FVB_SIZE
, // SubAreaData.Length
476 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
480 L
"", // Empty String indicates using memory
485 { // NV Ftw working Hob
488 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
489 sizeof (FVB_HOB
), // Hob size
492 EFI_FLASH_MAP_HOB_GUID
495 {0, 0, 0}, // Reserved[3]
496 EFI_FLASH_AREA_FTW_STATE
, // AreaType
497 { 0 }, // AreaTypeGuid
501 EFI_FLASH_AREA_SUBFV
| EFI_FLASH_AREA_MEMMAPPED_FV
, // SubAreaData.Attributes
502 0, // SubAreaData.Reserved
503 0, // SubAreaData.Base (Fixed later)
504 NV_FTW_WORKING_SIZE
, // SubAreaData.Length
505 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
508 0, // VolumeSignature
514 { // NV Ftw spare Hob
517 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
518 sizeof (FVB_HOB
), // Hob size
521 EFI_FLASH_MAP_HOB_GUID
524 {0, 0, 0}, // Reserved[3]
525 EFI_FLASH_AREA_FTW_BACKUP
, // AreaType
526 { 0 }, // AreaTypeGuid
530 EFI_FLASH_AREA_SUBFV
| EFI_FLASH_AREA_MEMMAPPED_FV
, // SubAreaData.Attributes
531 0, // SubAreaData.Reserved
532 0, // SubAreaData.Base (Fixed later)
533 NV_FTW_SPARE_SIZE
, // SubAreaData.Length
534 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
544 EFI_HOB_TYPE_END_OF_HOB_LIST
, // HobType
545 sizeof (EFI_HOB_GENERIC_HEADER
), // HobLength
550 HOB_TEMPLATE
*gHob
= &gHobTemplate
;
554 IN UINTN NumberOfMemoryMapEntries
,
555 IN EFI_MEMORY_DESCRIPTOR
*EfiMemoryDescriptor
559 Update the Hob filling MemoryFreeUnder1MB, MemoryAbove1MB, MemoryAbove4GB
562 NumberOfMemoryMapEntries - Count of Memory Descriptors
563 EfiMemoryDescriptor - Point to the buffer containing NumberOfMemoryMapEntries Memory Descriptors
566 VOID * : The end address of MemoryAbove1MB (or the top free memory under 4GB)
572 // Prepare Low Memory
573 // 0x18 pages is 72 KB.
575 gHob
->MemoryFreeUnder1MB
.ResourceLength
= EFI_MEMORY_BELOW_1MB_END
- EFI_MEMORY_BELOW_1MB_START
;
576 gHob
->MemoryFreeUnder1MB
.PhysicalStart
= EFI_MEMORY_BELOW_1MB_START
;
579 // Prepare High Memory
580 // Assume Memory Map is ordered from low to high
582 gHob
->MemoryAbove1MB
.PhysicalStart
= 0;
583 gHob
->MemoryAbove1MB
.ResourceLength
= 0;
584 gHob
->MemoryAbove4GB
.PhysicalStart
= 0;
585 gHob
->MemoryAbove4GB
.ResourceLength
= 0;
587 for (Index
= 0; Index
< NumberOfMemoryMapEntries
; Index
++) {
589 // Skip regions below 1MB
591 if (EfiMemoryDescriptor
[Index
].PhysicalStart
< 0x100000) {
595 // Process regions above 1MB
597 if (EfiMemoryDescriptor
[Index
].PhysicalStart
>= 0x100000) {
598 if (EfiMemoryDescriptor
[Index
].Type
== EfiConventionalMemory
) {
599 if (gHob
->MemoryAbove1MB
.PhysicalStart
== 0) {
600 gHob
->MemoryAbove1MB
.PhysicalStart
= EfiMemoryDescriptor
[Index
].PhysicalStart
;
601 gHob
->MemoryAbove1MB
.ResourceLength
= LShiftU64 (EfiMemoryDescriptor
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
);
602 } else if (gHob
->MemoryAbove1MB
.PhysicalStart
+ gHob
->MemoryAbove1MB
.ResourceLength
== EfiMemoryDescriptor
[Index
].PhysicalStart
) {
603 gHob
->MemoryAbove1MB
.ResourceLength
+= LShiftU64 (EfiMemoryDescriptor
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
);
606 if ((EfiMemoryDescriptor
[Index
].Type
== EfiReservedMemoryType
) ||
607 (EfiMemoryDescriptor
[Index
].Type
>= EfiACPIReclaimMemory
) ) {
610 if ((EfiMemoryDescriptor
[Index
].Type
== EfiRuntimeServicesCode
) ||
611 (EfiMemoryDescriptor
[Index
].Type
== EfiRuntimeServicesData
)) {
616 // Process region above 4GB
618 if (EfiMemoryDescriptor
[Index
].PhysicalStart
>= 0x100000000LL
) {
619 if (EfiMemoryDescriptor
[Index
].Type
== EfiConventionalMemory
) {
620 if (gHob
->MemoryAbove4GB
.PhysicalStart
== 0) {
621 gHob
->MemoryAbove4GB
.PhysicalStart
= EfiMemoryDescriptor
[Index
].PhysicalStart
;
622 gHob
->MemoryAbove4GB
.ResourceLength
= LShiftU64 (EfiMemoryDescriptor
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
);
624 if (gHob
->MemoryAbove4GB
.PhysicalStart
+ gHob
->MemoryAbove4GB
.ResourceLength
==
625 EfiMemoryDescriptor
[Index
].PhysicalStart
) {
626 gHob
->MemoryAbove4GB
.ResourceLength
+= LShiftU64 (EfiMemoryDescriptor
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
);
632 if (gHob
->MemoryAbove4GB
.ResourceLength
== 0) {
634 // If there is no memory above 4GB then change the resource descriptor HOB
635 // into another type. I'm doing this as it's unclear if a resource
636 // descriptor HOB of length zero is valid. Spec does not say it's illegal,
637 // but code in EDK does not seem to handle this case.
639 gHob
->MemoryAbove4GB
.Header
.HobType
= EFI_HOB_TYPE_UNUSED
;
642 return (VOID
*)(UINTN
)(gHob
->MemoryAbove1MB
.PhysicalStart
+ gHob
->MemoryAbove1MB
.ResourceLength
);
650 gHob
->Stack
.AllocDescriptor
.MemoryLength
= EFI_MEMORY_STACK_PAGE_NUM
* EFI_PAGE_SIZE
;
651 gHob
->Stack
.AllocDescriptor
.MemoryBaseAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)StackTop
- gHob
->Stack
.AllocDescriptor
.MemoryLength
;
653 return (VOID
*)(UINTN
)gHob
->Stack
.AllocDescriptor
.MemoryBaseAddress
;
657 PrepareHobMemoryDescriptor (
658 VOID
*MemoryDescriptorTop
,
660 EFI_MEMORY_DESCRIPTOR
*MemDesc
663 gHob
->MemoryDescriptor
.MemDescCount
= MemDescCount
;
664 gHob
->MemoryDescriptor
.MemDesc
= (EFI_MEMORY_DESCRIPTOR
*)((UINTN
)MemoryDescriptorTop
- MemDescCount
* sizeof(EFI_MEMORY_DESCRIPTOR
));
666 // Make MemoryDescriptor.MemDesc page aligned
668 gHob
->MemoryDescriptor
.MemDesc
= (EFI_MEMORY_DESCRIPTOR
*)((UINTN
) gHob
->MemoryDescriptor
.MemDesc
& ~EFI_PAGE_MASK
);
670 CopyMem (gHob
->MemoryDescriptor
.MemDesc
, MemDesc
, MemDescCount
* sizeof(EFI_MEMORY_DESCRIPTOR
));
672 return gHob
->MemoryDescriptor
.MemDesc
;
681 //UINTN BfvLengthPageSize;
684 // Calculate BFV location at top of the memory region.
685 // This is like a RAM Disk. Align to page boundry.
687 //BfvLengthPageSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (BfvLength));
689 gHob
->Bfv
.BaseAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Bfv
;
690 gHob
->Bfv
.Length
= BfvLength
;
693 // Resource descriptor for the FV
695 gHob
->BfvResource
.PhysicalStart
= gHob
->Bfv
.BaseAddress
;
696 gHob
->BfvResource
.ResourceLength
= gHob
->Bfv
.Length
;
701 VOID
*DxeCoreEntryPoint
,
702 EFI_PHYSICAL_ADDRESS DxeCoreImageBase
,
706 gHob
->DxeCore
.MemoryAllocationHeader
.MemoryBaseAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)DxeCoreImageBase
;
707 gHob
->DxeCore
.MemoryAllocationHeader
.MemoryLength
= DxeCoreLength
;
708 gHob
->DxeCore
.EntryPoint
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)DxeCoreEntryPoint
;
712 PrepareHobNvStorage (
716 Initialize Block-Aligned Firmware Block.
719 +-------------------+
721 +-------------------+
723 |VAR_STORAGE(0x4000)|
725 +-------------------+
727 +-------------------+
729 +-------------------+
733 +-------------------+
737 +-------------------+
740 STATIC VARIABLE_STORE_HEADER VarStoreHeader
= {
741 VARIABLE_STORE_SIGNATURE
,
742 0xffffffff, // will be fixed in Variable driver
743 VARIABLE_STORE_FORMATTED
,
744 VARIABLE_STORE_HEALTHY
,
749 STATIC EFI_FIRMWARE_VOLUME_HEADER NvStorageFvbHeader
= {
753 EFI_SYSTEM_NV_DATA_FV_GUID
,
756 EFI_FVB_READ_ENABLED_CAP
|
757 EFI_FVB_READ_STATUS
|
758 EFI_FVB_WRITE_ENABLED_CAP
|
759 EFI_FVB_WRITE_STATUS
|
760 EFI_FVB_ERASE_POLARITY
,
761 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
,
763 0, // ExtHeaderOffset
770 NV_STORAGE_FVB_BLOCK_NUM
,
776 STATIC EFI_FV_BLOCK_MAP_ENTRY BlockMapEntryEnd
= {0, 0};
778 EFI_PHYSICAL_ADDRESS StorageFvbBase
;
779 EFI_PHYSICAL_ADDRESS FtwFvbBase
;
786 // Use first 16-byte Reset Vector of FVB to store extra information
787 // UINT32 Offset 0 stores the volume signature
788 // UINT8 Offset 4 : should init the Variable Store Header if non-zero
790 gHob
->NvStorageFvb
.FvbInfo
.VolumeId
= *(UINT32
*) (UINTN
) (NV_STORAGE_STATE
);
791 gHob
->NvStorage
. FvbInfo
.VolumeId
= *(UINT32
*) (UINTN
) (NV_STORAGE_STATE
);
794 // *(NV_STORAGE_STATE + 4):
796 // 1 - File not exist
797 // 0 - File exist with correct size
799 if (*(UINT8
*) (UINTN
) (NV_STORAGE_STATE
+ 4) == 2) {
801 PrintString ("Error: Size of Efivar.bin should be 16k!\n");
805 if (*(UINT8
*) (UINTN
) (NV_STORAGE_STATE
+ 4) != 0) {
807 // Efivar.bin doesn't exist
808 // 1. Init variable storage header to valid header
811 (VOID
*) (UINTN
) NV_STORAGE_START
,
813 sizeof (VARIABLE_STORE_HEADER
)
816 // 2. set all bits in variable storage body to 1
819 (VOID
*) (UINTN
) (NV_STORAGE_START
+ sizeof (VARIABLE_STORE_HEADER
)),
820 NV_STORAGE_SIZE
- sizeof (VARIABLE_STORE_HEADER
),
826 // Relocate variable storage
828 // 1. Init FVB Header to valid header: First 0x48 bytes
829 // In real platform, these fields are fixed by tools
834 Ptr
= (UINT16
*) &NvStorageFvbHeader
;
835 Ptr
< (UINT16
*) ((UINTN
) (UINT8
*) &NvStorageFvbHeader
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
838 Checksum
= (UINT16
) (Checksum
+ (*Ptr
));
840 NvStorageFvbHeader
.Checksum
= (UINT16
) (0x10000 - Checksum
);
841 StorageFvbBase
= (EFI_PHYSICAL_ADDRESS
)(((UINTN
)NvStorageTop
- NV_STORAGE_FVB_SIZE
- NV_FTW_FVB_SIZE
) & ~EFI_PAGE_MASK
);
842 CopyMem ((VOID
*) (UINTN
) StorageFvbBase
, &NvStorageFvbHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
844 (VOID
*) (UINTN
) (StorageFvbBase
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER
)),
846 sizeof (EFI_FV_BLOCK_MAP_ENTRY
)
850 // 2. Relocate variable data
853 (VOID
*) (UINTN
) (StorageFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
),
854 (VOID
*) (UINTN
) NV_STORAGE_START
,
859 // 3. Set the remaining memory to 0xff
862 (VOID
*) (UINTN
) (StorageFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
+ NV_STORAGE_SIZE
),
863 NV_STORAGE_FVB_SIZE
- NV_STORAGE_SIZE
- EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
,
868 // Create the FVB holding NV Storage in memory
870 gHob
->NvStorageFvResource
.PhysicalStart
=
871 gHob
->NvStorageFvb
.FvbInfo
.Entries
[0].Base
= StorageFvbBase
;
873 // Create the NV Storage Hob
875 gHob
->NvStorage
.FvbInfo
.Entries
[0].Base
= StorageFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
;
878 // Create the FVB holding FTW spaces
880 FtwFvbBase
= (EFI_PHYSICAL_ADDRESS
)((UINTN
) StorageFvbBase
+ NV_STORAGE_FVB_SIZE
);
881 gHob
->NvFtwFvb
.FvbInfo
.Entries
[0].Base
= FtwFvbBase
;
883 // Put FTW Working in front
885 gHob
->NvFtwWorking
.FvbInfo
.Entries
[0].Base
= FtwFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
;
888 // Put FTW Spare area after FTW Working area
890 gHob
->NvFtwSpare
.FvbInfo
.Entries
[0].Base
=
891 (EFI_PHYSICAL_ADDRESS
)((UINTN
) FtwFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
+ NV_FTW_WORKING_SIZE
);
893 return (VOID
*)(UINTN
)StorageFvbBase
;
902 gHob
->Phit
.EfiMemoryTop
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)MemoryTop
;
903 gHob
->Phit
.EfiMemoryBottom
= gHob
->Phit
.EfiMemoryTop
- CONSUMED_MEMORY
;
904 gHob
->Phit
.EfiFreeMemoryTop
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)FreeMemoryTop
;
905 gHob
->Phit
.EfiFreeMemoryBottom
= gHob
->Phit
.EfiMemoryBottom
+ sizeof(HOB_TEMPLATE
);
907 CopyMem ((VOID
*)(UINTN
)gHob
->Phit
.EfiMemoryBottom
, gHob
, sizeof(HOB_TEMPLATE
));
908 gHob
= (HOB_TEMPLATE
*)(UINTN
)gHob
->Phit
.EfiMemoryBottom
;
910 gHob
->Phit
.EfiEndOfHobList
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)&gHob
->EndOfHobList
;
918 EFI_CPUID_REGISTER Reg
;
919 UINT8 CpuMemoryAddrBitNumber
;
922 // Create a CPU hand-off information
924 CpuMemoryAddrBitNumber
= 36;
925 AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION
, &Reg
.RegEax
, &Reg
.RegEbx
, &Reg
.RegEcx
, &Reg
.RegEdx
);
927 if (Reg
.RegEax
>= CPUID_EXTENDED_ADD_SIZE
) {
928 AsmCpuid (CPUID_EXTENDED_ADD_SIZE
, &Reg
.RegEax
, &Reg
.RegEbx
, &Reg
.RegEcx
, &Reg
.RegEdx
);
929 CpuMemoryAddrBitNumber
= (UINT8
)(UINTN
)(Reg
.RegEax
& 0xFF);
932 gHob
->Cpu
.SizeOfMemorySpace
= CpuMemoryAddrBitNumber
;
936 CompleteHobGeneration (
940 gHob
->MemoryAllocation
.AllocDescriptor
.MemoryBaseAddress
= gHob
->Phit
.EfiFreeMemoryTop
;
942 // Reserve all the memory under Stack above FreeMemoryTop as allocated
944 gHob
->MemoryAllocation
.AllocDescriptor
.MemoryLength
= gHob
->Stack
.AllocDescriptor
.MemoryBaseAddress
- gHob
->Phit
.EfiFreeMemoryTop
;
947 // adjust Above1MB ResourceLength
949 if (gHob
->MemoryAbove1MB
.PhysicalStart
+ gHob
->MemoryAbove1MB
.ResourceLength
> gHob
->Phit
.EfiMemoryTop
) {
950 gHob
->MemoryAbove1MB
.ResourceLength
= gHob
->Phit
.EfiMemoryTop
- gHob
->MemoryAbove1MB
.PhysicalStart
;