1 /****************************************************************************** 2 * 3 * Module Name: tbfadt - FADT table utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "actables.h" 47 48 #define _COMPONENT ACPI_TABLES 49 ACPI_MODULE_NAME("tbfadt") 50 51 /* Local prototypes */ 52 static void 53 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, 54 u8 space_id, 55 u8 byte_width, u64 address, char *register_name); 56 57 static void acpi_tb_convert_fadt(void); 58 59 static void acpi_tb_validate_fadt(void); 60 61 static void acpi_tb_setup_fadt_registers(void); 62 63 /* Table for conversion of FADT to common internal format and FADT validation */ 64 65 typedef struct acpi_fadt_info { 66 char *name; 67 u16 address64; 68 u16 address32; 69 u16 length; 70 u8 default_length; 71 u8 type; 72 73 } acpi_fadt_info; 74 75 #define ACPI_FADT_OPTIONAL 0 76 #define ACPI_FADT_REQUIRED 1 77 #define ACPI_FADT_SEPARATE_LENGTH 2 78 79 static struct acpi_fadt_info fadt_info_table[] = { 80 {"Pm1aEventBlock", 81 ACPI_FADT_OFFSET(xpm1a_event_block), 82 ACPI_FADT_OFFSET(pm1a_event_block), 83 ACPI_FADT_OFFSET(pm1_event_length), 84 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 85 ACPI_FADT_REQUIRED}, 86 87 {"Pm1bEventBlock", 88 ACPI_FADT_OFFSET(xpm1b_event_block), 89 ACPI_FADT_OFFSET(pm1b_event_block), 90 ACPI_FADT_OFFSET(pm1_event_length), 91 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 92 ACPI_FADT_OPTIONAL}, 93 94 {"Pm1aControlBlock", 95 ACPI_FADT_OFFSET(xpm1a_control_block), 96 ACPI_FADT_OFFSET(pm1a_control_block), 97 ACPI_FADT_OFFSET(pm1_control_length), 98 ACPI_PM1_REGISTER_WIDTH, 99 ACPI_FADT_REQUIRED}, 100 101 {"Pm1bControlBlock", 102 ACPI_FADT_OFFSET(xpm1b_control_block), 103 ACPI_FADT_OFFSET(pm1b_control_block), 104 ACPI_FADT_OFFSET(pm1_control_length), 105 ACPI_PM1_REGISTER_WIDTH, 106 ACPI_FADT_OPTIONAL}, 107 108 {"Pm2ControlBlock", 109 ACPI_FADT_OFFSET(xpm2_control_block), 110 ACPI_FADT_OFFSET(pm2_control_block), 111 ACPI_FADT_OFFSET(pm2_control_length), 112 ACPI_PM2_REGISTER_WIDTH, 113 ACPI_FADT_SEPARATE_LENGTH}, 114 115 {"PmTimerBlock", 116 ACPI_FADT_OFFSET(xpm_timer_block), 117 ACPI_FADT_OFFSET(pm_timer_block), 118 ACPI_FADT_OFFSET(pm_timer_length), 119 ACPI_PM_TIMER_WIDTH, 120 ACPI_FADT_SEPARATE_LENGTH}, /* ACPI 5.0A: Timer is optional */ 121 122 {"Gpe0Block", 123 ACPI_FADT_OFFSET(xgpe0_block), 124 ACPI_FADT_OFFSET(gpe0_block), 125 ACPI_FADT_OFFSET(gpe0_block_length), 126 0, 127 ACPI_FADT_SEPARATE_LENGTH}, 128 129 {"Gpe1Block", 130 ACPI_FADT_OFFSET(xgpe1_block), 131 ACPI_FADT_OFFSET(gpe1_block), 132 ACPI_FADT_OFFSET(gpe1_block_length), 133 0, 134 ACPI_FADT_SEPARATE_LENGTH} 135 }; 136 137 #define ACPI_FADT_INFO_ENTRIES \ 138 (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) 139 140 /* Table used to split Event Blocks into separate status/enable registers */ 141 142 typedef struct acpi_fadt_pm_info { 143 struct acpi_generic_address *target; 144 u16 source; 145 u8 register_num; 146 147 } acpi_fadt_pm_info; 148 149 static struct acpi_fadt_pm_info fadt_pm_info_table[] = { 150 {&acpi_gbl_xpm1a_status, 151 ACPI_FADT_OFFSET(xpm1a_event_block), 152 0}, 153 154 {&acpi_gbl_xpm1a_enable, 155 ACPI_FADT_OFFSET(xpm1a_event_block), 156 1}, 157 158 {&acpi_gbl_xpm1b_status, 159 ACPI_FADT_OFFSET(xpm1b_event_block), 160 0}, 161 162 {&acpi_gbl_xpm1b_enable, 163 ACPI_FADT_OFFSET(xpm1b_event_block), 164 1} 165 }; 166 167 #define ACPI_FADT_PM_INFO_ENTRIES \ 168 (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info)) 169 170 /******************************************************************************* 171 * 172 * FUNCTION: acpi_tb_init_generic_address 173 * 174 * PARAMETERS: generic_address - GAS struct to be initialized 175 * space_id - ACPI Space ID for this register 176 * byte_width - Width of this register 177 * address - Address of the register 178 * 179 * RETURN: None 180 * 181 * DESCRIPTION: Initialize a Generic Address Structure (GAS) 182 * See the ACPI specification for a full description and 183 * definition of this structure. 184 * 185 ******************************************************************************/ 186 187 static void 188 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, 189 u8 space_id, 190 u8 byte_width, u64 address, char *register_name) 191 { 192 u8 bit_width; 193 194 /* Bit width field in the GAS is only one byte long, 255 max */ 195 196 bit_width = (u8)(byte_width * 8); 197 198 if (byte_width > 31) { /* (31*8)=248 */ 199 ACPI_ERROR((AE_INFO, 200 "%s - 32-bit FADT register is too long (%u bytes, %u bits) " 201 "to convert to GAS struct - 255 bits max, truncating", 202 register_name, byte_width, (byte_width * 8))); 203 204 bit_width = 255; 205 } 206 207 /* 208 * The 64-bit Address field is non-aligned in the byte packed 209 * GAS struct. 210 */ 211 ACPI_MOVE_64_TO_64(&generic_address->address, &address); 212 213 /* All other fields are byte-wide */ 214 215 generic_address->space_id = space_id; 216 generic_address->bit_width = bit_width; 217 generic_address->bit_offset = 0; 218 generic_address->access_width = 0; /* Access width ANY */ 219 } 220 221 /******************************************************************************* 222 * 223 * FUNCTION: acpi_tb_parse_fadt 224 * 225 * PARAMETERS: table_index - Index for the FADT 226 * 227 * RETURN: None 228 * 229 * DESCRIPTION: Initialize the FADT, DSDT and FACS tables 230 * (FADT contains the addresses of the DSDT and FACS) 231 * 232 ******************************************************************************/ 233 234 void acpi_tb_parse_fadt(u32 table_index) 235 { 236 u32 length; 237 struct acpi_table_header *table; 238 239 /* 240 * The FADT has multiple versions with different lengths, 241 * and it contains pointers to both the DSDT and FACS tables. 242 * 243 * Get a local copy of the FADT and convert it to a common format 244 * Map entire FADT, assumed to be smaller than one page. 245 */ 246 length = acpi_gbl_root_table_list.tables[table_index].length; 247 248 table = 249 acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index]. 250 address, length); 251 if (!table) { 252 return; 253 } 254 255 /* 256 * Validate the FADT checksum before we copy the table. Ignore 257 * checksum error as we want to try to get the DSDT and FACS. 258 */ 259 (void)acpi_tb_verify_checksum(table, length); 260 261 /* Create a local copy of the FADT in common ACPI 2.0+ format */ 262 263 acpi_tb_create_local_fadt(table, length); 264 265 /* All done with the real FADT, unmap it */ 266 267 acpi_os_unmap_memory(table, length); 268 269 /* Obtain the DSDT and FACS tables via their addresses within the FADT */ 270 271 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, 272 ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); 273 274 /* If Hardware Reduced flag is set, there is no FACS */ 275 276 if (!acpi_gbl_reduced_hardware) { 277 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT. 278 Xfacs, ACPI_SIG_FACS, 279 ACPI_TABLE_INDEX_FACS); 280 } 281 } 282 283 /******************************************************************************* 284 * 285 * FUNCTION: acpi_tb_create_local_fadt 286 * 287 * PARAMETERS: table - Pointer to BIOS FADT 288 * length - Length of the table 289 * 290 * RETURN: None 291 * 292 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. 293 * Performs validation on some important FADT fields. 294 * 295 * NOTE: We create a local copy of the FADT regardless of the version. 296 * 297 ******************************************************************************/ 298 299 void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) 300 { 301 /* 302 * Check if the FADT is larger than the largest table that we expect 303 * (the ACPI 5.0 version). If so, truncate the table, and issue 304 * a warning. 305 */ 306 if (length > sizeof(struct acpi_table_fadt)) { 307 ACPI_BIOS_WARNING((AE_INFO, 308 "FADT (revision %u) is longer than ACPI 5.0 version, " 309 "truncating length %u to %u", 310 table->revision, length, 311 (u32)sizeof(struct acpi_table_fadt))); 312 } 313 314 /* Clear the entire local FADT */ 315 316 ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); 317 318 /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ 319 320 ACPI_MEMCPY(&acpi_gbl_FADT, table, 321 ACPI_MIN(length, sizeof(struct acpi_table_fadt))); 322 323 /* Take a copy of the Hardware Reduced flag */ 324 325 acpi_gbl_reduced_hardware = FALSE; 326 if (acpi_gbl_FADT.flags & ACPI_FADT_HW_REDUCED) { 327 acpi_gbl_reduced_hardware = TRUE; 328 } 329 330 /* Convert the local copy of the FADT to the common internal format */ 331 332 acpi_tb_convert_fadt(); 333 334 /* Validate FADT values now, before we make any changes */ 335 336 acpi_tb_validate_fadt(); 337 338 /* Initialize the global ACPI register structures */ 339 340 acpi_tb_setup_fadt_registers(); 341 } 342 343 /******************************************************************************* 344 * 345 * FUNCTION: acpi_tb_convert_fadt 346 * 347 * PARAMETERS: None, uses acpi_gbl_FADT 348 * 349 * RETURN: None 350 * 351 * DESCRIPTION: Converts all versions of the FADT to a common internal format. 352 * Expand 32-bit addresses to 64-bit as necessary. 353 * 354 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), 355 * and must contain a copy of the actual FADT. 356 * 357 * Notes on 64-bit register addresses: 358 * 359 * After this FADT conversion, later ACPICA code will only use the 64-bit "X" 360 * fields of the FADT for all ACPI register addresses. 361 * 362 * The 64-bit "X" fields are optional extensions to the original 32-bit FADT 363 * V1.0 fields. Even if they are present in the FADT, they are optional and 364 * are unused if the BIOS sets them to zero. Therefore, we must copy/expand 365 * 32-bit V1.0 fields if the corresponding X field is zero. 366 * 367 * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the 368 * corresponding "X" fields in the internal FADT. 369 * 370 * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded 371 * to the corresponding 64-bit X fields. For compatibility with other ACPI 372 * implementations, we ignore the 64-bit field if the 32-bit field is valid, 373 * regardless of whether the host OS is 32-bit or 64-bit. 374 * 375 ******************************************************************************/ 376 377 static void acpi_tb_convert_fadt(void) 378 { 379 struct acpi_generic_address *address64; 380 u32 address32; 381 u32 i; 382 383 /* 384 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. 385 * Later code will always use the X 64-bit field. Also, check for an 386 * address mismatch between the 32-bit and 64-bit address fields 387 * (FIRMWARE_CTRL/X_FIRMWARE_CTRL, DSDT/X_DSDT) which would indicate 388 * the presence of two FACS or two DSDT tables. 389 */ 390 if (!acpi_gbl_FADT.Xfacs) { 391 acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; 392 } else if (acpi_gbl_FADT.facs && 393 (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) { 394 ACPI_WARNING((AE_INFO, 395 "32/64 FACS address mismatch in FADT - two FACS tables!")); 396 } 397 398 if (!acpi_gbl_FADT.Xdsdt) { 399 acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; 400 } else if (acpi_gbl_FADT.dsdt && 401 (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) { 402 ACPI_WARNING((AE_INFO, 403 "32/64 DSDT address mismatch in FADT - two DSDT tables!")); 404 } 405 406 /* 407 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which 408 * should be zero are indeed zero. This will workaround BIOSs that 409 * inadvertently place values in these fields. 410 * 411 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located 412 * at offset 45, 55, 95, and the word located at offset 109, 110. 413 * 414 * Note: The FADT revision value is unreliable. Only the length can be 415 * trusted. 416 */ 417 if (acpi_gbl_FADT.header.length <= ACPI_FADT_V2_SIZE) { 418 acpi_gbl_FADT.preferred_profile = 0; 419 acpi_gbl_FADT.pstate_control = 0; 420 acpi_gbl_FADT.cst_control = 0; 421 acpi_gbl_FADT.boot_flags = 0; 422 } 423 424 /* Update the local FADT table header length */ 425 426 acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); 427 428 /* 429 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" 430 * generic address structures as necessary. Later code will always use 431 * the 64-bit address structures. 432 * 433 * March 2009: 434 * We now always use the 32-bit address if it is valid (non-null). This 435 * is not in accordance with the ACPI specification which states that 436 * the 64-bit address supersedes the 32-bit version, but we do this for 437 * compatibility with other ACPI implementations. Most notably, in the 438 * case where both the 32 and 64 versions are non-null, we use the 32-bit 439 * version. This is the only address that is guaranteed to have been 440 * tested by the BIOS manufacturer. 441 */ 442 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { 443 address32 = *ACPI_ADD_PTR(u32, 444 &acpi_gbl_FADT, 445 fadt_info_table[i].address32); 446 447 address64 = ACPI_ADD_PTR(struct acpi_generic_address, 448 &acpi_gbl_FADT, 449 fadt_info_table[i].address64); 450 451 /* 452 * If both 32- and 64-bit addresses are valid (non-zero), 453 * they must match. 454 */ 455 if (address64->address && address32 && 456 (address64->address != (u64)address32)) { 457 ACPI_BIOS_ERROR((AE_INFO, 458 "32/64X address mismatch in FADT/%s: " 459 "0x%8.8X/0x%8.8X%8.8X, using 32", 460 fadt_info_table[i].name, address32, 461 ACPI_FORMAT_UINT64(address64-> 462 address))); 463 } 464 465 /* Always use 32-bit address if it is valid (non-null) */ 466 467 if (address32) { 468 /* 469 * Copy the 32-bit address to the 64-bit GAS structure. The 470 * Space ID is always I/O for 32-bit legacy address fields 471 */ 472 acpi_tb_init_generic_address(address64, 473 ACPI_ADR_SPACE_SYSTEM_IO, 474 *ACPI_ADD_PTR(u8, 475 &acpi_gbl_FADT, 476 fadt_info_table 477 [i].length), 478 (u64) address32, 479 fadt_info_table[i].name); 480 } 481 } 482 } 483 484 /******************************************************************************* 485 * 486 * FUNCTION: acpi_tb_validate_fadt 487 * 488 * PARAMETERS: table - Pointer to the FADT to be validated 489 * 490 * RETURN: None 491 * 492 * DESCRIPTION: Validate various important fields within the FADT. If a problem 493 * is found, issue a message, but no status is returned. 494 * Used by both the table manager and the disassembler. 495 * 496 * Possible additional checks: 497 * (acpi_gbl_FADT.pm1_event_length >= 4) 498 * (acpi_gbl_FADT.pm1_control_length >= 2) 499 * (acpi_gbl_FADT.pm_timer_length >= 4) 500 * Gpe block lengths must be multiple of 2 501 * 502 ******************************************************************************/ 503 504 static void acpi_tb_validate_fadt(void) 505 { 506 char *name; 507 struct acpi_generic_address *address64; 508 u8 length; 509 u32 i; 510 511 /* 512 * Check for FACS and DSDT address mismatches. An address mismatch between 513 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and 514 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables. 515 */ 516 if (acpi_gbl_FADT.facs && 517 (acpi_gbl_FADT.Xfacs != (u64)acpi_gbl_FADT.facs)) { 518 ACPI_BIOS_WARNING((AE_INFO, 519 "32/64X FACS address mismatch in FADT - " 520 "0x%8.8X/0x%8.8X%8.8X, using 32", 521 acpi_gbl_FADT.facs, 522 ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs))); 523 524 acpi_gbl_FADT.Xfacs = (u64)acpi_gbl_FADT.facs; 525 } 526 527 if (acpi_gbl_FADT.dsdt && 528 (acpi_gbl_FADT.Xdsdt != (u64)acpi_gbl_FADT.dsdt)) { 529 ACPI_BIOS_WARNING((AE_INFO, 530 "32/64X DSDT address mismatch in FADT - " 531 "0x%8.8X/0x%8.8X%8.8X, using 32", 532 acpi_gbl_FADT.dsdt, 533 ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt))); 534 535 acpi_gbl_FADT.Xdsdt = (u64)acpi_gbl_FADT.dsdt; 536 } 537 538 /* If Hardware Reduced flag is set, we are all done */ 539 540 if (acpi_gbl_reduced_hardware) { 541 return; 542 } 543 544 /* Examine all of the 64-bit extended address fields (X fields) */ 545 546 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { 547 /* 548 * Generate pointer to the 64-bit address, get the register 549 * length (width) and the register name 550 */ 551 address64 = ACPI_ADD_PTR(struct acpi_generic_address, 552 &acpi_gbl_FADT, 553 fadt_info_table[i].address64); 554 length = 555 *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, 556 fadt_info_table[i].length); 557 name = fadt_info_table[i].name; 558 559 /* 560 * For each extended field, check for length mismatch between the 561 * legacy length field and the corresponding 64-bit X length field. 562 * Note: If the legacy length field is > 0xFF bits, ignore this 563 * check. (GPE registers can be larger than the 64-bit GAS structure 564 * can accomodate, 0xFF bits). 565 */ 566 if (address64->address && 567 (ACPI_MUL_8(length) <= ACPI_UINT8_MAX) && 568 (address64->bit_width != ACPI_MUL_8(length))) { 569 ACPI_BIOS_WARNING((AE_INFO, 570 "32/64X length mismatch in FADT/%s: %u/%u", 571 name, ACPI_MUL_8(length), 572 address64->bit_width)); 573 } 574 575 if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { 576 /* 577 * Field is required (Pm1a_event, Pm1a_control). 578 * Both the address and length must be non-zero. 579 */ 580 if (!address64->address || !length) { 581 ACPI_BIOS_ERROR((AE_INFO, 582 "Required FADT field %s has zero address and/or length: " 583 "0x%8.8X%8.8X/0x%X", 584 name, 585 ACPI_FORMAT_UINT64(address64-> 586 address), 587 length)); 588 } 589 } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { 590 /* 591 * Field is optional (Pm2_control, GPE0, GPE1) AND has its own 592 * length field. If present, both the address and length must 593 * be valid. 594 */ 595 if ((address64->address && !length) || 596 (!address64->address && length)) { 597 ACPI_BIOS_WARNING((AE_INFO, 598 "Optional FADT field %s has zero address or length: " 599 "0x%8.8X%8.8X/0x%X", 600 name, 601 ACPI_FORMAT_UINT64 602 (address64->address), 603 length)); 604 } 605 } 606 } 607 } 608 609 /******************************************************************************* 610 * 611 * FUNCTION: acpi_tb_setup_fadt_registers 612 * 613 * PARAMETERS: None, uses acpi_gbl_FADT. 614 * 615 * RETURN: None 616 * 617 * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally, 618 * force FADT register definitions to their default lengths. 619 * 620 ******************************************************************************/ 621 622 static void acpi_tb_setup_fadt_registers(void) 623 { 624 struct acpi_generic_address *target64; 625 struct acpi_generic_address *source64; 626 u8 pm1_register_byte_width; 627 u32 i; 628 629 /* 630 * Optionally check all register lengths against the default values and 631 * update them if they are incorrect. 632 */ 633 if (acpi_gbl_use_default_register_widths) { 634 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { 635 target64 = 636 ACPI_ADD_PTR(struct acpi_generic_address, 637 &acpi_gbl_FADT, 638 fadt_info_table[i].address64); 639 640 /* 641 * If a valid register (Address != 0) and the (default_length > 0) 642 * (Not a GPE register), then check the width against the default. 643 */ 644 if ((target64->address) && 645 (fadt_info_table[i].default_length > 0) && 646 (fadt_info_table[i].default_length != 647 target64->bit_width)) { 648 ACPI_BIOS_WARNING((AE_INFO, 649 "Invalid length for FADT/%s: %u, using default %u", 650 fadt_info_table[i].name, 651 target64->bit_width, 652 fadt_info_table[i]. 653 default_length)); 654 655 /* Incorrect size, set width to the default */ 656 657 target64->bit_width = 658 fadt_info_table[i].default_length; 659 } 660 } 661 } 662 663 /* 664 * Get the length of the individual PM1 registers (enable and status). 665 * Each register is defined to be (event block length / 2). Extra divide 666 * by 8 converts bits to bytes. 667 */ 668 pm1_register_byte_width = (u8) 669 ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width); 670 671 /* 672 * Calculate separate GAS structs for the PM1x (A/B) Status and Enable 673 * registers. These addresses do not appear (directly) in the FADT, so it 674 * is useful to pre-calculate them from the PM1 Event Block definitions. 675 * 676 * The PM event blocks are split into two register blocks, first is the 677 * PM Status Register block, followed immediately by the PM Enable 678 * Register block. Each is of length (pm1_event_length/2) 679 * 680 * Note: The PM1A event block is required by the ACPI specification. 681 * However, the PM1B event block is optional and is rarely, if ever, 682 * used. 683 */ 684 685 for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) { 686 source64 = 687 ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, 688 fadt_pm_info_table[i].source); 689 690 if (source64->address) { 691 acpi_tb_init_generic_address(fadt_pm_info_table[i]. 692 target, source64->space_id, 693 pm1_register_byte_width, 694 source64->address + 695 (fadt_pm_info_table[i]. 696 register_num * 697 pm1_register_byte_width), 698 "PmRegisters"); 699 } 700 } 701 } 702