Skip to content

Commit

Permalink
Hardware: Add sleep register hooks
Browse files Browse the repository at this point in the history
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 <lv.zheng@intel.com>
  • Loading branch information
Lv Zheng committed Nov 10, 2016
1 parent b138a24 commit ba665dc
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 14 deletions.
27 changes: 18 additions & 9 deletions source/components/hardware/hwesleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ AcpiHwExtendedSleep (
UINT8 SleepState)
{
ACPI_STATUS Status;
UINT8 SleepTypeValue;
UINT8 SleepControl;
UINT64 SleepStatus;


Expand All @@ -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.
*
Expand All @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions source/components/hardware/hwsleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 3 additions & 5 deletions source/include/acexcep.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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")
};
Expand Down
8 changes: 8 additions & 0 deletions source/include/acpiosxf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 27 additions & 0 deletions source/os_specific/service_layers/osunixxf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 27 additions & 0 deletions source/os_specific/service_layers/oswinxf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ba665dc

Please sign in to comment.