From f6ec0c771a4a1a9b19835345eca7d06510f08fa8 Mon Sep 17 00:00:00 2001
From: jyao1 <jyao1@6f19259b-4bc3-4df7-8a09-765794883524>
Date: Thu, 17 Nov 2011 09:35:20 +0000
Subject: In BootScriptSaver, put INFORMATION_OPCODE message to LockBox. In
 BootScriptExecutor, add code to display this INFORMATION_OPCODE message.

Signed-off-by: jyao1
Reviewed-by: rsun3

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12735 6f19259b-4bc3-4df7-8a09-765794883524
---
 .../PiDxeS3BootScriptLib/BootScriptExecute.c       |  16 +-
 .../Library/PiDxeS3BootScriptLib/BootScriptSave.c  | 165 ++++++++++++++++++++-
 2 files changed, 171 insertions(+), 10 deletions(-)

(limited to 'MdeModulePkg')

diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c
index 5a93549271..766396d1d1 100644
--- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c
+++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c
@@ -1,7 +1,7 @@
 /** @file
   Interpret and execute the S3 data in S3 boot script. 
 
-  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions
@@ -1199,8 +1199,18 @@ BootScriptExecuteInformation (
   )
 
 {
-  UINT8 Index;
-  for (Index = 0; Index < 10; Index++);
+  UINT32                        Index;
+  EFI_BOOT_SCRIPT_INFORMATION   Information;
+
+  CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(Information));
+
+  DEBUG ((EFI_D_INFO, "BootScriptExecuteInformation - 0x%08x\n", (UINTN)Information.Information));
+
+  DEBUG ((EFI_D_INFO, "BootScriptInformation: "));
+  for (Index = 0; Index < Information.InformationLength; Index++) {
+    DEBUG ((EFI_D_INFO, "%02x ", *(UINT8 *)(UINTN)(Information.Information + Index)));
+  }
+  DEBUG ((EFI_D_INFO, "\n"));
 }
 /**
   calculate the mask value for 'and' and 'or' operation
diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
index aa20d6d302..0ebfdbb1b6 100644
--- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
+++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
@@ -54,6 +54,10 @@ EFI_GUID                         mBootScriptHeaderDataGuid = {
   0x1810ab4a, 0x2314, 0x4df6, 0x81, 0xeb, 0x67, 0xc6, 0xec, 0x5, 0x85, 0x91
 };
 
+EFI_GUID                         mBootScriptInformationGuid = {
+  0x2c680508, 0x2b87, 0x46ab, 0xb9, 0x8a, 0x49, 0xfc, 0x23, 0xf9, 0xf5, 0x95
+};
+
 /**
   This is an internal function to add a terminate node the entry, recalculate the table 
   length and fill into the table. 
@@ -99,6 +103,113 @@ S3BootScriptInternalCloseTable (
   //
 }  
 
+/**
+  This function return the total size of INFORMATION OPCODE in boot script table.
+
+  @return InformationBufferSize The total size of INFORMATION OPCODE in boot script table.
+**/
+UINTN
+GetBootScriptInformationBufferSize (
+  VOID
+  )
+{
+  UINT8                          *S3TableBase;
+  UINT8                          *Script;
+  UINTN                          TableLength;
+  EFI_BOOT_SCRIPT_COMMON_HEADER  ScriptHeader;
+  EFI_BOOT_SCRIPT_TABLE_HEADER   TableHeader;
+  EFI_BOOT_SCRIPT_INFORMATION    Information;
+  UINTN                          InformationBufferSize;
+
+  InformationBufferSize = 0;
+
+  S3TableBase   = mS3BootScriptTablePtr->TableBase;
+  Script        = S3TableBase;
+  CopyMem ((VOID*)&TableHeader, Script, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));
+  TableLength   = TableHeader.TableLength;
+
+  //
+  // Go through the ScriptTable
+  //
+  while ((UINTN) Script < (UINTN) (S3TableBase + TableLength)) {
+    CopyMem ((VOID*)&ScriptHeader, Script, sizeof(EFI_BOOT_SCRIPT_COMMON_HEADER));
+    switch (ScriptHeader.OpCode) {
+    case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
+      CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(Information));
+      InformationBufferSize += Information.InformationLength;
+      break;
+    default:
+      break;
+    }
+    Script  = Script + ScriptHeader.Length;
+  }
+
+  return InformationBufferSize;
+}
+
+/**
+  This function fix INFORMATION OPCODE in boot script table.
+  Originally, the Information buffer is pointer to EfiRuntimeServicesCode,
+  EfiRuntimeServicesData, or EfiACPIMemoryNVS. They are seperated.
+  Now, in order to save it to LockBox, we allocate a big EfiACPIMemoryNVS,
+  and fix the pointer for INFORMATION opcode InformationBuffer.
+
+  @param InformationBuffer     The address of new Information buffer.
+  @param InformationBufferSize The size of new Information buffer.
+**/
+VOID
+FixBootScriptInformation (
+  IN VOID  *InformationBuffer,
+  IN UINTN InformationBufferSize
+  )
+{
+  UINT8                          *S3TableBase;
+  UINT8                          *Script;
+  UINTN                          TableLength;
+  EFI_BOOT_SCRIPT_COMMON_HEADER  ScriptHeader;
+  EFI_BOOT_SCRIPT_TABLE_HEADER   TableHeader;
+  EFI_BOOT_SCRIPT_INFORMATION    Information;
+  UINTN                          FixedInformationBufferSize;
+
+  FixedInformationBufferSize = 0;
+
+  S3TableBase   = mS3BootScriptTablePtr->TableBase;
+  Script        = S3TableBase;
+  CopyMem ((VOID*)&TableHeader, Script, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));
+  TableLength   = TableHeader.TableLength;
+
+  //
+  // Go through the ScriptTable
+  //
+  while ((UINTN) Script < (UINTN) (S3TableBase + TableLength)) {
+    CopyMem ((VOID*)&ScriptHeader, Script, sizeof(EFI_BOOT_SCRIPT_COMMON_HEADER));
+    switch (ScriptHeader.OpCode) {
+    case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
+      CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(Information));
+
+      CopyMem (
+        (VOID *)((UINTN)InformationBuffer + FixedInformationBufferSize),
+        (VOID *)(UINTN)Information.Information,
+        Information.InformationLength
+        );
+      gBS->FreePool ((VOID *)(UINTN)Information.Information);
+      Information.Information = (EFI_PHYSICAL_ADDRESS)((UINTN)InformationBuffer + FixedInformationBufferSize);
+
+      CopyMem ((VOID*)Script, (VOID*)&Information, sizeof(Information));
+
+      FixedInformationBufferSize += Information.InformationLength;
+      break;
+    default:
+      break;
+    }
+    Script  = Script + ScriptHeader.Length;
+  }
+
+  ASSERT (FixedInformationBufferSize == InformationBufferSize);
+
+  return ;
+}
+
 /**
   This function save boot script data to LockBox.
   1. BootSriptPrivate data, BootScript data - Image and DispatchContext are handled by platform.
@@ -111,7 +222,45 @@ SaveBootScriptDataToLockBox (
   VOID
   )
 {
-  EFI_STATUS Status;
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  InformationBuffer;
+  UINTN                 InformationBufferSize;
+
+  //
+  // We need save BootScriptInformation to LockBox, because it is in
+  // EfiRuntimeServicesCode, EfiRuntimeServicesData, or EfiACPIMemoryNVS.
+  // 
+  //
+  InformationBufferSize = GetBootScriptInformationBufferSize ();
+  if (InformationBufferSize != 0) {
+    InformationBuffer = 0xFFFFFFFF;
+    Status = gBS->AllocatePages (
+                    AllocateMaxAddress,
+                    EfiACPIMemoryNVS,
+                    EFI_SIZE_TO_PAGES(InformationBufferSize),
+                    &InformationBuffer
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Fix BootScript information pointer
+    //
+    FixBootScriptInformation ((VOID *)(UINTN)InformationBuffer, InformationBufferSize);
+
+    //
+    // Save BootScript information to lockbox
+    //
+    Status = SaveLockBox (
+               &mBootScriptInformationGuid,
+               (VOID *)(UINTN)InformationBuffer,
+               InformationBufferSize
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    Status = SetLockBoxAttributes (&mBootScriptInformationGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
+    ASSERT_EFI_ERROR (Status);
+  }
+
   //
   // mS3BootScriptTablePtr->TableLength does not include EFI_BOOT_SCRIPT_TERMINATE, because we need add entry at runtime.
   // Save all info here, just in case that no one will add boot script entry in SMM.
@@ -1237,7 +1386,7 @@ S3BootScriptSaveInformation (
   RETURN_STATUS         Status;
   UINT8                 Length;
   UINT8                 *Script;
-  EFI_PHYSICAL_ADDRESS  Buffer;
+  VOID                  *Buffer;
   EFI_BOOT_SCRIPT_INFORMATION  ScriptInformation;
 
   if (mS3BootScriptTablePtr->AtRuntime) {
@@ -1245,11 +1394,13 @@ S3BootScriptSaveInformation (
   }
   Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_INFORMATION));
   
-  Buffer = 0xFFFFFFFF;
-  Status = gBS->AllocatePages (
-                  AllocateMaxAddress,
-                  EfiACPIMemoryNVS,
-                  EFI_SIZE_TO_PAGES(InformationLength),
+  //
+  // Use BootServicesData to hold the data, just in case caller free it.
+  // It will be copied into ACPINvs later.
+  //
+  Status = gBS->AllocatePool (
+                  EfiBootServicesData,
+                  InformationLength,
                   &Buffer
                   );
   if (EFI_ERROR (Status)) {
-- 
cgit v1.2.3