n2piupc_tables.h revision ea1a228c80597366447774aa1988868492330eb5
/*
* 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 */