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