Mon Jan 15 02:13:16 2024 UTC (139d)
Add the "ISR priority" notion that's used on some m68k platforms:

       /*
        * Some devices are particularly sensitive to interrupt
        * handling latency.  Unbuffered serial ports, for example,
        * can lose data if their interrupts aren't handled with
        * reasonable speed.  For this reason, we sort interrupt
        * handlers by an abstract "ISR" priority, inserting higher-
        * priority interrupts before lower-priority interrupts.
        */

(...within the same shared auto-vectored interrupt list.)


(thorpej)
diff -r1.1 -r1.2 src/sys/arch/m68k/include/intr.h
diff -r1.3 -r1.4 src/sys/arch/m68k/m68k/m68k_intr.c

cvs diff -r1.1 -r1.2 src/sys/arch/m68k/include/intr.h (expand / switch to unified diff)

--- src/sys/arch/m68k/include/intr.h 2024/01/14 22:32:32 1.1
+++ src/sys/arch/m68k/include/intr.h 2024/01/15 02:13:16 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: intr.h,v 1.1 2024/01/14 22:32:32 thorpej Exp $ */ 1/* $NetBSD: intr.h,v 1.2 2024/01/15 02:13:16 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2023, 2024 The NetBSD Foundation, Inc. 4 * Copyright (c) 2023, 2024 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe. 8 * by Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -39,26 +39,38 @@ @@ -39,26 +39,38 @@
39 * Logical interrupt priority levels -- these are distinct from 39 * Logical interrupt priority levels -- these are distinct from
40 * the hardware interrupt priority levels of the m68k. 40 * the hardware interrupt priority levels of the m68k.
41 */ 41 */
42#define IPL_NONE 0 42#define IPL_NONE 0
43#define IPL_SOFTCLOCK 1 /* clock software interrupts */ 43#define IPL_SOFTCLOCK 1 /* clock software interrupts */
44#define IPL_SOFTBIO 2 /* block device software interrupts */ 44#define IPL_SOFTBIO 2 /* block device software interrupts */
45#define IPL_SOFTNET 3 /* network software interrupts */ 45#define IPL_SOFTNET 3 /* network software interrupts */
46#define IPL_SOFTSERIAL 4 /* serial device software interrupts */ 46#define IPL_SOFTSERIAL 4 /* serial device software interrupts */
47#define IPL_VM 5 /* all interrupts that can allocate memory */ 47#define IPL_VM 5 /* all interrupts that can allocate memory */
48#define IPL_SCHED 6 /* scheduler / hard clock interrupts */ 48#define IPL_SCHED 6 /* scheduler / hard clock interrupts */
49#define IPL_HIGH 7 /* blocks all interrupts */ 49#define IPL_HIGH 7 /* blocks all interrupts */
50#define NIPL 8 50#define NIPL 8
51 51
 52/*
 53 * Abstract ISR priorities. These allow sorting of latency-sensitive
 54 * devices earlier on the shared auto-vectored interrupt lists.
 55 */
 56#define ISRPRI_BIO 0 /* a block I/O device */
 57#define ISRPRI_MISC 0 /* misc. devices */
 58#define ISRPRI_NET 1 /* a network interface */
 59#define ISRPRI_TTY 2 /* a serial port */
 60#define ISRPRI_DISPLAY 2 /* display devices / framebuffers */
 61#define ISRPRI_TTYNOBUF 3 /* a particularly bad serial port */
 62#define ISRPRI_AUDIO 4 /* audio devices */
 63
