?? intel28f320_8x4.c
字號(hào):
/* intel28f320_8x4.c:
* Support for INTEL 28f320 devices each configured in 8-bit mode
* and 4 devices in parallel.
*/
#include "config.h"
#if INCLUDE_FLASH
#include "stddefs.h"
#include "genlib.h"
#include "cpu.h"
#include "flash.h"
#include "intel28f320_8x4.h"
#define SR_WAIT 50000
/* Strata flash buffer info:
* Each device can buffer 32 bytes.
* In this configuration we have 4 devices in parallel;
* hence, 128 byte buffering...
*/
#define BUFFER_SIZE 128
#define BUFFER_ALIGN 0x7f
#define DEV_WIDTH 4
#define WSMS 0x80808080
#define ESS 0x40404040
#define ES 0x20202020
#define PSS 0x04040404
#define PS 0x10101010
#define WBS 0x80808080
#define ftype volatile unsigned long
/* Manufacturer and device id... */
#define DEVICE_28F320J3 0x16161616 /* 32 Mbit (3 volt strata) */
#define DEVICE_28F640J3 0x17171717 /* 64 Mbit (3 volt strata) */
#define DEVICE_28F128J3 0x18181818 /* 128 Mbit (3 volt strata) */
/* INTEL_STRATA-Specific Macros...
*/
#define STRATACMD_READARRAY() (*(ftype *)(fdev->base) = 0xffffffff)
#define STRATACMD_PROTPROGRAM() (*(ftype *)(fdev->base) = 0xc0c0c0c0)
#define STRATACMD_READID() (*(ftype *)(fdev->base) = 0x90909090)
#define STRATACMD_READSTATUS() (*(ftype *)(fdev->base) = 0x70707070)
#define STRATACMD_LOCKBIT() (*(ftype *)(fdev->base) = 0x60606060)
#define STRATACMD_CLEARSTATUS() (*(ftype *)(fdev->base) = 0x50505050)
#define STRATACMD_PROGRAM(addr) (*(ftype *)(addr) = 0x40404040)
#define STRATACMD_WRITETOBUFFER(addr) (*(ftype *)(addr) = 0xe8e8e8e8)
#define STRATACMD_CONFIRM(addr) (*(ftype *)(addr) = 0xd0d0d0d0)
#define STRATACMD_BLOCKERASE(addr) (*(ftype *)(addr) = 0x20202020)
#define STRATACMD_SETLOCKCONFIRM(addr) (*(ftype *)(addr) = 0x01010101)
/* General Macros...
*/
#define FLASH_READ(addr) (*(ftype *)(addr))
#define FLASH_READBASE() (*(ftype *)(fdev->base))
#define FLASH_READ_MANUFACTURER() (*(ftype *)(fdev->base))
#define FLASH_READ_DEVICEID() (*(ftype *)(fdev->base+8))
#define FLASH_READ_BLOCKSTATUS(sbase) (*(ftype *)(sbase+16))
#define FLASH_WRITE(to,frm) (*(ftype *)(to) = *(ftype *)(frm))
#define WAIT_FOR_DATA(add,data) \
{ \
volatile int timeout = FLASH_LOOP_TIMEOUT; \
while(*(ftype *)add != *(ftype *)data) { \
if (--timeout <= 0) { \
STRATACMD_READARRAY(); \
return(-2); \
} \
WATCHDOG_MACRO; \
} \
}
#define WAIT_FOR_FF(add) \
{ \
volatile int timeout = FLASH_LOOP_TIMEOUT; \
while(*(ftype *)add != 0xffffffff) { \
if (--timeout <= 0) { \
STRATACMD_READARRAY(); \
return(-3); \
} \
WATCHDOG_MACRO; \
} \
}
#define WAIT_FOR_WSMS_READY() \
{ \
volatile int timeout = FLASH_LOOP_TIMEOUT; \
while((*(ftype *)(fdev->base) & WSMS) != WSMS) { \
if (--timeout <= 0) { \
STRATACMD_READARRAY(); \
return(-4); \
} \
WATCHDOG_MACRO; \
} \
}
#define ERASE_FAILURE() (*(ftype *)(fdev->base) & (ESS|ES|PS))
/* Intel28f320_8x4_erase():
* Erase the sector specified by snum.
* Return 0 if success, else negative to indicate some failure.
*/
int
Intel28f320_8x4_erase(struct flashinfo *fdev,int snum)
{
STRATACMD_CLEARSTATUS();
/* Issue the setup/confirm sequence: */
STRATACMD_BLOCKERASE(fdev->base);
STRATACMD_CONFIRM(fdev->sectors[snum].begin);
/* Wait for sector erase to complete by polling RSR... */
WAIT_FOR_WSMS_READY();
if (ERASE_FAILURE()) {
STRATACMD_READARRAY();
return(-1);
}
STRATACMD_READARRAY();
WAIT_FOR_FF(fdev->sectors[snum].begin);
return(0);
}
/* EndIntel28f320_8x4_erase():
* Function place holder to determine the end of the above function.
*/
void
EndIntel28f320_8x4_erase(void)
{}
int
Intel28f320_8x4_write(struct flashinfo *fdev,uchar *dest,uchar *src,
long bytecnt)
{
volatile int tot;
ulong bcount;
int i, j, giveup, aligntot, size;
volatile uchar buf[BUFFER_SIZE], *aligndest, *block, *destend;
/* The write buffer can only be used on (32*4)-byte blocks; hence, the
* low 7 bits of the destination must be zero at the start of a
* buffer write. This means that we must align the destination
* address on this boundary. To do this, we decrement the destination
* address until the alignment is reached, then load that space with
* the same data that is already there.
*/
destend = dest + bytecnt;
aligntot = 0;
aligndest = dest;
while(((ulong)aligndest & BUFFER_ALIGN) != 0) {
aligndest--;
aligntot++;
bytecnt++;
}
tot = 0;
while(tot < bytecnt) {
size = bytecnt - tot;
if (size > BUFFER_SIZE)
size = BUFFER_SIZE;
block = aligndest;
/* Copy buffer's worth of data into local buffer just in
* case the source is this flash device.
*/
for(i=0;i<size;i++) {
if (aligndest < dest)
buf[i] = *aligndest++;
else
buf[i] = *src++;
}
j = 0;
while (size < BUFFER_SIZE) {
size++;
buf[i++] = destend[j++];
}
aligndest = block;
/* Issue request to write to the buffer, then poll extended
* status register to wait for availability.
*/
giveup = SR_WAIT;
do {
STRATACMD_WRITETOBUFFER(aligndest);
giveup--;
} while (((FLASH_READ(aligndest) & WBS) != WBS) && (giveup > 0));
if (giveup == 0) {
STRATACMD_READARRAY();
return(-1);
}
/* Write the byte count. Notice that the bytecount fed to the
* device is one less than the actual count. Plus, in this case,
* the count is written into each byte because we are interfacing
* to 4 devices in parallel...
*/
bcount = (size-4)/4;
*(ftype *)block = bcount | (bcount << 8) |
(bcount << 16) | (bcount << 24);
/* Write the buffer data...
*/
for(i=0;i<size;i+=DEV_WIDTH) {
FLASH_WRITE(aligndest,(&buf[i]));
aligndest+=DEV_WIDTH;
}
STRATACMD_CONFIRM(block);
tot += size;
giveup = SR_WAIT;
do {
STRATACMD_READSTATUS();
giveup--;
} while(((FLASH_READBASE() & WSMS) != WSMS) && (giveup > 0));
if (giveup == 0) {
STRATACMD_READARRAY();
return(-2);
}
STRATACMD_READARRAY();
}
return(0);
}
/* EndIntel28f320_8x4_write():
* Function place holder to determine the end of the above function.
*/
void
EndIntel28f320_8x4_write(void)
{}
/* Intel28f320_8x4_ewrite():
* Erase all sectors that are part of the address space to be written,
* then write the data to that address space. This is basically a
* concatenation of the above erase & write done in one step. This is
* necessary primarily for re-writing the bootcode; because after the boot
* code is erased, there is nowhere to return so the re-write must be done
* while executing out of ram also. It is only needed in systems that are
* executing the monitor out of the same device that is being updated.
*/
int
Intel28f320_8x4_ewrite(struct flashinfo *fdev,uchar *destA,uchar *srcA,
long bytecnt)
{
ulong addr;
volatile int sector, i;
void (*reset)();
volatile uchar *src, *dest;
src = srcA;
dest = destA;
STRATACMD_CLEARSTATUS();
/* For each sector, if it overlaps any of the destination space */
/* then erase that sector. */
for (sector = 0; sector < fdev->sectorcnt; sector++) {
if ((((uchar *)dest) > (fdev->sectors[sector].end)) ||
(((uchar *)dest+bytecnt-1) < (fdev->sectors[sector].begin))) {
continue;
}
addr = (ulong)(fdev->sectors[sector].begin);
/* Issue the ERASE setup/confirm sequence: */
STRATACMD_BLOCKERASE(addr);
STRATACMD_CONFIRM(addr);
/* Wait for sector erase to complete by polling RSR... */
WAIT_FOR_WSMS_READY();
STRATACMD_READARRAY();
WAIT_FOR_FF(addr);
}
for(i = 0; i < bytecnt; i += DEV_WIDTH) {
/* Flash program setup command */
STRATACMD_PROGRAM(dest);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -