aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuresh Siddha <suresh.b.siddha@intel.com>2005-04-25 16:25:06 -0400
committerTony Luck <tony.luck@intel.com>2005-04-25 16:25:06 -0400
commite927ecb05e1ce4bbb1e10f57008c94994e2160f5 (patch)
treebc8256cc074f02d557088696035982fa7ae0b301
parent6118ec847e8e35393efc0f88394c2f5dd48c3313 (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.c69
-rw-r--r--arch/ia64/kernel/smpboot.c206
-rw-r--r--include/asm-ia64/pal.h68
-rw-r--r--include/asm-ia64/processor.h7
-rw-r--r--include/asm-ia64/sal.h12
-rw-r--r--include/asm-ia64/smp.h5
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
305static void
306check_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
299void __init 332void __init
300setup_arch (char **cmdline_p) 333setup_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);
122cpumask_t cpu_possible_map; 132cpumask_t cpu_possible_map;
123EXPORT_SYMBOL(cpu_possible_map); 133EXPORT_SYMBOL(cpu_possible_map);
124 134
135cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
136cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
137int smp_num_siblings = 1;
138int 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) */
126volatile int ia64_cpu_to_sapicid[NR_CPUS]; 141volatile int ia64_cpu_to_sapicid[NR_CPUS];
127EXPORT_SYMBOL(ia64_cpu_to_sapicid); 142EXPORT_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 */
621static 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
630static inline void
631remove_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
641static inline void
642clear_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
654static void
655remove_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
602extern void fixup_irqs(void); 678extern void fixup_irqs(void);
603/* must be called with cpucontrol mutex held */ 679/* must be called with cpucontrol mutex held */
604int __cpu_disable(void) 680int __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
743static inline void __devinit
744set_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
666int __devinit 760int __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
818static inline int __devinit
819check_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 */
835static int __devinit
836check_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 */
856void __devinit
857identify_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 */
1564typedef 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
1579typedef 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
1589typedef 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
1597typedef 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. */
1613static inline s64
1614ia64_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. */
820static inline s64
821ia64_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
818extern unsigned long sal_platform_features; 830extern unsigned long sal_platform_features;
819 831
820extern int (*salinfo_platform_oemdata)(const u8 *, u8 **, u64 *); 832extern 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 {
56extern char no_int_routing __devinitdata; 56extern char no_int_routing __devinitdata;
57 57
58extern cpumask_t cpu_online_map; 58extern cpumask_t cpu_online_map;
59extern cpumask_t cpu_core_map[NR_CPUS];
60extern cpumask_t cpu_sibling_map[NR_CPUS];
61extern int smp_num_siblings;
62extern int smp_num_cpucores;
59extern void __iomem *ipi_base_addr; 63extern void __iomem *ipi_base_addr;
60extern unsigned char smp_int_redirect; 64extern unsigned char smp_int_redirect;
61 65
@@ -124,6 +128,7 @@ extern int smp_call_function_single (int cpuid, void (*func) (void *info), void
124extern void smp_send_reschedule (int cpu); 128extern void smp_send_reschedule (int cpu);
125extern void lock_ipi_calllock(void); 129extern void lock_ipi_calllock(void);
126extern void unlock_ipi_calllock(void); 130extern void unlock_ipi_calllock(void);
131extern void identify_siblings (struct cpuinfo_ia64 *);
127 132
128#else 133#else
129 134