]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
arm: Enable / disable maintenance interrupt in distributor
authorJan Kiszka <jan.kiszka@siemens.com>
Thu, 16 Jun 2016 16:25:58 +0000 (18:25 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Thu, 16 Jun 2016 16:41:13 +0000 (18:41 +0200)
We did not get any maintenance interrupts so far because we didn't
enable the source in the distributor so far. Fix this, but also disable
it again when shutting down.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/arm/gic-v2.c
hypervisor/arch/arm/gic-v3.c

index aae5c0e59c5b2cbf9f3e25c32fef9a7a7aee9c08..8f5fc0b5e3ccb44bd5f40fdfdf7bbfcc5894c166 100644 (file)
@@ -76,11 +76,18 @@ static int gic_cpu_reset(struct per_cpu *cpu_data, bool is_shutdown)
                        mmio_write32(gicc_base + GICC_DIR, i);
        }
 
-       /* Disable PPIs if necessary */
-       if (!root_shutdown)
-               mmio_write32(gicd_base + GICD_ICENABLER, 0xffff0000);
-       /* Ensure IPIs are enabled */
-       mmio_write32(gicd_base + GICD_ISENABLER, 0x0000ffff);
+       /* Ensure all IPIs and the maintenance PPI are enabled */
+       mmio_write32(gicd_base + GICD_ISENABLER,
+                    0x0000ffff | (1 << MAINTENANCE_IRQ));
+
+       /*
+        * Disable PPIs, except for the maintenance interrupt.
+        * On shutdown, the root cell expects to find all its PPIs still
+        * enabled - except for the maintenance interrupt we used.
+        */
+       mmio_write32(gicd_base + GICD_ICENABLER,
+                    root_shutdown ? 1 << MAINTENANCE_IRQ :
+                                    0xffff0000 & ~(1 << MAINTENANCE_IRQ));
 
        if (is_shutdown)
                mmio_write32(gich_base + GICH_HCR, 0);
@@ -110,8 +117,9 @@ static int gic_cpu_init(struct per_cpu *cpu_data)
        u32 vtr, vmcr;
        u32 cell_gicc_ctlr, cell_gicc_pmr;
 
-       /* Ensure all IPIs are enabled */
-       mmio_write32(gicd_base + GICD_ISENABLER, 0x0000ffff);
+       /* Ensure all IPIs and the maintenance PPI are enabled. */
+       mmio_write32(gicd_base + GICD_ISENABLER,
+                    0x0000ffff | (1 << MAINTENANCE_IRQ));
 
        cell_gicc_ctlr = mmio_read32(gicc_base + GICC_CTLR);
        cell_gicc_pmr = mmio_read32(gicc_base + GICC_PMR);
index 65f326c6b40fbf1fb154d702d136e9e4345fb991..4ab03ad84282f2dfdea64b5ba8f52056fbedf27a 100644 (file)
@@ -92,14 +92,18 @@ static int gic_cpu_reset(struct per_cpu *cpu_data, bool is_shutdown)
                        arm_write_sysreg(ICC_DIR_EL1, i);
        }
 
+       /* Ensure all IPIs and the maintenance PPI are enabled. */
+       mmio_write32(gicr + GICR_ISENABLER,
+                    0x0000ffff | (1 << MAINTENANCE_IRQ));
+
        /*
-        * Disable all PPIs, ensure IPIs are enabled.
-        * On shutdown, the root cell expects to find all its PPIs still enabled
-        * when returning to the driver.
+        * Disable PPIs, except for the maintenance interrupt.
+        * On shutdown, the root cell expects to find all its PPIs still
+        * enabled - except for the maintenance interrupt we used.
         */
-       if (!root_shutdown)
-               mmio_write32(gicr + GICR_ICENABLER, 0xffff0000);
-       mmio_write32(gicr + GICR_ISENABLER, 0x0000ffff);
+       mmio_write32(gicr + GICR_ICENABLER,
+                    root_shutdown ? 1 << MAINTENANCE_IRQ :
+                                    0xffff0000 & ~(1 << MAINTENANCE_IRQ));
 
        if (root_shutdown) {
                /* Restore the root config */
@@ -152,8 +156,9 @@ static int gic_cpu_init(struct per_cpu *cpu_data)
                return -ENODEV;
        }
 
-       /* Ensure all IPIs are enabled */
-       mmio_write32(redist_base + GICR_SGI_BASE + GICR_ISENABLER, 0x0000ffff);
+       /* Ensure all IPIs and the maintenance PPI are enabled. */
+       mmio_write32(redist_base + GICR_SGI_BASE + GICR_ISENABLER,
+                    0x0000ffff | (1 << MAINTENANCE_IRQ));
 
        /*
         * Set EOIMode to 1