Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Jun 2011 04:55:15 +0000 (UTC)
From:      Navdeep Parhar <np@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r222974 - head/tools/tools/cxgbetool
Message-ID:  <201106110455.p5B4tFf9058709@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: np
Date: Sat Jun 11 04:55:15 2011
New Revision: 222974
URL: http://svn.freebsd.org/changeset/base/222974

Log:
  Add "context" subcommand to fetch and display SGE context.

Modified:
  head/tools/tools/cxgbetool/cxgbetool.c

Modified: head/tools/tools/cxgbetool/cxgbetool.c
==============================================================================
--- head/tools/tools/cxgbetool/cxgbetool.c	Sat Jun 11 04:50:54 2011	(r222973)
+++ head/tools/tools/cxgbetool/cxgbetool.c	Sat Jun 11 04:55:15 2011	(r222974)
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
+#define	max(x, y) ((x) > (y) ? (x) : (y))
+
 static const char *progname, *nexus;
 
 struct reg_info {
@@ -59,6 +61,15 @@ struct mod_regs {
 	const struct reg_info *ri;
 };
 
+struct field_desc {
+	const char *name;     /* Field name */
+	unsigned short start; /* Start bit position */
+	unsigned short end;   /* End bit position */
+	unsigned char shift;  /* # of low order bits omitted and implicitly 0 */
+	unsigned char hex;    /* Print field in hex instead of decimal */
+	unsigned char islog2; /* Field contains the base-2 log of the value */
+};
+
 #include "reg_defs_t4.c"
 #include "reg_defs_t4vf.c"
 
@@ -67,6 +78,7 @@ usage(FILE *fp)
 {
 	fprintf(fp, "Usage: %s <nexus> [operation]\n", progname);
 	fprintf(fp,
+	    "\tcontext <type> <id>                 show an SGE context\n"
 	    "\tfilter <idx> [<param> <val>] ...    set a filter\n"
 	    "\tfilter <idx> delete|clear           delete a filter\n"
 	    "\tfilter list                         list all filters\n"
@@ -1113,6 +1125,227 @@ filter_cmd(int argc, const char *argv[])
 	return set_filter(idx, argc - 1, argv + 1);
 }
 
+/*
+ * Shows the fields of a multi-word structure.  The structure is considered to
+ * consist of @nwords 32-bit words (i.e, it's an (@nwords * 32)-bit structure)
+ * whose fields are described by @fd.  The 32-bit words are given in @words
+ * starting with the least significant 32-bit word.
+ */
+static void
+show_struct(const uint32_t *words, int nwords, const struct field_desc *fd)
+{
+	unsigned int w = 0;
+	const struct field_desc *p;
+
+	for (p = fd; p->name; p++)
+		w = max(w, strlen(p->name));
+
+	while (fd->name) {
+		unsigned long long data;
+		int first_word = fd->start / 32;
+		int shift = fd->start % 32;
+		int width = fd->end - fd->start + 1;
+		unsigned long long mask = (1ULL << width) - 1;
+
+		data = (words[first_word] >> shift) |
+		       ((uint64_t)words[first_word + 1] << (32 - shift));
+		if (shift)
+		       data |= ((uint64_t)words[first_word + 2] << (64 - shift));
+		data &= mask;
+		if (fd->islog2)
+			data = 1 << data;
+		printf("%-*s ", w, fd->name);
+		printf(fd->hex ? "%#llx\n" : "%llu\n", data << fd->shift);
+		fd++;
+	}
+}
+
+#define FIELD(name, start, end) { name, start, end, 0, 0, 0 }
+#define FIELD1(name, start) FIELD(name, start, start)
+
+static void
+show_sge_context(const struct t4_sge_context *p)
+{
+	static struct field_desc egress[] = {
+		FIELD1("StatusPgNS:", 180),
+		FIELD1("StatusPgRO:", 179),
+		FIELD1("FetchNS:", 178),
+		FIELD1("FetchRO:", 177),
+		FIELD1("Valid:", 176),
+		FIELD("PCIeDataChannel:", 174, 175),
+		FIELD1("DCAEgrQEn:", 173),
+		FIELD("DCACPUID:", 168, 172),
+		FIELD1("FCThreshOverride:", 167),
+		FIELD("WRLength:", 162, 166),
+		FIELD1("WRLengthKnown:", 161),
+		FIELD1("ReschedulePending:", 160),
+		FIELD1("OnChipQueue:", 159),
+		FIELD1("FetchSizeMode", 158),
+		{ "FetchBurstMin:", 156, 157, 4, 0, 1 },
+		{ "FetchBurstMax:", 153, 154, 6, 0, 1 },
+		FIELD("uPToken:", 133, 152),
+		FIELD1("uPTokenEn:", 132),
+		FIELD1("UserModeIO:", 131),
+		FIELD("uPFLCredits:", 123, 130),
+		FIELD1("uPFLCreditEn:", 122),
+		FIELD("FID:", 111, 121),
+		FIELD("HostFCMode:", 109, 110),
+		FIELD1("HostFCOwner:", 108),
+		{ "CIDXFlushThresh:", 105, 107, 0, 0, 1 },
+		FIELD("CIDX:", 89, 104),
+		FIELD("PIDX:", 73, 88),
+		{ "BaseAddress:", 18, 72, 9, 1 },
+		FIELD("QueueSize:", 2, 17),
+		FIELD1("QueueType:", 1),
+		FIELD1("CachePriority:", 0),
+		{ NULL }
+	};
+	static struct field_desc fl[] = {
+		FIELD1("StatusPgNS:", 180),
+		FIELD1("StatusPgRO:", 179),
+		FIELD1("FetchNS:", 178),
+		FIELD1("FetchRO:", 177),
+		FIELD1("Valid:", 176),
+		FIELD("PCIeDataChannel:", 174, 175),
+		FIELD1("DCAEgrQEn:", 173),
+		FIELD("DCACPUID:", 168, 172),
+		FIELD1("FCThreshOverride:", 167),
+		FIELD("WRLength:", 162, 166),
+		FIELD1("WRLengthKnown:", 161),
+		FIELD1("ReschedulePending:", 160),
+		FIELD1("OnChipQueue:", 159),
+		FIELD1("FetchSizeMode", 158),
+		{ "FetchBurstMin:", 156, 157, 4, 0, 1 },
+		{ "FetchBurstMax:", 153, 154, 6, 0, 1 },
+		FIELD1("FLMcongMode:", 152),
+		FIELD("MaxuPFLCredits:", 144, 151),
+		FIELD("FLMcontextID:", 133, 143),
+		FIELD1("uPTokenEn:", 132),
+		FIELD1("UserModeIO:", 131),
+		FIELD("uPFLCredits:", 123, 130),
+		FIELD1("uPFLCreditEn:", 122),
+		FIELD("FID:", 111, 121),
+		FIELD("HostFCMode:", 109, 110),
+		FIELD1("HostFCOwner:", 108),
+		{ "CIDXFlushThresh:", 105, 107, 0, 0, 1 },
+		FIELD("CIDX:", 89, 104),
+		FIELD("PIDX:", 73, 88),
+		{ "BaseAddress:", 18, 72, 9, 1 },
+		FIELD("QueueSize:", 2, 17),
+		FIELD1("QueueType:", 1),
+		FIELD1("CachePriority:", 0),
+		{ NULL }
+	};
+	static struct field_desc ingress[] = {
+		FIELD1("NoSnoop:", 145),
+		FIELD1("RelaxedOrdering:", 144),
+		FIELD1("GTSmode:", 143),
+		FIELD1("ISCSICoalescing:", 142),
+		FIELD1("Valid:", 141),
+		FIELD1("TimerPending:", 140),
+		FIELD1("DropRSS:", 139),
+		FIELD("PCIeChannel:", 137, 138),
+		FIELD1("SEInterruptArmed:", 136),
+		FIELD1("CongestionMgtEnable:", 135),
+		FIELD1("DCAIngQEnable:", 134),
+		FIELD("DCACPUID:", 129, 133),
+		FIELD1("UpdateScheduling:", 128),
+		FIELD("UpdateDelivery:", 126, 127),
+		FIELD1("InterruptSent:", 125),
+		FIELD("InterruptIDX:", 114, 124),
+		FIELD1("InterruptDestination:", 113),
+		FIELD1("InterruptArmed:", 112),
+		FIELD("RxIntCounter:", 106, 111),
+		FIELD("RxIntCounterThreshold:", 104, 105),
+		FIELD1("Generation:", 103),
+		{ "BaseAddress:", 48, 102, 9, 1 },
+		FIELD("PIDX:", 32, 47),
+		FIELD("CIDX:", 16, 31),
+		{ "QueueSize:", 4, 15, 4, 0 },
+		{ "QueueEntrySize:", 2, 3, 4, 0, 1 },
+		FIELD1("QueueEntryOverride:", 1),
+		FIELD1("CachePriority:", 0),
+		{ NULL }
+	};
+	static struct field_desc flm[] = {
+		FIELD1("NoSnoop:", 79),
+		FIELD1("RelaxedOrdering:", 78),
+		FIELD1("Valid:", 77),
+		FIELD("DCACPUID:", 72, 76),
+		FIELD1("DCAFLEn:", 71),
+		FIELD("EQid:", 54, 70),
+		FIELD("SplitEn:", 52, 53),
+		FIELD1("PadEn:", 51),
+		FIELD1("PackEn:", 50),
+		FIELD1("DBpriority:", 48),
+		FIELD("PackOffset:", 16, 47),
+		FIELD("CIDX:", 8, 15),
+		FIELD("PIDX:", 0, 7),
+		{ NULL }
+	};
+	static struct field_desc conm[] = {
+		FIELD1("CngDBPHdr:", 6),
+		FIELD1("CngDBPData:", 5),
+		FIELD1("CngIMSG:", 4),
+		FIELD("CngChMap:", 0, 3),
+		{ NULL }
+	};
+
+	if (p->mem_id == SGE_CONTEXT_EGRESS)
+		show_struct(p->data, 6, (p->data[0] & 2) ? fl : egress);
+	else if (p->mem_id == SGE_CONTEXT_FLM)
+		show_struct(p->data, 3, flm);
+	else if (p->mem_id == SGE_CONTEXT_INGRESS)
+		show_struct(p->data, 5, ingress);
+	else if (p->mem_id == SGE_CONTEXT_CNM)
+		show_struct(p->data, 1, conm);
+}
+
+#undef FIELD
+#undef FIELD1
+
+static int
+get_sge_context(int argc, const char *argv[])
+{
+	int rc;
+	char *p;
+	long cid;
+	struct t4_sge_context cntxt = {0};
+
+	if (argc != 2) {
+		warnx("sge_context: incorrect number of arguments.");
+		return (EINVAL);
+	}
+
+	if (!strcmp(argv[0], "egress"))
+		cntxt.mem_id = SGE_CONTEXT_EGRESS;
+	else if (!strcmp(argv[0], "ingress"))
+		cntxt.mem_id = SGE_CONTEXT_INGRESS;
+	else if (!strcmp(argv[0], "fl"))
+		cntxt.mem_id = SGE_CONTEXT_FLM;
+	else if (!strcmp(argv[0], "cong"))
+		cntxt.mem_id = SGE_CONTEXT_CNM;
+	else {
+		warnx("unknown context type \"%s\"; known types are egress, "
+		    "ingress, fl, and cong.", argv[0]);
+		return (EINVAL);
+	}
+
+	p = str_to_number(argv[1], &cid, NULL);
+	if (*p) {
+		warnx("invalid context id \"%s\"", argv[1]);
+		return (EINVAL);
+	}
+	cntxt.cid = cid;
+
+	rc = doit(CHELSIO_T4_GET_SGE_CONTEXT, &cntxt);
+	if (rc != 0)
+		return (rc);
+
+	show_sge_context(&cntxt);
+	return (0);
+}
+
 static int
 run_cmd(int argc, const char *argv[])
 {
@@ -1131,6 +1364,8 @@ run_cmd(int argc, const char *argv[])
 		rc = dump_regs(argc, argv);
 	else if (!strcmp(cmd, "filter"))
 		rc = filter_cmd(argc, argv);
+	else if (!strcmp(cmd, "context"))
+		rc = get_sge_context(argc, argv);
 	else {
 		rc = EINVAL;
 		warnx("invalid command \"%s\"", cmd);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106110455.p5B4tFf9058709>