Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ iconnect(2) — CX/UX 6.20

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

uistat(1)

ienable(2)

mpadvise(2)

server_block(2)

spl_request(3C)

iconnect(2)

NAME

iconnect − user-level interrupt connection

SYNOPSIS

#include <sys/types.h>
#include <sys/iconnect.h>

int iconnect (command, arg)
int command;
union {
struct icon_conn ∗ic;
struct icon_ivec ∗ii;
struct icon_stat ∗is;
int vector;
} arg;

DESCRIPTION

The iconnect() system service allows the calling process to define an user-level interrupt connection to an external interrupt, to disconnect another process from an external interrupt, to allocate/deallocate interrupt vectors, and to return status information on interrupt vector connections or allocations.  This system service requires that the USERINT option be configured into the kernel.  The argument command may be:

ICON_CONN define an interrupt connection. 

ICON_DISC disconnect the connected process from the interrupt (if one is connected) and undefine the user-level interrupt connection. 

ICON_IVEC allocate or deallocate interrupt vectors. 

ICON_STAT return status information on allocated or connected interrupt vectors. 
 

CONNECTION DEFINITION

If command is ICON_CONN, then the arg parameter points to an icon_conn structure. 
 
The contents of the icon_conn structure include the following members:
 

int ic_version;/∗ should be IC_VERSION1 ∗/
u_int ic_flags;/∗ flags ∗/
int ic_vector;/∗ vector number ∗/
void (∗ic_routine)(); /∗ address of user interrupt routine ∗/
int ic_stack;/∗ address of user interrupt stack ∗/
int ic_value;/∗ value passed to interrupt routine ∗/

 
The ic_version field must contain a value of IC_VERSION1. 
 
The ic_flags field may be zero, or may contain any of the following bits:

IC_KROUTINE
if set, then also call the kernel device driver interrupt routine for this interrupt.  The kernel interrupt routine is called after the user-level interrupt routine has been executed.

IC_DEBUG if set, then the console processor will be entered on the first occurrence of the user-level interrupt.  Since user-level interrupt handlers execute at interrupt level, the user level debuggers, such as adb(1) and dbx(1), may not be used to debug user-level interrupt handlers.  However, the console processor may be used to provide some debugging capability for user-level interrupt handlers.  The console processor may be used as an assembler-level debugger that has the ability to display and modify registers and memory, set breakpoints, single step through instructions, disassemble instructions, and symbolically display variable and routine names. 
 
See the CX/UX Programmer’s Guide manual for more information on debugging user-level interrupt handlers. 

IC_LSHM if set, then allow the user-level interrupt process to be attached to shared memory region(s) that are bound to local memory.  (Usually checked during the process’s ienable(2) call.)  See the RESTRICTIONS section for more details. 

The ic_vector field contains the interrupt vector number to be connected to the user-level interrupt routine.  This vector number should be previously determined from one of several methods:
 

For the CX/UX or customer written device drivers that support user-level interrupts, the vector number should have been given to the process via a IOCTLVECNUM ioctl(2) system service call.  This command will return the base interrupt vector number for that device. 
 
The process has made an ICON_IVEC iconnect() call which ’allocated’ a vector that the process’s user-level device driver will configure the device to use. 
 
The system administrator statically reserved a specific vector in the interrupt vector table when the kernel was built, and this vector is being used for a device that will interrupt with this vector number.

 
The ic_routine field should contain the process’s user-level interrupt routine virtual address. 
 
The ic_stack field should contain the virtual address of the process’s data area that will be used as a stack area during execution of the user-level interrupt routine. 
 
The ic_value field should contain a value that will be passed to the user-level interrupt routine as the only parameter.  This value will always be passed to the user-level interrupt routine for the specified external interrupt. 
 
Upon return from the iconnect() call, the caller must make an ienable(2) system service call to enable the interrupt connection.  See ienable(2) for more information on enabling the interrupt. 
 

DISCONNECTING AND UNDEFINING A CONNECTION

