summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4u/starfire/sys/idn_sigb.h
blob: 9e1d256d9ad3dcbc9208977a50b51e9e20d45327 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
 * All rights reserved.
 *
 * Inter-Domain Network Sigblock Interface.
 *
 * ******************************************************
 * ******************************************************
 * IMPORTANT:	THE DEFINITIONS HERE ARE DUPLICATES OF
 *		THE cbe_idn_sigb.h FILE IN cbe/cbutils.
 *		ANY CHANGES THERE MUST BE RELECTED
 *		HERE AND VICE VERSA.  WE CANNOT INCLUDE
 *		THIS HEADER IN THE BUILD OF CBE.
 * ******************************************************
 * ******************************************************
 */

#ifndef _SYS_IDN_SIGB_H
#define	_SYS_IDN_SIGB_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <sys/types.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _SSP
#include <domain_config.h>
#include <sigblock.h>
#define	_MAX_DOMAINS	MAX_DOMAINS_PER_MACH
#else /* _SSP */
#include <sys/starfire.h>
#include <sys/cpu_sgnblk_defs.h>
#include <sys/cpu_sgn.h>
#define	MAX_BOARDS	STARFIRE_MAX_BOARDS
#define	MAX_DOMAINS	MAX_BOARDS
#define	_MAX_DOMAINS	MAX_DOMAINS
#endif /* _SSP */

#define	SSI_LINK	(('I' << 8) | 0x01)
#define	SSI_UNLINK	(('I' << 8) | 0x02)
#define	SSI_INFO	(('I' << 8) | 0x03)
#define	SSI_ACK		0x10

#define	VALID_IDNSIGBCMD(c)	((((c) & ~SSI_ACK) == SSI_LINK) || \
				(((c) & ~SSI_ACK) == SSI_UNLINK) || \
				(((c) & ~SSI_ACK) == SSI_INFO))

/*
 * SSI_LINK
 * timeout field must be first.
 */
typedef struct {
	int32_t		timeout;	/* seconds */
	int32_t		cpuid;
	int32_t		domid;
	int32_t		master_pri;
} idnsb_link_t;


/*
 * SSI_UNLINK
 * timeout field must be first.
 *
 * If both cpuid and domid are specified then they must match the
 * correct domain from the local domain's perspective.  The cpuid
 * and/or domid have precedence over the boardset parameter.
 * The boardset parameter is provided if the caller is unable to
 * determine the cpuid/domid of the target domain.  This may happen
 * if the target domain is currently down.
 *
 * idnsb_unlink_t.force values.
 */
#define	SSIFORCE_OFF	0
#define	SSIFORCE_SOFT	1
#define	SSIFORCE_HARD	2

typedef struct {
	int32_t		timeout;	/* seconds */
	int32_t		cpuid;
	int32_t		domid;
	ushort_t	boardset;
	short		force;
	ushort_t	idnset;
} idnsb_unlink_t;


/*
 * SSI_INFO
 *	Assumes max of 16 boards/domain.
 *
 * idnsb_info_t.idn_active values.
 */
#define	SSISTATE_INACTIVE	0
#define	SSISTATE_BUSY		1
#define	SSISTATE_ACTIVE		2

typedef struct {
	ushort_t	domain_boardset[_MAX_DOMAINS];
	uchar_t		idn_active;
	uchar_t		idn_state;	/* same as GSTATE */
	uchar_t		local_index;
	uchar_t		local_cpuid;
	uchar_t		master_index;
	uchar_t		master_cpuid;
	ushort_t	awol_domset;
	ushort_t	conn_domset;
	ushort_t	_filler;
} idnsb_info_t;

#define	INIT_IDNKERR(ep) \
		(bzero((caddr_t)(ep), sizeof (idnsb_error_t)))
#define	SET_IDNKERR_ERRNO(ep, err)	((ep)->k_errno = (int)(err))
#define	SET_IDNKERR_IDNERR(ep, err)	((ep)->k_idnerr = (int)(err))
#define	SET_IDNKERR_PARAM0(ep, p0)	((ep)->k_param[0] = (uint_t)(p0))
#define	SET_IDNKERR_PARAM1(ep, p1)	((ep)->k_param[1] = (uint_t)(p1))
#define	SET_IDNKERR_PARAM2(ep, p2)	((ep)->k_param[2] = (uint_t)(p2))
#define	GET_IDNKERR_ERRNO(ep)		((ep)->k_errno)
#define	GET_IDNKERR_IDNERR(ep)		((ep)->k_idnerr)
#define	GET_IDNKERR_PARAM0(ep)		((ep)->k_param[0])
#define	GET_IDNKERR_PARAM1(ep)		((ep)->k_param[1])
#define	GET_IDNKERR_PARAM2(ep)		((ep)->k_param[2])

