Dynamically compute the PSL value for spl{bio,net,tty,imp}() calls.

This commit is contained in:
thorpej 1996-12-09 03:04:46 +00:00
parent c36215249a
commit ce7ecde8a3
3 changed files with 135 additions and 12 deletions

View File

@ -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();
}
/*

View File

@ -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));

View File

@ -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()