| 1 | /* |
| 2 | * ARM Cortex-A registers |
| 3 | * |
| 4 | * This code is licensed under the GNU GPL v2 or later. |
| 5 | * |
| 6 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 7 | */ |
| 8 | |
| 9 | #include "qemu/osdep.h" |
| 10 | #include "cpu.h" |
| 11 | #include "cpregs.h" |
| 12 | |
| 13 | |
| 14 | static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) |
| 15 | { |
| 16 | ARMCPU *cpu = env_archcpu(env); |
| 17 | |
| 18 | /* |
| 19 | * Number of cores is in [25:24]; otherwise we RAZ. |
| 20 | * If the board didn't configure the CPUs into clusters, |
| 21 | * we default to "all CPUs in one cluster", which might be |
| 22 | * more than the 4 that the hardware permits and which is |
| 23 | * all you can report in this two-bit field. Saturate to |
| 24 | * 0b11 (== 4 CPUs) rather than overflowing the field. |
| 25 | */ |
| 26 | return MIN(cpu->core_count - 1, 3) << 24; |
| 27 | } |
| 28 | |
| 29 | static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = { |
| 30 | { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64, |
| 31 | .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2, |
| 32 | .access = PL1_RW, .readfn = l2ctlr_read, |
| 33 | .writefn = arm_cp_write_ignore }, |
| 34 | { .name = "L2CTLR", |
| 35 | .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2, |
| 36 | .access = PL1_RW, .readfn = l2ctlr_read, |
| 37 | .writefn = arm_cp_write_ignore }, |
| 38 | { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64, |
| 39 | .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3, |
| 40 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 41 | { .name = "L2ECTLR", |
| 42 | .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3, |
| 43 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 44 | { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH, |
| 45 | .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0, |
| 46 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 47 | { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64, |
| 48 | .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0, |
| 49 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 50 | { .name = "CPUACTLR", |
| 51 | .cp = 15, .opc1 = 0, .crm = 15, |
| 52 | .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, |
| 53 | { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64, |
| 54 | .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1, |
| 55 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 56 | { .name = "CPUECTLR", |
| 57 | .cp = 15, .opc1 = 1, .crm = 15, |
| 58 | .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, |
| 59 | { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64, |
| 60 | .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2, |
| 61 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 62 | { .name = "CPUMERRSR", |
| 63 | .cp = 15, .opc1 = 2, .crm = 15, |
| 64 | .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, |
| 65 | { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64, |
| 66 | .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3, |
| 67 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 68 | { .name = "L2MERRSR", |
| 69 | .cp = 15, .opc1 = 3, .crm = 15, |
| 70 | .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, |
| 71 | }; |
| 72 | |
| 73 | void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) |
| 74 | { |
| 75 | define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); |
| 76 | } |