Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

iconnect(2)

eti_map(3C)

spin_init(2)



spl_request(3C)                                   spl_request(3C)



NAME
     spl_map, spl_request, spl_unmap, spl_request_macro - system
     interrupt priority level controls

SYNOPSIS
     #include <sys/types.h>
     #include <ml/spl.h>

     caddr_t spl_map (addr)
     caddr_t addr;

     int spl_unmap (addr)
     caddr_t addr;

     void spl_request (value, addr)
     u_int value;
     caddr_t addr;

     spl_request_macro (value, addr, pv)
     u_int val;
     caddr_t addr;
     u_int pv;


DESCRIPTION
     The system interrupt priority level, ipl, may be modified
     from user-level, by using this set of spl library routines.
     This is accomplished by binding the physical address of the
     system interrupt priority register into the address space of
     the process, and then writing directly to this hardware
     register from the process's address space.

     By raising a cpu's ipl from the normal user-level value of
     zero, a process may hold out certain interrupts.  For exam-
     ple, by raising the ipl to SPL4, a process holds out all VME
     level 4 interrupts, which would prevent level 4 VME devices
     from interrupting the process's cpu.

     The spl_map() routine binds the physical address of the ipl
     register into the address space of the process and returns
     the resulting virtual address of the interrupt priority
     register.  This is accomplished by creating a shared memory
     region.  The addr parameter is a virtual address where the
     caller wishes the shared memory region to be attached.  If
     addr is zero, the system will pick the virtual address.  If
     addr is not zero, then spl_map() will attempt to attach the
     shared memory region at the specified address, automatically
     rounding the addr value to a SHMLBA boundary.

     Certain library routines, such as those contained in a
     user-level device driver, may make spl_map() calls in addi-
     tion to spl_map() calls made by the non-library code portion



Page 1                        CX/UX Programmer's Reference Manual





spl_request(3C)                                   spl_request(3C)



     of the program.  Therefore, if a process makes more than one
     call to spl_map() before making a spl_umap() call, an
     attempt will be made to use the previously bound spl shared
     memory region.  In this case, spl_map() will simply incre-
     ment an internal reference count and return the previously
     bound virtual address.  However, if an addr parameter is
     specified on an additional spl_map() call and the address
     does not match the previously bound spl region's address, an
     error wil be returned.

     The spl_request() routine sets the ipl to the specified
     interrupt priority level.  The value parameter should be an
     ipl value that is defined in the <ml/spl.h> include file.
     The addr parameter should be the virtual address value that
     was returned from a previous spl_map() call. spl_request()
     returns the previous ipl value; that is, the value of the
     ipl register before it was modified to the caller's speci-
     fied value.

     The spl_request_macro() macro is provided as a faster method
     for modifying the ipl register.  The value and addr parame-
     ters should contain the same information as the
     spl_request() routine.  The pv parameter should be an u_int
     variable where the previous ipl value will be returned.
     (The pv parameter should always be supplied.)  This macro is
     only available to C language programs and is not available
     to Fortran or Ada programs.

     The spl_unmap() routine is provided to detach the shared
     memory region from the process.  The addr parameter is the
     virtual address returned from the previous spl_map() routine
     call.  (The spl shared memory region will be automatically
     detached when a process terminates, or issues one of the
     exec(2) system service calls.)

     If the process has made multiple calls to spl_map() before
     calling spl_unmap(), the spl region will not actually be
     detached until the corresonding number of spl_unmap() calls
     have been made.


NOTES
     These routines would normally be used to coordinate shared
     data accesses between user-level processes and user-level
     interrupt routine(s).  (See iconnect(2) for more information
     on user-level interrupt routines).  By raising the ipl up to
     or higher than the interrupt priority level of the user-
     level interrupt routine's external interrupt, the user-level
     proces may then be assured that it may execute on it's cpu
     without being interrupted by its corresponding user-level
     interrupt routine process.




Page 2                        CX/UX Programmer's Reference Manual





spl_request(3C)                                   spl_request(3C)



     On multiprocessor systems, an additional user-level spin
     lock should be used, to provide synchronization to shared
     data among multiple cpus.  The spin_init(2),
     spin_trylock(2), spin_islock(2), spin_unlock(2) set of ser-
     vices are recommended for this purpose.  See this man page
     for more information on using these services.

     For example, on a multiprocessor system, a user-level pro-
     cess that shares data with a user-level interrupt process
     that needs to synchronize its access to this data would do
     so by:

          Raising ipl to the appropriate level.

          Locking the user defined spin lock.

          Accessing or modifying the shared data.

          Unlocking the user defined spin lock.

          Lowering ipl to zero.

     The corresponding user-level interrupt routine process would
     access this same data by:

          Locking the user defined spin lock

          Accessing or modifying the shared data.

          Unlocking the user defined spin lock.


RESTRICTIONS
     A process must be super-user, or must have the ACC_SHMBIND
     access vector bit set in order to use the spl_map() routine.

     During the time that a process has raised ipl until it has
     lowered ipl back to zero, the process should not:

          Make any system service calls.

          Reference any memory location that will result in a
          system page fault.  It is highly recommended that the
          process lock down its entire address space if it
          intends to use the spl_request() routine.

          Set any debugger breakpoints, or single-step in any
          section of code where ipl has been set above zero.

     It is recommended that a process not raise ipl above zero
     for any length of time.




Page 3                        CX/UX Programmer's Reference Manual





spl_request(3C)                                   spl_request(3C)



WARNINGS
     A user-level process (not a user-level interrupt routine
     process) that raises ipl should ALWAYS reset the ipl back to
     zero.

     If a user-level interrupt routine temporarily raises ipl, it
     should not set the ipl back to zero, but it should restore
     the ipl value back to what it was when it entered the user-
     level interrupt routine.  This should be the value that was
     returned on the initial spl_request() call.  See iconnect(2)
     for more information on user-level interrupt routines.

RETURN VALUE
     For spl_map() routine calls, upon successful completion, the
     virtual address of the ipl register is returned.  For
     spl_unmap() routine calls, upon successful completion, a
     value of zero is returned. Otherwise, for both of these
     calls, a value of -1 is returned and errno is set to indi-
     cate the error.

     The spl_request() routine returns no error status.

ERRORS
     If any of the following conditions is detected, spl_map()
     will return -1 and set errno to the following value:

     [EACCES]       The caller is not super-user, or does not
                    have the ACC_SHMBIND access vector bit set
                    (if access vectors are configured).

     [EINVAL]       The addr parameter is not a valid shared
                    memory segment value.

     [EBUSY]        The process has previously called spl_map(),
                    and the current addr parameter that was
                    specified does not match the previous bind
                    address.  The proces must first call
                    spl_unmap() before binding the spl shared
                    memory region to a new virtual address.

     [EMFILE]       The number of shared memory segments attached
                    to the calling process would exceed the
                    system-imposed limit.

     [ENOSPC]       The spl shared memory identifier is to be
                    created, but the system-imposed limit on the
                    maximum number of allowed system-wide shared
                    memory identifiers would be exceeded.

     If the following condition is detected, spl_unmap() will
     return -1 and set errno to the following value:




Page 4                        CX/UX Programmer's Reference Manual





spl_request(3C)                                   spl_request(3C)



     [EINVAL]       The specified addr parameter was not a valid
                    segment start address of the ipl shared
                    memory segment.

SEE ALSO
     iconnect(2), eti_map(3C), spin_init(2)

















































Page 5                        CX/UX Programmer's Reference Manual



Typewritten Software • bear@typewritten.org • Edmonds, WA 98026