The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/drm/drm_os_freebsd.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /**
    2  * \file drm_os_freebsd.h
    3  * OS-specific #defines for FreeBSD
    4  * 
    5  * \author Eric Anholt <anholt@FreeBSD.org>
    6  */
    7 
    8 /*-
    9  * Copyright 2003 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$
   32  */
   33 
   34 #include <sys/param.h>
   35 #include <sys/queue.h>
   36 #include <sys/malloc.h>
   37 #include <sys/kernel.h>
   38 #include <sys/module.h>
   39 #include <sys/systm.h>
   40 #include <sys/conf.h>
   41 #include <sys/stat.h>
   42 #include <sys/proc.h>
   43 #include <sys/lock.h>
   44 #include <sys/fcntl.h>
   45 #include <sys/uio.h>
   46 #include <sys/filio.h>
   47 #include <sys/sysctl.h>
   48 #include <sys/bus.h>
   49 #include <sys/signalvar.h>
   50 #include <sys/poll.h>
   51 #include <vm/vm.h>
   52 #include <vm/pmap.h>
   53 #include <vm/vm_extern.h>
   54 #include <vm/vm_map.h>
   55 #include <vm/vm_param.h>
   56 #include <machine/param.h>
   57 #include <machine/pmap.h>
   58 #include <machine/bus.h>
   59 #include <machine/resource.h>
   60 #if __FreeBSD_version >= 480000
   61 #include <sys/endian.h>
   62 #endif
   63 #include <sys/mman.h>
   64 #include <sys/rman.h>
   65 #include <sys/memrange.h>
   66 #if __FreeBSD_version >= 500000
   67 #include <dev/pci/pcivar.h>
   68 #include <sys/selinfo.h>
   69 #else
   70 #include <pci/pcivar.h>
   71 #include <sys/select.h>
   72 #endif
   73 #include <sys/bus.h>
   74 #if __FreeBSD_version >= 400005
   75 #include <sys/taskqueue.h>
   76 #endif
   77 #if __FreeBSD_version >= 500000
   78 #include <sys/mutex.h>
   79 #endif
   80 
   81 #include "dev/drm/drm_linux_list.h"
   82 
   83 #if __FreeBSD_version >= 400006
   84 #define __REALLY_HAVE_AGP       __HAVE_AGP
   85 #endif
   86 
   87 #ifdef __i386__
   88 #define __REALLY_HAVE_MTRR      (__HAVE_MTRR) && (__FreeBSD_version >= 460000)
   89 #else
   90 #define __REALLY_HAVE_MTRR      0
   91 #endif
   92 
   93 #define __REALLY_HAVE_SG        (__HAVE_SG)
   94 
   95 #if __REALLY_HAVE_AGP
   96 #include <pci/agpvar.h>
   97 #include <sys/agpio.h>
   98 #endif
   99 
  100 #include <opt_drm.h>
  101 #if DRM_DEBUG
  102 #undef  DRM_DEBUG_CODE
  103 #define DRM_DEBUG_CODE 2
  104 #endif
  105 #undef DRM_DEBUG
  106 
  107 #if DRM_LINUX
  108 #include <sys/file.h>
  109 #include <sys/proc.h>
  110 #include <machine/../linux/linux.h>
  111 #include <machine/../linux/linux_proto.h>
  112 #endif
  113 
  114 #define DRM_TIME_SLICE        (hz/20)  /* Time slice for GLXContexts      */
  115 
  116 #define DRM_DEV_MODE    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
  117 #define DRM_DEV_UID     0
  118 #define DRM_DEV_GID     0
  119 
  120 #if __FreeBSD_version >= 500000
  121 #define DRM_CURPROC             curthread
  122 #define DRM_STRUCTPROC          struct thread
  123 #define DRM_SPINTYPE            struct mtx
  124 #define DRM_SPININIT(l,name)    mtx_init(&l, name, NULL, MTX_DEF)
  125 #define DRM_SPINUNINIT(l)       mtx_destroy(&l)
  126 #define DRM_SPINLOCK(l)         mtx_lock(l)
  127 #define DRM_SPINUNLOCK(u)       mtx_unlock(u);
  128 #define DRM_SPINLOCK_ASSERT(l)  mtx_assert(l, MA_OWNED)
  129 #define DRM_CURRENTPID          curthread->td_proc->p_pid
  130 #define DRM_LOCK()              mtx_lock(&dev->dev_lock)
  131 #define DRM_UNLOCK()            mtx_unlock(&dev->dev_lock)
  132 #else
  133 /* There is no need for locking on FreeBSD 4.x.  Synchronization is handled by
  134  * the fact that there is no reentrancy of the kernel except for interrupt
  135  * handlers, and the interrupt handler synchronization is managed by spls.
  136  */
  137 #define DRM_CURPROC             curproc
  138 #define DRM_STRUCTPROC          struct proc
  139 #define DRM_SPINTYPE            
  140 #define DRM_SPININIT(l,name)
  141 #define DRM_SPINUNINIT(l)
  142 #define DRM_SPINLOCK(l)
  143 #define DRM_SPINUNLOCK(u)
  144 #define DRM_SPINLOCK_ASSERT(l)
  145 #define DRM_CURRENTPID          curproc->p_pid
  146 #define DRM_LOCK()
  147 #define DRM_UNLOCK()
  148 #endif
  149 
  150 /* Currently our DRMFILE (filp) is a void * which is actually the pid
  151  * of the current process.  It should be a per-open unique pointer, but
  152  * code for that is not yet written */
  153 #define DRMFILE                 void *
  154 #define DRM_IOCTL_ARGS          struct cdev *kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp
  155 #define DRM_SUSER(p)            suser(p)
  156 #define DRM_TASKQUEUE_ARGS      void *arg, int pending
  157 #define DRM_IRQ_ARGS            void *arg
  158 typedef void                    irqreturn_t;
  159 #define IRQ_HANDLED             /* nothing */
  160 #define IRQ_NONE                /* nothing */
  161 #define DRM_DEVICE              drm_device_t    *dev    = kdev->si_drv1
  162 #define DRM_MALLOC(size)        malloc( size, DRM(M_DRM), M_NOWAIT )
  163 #define DRM_FREE(pt,size)               free( pt, DRM(M_DRM) )
  164 
  165 /* Read/write from bus space, with byteswapping to le if necessary */
  166 #define DRM_READ8(map, offset)          *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset))
  167 #define DRM_READ32(map, offset)         *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset))
  168 #define DRM_WRITE8(map, offset, val)    *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset)) = val
  169 #define DRM_WRITE32(map, offset, val)   *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val
  170 /*
  171 #define DRM_READ8(map, offset)          bus_space_read_1(  (map)->iot, (map)->ioh, (offset) )
  172 #define DRM_READ32(map, offset)         bus_space_read_4(  (map)->iot, (map)->ioh, (offset) )
  173 #define DRM_WRITE8(map, offset, val)    bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) )
  174 #define DRM_WRITE32(map, offset, val)   bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) )
  175 */
  176 #define DRM_AGP_FIND_DEVICE()   agp_find_device()
  177 #define DRM_ERR(v)              v
  178 
  179 #define DRM_MTRR_WC     MDF_WRITECOMBINE
  180 
  181 #define DRM_GET_PRIV_WITH_RETURN(_priv, _filp)                  \
  182 do {                                                            \
  183         if (_filp != (DRMFILE)(intptr_t)DRM_CURRENTPID) {       \
  184                 DRM_ERROR("filp doesn't match curproc\n");      \
  185                 return EINVAL;                                  \
  186         }                                                       \
  187         DRM_LOCK();                                             \
  188         _priv = DRM(find_file_by_proc)(dev, DRM_CURPROC);       \
  189         DRM_UNLOCK();                                           \
  190         if (_priv == NULL) {                                    \
  191                 DRM_DEBUG("can't find authenticator\n");        \
  192                 return EINVAL;                                  \
  193         }                                                       \
  194 } while (0)
  195 
  196 #define LOCK_TEST_WITH_RETURN(dev, filp)                                \
  197 do {                                                                    \
  198         if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||              \
  199              dev->lock.filp != filp) {                                  \
  200                 DRM_ERROR("%s called without lock held\n",              \
  201                            __FUNCTION__);                               \
  202                 return EINVAL;                                          \
  203         }                                                               \
  204 } while (0)
  205 
  206 #define DRM_UDELAY( udelay )                                    \
  207 do {                                                            \
  208         struct timeval tv1, tv2;                                \
  209         microtime(&tv1);                                        \
  210         do {                                                    \
  211                 microtime(&tv2);                                \
  212         }                                                       \
  213         while (((tv2.tv_sec-tv1.tv_sec)*1000000 + tv2.tv_usec - tv1.tv_usec) < udelay ); \
  214 } while (0)
  215 
  216 #define DRM_GETSAREA()                                  \
  217 do {                                                            \
  218         drm_map_list_entry_t *listentry;                        \
  219         TAILQ_FOREACH(listentry, dev->maplist, link) {          \
  220                 drm_local_map_t *map = listentry->map;          \
  221                 if (map->type == _DRM_SHM &&                    \
  222                         map->flags & _DRM_CONTAINS_LOCK) {      \
  223                         dev_priv->sarea = map;                  \
  224                         break;                                  \
  225                 }                                               \
  226         }                                                       \
  227 } while (0)
  228 
  229 #define DRM_HZ hz
  230 
  231 #if defined(__FreeBSD__) && __FreeBSD_version > 500000
  232 #define DRM_WAIT_ON( ret, queue, timeout, condition )           \
  233 for ( ret = 0 ; !ret && !(condition) ; ) {                      \
  234         mtx_lock(&dev->irq_lock);                               \
  235         if (!(condition))                                       \
  236            ret = msleep(&(queue), &dev->irq_lock,       \
  237                          PZERO | PCATCH, "drmwtq", (timeout));  \
  238         mtx_unlock(&dev->irq_lock);                     \
  239 }
  240 #else
  241 #define DRM_WAIT_ON( ret, queue, timeout, condition )   \
  242 for ( ret = 0 ; !ret && !(condition) ; ) {              \
  243         int s = spldrm();                               \
  244         if (!(condition))                               \
  245            ret = tsleep( &(queue), PZERO | PCATCH,      \
  246                          "drmwtq", (timeout) );         \
  247         splx(s);                                        \
  248 }
  249 #endif
  250 
  251 #define DRM_WAKEUP( queue ) wakeup( queue )
  252 #define DRM_WAKEUP_INT( queue ) wakeup( queue )
  253 #define DRM_INIT_WAITQUEUE( queue )  do {} while (0)
  254 
  255 #define DRM_COPY_TO_USER_IOCTL(user, kern, size)        \
  256         if ( IOCPARM_LEN(cmd) != size)                  \
  257                 return EINVAL;                          \
  258         *user = kern;
  259 #define DRM_COPY_FROM_USER_IOCTL(kern, user, size) \
  260         if ( IOCPARM_LEN(cmd) != size)                  \
  261                 return EINVAL;                          \
  262         kern = *user;
  263 #define DRM_COPY_TO_USER(user, kern, size) \
  264         copyout(kern, user, size)
  265 #define DRM_COPY_FROM_USER(kern, user, size) \
  266         copyin(user, kern, size)
  267 /* Macros for userspace access with checking readability once */
  268 /* FIXME: can't find equivalent functionality for nocheck yet.
  269  * It'll be slower than linux, but should be correct.
  270  */
  271 #define DRM_VERIFYAREA_READ( uaddr, size )              \
  272         (!useracc((caddr_t)uaddr, size, VM_PROT_READ))
  273 #define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3)  \
  274         copyin(arg2, arg1, arg3)
  275 #define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3)    \
  276         copyout(arg2, arg1, arg3)
  277 #define DRM_GET_USER_UNCHECKED(val, uaddr)                      \
  278         ((val) = fuword32(uaddr), 0)
  279 #define DRM_PUT_USER_UNCHECKED(uaddr, val)                      \
  280         suword32(uaddr, val)
  281 
  282 /* DRM_READMEMORYBARRIER() prevents reordering of reads.
  283  * DRM_WRITEMEMORYBARRIER() prevents reordering of writes.
  284  * DRM_MEMORYBARRIER() prevents reordering of reads and writes.
  285  */
  286 #if defined(__i386__)
  287 #define DRM_READMEMORYBARRIER()         __asm __volatile( \
  288                                         "lock; addl $0,0(%%esp)" : : : "memory");
  289 #define DRM_WRITEMEMORYBARRIER()        __asm __volatile("" : : : "memory");
  290 #define DRM_MEMORYBARRIER()             __asm __volatile( \
  291                                         "lock; addl $0,0(%%esp)" : : : "memory");
  292 #elif defined(__alpha__)
  293 #define DRM_READMEMORYBARRIER()         alpha_mb();
  294 #define DRM_WRITEMEMORYBARRIER()        alpha_wmb();
  295 #define DRM_MEMORYBARRIER()             alpha_mb();
  296 #elif defined(__amd64__)
  297 //#warning FIX-ME!!!
  298 #define DRM_READMEMORYBARRIER()         __asm __volatile("lfence" ::: "memory");
  299 #define DRM_WRITEMEMORYBARRIER()        __asm __volatile("sfence" ::: "memory");
  300 #define DRM_MEMORYBARRIER()             __asm __volatile("mfence" ::: "memory");
  301 #endif
  302 
  303 #define PAGE_ALIGN(addr) round_page(addr)
  304 
  305 #ifndef M_WAITOK                /* M_WAITOK (=0) name removed in -current */
  306 #define M_WAITOK 0
  307 #endif
  308 
  309 #define malloctype DRM(M_DRM)
  310 /* The macros conflicted in the MALLOC_DEFINE */
  311 MALLOC_DECLARE(malloctype);
  312 #undef malloctype
  313 
  314 #if __FreeBSD_version < 502109
  315 #define bus_alloc_resource_any(dev, type, rid, flags) \
  316         bus_alloc_resource(dev, type, rid, 0ul, ~0ul, 1, flags)
  317 #endif
  318 
  319 #if __FreeBSD_version >= 480000
  320 #define cpu_to_le32(x) htole32(x)
  321 #define le32_to_cpu(x) le32toh(x)
  322 #else
  323 #define cpu_to_le32(x) (x)
  324 #define le32_to_cpu(x) (x)
  325 #endif
  326 
  327 typedef unsigned long dma_addr_t;
  328 typedef u_int32_t atomic_t;
  329 typedef u_int32_t u32;
  330 typedef u_int16_t u16;
  331 typedef u_int8_t u8;
  332 #define atomic_set(p, v)        (*(p) = (v))
  333 #define atomic_read(p)          (*(p))
  334 #define atomic_inc(p)           atomic_add_int(p, 1)
  335 #define atomic_dec(p)           atomic_subtract_int(p, 1)
  336 #define atomic_add(n, p)        atomic_add_int(p, n)
  337 #define atomic_sub(n, p)        atomic_subtract_int(p, n)
  338 
  339 /* Fake this */
  340 
  341 #if __FreeBSD_version < 500000
  342 /* The extra atomic functions from 5.0 haven't been merged to 4.x */
  343 static __inline int
  344 atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src)
  345 {
  346         int res = exp;
  347 
  348         __asm __volatile (
  349         "       lock ;                  "
  350         "       cmpxchgl %1,%2 ;        "
  351         "       setz    %%al ;          "
  352         "       movzbl  %%al,%0 ;       "
  353         "1:                             "
  354         "# atomic_cmpset_int"
  355         : "+a" (res)                    /* 0 (result) */
  356         : "r" (src),                    /* 1 */
  357           "m" (*(dst))                  /* 2 */
  358         : "memory");                             
  359 
  360         return (res);
  361 }
  362 #endif
  363 
  364 static __inline atomic_t
  365 test_and_set_bit(int b, volatile void *p)
  366 {
  367         int s = splhigh();
  368         unsigned int m = 1<<b;
  369         unsigned int r = *(volatile int *)p & m;
  370         *(volatile int *)p |= m;
  371         splx(s);
  372         return r;
  373 }
  374 
  375 static __inline void
  376 clear_bit(int b, volatile void *p)
  377 {
  378     atomic_clear_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f));
  379 }
  380 
  381 static __inline void
  382 set_bit(int b, volatile void *p)
  383 {
  384     atomic_set_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f));
  385 }
  386 
  387 static __inline int
  388 test_bit(int b, volatile void *p)
  389 {
  390     return ((volatile int *)p)[b >> 5] & (1 << (b & 0x1f));
  391 }
  392 
  393 static __inline int
  394 find_first_zero_bit(volatile void *p, int max)
  395 {
  396     int b;
  397 
  398     for (b = 0; b < max; b += 32) {
  399         if (((volatile int *)p)[b >> 5] != ~0) {
  400             for (;;) {
  401                 if ((((volatile int *)p)[b >> 5] & (1 << (b & 0x1f))) == 0)
  402                     return b;
  403                 b++;
  404             }
  405         }
  406     }
  407     return max;
  408 }
  409 
  410 #define spldrm()                spltty()
  411 
  412 /*
  413  * Fake out the module macros for versions of FreeBSD where they don't
  414  * exist.
  415  */
  416 #if (__FreeBSD_version < 500002 && __FreeBSD_version > 500000) || __FreeBSD_version < 420000
  417 #define MODULE_VERSION(a,b)             struct __hack
  418 #define MODULE_DEPEND(a,b,c,d,e)        struct __hack
  419 #endif
  420 
  421 /* Redefinitions to make templating easy */
  422 #define wait_queue_head_t       atomic_t
  423 #define agp_memory              void
  424 #define jiffies                 ticks
  425 
  426                                 /* Macros to make printf easier */
  427 #define DRM_ERROR(fmt, arg...) \
  428         printf("error: [" DRM_NAME ":pid%d:%s] *ERROR* " fmt,           \
  429             DRM_CURRENTPID, __func__ , ## arg)
  430 
  431 #define DRM_MEM_ERROR(area, fmt, arg...) \
  432         printf("error: [" DRM_NAME ":pid%d:%s:%s] *ERROR* " fmt,        \
  433             DRM_CURRENTPID , __func__, DRM(mem_stats)[area].name , ##arg)
  434 
  435 #define DRM_INFO(fmt, arg...)  printf("info: [" DRM_NAME "] " fmt , ## arg)
  436 
  437 #if DRM_DEBUG_CODE
  438 #define DRM_DEBUG(fmt, arg...)                                          \
  439         do {                                                            \
  440                 if (DRM(flags) & DRM_FLAG_DEBUG)                        \
  441                         printf("[" DRM_NAME ":pid%d:%s] " fmt,          \
  442                             DRM_CURRENTPID, __func__ , ## arg);         \
  443         } while (0)
  444 #else
  445 #define DRM_DEBUG(fmt, arg...)           do { } while (0)
  446 #endif
  447 
  448 #if (__FreeBSD_version >= 500000) || ((__FreeBSD_version < 500000) && (__FreeBSD_version >= 410002))
  449 #define DRM_SYSCTL_HANDLER_ARGS (SYSCTL_HANDLER_ARGS)
  450 #else
  451 #define DRM_SYSCTL_HANDLER_ARGS SYSCTL_HANDLER_ARGS
  452 #endif
  453 
  454 #define DRM_FIND_MAP(dest, o)                                           \
  455         do {                                                            \
  456                 drm_map_list_entry_t *listentry;                        \
  457                 TAILQ_FOREACH(listentry, dev->maplist, link) {          \
  458                         if ( listentry->map->offset == o ) {            \
  459                                 dest = listentry->map;                  \
  460                                 break;                                  \
  461                         }                                               \
  462                 }                                                       \
  463         } while (0)
  464 
  465 
  466 /* Internal functions */
  467 
  468 /* drm_drv.h */
  469 extern d_ioctl_t        DRM(ioctl);
  470 extern d_open_t         DRM(open);
  471 extern d_close_t        DRM(close);
  472 extern d_read_t         DRM(read);
  473 extern d_poll_t         DRM(poll);
  474 extern d_mmap_t         DRM(mmap);
  475 extern int              DRM(open_helper)(struct cdev *kdev, int flags, int fmt, 
  476                                          DRM_STRUCTPROC *p, drm_device_t *dev);
  477 extern drm_file_t       *DRM(find_file_by_proc)(drm_device_t *dev, 
  478                                          DRM_STRUCTPROC *p);
  479 
  480 /* sysctl support (drm_sysctl.h) */
  481 extern int              DRM(sysctl_init)(drm_device_t *dev);
  482 extern int              DRM(sysctl_cleanup)(drm_device_t *dev);
  483 
  484 /* Memory info sysctl (drm_memory_debug.h) */
  485 #ifdef DEBUG_MEMORY
  486 extern int              DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS;
  487 #endif

Cache object: c08f231b65f1fa5be0c8aa44ffe2be74


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.