Lines Matching refs:pic
1 /* $NetBSD: pic.c,v 1.85 2022/10/30 10:20:45 riastradh Exp $ */
37 __KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.85 2022/10/30 10:20:45 riastradh Exp $");
61 #include <arm/pic/picvar.h>
66 * the assumption that a PIC (pic_softc) shall only have all its interrupts
67 * come from the same CPU. In other words, interrupts from a single PIC will
175 struct pic_softc * const pic = pic_list[slot];
176 if (pic != NULL && pic->pic_ops->pic_cpu_init != NULL) {
177 (*pic->pic_ops->pic_cpu_init)(pic, ci);
192 struct pic_softc * const pic = pic_list[slot];
193 if (pic == NULL || pic->pic_cpus == NULL)
195 if (kcp == NULL || kcpuset_intersecting_p(kcp, pic->pic_cpus)) {
200 * that have a pic per cpu, e.g. RPI[23]. GIC sets
204 if (pic->pic_cpus == ci->ci_kcpuset)
207 (*pic->pic_ops->pic_ipi_send)(pic, kcp, ipi);
210 * If we were targeting a single CPU or this pic
213 if (kcp != NULL || pic->pic_cpus == kcpuset_running)
242 struct pic_softc * const pic = arg;
245 rv = (*pic->pic_ops->pic_find_pending_irqs)(pic);
252 pic_mark_pending_source(struct pic_softc *pic, struct intrsource *is)
257 atomic_or_32(&pic->pic_pending_irqs[is->is_irq >> 5],
260 atomic_or_32(&pic->pic_pending_ipls, ipl_mask);
262 ci->ci_pending_pics |= __BIT(pic->pic_id);
266 pic_mark_pending(struct pic_softc *pic, int irq)
268 struct intrsource * const is = pic->pic_sources[irq];
270 KASSERT(irq < pic->pic_maxsources);
273 pic_mark_pending_source(pic, is);
277 pic_mark_pending_sources(struct pic_softc *pic, size_t irq_base,
280 struct intrsource ** const isbase = &pic->pic_sources[irq_base];
283 volatile uint32_t *ipending = &pic->pic_pending_irqs[irq_base >> 5];
291 (*pic->pic_ops->pic_block_irqs)(pic, irq_base, pending);
305 atomic_or_32(&pic->pic_pending_ipls, ipl_mask);
307 ci->ci_pending_pics |= __BIT(pic->pic_id);
313 pic_find_pending_irqs_by_ipl(struct pic_softc *pic, size_t irq_base,
326 KASSERTMSG(pic->pic_sources[irq_base + irq] != NULL,
329 if (pic->pic_sources[irq_base + irq] == NULL) {
334 if (pic->pic_sources[irq_base + irq]->is_ipl == ipl)
379 KASSERTMSG(ocpl <= ncpl, "pic %s irq %u intrsource %s:"
392 pic_deliver_irqs(struct cpu_info *ci, struct pic_softc *pic, int ipl,
397 volatile uint32_t *ipending = pic->pic_pending_irqs;
398 volatile uint32_t *iblocked = pic->pic_blocked_irqs;
409 KASSERT(pic->pic_pending_ipls & ipl_mask);
417 pending_irqs = pic_find_pending_irqs_by_ipl(pic, irq_base,
424 if (__predict_true(irq_count >= pic->pic_maxsources)) {
431 ipending = pic->pic_pending_irqs;
432 iblocked = pic->pic_blocked_irqs;
437 KASSERT(irq_base <= pic->pic_maxsources);
451 is = pic->pic_sources[irq_base + irq];
468 pending_irqs = pic_find_pending_irqs_by_ipl(pic,
473 ci->ci_blocked_pics |= __BIT(pic->pic_id);
482 if (atomic_and_32_nv(&pic->pic_pending_ipls, ~ipl_mask) == 0)
483 ci->ci_pending_pics &= ~__BIT(pic->pic_id);
494 struct pic_softc *pic;
505 pic = pic_list[pic_id];
506 KASSERT(pic != NULL);
508 for (irq_base = 0, iblocked = pic->pic_blocked_irqs;
509 irq_base < pic->pic_maxsources;
512 (*pic->pic_ops->pic_unblock_irqs)(pic,
518 KASSERT(pic->pic_blocked_irqs[0] != 0);
519 (*pic->pic_ops->pic_unblock_irqs)(pic,
520 0, pic->pic_blocked_irqs[0]);
521 pic->pic_blocked_irqs[0] = 0;
531 struct pic_softc *pic;
538 pic = pic_list[pic_id];
539 KASSERT(pic != NULL);
540 if (pic->pic_pending_ipls & ipl_mask)
541 return pic;
551 struct pic_softc *pic;
553 while ((pic = pic_list_find_pic_by_pending_ipl(ci, ipl_mask)) != NULL) {
554 pic_deliver_irqs(ci, pic, ipl, frame);
555 KASSERT((pic->pic_pending_ipls & ipl_mask) == 0);
599 struct pic_softc * const pic = v1;
601 pcpu->pcpu_evs = kmem_zalloc(pic->pic_maxsources * sizeof(pcpu->pcpu_evs[0]),
606 const size_t namelen = strlen(pic->pic_name) + 4 + strlen(ci->ci_data.cpu_name);
612 "%s (%s)", pic->pic_name, ci->ci_data.cpu_name);
614 strlcpy(pcpu->pcpu_name, pic->pic_name, PCPU_NAMELEN);
619 __func__, ci->ci_data.cpu_name, pic->pic_name,
634 pic_add(struct pic_softc *pic, int irqbase)
644 KASSERT(strlen(pic->pic_name) > 0);
663 if (irqbase + pic->pic_maxsources <= xpic->pic_irqbase)
665 panic("pic_add: pic %s (%zu sources @ irq %u) conflicts"
666 " with pic %s (%zu sources @ irq %u)",
667 pic->pic_name, pic->pic_maxsources, irqbase,
673 pic->pic_name, pic_sourcebase, pic->pic_maxsources);
675 KASSERTMSG(pic->pic_maxsources <= PIC_MAXSOURCES, "%zu",
676 pic->pic_maxsources);
677 KASSERT(pic_sourcebase + pic->pic_maxsources <= PIC_MAXMAXSOURCES);
679 pic_sourcebase += pic->pic_maxsources;
680 if (pic_lastbase < irqbase + pic->pic_maxsources)
681 pic_lastbase = irqbase + pic->pic_maxsources;
692 pic->pic_percpu = percpu_create(sizeof(struct pic_percpu),
693 pic_percpu_allocate, NULL, pic);
695 pic->pic_sources = &pic_sources[sourcebase];
696 pic->pic_irqbase = irqbase;
697 pic->pic_id = slot;
699 KASSERT((slot == 0) == (pic->pic_ops->pic_set_priority != NULL));
702 KASSERT((pic->pic_cpus != NULL) == (pic->pic_ops->pic_ipi_send != NULL));
704 pic_list[slot] = pic;
710 pic_alloc_irq(struct pic_softc *pic)
714 for (irq = 0; irq < pic->pic_maxsources; irq++) {
715 if (pic->pic_sources[irq] == NULL)
736 struct pic_softc *pic = arg1;
739 (*pic->pic_ops->pic_unblock_irqs)(pic, is->is_irq & ~0x1f,
744 pic_establish_intr(struct pic_softc *pic, int irq, int ipl, int type,
750 if (pic->pic_sources[irq]) {
751 printf("pic_establish_intr: pic %s irq %d already present\n",
752 pic->pic_name, irq);
757 is->is_pic = pic;
767 if (pic->pic_ops->pic_source_name)
768 (*pic->pic_ops->pic_source_name)(pic, irq, is->is_source,
776 percpu_foreach(pic->pic_percpu, pic_percpu_evcnt_attach, is);
778 pic->pic_sources[irq] = is;
819 (*pic->pic_ops->pic_establish_irq)(pic, is);
822 (*pic->pic_ops->pic_unblock_irqs)(pic, is->is_irq & ~0x1f,
825 uint64_t xc = xc_broadcast(0, pic_unblock_percpu, pic, is);
854 struct pic_softc * const pic = is->is_pic;
857 KASSERT(is == pic->pic_sources[irq]);
859 (*pic->pic_ops->pic_block_irqs)(pic, irq & ~0x1f, __BIT(irq & 0x1f));
860 pic->pic_sources[irq] = NULL;
869 percpu_foreach(pic->pic_percpu, pic_percpu_evcnt_deattach, is);
888 struct pic_softc * const pic = pic_list[slot];
889 if (pic == NULL || pic->pic_irqbase < 0)
891 if (pic->pic_irqbase <= irq
892 && irq < pic->pic_irqbase + pic->pic_maxsources) {
893 return pic_establish_intr(pic, irq - pic->pic_irqbase,
916 struct pic_softc * const pic = is->is_pic;
920 (*pic->pic_ops->pic_block_irqs)(pic, irq & ~0x1f, __BIT(irq & 0x1f));
927 struct pic_softc * const pic = is->is_pic;
931 (*pic->pic_ops->pic_unblock_irqs)(pic, irq & ~0x1f, __BIT(irq & 0x1f));
938 struct pic_softc * const pic = pic_list[slot];
939 if (pic == NULL || pic->pic_irqbase < 0)
941 if (pic->pic_irqbase <= irq
942 && irq < pic->pic_irqbase + pic->pic_maxsources) {
943 struct intrsource * const is = pic->pic_sources[irq - pic->pic_irqbase];
944 snprintf(buf, len, "%s %s", pic->pic_name, is->is_source);
963 struct pic_softc * const pic = pic_list[slot];
964 if (pic == NULL || pic->pic_irqbase < 0)
966 for (irq = 0; irq < pic->pic_maxsources; irq++) {
967 is = pic->pic_sources[irq];
971 snprintf(buf, sizeof(buf), "%s %s", pic->pic_name, is->is_source);
993 struct pic_softc * const pic = pic_list[slot];
994 if (pic != NULL && pic->pic_irqbase >= 0) {
995 for (irq = 0; irq < pic->pic_maxsources; irq++) {
996 is = pic->pic_sources[irq];
1007 struct pic_softc * const pic = pic_list[slot];
1008 if (pic == NULL || pic->pic_irqbase < 0)
1010 for (irq = 0; irq < pic->pic_maxsources; irq++) {
1011 is = pic->pic_sources[irq];
1016 pic->pic_name, is->is_source);
1108 struct pic_softc *pic;
1115 pic = is->is_pic;
1116 if (pic && pic->pic_ops->pic_get_affinity)
1117 pic->pic_ops->pic_get_affinity(pic, is->is_irq, cpuset);
1145 struct pic_softc * const pic = is->is_pic;
1147 if (pic == NULL)
1149 if (pic->pic_ops->pic_set_affinity == NULL ||
1150 pic->pic_ops->pic_get_affinity == NULL)
1157 pic->pic_ops->pic_get_affinity(pic, is->is_irq, oldset);
1159 return pic->pic_ops->pic_set_affinity(pic, is->is_irq, newset);