Path: blob/main/sys/contrib/dev/acpica/components/tables/tbfadt.c
48406 views
/******************************************************************************1*2* Module Name: tbfadt - FADT table utilities3*4*****************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/actables.h>154155#define _COMPONENT ACPI_TABLES156ACPI_MODULE_NAME ("tbfadt")157158/* Local prototypes */159160static void161AcpiTbInitGenericAddress (162ACPI_GENERIC_ADDRESS *GenericAddress,163UINT8 SpaceId,164UINT8 ByteWidth,165UINT64 Address,166const char *RegisterName,167UINT8 Flags);168169static void170AcpiTbConvertFadt (171void);172173static void174AcpiTbSetupFadtRegisters (175void);176177static UINT64178AcpiTbSelectAddress (179char *RegisterName,180UINT32 Address32,181UINT64 Address64);182183184/* Table for conversion of FADT to common internal format and FADT validation */185186typedef struct acpi_fadt_info187{188const char *Name;189UINT16 Address64;190UINT16 Address32;191UINT16 Length;192UINT8 DefaultLength;193UINT8 Flags;194195} ACPI_FADT_INFO;196197#define ACPI_FADT_OPTIONAL 0198#define ACPI_FADT_REQUIRED 1199#define ACPI_FADT_SEPARATE_LENGTH 2200#define ACPI_FADT_GPE_REGISTER 4201202static ACPI_FADT_INFO FadtInfoTable[] =203{204{"Pm1aEventBlock",205ACPI_FADT_OFFSET (XPm1aEventBlock),206ACPI_FADT_OFFSET (Pm1aEventBlock),207ACPI_FADT_OFFSET (Pm1EventLength),208ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */209ACPI_FADT_REQUIRED},210211{"Pm1bEventBlock",212ACPI_FADT_OFFSET (XPm1bEventBlock),213ACPI_FADT_OFFSET (Pm1bEventBlock),214ACPI_FADT_OFFSET (Pm1EventLength),215ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */216ACPI_FADT_OPTIONAL},217218{"Pm1aControlBlock",219ACPI_FADT_OFFSET (XPm1aControlBlock),220ACPI_FADT_OFFSET (Pm1aControlBlock),221ACPI_FADT_OFFSET (Pm1ControlLength),222ACPI_PM1_REGISTER_WIDTH,223ACPI_FADT_REQUIRED},224225{"Pm1bControlBlock",226ACPI_FADT_OFFSET (XPm1bControlBlock),227ACPI_FADT_OFFSET (Pm1bControlBlock),228ACPI_FADT_OFFSET (Pm1ControlLength),229ACPI_PM1_REGISTER_WIDTH,230ACPI_FADT_OPTIONAL},231232{"Pm2ControlBlock",233ACPI_FADT_OFFSET (XPm2ControlBlock),234ACPI_FADT_OFFSET (Pm2ControlBlock),235ACPI_FADT_OFFSET (Pm2ControlLength),236ACPI_PM2_REGISTER_WIDTH,237ACPI_FADT_SEPARATE_LENGTH},238239{"PmTimerBlock",240ACPI_FADT_OFFSET (XPmTimerBlock),241ACPI_FADT_OFFSET (PmTimerBlock),242ACPI_FADT_OFFSET (PmTimerLength),243ACPI_PM_TIMER_WIDTH,244ACPI_FADT_SEPARATE_LENGTH}, /* ACPI 5.0A: Timer is optional */245246{"Gpe0Block",247ACPI_FADT_OFFSET (XGpe0Block),248ACPI_FADT_OFFSET (Gpe0Block),249ACPI_FADT_OFFSET (Gpe0BlockLength),2500,251ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER},252253{"Gpe1Block",254ACPI_FADT_OFFSET (XGpe1Block),255ACPI_FADT_OFFSET (Gpe1Block),256ACPI_FADT_OFFSET (Gpe1BlockLength),2570,258ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}259};260261#define ACPI_FADT_INFO_ENTRIES \262(sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO))263264265/* Table used to split Event Blocks into separate status/enable registers */266267typedef struct acpi_fadt_pm_info268{269ACPI_GENERIC_ADDRESS *Target;270UINT16 Source;271UINT8 RegisterNum;272273} ACPI_FADT_PM_INFO;274275static ACPI_FADT_PM_INFO FadtPmInfoTable[] =276{277{&AcpiGbl_XPm1aStatus,278ACPI_FADT_OFFSET (XPm1aEventBlock),2790},280281{&AcpiGbl_XPm1aEnable,282ACPI_FADT_OFFSET (XPm1aEventBlock),2831},284285{&AcpiGbl_XPm1bStatus,286ACPI_FADT_OFFSET (XPm1bEventBlock),2870},288289{&AcpiGbl_XPm1bEnable,290ACPI_FADT_OFFSET (XPm1bEventBlock),2911}292};293294#define ACPI_FADT_PM_INFO_ENTRIES \295(sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO))296297298/*******************************************************************************299*300* FUNCTION: AcpiTbInitGenericAddress301*302* PARAMETERS: GenericAddress - GAS struct to be initialized303* SpaceId - ACPI Space ID for this register304* ByteWidth - Width of this register305* Address - Address of the register306* RegisterName - ASCII name of the ACPI register307*308* RETURN: None309*310* DESCRIPTION: Initialize a Generic Address Structure (GAS)311* See the ACPI specification for a full description and312* definition of this structure.313*314******************************************************************************/315316static void317AcpiTbInitGenericAddress (318ACPI_GENERIC_ADDRESS *GenericAddress,319UINT8 SpaceId,320UINT8 ByteWidth,321UINT64 Address,322const char *RegisterName,323UINT8 Flags)324{325UINT8 BitWidth;326327328/*329* Bit width field in the GAS is only one byte long, 255 max.330* Check for BitWidth overflow in GAS.331*/332BitWidth = (UINT8) (ByteWidth * 8);333if (ByteWidth > 31) /* (31*8)=248, (32*8)=256 */334{335/*336* No error for GPE blocks, because we do not use the BitWidth337* for GPEs, the legacy length (ByteWidth) is used instead to338* allow for a large number of GPEs.339*/340if (!(Flags & ACPI_FADT_GPE_REGISTER))341{342ACPI_ERROR ((AE_INFO,343"%s - 32-bit FADT register is too long (%u bytes, %u bits) "344"to convert to GAS struct - 255 bits max, truncating",345RegisterName, ByteWidth, (ByteWidth * 8)));346}347348BitWidth = 255;349}350351/*352* The 64-bit Address field is non-aligned in the byte packed353* GAS struct.354*/355ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address);356357/* All other fields are byte-wide */358359GenericAddress->SpaceId = SpaceId;360GenericAddress->BitWidth = BitWidth;361GenericAddress->BitOffset = 0;362GenericAddress->AccessWidth = 0; /* Access width ANY */363}364365366/*******************************************************************************367*368* FUNCTION: AcpiTbSelectAddress369*370* PARAMETERS: RegisterName - ASCII name of the ACPI register371* Address32 - 32-bit address of the register372* Address64 - 64-bit address of the register373*374* RETURN: The resolved 64-bit address375*376* DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within377* the FADT. Used for the FACS and DSDT addresses.378*379* NOTES:380*381* Check for FACS and DSDT address mismatches. An address mismatch between382* the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and383* DSDT/X_DSDT) could be a corrupted address field or it might indicate384* the presence of two FACS or two DSDT tables.385*386* November 2013:387* By default, as per the ACPICA specification, a valid 64-bit address is388* used regardless of the value of the 32-bit address. However, this389* behavior can be overridden via the AcpiGbl_Use32BitFadtAddresses flag.390*391******************************************************************************/392393static UINT64394AcpiTbSelectAddress (395char *RegisterName,396UINT32 Address32,397UINT64 Address64)398{399400if (!Address64)401{402/* 64-bit address is zero, use 32-bit address */403404return ((UINT64) Address32);405}406407if (Address32 &&408(Address64 != (UINT64) Address32))409{410/* Address mismatch between 32-bit and 64-bit versions */411412ACPI_BIOS_WARNING ((AE_INFO,413"32/64X %s address mismatch in FADT: "414"0x%8.8X/0x%8.8X%8.8X, using %u-bit address",415RegisterName, Address32, ACPI_FORMAT_UINT64 (Address64),416AcpiGbl_Use32BitFadtAddresses ? 32 : 64));417418/* 32-bit address override */419420if (AcpiGbl_Use32BitFadtAddresses)421{422return ((UINT64) Address32);423}424}425426/* Default is to use the 64-bit address */427428return (Address64);429}430431432/*******************************************************************************433*434* FUNCTION: AcpiTbParseFadt435*436* PARAMETERS: None437*438* RETURN: None439*440* DESCRIPTION: Initialize the FADT, DSDT and FACS tables441* (FADT contains the addresses of the DSDT and FACS)442*443******************************************************************************/444445void446AcpiTbParseFadt (447void)448{449UINT32 Length;450ACPI_TABLE_HEADER *Table;451ACPI_TABLE_DESC *FadtDesc;452ACPI_STATUS Status;453454455/*456* The FADT has multiple versions with different lengths,457* and it contains pointers to both the DSDT and FACS tables.458*459* Get a local copy of the FADT and convert it to a common format460* Map entire FADT, assumed to be smaller than one page.461*/462FadtDesc = &AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex];463Status = AcpiTbGetTable (FadtDesc, &Table);464if (ACPI_FAILURE (Status))465{466return;467}468Length = FadtDesc->Length;469470/*471* Validate the FADT checksum before we copy the table. Ignore472* checksum error as we want to try to get the DSDT and FACS.473*/474(void) AcpiUtVerifyChecksum (Table, Length);475476/* Create a local copy of the FADT in common ACPI 2.0+ format */477478AcpiTbCreateLocalFadt (Table, Length);479480/* All done with the real FADT, unmap it */481482AcpiTbPutTable (FadtDesc);483484/* Obtain the DSDT and FACS tables via their addresses within the FADT */485486AcpiTbInstallStandardTable (487(ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt,488ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, NULL, FALSE, TRUE,489&AcpiGbl_DsdtIndex);490491if (AcpiGbl_FADT.Facs)492{493AcpiTbInstallStandardTable (494(ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.Facs,495ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, NULL, FALSE, TRUE,496&AcpiGbl_FacsIndex);497}498if (AcpiGbl_FADT.XFacs)499{500AcpiTbInstallStandardTable (501(ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,502ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, NULL, FALSE, TRUE,503&AcpiGbl_XFacsIndex);504}505}506507508/*******************************************************************************509*510* FUNCTION: AcpiTbCreateLocalFadt511*512* PARAMETERS: Table - Pointer to BIOS FADT513* Length - Length of the table514*515* RETURN: None516*517* DESCRIPTION: Get a local copy of the FADT and convert it to a common format.518* Performs validation on some important FADT fields.519*520* NOTE: We create a local copy of the FADT regardless of the version.521*522******************************************************************************/523524void525AcpiTbCreateLocalFadt (526ACPI_TABLE_HEADER *Table,527UINT32 Length)528{529530/*531* Check if the FADT is larger than the largest table that we expect532* (typically the current ACPI specification version). If so, truncate533* the table, and issue a warning.534*/535if (Length > sizeof (ACPI_TABLE_FADT))536{537ACPI_BIOS_WARNING ((AE_INFO,538"FADT (revision %u) is longer than %s length, "539"truncating length %u to %u",540Table->Revision, ACPI_FADT_CONFORMANCE, Length,541(UINT32) sizeof (ACPI_TABLE_FADT)));542}543544/* Clear the entire local FADT */545546memset (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));547548/* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */549550memcpy (&AcpiGbl_FADT, Table,551ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));552553/* Take a copy of the Hardware Reduced flag */554555AcpiGbl_ReducedHardware = FALSE;556if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED)557{558AcpiGbl_ReducedHardware = TRUE;559}560561/* Convert the local copy of the FADT to the common internal format */562563AcpiTbConvertFadt ();564565/* Initialize the global ACPI register structures */566567AcpiTbSetupFadtRegisters ();568}569570571/*******************************************************************************572*573* FUNCTION: AcpiTbConvertFadt574*575* PARAMETERS: None - AcpiGbl_FADT is used.576*577* RETURN: None578*579* DESCRIPTION: Converts all versions of the FADT to a common internal format.580* Expand 32-bit addresses to 64-bit as necessary. Also validate581* important fields within the FADT.582*583* NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), and must584* contain a copy of the actual BIOS-provided FADT.585*586* Notes on 64-bit register addresses:587*588* After this FADT conversion, later ACPICA code will only use the 64-bit "X"589* fields of the FADT for all ACPI register addresses.590*591* The 64-bit X fields are optional extensions to the original 32-bit FADT592* V1.0 fields. Even if they are present in the FADT, they are optional and593* are unused if the BIOS sets them to zero. Therefore, we must copy/expand594* 32-bit V1.0 fields to the 64-bit X fields if the 64-bit X field is originally595* zero.596*597* For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address598* fields are expanded to the corresponding 64-bit X fields in the internal599* common FADT.600*601* For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded602* to the corresponding 64-bit X fields, if the 64-bit field is originally603* zero. Adhering to the ACPI specification, we completely ignore the 32-bit604* field if the 64-bit field is valid, regardless of whether the host OS is605* 32-bit or 64-bit.606*607* Possible additional checks:608* (AcpiGbl_FADT.Pm1EventLength >= 4)609* (AcpiGbl_FADT.Pm1ControlLength >= 2)610* (AcpiGbl_FADT.PmTimerLength >= 4)611* Gpe block lengths must be multiple of 2612*613******************************************************************************/614615static void616AcpiTbConvertFadt (617void)618{619const char *Name;620ACPI_GENERIC_ADDRESS *Address64;621UINT32 Address32;622UINT8 Length;623UINT8 Flags;624UINT32 i;625626627/*628* For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which629* should be zero are indeed zero. This will workaround BIOSs that630* inadvertently place values in these fields.631*632* The ACPI 1.0 reserved fields that will be zeroed are the bytes located633* at offset 45, 55, 95, and the word located at offset 109, 110.634*635* Note: The FADT revision value is unreliable. Only the length can be636* trusted.637*/638if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)639{640AcpiGbl_FADT.PreferredProfile = 0;641AcpiGbl_FADT.PstateControl = 0;642AcpiGbl_FADT.CstControl = 0;643AcpiGbl_FADT.BootFlags = 0;644}645646/*647* Now we can update the local FADT length to the length of the648* current FADT version as defined by the ACPI specification.649* Thus, we will have a common FADT internally.650*/651AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);652653/*654* Expand the 32-bit DSDT addresses to 64-bit as necessary.655* Later ACPICA code will always use the X 64-bit field.656*/657AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT",658AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt);659660/* If Hardware Reduced flag is set, we are all done */661662if (AcpiGbl_ReducedHardware)663{664return;665}666667/* Examine all of the 64-bit extended address fields (X fields) */668669for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)670{671/*672* Get the 32-bit and 64-bit addresses, as well as the register673* length and register name.674*/675Address32 = *ACPI_ADD_PTR (UINT32,676&AcpiGbl_FADT, FadtInfoTable[i].Address32);677678Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,679&AcpiGbl_FADT, FadtInfoTable[i].Address64);680681Length = *ACPI_ADD_PTR (UINT8,682&AcpiGbl_FADT, FadtInfoTable[i].Length);683684Name = FadtInfoTable[i].Name;685Flags = FadtInfoTable[i].Flags;686687/*688* Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"689* generic address structures as necessary. Later code will always use690* the 64-bit address structures.691*692* November 2013:693* Now always use the 64-bit address if it is valid (non-zero), in694* accordance with the ACPI specification which states that a 64-bit695* address supersedes the 32-bit version. This behavior can be696* overridden by the AcpiGbl_Use32BitFadtAddresses flag.697*698* During 64-bit address construction and verification,699* these cases are handled:700*701* Address32 zero, Address64 [don't care] - Use Address64702*703* No override: if AcpiGbl_Use32BitFadtAddresses is FALSE, and:704* Address32 non-zero, Address64 zero - Copy/use Address32705* Address32 non-zero == Address64 non-zero - Use Address64706* Address32 non-zero != Address64 non-zero - Warning, use Address64707*708* Override: if AcpiGbl_Use32BitFadtAddresses is TRUE, and:709* Address32 non-zero, Address64 zero - Copy/use Address32710* Address32 non-zero == Address64 non-zero - Copy/use Address32711* Address32 non-zero != Address64 non-zero - Warning, copy/use Address32712*713* Note: SpaceId is always I/O for 32-bit legacy address fields714*/715if (Address32)716{717if (Address64->Address)718{719if (Address64->Address != (UINT64) Address32)720{721/* Address mismatch */722723ACPI_BIOS_WARNING ((AE_INFO,724"32/64X address mismatch in FADT/%s: "725"0x%8.8X/0x%8.8X%8.8X, using %u-bit address",726Name, Address32,727ACPI_FORMAT_UINT64 (Address64->Address),728AcpiGbl_Use32BitFadtAddresses ? 32 : 64));729}730731/*732* For each extended field, check for length mismatch733* between the legacy length field and the corresponding734* 64-bit X length field.735* Note: If the legacy length field is > 0xFF bits, ignore736* this check. (GPE registers can be larger than the737* 64-bit GAS structure can accommodate, 0xFF bits).738*/739if ((ACPI_MUL_8 (Length) <= ACPI_UINT8_MAX) &&740(Address64->BitWidth != ACPI_MUL_8 (Length)))741{742ACPI_BIOS_WARNING ((AE_INFO,743"32/64X length mismatch in FADT/%s: %u/%u",744Name, ACPI_MUL_8 (Length), Address64->BitWidth));745}746}747748/*749* Hardware register access code always uses the 64-bit fields.750* So if the 64-bit field is zero or is to be overridden,751* initialize it with the 32-bit fields.752* Note that when the 32-bit address favor is specified, the753* 64-bit fields are always re-initialized so that754* AccessSize/BitWidth/BitOffset fields can be correctly755* configured to the values to trigger a 32-bit compatible756* access mode in the hardware register access code.757*/758if (!Address64->Address || AcpiGbl_Use32BitFadtAddresses)759{760AcpiTbInitGenericAddress (Address64,761ACPI_ADR_SPACE_SYSTEM_IO, Length,762(UINT64) Address32, Name, Flags);763}764}765766if (FadtInfoTable[i].Flags & ACPI_FADT_REQUIRED)767{768/*769* Field is required (PM1aEvent, PM1aControl).770* Both the address and length must be non-zero.771*/772if (!Address64->Address || !Length)773{774ACPI_BIOS_ERROR ((AE_INFO,775"Required FADT field %s has zero address and/or length: "776"0x%8.8X%8.8X/0x%X",777Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));778}779}780else if (FadtInfoTable[i].Flags & ACPI_FADT_SEPARATE_LENGTH)781{782/*783* Field is optional (PM2Control, GPE0, GPE1) AND has its own784* length field. If present, both the address and length must785* be valid.786*/787if ((Address64->Address && !Length) ||788(!Address64->Address && Length))789{790ACPI_BIOS_WARNING ((AE_INFO,791"Optional FADT field %s has valid %s but zero %s: "792"0x%8.8X%8.8X/0x%X", Name,793(Length ? "Length" : "Address"),794(Length ? "Address": "Length"),795ACPI_FORMAT_UINT64 (Address64->Address), Length));796}797}798}799}800801802/*******************************************************************************803*804* FUNCTION: AcpiTbSetupFadtRegisters805*806* PARAMETERS: None, uses AcpiGbl_FADT.807*808* RETURN: None809*810* DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,811* force FADT register definitions to their default lengths.812*813******************************************************************************/814815static void816AcpiTbSetupFadtRegisters (817void)818{819ACPI_GENERIC_ADDRESS *Target64;820ACPI_GENERIC_ADDRESS *Source64;821UINT8 Pm1RegisterByteWidth;822UINT32 i;823824825/*826* Optionally check all register lengths against the default values and827* update them if they are incorrect.828*/829if (AcpiGbl_UseDefaultRegisterWidths)830{831for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)832{833Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,834FadtInfoTable[i].Address64);835836/*837* If a valid register (Address != 0) and the (DefaultLength > 0)838* (Not a GPE register), then check the width against the default.839*/840if ((Target64->Address) &&841(FadtInfoTable[i].DefaultLength > 0) &&842(FadtInfoTable[i].DefaultLength != Target64->BitWidth))843{844ACPI_BIOS_WARNING ((AE_INFO,845"Invalid length for FADT/%s: %u, using default %u",846FadtInfoTable[i].Name, Target64->BitWidth,847FadtInfoTable[i].DefaultLength));848849/* Incorrect size, set width to the default */850851Target64->BitWidth = FadtInfoTable[i].DefaultLength;852}853}854}855856/*857* Get the length of the individual PM1 registers (enable and status).858* Each register is defined to be (event block length / 2). Extra divide859* by 8 converts bits to bytes.860*/861Pm1RegisterByteWidth = (UINT8)862ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth);863864/*865* Calculate separate GAS structs for the PM1x (A/B) Status and Enable866* registers. These addresses do not appear (directly) in the FADT, so it867* is useful to pre-calculate them from the PM1 Event Block definitions.868*869* The PM event blocks are split into two register blocks, first is the870* PM Status Register block, followed immediately by the PM Enable871* Register block. Each is of length (Pm1EventLength/2)872*873* Note: The PM1A event block is required by the ACPI specification.874* However, the PM1B event block is optional and is rarely, if ever,875* used.876*/877878for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++)879{880Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,881FadtPmInfoTable[i].Source);882883if (Source64->Address)884{885AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,886Source64->SpaceId, Pm1RegisterByteWidth,887Source64->Address +888(FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth),889"PmRegisters", 0);890}891}892}893894895