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

📄 flash.c

📁 source code of armboot for s3c4510
💻 C
字号:
/* * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger <mgroeger@sysgo.de> * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include "armboot.h"#if defined (AM29LV160D) || defined (HY29LV320B)#define FLASH_BANK_SIZE 0x200000#define MAIN_SECT_SIZE  0x10000#define PARAM_SECT_SIZE 0x2000#define INIT_SECT_SIZE  0x4000  /* for AMD29LV160DB */#define MIDDLE_SECT_SIZE 0x8000 /* for AMD29LV160DB */#endif#ifdef K8B1616UBA#define FLASH_BANK_SIZE 0x200000#define MAIN_SECT_SIZE  0x10000#define PARAM_SECT_SIZE 0x2000#endif#if defined(AM29LV320D) || defined(AT49BV321)#define FLASH_BANK_SIZE 0x400000#define MAIN_SECT_SIZE  0x10000#define PARAM_SECT_SIZE 0x2000#endif#ifdef SST39VF160#define FLASH_BANK_SIZE 0x200000#define MAIN_SECT_SIZE  0x10000//#define PARAM_SECT_SIZE 0x800#define PARAM_SECT_SIZE 0x1000#endifflash_info_t    flash_info[CFG_MAX_FLASH_BANKS];/*----------------------------------------------------------------------- */ulong flash_init(bd_t *bd){    int i, j;    ulong size = 0;        for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)    {#if defined (AM29LV160D) || defined (HY29LV320B)    	ulong flashbase = 0;#if defined(MBM29LV160BE)    	flash_info[i].flash_id = (FUJ_MANUFACT & FLASH_VENDMASK) |(FUJ_ID_MBM29LV160BE & FLASH_TYPEMASK);#elif defined(M29W160DB)    	flash_info[i].flash_id = (ST_MANUFACT & FLASH_VENDMASK) |(ST_ID_M29W160DB & FLASH_TYPEMASK);#elif defined(HY29LV320B)    	flash_info[i].flash_id = (HYNIX_MANUFACT & FLASH_VENDMASK) |(HYNIX_ID_HY29LV320B & FLASH_TYPEMASK);#else    	flash_info[i].flash_id = (AMD_MANUFACT & FLASH_VENDMASK) |(AMD_ID_LV160D & FLASH_TYPEMASK);#endif    	flash_info[i].size = FLASH_BANK_SIZE;		flash_info[i].sector_count = CFG_MAX_FLASH_SECT;		memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);			 	flashbase = PHYS_FLASH_1;		for (j = 0; j < flash_info[i].sector_count; j++)        {			if(j <= 1)				flash_info[i].start[j] = flashbase + j * INIT_SECT_SIZE;			else if ((2 <= j)&&(j <= 3))				flash_info[i].start[j] = flashbase + (j+1) * PARAM_SECT_SIZE;			else				flash_info[i].start[j] = flashbase + (j-3)*MAIN_SECT_SIZE;		}		size += flash_info[i].size;#else     	ulong flashbase = 0;#if defined(K8B1616UBA)    	flash_info[i].flash_id = (SAMSUNG_MANUFACT & FLASH_VENDMASK) |(SAMSUNG_ID_K8B1616UBA & FLASH_TYPEMASK);#elif defined(AM29LV320D)    	flash_info[i].flash_id = (AMD_MANUFACT & FLASH_VENDMASK) |(AMD_ID_LV320DB & FLASH_TYPEMASK);#elif defined(AT49BV321)    	flash_info[i].flash_id = (ATMEL_MANUFACT & FLASH_VENDMASK) |(ATMEL_ID_AT49BV321 & FLASH_TYPEMASK);#elif defined(SST39VF160)    	flash_info[i].flash_id = (SST_MANUFACT & FLASH_VENDMASK) |(SST_ID_xF160A & FLASH_TYPEMASK);#endif				flash_info[i].size = FLASH_BANK_SIZE;		flash_info[i].sector_count = CFG_MAX_FLASH_SECT;		memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);			 	flashbase = PHYS_FLASH_1;	 	for (j = 0; j < flash_info[i].sector_count; j++)		{#ifdef SST39VF160	    	if (j <= 15)#else			if (j <= 7)#endif	    	{				flash_info[i].start[j] = flashbase + j * PARAM_SECT_SIZE;							}	    	else	    	{#ifdef SST39VF160				flash_info[i].start[j] = flashbase + (j - 15)*MAIN_SECT_SIZE;#else				flash_info[i].start[j] = flashbase + (j - 7)*MAIN_SECT_SIZE;#endif	   	 	}		}		size += flash_info[i].size;#endif	}               /* Protect monitor and environment sectors     */    flash_protect(FLAG_PROTECT_SET,		  CFG_FLASH_BASE,		  CFG_FLASH_BASE +_armboot_end - _armboot_start,		  &flash_info[0]);        flash_protect(FLAG_PROTECT_SET,		  CFG_ENV_ADDR,		  CFG_ENV_ADDR + CFG_ENV_SIZE - 1,		  &flash_info[0]);        return size;}/*----------------------------------------------------------------------- */void flash_print_info  (flash_info_t *info){    int i;    switch (info->flash_id & FLASH_VENDMASK)    {    	case (SAMSUNG_MANUFACT & FLASH_VENDMASK):		printf("SAMSUNG : ");		break;    	case (AMD_MANUFACT & FLASH_VENDMASK):		printf("AMD : ");		break;    	case (ATMEL_MANUFACT & FLASH_VENDMASK):		printf("ATMEL : ");		break;    	case (FUJ_MANUFACT & FLASH_VENDMASK):		printf("FUJITSU : ");		break;    	case (SST_MANUFACT & FLASH_VENDMASK):		printf("SST : ");		break;    	case (HYNIX_MANUFACT & FLASH_VENDMASK):		printf("HYNIX : ");		break;    	default:		printf("Unknown Vendor ");		break;    }        switch (info->flash_id & FLASH_TYPEMASK)    {    	case (SAMSUNG_ID_K8B1616UBA & FLASH_TYPEMASK):		printf("K8B1616UBA\n");		break;    	case (AMD_ID_LV320DB & FLASH_TYPEMASK):		printf("AM29LV320D\n");		break;    	case (ATMEL_ID_AT49BV321 & FLASH_TYPEMASK):		printf("AT49BV321\n");		break;#if defined(MBM29LV160BE)    	case (FUJ_ID_MBM29LV160BE & FLASH_TYPEMASK):		printf("MBM29LV160BE\n");		break;#elif defined(M29W160DB)    	case (ST_ID_M29W160DB & FLASH_TYPEMASK):		printf("M29W160DB\n");		break;#else    			case (AMD_ID_LV160D & FLASH_TYPEMASK):		printf("AM29LV160D\n");		break;#endif    	case (SST_ID_xF160A & FLASH_TYPEMASK):		printf("SST39VF160\n");		break;    	case (HYNIX_ID_HY29LV320B & FLASH_TYPEMASK):		printf("HY29LV320B\n");		break;    	default:		printf("Unknown Chip Type\n");		goto Done;		break;    }        printf("  Size: %ld MB in %d Sectors\n",info->size >> 20, info->sector_count);        printf("  Sector Start Addresses:");    for (i = 0; i < info->sector_count; i++)    {		if ((i % 5) == 0)		{	    	printf ("\n   ");		}		printf (" %08lX%s", info->start[i],			info->protect[i] ? " (RO)" : "     ");    }    printf ("\n");    Done:}void Delay1Sec(unsigned int nSec){	unsigned int i; 	while(nSec--)	{		printf("\n");		i=200000; 		while(i--) ;	}		}void Delay1(unsigned int nSec){	unsigned int i; 	while(nSec--)	{		i=20; 		while(i--) ;	}		}void FlashDelay(unsigned int  nusecs){	unsigned long j, k, i=0x1234;	while(nusecs--)	{		for (j=0; j<30; j++)			k = j * i;	}}/*----------------------------------------------------------------------- */int	flash_erase (flash_info_t *info, int s_first, int s_last){    int flag, prot, sect;    int rc = ERR_OK;           if (info->flash_id == FLASH_UNKNOWN)    	return ERR_UNKNOWN_FLASH_TYPE;    if ((s_first < 0) || (s_first > s_last))    	return ERR_INVAL;        //if ((info->flash_id & FLASH_VENDMASK) !=(SAMSUNG_MANUFACT & FLASH_VENDMASK))    //	return ERR_UNKNOWN_FLASH_VENDOR;        prot = 0;        for (sect=s_first; sect<=s_last; ++sect)    {		if (info->protect[sect])			prot++;		    }    if (prot)    {    	return ERR_PROTECTED;    }    /*      * Disable interrupts which might cause a timeout     * here. Remember that our exception vectors are     * at address 0 in the flash, and we don't want a     * (ticker) exception to happen while the flash     * chip is in programming mode.     */    flag = disable_interrupts();    /* Start erase on unprotected sectors */    for (sect = s_first; sect<=s_last && !ctrlc(); sect++)    {    	unsigned short	*Flash;		unsigned long	temp;		unsigned long	temp_E;		unsigned long	SectorAddr;		Flash = (unsigned short *)(CFG_FLASH_BASE);		    	printf("Erasing sector %2d ... ", sect);    	/* arm simple, non interrupt dependent timer */		/*reset_timer_masked();*/    	Delay1(5);    	SectorAddr = flash_info[0].start[sect];	/* total address */    #ifdef SST39VF160		if(sect < 16)		{			*(Flash+0x5555) = 0xAA;    		Delay1(1);    		*(Flash+0x2AAA) = 0x55;    		Delay1(1);			*(Flash+0x5555) = 0x80;			Delay1(1);			*(Flash+0x5555) = 0xAA;			Delay1(1);			*(Flash+0x2AAA) = 0x55;			Delay1(1);					*((volatile unsigned short *)(SectorAddr)) = 0x30;		}		else		{			*(Flash+0x5555) = 0xAA;    		Delay1(1);    		*(Flash+0x2AAA) = 0x55;    		Delay1(1);			*(Flash+0x5555) = 0x80;			Delay1(1);			*(Flash+0x5555) = 0xAA;			Delay1(1);			*(Flash+0x2AAA) = 0x55;			Delay1(1);					*((volatile unsigned short *)(SectorAddr)) = 0x50;		}#else				*(Flash+0x555) = 0xAA;    	Delay1(1);    	*(Flash+0x2AA) = 0x55;    	Delay1(1);		*(Flash+0x555) = 0x80;		Delay1(1);		*(Flash+0x555) = 0xAA;		Delay1(1);		*(Flash+0x2AA) = 0x55;		Delay1(1);				*((volatile unsigned short *)(SectorAddr)) = 0x30;#endif		temp_E = SectorAddr;		Delay1Sec(1);		temp = (*((volatile unsigned short *)(temp_E)) & 0x00FF);		while( temp != 0x00FF )		{			temp = (*((volatile unsigned short *)(temp_E)) & 0x00FF);		}		*((volatile unsigned short *)(CFG_FLASH_BASE)) = 0xF0;    	}    if (ctrlc())      printf("User Interrupt!\n");        #if 0outahere:       /* allow flash to settle - wait 10 ms */    udelay_masked(10000);       if (flag)      enable_interrupts();   #endif       return rc;}/*----------------------------------------------------------------------- * Copy memory to flash */static int write_word (flash_info_t *info, ulong dest, ushort data){    /*vulong *addr = (vulong *)dest;*/    unsigned short *addr;    u16 barf;    int rc = ERR_OK;    int flag;    	unsigned short	*Flash;	addr = (unsigned short *)(dest) ;    flag = disable_interrupts();    Flash = (unsigned short *)CFG_FLASH_BASE;#ifdef SST39VF160	*(Flash+0x5555) = 0xAA;	Delay1(1);	*(Flash+0x2AAA) = 0x55;	Delay1(1);	*(Flash+0x5555) = 0xA0;	Delay1(1);#else	*(Flash+0x555) = 0xAA;	Delay1(1);	*(Flash+0x2AA) = 0x55;	Delay1(1);	*(Flash+0x555) = 0xA0;	Delay1(1);#endif	*addr = (unsigned short)data;		FlashDelay(10);	*((unsigned short *)(CFG_FLASH_BASE)) = 0xF0;           /* arm simple, non interrupt dependent timer */    reset_timer_masked();      /* wait while polling the status register */    #if 0	if (get_timer_masked() > CFG_FLASH_WRITE_TOUT)	{	   	rc = ERR_TIMOUT;	   	Log(DEBUG,"ZZZ");	   	return rc;	}	#endif		if(FlashCompareData((unsigned int)dest, dest, 1))	{		barf = *addr;		printf("\nFlash write error %lx at address %lx\n",(u32)barf, dest);		rc = ERR_PROG_ERROR;		return rc;	}    return rc;    }/*----------------------------------------------------------------------- * Copy memory to flash. */int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt){    ulong cp, wp;    int l;    int i, rc;    ushort data=0;        wp = (addr & ~3);	/* get lower word aligned address */           /*     * handle unaligned start bytes     */    if ((l = addr - wp) != 0)    {    	data = 0;		for (i=0, cp=wp; i<l; ++i, ++cp)		    data = (data >> 8) | (*(uchar *)cp << 24);				for (; i<4 && cnt>0; ++i)		{	    	data = (data >> 8) | (*src++ << 24);	    	--cnt;	    	++cp;		}				for (; cnt==0 && i<4; ++i, ++cp)	    	data = (data >> 8) | (*(uchar *)cp << 24);					if ((rc = write_word(info, wp, data)) != 0)	    	return (rc);			wp += 4;    }        /*     * handle word aligned part     */    while (cnt >= 2)    {    	data = *((unsigned short *)src);    	if ((rc = write_word(info, addr, data)) != 0)			return (rc);		src += 2;		addr  += 2;		cnt -= 2;	}        if (cnt == 0)		return ERR_OK;            /*     * handle unaligned tail bytes     */    data = 0;    for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp)    {		data = (data >> 8) | (*src++ << 24);		--cnt;    }    for (; i<4; ++i, ++cp)		data = (data >> 8) | (*(uchar *)cp << 24);        return write_word(info, wp, data);}//--------------------------------------------------------------------------////  FlashCompareData: compare Flash to DRAM                                      ////                                                                          ////--------------------------------------------------------------------------//int FlashCompareData( unsigned int BaseAddr, unsigned int SrcAddr, unsigned int SrcSize ){	unsigned short	*src, *tgt;	unsigned int		i;	unsigned int		size;	src   = (unsigned short *)SrcAddr;	tgt   = (unsigned short *)BaseAddr;	size  = SrcSize/sizeof(unsigned short);	for ( i=0; i<size; i++, src++, tgt++ ) 	{		if ( *tgt != *src ) 		{			printf("\n>> Data Compare Error!\n");			return(ERR_PROG_ERROR);		}		}	return(ERR_OK);}

⌨️ 快捷键说明

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