[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v10 07/26] target-arm: insert AArch32 cpregs twice i
From: |
Greg Bellows |
Subject: |
[Qemu-devel] [PATCH v10 07/26] target-arm: insert AArch32 cpregs twice into hashtable |
Date: |
Thu, 6 Nov 2014 09:50:54 -0600 |
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>
---
v8 -> v9
- Fixed setting of secure field in add_cpreg_to_hashtable so it uses secstate
and happens in all cases.
- Fixed check for disabling of migration to only occur on duplicately defined
reginfos.
- Fixed comment on disabling migration and reset and eliminated crn special
case.
- Reworked define_one_arm_cp_reg_with_opaque() secure case handling.
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, 81 insertions(+), 17 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1aadb79..0471e6c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3296,23 +3296,59 @@ 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;
- int ns = (r->secure & ARM_CP_SECSTATE_NS) ? 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.
+ int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
+
+ /* Reset the secure state to the specific incoming state. This is
+ * necessary as the register may have been defined with both states.
+ */
+ r2->secure = secstate;
+
+ 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[ns];
+ }
+
+ if (state == ARM_CP_STATE_AA32) {
+ if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
+ /* If the register is banked then we don't need to migrate or
+ * reset the 32-bit instance in certain cases:
+ *
+ * 1) If the register has both 32-bit and 64-bit instances then we
+ * can count on the 64-bit instance taking care of the
+ * non-secure bank.
+ * 2) If ARMv8 is enabled then we can count on a 64-bit version
+ * taking care of the secure bank. This requires that separate
+ * 32 and 64-bit definitions are provided.
+ */
+ if ((r->state == ARM_CP_STATE_BOTH && ns) ||
+ (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
+ r2->type |= ARM_CP_NO_MIGRATE;
+ r2->resetfn = arm_cp_reset_ignore;
+ }
+ } else if ((secstate != r->secure) && !ns) {
+ /* 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
@@ -3461,10 +3497,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 */
@@ -3477,8 +3517,32 @@ 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,
- ARM_CP_SECSTATE_NS, crm, opc1,
opc2);
+ if (state == ARM_CP_STATE_AA32) {
+ /* Under AArch32 CP registers can be common
+ * (same for secure and non-secure world) or banked.
+ */
+ 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,
+ ARM_CP_SECSTATE_NS,
+ crm, opc1, opc2);
+ }
}
}
}
--
1.8.3.2
- [Qemu-devel] [PATCH v10 00/26] target-arm: add Security Extensions for CPUs, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 01/26] target-arm: extend async excp masking, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 03/26] target-arm: add banked register accessors, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 02/26] target-arm: add async excp target_el function, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 04/26] target-arm: add non-secure Translation Block flag, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 05/26] target-arm: add CPREG secure state support, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 06/26] target-arm: add secure state bit to CPREG hash, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 07/26] target-arm: insert AArch32 cpregs twice into hashtable,
Greg Bellows <=
- [Qemu-devel] [PATCH v10 08/26] target-arm: move AArch32 SCR into security reglist, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 09/26] target-arm: implement IRQ/FIQ routing to Monitor mode, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 10/26] target-arm: add NSACR register, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 11/26] target-arm: add SDER definition, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 12/26] target-arm: add MVBAR support, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 13/26] target-arm: add SCTLR_EL3 and make SCTLR banked, Greg Bellows, 2014/11/06
- [Qemu-devel] [PATCH v10 14/26] target-arm: respect SCR.FW, SCR.AW and SCTLR.NMFI, Greg Bellows, 2014/11/06