#define	IDNKERR_DRV_DISABLED	0x100	/* IDN driver disabled */
					/* param=none */
#define	IDNKERR_DATA_LEN	0x101	/* invalid length of idnsb_data_t */
					/* p0=length */
#define	IDNKERR_INFO_FAILED	0x102	/* SSI_INFO failed */
					/* param=none */
#define	IDNKERR_INVALID_DOMAIN	0x103	/* invalid domain specified */
					/* p0=domid, p1=cpuid */
#define	IDNKERR_INVALID_FORCE	0x104	/* invalid force option specified */
					/* p0=force */
#define	IDNKERR_INVALID_CMD	0x105	/* invalid IDN/SSI command req */
					/* p0=cmd */
#define	IDNKERR_INVALID_WTIME	0x106	/* invalid waittime specified */
					/* p0=waittime */
#define	IDNKERR_SMR_CORRUPTED	0x107	/* SMR memory is corrupted */
					/* p0=domid (against who detected) */
#define	IDNKERR_CPU_CONFIG	0x108	/* missing a cpu per board */
					/* p0=domid */
#define	IDNKERR_HW_ERROR	0x109	/* error programming hardware */
					/* p0=domid */
#define	IDNKERR_SIGBINTR_LOCKED	0x10a	/* sigbintr is locked */
#define	IDNKERR_SIGBINTR_BUSY	0x10b	/* sigbintr is busy working */
#define	IDNKERR_SIGBINTR_NOTRDY	0x10c	/* sigbintr thread not ready */
#define	IDNKERR_CONFIG_FATAL	0x10d	/* fatal error during config */
#define	IDNKERR_CONFIG_MULTIPLE	0x10e	/* multiple config conflicts */
					/* p0=domid, p1=count */
	/*
	 * For all CONFIG errors:
	 *	p0=domid, p1=expected, p2=actual.
	 */
#define	IDNKERR_CONFIG_MTU	0x10f	/* MTU configs conflict */
#define	IDNKERR_CONFIG_BUF	0x110	/* SMR_BUF_SIZE conflicts */
#define	IDNKERR_CONFIG_SLAB	0x111	/* slab-size conflicts */
#define	IDNKERR_CONFIG_NWR	0x112	/* NWR sizes conflict */
#define	IDNKERR_CONFIG_NETS	0x113	/* MAX_NETS conflict */
#define	IDNKERR_CONFIG_MBOX	0x114	/* MBOX_PER_NETS conflict */
#define	IDNKERR_CONFIG_NMCADR	0x115	/* Number of MCADRS conflicts */
#define	IDNKERR_CONFIG_MCADR	0x116	/* Missing MCADR */
#define	IDNKERR_CONFIG_CKSUM	0x117	/* checksum setting conflicts */
#define	IDNKERR_CONFIG_SMR	0x118	/* master's SMR too large */

typedef struct {
	int		k_errno;
	int		k_idnerr;
	uint_t		k_param[3];
} idnsb_error_t;

typedef struct {
	union {
		int		_ssb_timeout;	/* link & unlink only (secs) */
		idnsb_link_t	_ssb_link;
		idnsb_unlink_t	_ssb_unlink;
		idnsb_info_t	_ssb_info;
	} _u;
	idnsb_error_t	ssb_error;
} idnsb_data_t;

#define	ssb_timeout	_u._ssb_timeout
#define	ssb_link	_u._ssb_link
#define	ssb_unlink	_u._ssb_unlink
#define	ssb_info	_u._ssb_info


