Commit e927ecb05e1ce4bbb1e10f57008c94994e2160f5
Committed by
Tony Luck
1 parent
6118ec847e
[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>
Showing 6 changed files with 365 additions and 2 deletions Side-by-side Diff
arch/ia64/kernel/setup.c
... | ... | @@ -4,10 +4,15 @@ |
4 | 4 | * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co |
5 | 5 | * David Mosberger-Tang <davidm@hpl.hp.com> |
6 | 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 | 11 | * Copyright (C) 1999 VA Linux Systems |
9 | 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 | 16 | * 11/12/01 D.Mosberger Convert get_cpuinfo() to seq_file based show_cpuinfo(). |
12 | 17 | * 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map |
13 | 18 | * 03/31/00 R.Seth cpu_initialized and current->processor fixes |
... | ... | @@ -296,6 +301,34 @@ |
296 | 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 | 332 | void __init |
300 | 333 | setup_arch (char **cmdline_p) |
301 | 334 | { |
... | ... | @@ -356,6 +389,19 @@ |
356 | 389 | |
357 | 390 | #ifdef CONFIG_SMP |
358 | 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 | 405 | #endif |
360 | 406 | |
361 | 407 | cpu_init(); /* initialize the bootstrap CPU */ |
362 | 408 | |
... | ... | @@ -459,12 +505,23 @@ |
459 | 505 | "cpu regs : %u\n" |
460 | 506 | "cpu MHz : %lu.%06lu\n" |
461 | 507 | "itc MHz : %lu.%06lu\n" |
462 | - "BogoMIPS : %lu.%02lu\n\n", | |
508 | + "BogoMIPS : %lu.%02lu\n", | |
463 | 509 | cpunum, c->vendor, family, c->model, c->revision, c->archrev, |
464 | 510 | features, c->ppn, c->number, |
465 | 511 | c->proc_freq / 1000000, c->proc_freq % 1000000, |
466 | 512 | c->itc_freq / 1000000, c->itc_freq % 1000000, |
467 | 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 | 525 | return 0; |
469 | 526 | } |
470 | 527 | |
... | ... | @@ -533,6 +590,14 @@ |
533 | 590 | memcpy(c->vendor, cpuid.field.vendor, 16); |
534 | 591 | #ifdef CONFIG_SMP |
535 | 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 | 601 | #endif |
537 | 602 | c->ppn = cpuid.field.ppn; |
538 | 603 | c->number = cpuid.field.number; |
arch/ia64/kernel/smpboot.c
... | ... | @@ -3,6 +3,11 @@ |
3 | 3 | * |
4 | 4 | * Copyright (C) 1998-2003, 2005 Hewlett-Packard Co |
5 | 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 | 12 | * 01/05/16 Rohit Seth <rohit.seth@intel.com> Moved SMP booting functions from smp.c to here. |
8 | 13 | * 01/04/27 David Mosberger <davidm@hpl.hp.com> Added ITC synching code. |
... | ... | @@ -10,6 +15,11 @@ |
10 | 15 | * smp_boot_cpus()/smp_commence() is replaced by |
11 | 16 | * smp_prepare_cpus()/__cpu_up()/smp_cpus_done(). |
12 | 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 | 24 | #include <linux/config.h> |
15 | 25 | |
... | ... | @@ -122,6 +132,11 @@ |
122 | 132 | cpumask_t cpu_possible_map; |
123 | 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 | 140 | /* which logical CPU number maps to which CPU (physical APIC ID) */ |
126 | 141 | volatile int ia64_cpu_to_sapicid[NR_CPUS]; |
127 | 142 | EXPORT_SYMBOL(ia64_cpu_to_sapicid); |
128 | 143 | |
... | ... | @@ -598,7 +613,68 @@ |
598 | 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 | 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 | 678 | extern void fixup_irqs(void); |
603 | 679 | /* must be called with cpucontrol mutex held */ |
604 | 680 | int __cpu_disable(void) |
... | ... | @@ -611,6 +687,7 @@ |
611 | 687 | if (cpu == 0) |
612 | 688 | return -EBUSY; |
613 | 689 | |
690 | + remove_siblinginfo(cpu); | |
614 | 691 | fixup_irqs(); |
615 | 692 | local_flush_tlb_all(); |
616 | 693 | cpu_clear(cpu, cpu_callin_map); |
... | ... | @@ -663,6 +740,23 @@ |
663 | 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 | 760 | int __devinit |
667 | 761 | __cpu_up (unsigned int cpu) |
668 | 762 | { |
... | ... | @@ -685,6 +779,15 @@ |
685 | 779 | if (ret < 0) |
686 | 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 | 791 | return 0; |
689 | 792 | } |
690 | 793 | |
... | ... | @@ -710,5 +813,109 @@ |
710 | 813 | if (sal_ret < 0) |
711 | 814 | printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n", |
712 | 815 | ia64_sal_strerror(sal_ret)); |
816 | +} | |
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 | + } | |
713 | 920 | } |
include/asm-ia64/pal.h
... | ... | @@ -67,6 +67,7 @@ |
67 | 67 | #define PAL_REGISTER_INFO 39 /* return AR and CR register information*/ |
68 | 68 | #define PAL_SHUTDOWN 40 /* enter processor shutdown state */ |
69 | 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 | 72 | #define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */ |
72 | 73 | #define PAL_HALT_INFO 257 /* return the low power capabilities of processor */ |
... | ... | @@ -1559,6 +1560,73 @@ |
1559 | 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 | 1630 | #endif /* __ASSEMBLY__ */ |
1563 | 1631 | |
1564 | 1632 | #endif /* _ASM_IA64_PAL_H */ |
include/asm-ia64/processor.h
... | ... | @@ -148,6 +148,13 @@ |
148 | 148 | #ifdef CONFIG_SMP |
149 | 149 | __u64 loops_per_jiffy; |
150 | 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 | 158 | #endif |
152 | 159 | |
153 | 160 | /* CPUID-derived information: */ |
include/asm-ia64/sal.h
... | ... | @@ -91,6 +91,7 @@ |
91 | 91 | #define SAL_PCI_CONFIG_READ 0x01000010 |
92 | 92 | #define SAL_PCI_CONFIG_WRITE 0x01000011 |
93 | 93 | #define SAL_FREQ_BASE 0x01000012 |
94 | +#define SAL_PHYSICAL_ID_INFO 0x01000013 | |
94 | 95 | |
95 | 96 | #define SAL_UPDATE_PAL 0x01000020 |
96 | 97 | |
... | ... | @@ -812,6 +813,17 @@ |
812 | 813 | *error_code = isrv.v0; |
813 | 814 | if (scratch_buf_size_needed) |
814 | 815 | *scratch_buf_size_needed = isrv.v1; |
816 | + return isrv.status; | |
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; | |
815 | 827 | return isrv.status; |
816 | 828 | } |
817 | 829 |
include/asm-ia64/smp.h
... | ... | @@ -56,6 +56,10 @@ |
56 | 56 | extern char no_int_routing __devinitdata; |
57 | 57 | |
58 | 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 | 63 | extern void __iomem *ipi_base_addr; |
60 | 64 | extern unsigned char smp_int_redirect; |
61 | 65 | |
... | ... | @@ -124,6 +128,7 @@ |
124 | 128 | extern void smp_send_reschedule (int cpu); |
125 | 129 | extern void lock_ipi_calllock(void); |
126 | 130 | extern void unlock_ipi_calllock(void); |
131 | +extern void identify_siblings (struct cpuinfo_ia64 *); | |
127 | 132 | |
128 | 133 | #else |
129 | 134 |