target-arm: Adjust debug ID registers per-CPU

Allow each CPU type to specify the value for the debug ID
registers, by putting them in the ARMCPU struct, and use
the resulting information to only expose the correct number
of watchpoint and breakpoint registers for the CPU.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
This commit is contained in:
Peter Maydell 2014-08-19 18:56:25 +01:00
parent 10aae1049f
commit 48eb3ae64b
4 changed files with 31 additions and 7 deletions

View File

@ -148,6 +148,7 @@ typedef struct ARMCPU {
uint64_t id_aa64isar1; uint64_t id_aa64isar1;
uint64_t id_aa64mmfr0; uint64_t id_aa64mmfr0;
uint64_t id_aa64mmfr1; uint64_t id_aa64mmfr1;
uint32_t dbgdidr;
uint32_t clidr; uint32_t clidr;
/* The elements of this array are the CCSIDR values for each cache, /* The elements of this array are the CCSIDR values for each cache,
* in the order L1DCache, L1ICache, L2DCache, L2ICache, etc. * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.

View File

@ -640,6 +640,7 @@ static void cortex_a8_initfn(Object *obj)
cpu->id_isar2 = 0x21232031; cpu->id_isar2 = 0x21232031;
cpu->id_isar3 = 0x11112131; cpu->id_isar3 = 0x11112131;
cpu->id_isar4 = 0x00111142; cpu->id_isar4 = 0x00111142;
cpu->dbgdidr = 0x15141000;
cpu->clidr = (1 << 27) | (2 << 24) | 3; cpu->clidr = (1 << 27) | (2 << 24) | 3;
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */ cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
@ -712,6 +713,7 @@ static void cortex_a9_initfn(Object *obj)
cpu->id_isar2 = 0x21232041; cpu->id_isar2 = 0x21232041;
cpu->id_isar3 = 0x11112131; cpu->id_isar3 = 0x11112131;
cpu->id_isar4 = 0x00111142; cpu->id_isar4 = 0x00111142;
cpu->dbgdidr = 0x35141000;
cpu->clidr = (1 << 27) | (1 << 24) | 3; cpu->clidr = (1 << 27) | (1 << 24) | 3;
cpu->ccsidr[0] = 0xe00fe015; /* 16k L1 dcache. */ cpu->ccsidr[0] = 0xe00fe015; /* 16k L1 dcache. */
cpu->ccsidr[1] = 0x200fe015; /* 16k L1 icache. */ cpu->ccsidr[1] = 0x200fe015; /* 16k L1 icache. */
@ -773,6 +775,7 @@ static void cortex_a15_initfn(Object *obj)
cpu->id_isar2 = 0x21232041; cpu->id_isar2 = 0x21232041;
cpu->id_isar3 = 0x11112131; cpu->id_isar3 = 0x11112131;
cpu->id_isar4 = 0x10011142; cpu->id_isar4 = 0x10011142;
cpu->dbgdidr = 0x3515f021;
cpu->clidr = 0x0a200023; cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */

View File

@ -127,6 +127,7 @@ static void aarch64_a57_initfn(Object *obj)
cpu->id_aa64dfr0 = 0x10305106; cpu->id_aa64dfr0 = 0x10305106;
cpu->id_aa64isar0 = 0x00010000; cpu->id_aa64isar0 = 0x00010000;
cpu->id_aa64mmfr0 = 0x00001124; cpu->id_aa64mmfr0 = 0x00001124;
cpu->dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023; cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */ cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */

View File

@ -2186,12 +2186,6 @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri)
} }
static const ARMCPRegInfo debug_cp_reginfo[] = { static const ARMCPRegInfo debug_cp_reginfo[] = {
/* DBGDIDR: just RAZ. In particular this means the "debug architecture
* version" bits will read as a reserved value, which should cause
* Linux to not try to use the debug hardware.
*/
{ .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
/* DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped /* DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped
* debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1; * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1;
* unlike DBGDRAR it is never accessible from EL0. * unlike DBGDRAR it is never accessible from EL0.
@ -2233,14 +2227,32 @@ static void define_debug_regs(ARMCPU *cpu)
* These are just dummy implementations for now. * These are just dummy implementations for now.
*/ */
int i; int i;
int wrps, brps;
ARMCPRegInfo dbgdidr = {
.name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL0_R, .type = ARM_CP_CONST, .resetvalue = cpu->dbgdidr,
};
brps = extract32(cpu->dbgdidr, 24, 4);
wrps = extract32(cpu->dbgdidr, 28, 4);
/* The DBGDIDR and ID_AA64DFR0_EL1 define various properties
* of the debug registers such as number of breakpoints;
* check that if they both exist then they agree.
*/
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps);
assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps);
}
define_one_arm_cp_reg(cpu, &dbgdidr);
define_arm_cp_regs(cpu, debug_cp_reginfo); define_arm_cp_regs(cpu, debug_cp_reginfo);
if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) { if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
define_arm_cp_regs(cpu, debug_lpae_cp_reginfo); define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
} }
for (i = 0; i < 16; i++) { for (i = 0; i < brps + 1; i++) {
ARMCPRegInfo dbgregs[] = { ARMCPRegInfo dbgregs[] = {
{ .name = "DBGBVR", .state = ARM_CP_STATE_BOTH, { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4, .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
@ -2250,6 +2262,13 @@ static void define_debug_regs(ARMCPU *cpu)
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5, .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
.access = PL1_RW, .access = PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]) }, .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]) },
REGINFO_SENTINEL
};
define_arm_cp_regs(cpu, dbgregs);
}
for (i = 0; i < wrps + 1; i++) {
ARMCPRegInfo dbgregs[] = {
{ .name = "DBGWVR", .state = ARM_CP_STATE_BOTH, { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6, .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
.access = PL1_RW, .access = PL1_RW,