static bool irqchip_is_init;
static struct irqchip_ops irqchip;
+bool spi_in_cell(struct cell *cell, unsigned int spi)
+{
+ /* FIXME: Change the configuration to a bitmask range */
+ u32 spi_mask;
+
+ if (spi >= 64)
+ return false;
+ else if (spi >= 32)
+ spi_mask = cell->arch.spis >> 32;
+ else
+ spi_mask = cell->arch.spis;
+
+ return spi_mask & (1 << (spi & 31));
+}
+
static int irqchip_init_pending(struct per_cpu *cpu_data)
{
struct pending_irq *pend_array;
struct pending_irq pending;
pending.virt_id = irq_id;
- /* Priority must be less than ICC_PMR */
- pending.priority = 0;
-
- if (is_sgi(irq_id)) {
- pending.hw = 0;
- pending.type.sgi.maintenance = 0;
- pending.type.sgi.cpuid = 0;
- } else {
- pending.hw = 1;
- pending.type.irq = irq_id;
- }
if (try_inject && irqchip.inject_irq(cpu_data, &pending) == 0)
return 0;
return err;
if (irqchip.cpu_reset)
- return irqchip.cpu_reset(cpu_data);
+ return irqchip.cpu_reset(cpu_data, false);
return 0;
}
-int irqchip_mmio_access(struct per_cpu *cpu_data, struct mmio_access *access)
+void irqchip_cpu_shutdown(struct per_cpu *cpu_data)
{
- if (irqchip.mmio_access)
- return irqchip.mmio_access(cpu_data, access);
+ /*
+ * The GIC backend must take care of only resetting the hyp interface if
+ * it has been initialised: this function may be executed during the
+ * setup phase.
+ */
+ if (irqchip.cpu_reset)
+ irqchip.cpu_reset(cpu_data, true);
+}
- return TRAP_UNHANDLED;
+static const struct jailhouse_irqchip *
+irqchip_find_config(struct jailhouse_cell_desc *config)
+{
+ const struct jailhouse_irqchip *irq_config =
+ jailhouse_cell_irqchips(config);
+
+ if (config->num_irqchips)
+ return irq_config;
+ else
+ return NULL;
+}
+
+int irqchip_cell_init(struct cell *cell)
+{
+ const struct jailhouse_irqchip *pins = irqchip_find_config(cell->config);
+
+ cell->arch.spis = (pins ? pins->pin_bitmap : 0);
+
+ return irqchip.cell_init(cell);
+}
+
+void irqchip_cell_exit(struct cell *cell)
+{
+ const struct jailhouse_irqchip *root_pins =
+ irqchip_find_config(root_cell.config);
+
+ /* might be called by arch_shutdown while rolling back
+ * a failed setup */
+ if (!irqchip_is_init)
+ return;
+
+ if (root_pins)
+ root_cell.arch.spis |= cell->arch.spis & root_pins->pin_bitmap;
+
+ irqchip.cell_exit(cell);
+}
+
+void irqchip_root_cell_shrink(struct cell *cell)
+{
+ root_cell.arch.spis &= ~(cell->arch.spis);
}
/* Only the GIC is implemented */
pidr2 = mmio_read32(gicd_base + GICD_PIDR2);
switch (GICD_PIDR2_ARCH(pidr2)) {
case 0x2:
- break;
case 0x3:
case 0x4:
memcpy(&irqchip, &gic_irqchip, sizeof(struct irqchip_ops));