edt_optstring.c

00001 /* #pragma ident "@(#)edt_optstring.c   1.40 04/07/09 EDT" */
00002 
00003 #include "edtinc.h"
00004 
00005 #include <stdlib.h>
00006 #include <ctype.h> /* isdigit */
00007 
00008 #include "edt_optstring.h"
00009 #include "edt_bitload.h"
00010 
00011 /* extended board information. (configuration and installed options) */
00012 char *srxl_extbdid_info[] =
00013 {
00014     "Spartan 3 XC3S1500 -4, Two 4-channel DDC Graychips (GC4016)",      /* idx = 0 */
00015     "Spartan 3 XC3S1500 -4, One 4-channel DDC Graychip (GC4016)",       /* idx = 1 */
00016     "Spartan 3 XC3S1500 -4, NO DDC Graychips installed!",                       /* idx = 2 */
00017     NULL
00018 };
00019 
00020 
00021 int
00022 edt_ui_loaded(EdtDev *edt_p)
00023 
00024 {
00025     return (edt_reg_read(edt_p, EDT_DMA_CFG) & X_DONE) != 0;
00026 }
00027 
00039 int
00040 edt_read_old_option_string(EdtDev *edt_p, char *s)
00041 
00042 {
00043 
00044     int index=0;
00045 
00046     int ch;
00047 
00048     edt_reg_write(edt_p, EDT_OLD_BITFILE_STRING, 0);
00049     ch = edt_reg_read(edt_p, EDT_OLD_BITFILE_STRING);
00050 
00051     if (ch == 0 || ch == 0xff)
00052     {
00053         s[0] = 0;
00054         return -1;
00055     }
00056     else
00057     {
00058         while (ch && index < 16)
00059         {
00060             edt_reg_write(edt_p, EDT_OLD_BITFILE_STRING, index);
00061             ch = edt_reg_read(edt_p, EDT_OLD_BITFILE_STRING);
00062             s[index] = ch;
00063             index ++;
00064         }
00065     }
00066 
00067     s[index] = 0;
00068 
00069     return 0;
00070 
00071 }
00072 
00086 int
00087 edt_read_mezz_option_string(EdtDev *edt_p, char *s, int offset)
00088 
00089 {
00090 
00091     int index=0;
00092 
00093     int ch;
00094 
00095     u_int reg_addr = EDT_MEZZ_BITFILE_STRING + offset;
00096 
00097     edt_reg_write(edt_p, reg_addr, 0);
00098     ch = edt_reg_read(edt_p, reg_addr);
00099 
00100     if (ch == 0 || ch == 0xff)
00101     {
00102         return -1;
00103     }
00104     else
00105     {
00106         while (ch && index < 31)
00107         {
00108             edt_reg_write(edt_p, reg_addr, index);
00109             ch = edt_reg_read(edt_p, reg_addr);
00110             s[index] = ch;
00111             index ++;
00112         }
00113     }
00114 
00115     s[index] = 0;
00116     /* set pointer back to first cfg */
00117     edt_reg_write(edt_p, reg_addr, 0);
00118 
00119     return 0;
00120 
00121 }
00122 
00135 int
00136 edt_read_option_string(EdtDev *edt_p, char *s , int *rev_p)
00137 
00138 {
00139     int index=0;
00140     int rev;
00141 
00142     int ch;
00143 
00144     rev = edt_reg_read(edt_p, EDT_BITFILE_VERSION);
00145 
00146     if (rev_p)
00147         *rev_p = rev;
00148 
00149     edt_reg_write(edt_p, EDT_BITFILE_STRING, 0);
00150     ch = edt_reg_read(edt_p, EDT_BITFILE_STRING);
00151 
00152     /* 0xff usually indicates bitfile hasn't implented that register; 
00153     * 0xcc means no bitfile has been loaded */
00154     if (ch == 0 || ch == 0xff || ch == 0xcc)
00155     {
00156         if (rev_p)
00157             *rev_p = 0;
00158 
00159 
00160         return -1;
00161 
00162     }
00163     else
00164     {
00165         while (ch && index < 64)
00166         {
00167             edt_reg_write(edt_p, EDT_BITFILE_STRING, index);
00168             ch = edt_reg_read(edt_p, EDT_BITFILE_STRING);
00169             s[index] = ch;
00170             index ++;
00171         }
00172     }
00173 
00174     s[index] = 0;
00175 
00176     return 0;
00177 
00178 }
00179 
00180 static char *baseboard_names[] = {
00181     "unknown",
00182     "pciss",
00183     "pcigs",
00184     "cda",
00185     NULL
00186 };
00187 
00188 
00189 static char *mezzanine_names[] = {
00190     "RS422 I/O Board",
00191     "LVDS I/O Board",
00192     "ID is Extended, this is not a valid ID!",
00193     "RS422_12_LVDS_8",
00194     "SSE (high speed serial ECL) I/O Board",
00195     "HRC for E4/STM-1/OC-3 I/O",
00196     "OCM Board",
00197     "ComboII I/O LVDS Board",
00198     "ECL I/O Board",
00199     "TLK1501 I/O Board",
00200     "SRXL Board",
00201     "COMBOIII RS422",
00202     "COMBOIII LVDS",
00203     "COMBOIII ECL",
00204     "COMBOII I/O RS422",
00205     "COMBO I/O Board",                  /* idx = 15 */
00206     "16TE3IO Board",                    /* idx = 16 */
00207     "OC192",                    /* idx = 17 */
00208     "3X3G",                    /* idx = 18 */
00209     "MSDV",
00210     "SRXL2",
00211     "NET10G",
00212     "DRX",
00213     "DDSP",
00214     "SRXL2_IDMLBM",
00215     "SRXL2_IDMIDM",
00216     "SRXL2_IMMIMM",
00217     "SRXL2_IMMLBM",
00218     "SRXL2_IDMIMM",
00219     "DRX16",
00220     "OCM2P7G",
00221     "THREEP",
00222     "FAN",
00223     "",
00224     0
00225 };
00226 
00236 char *
00237 edt_mezz_name(int mezz_id)
00238 
00239 {
00240     if (mezz_id >= 0 && mezz_id <= MEZZ_LAST && mezzanine_names[mezz_id])
00241         return mezzanine_names[mezz_id];
00242 
00243     return "unknown id";
00244 }
00245 
00246 char *
00247 edt_default_base_for_mezz(EdtDev *edt_p)
00248 
00249 {
00250     switch (edt_p->mezz.id)
00251     {
00252     case MEZZ_OCM:
00253         return "ocm.bit";
00254         break;
00255 
00256     case MEZZ_OC192:
00257         return "oc192.bit";
00258         break;
00259 
00260     case MEZZ_SRXL:
00261         if (edtdev_channels_from_type(edt_p) == 16)
00262         {
00263             if (ID_IS_LX(edt_p->devid))
00264             {
00265                 if (edt_p->devid == PE8LX16_ID)
00266                     return "srxl_2in.bit";
00267                 else
00268                 {
00269                     fputs("\nedt_optstring.c: edt_default_base_for_mezz:\n\tERROR:  SRXL on LX requires PCI FPGA pe8lx16.bit loaded in flash\n\n", stderr);
00270                     return NULL;
00271                 }
00272             }
00273             else
00274                 return "srxl_16io.bit";
00275         }
00276         else
00277         {
00278             return "srxl_4io.bit";
00279         }
00280 
00281     case MEZZ_SRXL2_IDM_LBM:
00282     case MEZZ_SRXL2_IDM_IDM:
00283     case MEZZ_SRXL2_IMM_IMM:
00284     case MEZZ_SRXL2_IMM_LBM:
00285     case MEZZ_SRXL2_IDM_IMM:
00286     case MEZZ_SRXL2:
00287         if (ID_IS_LX(edt_p->devid))
00288             return "srxl2_2in.bit";
00289         else if (edtdev_channels_from_type(edt_p) == 16)
00290             return "srxl2_16in.bit";
00291         else
00292             return "srxl2_4in.bit";
00293 
00294     case MEZZ_DRX16:
00295         return "drx16_2in.bit";
00296 
00297     case MEZZ_SSE:
00298         return "eclopt_sse.bit";
00299 
00300     case MEZZ_NET10G:
00301         return "net10g.bit";
00302     case MEZZ_MSDV:
00303         return "msdv.bit";
00304     case MEZZ_DDSP:
00305         return "ddsp.bit";
00306 
00307     case MEZZ_THREEP:
00308         return "threep.bit";
00309     }
00310 
00311     return NULL;
00312 
00313 }
00314 
00315 static char*
00316 get_next_field(char *work, int target, char *errorstr)
00317 
00318 {
00319     char *next;
00320 
00321     next = strchr(work, target);
00322 
00323     if (next)
00324     {
00325         *next = 0;
00326         return next+1;
00327     }
00328     else
00329     {
00330         edt_msg(EDTLIB_MSG_WARNING, "Parse Error: '%c' expected %s\n", target, errorstr);
00331         return NULL;
00332     }
00333 
00334 }
00335 
00352 int
00353 edt_parse_option_string(char *s, EdtBitfileDescriptor *bfd)
00354 
00355 {
00356 
00357     char work[80];
00358 
00359     char * dma_intfc;
00360     char *  mezz_type;
00361     char *  mezz_vhdl;
00362     char *  version_major;
00363     char *  version_rev;
00364     char *  date;
00365     char *  customchannels;
00366     char *  totalchannels;
00367 
00368     bfd->string_type = 2;
00369 
00370     /* attempt to split string */
00371 
00372     if (s != bfd->optionstr)
00373         strcpy(bfd->optionstr, s);
00374 
00375     strcpy(work,bfd->optionstr);
00376     work[2] = 0;
00377 
00378     if (!strcasecmp(work,"ss"))
00379     {
00380         bfd->ostr.board_type = EDT_SS_TYPE;
00381     }
00382     else if (!strcasecmp(work,"lx"))
00383     {
00384         bfd->ostr.board_type = EDT_LX_TYPE;
00385     }
00386     else if (!strcasecmp(work,"gs"))
00387     {
00388         bfd->ostr.board_type = EDT_GS_TYPE;
00389     }
00390     else if (!strcasecmp(work,"cd"))
00391     {
00392         bfd->ostr.board_type = EDT_CD_TYPE;
00393     }
00394     else
00395     {
00396         edt_msg(EDTLIB_MSG_WARNING, "Parse error: first two option chars (%s) should be ss or gs\n",work);
00397         return -1;
00398     }
00399 
00400 
00401     strcpy(work,bfd->optionstr);
00402 
00403 
00404     dma_intfc = work + 2;
00405 
00406     if ((mezz_type = get_next_field(dma_intfc, '_', 
00407         "after DMA interface type")) == NULL)
00408         return -1;
00409     if ((mezz_vhdl = get_next_field(mezz_type, '_', 
00410         "after mezzanine type")) == NULL)
00411         return -1;
00412     if ((version_major = get_next_field(mezz_vhdl, ' ', 
00413         "after vhdl name")) == NULL)
00414         return -1;
00415     if ((version_rev = get_next_field(version_major, '.', 
00416         "after version major #")) == NULL)
00417         return -1;
00418     if ((date = get_next_field(version_rev, ' ', 
00419         "after version rev #")) == NULL)
00420         return -1;
00421     if ((customchannels = get_next_field(date, ' ', 
00422         "after date")) ==NULL)
00423         return -1;
00424 
00425     if (*customchannels == '(')
00426         customchannels++;
00427     else
00428     {
00429         edt_msg(EDTLIB_MSG_WARNING, "Parse Error: '(' expected after date\n");
00430         return -1;
00431     }
00432 
00433     if ((totalchannels = get_next_field(customchannels, ',', 
00434         "after custom channels")) == NULL)
00435         return -1;
00436 
00437     if (get_next_field(totalchannels, ')', 
00438         "after total channels") == NULL)
00439         return -1;
00440 
00441 
00442     bfd->ostr.DMA_channels = atoi(dma_intfc);
00443 
00444     if (bfd->ostr.DMA_channels != 1 &&
00445         bfd->ostr.DMA_channels != 4 &&
00446         bfd->ostr.DMA_channels != 16)
00447     {
00448         edt_msg(EDTLIB_MSG_WARNING, "Parse error: DMA interface # (%d) should 1, 4, or 16\n", bfd->ostr.DMA_channels);
00449         return -1;
00450     }
00451 
00452     strcpy(bfd->ostr.mezzanine_type, mezz_type);
00453     strcpy(bfd->ostr.filename, mezz_vhdl);
00454     strncpy(bfd->ostr.date, date, 11);
00455 
00456     bfd->ostr.version_number = atoi(version_major);
00457     bfd->ostr.rev_number = atoi(version_rev);
00458 
00459     bfd->ostr.custom_DMA_channels = strtol(customchannels,0,16);
00460     bfd->ostr.available_DMA_channels = strtol(totalchannels,0,16);
00461 
00462     return 0;
00463 
00464 }
00465 
00475 void
00476 edt_print_board_description(EdtDev *edt_p)
00477 
00478 {
00479 
00480 
00481     printf( "%-24s : %02x (%s)\n", "Board Type", edt_p->devid, edt_idstr(edt_p->devid));
00482     printf("%-24s : %d\n", "PCI Channels", edt_p->DMA_channels);
00483     printf("%-24s : %s\n", "Bitfile Loaded", edt_p->bfd.bitfile_name);
00484 
00485     printf("%-24s : %02x %s\n", "Mezzanine ID", edt_p->mezz.id, 
00486         edt_mezz_name(edt_p->mezz.id));
00487 
00488 
00489     printf("%-24s : %04x\n", "Revision Register", edt_p->bfd.revision_register);
00490     if (edt_p->bfd.string_type)
00491         printf("%-24s : %s\n", "Optionstr", edt_p->bfd.optionstr);
00492 
00493     if (edt_p->bfd.string_type == 2)
00494     {
00495         printf("Parsed Option String Values:\n");
00496         printf("    %-20s : %d (%s)\n", "Baseboard Type", edt_p->bfd.ostr.board_type, 
00497             baseboard_names[edt_p->bfd.ostr.board_type]);
00498         printf("    %-20s : %d\n", "PCI channels", edt_p->DMA_channels);
00499         printf("    %-20s : %s\n", "Mezzanine Type", edt_p->bfd.ostr.mezzanine_type);
00500         printf("    %-20s : %s\n", "VHDL name", edt_p->bfd.ostr.filename);
00501         printf("    %-20s : %02x\n", "Release", edt_p->bfd.ostr.version_number);
00502         printf("    %-20s : %02x\n", "Revision", edt_p->bfd.ostr.rev_number);
00503         printf("    %-20s : %s\n", "Date", edt_p->bfd.ostr.date);
00504         printf("    %-20s : %d\n", "Custom DMA channels", edt_p->bfd.ostr.custom_DMA_channels);
00505         printf("    %-20s : %d\n", "Total DMA channels", edt_p->bfd.ostr.available_DMA_channels);
00506 
00507     }
00508 
00509     if (ID_IS_SS(edt_p->devid) || ID_IS_GS(edt_p->devid) || ID_IS_LX(edt_p->devid))
00510     {
00511         printf("%-24s : %s\n", "Mezz Chan 0 Bitfile", edt_p->bfd.mezz_name0);
00512         printf("%-24s : %s\n", "Mezz Chan 1 Bitfile", edt_p->bfd.mezz_name1);
00513         if (edt_p->bfd.mezz_optionstr0[0])
00514             printf("%-24s : %s\n", "Mezzanine Opt Str Ch. 0", 
00515             edt_p->bfd.mezz_optionstr0);
00516 
00517         if (edt_p->bfd.mezz_optionstr1[0])
00518             printf("%-24s : %s\n", "Mezzanine Opt Str Ch. 1", 
00519             edt_p->bfd.mezz_optionstr1);
00520 
00521         printf("%-24s : %02x\n", "Mezzanine Rev.", edt_p->mezz.extended_rev);
00522         if (edt_p->mezz.n_extended_words)
00523         {
00524             int i;
00525             printf("%-24s : %02x  ", "Mezzanine Extended Words", edt_p->mezz.n_extended_words);
00526             for (i=0;i<edt_p->mezz.n_extended_words;i++)
00527                 printf("%08x  ", edt_p->mezz.extended_data[i]);
00528             printf("\n");
00529         }   
00530     }
00531 
00532 
00533 }
00534 
00535 /* return the best name for bitfile to use when
00536 the mezz id is unknown */
00537 char *
00538 edt_get_test_interface(EdtDev *edt_p)
00539 
00540 {
00541 
00542 
00543     switch (edt_p->devid)
00544     {
00545 
00546     case PGS4_ID:
00547     case PSS4_ID:
00548         return "pciss4test.bit";
00549 
00550         break;
00551 
00552     case PGS16_ID:
00553     case PSS16_ID:
00554     case PE8LX16_ID:
00555     case PE8LX16_LS_ID:
00556     case PE4AMC16_ID:
00557         return "pciss16test.bit";
00558         break;
00559 
00560     case PE8LX1_ID:
00561         return "pe8lx1test.bit";
00562         break;
00563 
00564     case PE8LX64_ID:
00565         return "pciss64test.bit";
00566         break;
00567 
00568     }
00569 
00570     return NULL;
00571 
00572 }
00573 
00574 /* check the current bitfile to see if test file */
00575 
00576 
00577 int
00578 edt_is_test_file_loaded(EdtDev *edt_p)
00579 
00580 {
00581 
00582     edt_get_bitname(edt_p, edt_p->bfd.bitfile_name, 
00583         sizeof(edt_p->bfd.bitfile_name));
00584 
00585     switch (edt_p->devid)
00586     {
00587 
00588     case PGS4_ID:
00589     case PSS4_ID:
00590         return !strcmp(edt_p->bfd.bitfile_name, "pciss4test.bit");
00591         break;
00592 
00593     case PGS16_ID:
00594     case PSS16_ID:
00595     case PE8LX16_ID:
00596     case PE8LX16_LS_ID:
00597     case PE4AMC16_ID:
00598         return !strcmp(edt_p->bfd.bitfile_name, "pciss16test.bit");
00599         break;
00600 
00601     case PE8LX64_ID:
00602         return !strcmp(edt_p->bfd.bitfile_name, "pciss64test.bit");
00603         break;
00604     }
00605 
00606     return 0;
00607 
00608 }
00609 
00631 int edt_test_3x3g(EdtDev *edt_p)
00632 
00633 {
00634     int ret = edt_bitload(edt_p, NULL,  "x3g.bit", 0, 0);
00635     int mezz_id;
00636 
00637     if (ret) {
00638    
00639         edt_msg(EDTAPP_MSG_FATAL, "%s bitload failed\n","x3g.bit");
00640 
00641         return 0;
00642 
00643     } 
00644 
00645     mezz_id = edt_get_board_id(edt_p); /* second try, now with x3g bitfile */
00646 
00647     if (mezz_id == MEZZ_3X3G)
00648         return 1;
00649     return 0;
00650 }
00651 
00652 int
00653 edt_get_board_description(EdtDev *edt_p, int force_mezzanine)
00654 
00655 {
00656     int rc = 0;
00657     char *s;
00658     int test_interface = 0;
00659 
00660     memset(&edt_p->bfd, 0, sizeof(EdtBitfileDescriptor));
00661 
00662     edt_get_bitname(edt_p, edt_p->bfd.bitfile_name, 
00663          sizeof(edt_p->bfd.bitfile_name));
00664     edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name0, 
00665          sizeof(edt_p->bfd.mezz_name0),0);
00666     edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name1, 
00667          sizeof(edt_p->bfd.mezz_name1),1);
00668 
00669     
00670     
00671     /* deal with OCM/OC192 hack*/
00672 
00673     if (ID_IS_SS(edt_p->devid) || ID_IS_GS(edt_p->devid) || ID_IS_LX(edt_p->devid))
00674     {
00675         if ((edt_p->devid != PE4AMC16_ID) && (force_mezzanine && (edt_p->bfd.bitfile_name[0] == 0) ||!edt_ui_loaded(edt_p)))
00676         {
00677 
00678             edt_msg(EDTLIB_MSG_INFO_1, "Forcing bitload...\n");
00679 
00680 #ifdef USE_LAST_BITPATH
00681             /* see what the last interface was - if nothing, load sstest */
00682             if (s = edt_get_last_bitpath(edt_p))
00683             {
00684                 edt_msg(EDTLIB_MSG_INFO_1, "Loading most recent bitfile %s\n", s);
00685             } 
00686             else 
00687 #endif
00688                 if (s = edt_get_test_interface(edt_p))
00689                 {
00690                     edt_msg(EDTLIB_MSG_INFO_1, "Loading test interface %s\n", s);
00691                     test_interface = 1;
00692                 }
00693                 else
00694                     goto fail;
00695 
00696             if ((rc = edt_bitload(edt_p, NULL, s, 0, 0)) != 0) 
00697             {
00698                 if (!test_interface)
00699                 {
00700                     if (s = edt_get_test_interface(edt_p))
00701                     {
00702                         if ((rc = edt_bitload(edt_p, NULL, s, 0, 0)) != 0)
00703                         {
00704                             edt_msg(EDTLIB_MSG_WARNING, "Unable to load %s\n", s);
00705                             goto fail;
00706                         }
00707 
00708                         test_interface = TRUE;
00709                     }
00710                     else
00711                         goto fail;
00712                 }
00713                 else
00714                     goto fail; 
00715             }
00716         }
00717 
00718         edt_p->mezz.id = edt_get_full_board_id(edt_p,NULL,NULL,NULL); 
00719 
00720         /* deal with kludges */
00721         /* for boards which don't work with standard bdid */
00722 
00723         if (edt_p->mezz.id == MEZZ_ERR_BAD_BITSTREAM)
00724         {
00725             if (edtdev_channels_from_type(edt_p) == 16)
00726             {
00727                 if (edt_test_16te3(edt_p))
00728                     edt_p->mezz.id = MEZZ_16TE3;
00729             }
00730             if (edt_p->mezz.id == MEZZ_ERR_BAD_BITSTREAM)
00731                 if (edt_test_3x3g(edt_p))
00732                     edt_p->mezz.id = MEZZ_3X3G;
00733 
00734             if (edt_p->mezz.id != MEZZ_ERR_BAD_BITSTREAM)
00735                 edt_set_mezz_id(edt_p);
00736         }
00737 
00738 
00739         edt_get_bitname(edt_p, edt_p->bfd.bitfile_name, 
00740             sizeof(edt_p->bfd.bitfile_name));
00741 
00742         if (edt_p->mezz.id == MEZZ_UNKN_EXTBDID)
00743         {
00744             rc = -1;
00745             goto fail;  
00746         }
00747 
00748         if (test_interface)
00749         {
00750             s = edt_default_base_for_mezz(edt_p);
00751 
00752             edt_msg(EDTLIB_MSG_INFO_1, "Loading default interface %s\n", s);
00753             if (s && ((rc = edt_bitload(edt_p, NULL, s, 0, 0)) != 0))
00754             {
00755                 edt_msg(EDTLIB_MSG_WARNING, "Unable to load %s, keeping test interface\n", s);
00756             }
00757 
00758         }
00759 
00760         edt_p->DMA_channels = edtdev_channels_from_type(edt_p);
00761 
00762         edt_get_bitname(edt_p, edt_p->bfd.bitfile_name, 
00763             sizeof(edt_p->bfd.bitfile_name));
00764         edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name0, 
00765             sizeof(edt_p->bfd.mezz_name0),0);
00766         edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name1, 
00767             sizeof(edt_p->bfd.mezz_name1),1);
00768 
00769         if (edt_read_option_string(edt_p, edt_p->bfd.optionstr, &edt_p->bfd.revision_register))
00770         {
00771             edt_p->bfd.string_type = 0;
00772             if (edt_read_old_option_string(edt_p, edt_p->bfd.optionstr) == 0)
00773             {
00774                 edt_p->bfd.string_type = 1;
00775 
00776 
00777             }
00778             rc = 0;
00779         }
00780         else
00781             edt_parse_option_string(edt_p->bfd.optionstr, &edt_p->bfd);
00782 
00783         edt_read_mezz_option_string(edt_p, edt_p->bfd.mezz_optionstr0, 0);
00784 
00785         edt_read_mezz_option_string(edt_p, edt_p->bfd.mezz_optionstr1, OFFSET_CH1_MEZ);
00786     }
00787 
00788 fail:
00789 
00790     return rc;
00791 
00792 }
00793 

Generated on Mon Mar 21 14:14:39 2011 by  doxygen 1.4.7