summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4v/io/n2piupc/n2piupc_tables.h
blob: 93dcbdba9a37768bbe7687e1fd2d0015582917d8 (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
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (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 2006 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_N2PIUPC_TABLES_H
#define	_N2PIUPC_TABLES_H

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

/*
 * Table definitions for the N2 PIU performance counter driver.
 *
 * Each table consists of one or more groups of counters.
 *
 * A counter group will a name (used by busstat as the kstat "module" name),
 * have its own set of kstats, and a common event select register.  A group is
 * represented as an n2piu_grp_t.
 *
 * Each counter is represented by an n2piu_cntr_t.  Each has its own register
 * offset (or address), bits for the data it represents, plus an associated
 * register for zeroing it.
 *
 * All registers for n2piu are 64 bit, but a size field can be entered into this
 * structure if registers sizes vary for other implementations (as if this code
 * is leveraged for a future driver).
 *
 * A select register is represented by an n2piu_regsel_t.  This defines the
 * offset or address, and an array of fields which define the events for each
 * counter it services.  All counters need to have an entry in the fields array
 * even if they don't have any representation in a select register.  Please see
 * the explanation of the events array (below) for more information.  Counters
 * without representation in a select register can specify their (non-existant)
 * select register field with mask NONPROG_DUMMY_MASK and offset
 * NONPROG_DUMMY_OFF.
 *
 * This implementation supports only one select register per group.  If more
 * are needed (e.g. if this implementation is used as a template for another
 * device which has multiple select registers per group) the data structures can
 * easily be changed to support an array of them.   Add an array index in the
 * counter structure to associate that counter with a particular select
 * register, and add a field for the number of select registers in the group
 * structure.
 *
 * Each counter has an array of programmable events associated with it, even if
 * it is not programmable.  This array is a series of name/value pairs defined
 * by n2piu_event_t.  The value is the event value loaded into the select
 * register to select that event for that counter.  The last entry in the array
 * is always an entry with a bitmask of LSB-aligned bits of that counter's
 * select register's field's width;  it is usually called the CLEAR_PIC entry.
 * CLEAR_PIC entries are not shown to the user.
 *
 * Note that counters without programmable events still need to define a
 * (small) events array with at least CLEAR_PIC and a single event, so that
 * event's name can display in busstat output.  The CLEAR_PIC entry of
 * nonprogrammable counters can have a value of NONPROG_DUMMY_MASK.
 */

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/kstat.h>
#include "n2piupc_acc.h"

/*
 * Description of a counter's events.  Each counter will have an array of these,
 * to define the events it can be programmed to report.  Nonprogrammable
 * counters still need an array of these, to contain the name busstat will
 * display for it, and a CLEAR_PIC entry.
 */
typedef struct n2piu_event {
	char *name;
	uint64_t value;
} n2piu_event_t;

/*
 * Description of a counter's event selection.  There will be one entry for
 * each counter in the group.
 */
typedef struct n2piu_regsel_fld {
	n2piu_event_t *events_p;
	int num_events;		/* Size of events array. */
	uint64_t event_mask;	/* Width of the event field. */
	int event_offset;	/* Offset of the event field. */
} n2piu_regsel_fld_t;

#define	NUM_EVTS(x)	(sizeof (x) / sizeof (n2piu_event_t))

/*
 * Description of a group's select register.
 */
typedef struct n2piu_regsel {
	off_t regoff;			/* Register offset or address. */
	n2piu_regsel_fld_t *fields_p;	/* select reg subfield descriptions.  */
	int num_fields;			/* Size of the fields array. */
} n2piu_regsel_t;

#define	NUM_FLDS(x)	(sizeof (x) / sizeof (n2piu_regsel_fld_t))

/*
 * Counter description, including its access logistics and how to zero it.
 */
typedef struct n2piu_cntr {
	off_t regoff;		/* Register offset or address. */
	uint64_t fld_mask;	/* Width of the active part of the register */
	off_t zero_regoff;	/* Offset of register used to zero counter. */
	uint64_t zero_value;	/* Value to write to zero_regoff, to clr cntr */
} n2piu_cntr_t;

#define	FULL64BIT	-1ULL	/* Can use this for fld_mask. */

/*
 * Group description.
 */
typedef struct n2piu_grp {
	char *grp_name;		  /* Name, shows up as busstat "module" name. */
	n2piu_regsel_t *regsel_p; /* Select register. */
	n2piu_cntr_t *counters_p; /* Counter definitions. */
	int num_counters;	  /* Size of the counters array. */
	kstat_t **name_kstats_pp; /* Named kstats.  One for all instances. */
} n2piu_grp_t;

#define	NUM_CTRS(x) (sizeof (x) / sizeof (n2piu_cntr_t))

/* N2PIU-specific definitions. */

/* Where groups are in the leaf_grps array. */

#define	NUM_GRPS	4
#define	IMU_GRP		0
#define	MMU_GRP		1
#define	PEU_GRP		2
#define	BIT_ERR_GRP	3

/* The table itself. */
extern n2piu_grp_t *leaf_grps[];

/* Standin symbol for when there is no register. */
#define	NO_REGISTER			(off_t)-1ULL

/*
 * Default event values used in n2piu_event_t structures for non-programmable
 * registers.
 */
#define	NONPROG_DUMMY_MASK	0
#define	NONPROG_DUMMY_OFF	0

/*
 * Event bitmask definitions for all groups.
 */
#define	IMU_CTR_EVT_MASK	0xffull
#define	IMU_CTR_0_EVT_OFF	0
#define	IMU_CTR_1_EVT_OFF	8

#define	MMU_CTR_EVT_MASK	0xffull
#define	MMU_CTR_0_EVT_OFF	0
#define	MMU_CTR_1_EVT_OFF	8

#define	PEU_CTR_01_EVT_MASK	0xffull
#define	PEU_CTR_2_EVT_MASK	0x3ull
#define	PEU_CTR_0_EVT_OFF	0
#define	PEU_CTR_1_EVT_OFF	8
#define	PEU_CTR_2_EVT_OFF	16

#define	BTERR_CTR_0_EVT_MASK	0x1ull
#define	BTERR_CTR_0_EVT_OFF	0

/*
 * Fake the biterr event register to be one with two fields, to store the
 * overall enable/disable event (looks like pic0 reset) and the bterr3 events.
 */

#define	BTERR_CTR_3_EVT_MASK	0xfull
#define	BTERR_CTR_3_EVT_OFF	0

/*
 * Note: this "event" is really an enable, and it serves all 4 PICs.
 *
 * PICs 0,1,2 are from the first counter, PIC3 is from the second counter.
 */
#define	BTERR_CTR_ENABLE_MASK	0x1ull
#define	BTERR_CTR_ENABLE_OFF	63

#define	BTERR_CTR_ENABLE	(BTERR_CTR_ENABLE_MASK << BTERR_CTR_ENABLE_OFF)

/*
 * This register also has a bit to zero the counters.
 */
#define	BTERR_CTR_CLR_MASK	0x1ull
#define	BTERR_CTR_CLR_OFF	62

#define	BTERR_CTR_CLR		(BTERR_CTR_CLR_MASK << BTERR_CTR_CLR_OFF)

#define	BTERR_CTR_ENABLE_AND_CLR	(BTERR_CTR_ENABLE | BTERR_CTR_CLR)

/*
 * Definitions of the different types of events.
 *
 * The first part says which registers these events are for.
 * For example, IMU01 means the IMU performance counters 0 and 1
 */

/* String sought by busstat to locate the event field width "event" entry. */
#define	COMMON_S_CLEAR_PIC			"clear_pic"


#define	IMU01_S_EVT_NONE			"event_none"
#define	IMU01_S_EVT_CLK				"clock_cyc"
#define	IMU01_S_EVT_TOTAL_MONDO			"total_mondo"
#define	IMU01_S_EVT_TOTAL_MSI			"total_msi"
#define	IMU01_S_EVT_NAK_MONDO			"mondo_nak"
#define	IMU01_S_EVT_EQ_WR			"eq_write"
#define	IMU01_S_EVT_EQ_MONDO			"eq_mondo"

#define	IMU01_EVT_NONE				0
#define	IMU01_EVT_CLK				1
#define	IMU01_EVT_TOTAL_MONDO			2
#define	IMU01_EVT_TOTAL_MSI			3
#define	IMU01_EVT_NAK_MONDO			4
#define	IMU01_EVT_EQ_WR				5
#define	IMU01_EVT_EQ_MONDO			6


#define	MMU01_S_EVT_NONE			"event_none"
#define	MMU01_S_EVT_CLK				"clock_cyc"
#define	MMU01_S_EVT_TRANS			"total_transl"
#define	MMU01_S_EVT_STALL			"total_stall_cyc"
#define	MMU01_S_EVT_TRANS_MISS			"total_transl_miss"
#define	MMU01_S_EVT_TBLWLK_STALL		"tblwlk_stall_cyc"
#define	MMU01_S_EVT_BYPASS_TRANSL		"bypass_transl"
#define	MMU01_S_EVT_TRANSL_TRANSL		"transl_transl"
#define	MMU01_S_EVT_FLOW_CNTL_STALL		"flow_stall_cyc"
#define	MMU01_S_EVT_FLUSH_CACHE_ENT		"cache_entr_flush"

#define	MMU01_EVT_NONE				0
#define	MMU01_EVT_CLK				1
#define	MMU01_EVT_TRANS				2
#define	MMU01_EVT_STALL				3
#define	MMU01_EVT_TRANS_MISS			4
#define	MMU01_EVT_TBLWLK_STALL			5
#define	MMU01_EVT_BYPASS_TRANSL			6
#define	MMU01_EVT_TRANSL_TRANSL			7
#define	MMU01_EVT_FLOW_CNTL_STALL		8
#define	MMU01_EVT_FLUSH_CACHE_ENT		9


#define	PEU2_S_EVT_NONE				"event_none"
#define	PEU2_S_EVT_NONPST_CMPL_TIME		"npost_compl_time"
#define	PEU2_S_EVT_XMIT_DATA			"xmit_data"
#define	PEU2_S_EVT_RCVD_DATA			"rcvd_data"

#define	PEU2_EVT_NONE				0
#define	PEU2_EVT_NONPST_CMPL_TIME		1
#define	PEU2_EVT_XMIT_DATA			2
#define	PEU2_EVT_RCVD_DATA			3


#define	PEU01_S_EVT_NONE			"event_none"
#define	PEU01_S_EVT_CLK				"clock_cyc"
#define	PEU01_S_EVT_COMPL			"compl_recvd"
#define	PEU01_S_EVT_XMT_POST_CR_UNAV		"post_cr_unav_cyc"
#define	PEU01_S_EVT_XMT_NPOST_CR_UNAV		"npost_cr_unav_cyc"
#define	PEU01_S_EVT_XMT_CMPL_CR_UNAV		"compl_cr_unav_cyc"
#define	PEU01_S_EVT_XMT_ANY_CR_UNAV		"trans_cr_any_unav"
#define	PEU01_S_EVT_RETRY_CR_UNAV		"retry_cr_unav"
#define	PEU01_S_EVT_MEMRD_PKT_RCVD		"recvd_mem_rd_pkt"
#define	PEU01_S_EVT_MEMWR_PKT_RCVD		"recvd_mem_wr_pkt"
#define	PEU01_S_EVT_RCV_CR_THRESH		"recv_cr_thresh"
#define	PEU01_S_EVT_RCV_PST_HDR_CR_EXH		"recv_hdr_cr_exh_cyc"
#define	PEU01_S_EVT_RCV_PST_DA_CR_MPS		"recv_post_da_cr_mps"
#define	PEU01_S_EVT_RCV_NPST_HDR_CR_EXH		"recv_npost_hdr_cr_exh"
#define	PEU01_S_EVT_RCVR_L0S			"recvr_l0s_cyc"
#define	PEU01_S_EVT_RCVR_L0S_TRANS		"recvr_l0s_trans"
#define	PEU01_S_EVT_XMTR_L0S			"trans_l0s_cyc"
#define	PEU01_S_EVT_XMTR_L0S_TRANS		"trans_l0s_trans"
#define	PEU01_S_EVT_RCVR_ERR			"recvr_err"
#define	PEU01_S_EVT_BAD_TLP			"bad_tlp"
#define	PEU01_S_EVT_BAD_DLLP			"bad_dllp"
#define	PEU01_S_EVT_REPLAY_ROLLOVER		"replay_rollover"
#define	PEU01_S_EVT_REPLAY_TMO			"replay_to"

#define	PEU01_EVT_NONE				0x0
#define	PEU01_EVT_CLK				0x1
#define	PEU01_EVT_COMPL				0x2
#define	PEU01_EVT_XMT_POST_CR_UNAV		0x10
#define	PEU01_EVT_XMT_NPOST_CR_UNAV		0x11
#define	PEU01_EVT_XMT_CMPL_CR_UNAV		0x12
#define	PEU01_EVT_XMT_ANY_CR_UNAV		0x13
#define	PEU01_EVT_RETRY_CR_UNAV			0x14
#define	PEU01_EVT_MEMRD_PKT_RCVD		0x20
#define	PEU01_EVT_MEMWR_PKT_RCVD		0x21
#define	PEU01_EVT_RCV_CR_THRESH			0x22
#define	PEU01_EVT_RCV_PST_HDR_CR_EXH		0x23
#define	PEU01_EVT_RCV_PST_DA_CR_MPS		0x24
#define	PEU01_EVT_RCV_NPST_HDR_CR_EXH		0x25
#define	PEU01_EVT_RCVR_L0S			0x30
#define	PEU01_EVT_RCVR_L0S_TRANS		0x31
#define	PEU01_EVT_XMTR_L0S			0x32
#define	PEU01_EVT_XMTR_L0S_TRANS		0x33
#define	PEU01_EVT_RCVR_ERR			0x40
#define	PEU01_EVT_BAD_TLP			0x42
#define	PEU01_EVT_BAD_DLLP			0x43
#define	PEU01_EVT_REPLAY_ROLLOVER		0x44
#define	PEU01_EVT_REPLAY_TMO			0x47

/*
 * BTERR counter 3 is presented by the device as one register with 8 different
 * counters.  Since busstat displays in decimal and not in hex, display of the
 * raw data is impractical except to make a non-zero test.  Fake that this
 * register has multiple modes, so that each lane can be shown separately.
 * Then one can use Busstat capabilities to display alternating events of a
 * register.
 */

#define	BTERR3_S_EVT_NONE			"event_none"
#define	BTERR3_S_EVT_ENC_ALL			"encd_err_ln_all"
#define	BTERR3_S_EVT_ENC_LANE_0			"encd_err_ln_0"
#define	BTERR3_S_EVT_ENC_LANE_1			"encd_err_ln_1"
#define	BTERR3_S_EVT_ENC_LANE_2			"encd_err_ln_2"
#define	BTERR3_S_EVT_ENC_LANE_3			"encd_err_ln_3"
#define	BTERR3_S_EVT_ENC_LANE_4			"encd_err_ln_4"
#define	BTERR3_S_EVT_ENC_LANE_5			"encd_err_ln_5"
#define	BTERR3_S_EVT_ENC_LANE_6			"encd_err_ln_6"
#define	BTERR3_S_EVT_ENC_LANE_7			"encd_err_ln_7"

#define	BTERR3_EVT_ENC_NONE			0
#define	BTERR3_EVT_ENC_ALL			1
#define	BTERR3_EVT_ENC_LANE_0			2
#define	BTERR3_EVT_ENC_LANE_1			3
#define	BTERR3_EVT_ENC_LANE_2			4
#define	BTERR3_EVT_ENC_LANE_3			5
#define	BTERR3_EVT_ENC_LANE_4			6
#define	BTERR3_EVT_ENC_LANE_5			7
#define	BTERR3_EVT_ENC_LANE_6			8
#define	BTERR3_EVT_ENC_LANE_7			9

/*
 * For non-programmable registers, include an n2piu_event_t which has two
 * fields, a default field (which gives the field a name even though it
 * can't be programmed, and clear_pic which busstat needs.
 */
#define	BTERR2_S_EVT_PRE			"phys_rcvr_errs"

#define	BTERR2_EVT_PRE				0

#define	BTERR1_S_EVT_BTLP			"bad_tlps"

#define	BTERR1_EVT_BTLP				0

/*
 * Note: All 4 biterr counter fields (split among two counter registers) are
 * tied together with a single enable.  Treat the first field as programmable
 * to provide a way to reset the counter set.
 */
#define	BTERR0_S_EVT_RESET	"reset_bterr"	/* All biterr counter zero */
#define	BTERR0_S_EVT_BDLLP	"bad_dllps"

#define	BTERR0_EVT_RESET	0
#define	BTERR0_EVT_BDLLP	1

/*
 * First bit error counter register has three counters.  Here are the
 * placements of these counters within the (virtual) registers.
 */
#define	BE1_BAD_DLLP_MASK	0xff000000ULL
#define	BE1_BAD_TLP_MASK	0xff0000ULL
#define	BE1_BAD_PRE_MASK	0x3ffULL
#define	BE2_8_10_MASK		FULL64BIT

#ifdef	__cplusplus
}
#endif

#endif	/* _N2PIUPC_TABLES_H */