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

📄 intel28f128_8x1.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* intel28f128_8x1.c:
 * Support for INTEL 28f128 configured as an 8-bit wide device.
 */
#include "config.h"
#if INCLUDE_FLASH
#include "stddefs.h"
#include "genlib.h"
#include "cpu.h"
#include "flash.h"
#include "intel28f128_8x1.h"

extern struct flashinfo	Fdev;
extern int FlashProtectWindow;

#define	ftype		    volatile unsigned char

/* Strata flash buffer info:
 */
#define BUFFER_SIZE		32
#define BUFFER_ALIGN	0x1f

/* Status register definitions:
 */
#define WSMS	0x80	/* Wait state machine status 1=ready */
#define ESS		0x40	/* Erase suspend status 1=suspended */
#define ECLBS	0x20	/* Erase/clear lock bit status 1=error */
#define PSLBS	0x10	/* Program/set lock bit status 1=error */
#define VPENS	0x08	/* Programming voltage status 1=error */
#define PSS		0x04	/* Program suspend status 1=suspended */
#define DPS		0x02	/* Device protect status 1=lock detected */
#define WBS		0x80	/* Write buffer status 1=available */

/* INTEL_STRATA-Specific Macros...
 */
#define STRATACMD_READARRAY()				(*(ftype *)(fdev->base) = 0xff)
#define STRATACMD_PROTPROGRAM()				(*(ftype *)(fdev->base) = 0xc0)
#define STRATACMD_READQUERY()				(*(ftype *)(fdev->base) = 0x98)
#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()					(*(ftype *)(fdev->base) = 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)
#define STRATA_BUFFERBYTECOUNT(addr,val)	(*(ftype *)(addr) = val)

/* General Macros...
 */
#define FLASH_WRITE(to,frm)				(*(ftype *)(to) = *(ftype *)(frm))
#define FLASH_READ(addr)				(*(ftype *)(addr))
#define FLASH_READBASE()				(*(ftype *)(fdev->base))
#define NOT_EQUAL(p1,p2)				(*(ftype *)(p1) != *(ftype *)(p2))
#define WAIT_FOR_WRITE(add,data)		while(*(ftype *)add != *(ftype *)data)
#define NOTERASED_32(a)					(a != 0xffffffff)

/* Intel28f128_8x1_erase():
 * Based on the 'snum' value, erase the appropriate sector(s).
 * Return 0 if success, else -1.
 */
int
Intel28f128_8x1_erase(struct flashinfo *fdev,int snum)
{
	struct	sectorinfo *sip;
	int		ret, sector;

	ret = 0;

	/* Erase the request sector(s):
	 */
	for (sector=0; sector < fdev->sectorcnt; sector++) {
		sip = &fdev->sectors[sector];
		if ((!FlashProtectWindow) && (sip->protected)) {
			continue;
		}
		if ((snum == ALL_SECTORS) || (snum == sector)) {
			register ulong *lp, *lp1;
			int	noterased;

			/* Avoid issuing the erase command if the sector is already
			 * erased...
			 */
			noterased = 0;
			lp = (ulong *)fdev->sectors[sector].begin; 
			lp1 = (ulong *)((char *)lp + sip->size - 1); 
			while(lp <= lp1) {
				if (NOTERASED_32(*lp++)) {
					noterased = 1;
					break;
				}
			}
			if (noterased) {
				/* Issue the ERASE setup/confirm sequence...
				 */
				STRATACMD_BLOCKERASE(sip->begin);
				STRATACMD_CONFIRM(sip->begin);

				/* Device automatically outputs status after the
				 * above sequence, so now poll status waiting for
				 * completion of the erase...
				 */
				do {
					STRATACMD_READSTATUS();
				} while((FLASH_READBASE() & WSMS) == 0);

				/* Clear status register and go to read-array mode.
				 */
				STRATACMD_CLEARSTATUS();
				STRATACMD_READARRAY();	
				while(NOTERASED_32(*(ulong *)(sip->begin)));
			}
			if (ret == -1)
				break;
		}
	}
	return(ret);
}

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

