kernel: PAT work, test_and_set_bit()
[dragonfly.git] / sys / dev / drm2 / drm_atomic.h
1 /**
2  * \file drm_atomic.h
3  * Atomic operations used in the DRM which may or may not be provided by the OS.
4  * 
5  * \author Eric Anholt <anholt@FreeBSD.org>
6  */
7
8 /*-
9  * Copyright 2004 Eric Anholt
10  * All Rights Reserved.
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice (including the next
20  * paragraph) shall be included in all copies or substantial portions of the
21  * Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
26  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
27  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29  * OTHER DEALINGS IN THE SOFTWARE.
30  *
31  * $FreeBSD: src/sys/dev/drm2/drm_atomic.h,v 1.1 2012/05/22 11:07:44 kib Exp $
32  */
33
34 /* Many of these implementations are rather fake, but good enough. */
35
36 typedef u_int32_t atomic_t;
37
38 #define atomic_set(p, v)        (*(p) = (v))
39 #define atomic_read(p)          (*(p))
40 #define atomic_inc(p)           atomic_add_int(p, 1)
41 #define atomic_dec(p)           atomic_subtract_int(p, 1)
42 #define atomic_add(n, p)        atomic_add_int(p, n)
43 #define atomic_sub(n, p)        atomic_subtract_int(p, n)
44
45 static __inline atomic_t
46 test_and_set_bit(int b, volatile void *p)
47 {
48         unsigned int mask = 1 << b;
49         unsigned int v;
50
51         for (;;) {
52                 v = *(volatile unsigned int *)p;
53                 cpu_ccfence();
54                 if (atomic_cmpset_int(p, v, v | mask))
55                         break;
56         }
57         return (v & mask);
58 }
59
60 static __inline void
61 clear_bit(int b, volatile void *p)
62 {
63         atomic_clear_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f));
64 }
65
66 static __inline void
67 set_bit(int b, volatile void *p)
68 {
69         atomic_set_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f));
70 }
71
72 static __inline int
73 test_bit(int b, volatile void *p)
74 {
75         return ((volatile int *)p)[b >> 5] & (1 << (b & 0x1f));
76 }
77
78 static __inline int
79 find_first_zero_bit(volatile void *p, int max)
80 {
81         int b;
82         volatile int *ptr = (volatile int *)p;
83
84         for (b = 0; b < max; b += 32) {
85                 if (ptr[b >> 5] != ~0) {
86                         for (;;) {
87                                 if ((ptr[b >> 5] & (1 << (b & 0x1f))) == 0)
88                                         return b;
89                                 b++;
90                         }
91                 }
92         }
93         return max;
94 }
95
96 #define BITS_TO_LONGS(x) (howmany((x), NBBY * sizeof(long)))