Skip to content
Snippets Groups Projects
main_pcie40_statlink.cpp 8 KiB
Newer Older

/*-------------------------------------------------------------------------------*\
  statlink: Monitoring the status of PCIe40 board and belle2links
Patrick Robbe's avatar
Patrick Robbe committed
 
  Qi-Dong Zhou, KEK 

  2020.04.28  0.01 first version based on staths.c
qzhou's avatar
qzhou committed
  2020.12.19  0.01 rename statlink to pcie40_statlink
  2020.12.23  0.02 add protection for pll status access
\*--------------------------------------------------------------------------------*/
qzhou's avatar
qzhou committed
#define VERSION 02
#define MOD_DATE 20200428

#include "pcie40_b2slc.h"
#include "pcie40_reg.h"
#include "pcie40_b2config.h"
qzhou's avatar
qzhou committed
#include "pcie40_ecs.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <bitset>
qzhou's avatar
qzhou committed
#include <sys/file.h>
#define MAX_NUM_CH   48
#define MAX_SLOT     3
#define SLC_BAR      2
qzhou's avatar
qzhou committed
#define SIZE_MEMO_FPGA 1024 // maximum size of memory in FPGA
bool INFO = false;

#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 
qzhou's avatar
qzhou committed
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);
qzhou's avatar
qzhou committed
	exit(1);
    if(ss=="--info"){
      INFO = true;
    }
    if(ss=="--ch"){
      for(int j = i+1; j<argc; j++){
	std::string sss = argv[j];
	if(sss == "--info")break;
	if(sss == "all"){
	  link_mask.set();	
	  break;	
	}
	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);
qzhou's avatar
qzhou committed
	  exit(1);
	}
	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); 
qzhou's avatar
qzhou committed
      exit(1);
/* ---------------------------------------------------------------------- *\
qzhou's avatar
qzhou committed
 *    statpcie40
\* ---------------------------------------------------------------------- */
int
qzhou's avatar
qzhou committed
statpice40(pcie40reg_t pcie40reg)
  FILE *fp = fopen("/tmp/pcie40_pll_lockfile.lck","w");
qzhou's avatar
qzhou committed
  pcie40reg_t *pcie = &pcie40reg;
qzhou's avatar
qzhou committed
  memset(pcie, 0, sizeof(*pcie));
qzhou's avatar
qzhou committed
  int pcie40_sta = pcie40_status(dev_slot);
  std::cout << "PCIE40 firmware version " << pcie40_fpgaVersion(dev_slot) << std::endl;
qzhou's avatar
qzhou committed
  printf("memory: %s | ttd: %s |  ttd clk: %s | run=: %d | trg: %d | trg type: %d\n", 
qzhou's avatar
qzhou committed
	 B(pcie40_sta, 8)?"FULL":"OK",
	 B(pcie40_sta, 12)?"UP":"DOWN",
	 B(pcie40_sta, 11)?"UP":"DOWN",
	 pcie40_run_number(dev_slot),
qzhou's avatar
qzhou committed
	 D(pcie40_sta, 28, 17),
	 pcie40_trg_type(dev_slot));	 
