Message ID | 1483977924-14522-8-git-send-email-peter.maydell@linaro.org |
---|---|
State | Superseded |
Headers | show |
On Mon, Jan 9, 2017 at 8:05 AM, Peter Maydell <peter.maydell@linaro.org> wrote: > As the first step in adding support for the virtualization > extensions to the GICv3 emulation: > * add the necessary data fields to the state structures > * add the fields to the migration state, as a subsection > which is only present if virtualization is enabled > > The use of a subsection means we retain migration > compatibility as EL2 is not enabled on any CPUs currently. > > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Alistair Francis <alistair.francis@xilinx.com> Thanks, Alistair > --- > include/hw/intc/arm_gicv3_common.h | 18 ++++++++++++++++++ > hw/intc/arm_gicv3_common.c | 25 +++++++++++++++++++++++++ > hw/intc/arm_gicv3_cpuif.c | 13 +++++++++++++ > 3 files changed, 56 insertions(+) > > diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h > index beb2c77..665d3f8 100644 > --- a/include/hw/intc/arm_gicv3_common.h > +++ b/include/hw/intc/arm_gicv3_common.h > @@ -38,6 +38,9 @@ > /* Number of SGI target-list bits */ > #define GICV3_TARGETLIST_BITS 16 > > +/* Maximum number of list registers (architectural limit) */ > +#define GICV3_LR_MAX 16 > + > /* Minimum BPR for Secure, or when security not enabled */ > #define GIC_MIN_BPR 0 > /* Minimum BPR for Nonsecure when security is enabled */ > @@ -175,6 +178,21 @@ struct GICv3CPUState { > uint64_t icc_igrpen[3]; > uint64_t icc_ctlr_el3; > > + /* Virtualization control interface */ > + uint64_t ich_apr[3][4]; /* ich_apr[GICV3_G1][x] never used */ > + uint64_t ich_hcr_el2; > + uint64_t ich_lr_el2[GICV3_LR_MAX]; > + uint64_t ich_vmcr_el2; > + > + /* Properties of the CPU interface. These are initialized from > + * the settings in the CPU proper. > + * If the number of implemented list registers is 0 then the > + * virtualization support is not implemented. > + */ > + int num_list_regs; > + int vpribits; /* number of virtual priority bits */ > + int vprebits; /* number of virtual preemption bits */ > + > /* Current highest priority pending interrupt for this CPU. > * This is cached information that can be recalculated from the > * real state above; it doesn't need to be migrated. > diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c > index 0ee67a4..16b9b0f 100644 > --- a/hw/intc/arm_gicv3_common.c > +++ b/hw/intc/arm_gicv3_common.c > @@ -49,6 +49,27 @@ static int gicv3_post_load(void *opaque, int version_id) > return 0; > } > > +static bool virt_state_needed(void *opaque) > +{ > + GICv3CPUState *cs = opaque; > + > + return cs->num_list_regs != 0; > +} > + > +static const VMStateDescription vmstate_gicv3_cpu_virt = { > + .name = "arm_gicv3_cpu/virt", > + .version_id = 1, > + .minimum_version_id = 1, > + .needed = virt_state_needed, > + .fields = (VMStateField[]) { > + VMSTATE_UINT64_2DARRAY(ich_apr, GICv3CPUState, 3, 4), > + VMSTATE_UINT64(ich_hcr_el2, GICv3CPUState), > + VMSTATE_UINT64_ARRAY(ich_lr_el2, GICv3CPUState, GICV3_LR_MAX), > + VMSTATE_UINT64(ich_vmcr_el2, GICv3CPUState), > + VMSTATE_END_OF_LIST() > + } > +}; > + > static const VMStateDescription vmstate_gicv3_cpu = { > .name = "arm_gicv3_cpu", > .version_id = 1, > @@ -75,6 +96,10 @@ static const VMStateDescription vmstate_gicv3_cpu = { > VMSTATE_UINT64_ARRAY(icc_igrpen, GICv3CPUState, 3), > VMSTATE_UINT64(icc_ctlr_el3, GICv3CPUState), > VMSTATE_END_OF_LIST() > + }, > + .subsections = (const VMStateDescription * []) { > + &vmstate_gicv3_cpu_virt, > + NULL > } > }; > > diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c > index 35e8eb3..d2f859c 100644 > --- a/hw/intc/arm_gicv3_cpuif.c > +++ b/hw/intc/arm_gicv3_cpuif.c > @@ -36,6 +36,12 @@ static bool gicv3_use_ns_bank(CPUARMState *env) > return !arm_is_secure_below_el3(env); > } > > +/* The minimum BPR for the virtual interface is a configurable property */ > +static inline int icv_min_vbpr(GICv3CPUState *cs) > +{ > + return 7 - cs->vprebits; > +} > + > static int icc_highest_active_prio(GICv3CPUState *cs) > { > /* Calculate the current running priority based on the set bits > @@ -1081,6 +1087,13 @@ static void icc_reset(CPUARMState *env, const ARMCPRegInfo *ri) > cs->icc_ctlr_el3 = ICC_CTLR_EL3_NDS | ICC_CTLR_EL3_A3V | > (1 << ICC_CTLR_EL3_IDBITS_SHIFT) | > (7 << ICC_CTLR_EL3_PRIBITS_SHIFT); > + > + memset(cs->ich_apr, 0, sizeof(cs->ich_apr)); > + cs->ich_hcr_el2 = 0; > + memset(cs->ich_lr_el2, 0, sizeof(cs->ich_lr_el2)); > + cs->ich_vmcr_el2 = ICH_VMCR_EL2_VFIQEN | > + (icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR1_SHIFT) | > + (icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR0_SHIFT); > } > > static const ARMCPRegInfo gicv3_cpuif_reginfo[] = { > -- > 2.7.4 > >
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index beb2c77..665d3f8 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -38,6 +38,9 @@ /* Number of SGI target-list bits */ #define GICV3_TARGETLIST_BITS 16 +/* Maximum number of list registers (architectural limit) */ +#define GICV3_LR_MAX 16 + /* Minimum BPR for Secure, or when security not enabled */ #define GIC_MIN_BPR 0 /* Minimum BPR for Nonsecure when security is enabled */ @@ -175,6 +178,21 @@ struct GICv3CPUState { uint64_t icc_igrpen[3]; uint64_t icc_ctlr_el3; + /* Virtualization control interface */ + uint64_t ich_apr[3][4]; /* ich_apr[GICV3_G1][x] never used */ + uint64_t ich_hcr_el2; + uint64_t ich_lr_el2[GICV3_LR_MAX]; + uint64_t ich_vmcr_el2; + + /* Properties of the CPU interface. These are initialized from + * the settings in the CPU proper. + * If the number of implemented list registers is 0 then the + * virtualization support is not implemented. + */ + int num_list_regs; + int vpribits; /* number of virtual priority bits */ + int vprebits; /* number of virtual preemption bits */ + /* Current highest priority pending interrupt for this CPU. * This is cached information that can be recalculated from the * real state above; it doesn't need to be migrated. diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 0ee67a4..16b9b0f 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -49,6 +49,27 @@ static int gicv3_post_load(void *opaque, int version_id) return 0; } +static bool virt_state_needed(void *opaque) +{ + GICv3CPUState *cs = opaque; + + return cs->num_list_regs != 0; +} + +static const VMStateDescription vmstate_gicv3_cpu_virt = { + .name = "arm_gicv3_cpu/virt", + .version_id = 1, + .minimum_version_id = 1, + .needed = virt_state_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64_2DARRAY(ich_apr, GICv3CPUState, 3, 4), + VMSTATE_UINT64(ich_hcr_el2, GICv3CPUState), + VMSTATE_UINT64_ARRAY(ich_lr_el2, GICv3CPUState, GICV3_LR_MAX), + VMSTATE_UINT64(ich_vmcr_el2, GICv3CPUState), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_gicv3_cpu = { .name = "arm_gicv3_cpu", .version_id = 1, @@ -75,6 +96,10 @@ static const VMStateDescription vmstate_gicv3_cpu = { VMSTATE_UINT64_ARRAY(icc_igrpen, GICv3CPUState, 3), VMSTATE_UINT64(icc_ctlr_el3, GICv3CPUState), VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription * []) { + &vmstate_gicv3_cpu_virt, + NULL } }; diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c index 35e8eb3..d2f859c 100644 --- a/hw/intc/arm_gicv3_cpuif.c +++ b/hw/intc/arm_gicv3_cpuif.c @@ -36,6 +36,12 @@ static bool gicv3_use_ns_bank(CPUARMState *env) return !arm_is_secure_below_el3(env); } +/* The minimum BPR for the virtual interface is a configurable property */ +static inline int icv_min_vbpr(GICv3CPUState *cs) +{ + return 7 - cs->vprebits; +} + static int icc_highest_active_prio(GICv3CPUState *cs) { /* Calculate the current running priority based on the set bits @@ -1081,6 +1087,13 @@ static void icc_reset(CPUARMState *env, const ARMCPRegInfo *ri) cs->icc_ctlr_el3 = ICC_CTLR_EL3_NDS | ICC_CTLR_EL3_A3V | (1 << ICC_CTLR_EL3_IDBITS_SHIFT) | (7 << ICC_CTLR_EL3_PRIBITS_SHIFT); + + memset(cs->ich_apr, 0, sizeof(cs->ich_apr)); + cs->ich_hcr_el2 = 0; + memset(cs->ich_lr_el2, 0, sizeof(cs->ich_lr_el2)); + cs->ich_vmcr_el2 = ICH_VMCR_EL2_VFIQEN | + (icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR1_SHIFT) | + (icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR0_SHIFT); } static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
As the first step in adding support for the virtualization extensions to the GICv3 emulation: * add the necessary data fields to the state structures * add the fields to the migration state, as a subsection which is only present if virtualization is enabled The use of a subsection means we retain migration compatibility as EL2 is not enabled on any CPUs currently. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/intc/arm_gicv3_common.h | 18 ++++++++++++++++++ hw/intc/arm_gicv3_common.c | 25 +++++++++++++++++++++++++ hw/intc/arm_gicv3_cpuif.c | 13 +++++++++++++ 3 files changed, 56 insertions(+) -- 2.7.4