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
194 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
195 sizeof (MEMORY_TYPE_INFORMATION_HOB
), // Hob size
197 EFI_MEMORY_TYPE_INFORMATION_GUID
,
200 EfiACPIReclaimMemory
,
202 }, // 0x80 pages = 512k for ASL
206 }, // 0x100 pages = 1024k for S3, SMM, etc
208 EfiReservedMemoryType
,
210 }, // 16k for BIOS Reserved
212 EfiRuntimeServicesData
,
216 EfiRuntimeServicesCode
,
241 { // Pointer to ACPI Table
242 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
243 sizeof (TABLE_HOB
), // Hob size
248 { // Pointer to ACPI20 Table
249 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
250 sizeof (TABLE_HOB
), // Hob size
252 EFI_ACPI_20_TABLE_GUID
,
255 { // Pointer to SMBIOS Table
256 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
257 sizeof (TABLE_HOB
), // Hob size
259 EFI_SMBIOS_TABLE_GUID
,
262 { // Pointer to MPS Table
263 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
264 sizeof (TABLE_HOB
), // Hob size
270 { // Pointer to FlushInstructionCache
271 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
272 sizeof (PROTOCOL_HOB), // Hob size
274 EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID,
277 { // Pointer to TransferControl
278 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
279 sizeof (PROTOCOL_HOB), // Hob size
281 EFI_PEI_TRANSFER_CONTROL_GUID,
284 { // Pointer to PeCoffLoader
285 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
286 sizeof (PROTOCOL_HOB), // Hob size
288 EFI_PEI_PE_COFF_LOADER_GUID,
291 { // Pointer to EfiDecompress
292 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
293 sizeof (PROTOCOL_HOB), // Hob size
295 EFI_DECOMPRESS_PROTOCOL_GUID,
298 { // Pointer to TianoDecompress
299 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
300 sizeof (PROTOCOL_HOB), // Hob size
302 EFI_TIANO_DECOMPRESS_PROTOCOL_GUID,
306 { // Pointer to ReportStatusCode
307 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
308 sizeof (PROTOCOL_HOB
), // Hob size
310 EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID
,
313 { // EFILDR Memory Descriptor
314 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
315 sizeof (MEMORY_DESC_HOB
), // Hob size
317 EFI_LDR_MEMORY_DESCRIPTOR_GUID
,
321 { // Pci Express Base Address Hob
322 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
323 sizeof (PCI_EXPRESS_BASE_HOB
), // Hob size
325 EFI_PCI_EXPRESS_BASE_ADDRESS_GUID
,
332 { // Acpi Description Hob
333 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
334 sizeof (ACPI_DESCRIPTION_HOB
), // Hob size
336 EFI_ACPI_DESCRIPTION_GUID
,
341 { // NV Storage FV Resource
343 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, // HobType
344 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR
), // HobLength
350 EFI_RESOURCE_FIRMWARE_DEVICE
, // ResourceType
351 (EFI_RESOURCE_ATTRIBUTE_PRESENT
|
352 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
353 EFI_RESOURCE_ATTRIBUTE_TESTED
|
354 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
), // ResourceAttribute
355 0, // PhysicalStart (Fixed later)
356 NV_STORAGE_FVB_SIZE
// ResourceLength
358 { // FVB holding NV Storage
359 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
362 EFI_FLASH_MAP_HOB_GUID
,
364 0, 0, 0, // Reserved[3]
365 EFI_FLASH_AREA_GUID_DEFINED
, // AreaType
366 EFI_SYSTEM_NV_DATA_HOB_GUID
, // AreaTypeGuid
369 EFI_FLASH_AREA_FV
| EFI_FLASH_AREA_MEMMAPPED_FV
, // SubAreaData.Attributes
370 0, // SubAreaData.Reserved
371 0, // SubAreaData.Base (Fixed later)
372 NV_STORAGE_FVB_SIZE
, // SubAreaData.Length
373 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
375 0, // VolumeSignature (Fixed later)
376 NV_STORAGE_FILE_PATH
, // Mapped file without padding
377 // TotalFVBSize = FileSize + PaddingSize = multiple of BLOCK_SIZE
378 NV_STORAGE_SIZE
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
,
380 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
384 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
385 sizeof (FVB_HOB
), // Hob size
387 EFI_FLASH_MAP_HOB_GUID
,
389 0, 0, 0, // Reserved[3]
390 EFI_FLASH_AREA_EFI_VARIABLES
, // AreaType
391 { 0 }, // AreaTypeGuid
394 EFI_FLASH_AREA_SUBFV
| EFI_FLASH_AREA_MEMMAPPED_FV
, // SubAreaData.Attributes
395 0, // SubAreaData.Reserved
396 0, // SubAreaData.Base (Fixed later)
397 NV_STORAGE_SIZE
, // SubAreaData.Length
398 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
401 NV_STORAGE_FILE_PATH
,
406 { // FVB holding FTW spaces including Working & Spare space
407 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
410 EFI_FLASH_MAP_HOB_GUID
,
412 0, 0, 0, // Reserved[3]
413 EFI_FLASH_AREA_GUID_DEFINED
, // AreaType
414 EFI_SYSTEM_NV_DATA_HOB_GUID
, // AreaTypeGuid
417 EFI_FLASH_AREA_FV
| EFI_FLASH_AREA_MEMMAPPED_FV
, // SubAreaData.Attributes
418 0, // SubAreaData.Reserved
419 0, // SubAreaData.Base (Fixed later)
420 NV_FTW_FVB_SIZE
, // SubAreaData.Length
421 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
424 L
"", // Empty String indicates using memory
429 { // NV Ftw working Hob
430 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
431 sizeof (FVB_HOB
), // Hob size
433 EFI_FLASH_MAP_HOB_GUID
,
435 0, 0, 0, // Reserved[3]
436 EFI_FLASH_AREA_FTW_STATE
, // AreaType
437 { 0 }, // AreaTypeGuid
440 EFI_FLASH_AREA_SUBFV
| EFI_FLASH_AREA_MEMMAPPED_FV
, // SubAreaData.Attributes
441 0, // SubAreaData.Reserved
442 0, // SubAreaData.Base (Fixed later)
443 NV_FTW_WORKING_SIZE
, // SubAreaData.Length
444 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
446 0, // VolumeSignature
452 { // NV Ftw spare Hob
453 EFI_HOB_TYPE_GUID_EXTENSION
, // Hob type
454 sizeof (FVB_HOB
), // Hob size
456 EFI_FLASH_MAP_HOB_GUID
,
458 0, 0, 0, // Reserved[3]
459 EFI_FLASH_AREA_FTW_BACKUP
, // AreaType
460 { 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_FTW_SPARE_SIZE
, // SubAreaData.Length
467 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
// SubAreaData.FileSystem
476 EFI_HOB_TYPE_END_OF_HOB_LIST
, // HobType
477 sizeof (EFI_HOB_GENERIC_HEADER
), // HobLength
482 HOB_TEMPLATE
*gHob
= &gHobTemplate
;
486 IN UINTN NumberOfMemoryMapEntries
,
487 IN EFI_MEMORY_DESCRIPTOR
*EfiMemoryDescriptor
491 Update the Hob filling MemoryFreeUnder1MB, MemoryAbove1MB, MemoryAbove4GB
494 NumberOfMemoryMapEntries - Count of Memory Descriptors
495 EfiMemoryDescriptor - Point to the buffer containing NumberOfMemoryMapEntries Memory Descriptors
498 VOID * : The end address of MemoryAbove1MB (or the top free memory under 4GB)
504 // Prepare Low Memory
505 // 0x18 pages is 72 KB.
507 gHob
->MemoryFreeUnder1MB
.ResourceLength
= EFI_MEMORY_BELOW_1MB_END
- EFI_MEMORY_BELOW_1MB_START
;
508 gHob
->MemoryFreeUnder1MB
.PhysicalStart
= EFI_MEMORY_BELOW_1MB_START
;
511 // Prepare High Memory
512 // Assume Memory Map is ordered from low to high
514 gHob
->MemoryAbove1MB
.PhysicalStart
= 0;
515 gHob
->MemoryAbove1MB
.ResourceLength
= 0;
516 gHob
->MemoryAbove4GB
.PhysicalStart
= 0;
517 gHob
->MemoryAbove4GB
.ResourceLength
= 0;
519 for (Index
= 0; Index
< NumberOfMemoryMapEntries
; Index
++) {
521 // Skip regions below 1MB
523 if (EfiMemoryDescriptor
[Index
].PhysicalStart
< 0x100000) {
527 // Process regions above 1MB
529 if (EfiMemoryDescriptor
[Index
].PhysicalStart
>= 0x100000) {
530 if (EfiMemoryDescriptor
[Index
].Type
== EfiConventionalMemory
) {
531 if (gHob
->MemoryAbove1MB
.PhysicalStart
== 0) {
532 gHob
->MemoryAbove1MB
.PhysicalStart
= EfiMemoryDescriptor
[Index
].PhysicalStart
;
533 gHob
->MemoryAbove1MB
.ResourceLength
= LShiftU64 (EfiMemoryDescriptor
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
);
534 } else if (gHob
->MemoryAbove1MB
.PhysicalStart
+ gHob
->MemoryAbove1MB
.ResourceLength
== EfiMemoryDescriptor
[Index
].PhysicalStart
) {
535 gHob
->MemoryAbove1MB
.ResourceLength
+= LShiftU64 (EfiMemoryDescriptor
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
);
538 if ((EfiMemoryDescriptor
[Index
].Type
== EfiReservedMemoryType
) ||
539 (EfiMemoryDescriptor
[Index
].Type
>= EfiACPIReclaimMemory
) ) {
542 if ((EfiMemoryDescriptor
[Index
].Type
== EfiRuntimeServicesCode
) ||
543 (EfiMemoryDescriptor
[Index
].Type
== EfiRuntimeServicesData
)) {
548 // Process region above 4GB
550 if (EfiMemoryDescriptor
[Index
].PhysicalStart
>= 0x100000000LL
) {
551 if (EfiMemoryDescriptor
[Index
].Type
== EfiConventionalMemory
) {
552 if (gHob
->MemoryAbove4GB
.PhysicalStart
== 0) {
553 gHob
->MemoryAbove4GB
.PhysicalStart
= EfiMemoryDescriptor
[Index
].PhysicalStart
;
554 gHob
->MemoryAbove4GB
.ResourceLength
= LShiftU64 (EfiMemoryDescriptor
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
);
556 if (gHob
->MemoryAbove4GB
.PhysicalStart
+ gHob
->MemoryAbove4GB
.ResourceLength
==
557 EfiMemoryDescriptor
[Index
].PhysicalStart
) {
558 gHob
->MemoryAbove4GB
.ResourceLength
+= LShiftU64 (EfiMemoryDescriptor
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
);
564 if (gHob
->MemoryAbove4GB
.ResourceLength
== 0) {
566 // If there is no memory above 4GB then change the resource descriptor HOB
567 // into another type. I'm doing this as it's unclear if a resource
568 // descriptor HOB of length zero is valid. Spec does not say it's illegal,
569 // but code in EDK does not seem to handle this case.
571 gHob
->MemoryAbove4GB
.Header
.HobType
= EFI_HOB_TYPE_UNUSED
;
574 return (VOID
*)(UINTN
)(gHob
->MemoryAbove1MB
.PhysicalStart
+ gHob
->MemoryAbove1MB
.ResourceLength
);
582 gHob
->Stack
.AllocDescriptor
.MemoryLength
= EFI_MEMORY_STACK_PAGE_NUM
* EFI_PAGE_SIZE
;
583 gHob
->Stack
.AllocDescriptor
.MemoryBaseAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)StackTop
- gHob
->Stack
.AllocDescriptor
.MemoryLength
;
585 return (VOID
*)(UINTN
)gHob
->Stack
.AllocDescriptor
.MemoryBaseAddress
;
589 PrepareHobMemoryDescriptor (
590 VOID
*MemoryDescriptorTop
,
592 EFI_MEMORY_DESCRIPTOR
*MemDesc
595 gHob
->MemoryDescriptor
.MemDescCount
= MemDescCount
;
596 gHob
->MemoryDescriptor
.MemDesc
= (EFI_MEMORY_DESCRIPTOR
*)((UINTN
)MemoryDescriptorTop
- MemDescCount
* sizeof(EFI_MEMORY_DESCRIPTOR
));
598 // Make MemoryDescriptor.MemDesc page aligned
600 gHob
->MemoryDescriptor
.MemDesc
= (EFI_MEMORY_DESCRIPTOR
*)((UINTN
) gHob
->MemoryDescriptor
.MemDesc
& ~EFI_PAGE_MASK
);
602 CopyMem (gHob
->MemoryDescriptor
.MemDesc
, MemDesc
, MemDescCount
* sizeof(EFI_MEMORY_DESCRIPTOR
));
604 return gHob
->MemoryDescriptor
.MemDesc
;
613 UINTN BfvLengthPageSize
;
616 // Calculate BFV location at top of the memory region.
617 // This is like a RAM Disk. Align to page boundry.
619 BfvLengthPageSize
= EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (BfvLength
));
621 gHob
->Bfv
.BaseAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Bfv
;
622 gHob
->Bfv
.Length
= BfvLength
;
625 // Resource descriptor for the FV
627 gHob
->BfvResource
.PhysicalStart
= gHob
->Bfv
.BaseAddress
;
628 gHob
->BfvResource
.ResourceLength
= gHob
->Bfv
.Length
;
633 VOID
*DxeCoreEntryPoint
,
634 EFI_PHYSICAL_ADDRESS DxeCoreImageBase
,
638 gHob
->DxeCore
.MemoryAllocationHeader
.MemoryBaseAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)DxeCoreImageBase
;
639 gHob
->DxeCore
.MemoryAllocationHeader
.MemoryLength
= DxeCoreLength
;
640 gHob
->DxeCore
.EntryPoint
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)DxeCoreEntryPoint
;
644 PrepareHobNvStorage (
648 Initialize Block-Aligned Firmware Block.
651 +-------------------+
653 +-------------------+
655 |VAR_STORAGE(0x4000)|
657 +-------------------+
659 +-------------------+
661 +-------------------+
665 +-------------------+
669 +-------------------+
672 static VARIABLE_STORE_HEADER VarStoreHeader
= {
673 VARIABLE_STORE_SIGNATURE
,
674 0xffffffff, // will be fixed in Variable driver
675 VARIABLE_STORE_FORMATTED
,
676 VARIABLE_STORE_HEALTHY
,
681 static EFI_FIRMWARE_VOLUME_HEADER NvStorageFvbHeader
= {
685 EFI_SYSTEM_NV_DATA_FV_GUID
,
688 EFI_FVB_READ_ENABLED_CAP
|
689 EFI_FVB_READ_STATUS
|
690 EFI_FVB_WRITE_ENABLED_CAP
|
691 EFI_FVB_WRITE_STATUS
|
692 EFI_FVB_ERASE_POLARITY
,
693 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
,
695 0, // ExtHeaderOffset
702 NV_STORAGE_FVB_BLOCK_NUM
,
708 static EFI_FV_BLOCK_MAP_ENTRY BlockMapEntryEnd
= {0, 0};
710 EFI_PHYSICAL_ADDRESS StorageFvbBase
;
711 EFI_PHYSICAL_ADDRESS FtwFvbBase
;
718 // Use first 16-byte Reset Vector of FVB to store extra information
719 // UINT32 Offset 0 stores the volume signature
720 // UINT8 Offset 4 : should init the Variable Store Header if non-zero
722 gHob
->NvStorageFvb
.FvbInfo
.VolumeId
= *(UINT32
*) (UINTN
) (NV_STORAGE_STATE
);
723 gHob
->NvStorage
. FvbInfo
.VolumeId
= *(UINT32
*) (UINTN
) (NV_STORAGE_STATE
);
726 // *(NV_STORAGE_STATE + 4):
728 // 1 - File not exist
729 // 0 - File exist with correct size
731 if (*(UINT8
*) (UINTN
) (NV_STORAGE_STATE
+ 4) == 2) {
733 PrintString ("Error: Size of Efivar.bin should be 16k!\n");
737 if (*(UINT8
*) (UINTN
) (NV_STORAGE_STATE
+ 4) != 0) {
739 // Efivar.bin doesn't exist
740 // 1. Init variable storage header to valid header
743 (VOID
*) (UINTN
) NV_STORAGE_START
,
745 sizeof (VARIABLE_STORE_HEADER
)
748 // 2. set all bits in variable storage body to 1
751 (VOID
*) (UINTN
) (NV_STORAGE_START
+ sizeof (VARIABLE_STORE_HEADER
)),
752 NV_STORAGE_SIZE
- sizeof (VARIABLE_STORE_HEADER
),
758 // Relocate variable storage
760 // 1. Init FVB Header to valid header: First 0x48 bytes
761 // In real platform, these fields are fixed by tools
766 Ptr
= (UINT16
*) &NvStorageFvbHeader
;
767 Ptr
< (UINT16
*) ((UINTN
) (UINT8
*) &NvStorageFvbHeader
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
770 Checksum
= (UINT16
) (Checksum
+ (*Ptr
));
772 NvStorageFvbHeader
.Checksum
= (UINT16
) (0x10000 - Checksum
);
773 StorageFvbBase
= (EFI_PHYSICAL_ADDRESS
)(((UINTN
)NvStorageTop
- NV_STORAGE_FVB_SIZE
- NV_FTW_FVB_SIZE
) & ~EFI_PAGE_MASK
);
774 CopyMem ((VOID
*) (UINTN
) StorageFvbBase
, &NvStorageFvbHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
776 (VOID
*) (UINTN
) (StorageFvbBase
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER
)),
778 sizeof (EFI_FV_BLOCK_MAP_ENTRY
)
782 // 2. Relocate variable data
785 (VOID
*) (UINTN
) (StorageFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
),
786 (VOID
*) (UINTN
) NV_STORAGE_START
,
791 // 3. Set the remaining memory to 0xff
794 (VOID
*) (UINTN
) (StorageFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
+ NV_STORAGE_SIZE
),
795 NV_STORAGE_FVB_SIZE
- NV_STORAGE_SIZE
- EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
,
800 // Create the FVB holding NV Storage in memory
802 gHob
->NvStorageFvResource
.PhysicalStart
=
803 gHob
->NvStorageFvb
.FvbInfo
.Entries
[0].Base
= StorageFvbBase
;
805 // Create the NV Storage Hob
807 gHob
->NvStorage
.FvbInfo
.Entries
[0].Base
= StorageFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
;
810 // Create the FVB holding FTW spaces
812 FtwFvbBase
= (EFI_PHYSICAL_ADDRESS
)((UINTN
) StorageFvbBase
+ NV_STORAGE_FVB_SIZE
);
813 gHob
->NvFtwFvb
.FvbInfo
.Entries
[0].Base
= FtwFvbBase
;
815 // Put FTW Working in front
817 gHob
->NvFtwWorking
.FvbInfo
.Entries
[0].Base
= FtwFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
;
820 // Put FTW Spare area after FTW Working area
822 gHob
->NvFtwSpare
.FvbInfo
.Entries
[0].Base
=
823 (EFI_PHYSICAL_ADDRESS
)((UINTN
) FtwFvbBase
+ EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
+ NV_FTW_WORKING_SIZE
);
825 return (VOID
*)(UINTN
)StorageFvbBase
;
834 gHob
->Phit
.EfiMemoryTop
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)MemoryTop
;
835 gHob
->Phit
.EfiMemoryBottom
= gHob
->Phit
.EfiMemoryTop
- CONSUMED_MEMORY
;
836 gHob
->Phit
.EfiFreeMemoryTop
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)FreeMemoryTop
;
837 gHob
->Phit
.EfiFreeMemoryBottom
= gHob
->Phit
.EfiMemoryBottom
+ sizeof(HOB_TEMPLATE
);
839 CopyMem ((VOID
*)(UINTN
)gHob
->Phit
.EfiMemoryBottom
, gHob
, sizeof(HOB_TEMPLATE
));
840 gHob
= (HOB_TEMPLATE
*)(UINTN
)gHob
->Phit
.EfiMemoryBottom
;
842 gHob
->Phit
.EfiEndOfHobList
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)&gHob
->EndOfHobList
;
850 EFI_CPUID_REGISTER Reg
;
851 UINT8 CpuMemoryAddrBitNumber
;
854 // Create a CPU hand-off information
856 CpuMemoryAddrBitNumber
= 36;
857 AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION
, &Reg
.RegEax
, &Reg
.RegEbx
, &Reg
.RegEcx
, &Reg
.RegEdx
);
859 if (Reg
.RegEax
>= CPUID_EXTENDED_ADD_SIZE
) {
860 AsmCpuid (CPUID_EXTENDED_ADD_SIZE
, &Reg
.RegEax
, &Reg
.RegEbx
, &Reg
.RegEcx
, &Reg
.RegEdx
);
861 CpuMemoryAddrBitNumber
= (UINT8
)(UINTN
)(Reg
.RegEax
& 0xFF);
864 gHob
->Cpu
.SizeOfMemorySpace
= CpuMemoryAddrBitNumber
;
868 CompleteHobGeneration (
872 gHob
->MemoryAllocation
.AllocDescriptor
.MemoryBaseAddress
= gHob
->Phit
.EfiFreeMemoryTop
;
874 // Reserve all the memory under Stack above FreeMemoryTop as allocated
876 gHob
->MemoryAllocation
.AllocDescriptor
.MemoryLength
= gHob
->Stack
.AllocDescriptor
.MemoryBaseAddress
- gHob
->Phit
.EfiFreeMemoryTop
;
879 // adjust Above1MB ResourceLength
881 if (gHob
->MemoryAbove1MB
.PhysicalStart
+ gHob
->MemoryAbove1MB
.ResourceLength
> gHob
->Phit
.EfiMemoryTop
) {
882 gHob
->MemoryAbove1MB
.ResourceLength
= gHob
->Phit
.EfiMemoryTop
- gHob
->MemoryAbove1MB
.PhysicalStart
;