📄 amd_flash.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 + -