[PATCH v5 07/17] target-s390x: Generate facility defines per S390 CPU model

Michael Mueller
2015-04-13T13:56:26Z

This patch introduces the helper "gen-facilities" which allows to generate
facility list definitions and masks at compile time. Its flexibility is
better and the error-proneness is lower when compared to static programming
time added statements.

The helper includes "target-s390x/cpu-facilities.h" to be able to use named
facility bits instead of numbers. Its output will be feed back into the
cpu model related header file "target-s390x/cpu-models.h" by including
gen-facilities.h to implement model related data structures.

The following defines/symbols are expected to be provided by the cpu-facilities
header file:

FAC_LIST_ARCH_S390_SIZE_UINT8
FAC_N3
FAC_ZARCH
FAC_ZARCH_ACTIVE
...

The defines provided by gen-facilities follow the following schema:

FAC_LIST_CPU_S390_SIZE_UINT1 %PRIu32
FAC_LIST_CPU_S390_SIZE_UINT8 %PRIu32
FAC_LIST_CPU_S390_SIZE_UINT64 %PRIu32
FAC_LIST_CPU_S390_MASK_QEMU 0x%016PRIx64,0x%016PRIx64,...
FAC_LIST_CPU_S390_<TYPE>_GA<n> 0x%016PRIx64,0x%016PRIx64,...

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
Makefile.target | 2 +-
rules.mak | 1 +
target-s390x/Makefile.objs | 20 ++
target-s390x/gen-facilities.c | 417 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 439 insertions(+), 1 deletion(-)
create mode 100644 target-s390x/gen-facilities.c

diff --git a/Makefile.target b/Makefile.target
index 2262d89..58cfc1b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -190,7 +190,7 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")

-clean:
+clean: clean-target
rm -f *.a *~ $(PROGS)
rm -f $(shell find . -name '*.[od]')
rm -f hmp-commands.h qmp-commands-old.h gdbstub-xml.c
diff --git a/rules.mak b/rules.mak
index 3a05627..43cf05c 100644
--- a/rules.mak
+++ b/rules.mak
@@ -12,6 +12,7 @@ MAKEFLAGS += -rR
%.cpp:
%.m:
%.mak:
+clean-target:

