diff options
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/xics.c | 95 | ||||
-rw-r--r-- | hw/intc/xics_kvm.c | 45 | ||||
-rw-r--r-- | hw/intc/xics_pnv.c | 6 |
3 files changed, 54 insertions, 92 deletions
diff --git a/hw/intc/xics.c b/hw/intc/xics.c index ea3516794a..7ccfb53c55 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -38,50 +38,6 @@ #include "monitor/monitor.h" #include "hw/intc/intc.h" -void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu) -{ - CPUState *cs = CPU(cpu); - ICPState *icp = ICP(cpu->intc); - - assert(icp); - assert(cs == icp->cs); - - icp->output = NULL; - icp->cs = NULL; -} - -void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu, ICPState *icp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - ICPStateClass *icpc; - - assert(icp); - - cpu->intc = OBJECT(icp); - icp->cs = cs; - - icpc = ICP_GET_CLASS(icp); - if (icpc->cpu_setup) { - icpc->cpu_setup(icp, cpu); - } - - switch (PPC_INPUT(env)) { - case PPC_FLAGS_INPUT_POWER7: - icp->output = env->irq_inputs[POWER7_INPUT_INT]; - break; - - case PPC_FLAGS_INPUT_970: - icp->output = env->irq_inputs[PPC970_INPUT_INT]; - break; - - default: - error_report("XICS interrupt controller does not support this CPU " - "bus model"); - abort(); - } -} - void icp_pic_print_info(ICPState *icp, Monitor *mon) { int cpu_index = icp->cs ? icp->cs->cpu_index : -1; @@ -325,6 +281,7 @@ static const VMStateDescription vmstate_icp_server = { static void icp_reset(void *dev) { ICPState *icp = ICP(dev); + ICPStateClass *icpc = ICP_GET_CLASS(icp); icp->xirr = 0; icp->pending_priority = 0xff; @@ -332,26 +289,58 @@ static void icp_reset(void *dev) /* Make all outputs are deasserted */ qemu_set_irq(icp->output, 0); + + if (icpc->reset) { + icpc->reset(icp); + } } static void icp_realize(DeviceState *dev, Error **errp) { ICPState *icp = ICP(dev); ICPStateClass *icpc = ICP_GET_CLASS(dev); + PowerPCCPU *cpu; + CPUPPCState *env; Object *obj; Error *err = NULL; - obj = object_property_get_link(OBJECT(dev), "xics", &err); + obj = object_property_get_link(OBJECT(dev), ICP_PROP_XICS, &err); if (!obj) { - error_setg(errp, "%s: required link 'xics' not found: %s", + error_setg(errp, "%s: required link '" ICP_PROP_XICS "' not found: %s", __func__, error_get_pretty(err)); return; } icp->xics = XICS_FABRIC(obj); + obj = object_property_get_link(OBJECT(dev), ICP_PROP_CPU, &err); + if (!obj) { + error_setg(errp, "%s: required link '" ICP_PROP_CPU "' not found: %s", + __func__, error_get_pretty(err)); + return; + } + + cpu = POWERPC_CPU(obj); + cpu->intc = OBJECT(icp); + icp->cs = CPU(obj); + + env = &cpu->env; + switch (PPC_INPUT(env)) { + case PPC_FLAGS_INPUT_POWER7: + icp->output = env->irq_inputs[POWER7_INPUT_INT]; + break; + + case PPC_FLAGS_INPUT_970: + icp->output = env->irq_inputs[PPC970_INPUT_INT]; + break; + + default: + error_setg(errp, "XICS interrupt controller does not support this CPU bus model"); + return; + } + if (icpc->realize) { - icpc->realize(dev, errp); + icpc->realize(icp, errp); } qemu_register_reset(icp_reset, dev); @@ -601,10 +590,8 @@ static void ics_simple_initfn(Object *obj) ics->offset = XICS_IRQ_BASE; } -static void ics_simple_realize(DeviceState *dev, Error **errp) +static void ics_simple_realize(ICSState *ics, Error **errp) { - ICSState *ics = ICS_SIMPLE(dev); - if (!ics->nr_irqs) { error_setg(errp, "Number of interrupts needs to be greater 0"); return; @@ -612,7 +599,7 @@ static void ics_simple_realize(DeviceState *dev, Error **errp) ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState)); ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs); - qemu_register_reset(ics_simple_reset, dev); + qemu_register_reset(ics_simple_reset, ics); } static Property ics_simple_properties[] = { @@ -649,9 +636,9 @@ static void ics_base_realize(DeviceState *dev, Error **errp) Object *obj; Error *err = NULL; - obj = object_property_get_link(OBJECT(dev), "xics", &err); + obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &err); if (!obj) { - error_setg(errp, "%s: required link 'xics' not found: %s", + error_setg(errp, "%s: required link '" ICS_PROP_XICS "' not found: %s", __func__, error_get_pretty(err)); return; } @@ -659,7 +646,7 @@ static void ics_base_realize(DeviceState *dev, Error **errp) if (icsc->realize) { - icsc->realize(dev, errp); + icsc->realize(ics, errp); } } diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 14b8f6f6e4..3091ad3ac2 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -110,25 +110,14 @@ static int icp_set_kvm_state(ICPState *icp, int version_id) return 0; } -static void icp_kvm_reset(void *dev) +static void icp_kvm_reset(ICPState *icp) { - ICPState *icp = ICP(dev); - - icp->xirr = 0; - icp->pending_priority = 0xff; - icp->mfrr = 0xff; - - /* Make all outputs as deasserted only if the CPU thread is in use */ - if (icp->output) { - qemu_set_irq(icp->output, 0); - } - icp_set_kvm_state(icp, 1); } -static void icp_kvm_cpu_setup(ICPState *icp, PowerPCCPU *cpu) +static void icp_kvm_realize(ICPState *icp, Error **errp) { - CPUState *cs = CPU(cpu); + CPUState *cs = icp->cs; KVMEnabledICP *enabled_icp; unsigned long vcpu_id = kvm_arch_vcpu_id(cs); int ret; @@ -150,35 +139,23 @@ static void icp_kvm_cpu_setup(ICPState *icp, PowerPCCPU *cpu) ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd, vcpu_id); if (ret < 0) { - error_report("Unable to connect CPU%ld to kernel XICS: %s", vcpu_id, - strerror(errno)); - exit(1); + error_setg(errp, "Unable to connect CPU%ld to kernel XICS: %s", vcpu_id, + strerror(errno)); + return; } enabled_icp = g_malloc(sizeof(*enabled_icp)); enabled_icp->vcpu_id = vcpu_id; QLIST_INSERT_HEAD(&kvm_enabled_icps, enabled_icp, node); } -static void icp_kvm_realize(DeviceState *dev, Error **errp) -{ - qemu_register_reset(icp_kvm_reset, dev); -} - -static void icp_kvm_unrealize(DeviceState *dev, Error **errp) -{ - qemu_unregister_reset(icp_kvm_reset, dev); -} - static void icp_kvm_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); ICPStateClass *icpc = ICP_CLASS(klass); - dc->realize = icp_kvm_realize; - dc->unrealize = icp_kvm_unrealize; icpc->pre_save = icp_get_kvm_state; icpc->post_load = icp_set_kvm_state; - icpc->cpu_setup = icp_kvm_cpu_setup; + icpc->realize = icp_kvm_realize; + icpc->reset = icp_kvm_reset; } static const TypeInfo icp_kvm_info = { @@ -351,10 +328,8 @@ static void ics_kvm_reset(void *dev) ics_set_kvm_state(ics, 1); } -static void ics_kvm_realize(DeviceState *dev, Error **errp) +static void ics_kvm_realize(ICSState *ics, Error **errp) { - ICSState *ics = ICS_SIMPLE(dev); - if (!ics->nr_irqs) { error_setg(errp, "Number of interrupts needs to be greater 0"); return; @@ -362,7 +337,7 @@ static void ics_kvm_realize(DeviceState *dev, Error **errp) ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState)); ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs); - qemu_register_reset(ics_kvm_reset, dev); + qemu_register_reset(ics_kvm_reset, ics); } static void ics_kvm_class_init(ObjectClass *klass, void *data) diff --git a/hw/intc/xics_pnv.c b/hw/intc/xics_pnv.c index 12ae605f10..2a955a8946 100644 --- a/hw/intc/xics_pnv.c +++ b/hw/intc/xics_pnv.c @@ -159,11 +159,11 @@ static const MemoryRegionOps pnv_icp_ops = { }, }; -static void pnv_icp_realize(DeviceState *dev, Error **errp) +static void pnv_icp_realize(ICPState *icp, Error **errp) { - PnvICPState *icp = PNV_ICP(dev); + PnvICPState *pnv_icp = PNV_ICP(icp); - memory_region_init_io(&icp->mmio, OBJECT(dev), &pnv_icp_ops, + memory_region_init_io(&pnv_icp->mmio, OBJECT(icp), &pnv_icp_ops, icp, "icp-thread", 0x1000); } |