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