Lines Matching full:gic

25 static void mips_gic_set_vp_irq(MIPSGICState *gic, int vp, int pin)  in mips_gic_set_vp_irq()  argument
31 for (i = 0; i < gic->num_irq; i++) { in mips_gic_set_vp_irq()
32 if ((gic->irq_state[i].map_pin & GIC_MAP_MSK) == pin && in mips_gic_set_vp_irq()
33 gic->irq_state[i].map_vp == vp && in mips_gic_set_vp_irq()
34 gic->irq_state[i].enabled) { in mips_gic_set_vp_irq()
35 ored_level |= gic->irq_state[i].pending; in mips_gic_set_vp_irq()
42 if (((gic->vps[vp].compare_map & GIC_MAP_MSK) == pin) && in mips_gic_set_vp_irq()
43 (gic->vps[vp].mask & GIC_VP_MASK_CMP_MSK)) { in mips_gic_set_vp_irq()
45 ored_level |= (gic->vps[vp].pend & GIC_VP_MASK_CMP_MSK) >> in mips_gic_set_vp_irq()
49 kvm_mips_set_ipi_interrupt(env_archcpu(gic->vps[vp].env), in mips_gic_set_vp_irq()
53 qemu_set_irq(gic->vps[vp].env->irq[pin + GIC_CPU_PIN_OFFSET], in mips_gic_set_vp_irq()
58 static void gic_update_pin_for_irq(MIPSGICState *gic, int n_IRQ) in gic_update_pin_for_irq() argument
60 int vp = gic->irq_state[n_IRQ].map_vp; in gic_update_pin_for_irq()
61 int pin = gic->irq_state[n_IRQ].map_pin & GIC_MAP_MSK; in gic_update_pin_for_irq()
63 if (vp < 0 || vp >= gic->num_vps) { in gic_update_pin_for_irq()
66 mips_gic_set_vp_irq(gic, vp, pin); in gic_update_pin_for_irq()
71 MIPSGICState *gic = (MIPSGICState *) opaque; in gic_set_irq() local
73 gic->irq_state[n_IRQ].pending = (uint8_t) level; in gic_set_irq()
74 if (!gic->irq_state[n_IRQ].enabled) { in gic_set_irq()
75 /* GIC interrupt source disabled */ in gic_set_irq()
78 gic_update_pin_for_irq(gic, n_IRQ); in gic_set_irq()
88 /* GIC Read VP Local/Other Registers */
89 static uint64_t gic_read_vp(MIPSGICState *gic, uint32_t vp_index, hwaddr addr, in gic_read_vp() argument
94 return gic->vps[vp_index].ctl; in gic_read_vp()
96 mips_gictimer_get_sh_count(gic->gic_timer); in gic_read_vp()
97 return gic->vps[vp_index].pend; in gic_read_vp()
99 return gic->vps[vp_index].mask; in gic_read_vp()
101 return gic->vps[vp_index].compare_map; in gic_read_vp()
103 return gic->vps[vp_index].other_addr; in gic_read_vp()
107 return mips_gictimer_get_vp_compare(gic->gic_timer, vp_index); in gic_read_vp()
111 qemu_log_mask(LOG_UNIMP, "Read %d bytes at GIC offset LOCAL/OTHER 0x%" in gic_read_vp()
120 MIPSGICState *gic = (MIPSGICState *) opaque; in gic_read() local
128 ret = gic->sh_config | (mips_gictimer_get_countstop(gic->gic_timer) << in gic_read()
132 ret = mips_gictimer_get_sh_count(gic->gic_timer); in gic_read()
140 OFFSET_CHECK((base + size * 8) <= gic->num_irq); in gic_read()
142 ret |= (uint64_t) (gic->irq_state[base + i].pending) << i; in gic_read()
148 OFFSET_CHECK((base + size * 8) <= gic->num_irq); in gic_read()
150 ret |= (uint64_t) (gic->irq_state[base + i].enabled) << i; in gic_read()
156 OFFSET_CHECK(irq_src < gic->num_irq); in gic_read()
157 ret = gic->irq_state[irq_src].map_pin; in gic_read()
162 OFFSET_CHECK(irq_src < gic->num_irq); in gic_read()
163 if ((gic->irq_state[irq_src].map_vp) >= 0) { in gic_read()
164 ret = (uint64_t) 1 << (gic->irq_state[irq_src].map_vp); in gic_read()
171 ret = gic_read_vp(gic, vp_index, addr - VP_LOCAL_SECTION_OFS, size); in gic_read()
175 other_index = gic->vps[vp_index].other_addr; in gic_read()
176 ret = gic_read_vp(gic, other_index, addr - VP_OTHER_SECTION_OFS, size); in gic_read()
180 ret = mips_gictimer_get_sh_count(gic->gic_timer); in gic_read()
186 qemu_log_mask(LOG_UNIMP, "Read %d bytes at GIC offset 0x%" PRIx64 "\n", in gic_read()
192 qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr); in gic_read()
198 MIPSGICState *gic = opaque; in gic_timer_expire_cb() local
200 gic->vps[vp_index].pend |= (1 << GIC_LOCAL_INT_COMPARE); in gic_timer_expire_cb()
201 if (gic->vps[vp_index].pend & in gic_timer_expire_cb()
202 (gic->vps[vp_index].mask & GIC_VP_MASK_CMP_MSK)) { in gic_timer_expire_cb()
203 if (gic->vps[vp_index].compare_map & GIC_MAP_TO_PIN_MSK) { in gic_timer_expire_cb()
204 /* it is safe to set the irq high regardless of other GIC IRQs */ in gic_timer_expire_cb()
205 uint32_t pin = (gic->vps[vp_index].compare_map & GIC_MAP_MSK); in gic_timer_expire_cb()
206 qemu_irq_raise(gic->vps[vp_index].env->irq in gic_timer_expire_cb()
212 static void gic_timer_store_vp_compare(MIPSGICState *gic, uint32_t vp_index, in gic_timer_store_vp_compare() argument
215 gic->vps[vp_index].pend &= ~(1 << GIC_LOCAL_INT_COMPARE); in gic_timer_store_vp_compare()
216 if (gic->vps[vp_index].compare_map & GIC_MAP_TO_PIN_MSK) { in gic_timer_store_vp_compare()
217 uint32_t pin = (gic->vps[vp_index].compare_map & GIC_MAP_MSK); in gic_timer_store_vp_compare()
218 mips_gic_set_vp_irq(gic, vp_index, pin); in gic_timer_store_vp_compare()
220 mips_gictimer_store_vp_compare(gic->gic_timer, vp_index, compare); in gic_timer_store_vp_compare()
223 /* GIC Write VP Local/Other Registers */
224 static void gic_write_vp(MIPSGICState *gic, uint32_t vp_index, hwaddr addr, in gic_write_vp() argument
232 gic->vps[vp_index].mask &= ~(data & GIC_VP_SET_RESET_MSK) & in gic_write_vp()
236 gic->vps[vp_index].mask |= data & GIC_VP_SET_RESET_MSK; in gic_write_vp()
241 gic->vps[vp_index].compare_map = data & GIC_MAP_TO_PIN_REG_MSK; in gic_write_vp()
244 OFFSET_CHECK(data < gic->num_vps); in gic_write_vp()
245 gic->vps[vp_index].other_addr = data; in gic_write_vp()
248 gic_timer_store_vp_compare(gic, vp_index, data); in gic_write_vp()
251 qemu_log_mask(LOG_UNIMP, "Write %d bytes at GIC offset LOCAL/OTHER " in gic_write_vp()
257 qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr); in gic_write_vp()
264 MIPSGICState *gic = (MIPSGICState *) opaque; in gic_write() local
272 uint32_t pre_cntstop = mips_gictimer_get_countstop(gic->gic_timer); in gic_write()
277 mips_gictimer_stop_count(gic->gic_timer); in gic_write()
279 mips_gictimer_start_count(gic->gic_timer); in gic_write()
285 if (mips_gictimer_get_countstop(gic->gic_timer)) { in gic_write()
286 mips_gictimer_store_sh_count(gic->gic_timer, data); in gic_write()
292 OFFSET_CHECK((base + size * 8) <= gic->num_irq); in gic_write()
294 gic->irq_state[base + i].enabled &= !((data >> i) & 1); in gic_write()
295 gic_update_pin_for_irq(gic, base + i); in gic_write()
302 OFFSET_CHECK(intr < gic->num_irq); in gic_write()
304 gic_set_irq(gic, intr, 1); in gic_write()
306 gic_set_irq(gic, intr, 0); in gic_write()
312 OFFSET_CHECK((base + size * 8) <= gic->num_irq); in gic_write()
314 gic->irq_state[base + i].enabled |= (data >> i) & 1; in gic_write()
315 gic_update_pin_for_irq(gic, base + i); in gic_write()
321 OFFSET_CHECK(irq_src < gic->num_irq); in gic_write()
324 gic->irq_state[irq_src].map_pin = data & GIC_MAP_TO_PIN_REG_MSK; in gic_write()
329 OFFSET_CHECK(irq_src < gic->num_irq); in gic_write()
331 OFFSET_CHECK(data < gic->num_vps); in gic_write()
332 gic->irq_state[irq_src].map_vp = data; in gic_write()
335 gic_write_vp(gic, vp_index, addr - VP_LOCAL_SECTION_OFS, data, size); in gic_write()
338 other_index = gic->vps[vp_index].other_addr; in gic_write()
339 gic_write_vp(gic, other_index, addr - VP_OTHER_SECTION_OFS, data, size); in gic_write()
346 qemu_log_mask(LOG_UNIMP, "Write %d bytes at GIC offset 0x%" PRIx64 in gic_write()
352 qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr); in gic_write()
358 MIPSGICState *gic = (MIPSGICState *) opaque; in gic_reset() local
359 int numintrs = (gic->num_irq / 8) - 1; in gic_reset()
361 gic->sh_config = /* COUNTSTOP = 0 it is accessible via MIPSGICTimer*/ in gic_reset()
365 (gic->num_vps << GIC_SH_CONFIG_PVPS_SHF); in gic_reset()
366 for (i = 0; i < gic->num_vps; i++) { in gic_reset()
367 gic->vps[i].ctl = 0x0; in gic_reset()
368 gic->vps[i].pend = 0x0; in gic_reset()
370 gic->vps[i].mask = 0x32; in gic_reset()
371 gic->vps[i].compare_map = GIC_MAP_TO_PIN_MSK; in gic_reset()
372 mips_gictimer_store_vp_compare(gic->gic_timer, i, 0xffffffff); in gic_reset()
373 gic->vps[i].other_addr = 0x0; in gic_reset()
375 for (i = 0; i < gic->num_irq; i++) { in gic_reset()
376 gic->irq_state[i].enabled = 0; in gic_reset()
377 gic->irq_state[i].pending = 0; in gic_reset()
378 gic->irq_state[i].map_pin = GIC_MAP_TO_PIN_MSK; in gic_reset()
379 gic->irq_state[i].map_vp = -1; in gic_reset()
381 mips_gictimer_store_sh_count(gic->gic_timer, 0); in gic_reset()
383 mips_gictimer_start_count(gic->gic_timer); in gic_reset()
401 "mips-gic", GIC_ADDRSPACE_SZ); in mips_gic_init()
417 error_setg(errp, "GIC supports up to %d external interrupts in " in mips_gic_realize()
423 /* Register the env for all VPs with the GIC */ in mips_gic_realize()
430 "Unable to initialize GIC, CPUState for CPU#%d not valid.", i); in mips_gic_realize()