qemu/hw/intc/xics.c
<<
>>
Prefs
   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 "trace.h"
  31#include "qemu/timer.h"
  32#include "hw/ppc/xics.h"
  33#include "hw/qdev-properties.h"
  34#include "qemu/error-report.h"
  35#include "qemu/module.h"
  36#include "qapi/visitor.h"
  37#include "migration/vmstate.h"
  38#include "monitor/monitor.h"
  39#include "hw/intc/intc.h"
  40#include "hw/irq.h"
  41#include "sysemu/kvm.h"
  42#include "sysemu/reset.h"
  43
  44void icp_pic_print_info(ICPState *icp, Monitor *mon)
  45{
  46    int cpu_index;
  47
  48    /* Skip partially initialized vCPUs. This can happen on sPAPR when vCPUs
  49     * are hot plugged or unplugged.
  50     */
  51    if (!icp) {
  52        return;
  53    }
  54
  55    cpu_index = icp->cs ? icp->cs->cpu_index : -1;
  56
  57    if (!icp->output) {
  58        return;
  59    }
  60
  61    if (kvm_irqchip_in_kernel()) {
  62        icp_synchronize_state(icp);
  63    }
  64
  65    monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
  66                   cpu_index, icp->xirr, icp->xirr_owner,
  67                   icp->pending_priority, icp->mfrr);
  68}
  69
  70void ics_pic_print_info(ICSState *ics, Monitor *mon)
  71{
  72    uint32_t i;
  73
  74    monitor_printf(mon, "ICS %4x..%4x %p\n",
  75                   ics->offset, ics->offset + ics->nr_irqs - 1, ics);
  76
  77    if (!ics->irqs) {
  78        return;
  79    }
  80
  81    if (kvm_irqchip_in_kernel()) {
  82        ics_synchronize_state(ics);
  83    }
  84
  85    for (i = 0; i < ics->nr_irqs; i++) {
  86        ICSIRQState *irq = ics->irqs + i;
  87
  88        if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
  89            continue;
  90        }
  91        monitor_printf(mon, "  %4x %s %02x %02x\n",
  92                       ics->offset + i,
  93                       (irq->flags & XICS_FLAGS_IRQ_LSI) ?
  94                       "LSI" : "MSI",
  95                       irq->priority, irq->status);
  96    }
  97}
  98
  99/*
 100 * ICP: Presentation layer
 101 */
 102
 103#define XISR_MASK  0x00ffffff
 104#define CPPR_MASK  0xff000000
 105
 106#define XISR(icp)   (((icp)->xirr) & XISR_MASK)
 107#define CPPR(icp)   (((icp)->xirr) >> 24)
 108
 109static void ics_reject(ICSState *ics, uint32_t nr);
 110static void ics_eoi(ICSState *ics, uint32_t nr);
 111
 112static void icp_check_ipi(ICPState *icp)
 113{
 114    if (XISR(icp) && (icp->pending_priority <= icp->mfrr)) {
 115        return;
 116    }
 117
 118    trace_xics_icp_check_ipi(icp->cs->cpu_index, icp->mfrr);
 119
 120    if (XISR(icp) && icp->xirr_owner) {
 121        ics_reject(icp->xirr_owner, XISR(icp));
 122    }
 123
 124    icp->xirr = (icp->xirr & ~XISR_MASK) | XICS_IPI;
 125    icp->pending_priority = icp->mfrr;
 126    icp->xirr_owner = NULL;
 127    qemu_irq_raise(icp->output);
 128}
 129
 130void icp_resend(ICPState *icp)
 131{
 132    XICSFabric *xi = icp->xics;
 133    XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi);
 134
 135    if (icp->mfrr < CPPR(icp)) {
 136        icp_check_ipi(icp);
 137    }
 138
 139    xic->ics_resend(xi);
 140}
 141
 142void icp_set_cppr(ICPState *icp, uint8_t cppr)
 143{
 144    uint8_t old_cppr;
 145    uint32_t old_xisr;
 146
 147    old_cppr = CPPR(icp);
 148    icp->xirr = (icp->xirr & ~CPPR_MASK) | (cppr << 24);
 149
 150    if (cppr < old_cppr) {
 151        if (XISR(icp) && (cppr <= icp->pending_priority)) {
 152            old_xisr = XISR(icp);
 153            icp->xirr &= ~XISR_MASK; /* Clear XISR */
 154            icp->pending_priority = 0xff;
 155            qemu_irq_lower(icp->output);
 156            if (icp->xirr_owner) {
 157                ics_reject(icp->xirr_owner, old_xisr);
 158                icp->xirr_owner = NULL;
 159            }
 160        }
 161    } else {
 162        if (!XISR(icp)) {
 163            icp_resend(icp);
 164        }
 165    }
 166}
 167
 168void icp_set_mfrr(ICPState *icp, uint8_t mfrr)
 169{
 170    icp->mfrr = mfrr;
 171    if (mfrr < CPPR(icp)) {
 172        icp_check_ipi(icp);
 173    }
 174}
 175
 176uint32_t icp_accept(ICPState *icp)
 177{
 178    uint32_t xirr = icp->xirr;
 179
 180    qemu_irq_lower(icp->output);
 181    icp->xirr = icp->pending_priority << 24;
 182    icp->pending_priority = 0xff;
 183    icp->xirr_owner = NULL;
 184
 185    trace_xics_icp_accept(xirr, icp->xirr);
 186
 187    return xirr;
 188}
 189
 190uint32_t icp_ipoll(ICPState *icp, uint32_t *mfrr)
 191{
 192    if (mfrr) {
 193        *mfrr = icp->mfrr;
 194    }
 195    return icp->xirr;
 196}
 197
 198void icp_eoi(ICPState *icp, uint32_t xirr)
 199{
 200    XICSFabric *xi = icp->xics;
 201    XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi);
 202    ICSState *ics;
 203    uint32_t irq;
 204
 205    /* Send EOI -> ICS */
 206    icp->xirr = (icp->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
 207    trace_xics_icp_eoi(icp->cs->cpu_index, xirr, icp->xirr);
 208    irq = xirr & XISR_MASK;
 209
 210    ics = xic->ics_get(xi, irq);
 211    if (ics) {
 212        ics_eoi(ics, irq);
 213    }
 214    if (!XISR(icp)) {
 215        icp_resend(icp);
 216    }
 217}
 218
 219void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
 220{
 221    ICPState *icp = xics_icp_get(ics->xics, server);
 222
 223    trace_xics_icp_irq(server, nr, priority);
 224
 225    if ((priority >= CPPR(icp))
 226        || (XISR(icp) && (icp->pending_priority <= priority))) {
 227        ics_reject(ics, nr);
 228    } else {
 229        if (XISR(icp) && icp->xirr_owner) {
 230            ics_reject(icp->xirr_owner, XISR(icp));
 231            icp->xirr_owner = NULL;
 232        }
 233        icp->xirr = (icp->xirr & ~XISR_MASK) | (nr & XISR_MASK);
 234        icp->xirr_owner = ics;
 235        icp->pending_priority = priority;
 236        trace_xics_icp_raise(icp->xirr, icp->pending_priority);
 237        qemu_irq_raise(icp->output);
 238    }
 239}
 240
 241static int icp_pre_save(void *opaque)
 242{
 243    ICPState *icp = opaque;
 244
 245    if (kvm_irqchip_in_kernel()) {
 246        icp_get_kvm_state(icp);
 247    }
 248
 249    return 0;
 250}
 251
 252static int icp_post_load(void *opaque, int version_id)
 253{
 254    ICPState *icp = opaque;
 255
 256    if (kvm_irqchip_in_kernel()) {
 257        Error *local_err = NULL;
 258        int ret;
 259
 260        ret = icp_set_kvm_state(icp, &local_err);
 261        if (ret < 0) {
 262            error_report_err(local_err);
 263            return ret;
 264        }
 265    }
 266
 267    return 0;
 268}
 269
 270static const VMStateDescription vmstate_icp_server = {
 271    .name = "icp/server",
 272    .version_id = 1,
 273    .minimum_version_id = 1,
 274    .pre_save = icp_pre_save,
 275    .post_load = icp_post_load,
 276    .fields = (VMStateField[]) {
 277        /* Sanity check */
 278        VMSTATE_UINT32(xirr, ICPState),
 279        VMSTATE_UINT8(pending_priority, ICPState),
 280        VMSTATE_UINT8(mfrr, ICPState),
 281        VMSTATE_END_OF_LIST()
 282    },
 283};
 284
 285void icp_reset(ICPState *icp)
 286{
 287    icp->xirr = 0;
 288    icp->pending_priority = 0xff;
 289    icp->mfrr = 0xff;
 290
 291    if (kvm_irqchip_in_kernel()) {
 292        Error *local_err = NULL;
 293
 294        icp_set_kvm_state(icp, &local_err);
 295        if (local_err) {
 296            error_report_err(local_err);
 297        }
 298    }
 299}
 300
 301static void icp_realize(DeviceState *dev, Error **errp)
 302{
 303    ICPState *icp = ICP(dev);
 304    CPUPPCState *env;
 305    Error *err = NULL;
 306
 307    assert(icp->xics);
 308    assert(icp->cs);
 309
 310    env = &POWERPC_CPU(icp->cs)->env;
 311    switch (PPC_INPUT(env)) {
 312    case PPC_FLAGS_INPUT_POWER7:
 313        icp->output = env->irq_inputs[POWER7_INPUT_INT];
 314        break;
 315    case PPC_FLAGS_INPUT_POWER9: /* For SPAPR xics emulation */
 316        icp->output = env->irq_inputs[POWER9_INPUT_INT];
 317        break;
 318
 319    case PPC_FLAGS_INPUT_970:
 320        icp->output = env->irq_inputs[PPC970_INPUT_INT];
 321        break;
 322
 323    default:
 324        error_setg(errp, "XICS interrupt controller does not support this CPU bus model");
 325        return;
 326    }
 327
 328    /* Connect the presenter to the VCPU (required for CPU hotplug) */
 329    if (kvm_irqchip_in_kernel()) {
 330        icp_kvm_realize(dev, &err);
 331        if (err) {
 332            error_propagate(errp, err);
 333            return;
 334        }
 335    }
 336
 337    vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp);
 338}
 339
 340static void icp_unrealize(DeviceState *dev)
 341{
 342    ICPState *icp = ICP(dev);
 343
 344    vmstate_unregister(NULL, &vmstate_icp_server, icp);
 345}
 346
 347static Property icp_properties[] = {
 348    DEFINE_PROP_LINK(ICP_PROP_XICS, ICPState, xics, TYPE_XICS_FABRIC,
 349                     XICSFabric *),
 350    DEFINE_PROP_LINK(ICP_PROP_CPU, ICPState, cs, TYPE_CPU, CPUState *),
 351    DEFINE_PROP_END_OF_LIST(),
 352};
 353
 354static void icp_class_init(ObjectClass *klass, void *data)
 355{
 356    DeviceClass *dc = DEVICE_CLASS(klass);
 357
 358    dc->realize = icp_realize;
 359    dc->unrealize = icp_unrealize;
 360    device_class_set_props(dc, icp_properties);
 361    /*
 362     * Reason: part of XICS interrupt controller, needs to be wired up
 363     * by icp_create().
 364     */
 365    dc->user_creatable = false;
 366}
 367
 368static 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
 376Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp)
 377{
 378    Object *obj;
 379
 380    obj = object_new(type);
 381    object_property_add_child(cpu, type, obj);
 382    object_unref(obj);
 383    object_property_set_link(obj, ICP_PROP_XICS, OBJECT(xi), &error_abort);
 384    object_property_set_link(obj, ICP_PROP_CPU, cpu, &error_abort);
 385    if (!qdev_realize(DEVICE(obj), NULL, errp)) {
 386        object_unparent(obj);
 387        obj = NULL;
 388    }
 389
 390    return obj;
 391}
 392
 393void icp_destroy(ICPState *icp)
 394{
 395    Object *obj = OBJECT(icp);
 396
 397    object_unparent(obj);
 398}
 399
 400/*
 401 * ICS: Source layer
 402 */
 403static void ics_resend_msi(ICSState *ics, int srcno)
 404{
 405    ICSIRQState *irq = ics->irqs + srcno;
 406
 407    /* FIXME: filter by server#? */
 408    if (irq->status & XICS_STATUS_REJECTED) {
 409        irq->status &= ~XICS_STATUS_REJECTED;
 410        if (irq->priority != 0xff) {
 411            icp_irq(ics, irq->server, srcno + ics->offset, irq->priority);
 412        }
 413    }
 414}
 415
 416static void ics_resend_lsi(ICSState *ics, int srcno)
 417{
 418    ICSIRQState *irq = ics->irqs + srcno;
 419
 420    if ((irq->priority != 0xff)
 421        && (irq->status & XICS_STATUS_ASSERTED)
 422        && !(irq->status & XICS_STATUS_SENT)) {
 423        irq->status |= XICS_STATUS_SENT;
 424        icp_irq(ics, irq->server, srcno + ics->offset, irq->priority);
 425    }
 426}
 427
 428static void ics_set_irq_msi(ICSState *ics, int srcno, int val)
 429{
 430    ICSIRQState *irq = ics->irqs + srcno;
 431
 432    trace_xics_ics_set_irq_msi(srcno, srcno + ics->offset);
 433
 434    if (val) {
 435        if (irq->priority == 0xff) {
 436            irq->status |= XICS_STATUS_MASKED_PENDING;
 437            trace_xics_masked_pending();
 438        } else  {
 439            icp_irq(ics, irq->server, srcno + ics->offset, irq->priority);
 440        }
 441    }
 442}
 443
 444static void ics_set_irq_lsi(ICSState *ics, int srcno, int val)
 445{
 446    ICSIRQState *irq = ics->irqs + srcno;
 447
 448    trace_xics_ics_set_irq_lsi(srcno, srcno + ics->offset);
 449    if (val) {
 450        irq->status |= XICS_STATUS_ASSERTED;
 451    } else {
 452        irq->status &= ~XICS_STATUS_ASSERTED;
 453    }
 454    ics_resend_lsi(ics, srcno);
 455}
 456
 457void ics_set_irq(void *opaque, int srcno, int val)
 458{
 459    ICSState *ics = (ICSState *)opaque;
 460
 461    if (kvm_irqchip_in_kernel()) {
 462        ics_kvm_set_irq(ics, srcno, val);
 463        return;
 464    }
 465
 466    if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
 467        ics_set_irq_lsi(ics, srcno, val);
 468    } else {
 469        ics_set_irq_msi(ics, srcno, val);
 470    }
 471}
 472
 473static void ics_write_xive_msi(ICSState *ics, int srcno)
 474{
 475    ICSIRQState *irq = ics->irqs + srcno;
 476
 477    if (!(irq->status & XICS_STATUS_MASKED_PENDING)
 478        || (irq->priority == 0xff)) {
 479        return;
 480    }
 481
 482    irq->status &= ~XICS_STATUS_MASKED_PENDING;
 483    icp_irq(ics, irq->server, srcno + ics->offset, irq->priority);
 484}
 485
 486static void ics_write_xive_lsi(ICSState *ics, int srcno)
 487{
 488    ics_resend_lsi(ics, srcno);
 489}
 490
 491void ics_write_xive(ICSState *ics, int srcno, int server,
 492                    uint8_t priority, uint8_t saved_priority)
 493{
 494    ICSIRQState *irq = ics->irqs + srcno;
 495
 496    irq->server = server;
 497    irq->priority = priority;
 498    irq->saved_priority = saved_priority;
 499
 500    trace_xics_ics_write_xive(ics->offset + srcno, srcno, server, priority);
 501
 502    if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
 503        ics_write_xive_lsi(ics, srcno);
 504    } else {
 505        ics_write_xive_msi(ics, srcno);
 506    }
 507}
 508
 509static void ics_reject(ICSState *ics, uint32_t nr)
 510{
 511    ICSStateClass *isc = ICS_GET_CLASS(ics);
 512    ICSIRQState *irq = ics->irqs + nr - ics->offset;
 513
 514    if (isc->reject) {
 515        isc->reject(ics, nr);
 516        return;
 517    }
 518
 519    trace_xics_ics_reject(nr, nr - ics->offset);
 520    if (irq->flags & XICS_FLAGS_IRQ_MSI) {
 521        irq->status |= XICS_STATUS_REJECTED;
 522    } else if (irq->flags & XICS_FLAGS_IRQ_LSI) {
 523        irq->status &= ~XICS_STATUS_SENT;
 524    }
 525}
 526
 527void ics_resend(ICSState *ics)
 528{
 529    ICSStateClass *isc = ICS_GET_CLASS(ics);
 530    int i;
 531
 532    if (isc->resend) {
 533        isc->resend(ics);
 534        return;
 535    }
 536
 537    for (i = 0; i < ics->nr_irqs; i++) {
 538        /* FIXME: filter by server#? */
 539        if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
 540            ics_resend_lsi(ics, i);
 541        } else {
 542            ics_resend_msi(ics, i);
 543        }
 544    }
 545}
 546
 547static void ics_eoi(ICSState *ics, uint32_t nr)
 548{
 549    int srcno = nr - ics->offset;
 550    ICSIRQState *irq = ics->irqs + srcno;
 551
 552    trace_xics_ics_eoi(nr);
 553
 554    if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
 555        irq->status &= ~XICS_STATUS_SENT;
 556    }
 557}
 558
 559static void ics_reset_irq(ICSIRQState *irq)
 560{
 561    irq->priority = 0xff;
 562    irq->saved_priority = 0xff;
 563}
 564
 565static void ics_reset(DeviceState *dev)
 566{
 567    ICSState *ics = ICS(dev);
 568    int i;
 569    uint8_t flags[ics->nr_irqs];
 570
 571    for (i = 0; i < ics->nr_irqs; i++) {
 572        flags[i] = ics->irqs[i].flags;
 573    }
 574
 575    memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
 576
 577    for (i = 0; i < ics->nr_irqs; i++) {
 578        ics_reset_irq(ics->irqs + i);
 579        ics->irqs[i].flags = flags[i];
 580    }
 581
 582    if (kvm_irqchip_in_kernel()) {
 583        Error *local_err = NULL;
 584
 585        ics_set_kvm_state(ICS(dev), &local_err);
 586        if (local_err) {
 587            error_report_err(local_err);
 588        }
 589    }
 590}
 591
 592static void ics_reset_handler(void *dev)
 593{
 594    ics_reset(dev);
 595}
 596
 597static void ics_realize(DeviceState *dev, Error **errp)
 598{
 599    ICSState *ics = ICS(dev);
 600
 601    assert(ics->xics);
 602
 603    if (!ics->nr_irqs) {
 604        error_setg(errp, "Number of interrupts needs to be greater 0");
 605        return;
 606    }
 607    ics->irqs = g_new0(ICSIRQState, ics->nr_irqs);
 608
 609    qemu_register_reset(ics_reset_handler, ics);
 610}
 611
 612static void ics_instance_init(Object *obj)
 613{
 614    ICSState *ics = ICS(obj);
 615
 616    ics->offset = XICS_IRQ_BASE;
 617}
 618
 619static int ics_pre_save(void *opaque)
 620{
 621    ICSState *ics = opaque;
 622
 623    if (kvm_irqchip_in_kernel()) {
 624        ics_get_kvm_state(ics);
 625    }
 626
 627    return 0;
 628}
 629
 630static int ics_post_load(void *opaque, int version_id)
 631{
 632    ICSState *ics = opaque;
 633
 634    if (kvm_irqchip_in_kernel()) {
 635        Error *local_err = NULL;
 636        int ret;
 637
 638        ret = ics_set_kvm_state(ics, &local_err);
 639        if (ret < 0) {
 640            error_report_err(local_err);
 641            return ret;
 642        }
 643    }
 644
 645    return 0;
 646}
 647
 648static const VMStateDescription vmstate_ics_irq = {
 649    .name = "ics/irq",
 650    .version_id = 2,
 651    .minimum_version_id = 1,
 652    .fields = (VMStateField[]) {
 653        VMSTATE_UINT32(server, ICSIRQState),
 654        VMSTATE_UINT8(priority, ICSIRQState),
 655        VMSTATE_UINT8(saved_priority, ICSIRQState),
 656        VMSTATE_UINT8(status, ICSIRQState),
 657        VMSTATE_UINT8(flags, ICSIRQState),
 658        VMSTATE_END_OF_LIST()
 659    },
 660};
 661
 662static const VMStateDescription vmstate_ics = {
 663    .name = "ics",
 664    .version_id = 1,
 665    .minimum_version_id = 1,
 666    .pre_save = ics_pre_save,
 667    .post_load = ics_post_load,
 668    .fields = (VMStateField[]) {
 669        /* Sanity check */
 670        VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL),
 671
 672        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
 673                                             vmstate_ics_irq,
 674                                             ICSIRQState),
 675        VMSTATE_END_OF_LIST()
 676    },
 677};
 678
 679static Property ics_properties[] = {
 680    DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0),
 681    DEFINE_PROP_LINK(ICS_PROP_XICS, ICSState, xics, TYPE_XICS_FABRIC,
 682                     XICSFabric *),
 683    DEFINE_PROP_END_OF_LIST(),
 684};
 685
 686static void ics_class_init(ObjectClass *klass, void *data)
 687{
 688    DeviceClass *dc = DEVICE_CLASS(klass);
 689
 690    dc->realize = ics_realize;
 691    device_class_set_props(dc, ics_properties);
 692    dc->reset = ics_reset;
 693    dc->vmsd = &vmstate_ics;
 694    /*
 695     * Reason: part of XICS interrupt controller, needs to be wired up,
 696     * e.g. by spapr_irq_init().
 697     */
 698    dc->user_creatable = false;
 699}
 700
 701static const TypeInfo ics_info = {
 702    .name = TYPE_ICS,
 703    .parent = TYPE_DEVICE,
 704    .instance_size = sizeof(ICSState),
 705    .instance_init = ics_instance_init,
 706    .class_init = ics_class_init,
 707    .class_size = sizeof(ICSStateClass),
 708};
 709
 710static const TypeInfo xics_fabric_info = {
 711    .name = TYPE_XICS_FABRIC,
 712    .parent = TYPE_INTERFACE,
 713    .class_size = sizeof(XICSFabricClass),
 714};
 715
 716/*
 717 * Exported functions
 718 */
 719ICPState *xics_icp_get(XICSFabric *xi, int server)
 720{
 721    XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi);
 722
 723    return xic->icp_get(xi, server);
 724}
 725
 726void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
 727{
 728    assert(!(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK));
 729
 730    ics->irqs[srcno].flags |=
 731        lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
 732
 733    if (kvm_irqchip_in_kernel()) {
 734        Error *local_err = NULL;
 735
 736        ics_reset_irq(ics->irqs + srcno);
 737        ics_set_kvm_state_one(ics, srcno, &local_err);
 738        if (local_err) {
 739            error_report_err(local_err);
 740        }
 741    }
 742}
 743
 744static void xics_register_types(void)
 745{
 746    type_register_static(&ics_info);
 747    type_register_static(&icp_info);
 748    type_register_static(&xics_fabric_info);
 749}
 750
 751type_init(xics_register_types)
 752