⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intel28f256_8x1.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* intel28f256_8x1.c:
 * Support for a single INTEL 28f256 device configured in 8-bit mode.
 */
#include "config.h"
#if INCLUDE_FLASH
#include "stddefs.h"
#include "genlib.h"
#include "cpu.h"
#include "flash.h"
#include "intel28f256_8x1.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		32
#define BUFFER_ALIGN	0x1f

#define DEV_WIDTH		1

#define WSMS			0x80
#define ESS				0x40
#define ES				0x20
#define PSS				0x04
#define PS				0x10
#define WBS				0x80

#define	ftype		    volatile unsigned char

/* Manufacturer and device id... */
#define DEVICE_28F320J3		0x00890016		/* 32  Mbit (3 volt strata) */
#define DEVICE_28F640J3		0x00890017		/* 64  Mbit (3 volt strata) */
#define DEVICE_28F128J3		0x00890018		/* 128 Mbit (3 volt strata) */
#define DEVICE_28F256J3		0x0089001d		/* 256 Mbit (3 volt strata) */

/* INTEL_STRATA-Specific Macros...
 */
#define STRATACMD_READARRAY()			(*(ftype *)(fdev->base) = 0xff)
#define STRATACMD_PROTPROGRAM()			(*(ftype *)(fdev->base) = 0xc0)
#define STRATACMD_READID()				(*(ftype *)(fdev->base) = 0x90)
#define STRATACMD_READSTATUS()			(*(ftype *)(fdev->base) = 0x70)
#define STRATACMD_LOCKBIT()				(*(ftype *)(fdev->base) = 0x60)
#define STRATACMD_CLEARSTATUS()			(*(ftype *)(fdev->base) = 0x50)
#define STRATACMD_PROGRAM(addr)			(*(ftype *)(addr) = 0x40)
#define STRATACMD_WRITETOBUFFER(addr)	(*(ftype *)(addr) = 0xe8)
#define STRATACMD_CONFIRM(addr)			(*(ftype *)(addr) = 0xd0)
#define STRATACMD_BLOCKERASE(addr)		(*(ftype *)(addr) = 0x20)
#define STRATACMD_SETLOCKCONFIRM(addr)	(*(ftype *)(addr) = 0x01)

/* 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+4))
#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 != 0xff) { \
			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))

/* Intel28f256_8x1_erase():
 * Erase the sector specified by snum.
 * Return 0 if success, else negative to indicate some failure.
 */
int
Intel28f256_8x1_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);
}

/* EndIntel28f256_8x1_erase():
 * Function place holder to determine the end of the above function.
 */
void
EndIntel28f256_8x1_erase(void)
{}

int
Intel28f256_8x1_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)-byte blocks; hence, the
	 * low 5 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.*/
		bcount = size-1;
		*(ftype *)block = bcount; 
        

		/* Write the buffer data...
		 */
		for(i = 0; i < size; i++) 
        {
			FLASH_WRITE(aligndest,(&buf[i]));
			aligndest+=1;
		}
		
		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);
}

/* EndIntel28f256_8x1_write():
 * Function place holder to determine the end of the above function.
 */
void
EndIntel28f256_8x1_write(void)
{}

/* Intel28f256_8x1_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
Intel28f256_8x1_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++) 
    {

		/* Flash program setup command */
		STRATACMD_PROGRAM(dest);
		
		/* Write the value */
		FLASH_WRITE(dest,src);

		WAIT_FOR_WSMS_READY();

		STRATACMD_READARRAY();

		WAIT_FOR_DATA(dest,src);

		++dest;
		++src;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -