1
0
Files
2022-09-29 17:59:04 +03:00

893 lines
21 KiB
C

/**************************************************************************
* *
* Copyright (C) 1996, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#if SA_DIAG
#include "sys/types.h"
#include "sys/cpu.h"
#include "sys/sbd.h"
#include <fault.h>
#include "setjmp.h"
#include "libsc.h"
#include "libsk.h"
#include "uif.h"
#include <sys/xtalk/xbow_info.h>
#include <sys/nic.h>
#include "sa.h"
extern xbowreg_t dump_xbow_regs(__psunsigned_t, int);
extern void print_xbow_link_regs(xb_linkregs_t *, int, int);
extern void print_xbow_perf_ctrs(xbow_t *xb);
extern void dump_widget_regs(widget_cfg_t *wp);
extern int xbow_link_alive(volatile __psunsigned_t xbow_base, int link);
extern int xbow_link_present(volatile __psunsigned_t xbow_base, int link);
extern int xbow_link_status(volatile __psunsigned_t xbow_base, int link);
extern void reset_xbow_link(__psunsigned_t xbow_base, int link);
/*
* xbow utility
*/
static const char xb_str[] = "xb";
static xbow_t *xb;
static widget_cfg_t *wid;
static int perf_enbled;
/*
* flags
*/
#define XBF_LINKOK 0x0001 /* LINKOK flag */
#define XBF_NICREAD 0x0002 /* read NIC for testing */
#define XBF_REGRD 0x0004 /* read wid registers for testing */
#define XBF_REGWR 0x0008 /* write wid registers for testing */
#define XBF_VERBOSE 0x8000 /* VERBOSE flag */
static uint f_flags;
static void
ff_flag(struct SaFlag *flp, int on)
{
printf("xb: %s (%s) 0x%x turned %s\n",
flp->name, flp->help, flp->bit, (on)?"ON":"OFF");
}
static struct SaFlag xbf[] = {
/* flags bit help (*func)(struct SaFlag *, int) */
{ "link_ok", XBF_LINKOK, "link port OK", ff_flag },
{ "nic_rd", XBF_NICREAD, "read NIC", ff_flag },
{ "reg_rd", XBF_REGRD, "read REGS", ff_flag },
{ "reg_wr", XBF_REGWR, "write REGS", ff_flag },
{ "verb", XBF_VERBOSE, "verbose", ff_flag },
{ 0 },
};
/*
* xb variables
*/
static int v_link; /* default link ID */
static int v_perfa; /* default perfa link */
static int v_perfb; /* default perfb link */
static int v_perfa_mode; /* mode values: count src (1), dst (2) */
static int v_perfb_mode; /* input pkt buf level (3) */
static int v_deltat; /* perf sampling period */
static int v_count; /* iteration count */
static int v_resetloop;
static int v_reg0;
static int v_reg1;
static int v_reg2;
static int v_reg3;
static int v_reg4;
static int v_reg5;
static int v_reg6;
static int v_reg7;
static int v_reg8;
static int v_reg9;
static int v_regf0;
static int v_regf1;
static int v_regf2;
static int v_regf3;
static int v_regf4;
static int v_regf5;
static int v_regf6;
static int v_regf7;
static int v_regf8;
static int v_regf9;
static volatile ulong perfa_prev_ticks, perfb_prev_ticks;
static xbow_perfcount_t xperfa_prev, xperfb_prev;
#define RD 0x1
#define WR 0x2
#define RDWR 0x4
static void
xb_init_vars (void)
{
f_flags = XBF_VERBOSE | XBF_REGRD |XBF_REGWR;
v_count = 1;
v_resetloop = -1;
v_reg0 = WIDGET_ID;
v_regf0 = ((RD) << 4) | sizeof(uint32_t);
v_reg1 = WIDGET_STATUS;
v_regf1 = ((RD) << 4) | sizeof(uint32_t);
v_reg2 = WIDGET_ERR_UPPER_ADDR;
v_regf2 = ((RD) << 4) | sizeof(uint32_t);
v_reg3 = WIDGET_ERR_LOWER_ADDR;
v_regf3 = ((RD) << 4) | sizeof(uint32_t);
v_reg4 = WIDGET_CONTROL;
v_regf4 = ((RD|WR|RDWR) << 4) | sizeof(uint32_t);
v_reg5 = WIDGET_REQ_TIMEOUT;
v_regf5 = ((RD|WR|RDWR) << 4) | sizeof(uint32_t);
v_reg6 = WIDGET_INTDEST_UPPER_ADDR;
v_regf6 = ((RD|WR|RDWR) << 4) | sizeof(uint32_t);
v_reg7 = WIDGET_INTDEST_LOWER_ADDR;
v_regf7 = ((RD|WR|RDWR) << 4) | sizeof(uint32_t);
v_reg8 = WIDGET_ERR_CMD_WORD;
v_regf8 = ((RD) << 4) | sizeof(uint32_t);
v_reg9 = WIDGET_LLP_CFG;
v_regf9 = ((RD|WR|RDWR) << 4) | sizeof(uint32_t);
}
static void
vf_link(struct SaVar *varp, int val)
{
*varp->val = val;
if (xtalk_probe(xb, val)) {
f_flags |= XBF_LINKOK;
wid = (widget_cfg_t *)K1_MAIN_WIDGET(v_link);
} else {
printf("WARNING no widget in port (0x%x)\n", val);
wid = 0;
f_flags &= ~XBF_LINKOK;
}
}
static void
vf_perf_mode(struct SaVar *varp, int val)
{
printf("%s: ", varp->name);
switch (val) {
case XBOW_MONITOR_NONE:
printf("set to NONE (0x%x)\n", val);
break;
case XBOW_MONITOR_SRC_LINK:
printf("set to SRC_LINK (0x%x)\n", val);
break;
case XBOW_MONITOR_DEST_LINK:
printf("set to DST_LINK (0x%x)\n", val);
break;
case XBOW_MONITOR_INP_PKT:
printf("set to INP PKT (0x%x)\n", val);
break;
default:
printf("bogus mode (0x%x)\n", val);
printf("no action taken\n");
return;
}
*varp->val = val; /* set to v_perfm */
}
void
vf_perf_port(struct SaVar *varp, int val)
{
xbow_perfcount_t xperf;
if (val < BASE_XBOW_PORT || val >= MAX_PORT_NUM)
printf("Bogus, port 0x%x\n", val);
*varp->val = val; /* set to v_perfb */
xperf.xb_counter_val = xb->xb_perf_ctr_b;
xperf.xb_perf.link_select = val - BASE_XBOW_PORT;
if (varp->arg)
xb->xb_perf_ctr_a = xperf.xb_counter_val;
else
xb->xb_perf_ctr_b = xperf.xb_counter_val;
printf("%s: is 0x%x, xb reg set\n", varp->name, val);
}
static struct SaVar xb_vars[] = {
/* name val (*func)(struct SaVar *, int) arg */
{ "link", &v_link, vf_link, 0 },
{ "modea", &v_perfa_mode, vf_perf_mode, 0 },
{ "modeb", &v_perfb_mode, vf_perf_mode, 0 },
{ "porta", &v_perfa, vf_perf_port, 1 },
{ "portb", &v_perfb, vf_perf_port, 0 },
{ "deltat", &v_deltat, 0, 0 },
{ "count", &v_count, 0, 0 },
{ "resetloop", &v_resetloop, 0, 0 },
{ "reg0", &v_reg0, 0, 0 },
{ "r0rw_sz", &v_regf0, 0, 0 },
{ "reg1", &v_reg1, 0, 0 },
{ "r1rw_sz", &v_regf1, 0, 0 },
{ "reg2", &v_reg2, 0, 0 },
{ "r2rw_sz", &v_regf2, 0, 0 },
{ "reg3", &v_reg3, 0, 0 },
{ "r3rw_sz", &v_regf3, 0, 0 },
{ "reg4", &v_reg4, 0, 0 },
{ "r4rw_sz", &v_regf4, 0, 0 },
{ "reg5", &v_reg5, 0, 0 },
{ "r5rw_sz", &v_regf5, 0, 0 },
{ "reg6", &v_reg6, 0, 0 },
{ "r6rw_sz", &v_regf6, 0, 0 },
{ "reg7", &v_reg7, 0, 0 },
{ "r7rw_sz", &v_regf7, 0, 0 },
{ "reg8", &v_reg8, 0, 0 },
{ "r8rw_sz", &v_regf8, 0, 0 },
{ "reg9", &v_reg9, 0, 0 },
{ "r9rw_sz", &v_regf9, 0, 0 },
{ 0 },
};
extern struct reg_desc widget_stat_desc[];
extern struct reg_desc widget_llp_confg_desc[];
extern struct reg_desc xbow_link_status_desc[];
extern struct reg_desc xbow_link_aux_status_desc[];
void
xb_reset_link(int port)
{
widget_cfg_t *wid = (widget_cfg_t *)K1_MAIN_WIDGET(port);
widgetreg_t control = wid->w_control;
reset_xbow_link((__psunsigned_t)XBOW_K1PTR, port);
wid->w_control = control;
if (f_flags & (XBF_VERBOSE))
printf("widget at port=%d reset and re-configed\n",
v_link);
}
int
xb_check_alive(int port)
{
/*
xbow_t *xb = (xbow_t *)XBOW_K1PTR;
xb_linkregs_t *xlk = &xb->xb_link(port);
xbwX_stat_t *linkstatus = (xbwX_stat_t *) &xlk->link_status;
return(linkstatus->xb_linkstatus.alive);
*/
return(xbow_link_status((__psunsigned_t)XBOW_K1PTR, port));
}
/*
* print_llp_errs
*/
void
xb_print_llp_info(int port)
{
xbow_t *xb = (xbow_t *)XBOW_K1PTR;
xb_linkregs_t *xlk = &xb->xb_link(port);
widget_cfg_t *wid = (widget_cfg_t *)K1_MAIN_WIDGET(port);
widgetreg_t x_sts, x_aux, w_sts, x_llp, w_llp;
x_sts = (widgetreg_t)xlk->link_status;
x_aux = (widgetreg_t)xlk->link_aux_status;
x_llp = (widgetreg_t)xb->xb_wid_llp;
w_sts = (widgetreg_t)wid->w_status;
w_llp = (widgetreg_t)wid->w_llp_cfg;
printf("xbow Link(%d):\n", port);
printf(" llp cfg: %R\n",
x_llp, widget_llp_confg_desc);
printf(" status: %R\n",
x_sts, xbow_link_status_desc);
printf(" aux st: %R\n",
x_aux, xbow_link_aux_status_desc);
printf("widget(%d):\n", port);
printf(" llp cfg: %R\n",
w_llp, widget_llp_confg_desc);
printf(" status: %R\n",
w_sts, widget_stat_desc);
}
void
xb_read_nic(int port)
{
char *nic_buf;
bridge_t *bridge;
if (!(f_flags & XBF_NICREAD))
return;
bridge = (bridge_t *)K1_MAIN_WIDGET(port);
nic_buf = malloc(4096);
if (nic_buf == 0) {
printf("cant malloc 4k\n");
return;
}
cfg_get_nic_info((nic_data_t)&bridge->b_nic, nic_buf);
free(nic_buf);
}
#define NUM_WREG_TEST 10
struct widget_reg_rw {
int *offset;
int *flags;
} reg_rw[NUM_WREG_TEST] = {
{ &v_reg0, &v_regf0 },
{ &v_reg1, &v_regf1 },
{ &v_reg2, &v_regf2 },
{ &v_reg3, &v_regf3 },
{ &v_reg4, &v_regf4 },
{ &v_reg5, &v_regf5 },
{ &v_reg6, &v_regf6 },
{ &v_reg7, &v_regf7 },
{ &v_reg8, &v_regf8 },
{ &v_reg9, &v_regf9 },
};
typedef union reg_test_u {
uint8_t u8[8];
uint16_t u16[4];
uint32_t u32[2];
uint64_t u64;
} reg_test_t;
reg_test_t reg_rw_val[NUM_WREG_TEST];
void
xb_reg_write(volatile void *p, reg_test_t *val, int size)
{
switch(size) {
case (sizeof(uint8_t)): {
*(uint8_t *)p = val->u8[7];
break;
}
case (sizeof(uint16_t)): {
*(uint16_t *)p = val->u16[3];
break;
}
case (sizeof(uint32_t)): {
*(uint32_t *)p = val->u32[1];
break;
}
case (sizeof(uint64_t)): {
*(uint64_t *)p = val->u64;
break;
}
default:
break;
}
}
void
xb_reg_read(volatile void *p, reg_test_t *val, int size)
{
val->u64 = 0;
switch(size) {
case (sizeof(uint8_t)): {
val->u8[7] = *(uint8_t *)p;
break;
}
case (sizeof(uint16_t)): {
val->u16[3] = *(uint16_t *)p;
break;
}
case (sizeof(uint32_t)): {
val->u32[1] = *(uint32_t *)p;
break;
}
case (sizeof(uint64_t)): {
val->u64 = *(uint64_t *)p;
break;
}
default:
break;
}
}
void
xb_reg_rw(int port)
{
int i;
widgetreg_t *wreg;
if (!(f_flags | (XBF_REGWR|XBF_REGRD)))
return;
for(i=0; i < NUM_WREG_TEST; i++) {
wreg = (widgetreg_t *) (K1_MAIN_WIDGET(port) | *(reg_rw[i].offset));
/*
* check if we need to pre-load the write value
*/
if (f_flags & XBF_REGWR &&
*(reg_rw[i].flags)>>4 & RDWR) {
xb_reg_read(wreg, &reg_rw_val[i], (*(reg_rw[i].flags))&0xf);
}
if (f_flags & XBF_REGWR && *(reg_rw[i].flags)>>4 & WR) {
xb_reg_write(wreg, &reg_rw_val[i], (*(reg_rw[i].flags))&0xf);
}
if (f_flags & XBF_REGRD && *(reg_rw[i].flags)>>4 & RD) {
xb_reg_read(wreg, &reg_rw_val[i], (*(reg_rw[i].flags))&0xf);
}
if (f_flags & (XBF_VERBOSE))
printf("offset: %x addr %x val %x [%s%s]\n",
*(reg_rw[i].offset), wreg, reg_rw_val[i].u64,
(*(reg_rw[i].flags)>>4 & RD)?"R":"",
(*(reg_rw[i].flags)>>4 & WR)?"W":"");
}
}
/*
* we disable the perf_mode registers
* but we keep the perf_mode variables as is
*/
void
xb_disable_perf(void)
{
volatile ulong heart_tick;
xbow_linkctrl_t ctla, ctlb;
volatile xbowreg_t *xctla, *xctlb;
/*
* set the perf mode on link(perfa) and link(perfb)
*/
xctla = &xb->xb_link_raw[v_perfa-BASE_XBOW_PORT].link_control;
ctla.xbl_ctrlword = *xctla;
ctla.xb_linkcontrol.perf_mode = XBOW_MONITOR_NONE;
xctlb = &xb->xb_link_raw[v_perfb-BASE_XBOW_PORT].link_control;
ctlb.xbl_ctrlword = *xctlb;
ctlb.xb_linkcontrol.perf_mode = XBOW_MONITOR_NONE;
*xctla = ctla.xbl_ctrlword;
*xctlb = ctlb.xbl_ctrlword;
flushbus();
}
void
xb_enable_perf(void)
{
volatile ulong heart_tick;
xbow_linkctrl_t ctla, ctlb;
volatile xbowreg_t *xctla, *xctlb;
/*
* get the initial perf value
*/
xperfa_prev.xb_counter_val = xb->xb_perf_ctr_a;
xperfb_prev.xb_counter_val = xb->xb_perf_ctr_b;
/*
* set the perf mode on link(perfa) and link(perfb)
*/
xctla = &xb->xb_link_raw[v_perfa-BASE_XBOW_PORT].link_control;
ctla.xbl_ctrlword = *xctla;
ctla.xb_linkcontrol.perf_mode = v_perfa_mode;
xctlb = &xb->xb_link_raw[v_perfb-BASE_XBOW_PORT].link_control;
ctlb.xbl_ctrlword = *xctlb;
ctlb.xb_linkcontrol.perf_mode = v_perfb_mode;
/*
* delay the store to the bss based perfa_prev_ticks until
* after we start the counters, for now use save the counter
* to register
*/
heart_tick = HEART_PIU_K1PTR->h_count;
*xctla = ctla.xbl_ctrlword;
*xctlb = ctlb.xbl_ctrlword;
perfa_prev_ticks = perfb_prev_ticks = heart_tick;
flushbus();
}
/*
* usage
*/
static char *ustr[] = {
" - if perf counting enabled same as delta",
" else dump xbow registers",
"dump - dump xbow regs",
"link - dump xbow link regs for slot=<link>",
"linkreset - reset xbow link fregs or slot=<link>",
"wid - dump widget regs at XIO slot=<link>",
"counters - show xbow perf counters a & b",
"llps - show xbow llp config register",
"en - set modea/b to enable perf counters",
"dis - disable enable perf counters",
"delta - show perf counter deltas",
"sample1 - equivalent to 'en wait(deltat) delta dis'",
"sample2 - equivalent to 'en llp delta dis'",
"llp - stress llp, read/write wid regs, read nic",
"llpstat - show xbow and wid stats for link",
" ",
0,
};
/************************ do_command functions ****************************/
/*
* cmd: ?
* print usage help
*/
static int
xb_dousage(int argc, char **argv)
{
sa_usage(xb_str, ustr);
sa_fusage(xb_str); /* flags */
sa_vusage(xb_str); /* variables */
printf("\nexample: start monitoring upkts from bridge to heart for 100 ms\n");
printf("xb flag +reg_rd +reg_wr\n");
printf("xb set modea=1 modeb=2 porta=0xf portb=8 link=0xf deltat=100\n");
printf("xb sample1\n");
printf("\nexample: start monitoring upkts from bridge to heart for 1000 sets of PIO R/W\n");
printf("xb flag +reg_rd +reg_wr\n");
printf("xb set modea=1 modeb=2 porta=0xf portb=8 link=0xf count=1000\n");
printf("xb sample2\n");
return(0);
}
/*
* cmd: flag
* set flags
*/
static int
xb_doflag(int argc, char **argv)
{
return(sa_flag(argc, argv, xb_str, xbf, &f_flags));
}
/*
* cmd: set
* set variable
*/
static int
xb_doset(int argc, char **argv)
{
if(argc < 3)
return(sa_listvars(xb_vars, "xb diag cmd"));
sa_getvars(xb_vars, argv + 2, xb_str);
return(0);
}
/*
* cmd: llpstat
* show llp stats for link n
*/
static int
xb_dollpstats(int argc, char **argv)
{
xb_print_llp_info(v_link);
return(0);
}
static int
xb_dollp(int argc, char **argv)
{
int n = v_count;
while (n--) {
xb_read_nic(v_link);
xb_reg_rw(v_link);
}
return(0);
}
/*
* cmd: dump
* dump registers
*/
static int
xb_dodump(int argc, char **argv)
{
dump_xbow_regs((__psunsigned_t)xb, 0 /* dont clear*/);
return(0);
}
/*
* cmd: link
* dump link(vlink) registers
*/
static int
xb_dolink_regs(int argc, char **argv)
{
print_xbow_link_regs(&xb->xb_link(v_link), v_link, 0);
return(0);
}
/*
* cmd: linkreset
* reset link(vlink)
*/
static int
xb_doody_flush(int argc, char **argv)
{
widget_cfg_t *wid = (widget_cfg_t *)K1_MAIN_WIDGET(v_link);
widgetreg_t control = wid->w_control;
widgetreg_t *wreg, wsav, wxxx;
wreg = (widgetreg_t *) (K1_MAIN_WIDGET(v_link) | v_reg0);
wsav = *wreg;
if (f_flags & (XBF_VERBOSE))
printf("will assert ody flush 0x%x(v0) = 0x%x(v1) for %d(v2)us\n",
wreg, (wsav|v_reg1), v_reg2);
*wreg = (wsav | v_reg1);
wxxx = *wreg;
DELAY(v_reg2);
/**wreg = wsav;*/
reset_xbow_link((__psunsigned_t)XBOW_K1PTR, v_link);
wid->w_control = control;
if (f_flags & (XBF_VERBOSE))
printf("widget at port=%d reset and re-configed\n",
v_link);
return(0);
}
/*
* cmd: linkreset
* reset link(vlink)
*/
static int
xb_dolink_reset(int argc, char **argv)
{
xb_reset_link(v_link);
while (v_resetloop && !xb_check_alive(v_link)) {
xb_reset_link(v_link);
if (v_resetloop > 0)
v_resetloop--;
}
return(0);
}
/*
* cmd: wid
* dump registers for widget at XIO slot (v_link)
*/
static int
xb_dowid_regs(int argc, char **argv)
{
if (v_link < XBOW_PORT_8 || v_link > XBOW_PORT_F) {
printf("bad xio port(%d), set valid link value\n", v_link);
return(0);
}
printf("Widget Registers at XIO port=%d\n", v_link);
dump_widget_regs((widget_cfg_t *)K1_MAIN_WIDGET(v_link));
return(0);
}
/*
* cmd: perf_ctrs
* dump perf registers
*/
static int
xb_doperf_ctrs(int argc, char **argv)
{
print_xbow_perf_ctrs(xb);
return(0);
}
/*
* cmd: retrys
* dump retrys registers
*/
static int
xb_dollpsts(int argc, char **argv)
{
xbow_aux_link_status_t aux_sts;
aux_sts.aux_linkstatus
= xb->xb_link_raw[v_link-BASE_XBOW_PORT].link_aux_status;
printf("link(0x%x): LLP STATS: rcv errs %d, tx retrys %d\n",
v_link,
aux_sts.xb_aux_linkstatus.rx_err_cnt,
aux_sts.xb_aux_linkstatus.tx_retry_cnt);
return(0);
}
static int
xb_doperf_dis(int argc, char **argv)
{
xb_disable_perf();
perf_enbled = 0;
return(0);
}
static int
xb_doperf_en(int argc, char **argv)
{
perf_enbled = 1;
xb_enable_perf();
return(0);
}
#define K(_n) (1000 * (_n))
#define MILL 1000000L
#define BILL 1000000000L
static int
xb_doperf_delta(int argc, char **argv)
{
xbow_perfcount_t xperfa, xperfb;
volatile ulong heart_tick;
ulong d, count, ups, kbs;
xperfa.xb_counter_val = xb->xb_perf_ctr_a;
xperfb.xb_counter_val = xb->xb_perf_ctr_b;
heart_tick = HEART_PIU_K1PTR->h_count;
d = (heart_tick - perfa_prev_ticks) * 80; /* in ns */
/*
* if we rolled over just once its still OK
* if more than once than all bets are off
*/
if (xperfa.xb_perf.count >= xperfa_prev.xb_perf.count)
count = xperfa.xb_perf.count - xperfa_prev.xb_perf.count;
else
count = (XBOW_COUNTER_MASK + 1 - xperfa_prev.xb_perf.count)
+ xperfa.xb_perf.count;
ups = (count * BILL)/d;
if (v_deltat < 1000 && d < BILL)
kbs = ((ups) * (ulong)v_deltat)/1000;
else
kbs = ups;
kbs = ((kbs * 128) + 512)/1024;
printf("Counter Delta:\telapsed time (ns)\tupkts/s\tKB/s\n");
printf(" A: %7d\t%3d,%03d,%03d,%03d\t\t%u\t%u,%03u\n",
count,
d/BILL, (d/MILL) % 1000, (d/1000) % 1000, d % 1000,
ups, kbs/1000, kbs%1000);
d = (heart_tick - perfb_prev_ticks) * 80; /* in ns */
if (xperfb.xb_perf.count >= xperfb_prev.xb_perf.count)
count = xperfb.xb_perf.count - xperfb_prev.xb_perf.count;
else
count = (XBOW_COUNTER_MASK + 1 - xperfb_prev.xb_perf.count)
+ xperfb.xb_perf.count;
ups = (count * BILL)/d;
if (v_deltat < 1000 && d < BILL)
kbs = ((ups) * (ulong)v_deltat)/1000;
else
kbs = ups;
kbs = ((kbs * 128) + 512)/1024;
printf(" B: %7d\t%3d,%03d,%03d,%03d\t\t%u\t%u,%03u\n",
count,
d/BILL, (d/MILL) % 1000, (d/1000) % 1000, d % 1000,
ups, kbs/1000, kbs%1000);
xperfa_prev = xperfa;
xperfb_prev = xperfb;
perfa_prev_ticks = perfb_prev_ticks = heart_tick;
return(0);
}
static int
xb_doperf_sample1(int argc, char **argv)
{
printf("Sampling perf counters for %d msecs\n\n", v_deltat);
xb_doperf_en(argc, argv);
us_delay(K(v_deltat));
xb_doperf_delta(argc, argv);
xb_doperf_dis(argc, argv);
return(0);
}
static int
xb_doperf_sample2(int argc, char **argv)
{
printf("Sampling perf counters for %d count of PIO R/W\n\n", v_count);
xb_doperf_en(argc, argv);
xb_dollp(argc, argv);
xb_doperf_delta(argc, argv);
xb_doperf_dis(argc, argv);
return(0);
}
/********************************/
/*
* probe the device
* returns 0 if error, else 1
*/
int
xb_probe(void)
{
uint base;
jmp_buf faultjmp;
volatile int intstat;
char *msg;
if(setjmp(faultjmp)) {
show_fault();
printf("xb_probe failed for xbow or link(0x%x)\n",
v_link);
return(0);
}
nofault = faultjmp;
/* initializations to access the device h/w */
xb = XBOW_K1PTR;
xb->xb_wid_id;
wid = (widget_cfg_t *)K1_MAIN_WIDGET(v_link);
wid->w_id;
/* peek and poke the device registers */
nofault = 0;
return(1);
}
/*
* cm commands
*/
static struct SaCmd xb_cmds[] = {
/* flags cmd (*func)(int, char **) */
{ 0, "set", xb_doset },
{ 0, "flag", xb_doflag },
{ 0, "?", xb_dousage },
{ 0, "llpstat", xb_dollpstats },
{ 0, "llp", xb_dollp },
{ 0, "dump", xb_dodump },
{ 0, "link", xb_dolink_regs },
{ 0, "linkreset", xb_dolink_reset },
{ 0, "wid", xb_dowid_regs },
{ 0, "counters", xb_doperf_ctrs },
{ 0, "llps", xb_dollpsts },
{ 0, "en", xb_doperf_en },
{ 0, "dis", xb_doperf_dis },
{ 0, "delta", xb_doperf_delta },
{ 0, "odyflush", xb_doody_flush },
{ 0, "sample1", xb_doperf_sample1 },
{ 0, "sample2", xb_doperf_sample2 },
{ 0 },
};
static jmp_buf restart_buf;
static void
main_intr(void)
{
printf("Interrupt ... \n");
longjmp (restart_buf, 1);
}
/*ARGSUSED*/
/*
* main entry
*/
int
xb_diag(int argc, char **argv, char **envp)
{
if(!xb) {
xb = XBOW_K1PTR;
xb_init_vars();
}
if(!wid && (f_flags & XBF_LINKOK))
wid = (widget_cfg_t *)K1_MAIN_WIDGET(v_link);
Signal(SIGINT, main_intr);
if (setjmp(restart_buf)) {
return(0);
}
if(argc < 2)
if (perf_enbled)
return(xb_doperf_delta(argc, argv));
else
return(xb_dodump(argc, argv));
return(sa_cmd(argc, argv, xb_cmds, xb_str, xb_probe));
}
#endif /* SA_DIAG */