mirror of
https://github.com/qemu/qemu.git
synced 2024-12-02 16:23:35 +08:00
target-arm: Stop underdecoding ARM946 PRBS registers
The ARM946 has 8 PRBS (protection region base and size) registers. Currently we implement these with a CP_ANY reginfo; however this underdecodes (since there are 16 possible values of CRm but only 8 registers) and we catch the invalid values in the read and write functions. However this causes issues with migration since we only migrate the first of a wildcard register set, so we only migrate c6_region[0]. It also makes it awkward to pull reginfo access checks out into their own function. Avoid all these problems by just defining separate reginfo structs for each of the 8 registers; this also lets us avoid having any read or write functions and will result in more efficient direct field accesses from generated code. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
626187d86b
commit
e508a92b62
@ -1162,26 +1162,6 @@ static int pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arm946_prbs_read(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t *value)
|
||||
{
|
||||
if (ri->crm >= 8) {
|
||||
return EXCP_UDEF;
|
||||
}
|
||||
*value = env->cp15.c6_region[ri->crm];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arm946_prbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
if (ri->crm >= 8) {
|
||||
return EXCP_UDEF;
|
||||
}
|
||||
env->cp15.c6_region[ri->crm] = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
|
||||
{ .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
|
||||
.access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
|
||||
@ -1204,9 +1184,30 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
|
||||
.access = PL1_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c2_insn), .resetvalue = 0, },
|
||||
/* Protection region base and size registers */
|
||||
{ .name = "946_PRBS", .cp = 15, .crn = 6, .crm = CP_ANY, .opc1 = 0,
|
||||
.opc2 = CP_ANY, .access = PL1_RW,
|
||||
.readfn = arm946_prbs_read, .writefn = arm946_prbs_write, },
|
||||
{ .name = "946_PRBS0", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0,
|
||||
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[0]) },
|
||||
{ .name = "946_PRBS1", .cp = 15, .crn = 6, .crm = 1, .opc1 = 0,
|
||||
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[1]) },
|
||||
{ .name = "946_PRBS2", .cp = 15, .crn = 6, .crm = 2, .opc1 = 0,
|
||||
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[2]) },
|
||||
{ .name = "946_PRBS3", .cp = 15, .crn = 6, .crm = 3, .opc1 = 0,
|
||||
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[3]) },
|
||||
{ .name = "946_PRBS4", .cp = 15, .crn = 6, .crm = 4, .opc1 = 0,
|
||||
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[4]) },
|
||||
{ .name = "946_PRBS5", .cp = 15, .crn = 6, .crm = 5, .opc1 = 0,
|
||||
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[5]) },
|
||||
{ .name = "946_PRBS6", .cp = 15, .crn = 6, .crm = 6, .opc1 = 0,
|
||||
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[6]) },
|
||||
{ .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0,
|
||||
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user