Commit 67afe775 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by David Gibson
Browse files

target/ppc: Add POWER9 external interrupt model



Adds support for the Hypervisor directed interrupts in addition to the
OS ones.

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: - modified the icp_realize() and xive_tctx_realize() to take
        into account explicitely the POWER9 interrupt model
      - introduced a specific power9_set_irq for POWER9 ]
Signed-off-by: default avatarCédric Le Goater <clg@kaod.org>
Message-Id: <20190215161648.9600-10-clg@kaod.org>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent d8ce5fd6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -338,6 +338,9 @@ static void icp_realize(DeviceState *dev, Error **errp)
    case PPC_FLAGS_INPUT_POWER7:
        icp->output = env->irq_inputs[POWER7_INPUT_INT];
        break;
    case PPC_FLAGS_INPUT_POWER9: /* For SPAPR xics emulation */
        icp->output = env->irq_inputs[POWER9_INPUT_INT];
        break;

    case PPC_FLAGS_INPUT_970:
        icp->output = env->irq_inputs[PPC970_INPUT_INT];
+3 −0
Original line number Diff line number Diff line
@@ -484,6 +484,9 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp)
    case PPC_FLAGS_INPUT_POWER7:
        tctx->output = env->irq_inputs[POWER7_INPUT_INT];
        break;
    case PPC_FLAGS_INPUT_POWER9:
        tctx->output = env->irq_inputs[POWER9_INPUT_INT];
        break;

    default:
        error_setg(errp, "XIVE interrupt controller does not support "
+42 −0
Original line number Diff line number Diff line
@@ -306,6 +306,48 @@ void ppcPOWER7_irq_init(PowerPCCPU *cpu)
    env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, cpu,
                                                  POWER7_INPUT_NB);
}

/* POWER9 internal IRQ controller */
static void power9_set_irq(void *opaque, int pin, int level)
{
    PowerPCCPU *cpu = opaque;
    CPUPPCState *env = &cpu->env;

    LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
                env, pin, level);

    switch (pin) {
    case POWER9_INPUT_INT:
        /* Level sensitive - active high */
        LOG_IRQ("%s: set the external IRQ state to %d\n",
                __func__, level);
        ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level);
        break;
    case POWER9_INPUT_HINT:
        /* Level sensitive - active high */
        LOG_IRQ("%s: set the external IRQ state to %d\n",
                __func__, level);
        ppc_set_irq(cpu, PPC_INTERRUPT_HVIRT, level);
        break;
    default:
        /* Unknown pin - do nothing */
        LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
        return;
    }
    if (level) {
        env->irq_input_state |= 1 << pin;
    } else {
        env->irq_input_state &= ~(1 << pin);
    }
}

void ppcPOWER9_irq_init(PowerPCCPU *cpu)
{
    CPUPPCState *env = &cpu->env;

    env->irq_inputs = (void **)qemu_allocate_irqs(&power9_set_irq, cpu,
                                                  POWER9_INPUT_NB);
}
#endif /* defined(TARGET_PPC64) */

void ppc40x_core_reset(PowerPCCPU *cpu)
+2 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ static inline void ppc40x_irq_init(PowerPCCPU *cpu) {}
static inline void ppc6xx_irq_init(PowerPCCPU *cpu) {}
static inline void ppc970_irq_init(PowerPCCPU *cpu) {}
static inline void ppcPOWER7_irq_init(PowerPCCPU *cpu) {}
static inline void ppcPOWER9_irq_init(PowerPCCPU *cpu) {}
static inline void ppce500_irq_init(PowerPCCPU *cpu) {}
#else
void ppc40x_irq_init(PowerPCCPU *cpu);
@@ -80,6 +81,7 @@ void ppce500_irq_init(PowerPCCPU *cpu);
void ppc6xx_irq_init(PowerPCCPU *cpu);
void ppc970_irq_init(PowerPCCPU *cpu);
void ppcPOWER7_irq_init(PowerPCCPU *cpu);
void ppcPOWER9_irq_init(PowerPCCPU *cpu);
#endif

/* PPC machines for OpenBIOS */
+2 −0
Original line number Diff line number Diff line
@@ -142,6 +142,8 @@ enum powerpc_input_t {
    PPC_FLAGS_INPUT_970,
    /* PowerPC POWER7 bus               */
    PPC_FLAGS_INPUT_POWER7,
    /* PowerPC POWER9 bus               */
    PPC_FLAGS_INPUT_POWER9,
    /* PowerPC 401 bus                  */
    PPC_FLAGS_INPUT_401,
    /* Freescale RCPU bus               */
Loading