1592ffb21SWarner Losh /**
2592ffb21SWarner Losh * \file drm_os_freebsd.h
3592ffb21SWarner Losh * OS abstraction macros.
4592ffb21SWarner Losh */
5592ffb21SWarner Losh
6592ffb21SWarner Losh #include <sys/cdefs.h>
7592ffb21SWarner Losh #ifndef _DRM_OS_FREEBSD_H_
8592ffb21SWarner Losh #define _DRM_OS_FREEBSD_H_
9592ffb21SWarner Losh
10592ffb21SWarner Losh #include <sys/fbio.h>
11592ffb21SWarner Losh #include <sys/smp.h>
12592ffb21SWarner Losh
13592ffb21SWarner Losh #if _BYTE_ORDER == _BIG_ENDIAN
14592ffb21SWarner Losh #define __BIG_ENDIAN 4321
15592ffb21SWarner Losh #else
16592ffb21SWarner Losh #define __LITTLE_ENDIAN 1234
17592ffb21SWarner Losh #endif
18592ffb21SWarner Losh
19592ffb21SWarner Losh #ifdef __LP64__
20592ffb21SWarner Losh #define BITS_PER_LONG 64
21592ffb21SWarner Losh #else
22592ffb21SWarner Losh #define BITS_PER_LONG 32
23592ffb21SWarner Losh #endif
24592ffb21SWarner Losh
25592ffb21SWarner Losh #ifndef __user
26592ffb21SWarner Losh #define __user
27592ffb21SWarner Losh #endif
28592ffb21SWarner Losh #ifndef __iomem
29592ffb21SWarner Losh #define __iomem
30592ffb21SWarner Losh #endif
31592ffb21SWarner Losh #ifndef __always_unused
32592ffb21SWarner Losh #define __always_unused
33592ffb21SWarner Losh #endif
34592ffb21SWarner Losh #ifndef __must_check
35592ffb21SWarner Losh #define __must_check
36592ffb21SWarner Losh #endif
37592ffb21SWarner Losh #ifndef __force
38592ffb21SWarner Losh #define __force
39592ffb21SWarner Losh #endif
40592ffb21SWarner Losh #ifndef uninitialized_var
41592ffb21SWarner Losh #define uninitialized_var(x) x
42592ffb21SWarner Losh #endif
43592ffb21SWarner Losh
44592ffb21SWarner Losh #define cpu_to_le16(x) htole16(x)
45592ffb21SWarner Losh #define le16_to_cpu(x) le16toh(x)
46592ffb21SWarner Losh #define cpu_to_le32(x) htole32(x)
47592ffb21SWarner Losh #define le32_to_cpu(x) le32toh(x)
48592ffb21SWarner Losh
49592ffb21SWarner Losh #define cpu_to_be16(x) htobe16(x)
50592ffb21SWarner Losh #define be16_to_cpu(x) be16toh(x)
51592ffb21SWarner Losh #define cpu_to_be32(x) htobe32(x)
52592ffb21SWarner Losh #define be32_to_cpu(x) be32toh(x)
53592ffb21SWarner Losh #define be32_to_cpup(x) be32toh(*x)
54592ffb21SWarner Losh
55592ffb21SWarner Losh typedef vm_paddr_t dma_addr_t;
56592ffb21SWarner Losh typedef vm_paddr_t resource_size_t;
57592ffb21SWarner Losh #define wait_queue_head_t atomic_t
58592ffb21SWarner Losh
59592ffb21SWarner Losh typedef uint64_t u64;
60592ffb21SWarner Losh typedef uint32_t u32;
61592ffb21SWarner Losh typedef uint16_t u16;
62592ffb21SWarner Losh typedef uint8_t u8;
63592ffb21SWarner Losh typedef int64_t s64;
64592ffb21SWarner Losh typedef int32_t s32;
65592ffb21SWarner Losh typedef int16_t s16;
66592ffb21SWarner Losh typedef int8_t s8;
67592ffb21SWarner Losh typedef uint16_t __le16;
68592ffb21SWarner Losh typedef uint32_t __le32;
69592ffb21SWarner Losh typedef uint64_t __le64;
70592ffb21SWarner Losh typedef uint16_t __be16;
71592ffb21SWarner Losh typedef uint32_t __be32;
72592ffb21SWarner Losh typedef uint64_t __be64;
73592ffb21SWarner Losh
74592ffb21SWarner Losh #define DRM_IRQ_ARGS void *arg
75592ffb21SWarner Losh typedef void irqreturn_t;
76592ffb21SWarner Losh #define IRQ_HANDLED /* nothing */
77592ffb21SWarner Losh #define IRQ_NONE /* nothing */
78592ffb21SWarner Losh
79592ffb21SWarner Losh #define __init
80592ffb21SWarner Losh #define __exit
81592ffb21SWarner Losh
82592ffb21SWarner Losh #define BUILD_BUG_ON(x) CTASSERT(!(x))
83592ffb21SWarner Losh #define BUILD_BUG_ON_NOT_POWER_OF_2(x)
84592ffb21SWarner Losh
85592ffb21SWarner Losh #ifndef WARN
86592ffb21SWarner Losh #define WARN(condition, format, ...) ({ \
87592ffb21SWarner Losh int __ret_warn_on = !!(condition); \
88592ffb21SWarner Losh if (unlikely(__ret_warn_on)) \
89592ffb21SWarner Losh DRM_ERROR(format, ##__VA_ARGS__); \
90592ffb21SWarner Losh unlikely(__ret_warn_on); \
91592ffb21SWarner Losh })
92592ffb21SWarner Losh #endif
93592ffb21SWarner Losh #define WARN_ONCE(condition, format, ...) \
94592ffb21SWarner Losh WARN(condition, format, ##__VA_ARGS__)
95592ffb21SWarner Losh #define WARN_ON(cond) WARN(cond, "WARN ON: " #cond)
96592ffb21SWarner Losh #define WARN_ON_SMP(cond) WARN_ON(cond)
97592ffb21SWarner Losh #define BUG() panic("BUG")
98592ffb21SWarner Losh #define BUG_ON(cond) KASSERT(!(cond), ("BUG ON: " #cond " -> 0x%jx", (uintmax_t)(cond)))
99592ffb21SWarner Losh #define unlikely(x) __builtin_expect(!!(x), 0)
100592ffb21SWarner Losh #define likely(x) __builtin_expect(!!(x), 1)
101592ffb21SWarner Losh #define container_of(ptr, type, member) ({ \
102592ffb21SWarner Losh __typeof( ((type *)0)->member ) *__mptr = (ptr); \
103592ffb21SWarner Losh (type *)( (char *)__mptr - offsetof(type,member) );})
104592ffb21SWarner Losh
105592ffb21SWarner Losh #define KHZ2PICOS(a) (1000000000UL/(a))
106592ffb21SWarner Losh
107592ffb21SWarner Losh #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
108592ffb21SWarner Losh
109592ffb21SWarner Losh #define HZ hz
110592ffb21SWarner Losh #define DRM_HZ hz
111592ffb21SWarner Losh #define DRM_CURRENTPID curthread->td_proc->p_pid
112592ffb21SWarner Losh #define DRM_SUSER(p) (priv_check(p, PRIV_DRIVER) == 0)
113592ffb21SWarner Losh #define udelay(usecs) DELAY(usecs)
114592ffb21SWarner Losh #define mdelay(msecs) do { int loops = (msecs); \
115592ffb21SWarner Losh while (loops--) DELAY(1000); \
116592ffb21SWarner Losh } while (0)
117592ffb21SWarner Losh #define DRM_UDELAY(udelay) DELAY(udelay)
118592ffb21SWarner Losh #define drm_msleep(x, msg) pause((msg), ((int64_t)(x)) * hz / 1000)
119592ffb21SWarner Losh #define DRM_MSLEEP(msecs) drm_msleep((msecs), "drm_msleep")
120592ffb21SWarner Losh #define get_seconds() time_second
121592ffb21SWarner Losh
122592ffb21SWarner Losh #define ioread8(addr) *(volatile uint8_t *)((char *)addr)
123592ffb21SWarner Losh #define ioread16(addr) *(volatile uint16_t *)((char *)addr)
124592ffb21SWarner Losh #define ioread32(addr) *(volatile uint32_t *)((char *)addr)
125592ffb21SWarner Losh
126592ffb21SWarner Losh #define iowrite8(data, addr) *(volatile uint8_t *)((char *)addr) = data;
127592ffb21SWarner Losh #define iowrite16(data, addr) *(volatile uint16_t *)((char *)addr) = data;
128592ffb21SWarner Losh #define iowrite32(data, addr) *(volatile uint32_t *)((char *)addr) = data;
129592ffb21SWarner Losh
130592ffb21SWarner Losh #define DRM_READ8(map, offset) \
131592ffb21SWarner Losh *(volatile u_int8_t *)(((vm_offset_t)(map)->handle) + \
132592ffb21SWarner Losh (vm_offset_t)(offset))
133592ffb21SWarner Losh #define DRM_READ16(map, offset) \
134592ffb21SWarner Losh le16toh(*(volatile u_int16_t *)(((vm_offset_t)(map)->handle) + \
135592ffb21SWarner Losh (vm_offset_t)(offset)))
136592ffb21SWarner Losh #define DRM_READ32(map, offset) \
137592ffb21SWarner Losh le32toh(*(volatile u_int32_t *)(((vm_offset_t)(map)->handle) + \
138592ffb21SWarner Losh (vm_offset_t)(offset)))
139592ffb21SWarner Losh #define DRM_READ64(map, offset) \
140592ffb21SWarner Losh le64toh(*(volatile u_int64_t *)(((vm_offset_t)(map)->handle) + \
141592ffb21SWarner Losh (vm_offset_t)(offset)))
142592ffb21SWarner Losh #define DRM_WRITE8(map, offset, val) \
143592ffb21SWarner Losh *(volatile u_int8_t *)(((vm_offset_t)(map)->handle) + \
144592ffb21SWarner Losh (vm_offset_t)(offset)) = val
145592ffb21SWarner Losh #define DRM_WRITE16(map, offset, val) \
146592ffb21SWarner Losh *(volatile u_int16_t *)(((vm_offset_t)(map)->handle) + \
147592ffb21SWarner Losh (vm_offset_t)(offset)) = htole16(val)
148592ffb21SWarner Losh #define DRM_WRITE32(map, offset, val) \
149592ffb21SWarner Losh *(volatile u_int32_t *)(((vm_offset_t)(map)->handle) + \
150592ffb21SWarner Losh (vm_offset_t)(offset)) = htole32(val)
151592ffb21SWarner Losh #define DRM_WRITE64(map, offset, val) \
152592ffb21SWarner Losh *(volatile u_int64_t *)(((vm_offset_t)(map)->handle) + \
153592ffb21SWarner Losh (vm_offset_t)(offset)) = htole64(val)
154592ffb21SWarner Losh
155662c3e20SNiclas Zeising #if !defined(__arm__)
156662c3e20SNiclas Zeising #if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) || defined(__aarch64__)
157662c3e20SNiclas Zeising #define DRM_MSG "This code is deprecated. Install the graphics/drm-kmod pkg\n"
158662c3e20SNiclas Zeising #else
159662c3e20SNiclas Zeising #define DRM_MSG "This code is deprecated."
160662c3e20SNiclas Zeising #endif
161264d4ffdSWarner Losh
162264d4ffdSWarner Losh #define DRM_OBSOLETE(dev) \
163264d4ffdSWarner Losh do { \
164264d4ffdSWarner Losh device_printf(dev, "=======================================================\n"); \
165662c3e20SNiclas Zeising device_printf(dev, DRM_MSG); \
166264d4ffdSWarner Losh device_printf(dev, "=======================================================\n"); \
167264d4ffdSWarner Losh gone_in_dev(dev, 13, "drm2 drivers"); \
168264d4ffdSWarner Losh } while (0)
169662c3e20SNiclas Zeising #endif /* __arm__ */
170264d4ffdSWarner Losh
171592ffb21SWarner Losh /* DRM_READMEMORYBARRIER() prevents reordering of reads.
172592ffb21SWarner Losh * DRM_WRITEMEMORYBARRIER() prevents reordering of writes.
173592ffb21SWarner Losh * DRM_MEMORYBARRIER() prevents reordering of reads and writes.
174592ffb21SWarner Losh */
175592ffb21SWarner Losh #define DRM_READMEMORYBARRIER() rmb()
176592ffb21SWarner Losh #define DRM_WRITEMEMORYBARRIER() wmb()
177592ffb21SWarner Losh #define DRM_MEMORYBARRIER() mb()
178592ffb21SWarner Losh #define smp_rmb() rmb()
179592ffb21SWarner Losh #define smp_wmb() wmb()
180592ffb21SWarner Losh #define smp_mb__before_atomic_inc() mb()
181592ffb21SWarner Losh #define smp_mb__after_atomic_inc() mb()
182592ffb21SWarner Losh #define barrier() __compiler_membar()
183592ffb21SWarner Losh
184592ffb21SWarner Losh #define do_div(a, b) ((a) /= (b))
185592ffb21SWarner Losh #define div64_u64(a, b) ((a) / (b))
186592ffb21SWarner Losh #define lower_32_bits(n) ((u32)(n))
187592ffb21SWarner Losh #define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
188592ffb21SWarner Losh
189592ffb21SWarner Losh #define __set_bit(n, s) set_bit((n), (s))
190592ffb21SWarner Losh #define __clear_bit(n, s) clear_bit((n), (s))
191592ffb21SWarner Losh
192592ffb21SWarner Losh #define min_t(type, x, y) ({ \
193592ffb21SWarner Losh type __min1 = (x); \
194592ffb21SWarner Losh type __min2 = (y); \
195592ffb21SWarner Losh __min1 < __min2 ? __min1 : __min2; })
196592ffb21SWarner Losh
197592ffb21SWarner Losh #define max_t(type, x, y) ({ \
198592ffb21SWarner Losh type __max1 = (x); \
199592ffb21SWarner Losh type __max2 = (y); \
200592ffb21SWarner Losh __max1 > __max2 ? __max1 : __max2; })
201592ffb21SWarner Losh
202592ffb21SWarner Losh #define memset_io(a, b, c) memset((a), (b), (c))
203592ffb21SWarner Losh #define memcpy_fromio(a, b, c) memcpy((a), (b), (c))
204592ffb21SWarner Losh #define memcpy_toio(a, b, c) memcpy((a), (b), (c))
205592ffb21SWarner Losh
206592ffb21SWarner Losh #define VERIFY_READ VM_PROT_READ
207592ffb21SWarner Losh #define VERIFY_WRITE VM_PROT_WRITE
208592ffb21SWarner Losh #define access_ok(prot, p, l) useracc((p), (l), (prot))
209592ffb21SWarner Losh
210592ffb21SWarner Losh /* XXXKIB what is the right code for the FreeBSD ? */
211592ffb21SWarner Losh /* kib@ used ENXIO here -- dumbbell@ */
212592ffb21SWarner Losh #define EREMOTEIO EIO
213592ffb21SWarner Losh #define ERESTARTSYS 512 /* Same value as Linux. */
214592ffb21SWarner Losh
215592ffb21SWarner Losh #define KTR_DRM KTR_DEV
216592ffb21SWarner Losh #define KTR_DRM_REG KTR_SPARE3
217592ffb21SWarner Losh
218592ffb21SWarner Losh #define DRM_AGP_KERN struct agp_info
219592ffb21SWarner Losh #define DRM_AGP_MEM void
220592ffb21SWarner Losh
221592ffb21SWarner Losh #define PCI_VENDOR_ID_APPLE 0x106b
222592ffb21SWarner Losh #define PCI_VENDOR_ID_ASUSTEK 0x1043
223592ffb21SWarner Losh #define PCI_VENDOR_ID_ATI 0x1002
224592ffb21SWarner Losh #define PCI_VENDOR_ID_DELL 0x1028
225592ffb21SWarner Losh #define PCI_VENDOR_ID_HP 0x103c
226592ffb21SWarner Losh #define PCI_VENDOR_ID_IBM 0x1014
227592ffb21SWarner Losh #define PCI_VENDOR_ID_INTEL 0x8086
228592ffb21SWarner Losh #define PCI_VENDOR_ID_SERVERWORKS 0x1166
229592ffb21SWarner Losh #define PCI_VENDOR_ID_SONY 0x104d
230592ffb21SWarner Losh #define PCI_VENDOR_ID_VIA 0x1106
231592ffb21SWarner Losh
232592ffb21SWarner Losh #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
233592ffb21SWarner Losh #define DIV_ROUND_CLOSEST(n,d) (((n) + (d) / 2) / (d))
234592ffb21SWarner Losh #define div_u64(n, d) ((n) / (d))
235592ffb21SWarner Losh #define hweight32(i) bitcount32(i)
236592ffb21SWarner Losh
237592ffb21SWarner Losh static inline unsigned long
roundup_pow_of_two(unsigned long x)238592ffb21SWarner Losh roundup_pow_of_two(unsigned long x)
239592ffb21SWarner Losh {
240592ffb21SWarner Losh
241592ffb21SWarner Losh return (1UL << flsl(x - 1));
242592ffb21SWarner Losh }
243592ffb21SWarner Losh
244592ffb21SWarner Losh /**
245592ffb21SWarner Losh * ror32 - rotate a 32-bit value right
246592ffb21SWarner Losh * @word: value to rotate
247592ffb21SWarner Losh * @shift: bits to roll
248592ffb21SWarner Losh *
249592ffb21SWarner Losh * Source: include/linux/bitops.h
250592ffb21SWarner Losh */
251592ffb21SWarner Losh static inline uint32_t
ror32(uint32_t word,unsigned int shift)252592ffb21SWarner Losh ror32(uint32_t word, unsigned int shift)
253592ffb21SWarner Losh {
254592ffb21SWarner Losh
255592ffb21SWarner Losh return (word >> shift) | (word << (32 - shift));
256592ffb21SWarner Losh }
257592ffb21SWarner Losh
258592ffb21SWarner Losh #define IS_ALIGNED(x, y) (((x) & ((y) - 1)) == 0)
259592ffb21SWarner Losh #define round_down(x, y) rounddown2((x), (y))
260592ffb21SWarner Losh #define round_up(x, y) roundup2((x), (y))
261592ffb21SWarner Losh #define get_unaligned(ptr) \
262592ffb21SWarner Losh ({ __typeof__(*(ptr)) __tmp; \
263592ffb21SWarner Losh memcpy(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
264592ffb21SWarner Losh
265592ffb21SWarner Losh #if _BYTE_ORDER == _LITTLE_ENDIAN
266592ffb21SWarner Losh /* Taken from linux/include/linux/unaligned/le_struct.h. */
267592ffb21SWarner Losh struct __una_u32 { u32 x; } __packed;
268592ffb21SWarner Losh
269592ffb21SWarner Losh static inline u32
__get_unaligned_cpu32(const void * p)270592ffb21SWarner Losh __get_unaligned_cpu32(const void *p)
271592ffb21SWarner Losh {
272592ffb21SWarner Losh const struct __una_u32 *ptr = (const struct __una_u32 *)p;
273592ffb21SWarner Losh
274592ffb21SWarner Losh return (ptr->x);
275592ffb21SWarner Losh }
276592ffb21SWarner Losh
277592ffb21SWarner Losh static inline u32
get_unaligned_le32(const void * p)278592ffb21SWarner Losh get_unaligned_le32(const void *p)
279592ffb21SWarner Losh {
280592ffb21SWarner Losh
281592ffb21SWarner Losh return (__get_unaligned_cpu32((const u8 *)p));
282592ffb21SWarner Losh }
283592ffb21SWarner Losh #else
284592ffb21SWarner Losh /* Taken from linux/include/linux/unaligned/le_byteshift.h. */
285592ffb21SWarner Losh static inline u32
__get_unaligned_le32(const u8 * p)286592ffb21SWarner Losh __get_unaligned_le32(const u8 *p)
287592ffb21SWarner Losh {
288592ffb21SWarner Losh
289592ffb21SWarner Losh return (p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24);
290592ffb21SWarner Losh }
291592ffb21SWarner Losh
292592ffb21SWarner Losh static inline u32
get_unaligned_le32(const void * p)293592ffb21SWarner Losh get_unaligned_le32(const void *p)
294592ffb21SWarner Losh {
295592ffb21SWarner Losh
296592ffb21SWarner Losh return (__get_unaligned_le32((const u8 *)p));
297592ffb21SWarner Losh }
298592ffb21SWarner Losh #endif
299592ffb21SWarner Losh
300592ffb21SWarner Losh static inline unsigned long
ilog2(unsigned long x)301592ffb21SWarner Losh ilog2(unsigned long x)
302592ffb21SWarner Losh {
303592ffb21SWarner Losh
304592ffb21SWarner Losh return (flsl(x) - 1);
305592ffb21SWarner Losh }
306592ffb21SWarner Losh
307592ffb21SWarner Losh int64_t timeval_to_ns(const struct timeval *tv);
308592ffb21SWarner Losh struct timeval ns_to_timeval(const int64_t nsec);
309592ffb21SWarner Losh
310592ffb21SWarner Losh #define PAGE_ALIGN(addr) round_page(addr)
311592ffb21SWarner Losh #define page_to_phys(x) VM_PAGE_TO_PHYS(x)
312592ffb21SWarner Losh #define offset_in_page(x) ((x) & PAGE_MASK)
313592ffb21SWarner Losh
314592ffb21SWarner Losh #define drm_get_device_from_kdev(_kdev) (((struct drm_minor *)(_kdev)->si_drv1)->dev)
315592ffb21SWarner Losh
316592ffb21SWarner Losh #define DRM_IOC_VOID IOC_VOID
317592ffb21SWarner Losh #define DRM_IOC_READ IOC_OUT
318592ffb21SWarner Losh #define DRM_IOC_WRITE IOC_IN
319592ffb21SWarner Losh #define DRM_IOC_READWRITE IOC_INOUT
320592ffb21SWarner Losh #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
321592ffb21SWarner Losh
322592ffb21SWarner Losh static inline long
__copy_to_user(void __user * to,const void * from,unsigned long n)323592ffb21SWarner Losh __copy_to_user(void __user *to, const void *from, unsigned long n)
324592ffb21SWarner Losh {
325592ffb21SWarner Losh return (copyout(from, to, n) != 0 ? n : 0);
326592ffb21SWarner Losh }
327592ffb21SWarner Losh #define copy_to_user(to, from, n) __copy_to_user((to), (from), (n))
328592ffb21SWarner Losh
329592ffb21SWarner Losh static inline int
__put_user(size_t size,void * ptr,void * x)330592ffb21SWarner Losh __put_user(size_t size, void *ptr, void *x)
331592ffb21SWarner Losh {
332592ffb21SWarner Losh
333592ffb21SWarner Losh size = copy_to_user(ptr, x, size);
334592ffb21SWarner Losh
335592ffb21SWarner Losh return (size ? -EFAULT : size);
336592ffb21SWarner Losh }
337592ffb21SWarner Losh #define put_user(x, ptr) __put_user(sizeof(*ptr), (ptr), &(x))
338592ffb21SWarner Losh
339592ffb21SWarner Losh static inline unsigned long
__copy_from_user(void * to,const void __user * from,unsigned long n)340592ffb21SWarner Losh __copy_from_user(void *to, const void __user *from, unsigned long n)
341592ffb21SWarner Losh {
342592ffb21SWarner Losh return ((copyin(__DECONST(void *, from), to, n) != 0 ? n : 0));
343592ffb21SWarner Losh }
344592ffb21SWarner Losh #define copy_from_user(to, from, n) __copy_from_user((to), (from), (n))
345592ffb21SWarner Losh
346592ffb21SWarner Losh static inline int
__get_user(size_t size,const void * ptr,void * x)347592ffb21SWarner Losh __get_user(size_t size, const void *ptr, void *x)
348592ffb21SWarner Losh {
349592ffb21SWarner Losh
350592ffb21SWarner Losh size = copy_from_user(x, ptr, size);
351592ffb21SWarner Losh
352592ffb21SWarner Losh return (size ? -EFAULT : size);
353592ffb21SWarner Losh }
354592ffb21SWarner Losh #define get_user(x, ptr) __get_user(sizeof(*ptr), (ptr), &(x))
355592ffb21SWarner Losh
356592ffb21SWarner Losh static inline int
__copy_to_user_inatomic(void __user * to,const void * from,unsigned n)357592ffb21SWarner Losh __copy_to_user_inatomic(void __user *to, const void *from, unsigned n)
358592ffb21SWarner Losh {
359592ffb21SWarner Losh
360592ffb21SWarner Losh return (copyout_nofault(from, to, n) != 0 ? n : 0);
361592ffb21SWarner Losh }
362592ffb21SWarner Losh #define __copy_to_user_inatomic_nocache(to, from, n) \
363592ffb21SWarner Losh __copy_to_user_inatomic((to), (from), (n))
364592ffb21SWarner Losh
365592ffb21SWarner Losh static inline unsigned long
__copy_from_user_inatomic(void * to,const void __user * from,unsigned long n)366592ffb21SWarner Losh __copy_from_user_inatomic(void *to, const void __user *from,
367592ffb21SWarner Losh unsigned long n)
368592ffb21SWarner Losh {
369592ffb21SWarner Losh
370592ffb21SWarner Losh /*
371592ffb21SWarner Losh * XXXKIB. Equivalent Linux function is implemented using
372592ffb21SWarner Losh * MOVNTI for aligned moves. For unaligned head and tail,
373592ffb21SWarner Losh * normal move is performed. As such, it is not incorrect, if
374592ffb21SWarner Losh * only somewhat slower, to use normal copyin. All uses
375592ffb21SWarner Losh * except shmem_pwrite_fast() have the destination mapped WC.
376592ffb21SWarner Losh */
377592ffb21SWarner Losh return ((copyin_nofault(__DECONST(void *, from), to, n) != 0 ? n : 0));
378592ffb21SWarner Losh }
379592ffb21SWarner Losh #define __copy_from_user_inatomic_nocache(to, from, n) \
380592ffb21SWarner Losh __copy_from_user_inatomic((to), (from), (n))
381592ffb21SWarner Losh
382592ffb21SWarner Losh static inline int
fault_in_multipages_readable(const char __user * uaddr,int size)383592ffb21SWarner Losh fault_in_multipages_readable(const char __user *uaddr, int size)
384592ffb21SWarner Losh {
385592ffb21SWarner Losh char c;
386592ffb21SWarner Losh int ret = 0;
387592ffb21SWarner Losh const char __user *end = uaddr + size - 1;
388592ffb21SWarner Losh
389592ffb21SWarner Losh if (unlikely(size == 0))
390592ffb21SWarner Losh return ret;
391592ffb21SWarner Losh
392592ffb21SWarner Losh while (uaddr <= end) {
393592ffb21SWarner Losh ret = -copyin(uaddr, &c, 1);
394592ffb21SWarner Losh if (ret != 0)
395592ffb21SWarner Losh return -EFAULT;
396592ffb21SWarner Losh uaddr += PAGE_SIZE;
397592ffb21SWarner Losh }
398592ffb21SWarner Losh
399592ffb21SWarner Losh /* Check whether the range spilled into the next page. */
400592ffb21SWarner Losh if (((unsigned long)uaddr & ~PAGE_MASK) ==
401592ffb21SWarner Losh ((unsigned long)end & ~PAGE_MASK)) {
402592ffb21SWarner Losh ret = -copyin(end, &c, 1);
403592ffb21SWarner Losh }
404592ffb21SWarner Losh
405592ffb21SWarner Losh return ret;
406592ffb21SWarner Losh }
407592ffb21SWarner Losh
408592ffb21SWarner Losh static inline int
fault_in_multipages_writeable(char __user * uaddr,int size)409592ffb21SWarner Losh fault_in_multipages_writeable(char __user *uaddr, int size)
410592ffb21SWarner Losh {
411592ffb21SWarner Losh int ret = 0;
412592ffb21SWarner Losh char __user *end = uaddr + size - 1;
413592ffb21SWarner Losh
414592ffb21SWarner Losh if (unlikely(size == 0))
415592ffb21SWarner Losh return ret;
416592ffb21SWarner Losh
417592ffb21SWarner Losh /*
418592ffb21SWarner Losh * Writing zeroes into userspace here is OK, because we know that if
419592ffb21SWarner Losh * the zero gets there, we'll be overwriting it.
420592ffb21SWarner Losh */
421592ffb21SWarner Losh while (uaddr <= end) {
422592ffb21SWarner Losh ret = subyte(uaddr, 0);
423592ffb21SWarner Losh if (ret != 0)
424592ffb21SWarner Losh return -EFAULT;
425592ffb21SWarner Losh uaddr += PAGE_SIZE;
426592ffb21SWarner Losh }
427592ffb21SWarner Losh
428592ffb21SWarner Losh /* Check whether the range spilled into the next page. */
429592ffb21SWarner Losh if (((unsigned long)uaddr & ~PAGE_MASK) ==
430592ffb21SWarner Losh ((unsigned long)end & ~PAGE_MASK))
431592ffb21SWarner Losh ret = subyte(end, 0);
432592ffb21SWarner Losh
433592ffb21SWarner Losh return ret;
434592ffb21SWarner Losh }
435592ffb21SWarner Losh
436592ffb21SWarner Losh enum __drm_capabilities {
437592ffb21SWarner Losh CAP_SYS_ADMIN
438592ffb21SWarner Losh };
439592ffb21SWarner Losh
440592ffb21SWarner Losh static inline bool
capable(enum __drm_capabilities cap)441592ffb21SWarner Losh capable(enum __drm_capabilities cap)
442592ffb21SWarner Losh {
443592ffb21SWarner Losh
444592ffb21SWarner Losh switch (cap) {
445592ffb21SWarner Losh case CAP_SYS_ADMIN:
446592ffb21SWarner Losh return DRM_SUSER(curthread);
447592ffb21SWarner Losh default:
448592ffb21SWarner Losh panic("%s: unhandled capability: %0x", __func__, cap);
449592ffb21SWarner Losh return (false);
450592ffb21SWarner Losh }
451592ffb21SWarner Losh }
452592ffb21SWarner Losh
453592ffb21SWarner Losh #define to_user_ptr(x) ((void *)(uintptr_t)(x))
454592ffb21SWarner Losh #define sigemptyset(set) SIGEMPTYSET(set)
455592ffb21SWarner Losh #define sigaddset(set, sig) SIGADDSET(set, sig)
456592ffb21SWarner Losh
457592ffb21SWarner Losh #define DRM_LOCK(dev) sx_xlock(&(dev)->dev_struct_lock)
458592ffb21SWarner Losh #define DRM_UNLOCK(dev) sx_xunlock(&(dev)->dev_struct_lock)
459592ffb21SWarner Losh
460592ffb21SWarner Losh extern unsigned long drm_linux_timer_hz_mask;
461592ffb21SWarner Losh #define jiffies ticks
462592ffb21SWarner Losh #define jiffies_to_msecs(x) (((int64_t)(x)) * 1000 / hz)
463592ffb21SWarner Losh #define msecs_to_jiffies(x) (((int64_t)(x)) * hz / 1000)
464592ffb21SWarner Losh #define timespec_to_jiffies(x) (((x)->tv_sec * 1000000 + (x)->tv_nsec) * hz / 1000000)
465592ffb21SWarner Losh #define time_after(a,b) ((long)(b) - (long)(a) < 0)
466592ffb21SWarner Losh #define time_after_eq(a,b) ((long)(b) - (long)(a) <= 0)
467592ffb21SWarner Losh #define round_jiffies(j) ((unsigned long)(((j) + drm_linux_timer_hz_mask) & ~drm_linux_timer_hz_mask))
468592ffb21SWarner Losh #define round_jiffies_up(j) round_jiffies(j) /* TODO */
469592ffb21SWarner Losh #define round_jiffies_up_relative(j) round_jiffies_up(j) /* TODO */
470592ffb21SWarner Losh
471592ffb21SWarner Losh #define getrawmonotonic(ts) getnanouptime(ts)
472592ffb21SWarner Losh
473592ffb21SWarner Losh #define wake_up(queue) wakeup_one((void *)queue)
474592ffb21SWarner Losh #define wake_up_interruptible(queue) wakeup_one((void *)queue)
475592ffb21SWarner Losh #define wake_up_all(queue) wakeup((void *)queue)
476592ffb21SWarner Losh #define wake_up_interruptible_all(queue) wakeup((void *)queue)
477592ffb21SWarner Losh
478592ffb21SWarner Losh struct completion {
479592ffb21SWarner Losh unsigned int done;
480592ffb21SWarner Losh struct mtx lock;
481592ffb21SWarner Losh };
482592ffb21SWarner Losh
483592ffb21SWarner Losh #define INIT_COMPLETION(c) ((c).done = 0);
484592ffb21SWarner Losh
485592ffb21SWarner Losh static inline void
init_completion(struct completion * c)486592ffb21SWarner Losh init_completion(struct completion *c)
487592ffb21SWarner Losh {
488592ffb21SWarner Losh
489592ffb21SWarner Losh mtx_init(&c->lock, "drmcompl", NULL, MTX_DEF);
490592ffb21SWarner Losh c->done = 0;
491592ffb21SWarner Losh }
492592ffb21SWarner Losh
493592ffb21SWarner Losh static inline void
free_completion(struct completion * c)494592ffb21SWarner Losh free_completion(struct completion *c)
495592ffb21SWarner Losh {
496592ffb21SWarner Losh
497592ffb21SWarner Losh mtx_destroy(&c->lock);
498592ffb21SWarner Losh }
499592ffb21SWarner Losh
500592ffb21SWarner Losh static inline void
complete_all(struct completion * c)501592ffb21SWarner Losh complete_all(struct completion *c)
502592ffb21SWarner Losh {
503592ffb21SWarner Losh
504592ffb21SWarner Losh mtx_lock(&c->lock);
505592ffb21SWarner Losh c->done++;
506592ffb21SWarner Losh mtx_unlock(&c->lock);
507592ffb21SWarner Losh wakeup(c);
508592ffb21SWarner Losh }
509592ffb21SWarner Losh
510592ffb21SWarner Losh static inline long
wait_for_completion_interruptible_timeout(struct completion * c,unsigned long timeout)511592ffb21SWarner Losh wait_for_completion_interruptible_timeout(struct completion *c,
512592ffb21SWarner Losh unsigned long timeout)
513592ffb21SWarner Losh {
514592ffb21SWarner Losh unsigned long start_jiffies, elapsed_jiffies;
515592ffb21SWarner Losh bool timeout_expired = false, awakened = false;
516592ffb21SWarner Losh long ret = timeout;
517592ffb21SWarner Losh
518592ffb21SWarner Losh start_jiffies = ticks;
519592ffb21SWarner Losh
520592ffb21SWarner Losh mtx_lock(&c->lock);
521592ffb21SWarner Losh while (c->done == 0 && !timeout_expired) {
522592ffb21SWarner Losh ret = -msleep(c, &c->lock, PCATCH, "drmwco", timeout);
523592ffb21SWarner Losh switch(ret) {
524592ffb21SWarner Losh case -EWOULDBLOCK:
525592ffb21SWarner Losh timeout_expired = true;
526592ffb21SWarner Losh ret = 0;
527592ffb21SWarner Losh break;
528592ffb21SWarner Losh case -EINTR:
529592ffb21SWarner Losh case -ERESTART:
530592ffb21SWarner Losh ret = -ERESTARTSYS;
531592ffb21SWarner Losh break;
532592ffb21SWarner Losh case 0:
533592ffb21SWarner Losh awakened = true;
534592ffb21SWarner Losh break;
535592ffb21SWarner Losh }
536592ffb21SWarner Losh }
537592ffb21SWarner Losh mtx_unlock(&c->lock);
538592ffb21SWarner Losh
539592ffb21SWarner Losh if (awakened) {
540592ffb21SWarner Losh elapsed_jiffies = ticks - start_jiffies;
541592ffb21SWarner Losh ret = timeout > elapsed_jiffies ? timeout - elapsed_jiffies : 1;
542592ffb21SWarner Losh }
543592ffb21SWarner Losh
544592ffb21SWarner Losh return (ret);
545592ffb21SWarner Losh }
546592ffb21SWarner Losh
547592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_DMA);
548592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_SAREA);
549592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_DRIVER);
550592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_MAGIC);
551592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_MINOR);
552592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_IOCTLS);
553592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_MAPS);
554592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_BUFS);
555592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_SEGS);
556592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_PAGES);
557592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_FILES);
558592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_QUEUES);
559592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_CMDS);
560592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_MAPPINGS);
561592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_BUFLISTS);
562592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_AGPLISTS);
563592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_CTXBITMAP);
564592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_SGLISTS);
565592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_MM);
566592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_HASHTAB);
567592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_KMS);
568592ffb21SWarner Losh MALLOC_DECLARE(DRM_MEM_VBLANK);
569592ffb21SWarner Losh
570592ffb21SWarner Losh #define simple_strtol(a, b, c) strtol((a), (b), (c))
571592ffb21SWarner Losh
572592ffb21SWarner Losh typedef struct drm_pci_id_list
573592ffb21SWarner Losh {
574592ffb21SWarner Losh int vendor;
575592ffb21SWarner Losh int device;
576592ffb21SWarner Losh long driver_private;
577592ffb21SWarner Losh char *name;
578592ffb21SWarner Losh } drm_pci_id_list_t;
579592ffb21SWarner Losh
580592ffb21SWarner Losh #ifdef __i386__
581592ffb21SWarner Losh #define CONFIG_X86 1
582592ffb21SWarner Losh #endif
583592ffb21SWarner Losh #ifdef __amd64__
584592ffb21SWarner Losh #define CONFIG_X86 1
585592ffb21SWarner Losh #define CONFIG_X86_64 1
586592ffb21SWarner Losh #endif
587592ffb21SWarner Losh #ifdef __ia64__
588592ffb21SWarner Losh #define CONFIG_IA64 1
589592ffb21SWarner Losh #endif
590592ffb21SWarner Losh
591592ffb21SWarner Losh #if defined(__i386__) || defined(__amd64__)
592592ffb21SWarner Losh #define CONFIG_ACPI
593592ffb21SWarner Losh #define CONFIG_DRM_I915_KMS
594592ffb21SWarner Losh #undef CONFIG_INTEL_IOMMU
595592ffb21SWarner Losh #endif
596592ffb21SWarner Losh
597592ffb21SWarner Losh #ifdef COMPAT_FREEBSD32
598592ffb21SWarner Losh #define CONFIG_COMPAT
599592ffb21SWarner Losh #endif
600592ffb21SWarner Losh
601592ffb21SWarner Losh #ifndef __arm__
602592ffb21SWarner Losh #define CONFIG_AGP 1
603592ffb21SWarner Losh #define CONFIG_MTRR 1
604592ffb21SWarner Losh #endif
605592ffb21SWarner Losh
606592ffb21SWarner Losh #define CONFIG_FB 1
607592ffb21SWarner Losh extern const char *fb_mode_option;
608592ffb21SWarner Losh
609592ffb21SWarner Losh #undef CONFIG_DEBUG_FS
610592ffb21SWarner Losh #undef CONFIG_VGA_CONSOLE
611592ffb21SWarner Losh
612592ffb21SWarner Losh #define EXPORT_SYMBOL(x)
613592ffb21SWarner Losh #define EXPORT_SYMBOL_GPL(x)
614592ffb21SWarner Losh #define MODULE_AUTHOR(author)
615592ffb21SWarner Losh #define MODULE_DESCRIPTION(desc)
616592ffb21SWarner Losh #define MODULE_LICENSE(license)
617592ffb21SWarner Losh #define MODULE_PARM_DESC(name, desc)
618592ffb21SWarner Losh #define MODULE_DEVICE_TABLE(name, list)
619592ffb21SWarner Losh #define module_param_named(name, var, type, perm)
620592ffb21SWarner Losh
621592ffb21SWarner Losh #define printk printf
622592ffb21SWarner Losh #define pr_err DRM_ERROR
623592ffb21SWarner Losh #define pr_warn DRM_WARNING
624592ffb21SWarner Losh #define pr_warn_once DRM_WARNING
625592ffb21SWarner Losh #define KERN_DEBUG ""
626592ffb21SWarner Losh
627592ffb21SWarner Losh /* I2C compatibility. */
628592ffb21SWarner Losh #define I2C_M_RD IIC_M_RD
629592ffb21SWarner Losh #define I2C_M_WR IIC_M_WR
630592ffb21SWarner Losh #define I2C_M_NOSTART IIC_M_NOSTART
631592ffb21SWarner Losh
632592ffb21SWarner Losh struct fb_info * framebuffer_alloc(void);
633592ffb21SWarner Losh void framebuffer_release(struct fb_info *info);
634592ffb21SWarner Losh
635592ffb21SWarner Losh #define console_lock()
636592ffb21SWarner Losh #define console_unlock()
637592ffb21SWarner Losh #define console_trylock() true
638592ffb21SWarner Losh
639592ffb21SWarner Losh #define PM_EVENT_SUSPEND 0x0002
640592ffb21SWarner Losh #define PM_EVENT_QUIESCE 0x0008
641592ffb21SWarner Losh #define PM_EVENT_PRETHAW PM_EVENT_QUIESCE
642592ffb21SWarner Losh
643592ffb21SWarner Losh typedef struct pm_message {
644592ffb21SWarner Losh int event;
645592ffb21SWarner Losh } pm_message_t;
646592ffb21SWarner Losh
647592ffb21SWarner Losh static inline int
pci_read_config_byte(device_t kdev,int where,u8 * val)648592ffb21SWarner Losh pci_read_config_byte(device_t kdev, int where, u8 *val)
649592ffb21SWarner Losh {
650592ffb21SWarner Losh
651592ffb21SWarner Losh *val = (u8)pci_read_config(kdev, where, 1);
652592ffb21SWarner Losh return (0);
653592ffb21SWarner Losh }
654592ffb21SWarner Losh
655592ffb21SWarner Losh static inline int
pci_write_config_byte(device_t kdev,int where,u8 val)656592ffb21SWarner Losh pci_write_config_byte(device_t kdev, int where, u8 val)
657592ffb21SWarner Losh {
658592ffb21SWarner Losh
659592ffb21SWarner Losh pci_write_config(kdev, where, val, 1);
660592ffb21SWarner Losh return (0);
661592ffb21SWarner Losh }
662592ffb21SWarner Losh
663592ffb21SWarner Losh static inline int
pci_read_config_word(device_t kdev,int where,uint16_t * val)664592ffb21SWarner Losh pci_read_config_word(device_t kdev, int where, uint16_t *val)
665592ffb21SWarner Losh {
666592ffb21SWarner Losh
667592ffb21SWarner Losh *val = (uint16_t)pci_read_config(kdev, where, 2);
668592ffb21SWarner Losh return (0);
669592ffb21SWarner Losh }
670592ffb21SWarner Losh
671592ffb21SWarner Losh static inline int
pci_write_config_word(device_t kdev,int where,uint16_t val)672592ffb21SWarner Losh pci_write_config_word(device_t kdev, int where, uint16_t val)
673592ffb21SWarner Losh {
674592ffb21SWarner Losh
675592ffb21SWarner Losh pci_write_config(kdev, where, val, 2);
676592ffb21SWarner Losh return (0);
677592ffb21SWarner Losh }
678592ffb21SWarner Losh
679592ffb21SWarner Losh static inline int
pci_read_config_dword(device_t kdev,int where,uint32_t * val)680592ffb21SWarner Losh pci_read_config_dword(device_t kdev, int where, uint32_t *val)
681592ffb21SWarner Losh {
682592ffb21SWarner Losh
683592ffb21SWarner Losh *val = (uint32_t)pci_read_config(kdev, where, 4);
684592ffb21SWarner Losh return (0);
685592ffb21SWarner Losh }
686592ffb21SWarner Losh
687592ffb21SWarner Losh static inline int
pci_write_config_dword(device_t kdev,int where,uint32_t val)688592ffb21SWarner Losh pci_write_config_dword(device_t kdev, int where, uint32_t val)
689592ffb21SWarner Losh {
690592ffb21SWarner Losh
691592ffb21SWarner Losh pci_write_config(kdev, where, val, 4);
692592ffb21SWarner Losh return (0);
693592ffb21SWarner Losh }
694592ffb21SWarner Losh
695592ffb21SWarner Losh static inline void
on_each_cpu(void callback (void * data),void * data,int wait)696592ffb21SWarner Losh on_each_cpu(void callback(void *data), void *data, int wait)
697592ffb21SWarner Losh {
698592ffb21SWarner Losh
699592ffb21SWarner Losh smp_rendezvous(NULL, callback, NULL, data);
700592ffb21SWarner Losh }
701592ffb21SWarner Losh
702592ffb21SWarner Losh void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
703592ffb21SWarner Losh int groupsize, char *linebuf, size_t linebuflen, bool ascii);
704592ffb21SWarner Losh
705592ffb21SWarner Losh #define KIB_NOTYET() \
706592ffb21SWarner Losh do { \
707592ffb21SWarner Losh if (drm_debug && drm_notyet) \
708592ffb21SWarner Losh printf("NOTYET: %s at %s:%d\n", __func__, __FILE__, __LINE__); \
709592ffb21SWarner Losh } while (0)
710592ffb21SWarner Losh
711592ffb21SWarner Losh #endif /* _DRM_OS_FREEBSD_H_ */
712