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"
17 #include "hw/sysbus.h"
18 #include "exec/memory.h"
19 #include "sysemu/sysemu.h"
20 #include "sysemu/kvm.h"
22 #include "hw/intc/mips_gic.h"
24 static void mips_gic_set_vp_irq(MIPSGICState
*gic
, int vp
, int pin
)
29 /* ORing pending registers sharing same pin */
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
;
37 /* no need to iterate all interrupts */
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
) >>
48 kvm_mips_set_ipi_interrupt(env_archcpu(gic
->vps
[vp
].env
),
49 pin
+ GIC_CPU_PIN_OFFSET
,
52 qemu_set_irq(gic
->vps
[vp
].env
->irq
[pin
+ GIC_CPU_PIN_OFFSET
],
57 static void gic_update_pin_for_irq(MIPSGICState
*gic
, int n_IRQ
)
59 int vp
= gic
->irq_state
[n_IRQ
].map_vp
;
60 int pin
= gic
->irq_state
[n_IRQ
].map_pin
& GIC_MAP_MSK
;
62 if (vp
< 0 || vp
>= gic
->num_vps
) {
65 mips_gic_set_vp_irq(gic
, vp
, pin
);
68 static void gic_set_irq(void *opaque
, int n_IRQ
, int level
)
70 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
72 gic
->irq_state
[n_IRQ
].pending
= (uint8_t) level
;
73 if (!gic
->irq_state
[n_IRQ
].enabled
) {
74 /* GIC interrupt source disabled */
77 gic_update_pin_for_irq(gic
, n_IRQ
);
80 #define OFFSET_CHECK(c) \
87 /* GIC Read VP Local/Other Registers */
88 static uint64_t gic_read_vp(MIPSGICState
*gic
, uint32_t vp_index
, hwaddr addr
,
93 return gic
->vps
[vp_index
].ctl
;
95 mips_gictimer_get_sh_count(gic
->gic_timer
);
96 return gic
->vps
[vp_index
].pend
;
98 return gic
->vps
[vp_index
].mask
;
99 case GIC_VP_COMPARE_MAP_OFS
:
100 return gic
->vps
[vp_index
].compare_map
;
101 case GIC_VP_OTHER_ADDR_OFS
:
102 return gic
->vps
[vp_index
].other_addr
;
103 case GIC_VP_IDENT_OFS
:
105 case GIC_VP_COMPARE_LO_OFS
:
106 return mips_gictimer_get_vp_compare(gic
->gic_timer
, vp_index
);
107 case GIC_VP_COMPARE_HI_OFS
:
110 qemu_log_mask(LOG_UNIMP
, "Read %d bytes at GIC offset LOCAL/OTHER 0x%"
111 PRIx64
"\n", size
, addr
);
117 static uint64_t gic_read(void *opaque
, hwaddr addr
, unsigned size
)
119 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
120 uint32_t vp_index
= current_cpu
->cpu_index
;
122 int i
, base
, irq_src
;
123 uint32_t other_index
;
126 case GIC_SH_CONFIG_OFS
:
127 ret
= gic
->sh_config
| (mips_gictimer_get_countstop(gic
->gic_timer
) <<
128 GIC_SH_CONFIG_COUNTSTOP_SHF
);
130 case GIC_SH_COUNTERLO_OFS
:
131 ret
= mips_gictimer_get_sh_count(gic
->gic_timer
);
133 case GIC_SH_COUNTERHI_OFS
:
136 case GIC_SH_PEND_OFS
... GIC_SH_PEND_LAST_OFS
:
137 /* each bit represents pending status for an interrupt pin */
138 base
= (addr
- GIC_SH_PEND_OFS
) * 8;
139 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
140 for (i
= 0; i
< size
* 8; i
++) {
141 ret
|= (uint64_t) (gic
->irq_state
[base
+ i
].pending
) << i
;
144 case GIC_SH_MASK_OFS
... GIC_SH_MASK_LAST_OFS
:
145 /* each bit represents status for an interrupt pin */
146 base
= (addr
- GIC_SH_MASK_OFS
) * 8;
147 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
148 for (i
= 0; i
< size
* 8; i
++) {
149 ret
|= (uint64_t) (gic
->irq_state
[base
+ i
].enabled
) << i
;
152 case GIC_SH_MAP0_PIN_OFS
... GIC_SH_MAP255_PIN_OFS
:
153 /* 32 bits per a pin */
154 irq_src
= (addr
- GIC_SH_MAP0_PIN_OFS
) / 4;
155 OFFSET_CHECK(irq_src
< gic
->num_irq
);
156 ret
= gic
->irq_state
[irq_src
].map_pin
;
158 case GIC_SH_MAP0_VP_OFS
... GIC_SH_MAP255_VP_LAST_OFS
:
159 /* up to 32 bytes per a pin */
160 irq_src
= (addr
- GIC_SH_MAP0_VP_OFS
) / 32;
161 OFFSET_CHECK(irq_src
< gic
->num_irq
);
162 if ((gic
->irq_state
[irq_src
].map_vp
) >= 0) {
163 ret
= (uint64_t) 1 << (gic
->irq_state
[irq_src
].map_vp
);
168 /* VP-Local Register */
169 case VP_LOCAL_SECTION_OFS
... (VP_LOCAL_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
170 ret
= gic_read_vp(gic
, vp_index
, addr
- VP_LOCAL_SECTION_OFS
, size
);
172 /* VP-Other Register */
173 case VP_OTHER_SECTION_OFS
... (VP_OTHER_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
174 other_index
= gic
->vps
[vp_index
].other_addr
;
175 ret
= gic_read_vp(gic
, other_index
, addr
- VP_OTHER_SECTION_OFS
, size
);
177 /* User-Mode Visible section */
178 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERLO
:
179 ret
= mips_gictimer_get_sh_count(gic
->gic_timer
);
181 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERHI
:
185 qemu_log_mask(LOG_UNIMP
, "Read %d bytes at GIC offset 0x%" PRIx64
"\n",
191 qemu_log_mask(LOG_GUEST_ERROR
, "Wrong GIC offset at 0x%" PRIx64
"\n", addr
);
195 static void gic_timer_expire_cb(void *opaque
, uint32_t vp_index
)
197 MIPSGICState
*gic
= opaque
;
199 gic
->vps
[vp_index
].pend
|= (1 << GIC_LOCAL_INT_COMPARE
);
200 if (gic
->vps
[vp_index
].pend
&
201 (gic
->vps
[vp_index
].mask
& GIC_VP_MASK_CMP_MSK
)) {
202 if (gic
->vps
[vp_index
].compare_map
& GIC_MAP_TO_PIN_MSK
) {
203 /* it is safe to set the irq high regardless of other GIC IRQs */
204 uint32_t pin
= (gic
->vps
[vp_index
].compare_map
& GIC_MAP_MSK
);
205 qemu_irq_raise(gic
->vps
[vp_index
].env
->irq
206 [pin
+ GIC_CPU_PIN_OFFSET
]);
211 static void gic_timer_store_vp_compare(MIPSGICState
*gic
, uint32_t vp_index
,
214 gic
->vps
[vp_index
].pend
&= ~(1 << GIC_LOCAL_INT_COMPARE
);
215 if (gic
->vps
[vp_index
].compare_map
& GIC_MAP_TO_PIN_MSK
) {
216 uint32_t pin
= (gic
->vps
[vp_index
].compare_map
& GIC_MAP_MSK
);
217 mips_gic_set_vp_irq(gic
, vp_index
, pin
);
219 mips_gictimer_store_vp_compare(gic
->gic_timer
, vp_index
, compare
);
222 /* GIC Write VP Local/Other Registers */
223 static void gic_write_vp(MIPSGICState
*gic
, uint32_t vp_index
, hwaddr addr
,
224 uint64_t data
, unsigned size
)
228 /* EIC isn't supported */
230 case GIC_VP_RMASK_OFS
:
231 gic
->vps
[vp_index
].mask
&= ~(data
& GIC_VP_SET_RESET_MSK
) &
232 GIC_VP_SET_RESET_MSK
;
234 case GIC_VP_SMASK_OFS
:
235 gic
->vps
[vp_index
].mask
|= data
& GIC_VP_SET_RESET_MSK
;
237 case GIC_VP_COMPARE_MAP_OFS
:
238 /* EIC isn't supported */
239 OFFSET_CHECK((data
& GIC_MAP_MSK
) <= GIC_CPU_INT_MAX
);
240 gic
->vps
[vp_index
].compare_map
= data
& GIC_MAP_TO_PIN_REG_MSK
;
242 case GIC_VP_OTHER_ADDR_OFS
:
243 OFFSET_CHECK(data
< gic
->num_vps
);
244 gic
->vps
[vp_index
].other_addr
= data
;
246 case GIC_VP_COMPARE_LO_OFS
:
247 gic_timer_store_vp_compare(gic
, vp_index
, data
);
250 qemu_log_mask(LOG_UNIMP
, "Write %d bytes at GIC offset LOCAL/OTHER "
251 "0x%" PRIx64
" 0x%08" PRIx64
"\n", size
, addr
, data
);
256 qemu_log_mask(LOG_GUEST_ERROR
, "Wrong GIC offset at 0x%" PRIx64
"\n", addr
);
260 static void gic_write(void *opaque
, hwaddr addr
, uint64_t data
, unsigned size
)
263 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
264 uint32_t vp_index
= current_cpu
->cpu_index
;
265 int i
, base
, irq_src
;
266 uint32_t other_index
;
269 case GIC_SH_CONFIG_OFS
:
271 uint32_t pre_cntstop
= mips_gictimer_get_countstop(gic
->gic_timer
);
272 uint32_t new_cntstop
= (data
& GIC_SH_CONFIG_COUNTSTOP_MSK
) >>
273 GIC_SH_CONFIG_COUNTSTOP_SHF
;
274 if (pre_cntstop
!= new_cntstop
) {
275 if (new_cntstop
== 1) {
276 mips_gictimer_stop_count(gic
->gic_timer
);
278 mips_gictimer_start_count(gic
->gic_timer
);
283 case GIC_SH_COUNTERLO_OFS
:
284 if (mips_gictimer_get_countstop(gic
->gic_timer
)) {
285 mips_gictimer_store_sh_count(gic
->gic_timer
, data
);
288 case GIC_SH_RMASK_OFS
... GIC_SH_RMASK_LAST_OFS
:
289 /* up to 64 bits per a pin */
290 base
= (addr
- GIC_SH_RMASK_OFS
) * 8;
291 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
292 for (i
= 0; i
< size
* 8; i
++) {
293 gic
->irq_state
[base
+ i
].enabled
&= !((data
>> i
) & 1);
294 gic_update_pin_for_irq(gic
, base
+ i
);
297 case GIC_SH_WEDGE_OFS
:
298 /* Figure out which VP/HW Interrupt this maps to */
299 intr
= data
& ~GIC_SH_WEDGE_RW_MSK
;
300 /* Mask/Enabled Checks */
301 OFFSET_CHECK(intr
< gic
->num_irq
);
302 if (data
& GIC_SH_WEDGE_RW_MSK
) {
303 gic_set_irq(gic
, intr
, 1);
305 gic_set_irq(gic
, intr
, 0);
308 case GIC_SH_SMASK_OFS
... GIC_SH_SMASK_LAST_OFS
:
309 /* up to 64 bits per a pin */
310 base
= (addr
- GIC_SH_SMASK_OFS
) * 8;
311 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
312 for (i
= 0; i
< size
* 8; i
++) {
313 gic
->irq_state
[base
+ i
].enabled
|= (data
>> i
) & 1;
314 gic_update_pin_for_irq(gic
, base
+ i
);
317 case GIC_SH_MAP0_PIN_OFS
... GIC_SH_MAP255_PIN_OFS
:
318 /* 32 bits per a pin */
319 irq_src
= (addr
- GIC_SH_MAP0_PIN_OFS
) / 4;
320 OFFSET_CHECK(irq_src
< gic
->num_irq
);
321 /* EIC isn't supported */
322 OFFSET_CHECK((data
& GIC_MAP_MSK
) <= GIC_CPU_INT_MAX
);
323 gic
->irq_state
[irq_src
].map_pin
= data
& GIC_MAP_TO_PIN_REG_MSK
;
325 case GIC_SH_MAP0_VP_OFS
... GIC_SH_MAP255_VP_LAST_OFS
:
326 /* up to 32 bytes per a pin */
327 irq_src
= (addr
- GIC_SH_MAP0_VP_OFS
) / 32;
328 OFFSET_CHECK(irq_src
< gic
->num_irq
);
329 data
= data
? ctz64(data
) : -1;
330 OFFSET_CHECK(data
< gic
->num_vps
);
331 gic
->irq_state
[irq_src
].map_vp
= data
;
333 case VP_LOCAL_SECTION_OFS
... (VP_LOCAL_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
334 gic_write_vp(gic
, vp_index
, addr
- VP_LOCAL_SECTION_OFS
, data
, size
);
336 case VP_OTHER_SECTION_OFS
... (VP_OTHER_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
337 other_index
= gic
->vps
[vp_index
].other_addr
;
338 gic_write_vp(gic
, other_index
, addr
- VP_OTHER_SECTION_OFS
, data
, size
);
340 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERLO
:
341 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERHI
:
342 /* do nothing. Read-only section */
345 qemu_log_mask(LOG_UNIMP
, "Write %d bytes at GIC offset 0x%" PRIx64
346 " 0x%08" PRIx64
"\n", size
, addr
, data
);
351 qemu_log_mask(LOG_GUEST_ERROR
, "Wrong GIC offset at 0x%" PRIx64
"\n", addr
);
354 static void gic_reset(void *opaque
)
357 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
358 int numintrs
= (gic
->num_irq
/ 8) - 1;
360 gic
->sh_config
= /* COUNTSTOP = 0 it is accessible via MIPSGICTimer*/
361 /* CounterHi not implemented */
362 (0 << GIC_SH_CONFIG_COUNTBITS_SHF
) |
363 (numintrs
<< GIC_SH_CONFIG_NUMINTRS_SHF
) |
364 (gic
->num_vps
<< GIC_SH_CONFIG_PVPS_SHF
);
365 for (i
= 0; i
< gic
->num_vps
; i
++) {
366 gic
->vps
[i
].ctl
= 0x0;
367 gic
->vps
[i
].pend
= 0x0;
368 /* PERFCNT, TIMER and WD not implemented */
369 gic
->vps
[i
].mask
= 0x32;
370 gic
->vps
[i
].compare_map
= GIC_MAP_TO_PIN_MSK
;
371 mips_gictimer_store_vp_compare(gic
->gic_timer
, i
, 0xffffffff);
372 gic
->vps
[i
].other_addr
= 0x0;
374 for (i
= 0; i
< gic
->num_irq
; i
++) {
375 gic
->irq_state
[i
].enabled
= 0;
376 gic
->irq_state
[i
].pending
= 0;
377 gic
->irq_state
[i
].map_pin
= GIC_MAP_TO_PIN_MSK
;
378 gic
->irq_state
[i
].map_vp
= -1;
380 mips_gictimer_store_sh_count(gic
->gic_timer
, 0);
382 mips_gictimer_start_count(gic
->gic_timer
);
385 static const MemoryRegionOps gic_ops
= {
388 .endianness
= DEVICE_NATIVE_ENDIAN
,
390 .max_access_size
= 8,
394 static void mips_gic_init(Object
*obj
)
396 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
397 MIPSGICState
*s
= MIPS_GIC(obj
);
399 memory_region_init_io(&s
->mr
, OBJECT(s
), &gic_ops
, s
,
400 "mips-gic", GIC_ADDRSPACE_SZ
);
401 sysbus_init_mmio(sbd
, &s
->mr
);
402 qemu_register_reset(gic_reset
, s
);
405 static void mips_gic_realize(DeviceState
*dev
, Error
**errp
)
407 MIPSGICState
*s
= MIPS_GIC(dev
);
408 CPUState
*cs
= first_cpu
;
411 if (s
->num_vps
> GIC_MAX_VPS
) {
412 error_setg(errp
, "Exceeded maximum CPUs %d", s
->num_vps
);
415 if ((s
->num_irq
> GIC_MAX_INTRS
) || (s
->num_irq
% 8) || (s
->num_irq
<= 0)) {
416 error_setg(errp
, "GIC supports up to %d external interrupts in "
417 "multiples of 8 : %d", GIC_MAX_INTRS
, s
->num_irq
);
420 s
->vps
= g_new(MIPSGICVPState
, s
->num_vps
);
421 s
->irq_state
= g_new(MIPSGICIRQState
, s
->num_irq
);
422 /* Register the env for all VPs with the GIC */
423 for (i
= 0; i
< s
->num_vps
; i
++) {
425 s
->vps
[i
].env
= cs
->env_ptr
;
429 "Unable to initialize GIC, CPUState for CPU#%d not valid.", i
);
433 s
->gic_timer
= mips_gictimer_init(s
, s
->num_vps
, gic_timer_expire_cb
);
434 qdev_init_gpio_in(dev
, gic_set_irq
, s
->num_irq
);
435 for (i
= 0; i
< s
->num_irq
; i
++) {
436 s
->irq_state
[i
].irq
= qdev_get_gpio_in(dev
, i
);
440 static Property mips_gic_properties
[] = {
441 DEFINE_PROP_INT32("num-vp", MIPSGICState
, num_vps
, 1),
442 DEFINE_PROP_INT32("num-irq", MIPSGICState
, num_irq
, 256),
443 DEFINE_PROP_END_OF_LIST(),
446 static void mips_gic_class_init(ObjectClass
*klass
, void *data
)
448 DeviceClass
*dc
= DEVICE_CLASS(klass
);
450 dc
->props
= mips_gic_properties
;
451 dc
->realize
= mips_gic_realize
;
454 static const TypeInfo mips_gic_info
= {
455 .name
= TYPE_MIPS_GIC
,
456 .parent
= TYPE_SYS_BUS_DEVICE
,
457 .instance_size
= sizeof(MIPSGICState
),
458 .instance_init
= mips_gic_init
,
459 .class_init
= mips_gic_class_init
,
462 static void mips_gic_register_types(void)
464 type_register_static(&mips_gic_info
);
467 type_init(mips_gic_register_types
)