qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 2/7] target-arm: Implement PMCCNTR_EL0 and re


From: Peter Crosthwaite
Subject: Re: [Qemu-devel] [PATCH v2 2/7] target-arm: Implement PMCCNTR_EL0 and related registers
Date: Mon, 18 Aug 2014 13:38:05 +1000

On Sat, Aug 2, 2014 at 1:28 AM, Peter Maydell <address@hidden> wrote:
> On 26 June 2014 06:02, Alistair Francis <address@hidden> wrote:
>> This patch adds support for the ARMv8 version of the PMCCNTR and
>> related registers. It also starts to implement the PMCCFILTR_EL0
>> register.
>>
>> Signed-off-by: Peter Crosthwaite <address@hidden>
>> Signed-off-by: Alistair Francis <address@hidden>
>> ---
>>
>>  target-arm/cpu.h    |    1 +
>>  target-arm/helper.c |   39 +++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 40 insertions(+), 0 deletions(-)
>>
>> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> index cd1c7b6..6a2efd8 100644
>> --- a/target-arm/cpu.h
>> +++ b/target-arm/cpu.h
>> @@ -224,6 +224,7 @@ typedef struct CPUARMState {
>>           * was reset. Otherwise it stores the counter value
>>           */
>>          uint64_t c15_ccnt;
>> +        uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
>>      } cp15;
>>
>>      struct {
>> diff --git a/target-arm/helper.c b/target-arm/helper.c
>> index ac10564..ce986ee 100644
>> --- a/target-arm/helper.c
>> +++ b/target-arm/helper.c
>> @@ -738,7 +738,22 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>>        .writefn = pmcntenset_write,
>>        .accessfn = pmreg_access,
>>        .raw_writefn = raw_write },
>> +    { .name = "PMCNTENSET_EL0", .crn = 9, .crm = 12, .opc0 = 3, .opc1 = 3,
>> +      .opc2 = 1, .access = PL0_RW, .resetvalue = 0,
>> +      .state = ARM_CP_STATE_AA64,
>> +      .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
>
> fieldoffset for an AArch64 register has to point at a uint64_t;
> this is going to read the state next to cp15.c9_pmcnten as
> well, resulting in garbage in half the register. You need to widen
> that field to uint64_t and change the AArch32 accessor to
> use offsetoflow32().
>

Fixed.

>> +      .writefn = pmcntenset_write,
>> +      .accessfn = pmreg_access,
>> +      .raw_writefn = raw_write },
>
> This is a pretty random order for the fields in a reginfo struct
> (though existing code is not great here either).
> Preferred is to put the .name first, then .state, then the
> encoding in the same order as the v8 ARM ARM:
>     .cp [if needed], .opc0, .opc1, .crn, .crm, .opc2
> then .access and .accessfn
> then .fieldoffset and .resetvalue, then read and writefns.
>

Done. I like the new scheme:

 792     { .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64,
 793       .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12,.opc2 = 1,
 794       .access = PL0_RW, .accessfn = pmreg_access,
 795       .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
.resetvalue = 0,
 796       .writefn = pmcntenset_write, .raw_writefn = raw_write },

For completeness where does .type fit in?

>>      { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 
>> = 2,
>> +      .access = PL0_RW,
>> +      .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
>> +      .accessfn = pmreg_access,
>> +      .writefn = pmcntenclr_write,
>> +      .type = ARM_CP_NO_MIGRATE },
>> +    { .name = "PMCNTENCLR_EL0", .crn = 9, .crm = 12, .opc0 = 3, .opc1 = 3,
>> +      .opc2 = 2,
>> +      .state = ARM_CP_STATE_AA64,
>>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, 
>> cp15.c9_pmcnten),
>>        .accessfn = pmreg_access,
>>        .writefn = pmcntenclr_write,
>> @@ -762,11 +777,25 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>>        .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO,
>>        .readfn = pmccntr_read, .writefn = pmccntr_write,
>>        .accessfn = pmreg_access },
>> +    { .name = "PMCCNTR_EL0", .cp = 15, .crn = 9, .crm = 13, .opc1 = 3,
>> +      .opc2 = 0,
>> +      .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO,
>> +      .state = ARM_CP_STATE_AA64,
>> +      .readfn = pmccntr_read, .writefn = pmccntr_write,
>> +      .accessfn = pmreg_access },
>
> The AArch32 reginfo now needs a NO_MIGRATE marker, or we'll
> migrate the underlying state twice.
>

Yep. And ditto for CNTENSET I guess.

> You don't need to specify a .cp for a STATE_AA64 only reginfo.
>
> The ARM ARM says the semantics of a 32 bit write to PMCCNTR
> are to write the lower 32 bits and not touch the high bits. I suspect
> your code will zero them instead. (Maybe this should have been a
> comment on patch 1...)
>

Hmm slightly tricky. Added the RMW logic to do this.

>>  #endif
>> +    { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
>> +      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
>> +      .access = PL0_RW, .accessfn = pmreg_access,
>> +      .state = ARM_CP_STATE_AA64,
>> +      .resetvalue = 0,
>> +      .type = ARM_CP_IO,
>> +      .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0), },
>>      { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 
>> = 1,
>>        .access = PL0_RW,
>>        .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper),
>>        .accessfn = pmreg_access, .writefn = pmxevtyper_write,
>> +      .resetvalue = 0,
>
> This seems like a stray unnecessary change.
>

Dropped.

>>        .raw_writefn = raw_write },
>>      /* Unimplemented, RAZ/WI. */
>>      { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 
>> = 2,
>> @@ -2324,6 +2353,16 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>>              .raw_writefn = raw_write,
>>          };
>>          define_one_arm_cp_reg(cpu, &pmcr);
>> +        ARMCPRegInfo pmcr64 = {
>> +            .name = "PMCR_EL0", .crn = 9, .crm = 12, .opc0 = 3, .opc1 = 3,
>> +            .opc2 = 0,
>> +            .state = ARM_CP_STATE_AA64,
>> +            .access = PL0_RW, .resetvalue = cpu->midr & 0xff000000,
>> +            .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
>> +            .accessfn = pmreg_access, .writefn = pmcr_write,
>> +            .raw_writefn = raw_write,
>> +        };
>
> Don't put variable definitions in the middle of code blocks, please.
>

Fixed. Although we have that problem from CLIDR in the context below.

> Same remarks as above about need for NO_MIGRATE and
> need for widening a uint32_t field apply here.
>

Fixed.

Thanks,

Regards,
Peter

>> +        define_one_arm_cp_reg(cpu, &pmcr64);
>>  #endif
>>          ARMCPRegInfo clidr = {
>>              .name = "CLIDR", .state = ARM_CP_STATE_BOTH,
>> --
>> 1.7.1
>>
>
> thanks
> -- PMM
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]