Also introduce constants for the vendor strings in CPUID leaf 0.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
#include <err.h>
#include <xen-tools/libs.h>
+#include <xen/asm/x86-vendors.h>
#include <xen/lib/x86/cpuid.h>
#include <xen/lib/x86/msr.h>
#include <xen/domctl.h>
printf(fmt, ##__VA_ARGS__); \
})
+static void test_vendor_identification(void)
+{
+ static const struct test {
+ union {
+ char ident[12];
+ struct {
+ uint32_t b, d, c;
+ };
+ };
+ unsigned int vendor;
+ } tests[] = {
+ { { "GenuineIntel" }, X86_VENDOR_INTEL },
+ { { "AuthenticAMD" }, X86_VENDOR_AMD },
+ { { "CentaurHauls" }, X86_VENDOR_CENTAUR },
+ { { " Shanghai " }, X86_VENDOR_SHANGHAI },
+
+ { { "" }, X86_VENDOR_UNKNOWN },
+ { { " " }, X86_VENDOR_UNKNOWN },
+ { { "xxxxxxxxxxxx" }, X86_VENDOR_UNKNOWN },
+ };
+
+ printf("Testing CPU vendor identification:\n");
+
+ for ( size_t i = 0; i < ARRAY_SIZE(tests); ++i )
+ {
+ const struct test *t = &tests[i];
+ unsigned int vendor = x86_cpuid_lookup_vendor(t->b, t->c, t->d);
+
+ if ( vendor != t->vendor )
+ fail(" Test '%.12s', expected vendor %u, got %u\n",
+ t->ident, t->vendor, vendor);
+ }
+}
+
static void test_cpuid_serialise_success(void)
{
static const struct test {
{
printf("CPU Policy unit tests\n");
+ test_vendor_identification();
+
test_cpuid_serialise_success();
test_msr_serialise_success();
/*
* CPU vendor IDs
+ *
+ * - X86_VENDOR_* are Xen-internal identifiers. Values and order are
+ * arbitrary.
+ * - X86_VENDOR_*_E?X are architectural information from CPUID leaf 0
*/
#define X86_VENDOR_UNKNOWN 0
+
#define X86_VENDOR_INTEL 1
+#define X86_VENDOR_INTEL_EBX 0x756e6547U /* "GenuineIntel" */
+#define X86_VENDOR_INTEL_ECX 0x6c65746eU
+#define X86_VENDOR_INTEL_EDX 0x49656e69U
+
#define X86_VENDOR_AMD 2
+#define X86_VENDOR_AMD_EBX 0x68747541U /* "AuthenticAMD" */
+#define X86_VENDOR_AMD_ECX 0x444d4163U
+#define X86_VENDOR_AMD_EDX 0x69746e65U
+
#define X86_VENDOR_CENTAUR 3
+#define X86_VENDOR_CENTAUR_EBX 0x746e6543U /* "CentaurHauls" */
+#define X86_VENDOR_CENTAUR_ECX 0x736c7561U
+#define X86_VENDOR_CENTAUR_EDX 0x48727561U
+
#define X86_VENDOR_SHANGHAI 4
+#define X86_VENDOR_SHANGHAI_EBX 0x68532020U /* " Shanghai " */
+#define X86_VENDOR_SHANGHAI_ECX 0x20206961U
+#define X86_VENDOR_SHANGHAI_EDX 0x68676e61U
+
#define X86_VENDOR_NUM 5
#endif /* __XEN_X86_VENDORS_H__ */
#undef BX_CON
#undef XCHG
+/**
+ * Given the vendor id from CPUID leaf 0, look up Xen's internal integer
+ * vendor ID. Returns X86_VENDOR_UNKNOWN for any unknown vendor.
+ */
+unsigned int x86_cpuid_lookup_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx);
+
#define CPUID_GUEST_NR_BASIC (0xdu + 1)
#define CPUID_GUEST_NR_CACHE (5u + 1)
#define CPUID_GUEST_NR_FEAT (0u + 1)
#include <xen/lib/x86/cpuid.h>
+unsigned int x86_cpuid_lookup_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx)
+{
+ switch ( ebx )
+ {
+ case X86_VENDOR_INTEL_EBX:
+ if ( ecx == X86_VENDOR_INTEL_ECX &&
+ edx == X86_VENDOR_INTEL_EDX )
+ return X86_VENDOR_INTEL;
+ break;
+
+ case X86_VENDOR_AMD_EBX:
+ if ( ecx == X86_VENDOR_AMD_ECX &&
+ edx == X86_VENDOR_AMD_EDX )
+ return X86_VENDOR_AMD;
+ break;
+
+ case X86_VENDOR_CENTAUR_EBX:
+ if ( ecx == X86_VENDOR_CENTAUR_ECX &&
+ edx == X86_VENDOR_CENTAUR_EDX )
+ return X86_VENDOR_CENTAUR;
+ break;
+
+ case X86_VENDOR_SHANGHAI_EBX:
+ if ( ecx == X86_VENDOR_SHANGHAI_ECX &&
+ edx == X86_VENDOR_SHANGHAI_EDX )
+ return X86_VENDOR_SHANGHAI;
+ break;
+ }
+
+ return X86_VENDOR_UNKNOWN;
+}
+
void x86_cpuid_policy_fill_native(struct cpuid_policy *p)
{
unsigned int i;
#include <stddef.h>
#include <xen/asm/msr-index.h>
+#include <xen/asm/x86-vendors.h>
#include <xen-tools/libs.h>