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