xics: split to xics and xics-common
[qemu/kevin.git] / hw / intc / xics.c
blob5ed2618769f768d98981722031d939a45200ea69
1 /*
2 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
4 * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
6 * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
28 #include "hw/hw.h"
29 #include "trace.h"
30 #include "hw/ppc/spapr.h"
31 #include "hw/ppc/xics.h"
32 #include "qemu/error-report.h"
33 #include "qapi/visitor.h"
35 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
37 CPUState *cs = CPU(cpu);
38 CPUPPCState *env = &cpu->env;
39 ICPState *ss = &icp->ss[cs->cpu_index];
41 assert(cs->cpu_index < icp->nr_servers);
43 switch (PPC_INPUT(env)) {
44 case PPC_FLAGS_INPUT_POWER7:
45 ss->output = env->irq_inputs[POWER7_INPUT_INT];
46 break;
48 case PPC_FLAGS_INPUT_970:
49 ss->output = env->irq_inputs[PPC970_INPUT_INT];
50 break;
52 default:
53 error_report("XICS interrupt controller does not support this CPU "
54 "bus model");
55 abort();
60 * XICS Common class - parent for emulated XICS and KVM-XICS
62 static void xics_common_reset(DeviceState *d)
64 XICSState *icp = XICS_COMMON(d);
65 int i;
67 for (i = 0; i < icp->nr_servers; i++) {
68 device_reset(DEVICE(&icp->ss[i]));
71 device_reset(DEVICE(icp->ics));
74 static void xics_prop_get_nr_irqs(Object *obj, Visitor *v,
75 void *opaque, const char *name, Error **errp)
77 XICSState *icp = XICS_COMMON(obj);
78 int64_t value = icp->nr_irqs;
80 visit_type_int(v, &value, name, errp);
83 static void xics_prop_set_nr_irqs(Object *obj, Visitor *v,
84 void *opaque, const char *name, Error **errp)
86 XICSState *icp = XICS_COMMON(obj);
87 XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
88 Error *error = NULL;
89 int64_t value;
91 visit_type_int(v, &value, name, &error);
92 if (error) {
93 error_propagate(errp, error);
94 return;
96 if (icp->nr_irqs) {
97 error_setg(errp, "Number of interrupts is already set to %u",
98 icp->nr_irqs);
99 return;
102 assert(info->set_nr_irqs);
103 assert(icp->ics);
104 info->set_nr_irqs(icp, value, errp);
107 static void xics_prop_get_nr_servers(Object *obj, Visitor *v,
108 void *opaque, const char *name,
109 Error **errp)
111 XICSState *icp = XICS_COMMON(obj);
112 int64_t value = icp->nr_servers;
114 visit_type_int(v, &value, name, errp);
117 static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
118 void *opaque, const char *name,
119 Error **errp)
121 XICSState *icp = XICS_COMMON(obj);
122 XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
123 Error *error = NULL;
124 int64_t value;
126 visit_type_int(v, &value, name, &error);
127 if (error) {
128 error_propagate(errp, error);
129 return;
131 if (icp->nr_servers) {
132 error_setg(errp, "Number of servers is already set to %u",
133 icp->nr_servers);
134 return;
137 assert(info->set_nr_servers);
138 info->set_nr_servers(icp, value, errp);
141 static void xics_common_initfn(Object *obj)
143 object_property_add(obj, "nr_irqs", "int",
144 xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
145 NULL, NULL, NULL);
146 object_property_add(obj, "nr_servers", "int",
147 xics_prop_get_nr_servers, xics_prop_set_nr_servers,
148 NULL, NULL, NULL);
151 static void xics_common_class_init(ObjectClass *oc, void *data)
153 DeviceClass *dc = DEVICE_CLASS(oc);
155 dc->reset = xics_common_reset;
158 static const TypeInfo xics_common_info = {
159 .name = TYPE_XICS_COMMON,
160 .parent = TYPE_SYS_BUS_DEVICE,
161 .instance_size = sizeof(XICSState),
162 .class_size = sizeof(XICSStateClass),
163 .instance_init = xics_common_initfn,
164 .class_init = xics_common_class_init,
168 * ICP: Presentation layer
171 #define XISR_MASK 0x00ffffff
172 #define CPPR_MASK 0xff000000
174 #define XISR(ss) (((ss)->xirr) & XISR_MASK)
175 #define CPPR(ss) (((ss)->xirr) >> 24)
177 static void ics_reject(ICSState *ics, int nr);
178 static void ics_resend(ICSState *ics);
179 static void ics_eoi(ICSState *ics, int nr);
181 static void icp_check_ipi(XICSState *icp, int server)
183 ICPState *ss = icp->ss + server;
185 if (XISR(ss) && (ss->pending_priority <= ss->mfrr)) {
186 return;
189 trace_xics_icp_check_ipi(server, ss->mfrr);
191 if (XISR(ss)) {
192 ics_reject(icp->ics, XISR(ss));
195 ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI;
196 ss->pending_priority = ss->mfrr;
197 qemu_irq_raise(ss->output);
200 static void icp_resend(XICSState *icp, int server)
202 ICPState *ss = icp->ss + server;
204 if (ss->mfrr < CPPR(ss)) {
205 icp_check_ipi(icp, server);
207 ics_resend(icp->ics);
210 static void icp_set_cppr(XICSState *icp, int server, uint8_t cppr)
212 ICPState *ss = icp->ss + server;
213 uint8_t old_cppr;
214 uint32_t old_xisr;
216 old_cppr = CPPR(ss);
217 ss->xirr = (ss->xirr & ~CPPR_MASK) | (cppr << 24);
219 if (cppr < old_cppr) {
220 if (XISR(ss) && (cppr <= ss->pending_priority)) {
221 old_xisr = XISR(ss);
222 ss->xirr &= ~XISR_MASK; /* Clear XISR */
223 ss->pending_priority = 0xff;
224 qemu_irq_lower(ss->output);
225 ics_reject(icp->ics, old_xisr);
227 } else {
228 if (!XISR(ss)) {
229 icp_resend(icp, server);
234 static void icp_set_mfrr(XICSState *icp, int server, uint8_t mfrr)
236 ICPState *ss = icp->ss + server;
238 ss->mfrr = mfrr;
239 if (mfrr < CPPR(ss)) {
240 icp_check_ipi(icp, server);
244 static uint32_t icp_accept(ICPState *ss)
246 uint32_t xirr = ss->xirr;
248 qemu_irq_lower(ss->output);
249 ss->xirr = ss->pending_priority << 24;
250 ss->pending_priority = 0xff;
252 trace_xics_icp_accept(xirr, ss->xirr);
254 return xirr;
257 static void icp_eoi(XICSState *icp, int server, uint32_t xirr)
259 ICPState *ss = icp->ss + server;
261 /* Send EOI -> ICS */
262 ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
263 trace_xics_icp_eoi(server, xirr, ss->xirr);
264 ics_eoi(icp->ics, xirr & XISR_MASK);
265 if (!XISR(ss)) {
266 icp_resend(icp, server);
270 static void icp_irq(XICSState *icp, int server, int nr, uint8_t priority)
272 ICPState *ss = icp->ss + server;
274 trace_xics_icp_irq(server, nr, priority);
276 if ((priority >= CPPR(ss))
277 || (XISR(ss) && (ss->pending_priority <= priority))) {
278 ics_reject(icp->ics, nr);
279 } else {
280 if (XISR(ss)) {
281 ics_reject(icp->ics, XISR(ss));
283 ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK);
284 ss->pending_priority = priority;
285 trace_xics_icp_raise(ss->xirr, ss->pending_priority);
286 qemu_irq_raise(ss->output);
290 static void icp_dispatch_pre_save(void *opaque)
292 ICPState *ss = opaque;
293 ICPStateClass *info = ICP_GET_CLASS(ss);
295 if (info->pre_save) {
296 info->pre_save(ss);
300 static int icp_dispatch_post_load(void *opaque, int version_id)
302 ICPState *ss = opaque;
303 ICPStateClass *info = ICP_GET_CLASS(ss);
305 if (info->post_load) {
306 return info->post_load(ss, version_id);
309 return 0;
312 static const VMStateDescription vmstate_icp_server = {
313 .name = "icp/server",
314 .version_id = 1,
315 .minimum_version_id = 1,
316 .minimum_version_id_old = 1,
317 .pre_save = icp_dispatch_pre_save,
318 .post_load = icp_dispatch_post_load,
319 .fields = (VMStateField []) {
320 /* Sanity check */
321 VMSTATE_UINT32(xirr, ICPState),
322 VMSTATE_UINT8(pending_priority, ICPState),
323 VMSTATE_UINT8(mfrr, ICPState),
324 VMSTATE_END_OF_LIST()
328 static void icp_reset(DeviceState *dev)
330 ICPState *icp = ICP(dev);
332 icp->xirr = 0;
333 icp->pending_priority = 0xff;
334 icp->mfrr = 0xff;
336 /* Make all outputs are deasserted */
337 qemu_set_irq(icp->output, 0);
340 static void icp_class_init(ObjectClass *klass, void *data)
342 DeviceClass *dc = DEVICE_CLASS(klass);
344 dc->reset = icp_reset;
345 dc->vmsd = &vmstate_icp_server;
348 static const TypeInfo icp_info = {
349 .name = TYPE_ICP,
350 .parent = TYPE_DEVICE,
351 .instance_size = sizeof(ICPState),
352 .class_init = icp_class_init,
353 .class_size = sizeof(ICPStateClass),
357 * ICS: Source layer
359 static int ics_valid_irq(ICSState *ics, uint32_t nr)
361 return (nr >= ics->offset)
362 && (nr < (ics->offset + ics->nr_irqs));
365 static void resend_msi(ICSState *ics, int srcno)
367 ICSIRQState *irq = ics->irqs + srcno;
369 /* FIXME: filter by server#? */
370 if (irq->status & XICS_STATUS_REJECTED) {
371 irq->status &= ~XICS_STATUS_REJECTED;
372 if (irq->priority != 0xff) {
373 icp_irq(ics->icp, irq->server, srcno + ics->offset,
374 irq->priority);
379 static void resend_lsi(ICSState *ics, int srcno)
381 ICSIRQState *irq = ics->irqs + srcno;
383 if ((irq->priority != 0xff)
384 && (irq->status & XICS_STATUS_ASSERTED)
385 && !(irq->status & XICS_STATUS_SENT)) {
386 irq->status |= XICS_STATUS_SENT;
387 icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
391 static void set_irq_msi(ICSState *ics, int srcno, int val)
393 ICSIRQState *irq = ics->irqs + srcno;
395 trace_xics_set_irq_msi(srcno, srcno + ics->offset);
397 if (val) {
398 if (irq->priority == 0xff) {
399 irq->status |= XICS_STATUS_MASKED_PENDING;
400 trace_xics_masked_pending();
401 } else {
402 icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
407 static void set_irq_lsi(ICSState *ics, int srcno, int val)
409 ICSIRQState *irq = ics->irqs + srcno;
411 trace_xics_set_irq_lsi(srcno, srcno + ics->offset);
412 if (val) {
413 irq->status |= XICS_STATUS_ASSERTED;
414 } else {
415 irq->status &= ~XICS_STATUS_ASSERTED;
417 resend_lsi(ics, srcno);
420 static void ics_set_irq(void *opaque, int srcno, int val)
422 ICSState *ics = (ICSState *)opaque;
424 if (ics->islsi[srcno]) {
425 set_irq_lsi(ics, srcno, val);
426 } else {
427 set_irq_msi(ics, srcno, val);
431 static void write_xive_msi(ICSState *ics, int srcno)
433 ICSIRQState *irq = ics->irqs + srcno;
435 if (!(irq->status & XICS_STATUS_MASKED_PENDING)
436 || (irq->priority == 0xff)) {
437 return;
440 irq->status &= ~XICS_STATUS_MASKED_PENDING;
441 icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
444 static void write_xive_lsi(ICSState *ics, int srcno)
446 resend_lsi(ics, srcno);
449 static void ics_write_xive(ICSState *ics, int nr, int server,
450 uint8_t priority, uint8_t saved_priority)
452 int srcno = nr - ics->offset;
453 ICSIRQState *irq = ics->irqs + srcno;
455 irq->server = server;
456 irq->priority = priority;
457 irq->saved_priority = saved_priority;
459 trace_xics_ics_write_xive(nr, srcno, server, priority);
461 if (ics->islsi[srcno]) {
462 write_xive_lsi(ics, srcno);
463 } else {
464 write_xive_msi(ics, srcno);
468 static void ics_reject(ICSState *ics, int nr)
470 ICSIRQState *irq = ics->irqs + nr - ics->offset;
472 trace_xics_ics_reject(nr, nr - ics->offset);
473 irq->status |= XICS_STATUS_REJECTED; /* Irrelevant but harmless for LSI */
474 irq->status &= ~XICS_STATUS_SENT; /* Irrelevant but harmless for MSI */
477 static void ics_resend(ICSState *ics)
479 int i;
481 for (i = 0; i < ics->nr_irqs; i++) {
482 /* FIXME: filter by server#? */
483 if (ics->islsi[i]) {
484 resend_lsi(ics, i);
485 } else {
486 resend_msi(ics, i);
491 static void ics_eoi(ICSState *ics, int nr)
493 int srcno = nr - ics->offset;
494 ICSIRQState *irq = ics->irqs + srcno;
496 trace_xics_ics_eoi(nr);
498 if (ics->islsi[srcno]) {
499 irq->status &= ~XICS_STATUS_SENT;
503 static void ics_reset(DeviceState *dev)
505 ICSState *ics = ICS(dev);
506 int i;
508 memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
509 for (i = 0; i < ics->nr_irqs; i++) {
510 ics->irqs[i].priority = 0xff;
511 ics->irqs[i].saved_priority = 0xff;
515 static int ics_post_load(ICSState *ics, int version_id)
517 int i;
519 for (i = 0; i < ics->icp->nr_servers; i++) {
520 icp_resend(ics->icp, i);
523 return 0;
526 static void ics_dispatch_pre_save(void *opaque)
528 ICSState *ics = opaque;
529 ICSStateClass *info = ICS_GET_CLASS(ics);
531 if (info->pre_save) {
532 info->pre_save(ics);
536 static int ics_dispatch_post_load(void *opaque, int version_id)
538 ICSState *ics = opaque;
539 ICSStateClass *info = ICS_GET_CLASS(ics);
541 if (info->post_load) {
542 return info->post_load(ics, version_id);
545 return 0;
548 static const VMStateDescription vmstate_ics_irq = {
549 .name = "ics/irq",
550 .version_id = 1,
551 .minimum_version_id = 1,
552 .minimum_version_id_old = 1,
553 .fields = (VMStateField []) {
554 VMSTATE_UINT32(server, ICSIRQState),
555 VMSTATE_UINT8(priority, ICSIRQState),
556 VMSTATE_UINT8(saved_priority, ICSIRQState),
557 VMSTATE_UINT8(status, ICSIRQState),
558 VMSTATE_END_OF_LIST()
562 static const VMStateDescription vmstate_ics = {
563 .name = "ics",
564 .version_id = 1,
565 .minimum_version_id = 1,
566 .minimum_version_id_old = 1,
567 .pre_save = ics_dispatch_pre_save,
568 .post_load = ics_dispatch_post_load,
569 .fields = (VMStateField []) {
570 /* Sanity check */
571 VMSTATE_UINT32_EQUAL(nr_irqs, ICSState),
573 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
574 vmstate_ics_irq, ICSIRQState),
575 VMSTATE_END_OF_LIST()
579 static void ics_initfn(Object *obj)
581 ICSState *ics = ICS(obj);
583 ics->offset = XICS_IRQ_BASE;
586 static void ics_realize(DeviceState *dev, Error **errp)
588 ICSState *ics = ICS(dev);
590 if (!ics->nr_irqs) {
591 error_setg(errp, "Number of interrupts needs to be greater 0");
592 return;
594 ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
595 ics->islsi = g_malloc0(ics->nr_irqs * sizeof(bool));
596 ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);
599 static void ics_class_init(ObjectClass *klass, void *data)
601 DeviceClass *dc = DEVICE_CLASS(klass);
602 ICSStateClass *isc = ICS_CLASS(klass);
604 dc->realize = ics_realize;
605 dc->vmsd = &vmstate_ics;
606 dc->reset = ics_reset;
607 isc->post_load = ics_post_load;
610 static const TypeInfo ics_info = {
611 .name = TYPE_ICS,
612 .parent = TYPE_DEVICE,
613 .instance_size = sizeof(ICSState),
614 .class_init = ics_class_init,
615 .class_size = sizeof(ICSStateClass),
616 .instance_init = ics_initfn,
620 * Exported functions
623 qemu_irq xics_get_qirq(XICSState *icp, int irq)
625 if (!ics_valid_irq(icp->ics, irq)) {
626 return NULL;
629 return icp->ics->qirqs[irq - icp->ics->offset];
632 void xics_set_irq_type(XICSState *icp, int irq, bool lsi)
634 assert(ics_valid_irq(icp->ics, irq));
636 icp->ics->islsi[irq - icp->ics->offset] = lsi;
640 * Guest interfaces
643 static target_ulong h_cppr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
644 target_ulong opcode, target_ulong *args)
646 CPUState *cs = CPU(cpu);
647 target_ulong cppr = args[0];
649 icp_set_cppr(spapr->icp, cs->cpu_index, cppr);
650 return H_SUCCESS;
653 static target_ulong h_ipi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
654 target_ulong opcode, target_ulong *args)
656 target_ulong server = args[0];
657 target_ulong mfrr = args[1];
659 if (server >= spapr->icp->nr_servers) {
660 return H_PARAMETER;
663 icp_set_mfrr(spapr->icp, server, mfrr);
664 return H_SUCCESS;
667 static target_ulong h_xirr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
668 target_ulong opcode, target_ulong *args)
670 CPUState *cs = CPU(cpu);
671 uint32_t xirr = icp_accept(spapr->icp->ss + cs->cpu_index);
673 args[0] = xirr;
674 return H_SUCCESS;
677 static target_ulong h_eoi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
678 target_ulong opcode, target_ulong *args)
680 CPUState *cs = CPU(cpu);
681 target_ulong xirr = args[0];
683 icp_eoi(spapr->icp, cs->cpu_index, xirr);
684 return H_SUCCESS;
687 static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
688 uint32_t token,
689 uint32_t nargs, target_ulong args,
690 uint32_t nret, target_ulong rets)
692 ICSState *ics = spapr->icp->ics;
693 uint32_t nr, server, priority;
695 if ((nargs != 3) || (nret != 1)) {
696 rtas_st(rets, 0, -3);
697 return;
700 nr = rtas_ld(args, 0);
701 server = rtas_ld(args, 1);
702 priority = rtas_ld(args, 2);
704 if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
705 || (priority > 0xff)) {
706 rtas_st(rets, 0, -3);
707 return;
710 ics_write_xive(ics, nr, server, priority, priority);
712 rtas_st(rets, 0, 0); /* Success */
715 static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
716 uint32_t token,
717 uint32_t nargs, target_ulong args,
718 uint32_t nret, target_ulong rets)
720 ICSState *ics = spapr->icp->ics;
721 uint32_t nr;
723 if ((nargs != 1) || (nret != 3)) {
724 rtas_st(rets, 0, -3);
725 return;
728 nr = rtas_ld(args, 0);
730 if (!ics_valid_irq(ics, nr)) {
731 rtas_st(rets, 0, -3);
732 return;
735 rtas_st(rets, 0, 0); /* Success */
736 rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
737 rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
740 static void rtas_int_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
741 uint32_t token,
742 uint32_t nargs, target_ulong args,
743 uint32_t nret, target_ulong rets)
745 ICSState *ics = spapr->icp->ics;
746 uint32_t nr;
748 if ((nargs != 1) || (nret != 1)) {
749 rtas_st(rets, 0, -3);
750 return;
753 nr = rtas_ld(args, 0);
755 if (!ics_valid_irq(ics, nr)) {
756 rtas_st(rets, 0, -3);
757 return;
760 ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
761 ics->irqs[nr - ics->offset].priority);
763 rtas_st(rets, 0, 0); /* Success */
766 static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr,
767 uint32_t token,
768 uint32_t nargs, target_ulong args,
769 uint32_t nret, target_ulong rets)
771 ICSState *ics = spapr->icp->ics;
772 uint32_t nr;
774 if ((nargs != 1) || (nret != 1)) {
775 rtas_st(rets, 0, -3);
776 return;
779 nr = rtas_ld(args, 0);
781 if (!ics_valid_irq(ics, nr)) {
782 rtas_st(rets, 0, -3);
783 return;
786 ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
787 ics->irqs[nr - ics->offset].saved_priority,
788 ics->irqs[nr - ics->offset].saved_priority);
790 rtas_st(rets, 0, 0); /* Success */
794 * XICS
797 static void xics_set_nr_irqs(XICSState *icp, uint32_t nr_irqs, Error **errp)
799 icp->nr_irqs = icp->ics->nr_irqs = nr_irqs;
802 static void xics_set_nr_servers(XICSState *icp, uint32_t nr_servers,
803 Error **errp)
805 int i;
807 icp->nr_servers = nr_servers;
809 icp->ss = g_malloc0(icp->nr_servers*sizeof(ICPState));
810 for (i = 0; i < icp->nr_servers; i++) {
811 char buffer[32];
812 object_initialize(&icp->ss[i], sizeof(icp->ss[i]), TYPE_ICP);
813 snprintf(buffer, sizeof(buffer), "icp[%d]", i);
814 object_property_add_child(OBJECT(icp), buffer, OBJECT(&icp->ss[i]),
815 errp);
819 static void xics_realize(DeviceState *dev, Error **errp)
821 XICSState *icp = XICS(dev);
822 Error *error = NULL;
823 int i;
825 if (!icp->nr_servers) {
826 error_setg(errp, "Number of servers needs to be greater 0");
827 return;
830 /* Registration of global state belongs into realize */
831 spapr_rtas_register("ibm,set-xive", rtas_set_xive);
832 spapr_rtas_register("ibm,get-xive", rtas_get_xive);
833 spapr_rtas_register("ibm,int-off", rtas_int_off);
834 spapr_rtas_register("ibm,int-on", rtas_int_on);
836 spapr_register_hypercall(H_CPPR, h_cppr);
837 spapr_register_hypercall(H_IPI, h_ipi);
838 spapr_register_hypercall(H_XIRR, h_xirr);
839 spapr_register_hypercall(H_EOI, h_eoi);
841 object_property_set_bool(OBJECT(icp->ics), true, "realized", &error);
842 if (error) {
843 error_propagate(errp, error);
844 return;
847 for (i = 0; i < icp->nr_servers; i++) {
848 object_property_set_bool(OBJECT(&icp->ss[i]), true, "realized", &error);
849 if (error) {
850 error_propagate(errp, error);
851 return;
856 static void xics_initfn(Object *obj)
858 XICSState *xics = XICS(obj);
860 xics->ics = ICS(object_new(TYPE_ICS));
861 object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
862 xics->ics->icp = xics;
865 static void xics_class_init(ObjectClass *oc, void *data)
867 DeviceClass *dc = DEVICE_CLASS(oc);
868 XICSStateClass *xsc = XICS_CLASS(oc);
870 dc->realize = xics_realize;
871 xsc->set_nr_irqs = xics_set_nr_irqs;
872 xsc->set_nr_servers = xics_set_nr_servers;
875 static const TypeInfo xics_info = {
876 .name = TYPE_XICS,
877 .parent = TYPE_XICS_COMMON,
878 .instance_size = sizeof(XICSState),
879 .class_size = sizeof(XICSStateClass),
880 .class_init = xics_class_init,
881 .instance_init = xics_initfn,
884 static void xics_register_types(void)
886 type_register_static(&xics_common_info);
887 type_register_static(&xics_info);
888 type_register_static(&ics_info);
889 type_register_static(&icp_info);
892 type_init(xics_register_types)