~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/kernel/cpu/topology.c

Version: ~ [ linux-5.5-rc6 ] ~ [ linux-5.4.11 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.95 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.164 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.209 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.209 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Check for extended topology enumeration cpuid leaf 0xb and if it
  3  * exists, use it for populating initial_apicid and cpu topology
  4  * detection.
  5  */
  6 
  7 #include <linux/cpu.h>
  8 #include <asm/apic.h>
  9 #include <asm/pat.h>
 10 #include <asm/processor.h>
 11 
 12 /* leaf 0xb SMT level */
 13 #define SMT_LEVEL       0
 14 
 15 /* leaf 0xb sub-leaf types */
 16 #define INVALID_TYPE    0
 17 #define SMT_TYPE        1
 18 #define CORE_TYPE       2
 19 
 20 #define LEAFB_SUBTYPE(ecx)              (((ecx) >> 8) & 0xff)
 21 #define BITS_SHIFT_NEXT_LEVEL(eax)      ((eax) & 0x1f)
 22 #define LEVEL_MAX_SIBLINGS(ebx)         ((ebx) & 0xffff)
 23 
 24 /*
 25  * Check for extended topology enumeration cpuid leaf 0xb and if it
 26  * exists, use it for populating initial_apicid and cpu topology
 27  * detection.
 28  */
 29 void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c)
 30 {
 31 #ifdef CONFIG_SMP
 32         unsigned int eax, ebx, ecx, edx, sub_index;
 33         unsigned int ht_mask_width, core_plus_mask_width;
 34         unsigned int core_select_mask, core_level_siblings;
 35         static bool printed;
 36 
 37         if (c->cpuid_level < 0xb)
 38                 return;
 39 
 40         cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
 41 
 42         /*
 43          * check if the cpuid leaf 0xb is actually implemented.
 44          */
 45         if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE))
 46                 return;
 47 
 48         set_cpu_cap(c, X86_FEATURE_XTOPOLOGY);
 49 
 50         /*
 51          * initial apic id, which also represents 32-bit extended x2apic id.
 52          */
 53         c->initial_apicid = edx;
 54 
 55         /*
 56          * Populate HT related information from sub-leaf level 0.
 57          */
 58         core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
 59         core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
 60 
 61         sub_index = 1;
 62         do {
 63                 cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx);
 64 
 65                 /*
 66                  * Check for the Core type in the implemented sub leaves.
 67                  */
 68                 if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) {
 69                         core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
 70                         core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
 71                         break;
 72                 }
 73 
 74                 sub_index++;
 75         } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE);
 76 
 77         core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width;
 78 
 79         c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, ht_mask_width)
 80                                                  & core_select_mask;
 81         c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, core_plus_mask_width);
 82         /*
 83          * Reinit the apicid, now that we have extended initial_apicid.
 84          */
 85         c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
 86 
 87         c->x86_max_cores = (core_level_siblings / smp_num_siblings);
 88 
 89         if (!printed) {
 90                 printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
 91                        c->phys_proc_id);
 92                 if (c->x86_max_cores > 1)
 93                         printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
 94                                c->cpu_core_id);
 95                 printed = 1;
 96         }
 97         return;
 98 #endif
 99 }
100 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp