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
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 * Authors: Sanjay Lal <sanjayl@kymasys.com>
9 * Copyright (C) 2016 Imagination Technologies
12 #include "qemu/osdep.h"
14 #include "qemu/module.h"
15 #include "qapi/error.h"
16 #include "hw/sysbus.h"
17 #include "exec/memory.h"
18 #include "sysemu/kvm.h"
19 #include "sysemu/reset.h"
21 #include "hw/intc/mips_gic.h"
23 #include "hw/qdev-properties.h"
25 static void mips_gic_set_vp_irq(MIPSGICState
*gic
, int vp
, int pin
)
30 /* ORing pending registers sharing same pin */
31 for (i
= 0; i
< gic
->num_irq
; i
++) {
32 if ((gic
->irq_state
[i
].map_pin
& GIC_MAP_MSK
) == pin
&&
33 gic
->irq_state
[i
].map_vp
== vp
&&
34 gic
->irq_state
[i
].enabled
) {
35 ored_level
|= gic
->irq_state
[i
].pending
;
38 /* no need to iterate all interrupts */
42 if (((gic
->vps
[vp
].compare_map
& GIC_MAP_MSK
) == pin
) &&
43 (gic
->vps
[vp
].mask
& GIC_VP_MASK_CMP_MSK
)) {
44 /* ORing with local pending register (count/compare) */
45 ored_level
|= (gic
->vps
[vp
].pend
& GIC_VP_MASK_CMP_MSK
) >>
49 kvm_mips_set_ipi_interrupt(env_archcpu(gic
->vps
[vp
].env
),
50 pin
+ GIC_CPU_PIN_OFFSET
,
53 qemu_set_irq(gic
->vps
[vp
].env
->irq
[pin
+ GIC_CPU_PIN_OFFSET
],
58 static void gic_update_pin_for_irq(MIPSGICState
*gic
, int n_IRQ
)
60 int vp
= gic
->irq_state
[n_IRQ
].map_vp
;
61 int pin
= gic
->irq_state
[n_IRQ
].map_pin
& GIC_MAP_MSK
;
63 if (vp
< 0 || vp
>= gic
->num_vps
) {
66 mips_gic_set_vp_irq(gic
, vp
, pin
);
69 static void gic_set_irq(void *opaque
, int n_IRQ
, int level
)
71 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
73 gic
->irq_state
[n_IRQ
].pending
= (uint8_t) level
;
74 if (!gic
->irq_state
[n_IRQ
].enabled
) {
75 /* GIC interrupt source disabled */
78 gic_update_pin_for_irq(gic
, n_IRQ
);
81 #define OFFSET_CHECK(c) \
88 /* GIC Read VP Local/Other Registers */
89 static uint64_t gic_read_vp(MIPSGICState
*gic
, uint32_t vp_index
, hwaddr addr
,
94 return gic
->vps
[vp_index
].ctl
;
96 mips_gictimer_get_sh_count(gic
->gic_timer
);
97 return gic
->vps
[vp_index
].pend
;
99 return gic
->vps
[vp_index
].mask
;
100 case GIC_VP_COMPARE_MAP_OFS
:
101 return gic
->vps
[vp_index
].compare_map
;
102 case GIC_VP_OTHER_ADDR_OFS
:
103 return gic
->vps
[vp_index
].other_addr
;
104 case GIC_VP_IDENT_OFS
:
106 case GIC_VP_COMPARE_LO_OFS
:
107 return mips_gictimer_get_vp_compare(gic
->gic_timer
, vp_index
);
108 case GIC_VP_COMPARE_HI_OFS
:
111 qemu_log_mask(LOG_UNIMP
, "Read %d bytes at GIC offset LOCAL/OTHER 0x%"
112 PRIx64
"\n", size
, addr
);
118 static uint64_t gic_read(void *opaque
, hwaddr addr
, unsigned size
)
120 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
121 uint32_t vp_index
= current_cpu
->cpu_index
;
123 int i
, base
, irq_src
;
124 uint32_t other_index
;
127 case GIC_SH_CONFIG_OFS
:
128 ret
= gic
->sh_config
| (mips_gictimer_get_countstop(gic
->gic_timer
) <<
129 GIC_SH_CONFIG_COUNTSTOP_SHF
);
131 case GIC_SH_COUNTERLO_OFS
:
132 ret
= mips_gictimer_get_sh_count(gic
->gic_timer
);
134 case GIC_SH_COUNTERHI_OFS
:
137 case GIC_SH_PEND_OFS
... GIC_SH_PEND_LAST_OFS
:
138 /* each bit represents pending status for an interrupt pin */
139 base
= (addr
- GIC_SH_PEND_OFS
) * 8;
140 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
141 for (i
= 0; i
< size
* 8; i
++) {
142 ret
|= (uint64_t) (gic
->irq_state
[base
+ i
].pending
) << i
;
145 case GIC_SH_MASK_OFS
... GIC_SH_MASK_LAST_OFS
:
146 /* each bit represents status for an interrupt pin */
147 base
= (addr
- GIC_SH_MASK_OFS
) * 8;
148 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
149 for (i
= 0; i
< size
* 8; i
++) {
150 ret
|= (uint64_t) (gic
->irq_state
[base
+ i
].enabled
) << i
;
153 case GIC_SH_MAP0_PIN_OFS
... GIC_SH_MAP255_PIN_OFS
:
154 /* 32 bits per a pin */
155 irq_src
= (addr
- GIC_SH_MAP0_PIN_OFS
) / 4;
156 OFFSET_CHECK(irq_src
< gic
->num_irq
);
157 ret
= gic
->irq_state
[irq_src
].map_pin
;
159 case GIC_SH_MAP0_VP_OFS
... GIC_SH_MAP255_VP_LAST_OFS
:
160 /* up to 32 bytes per a pin */
161 irq_src
= (addr
- GIC_SH_MAP0_VP_OFS
) / 32;
162 OFFSET_CHECK(irq_src
< gic
->num_irq
);
163 if ((gic
->irq_state
[irq_src
].map_vp
) >= 0) {
164 ret
= (uint64_t) 1 << (gic
->irq_state
[irq_src
].map_vp
);
169 /* VP-Local Register */
170 case VP_LOCAL_SECTION_OFS
... (VP_LOCAL_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
171 ret
= gic_read_vp(gic
, vp_index
, addr
- VP_LOCAL_SECTION_OFS
, size
);
173 /* VP-Other Register */
174 case VP_OTHER_SECTION_OFS
... (VP_OTHER_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
175 other_index
= gic
->vps
[vp_index
].other_addr
;
176 ret
= gic_read_vp(gic
, other_index
, addr
- VP_OTHER_SECTION_OFS
, size
);
178 /* User-Mode Visible section */
179 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERLO
:
180 ret
= mips_gictimer_get_sh_count(gic
->gic_timer
);
182 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERHI
:
186 qemu_log_mask(LOG_UNIMP
, "Read %d bytes at GIC offset 0x%" PRIx64
"\n",
192 qemu_log_mask(LOG_GUEST_ERROR
, "Wrong GIC offset at 0x%" PRIx64
"\n", addr
);
196 static void gic_timer_expire_cb(void *opaque
, uint32_t vp_index
)
198 MIPSGICState
*gic
= opaque
;
200 gic
->vps
[vp_index
].pend
|= (1 << GIC_LOCAL_INT_COMPARE
);
201 if (gic
->vps
[vp_index
].pend
&
202 (gic
->vps
[vp_index
].mask
& GIC_VP_MASK_CMP_MSK
)) {
203 if (gic
->vps
[vp_index
].compare_map
& GIC_MAP_TO_PIN_MSK
) {
204 /* it is safe to set the irq high regardless of other GIC IRQs */
205 uint32_t pin
= (gic
->vps
[vp_index
].compare_map
& GIC_MAP_MSK
);
206 qemu_irq_raise(gic
->vps
[vp_index
].env
->irq
207 [pin
+ GIC_CPU_PIN_OFFSET
]);
212 static void gic_timer_store_vp_compare(MIPSGICState
*gic
, uint32_t vp_index
,
215 gic
->vps
[vp_index
].pend
&= ~(1 << GIC_LOCAL_INT_COMPARE
);
216 if (gic
->vps
[vp_index
].compare_map
& GIC_MAP_TO_PIN_MSK
) {
217 uint32_t pin
= (gic
->vps
[vp_index
].compare_map
& GIC_MAP_MSK
);
218 mips_gic_set_vp_irq(gic
, vp_index
, pin
);
220 mips_gictimer_store_vp_compare(gic
->gic_timer
, vp_index
, compare
);
223 /* GIC Write VP Local/Other Registers */
224 static void gic_write_vp(MIPSGICState
*gic
, uint32_t vp_index
, hwaddr addr
,
225 uint64_t data
, unsigned size
)
229 /* EIC isn't supported */
231 case GIC_VP_RMASK_OFS
:
232 gic
->vps
[vp_index
].mask
&= ~(data
& GIC_VP_SET_RESET_MSK
) &
233 GIC_VP_SET_RESET_MSK
;
235 case GIC_VP_SMASK_OFS
:
236 gic
->vps
[vp_index
].mask
|= data
& GIC_VP_SET_RESET_MSK
;
238 case GIC_VP_COMPARE_MAP_OFS
:
239 /* EIC isn't supported */
240 OFFSET_CHECK((data
& GIC_MAP_MSK
) <= GIC_CPU_INT_MAX
);
241 gic
->vps
[vp_index
].compare_map
= data
& GIC_MAP_TO_PIN_REG_MSK
;
243 case GIC_VP_OTHER_ADDR_OFS
:
244 OFFSET_CHECK(data
< gic
->num_vps
);
245 gic
->vps
[vp_index
].other_addr
= data
;
247 case GIC_VP_COMPARE_LO_OFS
:
248 gic_timer_store_vp_compare(gic
, vp_index
, data
);
251 qemu_log_mask(LOG_UNIMP
, "Write %d bytes at GIC offset LOCAL/OTHER "
252 "0x%" PRIx64
" 0x%08" PRIx64
"\n", size
, addr
, data
);
257 qemu_log_mask(LOG_GUEST_ERROR
, "Wrong GIC offset at 0x%" PRIx64
"\n", addr
);
261 static void gic_write(void *opaque
, hwaddr addr
, uint64_t data
, unsigned size
)
264 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
265 uint32_t vp_index
= current_cpu
->cpu_index
;
266 int i
, base
, irq_src
;
267 uint32_t other_index
;
270 case GIC_SH_CONFIG_OFS
:
272 uint32_t pre_cntstop
= mips_gictimer_get_countstop(gic
->gic_timer
);
273 uint32_t new_cntstop
= (data
& GIC_SH_CONFIG_COUNTSTOP_MSK
) >>
274 GIC_SH_CONFIG_COUNTSTOP_SHF
;
275 if (pre_cntstop
!= new_cntstop
) {
276 if (new_cntstop
== 1) {
277 mips_gictimer_stop_count(gic
->gic_timer
);
279 mips_gictimer_start_count(gic
->gic_timer
);
284 case GIC_SH_COUNTERLO_OFS
:
285 if (mips_gictimer_get_countstop(gic
->gic_timer
)) {
286 mips_gictimer_store_sh_count(gic
->gic_timer
, data
);
289 case GIC_SH_RMASK_OFS
... GIC_SH_RMASK_LAST_OFS
:
290 /* up to 64 bits per a pin */
291 base
= (addr
- GIC_SH_RMASK_OFS
) * 8;
292 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
293 for (i
= 0; i
< size
* 8; i
++) {
294 gic
->irq_state
[base
+ i
].enabled
&= !((data
>> i
) & 1);
295 gic_update_pin_for_irq(gic
, base
+ i
);
298 case GIC_SH_WEDGE_OFS
:
299 /* Figure out which VP/HW Interrupt this maps to */
300 intr
= data
& ~GIC_SH_WEDGE_RW_MSK
;
301 /* Mask/Enabled Checks */
302 OFFSET_CHECK(intr
< gic
->num_irq
);
303 if (data
& GIC_SH_WEDGE_RW_MSK
) {
304 gic_set_irq(gic
, intr
, 1);
306 gic_set_irq(gic
, intr
, 0);
309 case GIC_SH_SMASK_OFS
... GIC_SH_SMASK_LAST_OFS
:
310 /* up to 64 bits per a pin */
311 base
= (addr
- GIC_SH_SMASK_OFS
) * 8;
312 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
313 for (i
= 0; i
< size
* 8; i
++) {
314 gic
->irq_state
[base
+ i
].enabled
|= (data
>> i
) & 1;
315 gic_update_pin_for_irq(gic
, base
+ i
);
318 case GIC_SH_MAP0_PIN_OFS
... GIC_SH_MAP255_PIN_OFS
:
319 /* 32 bits per a pin */
320 irq_src
= (addr
- GIC_SH_MAP0_PIN_OFS
) / 4;
321 OFFSET_CHECK(irq_src
< gic
->num_irq
);
322 /* EIC isn't supported */
323 OFFSET_CHECK((data
& GIC_MAP_MSK
) <= GIC_CPU_INT_MAX
);
324 gic
->irq_state
[irq_src
].map_pin
= data
& GIC_MAP_TO_PIN_REG_MSK
;
326 case GIC_SH_MAP0_VP_OFS
... GIC_SH_MAP255_VP_LAST_OFS
:
327 /* up to 32 bytes per a pin */
328 irq_src
= (addr
- GIC_SH_MAP0_VP_OFS
) / 32;
329 OFFSET_CHECK(irq_src
< gic
->num_irq
);
330 data
= data
? ctz64(data
) : -1;
331 OFFSET_CHECK(data
< gic
->num_vps
);
332 gic
->irq_state
[irq_src
].map_vp
= data
;
334 case VP_LOCAL_SECTION_OFS
... (VP_LOCAL_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
335 gic_write_vp(gic
, vp_index
, addr
- VP_LOCAL_SECTION_OFS
, data
, size
);
337 case VP_OTHER_SECTION_OFS
... (VP_OTHER_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
338 other_index
= gic
->vps
[vp_index
].other_addr
;
339 gic_write_vp(gic
, other_index
, addr
- VP_OTHER_SECTION_OFS
, data
, size
);
341 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERLO
:
342 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERHI
:
343 /* do nothing. Read-only section */
346 qemu_log_mask(LOG_UNIMP
, "Write %d bytes at GIC offset 0x%" PRIx64
347 " 0x%08" PRIx64
"\n", size
, addr
, data
);
352 qemu_log_mask(LOG_GUEST_ERROR
, "Wrong GIC offset at 0x%" PRIx64
"\n", addr
);
355 static void gic_reset(void *opaque
)
358 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
359 int numintrs
= (gic
->num_irq
/ 8) - 1;
361 gic
->sh_config
= /* COUNTSTOP = 0 it is accessible via MIPSGICTimer*/
362 /* CounterHi not implemented */
363 (0 << GIC_SH_CONFIG_COUNTBITS_SHF
) |
364 (numintrs
<< GIC_SH_CONFIG_NUMINTRS_SHF
) |
365 (gic
->num_vps
<< GIC_SH_CONFIG_PVPS_SHF
);
366 for (i
= 0; i
< gic
->num_vps
; i
++) {
367 gic
->vps
[i
].ctl
= 0x0;
368 gic
->vps
[i
].pend
= 0x0;
369 /* PERFCNT, TIMER and WD not implemented */
370 gic
->vps
[i
].mask
= 0x32;
371 gic
->vps
[i
].compare_map
= GIC_MAP_TO_PIN_MSK
;
372 mips_gictimer_store_vp_compare(gic
->gic_timer
, i
, 0xffffffff);
373 gic
->vps
[i
].other_addr
= 0x0;
375 for (i
= 0; i
< gic
->num_irq
; i
++) {
376 gic
->irq_state
[i
].enabled
= 0;
377 gic
->irq_state
[i
].pending
= 0;
378 gic
->irq_state
[i
].map_pin
= GIC_MAP_TO_PIN_MSK
;
379 gic
->irq_state
[i
].map_vp
= -1;
381 mips_gictimer_store_sh_count(gic
->gic_timer
, 0);
383 mips_gictimer_start_count(gic
->gic_timer
);
386 static const MemoryRegionOps gic_ops
= {
389 .endianness
= DEVICE_NATIVE_ENDIAN
,
391 .max_access_size
= 8,
395 static void mips_gic_init(Object
*obj
)
397 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
398 MIPSGICState
*s
= MIPS_GIC(obj
);
400 memory_region_init_io(&s
->mr
, OBJECT(s
), &gic_ops
, s
,
401 "mips-gic", GIC_ADDRSPACE_SZ
);
402 sysbus_init_mmio(sbd
, &s
->mr
);
403 qemu_register_reset(gic_reset
, s
);
406 static void mips_gic_realize(DeviceState
*dev
, Error
**errp
)
408 MIPSGICState
*s
= MIPS_GIC(dev
);
409 CPUState
*cs
= first_cpu
;
412 if (s
->num_vps
> GIC_MAX_VPS
) {
413 error_setg(errp
, "Exceeded maximum CPUs %d", s
->num_vps
);
416 if ((s
->num_irq
> GIC_MAX_INTRS
) || (s
->num_irq
% 8) || (s
->num_irq
<= 0)) {
417 error_setg(errp
, "GIC supports up to %d external interrupts in "
418 "multiples of 8 : %d", GIC_MAX_INTRS
, s
->num_irq
);
421 s
->vps
= g_new(MIPSGICVPState
, s
->num_vps
);
422 s
->irq_state
= g_new(MIPSGICIRQState
, s
->num_irq
);
423 /* Register the env for all VPs with the GIC */
424 for (i
= 0; i
< s
->num_vps
; i
++) {
426 s
->vps
[i
].env
= cpu_env(cs
);
430 "Unable to initialize GIC, CPUState for CPU#%d not valid.", i
);
434 s
->gic_timer
= mips_gictimer_init(s
, s
->num_vps
, gic_timer_expire_cb
);
435 qdev_init_gpio_in(dev
, gic_set_irq
, s
->num_irq
);
436 for (i
= 0; i
< s
->num_irq
; i
++) {
437 s
->irq_state
[i
].irq
= qdev_get_gpio_in(dev
, i
);
441 static Property mips_gic_properties
[] = {
442 DEFINE_PROP_UINT32("num-vp", MIPSGICState
, num_vps
, 1),
443 DEFINE_PROP_UINT32("num-irq", MIPSGICState
, num_irq
, 256),
444 DEFINE_PROP_END_OF_LIST(),
447 static void mips_gic_class_init(ObjectClass
*klass
, void *data
)
449 DeviceClass
*dc
= DEVICE_CLASS(klass
);
451 device_class_set_props(dc
, mips_gic_properties
);
452 dc
->realize
= mips_gic_realize
;
455 static const TypeInfo mips_gic_info
= {
456 .name
= TYPE_MIPS_GIC
,
457 .parent
= TYPE_SYS_BUS_DEVICE
,
458 .instance_size
= sizeof(MIPSGICState
),
459 .instance_init
= mips_gic_init
,
460 .class_init
= mips_gic_class_init
,
463 static void mips_gic_register_types(void)
465 type_register_static(&mips_gic_info
);
468 type_init(mips_gic_register_types
)