1 /* $OpenBSD: atomic.h,v 1.5 2011/03/23 16:54:35 pirofti Exp $ */ 2 3 /* Public Domain */ 4 5 #ifndef _MACHINE_ATOMIC_H_ 6 #define _MACHINE_ATOMIC_H_ 7 8 #if defined(_KERNEL) 9 10 #include <sys/mutex.h> 11 12 #ifdef MULTIPROCESSOR 13 extern struct mutex mtx_atomic; 14 #define ATOMIC_LOCK mtx_enter(&mtx_atomic) 15 #define ATOMIC_UNLOCK mtx_leave(&mtx_atomic) 16 #else 17 #define ATOMIC_LOCK 18 #define ATOMIC_UNLOCK 19 #endif 20 21 static __inline void 22 atomic_setbits_int(__volatile unsigned int *uip, unsigned int v) 23 { 24 register_t eiem; 25 26 __asm __volatile("mfctl %%cr15, %0": "=r" (eiem)); 27 __asm __volatile("mtctl %r0, %cr15"); 28 ATOMIC_LOCK; 29 *uip |= v; 30 ATOMIC_UNLOCK; 31 __asm __volatile("mtctl %0, %%cr15":: "r" (eiem)); 32 } 33 34 static __inline void 35 atomic_clearbits_int(__volatile unsigned int *uip, unsigned int v) 36 { 37 register_t eiem; 38 39 __asm __volatile("mfctl %%cr15, %0": "=r" (eiem)); 40 __asm __volatile("mtctl %r0, %cr15"); 41 ATOMIC_LOCK; 42 *uip &= ~v; 43 ATOMIC_UNLOCK; 44 __asm __volatile("mtctl %0, %%cr15":: "r" (eiem)); 45 } 46 47 static __inline void 48 atomic_setbits_long(__volatile unsigned long *uip, unsigned long v) 49 { 50 register_t eiem; 51 52 __asm __volatile("mfctl %%cr15, %0": "=r" (eiem)); 53 __asm __volatile("mtctl %r0, %cr15"); 54 ATOMIC_LOCK; 55 *uip |= v; 56 ATOMIC_UNLOCK; 57 __asm __volatile("mtctl %0, %%cr15":: "r" (eiem)); 58 } 59 60 static __inline void 61 atomic_clearbits_long(__volatile unsigned long *uip, unsigned long v) 62 { 63 register_t eiem; 64 65 __asm __volatile("mfctl %%cr15, %0": "=r" (eiem)); 66 __asm __volatile("mtctl %r0, %cr15"); 67 ATOMIC_LOCK; 68 *uip &= ~v; 69 ATOMIC_UNLOCK; 70 __asm __volatile("mtctl %0, %%cr15":: "r" (eiem)); 71 } 72 73 #endif /* defined(_KERNEL) */ 74 #endif /* _MACHINE_ATOMIC_H_ */ 75