Hi Greg Thanks for sharing your approach. I like your idea of keeping the hashtable small when Security Extensions are not present as well as isolating Sec-Ext specific registers in their own group. How do you want to proceed in this matter? Are you going to continue working on the banking and Sec-Ext patchset in general? Just so I know what I should focus on.
Best, Fabian On 16 May 2014, at 22:56, Greg Bellows <greg.bell...@linaro.org<mailto:greg.bell...@linaro.org>> wrote: As mentioned in an earlier thread, I too have been building on Sergey's trustzone changes. I wanted to share a subset of my changes related to banked register support as an alternative. Overview: The approach delicately hashes all the SP registers just as Fabian's approach does. The primary difference is that all the existing ARMCPRegInfo entries are left as-is and are blindly registered for both NS-bit settings (encoded in the hash key). Once all of the existing registers have been added to the hash, the set of security specific registers are hashed. Hashing of these registers involves a single new type to indicate that the ARMCPRegInfo is a security update of an existing register. On receipt of this type, a hash lookup is performed on the register and it is updated for the security specifics. This primarily involves updating the fieldoffset to point at the secure bank. There are benefits to both approaches. In the above approach it avoids to mark all register declarations as secure or banked and isolates the security registers to their own mechanism. This can also be considered a detriment as the existing registers are not explicitly marked. Update: Since the coding of the approach and reviewing of Fabian's changes, I have discovered that further optimizations may be possible over the diffs provided below. * The registration of the security registers do not need to go through add_cpreg_to_hash_table but rather have a simpler routine that takes the ARMCPRegInfo group and walks through updating each register. * The CP register duplication can be isolated to the routine used to update the security registers. This cuts down on the entries in the hash when the security extension is not present. Diffs: Below are a subset of the differences required for the aforementioned approach. The diffs are built on top of Sergey's original patches and against a recent baselevel. I have omitted code unnecessary for demonstrating the approach. Also, my implementation is intended for ARMv7 only. diff --combined target-arm/cpu.h index 467eaa5,c83f249..0000000 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@@ -90,41 -89,9 +90,41 @@@ typedef void ARMWriteCPFunc(void *opaqu typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info, int dstreg, int operand); +#define CP15_DEFAULT_BANK 1 + +/* Define a banked coprocessor register state field. Use %name as the active + * register state field name. The banked register state array field name has + * "banked_" prefix. The banked register state array indexes corresponds to + * SCR.NS bit value. + */ +#define BANKED_CP_REG(type, name) \ + union { \ + struct { \ + type name##_sec; \ + type name; \ + }; \ + type banked_##name[2]; \ + } + +/* Secure bank selector macro + * Determines whether a co-processor access instruction should use a banked + * Non-secure copy of a register instead of active one. + */ +#define CP_REG_BANK(env) \ + (arm_feature((env), ARM_FEATURE_SECURITY) ? \ + ((env)->cp15.c1_scr & 1) : CP15_DEFAULT_BANK) + +/* Get a banked CP15 register in co-processor access instruction handler */ +#define BANKED_CP15_REG_GET(env, regname) \ + (env)->cp15.banked_##regname[CP_REG_BANK(env)] + +/* Set a banked CP15 register in co-processor access instruction handler */ +#define BANKED_CP15_REG_SET(env, regname, val) \ + (env)->cp15.banked_##regname[CP_REG_BANK(env)] = (val) + struct arm_boot_info; -#define NB_MMU_MODES 2 +#define NB_MMU_MODES 4 /* We currently assume float and double are IEEE single and double precision respectively. @@@ -201,29 -168,27 +201,29 @@@ /* System control coprocessor (cp15) */ struct { uint32_t c0_cpuid; - uint64_t c0_cssel; /* Cache size selection. */ - uint64_t c1_sys; /* System control register. */ + BANKED_CP_REG(uint64_t, c0_cssel); /* Cache size selection. */ + BANKED_CP_REG(uint64_t, c1_sys); /* System control register. */ uint64_t c1_coproc; /* Coprocessor access register. */ uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */ uint32_t c1_scr; /* secure config register. */ - uint64_t ttbr0_el1; /* MMU translation table base 0. */ - uint64_t ttbr1_el1; /* MMU translation table base 1. */ - uint64_t c2_control; /* MMU translation table base control. */ + uint32_t c1_sder; /* Secure debug enable register. */ + uint32_t c1_nsacr; /* Non-secure access control register. */ + BANKED_CP_REG(uint64_t, ttbr0_el1); /* MMU translation table base 0. */ + BANKED_CP_REG(uint64_t, ttbr1_el1); /* MMU translation table base 1. */ + BANKED_CP_REG(uint64_t, c2_control); /* MMU x-lation tbl base cntrl.*/ uint32_t c2_mask; /* MMU translation table base selection mask. */ uint32_t c2_base_mask; /* MMU translation table base 0 mask. */ uint32_t c2_data; /* MPU data cachable bits. */ uint32_t c2_insn; /* MPU instruction cachable bits. */ - uint32_t c3; /* MMU domain access control register - MPU write buffer control. */ + BANKED_CP_REG(uint32_t, c3); /* MMU domain access control register + MPU write buffer control. */ uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */ uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */ - uint32_t ifsr_el2; /* Fault status registers. */ - uint64_t esr_el1; + BANKED_CP_REG(uint32_t, ifsr_el2); /* Fault status registers. */ + BANKED_CP_REG(uint64_t, esr_el1); uint32_t c6_region[8]; /* MPU base/size registers. */ - uint64_t far_el1; /* Fault address registers. */ - uint64_t par_el1; /* Translation result. */ + BANKED_CP_REG(uint64_t, far_el1); /* Fault address registers. */ + BANKED_CP_REG(uint64_t, par_el1); /* Translation result. */ uint32_t c9_insn; /* Cache lockdown registers. */ uint32_t c9_data; uint32_t c9_pmcr; /* performance monitor control register */ @@@ -232,13 -197,12 +232,13 @@@ uint32_t c9_pmxevtyper; /* perf monitor event type */ uint32_t c9_pmuserenr; /* perf monitor user enable */ uint32_t c9_pminten; /* perf monitor interrupt enables */ - uint64_t mair_el1; - uint64_t c12_vbar; /* vector base address register */ - uint32_t c13_fcse; /* FCSE PID. */ - uint64_t contextidr_el1; /* Context ID. */ - uint64_t tpidr_el0; /* User RW Thread register. */ - uint64_t tpidrro_el0; /* User RO Thread register. */ + BANKED_CP_REG(uint64_t, mair_el1); + BANKED_CP_REG(uint64_t, c12_vbar); /* vector base address register */ + uint32_t c12_mvbar; /* monitor vector base address register */ + BANKED_CP_REG(uint32_t, c13_fcse); /* FCSE PID. */ + BANKED_CP_REG(uint64_t, contextidr_el1); /* Context ID. */ + BANKED_CP_REG(uint64_t, tpidr_el0); /* User RW Thread register. */ + BANKED_CP_REG(uint64_t ,tpidrro_el0); /* User RO Thread register. */ uint64_t tpidr_el1; /* Privileged Thread register. */ uint64_t c14_cntfrq; /* Counter Frequency register */ uint64_t c14_cntkctl; /* Timer Control register */ @@@ -676,17 -638,6 +676,17 @@@ return (env->features & (1ULL << feature)) != 0; } +/* Return true if the processor is in Secure state */ +static inline bool arm_is_secure(CPUARMState *env) +{ +#if !defined(CONFIG_USER_ONLY) + return ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) || + !(env->cp15.c1_scr & 1); +#else + return false; +#endif +} + /* Return true if the specified exception level is running in AArch64 state. */ static inline bool arm_el_is_aa64(CPUARMState *env, int el) { @@@ -738,8 -689,8 +738,8 @@@ void armv7m_nvic_complete_irq(void *opa #define CP_REG_AA64_SHIFT 28 #define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT) -#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2) \ - (((cp) << 16) | ((is64) << 15) | ((crn) << 11) | \ +#define ENCODE_CP_REG(ns, cp, is64, crn, crm, opc1, opc2) \ + (((ns) << 31) | ((cp) << 16) | ((is64) << 15) | ((crn) << 11) | \ ((crm) << 7) | ((opc1) << 3) | (opc2)) #define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \ @@@ -809,12 -760,6 +809,12 @@@ static inline uint64_t cpreg_to_kvm_id( #define ARM_CP_OVERRIDE 16 #define ARM_CP_NO_MIGRATE 32 #define ARM_CP_IO 64 +/* Secure CP register type. + * This flag indicates that the ARMCPRegInfo is a secure register entry. + * This flag includes override as the registration may override the + * previously registered attributes. + */ +#define ARM_CP_SECURE (ARM_CP_OVERRIDE | 128) #define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8)) #define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8)) #define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8)) diff --combined target-arm/helper.c index 70f34c0,3be917c..0000000 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@@ -768,6 -763,14 +768,6 @@@ static const ARMCPRegInfo v7_cp_reginfo .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), .resetvalue = 0, .writefn = pmintenclr_write, }, - { .name = "VBAR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .writefn = vbar_write, - .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar), - .resetvalue = 0 }, - { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr), - .resetvalue = 0, }, { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0, .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE }, +static const ARMCPRegInfo security_cp_reginfo[] = { +#ifndef CONFIG_USER_ONLY + /* + * Restricted access registers + * These registers are restricted to secure state access only. Just like + * the non-secure registers, both ns-bit settings are registered. These + * registers are not marked secure as they are not banked. + */ + { .name = "VBAR", .state = ARM_CP_STATE_AA32, + .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL3_RW, .writefn = vbar_write, + .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar), + .resetvalue = 0 }, + { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr), + .writefn = scr_write, .resetvalue = 0 }, + { .name = "SDER", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 1, + .access = PL3_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c1_sder) }, + { .name = "MVBAR", .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL3_RW, .resetvalue = 0, + .writefn = vbar_write, + .fieldoffset = offsetof(CPUARMState, cp15.c12_mvbar) }, + { .name = "NSACR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 2, + .access = PL3_RW | PL1_R | PL2_R, .resetvalue = 0, .writefn = nsacr_write, + .fieldoffset = offsetof(CPUARMState, cp15.c1_nsacr) }, + + /* + * Banked registers + * These registers are banked so we need to reregister the secure bank + * to use a new register location. It is expected that the register was + * previously registered, in which case we will preserve the previous + * settings besides the fieldoffset and type. + */ + { .name = "CSSELR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0, + .state = ARM_CP_STATE_AA32, .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel_sec) }, + { .name = "SCTLR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0, + .state = ARM_CP_STATE_AA32, .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.c1_sys_sec), + .writefn = sctlr_write, .raw_writefn = raw_write}, + /* TODO: ADD ACTLR */ + { .name = "TTBR0_EL1", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, + .state = ARM_CP_STATE_AA32, .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1_sec) }, + { .name = "TTBR1_EL1", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1, + .state = ARM_CP_STATE_AA32, .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1_sec) }, + /* TODO: ADD in TTBR0/1 for LPAE */ + { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64, .type = ARM_CP_SECURE, + .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, + .fieldoffset = offsetof(CPUARMState, cp15.c2_control_sec) }, + { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, + .type = ARM_CP_SECURE, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c2_control_sec) }, + { .name = "DACR", + .cp = 15, .crn = 3, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, + .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.c3_sec) }, + { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, + .type = ARM_CP_SECURE, + .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1_sec) }, + { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1, + .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.ifsr_el2_sec) }, + { .name = "FAR_EL1", .state = ARM_CP_STATE_AA32, .type = ARM_CP_SECURE, + .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0, + .fieldoffset = offsetof(CPUARMState, cp15.far_el1_sec) }, + { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2, + .type = ARM_CP_SECURE, + .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1_sec) }, + { .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0, + .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.par_el1_sec) }, + { .name = "MAIR0", .state = ARM_CP_STATE_AA32, .type = ARM_CP_SECURE, + .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, + .fieldoffset = offsetoflow32(CPUARMState, cp15.mair_el1_sec) }, + { .name = "MAIR1", .state = ARM_CP_STATE_AA32, .type = ARM_CP_SECURE, + .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, + .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el1_sec) }, + { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0, + .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse_sec) }, + { .name = "CONTEXTIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 1, + .type = ARM_CP_SECURE, + .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el1_sec) }, + { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2, + .type = ARM_CP_SECURE, + .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0_sec) }, + { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3, + .type = ARM_CP_SECURE, + .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0_sec) }, +#endif + REGINFO_SENTINEL +}; + void register_cp_regs_for_features(ARMCPU *cpu) { /* Register all the coprocessor registers based on feature bits */ @@@ -2665,13 -2532,6 +2665,13 @@@ } define_one_arm_cp_reg(cpu, &sctlr); } + /* + * Register the security extension registers last as they may override the + * bank of previsously registered registers. + */ + if (arm_feature(env, ARM_FEATURE_SECURITY)) { + define_arm_cp_regs(cpu, security_cp_reginfo); + } } ARMCPU *cpu_arm_init(const char *cpu_model) @@@ -2785,7 -2645,7 +2785,7 @@@ CpuDefinitionInfoList *arch_query_cpu_d } static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r, - void *opaque, int state, + void *opaque, int state, int ns, int crm, int opc1, int opc2) { /* Private utility function for define_one_arm_cp_reg_with_opaque(): @@@ -2810,11 -2670,6 +2810,11 @@@ #endif } if (state == ARM_CP_STATE_AA64) { + if ((r->type & ARM_CP_SECURE) == ARM_CP_SECURE) { + g_free(key); + g_free(r2); + return; + } /* To allow abbreviation of ARMCPRegInfo * definitions, we treat cp == 0 as equivalent to * the value for "standard guest-visible sysreg". @@@ -2825,7 -2680,7 +2825,7 @@@ *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm, r2->opc0, opc1, opc2); } else { - *key = ENCODE_CP_REG(r2->cp, is64, r2->crn, crm, opc1, opc2); + *key = ENCODE_CP_REG(ns, r2->cp, is64, r2->crn, crm, opc1, opc2); } if (opaque) { r2->opaque = opaque; @@@ -2868,30 -2723,6 +2868,30 @@@ g_assert_not_reached(); } } + + if ((r->type & ARM_CP_SECURE) == ARM_CP_SECURE) { + if (ns == 1) { + /* SECURE registers only apply to the ns = 0, so skip the ns = 1, + * version, but first free the allocated hash data.. + */ + g_free(key); + g_free(r2); + return; + } + + ARMCPRegInfo *oldreg = g_hash_table_lookup(cpu->cp_regs, key); + /* If we find a match for the key then we can leave it in the hash and + * simply update the necessary fields. Once updated we can release the + * allocated hash data and return. + */ + if (oldreg) { + oldreg->type |= ARM_CP_SECURE; + oldreg->fieldoffset = r->fieldoffset; + g_free(key); + g_free(r2); + return; + } + } g_hash_table_insert(cpu->cp_regs, key, r2); } @@@ -2999,16 -2829,8 +2999,16 @@@ if (r->state != state && r->state != ARM_CP_STATE_BOTH) { continue; } - add_cpreg_to_hashtable(cpu, r, opaque, state, - crm, opc1, opc2); + for (ns = 0; ns < 2; ns++) { + /* We are not encoding 64-bit CP registers with the + * secure bit so skip the non-secure bit instance. + */ + if (state == ARM_CP_STATE_AA64 && ns == 1) { + continue; + } + add_cpreg_to_hashtable(cpu, r, opaque, state, ns, + crm, opc1, opc2); + } } } } @@@ -3501,25 -3319,22 +3501,25 @@@ void arm_cpu_do_interrupt(CPUState *cs env->exception.fsr = 2; /* Fall through to prefetch abort. */ case EXCP_PREFETCH_ABORT: - env->cp15.ifsr_el2 = env->exception.fsr; - env->cp15.far_el1 = deposit64(env->cp15.far_el1, 32, 32, - env->exception.vaddress); + BANKED_CP15_REG_SET(env, ifsr_el2, env->exception.fsr); + BANKED_CP15_REG_SET(env, far_el1, + deposit64(BANKED_CP15_REG_GET(env, far_el1), + 32, 32, env->exception.vaddress)); qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n", - env->cp15.ifsr_el2, (uint32_t)env->exception.vaddress); + BANKED_CP15_REG_GET(env, ifsr_el2), + (uint32_t)env->exception.vaddress); new_mode = ARM_CPU_MODE_ABT; addr = 0x0c; mask = CPSR_A | CPSR_I; offset = 4; break; case EXCP_DATA_ABORT: - env->cp15.esr_el1 = env->exception.fsr; - env->cp15.far_el1 = deposit64(env->cp15.far_el1, 0, 32, - env->exception.vaddress); + BANKED_CP15_REG_SET(env, esr_el1, env->exception.fsr); + BANKED_CP15_REG_SET(env, far_el1, + deposit64(BANKED_CP15_REG_GET(env, far_el1), + 0, 32, env->exception.vaddress)); qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n", - (uint32_t)env->cp15.esr_el1, + (uint32_t)BANKED_CP15_REG_GET(env, esr_el1), (uint32_t)env->exception.vaddress); new_mode = ARM_CPU_MODE_ABT; addr = 0x10; On 16 May 2014 01:00, Aggeler Fabian <aggel...@student.ethz.ch<mailto:aggel...@student.ethz.ch>> wrote: Yes, sorry about that. Best, Fabian > On 15.05.2014, at 20:58, "Sergey Fedorov" > <serge.f...@gmail.com<mailto:serge.f...@gmail.com>> wrote: > > Can s.fedo...@samsung.com<mailto:s.fedo...@samsung.com> be removed from CC > list since this mailbox has > been deleted? That was my address when I worked for Samsung. Now sending > to this address results with annoying delivery failure notification. > > Thanks, > Sergey. > > 13.05.2014 20:15, Fabian Aggeler wrote: >> Hi, >> >> This is a rework of the Samsung patches sent last year to add Security >> Extensions. The patches have been changed based on the discussion on >> the mailing list. Other changes became necessary because of Aarch64 >> support which got added in the meantime. This patchset makes it possible >> to run a kernel in the secure world and then switch to non-secure >> on CPUs that implement Security Extensions. It works for EL3 in Aarch32 >> state, but may add _EL3 registers where necessary to reflect the mapping >> of secure instances of cp registers to _EL3 registers. >> >> Banking of cp registers has been changed from active mass-swapping to >> the mechanism discussed on the mailing list, where every Aarch32 cp >> register goes into the hashtable twice. A ns-bit is added to the key >> of the register which is used when accessing a cp register to get the >> correct instance. >> >> Magic numbers have been changed to bitshifted constants or macros to make >> the code easier to read. >> >> The whole patchset now uses the term Security Extensions instead of >> TrustZone as this is the term which is used in the ARM ARM. >> >> I am happy for any feedback, especially for the banking of course. It should >> not be too hard to combine these changes with the recent effort towards EL3 >> in A64. >> >> Thanks, >> Fabian >> >> Fabian Aggeler (12): >> target-arm: add arm_is_secure() function >> target-arm: add NSACR support >> target-arm: Split TLB for secure state and EL3 in Aarch64 >> target-arm: add banked coprocessor register type and macros >> target-arm: Restrict EL3 to Aarch32 state >> target-arm: Use arm_current_sctlr to access SCTLR >> target-arm: Use raw_write/raw_read whenever possible >> target-arm: Convert banked coprocessor registers >> target-arm: maintain common bits of banked CP registers >> target-arm: add MVBAR support >> target-arm: implement IRQ/FIQ routing to Monitor mode >> target-arm: Respect SCR.FW, SCR.AW<http://scr.aw/> and SCTLR.NMFI >> >> Sergey Fedorov (8): >> target-arm: move SCR into Security Extensions register list >> target-arm: adjust TTBCR for Security Extension feature >> target-arm: reject switching to monitor mode from non-secure state >> target-arm: adjust arm_current_pl() for Security Extensions >> target-arm: add non-secure Translation Block flag >> target-arm: implement CPACR register logic >> target-arm: add SDER definition >> target-arm: implement SMC instruction >> >> Svetlana Fedoseeva (3): >> target-arm: add new CPU feature for Security Extensions >> target-arm: preserve RAO/WI bits of ARMv7 SCTLR >> target-arm: add CPU Monitor mode >> >> hw/arm/pxa2xx.c | 2 +- >> linux-user/main.c | 2 +- >> target-arm/cpu-qom.h | 1 + >> target-arm/cpu.c | 8 +- >> target-arm/cpu.h | 271 ++++++++++++++++++++++--- >> target-arm/helper-a64.c | 3 +- >> target-arm/helper.c | 489 >> ++++++++++++++++++++++++++++++++++++--------- >> target-arm/machine.c | 6 +- >> target-arm/op_helper.c | 2 +- >> target-arm/translate-a64.c | 9 +- >> target-arm/translate.c | 342 ++++++++++++++++++------------- >> target-arm/translate.h | 4 + >> 12 files changed, 866 insertions(+), 273 deletions(-) >