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 "qapi/error.h"
16 #include "hw/sysbus.h"
17 #include "exec/memory.h"
18 #include "sysemu/sysemu.h"
19 #include "sysemu/kvm.h"
21 #include "hw/intc/mips_gic.h"
23 static void mips_gic_set_vp_irq(MIPSGICState
*gic
, int vp
, int pin
)
28 /* ORing pending registers sharing same pin */
29 for (i
= 0; i
< gic
->num_irq
; i
++) {
30 if ((gic
->irq_state
[i
].map_pin
& GIC_MAP_MSK
) == pin
&&
31 gic
->irq_state
[i
].map_vp
== vp
&&
32 gic
->irq_state
[i
].enabled
) {
33 ored_level
|= gic
->irq_state
[i
].pending
;
36 /* no need to iterate all interrupts */
40 if (((gic
->vps
[vp
].compare_map
& GIC_MAP_MSK
) == pin
) &&
41 (gic
->vps
[vp
].mask
& GIC_VP_MASK_CMP_MSK
)) {
42 /* ORing with local pending register (count/compare) */
43 ored_level
|= (gic
->vps
[vp
].pend
& GIC_VP_MASK_CMP_MSK
) >>
47 kvm_mips_set_ipi_interrupt(env_archcpu(gic
->vps
[vp
].env
),
48 pin
+ GIC_CPU_PIN_OFFSET
,
51 qemu_set_irq(gic
->vps
[vp
].env
->irq
[pin
+ GIC_CPU_PIN_OFFSET
],
56 static void gic_update_pin_for_irq(MIPSGICState
*gic
, int n_IRQ
)
58 int vp
= gic
->irq_state
[n_IRQ
].map_vp
;
59 int pin
= gic
->irq_state
[n_IRQ
].map_pin
& GIC_MAP_MSK
;
61 if (vp
< 0 || vp
>= gic
->num_vps
) {
64 mips_gic_set_vp_irq(gic
, vp
, pin
);
67 static void gic_set_irq(void *opaque
, int n_IRQ
, int level
)
69 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
71 gic
->irq_state
[n_IRQ
].pending
= (uint8_t) level
;
72 if (!gic
->irq_state
[n_IRQ
].enabled
) {
73 /* GIC interrupt source disabled */
76 gic_update_pin_for_irq(gic
, n_IRQ
);
79 #define OFFSET_CHECK(c) \
86 /* GIC Read VP Local/Other Registers */
87 static uint64_t gic_read_vp(MIPSGICState
*gic
, uint32_t vp_index
, hwaddr addr
,
92 return gic
->vps
[vp_index
].ctl
;
94 mips_gictimer_get_sh_count(gic
->gic_timer
);
95 return gic
->vps
[vp_index
].pend
;
97 return gic
->vps
[vp_index
].mask
;
98 case GIC_VP_COMPARE_MAP_OFS
:
99 return gic
->vps
[vp_index
].compare_map
;
100 case GIC_VP_OTHER_ADDR_OFS
:
101 return gic
->vps
[vp_index
].other_addr
;
102 case GIC_VP_IDENT_OFS
:
104 case GIC_VP_COMPARE_LO_OFS
:
105 return mips_gictimer_get_vp_compare(gic
->gic_timer
, vp_index
);
106 case GIC_VP_COMPARE_HI_OFS
:
109 qemu_log_mask(LOG_UNIMP
, "Read %d bytes at GIC offset LOCAL/OTHER 0x%"
110 PRIx64
"\n", size
, addr
);
116 static uint64_t gic_read(void *opaque
, hwaddr addr
, unsigned size
)
118 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
119 uint32_t vp_index
= current_cpu
->cpu_index
;
121 int i
, base
, irq_src
;
122 uint32_t other_index
;
125 case GIC_SH_CONFIG_OFS
:
126 ret
= gic
->sh_config
| (mips_gictimer_get_countstop(gic
->gic_timer
) <<
127 GIC_SH_CONFIG_COUNTSTOP_SHF
);
129 case GIC_SH_COUNTERLO_OFS
:
130 ret
= mips_gictimer_get_sh_count(gic
->gic_timer
);
132 case GIC_SH_COUNTERHI_OFS
:
135 case GIC_SH_PEND_OFS
... GIC_SH_PEND_LAST_OFS
:
136 /* each bit represents pending status for an interrupt pin */
137 base
= (addr
- GIC_SH_PEND_OFS
) * 8;
138 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
139 for (i
= 0; i
< size
* 8; i
++) {
140 ret
|= (uint64_t) (gic
->irq_state
[base
+ i
].pending
) << i
;
143 case GIC_SH_MASK_OFS
... GIC_SH_MASK_LAST_OFS
:
144 /* each bit represents status for an interrupt pin */
145 base
= (addr
- GIC_SH_MASK_OFS
) * 8;
146 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
147 for (i
= 0; i
< size
* 8; i
++) {
148 ret
|= (uint64_t) (gic
->irq_state
[base
+ i
].enabled
) << i
;
151 case GIC_SH_MAP0_PIN_OFS
... GIC_SH_MAP255_PIN_OFS
:
152 /* 32 bits per a pin */
153 irq_src
= (addr
- GIC_SH_MAP0_PIN_OFS
) / 4;
154 OFFSET_CHECK(irq_src
< gic
->num_irq
);
155 ret
= gic
->irq_state
[irq_src
].map_pin
;
157 case GIC_SH_MAP0_VP_OFS
... GIC_SH_MAP255_VP_LAST_OFS
:
158 /* up to 32 bytes per a pin */
159 irq_src
= (addr
- GIC_SH_MAP0_VP_OFS
) / 32;
160 OFFSET_CHECK(irq_src
< gic
->num_irq
);
161 if ((gic
->irq_state
[irq_src
].map_vp
) >= 0) {
162 ret
= (uint64_t) 1 << (gic
->irq_state
[irq_src
].map_vp
);
167 /* VP-Local Register */
168 case VP_LOCAL_SECTION_OFS
... (VP_LOCAL_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
169 ret
= gic_read_vp(gic
, vp_index
, addr
- VP_LOCAL_SECTION_OFS
, size
);
171 /* VP-Other Register */
172 case VP_OTHER_SECTION_OFS
... (VP_OTHER_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
173 other_index
= gic
->vps
[vp_index
].other_addr
;
174 ret
= gic_read_vp(gic
, other_index
, addr
- VP_OTHER_SECTION_OFS
, size
);
176 /* User-Mode Visible section */
177 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERLO
:
178 ret
= mips_gictimer_get_sh_count(gic
->gic_timer
);
180 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERHI
:
184 qemu_log_mask(LOG_UNIMP
, "Read %d bytes at GIC offset 0x%" PRIx64
"\n",
190 qemu_log_mask(LOG_GUEST_ERROR
, "Wrong GIC offset at 0x%" PRIx64
"\n", addr
);
194 static void gic_timer_expire_cb(void *opaque
, uint32_t vp_index
)
196 MIPSGICState
*gic
= opaque
;
198 gic
->vps
[vp_index
].pend
|= (1 << GIC_LOCAL_INT_COMPARE
);
199 if (gic
->vps
[vp_index
].pend
&
200 (gic
->vps
[vp_index
].mask
& GIC_VP_MASK_CMP_MSK
)) {
201 if (gic
->vps
[vp_index
].compare_map
& GIC_MAP_TO_PIN_MSK
) {
202 /* it is safe to set the irq high regardless of other GIC IRQs */
203 uint32_t pin
= (gic
->vps
[vp_index
].compare_map
& GIC_MAP_MSK
);
204 qemu_irq_raise(gic
->vps
[vp_index
].env
->irq
205 [pin
+ GIC_CPU_PIN_OFFSET
]);
210 static void gic_timer_store_vp_compare(MIPSGICState
*gic
, uint32_t vp_index
,
213 gic
->vps
[vp_index
].pend
&= ~(1 << GIC_LOCAL_INT_COMPARE
);
214 if (gic
->vps
[vp_index
].compare_map
& GIC_MAP_TO_PIN_MSK
) {
215 uint32_t pin
= (gic
->vps
[vp_index
].compare_map
& GIC_MAP_MSK
);
216 mips_gic_set_vp_irq(gic
, vp_index
, pin
);
218 mips_gictimer_store_vp_compare(gic
->gic_timer
, vp_index
, compare
);
221 /* GIC Write VP Local/Other Registers */
222 static void gic_write_vp(MIPSGICState
*gic
, uint32_t vp_index
, hwaddr addr
,
223 uint64_t data
, unsigned size
)
227 /* EIC isn't supported */
229 case GIC_VP_RMASK_OFS
:
230 gic
->vps
[vp_index
].mask
&= ~(data
& GIC_VP_SET_RESET_MSK
) &
231 GIC_VP_SET_RESET_MSK
;
233 case GIC_VP_SMASK_OFS
:
234 gic
->vps
[vp_index
].mask
|= data
& GIC_VP_SET_RESET_MSK
;
236 case GIC_VP_COMPARE_MAP_OFS
:
237 /* EIC isn't supported */
238 OFFSET_CHECK((data
& GIC_MAP_MSK
) <= GIC_CPU_INT_MAX
);
239 gic
->vps
[vp_index
].compare_map
= data
& GIC_MAP_TO_PIN_REG_MSK
;
241 case GIC_VP_OTHER_ADDR_OFS
:
242 OFFSET_CHECK(data
< gic
->num_vps
);
243 gic
->vps
[vp_index
].other_addr
= data
;
245 case GIC_VP_COMPARE_LO_OFS
:
246 gic_timer_store_vp_compare(gic
, vp_index
, data
);
249 qemu_log_mask(LOG_UNIMP
, "Write %d bytes at GIC offset LOCAL/OTHER "
250 "0x%" PRIx64
" 0x%08" PRIx64
"\n", size
, addr
, data
);
255 qemu_log_mask(LOG_GUEST_ERROR
, "Wrong GIC offset at 0x%" PRIx64
"\n", addr
);
259 static void gic_write(void *opaque
, hwaddr addr
, uint64_t data
, unsigned size
)
262 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
263 uint32_t vp_index
= current_cpu
->cpu_index
;
264 int i
, base
, irq_src
;
265 uint32_t other_index
;
268 case GIC_SH_CONFIG_OFS
:
270 uint32_t pre_cntstop
= mips_gictimer_get_countstop(gic
->gic_timer
);
271 uint32_t new_cntstop
= (data
& GIC_SH_CONFIG_COUNTSTOP_MSK
) >>
272 GIC_SH_CONFIG_COUNTSTOP_SHF
;
273 if (pre_cntstop
!= new_cntstop
) {
274 if (new_cntstop
== 1) {
275 mips_gictimer_stop_count(gic
->gic_timer
);
277 mips_gictimer_start_count(gic
->gic_timer
);
282 case GIC_SH_COUNTERLO_OFS
:
283 if (mips_gictimer_get_countstop(gic
->gic_timer
)) {
284 mips_gictimer_store_sh_count(gic
->gic_timer
, data
);
287 case GIC_SH_RMASK_OFS
... GIC_SH_RMASK_LAST_OFS
:
288 /* up to 64 bits per a pin */
289 base
= (addr
- GIC_SH_RMASK_OFS
) * 8;
290 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
291 for (i
= 0; i
< size
* 8; i
++) {
292 gic
->irq_state
[base
+ i
].enabled
&= !((data
>> i
) & 1);
293 gic_update_pin_for_irq(gic
, base
+ i
);
296 case GIC_SH_WEDGE_OFS
:
297 /* Figure out which VP/HW Interrupt this maps to */
298 intr
= data
& ~GIC_SH_WEDGE_RW_MSK
;
299 /* Mask/Enabled Checks */
300 OFFSET_CHECK(intr
< gic
->num_irq
);
301 if (data
& GIC_SH_WEDGE_RW_MSK
) {
302 gic_set_irq(gic
, intr
, 1);
304 gic_set_irq(gic
, intr
, 0);
307 case GIC_SH_SMASK_OFS
... GIC_SH_SMASK_LAST_OFS
:
308 /* up to 64 bits per a pin */
309 base
= (addr
- GIC_SH_SMASK_OFS
) * 8;
310 OFFSET_CHECK((base
+ size
* 8) <= gic
->num_irq
);
311 for (i
= 0; i
< size
* 8; i
++) {
312 gic
->irq_state
[base
+ i
].enabled
|= (data
>> i
) & 1;
313 gic_update_pin_for_irq(gic
, base
+ i
);
316 case GIC_SH_MAP0_PIN_OFS
... GIC_SH_MAP255_PIN_OFS
:
317 /* 32 bits per a pin */
318 irq_src
= (addr
- GIC_SH_MAP0_PIN_OFS
) / 4;
319 OFFSET_CHECK(irq_src
< gic
->num_irq
);
320 /* EIC isn't supported */
321 OFFSET_CHECK((data
& GIC_MAP_MSK
) <= GIC_CPU_INT_MAX
);
322 gic
->irq_state
[irq_src
].map_pin
= data
& GIC_MAP_TO_PIN_REG_MSK
;
324 case GIC_SH_MAP0_VP_OFS
... GIC_SH_MAP255_VP_LAST_OFS
:
325 /* up to 32 bytes per a pin */
326 irq_src
= (addr
- GIC_SH_MAP0_VP_OFS
) / 32;
327 OFFSET_CHECK(irq_src
< gic
->num_irq
);
328 data
= data
? ctz64(data
) : -1;
329 OFFSET_CHECK(data
< gic
->num_vps
);
330 gic
->irq_state
[irq_src
].map_vp
= data
;
332 case VP_LOCAL_SECTION_OFS
... (VP_LOCAL_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
333 gic_write_vp(gic
, vp_index
, addr
- VP_LOCAL_SECTION_OFS
, data
, size
);
335 case VP_OTHER_SECTION_OFS
... (VP_OTHER_SECTION_OFS
+ GIC_VL_BRK_GROUP
):
336 other_index
= gic
->vps
[vp_index
].other_addr
;
337 gic_write_vp(gic
, other_index
, addr
- VP_OTHER_SECTION_OFS
, data
, size
);
339 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERLO
:
340 case USM_VISIBLE_SECTION_OFS
+ GIC_USER_MODE_COUNTERHI
:
341 /* do nothing. Read-only section */
344 qemu_log_mask(LOG_UNIMP
, "Write %d bytes at GIC offset 0x%" PRIx64
345 " 0x%08" PRIx64
"\n", size
, addr
, data
);
350 qemu_log_mask(LOG_GUEST_ERROR
, "Wrong GIC offset at 0x%" PRIx64
"\n", addr
);
353 static void gic_reset(void *opaque
)
356 MIPSGICState
*gic
= (MIPSGICState
*) opaque
;
357 int numintrs
= (gic
->num_irq
/ 8) - 1;
359 gic
->sh_config
= /* COUNTSTOP = 0 it is accessible via MIPSGICTimer*/
360 /* CounterHi not implemented */
361 (0 << GIC_SH_CONFIG_COUNTBITS_SHF
) |
362 (numintrs
<< GIC_SH_CONFIG_NUMINTRS_SHF
) |
363 (gic
->num_vps
<< GIC_SH_CONFIG_PVPS_SHF
);
364 for (i
= 0; i
< gic
->num_vps
; i
++) {
365 gic
->vps
[i
].ctl
= 0x0;
366 gic
->vps
[i
].pend
= 0x0;
367 /* PERFCNT, TIMER and WD not implemented */
368 gic
->vps
[i
].mask
= 0x32;
369 gic
->vps
[i
].compare_map
= GIC_MAP_TO_PIN_MSK
;
370 mips_gictimer_store_vp_compare(gic
->gic_timer
, i
, 0xffffffff);
371 gic
->vps
[i
].other_addr
= 0x0;
373 for (i
= 0; i
< gic
->num_irq
; i
++) {
374 gic
->irq_state
[i
].enabled
= 0;
375 gic
->irq_state
[i
].pending
= 0;
376 gic
->irq_state
[i
].map_pin
= GIC_MAP_TO_PIN_MSK
;
377 gic
->irq_state
[i
].map_vp
= -1;
379 mips_gictimer_store_sh_count(gic
->gic_timer
, 0);
381 mips_gictimer_start_count(gic
->gic_timer
);
384 static const MemoryRegionOps gic_ops
= {
387 .endianness
= DEVICE_NATIVE_ENDIAN
,
389 .max_access_size
= 8,
393 static void mips_gic_init(Object
*obj
)
395 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
396 MIPSGICState
*s
= MIPS_GIC(obj
);
398 memory_region_init_io(&s
->mr
, OBJECT(s
), &gic_ops
, s
,
399 "mips-gic", GIC_ADDRSPACE_SZ
);
400 sysbus_init_mmio(sbd
, &s
->mr
);
401 qemu_register_reset(gic_reset
, s
);
404 static void mips_gic_realize(DeviceState
*dev
, Error
**errp
)
406 MIPSGICState
*s
= MIPS_GIC(dev
);
407 CPUState
*cs
= first_cpu
;
410 if (s
->num_vps
> GIC_MAX_VPS
) {
411 error_setg(errp
, "Exceeded maximum CPUs %d", s
->num_vps
);
414 if ((s
->num_irq
> GIC_MAX_INTRS
) || (s
->num_irq
% 8) || (s
->num_irq
<= 0)) {
415 error_setg(errp
, "GIC supports up to %d external interrupts in "
416 "multiples of 8 : %d", GIC_MAX_INTRS
, s
->num_irq
);
419 s
->vps
= g_new(MIPSGICVPState
, s
->num_vps
);
420 s
->irq_state
= g_new(MIPSGICIRQState
, s
->num_irq
);
421 /* Register the env for all VPs with the GIC */
422 for (i
= 0; i
< s
->num_vps
; i
++) {
424 s
->vps
[i
].env
= cs
->env_ptr
;
428 "Unable to initialize GIC, CPUState for CPU#%d not valid.", i
);
432 s
->gic_timer
= mips_gictimer_init(s
, s
->num_vps
, gic_timer_expire_cb
);
433 qdev_init_gpio_in(dev
, gic_set_irq
, s
->num_irq
);
434 for (i
= 0; i
< s
->num_irq
; i
++) {
435 s
->irq_state
[i
].irq
= qdev_get_gpio_in(dev
, i
);
439 static Property mips_gic_properties
[] = {
440 DEFINE_PROP_INT32("num-vp", MIPSGICState
, num_vps
, 1),
441 DEFINE_PROP_INT32("num-irq", MIPSGICState
, num_irq
, 256),
442 DEFINE_PROP_END_OF_LIST(),
445 static void mips_gic_class_init(ObjectClass
*klass
, void *data
)
447 DeviceClass
*dc
= DEVICE_CLASS(klass
);
449 dc
->props
= mips_gic_properties
;
450 dc
->realize
= mips_gic_realize
;
453 static const TypeInfo mips_gic_info
= {
454 .name
= TYPE_MIPS_GIC
,
455 .parent
= TYPE_SYS_BUS_DEVICE
,
456 .instance_size
= sizeof(MIPSGICState
),
457 .instance_init
= mips_gic_init
,
458 .class_init
= mips_gic_class_init
,
461 static void mips_gic_register_types(void)
463 type_register_static(&mips_gic_info
);
466 type_init(mips_gic_register_types
)