xref: /openbmc/qemu/hw/xtensa/mx_pic.c (revision 10df8ff1)
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