mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 18:36:48 +00:00
target-arm: add secure state bit to CPREG hash
Added additional NS-bit to CPREG hash encoding. Updated hash lookup locations to specify hash bit currently set to non-secure. Backports commit 51a79b039728277e35fd19f7a7b4bc6cb323697f from qemu
This commit is contained in:
parent
4f5106b56d
commit
fb78e79d72
|
@ -893,6 +893,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
|
|||
* Crn, Crm, opc1, opc2 fields
|
||||
* 32 or 64 bit register (ie is it accessed via MRC/MCR
|
||||
* or via MRRC/MCRR?)
|
||||
* non-secure/secure bank (AArch32 only)
|
||||
* We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
|
||||
* (In this case crn and opc2 should be zero.)
|
||||
* For AArch64, there is no 32/64 bit size distinction;
|
||||
|
@ -910,9 +911,16 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
|
|||
#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) | \
|
||||
((crm) << 7) | ((opc1) << 3) | (opc2))
|
||||
/* To enable banking of coprocessor registers depending on ns-bit we
|
||||
* add a bit to distinguish between secure and non-secure cpregs in the
|
||||
* hashtable.
|
||||
*/
|
||||
#define CP_REG_NS_SHIFT 29
|
||||
#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
|
||||
|
||||
#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
|
||||
((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
|
||||
((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
|
||||
|
||||
#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
|
||||
(CP_REG_AA64_MASK | \
|
||||
|
@ -931,8 +939,15 @@ static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
|
|||
uint32_t cpregid = kvmid;
|
||||
if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
|
||||
cpregid |= CP_REG_AA64_MASK;
|
||||
} else if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
|
||||
cpregid |= (1 << 15);
|
||||
} else {
|
||||
if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
|
||||
cpregid |= (1 << 15);
|
||||
}
|
||||
|
||||
/* KVM is always non-secure so add the NS flag on AArch32 register
|
||||
* entries.
|
||||
*/
|
||||
cpregid |= 1 << CP_REG_NS_SHIFT;
|
||||
}
|
||||
return cpregid;
|
||||
}
|
||||
|
|
|
@ -2802,7 +2802,7 @@ void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
|||
}
|
||||
|
||||
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
|
||||
void *opaque, int state,
|
||||
void *opaque, int state, int secstate,
|
||||
int crm, int opc1, int opc2)
|
||||
{
|
||||
/* Private utility function for define_one_arm_cp_reg_with_opaque():
|
||||
|
@ -2811,6 +2811,7 @@ 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
|
||||
|
@ -2842,7 +2843,7 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
|
|||
*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(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
|
||||
}
|
||||
if (opaque) {
|
||||
r2->opaque = opaque;
|
||||
|
@ -2992,7 +2993,7 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
|||
continue;
|
||||
}
|
||||
add_cpreg_to_hashtable(cpu, r, opaque, state,
|
||||
crm, opc1, opc2);
|
||||
ARM_CP_SECSTATE_NS, crm, opc1, opc2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7252,7 +7252,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
|
|||
rt = (insn >> 12) & 0xf;
|
||||
|
||||
ri = get_arm_cp_reginfo(s->cp_regs,
|
||||
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
|
||||
ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
|
||||
if (ri) {
|
||||
/* Check access permissions */
|
||||
if (!cp_access_ok(s->current_el, ri, isread)) {
|
||||
|
@ -7434,12 +7434,16 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
|
|||
*/
|
||||
if (is64) {
|
||||
qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
|
||||
"64 bit system register cp:%d opc1: %d crm:%d\n",
|
||||
isread ? "read" : "write", cpnum, opc1, crm);
|
||||
"64 bit system register cp:%d opc1: %d crm:%d "
|
||||
"(%s)\n",
|
||||
isread ? "read" : "write", cpnum, opc1, crm,
|
||||
s->ns ? "non-secure" : "secure");
|
||||
} else {
|
||||
qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
|
||||
"system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
|
||||
isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
|
||||
"system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
|
||||
"(%s)\n",
|
||||
isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
|
||||
s->ns ? "non-secure" : "secure");
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
Loading…
Reference in a new issue