📄 asmi.c.svn-base
字号:
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] = ASMI_WRITE_BYTES; buf[1] = off >> 16; buf[2] = off >> 8; buf[3] = off; asmi_wr_enable (); asmi_cs (1); asmi_snd (buf,4); asmi_rsnd ((unsigned char *)addr, wrcnt); asmi_cs (0); /* Wait for write to complete */ while (asmi_status_rd() & ASMI_STATUS_WIP) ; cnt -= wrcnt; off += wrcnt; addr += wrcnt; } return (0);}staticint asmi_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; asmi_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 asmi_sect_erased (int sect, unsigned *offset, struct asmi_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) { asmi_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_asmi_info (struct asmi_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 = asmi_status_rd(); printf ("status: 0x%02x (WIP:%d, WEL:%d, PROT:%s)\n", stat, (stat & ASMI_STATUS_WIP) ? 1 : 0, (stat & ASMI_STATUS_WEL) ? 1 : 0, (stat & dev->prot_mask) ? "on" : "off" ); /* Configuration */ tmp = asmi_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 = asmi_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_asmi_erase (struct asmi_devinfo_t *dev, int argc, char *argv[]){ unsigned start,end; if ((argc < 3) || (argc > 4)) { printf ("USAGE: asmi erase sect [end]\n"); return; } if ((asmi_status_rd() & dev->prot_mask) != 0) { printf ( "asmi: 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 ("asmi: invalid sector range: [%d:%d]\n", start, end ); return; } asmi_erase (start, end); return;}staticvoid do_asmi_protect (struct asmi_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: asmi 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 = asmi_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 ("asmi: unknown protection: %s\n", argv[2]); return; } asmi_status_wr (stat); return;}staticvoid do_asmi_read (struct asmi_devinfo_t *dev, int argc, char *argv[]){ ulong addr,off,cnt; ulong sz; if (argc < 5) { printf ("USAGE: asmi 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 ("asmi: read %08lx <- %06lx (0x%lx bytes)\n", addr, off, cnt); asmi_read (addr, off, cnt); return;}staticvoid do_asmi_write (struct asmi_devinfo_t *dev, int argc, char *argv[]){ ulong addr,off,cnt; ulong sz; ulong err; if (argc < 5) { printf ("USAGE: asmi write addr offset count\n"); return; } if ((asmi_status_rd() & dev->prot_mask) != 0) { printf ( "asmi: 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 ("asmi: write %08lx -> %06lx (0x%lx bytes)\n", addr, off, cnt); asmi_write (addr, off, cnt); if (asmi_verify (addr, off, cnt, &err) != 0) printf ("asmi: write error at offset %06lx\n", err); return;}staticvoid do_asmi_verify (struct asmi_devinfo_t *dev, int argc, char *argv[]){ ulong addr,off,cnt; ulong sz; ulong err; if (argc < 5) { printf ("USAGE: asmi 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 ("asmi: verify %08lx -> %06lx (0x%lx bytes)\n", addr, off, cnt); if (asmi_verify (addr, off, cnt, &err) != 0) printf ("asmi: verify error at offset %06lx\n", err); return;}/*-----------------------------------------------------------------------*/int do_asmi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ int len; struct asmi_devinfo_t *dev = asmi_dev_find (); if (argc < 2) { printf ("Usage:%s", LONG_HELP); return (0); } if (!dev) { printf ("asmi: device not found.\n"); return (0); } len = strlen (argv[1]); if (strncmp ("info", argv[1], len) == 0) { do_asmi_info ( dev, argc, argv); } else if (strncmp ("erase", argv[1], len) == 0) { do_asmi_erase (dev, argc, argv); } else if (strncmp ("protect", argv[1], len) == 0) { do_asmi_protect (dev, argc, argv); } else if (strncmp ("read", argv[1], len) == 0) { do_asmi_read (dev, argc, argv); } else if (strncmp ("write", argv[1], len) == 0) { do_asmi_write (dev, argc, argv); } else if (strncmp ("verify", argv[1], len) == 0) { do_asmi_verify (dev, argc, argv); } else { printf ("asmi: unknown operation: %s\n", argv[1]); } return (0);}/*-----------------------------------------------------------------------*/U_BOOT_CMD( asmi, 5, 0, do_asmi, SHORT_HELP, LONG_HELP );#endif /* CONFIG_NIOS_ASMI */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -