]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
Add missing braces around initializer.
[mirror_edk2.git] / MdeModulePkg / Library / PiDxeS3BootScriptLib / BootScriptSave.c
index 8769509f76b10b56c0b56248031c2fb7cc1cb894..32c7a55ac2bf67f0331434f2167df1c30f7a9d08 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Save the S3 data to S3 boot script. \r
  \r
-  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions\r
@@ -47,11 +47,15 @@ SCRIPT_TABLE_PRIVATE_DATA        mS3BootScriptTable;
 UINTN                            mLockBoxLength;\r
 \r
 EFI_GUID                         mBootScriptDataGuid = {\r
-  0xaea6b965, 0xdcf5, 0x4311, 0xb4, 0xb8, 0xf, 0x12, 0x46, 0x44, 0x94, 0xd2\r
+  0xaea6b965, 0xdcf5, 0x4311, { 0xb4, 0xb8, 0xf, 0x12, 0x46, 0x44, 0x94, 0xd2 }\r
 };\r
 \r
 EFI_GUID                         mBootScriptHeaderDataGuid = {\r
-  0x1810ab4a, 0x2314, 0x4df6, 0x81, 0xeb, 0x67, 0xc6, 0xec, 0x5, 0x85, 0x91\r
+  0x1810ab4a, 0x2314, 0x4df6, { 0x81, 0xeb, 0x67, 0xc6, 0xec, 0x5, 0x85, 0x91 }\r
+};\r
+\r
+EFI_GUID                         mBootScriptInformationGuid = {\r
+  0x2c680508, 0x2b87, 0x46ab, { 0xb9, 0x8a, 0x49, 0xfc, 0x23, 0xf9, 0xf5, 0x95 }\r
 };\r
 \r
 /**\r
@@ -99,6 +103,113 @@ S3BootScriptInternalCloseTable (
   //\r
 }  \r
 \r
+/**\r
+  This function return the total size of INFORMATION OPCODE in boot script table.\r
+\r
+  @return InformationBufferSize The total size of INFORMATION OPCODE in boot script table.\r
+**/\r
+UINTN\r
+GetBootScriptInformationBufferSize (\r
+  VOID\r
+  )\r
+{\r
+  UINT8                          *S3TableBase;\r
+  UINT8                          *Script;\r
+  UINTN                          TableLength;\r
+  EFI_BOOT_SCRIPT_COMMON_HEADER  ScriptHeader;\r
+  EFI_BOOT_SCRIPT_TABLE_HEADER   TableHeader;\r
+  EFI_BOOT_SCRIPT_INFORMATION    Information;\r
+  UINTN                          InformationBufferSize;\r
+\r
+  InformationBufferSize = 0;\r
+\r
+  S3TableBase   = mS3BootScriptTablePtr->TableBase;\r
+  Script        = S3TableBase;\r
+  CopyMem ((VOID*)&TableHeader, Script, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));\r
+  TableLength   = TableHeader.TableLength;\r
+\r
+  //\r
+  // Go through the ScriptTable\r
+  //\r
+  while ((UINTN) Script < (UINTN) (S3TableBase + TableLength)) {\r
+    CopyMem ((VOID*)&ScriptHeader, Script, sizeof(EFI_BOOT_SCRIPT_COMMON_HEADER));\r
+    switch (ScriptHeader.OpCode) {\r
+    case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r
+      CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(Information));\r
+      InformationBufferSize += Information.InformationLength;\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+    Script  = Script + ScriptHeader.Length;\r
+  }\r
+\r
+  return InformationBufferSize;\r
+}\r
+\r
+/**\r
+  This function fix INFORMATION OPCODE in boot script table.\r
+  Originally, the Information buffer is pointer to EfiRuntimeServicesCode,\r
+  EfiRuntimeServicesData, or EfiACPIMemoryNVS. They are seperated.\r
+  Now, in order to save it to LockBox, we allocate a big EfiACPIMemoryNVS,\r
+  and fix the pointer for INFORMATION opcode InformationBuffer.\r
+\r
+  @param InformationBuffer     The address of new Information buffer.\r
+  @param InformationBufferSize The size of new Information buffer.\r
+**/\r
+VOID\r
+FixBootScriptInformation (\r
+  IN VOID  *InformationBuffer,\r
+  IN UINTN InformationBufferSize\r
+  )\r
+{\r
+  UINT8                          *S3TableBase;\r
+  UINT8                          *Script;\r
+  UINTN                          TableLength;\r
+  EFI_BOOT_SCRIPT_COMMON_HEADER  ScriptHeader;\r
+  EFI_BOOT_SCRIPT_TABLE_HEADER   TableHeader;\r
+  EFI_BOOT_SCRIPT_INFORMATION    Information;\r
+  UINTN                          FixedInformationBufferSize;\r
+\r
+  FixedInformationBufferSize = 0;\r
+\r
+  S3TableBase   = mS3BootScriptTablePtr->TableBase;\r
+  Script        = S3TableBase;\r
+  CopyMem ((VOID*)&TableHeader, Script, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));\r
+  TableLength   = TableHeader.TableLength;\r
+\r
+  //\r
+  // Go through the ScriptTable\r
+  //\r
+  while ((UINTN) Script < (UINTN) (S3TableBase + TableLength)) {\r
+    CopyMem ((VOID*)&ScriptHeader, Script, sizeof(EFI_BOOT_SCRIPT_COMMON_HEADER));\r
+    switch (ScriptHeader.OpCode) {\r
+    case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r
+      CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(Information));\r
+\r
+      CopyMem (\r
+        (VOID *)((UINTN)InformationBuffer + FixedInformationBufferSize),\r
+        (VOID *)(UINTN)Information.Information,\r
+        Information.InformationLength\r
+        );\r
+      gBS->FreePool ((VOID *)(UINTN)Information.Information);\r
+      Information.Information = (EFI_PHYSICAL_ADDRESS)((UINTN)InformationBuffer + FixedInformationBufferSize);\r
+\r
+      CopyMem ((VOID*)Script, (VOID*)&Information, sizeof(Information));\r
+\r
+      FixedInformationBufferSize += Information.InformationLength;\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+    Script  = Script + ScriptHeader.Length;\r
+  }\r
+\r
+  ASSERT (FixedInformationBufferSize == InformationBufferSize);\r
+\r
+  return ;\r
+}\r
+\r
 /**\r
   This function save boot script data to LockBox.\r
   1. BootSriptPrivate data, BootScript data - Image and DispatchContext are handled by platform.\r
@@ -111,7 +222,45 @@ SaveBootScriptDataToLockBox (
   VOID\r
   )\r
 {\r
-  EFI_STATUS Status;\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  InformationBuffer;\r
+  UINTN                 InformationBufferSize;\r
+\r
+  //\r
+  // We need save BootScriptInformation to LockBox, because it is in\r
+  // EfiRuntimeServicesCode, EfiRuntimeServicesData, or EfiACPIMemoryNVS.\r
+  // \r
+  //\r
+  InformationBufferSize = GetBootScriptInformationBufferSize ();\r
+  if (InformationBufferSize != 0) {\r
+    InformationBuffer = 0xFFFFFFFF;\r
+    Status = gBS->AllocatePages (\r
+                    AllocateMaxAddress,\r
+                    EfiACPIMemoryNVS,\r
+                    EFI_SIZE_TO_PAGES(InformationBufferSize),\r
+                    &InformationBuffer\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Fix BootScript information pointer\r
+    //\r
+    FixBootScriptInformation ((VOID *)(UINTN)InformationBuffer, InformationBufferSize);\r
+\r
+    //\r
+    // Save BootScript information to lockbox\r
+    //\r
+    Status = SaveLockBox (\r
+               &mBootScriptInformationGuid,\r
+               (VOID *)(UINTN)InformationBuffer,\r
+               InformationBufferSize\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Status = SetLockBoxAttributes (&mBootScriptInformationGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
   //\r
   // mS3BootScriptTablePtr->TableLength does not include EFI_BOOT_SCRIPT_TERMINATE, because we need add entry at runtime.\r
   // Save all info here, just in case that no one will add boot script entry in SMM.\r
@@ -1237,7 +1386,7 @@ S3BootScriptSaveInformation (
   RETURN_STATUS         Status;\r
   UINT8                 Length;\r
   UINT8                 *Script;\r
-  EFI_PHYSICAL_ADDRESS  Buffer;\r
+  VOID                  *Buffer;\r
   EFI_BOOT_SCRIPT_INFORMATION  ScriptInformation;\r
 \r
   if (mS3BootScriptTablePtr->AtRuntime) {\r
@@ -1245,11 +1394,13 @@ S3BootScriptSaveInformation (
   }\r
   Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_INFORMATION));\r
   \r
-  Buffer = 0xFFFFFFFF;\r
-  Status = gBS->AllocatePages (\r
-                  AllocateMaxAddress,\r
-                  EfiACPIMemoryNVS,\r
-                  EFI_SIZE_TO_PAGES(InformationLength),\r
+  //\r
+  // Use BootServicesData to hold the data, just in case caller free it.\r
+  // It will be copied into ACPINvs later.\r
+  //\r
+  Status = gBS->AllocatePool (\r
+                  EfiBootServicesData,\r
+                  InformationLength,\r
                   &Buffer\r
                   );\r
   if (EFI_ERROR (Status)) {\r
@@ -1754,9 +1905,15 @@ S3BootScriptLabel (
   EFI_BOOT_SCRIPT_TABLE_HEADER   TableHeader;\r
   UINT32                         LabelLength;\r
   //\r
-  // Assume Label is not NULL\r
+  // Check NULL Label\r
+  //\r
+  if (Label == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Check empty Label\r
   //\r
if (Label == NULL) {\r
 if (Label[0] == '\0') {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   \r