edt_optstring.c

00001 
00002 #include "edtinc.h"
00003 
00004 #include <stdlib.h>
00005 #include <ctype.h> /* isdigit */
00006 
00007 #include "edt_optstring.h"
00008 #include "edt_bitload.h"
00009 
00010 /* extended board information. (configuration and installed options) */
00011 char *srxl_extbdid_info[] =
00012 {
00013     "Spartan 3 XC3S1500 -4, Two 4-channel DDC Graychips (GC4016)",      /* idx = 0 */
00014     "Spartan 3 XC3S1500 -4, One 4-channel DDC Graychip (GC4016)",       /* idx = 1 */
00015     "Spartan 3 XC3S1500 -4, NO DDC Graychips installed!",                       /* idx = 2 */
00016     NULL
00017 };
00018 
00019 
00032 int
00033 edt_check_1_vs_4(EdtDev *edt_p)
00034 {   
00035     int     promcode;
00036     u_char  stat;
00037     int vb = 0;
00038     char name[129];
00039     int pci_channels = 4;
00040 
00041     promcode = edt_x_prom_detect(edt_p, &stat, vb);
00042     edt_x_getname(edt_p, promcode, name);
00043 
00044     if (isdigit(name[strlen(name)-1]))
00045     {
00046         if (strlen(name) >= 2 && isdigit(name[strlen(name)-2]))
00047         {
00048             pci_channels = atoi(name + strlen(name)-2);
00049         }
00050         else
00051         {
00052             pci_channels = atoi(name + strlen(name)-1);
00053         }
00054     }
00055 
00056     return pci_channels;
00057 }
00058 
00059 
00070 int
00071 edtdev_channels_from_type(EdtDev *edt_p)
00072 
00073 {
00074 
00075     switch(edt_p->devid) {
00076   case PCD20_ID:
00077   case PCD40_ID:
00078   case PCD60_ID:
00079 
00080   case PGP20_ID:
00081   case PGP40_ID:
00082   case PGP60_ID:
00083   case PGP_ECL_ID:
00084   case PDVFOI_ID:
00085   case PDVAERO_ID:
00086   case PE8LX4_ID:
00087 
00088       return 4;
00089 
00090   case PSS4_ID:
00091   case PGS4_ID:
00092   case PCDFOX_ID:
00093   case PCDA_ID:
00094   case PCDCL_ID:
00095   case PDVCL2_ID:
00096   case PDVFOX_ID:
00097   case PE4DVFOX_ID:
00098   case PE8DVFOX_ID:
00099       return edt_check_1_vs_4(edt_p);
00100 
00101   case PDVFCI_USPS_ID:
00102   case PE4DVFCI_ID:
00103   case PE8DVFCI_ID:
00104       return 2;
00105 
00106   case PE4DVCL_ID:
00107   case PE8DVCL_ID:
00108   case PDVCL_ID:
00109       return 3;
00110 
00111   case P53B_ID:
00112       return 34;
00113 
00114   case PCD_16_ID:
00115   case PSS16_ID:
00116   case PGS16_ID:
00117   case PCDA16_ID:
00118   case PE8LX16_ID:
00119 
00120       return 16;
00121 
00122     }
00123 
00124     return 1;
00125 
00126 }
00127 
00139 int
00140 edt_read_old_option_string(EdtDev *edt_p, char *s)
00141 
00142 {
00143 
00144     int index=0;
00145 
00146     int ch;
00147 
00148     edt_reg_write(edt_p, EDT_OLD_BITFILE_STRING, 0);
00149     ch = edt_reg_read(edt_p, EDT_OLD_BITFILE_STRING);
00150 
00151     if (ch == 0 || ch == 0xff)
00152     {
00153         s[0] = 0;
00154         return -1;
00155     }
00156     else
00157     {
00158         while (ch && index < 16)
00159         {
00160             edt_reg_write(edt_p, EDT_OLD_BITFILE_STRING, index);
00161             ch = edt_reg_read(edt_p, EDT_OLD_BITFILE_STRING);
00162             s[index] = ch;
00163             index ++;
00164         }
00165     }
00166 
00167     s[index] = 0;
00168 
00169     return 0;
00170 
00171 }
00172 
00186 int
00187 edt_read_mezz_option_string(EdtDev *edt_p, char *s, int offset)
00188 
00189 {
00190 
00191     int index=0;
00192 
00193     int ch;
00194 
00195     u_int reg_addr = EDT_MEZZ_BITFILE_STRING + offset;
00196 
00197     edt_reg_write(edt_p, reg_addr, 0);
00198     ch = edt_reg_read(edt_p, reg_addr);
00199 
00200     if (ch == 0 || ch == 0xff)
00201     {
00202         return -1;
00203     }
00204     else
00205     {
00206         while (ch && index < 16)
00207         {
00208             edt_reg_write(edt_p, reg_addr, index);
00209             ch = edt_reg_read(edt_p, reg_addr);
00210             s[index] = ch;
00211             index ++;
00212         }
00213     }
00214 
00215     s[index] = 0;
00216     /* set pointer back to first cfg */
00217     edt_reg_write(edt_p, reg_addr, 0);
00218 
00219     return 0;
00220 
00221 }
00222 
00235 int
00236 edt_read_option_string(EdtDev *edt_p, char *s , int *rev_p)
00237 
00238 {
00239     int index=0;
00240     int rev;
00241 
00242     int ch;
00243 
00244     rev = edt_reg_read(edt_p, EDT_BITFILE_VERSION);
00245 
00246     if (rev_p)
00247         *rev_p = rev;
00248 
00249     edt_reg_write(edt_p, EDT_BITFILE_STRING, 0);
00250     ch = edt_reg_read(edt_p, EDT_BITFILE_STRING);
00251 
00252     /* 0xff usually indicates bitfile hasn't implented that register; 
00253     * 0xcc means no bitfile has been loaded */
00254     if (ch == 0 || ch == 0xff || ch == 0xcc)
00255     {
00256         if (rev_p)
00257             *rev_p = 0;
00258 
00259 
00260         return -1;
00261 
00262     }
00263     else
00264     {
00265         while (ch && index < 64)
00266         {
00267             edt_reg_write(edt_p, EDT_BITFILE_STRING, index);
00268             ch = edt_reg_read(edt_p, EDT_BITFILE_STRING);
00269             s[index] = ch;
00270             index ++;
00271         }
00272     }
00273 
00274     s[index] = 0;
00275 
00276     return 0;
00277 
00278 }
00279 
00280 static char *baseboard_names[] = {
00281     "unknown",
00282     "pciss",
00283     "pcigs",
00284     "cda",
00285     NULL
00286 };
00287 
00288 
00289 static char *mezzanine_names[] = {
00290     "RS422 I/O Board",
00291     "LVDS I/O Board",
00292     "ID is Extended, this is not a valid ID!",
00293     "RS422_12_LVDS_8",
00294     "SSE (high speed serial ECL) I/O Board",
00295     "HRC for E4/STM-1/OC-3 I/O",
00296     "OCM Board",
00297     "ComboII I/O LVDS Board",
00298     "ECL I/O Board",
00299     "TLK1501 I/O Board",
00300     "SRXL Board",
00301     "COMBOIII RS422",
00302     "COMBOIII LVDS",
00303     "COMBOIII ECL",
00304     "COMBOII I/O RS422",
00305     "COMBO I/O Board",                  /* idx = 15 */
00306     "16TE3IO Board",                    /* idx = 16 */
00307     "OC192",                    /* idx = 17 */
00308     "3X3G",                    /* idx = 18 */
00309     "MSDV",
00310     "SRXL2",
00311     "NET10G",
00312     "",
00313     0
00314 };
00315 
00325 char *
00326 edt_mezz_name(int mezz_id)
00327 
00328 {
00329     if (mezz_id >= 0 && mezz_id <= MEZZ_LAST && mezzanine_names[mezz_id])
00330         return mezzanine_names[mezz_id];
00331 
00332     return "unknown id";
00333 }
00334 
00335 char *
00336 edt_default_base_for_mezz(EdtDev *edt_p)
00337 
00338 {
00339     switch (edt_p->mezz.id)
00340     {
00341     case MEZZ_OCM:
00342         return "ocm.bit";
00343         break;
00344 
00345     case MEZZ_OC192:
00346         return "oc192.bit";
00347         break;
00348 
00349     case MEZZ_SRXL:
00350         if (edtdev_channels_from_type(edt_p) == 16)
00351             return "srxl_16io.bit";
00352         else
00353             return "srxl_4io.bit";
00354 
00355     case MEZZ_SRXL2:
00356         if (edtdev_channels_from_type(edt_p) == 16)
00357             return "srxl2_16in.bit";
00358         else
00359             return "srxl2_4in.bit";
00360 
00361     case MEZZ_SSE:
00362         return "eclopt_sse.bit";
00363 
00364     case MEZZ_NET10G:
00365         return "net10g.bit";
00366     case MEZZ_MSDV:
00367         return "msdv.bit";
00368     }
00369 
00370     return NULL;
00371 
00372 }
00373 
00374 static char*
00375 get_next_field(char *work, int target, char *errorstr)
00376 
00377 {
00378     char *next;
00379 
00380     next = strchr(work, target);
00381 
00382     if (next)
00383     {
00384         *next = 0;
00385         return next+1;
00386     }
00387     else
00388     {
00389         edt_msg(EDTLIB_MSG_WARNING, "Parse Error: '%c' expected %s\n", target, errorstr);
00390         return NULL;
00391     }
00392 
00393 }
00394 
00411 int
00412 edt_parse_option_string(char *s, EdtBitfileDescriptor *bfd)
00413 
00414 {
00415 
00416     char work[80];
00417 
00418     char * dma_intfc;
00419     char *  mezz_type;
00420     char *  mezz_vhdl;
00421     char *  version_major;
00422     char *  version_rev;
00423     char *  date;
00424     char *  customchannels;
00425     char *  totalchannels;
00426 
00427     bfd->string_type = 2;
00428 
00429     /* attempt to split string */
00430 
00431     if (s != bfd->optionstr)
00432         strcpy(bfd->optionstr, s);
00433 
00434     strcpy(work,bfd->optionstr);
00435     work[2] = 0;
00436 
00437     if (!strcasecmp(work,"ss"))
00438     {
00439         bfd->ostr.board_type = EDT_SS_TYPE;
00440     }
00441     else if (!strcasecmp(work,"gs"))
00442     {
00443         bfd->ostr.board_type = EDT_GS_TYPE;
00444     }
00445     else if (!strcasecmp(work,"cd"))
00446     {
00447         bfd->ostr.board_type = EDT_CD_TYPE;
00448     }
00449     else
00450     {
00451         edt_msg(EDTLIB_MSG_WARNING, "Parse error: first two option chars (%s) should be ss or gs\n",work);
00452         return -1;
00453     }
00454 
00455 
00456     strcpy(work,bfd->optionstr);
00457 
00458 
00459     dma_intfc = work + 2;
00460 
00461     if ((mezz_type = get_next_field(dma_intfc, '_', 
00462         "after DMA interface type")) == NULL)
00463         return -1;
00464     if ((mezz_vhdl = get_next_field(mezz_type, '_', 
00465         "after mezzanine type")) == NULL)
00466         return -1;
00467     if ((version_major = get_next_field(mezz_vhdl, ' ', 
00468         "after vhdl name")) == NULL)
00469         return -1;
00470     if ((version_rev = get_next_field(version_major, '.', 
00471         "after version major #")) == NULL)
00472         return -1;
00473     if ((date = get_next_field(version_rev, ' ', 
00474         "after version rev #")) == NULL)
00475         return -1;
00476     if ((customchannels = get_next_field(date, ' ', 
00477         "after date")) ==NULL)
00478         return -1;
00479 
00480     if (*customchannels == '(')
00481         customchannels++;
00482     else
00483     {
00484         edt_msg(EDTLIB_MSG_WARNING, "Parse Error: '(' expected after date\n");
00485         return -1;
00486     }
00487 
00488     if ((totalchannels = get_next_field(customchannels, ',', 
00489         "after custom channels")) == NULL)
00490         return -1;
00491 
00492     if (get_next_field(totalchannels, ')', 
00493         "after total channels") == NULL)
00494         return -1;
00495 
00496 
00497     bfd->ostr.DMA_channels = atoi(dma_intfc);
00498 
00499     if (bfd->ostr.DMA_channels != 1 &&
00500         bfd->ostr.DMA_channels != 4 &&
00501         bfd->ostr.DMA_channels != 16)
00502     {
00503         edt_msg(EDTLIB_MSG_WARNING, "Parse error: DMA interface # (%d) should 1, 4, or 16\n", bfd->ostr.DMA_channels);
00504         return -1;
00505     }
00506 
00507     strcpy(bfd->ostr.mezzanine_type, mezz_type);
00508     strcpy(bfd->ostr.filename, mezz_vhdl);
00509     strncpy(bfd->ostr.date, date, 11);
00510 
00511     bfd->ostr.version_number = atoi(version_major);
00512     bfd->ostr.rev_number = atoi(version_rev);
00513 
00514     bfd->ostr.custom_DMA_channels = strtol(customchannels,0,16);
00515     bfd->ostr.available_DMA_channels = strtol(totalchannels,0,16);
00516 
00517     return 0;
00518 
00519 }
00520 
00530 void
00531 edt_print_board_description(EdtDev *edt_p)
00532 
00533 {
00534 
00535 
00536     printf( "%-20s : %02x (%s)\n", "Board Type", edt_p->devid, edt_idstr(edt_p->devid));
00537     printf("%-20s : %d\n", "PCI Channels", edt_p->DMA_channels);
00538     printf("%-20s : %s\n", "Bitfile Loaded", edt_p->bfd.bitfile_name);
00539 
00540     printf("%-20s : %02x %s\n", "Mezzanine ID", edt_p->mezz.id, 
00541         edt_mezz_name(edt_p->mezz.id));
00542     if (edt_p->bfd.string_type)
00543     {
00544 
00545         printf("%-20s : %04x\n", "Revision Register", edt_p->bfd.revision_register);
00546         printf("%-20s : %s\n", "Optionstr", edt_p->bfd.optionstr);
00547 
00548         if (edt_p->bfd.string_type == 2)
00549         {
00550             printf("Parsed Option String Values:\n");
00551             printf("    %-20s : %d (%s)\n", "Baseboard Type", edt_p->bfd.ostr.board_type, 
00552                 baseboard_names[edt_p->bfd.ostr.board_type]);
00553             printf("    %-20s : %d\n", "PCI channels", edt_p->DMA_channels);
00554             printf("    %-20s : %s\n", "Mezzanine Type", edt_p->bfd.ostr.mezzanine_type);
00555             printf("    %-20s : %s\n", "VHDL name", edt_p->bfd.ostr.filename);
00556             printf("    %-20s : %02x\n", "Release", edt_p->bfd.ostr.version_number);
00557             printf("    %-20s : %02x\n", "Revision", edt_p->bfd.ostr.rev_number);
00558             printf("    %-20s : %s\n", "Date", edt_p->bfd.ostr.date);
00559             printf("    %-20s : %d\n", "Custom DMA channels", edt_p->bfd.ostr.custom_DMA_channels);
00560             printf("    %-20s : %d\n", "Total DMA channels", edt_p->bfd.ostr.available_DMA_channels);
00561 
00562         }
00563 
00564         if (ID_IS_SS(edt_p->devid) || ID_IS_GS(edt_p->devid))
00565         {
00566             printf("%-20s : %s\n", "Mezz Chan 0 Bitfile", edt_p->bfd.mezz_name0);
00567             printf("%-20s : %s\n", "Mezz Chan 1 Bitfile", edt_p->bfd.mezz_name1);
00568             if (edt_p->bfd.mezz_optionstr0[0])
00569                 printf("%-20s : %s\n", "Mezzanine Opt Str Ch. 0", 
00570                 edt_p->bfd.mezz_optionstr0);
00571 
00572             if (edt_p->bfd.mezz_optionstr1[0])
00573                 printf("%-20s : %s\n", "Mezzanine Opt Str Ch. 1", 
00574                 edt_p->bfd.mezz_optionstr1);
00575 
00576             printf("%-20s : %02x\n", "Mezzanine Rev.", edt_p->mezz.extended_rev);
00577             if (edt_p->mezz.n_extended_words)
00578             {
00579                 int i;
00580                 printf("%-20s : %02x  ", "Mezzanine Extended Words", edt_p->mezz.n_extended_words-1);
00581                 for (i=1;i<edt_p->mezz.n_extended_words;i++)
00582                     printf("%08x  ", edt_p->mezz.extended_data[i]);
00583                 printf("\n");
00584             }   
00585         }
00586     }
00587     else
00588         printf("\nNo option string in this bitfile\n");
00589 }
00590 
00591 /* return the best name for bitfile to use when
00592    the mezz id is unknown */
00593 char *
00594 edt_get_test_interface(EdtDev *edt_p)
00595 
00596 {
00597     
00598 
00599     switch (edt_p->devid)
00600     {
00601 
00602     case PGS4_ID:
00603     case PSS4_ID:
00604     case PE8LX4_ID:
00605         return "pciss4test.bit";
00606 
00607         break;
00608 
00609     case PGS16_ID:
00610     case PSS16_ID:
00611     case PE8LX16_ID:
00612         return "pciss16test.bit";
00613         break;
00614 
00615     case PE8LX1_ID:
00616         return "pe8lx1test.bit";
00617         break;
00618 
00619     }
00620 
00621     return NULL;
00622 
00623 }
00624 
00625 /* check the current bitfile to see if test file */
00626 
00627 
00628 int
00629 edt_is_test_file_loaded(EdtDev *edt_p)
00630 
00631 {
00632     
00633     edt_get_bitpath(edt_p, edt_p->bfd.bitfile_name, 
00634          sizeof(edt_p->bfd.bitfile_name));
00635 
00636     switch (edt_p->devid)
00637     {
00638 
00639     case PGS4_ID:
00640     case PSS4_ID:
00641     case PE8LX4_ID:
00642         return !strcmp(edt_p->bfd.bitfile_name, "pciss4test.bit");
00643         break;
00644 
00645     case PGS16_ID:
00646     case PSS16_ID:
00647     case PE8LX16_ID:
00648         return !strcmp(edt_p->bfd.bitfile_name, "pciss16test.bit");
00649         break;
00650 
00651     }
00652 
00653     return 0;
00654 
00655 }
00656 
00678 int
00679 edt_get_board_description(EdtDev *test_edt_p, int force_mezzanine)
00680 
00681 {
00682     int rc = 0;
00683     EdtDev *edt_p;
00684     char *s;
00685     int test_interface = 0;
00686 
00687     if (test_edt_p->channel_no != 0)
00688     {
00689         edt_p = edt_open(EDT_INTERFACE, test_edt_p->unit_no);
00690     }
00691     else
00692         edt_p = test_edt_p;
00693 
00694     memset(&edt_p->bfd, 0, sizeof(EdtBitfileDescriptor));
00695 
00696     edt_get_bitpath(edt_p, edt_p->bfd.bitfile_name, 
00697         sizeof(edt_p->bfd.bitfile_name));
00698 
00699     /* deal with OCM/OC192 hack*/
00700 
00701     if (ID_IS_SS(edt_p->devid) || ID_IS_GS(edt_p->devid) || ID_IS_LX(edt_p->devid))
00702     {
00703         if (force_mezzanine && edt_p->bfd.bitfile_name[0] == 0)
00704         {
00705 
00706             edt_msg(EDTLIB_MSG_INFO_1, "Forcing bitload...\n");
00707             
00708 #ifdef USE_LAST_BITPATH
00709             /* see what the last interface was - if nothing, load sstest */
00710             if (s = edt_get_last_bitpath(edt_p))
00711             {
00712                 edt_msg(EDTLIB_MSG_INFO_1, "Loading most recent bitfile %s\n", s);
00713             } 
00714             else 
00715 #endif
00716             if (s = edt_get_test_interface(edt_p))
00717             {
00718                 edt_msg(EDTLIB_MSG_INFO_1, "Loading test interface %s\n", s);
00719                 test_interface = 1;
00720             }
00721             else
00722                 goto fail;
00723 
00724             if ((rc = edt_bitload(edt_p, ".", s, 0, 0)) != 0) 
00725             {
00726                 if (!test_interface)
00727                 {
00728                     if (s = edt_get_test_interface(edt_p))
00729                     {
00730                         if ((rc = edt_bitload(edt_p, ".", s, 0, 0)) != 0)
00731                         {
00732                             edt_msg(EDTLIB_MSG_WARNING, "Unable to load %s\n", s);
00733                             goto fail;
00734                         }
00735 
00736                         test_interface = TRUE;
00737                     }
00738                     else
00739                         goto fail;
00740                 }
00741                 else
00742                     goto fail; 
00743             }
00744         }
00745         edt_p->mezz.id = edt_get_full_board_id(edt_p,NULL,NULL,NULL); 
00746 
00747         edt_get_bitpath(edt_p, edt_p->bfd.bitfile_name, 
00748             sizeof(edt_p->bfd.bitfile_name));
00749 
00750 
00751         if (edt_p->mezz.id == MEZZ_UNKN_EXTBDID)
00752         {
00753             rc = -1;
00754             goto fail;  
00755         }
00756 
00757         if (test_interface)
00758         {
00759             s = edt_default_base_for_mezz(edt_p);
00760 
00761             edt_msg(EDTLIB_MSG_INFO_1, "Loading default interface %s\n", s);
00762             if (s && ((rc = edt_bitload(edt_p, ".", s, 0, 0)) != 0))
00763             {
00764                 edt_msg(EDTLIB_MSG_WARNING, "Unable to load %s, keeping test interface\n", s);
00765             }
00766 
00767         }
00768 
00769         edt_p->DMA_channels = edtdev_channels_from_type(edt_p);
00770 
00771         edt_get_bitpath(edt_p, edt_p->bfd.bitfile_name, 
00772             sizeof(edt_p->bfd.bitfile_name));
00773         edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name0, 
00774             sizeof(edt_p->bfd.mezz_name0),0);
00775         edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name1, 
00776             sizeof(edt_p->bfd.mezz_name1),1);
00777 
00778         if (edt_read_option_string(edt_p, edt_p->bfd.optionstr, &edt_p->bfd.revision_register))
00779         {
00780             edt_p->bfd.string_type = 0;
00781             if (edt_read_old_option_string(edt_p, edt_p->bfd.optionstr) == 0)
00782             {
00783                 edt_p->bfd.string_type = 1;
00784 
00785                 edt_read_mezz_option_string(edt_p, edt_p->bfd.mezz_optionstr0, 0);
00786                 edt_read_mezz_option_string(edt_p, edt_p->bfd.mezz_optionstr1, OFFSET_CH1_MEZ);
00787 
00788             }
00789             rc = 0;
00790         }
00791         else
00792             edt_parse_option_string(edt_p->bfd.optionstr, &edt_p->bfd);
00793     }
00794 
00795 fail:
00796     if (edt_p != test_edt_p)
00797     {
00798         memcpy(&test_edt_p->bfd, &edt_p->bfd, sizeof(test_edt_p->bfd));
00799         test_edt_p->mezz = edt_p->mezz;
00800         test_edt_p->DMA_channels = edt_p->DMA_channels;
00801 
00802         edt_close(edt_p);
00803     }
00804 
00805     return rc;
00806 
00807 }
00808 

Generated on Mon May 12 16:38:52 2008 by  doxygen 1.5.1