int
Intel28f128_8x1_write(struct flashinfo *fdev,uchar *dest,uchar *src,
	long bytecnt)
{
	volatile int	tot, ret;
	int				i, giveup, aligntot, size;
	volatile uchar	buf[BUFFER_SIZE], *aligndest, *block;

	/* 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.
	 */ 
	aligntot = 0;
	aligndest = dest;
	while(((ulong)aligndest & BUFFER_ALIGN) != 0) {
		aligndest--;
		aligntot++;
		bytecnt++;
	}

	ret = tot = 0;
	while((tot < bytecnt) && (ret == 0)) {
		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++;
		}
		aligndest = block;
    
		/* Issue request to write to the buffer, then poll extended
		 * status register to wait for availability.
		 */
		giveup = 10000000;
		do {
			STRATACMD_WRITETOBUFFER(aligndest);	
			giveup--;
		} while (((FLASH_READ(aligndest) & WBS) == 0) && (giveup > 0));
		if (giveup == 0) {
			ret = -2;
			break;
		}
                
		/* Write the byte count...  Notice that the bytecount fed to the
		 * device is one less than the actual count. 
		 */
		STRATA_BUFFERBYTECOUNT(block,size-1);

		/* Write the buffer data...
		 */
		for(i=0;i<size;i++) {
			FLASH_WRITE(aligndest,&buf[i]);
			aligndest++;
		}
		
		STRATACMD_CONFIRM(block);
		tot += size;

		do {
			STRATACMD_READSTATUS();
		} while((FLASH_READBASE() & WSMS) == 0);

		STRATACMD_READARRAY();	
	}
	return(ret);
}

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

/* Intel28f128_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
Intel28f128_8x1_ewrite(struct flashinfo *fdev,uchar *destA,uchar *srcA,
	int bytecnt)
{
	int	    sector, i;
	void	(*reset)();
	uchar   *src, *dest;
	struct	sectorinfo *sip;

	src = srcA;
	dest = destA;
	STRATACMD_CLEARSTATUS();
	STRATACMD_READARRAY();

	/* For each sector, if it overlaps any of the destination space
	 * then erase that sector.
	 */
	for (sector = 0; sector < fdev->sectorcnt; sector++) {
		sip = &fdev->sectors[sector];

		if ((((uchar *)dest) > (sip->end)) ||
		    (((uchar *)dest+bytecnt-1) < (sip->begin))) {
			continue;
		}

		/* Issue the ERASE setup/confirm sequence...
		 */
		STRATACMD_BLOCKERASE(sip->begin);
		STRATACMD_CONFIRM(sip->begin);

		/* Device automatically outputs status after the
		 * above sequence, so now poll status waiting for
		 * completion of the erase...
		 */
		do {
			STRATACMD_READSTATUS();
		} while((FLASH_READBASE() & WSMS) == 0);

		/* Clear status register and go to read-array mode.
		 */
		STRATACMD_CLEARSTATUS();
		STRATACMD_READARRAY();	
		while(NOTERASED_32(*(ulong *)(sip->begin)));
	}

	for(i = 0; i < bytecnt; i++) {
		
		/* Program sequence...
		 */
		STRATACMD_PROGRAM();
		FLASH_WRITE(dest,src);

		/* Wait for write to complete by polling RSR...
		 */
		do {
			STRATACMD_READSTATUS();	
		} while((FLASH_READBASE() & WSMS) == 0);

		STRATACMD_CLEARSTATUS();	

		do {
			STRATACMD_READARRAY();	
		} WAIT_FOR_WRITE(dest,src);		

		dest++;
		src++;
	}
	
	/* Now that the re-programming of flash is complete, reset: */
	reset = RESETFUNC();
	reset();

	return(0);	/* won't get here */
}

⌨️ 快捷键说明

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