Lines Matching +full:opp +full:- +full:1
28 * - Motorola MPC8245 & MPC8540 user manuals.
29 * - Motorola Harrier programmer manual
38 #include "hw/qdev-properties.h"
46 #include "qemu/error-report.h"
51 static const int debug_openpic = 1;
64 #define OPENPIC_FLAG_IDR_CRIT (1 << 0)
79 #define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000)
97 #define VIR_MPIC2A 0x00004614 /* IBM MPIC-2A */
108 #define IDR_EP_MASK (1U << IDR_EP_SHIFT)
111 #define IDR_P1_SHIFT 1
137 return inttgt_output[i][1]; in inttgt_to_output()
150 if (inttgt_output[i][1] == output) { in output_to_inttgt()
167 return -1; in get_current_cpu()
170 return current_cpu->cpu_index; in get_current_cpu()
197 set_bit(n_IRQ, q->queue); in IRQ_setbit()
202 clear_bit(n_IRQ, q->queue); in IRQ_resetbit()
205 static void IRQ_check(OpenPICState *opp, IRQQueue *q) in IRQ_check() argument
207 int irq = -1; in IRQ_check()
208 int next = -1; in IRQ_check()
209 int priority = -1; in IRQ_check()
212 irq = find_next_bit(q->queue, opp->max_irq, irq + 1); in IRQ_check()
213 if (irq == opp->max_irq) { in IRQ_check()
218 irq, IVPR_PRIORITY(opp->src[irq].ivpr), priority); in IRQ_check()
220 if (IVPR_PRIORITY(opp->src[irq].ivpr) > priority) { in IRQ_check()
222 priority = IVPR_PRIORITY(opp->src[irq].ivpr); in IRQ_check()
226 q->next = next; in IRQ_check()
227 q->priority = priority; in IRQ_check()
230 static int IRQ_get_next(OpenPICState *opp, IRQQueue *q) in IRQ_get_next() argument
233 IRQ_check(opp, q); in IRQ_get_next()
235 return q->next; in IRQ_get_next()
238 static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ, in IRQ_local_pipe() argument
245 dst = &opp->dst[n_CPU]; in IRQ_local_pipe()
246 src = &opp->src[n_IRQ]; in IRQ_local_pipe()
251 if (src->output != OPENPIC_OUTPUT_INT) { in IRQ_local_pipe()
253 __func__, src->output, n_IRQ, active, was_active, in IRQ_local_pipe()
254 dst->outputs_active[src->output]); in IRQ_local_pipe()
258 * IACK, EOI, etc. Before MPIC v4.1 they also ignore in IRQ_local_pipe()
262 if (!was_active && dst->outputs_active[src->output]++ == 0) { in IRQ_local_pipe()
264 __func__, src->output, n_CPU, n_IRQ); in IRQ_local_pipe()
265 qemu_irq_raise(dst->irqs[src->output]); in IRQ_local_pipe()
268 if (was_active && --dst->outputs_active[src->output] == 0) { in IRQ_local_pipe()
270 __func__, src->output, n_CPU, n_IRQ); in IRQ_local_pipe()
271 qemu_irq_lower(dst->irqs[src->output]); in IRQ_local_pipe()
278 priority = IVPR_PRIORITY(src->ivpr); in IRQ_local_pipe()
285 IRQ_setbit(&dst->raised, n_IRQ); in IRQ_local_pipe()
287 IRQ_resetbit(&dst->raised, n_IRQ); in IRQ_local_pipe()
290 IRQ_check(opp, &dst->raised); in IRQ_local_pipe()
292 if (active && priority <= dst->ctpr) { in IRQ_local_pipe()
294 __func__, n_IRQ, priority, dst->ctpr, n_CPU); in IRQ_local_pipe()
299 if (IRQ_get_next(opp, &dst->servicing) >= 0 && in IRQ_local_pipe()
300 priority <= dst->servicing.priority) { in IRQ_local_pipe()
302 __func__, n_IRQ, dst->servicing.next, n_CPU); in IRQ_local_pipe()
305 __func__, n_CPU, n_IRQ, dst->raised.next); in IRQ_local_pipe()
306 qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); in IRQ_local_pipe()
309 IRQ_get_next(opp, &dst->servicing); in IRQ_local_pipe()
310 if (dst->raised.priority > dst->ctpr && in IRQ_local_pipe()
311 dst->raised.priority > dst->servicing.priority) { in IRQ_local_pipe()
313 __func__, n_IRQ, dst->raised.next, dst->raised.priority, in IRQ_local_pipe()
314 dst->ctpr, dst->servicing.priority, n_CPU); in IRQ_local_pipe()
318 __func__, n_IRQ, dst->ctpr, dst->servicing.priority, n_CPU); in IRQ_local_pipe()
319 qemu_irq_lower(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); in IRQ_local_pipe()
325 static void openpic_update_irq(OpenPICState *opp, int n_IRQ) in openpic_update_irq() argument
331 src = &opp->src[n_IRQ]; in openpic_update_irq()
332 active = src->pending; in openpic_update_irq()
334 if ((src->ivpr & IVPR_MASK_MASK) && !src->nomask) { in openpic_update_irq()
340 was_active = !!(src->ivpr & IVPR_ACTIVITY_MASK); in openpic_update_irq()
343 * We don't have a similar check for already-active because in openpic_update_irq()
352 src->ivpr |= IVPR_ACTIVITY_MASK; in openpic_update_irq()
354 src->ivpr &= ~IVPR_ACTIVITY_MASK; in openpic_update_irq()
357 if (src->destmask == 0) { in openpic_update_irq()
363 if (src->destmask == (1 << src->last_cpu)) { in openpic_update_irq()
365 IRQ_local_pipe(opp, src->last_cpu, n_IRQ, active, was_active); in openpic_update_irq()
366 } else if (!(src->ivpr & IVPR_MODE_MASK)) { in openpic_update_irq()
368 for (i = 0; i < opp->nb_cpus; i++) { in openpic_update_irq()
369 if (src->destmask & (1 << i)) { in openpic_update_irq()
370 IRQ_local_pipe(opp, i, n_IRQ, active, was_active); in openpic_update_irq()
375 for (i = src->last_cpu + 1; i != src->last_cpu; i++) { in openpic_update_irq()
376 if (i == opp->nb_cpus) { in openpic_update_irq()
379 if (src->destmask & (1 << i)) { in openpic_update_irq()
380 IRQ_local_pipe(opp, i, n_IRQ, active, was_active); in openpic_update_irq()
381 src->last_cpu = i; in openpic_update_irq()
390 OpenPICState *opp = opaque; in openpic_set_irq() local
398 src = &opp->src[n_IRQ]; in openpic_set_irq()
400 n_IRQ, level, src->ivpr); in openpic_set_irq()
401 if (src->level) { in openpic_set_irq()
402 /* level-sensitive irq */ in openpic_set_irq()
403 src->pending = level; in openpic_set_irq()
404 openpic_update_irq(opp, n_IRQ); in openpic_set_irq()
406 /* edge-sensitive irq */ in openpic_set_irq()
408 src->pending = 1; in openpic_set_irq()
409 openpic_update_irq(opp, n_IRQ); in openpic_set_irq()
412 if (src->output != OPENPIC_OUTPUT_INT) { in openpic_set_irq()
414 * Edge-triggered interrupts shouldn't be used in openpic_set_irq()
415 * with non-INT delivery, but just in case, in openpic_set_irq()
420 src->pending = 0; in openpic_set_irq()
421 openpic_update_irq(opp, n_IRQ); in openpic_set_irq()
426 static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ) in read_IRQreg_idr() argument
428 return opp->src[n_IRQ].idr; in read_IRQreg_idr()
431 static inline uint32_t read_IRQreg_ilr(OpenPICState *opp, int n_IRQ) in read_IRQreg_ilr() argument
433 if (opp->flags & OPENPIC_FLAG_ILR) { in read_IRQreg_ilr()
434 return output_to_inttgt(opp->src[n_IRQ].output); in read_IRQreg_ilr()
440 static inline uint32_t read_IRQreg_ivpr(OpenPICState *opp, int n_IRQ) in read_IRQreg_ivpr() argument
442 return opp->src[n_IRQ].ivpr; in read_IRQreg_ivpr()
445 static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val) in write_IRQreg_idr() argument
447 IRQSource *src = &opp->src[n_IRQ]; in write_IRQreg_idr()
448 uint32_t normal_mask = (1UL << opp->nb_cpus) - 1; in write_IRQreg_idr()
451 int crit_shift = IDR_EP_SHIFT - opp->nb_cpus; in write_IRQreg_idr()
454 if (opp->flags & OPENPIC_FLAG_IDR_CRIT) { in write_IRQreg_idr()
459 src->idr = val & mask; in write_IRQreg_idr()
460 DPRINTF("Set IDR %d to 0x%08x", n_IRQ, src->idr); in write_IRQreg_idr()
462 if (opp->flags & OPENPIC_FLAG_IDR_CRIT) { in write_IRQreg_idr()
463 if (src->idr & crit_mask) { in write_IRQreg_idr()
464 if (src->idr & normal_mask) { in write_IRQreg_idr()
469 src->output = OPENPIC_OUTPUT_CINT; in write_IRQreg_idr()
470 src->nomask = true; in write_IRQreg_idr()
471 src->destmask = 0; in write_IRQreg_idr()
473 for (i = 0; i < opp->nb_cpus; i++) { in write_IRQreg_idr()
474 int n_ci = IDR_CI0_SHIFT - i; in write_IRQreg_idr()
476 if (src->idr & (1UL << n_ci)) { in write_IRQreg_idr()
477 src->destmask |= 1UL << i; in write_IRQreg_idr()
481 src->output = OPENPIC_OUTPUT_INT; in write_IRQreg_idr()
482 src->nomask = false; in write_IRQreg_idr()
483 src->destmask = src->idr & normal_mask; in write_IRQreg_idr()
486 src->destmask = src->idr; in write_IRQreg_idr()
490 static inline void write_IRQreg_ilr(OpenPICState *opp, int n_IRQ, uint32_t val) in write_IRQreg_ilr() argument
492 if (opp->flags & OPENPIC_FLAG_ILR) { in write_IRQreg_ilr()
493 IRQSource *src = &opp->src[n_IRQ]; in write_IRQreg_ilr()
495 src->output = inttgt_to_output(val & ILR_INTTGT_MASK); in write_IRQreg_ilr()
496 DPRINTF("Set ILR %d to 0x%08x, output %d", n_IRQ, src->idr, in write_IRQreg_ilr()
497 src->output); in write_IRQreg_ilr()
499 /* TODO: on MPIC v4.0 only, set nomask for non-INT */ in write_IRQreg_ilr()
503 static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val) in write_IRQreg_ivpr() argument
509 * the polarity bit is read-only on internal interrupts. in write_IRQreg_ivpr()
512 IVPR_POLARITY_MASK | opp->vector_mask; in write_IRQreg_ivpr()
514 /* ACTIVITY bit is read-only */ in write_IRQreg_ivpr()
515 opp->src[n_IRQ].ivpr = in write_IRQreg_ivpr()
516 (opp->src[n_IRQ].ivpr & IVPR_ACTIVITY_MASK) | (val & mask); in write_IRQreg_ivpr()
520 * and the interrupt is always level-triggered. Timers and IPIs in write_IRQreg_ivpr()
521 * have no sense or polarity bits, and are edge-triggered. in write_IRQreg_ivpr()
523 switch (opp->src[n_IRQ].type) { in write_IRQreg_ivpr()
525 opp->src[n_IRQ].level = !!(opp->src[n_IRQ].ivpr & IVPR_SENSE_MASK); in write_IRQreg_ivpr()
529 opp->src[n_IRQ].ivpr &= ~IVPR_SENSE_MASK; in write_IRQreg_ivpr()
533 opp->src[n_IRQ].ivpr &= ~(IVPR_POLARITY_MASK | IVPR_SENSE_MASK); in write_IRQreg_ivpr()
537 openpic_update_irq(opp, n_IRQ); in write_IRQreg_ivpr()
538 DPRINTF("Set IVPR %d to 0x%08x -> 0x%08x", n_IRQ, val, in write_IRQreg_ivpr()
539 opp->src[n_IRQ].ivpr); in write_IRQreg_ivpr()
542 static void openpic_gcr_write(OpenPICState *opp, uint64_t val) in openpic_gcr_write() argument
547 openpic_reset(DEVICE(opp)); in openpic_gcr_write()
551 opp->gcr &= ~opp->mpic_mode_mask; in openpic_gcr_write()
552 opp->gcr |= val & opp->mpic_mode_mask; in openpic_gcr_write()
555 if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) { in openpic_gcr_write()
565 OpenPICState *opp = opaque; in openpic_gbl_write() local
585 openpic_cpu_write_internal(opp, addr, val, get_current_cpu()); in openpic_gbl_write()
590 openpic_gcr_write(opp, val); in openpic_gbl_write()
595 for (idx = 0; idx < opp->nb_cpus; idx++) { in openpic_gbl_write()
596 if ((val & (1 << idx)) && !(opp->pir & (1 << idx))) { in openpic_gbl_write()
598 dst = &opp->dst[idx]; in openpic_gbl_write()
599 qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]); in openpic_gbl_write()
600 } else if (!(val & (1 << idx)) && (opp->pir & (1 << idx))) { in openpic_gbl_write()
602 dst = &opp->dst[idx]; in openpic_gbl_write()
603 qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]); in openpic_gbl_write()
606 opp->pir = val; in openpic_gbl_write()
612 idx = (addr - 0x10A0) >> 4; in openpic_gbl_write()
613 write_IRQreg_ivpr(opp, opp->irq_ipi0 + idx, val); in openpic_gbl_write()
616 opp->spve = val & opp->vector_mask; in openpic_gbl_write()
625 OpenPICState *opp = opaque; in openpic_gbl_read() local
635 retval = opp->frr; in openpic_gbl_read()
638 retval = opp->gcr; in openpic_gbl_read()
641 retval = opp->vir; in openpic_gbl_read()
647 retval = opp->brr1; in openpic_gbl_read()
657 retval = openpic_cpu_read_internal(opp, addr, get_current_cpu()); in openpic_gbl_read()
665 idx = (addr - 0x10A0) >> 4; in openpic_gbl_read()
666 retval = read_IRQreg_ivpr(opp, opp->irq_ipi0 + idx); in openpic_gbl_read()
670 retval = opp->spve; in openpic_gbl_read()
685 OpenPICState *opp = tmr->opp; in qemu_timer_cb() local
686 uint32_t n_IRQ = tmr->n_IRQ; in qemu_timer_cb()
687 uint32_t val = tmr->tbcr & ~TBCR_CI; in qemu_timer_cb()
688 uint32_t tog = ((tmr->tccr & TCCR_TOG) ^ TCCR_TOG); /* invert toggle. */ in qemu_timer_cb()
692 tmr->tccr = val | tog; in qemu_timer_cb()
695 opp->src[n_IRQ].destmask = read_IRQreg_idr(opp, n_IRQ); in qemu_timer_cb()
696 openpic_set_irq(opp, n_IRQ, 1); in qemu_timer_cb()
697 openpic_set_irq(opp, n_IRQ, 0); in qemu_timer_cb()
715 tmr->qemu_timer_active = false; in openpic_tmr_set_tmr()
716 tmr->tccr = tmr->tccr & TCCR_TOG; in openpic_tmr_set_tmr()
717 timer_del(tmr->qemu_timer); /* set timer to never expire. */ in openpic_tmr_set_tmr()
719 tmr->qemu_timer_active = true; in openpic_tmr_set_tmr()
721 tmr->origin_time = now; in openpic_tmr_set_tmr()
722 timer_mod(tmr->qemu_timer, now + ns); /* set timer expiration. */ in openpic_tmr_set_tmr()
733 if (!tmr->qemu_timer_active) { in openpic_tmr_get_timer()
734 retval = tmr->tccr; in openpic_tmr_get_timer()
737 uint64_t used = now - tmr->origin_time; /* nsecs */ in openpic_tmr_get_timer()
739 uint32_t count = (tmr->tccr & ~TCCR_TOG) - used_ticks; in openpic_tmr_get_timer()
740 retval = (uint32_t)((tmr->tccr & TCCR_TOG) | (count & ~TCCR_TOG)); in openpic_tmr_get_timer()
748 OpenPICState *opp = opaque; in openpic_tmr_write() local
759 opp->tfrr = val; in openpic_tmr_write()
762 addr -= 0x10; /* correct for TFRR */ in openpic_tmr_write()
770 if ((opp->timers[idx].tbcr & TBCR_CI) != (val & TBCR_CI)) { in openpic_tmr_write()
771 /* Did "Count Inhibit" transition from 1 to 0? */ in openpic_tmr_write()
773 opp->timers[idx].tccr = val & ~TCCR_TOG; in openpic_tmr_write()
775 openpic_tmr_set_tmr(&opp->timers[idx], in openpic_tmr_write()
779 opp->timers[idx].tbcr = val; in openpic_tmr_write()
782 write_IRQreg_ivpr(opp, opp->irq_tim0 + idx, val); in openpic_tmr_write()
785 write_IRQreg_idr(opp, opp->irq_tim0 + idx, val); in openpic_tmr_write()
792 OpenPICState *opp = opaque; in openpic_tmr_read() local
793 uint32_t retval = -1; in openpic_tmr_read()
802 retval = opp->tfrr; in openpic_tmr_read()
805 addr -= 0x10; /* correct for TFRR */ in openpic_tmr_read()
809 retval = openpic_tmr_get_timer(&opp->timers[idx]); in openpic_tmr_read()
812 retval = opp->timers[idx].tbcr; in openpic_tmr_read()
815 retval = read_IRQreg_ivpr(opp, opp->irq_tim0 + idx); in openpic_tmr_read()
818 retval = read_IRQreg_idr(opp, opp->irq_tim0 + idx); in openpic_tmr_read()
831 OpenPICState *opp = opaque; in openpic_src_write() local
842 write_IRQreg_ivpr(opp, idx, val); in openpic_src_write()
845 write_IRQreg_idr(opp, idx, val); in openpic_src_write()
848 write_IRQreg_ilr(opp, idx, val); in openpic_src_write()
855 OpenPICState *opp = opaque; in openpic_src_read() local
867 retval = read_IRQreg_ivpr(opp, idx); in openpic_src_read()
870 retval = read_IRQreg_idr(opp, idx); in openpic_src_read()
873 retval = read_IRQreg_ilr(opp, idx); in openpic_src_read()
884 OpenPICState *opp = opaque; in openpic_msi_write() local
885 int idx = opp->irq_msi; in openpic_msi_write()
899 opp->msi[srs].msir |= 1 << ibs; in openpic_msi_write()
900 openpic_set_irq(opp, idx, 1); in openpic_msi_write()
903 /* most registers are read-only, thus ignored */ in openpic_msi_write()
910 OpenPICState *opp = opaque; in openpic_msi_read() local
916 return -1; in openpic_msi_read()
930 r = opp->msi[srs].msir; in openpic_msi_read()
932 opp->msi[srs].msir = 0; in openpic_msi_read()
933 openpic_set_irq(opp, opp->irq_msi + srs, 0); in openpic_msi_read()
937 r |= (opp->msi[i].msir ? 1 : 0) << i; in openpic_msi_read()
968 OpenPICState *opp = opaque; in openpic_cpu_write_internal() local
976 if (idx < 0 || idx >= opp->nb_cpus) { in openpic_cpu_write_internal()
983 dst = &opp->dst[idx]; in openpic_cpu_write_internal()
990 idx = (addr - 0x40) >> 4; in openpic_cpu_write_internal()
992 opp->src[opp->irq_ipi0 + idx].destmask |= val; in openpic_cpu_write_internal()
993 openpic_set_irq(opp, opp->irq_ipi0 + idx, 1); in openpic_cpu_write_internal()
994 openpic_set_irq(opp, opp->irq_ipi0 + idx, 0); in openpic_cpu_write_internal()
997 dst->ctpr = val & 0x0000000F; in openpic_cpu_write_internal()
1000 __func__, idx, dst->ctpr, dst->raised.priority, in openpic_cpu_write_internal()
1001 dst->servicing.priority); in openpic_cpu_write_internal()
1003 if (dst->raised.priority <= dst->ctpr) { in openpic_cpu_write_internal()
1006 qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); in openpic_cpu_write_internal()
1007 } else if (dst->raised.priority > dst->servicing.priority) { in openpic_cpu_write_internal()
1009 __func__, idx, dst->raised.next); in openpic_cpu_write_internal()
1010 qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]); in openpic_cpu_write_internal()
1015 /* Read-only register */ in openpic_cpu_write_internal()
1018 /* Read-only register */ in openpic_cpu_write_internal()
1022 s_IRQ = IRQ_get_next(opp, &dst->servicing); in openpic_cpu_write_internal()
1029 IRQ_resetbit(&dst->servicing, s_IRQ); in openpic_cpu_write_internal()
1031 s_IRQ = IRQ_get_next(opp, &dst->servicing); in openpic_cpu_write_internal()
1033 n_IRQ = IRQ_get_next(opp, &dst->raised); in openpic_cpu_write_internal()
1034 if (n_IRQ != -1) { in openpic_cpu_write_internal()
1035 src = &opp->src[n_IRQ]; in openpic_cpu_write_internal()
1036 if (s_IRQ == -1 || in openpic_cpu_write_internal()
1037 IVPR_PRIORITY(src->ivpr) > dst->servicing.priority) { in openpic_cpu_write_internal()
1040 qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]); in openpic_cpu_write_internal()
1056 static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu) in openpic_iack() argument
1062 qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); in openpic_iack()
1064 irq = IRQ_get_next(opp, &dst->raised); in openpic_iack()
1067 if (irq == -1) { in openpic_iack()
1069 return opp->spve; in openpic_iack()
1072 src = &opp->src[irq]; in openpic_iack()
1073 if (!(src->ivpr & IVPR_ACTIVITY_MASK) || in openpic_iack()
1074 !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) { in openpic_iack()
1076 __func__, irq, dst->ctpr, src->ivpr); in openpic_iack()
1077 openpic_update_irq(opp, irq); in openpic_iack()
1078 retval = opp->spve; in openpic_iack()
1081 IRQ_setbit(&dst->servicing, irq); in openpic_iack()
1082 retval = IVPR_VECTOR(opp, src->ivpr); in openpic_iack()
1085 if (!src->level) { in openpic_iack()
1086 /* edge-sensitive IRQ */ in openpic_iack()
1087 src->ivpr &= ~IVPR_ACTIVITY_MASK; in openpic_iack()
1088 src->pending = 0; in openpic_iack()
1089 IRQ_resetbit(&dst->raised, irq); in openpic_iack()
1093 if (((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + OPENPIC_MAX_IPI))) || in openpic_iack()
1094 ((irq >= opp->irq_tim0) && (irq < (opp->irq_tim0 + OPENPIC_MAX_TMR)))) { in openpic_iack()
1096 src->destmask &= ~(1 << cpu); in openpic_iack()
1097 if (src->destmask && !src->level) { in openpic_iack()
1099 openpic_set_irq(opp, irq, 1); in openpic_iack()
1100 openpic_set_irq(opp, irq, 0); in openpic_iack()
1102 src->ivpr |= IVPR_ACTIVITY_MASK; in openpic_iack()
1112 OpenPICState *opp = opaque; in openpic_cpu_read_internal() local
1119 if (idx < 0 || idx >= opp->nb_cpus) { in openpic_cpu_read_internal()
1126 dst = &opp->dst[idx]; in openpic_cpu_read_internal()
1130 retval = dst->ctpr; in openpic_cpu_read_internal()
1136 retval = openpic_iack(opp, dst, idx); in openpic_cpu_read_internal()
1256 OpenPICState *opp = OPENPIC(d); in openpic_reset() local
1259 opp->gcr = GCR_RESET; in openpic_reset()
1261 opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) | in openpic_reset()
1262 ((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) | in openpic_reset()
1263 (opp->vid << FRR_VID_SHIFT); in openpic_reset()
1265 opp->pir = 0; in openpic_reset()
1266 opp->spve = -1 & opp->vector_mask; in openpic_reset()
1267 opp->tfrr = opp->tfrr_reset; in openpic_reset()
1269 for (i = 0; i < opp->max_irq; i++) { in openpic_reset()
1270 opp->src[i].ivpr = opp->ivpr_reset; in openpic_reset()
1271 switch (opp->src[i].type) { in openpic_reset()
1273 opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK); in openpic_reset()
1277 opp->src[i].ivpr |= IVPR_POLARITY_MASK; in openpic_reset()
1285 if ((opp->model == OPENPIC_MODEL_FSL_MPIC_20) || in openpic_reset()
1286 (opp->model == OPENPIC_MODEL_FSL_MPIC_42)) { in openpic_reset()
1287 if (i >= opp->irq_ipi0 && i < opp->irq_tim0) { in openpic_reset()
1288 write_IRQreg_idr(opp, i, 0); in openpic_reset()
1293 write_IRQreg_idr(opp, i, opp->idr_reset); in openpic_reset()
1296 for (i = 0; i < opp->nb_cpus; i++) { in openpic_reset()
1297 opp->dst[i].ctpr = 15; in openpic_reset()
1298 opp->dst[i].raised.next = -1; in openpic_reset()
1299 opp->dst[i].raised.priority = 0; in openpic_reset()
1300 bitmap_clear(opp->dst[i].raised.queue, 0, IRQQUEUE_SIZE_BITS); in openpic_reset()
1301 opp->dst[i].servicing.next = -1; in openpic_reset()
1302 opp->dst[i].servicing.priority = 0; in openpic_reset()
1303 bitmap_clear(opp->dst[i].servicing.queue, 0, IRQQUEUE_SIZE_BITS); in openpic_reset()
1307 opp->timers[i].tccr = 0; in openpic_reset()
1308 opp->timers[i].tbcr = TBCR_CI; in openpic_reset()
1309 if (opp->timers[i].qemu_timer_active) { in openpic_reset()
1310 timer_del(opp->timers[i].qemu_timer); /* Inhibit timer */ in openpic_reset()
1311 opp->timers[i].qemu_timer_active = false; in openpic_reset()
1315 opp->gcr = 0; in openpic_reset()
1325 static void fsl_common_init(OpenPICState *opp) in fsl_common_init() argument
1330 opp->vid = VID_REVISION_1_2; in fsl_common_init()
1331 opp->vir = VIR_GENERIC; in fsl_common_init()
1332 opp->vector_mask = 0xFFFF; in fsl_common_init()
1333 opp->tfrr_reset = 0; in fsl_common_init()
1334 opp->ivpr_reset = IVPR_MASK_MASK; in fsl_common_init()
1335 opp->idr_reset = 1 << 0; in fsl_common_init()
1336 opp->max_irq = OPENPIC_MAX_IRQ; in fsl_common_init()
1338 opp->irq_ipi0 = virq; in fsl_common_init()
1340 opp->irq_tim0 = virq; in fsl_common_init()
1345 opp->irq_msi = 224; in fsl_common_init()
1348 for (i = 0; i < opp->fsl->max_ext; i++) { in fsl_common_init()
1349 opp->src[i].level = false; in fsl_common_init()
1354 opp->src[i].type = IRQ_TYPE_FSLINT; in fsl_common_init()
1355 opp->src[i].level = true; in fsl_common_init()
1360 opp->src[i].type = IRQ_TYPE_FSLSPECIAL; in fsl_common_init()
1361 opp->src[i].level = false; in fsl_common_init()
1365 opp->timers[i].n_IRQ = opp->irq_tim0 + i; in fsl_common_init()
1366 opp->timers[i].qemu_timer_active = false; in fsl_common_init()
1367 opp->timers[i].qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, in fsl_common_init()
1369 &opp->timers[i]); in fsl_common_init()
1370 opp->timers[i].opp = opp; in fsl_common_init()
1374 static void map_list(OpenPICState *opp, const MemReg *list, int *count) in map_list() argument
1376 while (list->name) { in map_list()
1377 assert(*count < ARRAY_SIZE(opp->sub_io_mem)); in map_list()
1379 memory_region_init_io(&opp->sub_io_mem[*count], OBJECT(opp), list->ops, in map_list()
1380 opp, list->name, list->size); in map_list()
1382 memory_region_add_subregion(&opp->mem, list->start_addr, in map_list()
1383 &opp->sub_io_mem[*count]); in map_list()
1454 OpenPICState *opp = (OpenPICState *)opaque; in openpic_post_load() local
1458 for (i = 0; i < opp->max_irq; i++) { in openpic_post_load()
1459 write_IRQreg_idr(opp, i, opp->src[i].idr); in openpic_post_load()
1460 write_IRQreg_ivpr(opp, i, opp->src[i].ivpr); in openpic_post_load()
1496 OpenPICState *opp = OPENPIC(obj); in openpic_init() local
1498 memory_region_init(&opp->mem, obj, "openpic", 0x40000); in openpic_init()
1504 OpenPICState *opp = OPENPIC(dev); in openpic_realize() local
1537 if (opp->nb_cpus > MAX_CPU) { in openpic_realize()
1542 switch (opp->model) { in openpic_realize()
1545 opp->fsl = &fsl_mpic_20; in openpic_realize()
1546 opp->brr1 = 0x00400200; in openpic_realize()
1547 opp->flags |= OPENPIC_FLAG_IDR_CRIT; in openpic_realize()
1548 opp->nb_irqs = 80; in openpic_realize()
1549 opp->mpic_mode_mask = GCR_MODE_MIXED; in openpic_realize()
1551 fsl_common_init(opp); in openpic_realize()
1552 map_list(opp, list_be, &list_count); in openpic_realize()
1553 map_list(opp, list_fsl, &list_count); in openpic_realize()
1558 opp->fsl = &fsl_mpic_42; in openpic_realize()
1559 opp->brr1 = 0x00400402; in openpic_realize()
1560 opp->flags |= OPENPIC_FLAG_ILR; in openpic_realize()
1561 opp->nb_irqs = 196; in openpic_realize()
1562 opp->mpic_mode_mask = GCR_MODE_PROXY; in openpic_realize()
1564 fsl_common_init(opp); in openpic_realize()
1565 map_list(opp, list_be, &list_count); in openpic_realize()
1566 map_list(opp, list_fsl, &list_count); in openpic_realize()
1571 opp->nb_irqs = KEYLARGO_MAX_EXT; in openpic_realize()
1572 opp->vid = VID_REVISION_1_2; in openpic_realize()
1573 opp->vir = VIR_GENERIC; in openpic_realize()
1574 opp->vector_mask = 0xFF; in openpic_realize()
1575 opp->tfrr_reset = 4160000; in openpic_realize()
1576 opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK; in openpic_realize()
1577 opp->idr_reset = 0; in openpic_realize()
1578 opp->max_irq = KEYLARGO_MAX_IRQ; in openpic_realize()
1579 opp->irq_ipi0 = KEYLARGO_IPI_IRQ; in openpic_realize()
1580 opp->irq_tim0 = KEYLARGO_TMR_IRQ; in openpic_realize()
1581 opp->brr1 = -1; in openpic_realize()
1582 opp->mpic_mode_mask = GCR_MODE_MIXED; in openpic_realize()
1584 if (opp->nb_cpus != 1) { in openpic_realize()
1589 map_list(opp, list_le, &list_count); in openpic_realize()
1593 for (i = 0; i < opp->nb_cpus; i++) { in openpic_realize()
1594 opp->dst[i].irqs = g_new0(qemu_irq, OPENPIC_OUTPUT_NB); in openpic_realize()
1596 sysbus_init_irq(d, &opp->dst[i].irqs[j]); in openpic_realize()
1599 opp->dst[i].raised.queue_size = IRQQUEUE_SIZE_BITS; in openpic_realize()
1600 opp->dst[i].raised.queue = bitmap_new(IRQQUEUE_SIZE_BITS); in openpic_realize()
1601 opp->dst[i].servicing.queue_size = IRQQUEUE_SIZE_BITS; in openpic_realize()
1602 opp->dst[i].servicing.queue = bitmap_new(IRQQUEUE_SIZE_BITS); in openpic_realize()
1605 sysbus_init_mmio(d, &opp->mem); in openpic_realize()
1606 qdev_init_gpio_in(dev, openpic_set_irq, opp->max_irq); in openpic_realize()
1611 DEFINE_PROP_UINT32("nb_cpus", OpenPICState, nb_cpus, 1),
1619 dc->realize = openpic_realize; in openpic_class_init()
1622 dc->vmsd = &vmstate_openpic; in openpic_class_init()
1623 set_bit(DEVICE_CATEGORY_MISC, dc->categories); in openpic_class_init()