diff options
author | Myron Stowe <myron.stowe@hp.com> | 2008-11-04 16:53:00 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-11-06 20:14:41 -0500 |
commit | b26e9286fb438eb78bcdb68b67a3dbb8bc539125 (patch) | |
tree | b3990cdebfa7a11f3a49b9b01de81629e01d36c8 | |
parent | ad93a765c1834db031b5bf1c2baf2a50d0462ca4 (diff) |
ACPI: Behave uniquely based on processor declaration definition type
Associating a Local SAPIC with a processor object is dependent upon the
processor object's definition type. CPUs declared as "Processor" should
use the Local SAPIC's 'processor_id', and CPUs declared as "Device"
should use the 'uid'. Note that for "Processor" declarations, even if a
'_UID' child object exists, it has no bearing with respect to mapping
Local SAPICs (see section 5.2.11.13 - Local SAPIC Structure; "Advanced
Configuration and Power Interface Specification", Revision 3.0b).
This patch changes the lsapic mapping logic to rely on the distinction of
how the processor object was declared - the mapping can't just try both
types of matches regardless of declaration type and rely on one failing
as is currently being done.
Signed-off-by: Myron Stowe <myron.stowe@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/processor_core.c | 78 |
1 files changed, 44 insertions, 34 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 0c670dd297d7..bc332fc28d7f 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -410,7 +410,7 @@ static int acpi_processor_remove_fs(struct acpi_device *device) | |||
410 | /* Use the acpiid in MADT to map cpus in case of SMP */ | 410 | /* Use the acpiid in MADT to map cpus in case of SMP */ |
411 | 411 | ||
412 | #ifndef CONFIG_SMP | 412 | #ifndef CONFIG_SMP |
413 | static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;} | 413 | static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; } |
414 | #else | 414 | #else |
415 | 415 | ||
416 | static struct acpi_table_madt *madt; | 416 | static struct acpi_table_madt *madt; |
@@ -429,27 +429,35 @@ static int map_lapic_id(struct acpi_subtable_header *entry, | |||
429 | } | 429 | } |
430 | 430 | ||
431 | static int map_lsapic_id(struct acpi_subtable_header *entry, | 431 | static int map_lsapic_id(struct acpi_subtable_header *entry, |
432 | u32 acpi_id, int *apic_id) | 432 | int device_declaration, u32 acpi_id, int *apic_id) |
433 | { | 433 | { |
434 | struct acpi_madt_local_sapic *lsapic = | 434 | struct acpi_madt_local_sapic *lsapic = |
435 | (struct acpi_madt_local_sapic *)entry; | 435 | (struct acpi_madt_local_sapic *)entry; |
436 | u32 tmp = (lsapic->id << 8) | lsapic->eid; | ||
437 | |||
436 | /* Only check enabled APICs*/ | 438 | /* Only check enabled APICs*/ |
437 | if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { | 439 | if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) |
438 | /* First check against id */ | 440 | return 0; |
439 | if (lsapic->processor_id == acpi_id) { | 441 | |
440 | *apic_id = (lsapic->id << 8) | lsapic->eid; | 442 | /* Device statement declaration type */ |
441 | return 1; | 443 | if (device_declaration) { |
442 | /* Check against optional uid */ | 444 | if (entry->length < 16) |
443 | } else if (entry->length >= 16 && | 445 | printk(KERN_ERR PREFIX |
444 | lsapic->uid == acpi_id) { | 446 | "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", |
445 | *apic_id = lsapic->uid; | 447 | tmp); |
446 | return 1; | 448 | else if (lsapic->uid == acpi_id) |
447 | } | 449 | goto found; |
448 | } | 450 | /* Processor statement declaration type */ |
451 | } else if (lsapic->processor_id == acpi_id) | ||
452 | goto found; | ||
453 | |||
449 | return 0; | 454 | return 0; |
455 | found: | ||
456 | *apic_id = tmp; | ||
457 | return 1; | ||
450 | } | 458 | } |
451 | 459 | ||
452 | static int map_madt_entry(u32 acpi_id) | 460 | static int map_madt_entry(int type, u32 acpi_id) |
453 | { | 461 | { |
454 | unsigned long madt_end, entry; | 462 | unsigned long madt_end, entry; |
455 | int apic_id = -1; | 463 | int apic_id = -1; |
@@ -470,7 +478,7 @@ static int map_madt_entry(u32 acpi_id) | |||
470 | if (map_lapic_id(header, acpi_id, &apic_id)) | 478 | if (map_lapic_id(header, acpi_id, &apic_id)) |
471 | break; | 479 | break; |
472 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 480 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
473 | if (map_lsapic_id(header, acpi_id, &apic_id)) | 481 | if (map_lsapic_id(header, type, acpi_id, &apic_id)) |
474 | break; | 482 | break; |
475 | } | 483 | } |
476 | entry += header->length; | 484 | entry += header->length; |
@@ -478,7 +486,7 @@ static int map_madt_entry(u32 acpi_id) | |||
478 | return apic_id; | 486 | return apic_id; |
479 | } | 487 | } |
480 | 488 | ||
481 | static int map_mat_entry(acpi_handle handle, u32 acpi_id) | 489 | static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) |
482 | { | 490 | { |
483 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 491 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
484 | union acpi_object *obj; | 492 | union acpi_object *obj; |
@@ -501,7 +509,7 @@ static int map_mat_entry(acpi_handle handle, u32 acpi_id) | |||
501 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { | 509 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { |
502 | map_lapic_id(header, acpi_id, &apic_id); | 510 | map_lapic_id(header, acpi_id, &apic_id); |
503 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 511 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
504 | map_lsapic_id(header, acpi_id, &apic_id); | 512 | map_lsapic_id(header, type, acpi_id, &apic_id); |
505 | } | 513 | } |
506 | 514 | ||
507 | exit: | 515 | exit: |
@@ -510,14 +518,14 @@ exit: | |||
510 | return apic_id; | 518 | return apic_id; |
511 | } | 519 | } |
512 | 520 | ||
513 | static int get_cpu_id(acpi_handle handle, u32 acpi_id) | 521 | static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) |
514 | { | 522 | { |
515 | int i; | 523 | int i; |
516 | int apic_id = -1; | 524 | int apic_id = -1; |
517 | 525 | ||
518 | apic_id = map_mat_entry(handle, acpi_id); | 526 | apic_id = map_mat_entry(handle, type, acpi_id); |
519 | if (apic_id == -1) | 527 | if (apic_id == -1) |
520 | apic_id = map_madt_entry(acpi_id); | 528 | apic_id = map_madt_entry(type, acpi_id); |
521 | if (apic_id == -1) | 529 | if (apic_id == -1) |
522 | return apic_id; | 530 | return apic_id; |
523 | 531 | ||
@@ -533,15 +541,16 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id) | |||
533 | Driver Interface | 541 | Driver Interface |
534 | -------------------------------------------------------------------------- */ | 542 | -------------------------------------------------------------------------- */ |
535 | 543 | ||
536 | static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | 544 | static int acpi_processor_get_info(struct acpi_device *device) |
537 | { | 545 | { |
538 | acpi_status status = 0; | 546 | acpi_status status = 0; |
539 | union acpi_object object = { 0 }; | 547 | union acpi_object object = { 0 }; |
540 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | 548 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; |
541 | int cpu_index; | 549 | struct acpi_processor *pr; |
550 | int cpu_index, device_declaration = 0; | ||
542 | static int cpu0_initialized; | 551 | static int cpu0_initialized; |
543 | 552 | ||
544 | 553 | pr = acpi_driver_data(device); | |
545 | if (!pr) | 554 | if (!pr) |
546 | return -EINVAL; | 555 | return -EINVAL; |
547 | 556 | ||
@@ -562,22 +571,23 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | |||
562 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 571 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
563 | "No bus mastering arbitration control\n")); | 572 | "No bus mastering arbitration control\n")); |
564 | 573 | ||
565 | /* Check if it is a Device with HID and UID */ | 574 | if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) { |
566 | if (has_uid) { | 575 | /* |
576 | * Declared with "Device" statement; match _UID. | ||
577 | * Note that we don't handle string _UIDs yet. | ||
578 | */ | ||
567 | unsigned long long value; | 579 | unsigned long long value; |
568 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, | 580 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, |
569 | NULL, &value); | 581 | NULL, &value); |
570 | if (ACPI_FAILURE(status)) { | 582 | if (ACPI_FAILURE(status)) { |
571 | printk(KERN_ERR PREFIX "Evaluating processor _UID\n"); | 583 | printk(KERN_ERR PREFIX |
584 | "Evaluating processor _UID [%#x]\n", status); | ||
572 | return -ENODEV; | 585 | return -ENODEV; |
573 | } | 586 | } |
587 | device_declaration = 1; | ||
574 | pr->acpi_id = value; | 588 | pr->acpi_id = value; |
575 | } else { | 589 | } else { |
576 | /* | 590 | /* Declared with "Processor" statement; match ProcessorID */ |
577 | * Evalute the processor object. Note that it is common on SMP to | ||
578 | * have the first (boot) processor with a valid PBLK address while | ||
579 | * all others have a NULL address. | ||
580 | */ | ||
581 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | 591 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); |
582 | if (ACPI_FAILURE(status)) { | 592 | if (ACPI_FAILURE(status)) { |
583 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | 593 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); |
@@ -590,7 +600,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | |||
590 | */ | 600 | */ |
591 | pr->acpi_id = object.processor.proc_id; | 601 | pr->acpi_id = object.processor.proc_id; |
592 | } | 602 | } |
593 | cpu_index = get_cpu_id(pr->handle, pr->acpi_id); | 603 | cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); |
594 | 604 | ||
595 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | 605 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ |
596 | if (!cpu0_initialized && (cpu_index == -1) && | 606 | if (!cpu0_initialized && (cpu_index == -1) && |
@@ -662,7 +672,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) | |||
662 | 672 | ||
663 | pr = acpi_driver_data(device); | 673 | pr = acpi_driver_data(device); |
664 | 674 | ||
665 | result = acpi_processor_get_info(pr, device->flags.unique_id); | 675 | result = acpi_processor_get_info(device); |
666 | if (result) { | 676 | if (result) { |
667 | /* Processor is physically not present */ | 677 | /* Processor is physically not present */ |
668 | return 0; | 678 | return 0; |