00001
00002 #include "edtinc.h"
00003
00004 #include <stdlib.h>
00005 #include <ctype.h>
00006
00007 #include "edt_optstring.h"
00008 #include "edt_bitload.h"
00009
00010
00011 char *srxl_extbdid_info[] =
00012 {
00013 "Spartan 3 XC3S1500 -4, Two 4-channel DDC Graychips (GC4016)",
00014 "Spartan 3 XC3S1500 -4, One 4-channel DDC Graychip (GC4016)",
00015 "Spartan 3 XC3S1500 -4, NO DDC Graychips installed!",
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
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
00253
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",
00306 "16TE3IO Board",
00307 "OC192",
00308 "3X3G",
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
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
00592
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
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
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
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