Implement generic soft interrupt for hpcarm.
This commit is contained in:
parent
7073a10bbd
commit
3d513c3e7a
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.hpcarm,v 1.15 2001/05/06 18:31:15 bjh21 Exp $
|
||||
# $NetBSD: files.hpcarm,v 1.16 2001/05/22 17:25:15 toshii Exp $
|
||||
#
|
||||
# First try for arm-specific configuration info
|
||||
#
|
||||
|
@ -38,6 +38,7 @@ file arch/hpcarm/hpcarm/process_machdep.c
|
|||
file arch/hpcarm/hpcarm/procfs_machdep.c procfs
|
||||
file arch/hpcarm/hpcarm/setcpsr.S
|
||||
file arch/hpcarm/hpcarm/setstack.S
|
||||
file arch/hpcarm/hpcarm/softintr.c
|
||||
file arch/hpcarm/hpcarm/spl.S
|
||||
file arch/hpcarm/hpcarm/stubs.c
|
||||
file arch/hpcarm/hpcarm/vm_machdep.c
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: intr.c,v 1.2 2001/04/30 15:54:28 toshii Exp $ */
|
||||
/* $NetBSD: intr.c,v 1.3 2001/05/22 17:25:16 toshii Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994-1998 Mark Brinicombe.
|
||||
|
@ -52,6 +52,7 @@
|
|||
u_int soft_interrupts = 0;
|
||||
|
||||
extern int current_spl_level;
|
||||
extern int softintr_dispatch(int);
|
||||
|
||||
/* Generate soft interrupt counts if IRQSTATS is defined */
|
||||
#ifdef IRQSTATS
|
||||
|
@ -119,6 +120,8 @@ dosoftints()
|
|||
u_int softints;
|
||||
int s;
|
||||
|
||||
softintr_dispatch(current_spl_level);
|
||||
|
||||
softints = soft_interrupts & spl_smasks[current_spl_level];
|
||||
if (softints == 0) return;
|
||||
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
/* $NetBSD: softintr.c,v 1.1 2001/05/22 17:25:16 toshii Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by IWAMOTO Toshihiro.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/irqhandler.h>
|
||||
|
||||
extern int ipl_to_spl(int);
|
||||
int softintr_free(void *);
|
||||
|
||||
struct softintr_handler {
|
||||
struct softintr_handler *sh_vlink; /* vertical link */
|
||||
struct softintr_handler *sh_hlink; /* horizontal link */
|
||||
|
||||
int (*sh_fun)(void *);
|
||||
void *sh_arg;
|
||||
int sh_level;
|
||||
|
||||
int sh_pending;
|
||||
};
|
||||
|
||||
struct softintr_handler *softintrs;
|
||||
struct softintr_handler *softintr_pending;
|
||||
|
||||
void *
|
||||
softintr_establish(int level, int (*fun)(void *), void *arg)
|
||||
{
|
||||
struct softintr_handler *sh;
|
||||
|
||||
sh = malloc(sizeof(*sh), M_DEVBUF, M_NOWAIT);
|
||||
if (sh == NULL)
|
||||
return(NULL);
|
||||
|
||||
sh->sh_fun = fun;
|
||||
sh->sh_level = ipl_to_spl(level);
|
||||
sh->sh_arg = arg;
|
||||
sh->sh_pending = 0;
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
void
|
||||
softintr_disestablish(void *cookie)
|
||||
{
|
||||
struct softintr_handler *sh = cookie;
|
||||
u_int saved_cpsr;
|
||||
|
||||
saved_cpsr = SetCPSR(I32_bit, I32_bit);
|
||||
if (sh->sh_pending) {
|
||||
sh->sh_fun = softintr_free;
|
||||
sh->sh_arg = sh;
|
||||
SetCPSR(I32_bit, I32_bit & saved_cpsr);
|
||||
} else {
|
||||
SetCPSR(I32_bit, I32_bit & saved_cpsr);
|
||||
free(sh, M_DEVBUF);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
softintr_free(void *arg)
|
||||
{
|
||||
|
||||
free(arg, M_DEVBUF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
softintr_schedule(void *cookie)
|
||||
{
|
||||
struct softintr_handler **p, *sh = cookie;
|
||||
register int pending;
|
||||
u_int saved_cpsr;
|
||||
|
||||
pending = 1;
|
||||
asm("swp %0, %0, [%1]" : "+r" (pending) : "r" (&sh->sh_pending));
|
||||
|
||||
if (pending)
|
||||
return;
|
||||
|
||||
sh->sh_vlink = NULL;
|
||||
sh->sh_hlink = NULL;
|
||||
|
||||
saved_cpsr = SetCPSR(I32_bit, I32_bit);
|
||||
p = &softintr_pending;
|
||||
|
||||
for (;; p = &(*p)->sh_vlink) {
|
||||
if (*p == NULL) {
|
||||
*p = sh;
|
||||
SetCPSR(I32_bit, I32_bit & saved_cpsr);
|
||||
return;
|
||||
}
|
||||
if ((*p)->sh_level <= sh->sh_level)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((*p)->sh_level == sh->sh_level) {
|
||||
sh->sh_hlink = *p;
|
||||
sh->sh_vlink = (*p)->sh_vlink;
|
||||
(*p)->sh_vlink = NULL;
|
||||
*p = sh;
|
||||
SetCPSR(I32_bit, I32_bit & saved_cpsr);
|
||||
return;
|
||||
}
|
||||
|
||||
sh->sh_vlink = *p;
|
||||
*p = sh;
|
||||
SetCPSR(I32_bit, I32_bit & saved_cpsr);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
softintr_dispatch(int s)
|
||||
{
|
||||
struct softintr_handler *sh, *sh1;
|
||||
u_int saved_cpsr;
|
||||
|
||||
while (1) {
|
||||
/* Protect list operation from interrupts */
|
||||
saved_cpsr = SetCPSR(I32_bit, I32_bit);
|
||||
|
||||
if (softintr_pending == NULL ||
|
||||
softintr_pending->sh_level <= s) {
|
||||
SetCPSR(I32_bit, I32_bit & saved_cpsr);
|
||||
return;
|
||||
}
|
||||
sh = softintr_pending;
|
||||
softintr_pending = softintr_pending->sh_vlink;
|
||||
SetCPSR(I32_bit, I32_bit & saved_cpsr);
|
||||
|
||||
s = raisespl(sh->sh_level);
|
||||
while (1) {
|
||||
/* The order is important */
|
||||
sh1 = sh->sh_hlink;
|
||||
sh->sh_pending = 0;
|
||||
|
||||
(sh->sh_fun)(sh->sh_arg);
|
||||
if (sh1 == NULL)
|
||||
break;
|
||||
sh = sh1;
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: stubs.c,v 1.3 2001/05/22 17:01:16 toshii Exp $ */
|
||||
/* $NetBSD: stubs.c,v 1.4 2001/05/22 17:25:16 toshii Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994-1998 Mark Brinicombe.
|
||||
|
@ -278,6 +278,34 @@ set_spl_masks()
|
|||
spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_CLOCK);
|
||||
}
|
||||
|
||||
int
|
||||
ipl_to_spl(ipl)
|
||||
int ipl;
|
||||
{
|
||||
|
||||
switch(ipl) {
|
||||
case IPL_BIO:
|
||||
return _SPL_BIO;
|
||||
case IPL_NET:
|
||||
return _SPL_NET;
|
||||
case IPL_TTY:
|
||||
return _SPL_TTY;
|
||||
case IPL_IMP:
|
||||
return _SPL_IMP;
|
||||
case IPL_AUDIO:
|
||||
return _SPL_AUDIO;
|
||||
case IPL_CLOCK:
|
||||
return _SPL_CLOCK;
|
||||
case IPL_HIGH:
|
||||
return _SPL_HIGH;
|
||||
case IPL_SERIAL:
|
||||
return _SPL_SERIAL;
|
||||
|
||||
default:
|
||||
panic("bogus ipl\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
void
|
||||
dump_spl_masks()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: intr.h,v 1.3 2001/05/15 16:15:22 toshii Exp $ */
|
||||
/* $NetBSD: intr.h,v 1.4 2001/05/22 17:25:16 toshii Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Mark Brinicombe.
|
||||
|
@ -69,4 +69,10 @@
|
|||
#include <machine/irqhandler.h>
|
||||
#include <machine/psl.h>
|
||||
|
||||
#ifndef _LOCORE
|
||||
void *softintr_establish(int, int (*)(void *), void *);
|
||||
void softintr_disestablish(void *);
|
||||
void softintr_schedule(void *);
|
||||
#endif
|
||||
|
||||
#endif /* _HPCARM_INTR_H */
|
||||
|
|
Loading…
Reference in New Issue