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

📄 amd_flash.c

📁 motorola自己开发的针对coldfire 5272的Dbug bootloader程序
💻 C
字号:
/*
 * File:		amd_flash.c
 * Purpose:		Flash driver for programming all AMD Flash devices 
 *
 * Notes:       This driver supports a single type and width of AMD
 *              Flash. The type and width is determined at compile
 *              time. Multiple devices of the same type and width
 *				are supported.
 *
 * Modifications:
 *
 */

#include "src/include/dbug.h"

/* 
 * Compiler specific code relocation section
 */
#ifdef __DCC__
#pragma section CODE	".code_relocation"
#pragma section CONST	".code_relocation"
#endif

#include "src/dev/flash/amd_flash.h"

/********************************************************************/
/*
 * Global pointer to base of AMD Flash device
 * Initialized in amd_flash_init()
 */
#ifdef __MWERKS__
__relocate_data__
#endif
AMD_FLASH_CELL *pFlash;

/********************************************************************/
/* 
 * Flash sector definitions
 */
#ifdef __MWERKS__
__relocate_const__
#else
const
#endif
AMD_FLASH_SECTOR_INFO sector[] = 
#ifdef AMD_FLASH_AM29PL160CB_16BIT
{
	/* Bottom Boot */
	{ 16*1024, 0x000000}, /* SA0  */
	{  8*1024, 0x004000}, /* SA1  */
	{  8*1024, 0x006000}, /* SA2  */
	{224*1024, 0x008000}, /* SA3  */
	{256*1024, 0x040000}, /* SA4  */
	{256*1024, 0x080000}, /* SA5  */
	{256*1024, 0x0C0000}, /* SA6  */
	{256*1024, 0x100000}, /* SA7  */
	{256*1024, 0x140000}, /* SA8  */
	{256*1024, 0x180000}, /* SA9  */
	{256*1024, 0x1C0000}  /* SA10 */
};	
#elif defined(AMD_FLASH_AM29LV160DB_16BIT)
{
	/* Bottom Boot */
	{16*1024, 0x000000}, /* SA0  */
	{ 8*1024, 0x004000}, /* SA1  */
	{ 8*1024, 0x006000}, /* SA2  */
	{32*1024, 0x008000}, /* SA3  */
	{64*1024, 0x010000}, /* SA4  */
	{64*1024, 0x020000}, /* SA5  */
	{64*1024, 0x030000}, /* SA6  */
	{64*1024, 0x040000}, /* SA7  */
	{64*1024, 0x050000}, /* SA8  */
	{64*1024, 0x060000}, /* SA9  */
	{64*1024, 0x070000}, /* SA10 */
	{64*1024, 0x080000}, /* SA11 */
	{64*1024, 0x090000}, /* SA12 */
	{64*1024, 0x0A0000}, /* SA13 */
	{64*1024, 0x0B0000}, /* SA14 */
	{64*1024, 0x0C0000}, /* SA15 */
	{64*1024, 0x0D0000}, /* SA16 */
	{64*1024, 0x0E0000}, /* SA17 */
	{64*1024, 0x0F0000}, /* SA18 */
	{64*1024, 0x100000}, /* SA19 */
	{64*1024, 0x110000}, /* SA20 */
	{64*1024, 0x120000}, /* SA21 */
	{64*1024, 0x130000}, /* SA22 */
	{64*1024, 0x140000}, /* SA23 */
	{64*1024, 0x150000}, /* SA24 */
	{64*1024, 0x160000}, /* SA25 */
	{64*1024, 0x170000}, /* SA26 */
	{64*1024, 0x180000}, /* SA27 */
	{64*1024, 0x190000}, /* SA28 */
	{64*1024, 0x1A0000}, /* SA29 */
	{64*1024, 0x1B0000}, /* SA30 */
	{64*1024, 0x1C0000}, /* SA31 */
	{64*1024, 0x1D0000}, /* SA32 */
	{64*1024, 0x1E0000}, /* SA33 */
	{64*1024, 0x1F0000}  /* SA34 */
};	
#elif defined(AMD_FLASH_AM29BDD160GB_32BIT)
{
	/* Bottom Boot */
	{ 8*1024, 0x000000}, /* SA0  */
	{ 8*1024, 0x002000}, /* SA1  */
	{ 8*1024, 0x004000}, /* SA2  */
	{ 8*1024, 0x006000}, /* SA3  */
	{ 8*1024, 0x008000}, /* SA4  */
	{ 8*1024, 0x00A000}, /* SA5  */
	{ 8*1024, 0x00C000}, /* SA6  */
	{ 8*1024, 0x00E000}, /* SA7  */
	{64*1024, 0x010000}, /* SA8  */
	{64*1024, 0x020000}, /* SA9  */
	{64*1024, 0x030000}, /* SA10 */
	{64*1024, 0x040000}, /* SA11 */
	{64*1024, 0x050000}, /* SA12 */
	{64*1024, 0x060000}, /* SA13 */
	{64*1024, 0x070000}, /* SA14 */
	{64*1024, 0x080000}, /* SA15 */
	{64*1024, 0x090000}, /* SA16 */
	{64*1024, 0x0A0000}, /* SA17 */
	{64*1024, 0x0B0000}, /* SA18 */
	{64*1024, 0x0C0000}, /* SA19 */
	{64*1024, 0x0D0000}, /* SA20 */
	{64*1024, 0x0E0000}, /* SA21 */
	{64*1024, 0x0F0000}, /* SA22 */
	{64*1024, 0x100000}, /* SA23 */
	{64*1024, 0x110000}, /* SA24 */
	{64*1024, 0x120000}, /* SA25 */
	{64*1024, 0x130000}, /* SA26 */
	{64*1024, 0x140000}, /* SA27 */
	{64*1024, 0x150000}, /* SA28 */
	{64*1024, 0x160000}, /* SA29 */
	{64*1024, 0x170000}, /* SA30 */
	{64*1024, 0x180000}, /* SA31 */
	{64*1024, 0x190000}, /* SA32 */
	{64*1024, 0x1A0000}, /* SA33 */
	{64*1024, 0x1B0000}, /* SA34 */
	{64*1024, 0x1C0000}, /* SA35 */
	{64*1024, 0x1D0000}, /* SA36 */
	{64*1024, 0x1E0000}, /* SA37 */
	{ 8*1024, 0x1F0000}, /* SA38 */
	{ 8*1024, 0x1F2000}, /* SA39 */
	{ 8*1024, 0x1F4000}, /* SA40 */
	{ 8*1024, 0x1F6000}, /* SA41 */
	{ 8*1024, 0x1F8000}, /* SA42 */
	{ 8*1024, 0x1FA000}, /* SA43 */
	{ 8*1024, 0x1FC000}, /* SA44 */
	{ 8*1024, 0x1FE000}  /* SA45 */
};
#elif defined(AMD_FLASH_AM29LV640MH_16BIT)

	/* Uniform sectors (64KBytes) */
	#define SSIZE(n)	(0x10000 * AMD_FLASH_DEVICES)
	#define SOFFSET(n)	(SSIZE(n) * n)
	#define SADDR(n)	(SOFFSET(n) >> AMD_FLASH_BUS_SHIFT)

