fpc-kstats.c revision ae53df47ce6510c89a72cb9868322dc60bce861b
/*
* 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
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <fpc.h>
/*
* CLEAR_PIC is needed by busstat to extract the current event type of a PIC.
* There will be an entry for CLEAR_PIC in each fi_kev_mask_t table below, but
* they are different from the other entries in that busstat won't show them to
* the user.
*/
#define DEVICE_NAME_LEN 4
#define PIC_STR_LEN 12
/*
* Data structure used to build array of event-names and pcr-mask values
*/
typedef struct fi_kev_mask {
char *event_name;
typedef struct fi_ksinfo {
} fi_ksinfo_t;
static fi_ksinfo_t *fi_jbc_kstat;
/*
* Below are event lists, which map an event name specified on the commandline
* with a value to program the event register with.
*
* The last entry will be the mask of the entire event field for the PIC and
* counter type.
*/
/*
* JBC performance events.
*/
static fi_kev_mask_t
fire_jbc_events[] = {
};
/*
* IMU performance events
*/
static fi_kev_mask_t
fire_imu_events[] = {
};
/*
* MMU performance events
*/
static fi_kev_mask_t
fire_mmu_events[] = {
};
/*
* TLU performance events for counters 0 and 1
*/
static fi_kev_mask_t
fire_tlu_events[] = {
};
/*
* TLU performance events for counter 2
*/
static fi_kev_mask_t
fire_tlu2_events[] = {
};
/*
* LPU performance events
*/
static fi_kev_mask_t
fire_lpu_events[] = {
};
int
{
int avail;
return (DDI_FAILURE);
if (avail & PCIE_A_REGS_AVAIL)
num_inst++;
if (avail & PCIE_B_REGS_AVAIL)
num_inst++;
for (i = jbc; i < MAX_REG_TYPES; i++) {
if (i == jbc) {
if (avail & JBUS_REGS_AVAIL) {
return (DDI_FAILURE);
}
} else {
if (!num_inst)
break;
return (DDI_FAILURE);
}
}
return (DDI_SUCCESS);
}
static int
{
int i, base_cntrid, num_cntrs;
char dev_name[DEVICE_NAME_LEN];
switch (reg_group) {
case imu:
break;
case mmu:
break;
case lpu:
break;
case tlu:
num_events2 = sizeof (fire_tlu2_events) /
sizeof (fi_kev_mask_t);
break;
case jbc:
break;
default:
return (FAILURE);
}
for (i = 0; i < num_inst; i++) {
KM_SLEEP);
ksinfop->pic_leaf_id = i;
else
/*
* All error cleanup (deleting kstats and freeing memory) is
* done in fire_kstat_fini. So we need to save the ksinfop
* pointer before any possible error exit so fire_kstat_fini
* can find it.
*/
fi_imu_kstats[i] = ksinfop;
fi_mmu_kstats[i] = ksinfop;
fi_lpu_kstats[i] = ksinfop;
fi_tlu_kstats[i] = ksinfop;
/* Create basic pic event-type pair (only once) */
if (i == 0) {
base_cntrid = 0;
/* The extra counter for TLU is handled separately */
num_cntrs--;
goto err;
/*
* extra counter for TLU. The events associated with
* this third counter are different from the events
* for the first and second counters.
*/
base_cntrid += num_cntrs;
num_cntrs = 1;
!= SUCCESS)
goto err;
}
}
/* create counter kstats */
goto err;
}
return (SUCCESS);
err:
return (FAILURE);
}
static int
{
int i;
#ifdef DEBUG
#endif
return (FAILURE);
}
return (SUCCESS);
}
/*
* Create the picN kstat. Returns a pointer to the
* kstat which the driver must store to allow it
* to be deleted when necessary.
*/
static kstat_t *
{
int event;
char pic_name[PIC_STR_LEN];
struct kstat_named *pic_named_data;
return (NULL);
}
/*
* Fill up data section of the kstat
* Write event names and their associated pcr masks.
* num_ev - 1 is because CLEAR_PIC is added separately.
*/
}
/*
* add the clear_pic entry
*/
#ifdef DEBUG
FPC_DBG2("fpc_create_picN_kstat: name %s, pic %d, num_ev %d, "
#endif
return (picN_ksp);
}
/*
* Create the "counters" kstat.
*/
static kstat_t *
{
int i;
char pic_str[PIC_STR_LEN];
struct kstat *counters_ksp;
struct kstat_named *counters_named_data;
#ifdef DEBUG
FPC_DBG1("fpc_create_cntr_kstat: name: %s instance: %d\n",
#endif
/*
* Size of kstat is num_pics + 1. extra one for pcr.
*/
return (NULL);
}
for (i = 0; i < num_pics; i++) {
}
/*
* Store the reg type and other info. in the kstat's private field
* so that they are available to the update function.
*/
return (counters_ksp);
}
/*
*/
static int
{
struct kstat_named *data_p;
if (rw == KSTAT_WRITE) {
#ifdef DEBUG
FPC_DBG2("fpc_cntr_kstat_update: wr %ld\n",
#endif
return (EIO);
} else {
counters[2] = 0;
return (EIO);
}
#ifdef DEBUG
FPC_DBG2("fpc_cntr_kstat_update: rd event %ld, cntr0"
#endif
}
return (0);
}
void
{
int i;
#ifdef DEBUG
FPC_DBG1("fpc_kstat_fini called\n");
#endif
for (i = 0; i < NUM_LEAVES; i++) {
/* IMU */
if (fi_imu_kstats[i] != NULL) {
fi_imu_kstats[i] = NULL;
}
/* MMU */
if (fi_mmu_kstats[i] != NULL) {
fi_mmu_kstats[i] = NULL;
}
/* LPU */
if (fi_lpu_kstats[i] != NULL) {
fi_lpu_kstats[i] = NULL;
}
/* TLU */
if (fi_tlu_kstats[i] != NULL) {
fi_tlu_kstats[i] = NULL;
}
}
/* JBC */
if (fi_jbc_kstat != NULL) {
fi_jbc_kstat = NULL;
}
(void) fpc_perfcnt_module_fini(dip);
}
static void
{
int i;
for (i = 0; i < NUM_MAX_COUNTERS; i++) {
}
}
}