# Flags for C++ compilation
QEMU_CXXFLAGS = -D__STDC_LIMIT_MACROS $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wold-style-declaration -Wold-style-definition -Wredundant-decls, $(QEMU_CFLAGS))
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index dd62cbd..997dda4 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -3,3 +3,23 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
obj-y += gdbstub.o
obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
obj-$(CONFIG_KVM) += kvm.o
+
+# build and run facility generator
+#
+fac = gen-facilities
+fac-src = $(SRC_PATH)/target-$(TARGET_BASE_ARCH)
+fac-dst = $(BUILD_DIR)/$(TARGET_DIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+GENERATED_HEADERS += $(fac-dst)$(fac).h
+endif
+
+$(fac-dst)$(fac).h: $(fac-dst)$(fac)
+ $(call quiet-command,$< >$@," GEN $(TARGET_DIR)$(fac).h")
+
+$(fac-dst)$(fac): $(fac-src)/$(fac).c $(fac-src)/cpu-facilities.h
+ $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) -o $@ $<," CC $(TARGET_DIR)$(fac)")
+
+clean-target:
+ rm -f $(fac).h
+ rm -f $(fac)
diff --git a/target-s390x/gen-facilities.c b/target-s390x/gen-facilities.c
new file mode 100644
index 0000000..f4f4c57
--- /dev/null
+++ b/target-s390x/gen-facilities.c
@@ -0,0 +1,417 @@
+/*
+ * S390 facility list/mask generator
+ *
+ * Copyright 2015 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <assert.h>
+#include <values.h>
+#include "cpu-facilities.h"
+
+/***** BEGIN FACILITY DEFS *****/
+
+/*******************************
+ * CMOS G7 processors
+ *******************************/
+
+/* 2064-GA1 */
+static uint16_t set_2064_GA1[] = {
+ FAC_N3,
+ FAC_ZARCH,
+ FAC_ZARCH_ACTIVE,
+};
+#define clear_2064_GA1 EmptyFacs
+
+/* 2064-GA2 */
+static uint16_t set_2064_GA2[] = {
+ FAC_EXTENDED_TRANSLATION_2,
+};
+#define clear_2064_GA2 EmptyFacs
+
+/* 2064-GA3 */
+#define set_2064_GA3 EmptyFacs
+#define clear_2064_GA3 EmptyFacs
+
+/* 2066-GA1 */
+#define set_2066_GA1 EmptyFacs
+#define clear_2066_GA1 EmptyFacs
+
+/*******************************
+ * CMOS G8 processors
+ *******************************/
+
+/* 2084-GA1 */
+static uint16_t set_2084_GA1[] = {
+ FAC_DAT_ENH,
+ FAC_MESSAGE_SECURITY_ASSIST,
+ FAC_LONG_DISPLACEMENT,
+ FAC_LONG_DISPLACEMENT_FAST,
+ FAC_HFP_MADDSUB,
+};
+#define clear_2084_GA1 EmptyFacs
+
+/* 2084-GA2 */
+static uint16_t set_2084_GA2[] = {
+ 4,
+};
+#define clear_2084_GA2 EmptyFacs
+
+/* 2084-GA3 */
+static uint16_t set_2084_GA3[] = {
+ FAC_ASN_LX_REUSE,
+ FAC_EXTENDED_TRANSLATION_3,
+};
+#define clear_2084_GA3 EmptyFacs
+
+/* 2084-GA4 */
+#define set_2084_GA4 EmptyFacs
+#define clear_2084_GA4 EmptyFacs
+
+/* 2084-GA5 */
+static uint16_t set_2084_GA5[] = {
+ FAC_TOD_CLOCK_STEERING,
+};
+#define clear_2084_GA5 EmptyFacs
+
+/* 2086-GA1 */
+#define set_2086_GA1 EmptyFacs
+#define clear_2086_GA1 EmptyFacs
+
+/* 2086-GA2 */
+#define set_2086_GA2 EmptyFacs
+#define clear_2086_GA2 EmptyFacs
+
+/* 2086-GA3 */
+#define set_2086_GA3 EmptyFacs
+#define clear_2086_GA3 EmptyFacs
+
+/*******************************
+ * CMOS G9 processors
+ *******************************/
+
+/* 2094-GA1 */
+static uint16_t set_2094_GA1[] = {
+ FAC_STFLE,
+ FAC_EXTENDED_IMMEDIATE,
+ FAC_HFP_UNNORMALIZED_EXT,
+ FAC_ETF2_ENH,
+ FAC_STORE_CLOCK_FAST,
+ FAC_ETF3_ENH,
+ FAC_EXTRACT_CPU_TIME,
+};
+#define clear_2094_GA1 EmptyFacs
+
+/* 2094-GA2 */
+static uint16_t set_2094_GA2[] = {
+ FAC_SENSE_RUNNING_STATUS,
+ FAC_MOVE_WITH_OPTIONAL_SPEC,
+ FAC_COMPARE_AND_SWAP_AND_STORE,
+ FAC_FLOATING_POINT_SUPPPORT_ENH,
+ FAC_DFP,
+};
+#define clear_2094_GA2 EmptyFacs
+
+/* 2094-GA3 */
+static uint16_t set_2094_GA3[] = {
+ FAC_PFPO,
+};
+#define clear_2094_GA3 EmptyFacs
+
+/* 2096-GA1 */
+#define set_2096_GA1 EmptyFacs
+#define clear_2096_GA1 EmptyFacs
+
+/* 2096-GA2 */
+#define set_2096_GA2 EmptyFacs
+#define clear_2096_GA2 EmptyFacs
+
+/*******************************
+ * CMOS G10 processors
+ *******************************/
+
+/* 2097-GA1 */
+static uint16_t set_2097_GA1[] = {
+ FAC_ENHANCED_DAT_1,
+ FAC_CONDITIONAL_SSKE,
+ FAC_CONFIGURATION_TOPOLOGY,
+ FAC_PARSING_ENH,
+ FAC_COMPARE_AND_SWAP_AND_STORE_2,
+ FAC_GENERAL_INSTRUCTIONS_EXT,
+ FAC_EXECUTE_EXT,
+ FAC_DFP_FAST,
+};
+#define clear_2097_GA1 EmptyFacs
+
+/* 2097-GA2 */
+static uint16_t set_2097_GA2[] = {
+ 65,
+ FAC_CPU_MEASUREMENT_COUNTER,
+ FAC_CPU_MEASUREMENT_SAMPLING,
+};
+#define clear_2097_GA2 EmptyFacs
+
+/* 2097-GA3 */
+static uint16_t set_2097_GA3[] = {
+ FAC_LOAD_PROGRAM_PARAMETERS,
+};
+#define clear_2097_GA3 EmptyFacs
+
+/* 2098-GA1 */
+#define set_2098_GA1 EmptyFacs
+#define clear_2098_GA1 EmptyFacs
+
+/* 2098-GA2 */
+#define set_2098_GA2 EmptyFacs
+#define clear_2098_GA2 EmptyFacs
+
+/*******************************
+ * CMOS G11 processors
+ *******************************/
+
+/* 2817-GA1 */
+static uint16_t set_2817_GA1[] = {
+ FAC_ENHANCED_MONITOR,
+ FAC_FLOATING_POINT_EXT,
+ FAC_MULTI_45,
+ 46,
+ FAC_ACCESS_EXCEPTION_FS_INDICATION,
+};
+static uint16_t clear_2817_GA1[] = {
+ 65,
+};
+
+/* 2817-GA2 */
+static uint16_t set_2817_GA2[] = {
+ FAC_IPTE_RANGE,
+ FAC_NONQ_KEY_SETTING,
+ FAC_CMPSC_ENH,
+ FAC_RESET_REFERENCE_BITS_MULTIPLE,
+ FAC_MESSAGE_SECURITY_ASSIST_3,
+ FAC_MESSAGE_SECURITY_ASSIST_4,
+};
+#define clear_2817_GA2 EmptyFacs
+
+/* 2818-GA1 */
+#define set_2818_GA1 EmptyFacs
+#define clear_2818_GA1 EmptyFacs
+
+/*******************************
+ * CMOS G12 processors
+ *******************************/
+
+/* 2827-GA1 */
+static uint16_t set_2827_GA1[] = {
+ FAC_DFP_ZONED_CONVERSION,
+ FAC_MULTI_49,
+ FAC_CONSTRAINT_TRANSACTIONAL_EXE,
+ FAC_LOCAL_TLB_CLEARING,
+ FAC_INTERLOCKED_ACCESS_2,
+ FAC_TRANSACTIONAL_EXE,
+ FAC_ENHANCED_DAT_2,
+};
+#define clear_2827_GA1 EmptyFacs
+
+/* 2827-GA2 */
+static uint16_t set_2827_GA2[] = {
+ FAC_MESSAGE_SECURITY_ASSIST_5,
+};
+#define clear_2827_GA2 EmptyFacs
+
+/* 2828-GA1 */
+#define set_2828_GA1 EmptyFacs
+#define clear_2828_GA1 EmptyFacs
+
+/*******************************
+ * CMOS G13 processors
+ *******************************/
+
+/* 2964-GA1 */
+static uint16_t set_2964_GA1[] = {
+ FAC_LOAD_STORE_ON_COND_2,
+ FAC_DFP_PACKED_CONVERSION,
+ FAC_VECTOR,
+ FAC_STORE_CPU_COUNTER_MULTI,
+};
+#define clear_2964_GA1 EmptyFacs
+
+/****** END FACILITY DEFS ******/
+
+#define S390_ARCH_FAC_LIST_SIZE_BYTE \
+ (S390_ARCH_FAC_LIST_SIZE / 8)
+
+#define _YEARS "2014, 2015"
+#define _NAME_H "TARGET_S390X_GEN_FACILITIES_H"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+#define FAC_INITIALIZER(_name) \
+ { \
+ .Name = "FAC_LIST_CPU_S390_" #_name, \
+ .SetBits = \
+ { .Data = set_##_name, \
+ .Length = ARRAY_SIZE(set_##_name) }, \
+ .ClearBits = \
+ { .Data = clear_##_name, \
+ .Length = ARRAY_SIZE(clear_##_name) }, \
+ }
+
+enum BitOps {
+ SetBit,
+ ClearBit,
+};
+
+typedef struct BitSpec {
+ uint16_t *Data;
+ uint32_t Length;
+} BitSpec;
+
+typedef struct FacDefSpec {
+ const char *Name;
+ BitSpec SetBits;
+ BitSpec ClearBits;
+} FacDefSpec;
+
+static uint16_t EmptyFacs[] = {};
+
+/*******************************
+ * processor GA series
+ *******************************/
+static FacDefSpec FacDef[] = {
+ FAC_INITIALIZER(2064_GA1),
+ FAC_INITIALIZER(2064_GA2),
+ FAC_INITIALIZER(2064_GA3),
+ FAC_INITIALIZER(2066_GA1),
+ FAC_INITIALIZER(2084_GA1),
+ FAC_INITIALIZER(2084_GA2),
+ FAC_INITIALIZER(2084_GA3),
+ FAC_INITIALIZER(2086_GA1),
+ FAC_INITIALIZER(2084_GA4),
+ FAC_INITIALIZER(2086_GA2),
+ FAC_INITIALIZER(2084_GA5),
+ FAC_INITIALIZER(2086_GA3),
+ FAC_INITIALIZER(2094_GA1),
+ FAC_INITIALIZER(2094_GA2),
+ FAC_INITIALIZER(2094_GA3),
+ FAC_INITIALIZER(2096_GA1),
+ FAC_INITIALIZER(2096_GA2),
+ FAC_INITIALIZER(2097_GA1),
+ FAC_INITIALIZER(2097_GA2),
+ FAC_INITIALIZER(2098_GA1),
+ FAC_INITIALIZER(2097_GA3),
+ FAC_INITIALIZER(2098_GA2),
+ FAC_INITIALIZER(2817_GA1),
+ FAC_INITIALIZER(2817_GA2),
+ FAC_INITIALIZER(2818_GA1),
+ FAC_INITIALIZER(2827_GA1),
+ FAC_INITIALIZER(2827_GA2),
+ FAC_INITIALIZER(2828_GA1),
+ FAC_INITIALIZER(2964_GA1),
+};
+
+/*******************************
+ * QEMU facility list mask
+ *******************************/
+#define set_MASK_QEMU EmptyFacs
+#define clear_MASK_QEMU EmptyFacs
+
+static FacDefSpec QemuMaskDef = FAC_INITIALIZER(MASK_QEMU);
+
+static void BigEndianBitOps(enum BitOps BitOp, uint64_t Facility[],
+ uint32_t MaxWord, BitSpec Bits)
+{
+ uint32_t i, Bit, Word, WidthInBits;
+
+ WidthInBits = _TYPEBITS(typeof(Facility[0]));
+ for (i = 0; i < Bits.Length; i++) {
+ Bit = (WidthInBits - 1) - (Bits.Data[i] & (WidthInBits - 1));
+ Word = Bits.Data[i] / WidthInBits;
+ assert(Word < MaxWord);
+ switch (BitOp) {
+ case SetBit:
+ Facility[Word] |= __UINT64_C(1) << Bit;
+ break;
+ case ClearBit:
+ Facility[Word] &= ~(__UINT64_C(1) << Bit);
+ break;
+ }
+ }
+}
+
+static uint32_t PrintFacilityList(uint32_t Model, FacDefSpec FacDef[])
+{
+ uint32_t i, Words, Size;
+ uint64_t Facility[FAC_LIST_ARCH_S390_SIZE_UINT8];
+
+ for (Size = ARRAY_SIZE(Facility), i = 0; i < Size; i++) {
+ Facility[i] = __UINT64_C(0);
+ }
+ for (i = 0; i <= Model; i++) {
+ BigEndianBitOps(SetBit, Facility, Size, FacDef[i].SetBits);
+ BigEndianBitOps(ClearBit, Facility, Size, FacDef[i].ClearBits);
+ }
+ for (Words = 0, i = 0; i < Size; i++) {
+ if (Facility[i]) {
+ Words = i;
+ }
+ }
+ printf("#define %s\t", FacDef[Model].Name);
+ for (i = 0; i <= Words; i++) {
+ printf("0x%016"PRIx64"%c", Facility[i], i < Words ? ',' : '\n');
+ }
+ return ++Words;
+}
+
+static inline uint32_t Max(uint32_t uIntA, uint32_t uIntB)
+{
+ if (uIntA > uIntB) {
+ return uIntA;
+ }
+ return uIntB;
+}
+
+static inline void PrintAllFacilityDefs(void)
+{
+ uint32_t i, MaxWords, MaxBytes, MaxBits;
+
+ printf("\n/* CPU model facility list data */\n");
+ for (MaxWords = 0, i = 0; i < ARRAY_SIZE(FacDef); i++) {
+ MaxWords = Max(PrintFacilityList(i, FacDef), MaxWords);
+ }
+ printf("\n/* QEMU facility mask data */\n");
+ MaxWords = Max(PrintFacilityList(0, &QemuMaskDef), MaxWords);
+ MaxBytes = MaxWords * sizeof(uint64_t);
+ MaxBits = MaxBytes * CHARBITS;
+ printf("\n/* facility list/mask sizes */\n");
+ printf("#define FAC_LIST_CPU_S390_SIZE_UINT1\t%"PRIu32"\n", MaxBits);
+ printf("#define FAC_LIST_CPU_S390_SIZE_UINT8\t%"PRIu32"\n", MaxBytes);
+ printf("#define FAC_LIST_CPU_S390_SIZE_UINT64\t%"PRIu32"\n", MaxWords);
+}
+
+int main(int argc, char *argv[])
+{
+ printf("/*\n"
+ " * AUTOMATICALLY GENERATED, DO NOT MODIFY HERE, EDIT\n"
+ " * SOURCE FILE \"%s\" INSTEAD.\n"
+ " *\n"
+ " * Copyright %s IBM Corp.\n"
+ " *\n"
+ " * This work is licensed under the terms of the GNU GPL, "
+ "version 2 or (at\n * your option) any later version. See "
+ "the COPYING file in the top-level\n * directory.\n"
+ " */\n\n"
+ "#ifndef %s\n#define %s\n", __FILE__, _YEARS, _NAME_H, _NAME_H);
+ PrintAllFacilityDefs();
+ printf("\n#endif\n");
+ return 0;
+}
--
1.8.3.1