+++ /dev/null
-/** @file\r
- Implementation for S3 Boot Script Save thunk driver.\r
- This thunk driver consumes PI S3SaveState protocol to produce framework S3BootScriptSave Protocol \r
- \r
- Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-#include "ScriptSave.h"\r
-\r
-EFI_HANDLE mHandle;\r
-EFI_BOOT_SCRIPT_SAVE_PROTOCOL mS3ScriptSave = {\r
- BootScriptWrite,\r
- BootScriptCloseTable\r
- };\r
-EFI_S3_SAVE_STATE_PROTOCOL *mS3SaveState;\r
-\r
-/**\r
- Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
- long mode.\r
- \r
- @param Function The 32bit code entry to be executed.\r
- @param Param1 The first parameter to pass to 32bit code\r
- @param Param2 The second parameter to pass to 32bit code\r
- @retval EFI_SUCCESS Execute 32bit code successfully.\r
- @retval other Something wrong when execute the 32bit code \r
- \r
-**/ \r
-EFI_STATUS\r
-Execute32BitCode (\r
- IN UINT64 Function,\r
- IN UINT64 Param1,\r
- IN UINT64 Param2\r
- );\r
-\r
-/**\r
- A stub to convert framework boot script dispatch to PI boot script dispatch.\r
- \r
- @param ImageHandle It should be is NULL.\r
- @param Context The first parameter to pass to 32bit code\r
-\r
- @return dispatch value.\r
- \r
-**/ \r
-EFI_STATUS\r
-EFIAPI\r
-FrameworkBootScriptDispatchStub (\r
- IN EFI_HANDLE ImageHandle,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
- DISPATCH_ENTRYPOINT_FUNC EntryFunc;\r
- VOID *PeiServices;\r
- IA32_DESCRIPTOR Idtr;\r
-\r
- DEBUG ((EFI_D_ERROR, "FrameworkBootScriptDispatchStub - 0x%08x\n", (UINTN)Context));\r
-\r
- EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (Context);\r
- AsmReadIdtr (&Idtr);\r
- PeiServices = (VOID *)(UINTN)(*(UINT32 *)(Idtr.Base - sizeof (UINT32)));\r
-\r
- //\r
- // ECP assumes first parameter is NULL, and second parameter is PeiServices.\r
- //\r
- Status = Execute32BitCode ((UINT64)(UINTN)EntryFunc, 0, (UINT64)(UINTN)PeiServices);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Internal function to add IO write opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptIoWrite (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_BOOT_SCRIPT_WIDTH Width;\r
- UINT64 Address;\r
- UINTN Count;\r
- UINT8 *Buffer;\r
-\r
- Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);\r
- Address = VA_ARG (Marker, UINT64);\r
- Count = VA_ARG (Marker, UINTN);\r
- Buffer = VA_ARG (Marker, UINT8 *);\r
- \r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_IO_WRITE_OPCODE,\r
- Width, \r
- Address, \r
- Count, \r
- Buffer\r
- );\r
-}\r
-/**\r
- Internal function to add IO read/write opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptIoReadWrite (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_BOOT_SCRIPT_WIDTH Width;\r
- UINT64 Address;\r
- UINT8 *Data;\r
- UINT8 *DataMask;\r
- \r
- Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);\r
- Address = VA_ARG (Marker, UINT64);\r
- Data = VA_ARG (Marker, UINT8 *);\r
- DataMask = VA_ARG (Marker, UINT8 *);\r
- \r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE,\r
- Width, \r
- Address, \r
- Data, \r
- DataMask\r
- );\r
-}\r
-\r
-/**\r
- Internal function to add memory write opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptMemWrite (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_BOOT_SCRIPT_WIDTH Width;\r
- UINT64 Address;\r
- UINTN Count;\r
- UINT8 *Buffer;\r
- \r
- Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);\r
- Address = VA_ARG (Marker, UINT64);\r
- Count = VA_ARG (Marker, UINTN);\r
- Buffer = VA_ARG (Marker, UINT8 *);\r
-\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE,\r
- Width, \r
- Address, \r
- Count, \r
- Buffer\r
- );\r
-}\r
-\r
-/**\r
- Internal function to add memory read/write opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptMemReadWrite (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_BOOT_SCRIPT_WIDTH Width;\r
- UINT64 Address;\r
- UINT8 *Data;\r
- UINT8 *DataMask;\r
- \r
- Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);\r
- Address = VA_ARG (Marker, UINT64);\r
- Data = VA_ARG (Marker, UINT8 *);\r
- DataMask = VA_ARG (Marker, UINT8 *);\r
-\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE,\r
- Width, \r
- Address, \r
- Data, \r
- DataMask\r
- );\r
-}\r
-\r
-/**\r
- Internal function to add PciCfg write opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptPciCfgWrite (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_BOOT_SCRIPT_WIDTH Width;\r
- UINT64 Address;\r
- UINTN Count;\r
- UINT8 *Buffer;\r
-\r
- Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);\r
- Address = VA_ARG (Marker, UINT64);\r
- Count = VA_ARG (Marker, UINTN);\r
- Buffer = VA_ARG (Marker, UINT8 *);\r
-\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,\r
- Width, \r
- Address, \r
- Count, \r
- Buffer\r
- );\r
-}\r
-\r
-/**\r
- Internal function to PciCfg read/write opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptPciCfgReadWrite (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_BOOT_SCRIPT_WIDTH Width;\r
- UINT64 Address;\r
- UINT8 *Data;\r
- UINT8 *DataMask;\r
-\r
- Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);\r
- Address = VA_ARG (Marker, UINT64);\r
- Data = VA_ARG (Marker, UINT8 *);\r
- DataMask = VA_ARG (Marker, UINT8 *);\r
-\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE,\r
- Width,\r
- Address,\r
- Data,\r
- DataMask\r
- );\r
-}\r
-/**\r
- Internal function to add PciCfg2 write opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptPciCfg2Write (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_BOOT_SCRIPT_WIDTH Width;\r
- UINT64 Address;\r
- UINTN Count;\r
- UINT8 *Buffer;\r
- UINT16 Segment;\r
-\r
- Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);\r
- Address = VA_ARG (Marker, UINT64);\r
- Count = VA_ARG (Marker, UINTN);\r
- Buffer = VA_ARG (Marker, UINT8 *);\r
- Segment = VA_ARG (Marker, UINT16);\r
-\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE,\r
- Width, \r
- Segment, \r
- Address, \r
- Count, \r
- Buffer\r
- );\r
-}\r
-\r
-/**\r
- Internal function to PciCfg2 read/write opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptPciCfg2ReadWrite (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_BOOT_SCRIPT_WIDTH Width;\r
- UINT16 Segment;\r
- UINT64 Address;\r
- UINT8 *Data;\r
- UINT8 *DataMask;\r
- \r
- Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);\r
- Address = VA_ARG (Marker, UINT64);\r
- Segment = VA_ARG (Marker, UINT16);\r
- Data = VA_ARG (Marker, UINT8 *);\r
- DataMask = VA_ARG (Marker, UINT8 *);\r
- \r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE,\r
- Width, \r
- Segment,\r
- Address,\r
- Data,\r
- DataMask\r
- );\r
-}\r
-/**\r
- Internal function to add smbus execute opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptSmbusExecute (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;\r
- EFI_SMBUS_DEVICE_COMMAND Command;\r
- EFI_SMBUS_OPERATION Operation;\r
- BOOLEAN PecCheck;\r
- VOID *Buffer;\r
- UINTN *DataSize;\r
- \r
- SlaveAddress.SmbusDeviceAddress = VA_ARG (Marker, UINTN);\r
- Command = VA_ARG (Marker, EFI_SMBUS_DEVICE_COMMAND);\r
- Operation = VA_ARG (Marker, EFI_SMBUS_OPERATION);\r
- PecCheck = VA_ARG (Marker, BOOLEAN);\r
- DataSize = VA_ARG (Marker, UINTN *); \r
- Buffer = VA_ARG (Marker, VOID *);\r
- \r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE,\r
- SlaveAddress,\r
- Command, \r
- Operation, \r
- PecCheck,\r
- DataSize, \r
- Buffer\r
- );\r
-}\r
-/**\r
- Internal function to add stall opcode to the table.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptStall (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- UINT32 Duration;\r
-\r
- Duration = VA_ARG (Marker, UINT32);\r
-\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_STALL_OPCODE,\r
- Duration\r
- );\r
-}\r
-\r
-/**\r
- Internal function to add Save jmp address according to DISPATCH_OPCODE. \r
- We ignore "Context" parameter\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptDispatch (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- VOID *EntryPoint;\r
-\r
- EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_DISPATCH_OPCODE,\r
- EntryPoint\r
- );\r
-}\r
-\r
-/**\r
- Internal function to add Save jmp address according to DISPATCH_OPCODE. \r
- We ignore "Context" parameter.\r
- We need create thunk stub to convert PEI entrypoint (used in Framework version)\r
- to DXE entrypoint (defined in PI spec).\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-FrameworkBootScriptDispatch (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- VOID *EntryPoint;\r
- VOID *Context;\r
-\r
- EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
-\r
- //\r
- // Register callback\r
- //\r
- Context = EntryPoint;\r
- EntryPoint = (VOID *)(UINTN)FrameworkBootScriptDispatchStub;\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE,\r
- EntryPoint,\r
- Context\r
- );\r
-}\r
-\r
-/**\r
- Internal function to add memory pool operation to the table. \r
- \r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptMemPoll (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- EFI_BOOT_SCRIPT_WIDTH Width;\r
- UINT64 Address;\r
- UINT8 *BitMask;\r
- UINT8 *BitValue;\r
- UINT64 Duration;\r
- UINT64 LoopTimes;\r
- UINT64 Delay;\r
-\r
- Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);\r
- Address = VA_ARG (Marker, UINT64);\r
- BitMask = VA_ARG (Marker, UINT8 *);\r
- BitValue = VA_ARG (Marker, UINT8 *);\r
- Duration = (UINT64)VA_ARG (Marker, UINT64);\r
- LoopTimes = (UINT64)VA_ARG (Marker, UINT64);\r
- //\r
- // Framework version: Duration is used for Stall(), which is Microseconds.\r
- // Total time is: Duration(Microseconds) * LoopTimes.\r
- // PI version: Duration is always 100ns. Delay is LoopTimes.\r
- // Total time is: 100ns * Delay.\r
- // So Delay = Duration(Microseconds) * LoopTimes / 100ns\r
- // = Duration * 1000ns * LoopTimes / 100ns\r
- // = Duration * 10 * LoopTimes\r
- //\r
- Delay = MultU64x64 (MultU64x32 (Duration, 10), LoopTimes);\r
- \r
- //\r
- // Framework version: First BitMask, then BitValue\r
- // PI version: First Data, then DataMask\r
- // So we revert their order in function call\r
- //\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,\r
- Width,\r
- Address,\r
- BitValue,\r
- BitMask,\r
- Delay\r
- );\r
-}\r
-\r
-/**\r
- Internal function to add Save jmp address according to DISPATCH_OPCODE2. \r
- The "Context" parameter is not ignored.\r
-\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.\r
- @retval EFI_SUCCESS Opcode is added.\r
-\r
-**/\r
-EFI_STATUS\r
-BootScriptDispatch2 (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- VOID *EntryPoint;\r
- VOID *Context; \r
-\r
- EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
- Context = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
-\r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE,\r
- EntryPoint, \r
- Context\r
- );\r
-}\r
-/**\r
- Internal function to add the opcode link node to the link\r
- list.\r
- @param Marker The variable argument list to get the opcode\r
- and associated attributes.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Not enought resource to complete the operations.\r
- @retval EFI_SUCCESS The opcode entry is added to the link list\r
- successfully.\r
-**/\r
-EFI_STATUS\r
-BootScriptInformation (\r
- IN VA_LIST Marker\r
- )\r
-{\r
- UINT32 InformationLength;\r
- EFI_PHYSICAL_ADDRESS Information; \r
-\r
- InformationLength = VA_ARG (Marker, UINT32);\r
- Information = VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
- \r
- return mS3SaveState->Write (\r
- mS3SaveState,\r
- EFI_BOOT_SCRIPT_INFORMATION_OPCODE,\r
- InformationLength, \r
- (VOID*)(UINTN)Information\r
- );\r
-}\r
-\r
-/**\r
- Adds a record into a specified Framework boot script table.\r
-\r
- This function is used to store a boot script record into a given boot\r
- script table. If the table specified by TableName is nonexistent in the \r
- system, a new table will automatically be created and then the script record \r
- will be added into the new table. A boot script table can add new script records\r
- until EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable() is called. Currently, the only \r
- meaningful table name is EFI_ACPI_S3_RESUME_SCRIPT_TABLE. This function is\r
- responsible for allocating necessary memory for the script.\r
-\r
- This function has a variable parameter list. The exact parameter list depends on \r
- the OpCode that is passed into the function. If an unsupported OpCode or illegal \r
- parameter list is passed in, this function returns EFI_INVALID_PARAMETER.\r
- If there are not enough resources available for storing more scripts, this function returns\r
- EFI_OUT_OF_RESOURCES.\r
-\r
- @param This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.\r
- @param TableName Name of the script table. Currently, the only meaningful value is\r
- EFI_ACPI_S3_RESUME_SCRIPT_TABLE.\r
- @param OpCode The operation code (opcode) number.\r
- @param ... Argument list that is specific to each opcode. \r
-\r
- @retval EFI_SUCCESS The operation succeeded. A record was added into the\r
- specified script table.\r
- @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.\r
- If the opcode is unknow or not supported because of the PCD \r
- Feature Flags.\r
- @retval EFI_OUT_OF_RESOURCES There is insufficient memory to store the boot script.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BootScriptWrite (\r
- IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,\r
- IN UINT16 TableName,\r
- IN UINT16 OpCode,\r
- ...\r
- )\r
-{\r
- EFI_STATUS Status;\r
- VA_LIST Marker;\r
- \r
- if (TableName != FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE) {\r
- //\r
- // Only S3 boot script is supported for now\r
- //\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Build script according to opcode\r
- //\r
- switch (OpCode) {\r
-\r
- case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptIoWrite (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptIoReadWrite (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptMemWrite (Marker);\r
- VA_END (Marker); \r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptMemReadWrite (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptPciCfgWrite (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptPciCfgReadWrite (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptSmbusExecute (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_STALL_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptStall (Marker);\r
- VA_END (Marker);\r
- \r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = FrameworkBootScriptDispatch (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case FRAMEWORK_EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptDispatch2 (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptInformation (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case FRAMEWORK_EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptMemPoll (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptPciCfg2Write (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r
- VA_START (Marker, OpCode);\r
- Status = BootScriptPciCfg2ReadWrite (Marker);\r
- VA_END (Marker);\r
- break;\r
-\r
- default:\r
- Status = EFI_INVALID_PARAMETER;\r
- break;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Closes the specified script table.\r
-\r
- This function closes the specified boot script table and returns the base address \r
- of the table. It allocates a new pool to duplicate all the boot scripts in the specified \r
- table. Once this function is called, the specified table will be destroyed after it is \r
- copied into the allocated pool. As a result, any attempts to add a script record into a \r
- closed table will cause a new table to be created. The base address of the allocated pool \r
- will be returned in Address. After using the boot script table, the caller is responsible \r
- for freeing the pool that is allocated by this function. If the boot script table,\r
- such as EFI_ACPI_S3_RESUME_SCRIPT_TABLE, is required to be stored in a nonperturbed\r
- memory region, the caller should copy the table into the nonperturbed memory region by itself.\r
-\r
- @param This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.\r
- @param TableName Name of the script table. Currently, the only meaningful value is\r
- EFI_ACPI_S3_RESUME_SCRIPT_TABLE.\r
- @param Address A pointer to the physical address where the table begins. \r
- \r
- @retval EFI_SUCCESS The table was successfully returned.\r
- @retval EFI_NOT_FOUND The specified table was not created previously.\r
- @retval EFI_OUT_OF_RESOURCE Memory is insufficient to hold the reorganized boot script table.\r
- @retval EFI_UNSUPPORTED the table type is not EFI_ACPI_S3_RESUME_SCRIPT_TABLE\r
- \r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BootScriptCloseTable (\r
- IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,\r
- IN UINT16 TableName,\r
- OUT EFI_PHYSICAL_ADDRESS *Address\r
- )\r
-{ \r
- if (TableName != FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE) {\r
- //\r
- // Only S3 boot script is supported for now\r
- //\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Here the close table is not implemented. \r
- // \r
- \r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- Register image to memory profile.\r
-\r
- @param FileName File name of the image.\r
- @param ImageBase Image base address.\r
- @param ImageSize Image size.\r
- @param FileType File type of the image.\r
-\r
-**/\r
-VOID\r
-RegisterMemoryProfileImage (\r
- IN EFI_GUID *FileName,\r
- IN PHYSICAL_ADDRESS ImageBase,\r
- IN UINT64 ImageSize,\r
- IN EFI_FV_FILETYPE FileType\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol;\r
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;\r
- UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];\r
-\r
- if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0) {\r
-\r
- FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;\r
- Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **) &ProfileProtocol);\r
- if (!EFI_ERROR (Status)) {\r
- EfiInitializeFwVolDevicepathNode (FilePath, FileName);\r
- SetDevicePathEndNode (FilePath + 1);\r
-\r
- Status = ProfileProtocol->RegisterImage (\r
- ProfileProtocol,\r
- (EFI_DEVICE_PATH_PROTOCOL *) FilePath,\r
- ImageBase,\r
- ImageSize,\r
- FileType\r
- );\r
- }\r
- }\r
-}\r
-\r
-/**\r
- This routine is entry point of ScriptSave driver.\r
-\r
- @param ImageHandle Handle for this drivers loaded image protocol.\r
- @param SystemTable EFI system table.\r
-\r
- @retval EFI_OUT_OF_RESOURCES No enough resource\r
- @retval EFI_SUCCESS Succesfully installed the ScriptSave driver.\r
- @retval other Errors occured.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeScriptSaveOnS3SaveState (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- UINT8 *Buffer;\r
- UINTN BufferSize;\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
- BOOT_SCRIPT_THUNK_DATA *BootScriptThunkData;\r
- EFI_STATUS Status;\r
- VOID *DevicePath;\r
- EFI_PHYSICAL_ADDRESS MemoryAddress;\r
- UINTN PageNumber;\r
- EFI_HANDLE NewImageHandle;\r
-\r
- //\r
- // Test if the gEfiCallerIdGuid of this image is already installed. if not, the entry\r
- // point is loaded by DXE code which is the first time loaded. or else, it is already\r
- // be reloaded be itself.This is a work-around\r
- //\r
- Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &DevicePath);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // This is the first-time loaded by DXE core. reload itself to RESERVED mem\r
- //\r
- //\r
- // A workaround: Here we install a dummy handle\r
- //\r
- NewImageHandle = NULL;\r
- Status = gBS->InstallProtocolInterface (\r
- &NewImageHandle,\r
- &gEfiCallerIdGuid,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = GetSectionFromAnyFv (\r
- &gEfiCallerIdGuid,\r
- EFI_SECTION_PE32,\r
- 0,\r
- (VOID **) &Buffer,\r
- &BufferSize\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- ImageContext.Handle = Buffer;\r
- ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
- //\r
- // Get information about the image being loaded\r
- //\r
- Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- MemoryAddress = SIZE_4GB - 1;\r
- if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {\r
- PageNumber = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment));\r
- } else {\r
- PageNumber = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize);\r
- }\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiReservedMemoryType,\r
- PageNumber,\r
- &MemoryAddress\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)MemoryAddress;\r
- //\r
- // Align buffer on section boundary\r
- //\r
- ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;\r
- ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);\r
- //\r
- // Load the image to our new buffer\r
- //\r
- Status = PeCoffLoaderLoadImage (&ImageContext);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Relocate the image in our new buffer\r
- //\r
- Status = PeCoffLoaderRelocateImage (&ImageContext);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer\r
- //\r
- gBS->FreePool (Buffer);\r
-\r
- //\r
- // Flush the instruction cache so the image data is written before we execute it\r
- //\r
- InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
-\r
- RegisterMemoryProfileImage (\r
- &gEfiCallerIdGuid,\r
- ImageContext.ImageAddress,\r
- ImageContext.ImageSize,\r
- EFI_FV_FILETYPE_DRIVER\r
- );\r
-\r
- Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, SystemTable);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Additional step for BootScriptThunk integrity\r
- //\r
-\r
- //\r
- // Allocate BootScriptThunkData\r
- //\r
- BootScriptThunkData = AllocatePool (sizeof (BOOT_SCRIPT_THUNK_DATA));\r
- ASSERT (BootScriptThunkData != NULL);\r
-\r
- BootScriptThunkData->BootScriptThunkBase = ImageContext.ImageAddress;\r
- BootScriptThunkData->BootScriptThunkLength = ImageContext.ImageSize;\r
- //\r
- // Set BootScriptThunkData\r
- //\r
- PcdSet64 (BootScriptThunkDataPtr, (UINT64)(UINTN)BootScriptThunkData); \r
- return EFI_SUCCESS;\r
- } else {\r
- //\r
- // the entry point is invoked after reloading. following code only run in RESERVED mem\r
- //\r
-\r
- //\r
- // Locate and cache PI S3 Save State Protocol.\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiS3SaveStateProtocolGuid, \r
- NULL, \r
- (VOID **) &mS3SaveState\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return gBS->InstallProtocolInterface (\r
- &mHandle,\r
- &gEfiBootScriptSaveProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &mS3ScriptSave\r
- );\r
- }\r
-}\r
-\r
-\r