#else
#error "Unsupported Flash device"
#endif

#ifndef SSIZE
#define SSIZE(n)	(sector[n].size * AMD_FLASH_DEVICES)
#endif
#ifndef SOFFSET
#define SOFFSET(n)	(sector[n].offset * AMD_FLASH_DEVICES)
#endif
#ifndef SADDR
#define SADDR(n)	(SOFFSET(n) >> AMD_FLASH_BUS_SHIFT)
#endif

/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
amd_flash_init(ADDRESS base)
{
	pFlash = (AMD_FLASH_CELL *)base;
}

/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
amd_flash_sector_erase(int n)
{
	volatile AMD_FLASH_CELL status;
	
	pFlash[0x555] = AMD_FLASH_CMD_DATA(0xAA);
	pFlash[0x2AA] = AMD_FLASH_CMD_DATA(0x55);
	pFlash[0x555] = AMD_FLASH_CMD_DATA(0x80);
	pFlash[0x555] = AMD_FLASH_CMD_DATA(0xAA);
	pFlash[0x2AA] = AMD_FLASH_CMD_DATA(0x55);
	pFlash[SADDR(n)] = AMD_FLASH_CMD_DATA(0x30);
	
	do 
		status = pFlash[SADDR(n)];
	while ((status & AMD_FLASH_CMD_DATA(0x80)) != AMD_FLASH_CMD_DATA(0x80));
		
	/*
	 * Place device in read mode 
	 */
	pFlash[0] = AMD_FLASH_CMD_DATA(0xAA);
	pFlash[0] = AMD_FLASH_CMD_DATA(0x55);
	pFlash[0] = AMD_FLASH_CMD_DATA(0xF0);
}

/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
int
amd_flash_erase(ADDRESS start, int bytes, void (*putchar)(char))
{	
	int i, ebytes = 0;
	
	if (bytes == 0)
		return 0;
	
	for (i = 0; i < AMD_FLASH_SECTORS; i++)
	{
		if (start >= (ADDRESS)((ADDRESS)pFlash + SOFFSET(i)) &&
			start <= (ADDRESS)((ADDRESS)pFlash + SOFFSET(i) + (SSIZE(i) - 1)))
		{
			break;
		}
	}
	
	while (ebytes < bytes)
	{
		if (putchar != NULL)
		{
			putchar('.');
		}
		amd_flash_sector_erase(i);
		ebytes += SSIZE(i);
		i++;
	}
	
	if (putchar != NULL)
	{
		putchar(10);	/* LF */
		putchar(13);	/* CR */
	}
	
	return ebytes;
}

