Dynamically compute the PSL value for spl{bio,net,tty,imp}() calls.
This commit is contained in:
parent
c36215249a
commit
ce7ecde8a3
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: isr.c,v 1.3 1996/10/13 03:14:29 christos Exp $ */
|
||||
/* $NetBSD: isr.c,v 1.4 1996/12/09 03:04:46 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996 Jason R. Thorpe.
|
||||
@ -46,16 +46,21 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <net/netisr.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <hp300/hp300/isr.h>
|
||||
|
||||
typedef LIST_HEAD(, isr) isr_list_t;
|
||||
isr_list_t isr_list[NISR];
|
||||
|
||||
u_short hp300_bioipl, hp300_netipl, hp300_ttyipl, hp300_impipl;
|
||||
|
||||
extern int intrcnt[]; /* from locore.s */
|
||||
|
||||
void isrcomputeipl __P((void));
|
||||
|
||||
void
|
||||
isrinit()
|
||||
{
|
||||
@ -65,13 +70,90 @@ isrinit()
|
||||
for (i = 0; i < NISR; ++i) {
|
||||
LIST_INIT(&isr_list[i]);
|
||||
}
|
||||
|
||||
/* Default interrupt priorities. */
|
||||
hp300_bioipl = hp300_netipl = hp300_ttyipl = hp300_impipl =
|
||||
(PSL_S|PSL_IPL3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan all of the ISRs, recomputing the interrupt levels for the spl*()
|
||||
* calls. This doesn't have to be fast.
|
||||
*/
|
||||
void
|
||||
isrcomputeipl()
|
||||
{
|
||||
struct isr *isr;
|
||||
int ipl;
|
||||
|
||||
/* Start with low values. */
|
||||
hp300_bioipl = hp300_netipl = hp300_ttyipl = hp300_impipl =
|
||||
(PSL_S|PSL_IPL3);
|
||||
|
||||
for (ipl = 0; ipl < NISR; ipl++) {
|
||||
for (isr = isr_list[ipl].lh_first; isr != NULL;
|
||||
isr = isr->isr_link.le_next) {
|
||||
/*
|
||||
* Bump up the level for a given priority,
|
||||
* if necessary.
|
||||
*/
|
||||
switch (isr->isr_priority) {
|
||||
case ISRPRI_BIO:
|
||||
if (ipl > PSLTOIPL(hp300_bioipl))
|
||||
hp300_bioipl = IPLTOPSL(ipl);
|
||||
break;
|
||||
|
||||
case ISRPRI_NET:
|
||||
if (ipl > PSLTOIPL(hp300_netipl))
|
||||
hp300_netipl = IPLTOPSL(ipl);
|
||||
break;
|
||||
|
||||
case ISRPRI_TTY:
|
||||
case ISRPRI_TTYNOBUF:
|
||||
if (ipl > PSLTOIPL(hp300_ttyipl))
|
||||
hp300_ttyipl = IPLTOPSL(ipl);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("priority = %d\n", isr->isr_priority);
|
||||
panic("isrcomputeipl: bad priority");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enforce `bio <= net <= tty <= imp'
|
||||
*/
|
||||
|
||||
if (hp300_netipl < hp300_bioipl)
|
||||
hp300_netipl = hp300_bioipl;
|
||||
|
||||
if (hp300_ttyipl < hp300_netipl)
|
||||
hp300_ttyipl = hp300_netipl;
|
||||
|
||||
if (hp300_impipl < hp300_ttyipl)
|
||||
hp300_impipl = hp300_ttyipl;
|
||||
}
|
||||
|
||||
void
|
||||
isrprintlevels()
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("psl: bio = 0x%x, net = 0x%x, tty = 0x%x, imp = 0x%x\n",
|
||||
hp300_bioipl, hp300_netipl, hp300_ttyipl, hp300_impipl);
|
||||
#endif
|
||||
|
||||
printf("interrupt levels: bio = %d, net = %d, tty = %d\n",
|
||||
PSLTOIPL(hp300_bioipl), PSLTOIPL(hp300_netipl),
|
||||
PSLTOIPL(hp300_ttyipl));
|
||||
}
|
||||
|
||||
/*
|
||||
* Establish an interrupt handler.
|
||||
* Called by driver attach functions.
|
||||
*/
|
||||
void
|
||||
void *
|
||||
isrlink(func, arg, ipl, priority)
|
||||
int (*func) __P((void *));
|
||||
void *arg;
|
||||
@ -120,7 +202,7 @@ isrlink(func, arg, ipl, priority)
|
||||
list = &isr_list[ipl];
|
||||
if (list->lh_first == NULL) {
|
||||
LIST_INSERT_HEAD(list, newisr, isr_link);
|
||||
return;
|
||||
goto compute;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -132,7 +214,7 @@ isrlink(func, arg, ipl, priority)
|
||||
curisr = curisr->isr_link.le_next) {
|
||||
if (newisr->isr_priority > curisr->isr_priority) {
|
||||
LIST_INSERT_BEFORE(curisr, newisr, isr_link);
|
||||
return;
|
||||
goto compute;
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,6 +223,25 @@ isrlink(func, arg, ipl, priority)
|
||||
* on the end.
|
||||
*/
|
||||
LIST_INSERT_AFTER(curisr, newisr, isr_link);
|
||||
|
||||
compute:
|
||||
/* Compute new interrupt levels. */
|
||||
isrcomputeipl();
|
||||
return (newisr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disestablish an interrupt handler.
|
||||
*/
|
||||
void
|
||||
isrunlink(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct isr *isr = arg;
|
||||
|
||||
LIST_REMOVE(isr, isr_link);
|
||||
free(isr, M_DEVBUF);
|
||||
isrcomputeipl();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: isr.h,v 1.6 1996/02/28 01:03:53 thorpej Exp $ */
|
||||
/* $NetBSD: isr.h,v 1.7 1996/12/09 03:04:47 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
@ -55,12 +55,23 @@ struct isr {
|
||||
|
||||
/*
|
||||
* ISR priorities. These are not the same as interrupt levels.
|
||||
* These serve 2 purposes:
|
||||
* - properly order ISRs in the list
|
||||
* - compute levels for spl*() calls.
|
||||
*/
|
||||
#define ISRPRI_BIO 0
|
||||
#define ISRPRI_NET 1
|
||||
#define ISRPRI_TTY 2
|
||||
#define ISRPRI_TTYNOBUF 3
|
||||
|
||||
/*
|
||||
* Convert PSL values to IPLs and vice-versa.
|
||||
*/
|
||||
#define PSLTOIPL(x) (((x) >> 8) & 0xf)
|
||||
#define IPLTOPSL(x) ((((x) & 0xf) << 8) | PSL_S)
|
||||
|
||||
void isrinit __P((void));
|
||||
void isrlink __P((int (*)(void *), void *, int, int));
|
||||
void *isrlink __P((int (*)(void *), void *, int, int));
|
||||
void isrunlink __P((void *));
|
||||
void isrdispatch __P((int));
|
||||
void isrprintlevels __P((void));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: param.h,v 1.26 1996/05/17 15:38:08 thorpej Exp $ */
|
||||
/* $NetBSD: param.h,v 1.27 1996/12/09 03:04:48 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
@ -163,12 +163,23 @@
|
||||
#define spl6() _spl(PSL_S|PSL_IPL6)
|
||||
#define spl7() _spl(PSL_S|PSL_IPL7)
|
||||
|
||||
#if defined(_KERNEL) && !defined(_LOCORE)
|
||||
/*
|
||||
* These four globals contain the appropriate PSL_S|PSL_IPL? values
|
||||
* to raise interrupt priority to the requested level.
|
||||
*/
|
||||
extern unsigned short hp300_bioipl;
|
||||
extern unsigned short hp300_netipl;
|
||||
extern unsigned short hp300_ttyipl;
|
||||
extern unsigned short hp300_impipl;
|
||||
#endif /* _KERNEL && !_LOCORE */
|
||||
|
||||
#define splsoftclock() spl1()
|
||||
#define splsoftnet() spl1()
|
||||
#define splbio() spl5()
|
||||
#define splnet() spl5()
|
||||
#define spltty() spl5()
|
||||
#define splimp() spl5()
|
||||
#define splbio() _spl(hp300_bioipl)
|
||||
#define splnet() _spl(hp300_netipl)
|
||||
#define spltty() _spl(hp300_ttyipl)
|
||||
#define splimp() _spl(hp300_impipl)
|
||||
#define splclock() spl6()
|
||||
#define splstatclock() spl6()
|
||||
#define splvm() spl6()
|
||||
|
Loading…
Reference in New Issue
Block a user