[v1,for-2.12,3/5] s390x/tcg: implement SET CLOCK PROGRAMMABLE FIELD

Message ID 20171204125505.29203-4-david@redhat.com
State New
Headers show
Series
  • s390x/tcg: CCW hotplug support
Related show

Commit Message

David Hildenbrand Dec. 4, 2017, 12:55 p.m.
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. Suficient for now.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 target/s390x/helper.h      |  1 +
 target/s390x/insn-data.def |  2 ++
 target/s390x/misc_helper.c | 11 +++++++++++
 target/s390x/translate.c   |  7 +++++++
 4 files changed, 21 insertions(+)

Comments

Cornelia Huck Dec. 5, 2017, 11:05 a.m. | #1
On Mon,  4 Dec 2017 13:55:03 +0100
David Hildenbrand <david@redhat.com> wrote:

> 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. Suficient for now.

s/Suficient/Sufficient/

> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  target/s390x/helper.h      |  1 +
>  target/s390x/insn-data.def |  2 ++
>  target/s390x/misc_helper.c | 11 +++++++++++
>  target/s390x/translate.c   |  7 +++++++
>  4 files changed, 21 insertions(+)

Looks good to me.
Thomas Huth Dec. 6, 2017, 3:10 p.m. | #2
On 04.12.2017 13:55, David Hildenbrand wrote:
> 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. Suficient for now.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
[...]
> diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
> index 6d766ce1e7..2c6ab329fb 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)
> +{
> +    uint32_t val = env->regs[0];
> +
> +    if (val & 0xffff0000UL) {

I think you could drop the "UL" suffix here.

> +        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..48b031894a 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);
> +    return NO_EXIT;
> +}
> +
>  static ExitStatus op_stckc(DisasContext *s, DisasOps *o)
>  {
>      check_privileged(s);
> 

Reviewed-by: Thomas Huth <thuth@redhat.com>
David Hildenbrand Dec. 6, 2017, 3:15 p.m. | #3
On 06.12.2017 16:10, Thomas Huth wrote:
> On 04.12.2017 13:55, David Hildenbrand wrote:
>> 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. Suficient for now.
>>
>> Signed-off-by: David Hildenbrand <david@redhat.com>
>> ---
> [...]
>> diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
>> index 6d766ce1e7..2c6ab329fb 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)
>> +{
>> +    uint32_t val = env->regs[0];
>> +
>> +    if (val & 0xffff0000UL) {
> 
> I think you could drop the "UL" suffix here.
> 

Indeed, we should be fine as long as this fits into an int thanks!

Patch

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 9459b73c73..0281c286b8 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_1(sckpf, TCG_CALL_NO_RWG, void, env)
 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..2c6ab329fb 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)
+{
+    uint32_t val = env->regs[0];
+
+    if (val & 0xffff0000UL) {
+        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..48b031894a 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);
+    return NO_EXIT;
+}
+
 static ExitStatus op_stckc(DisasContext *s, DisasOps *o)
 {
     check_privileged(s);