From patchwork Mon Apr 13 13:56:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Mueller X-Patchwork-Id: 460815 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 8800D1400A0 for ; Tue, 14 Apr 2015 00:04:54 +1000 (AEST) Received: from localhost ([::1]:51985 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yheyq-0001Xn-6W for incoming@patchwork.ozlabs.org; Mon, 13 Apr 2015 10:04:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48735) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YherS-00067e-PU for qemu-devel@nongnu.org; Mon, 13 Apr 2015 09:57:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YherJ-0003kF-Re for qemu-devel@nongnu.org; Mon, 13 Apr 2015 09:57:14 -0400 Received: from e06smtp10.uk.ibm.com ([195.75.94.106]:36799) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YherJ-0003ip-E0 for qemu-devel@nongnu.org; Mon, 13 Apr 2015 09:57:05 -0400 Received: from /spool/local by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 13 Apr 2015 14:57:04 +0100 Received: from d06dlp01.portsmouth.uk.ibm.com (9.149.20.13) by e06smtp10.uk.ibm.com (192.168.101.140) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 13 Apr 2015 14:57:03 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (d06relay09.portsmouth.uk.ibm.com [9.149.109.194]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id 0441317D805F for ; Mon, 13 Apr 2015 14:57:38 +0100 (BST) Received: from d06av05.portsmouth.uk.ibm.com (d06av05.portsmouth.uk.ibm.com [9.149.37.229]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t3DDv2xt51249348 for ; Mon, 13 Apr 2015 13:57:02 GMT Received: from d06av05.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av05.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t3DDv2t1031847 for ; Mon, 13 Apr 2015 07:57:02 -0600 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av05.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t3DDuwIM031505; Mon, 13 Apr 2015 07:57:01 -0600 From: Michael Mueller To: qemu-devel@nongnu.org, kvm@vger.kernel.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 13 Apr 2015 15:56:26 +0200 Message-Id: <1428933396-37887-8-git-send-email-mimu@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1428933396-37887-1-git-send-email-mimu@linux.vnet.ibm.com> References: <1428933396-37887-1-git-send-email-mimu@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15041313-0041-0000-0000-000003E61576 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.75.94.106 Cc: Eduardo Habkost , Gleb Natapov , Alexander Graf , Christian Borntraeger , Daniel Hansel , "Jason J. Herne" , Cornelia Huck , Paolo Bonzini , Richard Henderson , Andreas Faerber , Michael Mueller Subject: [Qemu-devel] [PATCH v5 07/17] target-s390x: Generate facility defines per S390 CPU model X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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__GA 0x%016PRIx64,0x%016PRIx64,... Signed-off-by: Michael Mueller --- 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 + * + * 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 +#include +#include +#include +#include +#include +#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; +}