DEFINE_PROP_END_OF_LIST(),
};
+static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
+ PowerPCCPU *cpu, Error **errp)
+{
+ SpaprXive *xive = SPAPR_XIVE(intc);
+ Object *obj;
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+ obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(xive), errp);
+ if (!obj) {
+ return -1;
+ }
+
+ spapr_cpu->tctx = XIVE_TCTX(obj);
+
+ /*
+ * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
+ * don't beneficiate from the reset of the XIVE IRQ backend
+ */
+ spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
+ return 0;
+}
+
static void spapr_xive_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
+ SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
dc->desc = "sPAPR XIVE Interrupt Controller";
dc->props = spapr_xive_properties;
xrc->get_nvt = spapr_xive_get_nvt;
xrc->write_nvt = spapr_xive_write_nvt;
xrc->get_tctx = spapr_xive_get_tctx;
+
+ sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
}
static const TypeInfo spapr_xive_info = {
_FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
}
+static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
+ PowerPCCPU *cpu, Error **errp)
+{
+ ICSState *ics = ICS_SPAPR(intc);
+ Object *obj;
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+ obj = icp_create(OBJECT(cpu), TYPE_ICP, ics->xics, errp);
+ if (!obj) {
+ return -1;
+ }
+
+ spapr_cpu->icp = ICP(obj);
+ return 0;
+}
+
static void ics_spapr_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ICSStateClass *isc = ICS_CLASS(klass);
+ SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
device_class_set_parent_realize(dc, ics_spapr_realize,
&isc->parent_realize);
+ sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
}
static const TypeInfo ics_spapr_info = {
ics_pic_print_info(spapr->ics, mon);
}
-static void spapr_irq_cpu_intc_create_xics(SpaprMachineState *spapr,
- PowerPCCPU *cpu, Error **errp)
-{
- Error *local_err = NULL;
- Object *obj;
- SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
-
- obj = icp_create(OBJECT(cpu), TYPE_ICP, XICS_FABRIC(spapr),
- &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- spapr_cpu->icp = ICP(obj);
-}
-
static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
{
if (!kvm_irqchip_in_kernel()) {
.free = spapr_irq_free_xics,
.print_info = spapr_irq_print_info_xics,
.dt_populate = spapr_dt_xics,
- .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
.post_load = spapr_irq_post_load_xics,
.reset = spapr_irq_reset_xics,
.set_irq = spapr_irq_set_irq_xics,
spapr_xive_pic_print_info(spapr->xive, mon);
}
-static void spapr_irq_cpu_intc_create_xive(SpaprMachineState *spapr,
- PowerPCCPU *cpu, Error **errp)
-{
- Error *local_err = NULL;
- Object *obj;
- SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
-
- obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(spapr->xive), &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- spapr_cpu->tctx = XIVE_TCTX(obj);
-
- /*
- * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
- * don't beneficiate from the reset of the XIVE IRQ backend
- */
- spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
-}
-
static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
{
return spapr_xive_post_load(spapr->xive, version_id);
.free = spapr_irq_free_xive,
.print_info = spapr_irq_print_info_xive,
.dt_populate = spapr_dt_xive,
- .cpu_intc_create = spapr_irq_cpu_intc_create_xive,
.post_load = spapr_irq_post_load_xive,
.reset = spapr_irq_reset_xive,
.set_irq = spapr_irq_set_irq_xive,
spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
}
-static void spapr_irq_cpu_intc_create_dual(SpaprMachineState *spapr,
- PowerPCCPU *cpu, Error **errp)
-{
- Error *local_err = NULL;
-
- spapr_irq_xive.cpu_intc_create(spapr, cpu, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- spapr_irq_xics.cpu_intc_create(spapr, cpu, errp);
-}
-
static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
{
/*
.free = spapr_irq_free_dual,
.print_info = spapr_irq_print_info_dual,
.dt_populate = spapr_irq_dt_populate_dual,
- .cpu_intc_create = spapr_irq_cpu_intc_create_dual,
.post_load = spapr_irq_post_load_dual,
.reset = spapr_irq_reset_dual,
.set_irq = spapr_irq_set_irq_dual,
/*
* sPAPR IRQ frontend routines for devices
*/
+#define ALL_INTCS(spapr_) \
+ { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
+
+int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
+ PowerPCCPU *cpu, Error **errp)
+{
+ SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
+ int i;
+ int rc;
+
+ for (i = 0; i < ARRAY_SIZE(intcs); i++) {
+ SpaprInterruptController *intc = intcs[i];
+ if (intc) {
+ SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
+ rc = sicc->cpu_intc_create(intc, cpu, errp);
+ if (rc < 0) {
+ return rc;
+ }
+ }
+ }
+
+ return 0;
+}
+
void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
{
MachineState *machine = MACHINE(spapr);
.free = spapr_irq_free_xics,
.print_info = spapr_irq_print_info_xics,
.dt_populate = spapr_dt_xics,
- .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
.post_load = spapr_irq_post_load_xics,
.reset = spapr_irq_reset_xics,
.set_irq = spapr_irq_set_irq_xics,
typedef struct SpaprInterruptControllerClass {
InterfaceClass parent;
+
+ /*
+ * These methods will typically be called on all intcs, active and
+ * inactive
+ */
+ int (*cpu_intc_create)(SpaprInterruptController *intc,
+ PowerPCCPU *cpu, Error **errp);
} SpaprInterruptControllerClass;
+int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
+ PowerPCCPU *cpu, Error **errp);
+
+
void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
Error **errp);
void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
void *fdt, uint32_t phandle);
- void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu,
- Error **errp);
int (*post_load)(SpaprMachineState *spapr, int version_id);
void (*reset)(SpaprMachineState *spapr, Error **errp);
void (*set_irq)(void *opaque, int srcno, int val);