52#if defined(_KERNEL) || defined(_KMEMUSER) 64#if defined(_KERNEL) || defined(_KMEMUSER)
53typedef struct { 65typedef struct {
54 uint16_t _psl; /* physical manifestation of logical IPL_* */ 66 uint16_t _psl; /* physical manifestation of logical IPL_* */
55} ipl_cookie_t; 67} ipl_cookie_t;
56#endif 68#endif
57 69
58#ifdef _KERNEL 70#ifdef _KERNEL
59extern int idepth; /* interrupt depth */ 71extern int idepth; /* interrupt depth */
60extern const uint16_t ipl2psl_table[NIPL]; 72extern const uint16_t ipl2psl_table[NIPL];
61 73
62typedef int ipl_t; /* logical IPL_* value */ 74typedef int ipl_t; /* logical IPL_* value */
63 75
64static inline bool 76static inline bool
@@ -98,26 +110,27 @@ splraiseipl(ipl_cookie_t icookie) @@ -98,26 +110,27 @@ splraiseipl(ipl_cookie_t icookie)
98#define spl0() _spl0() 110#define spl0() _spl0()
99#define splx(s) _splx(s) 111#define splx(s) _splx(s)
100 112
101#ifdef _M68K_INTR_PRIVATE 113#ifdef _M68K_INTR_PRIVATE
102#include <sys/queue.h> 114#include <sys/queue.h>
103 115
104struct m68k_intrhand { 116struct m68k_intrhand {
105 LIST_ENTRY(m68k_intrhand) ih_link; 117 LIST_ENTRY(m68k_intrhand) ih_link;
106 int (*ih_func)(void *); 118 int (*ih_func)(void *);
107 void *ih_arg; 119 void *ih_arg;
108 struct evcnt *ih_evcnt; 120 struct evcnt *ih_evcnt;
109 int ih_ipl; /* m68k IPL, not IPL_* */ 121 int ih_ipl; /* m68k IPL, not IPL_* */
110 int ih_vec; 122 int ih_vec;
 123 int ih_isrpri;
111}; 124};
112LIST_HEAD(m68k_intrhand_list, m68k_intrhand); 125LIST_HEAD(m68k_intrhand_list, m68k_intrhand);
113 126
114struct m68k_ih_allocfuncs { 127struct m68k_ih_allocfuncs {
115 struct m68k_intrhand * (*alloc)(int km_flag); 128 struct m68k_intrhand * (*alloc)(int km_flag);
116 void (*free)(struct m68k_intrhand *); 129 void (*free)(struct m68k_intrhand *);
117}; 130};
118#else 131#else
119struct m68k_ih_allocfuncs; 132struct m68k_ih_allocfuncs;
120#endif /* _M68K_INTR_PRIVATE */ 133#endif /* _M68K_INTR_PRIVATE */
121 134
122struct evcnt; 135struct evcnt;
123 136

cvs diff -r1.3 -r1.4 src/sys/arch/m68k/m68k/m68k_intr.c (expand / switch to unified diff)

