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) 1999 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #ifndef _BUSSTAT_H 28 #define _BUSSTAT_H 29 30 /* 31 * busstat works by reading and writing from/to kstat's which are 32 * exported by drivers on the system. 33 * 34 * busstat parses the command line it is given and builds up a 35 * pair of linked list's to represent the various options specified. 36 * An example command line is given below.. 37 * 38 * -w ac2,pic0=wio_pkts,pic1=rbio_pkts -w ac2,pic0=rto_pkts,pic1=rto_pkts -r ac5 39 * ============================================================================= 40 * 41 * ______ 42 * | | 43 * | ac2|->wio_pkts->rto_pkts 44 * |pic0| | | 45 * | | -------<------ 46 * ------ 47 * | 48 * | 49 * ______ 50 * | | 51 * | ac2|->rbio_pkts->rto_pkts 52 * |pic1| | | 53 * | | --------<----- 54 * ------ 55 * | 56 * | 57 * ______ 58 * | | 59 * | ac5|->evt 60 * |pic0| 61 * | | 62 * ------ 63 * | 64 * | 65 * ______ 66 * | | 67 * | ac5|->evt 68 * |pic1| 69 * | | 70 * ------ 71 * 72 * The above diagram shows the lists created after the initial parsing. 73 * 74 * Each device instance/pic is represented by a device node. Hanging off 75 * that is at least one event node. 76 * 77 * Event nodes come in two different types. Nodes that are the result of a -r 78 * operation will have the r_w field in their parent dev_node set to EVT_READ, 79 * and most of their other fields set to zero or NULL. An event node that was 80 * created because of a -w operation (r_w = EVT_WRITE) will have all it's fields 81 * filled in. When a device node is created, an event node is automatically 82 * created and marked as EVT_READ. If the device node was created as the result 83 * of a -r operation, nothing more happens. But if it was a -w operation, then 84 * the event node is modified (r_w changed to EVT_WRITE, event pcr mask and 85 * event name written if known). 86 * 87 * Setting events : work along the list of dev_nodes, for each device node check 88 * the event node pointed to by evt_node, if it is marked as EVT_WRITE in the 89 * corresponding r_w array, if so set the event stored in the node. 90 * 91 * Reading events : work along the list of dev_nodes, for each device node check 92 * the event node pointed to by evt_node, if it is marked EVT_WRITE, just read 93 * the event count from the appropiate PIC and store it in the node. If the node 94 * is EVT_READ however, read the PCR, determine the event name, store it in the 95 * node along with the event count. 96 * 97 * Multiplexing is handled by cycling through the event nodes. The event nodes 98 * are on a circular list, which allows each pic to be multiplexing between 99 * different numbers of events. 100 */ 101 102 #define TRUE 1 103 #define FALSE 0 104 #define FAIL -1 105 106 #define READ_EVT 1 107 #define WRITE_EVT 0 108 109 #define EVT_READ 0x1 110 #define EVT_WRITE 0x2 111 #define ONE_INST_CALL 0x4 112 #define ALL_INST_CALL 0x8 113 114 #define STATE_INIT 0x10 /* Initial state of node when created */ 115 #define STATE_INST 0x20 /* Node was created by specific instance call */ 116 #define STATE_ALL 0x40 /* Node was created by call for all instances */ 117 118 #define NANO 1000000000 /* To convert from nanosecs to secs */ 119 120 #define PIC_STR_LEN 3 121 122 #define EVT_STR -1 123 124 typedef struct evt_node { 125 char evt_name[KSTAT_STRLEN]; /* The event name */ 126 uint64_t prev_count; /* The previous count for this evt */ 127 uint64_t total; /* Total count for this event */ 128 uint64_t evt_pcr_mask; /* PCR mask for this event */ 129 struct evt_node *next; 130 } evt_node_t; 131 132 typedef struct dev_node { 133 char name[KSTAT_STRLEN]; /* Device name e.g. ac */ 134 int dev_inst; /* Device instance number */ 135 int pic_num; /* PIC number. */ 136 kstat_t *cnt_ksp; /* "counters" kstat pointer */ 137 kstat_t *pic_ksp; /* pointer to picN kstat */ 138 int r_w; /* r_w flag */ 139 int state; /* state flag */ 140 struct evt_node *evt_node; /* ptr to current evt_node */ 141 struct dev_node *next; 142 } dev_node_t; 143 144 #endif /* _BUSSTAT_H */ 145