devmap(9e) 맨 페이지 - 윈디하나의 솔라나라

개요

섹션
맨 페이지 이름
검색(S)

devmap(9e)

devmap(9E)                    Driver Entry Points                   devmap(9E)



NAME
       devmap  -  validate  and  translate  virtual  mapping for memory mapped
       device

SYNOPSIS
       #include <sys/ddi.h>
       #include <sys/sunddi.h>

       int prefixdevmap(dev_t dev, devmap_cookie_t dhp, offset_t off,
            size_t len, size_t *maplen, uint_t model);

INTERFACE LEVEL
       Solaris DDI specific (Solaris DDI).

PARAMETERS
       dev       Device whose memory is to be mapped.


       dhp       An opaque mapping handle that the system uses to describe the
                 mapping.


       off       User  offset  within  the  logical device memory at which the
                 mapping begins.


       len       Length (in bytes) of the mapping to be mapped.


       maplen    Pointer to length (in bytes) of mapping that has  been  vali‐
                 dated. maplen is less than or equal to len.


       model     The data model type of the current thread.


DESCRIPTION
       devmap()  is  a  required  entry point for character drivers supporting
       memory-mapped devices if the drivers use the devmap framework to set up
       the  mapping. A memory mapped device has memory that can be mapped into
       a process's address space. The mmap(2) system call, when applied  to  a
       character  special  file,  allows  this device memory to be mapped into
       user space for direct access by the user applications.


       As a result of a mmap(2) system call, the  system  calls  the  devmap()
       entry  point  during  the  mapping  setup  when  D_DEVMAP is set in the
       cb_flag field of the cb_ops(9S) structure, and  any  of  the  following
       conditions apply:

           o      ddi_devmap_segmap(9F) is used as the segmap(9E) entry point.


           o      segmap(9E) entry point is set to NULL.


           o      mmap(9E) entry point is set to NULL.



       Otherwise EINVAL will be returned to mmap(2).


       When  the MAP_ALIGN flag is set, the system is informed that the align‐
       ment of pa must be the same as addr. The alignment value in  addr  must
       be  0  or  some  power  of  two  multiple  of  page size as returned by
       sysconf(3C). If addr is 0, the system will choose a suitable alignment.


       Device drivers should use devmap() to validate the user mappings to the
       device,  to  translate  the  logical  offset, off, to the corresponding
       physical offset within the device address space, and to pass  the  map‐
       ping information to the system for setting up the mapping.


       dhp  is a device mapping handle that the system uses to describe a map‐
       ping to a memory that is either contiguous in physical address space or
       in kernel virtual address space. The system may create multiple mapping
       handles in one mmap(2) system call (for example, if  the  mapping  con‐
       tains multiple physically discontiguous memory regions).


       model  returns  the  C  Language  Type  Model  which the current thread
       expects. It is set to DDI_MODEL_ILP32 if  the  current  thread  expects
       32-bit  (  ILP32)  semantics,  or  DDI_MODEL_LP64 if the current thread
       expects 64-bit ( LP64) semantics. model is  used  in  combination  with
       ddi_model_convert_from(9F)  to  determine whether there is a data model
       mismatch between the current thread and the device driver.  The  device
       driver might have to adjust the shape of data structures before export‐
       ing them to a user thread which supports a different data model.


       devmap() should return EINVAL if the logical offset, off, is out of the
       range  of  memory  exported  by  the device to user space. If off + len
       exceeds the range of the contiguous memory, devmap() should return  the
       length  from off to the end of the contiguous memory region. The system
       will repeatedly call devmap() until the original mapping length is sat‐
       isfied.  The  driver sets *maplen to the validated length which must be
       either less than or equal to len.


       The devmap() entry point must initialize the mapping parameters  before
       passing  them  to the system through either devmap_devmem_setup(9F) (if
       the memory being mapped is device memory) or devmap_umem_setup(9F)  (if
       the  memory  being  mapped  is kernel memory). The devmap() entry point
       initializes the mapping parameters  by  mapping  the  control  callback
       structure  (see devmap_callback_ctl(9S)), the device access attributes,
       mapping length,  maximum  protection  possible  for  the  mapping,  and
       optional     mapping    flags.    See    devmap_devmem_setup(9F)    and
       devmap_umem_setup(9F) for further information on initializing the  map‐
       ping parameters.


       The system will copy the driver's devmap_callback_ctl(9S) data into its
       private memory so the drivers do not need to keep  the  data  structure
       after    the    return    from    either   devmap_devmem_setup(9F)   or
       devmap_umem_setup(9F).


       For device mappings, the system establishes the mapping to the physical
       address  that corresponds to off by passing the register number and the
       offset within the register address space to devmap_devmem_setup(9F).


       For kernel memory mapping, the system selects a  user  virtual  address
       that  is  aligned with the kernel address being mapped for cache coher‐
       ence.

