[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 08/25] x86/cpuid: Introduce named feature bitfields



It greatly aids the readibility of code to express feature checks with their
direct name (e.g. p->basic.mtrr or p->extd.lm), rarther that by a field and a
bitmask.  gen-cpuid.py is augmented to calculate a suitable declaration to
live in a union with the underlying feature word.

gen-cpuid.py doesn't know Xen's choice of naming for the feature word indicies
(and arguably shouldn't care), so provides the declarations in terms of their
numeric feature word index.  The DECL_BITFIELD() macro (local to cpuid_policy)
takes a feature word index name and chooses the right declaration, to aid
clarity.

All X86_FEATURE_*'s are included in the naming, other than the features
fast-forwarded from other state (APIC, OSXSAVE, OSPKE), whose value cannot be
read out of the feature word.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>

v2:
 * Dynamically generate the names
---
 xen/include/asm-x86/cpuid.h | 61 ++++++++++++++++++++++++++++++++++++++++-----
 xen/tools/gen-cpuid.py      | 32 ++++++++++++++++++++++++
 2 files changed, 87 insertions(+), 6 deletions(-)

diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index 0592b38..924e5d4 100644
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -92,6 +92,10 @@ struct cpuid_policy
      * Everything else should be considered inaccurate, and not necesserily 0.
      */
 
+#define DECL_BITFIELD(word) _DECL_BITFIELD(FEATURESET_ ## word)
+#define _DECL_BITFIELD(x)   __DECL_BITFIELD(x)
+#define __DECL_BITFIELD(x)  NAMED_BITFIELD_ ## x
+
     /* Basic leaves: 0x000000xx */
     union {
         struct cpuid_leaf raw[CPUID_GUEST_NR_BASIC];
@@ -100,7 +104,15 @@ struct cpuid_policy
             uint32_t max_leaf, /* b */:32, /* c */:32, /* d */:32;
 
             /* Leaf 0x1 - Family/model/stepping and features. */
-            uint32_t /* a */:32, /* b */:32, _1c, _1d;
+            uint32_t /* a */:32, /* b */:32;
+            union {
+                uint32_t _1c;
+                struct { DECL_BITFIELD(1c); };
+            };
+            union {
+                uint32_t _1d;
+                struct { DECL_BITFIELD(1d); };
+            };
         };
     } basic;
 
@@ -109,7 +121,19 @@ struct cpuid_policy
         struct cpuid_leaf raw[CPUID_GUEST_NR_FEAT];
         struct {
             /* Subleaf 0. */
-            uint32_t max_subleaf, _7b0, _7c0, _7d0;
+            uint32_t max_subleaf;
+            union {
+                uint32_t _7b0;
+                struct { DECL_BITFIELD(7b0); };
+            };
+            union {
+                uint32_t _7c0;
+                struct { DECL_BITFIELD(7c0); };
+            };
+            union {
+                uint32_t _7d0;
+                struct { DECL_BITFIELD(7d0); };
+            };
         };
     } feat;
 
@@ -121,7 +145,11 @@ struct cpuid_policy
             uint32_t xcr0_low, /* b */:32, /* c */:32, xcr0_high;
 
             /* Subleaf 1. */
-            uint32_t Da1, /* b */:32, xss_low, xss_high;
+            union {
+                uint32_t Da1;
+                struct { DECL_BITFIELD(Da1); };
+            };
+            uint32_t /* b */:32, xss_low, xss_high;
         };
     } xstate;
 
@@ -133,7 +161,15 @@ struct cpuid_policy
             uint32_t max_leaf, /* b */:32, /* c */:32, /* d */:32;
 
             /* Leaf 0x80000001 - Family/model/stepping and features. */
-            uint32_t /* a */:32, /* b */:32, e1c, e1d;
+            uint32_t /* a */:32, /* b */:32;
+            union {
+                uint32_t e1c;
+                struct { DECL_BITFIELD(e1c); };
+            };
+            union {
+                uint32_t e1d;
+                struct { DECL_BITFIELD(e1d); };
+            };
 
             uint64_t :64, :64; /* Brand string. */
             uint64_t :64, :64; /* Brand string. */
@@ -142,13 +178,26 @@ struct cpuid_policy
             uint64_t :64, :64; /* L2/3 cache/TLB. */
 
             /* Leaf 0x80000007 - Advanced Power Management. */
-            uint32_t /* a */:32, /* b */:32, /* c */:32, e7d;
+            uint32_t /* a */:32, /* b */:32, /* c */:32;
+            union {
+                uint32_t e7d;
+                struct { DECL_BITFIELD(e7d); };
+            };
 
             /* Leaf 0x80000008 - Misc addr/feature info. */
-            uint32_t /* a */:32, e8b, /* c */:32, /* d */:32;
+            uint32_t /* a */:32;
+            union {
+                uint32_t e8b;
+                struct { DECL_BITFIELD(e8b); };
+            };
+            uint32_t /* c */:32, /* d */:32;
         };
     } extd;
 
+#undef __DECL_BITFIELD
+#undef _DECL_BITFIELD
+#undef DECL_BITFIELD
+
     /* Temporary featureset bitmap. */
     uint32_t fs[FSCAPINTS];
 };
diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py
index 420a5cc..b9da06c 100755
--- a/xen/tools/gen-cpuid.py
+++ b/xen/tools/gen-cpuid.py
@@ -29,6 +29,7 @@ class State(object):
         self.pv = []
         self.hvm_shadow = []
         self.hvm_hap = []
+        self.bitfields = [] # Text to declare named bitfields in C
 
 def parse_definitions(state):
     """
@@ -291,6 +292,28 @@ def crunch_numbers(state):
     for k, v in state.deep_deps.iteritems():
         state.deep_deps[k] = featureset_to_uint32s(v, nr_entries)
 
+    # Calculate the bitfield name declarations
+    for word in xrange(nr_entries):
+
+        names = []
+        for bit in xrange(32):
+
+            name = state.names.get(word * 32 + bit, "")
+
+            # Prepend an underscore if the name starts with a digit.
+            if name and name[0] in "0123456789":
+                name = "_" + name
+
+            # Don't generate names for the duplicate features, or ones
+            # fast-forwarded from other state
+            if (name.startswith("E1D_") or
+                name in ("APIC", "OSXSAVE", "OSPKE")):
+                name = ""
+
+            names.append(name.lower())
+
+        state.bitfields.append("bool " + ":1, ".join(names) + ":1")
+
 
 def write_results(state):
     state.output.write(
@@ -344,6 +367,15 @@ def write_results(state):
     state.output.write(
 """}
 
+""")
+
+    for idx, text in enumerate(state.bitfields):
+        state.output.write(
+            "#define NAMED_BITFIELD_%d \\\n    %s\n\n"
+            % (idx, text))
+
+    state.output.write(
+"""
 #endif /* __XEN_X86__FEATURESET_DATA__ */
 """)
 
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.