+/**\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