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/kernel/system/do_segctl.c

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 /* The kernel call implemented in this file:
    2  *   m_type:    SYS_SEGCTL
    3  *
    4  * The parameters for this kernel call are:
    5  *    m4_l3:    SEG_PHYS        (physical base address)
    6  *    m4_l4:    SEG_SIZE        (size of segment)
    7  *    m4_l1:    SEG_SELECT      (return segment selector here)
    8  *    m4_l2:    SEG_OFFSET      (return offset within segment here)
    9  *    m4_l5:    SEG_INDEX       (return index into remote memory map here)
   10  */
   11 #include "../system.h"
   12 #include "../protect.h"
   13 
   14 #if USE_SEGCTL
   15 
   16 /*===========================================================================*
   17  *                              do_segctl                                    *
   18  *===========================================================================*/
   19 PUBLIC int do_segctl(m_ptr)
   20 register message *m_ptr;        /* pointer to request message */
   21 {
   22 /* Return a segment selector and offset that can be used to reach a physical
   23  * address, for use by a driver doing memory I/O in the A0000 - DFFFF range.
   24  */
   25   u16_t selector;
   26   vir_bytes offset;
   27   int i, index;
   28   register struct proc *rp;
   29   phys_bytes phys = (phys_bytes) m_ptr->SEG_PHYS;
   30   vir_bytes size = (vir_bytes) m_ptr->SEG_SIZE;
   31   int result;
   32 
   33   /* First check if there is a slot available for this segment. */
   34   rp = proc_addr(m_ptr->m_source);
   35   index = -1;
   36   for (i=0; i < NR_REMOTE_SEGS; i++) {
   37       if (! rp->p_priv->s_farmem[i].in_use) {
   38           index = i; 
   39           rp->p_priv->s_farmem[i].in_use = TRUE;
   40           rp->p_priv->s_farmem[i].mem_phys = phys;
   41           rp->p_priv->s_farmem[i].mem_len = size;
   42           break;
   43       }
   44   }
   45   if (index < 0) return(ENOSPC);
   46 
   47   if (! machine.protected) {
   48       selector = phys / HCLICK_SIZE;
   49       offset = phys % HCLICK_SIZE;
   50       result = OK;
   51   } else {
   52       /* Check if the segment size can be recorded in bytes, that is, check
   53        * if descriptor's limit field can delimited the allowed memory region
   54        * precisely. This works up to 1MB. If the size is larger, 4K pages
   55        * instead of bytes are used.
   56        */
   57       if (size < BYTE_GRAN_MAX) {
   58           init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys, size, 
   59                 USER_PRIVILEGE);
   60           selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
   61           offset = 0;
   62           result = OK;
   63       } else {
   64           init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys & ~0xFFFF, 0, 
   65                 USER_PRIVILEGE);
   66           selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
   67           offset = phys & 0xFFFF;
   68           result = OK;
   69       }
   70   }
   71 
   72   /* Request successfully done. Now return the result. */
   73   m_ptr->SEG_INDEX = index | REMOTE_SEG;
   74   m_ptr->SEG_SELECT = selector;
   75   m_ptr->SEG_OFFSET = offset;
   76   return(result);
   77 }
   78 
   79 #endif /* USE_SEGCTL */
   80 

Cache object: a333b4e5d13c87583357445266c32ef9


[ 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.