LCOV - code coverage report
Current view: top level - mu2e-pcie-utils/mcs - mcs.cc (source / functions) Coverage Total Hit
Test: mu2edaq.info.cleaned Lines: 0.0 % 186 0
Test Date: 2026-07-30 01:56:44 Functions: 0.0 % 4 0

            Line data    Source code
       1              : // This file (mcs.cc) was created by Ron Rechenmacher <ron@fnal.gov> on
       2              : // May 19, 2014. "TERMS AND CONDITIONS" governing this file are in the README
       3              : // or COPYING file. If you do not have such a file, one can be obtained by
       4              : // contacting Ron or Fermi Lab in Batavia IL, 60510, phone: 630-840-3000.
       5              : // $RCSfile: .emacs.gnu,v $
       6              : const char *rev = "$Revision: 1.23 $$Date: 2012/01/23 15:32:40 $";
       7              : 
       8              : #include <getopt.h>  // getopt_long
       9              : #include <libgen.h>  // basename
      10              : #include <stdio.h>   // printf
      11              : #include <stdlib.h>  // setenv
      12              : 
      13              : #include "trace.h"  // TRACE
      14              : 
      15              : #include "pcidevl_ioctl.h"
      16              : 
      17              : #define USAGE \
      18              :         "\
      19              : usage: %s [opts] <mcs_file>\n\
      20              :     -e            just erase (then exit)\n\
      21              :    --swap-data    swap the data\n\
      22              : ",            \
      23              :                 basename(argv[0])
      24              : 
      25              : int g_fd;
      26              : 
      27              : // 32bit byte and half word swap
      28            0 : inline uint32_t swab32(uint32_t a)
      29              : {
      30            0 :         return ((0xFF000000 & a) >> 24) | ((0x00FF0000 & a) >> 8) | ((0x0000FF00 & a) << 8) | ((0x000000FF & a) << 24);
      31              : }  // swab32
      32              : 
      33            0 : int set_prom_program_data_reg32(uint32_t data)
      34              : {
      35              :         ioc_ioop ioop;
      36            0 :         ioop.offset = 0x9400;
      37            0 :         ioop.ops_mask = ioop_write;
      38            0 :         ioop.write_val = data;
      39            0 :         TRACE(5, "set_prom_program_status_reg32 0x%08x ==>", ioop.write_val);
      40            0 :         int sts = ioctl(g_fd, IOC_IOOP, &ioop);
      41            0 :         return sts;
      42              : }
      43              : 
      44            0 : int get_prom_program_status_reg32(uint32_t *val)
      45              : {
      46              :         ioc_ioop ioop;
      47            0 :         ioop.offset = 0x9404;
      48            0 :         ioop.ops_mask = ioop_read;
      49            0 :         int sts = ioctl(g_fd, IOC_IOOP, &ioop);
      50            0 :         *val = ioop.read_val;
      51            0 :         TRACE(5, "get_prom_program_status_reg32 val=0x%08x", ioop.read_val);
      52            0 :         return sts;
      53              : }
      54              : 
      55            0 : int main(int argc, char *argv[])
      56              : {
      57            0 :         int opt_v = 0;
      58            0 :         int opt_just_erase = 0;
      59            0 :         int opt_data_swap = 0;
      60              :         extern int optind; /* for getopt */
      61              :         char devfile[13];  /* /dev/pcidevX */
      62              : 
      63              :         while (1)
      64              :         {
      65            0 :                 int opt, option_index = 0;
      66              :                 static struct option long_options[] = {
      67              :                         /* name,   has_arg, int* flag, val_for_flag */
      68              :                         {"swap-data", 0, 0, 1},
      69              :                         {0, 0, 0, 0},
      70              :                 };
      71            0 :                 opt = getopt_long(argc, argv, "?hVve", long_options, &option_index);
      72            0 :                 if (opt == -1) break;
      73            0 :                 switch (opt)
      74              :                 {
      75            0 :                         case '?':
      76              :                         case 'h':
      77            0 :                                 printf(USAGE);
      78            0 :                                 exit(0);
      79              :                                 break;
      80            0 :                         case 'V':
      81            0 :                                 printf("%s\n", rev);
      82            0 :                                 return (0);
      83              :                                 break;
      84            0 :                         case 'v':
      85            0 :                                 opt_v++;
      86            0 :                                 break;
      87            0 :                         case 'e':
      88            0 :                                 opt_just_erase = 1;
      89            0 :                                 break;
      90            0 :                         case 1:
      91            0 :                                 opt_data_swap = 1;
      92            0 :                                 break;
      93            0 :                         default:
      94            0 :                                 printf("?? getopt returned character code 0%o ??\n", opt);
      95              :                 }
      96            0 :         }
      97            0 :         if (argc - optind < 2)
      98              :         {
      99            0 :                 printf("Need mcs_file and device number\n");
     100            0 :                 printf(USAGE);
     101            0 :                 return (-1);
     102              :         }
     103              : 
     104            0 :         setenv("TRACE_LVLS", "0xf", 0);  // setenv( "TRACE_NAME", "mcs", 0 );
     105            0 :         TRACE_CNTL("lvlset", 0xffffffffULL, strtoull(getenv("TRACE_LVLS"), NULL, 0), 0ULL);
     106            0 :         TRACE_CNTL("mode", 3ULL);
     107            0 :         TRACE(1, "hello");
     108              : 
     109            0 :         snprintf(devfile, 13, "/dev/" PCIDEVL_DEV_FILE, atoi(argv[optind++]));
     110              : 
     111            0 :         int fd = open(devfile, O_RDONLY);
     112            0 :         if (fd == -1)
     113              :         {
     114            0 :                 perror("open"); /*return (1);*/
     115              :         }
     116            0 :         g_fd = fd;
     117              : 
     118            0 :         FILE *stream = fopen(argv[optind], "r");
     119              : 
     120            0 :         int lines = 0, data_bytes = 0;
     121            0 :         unsigned StartBlockSet = 0, StartBlock, EndBlock, LastAddr = 0;
     122              :         int bytecount;
     123              :         unsigned address, RecType, data, checksum;
     124              :         int sts;
     125            0 :         while ((sts = fscanf(stream, ":%2x%4x%2x", (unsigned *)&bytecount, &address, &RecType)) == 3)
     126              :         {
     127            0 :                 if (RecType == 4)
     128              :                 {
     129            0 :                         if (StartBlockSet != 1)
     130              :                         {
     131            0 :                                 StartBlockSet = 1;
     132            0 :                                 sts = fscanf(stream, "%4x", &StartBlock);
     133            0 :                                 if (sts != 1)
     134              :                                 {
     135            0 :                                         TRACE(0, "Error getting StartBlock");
     136            0 :                                         return -1;
     137              :                                 }
     138              :                         }
     139              :                         else
     140              :                         {
     141            0 :                                 if (fscanf(stream, "%4x", &EndBlock) != 1)
     142              :                                 {
     143            0 :                                         TRACE(0, "Error getting EndBlock");
     144            0 :                                         return -1;
     145              :                                 }
     146              :                         }
     147            0 :                         bytecount -= 2;
     148              :                 }
     149            0 :                 else if (RecType == 0)
     150              :                 {
     151            0 :                         LastAddr = address;
     152              :                 }
     153            0 :                 while (bytecount--)
     154              :                 {
     155            0 :                         sts = fscanf(stream, "%2x", &data);
     156            0 :                         if (sts != 1)
     157              :                         {
     158            0 :                                 printf("did not get data\n");
     159            0 :                                 return -1;
     160              :                         }
     161              :                 }
     162            0 :                 sts = fscanf(stream, "%2x\n", &checksum);
     163            0 :                 lines++;
     164              :         }
     165            0 :         int FileSize = (((EndBlock << 16) | LastAddr) / 2) - ((StartBlock << 16) / 2);  // file size in bytes
     166            0 :         TRACE(1, "got %d lines. StartBlock=0x%x EndBlock=0x%x LastAddr=0x%x FileSize=%d", lines, StartBlock, EndBlock,
     167              :                   LastAddr, FileSize);
     168              : 
     169              :         // rewind
     170            0 :         fseek(stream, 0, SEEK_SET);
     171            0 :         lines = 0;
     172              : 
     173            0 :         uint32_t ReadMask = 0x1;
     174              :         uint32_t ReadData;
     175            0 :         sts = get_prom_program_status_reg32(&ReadData);
     176            0 :         if (sts) TRACE(0, "unexpected status");
     177            0 :         if ((ReadData & ReadMask) != ReadMask)
     178              :         {
     179            0 :                 TRACE(0, "not ready");
     180            0 :                 return -1;
     181              :         }
     182              : 
     183              :         // unlock all blocks
     184            0 :         uint32_t StartBlock_w = StartBlock / 2;  // bytes to "words" (1 word == 2 bytes)
     185              : 
     186            0 :         sts = set_prom_program_data_reg32(0x53410000 | (StartBlock_w << 8));
     187            0 :         if (sts) TRACE(0, "unexpected status");
     188            0 :         sts = set_prom_program_data_reg32(0x45000000 | (((EndBlock << 16) | LastAddr) / 2));
     189            0 :         if (sts) TRACE(0, "unexpected status");
     190            0 :         sts = set_prom_program_data_reg32(0x556e6c6b);
     191            0 :         if (sts) TRACE(0, "unexpected status");
     192              : 
     193            0 :         ReadData = 0;
     194            0 :         uint32_t checks = 0;
     195            0 :         while ((ReadData & ReadMask) != ReadMask)
     196              :         {
     197            0 :                 sts = get_prom_program_status_reg32(&ReadData);
     198            0 :                 if (sts) TRACE(0, "unexpected status");
     199            0 :                 checks++;
     200              :         }
     201            0 :         TRACE(1, "after unlock, checks=%u ReadData=0x%x", checks, ReadData);
     202              : 
     203              :         // Erase blocks
     204            0 :         sts = set_prom_program_data_reg32(0x45726173);
     205            0 :         if (sts) TRACE(0, "unexpected status");
     206            0 :         ReadData = checks = 0;
     207            0 :         while ((ReadData & ReadMask) != ReadMask)
     208              :         {
     209            0 :                 sts = get_prom_program_status_reg32(&ReadData);
     210            0 :                 if (sts) TRACE(0, "unexpected status");
     211            0 :                 checks++;
     212              :         }
     213            0 :         TRACE(1, "after Erase, checks=%u ReadData=0x%x", checks, ReadData);
     214              : 
     215            0 :         if (opt_just_erase) return (0);
     216              : 
     217              :         // Program
     218            0 :         sts = set_prom_program_data_reg32(0x50726f67);
     219            0 :         if (sts) TRACE(0, "unexpected status");
     220              : 
     221            0 :         ReadMask = 0xff0000;
     222              : 
     223            0 :         while ((sts = fscanf(stream, ":%2x%4x%2x", (unsigned *)&bytecount, &address, &RecType)) == 3)
     224              :         {
     225            0 :                 switch (RecType)
     226              :                 {
     227            0 :                         case 0:
     228            0 :                                 TRACE(4, "Data Record - bytecount=0x%02x, address0x%04x", bytecount, address);
     229            0 :                                 ReadData = checks = 0;
     230            0 :                                 if ((data_bytes % 64) == 0)
     231            0 :                                         while ((ReadData & ReadMask) != 0x800000)
     232              :                                         {
     233            0 :                                                 sts = get_prom_program_status_reg32(&ReadData);
     234            0 :                                                 if (sts) TRACE(0, "unexpected status");
     235            0 :                                                 if ((ReadData & ReadMask) == 0x900000)
     236              :                                                 {
     237            0 :                                                         TRACE(0, "program error ReadData=0x%x checks=%u data_bytes=%d", ReadData, checks, data_bytes);
     238            0 :                                                         return -1;
     239              :                                                 }
     240            0 :                                                 checks++;
     241            0 :                                                 if (checks == 10000000)
     242              :                                                 {
     243            0 :                                                         TRACE(0, "program timeout ReadData=0x%x", ReadData);
     244            0 :                                                         return -1;
     245              :                                                 }
     246              :                                         }
     247            0 :                                 TRACE(1, "before set_prom_program_data_reg32, checks=%u data_bytes=%d", checks, data_bytes);
     248            0 :                                 while (bytecount > 0)
     249              :                                 {
     250            0 :                                         sts = fscanf(stream, "%8x", &data);
     251            0 :                                         if (sts != 1)
     252              :                                         {
     253            0 :                                                 printf("did not get data\n");
     254            0 :                                                 return -1;
     255              :                                         }
     256              : 
     257            0 :                                         if (opt_data_swap)
     258            0 :                                                 sts = set_prom_program_data_reg32(swab32(data));
     259              :                                         else
     260            0 :                                                 sts = set_prom_program_data_reg32(data);
     261            0 :                                         if (sts) TRACE(0, "unexpected status");
     262            0 :                                         bytecount -= 4;
     263            0 :                                         data_bytes += 4;
     264              :                                 }
     265            0 :                                 sts = fscanf(stream, "%2x\n", &checksum);
     266            0 :                                 if (sts != 1)
     267              :                                 {
     268            0 :                                         printf("did not get checksum\n");
     269            0 :                                         return -1;
     270              :                                 }
     271            0 :                                 break;
     272            0 :                         case 1:
     273            0 :                                 TRACE(3, "End of File - bytecount=0x%02x, address0x%04x", bytecount, address);
     274            0 :                                 while (bytecount--)
     275              :                                 {
     276            0 :                                         sts = fscanf(stream, "%2x", &data);
     277            0 :                                         if (sts != 1)
     278              :                                         {
     279            0 :                                                 printf("did not get data\n");
     280            0 :                                                 return -1;
     281              :                                         }
     282              :                                 }
     283            0 :                                 sts = fscanf(stream, "%2x\n", &checksum);
     284            0 :                                 if (sts != 1)
     285              :                                 {
     286            0 :                                         printf("did not get checksum\n");
     287            0 :                                         return -1;
     288              :                                 }
     289            0 :                                 break;
     290            0 :                         case 4:
     291            0 :                                 TRACE(3, "Extended Linear Address - bytecount=0x%02x, address0x%04x", bytecount, address);
     292            0 :                                 while (bytecount--)
     293              :                                 {
     294            0 :                                         sts = fscanf(stream, "%2x", &data);
     295            0 :                                         if (sts != 1)
     296              :                                         {
     297            0 :                                                 printf("did not get data\n");
     298            0 :                                                 return -1;
     299              :                                         }
     300              :                                 }
     301            0 :                                 sts = fscanf(stream, "%2x\n", &checksum);
     302            0 :                                 if (sts != 1)
     303              :                                 {
     304            0 :                                         printf("did not get checksum\n");
     305            0 :                                         return -1;
     306              :                                 }
     307            0 :                                 break;
     308            0 :                         default:
     309            0 :                                 TRACE(1, "Programming - ignoring record type %d\n", RecType);
     310            0 :                                 while (bytecount--)
     311              :                                 {
     312            0 :                                         sts = fscanf(stream, "%2x", &data);
     313            0 :                                         if (sts != 1)
     314              :                                         {
     315            0 :                                                 printf("did not get data\n");
     316            0 :                                                 return -1;
     317              :                                         }
     318              :                                 }
     319            0 :                                 sts = fscanf(stream, "%2x\n", &checksum);
     320            0 :                                 if (sts != 1)
     321              :                                 {
     322            0 :                                         printf("did not get checksum\n");
     323            0 :                                         return -1;
     324              :                                 }
     325              :                 }
     326            0 :                 lines++;
     327              :         }
     328            0 :         TRACE(1, "got %d lines, %d data_bytes", lines, data_bytes);
     329              : 
     330            0 :         return (0);
     331              : }  // main
        

Generated by: LCOV version 2.0-1