diff options
author | David Hildenbrand <david@redhat.com> | 2017-12-08 17:01:56 +0100 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2017-12-14 17:56:54 +0100 |
commit | 257a119ee3464a0558d47f692fb007b2713e24ec (patch) | |
tree | 6cc73936402fd257779615049a0cca003ade66a2 /target/s390x | |
parent | b8d55db07089493da8cc264ab5991253e1102822 (diff) |
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 <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20171208160207.26494-4-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x')
-rw-r--r-- | target/s390x/helper.h | 1 | ||||
-rw-r--r-- | target/s390x/insn-data.def | 2 | ||||
-rw-r--r-- | target/s390x/misc_helper.c | 11 | ||||
-rw-r--r-- | target/s390x/translate.c | 7 |
4 files changed, 21 insertions, 0 deletions
diff --git a/target/s390x/helper.h b/target/s390x/helper.h index 9459b73c73..3eb7715e5b 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 16e27c8a35..8c2541f545 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 6d766ce1e7..769ec52e1d 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 26cf993405..d13f531c5b 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); |