EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c

Go to the documentation of this file.
00001 
00016 #include <PiSmm.h>
00017 #include <Library/SmmServicesTableLib.h>
00018 #include <Library/BaseLib.h>
00019 #include <Library/BaseMemoryLib.h>
00020 #include <Library/LockBoxLib.h>
00021 #include <Library/DebugLib.h>
00022 #include <Guid/SmmLockBox.h>
00023 
00024 #include "SmmLockBoxLibPrivate.h"
00025 
00030 SMM_LOCK_BOX_CONTEXT mSmmLockBoxContext;
00031 LIST_ENTRY           mLockBoxQueue = INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue);
00032 
00038 SMM_LOCK_BOX_CONTEXT *
00039 InternalGetSmmLockBoxContext (
00040   VOID
00041   )
00042 {
00043   UINTN   Index;
00044 
00045   //
00046   // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
00047   //
00048   for (Index = 0; Index < gSmst->NumberOfTableEntries; Index++) {
00049     if (CompareGuid (&gSmst->SmmConfigurationTable[Index].VendorGuid, &gEfiSmmLockBoxCommunicationGuid)) {
00050       //
00051       // Found. That means some other library instance is already run.
00052       // No need to install again, just return.
00053       //
00054       return (SMM_LOCK_BOX_CONTEXT *)gSmst->SmmConfigurationTable[Index].VendorTable;
00055     }
00056   }
00057 
00058   //
00059   // Not found.
00060   //
00061   return NULL;
00062 }
00063 
00074 EFI_STATUS
00075 EFIAPI
00076 SmmLockBoxSmmConstructuor (
00077   IN EFI_HANDLE        ImageHandle,
00078   IN EFI_SYSTEM_TABLE  *SystemTable
00079   )
00080 {
00081   EFI_STATUS           Status;
00082   SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;
00083 
00084   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructuor - Enter\n"));
00085 
00086   //
00087   // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
00088   //
00089   SmmLockBoxContext = InternalGetSmmLockBoxContext ();
00090   if (SmmLockBoxContext != NULL) {
00091     //
00092     // Find it. That means some other library instance is already run.
00093     // No need to install again, just return.
00094     //
00095     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - already installed\n"));
00096     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructuor - Exit\n"));
00097     return EFI_SUCCESS;
00098   }
00099 
00100   //
00101   // If no one install this, it means this is first instance. Install it.
00102   //
00103   if (sizeof(UINTN) == sizeof(UINT64)) {
00104     mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_64;
00105   } else {
00106     mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_32;
00107   }
00108   mSmmLockBoxContext.LockBoxDataAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)&mLockBoxQueue;
00109 
00110   Status = gSmst->SmmInstallConfigurationTable (
00111                     gSmst,
00112                     &gEfiSmmLockBoxCommunicationGuid,
00113                     &mSmmLockBoxContext,
00114                     sizeof(mSmmLockBoxContext)
00115                     );
00116   ASSERT_EFI_ERROR (Status);
00117 
00118   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - %x\n", (UINTN)&mSmmLockBoxContext));
00119   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib LockBoxDataAddress - %x\n", (UINTN)&mLockBoxQueue));
00120   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructuor - Exit\n"));
00121 
00122   return Status;
00123 }
00124 
00130 LIST_ENTRY *
00131 InternalGetLockBoxQueue (
00132   VOID
00133   )
00134 {
00135   SMM_LOCK_BOX_CONTEXT        *SmmLockBoxContext;
00136 
00137   SmmLockBoxContext = InternalGetSmmLockBoxContext ();
00138   ASSERT (SmmLockBoxContext != NULL);
00139   if (SmmLockBoxContext == NULL) {
00140     return NULL;
00141   }
00142   return (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;
00143 }
00144 
00152 SMM_LOCK_BOX_DATA *
00153 InternalFindLockBoxByGuid (
00154   IN EFI_GUID   *Guid
00155   )
00156 {
00157   LIST_ENTRY                    *Link;
00158   SMM_LOCK_BOX_DATA             *LockBox;
00159   LIST_ENTRY                    *LockBoxQueue;
00160 
00161   LockBoxQueue = InternalGetLockBoxQueue ();
00162   ASSERT (LockBoxQueue != NULL);
00163 
00164   for (Link = LockBoxQueue->ForwardLink;
00165        Link != LockBoxQueue;
00166        Link = Link->ForwardLink) {
00167     LockBox = BASE_CR (
00168                 Link,
00169                 SMM_LOCK_BOX_DATA,
00170                 Link
00171                 );
00172     if (CompareGuid (&LockBox->Guid, Guid)) {
00173       return LockBox;
00174     }
00175   }
00176   return NULL;
00177 }
00178 
00194 RETURN_STATUS
00195 EFIAPI
00196 SaveLockBox (
00197   IN  GUID                        *Guid,
00198   IN  VOID                        *Buffer,
00199   IN  UINTN                       Length
00200   )
00201 {
00202   SMM_LOCK_BOX_DATA           *LockBox;
00203   EFI_PHYSICAL_ADDRESS        SmramBuffer;
00204   EFI_STATUS                  Status;
00205   LIST_ENTRY                  *LockBoxQueue;
00206 
00207   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Enter\n"));
00208 
00209   //
00210   // Basic check
00211   //
00212   if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {
00213     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));
00214     return EFI_INVALID_PARAMETER;
00215   }
00216 
00217   //
00218   // Find LockBox
00219   //
00220   LockBox = InternalFindLockBoxByGuid (Guid);
00221   if (LockBox != NULL) {
00222     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_ALREADY_STARTED));
00223     return EFI_ALREADY_STARTED;
00224   }
00225 
00226   //
00227   // Allocate SMRAM buffer
00228   //
00229   Status = gSmst->SmmAllocatePages (
00230                     AllocateAnyPages,
00231                     EfiRuntimeServicesData,
00232                     EFI_SIZE_TO_PAGES (Length),
00233                     &SmramBuffer
00234                     );
00235   ASSERT_EFI_ERROR (Status);
00236   if (EFI_ERROR (Status)) {
00237     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));
00238     return EFI_OUT_OF_RESOURCES;
00239   }
00240 
00241   //
00242   // Allocate LockBox
00243   //
00244   Status = gSmst->SmmAllocatePool (
00245                     EfiRuntimeServicesData,
00246                     sizeof(*LockBox),
00247                     (VOID **)&LockBox
00248                     );
00249   ASSERT_EFI_ERROR (Status);
00250   if (EFI_ERROR (Status)) {
00251     gSmst->SmmFreePages (SmramBuffer, EFI_SIZE_TO_PAGES (Length));
00252     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));
00253     return EFI_OUT_OF_RESOURCES;
00254   }
00255 
00256   //
00257   // Save data
00258   //
00259   CopyMem ((VOID *)(UINTN)SmramBuffer, (VOID *)(UINTN)Buffer, Length);
00260 
00261   //
00262   // Insert LockBox to queue
00263   //
00264   LockBox->Signature   = SMM_LOCK_BOX_DATA_SIGNATURE;
00265   CopyMem (&LockBox->Guid, Guid, sizeof(EFI_GUID));
00266   LockBox->Buffer      = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
00267   LockBox->Length      = (UINT64)Length;
00268   LockBox->SmramBuffer = SmramBuffer;
00269   
00270   LockBoxQueue = InternalGetLockBoxQueue ();
00271   ASSERT (LockBoxQueue != NULL);
00272   InsertTailList (LockBoxQueue, &LockBox->Link);
00273 
00274   //
00275   // Done
00276   //
00277   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_SUCCESS));
00278   return EFI_SUCCESS;
00279 }
00280 
00294 RETURN_STATUS
00295 EFIAPI
00296 SetLockBoxAttributes (
00297   IN  GUID                        *Guid,
00298   IN  UINT64                      Attributes
00299   )
00300 {
00301   SMM_LOCK_BOX_DATA              *LockBox;
00302 
00303   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Enter\n"));
00304 
00305   //
00306   // Basic check
00307   //
00308   if ((Guid == NULL) ||
00309       ((Attributes & ~LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0)) {
00310     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER));
00311     return EFI_INVALID_PARAMETER;
00312   }
00313 
00314   //
00315   // Find LockBox
00316   //
00317   LockBox = InternalFindLockBoxByGuid (Guid);
00318   if (LockBox == NULL) {
00319     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_NOT_FOUND));
00320     return EFI_NOT_FOUND;
00321   }
00322 
00323   //
00324   // Update data
00325   //
00326   LockBox->Attributes = Attributes;
00327 
00328   //
00329   // Done
00330   //
00331   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_SUCCESS));
00332   return EFI_SUCCESS;
00333 }
00334 
00351 RETURN_STATUS
00352 EFIAPI
00353 UpdateLockBox (
00354   IN  GUID                        *Guid,
00355   IN  UINTN                       Offset,
00356   IN  VOID                        *Buffer,
00357   IN  UINTN                       Length
00358   )
00359 {
00360   SMM_LOCK_BOX_DATA             *LockBox;
00361 
00362   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));
00363 
00364   //
00365   // Basic check
00366   //
00367   if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {
00368     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));
00369     return EFI_INVALID_PARAMETER;
00370   }
00371 
00372   //
00373   // Find LockBox
00374   //
00375   LockBox = InternalFindLockBoxByGuid (Guid);
00376   if (LockBox == NULL) {
00377     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_NOT_FOUND));
00378     return EFI_NOT_FOUND;
00379   }
00380 
00381   //
00382   // Update data
00383   //
00384   if (LockBox->Length < Offset + Length) {
00385     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));
00386     return EFI_BUFFER_TOO_SMALL;
00387   }
00388   CopyMem ((VOID *)((UINTN)LockBox->SmramBuffer + Offset), Buffer, Length);
00389 
00390   //
00391   // Done
00392   //
00393   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_SUCCESS));
00394   return EFI_SUCCESS;
00395 }
00396 
00415 RETURN_STATUS
00416 EFIAPI
00417 RestoreLockBox (
00418   IN  GUID                        *Guid,
00419   IN  VOID                        *Buffer, OPTIONAL
00420   IN  OUT UINTN                   *Length  OPTIONAL
00421   )
00422 {
00423   SMM_LOCK_BOX_DATA              *LockBox;
00424   VOID                           *RestoreBuffer;
00425 
00426   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Enter\n"));
00427 
00428   //
00429   // Restore this, Buffer and Length MUST be both NULL or both non-NULL
00430   //
00431   if ((Guid == NULL) ||
00432       ((Buffer == NULL) && (Length != NULL)) ||
00433       ((Buffer != NULL) && (Length == NULL))) {
00434     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));
00435     return EFI_INVALID_PARAMETER;
00436   }
00437 
00438   //
00439   // Find LockBox
00440   //
00441   LockBox = InternalFindLockBoxByGuid (Guid);
00442   if (LockBox == NULL) {
00443     //
00444     // Not found
00445     //
00446     DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_NOT_FOUND));
00447     return EFI_NOT_FOUND;
00448   }
00449 
00450   //
00451   // Set RestoreBuffer
00452   //
00453   if (Buffer != NULL) {
00454     //
00455     // restore to new buffer
00456     //
00457     RestoreBuffer = Buffer;
00458   } else {
00459     //
00460     // restore to original buffer
00461     //
00462     if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) == 0) {
00463       DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_WRITE_PROTECTED));
00464       return EFI_WRITE_PROTECTED;
00465     }
00466     RestoreBuffer = (VOID *)(UINTN)LockBox->Buffer;
00467   }
00468 
00469   //
00470   // Set RestoreLength
00471   //
00472   if (Length != NULL) {
00473     if (*Length < (UINTN)LockBox->Length) {
00474       //
00475       // Input buffer is too small to hold all data.
00476       //
00477       *Length = (UINTN)LockBox->Length;
00478       DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));
00479       return EFI_BUFFER_TOO_SMALL;
00480     }
00481     *Length = (UINTN)LockBox->Length;
00482   }
00483 
00484   //
00485   // Restore data
00486   //
00487   CopyMem (RestoreBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);
00488 
00489   //
00490   // Done
00491   //
00492   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_SUCCESS));
00493   return EFI_SUCCESS;
00494 }
00495 
00503 RETURN_STATUS
00504 EFIAPI
00505 RestoreAllLockBoxInPlace (
00506   VOID
00507   )
00508 {
00509   SMM_LOCK_BOX_DATA             *LockBox;
00510   LIST_ENTRY                    *Link;
00511   LIST_ENTRY                    *LockBoxQueue;
00512 
00513   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Enter\n"));
00514 
00515   LockBoxQueue = InternalGetLockBoxQueue ();
00516   ASSERT (LockBoxQueue != NULL);
00517 
00518   //
00519   // Restore all, Buffer and Length MUST be NULL
00520   //
00521   for (Link = LockBoxQueue->ForwardLink;
00522        Link != LockBoxQueue;
00523        Link = Link->ForwardLink) {
00524     LockBox = BASE_CR (
00525                 Link,
00526                 SMM_LOCK_BOX_DATA,
00527                 Link
00528                 );
00529     if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) {
00530       //
00531       // Restore data
00532       //
00533       CopyMem ((VOID *)(UINTN)LockBox->Buffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);
00534     }
00535   }
00536   //
00537   // Done
00538   //
00539   DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Exit (%r)\n", EFI_SUCCESS));
00540   return EFI_SUCCESS;
00541 }
00542 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines