atomic-v6.h revision 129198
187866Ssheldonh/* $NetBSD: atomic.h,v 1.1 2002/10/19 12:22:34 bsh Exp $ */ 295267Ssheldonh 387866Ssheldonh/* 487866Ssheldonh * Copyright (C) 2003-2004 Olivier Houchard 587866Ssheldonh * Copyright (C) 1994-1997 Mark Brinicombe 687866Ssheldonh * Copyright (C) 1994 Brini 787866Ssheldonh * All rights reserved. 887866Ssheldonh * 987866Ssheldonh * This code is derived from software written for Brini by Mark Brinicombe 1087866Ssheldonh * 1187866Ssheldonh * Redistribution and use in source and binary forms, with or without 1287866Ssheldonh * modification, are permitted provided that the following conditions 1387866Ssheldonh * are met: 1487866Ssheldonh * 1. Redistributions of source code must retain the above copyright 1587866Ssheldonh * notice, this list of conditions and the following disclaimer. 1687866Ssheldonh * 2. Redistributions in binary form must reproduce the above copyright 1787866Ssheldonh * notice, this list of conditions and the following disclaimer in the 1887866Ssheldonh * documentation and/or other materials provided with the distribution. 1987866Ssheldonh * 3. All advertising materials mentioning features or use of this software 2087866Ssheldonh * must display the following acknowledgement: 2187866Ssheldonh * This product includes software developed by Brini. 2287866Ssheldonh * 4. The name of Brini may not be used to endorse or promote products 2387866Ssheldonh * derived from this software without specific prior written permission. 2487866Ssheldonh * 2587866Ssheldonh * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR 2687866Ssheldonh * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2787866Ssheldonh * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2887866Ssheldonh * IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2987866Ssheldonh * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 3087866Ssheldonh * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 3187866Ssheldonh * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 3295267Ssheldonh * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 33113396Stjr * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 3487866Ssheldonh * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3587866Ssheldonh * 3687866Ssheldonh * $FreeBSD: head/sys/arm/include/atomic.h 129198 2004-05-14 11:46:45Z cognet $ 3787866Ssheldonh */ 3887866Ssheldonh 3987866Ssheldonh#ifndef _MACHINE_ATOMIC_H_ 4087866Ssheldonh#define _MACHINE_ATOMIC_H_ 4187866Ssheldonh 4287866Ssheldonh 4387866Ssheldonh 4487866Ssheldonh#ifndef _LOCORE 4587866Ssheldonh 4687866Ssheldonh#include <sys/types.h> 4787866Ssheldonh 4887866Ssheldonh#ifndef I32_bit 4987866Ssheldonh#define I32_bit (1 << 7) /* IRQ disable */ 5087866Ssheldonh#endif 5187866Ssheldonh#ifndef F32_bit 5287866Ssheldonh#define F32_bit (1 << 6) /* FIQ disable */ 5387866Ssheldonh#endif 5487866Ssheldonh 5587866Ssheldonh#define __with_interrupts_disabled(expr) \ 5687866Ssheldonh do { \ 5787866Ssheldonh u_int cpsr_save, tmp; \ 5887866Ssheldonh \ 5987866Ssheldonh __asm __volatile( \ 6087866Ssheldonh "mrs %0, cpsr;" \ 6187866Ssheldonh "orr %1, %0, %2;" \ 6287866Ssheldonh "msr cpsr_all, %1;" \ 6387866Ssheldonh : "=r" (cpsr_save), "=r" (tmp) \ 6487866Ssheldonh : "I" (I32_bit) \ 6587866Ssheldonh : "cc" ); \ 6687866Ssheldonh (expr); \ 6787866Ssheldonh __asm __volatile( \ 6895267Ssheldonh "msr cpsr_all, %0" \ 6987866Ssheldonh : /* no output */ \ 7095267Ssheldonh : "r" (cpsr_save) \ 7187866Ssheldonh : "cc" ); \ 7287866Ssheldonh } while(0) 7387866Ssheldonh 7487866Ssheldonhstatic __inline void 7587866Ssheldonhatomic_set_32(volatile uint32_t *address, uint32_t setmask) 7687866Ssheldonh{ 7787866Ssheldonh __with_interrupts_disabled( *address |= setmask); 7887866Ssheldonh} 7987866Ssheldonh 8087866Ssheldonhstatic __inline void 8187866Ssheldonhatomic_set_ptr(volatile void *ptr, uint32_t src) 8287866Ssheldonh{ 8387866Ssheldonh atomic_set_32((volatile uint32_t *)ptr, (uint32_t)src); 8487866Ssheldonh} 8587866Ssheldonh 8687866Ssheldonh#define atomic_set_rel_int atomic_set_32 8787866Ssheldonh#define atomic_set_int atomic_set_32 8887866Ssheldonh#define atomic_readandclear_int atomic_readandclear_32 8987866Ssheldonhstatic __inline void 9087866Ssheldonhatomic_clear_32(volatile uint32_t *address, uint32_t clearmask) 9187866Ssheldonh{ 9287866Ssheldonh __with_interrupts_disabled( *address &= ~clearmask); 9387866Ssheldonh} 9487866Ssheldonh 9587866Ssheldonhstatic __inline void 9687866Ssheldonhatomic_clear_ptr(volatile void *ptr, uint32_t src) 9787866Ssheldonh{ 9895267Ssheldonh atomic_clear_32((volatile uint32_t *)ptr, (uint32_t)src); 9995267Ssheldonh} 10095267Ssheldonh 10195267Ssheldonhstatic __inline int 10295267Ssheldonhatomic_load_acq_int(volatile uint32_t *v) 10395267Ssheldonh{ 10495267Ssheldonh int bla; 10595267Ssheldonh 10687866Ssheldonh __with_interrupts_disabled(bla = *v); 10787866Ssheldonh return (bla); 10887866Ssheldonh} 10987866Ssheldonh 11087866Ssheldonh#define atomic_clear_int atomic_clear_32 11187866Ssheldonhstatic __inline void 11287866Ssheldonhatomic_store_32(volatile uint32_t *dst, uint32_t src) 11387866Ssheldonh{ 11487866Ssheldonh __with_interrupts_disabled(*dst = src); 11587866Ssheldonh} 11687866Ssheldonh 11787866Ssheldonhstatic __inline void 11887866Ssheldonhatomic_store_ptr(volatile void *dst, void *src) 11987866Ssheldonh{ 12087866Ssheldonh atomic_store_32((volatile uint32_t *)dst, (uint32_t) src); 12187866Ssheldonh} 12287866Ssheldonh 12387866Ssheldonh#define atomic_store_rel_ptr atomic_store_ptr 12487866Ssheldonh#define atomic_store_rel_int atomic_store_32 12587866Ssheldonh 12687866Ssheldonhstatic __inline uint32_t 12787866Ssheldonhatomic_readandclear_32(volatile u_int32_t *p) 12887866Ssheldonh{ 12987866Ssheldonh uint32_t ret; 13087866Ssheldonh 13187866Ssheldonh __with_interrupts_disabled((ret = *p) != 0 ? *p = 0 : 0); 13287866Ssheldonh return (ret); 13387866Ssheldonh} 13487866Ssheldonh 13587866Ssheldonhstatic __inline u_int32_t 13687866Ssheldonhatomic_cmpset_32(volatile u_int32_t *p, u_int32_t cmpval, u_int32_t newval) 13787866Ssheldonh{ 13887866Ssheldonh int done = 0; 13987866Ssheldonh __with_interrupts_disabled(*p = (*p == cmpval ? newval + done++ : *p)); 14087866Ssheldonh return (done); 14187866Ssheldonh} 14287866Ssheldonh 14387866Ssheldonhstatic __inline void 14487866Ssheldonhatomic_add_32(volatile u_int32_t *p, u_int32_t val) 14587866Ssheldonh{ 14687866Ssheldonh __with_interrupts_disabled(*p += val); 14787866Ssheldonh} 14887866Ssheldonh 14987866Ssheldonhstatic __inline void 15087866Ssheldonhatomic_subtract_32(volatile u_int32_t *p, u_int32_t val) 15187866Ssheldonh{ 15287866Ssheldonh __with_interrupts_disabled(*p -= val); 15387866Ssheldonh} 15487866Ssheldonh 15587866Ssheldonh#define atomic_subtract_int atomic_subtract_32 15687866Ssheldonh#define atomic_subtract_rel_int atomic_subtract_32 15787866Ssheldonh#define atomic_subtract_acq_int atomic_subtract_32 15887866Ssheldonh#define atomic_add_int atomic_add_32 15987866Ssheldonh#define atomic_add_rel_int atomic_add_32 16087866Ssheldonh#define atomic_add_acq_int atomic_add_32 16187866Ssheldonh#define atomic_cmpset_int atomic_cmpset_32 16287866Ssheldonh#define atomic_cmpset_rel_int atomic_cmpset_32 16387866Ssheldonh#define atomic_cmpset_acq_int atomic_cmpset_32 16487866Ssheldonh 16587866Ssheldonhstatic __inline u_int32_t 16687866Ssheldonhatomic_cmpset_ptr(volatile void *dst, void *exp, void *src) 16787866Ssheldonh{ 16887866Ssheldonh return (atomic_cmpset_32((volatile u_int32_t *)dst, (u_int32_t)exp, 16987866Ssheldonh (u_int32_t)src)); 17087866Ssheldonh} 17187866Ssheldonh 17287866Ssheldonhstatic __inline u_int32_t 17387866Ssheldonhatomic_cmpset_rel_32(volatile u_int32_t *p, u_int32_t cmpval, u_int32_t newval) 17487866Ssheldonh{ 17587866Ssheldonh return (atomic_cmpset_32(p, cmpval, newval)); 17687866Ssheldonh} 17787866Ssheldonh 17887866Ssheldonhstatic __inline u_int32_t 17987866Ssheldonhatomic_cmpset_rel_ptr(volatile void *dst, void *exp, void *src) 18087866Ssheldonh{ 18187866Ssheldonh return (atomic_cmpset_32((volatile u_int32_t *)dst, 18287866Ssheldonh (u_int32_t)exp, (u_int32_t)src)); 18387866Ssheldonh} 18487866Ssheldonh 18587866Ssheldonh#define atomic_cmpset_acq_ptr atomic_cmpset_ptr 18687866Ssheldonh 18787866Ssheldonh#if !defined(ATOMIC_SET_BIT_NOINLINE) 18887866Ssheldonh 18987866Ssheldonh#define atomic_set_bit(a,m) atomic_set_32(a,m) 19087866Ssheldonh#define atomic_clear_bit(a,m) atomic_clear_32(a,m) 19187866Ssheldonh 19287866Ssheldonh#endif 19387866Ssheldonh 19487866Ssheldonh#undef __with_interrupts_disabled 19587866Ssheldonh 19687866Ssheldonh#endif /* _LOCORE */ 19787866Ssheldonh#endif /* _MACHINE_ATOMIC_H_ */ 19887866Ssheldonh