aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/ppc.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2019-02-15 17:16:47 +0100
committerDavid Gibson <david@gibson.dropbear.id.au>2019-02-26 09:21:24 +1100
commit67afe7759df4c3dec8abfc373b98d1a8d108ff66 (patch)
tree1dce47e48de20ace358a57ecad02635fd46927fa /hw/ppc/ppc.c
parentd8ce5fd6643d5c568d6357354c205474e7022602 (diff)
target/ppc: Add POWER9 external interrupt model
Adds support for the Hypervisor directed interrupts in addition to the OS ones. Signed-off-by: Benjamin 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: Cédric Le Goater <clg@kaod.org> Message-Id: <20190215161648.9600-10-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw/ppc/ppc.c')
-rw-r--r--hw/ppc/ppc.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 12439dbe5d..d1e3d4cd20 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -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)