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,