mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-18 23:52:14 -06:00
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>
This commit is contained in:
parent
d8ce5fd664
commit
67afe7759d
7 changed files with 61 additions and 2 deletions
|
@ -338,6 +338,9 @@ static void icp_realize(DeviceState *dev, Error **errp)
|
||||||
case PPC_FLAGS_INPUT_POWER7:
|
case PPC_FLAGS_INPUT_POWER7:
|
||||||
icp->output = env->irq_inputs[POWER7_INPUT_INT];
|
icp->output = env->irq_inputs[POWER7_INPUT_INT];
|
||||||
break;
|
break;
|
||||||
|
case PPC_FLAGS_INPUT_POWER9: /* For SPAPR xics emulation */
|
||||||
|
icp->output = env->irq_inputs[POWER9_INPUT_INT];
|
||||||
|
break;
|
||||||
|
|
||||||
case PPC_FLAGS_INPUT_970:
|
case PPC_FLAGS_INPUT_970:
|
||||||
icp->output = env->irq_inputs[PPC970_INPUT_INT];
|
icp->output = env->irq_inputs[PPC970_INPUT_INT];
|
||||||
|
|
|
@ -484,6 +484,9 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp)
|
||||||
case PPC_FLAGS_INPUT_POWER7:
|
case PPC_FLAGS_INPUT_POWER7:
|
||||||
tctx->output = env->irq_inputs[POWER7_INPUT_INT];
|
tctx->output = env->irq_inputs[POWER7_INPUT_INT];
|
||||||
break;
|
break;
|
||||||
|
case PPC_FLAGS_INPUT_POWER9:
|
||||||
|
tctx->output = env->irq_inputs[POWER9_INPUT_INT];
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error_setg(errp, "XIVE interrupt controller does not support "
|
error_setg(errp, "XIVE interrupt controller does not support "
|
||||||
|
|
42
hw/ppc/ppc.c
42
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,
|
env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, cpu,
|
||||||
POWER7_INPUT_NB);
|
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) */
|
#endif /* defined(TARGET_PPC64) */
|
||||||
|
|
||||||
void ppc40x_core_reset(PowerPCCPU *cpu)
|
void ppc40x_core_reset(PowerPCCPU *cpu)
|
||||||
|
|
|
@ -73,6 +73,7 @@ static inline void ppc40x_irq_init(PowerPCCPU *cpu) {}
|
||||||
static inline void ppc6xx_irq_init(PowerPCCPU *cpu) {}
|
static inline void ppc6xx_irq_init(PowerPCCPU *cpu) {}
|
||||||
static inline void ppc970_irq_init(PowerPCCPU *cpu) {}
|
static inline void ppc970_irq_init(PowerPCCPU *cpu) {}
|
||||||
static inline void ppcPOWER7_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) {}
|
static inline void ppce500_irq_init(PowerPCCPU *cpu) {}
|
||||||
#else
|
#else
|
||||||
void ppc40x_irq_init(PowerPCCPU *cpu);
|
void ppc40x_irq_init(PowerPCCPU *cpu);
|
||||||
|
@ -80,6 +81,7 @@ void ppce500_irq_init(PowerPCCPU *cpu);
|
||||||
void ppc6xx_irq_init(PowerPCCPU *cpu);
|
void ppc6xx_irq_init(PowerPCCPU *cpu);
|
||||||
void ppc970_irq_init(PowerPCCPU *cpu);
|
void ppc970_irq_init(PowerPCCPU *cpu);
|
||||||
void ppcPOWER7_irq_init(PowerPCCPU *cpu);
|
void ppcPOWER7_irq_init(PowerPCCPU *cpu);
|
||||||
|
void ppcPOWER9_irq_init(PowerPCCPU *cpu);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* PPC machines for OpenBIOS */
|
/* PPC machines for OpenBIOS */
|
||||||
|
|
|
@ -142,6 +142,8 @@ enum powerpc_input_t {
|
||||||
PPC_FLAGS_INPUT_970,
|
PPC_FLAGS_INPUT_970,
|
||||||
/* PowerPC POWER7 bus */
|
/* PowerPC POWER7 bus */
|
||||||
PPC_FLAGS_INPUT_POWER7,
|
PPC_FLAGS_INPUT_POWER7,
|
||||||
|
/* PowerPC POWER9 bus */
|
||||||
|
PPC_FLAGS_INPUT_POWER9,
|
||||||
/* PowerPC 401 bus */
|
/* PowerPC 401 bus */
|
||||||
PPC_FLAGS_INPUT_401,
|
PPC_FLAGS_INPUT_401,
|
||||||
/* Freescale RCPU bus */
|
/* Freescale RCPU bus */
|
||||||
|
|
|
@ -2327,6 +2327,13 @@ enum {
|
||||||
* them */
|
* them */
|
||||||
POWER7_INPUT_NB,
|
POWER7_INPUT_NB,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/* POWER9 input pins */
|
||||||
|
POWER9_INPUT_INT = 0,
|
||||||
|
POWER9_INPUT_HINT = 1,
|
||||||
|
POWER9_INPUT_NB,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Hardware exceptions definitions */
|
/* Hardware exceptions definitions */
|
||||||
|
|
|
@ -8793,7 +8793,7 @@ static void init_proc_POWER9(CPUPPCState *env)
|
||||||
|
|
||||||
/* Allocate hardware IRQ controller */
|
/* Allocate hardware IRQ controller */
|
||||||
init_excp_POWER9(env);
|
init_excp_POWER9(env);
|
||||||
ppcPOWER7_irq_init(ppc_env_get_cpu(env));
|
ppcPOWER9_irq_init(ppc_env_get_cpu(env));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
|
static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
|
||||||
|
@ -8920,7 +8920,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
|
||||||
pcc->radix_page_info = &POWER9_radix_page_info;
|
pcc->radix_page_info = &POWER9_radix_page_info;
|
||||||
#endif
|
#endif
|
||||||
pcc->excp_model = POWERPC_EXCP_POWER9;
|
pcc->excp_model = POWERPC_EXCP_POWER9;
|
||||||
pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
|
pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
|
||||||
pcc->bfd_mach = bfd_mach_ppc64;
|
pcc->bfd_mach = bfd_mach_ppc64;
|
||||||
pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
|
pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
|
||||||
POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
|
POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue