0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/io.h>
0010
0011 #include <asm/cpu.h>
0012 #include <asm/smp.h>
0013 #include <asm/numa.h>
0014 #include <asm/cacheinfo.h>
0015 #include <asm/spec-ctrl.h>
0016 #include <asm/delay.h>
0017
0018 #include "cpu.h"
0019
0020 #define APICID_SOCKET_ID_BIT 6
0021
0022
0023
0024
0025
0026 static u32 nodes_per_socket = 1;
0027
0028 #ifdef CONFIG_NUMA
0029
0030
0031
0032
0033 static int nearby_node(int apicid)
0034 {
0035 int i, node;
0036
0037 for (i = apicid - 1; i >= 0; i--) {
0038 node = __apicid_to_node[i];
0039 if (node != NUMA_NO_NODE && node_online(node))
0040 return node;
0041 }
0042 for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
0043 node = __apicid_to_node[i];
0044 if (node != NUMA_NO_NODE && node_online(node))
0045 return node;
0046 }
0047 return first_node(node_online_map);
0048 }
0049 #endif
0050
0051 static void hygon_get_topology_early(struct cpuinfo_x86 *c)
0052 {
0053 if (cpu_has(c, X86_FEATURE_TOPOEXT))
0054 smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1;
0055 }
0056
0057
0058
0059
0060
0061
0062
0063 static void hygon_get_topology(struct cpuinfo_x86 *c)
0064 {
0065 int cpu = smp_processor_id();
0066
0067
0068 if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
0069 int err;
0070 u32 eax, ebx, ecx, edx;
0071
0072 cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
0073
0074 c->cpu_die_id = ecx & 0xff;
0075
0076 c->cpu_core_id = ebx & 0xff;
0077
0078 if (smp_num_siblings > 1)
0079 c->x86_max_cores /= smp_num_siblings;
0080
0081
0082
0083
0084
0085 err = detect_extended_topology(c);
0086 if (!err)
0087 c->x86_coreid_bits = get_count_order(c->x86_max_cores);
0088
0089
0090 c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT;
0091
0092 cacheinfo_hygon_init_llc_id(c, cpu);
0093 } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
0094 u64 value;
0095
0096 rdmsrl(MSR_FAM10H_NODE_ID, value);
0097 c->cpu_die_id = value & 7;
0098
0099 per_cpu(cpu_llc_id, cpu) = c->cpu_die_id;
0100 } else
0101 return;
0102
0103 if (nodes_per_socket > 1)
0104 set_cpu_cap(c, X86_FEATURE_AMD_DCM);
0105 }
0106
0107
0108
0109
0110
0111 static void hygon_detect_cmp(struct cpuinfo_x86 *c)
0112 {
0113 unsigned int bits;
0114 int cpu = smp_processor_id();
0115
0116 bits = c->x86_coreid_bits;
0117
0118 c->cpu_core_id = c->initial_apicid & ((1 << bits)-1);
0119
0120 c->phys_proc_id = c->initial_apicid >> bits;
0121
0122 per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
0123 }
0124
0125 static void srat_detect_node(struct cpuinfo_x86 *c)
0126 {
0127 #ifdef CONFIG_NUMA
0128 int cpu = smp_processor_id();
0129 int node;
0130 unsigned int apicid = c->apicid;
0131
0132 node = numa_cpu_node(cpu);
0133 if (node == NUMA_NO_NODE)
0134 node = per_cpu(cpu_llc_id, cpu);
0135
0136
0137
0138
0139
0140
0141 if (x86_cpuinit.fixup_cpu_id)
0142 x86_cpuinit.fixup_cpu_id(c, node);
0143
0144 if (!node_online(node)) {
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 int ht_nodeid = c->initial_apicid;
0164
0165 if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
0166 node = __apicid_to_node[ht_nodeid];
0167
0168 if (!node_online(node))
0169 node = nearby_node(apicid);
0170 }
0171 numa_set_node(cpu, node);
0172 #endif
0173 }
0174
0175 static void early_init_hygon_mc(struct cpuinfo_x86 *c)
0176 {
0177 #ifdef CONFIG_SMP
0178 unsigned int bits, ecx;
0179
0180
0181 if (c->extended_cpuid_level < 0x80000008)
0182 return;
0183
0184 ecx = cpuid_ecx(0x80000008);
0185
0186 c->x86_max_cores = (ecx & 0xff) + 1;
0187
0188
0189 bits = (ecx >> 12) & 0xF;
0190
0191
0192 if (bits == 0) {
0193 while ((1 << bits) < c->x86_max_cores)
0194 bits++;
0195 }
0196
0197 c->x86_coreid_bits = bits;
0198 #endif
0199 }
0200
0201 static void bsp_init_hygon(struct cpuinfo_x86 *c)
0202 {
0203 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
0204 u64 val;
0205
0206 rdmsrl(MSR_K7_HWCR, val);
0207 if (!(val & BIT(24)))
0208 pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n");
0209 }
0210
0211 if (cpu_has(c, X86_FEATURE_MWAITX))
0212 use_mwaitx_delay();
0213
0214 if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
0215 u32 ecx;
0216
0217 ecx = cpuid_ecx(0x8000001e);
0218 __max_die_per_package = nodes_per_socket = ((ecx >> 8) & 7) + 1;
0219 } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) {
0220 u64 value;
0221
0222 rdmsrl(MSR_FAM10H_NODE_ID, value);
0223 __max_die_per_package = nodes_per_socket = ((value >> 3) & 7) + 1;
0224 }
0225
0226 if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) &&
0227 !boot_cpu_has(X86_FEATURE_VIRT_SSBD)) {
0228
0229
0230
0231
0232 if (!rdmsrl_safe(MSR_AMD64_LS_CFG, &x86_amd_ls_cfg_base)) {
0233 setup_force_cpu_cap(X86_FEATURE_LS_CFG_SSBD);
0234 setup_force_cpu_cap(X86_FEATURE_SSBD);
0235 x86_amd_ls_cfg_ssbd_mask = 1ULL << 10;
0236 }
0237 }
0238 }
0239
0240 static void early_init_hygon(struct cpuinfo_x86 *c)
0241 {
0242 u32 dummy;
0243
0244 early_init_hygon_mc(c);
0245
0246 set_cpu_cap(c, X86_FEATURE_K8);
0247
0248 rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
0249
0250
0251
0252
0253
0254 if (c->x86_power & (1 << 8)) {
0255 set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
0256 set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
0257 }
0258
0259
0260 if (c->x86_power & BIT(12))
0261 set_cpu_cap(c, X86_FEATURE_ACC_POWER);
0262
0263
0264 if (c->x86_power & BIT(14))
0265 set_cpu_cap(c, X86_FEATURE_RAPL);
0266
0267 #ifdef CONFIG_X86_64
0268 set_cpu_cap(c, X86_FEATURE_SYSCALL32);
0269 #endif
0270
0271 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
0272
0273
0274
0275
0276 if (boot_cpu_has(X86_FEATURE_APIC))
0277 set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
0278 #endif
0279
0280
0281
0282
0283
0284
0285 set_cpu_cap(c, X86_FEATURE_VMMCALL);
0286
0287 hygon_get_topology_early(c);
0288 }
0289
0290 static void init_hygon(struct cpuinfo_x86 *c)
0291 {
0292 early_init_hygon(c);
0293
0294
0295
0296
0297
0298 clear_cpu_cap(c, 0*32+31);
0299
0300 set_cpu_cap(c, X86_FEATURE_REP_GOOD);
0301
0302
0303 c->apicid = hard_smp_processor_id();
0304
0305
0306
0307
0308
0309
0310
0311 set_cpu_cap(c, X86_FEATURE_ZEN);
0312 set_cpu_cap(c, X86_FEATURE_CPB);
0313
0314 cpu_detect_cache_sizes(c);
0315
0316 hygon_detect_cmp(c);
0317 hygon_get_topology(c);
0318 srat_detect_node(c);
0319
0320 init_hygon_cacheinfo(c);
0321
0322 if (cpu_has(c, X86_FEATURE_XMM2)) {
0323
0324
0325
0326
0327
0328
0329 msr_set_bit(MSR_F10H_DECFG,
0330 MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
0331
0332
0333 set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
0334 }
0335
0336
0337
0338
0339 set_cpu_cap(c, X86_FEATURE_ARAT);
0340
0341
0342 if (!cpu_has(c, X86_FEATURE_XENPV))
0343 set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
0344
0345 check_null_seg_clears_base(c);
0346 }
0347
0348 static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c)
0349 {
0350 u32 ebx, eax, ecx, edx;
0351 u16 mask = 0xfff;
0352
0353 if (c->extended_cpuid_level < 0x80000006)
0354 return;
0355
0356 cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
0357
0358 tlb_lld_4k[ENTRIES] = (ebx >> 16) & mask;
0359 tlb_lli_4k[ENTRIES] = ebx & mask;
0360
0361
0362 if (!((eax >> 16) & mask))
0363 tlb_lld_2m[ENTRIES] = (cpuid_eax(0x80000005) >> 16) & 0xff;
0364 else
0365 tlb_lld_2m[ENTRIES] = (eax >> 16) & mask;
0366
0367
0368 tlb_lld_4m[ENTRIES] = tlb_lld_2m[ENTRIES] >> 1;
0369
0370
0371 if (!(eax & mask)) {
0372 cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
0373 tlb_lli_2m[ENTRIES] = eax & 0xff;
0374 } else
0375 tlb_lli_2m[ENTRIES] = eax & mask;
0376
0377 tlb_lli_4m[ENTRIES] = tlb_lli_2m[ENTRIES] >> 1;
0378 }
0379
0380 static const struct cpu_dev hygon_cpu_dev = {
0381 .c_vendor = "Hygon",
0382 .c_ident = { "HygonGenuine" },
0383 .c_early_init = early_init_hygon,
0384 .c_detect_tlb = cpu_detect_tlb_hygon,
0385 .c_bsp_init = bsp_init_hygon,
0386 .c_init = init_hygon,
0387 .c_x86_vendor = X86_VENDOR_HYGON,
0388 };
0389
0390 cpu_dev_register(hygon_cpu_dev);