• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdint.h>
2 
3 #include <cpuinfo.h>
4 #include <cpuinfo/log.h>
5 #include <cpuinfo/utils.h>
6 #include <x86/api.h>
7 #include <x86/cpuid.h>
8 
9 union cpuinfo_x86_cache_descriptors {
10 	struct cpuid_regs regs;
11 	uint8_t as_bytes[16];
12 };
13 
14 enum cache_type {
15 	cache_type_none = 0,
16 	cache_type_data = 1,
17 	cache_type_instruction = 2,
18 	cache_type_unified = 3,
19 };
20 
cpuinfo_x86_detect_cache(uint32_t max_base_index,uint32_t max_extended_index,bool amd_topology_extensions,enum cpuinfo_vendor vendor,const struct cpuinfo_x86_model_info * model_info,struct cpuinfo_x86_caches * cache,struct cpuinfo_tlb * itlb_4KB,struct cpuinfo_tlb * itlb_2MB,struct cpuinfo_tlb * itlb_4MB,struct cpuinfo_tlb * dtlb0_4KB,struct cpuinfo_tlb * dtlb0_2MB,struct cpuinfo_tlb * dtlb0_4MB,struct cpuinfo_tlb * dtlb_4KB,struct cpuinfo_tlb * dtlb_2MB,struct cpuinfo_tlb * dtlb_4MB,struct cpuinfo_tlb * dtlb_1GB,struct cpuinfo_tlb * stlb2_4KB,struct cpuinfo_tlb * stlb2_2MB,struct cpuinfo_tlb * stlb2_1GB,uint32_t * log2_package_cores_max)21 void cpuinfo_x86_detect_cache(
22 	uint32_t max_base_index,
23 	uint32_t max_extended_index,
24 	bool amd_topology_extensions,
25 	enum cpuinfo_vendor vendor,
26 	const struct cpuinfo_x86_model_info* model_info,
27 	struct cpuinfo_x86_caches* cache,
28 	struct cpuinfo_tlb* itlb_4KB,
29 	struct cpuinfo_tlb* itlb_2MB,
30 	struct cpuinfo_tlb* itlb_4MB,
31 	struct cpuinfo_tlb* dtlb0_4KB,
32 	struct cpuinfo_tlb* dtlb0_2MB,
33 	struct cpuinfo_tlb* dtlb0_4MB,
34 	struct cpuinfo_tlb* dtlb_4KB,
35 	struct cpuinfo_tlb* dtlb_2MB,
36 	struct cpuinfo_tlb* dtlb_4MB,
37 	struct cpuinfo_tlb* dtlb_1GB,
38 	struct cpuinfo_tlb* stlb2_4KB,
39 	struct cpuinfo_tlb* stlb2_2MB,
40 	struct cpuinfo_tlb* stlb2_1GB,
41 	uint32_t* log2_package_cores_max) {
42 	if (max_base_index >= 2) {
43 		union cpuinfo_x86_cache_descriptors descriptors;
44 		descriptors.regs = cpuid(2);
45 		uint32_t iterations = (uint8_t)descriptors.as_bytes[0];
46 		if (iterations != 0) {
47 		iterate_descriptors:
48 			for (uint32_t i = 1 /* note: not 0 */; i < 16; i++) {
49 				const uint8_t descriptor = descriptors.as_bytes[i];
50 				if (descriptor != 0) {
51 					cpuinfo_x86_decode_cache_descriptor(
52 						descriptor,
53 						vendor,
54 						model_info,
55 						cache,
56 						itlb_4KB,
57 						itlb_2MB,
58 						itlb_4MB,
59 						dtlb0_4KB,
60 						dtlb0_2MB,
61 						dtlb0_4MB,
62 						dtlb_4KB,
63 						dtlb_2MB,
64 						dtlb_4MB,
65 						dtlb_1GB,
66 						stlb2_4KB,
67 						stlb2_2MB,
68 						stlb2_1GB,
69 						&cache->prefetch_size);
70 				}
71 			}
72 			if (--iterations != 0) {
73 				descriptors.regs = cpuid(2);
74 				goto iterate_descriptors;
75 			}
76 		}
77 
78 		if (vendor != cpuinfo_vendor_amd && vendor != cpuinfo_vendor_hygon && max_base_index >= 4) {
79 			struct cpuid_regs leaf4;
80 			uint32_t input_ecx = 0;
81 			uint32_t package_cores_max = 0;
82 			do {
83 				leaf4 = cpuidex(4, input_ecx++);
84 			} while (cpuinfo_x86_decode_deterministic_cache_parameters(leaf4, cache, &package_cores_max));
85 			if (package_cores_max != 0) {
86 				*log2_package_cores_max = bit_length(package_cores_max);
87 			}
88 		}
89 	}
90 	if (amd_topology_extensions && max_extended_index >= UINT32_C(0x8000001D)) {
91 		struct cpuid_regs leaf0x8000001D;
92 		uint32_t input_ecx = 0;
93 		do {
94 			leaf0x8000001D = cpuidex(UINT32_C(0x8000001D), input_ecx++);
95 		} while (cpuinfo_x86_decode_cache_properties(leaf0x8000001D, cache));
96 	}
97 }
98