/*
 * Boot information set by IDN driver when loaded.
 * SSIEVENT_BOOT Indicates IDN driver is ready for linking.
 *		 If this nibble is cleared (0) it
 *		 indicates domain has halted.
 * SSIEVENT_AWOL Indicates local IDN has reported
 *		 some domains (boards) have gone AWOL.
 * (event_handled) is primarily used by SSP/CB applications for
 * synchronization with respect to handling event triggered in (event).
 * The respective bits from (event) are set in (event_handled)
 * when the event has been successfully processed by IDNevent(SSP).
 * It is cleared by CBE based TCL scripts (mon_signatures.tcl, idn.tcl)
 * when event is detected and needs processing.
 * SSIEVENT_VERSION represents the version of the SSP side of
 * the IDN software.  While idnsb_event_t.version represents the
 * version of the OS side of the IDN software.
 *
 * Protocol:	Host				SSP
 *		----				---
 *		event
 *		- 1 -> evt[].e_handled
 *		- X -> evt[].e_event
 *		- Y -> evt[].e_event_data
 *		- 0 -> evt[].e_handled
 *					(!evt[].e_handled)
 *					...process(evt[].e_event)
 *					- evt[].e_handled_data =
 *							evt[].e_event_data
 *					- evt[].e_handled = 1
 */
#define	SSIEVENT_COOKIE		"IDN"
#define	SSIEVENT_COOKIE_LEN	3
#define	SSIEVENT_VERSION	1

#define	SSIEVENT_BOOT		0	/* index to evt[] */
#define	_SSIEVENT_BOOT_VAL	0xb
#define	_SSIEVENT_BOOT_SHIFT	(SSIEVENT_BOOT << 2)
#define	_SSIEVENT_BOOT_MASK	(_SSIEVENT_BOOT_VAL << _SSIEVENT_BOOT_SHIFT)

#define	SSIEVENT_AWOL		1
#define	_SSIEVENT_AWOL_VAL	0xa
#define	_SSIEVENT_AWOL_SHIFT	(SSIEVENT_AWOL << 2)
#define	_SSIEVENT_AWOL_MASK	(_SSIEVENT_AWOL_VAL << _SSIEVENT_AWOL_SHIFT)

#define	SSIEVENT_NUM		2	/* actual max simultaneous events */
#define	SSIEVENT_MAXNUM		3	/* last one in reserve */

#define	_SSIEVENT_VALUE(i) \
	((i == 0) ? _SSIEVENT_BOOT_VAL : ((i == 1) ? _SSIEVENT_AWOL_VAL : 0))

#define	_SSIEVENT_MASKS(i) \
	((i == 0) ? _SSIEVENT_BOOT_MASK : ((i == 1) ? _SSIEVENT_AWOL_MASK : 0))
/*
 * Get a bitmask of the current "state".
 */
#define	SSIEVENT_GET_STATE_MASK(s) \
	(((s).idn_evt[SSIEVENT_BOOT].e_event ? _SSIEVENT_BOOT_MASK : 0) \
	| ((s).idn_evt[SSIEVENT_AWOL].e_event ? _SSIEVENT_AWOL_MASK : 0))

#define	SSIEVENT_GET_STATE(s, e) \
			((s).idn_evt[e].e_event ? _SSIEVENT_VALUE(e) : 0)
#define	SSIEVENT_CLR_STATE(s, e) \
			((s).idn_evt[e].e_event = 0)
#define	SSIEVENT_SET_STATE(s, e) \
			((s).idn_evt[e].e_event = _SSIEVENT_VALUE(e))

/*
 * Get a bitmask of the currently handled states.
 */
#define	SSIEVENT_GET_HANDLED_MASK(s) \
	(((s).idn_evt[SSIEVENT_BOOT].e_handled ? _SSIEVENT_BOOT_MASK : 0) \
	| ((s).idn_evt[SSIEVENT_AWOL].e_handled ? _SSIEVENT_AWOL_MASK : 0))

#define	SSIEVENT_GET_HANDLED(s, e) \
			((s).idn_evt[e].e_handled ? _SSIEVENT_VALUE(e) : 0)
#define	SSIEVENT_CLR_HANDLED(s, e) \
			((s).idn_evt[e].e_handled = 0)
#define	SSIEVENT_SET_HANDLED(s, e) \
			((s).idn_evt[e].e_handled = _SSIEVENT_VALUE(e))
#define	SSIEVENT_SET_HANDLED_DATA(s, e, d) \
			((s).idn_evt[e].e_handled_data = (ushort_t)(d))
#define	SSIEVENT_GET_HANDLED_EVT(i, e) \
				((i).e_handled ? _SSIEVENT_VALUE(e) : 0)
#define	SSIEVENT_CLR_HANDLED_EVT(i)	((i).e_handled = 0)
#define	SSIEVENT_SET_HANDLED_EVT(i, e)	((i).e_handled = _SSIEVENT_VALUE(e))

/*
 * Check for the state of a particular event within a state bitmask.
 */
