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