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