/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
amd_flash_program_cell(AMD_FLASH_CELL *dst, AMD_FLASH_CELL data)
{
	volatile AMD_FLASH_CELL status;
	int retry;

	pFlash[0x555] = AMD_FLASH_CMD_DATA(0xAA);
	pFlash[0x2AA] = AMD_FLASH_CMD_DATA(0x55);
	pFlash[0x555] = AMD_FLASH_CMD_DATA(0xA0);
	*dst = data;
	
	/*
	 * Wait for program operation to finish
	 *	(Data# Polling Algorithm)
	 */
	retry = 0;
	while (1)
	{
		status = *dst;
		if ((status & AMD_FLASH_CMD_DATA(0x80)) ==
			(data & AMD_FLASH_CMD_DATA(0x80)))
		{
			break;
		}
		if (status & AMD_FLASH_CMD_DATA(0x20))
		{
			status = *dst;
			if ((status & AMD_FLASH_CMD_DATA(0x80)) ==
				(data & AMD_FLASH_CMD_DATA(0x80)))
			{
				break;
			}
			if (++retry > 1024)
			{
				break;
			}
		}				
	}
}
		
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
int 
amd_flash_program(ADDRESS dest, ADDRESS source, 
					int bytes, int erase, 
					void (*func)(void),
					void (*putchar)(char))
{
	AMD_FLASH_CELL *src, *dst;
	int hashi=1,hashj=0;
	char hash[5];
	
	hash[0]=8;	/* Backspace */
	hash[1]=124;/* "|" */
	hash[2]=47; /* "/" */
	hash[3]=45; /* "-" */
	hash[4]=92; /* "\" */

	src = (AMD_FLASH_CELL *)source;
	dst = (AMD_FLASH_CELL *)dest;

	/*
	 * Place device in read mode 
	 */
	pFlash[0] = AMD_FLASH_CMD_DATA(0xAA);
	pFlash[0] = AMD_FLASH_CMD_DATA(0x55);
	pFlash[0] = AMD_FLASH_CMD_DATA(0xF0);
	
	/*
	 * Erase device if necessary
	 */
	if (erase)
	{
		amd_flash_erase(dest, bytes, putchar);
	}
	
	/*
	 * Program device
	 */
	while (bytes > 0)
	{
		amd_flash_program_cell(dst,*src);
		
		/* Verify Write */
		if (*dst == *src)
		{
			bytes -= AMD_FLASH_CELL_BYTES;
			*dst++, *src++;

			if ((putchar != NULL))
			{	
				/* Hash marks to indicate progress */
				if (hashj == 0x1000)
				{
					hashj = -1;
					putchar(hash[0]);
					putchar(hash[hashi]);
							
					hashi++;
					if (hashi == 5)	
					{
						hashi=1;				
					}
		
				}
				hashj++;
			}
		}
		else
			break;
	}
	
	/*
	 * Place device in read mode 
	 */
	pFlash[0] = AMD_FLASH_CMD_DATA(0xAA);
	pFlash[0] = AMD_FLASH_CMD_DATA(0x55);
	pFlash[0] = AMD_FLASH_CMD_DATA(0xF0);
	
	if (putchar != NULL)
	{
		putchar(hash[0]);
	}
	
	/* 
	 * If a function was passed in, call it now
	 */
	if ((func != NULL))
	{
		func();
	}

	return ((int)src - (int)source);
}

/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
ADDRESS 
amd_flash_sector_start(ADDRESS addr)
{   
	/* 
	 * Returns beginning of sector containing ADDRESS 
	 */
	int i;
	
	for (i = 0; i < AMD_FLASH_SECTORS; i++)
	{
		if (addr >= (ADDRESS)((ADDRESS)pFlash + SOFFSET(i)) &&
			addr <= (ADDRESS)((ADDRESS)pFlash + SOFFSET(i) + (SSIZE(i) - 1)))
		{
			return (ADDRESS)((ADDRESS)pFlash + SOFFSET(i));
		}
	}
	return NULL;
}

/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
ADDRESS 
amd_flash_sector_end(ADDRESS addr)
{
	/* Returns end of sector containing ADDRESS */
	int i;
	
	for (i = 0; i < AMD_FLASH_SECTORS; i++)
	{
		if (addr >= (ADDRESS)((ADDRESS)pFlash + SOFFSET(i)) &&
			addr <= (ADDRESS)((ADDRESS)pFlash + SOFFSET(i) + (SSIZE(i) - 1)))
		{
			return (ADDRESS)((ADDRESS)pFlash + SOFFSET(i) + (SSIZE(i) - 1));
		}
	}									 
	return NULL;
}

/********************************************************************/

⌨️ 快捷键说明

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