[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v8 07/27] target-arm: insert AArch32 cpregs twic
From: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [PATCH v8 07/27] target-arm: insert AArch32 cpregs twice into hashtable |
Date: |
Fri, 31 Oct 2014 12:44:48 +0000 |
On 30 October 2014 21:28, Greg Bellows <address@hidden> wrote:
> From: Fabian Aggeler <address@hidden>
>
> Prepare for cp register banking by inserting every cp register twice,
> once for secure world and once for non-secure world.
>
> Signed-off-by: Fabian Aggeler <address@hidden>
> Signed-off-by: Greg Bellows <address@hidden>
>
> ---
>
> v7 -> v8
> - Updated define registers asserts to allow either a non-zero fieldoffset or
> non-zero bank_fieldoffsets.
> - Updated CP register hashing to always set the register fieldoffset when
> banked register offsets are specified.
>
> v5 -> v6
> - Fixed NS-bit number in the CPREG hash lookup from 27 to 29.
> - Switched to dedicated CPREG secure flags.
> - Fixed disablement of reset and migration of common 32/64-bit registers.
> - Globally replace Aarch# with AArch#
>
> v4 -> v5
> - Added use of ARM CP secure/non-secure bank flags during register processing
> in define_one_arm_cp_reg_with_opaque(). We now only register the specified
> bank if only one flag is specified, otherwise we register both a secure and
> non-secure instance.
> ---
> target-arm/helper.c | 98
> ++++++++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 82 insertions(+), 16 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 959a46e..c1c6303 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3296,22 +3296,62 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const
> ARMCPRegInfo *r,
> uint32_t *key = g_new(uint32_t, 1);
> ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
> int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
> - if (r->state == ARM_CP_STATE_BOTH && state == ARM_CP_STATE_AA32) {
> - /* The AArch32 view of a shared register sees the lower 32 bits
> - * of a 64 bit backing field. It is not migratable as the AArch64
> - * view handles that. AArch64 also handles reset.
> - * We assume it is a cp15 register if the .cp field is left unset.
> +
> + if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
> + /* Register is banked (using both entries in array).
> + * Overwriting fieldoffset as the array is only used to define
> + * banked registers but later only fieldoffset is used.
> */
> - if (r2->cp == 0) {
> - r2->cp = 15;
> + r2->fieldoffset = r->bank_fieldoffsets[nsbit];
> + }
> +
> + if (state == ARM_CP_STATE_AA32) {
> + /* Clear the secure state flags and set based on incoming nsbit */
> + r2->secure &= ~(ARM_CP_SECSTATE_S | ARM_CP_SECSTATE_NS);
> + r2->secure |= ARM_CP_SECSTATE_S << nsbit;
This bitmanipulation looks like leftover from when these were in 'state';
r2->secure = secstate;
should be sufficient (and you might as well put this down below the
'r2->state = state' assignment, since it's harmless to do it for all
regdefs including 64 bit ones).
> +
> + if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
> + /* If the register is banked and V8 is enabled then we don't need
> + * to migrate or reset the AArch32 version of the banked
> + * registers as this will be handled through the AArch64 view.
> + * If v7 then we don't need to migrate or reset the AArch32
> + * non-secure bank as this will be handled through the AArch64
> + * view. In this case the secure bank is not mirrored, so we
> must
> + * preserve it's reset criteria and allow it to be migrated.
> + *
> + * The exception to the above is cpregs with a crn of 13
> + * (specifically FCSEIDR and CONTEXTIDR) in which case there may
> + * not be an AArch64 equivalent for one or either bank so
> migration
> + * and reset must be preserved.
> + */
I'm not sure what this paragraph is trying to say. The AArch64 equivalent
of CONTEXTIDR(NS) is CONTEXTIDR_EL1. In v8 FCSEIDR is a constant RAZ/WI
register, so migration and reset aren't relevant anyway.
In any case, if we only have a couple of special case registers where
this bank handling doesn't work, I suggest that we should handle them
by having two separate reginfo structs for the S and NS versions,
rather than special casing a specific crn value here.
> + if (r->state == ARM_CP_STATE_BOTH) {
> + if ((arm_feature(&cpu->env, ARM_FEATURE_V8) && r->crn != 13)
> ||
> + nsbit) {
> + r2->type |= ARM_CP_NO_MIGRATE;
> + r2->resetfn = arm_cp_reset_ignore;
> + }
> + }
> + } else if (!nsbit) {
> + /* The register is not banked so we only want to allow migration
> of
> + * the non-secure instance.
> + */
> + r2->type |= ARM_CP_NO_MIGRATE;
> + r2->resetfn = arm_cp_reset_ignore;
> }
> - r2->type |= ARM_CP_NO_MIGRATE;
> - r2->resetfn = arm_cp_reset_ignore;
> +
> + if (r->state == ARM_CP_STATE_BOTH) {
> + /* We assume it is a cp15 register if the .cp field is left
> unset.
> + */
> + if (r2->cp == 0) {
> + r2->cp = 15;
> + }
> +
> #ifdef HOST_WORDS_BIGENDIAN
> - if (r2->fieldoffset) {
> - r2->fieldoffset += sizeof(uint32_t);
> - }
> + if (r2->fieldoffset) {
> + r2->fieldoffset += sizeof(uint32_t);
> + }
> #endif
> + }
> }
> if (state == ARM_CP_STATE_AA64) {
> /* To allow abbreviation of ARMCPRegInfo
> @@ -3460,10 +3500,14 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
> */
> if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
> if (r->access & PL3_R) {
> - assert(r->fieldoffset || r->readfn);
> + assert((r->fieldoffset ||
> + (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
> + r->readfn);
> }
> if (r->access & PL3_W) {
> - assert(r->fieldoffset || r->writefn);
> + assert((r->fieldoffset ||
> + (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
> + r->writefn);
> }
> }
> /* Bad type field probably means missing sentinel at end of reg list */
> @@ -3476,8 +3520,30 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
> if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
> continue;
> }
> - add_cpreg_to_hashtable(cpu, r, opaque, state,
> - crm, opc1, opc2, SCR_NS);
> + if (state == ARM_CP_STATE_AA32) {
> + /* Under AArch32 CP registers can be common
> + * (same for secure and non-secure world) or banked.
> + */
> + uint32_t s =
> + r->secure & (ARM_CP_SECSTATE_S |
> ARM_CP_SECSTATE_NS);
> + if (ARM_CP_SECSTATE_S == s) {
As a general remark, don't use this sort of "yoda conditional" with the
constant on the LHS of the ==, please.
> + add_cpreg_to_hashtable(cpu, r, opaque, state,
> + crm, opc1, opc2, !SCR_NS);
> + } else if (ARM_CP_SECSTATE_NS == s) {
> + add_cpreg_to_hashtable(cpu, r, opaque, state,
> + crm, opc1, opc2, SCR_NS);
> + } else {
> + add_cpreg_to_hashtable(cpu, r, opaque, state,
> + crm, opc1, opc2, !SCR_NS);
> + add_cpreg_to_hashtable(cpu, r, opaque, state,
> + crm, opc1, opc2, SCR_NS);
> + }
Given the change to make add_cpreg_to_hashtable() take an ARM_CP_SECSTATE*
constant that I suggested in the previous patch, you can simplify this to
switch (r->secure) {
case ARM_CP_SECSTATE_S:
case ARM_CP_SECSTATE_NS:
add_cpreg_to_hashtable(cpu, r, opaque, state, r->secure,
crm, opc1, opc2);
break;
default:
add_cpreg_to_hashtable(cpu, r, opaque, state,
ARM_CP_SECSTATE_S, crm, opc1, opc2);
add_cpreg_to_hashtable(cpu, r, opaque, state,
ARM_CP_SECSTATE_NS, crm, opc1, opc2);
break;
}
> + } else {
> + /* AArch64 registers get mapped to non-secure
> instance
> + * of AArch32 */
> + add_cpreg_to_hashtable(cpu, r, opaque, state,
> + crm, opc1, opc2, SCR_NS);
> + }
> }
> }
> }
> --
> 1.8.3.2
thanks
-- PMM
- [Qemu-devel] [PATCH v8 27/27] target-arm: add cpu feature EL3 to CPUs with Security Extensions, (continued)
- [Qemu-devel] [PATCH v8 27/27] target-arm: add cpu feature EL3 to CPUs with Security Extensions, Greg Bellows, 2014/10/31
- [Qemu-devel] [PATCH v8 08/27] target-arm: move AArch32 SCR into security reglist, Greg Bellows, 2014/10/31
- [Qemu-devel] [PATCH v8 03/27] target-arm: add banked register accessors, Greg Bellows, 2014/10/31
- [Qemu-devel] [PATCH v8 14/27] target-arm: respect SCR.FW, SCR.AW and SCTLR.NMFI, Greg Bellows, 2014/10/31
- [Qemu-devel] [PATCH v8 15/27] target-arm: make CSSELR banked, Greg Bellows, 2014/10/31
- [Qemu-devel] [PATCH v8 07/27] target-arm: insert AArch32 cpregs twice into hashtable, Greg Bellows, 2014/10/31
- Re: [Qemu-devel] [PATCH v8 07/27] target-arm: insert AArch32 cpregs twice into hashtable,
Peter Maydell <=
- [Qemu-devel] [PATCH v8 06/27] target-arm: add secure state bit to CPREG hash, Greg Bellows, 2014/10/31
- [Qemu-devel] [PATCH v8 02/27] target-arm: add async excp target_el function, Greg Bellows, 2014/10/31
- [Qemu-devel] [PATCH v8 26/27] target-arm: make MAIR0/1 banked, Greg Bellows, 2014/10/31