VirtualBox

Ignore:
Timestamp:
Mar 12, 2019 12:40:12 PM (6 years ago)
Author:
vboxsync
Message:

EFI: First step in UDK2018 merge. Does not build yet.

Location:
trunk/src/VBox/Devices/EFI/FirmwareNew
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/FirmwareNew

  • trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c

    r58466 r77662  
    22  Save the S3 data to S3 boot script.
    33
    4   Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
    55
    66  This program and the accompanying materials
     
    2020  Data structure usage:
    2121
    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  +------------------------------+
    2391  | 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  +------------------------------+
    38101
    39102**/
    40103
    41104SCRIPT_TABLE_PRIVATE_DATA        *mS3BootScriptTablePtr;
    42 EFI_EVENT                        mEnterRuntimeEvent;
     105
    43106//
    44 // Allocate SMM copy because we can not use mS3BootScriptTablePtr when we AtRuntime in InSmm.
     107// Allocate SMM copy because we can not use mS3BootScriptTablePtr after SmmReadyToLock in InSmm.
    45108//
    46109SCRIPT_TABLE_PRIVATE_DATA        *mS3BootScriptTableSmmPtr;
    47 UINTN                            mLockBoxLength;
    48110
    49111EFI_GUID                         mBootScriptDataGuid = {
     
    51113};
    52114
    53 EFI_GUID                         mBootScriptDataOrgGuid = {
     115EFI_GUID                         mBootScriptDataBootTimeGuid = {
    54116  0xb5af1d7a, 0xb8cf, 0x4eb3, { 0x89, 0x25, 0xa8, 0x20, 0xe1, 0x6b, 0x68, 0x7d }
    55117};
    56118
    57 EFI_GUID                         mBootScriptHeaderDataGuid = {
     119EFI_GUID                         mBootScriptTableBaseGuid = {
    58120  0x1810ab4a, 0x2314, 0x4df6, { 0x81, 0xeb, 0x67, 0xc6, 0xec, 0x5, 0x85, 0x91 }
    59121};
     122
     123EFI_GUID                         mBootScriptSmmPrivateDataGuid = {
     124  0x627ee2da, 0x3bf9, 0x439b, { 0x92, 0x9f, 0x2e, 0xe, 0x6e, 0x9d, 0xba, 0x62 }
     125};
     126
     127EFI_EVENT                        mEventDxeSmmReadyToLock = NULL;
     128VOID                             *mRegistrationSmmExitBootServices = NULL;
     129VOID                             *mRegistrationSmmLegacyBoot = NULL;
     130VOID                             *mRegistrationSmmReadyToLock = NULL;
     131BOOLEAN                          mS3BootScriptTableAllocated = FALSE;
     132BOOLEAN                          mS3BootScriptTableSmmAllocated = FALSE;
     133EFI_SMM_SYSTEM_TABLE2            *mBootScriptSmst = NULL;
    60134
    61135/**
     
    98172  //
    99173  // NOTE: Here we did NOT adjust the mS3BootScriptTablePtr->TableLength to
    100   // mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE). Because
    101   // maybe in runtime, we still need add entries into the table, and the runtime entry should be
    102   // added 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.
    103177  //
    104178}
     
    106180/**
    107181  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
    112183**/
    113184VOID
     
    119190
    120191  //
    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.
    123194  //
    124195  Status = SaveLockBox (
    125196             &mBootScriptDataGuid,
    126197             (VOID *)mS3BootScriptTablePtr->TableBase,
    127              mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE)
     198             EFI_PAGES_TO_SIZE (mS3BootScriptTablePtr->TableMemoryPageNumber)
    128199             );
    129200  ASSERT_EFI_ERROR (Status);
     
    133204
    134205  //
    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   //
    147206  // Just need save TableBase.
    148207  // Do not update other field because they will NOT be used in S3.
    149208  //
    150209  Status = SaveLockBox (
    151              &mBootScriptHeaderDataGuid,
     210             &mBootScriptTableBaseGuid,
    152211             (VOID *)&mS3BootScriptTablePtr->TableBase,
    153212             sizeof(mS3BootScriptTablePtr->TableBase)
     
    155214  ASSERT_EFI_ERROR (Status);
    156215
    157   Status = SetLockBoxAttributes (&mBootScriptHeaderDataGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
     216  Status = SetLockBoxAttributes (&mBootScriptTableBaseGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
    158217  ASSERT_EFI_ERROR (Status);
    159218}
     
    161220/**
    162221  This is the Event call back function to notify the Library the system is entering
    163   run time phase.
     222  SmmLocked phase.
    164223
    165224  @param  Event   Pointer to this event
     
    190249
    191250  //
    192   // Here we should tell the library that we are enter into runtime phase. and
    193   // 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) {
    196255    //
    197     // In boot time, we need not write the terminate node when adding a node to boot scipt table
    198     // or else, that will impact the performance. However, in runtime, we should append terminate
    199     // 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.
    200259    //
    201260    S3BootScriptInternalCloseTable ();
    202     mS3BootScriptTablePtr->AtRuntime = TRUE;
     261    mS3BootScriptTablePtr->SmmLocked = TRUE;
    203262
    204263    //
     
    208267  }
    209268}
    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.
    213273
    214274  @param  Protocol   Points to the protocol's unique identifier
     
    234294
    235295  //
    236   // Last chance to call-out, just make sure AtRuntime is set
     296  // Last chance to call-out, just make sure SmmLocked is set.
    237297  //
    238298  S3BootScriptEventCallBack (NULL, NULL);
     
    243303  if (mS3BootScriptTableSmmPtr->TableBase == NULL) {
    244304    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.
    248314  //
    249315  mS3BootScriptTablePtr = mS3BootScriptTableSmmPtr;
    250316
    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**/
     329VOID
     330SaveBootTimeDataToLockBox (
     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**/
     364VOID
     365SaveSmmPriviateDataToLockBoxAtRuntime (
     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 **/
     401EFI_STATUS
     402EFIAPI
     403S3BootScriptSmmAtRuntimeCallBack (
     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  }
    261416
    262417  return EFI_SUCCESS;
     
    271426  @param  SystemTable   A pointer to the EFI System Table.
    272427
    273   @retval  RETURN_SUCCESS            Allocate the global memory space to store S3 boot script table private data
    274   @retval  RETURN_OUT_OF_RESOURCES   No enough memory to allocated.
     428  @retval RETURN_SUCCESS    The constructor always returns RETURN_SUCCESS.
     429
    275430**/
    276431RETURN_STATUS
     
    287442  EFI_SMM_BASE2_PROTOCOL         *SmmBase2;
    288443  BOOLEAN                        InSmm;
    289   EFI_SMM_SYSTEM_TABLE2          *Smst;
    290444  EFI_PHYSICAL_ADDRESS           Buffer;
    291445
     
    298452    Status = gBS->AllocatePages (
    299453                    AllocateMaxAddress,
    300                     EfiACPIMemoryNVS,
     454                    EfiReservedMemoryType,
    301455                    EFI_SIZE_TO_PAGES(sizeof(SCRIPT_TABLE_PRIVATE_DATA)),
    302456                    &Buffer
    303457                    );
    304     if (EFI_ERROR (Status)) {
    305       return RETURN_OUT_OF_RESOURCES;
    306     }
     458    ASSERT_EFI_ERROR (Status);
     459    mS3BootScriptTableAllocated = TRUE;
    307460    S3TablePtr = (VOID *) (UINTN) Buffer;
    308461
    309     PcdSet64 (PcdS3BootScriptTablePrivateDataPtr, (UINT64) (UINTN)S3TablePtr);
     462    Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, (UINT64) (UINTN)S3TablePtr);
     463    ASSERT_EFI_ERROR (Status);
    310464    ZeroMem (S3TablePtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA));
    311465    //
    312     // create event to notify the library system enter the runtime phase
     466    // Create event to notify the library system enter the SmmLocked phase.
    313467    //
    314     mEnterRuntimeEvent = EfiCreateProtocolNotifyEvent (
    315                           &gEfiDxeSmmReadyToLockProtocolGuid,
    316                           TPL_CALLBACK,
    317                           S3BootScriptEventCallBack,
    318                           NULL,
    319                           &Registration
    320                           );
    321     ASSERT (mEnterRuntimeEvent != NULL);
     468    mEventDxeSmmReadyToLock = EfiCreateProtocolNotifyEvent (
     469                                &gEfiDxeSmmReadyToLockProtocolGuid,
     470                                TPL_CALLBACK,
     471                                S3BootScriptEventCallBack,
     472                                NULL,
     473                                &Registration
     474                                );
     475    ASSERT (mEventDxeSmmReadyToLock != NULL);
    322476  }
    323477  mS3BootScriptTablePtr = S3TablePtr;
     
    340494  // Good, we are in SMM
    341495  //
    342   Status = SmmBase2->GetSmstLocation (SmmBase2, &Smst);
     496  Status = SmmBase2->GetSmstLocation (SmmBase2, &mBootScriptSmst);
    343497  if (EFI_ERROR (Status)) {
    344498    return RETURN_SUCCESS;
     
    350504  //
    351505  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**/
     563RETURN_STATUS
     564EFIAPI
     565S3BootScriptLibDeinitialize (
     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);
    359593    }
    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  }
    376633
    377634  return RETURN_SUCCESS;
    378635}
     636
    379637/**
    380638  To get the start address from which a new boot time s3 boot script entry will write into.
     
    402660   S3TableBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(mS3BootScriptTablePtr->TableBase);
    403661   if (S3TableBase == 0) {
     662     //
    404663     // 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.
    407665     //
    408666     S3TableBase = 0xffffffff;
    409667     Status = gBS->AllocatePages (
    410668                  AllocateMaxAddress,
    411                   EfiACPIMemoryNVS,
     669                  EfiReservedMemoryType,
    412670                  2 + PcdGet16(PcdS3BootScriptRuntimeTableReservePageNumber),
    413671                  (EFI_PHYSICAL_ADDRESS*)&S3TableBase
     
    424682     ScriptTableInfo->OpCode      = S3_BOOT_SCRIPT_LIB_TABLE_OPCODE;
    425683     ScriptTableInfo->Length      = (UINT8) sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
     684     ScriptTableInfo->Version     = BOOT_SCRIPT_TABLE_VERSION;
    426685     ScriptTableInfo->TableLength = 0;   // will be calculate at CloseTable
    427686     mS3BootScriptTablePtr->TableLength = sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
     
    431690
    432691   // 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));
    434693   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))) {
    436695     //
    437696     // The buffer is too small to hold the table, Reallocate the buffer
     
    440699     Status = gBS->AllocatePages (
    441700                  AllocateMaxAddress,
    442                   EfiACPIMemoryNVS,
     701                  EfiReservedMemoryType,
    443702                  2 + PageNumber + PcdGet16(PcdS3BootScriptRuntimeTableReservePageNumber),
    444703                  (EFI_PHYSICAL_ADDRESS*)&NewS3TableBase
     
    476735}
    477736/**
    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.
    479738  In this case, it should be ensured that there is enough buffer to hold the entry.
    480739
    481740  @param EntryLength      the new entry length.
    482741
    483   @retval the address from which the a new s3 runtime script entry will write into
     742  @retval the address from which the a new s3 runtime(after SmmReadyToLock) script entry will write into
    484743 **/
    485744UINT8*
     
    494753   // Check if the memory range reserved for S3 Boot Script table is large enough to hold the node.
    495754   //
    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))) {
    497756     NewEntryPtr = mS3BootScriptTablePtr->TableBase + mS3BootScriptTablePtr->TableLength;
    498757     mS3BootScriptTablePtr->TableLength = mS3BootScriptTablePtr->TableLength + EntryLength;
     
    504763   return (UINT8*)NewEntryPtr;
    505764}
     765
     766/**
     767  This function is to restore boot time boot script data from LockBox.
     768
     769**/
     770VOID
     771RestoreBootTimeDataFromLockBox (
     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
    506806/**
    507807  To get the start address from which a new s3 boot script entry will write into.
     
    509809  @param EntryLength      the new entry length.
    510810
    511   @retval the address from which the a new s3 runtime script entry will write into
     811  @retval the address from which the a new s3 boot script entry will write into
    512812 **/
    513813UINT8*
     
    517817{
    518818  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) {
    524821    //
    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.
    526823    //
    527824    if (!mS3BootScriptTablePtr->InSmm) {
    528825      //
    529       // Add DEBUG ERROR, so that we can find it at 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.
    531828      //
    532       DEBUG ((EFI_D_ERROR, "FATAL ERROR: Set boot script after ReadyToLock!!!\n"));
     829      DEBUG ((EFI_D_ERROR, "FATAL ERROR: Set boot script outside SMM after SmmReadyToLock!!!\n"));
    533830      return NULL;
    534831    }
    535832
    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) {
    545834      //
    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.
    547837      //
    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;
    572840    }
    573841
    574842    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     }
    590843  } else {
    591844    NewEntryPtr  = S3BootScriptGetBootTimeEntryAddAddress (EntryLength);
     
    607860{
    608861  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) {
    614866    //
    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.
    616869    //
    617870    return ;
    618871  }
     872
     873  ScriptOffset = (UINT32) (Script - mS3BootScriptTablePtr->TableBase);
     874
     875  TotalScriptLength = (UINT32) (mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE));
    619876
    620877  //
     
    626883             ScriptOffset,
    627884             (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)
    629898             );
    630899  ASSERT_EFI_ERROR (Status);
     
    649918
    650919  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 an S3 resume because the boot script maintained by the lib will be
     920  how to get the script to run at S3 resume because the boot script maintained by the lib will be
    652921  destroyed.
    653922
     
    10231292  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
    10241293  @retval RETURN_SUCCESS           Opcode is added.
    1025   @note  A known Limitations in the implementation which is non-zero Segment and 64bits operations are not supported.
     1294  @note  A known Limitations in the implementation which is 64bits operations are not supported.
    10261295
    10271296**/
     
    10411310  EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE  ScriptPciWrite2;
    10421311
    1043   if (Segment != 0 ||
    1044       Width == S3BootScriptWidthUint64 ||
     1312  if (Width == S3BootScriptWidthUint64 ||
    10451313      Width == S3BootScriptWidthFifoUint64 ||
    10461314      Width == S3BootScriptWidthFillUint64) {
     
    10831351  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
    10841352  @retval RETURN_SUCCESS           Opcode is added.
    1085   @note  A known Limitations in the implementation which is non-zero Segment and 64bits operations are not supported.
     1353  @note  A known Limitations in the implementation which is 64bits operations are not supported.
    10861354
    10871355**/
     
    11011369  EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE  ScriptPciReadWrite2;
    11021370
    1103   if (Segment != 0 ||
    1104       Width == S3BootScriptWidthUint64 ||
     1371  if (Width == S3BootScriptWidthUint64 ||
    11051372      Width == S3BootScriptWidthFifoUint64 ||
    11061373      Width == S3BootScriptWidthFillUint64) {
     
    14061673  IN  VOID                              *BitValue,
    14071674  IN  UINTN                             Duration,
    1408   IN  UINTN                             LoopTimes
     1675  IN  UINT64                            LoopTimes
    14091676  )
    14101677{
     
    16781945 @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
    16791946 @retval RETURN_SUCCESS           Opcode is added.
    1680   @note  A known Limitations in the implementation which is non-zero Segment and 64bits operations are not supported.
     1947  @note  A known Limitations in the implementation which is 64bits operations are not supported.
    16811948
    16821949**/
     
    16971964  EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL  ScriptPci2Poll;
    16981965
    1699   if (Segment != 0 ||
    1700       Width == S3BootScriptWidthUint64 ||
     1966  if (Width == S3BootScriptWidthUint64 ||
    17011967      Width == S3BootScriptWidthFifoUint64 ||
    17021968      Width == S3BootScriptWidthFillUint64) {
     
    17602026   //
    17612027   if (Position != NULL) {
    1762      PositionOffset = (UINTN) ((UINT8 *)Position - S3TableBase);
     2028     PositionOffset = (UINTN)Position - (UINTN)S3TableBase;
    17632029
    17642030     //
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette