This patch defines s390 cpu facilities and their appearance/disappearance. The
implemented functions allow to calculate cpu model specific facility sets. These
sets are assiciated to the defiend cpu classes used to calculate the list of
supported cpu models.

Signed-off-by: Michael Mueller <m...@linux.vnet.ibm.com>
---
 target-s390x/cpu-models.c | 126 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index e2e8019..b813f89 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -27,7 +27,7 @@
         cc->class      = cpu_class(_cpu_id);                            \
         cc->ga         = cpu_ga(_cpu_id);                               \
         cc->generation = cpu_generation(_cpu_id);                       \
-        cc->facilities = NULL;                                          \
+        cc->facilities = facilities(_cpu_id);                           \
         cc->kvm_facilities = NULL;                                      \
         cc->is_active  = true;                                          \
         cc->is_host    = false;                                         \
@@ -47,6 +47,130 @@
     }                                                                   \
     type_init(glue(_cpu_id, _cpu_register_types))
 
+static unsigned int facility_availability[MAX_S390_FACILITY_BIT] = {
+    [0] = CPU_S390_2064_GA1,
+    [1] = CPU_S390_2064_GA1,
+    [2] = CPU_S390_2064_GA1,
+    [3] = CPU_S390_2084_GA1,
+    [4] = CPU_S390_2084_GA2,
+    [6] = CPU_S390_2084_GA3,
+    [7] = CPU_S390_2094_GA1,
+    [8] = CPU_S390_2097_GA1,
+    [9] = CPU_S390_2094_GA2,
+    [10] = CPU_S390_2097_GA1,
+    [11] = CPU_S390_2097_GA1,
+    [13] = CPU_S390_2817_GA2,
+    [14] = CPU_S390_2817_GA2,
+    [16] = CPU_S390_2064_GA2, /* GA1+ */
+    [17] = CPU_S390_2084_GA1,
+    [18] = CPU_S390_2084_GA1,
+    [19] = CPU_S390_2084_GA1,
+    [20] = CPU_S390_2084_GA1,
+    [21] = CPU_S390_2094_GA1,
+    [22] = CPU_S390_2084_GA3,
+    [23] = CPU_S390_2094_GA1,
+    [24] = CPU_S390_2094_GA1,
+    [25] = CPU_S390_2094_GA1,
+    [26] = CPU_S390_2097_GA1,
+    [27] = CPU_S390_2094_GA2,
+    [28] = CPU_S390_2084_GA5,
+    [30] = CPU_S390_2094_GA1,
+    [31] = CPU_S390_2094_GA1,
+    [32] = CPU_S390_2094_GA2,
+    [33] = CPU_S390_2097_GA1,
+    [34] = CPU_S390_2097_GA1,
+    [35] = CPU_S390_2097_GA1,
+    [36] = CPU_S390_2817_GA1,
+    [37] = CPU_S390_2817_GA1,
+    [40] = CPU_S390_2097_GA3,
+    [41] = CPU_S390_2094_GA2,
+    [42] = CPU_S390_2094_GA2,
+    [43] = CPU_S390_2097_GA1,
+    [44] = CPU_S390_2094_GA3,
+    [45] = CPU_S390_2817_GA1,
+    [46] = CPU_S390_2817_GA1,
+    [47] = CPU_S390_2817_GA2,
+    [48] = CPU_S390_2827_GA1,
+    [49] = CPU_S390_2827_GA1,
+    [50] = CPU_S390_2827_GA1,
+    [51] = CPU_S390_2827_GA1,
+    [52] = CPU_S390_2827_GA1,
+    [65] = CPU_S390_2097_GA2,
+    [66] = CPU_S390_2817_GA2,
+    [67] = CPU_S390_2097_GA2,
+    [68] = CPU_S390_2097_GA2,
+    [73] = CPU_S390_2827_GA1,
+    [75] = CPU_S390_2817_GA1,
+    [76] = CPU_S390_2817_GA2,
+    [77] = CPU_S390_2817_GA2,
+    [78] = CPU_S390_2827_GA1,
+};
+
+static unsigned int facility_revocation[MAX_S390_FACILITY_BIT] = {
+    [65] = CPU_S390_2817_GA1,
+};
+
+/* set a specific bit in facility set */
+static void set_facility(unsigned int nr, void *facilities)
+{
+    unsigned char *ptr;
+
+    if (nr >= MAX_S390_FACILITY_BIT) {
+        return;
+    }
+    ptr = (unsigned char *) facilities + (nr >> 3);
+    *ptr |= (0x80 >> (nr & 7));
+}
+
+/* clear a specific bit in facility set */
+static void clear_facility(unsigned int nr, void *facilities)
+{
+    unsigned char *ptr;
+
+    if (nr >= MAX_S390_FACILITY_BIT) {
+        return;
+    }
+    ptr = (unsigned char *) facilities + (nr >> 3);
+    *ptr &= ~(0x80 >> (nr & 7));
+}
+
+/* test a specific bit in facility set to be set */
+static inline int test_facility(unsigned long nr, void *facilities)
+{
+    unsigned char *ptr;
+
+    if (nr >= MAX_S390_FACILITY_BIT)
+        return 0;
+    ptr = (unsigned char *) facilities + (nr >> 3);
+    return (*ptr & (0x80 >> (nr & 7))) != 0;
+}
+
+/* calculate the facility set for a specific cpu type */
+static unsigned long *facilities(unsigned int cpu_id)
+{
+    unsigned long *fac;
+    unsigned int i;
+
+    fac = g_malloc0(MAX_S390_FACILITY_BYTE);
+    if (fac) {
+        for (i = 0; i < ARRAY_SIZE(facility_availability); i++) {
+            if (facility_availability[i]) {
+                if (cpu_order(facility_availability[i]) <= cpu_order(cpu_id)) {
+                    set_facility(i, fac);
+                }
+            }
+        }
+        for (i = 0; i < ARRAY_SIZE(facility_revocation); i++) {
+            if (facility_revocation[i]) {
+                if (cpu_order(facility_revocation[i]) <= cpu_order(cpu_id)) {
+                    clear_facility(i, fac);
+                }
+            }
+        }
+    }
+    return fac;
+}
+
 /* define S390 CPU model classes */
 S390_PROC_DEF("2064-ga1", CPU_S390_2064_GA1, "IBM zSeries 900 GA1")
 S390_PROC_DEF("2064-ga2", CPU_S390_2064_GA2, "IBM zSeries 900 GA2")
-- 
1.8.3.1


Reply via email to