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

📄 fl.c

📁 motorola自己开发的针对coldfire 5272的Dbug bootloader程序
💻 C
字号:
/*
 * File:		flash.c
 * Purpose:		Core dBUG Flash Utilities
 *
 * Notes:
 *
 * Modifications:
 *
 */

#include "src/include/dbug.h"
#include "src/uif/uif.h"

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

/*
 * Table for storing Flash device information
 */
static FLASH_INFO 
device[MAX_FLASH_DEVICES];

/*
 * Constant strings
 */
static const char FLASH_ADDRESS_ERROR[] = \
	"Invalid Flash address range\n";
static const char FLASH_ERASE_WARNING[] = \
	"Must erase complete sectors (%#08X to %#08X)\nContinue? ";
static const char FLASH_ERASE_ERROR[] = \
	"Flash Erase error: %#X bytes of %#X erased\n";
static const char FLASH_ERASE_SUCCESS[] = \
	"Flash Erase complete. %#X bytes erased\n";
static const char FLASH_PROGRAM_ERROR[] = \
	"Flash Write error: %#X bytes of %#X written\n";
static const char FLASH_PROGRAM_SUCCESS[] = \
	"Flash Write complete. %#X bytes written\n";
static const char FLASH_BYTE_ERROR[] = \
	"Flash Write error: byte count must be divisible by %d\n";
static const char FLASH_WRITE_ERROR[] = \
	"Flash Write error: source and destination in same device\n";
	 
/********************************************************************/
void
flash_init(void)
{
	int index;

	for (index = 0; index < MAX_FLASH_DEVICES; index++)
	{
		device[index].size = 0;
	}
}

/********************************************************************/
int
flash_dlio_vda(ADDRESS addr)
{
	int index;

	for (index = 0; index < MAX_FLASH_DEVICES; index++)
	{
		if ((device[index].size) && 
			(device[index].base <= addr) &&
		    (addr <= (ADDRESS)(device[index].base + (device[index].size - 1))))
		{
			if ((device[index].protect_start <= addr) &&
				(addr <= device[index].protect_start + 
						(device[index].protect_size - 1)))
			{	
				/* Address is protected */
				return 0;
			}
			else
			{
				return index+1;
			}
		}
	}
	/*
	 * Address was not found within a registered Flash device
	 */
	return 0;
}

/********************************************************************/
void
flash_display_info(void)
{
	int i, j, size, ssize, displayed;
	ADDRESS start, end;	

	printf("Flash Device Information:\n\n");

	for (i = 0; i < MAX_FLASH_DEVICES; i++)
	{
		if (!device[i].size)
			continue;
		printf("  Device %d:        %s\n",i,device[i].name);
		printf("  Total Size:      %#X ",device[i].size);
		if (device[i].size>>10 > 1024)
			printf("(%dM) bytes\n", device[i].size>>20);
		else
			printf("(%dK) bytes\n", device[i].size>>10);
		printf("  Address Range:   %#08X->%#08X\n",device[i].base, 
					device[i].base + device[i].size - 1);
		printf("  Protected Range: %#08X->%#08X\n",device[i].protect_start, 
					device[i].protect_start + (device[i].protect_size - 1));
		printf("  Access Size:     %d byte(s)\n", device[i].mask + 1);

		size = 0;
		displayed = 11;
		for (j = 0; size < device[i].size; j++)
		{
			start = device[i].sector_start(device[i].base + size);
			end = device[i].sector_end(device[i].base + size);
			ssize = (end - start) + 1;
			size += ssize;
			printf("  Sector %2d: %#08X->%#08X (%3dK)\n", j, start, end,
															ssize>>10);
			if (pause(&displayed))
				return;
		}
		printf("\n");
	}
}
				 
/********************************************************************/
void
flash_usage(void)
{
	printf("Flash Utility Usage:\n\n");
	printf("  (fl)ash (e)rase addr bytes\n");
	printf("  (fl)ash (w)rite dest src bytes\n\n");
}

/********************************************************************/
int
flash_register_device (FLASH_INFO *fl_info)
{
	int index;
	for (index = 0; index < MAX_FLASH_DEVICES; index++)
	{
		if (device[index].size == 0)
		{
			strcpy(device[index].name,fl_info->name);
			device[index].base = fl_info->base;
			device[index].size = fl_info->size;
			device[index].mask = fl_info->mask;
			device[index].erase = fl_info->erase;
			device[index].program = fl_info->program;
			device[index].sector_start = fl_info->sector_start;
			device[index].sector_end = fl_info->sector_end;
			device[index].putchar = fl_info->putchar;
			device[index].protect_start = fl_info->protect_start;
			device[index].protect_size = fl_info->protect_size;
			return TRUE;
		}
	}
	/*
	 * Table was full
	 */
	return FALSE;
}

