mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
target-arm: Implement AArch64 views of fault status and data registers
Implement AArch64 views of ESR_EL1 and FAR_EL1, and make the 32 bit DFSR, DFAR, IFAR share state with them as architecturally specified. The IFSR doesn't share state with any AArch64 register visible at EL1, so just rename the state field without widening it to 64 bits. Signed-off-by: Rob Herring <rob.herring@linaro.org> [PMM: Minor tweaks; fix some bugs involving inconsistencies between use of offsetof() or offsetoflow32() and struct field width] Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
This commit is contained in:
parent
7e09797c29
commit
6cd8a2649a
@ -425,7 +425,7 @@ static void arm1026_initfn(Object *obj)
|
||||
ARMCPRegInfo ifar = {
|
||||
.name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
|
||||
.access = PL1_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
|
||||
.fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1),
|
||||
.resetvalue = 0
|
||||
};
|
||||
define_one_arm_cp_reg(cpu, &ifar);
|
||||
|
@ -181,11 +181,10 @@ typedef struct CPUARMState {
|
||||
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 c5_insn; /* Fault status registers. */
|
||||
uint32_t c5_data;
|
||||
uint32_t ifsr_el2; /* Fault status registers. */
|
||||
uint64_t esr_el1;
|
||||
uint32_t c6_region[8]; /* MPU base/size registers. */
|
||||
uint32_t c6_insn; /* Fault address registers. */
|
||||
uint32_t c6_data;
|
||||
uint64_t far_el1; /* Fault address registers. */
|
||||
uint32_t c7_par; /* Translation result. */
|
||||
uint32_t c7_par_hi; /* Translation result, high 32 bits */
|
||||
uint32_t c9_insn; /* Cache lockdown registers. */
|
||||
|
@ -475,7 +475,8 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
|
||||
{ .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5,
|
||||
.access = PL0_W, .type = ARM_CP_NOP },
|
||||
{ .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2,
|
||||
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
|
||||
.access = PL1_RW,
|
||||
.fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1),
|
||||
.resetvalue = 0, },
|
||||
/* Watchpoint Fault Address Register : should actually only be present
|
||||
* for 1136, 1176, 11MPCore.
|
||||
@ -1414,11 +1415,16 @@ static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
|
||||
static const ARMCPRegInfo vmsa_cp_reginfo[] = {
|
||||
{ .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
|
||||
.access = PL1_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c5_data), .resetvalue = 0, },
|
||||
.access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
|
||||
.fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1),
|
||||
.resetfn = arm_cp_reset_ignore, },
|
||||
{ .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
|
||||
.access = PL1_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c5_insn), .resetvalue = 0, },
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.ifsr_el2), .resetvalue = 0, },
|
||||
{ .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
|
||||
.access = PL1_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.esr_el1), .resetvalue = 0, },
|
||||
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
|
||||
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
|
||||
@ -1436,8 +1442,10 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
|
||||
.access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .writefn = vmsa_ttbcr_write,
|
||||
.resetfn = arm_cp_reset_ignore, .raw_writefn = vmsa_ttbcr_raw_write,
|
||||
.fieldoffset = offsetoflow32(CPUARMState, cp15.c2_control) },
|
||||
{ .name = "DFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
|
||||
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c6_data),
|
||||
/* 64-bit FAR; this entry also gives us the AArch32 DFAR */
|
||||
{ .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
|
||||
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el1),
|
||||
.resetvalue = 0, },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
@ -1477,7 +1485,8 @@ static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
static const ARMCPRegInfo omap_cp_reginfo[] = {
|
||||
{ .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
|
||||
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c5_data), .resetvalue = 0, },
|
||||
.fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1),
|
||||
.resetvalue = 0, },
|
||||
{ .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
|
||||
.access = PL1_RW, .type = ARM_CP_NOP },
|
||||
{ .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
|
||||
@ -3087,20 +3096,23 @@ void arm_cpu_do_interrupt(CPUState *cs)
|
||||
env->exception.fsr = 2;
|
||||
/* Fall through to prefetch abort. */
|
||||
case EXCP_PREFETCH_ABORT:
|
||||
env->cp15.c5_insn = env->exception.fsr;
|
||||
env->cp15.c6_insn = env->exception.vaddress;
|
||||
env->cp15.ifsr_el2 = env->exception.fsr;
|
||||
env->cp15.far_el1 = deposit64(env->cp15.far_el1, 32, 32,
|
||||
env->exception.vaddress);
|
||||
qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
|
||||
env->cp15.c5_insn, env->cp15.c6_insn);
|
||||
env->cp15.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.c5_data = env->exception.fsr;
|
||||
env->cp15.c6_data = env->exception.vaddress;
|
||||
env->cp15.esr_el1 = env->exception.fsr;
|
||||
env->cp15.far_el1 = deposit64(env->cp15.far_el1, 0, 32,
|
||||
env->exception.vaddress);
|
||||
qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
|
||||
env->cp15.c5_data, env->cp15.c6_data);
|
||||
(uint32_t)env->cp15.esr_el1,
|
||||
(uint32_t)env->exception.vaddress);
|
||||
new_mode = ARM_CPU_MODE_ABT;
|
||||
addr = 0x10;
|
||||
mask = CPSR_A | CPSR_I;
|
||||
|
Loading…
Reference in New Issue
Block a user