00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "edtdef.h"
00010
00011 #ifdef _KERNEL
00012
00013 #include "edtdrv.h"
00014
00015 #define EdtDev Edt_Dev
00016
00017 #ifdef _NT_DRIVER_
00018
00019 #define edt_strtol strtol
00020
00021 #endif
00022
00023
00024 #include "pciload.h"
00025
00026
00027 #else
00028
00029 #include "edtinc.h"
00030
00031 #include "pciload.h"
00032
00033 #define edt_set edt_reg_write
00034 #define edt_get edt_reg_read
00035
00036 #define edt_delay edt_msleep
00037
00038 #define EDTPRINTF(a,b,c) if (edt_get_verbosity() > b) { printf c ; }
00039
00040 #define edt_strtol strtol
00041
00042 #endif
00043
00044
00045 #ifdef DOXYGEN_SHOW_UNDOC
00046
00050 #endif
00051
00052 u_int ida_4013e(void *dmy, int sector);
00053 u_int ida_4013xla(void *dmy, int sector);
00054 u_int ida_4028xla(void *dmy, int sector);
00055 u_int ida_xc2s100(void *dmy, int sector);
00056 u_int ida_xc3s1200e(void *dmy, int sector);
00057 u_int ida_xc2s1200e(void *dmy, int sector);
00058 u_int ida_xc5vlx30t(void * edt_p, int dmy);
00059 u_int edt_get_fpga_info_index(EdtDev *edt_p);
00060
00061 Edt_prominfo ep;
00062
00063
00064 Edt_prominfo EPinfo[16] =
00065 {
00066
00067 {"unknown [0]", "na", "na", 0, 0, 0, 0, 0, NULL, -1, -1},
00068 {"4013e", "AMD 29F010", "PCI", XTYPE_X, XilinxMagic, E_SECTOR_SIZE, 8, 0, ida_4013e, 1, -1},
00069 {"4013xla", "AMD 29F010", "PCI", XTYPE_X, XilinxMagic, XLA_SECTOR_SIZE, 1, 1, ida_4013xla, 1, 3},
00070 {"4028xla", "AMD 29F010", "PCI", XTYPE_BT, XilinxMagic, XLA_SECTOR_SIZE, 2, 2, ida_4028xla, 2, 3},
00071 {"xc2s150", "AMD 29LV040B", "PCI", XTYPE_BT, XilinxMagic, XLA_SECTOR_SIZE, 2, 2, ida_4028xla, 2, 3},
00072 {"xc2s200", "AMD 29LV040B 4MB", "PCI", XTYPE_BT, XilinxMagic, XLA_SECTOR_SIZE, 4, 2, ida_xc2s100, 0, 1},
00073 {"xc2s200", "AMD 29LV081B 8MB", "PCI", XTYPE_BT, XilinxMagic, XLA_SECTOR_SIZE, 4, 2, ida_xc2s100, 2, 3},
00074 {"xc2s100", "AMD 29LV081B 8MB", "PCI", XTYPE_BT, XilinxMagic, XLA_SECTOR_SIZE, 4, 2, ida_xc2s100, 2, 3},
00075 {"xc2s300e", "AMD 29LV081B 8MB", "PCI", XTYPE_LTX, XilinxMagic, XLA_SECTOR_SIZE, 4, 2, ida_xc2s100, -1, -1},
00076 {"xc3s1200e", "SPI W25P16", "PCIe", XTYPE_SPI, XilinxMagic, SPI_SECTOR_SIZE, 32, 0, ida_xc3s1200e, 0, -1},
00077 {"xc5vlx30t", "AMD S29GL064N", "PCIe", XTYPE_BT2, XilinxMagic, XLA_SECTOR_SIZE, 32, 3, ida_xc5vlx30t, 3, -1},
00078 {"xc5vlx50t", "AMD S29GL064N", "PCIe", XTYPE_BT2, XilinxMagic, XLA_SECTOR_SIZE, 32, 3, ida_xc5vlx30t, 3, -1},
00079 {"ep2sgx30d", "AMD S29GL128N", "PCIe", XTYPE_BT2, AlteraMagic, XLA_SECTOR_SIZE, 32, 3, ida_xc5vlx30t, 3, -1},
00080 {"xc5vlx70t", "AMD S29GL064N", "PCIe", XTYPE_BT2, XilinxMagic, XLA_SECTOR_SIZE, 64, 0, ida_xc5vlx30t, 0, -1},
00081 {"unknown [14]", "na", "na", 0, 0, 0, 0, 0, NULL, -1, -1},
00082 {"unknown [15]", "na", "na", 0, 0, 0, 0, 0, NULL, -1, -1},
00083 };
00084
00085
00086
00087 #define EDT_MAX_PROMCODE 13
00088
00089 static struct
00090 {
00091 u_int mid;
00092 u_int devid;
00093 u_int prom;
00094 } older_devices[] =
00095
00096 {
00097 {
00098 0x1, 0x20, AMD_4013E
00099 },
00100 {
00101 0x1, 0x4f, AMD_4013XLA
00102 },
00103 {
00104 0x20, 0xe3, AMD_4013XLA
00105 },
00106 {
00107 0x00, 0x00, 0
00108 }
00109 };
00110
00111
00112 #define DEBUG1 EDTLIB_MSG_INFO_1
00113 #define DEBUG2 EDTLIB_MSG_INFO_2
00114
00115
00116
00117
00118 #define BT_EN_READ 0x8000
00119
00120
00121
00122
00123
00124 #define EN_HIGH_ADD 0x00800000
00125
00126 static int needswap = 0;
00127
00128 static void spi_read(EdtDev *edt_p, int addr, u_char *rbuf, int rcnt);
00129 static int spi_reset(EdtDev *edt_p);
00130 static void spiprim(EdtDev *edt_p, int opcode, int wbytes, int rbytes, unsigned char* wbuf, unsigned char* rbuf);
00131 static void spi_xwr(EdtDev *edt_p, int val);
00132 static int spi_xrd(EdtDev *edt_p);
00133 static void spi_xw(EdtDev *edt_p, u_int addr, u_int data);
00134 static u_int spi_xr(EdtDev *edt_p, u_int addr);
00135
00136 static void bt_write(EdtDev *edt_p,u_int addr, u_char val);
00137 static u_char bt_read(EdtDev *edt_p, u_int addr);
00138 static void bt_reset(EdtDev *edt_p);
00139 static u_char bt_readstat(EdtDev *edt_p);
00140
00141 static void bt2_reset(EdtDev *edt_p);
00142
00143 static void xwrite(EdtDev *edt_p, u_int addr, u_char val);
00144 static u_char xread(EdtDev *edt_p, u_int addr);
00145 static void xreset(EdtDev *edt_p);
00146 static u_char xreadstat(EdtDev *edt_p);
00147
00148
00149 static void tst_write(EdtDev * edt_p, uint_t desc, uint_t val);
00150 static uint_t tst_read(EdtDev * edt_p, uint_t desc);
00151
00152
00153 static void
00154 edt_zero(void *s, size_t n)
00155 {
00156 #ifdef __sun
00157 bzero(s, n);
00158 #else
00159 memset(s, 0, n);
00160 #endif
00161 }
00162
00163 int
00164 edt_x_prom_detect(EdtDev * edt_p, u_char *stat);
00165 void
00166 edt_readinfo_keys(EdtDev *edt_p, int promcode, int segment, char *id, char *edtsn, char *oemsn, char *keys);
00167
00168 void tst_pflash(EdtDev *edt_p, uint_t addr, uint_t val);
00169
00170 void
00171 edt_x_block_program(EdtDev *edt_p, u_int addr, u_char *data, int nbytes, int xtype);
00172
00173 void
00174 edt_get_sns(EdtDev *edt_p, char *esn, char *osn);
00175
00176
00177 static int
00178 spi_block_program(EdtDev *edt_p, int addr0, int size, u_char *spibuf, int verify_only);
00179
00180 char *
00181 read_x_block(EdtDev *edt_p, u_int addr, u_char *buf, int size, int xtype);
00182
00183 void
00184 edt_read_prom_data(EdtDev *edt_p, int promcode, int segment,
00185 EdtPromData *pdata);
00186
00187
00188
00189
00190 Edt_prominfo *
00191 edt_get_prominfo(int promcode)
00192 {
00193 return &EPinfo[promcode];
00194 }
00195
00196
00197
00198
00199 int
00200 edt_get_max_promcode()
00201 {
00202 return EDT_MAX_PROMCODE;
00203 }
00204
00205
00206
00207 #ifdef _KERNEL
00208
00209 static int
00210 edt_little_endian()
00211 {
00212 u_short test;
00213 u_char *byte_p;
00214
00215 byte_p = (u_char *) & test;
00216 *byte_p++ = 0x11;
00217 *byte_p = 0x22;
00218 if (test == 0x1122)
00219 {
00220 return (0);
00221 }
00222 else
00223 {
00224 return (1);
00225 }
00226 }
00227
00228 #endif
00229
00230 #define DQ7 0x80
00231 #define DQ5 0x20
00232 #define DQ3 0x08
00233 static int maxloops = 0;
00234
00235
00236 static int debug_fast = 0;
00237 static int do_fast = 0;
00238 static int force_slow = 0;
00239
00240 int
00241 edt_get_debug_fast()
00242 {
00243 return (debug_fast) ;
00244 }
00245 int
00246 edt_set_debug_fast(int val)
00247 {
00248 (debug_fast = val) ;
00249 return val;
00250 }
00251 int
00252 edt_get_do_fast()
00253 {
00254 return (do_fast) ;
00255 }
00256 void
00257 edt_set_do_fast(int val)
00258 {
00259 do_fast = val ;
00260 }
00261
00262 int
00263 edt_get_force_slow()
00264 {
00265 return (force_slow) ;
00266 }
00267 void
00268 edt_set_force_slow(int val)
00269 {
00270 force_slow = val ;
00271 }
00272
00273
00274
00275 static char *device_name[NUM_DEVICE_TYPES] = {"pcd", "pdv", "p11w", "p16d", "p53b"};
00276 char *read_x_string(EdtDev *edt_p, u_int addr, char *buf, int size, int xtype);
00277
00278
00279
00280
00281
00282 volatile caddr_t dmyaddr = 0;
00283 volatile u_int *cfgaddr ;
00284 volatile u_int *tstaddr ;
00285
00286
00287 u_int
00288 swap32(u_int val)
00289 {
00290
00291 return (
00292 ((val & 0x000000ff) << 24)
00293 | ((val & 0x0000ff00) << 8)
00294 | ((val & 0x00ff0000) >> 8)
00295 | ((val & 0xff000000) >> 24));
00296 }
00297
00298
00299
00300
00301
00302 static void
00303 bt_print16(EdtDev * edt_p, u_int addr)
00304 {
00305 int i;
00306
00307 EDTPRINTF(edt_p,2,("%08x ", addr));
00308 for (i = 1; i < 16; i++)
00309 {
00310 EDTPRINTF(edt_p,2,(" %02x", bt_read(edt_p, addr)));
00311 addr++;
00312 }
00313 EDTPRINTF(edt_p,2,("\n"));
00314 }
00315
00316
00317
00318
00319 static void
00320 xprint16(EdtDev * edt_p, u_int addr)
00321 {
00322 int i;
00323
00324 EDTPRINTF(edt_p,2,("%08x ", addr));
00325 for (i = 1; i < 16; i++)
00326 {
00327 EDTPRINTF(edt_p,2,(" %02x", xread(edt_p, addr)));
00328 addr++;
00329 }
00330 EDTPRINTF(edt_p,2,("\n"));
00331 }
00332
00333
00334
00335
00336 static void
00337 spi_print16(EdtDev * edt_p, u_int addr)
00338 {
00339 int i;
00340 u_char val;
00341
00342 EDTPRINTF(edt_p,2,("%08x ", addr));
00343 for (i = 1; i < 16; i++)
00344 {
00345 spi_read(edt_p, (u_int)addr, &val, 1);
00346 EDTPRINTF(edt_p,2,(" %02x", val));
00347 addr++;
00348 }
00349 EDTPRINTF(edt_p,2,("\n"));
00350 }
00351
00352
00353
00354 void
00355 edt_x_print16(EdtDev * edt_p, u_int addr, int xtype)
00356 {
00357 switch(xtype)
00358 {
00359 case XTYPE_SPI:
00360 spi_print16(edt_p, (u_int)addr);
00361 break;
00362 case XTYPE_BT:
00363 case XTYPE_BT2:
00364 bt_print16(edt_p, addr);
00365 break;
00366 case XTYPE_X:
00367 xprint16(edt_p, addr);
00368 break;
00369 }
00370 }
00371
00372 u_char
00373 edt_x_read(EdtDev * edt_p, u_int addr, int xtype)
00374 {
00375 u_char val;
00376
00377 switch(xtype)
00378 {
00379 case XTYPE_SPI:
00380 spi_read(edt_p, addr, &val, 1);
00381 return val;
00382 case XTYPE_BT:
00383 case XTYPE_BT2:
00384 return bt_read(edt_p, addr);
00385 case XTYPE_X:
00386 return xread(edt_p, addr);
00387 }
00388
00389 return 0;
00390 }
00391
00392
00393
00394
00395 static int
00396 bt_sector_erase(EdtDev * edt_p, u_int sector, u_int sec_size)
00397 {
00398 u_int addr;
00399 int done = 0;
00400 int loops = 0;
00401 u_char val;
00402
00403 addr = sector * sec_size;
00404 bt_write(edt_p, 0x5555, 0xaa);
00405 bt_write(edt_p, 0x2aaa, 0x55);
00406 bt_write(edt_p, 0x5555, 0x80);
00407 bt_write(edt_p, 0x5555, 0xaa);
00408 bt_write(edt_p, 0x2aaa, 0x55);
00409 bt_write(edt_p, addr, 0x30);
00410 done = 0;
00411 while (!done)
00412 {
00413 val = bt_read(edt_p, addr);
00414 loops++;
00415 if (val & DQ7)
00416 {
00417 done = 1;
00418 }
00419 }
00420 return 0;
00421 }
00422
00423
00424
00425
00426 static int
00427 bt2_sector_erase(EdtDev * edt_p, u_int sector, u_int sec_size)
00428 {
00429 u_int addr;
00430 int done = 0;
00431 int loops = 0;
00432 u_char val;
00433
00434 addr = sector * sec_size;
00435 bt_write(edt_p, 0xaaa, 0xaa);
00436 bt_write(edt_p, 0x555, 0x55);
00437 bt_write(edt_p, 0xaaa, 0x80);
00438 bt_write(edt_p, 0xaaa, 0xaa);
00439 bt_write(edt_p, 0x555, 0x55);
00440 bt_write(edt_p, addr, 0x30);
00441 done = 0;
00442 while (!done)
00443 {
00444 val = bt_read(edt_p, addr);
00445 loops++;
00446 if (val & DQ7)
00447 {
00448 done = 1;
00449 }
00450 }
00451 return 0;
00452 }
00453
00454 static int
00455 xsector_erase(EdtDev * edt_p, u_int sector, u_int sec_size)
00456 {
00457 u_int addr;
00458 int done = 0;
00459 int loops = 0;
00460 u_char val;
00461
00462 addr = sector * sec_size;
00463 xwrite(edt_p, 0x5555, 0xaa);
00464 xwrite(edt_p, 0x2aaa, 0x55);
00465 xwrite(edt_p, 0x5555, 0x80);
00466 xwrite(edt_p, 0x5555, 0xaa);
00467 xwrite(edt_p, 0x2aaa, 0x55);
00468 xwrite(edt_p, addr, 0x30);
00469 done = 0;
00470 while (!done)
00471 {
00472 val = xread(edt_p, addr);
00473 loops++;
00474 if (val & DQ7)
00475 {
00476 done = 1;
00477 break;
00478 }
00479 }
00480 return 0;
00481 }
00482
00483
00484
00485
00486
00487
00488 static int
00489 bt_byte_program(EdtDev * edt_p, int xtype, u_int addr, u_char data)
00490 {
00491 u_char val;
00492 int done = 0;
00493 int loops = 0;
00494
00495 bt_write(edt_p, 0x5555, 0xaa);
00496 bt_write(edt_p, 0x2aaa, 0x55);
00497 bt_write(edt_p, 0x5555, 0xa0);
00498 bt_write(edt_p, addr, data);
00499 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00500
00501 while (!done)
00502 {
00503 val = (u_char) tst_read(edt_p, EDT_FLASHROM_DATA);
00504
00505 if (val == data)
00506 done = 1;
00507 if (loops > 1000)
00508 {
00509 EDTPRINTF(edt_p,1,("bt_byte_program: failed on %x data %x val %x\n",
00510 addr, data, val));
00511 bt_reset(edt_p );
00512 bt_write(edt_p, 0x555, 0xaa);
00513 bt_write(edt_p, 0x2aa, 0x55);
00514 bt_write(edt_p, 0x555, 0xa0);
00515 bt_write(edt_p, addr, data);
00516 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00517 loops = 0;
00518 }
00519 loops++;
00520 }
00521 if (loops > maxloops)
00522 {
00523 maxloops = loops;
00524 }
00525 if (done)
00526 return (0);
00527 else
00528 return (addr);
00529 }
00530
00531
00532
00533
00534
00535 static int
00536 bt2_byte_program(EdtDev * edt_p, int xtype, u_int addr, u_char data)
00537 {
00538 u_char val;
00539 int done = 0;
00540 int loops = 0;
00541 int failures = 0;
00542
00543 bt_write(edt_p, 0xaaa, 0xaa);
00544 bt_write(edt_p, 0x555, 0x55);
00545 bt_write(edt_p, 0xaaa, 0xa0);
00546 bt_write(edt_p, addr, data);
00547 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00548
00549 while (!done)
00550 {
00551 val = (u_char) tst_read(edt_p, EDT_FLASHROM_DATA);
00552
00553 if (val == data)
00554 done = 1;
00555 if (loops > 1000)
00556 {
00557 bt2_reset(edt_p);
00558 bt_write(edt_p, 0xaaa, 0xaa);
00559 bt_write(edt_p, 0x555, 0x55);
00560 bt_write(edt_p, 0xaaa, 0xa0);
00561 bt_write(edt_p, addr, data);
00562 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00563 loops = 0;
00564 failures++;
00565 }
00566 loops++;
00567
00568 if (failures > 5)
00569 {
00570 EDTPRINTF(edt_p,0,("bt2_byte_program: failed on %x data %x val %x\n", addr, data, val));
00571 return(1);
00572 }
00573 }
00574 if (loops > maxloops)
00575 {
00576 maxloops = loops;
00577 }
00578 if (done)
00579 return (0);
00580 else
00581 return (addr);
00582 }
00583
00584
00585
00586
00587
00588
00589
00590 static int
00591 xbyte_program(EdtDev * edt_p, u_int addr, u_char data)
00592 {
00593 u_char val;
00594 int done = 0;
00595 int loops = 0;
00596
00597 tst_pflash(edt_p, addr, data) ;
00598 while (!done)
00599 {
00600 loops++;
00601 val = xread(edt_p, addr);
00602 if (val == data)
00603 done = 1;
00604 if (loops > 100)
00605 {
00606 EDTPRINTF(edt_p,1,("xbyte_program: failed on %x data %x val %x\n",
00607 addr, data, val));
00608 loops = 0;
00609 }
00610 }
00611 if (loops > maxloops)
00612 {
00613 if (loops > 10)
00614 EDTPRINTF(edt_p,1,("maxloops %x %d\n", addr, loops));
00615 maxloops = loops;
00616 }
00617 if (done)
00618 return (0);
00619 else
00620 return (addr);
00621 }
00622
00623
00624
00625
00626
00627 void
00628 edt_x_byte_program(EdtDev *edt_p, u_int addr, u_char data, int xtype)
00629 {
00630 u_char buf[2];
00631
00632 switch(xtype)
00633 {
00634
00635 case XTYPE_SPI:
00636 buf[0] = data;
00637 edt_x_block_program(edt_p, addr, buf, 1, xtype);
00638
00639 break;
00640 case XTYPE_BT:
00641 bt_byte_program(edt_p, xtype, addr, data);
00642 break;
00643 case XTYPE_BT2:
00644 bt2_byte_program(edt_p, xtype, addr, data);
00645 break;
00646 case XTYPE_X:
00647 xbyte_program(edt_p, addr, data);
00648 break;
00649 }
00650 }
00651
00652
00653
00654
00655 void
00656 edt_x_block_program(EdtDev *edt_p, u_int addr, u_char *data, int nbytes, int xtype)
00657 {
00658 int i;
00659 u_char *dp = data;
00660
00661 switch(xtype)
00662 {
00663
00664 case XTYPE_SPI:
00665 spi_block_program(edt_p, addr, nbytes, data, 0);
00666 break;
00667
00668 case XTYPE_BT:
00669 for (i=0; i<nbytes; i++)
00670 bt_byte_program(edt_p, xtype, addr++, *(dp++));
00671 break;
00672 case XTYPE_BT2:
00673 for (i=0; i<nbytes; i++)
00674 bt2_byte_program(edt_p, xtype, addr++, *(dp++));
00675 break;
00676 case XTYPE_X:
00677 for (i=0; i<nbytes; i++)
00678 xbyte_program(edt_p, addr++, *(dp++));
00679 break;
00680
00681 }
00682 }
00683
00684
00685
00686
00687 void
00688 edt_x_verify(EdtDev *edt_p, u_int addr, u_char *data, int nbytes, int xtype)
00689 {
00690 switch(xtype)
00691 {
00692 case XTYPE_SPI:
00693 spi_block_program(edt_p, addr, nbytes, data, 1);
00694 break;
00695 default:
00696 EDTPRINTF(edt_p,1,("Oops! Can't verify type %d xilinx with edt_x_verify (pciload internal)\n", xtype));
00697 break;
00698 }
00699 }
00700
00701
00702
00724 void
00725 edt_get_esn(EdtDev *edt_p, char *esn)
00726 {
00727 char dmy[128];
00728 edt_get_sns(edt_p, esn, dmy);
00729 }
00730
00746 void
00747 edt_get_osn(EdtDev *edt_p, char *osn)
00748 {
00749 char dmy[128];
00750 edt_get_sns(edt_p, dmy, osn);
00751 }
00752
00753 static int
00754 isdigit_str(char *s)
00755 {
00756 unsigned int i;
00757
00758 for (i=0; i<strlen(s); i++)
00759 if ((s[i]) < '0' || s[i] > '9')
00760 return 0;
00761 return 1;
00762 }
00763
00764
00765
00766
00782 int
00783 edt_x_get_fname(EdtDev *edt_p, char *name)
00784 {
00785 int promcode;
00786 char *p;
00787 char *idstr;
00788 EdtPromData pdata;
00789 Edt_prominfo *ep;
00790 u_char stat;
00791
00792 promcode = edt_x_prom_detect(edt_p, &stat);
00793
00794 ep = edt_get_prominfo(promcode);
00795
00796 edt_read_prom_data(edt_p, promcode, ep->defaultseg,
00797 &pdata);
00798
00799 idstr = pdata.id;
00800
00801 if ((p = strrchr(idstr, '.')) != NULL)
00802 *p = '\0' ;
00803
00804 if ((p = strrchr(idstr, '_')) != NULL)
00805 {
00806 if (( *(p + 1) == '3' || *(p + 1) == '5' ) && ( *(p + 2) == 'v' ))
00807 *p = '\0' ;
00808 }
00809
00810 if ((p = strrchr(idstr, '-')) != NULL)
00811 {
00812 *p = '\0' ;
00813 }
00814
00815 strcpy(name, idstr);
00816
00817 return 0;
00818 }
00819
00836 int
00837 edt_x_get_fname_auto(EdtDev *edt_p, char *name)
00838 {
00839 Edt_prominfo *ep;
00840 char *p;
00841 char *idstr;
00842 EdtPromData pdata;
00843 int promcode;
00844 u_char stat;
00845
00846 promcode = edt_x_prom_detect(edt_p, &stat);
00847
00848 ep = edt_get_prominfo(promcode);
00849 edt_read_prom_data(edt_p, promcode, ep->defaultseg,
00850 &pdata);
00851
00852 idstr = pdata.id;
00853
00854
00855 if ((p = strrchr(idstr, '.')) != NULL)
00856 {
00857 *p = '\0' ;
00858
00859
00860 if ((strlen(idstr) > 3) && ((strcmp(p-3, "_3v") == 0) || (strcmp(p-3, "_5v") == 0)))
00861 *(p-3) = '\0' ;
00862
00863 }
00864
00865
00866 if ((p = strrchr(idstr, '-')) != NULL)
00867 *p = '\0';
00868
00869
00870 strcpy(name, idstr);
00871
00872 return 0;
00873 }
00874
00875
00900 void
00901 edt_get_sns_sector(EdtDev *edt_p, char *esn, char *osn, int sector)
00902 {
00903 int promcode;
00904 u_char stat;
00905 EdtPromData pdata;
00906
00907 promcode = edt_x_prom_detect(edt_p, &stat);
00908
00909 if ((promcode == PROM_UNKN) || (promcode > edt_get_max_promcode()))
00910 {
00911 esn[0] = 0;
00912 osn[0] = 0;
00913 }
00914 else
00915 {
00916 edt_read_prom_data(edt_p, promcode, sector, &pdata);
00917 strcpy(esn, pdata.esn);
00918 strcpy(osn, pdata.osn);
00919 }
00920 }
00921
00922 void
00923 edt_get_sns(EdtDev *edt_p, char *esn, char *osn)
00924 {
00925 u_char stat;
00926 int promcode = edt_x_prom_detect(edt_p, &stat);
00927 Edt_prominfo *ep = edt_get_prominfo(promcode);
00928
00929
00930 edt_get_sns_sector(edt_p, esn, osn, ep->defaultseg);
00931 }
00932
00933
00934
00935 #define SPI_WREN 0x06
00936 #define SPI_WRDI 0x04
00937 #define SPI_RDSR 0x05
00938 #define SPI_WRSR 0x01
00939 #define SPI_READ 0x03
00940 #define SPI_FREAD 0x0B
00941 #define SPI_PP 0x02
00942 #define SPI_SE 0xD8
00943 #define SPI_BE 0xC7
00944 #define SPI_DP 0xB9
00945 #define SPI_RES 0xAB
00946
00947 #define SPI_REG 0x02000084
00948 #define SPI_EN 0x8000
00949 #define SPI_S 0x2000
00950 #define SPI_D 0x1000
00951 #define SPI_Q 0x0200
00952
00953
00954
00955 unsigned char Spi_wbufa[260];
00956 unsigned char* Spi_wbuf=Spi_wbufa+3;
00957 unsigned char Spi_rbuf[260];
00958 volatile caddr_t Spi_mapaddr = 0;
00959
00960
00961
00962 static void
00963 spi_xw(EdtDev *edt_p, u_int addr, u_int data)
00964 {
00965 u_int dmy;
00966 edt_set(edt_p, addr, data) ;
00967 dmy = edt_get(edt_p, 0x04000080) ;
00968 }
00969
00970 static u_int
00971 spi_xr(EdtDev *edt_p, u_int addr)
00972 {
00973 return(edt_get(edt_p, addr)) ;
00974 }
00975
00976
00977 static void
00978 spi_xwr(EdtDev *edt_p, int val)
00979 {
00980 int d;
00981 d = SPI_EN | val;
00982 spi_xw(edt_p, SPI_REG, d);
00983 }
00984
00985 static int
00986 spi_xrd(EdtDev *edt_p)
00987 {
00988 int v;
00989 v = spi_xr(edt_p, 0x02000084);
00990 if (v & SPI_Q) return(1);
00991 else return(0);
00992 }
00993
00994
00995 static void
00996 spiprim(EdtDev *edt_p, int opcode, int wbytes, int rbytes, unsigned char* wbuf, unsigned char* rbuf)
00997 {
00998 int c, b, cdat;
00999
01000
01001
01002 cdat = opcode;
01003 for (b=0; b<8; b++) {
01004 if (cdat & 0x80) {
01005 spi_xwr(edt_p, SPI_D);
01006 } else {
01007 spi_xwr(edt_p, 0);
01008 }
01009 cdat <<= 1;
01010 }
01011
01012 for (c=0; c<wbytes; c++) {
01013 cdat = wbuf[c];
01014 for (b=0; b<8; b++) {
01015 if (cdat & 0x80) {
01016 spi_xwr(edt_p, SPI_D);
01017 } else {
01018 spi_xwr(edt_p, 0);
01019 }
01020 cdat <<= 1;
01021 }
01022 }
01023
01024 for (c=0; c<rbytes; c++) {
01025 cdat = 0;
01026 for (b=0; b<8; b++) {
01027 cdat <<= 1;
01028 if (spi_xrd(edt_p) & 1)
01029 cdat |= 1;
01030 if ((b!=7) || (c!=(rbytes-1))) {
01031 spi_xwr(edt_p, 0);
01032 }
01033 }
01034 rbuf[c] = (char) cdat;
01035 }
01036
01037 spi_xwr(edt_p, SPI_S);
01038 }
01039
01040
01041
01042
01043 static int
01044 spi_reset(EdtDev *edt_p)
01045 {
01046 unsigned char rval;
01047 char *magic = "555";
01048
01049 spiprim(edt_p, SPI_RES, 3, 1, (unsigned char *)magic, &rval);
01050
01051 return(rval&0xff);
01052 }
01053
01054
01055
01056
01057 static void
01058 spi_read(EdtDev *edt_p, int addr, u_char *rbuf, int rcnt)
01059 {
01060 if ((rcnt<1) || (rcnt > 256)) {
01061 EDTPRINTF(edt_p,1,("Error, bad spi_read() rcnt of %d\n", rcnt));
01062 return;
01063 }
01064 Spi_wbufa[0]=addr>>16;
01065 Spi_wbufa[1]=addr>>8;
01066 Spi_wbufa[2]=(char) addr;
01067 Spi_wbufa[3]=0;
01068
01069 spiprim(edt_p, SPI_FREAD, 4, rcnt, Spi_wbufa, rbuf);
01070 }
01071
01072 static int
01073 spi_write(EdtDev *edt_p, u_int addr, int wcnt)
01074 {
01075 int statcnt;
01076
01077 if ((wcnt<1) || (wcnt>256)) {
01078 EDTPRINTF(edt_p,1,("Error, bad spi_write() wcnt of %d\n", wcnt));
01079 return -1;
01080 }
01081 spiprim(edt_p, SPI_WREN, 0, 0, NULL, NULL);
01082
01083 Spi_wbufa[0]=addr>>16;
01084 Spi_wbufa[1]=addr>>8;
01085 Spi_wbufa[2]=(char) addr;
01086
01087 spiprim(edt_p, SPI_PP, 3+wcnt, 0, Spi_wbufa, NULL);
01088
01089 statcnt=0;
01090 do {
01091 spiprim(edt_p, SPI_RDSR, 0, 1, NULL, Spi_rbuf);
01092 statcnt++;
01093 } while ((Spi_rbuf[0] & 1) == 1);
01094
01095 return 0;
01096 }
01097
01098 #define TOO_MANY 100000
01099
01100
01101
01102
01103 static int
01104 spi_sector_erase(EdtDev *edt_p, u_int addr)
01105 {
01106 int statcnt;
01107
01108 spiprim(edt_p, SPI_WREN, 0, 0, NULL, NULL);
01109 Spi_wbufa[0]=addr>>16;
01110 Spi_wbufa[1]=addr>>8;
01111 Spi_wbufa[2]=(u_char) addr;
01112 spiprim(edt_p, SPI_SE, 3, 0, Spi_wbufa, NULL);
01113
01114 statcnt=0;
01115 do {
01116 spiprim(edt_p, SPI_RDSR, 0, 1, NULL, Spi_rbuf);
01117 if (statcnt++ > TOO_MANY)
01118 {
01119 EDTPRINTF(edt_p,1,("erase spun for too long, bailing out\n"));
01120 return(-1);
01121 }
01122 } while ((Spi_rbuf[0] & 1) == 1);
01123
01124
01125 return(0);
01126 }
01127
01128
01129
01130
01131 int
01132 has_slashes(char *name)
01133 {
01134 char *p = name;
01135
01136 while (*p)
01137 {
01138 if ((*p == '/') || (*p == '\\'))
01139 return 1;
01140 ++p;
01141 }
01142 return 0;
01143 }
01144
01145
01146
01147
01148
01149 static int
01150 spi_block_program(EdtDev *edt_p, int addr0, int size, u_char *spibuf, int verify_only)
01151 {
01152 int i, addr, n, bcnt, errorcnt, val, first, last;
01153
01154
01155 for (i=0; i<5; i++)
01156 {
01157 if ((val = spi_reset(edt_p)) != 0)
01158 break;
01159 (void)edt_delay(100);
01160 }
01161
01162 if ((val != 0x11) && (val != 0x13) && (val != 0x14))
01163 {
01164 EDTPRINTF(edt_p,0,(" Error, did not detect SPI flash device, \n"));
01165 EDTPRINTF(edt_p,0,(" spi_reset() returned 0x%02x, not 0x11/0x13/0x14\n", val));
01166 return -1;
01167 }
01168
01169 if (!verify_only)
01170 {
01171 first = (addr0&0xff0000)>>16;
01172 last = ((addr0+size)&0xff0000)>>16;
01173 EDTPRINTF(edt_p,0,(" First sector is %d, last is %d, erasing", first, last));
01174
01175 for (n=first; n<=last; n++)
01176 {
01177 spi_sector_erase(edt_p, n<<16);
01178 EDTPRINTF(edt_p,0,("."));
01179 }
01180 EDTPRINTF(edt_p,0,("\n"));
01181
01182 EDTPRINTF(edt_p,0,(" Writing 0x%x bytes to spiflash at 0x%x.",size,addr0));
01183 bcnt=0; addr=addr0;
01184 while (bcnt<size)
01185 {
01186 n=0;
01187 while (bcnt<size)
01188 {
01189 if ((n!=0) && (((addr+n)&0xff)==0)) break;
01190 #ifndef _KERNEL
01191 if (!(bcnt % 10000)) {printf("."); fflush(stdout); }
01192 #endif
01193 Spi_wbuf[n] = spibuf[bcnt];
01194 n = n+1;
01195 bcnt = bcnt+1;
01196 }
01197 if (n>0) spi_write(edt_p, addr, n);
01198 addr = addr + n;
01199 }
01200 }
01201
01202 EDTPRINTF(edt_p,0,("\n"));
01203 EDTPRINTF(edt_p,0,(" Verifying."));
01204 bcnt=0; addr=addr0; errorcnt=0;
01205 while (bcnt<size)
01206 {
01207 spi_read(edt_p, addr, Spi_rbuf, 256);
01208 n=0;
01209 while (bcnt<size) {
01210 if ((n!=0) && (((addr+n)&0xff)==0)) break;
01211 #ifndef _KERNEL
01212 if (!(bcnt % 10000)) {printf("."); fflush(stdout); }
01213 #endif
01214 if ((Spi_rbuf[n]&0xff) != (spibuf[bcnt]&0xff)) {
01215 if (errorcnt++ <= 10) {
01216 EDTPRINTF(edt_p,0,("Error at 0x%x: wrote:%02x, read:%02x\n",
01217 addr0+bcnt, spibuf[bcnt], Spi_rbuf[n]));
01218 }
01219 }
01220 n = n+1;
01221 bcnt = bcnt+1;
01222 }
01223 addr = addr + n;
01224 }
01225 if (errorcnt)
01226 EDTPRINTF(edt_p,0,(" Saw %d errors\n", errorcnt));
01227
01228 if (!errorcnt)
01229 EDTPRINTF(edt_p,0,("\nno errors\n"));
01230
01231 return 0;
01232 }
01233
01234
01235
01236
01237 static void
01238 xwrite(EdtDev * edt_p, u_int addr, u_char val)
01239 {
01240
01241 (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01242 tst_write(edt_p, EDT_FLASHROM_DATA, val) ;
01243 (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01244 tst_write(edt_p, EDT_FLASHROM_ADDR, EN_HIGH_ADD | addr | EDT_WRITECMD) ;
01245 }
01246
01247
01248 static u_char
01249 xread(EdtDev * edt_p, u_int addr)
01250 {
01251
01252 (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01253 tst_write(edt_p, EDT_FLASHROM_ADDR, EN_HIGH_ADD | addr) ;
01254 (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01255 return (u_char) (tst_read(edt_p, EDT_FLASHROM_DATA));
01256
01257 }
01258
01259
01260
01261 static void
01262 xreset(EdtDev * edt_p)
01263 {
01264 xwrite(edt_p, 0x5555, 0xaa);
01265 xwrite(edt_p, 0x2aaa, 0x55);
01266 xwrite(edt_p, 0x5555, 0xf0);
01267 }
01268
01269
01270
01271
01272
01273 static void
01274 bt_write(EdtDev * edt_p, u_int addr, u_char val)
01275 {
01276
01277
01278 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01279
01280 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_LO | (addr & 0xff));
01281 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01282
01283 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_MID | ((addr >> 8) & 0xff));
01284 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01285
01286
01287 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_HI | ((addr >> 16) & 0xff));
01288 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01289
01290 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_ROM | (val & 0xff));
01291 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01292 }
01293
01294
01295
01296
01297 static void
01298 bt_reset(EdtDev * edt_p)
01299 {
01300 bt_write(edt_p, 0x555, 0xaa);
01301 bt_write(edt_p, 0x2aa, 0x55);
01302 bt_write(edt_p, 0x555, 0xf0);
01303 }
01304
01305
01306 static void
01307 bt2_reset(EdtDev * edt_p)
01308 {
01309 bt_write(edt_p, 0x0, 0xf0);
01310 }
01311
01312
01313 static u_char
01314 xreadstat(EdtDev * edt_p)
01315 {
01316 u_char stat;
01317 uint_t rdval;
01318
01319
01320
01321
01322
01323 tst_write(edt_p, EDT_FLASHROM_ADDR, 0);
01324 rdval = tst_read(edt_p, EDT_FLASHROM_DATA);
01325 stat = (u_char) (rdval >> 8);
01326 return (stat);
01327 }
01328
01329
01330
01331
01332 static u_char
01333 bt_read(EdtDev * edt_p, u_int addr)
01334 {
01335 u_char stat;
01336
01337
01338
01339 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01340
01341 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_LO | (addr & 0xff));
01342
01343 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01344
01345 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_MID | ((addr >> 8) & 0xff));
01346
01347 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01348
01349 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_HI | ((addr >> 16) & 0xff));
01350
01351 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
01352
01353
01354 stat = (u_char) tst_read(edt_p, EDT_FLASHROM_DATA);
01355
01356 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01357 return (stat);
01358 }
01359
01360
01361
01362
01363 static u_char
01364 bt_readstat(EdtDev * edt_p)
01365 {
01366 u_char stat;
01367 uint_t rdval;
01368
01369
01370
01371
01372
01373 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01374 tst_write(edt_p, EDT_FLASHROM_DATA, BT_EN_READ | BT_READ);
01375 rdval = tst_read(edt_p, EDT_FLASHROM_DATA);
01376 stat = (u_char) rdval;
01377
01378 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01379 return (stat);
01380 }
01381
01382
01383
01384 void
01385 edt_x_reset(EdtDev *edt_p, int xtype)
01386 {
01387 switch(xtype)
01388 {
01389 case XTYPE_SPI:
01390 spi_reset(edt_p);
01391 break;
01392 case XTYPE_BT:
01393 bt_reset(edt_p);
01394 break;
01395 case XTYPE_BT2:
01396 bt2_reset(edt_p);
01397 break;
01398 case XTYPE_X:
01399 xreset(edt_p) ;
01400 break;
01401 }
01402 }
01403
01404
01405
01406
01407
01408
01409 u_int
01410 edt_get_fpga_sectorsize(EdtDev *edt_p, Edt_prominfo *ep)
01411 {
01412 u_int tmpval;
01413
01414 if (ep->xtype == XTYPE_BT)
01415 {
01416 tmpval = bt_read(edt_p, 0x0) |
01417 (bt_read(edt_p, 0x1) << 8) |
01418 (bt_read(edt_p, 0x2) << 16) |
01419 (bt_read(edt_p, 0x3) << 24) ;
01420 return tmpval;
01421 }
01422 else return ep->sectorsize;
01423 }
01424
01425
01426
01427
01428 u_int
01429 edt_get_fpga_info_index(EdtDev *edt_p)
01430 {
01431 u_int tmpval;
01432
01433 tmpval = bt_read(edt_p, 0x4) |
01434 (bt_read(edt_p, 0x5) << 8) |
01435 (bt_read(edt_p, 0x6) << 16) |
01436 (bt_read(edt_p, 0x7) << 24) ;
01437 return tmpval;
01438 }
01439
01440
01441
01442
01443
01444
01445 u_int
01446 edt_get_id_addr(int promcode, int segment)
01447 {
01448 u_int id_addr;
01449 Edt_prominfo *ep = edt_get_prominfo(promcode);
01450
01451 if (ep->sectorsize == 0)
01452 return 1;
01453
01454 switch(promcode)
01455 {
01456
01457 case AMD_4013E:
01458 id_addr = (ep->sectsperseg * ep->sectorsize) - PCI_ID_SIZE;
01459 break;
01460
01461 case SPI_XC3S1200E:
01462 id_addr = segment * ep->sectorsize;
01463 break;
01464
01465 default:
01466 id_addr = ((segment + 1) * ep->sectsperseg * ep->sectorsize) - PCI_ID_SIZE;
01467 break;
01468
01469 }
01470 return id_addr;
01471 }
01472
01473
01474
01475
01476
01477
01478
01479
01480 u_int
01481 edt_get_promaddrs(EdtDev *edt_p, int promcode, int segment,
01482 EdtPromIdAddresses *paddr)
01483
01484 {
01485 Edt_prominfo *ep = edt_get_prominfo(promcode);
01486 char tst[4];
01487
01488
01489
01490 paddr->id_addr = edt_get_id_addr(promcode, segment);
01491
01492
01493
01494
01495
01496
01497
01498
01499 if (ep->xtype == XTYPE_SPI)
01500 {
01501 paddr->osn_addr = paddr->id_addr + PCI_ID_SIZE;
01502 paddr->esn_addr = paddr->osn_addr + OSN_SIZE;
01503 paddr->extra_tag_addr = paddr->esn_addr + ESN_SIZE;
01504 paddr->extra_size_addr = paddr->extra_tag_addr + 4;
01505 paddr->extra_data_addr = paddr->extra_size_addr + 4;
01506
01507
01508 }
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519 else
01520 {
01521 paddr->osn_addr = paddr->id_addr - OSN_SIZE;
01522 paddr->esn_addr = paddr->osn_addr - ESN_SIZE;
01523 paddr->extra_tag_addr = paddr->esn_addr - 4;
01524 paddr->extra_size_addr = paddr->extra_tag_addr - 4;
01525
01526
01527 }
01528
01529 read_x_block(edt_p, paddr->extra_tag_addr, (u_char *)tst, 4, ep->xtype);
01530
01531 if (strncmp(tst,"XTR:",4) == 0)
01532 {
01533
01534 read_x_block(edt_p, paddr->extra_size_addr, (u_char *)&paddr->extra_size, 4, ep->xtype);
01535
01536 if (needswap)
01537 {
01538 paddr->extra_size = swap32(paddr->extra_size);
01539 }
01540 if (ep->xtype != XTYPE_SPI)
01541 paddr->extra_data_addr = paddr->extra_size_addr - (4 + paddr->extra_size);
01542
01543 }
01544 else
01545 paddr->extra_size = 0;
01546
01547 return paddr->id_addr;
01548 }
01549
01550
01551
01552
01553
01554 u_int
01555 ida_4013e(void *dmy, int segment)
01556 {
01557 return (8 * E_SECTOR_SIZE) - PCI_ID_SIZE;
01558 }
01559
01560 u_int
01561 ida_4013xla(void *dmy, int segment)
01562 {
01563 return (segment * XLA_SECTOR_SIZE) + XLA_SECTOR_SIZE - PCI_ID_SIZE;
01564 }
01565
01566 u_int
01567 ida_4028xla(void *dmy, int segment)
01568 {
01569 return ((segment + 1) * 2 * XLA_SECTOR_SIZE) - PCI_ID_SIZE;
01570 }
01571
01572 u_int
01573 ida_xc2s100(void *dmy, int segment)
01574 {
01575 return ((segment + 1) * 4 * XLA_SECTOR_SIZE) - PCI_ID_SIZE;
01576 }
01577
01578 u_int
01579 ida_xc3s1200e(void *dmy, int segment)
01580 {
01581 return segment * SPI_SECTOR_SIZE;
01582 }
01583
01584 u_int
01585 ida_xc5vlx30t(void * edt_p , int dmy)
01586 {
01587 return edt_get_fpga_info_index((EdtDev *)edt_p);
01588 }
01589
01590 void tst_init(EdtDev *edt_p)
01591 {
01592
01593 #ifndef _KERNEL
01594
01595 if (!edt_p->mapaddr)
01596 edt_p->mapaddr = (caddr_t)edt_mapmem(edt_p, 0, 256) ;
01597
01598 #endif
01599
01600 needswap = !edt_little_endian();
01601 }
01602
01603 static void
01604 tst_write(EdtDev * edt_p, uint_t desc, uint_t val)
01605 {
01606
01607 #ifndef _KERNEL
01608 u_int dmy;
01609
01610 if (edt_p->mapaddr)
01611 {
01612
01613 tstaddr = (volatile u_int *)(edt_p->mapaddr + (desc & 0xff)) ;
01614
01615 if (needswap)
01616 {
01617 *tstaddr = swap32(val) ;
01618 }
01619 else
01620 {
01621 *tstaddr = val ;
01622 }
01623
01624 dmy = *tstaddr;
01625 }
01626 else
01627 #endif
01628 edt_set(edt_p, desc, val) ;
01629
01630 }
01631
01632 static uint_t
01633 tst_read(EdtDev * edt_p, uint_t desc)
01634 {
01635
01636 #ifndef _KERNEL
01637
01638 if (edt_p->mapaddr)
01639 {
01640
01641 tstaddr = (volatile u_int *)(edt_p->mapaddr + (desc & 0xff)) ;
01642
01643 if (needswap)
01644 {
01645 return (swap32(*tstaddr)) ;
01646 }
01647 else
01648 return (*tstaddr) ;
01649
01650 }
01651 else
01652 #endif
01653 return(edt_get(edt_p, desc)) ;
01654 }
01655
01656 void tst_pflash(EdtDev *edt_p, uint_t addr, uint_t val)
01657 {
01658
01659 tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) 0xaa);
01660 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01661 tst_write(edt_p, EDT_FLASHROM_ADDR, (u_int) (0x5555 | EDT_WRITECMD));
01662 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01663 tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) 0x55);
01664 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01665 tst_write(edt_p, EDT_FLASHROM_ADDR, (u_int) (0x2aaa | EDT_WRITECMD));
01666 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01667 tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) 0xa0);
01668 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01669 tst_write(edt_p, EDT_FLASHROM_ADDR, (u_int) (0x5555 | EDT_WRITECMD));
01670 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01671 tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) val);
01672 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01673 tst_write(edt_p, EDT_FLASHROM_ADDR,
01674 (u_int) (EN_HIGH_ADD | addr | EDT_WRITECMD));
01675 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01676 }
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693 char *
01694 read_x_string(EdtDev *edt_p, u_int addr, char *buf, int size, int xtype)
01695 {
01696 int i;
01697 char *ret = 0;
01698 u_char val;
01699
01700
01701 for (i = 0; i < size; i++)
01702 {
01703 switch(xtype)
01704 {
01705 case XTYPE_SPI:
01706 spi_reset(edt_p);
01707 spi_read(edt_p, (u_int)addr, &val, 1);
01708 break;
01709 case XTYPE_BT:
01710 case XTYPE_BT2:
01711 val = bt_read(edt_p, (u_int)addr);
01712 break;
01713 case XTYPE_X:
01714 val = xread(edt_p, (u_int)addr);
01715 break;
01716 }
01717 buf[i] = val;
01718 addr++;
01719
01720
01721 if (!ret && val >= 0x20 && val <= 0x7e)
01722 ret = &buf[i];
01723 }
01724 buf[i] = 0;
01725 return ret;
01726 }
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742 char *
01743 read_x_block(EdtDev *edt_p, u_int addr, u_char *buf, int size, int xtype)
01744 {
01745 int i;
01746 char *ret = 0;
01747 u_char val;
01748
01749
01750 for (i = 0; i < size; i++)
01751 {
01752 switch(xtype)
01753 {
01754 case XTYPE_SPI:
01755 spi_reset(edt_p);
01756 spi_read(edt_p, (u_int)addr, &val, 1);
01757 break;
01758 case XTYPE_BT:
01759 case XTYPE_BT2:
01760 val = bt_read(edt_p, (u_int)addr);
01761 break;
01762 case XTYPE_X:
01763 val = xread(edt_p, (u_int)addr);
01764 break;
01765 }
01766 buf[i] = val;
01767 addr++;
01768
01769 }
01770
01771 return (char *) buf;
01772 }
01773
01774 int
01775 edt_sector_erase(EdtDev * edt_p, u_int sector, u_int sec_size, int xtype)
01776 {
01777 switch(xtype)
01778 {
01779 case XTYPE_SPI:
01780 spi_sector_erase(edt_p, sector << 16);
01781 break;
01782 case XTYPE_BT:
01783 bt_sector_erase(edt_p, sector, sec_size);
01784 break;
01785 case XTYPE_BT2:
01786 bt2_sector_erase(edt_p, sector, sec_size);
01787 break;
01788 case XTYPE_X:
01789 xsector_erase(edt_p, sector, sec_size);
01790 break;
01791 }
01792 return 0;
01793 }
01794
01795
01796 int
01797 edt_x_prom_detect(EdtDev * edt_p, u_char *stat)
01798 {
01799 u_int desc = EDT_FLASHROM_DATA;
01800 u_int flashrom_bits, idbits;
01801 u_char mid, devid;
01802 int prom;
01803
01804 EDTPRINTF(edt_p, 2, ("edt_x_prom_detect\n"));
01805
01806
01807 tst_init(edt_p) ;
01808
01809
01810
01811
01812
01813
01814 tst_write(edt_p, desc, BT_A0);
01815 flashrom_bits = tst_read(edt_p, desc) & BT_A0;
01816
01817 if (flashrom_bits == BT_A0)
01818 {
01819 EDTPRINTF(edt_p,2,(" FLASHROM command BT_A0 can be set board has boot controller\n"));
01820
01821 *stat = bt_readstat(edt_p);
01822 idbits = (u_int)((*stat & STAT_IDMASK) >> STAT_IDSHFT);
01823 EDTPRINTF(edt_p,2,("\t\tRead code %02x id bits %x\n", *stat, idbits));
01824
01825
01826 switch (idbits)
01827 {
01828 case STAT_EP2SGX30D:
01829 prom = AMD_EP2SGX30D;
01830 break;
01831 case STAT_XC3S1200E:
01832 prom = SPI_XC3S1200E;
01833 break;
01834 case STAT_XC5VLX30T:
01835 prom = AMD_XC5VLX30T;
01836 break;
01837 case STAT_XC5VLX50T:
01838 prom = AMD_XC5VLX50T;
01839 break;
01840 case STAT_XC5VLX70T:
01841 prom = AMD_XC5VLX70T;
01842 break;
01843 case STAT_XC4028XLA:
01844 prom = AMD_4028XLA;
01845 break;
01846 case STAT_XC2S150:
01847 prom = AMD_XC2S150;
01848 break;
01849 case STAT_XC2S200_NP:
01850 prom = AMD_XC2S200_4M;
01851 break;
01852 case STAT_XC2S200:
01853 prom = AMD_XC2S200_8M;
01854 break;
01855 case STAT_XC2S100:
01856 prom = AMD_XC2S100_8M;
01857 break;
01858 default:
01859 prom = PROM_UNKN;
01860 break;
01861 }
01862
01863
01864 }
01865 else
01866 {
01867 EDTPRINTF(edt_p,2,(" BT_A0 wrote, read back %02x, must not have boot controller\n", flashrom_bits));
01868 prom = PROM_UNKN;
01869 }
01870
01871
01872
01873
01874 if (prom == PROM_UNKN)
01875 {
01876 int i;
01877
01878 edt_x_reset(edt_p, 0);
01879
01880
01881 xwrite(edt_p, 0x5555, 0xaa);
01882 xwrite(edt_p, 0x2aaa, 0x55);
01883 xwrite(edt_p, 0x5555, 0x90);
01884 mid = xread(edt_p, 0x0);
01885 devid = xread(edt_p, 0x1);
01886
01887 for (i = 0; older_devices[i].prom != 0; i++)
01888 {
01889 if (mid == older_devices[i].mid && devid == older_devices[i].devid)
01890 {
01891 prom = older_devices[i].prom;
01892 break;
01893 }
01894 }
01895
01896 EDTPRINTF(edt_p,2,(" edt_x_prom_detect: autoselect manuf id %02x devid %02x code %d\n",
01897 mid, devid, prom));
01898 edt_x_reset(edt_p, 0);
01899
01900 *stat = xreadstat(edt_p);
01901 }
01902 return (prom);
01903 }
01904
01905
01906 EdtPromParmBlock *
01907 edt_get_parms_block(EdtPromData *pdata, char *id)
01908
01909 {
01910 EdtPromParmBlock *p;
01911
01912 p = (EdtPromParmBlock *) pdata->extra_buf;
01913
01914 if (p->size > (u_int) pdata->extra_size)
01915 return BAD_PARMS_BLOCK;
01916
01917 while (p->size && ((u_char *) p - pdata->extra_buf) < pdata->extra_size)
01918 {
01919 if (strncmp(id, p->type,4) == 0)
01920 return p;
01921 p = (EdtPromParmBlock *) ((u_char *) p + p->size);
01922 }
01923
01924 return NULL;
01925
01926 }
01927 EdtPromParmBlock *edt_add_parmblock(EdtPromData *pdata, char *type, int datasize)
01928
01929 {
01930
01931 EdtPromParmBlock *p;
01932
01933 p = edt_get_parms_block(pdata, type);
01934
01935 if (p)
01936 return NULL;
01937
01938 if (pdata->extra_size + datasize + 8 > PROM_EXTRA_SIZE)
01939 return NULL;
01940
01941 p = (EdtPromParmBlock *) (pdata->extra_buf + pdata->extra_size);
01942 strncpy(p->type,type,4);
01943 p->size = datasize;
01944
01945 pdata->extra_size += 8 + datasize;
01946
01947 return p;
01948 }
01949
01950
01951
01952
01953 void
01954 edt_x_program_extra(EdtDev *edt_p, int promcode, EdtPromData *pdata, int sect)
01955 {
01956 u_int id_addr;
01957 Edt_prominfo *ep = edt_get_prominfo(promcode);
01958 int sector;
01959 EdtPromIdAddresses addr;
01960 char *key_str = "XTR:";
01961
01962 sector = (sect == IS_DEFAULT_SECTOR)? ep->defaultseg:sect;
01963
01964 if ((id_addr = edt_get_promaddrs(edt_p, promcode, sector, &addr)) == 1)
01965 {
01966 EDTPRINTF(edt_p, 0, ("invalid device; no ID info\n"));
01967 return;
01968 }
01969
01970 edt_x_reset(edt_p, ep->xtype);
01971
01972 if (pdata->extra_size)
01973 {
01974 u_int size;
01975
01976 size = pdata->extra_size;
01977 if (!edt_little_endian())
01978 size = swap32(size);
01979
01980 if (ep->xtype != XTYPE_SPI)
01981 addr.extra_data_addr = addr.extra_size_addr - (4 + pdata->extra_size);
01982
01983 edt_x_block_program(edt_p, addr.extra_tag_addr, (u_char *) key_str, 4, ep->xtype);
01984 edt_x_block_program(edt_p, addr.extra_size_addr, (u_char *) &size, 4, ep->xtype);
01985 edt_x_block_program(edt_p, addr.extra_data_addr, pdata->extra_buf, pdata->extra_size, ep->xtype);
01986 }
01987
01988 edt_x_reset(edt_p, ep->xtype);
01989
01990 }
01991
01992 static void
01993 edt_program_sn_str(EdtDev *edt_p, u_int addr, char *str, char *tag, int size, int xtype)
01994
01995 {
01996 char sn_str[ESN_SIZE];
01997 if (str[0])
01998 {
01999 edt_x_reset(edt_p, xtype);
02000 edt_zero(sn_str, size);
02001 if (strncmp(str, "erase", 5) != 0)
02002 {
02003 strcpy(sn_str, tag);
02004 strcat(sn_str, str);
02005 }
02006
02007 edt_x_block_program(edt_p, addr, (u_char *)sn_str, size, xtype);
02008 }
02009 }
02010
02011
02012 void
02013 edt_program_promdata(EdtDev *edt_p,
02014 int promcode,
02015 int sector,
02016 EdtPromData *pdata)
02017 {
02018
02019 Edt_prominfo *ep = edt_get_prominfo(promcode);
02020
02021 EdtPromIdAddresses addr;
02022
02023
02024 addr.id_addr = edt_get_promaddrs(edt_p, promcode, sector, &addr);
02025
02026 EDTPRINTF(edt_p, 2,
02027 ("\nedt_program_promdata id_addr %x oemsn addr %x edtsn addr %x\n",
02028 addr.id_addr, addr.osn_addr, addr.esn_addr));
02029
02030 edt_program_sn_str(edt_p, addr.osn_addr,pdata->osn, "OSN:", OSN_SIZE, ep->xtype);
02031
02032 edt_program_sn_str(edt_p, addr.esn_addr,pdata->esn, "ESN:", ESN_SIZE, ep->xtype);
02033
02034 edt_x_program_extra(edt_p, promcode, pdata, sector);
02035 }
02036
02037
02038
02039
02040 char *
02041 edt_x_type_string(int xtype)
02042 {
02043 switch (xtype)
02044 {
02045 case XTYPE_X: return("XTYPE_X");
02046 case XTYPE_BT: return("XTYPE_BT");
02047 case XTYPE_LTX: return( "XTYPE_LTX");
02048 case XTYPE_SPI: return( "XTYPE_SPI");
02049 case XTYPE_BT2: return( "XTYPE_BT2");
02050 default: return("UNKNOWN");
02051 }
02052 }
02053
02054
02055
02056
02057
02058 void
02059 edt_read_prom_data(EdtDev *edt_p, int promcode, int segment,
02060 EdtPromData *pdata)
02061
02062 {
02063 Edt_prominfo *ep = edt_get_prominfo(promcode);
02064 char idbuf[PCI_ID_SIZE + 1];
02065 char oemsnbuf[OSN_SIZE + 1];
02066 char edtsnbuf[ESN_SIZE + 1];
02067
02068 char *ret;
02069
02070 EdtPromIdAddresses addr;
02071
02072 edt_zero(pdata, sizeof(EdtPromData));
02073
02074
02075 addr.id_addr = edt_get_promaddrs(edt_p, promcode, segment, &addr);
02076
02077 EDTPRINTF(edt_p, 2,
02078 ("\nedt_read_prom_data id_addr %x oemsn addr %x edtsn addr %x\n",
02079 addr.id_addr, addr.osn_addr, addr.esn_addr));
02080
02081
02082 if ((ret = read_x_string(edt_p, addr.id_addr, idbuf, PCI_ID_SIZE, ep->xtype)) != NULL)
02083 strncpy(pdata->id, ret, PCI_ID_SIZE);
02084
02085
02086 if ((ret = read_x_string(edt_p, addr.osn_addr, oemsnbuf, OSN_SIZE, ep->xtype)) != NULL)
02087 {
02088 if (strncmp(ret, "OSN:", 4) == 0)
02089 {
02090 strncpy(pdata->osn, &ret[4], OSN_SIZE);
02091 if (pdata->osn[strlen(pdata->osn)-1] == ':')
02092 pdata->osn[strlen(pdata->osn)-1] = '\0';
02093 }
02094 }
02095
02096
02097 if ((ret = read_x_string(edt_p, addr.esn_addr, edtsnbuf, ESN_SIZE, ep->xtype)) != NULL)
02098 if (strncmp(ret, "ESN:", 4) == 0)
02099 strncpy(pdata->esn, &ret[4], ESN_SIZE);
02100
02101
02102
02103 if (addr.extra_size)
02104 {
02105 if ((ret = read_x_block(edt_p, addr.extra_data_addr, pdata->extra_buf, addr.extra_size, ep->xtype)) != NULL)
02106 {
02107 pdata->extra_size = addr.extra_size;
02108 }
02109 }
02110
02111 #ifndef _KERNEL
02112 if (pdata->esn)
02113 edt_parse_esn(pdata->esn, &pdata->ei);
02114 #endif
02115
02116 edt_x_reset(edt_p, ep->xtype);
02117 }
02118
02119 #ifndef _KERNEL
02120
02141 int
02142 edt_parse_esn(char *str, Edt_embinfo *ei)
02143 {
02144 unsigned int i,j=0;
02145 int n;
02146 int nfields=0;
02147 char sn[128], pn[128], ifx[128], rev[128], clock[128], opt[128];
02148 char tmpstr[128];
02149
02150 edt_zero(ei,sizeof(*ei));
02151
02152 sn[0] = pn[0] = clock[0] = opt[0] = ifx[0] = '\0';
02153
02154 for (i=0; i<strlen(str); i++)
02155 {
02156 tmpstr[j++] = str[i];
02157 if (str[i] == ':')
02158 {
02159 ++nfields;
02160 if (str[i+1] == ':')
02161 tmpstr[j++] = ' ';
02162 }
02163 }
02164 tmpstr[j] = '\0';
02165
02166 if (nfields < 4)
02167 return -1;
02168
02169
02170 n = sscanf(tmpstr, "%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:", sn, pn, clock, opt, rev, ifx);
02171
02172
02173 if (strlen(sn) > 10)
02174 sn[10] = '\0';
02175
02176 if ((strlen(pn) > 10) || (strlen(opt) > 10) || !isdigit_str(clock))
02177 return -1;
02178
02179 if (n < 4)
02180 return -1;
02181
02182 if (n < 5)
02183 rev[0] = '\0';
02184
02185 if (n < 6)
02186 ifx[0] = '\0';
02187
02188 strcpy(ei->sn, sn);
02189 strcpy(ei->pn, pn);
02190 strcpy(ei->opt, opt);
02191 strcpy(ei->ifx, ifx);
02192 ei->clock = edt_strtol(clock,0,0);
02193 ei->rev = edt_strtol(rev,0,0);
02194
02195 return 0;
02196 }
02197
02198 #endif