aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables/tbfadt.c
diff options
context:
space:
mode:
authorrobert.moore@intel.com <robert.moore@intel.com>2008-12-31 00:07:26 -0500
committerLen Brown <len.brown@intel.com>2008-12-31 01:17:56 -0500
commit4b67a0e467a57e24da6b761dbf95fa5d0225ff19 (patch)
treeefbfb11d74b7b522dab8b4c7f8d332629d66166c /drivers/acpi/tables/tbfadt.c
parent06f5541960d02d5e0ddd8fd5c9a1554d85d94fa9 (diff)
ACPICA: FADT: set acpi_gbl_use_default_register_widths to TRUE by default
This returns the FADT support to the original behavior, which is to use default register widths. However, now check each register definition and report a warning if it differs from the default. This is a first step to moving away from the default widths, rather than outright believing the widths in all FADTs for all machines, considered rather dangerous until more data is obtained. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/tables/tbfadt.c')
-rw-r--r--drivers/acpi/tables/tbfadt.c173
1 files changed, 105 insertions, 68 deletions
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
index b4ce2074c91..7dec0af3f26 100644
--- a/drivers/acpi/tables/tbfadt.c
+++ b/drivers/acpi/tables/tbfadt.c
@@ -61,9 +61,10 @@ static void acpi_tb_validate_fadt(void);
61 61
62typedef struct acpi_fadt_info { 62typedef struct acpi_fadt_info {
63 char *name; 63 char *name;
64 u8 target; 64 u8 address64;
65 u8 source; 65 u8 address32;
66 u8 length; 66 u8 length;
67 u8 default_length;
67 u8 type; 68 u8 type;
68 69
69} acpi_fadt_info; 70} acpi_fadt_info;
@@ -72,37 +73,61 @@ typedef struct acpi_fadt_info {
72#define ACPI_FADT_SEPARATE_LENGTH 2 73#define ACPI_FADT_SEPARATE_LENGTH 2
73 74
74static struct acpi_fadt_info fadt_info_table[] = { 75static struct acpi_fadt_info fadt_info_table[] = {
75 {"Pm1aEventBlock", ACPI_FADT_OFFSET(xpm1a_event_block), 76 {"Pm1aEventBlock",
77 ACPI_FADT_OFFSET(xpm1a_event_block),
76 ACPI_FADT_OFFSET(pm1a_event_block), 78 ACPI_FADT_OFFSET(pm1a_event_block),
77 ACPI_FADT_OFFSET(pm1_event_length), ACPI_FADT_REQUIRED}, 79 ACPI_FADT_OFFSET(pm1_event_length),
80 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
81 ACPI_FADT_REQUIRED},
78 82
79 {"Pm1bEventBlock", ACPI_FADT_OFFSET(xpm1b_event_block), 83 {"Pm1bEventBlock",
84 ACPI_FADT_OFFSET(xpm1b_event_block),
80 ACPI_FADT_OFFSET(pm1b_event_block), 85 ACPI_FADT_OFFSET(pm1b_event_block),
81 ACPI_FADT_OFFSET(pm1_event_length), 0}, 86 ACPI_FADT_OFFSET(pm1_event_length),
87 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
88 0},
82 89
83 {"Pm1aControlBlock", ACPI_FADT_OFFSET(xpm1a_control_block), 90 {"Pm1aControlBlock",
91 ACPI_FADT_OFFSET(xpm1a_control_block),
84 ACPI_FADT_OFFSET(pm1a_control_block), 92 ACPI_FADT_OFFSET(pm1a_control_block),
85 ACPI_FADT_OFFSET(pm1_control_length), ACPI_FADT_REQUIRED}, 93 ACPI_FADT_OFFSET(pm1_control_length),
94 ACPI_PM1_REGISTER_WIDTH,
95 ACPI_FADT_REQUIRED},
86 96
87 {"Pm1bControlBlock", ACPI_FADT_OFFSET(xpm1b_control_block), 97 {"Pm1bControlBlock",
98 ACPI_FADT_OFFSET(xpm1b_control_block),
88 ACPI_FADT_OFFSET(pm1b_control_block), 99 ACPI_FADT_OFFSET(pm1b_control_block),
89 ACPI_FADT_OFFSET(pm1_control_length), 0}, 100 ACPI_FADT_OFFSET(pm1_control_length),
101 ACPI_PM1_REGISTER_WIDTH,
102 0},
90 103
91 {"Pm2ControlBlock", ACPI_FADT_OFFSET(xpm2_control_block), 104 {"Pm2ControlBlock",
105 ACPI_FADT_OFFSET(xpm2_control_block),
92 ACPI_FADT_OFFSET(pm2_control_block), 106 ACPI_FADT_OFFSET(pm2_control_block),
93 ACPI_FADT_OFFSET(pm2_control_length), ACPI_FADT_SEPARATE_LENGTH}, 107 ACPI_FADT_OFFSET(pm2_control_length),
108 ACPI_PM2_REGISTER_WIDTH,
109 ACPI_FADT_SEPARATE_LENGTH},
94 110
95 {"PmTimerBlock", ACPI_FADT_OFFSET(xpm_timer_block), 111 {"PmTimerBlock",
112 ACPI_FADT_OFFSET(xpm_timer_block),
96 ACPI_FADT_OFFSET(pm_timer_block), 113 ACPI_FADT_OFFSET(pm_timer_block),
97 ACPI_FADT_OFFSET(pm_timer_length), ACPI_FADT_REQUIRED}, 114 ACPI_FADT_OFFSET(pm_timer_length),
115 ACPI_PM_TIMER_WIDTH,
116 ACPI_FADT_REQUIRED},
98 117
99 {"Gpe0Block", ACPI_FADT_OFFSET(xgpe0_block), 118 {"Gpe0Block",
119 ACPI_FADT_OFFSET(xgpe0_block),
100 ACPI_FADT_OFFSET(gpe0_block), 120 ACPI_FADT_OFFSET(gpe0_block),
101 ACPI_FADT_OFFSET(gpe0_block_length), ACPI_FADT_SEPARATE_LENGTH}, 121 ACPI_FADT_OFFSET(gpe0_block_length),
122 0,
123 ACPI_FADT_SEPARATE_LENGTH},
102 124
103 {"Gpe1Block", ACPI_FADT_OFFSET(xgpe1_block), 125 {"Gpe1Block",
126 ACPI_FADT_OFFSET(xgpe1_block),
104 ACPI_FADT_OFFSET(gpe1_block), 127 ACPI_FADT_OFFSET(gpe1_block),
105 ACPI_FADT_OFFSET(gpe1_block_length), ACPI_FADT_SEPARATE_LENGTH} 128 ACPI_FADT_OFFSET(gpe1_block_length),
129 0,
130 ACPI_FADT_SEPARATE_LENGTH}
106}; 131};
107 132
108#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) 133#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
@@ -279,8 +304,9 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
279 304
280static void acpi_tb_convert_fadt(void) 305static void acpi_tb_convert_fadt(void)
281{ 306{
282 u8 pm1_register_length; 307 u8 pm1_register_bit_width;
283 struct acpi_generic_address *target; 308 u8 pm1_register_byte_width;
309 struct acpi_generic_address *target64;
284 u32 i; 310 u32 i;
285 311
286 /* Update the local FADT table header length */ 312 /* Update the local FADT table header length */
@@ -326,21 +352,22 @@ static void acpi_tb_convert_fadt(void)
326 } 352 }
327 353
328 /* 354 /*
329 * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X" 355 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
330 * generic address structures as necessary. 356 * generic address structures as necessary. Later code will always use
357 * the 64-bit address structures.
331 */ 358 */
332 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { 359 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
333 target = 360 target64 =
334 ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, 361 ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
335 fadt_info_table[i].target); 362 fadt_info_table[i].address64);
336 363
337 /* Expand only if the X target is null */ 364 /* Expand only if the 64-bit X target is null */
338 365
339 if (!target->address) { 366 if (!target64->address) {
340 367
341 /* The space_id is always I/O for the legacy address fields */ 368 /* The space_id is always I/O for the 32-bit legacy address fields */
342 369
343 acpi_tb_init_generic_address(target, 370 acpi_tb_init_generic_address(target64,
344 ACPI_ADR_SPACE_SYSTEM_IO, 371 ACPI_ADR_SPACE_SYSTEM_IO,
345 *ACPI_ADD_PTR(u8, 372 *ACPI_ADD_PTR(u8,
346 &acpi_gbl_FADT, 373 &acpi_gbl_FADT,
@@ -350,7 +377,7 @@ static void acpi_tb_convert_fadt(void)
350 &acpi_gbl_FADT, 377 &acpi_gbl_FADT,
351 fadt_info_table 378 fadt_info_table
352 [i]. 379 [i].
353 source)); 380 address32));
354 } 381 }
355 } 382 }
356 383
@@ -359,19 +386,53 @@ static void acpi_tb_convert_fadt(void)
359 acpi_tb_validate_fadt(); 386 acpi_tb_validate_fadt();
360 387
361 /* 388 /*
362 * Get the length of the individual PM1 registers. Each register is 389 * Optionally check all register lengths against the default values and
363 * defined to be the event block length / 2. 390 * update them if they are incorrect.
364 */ 391 */
365 pm1_register_length = (u8)ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length); 392 if (acpi_gbl_use_default_register_widths) {
393 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
394 target64 =
395 ACPI_ADD_PTR(struct acpi_generic_address,
396 &acpi_gbl_FADT,
397 fadt_info_table[i].address64);
398
399 /*
400 * If a valid register (Address != 0) and the (default_length > 0)
401 * (Not a GPE register), then check the width against the default.
402 */
403 if ((target64->address) &&
404 (fadt_info_table[i].default_length > 0) &&
405 (fadt_info_table[i].default_length !=
406 target64->bit_width)) {
407 ACPI_WARNING((AE_INFO,
408 "Invalid length for %s: %d, using default %d",
409 fadt_info_table[i].name,
410 target64->bit_width,
411 fadt_info_table[i].
412 default_length));
413
414 /* Incorrect size, set width to the default */
415
416 target64->bit_width =
417 fadt_info_table[i].default_length;
418 }
419 }
420 }
421
422 /*
423 * Get the length of the individual PM1 registers (enable and status).
424 * Each register is defined to be (event block length / 2).
425 */
426 pm1_register_bit_width =
427 (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
428 pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
366 429
367 /* 430 /*
368 * Adjust the lengths of the PM1 Event Blocks so that they can be used to 431 * Adjust the lengths of the PM1 Event Blocks so that they can be used to
369 * access the PM1 status register(s). 432 * access the PM1 status register(s). Use (width / 2)
370 */ 433 */
371 acpi_gbl_FADT.xpm1a_event_block.bit_width = 434 acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
372 (u8)ACPI_MUL_8(pm1_register_length); 435 acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
373 acpi_gbl_FADT.xpm1b_event_block.bit_width =
374 (u8)ACPI_MUL_8(pm1_register_length);
375 436
376 /* 437 /*
377 * Calculate separate GAS structs for the PM1 Enable registers. 438 * Calculate separate GAS structs for the PM1 Enable registers.
@@ -398,9 +459,9 @@ static void acpi_tb_convert_fadt(void)
398 459
399 acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, 460 acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
400 acpi_gbl_FADT.xpm1a_event_block.space_id, 461 acpi_gbl_FADT.xpm1a_event_block.space_id,
401 pm1_register_length, 462 pm1_register_byte_width,
402 (acpi_gbl_FADT.xpm1a_event_block.address + 463 (acpi_gbl_FADT.xpm1a_event_block.address +
403 pm1_register_length)); 464 pm1_register_byte_width));
404 /* Don't forget to copy space_id of the GAS */ 465 /* Don't forget to copy space_id of the GAS */
405 acpi_gbl_xpm1a_enable.space_id = 466 acpi_gbl_xpm1a_enable.space_id =
406 acpi_gbl_FADT.xpm1a_event_block.space_id; 467 acpi_gbl_FADT.xpm1a_event_block.space_id;
@@ -417,38 +478,14 @@ static void acpi_tb_convert_fadt(void)
417 acpi_gbl_FADT.pm1_event_length); 478 acpi_gbl_FADT.pm1_event_length);
418 acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, 479 acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
419 acpi_gbl_FADT.xpm1b_event_block.space_id, 480 acpi_gbl_FADT.xpm1b_event_block.space_id,
420 pm1_register_length, 481 pm1_register_byte_width,
421 (acpi_gbl_FADT.xpm1b_event_block. 482 (acpi_gbl_FADT.xpm1b_event_block.
422 address + pm1_register_length)); 483 address + pm1_register_byte_width));
423 /* Don't forget to copy space_id of the GAS */ 484 /* Don't forget to copy space_id of the GAS */
424 acpi_gbl_xpm1b_enable.space_id = 485 acpi_gbl_xpm1b_enable.space_id =
425 acpi_gbl_FADT.xpm1b_event_block.space_id; 486 acpi_gbl_FADT.xpm1b_event_block.space_id;
426 487
427 } 488 }
428
429 if (acpi_gbl_use_default_register_widths) {
430 /*
431 * Optionally, use the default sizes for the ACPI registers.
432 * Some FADTs do not have the correct length(s).
433 *
434 * Note: Xpm1a_event_block and Xpm1b_event_block are used to access the PM1
435 * status registers. The PM1 enable registers are created above.
436 */
437 acpi_gbl_xpm1a_enable.bit_width = ACPI_PM1_REGISTER_WIDTH;
438 acpi_gbl_xpm1b_enable.bit_width = ACPI_PM1_REGISTER_WIDTH;
439
440 acpi_gbl_FADT.xpm1a_event_block.bit_width =
441 ACPI_PM1_REGISTER_WIDTH;
442 acpi_gbl_FADT.xpm1b_event_block.bit_width =
443 ACPI_PM1_REGISTER_WIDTH;
444 acpi_gbl_FADT.xpm1a_control_block.bit_width =
445 ACPI_PM1_REGISTER_WIDTH;
446 acpi_gbl_FADT.xpm1b_control_block.bit_width =
447 ACPI_PM1_REGISTER_WIDTH;
448 acpi_gbl_FADT.xpm2_control_block.bit_width =
449 ACPI_PM2_REGISTER_WIDTH;
450 acpi_gbl_FADT.xpm_timer_block.bit_width = ACPI_PM_TIMER_WIDTH;
451 }
452} 489}
453 490
454/****************************************************************************** 491/******************************************************************************
@@ -511,10 +548,10 @@ static void acpi_tb_validate_fadt(void)
511 */ 548 */
512 address64 = ACPI_ADD_PTR(struct acpi_generic_address, 549 address64 = ACPI_ADD_PTR(struct acpi_generic_address,
513 &acpi_gbl_FADT, 550 &acpi_gbl_FADT,
514 fadt_info_table[i].target); 551 fadt_info_table[i].address64);
515 address32 = 552 address32 =
516 ACPI_ADD_PTR(u32, &acpi_gbl_FADT, 553 ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
517 fadt_info_table[i].source); 554 fadt_info_table[i].address32);
518 length = 555 length =
519 *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, 556 *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
520 fadt_info_table[i].length); 557 fadt_info_table[i].length);
@@ -522,7 +559,7 @@ static void acpi_tb_validate_fadt(void)
522 559
523 /* 560 /*
524 * For each extended field, check for length mismatch between the 561 * For each extended field, check for length mismatch between the
525 * legacy length field and the corresonding 64-bit X length field. 562 * legacy length field and the corresponding 64-bit X length field.
526 */ 563 */
527 if (address64 && (address64->bit_width != ACPI_MUL_8(length))) { 564 if (address64 && (address64->bit_width != ACPI_MUL_8(length))) {
528 ACPI_WARNING((AE_INFO, 565 ACPI_WARNING((AE_INFO,