If command is equal to ICON_DISC, then the arg parameter should contain the interrupt vector number of the interrupt to be disconnected/undefined.  If a process was blocked in an ienable(2) system service call for the specified interrupt, it will be unblocked (see ienable(2) for more information). 
 
If a process has defined an interrupt connection via a ICON_CONN command, but has not yet made an ienable(2) system service call, it may issue a ICON_DISC iconnect() call to clear its own user-level interrupt connection definition.  If a process that has defined a user-level interrupt connection terminates after making an iconnect(2) call without ever making an ienable(2) call, the user-level interrupt connection definition will automatically be removed from the system, allowing another process to define an user-level interrupt connection for this previously defined interrupt vector. 

DYNAMIC INTERRUPT VECTOR ALLOCATION

If command is equal to ICON_IVEC, then the arg parameter should point to an icon_ivec structure.  The contents of the icon_ivec structure include the following members:

u_int ii_flags;/∗ flags ∗/
int ii_nvect;/∗ number of vectors needed or returning ∗/
int ii_vector;/∗ base vector - only if II_VECSPEC or ... ∗/
/∗ ... II_DEALLOCATE is set. ∗/

The ii_nvect field specifies the number of interrupt vectors to be allocated or deallocated.  When multiple vectors are specified, they are always allocated or deallocated in a contiguous block of vectors. 
 
The ii_vector field specifies the first vector to be deallocated when the II_DEALLOCATE bit is set in the ii_flags field.  It also can specify the first vector to be allocated if the II_VECSPEC bit is set in the ii_flags field. 
 
If the II_EVEN_VECTOR bit is set in the ii_flags field, then the first vector allocated will be an even vector number. 
 
Once a vector has been allocated with the ICON_IVEC command, it may then be used on a ICON_CONN command as the vector to be connected.
 
Regardless of whether the vector is used on subsequent ICON_CONN and ICON_DISC commands, it will remain ’allocated’ until a II_DEALLOCATE ICON_IVEC command is issued for this vector.  The process that makes the vector allocation call is not directly associated with the allocated interrupt vector(s).  For example, if the process that allocates an interrupt vector exits or does not use the vector, the vector will remain in an allocated state. A different process may connect to this vector, or deallocate it, as long as it has the proper system access.
 
The uistat(1) program will display all vectors allocated via the ICON_IVEC command, and it will also have an option which will allow for the deallocation of ’allocated’ vectors. 
 
When iconnect() successfully allocates interrupt vector(s), it will return the (first) vector number that was allocated.  When iconnect() successfully deallocates/frees interrupt vector(s), it will return a value of zero. 
 

OBTAINING STATUS INFORMATION

If command is equal to ICON_STAT, then the arg parameter should point to an icon_stat structure. 
 
The contents of the icon_stat structure include the following members:
 

u_int is_flags;/∗ flags ∗/
int is_vector;/∗ -1 or interrupt vector number ∗/
pid_t is_pid;/∗ process id ∗/
u_int is_state;/∗ connection state, see below ∗/

 
Two mutually exclusive bits in the is_flags field specify the method for obtaining the user-level interrupt vector information.  If the IS_SPEC bit is set, then the interrupt vector information pertaining to the interrupt vector specified in is_vector will be returned. 
 
If the IS_SCAN bit is set in the is_flags field, or if the IS_SPEC bit is not set, then this call will scan, in ascending interrupt vector number order, for the next connected or allocated interrupt vector in the system.  The point where the forward scan begins is determined from the is_vector field that is supplied by the caller. 
 
When the is_vector field is equal to -1, the kernel will scan beginning with interrupt vector 0 for first allocated or connected vector.  When the is_vector field contains an interrupt vector number (also supplied by the caller), then the kernel will scan for the next higher interrupt vector that is allocated or connected in the system.  In other words, the scan will begin at the value in the is_vector field + 1. 
 
In scan mode, when the next allocated or connected interrupt vector is found, the kernel always returns that vector number in the is_vector field. 
 
Therefore, by initially setting the is_vector field to a -1, a caller may obtain information on all allocated and connected interrupt vectors in the system by making repeated iconnect() system service calls with the same icon_stat structure, until an unsuccessful status is returned. 
 
