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

📄 s29gl064a90.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
*
* Arguments  : start_addr       is the start byte address.
*              data             is the data pointer.
*              number           is the data of number to be read. It is counted by half-words.
*
* Return     : none.
*
* Note(s)    : 
*********************************************************************************************
*/
void NorFlashRdData(int start_addr, unsigned short *data, int number)
{
    int i;	
#if 1	
    /* The read array command */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    PIF_START();
    rPIF_PCMCIA_DATA = NOR_FLASH_RD_ARRAY;
    
    PifWaitTillDone();           // Wait till the first cycle complete
 #endif   
    NorFlashRd(start_addr, data, number);    	
}

/*
*********************************************************************************************
*                                       NorFlashRdDataBurst
*
* Description: read the data from the specified address.
*
* Arguments  : start_addr       is the start byte address.
*              data             is the data pointer.
*              number           is the data of number to be read. It is counted by half-words.
*                               Maximum is 2047. 
*
* Return     : none.
*
* Note(s)    : 
*********************************************************************************************
*/
void NorFlashRdDataBurst(int start_addr, unsigned short *data, int number)
{
    int i;	
	
#if 0	
    /* The read array command */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    PIF_START();
    rPIF_PCMCIA_DATA = NOR_FLASH_RD_ARRAY;
    
    PifWaitTillDone();           // Wait till the first cycle complete
 #endif   
    
    NorFlashRd1(start_addr, data, number);    	
}

/*
*********************************************************************************************
*                                       NorFlashRd1
*
* Description: read the data from the specified address.
*
* Arguments  : start_addr       is the start byte address.
*              data             is the data pointer.
*              number           is the data of number to be read. Counted by unsigned short integers.
*
* Return     : none.
*
* Note(s)    : number should be less than 2047.
*********************************************************************************************
*/
void NorFlashRd1(int start_addr, unsigned short *data, int number)
{
    unsigned int i, tmp, iN, word_number;	
    
    start_addr = start_addr * 1;
  	
    //number &= 0x7ff;         // Maxium of byte length of the transfer is 4096 bytes
    if(number & 0x1) {
        word_number = number/2 + 1;
    } else
        word_number = number/2;     	
    
    iN = 0;

    PIF_READ_SET();
    rPIF_PCI_LEN = number * 2;     // rPIF_PCI_LEN is counted by bytes.
    rPIF_PCI_DEV_A = start_addr;   // the byte address
    PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);    
    PIF_START();
    
    for(i = 0; i < word_number; i++) {
        tmp = rPIF_PCMCIA_DATA;	
        *data++ = tmp & 0xffff;
        iN++;
        if (iN == number)
            break;
        *data++ = (tmp >> 16);
        iN++;
    }
}

/*
*********************************************************************************************
*                                       NorFlashRd
*
* Description: read the data from the specified address.
*
* Arguments  : start_addr       is the start byte address.
*              data             is the data pointer.
*              number           is the data of number to be read. It is counted by half-words.
*
* Return     : none.
*
* Note(s)    : 
*********************************************************************************************
*/
void NorFlashRd(int start_addr, unsigned short *data, int number)
{
    unsigned int i, tmp;	        

//printf("NoFlashRd: start_addr = 0x%x, data_add = 0x%x, number = %d \n",start_addr,data,number);
    start_addr = start_addr * 1;

    PIF_READ_SET();
    rPIF_PCI_LEN = 2;          // rPIF_PCI_LEN is counted by bytes.  	
        
    for(i = 0; i < number; i++) {
    	rPIF_PCI_DEV_A = start_addr;    // the byte address
    	start_addr += 2;	    	
	PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);    
    	PIF_START();    	
        *data++ = rPIF_PCMCIA_DATA;	        
    }
}

/* S29GL064A90_16x1_erase():
 * Erase sector 'snum'.
 * Return 0 if success, else negative.
 */
