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