subr_intr.c (3b03e1bb86157cc235563fc6e86c33b6bd9baea8) subr_intr.c (4b01a7fa76ce5abd0ade631ac5566804ba657090)
1/*-
2 * Copyright (c) 2015-2016 Svatopluk Kraus
3 * Copyright (c) 2015-2016 Michal Meloun
4 * All rights reserved.
5 * Copyright (c) 2015-2016 The FreeBSD Foundation
6 * Copyright (c) 2021 Jessica Clarke <jrtc27@FreeBSD.org>
7 *
8 * Portions of this software were developed by Andrew Turner under

--- 75 unchanged lines hidden (view full) ---

84#include <dev/iommu/iommu_msi.h>
85#endif
86
87#include "pic_if.h"
88#include "msi_if.h"
89
90#define INTRNAME_LEN (2*MAXCOMLEN + 1)
91
1/*-
2 * Copyright (c) 2015-2016 Svatopluk Kraus
3 * Copyright (c) 2015-2016 Michal Meloun
4 * All rights reserved.
5 * Copyright (c) 2015-2016 The FreeBSD Foundation
6 * Copyright (c) 2021 Jessica Clarke <jrtc27@FreeBSD.org>
7 *
8 * Portions of this software were developed by Andrew Turner under

--- 75 unchanged lines hidden (view full) ---

84#include <dev/iommu/iommu_msi.h>
85#endif
86
87#include "pic_if.h"
88#include "msi_if.h"
89
90#define INTRNAME_LEN (2*MAXCOMLEN + 1)
91
92/*
93 * Archs may define multiple roots with INTR_ROOT_NUM to support different kinds
94 * of interrupts (e.g. arm64 FIQs which use a different exception vector than
95 * IRQs).
96 */
97#if !defined(INTR_ROOT_NUM)
98#define INTR_ROOT_NUM 1
99#endif
100
92#ifdef DEBUG
93#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
94 printf(fmt,##args); } while (0)
95#else
96#define debugf(fmt, args...)
97#endif
98
99MALLOC_DECLARE(M_INTRNG);
100MALLOC_DEFINE(M_INTRNG, "intr", "intr interrupt handling");
101
102/* Root interrupt controller stuff. */
103struct intr_irq_root {
104 device_t dev;
105 intr_irq_filter_t *filter;
106 void *arg;
107};
108
101#ifdef DEBUG
102#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
103 printf(fmt,##args); } while (0)
104#else
105#define debugf(fmt, args...)
106#endif
107
108MALLOC_DECLARE(M_INTRNG);
109MALLOC_DEFINE(M_INTRNG, "intr", "intr interrupt handling");
110
111/* Root interrupt controller stuff. */
112struct intr_irq_root {
113 device_t dev;
114 intr_irq_filter_t *filter;
115 void *arg;
116};
117
109static struct intr_irq_root intr_irq_roots[INTR_ROOT_COUNT];
118static struct intr_irq_root intr_irq_roots[INTR_ROOT_NUM];
110
111struct intr_pic_child {
112 SLIST_ENTRY(intr_pic_child) pc_next;
113 struct intr_pic *pc_pic;
114 intr_child_irq_filter_t *pc_filter;
115 void *pc_filter_arg;
116 uintptr_t pc_start;
117 uintptr_t pc_length;

--- 205 unchanged lines hidden (view full) ---

323 bit_nclear(intrcnt_bitmap, idx, idx + 1);
324}
325
326/*
327 * Main interrupt dispatch handler. It's called straight
328 * from the assembler, where CPU interrupt is served.
329 */
330void
119
120struct intr_pic_child {
121 SLIST_ENTRY(intr_pic_child) pc_next;
122 struct intr_pic *pc_pic;
123 intr_child_irq_filter_t *pc_filter;
124 void *pc_filter_arg;
125 uintptr_t pc_start;
126 uintptr_t pc_length;

--- 205 unchanged lines hidden (view full) ---

332 bit_nclear(intrcnt_bitmap, idx, idx + 1);
333}
334
335/*
336 * Main interrupt dispatch handler. It's called straight
337 * from the assembler, where CPU interrupt is served.
338 */
339void
331intr_irq_handler(struct trapframe *tf, u_register_t root_type)
340intr_irq_handler(struct trapframe *tf, uint32_t rootnum)
332{
333 struct trapframe * oldframe;
334 struct thread * td;
335 struct intr_irq_root *root;
336
341{
342 struct trapframe * oldframe;
343 struct thread * td;
344 struct intr_irq_root *root;
345
337 KASSERT((uintmax_t)root_type < INTR_ROOT_COUNT,
338 ("%s: invalid interrupt root %ju", __func__, (uintmax_t)root_type));
346 KASSERT(rootnum < INTR_ROOT_NUM,
347 ("%s: invalid interrupt root %d", __func__, rootnum));
339
348
340 root = &intr_irq_roots[root_type];
349 root = &intr_irq_roots[rootnum];
341 KASSERT(root->filter != NULL, ("%s: no filter", __func__));
342
343 kasan_mark(tf, sizeof(*tf), sizeof(*tf), 0);
344 kmsan_mark(tf, sizeof(*tf), KMSAN_STATE_INITED);
345
346 VM_CNT_INC(v_intr);
347 critical_enter();
348 td = curthread;

--- 132 unchanged lines hidden (view full) ---

481 */
482 if (irq_next_free >= intr_nirq)
483 irq_next_free = 0;
484
485 return (0);
486}
487
488device_t
350 KASSERT(root->filter != NULL, ("%s: no filter", __func__));
351
352 kasan_mark(tf, sizeof(*tf), sizeof(*tf), 0);
353 kmsan_mark(tf, sizeof(*tf), KMSAN_STATE_INITED);
354
355 VM_CNT_INC(v_intr);
356 critical_enter();
357 td = curthread;

--- 132 unchanged lines hidden (view full) ---

490 */
491 if (irq_next_free >= intr_nirq)
492 irq_next_free = 0;
493
494 return (0);
495}
496
497device_t
489intr_irq_root_device(enum root_type root_type)
498intr_irq_root_device(uint32_t rootnum)
490{
499{
491 KASSERT((uintmax_t)root_type < INTR_ROOT_COUNT,
492 ("%s: invalid interrupt root %ju", __func__, (uintmax_t)root_type));
493 return (intr_irq_roots[root_type].dev);
500 KASSERT(rootnum < INTR_ROOT_NUM,
501 ("%s: invalid interrupt root %d", __func__, rootnum));
502 return (intr_irq_roots[rootnum].dev);
494}
495
496/*
497 * Initialize interrupt source and register it into global interrupt table.
498 */
499int
500intr_isrc_register(struct intr_irqsrc *isrc, device_t dev, u_int flags,
501 const char *fmt, ...)

--- 384 unchanged lines hidden (view full) ---

886 * In FDT case, according to ePAPR approved version 1.1 from 08 April 2011,
887 * page 30:
888 * "The root of the interrupt tree is determined when traversal
889 * of the interrupt tree reaches an interrupt controller node without
890 * an interrupts property and thus no explicit interrupt parent."
891 */
892int
893intr_pic_claim_root(device_t dev, intptr_t xref, intr_irq_filter_t *filter,
503}
504
505/*
506 * Initialize interrupt source and register it into global interrupt table.
507 */
508int
509intr_isrc_register(struct intr_irqsrc *isrc, device_t dev, u_int flags,
510 const char *fmt, ...)

--- 384 unchanged lines hidden (view full) ---

895 * In FDT case, according to ePAPR approved version 1.1 from 08 April 2011,
896 * page 30:
897 * "The root of the interrupt tree is determined when traversal
898 * of the interrupt tree reaches an interrupt controller node without
899 * an interrupts property and thus no explicit interrupt parent."
900 */
901int
902intr_pic_claim_root(device_t dev, intptr_t xref, intr_irq_filter_t *filter,
894 void *arg, enum root_type root_type)
903 void *arg, uint32_t rootnum)
895{
896 struct intr_pic *pic;
897 struct intr_irq_root *root;
898
899 pic = pic_lookup(dev, xref, FLAG_PIC);
900 if (pic == NULL) {
901 device_printf(dev, "not registered\n");
902 return (EINVAL);

--- 8 unchanged lines hidden (view full) ---

911 return (EINVAL);
912 }
913
914 /*
915 * Only one interrupt controllers could be on the root for now.
916 * Note that we further suppose that there is not threaded interrupt
917 * routine (handler) on the root. See intr_irq_handler().
918 */
904{
905 struct intr_pic *pic;
906 struct intr_irq_root *root;
907
908 pic = pic_lookup(dev, xref, FLAG_PIC);
909 if (pic == NULL) {
910 device_printf(dev, "not registered\n");
911 return (EINVAL);

--- 8 unchanged lines hidden (view full) ---

920 return (EINVAL);
921 }
922
923 /*
924 * Only one interrupt controllers could be on the root for now.
925 * Note that we further suppose that there is not threaded interrupt
926 * routine (handler) on the root. See intr_irq_handler().
927 */
919 KASSERT((uintmax_t)root_type < INTR_ROOT_COUNT,
920 ("%s: invalid interrupt root %ju", __func__, (uintmax_t)root_type));
921 root = &intr_irq_roots[root_type];
928 KASSERT(rootnum < INTR_ROOT_NUM,
929 ("%s: invalid interrupt root %d", __func__, rootnum));
930 root = &intr_irq_roots[rootnum];
922 if (root->dev != NULL) {
923 device_printf(dev, "another root already set\n");
924 return (EBUSY);
925 }
926
927 root->dev = dev;
928 root->filter = filter;
929 root->arg = arg;

--- 636 unchanged lines hidden (view full) ---

1566#ifdef SMP
1567/*
1568 * Init interrupt controller on another CPU.
1569 */
1570void
1571intr_pic_init_secondary(void)
1572{
1573 device_t dev;
931 if (root->dev != NULL) {
932 device_printf(dev, "another root already set\n");
933 return (EBUSY);
934 }
935
936 root->dev = dev;
937 root->filter = filter;
938 root->arg = arg;

--- 636 unchanged lines hidden (view full) ---

1575#ifdef SMP
1576/*
1577 * Init interrupt controller on another CPU.
1578 */
1579void
1580intr_pic_init_secondary(void)
1581{
1582 device_t dev;
1574 enum root_type root_type;
1583 uint32_t rootnum;
1575
1576 /*
1577 * QQQ: Only root PICs are aware of other CPUs ???
1578 */
1579 //mtx_lock(&isrc_table_lock);
1584
1585 /*
1586 * QQQ: Only root PICs are aware of other CPUs ???
1587 */
1588 //mtx_lock(&isrc_table_lock);
1580 for (root_type = 0; root_type < INTR_ROOT_COUNT; root_type++) {
1581 dev = intr_irq_roots[root_type].dev;
1589 for (rootnum = 0; rootnum < INTR_ROOT_NUM; rootnum++) {
1590 dev = intr_irq_roots[rootnum].dev;
1582 if (dev != NULL) {
1591 if (dev != NULL) {
1583 PIC_INIT_SECONDARY(dev, root_type);
1592 PIC_INIT_SECONDARY(dev, rootnum);
1584 }
1585 }
1586 //mtx_unlock(&isrc_table_lock);
1587}
1588#endif
1589
1590#ifdef DDB
1591DB_SHOW_COMMAND_FLAGS(irqs, db_show_irqs, DB_CMD_MEMSAFE)

--- 362 unchanged lines hidden ---
1593 }
1594 }
1595 //mtx_unlock(&isrc_table_lock);
1596}
1597#endif
1598
1599#ifdef DDB
1600DB_SHOW_COMMAND_FLAGS(irqs, db_show_irqs, DB_CMD_MEMSAFE)

--- 362 unchanged lines hidden ---