/********************************************************************/
int
flash_erase(ADDRESS start, int bytes, int index)
{
	int ebytes, temp;
	char answer[UIF_MAX_LINE];
	ADDRESS s_start, s_end;
	int i = index - 1;
	
	if ((i < 0) || i >= MAX_FLASH_DEVICES)
		return FALSE;
		
	/*
	 * Verify erase operation with user
	 */
	s_start = device[i].sector_start(start);
	s_end = device[i].sector_end(start + bytes - 1);
	
	if ((s_start != start) || (s_end != (start + bytes - 1)))
	{
		printf(FLASH_ERASE_WARNING, s_start, s_end);
		get_line(answer);
		if (strncasecmp("yes",answer,1) != 0)
			return 0;
	}
	/*
	 * Call device specific erase routine
	 */
	temp = (s_end - s_start) + 1;
	ebytes = device[i].erase(s_start, temp, device[i].putchar);
	
	if (ebytes != temp)
	{
		printf(FLASH_ERASE_ERROR, ebytes, temp);
		return FALSE;
	}
	else
	{
		printf(FLASH_ERASE_SUCCESS, ebytes);
		return TRUE;
	}
}
				
/********************************************************************/
int
flash_program(ADDRESS dest, ADDRESS src, int bytes, int index, int er, int pc)
{
	/*
	 * er - if TRUE, then flash will be erased before programmed
	 * pc - if TRUE, then driver will output characters as progress indicator
	 */

	int i = index - 1;
	
	if ((i < 0) || i >= MAX_FLASH_DEVICES)
		return 0;
		
	if (pc)
		return device[i].program(dest, src, bytes, er, 0, device[i].putchar);
	else
		return device[i].program(dest, src, bytes, er, 0, 0);
}

/********************************************************************/
void
uif_cmd_fl (int argc, char **argv)
{
	ADDRESS addr1, addr2;
	int success, bytes, i, j;
	char answer[20];
	ADDRESS s_start, s_end;
	
	if (argc == 1)
	{
		flash_usage();
		flash_display_info();
	}
	else if (strncasecmp(argv[1],"erase",1) == 0)
	{
		if (argc != 4)
		{
			flash_usage();
			return;
		}
		
		/*
		 * Get start address
		 */
		addr1 = get_value(argv[2],&success,BASE);
		if (success == 0)
		{
			printf(INVALUE,argv[2]);
			return;
		}
		
		/*
		 * Get (minimum) number of bytes to erase
		 */		
		bytes = get_value(argv[3],&success,BASE);
		if (success == 0)
		{
			printf(INVALUE,argv[3]);
			return;
		}
		
		/*
		 * Verify that start and end are valid addresses
		 * within same device
		 */
		i = flash_dlio_vda(addr1);
		j = flash_dlio_vda(addr1 + bytes);
		
		if (!(i && j && (i == j)))
		{
			printf(FLASH_ADDRESS_ERROR);
			flash_display_info();
			return;
		}
		
		/*
		 * Call Flash erase routine
		 */
		flash_erase(addr1, bytes, i);		
	}
	else if (strncasecmp(argv[1],"write",1) == 0)
	{
		if (argc != 5)
		{
			flash_usage();
			return;
		}
		
		/*
		 * Get destination address
		 */
		addr1 = get_value(argv[2],&success,BASE);
		if (success == 0)
		{
			printf(INVALUE,argv[2]);
			return;
		}
		
		/*
		 * Get source address
		 */
		addr2 = get_value(argv[3],&success,BASE);
		if (success == 0)
		{
			printf(INVALUE,argv[3]);
			return;
		}
		
		/*
		 * Get number of bytes to copy
		 */		
		bytes = get_value(argv[4],&success,BASE);
		if (success == 0)
		{
			printf(INVALUE,argv[4]);
			return;
		}
		
		/*
		 * Verify that start and end are valid addresses
		 * within same device
		 */
		i = flash_dlio_vda(addr1);
		j = flash_dlio_vda(addr1 + bytes);
		
		if (!(i && j && (i == j)))
		{
			printf(FLASH_ADDRESS_ERROR);
			flash_display_info();
			return;
		}
		
		/*
		 * Verify bytes count is divisible by min. port size
		 */
		if (bytes & device[i].mask)
		{
			printf(FLASH_BYTE_ERROR,(device[i].mask + 1));
			flash_display_info();
			return;
		}
		
		/*
		 * Don't allow source and destination in same Flash device
		 */
		if (flash_dlio_vda(addr2) == i)
		{
			printf(FLASH_WRITE_ERROR);
			return;
		}
		
		/*
		 * Verify erase operation with user
		 */
		s_start = device[i-1].sector_start(addr1);
		s_end = device[i-1].sector_end(addr1 + bytes - 1);
		
		if ((s_start != addr1) || (s_end != (addr1 + bytes - 1)))
		{
			printf(FLASH_ERASE_WARNING, s_start, s_end);
			get_line(answer);
			if (strncasecmp("yes",answer,1) != 0)
				return;
		}
		
		/*
		 * Erase and program
		 */
		j = flash_program(addr1, addr2, bytes, i, TRUE, TRUE);
			
		if (j != bytes)
		{
			printf(FLASH_PROGRAM_ERROR, j, bytes);
		}
		else
		{
			printf(FLASH_PROGRAM_SUCCESS, j);
		}
	}
	else
	{
		flash_usage();
	}
}

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

⌨️ 快捷键说明

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