int
S29GL064A90_16x1_erase(struct flashinfo *fdev,int snum)
{
		unsigned int status;
		int i;
	
		//printf("S29GL064A90_16x1_erase erase block %d \n",snum);
    	
    /* the first cycle of block erase */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    rPIF_PCI_DEV_A = 0xaaa;    // the byte address
    
    PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);    
    PIF_START();
    rPIF_PCMCIA_DATA = 0xaa;
    PifWaitTillDone();         // Wait till the first cycle complete

    /* the second cycle of block erase */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    rPIF_PCI_DEV_A = 0x554;    // the byte address
    
    PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);    
    PIF_START();
    rPIF_PCMCIA_DATA = 0x55;
    PifWaitTillDone();         // Wait till the first cycle complete
    
    /* the third cycle of block erase */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    rPIF_PCI_DEV_A = 0xaaa;    // the byte address
    
    PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);    
    PIF_START();
    rPIF_PCMCIA_DATA = 0x80;
    PifWaitTillDone();         // Wait till the first cycle complete

    /* the fourth cycle of block erase */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    rPIF_PCI_DEV_A = 0xaaa;    // the byte address
    
    PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);    
    PIF_START();
    rPIF_PCMCIA_DATA = 0xaa;
    PifWaitTillDone();         // Wait till the first cycle complete

    /* the fifth cycle of block erase */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    rPIF_PCI_DEV_A = 0x554;    // the byte address
    
    PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);    
    PIF_START();
    rPIF_PCMCIA_DATA = 0x55;
    PifWaitTillDone();         // Wait till the first cycle complete

    /* the sixth cycle of block erase */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    //rPIF_PCI_DEV_A = block_no * NOR_FLASH_BYTES_PER_SECTOR ;    // the byte address
    rPIF_PCI_DEV_A = fdev->sectors[snum].begin;    // the byte address
    
    PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);    
    PIF_START();
    rPIF_PCMCIA_DATA = 0x30;  //30 -> 50
    PifWaitTillDone();         // Wait till the first cycle complete


    status = 0x0;
    while(!(status & 0x80)) {     // Flash is busy?
        NorFlashRd(rPIF_PCI_DEV_A, &status, 1);
    }
   // printf("Erase OK Status %d  !\r\n", status);    	
/*    
    status = 0x0;
    for(i=0; i< 40; i++)
    {
        NorFlashRd(fdev->sectors[snum].begin+i, &status, 1);
        printf("%x ",status);
        if(i&0xf == 0)
        	printf("\n");
        status = 0x0;
      }    
*/	
    //if(status & 0x20)             // Whether the SR4 or SR5 is set
    //    return FAILED;
    return SUCCESSFUL;
}

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

int
S29GL064A90_16x1_write(struct flashinfo *fdev,uchar *dest,uchar *src,
	long bytecnt)
{
	int		i,addr,step,process;
	unsigned short	*data;
	uchar	temp;

	addr = dest;
	data = (unsigned short *)src;

	step = bytecnt/100;
	process = 0;
	
	for(i = 0; i < bytecnt/2 + 1; i ++) {
		NorFlashProg(addr, *data);
		//printf("After program\r\n");
		/* Flash program setup command */
		addr +=2;
		data++;

		if(i>=process)
		{
			putchar('*');
			process += step;
		}
	}
	printf("Write %d byte OK!\r\n",bytecnt);
	
}

int
S29GL064A90_16x1_read(struct flashinfo *fdev,uchar *dest,uchar *src,
	long bytecnt)
{
	int		i,addr;
	unsigned short	*data;

	 addr = src;
	 //printf("flash read srcaddr == %x \n",addr);
	NorFlashRdData(addr ,(unsigned short *)dest, bytecnt/2 +1);	
}

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

	return 0;//stone debug
	
}

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

/* S29GL064A90_16x1_lock():
 */

int
S29GL064A90_16x1_lock(struct flashinfo *fdev,int snum,int operation)
{

	return 0;//stone debug
	
}

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

/* S29GL064A90_16x1_type():
 * Run the AUTOSELECT algorithm to retrieve the manufacturer and
 * device id of the flash.
 */
int
S29GL064A90_16x1_type(struct flashinfo *fdev)
{
	WORD	man, dev,block_lock_cfg;
//stone add
	NorFlashPifInit();
	fdev->id = NorFlashRdID();
	return((int)(fdev->id));

}

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

/**************************************************************************
 **************************************************************************
 *
 * The remainder of the code in this file can be included if the
 * target configuration is such that this 28F640 device is the only
 * real flash device in the system that is to be visible to the monitor.
 *
 **************************************************************************
 **************************************************************************
 */
#ifdef SINGLE_FLASH_DEVICE

/* FlashNamId[]:
 * Used to correlate between the ID and a string representing the name
 * of the flash device.
 * Note that this table (and the case statement in FlashBankInit())
 * allow a 28F128 flash ID to sneak by... This is to allow a 28F128
 * device to be put in the footprint of a 28F640, but with the upper
 * half of the device inaccessible (some CSB360 boards).
 */
