1*10df8ff1SMax Filippov /* 2*10df8ff1SMax Filippov * Copyright (c) 2013 - 2019, Max Filippov, Open Source and Linux Lab. 3*10df8ff1SMax Filippov * All rights reserved. 4*10df8ff1SMax Filippov * 5*10df8ff1SMax Filippov * Redistribution and use in source and binary forms, with or without 6*10df8ff1SMax Filippov * modification, are permitted provided that the following conditions are met: 7*10df8ff1SMax Filippov * * Redistributions of source code must retain the above copyright 8*10df8ff1SMax Filippov * notice, this list of conditions and the following disclaimer. 9*10df8ff1SMax Filippov * * Redistributions in binary form must reproduce the above copyright 10*10df8ff1SMax Filippov * notice, this list of conditions and the following disclaimer in the 11*10df8ff1SMax Filippov * documentation and/or other materials provided with the distribution. 12*10df8ff1SMax Filippov * * Neither the name of the Open Source and Linux Lab nor the 13*10df8ff1SMax Filippov * names of its contributors may be used to endorse or promote products 14*10df8ff1SMax Filippov * derived from this software without specific prior written permission. 15*10df8ff1SMax Filippov * 16*10df8ff1SMax Filippov * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17*10df8ff1SMax Filippov * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*10df8ff1SMax Filippov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*10df8ff1SMax Filippov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20*10df8ff1SMax Filippov * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21*10df8ff1SMax Filippov * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22*10df8ff1SMax Filippov * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23*10df8ff1SMax Filippov * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24*10df8ff1SMax Filippov * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25*10df8ff1SMax Filippov * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26*10df8ff1SMax Filippov */ 27*10df8ff1SMax Filippov 28*10df8ff1SMax Filippov #include "qemu/osdep.h" 29*10df8ff1SMax Filippov #include "hw/hw.h" 30*10df8ff1SMax Filippov #include "hw/xtensa/mx_pic.h" 31*10df8ff1SMax Filippov #include "qemu/log.h" 32*10df8ff1SMax Filippov 33*10df8ff1SMax Filippov #define MX_MAX_CPU 32 34*10df8ff1SMax Filippov #define MX_MAX_IRQ 32 35*10df8ff1SMax Filippov 36*10df8ff1SMax Filippov #define MIROUT 0x0 37*10df8ff1SMax Filippov #define MIPICAUSE 0x100 38*10df8ff1SMax Filippov #define MIPISET 0x140 39*10df8ff1SMax Filippov #define MIENG 0x180 40*10df8ff1SMax Filippov #define MIENGSET 0x184 41*10df8ff1SMax Filippov #define MIASG 0x188 42*10df8ff1SMax Filippov #define MIASGSET 0x18c 43*10df8ff1SMax Filippov #define MIPIPART 0x190 44*10df8ff1SMax Filippov #define SYSCFGID 0x1a0 45*10df8ff1SMax Filippov #define MPSCORE 0x200 46*10df8ff1SMax Filippov #define CCON 0x220 47*10df8ff1SMax Filippov 48*10df8ff1SMax Filippov struct XtensaMxPic { 49*10df8ff1SMax Filippov unsigned n_cpu; 50*10df8ff1SMax Filippov unsigned n_irq; 51*10df8ff1SMax Filippov 52*10df8ff1SMax Filippov uint32_t ext_irq_state; 53*10df8ff1SMax Filippov uint32_t mieng; 54*10df8ff1SMax Filippov uint32_t miasg; 55*10df8ff1SMax Filippov uint32_t mirout[MX_MAX_IRQ]; 56*10df8ff1SMax Filippov uint32_t mipipart; 57*10df8ff1SMax Filippov uint32_t runstall; 58*10df8ff1SMax Filippov 59*10df8ff1SMax Filippov qemu_irq *irq_inputs; 60*10df8ff1SMax Filippov struct XtensaMxPicCpu { 61*10df8ff1SMax Filippov XtensaMxPic *mx; 62*10df8ff1SMax Filippov qemu_irq *irq; 63*10df8ff1SMax Filippov qemu_irq runstall; 64*10df8ff1SMax Filippov uint32_t mipicause; 65*10df8ff1SMax Filippov uint32_t mirout_cache; 66*10df8ff1SMax Filippov uint32_t irq_state_cache; 67*10df8ff1SMax Filippov uint32_t ccon; 68*10df8ff1SMax Filippov MemoryRegion reg; 69*10df8ff1SMax Filippov } cpu[MX_MAX_CPU]; 70*10df8ff1SMax Filippov }; 71*10df8ff1SMax Filippov 72*10df8ff1SMax Filippov static uint64_t xtensa_mx_pic_ext_reg_read(void *opaque, hwaddr offset, 73*10df8ff1SMax Filippov unsigned size) 74*10df8ff1SMax Filippov { 75*10df8ff1SMax Filippov struct XtensaMxPicCpu *mx_cpu = opaque; 76*10df8ff1SMax Filippov struct XtensaMxPic *mx = mx_cpu->mx; 77*10df8ff1SMax Filippov 78*10df8ff1SMax Filippov if (offset < MIROUT + MX_MAX_IRQ) { 79*10df8ff1SMax Filippov return mx->mirout[offset - MIROUT]; 80*10df8ff1SMax Filippov } else if (offset >= MIPICAUSE && offset < MIPICAUSE + MX_MAX_CPU) { 81*10df8ff1SMax Filippov return mx->cpu[offset - MIPICAUSE].mipicause; 82*10df8ff1SMax Filippov } else { 83*10df8ff1SMax Filippov switch (offset) { 84*10df8ff1SMax Filippov case MIENG: 85*10df8ff1SMax Filippov return mx->mieng; 86*10df8ff1SMax Filippov 87*10df8ff1SMax Filippov case MIASG: 88*10df8ff1SMax Filippov return mx->miasg; 89*10df8ff1SMax Filippov 90*10df8ff1SMax Filippov case MIPIPART: 91*10df8ff1SMax Filippov return mx->mipipart; 92*10df8ff1SMax Filippov 93*10df8ff1SMax Filippov case SYSCFGID: 94*10df8ff1SMax Filippov return ((mx->n_cpu - 1) << 18) | (mx_cpu - mx->cpu); 95*10df8ff1SMax Filippov 96*10df8ff1SMax Filippov case MPSCORE: 97*10df8ff1SMax Filippov return mx->runstall; 98*10df8ff1SMax Filippov 99*10df8ff1SMax Filippov case CCON: 100*10df8ff1SMax Filippov return mx_cpu->ccon; 101*10df8ff1SMax Filippov 102*10df8ff1SMax Filippov default: 103*10df8ff1SMax Filippov qemu_log_mask(LOG_GUEST_ERROR, 104*10df8ff1SMax Filippov "unknown RER in MX PIC range: 0x%08x\n", 105*10df8ff1SMax Filippov (uint32_t)offset); 106*10df8ff1SMax Filippov return 0; 107*10df8ff1SMax Filippov } 108*10df8ff1SMax Filippov } 109*10df8ff1SMax Filippov } 110*10df8ff1SMax Filippov 111*10df8ff1SMax Filippov static uint32_t xtensa_mx_pic_get_ipi_for_cpu(const XtensaMxPic *mx, 112*10df8ff1SMax Filippov unsigned cpu) 113*10df8ff1SMax Filippov { 114*10df8ff1SMax Filippov uint32_t mipicause = mx->cpu[cpu].mipicause; 115*10df8ff1SMax Filippov uint32_t mipipart = mx->mipipart; 116*10df8ff1SMax Filippov 117*10df8ff1SMax Filippov return (((mipicause & 1) << (mipipart & 3)) | 118*10df8ff1SMax Filippov ((mipicause & 0x000e) != 0) << ((mipipart >> 2) & 3) | 119*10df8ff1SMax Filippov ((mipicause & 0x00f0) != 0) << ((mipipart >> 4) & 3) | 120*10df8ff1SMax Filippov ((mipicause & 0xff00) != 0) << ((mipipart >> 6) & 3)) & 0x7; 121*10df8ff1SMax Filippov } 122*10df8ff1SMax Filippov 123*10df8ff1SMax Filippov static uint32_t xtensa_mx_pic_get_ext_irq_for_cpu(const XtensaMxPic *mx, 124*10df8ff1SMax Filippov unsigned cpu) 125*10df8ff1SMax Filippov { 126*10df8ff1SMax Filippov return ((((mx->ext_irq_state & mx->mieng) | mx->miasg) & 127*10df8ff1SMax Filippov mx->cpu[cpu].mirout_cache) << 2) | 128*10df8ff1SMax Filippov xtensa_mx_pic_get_ipi_for_cpu(mx, cpu); 129*10df8ff1SMax Filippov } 130*10df8ff1SMax Filippov 131*10df8ff1SMax Filippov static void xtensa_mx_pic_update_cpu(XtensaMxPic *mx, unsigned cpu) 132*10df8ff1SMax Filippov { 133*10df8ff1SMax Filippov uint32_t irq = xtensa_mx_pic_get_ext_irq_for_cpu(mx, cpu); 134*10df8ff1SMax Filippov uint32_t changed_irq = mx->cpu[cpu].irq_state_cache ^ irq; 135*10df8ff1SMax Filippov unsigned i; 136*10df8ff1SMax Filippov 137*10df8ff1SMax Filippov qemu_log_mask(CPU_LOG_INT, "%s: CPU %d, irq: %08x, changed_irq: %08x\n", 138*10df8ff1SMax Filippov __func__, cpu, irq, changed_irq); 139*10df8ff1SMax Filippov mx->cpu[cpu].irq_state_cache = irq; 140*10df8ff1SMax Filippov for (i = 0; changed_irq; ++i) { 141*10df8ff1SMax Filippov uint32_t mask = 1u << i; 142*10df8ff1SMax Filippov 143*10df8ff1SMax Filippov if (changed_irq & mask) { 144*10df8ff1SMax Filippov changed_irq ^= mask; 145*10df8ff1SMax Filippov qemu_set_irq(mx->cpu[cpu].irq[i], irq & mask); 146*10df8ff1SMax Filippov } 147*10df8ff1SMax Filippov } 148*10df8ff1SMax Filippov } 149*10df8ff1SMax Filippov 150*10df8ff1SMax Filippov static void xtensa_mx_pic_update_all(XtensaMxPic *mx) 151*10df8ff1SMax Filippov { 152*10df8ff1SMax Filippov unsigned cpu; 153*10df8ff1SMax Filippov 154*10df8ff1SMax Filippov for (cpu = 0; cpu < mx->n_cpu; ++cpu) { 155*10df8ff1SMax Filippov xtensa_mx_pic_update_cpu(mx, cpu); 156*10df8ff1SMax Filippov } 157*10df8ff1SMax Filippov } 158*10df8ff1SMax Filippov 159*10df8ff1SMax Filippov static void xtensa_mx_pic_ext_reg_write(void *opaque, hwaddr offset, 160*10df8ff1SMax Filippov uint64_t v, unsigned size) 161*10df8ff1SMax Filippov { 162*10df8ff1SMax Filippov struct XtensaMxPicCpu *mx_cpu = opaque; 163*10df8ff1SMax Filippov struct XtensaMxPic *mx = mx_cpu->mx; 164*10df8ff1SMax Filippov unsigned cpu; 165*10df8ff1SMax Filippov 166*10df8ff1SMax Filippov if (offset < MIROUT + mx->n_irq) { 167*10df8ff1SMax Filippov mx->mirout[offset - MIROUT] = v; 168*10df8ff1SMax Filippov for (cpu = 0; cpu < mx->n_cpu; ++cpu) { 169*10df8ff1SMax Filippov uint32_t mask = 1u << (offset - MIROUT); 170*10df8ff1SMax Filippov 171*10df8ff1SMax Filippov if (!(mx->cpu[cpu].mirout_cache & mask) != !(v & (1u << cpu))) { 172*10df8ff1SMax Filippov mx->cpu[cpu].mirout_cache ^= mask; 173*10df8ff1SMax Filippov xtensa_mx_pic_update_cpu(mx, cpu); 174*10df8ff1SMax Filippov } 175*10df8ff1SMax Filippov } 176*10df8ff1SMax Filippov } else if (offset >= MIPICAUSE && offset < MIPICAUSE + mx->n_cpu) { 177*10df8ff1SMax Filippov cpu = offset - MIPICAUSE; 178*10df8ff1SMax Filippov mx->cpu[cpu].mipicause &= ~v; 179*10df8ff1SMax Filippov xtensa_mx_pic_update_cpu(mx, cpu); 180*10df8ff1SMax Filippov } else if (offset >= MIPISET && offset < MIPISET + 16) { 181*10df8ff1SMax Filippov for (cpu = 0; cpu < mx->n_cpu; ++cpu) { 182*10df8ff1SMax Filippov if (v & (1u << cpu)) { 183*10df8ff1SMax Filippov mx->cpu[cpu].mipicause |= 1u << (offset - MIPISET); 184*10df8ff1SMax Filippov xtensa_mx_pic_update_cpu(mx, cpu); 185*10df8ff1SMax Filippov } 186*10df8ff1SMax Filippov } 187*10df8ff1SMax Filippov } else { 188*10df8ff1SMax Filippov uint32_t change = 0; 189*10df8ff1SMax Filippov uint32_t oldv, newv; 190*10df8ff1SMax Filippov const char *name = "???"; 191*10df8ff1SMax Filippov 192*10df8ff1SMax Filippov switch (offset) { 193*10df8ff1SMax Filippov case MIENG: 194*10df8ff1SMax Filippov change = mx->mieng & v; 195*10df8ff1SMax Filippov oldv = mx->mieng; 196*10df8ff1SMax Filippov mx->mieng &= ~v; 197*10df8ff1SMax Filippov newv = mx->mieng; 198*10df8ff1SMax Filippov name = "MIENG"; 199*10df8ff1SMax Filippov break; 200*10df8ff1SMax Filippov 201*10df8ff1SMax Filippov case MIENGSET: 202*10df8ff1SMax Filippov change = ~mx->mieng & v; 203*10df8ff1SMax Filippov oldv = mx->mieng; 204*10df8ff1SMax Filippov mx->mieng |= v; 205*10df8ff1SMax Filippov newv = mx->mieng; 206*10df8ff1SMax Filippov name = "MIENG"; 207*10df8ff1SMax Filippov break; 208*10df8ff1SMax Filippov 209*10df8ff1SMax Filippov case MIASG: 210*10df8ff1SMax Filippov change = mx->miasg & v; 211*10df8ff1SMax Filippov oldv = mx->miasg; 212*10df8ff1SMax Filippov mx->miasg &= ~v; 213*10df8ff1SMax Filippov newv = mx->miasg; 214*10df8ff1SMax Filippov name = "MIASG"; 215*10df8ff1SMax Filippov break; 216*10df8ff1SMax Filippov 217*10df8ff1SMax Filippov case MIASGSET: 218*10df8ff1SMax Filippov change = ~mx->miasg & v; 219*10df8ff1SMax Filippov oldv = mx->miasg; 220*10df8ff1SMax Filippov mx->miasg |= v; 221*10df8ff1SMax Filippov newv = mx->miasg; 222*10df8ff1SMax Filippov name = "MIASG"; 223*10df8ff1SMax Filippov break; 224*10df8ff1SMax Filippov 225*10df8ff1SMax Filippov case MIPIPART: 226*10df8ff1SMax Filippov change = mx->mipipart ^ v; 227*10df8ff1SMax Filippov oldv = mx->mipipart; 228*10df8ff1SMax Filippov mx->mipipart = v; 229*10df8ff1SMax Filippov newv = mx->mipipart; 230*10df8ff1SMax Filippov name = "MIPIPART"; 231*10df8ff1SMax Filippov break; 232*10df8ff1SMax Filippov 233*10df8ff1SMax Filippov case MPSCORE: 234*10df8ff1SMax Filippov change = mx->runstall ^ v; 235*10df8ff1SMax Filippov oldv = mx->runstall; 236*10df8ff1SMax Filippov mx->runstall = v; 237*10df8ff1SMax Filippov newv = mx->runstall; 238*10df8ff1SMax Filippov name = "RUNSTALL"; 239*10df8ff1SMax Filippov for (cpu = 0; cpu < mx->n_cpu; ++cpu) { 240*10df8ff1SMax Filippov if (change & (1u << cpu)) { 241*10df8ff1SMax Filippov qemu_set_irq(mx->cpu[cpu].runstall, v & (1u << cpu)); 242*10df8ff1SMax Filippov } 243*10df8ff1SMax Filippov } 244*10df8ff1SMax Filippov break; 245*10df8ff1SMax Filippov 246*10df8ff1SMax Filippov case CCON: 247*10df8ff1SMax Filippov mx_cpu->ccon = v & 0x1; 248*10df8ff1SMax Filippov break; 249*10df8ff1SMax Filippov 250*10df8ff1SMax Filippov default: 251*10df8ff1SMax Filippov qemu_log_mask(LOG_GUEST_ERROR, 252*10df8ff1SMax Filippov "unknown WER in MX PIC range: 0x%08x = 0x%08x\n", 253*10df8ff1SMax Filippov (uint32_t)offset, (uint32_t)v); 254*10df8ff1SMax Filippov break; 255*10df8ff1SMax Filippov } 256*10df8ff1SMax Filippov if (change) { 257*10df8ff1SMax Filippov qemu_log_mask(CPU_LOG_INT, 258*10df8ff1SMax Filippov "%s: %s changed by CPU %d: %08x -> %08x\n", 259*10df8ff1SMax Filippov __func__, name, (int)(mx_cpu - mx->cpu), 260*10df8ff1SMax Filippov oldv, newv); 261*10df8ff1SMax Filippov xtensa_mx_pic_update_all(mx); 262*10df8ff1SMax Filippov } 263*10df8ff1SMax Filippov } 264*10df8ff1SMax Filippov } 265*10df8ff1SMax Filippov 266*10df8ff1SMax Filippov static const MemoryRegionOps xtensa_mx_pic_ops = { 267*10df8ff1SMax Filippov .read = xtensa_mx_pic_ext_reg_read, 268*10df8ff1SMax Filippov .write = xtensa_mx_pic_ext_reg_write, 269*10df8ff1SMax Filippov .endianness = DEVICE_NATIVE_ENDIAN, 270*10df8ff1SMax Filippov .valid = { 271*10df8ff1SMax Filippov .unaligned = true, 272*10df8ff1SMax Filippov }, 273*10df8ff1SMax Filippov }; 274*10df8ff1SMax Filippov 275*10df8ff1SMax Filippov MemoryRegion *xtensa_mx_pic_register_cpu(XtensaMxPic *mx, 276*10df8ff1SMax Filippov qemu_irq *irq, 277*10df8ff1SMax Filippov qemu_irq runstall) 278*10df8ff1SMax Filippov { 279*10df8ff1SMax Filippov struct XtensaMxPicCpu *mx_cpu = mx->cpu + mx->n_cpu; 280*10df8ff1SMax Filippov 281*10df8ff1SMax Filippov mx_cpu->mx = mx; 282*10df8ff1SMax Filippov mx_cpu->irq = irq; 283*10df8ff1SMax Filippov mx_cpu->runstall = runstall; 284*10df8ff1SMax Filippov 285*10df8ff1SMax Filippov memory_region_init_io(&mx_cpu->reg, NULL, &xtensa_mx_pic_ops, mx_cpu, 286*10df8ff1SMax Filippov "mx_pic", 0x280); 287*10df8ff1SMax Filippov 288*10df8ff1SMax Filippov ++mx->n_cpu; 289*10df8ff1SMax Filippov return &mx_cpu->reg; 290*10df8ff1SMax Filippov } 291*10df8ff1SMax Filippov 292*10df8ff1SMax Filippov static void xtensa_mx_pic_set_irq(void *opaque, int irq, int active) 293*10df8ff1SMax Filippov { 294*10df8ff1SMax Filippov XtensaMxPic *mx = opaque; 295*10df8ff1SMax Filippov 296*10df8ff1SMax Filippov if (irq < mx->n_irq) { 297*10df8ff1SMax Filippov uint32_t old_irq_state = mx->ext_irq_state; 298*10df8ff1SMax Filippov 299*10df8ff1SMax Filippov if (active) { 300*10df8ff1SMax Filippov mx->ext_irq_state |= 1u << irq; 301*10df8ff1SMax Filippov } else { 302*10df8ff1SMax Filippov mx->ext_irq_state &= ~(1u << irq); 303*10df8ff1SMax Filippov } 304*10df8ff1SMax Filippov if (old_irq_state != mx->ext_irq_state) { 305*10df8ff1SMax Filippov qemu_log_mask(CPU_LOG_INT, 306*10df8ff1SMax Filippov "%s: IRQ %d, active: %d, ext_irq_state: %08x -> %08x\n", 307*10df8ff1SMax Filippov __func__, irq, active, 308*10df8ff1SMax Filippov old_irq_state, mx->ext_irq_state); 309*10df8ff1SMax Filippov xtensa_mx_pic_update_all(mx); 310*10df8ff1SMax Filippov } 311*10df8ff1SMax Filippov } else { 312*10df8ff1SMax Filippov qemu_log_mask(LOG_GUEST_ERROR, "%s: IRQ %d out of range\n", 313*10df8ff1SMax Filippov __func__, irq); 314*10df8ff1SMax Filippov } 315*10df8ff1SMax Filippov } 316*10df8ff1SMax Filippov 317*10df8ff1SMax Filippov XtensaMxPic *xtensa_mx_pic_init(unsigned n_irq) 318*10df8ff1SMax Filippov { 319*10df8ff1SMax Filippov XtensaMxPic *mx = calloc(1, sizeof(XtensaMxPic)); 320*10df8ff1SMax Filippov 321*10df8ff1SMax Filippov mx->n_irq = n_irq + 1; 322*10df8ff1SMax Filippov mx->irq_inputs = qemu_allocate_irqs(xtensa_mx_pic_set_irq, mx, 323*10df8ff1SMax Filippov mx->n_irq); 324*10df8ff1SMax Filippov return mx; 325*10df8ff1SMax Filippov } 326*10df8ff1SMax Filippov 327*10df8ff1SMax Filippov void xtensa_mx_pic_reset(void *opaque) 328*10df8ff1SMax Filippov { 329*10df8ff1SMax Filippov XtensaMxPic *mx = opaque; 330*10df8ff1SMax Filippov unsigned i; 331*10df8ff1SMax Filippov 332*10df8ff1SMax Filippov mx->ext_irq_state = 0; 333*10df8ff1SMax Filippov mx->mieng = mx->n_irq < 32 ? (1u << mx->n_irq) - 1 : ~0u; 334*10df8ff1SMax Filippov mx->miasg = 0; 335*10df8ff1SMax Filippov mx->mipipart = 0; 336*10df8ff1SMax Filippov for (i = 0; i < mx->n_irq; ++i) { 337*10df8ff1SMax Filippov mx->mirout[i] = 1; 338*10df8ff1SMax Filippov } 339*10df8ff1SMax Filippov for (i = 0; i < mx->n_cpu; ++i) { 340*10df8ff1SMax Filippov mx->cpu[i].mipicause = 0; 341*10df8ff1SMax Filippov mx->cpu[i].mirout_cache = i ? 0 : mx->mieng; 342*10df8ff1SMax Filippov mx->cpu[i].irq_state_cache = 0; 343*10df8ff1SMax Filippov mx->cpu[i].ccon = 0; 344*10df8ff1SMax Filippov } 345*10df8ff1SMax Filippov mx->runstall = (1u << mx->n_cpu) - 2; 346*10df8ff1SMax Filippov for (i = 0; i < mx->n_cpu; ++i) { 347*10df8ff1SMax Filippov qemu_set_irq(mx->cpu[i].runstall, i > 0); 348*10df8ff1SMax Filippov } 349*10df8ff1SMax Filippov } 350*10df8ff1SMax Filippov 351*10df8ff1SMax Filippov qemu_irq *xtensa_mx_pic_get_extints(XtensaMxPic *mx) 352*10df8ff1SMax Filippov { 353*10df8ff1SMax Filippov return mx->irq_inputs + 1; 354*10df8ff1SMax Filippov } 355