00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "edtdef.h"
00013
00014 #ifdef _KERNEL
00015
00016 #include "edtdrv.h"
00017
00018 #define EdtDev Edt_Dev
00019
00020 #ifdef _NT_DRIVER_
00021
00022 #define edt_strtol strtol
00023
00024 #endif
00025
00026 #include "pciload.h"
00027
00028 #else
00029
00030 #include "edtinc.h"
00031 #include "pciload.h"
00032
00033
00034 #define edt_set edt_reg_write
00035 #define edt_get edt_reg_read
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
00053
00054
00055 static u_int ida_4013e(void *dmy, int sector);
00056 static u_int ida_4013xla(void *dmy, int sector);
00057 static u_int ida_4028xla(void *dmy, int sector);
00058 static u_int ida_xc2s100(void *dmy, int sector);
00059 static u_int ida_xc3s1200e(void *dmy, int sector);
00060 static u_int ida_xc2s1200e(void *dmy, int sector);
00061 static u_int ida_xc5vlx30t(void * edt_p, int dmy);
00062 static u_int ida_bt8(void * edt_p, int dmy);
00063 static u_int ida_f16(void * edt_p, int dmy);
00064 static u_int ida_micron(void * edt_p, int dmy);
00065 static u_int get_fpga_info_index_bt8(EdtDev *edt_p);
00066
00067
00068 static u_int mic_write(EdtDev *edt_p, u_int val);
00069 static u_int mic_read(EdtDev *edt_p);
00070 static u_int mic_read_flash(EdtDev *edt_p, u_int command, u_int address, u_char *read_bytes, u_int read_num_bytes);
00071 static u_char mic_read_status_register(EdtDev *edt_p);
00072 static u_int mic_write_enable(EdtDev *edt_p);
00073 static u_int mic_write_disable(EdtDev *edt_p);
00074 static u_int mic_subsector_erase(EdtDev *edt_p, u_int address);
00075 static u_int mic_sector_erase(EdtDev *edt_p, u_int address);
00076 static u_int mic_page_program(EdtDev *edt_p, u_int address, u_char *write_bytes, u_int write_num_bytes);
00077 static u_int mic_write_status_register(EdtDev *edt_p, u_char status_val);
00078 void mic_reset(EdtDev *edt_p);
00079 int edt_mic_is_protected(EdtDev *edt_p);
00080
00081 void edt_get_sns(EdtDev *edt_p, char *esn, char *osn);
00082 const char *edt_get_fpga_mfg(EdtDev * edt_p);
00083 int edt_flash_prom_detect(EdtDev *edt_p, u_short *stat);
00084 void edt_read_prom_data(EdtDev *edt_p, int promcode, int segment, EdtPromData *pdata);
00085 void edt_flash_byte_program(EdtDev *edt_p, u_int addr, u_char data, int ftype);
00086 void edt_flash_block_program(EdtDev *edt_p, u_int addr, u_char *data, u_int nbytes, int ftype);
00087 u_int edt_flash_get_cpld(EdtDev *edt_p, int ftype);
00088 u_char *edt_flash_block_read(EdtDev *edt_p, u_int addr, u_char *buf, u_int size, int ftype);
00089 int edt_get_max_promcode();
00090
00091
00092
00093 #define PROMCODE_TBL_SIZE 64
00094 static Edt_prominfo EPinfo[PROMCODE_TBL_SIZE] =
00095 {
00096
00097
00098 {"unknown", "unknown", 0xff, 0xff, "na", 0, 0, 0, 0, 0, 0, NULL, -1, -1},
00099 {"4013e", "AMD 29F010", 0xff, 0xff, "PCI", FTYPE_X, XilinxMagic, 0x004000, 8, 1, 0, ida_4013e, 1, -1},
00100 {"4013xla", "AMD 29F010", 0xff, 0xff, "PCI", FTYPE_X, XilinxMagic, 0x010000, 1, 3, 1, ida_4013xla, 1, 3},
00101 {"4028xla", "AMD 29F010", 0x00, 0xff, "PCI", FTYPE_BT, XilinxMagic, 0x010000, 2, 4, 2, ida_4028xla, 2, 3},
00102 {"xc2s150", "AMD 29LV040B", 0x01, 0xff, "PCI", FTYPE_BT, XilinxMagic, 0x010000, 2, 4, 2, ida_4028xla, 2, 3},
00103 {"xc2s200", "AMD 29LV040B 4MB", 0x02, 0xff, "PCI", FTYPE_BT, XilinxMagic, 0x010000, 4, 2, 2, ida_xc2s100, 0, 1},
00104 {"xc2s200", "AMD 29LV081B 8MB", 0x03, 0xff, "PCI", FTYPE_BT, XilinxMagic, 0x010000, 4, 4, 2, ida_xc2s100, 2, 3},
00105 {"xc2s100", "AMD 29LV081B 8MB", 0x04, 0xff, "PCI", FTYPE_BT, XilinxMagic, 0x010000, 4, 4, 2, ida_xc2s100, 2, 3},
00106 {"xc2s300e", "AMD 29LV081B 8MB", 0xff, 0xff, "PCI", FTYPE_LTX, XilinxMagic, 0x010000, 4, 4, 2, ida_xc2s100, -1, -1},
00107 {"xc3s1200e", "SPI W25P16", 0x05, 0xff, "PCIe", FTYPE_SPI, XilinxMagic, 0x100000, 32, 1, 0, ida_xc3s1200e, 0, -1},
00108 {"xc5vlx30t", "AMD S29GL064N", 0x06, 0xff, "PCIe", FTYPE_BT2, XilinxMagic, 0x010000, 32, 4, 3, ida_bt8, 3, -1},
00109 {"xc5vlx50t", "AMD S29GL064N", 0x07, 0xff, "PCIe", FTYPE_BT2, XilinxMagic, 0x010000, 32, 4, 3, ida_bt8, 3, -1},
00110 {"ep2sgx30d", "AMD S29GL128N", 0x15, 0xff, "PCIe", FTYPE_BT2, AlteraMagic, 0x010000, 32, 4, 3, ida_bt8, 3, -1},
00111 {"xc5vlx70t", "AMD S29GL064N", 0x08, 0xff, "PCIe", FTYPE_BT2, XilinxMagic, 0x010000, 64, 1, 0, ida_bt8, 0, -1},
00112 {"xc5vlx30t", "AMD S29GL064N (A)", 0x09, 0xff, "PCIe", FTYPE_BT2, XilinxMagic, 0x010000, 32, 4, 3, ida_bt8, 3, -1},
00113 {"xc6slx45", "AMD S29GL064N", 0x0a, 0xff, "PC104",FTYPE_BT2, XilinxMagic, 0x010000, 32, 4, 3, ida_bt8, 3, -1},
00114 {"ep2sgx30d", "AMD S29GL256P", 0x0b, 0xff, "PCIe", FTYPE_BT2, AlteraMagic, 0x020000, 32, 4, 3, ida_bt8, 3, -1},
00115 {"ep2agx45d", "AMD S29GL256S", 0x11, 0xff, "PCIe", FTYPE_F16, AlteraMagic, 0x010000, 64, 4, 3, ida_f16, 3, -1},
00116 {"5sgxma3k2f40c3", "AMD S29GL01GS", 0x0c, 0x03, "PCIe", FTYPE_F16, AlteraMagic, 0x010000, 512, 2, 1, ida_f16, 1, -1},
00117 {"5sgxma5k2f40c3", "AMD S29GL01GS", 0x0c, 0x04, "PCIe", FTYPE_F16, AlteraMagic, 0x010000, 512, 2, 1, ida_f16, 1, -1},
00118 {"5sgxma7k2f40c3", "AMD S29GL01GS", 0x0c, 0x02, "PCIe", FTYPE_F16, AlteraMagic, 0x010000, 512, 2, 1, ida_f16, 1, -1},
00119 {"5sgxma8k2h40c3n", "AMD S29GL01GS", 0x0c, 0x05, "PCIe", FTYPE_F16, AlteraMagic, 0x010000, 512, 2, 1, ida_f16, 1, -1},
00120 {"5sgxma7k1f40c2", "AMD S29GL01GS", 0x0c, 0x01, "PCIe", FTYPE_F16, AlteraMagic, 0x010000, 512, 2, 1, ida_f16, 1, -1},
00121 {"5sgxea2k1f40c2es", "AMD S29GL01GS", 0x0c, 0x00, "PCIe", FTYPE_F16, AlteraMagic, 0x010000, 512, 2, 1, ida_f16, 1, -1},
00122 {"5sgxma9k2h40c2", "AMD S29GL01GS", 0x0c, 0x06, "PCIe", FTYPE_F16, AlteraMagic, 0x010000, 512, 2, 1, ida_f16, 1, -1},
00123 {"5cgtfd5c5", "Micron N25Q064A13ESE40G", 0x0d, 0x01, "PCIe", FTYPE_MIC, Altera2Magic, 0x010000, 128, 1, 0, ida_micron, 0, -1},
00124 {"", "", 0x00, 0x00, "", 0, 0, 0, 0, 0, 0, NULL, -1, -1},
00125 };
00126
00127 static struct
00128 {
00129 u_int mid;
00130 u_int devid;
00131 u_int prom;
00132 } older_devices[] =
00133 {
00134 {
00135 0x1, 0x20, AMD_4013E
00136 },
00137 {
00138 0x1, 0x4f, AMD_4013XLA
00139 },
00140 {
00141 0x20, 0xe3, AMD_4013XLA
00142 },
00143 {
00144 0x00, 0x00, 0
00145 }
00146 };
00147
00148
00149 #define DEBUG1 EDTLIB_MSG_INFO_1
00150 #define DEBUG2 EDTLIB_MSG_INFO_2
00151
00152
00153
00154
00155 #define BT_EN_READ 0x8000
00156
00157
00158
00159
00160
00161 #define EN_HIGH_ADD 0x00800000
00162
00163 static int needswap = 0;
00164
00165 static void f16_print16(EdtDev *edt_p, u_int addr);
00166 static u_int f16_wr_cmd(EdtDev *edt_p, u_int cmd, u_int val, u_int wait_limit);
00167 static u_int f16_rd_cmd(EdtDev *edt_p, u_int cmd);
00168 static u_int f16_sector_erase(EdtDev *edt_p, u_int sector_addr);
00169 static int f16_wr_flash(EdtDev *edt_p, u_int addr, u_char *buffer, int nbytes);
00170 static void f16_rd_flash_block(EdtDev *edt_p, u_int addr, u_char *buffer, u_int byte_count);
00171 static int f16_reset(EdtDev *edt_p);
00172
00173 static void spi_read(EdtDev *edt_p, u_int addr, u_char *rbuf, int rcnt);
00174 static int spi_reset(EdtDev *edt_p);
00175 static void spiprim(EdtDev *edt_p, int opcode, u_int wbytes, u_int rbytes, u_char* wbuf, u_char* rbuf);
00176 static void spi_xwr(EdtDev *edt_p, int val);
00177 static int spi_xrd(EdtDev *edt_p);
00178 static void spi_xw(EdtDev *edt_p, u_int addr, u_int data);
00179 static u_int spi_xr(EdtDev *edt_p, u_int addr);
00180 static int spi_block_program(EdtDev *edt_p, int addr0, u_int size, u_char *spibuf, int verify_only);
00181 static void spi_print16(EdtDev * edt_p, u_int addr);
00182
00183 static void bt_write(EdtDev *edt_p,u_int addr, u_char val);
00184 static u_char bt_read(EdtDev *edt_p, u_int addr);
00185 static void bt_reset(EdtDev *edt_p);
00186 static u_char bt_readstat(EdtDev *edt_p);
00187
00188 static void bt2_reset(EdtDev *edt_p);
00189
00190 static void x_write(EdtDev *edt_p, u_int addr, u_char val);
00191 static u_char x_read(EdtDev *edt_p, u_int addr);
00192 static void x_reset(EdtDev *edt_p);
00193 static u_char x_readstat(EdtDev *edt_p);
00194 static void x_print16(EdtDev * edt_p, u_int addr);
00195
00196 static void tst_write(EdtDev * edt_p, uint_t desc, uint_t val);
00197 static uint_t tst_read(EdtDev * edt_p, uint_t desc);
00198 static void tst_pflash(EdtDev *edt_p, uint_t addr, uint_t val);
00199
00200
00201 static void program_info_str(EdtDev *edt_p, u_int addr, char *str, char *tag, u_int size, int ftype);
00202
00203
00210 Edt_prominfo *
00211 edt_get_prominfo(int promcode)
00212 {
00213 return (promcode <= edt_get_max_promcode()? &EPinfo[promcode] : &EPinfo[0]);
00214 }
00215
00222 const char *
00223 edt_get_fpga_mfg(EdtDev *edt_p)
00224 {
00225 u_short dmy;
00226 int promcode = edt_flash_prom_detect(edt_p, &dmy);
00227
00228 switch (EPinfo[promcode].magic)
00229 {
00230 case AlteraMagic:
00231 case Altera2Magic:
00232 return "Altera";
00233 break;
00234 case XilinxMagic:
00235 return "Xilinx";
00236 break;
00237
00238 default:
00239 return "";
00240 break;
00241 }
00242 }
00243
00244
00245
00246
00247
00248 int
00249 edt_get_max_promcode()
00250 {
00251 int i;
00252 for (i=0; i<PROMCODE_TBL_SIZE; i++)
00253 if (!EPinfo[i].fpga[0])
00254 return i-1;
00255 return PROMCODE_TBL_SIZE-1;
00256 }
00257
00258
00259
00260 #ifdef _KERNEL
00261
00262 static int
00263 edt_little_endian()
00264 {
00265 u_short test;
00266 u_char *byte_p;
00267
00268 byte_p = (u_char *) & test;
00269 *byte_p++ = 0x11;
00270 *byte_p = 0x22;
00271 if (test == 0x1122)
00272 {
00273 return (0);
00274 }
00275 else
00276 {
00277 return (1);
00278 }
00279 }
00280
00281 #endif
00282
00283 #define DQ7 0x80
00284 #define DQ5 0x20
00285 #define DQ3 0x08
00286 static int maxloops = 0;
00287
00288 static int debug_fast = 0;
00289 static int do_fast = 0;
00290 static int force_slow = 0;
00291
00292 int
00293 edt_flash_get_debug_fast()
00294 {
00295 return (debug_fast) ;
00296 }
00297 int
00298 edt_flash_set_debug_fast(int val)
00299 {
00300 (debug_fast = val) ;
00301 return val;
00302 }
00303
00304 int
00305 edt_flash_get_do_fast()
00306 {
00307 return (do_fast) ;
00308 }
00309 void
00310 edt_flash_set_do_fast(int val)
00311 {
00312 do_fast = val ;
00313 }
00314
00315 int
00316 edt_flash_get_force_slow()
00317 {
00318 return (force_slow) ;
00319 }
00320 void
00321 edt_flash_set_force_slow(int val)
00322 {
00323 force_slow = val ;
00324 }
00325
00326
00327
00328 volatile caddr_t dmyaddr = 0;
00329 volatile u_int *cfgaddr ;
00330 volatile u_int *tstaddr ;
00331
00332
00333 u_int
00334 swap32(u_int val)
00335 {
00336
00337 return (
00338 ((val & 0x000000ff) << 24)
00339 | ((val & 0x0000ff00) << 8)
00340 | ((val & 0x00ff0000) >> 8)
00341 | ((val & 0xff000000) >> 24));
00342 }
00343
00344
00345
00346
00347
00348 static void
00349 bt_print16(EdtDev * edt_p, u_int addr)
00350 {
00351 int i;
00352
00353 EDTPRINTF(edt_p,2,("%08x ", addr));
00354 for (i = 1; i < 16; i++)
00355 {
00356 EDTPRINTF(edt_p,2,(" %02x", bt_read(edt_p, addr)));
00357 addr++;
00358 }
00359 EDTPRINTF(edt_p,2,("\n"));
00360 }
00361
00362
00363 void
00364 edt_flash_print16(EdtDev * edt_p, u_int addr, int ftype)
00365 {
00366 switch(ftype)
00367 {
00368 case FTYPE_F16:
00369 f16_print16(edt_p, (u_int)addr);
00370 break;
00371
00372
00373
00374
00375
00376
00377
00378 case FTYPE_SPI:
00379 spi_print16(edt_p, (u_int)addr);
00380 break;
00381
00382 case FTYPE_BT:
00383 case FTYPE_BT2:
00384 bt_print16(edt_p, addr);
00385 break;
00386
00387 case FTYPE_X:
00388 x_print16(edt_p, addr);
00389 break;
00390
00391 default:
00392 break;
00393 }
00394 }
00395
00396 int
00397 edt_flash_get_ftype(EdtDev *edt_p)
00398 {
00399 u_short dmy;
00400 int promcode = edt_flash_prom_detect(edt_p, &dmy);
00401 Edt_prominfo *ep = edt_get_prominfo(promcode);
00402 return ep->ftype;
00403 }
00404
00405 u_char
00406 edt_flash_read8(EdtDev * edt_p, u_int addr, int ftype)
00407 {
00408 u_char val;
00409
00410 switch(ftype)
00411 {
00412 case FTYPE_F16:
00413 return 0;
00414 case FTYPE_MIC:
00415 return 0;
00416 case FTYPE_SPI:
00417 spi_read(edt_p, addr, &val, 1);
00418 return val;
00419 case FTYPE_BT:
00420 case FTYPE_BT2:
00421 return bt_read(edt_p, addr);
00422 case FTYPE_X:
00423 return x_read(edt_p, addr);
00424 }
00425
00426 return 0;
00427 }
00428
00429
00430
00431
00432 static int
00433 bt_sector_erase(EdtDev * edt_p, u_int sector, u_int sec_size)
00434 {
00435 u_int addr;
00436 int done = 0;
00437 u_int loops = 0;
00438 const u_int lots = 32768, too_many = 65535;
00439 u_char val;
00440
00441 addr = sector * sec_size;
00442 bt_write(edt_p, 0x5555, 0xaa);
00443 bt_write(edt_p, 0x2aaa, 0x55);
00444 bt_write(edt_p, 0x5555, 0x80);
00445 bt_write(edt_p, 0x5555, 0xaa);
00446 bt_write(edt_p, 0x2aaa, 0x55);
00447 bt_write(edt_p, addr, 0x30);
00448 done = 0;
00449 while (!done)
00450 {
00451 val = bt_read(edt_p, addr);
00452 loops++;
00453 if (val & DQ7)
00454 {
00455 done = 1;
00456 }
00457 else if (loops > lots)
00458 edt_delay(1);
00459
00460 else if (loops > too_many)
00461 {
00462 return -1;
00463 }
00464 }
00465 return 0;
00466 }
00467
00468
00469
00470
00471
00472
00473 static int
00474 bt2_sector_erase(EdtDev * edt_p, u_int sector, u_int sec_size)
00475 {
00476 u_int addr;
00477 int done = 0;
00478 int result = 0;
00479 u_char val;
00480 #ifndef _KERNEL
00481 double t= edt_timestamp();
00482 double elapsed;
00483
00484 addr = sector * sec_size;
00485 bt_write(edt_p, 0xaaa, 0xaa);
00486 bt_write(edt_p, 0x555, 0x55);
00487 bt_write(edt_p, 0xaaa, 0x80);
00488 bt_write(edt_p, 0xaaa, 0xaa);
00489 bt_write(edt_p, 0x555, 0x55);
00490 bt_write(edt_p, addr, 0x30);
00491 done = 0;
00492 while (!done)
00493 {
00494 edt_delay(1);
00495 val = bt_read(edt_p, addr);
00496 elapsed = edt_timestamp() - t;
00497
00498 if (val & DQ7)
00499 {
00500 done = 1;
00501 }
00502 if (elapsed > 3.0)
00503 {
00504 done = 1;
00505 result = 1;
00506 }
00507 }
00508 #endif
00509
00510 return(result);
00511 }
00512
00513 static int
00514 xsector_erase(EdtDev * edt_p, u_int sector, u_int sec_size)
00515 {
00516 u_int addr;
00517 int done = 0;
00518 int loops = 0;
00519 u_char val;
00520
00521 addr = sector * sec_size;
00522 x_write(edt_p, 0x5555, 0xaa);
00523 x_write(edt_p, 0x2aaa, 0x55);
00524 x_write(edt_p, 0x5555, 0x80);
00525 x_write(edt_p, 0x5555, 0xaa);
00526 x_write(edt_p, 0x2aaa, 0x55);
00527 x_write(edt_p, addr, 0x30);
00528 done = 0;
00529 while (!done)
00530 {
00531 val = x_read(edt_p, addr);
00532 loops++;
00533 if (val & DQ7)
00534 {
00535 done = 1;
00536 break;
00537 }
00538 }
00539 return 0;
00540 }
00541
00542
00543
00544
00545
00546
00547 static int
00548 bt_byte_program(EdtDev * edt_p, int ftype, u_int addr, u_char data)
00549 {
00550 u_char val;
00551 int done = 0;
00552 int loops = 0;
00553
00554 bt_write(edt_p, 0x5555, 0xaa);
00555 bt_write(edt_p, 0x2aaa, 0x55);
00556 bt_write(edt_p, 0x5555, 0xa0);
00557 bt_write(edt_p, addr, data);
00558 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00559
00560 while (!done)
00561 {
00562 val = (u_char) tst_read(edt_p, EDT_FLASHROM_DATA);
00563
00564 if (val == data)
00565 done = 1;
00566 if (loops > 1000)
00567 {
00568 EDTPRINTF(edt_p,1,("bt_byte_program: failed on %x data %x val %x\n",
00569 addr, data, val));
00570 bt_reset(edt_p );
00571 bt_write(edt_p, 0x555, 0xaa);
00572 bt_write(edt_p, 0x2aa, 0x55);
00573 bt_write(edt_p, 0x555, 0xa0);
00574 bt_write(edt_p, addr, data);
00575 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00576 loops = 0;
00577 }
00578 loops++;
00579 }
00580 if (loops > maxloops)
00581 {
00582 maxloops = loops;
00583 }
00584 if (done)
00585 return (0);
00586 else
00587 return (addr);
00588 }
00589
00590
00591
00592
00593
00594 static int
00595 bt2_byte_program(EdtDev * edt_p, int ftype, u_int addr, u_char data)
00596 {
00597 u_char val;
00598 int done = 0;
00599 int loops = 0;
00600 int failures = 0;
00601
00602 bt_write(edt_p, 0xaaa, 0xaa);
00603 bt_write(edt_p, 0x555, 0x55);
00604 bt_write(edt_p, 0xaaa, 0xa0);
00605 bt_write(edt_p, addr, data);
00606 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00607
00608 while (!done)
00609 {
00610 val = (u_char) tst_read(edt_p, EDT_FLASHROM_DATA);
00611
00612 if (val == data)
00613 done = 1;
00614 if (loops > 1000)
00615 {
00616 bt2_reset(edt_p);
00617 bt_write(edt_p, 0xaaa, 0xaa);
00618 bt_write(edt_p, 0x555, 0x55);
00619 bt_write(edt_p, 0xaaa, 0xa0);
00620 bt_write(edt_p, addr, data);
00621 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00622 loops = 0;
00623 failures++;
00624 }
00625 loops++;
00626
00627 if (failures > 5)
00628 {
00629 EDTPRINTF(edt_p,0,("bt2_byte_program: failed on %x data %x val %x\n", addr, data, val));
00630 return(1);
00631 }
00632 }
00633 if (loops > maxloops)
00634 {
00635 maxloops = loops;
00636 }
00637 if (done)
00638 return (0);
00639 else
00640 return (addr);
00641 }
00642
00643
00644
00645
00646
00647
00648
00649 static int
00650 xbyte_program(EdtDev * edt_p, u_int addr, u_char data)
00651 {
00652 u_char val;
00653 int done = 0;
00654 int loops = 0;
00655
00656 tst_pflash(edt_p, addr, data) ;
00657 while (!done)
00658 {
00659 loops++;
00660 val = x_read(edt_p, addr);
00661 if (val == data)
00662 done = 1;
00663 if (loops > 100)
00664 {
00665 EDTPRINTF(edt_p,1,("xbyte_program: failed on %x data %x val %x\n",
00666 addr, data, val));
00667 loops = 0;
00668 }
00669 }
00670 if (loops > maxloops)
00671 {
00672 if (loops > 10)
00673 EDTPRINTF(edt_p,1,("maxloops %x %d\n", addr, loops));
00674 maxloops = loops;
00675 }
00676 if (done)
00677 return (0);
00678 else
00679 return (addr);
00680 }
00681
00682
00683
00684
00685
00686 void
00687 edt_flash_byte_program(EdtDev *edt_p, u_int addr, u_char data, int ftype)
00688 {
00689 u_char buf[2];
00690
00691 switch(ftype)
00692 {
00693 case FTYPE_F16:
00694
00695 break;
00696
00697 case FTYPE_MIC:
00698
00699 break;
00700
00701 case FTYPE_SPI:
00702 buf[0] = data;
00703 edt_flash_block_program(edt_p, addr, buf, 1, ftype);
00704
00705 break;
00706 case FTYPE_BT:
00707 bt_byte_program(edt_p, ftype, addr, data);
00708 break;
00709
00710 case FTYPE_BT2:
00711 bt2_byte_program(edt_p, ftype, addr, data);
00712 break;
00713
00714 case FTYPE_X:
00715 xbyte_program(edt_p, addr, data);
00716 break;
00717 }
00718 }
00719
00720 u_int
00721 edt_flash_writesize(int ftype)
00722 {
00723 switch(ftype)
00724 {
00725 case FTYPE_F16:
00726 return 2;
00727 default:
00728 return 1;
00729 }
00730 }
00731
00732
00733
00734
00735 void
00736 edt_flash_block_program(EdtDev *edt_p, u_int addr, u_char *data, u_int nbytes, int ftype)
00737 {
00738 int i;
00739 u_char *dp = data;
00740
00741 switch(ftype)
00742 {
00743 case FTYPE_MIC:
00744 mic_page_program(edt_p, addr, data, nbytes);
00745 break;
00746
00747 case FTYPE_F16:
00748 f16_wr_flash(edt_p, addr, data, nbytes);
00749 break;
00750
00751 case FTYPE_SPI:
00752 spi_block_program(edt_p, addr, nbytes, data, 0);
00753 break;
00754
00755 case FTYPE_BT:
00756 for (i=0; (u_int)i<nbytes; i++)
00757 bt_byte_program(edt_p, ftype, addr++, *(dp++));
00758 break;
00759 case FTYPE_BT2:
00760 for (i=0; (u_int)i<nbytes; i++)
00761 bt2_byte_program(edt_p, ftype, addr++, *(dp++));
00762 break;
00763 case FTYPE_X:
00764 for (i=0; (u_int)i<nbytes; i++)
00765 xbyte_program(edt_p, addr++, *(dp++));
00766 break;
00767
00768 }
00769 }
00770
00771
00772
00773
00774 void
00775 edt_flash_verify(EdtDev *edt_p, u_int addr, u_char *data, int nbytes, int ftype)
00776 {
00777 switch(ftype)
00778 {
00779 case FTYPE_SPI:
00780 spi_block_program(edt_p, addr, nbytes, data, 1);
00781 break;
00782 default:
00783 EDTPRINTF(edt_p,1,("Oops! Can't verify type %d FPGA with edt_flash_verify (pciload internal)\n", ftype));
00784 break;
00785 }
00786 }
00787
00788
00789
00811 void
00812 edt_get_esn(EdtDev *edt_p, char *esn)
00813 {
00814 char dmy[256];
00815 edt_get_sns(edt_p, esn, dmy);
00816 }
00817
00833 void
00834 edt_get_osn(EdtDev *edt_p, char *osn)
00835 {
00836 char dmy[256];
00837 edt_get_sns(edt_p, dmy, osn);
00838 }
00839
00840 static int
00841 isdigit_str(char *s)
00842 {
00843 u_int i;
00844
00845 for (i=0; i<strlen(s); i++)
00846 if ((s[i]) < '0' || s[i] > '9')
00847 return 0;
00848 return 1;
00849 }
00850
00851
00867 int
00868 edt_flash_get_fname(EdtDev *edt_p, char *name)
00869 {
00870 int promcode;
00871 char *p;
00872 char *idstr;
00873 EdtPromData pdata;
00874 Edt_prominfo *ep;
00875 u_short stat;
00876
00877 promcode = edt_flash_prom_detect(edt_p, &stat);
00878
00879 ep = edt_get_prominfo(promcode);
00880
00881 edt_read_prom_data(edt_p, promcode, ep->defaultseg,
00882 &pdata);
00883
00884 idstr = pdata.id;
00885
00886 #if defined ( __APPLE__) && defined(_KERNEL)
00887 if ((p = edt_strrchr(idstr, '.')) != NULL)
00888 *p = '\0' ;
00889
00890 if ((p = edt_strrchr(idstr, '_')) != NULL)
00891 {
00892 if (( *(p + 1) == '3' || *(p + 1) == '5' ) && ( *(p + 2) == 'v' ))
00893 *p = '\0' ;
00894 }
00895
00896 if ((p = edt_strrchr(idstr, '-')) != NULL)
00897 {
00898 *p = '\0' ;
00899 }
00900 #else
00901 if ((p = strrchr(idstr, '.')) != NULL)
00902 *p = '\0' ;
00903
00904 if ((p = strrchr(idstr, '_')) != NULL)
00905 {
00906 if (( *(p + 1) == '3' || *(p + 1) == '5' ) && ( *(p + 2) == 'v' ))
00907 *p = '\0' ;
00908 }
00909
00910 if ((p = strrchr(idstr, '-')) != NULL)
00911 {
00912 *p = '\0' ;
00913 }
00914
00915 #endif
00916 strcpy(name, idstr);
00917
00918 return 0;
00919 }
00920
00937 int
00938 edt_flash_get_fname_auto(EdtDev *edt_p, char *name)
00939 {
00940 Edt_prominfo *ep;
00941 char *p;
00942 char *idstr;
00943 EdtPromData pdata;
00944 int promcode;
00945 u_short stat;
00946
00947 promcode = edt_flash_prom_detect(edt_p, &stat);
00948
00949 ep = edt_get_prominfo(promcode);
00950 edt_read_prom_data(edt_p, promcode, ep->defaultseg,
00951 &pdata);
00952
00953 idstr = pdata.id;
00954
00955
00956 #if defined( __APPLE__) && defined(_KERNEL)
00957 if ((p = edt_strrchr(idstr, '.')) != NULL)
00958 #else
00959 if ((p = strrchr(idstr, '.')) != NULL)
00960 #endif
00961 {
00962
00963 *p = '\0' ;
00964
00965
00966 if ((strlen(idstr) > 3) && ((strcmp(p-3, "_3v") == 0) || (strcmp(p-3, "_5v") == 0)))
00967 *(p-3) = '\0' ;
00968
00969 }
00970
00971
00972 #if defined(__APPLE__) && defined(_KERNEL)
00973 if ((p =edt_strrchr(idstr, '-')) != NULL)
00974 #else
00975 if ((p = strrchr(idstr, '-')) != NULL)
00976 #endif
00977 *p = '\0';
00978
00979
00980 strcpy(name, idstr);
00981
00982 return 0;
00983 }
00984
00985
01010 void
01011 edt_get_sns_sector(EdtDev *edt_p, char *esn, char *osn, int sector)
01012 {
01013 int promcode;
01014 u_short stat;
01015 EdtPromData pdata;
01016
01017 promcode = edt_flash_prom_detect(edt_p, &stat);
01018
01019 if ((promcode == PROM_UNKN) || (promcode > edt_get_max_promcode()))
01020 {
01021 esn[0] = 0;
01022 osn[0] = 0;
01023 }
01024 else
01025 {
01026 edt_read_prom_data(edt_p, promcode, sector, &pdata);
01027 strcpy(esn, pdata.esn);
01028 strcpy(osn, pdata.osn);
01029 }
01030 }
01031
01032 void
01033 edt_get_sns(EdtDev *edt_p, char *esn, char *osn)
01034 {
01035 u_short stat;
01036 int promcode = edt_flash_prom_detect(edt_p, &stat);
01037 Edt_prominfo *ep = edt_get_prominfo(promcode);
01038
01039
01040 edt_get_sns_sector(edt_p, esn, osn, ep->defaultseg);
01041 }
01042
01043 int
01044 edt_flash_is_protected(EdtDev *edt_p)
01045 {
01046 if (edt_flash_get_ftype(edt_p) == FTYPE_MIC)
01047 {
01048 if (edt_mic_is_protected(edt_p))
01049 return 1;
01050 }
01051 else
01052 {
01053 u_short stat;
01054 int promcode = edt_flash_prom_detect(edt_p, &stat);
01055
01056 if (((stat & EDT_ROM_JUMPER) == 0) && (promcode < AMD_XC2S150))
01057 return 1;
01058 }
01059 return 0;
01060 }
01061
01062
01063
01064 #define SPI_WREN 0x06
01065 #define SPI_WRDI 0x04
01066 #define SPI_RDSR 0x05
01067 #define SPI_WRSR 0x01
01068 #define SPI_READ 0x03
01069 #define SPI_FREAD 0x0B
01070 #define SPI_PP 0x02
01071 #define SPI_SE 0xD8
01072 #define SPI_BE 0xC7
01073 #define SPI_DP 0xB9
01074 #define SPI_RES 0xAB
01075
01076 #define SPI_REG 0x02000084
01077 #define SPI_EN 0x8000
01078 #define SPI_S 0x2000
01079 #define SPI_D 0x1000
01080 #define SPI_Q 0x0200
01081
01082
01083
01084 u_char Spi_wbufa[260];
01085 u_char* Spi_wbuf=Spi_wbufa+3;
01086 u_char Spi_rbuf[260];
01087 volatile caddr_t Spi_mapaddr = 0;
01088
01089
01090
01091 static void
01092 spi_xw(EdtDev *edt_p, u_int addr, u_int data)
01093 {
01094 u_int dmy;
01095 edt_set(edt_p, addr, data) ;
01096 dmy = edt_get(edt_p, 0x04000080) ;
01097 }
01098
01099 static u_int
01100 spi_xr(EdtDev *edt_p, u_int addr)
01101 {
01102 return(edt_get(edt_p, addr)) ;
01103 }
01104
01105
01106 static void
01107 spi_xwr(EdtDev *edt_p, int val)
01108 {
01109 int d;
01110 d = SPI_EN | val;
01111 spi_xw(edt_p, SPI_REG, d);
01112 }
01113
01114 static int
01115 spi_xrd(EdtDev *edt_p)
01116 {
01117 int v;
01118 v = spi_xr(edt_p, 0x02000084);
01119 if (v & SPI_Q) return(1);
01120 else return(0);
01121 }
01122
01123
01124 static void
01125 spiprim(EdtDev *edt_p, int opcode, u_int wbytes, u_int rbytes, u_char* wbuf, u_char* rbuf)
01126 {
01127 int b, cdat;
01128 u_int c;
01129
01130
01131
01132 cdat = opcode;
01133 for (b=0; b<8; b++) {
01134 if (cdat & 0x80) {
01135 spi_xwr(edt_p, SPI_D);
01136 } else {
01137 spi_xwr(edt_p, 0);
01138 }
01139 cdat <<= 1;
01140 }
01141
01142 for (c=0; c<wbytes; c++) {
01143 cdat = wbuf[c];
01144 for (b=0; b<8; b++) {
01145 if (cdat & 0x80) {
01146 spi_xwr(edt_p, SPI_D);
01147 } else {
01148 spi_xwr(edt_p, 0);
01149 }
01150 cdat <<= 1;
01151 }
01152 }
01153
01154 for (c=0; c<rbytes; c++) {
01155 cdat = 0;
01156 for (b=0; b<8; b++) {
01157 cdat <<= 1;
01158 if (spi_xrd(edt_p) & 1)
01159 cdat |= 1;
01160 if ((b!=7) || (c!=(rbytes-1))) {
01161 spi_xwr(edt_p, 0);
01162 }
01163 }
01164 rbuf[c] = (char) cdat;
01165 }
01166
01167 spi_xwr(edt_p, SPI_S);
01168 }
01169
01170
01171
01172
01173 static int
01174 spi_reset(EdtDev *edt_p)
01175 {
01176 u_char rval;
01177 char *magic = "555";
01178
01179 spiprim(edt_p, SPI_RES, 3, 1, (u_char *)magic, &rval);
01180
01181 return(rval&0xff);
01182 }
01183
01184
01185
01186
01187 static void
01188 spi_read(EdtDev *edt_p, u_int addr, u_char *rbuf, int rcnt)
01189 {
01190 if ((rcnt<1) || (rcnt > 256)) {
01191 EDTPRINTF(edt_p,1,("Error, bad spi_read() rcnt of %d\n", rcnt));
01192 return;
01193 }
01194 Spi_wbufa[0]=addr>>16;
01195 Spi_wbufa[1]=addr>>8;
01196 Spi_wbufa[2]=(char) addr;
01197 Spi_wbufa[3]=0;
01198
01199 spiprim(edt_p, SPI_FREAD, 4, rcnt, Spi_wbufa, rbuf);
01200 }
01201
01202 static int
01203 spi_write(EdtDev *edt_p, u_int addr, int wcnt)
01204 {
01205 int statcnt;
01206
01207 if ((wcnt<1) || (wcnt>256)) {
01208 EDTPRINTF(edt_p,1,("Error, bad spi_write() wcnt of %d\n", wcnt));
01209 return -1;
01210 }
01211 spiprim(edt_p, SPI_WREN, 0, 0, NULL, NULL);
01212
01213 Spi_wbufa[0]=addr>>16;
01214 Spi_wbufa[1]=addr>>8;
01215 Spi_wbufa[2]=(char) addr;
01216
01217 spiprim(edt_p, SPI_PP, 3+wcnt, 0, Spi_wbufa, NULL);
01218
01219 statcnt=0;
01220 do {
01221 spiprim(edt_p, SPI_RDSR, 0, 1, NULL, Spi_rbuf);
01222 statcnt++;
01223 } while ((Spi_rbuf[0] & 1) == 1);
01224
01225 return 0;
01226 }
01227
01228
01229 #define SPI_TOO_MANY 100000
01230
01231 static int
01232 spi_sector_erase(EdtDev *edt_p, u_int addr)
01233 {
01234 int statcnt;
01235
01236 spiprim(edt_p, SPI_WREN, 0, 0, NULL, NULL);
01237 Spi_wbufa[0]=addr>>16;
01238 Spi_wbufa[1]=addr>>8;
01239 Spi_wbufa[2]=(u_char) addr;
01240 spiprim(edt_p, SPI_SE, 3, 0, Spi_wbufa, NULL);
01241
01242 statcnt=0;
01243 do {
01244 spiprim(edt_p, SPI_RDSR, 0, 1, NULL, Spi_rbuf);
01245 if (statcnt++ > SPI_TOO_MANY)
01246 {
01247 EDTPRINTF(edt_p,1,("erase spun for too long, bailing out\n"));
01248 return(-1);
01249 }
01250 } while ((Spi_rbuf[0] & 1) == 1);
01251
01252
01253 return(0);
01254 }
01255
01256
01257
01258
01259 static void
01260 spi_print16(EdtDev * edt_p, u_int addr)
01261 {
01262 int i;
01263 u_char val;
01264
01265 EDTPRINTF(edt_p,2,("%08x ", addr));
01266 for (i = 1; i < 16; i++)
01267 {
01268 spi_read(edt_p, (u_int)addr, &val, 1);
01269 EDTPRINTF(edt_p,2,(" %02x", val));
01270 addr++;
01271 }
01272 EDTPRINTF(edt_p,2,("\n"));
01273 }
01274
01275
01276
01277
01278
01279 #define F16_FLASH_BANK 3
01280
01281 #define F16_REG0 0x30000000
01282 #define F16_P4_CMDDATA_REG 0x04000084
01283 #define F16_P4_DATA_REG 0x04000088
01284
01285 #define F16_CMD_NOP 0x0
01286 #define F16_CMD_LD_ADDR_HI 0x1
01287 #define F16_CMD_LD_CTRL_REG 0x2
01288 #define F16_CMD_LD_ADDR_LO 0x3
01289 #define F16_CMD_FW_ADDR_2AA 0x4
01290 #define F16_CMD_FW_ADDR_555 0x5
01291 #define F16_CMD_FW 0x6
01292 #define F16_CMD_FW_INC_ADDR 0x7
01293 #define F16_CMD_RD_PAL_ID 0x8
01294 #define F16_CMD_RD_PAL_VER 0x9
01295 #define F16_CMD_RD_ADDR_LO 0xA
01296 #define F16_CMD_RD_ADDR_HI 0xB
01297 #define F16_CMD_RD_CTRL_REG 0xC
01298 #define F16_CMD_RD_FLASH 0xD
01299
01300 #define F16_CMD_IDLE 0xF
01301
01302 #define F16_FL_BUSY 0x80
01303 #define F16_FL_RESET 0x80
01304 #define F16_FL_WBUF_SIZE 0x10000
01305 #define F16_FL_RBUF_SIZE 4096
01306
01307 static u_int
01308 f16_wr_cmd(EdtDev *edt_p, u_int cmd, u_int val, u_int wait_limit)
01309 {
01310 u_int waitcount = 0, loopwait = 0 ;
01311 u_int id_reg, cmd_data ;
01312
01313 cmd_data = (val & 0xffff) | ((cmd << 16) & 0x0f0000) ;
01314
01315 edt_set(edt_p, F16_P4_CMDDATA_REG, cmd_data) ;
01316
01317 cmd_data |= 0xf0000 ;
01318 edt_set(edt_p,F16_P4_CMDDATA_REG, cmd_data) ;
01319 cmd_data = (cmd_data & 0xffff) | ((F16_CMD_RD_PAL_ID <<16) & 0xf0000) ;
01320
01321 if (cmd == F16_CMD_FW)
01322 {
01323 edt_set(edt_p,F16_P4_CMDDATA_REG, cmd_data) ;
01324 if (wait_limit != 0)
01325 {
01326 while(1)
01327 {
01328 id_reg = edt_get(edt_p,F16_P4_CMDDATA_REG) ;
01329 if ((id_reg & F16_FL_BUSY) != 0) break ;
01330
01331
01332
01333
01334 if (loopwait++ > wait_limit)
01335 {
01336 edt_delay(1) ;
01337 ++waitcount;
01338 }
01339
01340 if (waitcount > wait_limit)
01341 {
01342 edt_set(edt_p,F16_P4_CMDDATA_REG, F16_CMD_IDLE << 16) ;
01343 EDTPRINTF(edt_p, 1, ("Timeout: ID_REG = %4.4X; CMD = %X; DATA = %4.4X; count = %d\n",id_reg,cmd,val,waitcount)) ;
01344 return waitcount ;
01345 }
01346
01347 }
01348 }
01349 }
01350 edt_set(edt_p,F16_P4_CMDDATA_REG, F16_CMD_IDLE << 16) ;
01351 return 0 ;
01352 }
01353
01354
01355 static u_int
01356 f16_rd_cmd(EdtDev *edt_p, u_int cmd)
01357 {
01358 int rdata ;
01359
01360 edt_set(edt_p,F16_P4_CMDDATA_REG, cmd << 16) ;
01361
01362 rdata = edt_get(edt_p,F16_P4_CMDDATA_REG) & 0xffff ;
01363 edt_set(edt_p,F16_P4_CMDDATA_REG, F16_CMD_IDLE << 16) ;
01364 return rdata ;
01365 }
01366
01367
01368 static u_int
01369 f16_sector_erase(EdtDev *edt_p, u_int sector_addr)
01370 {
01371 int rdata ;
01372
01373
01374 f16_wr_cmd(edt_p, F16_CMD_LD_ADDR_LO, (sector_addr & 0xffff), 0) ;
01375 f16_wr_cmd(edt_p, F16_CMD_LD_ADDR_HI, ((sector_addr >> 16) & 0xffff), 0) ;
01376
01377
01378 f16_wr_cmd(edt_p, F16_CMD_FW_ADDR_555, 0x00AA, 0) ;
01379 f16_wr_cmd(edt_p, F16_CMD_FW_ADDR_2AA, 0x0055, 0) ;
01380
01381 f16_wr_cmd(edt_p, F16_CMD_FW_ADDR_555, 0x0080, 0) ;
01382
01383 f16_wr_cmd(edt_p, F16_CMD_FW_ADDR_555, 0x00AA, 0) ;
01384
01385 f16_wr_cmd(edt_p, F16_CMD_FW_ADDR_2AA, 0x0055, 0) ;
01386
01387 rdata = f16_wr_cmd(edt_p, F16_CMD_FW, 0x0030, 1200);
01388 return rdata;
01389 }
01390
01391
01392 static int
01393 f16_wr_flash(EdtDev *edt_p, u_int addr, u_char *buffer, int nbytes)
01394 {
01395 int wr_data, sector_addr, pgm_count, max_pgm_count, i ;
01396
01397 if (nbytes == 0)
01398 {
01399 nbytes = (int)strlen((char *)buffer) ;
01400 }
01401
01402 while (nbytes > 0)
01403 {
01404 sector_addr = addr ;
01405 max_pgm_count = ((addr + 0x100) & 0xffffff00) - addr ;
01406 if (max_pgm_count > ((nbytes + 1)/2)) pgm_count = ((nbytes + 1)/2) - 1 ;
01407 else pgm_count = max_pgm_count - 1 ;
01408 f16_wr_cmd(edt_p, F16_CMD_LD_ADDR_LO, (sector_addr & 0xffff), 0) ;
01409 f16_wr_cmd(edt_p, F16_CMD_LD_ADDR_HI, ((sector_addr >> 16) & 0xffff), 0) ;
01410
01411
01412 f16_wr_cmd(edt_p, F16_CMD_FW_ADDR_555, 0x00AA, 0) ;
01413 f16_wr_cmd(edt_p, F16_CMD_FW_ADDR_2AA, 0x0055, 0) ;
01414 f16_wr_cmd(edt_p, F16_CMD_FW, 0x0025, 0) ;
01415 f16_wr_cmd(edt_p, F16_CMD_FW, pgm_count, 0) ;
01416
01417 do
01418 {
01419 wr_data = (u_int)*(buffer++) ;
01420 wr_data |= (u_int)*(buffer++) << 8 ;
01421 f16_wr_cmd(edt_p, F16_CMD_FW_INC_ADDR, wr_data, 0) ;
01422 sector_addr++ ;
01423 nbytes -= 2 ;
01424 if (nbytes <= 0) break ;
01425
01426 } while ((sector_addr & 0x000000ff) != 0) ;
01427
01428 f16_wr_cmd(edt_p, F16_CMD_LD_ADDR_LO, (addr & 0xffff), 0) ;
01429 f16_wr_cmd(edt_p, F16_CMD_LD_ADDR_HI, ((addr >> 16) & 0xffff), 0) ;
01430
01431
01432 i = f16_wr_cmd(edt_p, F16_CMD_FW, 0x0029, 200) ;
01433 if (i > 200)
01434 {
01435 EDTPRINTF(edt_p, 0, ("TIMEOUT: Programming failure at address %8.8X; code = %d\n",sector_addr, i)) ;
01436 return -1;
01437 }
01438
01439 addr = sector_addr ;
01440 }
01441 return 0;
01442 }
01443
01444
01445 static void
01446 f16_rd_flash_block(EdtDev *edt_p, u_int addr, u_char *buffer, u_int byte_count)
01447 {
01448 u_int i, rd_data ;
01449
01450 f16_wr_cmd(edt_p, F16_CMD_LD_ADDR_HI, ((addr >> 16) & 0xffff), 0) ;
01451
01452 for (i = 0; i < byte_count; i += 2)
01453 {
01454 f16_wr_cmd(edt_p, F16_CMD_LD_ADDR_LO, (addr & 0xffff), 0) ;
01455 rd_data = edt_get(edt_p,F16_P4_CMDDATA_REG) ;
01456 *(buffer + i) = (u_char)(rd_data & 0xff) ;
01457 *(buffer + i + 1) = (u_char)((rd_data >> 8) & 0xff) ;
01458 if (++addr & 0xffff0000) f16_wr_cmd(edt_p, F16_CMD_LD_ADDR_HI, ((addr >> 16) & 0xffff), 0) ;
01459 }
01460 }
01461
01462
01463
01464 static int
01465 f16_reset(EdtDev *edt_p)
01466 {
01467
01468 f16_wr_cmd(edt_p, F16_CMD_LD_CTRL_REG, F16_FL_RESET, 0) ;
01469 edt_delay(100) ;
01470 f16_wr_cmd(edt_p, F16_CMD_LD_CTRL_REG, 0, 0) ;
01471 edt_delay(100) ;
01472 return 0;
01473 }
01474
01475
01476
01477
01478 static void
01479 f16_print16(EdtDev * edt_p, u_int addr)
01480 {
01481 int i;
01482 u_char buf[16];
01483
01484 EDTPRINTF(edt_p,2,("%08x ", addr));
01485 f16_rd_flash_block(edt_p, addr, buf, 16);
01486 for (i = 1; i < 16; i++)
01487 {
01488 EDTPRINTF(edt_p,2,(" %02x", buf[i]));
01489 addr++;
01490 }
01491 EDTPRINTF(edt_p,2,("\n"));
01492 }
01493
01494
01495
01496
01497
01498 static int
01499 spi_block_program(EdtDev *edt_p, int addr0, u_int size, u_char *spibuf, int verify_only)
01500 {
01501 int i, n, errorcnt, val, first, last;
01502 u_int addr, bcnt;
01503
01504
01505 for (i=0; i<5; i++)
01506 {
01507 if ((val = spi_reset(edt_p)) != 0)
01508 break;
01509 (void)edt_delay(100);
01510 }
01511
01512 if ((val != 0x11) && (val != 0x13) && (val != 0x14))
01513 {
01514 EDTPRINTF(edt_p,0,(" Error, did not detect SPI flash device, \n"));
01515 EDTPRINTF(edt_p,0,(" spi_reset() returned 0x%02x, not 0x11/0x13/0x14\n", val));
01516 return -1;
01517 }
01518
01519 if (!verify_only)
01520 {
01521 first = (addr0&0xff0000)>>16;
01522 last = ((addr0+size)&0xff0000)>>16;
01523 EDTPRINTF(edt_p,0,(" First sector is %d, last is %d, erasing", first, last));
01524
01525 for (n=first; n<=last; n++)
01526 {
01527 spi_sector_erase(edt_p, n<<16);
01528 EDTPRINTF(edt_p,0,("."));
01529 }
01530 EDTPRINTF(edt_p,0,("\n"));
01531
01532 EDTPRINTF(edt_p,0,(" Writing 0x%x bytes to spiflash at 0x%x.",size,addr0));
01533 bcnt=0; addr=addr0;
01534 while (bcnt<size)
01535 {
01536 n=0;
01537 while (bcnt<size)
01538 {
01539 if ((n!=0) && (((addr+n)&0xff)==0)) break;
01540 #ifndef _KERNEL
01541 if (!(bcnt % 10000)) {printf("."); fflush(stdout); }
01542 #endif
01543 Spi_wbuf[n] = spibuf[bcnt];
01544 n = n+1;
01545 bcnt = bcnt+1;
01546 }
01547 if (n>0) spi_write(edt_p, addr, n);
01548 addr = addr + n;
01549 }
01550 }
01551
01552 EDTPRINTF(edt_p,0,("\n"));
01553 EDTPRINTF(edt_p,0,(" Verifying."));
01554 bcnt=0; addr=addr0; errorcnt=0;
01555 while (bcnt<size)
01556 {
01557 spi_read(edt_p, addr, Spi_rbuf, 256);
01558 n=0;
01559 while (bcnt<size) {
01560 if ((n!=0) && (((addr+n)&0xff)==0)) break;
01561 #ifndef _KERNEL
01562 if (!(bcnt % 10000)) {printf("."); fflush(stdout); }
01563 #endif
01564 if ((Spi_rbuf[n]&0xff) != (spibuf[bcnt]&0xff)) {
01565 if (errorcnt++ <= 10) {
01566 EDTPRINTF(edt_p,0,("Error at 0x%x: wrote:%02x, read:%02x\n",
01567 addr0+bcnt, spibuf[bcnt], Spi_rbuf[n]));
01568 }
01569 }
01570 n = n+1;
01571 bcnt = bcnt+1;
01572 }
01573 addr = addr + n;
01574 }
01575 if (errorcnt)
01576 EDTPRINTF(edt_p,0,(" Saw %d errors\n", errorcnt));
01577
01578 if (!errorcnt)
01579 EDTPRINTF(edt_p,0,("\nno errors\n"));
01580
01581 return 0;
01582 }
01583
01584
01585
01586
01587 static void
01588 x_write(EdtDev * edt_p, u_int addr, u_char val)
01589 {
01590
01591 (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01592 tst_write(edt_p, EDT_FLASHROM_DATA, val) ;
01593 (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01594 tst_write(edt_p, EDT_FLASHROM_ADDR, EN_HIGH_ADD | addr | EDT_WRITECMD) ;
01595 }
01596
01597
01598 static u_char
01599 x_read(EdtDev * edt_p, u_int addr)
01600 {
01601
01602 (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01603 tst_write(edt_p, EDT_FLASHROM_ADDR, EN_HIGH_ADD | addr) ;
01604 (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01605 return (u_char) (tst_read(edt_p, EDT_FLASHROM_DATA));
01606
01607 }
01608
01609
01610
01611 static void
01612 x_reset(EdtDev * edt_p)
01613 {
01614 x_write(edt_p, 0x5555, 0xaa);
01615 x_write(edt_p, 0x2aaa, 0x55);
01616 x_write(edt_p, 0x5555, 0xf0);
01617 }
01618
01619
01620
01621
01622
01623 static void
01624 bt_write(EdtDev * edt_p, u_int addr, u_char val)
01625 {
01626
01627
01628 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01629
01630 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_LO | (addr & 0xff));
01631 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01632
01633 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_MID | ((addr >> 8) & 0xff));
01634 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01635
01636
01637 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_HI | ((addr >> 16) & 0xff));
01638 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01639
01640 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_ROM | (val & 0xff));
01641 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01642 }
01643
01644
01645
01646
01647 static void
01648 bt_reset(EdtDev * edt_p)
01649 {
01650 bt_write(edt_p, 0x555, 0xaa);
01651 bt_write(edt_p, 0x2aa, 0x55);
01652 bt_write(edt_p, 0x555, 0xf0);
01653 }
01654
01655
01656 static void
01657 bt2_reset(EdtDev * edt_p)
01658 {
01659 bt_write(edt_p, 0x0, 0xf0);
01660 }
01661
01662
01663 static u_char
01664 x_readstat(EdtDev * edt_p)
01665 {
01666 uint_t stat;
01667 uint_t rdval;
01668
01669
01670
01671
01672
01673 tst_write(edt_p, EDT_FLASHROM_ADDR, 0);
01674 rdval = tst_read(edt_p, EDT_FLASHROM_DATA);
01675 stat = (u_short)((rdval >> 8) & 0xff);
01676 return (u_char)stat;
01677 }
01678
01679
01680
01681
01682 static void
01683 x_print16(EdtDev * edt_p, u_int addr)
01684 {
01685 int i;
01686
01687 EDTPRINTF(edt_p,2,("%08x ", addr));
01688 for (i = 1; i < 16; i++)
01689 {
01690 EDTPRINTF(edt_p,2,(" %02x", x_read(edt_p, addr)));
01691 addr++;
01692 }
01693 EDTPRINTF(edt_p,2,("\n"));
01694 }
01695
01696
01697
01698
01699 static u_char
01700 bt_read(EdtDev * edt_p, u_int addr)
01701 {
01702 u_char stat;
01703
01704
01705
01706 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01707
01708 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_LO | (addr & 0xff));
01709
01710 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01711
01712 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_MID | ((addr >> 8) & 0xff));
01713
01714 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01715
01716 tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_HI | ((addr >> 16) & 0xff));
01717
01718 tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
01719
01720
01721 stat = (u_short)tst_read(edt_p, EDT_FLASHROM_DATA) | 0xff00;
01722
01723 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01724 return (stat);
01725 }
01726
01727
01728
01729
01730 static u_char
01731 bt_readstat(EdtDev * edt_p)
01732 {
01733 u_char stat;
01734 uint_t rdval;
01735
01736
01737
01738
01739
01740 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01741 tst_write(edt_p, EDT_FLASHROM_DATA, BT_EN_READ | BT_READ);
01742 rdval = tst_read(edt_p, EDT_FLASHROM_DATA);
01743 stat = rdval;
01744
01745 tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01746 return (stat);
01747 }
01748
01749
01750
01751 void
01752 edt_flash_reset(EdtDev *edt_p, int ftype)
01753 {
01754 switch(ftype)
01755 {
01756 case FTYPE_F16:
01757 f16_reset(edt_p);
01758 break;
01759 case FTYPE_MIC:
01760 mic_reset(edt_p);
01761 break;
01762 case FTYPE_SPI:
01763 spi_reset(edt_p);
01764 break;
01765 case FTYPE_BT:
01766 bt_reset(edt_p);
01767 break;
01768 case FTYPE_BT2:
01769 bt2_reset(edt_p);
01770 break;
01771 case FTYPE_X:
01772 x_reset(edt_p) ;
01773 break;
01774 default:
01775 break;
01776 }
01777 }
01778
01779
01780
01781
01782
01783
01784 u_int
01785 edt_get_fpga_sectorsize(EdtDev *edt_p, Edt_prominfo *ep)
01786 {
01787 u_int tmpval;
01788
01789 if (ep->ftype == FTYPE_BT)
01790 {
01791 tmpval = bt_read(edt_p, 0x0) |
01792 (bt_read(edt_p, 0x1) << 8) |
01793 (bt_read(edt_p, 0x2) << 16) |
01794 (bt_read(edt_p, 0x3) << 24) ;
01795 return tmpval;
01796 }
01797 else return ep->sectorsize;
01798 }
01799
01800
01801
01802
01803 u_int
01804 get_fpga_info_index_bt8(EdtDev *edt_p)
01805 {
01806 u_int tmpval;
01807
01808 tmpval = bt_read(edt_p, 0x4) |
01809 (bt_read(edt_p, 0x5) << 8) |
01810 (bt_read(edt_p, 0x6) << 16) |
01811 (bt_read(edt_p, 0x7) << 24) ;
01812 return tmpval;
01813 }
01814
01815
01816 #if 0
01817
01818
01819
01820
01821 u_int
01822 get_fpga_info_index_f16(EdtDev *edt_p)
01823 {
01824 u_int tmpval;
01825 u_char buf[4];
01826
01827 f16_rd_flash_block(edt_p, 4, buf, 4);
01828 tmpval = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
01829 return tmpval;
01830
01831 }
01832 #endif
01833
01834
01835
01836
01837
01838
01839 u_int
01840 edt_get_id_addr(int promcode, int segment)
01841 {
01842 u_int id_addr;
01843 Edt_prominfo *ep = edt_get_prominfo(promcode);
01844
01845 if (ep->sectorsize == 0)
01846 return 1;
01847
01848 switch(promcode)
01849 {
01850
01851 case AMD_4013E:
01852 id_addr = (ep->sectsperseg * ep->sectorsize) - PCI_ID_SIZE;
01853 break;
01854
01855 case SPI_XC3S1200E:
01856 id_addr = segment * ep->sectorsize;
01857 break;
01858
01859 case MIC_N25Q064A13ESE40G:
01860 id_addr = MICRON_PROMINFO_ADDR;
01861 break;
01862
01863 default:
01864 id_addr = ((segment + 1) * ep->sectsperseg * ep->sectorsize) - PCI_ID_SIZE;
01865 break;
01866
01867 }
01868 return id_addr;
01869 }
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882 void
01883 edt_readinfo(EdtDev *edt_p, int promcode, int sect, char *idstr, char *devinfo, char *oemsn)
01884 {
01885 Edt_prominfo *ep = edt_get_prominfo(promcode);
01886 EdtPromData pdata;
01887 int sector = (sect < 0)? ep->defaultseg:sect;
01888
01889 edt_read_prom_data(edt_p, promcode, sector, &pdata);
01890 strncpy(idstr, pdata.id, PCIE_PID_SIZE);
01891 strncpy(devinfo, pdata.esn, ESN_SIZE);
01892 strncpy(oemsn, pdata.osn, OSN_SIZE);
01893 }
01894
01895
01896
01897
01898
01899
01900
01901
01902 u_int
01903 edt_flash_get_promaddrs(EdtDev *edt_p, int promcode, int segment,
01904 EdtPromIdAddresses *paddr)
01905
01906 {
01907 Edt_prominfo *ep = edt_get_prominfo(promcode);
01908 char tst[4];
01909
01910
01911
01912 paddr->id_addr = edt_get_id_addr(promcode, segment);
01913
01914
01915
01916
01917
01918
01919
01920
01921 if (ep->ftype == FTYPE_SPI)
01922 {
01923 paddr->osn_addr = paddr->id_addr + PCI_ID_SIZE;
01924 paddr->esn_addr = paddr->osn_addr + OSN_SIZE;
01925 paddr->extra_tag_addr = paddr->esn_addr + ESN_SIZE;
01926 paddr->extra_size_addr = paddr->extra_tag_addr + 4;
01927 paddr->extra_data_addr = paddr->extra_size_addr + 4;
01928 }
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939 else if (ep->ftype == FTYPE_MIC)
01940 {
01941 paddr->osn_addr = paddr->id_addr + PCI_ID_SIZE;
01942 paddr->esn_addr = paddr->osn_addr + OSN_SIZE;
01943 paddr->optsn_addr = paddr->esn_addr + ESN_SIZE;
01944 paddr->extra_tag_addr = paddr->optsn_addr + OPTSN_SIZE;
01945 paddr->extra_size_addr = paddr->extra_tag_addr + EXTRAADDR_SIZE;
01946 paddr->extra_data_addr = paddr->extra_size_addr + EXTRAADDR_SIZE;
01947 paddr->maclist_addr = paddr->extra_data_addr + EXTRAADDR_SIZE;
01948 }
01949 else
01950 {
01951 paddr->osn_addr = paddr->id_addr - OSN_SIZE;
01952 paddr->esn_addr = paddr->osn_addr - ESN_SIZE;
01953 paddr->extra_tag_addr = paddr->esn_addr - EXTRAADDR_SIZE;
01954 paddr->extra_size_addr = paddr->extra_tag_addr - EXTRAADDR_SIZE;
01955 paddr->optsn_addr = paddr->extra_tag_addr - OPTSN_SIZE;
01956 paddr->maclist_addr = paddr->optsn_addr - MACLIST_SIZE ;
01957 }
01958
01959 edt_flash_block_read(edt_p, paddr->extra_tag_addr, (u_char *)tst, 4, ep->ftype);
01960
01961 if (strncmp(tst,"XTR:",4) == 0)
01962 {
01963
01964 edt_flash_block_read(edt_p, paddr->extra_size_addr, (u_char *)&paddr->extra_size, 4, ep->ftype);
01965
01966 if (needswap)
01967 {
01968 paddr->extra_size = swap32(paddr->extra_size);
01969 }
01970 if ((ep->ftype != FTYPE_SPI) && (ep->ftype != FTYPE_F16) && (paddr->extra_size != 0) && (paddr->extra_size > PROM_EXTRA_SIZE))
01971 paddr->extra_data_addr = paddr->extra_size_addr - (4 + paddr->extra_size);
01972 else
01973 {
01974 paddr->extra_data_addr = 0;
01975 paddr->extra_size = 0;
01976 }
01977
01978 }
01979 else
01980 {
01981 paddr->extra_size = 0;
01982 paddr->extra_data_addr = 0;
01983 }
01984
01985 return paddr->id_addr;
01986 }
01987
01988 u_int edt_flash_get_cpld(EdtDev *edt_p, int ftype)
01989 {
01990 if (ftype == FTYPE_MIC)
01991 return mic_read_status_register(edt_p);
01992 return edt_get(edt_p, EDT_FLASHROM_DATA);
01993 }
01994
01995
01996
01997
01998
01999
02000 u_int
02001 ida_4013e(void *dmy, int segment)
02002 {
02003 return (8 * E_SECTOR_SIZE) - PCI_ID_SIZE;
02004 }
02005
02006 u_int
02007 ida_4013xla(void *dmy, int segment)
02008 {
02009 return (segment * AMD_SECTOR_SIZE) + AMD_SECTOR_SIZE - PCI_ID_SIZE;
02010 }
02011
02012 u_int
02013 ida_4028xla(void *dmy, int segment)
02014 {
02015 return ((segment + 1) * 2 * AMD_SECTOR_SIZE) - PCI_ID_SIZE;
02016 }
02017
02018 u_int
02019 ida_xc2s100(void *dmy, int segment)
02020 {
02021 return ((segment + 1) * 4 * AMD_SECTOR_SIZE) - PCI_ID_SIZE;
02022 }
02023
02024 u_int
02025 ida_xc3s1200e(void *dmy, int segment)
02026 {
02027 return segment * SPI_SECTOR_SIZE;
02028 }
02029
02030
02031 static u_int
02032 ida_bt8(void * edt_p , int dmy)
02033 {
02034 return get_fpga_info_index_bt8((EdtDev *)edt_p);
02035 }
02036
02037 static u_int
02038 ida_f16(void * edt_p , int segment)
02039 {
02040 u_short stat;
02041 int promcode = edt_flash_prom_detect(edt_p, &stat);
02042 Edt_prominfo *ep = edt_get_prominfo(promcode);
02043 u_int id_addr = ((segment + 1) * ep->sectsperseg * ep->sectorsize) - PCI_ID_SIZE;
02044
02045 return id_addr;
02046 }
02047
02048
02049 static u_int
02050 ida_micron(void * edt_p , int segment)
02051 {
02052 return MICRON_PROMINFO_ADDR;
02053 }
02054
02055 static void tst_init(EdtDev *edt_p)
02056 {
02057
02058 #ifndef _KERNEL
02059
02060 if (!edt_p->mapaddr)
02061 edt_p->mapaddr = (caddr_t)edt_mapmem(edt_p, 0, 256) ;
02062
02063 #endif
02064
02065 needswap = !edt_little_endian();
02066 }
02067
02068 static void
02069 tst_write(EdtDev * edt_p, uint_t desc, uint_t val)
02070 {
02071
02072 #ifndef _KERNEL
02073 u_int dmy;
02074
02075 if (edt_p->mapaddr)
02076 {
02077
02078 tstaddr = (volatile u_int *)(edt_p->mapaddr + (desc & 0xff)) ;
02079
02080 if (needswap)
02081 {
02082 *tstaddr = swap32(val) ;
02083 }
02084 else
02085 {
02086 *tstaddr = val ;
02087 }
02088
02089 dmy = *tstaddr;
02090 }
02091 else
02092 #endif
02093 edt_set(edt_p, desc, val) ;
02094
02095 }
02096
02097 static uint_t
02098 tst_read(EdtDev * edt_p, uint_t desc)
02099 {
02100
02101 #ifndef _KERNEL
02102
02103 if (edt_p->mapaddr)
02104 {
02105
02106 tstaddr = (volatile u_int *)(edt_p->mapaddr + (desc & 0xff)) ;
02107
02108 if (needswap)
02109 {
02110 return (swap32(*tstaddr)) ;
02111 }
02112 else
02113 return (*tstaddr) ;
02114
02115 }
02116 else
02117 #endif
02118 return(edt_get(edt_p, desc)) ;
02119 }
02120
02121 void tst_pflash(EdtDev *edt_p, uint_t addr, uint_t val)
02122 {
02123
02124 tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) 0xaa);
02125 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
02126 tst_write(edt_p, EDT_FLASHROM_ADDR, (u_int) (0x5555 | EDT_WRITECMD));
02127 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
02128 tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) 0x55);
02129 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
02130 tst_write(edt_p, EDT_FLASHROM_ADDR, (u_int) (0x2aaa | EDT_WRITECMD));
02131 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
02132 tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) 0xa0);
02133 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
02134 tst_write(edt_p, EDT_FLASHROM_ADDR, (u_int) (0x5555 | EDT_WRITECMD));
02135 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
02136 tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) val);
02137 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
02138 tst_write(edt_p, EDT_FLASHROM_ADDR,
02139 (u_int) (EN_HIGH_ADD | addr | EDT_WRITECMD));
02140 (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
02141 }
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158 static char *
02159 edt_flash_string_read(EdtDev *edt_p, u_int addr, char *buf, u_int size, int ftype)
02160 {
02161 u_int i;
02162 u_char *ret = 0;
02163
02164
02165
02166 edt_flash_block_read(edt_p, addr, (u_char *)buf, size, ftype);
02167
02168
02169 for (i=0; i<size; i++)
02170 {
02171 if (!ret && buf[i] >= 0x20 && buf[i] <= 0x7e)
02172 ret = &buf[i];
02173 }
02174
02175 buf[size] = 0;
02176 return ret;
02177 }
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192 u_char *
02193 edt_flash_block_read(EdtDev *edt_p, u_int addr, u_char *buf, u_int size, int ftype)
02194 {
02195 u_int i;
02196
02197
02198 switch(ftype)
02199 {
02200 case FTYPE_F16:
02201 f16_rd_flash_block(edt_p, addr, buf, size);
02202 break;
02203
02204 case FTYPE_MIC:
02205 mic_read_flash(edt_p, SPI_READ, addr, buf, size);
02206 break;
02207
02208 case FTYPE_SPI:
02209 spi_reset(edt_p);
02210 spi_read(edt_p, (u_int)addr, buf, size);
02211 break;
02212
02213 case FTYPE_BT:
02214 case FTYPE_BT2:
02215 for (i=0; i<size; i++)
02216 buf[i] = bt_read(edt_p, addr++);
02217 break;
02218
02219 case FTYPE_X:
02220 for (i=0; i<size; i++)
02221 buf[i] = x_read(edt_p, addr++);
02222 break;
02223
02224 default:
02225 break;
02226 }
02227
02228 return buf;
02229 }
02230
02231 int
02232 edt_sector_erase(EdtDev * edt_p, u_int sector, u_int sec_size, int ftype)
02233 {
02234 int result = 0;
02235
02236 switch(ftype)
02237 {
02238 case FTYPE_F16:
02239 result = f16_sector_erase(edt_p, sector << 16);
02240 break;
02241 case FTYPE_MIC:
02242 result = mic_sector_erase(edt_p, sector << 16);
02243 break;
02244 case FTYPE_SPI:
02245 result = spi_sector_erase(edt_p, sector << 16);
02246 break;
02247 case FTYPE_BT:
02248 result = bt_sector_erase(edt_p, sector, sec_size);
02249 break;
02250 case FTYPE_BT2:
02251 result = bt2_sector_erase(edt_p, sector, sec_size);
02252 break;
02253 case FTYPE_X:
02254 xsector_erase(edt_p, sector, sec_size);
02255 break;
02256 default:
02257 result = -1;
02258 break;
02259 }
02260 return(result);
02261 }
02262
02263
02273 int
02274 edt_flash_prom_detect(EdtDev * edt_p, u_short *stat)
02275 {
02276 u_int desc = EDT_FLASHROM_DATA;
02277 u_short idbits = 0xff;
02278 u_short xidbits = 0xff;
02279 int prom = PROM_UNKN;
02280 u_int flashrom_bits;
02281 u_int pal_ver, straps;
02282
02283 EDTPRINTF(edt_p, 2, ("edt_flash_prom_detect\n"));
02284
02285
02286 if (edt_is_micron_prom(edt_p))
02287 {
02288 u_char cstat = mic_read_status_register(edt_p);
02289
02290 *stat = (u_short)cstat;
02291
02292
02293 idbits = 0x0d;
02294 xidbits = 0x01;
02295 }
02296 else if (edt_is_16bit_prom(edt_p))
02297 {
02298 edt_set(edt_p, 0, 8);
02299 *stat = (u_short)(f16_rd_cmd(edt_p, F16_CMD_RD_PAL_ID) & 0xffff);
02300 straps = *stat & 0x03;
02301 idbits = (*stat >> 2) & 0x1f;
02302 xidbits = (*stat >> 8) & 0xff;
02303 pal_ver = f16_rd_cmd(edt_p, F16_CMD_RD_PAL_VER);
02304 EDTPRINTF(edt_p,2,("\t\tedt_flash_prom_detect (F16): read stat %04x id bits %02x %02x, pal_ver %x, finding prom...\n", *stat, xidbits, idbits, pal_ver));
02305 }
02306
02307
02308
02309
02310
02311
02312 else
02313 {
02314 tst_init(edt_p) ;
02315 tst_write(edt_p, desc, BT_A0);
02316 flashrom_bits = tst_read(edt_p, desc) & BT_A0;
02317
02318 if (flashrom_bits == BT_A0)
02319 {
02320 EDTPRINTF(edt_p,2,(" FLASHROM command BT_A0 can be set board has boot controller\n"));
02321 *stat = (u_short)bt_readstat(edt_p) & 0xff;
02322 xidbits = 0xff;
02323 idbits = (u_char)((*stat & STAT_IDMASK) >> STAT_IDSHFT);
02324 EDTPRINTF(edt_p,2,("\t\tedt_flash_prom_detect (BT): stat %02x id bits %x, finding prom...\n", *stat, idbits));
02325 }
02326 }
02327
02328 if (!(idbits == 0xff && xidbits == 0xff))
02329 {
02330 int i;
02331 int max = edt_get_max_promcode() + 1;
02332
02333 for (i=0; i<max ; i++)
02334 {
02335 if ((idbits == (u_int)EPinfo[i].stat)
02336 && ((EPinfo[i].statx == 0xff) || (xidbits == (u_int)EPinfo[i].statx)))
02337 {
02338 return (i);
02339 }
02340 }
02341 }
02342
02343
02344
02345
02346
02347
02348 if (prom == PROM_UNKN)
02349 {
02350 int i;
02351 u_char mid, devid;
02352
02353 edt_flash_reset(edt_p, 0);
02354
02355
02356 x_write(edt_p, 0x5555, 0xaa);
02357 x_write(edt_p, 0x2aaa, 0x55);
02358 x_write(edt_p, 0x5555, 0x90);
02359 mid = x_read(edt_p, 0x0);
02360 devid = x_read(edt_p, 0x1);
02361
02362 for (i = 0; older_devices[i].prom != 0; i++)
02363 {
02364 if (mid == older_devices[i].mid && devid == older_devices[i].devid)
02365 {
02366 prom = older_devices[i].prom;
02367 break;
02368 }
02369 }
02370
02371 edt_flash_reset(edt_p, 0);
02372 *stat = (u_short)x_readstat(edt_p) | 0xff00;
02373
02374 EDTPRINTF(edt_p,2,("\t\tedt_flash_prom_detect (X_): stat %04x prom %d\n", *stat, prom));
02375 }
02376 return (prom);
02377 }
02378
02379
02380 EdtPromParmBlock *
02381 edt_get_parms_block(EdtPromData *pdata, char *id)
02382
02383 {
02384 EdtPromParmBlock *p;
02385
02386 p = (EdtPromParmBlock *) pdata->extra_buf;
02387
02388 if (p->size > (u_int) pdata->extra_size)
02389 return BAD_PARMS_BLOCK;
02390
02391 while (p->size && ((u_char *) p - pdata->extra_buf) < pdata->extra_size)
02392 {
02393 if (strncmp(id, p->type,4) == 0)
02394 return p;
02395 p = (EdtPromParmBlock *) ((u_char *) p + p->size);
02396 }
02397
02398 return NULL;
02399
02400 }
02401 EdtPromParmBlock *edt_add_parmblock(EdtPromData *pdata, char *type, int datasize)
02402
02403 {
02404
02405 EdtPromParmBlock *p;
02406
02407 p = edt_get_parms_block(pdata, type);
02408
02409 if (p)
02410 return NULL;
02411
02412 if (pdata->extra_size + datasize + 8 > PROM_EXTRA_SIZE)
02413 return NULL;
02414
02415 p = (EdtPromParmBlock *) (pdata->extra_buf + pdata->extra_size);
02416 strncpy(p->type,type,4);
02417 p->size = datasize;
02418
02419 pdata->extra_size += 8 + datasize;
02420
02421 return p;
02422 }
02423
02424
02425
02426
02427 void
02428 program_extra(EdtDev *edt_p, int promcode, EdtPromData *pdata, int sect)
02429 {
02430 u_int id_addr;
02431 Edt_prominfo *ep = edt_get_prominfo(promcode);
02432 int sector;
02433 EdtPromIdAddresses addr;
02434 char *key_str = "XTR:";
02435 u_int size;
02436
02437 sector = (sect == IS_DEFAULT_SECTOR)? ep->defaultseg:sect;
02438
02439 if ((id_addr = edt_flash_get_promaddrs(edt_p, promcode, sector, &addr)) == 1)
02440 {
02441 EDTPRINTF(edt_p, 0, ("invalid device; no ID info\n"));
02442 return;
02443 }
02444
02445
02446
02447
02448
02449 if ((size = pdata->extra_size) > PROM_EXTRA_SIZE)
02450 return;
02451
02452 size = pdata->extra_size;
02453 if (!edt_little_endian())
02454 size = swap32(size);
02455
02456 addr.extra_data_addr = addr.extra_size_addr - (4 + pdata->extra_size);
02457 addr.extra_data_addr = addr.extra_size_addr - (4 + pdata->extra_size);
02458
02459 edt_flash_block_program(edt_p, addr.extra_tag_addr, (u_char *) key_str, 4, ep->ftype);
02460 edt_flash_block_program(edt_p, addr.extra_size_addr, (u_char *) &size, 4, ep->ftype);
02461 if ((ep->ftype != FTYPE_SPI) && size)
02462 edt_flash_block_program(edt_p, addr.extra_data_addr, pdata->extra_buf, pdata->extra_size, ep->ftype);
02463
02464 }
02465
02466
02467
02468
02469 void
02470 edt_zero(void *s, size_t n)
02471 {
02472 #ifdef __sun
02473 bzero(s, n);
02474 #else
02475 memset(s, 0, n);
02476 #endif
02477 }
02478
02479
02480 static void
02481 program_info_str(EdtDev *edt_p, u_int addr, char *str, char *tag, u_int size, int ftype)
02482 {
02483 char info_str[1024];
02484
02485 if (size < 1 || size > 1024)
02486 return;
02487
02488 if (!info_str)
02489 return;
02490
02491 if (str[0])
02492 {
02493
02494
02495
02496 edt_zero(info_str, size);
02497 if (strncmp(str, "erase", 5) != 0)
02498 {
02499 strcpy(info_str, tag);
02500 strcat(info_str, str);
02501 }
02502
02503 edt_flash_block_program(edt_p, addr, (u_char *)info_str, size, ftype);
02504 }
02505 }
02506
02507
02508 void
02509 edt_flash_program_prominfo(EdtDev *edt_p,
02510 int promcode,
02511 int segment,
02512 EdtPromData *pdata)
02513 {
02514
02515 Edt_prominfo *ep = edt_get_prominfo(promcode);
02516 EdtPromIdAddresses addr;
02517
02518 edt_flash_reset(edt_p, ep->ftype);
02519
02520
02521 addr.id_addr = edt_flash_get_promaddrs(edt_p, promcode, segment, &addr);
02522
02523 EDTPRINTF(edt_p, 2,
02524 ("\nedt_flash_program_promdata s%d addrs: maclist %x optsn %06x, xtrasize %06x, xtratag %06x,esn %06x, osn %06x, id %06x\n",
02525 segment, addr.maclist_addr, addr.optsn_addr, addr.extra_size_addr, addr.extra_tag_addr, addr.esn_addr, addr.osn_addr, addr.id_addr));
02526
02527 program_info_str(edt_p, addr.osn_addr, pdata->osn, "OSN:", OSN_SIZE, ep->ftype); EDTPRINTF(edt_p, 0, ("."));
02528 program_info_str(edt_p, addr.esn_addr, pdata->esn, "ESN:", ESN_SIZE, ep->ftype); EDTPRINTF(edt_p, 0, ("."));
02529 program_info_str(edt_p, addr.optsn_addr, pdata->optsn, "OPT:", OPTSN_SIZE, ep->ftype); EDTPRINTF(edt_p, 0, ("."));
02530 program_extra(edt_p, promcode, pdata, segment); EDTPRINTF(edt_p, 0, ("."));
02531 program_info_str(edt_p, addr.maclist_addr, pdata->maclist, "MAC:", MACLIST_SIZE, ep->ftype); EDTPRINTF(edt_p, 0, ("."));
02532 }
02533
02534
02535
02536
02537 char *
02538 edt_flash_type_string(int ftype)
02539 {
02540 switch (ftype)
02541 {
02542 case FTYPE_X: return("FTYPE_X");
02543 case FTYPE_BT: return("FTYPE_BT");
02544 case FTYPE_LTX: return( "FTYPE_LTX");
02545 case FTYPE_SPI: return( "FTYPE_SPI");
02546 case FTYPE_F16: return( "FTYPE_F16");
02547 case FTYPE_BT2: return( "FTYPE_BT2");
02548 case FTYPE_MIC: return( "FTYPE_MIC");
02549 default: return("UNKNOWN");
02550 }
02551 }
02552
02567 void
02568 edt_read_prom_data(EdtDev *edt_p, int promcode, int segment,
02569 EdtPromData *pdata)
02570
02571 {
02572 Edt_prominfo *ep = edt_get_prominfo(promcode);
02573 char idbuf[PCI_ID_SIZE + 1];
02574 char oemsnbuf[OSN_SIZE + 1];
02575 char edtsnbuf[ESN_SIZE + 1];
02576 char optsnbuf[OPTSN_SIZE + 1];
02577 char macbuf[MACLIST_SIZE + 1];
02578
02579 char *ret;
02580
02581 EdtPromIdAddresses addr;
02582
02583 edt_zero(pdata, sizeof(EdtPromData));
02584
02585
02586 addr.id_addr = edt_flash_get_promaddrs(edt_p, promcode, segment, &addr);
02587
02588 EDTPRINTF(edt_p, 2,
02589 ("\nedt_read_prom_data s%d addrs: maclist %x optsn %06x, xtrasize %06x, xtratag %06x,esn %06x, osn %06x, id %06x\n",
02590 segment, addr.maclist_addr, addr.optsn_addr, addr.extra_size_addr, addr.extra_tag_addr, addr.esn_addr, addr.osn_addr, addr.id_addr));
02591
02592
02593 if ((ret = edt_flash_string_read(edt_p, addr.id_addr, idbuf, PCI_ID_SIZE, ep->ftype)) != NULL)
02594 strncpy(pdata->id, ret, PCI_ID_SIZE);
02595
02596
02597 if ((ret = edt_flash_string_read(edt_p, addr.osn_addr, oemsnbuf, OSN_SIZE, ep->ftype)) != NULL)
02598 {
02599 if (strncmp(ret, "OSN:", 4) == 0)
02600 {
02601 strncpy(pdata->osn, &ret[4], OSN_SIZE);
02602 if (pdata->osn[strlen(pdata->osn)-1] == ':')
02603 pdata->osn[strlen(pdata->osn)-1] = '\0';
02604 }
02605 }
02606
02607
02608 if ((ret = edt_flash_string_read(edt_p, addr.esn_addr, edtsnbuf, ESN_SIZE, ep->ftype)) != NULL)
02609 if (strncmp(ret, "ESN:", 4) == 0)
02610 strncpy(pdata->esn, &ret[4], ESN_SIZE);
02611
02612
02613 if (addr.extra_size)
02614 {
02615 if ((ret = (char *)edt_flash_block_read(edt_p, addr.extra_data_addr, pdata->extra_buf, addr.extra_size, ep->ftype)) != NULL)
02616 {
02617 pdata->extra_size = addr.extra_size;
02618 }
02619 }
02620
02621
02622 if ((ret = edt_flash_string_read(edt_p, addr.optsn_addr, optsnbuf, OPTSN_SIZE, ep->ftype)) != NULL)
02623 if (strncmp(ret, "OPT:", 4) == 0)
02624 strncpy(pdata->optsn, &ret[4], OPTSN_SIZE);
02625
02626
02627
02628 if ((ret = edt_flash_string_read(edt_p, addr.maclist_addr, macbuf, MACLIST_SIZE, ep->ftype)) != NULL)
02629 if (strncmp(ret, "MAC:", 4) == 0)
02630 strncpy(pdata->maclist, &ret[4], MACLIST_SIZE-4);
02631
02632 #ifndef _KERNEL
02633 if (pdata->esn)
02634 edt_parse_devinfo(pdata->esn, &pdata->ei);
02635 #endif
02636 }
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647 int
02648 has_slashes(char *name)
02649 {
02650 char *p = name;
02651
02652 while (*p)
02653 {
02654 if ((*p == '/') || (*p == '\\'))
02655 return 1;
02656 ++p;
02657 }
02658 return 0;
02659 }
02660
02661
02662 #ifndef _KERNEL
02663
02685 int
02686 edt_parse_devinfo(char *str, Edt_embinfo *ei)
02687 {
02688 u_int i,j=0;
02689 int n;
02690 int nfields=0;
02691 char sn[EDT_STRBUF_SIZE], pn[EDT_STRBUF_SIZE];
02692 char ifx[EDT_STRBUF_SIZE], rev[EDT_STRBUF_SIZE], clock[EDT_STRBUF_SIZE], options[EDT_STRBUF_SIZE];
02693 char tmpstr[EDT_STRBUF_SIZE*10];
02694
02695 if (strlen(str) >= EDT_STRBUF_SIZE*4)
02696 return -1;
02697
02698 sn[0] = pn[0] = clock[0] = options[0] = ifx[0] = '\0';
02699
02700 for (i=0; i<strlen(str); i++)
02701 {
02702 tmpstr[j++] = str[i];
02703 if (str[i] == ':')
02704 {
02705 ++nfields;
02706 if (str[i+1] == ':')
02707 tmpstr[j++] = ' ';
02708 }
02709 }
02710 tmpstr[j] = '\0';
02711
02712 if (nfields < 4)
02713 {
02714 return -1;
02715 }
02716
02717
02718 n = sscanf(tmpstr, "%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:", sn, pn, clock, options, rev, ifx);
02719
02720
02721 if (strlen(sn) > 10)
02722 sn[10] = '\0';
02723
02724 if ((strlen(pn) > 10) || (strlen(options) > 10) || !isdigit_str(clock))
02725 return -1;
02726
02727 if (n < 4)
02728 return -1;
02729
02730 if (n < 5)
02731 rev[0] = '\0';
02732
02733 if (n < 6)
02734 ifx[0] = '\0';
02735
02736 strcpy(ei->sn, sn);
02737 strcpy(ei->pn, pn);
02738 strcpy(ei->opt, options);
02739 ei->clock = edt_strtol(clock,0,0);
02740 ei->rev = edt_strtol(rev,0,0);
02741 strcpy(ei->ifx, ifx);
02742
02743 return 0;
02744 }
02745
02746
02747
02748 int
02749 edt_parse_esn(char *str, Edt_embinfo *ei)
02750 {
02751 return edt_parse_devinfo(str, ei);
02752 }
02753
02754
02755 #endif
02756
02757
02758 #define MIC_RDID 0x9E
02759 #define SPI_READ 0x03
02760 #define SPI_FREAD 0x0B
02761 #define MIC_RDNVCR 0xB5
02762 #define MIC_WRNVCR 0xB1
02763
02764 #define SPI_WREN 0x06
02765 #define SPI_WRDI 0x04
02766 #define SPI_RDSR 0x05
02767 #define SPI_WRSR 0x01
02768 #define SPI_RDFS 0x70
02769 #define SPI_CLFS 0x50
02770 #define SPI_PP 0x02
02771 #define SPI_SSE 0x20
02772 #define SPI_SE 0xD8
02773 #define SPI_BE 0xC7
02774 #define SPI_DP 0xB9
02775
02776 #define MIC_EN 0x00008000
02777 #define MIC_CS 0x00004000
02778 #define MIC_STB 0x00002000
02779 #define MIC_LSB 0x00001000
02780
02781 #define F16_P4_CMDDATA_REG 0x04000084
02782 #define F16_P4_DATA_REG 0x04000088
02783
02784
02785 static u_int
02786 mic_write(EdtDev *edt_p, u_int val)
02787 {
02788 u_int cmd_data;
02789
02790 cmd_data = (val & 0xffff);
02791
02792 edt_set(edt_p, F16_P4_CMDDATA_REG, cmd_data) ;
02793 (void)edt_get(edt_p, F16_P4_CMDDATA_REG) ;
02794
02795 return 0 ;
02796 }
02797
02798 static u_int
02799 mic_read(EdtDev *edt_p)
02800 {
02801 u_int read_data;
02802
02803 (void)edt_get(edt_p, F16_P4_CMDDATA_REG) ;
02804 read_data = edt_get(edt_p, F16_P4_CMDDATA_REG) ;
02805
02806 return read_data ;
02807 }
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820 static u_int
02821 mic_write_enable(EdtDev *edt_p)
02822 {
02823 u_int stb;
02824 u_int read_data = 0;
02825
02826 mic_write(edt_p, MIC_EN);
02827
02828
02829 stb = MIC_STB;
02830 mic_write(edt_p, (MIC_EN + stb + SPI_WREN));
02831
02832
02833 mic_write(edt_p, (MIC_EN + stb + MIC_CS));
02834
02835
02836 mic_write(edt_p, (MIC_EN +stb));
02837
02838
02839 stb ^= MIC_STB;
02840 mic_write(edt_p, (MIC_EN + stb + SPI_RDSR));
02841
02842
02843 stb ^= MIC_STB;
02844 mic_write(edt_p, (MIC_EN + stb));
02845 read_data = mic_read(edt_p) & 0xFF;
02846 edt_delay(2);
02847
02848
02849 mic_write(edt_p, MIC_CS);
02850
02851
02852 read_data &= 0x02;
02853
02854 if (read_data)
02855 return 1;
02856 else
02857 return 0;
02858 }
02859
02860 static u_int
02861 mic_write_disable(EdtDev *edt_p)
02862 {
02863 u_int stb;
02864 u_int read_data = 0;
02865
02866
02867 mic_write(edt_p, MIC_EN);
02868
02869
02870 stb = MIC_STB;
02871 mic_write(edt_p, (MIC_EN + stb + SPI_WRDI));
02872
02873
02874 mic_write(edt_p, (MIC_EN + stb + MIC_CS));
02875
02876
02877 mic_write(edt_p, (MIC_EN + stb));
02878
02879
02880 stb ^= MIC_STB;
02881 mic_write(edt_p, (MIC_EN + stb + SPI_RDSR));
02882
02883
02884 stb ^= MIC_STB;
02885 mic_write(edt_p, (MIC_EN + stb));
02886 read_data = mic_read(edt_p) & 0xFF;
02887 #ifndef _KERNEL
02888 printf("Write Disable Read Status : %d\n", read_data);
02889 #endif
02890
02891
02892 mic_write(edt_p, MIC_CS);
02893
02894
02895 read_data &= 0x02;
02896
02897 if (read_data)
02898 return 0;
02899 else
02900 return 1;
02901 }
02902
02903 static u_int
02904 mic_read_flash(EdtDev *edt_p, u_int command, u_int address, u_char *read_bytes, u_int read_num_bytes)
02905 {
02906 u_int address_buf[3] = {0,0,0};
02907 u_int i = 0;
02908 u_int stb;
02909 u_int read_data = 0;
02910
02911
02912
02913 mic_write(edt_p, MIC_EN);
02914
02915
02916 stb = MIC_STB;
02917 mic_write(edt_p, (MIC_EN + stb + command));
02918
02919
02920 if (command == SPI_READ)
02921 {
02922 address_buf[0] = ((address & 0x00FF0000) >> 16);
02923 address_buf[1] = ((address & 0x0000FF00) >> 8);
02924 address_buf[2] = (address & 0x000000FF);
02925
02926
02927 for (i=0;i<3;i++)
02928 {
02929 stb ^= MIC_STB;
02930 mic_write(edt_p, (MIC_EN + stb + address_buf[i]));
02931 }
02932
02933 }
02934
02935
02936 for (i=0;i<read_num_bytes;i++)
02937 {
02938 stb ^= MIC_STB;
02939 if (command == SPI_READ)
02940 mic_write(edt_p, (MIC_EN + stb + MIC_LSB));
02941 else
02942 mic_write(edt_p, (MIC_EN + stb));
02943 read_bytes[i] = (u_char)(mic_read(edt_p) & 0xFF);
02944 }
02945
02946
02947 mic_write(edt_p, MIC_CS);
02948
02949
02950 return 1;
02951 }
02952
02953
02954
02955 static u_char
02956 mic_read_status_register(EdtDev *edt_p)
02957 {
02958 u_char read_buffer[1];
02959 mic_read_flash(edt_p, SPI_RDSR, 0, read_buffer, 1);
02960
02961 return read_buffer[0];
02962 }
02963
02964
02965
02966
02967
02968
02969
02970
02971 static u_int
02972 mic_write_flash(EdtDev *edt_p, u_int command, u_int address, u_char *write_bytes, u_int write_num_bytes, u_int time_min, u_int timeout_loops, u_int timeout_sleep)
02973
02974 {
02975 u_int stb;
02976 u_int i = 0;
02977 u_int write_in_progress;
02978 u_int address_buf[3] = {0,0,0};
02979 u_int read_data = 0;
02980
02981
02982 if (!(mic_write_enable(edt_p)))
02983 {
02984 #ifndef _KERNEL
02985 printf("Failure to set write enable bit\n");
02986 #endif
02987 return 0;
02988 }
02989
02990
02991 mic_write(edt_p, MIC_EN);
02992
02993 stb = MIC_STB;
02994
02995 mic_write(edt_p, (MIC_EN + stb + command));
02996
02997
02998 if ((command == SPI_PP) || (command == SPI_SE) || (command == SPI_SSE))
02999 {
03000 address_buf[0] = ((address & 0x00FF0000) >> 16);
03001 address_buf[1] = ((address & 0x0000FF00) >> 8);
03002 address_buf[2] = (address & 0x000000FF);
03003
03004
03005 for (i=0;i<3;i++)
03006 {
03007 stb ^= MIC_STB;
03008 mic_write(edt_p, (MIC_EN + stb + address_buf[i]));
03009 }
03010 }
03011
03012
03013 for (i=0;i<write_num_bytes;i++)
03014 {
03015 stb ^= MIC_STB;
03016 if (command == SPI_PP)
03017 {
03018
03019 mic_write(edt_p, (MIC_EN + stb + MIC_LSB + write_bytes[i]));
03020 }
03021 else
03022 {
03023 mic_write(edt_p, (MIC_EN + stb + write_bytes[i]));
03024 }
03025 }
03026
03027
03028 mic_write(edt_p, (MIC_EN + stb + MIC_CS));
03029
03030 edt_delay(time_min);
03031
03032
03033 mic_write(edt_p, (MIC_EN + stb));
03034
03035
03036 stb ^= MIC_STB;
03037 mic_write(edt_p, (MIC_EN + stb + SPI_RDSR));
03038
03039 i=0;
03040 write_in_progress = 1;
03041 while((i < timeout_loops) && write_in_progress)
03042 {
03043 stb ^= MIC_STB;
03044 mic_write(edt_p, (MIC_EN + stb));
03045 write_in_progress = (mic_read(edt_p) & 0x01);
03046 if (write_in_progress)
03047 {
03048 edt_delay(timeout_sleep);
03049 i++;
03050 }
03051 }
03052
03053
03054 mic_write(edt_p, MIC_CS);
03055
03056 if (write_in_progress)
03057 return -1;
03058 else
03059 return 0;
03060 }
03061
03062
03063 static u_int
03064 mic_subsector_erase(EdtDev *edt_p, u_int address)
03065 {
03066 return mic_write_flash(edt_p, SPI_SSE, address, 0, 0, 250, 15, 50);
03067 }
03068
03069
03070 static u_int
03071 mic_sector_erase(EdtDev *edt_p, u_int address)
03072 {
03073 return mic_write_flash(edt_p, SPI_SE, address, 0, 0, 700, 50, 50);
03074 }
03075
03076
03077 static u_int
03078 mic_bulk_erase(EdtDev *edt_p, u_int address)
03079 {
03080 return mic_write_flash(edt_p, SPI_BE, 0, 0, 0, 60000, 650, 100);
03081 }
03082
03083
03084
03085
03086
03087
03088 static u_int
03089 mic_page_program(EdtDev *edt_p, u_int address, u_char *write_bytes, u_int write_num_bytes)
03090 {
03091 u_int write_count;
03092 if (write_num_bytes > 256)
03093 write_count = 256;
03094 else
03095 write_count = write_num_bytes;
03096
03097 return mic_write_flash(edt_p, SPI_PP, address, write_bytes, write_count, 1, 6, 1);
03098 }
03099
03100
03101
03102 static u_int
03103 mic_write_status_register(EdtDev *edt_p, u_char status_val)
03104 {
03105 return mic_write_flash(edt_p, SPI_WRSR, 0, &status_val, 1, 2, 8, 1);
03106 }
03107
03108 void
03109 mic_reset(EdtDev *edt_p)
03110 {
03111
03112 }
03113
03114
03115
03116
03117
03118 int
03119 edt_mic_is_protected(EdtDev *edt_p)
03120 {
03121 if (mic_read_status_register(edt_p) & 0x5c)
03122 return 1;
03123 return 0;
03124 }
03125
03126