--- src/sys/arch/m68k/m68k/m68k_intr.c 2024/01/15 00:37:08 1.3
+++ src/sys/arch/m68k/m68k/m68k_intr.c 2024/01/15 02:13:16 1.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: m68k_intr.c,v 1.3 2024/01/15 00:37:08 thorpej Exp $ */ 1/* $NetBSD: m68k_intr.c,v 1.4 2024/01/15 02:13:16 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 2023, 2024 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 2023, 2024 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe. 8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */  30 */
31 31
32/* 32/*
33 * Common interrupt handling for m68k platforms. 33 * Common interrupt handling for m68k platforms.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: m68k_intr.c,v 1.3 2024/01/15 00:37:08 thorpej Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: m68k_intr.c,v 1.4 2024/01/15 02:13:16 thorpej Exp $");
38 38
39#define _M68K_INTR_PRIVATE 39#define _M68K_INTR_PRIVATE
40 40
41#include <sys/param.h>  41#include <sys/param.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/kmem.h> 43#include <sys/kmem.h>
44#include <sys/vmmeter.h> 44#include <sys/vmmeter.h>
45#include <sys/device.h> 45#include <sys/device.h>
46#include <sys/cpu.h> 46#include <sys/cpu.h>
47#include <sys/bus.h> 47#include <sys/bus.h>
48#include <sys/once.h> 48#include <sys/once.h>
49#include <sys/intr.h> 49#include <sys/intr.h>
50 50
@@ -198,27 +198,27 @@ m68k_intr_init(const struct m68k_ih_allo @@ -198,27 +198,27 @@ m68k_intr_init(const struct m68k_ih_allo
198 for (i = 0; i < NAUTOVECTORS; i++) { 198 for (i = 0; i < NAUTOVECTORS; i++) {
199 LIST_INIT(&m68k_intrhands_autovec[i]); 199 LIST_INIT(&m68k_intrhands_autovec[i]);
200 } 200 }
201} 201}
202 202
203/* 203/*
204 * m68k_intr_establish -- 204 * m68k_intr_establish --
205 * Establish an interrupt handler at the specified vector. 205 * Establish an interrupt handler at the specified vector.
206 * XXX We don't do anything with isrpri yet. 206 * XXX We don't do anything with isrpri yet.
207 * XXX We don't do anything with the flags yet. 207 * XXX We don't do anything with the flags yet.
208 */ 208 */
209void * 209void *
210m68k_intr_establish(int (*func)(void *), void *arg, struct evcnt *ev, 210m68k_intr_establish(int (*func)(void *), void *arg, struct evcnt *ev,
211 int vec, int ipl, int isrpri __unused, int flags __unused) 211 int vec, int ipl, int isrpri, int flags __unused)
212{ 212{
213 struct m68k_intrhand *ih; 213 struct m68k_intrhand *ih;
214 int s; 214 int s;
215 215
216 /* 216 /*
217 * If a platform doesn't want special behavior, we don't 217 * If a platform doesn't want special behavior, we don't
218 * require them to call m68k_intr_init(); we just handle 218 * require them to call m68k_intr_init(); we just handle
219 * it here. 219 * it here.
220 * 220 *
221 * XXX m68k_intr_init() might be called really early, so 221 * XXX m68k_intr_init() might be called really early, so
222 * XXX can't use a once control. 222 * XXX can't use a once control.
223 */ 223 */
224 if (__predict_false(ih_allocfuncs == NULL)) { 224 if (__predict_false(ih_allocfuncs == NULL)) {
@@ -232,46 +232,71 @@ m68k_intr_establish(int (*func)(void *), @@ -232,46 +232,71 @@ m68k_intr_establish(int (*func)(void *),
232 232
233#ifdef __HAVE_M68K_INTR_VECTORED 233#ifdef __HAVE_M68K_INTR_VECTORED
234 KASSERT(vec >= 0); 234 KASSERT(vec >= 0);
235 KASSERT(vec < NVECTORS); 235 KASSERT(vec < NVECTORS);
236#else 236#else
237 KASSERT(vec == 0); 237 KASSERT(vec == 0);
238#endif /* __HAVE_M68K_INTR_VECTORED */ 238#endif /* __HAVE_M68K_INTR_VECTORED */
239 239
240 ih = m68k_ih_alloc(); 240 ih = m68k_ih_alloc();
241 ih->ih_func = func; 241 ih->ih_func = func;
242 ih->ih_arg = arg; 242 ih->ih_arg = arg;
243 ih->ih_vec = vec; 243 ih->ih_vec = vec;
244 ih->ih_ipl = ipl; 244 ih->ih_ipl = ipl;
 245 ih->ih_isrpri = isrpri;
245 if ((ih->ih_evcnt = ev) == NULL) { 246 if ((ih->ih_evcnt = ev) == NULL) {
246 ih->ih_evcnt = &bitbucket; 247 ih->ih_evcnt = &bitbucket;
247 } 248 }
248 249
249#ifdef __HAVE_M68K_INTR_VECTORED 250#ifdef __HAVE_M68K_INTR_VECTORED
250 if (vec != 0) { 251 if (vec != 0) {
251 if (vec_get_entry(vec) != INTR_FREEVEC) { 252 if (vec_get_entry(vec) != INTR_FREEVEC) {
252 m68k_ih_free(ih); 253 m68k_ih_free(ih);
253 return NULL; 254 return NULL;
254 } 255 }
255 if (! m68k_intrvec_add(ih)) { 256 if (! m68k_intrvec_add(ih)) {
256 m68k_ih_free(ih); 257 m68k_ih_free(ih);
257 return NULL; 258 return NULL;
258 } 259 }
259 return ih; 260 return ih;
260 } 261 }
261#endif 262#endif
262 263
 264 /*
 265 * Some devices are particularly sensitive to interrupt
 266 * handling latency. Unbuffered serial ports, for example,
 267 * can lose data if their interrupts aren't handled with
 268 * reasonable speed. For this reason, we sort interrupt
 269 * handlers by an abstract "ISR" priority, inserting higher-
 270 * priority interrupts before lower-priority interrupts.
 271 */
 272 struct m68k_intrhand_list * const list = &m68k_intrhands_autovec[ipl];
 273 struct m68k_intrhand *curih;
 274
263 s = splhigh(); 275 s = splhigh();
264 LIST_INSERT_HEAD(&m68k_intrhands_autovec[ipl], ih, ih_link); 276 if (LIST_EMPTY(list)) {
 277 LIST_INSERT_HEAD(list, ih, ih_link);
 278 goto done;
 279 }
 280 for (curih = LIST_FIRST(list);
 281 LIST_NEXT(curih, ih_link) != NULL;
 282 curih = LIST_NEXT(curih, ih_link)) {
 283 if (ih->ih_isrpri > curih->ih_isrpri) {
 284 LIST_INSERT_BEFORE(curih, ih, ih_link);
 285 goto done;
 286 }
 287 }
 288 LIST_INSERT_AFTER(curih, ih, ih_link);
 289 done:
265 splx(s); 290 splx(s);
266 291
267 return ih; 292 return ih;
268} 293}
269 294
270/* 295/*
271 * m68k_intr_disestablish -- 296 * m68k_intr_disestablish --
272 * Remove an interrupt handler. Returns true if the handler 297 * Remove an interrupt handler. Returns true if the handler
273 * list for this vector is now empty. 298 * list for this vector is now empty.
274 */ 299 */
275bool 300bool
276m68k_intr_disestablish(void *v) 301m68k_intr_disestablish(void *v)
277{ 302{