2023-04-26 21:00:01 +03:00
|
|
|
/*
|
|
|
|
* ARM Cortex-A registers
|
|
|
|
*
|
|
|
|
* This code is licensed under the GNU GPL v2 or later.
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "qemu/osdep.h"
|
|
|
|
#include "cpu.h"
|
|
|
|
#include "cpregs.h"
|
|
|
|
|
|
|
|
|
|
|
|
static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
|
|
|
{
|
|
|
|
ARMCPU *cpu = env_archcpu(env);
|
|
|
|
|
2023-05-12 20:02:22 +03:00
|
|
|
/*
|
|
|
|
* Number of cores is in [25:24]; otherwise we RAZ.
|
|
|
|
* If the board didn't configure the CPUs into clusters,
|
|
|
|
* we default to "all CPUs in one cluster", which might be
|
|
|
|
* more than the 4 that the hardware permits and which is
|
|
|
|
* all you can report in this two-bit field. Saturate to
|
|
|
|
* 0b11 (== 4 CPUs) rather than overflowing the field.
|
|
|
|
*/
|
|
|
|
return MIN(cpu->core_count - 1, 3) << 24;
|
2023-04-26 21:00:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
|
|
|
|
{ .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
|
|
|
|
.opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
|
|
|
|
.access = PL1_RW, .readfn = l2ctlr_read,
|
|
|
|
.writefn = arm_cp_write_ignore },
|
|
|
|
{ .name = "L2CTLR",
|
|
|
|
.cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
|
|
|
|
.access = PL1_RW, .readfn = l2ctlr_read,
|
|
|
|
.writefn = arm_cp_write_ignore },
|
|
|
|
{ .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
|
|
|
|
.opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
|
|
|
|
{ .name = "L2ECTLR",
|
|
|
|
.cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
|
|
|
|
{ .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
|
|
|
|
.opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
|
|
|
|
{ .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
|
|
|
|
.opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
|
|
|
|
{ .name = "CPUACTLR",
|
|
|
|
.cp = 15, .opc1 = 0, .crm = 15,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
|
|
|
|
{ .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
|
|
|
|
.opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
|
|
|
|
{ .name = "CPUECTLR",
|
|
|
|
.cp = 15, .opc1 = 1, .crm = 15,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
|
|
|
|
{ .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
|
|
|
|
.opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
|
|
|
|
{ .name = "CPUMERRSR",
|
|
|
|
.cp = 15, .opc1 = 2, .crm = 15,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
|
|
|
|
{ .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
|
|
|
|
.opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
|
|
|
|
{ .name = "L2MERRSR",
|
|
|
|
.cp = 15, .opc1 = 3, .crm = 15,
|
|
|
|
.access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu)
|
|
|
|
{
|
|
|
|
define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
|
|
|
|
}
|