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>
This commit is contained in:
David Hildenbrand 2017-12-08 17:01:56 +01:00 committed by Cornelia Huck
parent b8d55db070
commit 257a119ee3
4 changed files with 21 additions and 0 deletions

View File

@ -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)

View File

@ -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 */

View File

@ -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)
{

View File

@ -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);