EPICURE Software Release Note 137.2<P> <b> VMS System Services for TVI Support</b>

EPICURE Software Release Note 137.2

VMS System Services for TVI Support

David M. Kline

This document shows the calling sequences for the TVI routines on the 80386 DAE processors with C as well as for use on the VAX under VMS. In addition, several VME Common Memory structures are outlined. See Epicure Design Note #6 for more information on Common Memory data structures and formats. Many similarities exist between the TURBOchannel and the QBus interfaces . Therefore, the release note was based on Epicure Design Note #3. Where applicable, text and data structure formats have been modified to accommodate the TURBOchannel interface. However, most of the document's content and structure remain similar to the design note. The reader is encouraged to review Epicure design note #126 for a complete description of the design and intention of the TURBOchannel interface and implementation.

Introduction

The data sources for the EPICURE system are the VS4000/60 Front End and the VME-based Data Acquisition Engines (DAE). The VAX is interfaced to the VME crate by the TURBOchannel/VME Interface (TVI) which allows VME address space to appear as if it were VAX memory. The VAX and DAE processors communicate via the Common Memory (CM) area in a VME memory module. All communication between the VAX and the DAE and between DAE modules is done by passing messages using queues in the CM. A set of user-written VMS system services supports access to the CM from the VAX. A smaller set of routines provides support for the DAE processors to manipulate information in the Common Memory. These various services are required due to:

The TVI services provide a means of encapsulating these needs and presenting a simpler interface to the Data Acquisition Server (DAS), the primary user of the TVI services. Transparency between QVI and TVI system services is maintained by related services residing at the same transfer address within the shareable image. The CM routines for the DAE processors provide a simple interface to the programmers and implement the same queue handling protocol as the TVI services. Similarly, 80386 DAE processors residing on QBus or TURBOchannel front ends maintain transparency by using indicators (flags) in the VAX return queue headers which select the means by which interrupts are generated.

The TURBOchannel Allocator (TCA) device driver was developed to manage TURBOchannel interface resources. A set of system services is available to hide the complexities associated with manipulating resources.

A special device driver on the VAX, the , is needed for handling the fielding of interrupts from the TURBOchannel interface. This driver was derived from the Digital Connect-to-Interrupt driver and the Epicure and is specifically designed to handle the TURBOchannel the DWTVX interface.

Descriptions of the TVI and CM Services

The TVI services are similar to the VMS system services. All the routines are functions returning a 32-bit VMS condition code as a status (with one exception). Scalar input arguments are passed by value; output or modified (read-write) arguments and input arrays are passed by reference (except as noted). The TVI services are divided into several classes and are described below:

TVI_US
These user services are meant for most users.
TVI_CS
The TVI Core Services are meant for special and diagnostic applications.
TVI_ES
These are Extended Services which are only available for the TURBOchannel interface.
TCA_CS
These are the Core Services used by the TVI_CS to allocate, load, and release TURBOchannel interface resources .
TCI_US
These User Services are used by other TVI services to establish connectivity between the VAX return queue device and a VAX process.

Service routines for the DAE processors are based on a simple subset of the TVI_US routines called the CM (for Common Memory) routines. The CM routines return VMS status codes to indicate success or failure; input arguments are passed by value and output arguments have a pointer passed by value (standard C calling sequences). Furthermore, these routines are implemented to work for both QVI and TVI front ends.

Common Memory queues and blocks are referenced by ``handles'' which are either offsets relative to the start of the Common Memory or addresses within the Common Memory as mapped into the local process's virtual address space (VAS). In particular, the actual interpretation of the ``handles'' returned by the TVI_US routines is unimportant to the users of the TVI_US routines. This does not hold true for the TVI_CS routines where the documentation specifies whether a particular ``handle'' is an actual address or an offset. The CM routines use 32-bit VMEbus addresses for Common Memory structures (normal startup of the 80386 DAE processors must setup for a 4 Gigabyte linear address space).

Common Memory Block Format

The Common Memory block which is entered or removed from a CM queue is called a CMB (for Common Memory Block). The CMB consists of two concatenated structures: the UMB contains the fields of importance to users, the CMH is the Common Memory Header containing information used only by the TVI services and the DAE modules. The format of a CM block which is entered or removed from a CM queue is:

This structure is called a CMB for Common Memory Block. The CMB consists of two concatenated structures: the UMB contains the fields of importance to users, the CMH is the Common Memory Header containing information used only by the TVI services and the DAE modules. The fields of the UMB and CMH which are common to all types of CMBs are: list [cmb_r_cmh] This structure contains the header fields of the CMB: list [cmh_l_link] This longword is the queue link. It contains a pointer to the next entry in the queue or a 0 if this is the tail entry. Normally this field is only of concern to the TVI and CM routines. [cmh_l_rtnqid] This longword is set to the queue handle (qhdl) for the VAX return queue associated with the user process. The return qhdl is used to return the CMB to the originator upon completion of the actions requested by the CMB contents. [cmh_l_orgid] This longword contains the same value as the rtnqid longword for normal return queues. Such queues are normally associated with an interrupt attached to the destination process on the VAX or are polled by that process. If the return queue used is the multiplexed return queue, then the value in this longword is used by the process to locate the true destination process and its return queue (see the information on the Queue Demultiplexing Block below). [cmh_l_diqhdl] This longword contains the handle of the DAE input queue. The TVI_US_GET routine uses this field to route the CM block to its destination queue if it is to be recycled. The queue handle is taken from the QIB which specifies the default DAE input queue. Applications can override the default queue by specifying the altdiq parameter of the TVI_US_PUT routine.

[cmb_r_umb] This structure is the portion of the CMB manipulated by the user of the TVI or CM services. The fields of the UMB are: list [umb_l_flags] This is a bit-vector of flags in a longword. The lowest bit (bit 0) is used as the CYCLE bit. If this bit is 1, when the CMB is removed from the VAX return queue it is placed back on the default processing queue rather than released to the free queue (cycled for another processing pass).

Bit 1 is used by the DAE processors as the first time flag ( 1ST_TIME). This flag is used by the DAE Timer processor on cyclic requests to flag the first cycle (or the first time that the Timer has seen this request).

Bits 2-4 are used by the DAE Timer processor to support fast time plot control and data buffer processing and expunges. [umb_w_type] This word contains an identification code describing the data contents of this UMB and is of direct concern to the users of the TVI and CM routines. [umb_w_reqsiz] This word contains the requested UMB size in bytes. This may not be the actual size of the UMB (or enclosing CMB); there may be unused bytes (internal fragmentation) between the end of the data and the actual end of the UMB. [umb_r_data] This is the start of the data field of the UMB. The format and contents of this portion of the UMB are specific to the block type defined by the Common Memory user. The cmh_l_rtnqid field is sometimes of concern to the DAE programmer. This field identifies the return queue of the ``originator'' of the message and is sometimes used if the request is fatally flawed and cannot be processed. In this case, the return queue identifier is used to route the request immediately back to the originator, usually with the CYCLE bit cleared and a error status someplace in the data fields.

CMB Structure Definitions

There C structure definitions reflect those in (see below). The definition of the UMB0 structure is given here as a prototype definition for the user block. Common Memory users should supply their own definitions, replacing the umb_r_data field with definitions specific to their applications.

struct CMH {
    unsigned long cmh_l_link;
    unsigned long cmh_l_rtnqid;
    unsigned long cmh_l_orgid;
    unsigned long cmh_l_diqhdl;
    };

struct UMB0 {        /* Prototypical definition */
    unsigned long umb_l_flags;
    unsigned short umb_w_type;
    unsigned short umb_w_reqsiz;
    unsigned long umb_r_data[2];
    };
  
#define  UMB_M_CYCLE     0X00000001
#define  UMB_M_1ST_TIME  0X00000002
#define  UMB_M_SUSPEND   0X00000004
#define  UMB_M_AVAILABLE 0X00000008
#define  UMB_M_EXPNDG    0X00000010
struct CMB {
    struct CMH cmb_r_cmh;
    struct UMB0 cmb_r_umb;
    };

Multicast Block Format

Provision is made for a special form of a UMB for ``multicast'' messages which are routed to all the DAE processors for which entries appear in the Queues Table. This special UMB is constructed by the DAP$MULTICAST routines (see below); the TVI user provides a block type and up to 4 longwords of multicast parameters. The DAE programmer basically receives this like any other request but does have TVI-equivalent CM services for forwarding the multicast request to the next destination.

The multicast message is sent to the first DAE processor with a non-zero Queue Table entry. The Queue Table Index (QTI) for this entry is stored in the multicast message. Each destination picks up the current QTI from the multicast message and begins searching the Queue Table from that point forward (towards the end of the Queue Table) for the next non-zero entry which will be the next destination of the multicast message. When the end of the Queue Table is reached, the multicast message is returned via the return queue handle in the CMB header.

Locating the TVI Files and Linking With the TVI Services

The TVI code is stored under the project of the . The procedure in area of defines the logical names and which specify the current locations of the TVI include files (except for those which are stored under the logical name ) and the shareable image. The files include: list [CMDEF.H] Contains definitions for the Common Memory structures for VAX and 80386 C programs. Stored in . [CMDEF.S] Public Common Memory definitions for 68020 assembly code modules ( obsolete). [MVMEIO.H] Definitions of TURBOchannel registers for both DWTVX and VBI modules. Stored in . [TVIMSG.A86] Definitions of the TVI status code constants (as symbols TVI__xxxx) for 80386 assembly language modules. [TVIMSG.H] Definitions of the TVI status code constants (as symbols TVI__xxxx) for C programs. Stored in . [TVIMSG.S] Definitions of the TVI status code constants for 68020 assembly code. [TVILINK.OPT] Options file for VAX Linker to link with the TVIUSS shareable image. Stored in .

The TVI routines in the shareable image can be linked to by adding to the command line:

    $ link  ...,tvi_inc:tvilink/options,...
This option file specifies that both the and the (VAX C Run Time Library shareable image in ) be linked to the image. Below shows its contents:
!
! Linker options file to link the TVI system services and
! VAX C RTL shareable images. Include general VAX-support
! routines in FERMILIB.
!
RDCS$LIB:FERMILIB/LIBRARY, -
EPICURE_ROOT:[WORK.TVI.USS]TVIUSS.EXE/SHARE,-
SYS$SHARE:VAXCRTL.EXE/SHARE

The TVI procedure also defines the logical name which specifies the current location of the object code files for the 80386 (file types ). The available files are: list [CMQLOCK] Contains the queue lock routines with the Test and Set instructions. Must be linked with all DAE system software. [CMQ] Contains the basic CM routines for manipulating the Common Memory queues. Must be linked with all DAE system software. [CMQGET] Contains the optional CM routines used if the DAE system will be generating unsolicited requests and so needs access to the free list queues. [CMQPOOL] Contains the optional CM data pool services for locating a Common Memory DataPool and locking or unlocking a DataPool.

VAX TVI User Services

Several ``combined'' service routines are defined to provide a simple interface to the DAE for the Data Acquisition Server (DAS) and other similar processes. The details of the Core Services are hidden within the US calls. In addition, the initialization routine provides for connecting to a interrupt-driven queue and receiving the interrupt notifications via event flags or ASTs.

TVI_US_DAP$LOCATE

status = TVI_US_DAP$LOCATE( qti, qhdl ) Locate a queue by its DAP queue index and return the queue handle. This routine is usually called once and the queue handle saved for later use in TVI_US_DAP$MULTICAST. qti DAP Queue Table index (unsigned byte, 0..255). Passed by value. qhdl queue handle returned in a longword. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__NOQUE fatal, queue not found TVI__NOTINIT fatal, TVI_US services not initialized

TVI_US_DAP$MULTICAST

status = TVI_US_DAP$MULTICAST( blktyp, mcpars, [cmbhdl] ) Allocate a free CM block and build a multicast UMB into this block. The first longword of the multicast UMB (after the standard UMB header) contains the Queue Table Index of the current queue; this is followed by 4 longwords of multicast parameters specified by the caller. This routine initializes the QTI longword to the first non-zero QTI entry. The CM block is then placed on the CM queue specified by that QTI entry. As each destination processes the multicast message, it advances the QTI longword to the next non-zero entry in the QTI table and passes the block on to that destination until all the QTI entries have been visited; after which the block is returned to the VAX by the return queue identifier found in the CM block header. blktyp Block type for the multicast UMB. Passed by value. mcpars Parameters for the multicast message. A block of 4 longwords (16 bytes) passed by reference. cmbhdl optional longword in which to return a pointer to the CMB allocated from the free list and filled with the multicast UMB contents. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__QTIEMPTY success, no multicast as QTI empty TVI__NOFREE error, no free CM blocks of the needed size are available TVI__QLCKFAI error, failed to acquire queue lock TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__NOTINIT fatal, TVI_US services not initialized

