mb/google/skyrim: Enable Chrome EC
[coreboot.git] / src / arch / x86 / cpu_common.c
blob302a14e6d2b2b94f2e94df0b8b8be6f0c99d7c39
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <cpu/cpu.h>
5 #if ENV_X86_32
6 /* Standard macro to see if a specific flag is changeable */
7 static inline int flag_is_changeable_p(uint32_t flag)
9 uint32_t f1, f2;
11 asm(
12 "pushfl\n\t"
13 "pushfl\n\t"
14 "popl %0\n\t"
15 "movl %0,%1\n\t"
16 "xorl %2,%0\n\t"
17 "pushl %0\n\t"
18 "popfl\n\t"
19 "pushfl\n\t"
20 "popl %0\n\t"
21 "popfl\n\t"
22 : "=&r" (f1), "=&r" (f2)
23 : "ir" (flag));
24 return ((f1^f2) & flag) != 0;
27 /* Probe for the CPUID instruction */
28 int cpu_have_cpuid(void)
30 return flag_is_changeable_p(X86_EFLAGS_ID);
33 #else
35 int cpu_have_cpuid(void)
37 return 1;
39 #endif
41 unsigned int cpu_cpuid_extended_level(void)
43 return cpuid_eax(0x80000000);
46 int cpu_phys_address_size(void)
48 if (!(cpu_have_cpuid()))
49 return 32;
51 if (cpu_cpuid_extended_level() >= 0x80000008)
52 return cpuid_eax(0x80000008) & 0xff;
54 if (cpuid_edx(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36))
55 return 36;
56 return 32;
60 * Get processor id using cpuid eax=1
61 * return value in EAX register
63 uint32_t cpu_get_cpuid(void)
65 return cpuid_eax(1);
69 * Get processor feature flag using cpuid eax=1
70 * return value in ECX register
72 uint32_t cpu_get_feature_flags_ecx(void)
74 return cpuid_ecx(1);
78 * Get processor feature flag using cpuid eax=1
79 * return value in EDX register
81 uint32_t cpu_get_feature_flags_edx(void)
83 return cpuid_edx(1);
86 enum cpu_type cpu_check_deterministic_cache_cpuid_supported(void)
88 struct cpuid_result res;
90 if (cpu_is_intel()) {
91 res = cpuid(0);
92 if (res.eax < 4)
93 return CPUID_COMMAND_UNSUPPORTED;
94 return CPUID_TYPE_INTEL;
95 } else if (cpu_is_amd()) {
96 res = cpuid(0x80000000);
97 if (res.eax < 0x80000001)
98 return CPUID_COMMAND_UNSUPPORTED;
100 res = cpuid(0x80000001);
101 if (!(res.ecx & (1 << 22)))
102 return CPUID_COMMAND_UNSUPPORTED;
104 return CPUID_TYPE_AMD;
105 } else {
106 return CPUID_TYPE_INVALID;
110 static uint32_t cpu_get_cache_info_leaf(void)
112 uint32_t leaf = (cpu_check_deterministic_cache_cpuid_supported() == CPUID_TYPE_AMD) ?
113 DETERMINISTIC_CACHE_PARAMETERS_CPUID_AMD :
114 DETERMINISTIC_CACHE_PARAMETERS_CPUID_IA;
116 return leaf;
119 size_t cpu_get_cache_ways_assoc_info(const struct cpu_cache_info *info)
121 if (!info)
122 return 0;
124 return info->num_ways;
127 uint8_t cpu_get_cache_type(const struct cpu_cache_info *info)
129 if (!info)
130 return 0;
132 return info->type;
135 uint8_t cpu_get_cache_level(const struct cpu_cache_info *info)
137 if (!info)
138 return 0;
140 return info->level;
143 size_t cpu_get_cache_phy_partition_info(const struct cpu_cache_info *info)
145 if (!info)
146 return 0;
148 return info->physical_partitions;
151 size_t cpu_get_cache_line_size(const struct cpu_cache_info *info)
153 if (!info)
154 return 0;
156 return info->line_size;
159 size_t cpu_get_cache_sets(const struct cpu_cache_info *info)
161 if (!info)
162 return 0;
164 return info->num_sets;
167 bool cpu_is_cache_full_assoc(const struct cpu_cache_info *info)
169 if (!info)
170 return false;
172 return info->fully_associative;
175 size_t cpu_get_max_cache_share(const struct cpu_cache_info *info)
177 if (!info)
178 return 0;
180 return info->num_cores_shared;
183 size_t get_cache_size(const struct cpu_cache_info *info)
185 if (!info)
186 return 0;
188 return info->num_ways * info->physical_partitions * info->line_size * info->num_sets;
191 bool fill_cpu_cache_info(uint8_t level, struct cpu_cache_info *info)
193 if (!info)
194 return false;
196 uint32_t leaf = cpu_get_cache_info_leaf();
197 if (!leaf)
198 return false;
200 struct cpuid_result cache_info_res = cpuid_ext(leaf, level);
202 info->type = CPUID_CACHE_TYPE(cache_info_res);
203 info->level = CPUID_CACHE_LEVEL(cache_info_res);
204 info->num_ways = CPUID_CACHE_WAYS_OF_ASSOC(cache_info_res) + 1;
205 info->num_sets = CPUID_CACHE_NO_OF_SETS(cache_info_res) + 1;
206 info->line_size = CPUID_CACHE_COHER_LINE(cache_info_res) + 1;
207 info->physical_partitions = CPUID_CACHE_PHYS_LINE(cache_info_res) + 1;
208 info->num_cores_shared = CPUID_CACHE_SHARING_CACHE(cache_info_res) + 1;
209 info->fully_associative = CPUID_CACHE_FULL_ASSOC(cache_info_res);
210 info->size = get_cache_size(info);
212 return true;