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

📄 flash.c

📁 Linux2.4.27在AT91RM9200下的U-BOOT代码。可以在Redhat9等版本下使用。适合ARM学习者使用。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (C) Copyright 2001 * Wolfgang Denk, DENX Software Engineering, wd@denx.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 <common.h>#include <mpc8xx.h>#include <flash.h>flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*//*----------------------------------------------------------------------- * Functions */ulong flash_recognize (vu_long *base);int write_word (flash_info_t *info, ulong dest, ulong data);void flash_get_geometry (vu_long *base, flash_info_t *info);void flash_unprotect(flash_info_t *info);int _flash_real_protect(flash_info_t *info, long idx, int on);unsigned long flash_init (void){	volatile immap_t	*immap  = (immap_t *)CFG_IMMR;	volatile memctl8xx_t	*memctl = &immap->im_memctl;	int i;	int rec;	for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {		flash_info[i].flash_id = FLASH_UNKNOWN;	}	*((vu_short*)CFG_FLASH_BASE) = 0xffff;	flash_get_geometry ((vu_long*)CFG_FLASH_BASE, &flash_info[0]);	/* Remap FLASH according to real size */	memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-flash_info[0].size & 0xFFFF8000);	memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) |		(memctl->memc_br0 & ~(BR_BA_MSK));	rec = flash_recognize((vu_long*)CFG_FLASH_BASE);	if (rec == FLASH_UNKNOWN) {		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",				flash_info[0].size, flash_info[0].size<<20);	}#if CFG_FLASH_PROTECTION	/*Unprotect all the flash memory*/	flash_unprotect(&flash_info[0]);#endif	*((vu_short*)CFG_FLASH_BASE) = 0xffff;	return (flash_info[0].size);#if CFG_MONITOR_BASE >= CFG_FLASH_BASE	/* monitor protection ON by default */	flash_protect(FLAG_PROTECT_SET,		      CFG_MONITOR_BASE,		      CFG_MONITOR_BASE+monitor_flash_len-1,		      &flash_info[0]);#endif#ifdef	CFG_ENV_IS_IN_FLASH	/* ENV protection ON by default */	flash_protect(FLAG_PROTECT_SET,		      CFG_ENV_OFFSET,		      CFG_ENV_OFFSET+CFG_ENV_SIZE-1,		      &flash_info[0]);#endif	return (flash_info[0].size);}int flash_get_protect_status(flash_info_t * info, long idx){	vu_short * base;	ushort res;#ifdef DEBUG	printf("\n Attempting to set protection info with %d sectors\n", info->sector_count);#endif	base = (vu_short*)info->start[idx];	*(base) = 0xffff;	*(base + 0x55) = 0x0098;	res = base[0x2];	*(base) = 0xffff;	if(res != 0)		res = 1;	else		res = 0;	return res;}void flash_get_geometry (vu_long *base, flash_info_t *info){	int i,j;	ulong ner = 0;	vu_short * sb  = (vu_short*)base;	ulong offset = (ulong)base;	/* Read Device geometry */	*sb = 0xffff;	*sb = 0x0090;	info->flash_id = ((ulong)base[0x0]);#ifdef DEBUG	printf("Id is %x\n", (uint)(ulong)info->flash_id);#endif	*sb = 0xffff;	*(sb+0x55) = 0x0098;	info->size = 1 << (sb[0x27]); /* Read flash size */#ifdef DEBUG	printf("Size is %x\n", (uint)(ulong)info->size);#endif	*sb = 0xffff;	*(sb + 0x55) = 0x0098;	ner = sb[0x2c] ; /*Number of erase regions*/#ifdef DEBUG	printf("Number of erase regions %x\n", (uint)ner);#endif	info->sector_count = 0;	for(i = 0; i < ner; i++)	{		uint s;		uint count;		uint t1,t2,t3,t4;		*sb = 0xffff;		*(sb + 0x55) = 0x0098;		t1 = sb[0x2d + i*4];		t2 = sb[0x2e + i*4];		t3 = sb[0x2f + i*4];		t4 = sb[0x30 + i*4];		count = ((t1 & 0x00ff) | (((t2 & 0x00ff) << 8) & 0xff00) )+ 1; /*sector count*/		s = ((t3 & 0x00ff) | (((t4 & 0x00ff) << 8) & 0xff00)) * 256;; /*Sector size*/#ifdef DEBUG		printf("count and size %x, %x\n", count, s);		printf("sector count for erase region %d is %d\n", i, count);#endif		for(j = 0; j < count; j++)		{#ifdef DEBUG			printf("%x, ", (uint)offset);#endif			info->start[ info->sector_count + j] = offset;			offset += s;		}		info->sector_count += count;	}	if ((offset - (ulong)base) != info->size)		printf("WARNING reported size %x does not match to calculted size %x.\n"				, (uint)info->size, (uint)(offset - (ulong)base) );	/* Next check if there are any sectors protected.*/	for(i = 0; i < info->sector_count; i++)		info->protect[i] = flash_get_protect_status(info, i);	*sb = 0xffff;}/*----------------------------------------------------------------------- */void flash_print_info  (flash_info_t *info){	int i;	if (info->flash_id == FLASH_UNKNOWN) {		printf ("missing or unknown FLASH type\n");		return ;	}	switch (info->flash_id & FLASH_VENDMASK) {	case INTEL_MANUFACT & FLASH_VENDMASK:		printf ("Intel ");		break;	default:		printf ("Unknown Vendor ");		break;	}	switch (info->flash_id & FLASH_TYPEMASK) {	case INTEL_ID_28F320C3B & FLASH_TYPEMASK:		printf ("28F320RC3(4 MB)\n");		break;	case INTEL_ID_28F320J3A:		printf("28F320J3A (4 MB)\n");		break;	default:		printf ("Unknown Chip Type\n");			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 % 4) == 0)			printf ("\n   ");		printf ("  %02d %08lX%s",			i, info->start[i],			info->protect[i]!=0 ? " (RO)" : "     "		);	}	printf ("\n");	return ;}ulong flash_recognize (vu_long *base){	ulong id;	ulong res = FLASH_UNKNOWN;	vu_short * sb = (vu_short*)base;	*sb = 0xffff;	*sb = 0x0090;	id = base[0];	switch (id & 0x00FF0000)	{		case (MT_MANUFACT & 0x00FF0000):	/* MT or => Intel */		case (INTEL_ALT_MANU & 0x00FF0000):		res = FLASH_MAN_INTEL;		break;	default:		res = FLASH_UNKNOWN;	}	*sb = 0xffff;	return res;}/*-----------------------------------------------------------------------*/#define INTEL_FLASH_STATUS_BLS	0x02#define INTEL_FLASH_STATUS_PSS	0x04#define INTEL_FLASH_STATUS_VPPS	0x08#define INTEL_FLASH_STATUS_PS	0x10#define INTEL_FLASH_STATUS_ES	0x20#define INTEL_FLASH_STATUS_ESS	0x40#define INTEL_FLASH_STATUS_WSMS	0x80int	flash_decode_status_bits(char status){	int err = 0;	if(!(status & INTEL_FLASH_STATUS_WSMS)) {		printf("Busy\n");		err = -1;	}	if(status & INTEL_FLASH_STATUS_ESS) {		printf("Erase suspended\n");		err = -1;	}	if(status & INTEL_FLASH_STATUS_ES) {		printf("Error in block erase\n");		err = -1;	}	if(status & INTEL_FLASH_STATUS_PS) {		printf("Error in programming\n");		err = -1;	}	if(status & INTEL_FLASH_STATUS_VPPS) {		printf("Vpp low, operation aborted\n");		err = -1;	}	if(status & INTEL_FLASH_STATUS_PSS) {		printf("Program is suspended\n");		err = -1;	}	if(status & INTEL_FLASH_STATUS_BLS) {		printf("Attempting to program/erase a locked sector\n");		err = -1;	}	if((status & INTEL_FLASH_STATUS_PS) &&	   (status & INTEL_FLASH_STATUS_ES) &&	   (status & INTEL_FLASH_STATUS_ESS)) {		printf("A command sequence error\n");		return -1;	}	return err;}/*----------------------------------------------------------------------- */int	flash_erase (flash_info_t *info, int s_first, int s_last){	vu_short *addr;	int flag, prot, sect;	ulong start, now;	int rcode = 0;	if ((s_first < 0) || (s_first > s_last)) {		if (info->flash_id == FLASH_UNKNOWN) {

⌨️ 快捷键说明

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