aboutsummaryrefslogtreecommitdiff
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
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>
-rw-r--r--pc-bios/s390-ccw.imgbin42608 -> 42608 bytes
-rw-r--r--pc-bios/s390-ccw/jump2ipl.c12
-rw-r--r--pc-bios/s390-netboot.imgbin67232 -> 67232 bytes
-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
-rw-r--r--tests/boot-sector.c4
11 files changed, 43 insertions, 68 deletions
diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index c84ae93561..91cdee4436 100644
--- a/pc-bios/s390-ccw.img
+++ b/pc-bios/s390-ccw.img
Binary files differ
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
index 266f1502b9..da13c43cc0 100644
--- a/pc-bios/s390-ccw/jump2ipl.c
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -12,11 +12,11 @@
#define KERN_IMAGE_START 0x010000UL
#define PSW_MASK_64 0x0000000100000000ULL
#define PSW_MASK_32 0x0000000080000000ULL
-#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
+#define PSW_MASK_SHORTPSW 0x0008000000000000ULL
+#define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_32 | PSW_MASK_64)
typedef struct ResetInfo {
- uint32_t ipl_mask;
- uint32_t ipl_addr;
+ uint64_t ipl_psw;
uint32_t ipl_continue;
} ResetInfo;
@@ -50,7 +50,9 @@ void jump_to_IPL_code(uint64_t address)
ResetInfo *current = 0;
save = *current;
- current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2;
+
+ current->ipl_psw = (uint64_t) &jump_to_IPL_2;
+ current->ipl_psw |= RESET_PSW_MASK;
current->ipl_continue = address & 0x7fffffff;
debug_print_int("set IPL addr to", current->ipl_continue);
@@ -82,7 +84,7 @@ void jump_to_low_kernel(void)
}
/* Trying to get PSW at zero address */
- if (*((uint64_t *)0) & IPL_PSW_MASK) {
+ if (*((uint64_t *)0) & RESET_PSW_MASK) {
jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
}
diff --git a/pc-bios/s390-netboot.img b/pc-bios/s390-netboot.img
index f9ef28ef1a..6bb5c86eb0 100644
--- a/pc-bios/s390-netboot.img
+++ b/pc-bios/s390-netboot.img
Binary files differ
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
diff --git a/tests/boot-sector.c b/tests/boot-sector.c
index 7824286b9a..9e66c6d013 100644
--- a/tests/boot-sector.c
+++ b/tests/boot-sector.c
@@ -75,11 +75,11 @@ static const uint8_t s390x_psw_and_magic[] = {
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* in the s390-ccw bios */
};
static const uint8_t s390x_code[] = {
- 0xa7, 0xf4, 0x00, 0x0a, /* j 0x10010 */
+ 0xa7, 0xf4, 0x00, 0x08, /* j 0x10010 */
0x00, 0x00, 0x00, 0x00,
'S', '3', '9', '0',
'E', 'P', 0x00, 0x01,
- 0xa7, 0x38, HIGH(SIGNATURE_ADDR), LOW(SIGNATURE_ADDR), /* lhi r3,0x7c10 */
+ 0xa7, 0x39, HIGH(SIGNATURE_ADDR), LOW(SIGNATURE_ADDR), /* lghi r3,0x7c10 */
0xa7, 0x48, LOW(SIGNATURE), HIGH(SIGNATURE), /* lhi r4,0xadde */
0x40, 0x40, 0x30, 0x00, /* sth r4,0(r3) */
0xa7, 0xf4, 0xff, 0xfa /* j 0x10010 */