diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2007-03-23 21:07:41 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2007-03-23 21:07:41 +0000 |
commit | f880be4594e702e459f1a64e16122a04a1548f62 (patch) | |
tree | 70a99d632099cd01c2d71fd4cbfe7953b2fcc287 /sys/arch/mips64 | |
parent | f9bb69616f2bcaf3c499675e6dc7a5fc93d64939 (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.h | 24 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/exception.S | 33 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/interrupt.c | 19 |
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); |