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
00011
00012 char *srxl_extbdid_info[] =
00013 {
00014 "Spartan 3 XC3S1500 -4, Two 4-channel DDC Graychips (GC4016)",
00015 "Spartan 3 XC3S1500 -4, One 4-channel DDC Graychip (GC4016)",
00016 "Spartan 3 XC3S1500 -4, NO DDC Graychips installed!",
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
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
00153
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",
00206 "16TE3IO Board",
00207 "OC192",
00208 "3X3G",
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
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
00536
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
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);
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
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
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
00721
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