From ba665dc8e20d9f7730466a659564dd6c557a6cbc Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 11 Nov 2016 01:14:39 +0800 Subject: Hardware: Add sleep register hooks In Linux, para-virtualization implmentation hooks critical register writes to prevent real hardware operations. This increases divergences when the sleep registers are cracked in Linux resident ACPICA. This patch tries to introduce a single OSL to reduce the divergences. Lv Zheng. Signed-off-by: Lv Zheng --- source/components/hardware/hwesleep.c | 27 ++++++++++++++++++--------- source/components/hardware/hwsleep.c | 10 ++++++++++ source/include/acexcep.h | 8 +++----- source/include/acpiosxf.h | 8 ++++++++ source/os_specific/service_layers/osunixxf.c | 27 +++++++++++++++++++++++++++ source/os_specific/service_layers/oswinxf.c | 27 +++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 14 deletions(-) diff --git a/source/components/hardware/hwesleep.c b/source/components/hardware/hwesleep.c index 51f006b20..05f5b49f1 100644 --- a/source/components/hardware/hwesleep.c +++ b/source/components/hardware/hwesleep.c @@ -185,7 +185,7 @@ AcpiHwExtendedSleep ( UINT8 SleepState) { ACPI_STATUS Status; - UINT8 SleepTypeValue; + UINT8 SleepControl; UINT64 SleepStatus; @@ -211,10 +211,6 @@ AcpiHwExtendedSleep ( AcpiGbl_SystemAwakeAndRunning = FALSE; - /* Flush caches, as per ACPI specification */ - - ACPI_FLUSH_CPU_CACHE (); - /* * Set the SLP_TYP and SLP_EN bits. * @@ -224,11 +220,24 @@ AcpiHwExtendedSleep ( ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%u]\n", SleepState)); - SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) & - ACPI_X_SLEEP_TYPE_MASK); + SleepControl = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) & + ACPI_X_SLEEP_TYPE_MASK) | ACPI_X_SLEEP_ENABLE; + + /* Flush caches, as per ACPI specification */ + + ACPI_FLUSH_CPU_CACHE (); + + Status = AcpiOsEnterSleep (SleepState, SleepControl, 0); + if (Status == AE_CTRL_TERMINATE) + { + return_ACPI_STATUS (AE_OK); + } + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } - Status = AcpiWrite ((UINT64) (SleepTypeValue | ACPI_X_SLEEP_ENABLE), - &AcpiGbl_FADT.SleepControl); + Status = AcpiWrite ((UINT64) SleepControl, &AcpiGbl_FADT.SleepControl); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); diff --git a/source/components/hardware/hwsleep.c b/source/components/hardware/hwsleep.c index c2a2a7f0a..567e312ad 100644 --- a/source/components/hardware/hwsleep.c +++ b/source/components/hardware/hwsleep.c @@ -231,6 +231,16 @@ AcpiHwLegacySleep ( ACPI_FLUSH_CPU_CACHE (); + Status = AcpiOsEnterSleep (SleepState, Pm1aControl, Pm1bControl); + if (Status == AE_CTRL_TERMINATE) + { + return_ACPI_STATUS (AE_OK); + } + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + /* Write #2: Write both SLP_TYP + SLP_EN */ Status = AcpiHwWritePm1Control (Pm1aControl, Pm1bControl); diff --git a/source/include/acexcep.h b/source/include/acexcep.h index c5217295d..e6d6adb9e 100644 --- a/source/include/acexcep.h +++ b/source/include/acexcep.h @@ -289,11 +289,10 @@ typedef struct acpi_exception_info #define AE_CTRL_TRANSFER EXCEP_CTL (0x0008) #define AE_CTRL_BREAK EXCEP_CTL (0x0009) #define AE_CTRL_CONTINUE EXCEP_CTL (0x000A) -#define AE_CTRL_SKIP EXCEP_CTL (0x000B) -#define AE_CTRL_PARSE_CONTINUE EXCEP_CTL (0x000C) -#define AE_CTRL_PARSE_PENDING EXCEP_CTL (0x000D) +#define AE_CTRL_PARSE_CONTINUE EXCEP_CTL (0x000B) +#define AE_CTRL_PARSE_PENDING EXCEP_CTL (0x000C) -#define AE_CODE_CTRL_MAX 0x000D +#define AE_CODE_CTRL_MAX 0x000C /* Exception strings for AcpiFormatException */ @@ -416,7 +415,6 @@ static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Ctrl[] = EXCEP_TXT ("AE_CTRL_TRANSFER", "Transfer control to called method"), EXCEP_TXT ("AE_CTRL_BREAK", "A Break has been executed"), EXCEP_TXT ("AE_CTRL_CONTINUE", "A Continue has been executed"), - EXCEP_TXT ("AE_CTRL_SKIP", "Not currently used"), EXCEP_TXT ("AE_CTRL_PARSE_CONTINUE", "Used to skip over bad opcodes"), EXCEP_TXT ("AE_CTRL_PARSE_PENDING", "Used to implement AML While loops") }; diff --git a/source/include/acpiosxf.h b/source/include/acpiosxf.h index 60d61f119..df8393e61 100644 --- a/source/include/acpiosxf.h +++ b/source/include/acpiosxf.h @@ -528,6 +528,14 @@ AcpiOsSignal ( void *Info); #endif +#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsEnterSleep +ACPI_STATUS +AcpiOsEnterSleep ( + UINT8 SleepState, + UINT32 RegaValue, + UINT32 RegbValue); +#endif + /* * Debug print routines diff --git a/source/os_specific/service_layers/osunixxf.c b/source/os_specific/service_layers/osunixxf.c index 413a708cc..c58bdfba2 100644 --- a/source/os_specific/service_layers/osunixxf.c +++ b/source/os_specific/service_layers/osunixxf.c @@ -431,6 +431,33 @@ AcpiOsPhysicalTableOverride ( } +/****************************************************************************** + * + * FUNCTION: AcpiOsEnterSleep + * + * PARAMETERS: SleepState - Which sleep state to enter + * RegaValue - Register A value + * RegbValue - Register B value + * + * RETURN: Status + * + * DESCRIPTION: A hook before writing sleep registers to enter the sleep + * state. Return AE_CTRL_SKIP to skip further sleep register + * writes. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiOsEnterSleep ( + UINT8 SleepState, + UINT32 RegaValue, + UINT32 RegbValue) +{ + + return (AE_OK); +} + + /****************************************************************************** * * FUNCTION: AcpiOsRedirectOutput diff --git a/source/os_specific/service_layers/oswinxf.c b/source/os_specific/service_layers/oswinxf.c index 07f284492..dd0e5f132 100644 --- a/source/os_specific/service_layers/oswinxf.c +++ b/source/os_specific/service_layers/oswinxf.c @@ -359,6 +359,33 @@ AcpiOsPhysicalTableOverride ( } +/****************************************************************************** + * + * FUNCTION: AcpiOsEnterSleep + * + * PARAMETERS: SleepState - Which sleep state to enter + * RegaValue - Register A value + * RegbValue - Register B value + * + * RETURN: Status + * + * DESCRIPTION: A hook before writing sleep registers to enter the sleep + * state. Return AE_CTRL_SKIP to skip further sleep register + * writes. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiOsEnterSleep ( + UINT8 SleepState, + UINT32 RegaValue, + UINT32 RegbValue) +{ + + return (AE_OK); +} + + /****************************************************************************** * * FUNCTION: AcpiOsGetTimer -- cgit v1.2.1