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

개요

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

devmap(9e)

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

NAME
       devmap  -  validate and translate virtual mapping for memory mapped de‐
       vice

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

       int prefix_devmap(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() en‐
       try 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 ex‐
       pects. It is set to  DDI_MODEL_ILP32  if  the  current  thread  expects
       32-bit  (ILP32)  semantics, or DDI_MODEL_LP64 if the current thread ex‐
       pects 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 ex‐
       ceeds 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 op‐
       tional    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() en‐
       try   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 ex‐
       ample, 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_callback_ctl(9S)


       Writing Device Drivers in Oracle Solaris 11.4

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