summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target-s390x/helper.h2
-rw-r--r--target-s390x/insn-data.def2
-rw-r--r--target-s390x/misc_helper.c13
-rw-r--r--target-s390x/translate.c16
4 files changed, 20 insertions, 13 deletions
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index 7e048ecb00..6be9f44aec 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -87,7 +87,7 @@ DEF_HELPER_FLAGS_1(popcnt, TCG_CALL_NO_RWG_SE, i64, i64)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_3(servc, i32, env, i64, i64)
-DEF_HELPER_4(diag, i64, env, i32, i64, i64)
+DEF_HELPER_4(diag, void, env, i32, i32, i32)
DEF_HELPER_3(load_psw, noreturn, env, i64, i64)
DEF_HELPER_FLAGS_2(spx, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_FLAGS_1(stck, TCG_CALL_NO_RWG_SE, i64, env)
diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
index 1223670721..fe5e591e9c 100644
--- a/target-s390x/insn-data.def
+++ b/target-s390x/insn-data.def
@@ -835,7 +835,7 @@
/* COMPARE AND SWAP AND PURGE */
C(0xb250, CSP, RRE, Z, 0, ra2, 0, 0, csp, 0)
/* DIAGNOSE (KVM hypercall) */
- C(0x8300, DIAG, RX_a, Z, 0, 0, 0, 0, diag, 0)
+ C(0x8300, DIAG, RSI, Z, 0, 0, 0, 0, diag, 0)
/* INSERT STORAGE KEY EXTENDED */
C(0xb229, ISKE, RRE, Z, 0, r2_o, new, r1_8, iske, 0)
/* INVALIDATE PAGE TABLE ENTRY */
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 6711504221..eebe608ba3 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -205,9 +205,15 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
switch (subcode) {
case 0:
modified_clear_reset(s390_env_get_cpu(env));
+ if (tcg_enabled()) {
+ cpu_loop_exit(CPU(s390_env_get_cpu(env)));
+ }
break;
case 1:
load_normal_reset(s390_env_get_cpu(env));
+ if (tcg_enabled()) {
+ cpu_loop_exit(CPU(s390_env_get_cpu(env)));
+ }
break;
case 5:
if ((r1 & 1) || (addr & 0x0fffULL)) {
@@ -254,9 +260,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
}
#endif
-/* DIAG */
-uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
- uint64_t code)
+void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
{
uint64_t r;
@@ -271,6 +275,7 @@ uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
break;
case 0x308:
/* ipl */
+ handle_diag_308(env, r1, r3);
r = 0;
break;
default:
@@ -281,8 +286,6 @@ uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
if (r) {
program_interrupt(env, PGM_OPERATION, ILEN_LATER_INC);
}
-
- return r;
}
/* Set Prefix */
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 9b877148c6..bde5e8a055 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -2025,15 +2025,19 @@ static ExitStatus op_ct(DisasContext *s, DisasOps *o)
#ifndef CONFIG_USER_ONLY
static ExitStatus op_diag(DisasContext *s, DisasOps *o)
{
- TCGv_i32 tmp;
+ TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
+ TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
+ TCGv_i32 func_code = tcg_const_i32(get_field(s->fields, i2));
check_privileged(s);
- potential_page_fault(s);
+ update_psw_addr(s);
+ gen_op_calc_cc(s);
- /* We pretend the format is RX_a so that D2 is the field we want. */
- tmp = tcg_const_i32(get_field(s->fields, d2) & 0xfff);
- gen_helper_diag(regs[2], cpu_env, tmp, regs[2], regs[1]);
- tcg_temp_free_i32(tmp);
+ gen_helper_diag(cpu_env, r1, r3, func_code);
+
+ tcg_temp_free_i32(func_code);
+ tcg_temp_free_i32(r3);
+ tcg_temp_free_i32(r1);
return NO_EXIT;
}
#endif