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