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 | |
parent | f9bb69616f2bcaf3c499675e6dc7a5fc93d64939 (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.h | 24 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/exception.S | 33 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/interrupt.c | 19 | ||||
-rw-r--r-- | sys/arch/sgi/include/intr.h | 32 | ||||
-rw-r--r-- | sys/arch/sgi/localbus/macebus.c | 15 |
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) { |