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

📄 flash.c.svn-base

📁 board type like smdk2443 ARM920T processor
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/* * (C) Copyright 2001 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net * * (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 <environment.h>#include <linux/byteorder/swab.h>flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	// info for FLASH chips// Board support for 1 or 2 flash devices#define fwr16(addr, data)		*(volatile ushort *)addr = (ushort)data#define frd16(addr)				*(volatile ushort *)addr#define fwr32(addr, data)		*(volatile ulong *)addr = (ulong)data#define frd32(addr)				*(volatile ulong *)addr#define nGCS0_AMD			1#define READY				1#define ERR					2#define TMO					4int nGCS0_is_amd = nGCS0_AMD;/*----------------------------------------------------------------------- * Functions ------------------------------------------------------------------------*/void start_flash_info_print(flash_info_t *info);static ulong flash_get_size (void *addr, flash_info_t *info);static int write_data (flash_info_t *info, ulong dest, ulong data);static int intel_write_data (flash_info_t *info, ulong dest, ulong data);static int amd_write_data (flash_info_t *info, ulong dest, ushort data);static void flash_get_offsets (ulong base, flash_info_t *info);/*-----------------------------------------------------------------------*/unsigned long flash_init (void){	int i;	ulong size = 0;	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {		switch (i) {		case 0:			flash_get_size ((void *) PHYS_FLASH_1, &flash_info[i]);			flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);			break;		case 1:#if !CONFIG_NAND_BOOT			if(nGCS0_is_amd == nGCS0_AMD){				flash_get_size ((void *) PHYS_FLASH_2, &flash_info[i]);				flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);			}else{				flash_get_size ((void *) PHYS_FLASH_3, &flash_info[i]);				flash_get_offsets (PHYS_FLASH_3, &flash_info[i]);			}#else			if(flash_get_size((void *) PHYS_FLASH_2, &flash_info[i]) != 0){				flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);			}else{				flash_get_size((void *) PHYS_FLASH_3, &flash_info[i]);				flash_get_offsets (PHYS_FLASH_3, &flash_info[i]);			}#endif			break;		default:			panic ("configured too many flash banks!\n");			break;		}		size += flash_info[i].size;	}//	if(flash_get_size((void *) PHYS_FLASH_2, &flash_info[0]) != 0){//		flash_get_offsets (PHYS_FLASH_2, &flash_info[0]);//	}else{//		flash_get_size((void *) PHYS_FLASH_3, &flash_info[0]);//		flash_get_offsets (PHYS_FLASH_3, &flash_info[0]);//	}	// Protect monitor and environment sectors 	flash_protect ( FLAG_PROTECT_SET,			CFG_FLASH_BASE,			CFG_FLASH_BASE + monitor_flash_len - 1,			&flash_info[0] );	if((flash_info[0].flash_id & FLASH_VENDMASK)== FLASH_MAN_AMD){		switch(flash_info[0].flash_id & FLASH_TYPEMASK){			case FLASH_AM400T:			case FLASH_AM400B:			case FLASH_AM800T:			case FLASH_AM800B:				flash_protect ( FLAG_PROTECT_SET, AMD_CFG_ENV_ADDR,					AMD_CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );				break;			default:				break;		}	}else if((flash_info[0].flash_id & FLASH_VENDMASK)== FLASH_MAN_INTEL){		switch(flash_info[0].flash_id & FLASH_TYPEMASK){			case FLASH_28F320J3A:			case FLASH_28F640J3A:			case FLASH_28F128J3A:				flash_protect ( FLAG_PROTECT_SET, INTEL_CFG_ENV_ADDR,					INTEL_CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );				break;			default:				break;		}	}	for(i = 0; i < CFG_MAX_FLASH_BANKS; i++){		printf("Bank # %d => [",i);		start_flash_info_print(&flash_info[i]);		printf("]\n");	}	return size;}/*-----------------------------------------------------------------------*/void start_flash_info_print(flash_info_t *info){	if (info->flash_id == FLASH_UNKNOWN) {        printf ("missing or unknown FLASH type");        return;    }	switch (info->flash_id & FLASH_VENDMASK) {		case FLASH_MAN_INTEL:			if(info->base_addr == PHYS_FLASH_1)				printf("<nGCS0:0x00000000> = ");			else				printf("<nGCS1:0x08000000> = ");			printf("INTEL-"); break;		case FLASH_MAN_AMD:			if(info->base_addr == PHYS_FLASH_1)				printf("<nGCS0:0x00000000> = ");			else				printf("<nGCS4:0x20000000> = ");			printf("AMD-"); break;		default:			printf("Unknown Vendor ");	break;	}	switch (info->flash_id & FLASH_TYPEMASK) {		case FLASH_AM400T:			printf("AM29LV400BT , %d KB", info->size>>10); 			break;		case FLASH_AM400B:			printf("AM29LV400BB , %d KB", info->size>>10); break;		case FLASH_AM800T:			printf("AM29LV800BT , %d KB", info->size>>10); break;		case FLASH_AM800B:			printf("AM29LV800BB , %d KB", info->size>>10); break;		case FLASH_28F320J3A:			printf("28F320J3A , %d MB", info->size>>20); break;		case FLASH_28F640J3A:			printf("28F640J3A , %d MB", info->size>>20); break;		case FLASH_28F128J3A:			printf("28F128J3A , %d MB", info->size>>20); break;		default:			printf("Unknown Chip Type");	break;	}		return;}/*-----------------------------------------------------------------------*/static void flash_get_offsets (ulong base, flash_info_t *info){	int i;	if (info->flash_id == FLASH_UNKNOWN) {		return;	}	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {		switch(info->flash_id & FLASH_TYPEMASK){			case FLASH_AM400T:			case FLASH_AM400B:			case FLASH_AM800T:			case FLASH_AM800B:				for (i = 0; i < info->sector_count; i++) {					if(i==0)		info->start[i] = base;					if(i==1)		info->start[i] = base+0x4000;					if(i==2)		info->start[i] = base+0x6000;					if(i==3)		info->start[i] = base+0x8000;						if(i>=4)	info->start[i] = base + ((i-3) * AMD_FLASH_SECT_SIZE);					info->protect[i] = 0;				}				break;			default://				printf("Unknown AMD chip, chip ID = 0x%x\n", info->flash_id & FLASH_TYPEMASK);				return;		}	}else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {		switch(info->flash_id & FLASH_TYPEMASK){			case FLASH_28F320J3A:			case FLASH_28F640J3A:			case FLASH_28F128J3A:				for (i = 0; i < info->sector_count; i++) {					info->start[i] = base + (i * INTEL_FLASH_SECT_SIZE);					info->protect[i] = 0;				}				break;			default://				printf("Unknown INTEL chip, chip ID = 0x%x\n", info->flash_id & FLASH_TYPEMASK);				return;		}	}}/*-----------------------------------------------------------------------*/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 FLASH_MAN_INTEL:		printf ("INTEL ");		break;	case FLASH_MAN_AMD:		printf("AMD ");		break;	default:		printf ("Unknown Vendor ");		break;	}	switch (info->flash_id & FLASH_TYPEMASK) {	case FLASH_AM400T:		printf("AM29LV400BT\n");		break;	case FLASH_AM400B:        printf("AM29LV400BB\n");        break;	case FLASH_AM800T:        printf("AM29LV800BT\n");        break;	case FLASH_AM800B:        printf("AM29LV800BB\n");        break;	case FLASH_28F320J3A:		printf("28F320J3A\n");		break;	case FLASH_28F640J3A:		printf("28F640J3A\n");		break;	case FLASH_28F128J3A:		printf ("28F128J3A\n");		break;	default:		printf ("Unknown Chip Type\n");		break;	}	printf ("  Size: 0x%lx Bytes, %d Sectors\n",			info->size , info->sector_count);	printf ("  Sector Start Addresses:");	for (i = 0; i < info->sector_count; ++i) {		if ((i % 4) == 0)			printf ("\n");		printf ("%08lX%s ",			info->start[i],			info->protect[i] ? "(RO)" : "    ");	}	printf ("\n");	return;}/* The following code cannot be run from FLASH! */static ulong flash_get_size (void *base, flash_info_t *info){	volatile ushort value16;	volatile ulong  value32;	ushort * addr16;	ulong  * addr32;	addr16 = (ushort *)base;	addr32 = (ulong *)base;	addr16[0x555] = (ushort)0xaaaa;	addr16[0x2aa] = (ushort)0x5555;	addr16[0x555] = (ushort)0x9090;	value16 = addr16[0];	switch(value16){		case (ushort)AMD_MANUFACT:			info->flash_id = FLASH_MAN_AMD;			info->base_addr = base;			nGCS0_is_amd = nGCS0_AMD;			value16 = addr16[1];			switch(value16){				case (ushort)AMD_ID_LV400T: //0x22B9                    info->flash_id += FLASH_AM400T;                    info->sector_count = 11;                    info->size = 0x80000;                    break;				case (ushort)AMD_ID_LV400B: //0x22BA                    info->flash_id += FLASH_AM400B;                    info->sector_count = 11;                    info->size = 0x80000;                    break;				case (ushort)AMD_ID_LV800T: //0x22DA					info->flash_id += FLASH_AM800T;					info->sector_count = 19;					info->size = 0x100000;					break;				case (ushort)AMD_ID_LV800B: // 0x225B					info->flash_id += FLASH_AM800B;					info->sector_count = 19;					info->size = 0x100000;					break;				default:					info->flash_id += FLASH_UNKNOWN;					return 0;			}			addr16[0] = (ushort)0xf0f0;	//AMD reset			break;		case (ushort)INTEL_MANUFACT:			info->flash_id = FLASH_MAN_INTEL;			info->base_addr = base;			nGCS0_is_amd = 0;			addr32[0x5555] = (ulong)0x00AA00AA;			addr32[0x2AAA] = (ulong)0x00550055;			addr32[0x5555] = (ulong)0x00900090;			value32 = addr32[0];			value32 = addr32[1];			switch(value32){				case (ulong)INTEL_ID_28F320J3A: //0x160016					info->flash_id += FLASH_28F320J3A;					info->sector_count = 32;//(0x400000/INTEL_FLASH_SECT_SIZE) * 2;					info->size = 0x400000 * 2;					break;				case (ulong)INTEL_ID_28F640J3A: //0x170017					info->flash_id += FLASH_28F640J3A;					info->sector_count = 64;//(0x800000/INTEL_FLASH_SECT_SIZE) * 2;					info->size = 0x800000 * 2;					break;				case (ulong) INTEL_ID_28F128J3A: //0x180018					info->flash_id += FLASH_28F128J3A;					info->sector_count = 128;//(0x1000000/INTEL_FLASH_SECT_SIZE) * 2;					info->size = 0x1000000 * 2;					break;				default:					info->flash_id = FLASH_UNKNOWN;					return 0;			}			addr32[0] = (ulong)0x00ff00ff;			break;		default:			info->flash_id = FLASH_UNKNOWN;			info->sector_count = 0;			info->size = 0;			addr16[0] = (ushort)0xf0f0; // restore read mode			addr32[0] = (ulong)0x00ff00ff;			return 0;         // no or unknown flash	}	if (info->sector_count > CFG_MAX_FLASH_SECT) {//		printf ("** ERROR: sector count %d > max (%d) **\n",//			info->sector_count, CFG_MAX_FLASH_SECT);		info->sector_count = CFG_MAX_FLASH_SECT;	}	return (info->size);}/*-----------------------------------------------------------------------*/int flash_erase(flash_info_t *info, int s_first, int s_last){	switch(info->flash_id & FLASH_TYPEMASK)	{		case FLASH_AM400T:		case FLASH_AM400B:		case FLASH_AM800T:		case FLASH_AM800B:			return amd_flash_erase(info, s_first, s_last);		case FLASH_28F320J3A:		case FLASH_28F640J3A:		case FLASH_28F128J3A:			return intel_flash_erase(info, s_first, s_last);		default:			printf("erase error.. Unknown chip type\n");			break;		}	return 1;}int amd_flash_erase (flash_info_t *info, int s_first, int s_last){	ushort prot, sect, result;	ulong base, chip;	int rcode = 0;	base = info->base_addr;	if((s_first < 0) || (s_first > s_last))	{		if(info->flash_id == FLASH_UNKNOWN)			printf("- missing\n");		else			printf("- no sectors to erase\n");		

⌨️ 快捷键说明

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