TVI_US_GET

status = TVI_US_GET( maxsize, umbbuf, [,blkhdl] ) Remove the CM block from the head of the VAX return queue specified in the TVI_US_INIT call and return the UMB contents from the CM block in the provided buffer. The CM block is either released to the free list or recycled depending on the value of the CYCLE flag. maxsize maximum expected UMB size. Passed by value. umbbuf address of a buffer in VAX memory to be filled with the contents of the UMB in the dequeued CM block. Passed by reference. blkhdl optional longword in which the block handle used to identify the dequeued CM block is returned. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__EMPTY warning, return queue was empty TVI__TRU warning, return block truncated as UMB too small TVI__QLCKFAI error, failed to acquire queue lock TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__NOTINIT fatal, TVI_US services not initialized others as returned by TVI_CS and VMS services

TVI_US_INIT

status = TVI_US_INIT( qname [,efn] [,ast] [,astprm] [,astcnt] ) Initialize the TVI_US services, including mapping all needed global sections which were created during the Common Memory initialization. The logical name RDCS$QVI_DAE_QUEUE is translated to provide the name of the CM queue to which messages are queued by TVI_US_PUT if no explicit target queue is given. This default queue is also used by TVI_US_GET for messages with the CYCLE flag set. The RDCS$QVI_WASTE_QUEUE logical name provides the name of the CM queue used as the ``toxic waste'' queue when inserts of ``defunct'' blocks onto the free lists fail. Also, the name of the CM return queue specified in the call is used to form the RDCS$QVI_VAXQ_name logical name which should translate to the VMS device to assign an I/O channel for the interrupt handling if either an event flag or an AST routine is specified in the call to this service. The RDCS$QVI_DEMUX_QUEUE logical name gives the name of the multiplexed CM queue to allow TVI user processes using that queue to specify it as the return queue. This is done automatically by TVI_US_INIT if the queue name specified in the call is marked as a multiplexed queue (MUX bit in the queue header). qname queue name to be used by this process as its VAX return queue. The queue name is a 1-8 character string passed by descriptor. efn Optional event flag number to be set when a block appears on the VAX return queue for processing. Passed by value. ast Optional address of an AST routine to be invoked when a block appears on the VAX return queue for processing. Passed by reference (address of the procedure's entry mask). astprm Optional parameter to be passed to the AST routine. Passed by value. astcnt Optional parameter specifying a count of AST blocks to be preallocated for handling rapid interrupts. Default value of 10 is used. Passed by value. status returns a VMS condition code: SS$_NORMAL success TVI__CMINIT fatal, CM not initialized TVI__MAPERR fatal, failed to map CM properly TVI__NOQUE fatal, queue named not found others as returned by TVI_CS and VMS services

TVI_US_LOCATE

status = TVI_US_LOCATE( qname, qhdl ) Locate a named queue and return its queue handle. This service is typically used once per queue and the resulting queue handle saved for later use with TVI_US_PUT. qname queue name to be located. The queue name is a 1-8 character string passed by descriptor. qhdl Queue handle returned in a longword. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__NOQUE fatal, queue named not found TVI__NOTINIT fatal, TVI_US services not initialized others as returned by TVI_CS and VMS services

TVI_US_MODFLG

status = TVI_US_MODFLG( blkhdl [,rmask] [,smask] ) Modify the flag bits of the specified CM block. This is normally used to clear the CYCLE flag before queuing a multicast EXPUNGE request for that CM block. The CM block handle must have been saved from a previous TVI_US_PUT call. blkhdl block handle used to identify the CM block whose flag bits are to be modified. Passed by value. rmask mask of those UMB_L_FLAGS bits to be reset (cleared to zero). Passed by value. smask mask of those UMB_L_FLAGS bits to be set (to one). Passed by value. status returns a VMS condition code: SS$_NORMAL success TVI__NOTORG error, not originator of CM block TVI__BADBHDL fatal, bad block handle TVI__NOTINIT fatal, TVI_US services not initialized others as returned by TVI_CS and VMS services

TVI_US_PUT

status = TVI_US_PUT( umbbuf [,toqhdl] [,blkhdl] [,altdiq] ) Allocate a block of CM and copy the UMB (User Memory Block) contents into the CM block from the VAX buffer. The CM block is then placed on the specified target CM queue. umbbuf address of a buffer in VAX memory to be copied into the UMB portion of the CM block. Passed by reference. The UMB size will be taken from the umb_w_reqsiz word in the VAX buffer. toqhdl optional queue handle of the target CM queue. Passed by value. If not specified (or specified as 0), then the block will be placed on the default DAE queue. This argument is the queue handle returned from a previous call to TVI_US_LOCATE. blkhdl optional longword in which the block handle used to identify the allocated CM block is returned. Passed by reference. altdiq optional queue handle of the CM queue which will receive the CM block if the CYCLE bit is set. Passed by value. If the parameter is not supplied or contains a value of zero, the CM block is directed towards the default DAE input queue as specified by the RDCS$QVI_DAE_QUEUE logical. This argument is the queue handle return from a previous call to TVI_US_LOCATE. status returns a VMS condition code: SS$_NORMAL success TVI__NOFREE error, no free CM blocks of the required size TVI__QLCKFAI error, failed to acquire queue lock TVI__BADQHDL fatal, bad queue handle TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__NOTINIT fatal, TVI_US services not initialized TVI__TOOBIG fatal, requested size exceeds that of the largest CM block others as returned by TVI_CS and VMS services

TVI_US_RESINM

status = TVI_US_RESINM( [efn] [,ast, astprm] ) This routine is called to reestablish the mechanism used to notify processes that an interrupt from the TURBOchannel adapter has been received. efn integer value of the event flag number set when an interrupt is received. Passed by value. ast address of the function to execute when an interrupt occurs. Passed by reference. astprm integer value passed to the AST routine if the ``ast'' parameter is specified. Passed by value. status returns a VMS condition code: SS$_NORMAL success SS$_BADPARAM fatal, bad parameter value FALSE error, services not initialized others as returned by VMS and $QIO services

TVI_US_TEST

status = TVI_US_TEST( [size] ) Test the VAX return queue (specified in the TVI_US_INIT call) to see if any entries are currently queued. size optional longword in which the size of the UMB in the CM block at the head of the queue is returned. Passed by reference. If the queue is empty, then zero is returned. status returns a VMS condition code: SS$_NORMAL success TVI__EMPTY warning, return queue was empty TVI__QLCKFAI error, failed to acquire queue lock TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__NOTINIT fatal, TVI_US services not initialized others as returned by TVI_CS and VMS services

TVI Core Services

The TVI Core Services (CS) are meant for direct use by the Common Memory initialization program and by diagnostics programs. In addition, several of the Core Services are used by the User-level Services (US routines) described above. In the US routines, queue headers and CM blocks are identified using ``handles'' which are meant to be transparent to the US users. In the CS routines, the handles are explicitly referred to as either offsets relative to the CM base or as addresses in the CM (in the local process's VAS). The CS routines locate the CM global section in the local VAS by the Common Memory Descriptor (cmdescr arguments in the routine descriptions). The CM Descriptor is a structure of 16 longwords (64 bytes) containing the base addresses (in the process's VAS) of the CM global section and other TVI-associated global sections along with other information needed by the TVI services. The US routines maintain a Common Memory descriptor in hidden static storage.

TVI_CS_CM2VAX

status = TVI_CS_CM2VAX( cmdescr, cmbptr, size, block ) Copy an array of longwords from a CM block into VAX memory. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. Passed by reference. cmbptr pointer to the CM block to be copied. Consider the pointer as passed by value or that the CM block itself is passed by reference (address of the CM block appears in the argument list). size Size of the longword array in bytes. Passed by value. block address of target VAX buffer to receive the longwords from the CM block. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__IVCMDS fatal, invalid CM descriptor TVI__BADBHDL fatal, bad block handle

TVI_CS_CREAA

status = TVI_CS_CREAA( cmdescr, blksiz, blkcnt, qptr, curcmo, aadptr ) Create a Common Memory allocation area. This routine is meant for use by the CM initialization program or by stand-alone diagnostics. cmdescr address of a CM descriptor returned by the TVI_CS_MAKECM routine. Passed by reference. blksiz size, in bytes, of the blocks in the allocation area being defined. The size must be less than 65,535. Passed by value. blkcnt number of blocks requested for the area (less may be defined if the end of the CM is reached first). Passed by value. qptr pointer to header of free list queue for the new allocation area. The free list queue is populated with all the blocks in the new area. Passed by value. curcmo current Common Memory offset on input, modified to reflect new value after the new allocation area has been setup. Passed by reference. aadptr returns the address of the Allocation Area Descriptor for the new allocation area. Passed by reference. status returns a VMS condition code: SS$_NORMAL success SS$_NOPRIV fatal, no privilege for the requested operation TVI__BADQHDL fatal, bad CM queue handle TVI__CMALRINI fatal, CM already completed initialization TVI__IVCMDS fatal, invalid CM descriptor TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__IVSIZE fatal, invalid CM block size TVI__OUTOFCM fatal, no free Allocation Area Descriptors remain This routine requires DIAGNOSE privilege to use.

TVI_CS_CREQH

status = TVI_CS_CREQH( cmdescr, qname, qptr ) Create and initialize a Common Memory queue header. This routine is meant for use by the Common Memory initialization program or by standalone diagnostics. cmdescr address of a CM descriptor returned by the TVI_CS_MAKECM routine. Passed by reference. qname queue name given as (up to 8) ASCII characters. Passed by fixed-length string descriptor. qptr pointer to the new queue header returned in a longword. Passed by reference. status returns a VMS condition code: SS$_NORMAL success SS$_NOPRIV fatal, no privilege for the requested operation TVI__CMALRINI fatal, CM already completed initialization TVI__IVCMDS fatal, invalid CM descriptor TVI__NOQUE fatal, no free queue headers left in CM This routine requires DIAGNOSE privilege to use.

TVI_CS_DAP$MULTICAST

status = TVI_CS_DAP$MULTICAST( cmdescr, qib, blktyp, mcpars, [cmbptr] ) Allocate a free CM block and build a multicast UMB into this block. The first longword of the multicast UMB (after the standard UMB header) contains the Queue Table Index of the current queue; this is followed by 4 longwords of multicast parameters specified by the caller. This routine initializes the QTI longword to the first non-zero QTI entry. The CM block is then placed on the CM queue specified by that QTI entry. As each destination processes the multicast message, it advances the QTI longword to the next non-zero entry in the QTI table and passes the block on to that destination until all the QTI entries have been visited; after which the block is returned to the VAX by the return queue identifier found in the CM block header. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. Passed by reference. qib Queues Information Block containing default DAE queue header pointer, free queue table and the DAP Queues Table. Passed by reference. blktyp Block type for the multicast UMB. Passed by value. mcpars Parameters for the multicast message. A block of 4 longwords (16 bytes) passed by reference. cmbptr optional longword in which to return a pointer to the CMB allocated from the free list and filled with the multicast UMB contents. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__QTIEMPTY success, no multicast as the DAP Queue Table is empty TVI__IVCMDS fatal, invalid CM descriptor TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__NOFREE error, no free CM blocks of the needed size are available TVI__QLCKFAI error, failed to acquire queue lock

TVI_CS_GET

status = TVI_CS_GET( cmdescr, qib, maxs, umbbuf, [qptr], [cmbptr] ) Remove the CM block from the head of the specified CM queue. If no explicit queue is specified, the VAX return queue specified in the Queues Information Block (QIB) is used. The contents of the UMB portion of the dequeued CM block (if any) are returned in the provided VAX UMB buffer. The CM block dequeued is either released to the CM free lists or recycled depending upon the UMB_M_CYCLE flag in the UMB header. A recycled CM block is placed on the DAE input queue as given in the CMH. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. Passed by reference. qib Queues Information Block containing the default return queue header pointer and free queue table. Passed by reference. maxs size of user data return buffer (in bytes). Passed by value. umbbuf buffer for user data returned from the CMB removed from the head of the queue. Passed by reference. qptr optional pointer to queue header from which to remove the head entry, default is the return queue pointed to in the QIB. Passed by value. cmbptr optional longword in which to return a pointer to the CMB dequeued. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__EMPTY warning, return queue was empty TVI__TRU warning, return block truncated TVI__BADQHDL fatal, bad queue handle TVI__IVCMDS fatal, invalid CM descriptor TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__IVSIZE fatal, invalid block size TVI__NOQUE fatal, no target or default queue given TVI__QLCKFAI error, failed to acquire queue lock

TVI_CS_INIT

status = TVI_CS_INIT( cmdescr ) Initializes the TVI control registers and creates the permanent global section which maps the TVI control registers. The pages of this global section are locked into the page tables to permit access at elevated IPLs. This service is meant for use by the Common Memory initialization program and by standalone diagnostics. cmdescr address of a 16 longword CM descriptor returned by this routine and used in other TVI_CS routines. Passed by reference. status returns a VMS condition code: SS$_NORMAL success SS$_NOPRIV fatal, no privilege for the requested operation TVI__MAPERR fatal, error mapping the TVI registers TVI__NOVMEPWR fatal, VME Bus is not powered others as returned by VMS services This routine requires SYSGBL, PRMGBL, PFNMAP and DIAGNOSE privileges to use.

TVI_CS_INSQT

status = TVI_CS_INSQT( cmdescr, cmbptr, qptr, genint ) Insert a Common Memory block onto the tail of a queue in the Common Memory. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. Passed by reference. cmbptr pointer to the CM block within the mapped CM section. Passed by value. qptr pointer to CM queue header on which to insert the CM block. Passed by value. genint interrupt generation control flag. If 1 then the interrupt associated with the queue is triggered. If 0, then the interrupt (if any) is not triggered. status returns a VMS condition code: SS$_NORMAL success TVI__IVCMDS fatal, invalid CM descriptor TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__BADBHDL fatal, bad block handle TVI__BADQHDL fatal, bad queue handle TVI__QLCKFAI fatal, failed to acquire queue lock

TVI_CS_INTERRUPT

status = TVI_CS_INTERRUPT( cmdescr, intno ) Generate an external mapped interrupt to a VME module using the VBI. The external mapped interrupts are generated by writing a mask of bits into a 32-bit control register in the VBI. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. The variant form of the CM descriptor returned by the TVI_CS_VMEWINDOW routine is also acceptable. Passed by reference. intno external interrupt number (0-11). Passed by value. status returns a VMS condition code: SS$_NORMAL success SS$_BADPARAM fatal, bad interrupt number TVI__IVCMDS fatal, invalid CM descriptor

TVI_CS_LOCATE

status = TVI_CS_LOCATE( cmdescr, qname, qptr ) Locate a Common Memory queue header. cmdescr address of a CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAP routine. Passed by reference. qname queue name given as (up to 8) ASCII characters. Passed by fixed-length string descriptor. qptr pointer to the new queue header returned in a longword. This is the address of the queue header in the CM as mapped into the process's virtual address space. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__IVCMDS fatal, invalid CM descriptor TVI__NOQUE fatal, no queue found

TVI_CS_LOCKCM

status = TVI_CS_LOCKCM( cmdescr ) Lock the Common Memory global section into the paging tables to permit access at elevated IPLs. This service is meant for use by the CM initialization program and by stand-alone diagnostics. Requires that TVI_CS_MAKECM have already been called. cmdescr address of a 16 longword CM descriptor which was returned by TVI_CS_MAKECM. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__IVCMDS fatal, invalid CM descriptor TVI__MAPERR fatal, not all of CM locked others as returned by VMS services This routine requires PSWAPM privilege to use.

TVI_CS_LOCKPOOL

status = TVI_CS_LOCKPOOL( cmdescr, poolno ) Lock specified DataPool against access by other processes or processors. cmdescr address of a CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAP routine. Passed by reference. poolno Common Memory DataPool selector number. Passed by value. status returns a VMS condition code: SS$_NORMAL success TVI__LOCKED warning, DataPool is already locked TVI__IVCMDS fatal, invalid CM descriptor TVI__BADPOOLNO fatal, bad data pool selector number

TVI_CS_MAKECM

status = TVI_CS_MAKECM( cmavme, cmsize, cmdescr ) Create and map the permanent global sections for the VMEbus Common Memory and Interrupter (VBI) module into the process's virtual address space. This service is meant for use by the CM initialization program. Requires that TVI_CS_INIT have been called previously. cmavme VME address of the base of the Common Memory module. Must be aligned on a TVI boundary (multiple of 128 KBytes). Passed by value. cmsize number of bytes of the Common Memory module to be used. Must be an integral number of Kbytes (an even number of VAX pages). Passed by value. cmdescr address of a 16 longword CM descriptor which was returned by TVI_CS_INIT and will be modified here. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__CMBASE fatal, CM base address not on TVI mapping boundary TVI__CMSIZEXC fatal, CM size exceeds QBus address space TVI__CMSIZODD fatal, CM size not even number of VAX pages TVI__IVCMDS fatal, invalid CM descriptor TVI__MAPERR fatal, not all of CM mapped TVI__VBIMAP fatal, failed to map VBI module properly others as returned by VMS services This routine requires SYSGBL, PRMGBL and PFNMAP privileges to use.

TVI_CS_MAKEFQT

status = TVI_CS_MAKEFQT( cmdescr, maxfq, fqtable ) Build a free queue location table to provide fast access to the free lists. cmdescr address of a CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAP routine. Passed by reference. maxfq maximum number of free list queues provided for in the table. Passed by value. fqtable free list queue table giving block sizes and pointers to the associated free queue headers. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__CMNOTINI fatal, Common Memory not initialized TVI__IVCMDS fatal, invalid CM descriptor TVI__TOOMNYFQ fatal, too many free queues for table

TVI_CS_MAPCM

status = TVI_CS_MAPCM( cmdescr ) Map the Common Memory, transient VME window and TVI control registers global sections into the current process's virtual address space. These global sections must have already been setup by a previous program (such as the CM initialization program). This service is used instead of TVI_US_INIT by those programs which depend upon the CM being initialized by a special program (usually at system startup). cmdescr address of a 16 longword block in which a CM descriptor is returned. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__CMNOTINI fatal, Common Memory not initialized TVI__MAPERR fatal, not all of a global section mapped or locked into the page tables TVI__NOVMEPWR fatal, VME Bus is not powered TVI__VBIMAP fatal, failed to map VBI module properly others as returned by VMS services

TVI_CS_MODIFLAGS

status = TVI_CS_MODIFLAGS( bp, [rstmsk], [setmsk] ) Modify the flag bits of the specified CM block. This is normally used the clear the CYCLE bit before queuing a CANCEL or EXPUNGE multicast request for a particular CM block. This is an internal routine for the TVI_US_MODFLG routine to do the flag modifications at elevated IPL. bp pointer to Common Memory block. Passed by value. rstmsk mask of flag bits to be cleared. Passed by value. setmsk mask of flag bits to be set. Passed by value. status returns a VMS condition code: SS$_NORMAL success SS$_ACCVIO fatal, no access to CMB flags

TVI_CS_POOLPOINTER

status = TVI_CS_POOLPOINTER( cmdescr, poolno, poolptr, poolsize ) Return pointer to selected Common Memory DataPool. cmdescr address of a 16 longword block returned by the TVI_CS_MAPCM service. Passed by reference. poolno selector number of Common Memory DataPool. Passed by value. poolptr address of a longword to receive a pointer to the base of the DataPool as mapped in current process virtual address space. Pointer to pool is passed by reference. poolsize address of a longword to receive size of the DataPool. Size is passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__NOPOOL error, no space allocated for selected data pool TVI__IVCMDS fatal, invalid CM descriptor TVI__BADPOOLNO fatal, bad CM data pool number others as returned by VMS services

TVI_CS_PUNCHVME

status = TVI_CS_PUNCHVME( ) This routine is obsolete with the TURBOchannel implementation and will return the status code of SS$_UNSUPPORTED.

TVI_CS_PUT

status = TVI_CS_PUT( cmdescr, umbbuf, qib, [tqptr], [cmbptr], [altdiq] ) Allocate a free CM block and copy the UMB contents into this free block from the VAX UMB buffer. The CM block size is retrieved from the UMB UMB buffer size field. The CM block is then placed on the specified CM queue or the default DAE queue (given in the QIB) if no target queue handle is provided. The CM block is recycled to the queue handle as specified by the altdiq parameter if the CYCLE bit is set. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. Passed by reference. umbbuf buffer of user data to be inserted into a CMB and placed on a queue for processing. Passed by reference. This data must have the structure of a UMB with the length of the UMB in the umb_w_reqsiz word. qib Queues Information Block containing default DAE queue header pointer and free queue table. Passed by reference. tqptr optional pointer to target queue header. If not given then the target is the default DAE queue from the QIB. Passed by value. cmbptr optional longword in which to return a pointer to the CMB allocated from the free list and queued to the target queue. Passed by reference. altdiq optional longword directing the CM block to be recycled on an alternate DAE input queue (DIQ). Passed by value. status returns a VMS condition code: SS$_NORMAL success TVI__NOFREE error, no free CM blocks of the needed size are available TVI__QLCKFAI error, failed to acquire queue lock TVI__BADQHDL fatal, bad queue handle TVI__IVCMDS fatal, invalid CM descriptor TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__IVSIZE fatal, invalid block size TVI__NOQUE fatal, no target or default queue given TVI__TOOBIG fatal, requested UMB size exceeds that of the largest CM block

TVI_CS_REMQH

status = TVI_CS_REMQH( cmdescr, qptr, cmbptr ) Remove the entry from the head of a queue in the Common Memory. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. Passed by reference. qptr pointer to queue header from which to remove the entry at the head of the queue. Passed by value. cmbptr returns a pointer to the CM block removed in a longword. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__EMPTY warning, queue is empty TVI__BADQHDL fatal, bad queue handle TVI__IVQLINK fatal, invalid queue link, possible CM corruption TVI__IVCMDS fatal, invalid CM descriptor TVI__QLCKFAI fatal, failed to acquire queue lock

TVI_CS_RESETVME

status = TVI_CS_RESETVME( cmdescr ) Use the TVI to generate a RESET on the VME bus. cmdescr address of a 16 longword block returned by the TVI_CS_INIT service. The variant form returned by the TVI_CS_VMEWINDOW routine is also acceptable. Passed by reference. status returns a VMS condition code: SS$_NORMAL success SS$_NOPRIV fatal, no privilege for requested operation TVI__IVCMDS fatal, invalid CM descriptor others as returned by VMS services The process must have DIAGNOSE privilege.

TVI_CS_SHUTDOWN

status = TVI_CS_SHUTDOWN( ) Shutdown the TVI services by deleting the permanent global sections used by these services. This service is meant for use by the CMShutdown program or stand-alone diagnostics. status returns a VMS condition code: SS$_NORMAL success SS$_NOPRIV fatal, no privilege for the requested operation others as returned by VMS services This routine requires SYSGBL, PRMGBL, PFNMAP and DIAGNOSE privileges to use.

TVI_CS_STATUS

status = TVI_CS_STATUS( cmdescr ) Return status from the TVI. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. The variant form CM descriptor returned by TVI_CS_VMEWINDOW is also acceptable. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__VMEBUSBSY warning, a TVI operation is in progress on the VME bu TVI__IVCMDS fatal, invalid CM descriptor TVI__VMEBUSERR fatal, a VME bus error has occurred TVI__MVIICR fatal, MVI ICR1 setup incorrectly TVI__MVIRCR fatal, MVI RCR setup incorrectly TVI__MVICSR fatal, MVI CSR setup incorrectly TVI__MVIARCR fatal, MVI ARCR setup incorrectly

TVI_CS_TEST

status = TVI_CS_TEST( cmdescr, qptr, [size] ) Test the specified queue to see if any entries are on it. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. Passed by reference. qptr pointer to CM queue header. Passed by value. size returns the size of the UMB of the entry at the head of the queue (or 0 if the queue is empty). Passed by reference. status returns a VMS condition code: SS$_NORMAL success TVI__EMPTY warning, queue was empty TVI__QLCKFAI error, failed to acquire queue lock TVI__BADQHDL fatal, bad queue handle TVI__IVQLINK fatal, invalid queue link possible CM corruption TVI__IVCMDS fatal, invalid CM descriptor

TVI_CS_TOUCHVME

status = TVI_CS_TOUCHVME( ) This routine is obsolete with the TURBOchannel implementation and will return the status code of SS$_UNSUPPORTED.

TVI_CS_UNLOCKPOOL

status = TVI_CS_UNLOCKPOOL( cmdescr, poolno ) Unlock specified DataPool to allow access by other processes or processors. cmdescr address of a CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAP routine. Passed by reference. poolno Common Memory DataPool selector number. Passed by value. status returns a VMS condition code: SS$_NORMAL success TVI__NOTLOCKED warning, DataPool was already unlocked TVI__IVCMDS fatal, invalid CM descriptor TVI__BADPOOLNO fatal, bad data pool selector number

TVI_CS_VAX2CM

status = TVI_CS_VAX2CM( cmdescr, block, size, cmbptr ) Copy an array of longwords from VAX memory into a CM block. cmdescr CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. Passed by reference. block address of a buffer of one or more longwords in VAX memory. Passed by reference. size Size of the longword buffer in bytes. Passed by value. cmbptr pointer to the CM block to be filled (pointer refers to the CM block as mapped by the CM global section into the process' virtual address space). Consider the pointer as passed by value or that the CM block itself is passed by reference (address of the CM block appears in the argument list). status returns a VMS condition code: SS$_NORMAL success TVI__IVCMDS fatal, invalid CM descriptor TVI__BADBHDL fatal, bad block handle TVI__IVSIZE fatal, not integral number of longwords

TVI_CS_VMEADRMOD

status = TVI_CS_VMEADRMOD( cmdescr, amod ) Set the VME address modifier of the roving VME window defined by the call to TVI_CS_VMEWINDOW to the selected value (or revert to the default). cmdescr address of a 16 longword block returned by from the TVI_CS_VMEWINDOW routine. Passed by reference. amod unsigned longword giving the VME address modifier code (see definitions in QVIDEF.H file) for the roving VME window. If 0 is passed, the VME address modifier is reset to the initialization value for Extended Supervisory Data Access. Below lists the valid address modifier codes: 0X3E Standard supervisory program access 0X3D Standard supervisory data access 0X3A Standard non-privileged program access 0X39 Standard non-privileged data access 0X2D Short supervisory access 0X29 Short non-privileged access 0X0E Extended supervisory program access 0X0D Extended supervisory data access 0X0A Extended non-privileged program access 0X09 Extended non-privileged data access status returns a VMS condition code: SS$_NORMAL success TVI__NOVME fatal, VME window not initialized

TVI_CS_VMEMAP

status = TVI_CS_VMEMAP( cmdescr, vmeadr ) Set the VME base address of the roving VME window defined by the call to TVI_CS_VMEWINDOW. NOTE: unlike the QVI system service QVI_CS_VMEMAP, the TVI_CS_VMEPOINTER system service must be called after TVI_CS_VMEMAP to establish the virutal address pointer to the VMEbus address space. cmdescr address of a 16 longword block returned by from the TVI_CS_VMEWINDOW routine. Passed by reference. vmeadr unsigned longword giving the base VME address of the window into the VME address space. The low-order 17 bits of the VME address are ignored. Passed by value. status returns a VMS condition code: SS$_NORMAL success TVI__NOVME fatal, VME window not initialized TVI__VBIMAP fatal, failed to map VBI module properly

TVI_CS_VMEPOINTER

address = TVI_CS_VMEPOINTER( cmdescr, vmeadr ) Return the VAX virtual address (in the process' VAS) which corresponds to the VME address as mapped by the roving VME window. The VME window has to have been setup by a call to CS_VMEMAP to map a range of VME addresses (including the VME address specified to this routine). cmdescr address of CM descriptor block returned by from the CS_VMEWINDOW routine. Passed by reference. vmeadr unsigned longword giving the VME address to be located. Passed by value.

TVI_CS_VMEWINDOW

status = TVI_CS_VMEWINDOW( cmdescr ) Probe the MVI registers and verify that the TURBOchannel adapter is available. Initialize the TCA_ system services for TURBOchannel resource management. Declare a user mode exit handler that releases the VMEbus window on image exit or process termination. Setup the information block with passed parameter that is used by the CS_VMEMAP routine to request TURBOchannel PMR resources. cmdescr address of the CM descriptor block returned by this routine with the TVI addresses. This variant form of the CM descriptor must be used with the CS_VMEMAP routine and is acceptable to the CS_INTERRUPT, CS_STATUS, and CS_RESETVME routines. This block must be allocated in static storage due to existence of an exit handler block within the common memory descriptor. Passed by reference. status returns a VMS condition code: SS$_NORMAL success SS$_NOPRIV fatal, no privilege for the requested operation TVI__VMEINUSE fatal, VME window in use by another process others as returned by TVI_CS and VMS services This routine requires PFNMAP and DIAGNOSE privileges to use.

TVI_ES_ALOVMEWIN

status = TVI_ES_ALOVMEWIN( handle, vmeaddr, addrspc, va [,vmeflg] ) This routine is part of the TURBOchannel extended services. It provides for any number of windows that can be mapped to both VMEbus device memories and control registers. The window created by this routine can be defined as either permanent or temporary. Permanent windows are ones which will not release any TURBOchannel resources until a reset to the adapters or a restart of the VMS operating system. Temporary windows can be release by using the compliment routine TVI_ES_RELVMEWIN(). This routine will probe the MVI registers and verify the existence of the TURBOchannel adapter option module. handle address of an identifier to the TURBOchannel resources. Address pointer passed by reference. vmeaddr base VMEbus address. Passed by value. addrspc address range of the VMEbus to map. Values must be aligned on 4Kb boundaries. Passed by value. va return pointer to the mapped VMEbus address as specified in the 'addrspc' parameter. Passed by reference. vmeflg optionl longword identifying the VMEbus address modifier. If parameter is not passed, the default of ``Extended Non-Privileged Data Access'' is used. Passed by value. status returns a VMS condition code: SS$_NORMAL success SS$_BADPARAM fatal, bad parameter value SS$_INSFARG fatal, insufficient call arguments SS$_NOPRIV fatal, no privilege for the requested operation others as returned by TVI_CS, TCA_CS, & VMS services This routine requires PFNMAP and DIAGNOSE privileges to use.

TVI_ES_GENINT

status = TVI_ES_GENINT( cmdsc, intdsc ) Generate an interrupt by writing the VBI/VAX interrupt queue. The parameter ``intdsc'' specifies the IRQ level and the particualar VAX return queue that will be actived when the interrupt is processed. The routine succeeds the TOUCHVME & PUNCHVME routines since they are unsupported by TURBOchannel. cmdsc CM descriptor returned by the TVI_CS_MAKECM or TVI_CS_MAPCM service. A variant CM descriptor returned by TVI_CS_VMEWINDOW is also acceptable. Passed by reference. intdsc Interrupt descriptor which gets written to the VBI/VAX interrupt queue. Passed by value. The descriptor is organized as follows: VECTOR the lower byte of the first word specifies which VAX return queue to activate. LEVEL the upper byte of the first word specifies the IRQ level which is asserted when the interrupt is generated. If no level is supplied, the interrupt will not be generated. INTNO the upper word specifies which external interrupt(s) are to be asserted when the interrupt is generated. status returns a VMS condition code: SS$_NORMAL success SS$_BADPARAM fatal, bad interrupt number

TVI_ES_MAKSEC

status = TVI_ES_MAKSEC( cmddescr, cmavme, cmsize, vbivme ) Create and map the permanent global sections for the TURBOchannel interface. The VMEbus common memory and interrupter modules are represented and accessed as permanent global sections. The CMDescriptor will contain virtual addresses to these sections and provide accesses to them at elevated access modes. This service is meant for use by the CM initialization program and requires that TVI_CS_INIT have been called previously. cmdescr address of a 16 longword CM descriptor which was returned by TVI_CS_INIT and will be modified here. Passed by reference. cmavme VME address of the base of the Common Memory module. Must be aligned on a TVI boundary (multiple of 128 KBytes). Passed by value. cmsize number of bytes of the Common Memory module to be used. Must be an integral number of Kbytes (an even number of VAX pages). Passed by value. vbivme VME address of the base of the VMEbus Interrupter Module. Must be aligned on a VMEbus boundary (multiple of 4 KBytes). Passed by value. status returns a VMS condition code: SS$_NORMAL success TVI__CMBASE fatal, CM base address not on TVI mapping boundary TVI__CMSIZEXC fatal, CM size exceeds QBus address space TVI__CMSIZODD fatal, CM size not even number of VAX pages TVI__IVCMDS fatal, invalid CM descriptor TVI__MAPERR fatal, not all of CM mapped TVI__VBIMAP fatal, failed to map VBI module properly others as returned by VMS services This routine requires SYSGBL, PRMGBL and PFNMAP privileges to use.

TVI_ES_RELVMEWIN

status = TVI_ES_RELVMEWIN( handle ) This routine is the compliment of the _ES_ALOVMEWIN() routine. It releases any TURBOchannel resources that are associated with the handle parameter. handle address of an identifier to the TURBOchannel resources. Address pointer passed by reference. status returns a VMS condition code: SS$_NORMAL success SS$_NOPRIV fatal, no privilege for the requested operation others as returned by TVI_CS, TCA_CS, & VMS services This routine requires PFNMAP and DIAGNOSE privileges to use.

TVI_ES_RESETVME

status = TVI_ES_RESETVME() Use the MVI to generate a RESET on the VME bus without the Common Memory initialized. status returns a VMS condition code: SS$_NORMAL success SS$_NOPRIV fatal, no privilege for requested operation others as returned by VMS services The process must have DIAGNOSE privilege.

TCA Core Services

The TCA Core Services are intended for VAX based applications that want to map VME address space into P0 or P1 process space. The services are primarily used by other TVI system services, or initialization & diagnostic applications that want map portions of VME address space.

TCA_CS_ALOVME_DMA_PMR

status = TCA_CS_ALOVME_DMA_PMR( handle, ddbreqsiz, ddbva, ddbretsiz, vmeaddr ) This routine allocates an AIB and requests a set of free map registers. The AIB is filled with DMA PMR information and linked in with the other ones located in the CAB. The ``ddbreqsiz'' parameter is used to determine the size of the DMA Data Buffer (DDB). The DDB is defined by the routine as a PFN mapped section and its virtual address is returned in the ``ddbva'' parameter. The VMEbus address that represents VMS memory is returned to the ``vmeaddr'' parameter. The value is written to the DMA controlling device which uses it to access VMS memory from the VMEbus. handle PMR handle returned. Passed by reference. ddbreqsiz integer requesting size of DDB in bytes. Passed by value. If parameter not provided, a size of 512 bytes is assumed. Size will be adjusted on integer boundaries. ddbva return integer providing the virtual address of the DDB. Address pointer passed by reference. ddbretsiz return integer of the actual size of the DDB. Passed by reference. vmeaddr return integer containing the VMEbus address of the DDB. This value represents the VMS virtual address to the DDB from the VMEbus. It is used by DMA controllers. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TCA__NOCAB no client allocation block found LIB$_INSVIRMEM insufficient virtual memory others as returned by VMS services

TCA_CS_ALOVME_PIO_PMR

status = TCA_CS_ALOVME_PIO_PMR( handle, perm, vmeaddr, addrspc, vbn, boff, vmeflg ) This routine allocates an AIB and requests a set of free map registers. The AIB is linked to other AIBs located in the CAB. The routine returns the virtual block number (VBN) that is used by client applications to map VMEbus address space as a PFN mapped section. handle PMR handle returned. Passed by reference. perm allocate the set of PMRs as permanent. Passed by value. The value of TRUE indicates that the set of PIO PMRs will be allocated as permanent, whereas FALSE indicates they will be temporary. vmeaddr start VMEbus address that is to be mapped. Passed by value. addrspc size of the VMEbus address space to map (in bytes). Passed by value. vbn return integer of the virtual block number of PIO PMR location in VMS dynamic memory. Passed by reference. boff return integer of the byte offset into the first VMS page that mapped to VMEbus space. Passed by reference. status returns a VMS condition code: SS$_NORMAL success SS$_BADPARAM bad parameter value others as returned by VMS services

TCA_CS_COPY_DDB

status = TCA_CS_COPY_DDB( handle, data, size ) This routine copies the contents of the DDB to the client data buffer. The address of the local buffer is return to the parameter ``data''. The user must call this routine to extract the data from the VME device immediately. If not, the data will get overwritten by the next DMA transaction. handle PMR handle. Passed by value. data address pointer of the data buffer. The routine returns a virtual address of the data buffer that the DDB was copied to. Passed by reference. size size if the copied data adjusted to integer boundaries. Passed by reference. status returns a VMS condition code: SS$_NORMAL success

TCA_CS_DISINT

status = TCA_CS_DISINT( mviio, intno ) Disable the IRQ level on the MVI as specified by the ``intno'' parameter. This routine assumes that the MVI control registers have already been mapped into virutal address space and is passed by the ``mviio'' parameter. mviio virtual address of the TURBOchannel MVI registers. In particular, the VIC-068A which contains the IRQ registers. Passed by reference. intno longword indicating which VMEbus IRQ level to disable. Passed by value. status returns a VMS condition code: SS$_NORMAL success TCA__NOADAP fatal, no MVI option module adapter found TCA__NOADDR fatal, MVI option module address not supplied TCA__IVIRQ error, invalid IRQ level specified. others as returned by VMS services

TCA_CS_ENAINT

status = TCA_CS_ENAINT( mviio, intno ) Enable the IRQ level on the MVI as specified by the ``intno'' parameter. This routine assumes that the MVI control registers have already been mapped into virutal address space and is passed by the ``mviio'' parameter. mviio virtual address of the TURBOchannel MVI registers. In particular, the VIC-068A which contains the IRQ registers. Passed by reference. intno longword indicating which VMEbus IRQ level to enable. Passed by value. status returns a VMS condition code: SS$_NORMAL success TCA__NOADAP fatal, no MVI option module adapter found TCA__NOADDR fatal, MVI option module address not supplied TCA__IVIRQ error, invalid IRQ level specified. others as returned by VMS services

TCA_CS_EXIT

status = TCA_CS_EXIT() This routine traverses the AIB list and releases PMR resources. PIO PMR resources are released to the set of free map registers. DMA PMR resources are released to the set of free map registers and the DDB private section virtual pages are unmapped. The TCA_CS_INIT routine establishes a user-mode exit handler with this routine. By default, the routine is executed as part of VMS image termination and guarantees that TURBOchannel resources will be relinquished. status returns a VMS condition code: SS$_NORMAL success TCA__NOCAB warning, no client allocation block found others as returned by VMS and LIB$ services

TCA_CS_INIT

status = TCA_CS_INIT( mviio, init ) Initializes TCA services by clearing the client allocation block (CAB). The CAB contains a linked list of allocation information blocks (AIB) that identify both PIO and DMA PMR allocation. Client resource usage can easily be tracked and identified by traversing the AIB list. mviio virtual address of the TURBOchannel MVI registers. In particular, the CSR data containing the board switch status. The switches are used to generate the VMEbus address. Passed by reference. init indicates whether to continue to initialize the MVI registers. Passed by value. status returns a VMS condition code: SS$_NORMAL success TCA__CABVAL warning, client allocation block already valid TCA__NOADAP fatal, no MVI option module adapter found TCA__NOADDR fatal, MVI option module address not supplied others as returned by VMS services

TCA_CS_READ_AIB

status = TCA_CS_READ_AIB( aibnum, aib, size ) This routine returns the number of allocation information blocks and the AIB descriptors located in client allocation block. The CAB AIB list is traversed and a block of dynamic memory is allocated. As AIBs are found, they are placed into dynamic memory. The address pointer to the array of AIBs is returned to the caller. aibnum return integer indicating the number of descriptors returned. Passed by reference. aib return address pointer of the array of AIB data structures describing the list of PIO & DMA PMR allocation. Passed by reference. The definition of the AIB is located in the header file ``epicure_sys_inc:tcadef.h''. size return size of the AIB array. Passed by reference. This value in used by clients to release dynamic memory to the free lists. status returns a VMS condition code: SS$_NORMAL success SS$_BADPARAM bad parameter value TCA__NOAIB no allocation information block found in CAB others as returned by VMS services

TCA_CS_READ_DDI

status = TCA_CS_READ_DDI( handle, data ) This routine retrieves the device-dependent information from the device UCB. The ``handle'' parameter identifies the device to read. handle PMR handle. Passed by value. data address of integer containing device-dependent information. Passed by reference. status returns a VMS condition code: SS$_NORMAL success LIB$_BADBLOADR bad block address others as returned by VMS services

TCA_CS_READ_PIO_PMR_STATUS

status = TCA_CS_READ_PIO_PMR_STATUS( numdsc, disreg, mapreg ) This routine returns the address to the list of free PIO PMRs. The structure format is defined in the ``epicure_sys_inc:tcadef.h'' header file. numdsc return integer indicating the number of descriptors returned. Passed by reference. disreg return integer indicating the number of disabled map registers. Passed by reference. mapreg return address pointer to the array describing the set of free map registers. Passed by reference. status returns a VMS condition code: SS$_NORMAL success TCA__NOAIB no allocation information block found in CAB others as returned by VMS services

TCA_CS_RELVME_PERM

status = TCA_CS_RELVME_PERM( num ) This routine releases all PIO PMRs that have been setup as permanent. The routine was intended for initialization routines only. num return unsigned integer containing the number of permanent PIO PMRs released. Passed by reference. status returns a VMS condition code: SS$_NORMAL success others as returned by VMS services

TCA_CS_RELVME_PMR

status = TCA_CS_RELVME_PMR( handle ) This routines scans the CAB AIB list for the AIB that matches the value as identified by the ``handle'' parameter. Resources that were allocated for DMA PMR, including the DDB PFN section, are released to the device adapter control block and dynamic memory pools. PIO PMR resources are released to the device adapter control block. handle address pointer of the PMR handle. Passed by reference. status returns a VMS condition code: SS$_NORMAL success LIB$_BADBLOADR bad block address LIB$_DABBLOSIZ bad block size others as returned by VMS services

TCI User Services

The TCI User Services are primarily used by the TVI initialization services to establish connectivity between a VME interrupt vector and VAX process.

TCI_US_CONNECT

status = TCI_US_CONNECT( dname [,efn] [,ast, astprm] [,astcnt] ) This routine connects a VMS application with a VMEbus interrupt vector. When the appropriate VMEbus device wants to interrupt the VAX, it asserts an interrupt vector on the bus. It is processed by the TURBOchannel MVIB module and sent to the VMS operating system. The OS uses the vector to lookup the interrupt service routine (ISR) in the system control block (SCB). The ISR queues an AST to the process that is associated with the vector. dname string name of the device to assign too. Passed by reference. efn integer value of the event flag number set when an interrupt is received. Passed by value. ast address of the function to execute when an interrupt occurs. Passed by reference. astprm integer value passed to the AST routine if the ``ast.fa.rp'' parameter is specified. Passed by value. astcnt integer value that preallocates a number of AST blocks. Passed by value. status returns a VMS condition code: SS$_NORMAL success SS$_BADPARAM fatal, bad parameter value FALSE error, services not initialized others as returned by VMS and $QIO services

TCI_US_EXIT

status = TCI_US_EXIT() This routine deassigns the channel and releases any resources associated with the device. The TCI_US_CONNECT routine declares this routine as a user-mode exit handler. Therefore, releasing TCI_ resources is an automatic feature of the system services. status returns a VMS condition code: SS$_NORMAL success others as returned by VMS system services

TCI_US_INIT

status = TCI_US_INIT() This routine prepares for use of the TCI_ system service routines. status returns a VMS condition code: SS$_NORMAL success, initialization complete others as returned by VMS and $LIB services

TCI_US_READ_ALL_VEC

status = TCI_US_READ_ALL_VEC( vectors, count ) This routine queries all devices for the vectors used to activate them. The ``vectors'' parameter is an address pointer to an array of structures that contain two integers. The first one indicates a VMS status code and the second the vector number. The parameter may be viewed as an array of I/O status blocks. The routine will allocate from the dynamic memory pool enough to hold the status and vector for every known device. A list of known devices is acquired by translating the logical RDCS$TVI_TCI_DEVICES. The address of the dynamic memory block is returned to the ``vectors'' parameter which the application may use to initialize the VBI module virtual DMA channels. Since the TCI_US_EXIT routine is responsible for releasing device resources, the application shouldn't attempt to release the memory block. vectors address pointer to array of two integer data packets. Passed by reference. count number of vectors returned. Passed by reference. status returns a VMS condition code: SS$_NORMAL success others as returned by VMS services

TCI_US_READ_VEC

status = TCI_US_READ_VEC( vector ) This routine requests the interrupt vector from the device assigned to after a call to the TCI_US_CONNECT routine. vector returned integer that contains the interrupt vector used to activate the device. Passed by reference. status returns a VMS condition code: SS$_NORMAL success SS$_BADPARAM fatal, bad parameter value FALSE error, services not initialized others as returned by VMS and $QIO services

TCI_US_RESINM

status = TCI_US_RESINM( [efn] [,ast, astprm] ) This routine is called to reestablish the mechanism used to notify processes that an interrupt from the TURBOchannel adapter has been received. efn integer value of the event flag number set when an interrupt is received. Passed by value. ast address of the function to execute when an interrupt occurs. Passed by reference. astprm integer value passed to the AST routine if the ``ast'' parameter is specified. Passed by value. status returns a VMS condition code: SS$_NORMAL success SS$_BADPARAM fatal, bad parameter value FALSE error, services not initialized others as returned by VMS and $QIO services

Basic Services for 80386 Code

The CM routines are linked with the DAE code itself and provide services at the level of the VAX TVI_US routines. The CM routines locate Common Memory blocks and queues by their VMEbus address in the memory module used to support the Common Memory.

cm_dapmcast

status = cm_dapmcast( cmbptr ) Insert a Common Memory block with a DAP Multicast message the next destination queue of the message. The next destination queue is given by either the next non-empty entry in the DAP Queue Table (as specified by the QTI within the Multicast message) or is the originator's return queue. By convention, DAP Multicast messages originate in the host MicroVAX. cmbptr pointer to CM block with the Multicast message. Passed by value (or consider the CM block as passed by reference). status returns a VMS condition code: SS$_NORMAL success QVI__CMNOTINI fatal, Common Memory not initialized QVI__QLCKFAI fatal, failed to acquire queue lock

cm_dapqloc

status = cm_dapqloc( qti, qhdl ) Locate a Common Memory queue by its Queue Table Index (QTI) as used in the Data Access Protocol (DAP) packets. qti queue table index given as a byte. Passed by value. qhdl returns a pointer to the queue header. Passed by reference. status returns a VMS condition code: SS$_NORMAL success QVI__CMNOTINI fatal, Common Memory not initialized QVI__NOQUE fatal, could not find named queue

cm_insqt

status = cm_insqt( cmbptr, qptr, genint ) Insert a Common Memory block onto the tail of a queue in Common Memory. cmbptr pointer to the CM block. Passed by value (or consider the CM block as passed by reference). Note that the pointer is to the CMB, not the UMB which is contained within the CMB. qptr pointer to CM queue header on which to insert the CM block or the offset of the queue header relative to the base of the CM. Passed by value (or consider the CM queue header as passed by reference). genint interrupt generation control flag. If 1 then the interrupt associated with the queue is triggered. If 0, then the interrupt (if any) is not triggered. Passed by value. status returns a VMS condition code: SS$_NORMAL success QVI__BADBHDL fatal, bad pointer to CM block QVI__BADQHDL fatal, bad pointer to CM queue header QVI__CMNOTINI fatal, Common Memory not initialized QVI__QLCKFAI fatal, failed to acquire queue lock

cm_locate

status = cm_locate( qname, qhdl ) Locate a Common Memory queue header. qname queue name given as (up to 8) ASCII characters. Passed by reference (a C string terminated by a NUL character). qhdl pointer to the new queue header returned in a longword. This is the address of the queue header in the CM. Passed by reference. status returns as VMS condition code: SS$_NORMAL success QVI__NOQUE fatal, no queue found

cm_remqh

status = cm_remqh( qptr, cmbptr ) Remove entry from the head of a Common Memory queue. qptr pointer to CM queue header from which to remove the CM block. Passed by value (consider the CM queue header as passed by reference). cmbptr address of longword to return pointer to the block removed from the head of the queue. Passed by reference. Note that the pointer is to the CMB, not to the UMB which is contained within the CMB. status returns a VMS condition code: SS$_NORMAL success QVI__EMPTY warning, queue is empty QVI__BADQHDL fatal, bad pointer to CM queue header QVI__CMNOTINI fatal, Common Memory not initialized QVI__QLCKFAI fatal, failed to acquire queue lock

cm_tstq

status = cm_tstq( qptr ) Test the status of a Common Memory queue. qptr pointer to CM queue header. Passed by value (consider the CM queue header as passed by reference). status returns a VMS condition code: SS$_NORMAL success QVI__EMPTY warning, queue is empty QVI__BADQHDL fatal, bad pointer to CM queue header QVI__CMNOTINI fatal, Common Memory not initialized QVI__QLCKFAI fatal, failed to acquire queue lock

Additional 80386 Services

These CM services are an optional addition to those listed above. Normally, the DAE processors receive requests from the VAX and pass responses back to the VAX in the same CMB as the request arrived in. In order to allow the DAE processors to generate unsolicited messages, these additional routines interface the DAE processors to the free block lists in the Common Memory. These routines assume that the VAX will be the sink for these messages and depend on the VAX to restore the exhausted block to its free list.

cm_get_block

status = cm_get_block( size, qhdl, cmbptr ) Allocate a block from the Common Memory free lists. size requested size of the UMB to be allocated from the CM free lists. Passed by value. The size will be stored in the standard field in the UMB header of the allocated block. The caller must fill in the UMB block type. qhdl queue pointer, returned by cm_locate(), of a queue owned by a VAX process which is the ultimate destination of the message in the block being requested. cmbptr address of longword to return pointer to the block removed from a free list queue. Passed by reference. Note that the pointer returned is to the CMB, not the UMB which is contained within the CMB. status returns a VMS condition code: SS$_NORMAL success QVI__NOFREE error, no free CM blocks QVI__CMNOTINI fatal, Common Memory not initialized QVI__IVSIZE fatal, invalid UMB size request QVI__QLCKFAI fatal, failed to acquire queue lock QVI__TOOBIG fatal, size exceeds largest CM block size

cm_get_init

status = cm_get_init() Perform necessary one-time-only initializations for the cm_get_block() routine. This includes building a list of the free lists in static storage which is sorted by the size of the blocks on the free lists. status returns a VMS condition code: SS$_NORMAL success QVI__CMNOTINI fatal, Common Memory not initialized QVI__TOOMNYFQ fatal, too many free queues for table Other optional CM services deal with Common Memory DataPools. A DataPool is a section of Common Memory set aside for the use of a group of cooperating processes (usually on multiple processors) as a data storage area. The usual setup is for one process to collect data, reformat it and deposit in the DataPool. Another process will then pick data out of the DataPool in response to user data acquisition requests.

cm_lockpool

status = cm_lockpool( pn ) Lock the selected data pool against updates by other processors. pn number of Common Memory DataPool. Passed by value. status returns a VMS condition code: SS$_NORMAL success, pool locked by this processor QVI__LOCKED warning, pool is already locked QVI__BADPOOLNO fatal, bad CM data pool number

cm_poolpointer

status = cm_poolpointer( pn, pp ) Return address of selected Common Memory DataPool area. pn number of Common Memory DataPool. Passed by value. pp address of a longword to return the pointer to the Common Memory DataPool. Passed by reference. status returns a VMS condition code: SS$_NORMAL success QVI__NOPOOL error, no space allocated for selected data pool QVI__CMNOTINI fatal, Common Memory not initialized QVI__BADPOOLNO fatal, bad CM data pool number

cm_unlockpool

status = cm_unlockpool( pn ) Release the lock on the selected data pool to allow updates by other processors. pn number of Common Memory DataPool. Passed by value. status returns a VMS condition code: SS$_NORMAL success, pool locked by this processor QVI__NOTLOCKED warning, pool was already unlocked QVI__BADPOOLNO fatal, bad CM data pool number

CM Initialization

The Common Memory is setup from the VAX program called TCCMInitializer (TCCMI). This program is run whenever the VAX is booted or the DAE is reset and restarted (without booting the VAX). The TCCMI program must run in a process with the necessary privileges to run the various TVI_CS services (CMKRNL, PFNMAP and DIAGNOSE) along with others as deemed necessary. The TCCMI performs the following actions in roughly the listed order:
  1. Read a text file of parameters using the logical name . The format of this file is described below.
  2. Create a permanent global section named if not already present. The global section is created using PFN (Page Frame Number) mapping of the TURBOchannel addresses used for the main CM window. In either case, map the global section into current process VAS P0 region.
  3. Create a permanent global section named if not already present. The global section is created using the PFN extract from the base hardware address of the TURBOchannel adapter. Furthermore, the TURBOchannel adapter registers are initialized to the VMEbus configurations: to and arbitration.
  4. Create a permanent global section named if not already present. The global section is created by using the PFN returned by the identifying the VAX window into the VMEbus address space of the VBI. The VBI FIFO interrupt queues are flushed and the QFULL registers are initialized.
  5. Zero all of the VME memory module locations (including the entire Common Memory region).
  6. Initialize the CM global area locations and build the CM queue headers, allocation area descriptors and other fixed structures.
  7. Initialize CM free queues and place all the CM blocks on their respective free queues.

Format of Parameter Descriptions

The parameters file is located by the logical name. The defaults for the file specification of the parameters file are:
     SYS_STARTUP:CM_PARAMETERS.INI
Each line of this file contains the description of a single parameter using DCL-like syntax:
 
    parameter-name[/qualifier(s)]  value[,value...]
Optional arguments are indicated by square brackets ([...]) in the syntax descriptions. Depending upon the parameter, values can be decimal numbers, hexadecimal numbers (%X...), non-delimited symbol names of alphanumeric characters (including ``$'' and ``_''), text strings enclosed in double quotes ("...") or keywords. Comments may be included with the parameters. All characters after an exclamation mark (``!'') to the end of the line are ignored and treated as comments. Multiple spaces and tabs outside of quoted text are treated as a single space. Lowercase characters are converted to uppercase, except within quoted text.

TCCMInitializer Parameters

list [ADDRESS address] Specifies an address: list [/CM] The base address of the memory board on the VME bus to be used for the Common Memory. [/VAX=qnum] Specifies the number of which general purpose VBI FIFO interrupt queue to use for interrupts generated by the VAX. Valid values are . [/VBI] The base address of the VMEbus Interrupt (VBI) module. [/VME=qnum] Specifies the number of which general purpose VBI FIFO interrupt queue to use for interrupts generated by the VMEbus devices. Valid values are . [BLOCKS queue-name] Specifications for a free block area. The argument is the name of the queue header for the free list of these blocks. list [/SIZE=n] Size, in bytes, of each of this class of blocks. [/COUNT=n] Number of blocks to be created in this class. [/AVAILABLE] Use remainder of available Common Memory for blocks of this free list.

Note, and are mutually exclusive and only one can be used on a given BLOCKS command. Similarly, only a single BLOCKS command in a parameters file can use the qualifier. [CLEARMEMORY size] Specifies the amount of memory in the VME memory module to be cleared to zeroes. Size is given in Kbytes. [DATAPOOL n size] Specifies that DataPool number n is to be initialized with a size of size bytes. [EXIT] Terminates parameters command file. [LDD name] Specifies the node name whose Listener Data Descriptor (LDD) is to be setup. The ``DEFS'' string is passed as the name parameter to specify defaults values. The defaults are used if a particular qualifier isn't specified for a given name, or if the current node doesn't match any of the names defined by the LDD command. Furthermore, ``DEFS'' be specified before any other LDD command definitions. list [/ID=number] Specifies the Listener ARCnet node number (0-255). [/DAE=number] Specifies the number (0-255) of seconds that must elapse before the DAE data is considered stale. [/FTP=number] Specifies the number (0-255) of seconds that must elapse before the FTP data is considered stale.

[MUXQUEUE name] Specifies the name of the multiplexed return queue (if any). [QUEUE name] Defines a named queue whose header is to be setup. Queue names are alphanumeric symbol names (``$'' and ``_'' permitted). The case of the queue name is unimportant as all the queue names are kept in uppercase. list [/EXTERNAL=number] Specifies the bit number of a TVI external interrupt associated with this queue. This interrupt is generated by writing a 1 to the selected bit number in a register. [/DEMUX] Specifies that this is a VAX return queue fed via the multiplexed return queue and the process. [/NONE] No interrupt is associated with the queue (normally used only for free list queues or input queues watched by a polling algorithm). [/DEVICE=device] Specifies the name of a VAX device with the TCI driver for handling interrupts for this queue. Used for input queues for VAX processes only. [/DAP_INDEX=number] Specifies that this queue is to be entered in the DAP queue table at the specified index number. [/IRQ=number] Specifies the VMEbus Interrupt Request Number (IRQ) number for this particular VAX return queue. If not specified, IRQ defaults to value as defined by the symbol TVI$B_RIQ_INIT. [/VECTOR=vector] Specifies the interrupt (IRQ) vector that activates the VAX return queue. Value is specified in hexadecimal. Normally, this is determined by reading the vector directly from the device. Specifying this value overrides the one read from the device. Valid vector range is . Only one of the qualifiers , and , , or may be present ( is taken by default if no qualifier is present). The and qualifiers are not allowed with (either an explicit or one implied by default) or . The qualifiers , , , or are not allowed with . In addition, and are not allowed together.

[RESET] Generate a VME bus reset. [SET keyword] Select an option: list [CHECK_ONLY] Read and validate the parameters, but do not actually initialize the CM. [VERIFY] List the commands as they are read. [TEST_MODE] Used for testing CMI.

[SHOW keyword] Select an output option: list [BUILD] Show details during the initialization of the Common Memory. [PARAMETERS] Show a table of the initialization parameters after the commands are read and before the CM is initialized. [SUMMARY] Show a summary of the initialization operations. [SIZE Kbytes] Specifies the size of the CM in Kbytes.

The following is an example of a command procedure used to initialize the Common Memory. The first part of the procedure defines the logical names which TCCMI will cross-check against its input parameters.

$ DEFINE := DEFINE /NOLOG
$!
$! Define logical names to identify default queue to send packets to
$! Data Acquisition Engine and to hold packets incase of INSQ failures.
$!
$ DEFINE /SYSTEM	RDCS$QVI_DAE_QUEUE	TIMER
$ DEFINE /SYSTEM	RDCS$QVI_WASTE_QUEUE	$TOXIC$
$!
$! Define logical names for VAX devices associated with CM queues used
$! as "input" to VAX processes; devices are used with Connect-to-Interrupt.
$!
$ DEFINE /SYSTEM	RDCS$QVI_VAXQ_DASRET	VAXQA0:
$ DEFINE /SYSTEM	RDCS$QVI_VAXQ_TSRET	VAXQB0:
$ DEFINE /SYSTEM	RDCS$QVI_VAXQ_HERMES	VAXQC0:
$ DEFINE /SYSTEM	RDCS$QVI_VAXQ_FEEDER	VAXQF0:
$ DEFINE /SYSTEM	RDCS$QVI_VAXQ_ECHOBACK	VAXQG0:
$!
$! Initialize the common memory with parameters in the specified file.
$!
$ SET PROCE/PRIV=("CMKRNL,DIAGNOSE,PSWAPM,PRMGBL,SYSGBL,PFNMAP,SYSLCK")
$ DEFINE /USER_MODE  CM_PARAMETERS   SYS$INPUT
$ RUN TCCMI
reset
address %XE0000000 /cm                 !CM VME card address
address	%XD0000000 /vbi /vax=0 /vme=1  !VMEbus Interrupter Module address
size    3072                           !Use 3 MB of memory
clear   4096                           !Clear all 4 MB of memory
!
! Queues for free lists:
!
queue	$256 /none
queue	$1K /none
queue	$4k /none
queue	$8k /none
queue	$16k /none
queue	$tiny /none
blocks	$16k /size=16384 /count=50
blocks	$8k /size=8192 /count=80
blocks	$4k /size=4096 /count=150
blocks	$1k /size=1048 /count=300
blocks	$256 /size=280 /count=500
blocks	$tiny /size=128 /available
!
! Listener parameters:
! The defaults MUST be defined first!
!
ldd     defs    /id=1 /dae=120 /ftp=120 !Setup listener defaults
ldd     huey    /id=1                   !For HUEY
ldd     dewey   /id=2                   !For DEWEY
ldd     louie   /id=3                   !For LOUIE
ldd     webby   /id=4                   !For WEBBY
!
! Action queues:
!
queue   $toxic$  /none
queue   dasret   /device=vaxqa0:                !DAS return queue
queue   tsret    /device=vaxqb0:                !TS return queue
queue   camac    /external=1 /dap_index=2       !CAMAC module's queue
queue   timer    /external=0 /dap_index=1       !Timer module's queue
queue   Hermes   /device=vaxqc0: /irq=5 /vector=%XFC !Message handler queue
exit
$ EXIT

Internals

Logical Names

A set of logical names of the form are used to specify special-purpose CM queues and to associate VAX return (or input) queues with a set of VMS device names (see the section on the TCIDRIVER below). Furthermore, the component of the logical remained for consistency between QVI & TVI front ends. TCCMI cross-checks its input parameters against these logical names. The Common Memory initialization procedure example in section illustrates some of these logical name definitions. The special logical names used by the TVI services are: list [RDCS$QVI_DAE_QUEUE] gives the name of the default DAE queue in Common Memory. This is the queue that blocks with the CYCLE bit set are placed on after being removed from a VAX return queue. [RDCS$QVI_WASTE_QUEUE] gives the name of the ``toxic waste'' Common Memory queue. The ``toxic waste'' queue provides a place for the TVI services on the VAX (and possibly their equivalents in the DAE processing elements) to place CM blocks which would otherwise be ``lost''. Some of the TVI services use this queue when problems arise in queuing blocks to other queues; the ``toxic waste'' queue is used rather than dropping the CM block on the floor which would result in the lose of the CM resources. The ``toxic waste'' queue is not associated with an interrupt, but a periodic VAX process will attempt to empty the ``toxic waste'' queue and recover the blocks (restore them to the free lists). [RDCS$QVI_DEMUX_QUEUE] gives the name of the multiplexed VAX return queue. This is the input queue for the process. [RDCS$QVI_VAXQ_qname] where ``qname'' is the name of a Common Memory queue. The equivalence string of the logical name is the name of the VAX device used to process the interrupts associated with the specified VAX return queue.

Another set of logical names of the form are used to specify special-purpose devices and associate them with registers. The variant encapsulated in the logical identifies the specific QFULL register.

TCADRIVER

VMEbus resources are managed by the device driver. The TVI system services assign to the main TCA device to request allocation, initialization, and releasing Programmed I/O (PIO) & Direct Memory Access (DMA) page map registers (PMRs). The internal formats and complexities of the requests are hidden from the user by the TCA system services. The TCA device is initialized and established by a startup command procedure:

$ RUN SYS$SYSTEM:SYSGEN
!
! NOTE: The below driver is implemented as a 'cloned'
!       device driver and requires NO /VECTOR qualifier
!
CONN TCAA0/ADAP=2/DRIV=RDCS_TVI:TCADRIVER
!
!
EXIT
$ EXIT

Loading the device initializes the TURBOchannel adapter data structures and prepares the device for requests. When users assign the device, a ``clone'' device is created. Each request for a set of PIO or DMA PMRs creates a new TCA device. When the user's image exits, the ``cloned'' device is deleted and all VMEbus resources allocated are then released .

TCIDRIVER and VAX Interrupt Devices

Interrupts associated with the VAX input queues are handled using VMS devices supported by the driver for the TURBOchannel DWTVX option modules. The is a modified and simplified Connect-to-Interrupt driver. The association between the VAX device name and the interrupt vector is setup at system startup by (see the example below). The TVI interrupt services associate a VAX device name with an VMEbus interrupt vector by the controller letter in the device name. Thus controller letters ``A'' through ``H'' map correspond to vectors . The interrupt vector to be loaded into the is located in the Interrupt Dispatch Block (IDB) of the system's I/O database as setup by . A startup file for to define devices for interrupt vectors on the TVI is:
$ RUN SYS$SYSTEM:SYSGEN
!
! NOTE: The /VEC establishes connectivity between
!       TVI message queues and VMS processes
!
CONN VAXQA0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%X10
CONN VAXQB0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%X20
CONN VAXQC0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%X30
CONN VAXQD0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%X40
CONN VAXQE0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%X50
CONN VAXQF0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%X60
CONN VAXQG0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%X70
CONN VAXQH0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%X80
!
! NOTE: The below devices are viewed as the VBI Q full
!       notification queues. The VQMonitor process assigns
!       to them and waits for the interrupt from the VBI.
!
CONN VAXQW0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%XF0
CONN VAXQX0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%XF4
CONN VAXQY0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%XF8
CONN VAXQZ0/ADAP=2/DRIV=RDCS_TVI:TCIDRIVER/VEC=%XFC
EXIT
$ EXIT

A process that assigns to a device is eligible for interrupts initiated from VMEbus given the corresponding vector as specified in the command. The TCI system services use the I/O function code (same function code as used by the VMS Connect-to-Interrupt Driver supplied by Digital) to initialize the connectivity.

The following is a short description of calling the . Serious users are directed to the description of the VMS Connect-to-Interrupt driver in the VAX/VMS Device Driver manual.

status = SYS$QIO( [efn], chan, func, [iosb], [astadr], [astprm], [p1], [p2], [p3], [p4], [p5], [p6])

The standard VMS $QIO system service when used with the takes the following arguments. Note that there is a distinction between the completion of the I/O operation and device interrupts. The $QIO call can be setup to receive a single interrupt and then have the I/O request complete. A more normal mode of operation, as used by the TVI_US routines, is to have multiple device interrupts reported without the I/O request completing. efn number of event flag set on completion of the I/O request. Passed by value. chan channel number assigned to one of the devices using the $ASSIGN system service. Passed by value. func I/O function code of IO$_CONINTREAD. Passed by value. iosb I/O status block set on completion of the I/O request. Passed by reference. astadr AST routine called upon completion of the I/O request. Passed by reference. astprm parameter for the I/O completion AST. Passed by value. p1 this parameter is ignored by the . Passed by value. p2 optionally specifies the interrupt level number if the flag in the p3 argument. Passed by value. p3 longword containing flags and an optional event flag number. This event flag is set on each device interrupt (as distinct from the efn parameter above). Passed by value. p4 AST routine called on each device interrupt (address of routine's entry mask). Passed by reference. p5 AST parameter to be passed to the device interrupt AST specified in p4. Passed by value. p6 number of AST control blocks to preallocate in anticipation of fast, recurrent interrupts from the device. Passed by value. status returns a VMS condition code: SS$_NORMAL success. SS$_BADPARAM number of preallocated AST control blocks in the p6 argument exceeds 65535. SS$_DISCONNECT a connection is already outstanding for the device or the driver cannot reallocate AST control blocks quickly enough. SS$_EXQUOTA process has exceeded its direct I/O limit quota or its AST limit quota. SS$_ILLEFC an illegal event flag number was specified. SS$_INSFMEM insufficient system dynamic memory is available to complete the system service. SS$_UNASEFC the process is not associated with the cluster containing the specified event flag.

list [CIN$M_EFN] set event flag on interrupt. [CIN$M_USECAL] p2 parameter contains the interrupt level number. [CIN$M_REPEAT] leave process connected to the interrupt vector until the connection is canceled and repeatedly report interrupts for this single I/O operation. [CIN$M_AST] queue p4 AST routine on interrupt. [CIN$M_EFNUM] high-order word specifies the number of the event flag to be set when an interrupt occurs.

KerrMcGee Process

This detached VMS process is planned to monitor the integrity of the Common Memory and the ``toxic waste'' queue in particular. Currently, only updates the time-of-year clink value in the Common Memory global area approximately every 21 minutes to keep the value in synchrony with the VAX system time.

DeMuxer Process

This detached VMS process has the multiplexed queue as its input queue. When an entry is made on this queue, is awakened by an interrupt and proceeds to empty the queue. As each entry is removed, the originator identifier in the CM block is used to locate the Queue Demultiplexing Block (QDB, see below) which contains a pointer to the true destination queue for the CM block. The QDB also identifies the VMS process associated with this return queue; simulates an interrupt to this process by using the Declare External Process AST routine in the Epicure System Services (ESS).

DAE Event Monitor (DEM) Process

This detached VMS process monitors activity on the VAX return queue. Messages which appear on the queue indicate that an exception occurred on one of the processors. When a message appears on the queue, is awakened by an interrupt and proceeds to empty the queue. The data within the message is translated, logged to a file, and sent to the VMS process. In addition, it's intended that these messages be integrated into the Epicure alarm system .

VBI Q Monitor (VQMonitor) Process

This detached VMS process responds to interrupts from the module when the FIFO interrupt queues reach the half full point. For each FIFO interrupt queue, a device exists that is used to signal when the queue has reached it's half full mark. When this occurs, the process is notified and logs a message to a file. In addition, it is intended that these messages be integrated into the Epicure Alarm System.

Queue Organization, Queue Headers and Queue Operations

A CM queue is a singly-linked FIFO list. The head pointer is the CM offset (from the base of Common Memory) to the first entry on the queue (or 0 if the queue is empty). The first longword of each queue entry contains the CM offset of the next entry; the last entry contains a 0 in the link longword (see Section 2.1, Format of a Common Memory Block). The tail pointer is the CM offset to the last (tail) entry on the queue (of 0 if the queue is empty). A CM queue header occupies 8 longwords (32 bytes). The format of a CM queue header (as seen on the VAX) is:

The fields of the CM queue header are: list [cqh_b_lock] Lock byte. The LCK bit is used to lock the queue during manipulations (by a on the VAX, a the 68020 and a on the 80386). list [CQH_V_LOCK] Offset to the lock bit in the lock byte.

[cqh_b_flags] Byte of bit flags: list [CQH_V_INT] Offset to the INT bit. This bit is set if an interrupt is associated with the queue (thus the cqh_l_intid field contains valid information). [CQH_V_EXT] Offset to the EXT bit. This bit indicates whether the interrupt is an external interrupt (EXT=1) or an interrupt triggered by touching a VME address (EXT=0). The EXT bit thus describes the contents of the cqh_l_intid field. Used only by QVI front ends. [CQH_V_MUX] Offset to the MUX bit. This bit indicates that the VAX return queue is fed via the multiplexed return queue and the process. [CQH_V_TC] Offset to the TC bit. This bit indicates whether the VAX return queue is configured for the VBI module. Used only by TURBOchannel front ends. [CQH_V_WRD] If set, a word instruction to the specified VME address is used to generate the associated interrupt. [CQH_V_DAS] Obsolete.

[cqh_l_headp] Offset to entry at head of queue. [cqh_l_tailp] Offset to entry at tail of queue. [cqh_w_curcnt] Count of current queue entries. [cqh_w_maxcnt] Count of maximum number of entries on queue since initialization (or last reset). [cqh_l_intid] Interrupt descriptor that identifies the external or vectored interrupt(s) to generate. If the bit is set, this value is written to the VBI module. [cqh_q_name] Queue name given as uppercase characters, padded with blanks. [cqh_l_putcnt] Unsigned count of the insert operations performed to the queue since the counter was zeroed (initially zeroed at CM initialization).

/*
 As seen by the VAX and the 80386:
*/
struct CQH {
    unsigned char cqh_b_lock;
    unsigned char cqh_b_flags;
    unsigned : 16;
    unsigned long cqh_l_headp;
    unsigned long cqh_l_tailp;
    unsigned short cqh_w_curcnt;
    unsigned short cqh_w_maxcnt;
    unsigned long cqh_l_intid;
    unsigned long cqh_q_name[2];
    unsigned long cqh_l_putcnt;
    };

/*
 As seen by the 68020:
*/
struct CQH {
    unsigned : 16;
    unsigned char cqh_b_flags;
    unsigned char cqh_b_lock;
    unsigned long cqh_l_headp;
    unsigned long cqh_l_tailp;
    unsigned short cqh_w_maxcnt;
    unsigned short cqh_w_curcnt;
    unsigned long cqh_l_intid;
    unsigned long cqh_q_name[2];
    unsigned long cqh_l_putcnt;
    };

/*
 Common to all processors:
*/
#define CQH_V_LOCK  7
#define CQH_M_LOCK  0X80
#define CQH_V_INT   0
#define CQH_M_INT   0X01
#define CQH_V_EXT   1
#define CQH_M_EXT   0X02
#define CQH_V_MUX   2
#define CQH_M_MUX   4
#define CQH_V_TC    3
#define CQH_M_TC    8
#define CQH_V_WRD   6
#define CQH_M_WRD   0X40
#define CQH_V_DAS   7
#define CQH_M_DAS   0X80
The CM queues are manipulated with the following sequence of operations:
  1. The queue reserve lock is set. This is done with a instruction on the 68020 against the lock byte of the queue header at offset CQH_B_LOCK. The 80386 uses a byte instruction with the prefix on that same byte with the register loaded with (this may change in the future to a instruction). The VAX sets the reserve lock with the instruction (Interlocked Branch on Bit Set and Set bit) on the bit at offset in the lock byte at offset . The offsets will be defined so that the , and instructions are manipulating the same bit in the Common Memory.

    Before the VAX issues the instruction, the TVI is preset to stretch the VMEbus cycle since the results in separate read and write TURBOchannel bus cycles. The TVI preset will keep the VMEbus busy until the next write operation (the write cycle from the in this case).

  2. The requested queue operation (insert entry at tail or remove entry from head) is performed by updating all the affected pointers.
  3. The counters (current and maximum number of entries, count of queue inserts) are updated.
  4. The queue reserve lock is cleared by clearing the lock byte with a Clear Byte instruction.

VAX Structures

This section describes some of the VAX-based data structures associated with the TVI services. These are internal to the TVI_US routines (maintained in local own storage) and are explicit arguments to the TVI_CS routines.

VMEbus Interrupter (VBI) Structures

The module is mapped to the global section and allows processes to access them through the TVI system services. This section describes the data structures that represent the module registers:

The structure displays the format of all general purpose queues and provides the necessary fields in order to generate external or VMEbus interrupts.

struct TVI_VBI_QENTRY
    {
    variant_union
        {
        unsigned int data;
        variant_struct
            {
            unsigned char vector;
            unsigned level : 3;
            unsigned : 5;
            unsigned short trigger;
            } $qentry_members;
        } $qentry_overlay;
    };

The structure fields can be described as follows:

list [vector] This field is the VMEbus vector that gets placed on the VMEbus during an interrupt acknowledge cycle. Interrupts must be enabled in order for the DWTVX interface to service the interrupt. This is performed by the application. Valid TURBOchannel interrupt vectors are . [level] This field works in conjunction with the field and specifies the level to generate the interrupt. Valid interrupt levels are . [trigger] This field specifies which external interrupt to trigger given the bit position. Multiple bits can be specified generating simultaneous external interrupts.

The structure displays the format of the registers used to generate VMEbus interrupts when the corresponding queue reaches its half full mark. Only vectored interrupts can be generated. Below describes the registers format.

struct TVI_VBI_QFULL
    {
    variant_union
        {
        unsigned int data;
        variant_struct
            {
            unsigned char vector;
            unsigned level : 3;
            unsigned : 1;
            unsigned q : 1;
            unsigned : 1;
            } $qentry_members;
        } $qentry_overlay;
    };

The structure fields can be described as follow:

list [vector] This field is the VMEbus vector that gets placed on the VMEbus during an interrupt acknowledge sequence. Interrupts must be enabled in order for the DWTVX interface to service the interrupt. This is performed by the application. Valid TURBOchannel interrupt vectors are . [level] This field works in conjunction with the field and specified the level to generate the interrupt. Valid interrupt ranges are . [q] This field specifies which FIFO queue will perform the interrupt. Valid queue numbers are .

Both structures and describe the formats used by the FIFO queues used to generate external and VMEbus interrupts for general purpose and specific use. The module registers are viewed by the VAX as linear addresses and not all registers are part of the current implementation. Below describes the format of the module as viewed by the system services given the current implementation:

struct TVI_VBI_IO {
    struct TVI_VBI_QENTRY q0_entry;
    struct TVI_VBI_QENTRY q1_entry;
    unsigned int q0_flush;
    unsigned int q1_flush;
    struct TVI_VBI_QFULL q0_full;
    struct TVI_VBI_QFULL q1_full;
    };

The fields which are relevant to the implementation are described below: list [q0_entry] This fields represents the general purpose FIFO interrupt queue zero that is used for interrupts from the VAX. [q1_entry] This fields represents the general purpose FIFO interrupt queue one that is used for interrupts from VMEbus. [q0_flush] Writing to this location clears the contents of . This action is performed only at CM initialization. [q1_flush] Writing to this location clears the contents of . This action is performed only at CM initialization. [q0_full] An interrupt descriptor is written to this location to generate an interrupt when has reached its half full mark. The VAX-based process will be notified by this interrupt. [q1_full] An interrupt descriptor is written to this location to generate an interrupt when has reached its half full mark. The VAX-based process will be notified by this interrupt.

TURBOchannel DWTVX Registers

The registers supported by the TURBOchannel DWCTX interface are mapped to the global section and allow TVI system services to access them. Although many registers exist, this section will describe only the registers that are used by the TVI system services.

The structure represents the contents of the global section. Only the registers that are used by the TVI system services are provided:

struct TVI_MVME_IO
    {
    unsigned char PROM[0X40000];
    struct TVI_MVI_CSR MVI_CSR;
                :
                :
    struct TVI_VIC_VICR VIC_VICR1;
    struct TVI_VIC_VICR VIC_VICR2;
    struct TVI_VIC_VICR VIC_VICR3;
    struct TVI_VIC_VICR VIC_VICR4;
    struct TVI_VIC_VICR VIC_VICR5;
    struct TVI_VIC_VICR VIC_VICR6;
    struct TVI_VIC_VICR VIC_VICR7;
                :
                :
    unsigned int VIC_ICR1;
    unsigned int VIC_ARCR;
                :
                :
    unsigned int VIC_RCR;
                :
                :
    unsigned int VIC_SRR;
    };

The fields which are relevant to the implementation are described as follows:

list [PROM] This area provides the TURBOchannel ROM header that contains information to determine if the option module exists. The information contained is probed by the TVI system services. The data contained is pattern fields, firmware version, vendor name, firmware type, and a flag field. [MVI_CSR] The DWTVXB interface command/status register. Consult the ``TURBOchannel-to-VME IO Subsystem Technical User's Guide'' for a complete description of this register. [VIC_VICR1..VIC_VICR7] Provides enabling as VMEbus interrupt handler for the corresponding interrupt level. [VIC_ICR1] VMEbus interface configuration register. A general purpose read/write register defining how operations are performed. [VIC_ARCR] This register provides configuration of the arbitration mode. When set, priority arbitration is used. When clear, round-robin arbitration is used. This register is configured for priority arbitration. [VIC_RCR] This register configures the VMEbus release mode. This register is configured for mode. [VIC_SRR] The system reset register provides the means to generate a VMEbus . Writing the value of causes this function to occur.

The structure represents the corresponding to the VMEbus interrupt levels. Assigning appropriate values to the individual members enables or disables the TURBOchannel DWTVB module as a VMEbus interrupt handler. Below indicates the format of the registers and describes the fields which compose the structure:

struct TVI_VIC_VICR
    {
    variant_union
        {
        unsigned int data;
        variant_struct
            {
            unsigned IPL: 3;
            unsigned : 4;
            unsigned interrupt_enable: 1;
            unsigned : 24;
            } bit_defs;
        } data_overlay;
    };

list [IPL] Is an encoded IRQ level and used for systems with 680X0 processors. [interrupt_enable] VMEbus interrupt mask. When clear, the DWCTX acts as interrupt handler for the corresponding interrupt level.

Common Memory Descriptor

A CM descriptor occupies 16 longwords (64 bytes). The CM descriptor basically describes the TVI and CM global sections as mapped into a process (each process has its own CM descriptor). The format of a CM descriptor is:

The fields of the CM descriptor are: list [cmd_l_check] Longword with validation check value. Used to validate CM descriptor as initialized. [cmd_a_base] Pointer to base of the CM global section as mapped into the process's virtual address space (VAS). This pointer, like all non-system space virtual addresses, is valid only for a the current process. This field also holds the pointer to the base of the ``roving'' VME window section created by the TVI_CS_VMEWINDOW service (see below). [cmd_a_mvi] Pointer to global section as mapped by this process. [cmd_a_top] Address of the top of the CM global section. [cmd_a_cqhbot] Pointer to the CM queue header array in the CM global section. Used to validate queue handles. [cmd_a_cqhtop] Pointer to end of the CM queue header array in the CM global section. Used to validate queue handles. [cmd_a_baabot] Pointer to the base of the CM block allocation areas in the CM global section. Used to validate block handles. [cmd_a_baatop] Pointer to the top of the CM block allocation areas in the CM global section. Used to validate block handles. [cmd_a_itwmr] Pointer to the TVI map register used for the ``transient'' window by the TVI services. A primary use of this window will be to trigger interrupts which require the touching of specific VME addresses. This window will be moved (at elevated IPL) to map the VME address to be touched. This field is unused by TURBOchannel front ends. [cmd_a_itw] Pointer to the ``transient'' window address range as mapped into the virtual address space of the VAX process. See the above explanation for cmd_a_itwmr. This field is unused by TURBOchannel front ends. [cmd_a_viq] Virtual address of the VBI FIFO interrupt queue used by VAX processes to generate interrupts. [cmd_a_csr] Virtual address of the TURBOchannel CSR used by VAX processes to preset for operations. [cmd_a_vbi] Virtual address of the VBI module. [cmd_l_exitsts] This field overlays cmd_a_top in the variant Common Memory descriptor procedure by the TVI_CS_VMEWINDOW routine. This field stores the exit status for the internally-declared exit handler used to release the lock on the ``roving'' VME window. [cmd_l_vwba] This field overlays cmd_a_cqhtop in the variant Common Memory descriptor produced by the TVI_CS_VMEWINDOW routine. This field stores the VME base address of the TVI window. It is setup by the TVI_CS_VMEMAP routine and used in the TVI_CS_VMEPOINTER routine. [cmd_r_ehblk] This is the exit handler block passed to the $DCLEXH system service by the VME_CS_VMEWINDOW routine to setup the internal exit handler.

struct CMDescriptor {  /* Normal format */
    unsigned long cmd_l_check;
    address cmd_a_base;
    struct TVI_MVME_IO *cmd_a_mvi;
    address cmd_a_top;
    struct CQH *cmd_a_cqhbot;
    struct CQH *cmd_a_cqhtop;
    address cmd_a_baabot;
    address cmd_a_baatop;
    unsigned short *cmd_a_itwmr;
    address cmd_a_itw;
    address cmd_a_viq;
    address cmd_a_csr;
    address cmd_a_vbi;
    };

struct CMDescriptor {  /* VMEWINDOW variant */
    unsigned long cmd_l_check;
    address cmd_a_base;
    struct TVI_MVME_IO *cmd_a_qvi;
    unsigned long cmd_l_exitsts;
    unsigned short *cmd_a_mapreg;
    unsigned long cmd_l_vwba;
    address cmd_a_baabot;
    address cmd_a_baatop;
    unsigned short *cmd_a_itwmr;
    address cmd_a_itw;
    struct {
      address ehb_a_link;
      unsigned long (*exit_handler)();
      unsigned long ehb_l_argcnt;
      unsigned long *ehb_a_exitsts;
      unsigned long ehb_l_lockid;
      } cmd_r_ehblk;
    };
The validation check field holds a 32-bit coded integer to describe the ``state'' of the Common Memory descriptor. The check value permits the Common Memory descriptor to have two states of partial and complete initialization. The partial initialization state is setup by the TVI_CS_INIT routine and reflects that the only valid field of the Common Memory descriptor is the pointer to the TVI registers. In the complete initialization state, all the Common Memory descriptor fields are valid. In addition, the validation check can hold a third value indicating that the Common Memory descriptor is the variant produced by the TVI_CS_VMEWINDOW routine. In this variant, the only valid fields are the pointers to the TVI registers and the TVI mapping register used for the ``roving'' VME window, the pointer to the base of (now) the VME window section in the process's VAS and (after a call to TVI_CS_VMEMAP) the VME base address field. Some routines (including TVI_CS_INTERRUPT, TVI_CS_RESETVME and TVI_CS_STATUS) will accept any valid form of the Common Memory descriptor (either state or the variant). The TVI_CS_VMEMAP routine will only accept the variant form and TVI_CS_MAPCM only accepts the partially initialized state. All other routines require a fully initialized Common Memory descriptor.

Queues Information Block

The Queues Information Block (QIB) contains process-specific information on Common Memory queues. An internal copy is maintained by the TVI_US routines and passed in the calling sequences of the TVI_CS_GET and TVI_CS_PUT routines. The fields of the Queues Information Block are:

list [myqh] Pointer to the CM queue header for the VAX return queue for this process. Used as the default return queue by TVI_CS_GET. Used by TVI_CS_PUT to set the return queue handle in CMBs put onto DAE queues. If the multiplexed queue is used, then this points to the real return queue for this specific process (queue without interrupts). [retqh] Pointer to actual CM return queue. If the multiplexed return queue is not used, then this has the same value as myqh, otherwise it points to the input queue of the process. [myid] Longword containing this process's originator identifier to be placed in CMBs put on DAE queues. If the multiplexed return queue is being used, then this is a pointer to the Queue Demux Block (QDB) in the CM for this process. If a normal return queue is used, then this has the same value as myqh. [daeqh] Pointer to the CM queue header defined as the default DAE queue. Used by TVI_CS_GET for reCYCLEd CMBs. [twqh] Pointer to the CM queue header defined as the ``toxic waste'' queue. Used by TVI_CS_GET and TVI_CS_PUT to avoid dropping CM blocks on the floor and losing them as available resources. This queue is periodically examined and emptied by a separate VAX process (). [fqtable] Free list queue table of quadword descriptors of the free queues. Each quadword contains the free block size and a pointer to the free list queue for blocks of that size (see the structure, below). Sorted by block size for efficient searching. [dapqtbl] DAP queue table copied from CM with queue header offsets converted to handles. Used by the TVI_US_DAP$LOCATE routine.

struct QIB {
    struct CQH *myqh;
    unsigned long myid;
    struct CQH *daeqh;
    struct CQH *twqh;
    struct FQL fqtable[QIB_C_MAXFQS];
    struct CQH *dapqtbl[QIB_C_MAXDQS];
    };

struct FQL {
    unsigned long fql_l_size;
    struct CQH *fql_a_qhdr;
    };

Queue Demultiplexing Block

The Queue Demux Block (QDB) is stored in the Common Memory, but only used by the VAX. It is used by the process to redirect CMBs from the input queue (the multiplexed return queue) to the return queues of the real destination processes. The format of the QDB is:

list [qdb_l_pid] Owning process identification. [qdb_l_astadr] Notification AST address in the destination process. [qdb_l_rtnqoff] Offset to header of the destination process return queue in Common Memory. [qdb_b_flags] Flag bits. Currently only the bit is defined. If the flag is set, the process will empty the destination process return queue (to the free lists) if the destination process does not exist.

struct QDB {
    unsigned long qdb_l_pid;
    unsigned long qdb_l_astadr;
    unsigned long qdb_l_rtnqoff;
    unsigned char qdb_b_flags;
    };

#define QDB_V_EINXP 0 #define QDB_M_EINXP 1

Differences with QVI and TVI Implementations

This section is meant for system and application programmers who have written and are planning on writing applications that have ran or will run on either Qbus or TURBOchannel front end machines. A few implementation peculiarities exist between the bus architectures and therefore effect applications that have used QVI system services. This section outlines these differences and suggests some solutions:

Keywords: EPICURE, VME, TVI, Common_Memory.

Distribution:

Normal

Security, Privacy, Legal

rwest@fsus04.fnal.gov