179414580SJérôme Duval/******************************************************************************
279414580SJérôme Duval *
379414580SJérôme Duval * Module Name: tbfadt   - FADT table utilities
479414580SJérôme Duval *
579414580SJérôme Duval *****************************************************************************/
679414580SJérôme Duval
779414580SJérôme Duval/******************************************************************************
879414580SJérôme Duval *
979414580SJérôme Duval * 1. Copyright Notice
1079414580SJérôme Duval *
11ff2e2f81SFredrik Holmqvist * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
1279414580SJérôme Duval * All rights reserved.
1379414580SJérôme Duval *
1479414580SJérôme Duval * 2. License
1579414580SJérôme Duval *
1679414580SJérôme Duval * 2.1. This is your license from Intel Corp. under its intellectual property
179b0d045cSFredrik Holmqvist * rights. You may have additional license terms from the party that provided
1879414580SJérôme Duval * you this software, covering your right to use that party's intellectual
1979414580SJérôme Duval * property rights.
2079414580SJérôme Duval *
2179414580SJérôme Duval * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2279414580SJérôme Duval * copy of the source code appearing in this file ("Covered Code") an
2379414580SJérôme Duval * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2479414580SJérôme Duval * base code distributed originally by Intel ("Original Intel Code") to copy,
2579414580SJérôme Duval * make derivatives, distribute, use and display any portion of the Covered
2679414580SJérôme Duval * Code in any form, with the right to sublicense such rights; and
2779414580SJérôme Duval *
2879414580SJérôme Duval * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
2979414580SJérôme Duval * license (with the right to sublicense), under only those claims of Intel
3079414580SJérôme Duval * patents that are infringed by the Original Intel Code, to make, use, sell,
3179414580SJérôme Duval * offer to sell, and import the Covered Code and derivative works thereof
3279414580SJérôme Duval * solely to the minimum extent necessary to exercise the above copyright
3379414580SJérôme Duval * license, and in no event shall the patent license extend to any additions
349b0d045cSFredrik Holmqvist * to or modifications of the Original Intel Code. No other license or right
3579414580SJérôme Duval * is granted directly or by implication, estoppel or otherwise;
3679414580SJérôme Duval *
3779414580SJérôme Duval * The above copyright and patent license is granted only if the following
3879414580SJérôme Duval * conditions are met:
3979414580SJérôme Duval *
4079414580SJérôme Duval * 3. Conditions
4179414580SJérôme Duval *
4279414580SJérôme Duval * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4379414580SJérôme Duval * Redistribution of source code of any substantial portion of the Covered
4479414580SJérôme Duval * Code or modification with rights to further distribute source must include
4579414580SJérôme Duval * the above Copyright Notice, the above License, this list of Conditions,
469b0d045cSFredrik Holmqvist * and the following Disclaimer and Export Compliance provision. In addition,
4779414580SJérôme Duval * Licensee must cause all Covered Code to which Licensee contributes to
4879414580SJérôme Duval * contain a file documenting the changes Licensee made to create that Covered
499b0d045cSFredrik Holmqvist * Code and the date of any change. Licensee must include in that file the
509b0d045cSFredrik Holmqvist * documentation of any changes made by any predecessor Licensee. Licensee
5179414580SJérôme Duval * must include a prominent statement that the modification is derived,
5279414580SJérôme Duval * directly or indirectly, from Original Intel Code.
5379414580SJérôme Duval *
5479414580SJérôme Duval * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5579414580SJérôme Duval * Redistribution of source code of any substantial portion of the Covered
5679414580SJérôme Duval * Code or modification without rights to further distribute source must
5779414580SJérôme Duval * include the following Disclaimer and Export Compliance provision in the
589b0d045cSFredrik Holmqvist * documentation and/or other materials provided with distribution. In
5979414580SJérôme Duval * addition, Licensee may not authorize further sublicense of source of any
6079414580SJérôme Duval * portion of the Covered Code, and must include terms to the effect that the
6179414580SJérôme Duval * license from Licensee to its licensee is limited to the intellectual
6279414580SJérôme Duval * property embodied in the software Licensee provides to its licensee, and
6379414580SJérôme Duval * not to intellectual property embodied in modifications its licensee may
6479414580SJérôme Duval * make.
6579414580SJérôme Duval *
6679414580SJérôme Duval * 3.3. Redistribution of Executable. Redistribution in executable form of any
6779414580SJérôme Duval * substantial portion of the Covered Code or modification must reproduce the
6879414580SJérôme Duval * above Copyright Notice, and the following Disclaimer and Export Compliance
6979414580SJérôme Duval * provision in the documentation and/or other materials provided with the
7079414580SJérôme Duval * distribution.
7179414580SJérôme Duval *
7279414580SJérôme Duval * 3.4. Intel retains all right, title, and interest in and to the Original
7379414580SJérôme Duval * Intel Code.
7479414580SJérôme Duval *
7579414580SJérôme Duval * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7679414580SJérôme Duval * Intel shall be used in advertising or otherwise to promote the sale, use or
7779414580SJérôme Duval * other dealings in products derived from or relating to the Covered Code
7879414580SJérôme Duval * without prior written authorization from Intel.
7979414580SJérôme Duval *
8079414580SJérôme Duval * 4. Disclaimer and Export Compliance
8179414580SJérôme Duval *
8279414580SJérôme Duval * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
839b0d045cSFredrik Holmqvist * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
849b0d045cSFredrik Holmqvist * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
859b0d045cSFredrik Holmqvist * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
869b0d045cSFredrik Holmqvist * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
8779414580SJérôme Duval * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8879414580SJérôme Duval * PARTICULAR PURPOSE.
8979414580SJérôme Duval *
9079414580SJérôme Duval * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9179414580SJérôme Duval * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9279414580SJérôme Duval * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9379414580SJérôme Duval * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9479414580SJérôme Duval * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
959b0d045cSFredrik Holmqvist * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
9679414580SJérôme Duval * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9779414580SJérôme Duval * LIMITED REMEDY.
9879414580SJérôme Duval *
9979414580SJérôme Duval * 4.3. Licensee shall not export, either directly or indirectly, any of this
10079414580SJérôme Duval * software or system incorporating such software without first obtaining any
10179414580SJérôme Duval * required license or other approval from the U. S. Department of Commerce or
1029b0d045cSFredrik Holmqvist * any other agency or department of the United States Government. In the
10379414580SJérôme Duval * event Licensee exports any such software from the United States or
10479414580SJérôme Duval * re-exports any such software from a foreign destination, Licensee shall
10579414580SJérôme Duval * ensure that the distribution and export/re-export of the software is in
10679414580SJérôme Duval * compliance with all laws, regulations, orders, or other restrictions of the
10779414580SJérôme Duval * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10879414580SJérôme Duval * any of its subsidiaries will export/re-export any technical data, process,
10979414580SJérôme Duval * software, or service, directly or indirectly, to any country for which the
11079414580SJérôme Duval * United States government or any agency thereof requires an export license,
11179414580SJérôme Duval * other governmental approval, or letter of assurance, without first obtaining
11279414580SJérôme Duval * such license, approval or letter.
11379414580SJérôme Duval *
114ff2e2f81SFredrik Holmqvist *****************************************************************************
115ff2e2f81SFredrik Holmqvist *
116ff2e2f81SFredrik Holmqvist * Alternatively, you may choose to be licensed under the terms of the
117ff2e2f81SFredrik Holmqvist * following license:
118ff2e2f81SFredrik Holmqvist *
119ff2e2f81SFredrik Holmqvist * Redistribution and use in source and binary forms, with or without
120ff2e2f81SFredrik Holmqvist * modification, are permitted provided that the following conditions
121ff2e2f81SFredrik Holmqvist * are met:
122ff2e2f81SFredrik Holmqvist * 1. Redistributions of source code must retain the above copyright
123ff2e2f81SFredrik Holmqvist *    notice, this list of conditions, and the following disclaimer,
124ff2e2f81SFredrik Holmqvist *    without modification.
125ff2e2f81SFredrik Holmqvist * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126ff2e2f81SFredrik Holmqvist *    substantially similar to the "NO WARRANTY" disclaimer below
127ff2e2f81SFredrik Holmqvist *    ("Disclaimer") and any redistribution must be conditioned upon
128ff2e2f81SFredrik Holmqvist *    including a substantially similar Disclaimer requirement for further
129ff2e2f81SFredrik Holmqvist *    binary redistribution.
130ff2e2f81SFredrik Holmqvist * 3. Neither the names of the above-listed copyright holders nor the names
131ff2e2f81SFredrik Holmqvist *    of any contributors may be used to endorse or promote products derived
132ff2e2f81SFredrik Holmqvist *    from this software without specific prior written permission.
133ff2e2f81SFredrik Holmqvist *
134ff2e2f81SFredrik Holmqvist * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135ff2e2f81SFredrik Holmqvist * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136ff2e2f81SFredrik Holmqvist * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137ff2e2f81SFredrik Holmqvist * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138ff2e2f81SFredrik Holmqvist * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139ff2e2f81SFredrik Holmqvist * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140ff2e2f81SFredrik Holmqvist * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141ff2e2f81SFredrik Holmqvist * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142ff2e2f81SFredrik Holmqvist * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143ff2e2f81SFredrik Holmqvist * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144ff2e2f81SFredrik Holmqvist * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145ff2e2f81SFredrik Holmqvist *
146ff2e2f81SFredrik Holmqvist * Alternatively, you may choose to be licensed under the terms of the
147ff2e2f81SFredrik Holmqvist * GNU General Public License ("GPL") version 2 as published by the Free
148ff2e2f81SFredrik Holmqvist * Software Foundation.
149ff2e2f81SFredrik Holmqvist *
15079414580SJérôme Duval *****************************************************************************/
15179414580SJérôme Duval
15279414580SJérôme Duval#include "acpi.h"
15380377d9aSJérôme Duval#include "accommon.h"
15479414580SJérôme Duval#include "actables.h"
15579414580SJérôme Duval
15679414580SJérôme Duval#define _COMPONENT          ACPI_TABLES
15779414580SJérôme Duval        ACPI_MODULE_NAME    ("tbfadt")
15879414580SJérôme Duval
15979414580SJérôme Duval/* Local prototypes */
16079414580SJérôme Duval
1616822cda0SFredrik Holmqviststatic void
16279414580SJérôme DuvalAcpiTbInitGenericAddress (
16379414580SJérôme Duval    ACPI_GENERIC_ADDRESS    *GenericAddress,
16480377d9aSJérôme Duval    UINT8                   SpaceId,
16580377d9aSJérôme Duval    UINT8                   ByteWidth,
1666822cda0SFredrik Holmqvist    UINT64                  Address,
16774ffd18dSFredrik Holmqvist    const char              *RegisterName,
168ad5bbfb8SFredrik Holmqvist    UINT8                   Flags);
16979414580SJérôme Duval
17079414580SJérôme Duvalstatic void
17179414580SJérôme DuvalAcpiTbConvertFadt (
17279414580SJérôme Duval    void);
17379414580SJérôme Duval
17480377d9aSJérôme Duvalstatic void
17580377d9aSJérôme DuvalAcpiTbSetupFadtRegisters (
17680377d9aSJérôme Duval    void);
17780377d9aSJérôme Duval
178ad5bbfb8SFredrik Holmqviststatic UINT64
179ad5bbfb8SFredrik HolmqvistAcpiTbSelectAddress (
180ad5bbfb8SFredrik Holmqvist    char                    *RegisterName,
181ad5bbfb8SFredrik Holmqvist    UINT32                  Address32,
182ad5bbfb8SFredrik Holmqvist    UINT64                  Address64);
183ad5bbfb8SFredrik Holmqvist
18479414580SJérôme Duval
18579414580SJérôme Duval/* Table for conversion of FADT to common internal format and FADT validation */
18679414580SJérôme Duval
18779414580SJérôme Duvaltypedef struct acpi_fadt_info
18879414580SJérôme Duval{
18974ffd18dSFredrik Holmqvist    const char              *Name;
1906822cda0SFredrik Holmqvist    UINT16                  Address64;
1916822cda0SFredrik Holmqvist    UINT16                  Address32;
1926822cda0SFredrik Holmqvist    UINT16                  Length;
19380377d9aSJérôme Duval    UINT8                   DefaultLength;
194ad5bbfb8SFredrik Holmqvist    UINT8                   Flags;
19579414580SJérôme Duval
19679414580SJérôme Duval} ACPI_FADT_INFO;
19779414580SJérôme Duval
1986822cda0SFredrik Holmqvist#define ACPI_FADT_OPTIONAL          0
19979414580SJérôme Duval#define ACPI_FADT_REQUIRED          1
20079414580SJérôme Duval#define ACPI_FADT_SEPARATE_LENGTH   2
201ad5bbfb8SFredrik Holmqvist#define ACPI_FADT_GPE_REGISTER      4
20279414580SJérôme Duval
20379414580SJérôme Duvalstatic ACPI_FADT_INFO     FadtInfoTable[] =
20479414580SJérôme Duval{
20580377d9aSJérôme Duval    {"Pm1aEventBlock",
20680377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPm1aEventBlock),
20780377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm1aEventBlock),
20880377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm1EventLength),
20980377d9aSJérôme Duval        ACPI_PM1_REGISTER_WIDTH * 2,        /* Enable + Status register */
21080377d9aSJérôme Duval        ACPI_FADT_REQUIRED},
21180377d9aSJérôme Duval
21280377d9aSJérôme Duval    {"Pm1bEventBlock",
21380377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPm1bEventBlock),
21480377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm1bEventBlock),
21580377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm1EventLength),
21680377d9aSJérôme Duval        ACPI_PM1_REGISTER_WIDTH * 2,        /* Enable + Status register */
2176822cda0SFredrik Holmqvist        ACPI_FADT_OPTIONAL},
21880377d9aSJérôme Duval
21980377d9aSJérôme Duval    {"Pm1aControlBlock",
22080377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPm1aControlBlock),
22180377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm1aControlBlock),
22280377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm1ControlLength),
22380377d9aSJérôme Duval        ACPI_PM1_REGISTER_WIDTH,
22480377d9aSJérôme Duval        ACPI_FADT_REQUIRED},
22580377d9aSJérôme Duval
22680377d9aSJérôme Duval    {"Pm1bControlBlock",
22780377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPm1bControlBlock),
22880377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm1bControlBlock),
22980377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm1ControlLength),
23080377d9aSJérôme Duval        ACPI_PM1_REGISTER_WIDTH,
2316822cda0SFredrik Holmqvist        ACPI_FADT_OPTIONAL},
23280377d9aSJérôme Duval
23380377d9aSJérôme Duval    {"Pm2ControlBlock",
23480377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPm2ControlBlock),
23580377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm2ControlBlock),
23680377d9aSJérôme Duval        ACPI_FADT_OFFSET (Pm2ControlLength),
23780377d9aSJérôme Duval        ACPI_PM2_REGISTER_WIDTH,
23880377d9aSJérôme Duval        ACPI_FADT_SEPARATE_LENGTH},
23980377d9aSJérôme Duval
24080377d9aSJérôme Duval    {"PmTimerBlock",
24180377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPmTimerBlock),
24280377d9aSJérôme Duval        ACPI_FADT_OFFSET (PmTimerBlock),
24380377d9aSJérôme Duval        ACPI_FADT_OFFSET (PmTimerLength),
24480377d9aSJérôme Duval        ACPI_PM_TIMER_WIDTH,
245c70258b7SJérôme Duval        ACPI_FADT_SEPARATE_LENGTH},         /* ACPI 5.0A: Timer is optional */
24680377d9aSJérôme Duval
24780377d9aSJérôme Duval    {"Gpe0Block",
24880377d9aSJérôme Duval        ACPI_FADT_OFFSET (XGpe0Block),
24980377d9aSJérôme Duval        ACPI_FADT_OFFSET (Gpe0Block),
25080377d9aSJérôme Duval        ACPI_FADT_OFFSET (Gpe0BlockLength),
25180377d9aSJérôme Duval        0,
252ad5bbfb8SFredrik Holmqvist        ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER},
25380377d9aSJérôme Duval
25480377d9aSJérôme Duval    {"Gpe1Block",
25580377d9aSJérôme Duval        ACPI_FADT_OFFSET (XGpe1Block),
25680377d9aSJérôme Duval        ACPI_FADT_OFFSET (Gpe1Block),
25780377d9aSJérôme Duval        ACPI_FADT_OFFSET (Gpe1BlockLength),
25880377d9aSJérôme Duval        0,
259ad5bbfb8SFredrik Holmqvist        ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}
26080377d9aSJérôme Duval};
26180377d9aSJérôme Duval
26280377d9aSJérôme Duval#define ACPI_FADT_INFO_ENTRIES \
26380377d9aSJérôme Duval            (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO))
26480377d9aSJérôme Duval
26579414580SJérôme Duval
26680377d9aSJérôme Duval/* Table used to split Event Blocks into separate status/enable registers */
26779414580SJérôme Duval
26880377d9aSJérôme Duvaltypedef struct acpi_fadt_pm_info
26980377d9aSJérôme Duval{
27080377d9aSJérôme Duval    ACPI_GENERIC_ADDRESS    *Target;
2716822cda0SFredrik Holmqvist    UINT16                  Source;
27280377d9aSJérôme Duval    UINT8                   RegisterNum;
27379414580SJérôme Duval
27480377d9aSJérôme Duval} ACPI_FADT_PM_INFO;
27579414580SJérôme Duval
27680377d9aSJérôme Duvalstatic ACPI_FADT_PM_INFO    FadtPmInfoTable[] =
27780377d9aSJérôme Duval{
27880377d9aSJérôme Duval    {&AcpiGbl_XPm1aStatus,
27980377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPm1aEventBlock),
28080377d9aSJérôme Duval        0},
28179414580SJérôme Duval
28280377d9aSJérôme Duval    {&AcpiGbl_XPm1aEnable,
28380377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPm1aEventBlock),
28480377d9aSJérôme Duval        1},
28579414580SJérôme Duval
28680377d9aSJérôme Duval    {&AcpiGbl_XPm1bStatus,
28780377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPm1bEventBlock),
28880377d9aSJérôme Duval        0},
28979414580SJérôme Duval
29080377d9aSJérôme Duval    {&AcpiGbl_XPm1bEnable,
29180377d9aSJérôme Duval        ACPI_FADT_OFFSET (XPm1bEventBlock),
29280377d9aSJérôme Duval        1}
29379414580SJérôme Duval};
29479414580SJérôme Duval
29580377d9aSJérôme Duval#define ACPI_FADT_PM_INFO_ENTRIES \
29680377d9aSJérôme Duval            (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO))
29779414580SJérôme Duval
29879414580SJérôme Duval
29979414580SJérôme Duval/*******************************************************************************
30079414580SJérôme Duval *
30179414580SJérôme Duval * FUNCTION:    AcpiTbInitGenericAddress
30279414580SJérôme Duval *
30379414580SJérôme Duval * PARAMETERS:  GenericAddress      - GAS struct to be initialized
30480377d9aSJérôme Duval *              SpaceId             - ACPI Space ID for this register
3056822cda0SFredrik Holmqvist *              ByteWidth           - Width of this register
30679414580SJérôme Duval *              Address             - Address of the register
307ad5bbfb8SFredrik Holmqvist *              RegisterName        - ASCII name of the ACPI register
30879414580SJérôme Duval *
30979414580SJérôme Duval * RETURN:      None
31079414580SJérôme Duval *
31179414580SJérôme Duval * DESCRIPTION: Initialize a Generic Address Structure (GAS)
31279414580SJérôme Duval *              See the ACPI specification for a full description and
31379414580SJérôme Duval *              definition of this structure.
31479414580SJérôme Duval *
31579414580SJérôme Duval ******************************************************************************/
31679414580SJérôme Duval
3176822cda0SFredrik Holmqviststatic void
31879414580SJérôme DuvalAcpiTbInitGenericAddress (
31979414580SJérôme Duval    ACPI_GENERIC_ADDRESS    *GenericAddress,
32080377d9aSJérôme Duval    UINT8                   SpaceId,
32180377d9aSJérôme Duval    UINT8                   ByteWidth,
3226822cda0SFredrik Holmqvist    UINT64                  Address,
32374ffd18dSFredrik Holmqvist    const char              *RegisterName,
324ad5bbfb8SFredrik Holmqvist    UINT8                   Flags)
32579414580SJérôme Duval{
3266822cda0SFredrik Holmqvist    UINT8                   BitWidth;
3276822cda0SFredrik Holmqvist
3286822cda0SFredrik Holmqvist
329ad5bbfb8SFredrik Holmqvist    /*
330ad5bbfb8SFredrik Holmqvist     * Bit width field in the GAS is only one byte long, 255 max.
331ad5bbfb8SFredrik Holmqvist     * Check for BitWidth overflow in GAS.
332ad5bbfb8SFredrik Holmqvist     */
3336822cda0SFredrik Holmqvist    BitWidth = (UINT8) (ByteWidth * 8);
334ad5bbfb8SFredrik Holmqvist    if (ByteWidth > 31)     /* (31*8)=248, (32*8)=256 */
3356822cda0SFredrik Holmqvist    {
336ad5bbfb8SFredrik Holmqvist        /*
337ad5bbfb8SFredrik Holmqvist         * No error for GPE blocks, because we do not use the BitWidth
338ad5bbfb8SFredrik Holmqvist         * for GPEs, the legacy length (ByteWidth) is used instead to
339ad5bbfb8SFredrik Holmqvist         * allow for a large number of GPEs.
340ad5bbfb8SFredrik Holmqvist         */
341ad5bbfb8SFredrik Holmqvist        if (!(Flags & ACPI_FADT_GPE_REGISTER))
342ad5bbfb8SFredrik Holmqvist        {
343ad5bbfb8SFredrik Holmqvist            ACPI_ERROR ((AE_INFO,
344ad5bbfb8SFredrik Holmqvist                "%s - 32-bit FADT register is too long (%u bytes, %u bits) "
345ad5bbfb8SFredrik Holmqvist                "to convert to GAS struct - 255 bits max, truncating",
346ad5bbfb8SFredrik Holmqvist                RegisterName, ByteWidth, (ByteWidth * 8)));
347ad5bbfb8SFredrik Holmqvist        }
3486822cda0SFredrik Holmqvist
3496822cda0SFredrik Holmqvist        BitWidth = 255;
3506822cda0SFredrik Holmqvist    }
35179414580SJérôme Duval
35279414580SJérôme Duval    /*
35379414580SJérôme Duval     * The 64-bit Address field is non-aligned in the byte packed
35479414580SJérôme Duval     * GAS struct.
35579414580SJérôme Duval     */
35679414580SJérôme Duval    ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address);
35779414580SJérôme Duval
35879414580SJérôme Duval    /* All other fields are byte-wide */
35979414580SJérôme Duval
36080377d9aSJérôme Duval    GenericAddress->SpaceId = SpaceId;
3616822cda0SFredrik Holmqvist    GenericAddress->BitWidth = BitWidth;
36279414580SJérôme Duval    GenericAddress->BitOffset = 0;
36380377d9aSJérôme Duval    GenericAddress->AccessWidth = 0; /* Access width ANY */
36479414580SJérôme Duval}
36579414580SJérôme Duval
36679414580SJérôme Duval
367ad5bbfb8SFredrik Holmqvist/*******************************************************************************
368ad5bbfb8SFredrik Holmqvist *
369ad5bbfb8SFredrik Holmqvist * FUNCTION:    AcpiTbSelectAddress
370ad5bbfb8SFredrik Holmqvist *
371ad5bbfb8SFredrik Holmqvist * PARAMETERS:  RegisterName        - ASCII name of the ACPI register
372ad5bbfb8SFredrik Holmqvist *              Address32           - 32-bit address of the register
373ad5bbfb8SFredrik Holmqvist *              Address64           - 64-bit address of the register
374ad5bbfb8SFredrik Holmqvist *
375ad5bbfb8SFredrik Holmqvist * RETURN:      The resolved 64-bit address
376ad5bbfb8SFredrik Holmqvist *
377ad5bbfb8SFredrik Holmqvist * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within
378ad5bbfb8SFredrik Holmqvist *              the FADT. Used for the FACS and DSDT addresses.
379ad5bbfb8SFredrik Holmqvist *
380ad5bbfb8SFredrik Holmqvist * NOTES:
381ad5bbfb8SFredrik Holmqvist *
382ad5bbfb8SFredrik Holmqvist * Check for FACS and DSDT address mismatches. An address mismatch between
383ad5bbfb8SFredrik Holmqvist * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
384ad5bbfb8SFredrik Holmqvist * DSDT/X_DSDT) could be a corrupted address field or it might indicate
385ad5bbfb8SFredrik Holmqvist * the presence of two FACS or two DSDT tables.
386ad5bbfb8SFredrik Holmqvist *
387ad5bbfb8SFredrik Holmqvist * November 2013:
388ad5bbfb8SFredrik Holmqvist * By default, as per the ACPICA specification, a valid 64-bit address is
389ad5bbfb8SFredrik Holmqvist * used regardless of the value of the 32-bit address. However, this
390ad5bbfb8SFredrik Holmqvist * behavior can be overridden via the AcpiGbl_Use32BitFadtAddresses flag.
391ad5bbfb8SFredrik Holmqvist *
392ad5bbfb8SFredrik Holmqvist ******************************************************************************/
393ad5bbfb8SFredrik Holmqvist
394ad5bbfb8SFredrik Holmqviststatic UINT64
395ad5bbfb8SFredrik HolmqvistAcpiTbSelectAddress (
396ad5bbfb8SFredrik Holmqvist    char                    *RegisterName,
397ad5bbfb8SFredrik Holmqvist    UINT32                  Address32,
398ad5bbfb8SFredrik Holmqvist    UINT64                  Address64)
399ad5bbfb8SFredrik Holmqvist{
400ad5bbfb8SFredrik Holmqvist
401ad5bbfb8SFredrik Holmqvist    if (!Address64)
402ad5bbfb8SFredrik Holmqvist    {
403ad5bbfb8SFredrik Holmqvist        /* 64-bit address is zero, use 32-bit address */
404ad5bbfb8SFredrik Holmqvist
405ad5bbfb8SFredrik Holmqvist        return ((UINT64) Address32);
406ad5bbfb8SFredrik Holmqvist    }
407ad5bbfb8SFredrik Holmqvist
408ad5bbfb8SFredrik Holmqvist    if (Address32 &&
409ad5bbfb8SFredrik Holmqvist       (Address64 != (UINT64) Address32))
410ad5bbfb8SFredrik Holmqvist    {
411ad5bbfb8SFredrik Holmqvist        /* Address mismatch between 32-bit and 64-bit versions */
412ad5bbfb8SFredrik Holmqvist
413ad5bbfb8SFredrik Holmqvist        ACPI_BIOS_WARNING ((AE_INFO,
414ad5bbfb8SFredrik Holmqvist            "32/64X %s address mismatch in FADT: "
415ad5bbfb8SFredrik Holmqvist            "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
416ad5bbfb8SFredrik Holmqvist            RegisterName, Address32, ACPI_FORMAT_UINT64 (Address64),
417ad5bbfb8SFredrik Holmqvist            AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
418ad5bbfb8SFredrik Holmqvist
419ad5bbfb8SFredrik Holmqvist        /* 32-bit address override */
420ad5bbfb8SFredrik Holmqvist
421ad5bbfb8SFredrik Holmqvist        if (AcpiGbl_Use32BitFadtAddresses)
422ad5bbfb8SFredrik Holmqvist        {
423ad5bbfb8SFredrik Holmqvist            return ((UINT64) Address32);
424ad5bbfb8SFredrik Holmqvist        }
425ad5bbfb8SFredrik Holmqvist    }
426ad5bbfb8SFredrik Holmqvist
427ad5bbfb8SFredrik Holmqvist    /* Default is to use the 64-bit address */
428ad5bbfb8SFredrik Holmqvist
429ad5bbfb8SFredrik Holmqvist    return (Address64);
430ad5bbfb8SFredrik Holmqvist}
431ad5bbfb8SFredrik Holmqvist
432ad5bbfb8SFredrik Holmqvist
43379414580SJérôme Duval/*******************************************************************************
43479414580SJérôme Duval *
43579414580SJérôme Duval * FUNCTION:    AcpiTbParseFadt
43679414580SJérôme Duval *
437b64e8511SFredrik Holmqvist * PARAMETERS:  None
43879414580SJérôme Duval *
43979414580SJérôme Duval * RETURN:      None
44079414580SJérôme Duval *
44179414580SJérôme Duval * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
44279414580SJérôme Duval *              (FADT contains the addresses of the DSDT and FACS)
44379414580SJérôme Duval *
44479414580SJérôme Duval ******************************************************************************/
44579414580SJérôme Duval
44679414580SJérôme Duvalvoid
44779414580SJérôme DuvalAcpiTbParseFadt (
448b64e8511SFredrik Holmqvist    void)
44979414580SJérôme Duval{
45079414580SJérôme Duval    UINT32                  Length;
45179414580SJérôme Duval    ACPI_TABLE_HEADER       *Table;
452ff2e2f81SFredrik Holmqvist    ACPI_TABLE_DESC         *FadtDesc;
453ff2e2f81SFredrik Holmqvist    ACPI_STATUS             Status;
45479414580SJérôme Duval
45579414580SJérôme Duval
45679414580SJérôme Duval    /*
45779414580SJérôme Duval     * The FADT has multiple versions with different lengths,
45879414580SJérôme Duval     * and it contains pointers to both the DSDT and FACS tables.
45979414580SJérôme Duval     *
46079414580SJérôme Duval     * Get a local copy of the FADT and convert it to a common format
46179414580SJérôme Duval     * Map entire FADT, assumed to be smaller than one page.
46279414580SJérôme Duval     */
463ff2e2f81SFredrik Holmqvist    FadtDesc = &AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex];
464ff2e2f81SFredrik Holmqvist    Status = AcpiTbGetTable (FadtDesc, &Table);
465ff2e2f81SFredrik Holmqvist    if (ACPI_FAILURE (Status))
46679414580SJérôme Duval    {
46779414580SJérôme Duval        return;
46879414580SJérôme Duval    }
469ff2e2f81SFredrik Holmqvist    Length = FadtDesc->Length;
47079414580SJérôme Duval
47179414580SJérôme Duval    /*
47279414580SJérôme Duval     * Validate the FADT checksum before we copy the table. Ignore
47379414580SJérôme Duval     * checksum error as we want to try to get the DSDT and FACS.
47479414580SJérôme Duval     */
47579414580SJérôme Duval    (void) AcpiTbVerifyChecksum (Table, Length);
47679414580SJérôme Duval
47780377d9aSJérôme Duval    /* Create a local copy of the FADT in common ACPI 2.0+ format */
47879414580SJérôme Duval
47979414580SJérôme Duval    AcpiTbCreateLocalFadt (Table, Length);
48079414580SJérôme Duval
48179414580SJérôme Duval    /* All done with the real FADT, unmap it */
48279414580SJérôme Duval
483ff2e2f81SFredrik Holmqvist    AcpiTbPutTable (FadtDesc);
48479414580SJérôme Duval
48579414580SJérôme Duval    /* Obtain the DSDT and FACS tables via their addresses within the FADT */
48679414580SJérôme Duval
487ff2e2f81SFredrik Holmqvist    AcpiTbInstallStandardTable (
488ff2e2f81SFredrik Holmqvist        (ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt,
489ff2e2f81SFredrik Holmqvist        ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, FALSE, TRUE,
490ff2e2f81SFredrik Holmqvist        &AcpiGbl_DsdtIndex);
49179414580SJérôme Duval
4926822cda0SFredrik Holmqvist    /* If Hardware Reduced flag is set, there is no FACS */
4936822cda0SFredrik Holmqvist
4946822cda0SFredrik Holmqvist    if (!AcpiGbl_ReducedHardware)
4956822cda0SFredrik Holmqvist    {
496e226d1d0SFredrik Holmqvist        if (AcpiGbl_FADT.Facs)
497e226d1d0SFredrik Holmqvist        {
498ff2e2f81SFredrik Holmqvist            AcpiTbInstallStandardTable (
499ff2e2f81SFredrik Holmqvist                (ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.Facs,
500ff2e2f81SFredrik Holmqvist                ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, FALSE, TRUE,
501ff2e2f81SFredrik Holmqvist                &AcpiGbl_FacsIndex);
502e226d1d0SFredrik Holmqvist        }
503e226d1d0SFredrik Holmqvist        if (AcpiGbl_FADT.XFacs)
504e226d1d0SFredrik Holmqvist        {
505ff2e2f81SFredrik Holmqvist            AcpiTbInstallStandardTable (
506ff2e2f81SFredrik Holmqvist                (ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,
507ff2e2f81SFredrik Holmqvist                ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, FALSE, TRUE,
508ff2e2f81SFredrik Holmqvist                &AcpiGbl_XFacsIndex);
509e226d1d0SFredrik Holmqvist        }
5106822cda0SFredrik Holmqvist    }
51179414580SJérôme Duval}
51279414580SJérôme Duval
51379414580SJérôme Duval
51479414580SJérôme Duval/*******************************************************************************
51579414580SJérôme Duval *
51679414580SJérôme Duval * FUNCTION:    AcpiTbCreateLocalFadt
51779414580SJérôme Duval *
51879414580SJérôme Duval * PARAMETERS:  Table               - Pointer to BIOS FADT
51979414580SJérôme Duval *              Length              - Length of the table
52079414580SJérôme Duval *
52179414580SJérôme Duval * RETURN:      None
52279414580SJérôme Duval *
52379414580SJérôme Duval * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
52479414580SJérôme Duval *              Performs validation on some important FADT fields.
52579414580SJérôme Duval *
5262608583eSJérôme Duval * NOTE:        We create a local copy of the FADT regardless of the version.
5272608583eSJérôme Duval *
52879414580SJérôme Duval ******************************************************************************/
52979414580SJérôme Duval
53079414580SJérôme Duvalvoid
53179414580SJérôme DuvalAcpiTbCreateLocalFadt (
53279414580SJérôme Duval    ACPI_TABLE_HEADER       *Table,
53379414580SJérôme Duval    UINT32                  Length)
53479414580SJérôme Duval{
53579414580SJérôme Duval
53679414580SJérôme Duval    /*
5372608583eSJérôme Duval     * Check if the FADT is larger than the largest table that we expect
53874ffd18dSFredrik Holmqvist     * (typically the current ACPI specification version). If so, truncate
53974ffd18dSFredrik Holmqvist     * the table, and issue a warning.
54079414580SJérôme Duval     */
54179414580SJérôme Duval    if (Length > sizeof (ACPI_TABLE_FADT))
54279414580SJérôme Duval    {
5436822cda0SFredrik Holmqvist        ACPI_BIOS_WARNING ((AE_INFO,
54474ffd18dSFredrik Holmqvist            "FADT (revision %u) is longer than %s length, "
545ffb873afSFredrik Holmqvist            "truncating length %u to %u",
54674ffd18dSFredrik Holmqvist            Table->Revision, ACPI_FADT_CONFORMANCE, Length,
54774ffd18dSFredrik Holmqvist            (UINT32) sizeof (ACPI_TABLE_FADT)));
54879414580SJérôme Duval    }
54979414580SJérôme Duval
5502608583eSJérôme Duval    /* Clear the entire local FADT */
55179414580SJérôme Duval
552e226d1d0SFredrik Holmqvist    memset (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));
55379414580SJérôme Duval
5542608583eSJérôme Duval    /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */
5552608583eSJérôme Duval
556e226d1d0SFredrik Holmqvist    memcpy (&AcpiGbl_FADT, Table,
55779414580SJérôme Duval        ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));
55879414580SJérôme Duval
5596822cda0SFredrik Holmqvist    /* Take a copy of the Hardware Reduced flag */
5606822cda0SFredrik Holmqvist
5616822cda0SFredrik Holmqvist    AcpiGbl_ReducedHardware = FALSE;
5626822cda0SFredrik Holmqvist    if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED)
5636822cda0SFredrik Holmqvist    {
5646822cda0SFredrik Holmqvist        AcpiGbl_ReducedHardware = TRUE;
5656822cda0SFredrik Holmqvist    }
5666822cda0SFredrik Holmqvist
56780377d9aSJérôme Duval    /* Convert the local copy of the FADT to the common internal format */
56880377d9aSJérôme Duval
56979414580SJérôme Duval    AcpiTbConvertFadt ();
57080377d9aSJérôme Duval
57180377d9aSJérôme Duval    /* Initialize the global ACPI register structures */
57280377d9aSJérôme Duval
57380377d9aSJérôme Duval    AcpiTbSetupFadtRegisters ();
57479414580SJérôme Duval}
57579414580SJérôme Duval
57679414580SJérôme Duval
57779414580SJérôme Duval/*******************************************************************************
57879414580SJérôme Duval *
57979414580SJérôme Duval * FUNCTION:    AcpiTbConvertFadt
58079414580SJérôme Duval *
581ad5bbfb8SFredrik Holmqvist * PARAMETERS:  None - AcpiGbl_FADT is used.
58279414580SJérôme Duval *
58379414580SJérôme Duval * RETURN:      None
58479414580SJérôme Duval *
58579414580SJérôme Duval * DESCRIPTION: Converts all versions of the FADT to a common internal format.
586ad5bbfb8SFredrik Holmqvist *              Expand 32-bit addresses to 64-bit as necessary. Also validate
587ad5bbfb8SFredrik Holmqvist *              important fields within the FADT.
58879414580SJérôme Duval *
589ad5bbfb8SFredrik Holmqvist * NOTE:        AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), and must
590ad5bbfb8SFredrik Holmqvist *              contain a copy of the actual BIOS-provided FADT.
59179414580SJérôme Duval *
59280377d9aSJérôme Duval * Notes on 64-bit register addresses:
59379414580SJérôme Duval *
59480377d9aSJérôme Duval * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
59580377d9aSJérôme Duval * fields of the FADT for all ACPI register addresses.
59679414580SJérôme Duval *
597ad5bbfb8SFredrik Holmqvist * The 64-bit X fields are optional extensions to the original 32-bit FADT
59880377d9aSJérôme Duval * V1.0 fields. Even if they are present in the FADT, they are optional and
59980377d9aSJérôme Duval * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
600ff2e2f81SFredrik Holmqvist * 32-bit V1.0 fields to the 64-bit X fields if the 64-bit X field is originally
601ff2e2f81SFredrik Holmqvist * zero.
60279414580SJérôme Duval *
603ad5bbfb8SFredrik Holmqvist * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address
604ad5bbfb8SFredrik Holmqvist * fields are expanded to the corresponding 64-bit X fields in the internal
605ad5bbfb8SFredrik Holmqvist * common FADT.
60680377d9aSJérôme Duval *
60780377d9aSJérôme Duval * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
608ad5bbfb8SFredrik Holmqvist * to the corresponding 64-bit X fields, if the 64-bit field is originally
609ad5bbfb8SFredrik Holmqvist * zero. Adhering to the ACPI specification, we completely ignore the 32-bit
610ad5bbfb8SFredrik Holmqvist * field if the 64-bit field is valid, regardless of whether the host OS is
611ad5bbfb8SFredrik Holmqvist * 32-bit or 64-bit.
612ad5bbfb8SFredrik Holmqvist *
613ad5bbfb8SFredrik Holmqvist * Possible additional checks:
614ad5bbfb8SFredrik Holmqvist *  (AcpiGbl_FADT.Pm1EventLength >= 4)
615ad5bbfb8SFredrik Holmqvist *  (AcpiGbl_FADT.Pm1ControlLength >= 2)
616ad5bbfb8SFredrik Holmqvist *  (AcpiGbl_FADT.PmTimerLength >= 4)
617ad5bbfb8SFredrik Holmqvist *  Gpe block lengths must be multiple of 2
61879414580SJérôme Duval *
61979414580SJérôme Duval ******************************************************************************/
62079414580SJérôme Duval
62179414580SJérôme Duvalstatic void
62279414580SJérôme DuvalAcpiTbConvertFadt (
62379414580SJérôme Duval    void)
62479414580SJérôme Duval{
62574ffd18dSFredrik Holmqvist    const char              *Name;
62680377d9aSJérôme Duval    ACPI_GENERIC_ADDRESS    *Address64;
62780377d9aSJérôme Duval    UINT32                  Address32;
628ad5bbfb8SFredrik Holmqvist    UINT8                   Length;
629ad5bbfb8SFredrik Holmqvist    UINT8                   Flags;
63045e9de08SJérôme Duval    UINT32                  i;
63179414580SJérôme Duval
63279414580SJérôme Duval
63379414580SJérôme Duval    /*
634ff2e2f81SFredrik Holmqvist     * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
6352608583eSJérôme Duval     * should be zero are indeed zero. This will workaround BIOSs that
6362608583eSJérôme Duval     * inadvertently place values in these fields.
6372608583eSJérôme Duval     *
63880377d9aSJérôme Duval     * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
63980377d9aSJérôme Duval     * at offset 45, 55, 95, and the word located at offset 109, 110.
640fcb8a5cbSFredrik Holmqvist     *
641ff2e2f81SFredrik Holmqvist     * Note: The FADT revision value is unreliable. Only the length can be
642ff2e2f81SFredrik Holmqvist     * trusted.
6432608583eSJérôme Duval     */
644ff2e2f81SFredrik Holmqvist    if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
6452608583eSJérôme Duval    {
6462608583eSJérôme Duval        AcpiGbl_FADT.PreferredProfile = 0;
6472608583eSJérôme Duval        AcpiGbl_FADT.PstateControl = 0;
6482608583eSJérôme Duval        AcpiGbl_FADT.CstControl = 0;
6492608583eSJérôme Duval        AcpiGbl_FADT.BootFlags = 0;
6502608583eSJérôme Duval    }
6512608583eSJérôme Duval
6526822cda0SFredrik Holmqvist    /*
6536822cda0SFredrik Holmqvist     * Now we can update the local FADT length to the length of the
6546822cda0SFredrik Holmqvist     * current FADT version as defined by the ACPI specification.
6556822cda0SFredrik Holmqvist     * Thus, we will have a common FADT internally.
6566822cda0SFredrik Holmqvist     */
6576822cda0SFredrik Holmqvist    AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);
6586822cda0SFredrik Holmqvist
6592608583eSJérôme Duval    /*
660e226d1d0SFredrik Holmqvist     * Expand the 32-bit DSDT addresses to 64-bit as necessary.
661ad5bbfb8SFredrik Holmqvist     * Later ACPICA code will always use the X 64-bit field.
66280377d9aSJérôme Duval     */
663ad5bbfb8SFredrik Holmqvist    AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT",
664ad5bbfb8SFredrik Holmqvist        AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt);
66580377d9aSJérôme Duval
6666822cda0SFredrik Holmqvist    /* If Hardware Reduced flag is set, we are all done */
6676822cda0SFredrik Holmqvist
6686822cda0SFredrik Holmqvist    if (AcpiGbl_ReducedHardware)
6696822cda0SFredrik Holmqvist    {
6706822cda0SFredrik Holmqvist        return;
6716822cda0SFredrik Holmqvist    }
6726822cda0SFredrik Holmqvist
67379414580SJérôme Duval    /* Examine all of the 64-bit extended address fields (X fields) */
67479414580SJérôme Duval
67579414580SJérôme Duval    for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
67679414580SJérôme Duval    {
67780377d9aSJérôme Duval        /*
678ad5bbfb8SFredrik Holmqvist         * Get the 32-bit and 64-bit addresses, as well as the register
679ad5bbfb8SFredrik Holmqvist         * length and register name.
68080377d9aSJérôme Duval         */
681ad5bbfb8SFredrik Holmqvist        Address32 = *ACPI_ADD_PTR (UINT32,
682ad5bbfb8SFredrik Holmqvist            &AcpiGbl_FADT, FadtInfoTable[i].Address32);
683ad5bbfb8SFredrik Holmqvist
68480377d9aSJérôme Duval        Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
685ad5bbfb8SFredrik Holmqvist            &AcpiGbl_FADT, FadtInfoTable[i].Address64);
686ad5bbfb8SFredrik Holmqvist
68780377d9aSJérôme Duval        Length = *ACPI_ADD_PTR (UINT8,
688ad5bbfb8SFredrik Holmqvist            &AcpiGbl_FADT, FadtInfoTable[i].Length);
689ad5bbfb8SFredrik Holmqvist
69080377d9aSJérôme Duval        Name = FadtInfoTable[i].Name;
691ad5bbfb8SFredrik Holmqvist        Flags = FadtInfoTable[i].Flags;
692ad5bbfb8SFredrik Holmqvist
693ad5bbfb8SFredrik Holmqvist        /*
694ad5bbfb8SFredrik Holmqvist         * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
695ad5bbfb8SFredrik Holmqvist         * generic address structures as necessary. Later code will always use
696ad5bbfb8SFredrik Holmqvist         * the 64-bit address structures.
697ad5bbfb8SFredrik Holmqvist         *
698ad5bbfb8SFredrik Holmqvist         * November 2013:
699ad5bbfb8SFredrik Holmqvist         * Now always use the 64-bit address if it is valid (non-zero), in
700ad5bbfb8SFredrik Holmqvist         * accordance with the ACPI specification which states that a 64-bit
701ad5bbfb8SFredrik Holmqvist         * address supersedes the 32-bit version. This behavior can be
702ad5bbfb8SFredrik Holmqvist         * overridden by the AcpiGbl_Use32BitFadtAddresses flag.
703ad5bbfb8SFredrik Holmqvist         *
704ad5bbfb8SFredrik Holmqvist         * During 64-bit address construction and verification,
705ad5bbfb8SFredrik Holmqvist         * these cases are handled:
706ad5bbfb8SFredrik Holmqvist         *
707ad5bbfb8SFredrik Holmqvist         * Address32 zero, Address64 [don't care]   - Use Address64
708ad5bbfb8SFredrik Holmqvist         *
709ff2e2f81SFredrik Holmqvist         * No override: if AcpiGbl_Use32BitFadtAddresses is FALSE, and:
710ad5bbfb8SFredrik Holmqvist         * Address32 non-zero, Address64 zero       - Copy/use Address32
711ad5bbfb8SFredrik Holmqvist         * Address32 non-zero == Address64 non-zero - Use Address64
712ad5bbfb8SFredrik Holmqvist         * Address32 non-zero != Address64 non-zero - Warning, use Address64
713ad5bbfb8SFredrik Holmqvist         *
714ad5bbfb8SFredrik Holmqvist         * Override: if AcpiGbl_Use32BitFadtAddresses is TRUE, and:
715ff2e2f81SFredrik Holmqvist         * Address32 non-zero, Address64 zero       - Copy/use Address32
716ff2e2f81SFredrik Holmqvist         * Address32 non-zero == Address64 non-zero - Copy/use Address32
717ad5bbfb8SFredrik Holmqvist         * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
718ad5bbfb8SFredrik Holmqvist         *
719ad5bbfb8SFredrik Holmqvist         * Note: SpaceId is always I/O for 32-bit legacy address fields
720ad5bbfb8SFredrik Holmqvist         */
721ad5bbfb8SFredrik Holmqvist        if (Address32)
722ad5bbfb8SFredrik Holmqvist        {
723ff2e2f81SFredrik Holmqvist            if (Address64->Address)
7243f04c835SFredrik Holmqvist            {
725ff2e2f81SFredrik Holmqvist                if (Address64->Address != (UINT64) Address32)
7260bc647d6SAlexander von Gluck IV                {
727ff2e2f81SFredrik Holmqvist                    /* Address mismatch */
728ff2e2f81SFredrik Holmqvist
729ff2e2f81SFredrik Holmqvist                    ACPI_BIOS_WARNING ((AE_INFO,
730ff2e2f81SFredrik Holmqvist                        "32/64X address mismatch in FADT/%s: "
731ff2e2f81SFredrik Holmqvist                        "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
732ff2e2f81SFredrik Holmqvist                        Name, Address32,
733ff2e2f81SFredrik Holmqvist                        ACPI_FORMAT_UINT64 (Address64->Address),
734ff2e2f81SFredrik Holmqvist                        AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
735ff2e2f81SFredrik Holmqvist                }
7363f04c835SFredrik Holmqvist
737ff2e2f81SFredrik Holmqvist                /*
738ff2e2f81SFredrik Holmqvist                 * For each extended field, check for length mismatch
739ff2e2f81SFredrik Holmqvist                 * between the legacy length field and the corresponding
740ff2e2f81SFredrik Holmqvist                 * 64-bit X length field.
741ff2e2f81SFredrik Holmqvist                 * Note: If the legacy length field is > 0xFF bits, ignore
742ff2e2f81SFredrik Holmqvist                 * this check. (GPE registers can be larger than the
743ff2e2f81SFredrik Holmqvist                 * 64-bit GAS structure can accomodate, 0xFF bits).
744ff2e2f81SFredrik Holmqvist                 */
745ff2e2f81SFredrik Holmqvist                if ((ACPI_MUL_8 (Length) <= ACPI_UINT8_MAX) &&
746ff2e2f81SFredrik Holmqvist                    (Address64->BitWidth != ACPI_MUL_8 (Length)))
747ff2e2f81SFredrik Holmqvist                {
748ff2e2f81SFredrik Holmqvist                    ACPI_BIOS_WARNING ((AE_INFO,
749ff2e2f81SFredrik Holmqvist                        "32/64X length mismatch in FADT/%s: %u/%u",
750ff2e2f81SFredrik Holmqvist                        Name, ACPI_MUL_8 (Length), Address64->BitWidth));
751ad5bbfb8SFredrik Holmqvist                }
752ad5bbfb8SFredrik Holmqvist            }
75380377d9aSJérôme Duval
754ff2e2f81SFredrik Holmqvist            /*
755ff2e2f81SFredrik Holmqvist             * Hardware register access code always uses the 64-bit fields.
756ff2e2f81SFredrik Holmqvist             * So if the 64-bit field is zero or is to be overridden,
757ff2e2f81SFredrik Holmqvist             * initialize it with the 32-bit fields.
758ff2e2f81SFredrik Holmqvist             * Note that when the 32-bit address favor is specified, the
759ff2e2f81SFredrik Holmqvist             * 64-bit fields are always re-initialized so that
760ff2e2f81SFredrik Holmqvist             * AccessSize/BitWidth/BitOffset fields can be correctly
761ff2e2f81SFredrik Holmqvist             * configured to the values to trigger a 32-bit compatible
762ff2e2f81SFredrik Holmqvist             * access mode in the hardware register access code.
763ff2e2f81SFredrik Holmqvist             */
764ff2e2f81SFredrik Holmqvist            if (!Address64->Address || AcpiGbl_Use32BitFadtAddresses)
765ff2e2f81SFredrik Holmqvist            {
766ff2e2f81SFredrik Holmqvist                AcpiTbInitGenericAddress (Address64,
767ff2e2f81SFredrik Holmqvist                    ACPI_ADR_SPACE_SYSTEM_IO, Length,
768ff2e2f81SFredrik Holmqvist                    (UINT64) Address32, Name, Flags);
769ff2e2f81SFredrik Holmqvist            }
77080377d9aSJérôme Duval        }
77179414580SJérôme Duval
772ad5bbfb8SFredrik Holmqvist        if (FadtInfoTable[i].Flags & ACPI_FADT_REQUIRED)
77379414580SJérôme Duval        {
77479414580SJérôme Duval            /*
775c70258b7SJérôme Duval             * Field is required (PM1aEvent, PM1aControl).
77679414580SJérôme Duval             * Both the address and length must be non-zero.
77779414580SJérôme Duval             */
77879414580SJérôme Duval            if (!Address64->Address || !Length)
77979414580SJérôme Duval            {
7806822cda0SFredrik Holmqvist                ACPI_BIOS_ERROR ((AE_INFO,
7816822cda0SFredrik Holmqvist                    "Required FADT field %s has zero address and/or length: "
7826822cda0SFredrik Holmqvist                    "0x%8.8X%8.8X/0x%X",
78380377d9aSJérôme Duval                    Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
78479414580SJérôme Duval            }
78579414580SJérôme Duval        }
786ad5bbfb8SFredrik Holmqvist        else if (FadtInfoTable[i].Flags & ACPI_FADT_SEPARATE_LENGTH)
78779414580SJérôme Duval        {
78879414580SJérôme Duval            /*
78979414580SJérôme Duval             * Field is optional (PM2Control, GPE0, GPE1) AND has its own
79080377d9aSJérôme Duval             * length field. If present, both the address and length must
79180377d9aSJérôme Duval             * be valid.
79279414580SJérôme Duval             */
79380377d9aSJérôme Duval            if ((Address64->Address && !Length) ||
79480377d9aSJérôme Duval                (!Address64->Address && Length))
79579414580SJérôme Duval            {
7966822cda0SFredrik Holmqvist                ACPI_BIOS_WARNING ((AE_INFO,
79774ffd18dSFredrik Holmqvist                    "Optional FADT field %s has valid %s but zero %s: "
79874ffd18dSFredrik Holmqvist                    "0x%8.8X%8.8X/0x%X", Name,
79974ffd18dSFredrik Holmqvist                    (Length ? "Length" : "Address"),
80074ffd18dSFredrik Holmqvist                    (Length ? "Address": "Length"),
80174ffd18dSFredrik Holmqvist                    ACPI_FORMAT_UINT64 (Address64->Address), Length));
80279414580SJérôme Duval            }
80379414580SJérôme Duval        }
80480377d9aSJérôme Duval    }
80580377d9aSJérôme Duval}
80679414580SJérôme Duval
80779414580SJérôme Duval
80880377d9aSJérôme Duval/*******************************************************************************
80980377d9aSJérôme Duval *
81080377d9aSJérôme Duval * FUNCTION:    AcpiTbSetupFadtRegisters
81180377d9aSJérôme Duval *
81280377d9aSJérôme Duval * PARAMETERS:  None, uses AcpiGbl_FADT.
81380377d9aSJérôme Duval *
81480377d9aSJérôme Duval * RETURN:      None
81580377d9aSJérôme Duval *
81680377d9aSJérôme Duval * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
81780377d9aSJérôme Duval *              force FADT register definitions to their default lengths.
81880377d9aSJérôme Duval *
81980377d9aSJérôme Duval ******************************************************************************/
82080377d9aSJérôme Duval
82180377d9aSJérôme Duvalstatic void
82280377d9aSJérôme DuvalAcpiTbSetupFadtRegisters (
82380377d9aSJérôme Duval    void)
82480377d9aSJérôme Duval{
82580377d9aSJérôme Duval    ACPI_GENERIC_ADDRESS    *Target64;
82680377d9aSJérôme Duval    ACPI_GENERIC_ADDRESS    *Source64;
82780377d9aSJérôme Duval    UINT8                   Pm1RegisterByteWidth;
82880377d9aSJérôme Duval    UINT32                  i;
82980377d9aSJérôme Duval
83080377d9aSJérôme Duval
83180377d9aSJérôme Duval    /*
83280377d9aSJérôme Duval     * Optionally check all register lengths against the default values and
83380377d9aSJérôme Duval     * update them if they are incorrect.
83480377d9aSJérôme Duval     */
83580377d9aSJérôme Duval    if (AcpiGbl_UseDefaultRegisterWidths)
83680377d9aSJérôme Duval    {
83780377d9aSJérôme Duval        for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
83879414580SJérôme Duval        {
83980377d9aSJérôme Duval            Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
84080377d9aSJérôme Duval                FadtInfoTable[i].Address64);
84180377d9aSJérôme Duval
84280377d9aSJérôme Duval            /*
84380377d9aSJérôme Duval             * If a valid register (Address != 0) and the (DefaultLength > 0)
84480377d9aSJérôme Duval             * (Not a GPE register), then check the width against the default.
84580377d9aSJérôme Duval             */
84680377d9aSJérôme Duval            if ((Target64->Address) &&
84780377d9aSJérôme Duval                (FadtInfoTable[i].DefaultLength > 0) &&
84880377d9aSJérôme Duval                (FadtInfoTable[i].DefaultLength != Target64->BitWidth))
84980377d9aSJérôme Duval            {
8506822cda0SFredrik Holmqvist                ACPI_BIOS_WARNING ((AE_INFO,
8516822cda0SFredrik Holmqvist                    "Invalid length for FADT/%s: %u, using default %u",
85280377d9aSJérôme Duval                    FadtInfoTable[i].Name, Target64->BitWidth,
85380377d9aSJérôme Duval                    FadtInfoTable[i].DefaultLength));
85480377d9aSJérôme Duval
85580377d9aSJérôme Duval                /* Incorrect size, set width to the default */
85680377d9aSJérôme Duval
85780377d9aSJérôme Duval                Target64->BitWidth = FadtInfoTable[i].DefaultLength;
85880377d9aSJérôme Duval            }
85980377d9aSJérôme Duval        }
86080377d9aSJérôme Duval    }
86180377d9aSJérôme Duval
86280377d9aSJérôme Duval    /*
86380377d9aSJérôme Duval     * Get the length of the individual PM1 registers (enable and status).
86480377d9aSJérôme Duval     * Each register is defined to be (event block length / 2). Extra divide
86580377d9aSJérôme Duval     * by 8 converts bits to bytes.
86680377d9aSJérôme Duval     */
86780377d9aSJérôme Duval    Pm1RegisterByteWidth = (UINT8)
86880377d9aSJérôme Duval        ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth);
86980377d9aSJérôme Duval
87080377d9aSJérôme Duval    /*
87180377d9aSJérôme Duval     * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
87280377d9aSJérôme Duval     * registers. These addresses do not appear (directly) in the FADT, so it
87380377d9aSJérôme Duval     * is useful to pre-calculate them from the PM1 Event Block definitions.
87480377d9aSJérôme Duval     *
87580377d9aSJérôme Duval     * The PM event blocks are split into two register blocks, first is the
87680377d9aSJérôme Duval     * PM Status Register block, followed immediately by the PM Enable
87780377d9aSJérôme Duval     * Register block. Each is of length (Pm1EventLength/2)
87880377d9aSJérôme Duval     *
87980377d9aSJérôme Duval     * Note: The PM1A event block is required by the ACPI specification.
88080377d9aSJérôme Duval     * However, the PM1B event block is optional and is rarely, if ever,
88180377d9aSJérôme Duval     * used.
88280377d9aSJérôme Duval     */
88380377d9aSJérôme Duval
88480377d9aSJérôme Duval    for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++)
88580377d9aSJérôme Duval    {
88680377d9aSJérôme Duval        Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
88780377d9aSJérôme Duval            FadtPmInfoTable[i].Source);
88880377d9aSJérôme Duval
88980377d9aSJérôme Duval        if (Source64->Address)
89080377d9aSJérôme Duval        {
89180377d9aSJérôme Duval            AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,
89280377d9aSJérôme Duval                Source64->SpaceId, Pm1RegisterByteWidth,
89380377d9aSJérôme Duval                Source64->Address +
8946822cda0SFredrik Holmqvist                    (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth),
895ad5bbfb8SFredrik Holmqvist                "PmRegisters", 0);
89679414580SJérôme Duval        }
89779414580SJérôme Duval    }
89879414580SJérôme Duval}
899