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

📄 intel28f320_8x4.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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);
		

⌨️ 快捷键说明

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