Commit 07a5628c authored by Vijaya Kumar K's avatar Vijaya Kumar K Committed by Peter Maydell
Browse files

hw/intc/arm_gicv3_kvm: Reset GICv3 cpu interface registers



Reset CPU interface registers of GICv3 when CPU is reset.
For this, ARMCPRegInfo struct is registered with one ICC
register whose resetfn is called when cpu is reset.

All the ICC registers are reset under one single register
reset function instead of calling resetfn for each ICC
register.

Signed-off-by: default avatarVijaya Kumar K <Vijaya.Kumar@cavium.com>
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
Message-id: 1487850673-26455-6-git-send-email-vijay.kilari@gmail.com
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent d3a3e529
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -604,6 +604,32 @@ static void kvm_arm_gicv3_get(GICv3State *s)
    }
}

static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
{
    ARMCPU *cpu;
    GICv3State *s;
    GICv3CPUState *c;

    c = (GICv3CPUState *)env->gicv3state;
    s = c->gic;
    cpu = ARM_CPU(c->cpu);

    /* Initialize to actual HW supported configuration */
    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
                      KVM_VGIC_ATTR(ICC_CTLR_EL1, cpu->mp_affinity),
                      &c->icc_ctlr_el1[GICV3_NS], false);

    c->icc_ctlr_el1[GICV3_S] = c->icc_ctlr_el1[GICV3_NS];
    c->icc_pmr_el1 = 0;
    c->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
    c->icc_bpr[GICV3_G1] = GIC_MIN_BPR;
    c->icc_bpr[GICV3_G1NS] = GIC_MIN_BPR;

    c->icc_sre_el1 = 0x7;
    memset(c->icc_apr, 0, sizeof(c->icc_apr));
    memset(c->icc_igrpen, 0, sizeof(c->icc_igrpen));
}

static void kvm_arm_gicv3_reset(DeviceState *dev)
{
    GICv3State *s = ARM_GICV3_COMMON(dev);
@@ -621,6 +647,34 @@ static void kvm_arm_gicv3_reset(DeviceState *dev)
    kvm_arm_gicv3_put(s);
}

/*
 * CPU interface registers of GIC needs to be reset on CPU reset.
 * For the calling arm_gicv3_icc_reset() on CPU reset, we register
 * below ARMCPRegInfo. As we reset the whole cpu interface under single
 * register reset, we define only one register of CPU interface instead
 * of defining all the registers.
 */
static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
    { .name = "ICC_CTLR_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 4,
      /*
       * If ARM_CP_NOP is used, resetfn is not called,
       * So ARM_CP_NO_RAW is appropriate type.
       */
      .type = ARM_CP_NO_RAW,
      .access = PL1_RW,
      .readfn = arm_cp_read_zero,
      .writefn = arm_cp_write_ignore,
      /*
       * We hang the whole cpu interface reset routine off here
       * rather than parcelling it out into one little function
       * per register
       */
      .resetfn = arm_gicv3_icc_reset,
    },
    REGINFO_SENTINEL
};

static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
{
    GICv3State *s = KVM_ARM_GICV3(dev);
@@ -644,6 +698,12 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)

    gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL);

    for (i = 0; i < s->num_cpu; i++) {
        ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));

        define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
    }

    /* Try to create the device via the device control API */
    s->dev_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V3, false);
    if (s->dev_fd < 0) {