aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/xics.c95
-rw-r--r--hw/intc/xics_kvm.c45
-rw-r--r--hw/intc/xics_pnv.c6
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);
}