1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
TP-Link_Archer-XR500v/EN7526G_3.18Kernel_SDK/bootrom/bootram/lib/commands.c
2024-07-22 01:58:46 -03:00

11179 lines
336 KiB
C
Executable File

#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/random.h>
#include <linux/string.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/tc3162.h>
#include <asm/io.h>
#include <asm/delay.h>
#include "common.h"
#if defined(TCSUPPORT_CPU_EN7512)||defined(TCSUPPORT_CPU_EN7521)
#include "spi_nand_flash.h"
#include "controller/spi_controller/spi_controller.h"
#else
#include "nandflash.h"
#endif
#include "flashhal.h"
#include "commands.h"
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
#include "flash_layout/prolinecmd.h"
#endif
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
#include "flash_layout/tc_partition.h"
#endif
#ifdef BOOT_LZMA_SUPPORT
#include "lwip/sys.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
#include "lwip/tcp.h"
#include "lwip/opt.h"
#endif
#if defined(MT7530_SLT)
#include "../net/switch_slt.h"
#include "../net/tc3262gmac.h"
#endif
#include "../../../tools/trx/trx.h"
#ifdef SPI_DRAM_TEST_CMD
#include "dramtest.h"
#endif
#if defined(CONFIG_DUAL_IMAGE) || defined(SPI_DRAM_TEST_CMD)
#if defined(TCSUPPORT_CPU_MT7505) || defined(TCSUPPORT_CPU_EN7512) || defined(TCSUPPORT_CPU_EN7521)
#include "newspiflash.h"
#else
#include "spiflash.h"
#endif
#endif
#if defined(TCSUPPORT_NEW_SPIFLASH_DEBUG)
#include "newspiflash.h"
#endif
#ifdef TCSUPPORT_MTD_PARTITIONS_CMDLINE
#include "mtd_partition_parse.h"
#endif
#if defined(TCSUPPORT_CPU_EN7521) && defined(DRAM_PROTECT_TEST)
int mp_dbg_level = 0xf;
int nmi_test_enable = 0;
#endif
#if defined(TCSUPPORT_FWC_ENV)
#define RESTART_TIME_COUNT (3*60*100)
int restart_time_flags = 0;
int restart_time_count = RESTART_TIME_COUNT;
#endif
#define KEY_BEL 0x07
#define KEY_BS 0x08
#define KEY_CR 0x0D
#define KEY_LF 0x0A
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
//#define HTTP_DBG 1
#define CMD 0 /*flag for cmd_gets() input cmd*/
#define PWD 1 /*flag for cmd_gets() input passwd*/
#define USERNAME_PASSWD_LEN 16 /*length of username or passwd*/
//#define FLASH_BASE 0xb0000000 /*base address for 16M flash*/
//#define RESERVED_BASE 0xfc0000 /*base address for reserved area in flash*/
//#define FLASH_USER_NAME ((USERNAMEPASSWD_RA_OFFSET+RESERVED_BASE)|FLASH_BASE) /*begin address of username in reserved area*/
//#define FLASH_USER_NAME ((USERNAMEPASSWD_RA_OFFSET+RESERVED_BASE)|flash_base) /*begin address of username in reserved area*/
//#define FLASH_PASS_WORD ((USERNAMEPASSWD_RA_OFFSET+USERNAME_PASSWD_LEN+RESERVED_BASE)|FLASH_BASE) /*begin address of passwd in reserved area*/
//#define FLASH_PASS_WORD ((USERNAMEPASSWD_RA_OFFSET+USERNAME_PASSWD_LEN+RESERVED_BASE)|flash_base) /*begin address of passwd in reserved area*/
//#define MRD_USER_NAME (0xff69|FLASH_BASE) /*begin address of username in MRD area*/
#define MRD_USER_NAME (0xff69|flash_base) /*begin address of username in MRD area*/
//#define MRD_PASS_WORD (0xff79|FLASH_BASE) /*begin address of passwd in mrd area*/
#define MRD_PASS_WORD (0xff79|flash_base) /*begin address of passwd in mrd area*/
#define CT_USER_NAME "telecomadmin" /*length should be less than 16*/
#endif
#ifdef TCSUPPORT_NAND_RT63368
#define NAND_KERNEL_OFFSET 0x40000
#endif
#define EOF (-1)
#define printf prom_printf
#define LINE_LEN 128
#ifdef BOOT_LZMA_SUPPORT
#define IP_ADDRESS_FORMAT( ip) (ip) & 0xff, ((ip) >> 8) & 0xff,\
((ip) >> 16) & 0xff, ((ip) >> 24) & 0xff
#define TCBOOT_NAME "tcboot.bin"
#define TCLINUX_NAME "tclinux.bin"
#define TCBOOT 1
#define TCLINUX 2
#define ERRFILE -1
#define UPLOAD_BUF_SIZE 2048
#ifdef TCSUPPORT_BB_NAND
extern struct ra_nand_chip ra;
#if defined(TCSUPPORT_CPU_MT7510)||defined(TCSUPPORT_CPU_MT7520) || defined(TCSUPPORT_CPU_EN7512) || defined(TCSUPPORT_CPU_EN7521)
extern int en_oob_write;
extern int en_oob_erase;
#endif
#endif
struct web_connection {
/* the client tcp connection */
struct tcp_pcb *current_connection;
/* Detect idle connection using the last seq number */
unsigned long last_rx_seqno;
/* the rx state */
int rx_state;
/* save the GET http path here */
char get_path[200];
/* use this buffer for processing received data */
char rx_buffer[UPLOAD_BUF_SIZE];
} the_web_connection;
static char print_buffer[2048];
#endif
struct mtd_info {
unsigned long offset; /* Offset within the memory */
unsigned long size; /* Total size of the MTD */
unsigned long erasesize;
};
extern struct mtd_info mtd;
extern void pause(int ms);
static char cmd_prompt[] = "bldr";
static u8 random_byte(void);
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
static char *cmd_gets(char *buf, int len, int flag);
#else
static char *cmd_gets(char *buf, int len);
#endif
static int cmd_parse(cmds_t cmds[], char *line);
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
void user_Auth(void);
static int trim(char *buf);
#endif
static int do_null(int argc, char *argv[]);
static int do_help(int argc, char *argv[]);
#ifndef BOOTROM_IN_SRAM
#if defined(TCSUPPORT_CT)
int do_go(int argc, char *argv[]);
#else
static int do_go(int argc, char *argv[]);
#endif
static int do_decomp(int argc, char *argv[]);
#endif
static int do_memrl(int argc, char *argv[]);
static int do_memwl(int argc, char *argv[]);
#ifdef CONFIG_TP_IMAGE
#ifdef CONFIG_TP_DUAL_IMAGE
/* add by renjun 2017.07.05, set bootflag */
static int do_bootflag(int argc, char *argv[]);
/* end add */
#endif /* CONFIG_TP_DUAL_IMAGE */
#endif /* CONFIG_TP_IMAGE */
static int do_dump(int argc, char *argv[]);
static int do_jump(int argc, char *argv[]);
static int do_flash(int argc, char *argv[]);
#ifdef MT7505_GDMP
static int doGDmpCfg(int argc, char *argv[]);
static int doSysGdmpMem(int argc, char *argv[]);
#endif
static int do_imginfo(int argc, char *argv[]);
#if defined(TCSUPPORT_NEW_SPIFLASH_DEBUG)
static int do_sf_basic_test(int argc, char *argv[]);
static int do_sf_mats(int argc, char *argv[]);
static int do_sf_be(int argc, char *argv[]);
static int do_sf_readidle_test(int argc, char *argv[]);
static int do_sf_bootin4Byte(int argc, char *argv[]);
static int do_sf_nonAlign_test(int argc, char *argv[]);
#ifdef TCSUPPORT_NEW_SPIFLASH_DEBUG_EXT
static int do_sf_memcpy(int argc, char *argv[]);
static int do_sf_1ByteTest(int argc, char *argv[]);
static int do_sf_ClockSet(int argc, char *argv[]);
static int do_sf_TnSet(int argc, char *argv[]);
#endif
#endif
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
#ifndef TCSUPPORT_RESERVEAREA_EXTEND
static int do_passwd(int argc, char *argv[]);
#endif
#endif
#if defined(TCSUPPORT_NEW_SPIFLASH_DEBUG)
static int do_spinand_rw_test(int argc, char *argv[]);
static int do_spinand_read(int argc, char *argv[]);
static int do_spinand_write(int argc, char *argv[]);
static int do_spinand_erase(int argc, char *argv[]);
static int do_spinand_nonalign(int argc, char *argv[]);
static int do_spicontroller_reg_test(int argc, char *argv[]);
static int do_spicontroller_interrupt_test(int argc, char *argv[]);
static int do_spicontroller_preload_test(int argc, char *argv[]);
void spicontroller_preload_function_test( void );
static int do_spicontroller_cpol_test(int argc, char *argv[]);
static int do_spicontroller_strap_test(int argc, char *argv[]);
static int do_spi_frequency(int argc, char *argv[]);
#endif
#ifdef NAND_TEST_CMD
static int init_nand(int argc, char *argv[]);
static int read_nand(int argc, char *argv[]);
static int erase_nand(int argc, char *argv[]);
static int check_data(int argc, char *argv[]);
static int innand(int argc, char *argv[]);
#ifdef TCSUPPORT_NAND_RT63368
static int check_badblock(int argc, char *argv[]);
static int mark_badblock(int argc, char *argv[]);
static int erase_block_phy(int argc, char *argv[]);
static int read_page_phy(int argc, char *argv[]);
static int write_page_phy(int argc, char *argv[]);
#endif
#endif
#ifdef BOOTROM_BACKDOOR
static int do_bdconfig_store(int argc, char *argv[]);
static int do_bdconfig_show(int argc, char *argv[]);
#ifdef BACKDOOR_SWITCH
static int do_bdconfig_switch (int argc, char *argv[]);
static int do_ddrcal_switch(int argc, char *argv[]);
static int do_dram_bist_switch(int argc, char *argv[]);
#endif
#endif
#ifndef BOOTROM_IN_SRAM
static int do_ipaddr(int argc, char *argv[]);
#endif
#ifdef BOOT_LZMA_SUPPORT
static int do_httpd(int argc, char *argv[]);
#endif
#ifdef SPI_TEST_CMD
static int do_erase(int argc, char *argv[]);
static int do_program(int argc, char *argv[]);
#endif
static int do_xmodem_rx(int argc, char *argv[]);
#ifdef BOOTROM_IN_SRAM
static int do_xmodem_rx_flash(int argc, char *argv[]);
#endif
#ifndef BOOTROM_IN_SRAM
static int do_miir(int argc, char *argv[]);
static int do_miiw(int argc, char *argv[]);
#endif
#if defined(MT7530_SLT)
static int doPhyMMDRead(int argc, char *argv[], void *p);
static int doPhyMMDWrite(int argc, char *argv[], void *p);
static int doTCMiiBPRead(int argc, char *argv[], void *p);
static void doTCMiiBPWrite(int argc, char *argv[], void *p);
static int doPhyMiiRead (int argc, char *argv[], void *p);
static int doPhyMiiWrite (int argc, char *argv[], void *p);
static int doDumpGSW(int argc, char *argv[]);
#endif
#if defined(MT7530_SLT) || defined(MT7530_SUPPORT)
static int doGswRead(int argc, char *argv[], void *p);
static int doGswWrite(int argc, char *argv[], void *p);
#endif
#ifdef SPI_TEST_CMD
static int do_memcmp(int argc, char *argv[]);
static int do_dmacpy(int argc, char *argv[]);
static int do_memcpy(int argc, char *argv[]);
static int do_memcmp4(int argc, char *argv[]);
static int do_memcpy4(int argc, char *argv[]);
static int do_memcmp2(int argc, char *argv[]);
static int do_memcpy2(int argc, char *argv[]);
static int do_memset(int argc, char *argv[]);
static int do_memset4(int argc, char *argv[]);
static int do_memset42(int argc, char *argv[]);
static int do_memset44(int argc, char *argv[]);
static int do_incr(int argc, char *argv[]);
static int do_incrcmp(int argc, char *argv[]);
static int do_rreadb(int argc, char *argv[]);
static int do_rreadl(int argc, char *argv[]);
static int do_rwritel(int argc, char *argv[]);
static int do_step(int argc, char *argv[]);
static int do_spidbg(int argc, char *argv[]);
static int do_spiqe(int argc, char *argv[]);
static int do_spird(int argc, char *argv[]);
#ifdef ETH_TEST_CMD
static int do_ethsend(int argc, char *argv[]);
static int do_ethsend2(int argc, char *argv[]);
static int do_ethdump(int argc, char *argv[]);
#endif
extern int memcmp4(const void * cs,const void * ct,size_t count);
extern void * memcpy4(void * dest,const void *src,size_t count);
extern int memcmp2(const void * cs,const void * ct,size_t count);
extern void * memcpy2(void * dest,const void *src,size_t count);
extern void * memset4(void * s,int c,size_t count);
#endif
#ifdef SPI_DRAM_TEST_CMD
static int do_dramtest(int argc, char *argv[]);
static int do_flashtest(int argc, char *argv[]);
static int do_spiregrw(int argc, char *argv[]);
static int do_gdmatestdram(int argc, char *argv[]);
static int do_gdmatestflash(int argc, char* argv[]);
static int do_gdmatestreg(int argc, char* argv[]);
#ifdef DRAM_PROTECT_TEST
static int do_rbus_init(int argc, char *argv[]);
static int do_dram_protect_size(int argc, char *argv[]);
static int do_dram_protect_test1(int argc, char *argv[]);
static int do_dram_protect_test2(int argc, char *argv[]);
static int do_dram_protect_test3(int argc, char *argv[]);
static int do_dram_protect_test4(int argc, char *argv[]);
static int do_seg_read_protect(int argc, char *argv[]);
static int do_seg_write_protect(int argc, char *argv[]);
static int do_seg_addr_set(int argc, char *argv[]);
static int do_seg_protect_test(int argc, char *argv[]);
static int do_mem_protect_test(int argc, char *argv[]);
static int do_mem_protect_test2(int argc, char *argv[]);
#if defined(TCSUPPORT_CPU_EN7521) && defined(DRAM_PROTECT_TEST)
int do_mem_protect_dbgLevel(int argc, char *argv[]);
int do_nmi_test_enable(int argc, char *argv[]);
#endif
#endif
#endif
#if defined(RBUS_COUNTER_TEST)
static int do_rbus_counter(int argc, char *argv[]);
#endif
#ifdef MT7550_GPIO_TEST//tony add
static int do_gpio_test(int argc, char *argv[]);
#endif
#if defined(TCSUPPORT_FWC_ENV)
static int do_show_all_flash_env_info(void);
static int do_show_all_dual_image_flag_info(void);
static int do_boot_debug_level(int argc, char *argv[]);
static int do_boot_reset(int argc, char *argv[]);
static int do_boot_version(int argc, char *argv[]);
static int do_flash_erase(int argc, char *argv[]);
static int do_personality_parm_cmd(int argc, char *argv[]);
static int do_stop_restart(int argc, char *argv[]);
#endif
static int do_cpufreq(int argc, char *argv[]);
#ifdef BOOT_LZMA_SUPPORT
extern unsigned long Jiffies;
void tc_mdelay(int delaytime);
static char *upload_buf = (unsigned char *)0x80020000;
static char *p_upload_buf = (unsigned char *)0x80020000;
unsigned char file_recv = 0;
#endif
//static unsigned char file_recv = 0;
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
static unsigned char auth_recv = 0;
static unsigned char post_recv = 0;
static unsigned char pass_auth = 0;
#endif
#ifdef MT7505_SWITCH_TBL_VERIRY
void MT7505_Switch_Tbl_Test(void);
#endif
#ifdef TC3262
#ifndef BOOTROM_IN_SRAM
static int do_ddrdrv(int argc, char *argv[]);
#endif
#ifdef DRAM_PROTECT_TEST
#define RBUS_INT 1
static int record1[1000][6]={0}; /* startAddr, size, overSize, seg1 & seg2, resv, resv */
static int record2[1000][6]={0}; /* valid, resv, overSize_fail, forbidden_seg_fail, illInfo, illRegAddr */
static int record3_RegAddr[1000]={0}; /*exillRegAddr */
static int record4_illInfo[1000]={0}; /*exillInfo */
static int test_round=0;
static int ex_addr_count = 0;
static int ex_info_count = 0;
void RbusIsr(int irq, void *dev_id, struct pt_regs *regs);
struct irqaction rbus_irq = {RbusIsr, NULL, 0, "rbus_isr", NULL, NULL};
#endif
#endif
static const cmds_t CMDS[] = {
{ "", do_null, 0, "", ""},
{ "?", do_help, 0, "?", "Print out help messages."},
{ "help", do_help, 0, "help", "Print out help messages."},
#if defined(TCSUPPORT_FWC_ENV)
{ "show_flash_info", do_show_all_flash_env_info, 0, "show_flash_info flash all env", "display flash all env"},
{ "show_dual_image", do_show_all_dual_image_flag_info, 0, "show_dual_image dual image flag", "display dual image flag env"},
{ "debug_level", do_boot_debug_level, 2, "debug_level <0/1>", "set debug level."},
{ "reset", do_boot_reset, 0, "reset", "board reset"},
{ "boot_version", do_boot_version, 0, "boot_version", "boot version"},
{ "flash_erase", do_flash_erase, 3, "flash_erase <addr> <len>", "erase flash"},
{ "dual_image", do_personality_parm_cmd, 4, "dual_image <set/get> <commit/active> <kernel/rootfs/app1/app2> <value>", "dual_image commit/active flag"},
{ "fwc", do_personality_parm_cmd, 3, "fwc <set/get> <snoui/hwcfg/ethaddr> <value>", "snoui/hwcfg/etaddr env"},
{ "stop_restart", do_stop_restart, 0, "stop_restart", "stop bootloader restart"},
#endif
#ifndef BOOTROM_IN_SRAM
#if !defined(TCSUPPORT_FWC_ENV)
{ "go", do_go, 0, "go", "Booting the linux kernel."},
{ "decomp", do_decomp, 0, "decomp", "Decompress kernel image to ram."},
#endif
#endif
{ "memrl", do_memrl, 2, "memrl <addr>", "Read a word from addr."},
{ "memwl", do_memwl, 3, "memwl <addr> <value>", "Write a word to addr."},
#ifdef CONFIG_TP_IMAGE
#ifdef CONFIG_TP_DUAL_IMAGE
/* add by renjun 2017.07.05, set bootflag */
{ "bflag", do_bootflag, 3, "bflag get|set <0 1>", "Get or set bootflag."},
/* end add */
#endif /* CONFIG_TP_DUAL_IMAGE */
#endif /* CONFIG_TP_IMAGE */
{ "dump", do_dump, 3, "dump <addr> <len>", "Dump memory content."},
{ "jump", do_jump, 2, "jump <addr>", "Jump to addr."},
#ifdef TCSUPPORT_BB_NAND
{ "flash", do_flash, 4, "flash <dst> <src> <len> <oob>", "Write to flash from src to dst(oob: write nand oob if 1)."},
#else
{ "flash", do_flash, 4, "flash <dst> <src> <len>", "Write to flash from src to dst."},
#endif
{ "imginfo", do_imginfo, 0, "imginfo", "Show images info."},
#ifdef MT7505_GDMP
{"gdmpr", doGDmpCfg, 1, "gdmpr", "Dump GDMP Registers."},
{"gdmpm", doSysGdmpMem, 3, "gdmpm <start> <len>", "Dump GDMP Memory."},
#endif
#ifdef TCSUPPORT_NEW_SPIFLASH_DEBUG
{ "sftest", do_sf_basic_test, 1, "sftest <round>", "New SPI FLASH Test."},
{ "sfmats", do_sf_mats, 1, "sfmats [Round] [Scope:0~1] [isChipTest:0~1] [Exit:0~1] [ReadMode:0~7] [StartAddr]", "New SPI FLASH MATS+ Test."},
{ "sfbe", do_sf_be, 1, "sfbe", "New SPI FLASH Bulk Erase Test."},
{ "sfreadidle", do_sf_readidle_test, 1, "sfreadidle <idleEn:0~1> <blockNum:0~100> <4ByteRead:0~1>", "New SPI FLASH Read Idle Enable Test."},
{ "sfboot4", do_sf_bootin4Byte, 1, "sfboot4 <AddrMode>", "New SPI FLASH boot in 4Byte Mode for W25Q256FV."},
{ "sfnonalign", do_sf_nonAlign_test, 1, "sfnonalign", "New SPI FLASH Test."},
#ifdef TCSUPPORT_NEW_SPIFLASH_DEBUG_EXT
{ "sfmemcpy", do_sf_memcpy, 1, "sfmemcpy <AddrMode>", "New SPI FLASH boot in 4Byte Mode for W25Q256FV."},
{ "sf1ByteReadTest", do_sf_1ByteTest, 1, "sf1ByteReadTest <AddrMode>", "1Byte Read Test via Old/New SPI Flash Controller."},
{ "sfclockset", do_sf_ClockSet, 1, "sfclockset <0~31>", "New SPI FLASH Clock Set."},
{ "sftnset", do_sf_TnSet, 1, "sftnset <0~5>", "New SPI FLASH Tn Set."},
#endif
#if defined(TCSUPPORT_CPU_EN7512)||defined(TCSUPPORT_CPU_EN7521)
#ifdef TCSUPPORT_NEW_SPIFLASH_DEBUG
{ "spinand_rwtest", do_spinand_rw_test, 1, "spi nand rw test", "SPI NAND Test"},
{ "spinand_read", do_spinand_read, 1, "spi nand read", "SPI NAND Read"},
{ "spinand_write", do_spinand_write, 1, "spi nand write", "SPI NAND Write"},
{ "spinand_erase", do_spinand_erase, 1, "spi nand erase", "SPI NAND Erase"},
{ "spinand_nonaligntest", do_spinand_nonalign, 1, "spi nand nonalign", "SPI NAND NonAlign"},
{ "spicontroller_reg_test", do_spicontroller_reg_test, 1, "spi controller regs test", "SPI CONTROLLER REGS TEST"},
{ "spicontroller_interrupt_test", do_spicontroller_interrupt_test, 1, "spi controller interrupt test", "SPI CONTROLLER INTERRUPT TEST"},
{ "spicontroller_preload_test", do_spicontroller_preload_test, 1, "spi controller preload test", "SPI CONTROLLER PRELOAD TEST"},
{ "spicontroller_cpol_test", do_spicontroller_cpol_test, 1, "spi controller cpol test", "SPI CONTROLLER CPOL TEST"},
{ "spicontroller_strap_test", do_spicontroller_strap_test, 1, "spi controller strap test", "SPI CONTROLLER STRAP TEST"},
{ "spi_frequency", do_spi_frequency, 1, "spi_frequency", "SPI FREQUENCY TEST"},
#endif
#endif
#endif
#ifdef NAND_TEST_CMD
{ "nandit", init_nand, 2, "nandit <addr>", "Write to flash from src to dst."},
{ "nandrd", read_nand, 3, "nandrd <src> <len>", "Read flash from src."},
{ "nander", erase_nand, 3, "nander <dst> <len> <oob>", "Erase flash from dst(oob: force erase oob if 1)."},
{ "chkmem", check_data, 4, "chkmem <nand> <ddr> <len>", "Check data between nand and ddr."},
{ "innand", innand, 4, "innand <dst> <src> <len>", "Move data from spi to nand."},
#ifdef TCSUPPORT_NAND_RT63368
{ "checkbb", check_badblock, 2, "checkbb <total block>", "Check nandflash bad block."},
{ "markbb", mark_badblock, 2, "markbb <block>", "Mark nandflash bad block."},
{ "erasepb", erase_block_phy, 3, "erasepb <block> <num>", "Erase nandflash physical block."},
{ "readpg", read_page_phy, 3, "readpg <page> <len>", "Read nandflash physical page."},
{ "writepg", write_page_phy, 5, "writepg <page> <byte index> <value> <ecc>",
"change one byte of page"},
#endif
#endif
#ifdef BOOTROM_BACKDOOR
{ "bdstore", do_bdconfig_store, 3, "bdstore <flash dst> <bin src>", "Do backdoor config store"},
{ "bdshow", do_bdconfig_show, 0, "bdshow", "Show backdoor config "},
#ifdef BACKDOOR_SWITCH
{ "bdswitch", do_bdconfig_switch, 0, "bdswitch[1|0]", "Enable or disable backdoor function "},
{ "ddrcalswitch", do_ddrcal_switch, 0, "ddrcalswitch[1|0]", "Enable or disable ddr calibration funciton "},
{ "drambistswitch", do_dram_bist_switch, 0, "drambistswitch[0|1|2]", "disable or enable, and quick or normal test "},
#endif
#endif
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
#ifndef TCSUPPORT_RESERVEAREA_EXTEND
{ "passwd", do_passwd, 3, "passwd <username> <password>", "Change username and password"},
#endif
#endif
#ifdef SPI_TEST_CMD
{ "erase", do_erase, 3, "erase <dst> <len>", "Erase flash."},
{ "program",do_program, 4, "program <dst> <src> <len>", "Program flash."},
#endif
{ "xmdm", do_xmodem_rx, 3, "xmdm <addr> <len>", "Xmodem receive to addr."},
#ifdef BOOTROM_IN_SRAM
{ "xmdmf", do_xmodem_rx_flash, 4, "xmdmf <addr> <len> <flash addr>", "Xmodem receive to addr and Write to flash."},
#endif
#ifndef BOOTROM_IN_SRAM
{ "miir", do_miir, 3, "miir <phyaddr> <reg>", "Read ethernet phy reg."},
{ "miiw", do_miiw, 4, "miiw <phyaddr> <reg> <value>", "Write ethernet phy reg."},
#if defined(MT7530_SLT) || defined(MT7530_SUPPORT)
{ "gswr", doGswRead, 2, "gswr <reg>", "Read gsw reg."},
{ "gsww", doGswWrite, 3, "gsww <reg> <value>", "Write gsw reg."},
#endif
#endif
#if defined(MT7530_SLT)
{"emiir", doPhyMMDRead, 4, "emiir <phyaddr> <devaddr> <reg>"},
{"emiiw", doPhyMMDWrite, 4, "emiiw <phyaddr> <devaddr> <reg> <val>"},
{"miibpr", doTCMiiBPRead, 3, "miibpr <phyAddr> <reg>"},
{"miibpw", doTCMiiBPWrite, 4, "miibpw <phyAddr> <reg> <value>"},
{ "phyr", doPhyMiiRead, 2, "phyr <phyaddr> <reg>", "Read ethernet phy reg."},
{ "phyw", doPhyMiiWrite, 2, "phyw <phyaddr> <reg> <value>", "Write ethernet phy reg."},
{ "dumpgsw",doDumpGSW, 2, "dumpgsw <port>", "Dump gsw reg."},
#endif
#ifdef SPI_TEST_CMD
{ "memcmp", do_memcmp, 4, "memcmp <addr1> <addr2> <len>", "Memory compare."},
{ "dmacpy", do_dmacpy, 4, "dmacpy <addr1> <addr2> <len>", "DMA Memory copy."},
{ "memcpy", do_memcpy, 4, "memcpy <addr1> <addr2> <len>", "Memory copy."},
{ "memcmp4",do_memcmp4, 4, "memcmp4 <addr1> <addr2> <len>", "Memory compare."},
{ "memcpy4",do_memcpy4, 4, "memcpy4 <addr1> <addr2> <len>", "Memory copy."},
{ "memcmp2",do_memcmp2, 4, "memcmp2 <addr1> <addr2> <len>", "Memory compare."},
{ "memcpy2",do_memcpy2, 4, "memcpy2 <addr1> <addr2> <len>", "Memory copy."},
{ "memset", do_memset, 4, "memset <addr> <pattern> <len>", "Memory set."},
{ "memset4",do_memset4, 4, "memset4 <addr> <pattern> <len>", "Memory set."},
{ "memset42",do_memset42, 5, "memset42 <addr> <pattern1> <pattern2> <len>", "Memory set."},
{ "memset44",do_memset44, 7, "memset44 <addr> <pattern1~4> <len>", "Memory set."},
{ "incr", do_incr, 4, "incr <addr> <pattern> <len>", "Memory set."},
{ "incrcmp",do_incrcmp, 4, "incrcmp <addr> <pattern> <len>", "Memory compare."},
{ "rreadb", do_rreadb, 3, "rreadb <addr1> <adddr2>", "Random read byte."},
{ "rreadl", do_rreadl, 4, "rreadl <addr1> <adddr2> <cnt>", "Random read word."},
{ "rwritel",do_rwritel, 5, "rwritel <addr1> <adddr2> <pattern> <cnt>", "Random read word."},
{ "step", do_step, 6, "step <addr> <pattern1> <pattern2> <step> <len>", "Memory set."},
{ "spidbg", do_spidbg, 2, "spidgb <1|0>", "spi flash debug."},
{ "spiqe", do_spiqe, 2, "spiqe <hpm>", ""},
{ "spird", do_spird, 0, "spird", ""},
#endif
#ifdef ETH_TEST_CMD
{ "ethsend", do_ethsend, 3, "ethsend <len> <cnt>", "Send ethernet frame."},
{ "ethsend2",do_ethsend2, 3, "ethsend2 <len> <cnt>", "Send ethernet frame."},
{ "ethdump", do_ethdump, 0, "ethdump", "Dump ethernet TX/RX ring"},
#endif
//{ "cpufreq",do_cpufreq, 3, "cpufreq <m> <n>", "Set CPU Freq"},
{ "cpufreq",do_cpufreq, 2, "cpufreq <freq num> / <m> <n>", "Set CPU Freq <156~450>(freq has to be multiple of 6)"},
#ifndef BOOTROM_IN_SRAM
{ "ipaddr", do_ipaddr, 2, "ipaddr <ip addr>", "Change modem's IP."},
#endif
#ifdef BOOT_LZMA_SUPPORT
{ "httpd", do_httpd, 0, "httpd", "Start Web Server"},
#endif
#ifdef TC3262
#ifndef BOOTROM_IN_SRAM
{ "ddrdrv", do_ddrdrv, 0, "ddrdrv <..>", "Change DDR driving length"},
#endif
#endif
#ifdef SPI_DRAM_TEST_CMD
{ "dramtest",do_dramtest, 0, "dramtest <addr> <size> <pat> <w Byte> <infinite>", ""},
{ "flashtest",do_flashtest, 0, "flashtest <addr> <size> <pat> <infinite>", ""},
{ "spiregrw",do_spiregrw, 0, "spiregrw", "spi ctrler reg rw test"},
{ "gdmatestdram",do_gdmatestdram, 0, "gdmatestdram <infinite>", ""},
{ "gdmatestflash",do_gdmatestflash, 0, "gdmatestflash <infinite>", ""},
{ "gdmatestreg",do_gdmatestreg, 0, "gdmatestreg", ""},
#if defined(DRAM_PROTECT_TEST)
/****************************** memory access range protection *****************************/
{ "rbus_init", do_rbus_init, 1, "rbus_init", "register rbus isr."},
{ "dram_protect_size", do_dram_protect_size, 2, "dram_protect_size <dram size>", "Dram protect size set."},
{ "dram_protect_test1", do_dram_protect_test1, 4, "dram_protect_test1 <counter> <isUnCache:0|1> <cpu:0|dma:1>",
"Dram memory protection test case 1"},
{ "dram_protect_test2", do_dram_protect_test2, 4, "dram_protect_test2 <counter> <isUnCache:0|1> <cpu:0|dma:1>",
"Dram memory protection test case 2"},
{ "dram_protect_test3", do_dram_protect_test3, 4, "dram_protect_test3 <counter> <isUnCache:0|1> <cpu:0|dma:1>",
"Dram memory protection test case 3"},
{ "dram_protect_test4", do_dram_protect_test4, 4, "dram_protect_test4 <counter> <isUnCache:0|1> <cpu:0|dma:1>",
"Dram memory protection test case 4"},
{ "seg_read_protect", do_seg_read_protect, 2, "seg_reade_protect <disable:0|enable:1>",
"Segmentation memory read protection set"},
{ "seg_write_protect", do_seg_write_protect, 2, "seg_write_protect <disable:0|enable:1>",
"Segmentation memory write protection set"},
{ "seg_addr_set", do_seg_addr_set, 4, "seg_addr_set <seg1:0|seg2:1> <start_addr> <end_addr>",
"Segmentation memory address set"},
{ "seg_read_protect", do_seg_read_protect, 2, "seg_read_protect <disable:0|enable:1>",
"Segmentation memory read protection set"},
{ "seg_protect_test", do_seg_protect_test, 6, "seg_protect_test <counter> <seg1:0|seg2:1> <isUnCache:0|1> <cpu:0|dma:1> <testCase: 0|1|2|3|4>", "Segmentation memory protection test case"},
{ "mem_protect_test", do_mem_protect_test, 4, "mem_protect_test <counter> <isUnCache:0|1> <cpu:0|dma:1> ", "Memory protection test"},
{ "mem_protect_test2", do_mem_protect_test2, 7, "mem_protect_test <counter> <isUnCache:0|1> <cpu:0|dma:1> <Add:0|Subtraction:1><byte offset> <Test Length>", "Memory protection test"},
#if defined(TCSUPPORT_CPU_EN7521) && defined(DRAM_PROTECT_TEST)
{ "mem_protect_dbgLevel", do_mem_protect_dbgLevel, 1, "mem_protect_dbgLevel 0~0xff (bitMap)", "set debug level for memory protection tests"},
{ "nmi_test_enable", do_nmi_test_enable, 1, "nmi_test_enable 0/1", "dis/enable nmi test in LAN driver ISR"},
#endif
/****************************** memory access range protection *****************************/
#endif
#endif
#if defined(RBUS_COUNTER_TEST)
{ "rbus_counter", do_rbus_counter, 0, "rbus_counter <type> <MIN~MAX> <length>"},
#endif
#ifdef MT7550_GPIO_TEST//tony add
{ "gpio_test", do_gpio_test, 0, "gpio_test"},
#endif
#ifdef TCSUPPORT_MTD_PARTITIONS_CMDLINE
{"mtd", do_get_mtd_info, 0, "mtd"},
#endif
{ NULL, NULL, 0, NULL, NULL}
};
static void cmd_pad_space(char *buf, int len)
{
int slen = len - strlen(buf);
char *cp = buf;
int i;
if (slen) {
cp += strlen(buf);
for (i = 0; i < slen; i++)
*cp++ = ' ';
*cp ='\0';
}
}
int do_null(int argc, char *argv[])
{
}
int do_help(int argc, char *argv[])
{
cmds_t *cmdp;
char buf[80];
for (cmdp = CMDS; cmdp->name != NULL; cmdp++) {
if (cmdp->usage != NULL) {
strcpy(buf, cmdp->usage);
cmd_pad_space(buf, 36);
printf("%s", buf);
}
if (cmdp->help != NULL) {
strcpy(buf, cmdp->help);
cmd_pad_space(buf, 42);
printf("%s", buf);
}
printf("\n");
}
return 0;
}
extern int set_lzma_addr(char* lzma_data_start, char* lzma_data_end);
extern unsigned long decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, unsigned long free_mem_ptr_end_p);
extern void macResetSwMAC(void);
#ifdef CONFIG_DUAL_IMAGE
extern int checkimage(int imageflag);
#ifdef TCSUPPORT_DUAL_IMAGE_ENHANCE
extern unsigned short CheckSum(unsigned short *szBUF,int iSize);
#endif
#endif
#ifndef BOOTROM_IN_SRAM
int do_decomp(int argc, char *argv[])
{
unsigned long output_data;
unsigned long free_mem_ptr;
unsigned long free_mem_ptr_end;
void (*jumpAddr)();
#ifdef CONFIG_DUAL_IMAGE
int retflag = 0;
char *bufaddr = (char*)FLAG_ADDR;
char flag = 0;
#ifdef TCSUPPORT_DUAL_IMAGE_ENHANCE
char* trx_addr = NULL;
unsigned char slave_ver[32], main_ver[32];
int index;
unsigned int header_len, kernel_len, rootfs_len;
unsigned long retlen;
int binlen = 0;
struct trx_header *trx_main = NULL;
struct trx_header *trx_slave = NULL;
unsigned short checkSum_main = 0;
unsigned short checkSum_slave = 0;
char checkflag = 0;
#endif
#endif
struct trx_header *trx_temp = NULL;
char* temp_addr = NULL;
unsigned long startAddr = 0x0;
unsigned int kernel_size = 0;
int trx_header_len = sizeof(struct trx_header);
output_data = KERNEL_START_ADDR;
free_mem_ptr = KERNEL_RAM_START;
free_mem_ptr_end = KERNEL_RAM_END;
if (tc_inl(CR_INTC_IMR) != 0x0)
macResetSwMAC();
tc_outl(CR_INTC_IMR, 0x0);
tc_outl(CR_TIMER_CTL, 0x0);
#ifdef CONFIG_DUAL_IMAGE
if(checkimage(MAIN_IMAGE) < 0)
#ifdef TCSUPPORT_DUAL_IMAGE_ENHANCE
trx_temp = (struct trx_header*)(flash_base+flash_tclinux_start+offset);
#else
trx_temp = (struct trx_header*)(flash_base+flash_tclinux_start+TCLINUX_SLAVE_FLASH_START);
#endif
else
#endif
trx_temp = (struct trx_header*)(flash_base+flash_tclinux_start);
temp_addr = &(trx_temp->kernel_len);
kernel_size = READ_FLASH_DWORD(temp_addr)+0x100;
kernel_size = (kernel_size+0x10000)&~(0x10000-1);
temp_addr = &(trx_temp->decompAddr);
startAddr = READ_FLASH_DWORD(temp_addr);
if(startAddr != 0)
{
output_data = startAddr;
#ifdef CONFIG_DUAL_IMAGE
bufaddr = (char*)(startAddr-1);
#endif
}
else
{
output_data = 0x80020000;
#ifdef CONFIG_DUAL_IMAGE
bufaddr = (char*)(0x8001ffff);
#endif
}
#ifdef CONFIG_DUAL_IMAGE
retflag = checkimage(MAIN_IMAGE);
if(retflag < 0)
{
flag = 1;
retflag = checkimage(SLAVE_IMAGE);
if(retflag < 0)
return;
}
//store flag information to 0x8001ffff
*bufaddr = flag;
#endif
printf("Decompress to %X free_mem_ptr=%X free_mem_ptr_end=%X\n", output_data, free_mem_ptr, free_mem_ptr_end);
#ifdef CONFIG_DUAL_IMAGE
/*flag 0:main image;1:backup image*/
/* frankliao added 20100806 */
if (flag==1){
prom_printf("from slave\n");
#ifdef TCSUPPORT_DUAL_IMAGE_ENHANCE
// set_lzma_addr(0xb0020100+offset, 0xb0120000+offset);
// set_lzma_addr(flash_base+0x20100+offset, flash_base+0x120000+offset);
set_lzma_addr(flash_base+flash_tclinux_start+trx_header_len+offset, flash_base+flash_tclinux_start+kernel_size+offset);
//copy slave to main
// trx_slave = (struct trx_header *)(0xb0000000+0x20000+offset);
trx_slave = (struct trx_header *)(flash_base+flash_tclinux_start+offset);
trx_addr = &(trx_slave->header_len);
header_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_slave->kernel_len);
kernel_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_slave->rootfs_len);
rootfs_len = READ_FLASH_DWORD(trx_addr);
// binlen = trx_slave->header_len + trx_slave->kernel_len + trx_slave->rootfs_len;
binlen = header_len + kernel_len + rootfs_len;
flash_erase(flash_tclinux_start, binlen);
if (IS_NANDFLASH)
flash_read(flash_base+flash_tclinux_start+offset, binlen, &retlen, 0x80020000);
else
memcpy(0x80020000, flash_base+flash_tclinux_start+offset, binlen);
// memcpy(0x80020000, 0xb0000000+0x20000+offset, binlen);
flash_write(flash_tclinux_start, binlen, &retlen, 0x80020000);
#else
// set_lzma_addr(0xb0020100+0x500000, 0xb0120000+0x500000);
// set_lzma_addr(flash_base + 0x20100 + 0x500000, flash_base + 0x120000 + 0x500000);
set_lzma_addr(flash_base + flash_tclinux_start+trx_header_len + TCLINUX_SLAVE_FLASH_START, flash_base + flash_tclinux_start+kernel_size+ TCLINUX_SLAVE_FLASH_START);
#endif
} else {
prom_printf("from main\n");
// set_lzma_addr(0xb0020100, 0xb0120000);
// set_lzma_addr(flash_base + 0x20100, flash_base + 0x120000);
set_lzma_addr(flash_base + flash_tclinux_start+trx_header_len, flash_base +flash_tclinux_start+ kernel_size);//xflu
#ifdef TCSUPPORT_DUAL_IMAGE_ENHANCE
//copy main to slave
trx_main = (struct trx_header*)(flash_base+flash_tclinux_start);
trx_addr = &(trx_main->header_len);
header_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_main->kernel_len);
kernel_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_main->rootfs_len);
rootfs_len = READ_FLASH_DWORD(trx_addr);
binlen = header_len + kernel_len + rootfs_len;
trx_slave = (struct trx_header *)(flash_base+flash_tclinux_start+offset);
trx_addr = &(trx_slave->version);
for (index=0; index<32; index++, trx_addr++){
slave_ver[index] = READ_FLASH_BYTE(trx_addr);
}
trx_addr = &(trx_main->version);
for (index=0; index<32; index++, trx_addr++){
main_ver[index] = READ_FLASH_BYTE(trx_addr);
}
#if 0
trx_main = (struct trx_header *)(0xb0000000+0x20000);
binlen = trx_main->header_len + trx_main->kernel_len + trx_main->rootfs_len;
trx_slave = (struct trx_header *)(0xb0000000+0x20000+offset);
#endif
// if((checkimage(SLAVE_IMAGE) < 0) || (strcmp(trx_main->version,trx_slave->version) != 0)) {
if((checkimage(SLAVE_IMAGE) < 0) || (strcmp(main_ver, slave_ver) != 0)) {
checkflag = 1;
}
if(checkflag == 0){
if (IS_NANDFLASH)
flash_read(flash_base+flash_tclinux_start, binlen, &retlen, 0x80020000);
else
memcpy(0x80020000, flash_base+flash_tclinux_start, binlen);
checkSum_main = CheckSum(0x80020000,binlen);
if (IS_NANDFLASH)
flash_read(flash_base+flash_tclinux_start+offset, binlen, &retlen, 0x80020000);
else
memcpy(0x80020000, flash_base+flash_tclinux_start+offset, binlen);
checkSum_slave = CheckSum(0x80020000,binlen);
if(checkSum_main != checkSum_slave){
checkflag = 1;
}
}
if(checkflag == 1){
flash_erase(flash_tclinux_start+offset, binlen);
if (IS_NANDFLASH)
flash_read(flash_base+flash_tclinux_start, binlen, &retlen, 0x80020000);
else
memcpy(0x80020000, flash_base+flash_tclinux_start, binlen);
flash_write(flash_tclinux_start+offset, binlen, &retlen, 0x80020000);
}
#if 0
if(checkflag == 0){
memcpy(0x80020000, 0xb0000000+0x20000, binlen);
checkSum_main = CheckSum(0x80020000,binlen);
memcpy(0x80020000, 0xb0000000+0x20000+offset, binlen);
checkSum_slave = CheckSum(0x80020000,binlen);
if(checkSum_main != checkSum_slave)
checkflag = 1;
}
if(checkflag == 1){
flash_erase(0x20000+offset, binlen);
memcpy(0x80020000, 0xb0000000+0x20000, binlen);
flash_write(0x20000+offset, binlen, &retlen, 0x80020000);
}
#endif
#endif
}
#else
// set_lzma_addr(KERNEL_FLASH_START, KERNEL_FLASH_END);
set_lzma_addr( (flash_base + flash_tclinux_start+trx_header_len), (flash_base + LZMA_FLASH_LARGE_END) );
#endif
decompress_kernel(output_data, free_mem_ptr, free_mem_ptr_end);
#ifdef TC3262
if (IS_NANDFLASH )
flush_icache_range(startAddr, startAddr + kernel_size*4);
#endif
return 0;
}
int do_go(int argc, char *argv[])
{
unsigned long output_data;
unsigned long free_mem_ptr;
unsigned long free_mem_ptr_end;
void (*jumpAddr)();
#ifdef CONFIG_DUAL_IMAGE
int retflag = 0;
char *bufaddr = (char*)FLAG_ADDR;
char flag = 0;
#if defined(TCSUPPORT_DUAL_IMAGE_ENHANCE) || defined(TCSUPPORT_NAND_BADBLOCK_CHECK)
char *trx_addr = NULL;
unsigned char slave_ver[32], main_ver[32];
unsigned int header_len, kernel_len, rootfs_len;
int index;
unsigned long retlen;
int binlen = 0;
struct trx_header *trx_main = NULL;
struct trx_header *trx_slave = NULL;
unsigned short checkSum_main = 0;
unsigned short checkSum_slave = 0;
char checkflag = 0;
#endif
#endif
struct trx_header *trx_temp = NULL;
char* temp_addr = NULL;
unsigned long startAddr = 0x0;
unsigned int kernel_size = 0;
int trx_header_len = sizeof(struct trx_header);
output_data = KERNEL_START_ADDR;
free_mem_ptr = KERNEL_RAM_START;
free_mem_ptr_end = KERNEL_RAM_END;
if(isRT65168){
VPint(0xbfb00084) = 0x1; //reset DMT
pause(20);
VPint(0xbfb00084) = 0x0; //reset DMT
pause(1);
VPint(0xbf500424) = 0x6004; //write AFE reg4
}
if (tc_inl(CR_INTC_IMR) != 0x0)
macResetSwMAC();
tc_outl(CR_INTC_IMR, 0x0);
tc_outl(CR_TIMER_CTL, 0x0);
#ifdef CONFIG_DUAL_IMAGE
if(checkimage(MAIN_IMAGE) < 0)
#ifdef TCSUPPORT_DUAL_IMAGE_ENHANCE
trx_temp = (struct trx_header*)(flash_base+flash_tclinux_start+offset);
#elif defined(TCSUPPORT_NAND_BADBLOCK_CHECK)
trx_temp = (struct trx_header*)(flash_base+0x2280000);
#else
trx_temp = (struct trx_header*)(flash_base+flash_tclinux_start+TCLINUX_SLAVE_FLASH_START);
#endif
else
#endif
#ifdef TCSUPPORT_NAND_BADBLOCK_CHECK
trx_temp = (struct trx_header*)(flash_base+0x280000);
#elif defined(TCSUPPORT_NAND_RT63368)
trx_temp = (struct trx_header*)(flash_base + NAND_KERNEL_OFFSET);
#else
trx_temp = (struct trx_header*)(flash_base+flash_tclinux_start);
#endif
#if defined(TCSUPPORT_NAND_BADBLOCK_CHECK) || defined(TCSUPPORT_NAND_RT63368)
temp_addr = &(trx_temp->kernel_len);
kernel_size = READ_FLASH_DWORD(temp_addr) + 0x100;
#else
temp_addr = &(trx_temp->kernel_len);
kernel_size = READ_FLASH_DWORD(temp_addr) + 0x100;
kernel_size = (kernel_size+0x10000)&~(0x10000-1);//64k aligin
#endif
temp_addr = &(trx_temp->decompAddr);
startAddr = READ_FLASH_DWORD(temp_addr);
if(startAddr != 0){
output_data = startAddr;
#ifdef CONFIG_DUAL_IMAGE
bufaddr = (char*)(startAddr-1);
#endif
}
else
{
output_data = 0x80020000;
#ifdef CONFIG_DUAL_IMAGE
bufaddr = (char*)(0x8001ffff);
#endif
}
#ifdef CONFIG_DUAL_IMAGE
retflag = checkimage(MAIN_IMAGE);
if(retflag < 0)
{
flag = 1;
retflag = checkimage(SLAVE_IMAGE);
if(retflag < 0)
return;
}
//store flag information to 0x8001ffff
*bufaddr = flag;
#endif
printf("Decompress to %X free_mem_ptr=%X free_mem_ptr_end=%X\n", output_data, free_mem_ptr, free_mem_ptr_end);
#ifdef CONFIG_DUAL_IMAGE
/*flag 0:main image;1:backup image*/
/* frankliao added 20100806 */
if (flag==1){
prom_printf("from slave\n");
#ifdef TCSUPPORT_DUAL_IMAGE_ENHANCE
// set_lzma_addr(0xb0020100+offset, 0xb0120000+offset);
// set_lzma_addr(flash_base+0x20100+offset, flash_base+0x120000+offset);
set_lzma_addr(flash_base+flash_tclinux_start+trx_header_len+offset, flash_base+flash_tclinux_start+kernel_size+offset);
// trx_slave = (struct trx_header *)(0xb0000000+0x20000+offset);
trx_slave = (struct trx_header*)(flash_base+flash_tclinux_start+offset);
trx_addr = &(trx_slave->header_len);
header_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_slave->kernel_len);
kernel_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_slave->rootfs_len);
rootfs_len = READ_FLASH_DWORD(trx_addr);
// binlen = trx_slave->header_len + trx_slave->kernel_len + trx_slave->rootfs_len;
binlen = header_len + kernel_len + rootfs_len;
#ifdef TCSUPPORT_NAND_RT63368
flash_erase(NAND_KERNEL_OFFSET, binlen);
#else
flash_erase(flash_tclinux_start, binlen);
#endif
if (IS_NANDFLASH)
flash_read(flash_base+flash_tclinux_start+offset, binlen, &retlen, 0x80020000);
else
memcpy(0x80020000, flash_base+flash_tclinux_start+offset, binlen);
#ifdef TCSUPPORT_NAND_RT63368
flash_write(NAND_KERNEL_OFFSET, binlen, &retlen, 0x80020000);
#else
flash_write(flash_tclinux_start, binlen, &retlen, 0x80020000);
#endif
#elif defined(TCSUPPORT_NAND_BADBLOCK_CHECK)
set_lzma_addr(flash_base+0x2280000+0x100, flash_base+0x2280000+kernel_size);
trx_slave = (struct trx_header*)(flash_base+0x2280000);
trx_addr = &(trx_slave->header_len);
header_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_slave->kernel_len);
kernel_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_slave->rootfs_len);
rootfs_len = READ_FLASH_DWORD(trx_addr);
binlen = header_len + kernel_len + rootfs_len;
flash_erase(0x280000, binlen);
flash_read(flash_base+0x2280000, binlen, &retlen, 0x80020000);
flash_write(0x2280000, binlen, &retlen, 0x80020000);
#else
// set_lzma_addr(0xb0020100+0x500000, 0xb0120000+0x500000);
// set_lzma_addr(flash_base + 0x20100 + 0x500000, flash_base + 0x120000 + 0x500000);
set_lzma_addr(flash_base + flash_tclinux_start+trx_header_len + TCLINUX_SLAVE_FLASH_START, flash_base + flash_tclinux_start+kernel_size+ TCLINUX_SLAVE_FLASH_START);
#endif
} else {
prom_printf("from main\n");
// set_lzma_addr(0xb0020100, 0xb0120000);
// set_lzma_addr(flash_base + 0x20100, flash_base + 0x120000);
#ifdef TCSUPPORT_NAND_BADBLOCK_CHECK
set_lzma_addr( (flash_base + 0x280000 + 0x100), (flash_base + 0x280000 + kernel_size) );
#elif defined(TCSUPPORT_NAND_RT63368)
set_lzma_addr( (flash_base + NAND_KERNEL_OFFSET + 0x100), (flash_base + NAND_KERNEL_OFFSET + kernel_size) );
#else
set_lzma_addr(flash_base + flash_tclinux_start+trx_header_len, flash_base + flash_tclinux_start + kernel_size);//xflu
#endif
#ifdef TCSUPPORT_DUAL_IMAGE_ENHANCE
//copy main to slave
// trx_main = (struct trx_header *)(0xb0000000+0x20000);
#ifdef TCSUPPORT_NAND_RT63368
trx_main = (struct trx_header*)(flash_base+NAND_KERNEL_OFFSET);
#else
trx_main = (struct trx_header *)(flash_base+flash_tclinux_start);
#endif
trx_addr = &(trx_main->header_len);
header_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_main->kernel_len);
kernel_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_main->rootfs_len);
rootfs_len = READ_FLASH_DWORD(trx_addr);
binlen = header_len + kernel_len + rootfs_len;
trx_slave = (struct trx_header *)(flash_base+flash_tclinux_start+offset);
trx_addr = &(trx_slave->version);
for (index=0; index<32; index++, trx_addr++){
slave_ver[index] = READ_FLASH_BYTE(trx_addr);
}
trx_addr = &(trx_main->version);
for (index=0; index<32; index++, trx_addr++){
main_ver[index] = READ_FLASH_BYTE(trx_addr);
}
// trx_slave = (struct trx_header *)(0xb0000000+0x20000+offset);
// if((checkimage(SLAVE_IMAGE) < 0) || (strcmp(trx_main->version,trx_slave->version) != 0)) {
if((checkimage(SLAVE_IMAGE) < 0) || (strcmp(main_ver, slave_ver) != 0)) {
checkflag = 1;
}
if(checkflag == 0){
if (IS_NANDFLASH)
#ifdef TCSUPPORT_NAND_RT63368
flash_read(flash_base+NAND_KERNEL_OFFSET, binlen, &retlen, 0x80020000);
#else
flash_read(flash_base+flash_tclinux_start, binlen, &retlen, 0x80020000);
#endif
else
memcpy(0x80020000, flash_base+flash_tclinux_start, binlen);
checkSum_main = CheckSum(0x80020000,binlen);
if (IS_NANDFLASH)
flash_read(flash_base+flash_tclinux_start+offset, binlen, &retlen, 0x80020000);
else
memcpy(0x80020000, flash_base+flash_tclinux_start+offset, binlen);
checkSum_slave = CheckSum(0x80020000,binlen);
if(checkSum_main != checkSum_slave){
checkflag = 1;
}
#if 0
memcpy(0x80020000, 0xb0000000+0x20000, binlen);
checkSum_main = CheckSum(0x80020000,binlen);
memcpy(0x80020000, 0xb0000000+0x20000+offset, binlen);
checkSum_slave = CheckSum(0x80020000,binlen);
if(checkSum_main != checkSum_slave)
checkflag = 1;
#endif
}
if(checkflag == 1){
flash_erase(flash_tclinux_start+offset, binlen);
if (IS_NANDFLASH)
#ifdef TCSUPPORT_NAND_RT63368
flash_read(flash_base+NAND_KERNEL_OFFSET, binlen, &retlen, 0x80020000);
#else
flash_read(flash_base+flash_tclinux_start, binlen, &retlen, 0x80020000);
#endif
else
memcpy(0x80020000, flash_base+flash_tclinux_start, binlen);
flash_write(flash_tclinux_start+offset, binlen, &retlen, 0x80020000);
}
#if 0
if(checkflag == 1){
flash_erase(0x20000+offset, binlen);
memcpy(0x80020000, 0xb0000000+0x20000, binlen);
flash_write(0x20000+offset, binlen, &retlen, 0x80020000);
}
#endif
#elif defined(TCSUPPORT_NAND_BADBLOCK_CHECK)
trx_main = (struct trx_header*)(flash_base+0x280000);
trx_addr = &(trx_main->header_len);
header_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_main->kernel_len);
kernel_len = READ_FLASH_DWORD(trx_addr);
trx_addr = &(trx_main->rootfs_len);
rootfs_len = READ_FLASH_DWORD(trx_addr);
binlen = header_len + kernel_len + rootfs_len;
trx_slave = (struct trx_header *)(flash_base+0x2280000);
trx_addr = &(trx_slave->version);
for (index=0; index<32; index++, trx_addr++){
slave_ver[index] = READ_FLASH_BYTE(trx_addr);
}
trx_addr = &(trx_main->version);
for (index=0; index<32; index++, trx_addr++){
main_ver[index] = READ_FLASH_BYTE(trx_addr);
}
if((checkimage(SLAVE_IMAGE) < 0) || (strcmp(main_ver, slave_ver) != 0)) {
checkflag = 1;
}
if(checkflag == 0){
flash_read(flash_base+0x280000, binlen, &retlen, 0x80020000);
checkSum_main = CheckSum(0x80020000,binlen);
flash_read(flash_base+0x2280000, binlen, &retlen, 0x80020000);
checkSum_slave = CheckSum(0x80020000,binlen);
if(checkSum_main != checkSum_slave){
checkflag = 1;
}
}
if(checkflag == 1){
flash_erase(0x2280000, binlen);
flash_read(flash_base+0x280000, binlen, &retlen, 0x80020000);
flash_write(0x2280000, binlen, &retlen, 0x80020000);
}
#endif
}
#else
// set_lzma_addr(KERNEL_FLASH_START, KERNEL_FLASH_END);
#ifdef TCSUPPORT_NAND_BADBLOCK_CHECK
set_lzma_addr( (flash_base + 0x280000 + 0x100), (flash_base + 0x280000 + 0x180000) );
#elif defined(TCSUPPORT_NAND_RT63368)
set_lzma_addr( (flash_base + NAND_KERNEL_OFFSET + 0x100), (flash_base + NAND_KERNEL_OFFSET + 0x1a0000) );
#else
set_lzma_addr( (flash_base + flash_tclinux_start+trx_header_len), (flash_base + flash_tclinux_start + kernel_size) );
#endif
#endif
decompress_kernel(output_data, free_mem_ptr, free_mem_ptr_end);
/*Unify the kernel address to jump for all chip, shnwind*/
//#ifdef TC3262
// jumpAddr = (void (*)(void))0x80020000;
//#else
/* FIXME */
// if (isTC3162L3P3 || isTC3162L4P4 || isTC3162L5P5) {
//jumpAddr = (void (*)(void))KERNEL_START_ADDR;
if(startAddr != 0)
jumpAddr = (void (*)(void))(startAddr);
else
jumpAddr = (void (*)(void))(0x80020000);
// } else {
//jumpAddr = (void (*)(void))0x80020404;
//jumpAddr = (void (*)(void))0x80020420;
//jumpAddr = (void (*)(void))0x800203fc;
// jumpAddr = (void (*)(void))0x800205bc;
// }
//#endif
#ifdef TC3262
if (IS_NANDFLASH )
flush_icache_range(startAddr, startAddr + kernel_size*4);
#endif
(*jumpAddr)();
return 0;
}
#endif
int do_memrl(int argc, char *argv[])
{
unsigned long addr;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
printf("%X: %X \n", addr, tc_inl(addr));
return 0;
}
int do_memwl(int argc, char *argv[])
{
unsigned long addr;
unsigned long value;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
value = strtoul((const char*)(argv[2]), (char **)NULL, 16);
tc_outl(addr, value);
printf("%X: %X \n", addr, tc_inl(addr));
return 0;
}
#ifdef CONFIG_TP_IMAGE
#ifdef CONFIG_TP_DUAL_IMAGE
/* add by renjun 2017.07.05, set bootflag */
static int do_bootflag(int argc, char *argv[])
{
char bootflag = 0;
unsigned long retlen = 0;
IMG_BOOT_INFO bootinfo;
memset(&bootinfo, 0, sizeof(IMG_BOOT_INFO));
bootinfo.active_flag = 0;
if(0 == strcmp("set", argv[1]))
{
bootinfo.magic = htonl(0x4455414C); /* DUAL */
bootflag = strtoul((const char*)(argv[2]), (char **)NULL, 16);
if(1 == bootflag)
{
bootinfo.image[0].is_committed = 0;
bootinfo.image[0].is_active = 0;
bootinfo.image[0].is_valid = 1; /* BosaZhong@17Sep2015, modify, 0 -> 1 specially for viettel. */
bootinfo.image[1].is_committed = 1;
bootinfo.image[1].is_active = 1; /* BosaZhong@17Sep2015, modify, 0 -> 1 specially for viettel. */
bootinfo.image[1].is_valid = 1;
}
else
{
bootinfo.image[0].is_committed = 1;
bootinfo.image[0].is_active = 1; /* BosaZhong@17Sep2015, modify, 0 -> 1 specially for viettel. */
bootinfo.image[0].is_valid = 1;
bootinfo.image[1].is_committed = 0;
bootinfo.image[1].is_active = 0;
bootinfo.image[1].is_valid = 1; /* BosaZhong@17Sep2015, modify, 0 -> 1 specially for viettel. */
}
flash_erase(TP_BOOT_FLAG_OFFSET, sizeof(IMG_BOOT_INFO));
printf("\n");
flash_write(TP_BOOT_FLAG_OFFSET, sizeof(IMG_BOOT_INFO), &retlen, (const unsigned char *)(&bootinfo));
}
else
{
flash_read(TP_BOOT_FLAG_OFFSET, sizeof(IMG_BOOT_INFO), &retlen, (unsigned char *)(&bootinfo));
printf("act_flag:%d, img0[%d %d %d], img1[%d %d %d]\n",
bootinfo.active_flag,
bootinfo.image[0].is_committed,
bootinfo.image[0].is_active,
bootinfo.image[0].is_valid,
bootinfo.image[1].is_committed,
bootinfo.image[1].is_active,
bootinfo.image[1].is_valid);
if(1 == bootinfo.active_flag)
{
if (1 == bootinfo.image[1].is_active)
{
bootflag = 1;
}
else
{
bootflag = 0;
}
}
else
{
if (1 == bootinfo.image[1].is_committed)
{
bootflag = 1;
}
else
{
bootflag = 0;
}
}
printf("bootflag = %X \n", bootflag);
}
return 0;
}
/* end add */
#endif /* CONFIG_TP_DUAL_IMAGE */
#endif /* CONFIG_TP_IMAGE */
#define putchar(x) serial_outc(x)
int do_dump(int argc, char *argv[])
{
unsigned long addr;
unsigned long len;
register int n, m, c, r;
unsigned char temp[16];
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
len = strtoul((const char*)(argv[2]), (char **)NULL, 16);
for( n = len; n > 0; ){
printf("%.8x", addr);
putchar(' ');
r = n < 16? n: 16;
memcpy((void *) temp, (void *) addr, r);
addr += r;
for( m = 0; m < r; ++m ){
putchar((m & 3) == 0 && m > 0? '.': ' ');
printf("%.2x", temp[m]);
}
for(; m < 16; ++m )
printf(" ");
printf(" |");
for( m = 0; m < r; ++m ){
c = temp[m];
putchar(' ' <= c && c <= '~'? c: '.');
}
n -= r;
for(; m < 16; ++m )
putchar(' ');
printf("|\n");
}
return 0;
}
int do_jump(int argc, char *argv[])
{
void (*jumpAddr)();
unsigned long addr;
int i;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
printf("Jump to %X\n", addr);
#ifndef BOOTROM_IN_SRAM
if (tc_inl(CR_INTC_IMR) != 0x0)
macResetSwMAC();
#endif
tc_outl(CR_INTC_IMR, 0x0);
tc_outl(CR_TIMER_CTL, 0x0);
jumpAddr = (void (*)(void))addr;
(*jumpAddr)();
return 0;
}
int do_flash(int argc, char *argv[])
{
unsigned long dst;
unsigned long src;
unsigned long len;
unsigned long retlen;
dst = strtoul((const char*)(argv[1]), (char **)NULL, 16);
src = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
#ifdef TCSUPPORT_BB_NAND
#if defined(TCSUPPORT_CPU_MT7510)||defined(TCSUPPORT_CPU_MT7520) || defined(TCSUPPORT_CPU_EN7512) || defined(TCSUPPORT_CPU_EN7521)
if(argc == 5){
en_oob_write = strtoul((const char*)(argv[4]), (char **)NULL, 16);
/*en_oob_write =1, read oob free buf from image and write to oob*/
}
#endif
#endif
printf("Write to flash from %X to %X with %X bytes\n", src, dst, len);
flash_erase(dst, len);
printf("\n");
flash_write(dst, len, &retlen, (const unsigned char *) (src));
return 0;
}
extern int flash_read(unsigned long from,
unsigned long len, unsigned long *retlen, unsigned char *buf);
int do_imginfo(int argc, char *argv[])
{
int os_size = 0;
char os_version[32];
int ret_len = 0;
struct trx_header trx_header_buff;
unsigned long mainStart = 0;
unsigned long slaveStart = 0;
#ifdef TCSUPPORT_NAND_BADBLOCK_CHECK
mainStart = 0x280000;
#elif defined(TCSUPPORT_NAND_RT63368)
mainStart = NAND_KERNEL_OFFSET;
#else
mainStart = TCLINUX_FLASH_START;
#endif
memset(&trx_header_buff,0,sizeof(struct trx_header));
flash_read(mainStart,sizeof(struct trx_header),&ret_len,(char*)(&trx_header_buff));
memset(os_version,0,32);
memmove(os_version,trx_header_buff.version,32);
os_size = trx_header_buff.len;
printf("os1:%s",os_version);
#ifdef TCSUPPORT_DUAL_IMAGE_ENHANCE
#ifdef TCSUPPORT_NAND_RT63368
slaveStart = mainStart + offset - 0x20000;
#else
slaveStart = mainStart+offset;
#endif
#elif defined(TCSUPPORT_NAND_BADBLOCK_CHECK)
slaveStart = mainStart + 0x2280000;
#else
slaveStart = mainStart+TCLINUX_SLAVE_FLASH_START;
#endif
memset(&trx_header_buff,0,sizeof(struct trx_header));
flash_read(slaveStart,sizeof(struct trx_header),&ret_len,(char*)(&trx_header_buff));
memset(os_version,0,32);
memmove(os_version,trx_header_buff.version,32);
os_size = trx_header_buff.len;
printf("os2:%s",os_version);
return 0;
}
#ifdef MT7505_GDMP
int doSysGdmpMem(int argc, char *argv[])
{
unsigned long length;
unsigned char buf[18];
int i,j = 0;
unsigned long *ptr;
ptr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
length = strtoul((const char*)(argv[2]), (char **)NULL, 16);
if ((length % 8) != 0)
{
printf("the length must be n times 8!!!\n");
return 0;
}
for( i = 0; i < length/4; i = i + 2)
{
printf("%.8x", (unsigned long) (*(ptr + i + 1)));
printf("%.8x", (unsigned long) (*(ptr + i)));
printf( "\r\n");
}
return 0;
}
int doGDmpCfg(int argc, char *argv[])
{
#define GDMP_REG_BASE 0xBFBF0000
#define GDMP_GLO_CFG (GDMP_REG_BASE + 0x00009000)
#define GDMP_CAP_RLT (GDMP_REG_BASE + 0x00009004)
#define GDMP_TRG_RLT (GDMP_REG_BASE + 0x00009008)
#define GDMP_INT_STS (GDMP_REG_BASE + 0x00009010)
#define GDMP_INT_MSK (GDMP_REG_BASE + 0x00009014)
#define GDMP_PRB_SEL (GDMP_REG_BASE + 0x00009020)
#define GDMP_TRG_PATN0_L (GDMP_REG_BASE + 0x00009030)
#define GDMP_TRG_PATN0_MSK_L (GDMP_REG_BASE + 0x00009034)
#define GDMP_TRG_PATN0_H (GDMP_REG_BASE + 0x00009038)
#define GDMP_TRG_PATN0_MSK_H (GDMP_REG_BASE + 0x0000903C)
#define GDMP_TRG_PATN1_L (GDMP_REG_BASE + 0x00009040)
#define GDMP_TRG_PATN1_MSK_L (GDMP_REG_BASE + 0x00009044)
#define GDMP_TRG_PATN1_H (GDMP_REG_BASE + 0x00009048)
#define GDMP_TRG_PATN1_MSK_H (GDMP_REG_BASE + 0x0000904C)
#define GDMP_TRG_MODE (GDMP_REG_BASE + 0x00009050)
#define GDMP_CAP_CFG (GDMP_REG_BASE + 0x00009060)
#define GDMP_CLK_CFG (GDMP_REG_BASE + 0x00009070)
printf("GDMP_GLO_CFG\t%08lx\r\n",VPint(GDMP_GLO_CFG));
printf("GDMP_CAP_RLT\t%08lx\r\n",VPint(GDMP_CAP_RLT));
printf("GDMP_TRG_RLT\t%08lx\r\n",VPint(GDMP_TRG_RLT));
printf("GDMP_INT_STS\t%08lx\r\n",VPint(GDMP_INT_STS));
printf("GDMP_INT_MSK\t%08lx\r\n",VPint(GDMP_INT_MSK));
printf("GDMP_PRB_SEL\t%08lx\r\n",VPint(GDMP_PRB_SEL));
printf("GDMP_TRG_PATN0_L\t%08lx\r\n",VPint(GDMP_TRG_PATN0_L));
printf("GDMP_TRG_PATN0_MSK_L\t%08lx\r\n",VPint(GDMP_TRG_PATN0_MSK_L));
printf("GDMP_TRG_PATN0_H\t%08lx\r\n",VPint(GDMP_TRG_PATN0_H));
printf("GDMP_TRG_PATN0_MSK_H\t%08lx\r\n",VPint(GDMP_TRG_PATN0_MSK_H));
printf("GDMP_TRG_PATN1_L\t%08lx\r\n",VPint(GDMP_TRG_PATN1_L));
printf("GDMP_TRG_PATN1_MSK_L\t%08lx\r\n",VPint(GDMP_TRG_PATN1_MSK_L));
printf("GDMP_TRG_PATN1_H\t%08lx\r\n",VPint(GDMP_TRG_PATN1_H));
printf("GDMP_TRG_PATN1_MSK_H\t%08lx\r\n",VPint(GDMP_TRG_PATN1_MSK_H));
printf("GDMP_TRG_MODE\t%08lx\r\n",VPint(GDMP_TRG_MODE));
printf("GDMP_CAP_CFG\t%08lx\r\n",VPint(GDMP_CAP_CFG));
printf("GDMP_CLK_CFG\t%08lx\r\n",VPint(GDMP_CLK_CFG));
return 0;
}
#endif
#if defined(TCSUPPORT_NEW_SPIFLASH_DEBUG)
#define SPI_FREQUENCY_ADJUST_REG 0xBFA200CC
static void set_spi_clock_speed( u32 clock_factor)
{
unsigned long val;
val = VPint(SPI_FREQUENCY_ADJUST_REG);
val &= 0xffff0000;
val |= (((clock_factor) << 8)|1);
pause(10);
val &= 0xfffffffe;
pause(10);
val |= 0x1;
VPint(SPI_FREQUENCY_ADJUST_REG) = val;
printf("Set SPI Clock to %d Mhz\n", (250/clock_factor));
}
#define PP_MAX (256)
#define SE_MAX (4096)
#define SE_CNT (16)
#define SEED_MAX (0x100)
#define AUTOREAD_TEST (0)
#define MANUALREAD_TEST (1)
#define MUXREAD_TEST (2)
#define SIZE_32MiB 0x2000000
#define SIZE_64KiB 0x10000
#define SFC_CLOCK_MAX 150
#define TP_MAX (10)
uint8 TestPattern[TP_MAX] =
{
{0xA5},
{0x5A},
{0xFF},
{0x00},
{0x55},
{0xAA},
{0x96},
{0x69},
{0xCC},
{0x33}
};
uint8 TestMode_TEXT[3][12] =
{
{"AutoMode"},
{"ManualMode"},
{"MuxMode"},
};
uint8 ReadMode_TEXT[6][20] =
{
{"ReadData"},
{"FastRead"},
{"FastRead_DualOut"},
{"FastRead_DualIO"},
{"FastRead_QuadOut"},
{"FastRead_QuadIO"},
};
uint8 MuxMode_TEXT[8][25] =
{
{"Auto_ReadData"},
{"Auto_FastRead"},
{"Auto_FastRead_DualOut"},
{"Auto_FastRead_DualIO"},
{"Manual_ReadData"},
{"Manual_FastRead"},
{"Manual_FastRead_DualOut"},
{"Manual_FastRead_DualIO"},
};
uint8 clk_rate=0;
uint8 CLKRate_TEXT[3][12] =
{
{"25MHZ"},
{"50MHZ"},
{"Changing"},
};
uint8 Address3B4B_TEXT[3][40] =
{
{"4Bytes access all 32MB flash"},
{"3Bytes access front 16MB flash"},
{"3Bytes access, and use 13/0C/3C/BC"},
};
uint32 Round_Value = 0;
uint16 AutoRead_Value = 0;
uint16 ManualRead_Value = 0;
uint16 MuxRead_Value = 0;
uint16 isProgram_Value = 0;
uint16 CLKRate_Value = 0;
uint16 Exit_Value = 0;
uint16 Address3B4B_Value = 0;
uint32 TestPattern_Value = 0;
uint32 StartAddress_Value = 0;
uint16 ReadIdle_Value = 0;
uint32 Mats_Round_Value = 0;
uint32 Mats_Scope_Value = 0;
uint32 Mats_isChipTest_Value = 0;
uint32 Mats_ReadMode_Value = 0;
uint32 Mats_Address_Value = 0;
uint16 Tn_Value = 0;
uint16 Tn_cnt = 0;
uint8 TnMappingTab[6];
uint16 AutoRead_cnt = 0;
uint16 ManualRead_cnt = 0;
uint16 MuxRead_cnt = 0;
uint16 AutoMappingTab[6];
uint16 ManualMappingTab[4];
uint16 MuxMappingTab[8];
uint32 rd_time = 0;
uint32 pp_time = 0;
uint32 se_time = 0;
uint32 be_time = 0;
extern void enter_4Byte_mode(void);
extern void exit_4Byte_mode(void);
static void SF_Test_Helper(){
#if 1
printf("\nusage: \tsftest [Round] [AutoRD:0~15] [ManualRD:0~15] [MuxRD:0~1] [isProg:0~1] [CLK Rate:0~31] [Exit:0~1] [3B4B:0~2] [Pattern] [StartAddr] [RDIdle] [Tn]\n");
#else
printf("\nusage: \tsftest [Round] [AutoRD:0~15] [ManualRD:0~15] [MuxRD:0~1] [isProg:0~1] [CLK Rate:0~2] [Exit:0~1] [3B4B:0~2] [Pattern] [StartAddr] [RDIdle] [Tn]\n");
#endif
printf("Round: \t\t0~65535 means test round. DEFAULT VALUE is 10\n");
printf("AutoRD: \t0~63 is b'00000000~00111111, bit5 means Auto QuadIO, bit4 means Auto QuadOutput, bit3 means Auto_singleRead, bit2 means Auto_FastRead, bit1 means Auto_FastDualOutput, \n\t\tbit0 means Auto_FastDualIO. DEFAULT VALUE is 8\n");
printf("ManualRD: \t0~15 is b'0000~1111, bit3 means Manual_singleRead, bit2 means Manual_FastRead, bit1 means Manual_FastDualOutput, \n\t\tbit0 means Manual_FastDualIO. DEFAULT VALUE is 0\n");
printf("MuxRD: \t\t0 means disable MuxRead, 1 means enable MuxRead. DEFAULT VALUE is 0\n");
printf("isProg: \t0 means disable Program, 1 means enable Program. DEFAULT VALUE is 0\n");
#ifdef TCSUPPORT_CPU_MT7505
#if 1
printf("CLK Rate: \t0 means 15MHZ, 1 means (150/1)MHZ, 2 means (150/2)MHZ, 3 means (150/3)MHZ, etc... DEFAULT VALUE is 0\n");
#else
printf("CLK Rate: \t0 means 25MHZ, 1 means 50MHZ, 2 means CLK Rate change on the fly. DEFAULT VALUE is 0\n");
#endif
#endif
#if defined(TCSUPPORT_CPU_EN7512)||defined(TCSUPPORT_CPU_EN7521)
#if 1 /* ASIC */
printf("CLK Rate: \t0 means auto switch clock test, 1 ~ 31 means (250/CLK Rate)MHZ, DEFAULT VALUE is 0\n");
#else /* FPGA */
printf("CLK Rate: \taoto test 25Mhz and 50Mhz\n");
#endif
#endif
printf("Exit: \t\t0 means continue test while error happens, 1 means exit test while error happens. DEFAULT VALUE is 0\n");
printf("3B4B: \t\t0 means 4Bytes access all 32MB, 1 means 3Bytes access front 16MB, 2 means uses 13/0C/3C/BC. DEFAULT VALUE is 0\n");
printf("TestPattern: \t0:normal test, 1:A5, 2:5A, 3:FF, 4:00, 5:55, 6:AA, 7:96, 8:69, 9:CC, 10:33, 11:Random. DEFAULT VALUE is 0\n");
printf("StartAddr: \tDEFAULT VALUE is 0xF00000\n");
printf("RDIdle: \t0: Disable Read IDLE, 1: Enable Read IDLE. DEFAULT VALUE is 0\n");
printf("Tn: \t0~15 is b'000000~111111, the value of bit0~bit5 means T0~T5 enable or desable. DEFAULT VALUE is 0\n");
}
static void SF_Mats_Helper(){
printf("\nusage: \tsfmats [Round] [Scope:0~1] [isChipTest:0~1] [Exit:0~1] [ReadMode:0~7] [StartAddr]\n");
printf("Round: \t\t0~65535 means test round. DEFAULT VALUE is 10\n");
printf("Scope: \t\t0 means 64KB, 1 means all Flash. DEFAULT VALUE is 0\n");
printf("isChipTest: \t0 means ChipTest disable, 1 means ChipTest enable. DEFAULT VALUE is 0\n");
printf("Exit: \t\t0 means continue test while error happens, 1 means exit test while error happens. DEFAULT VALUE is 0\n");
printf("ReadMode: \t0~3:Auto Mode[Single/Fast/DualOut/DualIO], 4~7:Manual Mode[Single/Fast/DualOut/DualIO] DEFAULT VALUE is 0\n");
printf("StartAddr: \tDEFAULT VALUE is 0x700000\n\n");
}
static void dumpCell_flash(u8* src, u32 len){
u32 i=0;
u32 src_temp=0;
src_temp = src;
src_temp &= 0x03FFFFFF;
src_temp |= 0xBC000000;
printf("\r\n src is 0x08x, src_temp is 0x%08x", src, src_temp);
printf("\r\n\t\t00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
for(i=0; i<len; i++){
if((i&15)==0){
printf("\r\n0x%08X:\t", src_temp+i);
}
printf("%02x ", *(u8*)(src_temp+i));
}
printf("\r\n");
}/*end dumpCell_flash*/
static void dumpCell_buffer(u8* buf, u32 len, u32 from){
u32 i=0;
from &= 0x03FFFFFF;
from |= 0xBC000000;
printf("\r\n\t\t00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
for(i=0; i<len; i++){
if((i&15)==0){
printf("\r\n0x%08X:\t", from+i);
}
printf("%02x ", *(buf+i));
}
printf("\r\n");
}/*end dumpCell_buffer*/
unsigned long sf_rand_ascend()
{
static unsigned long rand_asc=0;
rand_asc++;
return rand_asc;
}
unsigned long sf_rand_descend()
{
static unsigned long rand_des=0;
rand_des--;
return rand_des;
}
unsigned long sf_rand()
{
static unsigned long rand_item=0;
rand_item = (rand_item * 123 + 59) % 65536;
return rand_item;
}
int sf_mats_test(u32 round)
{
int i=0, j=0;
unsigned long retlen=0;
unsigned long size=0;
unsigned long erasesize=0;
unsigned long cur_se_off=0;
unsigned long cur_pp_off=0;
unsigned long start_addr=0;
unsigned char rd_buf[2]={0};
unsigned char pp_buf[2]={0};
erasesize = mtd.erasesize;
size = mtd.size;
start_addr = Mats_Address_Value;
pp_buf[0] = 0x00;
printf("\n\n\n>>>>>>> Round%d Test::current read mode is %s >>>>>>\n", round, MuxMode_TEXT[Mats_ReadMode_Value]);
if(Mats_isChipTest_Value) {
printf("\nChip Test-Ascend begin, Start Address is 0x%08x, End Address is 0x%08x!\n", start_addr, size);
for(cur_se_off = start_addr; (cur_se_off + erasesize) <= size; cur_se_off += erasesize) {
/* erase one block, the size is 64KB */
flash_erase(cur_se_off, erasesize);
}
for(cur_se_off = start_addr; (cur_se_off + erasesize) <= size; cur_se_off += erasesize) {
/* erase one block, the size is 64KB */
spiflash_mats_read(cur_se_off, 1, &retlen, rd_buf);
if(rd_buf[0] != 0xFF) {
printf("\n####Chip_Ascend: Read fail at Address %X, value is %X, should be FF, reg 0xBFA10000 is 0x%08x\n", cur_se_off, rd_buf[0], SF_READ_MODE_VALUE);
if(Exit_Value == 1)
goto read_fail;
else
break;
}
flash_write(cur_se_off, 1, &retlen, pp_buf);
}
printf("\nChip Test-Descend begin, Start Address is 0x%08x, End Address is 0x%08x!\n", start_addr, size);
for(cur_se_off = start_addr; (cur_se_off + erasesize) <= size; cur_se_off += erasesize) {
/* erase one block, the size is 64KB */
flash_erase(cur_se_off, erasesize);
}
for(cur_se_off = size-erasesize ; cur_se_off >= start_addr; cur_se_off -= erasesize) {
/* erase one block, the size is 64KB */
spiflash_mats_read(cur_se_off, 1, &retlen, rd_buf);
if(rd_buf[0] != 0xFF) {
printf("\n####Chip_Descend: Read fail at Address %X, value is %X, should be FF, reg 0xBFA10000 is 0x%08x\n", cur_se_off, rd_buf[0], SF_READ_MODE_VALUE);
if(Exit_Value == 1)
goto read_fail;
else
break;
}
flash_write(cur_se_off, 1, &retlen, pp_buf);
}
}
if(Mats_Scope_Value == 0)
size = start_addr + erasesize;
for(cur_se_off = start_addr; (cur_se_off + erasesize) <= size; cur_se_off += erasesize) {
printf("\n64KB Erase-Ascend begin, Address is 0x%08x!\n", cur_se_off);
/* erase one block, the size is 64KB */
flash_erase(cur_se_off, erasesize);
/* check the content of the block */
for(j=0; j<SE_CNT * SE_MAX; ++j){
spiflash_mats_read(cur_se_off+j, 1, &retlen, rd_buf);
if(rd_buf[0] != 0xFF) {
printf("\n####Block_Ascend: Read fail at Address %X::index is %d, value is %X, should be FF, reg 0xBFA10000 is 0x%08x, clk_rate is %s\n", cur_se_off+j, j, rd_buf[j], SF_READ_MODE_VALUE, CLKRate_TEXT[clk_rate]);
if(Exit_Value == 1)
goto read_fail;
else
break;
}
flash_write(cur_se_off+j, 1, &retlen, pp_buf);
}
printf("\n64KB Erase-Descend begin, Address is 0x%08x!\n", cur_se_off);
/* erase one block, the size is 64KB */
flash_erase(cur_se_off, erasesize);
/* check the content of the block */
for(j=SE_CNT * SE_MAX-1; j>=0 ; --j){
spiflash_mats_read(cur_se_off+j, 1, &retlen, rd_buf);
if(rd_buf[0] != 0xFF) {
printf("\n####Block_Descend: Read fail at Address %X::index is %d, value is %X, should be %X, reg 0xBFA10000 is 0x%08x, clk_rate is %s\n", cur_se_off+j, j, rd_buf[j], 0xFF, SF_READ_MODE_VALUE, CLKRate_TEXT[clk_rate]);
if(Exit_Value == 1)
goto read_fail;
else
break;
}
flash_write(cur_se_off+j, 1, &retlen, pp_buf);
}
}
return 0;
read_fail:
return -1;
}
static unsigned char se_buf[SE_MAX]={0};
int sf_basic_test(u32 round, u32 readtest)
{
unsigned long retlen=0;
unsigned long erasesize=0;
unsigned long size=0;
unsigned long cur_se_off=0;
unsigned long cur_pp_off=0;
unsigned long start_addr=0;
unsigned char se_buf[SE_MAX]={0};
unsigned char pp_buf[PP_MAX]={0};
unsigned char seed=0;
int cur_round=0;
int i=0, j=0, k=0;
int index=0;
u32 read_mode=0;
u32 begtime=0, endtime=0, passtime=0;
#if 0
u32 rd_begtime=0, rd_endtime=0, rd_passtime=0, rd_total_time=0;
u32 rd_begtick=0, rd_endtick=0;
#else
u32 rd_total_time=0;
u32 pp_total_time=0;
u32 rd1_average_time=0;
u32 rd2_average_time=0;
u32 se_average_time=0;
u32 pp_average_time=0;
u32 count_64KB=0;
#endif
erasesize = mtd.erasesize;
size = mtd.size;
start_addr = StartAddress_Value;
count_64KB = (size - start_addr) / SIZE_64KiB;
cur_round = round % (TP_MAX+1);
//read_mode = round % 5;
if(readtest == AUTOREAD_TEST)
printf("\n\n\n>>>>>>> Round%d Test::current test is AUTOREAD_TEST >>>>>>\n", round);
else if(readtest == MANUALREAD_TEST)
printf("\n\n\n>>>>>>> Round%d Test::current test is MANUALREAD_TEST >>>>>>\n", round);
else if(readtest == MUXREAD_TEST)
printf("\n\n\n>>>>>>> Round%d Test::current test is MUXREAD_TEST >>>>>>\n", round);
/* check flash ID */
index = spiflash_probe();
if (index < 0) {
printf ("\n########spiflash ID read error\n");
}
begtime = getTime();
for(cur_se_off = start_addr; (cur_se_off + erasesize) <= size; cur_se_off += erasesize) {
/* erase one block, the size is 64KB */
flash_erase(cur_se_off, erasesize);
printf("\nerase addr=%x size=%x passtime is %lu ", cur_se_off, erasesize, se_time);
se_average_time += se_time / count_64KB;
rd_total_time = 0;
/* check the content of the block */
for(j=0; j<SE_CNT; j++){
if(readtest == AUTOREAD_TEST)
spiflash_autoread_test(cur_se_off+j*SE_MAX, SE_MAX, &retlen, se_buf, (++read_mode));
else if(readtest == MANUALREAD_TEST)
spiflash_manualread_test(cur_se_off+j*SE_MAX, SE_MAX, &retlen, se_buf, (++read_mode));
else if(readtest == MUXREAD_TEST)
spiflash_muxread_test(cur_se_off+j*SE_MAX, SE_MAX, &retlen, se_buf, (++read_mode));
rd_total_time += rd_time;
for(i=0; i<SE_MAX; i++) {
if(se_buf[i] != 0xFF) {
if(readtest == MUXREAD_TEST)
printf("\n####Erase fail at Address %X::index is %d, value is %X, should be %X, ReadMode is %s::%s, reg 0xBFA10000 is 0x%08x, clk_rate is %s\n", cur_se_off+j*SE_MAX+i, i, se_buf[i], 0xFF, TestMode_TEXT[readtest], MuxMode_TEXT[retlen & 0x7], SF_READ_MODE_VALUE, CLKRate_TEXT[clk_rate]);
else
printf("\n####Erase fail at Address %X::index is %d, value is %X, should be %X, ReadMode is %s::%s, reg 0xBFA10000 is 0x%08x, clk_rate is %s\n", cur_se_off+j*SE_MAX+i, i, se_buf[i], 0xFF, TestMode_TEXT[readtest], ReadMode_TEXT[retlen & 0x3], SF_READ_MODE_VALUE, CLKRate_TEXT[clk_rate]);
dumpCell_buffer((u8 *)(se_buf), SE_MAX, cur_se_off+j*SE_MAX);
if(Exit_Value == 1)
goto erase_fail;
else
break;
}
}
}
printf("\ne-read at Address %x, passtime is %lu ", cur_se_off, rd_total_time);
rd1_average_time += rd_total_time / count_64KB;
if(isProgram_Value == 1) {
rd_total_time = 0;
pp_total_time = 0;
for(cur_pp_off = cur_se_off; (cur_pp_off + PP_MAX) <= (cur_se_off + erasesize); cur_pp_off += PP_MAX) {
/* program 256Bytes of current blcok */
if(TestPattern_Value == 0) {
if(cur_round == TP_MAX) {
seed = sf_rand() % SEED_MAX;
for(i=0; i<PP_MAX; i++) {
pp_buf[i] = (seed+i) % SEED_MAX;
}
} else {
for(i=0; i<PP_MAX; i++) {
pp_buf[i] = TestPattern[cur_round];
}
}
} else if(TestPattern_Value == 11) {
seed = sf_rand() % SEED_MAX;
for(i=0; i<PP_MAX; i++) {
pp_buf[i] = (seed+i) % SEED_MAX;
}
} else {
for(i=0; i<PP_MAX; i++) {
pp_buf[i] = TestPattern[TestPattern_Value-1];
}
}
flash_write(cur_pp_off, PP_MAX, &retlen, pp_buf);
pp_total_time += pp_time;
//printf("\n Program flash from %X to %X", cur_pp_off, cur_pp_off + PP_MAX);
/* check the content of current 256 Bytes */
//spiflash_read_test(cur_pp_off, PP_MAX, &retlen, pp_buf, (read_mode++)%2);
if(readtest == AUTOREAD_TEST)
spiflash_autoread_test(cur_pp_off, PP_MAX, &retlen, pp_buf, (read_mode++));
else if(readtest == MANUALREAD_TEST)
spiflash_manualread_test(cur_pp_off, PP_MAX, &retlen, pp_buf, (read_mode++));
else if(readtest == MUXREAD_TEST)
spiflash_muxread_test(cur_pp_off, PP_MAX, &retlen, pp_buf, (read_mode++));
rd_total_time += rd_time;
for(i=0; i<PP_MAX; i++) {
if( pp_buf[i] != ((TestPattern_Value==0)?((cur_round == TP_MAX)?((seed+i) % SEED_MAX):(TestPattern[cur_round])):((TestPattern_Value==11)?((seed+i) % SEED_MAX):(TestPattern[TestPattern_Value-1]))) ) {
if(readtest == MUXREAD_TEST)
printf("\n####Program fail at Address %X::index is %d, value is %X, should be %X, ReadMode is %s::%s, reg 0xBFA10000 is 0x%08x, clk_rate is %s\n", cur_pp_off+i, i, pp_buf[i], ((TestPattern_Value==0)?((cur_round == TP_MAX)?((seed+i) % SEED_MAX):(TestPattern[cur_round])):((TestPattern_Value==11)?((seed+i) % SEED_MAX):(TestPattern[TestPattern_Value-1]))), TestMode_TEXT[readtest], MuxMode_TEXT[retlen & 0x7], SF_READ_MODE_VALUE, CLKRate_TEXT[clk_rate]);
else
printf("\n####Program fail at Address %X::index is %d, value is %X, should be %X, ReadMode is %s::%s, reg 0xBFA10000 is 0x%08x, clk_rate is %s\n", cur_pp_off+i, i, pp_buf[i], ((TestPattern_Value==0)?((cur_round == TP_MAX)?((seed+i) % SEED_MAX):(TestPattern[cur_round])):((TestPattern_Value==11)?((seed+i) % SEED_MAX):(TestPattern[TestPattern_Value-1]))), TestMode_TEXT[readtest], ReadMode_TEXT[retlen & 0x3], SF_READ_MODE_VALUE, CLKRate_TEXT[clk_rate]);
printf("program average time is %lu, current time is %lu\n", (pp_total_time)/((cur_pp_off - cur_se_off)>>8+1), pp_time);
dumpCell_buffer((u8 *)(pp_buf), PP_MAX, cur_pp_off);
if(Exit_Value == 1)
goto program_fail;
else
break;
}
}
}
printf("\nprogram at Address %x, passtime is %lu ", cur_se_off, pp_total_time);
printf("\np-read at Address %x, passtime is %lu \n", cur_se_off, rd_total_time);
pp_average_time += pp_total_time / count_64KB;
rd2_average_time += rd_total_time / count_64KB;
}
}
endtime = getTime();
if(endtime < begtime)
passtime = 0xffffffff - begtime + endtime;
else
passtime = endtime - begtime;
printf("\n\nRD1: %lu \nRD2: %lu \nSE: %lu \nPP: %lu ", rd1_average_time, rd2_average_time, se_average_time, pp_average_time);
printf("\n>>>>>>> Round%d Test Finish::passtime is %lums", round, passtime);
printf("\nCurrent Time is %d:%d:%d\n", endtime/3600000, (endtime/60000)%60, (endtime/1000)%60);
return 0;
erase_fail:
return -1;
program_fail:
return -2;
}
int sf_manual_test(u32 round)
{
return sf_basic_test(round, MANUALREAD_TEST);
}
int sf_auto_test(u32 round)
{
return sf_basic_test(round, AUTOREAD_TEST);
}
int sf_mux_test(u32 round)
{
return sf_basic_test(round, MUXREAD_TEST);
}
int do_sf_basic_test(int argc, char *argv[])
{
int i=0;
u32 round = 0;
u32 pattern = 0;
int result = 0;
clk_rate = 0;
Round_Value = 10;
AutoRead_Value = 8;
ManualRead_Value = 0;
MuxRead_Value = 0;
isProgram_Value = 0;
CLKRate_Value = 0;
Exit_Value = 0;
Address3B4B_Value = 0;
TestPattern_Value = 0;
StartAddress_Value = 0xF00000;
ReadIdle_Value = 0;
Tn_Value = 0;
Tn_cnt = 0;
TnMappingTab[0] = 0;
AutoRead_cnt = 0;
ManualRead_cnt = 0;
MuxRead_cnt = 0;
AutoRead_cnt = 1;
AutoMappingTab[0] = 0;
if(argc == 1){
SF_Test_Helper();
return -1;
}
if(argc >= 2){
Round_Value = simple_strtoul(argv[1], NULL, 10);
printf("Round is %lu\n", Round_Value);
}
if(argc >= 3){
AutoRead_Value = simple_strtoul(argv[2], NULL, 10);
if(AutoRead_Value > 64) {
printf("\nError: AutoRead Value must be [0~64]!\n");
SF_Test_Helper();
return -3;
}
else {
AutoRead_cnt = 0;
MuxRead_cnt = 0;
printf("AutoRead Value is %u, ", AutoRead_Value);
if(AutoRead_Value == 0)
printf("no Auto Read Test\n");
else {
printf("including ");
if(AutoRead_Value & 0x8) {
printf("Single Read, ");
AutoMappingTab[AutoRead_cnt++] = 0;
MuxMappingTab[MuxRead_cnt++] = 0;
}
if(AutoRead_Value & 0x4) {
printf("Fast Read, ");
AutoMappingTab[AutoRead_cnt++] = 1;
MuxMappingTab[MuxRead_cnt++] = 1;
}
if(AutoRead_Value & 0x2) {
printf("Fast Read Dual Output, ");
AutoMappingTab[AutoRead_cnt++] = 2;
MuxMappingTab[MuxRead_cnt++] = 2;
}
if(AutoRead_Value & 0x1) {
printf("Fast Read Dual IO, ");
AutoMappingTab[AutoRead_cnt++] = 3;
MuxMappingTab[MuxRead_cnt++] = 3;
}
if(AutoRead_Value & 0x10) {
printf("Fast Read Quad Output, ");
AutoMappingTab[AutoRead_cnt++] = 4;
}
if(AutoRead_Value & 0x20) {
printf("Fast Read Quad IO, ");
AutoMappingTab[AutoRead_cnt++] = 5;
}
printf("\n");
}
}
}
if(argc >= 4){
ManualRead_Value = simple_strtoul(argv[3], NULL, 10);
if(ManualRead_Value > 15) {
printf("\nError: ManualRead Value must be [0~15]!\n");
SF_Test_Helper();
return -4;
}
else {
ManualRead_cnt = 0;
printf("ManualRead Value is %u, ", ManualRead_Value);
if(ManualRead_Value == 0)
printf("no Manual Read Test\n");
else {
printf("including ");
if(ManualRead_Value & 0x8) {
printf("Single Read, ");
ManualMappingTab[ManualRead_cnt++] = 0;
MuxMappingTab[MuxRead_cnt++] = 4;
}
if(ManualRead_Value & 0x4) {
printf("Fast Read, ");
ManualMappingTab[ManualRead_cnt++] = 1;
MuxMappingTab[MuxRead_cnt++] = 5;
}
if(ManualRead_Value & 0x2) {
printf("Fast Read Dual Output, ");
ManualMappingTab[ManualRead_cnt++] = 2;
MuxMappingTab[MuxRead_cnt++] = 6;
}
if(ManualRead_Value & 0x1) {
printf("Fast Read Dual IO, ");
ManualMappingTab[ManualRead_cnt++] = 3;
MuxMappingTab[MuxRead_cnt++] = 7;
}
printf("\n");
}
}
}
if(argc >= 5){
MuxRead_Value = simple_strtoul(argv[4], NULL, 10);
if(MuxRead_Value > 1) {
printf("\nError: MuxRead Value must be [0~1]!\n");
SF_Test_Helper();
return -5;
}
else
printf("MuxRead is %s\n", ((MuxRead_Value==1)?"enable":"disable"));
}
if(argc >= 6){
isProgram_Value = simple_strtoul(argv[5], NULL, 10);
if(isProgram_Value > 1) {
printf("\nError: isProgram Value must be [0~1]!\n");
SF_Test_Helper();
return -6;
}
else
printf("Program is %s\n", ((isProgram_Value==1)?"enable":"disable"));
}
#if 1
if(argc >= 7){
CLKRate_Value = simple_strtoul(argv[6], NULL, 10);
if(CLKRate_Value > 31) {
printf("\nError: CLK Rate Value must be [0~31]!\n");
SF_Test_Helper();
return -7;
}
else {
#ifdef TCSUPPORT_CPU_MT7505
if(CLKRate_Value == 0)
CLKRate_Value = 10;
printf("CLK Rate is %dMHZ\n", (SFC_CLOCK_MAX / CLKRate_Value));
#endif
}
}
#else
if(argc >= 7){
CLKRate_Value = simple_strtoul(argv[6], NULL, 10);
if(CLKRate_Value > 2) {
printf("\nError: CLK Rate Value must be [0~2]!\n");
SF_Test_Helper();
return -7;
}
else
printf("CLK Rate is %s\n", CLKRate_TEXT[CLKRate_Value]);
}
#endif
if(argc >= 8){
Exit_Value = simple_strtoul(argv[7], NULL, 10);
if(Exit_Value > 1) {
printf("\nError: Exit Value must be [0~1]!\n");
SF_Test_Helper();
return -8;
}
else
printf("Exit while error is %s\n", ((Exit_Value==1)?"enable":"disable"));
}
if(argc >= 9){
Address3B4B_Value = simple_strtoul(argv[8], NULL, 10);
if(Address3B4B_Value > 2) {
printf("\nError: 3B4B Value must be [0~2]!\n");
SF_Test_Helper();
return -9;
}
else
printf("The way to access 32MB flash is %s\n", Address3B4B_TEXT[Address3B4B_Value]);
}
if(argc >= 10){
TestPattern_Value = simple_strtoul(argv[9], NULL, 10);
if(TestPattern_Value > 11) {
printf("\nError: Pattern Value must be [0~11]!\n");
SF_Test_Helper();
return -10;
}
else {
if(TestPattern_Value == 0)
printf("TestPattern is Normal Test\n");
else if(TestPattern_Value == 11)
printf("TestPattern is Increment Digital\n");
else
printf("TestPattern is %X\n", TestPattern[TestPattern_Value-1]);
}
}
if(argc >= 11){
StartAddress_Value = simple_strtoul(argv[10], NULL, 16);
StartAddress_Value &= 0xFFFF0000;
if(StartAddress_Value < 0x20000) {
StartAddress_Value = 0x20000;
}
printf("Test Start Address 0x%08x\n", StartAddress_Value);
}
if(argc >= 12){
ReadIdle_Value = simple_strtoul(argv[11], NULL, 10);
if(ReadIdle_Value > 1) {
printf("\nError: RDIdle Value must be [0~1]!\n");
SF_Test_Helper();
return -11;
}
else
printf("Read Idle is %s\n", ((ReadIdle_Value==1)?"enable":"disable"));
}
if(argc >= 13){
Tn_Value = simple_strtoul(argv[12], NULL, 10);
if(Tn_Value > 0x3F) {
printf("\nError: Tn Value must be [0~0x3F]!\n");
SF_Test_Helper();
return -12;
}
else {
Tn_cnt = 0;
if(Tn_Value == 0)
printf("Tn Switching Disable\n");
else if((Tn_Value & (Tn_Value-1)) == 0) {
Tn_cnt = 1;
printf("Tn Switching unnecessary\n");
} else {
if(Tn_Value & 0x1) {
printf("T0 ");
TnMappingTab[Tn_cnt++] = 0;
}
if(Tn_Value & 0x2) {
printf("T1 ");
TnMappingTab[Tn_cnt++] = 1;
}
if(Tn_Value & 0x4) {
printf("T2 ");
TnMappingTab[Tn_cnt++] = 2;
}
if(Tn_Value & 0x8) {
printf("T3 ");
TnMappingTab[Tn_cnt++] = 3;
}
if(Tn_Value & 0x10) {
printf("T4 ");
TnMappingTab[Tn_cnt++] = 4;
}
if(Tn_Value & 0x20) {
printf("T5 ");
TnMappingTab[Tn_cnt++] = 5;
}
printf("is Switching now!\n");
}
}
}
#ifdef TCSUPPORT_CPU_MT7505
#if 1
spiflash_clk_change(CLKRate_Value);
clk_rate = 0;
#else
if(CLKRate_Value == 0) {
clk_rate = 0;
spiflash_clk_change_25MHZ();
} else if(CLKRate_Value == 1) {
clk_rate = 1;
spiflash_clk_change_50MHZ();
}
#endif
#endif
if(mtd.size >= SIZE_32MiB){
if(Address3B4B_Value == 0) {
enter_4Byte_mode();
SEND_AUTO_4B_CMD;
printf("\n>>>come in 4Bytes Mode\n");
} else {
exit_4Byte_mode();
SEND_AUTO_3B_CMD;
printf("\n>>>exit 4Bytes Mode\n");
}
}
printf("\nAutoRead_cnt is %u, ManualRead_cnt is %u, MuxRead_cnt is %u\n", AutoRead_cnt, ManualRead_cnt, MuxRead_cnt);
for(i=0; i<AutoRead_cnt; i++)
printf("AutoRead[%d] is %u\n", i, AutoMappingTab[i]);
for(i=0; i<ManualRead_cnt; i++)
printf("ManualRead[%d] is %u\n", i, ManualMappingTab[i]);
for(i=0; i<MuxRead_cnt; i++)
printf("MuxRead[%d] is %u\n", i, MuxMappingTab[i]);
printf("\n>>>>>>>>>>>> SPI FLASH Test Begin!!!\n");
printf("\nVPint(CR_TIMER1_LDV) is 0x%08X\n", VPint(CR_TIMER1_LDV));
//VPint(CR_TIMER1_LDV) = 0xFFFFFFFF;
printf("\nVPint(CR_TIMER1_LDV) is 0x%08X\n", VPint(CR_TIMER1_LDV));
sf_regDef_test();
for(pattern=0; pattern<16; pattern++)
sf_regRW_test(pattern);
sf_regRW_test(0xFFFFFFFF);
for(round = 0; round < Round_Value; round++) {
printf("\nRound %d\n\n", round);
#if defined(TCSUPPORT_CPU_EN7512) || defined(TCSUPPORT_CPU_EN7521)
#if 1 /* ASCI */
if( CLKRate_Value == 0 ) /* Aoto test for multiple spi clock frequency */
{
if( (round %4) ==0)
{
VPint(0xBFA10098)=0;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
pause(1000);
set_spi_clock_speed(7);
/* adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
pause(1000);
}
else if( (round %4) ==1)
{
VPint(0xBFA10098)=1;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
pause(1000);
set_spi_clock_speed(7);
printf("Clock register =0x%x\n", VPint(0xBFA200CC));
/* adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
pause(1000);
}
else if( (round %4) ==2)
{
VPint(0xBFA10098)=0;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
pause(1000);
set_spi_clock_speed(0xa);
/* adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
pause(1000);
}
else if( (round %4) ==3)
{
VPint(0xBFA10098)=1;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
pause(1000);
set_spi_clock_speed(0xa);
/* adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
pause(1000);
}
}
else /* Setting SPI clock frequency base on user intput */
{
set_spi_clock_speed(CLKRate_Value);
}
#else /* FPGA (Note: EN7512 FPGA only have 2 type of static clock speed to switch) */
if( (round %4) ==0)
{
VPint(0xBFA10098)=0;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
VPint(0xBFA2FF00) &= 0xFFFFFFFE ;
printf("Clock register =0x%x\n", VPint(0xBFA2FF00));
/* The 50Mhz must adjust the delay parameter */
VPint(0xbfa1009c) = 0xa;
printf("0xbfa1009c registet =0x%x\n", VPint(0xbfa1009c));
}
if( (round %4) ==1)
{
VPint(0xBFA10098)=1;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
VPint(0xBFA2FF00) &= 0xFFFFFFFE ;
printf("Clock register =0x%x\n", VPint(0xBFA2FF00));
/* The 50Mhz must adjust the delay parameter */
VPint(0xbfa1009c) = 0xa;
printf("0xbfa1009c registet =0x%x\n", VPint(0xbfa1009c));
}
if( (round %4) ==2)
{
VPint(0xBFA10098)=0;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
VPint(0xBFA2FF00) |= 0x1;
printf("Clock register =0x%x\n", VPint(0xBFA2FF00));
/* The 25Mhz must adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c registet =0x%x\n", VPint(0xbfa1009c));
}
if( (round %4) ==3)
{
VPint(0xBFA10098)=1;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
VPint(0xBFA2FF00) |= 0x1;
printf("Clock register =0x%x\n", VPint(0xBFA2FF00));
/* The 25Mhz must adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c registet =0x%x\n", VPint(0xbfa1009c));
}
#endif
#endif
if(AutoRead_Value != 0) {
result = sf_auto_test(round);
if((result != 0) && (Exit_Value == 1))
return -13;
}
if(ManualRead_Value != 0) {
result = sf_manual_test(round);
if((result != 0) && (Exit_Value == 1))
return -14;
}
if(MuxRead_Value != 0) {
result = sf_mux_test(round);
if((result != 0) && (Exit_Value == 1))
return -15;
}
}
return 0;
}
int do_sf_mats(int argc, char *argv[])
{
int i=0;
u32 round = 0;
u32 pattern = 0;
int result = 0;
Mats_Round_Value = 10;
Mats_Scope_Value = 0;
Mats_isChipTest_Value = 0;
Mats_ReadMode_Value = 0;
Mats_Address_Value = 0x700000;
clk_rate = 0;
Address3B4B_Value = 0;
CLKRate_Value = 0;
ReadIdle_Value = 0;
if(argc == 1){
SF_Mats_Helper();
return -1;
}
if(argc >= 2){
Mats_Round_Value = simple_strtoul(argv[1], NULL, 10);
printf("Mats Round is %lu\n", Mats_Round_Value);
}
if(argc >= 3){
Mats_Scope_Value = simple_strtoul(argv[2], NULL, 10);
if(Mats_Scope_Value > 1) {
printf("\nError: Scope Value must be [0~1]!\n");
SF_Mats_Helper();
return -2;
}
else
printf("Mats Test Scope is %s\n", ((Mats_Scope_Value==0)?"64KB":"All Flash"));
}
if(argc >= 4){
Mats_isChipTest_Value = simple_strtoul(argv[3], NULL, 10);
if(Mats_isChipTest_Value > 1) {
printf("\nError: isChipTest Value must be [0~1]!\n");
SF_Mats_Helper();
return -3;
}
else
printf("Mats Chip Test is %s\n", ((Mats_isChipTest_Value==1)?"enable":"disable"));
}
if(argc >= 5){
Exit_Value = simple_strtoul(argv[4], NULL, 10);
if(Exit_Value > 1) {
printf("\nError: Exit Value must be [0~1]!\n");
SF_Mats_Helper();
return -4;
}
else
printf("Exit while error is %s\n", ((Exit_Value==1)?"enable":"disable"));
}
if(argc >= 6){
Mats_ReadMode_Value = simple_strtoul(argv[5], NULL, 10);
if(Mats_ReadMode_Value > 7) {
printf("\nError: Read Mode must be [0~7]!\n");
SF_Mats_Helper();
return -5;
}
else
printf("Mats Read Mode is %s\n", MuxMode_TEXT[Mats_ReadMode_Value]);
}
if(argc >= 7){
Mats_Address_Value = simple_strtoul(argv[6], NULL, 16);
Mats_Address_Value &= 0xFFFF0000;
if(Mats_Address_Value < 0x20000) {
Mats_Address_Value = 0x20000;
}
printf("Mats Test Start Address 0x%08x\n", Mats_Address_Value);
}
spiflash_clk_change_25MHZ();
SEND_AUTO_READ_CMD;
if(mtd.size >= SIZE_32MiB){
enter_4Byte_mode();
}
for(round = 0; round < Mats_Round_Value; round++) {
result = sf_mats_test(round);
if((result != 0) && (Exit_Value == 1))
return -6;
}
}
int do_sf_be(int argc, char *argv[])
{
spiflash_bulk_erase();
printf("\nbulk erase time is %lums\n", be_time);
}
int do_sf_readidle_test(int argc, char *argv[])
{
register unsigned char tmp=0;
register unsigned int tmp4=0;
u32 count = 0x10000;
u32 blockNum = 0;
unsigned char *s = 0xbfc00000;
unsigned int *s4 = 0xbfc00000;
u8 read_idle_en = 0;
u8 readMode = 0;
u32 begtime=0, endtime=0, passtime=0;
u32 begtick=0, endtick=0;
if(argc == 1){
printf("sfreadidle <idleEn:0~1> <blockNum:0~100> <4ByteRead:0~1>\n");
return -1;
}
if(argc >= 2){
read_idle_en = simple_strtoul(argv[1], NULL, 10);
if(read_idle_en <=1)
printf("read_idle_en is %s\n", ((read_idle_en==1)?("enable"):("disable")));
else {
printf("read_idle_en should be in [0~1]\n");
return -2;
}
}
if(argc >= 3){
blockNum = simple_strtoul(argv[2], NULL, 10);
printf("block Num is %d\n", blockNum);
if(blockNum == 0) {
printf("block Num should not be 0, change to 1!\n");
blockNum = 1;
}
count *= blockNum;
}
if(argc >= 4){
readMode = simple_strtoul(argv[3], NULL, 10);
printf("Read Mode is %d\n", readMode);
if(readMode <=1)
printf("read in 4Byte Mode is %s\n", ((readMode==1)?("enable"):("disable")));
else {
printf("read mode should be in [0~1]\n");
return -3;
}
}
printf("1::read_idle_en status is %d\n", VPint(SF_READ_IDLE_EN));
begtime = getTime();
begtick = VPint(CR_TIMER1_VLR);
if((readMode == 0) && (read_idle_en == 1)) {
while (count--) {
WriteReg(SF_READ_IDLE_EN, RD_IDLE_EN);
tmp = *s++;
}
} else if((readMode == 0) && (read_idle_en == 0)) {
while (count--) {
WriteReg(SF_READ_IDLE_EN, RD_IDLE_DIS);
tmp = *s++;
}
} else if((readMode == 1) && (read_idle_en == 1)) {
while (count--) {
WriteReg(SF_READ_IDLE_EN, RD_IDLE_EN);
tmp4 = *s4++;
}
} else if((readMode == 1) && (read_idle_en == 0)) {
while (count--) {
WriteReg(SF_READ_IDLE_EN, RD_IDLE_DIS);
tmp4 = *s4++;
}
}
endtick = VPint(CR_TIMER1_VLR);
endtime = getTime();
printf("2::read_idle_en status is %d\n", VPint(SF_READ_IDLE_EN));
if(endtime < begtime)
passtime = 0xffffffff - begtime + endtime;
else
passtime = endtime - begtime;
passtime = (passtime/10) * VPint(CR_TIMER1_LDV)+ begtick - endtick;
printf("read_idle_en %s::passtime is %lu\n", ((read_idle_en==1)?("enable"):("disable")), passtime);
printf("s is 0x%08x, s4 is 0x%08x\n\n", s, s4);
return tmp+tmp4;
}
int do_sf_bootin4Byte(int argc, char *argv[])
{
return sf_bootin4Byte_Entry(argc, argv);
}
static int do_sf_nonAlign_test(int argc, char *argv[])
{
int i=0, j=0;
unsigned long curAddr=0, curAddr2=0, curLen=0;
unsigned long retlen=0;
unsigned long erasesize=0;
unsigned char seed=0, seedTmp=0;
unsigned char pp_buf[PP_MAX]={0};
unsigned char rd_buf[4100]={0};
unsigned long startAddr=0x80000;
unsigned long endAddr=0x80801;
unsigned long seEndAddr=0x81000;
unsigned long ppStartAddr=0x80100, ppEndAddr=0x80200;
unsigned long endPPLen=0x101, endRDLen=0x801;
unsigned long curtime=0;
unsigned long nonAlignFlag=0;
int rd_en=1, se_en=1, pp_en=1;
erasesize = mtd.erasesize;
if(argc >= 2){
nonAlignFlag = simple_strtoul(argv[1], NULL, 10);
if((nonAlignFlag&0x4)==0) {
rd_en=0;
} else {
rd_en=1;
}
if((nonAlignFlag&0x2)==0) {
se_en=0;
} else {
se_en=1;
}
if((nonAlignFlag&0x1)==0) {
pp_en = 0;
} else {
pp_en = 1;
}
if((nonAlignFlag&0x8)!=0) {
endAddr=0x80081;
seEndAddr=0x80081;
ppEndAddr=0x80110;
printf("\nrdEndAddr is 0x%08x, seEndAddr is 0x%08x, ppEndAddr is 0x%08x", endAddr, seEndAddr, ppEndAddr);
}
printf("\nnonAlignFlag is %lu, rd_en is %d, se_en is %d, pp_en is %d\n", nonAlignFlag, rd_en, se_en, pp_en);
}
/***************************************/
/********** non-aligned Read Test **********/
/***************************************/
if(rd_en == 1) {
printf("\n>>>non-aligned Read Test begin");
//1: Erase 64KB Sector
flash_erase(startAddr, erasesize);
//2: Program 64KB Sector with random ascend digitals
seed = sf_rand() % SEED_MAX;
for(i=0; i<PP_MAX; i++) {
pp_buf[i] = (seed+i) % SEED_MAX;
}
for(curAddr=startAddr; curAddr<startAddr+erasesize; curAddr+=PP_MAX)
flash_write(curAddr, PP_MAX, &retlen, pp_buf);
//3: Loop Read with non-aligned Address and Variable length
for(curAddr=startAddr; curAddr<=endAddr; ++curAddr) {
curtime = getTime();
printf("\nnon-aligned Read: curAddr is 0x%08x, curTime is %02d:%02d:%02d", curAddr, curtime/3600000, (curtime/60000)%60, (curtime/1000)%60);
for(curLen=0; curLen<=endRDLen; ++curLen) {
seedTmp = (seed+curAddr)%SEED_MAX;
//3.1: Auto Read Test with designated Address and Length
Mats_ReadMode_Value=0;
spiflash_mats_read(curAddr, curLen, &retlen, rd_buf);
for(i=0; i<curLen; i++) {
if(rd_buf[i] != (seedTmp+i)%SEED_MAX) {
printf("\n####Auto Read fail at Address %X::index is %d, value is %X, should be %X, curLen is %d, reg 0xBFA10000 is 0x%08x\n", curAddr+i, i, rd_buf[i], (seedTmp+i)%SEED_MAX, curLen, SF_READ_MODE_VALUE);
dumpCell_buffer((u8 *)(rd_buf), curLen, curAddr);
goto read_fail_exit;
}
}
//3.2: Manual Read Test with designated Address and Length
Mats_ReadMode_Value=4;
spiflash_mats_read(curAddr, curLen, &retlen, rd_buf);
for(i=0; i<curLen; i++) {
if(rd_buf[i] != (seedTmp+i)%SEED_MAX) {
printf("\n####Manual Read fail at Address %X::index is %d, value is %X, should be %X, curLen is %d, reg 0xBFA10000 is 0x%08x\n", curAddr+i, i, rd_buf[i], (seedTmp+i)%SEED_MAX, curLen, SF_READ_MODE_VALUE);
dumpCell_buffer((u8 *)(rd_buf), curLen, curAddr);
goto read_fail_exit;
}
}
}
}
printf("\n<<<non-aligned Read Test passed!\n");
}
/****************************************/
/********** non-aligned Erase Test **********/
/****************************************/
if(se_en == 1) {
printf("\n>>>non-aligned Erase Test begin");
for(curAddr=startAddr; curAddr<=seEndAddr; ++curAddr) {
curtime = getTime();
printf("\nnon-aligned Erase: curAddr is 0x%08x, curTime is %02d:%02d:%02d", curAddr, curtime/3600000, (curtime/60000)%60, (curtime/1000)%60);
//1: Erase 3*64KB Sector
flash_erase(startAddr-erasesize, erasesize);
flash_erase(startAddr, erasesize);
flash_erase(startAddr+erasesize, erasesize);
//2: Program 3*64KB Sector with 0
for(i=0; i<PP_MAX; i++) {
pp_buf[i] = 0;
}
for(curAddr2=startAddr-erasesize; curAddr2<startAddr+erasesize*2; curAddr2+=PP_MAX)
flash_write(curAddr2, PP_MAX, &retlen, pp_buf);
//3: Erase the second Sector
flash_erase(curAddr, erasesize);
//4: Read Data with designated Address and Length to verify
Mats_ReadMode_Value=0;
for(curAddr2=startAddr-erasesize; curAddr2<startAddr+erasesize*2; curAddr2+=SE_MAX) {
spiflash_mats_read(curAddr2, SE_MAX, &retlen, rd_buf);
for(i=0; i<SE_MAX; i++) {
if( ((rd_buf[i] != 0xFF) && (curAddr2>=startAddr) && (curAddr2<startAddr+erasesize)) || ((rd_buf[i] != 0) && ((curAddr2<startAddr) || (curAddr2>=startAddr+erasesize))) ) {
printf("\n####Erase fail at Address %X::index is %d, value is %X, should be %X, curLen is %d, reg 0xBFA10000 is 0x%08x\n", curAddr2+i, i, rd_buf[i], (((curAddr2<startAddr) || (curAddr2>=startAddr+erasesize))?(0):(0xFF)), SE_MAX, SF_READ_MODE_VALUE);
dumpCell_buffer((u8 *)(rd_buf), SE_MAX, curAddr2);
goto erase_fail_exit;
}
}
}
}
printf("\n<<<non-aligned Erase Test passed!\n");
}
/******************************************/
/********** non-aligned Program Test **********/
/******************************************/
if(pp_en == 1) {
printf("\n>>>non-aligned Program Test begin");
for(curAddr=ppStartAddr; curAddr<=ppEndAddr; ++curAddr) {
curtime = getTime();
printf("\nnon-aligned Program: curAddr is 0x%08x, curTime is %02d:%02d:%02d", curAddr, curtime/3600000, (curtime/60000)%60, (curtime/1000)%60);
for(curLen=0; curLen<=endPPLen; ++curLen) {
//1: Erase 64KB Sector
flash_erase(startAddr, erasesize);
//2: Program with non-aligned Address and Variable length
seed = sf_rand() % SEED_MAX;
for(i=0; i<curLen; i++) {
rd_buf[i] = (seed+i) % SEED_MAX;
}
flash_write(curAddr, curLen, &retlen, rd_buf);
//3: Read Data with designated Address and Length to verify
Mats_ReadMode_Value=0;
spiflash_mats_read(curAddr, curLen, &retlen, rd_buf);
for(i=0; i<curLen; i++) {
if(rd_buf[i] != (seed+i)%SEED_MAX) {
printf("\n####Program fail at Address %X::index is %d, value is %X, should be %X, curLen is %d, reg 0xBFA10000 is 0x%08x\n", curAddr+i, i, rd_buf[i], (seed+i)%SEED_MAX, curLen, SF_READ_MODE_VALUE);
dumpCell_buffer((u8 *)(rd_buf), curLen, curAddr);
goto program_fail_exit;
}
}
}
}
printf("\n<<<non-aligned Program Test passed!\n");
}
printf("\nnon-aligned Test Finished\n");
return 0;
erase_fail_exit:
return -1;
program_fail_exit:
return -2;
read_fail_exit:
return -3;
}
#ifdef TCSUPPORT_NEW_SPIFLASH_DEBUG_EXT
int do_sf_memcpy(int argc, char *argv[])
{
u32 srcAddr=0;
u32 destAddr=0;
u32 len=0;
if(argc <= 3){
printf("sfmemcpy <destAddr> <srcAddr> <len>\n");
return -1;
}
destAddr = simple_strtoul(argv[1], NULL, 16);
printf("destAddr is 0x%08x\n", destAddr);
srcAddr = simple_strtoul(argv[2], NULL, 16);
printf("srcAddr is 0x%08x\n", srcAddr);
len = simple_strtoul(argv[3], NULL, 16);
printf("len is 0x%08x\n", len);
srcAddr &= 0x03FFFFFF;
srcAddr |= 0xBC000000;
memcpy4((unsigned int*)destAddr, (unsigned int*)srcAddr, len);
dumpCell_buffer((u8 *)destAddr, len, srcAddr);
return 0;
}
static int do_sf_1ByteTest(int argc, char *argv[])
{
u32 i=0;
u32 startAddr=0x20000;
u32 steplen=0x100;
u32 cnt=1000;
u32 rd_begtime=0, rd_endtime=0, passtime=0;
u32 rd_begtick=0, rd_endtick=0;
unsigned char buf[2];
if(argc == 1){
printf("sf1ByteTest <startAddr> <steplen> <cnt>\n");
return -1;
}
if(argc >= 2){
startAddr = simple_strtoul(argv[1], NULL, 16);
startAddr &= 0xFFFF0000;
if(startAddr < 0x20000) {
startAddr = 0x20000;
}
printf("Start Address 0x%08x\n", startAddr);
}
if(argc >= 3){
steplen = simple_strtoul(argv[2], NULL, 16);
if(steplen == 0) {
steplen = 1;
}
printf("steplen is 0x%04x\n", steplen);
}
if(argc >= 4){
cnt = simple_strtoul(argv[3], NULL, 10);
if(cnt == 0) {
cnt = 1;
}
printf("cnt is %lux\n", cnt);
}
SEND_READ_IDLE_EN_CMD;
rd_begtime = getTime();
rd_begtick = VPint(CR_TIMER1_VLR);
for(i=0; i<cnt; i++) {
memcpy(buf, (unsigned char*)((mtd.offset + startAddr)), 1);
startAddr += steplen;
}
rd_endtick = VPint(CR_TIMER1_VLR);
rd_endtime = getTime();
if(rd_endtime < rd_begtime)
passtime = 0xffffffff - rd_begtime + rd_endtime;
else
passtime = rd_endtime - rd_begtime;
passtime = (passtime/10) * VPint(CR_TIMER1_LDV) + rd_begtick - rd_endtick;
SEND_READ_IDLE_DIS_CMD;
printf("\npasstime is %lu\n\n", passtime);
return 0;
}
int do_sf_ClockSet(int argc, char *argv[])
{
u8 sfClkRateValue=0;
if(argc == 1) {
printf("sfclockset <Clock:0~31>\n");
return -1;
}
if(argc >= 2) {
sfClkRateValue = simple_strtoul(argv[1], NULL, 10);
if(sfClkRateValue == 0)
sfClkRateValue = 10;
if(sfClkRateValue <= 31) {
printf("sfClkRateValue is %d, SFC Clock Rate is %dMHZ\n", sfClkRateValue, (SFC_CLOCK_MAX/sfClkRateValue));
}
else {
printf("sfClkRateValue should be in [0-31]\n");
return -2;
}
}
WriteReg(SF_CLK_CHANGE, sfClkRateValue);
return 0;
}
int do_sf_TnSet(int argc, char *argv[])
{
u8 sfTnValue=0;
if(argc == 1) {
printf("sftnset <Tn:0~5>\n");
return -1;
}
if(argc >= 2) {
sfTnValue = simple_strtoul(argv[1], NULL, 10);
if(sfTnValue <= 5) {
printf("sfTnValue is %d\n", sfTnValue);
}
else {
printf("sfTnValue should be in [0-5]\n");
return -2;
}
}
SEND_TN_CMD(sfTnValue);
return 0;
}
#endif
void sf_regDef_test()
{
int i=0;
int j=1;
printf("\n>>>>>>>SF Register Default Test Begin !!!\n");
// SF_READ_MODE
if(SF_READ_MODE_VALUE == 0x00000000){
//printf("\r\n%d. SF_READ_MODE default value correct.", j++);
}else{
printf("\r\n%d. SF_READ_MODE (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_READ_MODE_VALUE);
}
// SF_READ_IDLE_EN
if(SF_READ_IDLE_EN_VALUE == 0x00000000){
//printf("\r\n%d. SF_READ_IDLE_EN default value correct.", j++);
}else{
printf("\r\n%d. SF_READ_IDLE_EN (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_READ_IDLE_EN_VALUE);
}
// SF_SIDLY
if(SF_SIDLY_VALUE == 0x00000000){
//printf("\r\n%d. SF_SIDLY default value correct.", j++);
}else{
printf("\r\n%d. SF_SIDLY (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_SIDLY_VALUE);
}
// SF_CSHEXT
if(SF_CSHEXT_VALUE == 0x00000005){
//printf("\r\n%d. SF_CSHEXT default value correct.", j++);
}else{
printf("\r\n%d. SF_CSHEXT (default/real): (0x00000005/0x%08x).", j++, (uint32)SF_CSHEXT_VALUE);
}
// SF_CSLEXT
if(SF_CSLEXT_VALUE == 0x00000001){
//printf("\r\n%d. SF_CSLEXT default value correct.", j++);
}else{
printf("\r\n%d. SF_CSLEXT (default/real): (0x00000001/0x%08x).", j++, (uint32)SF_CSLEXT_VALUE);
}
// SF_MTX_MODE_TOG
if(SF_MTX_MODE_TOG_VALUE == 0x00000000){
//printf("\r\n%d. SF_MTX_MODE_TOG default value correct.", j++);
}else{
printf("\r\n%d. SF_MTX_MODE_TOG (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MTX_MODE_TOG_VALUE);
}
// SF_RDCTL_FSM
if(SF_RDCTL_FSM_VALUE == 0x00000000){
//printf("\r\n%d. SF_RDCTL_FSM default value correct.", j++);
}else{
printf("\r\n%d. SF_RDCTL_FSM (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_RDCTL_FSM_VALUE);
}
// SF_MACMUX_SEL
if(SF_MACMUX_SEL_VALUE == 0x00000001){
//printf("\r\n%d. SF_MACMUX_SEL default value correct.", j++);
}else{
printf("\r\n%d. SF_MACMUX_SEL (default/real): (0x00000001/0x%08x).", j++, (uint32)SF_MACMUX_SEL_VALUE);
}
// SF_MANUAL_EN
if(SF_MANUAL_EN_VALUE == 0x00000000){
//printf("\r\n%d. SF_MANUAL_EN default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_EN (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MANUAL_EN_VALUE);
}
// SF_MANUAL_OPFIFO_EMPTY
if(SF_MANUAL_OPFIFO_EMPTY_VALUE == 0x00000001){
//printf("\r\n%d. SF_MANUAL_OPFIFO_EMPTY default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_OPFIFO_EMPTY (default/real): (0x00000001/0x%08x).", j++, (uint32)SF_MANUAL_OPFIFO_EMPTY_VALUE);
}
// SF_MANUAL_OPFIFO_WDATA
if(SF_MANUAL_OPFIFO_WDATA_VALUE == 0x00000000){
//printf("\r\n%d. SF_MANUAL_OPFIFO_WDATA default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_OPFIFO_WDATA (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MANUAL_OPFIFO_WDATA_VALUE);
}
// SF_MANUAL_OPFIFO_FULL
if(SF_MANUAL_OPFIFO_FULL_VALUE == 0x00000000){
//printf("\r\n%d. SF_MANUAL_OPFIFO_FULL default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_OPFIFO_FULL (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MANUAL_OPFIFO_FULL_VALUE);
}
// SF_MANUAL_OPFIFO_WR
if(SF_MANUAL_OPFIFO_WR_VALUE == 0x00000000){
//printf("\r\n%d. SF_MANUAL_OPFIFO_WR default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_OPFIFO_WR (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MANUAL_OPFIFO_WR_VALUE);
}
// SF_MANUAL_DFIFO_FULL
if(SF_MANUAL_DFIFO_FULL_VALUE == 0x00000000){
//printf("\r\n%d. SF_MANUAL_DFIFO_FULL default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_DFIFO_FULL (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MANUAL_DFIFO_FULL_VALUE);
}
// SF_MANUAL_DFIFO_WDATA
if(SF_MANUAL_DFIFO_WDATA_VALUE == 0x00000000){
//printf("\r\n%d. SF_MANUAL_DFIFO_WDATA default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_DFIFO_WDATA (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MANUAL_DFIFO_WDATA_VALUE);
}
// SF_MANUAL_DFIFO_EMPTY
if(SF_MANUAL_DFIFO_EMPTY_VALUE == 0x00000000){
//printf("\r\n%d. SF_MANUAL_DFIFO_EMPTY default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_DFIFO_EMPTY (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MANUAL_DFIFO_EMPTY_VALUE);
}
// SF_MANUAL_DFIFO_RD
if(SF_MANUAL_DFIFO_RD_VALUE == 0x00000000){
//printf("\r\n%d. SF_MANUAL_DFIFO_RD default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_DFIFO_RD (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MANUAL_DFIFO_RD_VALUE);
}
// SF_MANUAL_DFIFO_RDATA
if(SF_MANUAL_DFIFO_RDATA_VALUE == 0x00000000){
//printf("\r\n%d. SF_MANUAL_DFIFO_RDATA default value correct.", j++);
}else{
printf("\r\n%d. SF_MANUAL_DFIFO_RDATA (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_MANUAL_DFIFO_RDATA_VALUE);
}
// SF_DUMMY
if(SF_DUMMY_VALUE == 0x00000001){
//printf("\r\n%d. SF_DUMMY default value correct.", j++);
}else{
printf("\r\n%d. SF_DUMMY (default/real): (0x00000001/0x%08x).", j++, (uint32)SF_DUMMY_VALUE);
}
// SF_ADDR_3B4B
if(SF_ADDR_3B4B_VALUE == 0x00000000){
//printf("\r\n%d. SF_ADDR_3B4B default value correct.", j++);
}else{
printf("\r\n%d. SF_ADDR_3B4B (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_ADDR_3B4B_VALUE);
}
// SF_CFG3B4B_EN
if(SF_CFG3B4B_EN_VALUE == 0x00000000){
//printf("\r\n%d. SF_CFG3B4B_EN default value correct.", j++);
}else{
printf("\r\n%d. SF_CFG3B4B_EN (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_CFG3B4B_EN_VALUE);
}
// SF_INTERRUPT
if(SF_INTERRUPT_VALUE == 0x00000000){
//printf("\r\n%d. SF_INTERRUPT default value correct.", j++);
}else{
printf("\r\n%d. SF_INTERRUPT (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_INTERRUPT_VALUE);
}
// SF_INTERRUPT_EN
if(SF_INTERRUPT_EN_VALUE == 0x00000000){
//printf("\r\n%d. SF_INTERRUPT default value correct.", j++);
}else{
printf("\r\n%d. SF_INTERRUPT_EN (default/real): (0x00000000/0x%08x).", j++, (uint32)SF_INTERRUPT_EN_VALUE);
}
// SF_SI_CK_SEL
if(SF_SI_CK_SEL_VALUE == 0x00000009){
//printf("\r\n%d. SF_CLK_CHANGE default value correct.", j++);
}else{
printf("\r\n%d. SF_SI_CK_SEL (default/real): (0x00000009/0x%08x).", j++, (uint32)SF_SI_CK_SEL_VALUE);
}
// SF_CLK_CHANGE
if(SF_CLK_CHANGE_VALUE == 0x00000000){
//printf("\r\n%d. SF_CLK_CHANGE default value correct.", j++);
}else{
printf("\r\n%d. SF_CLK_CHANGE (default/real): (0x00000000/0x%08x).\n", j++, (uint32)SF_CLK_CHANGE_VALUE);
}
}
void sf_regRW_test(u32 pattern)
{
int i=0;
int j=1;
u32 rval=0;
printf("\n>>>>>>>SF Register RW Test Begin, pattern is 0x%08x!!!\n", pattern);
// SF_READ_MODE
rval = SF_READ_MODE_VALUE;
SF_READ_MODE_VALUE = pattern;
if(SF_READ_MODE_VALUE == (pattern & 0x00000007)){
//printf("\r\n%d. SF_READ_MODE write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_READ_MODE (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x00000007), (uint32)SF_READ_MODE_VALUE);
}
SF_READ_MODE_VALUE = rval;
// SF_READ_IDLE_EN
rval = SF_READ_IDLE_EN_VALUE;
SF_READ_IDLE_EN_VALUE = pattern;
if(SF_READ_IDLE_EN_VALUE == (pattern & 0x00000001)){
//printf("\r\n%d. SF_READ_IDLE_EN write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_READ_IDLE_EN (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x00000001), (uint32)SF_READ_IDLE_EN_VALUE);
}
SF_READ_IDLE_EN_VALUE = rval;
// SF_SIDLY
rval = SF_SIDLY_VALUE;
SF_SIDLY_VALUE = pattern;
if(SF_SIDLY_VALUE == (pattern & 0x00000003)){
//printf("\r\n%d. SF_SIDLY write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_SIDLY (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x00000003), (uint32)SF_SIDLY_VALUE);
}
SF_SIDLY_VALUE = rval;
// SF_CSHEXT
rval = SF_CSHEXT_VALUE;
SF_CSHEXT_VALUE = pattern;
if(SF_CSHEXT_VALUE == (pattern & 0x00000007)){
//printf("\r\n%d. SF_CSHEXT write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_CSHEXT (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x00000007), (uint32)SF_CSHEXT_VALUE);
}
SF_CSHEXT_VALUE = rval;
// SF_CSLEXT
rval = SF_CSLEXT_VALUE;
SF_CSLEXT_VALUE = pattern;
if(SF_CSLEXT_VALUE == (pattern & 0x00000007)){
//printf("\r\n%d. SF_CSLEXT write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_CSLEXT (default/real): (0x%08x/0x%08x).", j++, (pattern & 0x00000007), (uint32)SF_CSLEXT_VALUE);
}
SF_CSLEXT_VALUE = rval;
// SF_MTX_MODE_TOG
rval = SF_MTX_MODE_TOG_VALUE;
SF_MTX_MODE_TOG_VALUE = pattern;
if(SF_MTX_MODE_TOG_VALUE == (pattern & 0x0000000F)){
//printf("\r\n%d. SF_MTX_MODE_TOG write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_MTX_MODE_TOG (default/real): (0x%08x/0x%08x).", j++, (pattern & 0x0000000F), (uint32)SF_MTX_MODE_TOG_VALUE);
}
SF_MTX_MODE_TOG_VALUE = rval;
// skip SF_RDCTL_FSM (RO)
// SF_MACMUX_SEL
rval = SF_MACMUX_SEL_VALUE;
SF_MACMUX_SEL_VALUE = pattern;
if(SF_MACMUX_SEL_VALUE == (pattern & 0x00000001)){
//printf("\r\n%d. SF_MACMUX_SEL write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_MACMUX_SEL (default/real): (0x%08x/0x%08x).", j++, (pattern & 0x00000001), (uint32)SF_MACMUX_SEL_VALUE);
}
SF_MACMUX_SEL_VALUE = rval;
// SF_MANUAL_EN
rval = SF_MANUAL_EN_VALUE;
SF_MANUAL_EN_VALUE = pattern;
if(SF_MANUAL_EN_VALUE == (pattern & 0x00000001)){
//printf("\r\n%d. SF_MANUAL_EN write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_MANUAL_EN (default/real): (0x%08x/0x%08x).", j++, (pattern & 0x00000001), (uint32)SF_MANUAL_EN_VALUE);
}
SF_MANUAL_EN_VALUE = rval;
// skip SF_MANUAL_OPFIFO_EMPTY (RO)
// SF_MANUAL_OPFIFO_WDATA
rval = SF_MANUAL_OPFIFO_WDATA_VALUE;
SF_MANUAL_OPFIFO_WDATA_VALUE = pattern;
if(SF_MANUAL_OPFIFO_WDATA_VALUE == (pattern & 0x00003FFF)){
//printf("\r\n%d. SF_MANUAL_OPFIFO_WDATA write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_MANUAL_OPFIFO_WDATA (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x00003FFF), (uint32)SF_MANUAL_OPFIFO_WDATA_VALUE);
}
SF_MANUAL_OPFIFO_WDATA_VALUE = rval;
// skip SF_MANUAL_OPFIFO_FULL (RO)
// skip SF_MANUAL_OPFIFO_WR (WO)
// skip SF_MANUAL_DPFIFO_FULL (RO)
// skip SF_MANUAL_DPFIFO_WDATA (WO)
// skip SF_MANUAL_DPFIFO_EMPTY (RO)
// skip SF_MANUAL_DPFIFO_RD (WO)
// skip SF_MANUAL_DPFIFO_RDATA(RO)
// SF_DUMMY
rval = SF_DUMMY_VALUE;
SF_DUMMY_VALUE = pattern;
if(SF_DUMMY_VALUE == (pattern & 0x0000000F)){
//printf("\r\n%d. SF_DUMMY write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_DUMMY (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x0000000F), (uint32)SF_DUMMY_VALUE);
}
SF_DUMMY_VALUE = rval;
// SF_ADDR_3B4B
rval = SF_ADDR_3B4B_VALUE;
SF_ADDR_3B4B_VALUE = pattern;
if(SF_ADDR_3B4B_VALUE == (pattern & 0x00000001)){
//printf("\r\n%d. SF_ADDR_3B4B write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_ADDR_3B4B (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x00000001), (uint32)SF_ADDR_3B4B_VALUE);
}
SF_ADDR_3B4B_VALUE = rval;
// SF_PROBE_SEL
rval = SF_PROBE_SEL_VALUE;
SF_PROBE_SEL_VALUE = pattern;
if(SF_PROBE_SEL_VALUE == (pattern & 0x8000001F)){
//printf("\r\n%d. SF_PROBE_SEL write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_PROBE_SEL (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x8000001F), (uint32)SF_PROBE_SEL_VALUE);
}
SF_PROBE_SEL_VALUE = rval;
// SF_CFG3B4B_EN
rval = SF_CFG3B4B_EN_VALUE;
SF_CFG3B4B_EN_VALUE = pattern;
if(SF_CFG3B4B_EN_VALUE == (pattern & 0x00000001)){
//printf("\r\n%d. SF_CFG3B4B_EN write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_CFG3B4B_EN (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x00000001), (uint32)SF_CFG3B4B_EN_VALUE);
}
SF_CFG3B4B_EN_VALUE = rval;
// skip SF_INTERRUPT (WO)
// SF_INTERRUPT_EN
rval = SF_INTERRUPT_EN_VALUE;
SF_INTERRUPT_EN_VALUE = pattern;
if(SF_INTERRUPT_EN_VALUE == (pattern & 0x000001FF)){
//printf("\r\n%d. SF_INTERRUPT_EN write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_INTERRUPT_EN (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x000001FF), (uint32)SF_INTERRUPT_EN_VALUE);
}
SF_INTERRUPT_EN_VALUE = rval;
// SF_SI_CK_SEL
rval = SF_SI_CK_SEL_VALUE;
SF_SI_CK_SEL_VALUE = pattern;
if(SF_SI_CK_SEL_VALUE == (pattern & 0x0000000F)){
//printf("\r\n%d. SF_SI_CK_SEL write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_SI_CK_SEL (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x0000000F), (uint32)SF_SI_CK_SEL_VALUE);
}
SF_SI_CK_SEL_VALUE = rval;
// SF_CLK_CHANGE
rval = SF_CLK_CHANGE_VALUE;
SF_CLK_CHANGE_VALUE = pattern;
if(SF_CLK_CHANGE_VALUE == (pattern & 0x0000001F)){
//printf("\r\n%d. SF_CLK_CHANGE write 0x%08x correct.", j++, pattern);
}else{
printf("\r\n%d. SF_CLK_CHANGE (default/real): (0x%08x/0x%08x).", j++,(pattern & 0x0000001F), (uint32)SF_CLK_CHANGE_VALUE);
}
SF_CLK_CHANGE_VALUE = rval;
}
#endif
#if defined(TCSUPPORT_CPU_EN7512)||defined(TCSUPPORT_CPU_EN7521)
#ifdef TCSUPPORT_NEW_SPIFLASH_DEBUG /*Chuck Kuo, For SPI NAND Test */
#define SPI_NAND_CHECK_PATTERN_SIZE 2048
typedef enum{
_SPI_NAND_TEST_RTN_NO_ERROR,
_SPI_NAND_TEST_RTN_ERROR_WITH_SOME_REASON,
_SPI_NAND_TEST_RTN_PARSER_ERROR,
_SPI_NAND_TEST_RTN_WRITE_MODE_CHECK_ERROR,
_SPI_NAND_TEST_RTN_WRITE_MODE_NOT_SET,
_SPI_NAND_TEST_RTN_READ_MODE_CHECK_ERROR,
_SPI_NAND_TEST_RTN_READ_MODE_NOT_SET,
_SPI_NAND_TEST_RTN_PATTER_TEST_ERROR,
_SPI_NAND_TEST_RTN_DEF_NO
} _SPI_NAND_TEST_RTN_T;
unsigned char SPI_NAND_TEST_PATTERN[]=
{
{0xA5},
{0x5A},
{0xFF},
{0x00},
{0x55},
{0xAA}
};
typedef struct{
char *ptr_parameter_name;
unsigned long default_value;
unsigned long current_value;
} _spi_nand_rwtest_parameter_value_t;
typedef struct{
unsigned int Round;
unsigned int ManualRead_Mode;
unsigned int ManualWrite_Mode;
unsigned int CLK_Rate;
unsigned int Pattern;
unsigned long StarAddr;
} _spi_nand_rwtest_input_parameter_t;
static _spi_nand_rwtest_input_parameter_t input_parameter_t;
static _spi_nand_rwtest_parameter_value_t _spi_nand_rwtest_info_t[]={
{ "Round", 10, 10},
{ "ManualRead_Mode", 0x1, 0x1},
{ "ManualWrite_Mode", 0x1, 0x1},
{ "CLK_Rate", 0, 0},
{ "Pattern", 0, 0},
{ "StarAddr", 0x7F00000, 0x7F00000},
};
static void SPI_NAND_RWTest_Helper()
{
printf("\nusage: spinand_rwtest[Round] [ManualRead_Mode] [ManualWrite_Mode] [CLK_Rate]\n");
printf(" [Pattern] [StartAddr]\n");
printf("[Round]: 0~65535 means test round. DEFAULT VALUE is 10\n");
printf("[ManualRead_Mode]: To setup the ManualRead_Mode Test Enable or not\n");
printf(" 0~7 is b'000~111, from bit0 to bit2\n");
printf(" set bit0 to enable Manual_singleRead\n");
printf(" set bit1 to enable Manual_DualRead\n");
printf(" set bit2 to enable Manual_QualRead\n");
printf(" Default is 0x1\n");
printf("[ManualWrite_Mode]: To setup the ManualWrite_Mode Test Enable or not\n");
printf(" 0~3 is b'00~11, from bit0 to bit1\n");
printf(" set bit0 to enable Manual_singleWrite\n");
printf(" set bit1 to enable Manual_QualWrite\n");
printf(" Default is 0x1\n");
#if 1 /* ASIC */
printf("[CLK Rate]: 0 means auto switch clock test\n");
printf(" 1 ~ 31 means (250/CLK Rate)MHZ\n");
printf(" DEFAULT VALUE is 0\n");
#else /* FPGA */
printf("[CLK Rate]: aoto test 25Mhz and 50Mhz\n");
#endif
printf("[TestPattern]: To setup test pattern\n");
printf(" 0: A5, 1: 5A, 2: FF, 3: 00, 4: 55, 5: AA\n");
printf(" 6: Random, 7: All\n");
printf(" DEFAULT VALUE is 0\n");
printf("[StartAddr]: To setup the test start address\n");
printf(" (Test Till to the end of Flash)\n");
printf(" DEFAULT VALUE is (chip size - 1MB)\n");
}
int spinand_rw_test_input_parser(int argc, char *argv[])
{
unsigned int idx;
struct SPI_NAND_FLASH_INFO_T flash_info_t;
if(argc < 2 ){
return -1;
}
SPI_NAND_Flash_Get_Flash_Info(&flash_info_t);
input_parameter_t.StarAddr = (flash_info_t.device_size) - 0x100000;
for( idx=2 ; idx<=argc ; idx++)
{
if(idx == 7)
{
/* The input "address" is HEX format */
_spi_nand_rwtest_info_t[idx-2].current_value = simple_strtoul(argv[idx-1], NULL, 16);
}
else
{
_spi_nand_rwtest_info_t[idx-2].current_value = simple_strtoul(argv[idx-1], NULL, 10);
}
}
printf("The Test Parameter Setting\n");
printf("Parameter_Name Default_Value Current_Value\n");
printf("---------------------------------------------\n");
for( idx=0 ; idx< (sizeof(_spi_nand_rwtest_info_t)/sizeof(_spi_nand_rwtest_parameter_value_t)) ; idx++)
{
printf("%-18s, 0x%-18x, 0x%-18x\n", _spi_nand_rwtest_info_t[idx].ptr_parameter_name, _spi_nand_rwtest_info_t[idx].default_value, _spi_nand_rwtest_info_t[idx].current_value);
}
input_parameter_t.Round = _spi_nand_rwtest_info_t[0].current_value;
input_parameter_t.ManualRead_Mode = _spi_nand_rwtest_info_t[1].current_value;
input_parameter_t.ManualWrite_Mode = _spi_nand_rwtest_info_t[2].current_value;
input_parameter_t.CLK_Rate = _spi_nand_rwtest_info_t[3].current_value;
input_parameter_t.Pattern = _spi_nand_rwtest_info_t[4].current_value;
input_parameter_t.StarAddr = _spi_nand_rwtest_info_t[5].current_value;
return 0;
}
static int spinand_write_speed_check( SPI_NAND_FLASH_WRITE_SPEED_MODE_T speed_mode )
{
_SPI_NAND_TEST_RTN_T rtn_status = _SPI_NAND_TEST_RTN_NO_ERROR;
if( ((input_parameter_t.ManualWrite_Mode) & (1 << speed_mode)) )
{
if( speed_mode == SPI_NAND_FLASH_WRITE_SPEED_MODE_SINGLE )
{
printf("\nSPI_NAND_RW_TEST: WRITE SPEED is SINGLE MODE\n");
}
else if( speed_mode == SPI_NAND_FLASH_WRITE_SPEED_MODE_QUAD )
{
printf("\nSPI_NAND_RW_TEST: WRITE SPEED is QUAD MODE\n");
}
else
{
printf("\nSPI_NAND_RW_TEST: WRITE SPEED UNKNOWN\n");
rtn_status = _SPI_NAND_TEST_RTN_WRITE_MODE_CHECK_ERROR;
}
}
else
{
printf("\nSPI_NAND_RW_TEST: NO SUCH WRITE SPEED\n");
rtn_status = _SPI_NAND_TEST_RTN_WRITE_MODE_NOT_SET;
}
return (rtn_status);
}
static int spinand_read_speed_check( SPI_NAND_FLASH_READ_SPEED_MODE_T speed_mode )
{
_SPI_NAND_TEST_RTN_T rtn_status = _SPI_NAND_TEST_RTN_NO_ERROR;
if( ((input_parameter_t.ManualRead_Mode) & (1 << speed_mode)) )
{
if( speed_mode == SPI_NAND_FLASH_READ_SPEED_MODE_SINGLE )
{
printf("SPI_NAND_RW_TEST: READ SPEED is SINGLE MODE\n");
}
else if( speed_mode == SPI_NAND_FLASH_READ_SPEED_MODE_DUAL )
{
printf("SPI_NAND_RW_TEST: READ SPEED is DUAL MODE\n");
}
else if( speed_mode == SPI_NAND_FLASH_READ_SPEED_MODE_QUAD )
{
printf("SPI_NAND_RW_TEST: READ SPEED is QUAD MODE\n");
}
else
{
printf("SPI_NAND_RW_TEST: READ SPEED UNKNOWN\n");
rtn_status = _SPI_NAND_TEST_RTN_READ_MODE_CHECK_ERROR;
}
}
else
{
rtn_status = _SPI_NAND_TEST_RTN_READ_MODE_NOT_SET;
}
return (rtn_status);
}
static int spinand_rw_test_with_pattern( unsigned char test_pattern )
{
SPI_NAND_FLASH_WRITE_SPEED_MODE_T write_speed;
SPI_NAND_FLASH_READ_SPEED_MODE_T read_speed;
struct SPI_NAND_FLASH_INFO_T flash_info_t;
unsigned long test_addr;
unsigned long write_return_len=0;
unsigned long read_return_len=0;
unsigned char test_pattern_write_buf[SPI_NAND_CHECK_PATTERN_SIZE];
unsigned char test_pattern_read_buf[SPI_NAND_CHECK_PATTERN_SIZE];
_SPI_NAND_TEST_RTN_T rtn_status = _SPI_NAND_TEST_RTN_PATTER_TEST_ERROR;
SPI_NAND_FLASH_RTN_T flash_rtn_status;
printf("SPI_NAND_RW_TEST: pattern=0x%x\n", test_pattern);
/* 1. Get Flash Information */
SPI_NAND_Flash_Get_Flash_Info(&flash_info_t);
//SPI_NAND_DEBUG_ENABLE();
/* 2. Preparre Test pattern buffer */
memset( test_pattern_write_buf, test_pattern, SPI_NAND_CHECK_PATTERN_SIZE);
for( write_speed= SPI_NAND_FLASH_WRITE_SPEED_MODE_SINGLE ; write_speed<SPI_NAND_FLASH_WRITE_SPEED_MODE_DEF_NO ; write_speed++ )
{
if( spinand_write_speed_check(write_speed)!= _SPI_NAND_TEST_RTN_NO_ERROR)
{
continue;
}
else
{
for( test_addr = input_parameter_t.StarAddr; (test_addr + (flash_info_t.erase_size)) < flash_info_t.device_size ; test_addr += (flash_info_t.erase_size))
{
printf("SPI_NAND_RW_TEST: test_addr=0x%x\n", test_addr);
/* 1. Ersa current test block */
flash_rtn_status = SPI_NAND_Flash_Erase( test_addr, (flash_info_t.erase_size));
if( flash_rtn_status == SPI_NAND_FLASH_RTN_NO_ERROR)
{
/* 2. Write Test Pattern */
flash_rtn_status = SPI_NAND_Flash_Write_Nbyte( test_addr, SPI_NAND_CHECK_PATTERN_SIZE, &write_return_len, &test_pattern_write_buf, write_speed);
if( flash_rtn_status == SPI_NAND_FLASH_RTN_NO_ERROR )
{
/* 3. Read Check (For the read mode if user enable) */
for( read_speed =SPI_NAND_FLASH_READ_SPEED_MODE_SINGLE ; read_speed<SPI_NAND_FLASH_READ_SPEED_MODE_DEF_NO ; read_speed++ )
{
SPI_NAND_Flash_Clear_Read_Cache_Data();
memset( test_pattern_read_buf, 0x0, SPI_NAND_CHECK_PATTERN_SIZE);
if( spinand_read_speed_check(read_speed) != _SPI_NAND_TEST_RTN_NO_ERROR)
{
continue;
}
else
{
//pause(1000);
//SPI_NAND_DEBUG_ENABLE();
flash_rtn_status = SPI_NAND_Flash_Read_NByte(test_addr, SPI_NAND_CHECK_PATTERN_SIZE, &read_return_len, test_pattern_read_buf, read_speed );
if( flash_rtn_status == SPI_NAND_FLASH_RTN_NO_ERROR )
{
if( memcmp(test_pattern_write_buf, test_pattern_read_buf , (SPI_NAND_CHECK_PATTERN_SIZE) ) !=0 )
{
printf("spinand_rw_test_with_pattern: test pattern compare error at addr =0x%x\n\n", test_addr );
goto spinand_rw_pattern_test_fail;
}
}
else if (flash_rtn_status == SPI_NAND_FLASH_RTN_DETECTED_BAD_BLOCK)
{
goto next_round;
}
else
{
printf("spinand_rw_test_with_pattern: read fail at addr =0x%x\n\n", test_addr);
goto spinand_rw_pattern_test_fail;
}
//SPI_NAND_DEBUG_DISABLE();
}
}
}
else
{
printf("spinand_rw_test_with_pattern: write pattern fail at addr =0x%x, with test pattern0x%x\n\n", test_addr, test_pattern );
goto next_round;
}
}
else
{
printf("spinand_rw_test_with_pattern: erase fail at addr =0x%x, SKIP\n\n", test_addr );
goto next_round;
}
next_round:
if (flash_rtn_status == SPI_NAND_FLASH_RTN_DETECTED_BAD_BLOCK)
{
printf("spinand_rw_test_with_pattern : BAD Block Detected , SKIP\n");
}
if (flash_rtn_status == SPI_NAND_FLASH_RTN_ERASE_FAIL)
{
printf("spinand_rw_test_with_pattern : Erase Fail Detected , SKIP\n");
}
if (flash_rtn_status == SPI_NAND_FLASH_RTN_PROGRAM_FAIL)
{
printf("spinand_rw_test_with_pattern : Program Fail Detected , SKIP\n");
}
}
}
}
rtn_status = _SPI_NAND_TEST_RTN_NO_ERROR;
//SPI_NAND_DEBUG_DISABLE();
spinand_rw_pattern_test_fail:
return (rtn_status);
}
int do_spinand_rw_test(int argc, char *argv[])
{
unsigned long test_round;
unsigned long idx;
unsigned char test_pattern;
unsigned char incemental_test_pattern=0x0;
u32 begtime=0, endtime=0, passtime=0, totaltime=0;
struct SPI_NAND_FLASH_INFO_T flash_info_t;
SPI_NAND_FLASH_RTN_T rtn_status;
//SPI_NAND_DEBUG_ENABLE();
/* 1. Parser User Input and setup Parameter */
if( spinand_rw_test_input_parser(argc, argv) != 0 )
{
printf("Input Error, the input format is: \n");
SPI_NAND_RWTest_Helper();
}
else
{
/* 2.1 Get Current Flash Information */
SPI_NAND_Flash_Get_Flash_Info(&flash_info_t);
printf("Flash Info: \nChip Name=%s \nchip size=0x%x \nerase size=0x%x\n\n", flash_info_t.ptr_name, flash_info_t.device_size, flash_info_t.erase_size);
/* 2.3 Test each round */
for( test_round=1 ; test_round<= (input_parameter_t.Round) ; test_round++)
{
begtime = getTime(); /* Caculate time start */
printf("================================================================\n");
printf("SPI_NAND_RW_TEST: ROUND %d start\n", test_round);
#if 1 /*ASIC */
if( (input_parameter_t.CLK_Rate) == 0 ) /* Aoto test for multiple spi clock frequency */
{
if( (test_round %6) ==0)
{
VPint(0xBFA10098)=0;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
set_spi_clock_speed(0xa);
/* adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
if( (test_round %6) ==1)
{
VPint(0xBFA10098)=1;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
set_spi_clock_speed(0xa);
/* adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
if( (test_round %6) ==2)
{
VPint(0xBFA10098)=0;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
set_spi_clock_speed(0x5);
/* adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
if( (test_round %6) ==3)
{
VPint(0xBFA10098)=1;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
set_spi_clock_speed(0x5);
/*adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
if( (test_round %6) ==4)
{
VPint(0xBFA10098)=0;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
set_spi_clock_speed(0x3);
/* adjust the delay parameter */
VPint(0xbfa1009c) = 0xa;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
if( (test_round %6) ==5)
{
VPint(0xBFA10098)=1;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
set_spi_clock_speed(0x3);
/* adjust the delay parameter */
VPint(0xbfa1009c) = 0xa;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
}
else /* Setting SPI clock frequency base on user intput */
{
set_spi_clock_speed((input_parameter_t.CLK_Rate));
}
#else /*FPGA */
if( (test_round %4) ==0)
{
VPint(0xBFA10098)=0;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
VPint(0xBFA2FF00) &= 0xFFFFFFFE ;
printf("Clock register =0x%x\n", VPint(0xBFA2FF00));
/* The 50Mhz must adjust the delay parameter */
VPint(0xbfa1009c) = 0xa;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
if( (test_round %4) ==1)
{
VPint(0xBFA10098)=1;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
VPint(0xBFA2FF00) &= 0xFFFFFFFE ;
printf("Clock register =0x%x\n", VPint(0xBFA2FF00));
/* The 50Mhz must adjust the delay parameter */
VPint(0xbfa1009c) = 0xa;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
if( (test_round %4) ==2)
{
VPint(0xBFA10098)=0;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
VPint(0xBFA2FF00) |= 0x1;
printf("Clock register =0x%x\n", VPint(0xBFA2FF00));
/* The 25Mhz must adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
if( (test_round %4) ==3)
{
VPint(0xBFA10098)=1;
printf("CPOL register =0x%x\n", VPint(0xBFA10098));
VPint(0xBFA2FF00) |= 0x1;
printf("Clock register =0x%x\n", VPint(0xBFA2FF00));
/* The 25Mhz must adjust the delay parameter */
VPint(0xbfa1009c) = 0x9;
printf("0xbfa1009c register =0x%x\n", VPint(0xbfa1009c));
}
#endif
printf("\n\n");
for( idx=0 ; idx< 7 ; idx++)
{
if( (idx < 6) && ((input_parameter_t.Pattern == idx) || input_parameter_t.Pattern== 7) ) /* Normal Test Pattern */
{
test_pattern = SPI_NAND_TEST_PATTERN[idx];
if( spinand_rw_test_with_pattern( test_pattern ) != _SPI_NAND_TEST_RTN_NO_ERROR)
{
printf("do_spinand_rw_test: fail at round %d, with pattern=0x%x\n\n", test_round, test_pattern);
return 0;
}
}
if( (idx == 6) && ( input_parameter_t.Pattern == 6 || input_parameter_t.Pattern== 7) ) /* Random Test Pattern */
{
test_pattern = random_byte() & 0xff;
if( spinand_rw_test_with_pattern( test_pattern ) != _SPI_NAND_TEST_RTN_NO_ERROR)
{
printf("do_spinand_rw_test: fail at round %d, with random pattern=0x%x\n\n", test_round, test_pattern);
return 0;
}
}
}
printf("SPI NAND RW_TEST: ROUND %d finish\n", test_round);
printf("================================================================\n");
endtime = getTime();
if(endtime < begtime)
passtime = 0xffffffff - begtime + endtime;
else
passtime = endtime - begtime;
totaltime+=passtime;
printf("\n>>>>>>> Round %d Test Finish::passtime is %lums", test_round, passtime);
printf("\nCurrent Time is %d:%d:%d\n", endtime/3600000, (endtime/60000)%60, (endtime/1000)%60);
}
printf("All Round test time is %lums\n", totaltime);
}
//SPI_NAND_DEBUG_DISABLE();
return 0;
}
static int do_spinand_read(int argc, char *argv[])
{
unsigned long idx;
unsigned long input_addr;
unsigned long input_len;
unsigned long input_speed;
unsigned long read_return_len;
unsigned char buf[4096];
u32 begtime=0, endtime=0, passtime=0;
SPI_NAND_FLASH_READ_SPEED_MODE_T read_mode = SPI_NAND_FLASH_READ_SPEED_MODE_SINGLE;
if(argc < 2 ){
return -1;
}
input_addr = simple_strtoul(argv[1], NULL, 16);
input_len = simple_strtoul(argv[2], NULL, 16);
read_mode = simple_strtoul(argv[3], NULL, 10);
printf("\n Read SPI NAND From 0x%x, len 0x%x, read_mode=0x%x\n", input_addr, input_len, read_mode);
memset(buf, 0x0 ,4096);
SPI_NAND_DEBUG_ENABLE();
begtime = getTime(); /* Caculate time start */
SPI_NAND_Flash_Clear_Read_Cache_Data();
SPI_NAND_Flash_Read_NByte( input_addr, input_len, &read_return_len, buf, read_mode);
endtime = getTime();
if(endtime < begtime)
passtime = 0xffffffff - begtime + endtime;
else
passtime = endtime - begtime;
printf("\n>>>>>>> Read Test Finish::passtime is %lums\n", passtime);
SPI_NAND_DEBUG_DISABLE();
#if 1
for(idx=0; idx< input_len; idx++)
{
if( ((idx) %8 == 0) )
{
printf("\n%d: ", (idx));
}
printf("0x%x ", buf[idx]);
}
#endif
printf("\n\n");
return 0;
}
static int do_spinand_write(int argc, char *argv[])
{
unsigned long idx;
unsigned long write_addr;
unsigned long write_len;
unsigned long write_retrun_len;
unsigned char buf[4096];
int rtn_status;
SPI_NAND_FLASH_WRITE_SPEED_MODE_T write_mode;
if(argc < 2 ){
return -1;
}
write_addr = simple_strtoul(argv[1], NULL, 16);
write_len = simple_strtoul(argv[2], NULL, 16);
write_mode = simple_strtoul(argv[3], NULL, 10);
for(idx=0; idx< 4096; idx++)
{
buf[idx] = 0x55;
}
printf("\nSPI NAND Write to 0x%x, len 0x%x, speed=0x%x\n", write_addr, write_len, write_mode);
SPI_NAND_Flash_Write_Nbyte( write_addr, write_len, &write_retrun_len, &buf, write_mode);
return 0;
}
static int do_spinand_erase(int argc, char *argv[])
{
unsigned long erase_addr;
unsigned long erase_len;
erase_addr = simple_strtoul(argv[1], NULL, 16);
erase_len = simple_strtoul(argv[2], NULL, 16);
printf("erase addr =0x%lx, erase_len=0x%lx\n", erase_addr, erase_len);
SPI_NAND_Flash_Erase(erase_addr, erase_len);
return 0;
}
#define SPI_NAND_ALIGN_TEST_START_ADDR 0x2000000
#define SPI_NAND_ALIGN_TEST_SIZE 0x801
static int do_spinand_nonalign(int argc, char *argv[])
{
unsigned long addr, idx, write_return_len, read_return_len;
unsigned char write_buf[SPI_NAND_ALIGN_TEST_SIZE];
unsigned char read_buf[SPI_NAND_ALIGN_TEST_SIZE];
struct SPI_NAND_FLASH_INFO_T flash_info_t;
/* 1. Get Flash Information */
SPI_NAND_Flash_Get_Flash_Info(&flash_info_t);
/* 2. Erase block */
for( addr=SPI_NAND_ALIGN_TEST_START_ADDR ; addr < (SPI_NAND_ALIGN_TEST_START_ADDR+SPI_NAND_ALIGN_TEST_SIZE) ; addr+=flash_info_t.erase_size )
{
SPI_NAND_Flash_Erase(addr, (flash_info_t.erase_size) );
}
/* 3. Prepare write buffer */
for( idx=0 ; idx<SPI_NAND_ALIGN_TEST_SIZE ; idx++)
{
write_buf[idx] = (unsigned char)idx;
}
/* 4. Write pattern */
SPI_NAND_Flash_Write_Nbyte( SPI_NAND_ALIGN_TEST_START_ADDR, SPI_NAND_ALIGN_TEST_SIZE, &write_return_len, &write_buf, SPI_NAND_FLASH_WRITE_SPEED_MODE_SINGLE);
pause(1000);
/* 5. Read Pattern Check */
SPI_NAND_Flash_Read_NByte(SPI_NAND_ALIGN_TEST_START_ADDR, SPI_NAND_ALIGN_TEST_SIZE, &read_return_len, read_buf, SPI_NAND_FLASH_READ_SPEED_MODE_SINGLE);
/* 6. Check */
for( idx=0 ; idx<SPI_NAND_ALIGN_TEST_SIZE; idx++ )
{
if( read_buf[idx] != write_buf[idx])
{
printf("[Fail]SPI NAND ALIGN Test Fail\n");
return 1;
}
}
printf("[Success]SPI NAND ALIGN Test OK\n");
return 0;
}
static int do_spicontroller_reg_test(int argc, char *argv[])
{
u32 regs_test_pattern[]={ 0x55555555, 0xAAAAAAAA, 0xFFFFFFFF, 0x00000000};
u32 idx;
printf("================================================================\n");
printf("SPI CONTROLLER regsiter default test start\n");
sf_regDef_test();
printf("\nSPI CONTROLLER regsiter default test finish\n");
printf("================================================================\n");
printf("\n\n================================================================\n");
printf("SPI CONTROLLER regsiter r/w test start\n");
for( idx=0 ; idx< (sizeof(regs_test_pattern)/sizeof(u32)) ; idx++)
{
sf_regRW_test( regs_test_pattern[idx] );
}
printf("\nSPI CONTROLLER regsiter r/w test finish\n");
printf("================================================================\n");
}
#define IMR1 0xBFB40050
static int do_spicontroller_interrupt_test(int argc, char *argv[])
{
unsigned long value;
int result = 0;
/* 1. Enable Manual Mode */
SPI_CONTROLLER_Enable_Manual_Mode();
printf("Check: The Interrupt EVENT register(0xBFA10090) is 0x%x\n", SF_INTERRUPT_VALUE );
printf("Check: The Interrupt MASK register(0xBFA10094) is 0x%x\n", SF_INTERRUPT_EN_VALUE );
if( !(SF_INTERRUPT_VALUE &0x1) ) /* Interrupt doesn't triggered yet */
{
/* 2. Using auto read to get the first byte */
value = *(volatile unsigned int *)(0xBFC00000);
/* 3. Check the interuupt bit */
if( SF_INTERRUPT_VALUE & 0x1 )
{
printf("[Sucess]The Auto Mode/Manual Mode Conflict interrupt has been triggered !\n");
SF_INTERRUPT_VALUE |= 0x1; /* Write 1 to clear the interrupt bit */
SF_INTERRUPT_EN_VALUE |= 0x1; /* Enable the conflict interupt bit to ISR Sources*/
VPint(IMR1) |=0x10;
/* 4. Using auto read to get the first byte */
value = *(volatile unsigned int *)(0xBFC00000);
}
else
{
printf("[Fail]The Auto Mode/Manual Mode Conflict interrupt doesn't be triggered !\n");
}
}
}
#define SPI_CONTROLLER_REGS_MTX_MODE_TOG 0xBFA10014
#define SPI_CONTROLLER_REGS_MTX_MAX_EN 0xBFA10020
#define SPI_CONTROLLER_REGS_CPOL 0xBFA10098
#define SPI_CONTROLLER_REGS_PLDCTL_RSTTIMER 0xBFA100E8
#define SPI_CONTROLLER_REGS_PLDCTL_CFG0 0xBFA100EC
#define SPI_CONTROLLER_REGS_PLDCTL_CFG1 0xBFA100F0
#define SPI_CONTROLLER_REGS_PLDCTL_SWEN 0xBFA100F4
#define SPI_CONTROLLER_REGS_PLDCTL_STS 0xBFA100FC
#define SPI_CONTROLLER_REGS_SW_CFGSPITYPE_VAL 0xBFA10104
#define SPI_CONTROLLER_REGS_SW_CFGSPITYPE_EN 0xBFA10108
#define SPI_CONTROLLER_REGS_SW_CFGNANDADDR_VAL 0xBFA1010C
#define SPI_CONTROLLER_REGS_SW_CFGNANDADDR_EN 0xBFA10110
#define SPI_CONTROLLER_REGS_SFC_STRAP 0xBFA10114
#define TIMERCTLR_REGS 0xBFBF0100
#define TIMER3LVR_REGS 0xBFBF012C
void spicontroller_preload_function_test( void )
{
unsigned char buf[100];
unsigned long rtn_len;
unsigned long addr;
unsigned long idx;
int result=0;
/* Read information */
SPI_NAND_Flash_Read_NByte( 0x1800, 16, &rtn_len, buf, SPI_NAND_FLASH_READ_SPEED_MODE_SINGLE );
/* Write 1 to clear the preload counter */
VPint(SPI_CONTROLLER_REGS_PLDCTL_STS) |= 0x1;
/* Indicate the #3 page (count from 0) */
VPint(SPI_CONTROLLER_REGS_PLDCTL_CFG1) = 0x00000313;
/* Software to trigger preload executing once */
VPint(SPI_CONTROLLER_REGS_PLDCTL_SWEN) |= 0x1;
pause(1000);
/* Check counter */
if( VPint(SPI_CONTROLLER_REGS_PLDCTL_STS) & 0x1 )
{
printf("The preload has been triggered\n");
/* Switch to Auto Mode */
VPint(SPI_CONTROLLER_REGS_MTX_MODE_TOG) =0;
VPint(SPI_CONTROLLER_REGS_MTX_MAX_EN) =0;
pause(1000);
/* Compare data */
for( idx=0 ; idx<16 ; idx+=4 )
{
if( (buf[idx] != ((VPint(0xBFC00000+idx)>>24) & 0xff)) ||
(buf[idx+1] != ((VPint(0xBFC00000+idx)>>16) & 0xff)) ||
(buf[idx+2] != ((VPint(0xBFC00000+idx)>> 8) & 0xff)) ||
(buf[idx+3] != ((VPint(0xBFC00000+idx)) & 0xff)) )
{
printf("[Fail]: Preload content not match\n");
break;
}
}
if( idx == 16)
{
printf("[Success]: Preload content match\n");
result =1;
}
}
else
{
printf("[Fail]: Preload counter not be triggered\n");
}
/* Switch to Manual Mode */
VPint(SPI_CONTROLLER_REGS_MTX_MODE_TOG) =9;
VPint(SPI_CONTROLLER_REGS_MTX_MAX_EN) =1;
pause(1000);
/* Show the Test Result */
if(result == 1)
{
printf("[Success] SPI CONTROLLER preload function test\n");
}
else
{
printf("[Fail] SPI CONTROLLER preload function test\n");
}
}
void spicontroller_preload_reset_test( unsigned int reset_mode )
{
/******** Load first page into the cache of SPI NAND chip ********/
/* Indicate the #0 page */
VPint(SPI_CONTROLLER_REGS_PLDCTL_CFG1) = 0x00000013;
pause(1000);
/* Software to trigger preload executing once */
VPint(SPI_CONTROLLER_REGS_PLDCTL_SWEN) |= 0x1;
pause(1000);
/******** Set Test Value ********/
VPint( SPI_CONTROLLER_REGS_PLDCTL_RSTTIMER ) = 0x123456;
VPint( SPI_CONTROLLER_REGS_PLDCTL_CFG0 ) = 0x1234;
VPint( SPI_CONTROLLER_REGS_PLDCTL_CFG1 ) = 0x12345678;
pause(1000);
if( reset_mode == 0 ) /* Software Reset */
{
/******** Triggered SW Reset ********/
VPint(0xBFB00040) = 0x80000000;
}
else if( reset_mode == 1 ) /* Watchdog Reset */
{
VPint(TIMER3LVR_REGS) = 0x1000;
VPint(TIMERCTLR_REGS) = 0x2000020;
}
else
{
}
}
void spicontroller_preload_reset_check( void )
{
if( (VPint(SPI_CONTROLLER_REGS_PLDCTL_RSTTIMER) == 0x123456) &&
(VPint(SPI_CONTROLLER_REGS_PLDCTL_CFG0) == 0x1234) &&
(VPint(SPI_CONTROLLER_REGS_PLDCTL_CFG1) == 0x12345678) )
{
printf("[Success] Preload parameter check\n");
}
else
{
printf("[Fail] Preload parameter check\n");
}
}
static int do_spicontroller_preload_test(int argc, char *argv[])
{
//printf("input=%s\n", argv[1]);
if( strcmp( argv[1], "function") == 0 )
{
printf("SPI CONTROLLER , preload function test\n");
spicontroller_preload_function_test();
}
else if( strcmp( argv[1], "sw_reset") == 0 )
{
printf("SPI CONTROLLER , software reset test\n");
spicontroller_preload_reset_test(0);
}
else if( strcmp( argv[1], "watchdog_reset") == 0 )
{
printf("SPI CONTROLLER , watchdog reset test\n");
spicontroller_preload_reset_test(1);
}
else if( strcmp( argv[1], "reset_check") == 0 )
{
printf("SPI CONTROLLER , reset parameter check test\n");
spicontroller_preload_reset_check();
}
else
{
printf("spicontroller_preload_test [ function | sw_reset | watchdog_reset | reset_check]\n");
}
return 0;
}
static int do_spicontroller_cpol_test(int argc, char *argv[])
{
unsigned long mode, idx, rtn_len;
unsigned char buf[16], buf2[16];
mode = simple_strtoul(argv[1], NULL, 10);
printf("The input CPOL mode is 0x%x\n", mode);
/* Read information */
SPI_NAND_Flash_Read_NByte( 0x1800, 16, &rtn_len, buf, SPI_NAND_FLASH_READ_SPEED_MODE_SINGLE );
if(mode == 0)
{
VPint(SPI_CONTROLLER_REGS_CPOL) = 0;
}
else if( mode == 1)
{
VPint(SPI_CONTROLLER_REGS_CPOL) = 1;
}
else
{
printf("CPOL value is 0 or 1, please input correctly\n");
return 0;
}
SPI_NAND_Flash_Read_NByte( 0x1800, 16, &rtn_len, buf2, SPI_NAND_FLASH_READ_SPEED_MODE_SINGLE );
for( idx=0 ; idx<16 ; idx++ )
{
if(buf[idx] != buf2[idx])
{
printf("[Fail]: CPOL Teset\n");
return 1;
}
}
printf("[Success]: CPOL Test\n");
return 0;
}
static int do_spicontroller_strap_test(int argc, char *argv[])
{
if( VPint(SPI_CONTROLLER_REGS_SFC_STRAP) == 0x6)
{
printf("[Success]Check Hardware STRAP Setting, OK\n");
/* Setup to Software control STRAP */
VPint(SPI_CONTROLLER_REGS_SW_CFGSPITYPE_VAL) = 0;
VPint(SPI_CONTROLLER_REGS_SW_CFGSPITYPE_EN) = 1;
VPint(SPI_CONTROLLER_REGS_SW_CFGNANDADDR_VAL) = 0;
VPint(SPI_CONTROLLER_REGS_SW_CFGNANDADDR_EN) = 1;
pause(1000);
printf("SPI_CONTROLLER_REGS_SFC_STRAP, value =0x%x\n", VPint(SPI_CONTROLLER_REGS_SFC_STRAP));
if( VPint(SPI_CONTROLLER_REGS_SFC_STRAP) == 0x0 )
{
printf("[Success]Software Configure STRAP value, OK\n");
pause(1000);
VPint(0xBFB00040) = 0x80000000; /* Triggered Software Reset */
}
else
{
printf("[Fail]Software Configure STRAP value, Fail\n");
}
}
else
{
printf("[Fail]Check Hardware STRAP Setting, Fail\n");
}
return 0;
}
static int do_spi_frequency(int argc, char *argv[])
{
unsigned long addr=0xbfc00000;
unsigned char sidly_idx, edge_idx;
unsigned char buf[4]={0x0};
unsigned long ret_len;
unsigned long val=0;
int idx;
//SPI_NAND_DEBUG_ENABLE();
#if 0
flash_read(0x0, 4, &ret_len, buf);
for( idx=0; idx<4 ;idx++)
{
printf("buf[%d]=0x%x ", idx, buf[idx]);
}
printf("\n");
#endif
#if 1
for( edge_idx=8 ; edge_idx<=0xd ; edge_idx++)
{
VPint(0xbfa1009c) = edge_idx;
for( sidly_idx=0 ; sidly_idx<=3 ; sidly_idx++)
{
VPint(0xbfa10008) = sidly_idx;
for(idx = SPI_NAND_FLASH_READ_SPEED_MODE_SINGLE ; idx< SPI_NAND_FLASH_READ_SPEED_MODE_DEF_NO ; idx++)
{
buf[0]=buf[1]=buf[2]=buf[3]=0;
SPI_NAND_Flash_Clear_Read_Cache_Data();
SPI_NAND_Flash_Read_NByte(0x0, 4, &ret_len, buf, SPI_NAND_FLASH_READ_SPEED_MODE_SINGLE);
/* flash_read(0x0, 4, &ret_len, buf); */
val = 0;
val |= buf[3];
val |= (buf[2]<<8);
val |= (buf[1]<<16);
val |= (buf[0]<<24);
printf("%x Mode: \n", idx);
printf("0xbfa1009c=0x%x, 0xbfa10008=0x%x\n", VPint(0xbfa1009c), VPint(0xbfa10008));
printf("%X: %X \n", addr, val);
}
}
}
#endif
}
#endif
#endif
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
#ifndef TCSUPPORT_RESERVEAREA_EXTEND
int do_passwd(int argc, char *argv[])
{
unsigned long retlen;
// uint8* flash_addr = ((EEPROM_RA_OFFSET+RESERVED_BASE)|FLASH_BASE);
uint8* flash_addr;
unsigned long reserved_base = 0;
int i ;
int username_len=0;
int passwd_len=0;
if (IS_SPIFLASH){
reserved_base = (mtd.size - 4 * mtd.erasesize);
} else {
#ifdef TCSUPPORT_BB_NAND
reserved_base = (1<<ra.flash->chip_shift) - 4 * (1<<ra.flash->erase_shift);
#endif
}
#if defined(TCSUPPORT_CT_E8B_ADSL) && defined(TCSUPPORT_CPU_MT7505)
flash_addr = ((TEMP_RA_OFFSET+reserved_base)|flash_base);
#else
flash_addr = ((EEPROM_RA_OFFSET+reserved_base)|flash_base);
#endif
username_len = strlen((const char*)(argv[1]));
passwd_len = strlen((const char*)(argv[2]));
if((username_len>=USERNAME_PASSWD_LEN)||(passwd_len>=USERNAME_PASSWD_LEN))
{
prom_printf("Length of username and password should be less than 16!\n");
return -1;
}
if(argc !=3)
{
prom_printf("command passwd only with 2 parameters!\n");
return -1;
}
// prom_printf("do_passwd:username = %s\n", argv[1]);
// prom_printf("do_passwd:passwd = %s\n", argv[2]);
for(i=0; i<RESERVEAREA_ERASE_SIZE; i++)
upload_buf[i] = READ_FLASH_BYTE(flash_addr + i);
#if defined(TCSUPPORT_CT_E8B_ADSL) && defined(TCSUPPORT_CPU_MT7505)
for(i=0; i<username_len; i++)
{
upload_buf[CERM1_RA_SIZE+CERM2_RA_SIZE+CERM3_RA_SIZE+CERM4_RA_SIZE+i]
= ((const char*)(argv[1]))[i];
}
upload_buf[CERM1_RA_SIZE+CERM2_RA_SIZE+CERM3_RA_SIZE+CERM4_RA_SIZE+username_len] = '\0';
for(i=0; i<passwd_len; i++)
{
upload_buf[CERM1_RA_SIZE+CERM2_RA_SIZE+CERM3_RA_SIZE+CERM4_RA_SIZE+0x10+i]
= ((const char*)(argv[2]))[i];
}
upload_buf[CERM1_RA_SIZE+CERM2_RA_SIZE+CERM3_RA_SIZE+CERM4_RA_SIZE+0x10+passwd_len] = '\0';
flash_erase(TEMP_RA_OFFSET+reserved_base, RESERVEAREA_ERASE_SIZE);
flash_write(TEMP_RA_OFFSET+reserved_base, RESERVEAREA_ERASE_SIZE, &retlen, (const unsigned char *) upload_buf);
#else
for(i=0; i<username_len; i++)
{
upload_buf[EEPROM_RA_SIZE+CERM1_RA_SIZE+CERM2_RA_SIZE+CERM3_RA_SIZE+CERM4_RA_SIZE+i]
= ((const char*)(argv[1]))[i];
}
upload_buf[EEPROM_RA_SIZE+CERM1_RA_SIZE+CERM2_RA_SIZE+CERM3_RA_SIZE+CERM4_RA_SIZE+username_len] = '\0';
for(i=0; i<passwd_len; i++)
{
upload_buf[EEPROM_RA_SIZE+CERM1_RA_SIZE+CERM2_RA_SIZE+CERM3_RA_SIZE+CERM4_RA_SIZE+0x10+i]
= ((const char*)(argv[2]))[i];
}
upload_buf[EEPROM_RA_SIZE+CERM1_RA_SIZE+CERM2_RA_SIZE+CERM3_RA_SIZE+CERM4_RA_SIZE+0x10+passwd_len] = '\0';
flash_erase(EEPROM_RA_OFFSET+reserved_base, RESERVEAREA_ERASE_SIZE);
flash_write(EEPROM_RA_OFFSET+reserved_base, RESERVEAREA_ERASE_SIZE, &retlen, (const unsigned char *) upload_buf);
#endif
printf("Change username and password successfully!\n");
return 0;
}
#endif
#endif
#ifdef NAND_TEST_CMD
int init_nand(int argc, char *argv[])
{
printf("init_nand\n");
nandflash_init(0);
return 0;
}
int erase_nand(int argc, char *argv[])
{
unsigned long dst;
unsigned long len;
printf("erase_nand\n");
dst = strtoul((const char*)(argv[1]), (char **)NULL, 16);
len = strtoul((const char*)(argv[2]), (char **)NULL, 16);
if(argc == 4){
en_oob_erase = strtoul((const char*)(argv[3]), (char **)NULL, 16);
/*en_oob_erase =1, donot find redirect block and force erase badblock flag and oob*/
}
nandflash_erase(dst, len);
printf("\n");
}
int read_nand(int argc, char *argv[])
{
int i;
unsigned long src;
unsigned long len;
unsigned long retlen;
char buf[4224];
unsigned long dst= 0;
printf("read_nand\n");
src = strtoul((const char*)(argv[1]), (char **)NULL, 16);
len = strtoul((const char*)(argv[2]), (char **)NULL, 16);
if(argv[3]){
dst = strtoul((const char*)(argv[3]), (char **)NULL, 16);
}
if(dst){
printf("read_nand to dst:%x\n", dst);
nandflash_read(src, len, &retlen, dst);
}
else{
nandflash_read(src, len, &retlen, buf);
printf("read len : %lu\n", len);
for (i=1; i<=len; i++) {
if ((i%16 == 0) && (i > 0)) {
printf("\n");
}
printf("%02x ", buf[i-1] & 0xff);
}
}
printf("\nretlen : %d\n\n", retlen);
}
int innand(int argc, char *argv[])
{
unsigned long dst;
unsigned long src;
unsigned long retlen;
unsigned long len;
char buffer[2112];
char ddr_data;
dst = strtoul((const char*)(argv[1]), (char **)NULL, 16);
src = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
printf("nand dst addr : %lx\n", dst);
printf("src addr : %lx\n", src);
printf("move %ld bytes\n", len);
nandflash_write(dst, len, &retlen, (const unsigned char*)src);
}
int check_data(int argc, char *argv[])
{
unsigned long nand_addr;
unsigned long ddr_addr;
unsigned long retlen;
unsigned long len;
unsigned long counter;
char buffer[2112];
char ddr_data;
int check_result = 0;
nand_addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
ddr_addr = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
printf("nand addr : %lx\n", nand_addr);
printf("ddr addr : %lx\n", ddr_addr);
printf("check %ld bytes\n", len);
counter = 0;
while (len > 0) {
nandflash_read(nand_addr, 1, &retlen, buffer);
ddr_data =*((char*)ddr_addr);
if (buffer[0] != ddr_data) {
printf("found error\n");
printf("offset %d\n", counter);
printf("nand : %2x\n", buffer[0] & 0xff);
printf("ddr : %2x\n", ddr_data & 0xff);
printf("\n\n");
check_result++;
}
printf(".");
nand_addr++;
ddr_addr++;
counter++;
len --;
}
if(check_result){
printf("check data fail,fail time:%d\n",check_result);
}
else{
printf("check data pass\n");
}
}
#ifdef TCSUPPORT_NAND_RT63368
int check_badblock(int argc, char *argv[])
{
int i, totalblock;
int addr = 0;
int block_size = 1 << ra.flash->erase_shift;
totalblock = strtoul((const char*)(argv[1]), (char **)NULL, 0);
for(i = 0; i < totalblock; i++)
{
if(mt6573_nand_block_bad_hw(&ra, addr, 0))
{
printf("badblock:%d \n", addr/block_size);
}
addr += block_size;
}
return 0;
}
int mark_badblock(int argc, char *argv[])
{
unsigned long block, addr;
block = strtoul((const char*)(argv[1]), (char **)NULL, 0);
addr = block << ra.flash->erase_shift;
mt6573_nand_block_markbad_hw(&ra, addr, 0);
return 0;
}
int erase_block_phy(int argc, char *argv[])
{
unsigned long erase_num, erase_start_block, i, page;
erase_start_block = strtoul((const char*)(argv[1]), (char **)NULL, 0);
erase_num = strtoul((const char*)(argv[2]), (char **)NULL, 0);
for(i = 0; i < erase_num; i++)
{
page = (erase_start_block << ra.flash->erase_shift) >> ra.flash->page_shift;
mt6573_nand_erase_hw(&ra, page);
erase_start_block++;
}
return 0;
}
int read_page_phy(int argc, char *argv[])
{
unsigned long page, len, i;
char buf[2112];
page = strtoul((const char*)(argv[1]), (char **)NULL, 0);
len = strtoul((const char*)(argv[2]), (char **)NULL, 0);
mt6573_nand_exec_read_page(&ra, page, 2048, buf, buf + 2048);
printf("read len: %u \n", len);
for(i = 0; i < len; i++)
{
if(i % 16 == 0)
printf("\n");
printf("%02x ", buf[i] & 0xff);
}
printf("\n");
return 0;
}
static int write_page_phy(int argc, char *argv[])
{
unsigned long page, byteIndex, value, ecc_flag;
char buf[2112];
char temp = 0;
page = strtoul((const char*)(argv[1]), (char **)NULL, 0);
byteIndex = strtoul((const char*)(argv[2]), (char **)NULL, 0);
value = strtoul((const char*)(argv[3]), (char **)NULL, 0);
ecc_flag = strtoul((const char*)(argv[4]), (char **)NULL, 0);
mt6573_nand_exec_read_page(&ra, page, 2048, buf, buf + 2048);
temp = value;
printf("\r\n page=%d, byteIndex=%d, value=%d, ecc_flag=%d\r\n", page, byteIndex, value, ecc_flag);
buf[byteIndex] = temp;
nfc_write_page(&ra, buf, page, (ecc_flag? FLAG_ECC_EN:0));
return 0;
}
#endif
#endif
#ifdef BOOTROM_BACKDOOR
#define BD_MAGIC_NUM 0x54321253
#define READ_BUF_BASE 0x80020000
#ifndef TCSUPPORT_CPU_MT7505
#define CONFIG_INFO_START 0xfef0
#else
#define CONFIG_INFO_START 0x30
#endif
typedef struct {
int magic_num;
int ddr_config_length;
int eth_config_length;
int reserved[5];
} header_t;
int do_bdconfig_store(int argc,char * argv [ ])
{
unsigned long dst;
unsigned long src;
unsigned long len;
unsigned long retlen;
int config_info[4];
header_t *p_bd_header;
dst = strtoul((const char*)(argv[1]), (char **)NULL, 16);
src = strtoul((const char*)(argv[2]), (char **)NULL, 16);
//len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
if (IS_NANDFLASH) {
printf("back door config is not support NAND Flash\n");
return 0;
}
/*check magic num*/
p_bd_header = (header_t *)src;
if(p_bd_header->magic_num != BD_MAGIC_NUM){
printf("Magic num is wrong: %x\n", p_bd_header->magic_num);
return 0;
}
config_info[0] = dst; //ddr config start address
config_info[1] = p_bd_header->ddr_config_length; //ddr config length
config_info[2] = dst+p_bd_header->ddr_config_length; //ddr config start address
config_info[3] = p_bd_header->eth_config_length; //ddr config start address
printf("ddr start:%x, ddr len:%x, eth start:%x, eth len:%x\n", config_info[0], config_info[1], config_info[2], config_info[3]);
src += sizeof(header_t);
len = config_info[1] + config_info[3];
printf("Write to flash from %X to %X with %X bytes\n", src, dst, len);
flash_erase(dst, len);
printf("\n");
flash_write(dst, len, &retlen, (const unsigned char *) (src));
/*write config into to flash*/
flash_read(TCBOOT_BASE, (unsigned long)TCBOOT_SIZE, &retlen,
(const unsigned char*)READ_BUF_BASE);
memcpy(READ_BUF_BASE+CONFIG_INFO_START, (char *) (config_info), sizeof(config_info));
flash_erase(TCBOOT_BASE, TCBOOT_SIZE);
prom_printf("\n");
flash_write(TCBOOT_BASE, (unsigned long)TCBOOT_SIZE, &retlen,
(const unsigned char*)READ_BUF_BASE);
return 0;
}
int do_bdconfig_show(int argc,char * argv [ ])
{
unsigned long dst;
unsigned long src;
unsigned long len;
unsigned long retlen;
int config_info[4], i;
char buf[16];
header_t *p_bd_header;
if (IS_NANDFLASH) {
printf("back door config is not support NAND Flash\n");
return 0;
}
#if 0
dst = strtoul((const char*)(argv[1]), (char **)NULL, 16);
len = strtoul((const char*)(argv[2]), (char **)NULL, 16);
if(dst){
printf("\n");
while(len){
flash_read(dst, 4, &retlen, (const unsigned char *) (buf));
printf(" %x \n", *(int*)buf);
len -= 4;
dst += 4;
}
printf("\n");
return 0;
}
#endif
/*read config from flash*/
flash_read(CONFIG_INFO_START, sizeof(config_info), &retlen, (const unsigned char *) (config_info));
printf("ddr start:%x, ddr len:%x, eth start:%x, eth len:%x\n", config_info[0], config_info[1], config_info[2], config_info[3]);
if(config_info[0] == 0x0 || config_info[1] == 0xffffffff){
printf("ddr back door config is none\n");
}
else{
for(i=0; i<config_info[1]; i+=8){
flash_read(config_info[0]+i, 8, &retlen, (const unsigned char *) (buf));
printf("ddr %x=%x\n", *(int*)buf, *(int*)(buf+4));
}
}
if(config_info[2] == 0x0 || config_info[3] == 0xffffffff){
printf("ether back door config is none\n");
}
else{
for(i=0; i<config_info[3]; i+=12){
flash_read(config_info[2]+i, 12, &retlen, (const unsigned char *) (buf));
printf("ether phy %x: %x=%x\n", *(int*)buf, *(int*)(buf+4), *(int*)(buf+8));
}
}
return 0;
}
#ifdef BACKDOOR_SWITCH
#define BD_CFG_FLAG 0x2c
#define BD_SWITCH_NUM 0x5a3978bc
static int do_bdconfig_switch (int argc, char *argv[])
{
unsigned long bdSwitchNew = 0;
unsigned long bdVaule;
unsigned long bdSwitchOld;
unsigned long retlen;
#if !defined(TCSUPPORT_CPU_EN7512) && !defined(TCSUPPORT_CPU_EN7521)
if (IS_NANDFLASH) {
printf("back door config is not support NAND Flash\n");
return 0;
}
#endif
flash_read(BD_CFG_FLAG, 4, &retlen, (const unsigned char *) (&bdVaule));
if(bdVaule == BD_SWITCH_NUM){
bdSwitchOld = 1;//now
bdVaule = 0;
}
else{
bdSwitchOld = 0;//now
bdVaule = BD_SWITCH_NUM;
}
printf("Current backdoor function is %s\n", ((bdSwitchOld==1)? "enable":"disable"));
if (argc >= 2) {
bdSwitchNew = strtoul((const char*)(argv[1]), (char **)NULL, 16);
if(bdSwitchNew!=bdSwitchOld){
/*write config into to flash*/
flash_read(TCBOOT_BASE, (unsigned long)TCBOOT_SIZE, &retlen,(const unsigned char*)READ_BUF_BASE);
memcpy(READ_BUF_BASE+BD_CFG_FLAG, (char *) (&bdVaule), sizeof(&bdVaule));
flash_erase(TCBOOT_BASE, TCBOOT_SIZE);
prom_printf("\n");
flash_write(TCBOOT_BASE, (unsigned long)TCBOOT_SIZE, &retlen,(const unsigned char*)READ_BUF_BASE);
printf("Current backdoor function change to %x %s\n", bdVaule, ((bdSwitchNew==1)? "enable":"disable"));
}
else
printf("No Change\r\n");
}
return 0;
}
#define DDR_CAL_FLAG 0x28
#define DC_SWITCH_NUM 0xa59387cb
static int do_ddrcal_switch(int argc, char *argv[])
{
unsigned long dcSwitchNew = 0;
unsigned long dcValue;
unsigned long dcSwitchOld;
unsigned long retlen;
if (IS_NANDFLASH) {
printf("DDR caliration switch is not support NAND Flash\n");
return 0;
}
flash_read(DDR_CAL_FLAG, 4, &retlen, (const unsigned char *) (&dcValue));
if(dcValue == DC_SWITCH_NUM){
dcSwitchOld = 0;//disable
dcValue = 0;
}
else{
dcSwitchOld = 1;//enable
dcValue = DC_SWITCH_NUM;
}
printf("DDR caliration function is %s\n", ((dcSwitchOld==1)? "enable":"disable"));
if (argc >= 2) {
dcSwitchNew = strtoul((const char*)(argv[1]), (char **)NULL, 16);
if(dcSwitchNew!=dcSwitchOld){
/*write config into to flash*/
flash_read(TCBOOT_BASE, (unsigned long)TCBOOT_SIZE, &retlen,(const unsigned char*)READ_BUF_BASE);
memcpy(READ_BUF_BASE+DDR_CAL_FLAG, (char *) (&dcValue), sizeof(&dcValue));
flash_erase(TCBOOT_BASE, TCBOOT_SIZE);
prom_printf("\n");
flash_write(TCBOOT_BASE, (unsigned long)TCBOOT_SIZE, &retlen,(const unsigned char*)READ_BUF_BASE);
printf("DDR caliration function change to %x %s\n", dcValue, ((dcSwitchNew==1)? "enable":"disable"));
}
else
printf("No Change\r\n");
}
return 0;
}
#define DB_CFG_FLAG 0x40
#define DB_QUICK_TEST 0xABCDEF01
#define BD_NORMAL_TEST 0xABCDEF02
static int do_dram_bist_switch(int argc, char *argv[])
{
unsigned long dbSwitchNew = 0;
unsigned long dbValue;
unsigned long dbSwitchOld;
unsigned long retlen;
if (IS_NANDFLASH) {
printf("DRAM BIST is not support NAND Flash\n");
return 0;
}
flash_read(DB_CFG_FLAG, 4, &retlen, (const unsigned char *) (&dbValue));
if(dbValue == DB_QUICK_TEST){
dbSwitchOld = 1;//now
}
else if(dbValue == BD_NORMAL_TEST){
dbSwitchOld = 2;//now
}
else{
dbSwitchOld = 0;//now
}
printf("Current DRAM BIST function is %s", ((dbSwitchOld == 0)? "disable":"enable"));
if(dbSwitchOld)
printf(", and Test mode is %s", ((dbSwitchOld == 1)? "quick":"normal"));
printf("\r\n");
if (argc >= 2) {
dbSwitchNew = strtoul((const char*)(argv[1]), (char **)NULL, 16);
if(dbSwitchNew != dbSwitchOld){
if(dbSwitchNew == 1)
dbSwitchNew = DB_QUICK_TEST;
else if(dbSwitchNew == 2)
dbSwitchNew = BD_NORMAL_TEST;
else
dbSwitchNew = 0;
/*write config into to flash*/
flash_read(TCBOOT_BASE, (unsigned long)TCBOOT_SIZE, &retlen,(const unsigned char*)READ_BUF_BASE);
memcpy(READ_BUF_BASE+DB_CFG_FLAG, (char *) (&dbSwitchNew), sizeof(&dbSwitchNew));
flash_erase(TCBOOT_BASE, TCBOOT_SIZE);
prom_printf("\n");
flash_write(TCBOOT_BASE, (unsigned long)TCBOOT_SIZE, &retlen,(const unsigned char*)READ_BUF_BASE);
printf("DRAM BIST function change to %s", ((dbSwitchNew == 0)? "disable":"enable"));
if(dbSwitchNew)
printf(", and Test mode is %s", ((dbSwitchNew == DB_QUICK_TEST)? "quick":"normal"));
printf("\r\n");
}
else
printf("No Change\r\n");
}
return 0;
}
#endif
#endif
#define isdigit(x) ((x)>='0'&&(x)<='9')
uint32
aton(
char *s
)
{
uint32 n;
int i;
n = 0;
if(s == NULL)
return 0;
for(i=24;i>=0;i -= 8)
{
/* Skip any leading stuff (e.g., spaces, '[') */
while(*s != '\0' && !isdigit(*s))
s++;
if(*s == '\0')
break;
n |= (strtoul((const char*)s, (char **)NULL, 10)) << i;
if((s = strchr(s,'.')) == NULL)
break;
s++;
}
return n;
} /* aton */
#ifndef BOOTROM_IN_SRAM
extern void IP_change(uint32 ipaddr);
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
extern int authed;
#endif
int do_ipaddr(int argc, char *argv[]){
uint32 ipaddr;
ipaddr = aton(argv[1]);
printf("Change IP address to %s\r\n", argv[1]);
IP_change(ipaddr);
}
#endif
#ifdef BOOT_LZMA_SUPPORT
/*
*
*/
static void my_err_tcp(void *arg,
err_t err) {
char what_error[30];
struct web_connection *web = (struct web_connection *)arg;
sprintf( what_error, "my tcp error %d", err);
#ifdef HTTP_DBG
prom_printf( what_error);
#endif
if ( web->current_connection != NULL) {
web->current_connection = NULL;
}
}
/*
* The TCP polling
*/
static err_t
my_poll_tcp(void *arg, struct tcp_pcb *tpcb) {
if ( tpcb != NULL) {
struct web_connection *web = (struct web_connection *)arg;
if ( tpcb == web->current_connection) {
/* see if there has been any traffic */
if ( tpcb->rcv_nxt == web->last_rx_seqno) {
#ifdef HTTP_DBG
prom_printf( "Closing idle connection");
#endif
/* close the connection */
tcp_close( tpcb);
}
else {
web->last_rx_seqno = tpcb->rcv_nxt;
}
}
else {
#ifdef HTTP_DBG
prom_printf( "Closing unserved connection");
#endif
/* close the connection */
tcp_close( tpcb);
}
}
return ERR_OK;
}
/*
* The TCP sent callback.
* The stack has received acknowledgement for some data it has sent.
*/
static err_t
my_sent_tcp( void *arg, struct tcp_pcb *tpcb,
u16_t len) {
#ifdef HTTP_DBG
prom_printf("my TCP sent\r\n");
#endif
return ERR_OK;
}
/*
* The TCP receive callback.
* This is where data is read off on the TCP stream.
*/
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
static err_t
my_recv_tcp( void *arg, struct tcp_pcb *tpcb,
struct pbuf *p, err_t err) {
struct web_connection *web = (struct web_connection *)arg;
unsigned long reserved_base = 0;
char *start, *end;
enum auth_index{ username=0, password,login,Upload, ending };
char* auth_Attr[5]={"username", "passwd", "login", "Upload\r\n","\r\n------"};
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
proline_Para proline;
char user_name[CFEUSRNAMELEN] = {0};
char pass_word[CFEPWDLEN] = {0};
#else
char user_name[USERNAME_PASSWD_LEN] = {0};
char pass_word[USERNAME_PASSWD_LEN] = {0};
#endif
// char *flash_user_name_addr = (char *)FLASH_USER_NAME;
// char *flash_pass_word_addr = (char *)FLASH_PASS_WORD;
char *flash_user_name_addr;
char *flash_pass_word_addr;
int i=0;
short filetype = 0;
/* frankliao modify 20100810 */
extern int checkfile(short, int, char *);
if (IS_SPIFLASH){
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
reserved_base = (mtd.size - 7 * mtd.erasesize);
#else
reserved_base = (mtd.size - 4 * mtd.erasesize);
#endif
} else {
#ifdef TCSUPPORT_BB_NAND
reserved_base = (1<<ra.flash->chip_shift) - 4 * (1<<ra.flash->erase_shift);
#endif
}
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
flash_user_name_addr = (char *)(((PROLINE_CWMPPARA_RA_OFFSET + reserved_base)|flash_base) + ((char *)&proline.cfeusrname[0] - (char *)&proline.flag));
flash_pass_word_addr = flash_user_name_addr + CFEUSRNAMELEN;
#else
flash_user_name_addr = (char *)((USERNAMEPASSWD_RA_OFFSET+reserved_base)|flash_base);
flash_pass_word_addr = (char *)((USERNAMEPASSWD_RA_OFFSET+USERNAME_PASSWD_LEN+reserved_base)|flash_base);
#endif
#ifdef HTTP_DBG
prom_printf("my_recv_tcp........\r\n");
#endif
if ( p != NULL)
{
if ( tpcb == web->current_connection)
{
int copy_size = p->len;
#ifdef HTTP_DBG
prom_printf("tpcb == web->current_connection\r\n");
#endif
memcpy( web->rx_buffer, p->payload, copy_size);
web->rx_buffer[copy_size] = '\0';
#ifdef HTTP_DBG
prom_printf("web->rx_buffer!!!\r\n");
#endif
if (strstr(web->rx_buffer, "POST")||(post_recv))
{
struct pbuf *ptemp=NULL;
post_recv = 1;
prom_printf(".");
for(ptemp=p; ptemp!=NULL; ptemp=ptemp->next)
{
copy_size = ptemp->len;
memcpy( web->rx_buffer, ptemp->payload, copy_size);
web->rx_buffer[copy_size] = '\0';
memcpy(p_upload_buf, web->rx_buffer, copy_size);
p_upload_buf += copy_size;
i = 0;
for (end = web->rx_buffer; memcmp(end, auth_Attr[login], strlen(auth_Attr[login])); ++end)
if (++i >= copy_size)
break;
if (i < copy_size)
{
auth_recv = 1;
post_recv = 0;
}
i = 0;
for (end = web->rx_buffer; memcmp(end, auth_Attr[Upload], strlen(auth_Attr[Upload])); ++end)
if(++i >= copy_size)
break;
if (i < copy_size)
{
if(pass_auth)
{
file_recv = 1;
post_recv = 0;
}
else
{
afterRefresh( p, tpcb);
p_upload_buf = (unsigned char *)0x80020000;
}
}
}
/* tell the stack we have received the data so it can advertise increase in the * receive window. */
tcp_recved( tpcb, p->tot_len);
}
else
{
/* process what we got */
process_http( p, tpcb);
}
if (auth_recv)
{
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
char UserName[CFEUSRNAMELEN] = {0};
char PassWord[CFEPWDLEN] = {0};
for(i=0; i<CFEUSRNAMELEN-1; i++)
{
user_name[i] = READ_FLASH_BYTE(flash_user_name_addr+i);
}
user_name[i] = '\0';
for(i=0; i<CFEPWDLEN-1; i++)
{
pass_word[i] = READ_FLASH_BYTE(flash_pass_word_addr+i);
}
pass_word[i] = '\0';
if((user_name[0] == 0 && user_name[1] == 0 && user_name[2] == 0)
|| (user_name[0] == 0xff && user_name[1] == 0xff && user_name[2] == 0xff))
{
memset(user_name, 0, CFEUSRNAMELEN);
snprintf(user_name,sizeof(user_name),"%s",DEFAULT_CFE_USERNAME);
}
if((pass_word[0] == 0 && pass_word[1] == 0 && pass_word[2] == 0)
|| (pass_word[0] == 0xff && pass_word[1] == 0xff && pass_word[2] == 0xff))
{
memset(pass_word, 0, CFEPWDLEN);
snprintf(pass_word,sizeof(pass_word),"%s",DEFAULT_CFE_PWD);
}
#else
char UserName[USERNAME_PASSWD_LEN] = {0};
char PassWord[USERNAME_PASSWD_LEN] = {0};
for(i=0; i<USERNAME_PASSWD_LEN-1; i++)
{
user_name[i] = READ_FLASH_BYTE(flash_user_name_addr+i);
pass_word[i] = READ_FLASH_BYTE(flash_pass_word_addr+i);
}
user_name[i] = '\0';
pass_word[i] = '\0';
#endif
#ifdef HTTP_DBG
prom_printf("my_recv_tcp:---flash---user_name = %s\n", user_name);
prom_printf("my_recv_tcp:---flash---pass_word = %s\n", pass_word);
#endif
#if 1//ndef TCSUPPORT_RESERVEAREA_EXTEND
if(strncmp(CT_USER_NAME, user_name, strlen(CT_USER_NAME)) != 0)
{
flash_user_name_addr = (char *)MRD_USER_NAME;
flash_pass_word_addr = (char *)MRD_PASS_WORD;
for(i=0; i<USERNAME_PASSWD_LEN-1; i++)
{
user_name[i] = READ_FLASH_BYTE(flash_user_name_addr+i);
pass_word[i] = READ_FLASH_BYTE(flash_pass_word_addr+i);
}
user_name[i] = '\0';
pass_word[i] = '\0';
}
#endif
start = strstr(upload_buf, "\"username\"\r\n\r\n");
start += strlen("\"username\"\r\n\r\n");
end = strstr(start,auth_Attr[ending]);
strncpy(UserName, start, end-start);
start = strstr(upload_buf, "\"passwd\"\r\n\r\n");
start += strlen("\"passwd\"\r\n\r\n");
end = strstr(start,auth_Attr[ending]);
strncpy(PassWord, start, end-start);
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
if ((!strncmp(UserName, user_name, CFEUSRNAMELEN))&&(!strncmp(PassWord, pass_word, CFEPWDLEN)))
#else
if ((!strncmp(UserName, user_name, USERNAME_PASSWD_LEN))&&(!strncmp(PassWord, pass_word, USERNAME_PASSWD_LEN)))
#endif
{
pass_auth = 1;
afterAuthed(p, tpcb);
}
p_upload_buf = (unsigned char *)0x80020000;
auth_recv = 0;
}
#ifdef HTTP_DBG
for(i = copy_size - 20; i < copy_size; i++)
prom_printf("%c ", web->rx_buffer[i]);
prom_printf("\r\n");
#endif
if(file_recv)
{
unsigned long retlen;
#ifdef HTTP_DBG
prom_printf("\r\n=================================\r\n%s\r\n==============================\r\n", upload_buf);
#endif
start = strstr(upload_buf, "filename=");
start += 10;
if(strstr(start, TCBOOT_NAME))
filetype = TCBOOT;
else if(strstr(start, TCLINUX_NAME))
filetype = TCLINUX;
else
filetype = ERRFILE;
//start = strstr(upload_buf, "octet-stream");
start = strstr(start, "\r\n\r\n");
start += 4;
for (end = start; memcmp(end, auth_Attr[ending], strlen(auth_Attr[ending])); ++end)
/* nothing */;
#ifdef HTTP_DBG
if(!end)
prom_printf("2. end is NULL\r\n");
prom_printf("start - upload_buf = %d\r\n", start - upload_buf);
for(i = 0; i < 10; i++)
prom_printf("start[%d] = 0x%2X ", i, start[i]);
for(i = end-start-10; i < end-start; i++)
prom_printf("start[%d] = 0x%2X ", i, start[i]);
prom_printf("\r\nsize = %d\r\n", end-start);
#endif
/* frankliao modify 20100810 */
if(!checkfile(filetype, end-start, 0x80020000+start-upload_buf))
{
afterUpload(p, tpcb);
if(filetype == TCBOOT)
{
flash_erase(0, end-start);
flash_write(0, end-start, &retlen, (const unsigned char *) (0x80020000+start - upload_buf));
}
else if(filetype == TCLINUX)
{
flash_erase(flash_tclinux_start, end-start);
flash_write(flash_tclinux_start, end-start, &retlen, (const unsigned char *) (0x80020000+start - upload_buf));
}
prom_printf("Firmware is uploaded successfully!\r\n");
do_go(0,NULL);
}
else
prom_printf("Fail to upload firmware!\r\n");
p_upload_buf = (unsigned char *)0x80020000;
file_recv = 0;
pass_auth = 0;
}
}
else
{
/* close the strange connection */
prom_printf("tcp_close()\r\n");
tcp_close( tpcb);
}
pbuf_free( p);
}
else if ( tpcb == web->current_connection)
{
/* connection is closed */
sprintf( print_buffer, "Connection from %ld.%ld.%ld.%ld is closed",
IP_ADDRESS_FORMAT( tpcb->remote_ip.addr));
#ifdef HTTP_DBG
prom_printf( print_buffer);
#endif
web->current_connection = NULL;
web->last_rx_seqno = 0;
}
return ERR_OK;
}
#else
static err_t
my_recv_tcp( void *arg, struct tcp_pcb *tpcb,
struct pbuf *p, err_t err) {
struct web_connection *web = (struct web_connection *)arg;
char *start, *end;
char upload[] = {'U', 'p', 'l', 'o', 'a', 'd'};
int i;
short filetype = 0;
int copy_size = 0;
struct pbuf *q;
static char count=0;
/* frankliao modify 20100810 */
extern int checkfile(short, int, char *);
#ifdef HTTP_DBG
prom_printf("my_recv_tcp........\r\n");
#endif
if ( p != NULL) {
if ( tpcb == web->current_connection) {
#ifdef HTTP_DBG
prom_printf("tpcb == web->current_connection\r\n");
#endif
if(p->len > UPLOAD_BUF_SIZE){
prom_printf("packet length is bigger than 20000????\n");
}
q = p;
for(copy_size=0; q!=NULL; q=q->next){
memcpy( (web->rx_buffer + copy_size), q->payload, q->len);
copy_size += q->len;
}
//if ( copy_size >= 200)
//copy_size = 199;
//memcpy( web->rx_buffer, p->payload, copy_size);
web->rx_buffer[copy_size] = '\0';
#ifdef HTTP_DBG
prom_printf("web->rx_buffer!!!\r\n");
#endif
if(strstr(web->rx_buffer, "POST")){
prom_printf("START TO RECEIVE the FILE\r\n");
// memset(upload_buf, 0, 4096);
file_recv = 1;
}
#ifdef HTTP_DBG
for(i = copy_size - 20; i < copy_size; i++)
prom_printf("%c ", web->rx_buffer[i]);
prom_printf("\r\n");
#endif
if(file_recv){
if((++count & 63) == 63)
prom_printf(".");
memcpy(p_upload_buf, web->rx_buffer, copy_size);
p_upload_buf += copy_size;
i = 0;
for (end = web->rx_buffer; memcmp(end, upload, 6); ++end)
if(++i >= copy_size)
break;
if(i < copy_size){
// if(strstr(web->rx_buffer, "Upload")){
// unsigned char *start, *end;
unsigned char upload_end[] = {0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d};
int i;
unsigned long retlen;
prom_printf("\r\nSTART TO CLOSE the FILE\r\n");
file_recv = 0;
#ifdef HTTP_DBG
prom_printf("\r\n=================================\r\n%s\r\n==============================\r\n", upload_buf);
#endif
start = strstr(upload_buf, "filename=");
start += 10;
end = strchr(start, '"');
// if(!memcmp(start, TCBOOT_NAME, end-start))
if(strstr(start, TCBOOT_NAME))
filetype = TCBOOT;
// else if(!memcmp(start, TCLINUX_NAME, end-start))
else if(strstr(start, TCLINUX_NAME))
filetype = TCLINUX;
else
filetype = ERRFILE;
//solve firefox upgrade crash. shnwind
//start = strstr(upload_buf, "octet-stream");
start = strstr(start, "\r\n\r\n");
start += 4;
for (end = start; memcmp(end, upload_end, 8); ++end)
/* nothing */;
#ifdef HTTP_DBG
if(!end)
prom_printf("2. end is NULL\r\n");
prom_printf("start - upload_buf = %d\r\n", start - upload_buf);
for(i = 0; i < 10; i++)
prom_printf("start[%d] = 0x%2X ", i, start[i]);
for(i = end-start-10; i < end-start; i++)
prom_printf("start[%d] = 0x%2X ", i, start[i]);
prom_printf("\r\nsize = %d\r\n", end-start);
#endif
/* frankliao modify 20100810 */
if(!checkfile(filetype, end-start, 0x80020000+start-upload_buf)){
if(filetype == TCBOOT){
flash_erase(0, end-start);
flash_write(0, end-start, &retlen, (const unsigned char *) (0x80020000+start - upload_buf));
}
else if(filetype == TCLINUX){
flash_erase(flash_tclinux_start, end-start);
flash_write(flash_tclinux_start, end-start, &retlen, (const unsigned char *) (0x80020000+start - upload_buf));
}
prom_printf("Firmware is uploaded successfully!\r\n");
}
else
prom_printf("Fail to upload firmware!\r\n");
afterUpload(p, tpcb);
p_upload_buf = (unsigned char *)0x80020000;
}
}
/* tell the stack we have received the data so it can advertise increase in the
* receive window. */
tcp_recved( tpcb, p->tot_len);
/* process what we got */
process_http( p, tpcb);
}
else {
/* close the strange connection */
prom_printf("tcp_close()\r\n");
tcp_close( tpcb);
}
pbuf_free( p);
}
else if ( tpcb == web->current_connection) {
/* connection is closed */
sprintf( print_buffer, "Connection from %ld.%ld.%ld.%ld is closed",
IP_ADDRESS_FORMAT( tpcb->remote_ip.addr));
#ifdef HTTP_DBG
prom_printf( print_buffer);
#endif
web->current_connection = NULL;
web->last_rx_seqno = 0;
}
return ERR_OK;
}
#endif
static err_t web_accept(void *arg, struct tcp_pcb *newpcb,
err_t err) {
struct web_connection *web = (struct web_connection *)arg;
err_t accept_err = ERR_ABRT;
#ifdef HTTP_DBG
prom_printf("web_accept\r\n");
#endif
if ( err == ERR_OK) {
// if ( web->current_connection == NULL) {
web->current_connection = newpcb;
/* Setup the connection */
tcp_arg( newpcb, web);
tcp_poll( newpcb, my_poll_tcp, 10);
tcp_recv( newpcb, my_recv_tcp);
tcp_sent( newpcb, my_sent_tcp);
tcp_err( newpcb, my_err_tcp);
accept_err = ERR_OK;
// }
#ifdef HTTP_DBG
} else {
prom_printf("One at a time please\r\n");
}
#else
}
#endif
return accept_err;
}
int do_httpd(int argc, char *argv[]){
struct tcp_pcb *web_pcb;
struct ip_addr ipaddr;
extern unsigned long local_ip;
stats_init();
sys_init();
mem_init();
memp_init();
pbuf_init();
etharp_init();
tcp_init();
#ifdef HTTP_DBG
prom_printf("start the web server\r\n");
#endif
the_web_connection.current_connection = NULL;
the_web_connection.last_rx_seqno = 0;
web_pcb = tcp_new();
if ( web_pcb == NULL) {
#ifdef HTTP_DBG
prom_printf("Failed to create Web server PCB\r\n");
#endif
return;
}
web_pcb = tcp_listen(web_pcb);
if ( web_pcb == NULL) {
#ifdef HTTP_DBG
prom_printf( "Failed to listen on web pcb\r\n");
#endif
return;
}
/* Pass the web connection data around the callbacks */
tcp_arg( web_pcb, (void *)&the_web_connection);
/* wait for connections */
tcp_accept( web_pcb, web_accept);
ipaddr.addr = local_ip;
if ( tcp_bind( web_pcb, &ipaddr, 80) != ERR_OK) {
#ifdef HTTP_DBG
prom_printf("Failed to bind to HTTP port (80)\r\n");
#endif
return;
}
}
#endif
#ifdef SPI_TEST_CMD
int do_erase(int argc, char *argv[])
{
unsigned long dst;
unsigned long len;
unsigned long retlen;
dst = strtoul((const char*)(argv[1]), (char **)NULL, 16);
len = strtoul((const char*)(argv[2]), (char **)NULL, 16);
printf("Erase flash from %X with %X bytes\n", dst, len);
flash_erase(dst, len);
printf("\n");
//flash_write(dst, len, &retlen, (const unsigned char *) (src));
return 0;
}
int do_program(int argc, char *argv[])
{
unsigned long dst;
unsigned long src;
unsigned long len;
unsigned long retlen;
dst = strtoul((const char*)(argv[1]), (char **)NULL, 16);
src = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
printf("Write to flash from %X to %X with %X bytes\n", src, dst, len);
//flash_erase(dst, len);
printf("\n");
flash_write(dst, len, &retlen, (const unsigned char *) (src));
return 0;
}
#endif
// MT7530 Switch SLT Program Function
#if defined(MT7530_SLT) || defined(MT7530_SUPPORT)
extern uint32 gswPbusRead(uint32 pbus_addr);
extern int gswPbusWrite(uint32 pbus_addr, uint32 pbus_data);
#endif
#if defined(MT7530_SLT)
extern void tcMiiBpw(uint32 enetPhyAddr, uint32 phyReg, uint32 miiData);
extern int tcMiiBpr(uint32 enetPhyAddr, uint32 phyReg);
extern int tcMiiExtStationFillAddr(uint32 portAddr, uint32 devAddr, uint32 regAddr);
extern int tcMiiExtStationFillAddr_ext(uint32 portAddr, uint32 devAddr, uint32 regAddr);
extern void tcMiiExtStationWrite_ext(uint32 portAddr, uint32 devAddr, uint32 regAddr, uint32 miiData);
extern uint32 tcMiiExtStationRead_ext(uint32 portAddr, uint32 devAddr, uint32 regAddr, uint8 op);
extern void mtEMiiRegWrite(uint32 port_num, uint32 dev_num, uint32 reg_num, uint32 reg_data);
extern uint32 mtEMiiRegRead(uint32 port_num, uint32 dev_num, uint32 reg_num);
extern uint32 gswPmiRead(uint32 phy_addr, uint32 phy_reg);
extern uint32 gswPmiWrite(uint32 phy_addr, uint32 phy_reg, uint32 phy_data);
extern void mtMiiRegWrite(uint32 port_num, uint32 reg_num, uint32 reg_data);
extern uint32 mtMiiRegRead(uint32 port_num,uint8 reg_num);
static int doDumpGSW(int argc, char *argv[])
{
int index = 0;
int port;
char buf[2000];
uint32 mib_offset;
port = strtoul((const char*)(argv[1]), (char **)NULL, 16);
{
mib_offset = MIB_PORT_OFFSET*port;
index += sprintf(buf+index, "[ Port %d ]\n", port);
index += sprintf(buf+index, "Tx drop pkts = 0x%08lx, ", gswPbusRead(MIB_TX_DROP_REG + mib_offset));
index += sprintf(buf+index, "Tx ucast pkts = 0x%08lx\n", gswPbusRead(MIB_TX_UCAST_REG + mib_offset));
index += sprintf(buf+index, "Tx mcast pkts = 0x%08lx, ", gswPbusRead(MIB_TX_MCAST_REG + mib_offset));
index += sprintf(buf+index, "Tx bcast pkts = 0x%08lx\n", gswPbusRead(MIB_TX_BCAST_REG + mib_offset));
index += sprintf(buf+index, "Tx col = 0x%08lx, ", gswPbusRead(MIB_TX_COL_REG + mib_offset));
index += sprintf(buf+index, "Tx scol = 0x%08lx\n", gswPbusRead(MIB_TX_SCOL_REG + mib_offset));
index += sprintf(buf+index, "Tx mcol = 0x%08lx, ", gswPbusRead(MIB_TX_MCOL_REG + mib_offset));
index += sprintf(buf+index, "Tx defer = 0x%08lx\n", gswPbusRead(MIB_TX_DEFER_REG + mib_offset));
index += sprintf(buf+index, "Tx lcol = 0x%08lx, ", gswPbusRead(MIB_TX_LCOL_REG + mib_offset));
index += sprintf(buf+index, "Tx xcol = 0x%08lx\n", gswPbusRead(MIB_TX_XCOL_REG + mib_offset));
index += sprintf(buf+index, "Tx pause = 0x%08lx\n", gswPbusRead(MIB_TX_PAUSE_REG + mib_offset));
index += sprintf(buf+index, "Tx 64 pkts = 0x%08lx, ", gswPbusRead(MIB_TX_PKT_64_CNT + mib_offset));
index += sprintf(buf+index, "Tx 65-127 pkts = 0x%08lx\n", gswPbusRead(MIB_TX_PKT_65TO127_CNT + mib_offset));
index += sprintf(buf+index, "Tx 128-255 pkts = 0x%08lx, ", gswPbusRead(MIB_TX_PKT_128TO255_CNT + mib_offset));
index += sprintf(buf+index, "Tx 256-511 pkts = 0x%08lx\n", gswPbusRead(MIB_TX_PKT_256TO511_CNT + mib_offset));
index += sprintf(buf+index, "Tx 512-1023 pkts = 0x%08lx, ", gswPbusRead(MIB_TX_PKT_512TO1023_CNT + mib_offset));
index += sprintf(buf+index, "Tx 1024-MAX pkts = 0x%08lx\n", gswPbusRead(MIB_TX_PKT_1024TOMAX_CNT + mib_offset));
index += sprintf(buf+index, "Rx drop pkts = 0x%08lx, ", gswPbusRead(MIB_RX_DROP_REG + mib_offset));
index += sprintf(buf+index, "Rx filter pkts = 0x%08lx\n", gswPbusRead(MIB_RX_FILTER_REG + mib_offset));
index += sprintf(buf+index, "Rx ucast pkts = 0x%08lx, ", gswPbusRead(MIB_RX_UCAST_REG + mib_offset));
index += sprintf(buf+index, "Rx mcast pkts = 0x%08lx\n", gswPbusRead(MIB_RX_MCAST_REG + mib_offset));
index += sprintf(buf+index, "Rx bcast pkts = 0x%08lx, ", gswPbusRead(MIB_RX_BCAST_REG + mib_offset));
index += sprintf(buf+index, "Rx align err pkts = 0x%08lx\n", gswPbusRead(MIB_RX_ALIGN_ERR_REG + mib_offset));
index += sprintf(buf+index, "Rx fcs pkts = 0x%08lx, ", gswPbusRead(MIB_RX_FCS_ERR_REG + mib_offset));
index += sprintf(buf+index, "Rx undersize pkts = 0x%08lx\n", gswPbusRead(MIB_RX_UNDERSIZE_REG + mib_offset));
index += sprintf(buf+index, "Rx frag err pkts = 0x%08lx, ", gswPbusRead(MIB_RX_FRAG_ERR_REG + mib_offset));
index += sprintf(buf+index, "Rx oversize pkts = 0x%08lx\n", gswPbusRead(MIB_RX_OVERSIZE_REG + mib_offset));
index += sprintf(buf+index, "Rx jabb err pkts = 0x%08lx, ", gswPbusRead(MIB_RX_JABB_ERR_REG + mib_offset));
index += sprintf(buf+index, "Rx pase pkts = 0x%08lx\n", gswPbusRead(MIB_RX_PAUSE_REG + mib_offset));
index += sprintf(buf+index, "Rx 64 pkts = 0x%08lx, ", gswPbusRead(MIB_RX_PKT_64_CNT + mib_offset));
index += sprintf(buf+index, "Rx 65-127 pkts = 0x%08lx\n", gswPbusRead(MIB_RX_PKT_65TO127_CNT + mib_offset));
index += sprintf(buf+index, "Rx 128-255 pkts = 0x%08lx, ", gswPbusRead(MIB_RX_PKT_128TO255_CNT + mib_offset));
index += sprintf(buf+index, "Rx 256-511 pkts = 0x%08lx\n", gswPbusRead(MIB_RX_PKT_256TO511_CNT + mib_offset));
index += sprintf(buf+index, "Rx 512-1023 pkts = 0x%08lx, ", gswPbusRead(MIB_RX_PKT_512TO1023_CNT + mib_offset));
index += sprintf(buf+index, "Rx 1024-MAX pkts = 0x%08lx\n", gswPbusRead(MIB_RX_PKT_1024TOMAX_CNT + mib_offset));
index += sprintf(buf+index, "Tx oct = 0x%08lx, ", gswPbusRead(MIB_TX_OCT_CNT_L + mib_offset));
index += sprintf(buf+index, "Rx oct = 0x%08lx\n", gswPbusRead(MIB_RX_OCT_CNT_L + mib_offset));
index += sprintf(buf+index, "------\n");
}
prom_printf("%s\n", buf);
return 0;
}
static void doTCMiiBPWrite(int argc, char *argv[], void *p)
{
uint32 enetPhyAddr, phyReg, miiData;
uint32 cnt=1000000;
enetPhyAddr=strtoul((const char*)(argv[1]), (char **)NULL, 16);
phyReg=strtoul((const char*)(argv[2]), (char **)NULL, 16);
miiData=strtoul((const char*)(argv[3]), (char **)NULL, 16);
tcMiiBpw(enetPhyAddr, phyReg, miiData);
prom_printf("PhyAddr=%x Reg=%x value:%x\r\n", enetPhyAddr, phyReg, miiData);
}
static int doTCMiiBPRead(int argc, char *argv[], void *p)
{
uint32 reg, enetPhyAddr, phyReg;
uint32 cnt=1000000;
enetPhyAddr=strtoul((const char*)(argv[1]), (char **)NULL, 16);
phyReg=strtoul((const char*)(argv[2]), (char **)NULL, 16);
reg = tcMiiBpr(enetPhyAddr, phyReg);
prom_printf("PhyAddr=%x Reg=%x value:%x\r\n", enetPhyAddr, phyReg, reg);
return reg;
}
int doPhyMMDRead(int argc, char *argv[], void *p)
{
uint32 dev_addr=0;
uint32 phyaddr=0;
uint32 reg_addr=0;
uint32 start_addr=0;
uint32 end_addr=0;
uint32 value=0;
int i=0;
if (argc!=4 && argc!=6){
prom_printf("Usage: emiir all <phyaddr> <devaddr> <s_addr> <e_addr>\r\n");
prom_printf(" emiir <phyaddr> <devaddr> <reg>\r\n");
return 0;
}
if (strcmp(argv[1], "all") == 0){ /*Post Read*/
phyaddr = simple_strtoul(argv[2],NULL,16);
dev_addr = simple_strtoul(argv[3],NULL,16);
reg_addr = simple_strtoul(argv[4],NULL,16);
value = simple_strtoul(argv[5],NULL,16);
if((start_addr>65535) ||(end_addr>65535)){
printk("s_addr or e_addr must be less than 65536\r\n");
return 0;
}
for(i=start_addr; i<=end_addr; i++)
{
value=mtEMiiRegRead(phyaddr,dev_addr,i);
prom_printf("* doPhyMMDRead =>phyaddr=%d, dev_addr=%d, data_addr=0x%04lX , value=0x%04lX\r\n", phyaddr, dev_addr, i, value);
}
prom_printf("\r\n");
}
else
{
// tce emiir <DevAddr> <PhyAddr> <regAddr>
phyaddr = simple_strtoul(argv[1],NULL,16);
dev_addr = simple_strtoul(argv[2],NULL,16);
reg_addr = simple_strtoul(argv[3],NULL,16);
value=mtEMiiRegRead(phyaddr,dev_addr,reg_addr);
prom_printf("* doPhyMMDRead =>phyaddr=%d, dev_addr=%d, data_addr=0x%04lX , value=0x%04lX\r\n", phyaddr, dev_addr, reg_addr, value);
return 0;
}
return 0;
}
int doPhyMMDWrite(int argc, char *argv[], void *p)
{
uint32 dev_addr=0;
uint32 phyaddr=0;
uint32 reg_addr=0;
uint32 value=0;
uint16 STBit=0;
uint16 BFlen=0;
uint16 BF,BFMsk=0;
uint32 RValue =0;
uint8 i=0;
if (argc==5)
{
// tce emiiw <DevAddr> <PhyAddr> <regAddr> <data>
phyaddr = simple_strtoul(argv[1],NULL,16);
dev_addr = simple_strtoul(argv[2],NULL,16);
reg_addr = simple_strtoul(argv[3],NULL,16);
value = simple_strtoul(argv[4],NULL,16);
}
if (((argc == 5) || (argc == 7)) && (phyaddr<=0x1f)){
if(argc == 5){
mtEMiiRegWrite(phyaddr, dev_addr,reg_addr,value);
prom_printf("* doPhyMMDWrite => phyaddr=%d, dev_addr=%d, data_addr=0x%04lX , value=0x%04lX\r\n", phyaddr, dev_addr, reg_addr, value);
}
else if(((argc == 7) && (strcmp(argv[0], "emiiwb")) == 0)){
RValue = mtEMiiRegRead(phyaddr,dev_addr, reg_addr);
for(i=0;i<BFlen;i++){
BF=1;
BF=BF<<(STBit+i);
BFMsk = BFMsk | BF;
}
BFMsk = ~BFMsk;
value = (RValue & BFMsk) | (value<<STBit);
prom_printf("* Phyaddr=%d, DevAddr=0x%02lX,RegAddr=0x%02lX, STBit=%0d, BFlen=%0d, value=0x%04lX\r\n", phyaddr,dev_addr, reg_addr, STBit, BFlen, value);
prom_printf("* OrgValue=0x%04lX,",RValue);
mtEMiiRegWrite(phyaddr, dev_addr,reg_addr, value);
RValue = mtEMiiRegRead(phyaddr,dev_addr, reg_addr);
prom_printf(" ModValue=0x%04lX\r\n", RValue);
}
return 0;
}
else {
prom_printf(" CMD Error : emiiw <PhyAddr> <DevAddr> <regAddr> <data>\r\n");
prom_printf(" emiiwb <PhyAddr> <DevAddr> <RegAddr> <STBit> <BFLen> <BFVal> \r\n");
return 0;
}
}
int
doPhyMiiRead (int argc, char *argv[], void *p)
{
uint16 phyaddr=0;
const uint16 page_reg=31;
uint16 page_val=0;
uint32 reg=0;
uint32 value;
int i;
// argc:3
// tce miir all <PhyAddr>
// tce miir <PhyAddr> <RegAddr>
// argc:4
// tce miir all <PhyAddr> <PageNo>
// tce miir <PhyAddr> <PageNo> <RegAddr>
// get parameters
if (argc==3){
if (strcmp(argv[1], "all") == 0){ // tce miir all <PhyAddr>
phyaddr = strtoul((const char*)(argv[2]), (char **)NULL, 16);
}
else { // tce miir <PhyAddr> <RegAddr>
phyaddr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
reg = strtoul((const char*)(argv[2]), (char **)NULL, 16);
}
}
else if (argc==4){
if (strcmp(argv[1], "all") == 0){ // tce miir all <PhyAddr> <PageNo>
phyaddr = strtoul((const char*)(argv[2]), (char **)NULL, 16);
page_val = getMiiPage(argv[3]);
}
else{ // tce miir <PhyAddr> <PageNo> <RegAddr>
phyaddr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
page_val = getMiiPage(argv[2]);
reg = strtoul((const char*)(argv[3]), (char **)NULL, 16);
}
}
if(reg != 31)
mtMiiRegWrite(phyaddr, page_reg, 0);
// check parameters
if ((argc==3 || argc==4)
&& phyaddr<=31 && reg<=31 && page_val!=0xffff){
// set page
if (argc==4){
if (strcmp(argv[1], "all") == 0){ // multiple read
prom_printf("* PageNo=%s ",argv[3]);
prom_printf("\r\n");
}
else{
prom_printf("* PageNo=%s ",argv[2]);
}
mtMiiRegWrite(phyaddr, page_reg, page_val);
}
// read data
if (strcmp(argv[1], "all") == 0){ // multiple read
for( i=0; i<32; i++ ){
value = mtMiiRegRead(phyaddr, i);
prom_printf("[reg=0x%02lX val=%04lX]", i, value);
if( (i+1) % 4 == 0 )
prom_printf("\r\n");
}
}
else{
// Frank
value = mtMiiRegRead(phyaddr, reg);
prom_printf("* PhyAddr=%d RegAddr=0x%02lX value=0x%04lX\r\n", phyaddr, reg, value);
}
return 0;
}
else { // error message
prom_printf("Usage: miir all <PhyAddr> [PageNo]\r\n");
prom_printf(" miir <PhyAddr> <RegAddr>\r\n");
prom_printf(" miir <PhyAddr> <PageNo> <RegAddr>\r\n");
return 0;
}
}
int
doPhyMiiWrite (int argc, char *argv[], void *p)
{
uint16 phyaddr=0;
const uint16 page_reg=31;
uint16 page_val=0;
uint32 reg=0;
uint32 value=0;
uint16 STBit=0;
uint16 BFlen=0;
uint16 BF,BFMsk=0;
uint32 RValue =0;
int i;
// tce miir <PhyAddr> <RegAddr> <Value>
// tce miir <PhyAddr> <PageNo> <RegAddr> <Value>
if (argc==4){
phyaddr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
reg = strtoul((const char*)(argv[2]), (char **)NULL, 16);
value = strtoul((const char*)(argv[3]), (char **)NULL, 16);
prom_printf("*1: argv[2]=%s, argv[3]=%s\r\n", argv[2], argv[3]);
prom_printf("*2: phyaddr=%d, reg=%x, value=%x\r\n", phyaddr, reg, value);
}
else if (argc==5){
phyaddr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
page_val = getMiiPage(argv[2]);
reg = strtoul((const char*)(argv[3]), (char **)NULL, 16);
value = strtoul((const char*)(argv[4]), (char **)NULL, 16);
prom_printf("*1: argv[1]=%s, argv[2]=%s, argv[3]=%s, argv[4]=%s\n", argv[1], argv[2], argv[3], argv[4]);
prom_printf("*2: phyaddr=%d, page =%x, reg=%x, value=%x\r\n", phyaddr, page_val, reg, value);
}
else if (argc==6){
if(strcmp(argv[0], "miiwb") == 0){
phyaddr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
reg = strtoul((const char*)(argv[2]), (char **)NULL, 16);
STBit = strtoul((const char*)(argv[3]), (char **)NULL, 16);
BFlen = strtoul((const char*)(argv[4]), (char **)NULL, 16);
value = strtoul((const char*)(argv[5]), (char **)NULL, 16);
prom_printf("* Phyaddr=%d, RegAddr=0x%02lX, STBit=%0d, BFlen=%0d, value=0x%04lX\r\n", phyaddr, reg, STBit, BFlen, value);
}
}
else if (argc==7){
if(strcmp(argv[0], "miiwb") == 0){
phyaddr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
page_val = getMiiPage(argv[2]);
reg = strtoul((const char*)(argv[3]), (char **)NULL, 16);
STBit = strtoul((const char*)(argv[4]), (char **)NULL, 16);
BFlen = strtoul((const char*)(argv[5]), (char **)NULL, 16);
value = strtoul((const char*)(argv[6]), (char **)NULL, 16);
prom_printf("* Phyaddr=%d, pageNo=%d, RegAddr=0x%02lX, STBit=%0d, BFlen=%0d, value=0x%04lX\r\n", phyaddr, page_val, reg, STBit, BFlen, value);
}
}
// check parameters and write
if(reg != 31)
mtMiiRegWrite(phyaddr, page_reg, 0);
if ((argc==4 || argc==5)
&& (phyaddr<=31) && (reg<=31) && (page_val!=0xffff)){
// set page
if (argc==5){
prom_printf("* PageNo=%s ",argv[2]);
mtMiiRegWrite(phyaddr, page_reg, page_val);
}
// write data
prom_printf("* Phyaddr=%d RegAddr=0x%02lX value=0x%04lX\r\n", phyaddr, reg, value);
mtMiiRegWrite(phyaddr, reg, value);
}
else if (((argc == 6) || (argc == 7))
&& (phyaddr<=31) && (reg<=31) && (page_val != 0xffff)){
if (argc==7){
prom_printf("* PageNo=%s ",argv[2]);
mtMiiRegWrite(phyaddr, page_reg, page_val);
}
if(strcmp(argv[0], "miiwb") == 0){
RValue = mtMiiRegRead(phyaddr, reg);
for(i=0;i<BFlen;i++){
BF=1;
BF=BF<<(STBit+i);
BFMsk = BFMsk | BF;
}
BFMsk = ~BFMsk;
value = (RValue & BFMsk) | (value<<STBit);
prom_printf("* OrgValue=0x%04lX,",RValue);
mtMiiRegWrite(phyaddr, reg, value);
RValue = mtMiiRegRead(phyaddr, reg);
prom_printf(" ModValue=0x%04lX\r\n", RValue);
}
}
else { // error message
prom_printf("Usage: miiw <PhyAddr> <RegAddr> <RegVal>\r\n");
prom_printf(" miiw <PhyAddr> <PageNo> <RegAddr> <RegVal>\r\n");
prom_printf(" miiwb <PhyAddr> <RegAddr> <STBit> <BFLen> <BFVal> \r\n");
prom_printf(" miiwb <PhyAddr> <PageNo> <RegAddr> <STBit> <BFLen> <BFVal> \r\n");
return 0;
}
return 0;
}
#endif
#ifndef BOOTROM_IN_SRAM
#if defined(MT7530_SLT) || defined(MT7530_SUPPORT)
int
doGswRead(int argc, char *argv[], void *p)
{
uint16 pbus_addr=0;
uint32 value;
pbus_addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
prom_printf("Read gsw register: %x\n", pbus_addr);
value = gswPbusRead(pbus_addr);
prom_printf("value: %x\n", value);
return 0;
}
int
doGswWrite(int argc, char *argv[], void *p)
{
uint16 pbus_addr=0;
uint32 pbus_data=0;
pbus_addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
pbus_data = strtoul((const char*)(argv[2]), (char **)NULL, 16);
prom_printf("Write gsw register %x into %x value\n", pbus_addr, pbus_data);
gswPbusWrite(pbus_addr, pbus_data);
return 0;
}
#endif
int do_miir(int argc, char *argv[])
{
unsigned long phyaddr;
unsigned long reg;
phyaddr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
reg = strtoul((const char*)(argv[2]), (char **)NULL, 16);
printf("Read phy reg %x from addr %x=%04x\n", reg, phyaddr, miiStationRead(phyaddr, reg));
return 0;
}
int do_miiw(int argc, char *argv[])
{
unsigned long phyaddr;
unsigned long reg;
unsigned long value;
phyaddr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
reg = strtoul((const char*)(argv[2]), (char **)NULL, 16);
value = strtoul((const char*)(argv[3]), (char **)NULL, 16);
miiStationWrite(phyaddr, reg, value);
printf("Write phy reg %x from addr %x=%04x\n", reg, phyaddr, miiStationRead(phyaddr, reg));
return 0;
}
#endif
static u32 zd_rand = 0;
static u32 rand_word = 0;
static u8 random_byte(void)
{
zd_rand = zd_rand * 1664525 + 1013904223;
return (u8) (zd_rand >> 24);
}
#ifdef SPI_TEST_CMD
static u32 random_word(void)
{
rand_word += (VPint(CR_TIMER1_VLR)) * (random_byte());
return rand_word;
}
int do_memcmp(int argc, char *argv[])
{
unsigned long addr1;
unsigned long addr2;
unsigned long len;
int result;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
result = memcmp(addr1, addr2, len);
printf("memcmp addr1=%X addr2=%X len=%X result=%d %X\n", addr1, addr2, len, result, result);
return 0;
}
int do_dmacpy(int argc, char *argv[])
{
unsigned long addr1;
unsigned long addr2;
unsigned long len;
unsigned char ch, burst_size;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
if (isRT63365 || isMT751020 || isMT7505) {
ch = random_byte() & 0xf;
burst_size = random_byte() & 0x7;
if (burst_size > 4)
burst_size = 4;
if (len == 0)
len = 1;
// GDMA
VPint(CR_GDMA_SA(ch)) = (addr2 & 0x1fffffff);
VPint(CR_GDMA_DA(ch)) = (addr1 & 0x1fffffff);
VPint(CR_GDMA_CT1(ch)) = (32<<16) | (32<<8);
VPint(CR_GDMA_CT0(ch)) = ((len&0xffff)<<16) | (burst_size<<3) | (1<<1) | (1<<0);
while (!(VPint(CR_GDMA_DONEINT) & (1<<ch))) ;
VPint(CR_GDMA_DONEINT) = (1<<ch);
} else {
// GDMA
VPint(CR_GDMA_DCSA) = (addr2 & 0x1fffffff);
VPint(CR_GDMA_DCDA) = (addr1 & 0x1fffffff);
VPint(CR_GDMA_DCBT) = (len & 0xffff);
VPint(CR_GDMA_DCC) = 0x101;
while(!((*(volatile unsigned char *)(0xbfb3000d) & 0x1)));
*(volatile unsigned char *)(0xbfb3000d) = 0x3;
}
if (isRT63365)
printf("ch=%d burst_size=%d ", ch, burst_size);
printf("dmacpy addr1=%X addr2=%X len=%X\n", addr1, addr2, len);
return 0;
}
int do_memcpy(int argc, char *argv[])
{
unsigned long addr1;
unsigned long addr2;
unsigned long len;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
memcpy(addr1, addr2, len);
printf("memcpy addr1=%X addr2=%X len=%X\n", addr1, addr2, len);
return 0;
}
int do_memcmp4(int argc, char *argv[])
{
unsigned long addr1;
unsigned long addr2;
unsigned long len;
int result;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
result = memcmp4(addr1, addr2, len);
printf("memcmp4 addr1=%X addr2=%X len=%X result=%d %X\n", addr1, addr2, len, result, result);
return 0;
}
int do_memcpy4(int argc, char *argv[])
{
unsigned long addr1;
unsigned long addr2;
unsigned long len;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
memcpy4(addr1, addr2, len);
printf("memcpy4 addr1=%X addr2=%X len=%X\n", addr1, addr2, len);
return 0;
}
int do_memcmp2(int argc, char *argv[])
{
unsigned long addr1;
unsigned long addr2;
unsigned long len;
int result;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
result = memcmp2(addr1, addr2, len);
printf("memcmp2 addr1=%X addr2=%X len=%X result=%d %X\n", addr1, addr2, len, result, result);
return 0;
}
int do_memcpy2(int argc, char *argv[])
{
unsigned long addr1;
unsigned long addr2;
unsigned long len;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
memcpy2(addr1, addr2, len);
printf("memcpy2 addr1=%X addr2=%X len=%X\n", addr1, addr2, len);
return 0;
}
int do_memset(int argc, char *argv[])
{
unsigned long addr;
unsigned char pattern;
unsigned long len;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
pattern = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
memset(addr, pattern, len);
printf("memset addr=%X pattern=%X len=%X\n", addr, pattern, len);
return 0;
}
int do_memset4(int argc, char *argv[])
{
unsigned long addr;
unsigned long pattern;
unsigned long len;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
pattern = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
memset4(addr, pattern, len);
printf("memset4 addr=%X pattern=%X len=%X\n", addr, pattern, len);
return 0;
}
int do_memset42(int argc, char *argv[])
{
unsigned long addr;
unsigned long pattern1;
unsigned long pattern2;
unsigned long len;
unsigned int *xs;
int toggle = 1;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
pattern1 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
pattern2 = strtoul((const char*)(argv[3]), (char **)NULL, 16);
len = strtoul((const char*)(argv[4]), (char **)NULL, 16);
printf("memset4 addr=%X pattern1=%X pattern2=%X len=%X\n", addr, pattern1, pattern2, len);
xs = (unsigned int *) addr;
len = len >> 2;
while (len--) {
if (toggle)
*xs++ = pattern1;
else
*xs++ = pattern2;
toggle = toggle ^ 1;
}
return 0;
}
int do_memset44(int argc, char *argv[])
{
unsigned long addr;
unsigned long pattern[4];
unsigned long len;
unsigned int *xs;
int i;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
for (i = 0 ; i < 4; i++)
pattern[i] = strtoul((const char*)(argv[2+i]), (char **)NULL, 16);
len = strtoul((const char*)(argv[6]), (char **)NULL, 16);
printf("memset4 addr=%X p1~4=%X %X %X %X len=%X\n", addr, pattern[0], pattern[1], pattern[2], pattern[3], len);
xs = (unsigned int *) addr;
len = len >> 2;
i=0;
while (len--) {
*xs++ = pattern[i];
i++;
if (i >= 4)
i = 0;
}
return 0;
}
int do_incr(int argc, char *argv[])
{
unsigned long addr;
unsigned long pattern;
unsigned long len;
unsigned char *xs;
unsigned char pat;
unsigned char step = 1;
int i;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
pattern = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
if (argc == 5)
step = strtoul((const char*)(argv[4]), (char **)NULL, 16);
pat = (unsigned char) pattern;
printf("incr addr=%X p=%X len=%X step=%X\n", addr, pat, len, step);
xs = (unsigned char *) addr;
while (len--) {
*xs++ = pat;
pat += step;
}
return 0;
}
int do_incrcmp(int argc, char *argv[])
{
unsigned long addr;
unsigned long pattern;
unsigned long len;
unsigned char *xs;
unsigned char pat;
unsigned char step = 1;
int i;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
pattern = strtoul((const char*)(argv[2]), (char **)NULL, 16);
len = strtoul((const char*)(argv[3]), (char **)NULL, 16);
if (argc == 5)
step = strtoul((const char*)(argv[4]), (char **)NULL, 16);
pat = (unsigned char) pattern;
printf("incrcmp addr=%X p=%X len=%X step=%X\n", addr, pat, len, step);
xs = (unsigned char *) addr;
while (len--) {
if (*xs != pat)
printf("incrcmp addr1=%X len=%X result=%X %X\n", xs, len, *xs, pat);
xs++;
pat += step;
}
return 0;
}
int do_rreadb(int argc, char* argv[])
{
unsigned long addr1;
unsigned long addr2;
int i;
const unsigned char *su1, *su2, *su3 = 0x80020000;
unsigned char c, d;
int offset;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
memcpy(0x80020000, addr1, addr2-addr1+1);
su1 = (const unsigned char *) addr1;
su2 = (const unsigned char *) addr2;
while (su1 < su2) {
c = *su1;
d = *su3;
if (c != d)
printf("error su1=%08x su3=%08x c=%02x d=%02x\n", su1, su3, c, d);
offset = (random_byte() & 0x7f);
su1 += offset;
su3 += offset;
}
return 0;
}
int do_rreadl(int argc, char* argv[])
{
unsigned long addr1;
unsigned long addr2;
volatile unsigned long *su1, *su2;
volatile unsigned long val;
unsigned long i, cnt;
int offset;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
cnt = strtoul((const char*)(argv[3]), (char **)NULL, 16);
for (i = 0; i < cnt; i++) {
su1 = (unsigned long *) addr1;
su2 = (unsigned long *) addr2;
while (su1 < su2) {
val = *su1;
offset = 1;
su1 += offset;
}
}
return 0;
}
int do_rwritel(int argc, char* argv[])
{
unsigned long addr1;
unsigned long addr2;
unsigned long *su1, *su2;
unsigned long c, d;
unsigned long pattern;
unsigned long i, cnt;
unsigned char random = 0;
int offset;
addr1 = strtoul((const char*)(argv[1]), (char **)NULL, 16);
addr2 = strtoul((const char*)(argv[2]), (char **)NULL, 16);
pattern = strtoul((const char*)(argv[3]), (char **)NULL, 16);
cnt = strtoul((const char*)(argv[4]), (char **)NULL, 16);
if (pattern == 0x00000000)
random = 1;
for (i = 0; i < cnt; i++) {
su1 = (unsigned long *) addr1;
su2 = (unsigned long *) addr2;
while (su1 < su2) {
*su1 = pattern;
offset = 1;
su1 += offset;
if (random)
pattern += VPint(CR_TIMER1_VLR) * random_byte();
}
}
return 0;
}
int do_step(int argc, char *argv[])
{
unsigned long addr;
unsigned long value;
unsigned long step;
unsigned long len;
unsigned char *xs;
unsigned char pat1;
unsigned char pat2;
unsigned char toggle = 1;
int i;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
value = strtoul((const char*)(argv[2]), (char **)NULL, 16);
pat1 = (unsigned char) value;
value = strtoul((const char*)(argv[3]), (char **)NULL, 16);
pat2 = (unsigned char) value;
step = strtoul((const char*)(argv[4]), (char **)NULL, 16);
len = strtoul((const char*)(argv[5]), (char **)NULL, 16);
printf("step addr=%X p1=%X p2=%x step=%X len=%X\n", addr, pat1, pat2, step, len);
xs = (unsigned char *) addr;
i = 0;
while (len--) {
if (toggle)
*xs++ = pat1;
else
*xs++ = pat2;
i++;
if (i >= step) {
toggle ^= 1;
i = 0;
}
}
return 0;
}
int do_spidbg(int argc, char* argv[])
{
extern unsigned long spidbg;
spidbg = strtoul((const char*)(argv[1]), (char **)NULL, 16);
prom_printf("spi dbg=%X\n", spidbg);
return 0;
}
#ifndef TCSUPPORT_NEW_SPIFLASH
extern void spiflash_qe(int hpm);
extern void spiflash_rdst(void);
#endif
int do_spiqe(int argc, char* argv[])
{
#ifndef TCSUPPORT_NEW_SPIFLASH
int hpm;
hpm = strtoul((const char*)(argv[1]), (char **)NULL, 10);
prom_printf("hpm=%X\n", hpm);
spiflash_qe(hpm);
#endif
return 0;
}
int do_spird(int argc, char* argv[])
{
#ifndef TCSUPPORT_NEW_SPIFLASH
spiflash_rdst();
#endif
return 0;
}
#endif
#ifdef MT7505_SWITCH_TBL_VERIRY
#define REG_ATC_ADDR (0xbfb58080)
#define REG_ATC_AC_CMD_OFFT (0)
#define REG_ATC_AC_CMD_LENG (3)
#define REG_ATC_AC_CMD_RELMASK (0x00000007)
#define REG_ATC_AC_CMD_MASK (REG_ATC_AC_CMD_RELMASK << REG_ATC_AC_CMD_OFFT)
#define REG_ATC_AC_SAT_OFFT (4)
#define REG_ATC_AC_SAT_LENG (2)
#define REG_ATC_AC_SAT_RELMASK (0x00000003)
#define REG_ATC_AC_SAT_MASK (REG_ATC_AC_SAT_RELMASK << REG_ATC_AC_SAT_OFFT)
#define REG_ATC_AC_MAT_OFFT (8)
#define REG_ATC_AC_MAT_LENG (4)
#define REG_ATC_AC_MAT_RELMASK (0x0000000F)
#define REG_ATC_AC_MAT_MASK (REG_ATC_AC_MAT_RELMASK << REG_ATC_AC_MAT_OFFT)
#define REG_AT_SRCH_HIT_OFFT (13)
#define REG_AT_SRCH_HIT_RELMASK (0x00000001)
#define REG_AT_SRCH_HIT_MASK (REG_AT_SRCH_HIT_RELMASK << REG_AT_SRCH_HIT_OFFT)
#define REG_AT_SRCH_END_OFFT (14)
#define REG_AT_SRCH_END_RELMASK (0x00000001)
#define REG_AT_SRCH_END_MASK (REG_AT_SRCH_END_RELMASK << REG_AT_SRCH_END_OFFT)
#define REG_ATC_BUSY_OFFT (15)
#define REG_ATC_BUSY_LENG (1)
#define REG_ATC_BUSY_RELMASK (0x00000001)
#define REG_ATC_BUSY_MASK (REG_ATC_BUSY_RELMASK << REG_ATC_BUSY_OFFT)
#define REG_AT_ADDR_OFFT (16)
#define REG_AT_ADDR_LENG (12)
#define REG_AT_ADDR_RELMASK (0x00000FFF)
#define REG_AT_ADDR_MASK (REG_AT_ADDR_RELMASK << REG_AT_ADDR_OFFT)
#define REG_TSRA1_ADDR (0xbfb58084)
#define REG_TSRA2_ADDR (0xbfb58088)
#define REG_ATRD_ADDR (0xbfb5808C)
#define REG_VTCR_ADDR (0xbfb58090)
#define REG_VTCR_VID_OFFT (0)
#define REG_VTCR_VID_LENG (12)
#define REG_VTCR_VID_RELMASK (0x00000FFF)
#define REG_VTCR_VID_MASK (REG_VTCR_VID_RELMASK << REG_VTCR_VID_OFFT)
#define REG_VTCR_FUNC_OFFT (12)
#define REG_VTCR_FUNC_LENG (4)
#define REG_VTCR_FUNC_RELMASK (0x0000000F)
#define REG_VTCR_FUNC_MASK (REG_VTCR_FUNC_RELMASK << REG_VTCR_FUNC_OFFT)
#define REG_VTCR_IDX_INVLD_OFFT (16)
#define REG_VTCR_IDX_INVLD_RELMASK (0x00000001)
#define REG_VTCR_IDX_INVLD_MASK (REG_VTCR_IDX_INVLD_RELMASK << REG_VTCR_IDX_INVLD_OFFT)
#define REG_VTCR_BUSY_OFFT (31)
#define REG_VTCR_BUSY_RELMASK (0x00000001)
#define REG_VTCR_BUSY_MASK (REG_VTCR_BUSY_RELMASK << REG_VTCR_BUSY_OFFT)
#define REG_VAWD1_ADDR (0xbfb58094)
#define REG_VAWD2_ADDR (0xbfb58098)
void MT7505_Switch_Tbl_Test(void)
{
int i;
unsigned long vawd1, vawd2, rule_vawd1, rule_vawd2, rate_vawd1, rate_vawd2;
unsigned long value, reg;
prom_printf("VLAN TABLE------------------->\n");
for (i=0; i<16; i++)
{
prom_printf("Entry[%d]--------->\n",i);
reg = REG_VTCR_ADDR; // VTCR
value = (0x80000000 + i);
//gsw_reg_write(swcfg->skfd, swcfg->ifr, reg, value);
VPint(reg) = value;
reg = REG_VTCR_ADDR; // VTCR
while (1) {
//value = gsw_reg_read(swcfg->skfd, swcfg->ifr, reg);
value = VPint(reg);
if ((value & 0x80000000) == 0) { //table busy
break;
}
}
reg = REG_VAWD1_ADDR; // VAWD1
//vawd1 = gsw_reg_read(swcfg->skfd, swcfg->ifr, reg);
vawd1 = VPint(reg);
prom_printf("bfb58094=%x\n", vawd1);
}
prom_printf("MAC TABLE------------------->\n");
for (i=0; i<512; i=i+4)
{
prom_printf("Entry[%d]--------->\n",i);
VPint(0xbfb58078) = i << 2;
VPint(REG_ATC_ADDR) = 0x8030;
prom_printf("bfb58084=%x,bfb58088=%x,bfb5808c=%x\n", VPint(REG_TSRA1_ADDR),VPint(REG_TSRA2_ADDR),VPint(REG_ATRD_ADDR));
}
prom_printf("ACL TABLE------------------->\n");
{
while (1){ // wait until not busy
//value = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VTCR_ADDR);
value = VPint(REG_VTCR_ADDR);
if ((value & REG_VTCR_BUSY_MASK) == 0){
break;
}
}
// Display ACL table entry 0~63
prom_printf("Found following ACL table entries :\n");
for (i = 0; i < 64; i ++){
value = REG_VTCR_BUSY_MASK | (0x04 << REG_VTCR_FUNC_OFFT) | i; // read ACL table (0x04)
//gsw_reg_write(swcfg->skfd, swcfg->ifr, REG_VTCR_ADDR, value);
VPint(REG_VTCR_ADDR) = value;
while (1){ // wait until not busy
//value = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VTCR_ADDR);
value = VPint(REG_VTCR_ADDR);
if ((value & REG_VTCR_BUSY_MASK) == 0){
break;
}
}
//vawd1 = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VAWD1_ADDR);
vawd1 = VPint(REG_VAWD1_ADDR);
//vawd2 = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VAWD2_ADDR);
vawd2 = VPint(REG_VAWD2_ADDR);
if (vawd2 & (1 << 19)){ // EN==1
prom_printf("[#%2d] CMP_SEL:%d, SP_map:%02X, OFST_TP:%d, WORD_OFST:%3d, BIT_MASK:%04X, CMP_PAT:%04X\n",
i, (vawd2 & 1), ((vawd2>>8) & 0xFF), ((vawd2>>16) & 0x07), ((vawd2>>1) & 0x3F), ((vawd1>>16) & 0xFFFF), (vawd1 & 0xFFFF));
}
}
// Display Mask, Rule Ctrl, and Rate Ctrl table entry 0~31
prom_printf("Found following Mask, Rule ctrl, Rate ctrl table entries : (in vawd1,vawd2)\n");
for (i = 0; i < 32; i ++){
value = REG_VTCR_BUSY_MASK | (0x08 << REG_VTCR_FUNC_OFFT) | i; // read Mask Table (0x08)
//gsw_reg_write(swcfg->skfd, swcfg->ifr, REG_VTCR_ADDR, value);
VPint(REG_VTCR_ADDR) = value;
while (1){ // wait until not busy
//value = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VTCR_ADDR);
value = VPint(REG_VTCR_ADDR);
if ((value & REG_VTCR_BUSY_MASK) == 0){
break;
}
}
//vawd1 = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VAWD1_ADDR);
vawd1 = VPint(REG_VAWD1_ADDR);
//vawd2 = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VAWD2_ADDR);
vawd2 = VPint(REG_VAWD2_ADDR);
if (vawd1 || vawd2){ // ACL_MASK[63:0] any bit != 0
value = REG_VTCR_BUSY_MASK | (0x0A << REG_VTCR_FUNC_OFFT) | i; // read Rule Ctrl Table (0x0A)
//gsw_reg_write(swcfg->skfd, swcfg->ifr, REG_VTCR_ADDR, value);
VPint(REG_VTCR_ADDR)=value;
while (1){ // wait until not busy
//value = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VTCR_ADDR);
value = VPint(REG_VTCR_ADDR);
if ((value & REG_VTCR_BUSY_MASK) == 0){
break;
}
}
//rule_vawd1 = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VAWD1_ADDR);
rule_vawd1 = VPint(REG_VAWD1_ADDR);
//rule_vawd2 = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VAWD2_ADDR);
rule_vawd2 = VPint(REG_VAWD2_ADDR);
value = REG_VTCR_BUSY_MASK | (0x0C << REG_VTCR_FUNC_OFFT) | i; // read Rate Ctrl Table (0x0C)
//gsw_reg_write(swcfg->skfd, swcfg->ifr, REG_VTCR_ADDR, value);
VPint(REG_VTCR_ADDR)=value;
while (1){ // wait until not busy
//value = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VTCR_ADDR);
value = VPint(REG_VTCR_ADDR);
if ((value & REG_VTCR_BUSY_MASK) == 0){
break;
}
}
//rate_vawd1 = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VAWD1_ADDR);
rate_vawd1 = VPint(REG_VAWD1_ADDR);
//rate_vawd2 = gsw_reg_read(swcfg->skfd, swcfg->ifr, REG_VAWD2_ADDR);
rate_vawd2= VPint(REG_VAWD2_ADDR);
prom_printf("[#%2d] Mask:%08X,%08X; Rule:%08X,%08X; Rate:%08X,%08X\n",
i, vawd1, vawd2, rule_vawd1, rule_vawd2, rate_vawd1, rate_vawd2);
}
}
}
}
#endif
#ifdef SPI_DRAM_TEST_CMD
#define MAX_CMD_LEN (128)
static void getAttrVal(const char *inStr, const char *pAttr, const char *delim, char *pVal, int valBufLen) {
char tmp[MAX_CMD_LEN] = {0};
char *t;
int len;
if((inStr == 0) || (pAttr == 0) || (delim == 0) || (pVal == 0))
{
return;
}
len = strlen(inStr);
if(len >= MAX_CMD_LEN)
{
len = MAX_CMD_LEN -1;
}
strncpy(tmp, inStr, len);
tmp[len] = '\0';
strcpy(pVal, "\0");
t = (char*)strtok(tmp, delim);
while (t) {
if (!strcmp(pAttr, t)){
t = (char*)strtok((void*)0, delim);
if (t) {
len = strlen(t);
if(len >= valBufLen)
{
len = valBufLen -1;
}
strncpy(pVal, t, len);
pVal[len] = '\0';
}
break;
}
t = (char*)strtok((void*)0, delim);
}
}
#define KSEG0_BASE_ADDR 0x80000000
#define KSEG0_START_ADDR 0x80020000
#define KSEG0_END_ADDR 0x8fffffff
#define KSEG1_BASE_ADDR 0xa0000000
#define KSEG1_START_ADDR 0xa0020000
#define KSEG1_END_ADDR 0xafffffff
#define MAX_DRAM_SIZE 0x10000000
#ifdef TCSUPPORT_ADDR_MAPPING
extern int highmemConfig(void);
#endif
int do_dramtest(int argc, char* argv[])
{
int i;
char pVal[MAX_CMD_LEN] = {0};
unsigned long addr = 0;
unsigned long size = 0;
unsigned long pattern = 0;
unsigned char wByte = 0;
unsigned char infinite = 0;
int isGetAddr = 0, isGetSize = 0, isGetPat = 0, isGetWByte = 0, isInfinite = 0;
unsigned long totalSize = 0;
unsigned long kseg0EndAddr = 0, kseg1EndAddr = 0;
unsigned long endAddr;
#ifdef TCSUPPORT_ADDR_MAPPING
int highmemFlag = 0;
int highmemSize = 0;
#endif
dramTest_info_t info;
totalSize = calculate_dram_size();
printf("totalSize=%d MB ",totalSize);
#ifdef TCSUPPORT_ADDR_MAPPING
if(totalSize >= 448){
highmemSize = (totalSize - 448)<<20;
totalSize = 448; // 20130130 pork added: for address mapping
highmemFlag = 1;
}
#endif
totalSize = totalSize << 20;
printf("0x%x \n",totalSize);
kseg0EndAddr = 0x80000000 + totalSize - 1;
kseg1EndAddr = 0xa0000000 + totalSize - 1;
printf("argc=%d \n",argc);
if(argc > 1)
{
for(i=1; i<argc; i++)
{
if(!isGetAddr)
{
getAttrVal(argv[i], "a", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
addr = strtoul((const char*)pVal, (char **)NULL, 16);
addr = addr & 0xfffffffc;
if((addr >= KSEG0_START_ADDR && addr <= kseg0EndAddr) || \
(addr >= KSEG1_START_ADDR && addr <= kseg1EndAddr))
{
isGetAddr = 1;
printf("addr=0x%x \n", addr);
}
continue;
}
}
if(!isGetSize)
{
getAttrVal(argv[i], "s", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
size = strtoul((const char*)pVal, (char **)NULL, 16);
if(isGetAddr)
{
endAddr = addr + size;
}
else{
endAddr = KSEG0_START_ADDR + size;
}
if((endAddr >= KSEG0_START_ADDR && endAddr <= kseg0EndAddr) || \
(endAddr >= KSEG1_START_ADDR && endAddr <= kseg1EndAddr))
{
isGetSize = 1;
printf("size=0x%x \n", size);
}
continue;
}
}
if(!isGetPat)
{
getAttrVal(argv[i], "p", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
pattern = strtoul((const char*)pVal, (char **)NULL, 16);
isGetPat = 1;
printf("pat=0x%x \n", pattern);
continue;
}
}
if(!isGetWByte)
{
getAttrVal(argv[i], "w", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
wByte = strtoul((const char*)pVal, (char **)NULL, 10);
if((wByte == 1) || (wByte == 2) || (wByte == 4))
{
isGetWByte = 1;
printf("wByte=%d \n", wByte);
}
continue;
}
}
if(!isInfinite)
{
getAttrVal(argv[i], "i", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
infinite = strtoul((const char*)pVal, (char **)NULL, 10);
isInfinite = 1;
printf("infinite=%d \n", infinite);
continue;
}
}
}
}
if(isGetAddr)
{
if(!isGetSize)
{
if(addr >= KSEG0_START_ADDR && addr <= kseg0EndAddr)
{
size = kseg0EndAddr - addr + 1;
}
else if(addr >= KSEG1_START_ADDR && addr <= kseg1EndAddr)
{
size = kseg1EndAddr - addr + 1;
}
}
info.startAddr = addr;
info.size = size;
info.pattern = pattern;
info.wByte = wByte;
if(infinite == 0)
{
printf("1TEST <addr=0x%x> <size=0x%x> <wByte=%d> \n", addr, size, wByte);
dramTest(&info, isGetPat);
}
else
{
while(1)
{
printf("1TEST <addr=0x%x> <size=0x%x> <wByte=%d> \n", addr, size, wByte);
if(dramTest(&info, isGetPat) != 0)
{
return 0;
}
}
}
}
else
{
if(!isGetSize)
{
size = totalSize - 0x20000;
}
info.size = size;
info.pattern = pattern;
info.wByte = wByte;
if(infinite == 0)
{
printf("2TEST <addr=0x%x> <size=0x%x> <wByte=%d> \n", KSEG0_START_ADDR, size, wByte);
info.startAddr = KSEG0_START_ADDR;
dramTest(&info, isGetPat);
printf("2TEST <addr=0x%x> <size=0x%x> <wByte=%d> \n", KSEG1_START_ADDR, size, wByte);
info.startAddr = KSEG1_START_ADDR;
dramTest(&info, isGetPat);
}
else
{
while(1)
{
#ifdef TCSUPPORT_ADDR_MAPPING
if(highmemFlag){
info.size = highmemSize;
info.startAddr = 0xd0000000;
printf("2TEST <Highmem size:0x%x> <wByte=%d> \n",info.size,wByte);
highmemConfig();
if(dramTest(&info, isGetPat) != 0)
return 0;
}
info.startAddr = KSEG0_START_ADDR;
info.size = size;
printf("2TEST <addr=0x%x> <size=0x%x> <wByte=%d> \n", KSEG0_START_ADDR, info.size, wByte);
#else
printf("2TEST <addr=0x%x> <size=0x%x> <wByte=%d> \n", KSEG0_START_ADDR, size, wByte);
info.startAddr = KSEG0_START_ADDR;
#endif
if(dramTest(&info, isGetPat) != 0)
{
return 0;
}
printf("2TEST <addr=0x%x> <size=0x%x> <wByte=%d> \n", KSEG1_START_ADDR, info.size, wByte);
info.startAddr = KSEG1_START_ADDR;
if(dramTest(&info, isGetPat) != 0)
{
return 0;
}
}
}
}
return 0;
}
int do_flashtest(int argc, char* argv[])
{
int i;
char pVal[MAX_CMD_LEN] = {0};
unsigned long addr = 0;
unsigned long size = 0;
unsigned long pattern = 0;
unsigned char infinite = 0;
int isGetAddr = 0, isGetSize = 0, isGetPat = 0, isInfinite = 0;
unsigned long totalSize = 0;
unsigned long flashEndAddr = 0;
unsigned long endAddr;
spiFlashTest_info_t info;
totalSize = spiflash_sizeGet();
if(totalSize == -1)
{
return 0;
}
printf("totalSize=0x%x %dMB \n", totalSize, totalSize>> 20);
flashEndAddr = totalSize - 1;
printf("argc=%d \n",argc);
if(argc > 1)
{
for(i=1; i<argc; i++)
{
if(!isGetAddr)
{
getAttrVal(argv[i], "a", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
addr = strtoul((const char*)pVal, (char **)NULL, 16);
addr = addr & 0xffff0000;
if((addr >= FLASH_START_TEST && addr <= flashEndAddr))
{
isGetAddr = 1;
printf("addr=0x%x \n", addr);
}
continue;
}
}
if(!isGetSize)
{
getAttrVal(argv[i], "s", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
size = strtoul((const char*)pVal, (char **)NULL, 16);
size = size & 0xffff0000;
if(isGetAddr)
{
endAddr = addr + size;
}
else{
endAddr = FLASH_START_TEST + size;
}
if((endAddr >= FLASH_START_TEST && endAddr <= flashEndAddr))
{
isGetSize = 1;
printf("size=0x%x \n", size);
}
continue;
}
}
if(!isGetPat)
{
getAttrVal(argv[i], "p", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
pattern = strtoul((const char*)pVal, (char **)NULL, 16);
isGetPat = 1;
printf("pat=0x%x \n", pattern);
continue;
}
}
if(!isInfinite)
{
getAttrVal(argv[i], "i", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
infinite = strtoul((const char*)pVal, (char **)NULL, 10);
isInfinite = 1;
printf("infinite=%d \n", infinite);
continue;
}
}
}
}
if(isGetAddr)
{
if(!isGetSize)
{
size = flashEndAddr - addr + 1;
}
}
else
{
addr = FLASH_START_TEST;
if(!isGetSize)
{
size = totalSize - 0x20000;
}
}
info.startAddr = addr;
info.size = size;
info.pattern = pattern;
if(infinite == 0)
{
printf("SPI FLASH TEST <addr=0x%x> <size=0x%x> \n", addr, size);
spiFlashTest(&info, isGetPat);
}
else
{
while(1)
{
printf("SPI FLASH TEST <addr=0x%x> <size=0x%x> \n", addr, size);
if(spiFlashTest(&info, isGetPat) != 0)
{
return 0;
}
}
}
return 0;
}
int do_spiregrw(int argc, char* argv[])
{
#define SPI_REG_BASE 0xbfbc0000
unsigned long regAddr[10] = {0x04, 0x08 , 0x0c , 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28};
unsigned long val[10] = {0x10f, 0x1ff0ef, 0x9f, 0x1ee0ff, 0xa52, 0x2fe034, 0x1ff0e, 0xfef, 0x2fe03, 0x26ff88};
unsigned long addr;
int i;
unsigned long writeVal, readVal;
for(i=0; i<10; i++)
{
addr = SPI_REG_BASE | regAddr[i];
writeVal = val[i];
/*write*/
tc_outl(addr, writeVal);
printf("addr=%x val=%x \n",addr, writeVal);
/*read*/
readVal = tc_inl(addr);
printf("readVal=%x\n", readVal);
if(readVal != writeVal)
{
printf("ERROR! addr=0x%x, write val=0x%x, read val=0x%x \n", addr, writeVal, readVal);
}
}
printf("register test finished \n");
return 0;
}
#define DEF_LENGTH 0xffff
#define TEST_STAR_ADDR 0x20000
int gdmaTestCpy(unsigned long sa, unsigned long da, unsigned long len, unsigned char burst_size, unsigned char wswap)
{
unsigned char ch;
int counter = 0;
if (!isMT751020 && !isMT7505) {
printf("No Support! \n");
return 0;
}
ch = random_byte() & 0xf;
if (isEN751221)
ch &= 0x7;
if (len == 0)
len = 1;
// GDMA
VPint(CR_GDMA_SA(ch)) = sa;
VPint(CR_GDMA_DA(ch)) = da;
VPint(CR_GDMA_CT1(ch)) = (wswap<<28) | (1<<2);
// printf("%X: %X \n", CR_GDMA_CT1(ch), tc_inl(CR_GDMA_CT1(ch)));
VPint(CR_GDMA_CT0(ch)) = ((len&0xffff)<<16) | (burst_size<<3) | (1<<1) | (1<<0);
// printf("%X: %X \n", CR_GDMA_CT0(ch), tc_inl(CR_GDMA_CT0(ch)));
while(counter < 500){
if(!(VPint(CR_GDMA_DONEINT) & (1<<ch))){
VPint(CR_GDMA_DONEINT) = (1<<ch);
break;
}
counter++;
}
printf("ch=%d burst_size=%d wswap=%d ", ch, burst_size, wswap);
printf("gdmaTestCpy sa=0x%x da=0x%x len=0x%x\n", sa, da, (len&0xffff));
return 0;
}
int do_gdmatestdram(int argc, char* argv[])
{
char pVal[MAX_CMD_LEN] = {0};
unsigned char infinite = 0;
gdmaTest_info_t info;
unsigned long dramSize = 0;
unsigned char burst_size;
if (!isMT751020 && !isMT7505) {
printf("No Support! \n");
return 0;
}
dramSize = calculate_dram_size();
printf("dramSize=%d MB ",dramSize);
dramSize = dramSize << 20;
printf("0x%x \n",dramSize);
getAttrVal(argv[1], "i", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
infinite = strtoul((const char*)pVal, (char **)NULL, 10);
printf("infinite=%d \n\n", infinite);
}
do
{
info.sa = (random_word() % (dramSize - TEST_STAR_ADDR)) + TEST_STAR_ADDR;
info.da = info.sa + DEF_LENGTH + 1;
if(info.da >= dramSize){
info.sa = TEST_STAR_ADDR;
info.da = info.sa + DEF_LENGTH + 1;
}
info.len = DEF_LENGTH;
info.wswap = 0;
for(burst_size=0; burst_size<=4; burst_size++)
{
info.burst_size = burst_size;
if(gdmaTestDram(&info) != 0)
{
return 0;
}
}
printf("*********\n");
}while(infinite);
return 0;
}
int do_gdmatestflash(int argc, char* argv[])
{
char pVal[MAX_CMD_LEN] = {0};
unsigned char infinite = 0;
gdmaTest_info_t info;
unsigned long flashSize = 0;
unsigned long len = 0;
unsigned char burst_size;
unsigned long addr = 0;
unsigned long flashPhyBaseAddrBlock1 = 0x1c000000;
if (!isMT751020 && !isMT7505) {
printf("No Support! \n");
return 0;
}
flashSize = spiflash_sizeGet();
if(flashSize == -1)
{
return 0;
}
printf("flashSize=0x%x %dMB \n", flashSize, flashSize>> 20);
getAttrVal(argv[1], "i", "=", pVal, MAX_CMD_LEN);
if(strlen(pVal))
{
infinite = strtoul((const char*)pVal, (char **)NULL, 10);
printf("infinite=%d \n\n", infinite);
}
do
{
addr = (random_word() % (flashSize - FLASH_START_TEST)) + FLASH_START_TEST;
addr &= ~(0xffff);
if((addr + DEF_LENGTH) >= flashSize)
{
addr = FLASH_START_TEST;
}
info.sa = addr + flashPhyBaseAddrBlock1; //flash phy addr
info.da = addr; //dram phy addr
info.len = DEF_LENGTH & ~(0x3);
info.wswap = 1;
for(burst_size=0; burst_size<=4; burst_size++)
{
info.burst_size = burst_size;
if(gdmaTestFlash(&info) != 0)
{
return 0;
}
}
printf("#########\n");
}while(infinite);
return 0;
}
int do_gdmatestreg(int argc, char* argv[])
{
#ifndef TCSUPPORT_CPU_MT7505
#define TEST_NUMS 4
#define KSEG1_START_ADDR 0xa0020000
/*ptm, atm, usb, pcie, fe, pcm, spi, */
unsigned long virAddr[TEST_NUMS] = {0xbfb62004, 0xbfb60004, /*0xbfba0054,*/ 0xbfb80000, 0xbfb50830, 0xbfbd0000, 0xbfbc0028};
unsigned long val[TEST_NUMS] = {0x2010101, 0x00000003, /*0x00001001,*/ 0x001000b0, 0xa52, 0xf5071306, 0x78880};
#else
#define TEST_NUMS 4
#define KSEG1_START_ADDR 0xa0020000
/*ptm, atm, usb, pcie, fe, pcm, spi, */
unsigned long virAddr[TEST_NUMS] = {/*0xbfb62004, */0xbfb60004, 0xbfbb0054, 0xbfb00088, 0xbfb50830/*, 0xbfbd0000, 0xbfbc0028*/ };
unsigned long val[TEST_NUMS] = {/*0x2010101, */0x00000003, 0x00002000, 0x13c08000, 0xa52/*, 0xf5071306, 0x78880*/};
#endif
unsigned long *dramAddr;
int i;
int ret = 0;
int len = 0;
unsigned char burst_size;
if (!isMT751020 && !isMT7505) {
printf("No Support! \n");
return 0;
}
dramAddr = KSEG1_START_ADDR;
len = 4;
for(burst_size=0; burst_size<=4; burst_size++)
{
for(i=0; i<TEST_NUMS; i++)
{
printf("index i=%d\n",i);
/*write*/
*dramAddr = val[i];
gdmaTestCpy(TEST_STAR_ADDR, PHYSADDR(virAddr[i]), len, burst_size, 1);
ret += memcmp(KSEG1_START_ADDR, virAddr[i], len);
/*read*/
*dramAddr = 0;
gdmaTestCpy(PHYSADDR(virAddr[i]), TEST_STAR_ADDR, len, burst_size, 1);
ret += memcmp(KSEG1_START_ADDR, virAddr[i], len);
printf("\n\n");
}
}
if(ret != 0)
{
printf("gdmatestreg FAIL!\n\n");
}
else
{
printf("gdmatestreg SUCCESS!\n\n");
}
return 0;
}
/**************** memory access range protection *****************/
#if defined(DRAM_PROTECT_TEST)
static unsigned long segAddr[2][2] = { {KSEG0_BASE_ADDR, KSEG0_START_ADDR},
{KSEG1_BASE_ADDR, KSEG1_START_ADDR} };
int illinfo_record(unsigned long ill_info_reg,unsigned long ill_addr_reg)
{
int i=0;
int new_data = 0;
//different address access
if(record2[test_round][5] != ill_addr_reg)
{
if(ex_addr_count < 1000)
{
if(ex_addr_count)
{
for(i=0;i<ex_addr_count;i++)
{
if(ill_addr_reg != record3_RegAddr[i])
{
new_data = 1;
}
else
{
new_data = 0;
break;
}
}
if(new_data)
{
record3_RegAddr[ex_addr_count] = ill_addr_reg;
ex_addr_count++;
}
}
else
{
record3_RegAddr[ex_addr_count] = ill_addr_reg;
ex_addr_count++;
}
}
}
//different ill_info
if(record2[test_round][4] != ill_info_reg)
{
if(ex_info_count< 1000)
{
if(ex_info_count)
{
for(i=0;i<ex_info_count;i++)
{
if(ill_info_reg != record4_illInfo[i])
{
new_data = 1;
}
else
{
new_data = 0;
break;
}
}
if(new_data)
{
record4_illInfo[ex_info_count] = ill_info_reg;
ex_info_count++;
}
}
else
{
record4_illInfo[ex_info_count] = ill_info_reg;
ex_info_count++;
}
}
}
return 1;
}
int dram_access_detect(void)
{
unsigned long ill_info_reg;
unsigned long ill_addr_reg;
ill_info_reg = VPint(0xbfa00030);
if (ill_info_reg & (1<<31)){
ill_addr_reg = VPint(0xbfa0002c);
if (ill_info_reg & (1<<30)){
MP_DBG(DBG_L4, "Invalid dram write interrupt!!\n");
} else {
MP_DBG(DBG_L4, "Invalid dram read interrupt!!\n");
}
MP_DBG(DBG_L4, "Access invalid dram address %X\n", ill_addr_reg);
MP_DBG(DBG_L4, "ill info register value: %X\n", ill_info_reg);
if (record2[test_round][0]==0)
{
record2[test_round][0] = 1;
record2[test_round][5] = ill_addr_reg;
record2[test_round][4] = ill_info_reg;
}
else
{
illinfo_record(ill_info_reg,ill_addr_reg);
}
if (ill_info_reg & (1<<24)){
record2[test_round][2] = 1;
} else {
record2[test_round][3] = 1;
}
VPint(0xbfa00030) = (1<<31);
return 1;
} else {
return 0;
}
}
void RbusIsr(int irq, void *dev_id, struct pt_regs *regs)
{
MP_DBG(DBG_L1, "Rbus Isr\n");
dram_access_detect();
}
#if defined(TCSUPPORT_CPU_EN7521)
int do_mem_protect_dbgLevel(int argc, char *argv[])
{
mp_dbg_level = strtoul((const char*)(argv[1]), (char **)NULL, 16);
prom_printf("memory protection debug level: 0x%x\n", mp_dbg_level);
return 0;
}
int do_nmi_test_enable(int argc, char *argv[])
{
nmi_test_enable = strtoul((const char*)(argv[1]), (char **)NULL, 16);
prom_printf("nmi_test_enable: %d\n", nmi_test_enable);
return 0;
}
#endif
static int do_rbus_init(int argc, char *argv[])
{
prom_printf("rbus init\n");
request_IRQ(RBUS_INT, &rbus_irq, NULL);
VPint(CR_INTC_IMR) |= (0x01 << RBUS_INT);
return 0;
}
int do_dram_protect_size(int argc, char* argv[])
{
unsigned long size;
size = strtoul((const char*)(argv[1]), (char **)NULL, 16);
prom_printf("Dram physical size : 0x0 ~ 0x%x\n", (size-1));
VPint(0xbfa00034) = (size - 1);
return 0;
}
int do_dram_protect_test1(int argc, char* argv[])
{
dramTest_info_t info;
unsigned long startAddr, phy_endAddr, vir_endAddr, randAddr, randSize, addrMask, maxSize;
unsigned long dramSize, counter, isUnCache, dmaEn, i;
counter = strtoul((const char*)(argv[1]), (char **)NULL, 16);
isUnCache = strtoul((const char*)(argv[2]), (char **)NULL, 16);
dmaEn = strtoul((const char*)(argv[3]), (char **)NULL, 16);
if (isUnCache)
isUnCache = 1;
if (dmaEn)
dmaEn = 1;
/* dram end addresss - dram start address + 1 */
phy_endAddr = (VPint(0xbfa00034));
dramSize = phy_endAddr - 0 + 1;
MP_DBG(DBG_L1, "Dram protect test case 1\n");
MP_DBG(DBG_L1, "Test physical address between 0x20000 ~ 0x%x\n", (dramSize - 1));
MP_DBG(DBG_L1, "Test virtual address between 0x%x ~ 0x%x\n", segAddr[isUnCache][1],
(segAddr[isUnCache][1] + dramSize - 0x20001));
MP_DBG(DBG_L1, "Memory Read/Write Test by %s\n", (dmaEn == 1) ? "GDMA" : "CPU");
MP_DBG(DBG_L1, "Test total round: %x\n", counter);
MP_DBG(DBG_L1, "========================================================================\n");
addrMask = (dramSize - 1);
MP_DBG(DBG_L1, "addrMask: %x\n", addrMask);
for (i=0; i<counter; i++){
randSize = ( (random_word()) & addrMask );
if (randSize > (dramSize - 4)){
randSize = dramSize - 4;
}
randSize -= (randSize % 4);
#if defined(TCSUPPORT_CPU_EN7521)
if (isEN7526c)
{
/* FPFA's DRAM is 128M and only its 64M is initialized as Memory use(by HW TRAP). In order not
* to be affected during tests, test code operates on 64M ~ 128M */
if (dmaEn) /* GDMA will use DRAMTESTOFFSET0 & 1 to move data, so don't operate on these areas */
info.startAddr = 0x4070000 + ((random_word()) % (dramSize-0x4070000));
else
info.startAddr = 0x4000000 + ((random_word()) % (dramSize-0x4000000));
info.startAddr += segAddr[isUnCache][0];
info.startAddr -= (info.startAddr % 4);
maxSize = 0xffff;
}
#else
/*Since 0x0~0x20000 is for bootloader, so startAddr starts from 0x20000*/
if (randSize > 0x20000){
info.startAddr = segAddr[isUnCache][0] + randSize;
} else {
info.startAddr = segAddr[isUnCache][1];
}
maxSize = 0x1000;
#endif
// random select test size
info.size = ((random_word()) % maxSize);
if (info.size == 0){
info.size = maxSize;
}
if ((info.size + info.startAddr) > (segAddr[isUnCache][0] + dramSize)){
info.size = (segAddr[isUnCache][0] + dramSize - info.startAddr);
}
/* 4 byte alignment */
info.size -= (info.size % 4);
MP_DBG(DBG_L1, "Test round: %x\n", i);
MP_DBG(DBG_L1, "Dram start address: %x\n", info.startAddr);
MP_DBG(DBG_L1, "Dram test size: %x\n", info.size);
info.wByte = 0;
if (dmaEn){
dramTest2(&info, 0);
} else {
if (dramTest(&info, 0))
prom_printf("\nRound %d FAIL !\n", i);
}
}
prom_printf("\n%d Test Rounds finished !\n", counter);
return 0;
}
int do_dram_protect_test2(int argc, char* argv[])
{
dramTest_info_t info;
unsigned long startAddr, phy_endAddr, vir_endAddr, randAddr, randSize, addrMask, minSize, randSize_2;
unsigned long dramSize, counter, isUnCache, dmaEn, i;
counter = strtoul((const char*)(argv[1]), (char **)NULL, 16);
isUnCache = strtoul((const char*)(argv[2]), (char **)NULL, 16);
dmaEn = strtoul((const char*)(argv[3]), (char **)NULL, 16);
if (isUnCache)
isUnCache = 1;
if (dmaEn)
dmaEn = 1;
/* dram end addresss - dram start address + 1 */
phy_endAddr = (VPint(0xbfa00034));
dramSize = phy_endAddr - 0 + 1;
MP_DBG(DBG_L1, "Dram protect test case 2\n");
MP_DBG(DBG_L1, "Test physical start address between 0x20000 ~ 0x%x\n", (dramSize - 1));
MP_DBG(DBG_L1, "Test physical end address over 0x%x\n", (dramSize - 1));
MP_DBG(DBG_L1, "Test virtual start address between 0x%x ~ 0x%x\n", segAddr[isUnCache][1],
(segAddr[isUnCache][1] + dramSize - 0x20001));
MP_DBG(DBG_L1, "Test virtual end address over 0x%x\n", (segAddr[isUnCache][1] + dramSize - 0x20001));
MP_DBG(DBG_L1, "Test total round: %x\n", counter);
MP_DBG(DBG_L1, "========================================================================\n");
addrMask = (dramSize - 1);
MP_DBG(DBG_L1, "addrMask: %x\n", addrMask);
for (i=0; i<counter; i++){
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
info.startAddr = (segAddr[isUnCache][0] + dramSize - 0xf000);
/* GDMA lenth has only 16 bites, so randSize or randSize_2 can't exceed 0xffff */
randSize = ((random_word()) & 0xf ) +1 +0xf000; /* 1~16 Byte for cpu uncached access*/
randSize_2 = ((random_word()) & 0xff ) +1 +0xf000; /* 1~256 Byte for gdma access*/
}
#else
startAddr = (segAddr[isUnCache][0] + dramSize - 0x10000);
randSize = ( (random_word()) & 0xfff ) + 4;
randSize -= (randSize % 4);
info.startAddr = startAddr + randSize;
minSize = 0x10000 - randSize;
randSize = minSize + ((random_word()) % 0x1000) + 4;
/* 4 byte alignment */
randSize -= (randSize % 4);
#endif
info.size = randSize;
info.wByte = 0;
MP_DBG(DBG_L1, "Test round: %x\n", i);
MP_DBG(DBG_L1, "Dram start address: %x\n", info.startAddr);
if (dmaEn){
if (info.size >= 0x10000){
info.size = 0xfffc;
}
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
info.size = randSize_2;
}
#endif
MP_DBG(DBG_L1, "Dram test size: %x\n", info.size);
dramTest2(&info, 0);
} else {
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
info.size = randSize;
}
#endif
MP_DBG(DBG_L1, "Dram test size: %x\n", info.size);
dramTest(&info, 0);
}
}
return 0;
}
int do_dram_protect_test3(int argc, char* argv[])
{
dramTest_info_t info;
unsigned long startAddr, phy_endAddr, vir_endAddr, randAddr, randSize, addrMask, maxSize;
unsigned long dramSize, counter, isUnCache, i;
counter = strtoul((const char*)(argv[1]), (char **)NULL, 16);
isUnCache = strtoul((const char*)(argv[2]), (char **)NULL, 16);
if (isUnCache)
isUnCache = 1;
/* dram end addresss - dram start address + 1 */
phy_endAddr = (VPint(0xbfa00034));
dramSize = phy_endAddr - 0 + 1;
prom_printf("Dram protect test case 3\n");
prom_printf("Test invalid physical start address\n");
prom_printf("Test physical end address between 0x0 ~ 0x%x\n", (dramSize - 1 - 0x40000));
prom_printf("Test invalid virtual start address between 0x%x ~ 0x%x\n", segAddr[isUnCache][0] - 0x20000,
segAddr[isUnCache][0] );
prom_printf("Test virtual address between 0x%x ~ 0x%x\n", segAddr[isUnCache][0] - 0x20000,
(segAddr[isUnCache][0] + dramSize - 0x40001));
prom_printf("Test total round: %x\n", counter);
prom_printf("========================================================================\n");
addrMask = (dramSize - 1);
prom_printf("addrMask: %x\n", addrMask);
for (i=0; i<counter; i++){
randSize = ( (random_word()) & 0x1ffff );
randSize -= (randSize % 4);
prom_printf("randSize1 %x\n", randSize);
startAddr = segAddr[isUnCache][0] - 0x20000 + randSize;
prom_printf("startAddr1 %x\n", startAddr);
#if 1
randSize = (0x20000 - randSize) + ((random_word()) & 0xfff);
/* 4 byte alignment */
randSize -= (randSize % 4);
#endif
prom_printf("randSize1 %x\n", randSize);
prom_printf("Test round: %x\n", i);
prom_printf("Dram start address: %x\n", startAddr);
prom_printf("Dram test size: %x\n", randSize);
info.startAddr = startAddr;
info.size = randSize;
info.wByte = 0;
dramTest(&info, 0);
}
return 0;
}
int do_dram_protect_test4(int argc, char* argv[])
{
dramTest_info_t info;
unsigned long startAddr, phy_endAddr, vir_endAddr, randAddr, randSize, addrMask, maxSize;
unsigned long dramSize, counter, isUnCache, dmaEn, i;
counter = strtoul((const char*)(argv[1]), (char **)NULL, 16);
isUnCache = strtoul((const char*)(argv[2]), (char **)NULL, 16);
dmaEn = strtoul((const char*)(argv[3]), (char **)NULL, 16);
if (isUnCache)
isUnCache = 1;
if (dmaEn)
dmaEn = 1;
/* dram end addresss - dram start address + 1 */
phy_endAddr = (VPint(0xbfa00034));
dramSize = phy_endAddr - 0 + 1;
prom_printf("Dram protect test case 4\n");
prom_printf("Test physical start address between 0x20000 ~ 0x%x\n", (dramSize - 1));
prom_printf("Test physical end address over 0x%x\n", (dramSize - 1));
prom_printf("Test virtual start address between 0x%x ~ 0x%x\n", segAddr[isUnCache][1],
(segAddr[isUnCache][1] + dramSize - 0x20001));
prom_printf("Test virtual end address over 0x%x\n", (segAddr[isUnCache][1] + dramSize - 0x20001));
prom_printf("Test total round: %x\n", counter);
prom_printf("========================================================================\n");
addrMask = (dramSize - 1);
prom_printf("addrMask: %x\n", addrMask);
randSize = ( (random_word()) & addrMask );
randSize -= (randSize % 4);
if (randSize > (dramSize - 4)){
randSize = dramSize - 4;
}
for (i=0; i<counter; i++){
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
info.startAddr = segAddr[isUnCache][0] + dramSize + ((random_word()) & addrMask );
info.startAddr -= (info.startAddr % 4);
if (dmaEn)
info.size = ((random_word()) & 0xff) + 1;
else
info.size = ((random_word()) & 0xf) + 1;
info.size -= (info.size % 4);
}
#else
info.startAddr = segAddr[isUnCache][0] + dramSize + randSize;
info.size = ( (random_word()) & 0xff ) + 4;
#endif
info.size -= (info.size % 4);
if (info.size == 0)
info.size = 4;
info.wByte = 0;
prom_printf("Test round: %x\n", i);
prom_printf("Dram start address: %x\n", info.startAddr);
prom_printf("Dram test size: %x\n", info.size);
if (dmaEn){
dramTest2(&info, 0);
} else {
dramTest(&info, 0);
}
}
return 0;
}
static int do_seg_write_protect(int argc, char *argv[])
{
unsigned long enable;
enable = strtoul((const char*)(argv[1]), (char **)NULL, 16);
if (enable)
enable = 1;
prom_printf("Segmentation write protect: %s\n", (enable==1) ? "enable" : "disable");
if (enable){
VPint(0xbfa00018) |= ((1<<1) | (1<<3));
} else {
VPint(0xbfa00018) &= (~((1<<1) | (1<<3)));
}
return 0;
}
static int do_seg_read_protect(int argc, char *argv[])
{
unsigned long enable;
enable = strtoul((const char*)(argv[1]), (char **)NULL, 16);
if (enable)
enable = 1;
prom_printf("Segmentation read protect: %s\n", (enable==1) ? "enable" : "disable");
if (enable){
VPint(0xbfa00018) |= ((1<<2) | (1<<4));
} else {
VPint(0xbfa00018) &= (~((1<<2) | (1<<4)));
}
return 0;
}
static int do_seg_addr_set(int argc, char *argv[])
{
unsigned long seg, startAddr, endAddr;
seg = strtoul((const char*)(argv[1]), (char **)NULL, 16);
startAddr = strtoul((const char*)(argv[2]), (char **)NULL, 16);
endAddr = strtoul((const char*)(argv[3]), (char **)NULL, 16);
if (seg)
seg = 1;
prom_printf("Segmentation%s: \n", (seg==1) ? "2" : "1");
prom_printf("Start address:%x\n", startAddr);
prom_printf("End address:%x\n", endAddr);
if (seg){
VPint(0xbfa00024) = startAddr;
VPint(0xbfa00028) = endAddr;
} else {
VPint(0xbfa0001c) = startAddr;
VPint(0xbfa00020) = endAddr;
}
}
static int do_seg_protect_test(int argc, char *argv[])
{
dramTest_info_t info;
unsigned long phy_endAddr, randAddr, randSize, addrMask, segStart, segEnd;
unsigned long dramSize, counter, isUnCache, dmaEn, seg, i;
unsigned long startAddr, testCase;
unsigned long segStartMin;
counter = strtoul((const char*)(argv[1]), (char **)NULL, 16);
seg = strtoul((const char*)(argv[2]), (char **)NULL, 16);
isUnCache = strtoul((const char*)(argv[3]), (char **)NULL, 16);
dmaEn = strtoul((const char*)(argv[4]), (char **)NULL, 16);
testCase = strtoul((const char*)(argv[5]), (char **)NULL, 16);
if (seg)
seg = 1;
if (isUnCache)
isUnCache = 1;
if (dmaEn)
dmaEn = 1;
phy_endAddr = (VPint(0xbfa00034));
dramSize = phy_endAddr - 0 + 1;
MP_DBG(DBG_L1, "Segmentation protect test case 1\n");
MP_DBG(DBG_L1, "Valid physical address: 0x0 ~ 0x%x\n", (dramSize - 1));
MP_DBG(DBG_L1, "Test Segmentation%s\n", (seg==1) ? "2" : "1");
if (seg){
segStart = VPint(0xbfa00024);
segEnd = VPint(0xbfa00028);
} else {
segStart = VPint(0xbfa0001c);
segEnd = VPint(0xbfa00020);
}
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
if (VPint(0xbfa00024) > VPint(0xbfa0001c))
segStartMin = VPint(0xbfa0001c);
else
segStartMin = VPint(0xbfa00024);
}
#endif
if (segStart < 4){
prom_printf("segStart address is too small to test\n");
return -1;
}
if (segEnd > (dramSize - 4)){
prom_printf("segEnd address is too large to test\n");
return -1;
}
MP_DBG(DBG_L1, "Segmentation Start Addr: %x, End Addr: %x\n", segStart, segEnd);
MP_DBG(DBG_L1, "Test total round: %x\n", counter);
MP_DBG(DBG_L1, "========================================================================\n");
addrMask = (dramSize - 1);
MP_DBG(DBG_L1, "addrMask: %x\n", addrMask);
for (i=0; i<counter; i++){
switch(testCase)
{
case 0:
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
/* FPFA's DRAM is 128M and only its 64M is initialized as Memory use(by HW TRAP).
* In order not to be affected during tests, test code operates above 64M */
if (dmaEn) /* DRAMTESTOFFSET0 & 1 areas will be used to move data during GDMA tests, so don't operate on these areas */
startAddr = (random_word() % (segStartMin-((DRAMTESTOFFSET1+0x1000)&0xfffffff))) + (DRAMTESTOFFSET1+0x1000);
else
startAddr = (random_word() % (segStartMin-0x4000000)) + 0x4000000;
if (startAddr >= (segStartMin-8))
startAddr = (segStartMin-8);
/* CPU word access needs to be word alignment */
startAddr -= (startAddr%4);
info.size = ((random_word()) & 0xfff);
if (info.size < 4)
info.size = 4;
if (startAddr + info.size >= segStartMin)
info.size = segStartMin - startAddr - 4;
}
#else
startAddr = segStart - (random_word() & 0xfff);
startAddr -= (startAddr%4);
startAddr = (startAddr<0) ? 0 : startAddr;
info.size = ((random_word() % (segStart - startAddr)) & 0xfff);
#endif
break;
case 1:
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
startAddr = (segStart - 0xf000);
if (dmaEn)
info.size = ((random_word()) & 0xff ) +1 +0xf000; /* 1~256 Byte for gdma access*/
else
info.size = ((random_word()) & 0xf ) +1 +0xf000; /* 1~16 Byte for cpu uncached access*/
info.size -= (info.size % 4);
if (startAddr + info.size <= segStart)
info.size += segStart - (startAddr + info.size) + 4;
}
#else
startAddr = segStart - ((random_word()) & 0xfff);
startAddr -= (startAddr%4);
startAddr = (startAddr<0) ? 0 : startAddr;
info.size = (segStart - startAddr) + (random_word() & 0xfff);
#endif
break;
case 2:
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
startAddr = (random_word() % (segEnd-segStart)) + segStart;
startAddr -= (startAddr%4);
if (dmaEn)
info.size = ((random_word()) & 0xff ) +1; /* 1~256 Byte for cpu uncached access*/
else
info.size = ((random_word()) & 0xf ) +1; /* 1~16 Byte for cpu uncached access*/
info.size -= (info.size%4);
if (startAddr + info.size >= segEnd)
info.size -= (startAddr + info.size) - segEnd + 4;
if (info.size == 0)
info.size = 4;
}
#else
startAddr = segStart - ((random_word()) & 0xfff);
startAddr -= (startAddr%4);
startAddr = (startAddr<0) ? 0 : startAddr;
info.size = (segEnd - startAddr) + (random_word() & 0xfff);
#endif
break;
case 3:
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
if (dmaEn)
startAddr = segEnd - (((random_word()) & 0xff ) +1);
else
startAddr = segEnd - (((random_word()) & 0xf ) +1);
startAddr -= (startAddr%4);
info.size = (segEnd - startAddr) + (random_word() & 0xfff);
if (startAddr+info.size <= segEnd)
info.size += segEnd - (startAddr+info.size)+4;
}
#else
startAddr = segStart + ((random_word()) % (segEnd - segStart));
startAddr -= (startAddr%4);
startAddr = (startAddr<0) ? 0 : startAddr;
info.size = (segEnd - startAddr) + (random_word() & 0xfff);
#endif
break;
case 4:
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
if (dmaEn) {
startAddr = segStart - (segStart % 0x10);
info.size = (segEnd-startAddr) + ((random_word())& 0xff) + 4;
}
else {
startAddr = segStart - (segStart%4);
info.size = (segEnd-startAddr) + ((random_word())& 0xf) + 4;
info.size += (info.size%4);
}
}
#else
startAddr = segStart + (random_word() % (segEnd - segStart));
startAddr -= (startAddr%4);
startAddr = (startAddr<0) ? 0 : startAddr;
info.size = ((random_word()%(segEnd - startAddr)) & 0xfff);
#endif
break;
default:
break;
}
info.startAddr = segAddr[isUnCache][0] + startAddr;
info.size -= (info.size%4);
info.wByte = 0;
MP_DBG(DBG_L1, "Test round: %x\n", i);
MP_DBG(DBG_L1, "Dram start address: %x\n", info.startAddr);
MP_DBG(DBG_L1, "Dram test size: %x\n", info.size);
if (dmaEn){
dramTest2(&info, 0);
} else {
dramTest(&info, 0);
}
}
prom_printf("\n%d Test Rounds finished !\n", counter);
return 0;
}
static int do_mem_protect_test(int argc, char *argv[])
{
dramTest_info_t info;
char flag = 0;
unsigned long phy_endAddr, randAddr, randSize, addrMask, segStart, segEnd;
unsigned long dramSize, counter, isUnCache, dmaEn, seg, i;
unsigned long startAddr, testCase;
unsigned long seg1Start, seg1End, seg2Start, seg2End, segStartMin;
counter = strtoul((const char*)(argv[1]), (char **)NULL, 10);
isUnCache = strtoul((const char*)(argv[2]), (char **)NULL, 16);
dmaEn = strtoul((const char*)(argv[3]), (char **)NULL, 16);
if (isUnCache)
isUnCache = 1;
if (dmaEn)
dmaEn = 1;
phy_endAddr = (VPint(0xbfa00034));
dramSize = phy_endAddr - 0 + 1;
MP_DBG(DBG_L1, "Memory Protect Test\n");
MP_DBG(DBG_L1, "Valid physical address: 0x0 ~ 0x%x\n", (dramSize - 1));
addrMask = (dramSize - 1);
MP_DBG(DBG_L1, "addrMask: %x\n", addrMask);
seg1Start = (VPint(0xbfa0001c));
seg1End = (VPint(0xbfa00020));
seg2Start = (VPint(0xbfa00024));
seg2End = (VPint(0xbfa00028));
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
if (seg1Start > seg2Start)
segStartMin = seg2Start;
else
segStartMin = seg1Start;
}
#endif
for (test_round=0; test_round<counter; test_round++){
for (i=0; i<6; i++){
record1[test_round][i] = 0;
record2[test_round][i] = 0;
}
}
for (test_round=0; test_round<counter; test_round++){
#if defined(TCSUPPORT_CPU_EN7521)
if(isEN7526c)
{
startAddr = 0x60000 + (random_word() % (dramSize-0x60000+0x800000));
startAddr -= (startAddr%4);
info.startAddr = segAddr[isUnCache][0] + startAddr;
if (dmaEn){
info.size = (random_word() & 0xff)+1;
}
else{
info.size = (random_word() & 0xf)+1;
}
}
#else
startAddr = (random_word() & addrMask);
startAddr -= (startAddr%4);
if (startAddr > (dramSize - 0xff))
startAddr -= 0x100;
if (startAddr < 0x40000)
startAddr += 0x40000;
info.startAddr = segAddr[isUnCache][1] + startAddr;
info.size = (random_word() & 0xff);
startAddr += 0x20000
#endif
info.size -= (info.size % 4);
if(!info.size)
info.size = 0x4;
info.wByte = 0;
MP_DBG(DBG_L1, "Test round: %d\n", test_round);
MP_DBG(DBG_L1, "Dram start address: %x\n", info.startAddr);
MP_DBG(DBG_L1, "Dram test size: %x\n", info.size);
record1[test_round][0] = startAddr;
record1[test_round][1] = info.size;
if ((startAddr + info.size) > phy_endAddr)
record1[test_round][2] = 1;
if ((startAddr>=seg1Start) && (startAddr<=seg1End))
record1[test_round][3] = 1;
if (((startAddr+info.size)>=seg1Start) && ((startAddr+info.size)<=seg1End))
record1[test_round][3] = 1;
if ((startAddr>=seg2Start) && (startAddr<=seg2End))
record1[test_round][3] = 1;
if (((startAddr+info.size)>=seg2Start) && ((startAddr+info.size)<=seg2End))
record1[test_round][3] = 1;
if (dmaEn){
dramTest2(&info, 0);
} else {
dramTest(&info, 0);
}
}
MP_DBG(DBG_L3, "seg1: %x ~ %x\n", seg1Start, seg1End);
MP_DBG(DBG_L3, "seg2: %x ~ %x\n", seg2Start, seg2End);
MP_DBG(DBG_L3, "Dram Size: %x\n\n", phy_endAddr);
for (i=0; i<counter; i++){
MP_DBG(DBG_L3, "test round: %d\n", i);
MP_DBG(DBG_L3, "test startAddr : %x\n", record1[i][0]);
MP_DBG(DBG_L3, "test size : %x\n", record1[i][1]);
MP_DBG(DBG_L3, "expected result: overdram-> %d seg_err-> %d\n", record1[i][2], record1[i][3]);
MP_DBG(DBG_L3, "testing result: overdram-> %d seg_err-> %d\n", record2[i][2], record2[i][3]);
if (record2[i][2] || record2[i][3]){
MP_DBG(DBG_L3, "invalid address : %x\n", record2[i][5]);
MP_DBG(DBG_L3, "invalid info : %x\n", record2[i][4]);
}
if ((record1[i][2] != record2[i][2]) || (record1[i][3] != record2[i][3])) {
flag = 1;
MP_DBG(DBG_L3, "test round:%d Fail\n\n", i);
}
else
MP_DBG(DBG_L3, "test round:%d Pass\n\n", i);
}
if (flag){
prom_printf("Memory Test Fail\n");
} else {
prom_printf("Memory Test Success\n");
}
return 0;
}
#if defined(TCSUPPORT_CPU_EN7521)
static int do_mem_protect_test2(int argc, char *argv[])
{
dramTest_info_t info;
char flag = 0;
unsigned long phy_endAddr, randAddr, randSize, addrMask, segStart, segEnd;
unsigned long dramSize, counter, isUnCache, dmaEn, seg, i, operation;
unsigned long startAddr, testCase;
unsigned long seg1Start, seg1End, seg2Start, seg2End, segStartMin;
long point_offset, testLen;
counter = strtoul((const char*)(argv[1]), (char **)NULL, 10);
isUnCache = strtoul((const char*)(argv[2]), (char **)NULL, 16);
dmaEn = strtoul((const char*)(argv[3]), (char **)NULL, 16);
operation= strtoul((const char*)(argv[4]), (char **)NULL, 10);
point_offset = strtoul((const char*)(argv[5]), (char **)NULL, 10);
testLen= strtoul((const char*)(argv[6]), (char **)NULL, 10);
if (isUnCache)
isUnCache = 1;
if (dmaEn)
dmaEn = 1;
dmaEn = 0; /*only test CPU access DRAM*/
/*record1 array maximum number is 1000.*/
if(counter > 1000)
{
counter = 1000;
}
phy_endAddr = (VPint(0xbfa00034));
dramSize = phy_endAddr - 0 + 1;
MP_DBG(DBG_L1, "Memory Protect Test\n");
MP_DBG(DBG_L1, "Valid physical address: 0x0 ~ 0x%x\n", (dramSize - 1));
addrMask = (dramSize - 1);
MP_DBG(DBG_L1, "addrMask: %x\n", addrMask);
seg1Start = (VPint(0xbfa0001c));
seg1End = (VPint(0xbfa00020));
seg2Start = (VPint(0xbfa00024));
seg2End = (VPint(0xbfa00028));
if(isEN7526c)
{
if (seg1Start > seg2Start)
segStartMin = seg2Start;
else
segStartMin = seg1Start;
}
for (test_round=0; test_round<counter; test_round++){
for (i=0; i<6; i++){
record1[test_round][i] = 0;
record2[test_round][i] = 0;
}
}
memset(record3_RegAddr,0,1000);
memset(record4_illInfo,0,1000);
ex_addr_count = 0;
ex_info_count = 0 ;
for (test_round=0; test_round<counter; test_round++)
{
if(isEN7526c)
{
if(operation)
{
startAddr = segStartMin - point_offset;
}
else
{
startAddr = segStartMin + point_offset;
}
/* assigned start address to non-alignment */
if(startAddr % 8 == 0)
{
startAddr = startAddr - 1;
}
info.startAddr = startAddr + segAddr[isUnCache][0];
if (dmaEn){
info.size = (random_word() & 0xff)+1;
}
else{
info.size = testLen;
}
}
if(!info.size)
info.size = 0x4;
info.wByte = 0;
MP_DBG(DBG_L1, "Test round: %d\n", test_round);
MP_DBG(DBG_L1, "Dram start address: %x\n", info.startAddr);
MP_DBG(DBG_L1, "Dram test size: %x\n", info.size);
record1[test_round][0] = startAddr;
record1[test_round][1] = info.size;
if ((startAddr + info.size) > phy_endAddr)
record1[test_round][2] = 1;
if ((startAddr>=seg1Start) && (startAddr<=seg1End))
record1[test_round][3] = 1;
if (((startAddr+info.size)>=seg1Start) && ((startAddr+info.size)<=seg1End))
record1[test_round][3] = 1;
/*cross the segment memory*/
if ((startAddr<seg1Start) && ((startAddr+info.size)>=seg1Start))
record1[test_round][3] = 1;
if ((startAddr>=seg2Start) && (startAddr<=seg2End))
record1[test_round][3] = 1;
if (((startAddr+info.size)>=seg2Start) && ((startAddr+info.size)<=seg2End))
record1[test_round][3] = 1;
/*cross the segment memory*/
if ((startAddr<seg2Start) && ((startAddr+info.size)>=seg2Start))
record1[test_round][3] = 1;
if (dmaEn){
dramTest2(&info, 0);
} else {
dram_Nonalignment_Test(&info, 0);
}
}
MP_DBG(DBG_L3, "seg1: %x ~ %x\n", seg1Start, seg1End);
MP_DBG(DBG_L3, "seg2: %x ~ %x\n", seg2Start, seg2End);
MP_DBG(DBG_L3, "Dram Size: %x\n\n", phy_endAddr);
for (i=0; i<counter; i++)
{
if((record1[i][2] != record2[i][2] )
||(record1[i][3] != record2[i][3])
)
{
MP_DBG(DBG_L3, "test round: %d\n", i);
MP_DBG(DBG_L3, "test startAddr/endAddr : 0x%x/0x%x\n", record1[i][0],(record1[i][0] + record1[i][1] - 1));
MP_DBG(DBG_L3, "test size : 0x%x\n", record1[i][1]);
MP_DBG(DBG_L3, "expected result: overdram-> %d seg_err-> %d\n", record1[i][2], record1[i][3]);
MP_DBG(DBG_L3, "testing result: overdram-> %d seg_err-> %d\n", record2[i][2], record2[i][3]);
if (record2[i][2] || record2[i][3])
{
MP_DBG(DBG_L3, "invalid address : 0x%x\n", record2[i][5]);
MP_DBG(DBG_L3, "invalid info : 0x%x\n", record2[i][4]);
}
flag = 1;
MP_DBG(DBG_L3, "test round:%d Fail\n\n", i);
}
}
if (flag)
{
prom_printf("Memory Test Fail\n");
} else {
prom_printf("Memory Test Success\n");
}
/*Print more infomation*/
MP_DBG(DBG_L3, "Count : %d\n", counter);
for (i=0; i<counter; i++)
{
if((record1[i][2]== record2[i][2] )
||(record1[i][3]== record2[i][3])
)
{
MP_DBG(DBG_L3, "test startAddr/endAddr : 0x%x/0x%x\n", record1[i][0],(record1[i][0] + record1[i][1] - 1));
MP_DBG(DBG_L3, "test size : 0x%x\n", record1[i][1]);
MP_DBG(DBG_L3, "expected result: overdram-> %d seg_err-> %d\n", record1[i][2], record1[i][3]);
MP_DBG(DBG_L3, "testing result: overdram-> %d seg_err-> %d\n", record2[i][2], record2[i][3]);
if (record2[i][2] || record2[i][3])
{
MP_DBG(DBG_L3, "invalid address : 0x%x\n", record2[i][5]);
MP_DBG(DBG_L3, "invalid info : 0x%x\n", record2[i][4]);
}
break;
}
}
/*illegal address different*/
if(ex_addr_count)
{
MP_DBG(DBG_L3, "more invalid address : ");
for (i=0; i<ex_addr_count; i++)
{
MP_DBG(DBG_L3, "0x%x, ", record3_RegAddr[i]);
}
MP_DBG(DBG_L3, "\n");
}
//illegal info different
if(ex_info_count)
{
MP_DBG(DBG_L3, "more invalid info : ");
for (i=0; i<ex_info_count; i++)
{
MP_DBG(DBG_L3, "0x%x, ", record4_illInfo[i]);
}
MP_DBG(DBG_L3, "\n");
}
return 0;
}
#endif
#if defined(TCSUPPORT_CPU_EN7521)
int nmi_mem_protect_test(void)
{
dramTest_info_t info;
char flag = 0;
unsigned long phy_endAddr, randAddr, randSize, addrMask, segStart, segEnd;
unsigned long dramSize, counter, isUnCache, dmaEn, seg, i;
unsigned long startAddr, testCase;
unsigned long seg1Start, seg1End, seg2Start, seg2End;
if (nmi_test_enable == 0)
return 0;
phy_endAddr = (VPint(0xbfa00034));
dramSize = phy_endAddr - 0 + 1;
MP_DBG(DBG_L1, "Memory Protect Test\n");
MP_DBG(DBG_L1, "Valid physical address: 0x0 ~ 0x%x\n", (dramSize - 1));
addrMask = (dramSize - 1);
MP_DBG(DBG_L1, "addrMask: %x\n", addrMask);
seg1Start = (VPint(0xbfa0001c));
seg1End = (VPint(0xbfa00020));
seg2Start = (VPint(0xbfa00024));
seg2End = (VPint(0xbfa00028));
MP_DBG(DBG_L1, "seg1: %x ~ %x\n", seg1Start, seg1End);
MP_DBG(DBG_L1, "seg2: %x ~ %x\n", seg2Start, seg2End);
MP_DBG(DBG_L1, "Dram Size: %x\n\n", phy_endAddr);
/* case0: 0x60000~seg1Start, case1: seg1Start~seg1End, case2: seg1End~seg2Start,
* case3: seg2Start~seg2End, case4: seg2End~dramSize, case5: dramSize~+0xff */
for (testCase=0; testCase<6; testCase++){
switch (testCase) {
case 0:
startAddr = 0x60000 + (random_word() % (seg1Start-0x60000));
break;
case 1:
startAddr = seg1Start + (random_word() % (seg1End-seg1Start-0xf));
break;
case 2:
startAddr = seg1End + (random_word() % (seg2Start-seg1End-0xf));
break;
case 3:
startAddr = seg2Start + (random_word() % (seg2End-seg2Start-0xf));
break;
case 4:
startAddr = seg2End + (random_word() % (dramSize-seg2End-0xf));
break;
case 5:
startAddr += dramSize+(random_word() % 0x800000)+4;
break;
default:
break;
}
startAddr -= (startAddr%4);
info.startAddr = segAddr[1][0] + startAddr;
info.size = (random_word() & 0xf);
info.size -= (info.size % 4);
if(!info.size)
info.size = 0x4;
info.wByte = 0;
MP_DBG(DBG_L1, "Test case: %d\n", testCase);
MP_DBG(DBG_L1, "Dram start address: %x\n", info.startAddr);
MP_DBG(DBG_L1, "Dram test size: %x\n", info.size);
dramTest(&info, 0);
}
nmi_test_enable = 0;
return 0;
}
#endif
/**************** memory access range protection *****************/
#endif
/****************** spi dram range protection ********************/
#endif
#if defined(RBUS_COUNTER_TEST)
rcnt_para rcnt_info[]=
{
{CPU2PBUS_WRCNT,CPU2PBUS_WRCNT_MIN,CPU2PBUS_WRCNT_MAX},
{CPU2PBUS_RDCNT,CPU2PBUS_RDCNT_MIN,CPU2PBUS_RDCNT_MAX},
{CPU2DRAM_WRCNT,CPU2DRAM_WRCNT_MIN,CPU2DRAM_WRCNT_MAX},
{CPU2DRAM_RDCNT,CPU2DRAM_RDCNT_MIN,CPU2DRAM_RDCNT_MAX},
{DMA2DRAM_WRCNT,DMA2DRAM_WRCNT_MIN,DMA2DRAM_WRCNT_MAX},
{DMA2DRAM_RDCNT,DMA2DRAM_RDCNT_MIN,DMA2DRAM_RDCNT_MAX},
{0, 0, 0}
};
auto_para auto_test_table[]=
{
#if 0//PCIe
{1, 0x1fb80000, 0x1fb81000, 0x500, 1025},
{1, 0x1fb80000, 0x1fb81004, 0x500, 1026},
{1, 0x1fb80000, 0x1fb81008, 0x500, 1027},
{1, 0x1fb80000, 0x1fb82000, 0x500, 1280},
{1, 0x1fb80000, 0x1fb84000, 0x500, 1280},
{2, 0x1fb80000, 0x1fb81000, 0x500, 1025},
{2, 0x1fb80000, 0x1fb81004, 0x500, 1026},
{2, 0x1fb80000, 0x1fb81008, 0x500, 1027},
{2, 0x1fb80000, 0x1fb82000, 0x500, 1280},
{2, 0x1fb80000, 0x1fb84000, 0x500, 1280},
#endif
#if 1//USB
{1, 0x1fba0000, 0x1fba1000, 0x500, 1025},
{1, 0x1fba0000, 0x1fba1004, 0x500, 1026},
{1, 0x1fba0000, 0x1fba1008, 0x500, 1027},
{1, 0x1fba0000, 0x1fba2000, 0x500, 1280},
{1, 0x1fba0000, 0x1fba4000, 0x500, 1280},
{2, 0x1fba0000, 0x1fba1000, 0x500, 1025},
{2, 0x1fba0000, 0x1fba1004, 0x500, 1026},
{2, 0x1fba0000, 0x1fba1008, 0x500, 1027},
{2, 0x1fba0000, 0x1fba2000, 0x500, 1280},
{2, 0x1fba0000, 0x1fba4000, 0x500, 1280},
#endif
#if 1//QDMA
{1, 0x1fb50000, 0x1fb51000, 0x500, 1025},
{1, 0x1fb50000, 0x1fb51004, 0x500, 1026},
{1, 0x1fb50000, 0x1fb51008, 0x500, 1027},
{1, 0x1fb50000, 0x1fb52000, 0x500, 1280},
{1, 0x1fb50000, 0x1fb54000, 0x500, 1280},
{2, 0x1fb50000, 0x1fb51000, 0x500, 1025},
{2, 0x1fb50000, 0x1fb51004, 0x500, 1026},
{2, 0x1fb50000, 0x1fb51008, 0x500, 1027},
{2, 0x1fb50000, 0x1fb52000, 0x500, 1280},
{2, 0x1fb50000, 0x1fb54000, 0x500, 1280},
#endif
////////////////////////////////////////////////////////////
{3, 0x20000, 0x21000, 0x1000, 1026},
{3, 0x20000, 0x22000, 0x1000, 2050},
{3, 0x20000, 0x22004, 0x1000, 2050},
{3, 0x20000, 0x22008, 0x1000, 2052},
{3, 0x20000, 0x24000, 0x1000, 4096},
{3, 0x20000, 0x24008, 0x1000, 4096},
{4, 0x20000, 0x21000, 0x1000, 1026},
{4, 0x20000, 0x22000, 0x1000, 2050},
{4, 0x20000, 0x22004, 0x1000, 2050},
{4, 0x20000, 0x22008, 0x1000, 2052},
{4, 0x20000, 0x24000, 0x1000, 4096},
{4, 0x20000, 0x24008, 0x1000, 4096},
////////////////////////////////////////////////////////////
{5, 0x20000, 0x21000, 0x64, 65},
{5, 0x20000, 0x21100, 0x64, 69},
{5, 0x20000, 0x21140, 0x64, 70},
{5, 0x20000, 0x2117f, 0x64, 70},
{5, 0x20000, 0x21180, 0x64, 71},
{5, 0x20000, 0x25000, 0x64, 100},
{6, 0x20000, 0x21000, 0x64, 65},
{6, 0x20000, 0x21100, 0x64, 69},
{6, 0x20000, 0x21140, 0x64, 70},
{6, 0x20000, 0x2117f, 0x64, 70},
{6, 0x20000, 0x21180, 0x64, 71},
{6, 0x20000, 0x25000, 0x64, 100},
{ 0, 0x0 , 0x0, 0x0, 0},
};
int gdmacopy(unsigned long addr1, unsigned long addr2, unsigned long len)
{
unsigned char ch, burst_size;
// ch = random_byte() & 0xf;
ch = 0xf;
if (isEN751221)
ch &= 0x7;
// burst_size = random_byte() & 0x7;
burst_size = 0x4;
if (len == 0)
len = 1;
// GDMA
VPint(CR_GDMA_SA(ch)) = (addr2 & 0x1fffffff);
VPint(CR_GDMA_DA(ch)) = (addr1 & 0x1fffffff);
VPint(CR_GDMA_CT1(ch)) = (32<<16) | (32<<8);
VPint(CR_GDMA_CT0(ch)) = ((len&0xffff)<<16) | (burst_size<<3) | (1<<1) | (1<<0);
while (!(VPint(CR_GDMA_DONEINT) & (1<<ch))) ;
VPint(CR_GDMA_DONEINT) = (1<<ch);
}
int Cfg_cnt_ctr(unsigned int type, unsigned int startAddr, unsigned int endAddr)
{
unsigned long tempvalue = 0;
tempvalue |= 1<<(type-1);
VPint(BUS_CNT_EN) = 0;
VPint(BUS_CNT_EN) = tempvalue;
VPint(rcnt_info[type-1].startAddr) = startAddr;
VPint(rcnt_info[type-1].endAddr) = endAddr;
prom_printf("\r\n(1)EN\t:0x%08x => 0x%08x", BUS_CNT_EN, VPint(BUS_CNT_EN));
prom_printf("\r\n(2)MIN\t:0x%08x => 0x%08x", rcnt_info[type-1].startAddr, VPint(rcnt_info[type-1].startAddr));
prom_printf("\r\n(3)MAX\t:0x%08x => 0x%08x", rcnt_info[type-1].endAddr, VPint(rcnt_info[type-1].endAddr));
return 0;
}
int Read_cnt_reg(unsigned int type)
{
prom_printf("\r\n(5)CNT\t:0x%08x => 0x%08x", rcnt_info[type-1].count, VPint(rcnt_info[type-1].count));
return VPint(rcnt_info[type-1].count);
}
int RCnt_func(unsigned int type, unsigned int startAddr, unsigned int endAddr, unsigned int len, int result)
{
unsigned char *ptrrw = NULL;
int i;
int count = 0;
unsigned long tempvalue;
prom_printf("\r\nStart Test!");
Cfg_cnt_ctr(type, startAddr, endAddr);
startAddr = startAddr | 0xa0000000;
ptrrw = startAddr;
prom_printf("\r\n(4)RED\t:0x%08x -> 0x%08x %x", startAddr, endAddr, len);
switch(type)
{
case 1://cpu2pbus write
for(i=0; i< len; i++)
{
*ptrrw = 0x005aa5ff;
ptrrw+=4;
}
count = Read_cnt_reg(type);
break;
case 2://cpu2pbus read
for(i=0; i< len; i++)
{
tempvalue = *(volatile unsigned long *)ptrrw;
ptrrw+=4;
}
count = Read_cnt_reg(type);
break;
case 3://cpu2dram write
for(i=0; i< len; i++)
{
*ptrrw = 0x005aa5ff;
ptrrw+=4;
}
count = Read_cnt_reg(type);
break;
case 4://cpu2dram read
for(i=0; i< len; i++)
{
tempvalue = *(volatile unsigned long *)ptrrw;
ptrrw+=4;
}
count = Read_cnt_reg(type);
break;
case 5://dma2dram write
for(i=0; i< len; i++)
{
gdmacopy(startAddr, 0xa0020000, 0x40);
startAddr+=0x40;
}
count = Read_cnt_reg(type);
break;
case 6://dma2dram read
for(i=0; i< len; i++)
{
gdmacopy(0xa0040000, startAddr, 0x40);
startAddr+=0x40;
}
count = Read_cnt_reg(type);
break;
default:
prom_printf("\r\nNot support this type!");
break;
}
if(count == result){
prom_printf("\r\nOK!\r\n");
return 0;
}
else{
prom_printf("\r\nXX %d VS %d!\r\n", count, result);
return 1;
}
}
static int do_rbus_counter(int argc, char *argv[])
{
unsigned int type, length;
unsigned long seg, startAddr, endAddr;
int i, auto_num, count, result;
auto_num = 0;
result = 0;
count = 0;
if(argc <2){
prom_printf("\r\nrbus_counter [all | <type> <MIN~MAX> <length> <count>]\r\n");
return 0;
}
if(strcmp(argv[1], "all") == 0){
auto_num = sizeof(auto_test_table)/sizeof(auto_para);
for(i = 0; i < auto_num-1; i++)
{
result = RCnt_func(auto_test_table[i].type, auto_test_table[i].startAddr,
auto_test_table[i].endAddr, auto_test_table[i].length, auto_test_table[i].count);
if(result != 0){
prom_printf("\r\nError %d, Try cmd: rbus_counter %d %x %x %x %d\r\n", i,
auto_test_table[i].type, auto_test_table[i].startAddr,
auto_test_table[i].endAddr, auto_test_table[i].length, auto_test_table[i].count);
return;
}
}
prom_printf("===========>Test All PASS\r\n");
}
else if(argc >= 6)
{
type = simple_strtoul(argv[1],NULL,16);
startAddr = strtoul((const char*)(argv[2]), (char **)NULL, 16);
endAddr = strtoul((const char*)(argv[3]), (char **)NULL, 16);
length = simple_strtoul(argv[4],NULL,16);
count = simple_strtoul(argv[5],NULL,16);
RCnt_func(type, startAddr, endAddr, length, count);
}
else
prom_printf("\r\nrbus_counter <type> <MIN~MAX> <length> <count>");
return 0;
}
#endif
#ifdef MT7550_GPIO_TEST//tony add
static int do_gpio_test(int argc, char *argv[])
{
uint8 regs = 0;
uint8 data1, data, num = 1;
uint8 valid, i;
if (argc>=3 && (strcmp(argv[1], "r") == 0))
{
regs = simple_strtoul(argv[2],NULL,16);
if (argc == 4)
num = simple_strtoul(argv[3],NULL,16);
for(i=0; i<num; i++)
{
valid = AfeMT7550ReadReg(regs+i, &data);
if(valid == 0)
{
prom_printf("\r\n7550 reg read not access!!");
}
if(((i % 8) == 0))
{
prom_printf("\r\nregs 0x%x: ", regs+i);
}
prom_printf("0x%x ", data);
}
prom_printf("\r\n");
}
else if (argc==4 && (strcmp(argv[1], "w") == 0))
{
regs = simple_strtoul(argv[2],NULL,16);
data = simple_strtoul(argv[3],NULL,16);
valid = AfeMT7550WriteReg(regs, data);
if(valid == 0)
{
prom_printf("\r\n7550 reg write not access!!");
}
AfeMT7550ReadReg(regs, &data1);
if(data1!= data)
{
prom_printf("\r\nWrite error: %x VS. %x\r\n", data1, data);
}
}
else
prom_printf("\r\ngpio_test [r/w] 0xregs [0xvalue]\r\n");
}
#endif
#ifdef TC3262
#ifdef MT75XX_REDUCE_SIZE
static void
delay1us(
int us
)
{
volatile uint32 timer_now, timer_last;
volatile uint32 tick_acc;
uint32 one_tick_unit = get_SYS_HCLK() << 1;
volatile uint32 tick_wait = us * one_tick_unit;
volatile uint32 timer1_ldv = VPint(CR_TIMER1_LDV);
tick_acc = 0;
timer_last = VPint(CR_TIMER1_VLR);
do {
timer_now = VPint(CR_TIMER1_VLR);
if (timer_last >= timer_now)
tick_acc += timer_last - timer_now;
else
tick_acc += timer1_ldv - timer_now + timer_last;
timer_last = timer_now;
} while (tick_acc < tick_wait);
}
#endif
int do_cpufreq(int argc, char* argv[])
{
#ifdef MT75XX_REDUCE_SIZE
#ifndef BOOTROM_IN_SRAM
unsigned int tmp, reg_temp, maxfreq, max_cpu_value, cur_cpu_value, target_cpu;
int step_num, cpu_step;
char cpu_trap, crys_trap;
cpu_trap = ((VPint(CR_AHB_HWCONF)>>9)&0x3);
crys_trap =((VPint(CR_AHB_HWCONF)>>22)&0x3);
if((crys_trap == 0)){
cpu_step = 2500;
}else if ((crys_trap == 1) || (crys_trap == 2)){
cpu_step = 2000;
}else{
prom_printf("error crystal hw trap\n");
return -1;
}
switch(cpu_trap)
{
case 0 :
maxfreq = 750;
cur_cpu_value = (VPint(0xbfb00364));
if(cpu_step == 2500)
max_cpu_value = 0x1e000000;
else
max_cpu_value = 0x25800000;
break;
case 1 :
maxfreq = 650;
if(cpu_step == 2500){
reg_temp = 0xbfb003b0;
max_cpu_value = 0x1a000000;
}else{
reg_temp = 0xbfb003b8;
max_cpu_value = 0x20800000;
}
cur_cpu_value = (((VPint(reg_temp)>>8)&0xff)<<24) | (((VPint(reg_temp)>>3)&0x1)<<23) | (VPint(0xbfb00364)&0x7fffff);
break;
case 2 :
maxfreq = 500;
if(cpu_step == 2500){
reg_temp = 0xbfb003b0;
max_cpu_value = 0x14000000;
}else{
reg_temp = 0xbfb003b8;
max_cpu_value = 0x19000000;
}
cur_cpu_value = (((VPint(reg_temp)>>24)&0xff)<<24) | (((VPint(reg_temp)>>19)&0x1)<<23) | (VPint(0xbfb00364)&0x7fffff);
break;
case 3 :
maxfreq = 250;
if(cpu_step == 2500){
reg_temp = 0xbfb003b4;
max_cpu_value = 0x14000000;
}else{
reg_temp = 0xbfb003bc;
max_cpu_value = 0x19000000;
}
cur_cpu_value = (((VPint(reg_temp)>>8)&0xff)<<24) | (((VPint(reg_temp)>>3)&0x1)<<23) | (VPint(0xbfb00364)&0x7fffff);
break;
default:
prom_printf("error cpu hw trap\n");
return -1;
}
target_cpu = strtoul((const char*)(argv[1]), (char **)NULL, 10);
prom_printf("Target CPU %dMHz MAX CPU %dMHz cpu step %dKHz\n",target_cpu,maxfreq,cpu_step);
if(target_cpu > maxfreq)
return -1;
step_num = ((max_cpu_value - cur_cpu_value)/0x199800) - ((maxfreq - target_cpu)*1000/cpu_step);
prom_printf("max_cpu_value %x,cur_cpu_value %x step_num %d\n",max_cpu_value,cur_cpu_value,step_num);
VPint(0xbfb0039c) = 0x00750025;
while(step_num != 0){
if(step_num > 0){
step_num--;
cur_cpu_value += 0x199800;
}else{
step_num++;
cur_cpu_value -= 0x199800;
}
//prom_printf("cur_cpu_value %x , CPU %x\n",cur_cpu_value,VPint(0xbfb00364));
switch(cpu_trap)
{
case 0 :
VPint(0xbfb00364) = cur_cpu_value;
break;
case 1:
if(cpu_step == 2500){
reg_temp = 0xbfb003b0;
}else{
reg_temp = 0xbfb003b8;
}
tmp = VPint(reg_temp);
tmp &= ((0xff<<8) | (1<3));
tmp |= (((cur_cpu_value>>24) &0xff)<<8) | (((cur_cpu_value>>23) &0x1)<<3);
VPint(reg_temp) = tmp;
break;
case 2:
if(cpu_step == 2500){
reg_temp = 0xbfb003b0;
}else{
reg_temp = 0xbfb003b8;
}
tmp = VPint(reg_temp);
tmp &= ((0xff<<24) | (1<19));
tmp |= (((cur_cpu_value>>24) &0xff)<<24) | (((cur_cpu_value>>23) &0x1)<<19);
VPint(reg_temp) = tmp;
break;
case 3:
if(cpu_step == 2500){
reg_temp = 0xbfb003b4;
}else{
reg_temp = 0xbfb003bc;
}
tmp = VPint(reg_temp);
tmp &= ((0xff<<8) | (1<3));
tmp |= (((cur_cpu_value>>24) &0xff)<<8) | (((cur_cpu_value>>3) &0x1)<<3);
VPint(reg_temp) = tmp;
break;
default:
prom_printf("error\n");
break;
}
if(cpu_trap != 0){
tmp = VPint(0xbfb00364);
tmp &= ~(0x7fffff);
tmp |= (cur_cpu_value) & 0x7fffff;
VPint(0xbfb00364) = tmp;
}
tmp = VPint(0xbfb00368);
if(tmp &(1<<12)){
tmp &= ~(1<<12);
}else{
tmp |= (1<<12);
}
VPint(0xbfb00368) = tmp;
delay1us(1);
}
VPint(0xbfb0039c) = 0;
#endif
#else
if (isTC3182 || isRT65168) {
unsigned int n;
unsigned int targetfreq;
unsigned int current_m = VPint(CR_AHB_CPUF)&0x1f;
unsigned int current_n = (VPint(CR_AHB_CPUF)&0x1ff0000)>>16;
unsigned int currentfreq = 12*(current_n+1)/(current_m+1);
prom_printf("usage: cpufreq <clk>\n");
targetfreq = strtoul((const char*)(argv[1]), (char **)NULL, 10);
n = (targetfreq*(current_m+1)/12)-1;
targetfreq = 12*(n+1)/(current_m+1);
prom_printf("m=%d n=%d change CPU freq to %dMhz\n", current_m, n, targetfreq);
if (currentfreq > targetfreq) {
while (current_n > n) {
current_n -= 5;
currentfreq = 12*(current_n+1)/(current_m+1);
VPint(CR_AHB_CPUF) = current_n << 16 | current_m;
pause(1);
}
} else {
while (current_n < n) {
current_n += 5;
currentfreq = 12*(current_n+1)/(current_m+1);
VPint(CR_AHB_CPUF) = current_n << 16 | current_m;
pause(1);
}
}
if (current_n != n) {
current_n = n;
currentfreq = 12*(current_n+1)/(current_m+1);
VPint(CR_AHB_CPUF) = current_n << 16 | current_m;
pause(1);
}
prom_printf("\n");
} else if (isRT63365) {
int divq_array[6] = {1, 2, 4, 8, 16, 32};
unsigned int pllreg;
unsigned int fvco;
unsigned int targetfreq;
unsigned int current_divf, current_divq, current_divr, currentfreq;
pllreg = (((VPint(0xbfb0008c)&((1<<9)|(1<<8)))>>8) == 0x1) ? 0xbfb001d0 : (VPint(0xbfb0008c)&(1<<25) ? 0xbfb001c8 : 0xbfb001cc);
current_divf = (VPint(pllreg)>>16)&0xff;
current_divq = (VPint(pllreg)>>8)&0x7;
current_divr = VPint(pllreg)&0x1f;
currentfreq = 20/(current_divr+1)*(current_divf+1)/divq_array[current_divq];
prom_printf("usage: cpufreq <clk>\n");
targetfreq = strtoul((const char*)(argv[1]), (char **)NULL, 10);
//prom_printf("divr=%d divf=%d divq=%d\n", current_divr, current_divf, current_divq);
prom_printf("current CPU freq=%dMhz change CPU freq to %dMhz\n", currentfreq, targetfreq);
if (currentfreq > targetfreq) {
while (currentfreq > targetfreq) {
current_divf--;
fvco = 20/(current_divr+1)*(current_divf+1);
if ((fvco < 1200) || (fvco > 2400)) {
current_divf = current_divf * 2;
current_divq++;
}
currentfreq = 20/(current_divr+1)*(current_divf+1)/divq_array[current_divq];
VPint(pllreg) = (VPint(pllreg) & 0xff00f8ff) | (current_divf<<16) | (current_divq<<8);
pause(1);
}
} else {
while (currentfreq < targetfreq) {
current_divf++;
fvco = 20/(current_divr+1)*(current_divf+1);
if ((fvco < 1200) || (fvco > 2400)) {
current_divf = current_divf / 2;
current_divq--;
}
currentfreq = 20/(current_divr+1)*(current_divf+1)/divq_array[current_divq];
VPint(pllreg) = (VPint(pllreg) & 0xff00f8ff) | (current_divf<<16) | (current_divq<<8);
pause(1);
}
}
currentfreq = 20/(current_divr+1)*(current_divf+1)/divq_array[current_divq];
prom_printf("change CPU freq to %dMhz\n", currentfreq);
prom_printf("\n");
} else {
unsigned int m, n;
unsigned int targetfreq;
unsigned int tmp_m = (VPint(CR_AHB_CPUF)&0x1ff0000)>>16;
unsigned int tmp_n = VPint(CR_AHB_CPUF)&0x1f;
unsigned int currentfreq = 6*(tmp_m+1)/((tmp_n+1));
/*cpufreq <freq>*/
if(argc==2){
targetfreq = strtoul((const char*)(argv[1]), (char **)NULL, 10);
targetfreq = targetfreq - (targetfreq%6);
m = targetfreq/6 - 1;
n = 0;
}
else{/*cpufreq <m> <n>*/
m = strtoul((const char*)(argv[1]), (char **)NULL, 10);
n = strtoul((const char*)(argv[2]), (char **)NULL, 10);
targetfreq = 6*(m+1)/((n+1));
tmp_m = (currentfreq/6)*(n+1) - 1;
}
if(targetfreq >450 || targetfreq < 156){
prom_printf("CPU freq has to be between 156~450 Mhz\n");
return 0;
}
if(argc==2){
prom_printf("change CPU freq to %d Mhz (the freq has to be multiple of 6)\n",targetfreq);
}
else{
prom_printf("m=%d n=%d change CPU freq to %dMhz\n", m, n, targetfreq);
}
if(currentfreq > targetfreq){
while(tmp_m > m){
tmp_m-=(n+1);
VPint(CR_AHB_CPUF) = tmp_m << 16 |n;
uart_init();
pause(1);
}
}
else{
while(tmp_m < m){
tmp_m+=(n+1);
VPint(CR_AHB_CPUF) = tmp_m << 16 |n;
uart_init();
pause(1);
}
}
prom_printf("\n");
}
#endif
return 0;
}
#else
/* TC3162U PLL configuration */
int do_cpufreq(int argc, char* argv[])
{
unsigned int n, pll_gain;
unsigned int targetfreq;
unsigned int current_m = (VPint(CR_AHB_PLL)>>25)&0x1f;
unsigned int current_n = (VPint(CR_AHB_PLL)>>16)&0x1ff;
unsigned int currentfreq = 6*(current_n+1)/((current_m+1));
if (!isTC3162U)
return;
prom_printf("usage: cpufreq <n> m=8\n");
n = strtoul((const char*)(argv[1]), (char **)NULL, 10);
targetfreq = 6*(n+1)/((current_m+1));
prom_printf("m=%d n=%d change CPU freq to %dMhz\n", current_m, n, targetfreq);
if (currentfreq > targetfreq) {
while (current_n > n) {
current_n -= 5;
currentfreq = 6*(current_n+1)/((current_m+1));
if (currentfreq > 300)
pll_gain = 1;
else
pll_gain = 0;
VPint(CR_AHB_PLL) = ((VPint(CR_AHB_PLL) & 0xffff)<<16) | (pll_gain<<15) | ((current_m & 0x1f) << 9) | (current_n & 0x1ff);
uart_init();
pause(1);
}
} else {
while (current_n < n) {
current_n += 5;
currentfreq = 6*(current_n+1)/((current_m+1));
if (currentfreq > 300)
pll_gain = 1;
else
pll_gain = 0;
currentfreq = 6*(current_n+1)/((current_m+1));
VPint(CR_AHB_PLL) = ((VPint(CR_AHB_PLL) & 0xffff)<<16) | (pll_gain<<15) | ((current_m & 0x1f) << 9) | (current_n & 0x1ff);
uart_init();
pause(1);
}
}
if (current_n != n) {
current_n = n;
currentfreq = 6*(current_n+1)/((current_m+1));
if (currentfreq > 300)
pll_gain = 1;
else
pll_gain = 0;
VPint(CR_AHB_PLL) = ((VPint(CR_AHB_PLL) & 0xffff)<<16) | (pll_gain<<15) | ((current_m & 0x1f) << 9) | (current_n & 0x1ff);
uart_init();
pause(1);
}
prom_printf("\n");
return 0;
}
#endif
#ifdef TC3262
#ifndef BOOTROM_IN_SRAM
int do_ddrdrv(int argc, char* argv[])
{
uint32 ma_drvp, ma_drvn;
uint32 odt_drvp, odt_drvn;
uint32 dq_drvp, dq_drvn;
uint32 dqs_drvp, dqs_drvn;
uint32 ck_drvp, ck_drvn;
uint32 csn_drvp, csn_drvn;
uint32 cke_drvp, cke_drvn;
if (argc != 15) {
ma_drvp = (VPint(0xbfb20100) >> 25) & 0x1f;
ma_drvn = (VPint(0xbfb20100) >> 20) & 0x1f;
odt_drvp = (VPint(0xbfb20100) >> 9) & 0x1f;
odt_drvn = (VPint(0xbfb20100) >> 4) & 0x1f;
dq_drvp = (VPint(0xbfb2010c) >> 12) & 0x1f;
dq_drvn = (VPint(0xbfb2010c) >> 4) & 0x1f;
dqs_drvp = (VPint(0xbfb20114) >> 12) & 0x1f;
dqs_drvn = (VPint(0xbfb20114) >> 4) & 0x1f;
ck_drvp = (VPint(0xbfb20104) >> 17) & 0x1f;
ck_drvn = (VPint(0xbfb20104) >> 12) & 0x1f;
csn_drvp = (VPint(0xbfb20104) >> 27) & 0x1f;
csn_drvn = (VPint(0xbfb20104) >> 22) & 0x1f;
cke_drvp = (VPint(0xbfb20108) >> 20) & 0x1f;
cke_drvn = (VPint(0xbfb20108) >> 12) & 0x1f;
prom_printf("MA DRVP=%04x DRVN=%04x\n", ma_drvp, ma_drvn);
prom_printf("ODT DRVP=%04x DRVN=%04x\n", odt_drvp, odt_drvn);
prom_printf("DQ DRVP=%04x DRVN=%04x\n", dq_drvp, dq_drvn);
prom_printf("DQS DRVP=%04x DRVN=%04x\n", dqs_drvp, dqs_drvn);
prom_printf("CK DRVP=%04x DRVN=%04x\n", ck_drvp, ck_drvn);
prom_printf("CSN DRVP=%04x DRVN=%04x\n", csn_drvp, csn_drvn);
prom_printf("CKE DRVP=%04x DRVN=%04x\n", cke_drvp, cke_drvn);
} else {
ma_drvp = strtoul((const char*)(argv[1]), (char **)NULL, 16) & 0x1f;
ma_drvn = strtoul((const char*)(argv[2]), (char **)NULL, 16) & 0x1f;
odt_drvp = strtoul((const char*)(argv[3]), (char **)NULL, 16) & 0x1f;
odt_drvn = strtoul((const char*)(argv[4]), (char **)NULL, 16) & 0x1f;
dq_drvp = strtoul((const char*)(argv[5]), (char **)NULL, 16) & 0x1f;
dq_drvn = strtoul((const char*)(argv[6]), (char **)NULL, 16) & 0x1f;
dqs_drvp = strtoul((const char*)(argv[7]), (char **)NULL, 16) & 0x1f;
dqs_drvn = strtoul((const char*)(argv[8]), (char **)NULL, 16) & 0x1f;
ck_drvp = strtoul((const char*)(argv[9]), (char **)NULL, 16) & 0x1f;
ck_drvn = strtoul((const char*)(argv[10]), (char **)NULL, 16) & 0x1f;
csn_drvp = strtoul((const char*)(argv[11]), (char **)NULL, 16) & 0x1f;
csn_drvn = strtoul((const char*)(argv[12]), (char **)NULL, 16) & 0x1f;
cke_drvp = strtoul((const char*)(argv[13]), (char **)NULL, 16) & 0x1f;
cke_drvn = strtoul((const char*)(argv[14]), (char **)NULL, 16) & 0x1f;
VPint(0xbfb20100) = VPint(0xbfb20100) & (~((0x1f<<25) | (0x1f<<20))) | ((ma_drvp<<25) | (ma_drvn<<20));
VPint(0xbfb20100) = VPint(0xbfb20100) & (~((0x1f<<9) | (0x1f<<4))) | ((odt_drvp<<9) | (odt_drvn<<4));
VPint(0xbfb2010c) = VPint(0xbfb2010c) & (~((0x1f<<12) | (0x1f<<4))) | ((dq_drvp<<12) | (dq_drvn<<4));
VPint(0xbfb20114) = VPint(0xbfb20114) & (~((0x1f<<12) | (0x1f<<4))) | ((dqs_drvp<<12) | (dqs_drvn<<4));
VPint(0xbfb20104) = VPint(0xbfb20104) & (~((0x1f<<17) | (0x1f<<12))) | ((ck_drvp<<17) | (ck_drvn<<12));
VPint(0xbfb20104) = VPint(0xbfb20104) & (~((0x1f<<27) | (0x1f<<22))) | ((csn_drvp<<27) | (csn_drvn<<22));
VPint(0xbfb20108) = VPint(0xbfb20108) & (~((0x1f<<20) | (0x1f<<12))) | ((cke_drvp<<20) | (cke_drvn<<12));
}
return 0;
}
#endif
#endif
#ifdef ETH_TEST_CMD
extern int tc3162_eth_testsend(unsigned long len, unsigned long cnt);
extern int tc3162_eth_testsend2(unsigned long len, unsigned long cnt);
extern int tc3162_eth_dump(void);
int do_ethsend(int argc, char *argv[])
{
unsigned long len;
unsigned long cnt;
unsigned long i;
unsigned char k;
len = strtoul((const char*)(argv[1]), (char **)NULL, 10);
cnt = strtoul((const char*)(argv[2]), (char **)NULL, 10);
prom_printf("Send %d ethernet frame with len=%d\n", cnt, len);
tc3162_eth_testsend(len, cnt);
return 0;
}
int do_ethsend2(int argc, char *argv[])
{
unsigned long len;
unsigned long cnt;
unsigned long i;
unsigned char k;
len = strtoul((const char*)(argv[1]), (char **)NULL, 10);
cnt = strtoul((const char*)(argv[2]), (char **)NULL, 10);
prom_printf("Send %d ethernet frame with len=%d\n", cnt, len);
tc3162_eth_testsend2(len, cnt);
return 0;
}
int do_ethdump(int argc, char *argv[])
{
tc3162_eth_dump();
return 0;
}
#endif
extern int XModemReceive(char *bufBase, int bufLen);
int do_xmodem_rx(int argc, char* argv[])
{
unsigned long addr;
unsigned int len;
unsigned int rcv_len;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
len = strtoul((const char*)(argv[2]), (char **)NULL, 16);
rcv_len = XModemReceive((char *) addr, len);
if (rcv_len)
prom_printf("received len=%x\n", rcv_len);
else
prom_printf("received error\n");
return 0;
}
#ifdef BOOTROM_IN_SRAM
extern int is_fw_upgrade;
extern int flash_base_addr;
int do_xmodem_rx_flash(int argc, char* argv[])
{
unsigned long addr;
unsigned int len;
unsigned int flash_addr;
unsigned int rcv_len;
addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
len = strtoul((const char*)(argv[2]), (char **)NULL, 16);
flash_addr = strtoul((const char*)(argv[3]), (char **)NULL, 16);
is_fw_upgrade = 1;
flash_base_addr = flash_addr;
prom_printf("received from UART and write to flash\n");
rcv_len = XModemReceive((char *) addr, len);
if (rcv_len)
prom_printf("received len=%x\n", rcv_len);
else
prom_printf("received error\n");
return 0;
}
#endif
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
char *cmd_gets(char *buf, int len, int flag)
{
int c,i=0;
char *cp;
cp = buf;
while ((c = serial_inc()) != KEY_CR)
{
if ( c == KEY_BS )
{
if ( cp != buf )
{
printf("\b \b");
cp--;
i--;
}
}
else
{
if ( buf != NULL )
{
if ( i <= len-1 )
{
if ( flag == CMD )
serial_outc(c); /*cmd mode*/
else
serial_outc('*'); /*passord mode*/
*cp++ = c;
i++;
}
}
}
}
if (buf != NULL)
*cp = '\0';
return buf;
}
#else
char *cmd_gets(char *buf, int len)
{
int c;
char *cp;
cp = buf;
while ((c = serial_inc()) != KEY_CR) {
if (c == KEY_BS) {
if ( cp != buf ) {
printf("\b \b");
cp--;
}
} else {
if(buf != NULL) {
serial_outc(c);
*cp++ = c;
}
}
}
if(buf != NULL)
*cp = '\0';
return buf;
}
#endif
int cmd_parse(cmds_t cmds[], char *line)
{
cmds_t *cmdp;
char *argv[NARGS],*cp;
char **pargv;
int argc,i;
/* Remove cr/lf */
if((cp = strchr(line,'\n')) != NULL)
*cp = '\0';
if((cp = strchr(line,'\r')) != NULL)
*cp = '\0';
for(argc = 0;argc < NARGS;argc++)
argv[argc] = NULL;
for(argc = 0;argc < NARGS;){
/* Skip leading white space */
while(*line == ' ' || *line == '\t')
line++;
if(*line == '\0')
break;
argv[argc++] = line; /* Beginning of token */
/* Find space or tab. If not present,
* then we've already found the last
* token.
*/
if((cp = strchr(line,' ')) == NULL && (cp = strchr(line,'\t')) == NULL) {
break;
}
*cp++ = '\0';
line = cp;
}
if (argc < 1) { /* empty command line */
argc = 1;
argv[0] = "";
}
/* Look up command in table; prefix matches are OK */
for(cmdp = cmds;cmdp->name != NULL;cmdp++){
if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0) {
break;
}
}
if(cmdp->name == NULL) {
if(cmdp->help != NULL)
printf("%s\n",cmdp->help);
return -1;
}
if(argc < cmdp->nargs) {
/* Insufficient arguments */
printf("Usage: %s\n",cmdp->usage);
return -1;
}
if(cmdp->func == NULL)
return 0;
return (*cmdp->func)(argc,argv);
}
int cmd_proc(void)
{
static uint8 line[LINE_LEN];
#if defined(TCSUPPORT_FWC_ENV)
restart_time_flags = 1;
restart_time_count = RESTART_TIME_COUNT;
#endif
while (1) {
printf("%s> ", cmd_prompt);
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
cmd_gets(line, LINE_LEN,CMD);
#else
cmd_gets(line, LINE_LEN);
#endif
printf("\n");
#if defined(TCSUPPORT_FWC_ENV)
if(0 == strlen(line)) {/*filter enter key*/
continue;
}
if(0 == cmd_parse(CMDS, line)) {/*parse command success*/
restart_time_count = RESTART_TIME_COUNT;
}
#else
cmd_parse(CMDS, line);
#endif
}
}
#if defined(TCSUPPORT_CT_BOOTLOADER_UPGRADE)
void user_Auth(void)
{
int i;
uint8 UserName[LINE_LEN];
uint8 Pwd[LINE_LEN];
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
proline_Para proline;
char user_name[CFEUSRNAMELEN] = {0};
char pass_word[CFEPWDLEN] = {0};
#else
char user_name[USERNAME_PASSWD_LEN] = {0};
char pass_word[USERNAME_PASSWD_LEN] = {0};
#endif
unsigned long reserved_base = 0;
// char *flash_user_name_addr = (char *)FLASH_USER_NAME;
// char *flash_pass_word_addr = (char *)FLASH_PASS_WORD;
char *flash_user_name_addr;
char *flash_pass_word_addr;
if (IS_SPIFLASH){
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
reserved_base = (mtd.size - 7 * mtd.erasesize);
#else
reserved_base = (mtd.size - 4 * mtd.erasesize);
#endif
} else {
#ifdef TCSUPPORT_BB_NAND
reserved_base = (1<<ra.flash->chip_shift) - 4 * (1<<ra.flash->erase_shift);
#endif
}
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
flash_user_name_addr = (char *)(((PROLINE_CWMPPARA_RA_OFFSET + reserved_base)|flash_base) + ((char *)&proline.cfeusrname[0] - (char *)&proline.flag));
flash_pass_word_addr = flash_user_name_addr + CFEUSRNAMELEN;
for(i=0; i<CFEUSRNAMELEN-1; i++)
{
user_name[i] = READ_FLASH_BYTE(flash_user_name_addr+i);
}
user_name[i] = '\0';
for(i=0; i<CFEPWDLEN-1; i++)
{
pass_word[i] = READ_FLASH_BYTE(flash_pass_word_addr+i);
}
pass_word[i] = '\0';
if((user_name[0] == 0 && user_name[1] == 0 && user_name[2] == 0)
|| (user_name[0] == 0xff && user_name[1] == 0xff && user_name[2] == 0xff))
{
memset(user_name, 0, CFEUSRNAMELEN);
snprintf(user_name,sizeof(user_name),"%s",DEFAULT_CFE_USERNAME);
}
if((pass_word[0] == 0 && pass_word[1] == 0 && pass_word[2] == 0)
|| (pass_word[0] == 0xff && pass_word[1] == 0xff && pass_word[2] == 0xff))
{
memset(pass_word, 0, CFEPWDLEN);
snprintf(pass_word,sizeof(pass_word),"%s",DEFAULT_CFE_PWD);
}
#else
flash_user_name_addr = (char *)((USERNAMEPASSWD_RA_OFFSET+reserved_base)|flash_base);
flash_pass_word_addr = (char *)((USERNAMEPASSWD_RA_OFFSET+USERNAME_PASSWD_LEN+reserved_base)|flash_base);
for(i=0; i<USERNAME_PASSWD_LEN-1; i++)
{
// user_name[i] = flash_user_name_addr[i];
// pass_word[i] = flash_pass_word_addr[i];
user_name[i] = READ_FLASH_BYTE(flash_user_name_addr+i);
pass_word[i] = READ_FLASH_BYTE(flash_pass_word_addr+i);
}
user_name[i] = '\0';
pass_word[i] = '\0';
// printf("user_Auth: flash---user_name = %s\n\n", user_name);
// printf("user_Auth: flash---pass_word = %s\n\n", pass_word);
#endif
if(strncmp(CT_USER_NAME, user_name, strlen(CT_USER_NAME)) != 0)
{
flash_user_name_addr = (char *)MRD_USER_NAME;
flash_pass_word_addr = (char *)MRD_PASS_WORD;
for(i=0; i<USERNAME_PASSWD_LEN-1; i++)
{
user_name[i] = READ_FLASH_BYTE(flash_user_name_addr+i);
pass_word[i] = READ_FLASH_BYTE(flash_pass_word_addr+i);
}
user_name[i] = '\0';
pass_word[i] = '\0';
}
while (1) {
memset(UserName, 0, LINE_LEN);
memset(Pwd, 0, LINE_LEN);
printf("UserName: ");
cmd_gets(UserName, LINE_LEN, CMD);
printf("\n");
printf("Password: ");
cmd_gets(Pwd, LINE_LEN, PWD);
i = trim(UserName);
printf("\n\n");
#ifdef TCSUPPORT_RESERVEAREA_EXTEND
if((!strncmp(&UserName[i], user_name, CFEUSRNAMELEN))&&(!strncmp(Pwd, pass_word, CFEPWDLEN)))
#else
if((!strncmp(&UserName[i], user_name, USERNAME_PASSWD_LEN))&&(!strncmp(Pwd, pass_word, USERNAME_PASSWD_LEN)))
#endif
{
authed = 1;
break;
}
}
}
int trim(char *buf)
{
int i,j;
int flag_i=1, flag_j=1;
for (i=0,j=strlen(buf)-1; i<=j; i++,j--)
{
if (flag_i)
{
if((buf[i] != ' ') && (buf[i] != '\t'))
flag_i = 0;
}
if (flag_j)
{
if((buf[j] == ' ') || (buf[j] == '\t'))
buf[j] = 0;
else
flag_j = 0;
}
if ((flag_i == 0) && (flag_j == 0))
break;
}
return i;
}
#endif
#if defined(TCSUPPORT_FWC_ENV)
int g_boot_debug_level = E_BOOT_NO_INFO_LEVLE;
static int do_boot_debug_level(int argc, char *argv[])
{
g_boot_debug_level = strtoul((const char*)(argv[1]), (char **)NULL, 16);
printf("g_boot_debug_level = 0x%X.\n", g_boot_debug_level);
return 0;
}
static int do_boot_reset(int argc, char *argv[])
{
unsigned long addr_value = 0;
unsigned long reset_control_register = RESET_CONTROL_REGISTER;
addr_value = tc_inl(reset_control_register);
addr_value |= (1 << SYSTEM_SOFTWARE_RESET_OFFSET);
tc_outl(reset_control_register, addr_value);
return 0;
}
static int do_boot_version(int argc, char *argv[])
{
unsigned int i = 0;
unsigned char buffer[FH_NW_PRODUCT_ENV_SIZE];
memset(buffer, 0, sizeof(buffer));
for(i=0; i <(FH_NW_PRODUCT_ENV_SIZE -1) ; i++)
{
buffer[i] = READ_FLASH_BYTE(flash_base+0xff04 + i);
}
buffer[i] = '\0';
printf("bootversion = %s.\n",buffer);
return 0;
}
static int do_flash_erase(int argc, char *argv[])
{
unsigned long len = 0;
unsigned long start_addr = 0;
start_addr = strtoul((const char*)(argv[1]), (char **)NULL, 16);
len = strtoul((const char*)(argv[2]), (char **)NULL, 16);
printf("start_addr = 0x%x, len = 0x%x.\n",start_addr, len);
flash_erase(start_addr, len);
}
/************************************************************************************************/
static int printf_flash_env_info(flash_env_personality_parm_partition_info_t *pt_info, unsigned int flag, unsigned int line)
{
if((g_boot_debug_level & E_BOOT_DEBUG_INFO_LEVLE) || (E_BOOT_DEBUG_INFO_LEVLE == flag))
{
int i = 0;
int j = 0;
printf("*****************line = %d**************************************.\n", line);
printf("snoui = %s\t", pt_info->env.sn_oui);
printf("hw_cfg = %s\t", pt_info->env.hw_cfg);
printf("ethaddr = %s\t", pt_info->env.eth_addr);
printf("f_reserve0 = %s\t", pt_info->env.f_reserve0);
printf("\n");
printf("f_reserve1 = %s\t", pt_info->env.f_reserve1);
printf("f_reserve2 = %s\t", pt_info->env.f_reserve2);
printf("f_reserve3 = %s\t", pt_info->env.f_reserve3);
printf("f_reserve4 = %s\t", pt_info->env.f_reserve4);
printf("\n");
printf("f_reserve5 = %s\t", pt_info->env.f_reserve5);
printf("f_reserve6 = %s\t", pt_info->env.f_reserve6);
printf("f_reserve7 = %s\t", pt_info->env.f_reserve7);
printf("f_reserve8 = %s\t", pt_info->env.f_reserve8);
printf("\n");
printf("f_reserve9 = %s\t", pt_info->env.f_reserve9);
printf("f_reserve10 = %s\t", pt_info->env.f_reserve10);
printf("f_reserve11 = %s\t", pt_info->env.f_reserve11);
printf("f_reserve12 = %s\t", pt_info->env.f_reserve12);
printf("\n");
printf("f_reserve13 = %s\t", pt_info->env.f_reserve13);
printf("f_reserve14 = %s\t", pt_info->env.f_reserve14);
printf("f_reserve15 = %s\t", pt_info->env.f_reserve15);
printf("f_reserve16 = %s\t", pt_info->env.f_reserve16);
printf("\n");
printf("f_reserve17 = %s\t", pt_info->env.f_reserve17);
printf("f_reserve18 = %s\t", pt_info->env.f_reserve18);
printf("f_reserve19 = %s\t", pt_info->env.f_reserve19);
printf("\n");
for(i=0; i<FH_NW_PRODUCT_CHECK_VENDOR_SIZE; i++)
{
j = i;
if(0 == j%4)
{
printf("\n");
}
printf("vendor[%d] = 0x%X.\t", i, pt_info->check_info.vendor[i]);
}
printf("\n");
printf("magic = 0x%X, crc_check = 0x%X.\n",pt_info->check_info.magic, pt_info->check_info.crc_check);
}
return 0;
}
static int printf_dual_image_info(dual_image_personality_parm_partition_info_t *pt_info, unsigned int flag, unsigned int line)
{
if((g_boot_debug_level & E_BOOT_DEBUG_INFO_LEVLE) || (E_BOOT_DEBUG_INFO_LEVLE == flag))
{
int i = 0;
int j = 0;
printf("*****************line = %d**************************************.\n", line);
printf("kernel_commit = %d\t", pt_info->dual_image_element.kernel_commit);
printf("kernel_active = %d\t", pt_info->dual_image_element.kernel_active);
printf("rootfs_commit = %d\t", pt_info->dual_image_element.rootfs_commit);
printf("rootfs_active = %d\t", pt_info->dual_image_element.rootfs_active);
printf("\n");
printf("app1_commit = %d\t", pt_info->dual_image_element.app1_commit);
printf("app1_active = %d\t", pt_info->dual_image_element.app1_active);
printf("app2_commit = %d\t", pt_info->dual_image_element.app2_commit);
printf("app2_active = %d\t", pt_info->dual_image_element.app2_active);
printf("\n");
for(i=0; i<FH_NW_PRODUCT_DUAL_IMAGE_FLAG_RESERVE_SIZE; i++)
{
j = i;
if(0 == j%4)
{
printf("\n");
}
printf("dual_reserve[%d] = 0x%X.\t", i, pt_info->dual_image_element.reserve[i]);
}
printf("\n");
for(i=0; i<FH_NW_PRODUCT_CHECK_RESERVE_SIZE; i++)
{
j = i;
if(0 == j%4)
{
printf("\n");
}
printf("check_reserve[%d] = 0x%X.\t", i, pt_info->check_info.reserve[i]);
}
printf("\n");
for(i=0; i<FH_NW_PRODUCT_CHECK_VENDOR_SIZE; i++)
{
j = i;
if(0 == j%4)
{
printf("\n");
}
printf("vendor[%d] = 0x%X.\t", i, pt_info->check_info.vendor[i]);
}
printf("\n");
printf("magic = 0x%X, crc_check = 0x%X.\n",pt_info->check_info.magic, pt_info->check_info.crc_check);
}
return 0;
}
static int dual_image_offset_convert_value(unsigned long offset, unsigned long vaule, unsigned char *flag)
{
switch(offset)
{
case KERNEL_COMMIT_OFFSET:
case ROOTFS_COMMIT_OFFSET:
case APP1_COMMIT_OFFSET:
case APP2_COMMIT_OFFSET:
{
if(E_FH_NW_PRODUCT_COMMIT_B != vaule)
{
vaule = E_FH_NW_PRODUCT_COMMIT_A;
}
break;
}
case KERNEL_ACTIVE_OFFSET:
case ROOTFS_ACTIVE_OFFSET:
case APP2_ACTIVE_OFFSET:
case APP1_ACTIVE_OFFSET:
{
if((E_FH_NW_PRODUCT_ACTIVE_A != vaule) && (E_FH_NW_PRODUCT_ACTIVE_B != vaule))
{
vaule = E_FH_NW_PRODUCT_ACTIVE_DEFAULT;
}
break;
}
default:
{
return E_PERSONALITY_PARM_INVALID_ARGUMENT;
}
}
*flag = (vaule & FH_NW_PRODUCT_DUAL_IMAGE_MASK);
return E_PERSONALITY_PARM_RIGHT_EXECUTE;
}
static int personality_parm_check_vendor_define(personality_parm_cmd_base_addr_t *pt_info)
{
unsigned long A_base_addr = 0;
unsigned long B_base_addr = 0;
unsigned long ret_len = 0;
unsigned char flag = 0;
unsigned char A_vaild_flag = INVLID;
unsigned char B_vaild_flag = INVLID;
check_personality_parm_partition_info_t A_policy;
check_personality_parm_partition_info_t B_policy;
memset(&A_policy, 0, sizeof(A_policy));
memset(&B_policy, 0, sizeof(B_policy));
switch(pt_info->read_base_addr)
{
case FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR:
case FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR:
{
A_base_addr = (pt_info->read_base_addr + FH_NW_PRODUCT_DUAL_IMAGE_FLAG_CHECK_INFO_OFFSET);
B_base_addr = (pt_info->write_base_addr + FH_NW_PRODUCT_DUAL_IMAGE_FLAG_CHECK_INFO_OFFSET);
break;
}
case FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR:
case FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR:
{
A_base_addr = (pt_info->read_base_addr + FH_NW_PRODUCT_FLASH_ENV_INFO_OFFSET);
B_base_addr = (pt_info->write_base_addr + FH_NW_PRODUCT_FLASH_ENV_INFO_OFFSET);
break;
}
default:
{
pt_info->both_valid_flag = INVLID;
return FH_NW_PRODUCT_BREAK;
}
}
BOOT_DEBUG_INFO("A_base_addr = 0x%X, B_base_addr = 0x%X.\n", A_base_addr, B_base_addr);
flash_read(A_base_addr, FH_NW_PRODUCT_CHECK_SIZE, &ret_len, (unsigned char *)&A_policy);
flash_read(B_base_addr, FH_NW_PRODUCT_CHECK_SIZE, &ret_len, (unsigned char *)&B_policy);
/*vendor define compare*/
if(0 == memcmp(A_policy.vendor, FH_NW_PRODUCT_VENDOR_DEFINE, FH_NW_PRODUCT_CHECK_VENDOR_SIZE))
{
A_vaild_flag = VALID;
}
if(0 == memcmp(B_policy.vendor, FH_NW_PRODUCT_VENDOR_DEFINE, FH_NW_PRODUCT_CHECK_VENDOR_SIZE))
{
B_vaild_flag = VALID;
}
BOOT_DEBUG_INFO("A_vaild_flag = %d, B_vaild_flag = %d.\n", A_vaild_flag, B_vaild_flag);
if((VALID == A_vaild_flag) && (INVLID == B_vaild_flag))
{
/******wait check A crc*********/
pt_info->A_valid_flag = FH_NW_PRODUCT_POSSIBLE_VALID;
return FH_NW_PRODUCT_CONTINUE;
}
else if((INVLID == A_vaild_flag) && (VALID == B_vaild_flag))
{
/******wait check B crc*********/
pt_info->B_valid_flag = FH_NW_PRODUCT_POSSIBLE_VALID;
return FH_NW_PRODUCT_CONTINUE;
}
else if((INVLID == A_vaild_flag) && (INVLID == B_vaild_flag))
{
/******read A, write B*********/
pt_info->valid_read_addr = pt_info->read_base_addr;
pt_info->valid_write_addr = pt_info->write_base_addr;
pt_info->both_valid_flag = INVLID;
return FH_NW_PRODUCT_BREAK;
}
/******wait check A&&B crc*********/
pt_info->A_valid_flag = FH_NW_PRODUCT_POSSIBLE_VALID;
pt_info->B_valid_flag = FH_NW_PRODUCT_POSSIBLE_VALID;
return FH_NW_PRODUCT_CONTINUE;
}
static int personality_parm_check_crc(personality_parm_cmd_base_addr_t *pt_info)
{
unsigned long A_base_addr = 0;
unsigned long B_base_addr = 0;
unsigned long ret_len = 0;
unsigned int A_crc = 0;
unsigned int B_crc = 0;
unsigned char flag = 0;
unsigned long check_data_size = 0;
unsigned char A_vaild_flag = INVLID;
unsigned char B_vaild_flag = INVLID;
dual_image_personality_parm_partition_info_t A_dual_image;
dual_image_personality_parm_partition_info_t B_dual_image;
flash_env_personality_parm_partition_info_t A_env_info;
flash_env_personality_parm_partition_info_t B_env_info;
memset(&A_dual_image, 0, sizeof(A_dual_image));
memset(&B_dual_image, 0, sizeof(B_dual_image));
memset(&A_env_info, 0, sizeof(A_env_info));
memset(&B_env_info, 0, sizeof(B_env_info));
BOOT_DEBUG_INFO("both_valid_flag = %d.\n", pt_info->both_valid_flag);
if(INVLID == pt_info->both_valid_flag)
{
return FH_NW_PRODUCT_BREAK;
}
switch(pt_info->read_base_addr)
{
case FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR:
case FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR:
{
flag = FH_NW_PRODUCT_DUAL_IMAGE_PARTITION;
A_base_addr = pt_info->read_base_addr;
B_base_addr = pt_info->write_base_addr;
check_data_size = (sizeof(dual_image_personality_parm_partition_info_t) - sizeof(unsigned int));
break;
}
case FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR:
case FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR:
{
flag = FH_NW_PRODUCT_FLASH_ENV_PARTITION;
A_base_addr = pt_info->read_base_addr;
B_base_addr = pt_info->write_base_addr;
check_data_size = (sizeof(flash_env_personality_parm_partition_info_t) - sizeof(unsigned int));
break;
}
default:
{
pt_info->both_valid_flag = INVLID;
return FH_NW_PRODUCT_BREAK;
}
}
BOOT_DEBUG_INFO("A_base_addr = 0x%X, B_base_addr = 0x%X.\n", A_base_addr, B_base_addr);
/*calc crc*/
if(FH_NW_PRODUCT_POSSIBLE_VALID == pt_info->A_valid_flag)
{
if(FH_NW_PRODUCT_DUAL_IMAGE_PARTITION == flag)
{
flash_read(A_base_addr, sizeof(A_dual_image), &ret_len, (unsigned char *)&A_dual_image);
A_crc = crc32buf((char *)&A_dual_image, check_data_size, 1);
BOOT_DEBUG_INFO("A_crc = 0x%X, A_dual_image.check_info.crc_check = 0x%X.\n",A_crc, A_dual_image.check_info.crc_check);
if(A_crc == A_dual_image.check_info.crc_check)
{
A_vaild_flag = VALID;
}
}
else if(FH_NW_PRODUCT_FLASH_ENV_PARTITION == flag)
{
flash_read(A_base_addr, sizeof(A_env_info), &ret_len, (unsigned char *)&A_env_info);
A_crc = crc32buf((char *)&A_env_info, check_data_size, 1);
BOOT_DEBUG_INFO("A_crc = 0x%X, A_env_info.check_info.crc_check = 0x%X.\n",A_crc, A_env_info.check_info.crc_check);
if(A_crc == A_env_info.check_info.crc_check)
{
A_vaild_flag = VALID;
}
}
}
if(FH_NW_PRODUCT_POSSIBLE_VALID == pt_info->B_valid_flag)
{
if(FH_NW_PRODUCT_DUAL_IMAGE_PARTITION == flag)
{
flash_read(B_base_addr, sizeof(B_dual_image), &ret_len, (unsigned char *)&B_dual_image);
B_crc = crc32buf((char *)&B_dual_image, check_data_size, 1);
BOOT_DEBUG_INFO("B_crc = 0x%X, B_dual_image.check_info.crc_check = 0x%X.\n",B_crc, B_dual_image.check_info.crc_check);
if(B_crc == B_dual_image.check_info.crc_check)
{
B_vaild_flag = VALID;
}
}
else if(FH_NW_PRODUCT_FLASH_ENV_PARTITION == flag)
{
flash_read(B_base_addr, sizeof(B_env_info), &ret_len, (unsigned char *)&B_env_info);
B_crc = crc32buf((char *)&B_env_info, check_data_size, 1);
BOOT_DEBUG_INFO("B_crc = 0x%X, B_env_info.check_info.crc_check = 0x%X.\n",B_crc, B_env_info.check_info.crc_check);
if(B_crc == B_env_info.check_info.crc_check)
{
B_vaild_flag = VALID;
}
}
}
BOOT_DEBUG_INFO("A_vaild_flag = %d, B_vaild_flag = %d.\n", A_vaild_flag, B_vaild_flag);
/*crc && vendor synthetic judgmen*/
if((VALID == A_vaild_flag) && (INVLID == B_vaild_flag))
{
/******read A, write B*********/
pt_info->valid_read_addr = pt_info->read_base_addr;
pt_info->valid_write_addr = pt_info->write_base_addr;
return FH_NW_PRODUCT_BREAK;
}
else if((INVLID == A_vaild_flag) && (VALID == B_vaild_flag))
{
/******read B, write A*********/
pt_info->valid_read_addr = pt_info->write_base_addr;
pt_info->valid_write_addr = pt_info->read_base_addr;
return FH_NW_PRODUCT_BREAK;
}
else if((INVLID == A_vaild_flag) && (INVLID == B_vaild_flag))
{
/******read A, write B*********/
pt_info->valid_read_addr = pt_info->read_base_addr;
pt_info->valid_write_addr = pt_info->write_base_addr;
pt_info->both_valid_flag = INVLID;
return FH_NW_PRODUCT_BREAK;
}
/**********wait check magic********/
pt_info->both_valid_flag = VALID;
return FH_NW_PRODUCT_CONTINUE;
}
static int personality_parm_check_magic(personality_parm_cmd_base_addr_t *pt_info)
{
unsigned long A_base_addr = 0;
unsigned long B_base_addr = 0;
unsigned long ret_len = 0;
unsigned char A_vaild_flag = INVLID;
unsigned char B_vaild_flag = INVLID;
check_personality_parm_partition_info_t A_policy;
check_personality_parm_partition_info_t B_policy;
memset(&A_policy, 0, sizeof(A_policy));
memset(&B_policy, 0, sizeof(B_policy));
BOOT_DEBUG_INFO("both_valid_flag = %d.\n", pt_info->both_valid_flag);
if(VALID != pt_info->both_valid_flag)
{
return 0;
}
switch(pt_info->read_base_addr)
{
case FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR:
case FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR:
{
A_base_addr = (pt_info->read_base_addr + FH_NW_PRODUCT_DUAL_IMAGE_FLAG_CHECK_INFO_OFFSET);
B_base_addr = (pt_info->write_base_addr + FH_NW_PRODUCT_DUAL_IMAGE_FLAG_CHECK_INFO_OFFSET);
break;
}
case FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR:
case FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR:
{
A_base_addr = (pt_info->read_base_addr + FH_NW_PRODUCT_FLASH_ENV_INFO_OFFSET);
B_base_addr = (pt_info->write_base_addr + FH_NW_PRODUCT_FLASH_ENV_INFO_OFFSET);
break;
}
default:
{
return -1;
}
}
BOOT_DEBUG_INFO("A_base_addr = 0x%X, B_base_addr = 0x%X.\n", A_base_addr, B_base_addr);
flash_read(A_base_addr, FH_NW_PRODUCT_CHECK_SIZE, &ret_len, (unsigned char *)&A_policy);
flash_read(B_base_addr, FH_NW_PRODUCT_CHECK_SIZE, &ret_len, (unsigned char *)&B_policy);
BOOT_DEBUG_INFO("A_policy.magic = 0x%X, B_policy.magic = 0x%X.\n", A_policy.magic, B_policy.magic);
/*crc && vendor &&magic synthetic judgmen*/
if((A_policy.magic == 0) && (B_policy.magic == MAX_MAGIC_VALUE))
{
/******read A, write B*********/
pt_info->valid_read_addr = pt_info->read_base_addr;
pt_info->valid_write_addr = pt_info->write_base_addr;
}
else if((A_policy.magic == MAX_MAGIC_VALUE) && (B_policy.magic == 0))
{
/******read B, write A*********/
pt_info->valid_read_addr = pt_info->write_base_addr;
pt_info->valid_write_addr = pt_info->read_base_addr;
}
else if(A_policy.magic >= B_policy.magic)
{
/******read A, write B*********/
pt_info->valid_read_addr = pt_info->read_base_addr;
pt_info->valid_write_addr = pt_info->write_base_addr;
}
else
{
/******read B, write A*********/
pt_info->valid_read_addr = pt_info->write_base_addr;
pt_info->valid_write_addr = pt_info->read_base_addr;
}
return 0;
}
int personality_parm_get_partition_valid(personality_parm_cmd_base_addr_t *pt_info)
{
int iret = 0;
iret = personality_parm_check_vendor_define(pt_info);
if(FH_NW_PRODUCT_CONTINUE != iret)
{
return 0;
}
BOOT_DEBUG_INFO("need check_crc.\n");
iret = personality_parm_check_crc(pt_info);
if(FH_NW_PRODUCT_CONTINUE != iret)
{
return 0;
}
BOOT_DEBUG_INFO("need check_magic.\n");
iret = personality_parm_check_magic(pt_info);
if(0 != iret)
{
printf("check magic fail.\n");
}
BOOT_DEBUG_INFO("check magic ok.\n");
return iret;
}
static int get_dual_image_entry(personality_parm_t* pt_info)
{
int iret = E_PERSONALITY_PARM_RIGHT_EXECUTE;
unsigned char flag = 0;
unsigned long value = 0;
personality_parm_cmd_base_addr_t info;
memset(&info, 0, sizeof(info));
info.read_base_addr = pt_info->read_base_addr;
info.write_base_addr = pt_info->write_base_addr;
iret = personality_parm_get_partition_valid(&info);
if(0 != iret)
{
pt_info->element.dual_image_flag = 0;
return E_PERSONALITY_PARM_INVALID_ARGUMENT;
}
BOOT_DEBUG_INFO("both_valid_flag = %d. v_offset = 0x%X.\n", info.both_valid_flag, pt_info->v_offset);
if(INVLID == info.both_valid_flag)
{
switch(pt_info->v_offset)
{
case KERNEL_COMMIT_OFFSET:
case ROOTFS_COMMIT_OFFSET:
case APP1_COMMIT_OFFSET:
case APP2_COMMIT_OFFSET:
{
pt_info->element.dual_image_flag = E_FH_NW_PRODUCT_COMMIT_A;
break;
}
case KERNEL_ACTIVE_OFFSET:
case ROOTFS_ACTIVE_OFFSET:
case APP2_ACTIVE_OFFSET:
case APP1_ACTIVE_OFFSET:
{
pt_info->element.dual_image_flag = E_FH_NW_PRODUCT_ACTIVE_DEFAULT;
break;
}
default:
{
pt_info->element.dual_image_flag = 0;
break;;
}
}
}
else
{
pt_info->read_base_addr = info.valid_read_addr;
pt_info->write_base_addr = info.valid_write_addr;
BOOT_DEBUG_INFO("read = 0x%X, write = 0x%X.\n", pt_info->read_base_addr, pt_info->write_base_addr);
BOOT_DEBUG_INFO("v_offset = 0x%X.\n", pt_info->v_offset);
value = READ_FLASH_BYTE(pt_info->read_base_addr + pt_info->v_offset);
iret = dual_image_offset_convert_value(pt_info->v_offset, value, &flag);
if(E_PERSONALITY_PARM_RIGHT_EXECUTE != iret)
{
return E_PERSONALITY_PARM_INVALID_ARGUMENT;
}
pt_info->element.dual_image_flag = (flag & FH_NW_PRODUCT_DUAL_IMAGE_MASK);
BOOT_DEBUG_INFO("value = %d, flag = %d.\n", value, flag);
}
BOOT_DEBUG_INFO("dual_image_flag = %d.\n",pt_info->element.dual_image_flag);
return E_PERSONALITY_PARM_RIGHT_EXECUTE;
}
static int offset_to_dual_image_info(personality_parm_t *offset_info, dual_image_personality_parm_partition_info_t *pt_info)
{
switch(offset_info->v_offset)
{
case KERNEL_COMMIT_OFFSET:
{
pt_info->dual_image_element.kernel_commit = offset_info->element.dual_image_flag;
break;
}
case ROOTFS_COMMIT_OFFSET:
{
pt_info->dual_image_element.rootfs_commit = offset_info->element.dual_image_flag;
break;
}
case APP1_COMMIT_OFFSET:
{
pt_info->dual_image_element.app1_commit = offset_info->element.dual_image_flag;
break;
}
case APP2_COMMIT_OFFSET:
{
pt_info->dual_image_element.app2_commit = offset_info->element.dual_image_flag;
break;
}
case KERNEL_ACTIVE_OFFSET:
{
pt_info->dual_image_element.kernel_active = offset_info->element.dual_image_flag;
break;
}
case ROOTFS_ACTIVE_OFFSET:
{
pt_info->dual_image_element.rootfs_active = offset_info->element.dual_image_flag;
break;
}
case APP2_ACTIVE_OFFSET:
{
pt_info->dual_image_element.app2_active = offset_info->element.dual_image_flag;
break;
}
case APP1_ACTIVE_OFFSET:
{
pt_info->dual_image_element.app1_active = offset_info->element.dual_image_flag;
break;
}
default:
{
break;
}
}
return 0;
}
static int set_dual_image_entry(personality_parm_t* pt_info)
{
int iret = E_PERSONALITY_PARM_RIGHT_EXECUTE;
unsigned char flag = 0;
unsigned long value = 0;
unsigned long ret_len = 0;
unsigned long check_data_size = 0;
unsigned int crc_check_sum = 0;
personality_parm_cmd_base_addr_t info;
dual_image_personality_parm_partition_info_t dual_info;
unsigned long dual_info_size = sizeof(dual_image_personality_parm_partition_info_t);
memset(&dual_info, 0, sizeof(dual_info));
memset(&info, 0, sizeof(info));
info.read_base_addr = pt_info->read_base_addr;
info.write_base_addr = pt_info->write_base_addr;
iret = personality_parm_get_partition_valid(&info);
if(0 != iret)
{
return E_PERSONALITY_PARM_INVALID_ARGUMENT;
}
pt_info->read_base_addr = info.valid_read_addr;
pt_info->write_base_addr = info.valid_write_addr;
BOOT_DEBUG_INFO("read = 0x%X, write = 0x%X.\n", pt_info->read_base_addr, pt_info->write_base_addr);
BOOT_DEBUG_INFO("info.both_valid_flag = %d.\n", info.both_valid_flag);
if(INVLID != info.both_valid_flag)
{
flash_read(pt_info->read_base_addr, dual_info_size, &ret_len, (unsigned char *)&dual_info);
}
printf_dual_image_info(&dual_info, E_BOOT_NO_INFO_LEVLE, __LINE__);
offset_to_dual_image_info(pt_info, &dual_info);
memcpy(dual_info.check_info.vendor, FH_NW_PRODUCT_VENDOR_DEFINE, FH_NW_PRODUCT_CHECK_VENDOR_SIZE);
if(dual_info.check_info.magic != 0xFFFF)
{
dual_info.check_info.magic += 1;
}
else
{
dual_info.check_info.magic = 0;
}
printf_dual_image_info(&dual_info, E_BOOT_NO_INFO_LEVLE, __LINE__);
check_data_size = (dual_info_size - sizeof(unsigned int));
crc_check_sum = crc32buf((char *)&dual_info, check_data_size, 1);
dual_info.check_info.crc_check = crc_check_sum;
printf_dual_image_info(&dual_info, E_BOOT_NO_INFO_LEVLE, __LINE__);
flash_erase(pt_info->write_base_addr, FH_NW_PRODUCT_BLOCK_SIZE);
flash_write(pt_info->write_base_addr, dual_info_size, &ret_len, (const unsigned char *)&dual_info);
return E_PERSONALITY_PARM_RIGHT_EXECUTE;
}
/*********************************************************************************/
static int set_flash_env_entry(personality_parm_t* pt_info)
{
int iret = E_PERSONALITY_PARM_RIGHT_EXECUTE;
unsigned char flag = 0;
unsigned long value = 0;
unsigned long ret_len = 0;
unsigned long check_data_size = 0;
unsigned int crc_check_sum = 0;
personality_parm_cmd_base_addr_t info;
flash_env_personality_parm_partition_info_t env_info;
unsigned long env_info_size = sizeof(flash_env_personality_parm_partition_info_t);
memset(&info, 0, sizeof(info));
memset(&env_info, 0, sizeof(env_info));
info.read_base_addr = pt_info->read_base_addr;
info.write_base_addr = pt_info->write_base_addr;
iret = personality_parm_get_partition_valid(&info);
if(0 != iret)
{
return E_PERSONALITY_PARM_INVALID_ARGUMENT;
}
pt_info->read_base_addr = info.valid_read_addr;
pt_info->write_base_addr = info.valid_write_addr;
BOOT_DEBUG_INFO("read = 0x%X, write = 0x%X\n", pt_info->read_base_addr, pt_info->write_base_addr);
BOOT_DEBUG_INFO("info.both_valid_flag = %d.\n", info.both_valid_flag);
if(INVLID != info.both_valid_flag)
{
flash_read(pt_info->read_base_addr, env_info_size, &ret_len, (unsigned char *)&env_info);
}
else
{
strcpy(env_info.env.sn_oui, "00");
strcpy(env_info.env.eth_addr, "00:0A:C2:12:34:56");
strcpy(env_info.env.hw_cfg, "0x77");
}
/*****************************************************************************************/
printf_flash_env_info(&env_info, E_BOOT_NO_INFO_LEVLE, __LINE__);
memset((unsigned char *)&env_info.env + pt_info->v_offset, 0, FH_NW_PRODUCT_ENV_SIZE);
strcpy((unsigned char *)&env_info.env + pt_info->v_offset, pt_info->element.env);
printf_flash_env_info(&env_info, E_BOOT_NO_INFO_LEVLE, __LINE__);
memcpy(env_info.check_info.vendor, FH_NW_PRODUCT_VENDOR_DEFINE, FH_NW_PRODUCT_CHECK_VENDOR_SIZE);
BOOT_DEBUG_INFO("check_info.magic = 0x%X.\n", env_info.check_info.magic);
if(env_info.check_info.magic != 0xFFFF)
{
env_info.check_info.magic += 1;
}
else
{
env_info.check_info.magic = 0;
}
printf_flash_env_info(&env_info, E_BOOT_NO_INFO_LEVLE, __LINE__);
check_data_size = (env_info_size - sizeof(unsigned int));
crc_check_sum = crc32buf((char *)&env_info, check_data_size, 1);
env_info.check_info.crc_check = crc_check_sum;
printf_flash_env_info(&env_info, E_BOOT_NO_INFO_LEVLE, __LINE__);
flash_erase(pt_info->write_base_addr, FH_NW_PRODUCT_BLOCK_SIZE);
flash_write(pt_info->write_base_addr, env_info_size, &ret_len, (const unsigned char *)&env_info);
return E_PERSONALITY_PARM_RIGHT_EXECUTE;
}
static int get_flash_env_entry(personality_parm_t* pt_info)
{
int iret = E_PERSONALITY_PARM_RIGHT_EXECUTE;
unsigned char flag = 0;
unsigned long value = 0;
unsigned long ret_len = 0;
personality_parm_cmd_base_addr_t info;
flash_env_personality_parm_partition_info_t env_info;
unsigned long env_info_size = sizeof(env_info);
memset(&info, 0, sizeof(info));
memset(&env_info, 0, sizeof(env_info));
info.read_base_addr = pt_info->read_base_addr;
info.write_base_addr = pt_info->write_base_addr;
iret = personality_parm_get_partition_valid(&info);
if(0 != iret)
{
return E_PERSONALITY_PARM_INVALID_ARGUMENT;
}
/*default value*/
if(INVLID == info.both_valid_flag)
{
switch(pt_info->v_offset)
{
case FH_FLASH_SNOUI_OFFSET:
{
strcpy(pt_info->element.env, "00");
break;
}
case FH_FLASH_HWCFG_OFFSET:
{
strcpy(pt_info->element.env, "0x77");
break;
}
case FH_FLASH_ETHADDR_OFFSET:
{
strcpy(pt_info->element.env, "00:0A:C2:12:34:56");
break;
}
default:
{
break;
}
}
}
else
{
pt_info->read_base_addr = info.valid_read_addr;
pt_info->write_base_addr = info.valid_write_addr;
BOOT_DEBUG_INFO("read = 0x%X, write = 0x%X.\n", pt_info->read_base_addr, pt_info->write_base_addr);
flash_read(pt_info->read_base_addr, env_info_size, &ret_len, (unsigned char *)&env_info);
memcpy(pt_info->element.env, (unsigned char *)&env_info.env + pt_info->v_offset, FH_NW_PRODUCT_ENV_SIZE);
}
return E_PERSONALITY_PARM_RIGHT_EXECUTE;
}
/*********************************************************************************/
int read_fh_nw_product_dual_image_flag_env(dual_image_flag_t *pt_info)
{
int iret = 0;
unsigned char flag = 0;
unsigned long value = 0;
unsigned long ret_len = 0;
personality_parm_cmd_base_addr_t info;
if(NULL == pt_info)
{
return -1;
}
memset(&info, 0, sizeof(info));
info.read_base_addr = FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR;
info.write_base_addr = FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR;
iret = personality_parm_get_partition_valid(&info);
if(0 != iret)
{
return -1;
}
/*default value*/
if(INVLID != info.both_valid_flag)
{
BOOT_DEBUG_INFO("read = 0x%X, write = 0x%X\n", info.valid_read_addr, info.valid_write_addr, __LINE__);
flash_read(info.valid_read_addr, sizeof(dual_image_flag_t), &ret_len, (unsigned char *)pt_info);
}
return 0;
}
int read_fh_nw_product_flash_env(personality_parm_flash_env_t *pt_info)
{
int iret = 0;
unsigned long ret_len = 0;
personality_parm_cmd_base_addr_t info;
if(NULL == pt_info)
{
return -1;
}
memset(&info, 0, sizeof(info));
info.read_base_addr = FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR;
info.write_base_addr = FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR;
iret = personality_parm_get_partition_valid(&info);
if(0 != iret)
{
return -1;
}
/*default value*/
if(INVLID != info.both_valid_flag)
{
BOOT_DEBUG_INFO("read = 0x%X, write = 0x%X\n", info.valid_read_addr, info.valid_write_addr, __LINE__);
flash_read(info.valid_read_addr, sizeof(personality_parm_flash_env_t), &ret_len, (unsigned char *)pt_info);
}
else
{
strcpy(pt_info->eth_addr, "00:0A:C2:12:34:56");
strcpy(pt_info->hw_cfg, "0x77");
strcpy(pt_info->sn_oui, "00");
}
return 0;
}
int read_fh_nw_product_memory_env(personality_parm_memory_env_t *pt_info)
{
int iret = 0;
unsigned int i = 0;
unsigned char buffer[FH_NW_PRODUCT_ENV_SIZE];
personality_parm_cmd_base_addr_t info;
memset(buffer, 0, sizeof(buffer));
memset(&info, 0, sizeof(info));
if(NULL == pt_info)
{
return -1;
}
/*bootversion*/
for(i=0; i <(FH_NW_PRODUCT_ENV_SIZE -1); i++)
{
buffer[i] = READ_FLASH_BYTE(flash_base+0xff04 + i);
}
buffer[i] = '\0';
memcpy(&pt_info->boot_version, buffer, FH_NW_PRODUCT_ENV_SIZE);
info.read_base_addr = FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR;
info.write_base_addr = FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR;
iret = personality_parm_get_partition_valid(&info);
if(0 != iret)
{
return -1;
}
if(FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR == info.valid_read_addr)
{
strcpy(&pt_info->m_reserve0, PERSONALITY_PARM_DUAL_IMAGE_READ_PARTITION);
}
else
{
strcpy(&pt_info->m_reserve0, PERSONALITY_PARM_DUAL_IMAGE_WRITE_PARTITION);
}
return 0;
}
static const personality_parm_table_t g_personality_parm_tab_b[]=
{
{"set", "commit", "kernel", E_FH_NW_PRODUCT_SET_COMMIT_KERNEL, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, KERNEL_COMMIT_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, NULL, set_dual_image_entry},
{"set", "commit", "rootfs", E_FH_NW_PRODUCT_SET_COMMIT_ROOTFS, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, ROOTFS_COMMIT_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, NULL, set_dual_image_entry},
{"set", "commit", "app1", E_FH_NW_PRODUCT_SET_COMMIT_APP1, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, APP1_COMMIT_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, NULL, set_dual_image_entry},
{"set", "commit", "app2", E_FH_NW_PRODUCT_SET_COMMIT_APP2, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, APP2_COMMIT_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, NULL, set_dual_image_entry},
{"get", "commit", "kernel", E_FH_NW_PRODUCT_GET_COMMIT_KERNEL, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, KERNEL_COMMIT_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, get_dual_image_entry, NULL},
{"get", "commit", "rootfs", E_FH_NW_PRODUCT_GET_COMMIT_ROOTFS, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, ROOTFS_COMMIT_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, get_dual_image_entry, NULL},
{"get", "commit", "app1", E_FH_NW_PRODUCT_GET_COMMIT_APP1, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, APP1_COMMIT_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, get_dual_image_entry, NULL},
{"get", "commit", "app2", E_FH_NW_PRODUCT_GET_COMMIT_APP2, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, APP2_COMMIT_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, get_dual_image_entry, NULL},
{"set", "active", "kernel", E_FH_NW_PRODUCT_SET_ACTIVE_KERNEL, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, KERNEL_ACTIVE_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, NULL, set_dual_image_entry},
{"set", "active", "rootfs", E_FH_NW_PRODUCT_SET_ACTIVE_ROOTFS, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, ROOTFS_ACTIVE_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, NULL, set_dual_image_entry},
{"set", "active", "app1", E_FH_NW_PRODUCT_SET_ACTIVE_APP1, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, APP1_ACTIVE_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, NULL, set_dual_image_entry},
{"set", "active", "app2", E_FH_NW_PRODUCT_SET_ACTIVE_APP2, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, APP2_ACTIVE_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, NULL, set_dual_image_entry},
{"get", "active", "kernel", E_FH_NW_PRODUCT_GET_ACTIVE_KERNEL, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, KERNEL_ACTIVE_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, get_dual_image_entry, NULL},
{"get", "active", "rootfs", E_FH_NW_PRODUCT_GET_ACTIVE_ROOTFS, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, ROOTFS_ACTIVE_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, get_dual_image_entry, NULL},
{"get", "active", "app1", E_FH_NW_PRODUCT_GET_ACTIVE_APP1, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, APP1_ACTIVE_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, get_dual_image_entry, NULL},
{"get", "active", "app2", E_FH_NW_PRODUCT_GET_ACTIVE_APP2, FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR, FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR, APP2_ACTIVE_OFFSET, FH_NW_PRODUCT_DUAL_IMAGE_FLAG_SIZE, get_dual_image_entry, NULL},
{"set", "snoui", NULL, E_FH_NW_PRODUCT_SET_SNOUI, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_SNOUI_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "hwcfg", NULL, E_FH_NW_PRODUCT_SET_HWCFG, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_HWCFG_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "ethaddr", NULL, E_FH_NW_PRODUCT_SET_ETHERADDR, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_ETHADDR_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve0", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE0, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE0_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve1", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE1, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE1_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve2", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE2, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE2_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve3", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE3, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE3_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve4", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE4, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE4_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve5", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE5, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE5_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve6", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE6, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE6_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve7", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE7, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE7_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve8", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE8, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE8_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve9", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE9, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE9_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve10", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE10, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE10_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve11", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE11, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE11_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve12", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE12, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE12_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve13", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE13, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE13_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve14", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE14, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE14_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve15", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE15, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE15_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve16", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE16, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE16_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve17", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE17, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE17_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve18", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE18, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE18_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"set", "reserve19", NULL, E_FH_NW_PRODUCT_SET_FLASH_ENV_RESERVE19, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE19_OFFSET, FH_NW_PRODUCT_ENV_SIZE, NULL, set_flash_env_entry},
{"get", "snoui", NULL, E_FH_NW_PRODUCT_GET_SNOUI, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_SNOUI_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "hwcfg", NULL, E_FH_NW_PRODUCT_GET_HWCFG, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_HWCFG_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "ethaddr", NULL, E_FH_NW_PRODUCT_GET_ETHERADDR, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_ETHADDR_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve0", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE0, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE0_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve1", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE1, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE1_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve2", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE2, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE2_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve3", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE3, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE3_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve4", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE4, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE4_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve5", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE5, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE5_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve6", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE6, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE6_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve7", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE7, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE7_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve8", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE8, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE8_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve9", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE9, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE9_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve10", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE10, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE10_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve11", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE11, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE11_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve12", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE12, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE12_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve13", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE13, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE13_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve14", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE14, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE14_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve15", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE15, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE15_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve16", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE16, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE16_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve17", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE17, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE17_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve18", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE18, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE18_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
{"get", "reserve19", NULL, E_FH_NW_PRODUCT_GET_FLASH_ENV_RESERVE19, FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR, FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR, FH_FLASH_RESERVE19_OFFSET, FH_NW_PRODUCT_ENV_SIZE, get_flash_env_entry, NULL},
};
#define MAX_PERSONALITY_PARM_TABLE_b_SIZE ((sizeof(g_personality_parm_tab_b)) / (sizeof(personality_parm_table_t)))
static int do_stop_restart(int argc, char *argv[])
{
restart_time_flags = 0;
printf("stop bootloader success\n");
return 0;
}
static int do_personality_parm_cmd(int argc, char *argv[])
{
int iret = E_PERSONALITY_PARM_RIGHT_EXECUTE;
unsigned int i = 0;
unsigned int cmd_len = 0;
unsigned char flag = 0;
unsigned long cmd_value = 0;
personality_parm_t info;
printf("\n enter do_personality_parm_cmd.\n");
for(i=0; ((i<MAX_PERSONALITY_PARM_TABLE_b_SIZE) && (NULL != g_personality_parm_tab_b[i].action_cmd)); i++)
{
if((0 == strcmp(g_personality_parm_tab_b[i].action_cmd, argv[1])) && (0 == strcmp(g_personality_parm_tab_b[i].node_name, argv[2])))
{
if(0 == strcmp(g_personality_parm_tab_b[i].action_cmd, "set") && (NULL != g_personality_parm_tab_b[i].set_func))
{
/*dual image flag*/
if(((0 == strcmp(g_personality_parm_tab_b[i].node_name, "commit")) || (0 == strcmp(g_personality_parm_tab_b[i].node_name, "active"))) \
&& (0 == strcmp(g_personality_parm_tab_b[i].sub_node_name, argv[3])))
{
if(argc < 5)
{
printf("please check parm.\n");
return 0;
}
cmd_value = strtoul((const char*)(argv[4]), (char **)NULL, 16);
iret = dual_image_offset_convert_value(g_personality_parm_tab_b[i].offset, cmd_value, &flag);
if(E_PERSONALITY_PARM_RIGHT_EXECUTE != iret)
{
printf("invaild argument error.line = %d.\n", __LINE__);
return E_PERSONALITY_PARM_INVALID_ARGUMENT;
}
memset(&info, 0, sizeof(info));
info.read_base_addr = g_personality_parm_tab_b[i].read_base_addr;
info.write_base_addr = g_personality_parm_tab_b[i].write_base_addr;
info.v_offset = g_personality_parm_tab_b[i].offset;
info.v_size = g_personality_parm_tab_b[i].size;
info.element.dual_image_flag = (flag & FH_NW_PRODUCT_DUAL_IMAGE_MASK);
iret = g_personality_parm_tab_b[i].set_func(&info);
if(E_PERSONALITY_PARM_RIGHT_EXECUTE != iret)
{
printf("set %s %s execute fail.\n", g_personality_parm_tab_b[i].node_name, g_personality_parm_tab_b[i].sub_node_name);
}
else
{
printf("set %s %s execute success.\n", g_personality_parm_tab_b[i].node_name, g_personality_parm_tab_b[i].sub_node_name);
}
return iret;
}
else if((0 == strcmp(g_personality_parm_tab_b[i].node_name, argv[2])) && ((0 != strcmp(g_personality_parm_tab_b[i].node_name, "commit")) && (0 != strcmp(g_personality_parm_tab_b[i].node_name, "active"))))
{
memset(&info, 0, sizeof(info));
cmd_len = 0;
info.read_base_addr = g_personality_parm_tab_b[i].read_base_addr;
info.write_base_addr = g_personality_parm_tab_b[i].write_base_addr;
info.v_offset = g_personality_parm_tab_b[i].offset;
info.v_size = g_personality_parm_tab_b[i].size;
if(argc < 4)
{
printf("please check parm.\n");
return 0;
}
cmd_len = strlen(argv[3]);
if(cmd_len >= (FH_NW_PRODUCT_ENV_SIZE - 1))
{
memcpy(info.element.env, argv[3], (FH_NW_PRODUCT_ENV_SIZE-1));
info.element.env[FH_NW_PRODUCT_ENV_SIZE-1] = '\0';
}
else
{
strcpy(info.element.env, argv[3]);
}
iret = g_personality_parm_tab_b[i].set_func(&info);
if(E_PERSONALITY_PARM_RIGHT_EXECUTE != iret)
{
printf("set %s %s execute fail.\n", g_personality_parm_tab_b[i].node_name, info.element.env);
}
else
{
printf("set %s %s execute success.\n", g_personality_parm_tab_b[i].node_name, info.element.env);
}
return iret;
}
else
{
continue;
}
}
else if(0 == strcmp(g_personality_parm_tab_b[i].action_cmd, "get") && (NULL != g_personality_parm_tab_b[i].get_func))
{
/*dual image get*/
if(((0 == strcmp(g_personality_parm_tab_b[i].node_name, "commit")) || (0 == strcmp(g_personality_parm_tab_b[i].node_name, "active"))) \
&& (0 == strcmp(g_personality_parm_tab_b[i].sub_node_name, argv[3])))
{
memset(&info, 0, sizeof(info));
info.read_base_addr = g_personality_parm_tab_b[i].read_base_addr;
info.write_base_addr = g_personality_parm_tab_b[i].write_base_addr;
info.v_offset = g_personality_parm_tab_b[i].offset;
info.v_size = g_personality_parm_tab_b[i].size;
iret = g_personality_parm_tab_b[i].get_func(&info);
if(E_PERSONALITY_PARM_RIGHT_EXECUTE != iret)
{
printf("get %s %s execute fail.\n", g_personality_parm_tab_b[i].node_name, g_personality_parm_tab_b[i].sub_node_name);
}
else
{
printf("get %s %s = %d execute success.\n", g_personality_parm_tab_b[i].node_name, g_personality_parm_tab_b[i].sub_node_name, info.element.dual_image_flag);
}
return iret;
}
else if((0 == strcmp(g_personality_parm_tab_b[i].node_name, argv[2])) && ((0 != strcmp(g_personality_parm_tab_b[i].node_name, "commit")) && (0 != strcmp(g_personality_parm_tab_b[i].node_name, "active"))))
{
memset(&info, 0, sizeof(info));
info.read_base_addr = g_personality_parm_tab_b[i].read_base_addr;
info.write_base_addr = g_personality_parm_tab_b[i].write_base_addr;
info.v_offset = g_personality_parm_tab_b[i].offset;
info.v_size = g_personality_parm_tab_b[i].size;
iret = g_personality_parm_tab_b[i].get_func(&info);
if(E_PERSONALITY_PARM_RIGHT_EXECUTE != iret)
{
printf("get %s execute fail.\n", g_personality_parm_tab_b[i].node_name);
}
else
{
printf("get %s = %s execute success.\n", g_personality_parm_tab_b[i].node_name, info.element.env);
}
return iret;
}
else
{
continue;
}
}
}
}
return E_PERSONALITY_PARM_RIGHT_EXECUTE;
}
static int do_show_all_dual_image_flag_info(void)
{
int iret = E_PERSONALITY_PARM_RIGHT_EXECUTE;
unsigned char flag = 0;
unsigned long ret_len = 0;
personality_parm_cmd_base_addr_t info;
dual_image_personality_parm_partition_info_t dual_info;
unsigned long dual_info_size = sizeof(dual_image_personality_parm_partition_info_t);
memset(&dual_info, 0, sizeof(dual_info));
memset(&info, 0, sizeof(info));
info.read_base_addr = FH_NW_PRODUCT_DUAL_IMAGE_READ_BASE_ADDR;
info.write_base_addr = FH_NW_PRODUCT_DUAL_IMAGE_WRITE_BASE_ADDR;
iret = personality_parm_get_partition_valid(&info);
if(0 != iret)
{
return E_PERSONALITY_PARM_INVALID_ARGUMENT;
}
/*default value*/
if(INVLID == info.both_valid_flag)
{
memset(&dual_info, 0, sizeof(dual_info));
}
else
{
flash_read(info.valid_read_addr, dual_info_size, &ret_len, (unsigned char *)&dual_info);
}
printf_dual_image_info(&dual_info, E_BOOT_DEBUG_INFO_LEVLE, __LINE__);
return E_PERSONALITY_PARM_RIGHT_EXECUTE;
}
static int do_show_all_flash_env_info(void)
{
int iret = E_PERSONALITY_PARM_RIGHT_EXECUTE;
unsigned long ret_len = 0;
personality_parm_cmd_base_addr_t info;
flash_env_personality_parm_partition_info_t env_info;
unsigned long env_info_size = sizeof(env_info);
memset(&info, 0, sizeof(info));
memset(&env_info, 0, sizeof(env_info));
info.read_base_addr = FH_NW_PRODUCT_FLASH_ENV_READ_BASE_ADDR;
info.write_base_addr = FH_NW_PRODUCT_FLASH_ENV_WRITE_BASE_ADDR;
iret = personality_parm_get_partition_valid(&info);
if(0 != iret)
{
return E_PERSONALITY_PARM_INVALID_ARGUMENT;
}
/*default value*/
if(INVLID == info.both_valid_flag)
{
printf("default value.\n");
printf("snoui = 00.\n");
printf("hwcfg = 0x77.\n");
printf("ethaddr = 00:0A:C2:12:34:56.\n");
}
else
{
flash_read(info.valid_read_addr, env_info_size, &ret_len, (unsigned char *)&env_info);
printf_flash_env_info(&env_info, E_BOOT_DEBUG_INFO_LEVLE, __LINE__);
}
return E_PERSONALITY_PARM_RIGHT_EXECUTE;
}
#endif