struct flashdesc FlashNamId[] = {
	{ INTEL_28F640,			"INTEL-28F640" },
	{ ST_M58LW064D,			"SGS_THOMPSON-M58LW064D" },
	{ INTEL_DT28F640J5,		"INTEL-DT28F640J5" },
	{ INTEL_DT28F128J5,		"INTEL-28F128 (half)" },
	{ S29GL128M90,			"SPANSION S29GL128M90"},
	{ SST39VF3201,			"SST39VF3201"},
	{ S29GL064A90, "S29GL064A90"},
	{ 0, 0 },
};

int
FlashBankInit(struct flashinfo *fbnk,int snum)
{
	uchar	*saddr,*tmp;
	int		i, msize;
	struct	sectorinfo *sinfotbl;
	unsigned short *data = 0xa0300000;
	
	/* Based on the flash bank ID returned, load a sector count and a
	 * sector size-information table...
	 */
	flashtype(fbnk);
	switch(fbnk->id) {
		case ST_M58LW064D:
		case INTEL_28F640:
		case INTEL_DT28F640J5:
			fbnk->sectorcnt = 64;
			break;
		case INTEL_DT28F128J5:	
		case ST_M25P64:
			fbnk->sectorcnt = 128;
			break;
//		case S29GL128M90:
//			fbnk->sectorcnt = 256;
//			break;
		case SST39VF3201:											//jason add 
			fbnk->sectorcnt = 64;
//			printf("SST39VF3201 flash program: flashid is %08lx\n", fbnk->id);
			break;
	  case S29GL064A90:											//jason add 
			fbnk->sectorcnt = 128;
//			printf("S29GL064A90 flash program: flashid is %08lx\n", fbnk->id);
			break;
		default:
			printf("Unrecognized flashid: 0x%08lx\n",fbnk->id);
			return(-1);
			break;
	}

	/* Create the per-sector information table.  The size of the table
	 * depends on the number of sectors in the device...
	 */
	if (fbnk->sectors)
		free((char *)fbnk->sectors);
	msize = fbnk->sectorcnt * (sizeof(struct sectorinfo));
	sinfotbl = (struct sectorinfo *)malloc(msize);
	if (!sinfotbl) {
		printf("Can't allocate space for flash sector information\n");
		return(-1);
	}
	fbnk->sectors = sinfotbl;

	/* Using the above-determined sector count, build the sector
	 * information table as part of the flash-bank structure.  For
	 * this set of devices, all sectors are the same size (0x20000).
	 */
	saddr = fbnk->base;
	for(i=0;i<fbnk->sectorcnt;i++) {
		fbnk->sectors[i].snum = snum+i;
		fbnk->sectors[i].size = NOR_FLASH_BYTES_PER_SECTOR;
		fbnk->sectors[i].begin = saddr;
		fbnk->sectors[i].end =
		    fbnk->sectors[i].begin + fbnk->sectors[i].size - 1;
		if(i ==fbnk->sectorcnt ) 
			{
				fbnk->sectors[i].protected = 1;
			} 
		else{  
				fbnk->sectors[i].protected = 0;
			}
		saddr += NOR_FLASH_BYTES_PER_SECTOR;
	}
	fbnk->end = saddr-1;
	
	return(fbnk->sectorcnt);
}

/* FlashInit():
 * Initialize data structures for each bank of flash...
 */
int
FlashInit(void)
{
	int		snum;
	struct	flashinfo *fbnk;
 	
	snum = 0;
	FlashCurrentBank = 0;

	fbnk = &FlashBank[0];
	//printf("flash init \n");
	fbnk->device_name = malloc(20);
	//printf("get device name\n");
	strcpy(fbnk->device_name, "nor");
	boot_device_name = fbnk->device_name;
	//printf("boot device name =  %s\n",boot_device_name);
	fbnk->base = (unsigned char *)FLASH_BANK0_BASE_ADDR;
	fbnk->width = FLASH_BANK0_WIDTH;

	fbnk->fltype = S29GL064A90_16x1_type;
	fbnk->flerase = S29GL064A90_16x1_erase;
	fbnk->flwrite = S29GL064A90_16x1_write;
	fbnk->flread = S29GL064A90_16x1_read;
	fbnk->flewrite = S29GL064A90_16x1_ewrite;
	fbnk->fllock = S29GL064A90_16x1_lock;

	snum += FlashBankInit(fbnk,snum);

	sectorProtect(FLASH_PROTECT_RANGE,1);
	return(0);
}

#endif	/* SINGLE_FLASH_DEVICE */

#endif
#endif

⌨️ 快捷键说明

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