Path: blob/main/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
48521 views
/******************************************************************************1*2* Name: hwxfsleep.c - ACPI Hardware Sleep/Wake External Interfaces3*4*****************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#define EXPORT_ACPI_INTERFACES152153#include <contrib/dev/acpica/include/acpi.h>154#include <contrib/dev/acpica/include/accommon.h>155156#define _COMPONENT ACPI_HARDWARE157ACPI_MODULE_NAME ("hwxfsleep")158159/* Local prototypes */160161static ACPI_STATUS162AcpiHwSetFirmwareWakingVector (163ACPI_TABLE_FACS *Facs,164ACPI_PHYSICAL_ADDRESS PhysicalAddress,165ACPI_PHYSICAL_ADDRESS PhysicalAddress64);166167static ACPI_STATUS168AcpiHwSleepDispatch (169UINT8 SleepState,170UINT32 FunctionId);171172/*173* Dispatch table used to efficiently branch to the various sleep174* functions.175*/176#define ACPI_SLEEP_FUNCTION_ID 0177#define ACPI_WAKE_PREP_FUNCTION_ID 1178#define ACPI_WAKE_FUNCTION_ID 2179180/* Legacy functions are optional, based upon ACPI_REDUCED_HARDWARE */181182static ACPI_SLEEP_FUNCTIONS AcpiSleepDispatch[] =183{184{ACPI_STRUCT_INIT (LegacyFunction,185ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacySleep)),186ACPI_STRUCT_INIT (ExtendedFunction,187AcpiHwExtendedSleep) },188{ACPI_STRUCT_INIT (LegacyFunction,189ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacyWakePrep)),190ACPI_STRUCT_INIT (ExtendedFunction,191AcpiHwExtendedWakePrep) },192{ACPI_STRUCT_INIT (LegacyFunction,193ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacyWake)),194ACPI_STRUCT_INIT (ExtendedFunction,195AcpiHwExtendedWake) }196};197198199/*******************************************************************************200*201* FUNCTION: AcpiHwSetFirmwareWakingVector202*203* PARAMETERS: Facs - Pointer to FACS table204* PhysicalAddress - 32-bit physical address of ACPI real mode205* entry point206* PhysicalAddress64 - 64-bit physical address of ACPI protected207* mode entry point208*209* RETURN: Status210*211* DESCRIPTION: Sets the FirmwareWakingVector fields of the FACS212*213******************************************************************************/214215static ACPI_STATUS216AcpiHwSetFirmwareWakingVector (217ACPI_TABLE_FACS *Facs,218ACPI_PHYSICAL_ADDRESS PhysicalAddress,219ACPI_PHYSICAL_ADDRESS PhysicalAddress64)220{221ACPI_FUNCTION_TRACE (AcpiHwSetFirmwareWakingVector);222223224/*225* According to the ACPI specification 2.0c and later, the 64-bit226* waking vector should be cleared and the 32-bit waking vector should227* be used, unless we want the wake-up code to be called by the BIOS in228* Protected Mode. Some systems (for example HP dv5-1004nr) are known229* to fail to resume if the 64-bit vector is used.230*/231232/* Set the 32-bit vector */233234Facs->FirmwareWakingVector = (UINT32) PhysicalAddress;235236if (Facs->Length > 32)237{238if (Facs->Version >= 1)239{240/* Set the 64-bit vector */241242Facs->XFirmwareWakingVector = PhysicalAddress64;243}244else245{246/* Clear the 64-bit vector if it exists */247248Facs->XFirmwareWakingVector = 0;249}250}251252return_ACPI_STATUS (AE_OK);253}254255256/*******************************************************************************257*258* FUNCTION: AcpiSetFirmwareWakingVector259*260* PARAMETERS: PhysicalAddress - 32-bit physical address of ACPI real mode261* entry point262* PhysicalAddress64 - 64-bit physical address of ACPI protected263* mode entry point264*265* RETURN: Status266*267* DESCRIPTION: Sets the FirmwareWakingVector fields of the FACS268*269******************************************************************************/270271ACPI_STATUS272AcpiSetFirmwareWakingVector (273ACPI_PHYSICAL_ADDRESS PhysicalAddress,274ACPI_PHYSICAL_ADDRESS PhysicalAddress64)275{276277ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector);278279if (AcpiGbl_FACS)280{281(void) AcpiHwSetFirmwareWakingVector (AcpiGbl_FACS,282PhysicalAddress, PhysicalAddress64);283}284285return_ACPI_STATUS (AE_OK);286}287288ACPI_EXPORT_SYMBOL (AcpiSetFirmwareWakingVector)289290291/*292* These functions are removed for the ACPI_REDUCED_HARDWARE case:293* AcpiEnterSleepStateS4bios294*/295296#if (!ACPI_REDUCED_HARDWARE)297/*******************************************************************************298*299* FUNCTION: AcpiEnterSleepStateS4bios300*301* PARAMETERS: None302*303* RETURN: Status304*305* DESCRIPTION: Perform a S4 bios request.306* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED307*308******************************************************************************/309310ACPI_STATUS311AcpiEnterSleepStateS4bios (312void)313{314UINT32 InValue;315ACPI_STATUS Status;316317318ACPI_FUNCTION_TRACE (AcpiEnterSleepStateS4bios);319320321/* Clear the wake status bit (PM1) */322323Status = AcpiWriteBitRegister (ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);324if (ACPI_FAILURE (Status))325{326return_ACPI_STATUS (Status);327}328329Status = AcpiHwClearAcpiStatus ();330if (ACPI_FAILURE (Status))331{332return_ACPI_STATUS (Status);333}334335/*336* 1) Disable all GPEs337* 2) Enable all wakeup GPEs338*/339Status = AcpiHwDisableAllGpes ();340if (ACPI_FAILURE (Status))341{342return_ACPI_STATUS (Status);343}344AcpiGbl_SystemAwakeAndRunning = FALSE;345346Status = AcpiHwEnableAllWakeupGpes ();347if (ACPI_FAILURE (Status))348{349return_ACPI_STATUS (Status);350}351352Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand,353(UINT32) AcpiGbl_FADT.S4BiosRequest, 8);354if (ACPI_FAILURE (Status))355{356return_ACPI_STATUS (Status);357}358359do {360AcpiOsStall (ACPI_USEC_PER_MSEC);361Status = AcpiReadBitRegister (ACPI_BITREG_WAKE_STATUS, &InValue);362if (ACPI_FAILURE (Status))363{364return_ACPI_STATUS (Status);365}366367} while (!InValue);368369return_ACPI_STATUS (AE_OK);370}371372ACPI_EXPORT_SYMBOL (AcpiEnterSleepStateS4bios)373374#endif /* !ACPI_REDUCED_HARDWARE */375376377/*******************************************************************************378*379* FUNCTION: AcpiHwSleepDispatch380*381* PARAMETERS: SleepState - Which sleep state to enter/exit382* FunctionId - Sleep, WakePrep, or Wake383*384* RETURN: Status from the invoked sleep handling function.385*386* DESCRIPTION: Dispatch a sleep/wake request to the appropriate handling387* function.388*389******************************************************************************/390391static ACPI_STATUS392AcpiHwSleepDispatch (393UINT8 SleepState,394UINT32 FunctionId)395{396ACPI_STATUS Status;397ACPI_SLEEP_FUNCTIONS *SleepFunctions = &AcpiSleepDispatch[FunctionId];398399400#if (!ACPI_REDUCED_HARDWARE)401/*402* If the Hardware Reduced flag is set (from the FADT), we must403* use the extended sleep registers (FADT). Note: As per the ACPI404* specification, these extended registers are to be used for HW-reduced405* platforms only. They are not general-purpose replacements for the406* legacy PM register sleep support.407*/408if (AcpiGbl_ReducedHardware)409{410Status = SleepFunctions->ExtendedFunction (SleepState);411}412else413{414/* Legacy sleep */415416Status = SleepFunctions->LegacyFunction (SleepState);417}418419return (Status);420421#else422/*423* For the case where reduced-hardware-only code is being generated,424* we know that only the extended sleep registers are available425*/426Status = SleepFunctions->ExtendedFunction (SleepState);427return (Status);428429#endif /* !ACPI_REDUCED_HARDWARE */430}431432433/*******************************************************************************434*435* FUNCTION: AcpiEnterSleepStatePrep436*437* PARAMETERS: SleepState - Which sleep state to enter438*439* RETURN: Status440*441* DESCRIPTION: Prepare to enter a system sleep state.442* This function must execute with interrupts enabled.443* We break sleeping into 2 stages so that OSPM can handle444* various OS-specific tasks between the two steps.445*446******************************************************************************/447448ACPI_STATUS449AcpiEnterSleepStatePrep (450UINT8 SleepState)451{452ACPI_STATUS Status;453ACPI_OBJECT_LIST ArgList;454ACPI_OBJECT Arg;455UINT32 SstValue;456457458ACPI_FUNCTION_TRACE (AcpiEnterSleepStatePrep);459460461Status = AcpiGetSleepTypeData (SleepState,462&AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);463if (ACPI_FAILURE (Status))464{465return_ACPI_STATUS (Status);466}467468Status = AcpiGetSleepTypeData (ACPI_STATE_S0,469&AcpiGbl_SleepTypeAS0, &AcpiGbl_SleepTypeBS0);470if (ACPI_FAILURE (Status)) {471AcpiGbl_SleepTypeAS0 = ACPI_SLEEP_TYPE_INVALID;472}473474/* Execute the _PTS method (Prepare To Sleep) */475476ArgList.Count = 1;477ArgList.Pointer = &Arg;478Arg.Type = ACPI_TYPE_INTEGER;479Arg.Integer.Value = SleepState;480481Status = AcpiEvaluateObject (NULL, METHOD_PATHNAME__PTS, &ArgList, NULL);482if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)483{484return_ACPI_STATUS (Status);485}486487/* Setup the argument to the _SST method (System STatus) */488489switch (SleepState)490{491case ACPI_STATE_S0:492493SstValue = ACPI_SST_WORKING;494break;495496case ACPI_STATE_S1:497case ACPI_STATE_S2:498case ACPI_STATE_S3:499500SstValue = ACPI_SST_SLEEPING;501break;502503case ACPI_STATE_S4:504505SstValue = ACPI_SST_SLEEP_CONTEXT;506break;507508default:509510SstValue = ACPI_SST_INDICATOR_OFF; /* Default is off */511break;512}513514/*515* Set the system indicators to show the desired sleep state.516* _SST is an optional method (return no error if not found)517*/518AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, SstValue);519return_ACPI_STATUS (AE_OK);520}521522ACPI_EXPORT_SYMBOL (AcpiEnterSleepStatePrep)523524525/*******************************************************************************526*527* FUNCTION: AcpiEnterSleepState528*529* PARAMETERS: SleepState - Which sleep state to enter530*531* RETURN: Status532*533* DESCRIPTION: Enter a system sleep state534* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED535*536******************************************************************************/537538ACPI_STATUS539AcpiEnterSleepState (540UINT8 SleepState)541{542ACPI_STATUS Status;543544545ACPI_FUNCTION_TRACE (AcpiEnterSleepState);546547548if ((AcpiGbl_SleepTypeA > ACPI_SLEEP_TYPE_MAX) ||549(AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX))550{551ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",552AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB));553return_ACPI_STATUS (AE_AML_OPERAND_VALUE);554}555556Status = AcpiHwSleepDispatch (SleepState, ACPI_SLEEP_FUNCTION_ID);557return_ACPI_STATUS (Status);558}559560ACPI_EXPORT_SYMBOL (AcpiEnterSleepState)561562563/*******************************************************************************564*565* FUNCTION: AcpiLeaveSleepStatePrep566*567* PARAMETERS: SleepState - Which sleep state we are exiting568*569* RETURN: Status570*571* DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a572* sleep. Called with interrupts DISABLED.573* We break wake/resume into 2 stages so that OSPM can handle574* various OS-specific tasks between the two steps.575*576******************************************************************************/577578ACPI_STATUS579AcpiLeaveSleepStatePrep (580UINT8 SleepState)581{582ACPI_STATUS Status;583584585ACPI_FUNCTION_TRACE (AcpiLeaveSleepStatePrep);586587588Status = AcpiHwSleepDispatch (SleepState, ACPI_WAKE_PREP_FUNCTION_ID);589return_ACPI_STATUS (Status);590}591592ACPI_EXPORT_SYMBOL (AcpiLeaveSleepStatePrep)593594595/*******************************************************************************596*597* FUNCTION: AcpiLeaveSleepState598*599* PARAMETERS: SleepState - Which sleep state we are exiting600*601* RETURN: Status602*603* DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep604* Called with interrupts ENABLED.605*606******************************************************************************/607608ACPI_STATUS609AcpiLeaveSleepState (610UINT8 SleepState)611{612ACPI_STATUS Status;613614615ACPI_FUNCTION_TRACE (AcpiLeaveSleepState);616617618Status = AcpiHwSleepDispatch (SleepState, ACPI_WAKE_FUNCTION_ID);619return_ACPI_STATUS (Status);620}621622ACPI_EXPORT_SYMBOL (AcpiLeaveSleepState)623624625