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