int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
{
+ spapr_irq_update_active_intc(spapr);
return spapr->irq->post_load(spapr, version_id);
}
{
assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr));
+ spapr_irq_update_active_intc(spapr);
+
if (spapr->irq->reset) {
spapr->irq->reset(spapr, errp);
}
return phandle;
}
+static void set_active_intc(SpaprMachineState *spapr,
+ SpaprInterruptController *new_intc)
+{
+ SpaprInterruptControllerClass *sicc;
+
+ assert(new_intc);
+
+ if (new_intc == spapr->active_intc) {
+ /* Nothing to do */
+ return;
+ }
+
+ if (spapr->active_intc) {
+ sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc);
+ if (sicc->deactivate) {
+ sicc->deactivate(spapr->active_intc);
+ }
+ }
+
+ sicc = SPAPR_INTC_GET_CLASS(new_intc);
+ if (sicc->activate) {
+ sicc->activate(new_intc, &error_fatal);
+ }
+
+ spapr->active_intc = new_intc;
+}
+
+void spapr_irq_update_active_intc(SpaprMachineState *spapr)
+{
+ SpaprInterruptController *new_intc;
+
+ if (!spapr->ics) {
+ /*
+ * XXX before we run CAS, ov5_cas is initialized empty, which
+ * indicates XICS, even if we have ic-mode=xive. TODO: clean
+ * up the CAS path so that we have a clearer way of handling
+ * this.
+ */
+ new_intc = SPAPR_INTC(spapr->xive);
+ } else if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+ new_intc = SPAPR_INTC(spapr->xive);
+ } else {
+ new_intc = SPAPR_INTC(spapr->ics);
+ }
+
+ set_active_intc(spapr, new_intc);
+}
+
/*
* XICS legacy routines - to deprecate one day
*/
struct SpaprVioBus *vio_bus;
QLIST_HEAD(, SpaprPhbState) phbs;
struct SpaprNvram *nvram;
- ICSState *ics;
SpaprRtcState rtc;
SpaprResizeHpt resize_hpt;
int32_t irq_map_nr;
unsigned long *irq_map;
- SpaprXive *xive;
SpaprIrq *irq;
qemu_irq *qirqs;
+ SpaprInterruptController *active_intc;
+ ICSState *ics;
+ SpaprXive *xive;
bool cmd_line_caps[SPAPR_CAP_NUM];
SpaprCapabilities def, eff, mig;
typedef struct SpaprInterruptControllerClass {
InterfaceClass parent;
+ int (*activate)(SpaprInterruptController *intc, Error **errp);
+ void (*deactivate)(SpaprInterruptController *intc);
+
/*
* These methods will typically be called on all intcs, active and
* inactive
void (*free_irq)(SpaprInterruptController *intc, int irq);
} SpaprInterruptControllerClass;
+void spapr_irq_update_active_intc(SpaprMachineState *spapr);
+
int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
PowerPCCPU *cpu, Error **errp);