qzhou's avatar
qzhou committed
  flock( fileno(fp), LOCK_EX );
  printf("PLLs:%s | rxlink: %s | txlink: %s | txlink: %s | rxdisp: %s | rxdata: %s\n", 	  
	 (pcie40_pllLockStatus(dev_slot, 1)&&pcie40_pllLockStatus(dev_slot, 2)&&pcie40_pllLockStatus(dev_slot, 3))?"LOCKED":"NOT LOCKED",
qzhou's avatar
qzhou committed
	 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");
  if(INFO){
qzhou's avatar
qzhou committed
    printf("__________________________________\n");
    printf("Input frequency = %f [MHz]\n",(double)pcie40_inputPLLFrequency(dev_slot)/1000000);
    printf("--------\n");
    printf("PLL No.   :   Lock sta | Input sta | Fre. sta | Lock cnt | Input. cnt | Fre. cnt\n");
    printf("PLL[0-23] : %*s | %s | %s | %s | %s | %s\n", 10,
	   pcie40_pllLockStatus(dev_slot, 1)?"LOCKED":"NOT LOCKED",
	   pcie40_pllInputStatus(dev_slot, 1)?"OK ":"BAD",
	   pcie40_pllFrequencyStatus(dev_slot, 1)?"OK ":"BAD",
	   pcie40_pllLockCounter(dev_slot, 1)?"OK ":"LOL",
	   pcie40_pllInputCounter(dev_slot, 1)?"OK ":"LOS",
	   pcie40_pllFrequencyCounter(dev_slot, 1)?"OK ":"OOF");
    printf("PLL[24-47]: %*s | %s | %s | %s | %s | %s\n", 10,
	   pcie40_pllLockStatus(dev_slot, 2)?"LOCKED":"NOT LOCKED",
	   pcie40_pllInputStatus(dev_slot, 2)?"OK ":"BAD",
	   pcie40_pllFrequencyStatus(dev_slot, 2)?"OK ":"BAD",
	   pcie40_pllLockCounter(dev_slot, 2)?"OK ":"LOL",
	   pcie40_pllInputCounter(dev_slot, 2)?"OK ":"LOS",
	   pcie40_pllFrequencyCounter(dev_slot, 2)?"OK ":"OOF");
    printf("PLL[FTSW] : %*s | %s | %s | %s | %s | %s\n", 10,
	   pcie40_pllLockStatus(dev_slot, 3)?"LOCKED":"NOT LOCKED",
	   pcie40_pllInputStatus(dev_slot, 3)?"OK ":"BAD",
	   pcie40_pllFrequencyStatus(dev_slot, 3)?"OK ":"BAD",
	   pcie40_pllLockCounter(dev_slot, 3)?"OK ":"LOL",
	   pcie40_pllInputCounter(dev_slot, 3)?"OK ":"LOS",
	   pcie40_pllFrequencyCounter(dev_slot, 3)?"OK ":"OOF");
    printf("__________________________________\n");
qzhou's avatar
qzhou committed
  }
  flock( fileno(fp), LOCK_UN );
  fclose(fp);
/* ---------------------------------------------------------------------- *\
 *    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++) {
qzhou's avatar
qzhou committed
    pcie40reg_t *pcie = &pcie40reg[i];
    double total;
    char prompt[128];
    
qzhou's avatar
qzhou committed
    if (!link_mask[i]) continue;
    quiet = 0;
    if (! first) printf("\n");
    first =0;
    
qzhou's avatar
qzhou committed
    sprintf(prompt, "(%02d)    ", i);
    
    printf("%s", prompt);
qzhou's avatar
qzhou committed
    printf("b2l=%s (gbt=%s rx=%s tx=%s rxsta=%s txsta=%s mask=%s)\n",
qzhou's avatar
qzhou committed
	   pcie40_b2l_status(dev_slot, i)?"UP":"DOWN",
qzhou's avatar
qzhou committed
	   pcie40_gbt_status(dev_slot, i)?"UP":"DOWN",
qzhou's avatar
qzhou committed
	   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);
qzhou's avatar
qzhou committed
    if ( pcie40_b2l_usebadidle(dev_slot, i) == 0 && pcie40_b2l_usebaddata(dev_slot, i) == 0) {
      printf("no b2link error correction");
qzhou's avatar
qzhou committed
    } else if (pcie40_b2l_cnt_vetoidle(dev_slot, i) == 0 && pcie40_b2l_cnt_vetodata(dev_slot, i) == 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",
qzhou's avatar
qzhou committed
	     pcie40_b2l_cnt_vetoidle(dev_slot, i),
	     pcie40_b2l_usebadidle(dev_slot, i) ? 'i' : '-',
	     pcie40_b2l_cnt_vetodata(dev_slot, i),
	     pcie40_b2l_usebaddata(dev_slot, i) ? 'd' : '-',
	     B(pcie40_b2l_3rdcharisk(dev_slot, i), 1)?'K':'D', D(pcie40_b2l_3rdrxdata(dev_slot, i),15,8),
	     B(pcie40_b2l_3rdcharisk(dev_slot, i), 0)?'K':'D', D(pcie40_b2l_3rdrxdata(dev_slot, i),7,0),
	     B(pcie40_b2l_2ndcharisk(dev_slot, i), 1)?'K':'D', D(pcie40_b2l_2ndrxdata(dev_slot, i),15,8),
	     B(pcie40_b2l_2ndcharisk(dev_slot, i), 0)?'K':'D', D(pcie40_b2l_2ndrxdata(dev_slot, i),7,0),
	     B(pcie40_b2l_1stcharisk(dev_slot, i), 1)?'K':'D', D(pcie40_b2l_1strxdata(dev_slot, i),15,8),
	     B(pcie40_b2l_1stcharisk(dev_slot, i), 0)?'K':'D', D(pcie40_b2l_1strxdata(dev_slot, i),7,0));
    }
    printf("\n");
  }

  if (quiet) {
    printf("no B2LINK No. was found\n");
int main(int argc, char** argv){
  
  // parse arguments
  argument(argc, argv);
qzhou's avatar
qzhou committed

  pcie40reg_t pcie40;
  pcie40reg_t pcie40reg[48];
qzhou's avatar
qzhou committed
  // open pcie40 device driver for current process
  ecs_open( dev_slot , SLC_BAR );
  
  printf("statlink version %d (%d) / ", VERSION, MOD_DATE);
  statpice40(pcie40);
  
  statlink(link_mask, pcie40reg);
  
  // close pcie40 device driver for current process
  ecs_close( dev_slot , SLC_BAR) ;