diff options
author | David Hildenbrand <david@redhat.com> | 2018-09-27 15:02:56 +0200 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2018-10-04 10:32:39 +0200 |
commit | bbf6ea3bd961970785a583117ac1c0b84a8ee736 (patch) | |
tree | 8c00137c06cfbdbec9a51a6b0fe09e2d7d147052 /target/s390x/excp_helper.c | |
parent | 52341ed61d3a7b84602f6ee6b4234027ed5e6172 (diff) |
s390x/tcg: factor out and fix DATA exception injection
The DXC is to be stored in the low core, and only in the FPC in case AFP
is enabled in CR0. Stub is not required in current code, but this way
we never run into problems.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180927130303.12236-3-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/excp_helper.c')
-rw-r--r-- | target/s390x/excp_helper.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c index 5dab3387c3..cd76c3163a 100644 --- a/target/s390x/excp_helper.c +++ b/target/s390x/excp_helper.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "internal.h" +#include "exec/helper-proto.h" #include "qemu/timer.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" @@ -61,6 +62,28 @@ void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code, cpu_loop_exit(cs); } +void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc, + uintptr_t ra) +{ + g_assert(dxc <= 0xff); +#if !defined(CONFIG_USER_ONLY) + /* Store the DXC into the lowcore */ + stl_phys(CPU(s390_env_get_cpu(env))->as, + env->psa + offsetof(LowCore, data_exc_code), dxc); +#endif + + /* Store the DXC into the FPC if AFP is enabled */ + if (env->cregs[0] & CR0_AFP) { + env->fpc = deposit32(env->fpc, 8, 8, dxc); + } + tcg_s390_program_interrupt(env, PGM_DATA, ILEN_AUTO, ra); +} + +void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc) +{ + tcg_s390_data_exception(env, dxc, GETPC()); +} + #if defined(CONFIG_USER_ONLY) void s390_cpu_do_interrupt(CPUState *cs) |