diff mbox

[PULL,03/12] target-arm: Add support for PMU register PMINTENSET_EL1

Message ID 1486750082-12324-4-git-send-email-peter.maydell@linaro.org
State New
Headers show

Commit Message

Peter Maydell Feb. 10, 2017, 6:07 p.m. UTC
From: Wei Huang <wei@redhat.com>

This patch adds access support for PMINTENSET_EL1.

Signed-off-by: Wei Huang <wei@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1486504171-26807-4-git-send-email-wei@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h    |  2 +-
 target/arm/helper.c | 10 +++++++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

Comments

Aaron Lindsay Feb. 23, 2017, 1:58 p.m. UTC | #1
Wei, Peter,

On Feb 10 18:07, Peter Maydell wrote:
> From: Wei Huang <wei@redhat.com>
> 
> This patch adds access support for PMINTENSET_EL1.
> 
> Signed-off-by: Wei Huang <wei@redhat.com>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Message-id: 1486504171-26807-4-git-send-email-wei@redhat.com
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h    |  2 +-
>  target/arm/helper.c | 10 +++++++++-
>  2 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index edc1f76..0956a54 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -309,7 +309,7 @@ typedef struct CPUARMState {
>          uint32_t c9_pmovsr; /* perf monitor overflow status */
>          uint32_t c9_pmuserenr; /* perf monitor user enable */
>          uint64_t c9_pmselr; /* perf monitor counter selection register */
> -        uint32_t c9_pminten; /* perf monitor interrupt enables */
> +        uint64_t c9_pminten; /* perf monitor interrupt enables */

PMINTENSET_EL1 and PMINTENCLR_EL1 are both 32-bit registers, just like
their AArch32 counterparts. Is there a reason I'm missing for why this
has been changed to a uint64_t? There are a number of other 32-bit PMU
registers also currently being represented by uint64_t.

-Aaron

>          union { /* Memory attribute redirection */
>              struct {
>  #ifdef HOST_WORDS_BIGENDIAN
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index b837d36..5358ac6 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -1275,9 +1275,17 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>        .writefn = pmuserenr_write, .raw_writefn = raw_write },
>      { .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
>        .access = PL1_RW, .accessfn = access_tpm,
> -      .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
> +      .type = ARM_CP_ALIAS,
> +      .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
>        .resetvalue = 0,
>        .writefn = pmintenset_write, .raw_writefn = raw_write },
> +    { .name = "PMINTENSET_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 1,
> +      .access = PL1_RW, .accessfn = access_tpm,
> +      .type = ARM_CP_IO,
> +      .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
> +      .writefn = pmintenset_write, .raw_writefn = raw_write,
> +      .resetvalue = 0x0 },
>      { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2,
>        .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
>        .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
> -- 
> 2.7.4
> 
>
Peter Maydell Feb. 23, 2017, 2:49 p.m. UTC | #2
On 23 February 2017 at 13:58, Aaron Lindsay <alindsay@codeaurora.org> wrote:
> Wei, Peter,
>
> On Feb 10 18:07, Peter Maydell wrote:
>> From: Wei Huang <wei@redhat.com>
>>
>> This patch adds access support for PMINTENSET_EL1.
>>
>> Signed-off-by: Wei Huang <wei@redhat.com>
>> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>> Message-id: 1486504171-26807-4-git-send-email-wei@redhat.com
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>  target/arm/cpu.h    |  2 +-
>>  target/arm/helper.c | 10 +++++++++-
>>  2 files changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>> index edc1f76..0956a54 100644
>> --- a/target/arm/cpu.h
>> +++ b/target/arm/cpu.h
>> @@ -309,7 +309,7 @@ typedef struct CPUARMState {
>>          uint32_t c9_pmovsr; /* perf monitor overflow status */
>>          uint32_t c9_pmuserenr; /* perf monitor user enable */
>>          uint64_t c9_pmselr; /* perf monitor counter selection register */
>> -        uint32_t c9_pminten; /* perf monitor interrupt enables */
>> +        uint64_t c9_pminten; /* perf monitor interrupt enables */
>
> PMINTENSET_EL1 and PMINTENCLR_EL1 are both 32-bit registers, just like
> their AArch32 counterparts. Is there a reason I'm missing for why this
> has been changed to a uint64_t? There are a number of other 32-bit PMU
> registers also currently being represented by uint64_t.

Two reasons:

 (1) The conceptual reason. In AArch64 "32-bit system register" is just
a convenient shorthand for "64-bit system register where the upper 32
bits are RAZ/WI". The register itself is still 64 bits and in a future
architecture revision it might end up with defined bits in the upper
half (this has happened already for a few registers).

 (2) The QEMU implementation reason. The way we implement system register
access instructions typically ends up in generating a simple "load/store
64 bit value from address" instruction. Rather than having the generic
"handle a system register access" code  have two codepaths to cope with
"64-bit sysreg that's stored in a 32-bit field" and "64-bit sysreg that's
stored in a 64-bit field", we choose to require that the fields are always
64-bits wide, so that the code that accesses them doesn't have to care.

(The implementation reason derives from the conceptual reason:
architecturally there is no real different "32-bit system register"
concept, so we don't need to implement handling differently. For
AArch32 we do distinguish between 32-bit and 64-bit coprocessor
registers, because they're really different things and need
different handling.)

thanks
-- PMM
diff mbox

Patch

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index edc1f76..0956a54 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -309,7 +309,7 @@  typedef struct CPUARMState {
         uint32_t c9_pmovsr; /* perf monitor overflow status */
         uint32_t c9_pmuserenr; /* perf monitor user enable */
         uint64_t c9_pmselr; /* perf monitor counter selection register */
-        uint32_t c9_pminten; /* perf monitor interrupt enables */
+        uint64_t c9_pminten; /* perf monitor interrupt enables */
         union { /* Memory attribute redirection */
             struct {
 #ifdef HOST_WORDS_BIGENDIAN
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b837d36..5358ac6 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1275,9 +1275,17 @@  static const ARMCPRegInfo v7_cp_reginfo[] = {
       .writefn = pmuserenr_write, .raw_writefn = raw_write },
     { .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
       .access = PL1_RW, .accessfn = access_tpm,
-      .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
+      .type = ARM_CP_ALIAS,
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
       .resetvalue = 0,
       .writefn = pmintenset_write, .raw_writefn = raw_write },
+    { .name = "PMINTENSET_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 1,
+      .access = PL1_RW, .accessfn = access_tpm,
+      .type = ARM_CP_IO,
+      .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
+      .writefn = pmintenset_write, .raw_writefn = raw_write,
+      .resetvalue = 0x0 },
     { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2,
       .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),