X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FAcpi%2FS3SaveStateDxe%2FS3SaveState.c;h=cfa8ebbd2f5d3316500c15ca4c2051097f844582;hb=812e3bade69b9584c6e6b8209b3ff95e79e0a31b;hp=249fb8caff85196266859acfdec24996fac1bd9d;hpb=960729473e14c847526af94c430bc38f93105ec7;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveState.c b/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveState.c index 249fb8caff..cfa8ebbd2f 100644 --- a/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveState.c +++ b/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveState.c @@ -1,16 +1,9 @@ /** @file Implementation for S3 Boot Script Saver state driver. - Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions - of the BSD License which accompanies this distribution. The - full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "InternalS3SaveState.h" @@ -46,7 +39,7 @@ BootScriptWriteIoWrite ( Address = VA_ARG (Marker, UINT64); Count = VA_ARG (Marker, UINTN); Buffer = VA_ARG (Marker, UINT8 *); - + return S3BootScriptSaveIoWrite (Width, Address, Count, Buffer); } /** @@ -68,12 +61,12 @@ BootScriptWriteIoReadWrite ( UINT64 Address; UINT8 *Data; UINT8 *DataMask; - + Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); Address = VA_ARG (Marker, UINT64); Data = VA_ARG (Marker, UINT8 *); DataMask = VA_ARG (Marker, UINT8 *); - + return S3BootScriptSaveIoReadWrite (Width, Address, Data, DataMask); } @@ -96,7 +89,7 @@ BootScriptWriteMemWrite ( UINT64 Address; UINTN Count; UINT8 *Buffer; - + Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); Address = VA_ARG (Marker, UINT64); Count = VA_ARG (Marker, UINTN); @@ -124,7 +117,7 @@ BootScriptWriteMemReadWrite ( UINT64 Address; UINT8 *Data; UINT8 *DataMask; - + Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); Address = VA_ARG (Marker, UINT64); Data = VA_ARG (Marker, UINT8 *); @@ -210,10 +203,10 @@ BootScriptWritePciCfg2Write ( UINT16 Segment; Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); + Segment = VA_ARG (Marker, UINT16); Address = VA_ARG (Marker, UINT64); Count = VA_ARG (Marker, UINTN); Buffer = VA_ARG (Marker, UINT8 *); - Segment = VA_ARG (Marker, UINT16); return S3BootScriptSavePciCfg2Write (Width, Segment, Address, Count, Buffer); } @@ -238,17 +231,17 @@ BootScriptWritePciCfg2ReadWrite ( UINT64 Address; UINT8 *Data; UINT8 *DataMask; - + Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); - Address = VA_ARG (Marker, UINT64); Segment = VA_ARG (Marker, UINT16); + Address = VA_ARG (Marker, UINT64); Data = VA_ARG (Marker, UINT8 *); DataMask = VA_ARG (Marker, UINT8 *); - + return S3BootScriptSavePciCfg2ReadWrite (Width, Segment, Address, Data, DataMask); } /** - Internal function to add smbus excute opcode to the table. + Internal function to add smbus execute opcode to the table. @param Marker The variable argument list to get the opcode and associated attributes. @@ -269,15 +262,15 @@ BootScriptWriteSmbusExecute ( VOID *Buffer; UINTN *DataSize; UINTN SmBusAddress; - + SlaveAddress.SmbusDeviceAddress = VA_ARG (Marker, UINTN); Command = VA_ARG (Marker, EFI_SMBUS_DEVICE_COMMAND); Operation = VA_ARG (Marker, EFI_SMBUS_OPERATION); PecCheck = VA_ARG (Marker, BOOLEAN); SmBusAddress = SMBUS_LIB_ADDRESS (SlaveAddress.SmbusDeviceAddress,Command,0,PecCheck); - DataSize = VA_ARG (Marker, UINTN *); + DataSize = VA_ARG (Marker, UINTN *); Buffer = VA_ARG (Marker, VOID *); - + return S3BootScriptSaveSmbusExecute (SmBusAddress, Operation, DataSize, Buffer); } /** @@ -303,7 +296,7 @@ BootScriptWriteStall ( } /** - Internal function to add Save jmp address according to DISPATCH_OPCODE. + Internal function to add Save jmp address according to DISPATCH_OPCODE. We ignore "Context" parameter @param Marker The variable argument list to get the opcode @@ -325,8 +318,8 @@ BootScriptWriteDispatch ( } /** - Internal function to add memory pool operation to the table. - + Internal function to add memory pool operation to the table. + @param Marker The variable argument list to get the opcode and associated attributes. @@ -339,26 +332,43 @@ BootScriptWriteMemPoll ( IN VA_LIST Marker ) { - S3_BOOT_SCRIPT_LIB_WIDTH Width; - UINT64 Address; - VOID *Data; - VOID *DataMask; - UINTN Delay; - - Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); - Address = VA_ARG (Marker, UINT64); - Data = VA_ARG (Marker, VOID *); - DataMask = VA_ARG (Marker, VOID *); - Delay = (UINTN)VA_ARG (Marker, UINT64); + S3_BOOT_SCRIPT_LIB_WIDTH Width; + UINT64 Address; + VOID *Data; + VOID *DataMask; + UINT64 Delay; + UINT64 LoopTimes; + UINT32 Remainder; + + Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); + Address = VA_ARG (Marker, UINT64); + Data = VA_ARG (Marker, VOID *); + DataMask = VA_ARG (Marker, VOID *); + Delay = VA_ARG (Marker, UINT64); // - // According to the spec, the interval between 2 pools is 100ns - // - return S3BootScriptSaveMemPoll (Width, Address, DataMask, Data, 100, Delay); + // According to the spec, the interval between 2 polls is 100ns, + // but the unit of Duration for S3BootScriptSaveMemPoll() is microsecond(1000ns). + // Duration * 1000ns * LoopTimes = Delay * 100ns + // Duration will be minimum 1(microsecond) to be minimum deviation, + // so LoopTimes = Delay / 10. + // + LoopTimes = DivU64x32Remainder ( + Delay, + 10, + &Remainder + ); + if (Remainder != 0) { + // + // If Remainder is not zero, LoopTimes will be rounded up by 1. + // + LoopTimes +=1; + } + return S3BootScriptSaveMemPoll (Width, Address, DataMask, Data, 1, LoopTimes); } /** - Internal function to add Save jmp address according to DISPATCH_OPCODE2. + Internal function to add Save jmp address according to DISPATCH_OPCODE2. The "Context" parameter is not ignored. @param Marker The variable argument list to get the opcode @@ -374,7 +384,7 @@ BootScriptWriteDispatch2 ( ) { VOID *EntryPoint; - VOID *Context; + VOID *Context; EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS); Context = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS); @@ -397,7 +407,7 @@ BootScriptWriteInformation ( ) { UINT32 InformationLength; - EFI_PHYSICAL_ADDRESS Information; + EFI_PHYSICAL_ADDRESS Information; InformationLength = VA_ARG (Marker, UINT32); Information = VA_ARG (Marker, EFI_PHYSICAL_ADDRESS); @@ -418,17 +428,17 @@ BootScriptWriteIoPoll ( ) { S3_BOOT_SCRIPT_LIB_WIDTH Width; - UINT64 Address; - VOID *Data; - VOID *DataMask; - UINT64 Delay; - - Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); - Address = VA_ARG (Marker, UINT64); - Data = VA_ARG (Marker, VOID *); - DataMask = VA_ARG (Marker, VOID *); - Delay = (UINT64)VA_ARG (Marker, UINT64); - + UINT64 Address; + VOID *Data; + VOID *DataMask; + UINT64 Delay; + + Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); + Address = VA_ARG (Marker, UINT64); + Data = VA_ARG (Marker, VOID *); + DataMask = VA_ARG (Marker, VOID *); + Delay = (UINT64)VA_ARG (Marker, UINT64); + return S3BootScriptSaveIoPoll (Width, Address, Data, DataMask, Delay); } /** @@ -452,13 +462,13 @@ BootScriptWritePciConfigPoll ( VOID *DataMask; UINT64 Delay; - - Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); - Address = VA_ARG (Marker, UINT64); - Data = VA_ARG (Marker, VOID *); - DataMask = VA_ARG (Marker, VOID *); - Delay = (UINT64)VA_ARG (Marker, UINT64); - + + Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); + Address = VA_ARG (Marker, UINT64); + Data = VA_ARG (Marker, VOID *); + DataMask = VA_ARG (Marker, VOID *); + Delay = (UINT64)VA_ARG (Marker, UINT64); + return S3BootScriptSavePciPoll (Width, Address, Data, DataMask, Delay); } /** @@ -482,14 +492,14 @@ BootScriptWritePciConfig2Poll ( VOID *Data; VOID *DataMask; UINT64 Delay; - - Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); - Segment = VA_ARG (Marker, UINT16); - Address = VA_ARG (Marker, UINT64); - Data = VA_ARG (Marker, VOID *); - DataMask = VA_ARG (Marker, VOID *); - Delay = (UINT64)VA_ARG (Marker, UINT64); - + + Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH); + Segment = VA_ARG (Marker, UINT16); + Address = VA_ARG (Marker, UINT64); + Data = VA_ARG (Marker, VOID *); + DataMask = VA_ARG (Marker, VOID *); + Delay = (UINT64)VA_ARG (Marker, UINT64); + return S3BootScriptSavePci2Poll (Width, Segment, Address, Data, DataMask, Delay); } @@ -498,25 +508,25 @@ BootScriptWritePciConfig2Poll ( Adds a record into S3 boot script table. This function is used to store a boot script record into a given boot - script table. If the table specified by TableName is nonexistent in the - system, a new table will automatically be created and then the script record - will be added into the new table. This function is responsible for allocating + script table. If the table specified by TableName is nonexistent in the + system, a new table will automatically be created and then the script record + will be added into the new table. This function is responsible for allocating necessary memory for the script. - This function has a variable parameter list. The exact parameter list depends on - the OpCode that is passed into the function. If an unsupported OpCode or illegal + This function has a variable parameter list. The exact parameter list depends on + the OpCode that is passed into the function. If an unsupported OpCode or illegal parameter list is passed in, this function returns EFI_INVALID_PARAMETER. If there are not enough resources available for storing more scripts, this function returns EFI_OUT_OF_RESOURCES. @param This A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance. @param OpCode The operation code (opcode) number. - @param ... Argument list that is specific to each opcode. - + @param ... Argument list that is specific to each opcode. + @retval EFI_SUCCESS The operation succeeded. A record was added into the specified script table. @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported. - If the opcode is unknow or not supported because of the PCD + If the opcode is unknow or not supported because of the PCD Feature Flags. @retval EFI_OUT_OF_RESOURCES There is insufficient memory to store the boot script. @@ -525,12 +535,12 @@ EFI_STATUS EFIAPI BootScriptWrite ( IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This, - IN UINT16 OpCode, + IN UINTN OpCode, ... ) { EFI_STATUS Status; - VA_LIST Marker; + VA_LIST Marker; // // Build script according to opcode // @@ -551,7 +561,7 @@ BootScriptWrite ( case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: VA_START (Marker, OpCode); Status = BootScriptWriteMemWrite (Marker); - VA_END (Marker); + VA_END (Marker); break; case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE: @@ -582,7 +592,7 @@ BootScriptWrite ( VA_START (Marker, OpCode); Status = BootScriptWriteStall (Marker); VA_END (Marker); - + break; case EFI_BOOT_SCRIPT_DISPATCH_OPCODE: @@ -621,23 +631,23 @@ BootScriptWrite ( VA_END (Marker); break; - case EFI_BOOT_SCRIPT_IO_POLL_OPCODE: + case EFI_BOOT_SCRIPT_IO_POLL_OPCODE: VA_START (Marker, OpCode); Status = BootScriptWriteIoPoll (Marker); VA_END (Marker); - break; - - case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: + break; + + case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: VA_START (Marker, OpCode); Status = BootScriptWritePciConfigPoll (Marker); VA_END (Marker); - break; - + break; + case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE: VA_START (Marker, OpCode); Status = BootScriptWritePciConfig2Poll (Marker); VA_END (Marker); - break; + break; default: Status = EFI_INVALID_PARAMETER; @@ -666,7 +676,7 @@ BootScriptWrite ( inserted, either before or after, depending on BeforeOrAfter. On exit, specifies the position of the inserted opcode in the boot script table. @param OpCode The operation code (opcode) number. - @param ... Argument list that is specific to each opcode. + @param ... Argument list that is specific to each opcode. @retval EFI_SUCCESS The operation succeeded. A record was added into the specified script table. @@ -680,12 +690,12 @@ BootScriptInsert ( IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This, IN BOOLEAN BeforeOrAfter, IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL, - IN UINT16 OpCode, + IN UINTN OpCode, ... ) { EFI_STATUS Status; - VA_LIST Marker; + VA_LIST Marker; // // Build script according to opcode // @@ -706,7 +716,7 @@ BootScriptInsert ( case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: VA_START (Marker, OpCode); Status = BootScriptWriteMemWrite (Marker); - VA_END (Marker); + VA_END (Marker); break; case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE: @@ -737,7 +747,7 @@ BootScriptInsert ( VA_START (Marker, OpCode); Status = BootScriptWriteStall (Marker); VA_END (Marker); - + break; case EFI_BOOT_SCRIPT_DISPATCH_OPCODE: @@ -775,32 +785,32 @@ BootScriptInsert ( Status = BootScriptWritePciCfg2ReadWrite (Marker); VA_END (Marker); break; - - case EFI_BOOT_SCRIPT_IO_POLL_OPCODE: + + case EFI_BOOT_SCRIPT_IO_POLL_OPCODE: VA_START (Marker, OpCode); Status = BootScriptWriteIoPoll (Marker); VA_END (Marker); - break; - - case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: + break; + + case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: VA_START (Marker, OpCode); Status = BootScriptWritePciConfigPoll (Marker); VA_END (Marker); - break; - + break; + case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE: VA_START (Marker, OpCode); Status = BootScriptWritePciConfig2Poll (Marker); VA_END (Marker); - break; + break; default: Status = EFI_INVALID_PARAMETER; break; } - + if (!EFI_ERROR (Status)) { - Status = S3BootScriptMoveLastOpcode (BeforeOrAfter, Position); + Status = S3BootScriptMoveLastOpcode (BeforeOrAfter, (VOID **)Position); } return Status; } @@ -829,7 +839,7 @@ BootScriptInsert ( @retval EFI_SUCCESS The label already exists or was inserted. @retval EFI_INVALID_PARAMETER The Label is NULL or points to an empty string. @retval EFI_INVALID_PARAMETER The Position is not a valid position in the boot script table. - + **/ EFI_STATUS EFIAPI @@ -841,27 +851,27 @@ BootScriptLabel ( IN CONST CHAR8 *Label ) { - return S3BootScriptLabel (BeforeOrAfter, CreateIfNotFound, Position, Label); + return S3BootScriptLabel (BeforeOrAfter, CreateIfNotFound, (VOID **)Position, Label); } /** Compare two positions in the boot script table and return their relative position. - + This function compares two positions in the boot script table and returns their relative positions. If Position1 is before Position2, then -1 is returned. If Position1 is equal to Position2, then 0 is returned. If Position1 is after Position2, then 1 is returned. - + @param This A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance. @param Position1 The positions in the boot script table to compare @param Position2 The positions in the boot script table to compare @param RelativePosition On return, points to the result of the comparison - @retval EFI_SUCCESS The operation succeeded. + @retval EFI_SUCCESS The operation succeeded. @retval EFI_INVALID_PARAMETER The Position1 or Position2 is not a valid position in the boot script table. @retval EFI_INVALID_PARAMETER The RelativePosition is NULL. **/ EFI_STATUS -EFIAPI +EFIAPI BootScriptCompare ( IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This, IN EFI_S3_BOOT_SCRIPT_POSITION Position1, @@ -869,7 +879,7 @@ BootScriptCompare ( OUT UINTN *RelativePosition ) { - return S3BootScriptCompare (Position1, Position2, RelativePosition); + return S3BootScriptCompare (Position1, Position2, RelativePosition); } /** This routine is entry point of ScriptSave driver. @@ -889,7 +899,22 @@ InitializeS3SaveState ( IN EFI_SYSTEM_TABLE *SystemTable ) { + EFI_STATUS Status; + EFI_EVENT EndOfDxeEvent; + if (!PcdGetBool (PcdAcpiS3Enable)) { + return EFI_UNSUPPORTED; + } + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + AcpiS3ContextSaveOnEndOfDxe, + NULL, + &gEfiEndOfDxeEventGroupGuid, + &EndOfDxeEvent + ); + ASSERT_EFI_ERROR (Status); return gBS->InstallProtocolInterface ( &mHandle,