1*3aa597f6SCédric Le Goater /* 2*3aa597f6SCédric Le Goater * QEMU PowerPC sPAPR XIVE interrupt controller model 3*3aa597f6SCédric Le Goater * 4*3aa597f6SCédric Le Goater * Copyright (c) 2017-2018, IBM Corporation. 5*3aa597f6SCédric Le Goater * 6*3aa597f6SCédric Le Goater * This code is licensed under the GPL version 2 or later. See the 7*3aa597f6SCédric Le Goater * COPYING file in the top-level directory. 8*3aa597f6SCédric Le Goater */ 9*3aa597f6SCédric Le Goater 10*3aa597f6SCédric Le Goater #include "qemu/osdep.h" 11*3aa597f6SCédric Le Goater #include "qemu/log.h" 12*3aa597f6SCédric Le Goater #include "qapi/error.h" 13*3aa597f6SCédric Le Goater #include "qemu/error-report.h" 14*3aa597f6SCédric Le Goater #include "target/ppc/cpu.h" 15*3aa597f6SCédric Le Goater #include "sysemu/cpus.h" 16*3aa597f6SCédric Le Goater #include "monitor/monitor.h" 17*3aa597f6SCédric Le Goater #include "hw/ppc/spapr.h" 18*3aa597f6SCédric Le Goater #include "hw/ppc/spapr_xive.h" 19*3aa597f6SCédric Le Goater #include "hw/ppc/xive.h" 20*3aa597f6SCédric Le Goater #include "hw/ppc/xive_regs.h" 21*3aa597f6SCédric Le Goater 22*3aa597f6SCédric Le Goater /* 23*3aa597f6SCédric Le Goater * XIVE Virtualization Controller BAR and Thread Managment BAR that we 24*3aa597f6SCédric Le Goater * use for the ESB pages and the TIMA pages 25*3aa597f6SCédric Le Goater */ 26*3aa597f6SCédric Le Goater #define SPAPR_XIVE_VC_BASE 0x0006010000000000ull 27*3aa597f6SCédric Le Goater #define SPAPR_XIVE_TM_BASE 0x0006030203180000ull 28*3aa597f6SCédric Le Goater 29*3aa597f6SCédric Le Goater /* 30*3aa597f6SCédric Le Goater * On sPAPR machines, use a simplified output for the XIVE END 31*3aa597f6SCédric Le Goater * structure dumping only the information related to the OS EQ. 32*3aa597f6SCédric Le Goater */ 33*3aa597f6SCédric Le Goater static void spapr_xive_end_pic_print_info(sPAPRXive *xive, XiveEND *end, 34*3aa597f6SCédric Le Goater Monitor *mon) 35*3aa597f6SCédric Le Goater { 36*3aa597f6SCédric Le Goater uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1); 37*3aa597f6SCédric Le Goater uint32_t qgen = xive_get_field32(END_W1_GENERATION, end->w1); 38*3aa597f6SCédric Le Goater uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0); 39*3aa597f6SCédric Le Goater uint32_t qentries = 1 << (qsize + 10); 40*3aa597f6SCédric Le Goater uint32_t nvt = xive_get_field32(END_W6_NVT_INDEX, end->w6); 41*3aa597f6SCédric Le Goater uint8_t priority = xive_get_field32(END_W7_F0_PRIORITY, end->w7); 42*3aa597f6SCédric Le Goater 43*3aa597f6SCédric Le Goater monitor_printf(mon, "%3d/%d % 6d/%5d ^%d", nvt, 44*3aa597f6SCédric Le Goater priority, qindex, qentries, qgen); 45*3aa597f6SCédric Le Goater 46*3aa597f6SCédric Le Goater xive_end_queue_pic_print_info(end, 6, mon); 47*3aa597f6SCédric Le Goater monitor_printf(mon, "]"); 48*3aa597f6SCédric Le Goater } 49*3aa597f6SCédric Le Goater 50*3aa597f6SCédric Le Goater void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon) 51*3aa597f6SCédric Le Goater { 52*3aa597f6SCédric Le Goater XiveSource *xsrc = &xive->source; 53*3aa597f6SCédric Le Goater int i; 54*3aa597f6SCédric Le Goater 55*3aa597f6SCédric Le Goater monitor_printf(mon, " LSIN PQ EISN CPU/PRIO EQ\n"); 56*3aa597f6SCédric Le Goater 57*3aa597f6SCédric Le Goater for (i = 0; i < xive->nr_irqs; i++) { 58*3aa597f6SCédric Le Goater uint8_t pq = xive_source_esb_get(xsrc, i); 59*3aa597f6SCédric Le Goater XiveEAS *eas = &xive->eat[i]; 60*3aa597f6SCédric Le Goater 61*3aa597f6SCédric Le Goater if (!xive_eas_is_valid(eas)) { 62*3aa597f6SCédric Le Goater continue; 63*3aa597f6SCédric Le Goater } 64*3aa597f6SCédric Le Goater 65*3aa597f6SCédric Le Goater monitor_printf(mon, " %08x %s %c%c%c %s %08x ", i, 66*3aa597f6SCédric Le Goater xive_source_irq_is_lsi(xsrc, i) ? "LSI" : "MSI", 67*3aa597f6SCédric Le Goater pq & XIVE_ESB_VAL_P ? 'P' : '-', 68*3aa597f6SCédric Le Goater pq & XIVE_ESB_VAL_Q ? 'Q' : '-', 69*3aa597f6SCédric Le Goater xsrc->status[i] & XIVE_STATUS_ASSERTED ? 'A' : ' ', 70*3aa597f6SCédric Le Goater xive_eas_is_masked(eas) ? "M" : " ", 71*3aa597f6SCédric Le Goater (int) xive_get_field64(EAS_END_DATA, eas->w)); 72*3aa597f6SCédric Le Goater 73*3aa597f6SCédric Le Goater if (!xive_eas_is_masked(eas)) { 74*3aa597f6SCédric Le Goater uint32_t end_idx = xive_get_field64(EAS_END_INDEX, eas->w); 75*3aa597f6SCédric Le Goater XiveEND *end; 76*3aa597f6SCédric Le Goater 77*3aa597f6SCédric Le Goater assert(end_idx < xive->nr_ends); 78*3aa597f6SCédric Le Goater end = &xive->endt[end_idx]; 79*3aa597f6SCédric Le Goater 80*3aa597f6SCédric Le Goater if (xive_end_is_valid(end)) { 81*3aa597f6SCédric Le Goater spapr_xive_end_pic_print_info(xive, end, mon); 82*3aa597f6SCédric Le Goater } 83*3aa597f6SCédric Le Goater } 84*3aa597f6SCédric Le Goater monitor_printf(mon, "\n"); 85*3aa597f6SCédric Le Goater } 86*3aa597f6SCédric Le Goater } 87*3aa597f6SCédric Le Goater 88*3aa597f6SCédric Le Goater static void spapr_xive_map_mmio(sPAPRXive *xive) 89*3aa597f6SCédric Le Goater { 90*3aa597f6SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->vc_base); 91*3aa597f6SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->end_base); 92*3aa597f6SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base); 93*3aa597f6SCédric Le Goater } 94*3aa597f6SCédric Le Goater 95*3aa597f6SCédric Le Goater static void spapr_xive_end_reset(XiveEND *end) 96*3aa597f6SCédric Le Goater { 97*3aa597f6SCédric Le Goater memset(end, 0, sizeof(*end)); 98*3aa597f6SCédric Le Goater 99*3aa597f6SCédric Le Goater /* switch off the escalation and notification ESBs */ 100*3aa597f6SCédric Le Goater end->w1 = cpu_to_be32(END_W1_ESe_Q | END_W1_ESn_Q); 101*3aa597f6SCédric Le Goater } 102*3aa597f6SCédric Le Goater 103*3aa597f6SCédric Le Goater static void spapr_xive_reset(void *dev) 104*3aa597f6SCédric Le Goater { 105*3aa597f6SCédric Le Goater sPAPRXive *xive = SPAPR_XIVE(dev); 106*3aa597f6SCédric Le Goater int i; 107*3aa597f6SCédric Le Goater 108*3aa597f6SCédric Le Goater /* 109*3aa597f6SCédric Le Goater * The XiveSource has its own reset handler, which mask off all 110*3aa597f6SCédric Le Goater * IRQs (!P|Q) 111*3aa597f6SCédric Le Goater */ 112*3aa597f6SCédric Le Goater 113*3aa597f6SCédric Le Goater /* Mask all valid EASs in the IRQ number space. */ 114*3aa597f6SCédric Le Goater for (i = 0; i < xive->nr_irqs; i++) { 115*3aa597f6SCédric Le Goater XiveEAS *eas = &xive->eat[i]; 116*3aa597f6SCédric Le Goater if (xive_eas_is_valid(eas)) { 117*3aa597f6SCédric Le Goater eas->w = cpu_to_be64(EAS_VALID | EAS_MASKED); 118*3aa597f6SCédric Le Goater } else { 119*3aa597f6SCédric Le Goater eas->w = 0; 120*3aa597f6SCédric Le Goater } 121*3aa597f6SCédric Le Goater } 122*3aa597f6SCédric Le Goater 123*3aa597f6SCédric Le Goater /* Clear all ENDs */ 124*3aa597f6SCédric Le Goater for (i = 0; i < xive->nr_ends; i++) { 125*3aa597f6SCédric Le Goater spapr_xive_end_reset(&xive->endt[i]); 126*3aa597f6SCédric Le Goater } 127*3aa597f6SCédric Le Goater } 128*3aa597f6SCédric Le Goater 129*3aa597f6SCédric Le Goater static void spapr_xive_instance_init(Object *obj) 130*3aa597f6SCédric Le Goater { 131*3aa597f6SCédric Le Goater sPAPRXive *xive = SPAPR_XIVE(obj); 132*3aa597f6SCédric Le Goater 133*3aa597f6SCédric Le Goater object_initialize(&xive->source, sizeof(xive->source), TYPE_XIVE_SOURCE); 134*3aa597f6SCédric Le Goater object_property_add_child(obj, "source", OBJECT(&xive->source), NULL); 135*3aa597f6SCédric Le Goater 136*3aa597f6SCédric Le Goater object_initialize(&xive->end_source, sizeof(xive->end_source), 137*3aa597f6SCédric Le Goater TYPE_XIVE_END_SOURCE); 138*3aa597f6SCédric Le Goater object_property_add_child(obj, "end_source", OBJECT(&xive->end_source), 139*3aa597f6SCédric Le Goater NULL); 140*3aa597f6SCédric Le Goater } 141*3aa597f6SCédric Le Goater 142*3aa597f6SCédric Le Goater static void spapr_xive_realize(DeviceState *dev, Error **errp) 143*3aa597f6SCédric Le Goater { 144*3aa597f6SCédric Le Goater sPAPRXive *xive = SPAPR_XIVE(dev); 145*3aa597f6SCédric Le Goater XiveSource *xsrc = &xive->source; 146*3aa597f6SCédric Le Goater XiveENDSource *end_xsrc = &xive->end_source; 147*3aa597f6SCédric Le Goater Error *local_err = NULL; 148*3aa597f6SCédric Le Goater 149*3aa597f6SCédric Le Goater if (!xive->nr_irqs) { 150*3aa597f6SCédric Le Goater error_setg(errp, "Number of interrupt needs to be greater 0"); 151*3aa597f6SCédric Le Goater return; 152*3aa597f6SCédric Le Goater } 153*3aa597f6SCédric Le Goater 154*3aa597f6SCédric Le Goater if (!xive->nr_ends) { 155*3aa597f6SCédric Le Goater error_setg(errp, "Number of interrupt needs to be greater 0"); 156*3aa597f6SCédric Le Goater return; 157*3aa597f6SCédric Le Goater } 158*3aa597f6SCédric Le Goater 159*3aa597f6SCédric Le Goater /* 160*3aa597f6SCédric Le Goater * Initialize the internal sources, for IPIs and virtual devices. 161*3aa597f6SCédric Le Goater */ 162*3aa597f6SCédric Le Goater object_property_set_int(OBJECT(xsrc), xive->nr_irqs, "nr-irqs", 163*3aa597f6SCédric Le Goater &error_fatal); 164*3aa597f6SCédric Le Goater object_property_add_const_link(OBJECT(xsrc), "xive", OBJECT(xive), 165*3aa597f6SCédric Le Goater &error_fatal); 166*3aa597f6SCédric Le Goater object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err); 167*3aa597f6SCédric Le Goater if (local_err) { 168*3aa597f6SCédric Le Goater error_propagate(errp, local_err); 169*3aa597f6SCédric Le Goater return; 170*3aa597f6SCédric Le Goater } 171*3aa597f6SCédric Le Goater 172*3aa597f6SCédric Le Goater /* 173*3aa597f6SCédric Le Goater * Initialize the END ESB source 174*3aa597f6SCédric Le Goater */ 175*3aa597f6SCédric Le Goater object_property_set_int(OBJECT(end_xsrc), xive->nr_irqs, "nr-ends", 176*3aa597f6SCédric Le Goater &error_fatal); 177*3aa597f6SCédric Le Goater object_property_add_const_link(OBJECT(end_xsrc), "xive", OBJECT(xive), 178*3aa597f6SCédric Le Goater &error_fatal); 179*3aa597f6SCédric Le Goater object_property_set_bool(OBJECT(end_xsrc), true, "realized", &local_err); 180*3aa597f6SCédric Le Goater if (local_err) { 181*3aa597f6SCédric Le Goater error_propagate(errp, local_err); 182*3aa597f6SCédric Le Goater return; 183*3aa597f6SCédric Le Goater } 184*3aa597f6SCédric Le Goater 185*3aa597f6SCédric Le Goater /* Set the mapping address of the END ESB pages after the source ESBs */ 186*3aa597f6SCédric Le Goater xive->end_base = xive->vc_base + (1ull << xsrc->esb_shift) * xsrc->nr_irqs; 187*3aa597f6SCédric Le Goater 188*3aa597f6SCédric Le Goater /* 189*3aa597f6SCédric Le Goater * Allocate the routing tables 190*3aa597f6SCédric Le Goater */ 191*3aa597f6SCédric Le Goater xive->eat = g_new0(XiveEAS, xive->nr_irqs); 192*3aa597f6SCédric Le Goater xive->endt = g_new0(XiveEND, xive->nr_ends); 193*3aa597f6SCédric Le Goater 194*3aa597f6SCédric Le Goater /* TIMA initialization */ 195*3aa597f6SCédric Le Goater memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops, xive, 196*3aa597f6SCédric Le Goater "xive.tima", 4ull << TM_SHIFT); 197*3aa597f6SCédric Le Goater 198*3aa597f6SCédric Le Goater /* Define all XIVE MMIO regions on SysBus */ 199*3aa597f6SCédric Le Goater sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xsrc->esb_mmio); 200*3aa597f6SCédric Le Goater sysbus_init_mmio(SYS_BUS_DEVICE(xive), &end_xsrc->esb_mmio); 201*3aa597f6SCédric Le Goater sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio); 202*3aa597f6SCédric Le Goater 203*3aa597f6SCédric Le Goater /* Map all regions */ 204*3aa597f6SCédric Le Goater spapr_xive_map_mmio(xive); 205*3aa597f6SCédric Le Goater 206*3aa597f6SCédric Le Goater qemu_register_reset(spapr_xive_reset, dev); 207*3aa597f6SCédric Le Goater } 208*3aa597f6SCédric Le Goater 209*3aa597f6SCédric Le Goater static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk, 210*3aa597f6SCédric Le Goater uint32_t eas_idx, XiveEAS *eas) 211*3aa597f6SCédric Le Goater { 212*3aa597f6SCédric Le Goater sPAPRXive *xive = SPAPR_XIVE(xrtr); 213*3aa597f6SCédric Le Goater 214*3aa597f6SCédric Le Goater if (eas_idx >= xive->nr_irqs) { 215*3aa597f6SCédric Le Goater return -1; 216*3aa597f6SCédric Le Goater } 217*3aa597f6SCédric Le Goater 218*3aa597f6SCédric Le Goater *eas = xive->eat[eas_idx]; 219*3aa597f6SCédric Le Goater return 0; 220*3aa597f6SCédric Le Goater } 221*3aa597f6SCédric Le Goater 222*3aa597f6SCédric Le Goater static int spapr_xive_get_end(XiveRouter *xrtr, 223*3aa597f6SCédric Le Goater uint8_t end_blk, uint32_t end_idx, XiveEND *end) 224*3aa597f6SCédric Le Goater { 225*3aa597f6SCédric Le Goater sPAPRXive *xive = SPAPR_XIVE(xrtr); 226*3aa597f6SCédric Le Goater 227*3aa597f6SCédric Le Goater if (end_idx >= xive->nr_ends) { 228*3aa597f6SCédric Le Goater return -1; 229*3aa597f6SCédric Le Goater } 230*3aa597f6SCédric Le Goater 231*3aa597f6SCédric Le Goater memcpy(end, &xive->endt[end_idx], sizeof(XiveEND)); 232*3aa597f6SCédric Le Goater return 0; 233*3aa597f6SCédric Le Goater } 234*3aa597f6SCédric Le Goater 235*3aa597f6SCédric Le Goater static int spapr_xive_write_end(XiveRouter *xrtr, uint8_t end_blk, 236*3aa597f6SCédric Le Goater uint32_t end_idx, XiveEND *end, 237*3aa597f6SCédric Le Goater uint8_t word_number) 238*3aa597f6SCédric Le Goater { 239*3aa597f6SCédric Le Goater sPAPRXive *xive = SPAPR_XIVE(xrtr); 240*3aa597f6SCédric Le Goater 241*3aa597f6SCédric Le Goater if (end_idx >= xive->nr_ends) { 242*3aa597f6SCédric Le Goater return -1; 243*3aa597f6SCédric Le Goater } 244*3aa597f6SCédric Le Goater 245*3aa597f6SCédric Le Goater memcpy(&xive->endt[end_idx], end, sizeof(XiveEND)); 246*3aa597f6SCédric Le Goater return 0; 247*3aa597f6SCédric Le Goater } 248*3aa597f6SCédric Le Goater 249*3aa597f6SCédric Le Goater static const VMStateDescription vmstate_spapr_xive_end = { 250*3aa597f6SCédric Le Goater .name = TYPE_SPAPR_XIVE "/end", 251*3aa597f6SCédric Le Goater .version_id = 1, 252*3aa597f6SCédric Le Goater .minimum_version_id = 1, 253*3aa597f6SCédric Le Goater .fields = (VMStateField []) { 254*3aa597f6SCédric Le Goater VMSTATE_UINT32(w0, XiveEND), 255*3aa597f6SCédric Le Goater VMSTATE_UINT32(w1, XiveEND), 256*3aa597f6SCédric Le Goater VMSTATE_UINT32(w2, XiveEND), 257*3aa597f6SCédric Le Goater VMSTATE_UINT32(w3, XiveEND), 258*3aa597f6SCédric Le Goater VMSTATE_UINT32(w4, XiveEND), 259*3aa597f6SCédric Le Goater VMSTATE_UINT32(w5, XiveEND), 260*3aa597f6SCédric Le Goater VMSTATE_UINT32(w6, XiveEND), 261*3aa597f6SCédric Le Goater VMSTATE_UINT32(w7, XiveEND), 262*3aa597f6SCédric Le Goater VMSTATE_END_OF_LIST() 263*3aa597f6SCédric Le Goater }, 264*3aa597f6SCédric Le Goater }; 265*3aa597f6SCédric Le Goater 266*3aa597f6SCédric Le Goater static const VMStateDescription vmstate_spapr_xive_eas = { 267*3aa597f6SCédric Le Goater .name = TYPE_SPAPR_XIVE "/eas", 268*3aa597f6SCédric Le Goater .version_id = 1, 269*3aa597f6SCédric Le Goater .minimum_version_id = 1, 270*3aa597f6SCédric Le Goater .fields = (VMStateField []) { 271*3aa597f6SCédric Le Goater VMSTATE_UINT64(w, XiveEAS), 272*3aa597f6SCédric Le Goater VMSTATE_END_OF_LIST() 273*3aa597f6SCédric Le Goater }, 274*3aa597f6SCédric Le Goater }; 275*3aa597f6SCédric Le Goater 276*3aa597f6SCédric Le Goater static const VMStateDescription vmstate_spapr_xive = { 277*3aa597f6SCédric Le Goater .name = TYPE_SPAPR_XIVE, 278*3aa597f6SCédric Le Goater .version_id = 1, 279*3aa597f6SCédric Le Goater .minimum_version_id = 1, 280*3aa597f6SCédric Le Goater .fields = (VMStateField[]) { 281*3aa597f6SCédric Le Goater VMSTATE_UINT32_EQUAL(nr_irqs, sPAPRXive, NULL), 282*3aa597f6SCédric Le Goater VMSTATE_STRUCT_VARRAY_POINTER_UINT32(eat, sPAPRXive, nr_irqs, 283*3aa597f6SCédric Le Goater vmstate_spapr_xive_eas, XiveEAS), 284*3aa597f6SCédric Le Goater VMSTATE_STRUCT_VARRAY_POINTER_UINT32(endt, sPAPRXive, nr_ends, 285*3aa597f6SCédric Le Goater vmstate_spapr_xive_end, XiveEND), 286*3aa597f6SCédric Le Goater VMSTATE_END_OF_LIST() 287*3aa597f6SCédric Le Goater }, 288*3aa597f6SCédric Le Goater }; 289*3aa597f6SCédric Le Goater 290*3aa597f6SCédric Le Goater static Property spapr_xive_properties[] = { 291*3aa597f6SCédric Le Goater DEFINE_PROP_UINT32("nr-irqs", sPAPRXive, nr_irqs, 0), 292*3aa597f6SCédric Le Goater DEFINE_PROP_UINT32("nr-ends", sPAPRXive, nr_ends, 0), 293*3aa597f6SCédric Le Goater DEFINE_PROP_UINT64("vc-base", sPAPRXive, vc_base, SPAPR_XIVE_VC_BASE), 294*3aa597f6SCédric Le Goater DEFINE_PROP_UINT64("tm-base", sPAPRXive, tm_base, SPAPR_XIVE_TM_BASE), 295*3aa597f6SCédric Le Goater DEFINE_PROP_END_OF_LIST(), 296*3aa597f6SCédric Le Goater }; 297*3aa597f6SCédric Le Goater 298*3aa597f6SCédric Le Goater static void spapr_xive_class_init(ObjectClass *klass, void *data) 299*3aa597f6SCédric Le Goater { 300*3aa597f6SCédric Le Goater DeviceClass *dc = DEVICE_CLASS(klass); 301*3aa597f6SCédric Le Goater XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass); 302*3aa597f6SCédric Le Goater 303*3aa597f6SCédric Le Goater dc->desc = "sPAPR XIVE Interrupt Controller"; 304*3aa597f6SCédric Le Goater dc->props = spapr_xive_properties; 305*3aa597f6SCédric Le Goater dc->realize = spapr_xive_realize; 306*3aa597f6SCédric Le Goater dc->vmsd = &vmstate_spapr_xive; 307*3aa597f6SCédric Le Goater 308*3aa597f6SCédric Le Goater xrc->get_eas = spapr_xive_get_eas; 309*3aa597f6SCédric Le Goater xrc->get_end = spapr_xive_get_end; 310*3aa597f6SCédric Le Goater xrc->write_end = spapr_xive_write_end; 311*3aa597f6SCédric Le Goater } 312*3aa597f6SCédric Le Goater 313*3aa597f6SCédric Le Goater static const TypeInfo spapr_xive_info = { 314*3aa597f6SCédric Le Goater .name = TYPE_SPAPR_XIVE, 315*3aa597f6SCédric Le Goater .parent = TYPE_XIVE_ROUTER, 316*3aa597f6SCédric Le Goater .instance_init = spapr_xive_instance_init, 317*3aa597f6SCédric Le Goater .instance_size = sizeof(sPAPRXive), 318*3aa597f6SCédric Le Goater .class_init = spapr_xive_class_init, 319*3aa597f6SCédric Le Goater }; 320*3aa597f6SCédric Le Goater 321*3aa597f6SCédric Le Goater static void spapr_xive_register_types(void) 322*3aa597f6SCédric Le Goater { 323*3aa597f6SCédric Le Goater type_register_static(&spapr_xive_info); 324*3aa597f6SCédric Le Goater } 325*3aa597f6SCédric Le Goater 326*3aa597f6SCédric Le Goater type_init(spapr_xive_register_types) 327*3aa597f6SCédric Le Goater 328*3aa597f6SCédric Le Goater bool spapr_xive_irq_claim(sPAPRXive *xive, uint32_t lisn, bool lsi) 329*3aa597f6SCédric Le Goater { 330*3aa597f6SCédric Le Goater XiveSource *xsrc = &xive->source; 331*3aa597f6SCédric Le Goater 332*3aa597f6SCédric Le Goater if (lisn >= xive->nr_irqs) { 333*3aa597f6SCédric Le Goater return false; 334*3aa597f6SCédric Le Goater } 335*3aa597f6SCédric Le Goater 336*3aa597f6SCédric Le Goater xive->eat[lisn].w |= cpu_to_be64(EAS_VALID); 337*3aa597f6SCédric Le Goater xive_source_irq_set(xsrc, lisn, lsi); 338*3aa597f6SCédric Le Goater return true; 339*3aa597f6SCédric Le Goater } 340*3aa597f6SCédric Le Goater 341*3aa597f6SCédric Le Goater bool spapr_xive_irq_free(sPAPRXive *xive, uint32_t lisn) 342*3aa597f6SCédric Le Goater { 343*3aa597f6SCédric Le Goater XiveSource *xsrc = &xive->source; 344*3aa597f6SCédric Le Goater 345*3aa597f6SCédric Le Goater if (lisn >= xive->nr_irqs) { 346*3aa597f6SCédric Le Goater return false; 347*3aa597f6SCédric Le Goater } 348*3aa597f6SCédric Le Goater 349*3aa597f6SCédric Le Goater xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID); 350*3aa597f6SCédric Le Goater xive_source_irq_set(xsrc, lisn, false); 351*3aa597f6SCédric Le Goater return true; 352*3aa597f6SCédric Le Goater } 353*3aa597f6SCédric Le Goater 354*3aa597f6SCédric Le Goater qemu_irq spapr_xive_qirq(sPAPRXive *xive, uint32_t lisn) 355*3aa597f6SCédric Le Goater { 356*3aa597f6SCédric Le Goater XiveSource *xsrc = &xive->source; 357*3aa597f6SCédric Le Goater 358*3aa597f6SCédric Le Goater if (lisn >= xive->nr_irqs) { 359*3aa597f6SCédric Le Goater return NULL; 360*3aa597f6SCédric Le Goater } 361*3aa597f6SCédric Le Goater 362*3aa597f6SCédric Le Goater /* The sPAPR machine/device should have claimed the IRQ before */ 363*3aa597f6SCédric Le Goater assert(xive_eas_is_valid(&xive->eat[lisn])); 364*3aa597f6SCédric Le Goater 365*3aa597f6SCédric Le Goater return xive_source_qirq(xsrc, lisn); 366*3aa597f6SCédric Le Goater } 367