[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v8 07/27] target-arm: insert AArch32 cpregs twice in
From: |
Greg Bellows |
Subject: |
[Qemu-devel] [PATCH v8 07/27] target-arm: insert AArch32 cpregs twice into hashtable |
Date: |
Thu, 30 Oct 2014 16:28:38 -0500 |
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;
+
+ 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.
+ */
+ 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) {
+ 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);
+ }
+ } 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
- Re: [Qemu-devel] [PATCH v8 11/27] target-arm: add SDER definition, (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 <=
- [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