1a159c266SJung-uk Kim /****************************************************************************** 2a159c266SJung-uk Kim * 3a159c266SJung-uk Kim * Module Name: tbfadt - FADT table utilities 4a159c266SJung-uk Kim * 5a159c266SJung-uk Kim *****************************************************************************/ 6a159c266SJung-uk Kim 70d84335fSJung-uk Kim /****************************************************************************** 80d84335fSJung-uk Kim * 90d84335fSJung-uk Kim * 1. Copyright Notice 100d84335fSJung-uk Kim * 11*804fe266SJung-uk Kim * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 12a159c266SJung-uk Kim * All rights reserved. 13a159c266SJung-uk Kim * 140d84335fSJung-uk Kim * 2. License 150d84335fSJung-uk Kim * 160d84335fSJung-uk Kim * 2.1. This is your license from Intel Corp. under its intellectual property 170d84335fSJung-uk Kim * rights. You may have additional license terms from the party that provided 180d84335fSJung-uk Kim * you this software, covering your right to use that party's intellectual 190d84335fSJung-uk Kim * property rights. 200d84335fSJung-uk Kim * 210d84335fSJung-uk Kim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 220d84335fSJung-uk Kim * copy of the source code appearing in this file ("Covered Code") an 230d84335fSJung-uk Kim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 240d84335fSJung-uk Kim * base code distributed originally by Intel ("Original Intel Code") to copy, 250d84335fSJung-uk Kim * make derivatives, distribute, use and display any portion of the Covered 260d84335fSJung-uk Kim * Code in any form, with the right to sublicense such rights; and 270d84335fSJung-uk Kim * 280d84335fSJung-uk Kim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 290d84335fSJung-uk Kim * license (with the right to sublicense), under only those claims of Intel 300d84335fSJung-uk Kim * patents that are infringed by the Original Intel Code, to make, use, sell, 310d84335fSJung-uk Kim * offer to sell, and import the Covered Code and derivative works thereof 320d84335fSJung-uk Kim * solely to the minimum extent necessary to exercise the above copyright 330d84335fSJung-uk Kim * license, and in no event shall the patent license extend to any additions 340d84335fSJung-uk Kim * to or modifications of the Original Intel Code. No other license or right 350d84335fSJung-uk Kim * is granted directly or by implication, estoppel or otherwise; 360d84335fSJung-uk Kim * 370d84335fSJung-uk Kim * The above copyright and patent license is granted only if the following 380d84335fSJung-uk Kim * conditions are met: 390d84335fSJung-uk Kim * 400d84335fSJung-uk Kim * 3. Conditions 410d84335fSJung-uk Kim * 420d84335fSJung-uk Kim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 430d84335fSJung-uk Kim * Redistribution of source code of any substantial portion of the Covered 440d84335fSJung-uk Kim * Code or modification with rights to further distribute source must include 450d84335fSJung-uk Kim * the above Copyright Notice, the above License, this list of Conditions, 460d84335fSJung-uk Kim * and the following Disclaimer and Export Compliance provision. In addition, 470d84335fSJung-uk Kim * Licensee must cause all Covered Code to which Licensee contributes to 480d84335fSJung-uk Kim * contain a file documenting the changes Licensee made to create that Covered 490d84335fSJung-uk Kim * Code and the date of any change. Licensee must include in that file the 500d84335fSJung-uk Kim * documentation of any changes made by any predecessor Licensee. Licensee 510d84335fSJung-uk Kim * must include a prominent statement that the modification is derived, 520d84335fSJung-uk Kim * directly or indirectly, from Original Intel Code. 530d84335fSJung-uk Kim * 540d84335fSJung-uk Kim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 550d84335fSJung-uk Kim * Redistribution of source code of any substantial portion of the Covered 560d84335fSJung-uk Kim * Code or modification without rights to further distribute source must 570d84335fSJung-uk Kim * include the following Disclaimer and Export Compliance provision in the 580d84335fSJung-uk Kim * documentation and/or other materials provided with distribution. In 590d84335fSJung-uk Kim * addition, Licensee may not authorize further sublicense of source of any 600d84335fSJung-uk Kim * portion of the Covered Code, and must include terms to the effect that the 610d84335fSJung-uk Kim * license from Licensee to its licensee is limited to the intellectual 620d84335fSJung-uk Kim * property embodied in the software Licensee provides to its licensee, and 630d84335fSJung-uk Kim * not to intellectual property embodied in modifications its licensee may 640d84335fSJung-uk Kim * make. 650d84335fSJung-uk Kim * 660d84335fSJung-uk Kim * 3.3. Redistribution of Executable. Redistribution in executable form of any 670d84335fSJung-uk Kim * substantial portion of the Covered Code or modification must reproduce the 680d84335fSJung-uk Kim * above Copyright Notice, and the following Disclaimer and Export Compliance 690d84335fSJung-uk Kim * provision in the documentation and/or other materials provided with the 700d84335fSJung-uk Kim * distribution. 710d84335fSJung-uk Kim * 720d84335fSJung-uk Kim * 3.4. Intel retains all right, title, and interest in and to the Original 730d84335fSJung-uk Kim * Intel Code. 740d84335fSJung-uk Kim * 750d84335fSJung-uk Kim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 760d84335fSJung-uk Kim * Intel shall be used in advertising or otherwise to promote the sale, use or 770d84335fSJung-uk Kim * other dealings in products derived from or relating to the Covered Code 780d84335fSJung-uk Kim * without prior written authorization from Intel. 790d84335fSJung-uk Kim * 800d84335fSJung-uk Kim * 4. Disclaimer and Export Compliance 810d84335fSJung-uk Kim * 820d84335fSJung-uk Kim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 830d84335fSJung-uk Kim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 840d84335fSJung-uk Kim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 850d84335fSJung-uk Kim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 860d84335fSJung-uk Kim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 870d84335fSJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 880d84335fSJung-uk Kim * PARTICULAR PURPOSE. 890d84335fSJung-uk Kim * 900d84335fSJung-uk Kim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 910d84335fSJung-uk Kim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 920d84335fSJung-uk Kim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 930d84335fSJung-uk Kim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 940d84335fSJung-uk Kim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 950d84335fSJung-uk Kim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 960d84335fSJung-uk Kim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 970d84335fSJung-uk Kim * LIMITED REMEDY. 980d84335fSJung-uk Kim * 990d84335fSJung-uk Kim * 4.3. Licensee shall not export, either directly or indirectly, any of this 1000d84335fSJung-uk Kim * software or system incorporating such software without first obtaining any 1010d84335fSJung-uk Kim * required license or other approval from the U. S. Department of Commerce or 1020d84335fSJung-uk Kim * any other agency or department of the United States Government. In the 1030d84335fSJung-uk Kim * event Licensee exports any such software from the United States or 1040d84335fSJung-uk Kim * re-exports any such software from a foreign destination, Licensee shall 1050d84335fSJung-uk Kim * ensure that the distribution and export/re-export of the software is in 1060d84335fSJung-uk Kim * compliance with all laws, regulations, orders, or other restrictions of the 1070d84335fSJung-uk Kim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1080d84335fSJung-uk Kim * any of its subsidiaries will export/re-export any technical data, process, 1090d84335fSJung-uk Kim * software, or service, directly or indirectly, to any country for which the 1100d84335fSJung-uk Kim * United States government or any agency thereof requires an export license, 1110d84335fSJung-uk Kim * other governmental approval, or letter of assurance, without first obtaining 1120d84335fSJung-uk Kim * such license, approval or letter. 1130d84335fSJung-uk Kim * 1140d84335fSJung-uk Kim ***************************************************************************** 1150d84335fSJung-uk Kim * 1160d84335fSJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the 1170d84335fSJung-uk Kim * following license: 1180d84335fSJung-uk Kim * 119a159c266SJung-uk Kim * Redistribution and use in source and binary forms, with or without 120a159c266SJung-uk Kim * modification, are permitted provided that the following conditions 121a159c266SJung-uk Kim * are met: 122a159c266SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 123a159c266SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 124a159c266SJung-uk Kim * without modification. 125a159c266SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126a159c266SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 127a159c266SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 128a159c266SJung-uk Kim * including a substantially similar Disclaimer requirement for further 129a159c266SJung-uk Kim * binary redistribution. 130a159c266SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 131a159c266SJung-uk Kim * of any contributors may be used to endorse or promote products derived 132a159c266SJung-uk Kim * from this software without specific prior written permission. 133a159c266SJung-uk Kim * 1340d84335fSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1350d84335fSJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1360d84335fSJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1370d84335fSJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1380d84335fSJung-uk Kim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1390d84335fSJung-uk Kim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1400d84335fSJung-uk Kim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1410d84335fSJung-uk Kim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1420d84335fSJung-uk Kim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1430d84335fSJung-uk Kim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1440d84335fSJung-uk Kim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1450d84335fSJung-uk Kim * 1460d84335fSJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the 147a159c266SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 148a159c266SJung-uk Kim * Software Foundation. 149a159c266SJung-uk Kim * 1500d84335fSJung-uk Kim *****************************************************************************/ 151a159c266SJung-uk Kim 152a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 153a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 154a159c266SJung-uk Kim #include <contrib/dev/acpica/include/actables.h> 155a159c266SJung-uk Kim 156a159c266SJung-uk Kim #define _COMPONENT ACPI_TABLES 157a159c266SJung-uk Kim ACPI_MODULE_NAME ("tbfadt") 158a159c266SJung-uk Kim 159a159c266SJung-uk Kim /* Local prototypes */ 160a159c266SJung-uk Kim 161a7a3b383SJung-uk Kim static void 162a159c266SJung-uk Kim AcpiTbInitGenericAddress ( 163a159c266SJung-uk Kim ACPI_GENERIC_ADDRESS *GenericAddress, 164a159c266SJung-uk Kim UINT8 SpaceId, 165a159c266SJung-uk Kim UINT8 ByteWidth, 166a7a3b383SJung-uk Kim UINT64 Address, 167f8146b88SJung-uk Kim const char *RegisterName, 168313a0c13SJung-uk Kim UINT8 Flags); 169a159c266SJung-uk Kim 170a159c266SJung-uk Kim static void 171a159c266SJung-uk Kim AcpiTbConvertFadt ( 172a159c266SJung-uk Kim void); 173a159c266SJung-uk Kim 174a159c266SJung-uk Kim static void 175a159c266SJung-uk Kim AcpiTbSetupFadtRegisters ( 176a159c266SJung-uk Kim void); 177a159c266SJung-uk Kim 178313a0c13SJung-uk Kim static UINT64 179313a0c13SJung-uk Kim AcpiTbSelectAddress ( 180313a0c13SJung-uk Kim char *RegisterName, 181313a0c13SJung-uk Kim UINT32 Address32, 182313a0c13SJung-uk Kim UINT64 Address64); 183313a0c13SJung-uk Kim 184a159c266SJung-uk Kim 185a159c266SJung-uk Kim /* Table for conversion of FADT to common internal format and FADT validation */ 186a159c266SJung-uk Kim 187a159c266SJung-uk Kim typedef struct acpi_fadt_info 188a159c266SJung-uk Kim { 189f8146b88SJung-uk Kim const char *Name; 190a159c266SJung-uk Kim UINT16 Address64; 191a159c266SJung-uk Kim UINT16 Address32; 192a159c266SJung-uk Kim UINT16 Length; 193a159c266SJung-uk Kim UINT8 DefaultLength; 194313a0c13SJung-uk Kim UINT8 Flags; 195a159c266SJung-uk Kim 196a159c266SJung-uk Kim } ACPI_FADT_INFO; 197a159c266SJung-uk Kim 198a159c266SJung-uk Kim #define ACPI_FADT_OPTIONAL 0 199a159c266SJung-uk Kim #define ACPI_FADT_REQUIRED 1 200a159c266SJung-uk Kim #define ACPI_FADT_SEPARATE_LENGTH 2 201313a0c13SJung-uk Kim #define ACPI_FADT_GPE_REGISTER 4 202a159c266SJung-uk Kim 203a159c266SJung-uk Kim static ACPI_FADT_INFO FadtInfoTable[] = 204a159c266SJung-uk Kim { 205a159c266SJung-uk Kim {"Pm1aEventBlock", 206a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPm1aEventBlock), 207a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm1aEventBlock), 208a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm1EventLength), 209a159c266SJung-uk Kim ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 210a159c266SJung-uk Kim ACPI_FADT_REQUIRED}, 211a159c266SJung-uk Kim 212a159c266SJung-uk Kim {"Pm1bEventBlock", 213a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPm1bEventBlock), 214a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm1bEventBlock), 215a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm1EventLength), 216a159c266SJung-uk Kim ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 217a159c266SJung-uk Kim ACPI_FADT_OPTIONAL}, 218a159c266SJung-uk Kim 219a159c266SJung-uk Kim {"Pm1aControlBlock", 220a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPm1aControlBlock), 221a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm1aControlBlock), 222a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm1ControlLength), 223a159c266SJung-uk Kim ACPI_PM1_REGISTER_WIDTH, 224a159c266SJung-uk Kim ACPI_FADT_REQUIRED}, 225a159c266SJung-uk Kim 226a159c266SJung-uk Kim {"Pm1bControlBlock", 227a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPm1bControlBlock), 228a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm1bControlBlock), 229a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm1ControlLength), 230a159c266SJung-uk Kim ACPI_PM1_REGISTER_WIDTH, 231a159c266SJung-uk Kim ACPI_FADT_OPTIONAL}, 232a159c266SJung-uk Kim 233a159c266SJung-uk Kim {"Pm2ControlBlock", 234a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPm2ControlBlock), 235a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm2ControlBlock), 236a159c266SJung-uk Kim ACPI_FADT_OFFSET (Pm2ControlLength), 237a159c266SJung-uk Kim ACPI_PM2_REGISTER_WIDTH, 238a159c266SJung-uk Kim ACPI_FADT_SEPARATE_LENGTH}, 239a159c266SJung-uk Kim 240a159c266SJung-uk Kim {"PmTimerBlock", 241a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPmTimerBlock), 242a159c266SJung-uk Kim ACPI_FADT_OFFSET (PmTimerBlock), 243a159c266SJung-uk Kim ACPI_FADT_OFFSET (PmTimerLength), 244a159c266SJung-uk Kim ACPI_PM_TIMER_WIDTH, 245bf6fac21SJung-uk Kim ACPI_FADT_SEPARATE_LENGTH}, /* ACPI 5.0A: Timer is optional */ 246a159c266SJung-uk Kim 247a159c266SJung-uk Kim {"Gpe0Block", 248a159c266SJung-uk Kim ACPI_FADT_OFFSET (XGpe0Block), 249a159c266SJung-uk Kim ACPI_FADT_OFFSET (Gpe0Block), 250a159c266SJung-uk Kim ACPI_FADT_OFFSET (Gpe0BlockLength), 251a159c266SJung-uk Kim 0, 252313a0c13SJung-uk Kim ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}, 253a159c266SJung-uk Kim 254a159c266SJung-uk Kim {"Gpe1Block", 255a159c266SJung-uk Kim ACPI_FADT_OFFSET (XGpe1Block), 256a159c266SJung-uk Kim ACPI_FADT_OFFSET (Gpe1Block), 257a159c266SJung-uk Kim ACPI_FADT_OFFSET (Gpe1BlockLength), 258a159c266SJung-uk Kim 0, 259313a0c13SJung-uk Kim ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER} 260a159c266SJung-uk Kim }; 261a159c266SJung-uk Kim 262a159c266SJung-uk Kim #define ACPI_FADT_INFO_ENTRIES \ 263a159c266SJung-uk Kim (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO)) 264a159c266SJung-uk Kim 265a159c266SJung-uk Kim 266a159c266SJung-uk Kim /* Table used to split Event Blocks into separate status/enable registers */ 267a159c266SJung-uk Kim 268a159c266SJung-uk Kim typedef struct acpi_fadt_pm_info 269a159c266SJung-uk Kim { 270a159c266SJung-uk Kim ACPI_GENERIC_ADDRESS *Target; 271a159c266SJung-uk Kim UINT16 Source; 272a159c266SJung-uk Kim UINT8 RegisterNum; 273a159c266SJung-uk Kim 274a159c266SJung-uk Kim } ACPI_FADT_PM_INFO; 275a159c266SJung-uk Kim 276a159c266SJung-uk Kim static ACPI_FADT_PM_INFO FadtPmInfoTable[] = 277a159c266SJung-uk Kim { 278a159c266SJung-uk Kim {&AcpiGbl_XPm1aStatus, 279a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPm1aEventBlock), 280a159c266SJung-uk Kim 0}, 281a159c266SJung-uk Kim 282a159c266SJung-uk Kim {&AcpiGbl_XPm1aEnable, 283a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPm1aEventBlock), 284a159c266SJung-uk Kim 1}, 285a159c266SJung-uk Kim 286a159c266SJung-uk Kim {&AcpiGbl_XPm1bStatus, 287a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPm1bEventBlock), 288a159c266SJung-uk Kim 0}, 289a159c266SJung-uk Kim 290a159c266SJung-uk Kim {&AcpiGbl_XPm1bEnable, 291a159c266SJung-uk Kim ACPI_FADT_OFFSET (XPm1bEventBlock), 292a159c266SJung-uk Kim 1} 293a159c266SJung-uk Kim }; 294a159c266SJung-uk Kim 295a159c266SJung-uk Kim #define ACPI_FADT_PM_INFO_ENTRIES \ 296a159c266SJung-uk Kim (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO)) 297a159c266SJung-uk Kim 298a159c266SJung-uk Kim 299a159c266SJung-uk Kim /******************************************************************************* 300a159c266SJung-uk Kim * 301a159c266SJung-uk Kim * FUNCTION: AcpiTbInitGenericAddress 302a159c266SJung-uk Kim * 303a159c266SJung-uk Kim * PARAMETERS: GenericAddress - GAS struct to be initialized 304a159c266SJung-uk Kim * SpaceId - ACPI Space ID for this register 305e8241eabSJung-uk Kim * ByteWidth - Width of this register 306a159c266SJung-uk Kim * Address - Address of the register 307313a0c13SJung-uk Kim * RegisterName - ASCII name of the ACPI register 308a159c266SJung-uk Kim * 309a159c266SJung-uk Kim * RETURN: None 310a159c266SJung-uk Kim * 311a159c266SJung-uk Kim * DESCRIPTION: Initialize a Generic Address Structure (GAS) 312a159c266SJung-uk Kim * See the ACPI specification for a full description and 313a159c266SJung-uk Kim * definition of this structure. 314a159c266SJung-uk Kim * 315a159c266SJung-uk Kim ******************************************************************************/ 316a159c266SJung-uk Kim 317a7a3b383SJung-uk Kim static void 318a159c266SJung-uk Kim AcpiTbInitGenericAddress ( 319a159c266SJung-uk Kim ACPI_GENERIC_ADDRESS *GenericAddress, 320a159c266SJung-uk Kim UINT8 SpaceId, 321a159c266SJung-uk Kim UINT8 ByteWidth, 322a7a3b383SJung-uk Kim UINT64 Address, 323f8146b88SJung-uk Kim const char *RegisterName, 324313a0c13SJung-uk Kim UINT8 Flags) 325a159c266SJung-uk Kim { 326a7a3b383SJung-uk Kim UINT8 BitWidth; 327a7a3b383SJung-uk Kim 328a7a3b383SJung-uk Kim 329313a0c13SJung-uk Kim /* 330313a0c13SJung-uk Kim * Bit width field in the GAS is only one byte long, 255 max. 331313a0c13SJung-uk Kim * Check for BitWidth overflow in GAS. 332313a0c13SJung-uk Kim */ 333a7a3b383SJung-uk Kim BitWidth = (UINT8) (ByteWidth * 8); 334313a0c13SJung-uk Kim if (ByteWidth > 31) /* (31*8)=248, (32*8)=256 */ 335313a0c13SJung-uk Kim { 336313a0c13SJung-uk Kim /* 337313a0c13SJung-uk Kim * No error for GPE blocks, because we do not use the BitWidth 338313a0c13SJung-uk Kim * for GPEs, the legacy length (ByteWidth) is used instead to 339313a0c13SJung-uk Kim * allow for a large number of GPEs. 340313a0c13SJung-uk Kim */ 341313a0c13SJung-uk Kim if (!(Flags & ACPI_FADT_GPE_REGISTER)) 342a7a3b383SJung-uk Kim { 343a7a3b383SJung-uk Kim ACPI_ERROR ((AE_INFO, 344a7a3b383SJung-uk Kim "%s - 32-bit FADT register is too long (%u bytes, %u bits) " 345a7a3b383SJung-uk Kim "to convert to GAS struct - 255 bits max, truncating", 346a7a3b383SJung-uk Kim RegisterName, ByteWidth, (ByteWidth * 8))); 347313a0c13SJung-uk Kim } 348a7a3b383SJung-uk Kim 349a7a3b383SJung-uk Kim BitWidth = 255; 350a7a3b383SJung-uk Kim } 351a159c266SJung-uk Kim 352a159c266SJung-uk Kim /* 353a159c266SJung-uk Kim * The 64-bit Address field is non-aligned in the byte packed 354a159c266SJung-uk Kim * GAS struct. 355a159c266SJung-uk Kim */ 356a159c266SJung-uk Kim ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address); 357a159c266SJung-uk Kim 358a159c266SJung-uk Kim /* All other fields are byte-wide */ 359a159c266SJung-uk Kim 360a159c266SJung-uk Kim GenericAddress->SpaceId = SpaceId; 361a7a3b383SJung-uk Kim GenericAddress->BitWidth = BitWidth; 362a159c266SJung-uk Kim GenericAddress->BitOffset = 0; 363a159c266SJung-uk Kim GenericAddress->AccessWidth = 0; /* Access width ANY */ 364a159c266SJung-uk Kim } 365a159c266SJung-uk Kim 366a159c266SJung-uk Kim 367a159c266SJung-uk Kim /******************************************************************************* 368a159c266SJung-uk Kim * 369313a0c13SJung-uk Kim * FUNCTION: AcpiTbSelectAddress 370313a0c13SJung-uk Kim * 371313a0c13SJung-uk Kim * PARAMETERS: RegisterName - ASCII name of the ACPI register 372313a0c13SJung-uk Kim * Address32 - 32-bit address of the register 373313a0c13SJung-uk Kim * Address64 - 64-bit address of the register 374313a0c13SJung-uk Kim * 375313a0c13SJung-uk Kim * RETURN: The resolved 64-bit address 376313a0c13SJung-uk Kim * 377313a0c13SJung-uk Kim * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within 378313a0c13SJung-uk Kim * the FADT. Used for the FACS and DSDT addresses. 379313a0c13SJung-uk Kim * 380313a0c13SJung-uk Kim * NOTES: 381313a0c13SJung-uk Kim * 382313a0c13SJung-uk Kim * Check for FACS and DSDT address mismatches. An address mismatch between 383313a0c13SJung-uk Kim * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and 384313a0c13SJung-uk Kim * DSDT/X_DSDT) could be a corrupted address field or it might indicate 385313a0c13SJung-uk Kim * the presence of two FACS or two DSDT tables. 386313a0c13SJung-uk Kim * 387313a0c13SJung-uk Kim * November 2013: 388313a0c13SJung-uk Kim * By default, as per the ACPICA specification, a valid 64-bit address is 389313a0c13SJung-uk Kim * used regardless of the value of the 32-bit address. However, this 390313a0c13SJung-uk Kim * behavior can be overridden via the AcpiGbl_Use32BitFadtAddresses flag. 391313a0c13SJung-uk Kim * 392313a0c13SJung-uk Kim ******************************************************************************/ 393313a0c13SJung-uk Kim 394313a0c13SJung-uk Kim static UINT64 395313a0c13SJung-uk Kim AcpiTbSelectAddress ( 396313a0c13SJung-uk Kim char *RegisterName, 397313a0c13SJung-uk Kim UINT32 Address32, 398313a0c13SJung-uk Kim UINT64 Address64) 399313a0c13SJung-uk Kim { 400313a0c13SJung-uk Kim 401313a0c13SJung-uk Kim if (!Address64) 402313a0c13SJung-uk Kim { 403313a0c13SJung-uk Kim /* 64-bit address is zero, use 32-bit address */ 404313a0c13SJung-uk Kim 405313a0c13SJung-uk Kim return ((UINT64) Address32); 406313a0c13SJung-uk Kim } 407313a0c13SJung-uk Kim 408313a0c13SJung-uk Kim if (Address32 && 409313a0c13SJung-uk Kim (Address64 != (UINT64) Address32)) 410313a0c13SJung-uk Kim { 411313a0c13SJung-uk Kim /* Address mismatch between 32-bit and 64-bit versions */ 412313a0c13SJung-uk Kim 413313a0c13SJung-uk Kim ACPI_BIOS_WARNING ((AE_INFO, 414313a0c13SJung-uk Kim "32/64X %s address mismatch in FADT: " 415313a0c13SJung-uk Kim "0x%8.8X/0x%8.8X%8.8X, using %u-bit address", 416313a0c13SJung-uk Kim RegisterName, Address32, ACPI_FORMAT_UINT64 (Address64), 417313a0c13SJung-uk Kim AcpiGbl_Use32BitFadtAddresses ? 32 : 64)); 418313a0c13SJung-uk Kim 419313a0c13SJung-uk Kim /* 32-bit address override */ 420313a0c13SJung-uk Kim 421313a0c13SJung-uk Kim if (AcpiGbl_Use32BitFadtAddresses) 422313a0c13SJung-uk Kim { 423313a0c13SJung-uk Kim return ((UINT64) Address32); 424313a0c13SJung-uk Kim } 425313a0c13SJung-uk Kim } 426313a0c13SJung-uk Kim 427313a0c13SJung-uk Kim /* Default is to use the 64-bit address */ 428313a0c13SJung-uk Kim 429313a0c13SJung-uk Kim return (Address64); 430313a0c13SJung-uk Kim } 431313a0c13SJung-uk Kim 432313a0c13SJung-uk Kim 433313a0c13SJung-uk Kim /******************************************************************************* 434313a0c13SJung-uk Kim * 435a159c266SJung-uk Kim * FUNCTION: AcpiTbParseFadt 436a159c266SJung-uk Kim * 437f8146b88SJung-uk Kim * PARAMETERS: None 438a159c266SJung-uk Kim * 439a159c266SJung-uk Kim * RETURN: None 440a159c266SJung-uk Kim * 441a159c266SJung-uk Kim * DESCRIPTION: Initialize the FADT, DSDT and FACS tables 442a159c266SJung-uk Kim * (FADT contains the addresses of the DSDT and FACS) 443a159c266SJung-uk Kim * 444a159c266SJung-uk Kim ******************************************************************************/ 445a159c266SJung-uk Kim 446a159c266SJung-uk Kim void 447a159c266SJung-uk Kim AcpiTbParseFadt ( 448f8146b88SJung-uk Kim void) 449a159c266SJung-uk Kim { 450a159c266SJung-uk Kim UINT32 Length; 451a159c266SJung-uk Kim ACPI_TABLE_HEADER *Table; 4521cc50d6bSJung-uk Kim ACPI_TABLE_DESC *FadtDesc; 4531cc50d6bSJung-uk Kim ACPI_STATUS Status; 454a159c266SJung-uk Kim 455a159c266SJung-uk Kim 456a159c266SJung-uk Kim /* 457a159c266SJung-uk Kim * The FADT has multiple versions with different lengths, 458a159c266SJung-uk Kim * and it contains pointers to both the DSDT and FACS tables. 459a159c266SJung-uk Kim * 460a159c266SJung-uk Kim * Get a local copy of the FADT and convert it to a common format 461a159c266SJung-uk Kim * Map entire FADT, assumed to be smaller than one page. 462a159c266SJung-uk Kim */ 4631cc50d6bSJung-uk Kim FadtDesc = &AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex]; 4641cc50d6bSJung-uk Kim Status = AcpiTbGetTable (FadtDesc, &Table); 4651cc50d6bSJung-uk Kim if (ACPI_FAILURE (Status)) 466a159c266SJung-uk Kim { 467a159c266SJung-uk Kim return; 468a159c266SJung-uk Kim } 4691cc50d6bSJung-uk Kim Length = FadtDesc->Length; 470a159c266SJung-uk Kim 471a159c266SJung-uk Kim /* 472a159c266SJung-uk Kim * Validate the FADT checksum before we copy the table. Ignore 473a159c266SJung-uk Kim * checksum error as we want to try to get the DSDT and FACS. 474a159c266SJung-uk Kim */ 4759a4bc520SJung-uk Kim (void) AcpiUtVerifyChecksum (Table, Length); 476a159c266SJung-uk Kim 477a159c266SJung-uk Kim /* Create a local copy of the FADT in common ACPI 2.0+ format */ 478a159c266SJung-uk Kim 479a159c266SJung-uk Kim AcpiTbCreateLocalFadt (Table, Length); 480a159c266SJung-uk Kim 481a159c266SJung-uk Kim /* All done with the real FADT, unmap it */ 482a159c266SJung-uk Kim 4831cc50d6bSJung-uk Kim AcpiTbPutTable (FadtDesc); 484a159c266SJung-uk Kim 485a159c266SJung-uk Kim /* Obtain the DSDT and FACS tables via their addresses within the FADT */ 486a159c266SJung-uk Kim 487493deb39SJung-uk Kim AcpiTbInstallStandardTable ( 488493deb39SJung-uk Kim (ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt, 489ab71bbb7SJung-uk Kim ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, NULL, FALSE, TRUE, 490493deb39SJung-uk Kim &AcpiGbl_DsdtIndex); 491a159c266SJung-uk Kim 4925ef50723SJung-uk Kim if (AcpiGbl_FADT.Facs) 4935ef50723SJung-uk Kim { 494493deb39SJung-uk Kim AcpiTbInstallStandardTable ( 495493deb39SJung-uk Kim (ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.Facs, 496ab71bbb7SJung-uk Kim ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, NULL, FALSE, TRUE, 497493deb39SJung-uk Kim &AcpiGbl_FacsIndex); 498a159c266SJung-uk Kim } 4995ef50723SJung-uk Kim if (AcpiGbl_FADT.XFacs) 5005ef50723SJung-uk Kim { 501493deb39SJung-uk Kim AcpiTbInstallStandardTable ( 502493deb39SJung-uk Kim (ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs, 503ab71bbb7SJung-uk Kim ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, NULL, FALSE, TRUE, 504493deb39SJung-uk Kim &AcpiGbl_XFacsIndex); 5055ef50723SJung-uk Kim } 5065ef50723SJung-uk Kim } 507a159c266SJung-uk Kim 508a159c266SJung-uk Kim 509a159c266SJung-uk Kim /******************************************************************************* 510a159c266SJung-uk Kim * 511a159c266SJung-uk Kim * FUNCTION: AcpiTbCreateLocalFadt 512a159c266SJung-uk Kim * 513a159c266SJung-uk Kim * PARAMETERS: Table - Pointer to BIOS FADT 514a159c266SJung-uk Kim * Length - Length of the table 515a159c266SJung-uk Kim * 516a159c266SJung-uk Kim * RETURN: None 517a159c266SJung-uk Kim * 518a159c266SJung-uk Kim * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. 519a159c266SJung-uk Kim * Performs validation on some important FADT fields. 520a159c266SJung-uk Kim * 521a159c266SJung-uk Kim * NOTE: We create a local copy of the FADT regardless of the version. 522a159c266SJung-uk Kim * 523a159c266SJung-uk Kim ******************************************************************************/ 524a159c266SJung-uk Kim 525a159c266SJung-uk Kim void 526a159c266SJung-uk Kim AcpiTbCreateLocalFadt ( 527a159c266SJung-uk Kim ACPI_TABLE_HEADER *Table, 528a159c266SJung-uk Kim UINT32 Length) 529a159c266SJung-uk Kim { 530a159c266SJung-uk Kim 531a159c266SJung-uk Kim /* 532a159c266SJung-uk Kim * Check if the FADT is larger than the largest table that we expect 533f8146b88SJung-uk Kim * (typically the current ACPI specification version). If so, truncate 534f8146b88SJung-uk Kim * the table, and issue a warning. 535a159c266SJung-uk Kim */ 536a159c266SJung-uk Kim if (Length > sizeof (ACPI_TABLE_FADT)) 537a159c266SJung-uk Kim { 538e8241eabSJung-uk Kim ACPI_BIOS_WARNING ((AE_INFO, 539f8146b88SJung-uk Kim "FADT (revision %u) is longer than %s length, " 540a159c266SJung-uk Kim "truncating length %u to %u", 541f8146b88SJung-uk Kim Table->Revision, ACPI_FADT_CONFORMANCE, Length, 542f8146b88SJung-uk Kim (UINT32) sizeof (ACPI_TABLE_FADT))); 543a159c266SJung-uk Kim } 544a159c266SJung-uk Kim 545a159c266SJung-uk Kim /* Clear the entire local FADT */ 546a159c266SJung-uk Kim 5475ef50723SJung-uk Kim memset (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT)); 548a159c266SJung-uk Kim 549a159c266SJung-uk Kim /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */ 550a159c266SJung-uk Kim 5515ef50723SJung-uk Kim memcpy (&AcpiGbl_FADT, Table, 552a159c266SJung-uk Kim ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT))); 553a159c266SJung-uk Kim 554a159c266SJung-uk Kim /* Take a copy of the Hardware Reduced flag */ 555a159c266SJung-uk Kim 556a159c266SJung-uk Kim AcpiGbl_ReducedHardware = FALSE; 557a159c266SJung-uk Kim if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED) 558a159c266SJung-uk Kim { 559a159c266SJung-uk Kim AcpiGbl_ReducedHardware = TRUE; 560a159c266SJung-uk Kim } 561a159c266SJung-uk Kim 562a159c266SJung-uk Kim /* Convert the local copy of the FADT to the common internal format */ 563a159c266SJung-uk Kim 564a159c266SJung-uk Kim AcpiTbConvertFadt (); 565a159c266SJung-uk Kim 566a159c266SJung-uk Kim /* Initialize the global ACPI register structures */ 567a159c266SJung-uk Kim 568a159c266SJung-uk Kim AcpiTbSetupFadtRegisters (); 569a159c266SJung-uk Kim } 570a159c266SJung-uk Kim 571a159c266SJung-uk Kim 572a159c266SJung-uk Kim /******************************************************************************* 573a159c266SJung-uk Kim * 574a159c266SJung-uk Kim * FUNCTION: AcpiTbConvertFadt 575a159c266SJung-uk Kim * 576313a0c13SJung-uk Kim * PARAMETERS: None - AcpiGbl_FADT is used. 577a159c266SJung-uk Kim * 578a159c266SJung-uk Kim * RETURN: None 579a159c266SJung-uk Kim * 580a159c266SJung-uk Kim * DESCRIPTION: Converts all versions of the FADT to a common internal format. 581313a0c13SJung-uk Kim * Expand 32-bit addresses to 64-bit as necessary. Also validate 582313a0c13SJung-uk Kim * important fields within the FADT. 583a159c266SJung-uk Kim * 584313a0c13SJung-uk Kim * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), and must 585313a0c13SJung-uk Kim * contain a copy of the actual BIOS-provided FADT. 586a159c266SJung-uk Kim * 587a159c266SJung-uk Kim * Notes on 64-bit register addresses: 588a159c266SJung-uk Kim * 589a159c266SJung-uk Kim * After this FADT conversion, later ACPICA code will only use the 64-bit "X" 590a159c266SJung-uk Kim * fields of the FADT for all ACPI register addresses. 591a159c266SJung-uk Kim * 592313a0c13SJung-uk Kim * The 64-bit X fields are optional extensions to the original 32-bit FADT 593a159c266SJung-uk Kim * V1.0 fields. Even if they are present in the FADT, they are optional and 594a159c266SJung-uk Kim * are unused if the BIOS sets them to zero. Therefore, we must copy/expand 595af051161SJung-uk Kim * 32-bit V1.0 fields to the 64-bit X fields if the 64-bit X field is originally 596af051161SJung-uk Kim * zero. 597a159c266SJung-uk Kim * 598313a0c13SJung-uk Kim * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address 599313a0c13SJung-uk Kim * fields are expanded to the corresponding 64-bit X fields in the internal 600313a0c13SJung-uk Kim * common FADT. 601a159c266SJung-uk Kim * 602a159c266SJung-uk Kim * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded 603313a0c13SJung-uk Kim * to the corresponding 64-bit X fields, if the 64-bit field is originally 604313a0c13SJung-uk Kim * zero. Adhering to the ACPI specification, we completely ignore the 32-bit 605313a0c13SJung-uk Kim * field if the 64-bit field is valid, regardless of whether the host OS is 606313a0c13SJung-uk Kim * 32-bit or 64-bit. 607313a0c13SJung-uk Kim * 608313a0c13SJung-uk Kim * Possible additional checks: 609313a0c13SJung-uk Kim * (AcpiGbl_FADT.Pm1EventLength >= 4) 610313a0c13SJung-uk Kim * (AcpiGbl_FADT.Pm1ControlLength >= 2) 611313a0c13SJung-uk Kim * (AcpiGbl_FADT.PmTimerLength >= 4) 612313a0c13SJung-uk Kim * Gpe block lengths must be multiple of 2 613a159c266SJung-uk Kim * 614a159c266SJung-uk Kim ******************************************************************************/ 615a159c266SJung-uk Kim 616a159c266SJung-uk Kim static void 617a159c266SJung-uk Kim AcpiTbConvertFadt ( 618a159c266SJung-uk Kim void) 619a159c266SJung-uk Kim { 620f8146b88SJung-uk Kim const char *Name; 621a159c266SJung-uk Kim ACPI_GENERIC_ADDRESS *Address64; 622a159c266SJung-uk Kim UINT32 Address32; 623313a0c13SJung-uk Kim UINT8 Length; 624313a0c13SJung-uk Kim UINT8 Flags; 625a159c266SJung-uk Kim UINT32 i; 626a159c266SJung-uk Kim 627a159c266SJung-uk Kim 628a159c266SJung-uk Kim /* 6291cc50d6bSJung-uk Kim * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which 630a159c266SJung-uk Kim * should be zero are indeed zero. This will workaround BIOSs that 631a159c266SJung-uk Kim * inadvertently place values in these fields. 632a159c266SJung-uk Kim * 633a159c266SJung-uk Kim * The ACPI 1.0 reserved fields that will be zeroed are the bytes located 634a159c266SJung-uk Kim * at offset 45, 55, 95, and the word located at offset 109, 110. 635a159c266SJung-uk Kim * 6361cc50d6bSJung-uk Kim * Note: The FADT revision value is unreliable. Only the length can be 6371cc50d6bSJung-uk Kim * trusted. 638a159c266SJung-uk Kim */ 6391cc50d6bSJung-uk Kim if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE) 640a159c266SJung-uk Kim { 641a159c266SJung-uk Kim AcpiGbl_FADT.PreferredProfile = 0; 642a159c266SJung-uk Kim AcpiGbl_FADT.PstateControl = 0; 643a159c266SJung-uk Kim AcpiGbl_FADT.CstControl = 0; 644a159c266SJung-uk Kim AcpiGbl_FADT.BootFlags = 0; 645a159c266SJung-uk Kim } 646a159c266SJung-uk Kim 647a159c266SJung-uk Kim /* 6484c52cad2SJung-uk Kim * Now we can update the local FADT length to the length of the 6494c52cad2SJung-uk Kim * current FADT version as defined by the ACPI specification. 6504c52cad2SJung-uk Kim * Thus, we will have a common FADT internally. 6514c52cad2SJung-uk Kim */ 6524c52cad2SJung-uk Kim AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT); 6534c52cad2SJung-uk Kim 6544c52cad2SJung-uk Kim /* 6555ef50723SJung-uk Kim * Expand the 32-bit DSDT addresses to 64-bit as necessary. 656313a0c13SJung-uk Kim * Later ACPICA code will always use the X 64-bit field. 657a159c266SJung-uk Kim */ 658313a0c13SJung-uk Kim AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT", 659313a0c13SJung-uk Kim AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt); 660a159c266SJung-uk Kim 661a159c266SJung-uk Kim /* If Hardware Reduced flag is set, we are all done */ 662a159c266SJung-uk Kim 663a159c266SJung-uk Kim if (AcpiGbl_ReducedHardware) 664a159c266SJung-uk Kim { 665a159c266SJung-uk Kim return; 666a159c266SJung-uk Kim } 667a159c266SJung-uk Kim 668a159c266SJung-uk Kim /* Examine all of the 64-bit extended address fields (X fields) */ 669a159c266SJung-uk Kim 670a159c266SJung-uk Kim for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 671a159c266SJung-uk Kim { 672a159c266SJung-uk Kim /* 673313a0c13SJung-uk Kim * Get the 32-bit and 64-bit addresses, as well as the register 674313a0c13SJung-uk Kim * length and register name. 675a159c266SJung-uk Kim */ 676313a0c13SJung-uk Kim Address32 = *ACPI_ADD_PTR (UINT32, 677313a0c13SJung-uk Kim &AcpiGbl_FADT, FadtInfoTable[i].Address32); 678313a0c13SJung-uk Kim 679a159c266SJung-uk Kim Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, 680a159c266SJung-uk Kim &AcpiGbl_FADT, FadtInfoTable[i].Address64); 681313a0c13SJung-uk Kim 682a159c266SJung-uk Kim Length = *ACPI_ADD_PTR (UINT8, 683a159c266SJung-uk Kim &AcpiGbl_FADT, FadtInfoTable[i].Length); 684313a0c13SJung-uk Kim 685a159c266SJung-uk Kim Name = FadtInfoTable[i].Name; 686313a0c13SJung-uk Kim Flags = FadtInfoTable[i].Flags; 687313a0c13SJung-uk Kim 688313a0c13SJung-uk Kim /* 689313a0c13SJung-uk Kim * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" 690313a0c13SJung-uk Kim * generic address structures as necessary. Later code will always use 691313a0c13SJung-uk Kim * the 64-bit address structures. 692313a0c13SJung-uk Kim * 693313a0c13SJung-uk Kim * November 2013: 694313a0c13SJung-uk Kim * Now always use the 64-bit address if it is valid (non-zero), in 695313a0c13SJung-uk Kim * accordance with the ACPI specification which states that a 64-bit 696313a0c13SJung-uk Kim * address supersedes the 32-bit version. This behavior can be 697313a0c13SJung-uk Kim * overridden by the AcpiGbl_Use32BitFadtAddresses flag. 698313a0c13SJung-uk Kim * 699313a0c13SJung-uk Kim * During 64-bit address construction and verification, 700313a0c13SJung-uk Kim * these cases are handled: 701313a0c13SJung-uk Kim * 702313a0c13SJung-uk Kim * Address32 zero, Address64 [don't care] - Use Address64 703313a0c13SJung-uk Kim * 704493deb39SJung-uk Kim * No override: if AcpiGbl_Use32BitFadtAddresses is FALSE, and: 705313a0c13SJung-uk Kim * Address32 non-zero, Address64 zero - Copy/use Address32 706313a0c13SJung-uk Kim * Address32 non-zero == Address64 non-zero - Use Address64 707313a0c13SJung-uk Kim * Address32 non-zero != Address64 non-zero - Warning, use Address64 708313a0c13SJung-uk Kim * 709313a0c13SJung-uk Kim * Override: if AcpiGbl_Use32BitFadtAddresses is TRUE, and: 710493deb39SJung-uk Kim * Address32 non-zero, Address64 zero - Copy/use Address32 711493deb39SJung-uk Kim * Address32 non-zero == Address64 non-zero - Copy/use Address32 712313a0c13SJung-uk Kim * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32 713313a0c13SJung-uk Kim * 714313a0c13SJung-uk Kim * Note: SpaceId is always I/O for 32-bit legacy address fields 715313a0c13SJung-uk Kim */ 716313a0c13SJung-uk Kim if (Address32) 717313a0c13SJung-uk Kim { 718493deb39SJung-uk Kim if (Address64->Address) 719313a0c13SJung-uk Kim { 720493deb39SJung-uk Kim if (Address64->Address != (UINT64) Address32) 721313a0c13SJung-uk Kim { 722313a0c13SJung-uk Kim /* Address mismatch */ 723313a0c13SJung-uk Kim 724313a0c13SJung-uk Kim ACPI_BIOS_WARNING ((AE_INFO, 725313a0c13SJung-uk Kim "32/64X address mismatch in FADT/%s: " 726313a0c13SJung-uk Kim "0x%8.8X/0x%8.8X%8.8X, using %u-bit address", 727313a0c13SJung-uk Kim Name, Address32, 728313a0c13SJung-uk Kim ACPI_FORMAT_UINT64 (Address64->Address), 729313a0c13SJung-uk Kim AcpiGbl_Use32BitFadtAddresses ? 32 : 64)); 730313a0c13SJung-uk Kim } 731a159c266SJung-uk Kim 732a159c266SJung-uk Kim /* 733493deb39SJung-uk Kim * For each extended field, check for length mismatch 734493deb39SJung-uk Kim * between the legacy length field and the corresponding 735493deb39SJung-uk Kim * 64-bit X length field. 736493deb39SJung-uk Kim * Note: If the legacy length field is > 0xFF bits, ignore 737493deb39SJung-uk Kim * this check. (GPE registers can be larger than the 738cd6518c7SJung-uk Kim * 64-bit GAS structure can accommodate, 0xFF bits). 739a159c266SJung-uk Kim */ 740493deb39SJung-uk Kim if ((ACPI_MUL_8 (Length) <= ACPI_UINT8_MAX) && 741a159c266SJung-uk Kim (Address64->BitWidth != ACPI_MUL_8 (Length))) 742a159c266SJung-uk Kim { 743e8241eabSJung-uk Kim ACPI_BIOS_WARNING ((AE_INFO, 744e8241eabSJung-uk Kim "32/64X length mismatch in FADT/%s: %u/%u", 745a159c266SJung-uk Kim Name, ACPI_MUL_8 (Length), Address64->BitWidth)); 746a159c266SJung-uk Kim } 747493deb39SJung-uk Kim } 748493deb39SJung-uk Kim 749493deb39SJung-uk Kim /* 750493deb39SJung-uk Kim * Hardware register access code always uses the 64-bit fields. 751493deb39SJung-uk Kim * So if the 64-bit field is zero or is to be overridden, 752493deb39SJung-uk Kim * initialize it with the 32-bit fields. 753493deb39SJung-uk Kim * Note that when the 32-bit address favor is specified, the 754493deb39SJung-uk Kim * 64-bit fields are always re-initialized so that 755493deb39SJung-uk Kim * AccessSize/BitWidth/BitOffset fields can be correctly 756493deb39SJung-uk Kim * configured to the values to trigger a 32-bit compatible 757493deb39SJung-uk Kim * access mode in the hardware register access code. 758493deb39SJung-uk Kim */ 759493deb39SJung-uk Kim if (!Address64->Address || AcpiGbl_Use32BitFadtAddresses) 760493deb39SJung-uk Kim { 761493deb39SJung-uk Kim AcpiTbInitGenericAddress (Address64, 762493deb39SJung-uk Kim ACPI_ADR_SPACE_SYSTEM_IO, Length, 763493deb39SJung-uk Kim (UINT64) Address32, Name, Flags); 764493deb39SJung-uk Kim } 765493deb39SJung-uk Kim } 766a159c266SJung-uk Kim 767313a0c13SJung-uk Kim if (FadtInfoTable[i].Flags & ACPI_FADT_REQUIRED) 768a159c266SJung-uk Kim { 769a159c266SJung-uk Kim /* 770bf6fac21SJung-uk Kim * Field is required (PM1aEvent, PM1aControl). 771a159c266SJung-uk Kim * Both the address and length must be non-zero. 772a159c266SJung-uk Kim */ 773a159c266SJung-uk Kim if (!Address64->Address || !Length) 774a159c266SJung-uk Kim { 775e8241eabSJung-uk Kim ACPI_BIOS_ERROR ((AE_INFO, 776e8241eabSJung-uk Kim "Required FADT field %s has zero address and/or length: " 777a159c266SJung-uk Kim "0x%8.8X%8.8X/0x%X", 778a159c266SJung-uk Kim Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); 779a159c266SJung-uk Kim } 780a159c266SJung-uk Kim } 781313a0c13SJung-uk Kim else if (FadtInfoTable[i].Flags & ACPI_FADT_SEPARATE_LENGTH) 782a159c266SJung-uk Kim { 783a159c266SJung-uk Kim /* 784a159c266SJung-uk Kim * Field is optional (PM2Control, GPE0, GPE1) AND has its own 785a159c266SJung-uk Kim * length field. If present, both the address and length must 786a159c266SJung-uk Kim * be valid. 787a159c266SJung-uk Kim */ 788a159c266SJung-uk Kim if ((Address64->Address && !Length) || 789a159c266SJung-uk Kim (!Address64->Address && Length)) 790a159c266SJung-uk Kim { 791e8241eabSJung-uk Kim ACPI_BIOS_WARNING ((AE_INFO, 792f8146b88SJung-uk Kim "Optional FADT field %s has valid %s but zero %s: " 793f8146b88SJung-uk Kim "0x%8.8X%8.8X/0x%X", Name, 794f8146b88SJung-uk Kim (Length ? "Length" : "Address"), 795f8146b88SJung-uk Kim (Length ? "Address": "Length"), 796f8146b88SJung-uk Kim ACPI_FORMAT_UINT64 (Address64->Address), Length)); 797a159c266SJung-uk Kim } 798a159c266SJung-uk Kim } 799a159c266SJung-uk Kim } 800a159c266SJung-uk Kim } 801a159c266SJung-uk Kim 802a159c266SJung-uk Kim 803a159c266SJung-uk Kim /******************************************************************************* 804a159c266SJung-uk Kim * 805a159c266SJung-uk Kim * FUNCTION: AcpiTbSetupFadtRegisters 806a159c266SJung-uk Kim * 807a159c266SJung-uk Kim * PARAMETERS: None, uses AcpiGbl_FADT. 808a159c266SJung-uk Kim * 809a159c266SJung-uk Kim * RETURN: None 810a159c266SJung-uk Kim * 811a159c266SJung-uk Kim * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally, 812a159c266SJung-uk Kim * force FADT register definitions to their default lengths. 813a159c266SJung-uk Kim * 814a159c266SJung-uk Kim ******************************************************************************/ 815a159c266SJung-uk Kim 816a159c266SJung-uk Kim static void 817a159c266SJung-uk Kim AcpiTbSetupFadtRegisters ( 818a159c266SJung-uk Kim void) 819a159c266SJung-uk Kim { 820a159c266SJung-uk Kim ACPI_GENERIC_ADDRESS *Target64; 821a159c266SJung-uk Kim ACPI_GENERIC_ADDRESS *Source64; 822a159c266SJung-uk Kim UINT8 Pm1RegisterByteWidth; 823a159c266SJung-uk Kim UINT32 i; 824a159c266SJung-uk Kim 825a159c266SJung-uk Kim 826a159c266SJung-uk Kim /* 827a159c266SJung-uk Kim * Optionally check all register lengths against the default values and 828a159c266SJung-uk Kim * update them if they are incorrect. 829a159c266SJung-uk Kim */ 830a159c266SJung-uk Kim if (AcpiGbl_UseDefaultRegisterWidths) 831a159c266SJung-uk Kim { 832a159c266SJung-uk Kim for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 833a159c266SJung-uk Kim { 834a159c266SJung-uk Kim Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 835a159c266SJung-uk Kim FadtInfoTable[i].Address64); 836a159c266SJung-uk Kim 837a159c266SJung-uk Kim /* 838a159c266SJung-uk Kim * If a valid register (Address != 0) and the (DefaultLength > 0) 839a159c266SJung-uk Kim * (Not a GPE register), then check the width against the default. 840a159c266SJung-uk Kim */ 841a159c266SJung-uk Kim if ((Target64->Address) && 842a159c266SJung-uk Kim (FadtInfoTable[i].DefaultLength > 0) && 843a159c266SJung-uk Kim (FadtInfoTable[i].DefaultLength != Target64->BitWidth)) 844a159c266SJung-uk Kim { 845e8241eabSJung-uk Kim ACPI_BIOS_WARNING ((AE_INFO, 846e8241eabSJung-uk Kim "Invalid length for FADT/%s: %u, using default %u", 847a159c266SJung-uk Kim FadtInfoTable[i].Name, Target64->BitWidth, 848a159c266SJung-uk Kim FadtInfoTable[i].DefaultLength)); 849a159c266SJung-uk Kim 850a159c266SJung-uk Kim /* Incorrect size, set width to the default */ 851a159c266SJung-uk Kim 852a159c266SJung-uk Kim Target64->BitWidth = FadtInfoTable[i].DefaultLength; 853a159c266SJung-uk Kim } 854a159c266SJung-uk Kim } 855a159c266SJung-uk Kim } 856a159c266SJung-uk Kim 857a159c266SJung-uk Kim /* 858a159c266SJung-uk Kim * Get the length of the individual PM1 registers (enable and status). 859a159c266SJung-uk Kim * Each register is defined to be (event block length / 2). Extra divide 860a159c266SJung-uk Kim * by 8 converts bits to bytes. 861a159c266SJung-uk Kim */ 862a159c266SJung-uk Kim Pm1RegisterByteWidth = (UINT8) 863a159c266SJung-uk Kim ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth); 864a159c266SJung-uk Kim 865a159c266SJung-uk Kim /* 866a159c266SJung-uk Kim * Calculate separate GAS structs for the PM1x (A/B) Status and Enable 867a159c266SJung-uk Kim * registers. These addresses do not appear (directly) in the FADT, so it 868a159c266SJung-uk Kim * is useful to pre-calculate them from the PM1 Event Block definitions. 869a159c266SJung-uk Kim * 870a159c266SJung-uk Kim * The PM event blocks are split into two register blocks, first is the 871a159c266SJung-uk Kim * PM Status Register block, followed immediately by the PM Enable 872a159c266SJung-uk Kim * Register block. Each is of length (Pm1EventLength/2) 873a159c266SJung-uk Kim * 874a159c266SJung-uk Kim * Note: The PM1A event block is required by the ACPI specification. 875a159c266SJung-uk Kim * However, the PM1B event block is optional and is rarely, if ever, 876a159c266SJung-uk Kim * used. 877a159c266SJung-uk Kim */ 878a159c266SJung-uk Kim 879a159c266SJung-uk Kim for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) 880a159c266SJung-uk Kim { 881a159c266SJung-uk Kim Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 882a159c266SJung-uk Kim FadtPmInfoTable[i].Source); 883a159c266SJung-uk Kim 884a159c266SJung-uk Kim if (Source64->Address) 885a159c266SJung-uk Kim { 886a159c266SJung-uk Kim AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target, 887a159c266SJung-uk Kim Source64->SpaceId, Pm1RegisterByteWidth, 888a159c266SJung-uk Kim Source64->Address + 889a7a3b383SJung-uk Kim (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth), 890313a0c13SJung-uk Kim "PmRegisters", 0); 891a159c266SJung-uk Kim } 892a159c266SJung-uk Kim } 893a159c266SJung-uk Kim } 894