]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
arm: GIC initialisation skeleton
authorJean-Philippe Brucker <jean-philippe.brucker@arm.com>
Thu, 26 Jun 2014 13:27:17 +0000 (14:27 +0100)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 19 Dec 2014 10:04:07 +0000 (11:04 +0100)
Since the GIC uses MMIOs, its initialisation must be done at EL2. This
is why arch_cpu_init first calls irqchip_init on the master CPU, to map
the devices, and then irqchip_cpu_init on all CPUs.

The aim of this patch is to allow support for both GICv2 and GICv3. It
abstracts the GIC operations by using `struct irqchip_ops', and fills it
with the right device hooks after detecting which irqchip is available.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/arm/Makefile
hypervisor/arch/arm/include/asm/irqchip.h [new file with mode: 0644]
hypervisor/arch/arm/irqchip.c [new file with mode: 0644]
hypervisor/arch/arm/setup.c

index c92f93f35f1705e1c99eddb4dd2ce923a0f529d5..1383fbde8c01aa199093916eb25d474ea2dc7168 100644 (file)
@@ -18,4 +18,5 @@ always := built-in.o
 
 obj-y := entry.o dbg-write.o exception.o setup.o lib.o traps.o
 obj-y += paging.o mmu_hyp.o mmu_cell.o
+obj-y += irqchip.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += dbg-write-pl011.o
diff --git a/hypervisor/arch/arm/include/asm/irqchip.h b/hypervisor/arch/arm/include/asm/irqchip.h
new file mode 100644 (file)
index 0000000..0ef5fe0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) ARM Limited, 2014
+ *
+ * Authors:
+ *  Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
+ *
+ * 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_IRQCHIP_H
+#define _JAILHOUSE_ASM_IRQCHIP_H
+
+#include <asm/percpu.h>
+
+#ifndef __ASSEMBLY__
+
+struct sgi {
+       /*
+        * Routing mode values:
+        * 0: use aff3.aff2.aff1.targets
+        * 1: all processors in the cell except this CPU
+        * 2: only this CPU
+        */
+       u8      routing_mode;
+       /* GICv2 only uses 8bit in targets, and no affinity routing */
+       u8      aff1;
+       u8      aff2;
+       /* Only available on 64-bit, when CTLR.A3V is 1 */
+       u8      aff3;
+       u16     targets;
+       u16     id;
+};
+
+struct irqchip_ops {
+       int     (*init)(void);
+       int     (*cpu_init)(struct per_cpu *cpu_data);
+
+       int     (*send_sgi)(struct sgi *sgi);
+       void    (*handle_irq)(struct per_cpu *cpu_data);
+};
+
+int irqchip_init(void);
+int irqchip_cpu_init(struct per_cpu *cpu_data);
+
+int irqchip_send_sgi(struct sgi *sgi);
+void irqchip_handle_irq(struct per_cpu *cpu_data);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _JAILHOUSE_ASM_IRQCHIP_H */
diff --git a/hypervisor/arch/arm/irqchip.c b/hypervisor/arch/arm/irqchip.c
new file mode 100644 (file)
index 0000000..67eef60
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) ARM Limited, 2014
+ *
+ * Authors:
+ *  Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <asm/irqchip.h>
+#include <asm/sysregs.h>
+#include <jailhouse/entry.h>
+#include <jailhouse/paging.h>
+#include <jailhouse/printk.h>
+#include <jailhouse/string.h>
+
+/*
+ * The init function must be called after the MMU setup, and whilst in the
+ * per-cpu setup, which means that a bool must be set by the master CPU
+ */
+static bool irqchip_is_init;
+static struct irqchip_ops irqchip;
+
+void irqchip_handle_irq(struct per_cpu *cpu_data)
+{
+       irqchip.handle_irq(cpu_data);
+}
+
+int irqchip_send_sgi(struct sgi *sgi)
+{
+       return irqchip.send_sgi(sgi);
+}
+
+int irqchip_cpu_init(struct per_cpu *cpu_data)
+{
+       if (irqchip.cpu_init)
+               return irqchip.cpu_init(cpu_data);
+
+       return 0;
+}
+
+int irqchip_init(void)
+{
+       /* Only executed on master CPU */
+       if (irqchip_is_init)
+               return 0;
+
+       memset(&irqchip, 0, sizeof(irqchip));
+       irqchip_is_init = true;
+
+       return -ENODEV;
+}
index 9885488ab6117c4f5ce26e8820f3c44dfac70641..ba9a92da795808538137de224f2c94c21e2b5f02 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <asm/control.h>
+#include <asm/irqchip.h>
 #include <asm/percpu.h>
 #include <asm/platform.h>
 #include <asm/setup.h>
@@ -74,6 +75,14 @@ int arch_cpu_init(struct per_cpu *cpu_data)
        arm_write_sysreg(HCR, hcr);
 
        err = arch_mmu_cpu_cell_init(cpu_data);
+       if (err)
+               return err;
+
+       err = irqchip_init();
+       if (err)
+               return err;
+
+       err = irqchip_cpu_init(cpu_data);
 
        return err;
 }