* Patch by Scott McNutt, 02 Jan 2004: Add support for the Nios Active Serial Memory Interface (ASMI) on Cyclone devices * Patch by Andrea Marson, 16 Dec 2003: Add support for the PPChameleon ME and HI modules * Patch by Yuli Barcohen, 22 Dec 2003: Add support for Motorola DUET ADS board (MPC87x/88x)master
parent
dd875c767e
commit
180d3f74e4
@ -0,0 +1,695 @@ |
|||||||
|
/*
|
||||||
|
* (C) Copyright 2003, Psyent Corporation <www.psyent.com> |
||||||
|
* Scott McNutt <smcnutt@psyent.com> |
||||||
|
* |
||||||
|
* See file CREDITS for list of people who contributed to this |
||||||
|
* project. |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU General Public License as |
||||||
|
* published by the Free Software Foundation; either version 2 of |
||||||
|
* the License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program; if not, write to the Free Software |
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||||
|
* MA 02111-1307 USA |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <common.h> |
||||||
|
|
||||||
|
#if defined(CONFIG_NIOS_ASMI) |
||||||
|
#include <command.h> |
||||||
|
#include <nios-io.h> |
||||||
|
|
||||||
|
#if !defined(CFG_NIOS_ASMIBASE) |
||||||
|
#error "*** CFG_NIOS_ASMIBASE not defined ***" |
||||||
|
#endif |
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/ |
||||||
|
#define SHORT_HELP\ |
||||||
|
"asmi - read/write Cyclone ASMI configuration device.\n" |
||||||
|
|
||||||
|
#define LONG_HELP\ |
||||||
|
"\n"\
|
||||||
|
"asmi erase start [end]\n"\
|
||||||
|
" - erase sector start or sectors start through end.\n"\
|
||||||
|
"asmi info\n"\
|
||||||
|
" - display ASMI device information.\n"\
|
||||||
|
"asmi protect on | off\n"\
|
||||||
|
" - turn device protection on or off.\n"\
|
||||||
|
"asmi read addr offset count\n"\
|
||||||
|
" - read count bytes from offset to addr.\n"\
|
||||||
|
"asmi write addr offset count\n"\
|
||||||
|
" - write count bytes to offset from addr.\n"\
|
||||||
|
"asmi verify addr offset count\n"\
|
||||||
|
" - verify count bytes at offset from addr.\n" |
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/ |
||||||
|
/* Operation codes for serial configuration devices
|
||||||
|
*/ |
||||||
|
#define ASMI_WRITE_ENA 0x06 /* Write enable */ |
||||||
|
#define ASMI_WRITE_DIS 0x04 /* Write disable */ |
||||||
|
#define ASMI_READ_STAT 0x05 /* Read status */ |
||||||
|
#define ASMI_READ_BYTES 0x03 /* Read bytes */ |
||||||
|
#define ASMI_READ_ID 0xab /* Read silicon id */ |
||||||
|
#define ASMI_WRITE_STAT 0x01 /* Write status */ |
||||||
|
#define ASMI_WRITE_BYTES 0x02 /* Write bytes */ |
||||||
|
#define ASMI_ERASE_BULK 0xc7 /* Erase entire device */ |
||||||
|
#define ASMI_ERASE_SECT 0xd8 /* Erase sector */ |
||||||
|
|
||||||
|
/* Device status register bits
|
||||||
|
*/ |
||||||
|
#define ASMI_STATUS_WIP (1<<0) /* Write in progress */ |
||||||
|
#define ASMI_STATUS_WEL (1<<1) /* Write enable latch */ |
||||||
|
|
||||||
|
static nios_asmi_t *asmi = (nios_asmi_t *)CFG_NIOS_ASMIBASE; |
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Device access |
||||||
|
***********************************************************************/ |
||||||
|
static void asmi_cs (int assert) |
||||||
|
{ |
||||||
|
if (assert) { |
||||||
|
asmi->control |= NIOS_ASMI_SSO; |
||||||
|
} else { |
||||||
|
/* Let all bits shift out */ |
||||||
|
while ((asmi->status & NIOS_ASMI_TMT) == 0) |
||||||
|
; |
||||||
|
asmi->control &= ~NIOS_ASMI_SSO; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void asmi_tx (unsigned char c) |
||||||
|
{ |
||||||
|
while ((asmi->status & NIOS_ASMI_TRDY) == 0) |
||||||
|
; |
||||||
|
asmi->txdata = c; |
||||||
|
} |
||||||
|
|
||||||
|
static int asmi_rx (void) |
||||||
|
{ |
||||||
|
while ((asmi->status & NIOS_ASMI_RRDY) == 0) |
||||||
|
; |
||||||
|
return (asmi->rxdata); |
||||||
|
} |
||||||
|
|
||||||
|
static unsigned char bitrev[] = { |
||||||
|
0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, |
||||||
|
0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f |
||||||
|
}; |
||||||
|
|
||||||
|
static unsigned char asmi_bitrev( unsigned char c ) |
||||||
|
{ |
||||||
|
unsigned char val; |
||||||
|
|
||||||
|
val = bitrev[c>>4]; |
||||||
|
val |= bitrev[c & 0x0f]<<4; |
||||||
|
return (val); |
||||||
|
} |
||||||
|
|
||||||
|
static void asmi_rcv (unsigned char *dst, int len) |
||||||
|
{ |
||||||
|
while (len--) { |
||||||
|
asmi_tx (0); |
||||||
|
*dst++ = asmi_rx (); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void asmi_rrcv (unsigned char *dst, int len) |
||||||
|
{ |
||||||
|
while (len--) { |
||||||
|
asmi_tx (0); |
||||||
|
*dst++ = asmi_bitrev (asmi_rx ()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void asmi_snd (unsigned char *src, int len) |
||||||
|
{ |
||||||
|
while (len--) { |
||||||
|
asmi_tx (*src++); |
||||||
|
asmi_rx (); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void asmi_rsnd (unsigned char *src, int len) |
||||||
|
{ |
||||||
|
while (len--) { |
||||||
|
asmi_tx (asmi_bitrev (*src++)); |
||||||
|
asmi_rx (); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void asmi_wr_enable (void) |
||||||
|
{ |
||||||
|
asmi_cs (1); |
||||||
|
asmi_tx (ASMI_WRITE_ENA); |
||||||
|
asmi_rx (); |
||||||
|
asmi_cs (0); |
||||||
|
} |
||||||
|
|
||||||
|
static unsigned char asmi_status_rd (void) |
||||||
|
{ |
||||||
|
unsigned char status; |
||||||
|
|
||||||
|
asmi_cs (1); |
||||||
|
asmi_tx (ASMI_READ_STAT); |
||||||
|
asmi_rx (); |
||||||
|
asmi_tx (0); |
||||||
|
status = asmi_rx (); |
||||||
|
asmi_cs (0); |
||||||
|
return (status); |
||||||
|
} |
||||||
|
|
||||||
|
static void asmi_status_wr (unsigned char status) |
||||||
|
{ |
||||||
|
asmi_wr_enable (); |
||||||
|
asmi_cs (1); |
||||||
|
asmi_tx (ASMI_WRITE_STAT); |
||||||
|
asmi_rx (); |
||||||
|
asmi_tx (status); |
||||||
|
asmi_rx (); |
||||||
|
asmi_cs (0); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Device information |
||||||
|
***********************************************************************/ |
||||||
|
typedef struct asmi_devinfo_t { |
||||||
|
const char *name; /* Device name */ |
||||||
|
unsigned char id; /* Device silicon id */ |
||||||
|
unsigned char size; /* Total size log2(bytes)*/ |
||||||
|
unsigned char num_sects; /* Number of sectors */ |
||||||
|
unsigned char sz_sect; /* Sector size log2(bytes) */ |
||||||
|
unsigned char sz_page; /* Page size log2(bytes) */ |
||||||
|
unsigned char prot_mask; /* Protection mask */ |
||||||
|
}asmi_devinfo_t; |
||||||
|
|
||||||
|
static struct asmi_devinfo_t devinfo[] = { |
||||||
|
{ "EPCS1 ", 0x10, 17, 4, 15, 8, 0x0c }, |
||||||
|
{ "EPCS4 ", 0x12, 19, 8, 16, 8, 0x1c }, |
||||||
|
{ 0, 0, 0, 0, 0, 0 } |
||||||
|
}; |
||||||
|
|
||||||
|
static asmi_devinfo_t *asmi_dev_find (void) |
||||||
|
{ |
||||||
|
unsigned char buf[4]; |
||||||
|
unsigned char id; |
||||||
|
int i; |
||||||
|
struct asmi_devinfo_t *dev = NULL; |
||||||
|
|
||||||
|
/* Read silicon id requires 3 "dummy bytes" before it's put
|
||||||
|
* on the wire. |
||||||
|
*/ |
||||||
|
buf[0] = ASMI_READ_ID; |
||||||
|
buf[1] = 0; |
||||||
|
buf[2] = 0; |
||||||
|
buf[3] = 0; |
||||||
|
|
||||||
|
asmi_cs (1); |
||||||
|
asmi_snd (buf,4); |
||||||
|
asmi_rcv (buf,1); |
||||||
|
asmi_cs (0); |
||||||
|
id = buf[0]; |
||||||
|
|
||||||
|
/* Find the info struct */ |
||||||
|
i = 0; |
||||||
|
while (devinfo[i].name) { |
||||||
|
if (id == devinfo[i].id) { |
||||||
|
dev = &devinfo[i]; |
||||||
|
break; |
||||||
|
} |
||||||
|
i++; |
||||||
|
} |
||||||
|
|
||||||
|
return (dev); |
||||||
|
} |
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Misc Utilities |
||||||
|
***********************************************************************/ |
||||||
|
static unsigned asmi_cfgsz (void) |
||||||
|
{ |
||||||
|
unsigned sz = 0; |
||||||
|
unsigned char buf[128]; |
||||||
|
unsigned char *p; |
||||||
|
|
||||||
|
/* Read in the first 128 bytes of the device */ |
||||||
|
buf[0] = ASMI_READ_BYTES; |
||||||
|
buf[1] = 0; |
||||||
|
buf[2] = 0; |
||||||
|
buf[3] = 0; |
||||||
|
|
||||||
|
asmi_cs (1); |
||||||
|
asmi_snd (buf,4); |
||||||
|
asmi_rrcv (buf, sizeof(buf)); |
||||||
|
asmi_cs (0); |
||||||
|
|
||||||
|
/* Search for the starting 0x6a which is followed by the
|
||||||
|
* 4-byte 'register' and 4-byte bit-count. |
||||||
|
*/ |
||||||
|
p = buf; |
||||||
|
while (p < buf + sizeof(buf)-8) { |
||||||
|
if ( *p == 0x6a ) { |
||||||
|
/* Point to bit count and extract */ |
||||||
|
p += 5; |
||||||
|
sz = *p++; |
||||||
|
sz |= *p++ << 8; |
||||||
|
sz |= *p++ << 16; |
||||||
|
sz |= *p++ << 24; |
||||||
|
/* Convert to byte count */ |
||||||
|
sz += 7; |
||||||
|
sz >>= 3; |
||||||
|
} else if (*p == 0xff) { |
||||||
|
/* 0xff is ok ... just skip */ |
||||||
|
p++; |
||||||
|
continue; |
||||||
|
} else { |
||||||
|
/* Not 0xff or 0x6a ... something's not
|
||||||
|
* right ... report 'unknown' (sz=0). |
||||||
|
*/ |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return (sz); |
||||||
|
} |
||||||
|
|
||||||
|
static int asmi_erase (unsigned start, unsigned end) |
||||||
|
{ |
||||||
|
unsigned off, sectsz; |
||||||
|
unsigned char buf[4]; |
||||||
|
struct asmi_devinfo_t *dev = asmi_dev_find (); |
||||||
|
|
||||||
|
if (!dev || (start>end)) |
||||||
|
return (-1); |
||||||
|
|
||||||
|
/* Erase the requested sectors. An address is required
|
||||||
|
* that lies within the requested sector -- we'll just |
||||||
|
* use the first address in the sector. |
||||||
|
*/ |
||||||
|
printf ("asmi erasing sector %d ", start); |
||||||
|
if (start != end) |
||||||
|
printf ("to %d ", end); |
||||||
|
sectsz = (1 << dev->sz_sect); |
||||||
|
while (start <= end) { |
||||||
|
off = start * sectsz; |
||||||
|
start++; |
||||||
|
|
||||||
|
buf[0] = ASMI_ERASE_SECT; |
||||||
|
buf[1] = off >> 16; |
||||||
|
buf[2] = off >> 8; |
||||||
|
buf[3] = off; |
||||||
|
|
||||||
|
asmi_wr_enable (); |
||||||
|
asmi_cs (1); |
||||||
|
asmi_snd (buf,4); |
||||||
|
asmi_cs (0); |
||||||
|
|
||||||
|
printf ("."); /* Some user feedback */ |
||||||
|
|
||||||
|
/* Wait for erase to complete */ |
||||||
|
while (asmi_status_rd() & ASMI_STATUS_WIP) |
||||||
|
; |
||||||
|
} |
||||||
|
printf (" done.\n"); |
||||||
|
return (0); |
||||||
|
} |
||||||
|
|
||||||
|
static int asmi_read (ulong addr, ulong off, ulong cnt) |
||||||
|
{ |
||||||
|
unsigned char buf[4]; |
||||||
|
|
||||||
|
buf[0] = ASMI_READ_BYTES; |
||||||
|
buf[1] = off >> 16; |
||||||
|
buf[2] = off >> 8; |
||||||
|
buf[3] = off; |
||||||
|
|
||||||
|
asmi_cs (1); |
||||||
|
asmi_snd (buf,4); |
||||||
|
asmi_rrcv ((unsigned char *)addr, cnt); |
||||||
|
asmi_cs (0); |
||||||
|
|
||||||
|
return (0); |
||||||
|
} |
||||||
|
|
||||||
|
static |
||||||
|
int asmi_write (ulong addr, ulong off, ulong cnt) |
||||||
|
{ |
||||||
|
ulong wrcnt; |
||||||
|
unsigned pgsz; |
||||||
|
unsigned char buf[4]; |
||||||
|
struct asmi_devinfo_t *dev = asmi_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] = 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); |
||||||
|
} |
||||||
|
|
||||||
|
static |
||||||
|
int 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 |
||||||
|
***********************************************************************/ |
||||||
|
static |
||||||
|
void 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; |
||||||
|
} |
||||||
|
|
||||||
|
static |
||||||
|
void 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; |
||||||
|
} |
||||||
|
|
||||||
|
static |
||||||
|
void 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; |
||||||
|
} |
||||||
|
|
||||||
|
static |
||||||
|
void 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; |
||||||
|
} |
||||||
|
|
||||||
|
static |
||||||
|
void 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; |
||||||
|
} |
||||||
|
|
||||||
|
static |
||||||
|
void 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 */ |
@ -1,133 +0,0 @@ |
|||||||
#ifndef __CRAMFS_FS_H |
|
||||||
#define __CRAMFS_FS_H |
|
||||||
|
|
||||||
/* Uncompression interfaces to the underlying zlib */ |
|
||||||
int cramfs_uncompress_block (void *dst, void *src, int srclen); |
|
||||||
int cramfs_uncompress_init (void); |
|
||||||
|
|
||||||
#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */ |
|
||||||
#define CRAMFS_SIGNATURE "Compressed ROMFS" |
|
||||||
|
|
||||||
/*
|
|
||||||
* Width of various bitfields in struct cramfs_inode. |
|
||||||
* Primarily used to generate warnings in mkcramfs. |
|
||||||
*/ |
|
||||||
#define CRAMFS_MODE_WIDTH 16 |
|
||||||
#define CRAMFS_UID_WIDTH 16 |
|
||||||
#define CRAMFS_SIZE_WIDTH 24 |
|
||||||
#define CRAMFS_GID_WIDTH 8 |
|
||||||
#define CRAMFS_NAMELEN_WIDTH 6 |
|
||||||
#define CRAMFS_OFFSET_WIDTH 26 |
|
||||||
|
|
||||||
/*
|
|
||||||
* Since inode.namelen is a unsigned 6-bit number, the maximum cramfs |
|
||||||
* path length is 63 << 2 = 252. |
|
||||||
*/ |
|
||||||
#define CRAMFS_MAXPATHLEN (((1 << CRAMFS_NAMELEN_WIDTH) - 1) << 2) |
|
||||||
|
|
||||||
/*
|
|
||||||
* Reasonably terse representation of the inode data. |
|
||||||
*/ |
|
||||||
struct cramfs_inode { |
|
||||||
u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH; |
|
||||||
/* SIZE for device files is i_rdev */ |
|
||||||
u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH; |
|
||||||
/* NAMELEN is the length of the file name, divided by 4 and
|
|
||||||
rounded up. (cramfs doesn't support hard links.) */ |
|
||||||
/* OFFSET: For symlinks and non-empty regular files, this
|
|
||||||
contains the offset (divided by 4) of the file data in |
|
||||||
compressed form (starting with an array of block pointers; |
|
||||||
see README). For non-empty directories it is the offset |
|
||||||
(divided by 4) of the inode of the first file in that |
|
||||||
directory. For anything else, offset is zero. */ |
|
||||||
u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH; |
|
||||||
}; |
|
||||||
|
|
||||||
struct cramfs_info { |
|
||||||
u32 crc; |
|
||||||
u32 edition; |
|
||||||
u32 blocks; |
|
||||||
u32 files; |
|
||||||
}; |
|
||||||
|
|
||||||
/*
|
|
||||||
* Superblock information at the beginning of the FS. |
|
||||||
*/ |
|
||||||
struct cramfs_super { |
|
||||||
u32 magic; /* 0x28cd3d45 - random number */ |
|
||||||
u32 size; /* length in bytes */ |
|
||||||
u32 flags; /* feature flags */ |
|
||||||
u32 future; /* reserved for future use */ |
|
||||||
u8 signature[16]; /* "Compressed ROMFS" */ |
|
||||||
struct cramfs_info fsid; /* unique filesystem info */ |
|
||||||
u8 name[16]; /* user-defined name */ |
|
||||||
struct cramfs_inode root; /* root inode data */ |
|
||||||
}; |
|
||||||
|
|
||||||
/*
|
|
||||||
* Feature flags |
|
||||||
* |
|
||||||
* 0x00000000 - 0x000000ff: features that work for all past kernels |
|
||||||
* 0x00000100 - 0xffffffff: features that don't work for past kernels |
|
||||||
*/ |
|
||||||
#define CRAMFS_FLAG_FSID_VERSION_2 0x00000001 /* fsid version #2 */ |
|
||||||
#define CRAMFS_FLAG_SORTED_DIRS 0x00000002 /* sorted dirs */ |
|
||||||
#define CRAMFS_FLAG_HOLES 0x00000100 /* support for holes */ |
|
||||||
#define CRAMFS_FLAG_WRONG_SIGNATURE 0x00000200 /* reserved */ |
|
||||||
#define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET 0x00000400 /* shifted root fs */ |
|
||||||
|
|
||||||
/*
|
|
||||||
* Valid values in super.flags. Currently we refuse to mount |
|
||||||
* if (flags & ~CRAMFS_SUPPORTED_FLAGS). Maybe that should be |
|
||||||
* changed to test super.future instead. |
|
||||||
*/ |
|
||||||
#define CRAMFS_SUPPORTED_FLAGS ( 0x000000ff \ |
|
||||||
| CRAMFS_FLAG_HOLES \
|
|
||||||
| CRAMFS_FLAG_WRONG_SIGNATURE \
|
|
||||||
| CRAMFS_FLAG_SHIFTED_ROOT_OFFSET ) |
|
||||||
|
|
||||||
/*
|
|
||||||
* Since cramfs is little-endian, provide macros to swab the bitfields. |
|
||||||
*/ |
|
||||||
|
|
||||||
#ifndef __BYTE_ORDER |
|
||||||
#if defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN) |
|
||||||
#define __BYTE_ORDER __LITTLE_ENDIAN |
|
||||||
#elif defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN) |
|
||||||
#define __BYTE_ORDER __BIG_ENDIAN |
|
||||||
#else |
|
||||||
#error "unable to define __BYTE_ORDER" |
|
||||||
#endif |
|
||||||
#endif /* not __BYTE_ORDER */ |
|
||||||
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN |
|
||||||
#define CRAMFS_16(x) (x) |
|
||||||
#define CRAMFS_24(x) (x) |
|
||||||
#define CRAMFS_32(x) (x) |
|
||||||
#define CRAMFS_GET_NAMELEN(x) ((x)->namelen) |
|
||||||
#define CRAMFS_GET_OFFSET(x) ((x)->offset) |
|
||||||
#define CRAMFS_SET_OFFSET(x,y) ((x)->offset = (y)) |
|
||||||
#define CRAMFS_SET_NAMELEN(x,y) ((x)->namelen = (y)) |
|
||||||
#elif __BYTE_ORDER == __BIG_ENDIAN |
|
||||||
#ifdef __KERNEL__ |
|
||||||
#define CRAMFS_16(x) swab16(x) |
|
||||||
#define CRAMFS_24(x) ((swab32(x)) >> 8) |
|
||||||
#define CRAMFS_32(x) swab32(x) |
|
||||||
#else /* not __KERNEL__ */ |
|
||||||
#define CRAMFS_16(x) bswap_16(x) |
|
||||||
#define CRAMFS_24(x) ((bswap_32(x)) >> 8) |
|
||||||
#define CRAMFS_32(x) bswap_32(x) |
|
||||||
#endif /* not __KERNEL__ */ |
|
||||||
#define CRAMFS_GET_NAMELEN(x) (((u8*)(x))[8] & 0x3f) |
|
||||||
#define CRAMFS_GET_OFFSET(x) ((CRAMFS_24(((u32*)(x))[2] & 0xffffff) << 2) |\ |
|
||||||
((((u32*)(x))[2] & 0xc0000000) >> 30)) |
|
||||||
#define CRAMFS_SET_NAMELEN(x,y) (((u8*)(x))[8] = (((0x3f & (y))) | \ |
|
||||||
(0xc0 & ((u8*)(x))[8]))) |
|
||||||
#define CRAMFS_SET_OFFSET(x,y) (((u32*)(x))[2] = (((y) & 3) << 30) | \ |
|
||||||
CRAMFS_24((((y) & 0x03ffffff) >> 2)) | \
|
|
||||||
(((u32)(((u8*)(x))[8] & 0x3f)) << 24)) |
|
||||||
#else |
|
||||||
#error "__BYTE_ORDER must be __LITTLE_ENDIAN or __BIG_ENDIAN" |
|
||||||
#endif |
|
||||||
|
|
||||||
#endif /* not __CRAMFS_FS_H */ |
|
@ -0,0 +1,53 @@ |
|||||||
|
/*
|
||||||
|
* A collection of structures, addresses, and values associated with |
||||||
|
* the Motorola DUET ADS board. Values common to all FADS family boards |
||||||
|
* are in board/fads/fads.h |
||||||
|
* |
||||||
|
* Copyright (C) 2003 Arabella Software Ltd. |
||||||
|
* Yuli Barcohen <yuli@arabellasw.com> |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __CONFIG_H |
||||||
|
#define __CONFIG_H |
||||||
|
|
||||||
|
/* Board type */ |
||||||
|
#define CONFIG_DUET_ADS 1 /* Duet (MPC87x/88x) ADS */ |
||||||
|
#define CONFIG_FADS 1 /* We are FADS compatible (more or less) */ |
||||||
|
|
||||||
|
#define CONFIG_MPC885 1 /* MPC885 CPU (Duet family) */ |
||||||
|
|
||||||
|
#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */ |
||||||
|
#undef CONFIG_8xx_CONS_SMC2 |
||||||
|
#undef CONFIG_8xx_CONS_NONE |
||||||
|
#define CONFIG_BAUDRATE 38400 |
||||||
|
|
||||||
|
#define CFG_8XX_FACT 5 /* Multiply by 5 */ |
||||||
|
#define CFG_8XX_XIN 10000000 /* 10 MHz in */ |
||||||
|
|
||||||
|
#define CONFIG_SDRAM_50MHZ 1 |
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* PLPRCR - PLL, Low-Power, and Reset Control Register 14-22 |
||||||
|
*----------------------------------------------------------------------- |
||||||
|
* set the PLL, the low-power modes and the reset control |
||||||
|
*/ |
||||||
|
#define CFG_PLPRCR ((CFG_8XX_FACT << PLPRCR_MFI_SHIFT) | PLPRCR_TEXPS) |
||||||
|
|
||||||
|
#include "fads.h" |
||||||
|
|
||||||
|
#define CFG_PHYDEV_ADDR (BCSR_ADDR + 0x20000) |
||||||
|
|
||||||
|
#define CFG_OR5_PRELIM 0xFFFF8110 /* 64Kbyte address space */ |
||||||
|
#define CFG_BR5_PRELIM (CFG_PHYDEV_ADDR | BR_PS_8 | BR_V) |
||||||
|
|
||||||
|
#define BCSR5 (CFG_PHYDEV_ADDR + 0x300) |
||||||
|
|
||||||
|
#define BCSR5_MII2_EN 0x40 |
||||||
|
#define BCSR5_MII2_RST 0x20 |
||||||
|
#define BCSR5_T1_RST 0x10 |
||||||
|
#define BCSR5_ATM155_RST 0x08 |
||||||
|
#define BCSR5_ATM25_RST 0x04 |
||||||
|
#define BCSR5_MII1_EN 0x02 |
||||||
|
#define BCSR5_MII1_RST 0x01 |
||||||
|
|
||||||
|
#endif /* __CONFIG_H */ |
Loading…
Reference in new issue