Reimplement spl*() as function calls. Implement software interrupts.

This commit is contained in:
Doug Rabson 1998-06-11 11:51:27 +00:00
parent 9945598607
commit c48c13cb5a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36897
3 changed files with 139 additions and 41 deletions

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: ipl_funcs.c,v 1.1 1998/06/10 10:52:49 dfr Exp $
*/
#include <sys/types.h>
@ -33,15 +33,108 @@
#include <net/netisr.h>
unsigned int netisr;
void (*netisrs[32]) __P((void));
u_int64_t ipending;
int cpl;
static void atomic_setbit(u_int64_t* p, u_int64_t bit)
{
u_int64_t temp;
__asm__ __volatile__ (
"1:\tldq_l %0,%2\n\t" /* load current mask value, asserting lock */
"or %3,%0,%0\n\t" /* add our bits */
"stq_c %0,%1\n\t" /* attempt to store */
"beq %0,2f\n\t" /* if the store failed, spin */
"br 3f\n" /* it worked, exit */
"2:\tbr 1b\n" /* *p not updated, loop */
"3:\tmb\n" /* it worked */
: "=&r"(temp), "=m" (*p)
: "m"(*p), "r"(bit)
: "memory");
}
static u_int64_t atomic_readandclear(u_int64_t* p)
{
u_int64_t v, temp;
__asm__ __volatile__ (
"wmb\n" /* ensure pending writes have drained */
"1:\tldq_l %0,%3\n\t" /* load current value, asserting lock */
"ldiq %1,0\n\t" /* value to store */
"stq_c %1,%2\n\t" /* attempt to store */
"beq %1,2f\n\t" /* if the store failed, spin */
"br 3f\n" /* it worked, exit */
"2:\tbr 1b\n" /* *p not updated, loop */
"3:\tmb\n" /* it worked */
: "=&r"(v), "=&r"(temp), "=m" (*p)
: "m"(*p)
: "memory");
return v;
}
void
do_sir()
{
u_int64_t pend = atomic_readandclear(&ipending);
#if 0
/*
* Later - no users of these yet.
*/
if (pend & (1 << SWI_TTY))
swi_tty();
if (pend & (1 << SWI_NET))
swi_net();
#endif
if (pend & (1 << SWI_CLOCK))
softclock();
}
void (*netisrs[32]) __P((void));
u_int64_t ssir;
#define GENSETSOFT(name, bit) \
\
void name(void) \
{ \
atomic_setbit(&ipending, (1 << bit)); \
}
GENSETSOFT(setsofttty, SWI_TTY)
GENSETSOFT(setsoftnet, SWI_NET)
GENSETSOFT(setsoftcamnet, SWI_CAMNET)
GENSETSOFT(setsoftcambio, SWI_CAMBIO)
GENSETSOFT(setsoftvm, SWI_VM)
GENSETSOFT(setsoftclock, SWI_CLOCK)
#define SPLDOWN(name, pri) \
\
int name(void) \
{ \
int s = alpha_pal_swpipl(ALPHA_PSL_IPL_##pri); \
cpl = ALPHA_PSL_IPL_##pri; \
return s; \
}
SPLDOWN(splsoftclock, SOFT)
SPLDOWN(splsoftnet, SOFT)
#define SPLUP(name, pri) \
\
int name(void) \
{ \
if (ALPHA_PSL_IPL_##pri > cpl) { \
int s = alpha_pal_swpipl(ALPHA_PSL_IPL_##pri); \
cpl = ALPHA_PSL_IPL_##pri; \
return s; \
} else \
return cpl; \
}
SPLUP(splnet, IO)
SPLUP(splbio, IO)
SPLUP(splimp, IO)
SPLUP(spltty, IO)
SPLUP(splvm, IO)
SPLUP(splclock, CLOCK)
SPLUP(splstatclock, CLOCK)
SPLUP(splhigh, HIGH)
void
spl0()
@ -49,4 +142,16 @@ spl0()
/* XXX soft interrupts here */
alpha_pal_swpipl(ALPHA_PSL_IPL_0);
cpl = ALPHA_PSL_IPL_0;
}
void
splx(int s)
{
if (s) {
alpha_pal_swpipl(s);
cpl = s;
} else
spl0();
}

View File

@ -1,4 +1,4 @@
/* $Id$ */
/* $Id: swtch.s,v 1.1 1998/06/10 10:53:23 dfr Exp $ */
/* $NetBSD: locore.s,v 1.47 1998/03/22 07:26:32 thorpej Exp $ */
/*
@ -278,7 +278,7 @@ LEAF(switch_trampoline, 0)
* exception_return: return from trap, exception, or syscall
*/
BSS(ssir, 8)
IMPORT(ipending, 8)
IMPORT(astpending, 8)
LEAF(exception_return, 1) /* XXX should be NESTED */
@ -290,7 +290,7 @@ Ler1: LDGP(pv)
bne t0, Lrestoreregs /* != 0: can't do AST or SIR */
/* see if we can do an SIR */
ldq t1, ssir /* SIR pending? */
ldq t1, ipending /* SIR pending? */
beq t1, Lchkast /* no, try an AST*/
/* We've got a SIR. */

View File

@ -23,53 +23,46 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: ipl.h,v 1.1 1998/06/10 10:55:05 dfr Exp $
*/
#ifndef _MACHINE_IPL_H_
#define _MACHINE_IPL_H_
#include <machine/alpha_cpu.h>
/* IPL-lowering/restoring macros */
#define splx(s) \
((s) == ALPHA_PSL_IPL_0 ? spl0() : alpha_pal_swpipl(s))
#define splsoft() alpha_pal_swpipl(ALPHA_PSL_IPL_SOFT)
#define splsoftclock() splsoft()
#define splsoftnet() splsoft()
/* IPL-raising functions/macros */
static __inline int _splraise __P((int)) __attribute__ ((unused));
static __inline int
_splraise(s)
int s;
{
int cur = alpha_pal_rdps() & ALPHA_PSL_IPL_MASK;
return (s > cur ? alpha_pal_swpipl(s) : cur);
}
#define splnet() _splraise(ALPHA_PSL_IPL_IO)
#define splbio() _splraise(ALPHA_PSL_IPL_IO)
#define splimp() _splraise(ALPHA_PSL_IPL_IO)
#define spltty() _splraise(ALPHA_PSL_IPL_IO)
#define splvm() _splraise(ALPHA_PSL_IPL_IO)
#define splclock() _splraise(ALPHA_PSL_IPL_CLOCK)
#define splstatclock() _splraise(ALPHA_PSL_IPL_CLOCK)
#define splhigh() _splraise(ALPHA_PSL_IPL_HIGH)
/*
* simulated software interrupt register
* Software interrupt bit numbers
*/
extern u_int64_t ssir;
#define SWI_TTY 0
#define SWI_NET 1
#define SWI_CAMNET 2
#define SWI_CAMBIO 3
#define SWI_VM 4
#define SWI_CLOCK 5
#define SIR_NET 0x1
#define SIR_CLOCK 0x2
extern int splsoftclock(void);
extern int splsoftnet(void);
extern int splnet(void);
extern int splbio(void);
extern int splimp(void);
extern int spltty(void);
extern int splvm(void);
extern int splclock(void);
extern int splstatclock(void);
extern int splhigh(void);
#define setsoftnet() ssir |= SIR_NET
#define setsoftclock() ssir |= SIR_CLOCK
extern void setsofttty(void);
extern void setsoftnet(void);
extern void setsoftcamnet(void);
extern void setsoftcambio(void);
extern void setsoftvm(void);
extern void setsoftclock(void);
extern void spl0(void);
extern void spl0(void);
extern void splx(int);
#if 0
/* XXX bogus */
extern unsigned cpl; /* current priority level mask */
#endif
#endif /* !_MACHINE_MD_VAR_H_ */