Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
util: Add cpuinfo-i386.c
Add cpuinfo.h for i386 and x86_64, and the initialization for that in util/. Populate that with a slightly altered copy of the tcg host probing code. Other uses of cpuid.h will be adjusted one patch at a time. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
- Loading branch information
Showing
5 changed files
with
142 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| /* | ||
| * SPDX-License-Identifier: GPL-2.0-or-later | ||
| * Host specific cpu indentification for x86. | ||
| */ | ||
|
|
||
| #ifndef HOST_CPUINFO_H | ||
| #define HOST_CPUINFO_H | ||
|
|
||
| /* Digested version of <cpuid.h> */ | ||
|
|
||
| #define CPUINFO_ALWAYS (1u << 0) /* so cpuinfo is nonzero */ | ||
| #define CPUINFO_CMOV (1u << 1) | ||
| #define CPUINFO_MOVBE (1u << 2) | ||
| #define CPUINFO_LZCNT (1u << 3) | ||
| #define CPUINFO_POPCNT (1u << 4) | ||
| #define CPUINFO_BMI1 (1u << 5) | ||
| #define CPUINFO_BMI2 (1u << 6) | ||
| #define CPUINFO_SSE2 (1u << 7) | ||
| #define CPUINFO_SSE4 (1u << 8) | ||
| #define CPUINFO_AVX1 (1u << 9) | ||
| #define CPUINFO_AVX2 (1u << 10) | ||
| #define CPUINFO_AVX512F (1u << 11) | ||
| #define CPUINFO_AVX512VL (1u << 12) | ||
| #define CPUINFO_AVX512BW (1u << 13) | ||
| #define CPUINFO_AVX512DQ (1u << 14) | ||
| #define CPUINFO_AVX512VBMI2 (1u << 15) | ||
| #define CPUINFO_ATOMIC_VMOVDQA (1u << 16) | ||
|
|
||
| /* Initialized with a constructor. */ | ||
| extern unsigned cpuinfo; | ||
|
|
||
| /* | ||
| * We cannot rely on constructor ordering, so other constructors must | ||
| * use the function interface rather than the variable above. | ||
| */ | ||
| unsigned cpuinfo_init(void); | ||
|
|
||
| #endif /* HOST_CPUINFO_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| #include "host/include/i386/host/cpuinfo.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| /* | ||
| * SPDX-License-Identifier: GPL-2.0-or-later | ||
| * Host specific cpu indentification for x86. | ||
| */ | ||
|
|
||
| #include "qemu/osdep.h" | ||
| #include "host/cpuinfo.h" | ||
| #ifdef CONFIG_CPUID_H | ||
| # include "qemu/cpuid.h" | ||
| #endif | ||
|
|
||
| unsigned cpuinfo; | ||
|
|
||
| /* Called both as constructor and (possibly) via other constructors. */ | ||
| unsigned __attribute__((constructor)) cpuinfo_init(void) | ||
| { | ||
| unsigned info = cpuinfo; | ||
|
|
||
| if (info) { | ||
| return info; | ||
| } | ||
|
|
||
| #ifdef CONFIG_CPUID_H | ||
| unsigned max, a, b, c, d, b7 = 0, c7 = 0; | ||
|
|
||
| max = __get_cpuid_max(0, 0); | ||
|
|
||
| if (max >= 7) { | ||
| __cpuid_count(7, 0, a, b7, c7, d); | ||
| info |= (b7 & bit_BMI ? CPUINFO_BMI1 : 0); | ||
| info |= (b7 & bit_BMI2 ? CPUINFO_BMI2 : 0); | ||
| } | ||
|
|
||
| if (max >= 1) { | ||
| __cpuid(1, a, b, c, d); | ||
|
|
||
| info |= (d & bit_CMOV ? CPUINFO_CMOV : 0); | ||
| info |= (d & bit_SSE2 ? CPUINFO_SSE2 : 0); | ||
| info |= (c & bit_SSE4_1 ? CPUINFO_SSE4 : 0); | ||
| info |= (c & bit_MOVBE ? CPUINFO_MOVBE : 0); | ||
| info |= (c & bit_POPCNT ? CPUINFO_POPCNT : 0); | ||
|
|
||
| /* For AVX features, we must check available and usable. */ | ||
| if ((c & bit_AVX) && (c & bit_OSXSAVE)) { | ||
| unsigned bv = xgetbv_low(0); | ||
|
|
||
| if ((bv & 6) == 6) { | ||
| info |= CPUINFO_AVX1; | ||
| info |= (b7 & bit_AVX2 ? CPUINFO_AVX2 : 0); | ||
|
|
||
| if ((bv & 0xe0) == 0xe0) { | ||
| info |= (b7 & bit_AVX512F ? CPUINFO_AVX512F : 0); | ||
| info |= (b7 & bit_AVX512VL ? CPUINFO_AVX512VL : 0); | ||
| info |= (b7 & bit_AVX512BW ? CPUINFO_AVX512BW : 0); | ||
| info |= (b7 & bit_AVX512DQ ? CPUINFO_AVX512DQ : 0); | ||
| info |= (c7 & bit_AVX512VBMI2 ? CPUINFO_AVX512VBMI2 : 0); | ||
| } | ||
|
|
||
| /* | ||
| * The Intel SDM has added: | ||
| * Processors that enumerate support for Intel® AVX | ||
| * (by setting the feature flag CPUID.01H:ECX.AVX[bit 28]) | ||
| * guarantee that the 16-byte memory operations performed | ||
| * by the following instructions will always be carried | ||
| * out atomically: | ||
| * - MOVAPD, MOVAPS, and MOVDQA. | ||
| * - VMOVAPD, VMOVAPS, and VMOVDQA when encoded with VEX.128. | ||
| * - VMOVAPD, VMOVAPS, VMOVDQA32, and VMOVDQA64 when encoded | ||
| * with EVEX.128 and k0 (masking disabled). | ||
| * Note that these instructions require the linear addresses | ||
| * of their memory operands to be 16-byte aligned. | ||
| * | ||
| * AMD has provided an even stronger guarantee that processors | ||
| * with AVX provide 16-byte atomicity for all cachable, | ||
| * naturally aligned single loads and stores, e.g. MOVDQU. | ||
| * | ||
| * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104688 | ||
| */ | ||
| __cpuid(0, a, b, c, d); | ||
| if (c == signature_INTEL_ecx || c == signature_AMD_ecx) { | ||
| info |= CPUINFO_ATOMIC_VMOVDQA; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| max = __get_cpuid_max(0x8000000, 0); | ||
| if (max >= 1) { | ||
| __cpuid(0x80000001, a, b, c, d); | ||
| info |= (c & bit_LZCNT ? CPUINFO_LZCNT : 0); | ||
| } | ||
| #endif | ||
|
|
||
| info |= CPUINFO_ALWAYS; | ||
| cpuinfo = info; | ||
| return info; | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters