Signed-off-by: Nikhil Devshatwar <[email protected]>
---
 hypervisor/arch/arm-common/Kbuild               |   1 +
 hypervisor/arch/arm-common/gic-v3.c             | 456 ++++++++++++++++++++++++
 hypervisor/arch/arm-common/include/asm/gic_v3.h | 269 ++++++++++++++
 hypervisor/arch/arm/Kbuild                      |   1 -
 hypervisor/arch/arm/gic-v3.c                    | 456 ------------------------
 hypervisor/arch/arm/include/asm/gic_v3.h        | 269 --------------
 6 files changed, 726 insertions(+), 726 deletions(-)
 create mode 100644 hypervisor/arch/arm-common/gic-v3.c
 create mode 100644 hypervisor/arch/arm-common/include/asm/gic_v3.h
 delete mode 100644 hypervisor/arch/arm/gic-v3.c
 delete mode 100644 hypervisor/arch/arm/include/asm/gic_v3.h

diff --git a/hypervisor/arch/arm-common/Kbuild 
b/hypervisor/arch/arm-common/Kbuild
index 7874b9e..779e204 100644
--- a/hypervisor/arch/arm-common/Kbuild
+++ b/hypervisor/arch/arm-common/Kbuild
@@ -16,5 +16,6 @@ ccflags-$(CONFIG_JAILHOUSE_GCOV) += -fprofile-arcs 
-ftest-coverage
 OBJS-y += dbg-write.o lib.o psci.o control.o paging.o mmu_cell.o
 OBJS-y += irqchip.o pci.o ivshmem.o uart-pl011.o uart-xuartps.o
 OBJS-$(CONFIG_ARM_GIC_V2) += gic-v2.o
+OBJS-$(CONFIG_ARM_GIC_V3) += gic-v3.o
 
 COMMON_OBJECTS = $(addprefix ../arm-common/,$(OBJS-y))