RETURN VALUES
       0           Successful completion.


       Non-zero    An error occurred.


EXAMPLES
       Example 1 Implementing the devmap() Entry Point



       The following is an example of  the  implementation  for  the  devmap()
       entry    point.    For    mapping   device   memory,   devmap()   calls
       devmap_devmem_setup(9F) with the register number, rnumber, and the off‐
       set  within  the  register, roff. For mapping kernel memory, the driver
       must first allocate the kernel  memory  using  ddi_umem_alloc(9F).  For
       example,  ddi_umem_alloc(9F)  can  be called in the attach(9E) routine.
       The resulting kernel memory cookie is stored in the driver  soft  state
       structure,  which  is  accessible  from  the  devmap() entry point. See
       ddi_soft_state(9F).  devmap()   passes   the   cookie   obtained   from
       ddi_umem_alloc(9F) and the offset within the allocated kernel memory to
       devmap_umem_setup(9F). The corresponding ddi_umem_free(9F) can be  made
       in the detach(9E) routine to free up the kernel memory.




         ...
         #define MAPPING_SIZE 0x2000        /* size of the mapping */
         #define MAPPING_START 0x70000000   /* logical offset at beginning
                                               of the mapping */
         static
         struct devmap_callback_ctl xxmap_ops = {
                 DEVMAP_OPS_REV,                /* devmap_ops version number */
                 xxmap_map,                     /* devmap_ops map routine */
                 xxmap_access,                  /* devmap_ops access routine */
                 xxmap_dup,                     /* devmap_ops dup routine */
                 xxmap_unmap,                   /* devmap_ops unmap routine  */
         };


         static int
         xxdevmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len,
            size_t *maplen, uint_t model)
         {
            int    instance;
            struct xxstate *xsp;
            struct ddi_device_acc_attr *endian_attr;
            struct devmap_callback_ctl *callbackops = NULL;
            ddi_umem_cookie_t cookie;
            dev_info_t *dip;
            offset_t   roff;
            offset_t   koff;
            uint_t rnumber;
            uint_t maxprot;
            uint_t flags = 0;
            size_t length;
            int    err;

            /* get device soft state */
            instance = getminor(dev);
            xsp = ddi_get_soft_state(statep, instance);
            if (xsp == NULL)
               return (-1);

            dip = xsp->dip;
            /* check for a valid offset */
            if ( off is invalid )
               return (-1);
            /* check if len is within the range of contiguous memory */
            if ( (off + len) is contiguous.)
                length = len;
            else
                length = MAPPING_START + MAPPING_SIZE - off;

            /* device access attributes */
            endian_attr = xsp->endian_attr;

            if (  off is referring to a device memory.  ) {
                                          /* assign register related parameters */
               rnumber = XXX;             /* index to register set at off */
               roff = XXX;                /* offset of rnumber at local bus */
               callbackops = &xxmap_ops;  /* do all callbacks for this mapping */
               maxprot = PROT_ALL;        /* allowing all access */
               if ((err = devmap_devmem_setup(dhp, dip, callbackops, rnumber, roff,
                        length, maxprot, flags, endian_attr)) < 0)


                   return (err);

            } else if ( off is referring to a kernel memory.) {
               cookie = xsp->cookie;      /* cookie is obtained from
                                             ddi_umem_alloc(9F) */
               koff = XXX;                /* offset within the kernel memory. */
               callbackops = NULL;        /* don't do callback for this mapping */
               maxprot = PROT_ALL;        /* allowing all access */
               if ((err = devmap_umem_setup(dhp, dip, callbackops, cookie, koff,
                        length, maxprot, flags, endian_attr)) < 0)
                  return (err);
           }

                  *maplen = length;
             return (0);
         }



SEE ALSO
       mmap(2),      attach(9E),     detach(9E),     mmap(9E),     segmap(9E),
       ddi_devmap_segmap(9F), ddi_model_convert_from(9F),  ddi_soft_state(9F),
       ddi_umem_alloc(9F),     ddi_umem_free(9F),     devmap_devmem_setup(9F),
       devmap_setup(9F),   devmap_umem_setup(9F),   cb_ops(9S),   devmap_call‐
       back_ctl(9S)


       Writing Device Drivers in Oracle Solaris 11.4



Oracle Solaris 11.4              04 July 2017                       devmap(9E)
맨 페이지 내용의 저작권은 맨 페이지 작성자에게 있습니다.
RSS ATOM XHTML 5 CSS3