hw/intc/gicv3: Add data fields for virtualization support

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>
Message-id: 1483977924-14522-8-git-send-email-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2017-01-20 11:15:09 +00:00
parent e69d2fa065
commit 4eb833b5df
3 changed files with 56 additions and 0 deletions

View File

@ -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
}
};

View File

@ -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[] = {

View File

@ -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.