• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdint.h>
2 #include <string.h>
3 
4 #include <cpuinfo.h>
5 #include <cpuinfo/common.h>
6 #include <cpuinfo/log.h>
7 #include <cpuinfo/utils.h>
8 #include <x86/api.h>
9 #include <x86/cpuid.h>
10 
11 struct cpuinfo_x86_isa cpuinfo_isa = {0};
12 CPUINFO_INTERNAL uint32_t cpuinfo_x86_clflush_size = 0;
13 
cpuinfo_x86_init_processor(struct cpuinfo_x86_processor * processor)14 void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor) {
15 	const struct cpuid_regs leaf0 = cpuid(0);
16 	const uint32_t max_base_index = leaf0.eax;
17 	const enum cpuinfo_vendor vendor = processor->vendor =
18 		cpuinfo_x86_decode_vendor(leaf0.ebx, leaf0.ecx, leaf0.edx);
19 
20 	const struct cpuid_regs leaf0x80000000 = cpuid(UINT32_C(0x80000000));
21 	const uint32_t max_extended_index = leaf0x80000000.eax >= UINT32_C(0x80000000) ? leaf0x80000000.eax : 0;
22 
23 	const struct cpuid_regs leaf0x80000001 = max_extended_index >= UINT32_C(0x80000001)
24 		? cpuid(UINT32_C(0x80000001))
25 		: (struct cpuid_regs){0, 0, 0, 0};
26 
27 	if (max_base_index >= 1) {
28 		const struct cpuid_regs leaf1 = cpuid(1);
29 		processor->cpuid = leaf1.eax;
30 
31 		const struct cpuinfo_x86_model_info model_info = cpuinfo_x86_decode_model_info(leaf1.eax);
32 		const enum cpuinfo_uarch uarch = processor->uarch = cpuinfo_x86_decode_uarch(vendor, &model_info);
33 
34 		cpuinfo_x86_clflush_size = ((leaf1.ebx >> 8) & UINT32_C(0x000000FF)) * 8;
35 
36 		/*
37 		 * Topology extensions support:
38 		 * - AMD: ecx[bit 22] in extended info (reserved bit on Intel
39 		 * CPUs).
40 		 */
41 		const bool amd_topology_extensions = !!(leaf0x80000001.ecx & UINT32_C(0x00400000));
42 
43 		cpuinfo_x86_detect_cache(
44 			max_base_index,
45 			max_extended_index,
46 			amd_topology_extensions,
47 			vendor,
48 			&model_info,
49 			&processor->cache,
50 			&processor->tlb.itlb_4KB,
51 			&processor->tlb.itlb_2MB,
52 			&processor->tlb.itlb_4MB,
53 			&processor->tlb.dtlb0_4KB,
54 			&processor->tlb.dtlb0_2MB,
55 			&processor->tlb.dtlb0_4MB,
56 			&processor->tlb.dtlb_4KB,
57 			&processor->tlb.dtlb_2MB,
58 			&processor->tlb.dtlb_4MB,
59 			&processor->tlb.dtlb_1GB,
60 			&processor->tlb.stlb2_4KB,
61 			&processor->tlb.stlb2_2MB,
62 			&processor->tlb.stlb2_1GB,
63 			&processor->topology.core_bits_length);
64 
65 		cpuinfo_x86_detect_topology(max_base_index, max_extended_index, leaf1, &processor->topology);
66 
67 		cpuinfo_isa = cpuinfo_x86_detect_isa(
68 			leaf1, leaf0x80000001, max_base_index, max_extended_index, vendor, uarch);
69 	}
70 	if (max_extended_index >= UINT32_C(0x80000004)) {
71 		struct cpuid_regs brand_string[3];
72 		for (uint32_t i = 0; i < 3; i++) {
73 			brand_string[i] = cpuid(UINT32_C(0x80000002) + i);
74 		}
75 		memcpy(processor->brand_string, brand_string, sizeof(processor->brand_string));
76 		cpuinfo_log_debug("raw CPUID brand string: \"%48s\"", processor->brand_string);
77 	}
78 }
79