?? epcs.c
字號:
return (0);}int epcs_write (ulong addr, ulong off, ulong cnt){ ulong wrcnt; unsigned pgsz; unsigned char buf[4]; struct epcs_devinfo_t *dev = epcs_dev_find (); if (!dev) return (-1); pgsz = (1<<dev->sz_page); while (cnt) { if (off % pgsz) wrcnt = pgsz - (off % pgsz); else wrcnt = pgsz; wrcnt = (wrcnt > cnt) ? cnt : wrcnt; buf[0] = EPCS_WRITE_BYTES; buf[1] = off >> 16; buf[2] = off >> 8; buf[3] = off; epcs_wr_enable (); epcs_cs (1); epcs_snd (buf,4); epcs_rsnd ((unsigned char *)addr, wrcnt); epcs_cs (0); /* Wait for write to complete */ while (epcs_status_rd() & EPCS_STATUS_WIP) ; cnt -= wrcnt; off += wrcnt; addr += wrcnt; } return (0);}int epcs_verify (ulong addr, ulong off, ulong cnt, ulong *err){ ulong rdcnt; unsigned char buf[256]; unsigned char *start,*end; int i; start = end = (unsigned char *)addr; while (cnt) { rdcnt = (cnt>sizeof(buf)) ? sizeof(buf) : cnt; epcs_read ((ulong)buf, off, rdcnt); for (i=0; i<rdcnt; i++) { if (*end != buf[i]) { *err = end - start; return(-1); } end++; } cnt -= rdcnt; off += rdcnt; } return (0);}static int epcs_sect_erased (int sect, unsigned *offset, struct epcs_devinfo_t *dev){ unsigned char buf[128]; unsigned off, end; unsigned sectsz; int i; sectsz = (1 << dev->sz_sect); off = sectsz * sect; end = off + sectsz; while (off < end) { epcs_read ((ulong)buf, off, sizeof(buf)); for (i=0; i < sizeof(buf); i++) { if (buf[i] != 0xff) { *offset = off + i; return (0); } } off += sizeof(buf); } return (1);}/*********************************************************************** * Commands ***********************************************************************/staticvoid do_epcs_info (struct epcs_devinfo_t *dev, int argc, char *argv[]){ int i; unsigned char stat; unsigned tmp; int erased; /* Basic device info */ printf ("%s: %d kbytes (%d sectors x %d kbytes," " %d bytes/page)\n", dev->name, 1 << (dev->size-10), dev->num_sects, 1 << (dev->sz_sect-10), 1 << dev->sz_page ); /* Status -- for now protection is all-or-nothing */ stat = epcs_status_rd(); printf ("status: 0x%02x (WIP:%d, WEL:%d, PROT:%s)\n", stat, (stat & EPCS_STATUS_WIP) ? 1 : 0, (stat & EPCS_STATUS_WEL) ? 1 : 0, (stat & dev->prot_mask) ? "on" : "off" ); /* Configuration */ tmp = epcs_cfgsz (); if (tmp) { printf ("config: 0x%06x (%d) bytes\n", tmp, tmp ); } else { printf ("config: unknown\n" ); } /* Sector info */ for (i=0; i<dev->num_sects; i++) { erased = epcs_sect_erased (i, &tmp, dev); printf (" %d: %06x ", i, i*(1<<dev->sz_sect) ); if (erased) printf ("erased\n"); else printf ("data @ 0x%06x\n", tmp); } return;}staticvoid do_epcs_erase (struct epcs_devinfo_t *dev, int argc, char *argv[]){ unsigned start,end; if ((argc < 3) || (argc > 4)) { printf ("USAGE: epcs erase sect [end]\n"); return; } if ((epcs_status_rd() & dev->prot_mask) != 0) { printf ( "epcs: device protected.\n"); return; } start = simple_strtoul (argv[2], NULL, 10); if (argc > 3) end = simple_strtoul (argv[3], NULL, 10); else end = start; if ((start >= dev->num_sects) || (start > end)) { printf ("epcs: invalid sector range: [%d:%d]\n", start, end ); return; } epcs_erase (start, end); return;}staticvoid do_epcs_protect (struct epcs_devinfo_t *dev, int argc, char *argv[]){ unsigned char stat; /* For now protection is all-or-nothing to keep things * simple. The protection bits don't map in a linear * fashion ... and we would rather protect the bottom * of the device since it contains the config data and * leave the top unprotected for app use. But unfortunately * protection works from top-to-bottom so it does * really help very much from a software app point-of-view. */ if (argc < 3) { printf ("USAGE: epcs protect on | off\n"); return; } if (!dev) return; /* Protection on/off is just a matter of setting/clearing * all protection bits in the status register. */ stat = epcs_status_rd (); if (strcmp ("on", argv[2]) == 0) { stat |= dev->prot_mask; } else if (strcmp ("off", argv[2]) == 0 ) { stat &= ~dev->prot_mask; } else { printf ("epcs: unknown protection: %s\n", argv[2]); return; } epcs_status_wr (stat); return;}staticvoid do_epcs_read (struct epcs_devinfo_t *dev, int argc, char *argv[]){ ulong addr,off,cnt; ulong sz; if (argc < 5) { printf ("USAGE: epcs read addr offset count\n"); return; } sz = 1 << dev->size; addr = simple_strtoul (argv[2], NULL, 16); off = simple_strtoul (argv[3], NULL, 16); cnt = simple_strtoul (argv[4], NULL, 16); if (off > sz) { printf ("offset is greater than device size" "... aborting.\n"); return; } if ((off + cnt) > sz) { printf ("request exceeds device size" "... truncating.\n"); cnt = sz - off; } printf ("epcs: read %08lx <- %06lx (0x%lx bytes)\n", addr, off, cnt); epcs_read (addr, off, cnt); return;}staticvoid do_epcs_write (struct epcs_devinfo_t *dev, int argc, char *argv[]){ ulong addr,off,cnt; ulong sz; ulong err; if (argc < 5) { printf ("USAGE: epcs write addr offset count\n"); return; } if ((epcs_status_rd() & dev->prot_mask) != 0) { printf ( "epcs: device protected.\n"); return; } sz = 1 << dev->size; addr = simple_strtoul (argv[2], NULL, 16); off = simple_strtoul (argv[3], NULL, 16); cnt = simple_strtoul (argv[4], NULL, 16); if (off > sz) { printf ("offset is greater than device size" "... aborting.\n"); return; } if ((off + cnt) > sz) { printf ("request exceeds device size" "... truncating.\n"); cnt = sz - off; } printf ("epcs: write %08lx -> %06lx (0x%lx bytes)\n", addr, off, cnt); epcs_write (addr, off, cnt); if (epcs_verify (addr, off, cnt, &err) != 0) printf ("epcs: write error at offset %06lx\n", err); return;}staticvoid do_epcs_verify (struct epcs_devinfo_t *dev, int argc, char *argv[]){ ulong addr,off,cnt; ulong sz; ulong err; if (argc < 5) { printf ("USAGE: epcs verify addr offset count\n"); return; } sz = 1 << dev->size; addr = simple_strtoul (argv[2], NULL, 16); off = simple_strtoul (argv[3], NULL, 16); cnt = simple_strtoul (argv[4], NULL, 16); if (off > sz) { printf ("offset is greater than device size" "... aborting.\n"); return; } if ((off + cnt) > sz) { printf ("request exceeds device size" "... truncating.\n"); cnt = sz - off; } printf ("epcs: verify %08lx -> %06lx (0x%lx bytes)\n", addr, off, cnt); if (epcs_verify (addr, off, cnt, &err) != 0) printf ("epcs: verify error at offset %06lx\n", err); return;}/*-----------------------------------------------------------------------*/int do_epcs (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ int len; struct epcs_devinfo_t *dev = epcs_dev_find (); if (!dev) { printf ("epcs: device not found.\n"); return (-1); } if (argc < 2) { do_epcs_info (dev, argc, argv); return (0); } len = strlen (argv[1]); if (strncmp ("info", argv[1], len) == 0) { do_epcs_info (dev, argc, argv); } else if (strncmp ("erase", argv[1], len) == 0) { do_epcs_erase (dev, argc, argv); } else if (strncmp ("protect", argv[1], len) == 0) { do_epcs_protect (dev, argc, argv); } else if (strncmp ("read", argv[1], len) == 0) { do_epcs_read (dev, argc, argv); } else if (strncmp ("write", argv[1], len) == 0) { do_epcs_write (dev, argc, argv); } else if (strncmp ("verify", argv[1], len) == 0) { do_epcs_verify (dev, argc, argv); } else { printf ("epcs: unknown operation: %s\n", argv[1]); } return (0);}/*-----------------------------------------------------------------------*/U_BOOT_CMD( epcs, 5, 0, do_epcs, SHORT_HELP, LONG_HELP );#endif /* CONFIG_NIOS_EPCS */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -