summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2007-03-23 21:07:41 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2007-03-23 21:07:41 +0000
commitf880be4594e702e459f1a64e16122a04a1548f62 (patch)
tree70a99d632099cd01c2d71fd4cbfe7953b2fcc287
parentf9bb69616f2bcaf3c499675e6dc7a5fc93d64939 (diff)
Real atomic_{set,clear}bits_int implementation, and replace similar
{set,clr}_ipending with the above routines. ok kettenis@
-rw-r--r--sys/arch/mips64/include/atomic.h24
-rw-r--r--sys/arch/mips64/mips64/exception.S33
-rw-r--r--sys/arch/mips64/mips64/interrupt.c19
-rw-r--r--sys/arch/sgi/include/intr.h32
-rw-r--r--sys/arch/sgi/localbus/macebus.c15
5 files changed, 45 insertions, 78 deletions
diff --git a/sys/arch/mips64/include/atomic.h b/sys/arch/mips64/include/atomic.h
index 9b8aead11a0..d4ce9845113 100644
--- a/sys/arch/mips64/include/atomic.h
+++ b/sys/arch/mips64/include/atomic.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomic.h,v 1.2 2007/02/19 17:18:43 deraadt Exp $ */
+/* $OpenBSD: atomic.h,v 1.3 2007/03/23 21:07:36 miod Exp $ */
/* Public Domain */
@@ -10,13 +10,31 @@
static __inline void
atomic_setbits_int(__volatile unsigned int *uip, unsigned int v)
{
- *uip |= v;
+ unsigned int tmp;
+
+ __asm__ __volatile__ (
+ "1: ll %0, 0(%1)\n"
+ " or %0, %2, %0\n"
+ " sc %0, 0(%1)\n"
+ " beqz %0, 1b\n"
+ " nop\n" :
+ "+r"(tmp) :
+ "r"(uip), "r"(v) : "memory");
}
static __inline void
atomic_clearbits_int(__volatile unsigned int *uip, unsigned int v)
{
- *uip &= ~v;
+ unsigned int tmp;
+
+ __asm__ __volatile__ (
+ "1: ll %0, 0(%1)\n"
+ " and %0, %2, %0\n"
+ " sc %0, 0(%1)\n"
+ " beqz %0, 1b\n"
+ " nop\n" :
+ "+r"(tmp) :
+ "r"(uip), "r"(~v) : "memory");
}
#endif /* defined(_KERNEL) */
diff --git a/sys/arch/mips64/mips64/exception.S b/sys/arch/mips64/mips64/exception.S
index ef6ec50d665..dcabd4539c7 100644
--- a/sys/arch/mips64/mips64/exception.S
+++ b/sys/arch/mips64/mips64/exception.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: exception.S,v 1.8 2005/12/20 07:06:26 miod Exp $ */
+/* $OpenBSD: exception.S,v 1.9 2007/03/23 21:07:38 miod Exp $ */
/*
* Copyright (c) 2002-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -351,37 +351,6 @@ NNON_LEAF(u_intr, FRAMESZ(CF_SZ), ra)
.set at
END(u_intr)
-/*---------------------------------------------------------------- set_ipending
- * Atomic ipending set
- */
-LEAF(set_ipending, 0)
- LA a1, ipending
-1:
- ll v0, 0(a1)
- or v1, v0, a0
- sc v1, 0(a1)
- beqz v1, 1b
- nop
- j ra
- nop
-END(set_ipending)
-
-/*---------------------------------------------------------------- set_ipending
- * Atomic ipending clear
- */
-LEAF(clr_ipending, 0)
- LA a1, ipending
- not a0, a0
-1:
- ll v0, 0(a1)
- and v1, v0, a0
- sc v1, 0(a1)
- beqz v1, 1b
- nop
- j ra
- nop
-END(clr_ipending)
-
/*---------------------------------------------------------------- k_general
* Handle a kernel general trap. This is very much like
* k_intr except that we call ktrap instead of interrupt.
diff --git a/sys/arch/mips64/mips64/interrupt.c b/sys/arch/mips64/mips64/interrupt.c
index 0cf196762fa..61ceccf200c 100644
--- a/sys/arch/mips64/mips64/interrupt.c
+++ b/sys/arch/mips64/mips64/interrupt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: interrupt.c,v 1.23 2007/03/15 10:22:29 art Exp $ */
+/* $OpenBSD: interrupt.c,v 1.24 2007/03/23 21:07:38 miod Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -46,6 +46,7 @@
#include <machine/autoconf.h>
#include <machine/frame.h>
#include <machine/regnum.h>
+#include <machine/atomic.h>
#include <mips64/rm7000.h>
@@ -198,21 +199,21 @@ printf("Unhandled interrupt %x:%x\n", cause, pending);
xcpl = splsoftnet();
if ((ipending & SINT_CLOCKMASK) & ~xcpl) {
- clr_ipending(SINT_CLOCKMASK);
+ atomic_clearbits_int(&ipending, SINT_CLOCKMASK);
softclock();
}
if ((ipending & SINT_NETMASK) & ~xcpl) {
extern int netisr;
int isr = netisr;
netisr = 0;
- clr_ipending(SINT_NETMASK);
+ atomic_clearbits_int(&ipending, SINT_NETMASK);
#define DONETISR(b,f) if (isr & (1 << (b))) f();
#include <net/netisr_dispatch.h>
}
#ifdef NOTYET
if ((ipending & SINT_TTYMASK) & ~xcpl) {
- clr_ipending(SINT_TTYMASK);
+ atomic_clearbits_int(&ipending, SINT_TTYMASK);
compoll(NULL);
}
#endif
@@ -480,7 +481,7 @@ generic_do_pending_int(int newcpl)
hwpend = ipending & ~newcpl; /* Do pendings being unmasked */
hwpend &= ~(SINT_ALLMASK);
- clr_ipending(hwpend);
+ atomic_clearbits_int(&ipending, hwpend);
intem |= hwpend;
while (hwpend) {
vector = ffs(hwpend) - 1;
@@ -495,20 +496,20 @@ generic_do_pending_int(int newcpl)
}
}
if ((ipending & SINT_CLOCKMASK) & ~newcpl) {
- clr_ipending(SINT_CLOCKMASK);
+ atomic_clearbits_int(&ipending, SINT_CLOCKMASK);
softclock();
}
if ((ipending & SINT_NETMASK) & ~newcpl) {
int isr = netisr;
netisr = 0;
- clr_ipending(SINT_NETMASK);
+ atomic_clearbits_int(&ipending, SINT_NETMASK);
#define DONETISR(b,f) if (isr & (1 << (b))) f();
#include <net/netisr_dispatch.h>
}
#ifdef NOTYET
if ((ipending & SINT_TTYMASK) & ~newcpl) {
- clr_ipending(SINT_TTYMASK);
+ atomic_clearbits_int(&ipending, SINT_TTYMASK);
compoll(NULL);
}
#endif
@@ -557,7 +558,7 @@ generic_iointr(intrmask_t pending, struct trap_frame *cf)
caught = 0;
- set_ipending((pending >> 8) & cpl);
+ atomic_setbits_int(&ipending, (pending >> 8) & cpl);
pending &= ~(cpl << 8);
cf->sr &= ~((ipending << 8) & SR_INT_MASK);
cf->ic &= ~(ipending & IC_INT_MASK);
diff --git a/sys/arch/sgi/include/intr.h b/sys/arch/sgi/include/intr.h
index 4f45611e1e6..41edd3da02b 100644
--- a/sys/arch/sgi/include/intr.h
+++ b/sys/arch/sgi/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.15 2006/07/09 22:10:05 mk Exp $ */
+/* $OpenBSD: intr.h,v 1.16 2007/03/23 21:07:39 miod Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -81,7 +81,6 @@
#ifndef _LOCORE
-#if 1
#define splbio() splraise(imask[IPL_BIO])
#define splnet() splraise(imask[IPL_NET])
#define spltty() splraise(imask[IPL_TTY])
@@ -91,24 +90,15 @@
#define splsoftclock() splraise(SINT_CLOCKMASK)
#define splsoftnet() splraise(SINT_NETMASK|SINT_CLOCKMASK)
#define splsofttty() splraise(SINT_TTYMASK)
-#else
-#define splbio() splhigh()
-#define splnet() splhigh()
-#define spltty() splhigh()
-#define splclock() splhigh()
-#define splvm() splhigh()
-#define splsoftclock() splhigh()
-#define splsoftnet() splhigh()
-#define splsofttty() splhigh()
-#endif
#define splstatclock() splhigh()
#define splhigh() splraise(-1)
#define spl0() spllower(0)
+#include <machine/atomic.h>
-#define setsoftclock() set_ipending(SINT_CLOCKMASK);
-#define setsoftnet() set_ipending(SINT_NETMASK);
-#define setsofttty() set_ipending(SINT_TTYMASK);
+#define setsoftclock() atomic_setbits_int(&ipending, SINT_CLOCKMASK)
+#define setsoftnet() atomic_setbits_int(&ipending, SINT_NETMASK)
+#define setsofttty() atomic_setbits_int(&ipending, SINT_TTYMASK)
void splinit(void);
@@ -129,12 +119,6 @@ typedef u_int32_t intrmask_t; /* Type of var holding interrupt mask */
#define INTMASKSIZE (sizeof(intrmask_t) * 8)
-void clearsoftclock(void);
-void clearsoftnet(void);
-#if 0
-void clearsofttty(void);
-#endif
-
extern volatile intrmask_t cpl;
extern volatile intrmask_t ipending;
extern volatile intrmask_t astpending;
@@ -204,12 +188,6 @@ spllower(int newcpl)
}
/*
- * Atomically update ipending.
- */
-void set_ipending(int);
-void clr_ipending(int);
-
-/*
* Interrupt control struct used by interrupt dispatchers
* to hold interrupt handler info.
*/
diff --git a/sys/arch/sgi/localbus/macebus.c b/sys/arch/sgi/localbus/macebus.c
index e6e56fd2d46..b072f25c2c7 100644
--- a/sys/arch/sgi/localbus/macebus.c
+++ b/sys/arch/sgi/localbus/macebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: macebus.c,v 1.18 2006/01/04 20:23:07 miod Exp $ */
+/* $OpenBSD: macebus.c,v 1.19 2007/03/23 21:07:40 miod Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -51,6 +51,7 @@
#include <machine/autoconf.h>
#include <machine/intr.h>
+#include <machine/atomic.h>
#include <sgi/localbus/macebus.h>
#include <sgi/localbus/crimebus.h>
@@ -619,7 +620,7 @@ macebus_do_pending_int(int newcpl)
/* Get what interrupt we should process */
hwpend = ipending & ~newcpl;
hwpend &= ~SINT_ALLMASK;
- clr_ipending(hwpend);
+ atomic_clearbits_int(&ipending, hwpend);
/* Enable all non pending non masked hardware interrupts */
cpl = (cpl & SINT_ALLMASK) | (newcpl & ~SINT_ALLMASK) | hwpend;
@@ -643,21 +644,21 @@ macebus_do_pending_int(int newcpl)
hw_setintrmask(cpl);
if ((ipending & SINT_CLOCKMASK) & ~newcpl) {
- clr_ipending(SINT_CLOCKMASK);
+ atomic_clearbits_int(&ipending, SINT_CLOCKMASK);
softclock();
}
if ((ipending & SINT_NETMASK) & ~newcpl) {
extern int netisr;
int isr = netisr;
netisr = 0;
- clr_ipending(SINT_NETMASK);
+ atomic_clearbits_int(&ipending, SINT_NETMASK);
#define DONETISR(b,f) if (isr & (1 << (b))) f();
#include <net/netisr_dispatch.h>
}
#ifdef NOTYET
if ((ipending & SINT_TTYMASK) & ~newcpl) {
- clr_ipending(SINT_TTYMASK);
+ atomic_clearbits_int(&ipending, SINT_TTYMASK);
compoll(NULL);
}
#endif
@@ -697,7 +698,7 @@ macebus_iointr(intrmask_t hwpend, struct trap_frame *cf)
/* Mask off masked interrupts and save them as pending */
if (intstat & cf->cpl) {
- set_ipending(intstat & cf->cpl);
+ atomic_setbits_int(&ipending, intstat & cf->cpl);
mask = bus_space_read_8(&crimebus_tag, crime_h, CRIME_INT_MASK);
mask &= ~ipending;
bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_MASK, mask);
@@ -706,7 +707,7 @@ macebus_iointr(intrmask_t hwpend, struct trap_frame *cf)
/* Scan all unmasked. Scan the first 16 for now */
pending = intstat & ~cf->cpl;
- clr_ipending(pending);
+ atomic_clearbits_int(&ipending, pending);
for (v = 0, vm = 1; pending != 0 && v < 16 ; v++, vm <<= 1) {
if (pending & vm) {