Changeset 77662 in vbox for trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
- Timestamp:
- Mar 12, 2019 12:40:12 PM (6 years ago)
- Location:
- trunk/src/VBox/Devices/EFI/FirmwareNew
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/FirmwareNew
-
Property svn:mergeinfo
changed from (toggle deleted branches)
to (toggle deleted branches)/vendor/edk2/current 103735-103757,103769-103776 /vendor/edk2/current 103735-103757,103769-103776,129194-129237
-
Property svn:mergeinfo
changed from (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
r58466 r77662 2 2 Save the S3 data to S3 boot script. 3 3 4 Copyright (c) 2006 - 201 4, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR> 5 5 6 6 This program and the accompanying materials … … 20 20 Data structure usage: 21 21 22 +------------------------------+<-- PcdS3BootScriptTablePrivateDataPtr 22 +------------------------------+<------- PcdS3BootScriptTablePrivateDataPtr 23 | SCRIPT_TABLE_PRIVATE_DATA | (mS3BootScriptTablePtr, Before SmmReadyToLock) 24 | TableBase |--- PcdS3BootScriptTablePrivateSmmDataPtr 25 | TableLength |--|-- (mS3BootScriptTablePtr = mS3BootScriptTableSmmPtr, After SmmReadyToLock InSmm) 26 | TableMemoryPageNumber |--|-|---- 27 | AtRuntime | | | | 28 | InSmm | | | | 29 | BootTimeScriptLength |--|-|---|--- 30 | SmmLocked | | | | | 31 | BackFromS3 | | | | | 32 +------------------------------+ | | | | 33 | | | | 34 +------------------------------+<-- | | | 35 | EFI_BOOT_SCRIPT_TABLE_HEADER | | | | 36 | TableLength |----|-- | | 37 +------------------------------+ | | | | 38 | ...... | | | | | 39 +------------------------------+<---- | | | 40 | EFI_BOOT_SCRIPT_TERMINATE | | | | 41 +------------------------------+<------ | | 42 | | 43 | | 44 mBootScriptDataBootTimeGuid LockBox: | | 45 Used to restore data after back from S3| | 46 to handle potential INSERT boot script | | 47 at runtime. | | 48 +------------------------------+ | | 49 | Boot Time Boot Script | | | 50 | Before SmmReadyToLock | | | 51 | | | | 52 | | | | 53 +------------------------------+ | | 54 | Boot Time Boot Script | | | 55 | After SmmReadyToLock InSmm | | | 56 | | | | 57 +------------------------------+<-------|--| 58 | | 59 | | 60 mBootScriptDataGuid LockBox: (IN_PLACE) | | 61 Used to restore data at S3 resume. | | 62 +------------------------------+ | | 63 | Boot Time Boot Script | | | 64 | Before SmmReadyToLock | | | 65 | | | | 66 | | | | 67 +------------------------------+ | | 68 | Boot Time Boot Script | | | 69 | After SmmReadyToLock InSmm | | | 70 | | | | 71 +------------------------------+<-------|--- 72 | Runtime Boot Script | | 73 | After SmmReadyToLock InSmm | | 74 +------------------------------+ | 75 | ...... | | 76 +------------------------------+<-------- 77 78 79 mBootScriptTableBaseGuid LockBox: (IN_PLACE) 80 +------------------------------+ 81 | mS3BootScriptTablePtr-> | 82 | TableBase | 83 +------------------------------+ 84 85 86 mBootScriptSmmPrivateDataGuid LockBox: (IN_PLACE) 87 SMM private data with BackFromS3 = TRUE 88 at runtime. S3 will help restore it to 89 tell the Library the system is back from S3. 90 +------------------------------+ 23 91 | SCRIPT_TABLE_PRIVATE_DATA | 24 | TableBase |--- 25 | TableLength |--|-- 26 | AtRuntime | | | 27 | InSmm | | | 28 +------------------------------+ | | 29 | | 30 +------------------------------+<-- | 31 | EFI_BOOT_SCRIPT_TABLE_HEADER | | 32 | TableLength |----|-- 33 +------------------------------+ | | 34 | ...... | | | 35 +------------------------------+<---- | 36 | EFI_BOOT_SCRIPT_TERMINATE | | 37 +------------------------------+<------ 92 | TableBase | 93 | TableLength | 94 | TableMemoryPageNumber | 95 | AtRuntime | 96 | InSmm | 97 | BootTimeScriptLength | 98 | SmmLocked | 99 | BackFromS3 = TRUE | 100 +------------------------------+ 38 101 39 102 **/ 40 103 41 104 SCRIPT_TABLE_PRIVATE_DATA *mS3BootScriptTablePtr; 42 EFI_EVENT mEnterRuntimeEvent; 105 43 106 // 44 // Allocate SMM copy because we can not use mS3BootScriptTablePtr when we AtRuntimein InSmm.107 // Allocate SMM copy because we can not use mS3BootScriptTablePtr after SmmReadyToLock in InSmm. 45 108 // 46 109 SCRIPT_TABLE_PRIVATE_DATA *mS3BootScriptTableSmmPtr; 47 UINTN mLockBoxLength;48 110 49 111 EFI_GUID mBootScriptDataGuid = { … … 51 113 }; 52 114 53 EFI_GUID mBootScriptData OrgGuid = {115 EFI_GUID mBootScriptDataBootTimeGuid = { 54 116 0xb5af1d7a, 0xb8cf, 0x4eb3, { 0x89, 0x25, 0xa8, 0x20, 0xe1, 0x6b, 0x68, 0x7d } 55 117 }; 56 118 57 EFI_GUID mBootScript HeaderDataGuid = {119 EFI_GUID mBootScriptTableBaseGuid = { 58 120 0x1810ab4a, 0x2314, 0x4df6, { 0x81, 0xeb, 0x67, 0xc6, 0xec, 0x5, 0x85, 0x91 } 59 121 }; 122 123 EFI_GUID mBootScriptSmmPrivateDataGuid = { 124 0x627ee2da, 0x3bf9, 0x439b, { 0x92, 0x9f, 0x2e, 0xe, 0x6e, 0x9d, 0xba, 0x62 } 125 }; 126 127 EFI_EVENT mEventDxeSmmReadyToLock = NULL; 128 VOID *mRegistrationSmmExitBootServices = NULL; 129 VOID *mRegistrationSmmLegacyBoot = NULL; 130 VOID *mRegistrationSmmReadyToLock = NULL; 131 BOOLEAN mS3BootScriptTableAllocated = FALSE; 132 BOOLEAN mS3BootScriptTableSmmAllocated = FALSE; 133 EFI_SMM_SYSTEM_TABLE2 *mBootScriptSmst = NULL; 60 134 61 135 /** … … 98 172 // 99 173 // NOTE: Here we did NOT adjust the mS3BootScriptTablePtr->TableLength to 100 // mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE). Because101 // maybe in runtime, we still need add entries into the table, and the runtime entry should be102 // a dded start before this TERMINATE node.174 // mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE). 175 // Because maybe after SmmReadyToLock, we still need add entries into the table, 176 // and the entry should be added start before this TERMINATE node. 103 177 // 104 178 } … … 106 180 /** 107 181 This function save boot script data to LockBox. 108 1. BootSriptPrivate data, BootScript data - Image and DispatchContext are handled by platform. 109 2. BootScriptExecutor, BootScriptExecutor context 110 - ACPI variable - (PI version) sould be handled by SMM driver. S3 Page table is handled here. 111 - ACPI variable - framework version is already handled by Framework CPU driver. 182 112 183 **/ 113 184 VOID … … 119 190 120 191 // 121 // mS3BootScriptTablePtr->TableLength does not include EFI_BOOT_SCRIPT_TERMINATE, because we need add entry at runtime.122 // Save all info here, just in case that no one will add boot script entry in SMM.192 // Save whole memory copy into LockBox. 193 // It will be used to restore data at S3 resume. 123 194 // 124 195 Status = SaveLockBox ( 125 196 &mBootScriptDataGuid, 126 197 (VOID *)mS3BootScriptTablePtr->TableBase, 127 mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE)198 EFI_PAGES_TO_SIZE (mS3BootScriptTablePtr->TableMemoryPageNumber) 128 199 ); 129 200 ASSERT_EFI_ERROR (Status); … … 133 204 134 205 // 135 // We need duplicate the original copy, because it may have INSERT boot script at runtime in SMM.136 // If so, we should use original copy to restore data after OS rewrites the ACPINvs region.137 // Or the data inserted may cause some original boot script data lost.138 //139 Status = SaveLockBox (140 &mBootScriptDataOrgGuid,141 (VOID *)mS3BootScriptTablePtr->TableBase,142 mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE)143 );144 ASSERT_EFI_ERROR (Status);145 146 //147 206 // Just need save TableBase. 148 207 // Do not update other field because they will NOT be used in S3. 149 208 // 150 209 Status = SaveLockBox ( 151 &mBootScript HeaderDataGuid,210 &mBootScriptTableBaseGuid, 152 211 (VOID *)&mS3BootScriptTablePtr->TableBase, 153 212 sizeof(mS3BootScriptTablePtr->TableBase) … … 155 214 ASSERT_EFI_ERROR (Status); 156 215 157 Status = SetLockBoxAttributes (&mBootScript HeaderDataGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);216 Status = SetLockBoxAttributes (&mBootScriptTableBaseGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); 158 217 ASSERT_EFI_ERROR (Status); 159 218 } … … 161 220 /** 162 221 This is the Event call back function to notify the Library the system is entering 163 run timephase.222 SmmLocked phase. 164 223 165 224 @param Event Pointer to this event … … 190 249 191 250 // 192 // Here we should tell the library that we are enter into runtime phase. and193 // the memory page number occupied by the table should not grow anymore.194 // 195 if (!mS3BootScriptTablePtr-> AtRuntime) {251 // Here we should tell the library that we are entering SmmLocked phase. 252 // and the memory page number occupied by the table should not grow anymore. 253 // 254 if (!mS3BootScriptTablePtr->SmmLocked) { 196 255 // 197 // In boot time, we need not write the terminate node when adding a node to boot scipt table198 // or else, that will impact the performance. However, in runtime, we should append terminate199 // node on every add to boot script table 256 // Before SmmReadyToLock, we need not write the terminate node when adding a node to boot scipt table 257 // or else, that will impact the performance. However, after SmmReadyToLock, we should append terminate 258 // node on every add to boot script table. 200 259 // 201 260 S3BootScriptInternalCloseTable (); 202 mS3BootScriptTablePtr-> AtRuntime= TRUE;261 mS3BootScriptTablePtr->SmmLocked = TRUE; 203 262 204 263 // … … 208 267 } 209 268 } 210 /** 211 This is the Event call back function is triggered in SMM to notify the Library the system is entering 212 run time phase and set InSmm flag. 269 270 /** 271 This is the Event call back function is triggered in SMM to notify the Library 272 the system is entering SmmLocked phase and set InSmm flag. 213 273 214 274 @param Protocol Points to the protocol's unique identifier … … 234 294 235 295 // 236 // Last chance to call-out, just make sure AtRuntime is set296 // Last chance to call-out, just make sure SmmLocked is set. 237 297 // 238 298 S3BootScriptEventCallBack (NULL, NULL); … … 243 303 if (mS3BootScriptTableSmmPtr->TableBase == NULL) { 244 304 CopyMem (mS3BootScriptTableSmmPtr, mS3BootScriptTablePtr, sizeof(*mS3BootScriptTablePtr)); 245 } 246 // 247 // We should not use ACPINvs copy, because it is not safe. 305 306 // 307 // Set InSmm, we allow boot script update when InSmm, but not allow boot script outside SMM. 308 // InSmm will only be checked if SmmLocked is TRUE. 309 // 310 mS3BootScriptTableSmmPtr->InSmm = TRUE; 311 } 312 // 313 // We should not use ACPI Reserved copy, because it is not safe. 248 314 // 249 315 mS3BootScriptTablePtr = mS3BootScriptTableSmmPtr; 250 316 251 // 252 // Set InSmm, we allow boot script update when InSmm, but not allow boot script outside SMM. 253 // InSmm will only be checked if AtRuntime is TRUE. 254 // 255 mS3BootScriptTablePtr->InSmm = TRUE; 256 257 // 258 // Record LockBoxLength 259 // 260 mLockBoxLength = mS3BootScriptTableSmmPtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE); 317 return EFI_SUCCESS; 318 } 319 320 /** 321 This function is to save boot time boot script data to LockBox. 322 323 Because there may be INSERT boot script at runtime in SMM. 324 The boot time copy will be used to restore data after back from S3. 325 Otherwise the data inserted may cause some boot time boot script data lost 326 if only BootScriptData used. 327 328 **/ 329 VOID 330 SaveBootTimeDataToLockBox ( 331 VOID 332 ) 333 { 334 EFI_STATUS Status; 335 336 // 337 // ACPI Reserved copy is not safe, restore from BootScriptData LockBox first, 338 // and then save the data to BootScriptDataBootTime LockBox. 339 // 340 Status = RestoreLockBox ( 341 &mBootScriptDataGuid, 342 NULL, 343 NULL 344 ); 345 ASSERT_EFI_ERROR (Status); 346 347 // 348 // Save BootScriptDataBootTime 349 // It will be used to restore data after back from S3. 350 // 351 Status = SaveLockBox ( 352 &mBootScriptDataBootTimeGuid, 353 (VOID *) mS3BootScriptTablePtr->TableBase, 354 mS3BootScriptTablePtr->BootTimeScriptLength 355 ); 356 ASSERT_EFI_ERROR (Status); 357 } 358 359 /** 360 This function save boot script SMM private data to LockBox with BackFromS3 = TRUE at runtime. 361 S3 resume will help restore it to tell the Library the system is back from S3. 362 363 **/ 364 VOID 365 SaveSmmPriviateDataToLockBoxAtRuntime ( 366 VOID 367 ) 368 { 369 EFI_STATUS Status; 370 371 // 372 // Save boot script SMM private data with BackFromS3 = TRUE. 373 // 374 mS3BootScriptTablePtr->BackFromS3 = TRUE; 375 Status = SaveLockBox ( 376 &mBootScriptSmmPrivateDataGuid, 377 (VOID *) mS3BootScriptTablePtr, 378 sizeof (SCRIPT_TABLE_PRIVATE_DATA) 379 ); 380 ASSERT_EFI_ERROR (Status); 381 382 Status = SetLockBoxAttributes (&mBootScriptSmmPrivateDataGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); 383 ASSERT_EFI_ERROR (Status); 384 385 // 386 // Set BackFromS3 flag back to FALSE to indicate that now is not back from S3. 387 // 388 mS3BootScriptTablePtr->BackFromS3 = FALSE; 389 } 390 391 /** 392 This is the Event call back function is triggered in SMM to notify the Library 393 the system is entering runtime phase. 394 395 @param[in] Protocol Points to the protocol's unique identifier 396 @param[in] Interface Points to the interface instance 397 @param[in] Handle The handle on which the interface was installed 398 399 @retval EFI_SUCCESS SmmAtRuntimeCallBack runs successfully 400 **/ 401 EFI_STATUS 402 EFIAPI 403 S3BootScriptSmmAtRuntimeCallBack ( 404 IN CONST EFI_GUID *Protocol, 405 IN VOID *Interface, 406 IN EFI_HANDLE Handle 407 ) 408 { 409 if (!mS3BootScriptTablePtr->AtRuntime) { 410 mS3BootScriptTablePtr->BootTimeScriptLength = (UINT32) (mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE)); 411 SaveBootTimeDataToLockBox (); 412 413 mS3BootScriptTablePtr->AtRuntime = TRUE; 414 SaveSmmPriviateDataToLockBoxAtRuntime (); 415 } 261 416 262 417 return EFI_SUCCESS; … … 271 426 @param SystemTable A pointer to the EFI System Table. 272 427 273 @retval RETURN_SUCCESS Allocate the global memory space to store S3 boot script table private data274 @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated. 428 @retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS. 429 275 430 **/ 276 431 RETURN_STATUS … … 287 442 EFI_SMM_BASE2_PROTOCOL *SmmBase2; 288 443 BOOLEAN InSmm; 289 EFI_SMM_SYSTEM_TABLE2 *Smst;290 444 EFI_PHYSICAL_ADDRESS Buffer; 291 445 … … 298 452 Status = gBS->AllocatePages ( 299 453 AllocateMaxAddress, 300 Efi ACPIMemoryNVS,454 EfiReservedMemoryType, 301 455 EFI_SIZE_TO_PAGES(sizeof(SCRIPT_TABLE_PRIVATE_DATA)), 302 456 &Buffer 303 457 ); 304 if (EFI_ERROR (Status)) { 305 return RETURN_OUT_OF_RESOURCES; 306 } 458 ASSERT_EFI_ERROR (Status); 459 mS3BootScriptTableAllocated = TRUE; 307 460 S3TablePtr = (VOID *) (UINTN) Buffer; 308 461 309 PcdSet64 (PcdS3BootScriptTablePrivateDataPtr, (UINT64) (UINTN)S3TablePtr); 462 Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, (UINT64) (UINTN)S3TablePtr); 463 ASSERT_EFI_ERROR (Status); 310 464 ZeroMem (S3TablePtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA)); 311 465 // 312 // create event to notify the library system enter the runtime phase466 // Create event to notify the library system enter the SmmLocked phase. 313 467 // 314 mE nterRuntimeEvent = EfiCreateProtocolNotifyEvent(315 &gEfiDxeSmmReadyToLockProtocolGuid,316 TPL_CALLBACK,317 S3BootScriptEventCallBack,318 NULL,319 &Registration320 );321 ASSERT (mE nterRuntimeEvent!= NULL);468 mEventDxeSmmReadyToLock = EfiCreateProtocolNotifyEvent ( 469 &gEfiDxeSmmReadyToLockProtocolGuid, 470 TPL_CALLBACK, 471 S3BootScriptEventCallBack, 472 NULL, 473 &Registration 474 ); 475 ASSERT (mEventDxeSmmReadyToLock != NULL); 322 476 } 323 477 mS3BootScriptTablePtr = S3TablePtr; … … 340 494 // Good, we are in SMM 341 495 // 342 Status = SmmBase2->GetSmstLocation (SmmBase2, & Smst);496 Status = SmmBase2->GetSmstLocation (SmmBase2, &mBootScriptSmst); 343 497 if (EFI_ERROR (Status)) { 344 498 return RETURN_SUCCESS; … … 350 504 // 351 505 if (S3TableSmmPtr == 0) { 352 Status = Smst->SmmAllocatePool ( 353 EfiRuntimeServicesData, 354 sizeof(SCRIPT_TABLE_PRIVATE_DATA), 355 (VOID **) &S3TableSmmPtr 356 ); 357 if (EFI_ERROR (Status)) { 358 return RETURN_OUT_OF_RESOURCES; 506 Status = mBootScriptSmst->SmmAllocatePool ( 507 EfiRuntimeServicesData, 508 sizeof(SCRIPT_TABLE_PRIVATE_DATA), 509 (VOID **) &S3TableSmmPtr 510 ); 511 ASSERT_EFI_ERROR (Status); 512 mS3BootScriptTableSmmAllocated = TRUE; 513 514 Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, (UINT64) (UINTN)S3TableSmmPtr); 515 ASSERT_EFI_ERROR (Status); 516 ZeroMem (S3TableSmmPtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA)); 517 518 // 519 // Register SmmExitBootServices and SmmLegacyBoot notification. 520 // 521 Status = mBootScriptSmst->SmmRegisterProtocolNotify ( 522 &gEdkiiSmmExitBootServicesProtocolGuid, 523 S3BootScriptSmmAtRuntimeCallBack, 524 &mRegistrationSmmExitBootServices 525 ); 526 ASSERT_EFI_ERROR (Status); 527 528 Status = mBootScriptSmst->SmmRegisterProtocolNotify ( 529 &gEdkiiSmmLegacyBootProtocolGuid, 530 S3BootScriptSmmAtRuntimeCallBack, 531 &mRegistrationSmmLegacyBoot 532 ); 533 ASSERT_EFI_ERROR (Status); 534 } 535 mS3BootScriptTableSmmPtr = S3TableSmmPtr; 536 537 // 538 // Register SmmReadyToLock notification. 539 // 540 Status = mBootScriptSmst->SmmRegisterProtocolNotify ( 541 &gEfiSmmReadyToLockProtocolGuid, 542 S3BootScriptSmmEventCallBack, 543 &mRegistrationSmmReadyToLock 544 ); 545 ASSERT_EFI_ERROR (Status); 546 547 return RETURN_SUCCESS; 548 } 549 550 /** 551 Library Destructor to free the resources allocated by 552 S3BootScriptLibInitialize() and unregister callbacks. 553 554 NOTICE: The destructor doesn't support unloading as a separate action, and it 555 only supports unloading if the containing driver's entry point function fails. 556 557 @param ImageHandle The firmware allocated handle for the EFI image. 558 @param SystemTable A pointer to the EFI System Table. 559 560 @retval RETURN_SUCCESS The destructor always returns RETURN_SUCCESS. 561 562 **/ 563 RETURN_STATUS 564 EFIAPI 565 S3BootScriptLibDeinitialize ( 566 IN EFI_HANDLE ImageHandle, 567 IN EFI_SYSTEM_TABLE *SystemTable 568 ) 569 { 570 EFI_STATUS Status; 571 572 DEBUG ((EFI_D_INFO, "%a() in %a module\n", __FUNCTION__, gEfiCallerBaseName)); 573 574 if (mEventDxeSmmReadyToLock != NULL) { 575 // 576 // Close the DxeSmmReadyToLock event. 577 // 578 Status = gBS->CloseEvent (mEventDxeSmmReadyToLock); 579 ASSERT_EFI_ERROR (Status); 580 } 581 582 if (mBootScriptSmst != NULL) { 583 if (mRegistrationSmmExitBootServices != NULL) { 584 // 585 // Unregister SmmExitBootServices notification. 586 // 587 Status = mBootScriptSmst->SmmRegisterProtocolNotify ( 588 &gEdkiiSmmExitBootServicesProtocolGuid, 589 NULL, 590 &mRegistrationSmmExitBootServices 591 ); 592 ASSERT_EFI_ERROR (Status); 359 593 } 360 361 PcdSet64 (PcdS3BootScriptTablePrivateSmmDataPtr, (UINT64) (UINTN)S3TableSmmPtr); 362 ZeroMem (S3TableSmmPtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA)); 363 } 364 mS3BootScriptTableSmmPtr = S3TableSmmPtr; 365 366 // 367 // Then register event after lock 368 // 369 Registration = NULL; 370 Status = Smst->SmmRegisterProtocolNotify ( 371 &gEfiSmmReadyToLockProtocolGuid, 372 S3BootScriptSmmEventCallBack, 373 &Registration 374 ); 375 ASSERT_EFI_ERROR (Status); 594 if (mRegistrationSmmLegacyBoot != NULL) { 595 // 596 // Unregister SmmLegacyBoot notification. 597 // 598 Status = mBootScriptSmst->SmmRegisterProtocolNotify ( 599 &gEdkiiSmmLegacyBootProtocolGuid, 600 NULL, 601 &mRegistrationSmmLegacyBoot 602 ); 603 ASSERT_EFI_ERROR (Status); 604 } 605 if (mRegistrationSmmReadyToLock != NULL) { 606 // 607 // Unregister SmmReadyToLock notification. 608 // 609 Status = mBootScriptSmst->SmmRegisterProtocolNotify ( 610 &gEfiSmmReadyToLockProtocolGuid, 611 NULL, 612 &mRegistrationSmmReadyToLock 613 ); 614 ASSERT_EFI_ERROR (Status); 615 } 616 } 617 618 // 619 // Free the resources allocated and set PCDs to 0. 620 // 621 if (mS3BootScriptTableAllocated) { 622 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) mS3BootScriptTablePtr, EFI_SIZE_TO_PAGES(sizeof(SCRIPT_TABLE_PRIVATE_DATA))); 623 ASSERT_EFI_ERROR (Status); 624 Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, 0); 625 ASSERT_EFI_ERROR (Status); 626 } 627 if ((mBootScriptSmst != NULL) && mS3BootScriptTableSmmAllocated) { 628 Status = mBootScriptSmst->SmmFreePool (mS3BootScriptTableSmmPtr); 629 ASSERT_EFI_ERROR (Status); 630 Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, 0); 631 ASSERT_EFI_ERROR (Status); 632 } 376 633 377 634 return RETURN_SUCCESS; 378 635 } 636 379 637 /** 380 638 To get the start address from which a new boot time s3 boot script entry will write into. … … 402 660 S3TableBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(mS3BootScriptTablePtr->TableBase); 403 661 if (S3TableBase == 0) { 662 // 404 663 // The table is not exist. This is the first to add entry. 405 // Allocate ACPI script table space under 4G memory. We need it to save 406 // some settings done by CSM, which runs after normal script table closed 664 // Allocate ACPI script table space under 4G memory. 407 665 // 408 666 S3TableBase = 0xffffffff; 409 667 Status = gBS->AllocatePages ( 410 668 AllocateMaxAddress, 411 Efi ACPIMemoryNVS,669 EfiReservedMemoryType, 412 670 2 + PcdGet16(PcdS3BootScriptRuntimeTableReservePageNumber), 413 671 (EFI_PHYSICAL_ADDRESS*)&S3TableBase … … 424 682 ScriptTableInfo->OpCode = S3_BOOT_SCRIPT_LIB_TABLE_OPCODE; 425 683 ScriptTableInfo->Length = (UINT8) sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER); 684 ScriptTableInfo->Version = BOOT_SCRIPT_TABLE_VERSION; 426 685 ScriptTableInfo->TableLength = 0; // will be calculate at CloseTable 427 686 mS3BootScriptTablePtr->TableLength = sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER); … … 431 690 432 691 // Here we do not count the reserved memory for runtime script table. 433 PageNumber = (UINT16)(mS3BootScriptTablePtr->TableMemoryPageNumber - PcdGet16(PcdS3BootScriptRuntimeTableReservePageNumber));692 PageNumber = (UINT16) (mS3BootScriptTablePtr->TableMemoryPageNumber - PcdGet16(PcdS3BootScriptRuntimeTableReservePageNumber)); 434 693 TableLength = mS3BootScriptTablePtr->TableLength; 435 if ( (UINT32)(PageNumber * EFI_PAGE_SIZE) < (TableLength + EntryLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE))) {694 if (EFI_PAGES_TO_SIZE ((UINTN) PageNumber) < (TableLength + EntryLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE))) { 436 695 // 437 696 // The buffer is too small to hold the table, Reallocate the buffer … … 440 699 Status = gBS->AllocatePages ( 441 700 AllocateMaxAddress, 442 Efi ACPIMemoryNVS,701 EfiReservedMemoryType, 443 702 2 + PageNumber + PcdGet16(PcdS3BootScriptRuntimeTableReservePageNumber), 444 703 (EFI_PHYSICAL_ADDRESS*)&NewS3TableBase … … 476 735 } 477 736 /** 478 To get the start address from which a new runtime s3 boot script entry will write into.737 To get the start address from which a new runtime(after SmmReadyToLock) s3 boot script entry will write into. 479 738 In this case, it should be ensured that there is enough buffer to hold the entry. 480 739 481 740 @param EntryLength the new entry length. 482 741 483 @retval the address from which the a new s3 runtime script entry will write into742 @retval the address from which the a new s3 runtime(after SmmReadyToLock) script entry will write into 484 743 **/ 485 744 UINT8* … … 494 753 // Check if the memory range reserved for S3 Boot Script table is large enough to hold the node. 495 754 // 496 if ( mS3BootScriptTablePtr->TableLength + EntryLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE) <= EFI_PAGES_TO_SIZE((UINT32)(mS3BootScriptTablePtr->TableMemoryPageNumber))) {755 if ((mS3BootScriptTablePtr->TableLength + EntryLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE)) <= EFI_PAGES_TO_SIZE ((UINTN) (mS3BootScriptTablePtr->TableMemoryPageNumber))) { 497 756 NewEntryPtr = mS3BootScriptTablePtr->TableBase + mS3BootScriptTablePtr->TableLength; 498 757 mS3BootScriptTablePtr->TableLength = mS3BootScriptTablePtr->TableLength + EntryLength; … … 504 763 return (UINT8*)NewEntryPtr; 505 764 } 765 766 /** 767 This function is to restore boot time boot script data from LockBox. 768 769 **/ 770 VOID 771 RestoreBootTimeDataFromLockBox ( 772 VOID 773 ) 774 { 775 EFI_STATUS Status; 776 UINTN LockBoxLength; 777 778 // 779 // Restore boot time boot script data from LockBox. 780 // 781 LockBoxLength = mS3BootScriptTablePtr->BootTimeScriptLength; 782 Status = RestoreLockBox ( 783 &mBootScriptDataBootTimeGuid, 784 (VOID *) mS3BootScriptTablePtr->TableBase, 785 &LockBoxLength 786 ); 787 ASSERT_EFI_ERROR (Status); 788 789 // 790 // Update the data to BootScriptData LockBox. 791 // 792 Status = UpdateLockBox ( 793 &mBootScriptDataGuid, 794 0, 795 (VOID *) mS3BootScriptTablePtr->TableBase, 796 LockBoxLength 797 ); 798 ASSERT_EFI_ERROR (Status); 799 800 // 801 // Update TableLength. 802 // 803 mS3BootScriptTablePtr->TableLength = (UINT32) (mS3BootScriptTablePtr->BootTimeScriptLength - sizeof (EFI_BOOT_SCRIPT_TERMINATE)); 804 } 805 506 806 /** 507 807 To get the start address from which a new s3 boot script entry will write into. … … 509 809 @param EntryLength the new entry length. 510 810 511 @retval the address from which the a new s3 runtimescript entry will write into811 @retval the address from which the a new s3 boot script entry will write into 512 812 **/ 513 813 UINT8* … … 517 817 { 518 818 UINT8* NewEntryPtr; 519 EFI_BOOT_SCRIPT_TABLE_HEADER TableHeader; 520 EFI_STATUS Status; 521 UINTN OrgLockBoxLength; 522 523 if (mS3BootScriptTablePtr->AtRuntime) { 819 820 if (mS3BootScriptTablePtr->SmmLocked) { 524 821 // 525 // We need check InSmm when AtRuntime, because after SmmReadyToLock, only SMM driver is allowed to write boot script.822 // We need check InSmm, because after SmmReadyToLock, only SMM driver is allowed to write boot script. 526 823 // 527 824 if (!mS3BootScriptTablePtr->InSmm) { 528 825 // 529 // Add DEBUG ERROR, so that we can find it a t boot time.530 // Do not use ASSERT, because we may have test invoke this interface.826 // Add DEBUG ERROR, so that we can find it after SmmReadyToLock. 827 // Do not use ASSERT, because we may have test to invoke this interface. 531 828 // 532 DEBUG ((EFI_D_ERROR, "FATAL ERROR: Set boot script afterReadyToLock!!!\n"));829 DEBUG ((EFI_D_ERROR, "FATAL ERROR: Set boot script outside SMM after SmmReadyToLock!!!\n")); 533 830 return NULL; 534 831 } 535 832 536 // 537 // NOTE: OS will restore ACPINvs data. After S3, the table length in mS3BootScriptTableSmmPtr (SMM) is different with 538 // table length in BootScriptTable header (ACPINvs). 539 // So here we need sync them. We choose ACPINvs table length, because we want to override the boot script saved 540 // in SMM every time. 541 // 542 ASSERT (mS3BootScriptTablePtr == mS3BootScriptTableSmmPtr); 543 CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER)); 544 if (mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE) != TableHeader.TableLength) { 833 if (mS3BootScriptTablePtr->BackFromS3) { 545 834 // 546 // Restore it to use original value 835 // Back from S3, restore boot time boot script data from LockBox 836 // and set BackFromS3 flag back to FALSE. 547 837 // 548 OrgLockBoxLength = mLockBoxLength; 549 Status = RestoreLockBox ( 550 &mBootScriptDataOrgGuid, 551 (VOID *)mS3BootScriptTablePtr->TableBase, 552 &OrgLockBoxLength 553 ); 554 ASSERT_EFI_ERROR (Status); 555 ASSERT (OrgLockBoxLength == mLockBoxLength); 556 557 // 558 // Update the current BootScriptData into LockBox as well 559 // 560 Status = UpdateLockBox ( 561 &mBootScriptDataGuid, 562 0, 563 (VOID *)mS3BootScriptTablePtr->TableBase, 564 OrgLockBoxLength 565 ); 566 ASSERT_EFI_ERROR (Status); 567 568 // 569 // NOTE: We should NOT use TableHeader.TableLength, because it is already updated to be whole length. 570 // 571 mS3BootScriptTablePtr->TableLength = (UINT32)(mLockBoxLength - sizeof(EFI_BOOT_SCRIPT_TERMINATE)); 838 RestoreBootTimeDataFromLockBox (); 839 mS3BootScriptTablePtr->BackFromS3 = FALSE; 572 840 } 573 841 574 842 NewEntryPtr = S3BootScriptGetRuntimeEntryAddAddress (EntryLength); 575 576 if (EntryLength != 0) {577 //578 // Now the length field is updated, need sync to lockbox.579 // So in S3 resume, the data can be restored correctly.580 //581 CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));582 Status = UpdateLockBox (583 &mBootScriptDataGuid,584 OFFSET_OF(EFI_BOOT_SCRIPT_TABLE_HEADER, TableLength),585 &TableHeader.TableLength,586 sizeof(TableHeader.TableLength)587 );588 ASSERT_EFI_ERROR (Status);589 }590 843 } else { 591 844 NewEntryPtr = S3BootScriptGetBootTimeEntryAddAddress (EntryLength); … … 607 860 { 608 861 EFI_STATUS Status; 609 UINTN ScriptOffset; 610 611 ScriptOffset = (UINTN) (Script - mS3BootScriptTablePtr->TableBase); 612 613 if (!mS3BootScriptTablePtr->AtRuntime || !mS3BootScriptTablePtr->InSmm || ScriptOffset >= mLockBoxLength) { 862 UINT32 ScriptOffset; 863 UINT32 TotalScriptLength; 864 865 if (!mS3BootScriptTablePtr->SmmLocked || !mS3BootScriptTablePtr->InSmm) { 614 866 // 615 // If it is not at runtime in SMM or in the range that needs to be synced in LockBox, just return. 867 // If it is not after SmmReadyToLock in SMM, 868 // just return. 616 869 // 617 870 return ; 618 871 } 872 873 ScriptOffset = (UINT32) (Script - mS3BootScriptTablePtr->TableBase); 874 875 TotalScriptLength = (UINT32) (mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE)); 619 876 620 877 // … … 626 883 ScriptOffset, 627 884 (VOID *)((UINTN)mS3BootScriptTablePtr->TableBase + ScriptOffset), 628 mLockBoxLength - ScriptOffset 885 TotalScriptLength - ScriptOffset 886 ); 887 ASSERT_EFI_ERROR (Status); 888 889 // 890 // Now the length field is updated, need sync to lockbox. 891 // So at S3 resume, the data can be restored correctly. 892 // 893 Status = UpdateLockBox ( 894 &mBootScriptDataGuid, 895 OFFSET_OF (EFI_BOOT_SCRIPT_TABLE_HEADER, TableLength), 896 &TotalScriptLength, 897 sizeof (TotalScriptLength) 629 898 ); 630 899 ASSERT_EFI_ERROR (Status); … … 649 918 650 919 If anyone does call CloseTable() on a real platform, then the caller is responsible for figuring out 651 how to get the script to run on anS3 resume because the boot script maintained by the lib will be920 how to get the script to run at S3 resume because the boot script maintained by the lib will be 652 921 destroyed. 653 922 … … 1023 1292 @retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation. 1024 1293 @retval RETURN_SUCCESS Opcode is added. 1025 @note A known Limitations in the implementation which is non-zero Segment and64bits operations are not supported.1294 @note A known Limitations in the implementation which is 64bits operations are not supported. 1026 1295 1027 1296 **/ … … 1041 1310 EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE ScriptPciWrite2; 1042 1311 1043 if (Segment != 0 || 1044 Width == S3BootScriptWidthUint64 || 1312 if (Width == S3BootScriptWidthUint64 || 1045 1313 Width == S3BootScriptWidthFifoUint64 || 1046 1314 Width == S3BootScriptWidthFillUint64) { … … 1083 1351 @retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation. 1084 1352 @retval RETURN_SUCCESS Opcode is added. 1085 @note A known Limitations in the implementation which is non-zero Segment and64bits operations are not supported.1353 @note A known Limitations in the implementation which is 64bits operations are not supported. 1086 1354 1087 1355 **/ … … 1101 1369 EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE ScriptPciReadWrite2; 1102 1370 1103 if (Segment != 0 || 1104 Width == S3BootScriptWidthUint64 || 1371 if (Width == S3BootScriptWidthUint64 || 1105 1372 Width == S3BootScriptWidthFifoUint64 || 1106 1373 Width == S3BootScriptWidthFillUint64) { … … 1406 1673 IN VOID *BitValue, 1407 1674 IN UINTN Duration, 1408 IN UINT NLoopTimes1675 IN UINT64 LoopTimes 1409 1676 ) 1410 1677 { … … 1678 1945 @retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation. 1679 1946 @retval RETURN_SUCCESS Opcode is added. 1680 @note A known Limitations in the implementation which is non-zero Segment and64bits operations are not supported.1947 @note A known Limitations in the implementation which is 64bits operations are not supported. 1681 1948 1682 1949 **/ … … 1697 1964 EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL ScriptPci2Poll; 1698 1965 1699 if (Segment != 0 || 1700 Width == S3BootScriptWidthUint64 || 1966 if (Width == S3BootScriptWidthUint64 || 1701 1967 Width == S3BootScriptWidthFifoUint64 || 1702 1968 Width == S3BootScriptWidthFillUint64) { … … 1760 2026 // 1761 2027 if (Position != NULL) { 1762 PositionOffset = (UINTN) ((UINT8 *)Position - S3TableBase);2028 PositionOffset = (UINTN)Position - (UINTN)S3TableBase; 1763 2029 1764 2030 //
Note:
See TracChangeset
for help on using the changeset viewer.