diff --git a/hypervisor/arch/arm-common/gic-v3.c 
b/hypervisor/arch/arm-common/gic-v3.c
new file mode 100644
index 0000000..2ea947f
--- /dev/null
+++ b/hypervisor/arch/arm-common/gic-v3.c
@@ -0,0 +1,456 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) ARM Limited, 2014
+ *
+ * Authors:
+ *  Jean-Philippe Brucker <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <jailhouse/control.h>
+#include <jailhouse/mmio.h>
+#include <jailhouse/printk.h>
+#include <jailhouse/processor.h>
+#include <jailhouse/types.h>
+#include <asm/control.h>
+#include <asm/gic.h>
+#include <asm/irqchip.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
+
+/*
+ * This implementation assumes that the kernel driver already initialised most
+ * of the GIC.
+ * There is almost no instruction barrier, since IRQs are always disabled in 
the
+ * hyp, and ERET serves as the context synchronization event.
+ */
+
+static unsigned int gic_num_lr;
+static unsigned int gic_num_priority_bits;
+static u32 gic_version;
+
+static void *gicr_base;
+
+static int gic_init(void)
+{
+       /* TODO: need to validate more? */
+       if (!(mmio_read32(gicd_base + GICD_CTLR) & GICD_CTLR_ARE_NS))
+               return trace_error(-EIO);
+
+       /* Let the per-cpu code access the redistributors */
+       gicr_base = paging_map_device(
+                       system_config->platform_info.arm.gicr_base, GICR_SIZE);
+       if (!gicr_base)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static void gic_clear_pending_irqs(void)
+{
+       unsigned int n;
+
+       /* Clear list registers. */
+       for (n = 0; n < gic_num_lr; n++)
+               gic_write_lr(n, 0);
+
+       /* Clear active priority bits */
+       if (gic_num_priority_bits >= 5)
+               arm_write_sysreg(ICH_AP1R0_EL2, 0);
+       if (gic_num_priority_bits >= 6)
+               arm_write_sysreg(ICH_AP1R1_EL2, 0);
+       if (gic_num_priority_bits > 6) {
+               arm_write_sysreg(ICH_AP1R2_EL2, 0);
+               arm_write_sysreg(ICH_AP1R3_EL2, 0);
+       }
+}
+
+static void gic_cpu_reset(struct per_cpu *cpu_data)
+{
+       unsigned int mnt_irq = system_config->platform_info.arm.maintenance_irq;
+       void *gicr = cpu_data->gicr_base + GICR_SGI_BASE;
+
+       gic_clear_pending_irqs();
+
+       /* Ensure all IPIs and the maintenance PPI are enabled. */
+       mmio_write32(gicr + GICR_ISENABLER, 0x0000ffff | (1 << mnt_irq));
+
+       /* Disable PPIs, except for the maintenance interrupt. */
+       mmio_write32(gicr + GICR_ICENABLER, 0xffff0000 & ~(1 << mnt_irq));
+
+       /* Deactivate all active PPIs */
+       mmio_write32(gicr + GICR_ICACTIVER, 0xffff0000);
+
+       arm_write_sysreg(ICH_VMCR_EL2, 0);
+}
+
+static int gic_cpu_init(struct per_cpu *cpu_data)
+{
+       unsigned int mnt_irq = system_config->platform_info.arm.maintenance_irq;
+       u64 typer;
+       u32 pidr;
+       u32 cell_icc_ctlr, cell_icc_pmr, cell_icc_igrpen1;
+       u32 ich_vtr;
+       u32 ich_vmcr;
+       void *redist_base = gicr_base;
+
+       /* Find redistributor */
+       do {
+               pidr = mmio_read32(redist_base + GICR_PIDR2);
+               gic_version = GICR_PIDR2_ARCH(pidr);
+               if (gic_version != 3 && gic_version != 4)
+                       break;
+
+               typer = mmio_read64(redist_base + GICR_TYPER);
+               if ((typer >> 32) == cpu_data->cpu_id) {
+                       cpu_data->gicr_base = redist_base;
+                       break;
+               }
+
+               redist_base += gic_version == 4 ? 0x40000 : 0x20000;
+       } while (!(typer & GICR_TYPER_Last));
+
+       if (!cpu_data->gicr_base) {
+               printk("GIC: No redist found for CPU%d\n", cpu_data->cpu_id);
+               return -ENODEV;
+       }
+
+       /* Ensure all IPIs and the maintenance PPI are enabled. */
+       mmio_write32(redist_base + GICR_SGI_BASE + GICR_ISENABLER,
+                    0x0000ffff | (1 << mnt_irq));
+
+       /*
+        * Set EOIMode to 1
+        * This allow to drop the priority of level-triggered interrupts without
+        * deactivating them, and thus ensure that they won't be immediately
+        * re-triggered. (e.g. timer)
+        * They can then be injected into the guest using the LR.HW bit, and
+        * will be deactivated once the guest does an EOI after handling the
+        * interrupt source.
+        */
+       arm_read_sysreg(ICC_CTLR_EL1, cell_icc_ctlr);
+       arm_write_sysreg(ICC_CTLR_EL1, ICC_CTLR_EOImode);
+
+       arm_read_sysreg(ICC_PMR_EL1, cell_icc_pmr);
+       arm_write_sysreg(ICC_PMR_EL1, ICC_PMR_DEFAULT);
+
+       arm_read_sysreg(ICC_IGRPEN1_EL1, cell_icc_igrpen1);
+       arm_write_sysreg(ICC_IGRPEN1_EL1, ICC_IGRPEN1_EN);
+
+       arm_read_sysreg(ICH_VTR_EL2, ich_vtr);
+       gic_num_lr = (ich_vtr & 0xf) + 1;
+       gic_num_priority_bits = (ich_vtr >> 29) + 1;
+
+       /*
+        * Clear pending virtual IRQs in case anything is left from previous
+        * use. Physically pending IRQs will be forwarded to Linux once we
+        * enable interrupts for the hypervisor.
+        */
+       gic_clear_pending_irqs();
+
+       ich_vmcr = (cell_icc_pmr & ICC_PMR_MASK) << ICH_VMCR_VPMR_SHIFT;
+       if (cell_icc_igrpen1 & ICC_IGRPEN1_EN)
+               ich_vmcr |= ICH_VMCR_VENG1;
+       if (cell_icc_ctlr & ICC_CTLR_EOImode)
+               ich_vmcr |= ICH_VMCR_VEOIM;
+       arm_write_sysreg(ICH_VMCR_EL2, ich_vmcr);
+
+       /* After this, the cells access the virtual interface of the GIC. */
+       arm_write_sysreg(ICH_HCR_EL2, ICH_HCR_EN);
+
+       return 0;
+}
+
+static void gic_cpu_shutdown(struct per_cpu *cpu_data)
+{
+       u32 ich_vmcr, icc_ctlr, cell_icc_igrpen1;
+
+       if (!cpu_data->gicr_base)
+               return;
+
+       arm_write_sysreg(ICH_HCR_EL2, 0);
+
+       /* Disable the maintenance interrupt - not used by Linux. */
+       mmio_write32(cpu_data->gicr_base + GICR_SGI_BASE + GICR_ICENABLER,
+                    1 << system_config->platform_info.arm.maintenance_irq);
+
+       /* Restore the root config */
+       arm_read_sysreg(ICH_VMCR_EL2, ich_vmcr);
+
+       if (!(ich_vmcr & ICH_VMCR_VEOIM)) {
+               arm_read_sysreg(ICC_CTLR_EL1, icc_ctlr);
+               icc_ctlr &= ~ICC_CTLR_EOImode;
+               arm_write_sysreg(ICC_CTLR_EL1, icc_ctlr);
+       }
+       if (!(ich_vmcr & ICH_VMCR_VENG1)) {
+               arm_read_sysreg(ICC_IGRPEN1_EL1, cell_icc_igrpen1);
+               cell_icc_igrpen1 &= ~ICC_IGRPEN1_EN;
+               arm_write_sysreg(ICC_IGRPEN1_EL1, cell_icc_igrpen1);
+       }
+}
+
+static void gic_adjust_irq_target(struct cell *cell, u16 irq_id)
+{
+       void *irouter = gicd_base + GICD_IROUTER + irq_id;
+       u32 route = mmio_read32(irouter);
+
+       if (!cell_owns_cpu(cell, route))
+               mmio_write32(irouter, first_cpu(cell->cpu_set));
+}
+
+static enum mmio_result gic_handle_redist_access(void *arg,
+                                                struct mmio_access *mmio)
+{
+       struct cell *cell = this_cell();
+       unsigned int cpu;
+       unsigned int virt_id;
+       unsigned int redist_size = (gic_version == 4) ? 0x40000 : 0x20000;
+       void *phys_redist = NULL;
+       unsigned long offs;
+
+       /*
+        * The redistributor accessed by the cell is not the one stored in these
+        * cpu_datas, but the one associated to its virtual id. So we first
+        * need to translate the redistributor address.
+        */
+       for_each_cpu(cpu, cell->cpu_set) {
+               virt_id = arm_cpu_phys2virt(cpu);
+               offs = per_cpu(virt_id)->gicr_base - gicr_base;
+               if (mmio->address >= offs &&
+                   mmio->address < offs + redist_size) {
+                       phys_redist = per_cpu(cpu)->gicr_base;
+                       break;
+               }
+       }
+
+       if (phys_redist == NULL)
+               return MMIO_ERROR;
+
+       mmio->address -= offs;
+
+       /* Change the ID register, all other accesses are allowed. */
+       if (!mmio->is_write) {
+               switch (mmio->address) {
+               case GICR_TYPER:
+                       if (virt_id == cell->arch.last_virt_id)
+                               mmio->value = GICR_TYPER_Last;
+                       else
+                               mmio->value = 0;
+                       /* AArch64 can use a writeq for this register */
+                       if (mmio->size == 8)
+                               mmio->value |= (u64)virt_id << 32;
+
+                       return MMIO_HANDLED;
+               case GICR_TYPER + 4:
+                       /* Upper bits contain the affinity */
+                       mmio->value = virt_id;
+                       return MMIO_HANDLED;
+               }
+       }
+       mmio_perform_access(phys_redist, mmio);
+       return MMIO_HANDLED;
+}
+
+static int gic_cell_init(struct cell *cell)
+{
+       mmio_region_register(cell, system_config->platform_info.arm.gicr_base,
+                            GICR_SIZE, gic_handle_redist_access, NULL);
+
+       return 0;
+}
+
+static int gic_send_sgi(struct sgi *sgi)
+{
+       u64 val;
+       u16 targets = sgi->targets;
+
+       if (!is_sgi(sgi->id))
+               return -EINVAL;
+
+       if (sgi->routing_mode == 2)
+               targets = 1 << phys_processor_id();
+
+       val = (u64)sgi->aff3 << ICC_SGIR_AFF3_SHIFT
+           | (u64)sgi->aff2 << ICC_SGIR_AFF2_SHIFT
+           | sgi->aff1 << ICC_SGIR_AFF1_SHIFT
+           | (targets & ICC_SGIR_TARGET_MASK)
+           | (sgi->id & 0xf) << ICC_SGIR_IRQN_SHIFT;
+
+       if (sgi->routing_mode == 1)
+               val |= ICC_SGIR_ROUTING_BIT;
+
+       /*
+        * Ensure the targets see our modifications to their per-cpu
+        * structures.
+        */
+       dsb(ish);
+
+       arm_write_sysreg(ICC_SGI1R_EL1, val);
+       isb();
+
+       return 0;
+}
+
+void gicv3_handle_sgir_write(u64 sgir)
+{
+       struct sgi sgi;
+       unsigned long routing_mode = !!(sgir & ICC_SGIR_ROUTING_BIT);
+
+       /* FIXME: clusters are not supported yet. */
+       sgi.targets = sgir & ICC_SGIR_TARGET_MASK;
+       sgi.routing_mode = routing_mode;
+       sgi.aff1 = sgir >> ICC_SGIR_AFF1_SHIFT & 0xff;
+       sgi.aff2 = sgir >> ICC_SGIR_AFF2_SHIFT & 0xff;
+       sgi.aff3 = sgir >> ICC_SGIR_AFF3_SHIFT & 0xff;
+       sgi.id = sgir >> ICC_SGIR_IRQN_SHIFT & 0xf;
+
+       gic_handle_sgir_write(&sgi, true);
+}
+
+/*
+ * GICv3 uses a 64bit register IROUTER for each IRQ
+ */
+enum mmio_result gic_handle_irq_route(struct mmio_access *mmio,
+                                     unsigned int irq)
+{
+       struct cell *cell = this_cell();
+       unsigned int cpu;
+
+       /* Ignore aff3 on AArch32 (return 0) */
+       if (mmio->size == 4 && (mmio->address % 8))
+               return MMIO_HANDLED;
+
+       /* SGIs and PPIs are res0 */
+       if (!is_spi(irq))
+               return MMIO_HANDLED;
+
+       /*
+        * Ignore accesses to SPIs that do not belong to the cell. This isn't
+        * forbidden, because the guest driver may simply iterate over all
+        * registers at initialisation
+        */
+       if (!irqchip_irq_in_cell(cell, irq))
+               return MMIO_HANDLED;
+
+       /* Translate the virtual cpu id into the physical one */
+       if (mmio->is_write) {
+               mmio->value = arm_cpu_virt2phys(cell, mmio->value);
+               if (mmio->value == -1) {
+                       printk("Attempt to route IRQ%d outside of cell\n", irq);
+                       return MMIO_ERROR;
+               }
+               mmio_perform_access(gicd_base, mmio);
+       } else {
+               cpu = mmio_read32(gicd_base + GICD_IROUTER + 8 * irq);
+               mmio->value = arm_cpu_phys2virt(cpu);
+       }
+       return MMIO_HANDLED;
+}
+
+static void gic_eoi_irq(u32 irq_id, bool deactivate)
+{
+       arm_write_sysreg(ICC_EOIR1_EL1, irq_id);
+       if (deactivate)
+               arm_write_sysreg(ICC_DIR_EL1, irq_id);
+}
+
+static int gic_inject_irq(struct per_cpu *cpu_data, u16 irq_id)
+{
+       int i;
+       int free_lr = -1;
+       u32 elsr;
+       u64 lr;
+
+       arm_read_sysreg(ICH_ELSR_EL2, elsr);
+       for (i = 0; i < gic_num_lr; i++) {
+               if ((elsr >> i) & 1) {
+                       /* Entry is invalid, candidate for injection */
+                       if (free_lr == -1)
+                               free_lr = i;
+                       continue;
+               }
+
+               /*
+                * Entry is in use, check that it doesn't match the one we want
+                * to inject.
+                */
+               lr = gic_read_lr(i);
+
+               /*
+                * A strict phys->virt id mapping is used for SPIs, so this test
+                * should be sufficient.
+                */
+               if ((u32)lr == irq_id)
+                       return -EEXIST;
+       }
+
+       if (free_lr == -1)
+               /* All list registers are in use */
+               return -EBUSY;
+
+       lr = irq_id;
+       /* Only group 1 interrupts */
+       lr |= ICH_LR_GROUP_BIT;
+       lr |= ICH_LR_PENDING;
+       if (!is_sgi(irq_id)) {
+               lr |= ICH_LR_HW_BIT;
+               lr |= (u64)irq_id << ICH_LR_PHYS_ID_SHIFT;
+       }
+
+       gic_write_lr(free_lr, lr);
+
+       return 0;
+}
+
+static void gicv3_enable_maint_irq(bool enable)
+{
+       u32 hcr;
+
+       arm_read_sysreg(ICH_HCR_EL2, hcr);
+       if (enable)
+               hcr |= ICH_HCR_UIE;
+       else
+               hcr &= ~ICH_HCR_UIE;
+       arm_write_sysreg(ICH_HCR_EL2, hcr);
+}
+
+static bool gicv3_has_pending_irqs(void)
+{
+       unsigned int n;
+
+       for (n = 0; n < gic_num_lr; n++)
+               if (gic_read_lr(n) & ICH_LR_PENDING)
+                       return true;
+
+       return false;
+}
+
+static enum mmio_result gicv3_handle_irq_target(struct mmio_access *mmio,
+                                               unsigned int irq)
+{
+       /* ignore writes, we are in affinity routing mode */
+       return MMIO_HANDLED;
+}
+
+unsigned int irqchip_mmio_count_regions(struct cell *cell)
+{
+       return 2;
+}
+
+struct irqchip_ops irqchip = {
+       .init = gic_init,
+       .cpu_init = gic_cpu_init,
+       .cpu_reset = gic_cpu_reset,
+       .cpu_shutdown = gic_cpu_shutdown,
+       .cell_init = gic_cell_init,
+       .adjust_irq_target = gic_adjust_irq_target,
+       .send_sgi = gic_send_sgi,
+       .inject_irq = gic_inject_irq,
+       .enable_maint_irq = gicv3_enable_maint_irq,
+       .has_pending_irqs = gicv3_has_pending_irqs,
+       .eoi_irq = gic_eoi_irq,
+       .handle_irq_target = gicv3_handle_irq_target,
+};
diff --git a/hypervisor/arch/arm-common/include/asm/gic_v3.h 
b/hypervisor/arch/arm-common/include/asm/gic_v3.h
new file mode 100644
index 0000000..d1b9346
--- /dev/null
+++ b/hypervisor/arch/arm-common/include/asm/gic_v3.h
@@ -0,0 +1,269 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) ARM Limited, 2014
+ *
+ * Authors:
+ *  Jean-Philippe Brucker <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef _JAILHOUSE_ASM_GIC_V3_H
+#define _JAILHOUSE_ASM_GIC_V3_H
+
+#include <asm/sysregs.h>
+
+#define GICD_SIZE              0x10000
+#define GICR_SIZE              0x100000
+
+#define GICD_CIDR0             0xfff0
+#define GICD_CIDR1             0xfff4
+#define GICD_CIDR2             0xfff8
+#define GICD_CIDR3             0xfffc
+
+#define GICD_PIDR0             0xffe0
+#define GICD_PIDR1             0xffe4
+#define GICD_PIDR2             0xffe8
+#define GICD_PIDR3             0xffec
+#define GICD_PIDR4             0xffd0
+#define GICD_PIDR5             0xffd4
+#define GICD_PIDR6             0xffd8
+#define GICD_PIDR7             0xffdc
+
+#define GICR_CTLR              GICD_CTLR
+#define GICR_TYPER             0x0008
+#define GICR_WAKER             0x0014
+#define GICR_CIDR0             GICD_CIDR0
+#define GICR_CIDR1             GICD_CIDR1
+#define GICR_CIDR2             GICD_CIDR2
+#define GICR_CIDR3             GICD_CIDR3
+#define GICR_PIDR0             GICD_PIDR0
+#define GICR_PIDR1             GICD_PIDR1
+#define GICR_PIDR2             GICD_PIDR2
+#define GICR_PIDR3             GICD_PIDR3
+#define GICR_PIDR4             GICD_PIDR4
+#define GICR_PIDR5             GICD_PIDR5
+#define GICR_PIDR6             GICD_PIDR6
+#define GICR_PIDR7             GICD_PIDR7
+
+#define GICR_SGI_BASE          0x10000
+#define GICR_IGROUPR           GICD_IGROUPR
+#define GICR_ISENABLER         GICD_ISENABLER
+#define GICR_ICENABLER         GICD_ICENABLER
+#define GICR_ISACTIVER         GICD_ISACTIVER
+#define GICR_ICACTIVER         GICD_ICACTIVER
+#define GICR_IPRIORITY         GICD_IPRIORITY
+
+#define GICR_TYPER_Last                (1 << 4)
+#define GICR_PIDR2_ARCH                GICD_PIDR2_ARCH
+
+#define ICC_IAR1_EL1           SYSREG_32(0, c12, c12, 0)
+#define ICC_EOIR1_EL1          SYSREG_32(0, c12, c12, 1)
+#define ICC_HPPIR1_EL1         SYSREG_32(0, c12, c12, 2)
+#define ICC_BPR1_EL1           SYSREG_32(0, c12, c12, 3)
+#define ICC_DIR_EL1            SYSREG_32(0, c12, c11, 1)
+#define ICC_PMR_EL1            SYSREG_32(0, c4, c6, 0)
+#define ICC_RPR_EL1            SYSREG_32(0, c12, c11, 3)
+#define ICC_CTLR_EL1           SYSREG_32(0, c12, c12, 4)
+#define ICC_SRE_EL1            SYSREG_32(0, c12, c12, 5)
+#define ICC_SRE_EL2            SYSREG_32(4, c12, c9, 5)
+#define ICC_IGRPEN1_EL1                SYSREG_32(0, c12, c12, 7)
+#define ICC_SGI1R_EL1          SYSREG_64(0, c12)
+#define ICC_AP1R0_EL1          SYSREG_32(0, c12, c9, 0)
+#define ICC_AP1R1_EL1          SYSREG_32(0, c12, c9, 1)
+#define ICC_AP1R2_EL1          SYSREG_32(0, c12, c9, 2)
+#define ICC_AP1R3_EL1          SYSREG_32(0, c12, c9, 3)
+
+#define ICH_HCR_EL2            SYSREG_32(4, c12, c11, 0)
+#define ICH_VTR_EL2            SYSREG_32(4, c12, c11, 1)
+#define ICH_MISR_EL2           SYSREG_32(4, c12, c11, 2)
+#define ICH_EISR_EL2           SYSREG_32(4, c12, c11, 3)
+#define ICH_ELSR_EL2           SYSREG_32(4, c12, c11, 5)
+#define ICH_VMCR_EL2           SYSREG_32(4, c12, c11, 7)
+#define ICH_AP1R0_EL2          SYSREG_32(4, c12, c9, 0)
+#define ICH_AP1R1_EL2          SYSREG_32(4, c12, c9, 1)
+#define ICH_AP1R2_EL2          SYSREG_32(4, c12, c9, 2)
+#define ICH_AP1R3_EL2          SYSREG_32(4, c12, c9, 3)
+
+/* Different on AArch32 and AArch64... */
+#define __ICH_LR0(x)           SYSREG_32(4, c12, c12, x)
+#define __ICH_LR8(x)           SYSREG_32(4, c12, c13, x)
+#define __ICH_LRC0(x)          SYSREG_32(4, c12, c14, x)
+#define __ICH_LRC8(x)          SYSREG_32(4, c12, c15, x)
+
+#define ICH_LR0                        __ICH_LR0(0)
+#define ICH_LR1                        __ICH_LR0(1)
+#define ICH_LR2                        __ICH_LR0(2)
+#define ICH_LR3                        __ICH_LR0(3)
+#define ICH_LR4                        __ICH_LR0(4)
+#define ICH_LR5                        __ICH_LR0(5)
+#define ICH_LR6                        __ICH_LR0(6)
+#define ICH_LR7                        __ICH_LR0(7)
+#define ICH_LR8                        __ICH_LR8(0)
+#define ICH_LR9                        __ICH_LR8(1)
+#define ICH_LR10               __ICH_LR8(2)
+#define ICH_LR11               __ICH_LR8(3)
+#define ICH_LR12               __ICH_LR8(4)
+#define ICH_LR13               __ICH_LR8(5)
+#define ICH_LR14               __ICH_LR8(6)
+#define ICH_LR15               __ICH_LR8(7)
+#define ICH_LRC0               __ICH_LRC0(0)
+#define ICH_LRC1               __ICH_LRC0(1)
+#define ICH_LRC2               __ICH_LRC0(2)
+#define ICH_LRC3               __ICH_LRC0(3)
+#define ICH_LRC4               __ICH_LRC0(4)
+#define ICH_LRC5               __ICH_LRC0(5)
+#define ICH_LRC6               __ICH_LRC0(6)
+#define ICH_LRC7               __ICH_LRC0(7)
+#define ICH_LRC8               __ICH_LRC8(0)
+#define ICH_LRC9               __ICH_LRC8(1)
+#define ICH_LRC10              __ICH_LRC8(2)
+#define ICH_LRC11              __ICH_LRC8(3)
+#define ICH_LRC12              __ICH_LRC8(4)
+#define ICH_LRC13              __ICH_LRC8(5)
+#define ICH_LRC14              __ICH_LRC8(6)
+#define ICH_LRC15              __ICH_LRC8(7)
+
+#define ICC_CTLR_EOImode       0x2
+#define ICC_PMR_MASK           0xff
+#define ICC_PMR_DEFAULT                0xf0
+#define ICC_IGRPEN1_EN         0x1
+
+#define ICC_SGIR_AFF3_SHIFT    48
+#define ICC_SGIR_AFF2_SHIFT    32
+#define ICC_SGIR_AFF1_SHIFT    16
+#define ICC_SGIR_TARGET_MASK   0xffff
+#define ICC_SGIR_IRQN_SHIFT    24
+#define ICC_SGIR_ROUTING_BIT   (1ULL << 40)
+
+#define ICH_HCR_EN             (1 << 0)
+#define ICH_HCR_UIE            (1 << 1)
+#define ICH_HCR_LRENPIE                (1 << 2)
+#define ICH_HCR_NPIE           (1 << 3)
+#define ICH_HCR_VGRP0EIE       (1 << 4)
+#define ICH_HCR_VGRP0DIE       (1 << 5)
+#define ICH_HCR_VGRP1EIE       (1 << 6)
+#define ICH_HCR_VGRP1DIE       (1 << 7)
+#define ICH_HCR_VARE           (1 << 9)
+#define ICH_HCR_TC             (1 << 10)
+#define ICH_HCR_TALL0          (1 << 11)
+#define ICH_HCR_TALL1          (1 << 12)
+#define ICH_HCR_TSEI           (1 << 13)
+#define ICH_HCR_EOICount       (0x1f << 27)
+
+#define ICH_MISR_EOI           (1 << 0)
+#define ICH_MISR_U             (1 << 1)
+#define ICH_MISR_LRENP         (1 << 2)
+#define ICH_MISR_NP            (1 << 3)
+#define ICH_MISR_VGRP0E                (1 << 4)
+#define ICH_MISR_VGRP0D                (1 << 5)
+#define ICH_MISR_VGRP1E                (1 << 6)
+#define ICH_MISR_VGRP1D                (1 << 7)
+
+#define ICH_VMCR_VENG0         (1 << 0)
+#define ICH_VMCR_VENG1         (1 << 1)
+#define ICH_VMCR_VACKCTL       (1 << 2)
+#define ICH_VMCR_VFIQEN                (1 << 3)
+#define ICH_VMCR_VCBPR         (1 << 4)
+#define ICH_VMCR_VEOIM         (1 << 9)
+#define ICH_VMCR_VBPR1_SHIFT   18
+#define ICH_VMCR_VBPR0_SHIFT   21
+#define ICH_VMCR_VPMR_SHIFT    24
+
+/* List registers upper bits */
+#define ICH_LR_INVALID         (0x0ULL << 62)
+#define ICH_LR_PENDING         (0x1ULL << 62)
+#define ICH_LR_ACTIVE          (0x2ULL << 62)
+#define ICH_LR_PENDACTIVE      (0x3ULL << 62)
+#define ICH_LR_HW_BIT          (0x1ULL << 61)
+#define ICH_LR_GROUP_BIT       (0x1ULL << 60)
+#define ICH_LR_PRIORITY_SHIFT  48
+#define ICH_LR_SGI_EOI         (0x1ULL << 41)
+#define ICH_LR_PHYS_ID_SHIFT   32
+
+#ifndef __ASSEMBLY__
+
+#include <jailhouse/types.h>
+
+static inline u64 gic_read_lr(unsigned int n)
+{
+       u32 lr, lrc;
+
+       switch (n) {
+#define __READ_LR(n)                                   \
+       case n:                                         \
+               arm_read_sysreg(ICH_LR##n, lr);         \
+               arm_read_sysreg(ICH_LRC##n, lrc);       \
+               break;
+
+       __READ_LR(0)
+       __READ_LR(1)
+       __READ_LR(2)
+       __READ_LR(3)
+       __READ_LR(4)
+       __READ_LR(5)
+       __READ_LR(6)
+       __READ_LR(7)
+       __READ_LR(8)
+       __READ_LR(9)
+       __READ_LR(10)
+       __READ_LR(11)
+       __READ_LR(12)
+       __READ_LR(13)
+       __READ_LR(14)
+       __READ_LR(15)
+#undef __READ_LR
+
+       default:
+               return (u64)(-1);
+       }
+
+       return (u64)lrc << 32 | lr;
+}
+
+static inline void gic_write_lr(unsigned int n, u64 val)
+{
+       u32 lr = (u32)val;
+       u32 lrc = val >> 32;
+
+       switch (n) {
+#define __WRITE_LR(n)                                  \
+       case n:                                         \
+               arm_write_sysreg(ICH_LR##n, lr);        \
+               arm_write_sysreg(ICH_LRC##n, lrc);      \
+               break;
+
+       __WRITE_LR(0)
+       __WRITE_LR(1)
+       __WRITE_LR(2)
+       __WRITE_LR(3)
+       __WRITE_LR(4)
+       __WRITE_LR(5)
+       __WRITE_LR(6)
+       __WRITE_LR(7)
+       __WRITE_LR(8)
+       __WRITE_LR(9)
+       __WRITE_LR(10)
+       __WRITE_LR(11)
+       __WRITE_LR(12)
+       __WRITE_LR(13)
+       __WRITE_LR(14)
+       __WRITE_LR(15)
+#undef __WRITE_LR
+       }
+}
+
+static inline u32 gic_read_iar(void)
+{
+       u32 irq_id;
+
+       arm_read_sysreg(ICC_IAR1_EL1, irq_id);
+       return irq_id;
+}
+
+void gicv3_handle_sgir_write(u64 sgir);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _JAILHOUSE_ASM_GIC_V3_H */
diff --git a/hypervisor/arch/arm/Kbuild b/hypervisor/arch/arm/Kbuild
index b996871..04e835c 100644
--- a/hypervisor/arch/arm/Kbuild
+++ b/hypervisor/arch/arm/Kbuild
@@ -26,5 +26,4 @@ obj-y += mmu_hyp.o caches.o mach-stubs.o
 #  should switch to that for higher granularity, but gcc7 is not even there
 CFLAGS_mmu_hyp.o += -fno-profile-arcs -fno-test-coverage
 
-obj-$(CONFIG_ARM_GIC_V3) += gic-v3.o
 obj-$(CONFIG_MACH_VEXPRESS) += mach-vexpress.o
diff --git a/hypervisor/arch/arm/gic-v3.c b/hypervisor/arch/arm/gic-v3.c
deleted file mode 100644
index 2ea947f..0000000
--- a/hypervisor/arch/arm/gic-v3.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * Jailhouse, a Linux-based partitioning hypervisor
- *
- * Copyright (c) ARM Limited, 2014
- *
- * Authors:
- *  Jean-Philippe Brucker <[email protected]>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- */
-
-#include <jailhouse/control.h>
-#include <jailhouse/mmio.h>
-#include <jailhouse/printk.h>
-#include <jailhouse/processor.h>
-#include <jailhouse/types.h>
-#include <asm/control.h>
-#include <asm/gic.h>
-#include <asm/irqchip.h>
-#include <asm/setup.h>
-#include <asm/traps.h>
-
-/*
- * This implementation assumes that the kernel driver already initialised most
- * of the GIC.
- * There is almost no instruction barrier, since IRQs are always disabled in 
the
- * hyp, and ERET serves as the context synchronization event.
- */
-
-static unsigned int gic_num_lr;
-static unsigned int gic_num_priority_bits;
-static u32 gic_version;
-
-static void *gicr_base;
-
-static int gic_init(void)
-{
-       /* TODO: need to validate more? */
-       if (!(mmio_read32(gicd_base + GICD_CTLR) & GICD_CTLR_ARE_NS))
-               return trace_error(-EIO);
-
-       /* Let the per-cpu code access the redistributors */
-       gicr_base = paging_map_device(
-                       system_config->platform_info.arm.gicr_base, GICR_SIZE);
-       if (!gicr_base)
-               return -ENOMEM;
-
-       return 0;
-}
-
-static void gic_clear_pending_irqs(void)
-{
-       unsigned int n;
-
-       /* Clear list registers. */
-       for (n = 0; n < gic_num_lr; n++)
-               gic_write_lr(n, 0);
-
-       /* Clear active priority bits */
-       if (gic_num_priority_bits >= 5)
-               arm_write_sysreg(ICH_AP1R0_EL2, 0);
-       if (gic_num_priority_bits >= 6)
-               arm_write_sysreg(ICH_AP1R1_EL2, 0);
-       if (gic_num_priority_bits > 6) {
-               arm_write_sysreg(ICH_AP1R2_EL2, 0);
-               arm_write_sysreg(ICH_AP1R3_EL2, 0);
-       }
-}
-
-static void gic_cpu_reset(struct per_cpu *cpu_data)
-{
-       unsigned int mnt_irq = system_config->platform_info.arm.maintenance_irq;
-       void *gicr = cpu_data->gicr_base + GICR_SGI_BASE;
-
-       gic_clear_pending_irqs();
-
-       /* Ensure all IPIs and the maintenance PPI are enabled. */
-       mmio_write32(gicr + GICR_ISENABLER, 0x0000ffff | (1 << mnt_irq));
-
-       /* Disable PPIs, except for the maintenance interrupt. */
-       mmio_write32(gicr + GICR_ICENABLER, 0xffff0000 & ~(1 << mnt_irq));
-
-       /* Deactivate all active PPIs */
-       mmio_write32(gicr + GICR_ICACTIVER, 0xffff0000);
-
-       arm_write_sysreg(ICH_VMCR_EL2, 0);
-}
-
-static int gic_cpu_init(struct per_cpu *cpu_data)
-{
-       unsigned int mnt_irq = system_config->platform_info.arm.maintenance_irq;
-       u64 typer;
-       u32 pidr;
-       u32 cell_icc_ctlr, cell_icc_pmr, cell_icc_igrpen1;
-       u32 ich_vtr;
-       u32 ich_vmcr;
-       void *redist_base = gicr_base;
-
-       /* Find redistributor */
-       do {
-               pidr = mmio_read32(redist_base + GICR_PIDR2);
-               gic_version = GICR_PIDR2_ARCH(pidr);
-               if (gic_version != 3 && gic_version != 4)
-                       break;
-
-               typer = mmio_read64(redist_base + GICR_TYPER);
-               if ((typer >> 32) == cpu_data->cpu_id) {
-                       cpu_data->gicr_base = redist_base;
-                       break;
-               }
-
-               redist_base += gic_version == 4 ? 0x40000 : 0x20000;
-       } while (!(typer & GICR_TYPER_Last));
-
-       if (!cpu_data->gicr_base) {
-               printk("GIC: No redist found for CPU%d\n", cpu_data->cpu_id);
-               return -ENODEV;
-       }
-
-       /* Ensure all IPIs and the maintenance PPI are enabled. */
-       mmio_write32(redist_base + GICR_SGI_BASE + GICR_ISENABLER,
-                    0x0000ffff | (1 << mnt_irq));
-
-       /*
-        * Set EOIMode to 1
-        * This allow to drop the priority of level-triggered interrupts without
-        * deactivating them, and thus ensure that they won't be immediately
-        * re-triggered. (e.g. timer)
-        * They can then be injected into the guest using the LR.HW bit, and
-        * will be deactivated once the guest does an EOI after handling the
-        * interrupt source.
-        */
-       arm_read_sysreg(ICC_CTLR_EL1, cell_icc_ctlr);
-       arm_write_sysreg(ICC_CTLR_EL1, ICC_CTLR_EOImode);
-
-       arm_read_sysreg(ICC_PMR_EL1, cell_icc_pmr);
-       arm_write_sysreg(ICC_PMR_EL1, ICC_PMR_DEFAULT);
-
-       arm_read_sysreg(ICC_IGRPEN1_EL1, cell_icc_igrpen1);
-       arm_write_sysreg(ICC_IGRPEN1_EL1, ICC_IGRPEN1_EN);
-
-       arm_read_sysreg(ICH_VTR_EL2, ich_vtr);
-       gic_num_lr = (ich_vtr & 0xf) + 1;
-       gic_num_priority_bits = (ich_vtr >> 29) + 1;
-
-       /*
-        * Clear pending virtual IRQs in case anything is left from previous
-        * use. Physically pending IRQs will be forwarded to Linux once we
-        * enable interrupts for the hypervisor.
-        */
-       gic_clear_pending_irqs();
-
-       ich_vmcr = (cell_icc_pmr & ICC_PMR_MASK) << ICH_VMCR_VPMR_SHIFT;
-       if (cell_icc_igrpen1 & ICC_IGRPEN1_EN)
-               ich_vmcr |= ICH_VMCR_VENG1;
-       if (cell_icc_ctlr & ICC_CTLR_EOImode)
-               ich_vmcr |= ICH_VMCR_VEOIM;
-       arm_write_sysreg(ICH_VMCR_EL2, ich_vmcr);
-
-       /* After this, the cells access the virtual interface of the GIC. */
-       arm_write_sysreg(ICH_HCR_EL2, ICH_HCR_EN);
-
-       return 0;
-}
-
-static void gic_cpu_shutdown(struct per_cpu *cpu_data)
-{
-       u32 ich_vmcr, icc_ctlr, cell_icc_igrpen1;
-
-       if (!cpu_data->gicr_base)
-               return;
-
-       arm_write_sysreg(ICH_HCR_EL2, 0);
-
-       /* Disable the maintenance interrupt - not used by Linux. */
-       mmio_write32(cpu_data->gicr_base + GICR_SGI_BASE + GICR_ICENABLER,
-                    1 << system_config->platform_info.arm.maintenance_irq);
-
-       /* Restore the root config */
-       arm_read_sysreg(ICH_VMCR_EL2, ich_vmcr);
-
-       if (!(ich_vmcr & ICH_VMCR_VEOIM)) {
-               arm_read_sysreg(ICC_CTLR_EL1, icc_ctlr);
-               icc_ctlr &= ~ICC_CTLR_EOImode;
-               arm_write_sysreg(ICC_CTLR_EL1, icc_ctlr);
-       }
-       if (!(ich_vmcr & ICH_VMCR_VENG1)) {
-               arm_read_sysreg(ICC_IGRPEN1_EL1, cell_icc_igrpen1);
-               cell_icc_igrpen1 &= ~ICC_IGRPEN1_EN;
-               arm_write_sysreg(ICC_IGRPEN1_EL1, cell_icc_igrpen1);
-       }
-}
-
-static void gic_adjust_irq_target(struct cell *cell, u16 irq_id)
-{
-       void *irouter = gicd_base + GICD_IROUTER + irq_id;
-       u32 route = mmio_read32(irouter);
-
-       if (!cell_owns_cpu(cell, route))
-               mmio_write32(irouter, first_cpu(cell->cpu_set));
-}
-
-static enum mmio_result gic_handle_redist_access(void *arg,
-                                                struct mmio_access *mmio)
-{
-       struct cell *cell = this_cell();
-       unsigned int cpu;
-       unsigned int virt_id;
-       unsigned int redist_size = (gic_version == 4) ? 0x40000 : 0x20000;
-       void *phys_redist = NULL;
-       unsigned long offs;
-
-       /*
-        * The redistributor accessed by the cell is not the one stored in these
-        * cpu_datas, but the one associated to its virtual id. So we first
-        * need to translate the redistributor address.
-        */
-       for_each_cpu(cpu, cell->cpu_set) {
-               virt_id = arm_cpu_phys2virt(cpu);
-               offs = per_cpu(virt_id)->gicr_base - gicr_base;
-               if (mmio->address >= offs &&
-                   mmio->address < offs + redist_size) {
-                       phys_redist = per_cpu(cpu)->gicr_base;
-                       break;
-               }
-       }
-
-       if (phys_redist == NULL)
-               return MMIO_ERROR;
-
-       mmio->address -= offs;
-
-       /* Change the ID register, all other accesses are allowed. */
-       if (!mmio->is_write) {
-               switch (mmio->address) {
-               case GICR_TYPER:
-                       if (virt_id == cell->arch.last_virt_id)
-                               mmio->value = GICR_TYPER_Last;
-                       else
-                               mmio->value = 0;
-                       /* AArch64 can use a writeq for this register */
-                       if (mmio->size == 8)
-                               mmio->value |= (u64)virt_id << 32;
-
-                       return MMIO_HANDLED;
-               case GICR_TYPER + 4:
-                       /* Upper bits contain the affinity */
-                       mmio->value = virt_id;
-                       return MMIO_HANDLED;
-               }
-       }
-       mmio_perform_access(phys_redist, mmio);
-       return MMIO_HANDLED;
-}
-
-static int gic_cell_init(struct cell *cell)
-{
-       mmio_region_register(cell, system_config->platform_info.arm.gicr_base,
-                            GICR_SIZE, gic_handle_redist_access, NULL);
-
-       return 0;
-}
-
-static int gic_send_sgi(struct sgi *sgi)
-{
-       u64 val;
-       u16 targets = sgi->targets;
-
-       if (!is_sgi(sgi->id))
-               return -EINVAL;
-
-       if (sgi->routing_mode == 2)
-               targets = 1 << phys_processor_id();
-
-       val = (u64)sgi->aff3 << ICC_SGIR_AFF3_SHIFT
-           | (u64)sgi->aff2 << ICC_SGIR_AFF2_SHIFT
-           | sgi->aff1 << ICC_SGIR_AFF1_SHIFT
-           | (targets & ICC_SGIR_TARGET_MASK)
-           | (sgi->id & 0xf) << ICC_SGIR_IRQN_SHIFT;
-
-       if (sgi->routing_mode == 1)
-               val |= ICC_SGIR_ROUTING_BIT;
-
-       /*
-        * Ensure the targets see our modifications to their per-cpu
-        * structures.
-        */
-       dsb(ish);
-
-       arm_write_sysreg(ICC_SGI1R_EL1, val);
-       isb();
-
-       return 0;
-}
-
-void gicv3_handle_sgir_write(u64 sgir)
-{
-       struct sgi sgi;
-       unsigned long routing_mode = !!(sgir & ICC_SGIR_ROUTING_BIT);
-
-       /* FIXME: clusters are not supported yet. */
-       sgi.targets = sgir & ICC_SGIR_TARGET_MASK;
-       sgi.routing_mode = routing_mode;
-       sgi.aff1 = sgir >> ICC_SGIR_AFF1_SHIFT & 0xff;
-       sgi.aff2 = sgir >> ICC_SGIR_AFF2_SHIFT & 0xff;
-       sgi.aff3 = sgir >> ICC_SGIR_AFF3_SHIFT & 0xff;
-       sgi.id = sgir >> ICC_SGIR_IRQN_SHIFT & 0xf;
-
-       gic_handle_sgir_write(&sgi, true);
-}
-
-/*
- * GICv3 uses a 64bit register IROUTER for each IRQ
- */
-enum mmio_result gic_handle_irq_route(struct mmio_access *mmio,
-                                     unsigned int irq)
-{
-       struct cell *cell = this_cell();
-       unsigned int cpu;
-
-       /* Ignore aff3 on AArch32 (return 0) */
-       if (mmio->size == 4 && (mmio->address % 8))
-               return MMIO_HANDLED;
-
-       /* SGIs and PPIs are res0 */
-       if (!is_spi(irq))
-               return MMIO_HANDLED;
-
-       /*
-        * Ignore accesses to SPIs that do not belong to the cell. This isn't
-        * forbidden, because the guest driver may simply iterate over all
-        * registers at initialisation
-        */
-       if (!irqchip_irq_in_cell(cell, irq))
-               return MMIO_HANDLED;
-
-       /* Translate the virtual cpu id into the physical one */
-       if (mmio->is_write) {
-               mmio->value = arm_cpu_virt2phys(cell, mmio->value);
-               if (mmio->value == -1) {
-                       printk("Attempt to route IRQ%d outside of cell\n", irq);
-                       return MMIO_ERROR;
-               }
-               mmio_perform_access(gicd_base, mmio);
-       } else {
-               cpu = mmio_read32(gicd_base + GICD_IROUTER + 8 * irq);
-               mmio->value = arm_cpu_phys2virt(cpu);
-       }
-       return MMIO_HANDLED;
-}
-
-static void gic_eoi_irq(u32 irq_id, bool deactivate)
-{
-       arm_write_sysreg(ICC_EOIR1_EL1, irq_id);
-       if (deactivate)
-               arm_write_sysreg(ICC_DIR_EL1, irq_id);
-}
-
-static int gic_inject_irq(struct per_cpu *cpu_data, u16 irq_id)
-{
-       int i;
-       int free_lr = -1;
-       u32 elsr;
-       u64 lr;
-
-       arm_read_sysreg(ICH_ELSR_EL2, elsr);
-       for (i = 0; i < gic_num_lr; i++) {
-               if ((elsr >> i) & 1) {
-                       /* Entry is invalid, candidate for injection */
-                       if (free_lr == -1)
-                               free_lr = i;
-                       continue;
-               }
-
-               /*
-                * Entry is in use, check that it doesn't match the one we want
-                * to inject.
-                */
-               lr = gic_read_lr(i);
-
-               /*
-                * A strict phys->virt id mapping is used for SPIs, so this test
-                * should be sufficient.
-                */
-               if ((u32)lr == irq_id)
-                       return -EEXIST;
-       }
-
-       if (free_lr == -1)
-               /* All list registers are in use */
-               return -EBUSY;
-
-       lr = irq_id;
-       /* Only group 1 interrupts */
-       lr |= ICH_LR_GROUP_BIT;
-       lr |= ICH_LR_PENDING;
-       if (!is_sgi(irq_id)) {
-               lr |= ICH_LR_HW_BIT;
-               lr |= (u64)irq_id << ICH_LR_PHYS_ID_SHIFT;
-       }
-
-       gic_write_lr(free_lr, lr);
-
-       return 0;
-}
-
-static void gicv3_enable_maint_irq(bool enable)
-{
-       u32 hcr;
-
-       arm_read_sysreg(ICH_HCR_EL2, hcr);
-       if (enable)
-               hcr |= ICH_HCR_UIE;
-       else
-               hcr &= ~ICH_HCR_UIE;
-       arm_write_sysreg(ICH_HCR_EL2, hcr);
-}
-
-static bool gicv3_has_pending_irqs(void)
-{
-       unsigned int n;
-
-       for (n = 0; n < gic_num_lr; n++)
-               if (gic_read_lr(n) & ICH_LR_PENDING)
-                       return true;
-
-       return false;
-}
-
-static enum mmio_result gicv3_handle_irq_target(struct mmio_access *mmio,
-                                               unsigned int irq)
-{
-       /* ignore writes, we are in affinity routing mode */
-       return MMIO_HANDLED;
-}
-
-unsigned int irqchip_mmio_count_regions(struct cell *cell)
-{
-       return 2;
-}
-
-struct irqchip_ops irqchip = {
-       .init = gic_init,
-       .cpu_init = gic_cpu_init,
-       .cpu_reset = gic_cpu_reset,
-       .cpu_shutdown = gic_cpu_shutdown,
-       .cell_init = gic_cell_init,
-       .adjust_irq_target = gic_adjust_irq_target,
-       .send_sgi = gic_send_sgi,
-       .inject_irq = gic_inject_irq,
-       .enable_maint_irq = gicv3_enable_maint_irq,
-       .has_pending_irqs = gicv3_has_pending_irqs,
-       .eoi_irq = gic_eoi_irq,
-       .handle_irq_target = gicv3_handle_irq_target,
-};
diff --git a/hypervisor/arch/arm/include/asm/gic_v3.h 
b/hypervisor/arch/arm/include/asm/gic_v3.h
deleted file mode 100644
index d1b9346..0000000
--- a/hypervisor/arch/arm/include/asm/gic_v3.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Jailhouse, a Linux-based partitioning hypervisor
- *
- * Copyright (c) ARM Limited, 2014
- *
- * Authors:
- *  Jean-Philippe Brucker <[email protected]>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- */
-
-#ifndef _JAILHOUSE_ASM_GIC_V3_H
-#define _JAILHOUSE_ASM_GIC_V3_H
-
-#include <asm/sysregs.h>
-
-#define GICD_SIZE              0x10000
-#define GICR_SIZE              0x100000
-
-#define GICD_CIDR0             0xfff0
-#define GICD_CIDR1             0xfff4
-#define GICD_CIDR2             0xfff8
-#define GICD_CIDR3             0xfffc
-
-#define GICD_PIDR0             0xffe0
-#define GICD_PIDR1             0xffe4
-#define GICD_PIDR2             0xffe8
-#define GICD_PIDR3             0xffec
-#define GICD_PIDR4             0xffd0
-#define GICD_PIDR5             0xffd4
-#define GICD_PIDR6             0xffd8
-#define GICD_PIDR7             0xffdc
-
-#define GICR_CTLR              GICD_CTLR
-#define GICR_TYPER             0x0008
-#define GICR_WAKER             0x0014
-#define GICR_CIDR0             GICD_CIDR0
-#define GICR_CIDR1             GICD_CIDR1
-#define GICR_CIDR2             GICD_CIDR2
-#define GICR_CIDR3             GICD_CIDR3
-#define GICR_PIDR0             GICD_PIDR0
-#define GICR_PIDR1             GICD_PIDR1
-#define GICR_PIDR2             GICD_PIDR2
-#define GICR_PIDR3             GICD_PIDR3
-#define GICR_PIDR4             GICD_PIDR4
-#define GICR_PIDR5             GICD_PIDR5
-#define GICR_PIDR6             GICD_PIDR6
-#define GICR_PIDR7             GICD_PIDR7
-
-#define GICR_SGI_BASE          0x10000
-#define GICR_IGROUPR           GICD_IGROUPR
-#define GICR_ISENABLER         GICD_ISENABLER
-#define GICR_ICENABLER         GICD_ICENABLER
-#define GICR_ISACTIVER         GICD_ISACTIVER
-#define GICR_ICACTIVER         GICD_ICACTIVER
-#define GICR_IPRIORITY         GICD_IPRIORITY
-
-#define GICR_TYPER_Last                (1 << 4)
-#define GICR_PIDR2_ARCH                GICD_PIDR2_ARCH
-
-#define ICC_IAR1_EL1           SYSREG_32(0, c12, c12, 0)
-#define ICC_EOIR1_EL1          SYSREG_32(0, c12, c12, 1)
-#define ICC_HPPIR1_EL1         SYSREG_32(0, c12, c12, 2)
-#define ICC_BPR1_EL1           SYSREG_32(0, c12, c12, 3)
-#define ICC_DIR_EL1            SYSREG_32(0, c12, c11, 1)
-#define ICC_PMR_EL1            SYSREG_32(0, c4, c6, 0)
-#define ICC_RPR_EL1            SYSREG_32(0, c12, c11, 3)
-#define ICC_CTLR_EL1           SYSREG_32(0, c12, c12, 4)
-#define ICC_SRE_EL1            SYSREG_32(0, c12, c12, 5)
-#define ICC_SRE_EL2            SYSREG_32(4, c12, c9, 5)
-#define ICC_IGRPEN1_EL1                SYSREG_32(0, c12, c12, 7)
-#define ICC_SGI1R_EL1          SYSREG_64(0, c12)
-#define ICC_AP1R0_EL1          SYSREG_32(0, c12, c9, 0)
-#define ICC_AP1R1_EL1          SYSREG_32(0, c12, c9, 1)
-#define ICC_AP1R2_EL1          SYSREG_32(0, c12, c9, 2)
-#define ICC_AP1R3_EL1          SYSREG_32(0, c12, c9, 3)
-
-#define ICH_HCR_EL2            SYSREG_32(4, c12, c11, 0)
-#define ICH_VTR_EL2            SYSREG_32(4, c12, c11, 1)
-#define ICH_MISR_EL2           SYSREG_32(4, c12, c11, 2)
-#define ICH_EISR_EL2           SYSREG_32(4, c12, c11, 3)
-#define ICH_ELSR_EL2           SYSREG_32(4, c12, c11, 5)
-#define ICH_VMCR_EL2           SYSREG_32(4, c12, c11, 7)
-#define ICH_AP1R0_EL2          SYSREG_32(4, c12, c9, 0)
-#define ICH_AP1R1_EL2          SYSREG_32(4, c12, c9, 1)
-#define ICH_AP1R2_EL2          SYSREG_32(4, c12, c9, 2)
-#define ICH_AP1R3_EL2          SYSREG_32(4, c12, c9, 3)
-
-/* Different on AArch32 and AArch64... */
-#define __ICH_LR0(x)           SYSREG_32(4, c12, c12, x)
-#define __ICH_LR8(x)           SYSREG_32(4, c12, c13, x)
-#define __ICH_LRC0(x)          SYSREG_32(4, c12, c14, x)
-#define __ICH_LRC8(x)          SYSREG_32(4, c12, c15, x)
-
-#define ICH_LR0                        __ICH_LR0(0)
-#define ICH_LR1                        __ICH_LR0(1)
-#define ICH_LR2                        __ICH_LR0(2)
-#define ICH_LR3                        __ICH_LR0(3)
-#define ICH_LR4                        __ICH_LR0(4)
-#define ICH_LR5                        __ICH_LR0(5)
-#define ICH_LR6                        __ICH_LR0(6)
-#define ICH_LR7                        __ICH_LR0(7)
-#define ICH_LR8                        __ICH_LR8(0)
-#define ICH_LR9                        __ICH_LR8(1)
-#define ICH_LR10               __ICH_LR8(2)
-#define ICH_LR11               __ICH_LR8(3)
-#define ICH_LR12               __ICH_LR8(4)
-#define ICH_LR13               __ICH_LR8(5)
-#define ICH_LR14               __ICH_LR8(6)
-#define ICH_LR15               __ICH_LR8(7)
-#define ICH_LRC0               __ICH_LRC0(0)
-#define ICH_LRC1               __ICH_LRC0(1)
-#define ICH_LRC2               __ICH_LRC0(2)
-#define ICH_LRC3               __ICH_LRC0(3)
-#define ICH_LRC4               __ICH_LRC0(4)
-#define ICH_LRC5               __ICH_LRC0(5)
-#define ICH_LRC6               __ICH_LRC0(6)
-#define ICH_LRC7               __ICH_LRC0(7)
-#define ICH_LRC8               __ICH_LRC8(0)
-#define ICH_LRC9               __ICH_LRC8(1)
-#define ICH_LRC10              __ICH_LRC8(2)
-#define ICH_LRC11              __ICH_LRC8(3)
-#define ICH_LRC12              __ICH_LRC8(4)
-#define ICH_LRC13              __ICH_LRC8(5)
-#define ICH_LRC14              __ICH_LRC8(6)
-#define ICH_LRC15              __ICH_LRC8(7)
-
-#define ICC_CTLR_EOImode       0x2
-#define ICC_PMR_MASK           0xff
-#define ICC_PMR_DEFAULT                0xf0
-#define ICC_IGRPEN1_EN         0x1
-
-#define ICC_SGIR_AFF3_SHIFT    48
-#define ICC_SGIR_AFF2_SHIFT    32
-#define ICC_SGIR_AFF1_SHIFT    16
-#define ICC_SGIR_TARGET_MASK   0xffff
-#define ICC_SGIR_IRQN_SHIFT    24
-#define ICC_SGIR_ROUTING_BIT   (1ULL << 40)
-
-#define ICH_HCR_EN             (1 << 0)
-#define ICH_HCR_UIE            (1 << 1)
-#define ICH_HCR_LRENPIE                (1 << 2)
-#define ICH_HCR_NPIE           (1 << 3)
-#define ICH_HCR_VGRP0EIE       (1 << 4)
-#define ICH_HCR_VGRP0DIE       (1 << 5)
-#define ICH_HCR_VGRP1EIE       (1 << 6)
-#define ICH_HCR_VGRP1DIE       (1 << 7)
-#define ICH_HCR_VARE           (1 << 9)
-#define ICH_HCR_TC             (1 << 10)
-#define ICH_HCR_TALL0          (1 << 11)
-#define ICH_HCR_TALL1          (1 << 12)
-#define ICH_HCR_TSEI           (1 << 13)
-#define ICH_HCR_EOICount       (0x1f << 27)
-
-#define ICH_MISR_EOI           (1 << 0)
-#define ICH_MISR_U             (1 << 1)
-#define ICH_MISR_LRENP         (1 << 2)
-#define ICH_MISR_NP            (1 << 3)
-#define ICH_MISR_VGRP0E                (1 << 4)
-#define ICH_MISR_VGRP0D                (1 << 5)
-#define ICH_MISR_VGRP1E                (1 << 6)
-#define ICH_MISR_VGRP1D                (1 << 7)
-
-#define ICH_VMCR_VENG0         (1 << 0)
-#define ICH_VMCR_VENG1         (1 << 1)
-#define ICH_VMCR_VACKCTL       (1 << 2)
-#define ICH_VMCR_VFIQEN                (1 << 3)
-#define ICH_VMCR_VCBPR         (1 << 4)
-#define ICH_VMCR_VEOIM         (1 << 9)
-#define ICH_VMCR_VBPR1_SHIFT   18
-#define ICH_VMCR_VBPR0_SHIFT   21
-#define ICH_VMCR_VPMR_SHIFT    24
-
-/* List registers upper bits */
-#define ICH_LR_INVALID         (0x0ULL << 62)
-#define ICH_LR_PENDING         (0x1ULL << 62)
-#define ICH_LR_ACTIVE          (0x2ULL << 62)
-#define ICH_LR_PENDACTIVE      (0x3ULL << 62)
-#define ICH_LR_HW_BIT          (0x1ULL << 61)
-#define ICH_LR_GROUP_BIT       (0x1ULL << 60)
-#define ICH_LR_PRIORITY_SHIFT  48
-#define ICH_LR_SGI_EOI         (0x1ULL << 41)
-#define ICH_LR_PHYS_ID_SHIFT   32
-
-#ifndef __ASSEMBLY__
-
-#include <jailhouse/types.h>
-
-static inline u64 gic_read_lr(unsigned int n)
-{
-       u32 lr, lrc;
-
-       switch (n) {
-#define __READ_LR(n)                                   \
-       case n:                                         \
-               arm_read_sysreg(ICH_LR##n, lr);         \
-               arm_read_sysreg(ICH_LRC##n, lrc);       \
-               break;
-
-       __READ_LR(0)
-       __READ_LR(1)
-       __READ_LR(2)
-       __READ_LR(3)
-       __READ_LR(4)
-       __READ_LR(5)
-       __READ_LR(6)
-       __READ_LR(7)
-       __READ_LR(8)
-       __READ_LR(9)
-       __READ_LR(10)
-       __READ_LR(11)
-       __READ_LR(12)
-       __READ_LR(13)
-       __READ_LR(14)
-       __READ_LR(15)
-#undef __READ_LR
-
-       default:
-               return (u64)(-1);
-       }
-
-       return (u64)lrc << 32 | lr;
-}
-
-static inline void gic_write_lr(unsigned int n, u64 val)
-{
-       u32 lr = (u32)val;
-       u32 lrc = val >> 32;
-
-       switch (n) {
-#define __WRITE_LR(n)                                  \
-       case n:                                         \
-               arm_write_sysreg(ICH_LR##n, lr);        \
-               arm_write_sysreg(ICH_LRC##n, lrc);      \
-               break;
-
-       __WRITE_LR(0)
-       __WRITE_LR(1)
-       __WRITE_LR(2)
-       __WRITE_LR(3)
-       __WRITE_LR(4)
-       __WRITE_LR(5)
-       __WRITE_LR(6)
-       __WRITE_LR(7)
-       __WRITE_LR(8)
-       __WRITE_LR(9)
-       __WRITE_LR(10)
-       __WRITE_LR(11)
-       __WRITE_LR(12)
-       __WRITE_LR(13)
-       __WRITE_LR(14)
-       __WRITE_LR(15)
-#undef __WRITE_LR
-       }
-}
-
-static inline u32 gic_read_iar(void)
-{
-       u32 irq_id;
-
-       arm_read_sysreg(ICC_IAR1_EL1, irq_id);
-       return irq_id;
-}
-
-void gicv3_handle_sgir_write(u64 sgir);
-
-#endif /* __ASSEMBLY__ */
-#endif /* _JAILHOUSE_ASM_GIC_V3_H */
-- 
1.9.1

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to