1 /*++ 2 3 Copyright (c) 2004 - 2010, 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 14 hob.c 15 16 Abstract: 17 18 Support for hob operation 19 20 --*/ 21 22 #include "Tiano.h" 23 #include "EfiDriverLib.h" 24 #include "PeiHob.h" 25 #include EFI_GUID_DEFINITION (IoBaseHob) 26 #include EFI_GUID_DEFINITION (MemoryAllocationHob) 27 28 VOID * 29 GetHob ( 30 IN UINT16 Type, 31 IN VOID *HobStart 32 ) 33 /*++ 34 35 Routine Description: 36 37 This function returns the first instance of a HOB type in a HOB list. 38 39 Arguments: 40 41 Type The HOB type to return. 42 HobStart The first HOB in the HOB list. 43 44 Returns: 45 46 HobStart There were no HOBs found with the requested type. 47 else Returns the first HOB with the matching type. 48 49 --*/ 50 { 51 EFI_PEI_HOB_POINTERS Hob; 52 53 Hob.Raw = HobStart; 54 // 55 // Return input if not found 56 // 57 if (HobStart == NULL) { 58 return HobStart; 59 } 60 61 // 62 // Parse the HOB list, stop if end of list or matching type found. 63 // 64 while (!END_OF_HOB_LIST (Hob)) { 65 66 if (Hob.Header->HobType == Type) { 67 break; 68 } 69 70 Hob.Raw = GET_NEXT_HOB (Hob); 71 } 72 73 // 74 // Return input if not found 75 // 76 if (END_OF_HOB_LIST (Hob)) { 77 return HobStart; 78 } 79 80 return (VOID *) (Hob.Raw); 81 } 82 83 UINTN 84 GetHobListSize ( 85 IN VOID *HobStart 86 ) 87 /*++ 88 89 Routine Description: 90 91 Get size of hob list. 92 93 Arguments: 94 95 HobStart - Start pointer of hob list 96 97 Returns: 98 99 Size of hob list. 100 101 --*/ 102 { 103 EFI_PEI_HOB_POINTERS Hob; 104 UINTN Size; 105 106 Hob.Raw = HobStart; 107 Size = 0; 108 109 while (Hob.Header->HobType != EFI_HOB_TYPE_END_OF_HOB_LIST) { 110 Size += Hob.Header->HobLength; 111 Hob.Raw += Hob.Header->HobLength; 112 } 113 114 Size += Hob.Header->HobLength; 115 116 return Size; 117 } 118 119 UINT32 120 GetHobVersion ( 121 IN VOID *HobStart 122 ) 123 /*++ 124 125 Routine Description: 126 127 Get hob version. 128 129 Arguments: 130 131 HobStart - Start pointer of hob list 132 133 Returns: 134 135 Hob version. 136 137 --*/ 138 { 139 EFI_PEI_HOB_POINTERS Hob; 140 141 Hob.Raw = HobStart; 142 return Hob.HandoffInformationTable->Version; 143 } 144 145 EFI_STATUS 146 GetHobBootMode ( 147 IN VOID *HobStart, 148 OUT EFI_BOOT_MODE *BootMode 149 ) 150 /*++ 151 152 Routine Description: 153 154 Get current boot mode. 155 156 Arguments: 157 158 HobStart - Start pointer of hob list 159 160 BootMode - Current boot mode recorded in PHIT hob 161 162 Returns: 163 164 EFI_NOT_FOUND - Invalid hob header 165 166 EFI_SUCCESS - Boot mode found 167 168 --*/ 169 { 170 EFI_PEI_HOB_POINTERS Hob; 171 172 Hob.Raw = HobStart; 173 if (Hob.Header->HobType != EFI_HOB_TYPE_HANDOFF) { 174 return EFI_NOT_FOUND; 175 } 176 177 *BootMode = Hob.HandoffInformationTable->BootMode; 178 return EFI_SUCCESS; 179 } 180 181 EFI_STATUS 182 GetCpuHobInfo ( 183 IN VOID *HobStart, 184 OUT UINT8 *SizeOfMemorySpace, 185 OUT UINT8 *SizeOfIoSpace 186 ) 187 /*++ 188 189 Routine Description: 190 191 Get information recorded in CPU hob (Memory space size, Io space size) 192 193 Arguments: 194 195 HobStart - Start pointer of hob list 196 197 SizeOfMemorySpace - Size of memory size 198 199 SizeOfIoSpace - Size of IO size 200 201 Returns: 202 203 EFI_NOT_FOUND - CPU hob not found 204 205 EFI_SUCCESS - CPU hob found and information got. 206 207 --*/ 208 { 209 EFI_PEI_HOB_POINTERS CpuHob; 210 211 CpuHob.Raw = HobStart; 212 CpuHob.Raw = GetHob (EFI_HOB_TYPE_CPU, CpuHob.Raw); 213 if (CpuHob.Header->HobType != EFI_HOB_TYPE_CPU) { 214 return EFI_NOT_FOUND; 215 } 216 217 *SizeOfMemorySpace = CpuHob.Cpu->SizeOfMemorySpace; 218 *SizeOfIoSpace = CpuHob.Cpu->SizeOfIoSpace; 219 return EFI_SUCCESS; 220 } 221 222 EFI_STATUS 223 GetDxeCoreHobInfo ( 224 IN VOID *HobStart, 225 OUT EFI_PHYSICAL_ADDRESS *BaseAddress, 226 OUT UINT64 *Length, 227 OUT VOID **EntryPoint, 228 OUT EFI_GUID **FileName 229 ) 230 /*++ 231 232 Routine Description: 233 234 Get memory allocation hob created for DXE core and extract its information 235 236 Arguments: 237 238 HobStart - Start pointer of the hob list 239 BaseAddress - Start address of memory allocated for DXE core 240 Length - Length of memory allocated for DXE core 241 EntryPoint - DXE core file name 242 FileName - File Name 243 244 Returns: 245 246 EFI_NOT_FOUND - DxeCoreHob not found 247 EFI_SUCCESS - DxeCoreHob found and information got 248 249 --*/ 250 { 251 EFI_PEI_HOB_POINTERS DxeCoreHob; 252 253 254 DxeCoreHob.Raw = HobStart; 255 DxeCoreHob.Raw = GetHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw); 256 while (DxeCoreHob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION && 257 !EfiCompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, 258 &gEfiHobMemeryAllocModuleGuid)) { 259 260 DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob); 261 DxeCoreHob.Raw = GetHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw); 262 263 } 264 265 if (DxeCoreHob.Header->HobType != EFI_HOB_TYPE_MEMORY_ALLOCATION) { 266 return EFI_NOT_FOUND; 267 } 268 269 *BaseAddress = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress; 270 *Length = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength; 271 *EntryPoint = (VOID *) (UINTN) DxeCoreHob.MemoryAllocationModule->EntryPoint; 272 *FileName = &DxeCoreHob.MemoryAllocationModule->ModuleName; 273 274 return EFI_SUCCESS; 275 } 276 277 EFI_STATUS 278 GetNextFirmwareVolumeHob ( 279 IN OUT VOID **HobStart, 280 OUT EFI_PHYSICAL_ADDRESS *BaseAddress, 281 OUT UINT64 *Length 282 ) 283 /*++ 284 285 Routine Description: 286 287 Get next firmware volume hob from HobStart 288 289 Arguments: 290 291 HobStart - Start pointer of hob list 292 293 BaseAddress - Start address of next firmware volume 294 295 Length - Length of next firmware volume 296 297 Returns: 298 299 EFI_NOT_FOUND - Next firmware volume not found 300 301 EFI_SUCCESS - Next firmware volume found with address information 302 303 --*/ 304 { 305 EFI_PEI_HOB_POINTERS FirmwareVolumeHob; 306 307 FirmwareVolumeHob.Raw = *HobStart; 308 if (END_OF_HOB_LIST (FirmwareVolumeHob)) { 309 return EFI_NOT_FOUND; 310 } 311 312 FirmwareVolumeHob.Raw = GetHob (EFI_HOB_TYPE_FV, *HobStart); 313 if (FirmwareVolumeHob.Header->HobType != EFI_HOB_TYPE_FV) { 314 return EFI_NOT_FOUND; 315 } 316 317 *BaseAddress = FirmwareVolumeHob.FirmwareVolume->BaseAddress; 318 *Length = FirmwareVolumeHob.FirmwareVolume->Length; 319 320 *HobStart = GET_NEXT_HOB (FirmwareVolumeHob); 321 322 return EFI_SUCCESS; 323 } 324 325 #if (PI_SPECIFICATION_VERSION >= 0x00010000) 326 EFI_STATUS 327 GetNextFirmwareVolume2Hob ( 328 IN OUT VOID **HobStart, 329 OUT EFI_PHYSICAL_ADDRESS *BaseAddress, 330 OUT UINT64 *Length, 331 OUT EFI_GUID *FileName 332 ) 333 /*++ 334 335 Routine Description: 336 337 Get next firmware volume2 hob from HobStart 338 339 Arguments: 340 341 HobStart - Start pointer of hob list 342 343 BaseAddress - Start address of next firmware volume 344 345 Length - Length of next firmware volume 346 347 Returns: 348 349 EFI_NOT_FOUND - Next firmware volume not found 350 351 EFI_SUCCESS - Next firmware volume found with address information 352 353 --*/ 354 { 355 EFI_PEI_HOB_POINTERS FirmwareVolumeHob; 356 357 FirmwareVolumeHob.Raw = *HobStart; 358 if (END_OF_HOB_LIST (FirmwareVolumeHob)) { 359 return EFI_NOT_FOUND; 360 } 361 362 FirmwareVolumeHob.Raw = GetHob (EFI_HOB_TYPE_FV2, *HobStart); 363 if (FirmwareVolumeHob.Header->HobType != EFI_HOB_TYPE_FV2) { 364 return EFI_NOT_FOUND; 365 } 366 367 *BaseAddress = FirmwareVolumeHob.FirmwareVolume2->BaseAddress; 368 *Length = FirmwareVolumeHob.FirmwareVolume2->Length; 369 EfiCommonLibCopyMem(FileName,&FirmwareVolumeHob.FirmwareVolume2->FileName,sizeof(EFI_GUID)); 370 371 *HobStart = GET_NEXT_HOB (FirmwareVolumeHob); 372 373 return EFI_SUCCESS; 374 } 375 #endif 376 377 EFI_STATUS 378 GetNextGuidHob ( 379 IN OUT VOID **HobStart, 380 IN EFI_GUID * Guid, 381 OUT VOID **Buffer, 382 OUT UINTN *BufferSize OPTIONAL 383 ) 384 /*++ 385 386 Routine Description: 387 Get the next guid hob. 388 389 Arguments: 390 HobStart A pointer to the start hob. 391 Guid A pointer to a guid. 392 Buffer A pointer to the buffer. 393 BufferSize Buffer size. 394 395 Returns: 396 Status code. 397 398 EFI_NOT_FOUND - Next Guid hob not found 399 400 EFI_SUCCESS - Next Guid hob found and data for this Guid got 401 402 EFI_INVALID_PARAMETER - invalid parameter 403 404 --*/ 405 { 406 EFI_STATUS Status; 407 EFI_PEI_HOB_POINTERS GuidHob; 408 409 if (Buffer == NULL) { 410 return EFI_INVALID_PARAMETER; 411 } 412 413 for (Status = EFI_NOT_FOUND; EFI_ERROR (Status);) { 414 415 GuidHob.Raw = *HobStart; 416 if (END_OF_HOB_LIST (GuidHob)) { 417 return EFI_NOT_FOUND; 418 } 419 420 GuidHob.Raw = GetHob (EFI_HOB_TYPE_GUID_EXTENSION, *HobStart); 421 if (GuidHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) { 422 if (EfiCompareGuid (Guid, &GuidHob.Guid->Name)) { 423 Status = EFI_SUCCESS; 424 *Buffer = (VOID *) ((UINT8 *) (&GuidHob.Guid->Name) + sizeof (EFI_GUID)); 425 if (BufferSize != NULL) { 426 *BufferSize = GuidHob.Header->HobLength - sizeof (EFI_HOB_GUID_TYPE); 427 } 428 } 429 } 430 431 *HobStart = GET_NEXT_HOB (GuidHob); 432 } 433 434 return Status; 435 } 436 437 438 #define PAL_ENTRY_HOB {0xe53cb8cc, 0xd62c, 0x4f74, {0xbd, 0xda, 0x31, 0xe5, 0x8d, 0xe5, 0x3e, 0x2}} 439 EFI_GUID gPalEntryHob = PAL_ENTRY_HOB; 440 441 EFI_STATUS 442 GetPalEntryHobInfo ( 443 IN VOID *HobStart, 444 OUT EFI_PHYSICAL_ADDRESS *PalEntry 445 ) 446 /*++ 447 448 Routine Description: 449 450 Get PAL entry from PalEntryHob 451 452 Arguments: 453 454 HobStart - Start pointer of hob list 455 456 PalEntry - Pointer to PAL entry 457 458 Returns: 459 460 Status code. 461 462 --*/ 463 { 464 VOID *Buffer; 465 UINTN BufferSize; 466 EFI_STATUS Status; 467 VOID *HobStart2; 468 469 // 470 // Initialize 'Buffer' to NULL before usage 471 // 472 Buffer = NULL; 473 HobStart2 = HobStart; 474 Status = GetNextGuidHob ( 475 &HobStart2, 476 &gPalEntryHob, 477 &Buffer, 478 &BufferSize 479 ); 480 if (EFI_ERROR (Status) || (Buffer == NULL)) { 481 // 482 // Failed to get HOB for gPalEntryHob 483 // 484 return EFI_NOT_FOUND; 485 } 486 *PalEntry = *((EFI_PHYSICAL_ADDRESS *) Buffer); 487 return EFI_SUCCESS; 488 } 489 490 491 EFI_STATUS 492 GetIoPortSpaceAddressHobInfo ( 493 IN VOID *HobStart, 494 OUT EFI_PHYSICAL_ADDRESS *IoPortSpaceAddress 495 ) 496 /*++ 497 498 Routine Description: 499 500 Get IO port space address from IoBaseHob. 501 502 Arguments: 503 504 HobStart - Start pointer of hob list 505 506 IoPortSpaceAddress - IO port space address 507 508 Returns: 509 510 Status code 511 512 --*/ 513 { 514 515 VOID *Buffer; 516 UINTN BufferSize; 517 EFI_STATUS Status; 518 VOID *HobStart2; 519 520 // 521 // Initialize 'Buffer' to NULL before usage 522 // 523 Buffer = NULL; 524 HobStart2 = HobStart; 525 Status = GetNextGuidHob ( 526 &HobStart2, 527 &gEfiIoBaseHobGuid, 528 &Buffer, 529 &BufferSize 530 ); 531 if (EFI_ERROR (Status) || (Buffer == NULL)) { 532 // 533 // Failed to get HOB for gEfiIoBaseHobGuid 534 // 535 return EFI_NOT_FOUND; 536 } 537 538 *IoPortSpaceAddress = *((EFI_PHYSICAL_ADDRESS *) Buffer); 539 return EFI_SUCCESS; 540 } 541