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 boundary.
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