From: David Hildenbrand Date: Fri, 8 Dec 2017 16:01:56 +0000 (+0100) Subject: s390x/tcg: implement SET CLOCK PROGRAMMABLE FIELD X-Git-Tag: v2.12.0-rc0~193^2~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=257a119ee3464a0558d47f692fb007b2713e24ec;p=thirdparty%2Fqemu.git s390x/tcg: implement SET CLOCK PROGRAMMABLE FIELD Needed for machine check handling inside Linux (when restoring registers). Except for SIGP and machine checks, we don't make use of the register yet. Sufficient for now. Reviewed-by: Thomas Huth Signed-off-by: David Hildenbrand Message-Id: <20171208160207.26494-4-david@redhat.com> Reviewed-by: Richard Henderson Signed-off-by: Cornelia Huck --- diff --git a/target/s390x/helper.h b/target/s390x/helper.h index 9459b73c732..3eb7715e5bc 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -127,6 +127,7 @@ 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) DEF_HELPER_FLAGS_2(sckc, TCG_CALL_NO_RWG, void, env, i64) +DEF_HELPER_FLAGS_2(sckpf, TCG_CALL_NO_RWG, void, env, i64) DEF_HELPER_FLAGS_1(stckc, TCG_CALL_NO_RWG, i64, env) DEF_HELPER_FLAGS_2(spt, TCG_CALL_NO_RWG, void, env, i64) DEF_HELPER_FLAGS_1(stpt, TCG_CALL_NO_RWG, i64, env) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index 16e27c8a351..8c2541f5453 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -999,6 +999,8 @@ C(0xb204, SCK, S, Z, 0, 0, 0, 0, 0, 0) /* SET CLOCK COMPARATOR */ C(0xb206, SCKC, S, Z, 0, m2_64, 0, 0, sckc, 0) +/* SET CLOCK PROGRAMMABLE FIELD */ + C(0x0107, SCKPF, E, Z, 0, 0, 0, 0, sckpf, 0) /* SET CPU TIMER */ C(0xb208, SPT, S, Z, 0, m2_64, 0, 0, spt, 0) /* SET PREFIX */ diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c index 6d766ce1e70..769ec52e1db 100644 --- a/target/s390x/misc_helper.c +++ b/target/s390x/misc_helper.c @@ -146,6 +146,17 @@ void HELPER(sckc)(CPUS390XState *env, uint64_t time) timer_mod(env->tod_timer, env->tod_basetime + time); } +/* Set Tod Programmable Field */ +void HELPER(sckpf)(CPUS390XState *env, uint64_t r0) +{ + uint32_t val = r0; + + if (val & 0xffff0000) { + s390_program_interrupt(env, PGM_SPECIFICATION, 2, GETPC()); + } + env->todpr = val; +} + /* Store Clock Comparator */ uint64_t HELPER(stckc)(CPUS390XState *env) { diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 26cf9934052..d13f531c5be 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -3922,6 +3922,13 @@ static ExitStatus op_sckc(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_sckpf(DisasContext *s, DisasOps *o) +{ + check_privileged(s); + gen_helper_sckpf(cpu_env, regs[0]); + return NO_EXIT; +} + static ExitStatus op_stckc(DisasContext *s, DisasOps *o) { check_privileged(s);