xref: /illumos-gate/usr/src/uts/sun4/sys/dmv.h (revision 657a8c206b913d1ee578fd725f0b25eca5b77253)
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