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