xref: /qemu/hw/intc/mips_gic.c (revision dfbd2768)
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
7  * Authors: Sanjay Lal <sanjayl@kymasys.com>
8  *
9  * Copyright (C) 2016 Imagination Technologies
10  */
11 
12 #include "qemu/osdep.h"
13 #include "qemu/log.h"
14 #include "qapi/error.h"
15 #include "hw/hw.h"
16 #include "hw/sysbus.h"
17 #include "exec/memory.h"
18 #include "sysemu/sysemu.h"
19 #include "sysemu/kvm.h"
20 #include "kvm_mips.h"
21 #include "hw/intc/mips_gic.h"
22 
23 static void mips_gic_set_vp_irq(MIPSGICState *gic, int vp, int pin, int level)
24 {
25     int ored_level = level;
26     int i;
27 
28     /* ORing pending registers sharing same pin */
29     if (!ored_level) {
30         for (i = 0; i < gic->num_irq; i++) {
31             if ((gic->irq_state[i].map_pin & GIC_MAP_MSK) == pin &&
32                     gic->irq_state[i].map_vp == vp &&
33                     gic->irq_state[i].enabled) {
34                 ored_level |= gic->irq_state[i].pending;
35             }
36             if (ored_level) {
37                 /* no need to iterate all interrupts */
38                 break;
39             }
40         }
41         if (((gic->vps[vp].compare_map & GIC_MAP_MSK) == pin) &&
42                 (gic->vps[vp].mask & GIC_VP_MASK_CMP_MSK)) {
43             /* ORing with local pending register (count/compare) */
44             ored_level |= (gic->vps[vp].pend & GIC_VP_MASK_CMP_MSK) >>
45                           GIC_VP_MASK_CMP_SHF;
46         }
47     }
48     if (kvm_enabled())  {
49         kvm_mips_set_ipi_interrupt(mips_env_get_cpu(gic->vps[vp].env),
50                                    pin + GIC_CPU_PIN_OFFSET,
51                                    ored_level);
52     } else {
53         qemu_set_irq(gic->vps[vp].env->irq[pin + GIC_CPU_PIN_OFFSET],
54                      ored_level);
55     }
56 }
57 
58 static void gic_set_irq(void *opaque, int n_IRQ, int level)
59 {
60     MIPSGICState *gic = (MIPSGICState *) opaque;
61     int vp = gic->irq_state[n_IRQ].map_vp;
62     int pin = gic->irq_state[n_IRQ].map_pin & GIC_MAP_MSK;
63 
64     gic->irq_state[n_IRQ].pending = (uint8_t) level;
65     if (!gic->irq_state[n_IRQ].enabled) {
66         /* GIC interrupt source disabled */
67         return;
68     }
69     if (vp < 0 || vp >= gic->num_vps) {
70         return;
71     }
72     mips_gic_set_vp_irq(gic, vp, pin, level);
73 }
74 
75 #define OFFSET_CHECK(c)                         \
76     do {                                        \
77         if (!(c)) {                             \
78             goto bad_offset;                    \
79         }                                       \
80     } while (0)
81 
82 /* GIC Read VP Local/Other Registers */
83 static uint64_t gic_read_vp(MIPSGICState *gic, uint32_t vp_index, hwaddr addr,
84                             unsigned size)
85 {
86     switch (addr) {
87     case GIC_VP_CTL_OFS:
88         return gic->vps[vp_index].ctl;
89     case GIC_VP_PEND_OFS:
90         mips_gictimer_get_sh_count(gic->gic_timer);
91         return gic->vps[vp_index].pend;
92     case GIC_VP_MASK_OFS:
93         return gic->vps[vp_index].mask;
94     case GIC_VP_COMPARE_MAP_OFS:
95         return gic->vps[vp_index].compare_map;
96     case GIC_VP_OTHER_ADDR_OFS:
97         return gic->vps[vp_index].other_addr;
98     case GIC_VP_IDENT_OFS:
99         return vp_index;
100     case GIC_VP_COMPARE_LO_OFS:
101         return mips_gictimer_get_vp_compare(gic->gic_timer, vp_index);
102     case GIC_VP_COMPARE_HI_OFS:
103         return 0;
104     default:
105         qemu_log_mask(LOG_UNIMP, "Read %d bytes at GIC offset LOCAL/OTHER 0x%"
106                       PRIx64 "\n", size, addr);
107         break;
108     }
109     return 0;
110 }
111 
112 static uint64_t gic_read(void *opaque, hwaddr addr, unsigned size)
113 {
114     MIPSGICState *gic = (MIPSGICState *) opaque;
115     uint32_t vp_index = current_cpu->cpu_index;
116     uint64_t ret = 0;
117     int i, base, irq_src;
118     uint32_t other_index;
119 
120     switch (addr) {
121     case GIC_SH_CONFIG_OFS:
122         ret = gic->sh_config | (mips_gictimer_get_countstop(gic->gic_timer) <<
123                                GIC_SH_CONFIG_COUNTSTOP_SHF);
124         break;
125     case GIC_SH_COUNTERLO_OFS:
126         ret = mips_gictimer_get_sh_count(gic->gic_timer);
127         break;
128     case GIC_SH_COUNTERHI_OFS:
129         ret = 0;
130         break;
131     case GIC_SH_PEND_OFS ... GIC_SH_PEND_LAST_OFS:
132         /* each bit represents pending status for an interrupt pin */
133         base = (addr - GIC_SH_PEND_OFS) * 8;
134         OFFSET_CHECK((base + size * 8) <= gic->num_irq);
135         for (i = 0; i < size * 8; i++) {
136             ret |= (uint64_t) (gic->irq_state[base + i].pending) << i;
137         }
138         break;
139     case GIC_SH_MASK_OFS ... GIC_SH_MASK_LAST_OFS:
140         /* each bit represents status for an interrupt pin */
141         base = (addr - GIC_SH_MASK_OFS) * 8;
142         OFFSET_CHECK((base + size * 8) <= gic->num_irq);
143         for (i = 0; i < size * 8; i++) {
144             ret |= (uint64_t) (gic->irq_state[base + i].enabled) << i;
145         }
146         break;
147     case GIC_SH_MAP0_PIN_OFS ... GIC_SH_MAP255_PIN_OFS:
148         /* 32 bits per a pin */
149         irq_src = (addr - GIC_SH_MAP0_PIN_OFS) / 4;
150         OFFSET_CHECK(irq_src < gic->num_irq);
151         ret = gic->irq_state[irq_src].map_pin;
152         break;
153     case GIC_SH_MAP0_VP_OFS ... GIC_SH_MAP255_VP_LAST_OFS:
154         /* up to 32 bytes per a pin */
155         irq_src = (addr - GIC_SH_MAP0_VP_OFS) / 32;
156         OFFSET_CHECK(irq_src < gic->num_irq);
157         if ((gic->irq_state[irq_src].map_vp) >= 0) {
158             ret = (uint64_t) 1 << (gic->irq_state[irq_src].map_vp);
159         } else {
160             ret = 0;
161         }
162         break;
163     /* VP-Local Register */
164     case VP_LOCAL_SECTION_OFS ... (VP_LOCAL_SECTION_OFS + GIC_VL_BRK_GROUP):
165         ret = gic_read_vp(gic, vp_index, addr - VP_LOCAL_SECTION_OFS, size);
166         break;
167     /* VP-Other Register */
168     case VP_OTHER_SECTION_OFS ... (VP_OTHER_SECTION_OFS + GIC_VL_BRK_GROUP):
169         other_index = gic->vps[vp_index].other_addr;
170         ret = gic_read_vp(gic, other_index, addr - VP_OTHER_SECTION_OFS, size);
171         break;
172     /* User-Mode Visible section */
173     case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERLO:
174         ret = mips_gictimer_get_sh_count(gic->gic_timer);
175         break;
176     case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERHI:
177         ret = 0;
178         break;
179     default:
180         qemu_log_mask(LOG_UNIMP, "Read %d bytes at GIC offset 0x%" PRIx64 "\n",
181                       size, addr);
182         break;
183     }
184     return ret;
185 bad_offset:
186     qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr);
187     return 0;
188 }
189 
190 static void gic_timer_expire_cb(void *opaque, uint32_t vp_index)
191 {
192     MIPSGICState *gic = opaque;
193 
194     gic->vps[vp_index].pend |= (1 << GIC_LOCAL_INT_COMPARE);
195     if (gic->vps[vp_index].pend &
196             (gic->vps[vp_index].mask & GIC_VP_MASK_CMP_MSK)) {
197         if (gic->vps[vp_index].compare_map & GIC_MAP_TO_PIN_MSK) {
198             /* it is safe to set the irq high regardless of other GIC IRQs */
199             uint32_t pin = (gic->vps[vp_index].compare_map & GIC_MAP_MSK);
200             qemu_irq_raise(gic->vps[vp_index].env->irq
201                            [pin + GIC_CPU_PIN_OFFSET]);
202         }
203     }
204 }
205 
206 static void gic_timer_store_vp_compare(MIPSGICState *gic, uint32_t vp_index,
207                                        uint64_t compare)
208 {
209     gic->vps[vp_index].pend &= ~(1 << GIC_LOCAL_INT_COMPARE);
210     if (gic->vps[vp_index].compare_map & GIC_MAP_TO_PIN_MSK) {
211         uint32_t pin = (gic->vps[vp_index].compare_map & GIC_MAP_MSK);
212         mips_gic_set_vp_irq(gic, vp_index, pin, 0);
213     }
214     mips_gictimer_store_vp_compare(gic->gic_timer, vp_index, compare);
215 }
216 
217 /* GIC Write VP Local/Other Registers */
218 static void gic_write_vp(MIPSGICState *gic, uint32_t vp_index, hwaddr addr,
219                               uint64_t data, unsigned size)
220 {
221     switch (addr) {
222     case GIC_VP_CTL_OFS:
223         /* EIC isn't supported */
224         break;
225     case GIC_VP_RMASK_OFS:
226         gic->vps[vp_index].mask &= ~(data & GIC_VP_SET_RESET_MSK) &
227                                    GIC_VP_SET_RESET_MSK;
228         break;
229     case GIC_VP_SMASK_OFS:
230         gic->vps[vp_index].mask |= data & GIC_VP_SET_RESET_MSK;
231         break;
232     case GIC_VP_COMPARE_MAP_OFS:
233         /* EIC isn't supported */
234         OFFSET_CHECK((data & GIC_MAP_MSK) <= GIC_CPU_INT_MAX);
235         gic->vps[vp_index].compare_map = data & GIC_MAP_TO_PIN_REG_MSK;
236         break;
237     case GIC_VP_OTHER_ADDR_OFS:
238         OFFSET_CHECK(data < gic->num_vps);
239         gic->vps[vp_index].other_addr = data;
240         break;
241     case GIC_VP_COMPARE_LO_OFS:
242         gic_timer_store_vp_compare(gic, vp_index, data);
243         break;
244     default:
245         qemu_log_mask(LOG_UNIMP, "Write %d bytes at GIC offset LOCAL/OTHER "
246                       "0x%" PRIx64" 0x%08" PRIx64 "\n", size, addr, data);
247         break;
248     }
249     return;
250 bad_offset:
251     qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr);
252     return;
253 }
254 
255 static void gic_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
256 {
257     int intr;
258     MIPSGICState *gic = (MIPSGICState *) opaque;
259     uint32_t vp_index = current_cpu->cpu_index;
260     int i, base, irq_src;
261     uint32_t other_index;
262 
263     switch (addr) {
264     case GIC_SH_CONFIG_OFS:
265         {
266             uint32_t pre_cntstop = mips_gictimer_get_countstop(gic->gic_timer);
267             uint32_t new_cntstop = (data & GIC_SH_CONFIG_COUNTSTOP_MSK) >>
268                                    GIC_SH_CONFIG_COUNTSTOP_SHF;
269             if (pre_cntstop != new_cntstop) {
270                 if (new_cntstop == 1) {
271                     mips_gictimer_stop_count(gic->gic_timer);
272                 } else {
273                     mips_gictimer_start_count(gic->gic_timer);
274                 }
275             }
276         }
277         break;
278     case GIC_SH_COUNTERLO_OFS:
279         if (mips_gictimer_get_countstop(gic->gic_timer)) {
280             mips_gictimer_store_sh_count(gic->gic_timer, data);
281         }
282         break;
283     case GIC_SH_RMASK_OFS ... GIC_SH_RMASK_LAST_OFS:
284         /* up to 64 bits per a pin */
285         base = (addr - GIC_SH_RMASK_OFS) * 8;
286         OFFSET_CHECK((base + size * 8) <= gic->num_irq);
287         for (i = 0; i < size * 8; i++) {
288             gic->irq_state[base + i].enabled &= !((data >> i) & 1);
289         }
290         break;
291     case GIC_SH_WEDGE_OFS:
292         /* Figure out which VP/HW Interrupt this maps to */
293         intr = data & ~GIC_SH_WEDGE_RW_MSK;
294         /* Mask/Enabled Checks */
295         OFFSET_CHECK(intr < gic->num_irq);
296         if (data & GIC_SH_WEDGE_RW_MSK) {
297             gic_set_irq(gic, intr, 1);
298         } else {
299             gic_set_irq(gic, intr, 0);
300         }
301         break;
302     case GIC_SH_SMASK_OFS ... GIC_SH_SMASK_LAST_OFS:
303         /* up to 64 bits per a pin */
304         base = (addr - GIC_SH_SMASK_OFS) * 8;
305         OFFSET_CHECK((base + size * 8) <= gic->num_irq);
306         for (i = 0; i < size * 8; i++) {
307             gic->irq_state[base + i].enabled |= (data >> i) & 1;
308         }
309         break;
310     case GIC_SH_MAP0_PIN_OFS ... GIC_SH_MAP255_PIN_OFS:
311         /* 32 bits per a pin */
312         irq_src = (addr - GIC_SH_MAP0_PIN_OFS) / 4;
313         OFFSET_CHECK(irq_src < gic->num_irq);
314         /* EIC isn't supported */
315         OFFSET_CHECK((data & GIC_MAP_MSK) <= GIC_CPU_INT_MAX);
316         gic->irq_state[irq_src].map_pin = data & GIC_MAP_TO_PIN_REG_MSK;
317         break;
318     case GIC_SH_MAP0_VP_OFS ... GIC_SH_MAP255_VP_LAST_OFS:
319         /* up to 32 bytes per a pin */
320         irq_src = (addr - GIC_SH_MAP0_VP_OFS) / 32;
321         OFFSET_CHECK(irq_src < gic->num_irq);
322         data = data ? ctz64(data) : -1;
323         OFFSET_CHECK(data < gic->num_vps);
324         gic->irq_state[irq_src].map_vp = data;
325         break;
326     case VP_LOCAL_SECTION_OFS ... (VP_LOCAL_SECTION_OFS + GIC_VL_BRK_GROUP):
327         gic_write_vp(gic, vp_index, addr - VP_LOCAL_SECTION_OFS, data, size);
328         break;
329     case VP_OTHER_SECTION_OFS ... (VP_OTHER_SECTION_OFS + GIC_VL_BRK_GROUP):
330         other_index = gic->vps[vp_index].other_addr;
331         gic_write_vp(gic, other_index, addr - VP_OTHER_SECTION_OFS, data, size);
332         break;
333     case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERLO:
334     case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERHI:
335         /* do nothing. Read-only section */
336         break;
337     default:
338         qemu_log_mask(LOG_UNIMP, "Write %d bytes at GIC offset 0x%" PRIx64
339                       " 0x%08" PRIx64 "\n", size, addr, data);
340         break;
341     }
342     return;
343 bad_offset:
344     qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr);
345 }
346 
347 static void gic_reset(void *opaque)
348 {
349     int i;
350     MIPSGICState *gic = (MIPSGICState *) opaque;
351     int numintrs = (gic->num_irq / 8) - 1;
352 
353     gic->sh_config = /* COUNTSTOP = 0 it is accessible via MIPSGICTimer*/
354                      /* CounterHi not implemented */
355                      (0            << GIC_SH_CONFIG_COUNTBITS_SHF) |
356                      (numintrs     << GIC_SH_CONFIG_NUMINTRS_SHF)  |
357                      (gic->num_vps << GIC_SH_CONFIG_PVPS_SHF);
358     for (i = 0; i < gic->num_vps; i++) {
359         gic->vps[i].ctl         = 0x0;
360         gic->vps[i].pend        = 0x0;
361         /* PERFCNT, TIMER and WD not implemented */
362         gic->vps[i].mask        = 0x32;
363         gic->vps[i].compare_map = GIC_MAP_TO_PIN_MSK;
364         mips_gictimer_store_vp_compare(gic->gic_timer, i, 0xffffffff);
365         gic->vps[i].other_addr  = 0x0;
366     }
367     for (i = 0; i < gic->num_irq; i++) {
368         gic->irq_state[i].enabled = 0;
369         gic->irq_state[i].pending = 0;
370         gic->irq_state[i].map_pin = GIC_MAP_TO_PIN_MSK;
371         gic->irq_state[i].map_vp  = -1;
372     }
373     mips_gictimer_store_sh_count(gic->gic_timer, 0);
374     /* COUNTSTOP = 0 */
375     mips_gictimer_start_count(gic->gic_timer);
376 }
377 
378 static const MemoryRegionOps gic_ops = {
379     .read = gic_read,
380     .write = gic_write,
381     .endianness = DEVICE_NATIVE_ENDIAN,
382     .impl = {
383         .max_access_size = 8,
384     },
385 };
386 
387 static void mips_gic_init(Object *obj)
388 {
389     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
390     MIPSGICState *s = MIPS_GIC(obj);
391 
392     memory_region_init_io(&s->mr, OBJECT(s), &gic_ops, s,
393                           "mips-gic", GIC_ADDRSPACE_SZ);
394     sysbus_init_mmio(sbd, &s->mr);
395     qemu_register_reset(gic_reset, s);
396 }
397 
398 static void mips_gic_realize(DeviceState *dev, Error **errp)
399 {
400     MIPSGICState *s = MIPS_GIC(dev);
401     CPUState *cs = first_cpu;
402     int i;
403 
404     if (s->num_vps > GIC_MAX_VPS) {
405         error_setg(errp, "Exceeded maximum CPUs %d", s->num_vps);
406         return;
407     }
408     if ((s->num_irq > GIC_MAX_INTRS) || (s->num_irq % 8) || (s->num_irq <= 0)) {
409         error_setg(errp, "GIC supports up to %d external interrupts in "
410                    "multiples of 8 : %d", GIC_MAX_INTRS, s->num_irq);
411         return;
412     }
413     s->vps = g_new(MIPSGICVPState, s->num_vps);
414     s->irq_state = g_new(MIPSGICIRQState, s->num_irq);
415     /* Register the env for all VPs with the GIC */
416     for (i = 0; i < s->num_vps; i++) {
417         if (cs != NULL) {
418             s->vps[i].env = cs->env_ptr;
419             cs = CPU_NEXT(cs);
420         } else {
421             error_setg(errp,
422                "Unable to initialize GIC, CPUState for CPU#%d not valid.", i);
423             return;
424         }
425     }
426     s->gic_timer = mips_gictimer_init(s, s->num_vps, gic_timer_expire_cb);
427     qdev_init_gpio_in(dev, gic_set_irq, s->num_irq);
428     for (i = 0; i < s->num_irq; i++) {
429         s->irq_state[i].irq = qdev_get_gpio_in(dev, i);
430     }
431 }
432 
433 static Property mips_gic_properties[] = {
434     DEFINE_PROP_INT32("num-vp", MIPSGICState, num_vps, 1),
435     DEFINE_PROP_INT32("num-irq", MIPSGICState, num_irq, 256),
436     DEFINE_PROP_END_OF_LIST(),
437 };
438 
439 static void mips_gic_class_init(ObjectClass *klass, void *data)
440 {
441     DeviceClass *dc = DEVICE_CLASS(klass);
442 
443     dc->props = mips_gic_properties;
444     dc->realize = mips_gic_realize;
445 }
446 
447 static const TypeInfo mips_gic_info = {
448     .name          = TYPE_MIPS_GIC,
449     .parent        = TYPE_SYS_BUS_DEVICE,
450     .instance_size = sizeof(MIPSGICState),
451     .instance_init = mips_gic_init,
452     .class_init    = mips_gic_class_init,
453 };
454 
455 static void mips_gic_register_types(void)
456 {
457     type_register_static(&mips_gic_info);
458 }
459 
460 type_init(mips_gic_register_types)
461