xref: /openbmc/qemu/hw/intc/xics.c (revision 63785678)
1 /*
2  * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
3  *
4  * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
5  *
6  * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
7  *
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:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
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.
25  *
26  */
27 
28 #include "qemu/osdep.h"
29 #include "qapi/error.h"
30 #include "qemu-common.h"
31 #include "cpu.h"
32 #include "hw/hw.h"
33 #include "trace.h"
34 #include "qemu/timer.h"
35 #include "hw/ppc/spapr.h"
36 #include "hw/ppc/xics.h"
37 #include "qemu/error-report.h"
38 #include "qapi/visitor.h"
39 
40 static int get_cpu_index_by_dt_id(int cpu_dt_id)
41 {
42     PowerPCCPU *cpu = ppc_get_vcpu_by_dt_id(cpu_dt_id);
43 
44     if (cpu) {
45         return cpu->parent_obj.cpu_index;
46     }
47 
48     return -1;
49 }
50 
51 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
52 {
53     CPUState *cs = CPU(cpu);
54     CPUPPCState *env = &cpu->env;
55     ICPState *ss = &icp->ss[cs->cpu_index];
56     XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
57 
58     assert(cs->cpu_index < icp->nr_servers);
59 
60     if (info->cpu_setup) {
61         info->cpu_setup(icp, cpu);
62     }
63 
64     switch (PPC_INPUT(env)) {
65     case PPC_FLAGS_INPUT_POWER7:
66         ss->output = env->irq_inputs[POWER7_INPUT_INT];
67         break;
68 
69     case PPC_FLAGS_INPUT_970:
70         ss->output = env->irq_inputs[PPC970_INPUT_INT];
71         break;
72 
73     default:
74         error_report("XICS interrupt controller does not support this CPU "
75                      "bus model");
76         abort();
77     }
78 }
79 
80 /*
81  * XICS Common class - parent for emulated XICS and KVM-XICS
82  */
83 static void xics_common_reset(DeviceState *d)
84 {
85     XICSState *icp = XICS_COMMON(d);
86     int i;
87 
88     for (i = 0; i < icp->nr_servers; i++) {
89         device_reset(DEVICE(&icp->ss[i]));
90     }
91 
92     device_reset(DEVICE(icp->ics));
93 }
94 
95 static void xics_prop_get_nr_irqs(Object *obj, Visitor *v, const char *name,
96                                   void *opaque, Error **errp)
97 {
98     XICSState *icp = XICS_COMMON(obj);
99     int64_t value = icp->nr_irqs;
100 
101     visit_type_int(v, name, &value, errp);
102 }
103 
104 static void xics_prop_set_nr_irqs(Object *obj, Visitor *v, const char *name,
105                                   void *opaque, Error **errp)
106 {
107     XICSState *icp = XICS_COMMON(obj);
108     XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
109     Error *error = NULL;
110     int64_t value;
111 
112     visit_type_int(v, name, &value, &error);
113     if (error) {
114         error_propagate(errp, error);
115         return;
116     }
117     if (icp->nr_irqs) {
118         error_setg(errp, "Number of interrupts is already set to %u",
119                    icp->nr_irqs);
120         return;
121     }
122 
123     assert(info->set_nr_irqs);
124     assert(icp->ics);
125     info->set_nr_irqs(icp, value, errp);
126 }
127 
128 static void xics_prop_get_nr_servers(Object *obj, Visitor *v,
129                                      const char *name, void *opaque,
130                                      Error **errp)
131 {
132     XICSState *icp = XICS_COMMON(obj);
133     int64_t value = icp->nr_servers;
134 
135     visit_type_int(v, name, &value, errp);
136 }
137 
138 static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
139                                      const char *name, void *opaque,
140                                      Error **errp)
141 {
142     XICSState *icp = XICS_COMMON(obj);
143     XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
144     Error *error = NULL;
145     int64_t value;
146 
147     visit_type_int(v, name, &value, &error);
148     if (error) {
149         error_propagate(errp, error);
150         return;
151     }
152     if (icp->nr_servers) {
153         error_setg(errp, "Number of servers is already set to %u",
154                    icp->nr_servers);
155         return;
156     }
157 
158     assert(info->set_nr_servers);
159     info->set_nr_servers(icp, value, errp);
160 }
161 
162 static void xics_common_initfn(Object *obj)
163 {
164     object_property_add(obj, "nr_irqs", "int",
165                         xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
166                         NULL, NULL, NULL);
167     object_property_add(obj, "nr_servers", "int",
168                         xics_prop_get_nr_servers, xics_prop_set_nr_servers,
169                         NULL, NULL, NULL);
170 }
171 
172 static void xics_common_class_init(ObjectClass *oc, void *data)
173 {
174     DeviceClass *dc = DEVICE_CLASS(oc);
175 
176     dc->reset = xics_common_reset;
177 }
178 
179 static const TypeInfo xics_common_info = {
180     .name          = TYPE_XICS_COMMON,
181     .parent        = TYPE_SYS_BUS_DEVICE,
182     .instance_size = sizeof(XICSState),
183     .class_size    = sizeof(XICSStateClass),
184     .instance_init = xics_common_initfn,
185     .class_init    = xics_common_class_init,
186 };
187 
188 /*
189  * ICP: Presentation layer
190  */
191 
192 #define XISR_MASK  0x00ffffff
193 #define CPPR_MASK  0xff000000
194 
195 #define XISR(ss)   (((ss)->xirr) & XISR_MASK)
196 #define CPPR(ss)   (((ss)->xirr) >> 24)
197 
198 static void ics_reject(ICSState *ics, int nr);
199 static void ics_resend(ICSState *ics);
200 static void ics_eoi(ICSState *ics, int nr);
201 
202 static void icp_check_ipi(XICSState *icp, int server)
203 {
204     ICPState *ss = icp->ss + server;
205 
206     if (XISR(ss) && (ss->pending_priority <= ss->mfrr)) {
207         return;
208     }
209 
210     trace_xics_icp_check_ipi(server, ss->mfrr);
211 
212     if (XISR(ss)) {
213         ics_reject(icp->ics, XISR(ss));
214     }
215 
216     ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI;
217     ss->pending_priority = ss->mfrr;
218     qemu_irq_raise(ss->output);
219 }
220 
221 static void icp_resend(XICSState *icp, int server)
222 {
223     ICPState *ss = icp->ss + server;
224 
225     if (ss->mfrr < CPPR(ss)) {
226         icp_check_ipi(icp, server);
227     }
228     ics_resend(icp->ics);
229 }
230 
231 static void icp_set_cppr(XICSState *icp, int server, uint8_t cppr)
232 {
233     ICPState *ss = icp->ss + server;
234     uint8_t old_cppr;
235     uint32_t old_xisr;
236 
237     old_cppr = CPPR(ss);
238     ss->xirr = (ss->xirr & ~CPPR_MASK) | (cppr << 24);
239 
240     if (cppr < old_cppr) {
241         if (XISR(ss) && (cppr <= ss->pending_priority)) {
242             old_xisr = XISR(ss);
243             ss->xirr &= ~XISR_MASK; /* Clear XISR */
244             ss->pending_priority = 0xff;
245             qemu_irq_lower(ss->output);
246             ics_reject(icp->ics, old_xisr);
247         }
248     } else {
249         if (!XISR(ss)) {
250             icp_resend(icp, server);
251         }
252     }
253 }
254 
255 static void icp_set_mfrr(XICSState *icp, int server, uint8_t mfrr)
256 {
257     ICPState *ss = icp->ss + server;
258 
259     ss->mfrr = mfrr;
260     if (mfrr < CPPR(ss)) {
261         icp_check_ipi(icp, server);
262     }
263 }
264 
265 static uint32_t icp_accept(ICPState *ss)
266 {
267     uint32_t xirr = ss->xirr;
268 
269     qemu_irq_lower(ss->output);
270     ss->xirr = ss->pending_priority << 24;
271     ss->pending_priority = 0xff;
272 
273     trace_xics_icp_accept(xirr, ss->xirr);
274 
275     return xirr;
276 }
277 
278 static void icp_eoi(XICSState *icp, int server, uint32_t xirr)
279 {
280     ICPState *ss = icp->ss + server;
281 
282     /* Send EOI -> ICS */
283     ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
284     trace_xics_icp_eoi(server, xirr, ss->xirr);
285     ics_eoi(icp->ics, xirr & XISR_MASK);
286     if (!XISR(ss)) {
287         icp_resend(icp, server);
288     }
289 }
290 
291 static void icp_irq(XICSState *icp, int server, int nr, uint8_t priority)
292 {
293     ICPState *ss = icp->ss + server;
294 
295     trace_xics_icp_irq(server, nr, priority);
296 
297     if ((priority >= CPPR(ss))
298         || (XISR(ss) && (ss->pending_priority <= priority))) {
299         ics_reject(icp->ics, nr);
300     } else {
301         if (XISR(ss)) {
302             ics_reject(icp->ics, XISR(ss));
303         }
304         ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK);
305         ss->pending_priority = priority;
306         trace_xics_icp_raise(ss->xirr, ss->pending_priority);
307         qemu_irq_raise(ss->output);
308     }
309 }
310 
311 static void icp_dispatch_pre_save(void *opaque)
312 {
313     ICPState *ss = opaque;
314     ICPStateClass *info = ICP_GET_CLASS(ss);
315 
316     if (info->pre_save) {
317         info->pre_save(ss);
318     }
319 }
320 
321 static int icp_dispatch_post_load(void *opaque, int version_id)
322 {
323     ICPState *ss = opaque;
324     ICPStateClass *info = ICP_GET_CLASS(ss);
325 
326     if (info->post_load) {
327         return info->post_load(ss, version_id);
328     }
329 
330     return 0;
331 }
332 
333 static const VMStateDescription vmstate_icp_server = {
334     .name = "icp/server",
335     .version_id = 1,
336     .minimum_version_id = 1,
337     .pre_save = icp_dispatch_pre_save,
338     .post_load = icp_dispatch_post_load,
339     .fields = (VMStateField[]) {
340         /* Sanity check */
341         VMSTATE_UINT32(xirr, ICPState),
342         VMSTATE_UINT8(pending_priority, ICPState),
343         VMSTATE_UINT8(mfrr, ICPState),
344         VMSTATE_END_OF_LIST()
345     },
346 };
347 
348 static void icp_reset(DeviceState *dev)
349 {
350     ICPState *icp = ICP(dev);
351 
352     icp->xirr = 0;
353     icp->pending_priority = 0xff;
354     icp->mfrr = 0xff;
355 
356     /* Make all outputs are deasserted */
357     qemu_set_irq(icp->output, 0);
358 }
359 
360 static void icp_class_init(ObjectClass *klass, void *data)
361 {
362     DeviceClass *dc = DEVICE_CLASS(klass);
363 
364     dc->reset = icp_reset;
365     dc->vmsd = &vmstate_icp_server;
366 }
367 
368 static const TypeInfo icp_info = {
369     .name = TYPE_ICP,
370     .parent = TYPE_DEVICE,
371     .instance_size = sizeof(ICPState),
372     .class_init = icp_class_init,
373     .class_size = sizeof(ICPStateClass),
374 };
375 
376 /*
377  * ICS: Source layer
378  */
379 static int ics_valid_irq(ICSState *ics, uint32_t nr)
380 {
381     return (nr >= ics->offset)
382         && (nr < (ics->offset + ics->nr_irqs));
383 }
384 
385 static void resend_msi(ICSState *ics, int srcno)
386 {
387     ICSIRQState *irq = ics->irqs + srcno;
388 
389     /* FIXME: filter by server#? */
390     if (irq->status & XICS_STATUS_REJECTED) {
391         irq->status &= ~XICS_STATUS_REJECTED;
392         if (irq->priority != 0xff) {
393             icp_irq(ics->icp, irq->server, srcno + ics->offset,
394                     irq->priority);
395         }
396     }
397 }
398 
399 static void resend_lsi(ICSState *ics, int srcno)
400 {
401     ICSIRQState *irq = ics->irqs + srcno;
402 
403     if ((irq->priority != 0xff)
404         && (irq->status & XICS_STATUS_ASSERTED)
405         && !(irq->status & XICS_STATUS_SENT)) {
406         irq->status |= XICS_STATUS_SENT;
407         icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
408     }
409 }
410 
411 static void set_irq_msi(ICSState *ics, int srcno, int val)
412 {
413     ICSIRQState *irq = ics->irqs + srcno;
414 
415     trace_xics_set_irq_msi(srcno, srcno + ics->offset);
416 
417     if (val) {
418         if (irq->priority == 0xff) {
419             irq->status |= XICS_STATUS_MASKED_PENDING;
420             trace_xics_masked_pending();
421         } else  {
422             icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
423         }
424     }
425 }
426 
427 static void set_irq_lsi(ICSState *ics, int srcno, int val)
428 {
429     ICSIRQState *irq = ics->irqs + srcno;
430 
431     trace_xics_set_irq_lsi(srcno, srcno + ics->offset);
432     if (val) {
433         irq->status |= XICS_STATUS_ASSERTED;
434     } else {
435         irq->status &= ~XICS_STATUS_ASSERTED;
436     }
437     resend_lsi(ics, srcno);
438 }
439 
440 static void ics_set_irq(void *opaque, int srcno, int val)
441 {
442     ICSState *ics = (ICSState *)opaque;
443 
444     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
445         set_irq_lsi(ics, srcno, val);
446     } else {
447         set_irq_msi(ics, srcno, val);
448     }
449 }
450 
451 static void write_xive_msi(ICSState *ics, int srcno)
452 {
453     ICSIRQState *irq = ics->irqs + srcno;
454 
455     if (!(irq->status & XICS_STATUS_MASKED_PENDING)
456         || (irq->priority == 0xff)) {
457         return;
458     }
459 
460     irq->status &= ~XICS_STATUS_MASKED_PENDING;
461     icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
462 }
463 
464 static void write_xive_lsi(ICSState *ics, int srcno)
465 {
466     resend_lsi(ics, srcno);
467 }
468 
469 static void ics_write_xive(ICSState *ics, int nr, int server,
470                            uint8_t priority, uint8_t saved_priority)
471 {
472     int srcno = nr - ics->offset;
473     ICSIRQState *irq = ics->irqs + srcno;
474 
475     irq->server = server;
476     irq->priority = priority;
477     irq->saved_priority = saved_priority;
478 
479     trace_xics_ics_write_xive(nr, srcno, server, priority);
480 
481     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
482         write_xive_lsi(ics, srcno);
483     } else {
484         write_xive_msi(ics, srcno);
485     }
486 }
487 
488 static void ics_reject(ICSState *ics, int nr)
489 {
490     ICSIRQState *irq = ics->irqs + nr - ics->offset;
491 
492     trace_xics_ics_reject(nr, nr - ics->offset);
493     irq->status |= XICS_STATUS_REJECTED; /* Irrelevant but harmless for LSI */
494     irq->status &= ~XICS_STATUS_SENT; /* Irrelevant but harmless for MSI */
495 }
496 
497 static void ics_resend(ICSState *ics)
498 {
499     int i;
500 
501     for (i = 0; i < ics->nr_irqs; i++) {
502         /* FIXME: filter by server#? */
503         if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
504             resend_lsi(ics, i);
505         } else {
506             resend_msi(ics, i);
507         }
508     }
509 }
510 
511 static void ics_eoi(ICSState *ics, int nr)
512 {
513     int srcno = nr - ics->offset;
514     ICSIRQState *irq = ics->irqs + srcno;
515 
516     trace_xics_ics_eoi(nr);
517 
518     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
519         irq->status &= ~XICS_STATUS_SENT;
520     }
521 }
522 
523 static void ics_reset(DeviceState *dev)
524 {
525     ICSState *ics = ICS(dev);
526     int i;
527     uint8_t flags[ics->nr_irqs];
528 
529     for (i = 0; i < ics->nr_irqs; i++) {
530         flags[i] = ics->irqs[i].flags;
531     }
532 
533     memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
534 
535     for (i = 0; i < ics->nr_irqs; i++) {
536         ics->irqs[i].priority = 0xff;
537         ics->irqs[i].saved_priority = 0xff;
538         ics->irqs[i].flags = flags[i];
539     }
540 }
541 
542 static int ics_post_load(ICSState *ics, int version_id)
543 {
544     int i;
545 
546     for (i = 0; i < ics->icp->nr_servers; i++) {
547         icp_resend(ics->icp, i);
548     }
549 
550     return 0;
551 }
552 
553 static void ics_dispatch_pre_save(void *opaque)
554 {
555     ICSState *ics = opaque;
556     ICSStateClass *info = ICS_GET_CLASS(ics);
557 
558     if (info->pre_save) {
559         info->pre_save(ics);
560     }
561 }
562 
563 static int ics_dispatch_post_load(void *opaque, int version_id)
564 {
565     ICSState *ics = opaque;
566     ICSStateClass *info = ICS_GET_CLASS(ics);
567 
568     if (info->post_load) {
569         return info->post_load(ics, version_id);
570     }
571 
572     return 0;
573 }
574 
575 static const VMStateDescription vmstate_ics_irq = {
576     .name = "ics/irq",
577     .version_id = 2,
578     .minimum_version_id = 1,
579     .fields = (VMStateField[]) {
580         VMSTATE_UINT32(server, ICSIRQState),
581         VMSTATE_UINT8(priority, ICSIRQState),
582         VMSTATE_UINT8(saved_priority, ICSIRQState),
583         VMSTATE_UINT8(status, ICSIRQState),
584         VMSTATE_UINT8(flags, ICSIRQState),
585         VMSTATE_END_OF_LIST()
586     },
587 };
588 
589 static const VMStateDescription vmstate_ics = {
590     .name = "ics",
591     .version_id = 1,
592     .minimum_version_id = 1,
593     .pre_save = ics_dispatch_pre_save,
594     .post_load = ics_dispatch_post_load,
595     .fields = (VMStateField[]) {
596         /* Sanity check */
597         VMSTATE_UINT32_EQUAL(nr_irqs, ICSState),
598 
599         VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
600                                              vmstate_ics_irq, ICSIRQState),
601         VMSTATE_END_OF_LIST()
602     },
603 };
604 
605 static void ics_initfn(Object *obj)
606 {
607     ICSState *ics = ICS(obj);
608 
609     ics->offset = XICS_IRQ_BASE;
610 }
611 
612 static void ics_realize(DeviceState *dev, Error **errp)
613 {
614     ICSState *ics = ICS(dev);
615 
616     if (!ics->nr_irqs) {
617         error_setg(errp, "Number of interrupts needs to be greater 0");
618         return;
619     }
620     ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
621     ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);
622 }
623 
624 static void ics_class_init(ObjectClass *klass, void *data)
625 {
626     DeviceClass *dc = DEVICE_CLASS(klass);
627     ICSStateClass *isc = ICS_CLASS(klass);
628 
629     dc->realize = ics_realize;
630     dc->vmsd = &vmstate_ics;
631     dc->reset = ics_reset;
632     isc->post_load = ics_post_load;
633 }
634 
635 static const TypeInfo ics_info = {
636     .name = TYPE_ICS,
637     .parent = TYPE_DEVICE,
638     .instance_size = sizeof(ICSState),
639     .class_init = ics_class_init,
640     .class_size = sizeof(ICSStateClass),
641     .instance_init = ics_initfn,
642 };
643 
644 /*
645  * Exported functions
646  */
647 static int xics_find_source(XICSState *icp, int irq)
648 {
649     int sources = 1;
650     int src;
651 
652     /* FIXME: implement multiple sources */
653     for (src = 0; src < sources; ++src) {
654         ICSState *ics = &icp->ics[src];
655         if (ics_valid_irq(ics, irq)) {
656             return src;
657         }
658     }
659 
660     return -1;
661 }
662 
663 qemu_irq xics_get_qirq(XICSState *icp, int irq)
664 {
665     int src = xics_find_source(icp, irq);
666 
667     if (src >= 0) {
668         ICSState *ics = &icp->ics[src];
669         return ics->qirqs[irq - ics->offset];
670     }
671 
672     return NULL;
673 }
674 
675 static void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
676 {
677     assert(!(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK));
678 
679     ics->irqs[srcno].flags |=
680         lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
681 }
682 
683 void xics_set_irq_type(XICSState *icp, int irq, bool lsi)
684 {
685     int src = xics_find_source(icp, irq);
686     ICSState *ics;
687 
688     assert(src >= 0);
689 
690     ics = &icp->ics[src];
691     ics_set_irq_type(ics, irq - ics->offset, lsi);
692 }
693 
694 #define ICS_IRQ_FREE(ics, srcno)   \
695     (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
696 
697 static int ics_find_free_block(ICSState *ics, int num, int alignnum)
698 {
699     int first, i;
700 
701     for (first = 0; first < ics->nr_irqs; first += alignnum) {
702         if (num > (ics->nr_irqs - first)) {
703             return -1;
704         }
705         for (i = first; i < first + num; ++i) {
706             if (!ICS_IRQ_FREE(ics, i)) {
707                 break;
708             }
709         }
710         if (i == (first + num)) {
711             return first;
712         }
713     }
714 
715     return -1;
716 }
717 
718 int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp)
719 {
720     ICSState *ics = &icp->ics[src];
721     int irq;
722 
723     if (irq_hint) {
724         assert(src == xics_find_source(icp, irq_hint));
725         if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
726             error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
727             return -1;
728         }
729         irq = irq_hint;
730     } else {
731         irq = ics_find_free_block(ics, 1, 1);
732         if (irq < 0) {
733             error_setg(errp, "can't allocate IRQ: no IRQ left");
734             return -1;
735         }
736         irq += ics->offset;
737     }
738 
739     ics_set_irq_type(ics, irq - ics->offset, lsi);
740     trace_xics_alloc(src, irq);
741 
742     return irq;
743 }
744 
745 /*
746  * Allocate block of consecutive IRQs, and return the number of the first IRQ in the block.
747  * If align==true, aligns the first IRQ number to num.
748  */
749 int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align,
750                      Error **errp)
751 {
752     int i, first = -1;
753     ICSState *ics = &icp->ics[src];
754 
755     assert(src == 0);
756     /*
757      * MSIMesage::data is used for storing VIRQ so
758      * it has to be aligned to num to support multiple
759      * MSI vectors. MSI-X is not affected by this.
760      * The hint is used for the first IRQ, the rest should
761      * be allocated continuously.
762      */
763     if (align) {
764         assert((num == 1) || (num == 2) || (num == 4) ||
765                (num == 8) || (num == 16) || (num == 32));
766         first = ics_find_free_block(ics, num, num);
767     } else {
768         first = ics_find_free_block(ics, num, 1);
769     }
770     if (first < 0) {
771         error_setg(errp, "can't find a free %d-IRQ block", num);
772         return -1;
773     }
774 
775     if (first >= 0) {
776         for (i = first; i < first + num; ++i) {
777             ics_set_irq_type(ics, i, lsi);
778         }
779     }
780     first += ics->offset;
781 
782     trace_xics_alloc_block(src, first, num, lsi, align);
783 
784     return first;
785 }
786 
787 static void ics_free(ICSState *ics, int srcno, int num)
788 {
789     int i;
790 
791     for (i = srcno; i < srcno + num; ++i) {
792         if (ICS_IRQ_FREE(ics, i)) {
793             trace_xics_ics_free_warn(ics - ics->icp->ics, i + ics->offset);
794         }
795         memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
796     }
797 }
798 
799 void xics_free(XICSState *icp, int irq, int num)
800 {
801     int src = xics_find_source(icp, irq);
802 
803     if (src >= 0) {
804         ICSState *ics = &icp->ics[src];
805 
806         /* FIXME: implement multiple sources */
807         assert(src == 0);
808 
809         trace_xics_ics_free(ics - icp->ics, irq, num);
810         ics_free(ics, irq - ics->offset, num);
811     }
812 }
813 
814 /*
815  * Guest interfaces
816  */
817 
818 static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
819                            target_ulong opcode, target_ulong *args)
820 {
821     CPUState *cs = CPU(cpu);
822     target_ulong cppr = args[0];
823 
824     icp_set_cppr(spapr->icp, cs->cpu_index, cppr);
825     return H_SUCCESS;
826 }
827 
828 static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
829                           target_ulong opcode, target_ulong *args)
830 {
831     target_ulong server = get_cpu_index_by_dt_id(args[0]);
832     target_ulong mfrr = args[1];
833 
834     if (server >= spapr->icp->nr_servers) {
835         return H_PARAMETER;
836     }
837 
838     icp_set_mfrr(spapr->icp, server, mfrr);
839     return H_SUCCESS;
840 }
841 
842 static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
843                            target_ulong opcode, target_ulong *args)
844 {
845     CPUState *cs = CPU(cpu);
846     uint32_t xirr = icp_accept(spapr->icp->ss + cs->cpu_index);
847 
848     args[0] = xirr;
849     return H_SUCCESS;
850 }
851 
852 static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
853                              target_ulong opcode, target_ulong *args)
854 {
855     CPUState *cs = CPU(cpu);
856     ICPState *ss = &spapr->icp->ss[cs->cpu_index];
857     uint32_t xirr = icp_accept(ss);
858 
859     args[0] = xirr;
860     args[1] = cpu_get_host_ticks();
861     return H_SUCCESS;
862 }
863 
864 static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
865                           target_ulong opcode, target_ulong *args)
866 {
867     CPUState *cs = CPU(cpu);
868     target_ulong xirr = args[0];
869 
870     icp_eoi(spapr->icp, cs->cpu_index, xirr);
871     return H_SUCCESS;
872 }
873 
874 static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
875                             target_ulong opcode, target_ulong *args)
876 {
877     CPUState *cs = CPU(cpu);
878     ICPState *ss = &spapr->icp->ss[cs->cpu_index];
879 
880     args[0] = ss->xirr;
881     args[1] = ss->mfrr;
882 
883     return H_SUCCESS;
884 }
885 
886 static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
887                           uint32_t token,
888                           uint32_t nargs, target_ulong args,
889                           uint32_t nret, target_ulong rets)
890 {
891     ICSState *ics = spapr->icp->ics;
892     uint32_t nr, server, priority;
893 
894     if ((nargs != 3) || (nret != 1)) {
895         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
896         return;
897     }
898 
899     nr = rtas_ld(args, 0);
900     server = get_cpu_index_by_dt_id(rtas_ld(args, 1));
901     priority = rtas_ld(args, 2);
902 
903     if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
904         || (priority > 0xff)) {
905         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
906         return;
907     }
908 
909     ics_write_xive(ics, nr, server, priority, priority);
910 
911     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
912 }
913 
914 static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
915                           uint32_t token,
916                           uint32_t nargs, target_ulong args,
917                           uint32_t nret, target_ulong rets)
918 {
919     ICSState *ics = spapr->icp->ics;
920     uint32_t nr;
921 
922     if ((nargs != 1) || (nret != 3)) {
923         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
924         return;
925     }
926 
927     nr = rtas_ld(args, 0);
928 
929     if (!ics_valid_irq(ics, nr)) {
930         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
931         return;
932     }
933 
934     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
935     rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
936     rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
937 }
938 
939 static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
940                          uint32_t token,
941                          uint32_t nargs, target_ulong args,
942                          uint32_t nret, target_ulong rets)
943 {
944     ICSState *ics = spapr->icp->ics;
945     uint32_t nr;
946 
947     if ((nargs != 1) || (nret != 1)) {
948         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
949         return;
950     }
951 
952     nr = rtas_ld(args, 0);
953 
954     if (!ics_valid_irq(ics, nr)) {
955         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
956         return;
957     }
958 
959     ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
960                    ics->irqs[nr - ics->offset].priority);
961 
962     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
963 }
964 
965 static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
966                         uint32_t token,
967                         uint32_t nargs, target_ulong args,
968                         uint32_t nret, target_ulong rets)
969 {
970     ICSState *ics = spapr->icp->ics;
971     uint32_t nr;
972 
973     if ((nargs != 1) || (nret != 1)) {
974         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
975         return;
976     }
977 
978     nr = rtas_ld(args, 0);
979 
980     if (!ics_valid_irq(ics, nr)) {
981         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
982         return;
983     }
984 
985     ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
986                    ics->irqs[nr - ics->offset].saved_priority,
987                    ics->irqs[nr - ics->offset].saved_priority);
988 
989     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
990 }
991 
992 /*
993  * XICS
994  */
995 
996 static void xics_set_nr_irqs(XICSState *icp, uint32_t nr_irqs, Error **errp)
997 {
998     icp->nr_irqs = icp->ics->nr_irqs = nr_irqs;
999 }
1000 
1001 static void xics_set_nr_servers(XICSState *icp, uint32_t nr_servers,
1002                                 Error **errp)
1003 {
1004     int i;
1005 
1006     icp->nr_servers = nr_servers;
1007 
1008     icp->ss = g_malloc0(icp->nr_servers*sizeof(ICPState));
1009     for (i = 0; i < icp->nr_servers; i++) {
1010         char buffer[32];
1011         object_initialize(&icp->ss[i], sizeof(icp->ss[i]), TYPE_ICP);
1012         snprintf(buffer, sizeof(buffer), "icp[%d]", i);
1013         object_property_add_child(OBJECT(icp), buffer, OBJECT(&icp->ss[i]),
1014                                   errp);
1015     }
1016 }
1017 
1018 static void xics_realize(DeviceState *dev, Error **errp)
1019 {
1020     XICSState *icp = XICS(dev);
1021     Error *error = NULL;
1022     int i;
1023 
1024     if (!icp->nr_servers) {
1025         error_setg(errp, "Number of servers needs to be greater 0");
1026         return;
1027     }
1028 
1029     /* Registration of global state belongs into realize */
1030     spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
1031     spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
1032     spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
1033     spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_int_on);
1034 
1035     spapr_register_hypercall(H_CPPR, h_cppr);
1036     spapr_register_hypercall(H_IPI, h_ipi);
1037     spapr_register_hypercall(H_XIRR, h_xirr);
1038     spapr_register_hypercall(H_XIRR_X, h_xirr_x);
1039     spapr_register_hypercall(H_EOI, h_eoi);
1040     spapr_register_hypercall(H_IPOLL, h_ipoll);
1041 
1042     object_property_set_bool(OBJECT(icp->ics), true, "realized", &error);
1043     if (error) {
1044         error_propagate(errp, error);
1045         return;
1046     }
1047 
1048     for (i = 0; i < icp->nr_servers; i++) {
1049         object_property_set_bool(OBJECT(&icp->ss[i]), true, "realized", &error);
1050         if (error) {
1051             error_propagate(errp, error);
1052             return;
1053         }
1054     }
1055 }
1056 
1057 static void xics_initfn(Object *obj)
1058 {
1059     XICSState *xics = XICS(obj);
1060 
1061     xics->ics = ICS(object_new(TYPE_ICS));
1062     object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
1063     xics->ics->icp = xics;
1064 }
1065 
1066 static void xics_class_init(ObjectClass *oc, void *data)
1067 {
1068     DeviceClass *dc = DEVICE_CLASS(oc);
1069     XICSStateClass *xsc = XICS_CLASS(oc);
1070 
1071     dc->realize = xics_realize;
1072     xsc->set_nr_irqs = xics_set_nr_irqs;
1073     xsc->set_nr_servers = xics_set_nr_servers;
1074 }
1075 
1076 static const TypeInfo xics_info = {
1077     .name          = TYPE_XICS,
1078     .parent        = TYPE_XICS_COMMON,
1079     .instance_size = sizeof(XICSState),
1080     .class_size = sizeof(XICSStateClass),
1081     .class_init    = xics_class_init,
1082     .instance_init = xics_initfn,
1083 };
1084 
1085 static void xics_register_types(void)
1086 {
1087     type_register_static(&xics_common_info);
1088     type_register_static(&xics_info);
1089     type_register_static(&ics_info);
1090     type_register_static(&icp_info);
1091 }
1092 
1093 type_init(xics_register_types)
1094