On successful ICON_STAT calls, the is_state field will contain the state of the interrupt vector.  The valid bits that may be set within is_state are:

IS_CONN The interrupt vector in the is_vector field has been successfully connected via an ICON_CONN iconnect() system service call.  The is_pid field will contain the process id of the process that made the ICON_CONN command iconnect() call. 

IS_ENABLED The interrupt vector in the is_vector field has been successfully enabled via an ienable(2) system service call.  The is_pid field will contain the process id of the process that made the ienable(2) system service call. 

IS_IVEC The interrupt vector in the is_vector field has been successfully allocated with an ICON_IVEC iconnect() system service call.  If the IS_CONN bit is not also set, then the is_pid field will be -1, since no process is currently associated with this interrupt vector.  However, if the IS_CONN bit is also set, then the is_pid field will contain the process id of the process that made the ICON_CONN comand iconnect(2) system service call. 

IS_PENDING The interrupt vector in the is_vector field is currently going through a transition from the iconnected to the ienabled state.  This state is short-lived and therefore, this bit will not normally be set. 

RESTRICTIONS

The following restrictions and limitations applies to a process that connects to an external interrupt:
 
A process must be super-user, or must have the ACC_USERINT access vector bit set (if access vectors are configured) to successfully use the iconnect(2) system service. 
 
A process may only connect to one external interrupt.  Further, only one process may be connected to an interrupt at any point in time.
 
The process that connects to an external interrupt must make an ienable(2) system service call.  This call will put the process into a blocked state in the kernel and will enable the process’s interrupt connection.  The process will no longer execute at normal program level,  but will only execute at interrupt level in user mode, in the user-level interrupt routine when the connected external interrupt becomes active. 
 
Processes that execute user-level interrupt routines should not use the profiling support, such as profil(2), and monitor(3C), since erroneous information will result. 
 
The user-level debuggers, such as adb(1) and dbx(1), may not be used to debug user-level interrupt routines.  Debugging of user-level interrupt routines must be done with the console debugger.  For more information on using the console processor debugging capabilities, see the the appropriate architecture’s Console Processor Reference Manual.
 
Not all CX/UX devices will allow a process to iconnect() to its interrupt(s).  Only the following CX/UX devices will support the user-level interrupt routine feature.  All these devices will support the IOCTLVECNUM ioctl(2) command, which returns the base interrupt vector number for that device.  If any of these devices are to be connected to a user-level interrupt routine, then they should be placed in the system configuration file:
 

The HVME Reflective Memory Driver
The Ikon Model 10089 DR11W Emulator Driver
The Edge Triggered Interrupt Driver
The VMIC-HSD Device Driver
The Real-time Clock Device Driver

 
For performance reasons, when a user-level interrupt process has bound some portion of its address space to local memory, it should ensure that the cpu receiving the connected interrupt be located on the same cpu board where the process’s local memory resides. For example, if a process binds some portion of its address space to local memory, and then makes the necessary iconnect() and ienable () system service calls, there is no guarantee that the cpu receiving the connected interrupt will be a cpu residing on the same cpu board where the process has bound its local memory.  Since foreign local memory accesses (see memory(7)) are much slower than other types of memory accesses, this situation should be avoided.  Therefore, if a user-level interrupt process plans to bind to local memory, it should be careful to bind to the local memory of the cpu that will be receiving the interrupt.  See mpadvise(2) and the CX/UX Programmer’s Guide manual for information on determining the cpu assignment for a given interrupt. 
 
In addition to the above local memory performance issues, it is not possible to maintain cache coherency on Series 4000 systems for shared memory regions that are bound to local memory that is foreign to the cpu that is executing the user-level interrupt routine.  Therefore, on all systems with multiple cpu boards, a user-level interrupt process may not be attached to a shared memory region that is bound to local memory at the time the process makes its ienable(2) system service call, unless the IC_LSHM bit was set in the ic_flags field of the icon_conn structure during the iconnect() call.  When this bit is set, an error will not be returned by ienable(2).  However, in this case, it is entirely up to the user to create any shared memory regions in the correct local memory pool before the user-level interrupt process attaches itself to them.  See the ienable(2) man page for details on the status returned for this error. 

