From c54854914ac3e4a9ea43d7d0311069e7e352386a Mon Sep 17 00:00:00 2001 From: np Date: Fri, 16 Dec 2011 20:38:22 +0000 Subject: Catch up with new driver ioctls in cxgbe. MFC after: 1 month --- tools/tools/cxgbetool/cxgbetool.c | 175 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) (limited to 'tools/tools') diff --git a/tools/tools/cxgbetool/cxgbetool.c b/tools/tools/cxgbetool/cxgbetool.c index 06fa50b..92ac978 100644 --- a/tools/tools/cxgbetool/cxgbetool.c +++ b/tools/tools/cxgbetool/cxgbetool.c @@ -30,14 +30,17 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -83,10 +86,13 @@ usage(FILE *fp) "\tfilter delete|clear delete a filter\n" "\tfilter list list all filters\n" "\tfilter mode [] ... get/set global filter mode\n" + "\tloadfw install firmware\n" + "\tmemdump dump a memory range\n" "\treg
[=] read/write register\n" "\treg64
[=] read/write 64 bit register\n" "\tregdump [] ... dump registers\n" "\tstdio interactive mode\n" + "\ttcb read TCB\n" ); } @@ -1353,6 +1359,169 @@ get_sge_context(int argc, const char *argv[]) } static int +loadfw(int argc, const char *argv[]) +{ + int rc, fd; + struct t4_data data = {0}; + const char *fname = argv[0]; + struct stat st = {0}; + + if (argc != 1) { + warnx("loadfw: incorrect number of arguments."); + return (EINVAL); + } + + fd = open(fname, O_RDONLY); + if (fd < 0) { + warn("open(%s)", fname); + return (errno); + } + + if (fstat(fd, &st) < 0) { + warn("fstat"); + close(fd); + return (errno); + } + + data.len = st.st_size; + data.data = mmap(0, data.len, PROT_READ, 0, fd, 0); + if (data.data == MAP_FAILED) { + warn("mmap"); + close(fd); + return (errno); + } + + rc = doit(CHELSIO_T4_LOAD_FW, &data); + munmap(data.data, data.len); + close(fd); + return (rc); +} + +static int +read_mem(uint32_t addr, uint32_t len, void (*output)(uint32_t *, uint32_t)) +{ + int rc; + struct t4_mem_range mr; + + mr.addr = addr; + mr.len = len; + mr.data = malloc(mr.len); + + if (mr.data == 0) { + warn("read_mem: malloc"); + return (errno); + } + + rc = doit(CHELSIO_T4_GET_MEM, &mr); + if (rc != 0) + goto done; + + if (output) + (*output)(mr.data, mr.len); +done: + free(mr.data); + return (rc); +} + +/* + * Display memory as list of 'n' 4-byte values per line. + */ +static void +show_mem(uint32_t *buf, uint32_t len) +{ + const char *s; + int i, n = 8; + + while (len) { + for (i = 0; len && i < n; i++, buf++, len -= 4) { + s = i ? " " : ""; + printf("%s%08x", s, htonl(*buf)); + } + printf("\n"); + } +} + +static int +memdump(int argc, const char *argv[]) +{ + char *p; + long l; + uint32_t addr, len; + + if (argc != 2) { + warnx("incorrect number of arguments."); + return (EINVAL); + } + + p = str_to_number(argv[0], &l, NULL); + if (*p) { + warnx("invalid address \"%s\"", argv[0]); + return (EINVAL); + } + addr = l; + + p = str_to_number(argv[1], &l, NULL); + if (*p) { + warnx("memdump: invalid length \"%s\"", argv[1]); + return (EINVAL); + } + len = l; + + return (read_mem(addr, len, show_mem)); +} + +/* + * Display TCB as list of 'n' 4-byte values per line. + */ +static void +show_tcb(uint32_t *buf, uint32_t len) +{ + const char *s; + int i, n = 8; + + while (len) { + for (i = 0; len && i < n; i++, buf++, len -= 4) { + s = i ? " " : ""; + printf("%s%08x", s, htonl(*buf)); + } + printf("\n"); + } +} + +#define A_TP_CMM_TCB_BASE 0x7d10 +#define TCB_SIZE 128 +static int +read_tcb(int argc, const char *argv[]) +{ + char *p; + long l; + long long val; + unsigned int tid; + uint32_t addr; + int rc; + + if (argc != 1) { + warnx("incorrect number of arguments."); + return (EINVAL); + } + + p = str_to_number(argv[0], &l, NULL); + if (*p) { + warnx("invalid tid \"%s\"", argv[0]); + return (EINVAL); + } + tid = l; + + rc = read_reg(A_TP_CMM_TCB_BASE, 4, &val); + if (rc != 0) + return (rc); + + addr = val + tid * TCB_SIZE; + + return (read_mem(addr, TCB_SIZE, show_tcb)); +} + +static int run_cmd(int argc, const char *argv[]) { int rc = -1; @@ -1372,6 +1541,12 @@ run_cmd(int argc, const char *argv[]) rc = filter_cmd(argc, argv); else if (!strcmp(cmd, "context")) rc = get_sge_context(argc, argv); + else if (!strcmp(cmd, "loadfw")) + rc = loadfw(argc, argv); + else if (!strcmp(cmd, "memdump")) + rc = memdump(argc, argv); + else if (!strcmp(cmd, "tcb")) + rc = read_tcb(argc, argv); else { rc = EINVAL; warnx("invalid command \"%s\"", cmd); -- cgit v1.1