1/****************************************************************************** 2 * 3 * Module Name: tbfadt - FADT table utilities 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2012, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44#define __TBFADT_C__ 45 46#include <contrib/dev/acpica/include/acpi.h> 47#include <contrib/dev/acpica/include/accommon.h> 48#include <contrib/dev/acpica/include/actables.h> 49 50#define _COMPONENT ACPI_TABLES 51 ACPI_MODULE_NAME ("tbfadt") 52 53/* Local prototypes */ 54
| 1/****************************************************************************** 2 * 3 * Module Name: tbfadt - FADT table utilities 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2012, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44#define __TBFADT_C__ 45 46#include <contrib/dev/acpica/include/acpi.h> 47#include <contrib/dev/acpica/include/accommon.h> 48#include <contrib/dev/acpica/include/actables.h> 49 50#define _COMPONENT ACPI_TABLES 51 ACPI_MODULE_NAME ("tbfadt") 52 53/* Local prototypes */ 54
|
55static ACPI_INLINE void
| 55static void
|
56AcpiTbInitGenericAddress ( 57 ACPI_GENERIC_ADDRESS *GenericAddress, 58 UINT8 SpaceId, 59 UINT8 ByteWidth,
| 56AcpiTbInitGenericAddress ( 57 ACPI_GENERIC_ADDRESS *GenericAddress, 58 UINT8 SpaceId, 59 UINT8 ByteWidth,
|
60 UINT64 Address);
| 60 UINT64 Address, 61 char *RegisterName);
|
61 62static void 63AcpiTbConvertFadt ( 64 void); 65 66static void 67AcpiTbValidateFadt ( 68 void); 69 70static void 71AcpiTbSetupFadtRegisters ( 72 void); 73 74 75/* Table for conversion of FADT to common internal format and FADT validation */ 76 77typedef struct acpi_fadt_info 78{ 79 char *Name; 80 UINT16 Address64; 81 UINT16 Address32; 82 UINT16 Length; 83 UINT8 DefaultLength; 84 UINT8 Type; 85 86} ACPI_FADT_INFO; 87 88#define ACPI_FADT_OPTIONAL 0 89#define ACPI_FADT_REQUIRED 1 90#define ACPI_FADT_SEPARATE_LENGTH 2 91 92static ACPI_FADT_INFO FadtInfoTable[] = 93{ 94 {"Pm1aEventBlock", 95 ACPI_FADT_OFFSET (XPm1aEventBlock), 96 ACPI_FADT_OFFSET (Pm1aEventBlock), 97 ACPI_FADT_OFFSET (Pm1EventLength), 98 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 99 ACPI_FADT_REQUIRED}, 100 101 {"Pm1bEventBlock", 102 ACPI_FADT_OFFSET (XPm1bEventBlock), 103 ACPI_FADT_OFFSET (Pm1bEventBlock), 104 ACPI_FADT_OFFSET (Pm1EventLength), 105 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 106 ACPI_FADT_OPTIONAL}, 107 108 {"Pm1aControlBlock", 109 ACPI_FADT_OFFSET (XPm1aControlBlock), 110 ACPI_FADT_OFFSET (Pm1aControlBlock), 111 ACPI_FADT_OFFSET (Pm1ControlLength), 112 ACPI_PM1_REGISTER_WIDTH, 113 ACPI_FADT_REQUIRED}, 114 115 {"Pm1bControlBlock", 116 ACPI_FADT_OFFSET (XPm1bControlBlock), 117 ACPI_FADT_OFFSET (Pm1bControlBlock), 118 ACPI_FADT_OFFSET (Pm1ControlLength), 119 ACPI_PM1_REGISTER_WIDTH, 120 ACPI_FADT_OPTIONAL}, 121 122 {"Pm2ControlBlock", 123 ACPI_FADT_OFFSET (XPm2ControlBlock), 124 ACPI_FADT_OFFSET (Pm2ControlBlock), 125 ACPI_FADT_OFFSET (Pm2ControlLength), 126 ACPI_PM2_REGISTER_WIDTH, 127 ACPI_FADT_SEPARATE_LENGTH}, 128 129 {"PmTimerBlock", 130 ACPI_FADT_OFFSET (XPmTimerBlock), 131 ACPI_FADT_OFFSET (PmTimerBlock), 132 ACPI_FADT_OFFSET (PmTimerLength), 133 ACPI_PM_TIMER_WIDTH, 134 ACPI_FADT_REQUIRED}, 135 136 {"Gpe0Block", 137 ACPI_FADT_OFFSET (XGpe0Block), 138 ACPI_FADT_OFFSET (Gpe0Block), 139 ACPI_FADT_OFFSET (Gpe0BlockLength), 140 0, 141 ACPI_FADT_SEPARATE_LENGTH}, 142 143 {"Gpe1Block", 144 ACPI_FADT_OFFSET (XGpe1Block), 145 ACPI_FADT_OFFSET (Gpe1Block), 146 ACPI_FADT_OFFSET (Gpe1BlockLength), 147 0, 148 ACPI_FADT_SEPARATE_LENGTH} 149}; 150 151#define ACPI_FADT_INFO_ENTRIES \ 152 (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO)) 153 154 155/* Table used to split Event Blocks into separate status/enable registers */ 156 157typedef struct acpi_fadt_pm_info 158{ 159 ACPI_GENERIC_ADDRESS *Target; 160 UINT16 Source; 161 UINT8 RegisterNum; 162 163} ACPI_FADT_PM_INFO; 164 165static ACPI_FADT_PM_INFO FadtPmInfoTable[] = 166{ 167 {&AcpiGbl_XPm1aStatus, 168 ACPI_FADT_OFFSET (XPm1aEventBlock), 169 0}, 170 171 {&AcpiGbl_XPm1aEnable, 172 ACPI_FADT_OFFSET (XPm1aEventBlock), 173 1}, 174 175 {&AcpiGbl_XPm1bStatus, 176 ACPI_FADT_OFFSET (XPm1bEventBlock), 177 0}, 178 179 {&AcpiGbl_XPm1bEnable, 180 ACPI_FADT_OFFSET (XPm1bEventBlock), 181 1} 182}; 183 184#define ACPI_FADT_PM_INFO_ENTRIES \ 185 (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO)) 186 187 188/******************************************************************************* 189 * 190 * FUNCTION: AcpiTbInitGenericAddress 191 * 192 * PARAMETERS: GenericAddress - GAS struct to be initialized 193 * SpaceId - ACPI Space ID for this register 194 * ByteWidth - Width of this register, in bytes 195 * Address - Address of the register 196 * 197 * RETURN: None 198 * 199 * DESCRIPTION: Initialize a Generic Address Structure (GAS) 200 * See the ACPI specification for a full description and 201 * definition of this structure. 202 * 203 ******************************************************************************/ 204
| 62 63static void 64AcpiTbConvertFadt ( 65 void); 66 67static void 68AcpiTbValidateFadt ( 69 void); 70 71static void 72AcpiTbSetupFadtRegisters ( 73 void); 74 75 76/* Table for conversion of FADT to common internal format and FADT validation */ 77 78typedef struct acpi_fadt_info 79{ 80 char *Name; 81 UINT16 Address64; 82 UINT16 Address32; 83 UINT16 Length; 84 UINT8 DefaultLength; 85 UINT8 Type; 86 87} ACPI_FADT_INFO; 88 89#define ACPI_FADT_OPTIONAL 0 90#define ACPI_FADT_REQUIRED 1 91#define ACPI_FADT_SEPARATE_LENGTH 2 92 93static ACPI_FADT_INFO FadtInfoTable[] = 94{ 95 {"Pm1aEventBlock", 96 ACPI_FADT_OFFSET (XPm1aEventBlock), 97 ACPI_FADT_OFFSET (Pm1aEventBlock), 98 ACPI_FADT_OFFSET (Pm1EventLength), 99 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 100 ACPI_FADT_REQUIRED}, 101 102 {"Pm1bEventBlock", 103 ACPI_FADT_OFFSET (XPm1bEventBlock), 104 ACPI_FADT_OFFSET (Pm1bEventBlock), 105 ACPI_FADT_OFFSET (Pm1EventLength), 106 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 107 ACPI_FADT_OPTIONAL}, 108 109 {"Pm1aControlBlock", 110 ACPI_FADT_OFFSET (XPm1aControlBlock), 111 ACPI_FADT_OFFSET (Pm1aControlBlock), 112 ACPI_FADT_OFFSET (Pm1ControlLength), 113 ACPI_PM1_REGISTER_WIDTH, 114 ACPI_FADT_REQUIRED}, 115 116 {"Pm1bControlBlock", 117 ACPI_FADT_OFFSET (XPm1bControlBlock), 118 ACPI_FADT_OFFSET (Pm1bControlBlock), 119 ACPI_FADT_OFFSET (Pm1ControlLength), 120 ACPI_PM1_REGISTER_WIDTH, 121 ACPI_FADT_OPTIONAL}, 122 123 {"Pm2ControlBlock", 124 ACPI_FADT_OFFSET (XPm2ControlBlock), 125 ACPI_FADT_OFFSET (Pm2ControlBlock), 126 ACPI_FADT_OFFSET (Pm2ControlLength), 127 ACPI_PM2_REGISTER_WIDTH, 128 ACPI_FADT_SEPARATE_LENGTH}, 129 130 {"PmTimerBlock", 131 ACPI_FADT_OFFSET (XPmTimerBlock), 132 ACPI_FADT_OFFSET (PmTimerBlock), 133 ACPI_FADT_OFFSET (PmTimerLength), 134 ACPI_PM_TIMER_WIDTH, 135 ACPI_FADT_REQUIRED}, 136 137 {"Gpe0Block", 138 ACPI_FADT_OFFSET (XGpe0Block), 139 ACPI_FADT_OFFSET (Gpe0Block), 140 ACPI_FADT_OFFSET (Gpe0BlockLength), 141 0, 142 ACPI_FADT_SEPARATE_LENGTH}, 143 144 {"Gpe1Block", 145 ACPI_FADT_OFFSET (XGpe1Block), 146 ACPI_FADT_OFFSET (Gpe1Block), 147 ACPI_FADT_OFFSET (Gpe1BlockLength), 148 0, 149 ACPI_FADT_SEPARATE_LENGTH} 150}; 151 152#define ACPI_FADT_INFO_ENTRIES \ 153 (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO)) 154 155 156/* Table used to split Event Blocks into separate status/enable registers */ 157 158typedef struct acpi_fadt_pm_info 159{ 160 ACPI_GENERIC_ADDRESS *Target; 161 UINT16 Source; 162 UINT8 RegisterNum; 163 164} ACPI_FADT_PM_INFO; 165 166static ACPI_FADT_PM_INFO FadtPmInfoTable[] = 167{ 168 {&AcpiGbl_XPm1aStatus, 169 ACPI_FADT_OFFSET (XPm1aEventBlock), 170 0}, 171 172 {&AcpiGbl_XPm1aEnable, 173 ACPI_FADT_OFFSET (XPm1aEventBlock), 174 1}, 175 176 {&AcpiGbl_XPm1bStatus, 177 ACPI_FADT_OFFSET (XPm1bEventBlock), 178 0}, 179 180 {&AcpiGbl_XPm1bEnable, 181 ACPI_FADT_OFFSET (XPm1bEventBlock), 182 1} 183}; 184 185#define ACPI_FADT_PM_INFO_ENTRIES \ 186 (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO)) 187 188 189/******************************************************************************* 190 * 191 * FUNCTION: AcpiTbInitGenericAddress 192 * 193 * PARAMETERS: GenericAddress - GAS struct to be initialized 194 * SpaceId - ACPI Space ID for this register 195 * ByteWidth - Width of this register, in bytes 196 * Address - Address of the register 197 * 198 * RETURN: None 199 * 200 * DESCRIPTION: Initialize a Generic Address Structure (GAS) 201 * See the ACPI specification for a full description and 202 * definition of this structure. 203 * 204 ******************************************************************************/ 205
|
205static ACPI_INLINE void
| 206static void
|
206AcpiTbInitGenericAddress ( 207 ACPI_GENERIC_ADDRESS *GenericAddress, 208 UINT8 SpaceId, 209 UINT8 ByteWidth,
| 207AcpiTbInitGenericAddress ( 208 ACPI_GENERIC_ADDRESS *GenericAddress, 209 UINT8 SpaceId, 210 UINT8 ByteWidth,
|
210 UINT64 Address)
| 211 UINT64 Address, 212 char *RegisterName)
|
211{
| 213{
|
| 214 UINT8 BitWidth;
|
212
| 215
|
| 216 217 /* Bit width field in the GAS is only one byte long, 255 max */ 218 219 BitWidth = (UINT8) (ByteWidth * 8); 220 221 if (ByteWidth > 31) /* (31*8)=248 */ 222 { 223 ACPI_ERROR ((AE_INFO, 224 "%s - 32-bit FADT register is too long (%u bytes, %u bits) " 225 "to convert to GAS struct - 255 bits max, truncating", 226 RegisterName, ByteWidth, (ByteWidth * 8))); 227 228 BitWidth = 255; 229 } 230
|
213 /* 214 * The 64-bit Address field is non-aligned in the byte packed 215 * GAS struct. 216 */ 217 ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address); 218 219 /* All other fields are byte-wide */ 220 221 GenericAddress->SpaceId = SpaceId;
| 231 /* 232 * The 64-bit Address field is non-aligned in the byte packed 233 * GAS struct. 234 */ 235 ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address); 236 237 /* All other fields are byte-wide */ 238 239 GenericAddress->SpaceId = SpaceId;
|
222 GenericAddress->BitWidth = (UINT8) ACPI_MUL_8 (ByteWidth);
| 240 GenericAddress->BitWidth = BitWidth;
|
223 GenericAddress->BitOffset = 0; 224 GenericAddress->AccessWidth = 0; /* Access width ANY */ 225} 226 227 228/******************************************************************************* 229 * 230 * FUNCTION: AcpiTbParseFadt 231 * 232 * PARAMETERS: TableIndex - Index for the FADT 233 * 234 * RETURN: None 235 * 236 * DESCRIPTION: Initialize the FADT, DSDT and FACS tables 237 * (FADT contains the addresses of the DSDT and FACS) 238 * 239 ******************************************************************************/ 240 241void 242AcpiTbParseFadt ( 243 UINT32 TableIndex) 244{ 245 UINT32 Length; 246 ACPI_TABLE_HEADER *Table; 247 248 249 /* 250 * The FADT has multiple versions with different lengths, 251 * and it contains pointers to both the DSDT and FACS tables. 252 * 253 * Get a local copy of the FADT and convert it to a common format 254 * Map entire FADT, assumed to be smaller than one page. 255 */ 256 Length = AcpiGbl_RootTableList.Tables[TableIndex].Length; 257 258 Table = AcpiOsMapMemory ( 259 AcpiGbl_RootTableList.Tables[TableIndex].Address, Length); 260 if (!Table) 261 { 262 return; 263 } 264 265 /* 266 * Validate the FADT checksum before we copy the table. Ignore 267 * checksum error as we want to try to get the DSDT and FACS. 268 */ 269 (void) AcpiTbVerifyChecksum (Table, Length); 270 271 /* Create a local copy of the FADT in common ACPI 2.0+ format */ 272 273 AcpiTbCreateLocalFadt (Table, Length); 274 275 /* All done with the real FADT, unmap it */ 276 277 AcpiOsUnmapMemory (Table, Length); 278 279 /* Obtain the DSDT and FACS tables via their addresses within the FADT */ 280 281 AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt, 282 ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); 283 284 /* If Hardware Reduced flag is set, there is no FACS */ 285 286 if (!AcpiGbl_ReducedHardware) 287 { 288 AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs, 289 ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); 290 } 291} 292 293 294/******************************************************************************* 295 * 296 * FUNCTION: AcpiTbCreateLocalFadt 297 * 298 * PARAMETERS: Table - Pointer to BIOS FADT 299 * Length - Length of the table 300 * 301 * RETURN: None 302 * 303 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. 304 * Performs validation on some important FADT fields. 305 * 306 * NOTE: We create a local copy of the FADT regardless of the version. 307 * 308 ******************************************************************************/ 309 310void 311AcpiTbCreateLocalFadt ( 312 ACPI_TABLE_HEADER *Table, 313 UINT32 Length) 314{ 315 316 /* 317 * Check if the FADT is larger than the largest table that we expect 318 * (the ACPI 5.0 version). If so, truncate the table, and issue 319 * a warning. 320 */ 321 if (Length > sizeof (ACPI_TABLE_FADT)) 322 { 323 ACPI_WARNING ((AE_INFO, 324 "FADT (revision %u) is longer than ACPI 5.0 version, " 325 "truncating length %u to %u", 326 Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT))); 327 } 328 329 /* Clear the entire local FADT */ 330 331 ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT)); 332 333 /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */ 334 335 ACPI_MEMCPY (&AcpiGbl_FADT, Table, 336 ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT))); 337 338 /* Take a copy of the Hardware Reduced flag */ 339 340 AcpiGbl_ReducedHardware = FALSE; 341 if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED) 342 { 343 AcpiGbl_ReducedHardware = TRUE; 344 } 345 346 /* Convert the local copy of the FADT to the common internal format */ 347 348 AcpiTbConvertFadt (); 349 350 /* Validate FADT values now, before we make any changes */ 351 352 AcpiTbValidateFadt (); 353 354 /* Initialize the global ACPI register structures */ 355 356 AcpiTbSetupFadtRegisters (); 357} 358 359 360/******************************************************************************* 361 * 362 * FUNCTION: AcpiTbConvertFadt 363 * 364 * PARAMETERS: None, uses AcpiGbl_FADT 365 * 366 * RETURN: None 367 * 368 * DESCRIPTION: Converts all versions of the FADT to a common internal format. 369 * Expand 32-bit addresses to 64-bit as necessary. 370 * 371 * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), 372 * and must contain a copy of the actual FADT. 373 * 374 * Notes on 64-bit register addresses: 375 * 376 * After this FADT conversion, later ACPICA code will only use the 64-bit "X" 377 * fields of the FADT for all ACPI register addresses. 378 * 379 * The 64-bit "X" fields are optional extensions to the original 32-bit FADT 380 * V1.0 fields. Even if they are present in the FADT, they are optional and 381 * are unused if the BIOS sets them to zero. Therefore, we must copy/expand 382 * 32-bit V1.0 fields if the corresponding X field is zero. 383 * 384 * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the 385 * corresponding "X" fields in the internal FADT. 386 * 387 * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded 388 * to the corresponding 64-bit X fields. For compatibility with other ACPI 389 * implementations, we ignore the 64-bit field if the 32-bit field is valid, 390 * regardless of whether the host OS is 32-bit or 64-bit. 391 * 392 ******************************************************************************/ 393 394static void 395AcpiTbConvertFadt ( 396 void) 397{ 398 ACPI_GENERIC_ADDRESS *Address64; 399 UINT32 Address32; 400 UINT32 i; 401 402 403 /* 404 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. 405 * Later code will always use the X 64-bit field. 406 */ 407 if (!AcpiGbl_FADT.XFacs) 408 { 409 AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs; 410 } 411 if (!AcpiGbl_FADT.XDsdt) 412 { 413 AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt; 414 } 415 416 /* 417 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which 418 * should be zero are indeed zero. This will workaround BIOSs that 419 * inadvertently place values in these fields. 420 * 421 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located 422 * at offset 45, 55, 95, and the word located at offset 109, 110. 423 * 424 * Note: The FADT revision value is unreliable. Only the length can be 425 * trusted. 426 */ 427 if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE) 428 { 429 AcpiGbl_FADT.PreferredProfile = 0; 430 AcpiGbl_FADT.PstateControl = 0; 431 AcpiGbl_FADT.CstControl = 0; 432 AcpiGbl_FADT.BootFlags = 0; 433 } 434 435 /* 436 * Now we can update the local FADT length to the length of the 437 * current FADT version as defined by the ACPI specification. 438 * Thus, we will have a common FADT internally. 439 */ 440 AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT); 441 442 /* 443 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" 444 * generic address structures as necessary. Later code will always use 445 * the 64-bit address structures. 446 * 447 * March 2009: 448 * We now always use the 32-bit address if it is valid (non-null). This 449 * is not in accordance with the ACPI specification which states that 450 * the 64-bit address supersedes the 32-bit version, but we do this for 451 * compatibility with other ACPI implementations. Most notably, in the 452 * case where both the 32 and 64 versions are non-null, we use the 32-bit 453 * version. This is the only address that is guaranteed to have been 454 * tested by the BIOS manufacturer. 455 */ 456 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 457 { 458 Address32 = *ACPI_ADD_PTR (UINT32, 459 &AcpiGbl_FADT, FadtInfoTable[i].Address32); 460 461 Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, 462 &AcpiGbl_FADT, FadtInfoTable[i].Address64); 463 464 /* 465 * If both 32- and 64-bit addresses are valid (non-zero), 466 * they must match. 467 */ 468 if (Address64->Address && Address32 && 469 (Address64->Address != (UINT64) Address32)) 470 { 471 ACPI_ERROR ((AE_INFO, 472 "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32", 473 FadtInfoTable[i].Name, Address32, 474 ACPI_FORMAT_UINT64 (Address64->Address))); 475 } 476 477 /* Always use 32-bit address if it is valid (non-null) */ 478 479 if (Address32) 480 { 481 /* 482 * Copy the 32-bit address to the 64-bit GAS structure. The 483 * Space ID is always I/O for 32-bit legacy address fields 484 */ 485 AcpiTbInitGenericAddress (Address64, ACPI_ADR_SPACE_SYSTEM_IO, 486 *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length),
| 241 GenericAddress->BitOffset = 0; 242 GenericAddress->AccessWidth = 0; /* Access width ANY */ 243} 244 245 246/******************************************************************************* 247 * 248 * FUNCTION: AcpiTbParseFadt 249 * 250 * PARAMETERS: TableIndex - Index for the FADT 251 * 252 * RETURN: None 253 * 254 * DESCRIPTION: Initialize the FADT, DSDT and FACS tables 255 * (FADT contains the addresses of the DSDT and FACS) 256 * 257 ******************************************************************************/ 258 259void 260AcpiTbParseFadt ( 261 UINT32 TableIndex) 262{ 263 UINT32 Length; 264 ACPI_TABLE_HEADER *Table; 265 266 267 /* 268 * The FADT has multiple versions with different lengths, 269 * and it contains pointers to both the DSDT and FACS tables. 270 * 271 * Get a local copy of the FADT and convert it to a common format 272 * Map entire FADT, assumed to be smaller than one page. 273 */ 274 Length = AcpiGbl_RootTableList.Tables[TableIndex].Length; 275 276 Table = AcpiOsMapMemory ( 277 AcpiGbl_RootTableList.Tables[TableIndex].Address, Length); 278 if (!Table) 279 { 280 return; 281 } 282 283 /* 284 * Validate the FADT checksum before we copy the table. Ignore 285 * checksum error as we want to try to get the DSDT and FACS. 286 */ 287 (void) AcpiTbVerifyChecksum (Table, Length); 288 289 /* Create a local copy of the FADT in common ACPI 2.0+ format */ 290 291 AcpiTbCreateLocalFadt (Table, Length); 292 293 /* All done with the real FADT, unmap it */ 294 295 AcpiOsUnmapMemory (Table, Length); 296 297 /* Obtain the DSDT and FACS tables via their addresses within the FADT */ 298 299 AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt, 300 ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); 301 302 /* If Hardware Reduced flag is set, there is no FACS */ 303 304 if (!AcpiGbl_ReducedHardware) 305 { 306 AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs, 307 ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); 308 } 309} 310 311 312/******************************************************************************* 313 * 314 * FUNCTION: AcpiTbCreateLocalFadt 315 * 316 * PARAMETERS: Table - Pointer to BIOS FADT 317 * Length - Length of the table 318 * 319 * RETURN: None 320 * 321 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. 322 * Performs validation on some important FADT fields. 323 * 324 * NOTE: We create a local copy of the FADT regardless of the version. 325 * 326 ******************************************************************************/ 327 328void 329AcpiTbCreateLocalFadt ( 330 ACPI_TABLE_HEADER *Table, 331 UINT32 Length) 332{ 333 334 /* 335 * Check if the FADT is larger than the largest table that we expect 336 * (the ACPI 5.0 version). If so, truncate the table, and issue 337 * a warning. 338 */ 339 if (Length > sizeof (ACPI_TABLE_FADT)) 340 { 341 ACPI_WARNING ((AE_INFO, 342 "FADT (revision %u) is longer than ACPI 5.0 version, " 343 "truncating length %u to %u", 344 Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT))); 345 } 346 347 /* Clear the entire local FADT */ 348 349 ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT)); 350 351 /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */ 352 353 ACPI_MEMCPY (&AcpiGbl_FADT, Table, 354 ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT))); 355 356 /* Take a copy of the Hardware Reduced flag */ 357 358 AcpiGbl_ReducedHardware = FALSE; 359 if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED) 360 { 361 AcpiGbl_ReducedHardware = TRUE; 362 } 363 364 /* Convert the local copy of the FADT to the common internal format */ 365 366 AcpiTbConvertFadt (); 367 368 /* Validate FADT values now, before we make any changes */ 369 370 AcpiTbValidateFadt (); 371 372 /* Initialize the global ACPI register structures */ 373 374 AcpiTbSetupFadtRegisters (); 375} 376 377 378/******************************************************************************* 379 * 380 * FUNCTION: AcpiTbConvertFadt 381 * 382 * PARAMETERS: None, uses AcpiGbl_FADT 383 * 384 * RETURN: None 385 * 386 * DESCRIPTION: Converts all versions of the FADT to a common internal format. 387 * Expand 32-bit addresses to 64-bit as necessary. 388 * 389 * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), 390 * and must contain a copy of the actual FADT. 391 * 392 * Notes on 64-bit register addresses: 393 * 394 * After this FADT conversion, later ACPICA code will only use the 64-bit "X" 395 * fields of the FADT for all ACPI register addresses. 396 * 397 * The 64-bit "X" fields are optional extensions to the original 32-bit FADT 398 * V1.0 fields. Even if they are present in the FADT, they are optional and 399 * are unused if the BIOS sets them to zero. Therefore, we must copy/expand 400 * 32-bit V1.0 fields if the corresponding X field is zero. 401 * 402 * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the 403 * corresponding "X" fields in the internal FADT. 404 * 405 * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded 406 * to the corresponding 64-bit X fields. For compatibility with other ACPI 407 * implementations, we ignore the 64-bit field if the 32-bit field is valid, 408 * regardless of whether the host OS is 32-bit or 64-bit. 409 * 410 ******************************************************************************/ 411 412static void 413AcpiTbConvertFadt ( 414 void) 415{ 416 ACPI_GENERIC_ADDRESS *Address64; 417 UINT32 Address32; 418 UINT32 i; 419 420 421 /* 422 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. 423 * Later code will always use the X 64-bit field. 424 */ 425 if (!AcpiGbl_FADT.XFacs) 426 { 427 AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs; 428 } 429 if (!AcpiGbl_FADT.XDsdt) 430 { 431 AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt; 432 } 433 434 /* 435 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which 436 * should be zero are indeed zero. This will workaround BIOSs that 437 * inadvertently place values in these fields. 438 * 439 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located 440 * at offset 45, 55, 95, and the word located at offset 109, 110. 441 * 442 * Note: The FADT revision value is unreliable. Only the length can be 443 * trusted. 444 */ 445 if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE) 446 { 447 AcpiGbl_FADT.PreferredProfile = 0; 448 AcpiGbl_FADT.PstateControl = 0; 449 AcpiGbl_FADT.CstControl = 0; 450 AcpiGbl_FADT.BootFlags = 0; 451 } 452 453 /* 454 * Now we can update the local FADT length to the length of the 455 * current FADT version as defined by the ACPI specification. 456 * Thus, we will have a common FADT internally. 457 */ 458 AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT); 459 460 /* 461 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" 462 * generic address structures as necessary. Later code will always use 463 * the 64-bit address structures. 464 * 465 * March 2009: 466 * We now always use the 32-bit address if it is valid (non-null). This 467 * is not in accordance with the ACPI specification which states that 468 * the 64-bit address supersedes the 32-bit version, but we do this for 469 * compatibility with other ACPI implementations. Most notably, in the 470 * case where both the 32 and 64 versions are non-null, we use the 32-bit 471 * version. This is the only address that is guaranteed to have been 472 * tested by the BIOS manufacturer. 473 */ 474 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 475 { 476 Address32 = *ACPI_ADD_PTR (UINT32, 477 &AcpiGbl_FADT, FadtInfoTable[i].Address32); 478 479 Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, 480 &AcpiGbl_FADT, FadtInfoTable[i].Address64); 481 482 /* 483 * If both 32- and 64-bit addresses are valid (non-zero), 484 * they must match. 485 */ 486 if (Address64->Address && Address32 && 487 (Address64->Address != (UINT64) Address32)) 488 { 489 ACPI_ERROR ((AE_INFO, 490 "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32", 491 FadtInfoTable[i].Name, Address32, 492 ACPI_FORMAT_UINT64 (Address64->Address))); 493 } 494 495 /* Always use 32-bit address if it is valid (non-null) */ 496 497 if (Address32) 498 { 499 /* 500 * Copy the 32-bit address to the 64-bit GAS structure. The 501 * Space ID is always I/O for 32-bit legacy address fields 502 */ 503 AcpiTbInitGenericAddress (Address64, ACPI_ADR_SPACE_SYSTEM_IO, 504 *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length),
|
487 (UINT64) Address32);
| 505 (UINT64) Address32, FadtInfoTable[i].Name);
|
488 } 489 } 490} 491 492 493/******************************************************************************* 494 * 495 * FUNCTION: AcpiTbValidateFadt 496 * 497 * PARAMETERS: Table - Pointer to the FADT to be validated 498 * 499 * RETURN: None 500 * 501 * DESCRIPTION: Validate various important fields within the FADT. If a problem 502 * is found, issue a message, but no status is returned. 503 * Used by both the table manager and the disassembler. 504 * 505 * Possible additional checks: 506 * (AcpiGbl_FADT.Pm1EventLength >= 4) 507 * (AcpiGbl_FADT.Pm1ControlLength >= 2) 508 * (AcpiGbl_FADT.PmTimerLength >= 4) 509 * Gpe block lengths must be multiple of 2 510 * 511 ******************************************************************************/ 512 513static void 514AcpiTbValidateFadt ( 515 void) 516{ 517 char *Name; 518 ACPI_GENERIC_ADDRESS *Address64; 519 UINT8 Length; 520 UINT32 i; 521 522 523 /* 524 * Check for FACS and DSDT address mismatches. An address mismatch between 525 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and 526 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables. 527 */ 528 if (AcpiGbl_FADT.Facs && 529 (AcpiGbl_FADT.XFacs != (UINT64) AcpiGbl_FADT.Facs)) 530 { 531 ACPI_WARNING ((AE_INFO, 532 "32/64X FACS address mismatch in FADT - " 533 "0x%8.8X/0x%8.8X%8.8X, using 32", 534 AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs))); 535 536 AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs; 537 } 538 539 if (AcpiGbl_FADT.Dsdt && 540 (AcpiGbl_FADT.XDsdt != (UINT64) AcpiGbl_FADT.Dsdt)) 541 { 542 ACPI_WARNING ((AE_INFO, 543 "32/64X DSDT address mismatch in FADT - " 544 "0x%8.8X/0x%8.8X%8.8X, using 32", 545 AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt))); 546 547 AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt; 548 } 549 550 /* If Hardware Reduced flag is set, we are all done */ 551 552 if (AcpiGbl_ReducedHardware) 553 { 554 return; 555 } 556 557 /* Examine all of the 64-bit extended address fields (X fields) */ 558 559 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 560 { 561 /* 562 * Generate pointer to the 64-bit address, get the register 563 * length (width) and the register name 564 */ 565 Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, 566 &AcpiGbl_FADT, FadtInfoTable[i].Address64); 567 Length = *ACPI_ADD_PTR (UINT8, 568 &AcpiGbl_FADT, FadtInfoTable[i].Length); 569 Name = FadtInfoTable[i].Name; 570 571 /* 572 * For each extended field, check for length mismatch between the 573 * legacy length field and the corresponding 64-bit X length field. 574 */ 575 if (Address64->Address && 576 (Address64->BitWidth != ACPI_MUL_8 (Length))) 577 { 578 ACPI_WARNING ((AE_INFO, 579 "32/64X length mismatch in %s: %u/%u", 580 Name, ACPI_MUL_8 (Length), Address64->BitWidth)); 581 } 582 583 if (FadtInfoTable[i].Type & ACPI_FADT_REQUIRED) 584 { 585 /* 586 * Field is required (PM1aEvent, PM1aControl, PmTimer). 587 * Both the address and length must be non-zero. 588 */ 589 if (!Address64->Address || !Length) 590 { 591 ACPI_ERROR ((AE_INFO, 592 "Required field %s has zero address and/or length:" 593 " 0x%8.8X%8.8X/0x%X", 594 Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); 595 } 596 } 597 else if (FadtInfoTable[i].Type & ACPI_FADT_SEPARATE_LENGTH) 598 { 599 /* 600 * Field is optional (PM2Control, GPE0, GPE1) AND has its own 601 * length field. If present, both the address and length must 602 * be valid. 603 */ 604 if ((Address64->Address && !Length) || 605 (!Address64->Address && Length)) 606 { 607 ACPI_WARNING ((AE_INFO, 608 "Optional field %s has zero address or length: " 609 "0x%8.8X%8.8X/0x%X", 610 Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); 611 } 612 } 613 } 614} 615 616 617/******************************************************************************* 618 * 619 * FUNCTION: AcpiTbSetupFadtRegisters 620 * 621 * PARAMETERS: None, uses AcpiGbl_FADT. 622 * 623 * RETURN: None 624 * 625 * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally, 626 * force FADT register definitions to their default lengths. 627 * 628 ******************************************************************************/ 629 630static void 631AcpiTbSetupFadtRegisters ( 632 void) 633{ 634 ACPI_GENERIC_ADDRESS *Target64; 635 ACPI_GENERIC_ADDRESS *Source64; 636 UINT8 Pm1RegisterByteWidth; 637 UINT32 i; 638 639 640 /* 641 * Optionally check all register lengths against the default values and 642 * update them if they are incorrect. 643 */ 644 if (AcpiGbl_UseDefaultRegisterWidths) 645 { 646 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 647 { 648 Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 649 FadtInfoTable[i].Address64); 650 651 /* 652 * If a valid register (Address != 0) and the (DefaultLength > 0) 653 * (Not a GPE register), then check the width against the default. 654 */ 655 if ((Target64->Address) && 656 (FadtInfoTable[i].DefaultLength > 0) && 657 (FadtInfoTable[i].DefaultLength != Target64->BitWidth)) 658 { 659 ACPI_WARNING ((AE_INFO, 660 "Invalid length for %s: %u, using default %u", 661 FadtInfoTable[i].Name, Target64->BitWidth, 662 FadtInfoTable[i].DefaultLength)); 663 664 /* Incorrect size, set width to the default */ 665 666 Target64->BitWidth = FadtInfoTable[i].DefaultLength; 667 } 668 } 669 } 670 671 /* 672 * Get the length of the individual PM1 registers (enable and status). 673 * Each register is defined to be (event block length / 2). Extra divide 674 * by 8 converts bits to bytes. 675 */ 676 Pm1RegisterByteWidth = (UINT8) 677 ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth); 678 679 /* 680 * Calculate separate GAS structs for the PM1x (A/B) Status and Enable 681 * registers. These addresses do not appear (directly) in the FADT, so it 682 * is useful to pre-calculate them from the PM1 Event Block definitions. 683 * 684 * The PM event blocks are split into two register blocks, first is the 685 * PM Status Register block, followed immediately by the PM Enable 686 * Register block. Each is of length (Pm1EventLength/2) 687 * 688 * Note: The PM1A event block is required by the ACPI specification. 689 * However, the PM1B event block is optional and is rarely, if ever, 690 * used. 691 */ 692 693 for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) 694 { 695 Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 696 FadtPmInfoTable[i].Source); 697 698 if (Source64->Address) 699 { 700 AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target, 701 Source64->SpaceId, Pm1RegisterByteWidth, 702 Source64->Address +
| 506 } 507 } 508} 509 510 511/******************************************************************************* 512 * 513 * FUNCTION: AcpiTbValidateFadt 514 * 515 * PARAMETERS: Table - Pointer to the FADT to be validated 516 * 517 * RETURN: None 518 * 519 * DESCRIPTION: Validate various important fields within the FADT. If a problem 520 * is found, issue a message, but no status is returned. 521 * Used by both the table manager and the disassembler. 522 * 523 * Possible additional checks: 524 * (AcpiGbl_FADT.Pm1EventLength >= 4) 525 * (AcpiGbl_FADT.Pm1ControlLength >= 2) 526 * (AcpiGbl_FADT.PmTimerLength >= 4) 527 * Gpe block lengths must be multiple of 2 528 * 529 ******************************************************************************/ 530 531static void 532AcpiTbValidateFadt ( 533 void) 534{ 535 char *Name; 536 ACPI_GENERIC_ADDRESS *Address64; 537 UINT8 Length; 538 UINT32 i; 539 540 541 /* 542 * Check for FACS and DSDT address mismatches. An address mismatch between 543 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and 544 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables. 545 */ 546 if (AcpiGbl_FADT.Facs && 547 (AcpiGbl_FADT.XFacs != (UINT64) AcpiGbl_FADT.Facs)) 548 { 549 ACPI_WARNING ((AE_INFO, 550 "32/64X FACS address mismatch in FADT - " 551 "0x%8.8X/0x%8.8X%8.8X, using 32", 552 AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs))); 553 554 AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs; 555 } 556 557 if (AcpiGbl_FADT.Dsdt && 558 (AcpiGbl_FADT.XDsdt != (UINT64) AcpiGbl_FADT.Dsdt)) 559 { 560 ACPI_WARNING ((AE_INFO, 561 "32/64X DSDT address mismatch in FADT - " 562 "0x%8.8X/0x%8.8X%8.8X, using 32", 563 AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt))); 564 565 AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt; 566 } 567 568 /* If Hardware Reduced flag is set, we are all done */ 569 570 if (AcpiGbl_ReducedHardware) 571 { 572 return; 573 } 574 575 /* Examine all of the 64-bit extended address fields (X fields) */ 576 577 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 578 { 579 /* 580 * Generate pointer to the 64-bit address, get the register 581 * length (width) and the register name 582 */ 583 Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, 584 &AcpiGbl_FADT, FadtInfoTable[i].Address64); 585 Length = *ACPI_ADD_PTR (UINT8, 586 &AcpiGbl_FADT, FadtInfoTable[i].Length); 587 Name = FadtInfoTable[i].Name; 588 589 /* 590 * For each extended field, check for length mismatch between the 591 * legacy length field and the corresponding 64-bit X length field. 592 */ 593 if (Address64->Address && 594 (Address64->BitWidth != ACPI_MUL_8 (Length))) 595 { 596 ACPI_WARNING ((AE_INFO, 597 "32/64X length mismatch in %s: %u/%u", 598 Name, ACPI_MUL_8 (Length), Address64->BitWidth)); 599 } 600 601 if (FadtInfoTable[i].Type & ACPI_FADT_REQUIRED) 602 { 603 /* 604 * Field is required (PM1aEvent, PM1aControl, PmTimer). 605 * Both the address and length must be non-zero. 606 */ 607 if (!Address64->Address || !Length) 608 { 609 ACPI_ERROR ((AE_INFO, 610 "Required field %s has zero address and/or length:" 611 " 0x%8.8X%8.8X/0x%X", 612 Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); 613 } 614 } 615 else if (FadtInfoTable[i].Type & ACPI_FADT_SEPARATE_LENGTH) 616 { 617 /* 618 * Field is optional (PM2Control, GPE0, GPE1) AND has its own 619 * length field. If present, both the address and length must 620 * be valid. 621 */ 622 if ((Address64->Address && !Length) || 623 (!Address64->Address && Length)) 624 { 625 ACPI_WARNING ((AE_INFO, 626 "Optional field %s has zero address or length: " 627 "0x%8.8X%8.8X/0x%X", 628 Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); 629 } 630 } 631 } 632} 633 634 635/******************************************************************************* 636 * 637 * FUNCTION: AcpiTbSetupFadtRegisters 638 * 639 * PARAMETERS: None, uses AcpiGbl_FADT. 640 * 641 * RETURN: None 642 * 643 * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally, 644 * force FADT register definitions to their default lengths. 645 * 646 ******************************************************************************/ 647 648static void 649AcpiTbSetupFadtRegisters ( 650 void) 651{ 652 ACPI_GENERIC_ADDRESS *Target64; 653 ACPI_GENERIC_ADDRESS *Source64; 654 UINT8 Pm1RegisterByteWidth; 655 UINT32 i; 656 657 658 /* 659 * Optionally check all register lengths against the default values and 660 * update them if they are incorrect. 661 */ 662 if (AcpiGbl_UseDefaultRegisterWidths) 663 { 664 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 665 { 666 Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 667 FadtInfoTable[i].Address64); 668 669 /* 670 * If a valid register (Address != 0) and the (DefaultLength > 0) 671 * (Not a GPE register), then check the width against the default. 672 */ 673 if ((Target64->Address) && 674 (FadtInfoTable[i].DefaultLength > 0) && 675 (FadtInfoTable[i].DefaultLength != Target64->BitWidth)) 676 { 677 ACPI_WARNING ((AE_INFO, 678 "Invalid length for %s: %u, using default %u", 679 FadtInfoTable[i].Name, Target64->BitWidth, 680 FadtInfoTable[i].DefaultLength)); 681 682 /* Incorrect size, set width to the default */ 683 684 Target64->BitWidth = FadtInfoTable[i].DefaultLength; 685 } 686 } 687 } 688 689 /* 690 * Get the length of the individual PM1 registers (enable and status). 691 * Each register is defined to be (event block length / 2). Extra divide 692 * by 8 converts bits to bytes. 693 */ 694 Pm1RegisterByteWidth = (UINT8) 695 ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth); 696 697 /* 698 * Calculate separate GAS structs for the PM1x (A/B) Status and Enable 699 * registers. These addresses do not appear (directly) in the FADT, so it 700 * is useful to pre-calculate them from the PM1 Event Block definitions. 701 * 702 * The PM event blocks are split into two register blocks, first is the 703 * PM Status Register block, followed immediately by the PM Enable 704 * Register block. Each is of length (Pm1EventLength/2) 705 * 706 * Note: The PM1A event block is required by the ACPI specification. 707 * However, the PM1B event block is optional and is rarely, if ever, 708 * used. 709 */ 710 711 for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) 712 { 713 Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 714 FadtPmInfoTable[i].Source); 715 716 if (Source64->Address) 717 { 718 AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target, 719 Source64->SpaceId, Pm1RegisterByteWidth, 720 Source64->Address +
|
703 (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth));
| 721 (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth), 722 "PmRegisters");
|
704 } 705 } 706} 707
| 723 } 724 } 725} 726
|