aboutsummaryrefslogtreecommitdiff
path: root/target/s390x
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-12-20 16:37:07 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-12-20 16:37:07 +0000
commitdd5b0f95490883cd8bc7d070db8de70d5c979cbc (patch)
treeff45eb019527d86b49d0f4a029be602e08914f0d /target/s390x
parentf59b31e6d0c69792b5d817c5aa0a6ed64fba42e0 (diff)
parent104130cb7c106378dab944397c6a455c4a6d552f (diff)
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20191219' into staging
More s390x patches: - tcg: implement LOAD/STORE TO REAL ADDRESS inline - fixes in tests, the bios, and diag308 handling # gpg: Signature made Thu 19 Dec 2019 10:53:19 GMT # gpg: using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF # gpg: issuer "cohuck@redhat.com" # gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [unknown] # gpg: aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full] # gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full] # gpg: aka "Cornelia Huck <cohuck@kernel.org>" [unknown] # gpg: aka "Cornelia Huck <cohuck@redhat.com>" [unknown] # Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF * remotes/cohuck/tags/s390x-20191219: s390x: Properly fetch and test the short psw on diag308 subc 0/1 pc-bios/s390: Update firmware images pc-bios/s390x: Fix reset psw mask tests/boot-sector: Fix the bad s390x assembler code target/s390x: Implement LOAD/STORE TO REAL ADDRESS inline target/s390x: Split out helper_per_store_real Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/s390x')
-rw-r--r--target/s390x/cpu.c12
-rw-r--r--target/s390x/cpu.h1
-rw-r--r--target/s390x/helper.h5
-rw-r--r--target/s390x/insn-data.def8
-rw-r--r--target/s390x/mem_helper.c38
-rw-r--r--target/s390x/misc_helper.c10
-rw-r--r--target/s390x/translate.c21
7 files changed, 34 insertions, 61 deletions
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 99ea09085a..625daeedd1 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -76,8 +76,16 @@ static bool s390_cpu_has_work(CPUState *cs)
static void s390_cpu_load_normal(CPUState *s)
{
S390CPU *cpu = S390_CPU(s);
- cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR;
- cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64;
+ uint64_t spsw = ldq_phys(s->as, 0);
+
+ cpu->env.psw.mask = spsw & 0xffffffff80000000ULL;
+ /*
+ * Invert short psw indication, so SIE will report a specification
+ * exception if it was not set.
+ */
+ cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
+ cpu->env.psw.addr = spsw & 0x7fffffffULL;
+
s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
}
#endif
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index aa829e954c..e195e5c7c8 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -269,6 +269,7 @@ extern const VMStateDescription vmstate_s390_cpu;
#define PSW_MASK_EXT 0x0100000000000000ULL
#define PSW_MASK_KEY 0x00F0000000000000ULL
#define PSW_SHIFT_KEY 52
+#define PSW_MASK_SHORTPSW 0x0008000000000000ULL
#define PSW_MASK_MCHECK 0x0004000000000000ULL
#define PSW_MASK_WAIT 0x0002000000000000ULL
#define PSW_MASK_PSTATE 0x0001000000000000ULL
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 56e8149866..b5813c2ac2 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -324,13 +324,10 @@ DEF_HELPER_FLAGS_4(ipte, TCG_CALL_NO_RWG, void, env, i64, i64, i32)
DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_1(purge, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_2(lra, i64, env, i64)
-DEF_HELPER_FLAGS_2(lura, TCG_CALL_NO_WG, i64, env, i64)
-DEF_HELPER_FLAGS_2(lurag, TCG_CALL_NO_WG, i64, env, i64)
-DEF_HELPER_FLAGS_3(stura, TCG_CALL_NO_WG, void, env, i64, i64)
-DEF_HELPER_FLAGS_3(sturg, TCG_CALL_NO_WG, void, env, i64, i64)
DEF_HELPER_1(per_check_exception, void, env)
DEF_HELPER_FLAGS_3(per_branch, TCG_CALL_NO_RWG, void, env, i64, i64)
DEF_HELPER_FLAGS_2(per_ifetch, TCG_CALL_NO_RWG, void, env, i64)
+DEF_HELPER_FLAGS_1(per_store_real, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_1(stfl, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_2(xsch, void, env, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 449eee1662..2bc77f0871 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1275,8 +1275,8 @@
F(0xe313, LRAY, RXY_a, LD, 0, a2, r1, 0, lra, 0, IF_PRIV)
F(0xe303, LRAG, RXY_a, Z, 0, a2, r1, 0, lra, 0, IF_PRIV)
/* LOAD USING REAL ADDRESS */
- F(0xb24b, LURA, RRE, Z, 0, r2, new, r1_32, lura, 0, IF_PRIV)
- F(0xb905, LURAG, RRE, Z, 0, r2, r1, 0, lurag, 0, IF_PRIV)
+ E(0xb24b, LURA, RRE, Z, 0, 0, new, r1_32, lura, 0, MO_TEUL, IF_PRIV)
+ E(0xb905, LURAG, RRE, Z, 0, 0, r1, 0, lura, 0, MO_TEQ, IF_PRIV)
/* MOVE TO PRIMARY */
F(0xda00, MVCP, SS_d, Z, la1, a2, 0, 0, mvcp, 0, IF_PRIV)
/* MOVE TO SECONDARY */
@@ -1329,8 +1329,8 @@
/* STORE THEN OR SYSTEM MASK */
F(0xad00, STOSM, SI, Z, la1, 0, 0, 0, stnosm, 0, IF_PRIV)
/* STORE USING REAL ADDRESS */
- F(0xb246, STURA, RRE, Z, r1_o, r2_o, 0, 0, stura, 0, IF_PRIV)
- F(0xb925, STURG, RRE, Z, r1_o, r2_o, 0, 0, sturg, 0, IF_PRIV)
+ E(0xb246, STURA, RRE, Z, r1_o, 0, 0, 0, stura, 0, MO_TEUL, IF_PRIV)
+ E(0xb925, STURG, RRE, Z, r1_o, 0, 0, 0, stura, 0, MO_TEQ, IF_PRIV)
/* TEST BLOCK */
F(0xb22c, TB, RRE, Z, 0, r2_o, 0, 0, testblock, 0, IF_PRIV)
/* TEST PROTECTION */
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 2325767f17..2921419c27 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -2329,44 +2329,6 @@ void HELPER(purge)(CPUS390XState *env)
tlb_flush_all_cpus_synced(env_cpu(env));
}
-/* load using real address */
-uint64_t HELPER(lura)(CPUS390XState *env, uint64_t addr)
-{
- return cpu_ldl_real_ra(env, wrap_address(env, addr), GETPC());
-}
-
-uint64_t HELPER(lurag)(CPUS390XState *env, uint64_t addr)
-{
- return cpu_ldq_real_ra(env, wrap_address(env, addr), GETPC());
-}
-
-/* store using real address */
-void HELPER(stura)(CPUS390XState *env, uint64_t addr, uint64_t v1)
-{
- cpu_stl_real_ra(env, wrap_address(env, addr), (uint32_t)v1, GETPC());
-
- if ((env->psw.mask & PSW_MASK_PER) &&
- (env->cregs[9] & PER_CR9_EVENT_STORE) &&
- (env->cregs[9] & PER_CR9_EVENT_STORE_REAL)) {
- /* PSW is saved just before calling the helper. */
- env->per_address = env->psw.addr;
- env->per_perc_atmid = PER_CODE_EVENT_STORE_REAL | get_per_atmid(env);
- }
-}
-
-void HELPER(sturg)(CPUS390XState *env, uint64_t addr, uint64_t v1)
-{
- cpu_stq_real_ra(env, wrap_address(env, addr), v1, GETPC());
-
- if ((env->psw.mask & PSW_MASK_PER) &&
- (env->cregs[9] & PER_CR9_EVENT_STORE) &&
- (env->cregs[9] & PER_CR9_EVENT_STORE_REAL)) {
- /* PSW is saved just before calling the helper. */
- env->per_address = env->psw.addr;
- env->per_perc_atmid = PER_CODE_EVENT_STORE_REAL | get_per_atmid(env);
- }
-}
-
/* load real address */
uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
{
diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
index bfb457fb63..58dbc023eb 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -620,6 +620,16 @@ void HELPER(per_ifetch)(CPUS390XState *env, uint64_t addr)
}
}
}
+
+void HELPER(per_store_real)(CPUS390XState *env)
+{
+ if ((env->cregs[9] & PER_CR9_EVENT_STORE) &&
+ (env->cregs[9] & PER_CR9_EVENT_STORE_REAL)) {
+ /* PSW is saved just before calling the helper. */
+ env->per_address = env->psw.addr;
+ env->per_perc_atmid = PER_CODE_EVENT_STORE_REAL | get_per_atmid(env);
+ }
+}
#endif
static uint8_t stfl_bytes[2048];
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 151dfa91fb..4292bb0dd0 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -3272,13 +3272,8 @@ static DisasJumpType op_lpq(DisasContext *s, DisasOps *o)
#ifndef CONFIG_USER_ONLY
static DisasJumpType op_lura(DisasContext *s, DisasOps *o)
{
- gen_helper_lura(o->out, cpu_env, o->in2);
- return DISAS_NEXT;
-}
-
-static DisasJumpType op_lurag(DisasContext *s, DisasOps *o)
-{
- gen_helper_lurag(o->out, cpu_env, o->in2);
+ o->addr1 = get_address(s, 0, get_field(s->fields, r2), 0);
+ tcg_gen_qemu_ld_tl(o->out, o->addr1, MMU_REAL_IDX, s->insn->data);
return DISAS_NEXT;
}
#endif
@@ -4506,13 +4501,13 @@ static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
static DisasJumpType op_stura(DisasContext *s, DisasOps *o)
{
- gen_helper_stura(cpu_env, o->in2, o->in1);
- return DISAS_NEXT;
-}
+ o->addr1 = get_address(s, 0, get_field(s->fields, r2), 0);
+ tcg_gen_qemu_st_tl(o->in1, o->addr1, MMU_REAL_IDX, s->insn->data);
-static DisasJumpType op_sturg(DisasContext *s, DisasOps *o)
-{
- gen_helper_sturg(cpu_env, o->in2, o->in1);
+ if (s->base.tb->flags & FLAG_MASK_PER) {
+ update_psw_addr(s);
+ gen_helper_per_store_real(cpu_env);
+ }
return DISAS_NEXT;
}
#endif