diff options
| author | Suresh Siddha <suresh.b.siddha@intel.com> | 2005-04-25 16:25:06 -0400 |
|---|---|---|
| committer | Tony Luck <tony.luck@intel.com> | 2005-04-25 16:25:06 -0400 |
| commit | e927ecb05e1ce4bbb1e10f57008c94994e2160f5 (patch) | |
| tree | bc8256cc074f02d557088696035982fa7ae0b301 | |
| parent | 6118ec847e8e35393efc0f88394c2f5dd48c3313 (diff) | |
[IA64] multi-core/multi-thread identification
Version 3 - rediffed to apply on top of Ashok's hotplug cpu
patch. /proc/cpuinfo output in step with x86.
This is an updated MC/MT identification patch based on the
previous discussions on list.
Add the Multi-core and Multi-threading detection for IPF.
- Add new core and threading related fields in /proc/cpuinfo.
Physical id
Core id
Thread id
Siblings
- setup the cpu_core_map and cpu_sibling_map appropriately
- Handles Hot plug CPU
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Gordon Jin <gordon.jin@intel.com>
Signed-off-by: Rohit Seth <rohit.seth@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
| -rw-r--r-- | arch/ia64/kernel/setup.c | 69 | ||||
| -rw-r--r-- | arch/ia64/kernel/smpboot.c | 206 | ||||
| -rw-r--r-- | include/asm-ia64/pal.h | 68 | ||||
| -rw-r--r-- | include/asm-ia64/processor.h | 7 | ||||
| -rw-r--r-- | include/asm-ia64/sal.h | 12 | ||||
| -rw-r--r-- | include/asm-ia64/smp.h | 5 |
6 files changed, 365 insertions, 2 deletions
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index f05650c801d2..88043841fb8a 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
| @@ -4,10 +4,15 @@ | |||
| 4 | * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co | 4 | * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co |
| 5 | * David Mosberger-Tang <davidm@hpl.hp.com> | 5 | * David Mosberger-Tang <davidm@hpl.hp.com> |
| 6 | * Stephane Eranian <eranian@hpl.hp.com> | 6 | * Stephane Eranian <eranian@hpl.hp.com> |
| 7 | * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com> | 7 | * Copyright (C) 2000, 2004 Intel Corp |
| 8 | * Rohit Seth <rohit.seth@intel.com> | ||
| 9 | * Suresh Siddha <suresh.b.siddha@intel.com> | ||
| 10 | * Gordon Jin <gordon.jin@intel.com> | ||
| 8 | * Copyright (C) 1999 VA Linux Systems | 11 | * Copyright (C) 1999 VA Linux Systems |
| 9 | * Copyright (C) 1999 Walt Drummond <drummond@valinux.com> | 12 | * Copyright (C) 1999 Walt Drummond <drummond@valinux.com> |
| 10 | * | 13 | * |
| 14 | * 12/26/04 S.Siddha, G.Jin, R.Seth | ||
| 15 | * Add multi-threading and multi-core detection | ||
| 11 | * 11/12/01 D.Mosberger Convert get_cpuinfo() to seq_file based show_cpuinfo(). | 16 | * 11/12/01 D.Mosberger Convert get_cpuinfo() to seq_file based show_cpuinfo(). |
| 12 | * 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map | 17 | * 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map |
| 13 | * 03/31/00 R.Seth cpu_initialized and current->processor fixes | 18 | * 03/31/00 R.Seth cpu_initialized and current->processor fixes |
| @@ -296,6 +301,34 @@ mark_bsp_online (void) | |||
| 296 | #endif | 301 | #endif |
| 297 | } | 302 | } |
| 298 | 303 | ||
| 304 | #ifdef CONFIG_SMP | ||
| 305 | static void | ||
| 306 | check_for_logical_procs (void) | ||
| 307 | { | ||
| 308 | pal_logical_to_physical_t info; | ||
| 309 | s64 status; | ||
| 310 | |||
| 311 | status = ia64_pal_logical_to_phys(0, &info); | ||
| 312 | if (status == -1) { | ||
| 313 | printk(KERN_INFO "No logical to physical processor mapping " | ||
| 314 | "available\n"); | ||
| 315 | return; | ||
| 316 | } | ||
| 317 | if (status) { | ||
| 318 | printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n", | ||
| 319 | status); | ||
| 320 | return; | ||
| 321 | } | ||
| 322 | /* | ||
| 323 | * Total number of siblings that BSP has. Though not all of them | ||
| 324 | * may have booted successfully. The correct number of siblings | ||
| 325 | * booted is in info.overview_num_log. | ||
| 326 | */ | ||
| 327 | smp_num_siblings = info.overview_tpc; | ||
| 328 | smp_num_cpucores = info.overview_cpp; | ||
| 329 | } | ||
| 330 | #endif | ||
| 331 | |||
| 299 | void __init | 332 | void __init |
| 300 | setup_arch (char **cmdline_p) | 333 | setup_arch (char **cmdline_p) |
| 301 | { | 334 | { |
| @@ -356,6 +389,19 @@ setup_arch (char **cmdline_p) | |||
| 356 | 389 | ||
| 357 | #ifdef CONFIG_SMP | 390 | #ifdef CONFIG_SMP |
| 358 | cpu_physical_id(0) = hard_smp_processor_id(); | 391 | cpu_physical_id(0) = hard_smp_processor_id(); |
| 392 | |||
| 393 | cpu_set(0, cpu_sibling_map[0]); | ||
| 394 | cpu_set(0, cpu_core_map[0]); | ||
| 395 | |||
| 396 | check_for_logical_procs(); | ||
| 397 | if (smp_num_cpucores > 1) | ||
| 398 | printk(KERN_INFO | ||
| 399 | "cpu package is Multi-Core capable: number of cores=%d\n", | ||
| 400 | smp_num_cpucores); | ||
| 401 | if (smp_num_siblings > 1) | ||
| 402 | printk(KERN_INFO | ||
| 403 | "cpu package is Multi-Threading capable: number of siblings=%d\n", | ||
| 404 | smp_num_siblings); | ||
| 359 | #endif | 405 | #endif |
| 360 | 406 | ||
| 361 | cpu_init(); /* initialize the bootstrap CPU */ | 407 | cpu_init(); /* initialize the bootstrap CPU */ |
| @@ -459,12 +505,23 @@ show_cpuinfo (struct seq_file *m, void *v) | |||
| 459 | "cpu regs : %u\n" | 505 | "cpu regs : %u\n" |
| 460 | "cpu MHz : %lu.%06lu\n" | 506 | "cpu MHz : %lu.%06lu\n" |
| 461 | "itc MHz : %lu.%06lu\n" | 507 | "itc MHz : %lu.%06lu\n" |
| 462 | "BogoMIPS : %lu.%02lu\n\n", | 508 | "BogoMIPS : %lu.%02lu\n", |
| 463 | cpunum, c->vendor, family, c->model, c->revision, c->archrev, | 509 | cpunum, c->vendor, family, c->model, c->revision, c->archrev, |
| 464 | features, c->ppn, c->number, | 510 | features, c->ppn, c->number, |
| 465 | c->proc_freq / 1000000, c->proc_freq % 1000000, | 511 | c->proc_freq / 1000000, c->proc_freq % 1000000, |
| 466 | c->itc_freq / 1000000, c->itc_freq % 1000000, | 512 | c->itc_freq / 1000000, c->itc_freq % 1000000, |
| 467 | lpj*HZ/500000, (lpj*HZ/5000) % 100); | 513 | lpj*HZ/500000, (lpj*HZ/5000) % 100); |
| 514 | #ifdef CONFIG_SMP | ||
| 515 | if (c->threads_per_core > 1 || c->cores_per_socket > 1) | ||
| 516 | seq_printf(m, | ||
| 517 | "physical id: %u\n" | ||
| 518 | "core id : %u\n" | ||
| 519 | "thread id : %u\n", | ||
| 520 | c->socket_id, c->core_id, c->thread_id); | ||
| 521 | seq_printf(m, "siblings : %u\n", c->num_log); | ||
| 522 | #endif | ||
| 523 | seq_printf(m,"\n"); | ||
| 524 | |||
| 468 | return 0; | 525 | return 0; |
| 469 | } | 526 | } |
| 470 | 527 | ||
| @@ -533,6 +590,14 @@ identify_cpu (struct cpuinfo_ia64 *c) | |||
| 533 | memcpy(c->vendor, cpuid.field.vendor, 16); | 590 | memcpy(c->vendor, cpuid.field.vendor, 16); |
| 534 | #ifdef CONFIG_SMP | 591 | #ifdef CONFIG_SMP |
| 535 | c->cpu = smp_processor_id(); | 592 | c->cpu = smp_processor_id(); |
| 593 | |||
| 594 | /* below default values will be overwritten by identify_siblings() | ||
| 595 | * for Multi-Threading/Multi-Core capable cpu's | ||
| 596 | */ | ||
| 597 | c->threads_per_core = c->cores_per_socket = c->num_log = 1; | ||
| 598 | c->socket_id = -1; | ||
| 599 | |||
| 600 | identify_siblings(c); | ||
| 536 | #endif | 601 | #endif |
| 537 | c->ppn = cpuid.field.ppn; | 602 | c->ppn = cpuid.field.ppn; |
| 538 | c->number = cpuid.field.number; | 603 | c->number = cpuid.field.number; |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index dbc6b610cc64..0d5ee57c9865 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
| @@ -3,6 +3,11 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright (C) 1998-2003, 2005 Hewlett-Packard Co | 4 | * Copyright (C) 1998-2003, 2005 Hewlett-Packard Co |
| 5 | * David Mosberger-Tang <davidm@hpl.hp.com> | 5 | * David Mosberger-Tang <davidm@hpl.hp.com> |
| 6 | * Copyright (C) 2001, 2004-2005 Intel Corp | ||
| 7 | * Rohit Seth <rohit.seth@intel.com> | ||
| 8 | * Suresh Siddha <suresh.b.siddha@intel.com> | ||
| 9 | * Gordon Jin <gordon.jin@intel.com> | ||
| 10 | * Ashok Raj <ashok.raj@intel.com> | ||
| 6 | * | 11 | * |
| 7 | * 01/05/16 Rohit Seth <rohit.seth@intel.com> Moved SMP booting functions from smp.c to here. | 12 | * 01/05/16 Rohit Seth <rohit.seth@intel.com> Moved SMP booting functions from smp.c to here. |
| 8 | * 01/04/27 David Mosberger <davidm@hpl.hp.com> Added ITC synching code. | 13 | * 01/04/27 David Mosberger <davidm@hpl.hp.com> Added ITC synching code. |
| @@ -10,6 +15,11 @@ | |||
| 10 | * smp_boot_cpus()/smp_commence() is replaced by | 15 | * smp_boot_cpus()/smp_commence() is replaced by |
| 11 | * smp_prepare_cpus()/__cpu_up()/smp_cpus_done(). | 16 | * smp_prepare_cpus()/__cpu_up()/smp_cpus_done(). |
| 12 | * 04/06/21 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support | 17 | * 04/06/21 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support |
| 18 | * 04/12/26 Jin Gordon <gordon.jin@intel.com> | ||
| 19 | * 04/12/26 Rohit Seth <rohit.seth@intel.com> | ||
| 20 | * Add multi-threading and multi-core detection | ||
| 21 | * 05/01/30 Suresh Siddha <suresh.b.siddha@intel.com> | ||
| 22 | * Setup cpu_sibling_map and cpu_core_map | ||
| 13 | */ | 23 | */ |
| 14 | #include <linux/config.h> | 24 | #include <linux/config.h> |
| 15 | 25 | ||
| @@ -122,6 +132,11 @@ EXPORT_SYMBOL(cpu_online_map); | |||
| 122 | cpumask_t cpu_possible_map; | 132 | cpumask_t cpu_possible_map; |
| 123 | EXPORT_SYMBOL(cpu_possible_map); | 133 | EXPORT_SYMBOL(cpu_possible_map); |
| 124 | 134 | ||
| 135 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; | ||
| 136 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; | ||
| 137 | int smp_num_siblings = 1; | ||
| 138 | int smp_num_cpucores = 1; | ||
| 139 | |||
| 125 | /* which logical CPU number maps to which CPU (physical APIC ID) */ | 140 | /* which logical CPU number maps to which CPU (physical APIC ID) */ |
| 126 | volatile int ia64_cpu_to_sapicid[NR_CPUS]; | 141 | volatile int ia64_cpu_to_sapicid[NR_CPUS]; |
| 127 | EXPORT_SYMBOL(ia64_cpu_to_sapicid); | 142 | EXPORT_SYMBOL(ia64_cpu_to_sapicid); |
| @@ -598,7 +613,68 @@ void __devinit smp_prepare_boot_cpu(void) | |||
| 598 | cpu_set(smp_processor_id(), cpu_callin_map); | 613 | cpu_set(smp_processor_id(), cpu_callin_map); |
| 599 | } | 614 | } |
| 600 | 615 | ||
| 616 | /* | ||
| 617 | * mt_info[] is a temporary store for all info returned by | ||
| 618 | * PAL_LOGICAL_TO_PHYSICAL, to be copied into cpuinfo_ia64 when the | ||
| 619 | * specific cpu comes. | ||
| 620 | */ | ||
| 621 | static struct { | ||
| 622 | __u32 socket_id; | ||
| 623 | __u16 core_id; | ||
| 624 | __u16 thread_id; | ||
| 625 | __u16 proc_fixed_addr; | ||
| 626 | __u8 valid; | ||
| 627 | }mt_info[NR_CPUS] __devinit; | ||
| 628 | |||
| 601 | #ifdef CONFIG_HOTPLUG_CPU | 629 | #ifdef CONFIG_HOTPLUG_CPU |
| 630 | static inline void | ||
| 631 | remove_from_mtinfo(int cpu) | ||
| 632 | { | ||
| 633 | int i; | ||
| 634 | |||
| 635 | for_each_cpu(i) | ||
| 636 | if (mt_info[i].valid && mt_info[i].socket_id == | ||
| 637 | cpu_data(cpu)->socket_id) | ||
| 638 | mt_info[i].valid = 0; | ||
| 639 | } | ||
| 640 | |||
| 641 | static inline void | ||
| 642 | clear_cpu_sibling_map(int cpu) | ||
| 643 | { | ||
| 644 | int i; | ||
| 645 | |||
| 646 | for_each_cpu_mask(i, cpu_sibling_map[cpu]) | ||
| 647 | cpu_clear(cpu, cpu_sibling_map[i]); | ||
| 648 | for_each_cpu_mask(i, cpu_core_map[cpu]) | ||
| 649 | cpu_clear(cpu, cpu_core_map[i]); | ||
| 650 | |||
| 651 | cpu_sibling_map[cpu] = cpu_core_map[cpu] = CPU_MASK_NONE; | ||
| 652 | } | ||
| 653 | |||
| 654 | static void | ||
| 655 | remove_siblinginfo(int cpu) | ||
| 656 | { | ||
| 657 | int last = 0; | ||
| 658 | |||
| 659 | if (cpu_data(cpu)->threads_per_core == 1 && | ||
| 660 | cpu_data(cpu)->cores_per_socket == 1) { | ||
| 661 | cpu_clear(cpu, cpu_core_map[cpu]); | ||
| 662 | cpu_clear(cpu, cpu_sibling_map[cpu]); | ||
| 663 | return; | ||
| 664 | } | ||
| 665 | |||
| 666 | last = (cpus_weight(cpu_core_map[cpu]) == 1 ? 1 : 0); | ||
| 667 | |||
| 668 | /* remove it from all sibling map's */ | ||
| 669 | clear_cpu_sibling_map(cpu); | ||
| 670 | |||
| 671 | /* if this cpu is the last in the core group, remove all its info | ||
| 672 | * from mt_info structure | ||
| 673 | */ | ||
| 674 | if (last) | ||
| 675 | remove_from_mtinfo(cpu); | ||
| 676 | } | ||
| 677 | |||
| 602 | extern void fixup_irqs(void); | 678 | extern void fixup_irqs(void); |
| 603 | /* must be called with cpucontrol mutex held */ | 679 | /* must be called with cpucontrol mutex held */ |
| 604 | int __cpu_disable(void) | 680 | int __cpu_disable(void) |
| @@ -611,6 +687,7 @@ int __cpu_disable(void) | |||
| 611 | if (cpu == 0) | 687 | if (cpu == 0) |
| 612 | return -EBUSY; | 688 | return -EBUSY; |
| 613 | 689 | ||
| 690 | remove_siblinginfo(cpu); | ||
| 614 | fixup_irqs(); | 691 | fixup_irqs(); |
| 615 | local_flush_tlb_all(); | 692 | local_flush_tlb_all(); |
| 616 | cpu_clear(cpu, cpu_callin_map); | 693 | cpu_clear(cpu, cpu_callin_map); |
| @@ -663,6 +740,23 @@ smp_cpus_done (unsigned int dummy) | |||
| 663 | (int)num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); | 740 | (int)num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); |
| 664 | } | 741 | } |
| 665 | 742 | ||
| 743 | static inline void __devinit | ||
| 744 | set_cpu_sibling_map(int cpu) | ||
| 745 | { | ||
| 746 | int i; | ||
| 747 | |||
| 748 | for_each_online_cpu(i) { | ||
| 749 | if ((cpu_data(cpu)->socket_id == cpu_data(i)->socket_id)) { | ||
| 750 | cpu_set(i, cpu_core_map[cpu]); | ||
| 751 | cpu_set(cpu, cpu_core_map[i]); | ||
| 752 | if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) { | ||
| 753 | cpu_set(i, cpu_sibling_map[cpu]); | ||
| 754 | cpu_set(cpu, cpu_sibling_map[i]); | ||
| 755 | } | ||
| 756 | } | ||
| 757 | } | ||
| 758 | } | ||
| 759 | |||
| 666 | int __devinit | 760 | int __devinit |
| 667 | __cpu_up (unsigned int cpu) | 761 | __cpu_up (unsigned int cpu) |
| 668 | { | 762 | { |
| @@ -685,6 +779,15 @@ __cpu_up (unsigned int cpu) | |||
| 685 | if (ret < 0) | 779 | if (ret < 0) |
| 686 | return ret; | 780 | return ret; |
| 687 | 781 | ||
| 782 | if (cpu_data(cpu)->threads_per_core == 1 && | ||
| 783 | cpu_data(cpu)->cores_per_socket == 1) { | ||
| 784 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
| 785 | cpu_set(cpu, cpu_core_map[cpu]); | ||
| 786 | return 0; | ||
| 787 | } | ||
| 788 | |||
| 789 | set_cpu_sibling_map(cpu); | ||
| 790 | |||
| 688 | return 0; | 791 | return 0; |
| 689 | } | 792 | } |
| 690 | 793 | ||
| @@ -712,3 +815,106 @@ init_smp_config(void) | |||
| 712 | ia64_sal_strerror(sal_ret)); | 815 | ia64_sal_strerror(sal_ret)); |
| 713 | } | 816 | } |
| 714 | 817 | ||
| 818 | static inline int __devinit | ||
| 819 | check_for_mtinfo_index(void) | ||
| 820 | { | ||
| 821 | int i; | ||
| 822 | |||
| 823 | for_each_cpu(i) | ||
| 824 | if (!mt_info[i].valid) | ||
| 825 | return i; | ||
| 826 | |||
| 827 | return -1; | ||
| 828 | } | ||
| 829 | |||
| 830 | /* | ||
| 831 | * Search the mt_info to find out if this socket's cid/tid information is | ||
| 832 | * cached or not. If the socket exists, fill in the core_id and thread_id | ||
| 833 | * in cpuinfo | ||
| 834 | */ | ||
| 835 | static int __devinit | ||
| 836 | check_for_new_socket(__u16 logical_address, struct cpuinfo_ia64 *c) | ||
| 837 | { | ||
| 838 | int i; | ||
| 839 | __u32 sid = c->socket_id; | ||
| 840 | |||
| 841 | for_each_cpu(i) { | ||
| 842 | if (mt_info[i].valid && mt_info[i].proc_fixed_addr == logical_address | ||
| 843 | && mt_info[i].socket_id == sid) { | ||
| 844 | c->core_id = mt_info[i].core_id; | ||
| 845 | c->thread_id = mt_info[i].thread_id; | ||
| 846 | return 1; /* not a new socket */ | ||
| 847 | } | ||
| 848 | } | ||
| 849 | return 0; | ||
| 850 | } | ||
| 851 | |||
| 852 | /* | ||
| 853 | * identify_siblings(cpu) gets called from identify_cpu. This populates the | ||
| 854 | * information related to logical execution units in per_cpu_data structure. | ||
| 855 | */ | ||
| 856 | void __devinit | ||
| 857 | identify_siblings(struct cpuinfo_ia64 *c) | ||
| 858 | { | ||
| 859 | s64 status; | ||
| 860 | u16 pltid; | ||
| 861 | u64 proc_fixed_addr; | ||
| 862 | int count, i; | ||
| 863 | pal_logical_to_physical_t info; | ||
| 864 | |||
| 865 | if (smp_num_cpucores == 1 && smp_num_siblings == 1) | ||
| 866 | return; | ||
| 867 | |||
| 868 | if ((status = ia64_pal_logical_to_phys(0, &info)) != PAL_STATUS_SUCCESS) { | ||
| 869 | printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n", | ||
| 870 | status); | ||
| 871 | return; | ||
| 872 | } | ||
| 873 | if ((status = ia64_sal_physical_id_info(&pltid)) != PAL_STATUS_SUCCESS) { | ||
| 874 | printk(KERN_ERR "ia64_sal_pltid failed with %ld\n", status); | ||
| 875 | return; | ||
| 876 | } | ||
| 877 | if ((status = ia64_pal_fixed_addr(&proc_fixed_addr)) != PAL_STATUS_SUCCESS) { | ||
| 878 | printk(KERN_ERR "ia64_pal_fixed_addr failed with %ld\n", status); | ||
| 879 | return; | ||
| 880 | } | ||
| 881 | |||
| 882 | c->socket_id = (pltid << 8) | info.overview_ppid; | ||
| 883 | c->cores_per_socket = info.overview_cpp; | ||
| 884 | c->threads_per_core = info.overview_tpc; | ||
| 885 | count = c->num_log = info.overview_num_log; | ||
| 886 | |||
| 887 | /* If the thread and core id information is already cached, then | ||
| 888 | * we will simply update cpu_info and return. Otherwise, we will | ||
| 889 | * do the PAL calls and cache core and thread id's of all the siblings. | ||
| 890 | */ | ||
| 891 | if (check_for_new_socket(proc_fixed_addr, c)) | ||
| 892 | return; | ||
| 893 | |||
| 894 | for (i = 0; i < count; i++) { | ||
| 895 | int index; | ||
| 896 | |||
| 897 | if (i && (status = ia64_pal_logical_to_phys(i, &info)) | ||
| 898 | != PAL_STATUS_SUCCESS) { | ||
| 899 | printk(KERN_ERR "ia64_pal_logical_to_phys failed" | ||
| 900 | " with %ld\n", status); | ||
| 901 | return; | ||
| 902 | } | ||
| 903 | if (info.log2_la == proc_fixed_addr) { | ||
| 904 | c->core_id = info.log1_cid; | ||
| 905 | c->thread_id = info.log1_tid; | ||
| 906 | } | ||
| 907 | |||
| 908 | index = check_for_mtinfo_index(); | ||
| 909 | /* We will not do the mt_info caching optimization in this case. | ||
| 910 | */ | ||
| 911 | if (index < 0) | ||
| 912 | continue; | ||
| 913 | |||
| 914 | mt_info[index].valid = 1; | ||
| 915 | mt_info[index].socket_id = c->socket_id; | ||
| 916 | mt_info[index].core_id = info.log1_cid; | ||
| 917 | mt_info[index].thread_id = info.log1_tid; | ||
| 918 | mt_info[index].proc_fixed_addr = info.log2_la; | ||
| 919 | } | ||
| 920 | } | ||
diff --git a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h index 5dd477ffb88e..2303a10ee595 100644 --- a/include/asm-ia64/pal.h +++ b/include/asm-ia64/pal.h | |||
| @@ -67,6 +67,7 @@ | |||
| 67 | #define PAL_REGISTER_INFO 39 /* return AR and CR register information*/ | 67 | #define PAL_REGISTER_INFO 39 /* return AR and CR register information*/ |
| 68 | #define PAL_SHUTDOWN 40 /* enter processor shutdown state */ | 68 | #define PAL_SHUTDOWN 40 /* enter processor shutdown state */ |
| 69 | #define PAL_PREFETCH_VISIBILITY 41 /* Make Processor Prefetches Visible */ | 69 | #define PAL_PREFETCH_VISIBILITY 41 /* Make Processor Prefetches Visible */ |
| 70 | #define PAL_LOGICAL_TO_PHYSICAL 42 /* returns information on logical to physical processor mapping */ | ||
| 70 | 71 | ||
| 71 | #define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */ | 72 | #define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */ |
| 72 | #define PAL_HALT_INFO 257 /* return the low power capabilities of processor */ | 73 | #define PAL_HALT_INFO 257 /* return the low power capabilities of processor */ |
| @@ -1559,6 +1560,73 @@ ia64_pal_prefetch_visibility (s64 trans_type) | |||
| 1559 | return iprv.status; | 1560 | return iprv.status; |
| 1560 | } | 1561 | } |
| 1561 | 1562 | ||
| 1563 | /* data structure for getting information on logical to physical mappings */ | ||
| 1564 | typedef union pal_log_overview_u { | ||
| 1565 | struct { | ||
| 1566 | u64 num_log :16, /* Total number of logical | ||
| 1567 | * processors on this die | ||
| 1568 | */ | ||
| 1569 | tpc :8, /* Threads per core */ | ||
| 1570 | reserved3 :8, /* Reserved */ | ||
| 1571 | cpp :8, /* Cores per processor */ | ||
| 1572 | reserved2 :8, /* Reserved */ | ||
| 1573 | ppid :8, /* Physical processor ID */ | ||
| 1574 | reserved1 :8; /* Reserved */ | ||
| 1575 | } overview_bits; | ||
| 1576 | u64 overview_data; | ||
| 1577 | } pal_log_overview_t; | ||
| 1578 | |||
| 1579 | typedef union pal_proc_n_log_info1_u{ | ||
| 1580 | struct { | ||
| 1581 | u64 tid :16, /* Thread id */ | ||
| 1582 | reserved2 :16, /* Reserved */ | ||
| 1583 | cid :16, /* Core id */ | ||
| 1584 | reserved1 :16; /* Reserved */ | ||
| 1585 | } ppli1_bits; | ||
| 1586 | u64 ppli1_data; | ||
| 1587 | } pal_proc_n_log_info1_t; | ||
| 1588 | |||
| 1589 | typedef union pal_proc_n_log_info2_u { | ||
| 1590 | struct { | ||
| 1591 | u64 la :16, /* Logical address */ | ||
| 1592 | reserved :48; /* Reserved */ | ||
| 1593 | } ppli2_bits; | ||
| 1594 | u64 ppli2_data; | ||
| 1595 | } pal_proc_n_log_info2_t; | ||
| 1596 | |||
| 1597 | typedef struct pal_logical_to_physical_s | ||
| 1598 | { | ||
| 1599 | pal_log_overview_t overview; | ||
| 1600 | pal_proc_n_log_info1_t ppli1; | ||
| 1601 | pal_proc_n_log_info2_t ppli2; | ||
| 1602 | } pal_logical_to_physical_t; | ||
| 1603 | |||
| 1604 | #define overview_num_log overview.overview_bits.num_log | ||
| 1605 | #define overview_tpc overview.overview_bits.tpc | ||
| 1606 | #define overview_cpp overview.overview_bits.cpp | ||
| 1607 | #define overview_ppid overview.overview_bits.ppid | ||
| 1608 | #define log1_tid ppli1.ppli1_bits.tid | ||
| 1609 | #define log1_cid ppli1.ppli1_bits.cid | ||
| 1610 | #define log2_la ppli2.ppli2_bits.la | ||
| 1611 | |||
| 1612 | /* Get information on logical to physical processor mappings. */ | ||
| 1613 | static inline s64 | ||
| 1614 | ia64_pal_logical_to_phys(u64 proc_number, pal_logical_to_physical_t *mapping) | ||
| 1615 | { | ||
| 1616 | struct ia64_pal_retval iprv; | ||
| 1617 | |||
| 1618 | PAL_CALL(iprv, PAL_LOGICAL_TO_PHYSICAL, proc_number, 0, 0); | ||
| 1619 | |||
| 1620 | if (iprv.status == PAL_STATUS_SUCCESS) | ||
| 1621 | { | ||
| 1622 | if (proc_number == 0) | ||
| 1623 | mapping->overview.overview_data = iprv.v0; | ||
| 1624 | mapping->ppli1.ppli1_data = iprv.v1; | ||
| 1625 | mapping->ppli2.ppli2_data = iprv.v2; | ||
| 1626 | } | ||
| 1627 | |||
| 1628 | return iprv.status; | ||
| 1629 | } | ||
| 1562 | #endif /* __ASSEMBLY__ */ | 1630 | #endif /* __ASSEMBLY__ */ |
| 1563 | 1631 | ||
| 1564 | #endif /* _ASM_IA64_PAL_H */ | 1632 | #endif /* _ASM_IA64_PAL_H */ |
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 983798ec1791..9e1ba8b7fb68 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h | |||
| @@ -148,6 +148,13 @@ struct cpuinfo_ia64 { | |||
| 148 | #ifdef CONFIG_SMP | 148 | #ifdef CONFIG_SMP |
| 149 | __u64 loops_per_jiffy; | 149 | __u64 loops_per_jiffy; |
| 150 | int cpu; | 150 | int cpu; |
| 151 | __u32 socket_id; /* physical processor socket id */ | ||
| 152 | __u16 core_id; /* core id */ | ||
| 153 | __u16 thread_id; /* thread id */ | ||
| 154 | __u16 num_log; /* Total number of logical processors on | ||
| 155 | * this socket that were successfully booted */ | ||
| 156 | __u8 cores_per_socket; /* Cores per processor socket */ | ||
| 157 | __u8 threads_per_core; /* Threads per core */ | ||
| 151 | #endif | 158 | #endif |
| 152 | 159 | ||
| 153 | /* CPUID-derived information: */ | 160 | /* CPUID-derived information: */ |
diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h index 240676f75390..29df88bdd2bc 100644 --- a/include/asm-ia64/sal.h +++ b/include/asm-ia64/sal.h | |||
| @@ -91,6 +91,7 @@ extern spinlock_t sal_lock; | |||
| 91 | #define SAL_PCI_CONFIG_READ 0x01000010 | 91 | #define SAL_PCI_CONFIG_READ 0x01000010 |
| 92 | #define SAL_PCI_CONFIG_WRITE 0x01000011 | 92 | #define SAL_PCI_CONFIG_WRITE 0x01000011 |
| 93 | #define SAL_FREQ_BASE 0x01000012 | 93 | #define SAL_FREQ_BASE 0x01000012 |
| 94 | #define SAL_PHYSICAL_ID_INFO 0x01000013 | ||
| 94 | 95 | ||
| 95 | #define SAL_UPDATE_PAL 0x01000020 | 96 | #define SAL_UPDATE_PAL 0x01000020 |
| 96 | 97 | ||
| @@ -815,6 +816,17 @@ ia64_sal_update_pal (u64 param_buf, u64 scratch_buf, u64 scratch_buf_size, | |||
| 815 | return isrv.status; | 816 | return isrv.status; |
| 816 | } | 817 | } |
| 817 | 818 | ||
| 819 | /* Get physical processor die mapping in the platform. */ | ||
| 820 | static inline s64 | ||
| 821 | ia64_sal_physical_id_info(u16 *splid) | ||
| 822 | { | ||
| 823 | struct ia64_sal_retval isrv; | ||
| 824 | SAL_CALL(isrv, SAL_PHYSICAL_ID_INFO, 0, 0, 0, 0, 0, 0, 0); | ||
| 825 | if (splid) | ||
| 826 | *splid = isrv.v0; | ||
| 827 | return isrv.status; | ||
| 828 | } | ||
| 829 | |||
| 818 | extern unsigned long sal_platform_features; | 830 | extern unsigned long sal_platform_features; |
| 819 | 831 | ||
| 820 | extern int (*salinfo_platform_oemdata)(const u8 *, u8 **, u64 *); | 832 | extern int (*salinfo_platform_oemdata)(const u8 *, u8 **, u64 *); |
diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h index c4a227acfeb0..3ba1a061e4ae 100644 --- a/include/asm-ia64/smp.h +++ b/include/asm-ia64/smp.h | |||
| @@ -56,6 +56,10 @@ extern struct smp_boot_data { | |||
| 56 | extern char no_int_routing __devinitdata; | 56 | extern char no_int_routing __devinitdata; |
| 57 | 57 | ||
| 58 | extern cpumask_t cpu_online_map; | 58 | extern cpumask_t cpu_online_map; |
| 59 | extern cpumask_t cpu_core_map[NR_CPUS]; | ||
| 60 | extern cpumask_t cpu_sibling_map[NR_CPUS]; | ||
| 61 | extern int smp_num_siblings; | ||
| 62 | extern int smp_num_cpucores; | ||
| 59 | extern void __iomem *ipi_base_addr; | 63 | extern void __iomem *ipi_base_addr; |
| 60 | extern unsigned char smp_int_redirect; | 64 | extern unsigned char smp_int_redirect; |
| 61 | 65 | ||
| @@ -124,6 +128,7 @@ extern int smp_call_function_single (int cpuid, void (*func) (void *info), void | |||
| 124 | extern void smp_send_reschedule (int cpu); | 128 | extern void smp_send_reschedule (int cpu); |
| 125 | extern void lock_ipi_calllock(void); | 129 | extern void lock_ipi_calllock(void); |
| 126 | extern void unlock_ipi_calllock(void); | 130 | extern void unlock_ipi_calllock(void); |
| 131 | extern void identify_siblings (struct cpuinfo_ia64 *); | ||
| 127 | 132 | ||
| 128 | #else | 133 | #else |
| 129 | 134 | ||
