diff options
Diffstat (limited to 'linux-user/s390x')
| -rw-r--r-- | linux-user/s390x/cpu_loop.c | 15 | ||||
| -rw-r--r-- | linux-user/s390x/elfload.c | 68 | ||||
| -rw-r--r-- | linux-user/s390x/target_elf.h | 7 | ||||
| -rw-r--r-- | linux-user/s390x/target_proc.h | 2 |
4 files changed, 80 insertions, 12 deletions
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c index c9124444ed..49e44548f8 100644 --- a/linux-user/s390x/cpu_loop.c +++ b/linux-user/s390x/cpu_loop.c @@ -180,12 +180,13 @@ void cpu_loop(CPUS390XState *env) } } -void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs) +void init_main_thread(CPUState *cs, struct image_info *info) { - int i; - for (i = 0; i < 16; i++) { - env->regs[i] = regs->gprs[i]; - } - env->psw.mask = regs->psw.mask; - env->psw.addr = regs->psw.addr; + CPUArchState *env = cpu_env(cs); + + env->psw.addr = info->entry; + env->psw.mask = PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | + PSW_MASK_MCHECK | PSW_MASK_PSTATE | PSW_MASK_64 | + PSW_MASK_32; + env->regs[15] = info->start_stack; } diff --git a/linux-user/s390x/elfload.c b/linux-user/s390x/elfload.c new file mode 100644 index 0000000000..79ceaba51d --- /dev/null +++ b/linux-user/s390x/elfload.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "qemu/osdep.h" +#include "qemu.h" +#include "loader.h" +#include "elf.h" + + +const char *get_elf_cpu_model(uint32_t eflags) +{ + return "qemu"; +} + +#define GET_FEATURE(_feat, _hwcap) \ + do { if (s390_has_feat(_feat)) { hwcap |= _hwcap; } } while (0) + +abi_ulong get_elf_hwcap(CPUState *cs) +{ + /* + * 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); + GET_FEATURE(S390_FEAT_VECTOR_ENH, HWCAP_S390_VXRS_EXT); + GET_FEATURE(S390_FEAT_VECTOR_ENH2, HWCAP_S390_VXRS_EXT2); + + return hwcap; +} + +const char *elf_hwcap_str(uint32_t bit) +{ + static const char *hwcap_str[] = { + [HWCAP_S390_NR_ESAN3] = "esan3", + [HWCAP_S390_NR_ZARCH] = "zarch", + [HWCAP_S390_NR_STFLE] = "stfle", + [HWCAP_S390_NR_MSA] = "msa", + [HWCAP_S390_NR_LDISP] = "ldisp", + [HWCAP_S390_NR_EIMM] = "eimm", + [HWCAP_S390_NR_DFP] = "dfp", + [HWCAP_S390_NR_HPAGE] = "edat", + [HWCAP_S390_NR_ETF3EH] = "etf3eh", + [HWCAP_S390_NR_HIGH_GPRS] = "highgprs", + [HWCAP_S390_NR_TE] = "te", + [HWCAP_S390_NR_VXRS] = "vx", + [HWCAP_S390_NR_VXRS_BCD] = "vxd", + [HWCAP_S390_NR_VXRS_EXT] = "vxe", + [HWCAP_S390_NR_GS] = "gs", + [HWCAP_S390_NR_VXRS_EXT2] = "vxe2", + [HWCAP_S390_NR_VXRS_PDE] = "vxp", + [HWCAP_S390_NR_SORT] = "sort", + [HWCAP_S390_NR_DFLT] = "dflt", + [HWCAP_S390_NR_NNPA] = "nnpa", + [HWCAP_S390_NR_PCI_MIO] = "pcimio", + [HWCAP_S390_NR_SIE] = "sie", + }; + + return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL; +} diff --git a/linux-user/s390x/target_elf.h b/linux-user/s390x/target_elf.h index 8114b59c1d..cebace949a 100644 --- a/linux-user/s390x/target_elf.h +++ b/linux-user/s390x/target_elf.h @@ -7,8 +7,7 @@ #ifndef S390X_TARGET_ELF_H #define S390X_TARGET_ELF_H -static inline const char *cpu_get_model(uint32_t eflags) -{ - return "qemu"; -} + +#define HAVE_ELF_HWCAP 1 + #endif diff --git a/linux-user/s390x/target_proc.h b/linux-user/s390x/target_proc.h index a4a4821ea5..60cc22d3b4 100644 --- a/linux-user/s390x/target_proc.h +++ b/linux-user/s390x/target_proc.h @@ -48,7 +48,7 @@ static void show_cpu_summary(CPUArchState *cpu_env, int fd) { S390CPUModel *model = env_archcpu(cpu_env)->model; int num_cpus = sysconf(_SC_NPROCESSORS_ONLN); - uint32_t elf_hwcap = get_elf_hwcap(); + uint32_t elf_hwcap = get_elf_hwcap(env_cpu(cpu_env)); const char *hwcap_str; int i; |