#define	SSIEVENT_CHK_STATE_MASK(m, e) \
	((((m) & (0xf << ((e) << 2))) == _SSIEVENT_MASKS(e)) ? 1 : 0)
#define	SSIEVENT_CHK_HANDLED_MASK(m, e)	SSIEVENT_CHK_STATE_MASK((m), (e))

/*
 * Build the state mask managed in the cbe to represent the state
 * of the respective events above.
 */
#define	SSIEVENT_DEL_STATE_MASK(m, e)	((m) &= ~(0xf << ((e) << 2)))
#define	SSIEVENT_ADD_STATE_MASK(m, e) \
		(SSIEVENT_DEL_STATE_MASK((m), (e)), \
		((m) |= _SSIEVENT_MASKS(e)))
#define	SSIEVENT_STATE_MASK	(_SSIEVENT_BOOT_MASK | _SSIEVENT_AWOL_MASK)
#define	SSIEVENT_STATE_NIL	0

#ifdef _KERNEL
#define	SSIEVENT_SET(s, e, d) { \
		SSIEVENT_SET_HANDLED(*(s), (e)); \
		membar_stst_stld(); \
		SSIEVENT_SET_STATE(*(s), (e)); \
		(s)->idn_evt[e].e_event_data = (ushort_t)(d); \
		membar_stst_stld(); \
		SSIEVENT_CLR_HANDLED(*(s), (e)); \
}
#define	SSIEVENT_CLEAR(s, e, d) { \
		SSIEVENT_SET_HANDLED(*(s), (e)); \
		membar_stst_stld(); \
		SSIEVENT_CLR_STATE(*(s), (e)); \
		(s)->idn_evt[e].e_event_data &= (ushort_t)~(d); \
		membar_stst_stld(); \
		SSIEVENT_CLR_HANDLED(*(s), (e)); \
}
#define	SSIEVENT_ADD(s, e, d) { \
		SSIEVENT_SET_HANDLED(*(s), (e)); \
		membar_stst_stld(); \
		SSIEVENT_SET_STATE(*(s), (e)); \
		(s)->idn_evt[e].e_event_data |= (ushort_t)(d); \
		membar_stst_stld(); \
		SSIEVENT_CLR_HANDLED(*(s), (e)); \
}
#define	SSIEVENT_DEL(s, e, d) { \
		SSIEVENT_SET_HANDLED(*(s), (e)); \
		membar_stst_stld(); \
		(s)->idn_evt[e].e_event_data &= (ushort_t)~(d); \
		if ((s)->idn_evt[e].e_event_data != 0) { \
			SSIEVENT_SET_STATE(*(s), (e)); \
			membar_stst_stld(); \
			SSIEVENT_CLR_HANDLED(*(s), (e)); \
		} else { \
			membar_stst_stld(); \
			SSIEVENT_CLR_STATE(*(s), (e)); \
		} \
}
#endif /* _KERNEL */

typedef struct idnevent {
	uchar_t		e_event;
	uchar_t		e_handled;
	ushort_t	e_event_data;
	ushort_t	e_handled_data;
	ushort_t	reserved;
} idnevent_t;

/*
 * IMPORTANT: This data structure must be the size of a sigbmbox_t
 *	      so that it fits in the space it steals in the sigblock.
 *            Also, any changes to this structure must be cross-checked
 *	      with (struct idnsb) in <sun4u1/sys/idn.h> with respect
 *	      the area from reserved1 on down.
 */
#define	IDNSB_EVENT_SIZE	(sizeof (sigbmbox_t))
typedef struct {
	struct _idnsb_event {
		union {
			struct {
				char	_cookie[SSIEVENT_COOKIE_LEN];
				uchar_t	_version;
			} _ss;
			struct {
				uint_t	_cookie : 24;
				uint_t	_version : 8;
			} _sn;
		} _u;
		uint_t		_reserved1;	/* reserved for IDN driver */
		idnevent_t	_evt[SSIEVENT_MAXNUM];
	} _s;

		/* reserved for IDN driver */
	char	reserved2[IDNSB_EVENT_SIZE - sizeof (struct _idnsb_event)];
} idnsb_event_t;

#define	idn_evt			_s._evt
#define	idn_reserved1		_s._reserved1
#define	idn_cookie_str		_s._u._ss._cookie
#define	idn_version_byte	_s._u._ss._version
#define	idn_cookie		_s._u._sn._cookie
#define	idn_version		_s._u._sn._version

#ifdef	__cplusplus
}
#endif

#endif /* _SYS_IDN_SIGB_H */