diff options
author | David Hildenbrand <david@redhat.com> | 2019-06-04 11:30:07 +0200 |
---|---|---|
committer | David Hildenbrand <david@redhat.com> | 2019-06-07 14:53:26 +0200 |
commit | 6d88baf18653ff8826db3dd840a6b372d3477280 (patch) | |
tree | 26f5238962af64416ee93aea4072c79fa33b5879 | |
parent | 37c70c43dc29b764969cd8b704fbf946fcc2ef5a (diff) |
linux-user: elf: ELF_HWCAP for s390x
Let's add all HWCAPs that we can support under TCG right now, when the
respective CPU facilities are enabled.
Cc: Riku Voipio <riku.voipio@iki.fi>
Cc: Laurent Vivier <laurent@vivier.eu>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Laurent Vivier <laurent@vivier.eu>
Cc: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
-rw-r--r-- | include/elf.h | 1 | ||||
-rw-r--r-- | linux-user/elfload.c | 28 |
2 files changed, 29 insertions, 0 deletions
diff --git a/include/elf.h b/include/elf.h index ea7708a4ea..3501e0c8d0 100644 --- a/include/elf.h +++ b/include/elf.h @@ -598,6 +598,7 @@ typedef struct { #define HWCAP_S390_ETF3EH 256 #define HWCAP_S390_HIGH_GPRS 512 #define HWCAP_S390_TE 1024 +#define HWCAP_S390_VXRS 2048 /* M68K specific definitions. */ /* We use the top 24 bits to encode information about the diff --git a/linux-user/elfload.c b/linux-user/elfload.c index a57b7049dd..5451d262ec 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1308,6 +1308,34 @@ static inline void init_thread(struct target_pt_regs *regs, #define ELF_DATA ELFDATA2MSB #define ELF_ARCH EM_S390 +#include "elf.h" + +#define ELF_HWCAP get_elf_hwcap() + +#define GET_FEATURE(_feat, _hwcap) \ + do { if (s390_has_feat(_feat)) { hwcap |= _hwcap; } } while (0) + +static uint32_t get_elf_hwcap(void) +{ + /* + * Let's assume we always have esan3 and zarch. + * 31-bit processes can use 64-bit registers (high gprs). + */ + uint32_t hwcap = HWCAP_S390_ESAN3 | HWCAP_S390_ZARCH | HWCAP_S390_HIGH_GPRS; + + GET_FEATURE(S390_FEAT_STFLE, HWCAP_S390_STFLE); + GET_FEATURE(S390_FEAT_MSA, HWCAP_S390_MSA); + GET_FEATURE(S390_FEAT_LONG_DISPLACEMENT, HWCAP_S390_LDISP); + GET_FEATURE(S390_FEAT_EXTENDED_IMMEDIATE, HWCAP_S390_EIMM); + if (s390_has_feat(S390_FEAT_EXTENDED_TRANSLATION_3) && + s390_has_feat(S390_FEAT_ETF3_ENH)) { + hwcap |= HWCAP_S390_ETF3EH; + } + GET_FEATURE(S390_FEAT_VECTOR, HWCAP_S390_VXRS); + + return hwcap; +} + static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) { regs->psw.addr = infop->entry; |