Home | History | Annotate | Line # | Download | only in hardware
hwacpi.c revision 1.1.1.11
      1 /******************************************************************************
      2  *
      3  * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 
     47 
     48 #define _COMPONENT          ACPI_HARDWARE
     49         ACPI_MODULE_NAME    ("hwacpi")
     50 
     51 
     52 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
     53 /******************************************************************************
     54  *
     55  * FUNCTION:    AcpiHwSetMode
     56  *
     57  * PARAMETERS:  Mode            - SYS_MODE_ACPI or SYS_MODE_LEGACY
     58  *
     59  * RETURN:      Status
     60  *
     61  * DESCRIPTION: Transitions the system into the requested mode.
     62  *
     63  ******************************************************************************/
     64 
     65 ACPI_STATUS
     66 AcpiHwSetMode (
     67     UINT32                  Mode)
     68 {
     69 
     70     ACPI_STATUS             Status;
     71     UINT32                  Retry;
     72 
     73 
     74     ACPI_FUNCTION_TRACE (HwSetMode);
     75 
     76 
     77     /* If the Hardware Reduced flag is set, machine is always in acpi mode */
     78 
     79     if (AcpiGbl_ReducedHardware)
     80     {
     81         return_ACPI_STATUS (AE_OK);
     82     }
     83 
     84     /*
     85      * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
     86      * system does not support mode transition.
     87      */
     88     if (!AcpiGbl_FADT.SmiCommand)
     89     {
     90         ACPI_ERROR ((AE_INFO, "No SMI_CMD in FADT, mode transition failed"));
     91         return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
     92     }
     93 
     94     /*
     95      * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
     96      * in FADT: If it is zero, enabling or disabling is not supported.
     97      * As old systems may have used zero for mode transition,
     98      * we make sure both the numbers are zero to determine these
     99      * transitions are not supported.
    100      */
    101     if (!AcpiGbl_FADT.AcpiEnable && !AcpiGbl_FADT.AcpiDisable)
    102     {
    103         ACPI_ERROR ((AE_INFO,
    104             "No ACPI mode transition supported in this system "
    105             "(enable/disable both zero)"));
    106         return_ACPI_STATUS (AE_OK);
    107     }
    108 
    109     switch (Mode)
    110     {
    111     case ACPI_SYS_MODE_ACPI:
    112 
    113         /* BIOS should have disabled ALL fixed and GP events */
    114 
    115         Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand,
    116             (UINT32) AcpiGbl_FADT.AcpiEnable, 8);
    117         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Attempting to enable ACPI mode\n"));
    118         break;
    119 
    120     case ACPI_SYS_MODE_LEGACY:
    121         /*
    122          * BIOS should clear all fixed status bits and restore fixed event
    123          * enable bits to default
    124          */
    125         Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand,
    126             (UINT32) AcpiGbl_FADT.AcpiDisable, 8);
    127         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    128             "Attempting to enable Legacy (non-ACPI) mode\n"));
    129         break;
    130 
    131     default:
    132 
    133         return_ACPI_STATUS (AE_BAD_PARAMETER);
    134     }
    135 
    136     if (ACPI_FAILURE (Status))
    137     {
    138         ACPI_EXCEPTION ((AE_INFO, Status,
    139             "Could not write ACPI mode change"));
    140         return_ACPI_STATUS (Status);
    141     }
    142 
    143     /*
    144      * Some hardware takes a LONG time to switch modes. Give them 3 sec to
    145      * do so, but allow faster systems to proceed more quickly.
    146      */
    147     Retry = 3000;
    148     while (Retry)
    149     {
    150         if (AcpiHwGetMode () == Mode)
    151         {
    152             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    153                 "Mode %X successfully enabled\n", Mode));
    154             return_ACPI_STATUS (AE_OK);
    155         }
    156         AcpiOsStall (ACPI_USEC_PER_MSEC);
    157         Retry--;
    158     }
    159 
    160     ACPI_ERROR ((AE_INFO, "Hardware did not change modes"));
    161     return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
    162 }
    163 
    164 
    165 /*******************************************************************************
    166  *
    167  * FUNCTION:    AcpiHwGetMode
    168  *
    169  * PARAMETERS:  none
    170  *
    171  * RETURN:      SYS_MODE_ACPI or SYS_MODE_LEGACY
    172  *
    173  * DESCRIPTION: Return current operating state of system. Determined by
    174  *              querying the SCI_EN bit.
    175  *
    176  ******************************************************************************/
    177 
    178 UINT32
    179 AcpiHwGetMode (
    180     void)
    181 {
    182     ACPI_STATUS             Status;
    183     UINT32                  Value;
    184 
    185 
    186     ACPI_FUNCTION_TRACE (HwGetMode);
    187 
    188 
    189     /* If the Hardware Reduced flag is set, machine is always in acpi mode */
    190 
    191     if (AcpiGbl_ReducedHardware)
    192     {
    193         return_UINT32 (ACPI_SYS_MODE_ACPI);
    194     }
    195 
    196     /*
    197      * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
    198      * system does not support mode transition.
    199      */
    200     if (!AcpiGbl_FADT.SmiCommand)
    201     {
    202         return_UINT32 (ACPI_SYS_MODE_ACPI);
    203     }
    204 
    205     Status = AcpiReadBitRegister (ACPI_BITREG_SCI_ENABLE, &Value);
    206     if (ACPI_FAILURE (Status))
    207     {
    208         return_UINT32 (ACPI_SYS_MODE_LEGACY);
    209     }
    210 
    211     if (Value)
    212     {
    213         return_UINT32 (ACPI_SYS_MODE_ACPI);
    214     }
    215     else
    216     {
    217         return_UINT32 (ACPI_SYS_MODE_LEGACY);
    218     }
    219 }
    220 
    221 #endif /* !ACPI_REDUCED_HARDWARE */
    222