wanpipe/util/wan_aftup/wan_aft_flash_shark_116.c

428 lines
12 KiB
C

#include <stdlib.h>
#include <stdio.h>
#if !defined(__WINDOWS__)
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <netinet/in.h>
#endif
#if defined(__LINUX__)
# include <linux/if.h>
# include <linux/types.h>
# include <linux/if_packet.h>
# include <linux/wanpipe_defines.h>
# include <linux/sdlasfm.h>
# include <linux/wanpipe_cfg.h>
#elif defined(__WINDOWS__)
# include <windows.h>
# include <winioctl.h>
# include <conio.h>
# include <stddef.h> /* offsetof() */
# include <string.h>
# include "wanpipe_includes.h"
# include "wanpipe_common.h"
# include "wanpipe_time.h" /* wp_usleep() */
# include "sdlasfm.h"
# include "sdlapci.h"
#else
# include <net/if.h>
# include <wanpipe_defines.h>
# include <sdlasfm.h>
# include <wanpipe_cfg.h>
#endif
#include "wan_aft_prg.h"
#define MASK_DEF_SECTOR_FLASH 0x00
#define MASK_USER_SECTOR_FLASH 0x08
/* Manufacturer code */
#define MCODE_ST 0x20
/* Device code */
#define DCODE_M29W040B 0xE3
#define DCODE_M29W800DT 0xD7
#define DCODE_M29W800DB 0x5B
#define M29W800DT_FID 0
#define M29W800DB_FID 1
struct {
unsigned long start_addr;
unsigned long start_off;
unsigned long len;
unsigned int sector_type;
} aft_shark_flash_spec_116 [2][19] =
{
{
{ 0x00000, 0x00000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x10000, 0x10000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x20000, 0x20000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x30000, 0x30000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x40000, 0x40000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x50000, 0x50000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x60000, 0x60000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x70000, 0x70000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x80000, 0x00000, 0xFFFF, USER_SECTOR_FLASH },
{ 0x90000, 0x10000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xA0000, 0x20000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xB0000, 0x30000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xC0000, 0x40000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xD0000, 0x50000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xE0000, 0x60000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xF0000, 0x70000, 0x7FFF, USER_SECTOR_FLASH },
{ 0xF8000, 0x78000, 0x1FFF, USER_SECTOR_FLASH },
{ 0xFA000, 0x7A000, 0x1FFF, USER_SECTOR_FLASH },
{ 0xFC000, 0x7C000, 0x3FFF, USER_SECTOR_FLASH },
},
{
{ 0x00000, 0x00000, 0x3FFF, DEF_SECTOR_FLASH },
{ 0x04000, 0x40000, 0x1FFF, DEF_SECTOR_FLASH },
{ 0x06000, 0x60000, 0x1FFF, DEF_SECTOR_FLASH },
{ 0x08000, 0x80000, 0x7FFF, DEF_SECTOR_FLASH },
{ 0x10000, 0x10000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x20000, 0x20000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x30000, 0x30000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x40000, 0x40000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x50000, 0x50000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x60000, 0x60000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x70000, 0x70000, 0xFFFF, DEF_SECTOR_FLASH },
{ 0x80000, 0x00000, 0xFFFF, USER_SECTOR_FLASH },
{ 0x90000, 0x10000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xA0000, 0x20000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xB0000, 0x30000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xC0000, 0x40000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xD0000, 0x50000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xE0000, 0x60000, 0xFFFF, USER_SECTOR_FLASH },
{ 0xF0000, 0x70000, 0xFFFF, USER_SECTOR_FLASH },
}
};
aftup_flash_t aft_shark_flash_116 = { 0x014F, AFT_CORE_X1600_SIZE };
extern int verbose;
extern int progress_bar(char*,int,int);
/*
******************************************************************************
FUNCTION PROTOTYPES
******************************************************************************
*/
extern int exec_read_cmd(void*,unsigned int, unsigned int, unsigned int*);
extern int exec_write_cmd(void*,unsigned int, unsigned int, unsigned int);
extern void hit_any_key(void);
static int aft_reset_flash_shark(wan_aft_cpld_t *cpld);
static int aft_is_protected_shark(wan_aft_cpld_t *cpld, int stype);
static int aft_flash_id_shark(wan_aft_cpld_t *cpld, int mtype, int stype, int *flash_id);
static int aft_reload_flash_shark(wan_aft_cpld_t *cpld, int sector_type);
static int aft_write_flash_shark(wan_aft_cpld_t*,int, unsigned long,unsigned char*);
static int aft_read_flash_shark(wan_aft_cpld_t*,int,int,unsigned long, unsigned char**);
static unsigned char aft_read_flash_byte_shark(wan_aft_cpld_t*,int,int,unsigned long);
static int aft_erase_flash_shark(wan_aft_cpld_t*,int,int);
aftup_flash_iface_t aftup_shark_flash_116_iface =
{
aft_reset_flash_shark,
aft_is_protected_shark,
aft_flash_id_shark,
aft_reload_flash_shark,
aft_write_flash_shark,
aft_read_flash_shark,
aft_erase_flash_shark
};
/******************************************************************************
* FUNCTION DEFINITION
******************************************************************************/
static unsigned short get_cpld_off(int adptr_type, unsigned short cpld_off)
{
switch(adptr_type){
case A300_ADPTR_U_1TE3:
cpld_off &= ~AFT_BIT_DEV_ADDR_CLEAR;
cpld_off |= AFT_BIT_DEV_ADDR_CPLD;
break;
case AFT_ADPTR_56K:
cpld_off &= ~AFT8_BIT_DEV_ADDR_CLEAR;
cpld_off |= AFT8_BIT_DEV_ADDR_CPLD;
break;
default:
cpld_off |= AFT4_BIT_DEV_ADDR_CPLD;
break;
}
return cpld_off;
}
static unsigned int
write_cpld(wan_aft_cpld_t *cpld, unsigned short cpld_off,unsigned short cpld_data)
{
cpld_off = get_cpld_off(cpld->adptr_type, cpld_off);
exec_write_cmd(cpld->private, 0x46, 2, cpld_off);
exec_write_cmd(cpld->private, 0x44, 2, cpld_data);
return 0;
}
static unsigned int
read_cpld(wan_aft_cpld_t *cpld, unsigned short cpld_off)
{
unsigned int cpld_data;
cpld_off = get_cpld_off(cpld->adptr_type, cpld_off);
exec_write_cmd(cpld->private, 0x46, 2, cpld_off);
if (exec_read_cmd(cpld->private, 0x44, 4, &cpld_data) == 0){
return cpld_data;
}else{
return 0;
}
}
static unsigned int
__aft_write_flash_shark_byte(wan_aft_cpld_t *cpld, int stype, int mtype, unsigned long off,unsigned char data)
{
unsigned char offset;
//Writing flash address to cpld
offset = off & 0xFF;
write_cpld(cpld, 0x05, offset);
offset = (off >> 8) & 0xFF;
write_cpld(cpld, 0x06, offset);
offset = (off >> 16) & 0xF;
write_cpld(cpld, 0x07, offset);
write_cpld(cpld, 0x04, data);
write_cpld(cpld, 0x07, 0x00); // disable CS signal for the Boot FLASH/SRAM
return 0;
}
static unsigned int
aft_write_flash_shark_byte(wan_aft_cpld_t *cpld, int stype, int mtype, unsigned long off,unsigned char data)
{
unsigned long sec_off = 0x00;
return __aft_write_flash_shark_byte(cpld, stype, mtype, sec_off + off, data);
}
static unsigned char
__aft_read_flash_byte_shark(wan_aft_cpld_t *cpld, int stype, int mtype, unsigned long off)
{
unsigned char offset;
unsigned char data;
//Writing flash address to cpld
offset = off & 0xFF;
write_cpld(cpld, 0x05, offset);
offset = (off >> 8) & 0xFF;
write_cpld(cpld, 0x06, offset);
offset = (off >> 16) & 0xF;
offset |= MASK_MEMORY_TYPE_FLASH;
write_cpld(cpld, 0x07, offset);
data = read_cpld(cpld, 0x04);
write_cpld(cpld, 0x07, 0x00); // Disable CS for the Boot FLASH/SRAM
return data;
}
static unsigned char
aft_read_flash_byte_shark(wan_aft_cpld_t *cpld, int stype, int mtype, unsigned long off)
{
unsigned long sec_off = 0x00;
return __aft_read_flash_byte_shark(cpld, stype, mtype, sec_off + off);
}
static int
aft_erase_flash_shark(wan_aft_cpld_t *cpld, int stype, int verify)
{
unsigned long offset = 0x00;
unsigned char data = 0x00;
int sector_no = 0;
for(sector_no = 0; sector_no < 19; sector_no++){
offset = aft_shark_flash_spec_116[cpld->flash_index][sector_no].start_addr;
__aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, 0xAAA, 0xAA);
__aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, 0x555, 0x55);
__aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, 0xAAA, 0x80);
__aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, 0xAAA, 0xAA);
__aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, 0x555, 0x55);
aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, offset, 0x30);
do{
data = aft_read_flash_byte_shark(
cpld, stype,
MEMORY_TYPE_FLASH,
offset);
if (data & 0x80){
break;
}else if (data & 0x20){
data = aft_read_flash_byte_shark(
cpld, stype,
MEMORY_TYPE_FLASH,
offset);
if (data & 0x80){
break;
}else{
printf("%s: Failed!\n", __FUNCTION__);
printf("%s: Sector=%d!\n",
__FUNCTION__,
(stype == USER_SECTOR_FLASH) ?
sector_no+4:sector_no);
return -EINVAL;
}
}
} while(1);
progress_bar("\tErasing sectors\t\t\t\t",
sector_no, 19);
}
printf("\r\tErasing sectors\t\t\t\tPassed\n");
if (!verify) return 0;
// Verify that flash is 0xFF
for(offset = 0; offset < 0x100000; offset++){
// for(i=0;i<1000;i++);
data = aft_read_flash_byte_shark(cpld, stype, MEMORY_TYPE_FLASH, offset);
if (data != 0xFF){
printf(" Failed to compare! %05lx -> %02x \n",
offset,data);
return -EINVAL;
}
if ((offset & 0x3FFF) == 0x2000){
progress_bar("\tErasing sectors (verification)\t\t",
offset, 0x100000);
}
}
printf("\r\tErasing sectors (verification)\t\tPassed\n");
return 0;
}
static int
aft_write_flash_shark(wan_aft_cpld_t *cpld, int stype, unsigned long off32, unsigned char* pdata)
{
unsigned char data;
unsigned char data1 = 0x00;
int num_bytes = 1;
int i;
data = *pdata;
__aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, 0xAAA, 0xAA);
__aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, 0x555, 0x55);
__aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, 0xAAA, 0xA0);
aft_write_flash_shark_byte(cpld, stype, MEMORY_TYPE_FLASH, off32, data);
do{
for(i=0;i<1000;i++);
data1 = aft_read_flash_byte_shark(cpld, stype, MEMORY_TYPE_FLASH, off32);
if ((data1 & 0x80) == (data & 0x80)){
break;
}else if (data1 & 0x20){
data1 = aft_read_flash_byte_shark(
cpld, stype,
MEMORY_TYPE_FLASH,
off32);
if ((data1 & 0x80) == (data & 0x80)){
break;
}else{
printf("prg_flash_byte: Failed Addr=(%lX)!\n",
off32);
return -EINVAL;
}
}
} while(1);
return num_bytes;
}
static int
aft_read_flash_shark(wan_aft_cpld_t *cpld, int stype, int mtype, unsigned long off, unsigned char** ppdata)
{
int num_bytes = 1;
unsigned char* pdata = NULL;
unsigned long sec_off = 0x00;
pdata = malloc(num_bytes);
if (pdata == NULL) {
printf("Failed to allocate memory (%s:%d)\n",
__FUNCTION__,__LINE__);
return -ENOMEM;
}
memset(pdata, 0, num_bytes);
*pdata = __aft_read_flash_byte_shark(cpld, stype, mtype, sec_off + off);
*ppdata = pdata;
return num_bytes;
}
static int aft_reset_flash_shark(wan_aft_cpld_t *cpld)
{
__aft_write_flash_shark_byte(cpld, DEF_SECTOR_FLASH, MEMORY_TYPE_FLASH, 0x00, 0xF0);
return 0;
}
static int aft_is_protected_shark(wan_aft_cpld_t *cpld, int stype)
{
return 0;
}
static int aft_flash_id_shark(wan_aft_cpld_t *cpld, int mtype, int stype, int *flash_id)
{
unsigned char man_code, device_code;
aft_reset_flash_shark(cpld);
__aft_write_flash_shark_byte(cpld, stype, mtype, 0xAAA, 0xAA);
__aft_write_flash_shark_byte(cpld, stype, mtype, 0x555, 0x55);
__aft_write_flash_shark_byte(cpld, stype, mtype, 0xAAA, 0x90);
man_code = aft_read_flash_byte_shark(cpld, stype, mtype, 0x00);
if (man_code != MCODE_ST){
printf("The current shark flash is not supported (man id %02X)!\n",
man_code);
return -EINVAL;
}
*flash_id = man_code << 8;
device_code = aft_read_flash_byte_shark(cpld, stype, mtype, 0x02);
switch(device_code){
case DCODE_M29W800DT:
cpld->flash_index = M29W800DT_FID;
break;
case DCODE_M29W800DB:
cpld->flash_index = M29W800DB_FID;
break;
default:
printf("The current flash is not supported (dev id %02X)!\n",
device_code);
return -EINVAL;
break;
}
*flash_id |= device_code;
aft_reset_flash_shark(cpld);
return 0;
}
static int aft_reload_flash_shark(wan_aft_cpld_t *cpld, int sector_type)
{
/* Reload new code in to Xilinx from
** Flash Default sector */
write_cpld(cpld, 0x07,0x80);
return 0;
}