summaryrefslogtreecommitdiff
path: root/sys/arch/mips64
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 /sys/arch/mips64
parentf9bb69616f2bcaf3c499675e6dc7a5fc93d64939 (diff)
Real atomic_{set,clear}bits_int implementation, and replace similar
{set,clr}_ipending with the above routines. ok kettenis@
Diffstat (limited to 'sys/arch/mips64')
-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
3 files changed, 32 insertions, 44 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);