]> Git Repo - qemu.git/blob - hw/xics.c
uhci: Use only one queue for ctrl endpoints
[qemu.git] / hw / xics.c
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 "hw.h"
29 #include "hw/spapr.h"
30 #include "hw/xics.h"
31
32 /*
33  * ICP: Presentation layer
34  */
35
36 struct icp_server_state {
37     uint32_t xirr;
38     uint8_t pending_priority;
39     uint8_t mfrr;
40     qemu_irq output;
41 };
42
43 #define XISR_MASK  0x00ffffff
44 #define CPPR_MASK  0xff000000
45
46 #define XISR(ss)   (((ss)->xirr) & XISR_MASK)
47 #define CPPR(ss)   (((ss)->xirr) >> 24)
48
49 struct ics_state;
50
51 struct icp_state {
52     long nr_servers;
53     struct icp_server_state *ss;
54     struct ics_state *ics;
55 };
56
57 static void ics_reject(struct ics_state *ics, int nr);
58 static void ics_resend(struct ics_state *ics);
59 static void ics_eoi(struct ics_state *ics, int nr);
60
61 static void icp_check_ipi(struct icp_state *icp, int server)
62 {
63     struct icp_server_state *ss = icp->ss + server;
64
65     if (XISR(ss) && (ss->pending_priority <= ss->mfrr)) {
66         return;
67     }
68
69     if (XISR(ss)) {
70         ics_reject(icp->ics, XISR(ss));
71     }
72
73     ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI;
74     ss->pending_priority = ss->mfrr;
75     qemu_irq_raise(ss->output);
76 }
77
78 static void icp_resend(struct icp_state *icp, int server)
79 {
80     struct icp_server_state *ss = icp->ss + server;
81
82     if (ss->mfrr < CPPR(ss)) {
83         icp_check_ipi(icp, server);
84     }
85     ics_resend(icp->ics);
86 }
87
88 static void icp_set_cppr(struct icp_state *icp, int server, uint8_t cppr)
89 {
90     struct icp_server_state *ss = icp->ss + server;
91     uint8_t old_cppr;
92     uint32_t old_xisr;
93
94     old_cppr = CPPR(ss);
95     ss->xirr = (ss->xirr & ~CPPR_MASK) | (cppr << 24);
96
97     if (cppr < old_cppr) {
98         if (XISR(ss) && (cppr <= ss->pending_priority)) {
99             old_xisr = XISR(ss);
100             ss->xirr &= ~XISR_MASK; /* Clear XISR */
101             qemu_irq_lower(ss->output);
102             ics_reject(icp->ics, old_xisr);
103         }
104     } else {
105         if (!XISR(ss)) {
106             icp_resend(icp, server);
107         }
108     }
109 }
110
111 static void icp_set_mfrr(struct icp_state *icp, int nr, uint8_t mfrr)
112 {
113     struct icp_server_state *ss = icp->ss + nr;
114
115     ss->mfrr = mfrr;
116     if (mfrr < CPPR(ss)) {
117         icp_check_ipi(icp, nr);
118     }
119 }
120
121 static uint32_t icp_accept(struct icp_server_state *ss)
122 {
123     uint32_t xirr;
124
125     qemu_irq_lower(ss->output);
126     xirr = ss->xirr;
127     ss->xirr = ss->pending_priority << 24;
128     return xirr;
129 }
130
131 static void icp_eoi(struct icp_state *icp, int server, uint32_t xirr)
132 {
133     struct icp_server_state *ss = icp->ss + server;
134
135     /* Send EOI -> ICS */
136     ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
137     ics_eoi(icp->ics, xirr & XISR_MASK);
138     if (!XISR(ss)) {
139         icp_resend(icp, server);
140     }
141 }
142
143 static void icp_irq(struct icp_state *icp, int server, int nr, uint8_t priority)
144 {
145     struct icp_server_state *ss = icp->ss + server;
146
147     if ((priority >= CPPR(ss))
148         || (XISR(ss) && (ss->pending_priority <= priority))) {
149         ics_reject(icp->ics, nr);
150     } else {
151         if (XISR(ss)) {
152             ics_reject(icp->ics, XISR(ss));
153         }
154         ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK);
155         ss->pending_priority = priority;
156         qemu_irq_raise(ss->output);
157     }
158 }
159
160 /*
161  * ICS: Source layer
162  */
163
164 struct ics_irq_state {
165     int server;
166     uint8_t priority;
167     uint8_t saved_priority;
168 #define XICS_STATUS_ASSERTED           0x1
169 #define XICS_STATUS_SENT               0x2
170 #define XICS_STATUS_REJECTED           0x4
171 #define XICS_STATUS_MASKED_PENDING     0x8
172     uint8_t status;
173     bool lsi;
174 };
175
176 struct ics_state {
177     int nr_irqs;
178     int offset;
179     qemu_irq *qirqs;
180     struct ics_irq_state *irqs;
181     struct icp_state *icp;
182 };
183
184 static int ics_valid_irq(struct ics_state *ics, uint32_t nr)
185 {
186     return (nr >= ics->offset)
187         && (nr < (ics->offset + ics->nr_irqs));
188 }
189
190 static void resend_msi(struct ics_state *ics, int srcno)
191 {
192     struct ics_irq_state *irq = ics->irqs + srcno;
193
194     /* FIXME: filter by server#? */
195     if (irq->status & XICS_STATUS_REJECTED) {
196         irq->status &= ~XICS_STATUS_REJECTED;
197         if (irq->priority != 0xff) {
198             icp_irq(ics->icp, irq->server, srcno + ics->offset,
199                     irq->priority);
200         }
201     }
202 }
203
204 static void resend_lsi(struct ics_state *ics, int srcno)
205 {
206     struct ics_irq_state *irq = ics->irqs + srcno;
207
208     if ((irq->priority != 0xff)
209         && (irq->status & XICS_STATUS_ASSERTED)
210         && !(irq->status & XICS_STATUS_SENT)) {
211         irq->status |= XICS_STATUS_SENT;
212         icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
213     }
214 }
215
216 static void set_irq_msi(struct ics_state *ics, int srcno, int val)
217 {
218     struct ics_irq_state *irq = ics->irqs + srcno;
219
220     if (val) {
221         if (irq->priority == 0xff) {
222             irq->status |= XICS_STATUS_MASKED_PENDING;
223             /* masked pending */ ;
224         } else  {
225             icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
226         }
227     }
228 }
229
230 static void set_irq_lsi(struct ics_state *ics, int srcno, int val)
231 {
232     struct ics_irq_state *irq = ics->irqs + srcno;
233
234     if (val) {
235         irq->status |= XICS_STATUS_ASSERTED;
236     } else {
237         irq->status &= ~XICS_STATUS_ASSERTED;
238     }
239     resend_lsi(ics, srcno);
240 }
241
242 static void ics_set_irq(void *opaque, int srcno, int val)
243 {
244     struct ics_state *ics = (struct ics_state *)opaque;
245     struct ics_irq_state *irq = ics->irqs + srcno;
246
247     if (irq->lsi) {
248         set_irq_lsi(ics, srcno, val);
249     } else {
250         set_irq_msi(ics, srcno, val);
251     }
252 }
253
254 static void write_xive_msi(struct ics_state *ics, int srcno)
255 {
256     struct ics_irq_state *irq = ics->irqs + srcno;
257
258     if (!(irq->status & XICS_STATUS_MASKED_PENDING)
259         || (irq->priority == 0xff)) {
260         return;
261     }
262
263     irq->status &= ~XICS_STATUS_MASKED_PENDING;
264     icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
265 }
266
267 static void write_xive_lsi(struct ics_state *ics, int srcno)
268 {
269     resend_lsi(ics, srcno);
270 }
271
272 static void ics_write_xive(struct ics_state *ics, int nr, int server,
273                            uint8_t priority, uint8_t saved_priority)
274 {
275     int srcno = nr - ics->offset;
276     struct ics_irq_state *irq = ics->irqs + srcno;
277
278     irq->server = server;
279     irq->priority = priority;
280     irq->saved_priority = saved_priority;
281
282     if (irq->lsi) {
283         write_xive_lsi(ics, srcno);
284     } else {
285         write_xive_msi(ics, srcno);
286     }
287 }
288
289 static void ics_reject(struct ics_state *ics, int nr)
290 {
291     struct ics_irq_state *irq = ics->irqs + nr - ics->offset;
292
293     irq->status |= XICS_STATUS_REJECTED; /* Irrelevant but harmless for LSI */
294     irq->status &= ~XICS_STATUS_SENT; /* Irrelevant but harmless for MSI */
295 }
296
297 static void ics_resend(struct ics_state *ics)
298 {
299     int i;
300
301     for (i = 0; i < ics->nr_irqs; i++) {
302         struct ics_irq_state *irq = ics->irqs + i;
303
304         /* FIXME: filter by server#? */
305         if (irq->lsi) {
306             resend_lsi(ics, i);
307         } else {
308             resend_msi(ics, i);
309         }
310     }
311 }
312
313 static void ics_eoi(struct ics_state *ics, int nr)
314 {
315     int srcno = nr - ics->offset;
316     struct ics_irq_state *irq = ics->irqs + srcno;
317
318     if (irq->lsi) {
319         irq->status &= ~XICS_STATUS_SENT;
320     }
321 }
322
323 /*
324  * Exported functions
325  */
326
327 qemu_irq xics_get_qirq(struct icp_state *icp, int irq)
328 {
329     if ((irq < icp->ics->offset)
330         || (irq >= (icp->ics->offset + icp->ics->nr_irqs))) {
331         return NULL;
332     }
333
334     return icp->ics->qirqs[irq - icp->ics->offset];
335 }
336
337 void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi)
338 {
339     assert((irq >= icp->ics->offset)
340            && (irq < (icp->ics->offset + icp->ics->nr_irqs)));
341
342     icp->ics->irqs[irq - icp->ics->offset].lsi = lsi;
343 }
344
345 static target_ulong h_cppr(CPUPPCState *env, sPAPREnvironment *spapr,
346                            target_ulong opcode, target_ulong *args)
347 {
348     target_ulong cppr = args[0];
349
350     icp_set_cppr(spapr->icp, env->cpu_index, cppr);
351     return H_SUCCESS;
352 }
353
354 static target_ulong h_ipi(CPUPPCState *env, sPAPREnvironment *spapr,
355                           target_ulong opcode, target_ulong *args)
356 {
357     target_ulong server = args[0];
358     target_ulong mfrr = args[1];
359
360     if (server >= spapr->icp->nr_servers) {
361         return H_PARAMETER;
362     }
363
364     icp_set_mfrr(spapr->icp, server, mfrr);
365     return H_SUCCESS;
366
367 }
368
369 static target_ulong h_xirr(CPUPPCState *env, sPAPREnvironment *spapr,
370                            target_ulong opcode, target_ulong *args)
371 {
372     uint32_t xirr = icp_accept(spapr->icp->ss + env->cpu_index);
373
374     args[0] = xirr;
375     return H_SUCCESS;
376 }
377
378 static target_ulong h_eoi(CPUPPCState *env, sPAPREnvironment *spapr,
379                           target_ulong opcode, target_ulong *args)
380 {
381     target_ulong xirr = args[0];
382
383     icp_eoi(spapr->icp, env->cpu_index, xirr);
384     return H_SUCCESS;
385 }
386
387 static void rtas_set_xive(sPAPREnvironment *spapr, uint32_t token,
388                           uint32_t nargs, target_ulong args,
389                           uint32_t nret, target_ulong rets)
390 {
391     struct ics_state *ics = spapr->icp->ics;
392     uint32_t nr, server, priority;
393
394     if ((nargs != 3) || (nret != 1)) {
395         rtas_st(rets, 0, -3);
396         return;
397     }
398
399     nr = rtas_ld(args, 0);
400     server = rtas_ld(args, 1);
401     priority = rtas_ld(args, 2);
402
403     if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
404         || (priority > 0xff)) {
405         rtas_st(rets, 0, -3);
406         return;
407     }
408
409     ics_write_xive(ics, nr, server, priority, priority);
410
411     rtas_st(rets, 0, 0); /* Success */
412 }
413
414 static void rtas_get_xive(sPAPREnvironment *spapr, uint32_t token,
415                           uint32_t nargs, target_ulong args,
416                           uint32_t nret, target_ulong rets)
417 {
418     struct ics_state *ics = spapr->icp->ics;
419     uint32_t nr;
420
421     if ((nargs != 1) || (nret != 3)) {
422         rtas_st(rets, 0, -3);
423         return;
424     }
425
426     nr = rtas_ld(args, 0);
427
428     if (!ics_valid_irq(ics, nr)) {
429         rtas_st(rets, 0, -3);
430         return;
431     }
432
433     rtas_st(rets, 0, 0); /* Success */
434     rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
435     rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
436 }
437
438 static void rtas_int_off(sPAPREnvironment *spapr, uint32_t token,
439                          uint32_t nargs, target_ulong args,
440                          uint32_t nret, target_ulong rets)
441 {
442     struct ics_state *ics = spapr->icp->ics;
443     uint32_t nr;
444
445     if ((nargs != 1) || (nret != 1)) {
446         rtas_st(rets, 0, -3);
447         return;
448     }
449
450     nr = rtas_ld(args, 0);
451
452     if (!ics_valid_irq(ics, nr)) {
453         rtas_st(rets, 0, -3);
454         return;
455     }
456
457     ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
458                    ics->irqs[nr - ics->offset].priority);
459
460     rtas_st(rets, 0, 0); /* Success */
461 }
462
463 static void rtas_int_on(sPAPREnvironment *spapr, uint32_t token,
464                         uint32_t nargs, target_ulong args,
465                         uint32_t nret, target_ulong rets)
466 {
467     struct ics_state *ics = spapr->icp->ics;
468     uint32_t nr;
469
470     if ((nargs != 1) || (nret != 1)) {
471         rtas_st(rets, 0, -3);
472         return;
473     }
474
475     nr = rtas_ld(args, 0);
476
477     if (!ics_valid_irq(ics, nr)) {
478         rtas_st(rets, 0, -3);
479         return;
480     }
481
482     ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
483                    ics->irqs[nr - ics->offset].saved_priority,
484                    ics->irqs[nr - ics->offset].saved_priority);
485
486     rtas_st(rets, 0, 0); /* Success */
487 }
488
489 static void xics_reset(void *opaque)
490 {
491     struct icp_state *icp = (struct icp_state *)opaque;
492     struct ics_state *ics = icp->ics;
493     int i;
494
495     for (i = 0; i < icp->nr_servers; i++) {
496         icp->ss[i].xirr = 0;
497         icp->ss[i].pending_priority = 0;
498         icp->ss[i].mfrr = 0xff;
499         /* Make all outputs are deasserted */
500         qemu_set_irq(icp->ss[i].output, 0);
501     }
502
503     for (i = 0; i < ics->nr_irqs; i++) {
504         /* Reset everything *except* the type */
505         ics->irqs[i].server = 0;
506         ics->irqs[i].status = 0;
507         ics->irqs[i].priority = 0xff;
508         ics->irqs[i].saved_priority = 0xff;
509     }
510 }
511
512 struct icp_state *xics_system_init(int nr_irqs)
513 {
514     CPUPPCState *env;
515     int max_server_num;
516     struct icp_state *icp;
517     struct ics_state *ics;
518
519     max_server_num = -1;
520     for (env = first_cpu; env != NULL; env = env->next_cpu) {
521         if (env->cpu_index > max_server_num) {
522             max_server_num = env->cpu_index;
523         }
524     }
525
526     icp = g_malloc0(sizeof(*icp));
527     icp->nr_servers = max_server_num + 1;
528     icp->ss = g_malloc0(icp->nr_servers*sizeof(struct icp_server_state));
529
530     for (env = first_cpu; env != NULL; env = env->next_cpu) {
531         struct icp_server_state *ss = &icp->ss[env->cpu_index];
532
533         switch (PPC_INPUT(env)) {
534         case PPC_FLAGS_INPUT_POWER7:
535             ss->output = env->irq_inputs[POWER7_INPUT_INT];
536             break;
537
538         case PPC_FLAGS_INPUT_970:
539             ss->output = env->irq_inputs[PPC970_INPUT_INT];
540             break;
541
542         default:
543             hw_error("XICS interrupt model does not support this CPU bus "
544                      "model\n");
545             exit(1);
546         }
547     }
548
549     ics = g_malloc0(sizeof(*ics));
550     ics->nr_irqs = nr_irqs;
551     ics->offset = 16;
552     ics->irqs = g_malloc0(nr_irqs * sizeof(struct ics_irq_state));
553
554     icp->ics = ics;
555     ics->icp = icp;
556
557     ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, nr_irqs);
558
559     spapr_register_hypercall(H_CPPR, h_cppr);
560     spapr_register_hypercall(H_IPI, h_ipi);
561     spapr_register_hypercall(H_XIRR, h_xirr);
562     spapr_register_hypercall(H_EOI, h_eoi);
563
564     spapr_rtas_register("ibm,set-xive", rtas_set_xive);
565     spapr_rtas_register("ibm,get-xive", rtas_get_xive);
566     spapr_rtas_register("ibm,int-off", rtas_int_off);
567     spapr_rtas_register("ibm,int-on", rtas_int_on);
568
569     qemu_register_reset(xics_reset, icp);
570
571     return icp;
572 }
This page took 0.056558 seconds and 4 git commands to generate.