Home | History | Annotate | Download | only in sys
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright (c) 1998 by Sun Microsystems, Inc.
     24  * All rights reserved.
     25  */
     26 
     27 #ifndef _SYS_DMV_H
     28 #define	_SYS_DMV_H
     29 
     30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31 
     32 #ifdef	__cplusplus
     33 extern "C" {
     34 #endif
     35 
     36 #ifndef _ASM
     37 #include <sys/inttypes.h>
     38 #endif
     39 
     40 
     41 /*
     42  * Definitions for databearing mondo vector facility.  See PSARC 1998/222 for
     43  * more details.
     44  */
     45 
     46 /*
     47  * DMV layout.
     48  *
     49  *		  +--+----------------+----------+---------------------------+
     50  *		  |63|62            61|60      48|47                        0|
     51  *		  +--+----------------+----------+---------------------------+
     52  *	Word 0:   | 1| reserved (MBZ) | dmv_inum | device private data       |
     53  *		  +--+----------+----------------+---------------------------+
     54  *	Word 1-7: | device private data                                      |
     55  *		  +----------------------------------------------------------+
     56  */
     57 
     58 #define	DMV_INUM_SHIFT		48
     59 #define	DMV_INUM_MASK		0x1FFF
     60 #define	DMV_PRIVATE_MASK	0xFFFFFFFFFFFF
     61 
     62 /*
     63  * The following macro is designed to allow the construction of the first
     64  * word of a DMV in software, for instance for testing purposes.
     65  */
     66 #define	DMV_MAKE_DMV(dmv_inum, dev_private) \
     67 	((UINT64_C(1) << 63) | \
     68 	    ((((uint64_t)(dmv_inum)) & UINT64_C(DMV_INUM_MASK)) <<  \
     69 	    DMV_INUM_SHIFT) | \
     70 	    (((uint64_t)(dev_private)) & UINT64_C(DMV_PRIVATE_MASK)))
     71 
     72 #define	DMV_IS_DMV(irdr0)	(((uint64_t)(irdr0)) >> 63)
     73 
     74 
     75 /*
     76  * Version control for the dmv interfaces.
     77  */
     78 
     79 #define	DMV_INTERFACE_MAJOR_VERSION	1
     80 #define	DMV_INTERFACE_MINOR_VERSION	1
     81 
     82 #ifndef _ASM
     83 
     84 extern int dmv_interface_major_version;
     85 extern int dmv_interface_minor_version;
     86 
     87 int dmv_add_intr(int dmv_inum, void (*routine)(), void *arg);
     88 int dmv_add_softintr(void (*routine)(void), void *arg);
     89 int dmv_rem_intr(int dmv_inum);
     90 
     91 /*
     92  * The following macros are for use with the intr_add_cpu and
     93  * intr_rem_cpu functions.  These functions allow a driver to choose
     94  * a CPU to be targeted by a device's interrupts, and also allow
     95  * interrupt retargeting when a CPU is taken offline.  The macros
     96  * convert a databearing inum to (and from) a value which will not
     97  * clash with an ordinary inum, thus allowing both values to coexist
     98  * in the same linked list.
     99  *
    100  * If a driver registers at least one soft interrupt handler for each
    101  * databearing mondo is uses, and keeps track of the correspondence
    102  * between them, it could also use the soft interrupt inum as input to
    103  * intr_add_cpu.
    104  */
    105 
    106 #define	DMV_INUM_2_INUM(i)	(((i) | 0x8000) << 16)
    107 #define	INUM_2_DMV_INUM(i)	(((i) >> 16) & 0x1FFF)
    108 
    109 /*
    110  * DMV dispatch table entry.
    111  *
    112  * Note on consistency: we want to ensure that if dmv_func is valid, then
    113  * dmv_arg is as well.  We don't want to have to do any locking in the
    114  * interrupt handler, so instead we do the following:
    115  *
    116  * 1. When we initialize an entry, we set dmv_arg first, then do a membar #sync,
    117  *    then set dmv_func.
    118  *
    119  * 2. When we clear an entry, we only clear dmv_func.
    120  *
    121  * 3. When the interrupt handler uses an entry, it uses either an ldx (in
    122  *    the 32-bit kernel) or an atomic quad load (in the 64-bit kernel) to
    123  *    get a matching func/arg pair.  If func is zero, there is no handler and
    124  *    we discard the interrupt.
    125  */
    126 
    127 struct dmv_disp {
    128 	void (*dmv_func)(void);
    129 	void *dmv_arg;
    130 };
    131 
    132 #endif	/* _ASM */
    133 
    134 #ifdef	__cplusplus
    135 }
    136 #endif
    137 
    138 #endif	/* _SYS_DMV_H */
    139