NOTES

The following is a list of some of the attributes of user-level interrupt routines.  For a complete list and additional details, see the CX/UX Programmer’s Guide.
 
There is one parameter passed to an interrupt routine; this is the value that was specified in the ic_value field of the icon_conn structure on the iconnect() call. 
 
A user-level interrupt process is entered in user mode, with the connected interrupt level still active.
 
A user-level interrupt routine may reference any memory that is within the address space of that process, including VME I/O space that has been previously bound into the process’s address space. However, the process must have previously (before the ienable () call) locked down any memory within its address space that is referenced by its interrupt routine.  All types of exceptions, such as page faults and floating point exceptions, are fatal while in a user-level interrupt routine. 
 
Almost all kernel system service calls may not be called from a user-level interrupt routine.  However, a user-level interrupt routine may make server_wake1(2) and server_wakevec(2) system service calls. 
 
The user-level interrupt process may also call other routines, but it must eventually exit the interrupt routine via an explicit or implicit return from within the same routine where the interrupt handling initially started (the routine whose address was specified in the ic_routine field of the icon_conn structure on the iconnect() system service call). 

RETURN VALUE

Upon successful completion, a value of zero is returned for the ICON_DISC, ICON_CONN, ICON_STAT and ICON_IVEC vector deallocation commands.  For the ICON_IVEC vector allocation command, the (first) vector number is returned, if successful.  Otherwise, for all commands, a value of -1 is returned and errno is set to indicate the error. 

ERRORS

If any of the following conditions occur, iconnect() will return -1 and set errno to the corresponding value:

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

[EINVAL] Invalid version number (ICON_CONN), invalid command, invalid vector number, invalid number of vectors (ICON_IVEC) was specified. 

[EINVAL] An ICON_STAT command was specified, and invalid is_flags bits, or both IS_SCAN and IS_SPEC is_flags bits were specified. 

[EINVAL] The iconnect(2) system service is not configured in this kernel.  This service requires that the USERINT option be specified in the system configuration file. 

[EBUSY] An ICON_CONN command was specified and the process already has an interrupt connection defined.  An ICON_DISC command must be issued before a new ICON_CONN command may be issued. 

[EBUSY] An ICON_CONN command was specified and another process is already connected to the specified interrupt. 

[EBUSY] An ICON_DISC command was specified, and the interrupt to be disconnected was currently being connected to the user-level interrupt process by modification of the interrupt vector table.  Retry the ICON_DISC command. 

[EBUSY] An ICON_IVEC command was specified with the II_DEALLOCATE option, and the vector specified currently has a user-level interrupt definition.  An ICON_DISC command must first be issued for this vector. 

[EBUSY] An ICON_IVEC command was specified with the II_VECSPEC option, and the specified vector(s) are already allocated. 

[ENOSPC] An ICON_IVEC command was specified to allocate vectors, and there are not enough free vectors in the interrupt vector table to satisfy the request. 

[ENOMEM] The IC_DEBUG option was specified, and the system was unable to properly create a private text region. 

[ENOTCONN] An ICON_DISC command was specified, and the vector specified currently has no user-level interrupt routine connection defined. 

[ENOTCONN] An ICON_IVEC command was specified with the II_DEALLOCATE option, and the vector(s) specified was not ’allocated’.  When this error is returned, no vectors are deallocated, even if multiple vector deallocation was specified. 

[ENOTCONN] An ICON_STAT command was specified with the IS_SPEC bit set in the is_flags field and the specified interrupt vector was not currently allocated or connected, or the command was specified with the IS_SCAN bit set in the is_flags field and there were no additional allocated or connected interrupt vectors in the system. 

[EFAULT] The icon_conn , icon_ivec , or icon_stat structure pointer is not a valid user space address. 

SEE ALSO

CX/UX Programmer’s Guide,
uistat(1), ienable(2), mpadvise(2), server_block(2), spl_request(3C)

CX/UX Programmer’s Reference Manual

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