xref: /qemu/hw/intc/riscv_aplic.c (revision 513823e7521a09ed7ad1e32e6454bac3b2cbf52d)
1 /*
2  * RISC-V APLIC (Advanced Platform Level Interrupt Controller)
3  *
4  * Copyright (c) 2021 Western Digital Corporation or its affiliates.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2 or later, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "qemu/osdep.h"
20 #include "qapi/error.h"
21 #include "qemu/log.h"
22 #include "qemu/module.h"
23 #include "qemu/error-report.h"
24 #include "qemu/bswap.h"
25 #include "exec/address-spaces.h"
26 #include "hw/sysbus.h"
27 #include "hw/pci/msi.h"
28 #include "hw/boards.h"
29 #include "hw/qdev-properties.h"
30 #include "hw/intc/riscv_aplic.h"
31 #include "hw/irq.h"
32 #include "target/riscv/cpu.h"
33 #include "system/system.h"
34 #include "system/kvm.h"
35 #include "system/tcg.h"
36 #include "kvm/kvm_riscv.h"
37 #include "migration/vmstate.h"
38 
39 #define APLIC_MAX_IDC                  (1UL << 14)
40 #define APLIC_MAX_SOURCE               1024
41 #define APLIC_MIN_IPRIO_BITS           1
42 #define APLIC_MAX_IPRIO_BITS           8
43 #define APLIC_MAX_CHILDREN             1024
44 
45 #define APLIC_DOMAINCFG                0x0000
46 #define APLIC_DOMAINCFG_RDONLY         0x80000000
47 #define APLIC_DOMAINCFG_IE             (1 << 8)
48 #define APLIC_DOMAINCFG_DM             (1 << 2)
49 #define APLIC_DOMAINCFG_BE             (1 << 0)
50 
51 #define APLIC_SOURCECFG_BASE           0x0004
52 #define APLIC_SOURCECFG_D              (1 << 10)
53 #define APLIC_SOURCECFG_CHILDIDX_MASK  0x000003ff
54 #define APLIC_SOURCECFG_SM_MASK        0x00000007
55 #define APLIC_SOURCECFG_SM_INACTIVE    0x0
56 #define APLIC_SOURCECFG_SM_DETACH      0x1
57 #define APLIC_SOURCECFG_SM_EDGE_RISE   0x4
58 #define APLIC_SOURCECFG_SM_EDGE_FALL   0x5
59 #define APLIC_SOURCECFG_SM_LEVEL_HIGH  0x6
60 #define APLIC_SOURCECFG_SM_LEVEL_LOW   0x7
61 
62 #define APLIC_MMSICFGADDR              0x1bc0
63 #define APLIC_MMSICFGADDRH             0x1bc4
64 #define APLIC_SMSICFGADDR              0x1bc8
65 #define APLIC_SMSICFGADDRH             0x1bcc
66 
67 #define APLIC_xMSICFGADDRH_L           (1UL << 31)
68 #define APLIC_xMSICFGADDRH_HHXS_MASK   0x1f
69 #define APLIC_xMSICFGADDRH_HHXS_SHIFT  24
70 #define APLIC_xMSICFGADDRH_LHXS_MASK   0x7
71 #define APLIC_xMSICFGADDRH_LHXS_SHIFT  20
72 #define APLIC_xMSICFGADDRH_HHXW_MASK   0x7
73 #define APLIC_xMSICFGADDRH_HHXW_SHIFT  16
74 #define APLIC_xMSICFGADDRH_LHXW_MASK   0xf
75 #define APLIC_xMSICFGADDRH_LHXW_SHIFT  12
76 #define APLIC_xMSICFGADDRH_BAPPN_MASK  0xfff
77 
78 #define APLIC_xMSICFGADDR_PPN_SHIFT    12
79 
80 #define APLIC_xMSICFGADDR_PPN_HART(__lhxs) \
81     ((1UL << (__lhxs)) - 1)
82 
83 #define APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) \
84     ((1UL << (__lhxw)) - 1)
85 #define APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs) \
86     ((__lhxs))
87 #define APLIC_xMSICFGADDR_PPN_LHX(__lhxw, __lhxs) \
88     (APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) << \
89      APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs))
90 
91 #define APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) \
92     ((1UL << (__hhxw)) - 1)
93 #define APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs) \
94     ((__hhxs) + APLIC_xMSICFGADDR_PPN_SHIFT)
95 #define APLIC_xMSICFGADDR_PPN_HHX(__hhxw, __hhxs) \
96     (APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) << \
97      APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs))
98 
99 #define APLIC_xMSICFGADDRH_VALID_MASK   \
100     (APLIC_xMSICFGADDRH_L | \
101      (APLIC_xMSICFGADDRH_HHXS_MASK << APLIC_xMSICFGADDRH_HHXS_SHIFT) | \
102      (APLIC_xMSICFGADDRH_LHXS_MASK << APLIC_xMSICFGADDRH_LHXS_SHIFT) | \
103      (APLIC_xMSICFGADDRH_HHXW_MASK << APLIC_xMSICFGADDRH_HHXW_SHIFT) | \
104      (APLIC_xMSICFGADDRH_LHXW_MASK << APLIC_xMSICFGADDRH_LHXW_SHIFT) | \
105      APLIC_xMSICFGADDRH_BAPPN_MASK)
106 
107 #define APLIC_SETIP_BASE               0x1c00
108 #define APLIC_SETIPNUM                 0x1cdc
109 
110 #define APLIC_CLRIP_BASE               0x1d00
111 #define APLIC_CLRIPNUM                 0x1ddc
112 
113 #define APLIC_SETIE_BASE               0x1e00
114 #define APLIC_SETIENUM                 0x1edc
115 
116 #define APLIC_CLRIE_BASE               0x1f00
117 #define APLIC_CLRIENUM                 0x1fdc
118 
119 #define APLIC_SETIPNUM_LE              0x2000
120 #define APLIC_SETIPNUM_BE              0x2004
121 
122 #define APLIC_ISTATE_PENDING           (1U << 0)
123 #define APLIC_ISTATE_ENABLED           (1U << 1)
124 #define APLIC_ISTATE_ENPEND            (APLIC_ISTATE_ENABLED | \
125                                         APLIC_ISTATE_PENDING)
126 #define APLIC_ISTATE_INPUT             (1U << 8)
127 
128 #define APLIC_GENMSI                   0x3000
129 
130 #define APLIC_TARGET_BASE              0x3004
131 #define APLIC_TARGET_HART_IDX_SHIFT    18
132 #define APLIC_TARGET_HART_IDX_MASK     0x3fff
133 #define APLIC_TARGET_GUEST_IDX_SHIFT   12
134 #define APLIC_TARGET_GUEST_IDX_MASK    0x3f
135 #define APLIC_TARGET_IPRIO_MASK        0xff
136 #define APLIC_TARGET_EIID_MASK         0x7ff
137 
138 #define APLIC_IDC_BASE                 0x4000
139 #define APLIC_IDC_SIZE                 32
140 
141 #define APLIC_IDC_IDELIVERY            0x00
142 
143 #define APLIC_IDC_IFORCE               0x04
144 
145 #define APLIC_IDC_ITHRESHOLD           0x08
146 
147 #define APLIC_IDC_TOPI                 0x18
148 #define APLIC_IDC_TOPI_ID_SHIFT        16
149 #define APLIC_IDC_TOPI_ID_MASK         0x3ff
150 #define APLIC_IDC_TOPI_PRIO_MASK       0xff
151 
152 #define APLIC_IDC_CLAIMI               0x1c
153 
154 /*
155  * KVM AIA only supports APLIC MSI, fallback to QEMU emulation if we want to use
156  * APLIC Wired.
157  */
158 bool riscv_is_kvm_aia_aplic_imsic(bool msimode)
159 {
160     return kvm_irqchip_in_kernel() && msimode;
161 }
162 
163 bool riscv_use_emulated_aplic(bool msimode)
164 {
165 #ifdef CONFIG_KVM
166     if (tcg_enabled()) {
167         return true;
168     }
169 
170     if (!riscv_is_kvm_aia_aplic_imsic(msimode)) {
171         return true;
172     }
173 
174     return kvm_kernel_irqchip_split();
175 #else
176     return true;
177 #endif
178 }
179 
180 void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr)
181 {
182 #ifdef CONFIG_KVM
183     if (riscv_use_emulated_aplic(aplic->msimode)) {
184         aplic->kvm_msicfgaddr = extract64(addr, 0, 32);
185         aplic->kvm_msicfgaddrH = extract64(addr, 32, 32);
186     }
187 #endif
188 }
189 
190 static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic,
191                                           uint32_t irq)
192 {
193     uint32_t sourcecfg, sm, raw_input, irq_inverted;
194 
195     if (!irq || aplic->num_irqs <= irq) {
196         return false;
197     }
198 
199     sourcecfg = aplic->sourcecfg[irq];
200     if (sourcecfg & APLIC_SOURCECFG_D) {
201         return false;
202     }
203 
204     sm = sourcecfg & APLIC_SOURCECFG_SM_MASK;
205     if (sm == APLIC_SOURCECFG_SM_INACTIVE) {
206         return false;
207     }
208 
209     raw_input = (aplic->state[irq] & APLIC_ISTATE_INPUT) ? 1 : 0;
210     irq_inverted = (sm == APLIC_SOURCECFG_SM_LEVEL_LOW ||
211                     sm == APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0;
212 
213     return !!(raw_input ^ irq_inverted);
214 }
215 
216 static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic,
217                                             uint32_t word)
218 {
219     uint32_t i, irq, rectified_val, ret = 0;
220 
221     for (i = 0; i < 32; i++) {
222         irq = word * 32 + i;
223 
224         rectified_val = riscv_aplic_irq_rectified_val(aplic, irq);
225         ret |= rectified_val << i;
226     }
227 
228     return ret;
229 }
230 
231 static uint32_t riscv_aplic_read_pending_word(RISCVAPLICState *aplic,
232                                               uint32_t word)
233 {
234     uint32_t i, irq, ret = 0;
235 
236     for (i = 0; i < 32; i++) {
237         irq = word * 32 + i;
238         if (!irq || aplic->num_irqs <= irq) {
239             continue;
240         }
241 
242         ret |= ((aplic->state[irq] & APLIC_ISTATE_PENDING) ? 1 : 0) << i;
243     }
244 
245     return ret;
246 }
247 
248 static void riscv_aplic_set_pending_raw(RISCVAPLICState *aplic,
249                                         uint32_t irq, bool pending)
250 {
251     if (pending) {
252         aplic->state[irq] |= APLIC_ISTATE_PENDING;
253     } else {
254         aplic->state[irq] &= ~APLIC_ISTATE_PENDING;
255     }
256 }
257 
258 static void riscv_aplic_set_pending(RISCVAPLICState *aplic,
259                                     uint32_t irq, bool pending)
260 {
261     uint32_t sourcecfg, sm;
262 
263     if ((irq <= 0) || (aplic->num_irqs <= irq)) {
264         return;
265     }
266 
267     sourcecfg = aplic->sourcecfg[irq];
268     if (sourcecfg & APLIC_SOURCECFG_D) {
269         return;
270     }
271 
272     sm = sourcecfg & APLIC_SOURCECFG_SM_MASK;
273     if (sm == APLIC_SOURCECFG_SM_INACTIVE) {
274         return;
275     }
276 
277     if ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) ||
278         (sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) {
279         if (!aplic->msimode) {
280             return;
281         }
282         if (aplic->msimode && !pending) {
283             goto noskip_write_pending;
284         }
285         if ((aplic->state[irq] & APLIC_ISTATE_INPUT) &&
286             (sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) {
287             return;
288         }
289         if (!(aplic->state[irq] & APLIC_ISTATE_INPUT) &&
290             (sm == APLIC_SOURCECFG_SM_LEVEL_HIGH)) {
291             return;
292         }
293     }
294 
295 noskip_write_pending:
296     riscv_aplic_set_pending_raw(aplic, irq, pending);
297 }
298 
299 static void riscv_aplic_set_pending_word(RISCVAPLICState *aplic,
300                                          uint32_t word, uint32_t value,
301                                          bool pending)
302 {
303     uint32_t i, irq;
304 
305     for (i = 0; i < 32; i++) {
306         irq = word * 32 + i;
307         if (!irq || aplic->num_irqs <= irq) {
308             continue;
309         }
310 
311         if (value & (1U << i)) {
312             riscv_aplic_set_pending(aplic, irq, pending);
313         }
314     }
315 }
316 
317 static uint32_t riscv_aplic_read_enabled_word(RISCVAPLICState *aplic,
318                                               int word)
319 {
320     uint32_t i, irq, ret = 0;
321 
322     for (i = 0; i < 32; i++) {
323         irq = word * 32 + i;
324         if (!irq || aplic->num_irqs <= irq) {
325             continue;
326         }
327 
328         ret |= ((aplic->state[irq] & APLIC_ISTATE_ENABLED) ? 1 : 0) << i;
329     }
330 
331     return ret;
332 }
333 
334 static void riscv_aplic_set_enabled_raw(RISCVAPLICState *aplic,
335                                         uint32_t irq, bool enabled)
336 {
337     if (enabled) {
338         aplic->state[irq] |= APLIC_ISTATE_ENABLED;
339     } else {
340         aplic->state[irq] &= ~APLIC_ISTATE_ENABLED;
341     }
342 }
343 
344 static void riscv_aplic_set_enabled(RISCVAPLICState *aplic,
345                                     uint32_t irq, bool enabled)
346 {
347     uint32_t sourcecfg, sm;
348 
349     if ((irq <= 0) || (aplic->num_irqs <= irq)) {
350         return;
351     }
352 
353     sourcecfg = aplic->sourcecfg[irq];
354     if (sourcecfg & APLIC_SOURCECFG_D) {
355         return;
356     }
357 
358     sm = sourcecfg & APLIC_SOURCECFG_SM_MASK;
359     if (sm == APLIC_SOURCECFG_SM_INACTIVE) {
360         return;
361     }
362 
363     riscv_aplic_set_enabled_raw(aplic, irq, enabled);
364 }
365 
366 static void riscv_aplic_set_enabled_word(RISCVAPLICState *aplic,
367                                          uint32_t word, uint32_t value,
368                                          bool enabled)
369 {
370     uint32_t i, irq;
371 
372     for (i = 0; i < 32; i++) {
373         irq = word * 32 + i;
374         if (!irq || aplic->num_irqs <= irq) {
375             continue;
376         }
377 
378         if (value & (1U << i)) {
379             riscv_aplic_set_enabled(aplic, irq, enabled);
380         }
381     }
382 }
383 
384 static void riscv_aplic_msi_send(RISCVAPLICState *aplic,
385                                  uint32_t hart_idx, uint32_t guest_idx,
386                                  uint32_t eiid)
387 {
388     uint64_t addr;
389     MemTxResult result;
390     RISCVAPLICState *aplic_m;
391     uint32_t lhxs, lhxw, hhxs, hhxw, group_idx, msicfgaddr, msicfgaddrH;
392 
393     aplic_m = aplic;
394 
395     if (!aplic->kvm_splitmode) {
396         while (aplic_m && !aplic_m->mmode) {
397             aplic_m = aplic_m->parent;
398         }
399         if (!aplic_m) {
400             qemu_log_mask(LOG_GUEST_ERROR, "%s: m-level APLIC not found\n",
401                           __func__);
402             return;
403         }
404     }
405 
406     if (aplic->mmode) {
407         msicfgaddr = aplic_m->mmsicfgaddr;
408         msicfgaddrH = aplic_m->mmsicfgaddrH;
409     } else {
410         msicfgaddr = aplic_m->smsicfgaddr;
411         msicfgaddrH = aplic_m->smsicfgaddrH;
412     }
413 
414     lhxs = (msicfgaddrH >> APLIC_xMSICFGADDRH_LHXS_SHIFT) &
415             APLIC_xMSICFGADDRH_LHXS_MASK;
416     lhxw = (msicfgaddrH >> APLIC_xMSICFGADDRH_LHXW_SHIFT) &
417             APLIC_xMSICFGADDRH_LHXW_MASK;
418     hhxs = (msicfgaddrH >> APLIC_xMSICFGADDRH_HHXS_SHIFT) &
419             APLIC_xMSICFGADDRH_HHXS_MASK;
420     hhxw = (msicfgaddrH >> APLIC_xMSICFGADDRH_HHXW_SHIFT) &
421             APLIC_xMSICFGADDRH_HHXW_MASK;
422 
423     group_idx = hart_idx >> lhxw;
424     hart_idx &= APLIC_xMSICFGADDR_PPN_LHX_MASK(lhxw);
425 
426     addr = msicfgaddr;
427     addr |= ((uint64_t)(msicfgaddrH & APLIC_xMSICFGADDRH_BAPPN_MASK)) << 32;
428     addr |= ((uint64_t)(group_idx & APLIC_xMSICFGADDR_PPN_HHX_MASK(hhxw))) <<
429              APLIC_xMSICFGADDR_PPN_HHX_SHIFT(hhxs);
430     addr |= ((uint64_t)(hart_idx & APLIC_xMSICFGADDR_PPN_LHX_MASK(lhxw))) <<
431              APLIC_xMSICFGADDR_PPN_LHX_SHIFT(lhxs);
432     addr |= (uint64_t)(guest_idx & APLIC_xMSICFGADDR_PPN_HART(lhxs));
433     addr <<= APLIC_xMSICFGADDR_PPN_SHIFT;
434 
435     if (aplic->kvm_splitmode) {
436         addr |= aplic->kvm_msicfgaddr;
437         addr |= ((uint64_t)aplic->kvm_msicfgaddrH << 32);
438     }
439 
440     address_space_stl_le(&address_space_memory, addr,
441                          eiid, MEMTXATTRS_UNSPECIFIED, &result);
442     if (result != MEMTX_OK) {
443         qemu_log_mask(LOG_GUEST_ERROR, "%s: MSI write failed for "
444                       "hart_index=%d guest_index=%d eiid=%d\n",
445                       __func__, hart_idx, guest_idx, eiid);
446     }
447 }
448 
449 static void riscv_aplic_msi_irq_update(RISCVAPLICState *aplic, uint32_t irq)
450 {
451     uint32_t hart_idx, guest_idx, eiid;
452 
453     if (!aplic->msimode || (aplic->num_irqs <= irq) ||
454         !(aplic->domaincfg & APLIC_DOMAINCFG_IE)) {
455         return;
456     }
457 
458     if ((aplic->state[irq] & APLIC_ISTATE_ENPEND) != APLIC_ISTATE_ENPEND) {
459         return;
460     }
461 
462     riscv_aplic_set_pending_raw(aplic, irq, false);
463 
464     hart_idx = aplic->target[irq] >> APLIC_TARGET_HART_IDX_SHIFT;
465     hart_idx &= APLIC_TARGET_HART_IDX_MASK;
466     if (aplic->mmode) {
467         /* M-level APLIC ignores guest_index */
468         guest_idx = 0;
469     } else {
470         guest_idx = aplic->target[irq] >> APLIC_TARGET_GUEST_IDX_SHIFT;
471         guest_idx &= APLIC_TARGET_GUEST_IDX_MASK;
472     }
473     eiid = aplic->target[irq] & APLIC_TARGET_EIID_MASK;
474     riscv_aplic_msi_send(aplic, hart_idx, guest_idx, eiid);
475 }
476 
477 static uint32_t riscv_aplic_idc_topi(RISCVAPLICState *aplic, uint32_t idc)
478 {
479     uint32_t best_irq, best_iprio;
480     uint32_t irq, iprio, ihartidx, ithres;
481 
482     if (aplic->num_harts <= idc) {
483         return 0;
484     }
485 
486     ithres = aplic->ithreshold[idc];
487     best_irq = best_iprio = UINT32_MAX;
488     for (irq = 1; irq < aplic->num_irqs; irq++) {
489         if ((aplic->state[irq] & APLIC_ISTATE_ENPEND) !=
490             APLIC_ISTATE_ENPEND) {
491             continue;
492         }
493 
494         ihartidx = aplic->target[irq] >> APLIC_TARGET_HART_IDX_SHIFT;
495         ihartidx &= APLIC_TARGET_HART_IDX_MASK;
496         if (ihartidx != idc) {
497             continue;
498         }
499 
500         iprio = aplic->target[irq] & aplic->iprio_mask;
501         if (ithres && iprio >= ithres) {
502             continue;
503         }
504 
505         if (iprio < best_iprio) {
506             best_irq = irq;
507             best_iprio = iprio;
508         }
509     }
510 
511     if (best_irq < aplic->num_irqs && best_iprio <= aplic->iprio_mask) {
512         return (best_irq << APLIC_IDC_TOPI_ID_SHIFT) | best_iprio;
513     }
514 
515     return 0;
516 }
517 
518 static void riscv_aplic_idc_update(RISCVAPLICState *aplic, uint32_t idc)
519 {
520     uint32_t topi;
521 
522     if (aplic->msimode || aplic->num_harts <= idc) {
523         return;
524     }
525 
526     topi = riscv_aplic_idc_topi(aplic, idc);
527     if ((aplic->domaincfg & APLIC_DOMAINCFG_IE) &&
528         aplic->idelivery[idc] &&
529         (aplic->iforce[idc] || topi)) {
530         qemu_irq_raise(aplic->external_irqs[idc]);
531     } else {
532         qemu_irq_lower(aplic->external_irqs[idc]);
533     }
534 }
535 
536 static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
537 {
538     uint32_t irq, state, sm, topi = riscv_aplic_idc_topi(aplic, idc);
539 
540     if (!topi) {
541         aplic->iforce[idc] = 0;
542         riscv_aplic_idc_update(aplic, idc);
543         return 0;
544     }
545 
546     irq = (topi >> APLIC_IDC_TOPI_ID_SHIFT) & APLIC_IDC_TOPI_ID_MASK;
547     sm = aplic->sourcecfg[irq] & APLIC_SOURCECFG_SM_MASK;
548     state = aplic->state[irq];
549     riscv_aplic_set_pending_raw(aplic, irq, false);
550     if ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) &&
551         (state & APLIC_ISTATE_INPUT)) {
552         riscv_aplic_set_pending_raw(aplic, irq, true);
553     } else if ((sm == APLIC_SOURCECFG_SM_LEVEL_LOW) &&
554                !(state & APLIC_ISTATE_INPUT)) {
555         riscv_aplic_set_pending_raw(aplic, irq, true);
556     }
557     riscv_aplic_idc_update(aplic, idc);
558 
559     return topi;
560 }
561 
562 static void riscv_aplic_request(void *opaque, int irq, int level)
563 {
564     bool update = false;
565     RISCVAPLICState *aplic = opaque;
566     uint32_t sourcecfg, childidx, state, idc;
567 
568     assert((0 < irq) && (irq < aplic->num_irqs));
569 
570     sourcecfg = aplic->sourcecfg[irq];
571     if (sourcecfg & APLIC_SOURCECFG_D) {
572         childidx = sourcecfg & APLIC_SOURCECFG_CHILDIDX_MASK;
573         if (childidx < aplic->num_children) {
574             riscv_aplic_request(aplic->children[childidx], irq, level);
575         }
576         return;
577     }
578 
579     state = aplic->state[irq];
580     switch (sourcecfg & APLIC_SOURCECFG_SM_MASK) {
581     case APLIC_SOURCECFG_SM_EDGE_RISE:
582         if ((level > 0) && !(state & APLIC_ISTATE_INPUT) &&
583             !(state & APLIC_ISTATE_PENDING)) {
584             riscv_aplic_set_pending_raw(aplic, irq, true);
585             update = true;
586         }
587         break;
588     case APLIC_SOURCECFG_SM_EDGE_FALL:
589         if ((level <= 0) && (state & APLIC_ISTATE_INPUT) &&
590             !(state & APLIC_ISTATE_PENDING)) {
591             riscv_aplic_set_pending_raw(aplic, irq, true);
592             update = true;
593         }
594         break;
595     case APLIC_SOURCECFG_SM_LEVEL_HIGH:
596         if ((level > 0) && !(state & APLIC_ISTATE_PENDING)) {
597             riscv_aplic_set_pending_raw(aplic, irq, true);
598             update = true;
599         }
600         break;
601     case APLIC_SOURCECFG_SM_LEVEL_LOW:
602         if ((level <= 0) && !(state & APLIC_ISTATE_PENDING)) {
603             riscv_aplic_set_pending_raw(aplic, irq, true);
604             update = true;
605         }
606         break;
607     default:
608         break;
609     }
610 
611     if (level <= 0) {
612         aplic->state[irq] &= ~APLIC_ISTATE_INPUT;
613     } else {
614         aplic->state[irq] |= APLIC_ISTATE_INPUT;
615     }
616 
617     if (update) {
618         if (aplic->msimode) {
619             riscv_aplic_msi_irq_update(aplic, irq);
620         } else {
621             idc = aplic->target[irq] >> APLIC_TARGET_HART_IDX_SHIFT;
622             idc &= APLIC_TARGET_HART_IDX_MASK;
623             riscv_aplic_idc_update(aplic, idc);
624         }
625     }
626 }
627 
628 static uint64_t riscv_aplic_read(void *opaque, hwaddr addr, unsigned size)
629 {
630     uint32_t irq, word, idc;
631     RISCVAPLICState *aplic = opaque;
632 
633     /* Reads must be 4 byte words */
634     if ((addr & 0x3) != 0) {
635         goto err;
636     }
637 
638     if (addr == APLIC_DOMAINCFG) {
639         return APLIC_DOMAINCFG_RDONLY | aplic->domaincfg |
640                (aplic->msimode ? APLIC_DOMAINCFG_DM : 0);
641     } else if ((APLIC_SOURCECFG_BASE <= addr) &&
642             (addr < (APLIC_SOURCECFG_BASE + (aplic->num_irqs - 1) * 4))) {
643         irq  = ((addr - APLIC_SOURCECFG_BASE) >> 2) + 1;
644         return aplic->sourcecfg[irq];
645     } else if (aplic->mmode && aplic->msimode &&
646                (addr == APLIC_MMSICFGADDR)) {
647         return aplic->mmsicfgaddr;
648     } else if (aplic->mmode && aplic->msimode &&
649                (addr == APLIC_MMSICFGADDRH)) {
650         return aplic->mmsicfgaddrH;
651     } else if (aplic->mmode && aplic->msimode &&
652                (addr == APLIC_SMSICFGADDR)) {
653         /*
654          * Registers SMSICFGADDR and SMSICFGADDRH are implemented only if:
655          * (a) the interrupt domain is at machine level
656          * (b) the domain's harts implement supervisor mode
657          * (c) the domain has one or more child supervisor-level domains
658          *     that support MSI delivery mode (domaincfg.DM is not read-
659          *     only zero in at least one of the supervisor-level child
660          * domains).
661          */
662         return (aplic->num_children) ? aplic->smsicfgaddr : 0;
663     } else if (aplic->mmode && aplic->msimode &&
664                (addr == APLIC_SMSICFGADDRH)) {
665         return (aplic->num_children) ? aplic->smsicfgaddrH : 0;
666     } else if ((APLIC_SETIP_BASE <= addr) &&
667             (addr < (APLIC_SETIP_BASE + aplic->bitfield_words * 4))) {
668         word = (addr - APLIC_SETIP_BASE) >> 2;
669         return riscv_aplic_read_pending_word(aplic, word);
670     } else if (addr == APLIC_SETIPNUM) {
671         return 0;
672     } else if ((APLIC_CLRIP_BASE <= addr) &&
673             (addr < (APLIC_CLRIP_BASE + aplic->bitfield_words * 4))) {
674         word = (addr - APLIC_CLRIP_BASE) >> 2;
675         return riscv_aplic_read_input_word(aplic, word);
676     } else if (addr == APLIC_CLRIPNUM) {
677         return 0;
678     } else if ((APLIC_SETIE_BASE <= addr) &&
679             (addr < (APLIC_SETIE_BASE + aplic->bitfield_words * 4))) {
680         word = (addr - APLIC_SETIE_BASE) >> 2;
681         return riscv_aplic_read_enabled_word(aplic, word);
682     } else if (addr == APLIC_SETIENUM) {
683         return 0;
684     } else if ((APLIC_CLRIE_BASE <= addr) &&
685             (addr < (APLIC_CLRIE_BASE + aplic->bitfield_words * 4))) {
686         return 0;
687     } else if (addr == APLIC_CLRIENUM) {
688         return 0;
689     } else if (addr == APLIC_SETIPNUM_LE) {
690         return 0;
691     } else if (addr == APLIC_SETIPNUM_BE) {
692         return 0;
693     } else if (addr == APLIC_GENMSI) {
694         return (aplic->msimode) ? aplic->genmsi : 0;
695     } else if ((APLIC_TARGET_BASE <= addr) &&
696             (addr < (APLIC_TARGET_BASE + (aplic->num_irqs - 1) * 4))) {
697         irq = ((addr - APLIC_TARGET_BASE) >> 2) + 1;
698         return aplic->target[irq];
699     } else if (!aplic->msimode && (APLIC_IDC_BASE <= addr) &&
700             (addr < (APLIC_IDC_BASE + aplic->num_harts * APLIC_IDC_SIZE))) {
701         idc = (addr - APLIC_IDC_BASE) / APLIC_IDC_SIZE;
702         switch (addr - (APLIC_IDC_BASE + idc * APLIC_IDC_SIZE)) {
703         case APLIC_IDC_IDELIVERY:
704             return aplic->idelivery[idc];
705         case APLIC_IDC_IFORCE:
706             return aplic->iforce[idc];
707         case APLIC_IDC_ITHRESHOLD:
708             return aplic->ithreshold[idc];
709         case APLIC_IDC_TOPI:
710             return riscv_aplic_idc_topi(aplic, idc);
711         case APLIC_IDC_CLAIMI:
712             return riscv_aplic_idc_claimi(aplic, idc);
713         default:
714             goto err;
715         };
716     }
717 
718 err:
719     qemu_log_mask(LOG_GUEST_ERROR,
720                   "%s: Invalid register read 0x%" HWADDR_PRIx "\n",
721                   __func__, addr);
722     return 0;
723 }
724 
725 static void riscv_aplic_write(void *opaque, hwaddr addr, uint64_t value,
726         unsigned size)
727 {
728     RISCVAPLICState *aplic = opaque;
729     uint32_t irq, word, idc = UINT32_MAX;
730 
731     /* Writes must be 4 byte words */
732     if ((addr & 0x3) != 0) {
733         goto err;
734     }
735 
736     if (addr == APLIC_DOMAINCFG) {
737         /* Only IE bit writable at the moment */
738         value &= APLIC_DOMAINCFG_IE;
739         aplic->domaincfg = value;
740     } else if ((APLIC_SOURCECFG_BASE <= addr) &&
741             (addr < (APLIC_SOURCECFG_BASE + (aplic->num_irqs - 1) * 4))) {
742         irq  = ((addr - APLIC_SOURCECFG_BASE) >> 2) + 1;
743         if (!aplic->num_children && (value & APLIC_SOURCECFG_D)) {
744             value = 0;
745         }
746         if (value & APLIC_SOURCECFG_D) {
747             value &= (APLIC_SOURCECFG_D | APLIC_SOURCECFG_CHILDIDX_MASK);
748         } else {
749             value &= (APLIC_SOURCECFG_D | APLIC_SOURCECFG_SM_MASK);
750         }
751         aplic->sourcecfg[irq] = value;
752         if ((aplic->sourcecfg[irq] & APLIC_SOURCECFG_D) ||
753             (aplic->sourcecfg[irq] == 0)) {
754             riscv_aplic_set_pending_raw(aplic, irq, false);
755             riscv_aplic_set_enabled_raw(aplic, irq, false);
756         } else {
757             if (riscv_aplic_irq_rectified_val(aplic, irq)) {
758                 riscv_aplic_set_pending_raw(aplic, irq, true);
759             }
760         }
761     } else if (aplic->mmode && aplic->msimode &&
762                (addr == APLIC_MMSICFGADDR)) {
763         if (!(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
764             aplic->mmsicfgaddr = value;
765         }
766     } else if (aplic->mmode && aplic->msimode &&
767                (addr == APLIC_MMSICFGADDRH)) {
768         if (!(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
769             aplic->mmsicfgaddrH = value & APLIC_xMSICFGADDRH_VALID_MASK;
770         }
771     } else if (aplic->mmode && aplic->msimode &&
772                (addr == APLIC_SMSICFGADDR)) {
773         /*
774          * Registers SMSICFGADDR and SMSICFGADDRH are implemented only if:
775          * (a) the interrupt domain is at machine level
776          * (b) the domain's harts implement supervisor mode
777          * (c) the domain has one or more child supervisor-level domains
778          *     that support MSI delivery mode (domaincfg.DM is not read-
779          *     only zero in at least one of the supervisor-level child
780          * domains).
781          */
782         if (aplic->num_children &&
783             !(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
784             aplic->smsicfgaddr = value;
785         }
786     } else if (aplic->mmode && aplic->msimode &&
787                (addr == APLIC_SMSICFGADDRH)) {
788         if (aplic->num_children &&
789             !(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
790             aplic->smsicfgaddrH = value & APLIC_xMSICFGADDRH_VALID_MASK;
791         }
792     } else if ((APLIC_SETIP_BASE <= addr) &&
793             (addr < (APLIC_SETIP_BASE + aplic->bitfield_words * 4))) {
794         word = (addr - APLIC_SETIP_BASE) >> 2;
795         riscv_aplic_set_pending_word(aplic, word, value, true);
796     } else if (addr == APLIC_SETIPNUM) {
797         riscv_aplic_set_pending(aplic, value, true);
798     } else if ((APLIC_CLRIP_BASE <= addr) &&
799             (addr < (APLIC_CLRIP_BASE + aplic->bitfield_words * 4))) {
800         word = (addr - APLIC_CLRIP_BASE) >> 2;
801         riscv_aplic_set_pending_word(aplic, word, value, false);
802     } else if (addr == APLIC_CLRIPNUM) {
803         riscv_aplic_set_pending(aplic, value, false);
804     } else if ((APLIC_SETIE_BASE <= addr) &&
805             (addr < (APLIC_SETIE_BASE + aplic->bitfield_words * 4))) {
806         word = (addr - APLIC_SETIE_BASE) >> 2;
807         riscv_aplic_set_enabled_word(aplic, word, value, true);
808     } else if (addr == APLIC_SETIENUM) {
809         riscv_aplic_set_enabled(aplic, value, true);
810     } else if ((APLIC_CLRIE_BASE <= addr) &&
811             (addr < (APLIC_CLRIE_BASE + aplic->bitfield_words * 4))) {
812         word = (addr - APLIC_CLRIE_BASE) >> 2;
813         riscv_aplic_set_enabled_word(aplic, word, value, false);
814     } else if (addr == APLIC_CLRIENUM) {
815         riscv_aplic_set_enabled(aplic, value, false);
816     } else if (addr == APLIC_SETIPNUM_LE) {
817         riscv_aplic_set_pending(aplic, value, true);
818     } else if (addr == APLIC_SETIPNUM_BE) {
819         riscv_aplic_set_pending(aplic, bswap32(value), true);
820     } else if (addr == APLIC_GENMSI) {
821         if (aplic->msimode) {
822             aplic->genmsi = value & ~(APLIC_TARGET_GUEST_IDX_MASK <<
823                                       APLIC_TARGET_GUEST_IDX_SHIFT);
824             riscv_aplic_msi_send(aplic,
825                                  value >> APLIC_TARGET_HART_IDX_SHIFT,
826                                  0,
827                                  value & APLIC_TARGET_EIID_MASK);
828         }
829     } else if ((APLIC_TARGET_BASE <= addr) &&
830             (addr < (APLIC_TARGET_BASE + (aplic->num_irqs - 1) * 4))) {
831         irq = ((addr - APLIC_TARGET_BASE) >> 2) + 1;
832         if (aplic->msimode) {
833             aplic->target[irq] = value;
834         } else {
835             aplic->target[irq] = (value & ~APLIC_TARGET_IPRIO_MASK) |
836                                  ((value & aplic->iprio_mask) ?
837                                   (value & aplic->iprio_mask) : 1);
838         }
839     } else if (!aplic->msimode && (APLIC_IDC_BASE <= addr) &&
840             (addr < (APLIC_IDC_BASE + aplic->num_harts * APLIC_IDC_SIZE))) {
841         idc = (addr - APLIC_IDC_BASE) / APLIC_IDC_SIZE;
842         switch (addr - (APLIC_IDC_BASE + idc * APLIC_IDC_SIZE)) {
843         case APLIC_IDC_IDELIVERY:
844             aplic->idelivery[idc] = value & 0x1;
845             break;
846         case APLIC_IDC_IFORCE:
847             aplic->iforce[idc] = value & 0x1;
848             break;
849         case APLIC_IDC_ITHRESHOLD:
850             aplic->ithreshold[idc] = value & aplic->iprio_mask;
851             break;
852         default:
853             goto err;
854         };
855     } else {
856         goto err;
857     }
858 
859     if (aplic->msimode) {
860         for (irq = 1; irq < aplic->num_irqs; irq++) {
861             riscv_aplic_msi_irq_update(aplic, irq);
862         }
863     } else {
864         if (idc == UINT32_MAX) {
865             for (idc = 0; idc < aplic->num_harts; idc++) {
866                 riscv_aplic_idc_update(aplic, idc);
867             }
868         } else {
869             riscv_aplic_idc_update(aplic, idc);
870         }
871     }
872 
873     return;
874 
875 err:
876     qemu_log_mask(LOG_GUEST_ERROR,
877                   "%s: Invalid register write 0x%" HWADDR_PRIx "\n",
878                   __func__, addr);
879 }
880 
881 static const MemoryRegionOps riscv_aplic_ops = {
882     .read = riscv_aplic_read,
883     .write = riscv_aplic_write,
884     .endianness = DEVICE_LITTLE_ENDIAN,
885     .valid = {
886         .min_access_size = 4,
887         .max_access_size = 4
888     }
889 };
890 
891 static void riscv_aplic_realize(DeviceState *dev, Error **errp)
892 {
893     uint32_t i;
894     RISCVAPLICState *aplic = RISCV_APLIC(dev);
895 
896     if (riscv_use_emulated_aplic(aplic->msimode)) {
897         aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
898         aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
899         aplic->state = g_new0(uint32_t, aplic->num_irqs);
900         aplic->target = g_new0(uint32_t, aplic->num_irqs);
901         if (!aplic->msimode) {
902             for (i = 0; i < aplic->num_irqs; i++) {
903                 aplic->target[i] = 1;
904             }
905         }
906         aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
907         aplic->iforce = g_new0(uint32_t, aplic->num_harts);
908         aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
909 
910         memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops,
911                               aplic, TYPE_RISCV_APLIC, aplic->aperture_size);
912         sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
913 
914         if (kvm_enabled()) {
915             aplic->kvm_splitmode = true;
916         }
917     }
918 
919     /*
920      * Only root APLICs have hardware IRQ lines. All non-root APLICs
921      * have IRQ lines delegated by their parent APLIC.
922      */
923     if (!aplic->parent) {
924         if (kvm_enabled() && !riscv_use_emulated_aplic(aplic->msimode)) {
925             qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
926         } else {
927             qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
928         }
929     }
930 
931     /* Create output IRQ lines for non-MSI mode */
932     if (!aplic->msimode) {
933         aplic->external_irqs = g_malloc(sizeof(qemu_irq) * aplic->num_harts);
934         qdev_init_gpio_out(dev, aplic->external_irqs, aplic->num_harts);
935 
936         /* Claim the CPU interrupt to be triggered by this APLIC */
937         for (i = 0; i < aplic->num_harts; i++) {
938             RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(aplic->hartid_base + i));
939             if (riscv_cpu_claim_interrupts(cpu,
940                 (aplic->mmode) ? MIP_MEIP : MIP_SEIP) < 0) {
941                 error_report("%s already claimed",
942                              (aplic->mmode) ? "MEIP" : "SEIP");
943                 exit(1);
944             }
945         }
946     }
947 
948     msi_nonbroken = true;
949 }
950 
951 static const Property riscv_aplic_properties[] = {
952     DEFINE_PROP_UINT32("aperture-size", RISCVAPLICState, aperture_size, 0),
953     DEFINE_PROP_UINT32("hartid-base", RISCVAPLICState, hartid_base, 0),
954     DEFINE_PROP_UINT32("num-harts", RISCVAPLICState, num_harts, 0),
955     DEFINE_PROP_UINT32("iprio-mask", RISCVAPLICState, iprio_mask, 0),
956     DEFINE_PROP_UINT32("num-irqs", RISCVAPLICState, num_irqs, 0),
957     DEFINE_PROP_BOOL("msimode", RISCVAPLICState, msimode, 0),
958     DEFINE_PROP_BOOL("mmode", RISCVAPLICState, mmode, 0),
959 };
960 
961 static const VMStateDescription vmstate_riscv_aplic = {
962     .name = "riscv_aplic",
963     .version_id = 2,
964     .minimum_version_id = 2,
965     .fields = (const VMStateField[]) {
966             VMSTATE_UINT32(domaincfg, RISCVAPLICState),
967             VMSTATE_UINT32(mmsicfgaddr, RISCVAPLICState),
968             VMSTATE_UINT32(mmsicfgaddrH, RISCVAPLICState),
969             VMSTATE_UINT32(smsicfgaddr, RISCVAPLICState),
970             VMSTATE_UINT32(smsicfgaddrH, RISCVAPLICState),
971             VMSTATE_UINT32(genmsi, RISCVAPLICState),
972             VMSTATE_UINT32(kvm_msicfgaddr, RISCVAPLICState),
973             VMSTATE_UINT32(kvm_msicfgaddrH, RISCVAPLICState),
974             VMSTATE_VARRAY_UINT32(sourcecfg, RISCVAPLICState,
975                                   num_irqs, 0,
976                                   vmstate_info_uint32, uint32_t),
977             VMSTATE_VARRAY_UINT32(state, RISCVAPLICState,
978                                   num_irqs, 0,
979                                   vmstate_info_uint32, uint32_t),
980             VMSTATE_VARRAY_UINT32(target, RISCVAPLICState,
981                                   num_irqs, 0,
982                                   vmstate_info_uint32, uint32_t),
983             VMSTATE_VARRAY_UINT32(idelivery, RISCVAPLICState,
984                                   num_harts, 0,
985                                   vmstate_info_uint32, uint32_t),
986             VMSTATE_VARRAY_UINT32(iforce, RISCVAPLICState,
987                                   num_harts, 0,
988                                   vmstate_info_uint32, uint32_t),
989             VMSTATE_VARRAY_UINT32(ithreshold, RISCVAPLICState,
990                                   num_harts, 0,
991                                   vmstate_info_uint32, uint32_t),
992             VMSTATE_END_OF_LIST()
993         }
994 };
995 
996 static void riscv_aplic_class_init(ObjectClass *klass, void *data)
997 {
998     DeviceClass *dc = DEVICE_CLASS(klass);
999 
1000     device_class_set_props(dc, riscv_aplic_properties);
1001     dc->realize = riscv_aplic_realize;
1002     dc->vmsd = &vmstate_riscv_aplic;
1003 }
1004 
1005 static const TypeInfo riscv_aplic_info = {
1006     .name          = TYPE_RISCV_APLIC,
1007     .parent        = TYPE_SYS_BUS_DEVICE,
1008     .instance_size = sizeof(RISCVAPLICState),
1009     .class_init    = riscv_aplic_class_init,
1010 };
1011 
1012 static void riscv_aplic_register_types(void)
1013 {
1014     type_register_static(&riscv_aplic_info);
1015 }
1016 
1017 type_init(riscv_aplic_register_types)
1018 
1019 /*
1020  * Add a APLIC device to another APLIC device as child for
1021  * interrupt delegation.
1022  */
1023 void riscv_aplic_add_child(DeviceState *parent, DeviceState *child)
1024 {
1025     RISCVAPLICState *caplic, *paplic;
1026 
1027     assert(parent && child);
1028     caplic = RISCV_APLIC(child);
1029     paplic = RISCV_APLIC(parent);
1030 
1031     assert(paplic->num_irqs == caplic->num_irqs);
1032     assert(paplic->num_children <= QEMU_APLIC_MAX_CHILDREN);
1033 
1034     caplic->parent = paplic;
1035     paplic->children[paplic->num_children] = caplic;
1036     paplic->num_children++;
1037 }
1038 
1039 /*
1040  * Create APLIC device.
1041  */
1042 DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
1043     uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,
1044     uint32_t iprio_bits, bool msimode, bool mmode, DeviceState *parent)
1045 {
1046     DeviceState *dev = qdev_new(TYPE_RISCV_APLIC);
1047     uint32_t i;
1048 
1049     assert(num_harts < APLIC_MAX_IDC);
1050     assert((APLIC_IDC_BASE + (num_harts * APLIC_IDC_SIZE)) <= size);
1051     assert(num_sources < APLIC_MAX_SOURCE);
1052     assert(APLIC_MIN_IPRIO_BITS <= iprio_bits);
1053     assert(iprio_bits <= APLIC_MAX_IPRIO_BITS);
1054 
1055     qdev_prop_set_uint32(dev, "aperture-size", size);
1056     qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
1057     qdev_prop_set_uint32(dev, "num-harts", num_harts);
1058     qdev_prop_set_uint32(dev, "iprio-mask", ((1U << iprio_bits) - 1));
1059     qdev_prop_set_uint32(dev, "num-irqs", num_sources + 1);
1060     qdev_prop_set_bit(dev, "msimode", msimode);
1061     qdev_prop_set_bit(dev, "mmode", mmode);
1062 
1063     if (parent) {
1064         riscv_aplic_add_child(parent, dev);
1065     }
1066 
1067     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1068 
1069     if (riscv_use_emulated_aplic(msimode)) {
1070         sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
1071     }
1072 
1073     if (!msimode) {
1074         for (i = 0; i < num_harts; i++) {
1075             CPUState *cpu = cpu_by_arch_id(hartid_base + i);
1076 
1077             qdev_connect_gpio_out_named(dev, NULL, i,
1078                                         qdev_get_gpio_in(DEVICE(cpu),
1079                                             (mmode) ? IRQ_M_EXT : IRQ_S_EXT));
1080         }
1081     }
1082 
1083     return dev;
1084 }
1085