diff --git a/.gitignore b/.gitignore index 1e69f92bfa0862eeb16acb5d1cc7d7bdd063c61e..ffc95991b922acef816f69f76308baed70369227 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,6 @@ Pcie40Applications/pcie40_miniPod Pcie40Applications/pcie40_send_ul *.d **/pcie40_reload.out - +Pcie40Applications/regconfig +Pcie40Applications/statlink +Pcie40Applications/timediff diff --git a/Pcie40Applications/Makefile b/Pcie40Applications/Makefile index ee95ed5c34e361f2275290cbf83d2d3bd0bd9a76..c0ecff2f5f96d9c84f03653fb78be73b94fdb1e1 100644 --- a/Pcie40Applications/Makefile +++ b/Pcie40Applications/Makefile @@ -100,6 +100,24 @@ PCIE40_MINIPOD_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Driver -I$(TOP)/.. PCIE40_MINIPOD_INSTALL =$(PREFIX)/bin PCIE40_MINIPOD_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLibraries/ -lpcie40driver_ecs +REGCONFIG :=regconfig +REGCONFIG_OBJS =regconfig.o +REGCONFIG_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Libraries +REGCONFIG_INSTALL =$(PREFIX)/bin +REGCONFIG_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLibraries/ -lpcie40driver_ecs + +STATLINK :=statlink +STATLINK_OBJS =statlink.o +STATLINK_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Libraries +STATLINK_INSTALL =$(PREFIX)/bin +STATLINK_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLibraries/ -lpcie40driver_ecs + +TIMEDIFF :=timediff +TIMEDIFF_OBJS =timediff.o +TIMEDIFF_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Libraries +TIMEDIFF_INSTALL =$(PREFIX)/bin +TIMEDIFF_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLibraries/ -lpcie40driver_ecs -lrt + VPATH :=$(TOP) include $(TOP)/rules.mk @@ -118,6 +136,9 @@ $(eval $(call ODIR_template,PCIE40_ULRESET)) $(eval $(call ODIR_template,PCIE40_DMA_CHECK)) $(eval $(call ODIR_template,PCIE40_READFPGAVERSION)) $(eval $(call ODIR_template,PCIE40_MINIPOD)) +$(eval $(call ODIR_template,REGCONFIG)) +$(eval $(call ODIR_template,STATLINK)) +$(eval $(call ODIR_template,TIMEDIFF)) $(eval $(call COPY_template,SCRIPTS,755)) $(eval $(call LINK_template,PCIE40_RELOAD)) $(eval $(call ODIR_template,PCIE40_RELOAD_SUID)) diff --git a/Pcie40Applications/regconfig.cpp b/Pcie40Applications/regconfig.cpp new file mode 100644 index 0000000000000000000000000000000000000000..882860ee456bc610dc82f8eabe4b4486472935aa --- /dev/null +++ b/Pcie40Applications/regconfig.cpp @@ -0,0 +1,384 @@ + +/*-------------------------------------------------------------------------------*\ + regconfig: From PCIe40 board to access register of FEE through belle2link + + Qi-Dong Zhou, KEK + + 2020.03.06 0.01 first version based on reghs.c + +\*--------------------------------------------------------------------------------*/ +#define VERSION 01 +#define MOD_DATE 20200420 + +#include "pcie40_b2slc.h" +#include "pcie40_reg.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <iostream> +#include <vector> + +extern "C" int ecs_open(int dev, int bar); +extern "C" void ecs_close(int dev, int bar); +//#define PCIE_DEV 0 +#define MAX_NUM_CH 48 +#define MAX_SLOT 3 +#define SLC_BAR 2 + +// parse +int dev_slot = 0; // default device slot number, If use multiple PCIe40 on a server, change it with --dev xx option +int ch = -1; +unsigned int addr = 0; +unsigned int data = 0; +char *filename; +char *operation; + +//Flag for switch slc access method +bool USE_FEE8 = false; +bool USE_FEE32 = false; +bool READ_ONLY = false; +bool WRITE = false; +bool STREAM = false; +bool STREAM_ARICH = false; +bool OP_FLAG = false; + +/* 0 parameter */ +#define PCIE40_NOP 0x100 +#define PCIE40_LINK 0x101 +#define PCIE40_CHECKFEE 0x102 +#define PCIE40_TRGOFF 0x104 +#define PCIE40_TRGON 0x105 + +/* 0 parameter (obsolete, unused) */ +#define PCIE40_TTTRG 0x106 +#define PCIE40_DUMTRG 0x107 + +/* 0 parameter (CDC special) */ +#define PCIE40_SUPMODE 0x108 +#define PCIE40_RAWMODE 0x109 + +/* 1 parameter */ +#define PCIE40_STREAM 0x200 + +/* 1 parameter (CDC special) */ +#define PCIE40_PDSTLALL 0x201 +#define PCIE40_ADCTH 0x202 +#define PCIE40_TDCTH 0x203 +#define PCIE40_DELAY 0x204 +#define PCIE40_WINDOW 0x205 + +/* 2 parameters */ +#define PCIE40_FEE8 0x300 +#define PCIE40_FEE32 0x301 + +/* 2 parameters (CDC special) */ +#define PCIE40_PDSTL 0x302 + +/* defined address */ +#define REG_FEEHWTYPE 0x0 +#define REG_FEESERIAL 0x0 +#define REG_FEEFWTYPE 0x0 +#define REG_FEEFWVER 0x0 + + +std::vector<std::string> splitpath(const std::string str, const char del) { + int first = 0; + int last = str.find_first_of(del); + + std::vector<std::string> result; + + while (first < str.size()) { + std::string subStr(str, first, last - first); + + result.push_back(subStr); + + first = last + 1; + last = str.find_first_of(del, first); + + if (last == std::string::npos) { + last = str.size(); + } + } + return result; +} + +void argument(int argc, char **argv){ + char *ARGV0 = argv[0]; + for(int i=1;i<argc;i++){ + std::string ss = argv[i]; + if(ss=="--dev"){ + dev_slot = atoi(argv[++i]); + if( dev_slot<0 || dev_slot >= MAX_SLOT){ + fprintf(stderr, "Invalid device slot %d, Valid slot [0, %d]\n", dev_slot, MAX_SLOT); + } + } + if(ss=="--ch"){ + ch = atoi(argv[++i]); + if( ch<0 || ch >= MAX_NUM_CH){ + fprintf(stderr, "Invalid channel ID %d, Valid ID [0, %d]\n", ch, MAX_NUM_CH); + } + } + if(ss=="--fee8"){ + USE_FEE8 = true; + } + if(ss=="--fee32"){ + USE_FEE32 = true; + } + if(ss=="-r" || ss=="--read"){ + READ_ONLY = true; + addr = strtoul(argv[++i], 0, 16); + } + if(ss=="-w" || ss=="--write"){ + WRITE = true; + addr = strtoul(argv[++i], 0, 16); + data = strtoul(argv[++i], 0, 16); + //printf("add = %02x data = %08x\n", addr, data); + } + if(ss=="--stream"){ + STREAM = true; + filename = argv[++i]; + std::string file_str = filename; + char delims = '.'; + std::vector<std::string> path = splitpath(file_str, delims); + if(path.back() == "bin" || path.back() == "bit"){ + STREAM_ARICH = true; + } + //std::cout << path.back() << std::endl; + + } + if(ss=="--op"){ + OP_FLAG = true; + operation = argv[++i]; + addr = strtoul(argv[++i], 0, 16); + data = strtoul(argv[++i], 0, 16); + } + if(ss=="-h" || ss=="-help"){ + fprintf(stderr, "%s version %d.%02d date %d\n" + , ARGV0, VERSION/100, VERSION%100, MOD_DATE); + fprintf(stderr, "usage: %s --ch 0 --fee32 -w 0x12 0x0\n" + " --dev xx #device slot number which installed PCIe40\n" + " --ch xx #link channel number\n" + " --fee8 or --fee32 #use A7D8 or A16D32 for access register\n" + " -r xx or -w xx xx #read or write register with address xx[hex] or data xx[hex]\n\n" + " %s --ch 0 --stream /path/firmware.bit\n" + " --stream /path/filename #streaming a file by using stream file method\n\n" + , ARGV0, ARGV0); + return; + } + } +} + +/* ---------------------------------------------------------------------- *\ + hsreg +\* ---------------------------------------------------------------------- */ +int +hsreg(const char *name) +{ + static struct { char *name; int adrs; } regs[] = { + { "link", PCIE40_LINK } , + { "checkfee", PCIE40_CHECKFEE }, + + { "trghold", PCIE40_TRGOFF }, + { "trigger", PCIE40_TRGON }, + { "realtrg", PCIE40_TTTRG }, + { "simtrg" , PCIE40_DUMTRG }, + { "simple", PCIE40_SUPMODE }, + { "verbose", PCIE40_RAWMODE }, + + { "supmode", PCIE40_SUPMODE }, + { "rawmode", PCIE40_RAWMODE }, + + { "pdstl", PCIE40_PDSTL }, + { "pdstlall", PCIE40_PDSTLALL }, + { "adcth", PCIE40_ADCTH }, + { "tdcth", PCIE40_TDCTH }, + { "delay", PCIE40_DELAY }, + { "window", PCIE40_WINDOW }, + + { "stat", PCIE40REGL_STAT }, + }; + int i; + + if (isdigit(name[0])) { + return strtoul(name, 0, 16); + } + + for (i = 0; i<sizeof(regs)/sizeof(regs[0]); i++) { + if (strcmp(regs[i].name, name) == 0) { + return regs[i].adrs; + } + } + + i = strtoul(name, 0, 16); + return (i > 0 && i < 0x100) ? i : -1; +} + +/* ---------------------------------------------------------------------- *\ + pcie40_op +\* ---------------------------------------------------------------------- */ +int +pcie40_op(int dev, int ch, int op_addr, int addr, int data) +{ + int i; + const char *feetype; + int cmd = 0; + int cmd_cdc = 0; + + switch (op_addr) { + case PCIE40_LINK: cmd = 0x01; break; + case PCIE40_TRGOFF: cmd = 0x03; break; + case PCIE40_TRGON: cmd = 0x04; break; + case PCIE40_SUPMODE: cmd_cdc = 0x07; break; /* suppress mode */ + case PCIE40_RAWMODE: cmd_cdc = 0x08; break; /* raw mode */ + } + + if (op_addr == PCIE40_CHECKFEE) { + int ret; + int hwtype; + int serial; + int fwtype; + int fwver; + static const char *feetype[] = { + "UNDEF", "SVD", "CDC", "BPID", "EPID", "ECL", "EECL", "KLM", "EKLM", + "TRG", "UNKNOWN-10", "UNKNOWN-11", + "UNKNOWN-12", "UNKNOWN-13", "DEMO", "TEST" }; + static const char *demotype[] = { + "UNDEF", "HSLB-B2L", "SP605-B2L", "ML605-B2L", "AC701-B2L" }; + static const char *trgtype[] = { + "TRGMERGER", /* = 0 */ + "TRGTSF", /* = 1 */ + "TRG2D", /* = 2 */ + "TRG3D", /* = 3 */ + "TRGNN", /* = 4 */ + "TRGEVTT", /* = 5 */ + "TRGGRL", /* = 6 */ + "TRGGDL", /* = 7 */ + "TRGETM", /* = 8 */ + "TRGTOP", /* = 9 */ + "TRGKLM", /* = 10 */ + }; + + if (!pcie40_b2l_status(dev_slot, ch)) { + printf("Failed: b2l is down\n"); + return -1; + } + hwtype = pcie40_readfee8(dev, ch, REG_FEEHWTYPE); + serial = pcie40_readfee8(dev, ch, REG_FEESERIAL); + fwtype = pcie40_readfee8(dev, ch, REG_FEEFWTYPE); + fwver = pcie40_readfee8(dev, ch, REG_FEEFWVER); + + serial |= (hwtype & 0xf) << 8; + fwver |= (fwtype & 0xf) << 8; + hwtype = (hwtype >> 4) & 0xf; + fwtype = (fwtype >> 4) & 0xf; + + if (hwtype == 14 && fwtype > 0 && fwtype <= 4) { + printf("FEE type %s serial %d version %d at PCIE40_LINK-%d\n", + demotype[fwtype], serial, fwver, ch); + } else if (hwtype == 9 && fwtype >= 0 && fwtype <= 10) { + printf("FEE type %s serial %d version %d at PCIE40_LINK-%d\n", + trgtype[fwtype], serial, fwver, ch); + } else { + printf("FEE type %s serial %d firmware %d version %d at PCIE40_LINK-%d\n", + feetype[hwtype], serial, fwtype, fwver, ch); + } + } else if (cmd) { + pcie40_writefee8(dev, ch, PCIE40REG_FEECONT, cmd); + + } else if (cmd_cdc) { + pcie40_writefee8(dev, ch, PCIE40REG_CDCCONT, cmd_cdc); + }else if (op_addr == PCIE40_PDSTL) { + if (addr <= 0 || addr > 48) { + printf("pedestal channel %d out of range [1,48]\n", addr); + return -1; + } + pcie40_writefee8(dev, ch, PCIE40REG_PDSTLMIN + (addr-1)*2+0, (data>>0) & 0xff); + pcie40_writefee8(dev, ch, PCIE40REG_PDSTLMIN + (addr-1)*2+1, (data>>8) & 0xff); + } else if (op_addr == PCIE40_PDSTLALL) { + for (i=1; i<=48; i++) { + pcie40_writefee8(dev, ch, PCIE40REG_PDSTLMIN + (i-1)*2+0, (addr>>0) & 0xff); + pcie40_writefee8(dev, ch, PCIE40REG_PDSTLMIN + (i-1)*2+1, (addr>>8) & 0xff); + } + + } else if (op_addr == PCIE40_ADCTH || op_addr == PCIE40_TDCTH) { + int adr = (op_addr == PCIE40_ADCTH) ? PCIE40REG_ADCTH : PCIE40REG_TDCTH; + + if (addr != -1) { + pcie40_writefee8(dev, ch, adr + 0, (addr>>0) & 0xff); + pcie40_writefee8(dev, ch, adr + 1, (addr>>8) & 0xff); + } else { + printf("reg%02x = %02x%02x\n", adr, + pcie40_readfee8(dev, ch, adr + 1) & 0xff, + pcie40_readfee8(dev, ch, adr + 0) & 0xff); + } + + }else if (op_addr == PCIE40_WINDOW || op_addr == PCIE40_DELAY) { + int adr = (op_addr == PCIE40_WINDOW) ? PCIE40REG_WINDOW : PCIE40REG_DELAY; + + if (addr != -1) { + pcie40_writefee8(dev, ch, adr, addr & 0xff); + } else { + printf("reg%02x = %02x\n", adr, pcie40_readfee8(dev, ch, adr)); + } + + } else { + + printf("undefined action %x\n", op_addr); + return -1; + + } + return 0; +} + +int main(int argc, char** argv){ + + // parse arguments + argument(argc, argv); + + // open pcie40 device driver for current process + ecs_open( dev_slot , SLC_BAR ); + + int result = -1; + + if(USE_FEE8 && READ_ONLY){ + result = pcie40_readfee8( dev_slot , ch , addr ); + printf("reg%04x = %08x\n", addr, result); + }else if(USE_FEE8 && WRITE){ + result = pcie40_writefee8( dev_slot , ch , addr, data ); + if(result == 0) + printf("Write 0x%04x to register 0x%04x\n", data, addr); + else + printf("ERROR: Failed to write 0x%04x to register 0x%04x\n", data, addr); + }else if(USE_FEE32 && READ_ONLY){ + result = pcie40_readfee32( dev_slot , ch , addr ); + printf("reg%04x = %08x\n", addr, result); + }else if(USE_FEE32 && WRITE){ + result = pcie40_writefee32( dev_slot , ch , addr, data ); + if(result == 0) + printf("Write 0x%08x to register 0x%04x\n", data, addr); + else + printf("ERROR: Failed to write 0x%08x to register %04x\n", data, addr); + }else if(STREAM){ + if(STREAM_ARICH) + result = pcie40_writestream_arich( dev_slot , ch , filename ) ; + else + result = pcie40_writestream_klm( dev_slot , ch , filename ) ; + if(result == 0) + std::cerr<<"Succeed streaming file: " << filename << std::endl; + else + std::cerr<<"ERROR: Failed streaming file: " << filename << std::endl; + } + + //This is only frame for register operation in the furture + if(OP_FLAG){ + unsigned int op_addr = hsreg( operation ); + pcie40_op(dev_slot, ch, op_addr, addr, data); + } + + // close pcie40 device driver for current process + ecs_close( dev_slot , SLC_BAR) ; + + return 0 ; +} + + diff --git a/Pcie40Applications/rules.mk b/Pcie40Applications/rules.mk index 38479046d3cd79a07122c28c8f4eeee3fdf8d870..a8cd3a880a0a25ef17e1ed4179dd48f62db4d731 100644 --- a/Pcie40Applications/rules.mk +++ b/Pcie40Applications/rules.mk @@ -2,8 +2,8 @@ BUILD_PREFIX ?= LIBDIR_SUFFIX ?=64 FLEX ?=flex LFLAGS ?= -CFLAGS +=-Wall -g -O3 -CXXFLAGS +=-Wall -g -O3 +CFLAGS +=-Wall -g -O3 +CXXFLAGS +=-Wall -g -O3 DOCRA ?=docra ASCIIDOCTOR ?=asciidoctor diff --git a/Pcie40Applications/statlink.cpp b/Pcie40Applications/statlink.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c60e53cc37f0b8c5a6be53e2940a8519afd48e5 --- /dev/null +++ b/Pcie40Applications/statlink.cpp @@ -0,0 +1,298 @@ + +/*-------------------------------------------------------------------------------*\ + regconfig: Monitoring the status of PCIe40 board and belle2links + + Qi-Dong Zhou, KEK + + 2020.04.28 0.01 first version based on staths.c + +\*--------------------------------------------------------------------------------*/ +#define VERSION 01 +#define MOD_DATE 20200428 + +#include "pcie40_b2slc.h" +#include "pcie40_reg.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <iostream> +#include <vector> +#include <bitset> + +extern "C" int ecs_open(int dev, int bar); +extern "C" void ecs_close(int dev, int bar); +//#define PCIE_DEV 0 +#define MAX_NUM_CH 48 +#define MAX_SLOT 3 +#define SLC_BAR 2 + +#ifndef D +#define D(a,b,c) (((a)>>(c))&((1<<((b)+1-(c)))-1)) +#define B(a,b) D(a,b,b) +#define Bs(a,b,s) (B(a,b)?(s):"") +#define Ds(a,b,c,s) (D(a,b,c)?(s):"") +#endif + +// parse +int dev_slot = 0; // default device slot number, for use multiple PCIe40 on a server,--dev xx option +int ch = -1; +std::bitset<48> link_mask; +//Flag for switch slc access method + +void argument(int argc, char **argv){ + char *ARGV0 = argv[0]; + std::bitset<48> en_link; + if(argc == 1){ + link_mask.set(); + std::cout<<std::hex<<link_mask<<std::endl; + } + + for(int i=1;i<argc;i++){ + std::string ss = argv[i]; + if(ss=="--dev"){ + dev_slot = atoi(argv[++i]); + if( dev_slot<0 || dev_slot >= MAX_SLOT){ + fprintf(stderr, "Invalid device slot %d, Valid slot [0, %d]\n", dev_slot, MAX_SLOT); + } + } + if(ss=="--ch"){ + for(int j = i+1; j<argc; j++){ + ch = atoi(argv[j]); + if( ch<0 || ch >= MAX_NUM_CH){ + fprintf(stderr, "Invalid channel ID %d, Valid ID [0, %d]\n", ch, MAX_NUM_CH); + } + en_link.reset(); + en_link.set(ch, true); + link_mask = link_mask | en_link; + //std::cout <<i << " " << j <<" "<< ch <<" "<<std::hex<< en_link <<" "<<std::hex<<link_mask<< std::endl; + + } + } + if(ss=="-h" || ss=="-help"){ + fprintf(stderr, "%s version %d.%02d date %d\n" + , ARGV0, VERSION/100, VERSION%100, MOD_DATE); + fprintf(stderr, "usage: %s --ch 0 \n" + " --dev xx #device slot number which installed PCIe40\n" + " --ch xx xx ... #link channel number\n" + , ARGV0); + return; + } + } +} + + +/* ---------------------------------------------------------------------- *\ + * statpcie40 +\* ---------------------------------------------------------------------- */ +int +statpice40(pcie40reg_t pcie40reg) +{ + pcie40reg_t *pcie = &pcie40reg; + memset(pcie, 0, sizeof(*pcie)); + int pcie40_sta = pcie40_status(dev_slot); + int pcie40_fwver = 0; + printf("PCIE40 firmware version %d.%02d\n",pcie40_fwver / 100, pcie40_fwver % 100); + printf("memory: %s | ttd: %s | ttd clk: %s | run=: %d | trg: %d \n", + B(pcie40_sta, 8)?"FULL":"OK", + B(pcie40_sta, 12)?"UP":"DOWN", + B(pcie40_sta, 11)?"UP":"DOWN", + pcie40_run_number(dev_slot), + D(pcie40_sta, 28, 17)); + printf("rxlink: %s | txlink: %s | txlink: %s | rxdisp: %s | rxdata: %s\n", + B(pcie40_sta, 0)?"READY":"NOT READY", + B(pcie40_sta, 1)?"READY":"NOT READY", + B(pcie40_sta, 2)?"SYNCED":"NOT SYNCED", + B(pcie40_sta, 3)?"ERROR":"OK", + B(pcie40_sta, 4)?"ERROR":"OK"); + + return 0; +} + + + +/* ---------------------------------------------------------------------- *\ + * getfee +\* ---------------------------------------------------------------------- */ +int +getfee( pcie40reg_t *pcie40p) +{ + int i; + const char *feetype; + + int ret; + int hwtype; + int serial; + int fwtype; + int fwver; + + hwtype = pcie40_readfee8(dev_slot, ch, PCIE40REG_FEEHWTYPE); + serial = pcie40_readfee8(dev_slot, ch, PCIE40REG_FEESERIAL); + fwtype = pcie40_readfee8(dev_slot, ch, PCIE40REG_FEEFWTYPE); + fwver = pcie40_readfee8(dev_slot, ch, PCIE40REG_FEEFWVER); + + pcie40p->feeser = (serial | (hwtype << 8)) & 0xfff; + pcie40p->feever = (fwver | (fwtype << 8)) & 0xfff; + pcie40p->feehw = (hwtype >> 4) & 0x0f; + pcie40p->feefw = (fwtype >> 4) & 0x0f; + + pcie40p->feecrce = pcie40_readfee8(dev_slot, ch, PCIE40REG_CRCERR); + + return 0; +} + + +/* ---------------------------------------------------------------------- *\ + * readregs +\* ---------------------------------------------------------------------- */ +int +readregs(std::bitset<48> link_mask, pcie40reg_t pcie40reg[]) +{ + int i; + int o_readonly = 1; + int notfound = 1; + + // for (i=0; i<48; i++) { + pcie40reg_t *pcie = &pcie40reg[i]; + memset(pcie, 0, sizeof(*pcie)); + // if (!link_mask[i]) continue; + + pcie->xbusy = pcie40_readfee32(dev_slot, ch, PCIE40REG_CCLK); + pcie->conf = pcie40_readfee32(dev_slot, ch, PCIE40REG_CONF); + + pcie->pcie40ver = pcie40_readfee32(dev_slot, ch, PCIE40REGL_VER); /* 81 */ + pcie->rxdata = pcie40_readfee32(dev_slot, ch, PCIE40REGL_RXDATA); /* 84 */ + pcie->eventsz = pcie40_readfee32(dev_slot, ch, PCIE40REGL_EVENTSZ); /* 85 */ + pcie->nevent = pcie40_readfee32(dev_slot, ch, PCIE40REGL_NEVENT); /* 86 */ + pcie->nkbyte = pcie40_readfee32(dev_slot, ch, PCIE40REGL_NKBYTE); /* 87 */ + pcie->nword = pcie40_readfee32(dev_slot, ch, PCIE40REGL_NWORD); /* 88 */ + pcie->vetoset = pcie40_readfee32(dev_slot, ch, PCIE40REGL_VETOSET); /* 89 */ + pcie->vetocnt = pcie40_readfee32(dev_slot, ch, PCIE40REGL_VETOCNT); /* 8a */ + pcie->vetobuf[0] = pcie40_readfee32(dev_slot, ch, PCIE40REGL_VETOBUF0); /* 8b */ + pcie->vetobuf[1] = pcie40_readfee32(dev_slot, ch, PCIE40REGL_VETOBUF1); /* 8c */ + + pcie->feeser = 0xffff; + pcie->feever = 0xffff; + if ( pcie40_b2l_status(dev_slot, i) ) { + getfee(pcie); + } + + // } + return notfound; +} + +/* ---------------------------------------------------------------------- *\ + * statlink +\* ---------------------------------------------------------------------- */ +int +statlink(std::bitset<48> link_mask, pcie40reg_t pcie40reg[]) +{ + int i; + int first = 1; + int quiet = 1; + + for (i=0; i<48; i++) { + pcie40reg_t *pcie = &pcie40reg[i]; + double total; + char prompt[128]; + + if (!link_mask[i]) continue; + + quiet = 0; + if (! first) printf("\n"); + first =0; + + sprintf(prompt, "(%02d) ", i); + + if ( !pcie40_b2l_status(dev_slot, i) ) { + printf("b2link is down\n"); + } else if (pcie->feeser & 0x8000) { + printf("fee info is not available\n"); + } else { + printf("%s serial %d version %d\n", + feename(pcie->feehw, pcie->feefw), pcie->feeser, pcie->feever); + } + + printf("%s", prompt); + printf("b2l=%s (rx=%s tx=%s rxsta=%s txsta=%s mask=%s)\n", + pcie40_b2l_status(dev_slot, i)?"UP":"DOWN", + pcie40_b2l_rxstatus(dev_slot, i)?"UP":"DOWN", + pcie40_b2l_txstatus(dev_slot, i)?"UP":"DOWN", + pcie40_b2l_rxready(dev_slot, i)?"READY":"NOT READY", + pcie40_b2l_txready(dev_slot, i)?"READY":"NOT READY", + pcie40_b2l_mask(dev_slot, i)?"UNMASK":"MASK"); + + printf("%s", prompt); + + printf("%s", prompt); + printf("rxdata=%04x rxlinkdown=%d rxcrcerr=%d feecrcerr=%d\n", + D(pcie->rxdata,15,0), D(pcie->rxdata,31,24), D(pcie->rxdata,23,16), + pcie->feecrce); + printf("%s", prompt); + total = (pcie->nkbyte * 256.0 + (pcie->nword & 0xff)) * 4.0; + printf("event=%d total=%1.0fkB", pcie->nevent, total / 1000); + if (pcie->nevent) { + double avg = total / pcie->nevent; + printf(" (avg=%1.0fB", avg); + if (D(pcie->eventsz,31,16) == 0xffff) { + printf(" last=oflow"); + } else { + printf(" last=%dB", D(pcie->eventsz,31,16)*4); + } + if (D(pcie->eventsz,15,0) == 0xffff) { + printf(" max=oflow)"); + } else { + printf(" max=%dB)", D(pcie->eventsz,15,0)*4); + } + } + printf("\n"); + + printf("%s", prompt); + if ((pcie->vetoset & 3) == 0) { + printf("no b2link error correction"); + } else if (pcie->vetocnt == 0) { + printf("no b2link error"); + } else { + printf("b2link error %d(%c) %d(%c) %c%02x %c%02x %c%02x %c%02x %c%02x %c%02x", + D(pcie->vetocnt,31,16), + B(pcie->vetoset,1) ? 'i' : '-', + D(pcie->vetocnt,15,0), + B(pcie->vetoset,0) ? 'd' : '-', + B(pcie->vetobuf[0],25)?'K':'D', D(pcie->vetobuf[0],15,8), + B(pcie->vetobuf[0],24)?'K':'D', D(pcie->vetobuf[0],7,0), + B(pcie->vetobuf[0],21)?'K':'D', D(pcie->vetobuf[1],31,24), + B(pcie->vetobuf[0],20)?'K':'D', D(pcie->vetobuf[1],23,16), + B(pcie->vetobuf[0],17)?'K':'D', D(pcie->vetobuf[1],15,8), + B(pcie->vetobuf[0],16)?'K':'D', D(pcie->vetobuf[1],7,0)); + } + printf("\n"); + } + + if (quiet) { + printf("no PCIE40 was found.\n"); + } +} + + +int main(int argc, char** argv){ + + // parse arguments + argument(argc, argv); + + pcie40reg_t pcie40; + pcie40reg_t pcie40reg[48]; + + // open pcie40 device driver for current process + ecs_open( dev_slot , SLC_BAR ); + + printf("statlink version %d (%d) / ", VERSION, MOD_DATE); + statpice40(pcie40); + readregs(link_mask, pcie40reg); + statlink(link_mask, pcie40reg); + + // close pcie40 device driver for current process + ecs_close( dev_slot , SLC_BAR) ; + + return 0 ; +} + + diff --git a/Pcie40Applications/timediff.cpp b/Pcie40Applications/timediff.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b8b61dc40aa912f4dd31457e1a5b29beeabb7a1 --- /dev/null +++ b/Pcie40Applications/timediff.cpp @@ -0,0 +1,100 @@ +#include <iostream> +#include <ctime> +#include <string> +#include <stdlib.h> +#include <unistd.h> +#include <memory.h> +#include <stdexcept> +#include <string.h> +#include <cstdio> + +#include "pcie40_b2slc.h" +extern "C" int ecs_open(int dev, int bar); +extern "C" void ecs_close(int dev, int bar); +/* +std::string exec(const char* cmd) { + char buffer[128]; + std::string result = ""; + FILE* pipe = popen(cmd, "r"); + if (!pipe) throw std::runtime_error("popen() failed!"); + try { + while (fgets(buffer, sizeof buffer, pipe) != NULL) { + result += buffer; + } + } catch (...) { + pclose(pipe); + throw; + } + pclose(pipe); + return result; +} +*/ +int main(int argc, char **argv) { + + int ch = -1; + int addr = 0; + int data = 0; + int loops = 0; + bool WRITE_FLAG = false; + bool READ_FLAG = false; + bool HSLB_FLAG = false; + + for(int i=1; i<argc; i++){ + std::string ss = argv[i]; + if(ss=="--ch"){ + ch = atoi(argv[++i]); + } + if(ss=="-w" || ss=="--write"){ + WRITE_FLAG = true; + addr = strtoul(argv[++i], 0, 16); + data = strtoul(argv[++i], 0, 16); + } + if(ss=="-r" || ss=="--read"){ + READ_FLAG = true; + addr = strtoul(argv[++i], 0, 16); + } + if(ss=="-l" || ss=="--loop"){ + loops = atoi(argv[++i]); + } + if(ss=="--hslb"){ + HSLB_FLAG = true; + } + } + + struct timespec ts; + struct timespec ts1; + // Success: Returns 0 + // // Failure: Returns -1 + // // First arg: CLOCK_REALTIME, CLOCL_MONOTONIC, etc. + int ret = clock_gettime(CLOCK_REALTIME, &ts); + int result; + int valp; + ecs_open( 0 , 2 ); + for(int i=0; i<loops; i++){ + if(HSLB_FLAG){ + //int result = system("./reghsx -c fee32 0x12"); + //int result = readfee32(0, ch, addr, &valp); + //std::cout << valp << std::endl; + }else{ + if(WRITE_FLAG){ + result = pcie40_writefee32( 0 , ch , addr, data) ; + }else if (READ_FLAG){ + result = pcie40_readfee32( 0 , ch , addr) ; + } + } + //usleep(1000); + } + ecs_close( 0 , 2 ) ; + + //usleep(1e6); + + int ret1 = clock_gettime(CLOCK_REALTIME, &ts1); + + if(ret == 0 && ret1 == 0){ + std::cout << "Processing time in Seconds : " << ts1.tv_sec - ts.tv_sec << std::endl + << "Processing time in Nano seconds : " << ts1.tv_nsec - ts.tv_nsec << std::endl; + }else{ + std::cout << "Failed clock_gettime()" << std::endl; + } + return 0; +} diff --git a/Pcie40Libraries/Makefile b/Pcie40Libraries/Makefile index 8969d645969d3af8b3adff0ce4c61ab5a52264fa..b5c09f013f7f4d15ac7dd560582750b52ba222d9 100644 --- a/Pcie40Libraries/Makefile +++ b/Pcie40Libraries/Makefile @@ -29,7 +29,7 @@ LTC2990_SRC= LTC2990_OBJ=$(LTC2990_SRC:$(SRC_DIR)$(LTC2990_DIR)%.c=$(OBJ_DIR)%.o) # Belle II specific libraries (slow control, ECS, ...) -B2LIB_SRC= pcie40_b2slc.cpp pcie40_b2ecs.c pcie40_b2dma.c +B2LIB_SRC= pcie40_b2slc.cpp pcie40_reg.cpp pcie40_b2ecs.c pcie40_b2dma.c B2LIB_OBJ=$(B2LIB_SRC:%.c=$(OBJ_DIR)%.o) # static libraries diff --git a/Pcie40Libraries/pcie40_reg.cpp b/Pcie40Libraries/pcie40_reg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..160b06be34ca7b21728c0e4b737550b5d3656c97 --- /dev/null +++ b/Pcie40Libraries/pcie40_reg.cpp @@ -0,0 +1,115 @@ +#include "pcie40_reg.h" +#include <unistd.h> +#include <stdio.h> +#include <vector> +#include <string.h> + +// ===== +// CALL C functions +// ===== + +#ifndef D +#define D(a,b,c) (((a)>>(c))&((1<<((b)+1-(c)))-1)) +#define B(a,b) D(a,b,b) +#define Bs(a,b,s) (B(a,b)?(s):"") +#define Ds(a,b,c,s) (D(a,b,c)?(s):"") +#endif + +extern "C" int ecs_write(int dev, int bar, unsigned add, int val); +extern "C" unsigned ecs_read(int dev, int bar, unsigned add) ; + +int pcie40_status(int dev){ + int ret = -1; + ret = ecs_read(dev, SLC_BAR, SLC_PCIE40_STATUS); + return ret; +} + +int pcie40_run_number(int dev){ + int ret = -1; + ret = ecs_read(dev, SLC_BAR, SLC_RUM_NUMBER); + return (ret & 0xFF00) >> 8 | (ret & 0x00FF) << 8; +} + +int pcie40_trgtag_number(int dev){ + int ret = -1; + ret = ecs_read(dev, SLC_BAR, SLC_TRGTAG_NUMBER); + return ret; +} + + +//---------------------------------------------- +// Belle2link dedicated +//---------------------------------------------- +int pcie40_b2l_status(int dev, int ch){ + int ret = -1; + if(ch >= 0 && ch <=23) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_STATUS1); + else if (ch >= 24 && ch <= 47 ) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_STATUS2); + + return ( ( ret & ( 1 << ( SLC_BASE_BIT + ch ) ) ) + >> ( SLC_BASE_BIT + ch )); +} + +int pcie40_b2l_mask(int dev, int ch){ + int ret = -1; + if(ch >= 0 && ch <=23) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_MASK1); + else if (ch >= 24 && ch <= 47 ) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_MASK2); + + return ( ( ret & ( 1 << ( SLC_BASE_BIT + ch ) ) ) + >> ( SLC_BASE_BIT + ch )); +} + +int pcie40_b2l_txstatus(int dev, int ch){ + int ret = -1; + if(ch >= 0 && ch <=23) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_TX_STATUS1); + else if (ch >= 24 && ch <= 47 ) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_TX_STATUS2); + + return ( ( ret & ( 1 << ( SLC_BASE_BIT + ch ) ) ) + >> ( SLC_BASE_BIT + ch )); +} + +int pcie40_b2l_rxstatus(int dev, int ch){ + int ret = -1; + if(ch >= 0 && ch <=23) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_RX_STATUS1); + else if (ch >= 24 && ch <= 47 ) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_RX_STATUS2); + + return ( ( ret & ( 1 << ( SLC_BASE_BIT + ch ) ) ) + >> ( SLC_BASE_BIT + ch )); +} + +int pcie40_b2l_txready(int dev, int ch){ + int ret = -1; + if(ch >= 0 && ch <=23) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_TX_READY1); + else if (ch >= 24 && ch <= 47 ) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_TX_READY2); + + return ( ( ret & ( 1 << ( SLC_BASE_BIT + ch ) ) ) + >> ( SLC_BASE_BIT + ch )); +} + +int pcie40_b2l_rxready(int dev, int ch){ + int ret = -1; + if(ch >= 0 && ch <=23) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_RX_READY1); + else if (ch >= 24 && ch <= 47 ) + ret = ecs_read(dev, SLC_BAR, SLC_B2LINK_RX_READY2); + + return ( ( ret & ( 1 << ( SLC_BASE_BIT + ch ) ) ) + >> ( SLC_BASE_BIT + ch )); +} + + + + + + + + diff --git a/Pcie40Libraries/pcie40_reg.h b/Pcie40Libraries/pcie40_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..83228501ea403e3a1faea53574a015cdc556c405 --- /dev/null +++ b/Pcie40Libraries/pcie40_reg.h @@ -0,0 +1,280 @@ +/* + hsreg.h + + PCIE40 registers + + +*/ + +#ifndef __PICE40REG_H__ +#define __PICE40REG_H__ + +#include <stdint.h> +#include <stdio.h> + +#if defined(__cplusplus) +extern "C" { +#endif +#if defined(__dummy_close_bracket_to_cheat_emacs_auto_indent) +} +#endif + +#define SLC_BAR 2 + +#define SLC_BASE_BIT 0 +#define SLC_B2LINK_RX_READY1 0x000500E0 // link in the ready state for rxdata, channel 0-23, 1 bit pre channel +#define SLC_B2LINK_RX_READY2 0x00050100 // link in the ready state for rxdata, channel 0-23, 1 bit pre channel +#define SLC_B2LINK_TX_READY1 0x00050120 // link in the ready state for txdata, channel 0-23, 1 bit pre channel +#define SLC_B2LINK_TX_READY2 0x00050140 // link in the ready state for txdata, channel 0-23, 1 bit pre channel +#define SLC_B2LINK_RX_STATUS1 0x00050160 // link in the ready state for txdata, channel 0-23, 1 bit pre channel +#define SLC_B2LINK_RX_STATUS2 0x00050180 // link in the ready state for txdata, channel 0-23, 1 bit pre channel +#define SLC_B2LINK_TX_STATUS1 0x000501A0 // link in the ready state for txdata, channel 0-23, 1 bit pre channel +#define SLC_B2LINK_TX_STATUS2 0x000501C0 // link in the ready state for txdata, channel 0-23, 1 bit pre channel +#define SLC_B2LINK_STATUS1 0x000501E0 // link up/down channel 0-23, 1 bit pre channel +#define SLC_B2LINK_STATUS2 0x00050200 // link up/down channel 24-47, 1 bit pre channel +#define SLC_B2LINK_MASK1 0x00050520 // link up/down channel 0-23, 1 bit pre channel +#define SLC_B2LINK_MASK2 0x00050540 // link up/down channel 24-47, 1 bit pre channel +#define SLC_RFIFO_STATUS 0x00060010 + + +#define SLC_PCIE40_STATUS 0x00050000 +#define SLC_RUM_NUMBER 0x00050020 +#define SLC_TRGTAG_NUMBER 0x00050040 + +int pcie40_b2l_status(int dev, int ch); +int pcie40_b2l_txstatus(int dev, int ch); +int pcie40_b2l_rxstatus(int dev, int ch); +int pcie40_b2l_txready(int dev, int ch); +int pcie40_b2l_rxready(int dev, int ch); +int pcie40_b2l_mask(int dev, int ch); +int pcie40_status(int dev); +int pcie40_run_number(int dev); +int pcie40_trgtag_number(int dev); + + + + +/* FEE registers as implemented in belle2link_cdc */ + +#define PCIE40REG_SERIAL 0x00 +#define PCIE40REG_PDSTL 0x01 /* 0x01 .. 0x60 for 48 ch (x2) */ +#define PCIE40REG_PDSTLMIN 0x01 +#define PCIE40REG_PDSTLMAX 0x60 +#define PCIE40REG_ADCTH 0x61 /* same as lower 8 bit of ADC threshold setting */ +#define PCIE40REG_ADCL 0x61 +#define PCIE40REG_ADCH 0x62 +#define PCIE40REG_WINDOW 0x63 +#define PCIE40REG_DELAY 0x64 +#define PCIE40REG_TDCTH 0x65 /* same as lower 8 bit of DAC setting for TDC */ +#define PCIE40REG_DACL 0x65 +#define PCIE40REG_DACH 0x66 +#define PCIE40REG_CDCCONT 0x67 /* part of b2ldo (FEE_CONTROL) moved from 0x69 */ + +/* FEE registers for Belle2link internal use */ + +#define PCIE40REG_CRCERR 0x68 +#define PCIE40REG_FEECONT 0x69 +#define PCIE40REG_D32A 0x6a +#define PCIE40REG_D32B 0x6b +#define PCIE40REG_D32C 0x6c +#define PCIE40REG_D32D 0x6d + +/* HSLB registers in addition to predefined FINESSE registers */ + +#define PCIE40REG_D32 0x6e +#define PCIE40REG_A32 0x6f +#define PCIE40REG_STAT 0x72 /* b2ldo (STATUS) */ + +#define PCIE40REG_CCLK 0x74 /* cpld */ +#define PCIE40REG_CONF 0x75 /* cpld */ +#define PCIE40REG_CPLDVER 0x76 /* cpld */ +#define PCIE40REG_FEEHWTYPE 0x77 +#define PCIE40REG_FEESERIAL 0x78 +#define PCIE40REG_FEEFWTYPE 0x79 +#define PCIE40REG_FEEFWVER 0x7a + +#define B2LFEE_UNDEF 0 +#define B2LFEE_SVD 1 +#define B2LFEE_CDC 2 +#define B2LFEE_BPID 3 +#define B2LFEE_EPID 4 +#define B2LFEE_ECL 5 +#define B2LFEE_KLM 6 +#define B2LFEE_TRG 7 +#define B2LFEE_TEST 15 + + +/* HSLB 32-bit register extension */ + +#define PCIE40REGL_ID 0x80 +#define PCIE40REGL_VER 0x81 +#define PCIE40REGL_RESET 0x82 +#define PCIE40REGL_STAT 0x83 +/* + -- input + stal(16#81#) <= x"0000" & std_logic_vector(to_unsigned(VERSION, 16)); + + stal(16#83#)(0) <= not linkup; + stal(16#83#)(1) <= disable; + stal(16#83#)(2) <= led3; -- FFUL + stal(16#83#)(3) <= led4; -- LinkError + stal(16#83#)(4) <= led5; -- NWFF + stal(16#83#)(5) <= sta_bad127; + stal(16#83#)(6) <= not plllk; + stal(16#83#)(7) <= not stapll2; + stal(16#83#)(11 downto 8) <= stateff; + stal(16#83#)(15 downto 12) <= staterx; + stal(16#83#)(19 downto 16) <= statepr; + stal(16#83#)(23 downto 20) <= statept; + stal(16#83#)(28 downto 24) <= statetx; + stal(16#83#)(29) <= not stapll; + stal(16#83#)(30) <= not fwenb; + stal(16#83#)(31) <= stalinkdown; + + stal(16#84#) <= cntlinkdown(7 downto 0) & cntcrcerr(7 downto 0) & rxdata; + stal(16#85#) <= cnt_evtsz & cnt_maxsz; + stal(16#86#) <= cnt_event; -- number of events into copper fifo + stal(16#87#) <= cnt_sec127; + + stal(16#88#) <= cnt_nword(39 downto 8); + + stal(16#89#)(31 downto 28) <= cnt_oflow; + stal(16#89#)(27 downto 24) <= cnt_badalign; + stal(16#89#)(23 downto 20) <= cnt_realign; + stal(16#89#)(19) <= badalign; + stal(16#89#)(18) <= rxrealign; + stal(16#89#)(17) <= not rxaligned; + stal(16#89#)(16) <= not led6; -- sta_rxbyteisaligned + stal(16#89#)(15 downto 8) <= cnt_fwclk; + stal(16#89#)(7 downto 0) <= cnt_nword(7 downto 0); + + stal(16#8c#)(31 downto 16) <= cntvetoidle; + stal(16#8c#)(15 downto 0) <= cntvetodata; + stal(16#8d#)(25 downto 24) <= bufvetodown(53 downto 52); + stal(16#8d#)(21 downto 20) <= bufvetodown(51 downto 50); + stal(16#8d#)(17 downto 16) <= bufvetodown(49 downto 48); + stal(16#8d#)(15 downto 0) <= bufvetodown(47 downto 32); + stal(16#8e#)(31 downto 0) <= bufvetodown(31 downto 0); + + stal(16#8f#) <= dbg; + + -- output + setrunreset <= regl(16#82#)(0); + b2lreset <= regl(16#82#)(4); + txreset <= regl(16#82#)(8); + gtpreset <= regl(16#82#)(12); + clrpll <= regl(16#82#)(16); + clrpll2 <= regl(16#82#)(20); + usebadidle <= regl(16#8b#)(1); + usebaddata <= regl(16#8b#)(0); +*/ +#define PCIE40REGL_RXDATA 0x84 /* stal(16#84#) <= cntcrcerr & rxdata; */ +#define PCIE40REGL_EVENTSZ 0x85 +#define PCIE40REGL_NEVENT 0x86 +#define PCIE40REGL_UPTIME 0x87 +#define PCIE40REGL_NKBYTE 0x88 +#define PCIE40REGL_NWORD 0x89 +#define PCIE40REGL_VETOSET 0x8b +#define PCIE40REGL_VETOCNT 0x8c +#define PCIE40REGL_VETOBUF0 0x8d +#define PCIE40REGL_VETOBUF1 0x8e +#define PCIE40REGL_CNTFF00 0x95 /* new in hslb055 */ +#define PCIE40REGL_CNTDATAPKT 0x96 /* new in hslb055 */ +#define PCIE40REGL_CNTDATAWORD 0x97 /* new in hslb055 */ + +static const int hsreg_revision = 1; + +struct pcie40reg { + uint32_t stat; /* 72 */ + uint8_t csr; /* 73 */ + uint8_t xbusy; /* 74 */ + uint8_t conf; /* 75 */ + uint8_t feehw; /* 77 >> 4 */ + uint8_t feefw; /* 79 >> 4 */ + uint8_t feecrce; /* 68 */ + uint16_t feeser; /* 78 | ((77 & f) << 8) */ + uint16_t feever; /* 7a | ((79 & f) << 8) */ + uint32_t pcie40id; /* 80 */ + uint32_t pcie40ver; /* 81 */ + uint32_t pcie40rst; /* 82 */ + uint32_t pcie40sta; /* 83 */ + uint32_t rxdata; /* 84 */ + uint32_t eventsz; /* 85 */ + uint32_t nevent; /* 86 */ + uint32_t uptime; /* 87 */ + uint32_t nkbyte; /* 88 */ + uint32_t nword; /* 89 */ + uint32_t vetoset; /* 8b */ + uint32_t vetocnt; /* 8c */ + uint32_t vetobuf[2]; /* 8d, 8e */ + uint32_t cntff00; /* 95 */ + uint32_t cntdatapkt; /* 96 */ + uint32_t cntdataword; /* 97 */ +}; + +typedef struct pcie40reg pcie40reg_t; + + +int pcie40reg_read(int fd /* 0-3 */, pcie40reg_t*); +int pcie40reg_getfee(int fd /* 0-3 */, pcie40reg_t*); + +/* ---------------------------------------------------------------------- *\ + * feename + * +\* ---------------------------------------------------------------------- */ +const char * +feename(int hwtype, int fwtype) +{ + static const char *feetype[] = { + "UNDEF", "SVD", "CDC", "TOP", "ARI", "ECL", "EECL", "KLM", "EKLM", + "TRG", "FEE10", "FEE11", "FEE12", "FEE13", "DEMO", "TEST" }; + static const char *demotype[] = { + "UNDEF", "HSLB-B2L", "SP605-B2L", "ML605-B2L", "AC701-B2L" }; + static const char *trgtype[] = { + "TRGMERGER", /* = 0 */ + "TRGTSF", /* = 1 */ + "TRG2D", /* = 2 */ + "TRG3D", /* = 3 */ + "TRGNN", /* = 4 */ + "TRGEVTT", /* = 5 */ + "TRGGRL", /* = 6 */ + "TRGGDL", /* = 7 */ + "TRGETM", /* = 8 */ + "TRGTOP", /* = 9 */ + "TRGKLM", /* = 10 */ + }; + + hwtype &= 0x0f; + fwtype %= 16; + + if (hwtype == 14 && fwtype > 0 && fwtype <= 4) { + return demotype[fwtype]; + } else if (hwtype == 9 && fwtype >= 0 && fwtype <= 10) { + return trgtype[fwtype]; + } else { + int i; + static int ringi = 0; + static int ringval[32]; + static char ringbuf[32][20]; + for (i=0; i<32; i++) { + if (ringval[i] == 0x100 + (hwtype<<4) + fwtype) break; + } + if (i == 32) { + i = ringi; + ringval[i] = 0x100 + (hwtype<<4) + fwtype; + sprintf(ringbuf[i], "%s", feetype[hwtype]); + ringi = (ringi + 1) % 32; + } + return ringbuf[i]; + } +} + +#if defined(__dummy_open_bracket_to_cheat_emacs_auto_indent) +__dummy_open_bracket_to_cheat_emacs_auto_indent { +#endif +#if defined(__cplusplus) +} +#endif + +#endif /* __PCIE40REG_H__ */ +