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/xics.h" 36 #include "qemu/error-report.h" 37 #include "qapi/visitor.h" 38 #include "monitor/monitor.h" 39 #include "hw/intc/intc.h" 40 41 int xics_get_cpu_index_by_dt_id(int cpu_dt_id) 42 { 43 PowerPCCPU *cpu = ppc_get_vcpu_by_dt_id(cpu_dt_id); 44 45 if (cpu) { 46 return cpu->parent_obj.cpu_index; 47 } 48 49 return -1; 50 } 51 52 void xics_cpu_destroy(XICSState *xics, PowerPCCPU *cpu) 53 { 54 CPUState *cs = CPU(cpu); 55 ICPState *ss = &xics->ss[cs->cpu_index]; 56 57 assert(cs->cpu_index < xics->nr_servers); 58 assert(cs == ss->cs); 59 60 ss->output = NULL; 61 ss->cs = NULL; 62 } 63 64 void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu) 65 { 66 CPUState *cs = CPU(cpu); 67 CPUPPCState *env = &cpu->env; 68 ICPState *ss = &xics->ss[cs->cpu_index]; 69 XICSStateClass *info = XICS_COMMON_GET_CLASS(xics); 70 71 assert(cs->cpu_index < xics->nr_servers); 72 73 ss->cs = cs; 74 75 if (info->cpu_setup) { 76 info->cpu_setup(xics, cpu); 77 } 78 79 switch (PPC_INPUT(env)) { 80 case PPC_FLAGS_INPUT_POWER7: 81 ss->output = env->irq_inputs[POWER7_INPUT_INT]; 82 break; 83 84 case PPC_FLAGS_INPUT_970: 85 ss->output = env->irq_inputs[PPC970_INPUT_INT]; 86 break; 87 88 default: 89 error_report("XICS interrupt controller does not support this CPU " 90 "bus model"); 91 abort(); 92 } 93 } 94 95 static void icp_pic_print_info(InterruptStatsProvider *obj, 96 Monitor *mon) 97 { 98 ICPState *icp = ICP(obj); 99 int cpu_index = icp->cs ? icp->cs->cpu_index : -1; 100 101 if (!icp->output) { 102 return; 103 } 104 monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n", 105 cpu_index, icp->xirr, icp->xirr_owner, 106 icp->pending_priority, icp->mfrr); 107 } 108 109 static void ics_simple_pic_print_info(InterruptStatsProvider *obj, 110 Monitor *mon) 111 { 112 ICSState *ics = ICS_SIMPLE(obj); 113 uint32_t i; 114 115 monitor_printf(mon, "ICS %4x..%4x %p\n", 116 ics->offset, ics->offset + ics->nr_irqs - 1, ics); 117 118 if (!ics->irqs) { 119 return; 120 } 121 122 for (i = 0; i < ics->nr_irqs; i++) { 123 ICSIRQState *irq = ics->irqs + i; 124 125 if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) { 126 continue; 127 } 128 monitor_printf(mon, " %4x %s %02x %02x\n", 129 ics->offset + i, 130 (irq->flags & XICS_FLAGS_IRQ_LSI) ? 131 "LSI" : "MSI", 132 irq->priority, irq->status); 133 } 134 } 135 136 /* 137 * XICS Common class - parent for emulated XICS and KVM-XICS 138 */ 139 static void xics_common_reset(DeviceState *d) 140 { 141 XICSState *xics = XICS_COMMON(d); 142 ICSState *ics; 143 int i; 144 145 for (i = 0; i < xics->nr_servers; i++) { 146 device_reset(DEVICE(&xics->ss[i])); 147 } 148 149 QLIST_FOREACH(ics, &xics->ics, list) { 150 device_reset(DEVICE(ics)); 151 } 152 } 153 154 static void xics_common_initfn(Object *obj) 155 { 156 XICSState *xics = XICS_COMMON(obj); 157 158 QLIST_INIT(&xics->ics); 159 } 160 161 static void xics_common_class_init(ObjectClass *oc, void *data) 162 { 163 DeviceClass *dc = DEVICE_CLASS(oc); 164 165 dc->reset = xics_common_reset; 166 } 167 168 static const TypeInfo xics_common_info = { 169 .name = TYPE_XICS_COMMON, 170 .parent = TYPE_DEVICE, 171 .instance_size = sizeof(XICSState), 172 .class_size = sizeof(XICSStateClass), 173 .instance_init = xics_common_initfn, 174 .class_init = xics_common_class_init, 175 }; 176 177 /* 178 * ICP: Presentation layer 179 */ 180 181 #define XISR_MASK 0x00ffffff 182 #define CPPR_MASK 0xff000000 183 184 #define XISR(ss) (((ss)->xirr) & XISR_MASK) 185 #define CPPR(ss) (((ss)->xirr) >> 24) 186 187 static void ics_reject(ICSState *ics, uint32_t nr) 188 { 189 ICSStateClass *k = ICS_BASE_GET_CLASS(ics); 190 191 if (k->reject) { 192 k->reject(ics, nr); 193 } 194 } 195 196 void ics_resend(ICSState *ics) 197 { 198 ICSStateClass *k = ICS_BASE_GET_CLASS(ics); 199 200 if (k->resend) { 201 k->resend(ics); 202 } 203 } 204 205 static void ics_eoi(ICSState *ics, int nr) 206 { 207 ICSStateClass *k = ICS_BASE_GET_CLASS(ics); 208 209 if (k->eoi) { 210 k->eoi(ics, nr); 211 } 212 } 213 214 static void icp_check_ipi(ICPState *ss) 215 { 216 if (XISR(ss) && (ss->pending_priority <= ss->mfrr)) { 217 return; 218 } 219 220 trace_xics_icp_check_ipi(ss->cs->cpu_index, ss->mfrr); 221 222 if (XISR(ss) && ss->xirr_owner) { 223 ics_reject(ss->xirr_owner, XISR(ss)); 224 } 225 226 ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI; 227 ss->pending_priority = ss->mfrr; 228 ss->xirr_owner = NULL; 229 qemu_irq_raise(ss->output); 230 } 231 232 static void icp_resend(ICPState *ss) 233 { 234 ICSState *ics; 235 236 if (ss->mfrr < CPPR(ss)) { 237 icp_check_ipi(ss); 238 } 239 QLIST_FOREACH(ics, &ss->xics->ics, list) { 240 ics_resend(ics); 241 } 242 } 243 244 void icp_set_cppr(ICPState *ss, uint8_t cppr) 245 { 246 uint8_t old_cppr; 247 uint32_t old_xisr; 248 249 old_cppr = CPPR(ss); 250 ss->xirr = (ss->xirr & ~CPPR_MASK) | (cppr << 24); 251 252 if (cppr < old_cppr) { 253 if (XISR(ss) && (cppr <= ss->pending_priority)) { 254 old_xisr = XISR(ss); 255 ss->xirr &= ~XISR_MASK; /* Clear XISR */ 256 ss->pending_priority = 0xff; 257 qemu_irq_lower(ss->output); 258 if (ss->xirr_owner) { 259 ics_reject(ss->xirr_owner, old_xisr); 260 ss->xirr_owner = NULL; 261 } 262 } 263 } else { 264 if (!XISR(ss)) { 265 icp_resend(ss); 266 } 267 } 268 } 269 270 void icp_set_mfrr(ICPState *ss, uint8_t mfrr) 271 { 272 ss->mfrr = mfrr; 273 if (mfrr < CPPR(ss)) { 274 icp_check_ipi(ss); 275 } 276 } 277 278 uint32_t icp_accept(ICPState *ss) 279 { 280 uint32_t xirr = ss->xirr; 281 282 qemu_irq_lower(ss->output); 283 ss->xirr = ss->pending_priority << 24; 284 ss->pending_priority = 0xff; 285 ss->xirr_owner = NULL; 286 287 trace_xics_icp_accept(xirr, ss->xirr); 288 289 return xirr; 290 } 291 292 uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr) 293 { 294 if (mfrr) { 295 *mfrr = ss->mfrr; 296 } 297 return ss->xirr; 298 } 299 300 void icp_eoi(ICPState *ss, uint32_t xirr) 301 { 302 ICSState *ics; 303 uint32_t irq; 304 305 /* Send EOI -> ICS */ 306 ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK); 307 trace_xics_icp_eoi(ss->cs->cpu_index, xirr, ss->xirr); 308 irq = xirr & XISR_MASK; 309 QLIST_FOREACH(ics, &ss->xics->ics, list) { 310 if (ics_valid_irq(ics, irq)) { 311 ics_eoi(ics, irq); 312 } 313 } 314 if (!XISR(ss)) { 315 icp_resend(ss); 316 } 317 } 318 319 static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority) 320 { 321 XICSState *xics = ics->xics; 322 ICPState *ss = xics->ss + server; 323 324 trace_xics_icp_irq(server, nr, priority); 325 326 if ((priority >= CPPR(ss)) 327 || (XISR(ss) && (ss->pending_priority <= priority))) { 328 ics_reject(ics, nr); 329 } else { 330 if (XISR(ss) && ss->xirr_owner) { 331 ics_reject(ss->xirr_owner, XISR(ss)); 332 ss->xirr_owner = NULL; 333 } 334 ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK); 335 ss->xirr_owner = ics; 336 ss->pending_priority = priority; 337 trace_xics_icp_raise(ss->xirr, ss->pending_priority); 338 qemu_irq_raise(ss->output); 339 } 340 } 341 342 static void icp_dispatch_pre_save(void *opaque) 343 { 344 ICPState *ss = opaque; 345 ICPStateClass *info = ICP_GET_CLASS(ss); 346 347 if (info->pre_save) { 348 info->pre_save(ss); 349 } 350 } 351 352 static int icp_dispatch_post_load(void *opaque, int version_id) 353 { 354 ICPState *ss = opaque; 355 ICPStateClass *info = ICP_GET_CLASS(ss); 356 357 if (info->post_load) { 358 return info->post_load(ss, version_id); 359 } 360 361 return 0; 362 } 363 364 static const VMStateDescription vmstate_icp_server = { 365 .name = "icp/server", 366 .version_id = 1, 367 .minimum_version_id = 1, 368 .pre_save = icp_dispatch_pre_save, 369 .post_load = icp_dispatch_post_load, 370 .fields = (VMStateField[]) { 371 /* Sanity check */ 372 VMSTATE_UINT32(xirr, ICPState), 373 VMSTATE_UINT8(pending_priority, ICPState), 374 VMSTATE_UINT8(mfrr, ICPState), 375 VMSTATE_END_OF_LIST() 376 }, 377 }; 378 379 static void icp_reset(DeviceState *dev) 380 { 381 ICPState *icp = ICP(dev); 382 383 icp->xirr = 0; 384 icp->pending_priority = 0xff; 385 icp->mfrr = 0xff; 386 387 /* Make all outputs are deasserted */ 388 qemu_set_irq(icp->output, 0); 389 } 390 391 static void icp_realize(DeviceState *dev, Error **errp) 392 { 393 ICPState *icp = ICP(dev); 394 Object *obj; 395 Error *err = NULL; 396 397 obj = object_property_get_link(OBJECT(dev), "xics", &err); 398 if (!obj) { 399 error_setg(errp, "%s: required link 'xics' not found: %s", 400 __func__, error_get_pretty(err)); 401 return; 402 } 403 404 icp->xics = XICS_COMMON(obj); 405 } 406 407 408 static void icp_class_init(ObjectClass *klass, void *data) 409 { 410 DeviceClass *dc = DEVICE_CLASS(klass); 411 InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass); 412 413 dc->reset = icp_reset; 414 dc->vmsd = &vmstate_icp_server; 415 dc->realize = icp_realize; 416 ic->print_info = icp_pic_print_info; 417 } 418 419 static const TypeInfo icp_info = { 420 .name = TYPE_ICP, 421 .parent = TYPE_DEVICE, 422 .instance_size = sizeof(ICPState), 423 .class_init = icp_class_init, 424 .class_size = sizeof(ICPStateClass), 425 .interfaces = (InterfaceInfo[]) { 426 { TYPE_INTERRUPT_STATS_PROVIDER }, 427 { } 428 }, 429 }; 430 431 /* 432 * ICS: Source layer 433 */ 434 static void ics_simple_resend_msi(ICSState *ics, int srcno) 435 { 436 ICSIRQState *irq = ics->irqs + srcno; 437 438 /* FIXME: filter by server#? */ 439 if (irq->status & XICS_STATUS_REJECTED) { 440 irq->status &= ~XICS_STATUS_REJECTED; 441 if (irq->priority != 0xff) { 442 icp_irq(ics, irq->server, srcno + ics->offset, irq->priority); 443 } 444 } 445 } 446 447 static void ics_simple_resend_lsi(ICSState *ics, int srcno) 448 { 449 ICSIRQState *irq = ics->irqs + srcno; 450 451 if ((irq->priority != 0xff) 452 && (irq->status & XICS_STATUS_ASSERTED) 453 && !(irq->status & XICS_STATUS_SENT)) { 454 irq->status |= XICS_STATUS_SENT; 455 icp_irq(ics, irq->server, srcno + ics->offset, irq->priority); 456 } 457 } 458 459 static void ics_simple_set_irq_msi(ICSState *ics, int srcno, int val) 460 { 461 ICSIRQState *irq = ics->irqs + srcno; 462 463 trace_xics_ics_simple_set_irq_msi(srcno, srcno + ics->offset); 464 465 if (val) { 466 if (irq->priority == 0xff) { 467 irq->status |= XICS_STATUS_MASKED_PENDING; 468 trace_xics_masked_pending(); 469 } else { 470 icp_irq(ics, irq->server, srcno + ics->offset, irq->priority); 471 } 472 } 473 } 474 475 static void ics_simple_set_irq_lsi(ICSState *ics, int srcno, int val) 476 { 477 ICSIRQState *irq = ics->irqs + srcno; 478 479 trace_xics_ics_simple_set_irq_lsi(srcno, srcno + ics->offset); 480 if (val) { 481 irq->status |= XICS_STATUS_ASSERTED; 482 } else { 483 irq->status &= ~XICS_STATUS_ASSERTED; 484 } 485 ics_simple_resend_lsi(ics, srcno); 486 } 487 488 static void ics_simple_set_irq(void *opaque, int srcno, int val) 489 { 490 ICSState *ics = (ICSState *)opaque; 491 492 if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) { 493 ics_simple_set_irq_lsi(ics, srcno, val); 494 } else { 495 ics_simple_set_irq_msi(ics, srcno, val); 496 } 497 } 498 499 static void ics_simple_write_xive_msi(ICSState *ics, int srcno) 500 { 501 ICSIRQState *irq = ics->irqs + srcno; 502 503 if (!(irq->status & XICS_STATUS_MASKED_PENDING) 504 || (irq->priority == 0xff)) { 505 return; 506 } 507 508 irq->status &= ~XICS_STATUS_MASKED_PENDING; 509 icp_irq(ics, irq->server, srcno + ics->offset, irq->priority); 510 } 511 512 static void ics_simple_write_xive_lsi(ICSState *ics, int srcno) 513 { 514 ics_simple_resend_lsi(ics, srcno); 515 } 516 517 void ics_simple_write_xive(ICSState *ics, int srcno, int server, 518 uint8_t priority, uint8_t saved_priority) 519 { 520 ICSIRQState *irq = ics->irqs + srcno; 521 522 irq->server = server; 523 irq->priority = priority; 524 irq->saved_priority = saved_priority; 525 526 trace_xics_ics_simple_write_xive(ics->offset + srcno, srcno, server, 527 priority); 528 529 if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) { 530 ics_simple_write_xive_lsi(ics, srcno); 531 } else { 532 ics_simple_write_xive_msi(ics, srcno); 533 } 534 } 535 536 static void ics_simple_reject(ICSState *ics, uint32_t nr) 537 { 538 ICSIRQState *irq = ics->irqs + nr - ics->offset; 539 540 trace_xics_ics_simple_reject(nr, nr - ics->offset); 541 if (irq->flags & XICS_FLAGS_IRQ_MSI) { 542 irq->status |= XICS_STATUS_REJECTED; 543 } else if (irq->flags & XICS_FLAGS_IRQ_LSI) { 544 irq->status &= ~XICS_STATUS_SENT; 545 } 546 } 547 548 static void ics_simple_resend(ICSState *ics) 549 { 550 int i; 551 552 for (i = 0; i < ics->nr_irqs; i++) { 553 /* FIXME: filter by server#? */ 554 if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) { 555 ics_simple_resend_lsi(ics, i); 556 } else { 557 ics_simple_resend_msi(ics, i); 558 } 559 } 560 } 561 562 static void ics_simple_eoi(ICSState *ics, uint32_t nr) 563 { 564 int srcno = nr - ics->offset; 565 ICSIRQState *irq = ics->irqs + srcno; 566 567 trace_xics_ics_simple_eoi(nr); 568 569 if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) { 570 irq->status &= ~XICS_STATUS_SENT; 571 } 572 } 573 574 static void ics_simple_reset(DeviceState *dev) 575 { 576 ICSState *ics = ICS_SIMPLE(dev); 577 int i; 578 uint8_t flags[ics->nr_irqs]; 579 580 for (i = 0; i < ics->nr_irqs; i++) { 581 flags[i] = ics->irqs[i].flags; 582 } 583 584 memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs); 585 586 for (i = 0; i < ics->nr_irqs; i++) { 587 ics->irqs[i].priority = 0xff; 588 ics->irqs[i].saved_priority = 0xff; 589 ics->irqs[i].flags = flags[i]; 590 } 591 } 592 593 static int ics_simple_post_load(ICSState *ics, int version_id) 594 { 595 int i; 596 597 for (i = 0; i < ics->xics->nr_servers; i++) { 598 icp_resend(&ics->xics->ss[i]); 599 } 600 601 return 0; 602 } 603 604 static void ics_simple_dispatch_pre_save(void *opaque) 605 { 606 ICSState *ics = opaque; 607 ICSStateClass *info = ICS_BASE_GET_CLASS(ics); 608 609 if (info->pre_save) { 610 info->pre_save(ics); 611 } 612 } 613 614 static int ics_simple_dispatch_post_load(void *opaque, int version_id) 615 { 616 ICSState *ics = opaque; 617 ICSStateClass *info = ICS_BASE_GET_CLASS(ics); 618 619 if (info->post_load) { 620 return info->post_load(ics, version_id); 621 } 622 623 return 0; 624 } 625 626 static const VMStateDescription vmstate_ics_simple_irq = { 627 .name = "ics/irq", 628 .version_id = 2, 629 .minimum_version_id = 1, 630 .fields = (VMStateField[]) { 631 VMSTATE_UINT32(server, ICSIRQState), 632 VMSTATE_UINT8(priority, ICSIRQState), 633 VMSTATE_UINT8(saved_priority, ICSIRQState), 634 VMSTATE_UINT8(status, ICSIRQState), 635 VMSTATE_UINT8(flags, ICSIRQState), 636 VMSTATE_END_OF_LIST() 637 }, 638 }; 639 640 static const VMStateDescription vmstate_ics_simple = { 641 .name = "ics", 642 .version_id = 1, 643 .minimum_version_id = 1, 644 .pre_save = ics_simple_dispatch_pre_save, 645 .post_load = ics_simple_dispatch_post_load, 646 .fields = (VMStateField[]) { 647 /* Sanity check */ 648 VMSTATE_UINT32_EQUAL(nr_irqs, ICSState), 649 650 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs, 651 vmstate_ics_simple_irq, 652 ICSIRQState), 653 VMSTATE_END_OF_LIST() 654 }, 655 }; 656 657 static void ics_simple_initfn(Object *obj) 658 { 659 ICSState *ics = ICS_SIMPLE(obj); 660 661 ics->offset = XICS_IRQ_BASE; 662 } 663 664 static void ics_simple_realize(DeviceState *dev, Error **errp) 665 { 666 ICSState *ics = ICS_SIMPLE(dev); 667 668 if (!ics->nr_irqs) { 669 error_setg(errp, "Number of interrupts needs to be greater 0"); 670 return; 671 } 672 ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState)); 673 ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs); 674 } 675 676 static Property ics_simple_properties[] = { 677 DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0), 678 DEFINE_PROP_END_OF_LIST(), 679 }; 680 681 static void ics_simple_class_init(ObjectClass *klass, void *data) 682 { 683 DeviceClass *dc = DEVICE_CLASS(klass); 684 ICSStateClass *isc = ICS_BASE_CLASS(klass); 685 InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass); 686 687 isc->realize = ics_simple_realize; 688 dc->props = ics_simple_properties; 689 dc->vmsd = &vmstate_ics_simple; 690 dc->reset = ics_simple_reset; 691 isc->post_load = ics_simple_post_load; 692 isc->reject = ics_simple_reject; 693 isc->resend = ics_simple_resend; 694 isc->eoi = ics_simple_eoi; 695 ic->print_info = ics_simple_pic_print_info; 696 } 697 698 static const TypeInfo ics_simple_info = { 699 .name = TYPE_ICS_SIMPLE, 700 .parent = TYPE_ICS_BASE, 701 .instance_size = sizeof(ICSState), 702 .class_init = ics_simple_class_init, 703 .class_size = sizeof(ICSStateClass), 704 .instance_init = ics_simple_initfn, 705 .interfaces = (InterfaceInfo[]) { 706 { TYPE_INTERRUPT_STATS_PROVIDER }, 707 { } 708 }, 709 }; 710 711 static void ics_base_realize(DeviceState *dev, Error **errp) 712 { 713 ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev); 714 ICSState *ics = ICS_BASE(dev); 715 Object *obj; 716 Error *err = NULL; 717 718 obj = object_property_get_link(OBJECT(dev), "xics", &err); 719 if (!obj) { 720 error_setg(errp, "%s: required link 'xics' not found: %s", 721 __func__, error_get_pretty(err)); 722 return; 723 } 724 ics->xics = XICS_COMMON(obj); 725 726 727 if (icsc->realize) { 728 icsc->realize(dev, errp); 729 } 730 } 731 732 static void ics_base_class_init(ObjectClass *klass, void *data) 733 { 734 DeviceClass *dc = DEVICE_CLASS(klass); 735 736 dc->realize = ics_base_realize; 737 } 738 739 static const TypeInfo ics_base_info = { 740 .name = TYPE_ICS_BASE, 741 .parent = TYPE_DEVICE, 742 .abstract = true, 743 .instance_size = sizeof(ICSState), 744 .class_init = ics_base_class_init, 745 .class_size = sizeof(ICSStateClass), 746 }; 747 748 static const TypeInfo xics_fabric_info = { 749 .name = TYPE_XICS_FABRIC, 750 .parent = TYPE_INTERFACE, 751 .class_size = sizeof(XICSFabricClass), 752 }; 753 754 /* 755 * Exported functions 756 */ 757 ICSState *xics_find_source(XICSState *xics, int irq) 758 { 759 ICSState *ics; 760 761 QLIST_FOREACH(ics, &xics->ics, list) { 762 if (ics_valid_irq(ics, irq)) { 763 return ics; 764 } 765 } 766 return NULL; 767 } 768 769 qemu_irq xics_get_qirq(XICSFabric *xi, int irq) 770 { 771 XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi); 772 ICSState *ics = xic->ics_get(xi, irq); 773 774 if (ics) { 775 return ics->qirqs[irq - ics->offset]; 776 } 777 778 return NULL; 779 } 780 781 void ics_set_irq_type(ICSState *ics, int srcno, bool lsi) 782 { 783 assert(!(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK)); 784 785 ics->irqs[srcno].flags |= 786 lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI; 787 } 788 789 static void xics_register_types(void) 790 { 791 type_register_static(&xics_common_info); 792 type_register_static(&ics_simple_info); 793 type_register_static(&ics_base_info); 794 type_register_static(&icp_info); 795 type_register_static(&xics_fabric_info); 796 } 797 798 type_init(xics_register_types) 799