aboutsummaryrefslogtreecommitdiff
path: root/include/hw/intc
diff options
context:
space:
mode:
authorLuc Michel <luc.michel@greensocs.com>2018-08-14 17:17:20 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-08-14 17:17:20 +0100
commit5773c0494ae8045250288a801417270e0ef5de55 (patch)
treed1d8bdf1cdec530d4a8a47242b66f495bfba6e86 /include/hw/intc
parentb77473a0f7799f3484a1e483515c8bde7a872248 (diff)
downloadqemu-5773c0494ae8045250288a801417270e0ef5de55.zip
qemu-5773c0494ae8045250288a801417270e0ef5de55.tar.gz
qemu-5773c0494ae8045250288a801417270e0ef5de55.tar.bz2
intc/arm_gic: Add the virtualization extensions to the GIC state
Add the necessary parts of the virtualization extensions state to the GIC state. We choose to increase the size of the CPU interfaces state to add space for the vCPU interfaces (the GIC_NCPU_VCPU macro). This way, we'll be able to reuse most of the CPU interface code for the vCPUs. The only exception is the APR value, which is stored in h_apr in the virtual interface state for vCPUs. This is due to some complications with the GIC VMState, for which we don't want to break backward compatibility. APRs being stored in 2D arrays, increasing the second dimension would lead to some ugly VMState description. To avoid that, we keep it in h_apr for vCPUs. The vCPUs are numbered from GIC_NCPU to (GIC_NCPU * 2) - 1. The `gic_is_vcpu` function help to determine if a given CPU id correspond to a physical CPU or a virtual one. For the in-kernel KVM VGIC, since the exposed VGIC does not implement the virtualization extensions, we report an error if the corresponding property is set to true. Signed-off-by: Luc Michel <luc.michel@greensocs.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20180727095421.386-6-luc.michel@greensocs.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include/hw/intc')
-rw-r--r--include/hw/intc/arm_gic_common.h43
1 files changed, 36 insertions, 7 deletions
diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h
index af3ca18..b5585fe 100644
--- a/include/hw/intc/arm_gic_common.h
+++ b/include/hw/intc/arm_gic_common.h
@@ -30,6 +30,8 @@
#define GIC_NR_SGIS 16
/* Maximum number of possible CPU interfaces, determined by GIC architecture */
#define GIC_NCPU 8
+/* Maximum number of possible CPU interfaces with their respective vCPU */
+#define GIC_NCPU_VCPU (GIC_NCPU * 2)
#define MAX_NR_GROUP_PRIO 128
#define GIC_NR_APRS (MAX_NR_GROUP_PRIO / 32)
@@ -37,6 +39,17 @@
#define GIC_MIN_BPR 0
#define GIC_MIN_ABPR (GIC_MIN_BPR + 1)
+/* Architectural maximum number of list registers in the virtual interface */
+#define GIC_MAX_LR 64
+
+/* Only 32 priority levels and 32 preemption levels in the vCPU interfaces */
+#define GIC_VIRT_MAX_GROUP_PRIO_BITS 5
+#define GIC_VIRT_MAX_NR_GROUP_PRIO (1 << GIC_VIRT_MAX_GROUP_PRIO_BITS)
+#define GIC_VIRT_NR_APRS (GIC_VIRT_MAX_NR_GROUP_PRIO / 32)
+
+#define GIC_VIRT_MIN_BPR 2
+#define GIC_VIRT_MIN_ABPR (GIC_VIRT_MIN_BPR + 1)
+
typedef struct gic_irq_state {
/* The enable bits are only banked for per-cpu interrupts. */
uint8_t enabled;
@@ -57,6 +70,8 @@ typedef struct GICState {
qemu_irq parent_fiq[GIC_NCPU];
qemu_irq parent_virq[GIC_NCPU];
qemu_irq parent_vfiq[GIC_NCPU];
+ qemu_irq maintenance_irq[GIC_NCPU];
+
/* GICD_CTLR; for a GIC with the security extensions the NS banked version
* of this register is just an alias of bit 1 of the S banked version.
*/
@@ -64,7 +79,7 @@ typedef struct GICState {
/* GICC_CTLR; again, the NS banked version is just aliases of bits of
* the S banked register, so our state only needs to store the S version.
*/
- uint32_t cpu_ctlr[GIC_NCPU];
+ uint32_t cpu_ctlr[GIC_NCPU_VCPU];
gic_irq_state irq_state[GIC_MAXIRQ];
uint8_t irq_target[GIC_MAXIRQ];
@@ -78,9 +93,9 @@ typedef struct GICState {
*/
uint8_t sgi_pending[GIC_NR_SGIS][GIC_NCPU];
- uint16_t priority_mask[GIC_NCPU];
- uint16_t running_priority[GIC_NCPU];
- uint16_t current_pending[GIC_NCPU];
+ uint16_t priority_mask[GIC_NCPU_VCPU];
+ uint16_t running_priority[GIC_NCPU_VCPU];
+ uint16_t current_pending[GIC_NCPU_VCPU];
/* If we present the GICv2 without security extensions to a guest,
* the guest can configure the GICC_CTLR to configure group 1 binary point
@@ -88,8 +103,8 @@ typedef struct GICState {
* For a GIC with Security Extensions we use use bpr for the
* secure copy and abpr as storage for the non-secure copy of the register.
*/
- uint8_t bpr[GIC_NCPU];
- uint8_t abpr[GIC_NCPU];
+ uint8_t bpr[GIC_NCPU_VCPU];
+ uint8_t abpr[GIC_NCPU_VCPU];
/* The APR is implementation defined, so we choose a layout identical to
* the KVM ABI layout for QEMU's implementation of the gic:
@@ -100,6 +115,15 @@ typedef struct GICState {
uint32_t apr[GIC_NR_APRS][GIC_NCPU];
uint32_t nsapr[GIC_NR_APRS][GIC_NCPU];
+ /* Virtual interface control registers */
+ uint32_t h_hcr[GIC_NCPU];
+ uint32_t h_misr[GIC_NCPU];
+ uint32_t h_lr[GIC_MAX_LR][GIC_NCPU];
+ uint32_t h_apr[GIC_NCPU];
+
+ /* Number of LRs implemented in this GIC instance */
+ uint32_t num_lrs;
+
uint32_t num_cpu;
MemoryRegion iomem; /* Distributor */
@@ -108,9 +132,13 @@ typedef struct GICState {
*/
struct GICState *backref[GIC_NCPU];
MemoryRegion cpuiomem[GIC_NCPU + 1]; /* CPU interfaces */
+ MemoryRegion vifaceiomem[GIC_NCPU + 1]; /* Virtual interfaces */
+ MemoryRegion vcpuiomem; /* vCPU interface */
+
uint32_t num_irq;
uint32_t revision;
bool security_extn;
+ bool virt_extn;
bool irq_reset_nonsecure; /* configure IRQs as group 1 (NS) on reset? */
int dev_fd; /* kvm device fd if backed by kvm vgic support */
Error *migration_blocker;
@@ -134,6 +162,7 @@ typedef struct ARMGICCommonClass {
} ARMGICCommonClass;
void gic_init_irqs_and_mmio(GICState *s, qemu_irq_handler handler,
- const MemoryRegionOps *ops);
+ const MemoryRegionOps *ops,
+ const MemoryRegionOps *virt_ops);
#endif