root/usr/src/uts/sun4v/io/n2piupc/n2piupc_tables.h
/*
 * 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 */