diff options
author | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-09-05 13:11:49 +0200 |
---|---|---|
committer | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-09-05 13:11:49 +0200 |
commit | e00be03fe04b2164d06a904f2117234ab8d384f6 (patch) | |
tree | ab3e6b3a20267fae4530fe5f14e4a6500a017ba7 | |
parent | 4d872fb09a33a5db3068a759949c33b93d23b801 (diff) | |
download | barebox-e00be03fe04b2164d06a904f2117234ab8d384f6.tar.gz barebox-e00be03fe04b2164d06a904f2117234ab8d384f6.tar.xz |
Remove all unused files from common. They can be added later from
U-Boot 1.x when needed.
52 files changed, 0 insertions, 22318 deletions
diff --git a/common/ACEX1K.c b/common/ACEX1K.c deleted file mode 100644 index 97ea6cb0f1..0000000000 --- a/common/ACEX1K.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * (C) Copyright 2003 - * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de - * - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include <common.h> /* core U-Boot definitions */ -#include <ACEX1K.h> /* ACEX device family */ - -#if (CONFIG_FPGA & (CFG_ALTERA | CFG_ACEX1K)) - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Note: The assumption is that we cannot possibly run fast enough to - * overrun the device (the Slave Parallel mode can free run at 50MHz). - * If there is a need to operate slower, define CONFIG_FPGA_DELAY in - * the board config file to slow things down. - */ -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CFG_FPGA_WAIT -#define CFG_FPGA_WAIT CFG_HZ/10 /* 100 ms */ -#endif - -static int ACEX1K_ps_load( Altera_desc *desc, void *buf, size_t bsize ); -static int ACEX1K_ps_dump( Altera_desc *desc, void *buf, size_t bsize ); -/* static int ACEX1K_ps_info( Altera_desc *desc ); */ -static int ACEX1K_ps_reloc( Altera_desc *desc, ulong reloc_offset ); - -/* ------------------------------------------------------------------------- */ -/* ACEX1K Generic Implementation */ -int ACEX1K_load (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__); - ret_val = ACEX1K_ps_load (desc, buf, bsize); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int ACEX1K_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__); - ret_val = ACEX1K_ps_dump (desc, buf, bsize); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int ACEX1K_info( Altera_desc *desc ) -{ - return FPGA_SUCCESS; -} - - -int ACEX1K_reloc (Altera_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (desc->family != Altera_ACEX1K) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case passive_serial: - ret_val = ACEX1K_ps_reloc (desc, reloc_offset); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - - -/* ------------------------------------------------------------------------- */ -/* ACEX1K Passive Serial Generic Implementation */ - -static int ACEX1K_ps_load (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Altera_ACEX1K_Passive_Serial_fns *fn = desc->iface_fns; - int i; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "config:\t0x%p\n" - "status:\t0x%p\n" - "clk:\t0x%p\n" - "data:\t0x%p\n" - "done:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->config, fn->status, - fn->clk, fn->data, fn->done); -#ifdef CFG_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...", cookie); -#endif - - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->config) (TRUE, TRUE, cookie); /* Assert nCONFIG */ - - udelay(2); /* T_cfg > 2us */ - - /* nSTATUS should be asserted now */ - (*fn->done) (cookie); - if ( !(*fn->status) (cookie) ) { - puts ("** nSTATUS is not asserted.\n"); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - - (*fn->config) (FALSE, TRUE, cookie); /* Deassert nCONFIG */ - udelay(2); /* T_cf2st1 < 4us */ - - /* Wait for nSTATUS to be released (i.e. deasserted) */ - ts = get_timer (0); /* get current time */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for STATUS to go high.\n"); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - (*fn->done) (cookie); - } while ((*fn->status) (cookie)); - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - - /* Load the data */ - while (bytecount < bsize) { - unsigned char val=0; -#ifdef CFG_FPGA_CHECK_CTRLC - if (ctrlc ()) { - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#endif - /* Altera detects an error if INIT goes low (active) - while DONE is low (inactive) */ - val = data [bytecount ++ ]; - i = 8; - do { - /* Deassert the clock */ - (*fn->clk) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Write data */ - (*fn->data) ( (val & 0x01), TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Assert the clock */ - (*fn->clk) (TRUE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - val >>= 1; - i --; - } while (i > 0); - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc (' '); /* terminate the dotted line */ -#endif - - /* - * Checking FPGA's CONF_DONE signal - correctly booted ? - */ - - if ( ! (*fn->done) (cookie) ) { - puts ("** Booting failed! CONF_DONE is still deasserted.\n"); - (*fn->abort) (cookie); - return (FPGA_FAIL); - } - - /* - * "DCLK must be clocked an additional 10 times fpr ACEX 1K..." - */ - - for (i = 0; i < 12; i++) { - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - } - - ret_val = FPGA_SUCCESS; - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) { - puts ("Done.\n"); - } - else { - puts ("Fail.\n"); - } -#endif - (*fn->post) (cookie); - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int ACEX1K_ps_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - /* Readback is only available through the Slave Parallel and */ - /* boundary-scan interfaces. */ - printf ("%s: Passive Serial Dumping is unavailable\n", - __FUNCTION__); - return FPGA_FAIL; -} - -static int ACEX1K_ps_reloc (Altera_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Altera_ACEX1K_Passive_Serial_fns *fn_r, *fn = - (Altera_ACEX1K_Passive_Serial_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Altera_ACEX1K_Passive_Serial_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Altera_ACEX1K_Passive_Serial_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Altera_pre_fn) addr; - - addr = (ulong) (fn->config) + reloc_offset; - fn_r->config = (Altera_config_fn) addr; - - addr = (ulong) (fn->status) + reloc_offset; - fn_r->status = (Altera_status_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Altera_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Altera_clk_fn) addr; - - addr = (ulong) (fn->data) + reloc_offset; - fn_r->data = (Altera_data_fn) addr; - - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Altera_abort_fn) addr; - - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Altera_post_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} - -#endif /* (CONFIG_FPGA & (CFG_ALTERA | CFG_ACEX1K)) */ diff --git a/common/Makefile b/common/Makefile index c1b464851c..df1ccdd0f1 100644 --- a/common/Makefile +++ b/common/Makefile @@ -13,63 +13,3 @@ obj-y += env.o obj-y += startup.o obj-y += misc.o obj-y += memsize.o - -#obj-y += cmd_elf.o -#obj-y += cmd_itest.o -#obj-y += cmd_usb.o -#obj-y += docecc.o -#obj-y += usb.o -#obj-y += cmd_cache.o -#obj-y += cmd_ext2.o -#obj-y += cmd_jffs2.o -#obj-y += cmd_vfd.o -#obj-y += usb_kbd.o -#obj-y += bedbug.o -#obj-y += cmd_fat.o -#obj-y += cmd_pci.o -#obj-y += cmd_ximg.o -#obj-y += miiphybb.o -#obj-y += usb_storage.o -#obj-y += circbuf.o -#obj-y += cmd_date.o -#obj-y += cmd_fdc.o -#obj-y += cmd_log.o -#obj-y += cmd_pcmcia.o -#obj-y += virtex2.o -#obj-y += cmd_ace.o -#obj-y += cmd_dcr.o -#obj-y += cmd_fdos.o -#obj-y += cmd_mac.o -#obj-y += cmd_portio.o -#obj-y += serial.o -#obj-y += cmd_diag.o -#obj-y += cmd_reginfo.o -#obj-y += kgdb.o -#obj-y += soft_i2c.o -#obj-y += cmd_bdinfo.o -#obj-y += cmd_display.o -#obj-y += cmd_fpga.o -#obj-y += cmd_reiser.o -#obj-y += lcd.o -#obj-y += soft_spi.o -#obj-y += cmd_bedbug.o -#obj-y += cmd_doc.o -#obj-y += cmd_misc.o -#obj-y += cmd_scsi.o -#obj-y += cmd_bmp.o -#obj-y += cmd_dtt.o -#obj-y += cmd_ide.o -#obj-y += cmd_mmc.o -#obj-y += cmd_spi.o -#obj-y += lynxkdi.o -#obj-y += cmd_eeprom.o -#obj-y += cmd_immap.o -#obj-y += cmd_nand.o -#obj-y += cmd_universe.o -#obj-y += spartan3.o -#obj-y += spartan2.o -#obj-y += ACEX1K.o -#obj-y += xilinx.o -#obj-y += fpga.o -#obj-y += altera.o -#obj-y += cyclon2.o diff --git a/common/altera.c b/common/altera.c deleted file mode 100644 index 06e8a95015..0000000000 --- a/common/altera.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * (C) Copyright 2003 - * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de - * - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Altera FPGA support - */ -#include <common.h> -#include <ACEX1K.h> - -/* Define FPGA_DEBUG to get debug printf's */ -/* #define FPGA_DEBUG */ - -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -#if (CONFIG_FPGA & CFG_FPGA_ALTERA) - -/* Local Static Functions */ -static int altera_validate (Altera_desc * desc, char *fn); - -/* ------------------------------------------------------------------------- */ -int altera_load( Altera_desc *desc, void *buf, size_t bsize ) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!altera_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else { - switch (desc->family) { - case Altera_ACEX1K: - case Altera_CYC2: -#if (CONFIG_FPGA & CFG_ACEX1K) - PRINTF ("%s: Launching the ACEX1K Loader...\n", - __FUNCTION__); - ret_val = ACEX1K_load (desc, buf, bsize); -#elif (CONFIG_FPGA & CFG_CYCLON2) - PRINTF ("%s: Launching the CYCLON II Loader...\n", - __FUNCTION__); - ret_val = CYC2_load (desc, buf, bsize); -#else - printf ("%s: No support for ACEX1K devices.\n", - __FUNCTION__); -#endif - break; - - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - } - - return ret_val; -} - -int altera_dump( Altera_desc *desc, void *buf, size_t bsize ) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!altera_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else { - switch (desc->family) { - case Altera_ACEX1K: -#if (CONFIG_FPGA & CFG_ACEX) - PRINTF ("%s: Launching the ACEX1K Reader...\n", - __FUNCTION__); - ret_val = ACEX1K_dump (desc, buf, bsize); -#else - printf ("%s: No support for ACEX1K devices.\n", - __FUNCTION__); -#endif - break; - - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - } - - return ret_val; -} - -int altera_info( Altera_desc *desc ) -{ - int ret_val = FPGA_FAIL; - - if (altera_validate (desc, (char *)__FUNCTION__)) { - printf ("Family: \t"); - switch (desc->family) { - case Altera_ACEX1K: - printf ("ACEX1K\n"); - break; - /* Add new family types here */ - case Altera_CYC2: - printf ("CYCLON II\n"); - break; - default: - printf ("Unknown family type, %d\n", desc->family); - } - - printf ("Interface type:\t"); - switch (desc->iface) { - case passive_serial: - printf ("Passive Serial (PS)\n"); - break; - case passive_parallel_synchronous: - printf ("Passive Parallel Synchronous (PPS)\n"); - break; - case passive_parallel_asynchronous: - printf ("Passive Parallel Asynchronous (PPA)\n"); - break; - case passive_serial_asynchronous: - printf ("Passive Serial Asynchronous (PSA)\n"); - break; - case altera_jtag_mode: /* Not used */ - printf ("JTAG Mode\n"); - break; - /* Add new interface types here */ - default: - printf ("Unsupported interface type, %d\n", desc->iface); - } - - printf ("Device Size: \t%d bytes\n" - "Cookie: \t0x%x (%d)\n", - desc->size, desc->cookie, desc->cookie); - - if (desc->iface_fns) { - printf ("Device Function Table @ 0x%p\n", desc->iface_fns); - switch (desc->family) { - case Altera_ACEX1K: - case Altera_CYC2: -#if (CONFIG_FPGA & CFG_ACEX1K) - ACEX1K_info (desc); -#elif (CONFIG_FPGA & CFG_CYCLON2) - CYC2_info (desc); -#else - /* just in case */ - printf ("%s: No support for ACEX1K devices.\n", - __FUNCTION__); -#endif - break; - /* Add new family types here */ - default: - /* we don't need a message here - we give one up above */ - break; - } - } else { - printf ("No Device Function Table.\n"); - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } - - return ret_val; -} - -int altera_reloc( Altera_desc *desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!altera_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else { - switch (desc->family) { - case Altera_ACEX1K: -#if (CONFIG_FPGA & CFG_ACEX1K) - ret_val = ACEX1K_reloc (desc, reloc_offset); -#else - printf ("%s: No support for ACEX devices.\n", - __FUNCTION__); -#endif - break; - case Altera_CYC2: -#if (CONFIG_FPGA & CFG_CYCLON2) - ret_val = CYC2_reloc (desc, reloc_offset); -#else - printf ("%s: No support for CYCLON II devices.\n", - __FUNCTION__); -#endif - break; - /* Add new family types here */ - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - } - - return ret_val; -} - -/* ------------------------------------------------------------------------- */ - -static int altera_validate (Altera_desc * desc, char *fn) -{ - int ret_val = FALSE; - - if (desc) { - if ((desc->family > min_altera_type) && - (desc->family < max_altera_type)) { - if ((desc->iface > min_altera_iface_type) && - (desc->iface < max_altera_iface_type)) { - if (desc->size) { - ret_val = TRUE; - } else { - printf ("%s: NULL part size\n", fn); - } - } else { - printf ("%s: Invalid Interface type, %d\n", - fn, desc->iface); - } - } else { - printf ("%s: Invalid family type, %d\n", fn, desc->family); - } - } else { - printf ("%s: NULL descriptor!\n", fn); - } - - return ret_val; -} - -/* ------------------------------------------------------------------------- */ - -#endif /* CONFIG_FPGA & CFG_FPGA_ALTERA */ diff --git a/common/bedbug.c b/common/bedbug.c deleted file mode 100644 index 6966de7445..0000000000 --- a/common/bedbug.c +++ /dev/null @@ -1,1256 +0,0 @@ -/* $Id$ */ - -#include <common.h> - -#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) - -#include <linux/ctype.h> -#include <bedbug/bedbug.h> -#include <bedbug/ppc.h> -#include <bedbug/regs.h> -#include <bedbug/tables.h> - -#define Elf32_Word unsigned long - -/* USE_SOURCE_CODE enables some symbolic debugging functions of this - code. This is only useful if the program will have access to the - source code for the binary being examined. -*/ - -/* #define USE_SOURCE_CODE 1 */ - -#ifdef USE_SOURCE_CODE -extern int line_info_from_addr __P ((Elf32_Word, char *, char *, int *)); -extern struct symreflist *symByAddr; -extern char *symbol_name_from_addr __P ((Elf32_Word, int, int *)); -#endif /* USE_SOURCE_CODE */ - -int print_operands __P ((struct ppc_ctx *)); -int get_operand_value __P ((struct opcode *, unsigned long, - enum OP_FIELD, unsigned long *)); -struct opcode *find_opcode __P ((unsigned long)); -struct opcode *find_opcode_by_name __P ((char *)); -char *spr_name __P ((int)); -int spr_value __P ((char *)); -char *tbr_name __P ((int)); -int tbr_value __P ((char *)); -int parse_operand __P ((unsigned long, struct opcode *, - struct operand *, char *, int *)); -int get_word __P ((char **, char *)); -long read_number __P ((char *)); -int downstring __P ((char *)); - - -/*====================================================================== - * Entry point for the PPC disassembler. - * - * Arguments: - * memaddr The address to start disassembling from. - * - * virtual If this value is non-zero, then this will be - * used as the base address for the output and - * symbol lookups. If this value is zero then - * memaddr is used as the absolute address. - * - * num_instr The number of instructions to disassemble. Since - * each instruction is 32 bits long, this can be - * computed if you know the total size of the region. - * - * pfunc The address of a function that is called to print - * each line of output. The function should take a - * single character pointer as its parameters a la puts. - * - * flags Sets options for the output. This is a - * bitwise-inclusive-OR of the following - * values. Note that only one of the radix - * options may be set. - * - * F_RADOCTAL - output radix is unsigned base 8. - * F_RADUDECIMAL - output radix is unsigned base 10. - * F_RADSDECIMAL - output radix is signed base 10. - * F_RADHEX - output radix is unsigned base 16. - * F_SIMPLE - use simplified mnemonics. - * F_SYMBOL - lookup symbols for addresses. - * F_INSTR - output raw instruction. - * F_LINENO - show line # info if available. - * - * Returns TRUE if the area was successfully disassembled or FALSE if - * a problem was encountered with accessing the memory. - */ - -int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr, - int (*pfunc) (const char *), unsigned long flags) -{ - int i; - struct ppc_ctx ctx; - -#ifdef USE_SOURCE_CODE - int line_no = 0; - int last_line_no = 0; - char funcname[128] = { 0 }; - char filename[256] = { 0 }; - char last_funcname[128] = { 0 }; - int symoffset; - char *symname; - char *cursym = (char *) 0; -#endif /* USE_SOURCE_CODE */ - /*------------------------------------------------------------*/ - - ctx.flags = flags; - ctx.virtual = virtual; - - /* Figure out the output radix before we go any further */ - - if (ctx.flags & F_RADOCTAL) { - /* Unsigned octal output */ - strcpy (ctx.radix_fmt, "O%o"); - } else if (ctx.flags & F_RADUDECIMAL) { - /* Unsigned decimal output */ - strcpy (ctx.radix_fmt, "%u"); - } else if (ctx.flags & F_RADSDECIMAL) { - /* Signed decimal output */ - strcpy (ctx.radix_fmt, "%d"); - } else { - /* Unsigned hex output */ - strcpy (ctx.radix_fmt, "0x%x"); - } - - if (ctx.virtual == 0) { - ctx.virtual = memaddr; - } -#ifdef USE_SOURCE_CODE - if (ctx.flags & F_SYMBOL) { - if (symByAddr == 0) /* no symbols loaded */ - ctx.flags &= ~F_SYMBOL; - else { - cursym = (char *) 0; - symoffset = 0; - } - } -#endif /* USE_SOURCE_CODE */ - - /* format each line as "XXXXXXXX: <symbol> IIIIIIII disassembly" where, - XXXXXXXX is the memory address in hex, - <symbol> is the symbolic location if F_SYMBOL is set. - IIIIIIII is the raw machine code in hex if F_INSTR is set, - and disassembly is the disassembled machine code with numbers - formatted according to the 'radix' parameter */ - - for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) { -#ifdef USE_SOURCE_CODE - if (ctx.flags & F_LINENO) { - if ((line_info_from_addr ((Elf32_Word) ctx.virtual, filename, - funcname, &line_no) == TRUE) && - ((line_no != last_line_no) || - (strcmp (last_funcname, funcname) != 0))) { - print_source_line (filename, funcname, line_no, pfunc); - } - last_line_no = line_no; - strcpy (last_funcname, funcname); - } -#endif /* USE_SOURCE_CODE */ - - sprintf (ctx.data, "%08lx: ", (unsigned long) ctx.virtual); - ctx.datalen = 10; - -#ifdef USE_SOURCE_CODE - if (ctx.flags & F_SYMBOL) { - if ((symname = - symbol_name_from_addr ((Elf32_Word) ctx.virtual, - TRUE, 0)) != 0) { - cursym = symname; - symoffset = 0; - } else { - if ((cursym == 0) && - ((symname = - symbol_name_from_addr ((Elf32_Word) ctx.virtual, - FALSE, &symoffset)) != 0)) { - cursym = symname; - } else { - symoffset += 4; - } - } - - if (cursym != 0) { - sprintf (&ctx.data[ctx.datalen], "<%s+", cursym); - ctx.datalen = strlen (ctx.data); - sprintf (&ctx.data[ctx.datalen], ctx.radix_fmt, symoffset); - strcat (ctx.data, ">"); - ctx.datalen = strlen (ctx.data); - } - } -#endif /* USE_SOURCE_CODE */ - - ctx.instr = INSTRUCTION (memaddr); - - if (ctx.flags & F_INSTR) { - /* Find the opcode structure for this opcode. If one is not found - then it must be an illegal instruction */ - sprintf (&ctx.data[ctx.datalen], - " %02lx %02lx %02lx %02lx ", - ((ctx.instr >> 24) & 0xff), - ((ctx.instr >> 16) & 0xff), ((ctx.instr >> 8) & 0xff), - (ctx.instr & 0xff)); - ctx.datalen += 18; - } else { - strcat (ctx.data, " "); - ctx.datalen += 3; - } - - if ((ctx.op = find_opcode (ctx.instr)) == 0) { - /* Illegal Opcode */ - sprintf (&ctx.data[ctx.datalen], " .long 0x%08lx", - ctx.instr); - ctx.datalen += 24; - (*pfunc) (ctx.data); - continue; - } - - if (((ctx.flags & F_SIMPLE) == 0) || - (ctx.op->hfunc == 0) || ((*ctx.op->hfunc) (&ctx) == FALSE)) { - sprintf (&ctx.data[ctx.datalen], "%-7s ", ctx.op->name); - ctx.datalen += 8; - print_operands (&ctx); - } - - (*pfunc) (ctx.data); - } - - return TRUE; -} /* disppc */ - - - -/*====================================================================== - * Called by the disassembler to print the operands for an instruction. - * - * Arguments: - * ctx A pointer to the disassembler context record. - * - * always returns 0. - */ - -int print_operands (struct ppc_ctx *ctx) -{ - int open_parens = 0; - int field; - unsigned long operand; - struct operand *opr; - -#ifdef USE_SOURCE_CODE - char *symname; - int offset; -#endif /* USE_SOURCE_CODE */ - /*------------------------------------------------------------*/ - - /* Walk through the operands and list each in order */ - for (field = 0; ctx->op->fields[field] != 0; ++field) { - if (ctx->op->fields[field] > n_operands) { - continue; /* bad operand ?! */ - } - - opr = &operands[ctx->op->fields[field] - 1]; - - if (opr->hint & OH_SILENT) { - continue; - } - - if ((field > 0) && !open_parens) { - strcat (ctx->data, ","); - ctx->datalen++; - } - - operand = (ctx->instr >> opr->shift) & ((1 << opr->bits) - 1); - - if (opr->hint & OH_ADDR) { - if ((operand & (1 << (opr->bits - 1))) != 0) { - operand = operand - (1 << opr->bits); - } - - if (ctx->op->hint & H_RELATIVE) - operand = (operand << 2) + (unsigned long) ctx->virtual; - else - operand = (operand << 2); - - - sprintf (&ctx->data[ctx->datalen], "0x%lx", operand); - ctx->datalen = strlen (ctx->data); - -#ifdef USE_SOURCE_CODE - if ((ctx->flags & F_SYMBOL) && - ((symname = - symbol_name_from_addr (operand, 0, &offset)) != 0)) { - sprintf (&ctx->data[ctx->datalen], " <%s", symname); - if (offset != 0) { - strcat (ctx->data, "+"); - ctx->datalen = strlen (ctx->data); - sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt, - offset); - } - strcat (ctx->data, ">"); - } -#endif /* USE_SOURCE_CODE */ - } - - else if (opr->hint & OH_REG) { - if ((operand == 0) && - (opr->field == O_rA) && (ctx->op->hint & H_RA0_IS_0)) { - strcat (ctx->data, "0"); - } else { - sprintf (&ctx->data[ctx->datalen], "r%d", (short) operand); - } - - if (open_parens) { - strcat (ctx->data, ")"); - open_parens--; - } - } - - else if (opr->hint & OH_SPR) { - strcat (ctx->data, spr_name (operand)); - } - - else if (opr->hint & OH_TBR) { - strcat (ctx->data, tbr_name (operand)); - } - - else if (opr->hint & OH_LITERAL) { - switch (opr->field) { - case O_cr2: - strcat (ctx->data, "cr2"); - ctx->datalen += 3; - break; - - default: - break; - } - } - - else { - sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt, - (unsigned short) operand); - - if (open_parens) { - strcat (ctx->data, ")"); - open_parens--; - } - - else if (opr->hint & OH_OFFSET) { - strcat (ctx->data, "("); - open_parens++; - } - } - - ctx->datalen = strlen (ctx->data); - } - - return 0; -} /* print_operands */ - - - -/*====================================================================== - * Called to get the value of an arbitrary operand with in an instruction. - * - * Arguments: - * op The pointer to the opcode structure to which - * the operands belong. - * - * instr The instruction (32 bits) containing the opcode - * and the operands to print. By the time that - * this routine is called the operand has already - * been added to the output. - * - * field The field (operand) to get the value of. - * - * value The address of an unsigned long to be filled in - * with the value of the operand if it is found. This - * will only be filled in if the function returns - * TRUE. This may be passed as 0 if the value is - * not required. - * - * Returns TRUE if the operand was found or FALSE if it was not. - */ - -int get_operand_value (struct opcode *op, unsigned long instr, - enum OP_FIELD field, unsigned long *value) -{ - int i; - struct operand *opr; - - /*------------------------------------------------------------*/ - - if (field > n_operands) { - return FALSE; /* bad operand ?! */ - } - - /* Walk through the operands and list each in order */ - for (i = 0; op->fields[i] != 0; ++i) { - if (op->fields[i] != field) { - continue; - } - - opr = &operands[op->fields[i] - 1]; - - if (value) { - *value = (instr >> opr->shift) & ((1 << opr->bits) - 1); - } - return TRUE; - } - - return FALSE; -} /* operand_value */ - - - -/*====================================================================== - * Called by the disassembler to match an opcode value to an opcode structure. - * - * Arguments: - * instr The instruction (32 bits) to match. This value - * may contain operand values as well as the opcode - * since they will be masked out anyway for this - * search. - * - * Returns the address of an opcode struct (from the opcode table) if the - * operand successfully matched an entry, or 0 if no match was found. - */ - -struct opcode *find_opcode (unsigned long instr) -{ - struct opcode *ptr; - int top = 0; - int bottom = n_opcodes - 1; - int idx; - - /*------------------------------------------------------------*/ - - while (top <= bottom) { - idx = (top + bottom) >> 1; - ptr = &opcodes[idx]; - - if ((instr & ptr->mask) < ptr->opcode) { - bottom = idx - 1; - } else if ((instr & ptr->mask) > ptr->opcode) { - top = idx + 1; - } else { - return ptr; - } - } - - return (struct opcode *) 0; -} /* find_opcode */ - - - -/*====================================================================== - * Called by the assembler to match an opcode name to an opcode structure. - * - * Arguments: - * name The text name of the opcode, e.g. "b", "mtspr", etc. - * - * The opcodes are sorted numerically by their instruction binary code - * so a search for the name cannot use the binary search used by the - * other find routine. - * - * Returns the address of an opcode struct (from the opcode table) if the - * name successfully matched an entry, or 0 if no match was found. - */ - -struct opcode *find_opcode_by_name (char *name) -{ - int idx; - - /*------------------------------------------------------------*/ - - downstring (name); - - for (idx = 0; idx < n_opcodes; ++idx) { - if (!strcmp (name, opcodes[idx].name)) - return &opcodes[idx]; - } - - return (struct opcode *) 0; -} /* find_opcode_by_name */ - - - -/*====================================================================== - * Convert the 'spr' operand from its numeric value to its symbolic name. - * - * Arguments: - * value The value of the 'spr' operand. This value should - * be unmodified from its encoding in the instruction. - * the split-field computations will be performed - * here before the switch. - * - * Returns the address of a character array containing the name of the - * special purpose register defined by the 'value' parameter, or the - * address of a character array containing "???" if no match was found. - */ - -char *spr_name (int value) -{ - unsigned short spr; - static char other[10]; - int i; - - /*------------------------------------------------------------*/ - - /* spr is a 10 bit field whose interpretation has the high and low - five-bit fields reversed from their encoding in the operand */ - - spr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5); - - for (i = 0; i < n_sprs; ++i) { - if (spr == spr_map[i].spr_val) - return spr_map[i].spr_name; - } - - sprintf (other, "%d", spr); - return other; -} /* spr_name */ - - - -/*====================================================================== - * Convert the 'spr' operand from its symbolic name to its numeric value - * - * Arguments: - * name The symbolic name of the 'spr' operand. The - * split-field encoding will be done by this routine. - * NOTE: name can be a number. - * - * Returns the numeric value for the spr appropriate for encoding a machine - * instruction. Returns 0 if unable to find the SPR. - */ - -int spr_value (char *name) -{ - struct spr_info *sprp; - int spr; - int i; - - /*------------------------------------------------------------*/ - - if (!name || !*name) - return 0; - - if (isdigit ((int) name[0])) { - i = htonl (read_number (name)); - spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5); - return spr; - } - - downstring (name); - - for (i = 0; i < n_sprs; ++i) { - sprp = &spr_map[i]; - - if (strcmp (name, sprp->spr_name) == 0) { - /* spr is a 10 bit field whose interpretation has the high and low - five-bit fields reversed from their encoding in the operand */ - i = htonl (sprp->spr_val); - spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5); - - return spr; - } - } - - return 0; -} /* spr_value */ - - - -/*====================================================================== - * Convert the 'tbr' operand from its numeric value to its symbolic name. - * - * Arguments: - * value The value of the 'tbr' operand. This value should - * be unmodified from its encoding in the instruction. - * the split-field computations will be performed - * here before the switch. - * - * Returns the address of a character array containing the name of the - * time base register defined by the 'value' parameter, or the address - * of a character array containing "???" if no match was found. - */ - -char *tbr_name (int value) -{ - unsigned short tbr; - - /*------------------------------------------------------------*/ - - /* tbr is a 10 bit field whose interpretation has the high and low - five-bit fields reversed from their encoding in the operand */ - - tbr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5); - - if (tbr == 268) - return "TBL"; - - else if (tbr == 269) - return "TBU"; - - - return "???"; -} /* tbr_name */ - - - -/*====================================================================== - * Convert the 'tbr' operand from its symbolic name to its numeric value. - * - * Arguments: - * name The symbolic name of the 'tbr' operand. The - * split-field encoding will be done by this routine. - * - * Returns the numeric value for the spr appropriate for encoding a machine - * instruction. Returns 0 if unable to find the TBR. - */ - -int tbr_value (char *name) -{ - int tbr; - int val; - - /*------------------------------------------------------------*/ - - if (!name || !*name) - return 0; - - downstring (name); - - if (isdigit ((int) name[0])) { - val = read_number (name); - - if (val != 268 && val != 269) - return 0; - } else if (strcmp (name, "tbl") == 0) - val = 268; - else if (strcmp (name, "tbu") == 0) - val = 269; - else - return 0; - - /* tbr is a 10 bit field whose interpretation has the high and low - five-bit fields reversed from their encoding in the operand */ - - val = htonl (val); - tbr = ((val >> 5) & 0x1f) | ((val & 0x1f) << 5); - return tbr; -} /* tbr_name */ - - - -/*====================================================================== - * The next several functions (handle_xxx) are the routines that handle - * disassembling the opcodes with simplified mnemonics. - * - * Arguments: - * ctx A pointer to the disassembler context record. - * - * Returns TRUE if the simpler form was printed or FALSE if it was not. - */ - -int handle_bc (struct ppc_ctx *ctx) -{ - unsigned long bo; - unsigned long bi; - static struct opcode blt = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0}, - 0, "blt", H_RELATIVE - }; - static struct opcode bne = - { B_OPCODE (16, 0, 0), B_MASK, {O_cr2, O_BD, 0}, - 0, "bne", H_RELATIVE - }; - static struct opcode bdnz = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0}, - 0, "bdnz", H_RELATIVE - }; - - /*------------------------------------------------------------*/ - - if (get_operand_value (ctx->op, ctx->instr, O_BO, &bo) == FALSE) - return FALSE; - - if (get_operand_value (ctx->op, ctx->instr, O_BI, &bi) == FALSE) - return FALSE; - - if ((bo == 12) && (bi == 0)) { - ctx->op = &blt; - sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name); - ctx->datalen += 8; - print_operands (ctx); - return TRUE; - } else if ((bo == 4) && (bi == 10)) { - ctx->op = =⃥ - sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name); - ctx->datalen += 8; - print_operands (ctx); - return TRUE; - } else if ((bo == 16) && (bi == 0)) { - ctx->op = &bdnz; - sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name); - ctx->datalen += 8; - print_operands (ctx); - return TRUE; - } - - return FALSE; -} /* handle_blt */ - - - -/*====================================================================== - * Outputs source line information for the disassembler. This should - * be modified in the future to lookup the actual line of source code - * from the file, but for now this will do. - * - * Arguments: - * filename The address of a character array containing the - * absolute path and file name of the source file. - * - * funcname The address of a character array containing the - * name of the function (not C++ demangled (yet)) - * to which this code belongs. - * - * line_no An integer specifying the source line number that - * generated this code. - * - * pfunc The address of a function to call to print the output. - * - * - * Returns TRUE if it was able to output the line info, or false if it was - * not. - */ - -int print_source_line (char *filename, char *funcname, - int line_no, int (*pfunc) (const char *)) -{ - char out_buf[256]; - - /*------------------------------------------------------------*/ - - (*pfunc) (""); /* output a newline */ - sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no); - (*pfunc) (out_buf); - - return TRUE; -} /* print_source_line */ - - - -/*====================================================================== - * Entry point for the PPC assembler. - * - * Arguments: - * asm_buf An array of characters containing the assembly opcode - * and operands to convert to a POWERPC machine - * instruction. - * - * Returns the machine instruction or zero. - */ - -unsigned long asmppc (unsigned long memaddr, char *asm_buf, int *err) -{ - struct opcode *opc; - struct operand *oper[MAX_OPERANDS]; - unsigned long instr; - unsigned long param; - char *ptr = asm_buf; - char scratch[20]; - int i; - int w_operands = 0; /* wanted # of operands */ - int n_operands = 0; /* # of operands read */ - int asm_debug = 0; - - /*------------------------------------------------------------*/ - - if (err) - *err = 0; - - if (get_word (&ptr, scratch) == 0) - return 0; - - /* Lookup the opcode structure based on the opcode name */ - if ((opc = find_opcode_by_name (scratch)) == (struct opcode *) 0) { - if (err) - *err = E_ASM_BAD_OPCODE; - return 0; - } - - if (asm_debug) { - printf ("asmppc: Opcode = \"%s\"\n", opc->name); - } - - for (i = 0; i < 8; ++i) { - if (opc->fields[i] == 0) - break; - ++w_operands; - } - - if (asm_debug) { - printf ("asmppc: Expecting %d operands\n", w_operands); - } - - instr = opc->opcode; - - /* read each operand */ - while (n_operands < w_operands) { - - oper[n_operands] = &operands[opc->fields[n_operands] - 1]; - - if (oper[n_operands]->hint & OH_SILENT) { - /* Skip silent operands, they are covered in opc->opcode */ - - if (asm_debug) { - printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands, - oper[n_operands]->name); - } - - ++n_operands; - continue; - } - - if (get_word (&ptr, scratch) == 0) - break; - - if (asm_debug) { - printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands, - oper[n_operands]->name, scratch); - } - - if ((param = parse_operand (memaddr, opc, oper[n_operands], - scratch, err)) == -1) - return 0; - - instr |= param; - ++n_operands; - } - - if (n_operands < w_operands) { - if (err) - *err = E_ASM_NUM_OPERANDS; - return 0; - } - - if (asm_debug) { - printf ("asmppc: Instruction = 0x%08lx\n", instr); - } - - return instr; -} /* asmppc */ - - - -/*====================================================================== - * Called by the assembler to interpret a single operand - * - * Arguments: - * ctx A pointer to the disassembler context record. - * - * Returns 0 if the operand is ok, or -1 if it is bad. - */ - -int parse_operand (unsigned long memaddr, struct opcode *opc, - struct operand *oper, char *txt, int *err) -{ - long data; - long mask; - int is_neg = 0; - - /*------------------------------------------------------------*/ - - mask = (1 << oper->bits) - 1; - - if (oper->hint & OH_ADDR) { - data = read_number (txt); - - if (opc->hint & H_RELATIVE) - data = data - memaddr; - - if (data < 0) - is_neg = 1; - - data >>= 2; - data &= (mask >> 1); - - if (is_neg) - data |= 1 << (oper->bits - 1); - } - - else if (oper->hint & OH_REG) { - if (txt[0] == 'r' || txt[0] == 'R') - txt++; - else if (txt[0] == '%' && (txt[1] == 'r' || txt[1] == 'R')) - txt += 2; - - data = read_number (txt); - if (data > 31) { - if (err) - *err = E_ASM_BAD_REGISTER; - return -1; - } - - data = htonl (data); - } - - else if (oper->hint & OH_SPR) { - if ((data = spr_value (txt)) == 0) { - if (err) - *err = E_ASM_BAD_SPR; - return -1; - } - } - - else if (oper->hint & OH_TBR) { - if ((data = tbr_value (txt)) == 0) { - if (err) - *err = E_ASM_BAD_TBR; - return -1; - } - } - - else { - data = htonl (read_number (txt)); - } - - return (data & mask) << oper->shift; -} /* parse_operand */ - - -char *asm_error_str (int err) -{ - switch (err) { - case E_ASM_BAD_OPCODE: - return "Bad opcode"; - case E_ASM_NUM_OPERANDS: - return "Bad number of operands"; - case E_ASM_BAD_REGISTER: - return "Bad register number"; - case E_ASM_BAD_SPR: - return "Bad SPR name or number"; - case E_ASM_BAD_TBR: - return "Bad TBR name or number"; - } - - return ""; -} /* asm_error_str */ - - - -/*====================================================================== - * Copy a word from one buffer to another, ignores leading white spaces. - * - * Arguments: - * src The address of a character pointer to the - * source buffer. - * dest A pointer to a character buffer to write the word - * into. - * - * Returns the number of non-white space characters copied, or zero. - */ - -int get_word (char **src, char *dest) -{ - char *ptr = *src; - int nchars = 0; - - /*------------------------------------------------------------*/ - - /* Eat white spaces */ - while (*ptr && isblank (*ptr)) - ptr++; - - if (*ptr == 0) { - *src = ptr; - return 0; - } - - /* Find the text of the word */ - while (*ptr && !isblank (*ptr) && (*ptr != ',')) - dest[nchars++] = *ptr++; - ptr = (*ptr == ',') ? ptr + 1 : ptr; - dest[nchars] = 0; - - *src = ptr; - return nchars; -} /* get_word */ - - - -/*====================================================================== - * Convert a numeric string to a number, be aware of base notations. - * - * Arguments: - * txt The numeric string. - * - * Returns the converted numeric value. - */ - -long read_number (char *txt) -{ - long val; - int is_neg = 0; - - /*------------------------------------------------------------*/ - - if (txt == 0 || *txt == 0) - return 0; - - if (*txt == '-') { - is_neg = 1; - ++txt; - } - - if (txt[0] == '0' && (txt[1] == 'x' || txt[1] == 'X')) /* hex */ - val = simple_strtoul (&txt[2], NULL, 16); - else /* decimal */ - val = simple_strtoul (txt, NULL, 10); - - if (is_neg) - val = -val; - - return val; -} /* read_number */ - - -int downstring (char *s) -{ - if (!s || !*s) - return 0; - - while (*s) { - if (isupper (*s)) - *s = tolower (*s); - s++; - } - - return 0; -} /* downstring */ - - - -/*====================================================================== - * Examines the instruction at the current address and determines the - * next address to be executed. This will take into account branches - * of different types so that a "step" and "next" operations can be - * supported. - * - * Arguments: - * nextaddr The address (to be filled in) of the next - * instruction to execute. This will only be a valid - * address if TRUE is returned. - * - * step_over A flag indicating how to compute addresses for - * branch statements: - * TRUE = Step over the branch (next) - * FALSE = step into the branch (step) - * - * Returns TRUE if it was able to compute the address. Returns FALSE if - * it has a problem reading the current instruction or one of the registers. - */ - -int find_next_address (unsigned char *nextaddr, int step_over, - struct pt_regs *regs) -{ - unsigned long pc; /* SRR0 register from PPC */ - unsigned long ctr; /* CTR register from PPC */ - unsigned long cr; /* CR register from PPC */ - unsigned long lr; /* LR register from PPC */ - unsigned long instr; /* instruction at SRR0 */ - unsigned long next; /* computed instruction for 'next' */ - unsigned long step; /* computed instruction for 'step' */ - unsigned long addr = 0; /* target address operand */ - unsigned long aa = 0; /* AA operand */ - unsigned long lk = 0; /* LK operand */ - unsigned long bo = 0; /* BO operand */ - unsigned long bi = 0; /* BI operand */ - struct opcode *op = 0; /* opcode structure for 'instr' */ - int ctr_ok = 0; - int cond_ok = 0; - int conditional = 0; - int branch = 0; - - /*------------------------------------------------------------*/ - - if (nextaddr == 0 || regs == 0) { - printf ("find_next_address: bad args"); - return FALSE; - } - - pc = regs->nip & 0xfffffffc; - instr = INSTRUCTION (pc); - - if ((op = find_opcode (instr)) == (struct opcode *) 0) { - printf ("find_next_address: can't parse opcode 0x%lx", instr); - return FALSE; - } - - ctr = regs->ctr; - cr = regs->ccr; - lr = regs->link; - - switch (op->opcode) { - case B_OPCODE (16, 0, 0): /* bc */ - case B_OPCODE (16, 0, 1): /* bcl */ - case B_OPCODE (16, 1, 0): /* bca */ - case B_OPCODE (16, 1, 1): /* bcla */ - if (!get_operand_value (op, instr, O_BD, &addr) || - !get_operand_value (op, instr, O_BO, &bo) || - !get_operand_value (op, instr, O_BI, &bi) || - !get_operand_value (op, instr, O_AA, &aa) || - !get_operand_value (op, instr, O_LK, &lk)) - return FALSE; - - if ((addr & (1 << 13)) != 0) - addr = addr - (1 << 14); - addr <<= 2; - conditional = 1; - branch = 1; - break; - - case I_OPCODE (18, 0, 0): /* b */ - case I_OPCODE (18, 0, 1): /* bl */ - case I_OPCODE (18, 1, 0): /* ba */ - case I_OPCODE (18, 1, 1): /* bla */ - if (!get_operand_value (op, instr, O_LI, &addr) || - !get_operand_value (op, instr, O_AA, &aa) || - !get_operand_value (op, instr, O_LK, &lk)) - return FALSE; - - if ((addr & (1 << 23)) != 0) - addr = addr - (1 << 24); - addr <<= 2; - conditional = 0; - branch = 1; - break; - - case XL_OPCODE (19, 528, 0): /* bcctr */ - case XL_OPCODE (19, 528, 1): /* bcctrl */ - if (!get_operand_value (op, instr, O_BO, &bo) || - !get_operand_value (op, instr, O_BI, &bi) || - !get_operand_value (op, instr, O_LK, &lk)) - return FALSE; - - addr = ctr; - aa = 1; - conditional = 1; - branch = 1; - break; - - case XL_OPCODE (19, 16, 0): /* bclr */ - case XL_OPCODE (19, 16, 1): /* bclrl */ - if (!get_operand_value (op, instr, O_BO, &bo) || - !get_operand_value (op, instr, O_BI, &bi) || - !get_operand_value (op, instr, O_LK, &lk)) - return FALSE; - - addr = lr; - aa = 1; - conditional = 1; - branch = 1; - break; - - default: - conditional = 0; - branch = 0; - break; - } - - if (conditional) { - switch ((bo & 0x1e) >> 1) { - case 0: /* 0000y */ - if (--ctr != 0) - ctr_ok = 1; - - cond_ok = !(cr & (1 << (31 - bi))); - break; - - case 1: /* 0001y */ - if (--ctr == 0) - ctr_ok = 1; - - cond_ok = !(cr & (1 << (31 - bi))); - break; - - case 2: /* 001zy */ - ctr_ok = 1; - cond_ok = !(cr & (1 << (31 - bi))); - break; - - case 4: /* 0100y */ - if (--ctr != 0) - ctr_ok = 1; - - cond_ok = cr & (1 << (31 - bi)); - break; - - case 5: /* 0101y */ - if (--ctr == 0) - ctr_ok = 1; - - cond_ok = cr & (1 << (31 - bi)); - break; - - case 6: /* 011zy */ - ctr_ok = 1; - cond_ok = cr & (1 << (31 - bi)); - break; - - case 8: /* 1z00y */ - if (--ctr != 0) - ctr_ok = cond_ok = 1; - break; - - case 9: /* 1z01y */ - if (--ctr == 0) - ctr_ok = cond_ok = 1; - break; - - case 10: /* 1z1zz */ - ctr_ok = cond_ok = 1; - break; - } - } - - if (branch && (!conditional || (ctr_ok && cond_ok))) { - if (aa) - step = addr; - else - step = addr + pc; - - if (lk) - next = pc + 4; - else - next = step; - } else { - step = next = pc + 4; - } - - if (step_over == TRUE) - *(unsigned long *) nextaddr = next; - else - *(unsigned long *) nextaddr = step; - - return TRUE; -} /* find_next_address */ - - -/* - * Copyright (c) 2000 William L. Pitts and W. Gerald Hicks - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - */ - -#endif /* CONFIG_COMMANDS & CFG_CMD_BEDBUG */ diff --git a/common/circbuf.c b/common/circbuf.c deleted file mode 100644 index 2332c63717..0000000000 --- a/common/circbuf.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * (C) Copyright 2003 - * Gerry Hamel, geh@ti.com, Texas Instruments - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include <common.h> -#include <malloc.h> - -#include <circbuf.h> - - -int buf_init (circbuf_t * buf, unsigned int size) -{ - assert (buf != NULL); - - buf->size = 0; - buf->totalsize = size; - buf->data = (char *) malloc (sizeof (char) * size); - assert (buf->data != NULL); - - buf->top = buf->data; - buf->tail = buf->data; - buf->end = &(buf->data[size]); - - return 1; -} - -int buf_free (circbuf_t * buf) -{ - assert (buf != NULL); - assert (buf->data != NULL); - - free (buf->data); - memset (buf, 0, sizeof (circbuf_t)); - - return 1; -} - -int buf_pop (circbuf_t * buf, char *dest, unsigned int len) -{ - unsigned int i; - char *p = buf->top; - - assert (buf != NULL); - assert (dest != NULL); - - /* Cap to number of bytes in buffer */ - if (len > buf->size) - len = buf->size; - - for (i = 0; i < len; i++) { - dest[i] = *p++; - /* Bounds check. */ - if (p == buf->end) { - p = buf->data; - } - } - - /* Update 'top' pointer */ - buf->top = p; - buf->size -= len; - - return len; -} - -int buf_push (circbuf_t * buf, const char *src, unsigned int len) -{ - /* NOTE: this function allows push to overwrite old data. */ - unsigned int i; - char *p = buf->tail; - - assert (buf != NULL); - assert (src != NULL); - - for (i = 0; i < len; i++) { - *p++ = src[i]; - if (p == buf->end) { - p = buf->data; - } - /* Make sure pushing too much data just replaces old data */ - if (buf->size < buf->totalsize) { - buf->size++; - } else { - buf->top++; - if (buf->top == buf->end) { - buf->top = buf->data; - } - } - } - - /* Update 'tail' pointer */ - buf->tail = p; - - return len; -} diff --git a/common/cmd_ace.c b/common/cmd_ace.c deleted file mode 100644 index b6d61057fd..0000000000 --- a/common/cmd_ace.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (c) 2004 Picture Elements, Inc. - * Stephen Williams (XXXXXXXXXXXXXXXX) - * - * This source code is free software; you can redistribute it - * and/or modify it in source code form under the terms of the GNU - * General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ident "$Id:$" - -/* - * The Xilinx SystemACE chip support is activated by defining - * CONFIG_SYSTEMACE to turn on support, and CFG_SYSTEMACE_BASE - * to set the base address of the device. This code currently - * assumes that the chip is connected via a byte-wide bus. - * - * The CONFIG_SYSTEMACE also adds to fat support the device class - * "ace" that allows the user to execute "fatls ace 0" and the - * like. This works by making the systemace_get_dev function - * available to cmd_fat.c:get_dev and filling in a block device - * description that has all the bits needed for FAT support to - * read sectors. - * - * According to Xilinx technical support, before accessing the - * SystemACE CF you need to set the following control bits: - * FORCECFGMODE : 1 - * CFGMODE : 0 - * CFGSTART : 0 - */ - -# include <common.h> -# include <command.h> -# include <systemace.h> -# include <part.h> -# include <asm/io.h> - -#ifdef CONFIG_SYSTEMACE - -/* - * The ace_readw and writew functions read/write 16bit words, but the - * offset value is the BYTE offset as most used in the Xilinx - * datasheet for the SystemACE chip. The CFG_SYSTEMACE_BASE is defined - * to be the base address for the chip, usually in the local - * peripheral bus. - */ -static unsigned ace_readw(unsigned offset) -{ -#if (CFG_SYSTEMACE_WIDTH == 8) - u16 temp; - -#if !defined(__BIG_ENDIAN) - temp =((u16)readb(CFG_SYSTEMACE_BASE+offset) << 8); - temp |= (u16)readb(CFG_SYSTEMACE_BASE+offset+1); -#else - temp = (u16)readb(CFG_SYSTEMACE_BASE+offset); - temp |=((u16)readb(CFG_SYSTEMACE_BASE+offset+1) << 8); -#endif - return temp; -#else - return readw(CFG_SYSTEMACE_BASE+offset); -#endif -} - -static void ace_writew(unsigned val, unsigned offset) -{ -#if (CFG_SYSTEMACE_WIDTH == 8) -#if !defined(__BIG_ENDIAN) - writeb((u8)(val>>8), CFG_SYSTEMACE_BASE+offset); - writeb((u8)val, CFG_SYSTEMACE_BASE+offset+1); -#else - writeb((u8)val, CFG_SYSTEMACE_BASE+offset); - writeb((u8)(val>>8), CFG_SYSTEMACE_BASE+offset+1); -#endif -#else - writew(val, CFG_SYSTEMACE_BASE+offset); -#endif -} - -/* */ - -static unsigned long systemace_read(int dev, - unsigned long start, - unsigned long blkcnt, - unsigned long *buffer); - -static block_dev_desc_t systemace_dev = {0}; - -static int get_cf_lock(void) -{ - int retry = 10; - - /* CONTROLREG = LOCKREG */ - unsigned val=ace_readw(0x18); - val|=0x0002; - ace_writew((val&0xffff), 0x18); - - /* Wait for MPULOCK in STATUSREG[15:0] */ - while (! (ace_readw(0x04) & 0x0002)) { - - if (retry < 0) - return -1; - - udelay(100000); - retry -= 1; - } - - return 0; -} - -static void release_cf_lock(void) -{ - unsigned val=ace_readw(0x18); - val&=~(0x0002); - ace_writew((val&0xffff), 0x18); -} - -block_dev_desc_t * systemace_get_dev(int dev) -{ - /* The first time through this, the systemace_dev object is - not yet initialized. In that case, fill it in. */ - if (systemace_dev.blksz == 0) { - systemace_dev.if_type = IF_TYPE_UNKNOWN; - systemace_dev.dev = 0; - systemace_dev.part_type = PART_TYPE_UNKNOWN; - systemace_dev.type = DEV_TYPE_HARDDISK; - systemace_dev.blksz = 512; - systemace_dev.removable = 1; - systemace_dev.block_read = systemace_read; - - init_part(&systemace_dev); - - } - - return &systemace_dev; -} - -/* - * This function is called (by dereferencing the block_read pointer in - * the dev_desc) to read blocks of data. The return value is the - * number of blocks read. A zero return indicates an error. - */ -static unsigned long systemace_read(int dev, - unsigned long start, - unsigned long blkcnt, - unsigned long *buffer) -{ - int retry; - unsigned blk_countdown; - unsigned char*dp = (unsigned char*)buffer; - unsigned val; - - if (get_cf_lock() < 0) { - unsigned status = ace_readw(0x04); - - /* If CFDETECT is false, card is missing. */ - if (! (status&0x0010)) { - printf("** CompactFlash card not present. **\n"); - return 0; - } - - printf("**** ACE locked away from me (STATUSREG=%04x)\n", status); - return 0; - } - -#ifdef DEBUG_SYSTEMACE - printf("... systemace read %lu sectors at %lu\n", blkcnt, start); -#endif - - retry = 2000; - for (;;) { - val = ace_readw(0x04); - - /* If CFDETECT is false, card is missing. */ - if (! (val & 0x0010)) { - printf("**** ACE CompactFlash not found.\n"); - release_cf_lock(); - return 0; - } - - /* If RDYFORCMD, then we are ready to go. */ - if (val & 0x0100) - break; - - if (retry < 0) { - printf("**** SystemACE not ready.\n"); - release_cf_lock(); - return 0; - } - - udelay(1000); - retry -= 1; - } - - /* The SystemACE can only transfer 256 sectors at a time, so - limit the current chunk of sectors. The blk_countdown - variable is the number of sectors left to transfer. */ - - blk_countdown = blkcnt; - while (blk_countdown > 0) { - unsigned trans = blk_countdown; - - if (trans > 256) trans = 256; - -#ifdef DEBUG_SYSTEMACE - printf("... transfer %lu sector in a chunk\n", trans); -#endif - /* Write LBA block address */ - ace_writew((start>> 0) & 0xffff, 0x10); - ace_writew((start>>16) & 0x00ff, 0x12); - - /* NOTE: in the Write Sector count below, a count of 0 - causes a transfer of 256, so &0xff gives the right - value for whatever transfer count we want. */ - - /* Write sector count | ReadMemCardData. */ - ace_writew((trans&0xff) | 0x0300, 0x14); - - /* Reset the configruation controller */ - val = ace_readw(0x18); - val|=0x0080; - ace_writew(val, 0x18); - - retry = trans * 16; - while (retry > 0) { - int idx; - - /* Wait for buffer to become ready. */ - while (! (ace_readw(0x04) & 0x0020)) { - udelay(100); - } - - /* Read 16 words of 2bytes from the sector buffer. */ - for (idx = 0 ; idx < 16 ; idx += 1) { - unsigned short val = ace_readw(0x40); - *dp++ = val & 0xff; - *dp++ = (val>>8) & 0xff; - } - - retry -= 1; - } - - /* Clear the configruation controller reset */ - val = ace_readw(0x18); - val&=~0x0080; - ace_writew(val, 0x18); - - /* Count the blocks we transfer this time. */ - start += trans; - blk_countdown -= trans; - } - - release_cf_lock(); - - return blkcnt; -} -#endif /* CONFIG_SYSTEMACE */ diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c deleted file mode 100644 index 70de795dee..0000000000 --- a/common/cmd_bdinfo.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * Boot support - */ -#include <common.h> -#include <command.h> -#include <net.h> /* for print_IPaddr */ - -DECLARE_GLOBAL_DATA_PTR; - -#if (CONFIG_COMMANDS & CFG_CMD_BDI) -static void print_num(const char *, ulong); - -#ifndef CONFIG_ARM /* PowerPC and other */ - -#ifdef CONFIG_PPC -static void print_str(const char *, const char *); - -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int i; - bd_t *bd = gd->bd; - char buf[32]; - -#ifdef DEBUG - print_num ("bd address", (ulong)bd ); -#endif - print_num ("memstart", bd->bi_memstart ); - print_num ("memsize", bd->bi_memsize ); - print_num ("flashstart", bd->bi_flashstart ); - print_num ("flashsize", bd->bi_flashsize ); - print_num ("flashoffset", bd->bi_flashoffset ); - print_num ("sramstart", bd->bi_sramstart ); - print_num ("sramsize", bd->bi_sramsize ); -#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || \ - defined(CONFIG_8260) || defined(CONFIG_E500) - print_num ("immr_base", bd->bi_immr_base ); -#endif - print_num ("bootflags", bd->bi_bootflags ); -#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \ - defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300) || \ - defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_440SP) || defined(CONFIG_440SPE) - print_str ("procfreq", strmhz(buf, bd->bi_procfreq)); - print_str ("plb_busfreq", strmhz(buf, bd->bi_plb_busfreq)); -#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300) || \ - defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) - print_str ("pci_busfreq", strmhz(buf, bd->bi_pci_busfreq)); -#endif -#else /* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300, CONFIG_440EP CONFIG_440GR */ -#if defined(CONFIG_CPM2) - print_str ("vco", strmhz(buf, bd->bi_vco)); - print_str ("sccfreq", strmhz(buf, bd->bi_sccfreq)); - print_str ("brgfreq", strmhz(buf, bd->bi_brgfreq)); -#endif - print_str ("intfreq", strmhz(buf, bd->bi_intfreq)); -#if defined(CONFIG_CPM2) - print_str ("cpmfreq", strmhz(buf, bd->bi_cpmfreq)); -#endif - print_str ("busfreq", strmhz(buf, bd->bi_busfreq)); -#endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300, CONFIG_440EP CONFIG_440GR */ -#if defined(CONFIG_MPC8220) - print_str ("inpfreq", strmhz(buf, bd->bi_inpfreq)); - print_str ("flbfreq", strmhz(buf, bd->bi_flbfreq)); - print_str ("pcifreq", strmhz(buf, bd->bi_pcifreq)); - print_str ("vcofreq", strmhz(buf, bd->bi_vcofreq)); - print_str ("pevfreq", strmhz(buf, bd->bi_pevfreq)); -#endif - - puts ("ethaddr ="); - for (i=0; i<6; ++i) { - printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]); - } - -#if defined(CONFIG_HAS_ETH1) - puts ("\neth1addr ="); - for (i=0; i<6; ++i) { - printf ("%c%02X", i ? ':' : ' ', bd->bi_enet1addr[i]); - } -#endif - -#if defined(CONFIG_HAS_ETH2) - puts ("\neth2addr ="); - for (i=0; i<6; ++i) { - printf ("%c%02X", i ? ':' : ' ', bd->bi_enet2addr[i]); - } -#endif - -#if defined(CONFIG_HAS_ETH3) - puts ("\neth3addr ="); - for (i=0; i<6; ++i) { - printf ("%c%02X", i ? ':' : ' ', bd->bi_enet3addr[i]); - } -#endif - -#ifdef CONFIG_HERMES - print_str ("ethspeed", strmhz(buf, bd->bi_ethspeed)); -#endif - puts ("\nIP addr = "); print_IPaddr (bd->bi_ip_addr); - printf ("\nbaudrate = %6ld bps\n", bd->bi_baudrate ); - return 0; -} - -#elif defined(CONFIG_NIOS) /* NIOS*/ - -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int i; - bd_t *bd = gd->bd; - - print_num ("memstart", (ulong)bd->bi_memstart); - print_num ("memsize", (ulong)bd->bi_memsize); - print_num ("flashstart", (ulong)bd->bi_flashstart); - print_num ("flashsize", (ulong)bd->bi_flashsize); - print_num ("flashoffset", (ulong)bd->bi_flashoffset); - - puts ("ethaddr ="); - for (i=0; i<6; ++i) { - printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]); - } - puts ("\nip_addr = "); - print_IPaddr (bd->bi_ip_addr); - printf ("\nbaudrate = %ld bps\n", bd->bi_baudrate); - - return 0; -} - -#elif defined(CONFIG_NIOS2) /* Nios-II */ - -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int i; - bd_t *bd = gd->bd; - - print_num ("mem start", (ulong)bd->bi_memstart); - print_num ("mem size", (ulong)bd->bi_memsize); - print_num ("flash start", (ulong)bd->bi_flashstart); - print_num ("flash size", (ulong)bd->bi_flashsize); - print_num ("flash offset", (ulong)bd->bi_flashoffset); - -#if defined(CFG_SRAM_BASE) - print_num ("sram start", (ulong)bd->bi_sramstart); - print_num ("sram size", (ulong)bd->bi_sramsize); -#endif - -#if defined(CFG_CMD_NET) - puts ("ethaddr ="); - for (i=0; i<6; ++i) { - printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]); - } - puts ("\nip_addr = "); - print_IPaddr (bd->bi_ip_addr); -#endif - - printf ("\nbaudrate = %ld bps\n", bd->bi_baudrate); - - return 0; -} - -#else /* ! PPC, which leaves MIPS */ - -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int i; - bd_t *bd = gd->bd; - - print_num ("boot_params", (ulong)bd->bi_boot_params); - print_num ("memstart", (ulong)bd->bi_memstart); - print_num ("memsize", (ulong)bd->bi_memsize); - print_num ("flashstart", (ulong)bd->bi_flashstart); - print_num ("flashsize", (ulong)bd->bi_flashsize); - print_num ("flashoffset", (ulong)bd->bi_flashoffset); - - puts ("ethaddr ="); - for (i=0; i<6; ++i) { - printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]); - } - puts ("\nip_addr = "); - print_IPaddr (bd->bi_ip_addr); - printf ("\nbaudrate = %d bps\n", bd->bi_baudrate); - - return 0; -} -#endif /* MIPS */ - -#else /* ARM */ - -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int i; - bd_t *bd = gd->bd; - - print_num ("arch_number", bd->bi_arch_number); - print_num ("env_t", (ulong)bd->bi_env); - print_num ("boot_params", (ulong)bd->bi_boot_params); - - for (i=0; i<CONFIG_NR_DRAM_BANKS; ++i) { - print_num("DRAM bank", i); - print_num("-> start", bd->bi_dram[i].start); - print_num("-> size", bd->bi_dram[i].size); - } - - puts ("ethaddr ="); - for (i=0; i<6; ++i) { - printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]); - } - puts ( "\n" - "ip_addr = "); - print_IPaddr (bd->bi_ip_addr); - printf ("\n" - "baudrate = %d bps\n", bd->bi_baudrate); - - return 0; -} - -#endif /* CONFIG_ARM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ - -static void print_num(const char *name, ulong value) -{ - printf ("%-12s= 0x%08lX\n", name, value); -} - -#ifdef CONFIG_PPC -static void print_str(const char *name, const char *str) -{ - printf ("%-12s= %6s MHz\n", name, str); -} -#endif /* CONFIG_PPC */ - - -/* -------------------------------------------------------------------- */ - -U_BOOT_CMD( - bdinfo, 1, 1, do_bdinfo, - "bdinfo - print Board Info structure\n", - NULL -); -#endif /* CFG_CMD_BDI */ diff --git a/common/cmd_bedbug.c b/common/cmd_bedbug.c deleted file mode 100644 index 3cb4e4692b..0000000000 --- a/common/cmd_bedbug.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * BedBug Functions - */ - -#include <common.h> -#include <command.h> -#include <linux/ctype.h> -#include <net.h> -#include <bedbug/type.h> -#include <bedbug/bedbug.h> -#include <bedbug/regs.h> -#include <bedbug/ppc.h> - -DECLARE_GLOBAL_DATA_PTR; - -#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) - -#ifndef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -extern void show_regs __P ((struct pt_regs *)); -extern int run_command __P ((const char *, int)); -extern char console_buffer[]; - -ulong dis_last_addr = 0; /* Last address disassembled */ -ulong dis_last_len = 20; /* Default disassembler length */ -CPU_DEBUG_CTX bug_ctx; /* Bedbug context structure */ - - -/* ====================================================================== - * U-Boot's puts function does not append a newline, so the bedbug stuff - * will use this for the output of the dis/assembler. - * ====================================================================== */ - -int bedbug_puts (const char *str) -{ - /* -------------------------------------------------- */ - - printf ("%s\r\n", str); - return 0; -} /* bedbug_puts */ - - - -/* ====================================================================== - * Initialize the bug_ctx structure used by the bedbug debugger. This is - * specific to the CPU since each has different debug registers and - * settings. - * ====================================================================== */ - -void bedbug_init (void) -{ - /* -------------------------------------------------- */ - -#if defined(CONFIG_4xx) - void bedbug405_init (void); - - bedbug405_init (); -#elif defined(CONFIG_8xx) - void bedbug860_init (void); - - bedbug860_init (); -#endif - -#if defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260) - /* Processors that are 603e core based */ - void bedbug603e_init (void); - - bedbug603e_init (); -#endif - - return; -} /* bedbug_init */ - - - -/* ====================================================================== - * Entry point from the interpreter to the disassembler. Repeated calls - * will resume from the last disassembled address. - * ====================================================================== */ -int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - ulong addr; /* Address to start disassembly from */ - ulong len; /* # of instructions to disassemble */ - - /* -------------------------------------------------- */ - - /* Setup to go from the last address if none is given */ - addr = dis_last_addr; - len = dis_last_len; - - if (argc < 2) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - if ((flag & CMD_FLAG_REPEAT) == 0) { - /* New command */ - addr = simple_strtoul (argv[1], NULL, 16); - - /* If an extra param is given then it is the length */ - if (argc > 2) - len = simple_strtoul (argv[2], NULL, 16); - } - - /* Run the disassembler */ - disppc ((unsigned char *) addr, 0, len, bedbug_puts, F_RADHEX); - - dis_last_addr = addr + (len * 4); - dis_last_len = len; - return 0; -} /* do_bedbug_dis */ - -U_BOOT_CMD (ds, 3, 1, do_bedbug_dis, - "ds - disassemble memory\n", - "ds <address> [# instructions]\n"); - -/* ====================================================================== - * Entry point from the interpreter to the assembler. Assembles - * instructions in consecutive memory locations until a '.' (period) is - * entered on a line by itself. - * ====================================================================== */ -int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - long mem_addr; /* Address to assemble into */ - unsigned long instr; /* Machine code for text */ - char prompt[15]; /* Prompt string for user input */ - int asm_err; /* Error code from the assembler */ - - /* -------------------------------------------------- */ - int rcode = 0; - - if (argc < 2) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - printf ("\nEnter '.' when done\n"); - mem_addr = simple_strtoul (argv[1], NULL, 16); - - while (1) { - putc ('\n'); - disppc ((unsigned char *) mem_addr, 0, 1, bedbug_puts, - F_RADHEX); - - sprintf (prompt, "%08lx: ", mem_addr); - readline (prompt); - - if (console_buffer[0] && strcmp (console_buffer, ".")) { - if ((instr = - asmppc (mem_addr, console_buffer, - &asm_err)) != 0) { - *(unsigned long *) mem_addr = instr; - mem_addr += 4; - } else { - printf ("*** Error: %s ***\n", - asm_error_str (asm_err)); - rcode = 1; - } - } else { - break; - } - } - return rcode; -} /* do_bedbug_asm */ - -U_BOOT_CMD (as, 2, 0, do_bedbug_asm, - "as - assemble memory\n", "as <address>\n"); - -/* ====================================================================== - * Used to set a break point from the interpreter. Simply calls into the - * CPU-specific break point set routine. - * ====================================================================== */ - -int do_bedbug_break (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - /* -------------------------------------------------- */ - if (bug_ctx.do_break) - (*bug_ctx.do_break) (cmdtp, flag, argc, argv); - return 0; - -} /* do_bedbug_break */ - -U_BOOT_CMD (break, 3, 0, do_bedbug_break, - "break - set or clear a breakpoint\n", - " - Set or clear a breakpoint\n" - "break <address> - Break at an address\n" - "break off <bp#> - Disable breakpoint.\n" - "break show - List breakpoints.\n"); - -/* ====================================================================== - * Called from the debug interrupt routine. Simply calls the CPU-specific - * breakpoint handling routine. - * ====================================================================== */ - -void do_bedbug_breakpoint (struct pt_regs *regs) -{ - /* -------------------------------------------------- */ - - if (bug_ctx.break_isr) - (*bug_ctx.break_isr) (regs); - - return; -} /* do_bedbug_breakpoint */ - - - -/* ====================================================================== - * Called from the CPU-specific breakpoint handling routine. Enter a - * mini main loop until the stopped flag is cleared from the breakpoint - * context. - * - * This handles the parts of the debugger that are common to all CPU's. - * ====================================================================== */ - -void bedbug_main_loop (unsigned long addr, struct pt_regs *regs) -{ - int len; /* Length of command line */ - int flag; /* Command flags */ - int rc = 0; /* Result from run_command */ - char prompt_str[20]; /* Prompt string */ - static char lastcommand[CONFIG_CBSIZE] = { 0 }; /* previous command */ - /* -------------------------------------------------- */ - - if (bug_ctx.clear) - (*bug_ctx.clear) (bug_ctx.current_bp); - - printf ("Breakpoint %d: ", bug_ctx.current_bp); - disppc ((unsigned char *) addr, 0, 1, bedbug_puts, F_RADHEX); - - bug_ctx.stopped = 1; - bug_ctx.regs = regs; - - sprintf (prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp); - - /* A miniature main loop */ - while (bug_ctx.stopped) { - len = readline (prompt_str); - - flag = 0; /* assume no special flags for now */ - - if (len > 0) - strcpy (lastcommand, console_buffer); - else if (len == 0) - flag |= CMD_FLAG_REPEAT; - - if (len == -1) - printf ("<INTERRUPT>\n"); - else - rc = run_command (lastcommand, flag); - - if (rc <= 0) { - /* invalid command or not repeatable, forget it */ - lastcommand[0] = 0; - } - } - - bug_ctx.regs = NULL; - bug_ctx.current_bp = 0; - - return; -} /* bedbug_main_loop */ - - - -/* ====================================================================== - * Interpreter command to continue from a breakpoint. Just clears the - * stopped flag in the context so that the breakpoint routine will - * return. - * ====================================================================== */ -int do_bedbug_continue (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - /* -------------------------------------------------- */ - - if (!bug_ctx.stopped) { - printf ("Not at a breakpoint\n"); - return 1; - } - - bug_ctx.stopped = 0; - return 0; -} /* do_bedbug_continue */ - -U_BOOT_CMD (continue, 1, 0, do_bedbug_continue, - "continue- continue from a breakpoint\n", - " - continue from a breakpoint.\n"); - -/* ====================================================================== - * Interpreter command to continue to the next instruction, stepping into - * subroutines. Works by calling the find_next_addr() routine to compute - * the address passes control to the CPU-specific set breakpoint routine - * for the current breakpoint number. - * ====================================================================== */ -int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - unsigned long addr; /* Address to stop at */ - - /* -------------------------------------------------- */ - - if (!bug_ctx.stopped) { - printf ("Not at a breakpoint\n"); - return 1; - } - - if (!find_next_address ((unsigned char *) &addr, FALSE, bug_ctx.regs)) - return 1; - - if (bug_ctx.set) - (*bug_ctx.set) (bug_ctx.current_bp, addr); - - bug_ctx.stopped = 0; - return 0; -} /* do_bedbug_step */ - -U_BOOT_CMD (step, 1, 1, do_bedbug_step, - "step - single step execution.\n", - " - single step execution.\n"); - -/* ====================================================================== - * Interpreter command to continue to the next instruction, stepping over - * subroutines. Works by calling the find_next_addr() routine to compute - * the address passes control to the CPU-specific set breakpoint routine - * for the current breakpoint number. - * ====================================================================== */ -int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - unsigned long addr; /* Address to stop at */ - - /* -------------------------------------------------- */ - - if (!bug_ctx.stopped) { - printf ("Not at a breakpoint\n"); - return 1; - } - - if (!find_next_address ((unsigned char *) &addr, TRUE, bug_ctx.regs)) - return 1; - - if (bug_ctx.set) - (*bug_ctx.set) (bug_ctx.current_bp, addr); - - bug_ctx.stopped = 0; - return 0; -} /* do_bedbug_next */ - -U_BOOT_CMD (next, 1, 1, do_bedbug_next, - "next - single step execution, stepping over subroutines.\n", - " - single step execution, stepping over subroutines.\n"); - -/* ====================================================================== - * Interpreter command to print the current stack. This assumes an EABI - * architecture, so it starts with GPR R1 and works back up the stack. - * ====================================================================== */ -int do_bedbug_stack (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - unsigned long sp; /* Stack pointer */ - unsigned long func; /* LR from stack */ - int depth; /* Stack iteration level */ - int skip = 1; /* Flag to skip the first entry */ - unsigned long top; /* Top of memory address */ - - /* -------------------------------------------------- */ - - if (!bug_ctx.stopped) { - printf ("Not at a breakpoint\n"); - return 1; - } - - top = gd->bd->bi_memstart + gd->bd->bi_memsize; - depth = 0; - - printf ("Depth PC\n"); - printf ("----- --------\n"); - printf ("%5d %08lx\n", depth++, bug_ctx.regs->nip); - - sp = bug_ctx.regs->gpr[1]; - func = *(unsigned long *) (sp + 4); - - while ((func < top) && (sp < top)) { - if (!skip) - printf ("%5d %08lx\n", depth++, func); - else - --skip; - - sp = *(unsigned long *) sp; - func = *(unsigned long *) (sp + 4); - } - return 0; -} /* do_bedbug_stack */ - -U_BOOT_CMD (where, 1, 1, do_bedbug_stack, - "where - Print the running stack.\n", - " - Print the running stack.\n"); - -/* ====================================================================== - * Interpreter command to dump the registers. Calls the CPU-specific - * show registers routine. - * ====================================================================== */ -int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - /* -------------------------------------------------- */ - - if (!bug_ctx.stopped) { - printf ("Not at a breakpoint\n"); - return 1; - } - - show_regs (bug_ctx.regs); - return 0; -} /* do_bedbug_rdump */ - -U_BOOT_CMD (rdump, 1, 1, do_bedbug_rdump, - "rdump - Show registers.\n", " - Show registers.\n"); -/* ====================================================================== */ -#endif /* CFG_CMD_BEDBUG */ - - -/* - * Copyright (c) 2001 William L. Pitts - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - */ diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c deleted file mode 100644 index ad412c81eb..0000000000 --- a/common/cmd_bmp.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * (C) Copyright 2002 - * Detlev Zundel, DENX Software Engineering, dzu@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * BMP handling routines - */ - -#include <common.h> -#include <bmp_layout.h> -#include <command.h> -#include <asm/byteorder.h> -#include <malloc.h> - -#if (CONFIG_COMMANDS & CFG_CMD_BMP) - -static int bmp_info (ulong addr); -static int bmp_display (ulong addr, int x, int y); - -int gunzip(void *, int, unsigned char *, unsigned long *); - -/* - * Subroutine: do_bmp - * - * Description: Handler for 'bmp' command.. - * - * Inputs: argv[1] contains the subcommand - * - * Return: None - * - */ -int do_bmp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - ulong addr; - int x = 0, y = 0; - - switch (argc) { - case 2: /* use load_addr as default address */ - addr = load_addr; - break; - case 3: /* use argument */ - addr = simple_strtoul(argv[2], NULL, 16); - break; - case 5: - addr = simple_strtoul(argv[2], NULL, 16); - x = simple_strtoul(argv[3], NULL, 10); - y = simple_strtoul(argv[4], NULL, 10); - break; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* Allow for short names - * Adjust length if more sub-commands get added - */ - if (strncmp(argv[1],"info",1) == 0) { - return (bmp_info(addr)); - } else if (strncmp(argv[1],"display",1) == 0) { - return (bmp_display(addr, x, y)); - } else { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } -} - -U_BOOT_CMD( - bmp, 5, 1, do_bmp, - "bmp - manipulate BMP image data\n", - "info <imageAddr> - display image info\n" - "bmp display <imageAddr> [x y] - display image at x,y\n" -); - -/* - * Subroutine: bmp_info - * - * Description: Show information about bmp file in memory - * - * Inputs: addr address of the bmp file - * - * Return: None - * - */ -static int bmp_info(ulong addr) -{ - bmp_image_t *bmp=(bmp_image_t *)addr; -#ifdef CONFIG_VIDEO_BMP_GZIP - unsigned char *dst = NULL; - ulong len; -#endif /* CONFIG_VIDEO_BMP_GZIP */ - - if (!((bmp->header.signature[0]=='B') && - (bmp->header.signature[1]=='M'))) { - -#ifdef CONFIG_VIDEO_BMP_GZIP - /* - * Decompress bmp image - */ - len = CFG_VIDEO_LOGO_MAX_SIZE; - dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE); - if (dst == NULL) { - printf("Error: malloc in gunzip failed!\n"); - return(1); - } - if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)addr, &len) != 0) { - printf("There is no valid bmp file at the given address\n"); - return(1); - } - if (len == CFG_VIDEO_LOGO_MAX_SIZE) { - printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n"); - } - - /* - * Set addr to decompressed image - */ - bmp = (bmp_image_t *)dst; - - /* - * Check for bmp mark 'BM' - */ - if (!((bmp->header.signature[0] == 'B') && - (bmp->header.signature[1] == 'M'))) { - printf("There is no valid bmp file at the given address\n"); - free(dst); - return(1); - } - - printf("Gzipped BMP image detected!\n"); -#else /* CONFIG_VIDEO_BMP_GZIP */ - printf("There is no valid bmp file at the given address\n"); - return(1); -#endif /* CONFIG_VIDEO_BMP_GZIP */ - } - printf("Image size : %d x %d\n", le32_to_cpu(bmp->header.width), - le32_to_cpu(bmp->header.height)); - printf("Bits per pixel: %d\n", le16_to_cpu(bmp->header.bit_count)); - printf("Compression : %d\n", le32_to_cpu(bmp->header.compression)); - -#ifdef CONFIG_VIDEO_BMP_GZIP - if (dst) { - free(dst); - } -#endif /* CONFIG_VIDEO_BMP_GZIP */ - - return(0); -} - -/* - * Subroutine: bmp_display - * - * Description: Display bmp file located in memory - * - * Inputs: addr address of the bmp file - * - * Return: None - * - */ -static int bmp_display(ulong addr, int x, int y) -{ -#if defined(CONFIG_LCD) - extern int lcd_display_bitmap (ulong, int, int); - - return (lcd_display_bitmap (addr, x, y)); -#elif defined(CONFIG_VIDEO) - extern int video_display_bitmap (ulong, int, int); - return (video_display_bitmap (addr, x, y)); -#else -# error bmp_display() requires CONFIG_LCD or CONFIG_VIDEO -#endif -} - -#endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) */ diff --git a/common/cmd_cache.c b/common/cmd_cache.c deleted file mode 100644 index e34815d7d9..0000000000 --- a/common/cmd_cache.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * Cache support: switch on or off, get status - */ -#include <common.h> -#include <command.h> - -#if (CONFIG_COMMANDS & CFG_CMD_CACHE) - -static int on_off (const char *); - -int do_icache ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - switch (argc) { - case 2: /* on / off */ - switch (on_off(argv[1])) { - case 0: icache_disable(); - break; - case 1: icache_enable (); - break; - } - /* FALL TROUGH */ - case 1: /* get status */ - printf ("Instruction Cache is %s\n", - icache_status() ? "ON" : "OFF"); - return 0; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - return 0; -} - -int do_dcache ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - switch (argc) { - case 2: /* on / off */ - switch (on_off(argv[1])) { - case 0: dcache_disable(); - break; - case 1: dcache_enable (); - break; - } - /* FALL TROUGH */ - case 1: /* get status */ - printf ("Data (writethrough) Cache is %s\n", - dcache_status() ? "ON" : "OFF"); - return 0; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - return 0; - -} - -static int on_off (const char *s) -{ - if (strcmp(s, "on") == 0) { - return (1); - } else if (strcmp(s, "off") == 0) { - return (0); - } - return (-1); -} - - -U_BOOT_CMD( - icache, 2, 1, do_icache, - "icache - enable or disable instruction cache\n", - "[on, off]\n" - " - enable or disable instruction cache\n" -); - -U_BOOT_CMD( - dcache, 2, 1, do_dcache, - "dcache - enable or disable data cache\n", - "[on, off]\n" - " - enable or disable data (writethrough) cache\n" -); - -#endif /* CFG_CMD_CACHE */ diff --git a/common/cmd_date.c b/common/cmd_date.c deleted file mode 100644 index 84932f7568..0000000000 --- a/common/cmd_date.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * (C) Copyright 2001 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * RTC, Date & Time support: get and set date & time - */ -#include <common.h> -#include <command.h> -#include <rtc.h> - -DECLARE_GLOBAL_DATA_PTR; - -#if (CONFIG_COMMANDS & CFG_CMD_DATE) - -const char *weekdays[] = { - "Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", -}; - -#define RELOC(a) ((typeof(a))((unsigned long)(a) + gd->reloc_off)) - -int mk_date (char *, struct rtc_time *); - -int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - struct rtc_time tm; - int rcode = 0; - - switch (argc) { - case 2: /* set date & time */ - if (strcmp(argv[1],"reset") == 0) { - puts ("Reset RTC...\n"); - rtc_reset (); - } else { - /* initialize tm with current time */ - rtc_get (&tm); - /* insert new date & time */ - if (mk_date (argv[1], &tm) != 0) { - puts ("## Bad date format\n"); - return 1; - } - /* and write to RTC */ - rtc_set (&tm); - } - /* FALL TROUGH */ - case 1: /* get date & time */ - rtc_get (&tm); - - printf ("Date: %4d-%02d-%02d (%sday) Time: %2d:%02d:%02d\n", - tm.tm_year, tm.tm_mon, tm.tm_mday, - (tm.tm_wday<0 || tm.tm_wday>6) ? - "unknown " : RELOC(weekdays[tm.tm_wday]), - tm.tm_hour, tm.tm_min, tm.tm_sec); - - return 0; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - rcode = 1; - } - return rcode; -} - -/* - * simple conversion of two-digit string with error checking - */ -static int cnvrt2 (char *str, int *valp) -{ - int val; - - if ((*str < '0') || (*str > '9')) - return (-1); - - val = *str - '0'; - - ++str; - - if ((*str < '0') || (*str > '9')) - return (-1); - - *valp = 10 * val + (*str - '0'); - - return (0); -} - -/* - * Convert date string: MMDDhhmm[[CC]YY][.ss] - * - * Some basic checking for valid values is done, but this will not catch - * all possible error conditions. - */ -int mk_date (char *datestr, struct rtc_time *tmp) -{ - int len, val; - char *ptr; - - ptr = strchr (datestr,'.'); - len = strlen (datestr); - - /* Set seconds */ - if (ptr) { - int sec; - - *ptr++ = '\0'; - if ((len - (ptr - datestr)) != 2) - return (-1); - - len = strlen (datestr); - - if (cnvrt2 (ptr, &sec)) - return (-1); - - tmp->tm_sec = sec; - } else { - tmp->tm_sec = 0; - } - - if (len == 12) { /* MMDDhhmmCCYY */ - int year, century; - - if (cnvrt2 (datestr+ 8, ¢ury) || - cnvrt2 (datestr+10, &year) ) { - return (-1); - } - tmp->tm_year = 100 * century + year; - } else if (len == 10) { /* MMDDhhmmYY */ - int year, century; - - century = tmp->tm_year / 100; - if (cnvrt2 (datestr+ 8, &year)) - return (-1); - tmp->tm_year = 100 * century + year; - } - - switch (len) { - case 8: /* MMDDhhmm */ - /* fall thru */ - case 10: /* MMDDhhmmYY */ - /* fall thru */ - case 12: /* MMDDhhmmCCYY */ - if (cnvrt2 (datestr+0, &val) || - val > 12) { - break; - } - tmp->tm_mon = val; - if (cnvrt2 (datestr+2, &val) || - val > ((tmp->tm_mon==2) ? 29 : 31)) { - break; - } - tmp->tm_mday = val; - - if (cnvrt2 (datestr+4, &val) || - val > 23) { - break; - } - tmp->tm_hour = val; - - if (cnvrt2 (datestr+6, &val) || - val > 59) { - break; - } - tmp->tm_min = val; - - /* calculate day of week */ - GregorianDay (tmp); - - return (0); - default: - break; - } - - return (-1); -} - -/***************************************************/ - -U_BOOT_CMD( - date, 2, 1, do_date, - "date - get/set/reset date & time\n", - "[MMDDhhmm[[CC]YY][.ss]]\ndate reset\n" - " - without arguments: print date & time\n" - " - with numeric argument: set the system date & time\n" - " - with 'reset' argument: reset the RTC\n" -); - -#endif /* CFG_CMD_DATE */ diff --git a/common/cmd_dcr.c b/common/cmd_dcr.c deleted file mode 100644 index 7221a865ed..0000000000 --- a/common/cmd_dcr.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * (C) Copyright 2001 - * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * AMCC 4XX DCR Functions - */ - -#include <common.h> -#include <config.h> -#include <command.h> - -#if defined(CONFIG_4xx) && (CONFIG_COMMANDS & CFG_CMD_SETGETDCR) - -unsigned long get_dcr (unsigned short); -unsigned long set_dcr (unsigned short, unsigned long); - -/* ======================================================================= - * Interpreter command to retrieve an AMCC PPC 4xx Device Control Register - * ======================================================================= - */ -int do_getdcr ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ) -{ - unsigned short dcrn; /* Device Control Register Num */ - unsigned long value; /* DCR's value */ - - unsigned long get_dcr (unsigned short); - - /* Validate arguments */ - if (argc < 2) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* Get a DCR */ - dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16); - value = get_dcr (dcrn); - - printf ("%04x: %08lx\n", dcrn, value); - - return 0; -} - - -/* ====================================================================== - * Interpreter command to set an AMCC PPC 4xx Device Control Register - * ====================================================================== -*/ -int do_setdcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - unsigned short dcrn; /* Device Control Register Num */ - unsigned long value; - - /* DCR's value */ - int nbytes; - extern char console_buffer[]; - - /* Validate arguments */ - if (argc < 2) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* Set a DCR */ - dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16); - do { - value = get_dcr (dcrn); - printf ("%04x: %08lx", dcrn, value); - nbytes = readline (" ? "); - if (nbytes == 0) { - /* - * <CR> pressed as only input, don't modify current - * location and exit command. - */ - nbytes = 1; - return 0; - } else { - unsigned long i; - char *endp; - - i = simple_strtoul (console_buffer, &endp, 16); - nbytes = endp - console_buffer; - if (nbytes) - set_dcr (dcrn, i); - } - } while (nbytes); - - return 0; -} - -/* ======================================================================= - * Interpreter command to retrieve an register value through AMCC PPC 4xx - * Device Control Register inderect addressing. - * ======================================================================= - */ -int do_getidcr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned short adr_dcrn; /* Device Control Register Num for Address */ - unsigned short dat_dcrn; /* Device Control Register Num for Data */ - unsigned short offset; /* Register's offset */ - unsigned long value; /* Register's value */ - char *ptr = NULL; - char buf[80]; - - /* Validate arguments */ - if (argc < 3) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* Find out whether ther is '.' (dot) symbol in the first parameter. */ - strncpy (buf, argv[1], sizeof(buf)-1); - buf[sizeof(buf)-1] = 0; /* will guarantee zero-end string */ - ptr = strchr (buf, '.'); - - if (ptr != NULL) { - /* First parameter has format adr_dcrn.dat_dcrn */ - *ptr++ = 0; /* erase '.', create zero-end string */ - adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16); - dat_dcrn = (unsigned short) simple_strtoul (ptr, NULL, 16); - } else { - /* - * First parameter has format adr_dcrn; dat_dcrn will be - * calculated as adr_dcrn+1. - */ - adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16); - dat_dcrn = adr_dcrn+1; - } - - /* Register's offset */ - offset = (unsigned short) simple_strtoul (argv[2], NULL, 16); - - /* Disable interrupts */ - disable_interrupts (); - /* Set offset */ - set_dcr (adr_dcrn, offset); - /* get data */ - value = get_dcr (dat_dcrn); - /* Enable interrupts */ - enable_interrupts (); - - printf ("%04x.%04x-%04x Read %08lx\n", adr_dcrn, dat_dcrn, offset, value); - - return 0; -} - -/* ======================================================================= - * Interpreter command to update an register value through AMCC PPC 4xx - * Device Control Register inderect addressing. - * ======================================================================= - */ -int do_setidcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - unsigned short adr_dcrn; /* Device Control Register Num for Address */ - unsigned short dat_dcrn; /* Device Control Register Num for Data */ - unsigned short offset; /* Register's offset */ - unsigned long value; /* Register's value */ - char *ptr = NULL; - char buf[80]; - - /* Validate arguments */ - if (argc < 4) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* Find out whether ther is '.' (dot) symbol in the first parameter. */ - strncpy (buf, argv[1], sizeof(buf)-1); - buf[sizeof(buf)-1] = 0; /* will guarantee zero-end string */ - ptr = strchr (buf, '.'); - - if (ptr != NULL) { - /* First parameter has format adr_dcrn.dat_dcrn */ - *ptr++ = 0; /* erase '.', create zero-end string */ - adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16); - dat_dcrn = (unsigned short) simple_strtoul (ptr, NULL, 16); - } else { - /* - * First parameter has format adr_dcrn; dat_dcrn will be - * calculated as adr_dcrn+1. - */ - adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16); - dat_dcrn = adr_dcrn+1; - } - - /* Register's offset */ - offset = (unsigned short) simple_strtoul (argv[2], NULL, 16); - /* New value */ - value = (unsigned long) simple_strtoul (argv[3], NULL, 16); - - /* Disable interrupts */ - disable_interrupts (); - /* Set offset */ - set_dcr (adr_dcrn, offset); - /* set data */ - set_dcr (dat_dcrn, value); - /* Enable interrupts */ - enable_interrupts (); - - printf ("%04x.%04x-%04x Write %08lx\n", adr_dcrn, dat_dcrn, offset, value); - - return 0; -} - -/***************************************************/ - -U_BOOT_CMD( - getdcr, 2, 1, do_getdcr, - "getdcr - Get an AMCC PPC 4xx DCR's value\n", - "dcrn - return a DCR's value.\n" -); -U_BOOT_CMD( - setdcr, 2, 1, do_setdcr, - "setdcr - Set an AMCC PPC 4xx DCR's value\n", - "dcrn - set a DCR's value.\n" -); - -U_BOOT_CMD( - getidcr, 3, 1, do_getidcr, - "getidcr - Get a register value via indirect DCR addressing\n", - "adr_dcrn[.dat_dcrn] offset - write offset to adr_dcrn, read value from dat_dcrn.\n" -); - -U_BOOT_CMD( - setidcr, 4, 1, do_setidcr, - "setidcr - Set a register value via indirect DCR addressing\n", - "adr_dcrn[.dat_dcrn] offset value - write offset to adr_dcrn, write value to dat_dcrn.\n" -); - -#endif /* CONFIG_4xx & CFG_CMD_SETGETDCR */ diff --git a/common/cmd_diag.c b/common/cmd_diag.c deleted file mode 100644 index c3b31220d1..0000000000 --- a/common/cmd_diag.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * (C) Copyright 2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * Diagnostics support - */ -#include <common.h> -#include <command.h> -#include <post.h> - -#if (CONFIG_COMMANDS & CFG_CMD_DIAG) && defined(CONFIG_POST) - -int do_diag (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int i; - - if (argc == 1 || strcmp (argv[1], "run") != 0) { - /* List test info */ - if (argc == 1) { - puts ("Available hardware tests:\n"); - post_info (NULL); - puts ("Use 'diag [<test1> [<test2> ...]]'" - " to get more info.\n"); - puts ("Use 'diag run [<test1> [<test2> ...]]'" - " to run tests.\n"); - } else { - for (i = 1; i < argc; i++) { - if (post_info (argv[i]) != 0) - printf ("%s - no such test\n", argv[i]); - } - } - } else { - /* Run tests */ - if (argc == 2) { - post_run (NULL, POST_RAM | POST_MANUAL); - } else { - for (i = 2; i < argc; i++) { - if (post_run (argv[i], POST_RAM | POST_MANUAL) != 0) - printf ("%s - unable to execute the test\n", - argv[i]); - } - } - } - - return 0; -} -/***************************************************/ - -U_BOOT_CMD( - diag, CONFIG_MAXARGS, 0, do_diag, - "diag - perform board diagnostics\n", - " - print list of available tests\n" - "diag [test1 [test2]]\n" - " - print information about specified tests\n" - "diag run - run all available tests\n" - "diag run [test1 [test2]]\n" - " - run specified tests\n" -); - -#endif /* CFG_CMD_DIAG */ diff --git a/common/cmd_display.c b/common/cmd_display.c deleted file mode 100644 index 3ee781f7e1..0000000000 --- a/common/cmd_display.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * (C) Copyright 2005 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <command.h> - -#if (CONFIG_COMMANDS & CFG_CMD_DISPLAY) - -#undef DEBUG_DISP - -#define DISP_SIZE 8 -#define CWORD_CLEAR 0x80 -#define CLEAR_DELAY (110 * 2) - -int do_display (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int i; - int pos; - - /* Clear display */ - *((volatile char*)(CFG_DISP_CWORD)) = CWORD_CLEAR; - udelay(1000 * CLEAR_DELAY); - - if (argc < 2) - return (0); - - for (pos = 0, i = 1; i < argc && pos < DISP_SIZE; i++) { - char *p = argv[i], c; - - if (i > 1) { - *((volatile uchar *) (CFG_DISP_CHR_RAM + pos++)) = ' '; -#ifdef DEBUG_DISP - putc(' '); -#endif - } - - while ((c = *p++) != '\0' && pos < DISP_SIZE) { - *((volatile uchar *) (CFG_DISP_CHR_RAM + pos++)) = c; -#ifdef DEBUG_DISP - putc(c); -#endif - } - } - -#ifdef DEBUG_DISP - putc('\n'); -#endif - - return (0); -} - -/***************************************************/ - -U_BOOT_CMD( - display, CONFIG_MAXARGS, 1, do_display, - "display- display string on dot matrix display\n", - "[<string>]\n" - " - with <string> argument: display <string> on dot matrix display\n" - " - without arguments: clear dot matrix display\n" -); - -#endif /* CFG_CMD_DISPLAY */ diff --git a/common/cmd_doc.c b/common/cmd_doc.c deleted file mode 100644 index 6ca7035e6a..0000000000 --- a/common/cmd_doc.c +++ /dev/null @@ -1,1594 +0,0 @@ -/* - * Driver for Disk-On-Chip 2000 and Millennium - * (c) 1999 Machine Vision Holdings, Inc. - * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> - * - * $Id: doc2000.c,v 1.46 2001/10/02 15:05:13 dwmw2 Exp $ - */ - -#include <common.h> -#include <config.h> -#include <command.h> -#include <malloc.h> -#include <asm/io.h> - -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include <status_led.h> -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - -#if (CONFIG_COMMANDS & CFG_CMD_DOC) - -#include <linux/mtd/nftl.h> -#include <linux/mtd/doc2000.h> - -#ifdef CFG_DOC_SUPPORT_2000 -#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k) -#else -#define DoC_is_2000(doc) (0) -#endif - -#ifdef CFG_DOC_SUPPORT_MILLENNIUM -#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil) -#else -#define DoC_is_Millennium(doc) (0) -#endif - -/* CFG_DOC_PASSIVE_PROBE: - In order to ensure that the BIOS checksum is correct at boot time, and - hence that the onboard BIOS extension gets executed, the DiskOnChip - goes into reset mode when it is read sequentially: all registers - return 0xff until the chip is woken up again by writing to the - DOCControl register. - - Unfortunately, this means that the probe for the DiskOnChip is unsafe, - because one of the first things it does is write to where it thinks - the DOCControl register should be - which may well be shared memory - for another device. I've had machines which lock up when this is - attempted. Hence the possibility to do a passive probe, which will fail - to detect a chip in reset mode, but is at least guaranteed not to lock - the machine. - - If you have this problem, uncomment the following line: -#define CFG_DOC_PASSIVE_PROBE -*/ - -#undef DOC_DEBUG -#undef ECC_DEBUG -#undef PSYCHO_DEBUG -#undef NFTL_DEBUG - -static struct DiskOnChip doc_dev_desc[CFG_MAX_DOC_DEVICE]; - -/* Current DOC Device */ -static int curr_device = -1; - -/* Supported NAND flash devices */ -static struct nand_flash_dev nand_flash_ids[] = { - {"Toshiba TC5816BDC", NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000, 0}, - {"Toshiba TC5832DC", NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000, 0}, - {"Toshiba TH58V128DC", NAND_MFR_TOSHIBA, 0x73, 24, 0, 2, 0x4000, 0}, - {"Toshiba TC58256FT/DC", NAND_MFR_TOSHIBA, 0x75, 25, 0, 2, 0x4000, 0}, - {"Toshiba TH58512FT", NAND_MFR_TOSHIBA, 0x76, 26, 0, 3, 0x4000, 0}, - {"Toshiba TC58V32DC", NAND_MFR_TOSHIBA, 0xe5, 22, 0, 2, 0x2000, 0}, - {"Toshiba TC58V64AFT/DC", NAND_MFR_TOSHIBA, 0xe6, 23, 0, 2, 0x2000, 0}, - {"Toshiba TC58V16BDC", NAND_MFR_TOSHIBA, 0xea, 21, 1, 2, 0x1000, 0}, - {"Toshiba TH58100FT", NAND_MFR_TOSHIBA, 0x79, 27, 0, 3, 0x4000, 0}, - {"Samsung KM29N16000", NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000, 0}, - {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000, 0}, - {"Samsung KM29U128T", NAND_MFR_SAMSUNG, 0x73, 24, 0, 2, 0x4000, 0}, - {"Samsung KM29U256T", NAND_MFR_SAMSUNG, 0x75, 25, 0, 2, 0x4000, 0}, - {"Samsung unknown 64Mb", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0}, - {"Samsung KM29W32000", NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000, 0}, - {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000, 0}, - {"Samsung KM29U64000", NAND_MFR_SAMSUNG, 0xe6, 23, 0, 2, 0x2000, 0}, - {"Samsung KM29W16000", NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0}, - {"Samsung K9F5616Q0C", NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1}, - {"Samsung K9K1216Q0C", NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1}, - {"Samsung K9F1G08U0M", NAND_MFR_SAMSUNG, 0xf1, 27, 0, 2, 0, 0}, - {NULL,} -}; - -/* ------------------------------------------------------------------------- */ - -int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int rcode = 0; - - switch (argc) { - case 0: - case 1: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 2: - if (strcmp(argv[1],"info") == 0) { - int i; - - putc ('\n'); - - for (i=0; i<CFG_MAX_DOC_DEVICE; ++i) { - if(doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN) - continue; /* list only known devices */ - printf ("Device %d: ", i); - doc_print(&doc_dev_desc[i]); - } - return 0; - - } else if (strcmp(argv[1],"device") == 0) { - if ((curr_device < 0) || (curr_device >= CFG_MAX_DOC_DEVICE)) { - puts ("\nno devices available\n"); - return 1; - } - printf ("\nDevice %d: ", curr_device); - doc_print(&doc_dev_desc[curr_device]); - return 0; - } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 3: - if (strcmp(argv[1],"device") == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - printf ("\nDevice %d: ", dev); - if (dev >= CFG_MAX_DOC_DEVICE) { - puts ("unknown device\n"); - return 1; - } - doc_print(&doc_dev_desc[dev]); - /*doc_print (dev);*/ - - if (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN) { - return 1; - } - - curr_device = dev; - - puts ("... is now current device\n"); - - return 0; - } - - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - default: - /* at least 4 args */ - - if (strcmp(argv[1],"read") == 0 || strcmp(argv[1],"write") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong off = simple_strtoul(argv[3], NULL, 16); - ulong size = simple_strtoul(argv[4], NULL, 16); - int cmd = (strcmp(argv[1],"read") == 0); - int ret, total; - - printf ("\nDOC %s: device %d offset %ld, size %ld ... ", - cmd ? "read" : "write", curr_device, off, size); - - ret = doc_rw(doc_dev_desc + curr_device, cmd, off, size, - (size_t *)&total, (u_char*)addr); - - printf ("%d bytes %s: %s\n", total, cmd ? "read" : "write", - ret ? "ERROR" : "OK"); - - return ret; - } else if (strcmp(argv[1],"erase") == 0) { - ulong off = simple_strtoul(argv[2], NULL, 16); - ulong size = simple_strtoul(argv[3], NULL, 16); - int ret; - - printf ("\nDOC erase: device %d offset %ld, size %ld ... ", - curr_device, off, size); - - ret = doc_erase (doc_dev_desc + curr_device, off, size); - - printf("%s\n", ret ? "ERROR" : "OK"); - - return ret; - } else { - printf ("Usage:\n%s\n", cmdtp->usage); - rcode = 1; - } - - return rcode; - } -} -U_BOOT_CMD( - doc, 5, 1, do_doc, - "doc - Disk-On-Chip sub-system\n", - "info - show available DOC devices\n" - "doc device [dev] - show or set current device\n" - "doc read addr off size\n" - "doc write addr off size - read/write `size'" - " bytes starting at offset `off'\n" - " to/from memory address `addr'\n" - "doc erase off size - erase `size' bytes of DOC from offset `off'\n" -); - -int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - char *boot_device = NULL; - char *ep; - int dev; - ulong cnt; - ulong addr; - ulong offset = 0; - image_header_t *hdr; - int rcode = 0; - - switch (argc) { - case 1: - addr = CFG_LOAD_ADDR; - boot_device = getenv ("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv ("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - case 4: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - offset = simple_strtoul(argv[3], NULL, 16); - break; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - if (!boot_device) { - puts ("\n** No boot device **\n"); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - dev = simple_strtoul(boot_device, &ep, 16); - - if ((dev >= CFG_MAX_DOC_DEVICE) || - (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN)) { - printf ("\n** Device %d not available\n", dev); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - printf ("\nLoading from device %d: %s at 0x%lX (offset 0x%lX)\n", - dev, doc_dev_desc[dev].name, doc_dev_desc[dev].physadr, - offset); - - if (doc_rw (doc_dev_desc + dev, 1, offset, - SECTORSIZE, NULL, (u_char *)addr)) { - printf ("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - hdr = (image_header_t *)addr; - - if (hdr->ih_magic == IH_MAGIC) { - - print_image_hdr (hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); - cnt -= SECTORSIZE; - } else { - puts ("\n** Bad Magic Number **\n"); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt, - NULL, (u_char *)(addr+SECTORSIZE))) { - printf ("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - /* Loading ok, update default load address */ - - load_addr = addr; - - return rcode; -} - -U_BOOT_CMD( - docboot, 4, 1, do_docboot, - "docboot - boot from DOC device\n", - "loadAddr dev\n" -); - -int doc_rw (struct DiskOnChip* this, int cmd, - loff_t from, size_t len, - size_t * retlen, u_char * buf) -{ - int noecc, ret = 0, n, total = 0; - char eccbuf[6]; - - while(len) { - /* The ECC will not be calculated correctly if - less than 512 is written or read */ - noecc = (from != (from | 0x1ff) + 1) || (len < 0x200); - - if (cmd) - ret = doc_read_ecc(this, from, len, - (size_t *)&n, (u_char*)buf, - noecc ? (uchar *)NULL : (uchar *)eccbuf); - else - ret = doc_write_ecc(this, from, len, - (size_t *)&n, (u_char*)buf, - noecc ? (uchar *)NULL : (uchar *)eccbuf); - - if (ret) - break; - - from += n; - buf += n; - total += n; - len -= n; - } - - if (retlen) - *retlen = total; - - return ret; -} - -void doc_print(struct DiskOnChip *this) { - printf("%s at 0x%lX,\n" - "\t %d chip%s %s, size %d MB, \n" - "\t total size %ld MB, sector size %ld kB\n", - this->name, this->physadr, this->numchips, - this->numchips>1 ? "s" : "", this->chips_name, - 1 << (this->chipshift - 20), - this->totlen >> 20, this->erasesize >> 10); - - if (this->nftl_found) { - struct NFTLrecord *nftl = &this->nftl; - unsigned long bin_size, flash_size; - - bin_size = nftl->nb_boot_blocks * this->erasesize; - flash_size = (nftl->nb_blocks - nftl->nb_boot_blocks) * this->erasesize; - - printf("\t NFTL boot record:\n" - "\t Binary partition: size %ld%s\n" - "\t Flash disk partition: size %ld%s, offset 0x%lx\n", - bin_size > (1 << 20) ? bin_size >> 20 : bin_size >> 10, - bin_size > (1 << 20) ? "MB" : "kB", - flash_size > (1 << 20) ? flash_size >> 20 : flash_size >> 10, - flash_size > (1 << 20) ? "MB" : "kB", bin_size); - } else { - puts ("\t No NFTL boot record found.\n"); - } -} - -/* ------------------------------------------------------------------------- */ - -/* This function is needed to avoid calls of the __ashrdi3 function. */ -static int shr(int val, int shift) { - return val >> shift; -} - -/* Perform the required delay cycles by reading from the appropriate register */ -static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles) -{ - volatile char dummy; - int i; - - for (i = 0; i < cycles; i++) { - if (DoC_is_Millennium(doc)) - dummy = ReadDOC(doc->virtadr, NOP); - else - dummy = ReadDOC(doc->virtadr, DOCStatus); - } - -} - -/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ -static int _DoC_WaitReady(struct DiskOnChip *doc) -{ - unsigned long docptr = doc->virtadr; - unsigned long start = get_timer(0); - -#ifdef PSYCHO_DEBUG - puts ("_DoC_WaitReady called for out-of-line wait\n"); -#endif - - /* Out-of-line routine to wait for chip response */ - while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { -#ifdef CFG_DOC_SHORT_TIMEOUT - /* it seems that after a certain time the DoC deasserts - * the CDSN_CTRL_FR_B although it is not ready... - * using a short timout solve this (timer increments every ms) */ - if (get_timer(start) > 10) { - return DOC_ETIMEOUT; - } -#else - if (get_timer(start) > 10 * 1000) { - puts ("_DoC_WaitReady timed out.\n"); - return DOC_ETIMEOUT; - } -#endif - udelay(1); - } - - return 0; -} - -static int DoC_WaitReady(struct DiskOnChip *doc) -{ - unsigned long docptr = doc->virtadr; - /* This is inline, to optimise the common case, where it's ready instantly */ - int ret = 0; - - /* 4 read form NOP register should be issued in prior to the read from CDSNControl - see Software Requirement 11.4 item 2. */ - DoC_Delay(doc, 4); - - if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) - /* Call the out-of-line routine to wait */ - ret = _DoC_WaitReady(doc); - - /* issue 2 read from NOP register after reading from CDSNControl register - see Software Requirement 11.4 item 2. */ - DoC_Delay(doc, 2); - - return ret; -} - -/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to - bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is - required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */ - -static inline int DoC_Command(struct DiskOnChip *doc, unsigned char command, - unsigned char xtraflags) -{ - unsigned long docptr = doc->virtadr; - - if (DoC_is_2000(doc)) - xtraflags |= CDSN_CTRL_FLASH_IO; - - /* Assert the CLE (Command Latch Enable) line to the flash chip */ - WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl); - DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */ - - if (DoC_is_Millennium(doc)) - WriteDOC(command, docptr, CDSNSlowIO); - - /* Send the command */ - WriteDOC_(command, docptr, doc->ioreg); - - /* Lower the CLE line */ - WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl); - DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */ - - /* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */ - return DoC_WaitReady(doc); -} - -/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to - bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is - required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */ - -static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs, - unsigned char xtraflags1, unsigned char xtraflags2) -{ - unsigned long docptr; - int i; - - docptr = doc->virtadr; - - if (DoC_is_2000(doc)) - xtraflags1 |= CDSN_CTRL_FLASH_IO; - - /* Assert the ALE (Address Latch Enable) line to the flash chip */ - WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl); - - DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */ - - /* Send the address */ - /* Devices with 256-byte page are addressed as: - Column (bits 0-7), Page (bits 8-15, 16-23, 24-31) - * there is no device on the market with page256 - and more than 24 bits. - Devices with 512-byte page are addressed as: - Column (bits 0-7), Page (bits 9-16, 17-24, 25-31) - * 25-31 is sent only if the chip support it. - * bit 8 changes the read command to be sent - (NAND_CMD_READ0 or NAND_CMD_READ1). - */ - - if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) { - if (DoC_is_Millennium(doc)) - WriteDOC(ofs & 0xff, docptr, CDSNSlowIO); - WriteDOC_(ofs & 0xff, docptr, doc->ioreg); - } - - if (doc->page256) { - ofs = ofs >> 8; - } else { - ofs = ofs >> 9; - } - - if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) { - for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) { - if (DoC_is_Millennium(doc)) - WriteDOC(ofs & 0xff, docptr, CDSNSlowIO); - WriteDOC_(ofs & 0xff, docptr, doc->ioreg); - } - } - - DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */ - - /* FIXME: The SlowIO's for millennium could be replaced by - a single WritePipeTerm here. mf. */ - - /* Lower the ALE line */ - WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, - CDSNControl); - - DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */ - - /* Wait for the chip to respond - Software requirement 11.4.1 */ - return DoC_WaitReady(doc); -} - -/* Read a buffer from DoC, taking care of Millennium oddities */ -static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len) -{ - volatile int dummy; - int modulus = 0xffff; - unsigned long docptr; - int i; - - docptr = doc->virtadr; - - if (len <= 0) - return; - - if (DoC_is_Millennium(doc)) { - /* Read the data via the internal pipeline through CDSN IO register, - see Pipelined Read Operations 11.3 */ - dummy = ReadDOC(docptr, ReadPipeInit); - - /* Millennium should use the LastDataRead register - Pipeline Reads */ - len--; - - /* This is needed for correctly ECC calculation */ - modulus = 0xff; - } - - for (i = 0; i < len; i++) - buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus)); - - if (DoC_is_Millennium(doc)) { - buf[i] = ReadDOC(docptr, LastDataRead); - } -} - -/* Write a buffer to DoC, taking care of Millennium oddities */ -static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len) -{ - unsigned long docptr; - int i; - - docptr = doc->virtadr; - - if (len <= 0) - return; - - for (i = 0; i < len; i++) - WriteDOC_(buf[i], docptr, doc->ioreg + i); - - if (DoC_is_Millennium(doc)) { - WriteDOC(0x00, docptr, WritePipeTerm); - } -} - - -/* DoC_SelectChip: Select a given flash chip within the current floor */ - -static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip) -{ - unsigned long docptr = doc->virtadr; - - /* Software requirement 11.4.4 before writing DeviceSelect */ - /* Deassert the CE line to eliminate glitches on the FCE# outputs */ - WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl); - DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */ - - /* Select the individual flash chip requested */ - WriteDOC(chip, docptr, CDSNDeviceSelect); - DoC_Delay(doc, 4); - - /* Reassert the CE line */ - WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr, - CDSNControl); - DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */ - - /* Wait for it to be ready */ - return DoC_WaitReady(doc); -} - -/* DoC_SelectFloor: Select a given floor (bank of flash chips) */ - -static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor) -{ - unsigned long docptr = doc->virtadr; - - /* Select the floor (bank) of chips required */ - WriteDOC(floor, docptr, FloorSelect); - - /* Wait for the chip to be ready */ - return DoC_WaitReady(doc); -} - -/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */ - -static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip) -{ - int mfr, id, i; - volatile char dummy; - - /* Page in the required floor/chip */ - DoC_SelectFloor(doc, floor); - DoC_SelectChip(doc, chip); - - /* Reset the chip */ - if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) { -#ifdef DOC_DEBUG - printf("DoC_Command (reset) for %d,%d returned true\n", - floor, chip); -#endif - return 0; - } - - - /* Read the NAND chip ID: 1. Send ReadID command */ - if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) { -#ifdef DOC_DEBUG - printf("DoC_Command (ReadID) for %d,%d returned true\n", - floor, chip); -#endif - return 0; - } - - /* Read the NAND chip ID: 2. Send address byte zero */ - DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0); - - /* Read the manufacturer and device id codes from the device */ - - /* CDSN Slow IO register see Software Requirement 11.4 item 5. */ - dummy = ReadDOC(doc->virtadr, CDSNSlowIO); - DoC_Delay(doc, 2); - mfr = ReadDOC_(doc->virtadr, doc->ioreg); - - /* CDSN Slow IO register see Software Requirement 11.4 item 5. */ - dummy = ReadDOC(doc->virtadr, CDSNSlowIO); - DoC_Delay(doc, 2); - id = ReadDOC_(doc->virtadr, doc->ioreg); - - /* No response - return failure */ - if (mfr == 0xff || mfr == 0) - return 0; - - /* Check it's the same as the first chip we identified. - * M-Systems say that any given DiskOnChip device should only - * contain _one_ type of flash part, although that's not a - * hardware restriction. */ - if (doc->mfr) { - if (doc->mfr == mfr && doc->id == id) - return 1; /* This is another the same the first */ - else - printf("Flash chip at floor %d, chip %d is different:\n", - floor, chip); - } - - /* Print and store the manufacturer and ID codes. */ - for (i = 0; nand_flash_ids[i].name != NULL; i++) { - if (mfr == nand_flash_ids[i].manufacture_id && - id == nand_flash_ids[i].model_id) { -#ifdef DOC_DEBUG - printf("Flash chip found: Manufacturer ID: %2.2X, " - "Chip ID: %2.2X (%s)\n", mfr, id, - nand_flash_ids[i].name); -#endif - if (!doc->mfr) { - doc->mfr = mfr; - doc->id = id; - doc->chipshift = - nand_flash_ids[i].chipshift; - doc->page256 = nand_flash_ids[i].page256; - doc->pageadrlen = - nand_flash_ids[i].pageadrlen; - doc->erasesize = - nand_flash_ids[i].erasesize; - doc->chips_name = - nand_flash_ids[i].name; - return 1; - } - return 0; - } - } - - -#ifdef DOC_DEBUG - /* We haven't fully identified the chip. Print as much as we know. */ - printf("Unknown flash chip found: %2.2X %2.2X\n", - id, mfr); -#endif - - return 0; -} - -/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */ - -static void DoC_ScanChips(struct DiskOnChip *this) -{ - int floor, chip; - int numchips[MAX_FLOORS]; - int maxchips = MAX_CHIPS; - int ret = 1; - - this->numchips = 0; - this->mfr = 0; - this->id = 0; - - if (DoC_is_Millennium(this)) - maxchips = MAX_CHIPS_MIL; - - /* For each floor, find the number of valid chips it contains */ - for (floor = 0; floor < MAX_FLOORS; floor++) { - ret = 1; - numchips[floor] = 0; - for (chip = 0; chip < maxchips && ret != 0; chip++) { - - ret = DoC_IdentChip(this, floor, chip); - if (ret) { - numchips[floor]++; - this->numchips++; - } - } - } - - /* If there are none at all that we recognise, bail */ - if (!this->numchips) { - puts ("No flash chips recognised.\n"); - return; - } - - /* Allocate an array to hold the information for each chip */ - this->chips = malloc(sizeof(struct Nand) * this->numchips); - if (!this->chips) { - puts ("No memory for allocating chip info structures\n"); - return; - } - - ret = 0; - - /* Fill out the chip array with {floor, chipno} for each - * detected chip in the device. */ - for (floor = 0; floor < MAX_FLOORS; floor++) { - for (chip = 0; chip < numchips[floor]; chip++) { - this->chips[ret].floor = floor; - this->chips[ret].chip = chip; - this->chips[ret].curadr = 0; - this->chips[ret].curmode = 0x50; - ret++; - } - } - - /* Calculate and print the total size of the device */ - this->totlen = this->numchips * (1 << this->chipshift); - -#ifdef DOC_DEBUG - printf("%d flash chips found. Total DiskOnChip size: %ld MB\n", - this->numchips, this->totlen >> 20); -#endif -} - -/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the - * various device information of the NFTL partition and Bad Unit Table. Update - * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[] - * is used for management of Erase Unit in other routines in nftl.c and nftlmount.c - */ -static int find_boot_record(struct NFTLrecord *nftl) -{ - struct nftl_uci1 h1; - struct nftl_oob oob; - unsigned int block, boot_record_count = 0; - int retlen; - u8 buf[SECTORSIZE]; - struct NFTLMediaHeader *mh = &nftl->MediaHdr; - unsigned int i; - - nftl->MediaUnit = BLOCK_NIL; - nftl->SpareMediaUnit = BLOCK_NIL; - - /* search for a valid boot record */ - for (block = 0; block < nftl->nb_blocks; block++) { - int ret; - - /* Check for ANAND header first. Then can whinge if it's found but later - checks fail */ - if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, - (size_t *)&retlen, buf, NULL))) { - static int warncount = 5; - - if (warncount) { - printf("Block read at 0x%x failed\n", block * nftl->EraseSize); - if (!--warncount) - puts ("Further failures for this block will not be printed\n"); - } - continue; - } - - if (retlen < 6 || memcmp(buf, "ANAND", 6)) { - /* ANAND\0 not found. Continue */ -#ifdef PSYCHO_DEBUG - printf("ANAND header not found at 0x%x\n", block * nftl->EraseSize); -#endif - continue; - } - -#ifdef NFTL_DEBUG - printf("ANAND header found at 0x%x\n", block * nftl->EraseSize); -#endif - - /* To be safer with BIOS, also use erase mark as discriminant */ - if ((ret = doc_read_oob(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, - 8, (size_t *)&retlen, (uchar *)&h1) < 0)) { -#ifdef NFTL_DEBUG - printf("ANAND header found at 0x%x, but OOB data read failed\n", - block * nftl->EraseSize); -#endif - continue; - } - - /* OK, we like it. */ - - if (boot_record_count) { - /* We've already processed one. So we just check if - this one is the same as the first one we found */ - if (memcmp(mh, buf, sizeof(struct NFTLMediaHeader))) { -#ifdef NFTL_DEBUG - printf("NFTL Media Headers at 0x%x and 0x%x disagree.\n", - nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize); -#endif - /* if (debug) Print both side by side */ - return -1; - } - if (boot_record_count == 1) - nftl->SpareMediaUnit = block; - - boot_record_count++; - continue; - } - - /* This is the first we've seen. Copy the media header structure into place */ - memcpy(mh, buf, sizeof(struct NFTLMediaHeader)); - - /* Do some sanity checks on it */ - if (mh->UnitSizeFactor == 0) { -#ifdef NFTL_DEBUG - puts ("UnitSizeFactor 0x00 detected.\n" - "This violates the spec but we think we know what it means...\n"); -#endif - } else if (mh->UnitSizeFactor != 0xff) { - printf ("Sorry, we don't support UnitSizeFactor " - "of != 1 yet.\n"); - return -1; - } - - nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN); - if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) { - printf ("NFTL Media Header sanity check failed:\n" - "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n", - nftl->nb_boot_blocks, nftl->nb_blocks); - return -1; - } - - nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize; - if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) { - printf ("NFTL Media Header sanity check failed:\n" - "numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n", - nftl->numvunits, - nftl->nb_blocks, - nftl->nb_boot_blocks); - return -1; - } - - nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); - - /* If we're not using the last sectors in the device for some reason, - reduce nb_blocks accordingly so we forget they're there */ - nftl->nb_blocks = le16_to_cpu(mh->NumEraseUnits) + le16_to_cpu(mh->FirstPhysicalEUN); - - /* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */ - for (i = 0; i < nftl->nb_blocks; i++) { - if ((i & (SECTORSIZE - 1)) == 0) { - /* read one sector for every SECTORSIZE of blocks */ - if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize + - i + SECTORSIZE, SECTORSIZE, - (size_t *)&retlen, buf, (uchar *)&oob)) < 0) { - puts ("Read of bad sector table failed\n"); - return -1; - } - } - /* mark the Bad Erase Unit as RESERVED in ReplUnitTable */ - if (buf[i & (SECTORSIZE - 1)] != 0xff) - nftl->ReplUnitTable[i] = BLOCK_RESERVED; - } - - nftl->MediaUnit = block; - boot_record_count++; - - } /* foreach (block) */ - - return boot_record_count?0:-1; -} - -/* This routine is made available to other mtd code via - * inter_module_register. It must only be accessed through - * inter_module_get which will bump the use count of this module. The - * addresses passed back in mtd are valid as long as the use count of - * this module is non-zero, i.e. between inter_module_get and - * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000. - */ -static void DoC2k_init(struct DiskOnChip* this) -{ - struct NFTLrecord *nftl; - - switch (this->ChipID) { - case DOC_ChipID_Doc2k: - this->name = "DiskOnChip 2000"; - this->ioreg = DoC_2k_CDSN_IO; - break; - case DOC_ChipID_DocMil: - this->name = "DiskOnChip Millennium"; - this->ioreg = DoC_Mil_CDSN_IO; - break; - } - -#ifdef DOC_DEBUG - printf("%s found at address 0x%lX\n", this->name, - this->physadr); -#endif - - this->totlen = 0; - this->numchips = 0; - - this->curfloor = -1; - this->curchip = -1; - - /* Ident all the chips present. */ - DoC_ScanChips(this); - if ((!this->numchips) || (!this->chips)) - return; - - nftl = &this->nftl; - - /* Get physical parameters */ - nftl->EraseSize = this->erasesize; - nftl->nb_blocks = this->totlen / this->erasesize; - nftl->mtd = this; - - if (find_boot_record(nftl) != 0) - this->nftl_found = 0; - else - this->nftl_found = 1; - - printf("%s @ 0x%lX, %ld MB\n", this->name, this->physadr, this->totlen >> 20); -} - -int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len, - size_t * retlen, u_char * buf, u_char * eccbuf) -{ - unsigned long docptr; - struct Nand *mychip; - unsigned char syndrome[6]; - volatile char dummy; - int i, len256 = 0, ret=0; - - docptr = this->virtadr; - - /* Don't allow read past end of device */ - if (from >= this->totlen) { - puts ("Out of flash\n"); - return DOC_EINVAL; - } - - /* Don't allow a single read to cross a 512-byte block boundary */ - if (from + len > ((from | 0x1ff) + 1)) - len = ((from | 0x1ff) + 1) - from; - - /* The ECC will not be calculated correctly if less than 512 is read */ - if (len != 0x200 && eccbuf) - printf("ECC needs a full sector read (adr: %lx size %lx)\n", - (long) from, (long) len); - -#ifdef PSYCHO_DEBUG - printf("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len); -#endif - - /* Find the chip which is to be used and select it */ - mychip = &this->chips[shr(from, this->chipshift)]; - - if (this->curfloor != mychip->floor) { - DoC_SelectFloor(this, mychip->floor); - DoC_SelectChip(this, mychip->chip); - } else if (this->curchip != mychip->chip) { - DoC_SelectChip(this, mychip->chip); - } - - this->curfloor = mychip->floor; - this->curchip = mychip->chip; - - DoC_Command(this, - (!this->page256 - && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0, - CDSN_CTRL_WP); - DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP, - CDSN_CTRL_ECC_IO); - - if (eccbuf) { - /* Prime the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_EN, docptr, ECCConf); - } else { - /* disable the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_DIS, docptr, ECCConf); - } - - /* treat crossing 256-byte sector for 2M x 8bits devices */ - if (this->page256 && from + len > (from | 0xff) + 1) { - len256 = (from | 0xff) + 1 - from; - DoC_ReadBuf(this, buf, len256); - - DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP); - DoC_Address(this, ADDR_COLUMN_PAGE, from + len256, - CDSN_CTRL_WP, CDSN_CTRL_ECC_IO); - } - - DoC_ReadBuf(this, &buf[len256], len - len256); - - /* Let the caller know we completed it */ - *retlen = len; - - if (eccbuf) { - /* Read the ECC data through the DiskOnChip ECC logic */ - /* Note: this will work even with 2M x 8bit devices as */ - /* they have 8 bytes of OOB per 256 page. mf. */ - DoC_ReadBuf(this, eccbuf, 6); - - /* Flush the pipeline */ - if (DoC_is_Millennium(this)) { - dummy = ReadDOC(docptr, ECCConf); - dummy = ReadDOC(docptr, ECCConf); - i = ReadDOC(docptr, ECCConf); - } else { - dummy = ReadDOC(docptr, 2k_ECCStatus); - dummy = ReadDOC(docptr, 2k_ECCStatus); - i = ReadDOC(docptr, 2k_ECCStatus); - } - - /* Check the ECC Status */ - if (i & 0x80) { - int nb_errors; - /* There was an ECC error */ -#ifdef ECC_DEBUG - printf("DiskOnChip ECC Error: Read at %lx\n", (long)from); -#endif - /* Read the ECC syndrom through the DiskOnChip ECC logic. - These syndrome will be all ZERO when there is no error */ - for (i = 0; i < 6; i++) { - syndrome[i] = - ReadDOC(docptr, ECCSyndrome0 + i); - } - nb_errors = doc_decode_ecc(buf, syndrome); - -#ifdef ECC_DEBUG - printf("Errors corrected: %x\n", nb_errors); -#endif - if (nb_errors < 0) { - /* We return error, but have actually done the read. Not that - this can be told to user-space, via sys_read(), but at least - MTD-aware stuff can know about it by checking *retlen */ - printf("ECC Errors at %lx\n", (long)from); - ret = DOC_EECC; - } - } - -#ifdef PSYCHO_DEBUG - printf("ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", - (long)from, eccbuf[0], eccbuf[1], eccbuf[2], - eccbuf[3], eccbuf[4], eccbuf[5]); -#endif - - /* disable the ECC engine */ - WriteDOC(DOC_ECC_DIS, docptr , ECCConf); - } - - /* according to 11.4.1, we need to wait for the busy line - * drop if we read to the end of the page. */ - if(0 == ((from + *retlen) & 0x1ff)) - { - DoC_WaitReady(this); - } - - return ret; -} - -int doc_write_ecc(struct DiskOnChip* this, loff_t to, size_t len, - size_t * retlen, const u_char * buf, - u_char * eccbuf) -{ - int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */ - unsigned long docptr; - volatile char dummy; - int len256 = 0; - struct Nand *mychip; - - docptr = this->virtadr; - - /* Don't allow write past end of device */ - if (to >= this->totlen) { - puts ("Out of flash\n"); - return DOC_EINVAL; - } - - /* Don't allow a single write to cross a 512-byte block boundary */ - if (to + len > ((to | 0x1ff) + 1)) - len = ((to | 0x1ff) + 1) - to; - - /* The ECC will not be calculated correctly if less than 512 is written */ - if (len != 0x200 && eccbuf) - printf("ECC needs a full sector write (adr: %lx size %lx)\n", - (long) to, (long) len); - - /* printf("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */ - - /* Find the chip which is to be used and select it */ - mychip = &this->chips[shr(to, this->chipshift)]; - - if (this->curfloor != mychip->floor) { - DoC_SelectFloor(this, mychip->floor); - DoC_SelectChip(this, mychip->chip); - } else if (this->curchip != mychip->chip) { - DoC_SelectChip(this, mychip->chip); - } - - this->curfloor = mychip->floor; - this->curchip = mychip->chip; - - /* Set device to main plane of flash */ - DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP); - DoC_Command(this, - (!this->page256 - && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0, - CDSN_CTRL_WP); - - DoC_Command(this, NAND_CMD_SEQIN, 0); - DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO); - - if (eccbuf) { - /* Prime the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); - } else { - /* disable the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_DIS, docptr, ECCConf); - } - - /* treat crossing 256-byte sector for 2M x 8bits devices */ - if (this->page256 && to + len > (to | 0xff) + 1) { - len256 = (to | 0xff) + 1 - to; - DoC_WriteBuf(this, buf, len256); - - DoC_Command(this, NAND_CMD_PAGEPROG, 0); - - DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); - /* There's an implicit DoC_WaitReady() in DoC_Command */ - - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); - - if (ReadDOC_(docptr, this->ioreg) & 1) { - puts ("Error programming flash\n"); - /* Error in programming */ - *retlen = 0; - return DOC_EIO; - } - - DoC_Command(this, NAND_CMD_SEQIN, 0); - DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0, - CDSN_CTRL_ECC_IO); - } - - DoC_WriteBuf(this, &buf[len256], len - len256); - - if (eccbuf) { - WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, - CDSNControl); - - if (DoC_is_Millennium(this)) { - WriteDOC(0, docptr, NOP); - WriteDOC(0, docptr, NOP); - WriteDOC(0, docptr, NOP); - } else { - WriteDOC_(0, docptr, this->ioreg); - WriteDOC_(0, docptr, this->ioreg); - WriteDOC_(0, docptr, this->ioreg); - } - - /* Read the ECC data through the DiskOnChip ECC logic */ - for (di = 0; di < 6; di++) { - eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); - } - - /* Reset the ECC engine */ - WriteDOC(DOC_ECC_DIS, docptr, ECCConf); - -#ifdef PSYCHO_DEBUG - printf - ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", - (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], - eccbuf[4], eccbuf[5]); -#endif - } - - DoC_Command(this, NAND_CMD_PAGEPROG, 0); - - DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); - /* There's an implicit DoC_WaitReady() in DoC_Command */ - - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); - - if (ReadDOC_(docptr, this->ioreg) & 1) { - puts ("Error programming flash\n"); - /* Error in programming */ - *retlen = 0; - return DOC_EIO; - } - - /* Let the caller know we completed it */ - *retlen = len; - - if (eccbuf) { - unsigned char x[8]; - size_t dummy; - int ret; - - /* Write the ECC data to flash */ - for (di=0; di<6; di++) - x[di] = eccbuf[di]; - - x[6]=0x55; - x[7]=0x55; - - ret = doc_write_oob(this, to, 8, &dummy, x); - return ret; - } - return 0; -} - -int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len, - size_t * retlen, u_char * buf) -{ - int len256 = 0, ret; - unsigned long docptr; - struct Nand *mychip; - - docptr = this->virtadr; - - mychip = &this->chips[shr(ofs, this->chipshift)]; - - if (this->curfloor != mychip->floor) { - DoC_SelectFloor(this, mychip->floor); - DoC_SelectChip(this, mychip->chip); - } else if (this->curchip != mychip->chip) { - DoC_SelectChip(this, mychip->chip); - } - this->curfloor = mychip->floor; - this->curchip = mychip->chip; - - /* update address for 2M x 8bit devices. OOB starts on the second */ - /* page to maintain compatibility with doc_read_ecc. */ - if (this->page256) { - if (!(ofs & 0x8)) - ofs += 0x100; - else - ofs -= 0x8; - } - - DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP); - DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0); - - /* treat crossing 8-byte OOB data for 2M x 8bit devices */ - /* Note: datasheet says it should automaticaly wrap to the */ - /* next OOB block, but it didn't work here. mf. */ - if (this->page256 && ofs + len > (ofs | 0x7) + 1) { - len256 = (ofs | 0x7) + 1 - ofs; - DoC_ReadBuf(this, buf, len256); - - DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP); - DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), - CDSN_CTRL_WP, 0); - } - - DoC_ReadBuf(this, &buf[len256], len - len256); - - *retlen = len; - /* Reading the full OOB data drops us off of the end of the page, - * causing the flash device to go into busy mode, so we need - * to wait until ready 11.4.1 and Toshiba TC58256FT docs */ - - ret = DoC_WaitReady(this); - - return ret; - -} - -int doc_write_oob(struct DiskOnChip* this, loff_t ofs, size_t len, - size_t * retlen, const u_char * buf) -{ - int len256 = 0; - unsigned long docptr = this->virtadr; - struct Nand *mychip = &this->chips[shr(ofs, this->chipshift)]; - volatile int dummy; - -#ifdef PSYCHO_DEBUG - printf("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n", - (long)ofs, len, buf[0], buf[1], buf[2], buf[3], - buf[8], buf[9], buf[14],buf[15]); -#endif - - /* Find the chip which is to be used and select it */ - if (this->curfloor != mychip->floor) { - DoC_SelectFloor(this, mychip->floor); - DoC_SelectChip(this, mychip->chip); - } else if (this->curchip != mychip->chip) { - DoC_SelectChip(this, mychip->chip); - } - this->curfloor = mychip->floor; - this->curchip = mychip->chip; - - /* disable the ECC engine */ - WriteDOC (DOC_ECC_RESET, docptr, ECCConf); - WriteDOC (DOC_ECC_DIS, docptr, ECCConf); - - /* Reset the chip, see Software Requirement 11.4 item 1. */ - DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP); - - /* issue the Read2 command to set the pointer to the Spare Data Area. */ - DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP); - - /* update address for 2M x 8bit devices. OOB starts on the second */ - /* page to maintain compatibility with doc_read_ecc. */ - if (this->page256) { - if (!(ofs & 0x8)) - ofs += 0x100; - else - ofs -= 0x8; - } - - /* issue the Serial Data In command to initial the Page Program process */ - DoC_Command(this, NAND_CMD_SEQIN, 0); - DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0); - - /* treat crossing 8-byte OOB data for 2M x 8bit devices */ - /* Note: datasheet says it should automaticaly wrap to the */ - /* next OOB block, but it didn't work here. mf. */ - if (this->page256 && ofs + len > (ofs | 0x7) + 1) { - len256 = (ofs | 0x7) + 1 - ofs; - DoC_WriteBuf(this, buf, len256); - - DoC_Command(this, NAND_CMD_PAGEPROG, 0); - DoC_Command(this, NAND_CMD_STATUS, 0); - /* DoC_WaitReady() is implicit in DoC_Command */ - - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); - - if (ReadDOC_(docptr, this->ioreg) & 1) { - puts ("Error programming oob data\n"); - /* There was an error */ - *retlen = 0; - return DOC_EIO; - } - DoC_Command(this, NAND_CMD_SEQIN, 0); - DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0); - } - - DoC_WriteBuf(this, &buf[len256], len - len256); - - DoC_Command(this, NAND_CMD_PAGEPROG, 0); - DoC_Command(this, NAND_CMD_STATUS, 0); - /* DoC_WaitReady() is implicit in DoC_Command */ - - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); - - if (ReadDOC_(docptr, this->ioreg) & 1) { - puts ("Error programming oob data\n"); - /* There was an error */ - *retlen = 0; - return DOC_EIO; - } - - *retlen = len; - return 0; - -} - -int doc_erase(struct DiskOnChip* this, loff_t ofs, size_t len) -{ - volatile int dummy; - unsigned long docptr; - struct Nand *mychip; - - if (ofs & (this->erasesize-1) || len & (this->erasesize-1)) { - puts ("Offset and size must be sector aligned\n"); - return DOC_EINVAL; - } - - docptr = this->virtadr; - - /* FIXME: Do this in the background. Use timers or schedule_task() */ - while(len) { - mychip = &this->chips[shr(ofs, this->chipshift)]; - - if (this->curfloor != mychip->floor) { - DoC_SelectFloor(this, mychip->floor); - DoC_SelectChip(this, mychip->chip); - } else if (this->curchip != mychip->chip) { - DoC_SelectChip(this, mychip->chip); - } - this->curfloor = mychip->floor; - this->curchip = mychip->chip; - - DoC_Command(this, NAND_CMD_ERASE1, 0); - DoC_Address(this, ADDR_PAGE, ofs, 0, 0); - DoC_Command(this, NAND_CMD_ERASE2, 0); - - DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); - - dummy = ReadDOC(docptr, CDSNSlowIO); - DoC_Delay(this, 2); - - if (ReadDOC_(docptr, this->ioreg) & 1) { - printf("Error erasing at 0x%lx\n", (long)ofs); - /* There was an error */ - goto callback; - } - ofs += this->erasesize; - len -= this->erasesize; - } - - callback: - return 0; -} - -static inline int doccheck(unsigned long potential, unsigned long physadr) -{ - unsigned long window=potential; - unsigned char tmp, ChipID; -#ifndef DOC_PASSIVE_PROBE - unsigned char tmp2; -#endif - - /* Routine copied from the Linux DOC driver */ - -#ifdef CFG_DOCPROBE_55AA - /* Check for 0x55 0xAA signature at beginning of window, - this is no longer true once we remove the IPL (for Millennium */ - if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa) - return 0; -#endif /* CFG_DOCPROBE_55AA */ - -#ifndef DOC_PASSIVE_PROBE - /* It's not possible to cleanly detect the DiskOnChip - the - * bootup procedure will put the device into reset mode, and - * it's not possible to talk to it without actually writing - * to the DOCControl register. So we store the current contents - * of the DOCControl register's location, in case we later decide - * that it's not a DiskOnChip, and want to put it back how we - * found it. - */ - tmp2 = ReadDOC(window, DOCControl); - - /* Reset the DiskOnChip ASIC */ - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, - window, DOCControl); - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, - window, DOCControl); - - /* Enable the DiskOnChip ASIC */ - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, - window, DOCControl); - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, - window, DOCControl); -#endif /* !DOC_PASSIVE_PROBE */ - - ChipID = ReadDOC(window, ChipID); - - switch (ChipID) { - case DOC_ChipID_Doc2k: - /* Check the TOGGLE bit in the ECC register */ - tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT; - if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp) - return ChipID; - break; - - case DOC_ChipID_DocMil: - /* Check the TOGGLE bit in the ECC register */ - tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT; - if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp) - return ChipID; - break; - - default: -#ifndef CFG_DOCPROBE_55AA -/* - * if the ID isn't the DoC2000 or DoCMillenium ID, so we can assume - * the DOC is missing - */ -#endif -#ifndef DOC_PASSIVE_PROBE - /* Put back the contents of the DOCControl register, in case it's not - * actually a DiskOnChip. - */ - WriteDOC(tmp2, window, DOCControl); -#endif - return 0; - } - - puts ("DiskOnChip failed TOGGLE test, dropping.\n"); - -#ifndef DOC_PASSIVE_PROBE - /* Put back the contents of the DOCControl register: it's not a DiskOnChip */ - WriteDOC(tmp2, window, DOCControl); -#endif - return 0; -} - -void doc_probe(unsigned long physadr) -{ - struct DiskOnChip *this = NULL; - int i=0, ChipID; - - if ((ChipID = doccheck(physadr, physadr))) { - - for (i=0; i<CFG_MAX_DOC_DEVICE; i++) { - if (doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN) { - this = doc_dev_desc + i; - break; - } - } - - if (!this) { - puts ("Cannot allocate memory for data structures.\n"); - return; - } - - if (curr_device == -1) - curr_device = i; - - memset((char *)this, 0, sizeof(struct DiskOnChip)); - - this->virtadr = physadr; - this->physadr = physadr; - this->ChipID = ChipID; - - DoC2k_init(this); - } else { - puts ("No DiskOnChip found\n"); - } -} - -#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */ diff --git a/common/cmd_dtt.c b/common/cmd_dtt.c deleted file mode 100644 index 9db64e9e3d..0000000000 --- a/common/cmd_dtt.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2001 - * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <config.h> -#include <command.h> - -#if (CONFIG_COMMANDS & CFG_CMD_DTT) - -#include <dtt.h> - -int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - int i; - unsigned char sensors[] = CONFIG_DTT_SENSORS; - - /* - * Loop through sensors, read - * temperature, and output it. - */ - for (i = 0; i < sizeof (sensors); i++) { - printf ("DTT%d: %i C\n", i + 1, dtt_get_temp (sensors[i])); - } - - return 0; -} /* do_dtt() */ - -/***************************************************/ - -U_BOOT_CMD( - dtt, 1, 1, do_dtt, - "dtt - Digital Thermometer and Themostat\n", - " - Read temperature from digital thermometer and thermostat.\n" -); - -#endif /* CONFIG_COMMANDS & CFG_CMD_DTT */ diff --git a/common/cmd_eeprom.c b/common/cmd_eeprom.c deleted file mode 100644 index d15a412057..0000000000 --- a/common/cmd_eeprom.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * (C) Copyright 2000, 2001 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Support for read and write access to EEPROM like memory devices. This - * includes regular EEPROM as well as FRAM (ferroelectic nonvolaile RAM). - * FRAM devices read and write data at bus speed. In particular, there is no - * write delay. Also, there is no limit imposed on the numer of bytes that can - * be transferred with a single read or write. - * - * Use the following configuration options to ensure no unneeded performance - * degradation (typical for EEPROM) is incured for FRAM memory: - * - * #define CFG_I2C_FRAM - * #undef CFG_EEPROM_PAGE_WRITE_DELAY_MS - * - */ - -#include <common.h> -#include <config.h> -#include <command.h> -#include <i2c.h> - -#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM) - -extern void eeprom_init (void); -extern int eeprom_read (unsigned dev_addr, unsigned offset, - uchar *buffer, unsigned cnt); -extern int eeprom_write (unsigned dev_addr, unsigned offset, - uchar *buffer, unsigned cnt); -#if defined(CFG_EEPROM_WREN) -extern int eeprom_write_enable (unsigned dev_addr, int state); -#endif -#endif - - -#if defined(CFG_EEPROM_X40430) - /* Maximum number of times to poll for acknowledge after write */ -#define MAX_ACKNOWLEDGE_POLLS 10 -#endif - -/* ------------------------------------------------------------------------- */ - -#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) -int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - const char *const fmt = - "\nEEPROM @0x%lX %s: addr %08lx off %04lx count %ld ... "; - -#if defined(CFG_I2C_MULTI_EEPROMS) - if (argc == 6) { - ulong dev_addr = simple_strtoul (argv[2], NULL, 16); - ulong addr = simple_strtoul (argv[3], NULL, 16); - ulong off = simple_strtoul (argv[4], NULL, 16); - ulong cnt = simple_strtoul (argv[5], NULL, 16); -#else - if (argc == 5) { - ulong dev_addr = CFG_DEF_EEPROM_ADDR; - ulong addr = simple_strtoul (argv[2], NULL, 16); - ulong off = simple_strtoul (argv[3], NULL, 16); - ulong cnt = simple_strtoul (argv[4], NULL, 16); -#endif /* CFG_I2C_MULTI_EEPROMS */ - -# ifndef CONFIG_SPI - eeprom_init (); -# endif /* !CONFIG_SPI */ - - if (strcmp (argv[1], "read") == 0) { - int rcode; - - printf (fmt, dev_addr, argv[1], addr, off, cnt); - - rcode = eeprom_read (dev_addr, off, (uchar *) addr, cnt); - - puts ("done\n"); - return rcode; - } else if (strcmp (argv[1], "write") == 0) { - int rcode; - - printf (fmt, dev_addr, argv[1], addr, off, cnt); - - rcode = eeprom_write (dev_addr, off, (uchar *) addr, cnt); - - puts ("done\n"); - return rcode; - } - } - - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; -} -#endif /* CFG_CMD_EEPROM */ - -/*----------------------------------------------------------------------- - * - * for CFG_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is - * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM. - * - * for CFG_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is - * 0x00000nxx for EEPROM address selectors and page number at n. - */ - -#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM) - -#ifndef CONFIG_SPI -#if !defined(CFG_I2C_EEPROM_ADDR_LEN) || CFG_I2C_EEPROM_ADDR_LEN < 1 || CFG_I2C_EEPROM_ADDR_LEN > 2 -#error CFG_I2C_EEPROM_ADDR_LEN must be 1 or 2 -#endif -#endif - -int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt) -{ - unsigned end = offset + cnt; - unsigned blk_off; - int rcode = 0; - - /* Read data until done or would cross a page boundary. - * We must write the address again when changing pages - * because the next page may be in a different device. - */ - while (offset < end) { - unsigned alen, len; -#if !defined(CFG_I2C_FRAM) - unsigned maxlen; -#endif - -#if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X) - uchar addr[2]; - - blk_off = offset & 0xFF; /* block offset */ - - addr[0] = offset >> 8; /* block number */ - addr[1] = blk_off; /* block offset */ - alen = 2; -#else - uchar addr[3]; - - blk_off = offset & 0xFF; /* block offset */ - - addr[0] = offset >> 16; /* block number */ - addr[1] = offset >> 8; /* upper address octet */ - addr[2] = blk_off; /* lower address octet */ - alen = 3; -#endif /* CFG_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */ - - addr[0] |= dev_addr; /* insert device address */ - - len = end - offset; - - /* - * For a FRAM device there is no limit on the number of the - * bytes that can be ccessed with the single read or write - * operation. - */ -#if !defined(CFG_I2C_FRAM) - maxlen = 0x100 - blk_off; - if (maxlen > I2C_RXTX_LEN) - maxlen = I2C_RXTX_LEN; - if (len > maxlen) - len = maxlen; -#endif - -#ifdef CONFIG_SPI - spi_read (addr, alen, buffer, len); -#else - if (i2c_read (addr[0], offset, alen-1, buffer, len) != 0) - rcode = 1; -#endif - buffer += len; - offset += len; - } - - return rcode; -} - -/*----------------------------------------------------------------------- - * - * for CFG_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is - * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM. - * - * for CFG_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is - * 0x00000nxx for EEPROM address selectors and page number at n. - */ - -int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt) -{ - unsigned end = offset + cnt; - unsigned blk_off; - int rcode = 0; - -#if defined(CFG_EEPROM_X40430) - uchar contr_r_addr[2]; - uchar addr_void[2]; - uchar contr_reg[2]; - uchar ctrl_reg_v; - int i; -#endif - -#if defined(CFG_EEPROM_WREN) - eeprom_write_enable (dev_addr,1); -#endif - /* Write data until done or would cross a write page boundary. - * We must write the address again when changing pages - * because the address counter only increments within a page. - */ - - while (offset < end) { - unsigned alen, len; -#if !defined(CFG_I2C_FRAM) - unsigned maxlen; -#endif - -#if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X) - uchar addr[2]; - - blk_off = offset & 0xFF; /* block offset */ - - addr[0] = offset >> 8; /* block number */ - addr[1] = blk_off; /* block offset */ - alen = 2; -#else - uchar addr[3]; - - blk_off = offset & 0xFF; /* block offset */ - - addr[0] = offset >> 16; /* block number */ - addr[1] = offset >> 8; /* upper address octet */ - addr[2] = blk_off; /* lower address octet */ - alen = 3; -#endif /* CFG_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */ - - addr[0] |= dev_addr; /* insert device address */ - - len = end - offset; - - /* - * For a FRAM device there is no limit on the number of the - * bytes that can be ccessed with the single read or write - * operation. - */ -#if !defined(CFG_I2C_FRAM) - -#if defined(CFG_EEPROM_PAGE_WRITE_BITS) - -#define EEPROM_PAGE_SIZE (1 << CFG_EEPROM_PAGE_WRITE_BITS) -#define EEPROM_PAGE_OFFSET(x) ((x) & (EEPROM_PAGE_SIZE - 1)) - - maxlen = EEPROM_PAGE_SIZE - EEPROM_PAGE_OFFSET(blk_off); -#else - maxlen = 0x100 - blk_off; -#endif - if (maxlen > I2C_RXTX_LEN) - maxlen = I2C_RXTX_LEN; - - if (len > maxlen) - len = maxlen; -#endif - -#ifdef CONFIG_SPI - spi_write (addr, alen, buffer, len); -#else -#if defined(CFG_EEPROM_X40430) - /* Get the value of the control register. - * Set current address (internal pointer in the x40430) - * to 0x1ff. - */ - contr_r_addr[0] = 9; - contr_r_addr[1] = 0xff; - addr_void[0] = 0; - addr_void[1] = addr[1]; -#ifdef CFG_I2C_EEPROM_ADDR - contr_r_addr[0] |= CFG_I2C_EEPROM_ADDR; - addr_void[0] |= CFG_I2C_EEPROM_ADDR; -#endif - contr_reg[0] = 0xff; - if (i2c_read (contr_r_addr[0], contr_r_addr[1], 1, contr_reg, 1) != 0) { - rcode = 1; - } - ctrl_reg_v = contr_reg[0]; - - /* Are any of the eeprom blocks write protected? - */ - if (ctrl_reg_v & 0x18) { - ctrl_reg_v &= ~0x18; /* reset block protect bits */ - ctrl_reg_v |= 0x02; /* set write enable latch */ - ctrl_reg_v &= ~0x04; /* clear RWEL */ - - /* Set write enable latch. - */ - contr_reg[0] = 0x02; - if (i2c_write (contr_r_addr[0], 0xff, 1, contr_reg, 1) != 0) { - rcode = 1; - } - - /* Set register write enable latch. - */ - contr_reg[0] = 0x06; - if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) { - rcode = 1; - } - - /* Modify ctrl register. - */ - contr_reg[0] = ctrl_reg_v; - if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) { - rcode = 1; - } - - /* The write (above) is an operation on NV memory. - * These can take some time (~5ms), and the device - * will not respond to further I2C messages till - * it's completed the write. - * So poll device for an I2C acknowledge. - * When we get one we know we can continue with other - * operations. - */ - contr_reg[0] = 0; - for (i = 0; i < MAX_ACKNOWLEDGE_POLLS; i++) { - if (i2c_read (addr_void[0], addr_void[1], 1, contr_reg, 1) == 0) - break; /* got ack */ -#if defined(CFG_EEPROM_PAGE_WRITE_DELAY_MS) - udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); -#endif - } - if (i == MAX_ACKNOWLEDGE_POLLS) { - puts ("EEPROM poll acknowledge failed\n"); - rcode = 1; - } - } - - /* Is the write enable latch on?. - */ - else if (!(ctrl_reg_v & 0x02)) { - /* Set write enable latch. - */ - contr_reg[0] = 0x02; - if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) { - rcode = 1; - } - } - /* Write is enabled ... now write eeprom value. - */ -#endif - if (i2c_write (addr[0], offset, alen-1, buffer, len) != 0) - rcode = 1; - -#endif - buffer += len; - offset += len; - -#if defined(CFG_EEPROM_PAGE_WRITE_DELAY_MS) - udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); -#endif - } -#if defined(CFG_EEPROM_WREN) - eeprom_write_enable (dev_addr,0); -#endif - return rcode; -} - -#ifndef CONFIG_SPI -int -eeprom_probe (unsigned dev_addr, unsigned offset) -{ - unsigned char chip; - - /* Probe the chip address - */ -#if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X) - chip = offset >> 8; /* block number */ -#else - chip = offset >> 16; /* block number */ -#endif /* CFG_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */ - - chip |= dev_addr; /* insert device address */ - - return (i2c_probe (chip)); -} -#endif - -/*----------------------------------------------------------------------- - * Set default values - */ -#ifndef CFG_I2C_SPEED -#define CFG_I2C_SPEED 50000 -#endif - -#ifndef CFG_I2C_SLAVE -#define CFG_I2C_SLAVE 0xFE -#endif - -void eeprom_init (void) -{ -#if defined(CONFIG_SPI) - spi_init_f (); -#endif -#if defined(CONFIG_HARD_I2C) || \ - defined(CONFIG_SOFT_I2C) - i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); -#endif -} -/*----------------------------------------------------------------------- - */ -#endif /* CFG_CMD_EEPROM */ -/***************************************************/ - -#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) - -#ifdef CFG_I2C_MULTI_EEPROMS -U_BOOT_CMD( - eeprom, 6, 1, do_eeprom, - "eeprom - EEPROM sub-system\n", - "read devaddr addr off cnt\n" - "eeprom write devaddr addr off cnt\n" - " - read/write `cnt' bytes from `devaddr` EEPROM at offset `off'\n" -); -#else /* One EEPROM */ -U_BOOT_CMD( - eeprom, 5, 1, do_eeprom, - "eeprom - EEPROM sub-system\n", - "read addr off cnt\n" - "eeprom write addr off cnt\n" - " - read/write `cnt' bytes at EEPROM offset `off'\n" -); -#endif /* CFG_I2C_MULTI_EEPROMS */ - -#endif /* CFG_CMD_EEPROM */ diff --git a/common/cmd_elf.c b/common/cmd_elf.c deleted file mode 100644 index 9c5d81ecae..0000000000 --- a/common/cmd_elf.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2001 William L. Pitts - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - */ - -#include <common.h> -#include <command.h> -#include <linux/ctype.h> -#include <net.h> -#include <elf.h> - -#if defined(CONFIG_WALNUT) || defined(CFG_VXWORKS_MAC_PTR) -DECLARE_GLOBAL_DATA_PTR; -#endif - -#if (CONFIG_COMMANDS & CFG_CMD_ELF) - -#ifndef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -int valid_elf_image (unsigned long addr); -unsigned long load_elf_image (unsigned long addr); - -/* ====================================================================== - * Interpreter command to boot an arbitrary ELF image from memory. - * ====================================================================== */ -int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned long addr; /* Address of the ELF image */ - unsigned long rc; /* Return value from user code */ - - /* -------------------------------------------------- */ - int rcode = 0; - - if (argc < 2) - addr = load_addr; - else - addr = simple_strtoul (argv[1], NULL, 16); - - if (!valid_elf_image (addr)) - return 1; - - addr = load_elf_image (addr); - - printf ("## Starting application at 0x%08lx ...\n", addr); - - /* - * QNX images require the data cache is disabled. - * Data cache is already flushed, so just turn it off. - */ - if (dcache_status ()) - dcache_disable (); - - /* - * pass address parameter as argv[0] (aka command name), - * and all remaining args - */ - rc = ((ulong (*)(int, char *[])) addr) (--argc, &argv[1]); - if (rc != 0) - rcode = 1; - - printf ("## Application terminated, rc = 0x%lx\n", rc); - return rcode; -} - -/* ====================================================================== - * Interpreter command to boot VxWorks from a memory image. The image can - * be either an ELF image or a raw binary. Will attempt to setup the - * bootline and other parameters correctly. - * ====================================================================== */ -int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned long addr; /* Address of image */ - unsigned long bootaddr; /* Address to put the bootline */ - char *bootline; /* Text of the bootline */ - char *tmp; /* Temporary char pointer */ - -#if defined(CONFIG_4xx) || defined(CONFIG_IOP480) - char build_buf[80]; /* Buffer for building the bootline */ -#endif - /* -------------------------------------------------- */ - - /* - * Check the loadaddr variable. - * If we don't know where the image is then we're done. - */ - - if (argc < 2) - addr = load_addr; - else - addr = simple_strtoul (argv[1], NULL, 16); - -#if (CONFIG_COMMANDS & CFG_CMD_NET) - /* Check to see if we need to tftp the image ourselves before starting */ - - if ((argc == 2) && (strcmp (argv[1], "tftp") == 0)) { - if (NetLoop (TFTP) <= 0) - return 1; - printf ("Automatic boot of VxWorks image at address 0x%08lx ... \n", addr); - } -#endif - - /* This should equate - * to NV_RAM_ADRS + NV_BOOT_OFFSET + NV_ENET_OFFSET - * from the VxWorks BSP header files. - * This will vary from board to board - */ - -#if defined(CONFIG_WALNUT) - tmp = (char *) CFG_NVRAM_BASE_ADDR + 0x500; - memcpy ((char *) tmp, (char *) &gd->bd->bi_enetaddr[3], 3); -#elif defined(CFG_VXWORKS_MAC_PTR) - tmp = (char *) CFG_VXWORKS_MAC_PTR; - memcpy ((char *) tmp, (char *) &gd->bd->bi_enetaddr[0], 6); -#else - puts ("## Ethernet MAC address not copied to NV RAM\n"); -#endif - - /* - * Use bootaddr to find the location in memory that VxWorks - * will look for the bootline string. The default value for - * PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which - * defaults to 0x4200 - */ - - if ((tmp = getenv ("bootaddr")) == NULL) - bootaddr = 0x4200; - else - bootaddr = simple_strtoul (tmp, NULL, 16); - - /* - * Check to see if the bootline is defined in the 'bootargs' - * parameter. If it is not defined, we may be able to - * construct the info - */ - - if ((bootline = getenv ("bootargs")) != NULL) { - memcpy ((void *) bootaddr, bootline, MAX(strlen(bootline), 255)); - flush_cache (bootaddr, MAX(strlen(bootline), 255)); - } else { -#if defined(CONFIG_4xx) - sprintf (build_buf, "ibmEmac(0,0)"); - - if ((tmp = getenv ("hostname")) != NULL) { - sprintf (&build_buf[strlen (build_buf - 1)], - "host:%s ", tmp); - } else { - sprintf (&build_buf[strlen (build_buf - 1)], - ": "); - } - - if ((tmp = getenv ("ipaddr")) != NULL) { - sprintf (&build_buf[strlen (build_buf - 1)], - "e=%s ", tmp); - } - memcpy ((void *)bootaddr, build_buf, MAX(strlen(build_buf), 255)); - flush_cache (bootaddr, MAX(strlen(build_buf), 255)); -#elif defined(CONFIG_IOP480) - sprintf (build_buf, "dc(0,0)"); - - if ((tmp = getenv ("hostname")) != NULL) { - sprintf (&build_buf[strlen (build_buf - 1)], - "host:%s ", tmp); - } else { - sprintf (&build_buf[strlen (build_buf - 1)], - ": "); - } - - if ((tmp = getenv ("ipaddr")) != NULL) { - sprintf (&build_buf[strlen (build_buf - 1)], - "e=%s ", tmp); - } - memcpy ((void *) bootaddr, build_buf, MAX(strlen(build_buf), 255)); - flush_cache (bootaddr, MAX(strlen(build_buf), 255)); -#else - - /* - * I'm not sure what the device should be for other - * PPC flavors, the hostname and ipaddr should be ok - * to just copy - */ - - puts ("No bootargs defined\n"); - return 1; -#endif - } - - /* - * If the data at the load address is an elf image, then - * treat it like an elf image. Otherwise, assume that it is a - * binary image - */ - - if (valid_elf_image (addr)) { - addr = load_elf_image (addr); - } else { - puts ("## Not an ELF image, assuming binary\n"); - /* leave addr as load_addr */ - } - - printf ("## Using bootline (@ 0x%lx): %s\n", bootaddr, - (char *) bootaddr); - printf ("## Starting vxWorks at 0x%08lx ...\n", addr); - - ((void (*)(void)) addr) (); - - puts ("## vxWorks terminated\n"); - return 1; -} - -/* ====================================================================== - * Determine if a valid ELF image exists at the given memory location. - * First looks at the ELF header magic field, the makes sure that it is - * executable and makes sure that it is for a PowerPC. - * ====================================================================== */ -int valid_elf_image (unsigned long addr) -{ - Elf32_Ehdr *ehdr; /* Elf header structure pointer */ - - /* -------------------------------------------------- */ - - ehdr = (Elf32_Ehdr *) addr; - - if (!IS_ELF (*ehdr)) { - printf ("## No elf image at address 0x%08lx\n", addr); - return 0; - } - - if (ehdr->e_type != ET_EXEC) { - printf ("## Not a 32-bit elf image at address 0x%08lx\n", - addr); - return 0; - } - - - return 1; -} - - -/* ====================================================================== - * A very simple elf loader, assumes the image is valid, returns the - * entry point address. - * ====================================================================== */ -unsigned long load_elf_image (unsigned long addr) -{ - Elf32_Ehdr *ehdr; /* Elf header structure pointer */ - Elf32_Shdr *shdr; /* Section header structure pointer */ - unsigned char *strtab = 0; /* String table pointer */ - unsigned char *image; /* Binary image pointer */ - int i; /* Loop counter */ - - /* -------------------------------------------------- */ - - ehdr = (Elf32_Ehdr *) addr; - - /* Find the section header string table for output info */ - shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff + - (ehdr->e_shstrndx * sizeof (Elf32_Shdr))); - - if (shdr->sh_type == SHT_STRTAB) - strtab = (unsigned char *) (addr + shdr->sh_offset); - - /* Load each appropriate section */ - for (i = 0; i < ehdr->e_shnum; ++i) { - shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff + - (i * sizeof (Elf32_Shdr))); - - if (!(shdr->sh_flags & SHF_ALLOC) - || shdr->sh_addr == 0 || shdr->sh_size == 0) { - continue; - } - - if (strtab) { - printf ("%sing %s @ 0x%08lx (%ld bytes)\n", - (shdr->sh_type == SHT_NOBITS) ? - "Clear" : "Load", - &strtab[shdr->sh_name], - (unsigned long) shdr->sh_addr, - (long) shdr->sh_size); - } - - if (shdr->sh_type == SHT_NOBITS) { - memset ((void *)shdr->sh_addr, 0, shdr->sh_size); - } else { - image = (unsigned char *) addr + shdr->sh_offset; - memcpy ((void *) shdr->sh_addr, - (const void *) image, - shdr->sh_size); - } - flush_cache (shdr->sh_addr, shdr->sh_size); - } - - return ehdr->e_entry; -} - -/* ====================================================================== */ -U_BOOT_CMD( - bootelf, 2, 0, do_bootelf, - "bootelf - Boot from an ELF image in memory\n", - " [address] - load address of ELF image.\n" -); - -U_BOOT_CMD( - bootvx, 2, 0, do_bootvx, - "bootvx - Boot vxWorks from an ELF image\n", - " [address] - load address of vxWorks ELF image.\n" -); - -#endif /* CFG_CMD_ELF */ diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c deleted file mode 100644 index 1f2c0bc0b9..0000000000 --- a/common/cmd_fdc.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * (C) Copyright 2001 - * Denis Peter, MPL AG, d.peter@mpl.ch. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ -/* - * Floppy Disk support - */ - -#include <common.h> -#include <config.h> -#include <command.h> -#include <image.h> - - -#undef FDC_DEBUG - -#ifdef FDC_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - - -/*#if (CONFIG_COMMANDS & CFG_CMD_DATE) */ -/*#include <rtc.h> */ -/*#endif */ - -#if ((CONFIG_COMMANDS & CFG_CMD_FDC) || (CONFIG_COMMANDS & CFG_CMD_FDOS)) - - -typedef struct { - int flags; /* connected drives ect */ - unsigned long blnr; /* Logical block nr */ - uchar drive; /* drive no */ - uchar cmdlen; /* cmd length */ - uchar cmd[16]; /* cmd desc */ - uchar dma; /* if > 0 dma enabled */ - uchar result[11];/* status information */ - uchar resultlen; /* lenght of result */ -} FDC_COMMAND_STRUCT; -/* flags: only the lower 8bit used: - * bit 0 if set drive 0 is present - * bit 1 if set drive 1 is present - * bit 2 if set drive 2 is present - * bit 3 if set drive 3 is present - * bit 4 if set disk in drive 0 is inserted - * bit 5 if set disk in drive 1 is inserted - * bit 6 if set disk in drive 2 is inserted - * bit 7 if set disk in drive 4 is inserted - */ - - -/* cmd indexes */ -#define COMMAND 0 -#define DRIVE 1 -#define CONFIG0 1 -#define SPEC_HUTSRT 1 -#define TRACK 2 -#define CONFIG1 2 -#define SPEC_HLT 2 -#define HEAD 3 -#define CONFIG2 3 -#define SECTOR 4 -#define SECTOR_SIZE 5 -#define LAST_TRACK 6 -#define GAP 7 -#define DTL 8 -/* result indexes */ -#define STATUS_0 0 -#define STATUS_PCN 1 -#define STATUS_1 1 -#define STATUS_2 2 -#define STATUS_TRACK 3 -#define STATUS_HEAD 4 -#define STATUS_SECT 5 -#define STATUS_SECT_SIZE 6 - - -/* Register addresses */ -#define FDC_BASE 0x3F0 -#define FDC_SRA FDC_BASE + 0 /* Status Register A */ -#define FDC_SRB FDC_BASE + 1 /* Status Register B */ -#define FDC_DOR FDC_BASE + 2 /* Digital Output Register */ -#define FDC_TDR FDC_BASE + 3 /* Tape Drive Register */ -#define FDC_DSR FDC_BASE + 4 /* Data rate Register */ -#define FDC_MSR FDC_BASE + 4 /* Main Status Register */ -#define FDC_FIFO FDC_BASE + 5 /* FIFO */ -#define FDC_DIR FDC_BASE + 6 /* Digital Input Register */ -#define FDC_CCR FDC_BASE + 7 /* Configuration Control */ -/* Commands */ -#define FDC_CMD_SENSE_INT 0x08 -#define FDC_CMD_CONFIGURE 0x13 -#define FDC_CMD_SPECIFY 0x03 -#define FDC_CMD_RECALIBRATE 0x07 -#define FDC_CMD_READ 0x06 -#define FDC_CMD_READ_TRACK 0x02 -#define FDC_CMD_READ_ID 0x0A -#define FDC_CMD_DUMP_REG 0x0E -#define FDC_CMD_SEEK 0x0F - -#define FDC_CMD_SENSE_INT_LEN 0x01 -#define FDC_CMD_CONFIGURE_LEN 0x04 -#define FDC_CMD_SPECIFY_LEN 0x03 -#define FDC_CMD_RECALIBRATE_LEN 0x02 -#define FDC_CMD_READ_LEN 0x09 -#define FDC_CMD_READ_TRACK_LEN 0x09 -#define FDC_CMD_READ_ID_LEN 0x02 -#define FDC_CMD_DUMP_REG_LEN 0x01 -#define FDC_CMD_SEEK_LEN 0x03 - -#define FDC_FIFO_THR 0x0C -#define FDC_FIFO_DIS 0x00 -#define FDC_IMPLIED_SEEK 0x01 -#define FDC_POLL_DIS 0x00 -#define FDC_PRE_TRK 0x00 -#define FDC_CONFIGURE FDC_FIFO_THR | (FDC_POLL_DIS<<4) | (FDC_FIFO_DIS<<5) | (FDC_IMPLIED_SEEK << 6) -#define FDC_MFM_MODE 0x01 /* MFM enable */ -#define FDC_SKIP_MODE 0x00 /* skip enable */ - -#define FDC_TIME_OUT 100000 /* time out */ -#define FDC_RW_RETRIES 3 /* read write retries */ -#define FDC_CAL_RETRIES 3 /* calibration and seek retries */ - - -/* Disk structure */ -typedef struct { - unsigned int size; /* nr of sectors total */ - unsigned int sect; /* sectors per track */ - unsigned int head; /* nr of heads */ - unsigned int track; /* nr of tracks */ - unsigned int stretch; /* !=0 means double track steps */ - unsigned char gap; /* gap1 size */ - unsigned char rate; /* data rate. |= 0x40 for perpendicular */ - unsigned char spec1; /* stepping rate, head unload time */ - unsigned char fmt_gap; /* gap2 size */ - unsigned char hlt; /* head load time */ - unsigned char sect_code; /* Sector Size code */ - const char * name; /* used only for predefined formats */ -} FD_GEO_STRUCT; - - -/* supported Floppy types (currently only one) */ -const static FD_GEO_STRUCT floppy_type[2] = { - { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,16,2,"H1440" }, /* 7 1.44MB 3.5" */ - { 0, 0,0, 0,0,0x00,0x00,0x00,0x00, 0,0,NULL }, /* end of table */ -}; - -static FDC_COMMAND_STRUCT cmd; /* global command struct */ - -/* If the boot drive number is undefined, we assume it's drive 0 */ -#ifndef CFG_FDC_DRIVE_NUMBER -#define CFG_FDC_DRIVE_NUMBER 0 -#endif - -/* Hardware access */ -#ifndef CFG_ISA_IO_STRIDE -#define CFG_ISA_IO_STRIDE 1 -#endif - -#ifndef CFG_ISA_IO_OFFSET -#define CFG_ISA_IO_OFFSET 0 -#endif - - -#ifdef CONFIG_AMIGAONEG3SE -unsigned char INT6_Status; - -void fdc_interrupt(void) -{ - INT6_Status = 0x80; -} - -/* waits for an interrupt (polling) */ -int wait_for_fdc_int(void) -{ - unsigned long timeout; - timeout = FDC_TIME_OUT; - while(((volatile)INT6_Status & 0x80) == 0) { - timeout--; - udelay(10); - if(timeout == 0) /* timeout occured */ - return FALSE; - } - INT6_Status = 0; - return TRUE; -} -#endif - -/* Supporting Functions */ -/* reads a Register of the FDC */ -unsigned char read_fdc_reg(unsigned int addr) -{ - volatile unsigned char *val = - (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS + - (addr * CFG_ISA_IO_STRIDE) + - CFG_ISA_IO_OFFSET); - - return val [0]; -} - -/* writes a Register of the FDC */ -void write_fdc_reg(unsigned int addr, unsigned char val) -{ - volatile unsigned char *tmp = - (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS + - (addr * CFG_ISA_IO_STRIDE) + - CFG_ISA_IO_OFFSET); - tmp[0]=val; -} - -#ifndef CONFIG_AMIGAONEG3SE -/* waits for an interrupt (polling) */ -int wait_for_fdc_int(void) -{ - unsigned long timeout; - timeout = FDC_TIME_OUT; - while((read_fdc_reg(FDC_SRA)&0x80)==0) { - timeout--; - udelay(10); - if(timeout==0) /* timeout occured */ - return FALSE; - } - return TRUE; -} - -#endif - -/* reads a byte from the FIFO of the FDC and checks direction and RQM bit - of the MSR. returns -1 if timeout, or byte if ok */ -int read_fdc_byte(void) -{ - unsigned long timeout; - timeout = FDC_TIME_OUT; - while((read_fdc_reg(FDC_MSR)&0xC0)!=0xC0) { - /* direction out and ready */ - udelay(10); - timeout--; - if(timeout==0) /* timeout occured */ - return -1; - } - return read_fdc_reg(FDC_FIFO); -} - -/* if the direction of the FIFO is wrong, this routine is used to - empty the FIFO. Should _not_ be used */ -int fdc_need_more_output(void) -{ - unsigned char c; - while((read_fdc_reg(FDC_MSR)&0xC0)==0xC0) { - c=(unsigned char)read_fdc_byte(); - printf("Error: more output: %x\n",c); - } - return TRUE; -} - - -/* writes a byte to the FIFO of the FDC and checks direction and RQM bit - of the MSR */ -int write_fdc_byte(unsigned char val) -{ - unsigned long timeout; - timeout = FDC_TIME_OUT; - while((read_fdc_reg(FDC_MSR)&0xC0)!=0x80) { - /* direction in and ready for byte */ - timeout--; - udelay(10); - fdc_need_more_output(); - if(timeout==0) /* timeout occured */ - return FALSE; - } - write_fdc_reg(FDC_FIFO,val); - return TRUE; -} - -/* sets up all FDC commands and issues it to the FDC. If - the command causes direct results (no Execution Phase) - the result is be read as well. */ - -int fdc_issue_cmd(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) -{ - int i; - unsigned long head,track,sect,timeout; - track = pCMD->blnr / (pFG->sect * pFG->head); /* track nr */ - sect = pCMD->blnr % (pFG->sect * pFG->head); /* remaining blocks */ - head = sect / pFG->sect; /* head nr */ - sect = sect % pFG->sect; /* remaining blocks */ - sect++; /* sectors are 1 based */ - PRINTF("Cmd 0x%02x Track %ld, Head %ld, Sector %ld, Drive %d (blnr %ld)\n", - pCMD->cmd[0],track,head,sect,pCMD->drive,pCMD->blnr); - - if(head|=0) { /* max heads = 2 */ - pCMD->cmd[DRIVE]=pCMD->drive | 0x04; /* head 1 */ - pCMD->cmd[HEAD]=(unsigned char) head; /* head register */ - } - else { - pCMD->cmd[DRIVE]=pCMD->drive; /* head 0 */ - pCMD->cmd[HEAD]=(unsigned char) head; /* head register */ - } - pCMD->cmd[TRACK]=(unsigned char) track; /* track */ - switch (pCMD->cmd[COMMAND]) { - case FDC_CMD_READ: - pCMD->cmd[SECTOR]=(unsigned char) sect; /* sector */ - pCMD->cmd[SECTOR_SIZE]=pFG->sect_code; /* sector size code */ - pCMD->cmd[LAST_TRACK]=pFG->sect; /* End of track */ - pCMD->cmd[GAP]=pFG->gap; /* gap */ - pCMD->cmd[DTL]=0xFF; /* DTL */ - pCMD->cmdlen=FDC_CMD_READ_LEN; - pCMD->cmd[COMMAND]|=(FDC_MFM_MODE<<6); /* set MFM bit */ - pCMD->cmd[COMMAND]|=(FDC_SKIP_MODE<<5); /* set Skip bit */ - pCMD->resultlen=0; /* result only after execution */ - break; - case FDC_CMD_SEEK: - pCMD->cmdlen=FDC_CMD_SEEK_LEN; - pCMD->resultlen=0; /* no result */ - break; - case FDC_CMD_CONFIGURE: - pCMD->cmd[CONFIG0]=0; - pCMD->cmd[CONFIG1]=FDC_CONFIGURE; /* FIFO Threshold, Poll, Enable FIFO */ - pCMD->cmd[CONFIG2]=FDC_PRE_TRK; /* Precompensation Track */ - pCMD->cmdlen=FDC_CMD_CONFIGURE_LEN; - pCMD->resultlen=0; /* no result */ - break; - case FDC_CMD_SPECIFY: - pCMD->cmd[SPEC_HUTSRT]=pFG->spec1; - pCMD->cmd[SPEC_HLT]=(pFG->hlt)<<1; /* head load time */ - if(pCMD->dma==0) - pCMD->cmd[SPEC_HLT]|=0x1; /* no dma */ - pCMD->cmdlen=FDC_CMD_SPECIFY_LEN; - pCMD->resultlen=0; /* no result */ - break; - case FDC_CMD_DUMP_REG: - pCMD->cmdlen=FDC_CMD_DUMP_REG_LEN; - pCMD->resultlen=10; /* 10 byte result */ - break; - case FDC_CMD_READ_ID: - pCMD->cmd[COMMAND]|=(FDC_MFM_MODE<<6); /* set MFM bit */ - pCMD->cmdlen=FDC_CMD_READ_ID_LEN; - pCMD->resultlen=7; /* 7 byte result */ - break; - case FDC_CMD_RECALIBRATE: - pCMD->cmd[DRIVE]&=0x03; /* don't set the head bit */ - pCMD->cmdlen=FDC_CMD_RECALIBRATE_LEN; - pCMD->resultlen=0; /* no result */ - break; - break; - case FDC_CMD_SENSE_INT: - pCMD->cmdlen=FDC_CMD_SENSE_INT_LEN; - pCMD->resultlen=2; - break; - } - for(i=0;i<pCMD->cmdlen;i++) { - /* PRINTF("write cmd%d = 0x%02X\n",i,pCMD->cmd[i]); */ - if(write_fdc_byte(pCMD->cmd[i])==FALSE) { - PRINTF("Error: timeout while issue cmd%d\n",i); - return FALSE; - } - } - timeout=FDC_TIME_OUT; - for(i=0;i<pCMD->resultlen;i++) { - while((read_fdc_reg(FDC_MSR)&0xC0)!=0xC0) { - timeout--; - if(timeout==0) { - PRINTF(" timeout while reading result%d MSR=0x%02X\n",i,read_fdc_reg(FDC_MSR)); - return FALSE; - } - } - pCMD->result[i]=(unsigned char)read_fdc_byte(); - } - return TRUE; -} - -/* selects the drive assigned in the cmd structur and - switches on the Motor */ -void select_fdc_drive(FDC_COMMAND_STRUCT *pCMD) -{ - unsigned char val; - - val=(1<<(4+pCMD->drive))|pCMD->drive|0xC; /* set reset, dma gate and motor bits */ - if((read_fdc_reg(FDC_DOR)&val)!=val) { - write_fdc_reg(FDC_DOR,val); - for(val=0;val<255;val++) - udelay(500); /* wait some time to start motor */ - } -} - -/* switches off the Motor of the specified drive */ -void stop_fdc_drive(FDC_COMMAND_STRUCT *pCMD) -{ - unsigned char val; - - val=(1<<(4+pCMD->drive))|pCMD->drive; /* sets motor bits */ - write_fdc_reg(FDC_DOR,(read_fdc_reg(FDC_DOR)&~val)); -} - -/* issues a recalibrate command, waits for interrupt and - * issues a sense_interrupt */ -int fdc_recalibrate(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) -{ - pCMD->cmd[COMMAND]=FDC_CMD_RECALIBRATE; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) - return FALSE; - while(wait_for_fdc_int()!=TRUE); - pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT; - return(fdc_issue_cmd(pCMD,pFG)); -} - -/* issues a recalibrate command, waits for interrupt and - * issues a sense_interrupt */ -int fdc_seek(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) -{ - pCMD->cmd[COMMAND]=FDC_CMD_SEEK; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) - return FALSE; - while(wait_for_fdc_int()!=TRUE); - pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT; - return(fdc_issue_cmd(pCMD,pFG)); -} - -#ifndef CONFIG_AMIGAONEG3SE -/* terminates current command, by not servicing the FIFO - * waits for interrupt and fills in the result bytes */ -int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) -{ - int i; - for(i=0;i<100;i++) - udelay(500); /* wait 500usec for fifo overrun */ - while((read_fdc_reg(FDC_SRA)&0x80)==0x00); /* wait as long as no int has occured */ - for(i=0;i<7;i++) { - pCMD->result[i]=(unsigned char)read_fdc_byte(); - } - return TRUE; -} -#endif -#ifdef CONFIG_AMIGAONEG3SE -int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) -{ - int i; - for(i=0;i<100;i++) - udelay(500); /* wait 500usec for fifo overrun */ - while((INT6_Status&0x80)==0x00); /* wait as long as no int has occured */ - for(i=0;i<7;i++) { - pCMD->result[i]=(unsigned char)read_fdc_byte(); - } - INT6_Status = 0; - return TRUE; -} - -#endif - -#ifdef CONFIG_AMIGAONEG3SE -#define disable_interrupts() 0 -#define enable_interrupts() (void)0 -#endif - -/* reads data from FDC, seek commands are issued automatic */ -int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) -{ - /* first seek to start address */ - unsigned long len,lastblk,readblk,i,timeout,ii,offset; - unsigned char pcn,c,retriesrw,retriescal; - unsigned char *bufferw; /* working buffer */ - int sect_size; - int flags; - - flags=disable_interrupts(); /* switch off all Interrupts */ - select_fdc_drive(pCMD); /* switch on drive */ - sect_size=0x080<<pFG->sect_code; - retriesrw=0; - retriescal=0; - offset=0; - if(fdc_seek(pCMD,pFG)==FALSE) { - stop_fdc_drive(pCMD); - enable_interrupts(); - return FALSE; - } - if((pCMD->result[STATUS_0]&0x20)!=0x20) { - printf("Seek error Status: %02X\n",pCMD->result[STATUS_0]); - stop_fdc_drive(pCMD); - enable_interrupts(); - return FALSE; - } - pcn=pCMD->result[STATUS_PCN]; /* current track */ - /* now determine the next seek point */ - lastblk=pCMD->blnr + blocks; - /* readblk=(pFG->head*pFG->sect)-(pCMD->blnr%(pFG->head*pFG->sect)); */ - readblk=pFG->sect-(pCMD->blnr%pFG->sect); - PRINTF("1st nr of block possible read %ld start %ld\n",readblk,pCMD->blnr); - if(readblk>blocks) /* is end within 1st track */ - readblk=blocks; /* yes, correct it */ - PRINTF("we read %ld blocks start %ld\n",readblk,pCMD->blnr); - bufferw=&buffer[0]; /* setup working buffer */ - do { -retryrw: - len=sect_size * readblk; - pCMD->cmd[COMMAND]=FDC_CMD_READ; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) { - stop_fdc_drive(pCMD); - enable_interrupts(); - return FALSE; - } - for (i=0;i<len;i++) { - timeout=FDC_TIME_OUT; - do { - c=read_fdc_reg(FDC_MSR); - if((c&0xC0)==0xC0) { - bufferw[i]=read_fdc_reg(FDC_FIFO); - break; - } - if((c&0xC0)==0x80) { /* output */ - PRINTF("Transfer error transfered: at %ld, MSR=%02X\n",i,c); - if(i>6) { - for(ii=0;ii<7;ii++) { - pCMD->result[ii]=bufferw[(i-7+ii)]; - } /* for */ - } - if(retriesrw++>FDC_RW_RETRIES) { - if (retriescal++>FDC_CAL_RETRIES) { - stop_fdc_drive(pCMD); - enable_interrupts(); - return FALSE; - } - else { - PRINTF(" trying to recalibrate Try %d\n",retriescal); - if(fdc_recalibrate(pCMD,pFG)==FALSE) { - stop_fdc_drive(pCMD); - enable_interrupts(); - return FALSE; - } - retriesrw=0; - goto retrycal; - } /* else >FDC_CAL_RETRIES */ - } - else { - PRINTF("Read retry %d\n",retriesrw); - goto retryrw; - } /* else >FDC_RW_RETRIES */ - }/* if output */ - timeout--; - }while(TRUE); - } /* for len */ - /* the last sector of a track or all data has been read, - * we need to get the results */ - fdc_terminate(pCMD); - offset+=(sect_size*readblk); /* set up buffer pointer */ - bufferw=&buffer[offset]; - pCMD->blnr+=readblk; /* update current block nr */ - blocks-=readblk; /* update blocks */ - if(blocks==0) - break; /* we are finish */ - /* setup new read blocks */ - /* readblk=pFG->head*pFG->sect; */ - readblk=pFG->sect; - if(readblk>blocks) - readblk=blocks; -retrycal: - /* a seek is necessary */ - if(fdc_seek(pCMD,pFG)==FALSE) { - stop_fdc_drive(pCMD); - enable_interrupts(); - return FALSE; - } - if((pCMD->result[STATUS_0]&0x20)!=0x20) { - PRINTF("Seek error Status: %02X\n",pCMD->result[STATUS_0]); - stop_fdc_drive(pCMD); - return FALSE; - } - pcn=pCMD->result[STATUS_PCN]; /* current track */ - }while(TRUE); /* start over */ - stop_fdc_drive(pCMD); /* switch off drive */ - enable_interrupts(); - return TRUE; -} - -#ifdef CONFIG_AMIGAONEG3SE -#undef disable_interrupts() -#undef enable_interrupts() -#endif - -/* Scan all drives and check if drive is present and disk is inserted */ -int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) -{ - int i,drives,state; - /* OK procedure of data book is satisfied. - * trying to get some information over the drives */ - state=0; /* no drives, no disks */ - for(drives=0;drives<4;drives++) { - pCMD->drive=drives; - select_fdc_drive(pCMD); - pCMD->blnr=0; /* set to the 1st block */ - if(fdc_recalibrate(pCMD,pFG)==FALSE) - continue; - if((pCMD->result[STATUS_0]&0x10)==0x10) - continue; - /* ok drive connected check for disk */ - state|=(1<<drives); - pCMD->blnr=pFG->size; /* set to the last block */ - if(fdc_seek(pCMD,pFG)==FALSE) - continue; - pCMD->blnr=0; /* set to the 1st block */ - if(fdc_recalibrate(pCMD,pFG)==FALSE) - continue; - pCMD->cmd[COMMAND]=FDC_CMD_READ_ID; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) - continue; - state|=(0x10<<drives); - } - stop_fdc_drive(pCMD); - for(i=0;i<4;i++) { - PRINTF("Floppy Drive %d %sconnected %sDisk inserted %s\n",i, - ((state&(1<<i))==(1<<i)) ? "":"not ", - ((state&(0x10<<i))==(0x10<<i)) ? "":"no ", - ((state&(0x10<<i))==(0x10<<i)) ? pFG->name : ""); - } - pCMD->flags=state; - return TRUE; -} - - -/************************************************************************** -* int fdc_setup -* setup the fdc according the datasheet -* assuming in PS2 Mode -*/ -int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) -{ - int i; - -#ifdef CONFIG_AMIGAONEG3SE - irq_install_handler(6, (interrupt_handler_t *)fdc_interrupt, NULL); - i8259_unmask_irq(6); -#endif - -#ifdef CFG_FDC_HW_INIT - fdc_hw_init (); -#endif - /* first, we reset the FDC via the DOR */ - write_fdc_reg(FDC_DOR,0x00); - for(i=0; i<255; i++) /* then we wait some time */ - udelay(500); - /* then, we clear the reset in the DOR */ - pCMD->drive=drive; - select_fdc_drive(pCMD); - /* initialize the CCR */ - write_fdc_reg(FDC_CCR,pFG->rate); - /* then initialize the DSR */ - write_fdc_reg(FDC_DSR,pFG->rate); - if(wait_for_fdc_int()==FALSE) { - PRINTF("Time Out after writing CCR\n"); - return FALSE; - } - /* now issue sense Interrupt and status command - * assuming only one drive present (drive 0) */ - pCMD->dma=0; /* we don't use any dma at all */ - for(i=0;i<4;i++) { - /* issue sense interrupt for all 4 possible drives */ - pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) { - PRINTF("Sense Interrupt for drive %d failed\n",i); - } - } - /* issue the configure command */ - pCMD->drive=drive; - select_fdc_drive(pCMD); - pCMD->cmd[COMMAND]=FDC_CMD_CONFIGURE; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) { - PRINTF(" configure timeout\n"); - stop_fdc_drive(pCMD); - return FALSE; - } - /* issue specify command */ - pCMD->cmd[COMMAND]=FDC_CMD_SPECIFY; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) { - PRINTF(" specify timeout\n"); - stop_fdc_drive(pCMD); - return FALSE; - - } - /* then, we clear the reset in the DOR */ - /* fdc_check_drive(pCMD,pFG); */ - /* write_fdc_reg(FDC_DOR,0x04); */ - - return TRUE; -} -#endif /* ((CONFIG_COMMANDS & CFG_CMD_FDC)||(CONFIG_COMMANDS & CFG_CMD_FDOS))*/ - -#if (CONFIG_COMMANDS & CFG_CMD_FDOS) - -/* Low level functions for the Floppy-DOS layer */ - -/************************************************************************** -* int fdc_fdos_init -* initialize the FDC layer -* -*/ -int fdc_fdos_init (int drive) -{ - FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; - FDC_COMMAND_STRUCT *pCMD = &cmd; - - /* setup FDC and scan for drives */ - if(fdc_setup(drive,pCMD,pFG)==FALSE) { - printf("\n** Error in setup FDC **\n"); - return FALSE; - } - if(fdc_check_drive(pCMD,pFG)==FALSE) { - printf("\n** Error in check_drives **\n"); - return FALSE; - } - if((pCMD->flags&(1<<drive))==0) { - /* drive not available */ - printf("\n** Drive %d not available **\n",drive); - return FALSE; - } - if((pCMD->flags&(0x10<<drive))==0) { - /* no disk inserted */ - printf("\n** No disk inserted in drive %d **\n",drive); - return FALSE; - } - /* ok, we have a valid source */ - pCMD->drive=drive; - - /* read first block */ - pCMD->blnr=0; - return TRUE; -} -/************************************************************************** -* int fdc_fdos_seek -* parameter is a block number -*/ -int fdc_fdos_seek (int where) -{ - FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; - FDC_COMMAND_STRUCT *pCMD = &cmd; - - pCMD -> blnr = where ; - return (fdc_seek (pCMD, pFG)); -} -/************************************************************************** -* int fdc_fdos_read -* the length is in block number -*/ -int fdc_fdos_read (void *buffer, int len) -{ - FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; - FDC_COMMAND_STRUCT *pCMD = &cmd; - - return (fdc_read_data (buffer, len, pCMD, pFG)); -} -#endif /* (CONFIG_COMMANDS & CFG_CMD_FDOS) */ - -#if (CONFIG_COMMANDS & CFG_CMD_FDC) -/**************************************************************************** - * main routine do_fdcboot - */ -int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; - FDC_COMMAND_STRUCT *pCMD = &cmd; - unsigned long addr,imsize; - image_header_t *hdr; /* used for fdc boot */ - unsigned char boot_drive; - int i,nrofblk; - char *ep; - int rcode = 0; - - switch (argc) { - case 1: - addr = CFG_LOAD_ADDR; - boot_drive=CFG_FDC_DRIVE_NUMBER; - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_drive=CFG_FDC_DRIVE_NUMBER; - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_drive=simple_strtoul(argv[2], NULL, 10); - break; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - /* setup FDC and scan for drives */ - if(fdc_setup(boot_drive,pCMD,pFG)==FALSE) { - printf("\n** Error in setup FDC **\n"); - return 1; - } - if(fdc_check_drive(pCMD,pFG)==FALSE) { - printf("\n** Error in check_drives **\n"); - return 1; - } - if((pCMD->flags&(1<<boot_drive))==0) { - /* drive not available */ - printf("\n** Drive %d not availabe **\n",boot_drive); - return 1; - } - if((pCMD->flags&(0x10<<boot_drive))==0) { - /* no disk inserted */ - printf("\n** No disk inserted in drive %d **\n",boot_drive); - return 1; - } - /* ok, we have a valid source */ - pCMD->drive=boot_drive; - /* read first block */ - pCMD->blnr=0; - if(fdc_read_data((unsigned char *)addr,1,pCMD,pFG)==FALSE) { - printf("\nRead error:"); - for(i=0;i<7;i++) - printf("result%d: 0x%02X\n",i,pCMD->result[i]); - return 1; - } - hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf ("Bad Magic Number\n"); - return 1; - } - print_image_hdr(hdr); - - imsize= ntohl(hdr->ih_size)+sizeof(image_header_t); - nrofblk=imsize/512; - if((imsize%512)>0) - nrofblk++; - printf("Loading %ld Bytes (%d blocks) at 0x%08lx..\n",imsize,nrofblk,addr); - pCMD->blnr=0; - if(fdc_read_data((unsigned char *)addr,nrofblk,pCMD,pFG)==FALSE) { - /* read image block */ - printf("\nRead error:"); - for(i=0;i<7;i++) - printf("result%d: 0x%02X\n",i,pCMD->result[i]); - return 1; - } - printf("OK %ld Bytes loaded.\n",imsize); - - flush_cache (addr, imsize); - /* Loading ok, update default load address */ - - load_addr = addr; - return rcode; -} - - -#endif /* CONFIG_COMMANDS & CFG_CMD_FDC */ - - -/***************************************************/ - - -#if (CONFIG_COMMANDS & CFG_CMD_FDC) - -U_BOOT_CMD( - fdcboot, 3, 1, do_fdcboot, - "fdcboot - boot from floppy device\n", - "loadAddr drive\n" -); -#endif diff --git a/common/cmd_fdos.c b/common/cmd_fdos.c deleted file mode 100644 index e51de8bc35..0000000000 --- a/common/cmd_fdos.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * Dos floppy support - */ - -#include <common.h> -#include <config.h> -#include <command.h> -#include <fdc.h> - -#if (CONFIG_COMMANDS & CFG_CMD_FDOS) - -/*----------------------------------------------------------------------------- - * do_fdosboot -- - *----------------------------------------------------------------------------- - */ -int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - char *name; - char *ep; - int size; - int rcode = 0; - char buf [12]; - int drive = CFG_FDC_DRIVE_NUMBER; - - /* pre-set load_addr */ - if ((ep = getenv("loadaddr")) != NULL) { - load_addr = simple_strtoul(ep, NULL, 16); - } - - /* pre-set Boot file name */ - if ((name = getenv("bootfile")) == NULL) { - name = "uImage"; - } - - switch (argc) { - case 1: - break; - case 2: - /* only one arg - accept two forms: - * just load address, or just boot file name. - * The latter form must be written "filename" here. - */ - if (argv[1][0] == '"') { /* just boot filename */ - name = argv [1]; - } else { /* load address */ - load_addr = simple_strtoul(argv[1], NULL, 16); - } - break; - case 3: - load_addr = simple_strtoul(argv[1], NULL, 16); - name = argv [2]; - break; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - break; - } - - /* Init physical layer */ - if (!fdc_fdos_init (drive)) { - return (-1); - } - - /* Open file */ - if (dos_open (name) < 0) { - printf ("Unable to open %s\n", name); - return 1; - } - if ((size = dos_read (load_addr)) < 0) { - printf ("boot error\n"); - return 1; - } - flush_cache (load_addr, size); - - sprintf(buf, "%x", size); - setenv("filesize", buf); - - printf("Floppy DOS load complete: %d bytes loaded to 0x%lx\n", - size, load_addr); - - return rcode; -} - -/*----------------------------------------------------------------------------- - * do_fdosls -- - *----------------------------------------------------------------------------- - */ -int do_fdosls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - char *path = ""; - int drive = CFG_FDC_DRIVE_NUMBER; - - switch (argc) { - case 1: - break; - case 2: - path = argv [1]; - break; - } - - /* Init physical layer */ - if (!fdc_fdos_init (drive)) { - return (-1); - } - /* Open directory */ - if (dos_open (path) < 0) { - printf ("Unable to open %s\n", path); - return 1; - } - return (dos_dir ()); -} - -U_BOOT_CMD( - fdosboot, 3, 0, do_fdosboot, - "fdosboot- boot from a dos floppy file\n", - "[loadAddr] [filename]\n" -); - -U_BOOT_CMD( - fdosls, 2, 0, do_fdosls, - "fdosls - list files in a directory\n", - "[directory]\n" -); - -#endif /* CONFIG_COMMANDS & CFG_CMD_FDOS */ diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c deleted file mode 100644 index 621e136862..0000000000 --- a/common/cmd_fpga.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * (C) Copyright 2000, 2001 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * FPGA support - */ -#include <common.h> -#include <command.h> -#if (CONFIG_COMMANDS & CFG_CMD_NET) -#include <net.h> -#endif -#include <fpga.h> -#include <malloc.h> - - -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -#if defined (CONFIG_FPGA) && ( CONFIG_COMMANDS & CFG_CMD_FPGA ) - -/* Local functions */ -static void fpga_usage (cmd_tbl_t * cmdtp); -static int fpga_get_op (char *opstr); - -/* Local defines */ -#define FPGA_NONE -1 -#define FPGA_INFO 0 -#define FPGA_LOAD 1 -#define FPGA_LOADB 2 -#define FPGA_DUMP 3 -#define FPGA_LOADMK 4 - -/* Convert bitstream data and load into the fpga */ -int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size) -{ - unsigned int length; - unsigned char* swapdata; - unsigned int swapsize; - char buffer[80]; - unsigned char *ptr; - unsigned char *dataptr; - unsigned char data; - unsigned int i; - int rc; - - dataptr = (unsigned char *)fpgadata; - -#if CFG_FPGA_XILINX - /* skip the first bytes of the bitsteam, their meaning is unknown */ - length = (*dataptr << 8) + *(dataptr+1); - dataptr+=2; - dataptr+=length; - - /* get design name (identifier, length, string) */ - length = (*dataptr << 8) + *(dataptr+1); - dataptr+=2; - if (*dataptr++ != 0x61) { - PRINTF ("%s: Design name identifier not recognized in bitstream\n", - __FUNCTION__ ); - return FPGA_FAIL; - } - - length = (*dataptr << 8) + *(dataptr+1); - dataptr+=2; - for(i=0;i<length;i++) - buffer[i]=*dataptr++; - - printf(" design filename = \"%s\"\n", buffer); - - /* get part number (identifier, length, string) */ - if (*dataptr++ != 0x62) { - printf("%s: Part number identifier not recognized in bitstream\n", - __FUNCTION__ ); - return FPGA_FAIL; - } - - length = (*dataptr << 8) + *(dataptr+1); - dataptr+=2; - for(i=0;i<length;i++) - buffer[i]=*dataptr++; - printf(" part number = \"%s\"\n", buffer); - - /* get date (identifier, length, string) */ - if (*dataptr++ != 0x63) { - printf("%s: Date identifier not recognized in bitstream\n", - __FUNCTION__); - return FPGA_FAIL; - } - - length = (*dataptr << 8) + *(dataptr+1); - dataptr+=2; - for(i=0;i<length;i++) - buffer[i]=*dataptr++; - printf(" date = \"%s\"\n", buffer); - - /* get time (identifier, length, string) */ - if (*dataptr++ != 0x64) { - printf("%s: Time identifier not recognized in bitstream\n",__FUNCTION__); - return FPGA_FAIL; - } - - length = (*dataptr << 8) + *(dataptr+1); - dataptr+=2; - for(i=0;i<length;i++) - buffer[i]=*dataptr++; - printf(" time = \"%s\"\n", buffer); - - /* get fpga data length (identifier, length) */ - if (*dataptr++ != 0x65) { - printf("%s: Data length identifier not recognized in bitstream\n", - __FUNCTION__); - return FPGA_FAIL; - } - swapsize = ((unsigned int) *dataptr <<24) + - ((unsigned int) *(dataptr+1) <<16) + - ((unsigned int) *(dataptr+2) <<8 ) + - ((unsigned int) *(dataptr+3) ) ; - dataptr+=4; - printf(" bytes in bitstream = %d\n", swapsize); - - /* check consistency of length obtained */ - if (swapsize >= size) { - printf("%s: Could not find right length of data in bitstream\n", - __FUNCTION__); - return FPGA_FAIL; - } - - /* allocate memory */ - swapdata = (unsigned char *)malloc(swapsize); - if (swapdata == NULL) { - printf("%s: Could not allocate %d bytes memory !\n", - __FUNCTION__, swapsize); - return FPGA_FAIL; - } - - /* read data into memory and swap bits */ - ptr = swapdata; - for (i = 0; i < swapsize; i++) { - data = 0x00; - data |= (*dataptr & 0x01) << 7; - data |= (*dataptr & 0x02) << 5; - data |= (*dataptr & 0x04) << 3; - data |= (*dataptr & 0x08) << 1; - data |= (*dataptr & 0x10) >> 1; - data |= (*dataptr & 0x20) >> 3; - data |= (*dataptr & 0x40) >> 5; - data |= (*dataptr & 0x80) >> 7; - *ptr++ = data; - dataptr++; - } - - rc = fpga_load(dev, swapdata, swapsize); - free(swapdata); - return rc; -#else - printf("Bitstream support only for Xilinx devices\n"); - return FPGA_FAIL; -#endif -} - -/* ------------------------------------------------------------------------- */ -/* command form: - * fpga <op> <device number> <data addr> <datasize> - * where op is 'load', 'dump', or 'info' - * If there is no device number field, the fpga environment variable is used. - * If there is no data addr field, the fpgadata environment variable is used. - * The info command requires no data address field. - */ -int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - int op, dev = FPGA_INVALID_DEVICE; - size_t data_size = 0; - void *fpga_data = NULL; - char *devstr = getenv ("fpga"); - char *datastr = getenv ("fpgadata"); - int rc = FPGA_FAIL; - - if (devstr) - dev = (int) simple_strtoul (devstr, NULL, 16); - if (datastr) - fpga_data = (void *) simple_strtoul (datastr, NULL, 16); - - switch (argc) { - case 5: /* fpga <op> <dev> <data> <datasize> */ - data_size = simple_strtoul (argv[4], NULL, 16); - case 4: /* fpga <op> <dev> <data> */ - fpga_data = (void *) simple_strtoul (argv[3], NULL, 16); - PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data); - case 3: /* fpga <op> <dev | data addr> */ - dev = (int) simple_strtoul (argv[2], NULL, 16); - PRINTF ("%s: device = %d\n", __FUNCTION__, dev); - /* FIXME - this is a really weak test */ - if ((argc == 3) && (dev > fpga_count ())) { /* must be buffer ptr */ - PRINTF ("%s: Assuming buffer pointer in arg 3\n", - __FUNCTION__); - fpga_data = (void *) dev; - PRINTF ("%s: fpga_data = 0x%x\n", - __FUNCTION__, (uint) fpga_data); - dev = FPGA_INVALID_DEVICE; /* reset device num */ - } - case 2: /* fpga <op> */ - op = (int) fpga_get_op (argv[1]); - break; - default: - PRINTF ("%s: Too many or too few args (%d)\n", - __FUNCTION__, argc); - op = FPGA_NONE; /* force usage display */ - break; - } - - switch (op) { - case FPGA_NONE: - fpga_usage (cmdtp); - break; - - case FPGA_INFO: - rc = fpga_info (dev); - break; - - case FPGA_LOAD: - rc = fpga_load (dev, fpga_data, data_size); - break; - - case FPGA_LOADB: - rc = fpga_loadbitstream(dev, fpga_data, data_size); - break; - - case FPGA_LOADMK: - { - image_header_t header; - image_header_t *hdr = &header; - ulong data; - - memmove (&header, (char *)fpga_data, sizeof(image_header_t)); - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - puts ("Bad Magic Number\n"); - return 1; - } - data = ((ulong)fpga_data + sizeof(image_header_t)); - data_size = ntohl(hdr->ih_size); - rc = fpga_load (dev, (void *)data, data_size); - } - break; - - case FPGA_DUMP: - rc = fpga_dump (dev, fpga_data, data_size); - break; - - default: - printf ("Unknown operation\n"); - fpga_usage (cmdtp); - break; - } - return (rc); -} - -static void fpga_usage (cmd_tbl_t * cmdtp) -{ - printf ("Usage:\n%s\n", cmdtp->usage); -} - -/* - * Map op to supported operations. We don't use a table since we - * would just have to relocate it from flash anyway. - */ -static int fpga_get_op (char *opstr) -{ - int op = FPGA_NONE; - - if (!strcmp ("info", opstr)) { - op = FPGA_INFO; - } else if (!strcmp ("loadb", opstr)) { - op = FPGA_LOADB; - } else if (!strcmp ("load", opstr)) { - op = FPGA_LOAD; - } else if (!strcmp ("loadmk", opstr)) { - op = FPGA_LOADMK; - } else if (!strcmp ("dump", opstr)) { - op = FPGA_DUMP; - } - - if (op == FPGA_NONE) { - printf ("Unknown fpga operation \"%s\"\n", opstr); - } - return op; -} - -U_BOOT_CMD (fpga, 6, 1, do_fpga, - "fpga - loadable FPGA image support\n", - "fpga [operation type] [device number] [image address] [image size]\n" - "fpga operations:\n" - "\tinfo\tlist known device information\n" - "\tload\tLoad device from memory buffer\n" - "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n" - "\tloadmk\tLoad device generated with mkimage\n" - "\tdump\tLoad device to memory buffer\n"); -#endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */ diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c deleted file mode 100644 index 28798ea9ee..0000000000 --- a/common/cmd_i2c.c +++ /dev/null @@ -1,1015 +0,0 @@ -/* - * (C) Copyright 2001 - * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * I2C Functions similar to the standard memory functions. - * - * There are several parameters in many of the commands that bear further - * explanations: - * - * Two of the commands (imm and imw) take a byte/word/long modifier - * (e.g. imm.w specifies the word-length modifier). This was done to - * allow manipulating word-length registers. It was not done on any other - * commands because it was not deemed useful. - * - * {i2c_chip} is the I2C chip address (the first byte sent on the bus). - * Each I2C chip on the bus has a unique address. On the I2C data bus, - * the address is the upper seven bits and the LSB is the "read/write" - * bit. Note that the {i2c_chip} address specified on the command - * line is not shifted up: e.g. a typical EEPROM memory chip may have - * an I2C address of 0x50, but the data put on the bus will be 0xA0 - * for write and 0xA1 for read. This "non shifted" address notation - * matches at least half of the data sheets :-/. - * - * {addr} is the address (or offset) within the chip. Small memory - * chips have 8 bit addresses. Large memory chips have 16 bit - * addresses. Other memory chips have 9, 10, or 11 bit addresses. - * Many non-memory chips have multiple registers and {addr} is used - * as the register index. Some non-memory chips have only one register - * and therefore don't need any {addr} parameter. - * - * The default {addr} parameter is one byte (.1) which works well for - * memories and registers with 8 bits of address space. - * - * You can specify the length of the {addr} field with the optional .0, - * .1, or .2 modifier (similar to the .b, .w, .l modifier). If you are - * manipulating a single register device which doesn't use an address - * field, use "0.0" for the address and the ".0" length field will - * suppress the address in the I2C data stream. This also works for - * successive reads using the I2C auto-incrementing memory pointer. - * - * If you are manipulating a large memory with 2-byte addresses, use - * the .2 address modifier, e.g. 210.2 addresses location 528 (decimal). - * - * Then there are the unfortunate memory chips that spill the most - * significant 1, 2, or 3 bits of address into the chip address byte. - * This effectively makes one chip (logically) look like 2, 4, or - * 8 chips. This is handled (awkwardly) by #defining - * CFG_I2C_EEPROM_ADDR_OVERFLOW and using the .1 modifier on the - * {addr} field (since .1 is the default, it doesn't actually have to - * be specified). Examples: given a memory chip at I2C chip address - * 0x50, the following would happen... - * imd 50 0 10 display 16 bytes starting at 0x000 - * On the bus: <S> A0 00 <E> <S> A1 <rd> ... <rd> - * imd 50 100 10 display 16 bytes starting at 0x100 - * On the bus: <S> A2 00 <E> <S> A3 <rd> ... <rd> - * imd 50 210 10 display 16 bytes starting at 0x210 - * On the bus: <S> A4 10 <E> <S> A5 <rd> ... <rd> - * This is awfully ugly. It would be nice if someone would think up - * a better way of handling this. - * - * Adapted from cmd_mem.c which is copyright Wolfgang Denk (wd@denx.de). - */ - -#include <common.h> -#include <command.h> -#include <i2c.h> -#include <asm/byteorder.h> - -/* Display values from last command. - * Memory modify remembered values are different from display memory. - */ -static uchar i2c_dp_last_chip; -static uint i2c_dp_last_addr; -static uint i2c_dp_last_alen; -static uint i2c_dp_last_length = 0x10; - -static uchar i2c_mm_last_chip; -static uint i2c_mm_last_addr; -static uint i2c_mm_last_alen; - -/* If only one I2C bus is present, the list of devices to ignore when - * the probe command is issued is represented by a 1D array of addresses. - * When multiple buses are present, the list is an array of bus-address - * pairs. The following macros take care of this */ - -#if defined(CFG_I2C_NOPROBES) -#if defined(CONFIG_I2C_MULTI_BUS) -static struct -{ - uchar bus; - uchar addr; -} i2c_no_probes[] = CFG_I2C_NOPROBES; -#define GET_BUS_NUM i2c_get_bus_num() -#define COMPARE_BUS(b,i) (i2c_no_probes[(i)].bus == (b)) -#define COMPARE_ADDR(a,i) (i2c_no_probes[(i)].addr == (a)) -#define NO_PROBE_ADDR(i) i2c_no_probes[(i)].addr -#else /* single bus */ -static uchar i2c_no_probes[] = CFG_I2C_NOPROBES; -#define GET_BUS_NUM 0 -#define COMPARE_BUS(b,i) ((b) == 0) /* Make compiler happy */ -#define COMPARE_ADDR(a,i) (i2c_no_probes[(i)] == (a)) -#define NO_PROBE_ADDR(i) i2c_no_probes[(i)] -#endif /* CONFIG_MULTI_BUS */ - -#define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0])) -#endif - -static int -mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]); - -/* - * Syntax: - * imd {i2c_chip} {addr}{.0, .1, .2} {len} - */ -#define DISP_LINE_LEN 16 - -int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - u_char chip; - uint addr, alen, length; - int j, nbytes, linebytes; - - /* We use the last specified parameters, unless new ones are - * entered. - */ - chip = i2c_dp_last_chip; - addr = i2c_dp_last_addr; - alen = i2c_dp_last_alen; - length = i2c_dp_last_length; - - if (argc < 3) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - if ((flag & CMD_FLAG_REPEAT) == 0) { - /* - * New command specified. - */ - alen = 1; - - /* - * I2C chip address - */ - chip = simple_strtoul(argv[1], NULL, 16); - - /* - * I2C data address within the chip. This can be 1 or - * 2 bytes long. Some day it might be 3 bytes long :-). - */ - addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } - - /* - * If another parameter, it is the length to display. - * Length is the number of objects, not number of bytes. - */ - if (argc > 3) - length = simple_strtoul(argv[3], NULL, 16); - } - - /* - * Print the lines. - * - * We buffer all read data, so we can make sure data is read only - * once. - */ - nbytes = length; - do { - unsigned char linebuf[DISP_LINE_LEN]; - unsigned char *cp; - - linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; - - if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0) - puts ("Error reading the chip.\n"); - else { - printf("%04x:", addr); - cp = linebuf; - for (j=0; j<linebytes; j++) { - printf(" %02x", *cp++); - addr++; - } - puts (" "); - cp = linebuf; - for (j=0; j<linebytes; j++) { - if ((*cp < 0x20) || (*cp > 0x7e)) - puts ("."); - else - printf("%c", *cp); - cp++; - } - putc ('\n'); - } - nbytes -= linebytes; - } while (nbytes > 0); - - i2c_dp_last_chip = chip; - i2c_dp_last_addr = addr; - i2c_dp_last_alen = alen; - i2c_dp_last_length = length; - - return 0; -} - -int do_i2c_mm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - return mod_i2c_mem (cmdtp, 1, flag, argc, argv); -} - - -int do_i2c_nm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - return mod_i2c_mem (cmdtp, 0, flag, argc, argv); -} - -/* Write (fill) memory - * - * Syntax: - * imw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}] - */ -int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - uchar chip; - ulong addr; - uint alen; - uchar byte; - int count; - int j; - - if ((argc < 4) || (argc > 5)) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* - * Chip is always specified. - */ - chip = simple_strtoul(argv[1], NULL, 16); - - /* - * Address is always specified. - */ - addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } - - /* - * Value to write is always specified. - */ - byte = simple_strtoul(argv[3], NULL, 16); - - /* - * Optional count - */ - if (argc == 5) - count = simple_strtoul(argv[4], NULL, 16); - else - count = 1; - - while (count-- > 0) { - if (i2c_write(chip, addr++, alen, &byte, 1) != 0) - puts ("Error writing the chip.\n"); - /* - * Wait for the write to complete. The write can take - * up to 10mSec (we allow a little more time). - * - * On some chips, while the write is in progress, the - * chip doesn't respond. This apparently isn't a - * universal feature so we don't take advantage of it. - */ -/* - * No write delay with FRAM devices. - */ -#if !defined(CFG_I2C_FRAM) - udelay(11000); -#endif - - } - - return (0); -} - - -/* Calculate a CRC on memory - * - * Syntax: - * icrc32 {i2c_chip} {addr}{.0, .1, .2} {count} - */ -int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - uchar chip; - ulong addr; - uint alen; - int count; - uchar byte; - ulong crc; - ulong err; - int j; - - if (argc < 4) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* - * Chip is always specified. - */ - chip = simple_strtoul(argv[1], NULL, 16); - - /* - * Address is always specified. - */ - addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } - - /* - * Count is always specified - */ - count = simple_strtoul(argv[3], NULL, 16); - - printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1); - /* - * CRC a byte at a time. This is going to be slooow, but hey, the - * memories are small and slow too so hopefully nobody notices. - */ - crc = 0; - err = 0; - while (count-- > 0) { - if (i2c_read(chip, addr, alen, &byte, 1) != 0) - err++; - crc = crc32 (crc, &byte, 1); - addr++; - } - if (err > 0) - puts ("Error reading the chip,\n"); - else - printf ("%08lx\n", crc); - - return 0; -} - - -/* Modify memory. - * - * Syntax: - * imm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} - * inm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} - */ - -static int -mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) -{ - uchar chip; - ulong addr; - uint alen; - ulong data; - int size = 1; - int nbytes; - int j; - extern char console_buffer[]; - - if (argc != 3) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - -#ifdef CONFIG_BOOT_RETRY_TIME - reset_cmd_timeout(); /* got a good command to get here */ -#endif - /* - * We use the last specified parameters, unless new ones are - * entered. - */ - chip = i2c_mm_last_chip; - addr = i2c_mm_last_addr; - alen = i2c_mm_last_alen; - - if ((flag & CMD_FLAG_REPEAT) == 0) { - /* - * New command specified. Check for a size specification. - * Defaults to byte if no or incorrect specification. - */ - size = cmd_get_data_size(argv[0], 1); - - /* - * Chip is always specified. - */ - chip = simple_strtoul(argv[1], NULL, 16); - - /* - * Address is always specified. - */ - addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } - } - - /* - * Print the address, followed by value. Then accept input for - * the next value. A non-converted value exits. - */ - do { - printf("%08lx:", addr); - if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) - puts ("\nError reading the chip,\n"); - else { - data = cpu_to_be32(data); - if (size == 1) - printf(" %02lx", (data >> 24) & 0x000000FF); - else if (size == 2) - printf(" %04lx", (data >> 16) & 0x0000FFFF); - else - printf(" %08lx", data); - } - - nbytes = readline (" ? "); - if (nbytes == 0) { - /* - * <CR> pressed as only input, don't modify current - * location and move to next. - */ - if (incrflag) - addr += size; - nbytes = size; -#ifdef CONFIG_BOOT_RETRY_TIME - reset_cmd_timeout(); /* good enough to not time out */ -#endif - } -#ifdef CONFIG_BOOT_RETRY_TIME - else if (nbytes == -2) - break; /* timed out, exit the command */ -#endif - else { - char *endp; - - data = simple_strtoul(console_buffer, &endp, 16); - if (size == 1) - data = data << 24; - else if (size == 2) - data = data << 16; - data = be32_to_cpu(data); - nbytes = endp - console_buffer; - if (nbytes) { -#ifdef CONFIG_BOOT_RETRY_TIME - /* - * good enough to not time out - */ - reset_cmd_timeout(); -#endif - if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0) - puts ("Error writing the chip.\n"); -#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS - udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); -#endif - if (incrflag) - addr += size; - } - } - } while (nbytes); - - chip = i2c_mm_last_chip; - addr = i2c_mm_last_addr; - alen = i2c_mm_last_alen; - - return 0; -} - -/* - * Syntax: - * iprobe {addr}{.0, .1, .2} - */ -int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int j; -#if defined(CFG_I2C_NOPROBES) - int k, skip; - uchar bus = GET_BUS_NUM; -#endif /* NOPROBES */ - - puts ("Valid chip addresses:"); - for (j = 0; j < 128; j++) { -#if defined(CFG_I2C_NOPROBES) - skip = 0; - for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { - if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) { - skip = 1; - break; - } - } - if (skip) - continue; -#endif - if (i2c_probe(j) == 0) - printf(" %02X", j); - } - putc ('\n'); - -#if defined(CFG_I2C_NOPROBES) - puts ("Excluded chip addresses:"); - for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) { - if (COMPARE_BUS(bus,k)) - printf(" %02X", NO_PROBE_ADDR(k)); - } - putc ('\n'); -#endif - - return 0; -} - - -/* - * Syntax: - * iloop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}] - * {length} - Number of bytes to read - * {delay} - A DECIMAL number and defaults to 1000 uSec - */ -int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - u_char chip; - ulong alen; - uint addr; - uint length; - u_char bytes[16]; - int delay; - int j; - - if (argc < 3) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* - * Chip is always specified. - */ - chip = simple_strtoul(argv[1], NULL, 16); - - /* - * Address is always specified. - */ - addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } - - /* - * Length is the number of objects, not number of bytes. - */ - length = 1; - length = simple_strtoul(argv[3], NULL, 16); - if (length > sizeof(bytes)) - length = sizeof(bytes); - - /* - * The delay time (uSec) is optional. - */ - delay = 1000; - if (argc > 3) - delay = simple_strtoul(argv[4], NULL, 10); - /* - * Run the loop... - */ - while (1) { - if (i2c_read(chip, addr, alen, bytes, length) != 0) - puts ("Error reading the chip.\n"); - udelay(delay); - } - - /* NOTREACHED */ - return 0; -} - - -/* - * The SDRAM command is separately configured because many - * (most?) embedded boards don't use SDRAM DIMMs. - */ -#if (CONFIG_COMMANDS & CFG_CMD_SDRAM) - -/* - * Syntax: - * sdram {i2c_chip} - */ -int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - u_char chip; - u_char data[128]; - u_char cksum; - int j; - - if (argc < 2) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - /* - * Chip is always specified. - */ - chip = simple_strtoul(argv[1], NULL, 16); - - if (i2c_read(chip, 0, 1, data, sizeof(data)) != 0) { - puts ("No SDRAM Serial Presence Detect found.\n"); - return 1; - } - - cksum = 0; - for (j = 0; j < 63; j++) { - cksum += data[j]; - } - if (cksum != data[63]) { - printf ("WARNING: Configuration data checksum failure:\n" - " is 0x%02x, calculated 0x%02x\n", - data[63], cksum); - } - printf("SPD data revision %d.%d\n", - (data[62] >> 4) & 0x0F, data[62] & 0x0F); - printf("Bytes used 0x%02X\n", data[0]); - printf("Serial memory size 0x%02X\n", 1 << data[1]); - puts ("Memory type "); - switch(data[2]) { - case 2: puts ("EDO\n"); break; - case 4: puts ("SDRAM\n"); break; - default: puts ("unknown\n"); break; - } - puts ("Row address bits "); - if ((data[3] & 0x00F0) == 0) - printf("%d\n", data[3] & 0x0F); - else - printf("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F); - puts ("Column address bits "); - if ((data[4] & 0x00F0) == 0) - printf("%d\n", data[4] & 0x0F); - else - printf("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F); - printf("Module rows %d\n", data[5]); - printf("Module data width %d bits\n", (data[7] << 8) | data[6]); - puts ("Interface signal levels "); - switch(data[8]) { - case 0: puts ("5.0v/TTL\n"); break; - case 1: puts ("LVTTL\n"); break; - case 2: puts ("HSTL 1.5\n"); break; - case 3: puts ("SSTL 3.3\n"); break; - case 4: puts ("SSTL 2.5\n"); break; - default: puts ("unknown\n"); break; - } - printf("SDRAM cycle time %d.%d nS\n", - (data[9] >> 4) & 0x0F, data[9] & 0x0F); - printf("SDRAM access time %d.%d nS\n", - (data[10] >> 4) & 0x0F, data[10] & 0x0F); - puts ("EDC configuration "); - switch(data[11]) { - case 0: puts ("None\n"); break; - case 1: puts ("Parity\n"); break; - case 2: puts ("ECC\n"); break; - default: puts ("unknown\n"); break; - } - if ((data[12] & 0x80) == 0) - puts ("No self refresh, rate "); - else - puts ("Self refresh, rate "); - switch(data[12] & 0x7F) { - case 0: puts ("15.625uS\n"); break; - case 1: puts ("3.9uS\n"); break; - case 2: puts ("7.8uS\n"); break; - case 3: puts ("31.3uS\n"); break; - case 4: puts ("62.5uS\n"); break; - case 5: puts ("125uS\n"); break; - default: puts ("unknown\n"); break; - } - printf("SDRAM width (primary) %d\n", data[13] & 0x7F); - if ((data[13] & 0x80) != 0) { - printf(" (second bank) %d\n", - 2 * (data[13] & 0x7F)); - } - if (data[14] != 0) { - printf("EDC width %d\n", - data[14] & 0x7F); - if ((data[14] & 0x80) != 0) - printf(" (second bank) %d\n", - 2 * (data[14] & 0x7F)); - } - printf("Min clock delay, back-to-back random column addresses %d\n", - data[15]); - puts ("Burst length(s) "); - if (data[16] & 0x80) puts (" Page"); - if (data[16] & 0x08) puts (" 8"); - if (data[16] & 0x04) puts (" 4"); - if (data[16] & 0x02) puts (" 2"); - if (data[16] & 0x01) puts (" 1"); - putc ('\n'); - printf("Number of banks %d\n", data[17]); - puts ("CAS latency(s) "); - if (data[18] & 0x80) puts (" TBD"); - if (data[18] & 0x40) puts (" 7"); - if (data[18] & 0x20) puts (" 6"); - if (data[18] & 0x10) puts (" 5"); - if (data[18] & 0x08) puts (" 4"); - if (data[18] & 0x04) puts (" 3"); - if (data[18] & 0x02) puts (" 2"); - if (data[18] & 0x01) puts (" 1"); - putc ('\n'); - puts ("CS latency(s) "); - if (data[19] & 0x80) puts (" TBD"); - if (data[19] & 0x40) puts (" 6"); - if (data[19] & 0x20) puts (" 5"); - if (data[19] & 0x10) puts (" 4"); - if (data[19] & 0x08) puts (" 3"); - if (data[19] & 0x04) puts (" 2"); - if (data[19] & 0x02) puts (" 1"); - if (data[19] & 0x01) puts (" 0"); - putc ('\n'); - puts ("WE latency(s) "); - if (data[20] & 0x80) puts (" TBD"); - if (data[20] & 0x40) puts (" 6"); - if (data[20] & 0x20) puts (" 5"); - if (data[20] & 0x10) puts (" 4"); - if (data[20] & 0x08) puts (" 3"); - if (data[20] & 0x04) puts (" 2"); - if (data[20] & 0x02) puts (" 1"); - if (data[20] & 0x01) puts (" 0"); - putc ('\n'); - puts ("Module attributes:\n"); - if (!data[21]) puts (" (none)\n"); - if (data[21] & 0x80) puts (" TBD (bit 7)\n"); - if (data[21] & 0x40) puts (" Redundant row address\n"); - if (data[21] & 0x20) puts (" Differential clock input\n"); - if (data[21] & 0x10) puts (" Registerd DQMB inputs\n"); - if (data[21] & 0x08) puts (" Buffered DQMB inputs\n"); - if (data[21] & 0x04) puts (" On-card PLL\n"); - if (data[21] & 0x02) puts (" Registered address/control lines\n"); - if (data[21] & 0x01) puts (" Buffered address/control lines\n"); - puts ("Device attributes:\n"); - if (data[22] & 0x80) puts (" TBD (bit 7)\n"); - if (data[22] & 0x40) puts (" TBD (bit 6)\n"); - if (data[22] & 0x20) puts (" Upper Vcc tolerance 5%\n"); - else puts (" Upper Vcc tolerance 10%\n"); - if (data[22] & 0x10) puts (" Lower Vcc tolerance 5%\n"); - else puts (" Lower Vcc tolerance 10%\n"); - if (data[22] & 0x08) puts (" Supports write1/read burst\n"); - if (data[22] & 0x04) puts (" Supports precharge all\n"); - if (data[22] & 0x02) puts (" Supports auto precharge\n"); - if (data[22] & 0x01) puts (" Supports early RAS# precharge\n"); - printf("SDRAM cycle time (2nd highest CAS latency) %d.%d nS\n", - (data[23] >> 4) & 0x0F, data[23] & 0x0F); - printf("SDRAM access from clock (2nd highest CAS latency) %d.%d nS\n", - (data[24] >> 4) & 0x0F, data[24] & 0x0F); - printf("SDRAM cycle time (3rd highest CAS latency) %d.%d nS\n", - (data[25] >> 4) & 0x0F, data[25] & 0x0F); - printf("SDRAM access from clock (3rd highest CAS latency) %d.%d nS\n", - (data[26] >> 4) & 0x0F, data[26] & 0x0F); - printf("Minimum row precharge %d nS\n", data[27]); - printf("Row active to row active min %d nS\n", data[28]); - printf("RAS to CAS delay min %d nS\n", data[29]); - printf("Minimum RAS pulse width %d nS\n", data[30]); - puts ("Density of each row "); - if (data[31] & 0x80) puts (" 512"); - if (data[31] & 0x40) puts (" 256"); - if (data[31] & 0x20) puts (" 128"); - if (data[31] & 0x10) puts (" 64"); - if (data[31] & 0x08) puts (" 32"); - if (data[31] & 0x04) puts (" 16"); - if (data[31] & 0x02) puts (" 8"); - if (data[31] & 0x01) puts (" 4"); - puts ("MByte\n"); - printf("Command and Address setup %c%d.%d nS\n", - (data[32] & 0x80) ? '-' : '+', - (data[32] >> 4) & 0x07, data[32] & 0x0F); - printf("Command and Address hold %c%d.%d nS\n", - (data[33] & 0x80) ? '-' : '+', - (data[33] >> 4) & 0x07, data[33] & 0x0F); - printf("Data signal input setup %c%d.%d nS\n", - (data[34] & 0x80) ? '-' : '+', - (data[34] >> 4) & 0x07, data[34] & 0x0F); - printf("Data signal input hold %c%d.%d nS\n", - (data[35] & 0x80) ? '-' : '+', - (data[35] >> 4) & 0x07, data[35] & 0x0F); - puts ("Manufacturer's JEDEC ID "); - for (j = 64; j <= 71; j++) - printf("%02X ", data[j]); - putc ('\n'); - printf("Manufacturing Location %02X\n", data[72]); - puts ("Manufacturer's Part Number "); - for (j = 73; j <= 90; j++) - printf("%02X ", data[j]); - putc ('\n'); - printf("Revision Code %02X %02X\n", data[91], data[92]); - printf("Manufacturing Date %02X %02X\n", data[93], data[94]); - puts ("Assembly Serial Number "); - for (j = 95; j <= 98; j++) - printf("%02X ", data[j]); - putc ('\n'); - printf("Speed rating PC%d\n", - data[126] == 0x66 ? 66 : data[126]); - - return 0; -} -#endif /* CFG_CMD_SDRAM */ - -#if defined(CONFIG_I2C_CMD_TREE) -#if defined(CONFIG_I2C_MULTI_BUS) -int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - int bus_idx, ret=0; - - if (argc == 1) - /* querying current setting */ - printf("Current bus is %d\n", i2c_get_bus_num()); - else { - bus_idx = simple_strtoul(argv[1], NULL, 10); - printf("Setting bus to %d\n", bus_idx); - ret = i2c_set_bus_num(bus_idx); - if (ret) - printf("Failure changing bus number (%d)\n", ret); - } - return ret; -} -#endif /* CONFIG_I2C_MULTI_BUS */ - -int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - int speed, ret=0; - - if (argc == 1) - /* querying current speed */ - printf("Current bus speed=%d\n", i2c_get_bus_speed()); - else { - speed = simple_strtoul(argv[1], NULL, 10); - printf("Setting bus speed to %d Hz\n", speed); - ret = i2c_set_bus_speed(speed); - if (ret) - printf("Failure changing bus speed (%d)\n", ret); - } - return ret; -} - -int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ -#if defined(CONFIG_I2C_MULTI_BUS) - if (!strncmp(argv[1], "de", 2)) - return do_i2c_bus_num(cmdtp, flag, --argc, ++argv); -#endif /* CONFIG_I2C_MULTI_BUS */ - if (!strncmp(argv[1], "sp", 2)) - return do_i2c_bus_speed(cmdtp, flag, --argc, ++argv); - if (!strncmp(argv[1], "md", 2)) - return do_i2c_md(cmdtp, flag, --argc, ++argv); - if (!strncmp(argv[1], "mm", 2)) - return do_i2c_mm(cmdtp, flag, --argc, ++argv); - if (!strncmp(argv[1], "mw", 2)) - return do_i2c_mw(cmdtp, flag, --argc, ++argv); - if (!strncmp(argv[1], "nm", 2)) - return do_i2c_nm(cmdtp, flag, --argc, ++argv); - if (!strncmp(argv[1], "cr", 2)) - return do_i2c_crc(cmdtp, flag, --argc, ++argv); - if (!strncmp(argv[1], "pr", 2)) - return do_i2c_probe(cmdtp, flag, --argc, ++argv); - if (!strncmp(argv[1], "lo", 2)) - return do_i2c_loop(cmdtp, flag, --argc, ++argv); -#if (CONFIG_COMMANDS & CFG_CMD_SDRAM) - if (!strncmp(argv[1], "sd", 2)) - return do_sdram(cmdtp, flag, --argc, ++argv); -#endif /* CFG_CMD_SDRAM */ - else - printf ("Usage:\n%s\n", cmdtp->usage); - return 0; -} -#endif /* CONFIG_I2C_CMD_TREE */ - -/***************************************************/ - -U_BOOT_CMD( - imd, 4, 1, do_i2c_md, \ - "imd - i2c memory display\n", \ - "chip address[.0, .1, .2] [# of objects]\n - i2c memory display\n" \ -); - -U_BOOT_CMD( - imm, 3, 1, do_i2c_mm, - "imm - i2c memory modify (auto-incrementing)\n", - "chip address[.0, .1, .2]\n" - " - memory modify, auto increment address\n" -); -U_BOOT_CMD( - inm, 3, 1, do_i2c_nm, - "inm - memory modify (constant address)\n", - "chip address[.0, .1, .2]\n - memory modify, read and keep address\n" -); - -U_BOOT_CMD( - imw, 5, 1, do_i2c_mw, - "imw - memory write (fill)\n", - "chip address[.0, .1, .2] value [count]\n - memory write (fill)\n" -); - -U_BOOT_CMD( - icrc32, 5, 1, do_i2c_crc, - "icrc32 - checksum calculation\n", - "chip address[.0, .1, .2] count\n - compute CRC32 checksum\n" -); - -U_BOOT_CMD( - iprobe, 1, 1, do_i2c_probe, - "iprobe - probe to discover valid I2C chip addresses\n", - "\n -discover valid I2C chip addresses\n" -); - -/* - * Require full name for "iloop" because it is an infinite loop! - */ -U_BOOT_CMD( - iloop, 5, 1, do_i2c_loop, - "iloop - infinite loop on address range\n", - "chip address[.0, .1, .2] [# of objects]\n" - " - loop, reading a set of addresses\n" -); - -#if (CONFIG_COMMANDS & CFG_CMD_SDRAM) -U_BOOT_CMD( - isdram, 2, 1, do_sdram, - "isdram - print SDRAM configuration information\n", - "chip\n - print SDRAM configuration information\n" - " (valid chip values 50..57)\n" -); -#endif - -#if defined(CONFIG_I2C_CMD_TREE) -U_BOOT_CMD( - i2c, 6, 1, do_i2c, - "i2c - I2C sub-system\n", -#if defined(CONFIG_I2C_MULTI_BUS) - "dev [dev] - show or set current I2C bus\n" -#endif /* CONFIG_I2C_MULTI_BUS */ - "i2c speed [speed] - show or set I2C bus speed\n" - "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n" - "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n" - "i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n" - "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n" - "i2c crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" - "i2c probe - show devices on the I2C bus\n" - "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n" -#if (CONFIG_COMMANDS & CFG_CMD_SDRAM) - "i2c sdram chip - print SDRAM configuration information\n" -#endif /* CFG_CMD_SDRAM */ -); -#endif /* CONFIG_I2C_CMD_TREE */ - diff --git a/common/cmd_ide.c b/common/cmd_ide.c deleted file mode 100644 index 5976968d43..0000000000 --- a/common/cmd_ide.c +++ /dev/null @@ -1,2003 +0,0 @@ -/* - * (C) Copyright 2000-2005 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * IDE support - */ -#include <common.h> -#include <config.h> -#include <watchdog.h> -#include <command.h> -#include <image.h> -#include <asm/byteorder.h> -#if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA) -# include <pcmcia.h> -#endif -#ifdef CONFIG_8xx -# include <mpc8xx.h> -#endif -#ifdef CONFIG_MPC5xxx -#include <mpc5xxx.h> -#endif -#include <ide.h> -#include <ata.h> -#ifdef CONFIG_STATUS_LED -# include <status_led.h> -#endif -#ifndef __PPC__ -#include <asm/io.h> -#ifdef __MIPS__ -/* Macros depend on this variable */ -unsigned long mips_io_port_base = 0; -#endif -#endif - -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include <status_led.h> -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - -#ifdef CONFIG_IDE_8xx_DIRECT -DECLARE_GLOBAL_DATA_PTR; -#endif - -#ifdef __PPC__ -# define EIEIO __asm__ volatile ("eieio") -# define SYNC __asm__ volatile ("sync") -#else -# define EIEIO /* nothing */ -# define SYNC /* nothing */ -#endif - -#if (CONFIG_COMMANDS & CFG_CMD_IDE) - -#ifdef CONFIG_IDE_8xx_DIRECT -/* Timings for IDE Interface - * - * SETUP / LENGTH / HOLD - cycles valid for 50 MHz clk - * 70 165 30 PIO-Mode 0, [ns] - * 4 9 2 [Cycles] - * 50 125 20 PIO-Mode 1, [ns] - * 3 7 2 [Cycles] - * 30 100 15 PIO-Mode 2, [ns] - * 2 6 1 [Cycles] - * 30 80 10 PIO-Mode 3, [ns] - * 2 5 1 [Cycles] - * 25 70 10 PIO-Mode 4, [ns] - * 2 4 1 [Cycles] - */ - -const static pio_config_t pio_config_ns [IDE_MAX_PIO_MODE+1] = -{ - /* Setup Length Hold */ - { 70, 165, 30 }, /* PIO-Mode 0, [ns] */ - { 50, 125, 20 }, /* PIO-Mode 1, [ns] */ - { 30, 101, 15 }, /* PIO-Mode 2, [ns] */ - { 30, 80, 10 }, /* PIO-Mode 3, [ns] */ - { 25, 70, 10 }, /* PIO-Mode 4, [ns] */ -}; - -static pio_config_t pio_config_clk [IDE_MAX_PIO_MODE+1]; - -#ifndef CFG_PIO_MODE -#define CFG_PIO_MODE 0 /* use a relaxed default */ -#endif -static int pio_mode = CFG_PIO_MODE; - -/* Make clock cycles and always round up */ - -#define PCMCIA_MK_CLKS( t, T ) (( (t) * (T) + 999U ) / 1000U ) - -#endif /* CONFIG_IDE_8xx_DIRECT */ - -/* ------------------------------------------------------------------------- */ - -/* Current I/O Device */ -static int curr_device = -1; - -/* Current offset for IDE0 / IDE1 bus access */ -ulong ide_bus_offset[CFG_IDE_MAXBUS] = { -#if defined(CFG_ATA_IDE0_OFFSET) - CFG_ATA_IDE0_OFFSET, -#endif -#if defined(CFG_ATA_IDE1_OFFSET) && (CFG_IDE_MAXBUS > 1) - CFG_ATA_IDE1_OFFSET, -#endif -}; - - -#define ATA_CURR_BASE(dev) (CFG_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)]) - -#ifndef CONFIG_AMIGAONEG3SE -static int ide_bus_ok[CFG_IDE_MAXBUS]; -#else -static int ide_bus_ok[CFG_IDE_MAXBUS] = {0,}; -#endif - -block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; -/* ------------------------------------------------------------------------- */ - -#ifdef CONFIG_IDE_LED -#if !defined(CONFIG_KUP4K) && !defined(CONFIG_KUP4X) &&!defined(CONFIG_BMS2003) &&!defined(CONFIG_CPC45) -static void ide_led (uchar led, uchar status); -#else -extern void ide_led (uchar led, uchar status); -#endif -#else -#ifndef CONFIG_AMIGAONEG3SE -#define ide_led(a,b) /* dummy */ -#else -extern void ide_led(uchar led, uchar status); -#define LED_IDE1 1 -#define LED_IDE2 2 -#define CONFIG_IDE_LED 1 -#define DEVICE_LED(x) 1 -#endif -#endif - -#ifdef CONFIG_IDE_RESET -static void ide_reset (void); -#else -#define ide_reset() /* dummy */ -#endif - -static void ide_ident (block_dev_desc_t *dev_desc); -static uchar ide_wait (int dev, ulong t); - -#define IDE_TIME_OUT 2000 /* 2 sec timeout */ - -#define ATAPI_TIME_OUT 7000 /* 7 sec timeout (5 sec seems to work...) */ - -#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */ - -static void __inline__ ide_outb(int dev, int port, unsigned char val); -static unsigned char __inline__ ide_inb(int dev, int port); -static void input_data(int dev, ulong *sect_buf, int words); -static void output_data(int dev, ulong *sect_buf, int words); -static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); - - -#ifdef CONFIG_ATAPI -static void atapi_inquiry(block_dev_desc_t *dev_desc); -ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer); -#endif - - -#ifdef CONFIG_IDE_8xx_DIRECT -static void set_pcmcia_timing (int pmode); -#endif - -/* ------------------------------------------------------------------------- */ - -int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int rcode = 0; - - switch (argc) { - case 0: - case 1: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 2: - if (strncmp(argv[1],"res",3) == 0) { - puts ("\nReset IDE" -#ifdef CONFIG_IDE_8xx_DIRECT - " on PCMCIA " PCMCIA_SLOT_MSG -#endif - ": "); - - ide_init (); - return 0; - } else if (strncmp(argv[1],"inf",3) == 0) { - int i; - - putc ('\n'); - - for (i=0; i<CFG_IDE_MAXDEVICE; ++i) { - if (ide_dev_desc[i].type==DEV_TYPE_UNKNOWN) - continue; /* list only known devices */ - printf ("IDE device %d: ", i); - dev_print(&ide_dev_desc[i]); - } - return 0; - - } else if (strncmp(argv[1],"dev",3) == 0) { - if ((curr_device < 0) || (curr_device >= CFG_IDE_MAXDEVICE)) { - puts ("\nno IDE devices available\n"); - return 1; - } - printf ("\nIDE device %d: ", curr_device); - dev_print(&ide_dev_desc[curr_device]); - return 0; - } else if (strncmp(argv[1],"part",4) == 0) { - int dev, ok; - - for (ok=0, dev=0; dev<CFG_IDE_MAXDEVICE; ++dev) { - if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) { - ++ok; - if (dev) - putc ('\n'); - print_part(&ide_dev_desc[dev]); - } - } - if (!ok) { - puts ("\nno IDE devices available\n"); - rcode ++; - } - return rcode; - } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 3: - if (strncmp(argv[1],"dev",3) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - printf ("\nIDE device %d: ", dev); - if (dev >= CFG_IDE_MAXDEVICE) { - puts ("unknown device\n"); - return 1; - } - dev_print(&ide_dev_desc[dev]); - /*ide_print (dev);*/ - - if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - return 1; - } - - curr_device = dev; - - puts ("... is now current device\n"); - - return 0; - } else if (strncmp(argv[1],"part",4) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) { - print_part(&ide_dev_desc[dev]); - } else { - printf ("\nIDE device %d not available\n", dev); - rcode = 1; - } - return rcode; - } - - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - default: - /* at least 4 args */ - - if (strcmp(argv[1],"read") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; -#ifdef CFG_64BIT_STRTOUL - lbaint_t blk = simple_strtoull(argv[3], NULL, 16); - - printf ("\nIDE read: device %d block # %qd, count %ld ... ", - curr_device, blk, cnt); -#else - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf ("\nIDE read: device %d block # %ld, count %ld ... ", - curr_device, blk, cnt); -#endif - - n = ide_dev_desc[curr_device].block_read (curr_device, - blk, cnt, - (ulong *)addr); - /* flush cache after read */ - flush_cache (addr, cnt*ide_dev_desc[curr_device].blksz); - - printf ("%ld blocks read: %s\n", - n, (n==cnt) ? "OK" : "ERROR"); - if (n==cnt) { - return 0; - } else { - return 1; - } - } else if (strcmp(argv[1],"write") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; -#ifdef CFG_64BIT_STRTOUL - lbaint_t blk = simple_strtoull(argv[3], NULL, 16); - - printf ("\nIDE write: device %d block # %qd, count %ld ... ", - curr_device, blk, cnt); -#else - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf ("\nIDE write: device %d block # %ld, count %ld ... ", - curr_device, blk, cnt); -#endif - - n = ide_write (curr_device, blk, cnt, (ulong *)addr); - - printf ("%ld blocks written: %s\n", - n, (n==cnt) ? "OK" : "ERROR"); - if (n==cnt) { - return 0; - } else { - return 1; - } - } else { - printf ("Usage:\n%s\n", cmdtp->usage); - rcode = 1; - } - - return rcode; - } -} - -int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - char *boot_device = NULL; - char *ep; - int dev, part = 0; - ulong addr, cnt, checksum; - disk_partition_t info; - image_header_t *hdr; - int rcode = 0; - - switch (argc) { - case 1: - addr = CFG_LOAD_ADDR; - boot_device = getenv ("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv ("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - if (!boot_device) { - puts ("\n** No boot device **\n"); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - dev = simple_strtoul(boot_device, &ep, 16); - - if (ide_dev_desc[dev].type==DEV_TYPE_UNKNOWN) { - printf ("\n** Device %d not available\n", dev); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - if (get_partition_info (ide_dev_desc, part, &info)) { - SHOW_BOOT_PROGRESS (-1); - return 1; - } - if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) && - (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) { - printf ("\n** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - printf ("\nLoading from IDE device %d, partition %d: " - "Name: %.32s Type: %.32s\n", - dev, part, info.name, info.type); - - debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", - info.start, info.size, info.blksz); - - if (ide_dev_desc[dev].block_read (dev, info.start, 1, (ulong *)addr) != 1) { - printf ("** Read error on %d:%d\n", dev, part); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - hdr = (image_header_t *)addr; - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf("\n** Bad Magic Number **\n"); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { - puts ("\n** Bad Header Checksum **\n"); - SHOW_BOOT_PROGRESS (-2); - return 1; - } - hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */ - - print_image_hdr (hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; - - if (ide_dev_desc[dev].block_read (dev, info.start+1, cnt, - (ulong *)(addr+info.blksz)) != cnt) { - printf ("** Read error on %d:%d\n", dev, part); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - - /* Loading ok, update default load address */ - - load_addr = addr; - - return rcode; -} - -/* ------------------------------------------------------------------------- */ - -void ide_init (void) -{ - -#ifdef CONFIG_IDE_8xx_DIRECT - volatile immap_t *immr = (immap_t *)CFG_IMMR; - volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); -#endif - unsigned char c; - int i, bus; -#ifdef CONFIG_AMIGAONEG3SE - unsigned int max_bus_scan; - unsigned int ata_reset_time; - char *s; -#endif -#ifdef CONFIG_IDE_8xx_PCCARD - extern int pcmcia_on (void); - extern int ide_devices_found; /* Initialized in check_ide_device() */ -#endif /* CONFIG_IDE_8xx_PCCARD */ - -#ifdef CONFIG_IDE_PREINIT - extern int ide_preinit (void); - WATCHDOG_RESET(); - - if (ide_preinit ()) { - puts ("ide_preinit failed\n"); - return; - } -#endif /* CONFIG_IDE_PREINIT */ - -#ifdef CONFIG_IDE_8xx_PCCARD - extern int pcmcia_on (void); - extern int ide_devices_found; /* Initialized in check_ide_device() */ - - WATCHDOG_RESET(); - - ide_devices_found = 0; - /* initialize the PCMCIA IDE adapter card */ - pcmcia_on(); - if (!ide_devices_found) - return; - udelay (1000000); /* 1 s */ -#endif /* CONFIG_IDE_8xx_PCCARD */ - - WATCHDOG_RESET(); - -#ifdef CONFIG_IDE_8xx_DIRECT - /* Initialize PIO timing tables */ - for (i=0; i <= IDE_MAX_PIO_MODE; ++i) { - pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup, - gd->bus_clk); - pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length, - gd->bus_clk); - pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold, - gd->bus_clk); - debug ( "PIO Mode %d: setup=%2d ns/%d clk" - " len=%3d ns/%d clk" - " hold=%2d ns/%d clk\n", - i, - pio_config_ns[i].t_setup, pio_config_clk[i].t_setup, - pio_config_ns[i].t_length, pio_config_clk[i].t_length, - pio_config_ns[i].t_hold, pio_config_clk[i].t_hold); - } -#endif /* CONFIG_IDE_8xx_DIRECT */ - - /* Reset the IDE just to be sure. - * Light LED's to show - */ - ide_led ((LED_IDE1 | LED_IDE2), 1); /* LED's on */ - ide_reset (); /* ATAPI Drives seems to need a proper IDE Reset */ - -#ifdef CONFIG_IDE_8xx_DIRECT - /* PCMCIA / IDE initialization for common mem space */ - pcmp->pcmc_pgcrb = 0; - - /* start in PIO mode 0 - most relaxed timings */ - pio_mode = 0; - set_pcmcia_timing (pio_mode); -#endif /* CONFIG_IDE_8xx_DIRECT */ - - /* - * Wait for IDE to get ready. - * According to spec, this can take up to 31 seconds! - */ -#ifndef CONFIG_AMIGAONEG3SE - for (bus=0; bus<CFG_IDE_MAXBUS; ++bus) { - int dev = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS); -#else - s = getenv("ide_maxbus"); - if (s) - max_bus_scan = simple_strtol(s, NULL, 10); - else - max_bus_scan = CFG_IDE_MAXBUS; - - for (bus=0; bus<max_bus_scan; ++bus) { - int dev = bus * (CFG_IDE_MAXDEVICE / max_bus_scan); -#endif - -#ifdef CONFIG_IDE_8xx_PCCARD - /* Skip non-ide devices from probing */ - if ((ide_devices_found & (1 << bus)) == 0) { - ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */ - continue; - } -#endif - printf ("Bus %d: ", bus); - - ide_bus_ok[bus] = 0; - - /* Select device - */ - udelay (100000); /* 100 ms */ - ide_outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev)); - udelay (100000); /* 100 ms */ -#ifdef CONFIG_AMIGAONEG3SE - ata_reset_time = ATA_RESET_TIME; - s = getenv("ide_reset_timeout"); - if (s) ata_reset_time = 2*simple_strtol(s, NULL, 10); -#endif - i = 0; - do { - udelay (10000); /* 10 ms */ - - c = ide_inb (dev, ATA_STATUS); - i++; -#ifdef CONFIG_AMIGAONEG3SE - if (i > (ata_reset_time * 100)) { -#else - if (i > (ATA_RESET_TIME * 100)) { -#endif - puts ("** Timeout **\n"); - ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */ -#ifdef CONFIG_AMIGAONEG3SE - /* If this is the second bus, the first one was OK */ - if (bus != 0) { - ide_bus_ok[bus] = 0; - goto skip_bus; - } -#endif - return; - } - if ((i >= 100) && ((i%100)==0)) { - putc ('.'); - } - } while (c & ATA_STAT_BUSY); - - if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) { - puts ("not available "); - debug ("Status = 0x%02X ", c); -#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */ - } else if ((c & ATA_STAT_READY) == 0) { - puts ("not available "); - debug ("Status = 0x%02X ", c); -#endif - } else { - puts ("OK "); - ide_bus_ok[bus] = 1; - } - WATCHDOG_RESET(); - } - -#ifdef CONFIG_AMIGAONEG3SE - skip_bus: -#endif - putc ('\n'); - - ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */ - - curr_device = -1; - for (i=0; i<CFG_IDE_MAXDEVICE; ++i) { -#ifdef CONFIG_IDE_LED - int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2; -#endif - ide_dev_desc[i].type=DEV_TYPE_UNKNOWN; - ide_dev_desc[i].if_type=IF_TYPE_IDE; - ide_dev_desc[i].dev=i; - ide_dev_desc[i].part_type=PART_TYPE_UNKNOWN; - ide_dev_desc[i].blksz=0; - ide_dev_desc[i].lba=0; - ide_dev_desc[i].block_read=ide_read; - if (!ide_bus_ok[IDE_BUS(i)]) - continue; - ide_led (led, 1); /* LED on */ - ide_ident(&ide_dev_desc[i]); - ide_led (led, 0); /* LED off */ - dev_print(&ide_dev_desc[i]); -/* ide_print (i); */ - if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) { - init_part (&ide_dev_desc[i]); /* initialize partition type */ - if (curr_device < 0) - curr_device = i; - } - } - WATCHDOG_RESET(); -} - -/* ------------------------------------------------------------------------- */ - -block_dev_desc_t * ide_get_dev(int dev) -{ - return ((block_dev_desc_t *)&ide_dev_desc[dev]); -} - - -#ifdef CONFIG_IDE_8xx_DIRECT - -static void -set_pcmcia_timing (int pmode) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); - ulong timings; - - debug ("Set timing for PIO Mode %d\n", pmode); - - timings = PCMCIA_SHT(pio_config_clk[pmode].t_hold) - | PCMCIA_SST(pio_config_clk[pmode].t_setup) - | PCMCIA_SL (pio_config_clk[pmode].t_length) - ; - - /* IDE 0 - */ - pcmp->pcmc_pbr0 = CFG_PCMCIA_PBR0; - pcmp->pcmc_por0 = CFG_PCMCIA_POR0 -#if (CFG_PCMCIA_POR0 != 0) - | timings -#endif - ; - debug ("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0); - - pcmp->pcmc_pbr1 = CFG_PCMCIA_PBR1; - pcmp->pcmc_por1 = CFG_PCMCIA_POR1 -#if (CFG_PCMCIA_POR1 != 0) - | timings -#endif - ; - debug ("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1); - - pcmp->pcmc_pbr2 = CFG_PCMCIA_PBR2; - pcmp->pcmc_por2 = CFG_PCMCIA_POR2 -#if (CFG_PCMCIA_POR2 != 0) - | timings -#endif - ; - debug ("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2); - - pcmp->pcmc_pbr3 = CFG_PCMCIA_PBR3; - pcmp->pcmc_por3 = CFG_PCMCIA_POR3 -#if (CFG_PCMCIA_POR3 != 0) - | timings -#endif - ; - debug ("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3); - - /* IDE 1 - */ - pcmp->pcmc_pbr4 = CFG_PCMCIA_PBR4; - pcmp->pcmc_por4 = CFG_PCMCIA_POR4 -#if (CFG_PCMCIA_POR4 != 0) - | timings -#endif - ; - debug ("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4); - - pcmp->pcmc_pbr5 = CFG_PCMCIA_PBR5; - pcmp->pcmc_por5 = CFG_PCMCIA_POR5 -#if (CFG_PCMCIA_POR5 != 0) - | timings -#endif - ; - debug ("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5); - - pcmp->pcmc_pbr6 = CFG_PCMCIA_PBR6; - pcmp->pcmc_por6 = CFG_PCMCIA_POR6 -#if (CFG_PCMCIA_POR6 != 0) - | timings -#endif - ; - debug ("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6); - - pcmp->pcmc_pbr7 = CFG_PCMCIA_PBR7; - pcmp->pcmc_por7 = CFG_PCMCIA_POR7 -#if (CFG_PCMCIA_POR7 != 0) - | timings -#endif - ; - debug ("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7); - -} - -#endif /* CONFIG_IDE_8xx_DIRECT */ - -/* ------------------------------------------------------------------------- */ - -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) -static void __inline__ -ide_outb(int dev, int port, unsigned char val) -{ - debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n", - dev, port, val, (ATA_CURR_BASE(dev)+port)); - - /* Ensure I/O operations complete */ - EIEIO; - *((uchar *)(ATA_CURR_BASE(dev)+port)) = val; -} -#else /* ! __PPC__ */ -static void __inline__ -ide_outb(int dev, int port, unsigned char val) -{ - outb(val, ATA_CURR_BASE(dev)+port); -} -#endif /* __PPC__ */ - - -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) -static unsigned char __inline__ -ide_inb(int dev, int port) -{ - uchar val; - /* Ensure I/O operations complete */ - EIEIO; - val = *((uchar *)(ATA_CURR_BASE(dev)+port)); - debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n", - dev, port, (ATA_CURR_BASE(dev)+port), val); - return (val); -} -#else /* ! __PPC__ */ -static unsigned char __inline__ -ide_inb(int dev, int port) -{ - return inb(ATA_CURR_BASE(dev)+port); -} -#endif /* __PPC__ */ - -#ifdef __PPC__ -# ifdef CONFIG_AMIGAONEG3SE -static void -output_data_short(int dev, ulong *sect_buf, int words) -{ - ushort *dbuf; - volatile ushort *pbuf; - - pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); - dbuf = (ushort *)sect_buf; - while (words--) { - EIEIO; - *pbuf = *dbuf++; - EIEIO; - } - - if (words&1) - *pbuf = 0; -} -# endif /* CONFIG_AMIGAONEG3SE */ -#endif /* __PPC_ */ - -/* We only need to swap data if we are running on a big endian cpu. */ -/* But Au1x00 cpu:s already swaps data in big endian mode! */ -#if defined(__LITTLE_ENDIAN) || ( defined(CONFIG_AU1X00) && !defined(CONFIG_GTH2) ) -#define input_swap_data(x,y,z) input_data(x,y,z) -#else -static void -input_swap_data(int dev, ulong *sect_buf, int words) -{ -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) - uchar i; - volatile uchar *pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN); - volatile uchar *pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); - ushort *dbuf = (ushort *)sect_buf; - - while (words--) { - for (i=0; i<2; i++) { - *(((uchar *)(dbuf)) + 1) = *pbuf_even; - *(uchar *)dbuf = *pbuf_odd; - dbuf+=1; - } - } -#else - volatile ushort *pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); - ushort *dbuf = (ushort *)sect_buf; - - debug("in input swap data base for read is %lx\n", (unsigned long) pbuf); - - while (words--) { -#ifdef __MIPS__ - *dbuf++ = swab16p((u16*)pbuf); - *dbuf++ = swab16p((u16*)pbuf); -#else - *dbuf++ = ld_le16(pbuf); - *dbuf++ = ld_le16(pbuf); -#endif /* !MIPS */ - } -#endif -} -#endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */ - - -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) -static void -output_data(int dev, ulong *sect_buf, int words) -{ -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) - uchar *dbuf; - volatile uchar *pbuf_even; - volatile uchar *pbuf_odd; - - pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN); - pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); - dbuf = (uchar *)sect_buf; - while (words--) { - EIEIO; - *pbuf_even = *dbuf++; - EIEIO; - *pbuf_odd = *dbuf++; - EIEIO; - *pbuf_even = *dbuf++; - EIEIO; - *pbuf_odd = *dbuf++; - } -#else - ushort *dbuf; - volatile ushort *pbuf; - - pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); - dbuf = (ushort *)sect_buf; - while (words--) { - EIEIO; - *pbuf = *dbuf++; - EIEIO; - *pbuf = *dbuf++; - } -#endif -} -#else /* ! __PPC__ */ -static void -output_data(int dev, ulong *sect_buf, int words) -{ - outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words<<1); -} -#endif /* __PPC__ */ - -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) -static void -input_data(int dev, ulong *sect_buf, int words) -{ -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) - uchar *dbuf; - volatile uchar *pbuf_even; - volatile uchar *pbuf_odd; - - pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN); - pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); - dbuf = (uchar *)sect_buf; - while (words--) { - *dbuf++ = *pbuf_even; - EIEIO; - SYNC; - *dbuf++ = *pbuf_odd; - EIEIO; - SYNC; - *dbuf++ = *pbuf_even; - EIEIO; - SYNC; - *dbuf++ = *pbuf_odd; - EIEIO; - SYNC; - } -#else - ushort *dbuf; - volatile ushort *pbuf; - - pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); - dbuf = (ushort *)sect_buf; - - debug("in input data base for read is %lx\n", (unsigned long) pbuf); - - while (words--) { - EIEIO; - *dbuf++ = *pbuf; - EIEIO; - *dbuf++ = *pbuf; - } -#endif -} -#else /* ! __PPC__ */ -static void -input_data(int dev, ulong *sect_buf, int words) -{ - insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1); -} - -#endif /* __PPC__ */ - -#ifdef CONFIG_AMIGAONEG3SE -static void -input_data_short(int dev, ulong *sect_buf, int words) -{ - ushort *dbuf; - volatile ushort *pbuf; - - pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); - dbuf = (ushort *)sect_buf; - while (words--) { - EIEIO; - *dbuf++ = *pbuf; - EIEIO; - } - - if (words&1) { - ushort dummy; - dummy = *pbuf; - } -} -#endif - -/* ------------------------------------------------------------------------- - */ -static void ide_ident (block_dev_desc_t *dev_desc) -{ - ulong iobuf[ATA_SECTORWORDS]; - unsigned char c; - hd_driveid_t *iop = (hd_driveid_t *)iobuf; - -#ifdef CONFIG_AMIGAONEG3SE - int max_bus_scan; - char *s; -#endif -#ifdef CONFIG_ATAPI - int retries = 0; - int do_retry = 0; -#endif - - int device; - device=dev_desc->dev; - printf (" Device %d: ", device); - -#ifdef CONFIG_AMIGAONEG3SE - s = getenv("ide_maxbus"); - if (s) { - max_bus_scan = simple_strtol(s, NULL, 10); - } else { - max_bus_scan = CFG_IDE_MAXBUS; - } - if (device >= max_bus_scan*2) { - dev_desc->type=DEV_TYPE_UNKNOWN; - return; - } -#endif - - ide_led (DEVICE_LED(device), 1); /* LED on */ - /* Select device - */ - ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - dev_desc->if_type=IF_TYPE_IDE; -#ifdef CONFIG_ATAPI - - do_retry = 0; - retries = 0; - - /* Warning: This will be tricky to read */ - while (retries <= 1) { - /* check signature */ - if ((ide_inb(device,ATA_SECT_CNT) == 0x01) && - (ide_inb(device,ATA_SECT_NUM) == 0x01) && - (ide_inb(device,ATA_CYL_LOW) == 0x14) && - (ide_inb(device,ATA_CYL_HIGH) == 0xEB)) { - /* ATAPI Signature found */ - dev_desc->if_type=IF_TYPE_ATAPI; - /* Start Ident Command - */ - ide_outb (device, ATA_COMMAND, ATAPI_CMD_IDENT); - /* - * Wait for completion - ATAPI devices need more time - * to become ready - */ - c = ide_wait (device, ATAPI_TIME_OUT); - } else -#endif - { - /* Start Ident Command - */ - ide_outb (device, ATA_COMMAND, ATA_CMD_IDENT); - - /* Wait for completion - */ - c = ide_wait (device, IDE_TIME_OUT); - } - ide_led (DEVICE_LED(device), 0); /* LED off */ - - if (((c & ATA_STAT_DRQ) == 0) || - ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) { -#ifdef CONFIG_ATAPI -#ifdef CONFIG_AMIGAONEG3SE - s = getenv("ide_doreset"); - if (s && strcmp(s, "on") == 0) -#endif - { - /* Need to soft reset the device in case it's an ATAPI... */ - debug ("Retrying...\n"); - ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - udelay(100000); - ide_outb (device, ATA_COMMAND, 0x08); - udelay (500000); /* 500 ms */ - } - /* Select device - */ - ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - retries++; -#else - return; -#endif - } -#ifdef CONFIG_ATAPI - else - break; - } /* see above - ugly to read */ - - if (retries == 2) /* Not found */ - return; -#endif - - input_swap_data (device, iobuf, ATA_SECTORWORDS); - - ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision)); - ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor)); - ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product)); -#ifdef __LITTLE_ENDIAN - /* - * firmware revision and model number have Big Endian Byte - * order in Word. Convert both to little endian. - * - * See CF+ and CompactFlash Specification Revision 2.0: - * 6.2.1.6: Identfy Drive, Table 39 for more details - */ - - strswab (dev_desc->revision); - strswab (dev_desc->vendor); -#endif /* __LITTLE_ENDIAN */ - - if ((iop->config & 0x0080)==0x0080) - dev_desc->removable = 1; - else - dev_desc->removable = 0; - -#ifdef CONFIG_ATAPI - if (dev_desc->if_type==IF_TYPE_ATAPI) { - atapi_inquiry(dev_desc); - return; - } -#endif /* CONFIG_ATAPI */ - -#ifdef __BIG_ENDIAN - /* swap shorts */ - dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16); -#else /* ! __BIG_ENDIAN */ - /* - * do not swap shorts on little endian - * - * See CF+ and CompactFlash Specification Revision 2.0: - * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details. - */ - dev_desc->lba = iop->lba_capacity; -#endif /* __BIG_ENDIAN */ - -#ifdef CONFIG_LBA48 - if (iop->command_set_2 & 0x0400) { /* LBA 48 support */ - dev_desc->lba48 = 1; - dev_desc->lba = (unsigned long long)iop->lba48_capacity[0] | - ((unsigned long long)iop->lba48_capacity[1] << 16) | - ((unsigned long long)iop->lba48_capacity[2] << 32) | - ((unsigned long long)iop->lba48_capacity[3] << 48); - } else { - dev_desc->lba48 = 0; - } -#endif /* CONFIG_LBA48 */ - /* assuming HD */ - dev_desc->type=DEV_TYPE_HARDDISK; - dev_desc->blksz=ATA_BLOCKSIZE; - dev_desc->lun=0; /* just to fill something in... */ -} - - -/* ------------------------------------------------------------------------- */ - -ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) -{ - ulong n = 0; - unsigned char c; - unsigned char pwrsave=0; /* power save */ -#ifdef CONFIG_LBA48 - unsigned char lba48 = 0; - - if (blknr & 0x0000fffff0000000) { - /* more than 28 bits used, use 48bit mode */ - lba48 = 1; - } -#endif - debug ("ide_read dev %d start %qX, blocks %lX buffer at %lX\n", - device, blknr, blkcnt, (ulong)buffer); - - ide_led (DEVICE_LED(device), 1); /* LED on */ - - /* Select device - */ - ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - c = ide_wait (device, IDE_TIME_OUT); - - if (c & ATA_STAT_BUSY) { - printf ("IDE read: device %d not ready\n", device); - goto IDE_READ_E; - } - - /* first check if the drive is in Powersaving mode, if yes, - * increase the timeout value */ - ide_outb (device, ATA_COMMAND, ATA_CMD_CHK_PWR); - udelay (50); - - c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */ - - if (c & ATA_STAT_BUSY) { - printf ("IDE read: device %d not ready\n", device); - goto IDE_READ_E; - } - if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) { - printf ("No Powersaving mode %X\n", c); - } else { - c = ide_inb(device,ATA_SECT_CNT); - debug ("Powersaving %02X\n",c); - if(c==0) - pwrsave=1; - } - - - while (blkcnt-- > 0) { - - c = ide_wait (device, IDE_TIME_OUT); - - if (c & ATA_STAT_BUSY) { - printf ("IDE read: device %d not ready\n", device); - break; - } -#ifdef CONFIG_LBA48 - if (lba48) { - /* write high bits */ - ide_outb (device, ATA_SECT_CNT, 0); - ide_outb (device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); - ide_outb (device, ATA_LBA_MID, (blknr >> 32) & 0xFF); - ide_outb (device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); - } -#endif - ide_outb (device, ATA_SECT_CNT, 1); - ide_outb (device, ATA_LBA_LOW, (blknr >> 0) & 0xFF); - ide_outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF); - ide_outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); - -#ifdef CONFIG_LBA48 - if (lba48) { - ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device) ); - ide_outb (device, ATA_COMMAND, ATA_CMD_READ_EXT); - - } else -#endif - { - ide_outb (device, ATA_DEV_HD, ATA_LBA | - ATA_DEVICE(device) | - ((blknr >> 24) & 0xF) ); - ide_outb (device, ATA_COMMAND, ATA_CMD_READ); - } - - udelay (50); - - if(pwrsave) { - c = ide_wait (device, IDE_SPIN_UP_TIME_OUT); /* may take up to 4 sec */ - pwrsave=0; - } else { - c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */ - } - - if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) { -#if defined(CFG_64BIT_LBA) && defined(CFG_64BIT_VSPRINTF) - printf ("Error (no IRQ) dev %d blk %qd: status 0x%02x\n", - device, blknr, c); -#else - printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n", - device, (ulong)blknr, c); -#endif - break; - } - - input_data (device, buffer, ATA_SECTORWORDS); - (void) ide_inb (device, ATA_STATUS); /* clear IRQ */ - - ++n; - ++blknr; - buffer += ATA_SECTORWORDS; - } -IDE_READ_E: - ide_led (DEVICE_LED(device), 0); /* LED off */ - return (n); -} - -/* ------------------------------------------------------------------------- */ - - -ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) -{ - ulong n = 0; - unsigned char c; -#ifdef CONFIG_LBA48 - unsigned char lba48 = 0; - - if (blknr & 0x0000fffff0000000) { - /* more than 28 bits used, use 48bit mode */ - lba48 = 1; - } -#endif - - ide_led (DEVICE_LED(device), 1); /* LED on */ - - /* Select device - */ - ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - - while (blkcnt-- > 0) { - - c = ide_wait (device, IDE_TIME_OUT); - - if (c & ATA_STAT_BUSY) { - printf ("IDE read: device %d not ready\n", device); - goto WR_OUT; - } -#ifdef CONFIG_LBA48 - if (lba48) { - /* write high bits */ - ide_outb (device, ATA_SECT_CNT, 0); - ide_outb (device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); - ide_outb (device, ATA_LBA_MID, (blknr >> 32) & 0xFF); - ide_outb (device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); - } -#endif - ide_outb (device, ATA_SECT_CNT, 1); - ide_outb (device, ATA_LBA_LOW, (blknr >> 0) & 0xFF); - ide_outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF); - ide_outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); - -#ifdef CONFIG_LBA48 - if (lba48) { - ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device) ); - ide_outb (device, ATA_COMMAND, ATA_CMD_WRITE_EXT); - - } else -#endif - { - ide_outb (device, ATA_DEV_HD, ATA_LBA | - ATA_DEVICE(device) | - ((blknr >> 24) & 0xF) ); - ide_outb (device, ATA_COMMAND, ATA_CMD_WRITE); - } - - udelay (50); - - c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */ - - if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) { -#if defined(CFG_64BIT_LBA) && defined(CFG_64BIT_VSPRINTF) - printf ("Error (no IRQ) dev %d blk %qd: status 0x%02x\n", - device, blknr, c); -#else - printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n", - device, (ulong)blknr, c); -#endif - goto WR_OUT; - } - - output_data (device, buffer, ATA_SECTORWORDS); - c = ide_inb (device, ATA_STATUS); /* clear IRQ */ - ++n; - ++blknr; - buffer += ATA_SECTORWORDS; - } -WR_OUT: - ide_led (DEVICE_LED(device), 0); /* LED off */ - return (n); -} - -/* ------------------------------------------------------------------------- */ - -/* - * copy src to dest, skipping leading and trailing blanks and null - * terminate the string - * "len" is the size of available memory including the terminating '\0' - */ -static void ident_cpy (unsigned char *dst, unsigned char *src, unsigned int len) -{ - unsigned char *end, *last; - - last = dst; - end = src + len - 1; - - /* reserve space for '\0' */ - if (len < 2) - goto OUT; - - /* skip leading white space */ - while ((*src) && (src<end) && (*src==' ')) - ++src; - - /* copy string, omitting trailing white space */ - while ((*src) && (src<end)) { - *dst++ = *src; - if (*src++ != ' ') - last = dst; - } -OUT: - *last = '\0'; -} - -/* ------------------------------------------------------------------------- */ - -/* - * Wait until Busy bit is off, or timeout (in ms) - * Return last status - */ -static uchar ide_wait (int dev, ulong t) -{ - ulong delay = 10 * t; /* poll every 100 us */ - uchar c; - - while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) { - udelay (100); - if (delay-- == 0) { - break; - } - } - return (c); -} - -/* ------------------------------------------------------------------------- */ - -#ifdef CONFIG_IDE_RESET -extern void ide_set_reset(int idereset); - -static void ide_reset (void) -{ -#if defined(CFG_PB_12V_ENABLE) || defined(CFG_PB_IDE_MOTOR) - volatile immap_t *immr = (immap_t *)CFG_IMMR; -#endif - int i; - - curr_device = -1; - for (i=0; i<CFG_IDE_MAXBUS; ++i) - ide_bus_ok[i] = 0; - for (i=0; i<CFG_IDE_MAXDEVICE; ++i) - ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; - - ide_set_reset (1); /* assert reset */ - - WATCHDOG_RESET(); - -#ifdef CFG_PB_12V_ENABLE - immr->im_cpm.cp_pbdat &= ~(CFG_PB_12V_ENABLE); /* 12V Enable output OFF */ - immr->im_cpm.cp_pbpar &= ~(CFG_PB_12V_ENABLE); - immr->im_cpm.cp_pbodr &= ~(CFG_PB_12V_ENABLE); - immr->im_cpm.cp_pbdir |= CFG_PB_12V_ENABLE; - - /* wait 500 ms for the voltage to stabilize - */ - for (i=0; i<500; ++i) { - udelay (1000); - } - - immr->im_cpm.cp_pbdat |= CFG_PB_12V_ENABLE; /* 12V Enable output ON */ -#endif /* CFG_PB_12V_ENABLE */ - -#ifdef CFG_PB_IDE_MOTOR - /* configure IDE Motor voltage monitor pin as input */ - immr->im_cpm.cp_pbpar &= ~(CFG_PB_IDE_MOTOR); - immr->im_cpm.cp_pbodr &= ~(CFG_PB_IDE_MOTOR); - immr->im_cpm.cp_pbdir &= ~(CFG_PB_IDE_MOTOR); - - /* wait up to 1 s for the motor voltage to stabilize - */ - for (i=0; i<1000; ++i) { - if ((immr->im_cpm.cp_pbdat & CFG_PB_IDE_MOTOR) != 0) { - break; - } - udelay (1000); - } - - if (i == 1000) { /* Timeout */ - printf ("\nWarning: 5V for IDE Motor missing\n"); -# ifdef CONFIG_STATUS_LED -# ifdef STATUS_LED_YELLOW - status_led_set (STATUS_LED_YELLOW, STATUS_LED_ON ); -# endif -# ifdef STATUS_LED_GREEN - status_led_set (STATUS_LED_GREEN, STATUS_LED_OFF); -# endif -# endif /* CONFIG_STATUS_LED */ - } -#endif /* CFG_PB_IDE_MOTOR */ - - WATCHDOG_RESET(); - - /* de-assert RESET signal */ - ide_set_reset(0); - - /* wait 250 ms */ - for (i=0; i<250; ++i) { - udelay (1000); - } -} - -#endif /* CONFIG_IDE_RESET */ - -/* ------------------------------------------------------------------------- */ - -#if defined(CONFIG_IDE_LED) && \ - !defined(CONFIG_AMIGAONEG3SE)&& \ - !defined(CONFIG_CPC45) && \ - !defined(CONFIG_HMI10) && \ - !defined(CONFIG_KUP4K) && \ - !defined(CONFIG_KUP4X) - -static uchar led_buffer = 0; /* Buffer for current LED status */ - -static void ide_led (uchar led, uchar status) -{ - uchar *led_port = LED_PORT; - - if (status) { /* switch LED on */ - led_buffer |= led; - } else { /* switch LED off */ - led_buffer &= ~led; - } - - *led_port = led_buffer; -} - -#endif /* CONFIG_IDE_LED */ - -/* ------------------------------------------------------------------------- */ - -#ifdef CONFIG_ATAPI -/**************************************************************************** - * ATAPI Support - */ - -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) -/* since ATAPI may use commands with not 4 bytes alligned length - * we have our own transfer functions, 2 bytes alligned */ -static void -output_data_shorts(int dev, ushort *sect_buf, int shorts) -{ -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) - uchar *dbuf; - volatile uchar *pbuf_even; - volatile uchar *pbuf_odd; - - pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN); - pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); - while (shorts--) { - EIEIO; - *pbuf_even = *dbuf++; - EIEIO; - *pbuf_odd = *dbuf++; - } -#else - ushort *dbuf; - volatile ushort *pbuf; - - pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); - dbuf = (ushort *)sect_buf; - - debug ("in output data shorts base for read is %lx\n", (unsigned long) pbuf); - - while (shorts--) { - EIEIO; - *pbuf = *dbuf++; - } -#endif -} - -static void -input_data_shorts(int dev, ushort *sect_buf, int shorts) -{ -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) - uchar *dbuf; - volatile uchar *pbuf_even; - volatile uchar *pbuf_odd; - - pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN); - pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); - while (shorts--) { - EIEIO; - *dbuf++ = *pbuf_even; - EIEIO; - *dbuf++ = *pbuf_odd; - } -#else - ushort *dbuf; - volatile ushort *pbuf; - - pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); - dbuf = (ushort *)sect_buf; - - debug("in input data shorts base for read is %lx\n", (unsigned long) pbuf); - - while (shorts--) { - EIEIO; - *dbuf++ = *pbuf; - } -#endif -} - -#else /* ! __PPC__ */ -static void -output_data_shorts(int dev, ushort *sect_buf, int shorts) -{ - outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, shorts); -} - -static void -input_data_shorts(int dev, ushort *sect_buf, int shorts) -{ - insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, shorts); -} - -#endif /* __PPC__ */ - -/* - * Wait until (Status & mask) == res, or timeout (in ms) - * Return last status - * This is used since some ATAPI CD ROMs clears their Busy Bit first - * and then they set their DRQ Bit - */ -static uchar atapi_wait_mask (int dev, ulong t,uchar mask, uchar res) -{ - ulong delay = 10 * t; /* poll every 100 us */ - uchar c; - - c = ide_inb(dev,ATA_DEV_CTL); /* prevents to read the status before valid */ - while (((c = ide_inb(dev, ATA_STATUS)) & mask) != res) { - /* break if error occurs (doesn't make sense to wait more) */ - if((c & ATA_STAT_ERR)==ATA_STAT_ERR) - break; - udelay (100); - if (delay-- == 0) { - break; - } - } - return (c); -} - -/* - * issue an atapi command - */ -unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned char * buffer,int buflen) -{ - unsigned char c,err,mask,res; - int n; - ide_led (DEVICE_LED(device), 1); /* LED on */ - - /* Select device - */ - mask = ATA_STAT_BUSY|ATA_STAT_DRQ; - res = 0; -#ifdef CONFIG_AMIGAONEG3SE -# warning THF: Removed LBA mode ??? -#endif - ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res); - if ((c & mask) != res) { - printf ("ATAPI_ISSUE: device %d not ready status %X\n", device,c); - err=0xFF; - goto AI_OUT; - } - /* write taskfile */ - ide_outb (device, ATA_ERROR_REG, 0); /* no DMA, no overlaped */ - ide_outb (device, ATA_SECT_CNT, 0); - ide_outb (device, ATA_SECT_NUM, 0); - ide_outb (device, ATA_CYL_LOW, (unsigned char)(buflen & 0xFF)); - ide_outb (device, ATA_CYL_HIGH, (unsigned char)((buflen>>8) & 0xFF)); -#ifdef CONFIG_AMIGAONEG3SE -# warning THF: Removed LBA mode ??? -#endif - ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - - ide_outb (device, ATA_COMMAND, ATAPI_CMD_PACKET); - udelay (50); - - mask = ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR; - res = ATA_STAT_DRQ; - c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res); - - if ((c & mask) != res) { /* DRQ must be 1, BSY 0 */ - printf ("ATTAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n",device,c); - err=0xFF; - goto AI_OUT; - } - - output_data_shorts (device, (unsigned short *)ccb,ccblen/2); /* write command block */ - /* ATAPI Command written wait for completition */ - udelay (5000); /* device must set bsy */ - - mask = ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR; - /* if no data wait for DRQ = 0 BSY = 0 - * if data wait for DRQ = 1 BSY = 0 */ - res=0; - if(buflen) - res = ATA_STAT_DRQ; - c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res); - if ((c & mask) != res ) { - if (c & ATA_STAT_ERR) { - err=(ide_inb(device,ATA_ERROR_REG))>>4; - debug ("atapi_issue 1 returned sense key %X status %02X\n",err,c); - } else { - printf ("ATTAPI_ISSUE: (no DRQ) after sending ccb (%x) status 0x%02x\n", ccb[0],c); - err=0xFF; - } - goto AI_OUT; - } - n=ide_inb(device, ATA_CYL_HIGH); - n<<=8; - n+=ide_inb(device, ATA_CYL_LOW); - if(n>buflen) { - printf("ERROR, transfer bytes %d requested only %d\n",n,buflen); - err=0xff; - goto AI_OUT; - } - if((n==0)&&(buflen<0)) { - printf("ERROR, transfer bytes %d requested %d\n",n,buflen); - err=0xff; - goto AI_OUT; - } - if(n!=buflen) { - debug ("WARNING, transfer bytes %d not equal with requested %d\n",n,buflen); - } - if(n!=0) { /* data transfer */ - debug ("ATAPI_ISSUE: %d Bytes to transfer\n",n); - /* we transfer shorts */ - n>>=1; - /* ok now decide if it is an in or output */ - if ((ide_inb(device, ATA_SECT_CNT)&0x02)==0) { - debug ("Write to device\n"); - output_data_shorts(device,(unsigned short *)buffer,n); - } else { - debug ("Read from device @ %p shorts %d\n",buffer,n); - input_data_shorts(device,(unsigned short *)buffer,n); - } - } - udelay(5000); /* seems that some CD ROMs need this... */ - mask = ATA_STAT_BUSY|ATA_STAT_ERR; - res=0; - c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res); - if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) { - err=(ide_inb(device,ATA_ERROR_REG) >> 4); - debug ("atapi_issue 2 returned sense key %X status %X\n",err,c); - } else { - err = 0; - } -AI_OUT: - ide_led (DEVICE_LED(device), 0); /* LED off */ - return (err); -} - -/* - * sending the command to atapi_issue. If an status other than good - * returns, an request_sense will be issued - */ - -#define ATAPI_DRIVE_NOT_READY 100 -#define ATAPI_UNIT_ATTN 10 - -unsigned char atapi_issue_autoreq (int device, - unsigned char* ccb, - int ccblen, - unsigned char *buffer, - int buflen) -{ - unsigned char sense_data[18],sense_ccb[12]; - unsigned char res,key,asc,ascq; - int notready,unitattn; - -#ifdef CONFIG_AMIGAONEG3SE - char *s; - unsigned int timeout, retrycnt; - - s = getenv("ide_cd_timeout"); - timeout = s ? (simple_strtol(s, NULL, 10)*1000000)/5 : 0; - - retrycnt = 0; -#endif - - unitattn=ATAPI_UNIT_ATTN; - notready=ATAPI_DRIVE_NOT_READY; - -retry: - res= atapi_issue(device,ccb,ccblen,buffer,buflen); - if (res==0) - return (0); /* Ok */ - - if (res==0xFF) - return (0xFF); /* error */ - - debug ("(auto_req)atapi_issue returned sense key %X\n",res); - - memset(sense_ccb,0,sizeof(sense_ccb)); - memset(sense_data,0,sizeof(sense_data)); - sense_ccb[0]=ATAPI_CMD_REQ_SENSE; - sense_ccb[4]=18; /* allocation Length */ - - res=atapi_issue(device,sense_ccb,12,sense_data,18); - key=(sense_data[2]&0xF); - asc=(sense_data[12]); - ascq=(sense_data[13]); - - debug ("ATAPI_CMD_REQ_SENSE returned %x\n",res); - debug (" Sense page: %02X key %02X ASC %02X ASCQ %02X\n", - sense_data[0], - key, - asc, - ascq); - - if((key==0)) - return 0; /* ok device ready */ - - if((key==6)|| (asc==0x29) || (asc==0x28)) { /* Unit Attention */ - if(unitattn-->0) { - udelay(200*1000); - goto retry; - } - printf("Unit Attention, tried %d\n",ATAPI_UNIT_ATTN); - goto error; - } - if((asc==0x4) && (ascq==0x1)) { /* not ready, but will be ready soon */ - if (notready-->0) { - udelay(200*1000); - goto retry; - } - printf("Drive not ready, tried %d times\n",ATAPI_DRIVE_NOT_READY); - goto error; - } - if(asc==0x3a) { - debug ("Media not present\n"); - goto error; - } - -#ifdef CONFIG_AMIGAONEG3SE - if ((sense_data[2]&0xF)==0x0B) { - debug ("ABORTED COMMAND...retry\n"); - if (retrycnt++ < 4) - goto retry; - return (0xFF); - } - - if ((sense_data[2]&0xf) == 0x02 && - sense_data[12] == 0x04 && - sense_data[13] == 0x01 ) { - debug ("Waiting for unit to become active\n"); - udelay(timeout); - if (retrycnt++ < 4) - goto retry; - return 0xFF; - } -#endif /* CONFIG_AMIGAONEG3SE */ - - printf ("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq); -error: - debug ("ERROR Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq); - return (0xFF); -} - - -static void atapi_inquiry(block_dev_desc_t * dev_desc) -{ - unsigned char ccb[12]; /* Command descriptor block */ - unsigned char iobuf[64]; /* temp buf */ - unsigned char c; - int device; - - device=dev_desc->dev; - dev_desc->type=DEV_TYPE_UNKNOWN; /* not yet valid */ - dev_desc->block_read=atapi_read; - - memset(ccb,0,sizeof(ccb)); - memset(iobuf,0,sizeof(iobuf)); - - ccb[0]=ATAPI_CMD_INQUIRY; - ccb[4]=40; /* allocation Legnth */ - c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,40); - - debug ("ATAPI_CMD_INQUIRY returned %x\n",c); - if (c!=0) - return; - - /* copy device ident strings */ - ident_cpy(dev_desc->vendor,&iobuf[8],8); - ident_cpy(dev_desc->product,&iobuf[16],16); - ident_cpy(dev_desc->revision,&iobuf[32],5); - - dev_desc->lun=0; - dev_desc->lba=0; - dev_desc->blksz=0; - dev_desc->type=iobuf[0] & 0x1f; - - if ((iobuf[1]&0x80)==0x80) - dev_desc->removable = 1; - else - dev_desc->removable = 0; - - memset(ccb,0,sizeof(ccb)); - memset(iobuf,0,sizeof(iobuf)); - ccb[0]=ATAPI_CMD_START_STOP; - ccb[4]=0x03; /* start */ - - c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0); - - debug ("ATAPI_CMD_START_STOP returned %x\n",c); - if (c!=0) - return; - - memset(ccb,0,sizeof(ccb)); - memset(iobuf,0,sizeof(iobuf)); - c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0); - - debug ("ATAPI_CMD_UNIT_TEST_READY returned %x\n",c); - if (c!=0) - return; - - memset(ccb,0,sizeof(ccb)); - memset(iobuf,0,sizeof(iobuf)); - ccb[0]=ATAPI_CMD_READ_CAP; - c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,8); - debug ("ATAPI_CMD_READ_CAP returned %x\n",c); - if (c!=0) - return; - - debug ("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n", - iobuf[0],iobuf[1],iobuf[2],iobuf[3], - iobuf[4],iobuf[5],iobuf[6],iobuf[7]); - - dev_desc->lba =((unsigned long)iobuf[0]<<24) + - ((unsigned long)iobuf[1]<<16) + - ((unsigned long)iobuf[2]<< 8) + - ((unsigned long)iobuf[3]); - dev_desc->blksz=((unsigned long)iobuf[4]<<24) + - ((unsigned long)iobuf[5]<<16) + - ((unsigned long)iobuf[6]<< 8) + - ((unsigned long)iobuf[7]); -#ifdef CONFIG_LBA48 - dev_desc->lba48 = 0; /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */ -#endif - return; -} - - -/* - * atapi_read: - * we transfer only one block per command, since the multiple DRQ per - * command is not yet implemented - */ -#define ATAPI_READ_MAX_BYTES 2048 /* we read max 2kbytes */ -#define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */ -#define ATAPI_READ_MAX_BLOCK ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE /* max blocks */ - -ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) -{ - ulong n = 0; - unsigned char ccb[12]; /* Command descriptor block */ - ulong cnt; - - debug ("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n", - device, blknr, blkcnt, (ulong)buffer); - - do { - if (blkcnt>ATAPI_READ_MAX_BLOCK) { - cnt=ATAPI_READ_MAX_BLOCK; - } else { - cnt=blkcnt; - } - ccb[0]=ATAPI_CMD_READ_12; - ccb[1]=0; /* reserved */ - ccb[2]=(unsigned char) (blknr>>24) & 0xFF; /* MSB Block */ - ccb[3]=(unsigned char) (blknr>>16) & 0xFF; /* */ - ccb[4]=(unsigned char) (blknr>> 8) & 0xFF; - ccb[5]=(unsigned char) blknr & 0xFF; /* LSB Block */ - ccb[6]=(unsigned char) (cnt >>24) & 0xFF; /* MSB Block count */ - ccb[7]=(unsigned char) (cnt >>16) & 0xFF; - ccb[8]=(unsigned char) (cnt >> 8) & 0xFF; - ccb[9]=(unsigned char) cnt & 0xFF; /* LSB Block */ - ccb[10]=0; /* reserved */ - ccb[11]=0; /* reserved */ - - if (atapi_issue_autoreq(device,ccb,12, - (unsigned char *)buffer, - cnt*ATAPI_READ_BLOCK_SIZE) == 0xFF) { - return (n); - } - n+=cnt; - blkcnt-=cnt; - blknr+=cnt; - buffer+=cnt*(ATAPI_READ_BLOCK_SIZE/4); /* ulong blocksize in ulong */ - } while (blkcnt > 0); - return (n); -} - -/* ------------------------------------------------------------------------- */ - -#endif /* CONFIG_ATAPI */ - -U_BOOT_CMD( - ide, 5, 1, do_ide, - "ide - IDE sub-system\n", - "reset - reset IDE controller\n" - "ide info - show available IDE devices\n" - "ide device [dev] - show or set current device\n" - "ide part [dev] - print partition table of one or all IDE devices\n" - "ide read addr blk# cnt\n" - "ide write addr blk# cnt - read/write `cnt'" - " blocks starting at block `blk#'\n" - " to/from memory address `addr'\n" -); - -U_BOOT_CMD( - diskboot, 3, 1, do_diskboot, - "diskboot- boot from IDE device\n", - "loadAddr dev:part\n" -); - -#endif /* CONFIG_COMMANDS & CFG_CMD_IDE */ diff --git a/common/cmd_immap.c b/common/cmd_immap.c deleted file mode 100644 index fa79b45a3c..0000000000 --- a/common/cmd_immap.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * MPC8xx/MPC8260 Internal Memory Map Functions - */ - -#include <common.h> -#include <command.h> - -#if (CONFIG_COMMANDS & CFG_CMD_IMMAP) && \ - (defined(CONFIG_8xx) || defined(CONFIG_8260)) - -#if defined(CONFIG_8xx) -#include <asm/8xx_immap.h> -#include <commproc.h> -#include <asm/iopin_8xx.h> -#elif defined(CONFIG_8260) -#include <asm/immap_8260.h> -#include <asm/cpm_8260.h> -#include <asm/iopin_8260.h> -#endif - -#if defined(CONFIG_8xx) || defined(CONFIG_8260) -DECLARE_GLOBAL_DATA_PTR; -#endif - -static void -unimplemented ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - printf ("Sorry, but the '%s' command has not been implemented\n", - cmdtp->name); -} - -int -do_siuinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - volatile immap_t *immap = (immap_t *) CFG_IMMR; - -#if defined(CONFIG_8xx) - volatile sysconf8xx_t *sc = &immap->im_siu_conf; -#elif defined(CONFIG_8260) - volatile sysconf8260_t *sc = &immap->im_siu_conf; -#endif - - printf ("SIUMCR= %08x SYPCR = %08x\n", sc->sc_siumcr, sc->sc_sypcr); -#if defined(CONFIG_8xx) - printf ("SWT = %08x\n", sc->sc_swt); - printf ("SIPEND= %08x SIMASK= %08x\n", sc->sc_sipend, sc->sc_simask); - printf ("SIEL = %08x SIVEC = %08x\n", sc->sc_siel, sc->sc_sivec); - printf ("TESR = %08x SDCR = %08x\n", sc->sc_tesr, sc->sc_sdcr); -#elif defined(CONFIG_8260) - printf ("BCR = %08x\n", sc->sc_bcr); - printf ("P_ACR = %02x P_ALRH= %08x P_ALRL= %08x\n", - sc->sc_ppc_acr, sc->sc_ppc_alrh, sc->sc_ppc_alrl); - printf ("L_ACR = %02x L_ALRH= %08x L_ALRL= %08x\n", - sc->sc_lcl_acr, sc->sc_lcl_alrh, sc->sc_lcl_alrl); - printf ("PTESR1= %08x PTESR2= %08x\n", sc->sc_tescr1, sc->sc_tescr2); - printf ("LTESR1= %08x LTESR2= %08x\n", sc->sc_ltescr1, sc->sc_ltescr2); - printf ("PDTEA = %08x PDTEM = %02x\n", sc->sc_pdtea, sc->sc_pdtem); - printf ("LDTEA = %08x LDTEM = %02x\n", sc->sc_ldtea, sc->sc_ldtem); -#endif - return 0; -} - -int -do_memcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - volatile immap_t *immap = (immap_t *) CFG_IMMR; - -#if defined(CONFIG_8xx) - volatile memctl8xx_t *memctl = &immap->im_memctl; - int nbanks = 8; -#elif defined(CONFIG_8260) - volatile memctl8260_t *memctl = &immap->im_memctl; - int nbanks = 12; -#endif - volatile uint *p = &memctl->memc_br0; - int i; - - for (i = 0; i < nbanks; i++, p += 2) { - if (i < 10) { - printf ("BR%d = %08x OR%d = %08x\n", - i, p[0], i, p[1]); - } else { - printf ("BR%d = %08x OR%d = %08x\n", - i, p[0], i, p[1]); - } - } - - printf ("MAR = %08x", memctl->memc_mar); -#if defined(CONFIG_8xx) - printf (" MCR = %08x\n", memctl->memc_mcr); -#elif defined(CONFIG_8260) - putc ('\n'); -#endif - printf ("MAMR = %08x MBMR = %08x", - memctl->memc_mamr, memctl->memc_mbmr); -#if defined(CONFIG_8xx) - printf ("\nMSTAT = %04x\n", memctl->memc_mstat); -#elif defined(CONFIG_8260) - printf (" MCMR = %08x\n", memctl->memc_mcmr); -#endif - printf ("MPTPR = %04x MDR = %08x\n", - memctl->memc_mptpr, memctl->memc_mdr); -#if defined(CONFIG_8260) - printf ("PSDMR = %08x LSDMR = %08x\n", - memctl->memc_psdmr, memctl->memc_lsdmr); - printf ("PURT = %02x PSRT = %02x\n", - memctl->memc_purt, memctl->memc_psrt); - printf ("LURT = %02x LSRT = %02x\n", - memctl->memc_lurt, memctl->memc_lsrt); - printf ("IMMR = %08x\n", memctl->memc_immr); -#endif - return 0; -} - -int -do_sitinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} - -#ifdef CONFIG_8260 -int -do_icinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} -#endif - -int -do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - volatile immap_t *immap = (immap_t *) CFG_IMMR; - -#if defined(CONFIG_8xx) - volatile car8xx_t *car = &immap->im_clkrst; -#elif defined(CONFIG_8260) - volatile car8260_t *car = &immap->im_clkrst; -#endif - -#if defined(CONFIG_8xx) - printf ("SCCR = %08x\n", car->car_sccr); - printf ("PLPRCR= %08x\n", car->car_plprcr); - printf ("RSR = %08x\n", car->car_rsr); -#elif defined(CONFIG_8260) - printf ("SCCR = %08x\n", car->car_sccr); - printf ("SCMR = %08x\n", car->car_scmr); - printf ("RSR = %08x\n", car->car_rsr); - printf ("RMR = %08x\n", car->car_rmr); -#endif - return 0; -} - -static int counter; - -static void -header(void) -{ - char *data = "\ - -------------------------------- --------------------------------\ - 00000000001111111111222222222233 00000000001111111111222222222233\ - 01234567890123456789012345678901 01234567890123456789012345678901\ - -------------------------------- --------------------------------\ - "; - int i; - - if (counter % 2) - putc('\n'); - counter = 0; - - for (i = 0; i < 4; i++, data += 79) - printf("%.79s\n", data); -} - -static void binary (char *label, uint value, int nbits) -{ - uint mask = 1 << (nbits - 1); - int i, second = (counter++ % 2); - - if (second) - putc (' '); - puts (label); - for (i = 32 + 1; i != nbits; i--) - putc (' '); - - while (mask != 0) { - if (value & mask) - putc ('1'); - else - putc ('0'); - mask >>= 1; - } - - if (second) - putc ('\n'); -} - -#if defined(CONFIG_8xx) -#define PA_NBITS 16 -#define PA_NB_ODR 8 -#define PB_NBITS 18 -#define PB_NB_ODR 16 -#define PC_NBITS 12 -#define PD_NBITS 13 -#elif defined(CONFIG_8260) -#define PA_NBITS 32 -#define PA_NB_ODR 32 -#define PB_NBITS 28 -#define PB_NB_ODR 28 -#define PC_NBITS 32 -#define PD_NBITS 28 -#endif - -int -do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - volatile immap_t *immap = (immap_t *) CFG_IMMR; - -#if defined(CONFIG_8xx) - volatile iop8xx_t *iop = &immap->im_ioport; - volatile ushort *l, *r; -#elif defined(CONFIG_8260) - volatile iop8260_t *iop = &immap->im_ioport; - volatile uint *l, *r; -#endif - volatile uint *R; - - counter = 0; - header (); - - /* - * Ports A & B - */ - -#if defined(CONFIG_8xx) - l = &iop->iop_padir; - R = &immap->im_cpm.cp_pbdir; -#elif defined(CONFIG_8260) - l = &iop->iop_pdira; - R = &iop->iop_pdirb; -#endif - binary ("PA_DIR", *l++, PA_NBITS); - binary ("PB_DIR", *R++, PB_NBITS); - binary ("PA_PAR", *l++, PA_NBITS); - binary ("PB_PAR", *R++, PB_NBITS); -#if defined(CONFIG_8260) - binary ("PA_SOR", *l++, PA_NBITS); - binary ("PB_SOR", *R++, PB_NBITS); -#endif - binary ("PA_ODR", *l++, PA_NB_ODR); - binary ("PB_ODR", *R++, PB_NB_ODR); - binary ("PA_DAT", *l++, PA_NBITS); - binary ("PB_DAT", *R++, PB_NBITS); - - header (); - - /* - * Ports C & D - */ - -#if defined(CONFIG_8xx) - l = &iop->iop_pcdir; - r = &iop->iop_pddir; -#elif defined(CONFIG_8260) - l = &iop->iop_pdirc; - r = &iop->iop_pdird; -#endif - binary ("PC_DIR", *l++, PC_NBITS); - binary ("PD_DIR", *r++, PD_NBITS); - binary ("PC_PAR", *l++, PC_NBITS); - binary ("PD_PAR", *r++, PD_NBITS); -#if defined(CONFIG_8xx) - binary ("PC_SO ", *l++, PC_NBITS); - binary (" ", 0, 0); - r++; -#elif defined(CONFIG_8260) - binary ("PC_SOR", *l++, PC_NBITS); - binary ("PD_SOR", *r++, PD_NBITS); - binary ("PC_ODR", *l++, PC_NBITS); - binary ("PD_ODR", *r++, PD_NBITS); -#endif - binary ("PC_DAT", *l++, PC_NBITS); - binary ("PD_DAT", *r++, PD_NBITS); -#if defined(CONFIG_8xx) - binary ("PC_INT", *l++, PC_NBITS); -#endif - - header (); - return 0; -} - -/* - * set the io pins - * this needs a clean up for smaller tighter code - * use *uint and set the address based on cmd + port - */ -int -do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - uint rcode = 0; - iopin_t iopin; - static uint port = 0; - static uint pin = 0; - static uint value = 0; - static enum { - DIR, - PAR, - SOR, - ODR, - DAT, -#if defined(CONFIG_8xx) - INT -#endif - } cmd = DAT; - - if (argc != 5) { - puts ("iopset PORT PIN CMD VALUE\n"); - return 1; - } - port = argv[1][0] - 'A'; - if (port > 3) - port -= 0x20; - if (port > 3) - rcode = 1; - pin = simple_strtol (argv[2], NULL, 10); - if (pin > 31) - rcode = 1; - - - switch (argv[3][0]) { - case 'd': - if (argv[3][1] == 'a') - cmd = DAT; - else if (argv[3][1] == 'i') - cmd = DIR; - else - rcode = 1; - break; - case 'p': - cmd = PAR; - break; - case 'o': - cmd = ODR; - break; - case 's': - cmd = SOR; - break; -#if defined(CONFIG_8xx) - case 'i': - cmd = INT; - break; -#endif - default: - printf ("iopset: unknown command %s\n", argv[3]); - rcode = 1; - } - if (argv[4][0] == '1') - value = 1; - else if (argv[4][0] == '0') - value = 0; - else - rcode = 1; - if (rcode == 0) { - iopin.port = port; - iopin.pin = pin; - iopin.flag = 0; - switch (cmd) { - case DIR: - if (value) - iopin_set_out (&iopin); - else - iopin_set_in (&iopin); - break; - case PAR: - if (value) - iopin_set_ded (&iopin); - else - iopin_set_gen (&iopin); - break; - case SOR: - if (value) - iopin_set_opt2 (&iopin); - else - iopin_set_opt1 (&iopin); - break; - case ODR: - if (value) - iopin_set_odr (&iopin); - else - iopin_set_act (&iopin); - break; - case DAT: - if (value) - iopin_set_high (&iopin); - else - iopin_set_low (&iopin); - break; -#if defined(CONFIG_8xx) - case INT: - if (value) - iopin_set_falledge (&iopin); - else - iopin_set_anyedge (&iopin); - break; -#endif - } - - } - return rcode; -} - -int -do_dmainfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} - -int -do_fccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} - -static void prbrg (int n, uint val) -{ - uint extc = (val >> 14) & 3; - uint cd = (val & CPM_BRG_CD_MASK) >> 1; - uint div16 = (val & CPM_BRG_DIV16) != 0; - -#if defined(CONFIG_8xx) - ulong clock = gd->cpu_clk; -#elif defined(CONFIG_8260) - ulong clock = gd->brg_clk; -#endif - - printf ("BRG%d:", n); - - if (val & CPM_BRG_RST) - puts (" RESET"); - else - puts (" "); - - if (val & CPM_BRG_EN) - puts (" ENABLED"); - else - puts (" DISABLED"); - - printf (" EXTC=%d", extc); - - if (val & CPM_BRG_ATB) - puts (" ATB"); - else - puts (" "); - - printf (" DIVIDER=%4d", cd); - if (extc == 0 && cd != 0) { - uint baudrate; - - if (div16) - baudrate = (clock / 16) / (cd + 1); - else - baudrate = clock / (cd + 1); - - printf ("=%6d bps", baudrate); - } else { - puts (" "); - } - - if (val & CPM_BRG_DIV16) - puts (" DIV16"); - else - puts (" "); - - putc ('\n'); -} - -int -do_brginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - volatile immap_t *immap = (immap_t *) CFG_IMMR; - -#if defined(CONFIG_8xx) - volatile cpm8xx_t *cp = &immap->im_cpm; - volatile uint *p = &cp->cp_brgc1; -#elif defined(CONFIG_8260) - volatile uint *p = &immap->im_brgc1; -#endif - int i = 1; - - while (i <= 4) - prbrg (i++, *p++); - -#if defined(CONFIG_8260) - p = &immap->im_brgc5; - while (i <= 8) - prbrg (i++, *p++); -#endif - return 0; -} - -int -do_i2cinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - volatile immap_t *immap = (immap_t *) CFG_IMMR; - -#if defined(CONFIG_8xx) - volatile i2c8xx_t *i2c = &immap->im_i2c; - volatile cpm8xx_t *cp = &immap->im_cpm; - volatile iic_t *iip = (iic_t *) & cp->cp_dparam[PROFF_IIC]; -#elif defined(CONFIG_8260) - volatile i2c8260_t *i2c = &immap->im_i2c; - volatile iic_t *iip; - uint dpaddr; - - dpaddr = *((unsigned short *) (&immap->im_dprambase[PROFF_I2C_BASE])); - if (dpaddr == 0) - iip = NULL; - else - iip = (iic_t *) & immap->im_dprambase[dpaddr]; -#endif - - printf ("I2MOD = %02x I2ADD = %02x\n", i2c->i2c_i2mod, i2c->i2c_i2add); - printf ("I2BRG = %02x I2COM = %02x\n", i2c->i2c_i2brg, i2c->i2c_i2com); - printf ("I2CER = %02x I2CMR = %02x\n", i2c->i2c_i2cer, i2c->i2c_i2cmr); - - if (iip == NULL) - puts ("i2c parameter ram not allocated\n"); - else { - printf ("RBASE = %08x TBASE = %08x\n", - iip->iic_rbase, iip->iic_tbase); - printf ("RFCR = %02x TFCR = %02x\n", - iip->iic_rfcr, iip->iic_tfcr); - printf ("MRBLR = %04x\n", iip->iic_mrblr); - printf ("RSTATE= %08x RDP = %08x\n", - iip->iic_rstate, iip->iic_rdp); - printf ("RBPTR = %04x RBC = %04x\n", - iip->iic_rbptr, iip->iic_rbc); - printf ("RXTMP = %08x\n", iip->iic_rxtmp); - printf ("TSTATE= %08x TDP = %08x\n", - iip->iic_tstate, iip->iic_tdp); - printf ("TBPTR = %04x TBC = %04x\n", - iip->iic_tbptr, iip->iic_tbc); - printf ("TXTMP = %08x\n", iip->iic_txtmp); - } - return 0; -} - -int -do_sccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} - -int -do_smcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} - -int -do_spiinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} - -int -do_muxinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} - -int -do_siinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} - -int -do_mccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unimplemented (cmdtp, flag, argc, argv); - return 0; -} - -/***************************************************/ - -U_BOOT_CMD( - siuinfo, 1, 1, do_siuinfo, - "siuinfo - print System Interface Unit (SIU) registers\n", - NULL -); - -U_BOOT_CMD( - memcinfo, 1, 1, do_memcinfo, - "memcinfo- print Memory Controller registers\n", - NULL -); - -U_BOOT_CMD( - sitinfo, 1, 1, do_sitinfo, - "sitinfo - print System Integration Timers (SIT) registers\n", - NULL -); - -#ifdef CONFIG_8260 -U_BOOT_CMD( - icinfo, 1, 1, do_icinfo, - "icinfo - print Interrupt Controller registers\n", - NULL -); -#endif - -U_BOOT_CMD( - carinfo, 1, 1, do_carinfo, - "carinfo - print Clocks and Reset registers\n", - NULL -); - -U_BOOT_CMD( - iopinfo, 1, 1, do_iopinfo, - "iopinfo - print I/O Port registers\n", - NULL -); - -U_BOOT_CMD( - iopset, 5, 0, do_iopset, - "iopset - set I/O Port registers\n", - "PORT PIN CMD VALUE\nPORT: A-D, PIN: 0-31, CMD: [dat|dir|odr|sor], VALUE: 0|1" -); - -U_BOOT_CMD( - dmainfo, 1, 1, do_dmainfo, - "dmainfo - print SDMA/IDMA registers\n", - NULL -); - -U_BOOT_CMD( - fccinfo, 1, 1, do_fccinfo, - "fccinfo - print FCC registers\n", - NULL -); - -U_BOOT_CMD( - brginfo, 1, 1, do_brginfo, - "brginfo - print Baud Rate Generator (BRG) registers\n", - NULL -); - -U_BOOT_CMD( - i2cinfo, 1, 1, do_i2cinfo, - "i2cinfo - print I2C registers\n", - NULL -); - -U_BOOT_CMD( - sccinfo, 1, 1, do_sccinfo, - "sccinfo - print SCC registers\n", - NULL -); - -U_BOOT_CMD( - smcinfo, 1, 1, do_smcinfo, - "smcinfo - print SMC registers\n", - NULL -); - -U_BOOT_CMD( - spiinfo, 1, 1, do_spiinfo, - "spiinfo - print Serial Peripheral Interface (SPI) registers\n", - NULL -); - -U_BOOT_CMD( - muxinfo, 1, 1, do_muxinfo, - "muxinfo - print CPM Multiplexing registers\n", - NULL -); - -U_BOOT_CMD( - siinfo, 1, 1, do_siinfo, - "siinfo - print Serial Interface (SI) registers\n", - NULL -); - -U_BOOT_CMD( - mccinfo, 1, 1, do_mccinfo, - "mccinfo - print MCC registers\n", - NULL -); - - -#endif /* CFG_CMD_IMMAP && (CONFIG_8xx || CONFIG_8260) */ diff --git a/common/cmd_itest.c b/common/cmd_itest.c deleted file mode 100644 index 0aeef5a4ef..0000000000 --- a/common/cmd_itest.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * (C) Copyright 2003 - * Tait Electronics Limited, Christchurch, New Zealand - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * This file provides a shell like 'test' function to return - * true/false from an integer or string compare of two memory - * locations or a location and a scalar/literal. - * A few parts were lifted from bash 'test' command - */ - -#include <common.h> -#include <config.h> -#include <command.h> - -#if (CONFIG_COMMANDS & CFG_CMD_ITEST) - -#define EQ 0 -#define NE 1 -#define LT 2 -#define GT 3 -#define LE 4 -#define GE 5 - -struct op_tbl_s { - char *op; /* operator string */ - int opcode; /* internal representation of opcode */ -}; - -typedef struct op_tbl_s op_tbl_t; - -op_tbl_t op_table [] = { - { "-lt", LT }, - { "<" , LT }, - { "-gt", GT }, - { ">" , GT }, - { "-eq", EQ }, - { "==" , EQ }, - { "-ne", NE }, - { "!=" , NE }, - { "<>" , NE }, - { "-ge", GE }, - { ">=" , GE }, - { "-le", LE }, - { "<=" , LE }, -}; - -#define op_tbl_size (sizeof(op_table)/sizeof(op_table[0])) - -static long evalexp(char *s, int w) -{ - long l, *p; - - /* if the parameter starts with a * then assume is a pointer to the value we want */ - if (s[0] == '*') { - p = (long *)simple_strtoul(&s[1], NULL, 16); - l = *p; - } else { - l = simple_strtoul(s, NULL, 16); - } - - return (l & ((1 << (w * 8)) - 1)); -} - -static char * evalstr(char *s) -{ - /* if the parameter starts with a * then assume a string pointer else its a literal */ - if (s[0] == '*') { - return (char *)simple_strtoul(&s[1], NULL, 16); - } else { - return s; - } -} - -static int stringcomp(char *s, char *t, int op) -{ - int n, p; - char *l, *r; - - l = evalstr(s); - r = evalstr(t); - - /* we'll do a compare based on the length of the shortest string */ - n = min(strlen(l), strlen(r)); - - p = strncmp(l, r, n); - switch (op) { - case EQ: return (p == 0); - case NE: return (p != 0); - case LT: return (p < 0); - case GT: return (p > 0); - case LE: return (p <= 0); - case GE: return (p >= 0); - } - return (0); -} - -static int arithcomp (char *s, char *t, int op, int w) -{ - long l, r; - - l = evalexp (s, w); - r = evalexp (t, w); - - switch (op) { - case EQ: return (l == r); - case NE: return (l != r); - case LT: return (l < r); - case GT: return (l > r); - case LE: return (l <= r); - case GE: return (l >= r); - } - return (0); -} - -int binary_test (char *op, char *arg1, char *arg2, int w) -{ - int len, i; - op_tbl_t *optp; - - len = strlen(op); - - for (optp = (op_tbl_t *)&op_table, i = 0; - i < op_tbl_size; - optp++, i++) { - - if ((strncmp (op, optp->op, len) == 0) && (len == strlen (optp->op))) { - if (w == 0) { - return (stringcomp(arg1, arg2, optp->opcode)); - } else { - return (arithcomp (arg1, arg2, optp->opcode, w)); - } - } - } - - printf("Unknown operator '%s'\n", op); - return 0; /* op code not found */ -} - -/* command line interface to the shell test */ -int do_itest ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ) -{ - int value, w; - - /* Validate arguments */ - if ((argc != 4)){ - printf("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* Check for a data width specification. - * Defaults to long (4) if no specification. - * Uses -2 as 'width' for .s (string) so as not to upset existing code - */ - switch (w = cmd_get_data_size(argv[0], 4)) { - case 1: - case 2: - case 4: - value = binary_test (argv[2], argv[1], argv[3], w); - break; - case -2: - value = binary_test (argv[2], argv[1], argv[3], 0); - break; - case -1: - default: - puts("Invalid data width specifier\n"); - value = 0; - break; - } - - return !value; -} - -U_BOOT_CMD( - itest, 4, 0, do_itest, - "itest\t- return true/false on integer compare\n", - "[.b, .w, .l, .s] [*]value1 <op> [*]value2\n" -); -#endif /* CONFIG_COMMANDS & CFG_CMD_ITEST */ diff --git a/common/cmd_log.c b/common/cmd_log.c deleted file mode 100644 index 042a403026..0000000000 --- a/common/cmd_log.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * (C) Copyright 2002 - * Detlev Zundel, DENX Software Engineering, dzu@denx.de. - * - * Code used from linux/kernel/printk.c - * Copyright (C) 1991, 1992 Linus Torvalds - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * Comments: - * - * After relocating the code, the environment variable "loglevel" is - * copied to console_loglevel. The functionality is similar to the - * handling in the Linux kernel, i.e. messages logged with a priority - * less than console_loglevel are also output to stdout. - * - * If you want messages with the default level (e.g. POST messages) to - * appear on stdout also, make sure the environment variable - * "loglevel" is set at boot time to a number higher than - * default_message_loglevel below. - */ - -/* - * Logbuffer handling routines - */ - -#include <common.h> -#include <command.h> -#include <devices.h> -#include <post.h> -#include <logbuff.h> - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_LOGBUFFER) - -/* Local prototypes */ -static void logbuff_putc (const char c); -static void logbuff_puts (const char *s); -static int logbuff_printk(const char *line); - -static char buf[1024]; - -/* This combination will not print messages with the default loglevel */ -static unsigned console_loglevel = 3; -static unsigned default_message_loglevel = 4; -static unsigned char *log_buf = NULL; -static unsigned long *ext_log_size; -static unsigned long *ext_log_start; -static unsigned long *ext_logged_chars; -#define log_size (*ext_log_size) -#define log_start (*ext_log_start) -#define logged_chars (*ext_logged_chars) - -/* Forced by code, eh! */ -#define LOGBUFF_MAGIC 0xc0de4ced - -/* The mapping used here has to be the same as in setup_ext_logbuff () - in linux/kernel/printk */ -void logbuff_init_ptrs (void) -{ - unsigned long *ext_tag; - unsigned long post_word; - char *s; - - log_buf = (unsigned char *)(gd->bd->bi_memsize-LOGBUFF_LEN); - ext_tag = (unsigned long *)(log_buf)-4; - ext_log_start = (unsigned long *)(log_buf)-3; - ext_log_size = (unsigned long *)(log_buf)-2; - ext_logged_chars = (unsigned long *)(log_buf)-1; - post_word = post_word_load(); -#ifdef CONFIG_POST - /* The post routines have setup the word so we can simply test it */ - if (post_word_load () & POST_COLDBOOT) { - logged_chars = log_size = log_start = 0; - *ext_tag = LOGBUFF_MAGIC; - } -#else - /* No post routines, so we do our own checking */ - if (post_word != LOGBUFF_MAGIC) { - logged_chars = log_size = log_start = 0; - post_word_store (LOGBUFF_MAGIC); - *ext_tag = LOGBUFF_MAGIC; - } -#endif - /* Initialize default loglevel if present */ - if ((s = getenv ("loglevel")) != NULL) - console_loglevel = (int)simple_strtoul (s, NULL, 10); - - gd->post_log_word |= LOGBUFF_INITIALIZED; -} - -int drv_logbuff_init (void) -{ - device_t logdev; - int rc; - - /* Device initialization */ - memset (&logdev, 0, sizeof (logdev)); - - strcpy (logdev.name, "logbuff"); - logdev.ext = 0; /* No extensions */ - logdev.flags = DEV_FLAGS_OUTPUT; /* Output only */ - logdev.putc = logbuff_putc; /* 'putc' function */ - logdev.puts = logbuff_puts; /* 'puts' function */ - - rc = device_register (&logdev); - - return (rc == 0) ? 1 : rc; -} - -static void logbuff_putc (const char c) -{ - char buf[2]; - buf[0] = c; - buf[1] = '\0'; - logbuff_printk (buf); -} - -static void logbuff_puts (const char *s) -{ - logbuff_printk (s); -} - -void logbuff_log(char *msg) -{ - if ((gd->post_log_word & LOGBUFF_INITIALIZED)) { - logbuff_printk (msg); - } else { - /* Can happen only for pre-relocated errors as logging */ - /* at that stage should be disabled */ - puts (msg); - } -} - -/* - * Subroutine: do_log - * - * Description: Handler for 'log' command.. - * - * Inputs: argv[1] contains the subcommand - * - * Return: None - * - */ -int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - char *s; - unsigned long i; - - if (strcmp(argv[1],"append") == 0) { - /* Log concatenation of all arguments separated by spaces */ - for (i=2; i<argc; i++) { - logbuff_printk (argv[i]); - logbuff_putc ((i<argc-1) ? ' ' : '\n'); - } - return 0; - } - - switch (argc) { - - case 2: - if (strcmp(argv[1],"show") == 0) { - for (i=0; i < (log_size&LOGBUFF_MASK); i++) { - s = (char *)log_buf+((log_start+i)&LOGBUFF_MASK); - putc (*s); - } - return 0; - } else if (strcmp(argv[1],"reset") == 0) { - log_start = 0; - log_size = 0; - logged_chars = 0; - return 0; - } else if (strcmp(argv[1],"info") == 0) { - printf ("Logbuffer at %08lx\n", (unsigned long)log_buf); - printf ("log_start = %08lx\n", log_start); - printf ("log_size = %08lx\n", log_size); - printf ("logged_chars = %08lx\n", logged_chars); - return 0; - } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - - default: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } -} -#if defined(CONFIG_LOGBUFFER) -U_BOOT_CMD( - log, 255, 1, do_log, - "log - manipulate logbuffer\n", - "info - show pointer details\n" - "log reset - clear contents\n" - "log show - show contents\n" - "log append <msg> - append <msg> to the logbuffer\n" -); -#endif /* CONFIG_LOGBUFFER */ -static int logbuff_printk(const char *line) -{ - int i; - char *msg, *p, *buf_end; - int line_feed; - static signed char msg_level = -1; - - strcpy (buf + 3, line); - i = strlen (line); - buf_end = buf + 3 + i; - for (p = buf + 3; p < buf_end; p++) { - msg = p; - if (msg_level < 0) { - if ( - p[0] != '<' || - p[1] < '0' || - p[1] > '7' || - p[2] != '>' - ) { - p -= 3; - p[0] = '<'; - p[1] = default_message_loglevel + '0'; - p[2] = '>'; - } else - msg += 3; - msg_level = p[1] - '0'; - } - line_feed = 0; - for (; p < buf_end; p++) { - log_buf[(log_start+log_size) & LOGBUFF_MASK] = *p; - if (log_size < LOGBUFF_LEN) - log_size++; - else - log_start++; - - logged_chars++; - if (*p == '\n') { - line_feed = 1; - break; - } - } - if (msg_level < console_loglevel) { - printf("%s", msg); - } - if (line_feed) - msg_level = -1; - } - return i; -} - -#endif /* (CONFIG_LOGBUFFER) */ diff --git a/common/cmd_mac.c b/common/cmd_mac.c deleted file mode 100644 index 0add43285f..0000000000 --- a/common/cmd_mac.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2006 Freescale Semiconductor - * York Sun (yorksun@freescale.com) - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <command.h> - -#ifdef CFG_ID_EEPROM - -extern int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - -U_BOOT_CMD( - mac, 3, 1, do_mac, - "mac - display and program the system ID and MAC addresses in EEPROM\n", - "[read|save|id|num|errata|date|ports|0|1|2|3|4|5|6|7]\n" - "read\n" - " - show content of mac\n" - "mac save\n" - " - save to the EEPROM\n" - "mac id\n" - " - program system id\n" - "mac num\n" - " - program system serial number\n" - "mac errata\n" - " - program errata data\n" - "mac date\n" - " - program data date\n" - "mac ports\n" - " - program the number of ports\n" - "mac 0\n" - " - program the MAC address for port 0\n" - "mac 1\n" - " - program the MAC address for port 1\n" - "mac 2\n" - " - program the MAC address for port 2\n" - "mac 3\n" - " - program the MAC address for port 3\n" - "mac 4\n" - " - program the MAC address for port 4\n" - "mac 5\n" - " - program the MAC address for port 5\n" - "mac 6\n" - " - program the MAC address for port 6\n" - "mac 7\n" - " - program the MAC address for port 7\n" -); -#endif /* CFG_ID_EEPROM */ diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c deleted file mode 100644 index 573eb97ead..0000000000 --- a/common/cmd_mmc.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * (C) Copyright 2003 - * Kyle Harris, kharris@nexus-tech.net - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <command.h> - -#if (CONFIG_COMMANDS & CFG_CMD_MMC) - -#include <mmc.h> - -int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - if (mmc_init (1) != 0) { - printf ("No MMC card found\n"); - return 1; - } - return 0; -} - -U_BOOT_CMD( - mmcinit, 1, 0, do_mmc, - "mmcinit - init mmc card\n", - NULL -); - -#endif /* CFG_CMD_MMC */ diff --git a/common/cmd_nand.c b/common/cmd_nand.c deleted file mode 100644 index a40983fa17..0000000000 --- a/common/cmd_nand.c +++ /dev/null @@ -1,973 +0,0 @@ -/* - * Driver for NAND support, Rick Bronson - * borrowed heavily from: - * (c) 1999 Machine Vision Holdings, Inc. - * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> - * - * Added 16-bit nand support - * (C) 2004 Texas Instruments - */ - -#include <common.h> - - -#ifndef CFG_NAND_LEGACY -/* - * - * New NAND support - * - */ -#include <common.h> - -#if (CONFIG_COMMANDS & CFG_CMD_NAND) - -#include <command.h> -#include <watchdog.h> -#include <malloc.h> -#include <asm/byteorder.h> - -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include <status_led.h> -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - -#include <jffs2/jffs2.h> -#include <nand.h> - -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) - -/* parition handling routines */ -int mtdparts_init(void); -int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); -int find_dev_and_part(const char *id, struct mtd_device **dev, - u8 *part_num, struct part_info **part); -#endif - -extern nand_info_t nand_info[]; /* info for NAND chips */ - -static int nand_dump_oob(nand_info_t *nand, ulong off) -{ - return 0; -} - -static int nand_dump(nand_info_t *nand, ulong off) -{ - int i; - u_char *buf, *p; - - buf = malloc(nand->oobblock + nand->oobsize); - if (!buf) { - puts("No memory for page buffer\n"); - return 1; - } - off &= ~(nand->oobblock - 1); - i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); - if (i < 0) { - printf("Error (%d) reading page %08x\n", i, off); - free(buf); - return 1; - } - printf("Page %08x dump:\n", off); - i = nand->oobblock >> 4; p = buf; - while (i--) { - printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" - " %02x %02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], - p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); - p += 16; - } - puts("OOB:\n"); - i = nand->oobsize >> 3; - while (i--) { - printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - p += 8; - } - free(buf); - - return 0; -} - -/* ------------------------------------------------------------------------- */ - -static inline int str2long(char *p, ulong *num) -{ - char *endptr; - - *num = simple_strtoul(p, &endptr, 16); - return (*p != '\0' && *endptr == '\0') ? 1 : 0; -} - -static int -arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size) -{ - int idx = nand_curr_device; -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) - struct mtd_device *dev; - struct part_info *part; - u8 pnum; - - if (argc >= 1 && !(str2long(argv[0], off))) { - if ((mtdparts_init() == 0) && - (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) { - if (dev->id->type != MTD_DEV_TYPE_NAND) { - puts("not a NAND device\n"); - return -1; - } - *off = part->offset; - if (argc >= 2) { - if (!(str2long(argv[1], size))) { - printf("'%s' is not a number\n", argv[1]); - return -1; - } - if (*size > part->size) - *size = part->size; - } else { - *size = part->size; - } - idx = dev->id->num; - *nand = nand_info[idx]; - goto out; - } - } -#endif - - if (argc >= 1) { - if (!(str2long(argv[0], off))) { - printf("'%s' is not a number\n", argv[0]); - return -1; - } - } else { - *off = 0; - } - - if (argc >= 2) { - if (!(str2long(argv[1], size))) { - printf("'%s' is not a number\n", argv[1]); - return -1; - } - } else { - *size = nand->size - *off; - } - -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) -out: -#endif - printf("device %d ", idx); - if (*size == nand->size) - puts("whole chip\n"); - else - printf("offset 0x%x, size 0x%x\n", *off, *size); - return 0; -} - -int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - int i, dev, ret; - ulong addr, off, size; - char *cmd, *s; - nand_info_t *nand; - int quiet = 0; - const char *quiet_str = getenv("quiet"); - - /* at least two arguments please */ - if (argc < 2) - goto usage; - - if (quiet_str) - quiet = simple_strtoul(quiet_str, NULL, 0) != 0; - - cmd = argv[1]; - - if (strcmp(cmd, "info") == 0) { - - putc('\n'); - for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { - if (nand_info[i].name) - printf("Device %d: %s, sector size %lu KiB\n", - i, nand_info[i].name, - nand_info[i].erasesize >> 10); - } - return 0; - } - - if (strcmp(cmd, "device") == 0) { - - if (argc < 3) { - if ((nand_curr_device < 0) || - (nand_curr_device >= CFG_MAX_NAND_DEVICE)) - puts("\nno devices available\n"); - else - printf("\nDevice %d: %s\n", nand_curr_device, - nand_info[nand_curr_device].name); - return 0; - } - dev = (int)simple_strtoul(argv[2], NULL, 10); - if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { - puts("No such device\n"); - return 1; - } - printf("Device %d: %s", dev, nand_info[dev].name); - puts("... is now current device\n"); - nand_curr_device = dev; - -#ifdef CFG_NAND_SELECT_DEVICE - /* - * Select the chip in the board/cpu specific driver - */ - board_nand_select_device(nand_info[dev].priv, dev); -#endif - - return 0; - } - - if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && - strncmp(cmd, "dump", 4) != 0 && - strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 && - strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 && - strcmp(cmd, "biterr") != 0 && - strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 ) - goto usage; - - /* the following commands operate on the current device */ - if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE || - !nand_info[nand_curr_device].name) { - puts("\nno devices available\n"); - return 1; - } - nand = &nand_info[nand_curr_device]; - - if (strcmp(cmd, "bad") == 0) { - printf("\nDevice %d bad blocks:\n", nand_curr_device); - for (off = 0; off < nand->size; off += nand->erasesize) - if (nand_block_isbad(nand, off)) - printf(" %08x\n", off); - return 0; - } - - /* - * Syntax is: - * 0 1 2 3 4 - * nand erase [clean] [off size] - */ - if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) { - nand_erase_options_t opts; - /* "clean" at index 2 means request to write cleanmarker */ - int clean = argc > 2 && !strcmp("clean", argv[2]); - int o = clean ? 3 : 2; - int scrub = !strcmp(cmd, "scrub"); - - printf("\nNAND %s: ", scrub ? "scrub" : "erase"); - /* skip first two or three arguments, look for offset and size */ - if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0) - return 1; - - memset(&opts, 0, sizeof(opts)); - opts.offset = off; - opts.length = size; - opts.jffs2 = clean; - opts.quiet = quiet; - - if (scrub) { - puts("Warning: " - "scrub option will erase all factory set " - "bad blocks!\n" - " " - "There is no reliable way to recover them.\n" - " " - "Use this command only for testing purposes " - "if you\n" - " " - "are sure of what you are doing!\n" - "\nReally scrub this NAND flash? <y/N>\n"); - - if (getc() == 'y' && getc() == '\r') { - opts.scrub = 1; - } else { - puts("scrub aborted\n"); - return -1; - } - } - ret = nand_erase_opts(nand, &opts); - printf("%s\n", ret ? "ERROR" : "OK"); - - return ret == 0 ? 0 : 1; - } - - if (strncmp(cmd, "dump", 4) == 0) { - if (argc < 3) - goto usage; - - s = strchr(cmd, '.'); - off = (int)simple_strtoul(argv[2], NULL, 16); - - if (s != NULL && strcmp(s, ".oob") == 0) - ret = nand_dump_oob(nand, off); - else - ret = nand_dump(nand, off); - - return ret == 0 ? 1 : 0; - - } - - /* read write */ - if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { - int read; - - if (argc < 4) - goto usage; - - addr = (ulong)simple_strtoul(argv[2], NULL, 16); - - read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ - printf("\nNAND %s: ", read ? "read" : "write"); - if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) - return 1; - - s = strchr(cmd, '.'); - if (s != NULL && - (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { - if (read) { - /* read */ - nand_read_options_t opts; - memset(&opts, 0, sizeof(opts)); - opts.buffer = (u_char*) addr; - opts.length = size; - opts.offset = off; - opts.quiet = quiet; - ret = nand_read_opts(nand, &opts); - } else { - /* write */ - nand_write_options_t opts; - memset(&opts, 0, sizeof(opts)); - opts.buffer = (u_char*) addr; - opts.length = size; - opts.offset = off; - /* opts.forcejffs2 = 1; */ - opts.pad = 1; - opts.blockalign = 1; - opts.quiet = quiet; - ret = nand_write_opts(nand, &opts); - } - } else { - if (read) - ret = nand_read(nand, off, &size, (u_char *)addr); - else - ret = nand_write(nand, off, &size, (u_char *)addr); - } - - printf(" %d bytes %s: %s\n", size, - read ? "read" : "written", ret ? "ERROR" : "OK"); - - return ret == 0 ? 0 : 1; - } - - if (strcmp(cmd, "markbad") == 0) { - addr = (ulong)simple_strtoul(argv[2], NULL, 16); - - int ret = nand->block_markbad(nand, addr); - if (ret == 0) { - printf("block 0x%08lx successfully marked as bad\n", - (ulong) addr); - return 0; - } else { - printf("block 0x%08lx NOT marked as bad! ERROR %d\n", - (ulong) addr, ret); - } - return 1; - } - if (strcmp(cmd, "biterr") == 0) { - /* todo */ - return 1; - } - - if (strcmp(cmd, "lock") == 0) { - int tight = 0; - int status = 0; - if (argc == 3) { - if (!strcmp("tight", argv[2])) - tight = 1; - if (!strcmp("status", argv[2])) - status = 1; - } - - if (status) { - ulong block_start = 0; - ulong off; - int last_status = -1; - - struct nand_chip *nand_chip = nand->priv; - /* check the WP bit */ - nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1); - printf("device is %swrite protected\n", - (nand_chip->read_byte(nand) & 0x80 ? - "NOT " : "" ) ); - - for (off = 0; off < nand->size; off += nand->oobblock) { - int s = nand_get_lock_status(nand, off); - - /* print message only if status has changed - * or at end of chip - */ - if (off == nand->size - nand->oobblock - || (s != last_status && off != 0)) { - - printf("%08x - %08x: %8d pages %s%s%s\n", - block_start, - off-1, - (off-block_start)/nand->oobblock, - ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), - ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), - ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); - } - - last_status = s; - } - } else { - if (!nand_lock(nand, tight)) { - puts("NAND flash successfully locked\n"); - } else { - puts("Error locking NAND flash\n"); - return 1; - } - } - return 0; - } - - if (strcmp(cmd, "unlock") == 0) { - if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0) - return 1; - - if (!nand_unlock(nand, off, size)) { - puts("NAND flash successfully unlocked\n"); - } else { - puts("Error unlocking NAND flash, " - "write and erase will probably fail\n"); - return 1; - } - return 0; - } - -usage: - printf("Usage:\n%s\n", cmdtp->usage); - return 1; -} - -U_BOOT_CMD(nand, 5, 1, do_nand, - "nand - NAND sub-system\n", - "info - show available NAND devices\n" - "nand device [dev] - show or set current device\n" - "nand read[.jffs2] - addr off|partition size\n" - "nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n" - " at offset `off' to/from memory address `addr'\n" - "nand erase [clean] [off size] - erase `size' bytes from\n" - " offset `off' (entire device if not specified)\n" - "nand bad - show bad blocks\n" - "nand dump[.oob] off - dump page\n" - "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" - "nand markbad off - mark bad block at offset (UNSAFE)\n" - "nand biterr off - make a bit error at offset (UNSAFE)\n" - "nand lock [tight] [status] - bring nand to lock state or display locked pages\n" - "nand unlock [offset] [size] - unlock section\n"); - -static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, - ulong offset, ulong addr, char *cmd) -{ - int r; - char *ep; - ulong cnt; - image_header_t *hdr; - - printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset); - - cnt = nand->oobblock; - r = nand_read(nand, offset, &cnt, (u_char *) addr); - if (r) { - puts("** Read error\n"); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - hdr = (image_header_t *) addr; - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - print_image_hdr(hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); - - r = nand_read(nand, offset, &cnt, (u_char *) addr); - if (r) { - puts("** Read error\n"); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - /* Loading ok, update default load address */ - - load_addr = addr; - - return 0; -} - -int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - char *boot_device = NULL; - int idx; - ulong addr, offset = 0; -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) - struct mtd_device *dev; - struct part_info *part; - u8 pnum; - - if (argc >= 2) { - char *p = (argc == 2) ? argv[1] : argv[2]; - if (!(str2long(p, &addr)) && (mtdparts_init() == 0) && - (find_dev_and_part(p, &dev, &pnum, &part) == 0)) { - if (dev->id->type != MTD_DEV_TYPE_NAND) { - puts("Not a NAND device\n"); - return 1; - } - if (argc > 3) - goto usage; - if (argc == 3) - addr = simple_strtoul(argv[2], NULL, 16); - else - addr = CFG_LOAD_ADDR; - return nand_load_image(cmdtp, &nand_info[dev->id->num], - part->offset, addr, argv[0]); - } - } -#endif - - switch (argc) { - case 1: - addr = CFG_LOAD_ADDR; - boot_device = getenv("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - case 4: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - offset = simple_strtoul(argv[3], NULL, 16); - break; - default: -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE) -usage: -#endif - printf("Usage:\n%s\n", cmdtp->usage); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - if (!boot_device) { - puts("\n** No boot device **\n"); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - idx = simple_strtoul(boot_device, NULL, 16); - - if (idx < 0 || idx >= CFG_MAX_NAND_DEVICE || !nand_info[idx].name) { - printf("\n** Device %d not available\n", idx); - SHOW_BOOT_PROGRESS(-1); - return 1; - } - - return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]); -} - -U_BOOT_CMD(nboot, 4, 1, do_nandboot, - "nboot - boot from NAND device\n", - "[partition] | [[[loadAddr] dev] offset]\n"); - -#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ - -#else /* CFG_NAND_LEGACY */ -/* - * - * Legacy NAND support - to be phased out - * - */ -#include <command.h> -#include <malloc.h> -#include <asm/io.h> -#include <watchdog.h> - -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include <status_led.h> -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - -#if (CONFIG_COMMANDS & CFG_CMD_NAND) -#include <linux/mtd/nand_legacy.h> - -#ifdef CONFIG_OMAP1510 -void archflashwp(void *archdata, int wp); -#endif - -#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) - -#undef NAND_DEBUG -#undef PSYCHO_DEBUG - -/* ****************** WARNING ********************* - * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will - * erase (or at least attempt to erase) blocks that are marked - * bad. This can be very handy if you are _sure_ that the block - * is OK, say because you marked a good block bad to test bad - * block handling and you are done testing, or if you have - * accidentally marked blocks bad. - * - * Erasing factory marked bad blocks is a _bad_ idea. If the - * erase succeeds there is no reliable way to find them again, - * and attempting to program or erase bad blocks can affect - * the data in _other_ (good) blocks. - */ -#define ALLOW_ERASE_BAD_DEBUG 0 - -#define CONFIG_MTD_NAND_ECC /* enable ECC */ -#define CONFIG_MTD_NAND_ECC_JFFS2 - -/* bits for nand_legacy_rw() `cmd'; or together as needed */ -#define NANDRW_READ 0x01 -#define NANDRW_WRITE 0x00 -#define NANDRW_JFFS2 0x02 -#define NANDRW_JFFS2_SKIP 0x04 - -/* - * Imports from nand_legacy.c - */ -extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; -extern int curr_device; -extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, - size_t len, int clean); -extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start, - size_t len, size_t *retlen, u_char *buf); -extern void nand_print(struct nand_chip *nand); -extern void nand_print_bad(struct nand_chip *nand); -extern int nand_read_oob(struct nand_chip *nand, size_t ofs, - size_t len, size_t *retlen, u_char *buf); -extern int nand_write_oob(struct nand_chip *nand, size_t ofs, - size_t len, size_t *retlen, const u_char *buf); - - -int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - int rcode = 0; - - switch (argc) { - case 0: - case 1: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 2: - if (strcmp (argv[1], "info") == 0) { - int i; - - putc ('\n'); - - for (i = 0; i < CFG_MAX_NAND_DEVICE; ++i) { - if (nand_dev_desc[i].ChipID == - NAND_ChipID_UNKNOWN) - continue; /* list only known devices */ - printf ("Device %d: ", i); - nand_print (&nand_dev_desc[i]); - } - return 0; - - } else if (strcmp (argv[1], "device") == 0) { - if ((curr_device < 0) - || (curr_device >= CFG_MAX_NAND_DEVICE)) { - puts ("\nno devices available\n"); - return 1; - } - printf ("\nDevice %d: ", curr_device); - nand_print (&nand_dev_desc[curr_device]); - return 0; - - } else if (strcmp (argv[1], "bad") == 0) { - if ((curr_device < 0) - || (curr_device >= CFG_MAX_NAND_DEVICE)) { - puts ("\nno devices available\n"); - return 1; - } - printf ("\nDevice %d bad blocks:\n", curr_device); - nand_print_bad (&nand_dev_desc[curr_device]); - return 0; - - } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 3: - if (strcmp (argv[1], "device") == 0) { - int dev = (int) simple_strtoul (argv[2], NULL, 10); - - printf ("\nDevice %d: ", dev); - if (dev >= CFG_MAX_NAND_DEVICE) { - puts ("unknown device\n"); - return 1; - } - nand_print (&nand_dev_desc[dev]); - /*nand_print (dev); */ - - if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) { - return 1; - } - - curr_device = dev; - - puts ("... is now current device\n"); - - return 0; - } else if (strcmp (argv[1], "erase") == 0 - && strcmp (argv[2], "clean") == 0) { - struct nand_chip *nand = &nand_dev_desc[curr_device]; - ulong off = 0; - ulong size = nand->totlen; - int ret; - - printf ("\nNAND erase: device %d offset %ld, size %ld ... ", curr_device, off, size); - - ret = nand_legacy_erase (nand, off, size, 1); - - printf ("%s\n", ret ? "ERROR" : "OK"); - - return ret; - } - - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - default: - /* at least 4 args */ - - if (strncmp (argv[1], "read", 4) == 0 || - strncmp (argv[1], "write", 5) == 0) { - ulong addr = simple_strtoul (argv[2], NULL, 16); - ulong off = simple_strtoul (argv[3], NULL, 16); - ulong size = simple_strtoul (argv[4], NULL, 16); - int cmd = (strncmp (argv[1], "read", 4) == 0) ? - NANDRW_READ : NANDRW_WRITE; - int ret, total; - char *cmdtail = strchr (argv[1], '.'); - - if (cmdtail && !strncmp (cmdtail, ".oob", 2)) { - /* read out-of-band data */ - if (cmd & NANDRW_READ) { - ret = nand_read_oob (nand_dev_desc + curr_device, - off, size, (size_t *) & total, - (u_char *) addr); - } else { - ret = nand_write_oob (nand_dev_desc + curr_device, - off, size, (size_t *) & total, - (u_char *) addr); - } - return ret; - } else if (cmdtail && !strncmp (cmdtail, ".jffs2", 2)) - cmd |= NANDRW_JFFS2; /* skip bad blocks */ - else if (cmdtail && !strncmp (cmdtail, ".jffs2s", 2)) { - cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ - if (cmd & NANDRW_READ) - cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ - } -#ifdef SXNI855T - /* need ".e" same as ".j" for compatibility with older units */ - else if (cmdtail && !strcmp (cmdtail, ".e")) - cmd |= NANDRW_JFFS2; /* skip bad blocks */ -#endif -#ifdef CFG_NAND_SKIP_BAD_DOT_I - /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */ - /* ".i" for image -> read skips bad block (no 0xff) */ - else if (cmdtail && !strcmp (cmdtail, ".i")) { - cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ - if (cmd & NANDRW_READ) - cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ - } -#endif /* CFG_NAND_SKIP_BAD_DOT_I */ - else if (cmdtail) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - printf ("\nNAND %s: device %d offset %ld, size %ld ...\n", - (cmd & NANDRW_READ) ? "read" : "write", - curr_device, off, size); - - ret = nand_legacy_rw (nand_dev_desc + curr_device, - cmd, off, size, - (size_t *) & total, - (u_char *) addr); - - printf (" %d bytes %s: %s\n", total, - (cmd & NANDRW_READ) ? "read" : "written", - ret ? "ERROR" : "OK"); - - return ret; - } else if (strcmp (argv[1], "erase") == 0 && - (argc == 4 || strcmp ("clean", argv[2]) == 0)) { - int clean = argc == 5; - ulong off = - simple_strtoul (argv[2 + clean], NULL, 16); - ulong size = - simple_strtoul (argv[3 + clean], NULL, 16); - int ret; - - printf ("\nNAND erase: device %d offset %ld, size %ld ...\n", - curr_device, off, size); - - ret = nand_legacy_erase (nand_dev_desc + curr_device, - off, size, clean); - - printf ("%s\n", ret ? "ERROR" : "OK"); - - return ret; - } else { - printf ("Usage:\n%s\n", cmdtp->usage); - rcode = 1; - } - - return rcode; - } -} - -U_BOOT_CMD( - nand, 5, 1, do_nand, - "nand - legacy NAND sub-system\n", - "info - show available NAND devices\n" - "nand device [dev] - show or set current device\n" - "nand read[.jffs2[s]] addr off size\n" - "nand write[.jffs2] addr off size - read/write `size' bytes starting\n" - " at offset `off' to/from memory address `addr'\n" - "nand erase [clean] [off size] - erase `size' bytes from\n" - " offset `off' (entire device if not specified)\n" - "nand bad - show bad blocks\n" - "nand read.oob addr off size - read out-of-band data\n" - "nand write.oob addr off size - read out-of-band data\n" -); - -int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - char *boot_device = NULL; - char *ep; - int dev; - ulong cnt; - ulong addr; - ulong offset = 0; - image_header_t *hdr; - int rcode = 0; - switch (argc) { - case 1: - addr = CFG_LOAD_ADDR; - boot_device = getenv ("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv ("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - case 4: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - offset = simple_strtoul(argv[3], NULL, 16); - break; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - if (!boot_device) { - puts ("\n** No boot device **\n"); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - dev = simple_strtoul(boot_device, &ep, 16); - - if ((dev >= CFG_MAX_NAND_DEVICE) || - (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) { - printf ("\n** Device %d not available\n", dev); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n", - dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR, - offset); - - if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset, - SECTORSIZE, NULL, (u_char *)addr)) { - printf ("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - hdr = (image_header_t *)addr; - - if (ntohl(hdr->ih_magic) == IH_MAGIC) { - - print_image_hdr (hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); - cnt -= SECTORSIZE; - } else { - printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic)); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, - offset + SECTORSIZE, cnt, NULL, - (u_char *)(addr+SECTORSIZE))) { - printf ("** Read error on %d\n", dev); - SHOW_BOOT_PROGRESS (-1); - return 1; - } - - /* Loading ok, update default load address */ - - load_addr = addr; - - /* Check if we should attempt an auto-start */ - if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { - char *local_args[2]; - extern int do_bootm (cmd_tbl_t *, int, int, char *[]); - - local_args[0] = argv[0]; - local_args[1] = NULL; - - printf ("Automatic boot of image at addr 0x%08lx ...\n", addr); - - do_bootm (cmdtp, 0, 1, local_args); - rcode = 1; - } - return rcode; -} - -U_BOOT_CMD( - nboot, 4, 1, do_nandboot, - "nboot - boot from NAND device\n", - "loadAddr dev\n" -); - -#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */ - -#endif /* CFG_NAND_LEGACY */ diff --git a/common/cmd_pci.c b/common/cmd_pci.c deleted file mode 100644 index 45085462fc..0000000000 --- a/common/cmd_pci.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Andreas Heppel <aheppel@sysgo.de> - * - * (C) Copyright 2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * Wolfgang Grandegger, DENX Software Engineering, wg@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * PCI routines - */ - -#include <common.h> - -#ifdef CONFIG_PCI - -#include <command.h> -#include <asm/processor.h> -#include <asm/io.h> -#include <pci.h> - -#if (CONFIG_COMMANDS & CFG_CMD_PCI) - -extern int cmd_get_data_size(char* arg, int default_size); - -unsigned char ShortPCIListing = 1; - -/* - * Follows routines for the output of infos about devices on PCI bus. - */ - -void pci_header_show(pci_dev_t dev); -void pci_header_show_brief(pci_dev_t dev); - -/* - * Subroutine: pciinfo - * - * Description: Show information about devices on PCI bus. - * Depending on the define CFG_SHORT_PCI_LISTING - * the output will be more or less exhaustive. - * - * Inputs: bus_no the number of the bus to be scanned. - * - * Return: None - * - */ -void pciinfo(int BusNum, int ShortPCIListing) -{ - int Device; - int Function; - unsigned char HeaderType; - unsigned short VendorID; - pci_dev_t dev; - - printf("Scanning PCI devices on bus %d\n", BusNum); - - if (ShortPCIListing) { - printf("BusDevFun VendorId DeviceId Device Class Sub-Class\n"); - printf("_____________________________________________________________\n"); - } - - for (Device = 0; Device < PCI_MAX_PCI_DEVICES; Device++) { - HeaderType = 0; - VendorID = 0; - for (Function = 0; Function < PCI_MAX_PCI_FUNCTIONS; Function++) { - /* - * If this is not a multi-function device, we skip the rest. - */ - if (Function && !(HeaderType & 0x80)) - break; - - dev = PCI_BDF(BusNum, Device, Function); - - pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID); - if ((VendorID == 0xFFFF) || (VendorID == 0x0000)) - continue; - - if (!Function) pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType); - - if (ShortPCIListing) - { - printf("%02x.%02x.%02x ", BusNum, Device, Function); - pci_header_show_brief(dev); - } - else - { - printf("\nFound PCI device %02x.%02x.%02x:\n", - BusNum, Device, Function); - pci_header_show(dev); - } - } - } -} - -static char *pci_classes_str(u8 class) -{ - switch (class) { - case PCI_CLASS_NOT_DEFINED: - return "Build before PCI Rev2.0"; - break; - case PCI_BASE_CLASS_STORAGE: - return "Mass storage controller"; - break; - case PCI_BASE_CLASS_NETWORK: - return "Network controller"; - break; - case PCI_BASE_CLASS_DISPLAY: - return "Display controller"; - break; - case PCI_BASE_CLASS_MULTIMEDIA: - return "Multimedia device"; - break; - case PCI_BASE_CLASS_MEMORY: - return "Memory controller"; - break; - case PCI_BASE_CLASS_BRIDGE: - return "Bridge device"; - break; - case PCI_BASE_CLASS_COMMUNICATION: - return "Simple comm. controller"; - break; - case PCI_BASE_CLASS_SYSTEM: - return "Base system peripheral"; - break; - case PCI_BASE_CLASS_INPUT: - return "Input device"; - break; - case PCI_BASE_CLASS_DOCKING: - return "Docking station"; - break; - case PCI_BASE_CLASS_PROCESSOR: - return "Processor"; - break; - case PCI_BASE_CLASS_SERIAL: - return "Serial bus controller"; - break; - case PCI_BASE_CLASS_INTELLIGENT: - return "Intelligent controller"; - break; - case PCI_BASE_CLASS_SATELLITE: - return "Satellite controller"; - break; - case PCI_BASE_CLASS_CRYPT: - return "Cryptographic device"; - break; - case PCI_BASE_CLASS_SIGNAL_PROCESSING: - return "DSP"; - break; - case PCI_CLASS_OTHERS: - return "Does not fit any class"; - break; - default: - return "???"; - break; - }; -} - -/* - * Subroutine: pci_header_show_brief - * - * Description: Reads and prints the header of the - * specified PCI device in short form. - * - * Inputs: dev Bus+Device+Function number - * - * Return: None - * - */ -void pci_header_show_brief(pci_dev_t dev) -{ - u16 vendor, device; - u8 class, subclass; - - pci_read_config_word(dev, PCI_VENDOR_ID, &vendor); - pci_read_config_word(dev, PCI_DEVICE_ID, &device); - pci_read_config_byte(dev, PCI_CLASS_CODE, &class); - pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &subclass); - - printf("0x%.4x 0x%.4x %-23s 0x%.2x\n", - vendor, device, - pci_classes_str(class), subclass); -} - -/* - * Subroutine: PCI_Header_Show - * - * Description: Reads the header of the specified PCI device. - * - * Inputs: BusDevFunc Bus+Device+Function number - * - * Return: None - * - */ -void pci_header_show(pci_dev_t dev) -{ - u8 _byte, header_type; - u16 _word; - u32 _dword; - -#define PRINT(msg, type, reg) \ - pci_read_config_##type(dev, reg, &_##type); \ - printf(msg, _##type) - -#define PRINT2(msg, type, reg, func) \ - pci_read_config_##type(dev, reg, &_##type); \ - printf(msg, _##type, func(_##type)) - - pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); - - PRINT (" vendor ID = 0x%.4x\n", word, PCI_VENDOR_ID); - PRINT (" device ID = 0x%.4x\n", word, PCI_DEVICE_ID); - PRINT (" command register = 0x%.4x\n", word, PCI_COMMAND); - PRINT (" status register = 0x%.4x\n", word, PCI_STATUS); - PRINT (" revision ID = 0x%.2x\n", byte, PCI_REVISION_ID); - PRINT2(" class code = 0x%.2x (%s)\n", byte, PCI_CLASS_CODE, - pci_classes_str); - PRINT (" sub class code = 0x%.2x\n", byte, PCI_CLASS_SUB_CODE); - PRINT (" programming interface = 0x%.2x\n", byte, PCI_CLASS_PROG); - PRINT (" cache line = 0x%.2x\n", byte, PCI_CACHE_LINE_SIZE); - PRINT (" latency time = 0x%.2x\n", byte, PCI_LATENCY_TIMER); - PRINT (" header type = 0x%.2x\n", byte, PCI_HEADER_TYPE); - PRINT (" BIST = 0x%.2x\n", byte, PCI_BIST); - PRINT (" base address 0 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_0); - - switch (header_type & 0x03) { - case PCI_HEADER_TYPE_NORMAL: /* "normal" PCI device */ - PRINT (" base address 1 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_1); - PRINT (" base address 2 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_2); - PRINT (" base address 3 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_3); - PRINT (" base address 4 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_4); - PRINT (" base address 5 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_5); - PRINT (" cardBus CIS pointer = 0x%.8x\n", dword, PCI_CARDBUS_CIS); - PRINT (" sub system vendor ID = 0x%.4x\n", word, PCI_SUBSYSTEM_VENDOR_ID); - PRINT (" sub system ID = 0x%.4x\n", word, PCI_SUBSYSTEM_ID); - PRINT (" expansion ROM base address = 0x%.8x\n", dword, PCI_ROM_ADDRESS); - PRINT (" interrupt line = 0x%.2x\n", byte, PCI_INTERRUPT_LINE); - PRINT (" interrupt pin = 0x%.2x\n", byte, PCI_INTERRUPT_PIN); - PRINT (" min Grant = 0x%.2x\n", byte, PCI_MIN_GNT); - PRINT (" max Latency = 0x%.2x\n", byte, PCI_MAX_LAT); - break; - - case PCI_HEADER_TYPE_BRIDGE: /* PCI-to-PCI bridge */ - - PRINT (" base address 1 = 0x%.8x\n", dword, PCI_BASE_ADDRESS_1); - PRINT (" primary bus number = 0x%.2x\n", byte, PCI_PRIMARY_BUS); - PRINT (" secondary bus number = 0x%.2x\n", byte, PCI_SECONDARY_BUS); - PRINT (" subordinate bus number = 0x%.2x\n", byte, PCI_SUBORDINATE_BUS); - PRINT (" secondary latency timer = 0x%.2x\n", byte, PCI_SEC_LATENCY_TIMER); - PRINT (" IO base = 0x%.2x\n", byte, PCI_IO_BASE); - PRINT (" IO limit = 0x%.2x\n", byte, PCI_IO_LIMIT); - PRINT (" secondary status = 0x%.4x\n", word, PCI_SEC_STATUS); - PRINT (" memory base = 0x%.4x\n", word, PCI_MEMORY_BASE); - PRINT (" memory limit = 0x%.4x\n", word, PCI_MEMORY_LIMIT); - PRINT (" prefetch memory base = 0x%.4x\n", word, PCI_PREF_MEMORY_BASE); - PRINT (" prefetch memory limit = 0x%.4x\n", word, PCI_PREF_MEMORY_LIMIT); - PRINT (" prefetch memory base upper = 0x%.8x\n", dword, PCI_PREF_BASE_UPPER32); - PRINT (" prefetch memory limit upper = 0x%.8x\n", dword, PCI_PREF_LIMIT_UPPER32); - PRINT (" IO base upper 16 bits = 0x%.4x\n", word, PCI_IO_BASE_UPPER16); - PRINT (" IO limit upper 16 bits = 0x%.4x\n", word, PCI_IO_LIMIT_UPPER16); - PRINT (" expansion ROM base address = 0x%.8x\n", dword, PCI_ROM_ADDRESS1); - PRINT (" interrupt line = 0x%.2x\n", byte, PCI_INTERRUPT_LINE); - PRINT (" interrupt pin = 0x%.2x\n", byte, PCI_INTERRUPT_PIN); - PRINT (" bridge control = 0x%.4x\n", word, PCI_BRIDGE_CONTROL); - break; - - case PCI_HEADER_TYPE_CARDBUS: /* PCI-to-CardBus bridge */ - - PRINT (" capabilities = 0x%.2x\n", byte, PCI_CB_CAPABILITY_LIST); - PRINT (" secondary status = 0x%.4x\n", word, PCI_CB_SEC_STATUS); - PRINT (" primary bus number = 0x%.2x\n", byte, PCI_CB_PRIMARY_BUS); - PRINT (" CardBus number = 0x%.2x\n", byte, PCI_CB_CARD_BUS); - PRINT (" subordinate bus number = 0x%.2x\n", byte, PCI_CB_SUBORDINATE_BUS); - PRINT (" CardBus latency timer = 0x%.2x\n", byte, PCI_CB_LATENCY_TIMER); - PRINT (" CardBus memory base 0 = 0x%.8x\n", dword, PCI_CB_MEMORY_BASE_0); - PRINT (" CardBus memory limit 0 = 0x%.8x\n", dword, PCI_CB_MEMORY_LIMIT_0); - PRINT (" CardBus memory base 1 = 0x%.8x\n", dword, PCI_CB_MEMORY_BASE_1); - PRINT (" CardBus memory limit 1 = 0x%.8x\n", dword, PCI_CB_MEMORY_LIMIT_1); - PRINT (" CardBus IO base 0 = 0x%.4x\n", word, PCI_CB_IO_BASE_0); - PRINT (" CardBus IO base high 0 = 0x%.4x\n", word, PCI_CB_IO_BASE_0_HI); - PRINT (" CardBus IO limit 0 = 0x%.4x\n", word, PCI_CB_IO_LIMIT_0); - PRINT (" CardBus IO limit high 0 = 0x%.4x\n", word, PCI_CB_IO_LIMIT_0_HI); - PRINT (" CardBus IO base 1 = 0x%.4x\n", word, PCI_CB_IO_BASE_1); - PRINT (" CardBus IO base high 1 = 0x%.4x\n", word, PCI_CB_IO_BASE_1_HI); - PRINT (" CardBus IO limit 1 = 0x%.4x\n", word, PCI_CB_IO_LIMIT_1); - PRINT (" CardBus IO limit high 1 = 0x%.4x\n", word, PCI_CB_IO_LIMIT_1_HI); - PRINT (" interrupt line = 0x%.2x\n", byte, PCI_INTERRUPT_LINE); - PRINT (" interrupt pin = 0x%.2x\n", byte, PCI_INTERRUPT_PIN); - PRINT (" bridge control = 0x%.4x\n", word, PCI_CB_BRIDGE_CONTROL); - PRINT (" subvendor ID = 0x%.4x\n", word, PCI_CB_SUBSYSTEM_VENDOR_ID); - PRINT (" subdevice ID = 0x%.4x\n", word, PCI_CB_SUBSYSTEM_ID); - PRINT (" PC Card 16bit base address = 0x%.8x\n", dword, PCI_CB_LEGACY_MODE_BASE); - break; - - default: - printf("unknown header\n"); - break; - } - -#undef PRINT -#undef PRINT2 -} - -/* Convert the "bus.device.function" identifier into a number. - */ -static pci_dev_t get_pci_dev(char* name) -{ - char cnum[12]; - int len, i, iold, n; - int bdfs[3] = {0,0,0}; - - len = strlen(name); - if (len > 8) - return -1; - for (i = 0, iold = 0, n = 0; i < len; i++) { - if (name[i] == '.') { - memcpy(cnum, &name[iold], i - iold); - cnum[i - iold] = '\0'; - bdfs[n++] = simple_strtoul(cnum, NULL, 16); - iold = i + 1; - } - } - strcpy(cnum, &name[iold]); - if (n == 0) - n = 1; - bdfs[n] = simple_strtoul(cnum, NULL, 16); - return PCI_BDF(bdfs[0], bdfs[1], bdfs[2]); -} - -static int pci_cfg_display(pci_dev_t bdf, ulong addr, ulong size, ulong length) -{ -#define DISP_LINE_LEN 16 - ulong i, nbytes, linebytes; - int rc = 0; - - if (length == 0) - length = 0x40 / size; /* Standard PCI configuration space */ - - /* Print the lines. - * once, and all accesses are with the specified bus width. - */ - nbytes = length * size; - do { - uint val4; - ushort val2; - u_char val1; - - printf("%08lx:", addr); - linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes; - for (i=0; i<linebytes; i+= size) { - if (size == 4) { - pci_read_config_dword(bdf, addr, &val4); - printf(" %08x", val4); - } else if (size == 2) { - pci_read_config_word(bdf, addr, &val2); - printf(" %04x", val2); - } else { - pci_read_config_byte(bdf, addr, &val1); - printf(" %02x", val1); - } - addr += size; - } - printf("\n"); - nbytes -= linebytes; - if (ctrlc()) { - rc = 1; - break; - } - } while (nbytes > 0); - - return (rc); -} - -static int pci_cfg_write (pci_dev_t bdf, ulong addr, ulong size, ulong value) -{ - if (size == 4) { - pci_write_config_dword(bdf, addr, value); - } - else if (size == 2) { - ushort val = value & 0xffff; - pci_write_config_word(bdf, addr, val); - } - else { - u_char val = value & 0xff; - pci_write_config_byte(bdf, addr, val); - } - return 0; -} - -static int -pci_cfg_modify (pci_dev_t bdf, ulong addr, ulong size, ulong value, int incrflag) -{ - ulong i; - int nbytes; - extern char console_buffer[]; - uint val4; - ushort val2; - u_char val1; - - /* Print the address, followed by value. Then accept input for - * the next value. A non-converted value exits. - */ - do { - printf("%08lx:", addr); - if (size == 4) { - pci_read_config_dword(bdf, addr, &val4); - printf(" %08x", val4); - } - else if (size == 2) { - pci_read_config_word(bdf, addr, &val2); - printf(" %04x", val2); - } - else { - pci_read_config_byte(bdf, addr, &val1); - printf(" %02x", val1); - } - - nbytes = readline (" ? "); - if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) { - /* <CR> pressed as only input, don't modify current - * location and move to next. "-" pressed will go back. - */ - if (incrflag) - addr += nbytes ? -size : size; - nbytes = 1; -#ifdef CONFIG_BOOT_RETRY_TIME - reset_cmd_timeout(); /* good enough to not time out */ -#endif - } -#ifdef CONFIG_BOOT_RETRY_TIME - else if (nbytes == -2) { - break; /* timed out, exit the command */ - } -#endif - else { - char *endp; - i = simple_strtoul(console_buffer, &endp, 16); - nbytes = endp - console_buffer; - if (nbytes) { -#ifdef CONFIG_BOOT_RETRY_TIME - /* good enough to not time out - */ - reset_cmd_timeout(); -#endif - pci_cfg_write (bdf, addr, size, i); - if (incrflag) - addr += size; - } - } - } while (nbytes); - - return 0; -} - -/* PCI Configuration Space access commands - * - * Syntax: - * pci display[.b, .w, .l] bus.device.function} [addr] [len] - * pci next[.b, .w, .l] bus.device.function [addr] - * pci modify[.b, .w, .l] bus.device.function [addr] - * pci write[.b, .w, .l] bus.device.function addr value - */ -int do_pci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - ulong addr = 0, value = 0, size = 0; - pci_dev_t bdf = 0; - char cmd = 's'; - - if (argc > 1) - cmd = argv[1][0]; - - switch (cmd) { - case 'd': /* display */ - case 'n': /* next */ - case 'm': /* modify */ - case 'w': /* write */ - /* Check for a size specification. */ - size = cmd_get_data_size(argv[1], 4); - if (argc > 3) - addr = simple_strtoul(argv[3], NULL, 16); - if (argc > 4) - value = simple_strtoul(argv[4], NULL, 16); - case 'h': /* header */ - if (argc < 3) - goto usage; - if ((bdf = get_pci_dev(argv[2])) == -1) - return 1; - break; - default: /* scan bus */ - value = 1; /* short listing */ - bdf = 0; /* bus number */ - if (argc > 1) { - if (argv[argc-1][0] == 'l') { - value = 0; - argc--; - } - if (argc > 1) - bdf = simple_strtoul(argv[1], NULL, 16); - } - pciinfo(bdf, value); - return 0; - } - - switch (argv[1][0]) { - case 'h': /* header */ - pci_header_show(bdf); - return 0; - case 'd': /* display */ - return pci_cfg_display(bdf, addr, size, value); - case 'n': /* next */ - if (argc < 4) - goto usage; - return pci_cfg_modify(bdf, addr, size, value, 0); - case 'm': /* modify */ - if (argc < 4) - goto usage; - return pci_cfg_modify(bdf, addr, size, value, 1); - case 'w': /* write */ - if (argc < 5) - goto usage; - return pci_cfg_write(bdf, addr, size, value); - } - - return 1; - usage: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; -} - -/***************************************************/ - - -U_BOOT_CMD( - pci, 5, 1, do_pci, - "pci - list and access PCI Configuration Space\n", - "[bus] [long]\n" - " - short or long list of PCI devices on bus 'bus'\n" - "pci header b.d.f\n" - " - show header of PCI device 'bus.device.function'\n" - "pci display[.b, .w, .l] b.d.f [address] [# of objects]\n" - " - display PCI configuration space (CFG)\n" - "pci next[.b, .w, .l] b.d.f address\n" - " - modify, read and keep CFG address\n" - "pci modify[.b, .w, .l] b.d.f address\n" - " - modify, auto increment CFG address\n" - "pci write[.b, .w, .l] b.d.f address value\n" - " - write to CFG address\n" -); - -#endif /* (CONFIG_COMMANDS & CFG_CMD_PCI) */ - -#endif /* CONFIG_PCI */ diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c deleted file mode 100644 index 97df7a2cd5..0000000000 --- a/common/cmd_pcmcia.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * (C) Copyright 2000-2006 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ******************************************************************** - * - * Lots of code copied from: - * - * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series. - * (C) 1999-2000 Magnus Damm <damm@bitsmart.com> - * - * "The ExCA standard specifies that socket controllers should provide - * two IO and five memory windows per socket, which can be independently - * configured and positioned in the host address space and mapped to - * arbitrary segments of card address space. " - David A Hinds. 1999 - * - * This controller does _not_ meet the ExCA standard. - * - * m8xx pcmcia controller brief info: - * + 8 windows (attrib, mem, i/o) - * + up to two slots (SLOT_A and SLOT_B) - * + inputpins, outputpins, event and mask registers. - * - no offset register. sigh. - * - * Because of the lacking offset register we must map the whole card. - * We assign each memory window PCMCIA_MEM_WIN_SIZE address space. - * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO - * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE. - * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE. - * They are maximum 64KByte each... - */ - -/* #define DEBUG 1 */ - -/* - * PCMCIA support - */ -#include <common.h> -#include <command.h> -#include <config.h> -#include <pcmcia.h> -#include <asm/io.h> - -/* -------------------------------------------------------------------- */ - -#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) - -extern int pcmcia_on (void); -extern int pcmcia_off (void); - -int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int rcode = 0; - - if (argc != 2) { - printf ("Usage: pinit {on | off}\n"); - return 1; - } - if (strcmp(argv[1],"on") == 0) { - rcode = pcmcia_on (); - } else if (strcmp(argv[1],"off") == 0) { - rcode = pcmcia_off (); - } else { - printf ("Usage: pinit {on | off}\n"); - return 1; - } - - return rcode; -} - -U_BOOT_CMD( - pinit, 2, 1, do_pinit, - "pinit - PCMCIA sub-system\n", - "on - power on PCMCIA socket\n" - "pinit off - power off PCMCIA socket\n" - ); - -#endif /* CONFIG_COMMANDS & CFG_CMD_PCMCIA */ - -/* -------------------------------------------------------------------- */ - -#undef CHECK_IDE_DEVICE - -#if (CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) -#define CHECK_IDE_DEVICE -#endif - -#if defined(CONFIG_PXA_PCMCIA) -#define CHECK_IDE_DEVICE -#endif - -#ifdef CHECK_IDE_DEVICE - -int ide_devices_found; -static uchar *known_cards[] = { - (uchar *)"ARGOSY PnPIDE D5", - NULL -}; - -#define MAX_TUPEL_SZ 512 -#define MAX_FEATURES 4 - -#define MAX_IDENT_CHARS 64 -#define MAX_IDENT_FIELDS 4 - -#define indent "\t " - -static void print_funcid (int func) -{ - puts (indent); - switch (func) { - case CISTPL_FUNCID_MULTI: - puts (" Multi-Function"); - break; - case CISTPL_FUNCID_MEMORY: - puts (" Memory"); - break; - case CISTPL_FUNCID_SERIAL: - puts (" Serial Port"); - break; - case CISTPL_FUNCID_PARALLEL: - puts (" Parallel Port"); - break; - case CISTPL_FUNCID_FIXED: - puts (" Fixed Disk"); - break; - case CISTPL_FUNCID_VIDEO: - puts (" Video Adapter"); - break; - case CISTPL_FUNCID_NETWORK: - puts (" Network Adapter"); - break; - case CISTPL_FUNCID_AIMS: - puts (" AIMS Card"); - break; - case CISTPL_FUNCID_SCSI: - puts (" SCSI Adapter"); - break; - default: - puts (" Unknown"); - break; - } - puts (" Card\n"); -} - -static void print_fixed (volatile uchar *p) -{ - if (p == NULL) - return; - - puts(indent); - - switch (*p) { - case CISTPL_FUNCE_IDE_IFACE: - { uchar iface = *(p+2); - - puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown"); - puts (" interface "); - break; - } - case CISTPL_FUNCE_IDE_MASTER: - case CISTPL_FUNCE_IDE_SLAVE: - { uchar f1 = *(p+2); - uchar f2 = *(p+4); - - puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]"); - - if (f1 & CISTPL_IDE_UNIQUE) - puts (" [unique]"); - - puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]"); - - if (f2 & CISTPL_IDE_HAS_SLEEP) - puts (" [sleep]"); - - if (f2 & CISTPL_IDE_HAS_STANDBY) - puts (" [standby]"); - - if (f2 & CISTPL_IDE_HAS_IDLE) - puts (" [idle]"); - - if (f2 & CISTPL_IDE_LOW_POWER) - puts (" [low power]"); - - if (f2 & CISTPL_IDE_REG_INHIBIT) - puts (" [reg inhibit]"); - - if (f2 & CISTPL_IDE_HAS_INDEX) - puts (" [index]"); - - if (f2 & CISTPL_IDE_IOIS16) - puts (" [IOis16]"); - - break; - } - } - putc ('\n'); -} - -static int identify (volatile uchar *p) -{ - uchar id_str[MAX_IDENT_CHARS]; - uchar data; - uchar *t; - uchar **card; - int i, done; - - if (p == NULL) - return (0); /* Don't know */ - - t = id_str; - done =0; - - for (i=0; i<=4 && !done; ++i, p+=2) { - while ((data = *p) != '\0') { - if (data == 0xFF) { - done = 1; - break; - } - *t++ = data; - if (t == &id_str[MAX_IDENT_CHARS-1]) { - done = 1; - break; - } - p += 2; - } - if (!done) - *t++ = ' '; - } - *t = '\0'; - while (--t > id_str) { - if (*t == ' ') - *t = '\0'; - else - break; - } - puts ((char *)id_str); - putc ('\n'); - - for (card=known_cards; *card; ++card) { - debug ("## Compare against \"%s\"\n", *card); - if (strcmp((char *)*card, (char *)id_str) == 0) { /* found! */ - debug ("## CARD FOUND ##\n"); - return (1); - } - } - - return (0); /* don't know */ -} - -int check_ide_device (int slot) -{ - volatile uchar *ident = NULL; - volatile uchar *feature_p[MAX_FEATURES]; - volatile uchar *p, *start, *addr; - int n_features = 0; - uchar func_id = ~0; - uchar code, len; - ushort config_base = 0; - int found = 0; - int i; - - addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR + - CFG_PCMCIA_MEM_SIZE * (slot * 4)); - debug ("PCMCIA MEM: %08lX\n", (ulong)addr); - - start = p = (volatile uchar *) addr; - - while ((p - start) < MAX_TUPEL_SZ) { - - code = *p; p += 2; - - if (code == 0xFF) { /* End of chain */ - break; - } - - len = *p; p += 2; -#if defined(DEBUG) && (DEBUG > 1) - { volatile uchar *q = p; - printf ("\nTuple code %02x length %d\n\tData:", - code, len); - - for (i = 0; i < len; ++i) { - printf (" %02x", *q); - q+= 2; - } - } -#endif /* DEBUG */ - switch (code) { - case CISTPL_VERS_1: - ident = p + 4; - break; - case CISTPL_FUNCID: - /* Fix for broken SanDisk which may have 0x80 bit set */ - func_id = *p & 0x7F; - break; - case CISTPL_FUNCE: - if (n_features < MAX_FEATURES) - feature_p[n_features++] = p; - break; - case CISTPL_CONFIG: - config_base = (*(p+6) << 8) + (*(p+4)); - debug ("\n## Config_base = %04x ###\n", config_base); - default: - break; - } - p += 2 * len; - } - - found = identify (ident); - - if (func_id != ((uchar)~0)) { - print_funcid (func_id); - - if (func_id == CISTPL_FUNCID_FIXED) - found = 1; - else - return (1); /* no disk drive */ - } - - for (i=0; i<n_features; ++i) { - print_fixed (feature_p[i]); - } - - if (!found) { - printf ("unknown card type\n"); - return (1); - } - - ide_devices_found |= (1 << slot); - -#if CONFIG_CPC45 -#else - /* set I/O area in config reg -> only valid for ARGOSY D5!!! */ - *((uchar *)(addr + config_base)) = 1; -#endif - return (0); -} - -#endif /* CHECK_IDE_DEVICE */ diff --git a/common/cmd_portio.c b/common/cmd_portio.c deleted file mode 100644 index 206a3f9a67..0000000000 --- a/common/cmd_portio.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * (C) Copyright 2003 - * Marc Singer, elf@buici.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * Port I/O Functions - * - * Copied from FADS ROM, Dan Malek (dmalek@jlc.net) - */ - -#include <common.h> -#include <command.h> - -#if (CONFIG_COMMANDS & CFG_CMD_PORTIO) - -/* Display values from last command. - * Memory modify remembered values are different from display memory. - */ -static uint in_last_addr, in_last_size; -static uint out_last_addr, out_last_size, out_last_value; - - -int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - uint addr = out_last_addr; - uint size = out_last_size; - uint value = out_last_value; - - if (argc != 3) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - if ((flag & CMD_FLAG_REPEAT) == 0) { - /* New command specified. Check for a size specification. - * Defaults to long if no or incorrect specification. - */ - size = cmd_get_data_size (argv[0], 1); - addr = simple_strtoul (argv[1], NULL, 16); - value = simple_strtoul (argv[2], NULL, 16); - } -#if defined (CONFIG_X86) - - { - unsigned short port = addr; - - switch (size) { - default: - case 1: - { - unsigned char ch = value; - __asm__ volatile ("out %0, %%dx"::"a" (ch), "d" (port)); - } - break; - case 2: - { - unsigned short w = value; - __asm__ volatile ("out %0, %%dx"::"a" (w), "d" (port)); - } - break; - case 4: - __asm__ volatile ("out %0, %%dx"::"a" (value), "d" (port)); - - break; - } - } - -#endif /* CONFIG_X86 */ - - out_last_addr = addr; - out_last_size = size; - out_last_value = value; - - return 0; -} - -U_BOOT_CMD( - out, 3, 1, do_portio_out, - "out - write datum to IO port\n", - "[.b, .w, .l] port value\n - output to IO port\n" -); - -int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - uint addr = in_last_addr; - uint size = in_last_size; - - if (argc != 2) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - if ((flag & CMD_FLAG_REPEAT) == 0) { - /* New command specified. Check for a size specification. - * Defaults to long if no or incorrect specification. - */ - size = cmd_get_data_size (argv[0], 1); - addr = simple_strtoul (argv[1], NULL, 16); - } -#if defined (CONFIG_X86) - - { - unsigned short port = addr; - - switch (size) { - default: - case 1: - { - unsigned char ch; - __asm__ volatile ("in %%dx, %0":"=a" (ch):"d" (port)); - - printf (" %02x\n", ch); - } - break; - case 2: - { - unsigned short w; - __asm__ volatile ("in %%dx, %0":"=a" (w):"d" (port)); - - printf (" %04x\n", w); - } - break; - case 4: - { - unsigned long l; - __asm__ volatile ("in %%dx, %0":"=a" (l):"d" (port)); - - printf (" %08lx\n", l); - } - break; - } - } -#endif /* CONFIG_X86 */ - - in_last_addr = addr; - in_last_size = size; - - return 0; -} - -U_BOOT_CMD( - in, 2, 1, do_portio_in, - "in - read data from an IO port\n", - "[.b, .w, .l] port\n" - " - read datum from IO port\n" -); - -#endif /* CFG_CMD_PORTIO */ diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c deleted file mode 100644 index eab4d50ab0..0000000000 --- a/common/cmd_scsi.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * (C) Copyright 2001 - * Denis Peter, MPL AG Switzerland - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * - * - */ - -/* - * SCSI support. - */ -#include <common.h> -#include <command.h> -#include <asm/processor.h> -#include <scsi.h> -#include <image.h> -#include <pci.h> - -#if (CONFIG_COMMANDS & CFG_CMD_SCSI) - -#ifdef CONFIG_SCSI_SYM53C8XX -#define SCSI_VEND_ID 0x1000 -#ifndef CONFIG_SCSI_DEV_ID -#define SCSI_DEV_ID 0x0001 -#else -#define SCSI_DEV_ID CONFIG_SCSI_DEV_ID -#endif -#elif defined CONFIG_SATA_ULI5288 - -#define SCSI_VEND_ID 0x10b9 -#define SCSI_DEV_ID 0x5288 - -#else -#error no scsi device defined -#endif - - -static ccb tempccb; /* temporary scsi command buffer */ - -static unsigned char tempbuff[512]; /* temporary data buffer */ - -static int scsi_max_devs; /* number of highest available scsi device */ - -static int scsi_curr_dev; /* current device */ - -static block_dev_desc_t scsi_dev_desc[CFG_SCSI_MAX_DEVICE]; - -/******************************************************************************** - * forward declerations of some Setup Routines - */ -void scsi_setup_test_unit_ready(ccb * pccb); -void scsi_setup_read_capacity(ccb * pccb); -void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks); -void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks); -void scsi_setup_inquiry(ccb * pccb); -void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); - - -ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer); - - -/********************************************************************************* - * (re)-scan the scsi bus and reports scsi device info - * to the user if mode = 1 - */ -void scsi_scan(int mode) -{ - unsigned char i,perq,modi,lun; - unsigned long capacity,blksz; - ccb* pccb=(ccb *)&tempccb; - - if(mode==1) { - printf("scanning bus for devices...\n"); - } - for(i=0;i<CFG_SCSI_MAX_DEVICE;i++) { - scsi_dev_desc[i].target=0xff; - scsi_dev_desc[i].lun=0xff; - scsi_dev_desc[i].lba=0; - scsi_dev_desc[i].blksz=0; - scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN; - scsi_dev_desc[i].vendor[0]=0; - scsi_dev_desc[i].product[0]=0; - scsi_dev_desc[i].revision[0]=0; - scsi_dev_desc[i].removable=FALSE; - scsi_dev_desc[i].if_type=IF_TYPE_SCSI; - scsi_dev_desc[i].dev=i; - scsi_dev_desc[i].part_type=PART_TYPE_UNKNOWN; - scsi_dev_desc[i].block_read=scsi_read; - } - scsi_max_devs=0; - for(i=0;i<CFG_SCSI_MAX_SCSI_ID;i++) { - pccb->target=i; - for(lun=0;lun<CFG_SCSI_MAX_LUN;lun++) { - pccb->lun=lun; - pccb->pdata=(unsigned char *)&tempbuff; - pccb->datalen=512; - scsi_setup_inquiry(pccb); - if(scsi_exec(pccb)!=TRUE) { - if(pccb->contr_stat==SCSI_SEL_TIME_OUT) { - debug ("Selection timeout ID %d\n",pccb->target); - continue; /* selection timeout => assuming no device present */ - } - scsi_print_error(pccb); - continue; - } - perq=tempbuff[0]; - modi=tempbuff[1]; - if((perq & 0x1f)==0x1f) { - continue; /* skip unknown devices */ - } - if((modi&0x80)==0x80) /* drive is removable */ - scsi_dev_desc[scsi_max_devs].removable=TRUE; - /* get info for this device */ - scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].vendor[0],&tempbuff[8],8); - scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].product[0],&tempbuff[16],16); - scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].revision[0],&tempbuff[32],4); - scsi_dev_desc[scsi_max_devs].target=pccb->target; - scsi_dev_desc[scsi_max_devs].lun=pccb->lun; - - pccb->datalen=0; - scsi_setup_test_unit_ready(pccb); - if(scsi_exec(pccb)!=TRUE) { - if(scsi_dev_desc[scsi_max_devs].removable==TRUE) { - scsi_dev_desc[scsi_max_devs].type=perq; - goto removable; - } - scsi_print_error(pccb); - continue; - } - pccb->datalen=8; - scsi_setup_read_capacity(pccb); - if(scsi_exec(pccb)!=TRUE) { - scsi_print_error(pccb); - continue; - } - capacity=((unsigned long)tempbuff[0]<<24)|((unsigned long)tempbuff[1]<<16)| - ((unsigned long)tempbuff[2]<<8)|((unsigned long)tempbuff[3]); - blksz=((unsigned long)tempbuff[4]<<24)|((unsigned long)tempbuff[5]<<16)| - ((unsigned long)tempbuff[6]<<8)|((unsigned long)tempbuff[7]); - scsi_dev_desc[scsi_max_devs].lba=capacity; - scsi_dev_desc[scsi_max_devs].blksz=blksz; - scsi_dev_desc[scsi_max_devs].type=perq; - init_part(&scsi_dev_desc[scsi_max_devs]); -removable: - if(mode==1) { - printf (" Device %d: ", scsi_max_devs); - dev_print(&scsi_dev_desc[scsi_max_devs]); - } /* if mode */ - scsi_max_devs++; - } /* next LUN */ - } - if(scsi_max_devs>0) - scsi_curr_dev=0; - else - scsi_curr_dev=-1; -} - - -void scsi_init(void) -{ - int busdevfunc; - - busdevfunc=pci_find_device(SCSI_VEND_ID,SCSI_DEV_ID,0); /* get PCI Device ID */ - if(busdevfunc==-1) { - printf("Error SCSI Controller (%04X,%04X) not found\n",SCSI_VEND_ID,SCSI_DEV_ID); - return; - } -#ifdef DEBUG - else { - printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",SCSI_VEND_ID,SCSI_DEV_ID,(busdevfunc>>16)&0xFF,(busdevfunc>>11)&0x1F,(busdevfunc>>8)&0x7); - } -#endif - scsi_low_level_init(busdevfunc); - scsi_scan(1); -} - -block_dev_desc_t * scsi_get_dev(int dev) -{ - return((block_dev_desc_t *)&scsi_dev_desc[dev]); -} - - -/****************************************************************************** - * scsi boot command intepreter. Derived from diskboot - */ -int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - char *boot_device = NULL; - char *ep; - int dev, part = 0; - ulong addr, cnt, checksum; - disk_partition_t info; - image_header_t *hdr; - int rcode = 0; - - switch (argc) { - case 1: - addr = CFG_LOAD_ADDR; - boot_device = getenv ("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv ("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - if (!boot_device) { - puts ("\n** No boot device **\n"); - return 1; - } - - dev = simple_strtoul(boot_device, &ep, 16); - printf("booting from dev %d\n",dev); - if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - printf ("\n** Device %d not available\n", dev); - return 1; - } - - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - if (get_partition_info (scsi_dev_desc, part, &info)) { - printf("error reading partinfo\n"); - return 1; - } - if ((strncmp((char *)(info.type), BOOT_PART_TYPE, sizeof(info.type)) != 0) && - (strncmp((char *)(info.type), BOOT_PART_COMP, sizeof(info.type)) != 0)) { - printf ("\n** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - - printf ("\nLoading from SCSI device %d, partition %d: " - "Name: %.32s Type: %.32s\n", - dev, part, info.name, info.type); - - debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", - info.start, info.size, info.blksz); - - if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) { - printf ("** Read error on %d:%d\n", dev, part); - return 1; - } - - hdr = (image_header_t *)addr; - - if (ntohl(hdr->ih_magic) == IH_MAGIC) { - printf("\n** Bad Magic Number **\n"); - return 1; - } - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { - puts ("\n** Bad Header Checksum **\n"); - return 1; - } - hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */ - - print_image_hdr (hdr); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; - - if (scsi_read (dev, info.start+1, cnt, - (ulong *)(addr+info.blksz)) != cnt) { - printf ("** Read error on %d:%d\n", dev, part); - return 1; - } - /* Loading ok, update default load address */ - load_addr = addr; - - flush_cache (addr, (cnt+1)*info.blksz); - - return rcode; -} - -/********************************************************************************* - * scsi command intepreter - */ -int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - switch (argc) { - case 0: - case 1: printf ("Usage:\n%s\n", cmdtp->usage); return 1; - case 2: - if (strncmp(argv[1],"res",3) == 0) { - printf("\nReset SCSI\n"); - scsi_bus_reset(); - scsi_scan(1); - return 0; - } - if (strncmp(argv[1],"inf",3) == 0) { - int i; - for (i=0; i<CFG_SCSI_MAX_DEVICE; ++i) { - if(scsi_dev_desc[i].type==DEV_TYPE_UNKNOWN) - continue; /* list only known devices */ - printf ("SCSI dev. %d: ", i); - dev_print(&scsi_dev_desc[i]); - } - return 0; - } - if (strncmp(argv[1],"dev",3) == 0) { - if ((scsi_curr_dev < 0) || (scsi_curr_dev >= CFG_SCSI_MAX_DEVICE)) { - printf("\nno SCSI devices available\n"); - return 1; - } - printf ("\n Device %d: ", scsi_curr_dev); - dev_print(&scsi_dev_desc[scsi_curr_dev]); - return 0; - } - if (strncmp(argv[1],"scan",4) == 0) { - scsi_scan(1); - return 0; - } - if (strncmp(argv[1],"part",4) == 0) { - int dev, ok; - for (ok=0, dev=0; dev<CFG_SCSI_MAX_DEVICE; ++dev) { - if (scsi_dev_desc[dev].type!=DEV_TYPE_UNKNOWN) { - ok++; - if (dev) - printf("\n"); - debug ("print_part of %x\n",dev); - print_part(&scsi_dev_desc[dev]); - } - } - if (!ok) - printf("\nno SCSI devices available\n"); - return 1; - } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 3: - if (strncmp(argv[1],"dev",3) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - printf ("\nSCSI device %d: ", dev); - if (dev >= CFG_SCSI_MAX_DEVICE) { - printf("unknown device\n"); - return 1; - } - printf ("\n Device %d: ", dev); - dev_print(&scsi_dev_desc[dev]); - if(scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - return 1; - } - scsi_curr_dev = dev; - printf("... is now current device\n"); - return 0; - } - if (strncmp(argv[1],"part",4) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - if(scsi_dev_desc[dev].type != DEV_TYPE_UNKNOWN) { - print_part(&scsi_dev_desc[dev]); - } - else { - printf ("\nSCSI device %d not available\n", dev); - } - return 1; - } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - default: - /* at least 4 args */ - if (strcmp(argv[1],"read") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong blk = simple_strtoul(argv[3], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - printf ("\nSCSI read: device %d block # %ld, count %ld ... ", - scsi_curr_dev, blk, cnt); - n = scsi_read(scsi_curr_dev, blk, cnt, (ulong *)addr); - printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR"); - return 0; - } - } /* switch */ - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; -} - -/**************************************************************************************** - * scsi_read - */ - -#define SCSI_MAX_READ_BLK 0xFFFF /* almost the maximum amount of the scsi_ext command.. */ - -ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer) -{ - ulong start,blks, buf_addr; - unsigned short smallblks; - ccb* pccb=(ccb *)&tempccb; - device&=0xff; - /* Setup device - */ - pccb->target=scsi_dev_desc[device].target; - pccb->lun=scsi_dev_desc[device].lun; - buf_addr=(unsigned long)buffer; - start=blknr; - blks=blkcnt; - debug ("\nscsi_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks,(unsigned long)buffer); - do { - pccb->pdata=(unsigned char *)buf_addr; - if(blks>SCSI_MAX_READ_BLK) { - pccb->datalen=scsi_dev_desc[device].blksz * SCSI_MAX_READ_BLK; - smallblks=SCSI_MAX_READ_BLK; - scsi_setup_read_ext(pccb,start,smallblks); - start+=SCSI_MAX_READ_BLK; - blks-=SCSI_MAX_READ_BLK; - } - else { - pccb->datalen=scsi_dev_desc[device].blksz * blks; - smallblks=(unsigned short) blks; - scsi_setup_read_ext(pccb,start,smallblks); - start+=blks; - blks=0; - } - debug ("scsi_read_ext: startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr); - if(scsi_exec(pccb)!=TRUE) { - scsi_print_error(pccb); - blkcnt-=blks; - break; - } - buf_addr+=pccb->datalen; - } while(blks!=0); - debug ("scsi_read_ext: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr); - return(blkcnt); -} - -/* copy src to dest, skipping leading and trailing blanks - * and null terminate the string - */ -void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len) -{ - int start,end; - - start=0; - while(start<len) { - if(src[start]!=' ') - break; - start++; - } - end=len-1; - while(end>start) { - if(src[end]!=' ') - break; - end--; - } - for( ; start<=end; start++) { - *dest++=src[start]; - } - *dest='\0'; -} - - -/* Trim trailing blanks, and NUL-terminate string - */ -void scsi_trim_trail (unsigned char *str, unsigned int len) -{ - unsigned char *p = str + len - 1; - - while (len-- > 0) { - *p-- = '\0'; - if (*p != ' ') { - return; - } - } -} - - -/************************************************************************************ - * Some setup (fill-in) routines - */ -void scsi_setup_test_unit_ready(ccb * pccb) -{ - pccb->cmd[0]=SCSI_TST_U_RDY; - pccb->cmd[1]=pccb->lun<<5; - pccb->cmd[2]=0; - pccb->cmd[3]=0; - pccb->cmd[4]=0; - pccb->cmd[5]=0; - pccb->cmdlen=6; - pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ -} - -void scsi_setup_read_capacity(ccb * pccb) -{ - pccb->cmd[0]=SCSI_RD_CAPAC; - pccb->cmd[1]=pccb->lun<<5; - pccb->cmd[2]=0; - pccb->cmd[3]=0; - pccb->cmd[4]=0; - pccb->cmd[5]=0; - pccb->cmd[6]=0; - pccb->cmd[7]=0; - pccb->cmd[8]=0; - pccb->cmd[9]=0; - pccb->cmdlen=10; - pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ - -} - -void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks) -{ - pccb->cmd[0]=SCSI_READ10; - pccb->cmd[1]=pccb->lun<<5; - pccb->cmd[2]=((unsigned char) (start>>24))&0xff; - pccb->cmd[3]=((unsigned char) (start>>16))&0xff; - pccb->cmd[4]=((unsigned char) (start>>8))&0xff; - pccb->cmd[5]=((unsigned char) (start))&0xff; - pccb->cmd[6]=0; - pccb->cmd[7]=((unsigned char) (blocks>>8))&0xff; - pccb->cmd[8]=(unsigned char) blocks & 0xff; - pccb->cmd[6]=0; - pccb->cmdlen=10; - pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ - debug ("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n", - pccb->cmd[0],pccb->cmd[1], - pccb->cmd[2],pccb->cmd[3],pccb->cmd[4],pccb->cmd[5], - pccb->cmd[7],pccb->cmd[8]); -} - -void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks) -{ - pccb->cmd[0]=SCSI_READ6; - pccb->cmd[1]=pccb->lun<<5 | (((unsigned char)(start>>16))&0x1f); - pccb->cmd[2]=((unsigned char) (start>>8))&0xff; - pccb->cmd[3]=((unsigned char) (start))&0xff; - pccb->cmd[4]=(unsigned char) blocks & 0xff; - pccb->cmd[5]=0; - pccb->cmdlen=6; - pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ - debug ("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n", - pccb->cmd[0],pccb->cmd[1], - pccb->cmd[2],pccb->cmd[3],pccb->cmd[4]); -} - - -void scsi_setup_inquiry(ccb * pccb) -{ - pccb->cmd[0]=SCSI_INQUIRY; - pccb->cmd[1]=pccb->lun<<5; - pccb->cmd[2]=0; - pccb->cmd[3]=0; - if(pccb->datalen>255) - pccb->cmd[4]=255; - else - pccb->cmd[4]=(unsigned char)pccb->datalen; - pccb->cmd[5]=0; - pccb->cmdlen=6; - pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ -} - - -U_BOOT_CMD( - scsi, 5, 1, do_scsi, - "scsi - SCSI sub-system\n", - "reset - reset SCSI controller\n" - "scsi info - show available SCSI devices\n" - "scsi scan - (re-)scan SCSI bus\n" - "scsi device [dev] - show or set current device\n" - "scsi part [dev] - print partition table of one or all SCSI devices\n" - "scsi read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" - " to memory address `addr'\n" -); - -U_BOOT_CMD( - scsiboot, 3, 1, do_scsiboot, - "scsiboot- boot from SCSI device\n", - "loadAddr dev:part\n" -); - -#endif /* #if (CONFIG_COMMANDS & CFG_CMD_SCSI) */ diff --git a/common/cmd_spi.c b/common/cmd_spi.c deleted file mode 100644 index a6fdf7fddb..0000000000 --- a/common/cmd_spi.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * (C) Copyright 2002 - * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * SPI Read/Write Utilities - */ - -#include <common.h> -#include <command.h> -#include <spi.h> - -#if (CONFIG_COMMANDS & CFG_CMD_SPI) - -/*----------------------------------------------------------------------- - * Definitions - */ - -#ifndef MAX_SPI_BYTES -# define MAX_SPI_BYTES 32 /* Maximum number of bytes we can handle */ -#endif - -/* - * External table of chip select functions (see the appropriate board - * support for the actual definition of the table). - */ -extern spi_chipsel_type spi_chipsel[]; -extern int spi_chipsel_cnt; - -/* - * Values from last command. - */ -static int device; -static int bitlen; -static uchar dout[MAX_SPI_BYTES]; -static uchar din[MAX_SPI_BYTES]; - -/* - * SPI read/write - * - * Syntax: - * spi {dev} {num_bits} {dout} - * {dev} is the device number for controlling chip select (see TBD) - * {num_bits} is the number of bits to send & receive (base 10) - * {dout} is a hexadecimal string of data to send - * The command prints out the hexadecimal string received via SPI. - */ - -int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - char *cp = 0; - uchar tmp; - int j; - int rcode = 0; - - /* - * We use the last specified parameters, unless new ones are - * entered. - */ - - if ((flag & CMD_FLAG_REPEAT) == 0) - { - if (argc >= 2) - device = simple_strtoul(argv[1], NULL, 10); - if (argc >= 3) - bitlen = simple_strtoul(argv[2], NULL, 10); - if (argc >= 4) { - cp = argv[3]; - for(j = 0; *cp; j++, cp++) { - tmp = *cp - '0'; - if(tmp > 9) - tmp -= ('A' - '0') - 10; - if(tmp > 15) - tmp -= ('a' - 'A'); - if(tmp > 15) { - printf("Hex conversion error on %c, giving up.\n", *cp); - return 1; - } - if((j % 2) == 0) - dout[j / 2] = (tmp << 4); - else - dout[j / 2] |= tmp; - } - } - } - - if ((device < 0) || (device >= spi_chipsel_cnt)) { - printf("Invalid device %d, giving up.\n", device); - return 1; - } - if ((bitlen < 0) || (bitlen > (MAX_SPI_BYTES * 8))) { - printf("Invalid bitlen %d, giving up.\n", bitlen); - return 1; - } - - debug ("spi_chipsel[%d] = %08X\n", - device, (uint)spi_chipsel[device]); - - if(spi_xfer(spi_chipsel[device], bitlen, dout, din) != 0) { - printf("Error with the SPI transaction.\n"); - rcode = 1; - } else { - cp = (char *)din; - for(j = 0; j < ((bitlen + 7) / 8); j++) { - printf("%02X", *cp++); - } - printf("\n"); - } - - return rcode; -} - -/***************************************************/ - -U_BOOT_CMD( - sspi, 5, 1, do_spi, - "sspi - SPI utility commands\n", - "<device> <bit_len> <dout> - Send <bit_len> bits from <dout> out the SPI\n" - "<device> - Identifies the chip select of the device\n" - "<bit_len> - Number of bits to send (base 10)\n" - "<dout> - Hexadecimal string that gets sent\n" -); - -#endif /* CFG_CMD_SPI */ diff --git a/common/cmd_universe.c b/common/cmd_universe.c deleted file mode 100644 index 8d7b6fee12..0000000000 --- a/common/cmd_universe.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * (C) Copyright 2003 Stefan Roese, stefan.roese@esd-electronics.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <command.h> -#include <malloc.h> -#include <asm/io.h> -#include <pci.h> - -#include <universe.h> - -#if (CONFIG_COMMANDS & CFG_CMD_UNIVERSE) - -#define PCI_VENDOR PCI_VENDOR_ID_TUNDRA -#define PCI_DEVICE PCI_DEVICE_ID_TUNDRA_CA91C042 - - -typedef struct _UNI_DEV UNI_DEV; - -struct _UNI_DEV { - int bus; - pci_dev_t busdevfn; - UNIVERSE *uregs; - unsigned int pci_bs; -}; - -static UNI_DEV *dev; - - -int universe_init(void) -{ - int j, result, lastError = 0; - pci_dev_t busdevfn; - unsigned int val; - - busdevfn = pci_find_device(PCI_VENDOR, PCI_DEVICE, 0); - if (busdevfn == -1) { - puts("No Tundra Universe found!\n"); - return -1; - } - - /* Lets turn Latency off */ - pci_write_config_dword(busdevfn, 0x0c, 0); - - dev = malloc(sizeof(*dev)); - if (NULL == dev) { - puts("UNIVERSE: No memory!\n"); - result = -1; - goto break_20; - } - - memset(dev, 0, sizeof(*dev)); - dev->busdevfn = busdevfn; - - pci_read_config_dword(busdevfn, PCI_BASE_ADDRESS_1, &val); - if (val & 1) { - pci_read_config_dword(busdevfn, PCI_BASE_ADDRESS_0, &val); - } - val &= ~0xf; - dev->uregs = (UNIVERSE *)val; - - debug ("UNIVERSE-Base : %p\n", dev->uregs); - - /* check mapping */ - debug (" Read via mapping, PCI_ID = %08X\n", readl(&dev->uregs->pci_id)); - if (((PCI_DEVICE <<16) | PCI_VENDOR) != readl(&dev->uregs->pci_id)) { - printf ("UNIVERSE: Cannot read PCI-ID via Mapping: %08x\n", - readl(&dev->uregs->pci_id)); - result = -1; - goto break_30; - } - - debug ("PCI_BS = %08X\n", readl(&dev->uregs->pci_bs)); - - dev->pci_bs = readl(&dev->uregs->pci_bs); - - /* turn off windows */ - for (j=0; j <4; j ++) { - writel(0x00800000, &dev->uregs->lsi[j].ctl); - writel(0x00800000, &dev->uregs->vsi[j].ctl); - } - - /* - * Write to Misc Register - * Set VME Bus Time-out - * Arbitration Mode - * DTACK Enable - */ - writel(0x15040000 | (readl(&dev->uregs->misc_ctl) & 0x00020000), &dev->uregs->misc_ctl); - - if (readl(&dev->uregs->misc_ctl) & 0x00020000) { - debug ("System Controller!\n"); /* test-only */ - } else { - debug ("Not System Controller!\n"); /* test-only */ - } - - /* - * Lets turn off interrupts - */ - writel(0x00000000,&dev->uregs->lint_en); /* Disable interrupts in the Universe first */ - writel(0x0000FFFF,&dev->uregs->lint_stat); /* Clear Any Pending Interrupts */ - eieio(); - writel(0x0000, &dev->uregs->lint_map0); /* Map all ints to 0 */ - writel(0x0000, &dev->uregs->lint_map1); /* Map all ints to 0 */ - eieio(); - - return 0; - - break_30: - free(dev); - break_20: - lastError = result; - - return result; -} - - -/* - * Create pci slave window (access: pci -> vme) - */ -int universe_pci_slave_window(unsigned int pciAddr, unsigned int vmeAddr, int size, int vam, int pms, int vdw) -{ - int result, i; - unsigned int ctl = 0; - - if (NULL == dev) { - result = -1; - goto exit_10; - } - - for (i = 0; i < 4; i++) { - if (0x00800000 == readl(&dev->uregs->lsi[i].ctl)) - break; - } - - if (i == 4) { - printf ("universe: No Image available\n"); - result = -1; - goto exit_10; - } - - debug ("universe: Using image %d\n", i); - - writel(pciAddr , &dev->uregs->lsi[i].bs); - writel((pciAddr + size), &dev->uregs->lsi[i].bd); - writel((vmeAddr - pciAddr), &dev->uregs->lsi[i].to); - - switch (vam & VME_AM_Axx) { - case VME_AM_A16: - ctl = 0x00000000; - break; - case VME_AM_A24: - ctl = 0x00010000; - break; - case VME_AM_A32: - ctl = 0x00020000; - break; - } - - switch (vam & VME_AM_Mxx) { - case VME_AM_DATA: - ctl |= 0x00000000; - break; - case VME_AM_PROG: - ctl |= 0x00008000; - break; - } - - if (vam & VME_AM_SUP) { - ctl |= 0x00001000; - - } - - switch (vdw & VME_FLAG_Dxx) { - case VME_FLAG_D8: - ctl |= 0x00000000; - break; - case VME_FLAG_D16: - ctl |= 0x00400000; - break; - case VME_FLAG_D32: - ctl |= 0x00800000; - break; - } - - switch (pms & PCI_MS_Mxx) { - case PCI_MS_MEM: - ctl |= 0x00000000; - break; - case PCI_MS_IO: - ctl |= 0x00000001; - break; - case PCI_MS_CONFIG: - ctl |= 0x00000002; - break; - } - - ctl |= 0x80000000; /* enable */ - - writel(ctl, &dev->uregs->lsi[i].ctl); - - debug ("universe: window-addr=%p\n", &dev->uregs->lsi[i].ctl); - debug ("universe: pci slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->lsi[i].ctl)); - debug ("universe: pci slave window[%d] bs=%08x\n", i, readl(&dev->uregs->lsi[i].bs)); - debug ("universe: pci slave window[%d] bd=%08x\n", i, readl(&dev->uregs->lsi[i].bd)); - debug ("universe: pci slave window[%d] to=%08x\n", i, readl(&dev->uregs->lsi[i].to)); - - return 0; - - exit_10: - return -result; -} - - -/* - * Create vme slave window (access: vme -> pci) - */ -int universe_vme_slave_window(unsigned int vmeAddr, unsigned int pciAddr, int size, int vam, int pms) -{ - int result, i; - unsigned int ctl = 0; - - if (NULL == dev) { - result = -1; - goto exit_10; - } - - for (i = 0; i < 4; i++) { - if (0x00800000 == readl(&dev->uregs->vsi[i].ctl)) - break; - } - - if (i == 4) { - printf ("universe: No Image available\n"); - result = -1; - goto exit_10; - } - - debug ("universe: Using image %d\n", i); - - writel(vmeAddr , &dev->uregs->vsi[i].bs); - writel((vmeAddr + size), &dev->uregs->vsi[i].bd); - writel((pciAddr - vmeAddr), &dev->uregs->vsi[i].to); - - switch (vam & VME_AM_Axx) { - case VME_AM_A16: - ctl = 0x00000000; - break; - case VME_AM_A24: - ctl = 0x00010000; - break; - case VME_AM_A32: - ctl = 0x00020000; - break; - } - - switch (vam & VME_AM_Mxx) { - case VME_AM_DATA: - ctl |= 0x00000000; - break; - case VME_AM_PROG: - ctl |= 0x00800000; - break; - } - - if (vam & VME_AM_SUP) { - ctl |= 0x00100000; - - } - - switch (pms & PCI_MS_Mxx) { - case PCI_MS_MEM: - ctl |= 0x00000000; - break; - case PCI_MS_IO: - ctl |= 0x00000001; - break; - case PCI_MS_CONFIG: - ctl |= 0x00000002; - break; - } - - ctl |= 0x80f00000; /* enable */ - - writel(ctl, &dev->uregs->vsi[i].ctl); - - debug ("universe: window-addr=%p\n", &dev->uregs->vsi[i].ctl); - debug ("universe: vme slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->vsi[i].ctl)); - debug ("universe: vme slave window[%d] bs=%08x\n", i, readl(&dev->uregs->vsi[i].bs)); - debug ("universe: vme slave window[%d] bd=%08x\n", i, readl(&dev->uregs->vsi[i].bd)); - debug ("universe: vme slave window[%d] to=%08x\n", i, readl(&dev->uregs->vsi[i].to)); - - return 0; - - exit_10: - return -result; -} - - -/* - * Tundra Universe configuration - */ -int do_universe(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - ulong addr1 = 0, addr2 = 0, size = 0, vam = 0, pms = 0, vdw = 0; - char cmd = 'x'; - - /* get parameter */ - if (argc > 1) - cmd = argv[1][0]; - if (argc > 2) - addr1 = simple_strtoul(argv[2], NULL, 16); - if (argc > 3) - addr2 = simple_strtoul(argv[3], NULL, 16); - if (argc > 4) - size = simple_strtoul(argv[4], NULL, 16); - if (argc > 5) - vam = simple_strtoul(argv[5], NULL, 16); - if (argc > 6) - pms = simple_strtoul(argv[6], NULL, 16); - if (argc > 7) - vdw = simple_strtoul(argv[7], NULL, 16); - - switch (cmd) { - case 'i': /* init */ - universe_init(); - break; - case 'v': /* vme */ - printf("Configuring Universe VME Slave Window (VME->PCI):\n"); - printf(" vme=%08lx pci=%08lx size=%08lx vam=%02lx pms=%02lx\n", - addr1, addr2, size, vam, pms); - universe_vme_slave_window(addr1, addr2, size, vam, pms); - break; - case 'p': /* pci */ - printf("Configuring Universe PCI Slave Window (PCI->VME):\n"); - printf(" pci=%08lx vme=%08lx size=%08lx vam=%02lx pms=%02lx vdw=%02lx\n", - addr1, addr2, size, vam, pms, vdw); - universe_pci_slave_window(addr1, addr2, size, vam, pms, vdw); - break; - default: - printf("Universe command %s not supported!\n", argv[1]); - } - - return 0; -} - - -U_BOOT_CMD( - universe, 8, 1, do_universe, - "universe- initialize and configure Turndra Universe\n", - "init\n" - " - initialize universe\n" - "universe vme [vme_addr] [pci_addr] [size] [vam] [pms]\n" - " - create vme slave window (access: vme->pci)\n" - "universe pci [pci_addr] [vme_addr] [size] [vam] [pms] [vdw]\n" - " - create pci slave window (access: pci->vme)\n" - " [vam] = VMEbus Address-Modifier: 01 -> A16 Address Space\n" - " 02 -> A24 Address Space\n" - " 03 -> A32 Address Space\n" - " 04 -> Supervisor AM Code\n" - " 10 -> Data AM Code\n" - " 20 -> Program AM Code\n" - " [pms] = PCI Memory Space: 01 -> Memory Space\n" - " 02 -> I/O Space\n" - " 03 -> Configuration Space\n" - " [vdw] = VMEbus Maximum Datawidth: 01 -> D8 Data Width\n" - " 02 -> D16 Data Width\n" - " 03 -> D32 Data Width\n" -); - -#endif /* (CONFIG_COMMANDS & CFG_CMD_UNIVERSE) */ diff --git a/common/cmd_vfd.c b/common/cmd_vfd.c deleted file mode 100644 index 5e623a2705..0000000000 --- a/common/cmd_vfd.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * (C) Copyright 2001 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * Command to load a splash screen to the VFDs. - * NOTE that this will be controlled by a key combination when - * the keyboard stuff works. For now the user has to enter a - * bitmap number (only VFD_TEST_LOGO is supported now - 16.10.2002). - * Added VFD_REMOTE_LOGO (same as VFD_TEST_LOGO but a different color) - * on 20.10.2002. - * - * This rather crudely requires that each bitmap be included as a - * header file. - */ -#include <common.h> -#include <command.h> - -#if (CONFIG_COMMANDS & CFG_CMD_VFD) - -#include <vfd_logo.h> -#define VFD_TEST_LOGO_BMPNR 0 -#define VFD_REMOTE_LOGO_BMPNR 1 - -extern int transfer_pic(unsigned char, unsigned char *, int, int); - -int trab_vfd (ulong bitmap); - -int do_vfd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - ulong bitmap; - - if (argc != 2) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - if (argv[1][0] == '/') { /* select bitmap by number */ - bitmap = simple_strtoul(argv[1]+1, NULL, 10); - return (trab_vfd(bitmap)); - } - - /* display bitmap at given address */ - bitmap = simple_strtoul(argv[1], NULL, 16); - transfer_pic(3, (uchar *)bitmap, VFD_LOGO_HEIGHT, VFD_LOGO_WIDTH); - return 0; -} - -U_BOOT_CMD( - vfd, 2, 0, do_vfd, - "vfd - load a bitmap to the VFDs on TRAB\n", - "/N\n" - " - load bitmap N to the VFDs (N is _decimal_ !!!)\n" - "vfd ADDR\n" - " - load bitmap at address ADDR\n" -); -#endif /* CFG_CMD_VFD */ - -#ifdef CONFIG_VFD -int trab_vfd (ulong bitmap) -{ - uchar *addr; - char *s; - - switch (bitmap) { - case VFD_TEST_LOGO_BMPNR: - if ((s = getenv ("bitmap0")) != NULL) { - addr = (uchar *)simple_strtoul (s, NULL, 16); - } else { - addr = &vfd_test_logo_bitmap[0]; - } - break; - case VFD_REMOTE_LOGO_BMPNR: - if ((s = getenv ("bitmap1")) != NULL) { - addr = (uchar *)simple_strtoul (s, NULL, 16); - } else { - addr = &vfd_remote_logo_bitmap[0]; - } - break; - default: - printf("Unknown bitmap %ld\n", bitmap); - return 1; - } - transfer_pic(3, addr, VFD_LOGO_HEIGHT, VFD_LOGO_WIDTH); - return 0; -} -#endif /* CONFIG_VFD */ diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c deleted file mode 100644 index 8359153b2b..0000000000 --- a/common/cmd_ximg.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2003 - * Kai-Uwe Bloem, Auerswald GmbH & Co KG, <linux-development@auerswald.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#if (CONFIG_COMMANDS & CFG_CMD_XIMG) - -/* - * Multi Image extract - */ -#include <common.h> -#include <command.h> -#include <image.h> -#include <asm/byteorder.h> - -int -do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - ulong addr = load_addr, dest = 0; - ulong data, len, checksum; - ulong *len_ptr; - int i, verify, part = 0; - char pbuf[10], *s; - image_header_t header; - - s = getenv("verify"); - verify = (s && (*s == 'n')) ? 0 : 1; - - if (argc > 1) { - addr = simple_strtoul(argv[1], NULL, 16); - } - if (argc > 2) { - part = simple_strtoul(argv[2], NULL, 16); - } - if (argc > 3) { - dest = simple_strtoul(argv[3], NULL, 16); - } - - printf("## Copying from image at %08lx ...\n", addr); - - /* Copy header so we can blank CRC field for re-calculation */ - memmove(&header, (char *) addr, sizeof (image_header_t)); - - if (ntohl(header.ih_magic) != IH_MAGIC) { - printf("Bad Magic Number\n"); - return 1; - } - - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl(header.ih_hcrc); - header.ih_hcrc = 0; - - if (crc32(0, (char *) data, len) != checksum) { - printf("Bad Header Checksum\n"); - return 1; - } -#ifdef DEBUG - print_image_hdr((image_header_t *) addr); -#endif - - data = addr + sizeof (image_header_t); - len = ntohl(header.ih_size); - - if (header.ih_type != IH_TYPE_MULTI) { - printf("Wrong Image Type for %s command\n", cmdtp->name); - return 1; - } - - if (header.ih_comp != IH_COMP_NONE) { - printf("Wrong Compression Type for %s command\n", cmdtp->name); - return 1; - } - - if (verify) { - printf(" Verifying Checksum ... "); - if (crc32(0, (char *) data, len) != ntohl(header.ih_dcrc)) { - printf("Bad Data CRC\n"); - return 1; - } - printf("OK\n"); - } - - len_ptr = (ulong *) data; - - data += 4; /* terminator */ - for (i = 0; len_ptr[i]; ++i) { - data += 4; - if (argc > 2 && part > i) { - u_long tail; - len = ntohl(len_ptr[i]); - tail = len % 4; - data += len; - if (tail) { - data += 4 - tail; - } - } - } - if (argc > 2 && part >= i) { - printf("Bad Image Part\n"); - return 1; - } - len = ntohl(len_ptr[part]); - - if (argc > 3) { - memcpy((char *) dest, (char *) data, len); - } - - sprintf(pbuf, "%8lx", data); - setenv("fileaddr", pbuf); - sprintf(pbuf, "%8lx", len); - setenv("filesize", pbuf); - - return 0; -} - -U_BOOT_CMD(imxtract, 4, 1, do_imgextract, - "imxtract- extract a part of a multi-image\n", - "addr part [dest]\n" - " - extract <part> from image at <addr> and copy to <dest>\n"); - -#endif /* CONFIG_COMMANDS & CFG_CMD_XIMG */ diff --git a/common/cyclon2.c b/common/cyclon2.c deleted file mode 100644 index dce13b50d0..0000000000 --- a/common/cyclon2.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * (C) Copyright 2006 - * Heiko Schocher, hs@denx.de - * Based on ACE1XK.c - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include <common.h> /* core U-Boot definitions */ -#include <altera.h> -#include <ACEX1K.h> /* ACEX device family */ - -#if (CONFIG_FPGA & (CFG_ALTERA | CFG_CYCLON2)) - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Note: The assumption is that we cannot possibly run fast enough to - * overrun the device (the Slave Parallel mode can free run at 50MHz). - * If there is a need to operate slower, define CONFIG_FPGA_DELAY in - * the board config file to slow things down. - */ -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CFG_FPGA_WAIT -#define CFG_FPGA_WAIT CFG_HZ/10 /* 100 ms */ -#endif - -static int CYC2_ps_load( Altera_desc *desc, void *buf, size_t bsize ); -static int CYC2_ps_dump( Altera_desc *desc, void *buf, size_t bsize ); -/* static int CYC2_ps_info( Altera_desc *desc ); */ -static int CYC2_ps_reloc( Altera_desc *desc, ulong reloc_offset ); - -/* ------------------------------------------------------------------------- */ -/* CYCLON2 Generic Implementation */ -int CYC2_load (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__); - ret_val = CYC2_ps_load (desc, buf, bsize); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int CYC2_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__); - ret_val = CYC2_ps_dump (desc, buf, bsize); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int CYC2_info( Altera_desc *desc ) -{ - return FPGA_SUCCESS; -} - -int CYC2_reloc (Altera_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (desc->family != Altera_CYC2) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case passive_serial: - ret_val = CYC2_ps_reloc (desc, reloc_offset); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -/* ------------------------------------------------------------------------- */ -/* CYCLON2 Passive Serial Generic Implementation */ -static int CYC2_ps_load (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns; - int ret = 0; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "config:\t0x%p\n" - "status:\t0x%p\n" - "write:\t0x%p\n" - "done:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->config, fn->status, - fn->write, fn->done); -#ifdef CFG_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...", cookie); -#endif - - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->config) (TRUE, TRUE, cookie); /* Assert nCONFIG */ - - udelay(2); /* T_cfg > 2us */ - - /* Wait for nSTATUS to be asserted */ - ts = get_timer (0); /* get current time */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for STATUS to go high.\n"); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - } while (!(*fn->status) (cookie)); - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - - ret = (*fn->write) (buf, bsize, TRUE, cookie); - if (ret) { - puts ("** Write failed.\n"); - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#ifdef CFG_FPGA_PROG_FEEDBACK - puts(" OK? ..."); -#endif - - CONFIG_FPGA_DELAY (); - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc (' '); /* terminate the dotted line */ -#endif - - /* - * Checking FPGA's CONF_DONE signal - correctly booted ? - */ - - if ( ! (*fn->done) (cookie) ) { - puts ("** Booting failed! CONF_DONE is still deasserted.\n"); - (*fn->abort) (cookie); - return (FPGA_FAIL); - } -#ifdef CFG_FPGA_PROG_FEEDBACK - puts(" OK\n"); -#endif - - ret_val = FPGA_SUCCESS; - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) { - puts ("Done.\n"); - } - else { - puts ("Fail.\n"); - } -#endif - (*fn->post) (cookie); - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int CYC2_ps_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - /* Readback is only available through the Slave Parallel and */ - /* boundary-scan interfaces. */ - printf ("%s: Passive Serial Dumping is unavailable\n", - __FUNCTION__); - return FPGA_FAIL; -} - -static int CYC2_ps_reloc (Altera_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Altera_CYC2_Passive_Serial_fns *fn_r, *fn = - (Altera_CYC2_Passive_Serial_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Altera_CYC2_Passive_Serial_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Altera_CYC2_Passive_Serial_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Altera_pre_fn) addr; - - addr = (ulong) (fn->config) + reloc_offset; - fn_r->config = (Altera_config_fn) addr; - - addr = (ulong) (fn->status) + reloc_offset; - fn_r->status = (Altera_status_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Altera_done_fn) addr; - - addr = (ulong) (fn->write) + reloc_offset; - fn_r->write = (Altera_write_fn) addr; - - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Altera_abort_fn) addr; - - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Altera_post_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -#endif /* (CONFIG_FPGA & (CFG_ALTERA | CFG_CYCLON2)) */ diff --git a/common/docecc.c b/common/docecc.c deleted file mode 100644 index 79adb48958..0000000000 --- a/common/docecc.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * ECC algorithm for M-systems disk on chip. We use the excellent Reed - * Solmon code of Phil Karn (karn@ka9q.ampr.org) available under the - * GNU GPL License. The rest is simply to convert the disk on chip - * syndrom into a standard syndom. - * - * Author: Fabrice Bellard (fabrice.bellard@netgem.com) - * Copyright (C) 2000 Netgem S.A. - * - * $Id: docecc.c,v 1.4 2001/10/02 15:05:13 dwmw2 Exp $ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <config.h> -#include <common.h> -#include <malloc.h> - -#undef ECC_DEBUG -#undef PSYCHO_DEBUG - -#if (CONFIG_COMMANDS & CFG_CMD_DOC) - -#include <linux/mtd/doc2000.h> - -/* need to undef it (from asm/termbits.h) */ -#undef B0 - -#define MM 10 /* Symbol size in bits */ -#define KK (1023-4) /* Number of data symbols per block */ -#define B0 510 /* First root of generator polynomial, alpha form */ -#define PRIM 1 /* power of alpha used to generate roots of generator poly */ -#define NN ((1 << MM) - 1) - -typedef unsigned short dtype; - -/* 1+x^3+x^10 */ -static const int Pp[MM+1] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 }; - -/* This defines the type used to store an element of the Galois Field - * used by the code. Make sure this is something larger than a char if - * if anything larger than GF(256) is used. - * - * Note: unsigned char will work up to GF(256) but int seems to run - * faster on the Pentium. - */ -typedef int gf; - -/* No legal value in index form represents zero, so - * we need a special value for this purpose - */ -#define A0 (NN) - -/* Compute x % NN, where NN is 2**MM - 1, - * without a slow divide - */ -static inline gf -modnn(int x) -{ - while (x >= NN) { - x -= NN; - x = (x >> MM) + (x & NN); - } - return x; -} - -#define CLEAR(a,n) {\ -int ci;\ -for(ci=(n)-1;ci >=0;ci--)\ -(a)[ci] = 0;\ -} - -#define COPY(a,b,n) {\ -int ci;\ -for(ci=(n)-1;ci >=0;ci--)\ -(a)[ci] = (b)[ci];\ -} - -#define COPYDOWN(a,b,n) {\ -int ci;\ -for(ci=(n)-1;ci >=0;ci--)\ -(a)[ci] = (b)[ci];\ -} - -#define Ldec 1 - -/* generate GF(2**m) from the irreducible polynomial p(X) in Pp[0]..Pp[m] - lookup tables: index->polynomial form alpha_to[] contains j=alpha**i; - polynomial form -> index form index_of[j=alpha**i] = i - alpha=2 is the primitive element of GF(2**m) - HARI's COMMENT: (4/13/94) alpha_to[] can be used as follows: - Let @ represent the primitive element commonly called "alpha" that - is the root of the primitive polynomial p(x). Then in GF(2^m), for any - 0 <= i <= 2^m-2, - @^i = a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1) - where the binary vector (a(0),a(1),a(2),...,a(m-1)) is the representation - of the integer "alpha_to[i]" with a(0) being the LSB and a(m-1) the MSB. Thus for - example the polynomial representation of @^5 would be given by the binary - representation of the integer "alpha_to[5]". - Similarily, index_of[] can be used as follows: - As above, let @ represent the primitive element of GF(2^m) that is - the root of the primitive polynomial p(x). In order to find the power - of @ (alpha) that has the polynomial representation - a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1) - we consider the integer "i" whose binary representation with a(0) being LSB - and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry - "index_of[i]". Now, @^index_of[i] is that element whose polynomial - representation is (a(0),a(1),a(2),...,a(m-1)). - NOTE: - The element alpha_to[2^m-1] = 0 always signifying that the - representation of "@^infinity" = 0 is (0,0,0,...,0). - Similarily, the element index_of[0] = A0 always signifying - that the power of alpha which has the polynomial representation - (0,0,...,0) is "infinity". - -*/ - -static void -generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1]) -{ - register int i, mask; - - mask = 1; - Alpha_to[MM] = 0; - for (i = 0; i < MM; i++) { - Alpha_to[i] = mask; - Index_of[Alpha_to[i]] = i; - /* If Pp[i] == 1 then, term @^i occurs in poly-repr of @^MM */ - if (Pp[i] != 0) - Alpha_to[MM] ^= mask; /* Bit-wise EXOR operation */ - mask <<= 1; /* single left-shift */ - } - Index_of[Alpha_to[MM]] = MM; - /* - * Have obtained poly-repr of @^MM. Poly-repr of @^(i+1) is given by - * poly-repr of @^i shifted left one-bit and accounting for any @^MM - * term that may occur when poly-repr of @^i is shifted. - */ - mask >>= 1; - for (i = MM + 1; i < NN; i++) { - if (Alpha_to[i - 1] >= mask) - Alpha_to[i] = Alpha_to[MM] ^ ((Alpha_to[i - 1] ^ mask) << 1); - else - Alpha_to[i] = Alpha_to[i - 1] << 1; - Index_of[Alpha_to[i]] = i; - } - Index_of[0] = A0; - Alpha_to[NN] = 0; -} - -/* - * Performs ERRORS+ERASURES decoding of RS codes. bb[] is the content - * of the feedback shift register after having processed the data and - * the ECC. - * - * Return number of symbols corrected, or -1 if codeword is illegal - * or uncorrectable. If eras_pos is non-null, the detected error locations - * are written back. NOTE! This array must be at least NN-KK elements long. - * The corrected data are written in eras_val[]. They must be xor with the data - * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] . - * - * First "no_eras" erasures are declared by the calling program. Then, the - * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2). - * If the number of channel errors is not greater than "t_after_eras" the - * transmitted codeword will be recovered. Details of algorithm can be found - * in R. Blahut's "Theory ... of Error-Correcting Codes". - - * Warning: the eras_pos[] array must not contain duplicate entries; decoder failure - * will result. The decoder *could* check for this condition, but it would involve - * extra time on every decoding operation. - * */ -static int -eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1], - gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK], - int no_eras) -{ - int deg_lambda, el, deg_omega; - int i, j, r,k; - gf u,q,tmp,num1,num2,den,discr_r; - gf lambda[NN-KK + 1], s[NN-KK + 1]; /* Err+Eras Locator poly - * and syndrome poly */ - gf b[NN-KK + 1], t[NN-KK + 1], omega[NN-KK + 1]; - gf root[NN-KK], reg[NN-KK + 1], loc[NN-KK]; - int syn_error, count; - - syn_error = 0; - for(i=0;i<NN-KK;i++) - syn_error |= bb[i]; - - if (!syn_error) { - /* if remainder is zero, data[] is a codeword and there are no - * errors to correct. So return data[] unmodified - */ - count = 0; - goto finish; - } - - for(i=1;i<=NN-KK;i++){ - s[i] = bb[0]; - } - for(j=1;j<NN-KK;j++){ - if(bb[j] == 0) - continue; - tmp = Index_of[bb[j]]; - - for(i=1;i<=NN-KK;i++) - s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)]; - } - - /* undo the feedback register implicit multiplication and convert - syndromes to index form */ - - for(i=1;i<=NN-KK;i++) { - tmp = Index_of[s[i]]; - if (tmp != A0) - tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM); - s[i] = tmp; - } - - CLEAR(&lambda[1],NN-KK); - lambda[0] = 1; - - if (no_eras > 0) { - /* Init lambda to be the erasure locator polynomial */ - lambda[1] = Alpha_to[modnn(PRIM * eras_pos[0])]; - for (i = 1; i < no_eras; i++) { - u = modnn(PRIM*eras_pos[i]); - for (j = i+1; j > 0; j--) { - tmp = Index_of[lambda[j - 1]]; - if(tmp != A0) - lambda[j] ^= Alpha_to[modnn(u + tmp)]; - } - } -#ifdef ECC_DEBUG - /* Test code that verifies the erasure locator polynomial just constructed - Needed only for decoder debugging. */ - - /* find roots of the erasure location polynomial */ - for(i=1;i<=no_eras;i++) - reg[i] = Index_of[lambda[i]]; - count = 0; - for (i = 1,k=NN-Ldec; i <= NN; i++,k = modnn(NN+k-Ldec)) { - q = 1; - for (j = 1; j <= no_eras; j++) - if (reg[j] != A0) { - reg[j] = modnn(reg[j] + j); - q ^= Alpha_to[reg[j]]; - } - if (q != 0) - continue; - /* store root and error location number indices */ - root[count] = i; - loc[count] = k; - count++; - } - if (count != no_eras) { - printf("\n lambda(x) is WRONG\n"); - count = -1; - goto finish; - } -#ifdef PSYCHO_DEBUG - printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n"); - for (i = 0; i < count; i++) - printf("%d ", loc[i]); - printf("\n"); -#endif -#endif - } - for(i=0;i<NN-KK+1;i++) - b[i] = Index_of[lambda[i]]; - - /* - * Begin Berlekamp-Massey algorithm to determine error+erasure - * locator polynomial - */ - r = no_eras; - el = no_eras; - while (++r <= NN-KK) { /* r is the step number */ - /* Compute discrepancy at the r-th step in poly-form */ - discr_r = 0; - for (i = 0; i < r; i++){ - if ((lambda[i] != 0) && (s[r - i] != A0)) { - discr_r ^= Alpha_to[modnn(Index_of[lambda[i]] + s[r - i])]; - } - } - discr_r = Index_of[discr_r]; /* Index form */ - if (discr_r == A0) { - /* 2 lines below: B(x) <-- x*B(x) */ - COPYDOWN(&b[1],b,NN-KK); - b[0] = A0; - } else { - /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */ - t[0] = lambda[0]; - for (i = 0 ; i < NN-KK; i++) { - if(b[i] != A0) - t[i+1] = lambda[i+1] ^ Alpha_to[modnn(discr_r + b[i])]; - else - t[i+1] = lambda[i+1]; - } - if (2 * el <= r + no_eras - 1) { - el = r + no_eras - el; - /* - * 2 lines below: B(x) <-- inv(discr_r) * - * lambda(x) - */ - for (i = 0; i <= NN-KK; i++) - b[i] = (lambda[i] == 0) ? A0 : modnn(Index_of[lambda[i]] - discr_r + NN); - } else { - /* 2 lines below: B(x) <-- x*B(x) */ - COPYDOWN(&b[1],b,NN-KK); - b[0] = A0; - } - COPY(lambda,t,NN-KK+1); - } - } - - /* Convert lambda to index form and compute deg(lambda(x)) */ - deg_lambda = 0; - for(i=0;i<NN-KK+1;i++){ - lambda[i] = Index_of[lambda[i]]; - if(lambda[i] != A0) - deg_lambda = i; - } - /* - * Find roots of the error+erasure locator polynomial by Chien - * Search - */ - COPY(®[1],&lambda[1],NN-KK); - count = 0; /* Number of roots of lambda(x) */ - for (i = 1,k=NN-Ldec; i <= NN; i++,k = modnn(NN+k-Ldec)) { - q = 1; - for (j = deg_lambda; j > 0; j--){ - if (reg[j] != A0) { - reg[j] = modnn(reg[j] + j); - q ^= Alpha_to[reg[j]]; - } - } - if (q != 0) - continue; - /* store root (index-form) and error location number */ - root[count] = i; - loc[count] = k; - /* If we've already found max possible roots, - * abort the search to save time - */ - if(++count == deg_lambda) - break; - } - if (deg_lambda != count) { - /* - * deg(lambda) unequal to number of roots => uncorrectable - * error detected - */ - count = -1; - goto finish; - } - /* - * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo - * x**(NN-KK)). in index form. Also find deg(omega). - */ - deg_omega = 0; - for (i = 0; i < NN-KK;i++){ - tmp = 0; - j = (deg_lambda < i) ? deg_lambda : i; - for(;j >= 0; j--){ - if ((s[i + 1 - j] != A0) && (lambda[j] != A0)) - tmp ^= Alpha_to[modnn(s[i + 1 - j] + lambda[j])]; - } - if(tmp != 0) - deg_omega = i; - omega[i] = Index_of[tmp]; - } - omega[NN-KK] = A0; - - /* - * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = - * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form - */ - for (j = count-1; j >=0; j--) { - num1 = 0; - for (i = deg_omega; i >= 0; i--) { - if (omega[i] != A0) - num1 ^= Alpha_to[modnn(omega[i] + i * root[j])]; - } - num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)]; - den = 0; - - /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ - for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) { - if(lambda[i+1] != A0) - den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])]; - } - if (den == 0) { -#ifdef ECC_DEBUG - printf("\n ERROR: denominator = 0\n"); -#endif - /* Convert to dual- basis */ - count = -1; - goto finish; - } - /* Apply error to data */ - if (num1 != 0) { - eras_val[j] = Alpha_to[modnn(Index_of[num1] + Index_of[num2] + NN - Index_of[den])]; - } else { - eras_val[j] = 0; - } - } - finish: - for(i=0;i<count;i++) - eras_pos[i] = loc[i]; - return count; -} - -/***************************************************************************/ -/* The DOC specific code begins here */ - -#define SECTOR_SIZE 512 -/* The sector bytes are packed into NB_DATA MM bits words */ -#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM) - -/* - * Correct the errors in 'sector[]' by using 'ecc1[]' which is the - * content of the feedback shift register applyied to the sector and - * the ECC. Return the number of errors corrected (and correct them in - * sector), or -1 if error - */ -int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6]) -{ - int parity, i, nb_errors; - gf bb[NN - KK + 1]; - gf error_val[NN-KK]; - int error_pos[NN-KK], pos, bitpos, index, val; - dtype *Alpha_to, *Index_of; - - /* init log and exp tables here to save memory. However, it is slower */ - Alpha_to = malloc((NN + 1) * sizeof(dtype)); - if (!Alpha_to) - return -1; - - Index_of = malloc((NN + 1) * sizeof(dtype)); - if (!Index_of) { - free(Alpha_to); - return -1; - } - - generate_gf(Alpha_to, Index_of); - - parity = ecc1[1]; - - bb[0] = (ecc1[4] & 0xff) | ((ecc1[5] & 0x03) << 8); - bb[1] = ((ecc1[5] & 0xfc) >> 2) | ((ecc1[2] & 0x0f) << 6); - bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4); - bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2); - - nb_errors = eras_dec_rs(Alpha_to, Index_of, bb, - error_val, error_pos, 0); - if (nb_errors <= 0) - goto the_end; - - /* correct the errors */ - for(i=0;i<nb_errors;i++) { - pos = error_pos[i]; - if (pos >= NB_DATA && pos < KK) { - nb_errors = -1; - goto the_end; - } - if (pos < NB_DATA) { - /* extract bit position (MSB first) */ - pos = 10 * (NB_DATA - 1 - pos) - 6; - /* now correct the following 10 bits. At most two bytes - can be modified since pos is even */ - index = (pos >> 3) ^ 1; - bitpos = pos & 7; - if ((index >= 0 && index < SECTOR_SIZE) || - index == (SECTOR_SIZE + 1)) { - val = error_val[i] >> (2 + bitpos); - parity ^= val; - if (index < SECTOR_SIZE) - sector[index] ^= val; - } - index = ((pos >> 3) + 1) ^ 1; - bitpos = (bitpos + 10) & 7; - if (bitpos == 0) - bitpos = 8; - if ((index >= 0 && index < SECTOR_SIZE) || - index == (SECTOR_SIZE + 1)) { - val = error_val[i] << (8 - bitpos); - parity ^= val; - if (index < SECTOR_SIZE) - sector[index] ^= val; - } - } - } - - /* use parity to test extra errors */ - if ((parity & 0xff) != 0) - nb_errors = -1; - - the_end: - free(Alpha_to); - free(Index_of); - return nb_errors; -} - -#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */ diff --git a/common/fpga.c b/common/fpga.c deleted file mode 100644 index 81b9bc76e0..0000000000 --- a/common/fpga.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Generic FPGA support - */ -#include <common.h> /* core U-Boot definitions */ -#include <xilinx.h> /* xilinx specific definitions */ -#include <altera.h> /* altera specific definitions */ - -#if defined(CONFIG_FPGA) - - -/* Local definitions */ -#ifndef CONFIG_MAX_FPGA_DEVICES -#define CONFIG_MAX_FPGA_DEVICES 5 -#endif - -/* Enable/Disable debug console messages */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Local static data */ -static ulong relocation_offset = 0; -static int next_desc = FPGA_INVALID_DEVICE; -static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES]; - -/* Local static functions */ -static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum ); -static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf, - size_t bsize, char *fn ); -static int fpga_dev_info( int devnum ); - - -/* ------------------------------------------------------------------------- */ - -/* fpga_no_sup - * 'no support' message function - */ -static void fpga_no_sup( char *fn, char *msg ) -{ - if ( fn && msg ) { - printf( "%s: No support for %s. CONFIG_FPGA defined as 0x%x.\n", - fn, msg, CONFIG_FPGA ); - } else if ( msg ) { - printf( "No support for %s. CONFIG_FPGA defined as 0x%x.\n", - msg, CONFIG_FPGA ); - } else { - printf( "No FPGA suport! CONFIG_FPGA defined as 0x%x.\n", - CONFIG_FPGA ); - } -} - - -/* fpga_get_desc - * map a device number to a descriptor - */ -static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum ) -{ - fpga_desc *desc = (fpga_desc * )NULL; - - if (( devnum >= 0 ) && (devnum < next_desc )) { - desc = &desc_table[devnum]; - PRINTF( "%s: found fpga descriptor #%d @ 0x%p\n", - __FUNCTION__, devnum, desc ); - } - - return desc; -} - - -/* fpga_validate - * generic parameter checking code - */ -static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf, - size_t bsize, char *fn ) -{ - fpga_desc * desc = fpga_get_desc( devnum ); - - if ( !desc ) { - printf( "%s: Invalid device number %d\n", fn, devnum ); - } - - if ( !buf ) { - printf( "%s: Null buffer.\n", fn ); - return (fpga_desc * const)NULL; - } - if ( !bsize ) { - printf( "%s: Null buffer size.\n", fn ); - return (fpga_desc * const)NULL; - } - - return desc; -} - - -/* fpga_dev_info - * generic multiplexing code - */ -static int fpga_dev_info( int devnum ) -{ - int ret_val = FPGA_FAIL; /* assume failure */ - const fpga_desc * const desc = fpga_get_desc( devnum ); - - if ( desc ) { - PRINTF( "%s: Device Descriptor @ 0x%p\n", - __FUNCTION__, desc->devdesc ); - - switch ( desc->devtype ) { - case fpga_xilinx: -#if CONFIG_FPGA & CFG_FPGA_XILINX - printf( "Xilinx Device\nDescriptor @ 0x%p\n", desc ); - ret_val = xilinx_info( desc->devdesc ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); -#endif - break; - case fpga_altera: -#if CONFIG_FPGA & CFG_FPGA_ALTERA - printf( "Altera Device\nDescriptor @ 0x%p\n", desc ); - ret_val = altera_info( desc->devdesc ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); -#endif - break; - default: - printf( "%s: Invalid or unsupported device type %d\n", - __FUNCTION__, desc->devtype ); - } - } else { - printf( "%s: Invalid device number %d\n", - __FUNCTION__, devnum ); - } - - return ret_val; -} - - -/* fpga_reloc - * generic multiplexing code - */ -int fpga_reloc( fpga_type devtype, void *desc, ulong reloc_off ) -{ - int ret_val = FPGA_FAIL; - - PRINTF( "%s: Relocating Device of type %d @ 0x%p with offset %lx\n", - __FUNCTION__, devtype, desc, reloc_off ); - - switch ( devtype ) { - case fpga_xilinx: -#if CONFIG_FPGA & CFG_FPGA_XILINX - ret_val = xilinx_reloc( desc, reloc_off ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); -#endif - break; - case fpga_altera: -#if CONFIG_FPGA & CFG_FPGA_ALTERA - ret_val = altera_reloc( desc, reloc_off ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); -#endif - break; - default: - printf( "%s: Invalid or unsupported device type %d\n", - __FUNCTION__, devtype ); - } - - return ret_val; -} - -/* ------------------------------------------------------------------------- */ -/* fgpa_init is usually called from misc_init_r() and MUST be called - * before any of the other fpga functions are used. - */ -void fpga_init( ulong reloc_off ) -{ - relocation_offset = reloc_off; - next_desc = 0; - memset( desc_table, 0, sizeof(desc_table)); - - PRINTF( "%s: CONFIG_FPGA = 0x%x\n", __FUNCTION__, CONFIG_FPGA ); -} - -/* fpga_count - * Basic interface function to get the current number of devices available. - */ -int fpga_count( void ) -{ - return next_desc; -} - -/* fpga_add - * Attempts to relocate the device/board specific interface code - * to the proper RAM locations and adds the device descriptor to - * the device table. - */ -int fpga_add( fpga_type devtype, void *desc ) -{ - int devnum = FPGA_INVALID_DEVICE; - - if ( next_desc < 0 ) { - printf( "%s: FPGA support not initialized!\n", __FUNCTION__ ); - } else if (( devtype > fpga_min_type ) && ( devtype < fpga_undefined )) { - if ( desc ) { - if ( next_desc < CONFIG_MAX_FPGA_DEVICES ) { - if ( fpga_reloc( devtype, desc, relocation_offset ) - == FPGA_SUCCESS ) { - devnum = next_desc; - desc_table[next_desc].devtype = devtype; - desc_table[next_desc++].devdesc = desc; - } else { - printf( "%s: Unable to relocate device interface table!\n", - __FUNCTION__ ); - } - } else { - printf( "%s: Exceeded Max FPGA device count\n", __FUNCTION__ ); - } - } else { - printf( "%s: NULL device descriptor\n", __FUNCTION__ ); - } - } else { - printf( "%s: Unsupported FPGA type %d\n", __FUNCTION__, devtype ); - } - - return devnum; -} - -/* - * Generic multiplexing code - */ -int fpga_load( int devnum, void *buf, size_t bsize ) -{ - int ret_val = FPGA_FAIL; /* assume failure */ - fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ ); - - if ( desc ) { - switch ( desc->devtype ) { - case fpga_xilinx: -#if CONFIG_FPGA & CFG_FPGA_XILINX - ret_val = xilinx_load( desc->devdesc, buf, bsize ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); -#endif - break; - case fpga_altera: -#if CONFIG_FPGA & CFG_FPGA_ALTERA - ret_val = altera_load( desc->devdesc, buf, bsize ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); -#endif - break; - default: - printf( "%s: Invalid or unsupported device type %d\n", - __FUNCTION__, desc->devtype ); - } - } - - return ret_val; -} - -/* fpga_dump - * generic multiplexing code - */ -int fpga_dump( int devnum, void *buf, size_t bsize ) -{ - int ret_val = FPGA_FAIL; /* assume failure */ - fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ ); - - if ( desc ) { - switch ( desc->devtype ) { - case fpga_xilinx: -#if CONFIG_FPGA & CFG_FPGA_XILINX - ret_val = xilinx_dump( desc->devdesc, buf, bsize ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); -#endif - break; - case fpga_altera: -#if CONFIG_FPGA & CFG_FPGA_ALTERA - ret_val = altera_dump( desc->devdesc, buf, bsize ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); -#endif - break; - default: - printf( "%s: Invalid or unsupported device type %d\n", - __FUNCTION__, desc->devtype ); - } - } - - return ret_val; -} - - -/* fpga_info - * front end to fpga_dev_info. If devnum is invalid, report on all - * available devices. - */ -int fpga_info( int devnum ) -{ - if ( devnum == FPGA_INVALID_DEVICE ) { - if ( next_desc > 0 ) { - int dev; - - for ( dev = 0; dev < next_desc; dev++ ) { - fpga_dev_info( dev ); - } - return FPGA_SUCCESS; - } else { - printf( "%s: No FPGA devices available.\n", __FUNCTION__ ); - return FPGA_FAIL; - } - } - else return fpga_dev_info( devnum ); -} - -/* ------------------------------------------------------------------------- */ - -#endif /* CONFIG_FPGA */ diff --git a/common/kgdb.c b/common/kgdb.c deleted file mode 100644 index 5f20c5890a..0000000000 --- a/common/kgdb.c +++ /dev/null @@ -1,594 +0,0 @@ -/* taken from arch/ppc/kernel/ppc-stub.c */ - -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or its performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for SPARC by Stu Grossman, Cygnus Support. - * - * This code has been extensively tested on the Fujitsu SPARClite demo board. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * qOffsets Get section offsets. Reply is Text=xxx;Data=yyy;Bss=zzz - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * bBB..BB Set baud rate to BB..BB OK or BNN, then sets - * baud rate - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $<packet info>#<checksum>. - * - * where - * <packet info> :: <characters representing the command or response> - * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>> - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - -#include <common.h> - -#include <kgdb.h> -#include <command.h> - -#if (CONFIG_COMMANDS & CFG_CMD_KGDB) - -#undef KGDB_DEBUG - -/* - * BUFMAX defines the maximum number of characters in inbound/outbound buffers - */ -#define BUFMAX 1024 -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; -static char remcomRegBuffer[BUFMAX]; - -static int initialized = 0; -static int kgdb_active = 0, first_entry = 1; -static struct pt_regs entry_regs; -static u_int error_jmp_buf[BUFMAX/2]; -static int longjmp_on_fault = 0; -#ifdef KGDB_DEBUG -static int kdebug = 1; -#endif - -static const char hexchars[]="0123456789abcdef"; - -/* Convert ch from a hex digit to an int */ -static int -hex(unsigned char ch) -{ - if (ch >= 'a' && ch <= 'f') - return ch-'a'+10; - if (ch >= '0' && ch <= '9') - return ch-'0'; - if (ch >= 'A' && ch <= 'F') - return ch-'A'+10; - return -1; -} - -/* Convert the memory pointed to by mem into hex, placing result in buf. - * Return a pointer to the last char put in buf (null). - */ -static unsigned char * -mem2hex(char *mem, char *buf, int count) -{ - unsigned char ch; - - longjmp_on_fault = 1; - while (count-- > 0) { - ch = *mem++; - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch & 0xf]; - } - *buf = 0; - longjmp_on_fault = 0; - return (unsigned char *)buf; -} - -/* convert the hex array pointed to by buf into binary to be placed in mem - * return a pointer to the character AFTER the last byte fetched from buf. -*/ -static char * -hex2mem(char *buf, char *mem, int count) -{ - int i, hexValue; - unsigned char ch; - char *mem_start = mem; - - longjmp_on_fault = 1; - for (i=0; i<count; i++) { - if ((hexValue = hex(*buf++)) < 0) - kgdb_error(KGDBERR_NOTHEXDIG); - ch = hexValue << 4; - if ((hexValue = hex(*buf++)) < 0) - kgdb_error(KGDBERR_NOTHEXDIG); - ch |= hexValue; - *mem++ = ch; - } - kgdb_flush_cache_range((void *)mem_start, (void *)(mem - 1)); - longjmp_on_fault = 0; - - return buf; -} - -/* - * While we find nice hex chars, build an int. - * Return number of chars processed. - */ -static int -hexToInt(char **ptr, int *intValue) -{ - int numChars = 0; - int hexValue; - - *intValue = 0; - - longjmp_on_fault = 1; - while (**ptr) { - hexValue = hex(**ptr); - if (hexValue < 0) - break; - - *intValue = (*intValue << 4) | hexValue; - numChars ++; - - (*ptr)++; - } - longjmp_on_fault = 0; - - return (numChars); -} - -/* scan for the sequence $<data>#<checksum> */ -static void -getpacket(char *buffer) -{ - unsigned char checksum; - unsigned char xmitcsum; - int i; - int count; - unsigned char ch; - - do { - /* wait around for the start character, ignore all other - * characters */ - while ((ch = (getDebugChar() & 0x7f)) != '$') { -#ifdef KGDB_DEBUG - if (kdebug) - putc(ch); -#endif - ; - } - - checksum = 0; - xmitcsum = -1; - - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) { - ch = getDebugChar() & 0x7f; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - - if (count >= BUFMAX) - continue; - - buffer[count] = 0; - - if (ch == '#') { - xmitcsum = hex(getDebugChar() & 0x7f) << 4; - xmitcsum |= hex(getDebugChar() & 0x7f); - if (checksum != xmitcsum) - putDebugChar('-'); /* failed checksum */ - else { - putDebugChar('+'); /* successful transfer */ - /* if a sequence char is present, reply the ID */ - if (buffer[2] == ':') { - putDebugChar(buffer[0]); - putDebugChar(buffer[1]); - /* remove sequence chars from buffer */ - count = strlen(buffer); - for (i=3; i <= count; i++) - buffer[i-3] = buffer[i]; - } - } - } - } while (checksum != xmitcsum); -} - -/* send the packet in buffer. */ -static void -putpacket(unsigned char *buffer) -{ - unsigned char checksum; - int count; - unsigned char ch, recv; - - /* $<packet info>#<checksum>. */ - do { - putDebugChar('$'); - checksum = 0; - count = 0; - - while ((ch = buffer[count])) { - putDebugChar(ch); - checksum += ch; - count += 1; - } - - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum & 0xf]); - recv = getDebugChar(); - } while ((recv & 0x7f) != '+'); -} - -/* - * This function does all command processing for interfacing to gdb. - */ -static int -handle_exception (struct pt_regs *regs) -{ - int addr; - int length; - char *ptr; - kgdb_data kd; - int i; - - if (!initialized) { - printf("kgdb: exception before kgdb is initialized! huh?\n"); - return (0); - } - - /* probably should check which exception occured as well */ - if (longjmp_on_fault) { - longjmp_on_fault = 0; - kgdb_longjmp((long*)error_jmp_buf, KGDBERR_MEMFAULT); - panic("kgdb longjump failed!\n"); - } - - if (kgdb_active) { - printf("kgdb: unexpected exception from within kgdb\n"); - return (0); - } - kgdb_active = 1; - - kgdb_interruptible(0); - - printf("kgdb: handle_exception; trap [0x%x]\n", kgdb_trap(regs)); - - if (kgdb_setjmp((long*)error_jmp_buf) != 0) - panic("kgdb: error or fault in entry init!\n"); - - kgdb_enter(regs, &kd); - - if (first_entry) { - /* - * the first time we enter kgdb, we save the processor - * state so that we can return to the monitor if the - * remote end quits gdb (or at least, tells us to quit - * with the 'k' packet) - */ - entry_regs = *regs; - first_entry = 0; - } - - ptr = remcomOutBuffer; - - *ptr++ = 'T'; - - *ptr++ = hexchars[kd.sigval >> 4]; - *ptr++ = hexchars[kd.sigval & 0xf]; - - for (i = 0; i < kd.nregs; i++) { - kgdb_reg *rp = &kd.regs[i]; - - *ptr++ = hexchars[rp->num >> 4]; - *ptr++ = hexchars[rp->num & 0xf]; - *ptr++ = ':'; - ptr = (char *)mem2hex((char *)&rp->val, ptr, 4); - *ptr++ = ';'; - } - - *ptr = 0; - -#ifdef KGDB_DEBUG - if (kdebug) - printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer); -#endif - - putpacket((unsigned char *)&remcomOutBuffer); - - while (1) { - volatile int errnum; - - remcomOutBuffer[0] = 0; - - getpacket(remcomInBuffer); - ptr = &remcomInBuffer[1]; - -#ifdef KGDB_DEBUG - if (kdebug) - printf("kgdb: remcomInBuffer: %s\n", remcomInBuffer); -#endif - - errnum = kgdb_setjmp((long*)error_jmp_buf); - - if (errnum == 0) switch (remcomInBuffer[0]) { - - case '?': /* report most recent signal */ - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[kd.sigval >> 4]; - remcomOutBuffer[2] = hexchars[kd.sigval & 0xf]; - remcomOutBuffer[3] = 0; - break; - -#ifdef KGDB_DEBUG - case 'd': - /* toggle debug flag */ - kdebug ^= 1; - break; -#endif - - case 'g': /* return the value of the CPU registers. */ - length = kgdb_getregs(regs, remcomRegBuffer, BUFMAX); - mem2hex(remcomRegBuffer, remcomOutBuffer, length); - break; - - case 'G': /* set the value of the CPU registers */ - length = strlen(ptr); - if ((length & 1) != 0) kgdb_error(KGDBERR_BADPARAMS); - hex2mem(ptr, remcomRegBuffer, length/2); - kgdb_putregs(regs, remcomRegBuffer, length/2); - strcpy(remcomOutBuffer,"OK"); - break; - - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* Try to read %x,%x. */ - - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length)) { - mem2hex((char *)addr, remcomOutBuffer, length); - } else { - kgdb_error(KGDBERR_BADPARAMS); - } - break; - - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - /* Try to read '%x,%x:'. */ - - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length) - && *ptr++ == ':') { - hex2mem(ptr, (char *)addr, length); - strcpy(remcomOutBuffer, "OK"); - } else { - kgdb_error(KGDBERR_BADPARAMS); - } - break; - - - case 'k': /* kill the program, actually return to monitor */ - kd.extype = KGDBEXIT_KILL; - *regs = entry_regs; - first_entry = 1; - goto doexit; - - case 'C': /* CSS continue with signal SS */ - *ptr = '\0'; /* ignore the signal number for now */ - /* fall through */ - - case 'c': /* cAA..AA Continue; address AA..AA optional */ - /* try to read optional parameter, pc unchanged if no parm */ - kd.extype = KGDBEXIT_CONTINUE; - - if (hexToInt(&ptr, &addr)) { - kd.exaddr = addr; - kd.extype |= KGDBEXIT_WITHADDR; - } - - goto doexit; - - case 'S': /* SSS single step with signal SS */ - *ptr = '\0'; /* ignore the signal number for now */ - /* fall through */ - - case 's': - kd.extype = KGDBEXIT_SINGLE; - - if (hexToInt(&ptr, &addr)) { - kd.exaddr = addr; - kd.extype |= KGDBEXIT_WITHADDR; - } - - doexit: -/* Need to flush the instruction cache here, as we may have deposited a - * breakpoint, and the icache probably has no way of knowing that a data ref to - * some location may have changed something that is in the instruction cache. - */ - kgdb_flush_cache_all(); - kgdb_exit(regs, &kd); - kgdb_active = 0; - kgdb_interruptible(1); - return (1); - - case 'r': /* Reset (if user process..exit ???)*/ - panic("kgdb reset."); - break; - - case 'P': /* Pr=v set reg r to value v (r and v are hex) */ - if (hexToInt(&ptr, &addr) - && *ptr++ == '=' - && ((length = strlen(ptr)) & 1) == 0) { - hex2mem(ptr, remcomRegBuffer, length/2); - kgdb_putreg(regs, addr, - remcomRegBuffer, length/2); - strcpy(remcomOutBuffer,"OK"); - } else { - kgdb_error(KGDBERR_BADPARAMS); - } - break; - } /* switch */ - - if (errnum != 0) - sprintf(remcomOutBuffer, "E%02d", errnum); - -#ifdef KGDB_DEBUG - if (kdebug) - printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer); -#endif - - /* reply to the request */ - putpacket((unsigned char *)&remcomOutBuffer); - - } /* while(1) */ -} - -/* - * kgdb_init must be called *after* the - * monitor is relocated into ram - */ -void -kgdb_init(void) -{ - kgdb_serial_init(); - debugger_exception_handler = handle_exception; - initialized = 1; - - putDebugStr("kgdb ready\n"); - puts("ready\n"); -} - -void -kgdb_error(int errnum) -{ - longjmp_on_fault = 0; - kgdb_longjmp((long*)error_jmp_buf, errnum); - panic("kgdb_error: longjmp failed!\n"); -} - -/* Output string in GDB O-packet format if GDB has connected. If nothing - output, returns 0 (caller must then handle output). */ -int -kgdb_output_string (const char* s, unsigned int count) -{ - char buffer[512]; - - count = (count <= (sizeof(buffer) / 2 - 2)) - ? count : (sizeof(buffer) / 2 - 2); - - buffer[0] = 'O'; - mem2hex ((char *)s, &buffer[1], count); - putpacket((unsigned char *)&buffer); - - return 1; -} - -void -breakpoint(void) -{ - if (!initialized) { - printf("breakpoint() called b4 kgdb init\n"); - return; - } - - kgdb_breakpoint(0, 0); -} - -int -do_kgdb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - printf("Entering KGDB mode via exception handler...\n\n"); - kgdb_breakpoint(argc - 1, argv + 1); - printf("\nReturned from KGDB mode\n"); - return 0; -} - -U_BOOT_CMD( - kgdb, CONFIG_MAXARGS, 1, do_kgdb, - "kgdb - enter gdb remote debug mode\n", - "[arg0 arg1 .. argN]\n" - " - executes a breakpoint so that kgdb mode is\n" - " entered via the exception handler. To return\n" - " to the monitor, the remote gdb debugger must\n" - " execute a \"continue\" or \"quit\" command.\n" - "\n" - " if a program is loaded by the remote gdb, any args\n" - " passed to the kgdb command are given to the loaded\n" - " program if it is executed (see the \"hello_world\"\n" - " example program in the U-Boot examples directory)." -); -#else - -int kgdb_not_configured = 1; - -#endif /* CFG_CMD_KGDB */ diff --git a/common/lcd.c b/common/lcd.c deleted file mode 100644 index dbb5aad9d4..0000000000 --- a/common/lcd.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * Common LCD routines for supported CPUs - * - * (C) Copyright 2001-2002 - * Wolfgang Denk, DENX Software Engineering -- wd@denx.de - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/************************************************************************/ -/* ** HEADER FILES */ -/************************************************************************/ - -/* #define DEBUG */ - -#include <config.h> -#include <common.h> -#include <command.h> -#include <version.h> -#include <stdarg.h> -#include <linux/types.h> -#include <devices.h> -#if defined(CONFIG_POST) -#include <post.h> -#endif -#include <lcd.h> -#include <watchdog.h> - -#if defined(CONFIG_PXA250) -#include <asm/byteorder.h> -#endif - -#if defined(CONFIG_MPC823) -#include <lcdvideo.h> -#endif - -#ifdef CONFIG_LCD - -/************************************************************************/ -/* ** FONT DATA */ -/************************************************************************/ -#include <video_font.h> /* Get font data, width and height */ - -/************************************************************************/ -/* ** LOGO DATA */ -/************************************************************************/ -#ifdef CONFIG_LCD_LOGO -# include <bmp_logo.h> /* Get logo data, width and height */ -# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) -# error Default Color Map overlaps with Logo Color Map -# endif -#endif - -DECLARE_GLOBAL_DATA_PTR; - -ulong lcd_setmem (ulong addr); - -static void lcd_drawchars (ushort x, ushort y, uchar *str, int count); -static inline void lcd_puts_xy (ushort x, ushort y, uchar *s); -static inline void lcd_putc_xy (ushort x, ushort y, uchar c); - -static int lcd_init (void *lcdbase); - -static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); -extern void lcd_ctrl_init (void *lcdbase); -extern void lcd_enable (void); -static void *lcd_logo (void); - - -#if LCD_BPP == LCD_COLOR8 -extern void lcd_setcolreg (ushort regno, - ushort red, ushort green, ushort blue); -#endif -#if LCD_BPP == LCD_MONOCHROME -extern void lcd_initcolregs (void); -#endif - -static int lcd_getbgcolor (void); -static void lcd_setfgcolor (int color); -static void lcd_setbgcolor (int color); - -char lcd_is_enabled = 0; -extern vidinfo_t panel_info; - -#ifdef NOT_USED_SO_FAR -static void lcd_getcolreg (ushort regno, - ushort *red, ushort *green, ushort *blue); -static int lcd_getfgcolor (void); -#endif /* NOT_USED_SO_FAR */ - -/************************************************************************/ - -/*----------------------------------------------------------------------*/ - -static void console_scrollup (void) -{ - /* Copy up rows ignoring the first one */ - memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE); - - /* Clear the last one */ - memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE); -} - -/*----------------------------------------------------------------------*/ - -static inline void console_back (void) -{ - if (--console_col < 0) { - console_col = CONSOLE_COLS-1 ; - if (--console_row < 0) { - console_row = 0; - } - } - - lcd_putc_xy (console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, - ' '); -} - -/*----------------------------------------------------------------------*/ - -static inline void console_newline (void) -{ - ++console_row; - console_col = 0; - - /* Check if we need to scroll the terminal */ - if (console_row >= CONSOLE_ROWS) { - /* Scroll everything up */ - console_scrollup () ; - --console_row; - } -} - -/*----------------------------------------------------------------------*/ - -void lcd_putc (const char c) -{ - if (!lcd_is_enabled) { - serial_putc(c); - return; - } - - switch (c) { - case '\r': console_col = 0; - return; - - case '\n': console_newline(); - return; - - case '\t': /* Tab (8 chars alignment) */ - console_col |= 8; - console_col &= ~7; - - if (console_col >= CONSOLE_COLS) { - console_newline(); - } - return; - - case '\b': console_back(); - return; - - default: lcd_putc_xy (console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, - c); - if (++console_col >= CONSOLE_COLS) { - console_newline(); - } - return; - } - /* NOTREACHED */ -} - -/*----------------------------------------------------------------------*/ - -void lcd_puts (const char *s) -{ - if (!lcd_is_enabled) { - serial_puts (s); - return; - } - - while (*s) { - lcd_putc (*s++); - } -} - -/************************************************************************/ -/* ** Low-Level Graphics Routines */ -/************************************************************************/ - -static void lcd_drawchars (ushort x, ushort y, uchar *str, int count) -{ - uchar *dest; - ushort off, row; - - dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8); - off = x * (1 << LCD_BPP) % 8; - - for (row=0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) { - uchar *s = str; - uchar *d = dest; - int i; - -#if LCD_BPP == LCD_MONOCHROME - uchar rest = *d & -(1 << (8-off)); - uchar sym; -#endif - for (i=0; i<count; ++i) { - uchar c, bits; - - c = *s++; - bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; - -#if LCD_BPP == LCD_MONOCHROME - sym = (COLOR_MASK(lcd_color_fg) & bits) | - (COLOR_MASK(lcd_color_bg) & ~bits); - - *d++ = rest | (sym >> off); - rest = sym << (8-off); -#elif LCD_BPP == LCD_COLOR8 - for (c=0; c<8; ++c) { - *d++ = (bits & 0x80) ? - lcd_color_fg : lcd_color_bg; - bits <<= 1; - } -#elif LCD_BPP == LCD_COLOR16 - for (c=0; c<16; ++c) { - *d++ = (bits & 0x80) ? - lcd_color_fg : lcd_color_bg; - bits <<= 1; - } -#endif - } -#if LCD_BPP == LCD_MONOCHROME - *d = rest | (*d & ((1 << (8-off)) - 1)); -#endif - } -} - -/*----------------------------------------------------------------------*/ - -static inline void lcd_puts_xy (ushort x, ushort y, uchar *s) -{ -#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) - lcd_drawchars (x, y+BMP_LOGO_HEIGHT, s, strlen ((char *)s)); -#else - lcd_drawchars (x, y, s, strlen ((char *)s)); -#endif -} - -/*----------------------------------------------------------------------*/ - -static inline void lcd_putc_xy (ushort x, ushort y, uchar c) -{ -#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) - lcd_drawchars (x, y+BMP_LOGO_HEIGHT, &c, 1); -#else - lcd_drawchars (x, y, &c, 1); -#endif -} - -/************************************************************************/ -/** Small utility to check that you got the colours right */ -/************************************************************************/ -#ifdef LCD_TEST_PATTERN - -#define N_BLK_VERT 2 -#define N_BLK_HOR 3 - -static int test_colors[N_BLK_HOR*N_BLK_VERT] = { - CONSOLE_COLOR_RED, CONSOLE_COLOR_GREEN, CONSOLE_COLOR_YELLOW, - CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN, -}; - -static void test_pattern (void) -{ - ushort v_max = panel_info.vl_row; - ushort h_max = panel_info.vl_col; - ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT; - ushort h_step = (h_max + N_BLK_HOR - 1) / N_BLK_HOR; - ushort v, h; - uchar *pix = (uchar *)lcd_base; - - printf ("[LCD] Test Pattern: %d x %d [%d x %d]\n", - h_max, v_max, h_step, v_step); - - /* WARNING: Code silently assumes 8bit/pixel */ - for (v=0; v<v_max; ++v) { - uchar iy = v / v_step; - for (h=0; h<h_max; ++h) { - uchar ix = N_BLK_HOR * iy + (h/h_step); - *pix++ = test_colors[ix]; - } - } -} -#endif /* LCD_TEST_PATTERN */ - - -/************************************************************************/ -/* ** GENERIC Initialization Routines */ -/************************************************************************/ - -int drv_lcd_init (void) -{ - device_t lcddev; - int rc; - - lcd_base = (void *)(gd->fb_base); - - lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8; - - lcd_init (lcd_base); /* LCD initialization */ - - /* Device initialization */ - memset (&lcddev, 0, sizeof (lcddev)); - - strcpy (lcddev.name, "lcd"); - lcddev.ext = 0; /* No extensions */ - lcddev.flags = DEV_FLAGS_OUTPUT; /* Output only */ - lcddev.putc = lcd_putc; /* 'putc' function */ - lcddev.puts = lcd_puts; /* 'puts' function */ - - rc = device_register (&lcddev); - - return (rc == 0) ? 1 : rc; -} - -/*----------------------------------------------------------------------*/ -static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ -#if LCD_BPP == LCD_MONOCHROME - /* Setting the palette */ - lcd_initcolregs(); - -#elif LCD_BPP == LCD_COLOR8 - /* Setting the palette */ - lcd_setcolreg (CONSOLE_COLOR_BLACK, 0, 0, 0); - lcd_setcolreg (CONSOLE_COLOR_RED, 0xFF, 0, 0); - lcd_setcolreg (CONSOLE_COLOR_GREEN, 0, 0xFF, 0); - lcd_setcolreg (CONSOLE_COLOR_YELLOW, 0xFF, 0xFF, 0); - lcd_setcolreg (CONSOLE_COLOR_BLUE, 0, 0, 0xFF); - lcd_setcolreg (CONSOLE_COLOR_MAGENTA, 0xFF, 0, 0xFF); - lcd_setcolreg (CONSOLE_COLOR_CYAN, 0, 0xFF, 0xFF); - lcd_setcolreg (CONSOLE_COLOR_GREY, 0xAA, 0xAA, 0xAA); - lcd_setcolreg (CONSOLE_COLOR_WHITE, 0xFF, 0xFF, 0xFF); -#endif - -#ifndef CFG_WHITE_ON_BLACK - lcd_setfgcolor (CONSOLE_COLOR_BLACK); - lcd_setbgcolor (CONSOLE_COLOR_WHITE); -#else - lcd_setfgcolor (CONSOLE_COLOR_WHITE); - lcd_setbgcolor (CONSOLE_COLOR_BLACK); -#endif /* CFG_WHITE_ON_BLACK */ - -#ifdef LCD_TEST_PATTERN - test_pattern(); -#else - /* set framebuffer to background color */ - memset ((char *)lcd_base, - COLOR_MASK(lcd_getbgcolor()), - lcd_line_length*panel_info.vl_row); -#endif - /* Paint the logo and retrieve LCD base address */ - debug ("[LCD] Drawing the logo...\n"); - lcd_console_address = lcd_logo (); - - console_col = 0; - console_row = 0; - - return (0); -} - -U_BOOT_CMD( - cls, 1, 1, lcd_clear, - "cls - clear screen\n", - NULL -); - -/*----------------------------------------------------------------------*/ - -static int lcd_init (void *lcdbase) -{ - /* Initialize the lcd controller */ - debug ("[LCD] Initializing LCD frambuffer at %p\n", lcdbase); - - lcd_ctrl_init (lcdbase); - lcd_clear (NULL, 1, 1, NULL); /* dummy args */ - lcd_enable (); - - /* Initialize the console */ - console_col = 0; -#ifdef CONFIG_LCD_INFO_BELOW_LOGO - console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT; -#else - console_row = 1; /* leave 1 blank line below logo */ -#endif - lcd_is_enabled = 1; - - return 0; -} - - -/************************************************************************/ -/* ** ROM capable initialization part - needed to reserve FB memory */ -/************************************************************************/ -/* - * This is called early in the system initialization to grab memory - * for the LCD controller. - * Returns new address for monitor, after reserving LCD buffer memory - * - * Note that this is running from ROM, so no write access to global data. - */ -ulong lcd_setmem (ulong addr) -{ - ulong size; - int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8; - - debug ("LCD panel info: %d x %d, %d bit/pix\n", - panel_info.vl_col, panel_info.vl_row, NBITS (panel_info.vl_bpix) ); - - size = line_length * panel_info.vl_row; - - /* Round up to nearest full page */ - size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); - - /* Allocate pages for the frame buffer. */ - addr -= size; - - debug ("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr); - - return (addr); -} - -/*----------------------------------------------------------------------*/ - -static void lcd_setfgcolor (int color) -{ - lcd_color_fg = color & 0x0F; -} - -/*----------------------------------------------------------------------*/ - -static void lcd_setbgcolor (int color) -{ - lcd_color_bg = color & 0x0F; -} - -/*----------------------------------------------------------------------*/ - -#ifdef NOT_USED_SO_FAR -static int lcd_getfgcolor (void) -{ - return lcd_color_fg; -} -#endif /* NOT_USED_SO_FAR */ - -/*----------------------------------------------------------------------*/ - -static int lcd_getbgcolor (void) -{ - return lcd_color_bg; -} - -/*----------------------------------------------------------------------*/ - -/************************************************************************/ -/* ** Chipset depending Bitmap / Logo stuff... */ -/************************************************************************/ -#ifdef CONFIG_LCD_LOGO -void bitmap_plot (int x, int y) -{ - ushort *cmap; - ushort i, j; - uchar *bmap; - uchar *fb; - ushort *fb16; -#if defined(CONFIG_PXA250) - struct pxafb_info *fbi = &panel_info.pxa; -#elif defined(CONFIG_MPC823) - volatile immap_t *immr = (immap_t *) CFG_IMMR; - volatile cpm8xx_t *cp = &(immr->im_cpm); -#endif - - debug ("Logo: width %d height %d colors %d cmap %d\n", - BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS, - sizeof(bmp_logo_palette)/(sizeof(ushort))); - - bmap = &bmp_logo_bitmap[0]; - fb = (uchar *)(lcd_base + y * lcd_line_length + x); - - if (NBITS(panel_info.vl_bpix) < 12) { - /* Leave room for default color map */ -#if defined(CONFIG_PXA250) - cmap = (ushort *)fbi->palette; -#elif defined(CONFIG_MPC823) - cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]); -#endif - - WATCHDOG_RESET(); - - /* Set color map */ - for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(ushort))); ++i) { - ushort colreg = bmp_logo_palette[i]; -#ifdef CFG_INVERT_COLORS - *cmap++ = 0xffff - colreg; -#else - *cmap++ = colreg; -#endif - } - - WATCHDOG_RESET(); - - for (i=0; i<BMP_LOGO_HEIGHT; ++i) { - memcpy (fb, bmap, BMP_LOGO_WIDTH); - bmap += BMP_LOGO_WIDTH; - fb += panel_info.vl_col; - } - } - else { /* true color mode */ - fb16 = (ushort *)(lcd_base + y * lcd_line_length + x); - for (i=0; i<BMP_LOGO_HEIGHT; ++i) { - for (j=0; j<BMP_LOGO_WIDTH; j++) { - fb16[j] = bmp_logo_palette[(bmap[j])]; - } - bmap += BMP_LOGO_WIDTH; - fb16 += panel_info.vl_col; - } - } - - WATCHDOG_RESET(); -} -#endif /* CONFIG_LCD_LOGO */ - -/*----------------------------------------------------------------------*/ -#if (CONFIG_COMMANDS & CFG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) -/* - * Display the BMP file located at address bmp_image. - * Only uncompressed. - */ -int lcd_display_bitmap(ulong bmp_image, int x, int y) -{ -#if !defined(CONFIG_MCC200) - ushort *cmap; -#endif - ushort i, j; - uchar *fb; - bmp_image_t *bmp=(bmp_image_t *)bmp_image; - uchar *bmap; - ushort padded_line; - unsigned long width, height; - unsigned long pwidth = panel_info.vl_col; - unsigned colors,bpix; - unsigned long compression; -#if defined(CONFIG_PXA250) - struct pxafb_info *fbi = &panel_info.pxa; -#elif defined(CONFIG_MPC823) - volatile immap_t *immr = (immap_t *) CFG_IMMR; - volatile cpm8xx_t *cp = &(immr->im_cpm); -#endif - - if (!((bmp->header.signature[0]=='B') && - (bmp->header.signature[1]=='M'))) { - printf ("Error: no valid bmp image at %lx\n", bmp_image); - return 1; -} - - width = le32_to_cpu (bmp->header.width); - height = le32_to_cpu (bmp->header.height); - colors = 1<<le16_to_cpu (bmp->header.bit_count); - compression = le32_to_cpu (bmp->header.compression); - - bpix = NBITS(panel_info.vl_bpix); - - if ((bpix != 1) && (bpix != 8)) { - printf ("Error: %d bit/pixel mode not supported by U-Boot\n", - bpix); - return 1; - } - - if (bpix != le16_to_cpu(bmp->header.bit_count)) { - printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n", - bpix, - le16_to_cpu(bmp->header.bit_count)); - return 1; - } - - debug ("Display-bmp: %d x %d with %d colors\n", - (int)width, (int)height, (int)colors); - -#if !defined(CONFIG_MCC200) - /* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */ - if (bpix==8) { -#if defined(CONFIG_PXA250) - cmap = (ushort *)fbi->palette; -#elif defined(CONFIG_MPC823) - cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]); -#else -# error "Don't know location of color map" -#endif - - /* Set color map */ - for (i=0; i<colors; ++i) { - bmp_color_table_entry_t cte = bmp->color_table[i]; - ushort colreg = - ( ((cte.red) << 8) & 0xf800) | - ( ((cte.green) << 3) & 0x07e0) | - ( ((cte.blue) >> 3) & 0x001f) ; -#ifdef CFG_INVERT_COLORS - *cmap = 0xffff - colreg; -#else - *cmap = colreg; -#endif -#if defined(CONFIG_PXA250) - cmap++; -#elif defined(CONFIG_MPC823) - cmap--; -#endif - } - } -#endif - - /* - * BMP format for Monochrome assumes that the state of a - * pixel is described on a per Bit basis, not per Byte. - * So, in case of Monochrome BMP we should align widths - * on a byte boundary and convert them from Bit to Byte - * units. - * Probably, PXA250 and MPC823 process 1bpp BMP images in - * their own ways, so make the converting to be MCC200 - * specific. - */ -#if defined(CONFIG_MCC200) - if (bpix==1) - { - width = ((width + 7) & ~7) >> 3; - x = ((x + 7) & ~7) >> 3; - pwidth= ((pwidth + 7) & ~7) >> 3; - } -#endif - - padded_line = (width&0x3) ? ((width&~0x3)+4) : (width); - if ((x + width)>pwidth) - width = pwidth - x; - if ((y + height)>panel_info.vl_row) - height = panel_info.vl_row - y; - - bmap = (uchar *)bmp + le32_to_cpu (bmp->header.data_offset); - fb = (uchar *) (lcd_base + - (y + height - 1) * lcd_line_length + x); - for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); - for (j = 0; j < width ; j++) -#if defined(CONFIG_PXA250) - *(fb++)=*(bmap++); -#elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200) - *(fb++)=255-*(bmap++); -#endif - bmap += (width - padded_line); - fb -= (width + lcd_line_length); - } - - return (0); -} -#endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) || CONFIG_SPLASH_SCREEN */ - - -static void *lcd_logo (void) -{ -#ifdef CONFIG_LCD_INFO - char info[80]; - char temp[32]; -#endif /* CONFIG_LCD_INFO */ - -#ifdef CONFIG_SPLASH_SCREEN - char *s; - ulong addr; - static int do_splash = 1; - - if (do_splash && (s = getenv("splashimage")) != NULL) { - addr = simple_strtoul(s, NULL, 16); - do_splash = 0; - - if (lcd_display_bitmap (addr, 0, 0) == 0) { - return ((void *)lcd_base); - } - } -#endif /* CONFIG_SPLASH_SCREEN */ - -#ifdef CONFIG_LCD_LOGO - bitmap_plot (0, 0); -#endif /* CONFIG_LCD_LOGO */ - -#ifdef CONFIG_MPC823 -# ifdef CONFIG_LCD_INFO - sprintf (info, "%s (%s - %s) ", U_BOOT_VERSION, __DATE__, __TIME__); - lcd_drawchars (LCD_INFO_X, LCD_INFO_Y, (uchar *)info, strlen(info)); - - sprintf (info, "(C) 2004 DENX Software Engineering"); - lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT, - (uchar *)info, strlen(info)); - - sprintf (info, " Wolfgang DENK, wd@denx.de"); - lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 2, - (uchar *)info, strlen(info)); -# ifdef CONFIG_LCD_INFO_BELOW_LOGO - sprintf (info, "MPC823 CPU at %s MHz", - strmhz(temp, gd->cpu_clk)); - lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 3, - info, strlen(info)); - sprintf (info, " %ld MB RAM, %ld MB Flash", - gd->ram_size >> 20, - gd->bd->bi_flashsize >> 20 ); - lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 4, - info, strlen(info)); -# else - /* leave one blank line */ - - sprintf (info, "MPC823 CPU at %s MHz, %ld MB RAM, %ld MB Flash", - strmhz(temp, gd->cpu_clk), - gd->ram_size >> 20, - gd->bd->bi_flashsize >> 20 ); - lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 4, - (uchar *)info, strlen(info)); - -# endif /* CONFIG_LCD_INFO_BELOW_LOGO */ -# endif /* CONFIG_LCD_INFO */ -#endif /* CONFIG_MPC823 */ - -#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) - return ((void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length)); -#else - return ((void *)lcd_base); -#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */ -} - -/************************************************************************/ -/************************************************************************/ - -#endif /* CONFIG_LCD */ diff --git a/common/lynxkdi.c b/common/lynxkdi.c deleted file mode 100644 index 76a271b966..0000000000 --- a/common/lynxkdi.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) Orbacom Systems, Inc <www.orbacom.com> - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - */ - -#include <common.h> -#include <asm/processor.h> -#include <image.h> - -#if defined(CONFIG_LYNXKDI) -#include <lynxkdi.h> - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR) -void lynxkdi_boot ( image_header_t *hdr ) -{ - void (*lynxkdi)(void) = (void(*)(void)) ntohl(hdr->ih_ep); - lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020; - bd_t *kbd; - u32 *psz = (u32 *)(ntohl(hdr->ih_load) + 0x0204); - - memset( parms, 0, sizeof(*parms)); - kbd = gd->bd; - parms->clock_ref = kbd->bi_busfreq; - parms->dramsz = kbd->bi_memsize; - memcpy(parms->ethaddr, kbd->bi_enetaddr, 6); - mtspr(SPRN_SPRG2, 0x0020); - - /* Do a simple check for Bluecat so we can pass the - * kernel command line parameters. - */ - if( le32_to_cpu(*psz) == ntohl(hdr->ih_size) ){ /* FIXME: NOT SURE HERE ! */ - char *args; - char *cmdline = (char *)(ntohl(hdr->ih_load) + 0x020c); - int len; - - printf("Booting Bluecat KDI ...\n"); - udelay(200*1000); /* Allow serial port to flush */ - if ((args = getenv("bootargs")) == NULL) - args = ""; - /* Prepend the cmdline */ - len = strlen(args); - if( len && (len + strlen(cmdline) + 2 < (0x0400 - 0x020c))) { - memmove( cmdline + strlen(args) + 1, cmdline, strlen(cmdline) ); - strcpy( cmdline, args ); - cmdline[len] = ' '; - } - } - else { - printf("Booting LynxOS KDI ...\n"); - } - - lynxkdi(); -} -#else -#error "Lynx KDI support not implemented for configured CPU" -#endif - -#endif /* CONFIG_LYNXKDI */ diff --git a/common/miiphybb.c b/common/miiphybb.c deleted file mode 100644 index 537c15d29b..0000000000 --- a/common/miiphybb.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * (C) Copyright 2001 - * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * This provides a bit-banged interface to the ethernet MII management - * channel. - */ - -#include <common.h> -#include <ioports.h> -#include <ppc_asm.tmpl> - -#ifdef CONFIG_BITBANGMII - - -/***************************************************************************** - * - * Utility to send the preamble, address, and register (common to read - * and write). - */ -static void miiphy_pre (char read, unsigned char addr, unsigned char reg) -{ - int j; /* counter */ -#if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM)) - volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT); -#endif - - /* - * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure. - * The IEEE spec says this is a PHY optional requirement. The AMD - * 79C874 requires one after power up and one after a MII communications - * error. This means that we are doing more preambles than we need, - * but it is safer and will be much more robust. - */ - - MDIO_ACTIVE; - MDIO (1); - for (j = 0; j < 32; j++) { - MDC (0); - MIIDELAY; - MDC (1); - MIIDELAY; - } - - /* send the start bit (01) and the read opcode (10) or write (10) */ - MDC (0); - MDIO (0); - MIIDELAY; - MDC (1); - MIIDELAY; - MDC (0); - MDIO (1); - MIIDELAY; - MDC (1); - MIIDELAY; - MDC (0); - MDIO (read); - MIIDELAY; - MDC (1); - MIIDELAY; - MDC (0); - MDIO (!read); - MIIDELAY; - MDC (1); - MIIDELAY; - - /* send the PHY address */ - for (j = 0; j < 5; j++) { - MDC (0); - if ((addr & 0x10) == 0) { - MDIO (0); - } else { - MDIO (1); - } - MIIDELAY; - MDC (1); - MIIDELAY; - addr <<= 1; - } - - /* send the register address */ - for (j = 0; j < 5; j++) { - MDC (0); - if ((reg & 0x10) == 0) { - MDIO (0); - } else { - MDIO (1); - } - MIIDELAY; - MDC (1); - MIIDELAY; - reg <<= 1; - } -} - - -/***************************************************************************** - * - * Read a MII PHY register. - * - * Returns: - * 0 on success - */ -int bb_miiphy_read (char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - short rdreg; /* register working value */ - int j; /* counter */ -#if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM)) - volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT); -#endif - - miiphy_pre (1, addr, reg); - - /* tri-state our MDIO I/O pin so we can read */ - MDC (0); - MDIO_TRISTATE; - MIIDELAY; - MDC (1); - MIIDELAY; - - /* check the turnaround bit: the PHY should be driving it to zero */ - if (MDIO_READ != 0) { - /* puts ("PHY didn't drive TA low\n"); */ - for (j = 0; j < 32; j++) { - MDC (0); - MIIDELAY; - MDC (1); - MIIDELAY; - } - return (-1); - } - - MDC (0); - MIIDELAY; - - /* read 16 bits of register data, MSB first */ - rdreg = 0; - for (j = 0; j < 16; j++) { - MDC (1); - MIIDELAY; - rdreg <<= 1; - rdreg |= MDIO_READ; - MDC (0); - MIIDELAY; - } - - MDC (1); - MIIDELAY; - MDC (0); - MIIDELAY; - MDC (1); - MIIDELAY; - - *value = rdreg; - -#ifdef DEBUG - printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value); -#endif - - return 0; -} - - -/***************************************************************************** - * - * Write a MII PHY register. - * - * Returns: - * 0 on success - */ -int bb_miiphy_write (char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - int j; /* counter */ -#if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM)) - volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT); -#endif - - miiphy_pre (0, addr, reg); - - /* send the turnaround (10) */ - MDC (0); - MDIO (1); - MIIDELAY; - MDC (1); - MIIDELAY; - MDC (0); - MDIO (0); - MIIDELAY; - MDC (1); - MIIDELAY; - - /* write 16 bits of register data, MSB first */ - for (j = 0; j < 16; j++) { - MDC (0); - if ((value & 0x00008000) == 0) { - MDIO (0); - } else { - MDIO (1); - } - MIIDELAY; - MDC (1); - MIIDELAY; - value <<= 1; - } - - /* - * Tri-state the MDIO line. - */ - MDIO_TRISTATE; - MDC (0); - MIIDELAY; - MDC (1); - MIIDELAY; - - return 0; -} - -#endif /* CONFIG_BITBANGMII */ diff --git a/common/miiphyutil.c b/common/miiphyutil.c deleted file mode 100644 index e411e573c7..0000000000 --- a/common/miiphyutil.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * (C) Copyright 2001 - * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * This provides a bit-banged interface to the ethernet MII management - * channel. - */ - -#include <common.h> -#include <miiphy.h> - -#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) -#include <asm/types.h> -#include <linux/list.h> -#include <malloc.h> -#include <net.h> - -/* local debug macro */ -#define MII_DEBUG -#undef MII_DEBUG - -#undef debug -#ifdef MII_DEBUG -#define debug(fmt,args...) printf (fmt ,##args) -#else -#define debug(fmt,args...) -#endif /* MII_DEBUG */ - -struct mii_dev { - struct list_head link; - char *name; - int (* read)(char *devname, unsigned char addr, - unsigned char reg, unsigned short *value); - int (* write)(char *devname, unsigned char addr, - unsigned char reg, unsigned short value); -}; - -static struct list_head mii_devs; -static struct mii_dev *current_mii; - -/***************************************************************************** - * - * Initialize global data. Need to be called before any other miiphy routine. - */ -void miiphy_init() -{ - INIT_LIST_HEAD(&mii_devs); - current_mii = NULL; -} - -/***************************************************************************** - * - * Register read and write MII access routines for the device <name>. - */ -void miiphy_register(char *name, - int (* read)(char *devname, unsigned char addr, - unsigned char reg, unsigned short *value), - int (* write)(char *devname, unsigned char addr, - unsigned char reg, unsigned short value)) -{ - struct list_head *entry; - struct mii_dev *new_dev; - struct mii_dev *miidev; - unsigned int name_len; - - /* check if we have unique name */ - list_for_each(entry, &mii_devs) { - miidev = list_entry(entry, struct mii_dev, link); - if (strcmp(miidev->name, name) == 0) { - printf("miiphy_register: non unique device name '%s'\n", - name); - return; - } - } - - /* allocate memory */ - name_len = strlen(name); - new_dev = (struct mii_dev *)malloc(sizeof(struct mii_dev) + name_len + 1); - - if(new_dev == NULL) { - printf("miiphy_register: cannot allocate memory for '%s'\n", - name); - return; - } - memset(new_dev, 0, sizeof(struct mii_dev) + name_len); - - /* initalize mii_dev struct fields */ - INIT_LIST_HEAD(&new_dev->link); - new_dev->read = read; - new_dev->write = write; - new_dev->name = (char *)(new_dev + 1); - strncpy(new_dev->name, name, name_len); - new_dev->name[name_len] = '\0'; - - debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n", - new_dev->name, new_dev->read, new_dev->write); - - /* add it to the list */ - list_add_tail(&new_dev->link, &mii_devs); - - if (!current_mii) - current_mii = new_dev; -} - -int miiphy_set_current_dev(char *devname) -{ - struct list_head *entry; - struct mii_dev *dev; - - list_for_each(entry, &mii_devs) { - dev = list_entry(entry, struct mii_dev, link); - - if (strcmp(devname, dev->name) == 0) { - current_mii = dev; - return 0; - } - } - - printf("No such device: %s\n", devname); - return 1; -} - -char *miiphy_get_current_dev() -{ - if (current_mii) - return current_mii->name; - - return NULL; -} - -/***************************************************************************** - * - * Read to variable <value> from the PHY attached to device <devname>, - * use PHY address <addr> and register <reg>. - * - * Returns: - * 0 on success - */ -int miiphy_read(char *devname, unsigned char addr, unsigned char reg, - unsigned short *value) -{ - struct list_head *entry; - struct mii_dev *dev; - int found_dev = 0; - int read_ret = 0; - - if (!devname) { - printf("NULL device name!\n"); - return 1; - } - - list_for_each(entry, &mii_devs) { - dev = list_entry(entry, struct mii_dev, link); - - if (strcmp(devname, dev->name) == 0) { - found_dev = 1; - read_ret = dev->read(devname, addr, reg, value); - break; - } - } - - if (found_dev == 0) - printf("No such device: %s\n", devname); - - return ((found_dev) ? read_ret : 1); -} - -/***************************************************************************** - * - * Write <value> to the PHY attached to device <devname>, - * use PHY address <addr> and register <reg>. - * - * Returns: - * 0 on success - */ -int miiphy_write(char *devname, unsigned char addr, unsigned char reg, - unsigned short value) -{ - struct list_head *entry; - struct mii_dev *dev; - int found_dev = 0; - int write_ret = 0; - - if (!devname) { - printf("NULL device name!\n"); - return 1; - } - - list_for_each(entry, &mii_devs) { - dev = list_entry(entry, struct mii_dev, link); - - if (strcmp(devname, dev->name) == 0) { - found_dev = 1; - write_ret = dev->write(devname, addr, reg, value); - break; - } - } - - if (found_dev == 0) - printf("No such device: %s\n", devname); - - return ((found_dev) ? write_ret : 1); -} - -/***************************************************************************** - * - * Print out list of registered MII capable devices. - */ -void miiphy_listdev(void) -{ - struct list_head *entry; - struct mii_dev *dev; - - puts("MII devices: "); - list_for_each(entry, &mii_devs) { - dev = list_entry(entry, struct mii_dev, link); - printf("'%s' ", dev->name); - } - puts("\n"); - - if (current_mii) - printf("Current device: '%s'\n", current_mii->name); -} - - -/***************************************************************************** - * - * Read the OUI, manufacture's model number, and revision number. - * - * OUI: 22 bits (unsigned int) - * Model: 6 bits (unsigned char) - * Revision: 4 bits (unsigned char) - * - * Returns: - * 0 on success - */ -int miiphy_info (char *devname, - unsigned char addr, - unsigned int *oui, - unsigned char *model, unsigned char *rev) -{ - unsigned int reg = 0; - unsigned short tmp; - - if (miiphy_read (devname, addr, PHY_PHYIDR2, &tmp) != 0) { -#ifdef DEBUG - puts ("PHY ID register 2 read failed\n"); -#endif - return (-1); - } - reg = tmp; - -#ifdef DEBUG - printf ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg); -#endif - if (reg == 0xFFFF) { - /* No physical device present at this address */ - return (-1); - } - - if (miiphy_read (devname, addr, PHY_PHYIDR1, &tmp) != 0) { -#ifdef DEBUG - puts ("PHY ID register 1 read failed\n"); -#endif - return (-1); - } - reg |= tmp << 16; -#ifdef DEBUG - printf ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg); -#endif - *oui = ( reg >> 10); - *model = (unsigned char) ((reg >> 4) & 0x0000003F); - *rev = (unsigned char) ( reg & 0x0000000F); - return (0); -} - - -/***************************************************************************** - * - * Reset the PHY. - * Returns: - * 0 on success - */ -int miiphy_reset (char *devname, unsigned char addr) -{ - unsigned short reg; - int loop_cnt; - - if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { -#ifdef DEBUG - printf ("PHY status read failed\n"); -#endif - return (-1); - } - if (miiphy_write (devname, addr, PHY_BMCR, reg | 0x8000) != 0) { -#ifdef DEBUG - puts ("PHY reset failed\n"); -#endif - return (-1); - } -#ifdef CONFIG_PHY_RESET_DELAY - udelay (CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */ -#endif - /* - * Poll the control register for the reset bit to go to 0 (it is - * auto-clearing). This should happen within 0.5 seconds per the - * IEEE spec. - */ - loop_cnt = 0; - reg = 0x8000; - while (((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) { - if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { -# ifdef DEBUG - puts ("PHY status read failed\n"); -# endif - return (-1); - } - } - if ((reg & 0x8000) == 0) { - return (0); - } else { - puts ("PHY reset timed out\n"); - return (-1); - } - return (0); -} - - -/***************************************************************************** - * - * Determine the ethernet speed (10/100). - */ -int miiphy_speed (char *devname, unsigned char addr) -{ - unsigned short reg; - -#if defined(CONFIG_PHY_GIGE) - if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) { - printf ("PHY 1000BT Status read failed\n"); - } else { - if (reg != 0xFFFF) { - if ((reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) !=0) { - return (_1000BASET); - } - } - } -#endif /* CONFIG_PHY_GIGE */ - - /* Check Basic Management Control Register first. */ - if (miiphy_read (devname, addr, PHY_BMCR, ®)) { - puts ("PHY speed read failed, assuming 10bT\n"); - return (_10BASET); - } - /* Check if auto-negotiation is on. */ - if ((reg & PHY_BMCR_AUTON) != 0) { - /* Get auto-negotiation results. */ - if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) { - puts ("PHY AN speed read failed, assuming 10bT\n"); - return (_10BASET); - } - if ((reg & PHY_ANLPAR_100) != 0) { - return (_100BASET); - } else { - return (_10BASET); - } - } - /* Get speed from basic control settings. */ - else if (reg & PHY_BMCR_100MB) { - return (_100BASET); - } else { - return (_10BASET); - } - -} - - -/***************************************************************************** - * - * Determine full/half duplex. - */ -int miiphy_duplex (char *devname, unsigned char addr) -{ - unsigned short reg; - -#if defined(CONFIG_PHY_GIGE) - if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) { - printf ("PHY 1000BT Status read failed\n"); - } else { - if ( (reg != 0xFFFF) && - (reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) ) { - if ((reg & PHY_1000BTSR_1000FD) !=0) { - return (FULL); - } else { - return (HALF); - } - } - } -#endif /* CONFIG_PHY_GIGE */ - - /* Check Basic Management Control Register first. */ - if (miiphy_read (devname, addr, PHY_BMCR, ®)) { - puts ("PHY duplex read failed, assuming half duplex\n"); - return (HALF); - } - /* Check if auto-negotiation is on. */ - if ((reg & PHY_BMCR_AUTON) != 0) { - /* Get auto-negotiation results. */ - if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) { - puts ("PHY AN duplex read failed, assuming half duplex\n"); - return (HALF); - } - - if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) { - return (FULL); - } else { - return (HALF); - } - } - /* Get speed from basic control settings. */ - else if (reg & PHY_BMCR_DPLX) { - return (FULL); - } else { - return (HALF); - } - -} - -#ifdef CFG_FAULT_ECHO_LINK_DOWN -/***************************************************************************** - * - * Determine link status - */ -int miiphy_link (char *devname, unsigned char addr) -{ - unsigned short reg; - - /* dummy read; needed to latch some phys */ - (void)miiphy_read(devname, addr, PHY_BMSR, ®); - if (miiphy_read (devname, addr, PHY_BMSR, ®)) { - puts ("PHY_BMSR read failed, assuming no link\n"); - return (0); - } - - /* Determine if a link is active */ - if ((reg & PHY_BMSR_LS) != 0) { - return (1); - } else { - return (0); - } -} -#endif - -#endif /* CONFIG_MII || (CONFIG_COMMANDS & CFG_CMD_MII) */ diff --git a/common/soft_i2c.c b/common/soft_i2c.c deleted file mode 100644 index edad51bc41..0000000000 --- a/common/soft_i2c.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * (C) Copyright 2001, 2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * This has been changed substantially by Gerald Van Baren, Custom IDEAS, - * vanbaren@cideas.com. It was heavily influenced by LiMon, written by - * Neil Russell. - */ - -#include <common.h> -#ifdef CONFIG_MPC8260 /* only valid for MPC8260 */ -#include <ioports.h> -#endif -#ifdef CONFIG_AT91RM9200DK /* need this for the at91rm9200dk */ -#include <asm/io.h> -#include <asm/arch/hardware.h> -#endif -#ifdef CONFIG_IXP425 /* only valid for IXP425 */ -#include <asm/arch/ixp425.h> -#endif -#include <i2c.h> - -#if defined(CONFIG_SOFT_I2C) - -/* #define DEBUG_I2C */ - -#ifdef DEBUG_I2C -DECLARE_GLOBAL_DATA_PTR; -#endif - - -/*----------------------------------------------------------------------- - * Definitions - */ - -#define RETRIES 0 - - -#define I2C_ACK 0 /* PD_SDA level to ack a byte */ -#define I2C_NOACK 1 /* PD_SDA level to noack a byte */ - - -#ifdef DEBUG_I2C -#define PRINTD(fmt,args...) do { \ - if (gd->have_console) \ - printf (fmt ,##args); \ - } while (0) -#else -#define PRINTD(fmt,args...) -#endif - -/*----------------------------------------------------------------------- - * Local functions - */ -static void send_reset (void); -static void send_start (void); -static void send_stop (void); -static void send_ack (int); -static int write_byte (uchar byte); -static uchar read_byte (int); - - -/*----------------------------------------------------------------------- - * Send a reset sequence consisting of 9 clocks with the data signal high - * to clock any confused device back into an idle state. Also send a - * <stop> at the end of the sequence for belts & suspenders. - */ -static void send_reset(void) -{ -#ifdef CONFIG_MPC8260 - volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); -#endif -#ifdef CONFIG_8xx - volatile immap_t *immr = (immap_t *)CFG_IMMR; -#endif - int j; - - I2C_SCL(1); - I2C_SDA(1); -#ifdef I2C_INIT - I2C_INIT; -#endif - I2C_TRISTATE; - for(j = 0; j < 9; j++) { - I2C_SCL(0); - I2C_DELAY; - I2C_DELAY; - I2C_SCL(1); - I2C_DELAY; - I2C_DELAY; - } - send_stop(); - I2C_TRISTATE; -} - -/*----------------------------------------------------------------------- - * START: High -> Low on SDA while SCL is High - */ -static void send_start(void) -{ -#ifdef CONFIG_MPC8260 - volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); -#endif -#ifdef CONFIG_8xx - volatile immap_t *immr = (immap_t *)CFG_IMMR; -#endif - - I2C_DELAY; - I2C_SDA(1); - I2C_ACTIVE; - I2C_DELAY; - I2C_SCL(1); - I2C_DELAY; - I2C_SDA(0); - I2C_DELAY; -} - -/*----------------------------------------------------------------------- - * STOP: Low -> High on SDA while SCL is High - */ -static void send_stop(void) -{ -#ifdef CONFIG_MPC8260 - volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); -#endif -#ifdef CONFIG_8xx - volatile immap_t *immr = (immap_t *)CFG_IMMR; -#endif - - I2C_SCL(0); - I2C_DELAY; - I2C_SDA(0); - I2C_ACTIVE; - I2C_DELAY; - I2C_SCL(1); - I2C_DELAY; - I2C_SDA(1); - I2C_DELAY; - I2C_TRISTATE; -} - - -/*----------------------------------------------------------------------- - * ack should be I2C_ACK or I2C_NOACK - */ -static void send_ack(int ack) -{ -#ifdef CONFIG_MPC8260 - volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); -#endif -#ifdef CONFIG_8xx - volatile immap_t *immr = (immap_t *)CFG_IMMR; -#endif - - I2C_SCL(0); - I2C_DELAY; - I2C_ACTIVE; - I2C_SDA(ack); - I2C_DELAY; - I2C_SCL(1); - I2C_DELAY; - I2C_DELAY; - I2C_SCL(0); - I2C_DELAY; -} - - -/*----------------------------------------------------------------------- - * Send 8 bits and look for an acknowledgement. - */ -static int write_byte(uchar data) -{ -#ifdef CONFIG_MPC8260 - volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); -#endif -#ifdef CONFIG_8xx - volatile immap_t *immr = (immap_t *)CFG_IMMR; -#endif - int j; - int nack; - - I2C_ACTIVE; - for(j = 0; j < 8; j++) { - I2C_SCL(0); - I2C_DELAY; - I2C_SDA(data & 0x80); - I2C_DELAY; - I2C_SCL(1); - I2C_DELAY; - I2C_DELAY; - - data <<= 1; - } - - /* - * Look for an <ACK>(negative logic) and return it. - */ - I2C_SCL(0); - I2C_DELAY; - I2C_SDA(1); - I2C_TRISTATE; - I2C_DELAY; - I2C_SCL(1); - I2C_DELAY; - I2C_DELAY; - nack = I2C_READ; - I2C_SCL(0); - I2C_DELAY; - I2C_ACTIVE; - - return(nack); /* not a nack is an ack */ -} - - -/*----------------------------------------------------------------------- - * if ack == I2C_ACK, ACK the byte so can continue reading, else - * send I2C_NOACK to end the read. - */ -static uchar read_byte(int ack) -{ -#ifdef CONFIG_MPC8260 - volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); -#endif -#ifdef CONFIG_8xx - volatile immap_t *immr = (immap_t *)CFG_IMMR; -#endif - int data; - int j; - - /* - * Read 8 bits, MSB first. - */ - I2C_TRISTATE; - data = 0; - for(j = 0; j < 8; j++) { - I2C_SCL(0); - I2C_DELAY; - I2C_SCL(1); - I2C_DELAY; - data <<= 1; - data |= I2C_READ; - I2C_DELAY; - } - send_ack(ack); - - return(data); -} - -/*=====================================================================*/ -/* Public Functions */ -/*=====================================================================*/ - -/*----------------------------------------------------------------------- - * Initialization - */ -void i2c_init (int speed, int slaveaddr) -{ - /* - * WARNING: Do NOT save speed in a static variable: if the - * I2C routines are called before RAM is initialized (to read - * the DIMM SPD, for instance), RAM won't be usable and your - * system will crash. - */ - send_reset (); -} - -/*----------------------------------------------------------------------- - * Probe to see if a chip is present. Also good for checking for the - * completion of EEPROM writes since the chip stops responding until - * the write completes (typically 10mSec). - */ -int i2c_probe(uchar addr) -{ - int rc; - - /* - * perform 1 byte write transaction with just address byte - * (fake write) - */ - send_start(); - rc = write_byte ((addr << 1) | 0); - send_stop(); - - return (rc ? 1 : 0); -} - -/*----------------------------------------------------------------------- - * Read bytes - */ -int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) -{ - int shift; - PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n", - chip, addr, alen, buffer, len); - -#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW - /* - * EEPROM chips that implement "address overflow" are ones - * like Catalyst 24WC04/08/16 which has 9/10/11 bits of - * address and the extra bits end up in the "chip address" - * bit slots. This makes a 24WC08 (1Kbyte) chip look like - * four 256 byte chips. - * - * Note that we consider the length of the address field to - * still be one byte because the extra address bits are - * hidden in the chip address. - */ - chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW); - - PRINTD("i2c_read: fix addr_overflow: chip %02X addr %02X\n", - chip, addr); -#endif - - /* - * Do the addressing portion of a write cycle to set the - * chip's address pointer. If the address length is zero, - * don't do the normal write cycle to set the address pointer, - * there is no address pointer in this chip. - */ - send_start(); - if(alen > 0) { - if(write_byte(chip << 1)) { /* write cycle */ - send_stop(); - PRINTD("i2c_read, no chip responded %02X\n", chip); - return(1); - } - shift = (alen-1) * 8; - while(alen-- > 0) { - if(write_byte(addr >> shift)) { - PRINTD("i2c_read, address not <ACK>ed\n"); - return(1); - } - shift -= 8; - } - send_stop(); /* reportedly some chips need a full stop */ - send_start(); - } - /* - * Send the chip address again, this time for a read cycle. - * Then read the data. On the last byte, we do a NACK instead - * of an ACK(len == 0) to terminate the read. - */ - write_byte((chip << 1) | 1); /* read cycle */ - while(len-- > 0) { - *buffer++ = read_byte(len == 0); - } - send_stop(); - return(0); -} - -/*----------------------------------------------------------------------- - * Write bytes - */ -int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) -{ - int shift, failures = 0; - - PRINTD("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n", - chip, addr, alen, buffer, len); - - send_start(); - if(write_byte(chip << 1)) { /* write cycle */ - send_stop(); - PRINTD("i2c_write, no chip responded %02X\n", chip); - return(1); - } - shift = (alen-1) * 8; - while(alen-- > 0) { - if(write_byte(addr >> shift)) { - PRINTD("i2c_write, address not <ACK>ed\n"); - return(1); - } - shift -= 8; - } - - while(len-- > 0) { - if(write_byte(*buffer++)) { - failures++; - } - } - send_stop(); - return(failures); -} - -/*----------------------------------------------------------------------- - * Read a register - */ -uchar i2c_reg_read(uchar i2c_addr, uchar reg) -{ - uchar buf; - - i2c_read(i2c_addr, reg, 1, &buf, 1); - - return(buf); -} - -/*----------------------------------------------------------------------- - * Write a register - */ -void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) -{ - i2c_write(i2c_addr, reg, 1, &val, 1); -} - - -#endif /* CONFIG_SOFT_I2C */ diff --git a/common/soft_spi.c b/common/soft_spi.c deleted file mode 100644 index 00a57de8aa..0000000000 --- a/common/soft_spi.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * (C) Copyright 2002 - * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. - * - * Influenced by code from: - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <spi.h> - -#if defined(CONFIG_SOFT_SPI) - -/*----------------------------------------------------------------------- - * Definitions - */ - -#ifdef DEBUG_SPI -#define PRINTD(fmt,args...) printf (fmt ,##args) -#else -#define PRINTD(fmt,args...) -#endif - - -/*=====================================================================*/ -/* Public Functions */ -/*=====================================================================*/ - -/*----------------------------------------------------------------------- - * Initialization - */ -void spi_init (void) -{ -#ifdef SPI_INIT - volatile immap_t *immr = (immap_t *)CFG_IMMR; - - SPI_INIT; -#endif -} - - -/*----------------------------------------------------------------------- - * SPI transfer - * - * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks - * "bitlen" bits in the SPI MISO port. That's just the way SPI works. - * - * The source of the outgoing bits is the "dout" parameter and the - * destination of the input bits is the "din" parameter. Note that "dout" - * and "din" can point to the same memory location, in which case the - * input data overwrites the output data (since both are buffered by - * temporary variables, this is OK). - * - * If the chipsel() function is not NULL, it is called with a parameter - * of '1' (chip select active) at the start of the transfer and again with - * a parameter of '0' at the end of the transfer. - * - * If the chipsel() function _is_ NULL, it the responsibility of the - * caller to make the appropriate chip select active before calling - * spi_xfer() and making it inactive after spi_xfer() returns. - */ -int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - uchar tmpdin = 0; - uchar tmpdout = 0; - int j; - - PRINTD("spi_xfer: chipsel %08X dout %08X din %08X bitlen %d\n", - (int)chipsel, *(uint *)dout, *(uint *)din, bitlen); - - if(chipsel != NULL) { - (*chipsel)(1); /* select the target chip */ - } - - for(j = 0; j < bitlen; j++) { - /* - * Check if it is time to work on a new byte. - */ - if((j % 8) == 0) { - tmpdout = *dout++; - if(j != 0) { - *din++ = tmpdin; - } - tmpdin = 0; - } - SPI_SCL(0); - SPI_SDA(tmpdout & 0x80); - SPI_DELAY; - SPI_SCL(1); - SPI_DELAY; - tmpdin <<= 1; - tmpdin |= SPI_READ; - tmpdout <<= 1; - } - /* - * If the number of bits isn't a multiple of 8, shift the last - * bits over to left-justify them. Then store the last byte - * read in. - */ - if((bitlen % 8) != 0) - tmpdin <<= 8 - (bitlen % 8); - *din++ = tmpdin; - - SPI_SCL(0); /* SPI wants the clock left low for idle */ - - if(chipsel != NULL) { - (*chipsel)(0); /* deselect the target chip */ - - } - - return(0); -} - -#endif /* CONFIG_SOFT_SPI */ diff --git a/common/spartan2.c b/common/spartan2.c deleted file mode 100644 index 0fb23b6592..0000000000 --- a/common/spartan2.c +++ /dev/null @@ -1,653 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include <common.h> /* core U-Boot definitions */ -#include <spartan2.h> /* Spartan-II device family */ - -#if (CONFIG_FPGA & (CFG_XILINX | CFG_SPARTAN2)) - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -#undef CFG_FPGA_CHECK_BUSY -#undef CFG_FPGA_PROG_FEEDBACK - -/* Note: The assumption is that we cannot possibly run fast enough to - * overrun the device (the Slave Parallel mode can free run at 50MHz). - * If there is a need to operate slower, define CONFIG_FPGA_DELAY in - * the board config file to slow things down. - */ -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CFG_FPGA_WAIT -#define CFG_FPGA_WAIT CFG_HZ/100 /* 10 ms */ -#endif - -static int Spartan2_sp_load( Xilinx_desc *desc, void *buf, size_t bsize ); -static int Spartan2_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize ); -/* static int Spartan2_sp_info( Xilinx_desc *desc ); */ -static int Spartan2_sp_reloc( Xilinx_desc *desc, ulong reloc_offset ); - -static int Spartan2_ss_load( Xilinx_desc *desc, void *buf, size_t bsize ); -static int Spartan2_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize ); -/* static int Spartan2_ss_info( Xilinx_desc *desc ); */ -static int Spartan2_ss_reloc( Xilinx_desc *desc, ulong reloc_offset ); - -/* ------------------------------------------------------------------------- */ -/* Spartan-II Generic Implementation */ -int Spartan2_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); - ret_val = Spartan2_ss_load (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); - ret_val = Spartan2_sp_load (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int Spartan2_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); - ret_val = Spartan2_ss_dump (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); - ret_val = Spartan2_sp_dump (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int Spartan2_info( Xilinx_desc *desc ) -{ - return FPGA_SUCCESS; -} - - -int Spartan2_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (desc->family != Xilinx_Spartan2) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case slave_serial: - ret_val = Spartan2_ss_reloc (desc, reloc_offset); - break; - - case slave_parallel: - ret_val = Spartan2_sp_reloc (desc, reloc_offset); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - - -/* ------------------------------------------------------------------------- */ -/* Spartan-II Slave Parallel Generic Implementation */ - -static int Spartan2_sp_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "pre: 0x%p\n" - "pgm:\t0x%p\n" - "init:\t0x%p\n" - "err:\t0x%p\n" - "clk:\t0x%p\n" - "cs:\t0x%p\n" - "wr:\t0x%p\n" - "read data:\t0x%p\n" - "write data:\t0x%p\n" - "busy:\t0x%p\n" - "abort:\t0x%p\n", - "post:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err, - fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy, - fn->abort, fn->post); - - /* - * This code is designed to emulate the "Express Style" - * Continuous Data Loading in Slave Parallel Mode for - * the Spartan-II Family. - */ -#ifdef CFG_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...\n", cookie); -#endif - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ - - ts = get_timer (0); /* get current time */ - /* Now wait for INIT and BUSY to go high */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - return FPGA_FAIL; - } - } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); - - (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */ - (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - /* Load the data */ - while (bytecount < bsize) { - /* XXX - do we check for an Ctrl-C press in here ??? */ - /* XXX - Check the error bit? */ - - (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - -#ifdef CFG_FPGA_CHECK_BUSY - ts = get_timer (0); /* get current time */ - while ((*fn->busy) (cookie)) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for BUSY to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - return FPGA_FAIL; - } - } -#endif - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */ - (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */ - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - - /* now check for done signal */ - ts = get_timer (0); /* get current time */ - ret_val = FPGA_SUCCESS; - while ((*fn->done) (cookie) == FPGA_FAIL) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for DONE to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - ret_val = FPGA_FAIL; - break; - } - } - - if (ret_val == FPGA_SUCCESS) { -#ifdef CFG_FPGA_PROG_FEEDBACK - puts ("Done.\n"); -#endif - } - /* - * Run the post configuration function if there is one. - */ - if (*fn->post) { - (*fn->post) (cookie); - } - - else { -#ifdef CFG_FPGA_PROG_FEEDBACK - puts ("Fail.\n"); -#endif - } - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int Spartan2_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns; - - if (fn) { - unsigned char *data = (unsigned char *) buf; - size_t bytecount = 0; - int cookie = desc->cookie; /* make a local copy */ - - printf ("Starting Dump of FPGA Device %d...\n", cookie); - - (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - /* dump the data */ - while (bytecount < bsize) { - /* XXX - do we check for an Ctrl-C press in here ??? */ - - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */ -#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */ - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - puts ("Done.\n"); - - /* XXX - checksum the data? */ - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - - -static int Spartan2_sp_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Parallel_fns *fn_r, *fn = - (Xilinx_Spartan2_Slave_Parallel_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Spartan2_Slave_Parallel_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Xilinx_Spartan2_Slave_Parallel_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - - addr = (ulong) (fn->err) + reloc_offset; - fn_r->err = (Xilinx_err_fn) addr; - - addr = (ulong) (fn->cs) + reloc_offset; - fn_r->cs = (Xilinx_cs_fn) addr; - - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - - addr = (ulong) (fn->rdata) + reloc_offset; - fn_r->rdata = (Xilinx_rdata_fn) addr; - - addr = (ulong) (fn->wdata) + reloc_offset; - fn_r->wdata = (Xilinx_wdata_fn) addr; - - addr = (ulong) (fn->busy) + reloc_offset; - fn_r->busy = (Xilinx_busy_fn) addr; - - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Xilinx_abort_fn) addr; - - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Xilinx_post_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} - -/* ------------------------------------------------------------------------- */ - -static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Serial_fns *fn = desc->iface_fns; - int i; - char val; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "pgm:\t0x%p\n" - "init:\t0x%p\n" - "clk:\t0x%p\n" - "wr:\t0x%p\n" - "done:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->pgm, fn->init, - fn->clk, fn->wr, fn->done); -#ifdef CFG_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...\n", cookie); -#endif - - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ - - /* Wait for INIT state (init low) */ - ts = get_timer (0); /* get current time */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to start.\n"); - return FPGA_FAIL; - } - } while (!(*fn->init) (cookie)); - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ - - ts = get_timer (0); /* get current time */ - /* Now wait for INIT to go high */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to clear.\n"); - return FPGA_FAIL; - } - } while ((*fn->init) (cookie)); - - /* Load the data */ - while (bytecount < bsize) { - - /* Xilinx detects an error if INIT goes low (active) - while DONE is low (inactive) */ - if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { - puts ("** CRC error during FPGA load.\n"); - return (FPGA_FAIL); - } - val = data [bytecount ++]; - i = 8; - do { - /* Deassert the clock */ - (*fn->clk) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Write data */ - (*fn->wr) ((val < 0), TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Assert the clock */ - (*fn->clk) (TRUE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - val <<= 1; - i --; - } while (i > 0); - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - - /* now check for done signal */ - ts = get_timer (0); /* get current time */ - ret_val = FPGA_SUCCESS; - (*fn->wr) (TRUE, TRUE, cookie); - - while (! (*fn->done) (cookie)) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - putc ('*'); - - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for DONE to clear.\n"); - ret_val = FPGA_FAIL; - break; - } - } - putc ('\n'); /* terminate the dotted line */ - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) { - puts ("Done.\n"); - } - else { - puts ("Fail.\n"); - } -#endif - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int Spartan2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - /* Readback is only available through the Slave Parallel and */ - /* boundary-scan interfaces. */ - printf ("%s: Slave Serial Dumping is unavailable\n", - __FUNCTION__); - return FPGA_FAIL; -} - -static int Spartan2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Serial_fns *fn_r, *fn = - (Xilinx_Spartan2_Slave_Serial_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Spartan2_Slave_Serial_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Xilinx_Spartan2_Slave_Serial_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} - -#endif diff --git a/common/spartan3.c b/common/spartan3.c deleted file mode 100644 index c0f2b05e48..0000000000 --- a/common/spartan3.c +++ /dev/null @@ -1,658 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Configuration support for Xilinx Spartan3 devices. Based - * on spartan2.c (Rich Ireland, rireland@enterasys.com). - */ - -#include <common.h> /* core U-Boot definitions */ -#include <spartan3.h> /* Spartan-II device family */ - -#if (CONFIG_FPGA & (CFG_XILINX | CFG_SPARTAN3)) - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -#undef CFG_FPGA_CHECK_BUSY -#undef CFG_FPGA_PROG_FEEDBACK - -/* Note: The assumption is that we cannot possibly run fast enough to - * overrun the device (the Slave Parallel mode can free run at 50MHz). - * If there is a need to operate slower, define CONFIG_FPGA_DELAY in - * the board config file to slow things down. - */ -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CFG_FPGA_WAIT -#define CFG_FPGA_WAIT CFG_HZ/100 /* 10 ms */ -#endif - -static int Spartan3_sp_load( Xilinx_desc *desc, void *buf, size_t bsize ); -static int Spartan3_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize ); -/* static int Spartan3_sp_info( Xilinx_desc *desc ); */ -static int Spartan3_sp_reloc( Xilinx_desc *desc, ulong reloc_offset ); - -static int Spartan3_ss_load( Xilinx_desc *desc, void *buf, size_t bsize ); -static int Spartan3_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize ); -/* static int Spartan3_ss_info( Xilinx_desc *desc ); */ -static int Spartan3_ss_reloc( Xilinx_desc *desc, ulong reloc_offset ); - -/* ------------------------------------------------------------------------- */ -/* Spartan-II Generic Implementation */ -int Spartan3_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); - ret_val = Spartan3_ss_load (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); - ret_val = Spartan3_sp_load (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int Spartan3_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); - ret_val = Spartan3_ss_dump (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); - ret_val = Spartan3_sp_dump (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int Spartan3_info( Xilinx_desc *desc ) -{ - return FPGA_SUCCESS; -} - - -int Spartan3_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (desc->family != Xilinx_Spartan3) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case slave_serial: - ret_val = Spartan3_ss_reloc (desc, reloc_offset); - break; - - case slave_parallel: - ret_val = Spartan3_sp_reloc (desc, reloc_offset); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - - -/* ------------------------------------------------------------------------- */ -/* Spartan-II Slave Parallel Generic Implementation */ - -static int Spartan3_sp_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "pre: 0x%p\n" - "pgm:\t0x%p\n" - "init:\t0x%p\n" - "err:\t0x%p\n" - "clk:\t0x%p\n" - "cs:\t0x%p\n" - "wr:\t0x%p\n" - "read data:\t0x%p\n" - "write data:\t0x%p\n" - "busy:\t0x%p\n" - "abort:\t0x%p\n", - "post:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err, - fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy, - fn->abort, fn->post); - - /* - * This code is designed to emulate the "Express Style" - * Continuous Data Loading in Slave Parallel Mode for - * the Spartan-II Family. - */ -#ifdef CFG_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...\n", cookie); -#endif - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ - - ts = get_timer (0); /* get current time */ - /* Now wait for INIT and BUSY to go high */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - return FPGA_FAIL; - } - } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); - - (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */ - (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - /* Load the data */ - while (bytecount < bsize) { - /* XXX - do we check for an Ctrl-C press in here ??? */ - /* XXX - Check the error bit? */ - - (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - -#ifdef CFG_FPGA_CHECK_BUSY - ts = get_timer (0); /* get current time */ - while ((*fn->busy) (cookie)) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for BUSY to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - return FPGA_FAIL; - } - } -#endif - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */ - (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */ - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - - /* now check for done signal */ - ts = get_timer (0); /* get current time */ - ret_val = FPGA_SUCCESS; - while ((*fn->done) (cookie) == FPGA_FAIL) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for DONE to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - ret_val = FPGA_FAIL; - break; - } - } - - if (ret_val == FPGA_SUCCESS) { -#ifdef CFG_FPGA_PROG_FEEDBACK - puts ("Done.\n"); -#endif - } - /* - * Run the post configuration function if there is one. - */ - if (*fn->post) { - (*fn->post) (cookie); - } - - else { -#ifdef CFG_FPGA_PROG_FEEDBACK - puts ("Fail.\n"); -#endif - } - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int Spartan3_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns; - - if (fn) { - unsigned char *data = (unsigned char *) buf; - size_t bytecount = 0; - int cookie = desc->cookie; /* make a local copy */ - - printf ("Starting Dump of FPGA Device %d...\n", cookie); - - (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - /* dump the data */ - while (bytecount < bsize) { - /* XXX - do we check for an Ctrl-C press in here ??? */ - - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */ -#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */ - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - puts ("Done.\n"); - - /* XXX - checksum the data? */ - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - - -static int Spartan3_sp_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Parallel_fns *fn_r, *fn = - (Xilinx_Spartan3_Slave_Parallel_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Spartan3_Slave_Parallel_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Xilinx_Spartan3_Slave_Parallel_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - - addr = (ulong) (fn->err) + reloc_offset; - fn_r->err = (Xilinx_err_fn) addr; - - addr = (ulong) (fn->cs) + reloc_offset; - fn_r->cs = (Xilinx_cs_fn) addr; - - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - - addr = (ulong) (fn->rdata) + reloc_offset; - fn_r->rdata = (Xilinx_rdata_fn) addr; - - addr = (ulong) (fn->wdata) + reloc_offset; - fn_r->wdata = (Xilinx_wdata_fn) addr; - - addr = (ulong) (fn->busy) + reloc_offset; - fn_r->busy = (Xilinx_busy_fn) addr; - - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Xilinx_abort_fn) addr; - - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Xilinx_post_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} - -/* ------------------------------------------------------------------------- */ - -static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns; - int i; - char val; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "pgm:\t0x%p\n" - "init:\t0x%p\n" - "clk:\t0x%p\n" - "wr:\t0x%p\n" - "done:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->pgm, fn->init, - fn->clk, fn->wr, fn->done); -#ifdef CFG_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...\n", cookie); -#endif - - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ - - /* Wait for INIT state (init low) */ - ts = get_timer (0); /* get current time */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to start.\n"); - return FPGA_FAIL; - } - } while (!(*fn->init) (cookie)); - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ - - ts = get_timer (0); /* get current time */ - /* Now wait for INIT to go high */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to clear.\n"); - return FPGA_FAIL; - } - } while ((*fn->init) (cookie)); - - /* Load the data */ - while (bytecount < bsize) { - - /* Xilinx detects an error if INIT goes low (active) - while DONE is low (inactive) */ - if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { - puts ("** CRC error during FPGA load.\n"); - return (FPGA_FAIL); - } - val = data [bytecount ++]; - i = 8; - do { - /* Deassert the clock */ - (*fn->clk) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Write data */ - (*fn->wr) ((val < 0), TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Assert the clock */ - (*fn->clk) (TRUE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - val <<= 1; - i --; - } while (i > 0); - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - - /* now check for done signal */ - ts = get_timer (0); /* get current time */ - ret_val = FPGA_SUCCESS; - (*fn->wr) (TRUE, TRUE, cookie); - - while (! (*fn->done) (cookie)) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - putc ('*'); - - if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for DONE to clear.\n"); - ret_val = FPGA_FAIL; - break; - } - } - putc ('\n'); /* terminate the dotted line */ - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) { - puts ("Done.\n"); - } - else { - puts ("Fail.\n"); - } -#endif - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int Spartan3_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - /* Readback is only available through the Slave Parallel and */ - /* boundary-scan interfaces. */ - printf ("%s: Slave Serial Dumping is unavailable\n", - __FUNCTION__); - return FPGA_FAIL; -} - -static int Spartan3_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Serial_fns *fn_r, *fn = - (Xilinx_Spartan3_Slave_Serial_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Spartan3_Slave_Serial_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Xilinx_Spartan3_Slave_Serial_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} - -#endif diff --git a/common/virtex2.c b/common/virtex2.c deleted file mode 100644 index 5d98a5571a..0000000000 --- a/common/virtex2.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * Keith Outwater, keith_outwater@mvis.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Configuration support for Xilinx Virtex2 devices. Based - * on spartan2.c (Rich Ireland, rireland@enterasys.com). - */ - -#include <common.h> -#include <virtex2.h> - -#if (CONFIG_FPGA & (CFG_XILINX | CFG_VIRTEX2)) - - -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* - * If the SelectMap interface can be overrun by the processor, define - * CFG_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration - * file and add board-specific support for checking BUSY status. By default, - * assume that the SelectMap interface cannot be overrun. - */ -#ifndef CFG_FPGA_CHECK_BUSY -#undef CFG_FPGA_CHECK_BUSY -#endif - -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CFG_FPGA_PROG_FEEDBACK -#define CFG_FPGA_PROG_FEEDBACK -#endif - -/* - * Don't allow config cycle to be interrupted - */ -#ifndef CFG_FPGA_CHECK_CTRLC -#undef CFG_FPGA_CHECK_CTRLC -#endif - -/* - * Check for errors during configuration by default - */ -#ifndef CFG_FPGA_CHECK_ERROR -#define CFG_FPGA_CHECK_ERROR -#endif - -/* - * The default timeout in mS for INIT_B to deassert after PROG_B has - * been deasserted. Per the latest Virtex II Handbook (page 347), the - * max time from PORG_B deassertion to INIT_B deassertion is 4uS per - * data frame for the XC2V8000. The XC2V8000 has 2860 data frames - * which yields 11.44 mS. So let's make it bigger in order to handle - * an XC2V1000, if anyone can ever get ahold of one. - */ -#ifndef CFG_FPGA_WAIT_INIT -#define CFG_FPGA_WAIT_INIT CFG_HZ/2 /* 500 ms */ -#endif - -/* - * The default timeout for waiting for BUSY to deassert during configuration. - * This is normally not necessary since for most reasonable configuration - * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary. - */ -#ifndef CFG_FPGA_WAIT_BUSY -#define CFG_FPGA_WAIT_BUSY CFG_HZ/200 /* 5 ms*/ -#endif - -/* Default timeout for waiting for FPGA to enter operational mode after - * configuration data has been written. - */ -#ifndef CFG_FPGA_WAIT_CONFIG -#define CFG_FPGA_WAIT_CONFIG CFG_HZ/5 /* 200 ms */ -#endif - -static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize); -static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize); -static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset); - -static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize); -static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize); -static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset); - -int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); - ret_val = Virtex2_ss_load (desc, buf, bsize); - break; - - case slave_selectmap: - PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); - ret_val = Virtex2_ssm_load (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - return ret_val; -} - -int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); - ret_val = Virtex2_ss_dump (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); - ret_val = Virtex2_ssm_dump (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - return ret_val; -} - -int Virtex2_info (Xilinx_desc * desc) -{ - return FPGA_SUCCESS; -} - -int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; - - if (desc->family != Xilinx_Virtex2) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case slave_serial: - ret_val = Virtex2_ss_reloc (desc, reloc_offset); - break; - - case slave_selectmap: - ret_val = Virtex2_ssm_reloc (desc, reloc_offset); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - return ret_val; -} - -/* - * Virtex-II Slave SelectMap configuration loader. Configuration via - * SelectMap is as follows: - * 1. Set the FPGA's PROG_B line low. - * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high. - * 3. Write data to the SelectMap port. If INIT_B goes low at any time - * this process, a configuration error (most likely CRC failure) has - * ocurred. At this point a status word may be read from the - * SelectMap interface to determine the source of the problem (You - * could, for instance, put this in your 'abort' function handler). - * 4. After all data has been written, test the state of the FPGA - * INIT_B and DONE lines. If both are high, configuration has - * succeeded. Congratulations! - */ -static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; - - PRINTF ("%s:%d: Start with interface functions @ 0x%p\n", - __FUNCTION__, __LINE__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; - unsigned long ts; - - /* Gotta split this one up (so the stack won't blow??) */ - PRINTF ("%s:%d: Function Table:\n" - " base 0x%p\n" - " struct 0x%p\n" - " pre 0x%p\n" - " prog 0x%p\n" - " init 0x%p\n" - " error 0x%p\n", - __FUNCTION__, __LINE__, - &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); - PRINTF (" clock 0x%p\n" - " cs 0x%p\n" - " write 0x%p\n" - " rdata 0x%p\n" - " wdata 0x%p\n" - " busy 0x%p\n" - " abort 0x%p\n" - " post 0x%p\n\n", - fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, - fn->busy, fn->abort, fn->post); - -#ifdef CFG_FPGA_PROG_FEEDBACK - printf ("Initializing FPGA Device %d...\n", cookie); -#endif - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* - * Assert the program line. The minimum pulse width for - * Virtex II devices is 300 nS (Tprogram parameter in datasheet). - * There is no maximum value for the pulse width. Check to make - * sure that INIT_B goes low after assertion of PROG_B - */ - (*fn->pgm) (TRUE, TRUE, cookie); - udelay (10); - ts = get_timer (0); - do { - if (get_timer (ts) > CFG_FPGA_WAIT_INIT) { - printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" - " to assert.\n", __FUNCTION__, __LINE__, - CFG_FPGA_WAIT_INIT); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - } while (!(*fn->init) (cookie)); - - (*fn->pgm) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); - - /* - * Start a timer and wait for INIT_B to go high - */ - ts = get_timer (0); - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CFG_FPGA_WAIT_INIT) { - printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" - " to deassert.\n", __FUNCTION__, __LINE__, - CFG_FPGA_WAIT_INIT); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); - - (*fn->wr) (TRUE, TRUE, cookie); - (*fn->cs) (TRUE, TRUE, cookie); - - udelay (10000); - - /* - * Load the data byte by byte - */ - while (bytecount < bsize) { -#ifdef CFG_FPGA_CHECK_CTRLC - if (ctrlc ()) { - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#endif - - if ((*fn->done) (cookie) == FPGA_SUCCESS) { - PRINTF ("%s:%d:done went active early, bytecount = %d\n", - __FUNCTION__, __LINE__, bytecount); - break; - } - -#ifdef CFG_FPGA_CHECK_ERROR - if ((*fn->init) (cookie)) { - printf ("\n%s:%d: ** Error: INIT asserted during" - " configuration\n", __FUNCTION__, __LINE__); - printf ("%d = buffer offset, %d = buffer size\n", - bytecount, bsize); - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#endif - - (*fn->wdata) (data[bytecount++], TRUE, cookie); - CONFIG_FPGA_DELAY (); - - /* - * Cycle the clock pin - */ - (*fn->clk) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); - -#ifdef CFG_FPGA_CHECK_BUSY - ts = get_timer (0); - while ((*fn->busy) (cookie)) { - if (get_timer (ts) > CFG_FPGA_WAIT_BUSY) { - printf ("%s:%d: ** Timeout after %d ticks waiting for" - " BUSY to deassert\n", - __FUNCTION__, __LINE__, CFG_FPGA_WAIT_BUSY); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - } -#endif - -#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); -#endif - } - - /* - * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. - */ - CONFIG_FPGA_DELAY (); - (*fn->cs) (FALSE, TRUE, cookie); - (*fn->wr) (FALSE, TRUE, cookie); - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc ('\n'); -#endif - - /* - * Check for successful configuration. FPGA INIT_B and DONE should - * both be high upon successful configuration. - */ - ts = get_timer (0); - ret_val = FPGA_SUCCESS; - while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { - if (get_timer (ts) > CFG_FPGA_WAIT_CONFIG) { - printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to" - "assert and INIT to deassert\n", - __FUNCTION__, __LINE__, CFG_FPGA_WAIT_CONFIG); - (*fn->abort) (cookie); - ret_val = FPGA_FAIL; - break; - } - } - - if (ret_val == FPGA_SUCCESS) { -#ifdef CFG_FPGA_PROG_FEEDBACK - printf ("Initialization of FPGA device %d complete\n", cookie); -#endif - /* - * Run the post configuration function if there is one. - */ - if (*fn->post) { - (*fn->post) (cookie); - } - } else { -#ifdef CFG_FPGA_PROG_FEEDBACK - printf ("** Initialization of FPGA device %d FAILED\n", - cookie); -#endif - } - } else { - printf ("%s:%d: NULL Interface function table!\n", - __FUNCTION__, __LINE__); - } - return ret_val; -} - -/* - * Read the FPGA configuration data - */ -static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; - - if (fn) { - unsigned char *data = (unsigned char *) buf; - size_t bytecount = 0; - int cookie = desc->cookie; - - printf ("Starting Dump of FPGA Device %d...\n", cookie); - - (*fn->cs) (TRUE, TRUE, cookie); - (*fn->clk) (TRUE, TRUE, cookie); - - while (bytecount < bsize) { -#ifdef CFG_FPGA_CHECK_CTRLC - if (ctrlc ()) { - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#endif - /* - * Cycle the clock and read the data - */ - (*fn->clk) (FALSE, TRUE, cookie); - (*fn->clk) (TRUE, TRUE, cookie); - (*fn->rdata) (&(data[bytecount++]), cookie); -#ifdef CFG_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); -#endif - } - - /* - * Deassert CS_B and cycle the clock to deselect the device. - */ - (*fn->cs) (FALSE, FALSE, cookie); - (*fn->clk) (FALSE, TRUE, cookie); - (*fn->clk) (TRUE, TRUE, cookie); - -#ifdef CFG_FPGA_PROG_FEEDBACK - putc ('\n'); -#endif - puts ("Done.\n"); - } else { - printf ("%s:%d: NULL Interface function table!\n", - __FUNCTION__, __LINE__); - } - return ret_val; -} - -/* - * Relocate the addresses in the function table from FLASH (or ROM, - * or whatever) to RAM. - */ -static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - ulong addr; - int ret_val = FPGA_FAIL; - Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn = - (Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns); - - if (fn) { - /* - * Get the relocated table address - */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr; - - /* - * Check to see if the table has already been relocated. If not, do - * a sanity check to make sure there is a faithful copy of the - * FLASH based function table in RAM, then adjust the table. - */ - if (!fn_r->relocated) { - if (memcmp - (fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns)) - == 0) { - desc->iface_fns = fn_r; - } else { - PRINTF ("%s:%d: Invalid function table at 0x%p\n", - __FUNCTION__, __LINE__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s:%d: Relocating descriptor at 0x%p\n", - __FUNCTION__, __LINE__, desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - addr = (ulong) (fn->err) + reloc_offset; - fn_r->err = (Xilinx_err_fn) addr; - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - addr = (ulong) (fn->cs) + reloc_offset; - fn_r->cs = (Xilinx_cs_fn) addr; - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - addr = (ulong) (fn->rdata) + reloc_offset; - fn_r->rdata = (Xilinx_rdata_fn) addr; - addr = (ulong) (fn->wdata) + reloc_offset; - fn_r->wdata = (Xilinx_wdata_fn) addr; - addr = (ulong) (fn->busy) + reloc_offset; - fn_r->busy = (Xilinx_busy_fn) addr; - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Xilinx_abort_fn) addr; - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Xilinx_post_fn) addr; - fn_r->relocated = TRUE; - } else { - printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r); - desc->iface_fns = fn_r; - } - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - return ret_val; -} - -static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__); - return FPGA_FAIL; -} - -static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__); - return FPGA_FAIL; -} - -static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; - Xilinx_Virtex2_Slave_Serial_fns *fn = - (Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns); - - if (fn) { - printf ("%s:%d: Slave Serial Loading is unsupported\n", - __FUNCTION__, __LINE__); - } else { - printf ("%s:%d: NULL Interface function table!\n", - __FUNCTION__, __LINE__); - } - return ret_val; -} -#endif - -/* vim: set ts=4 tw=78: */ diff --git a/common/xilinx.c b/common/xilinx.c deleted file mode 100644 index b54c660a24..0000000000 --- a/common/xilinx.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * Keith Outwater, keith_outwater@mvis.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Xilinx FPGA support - */ - -#include <common.h> -#include <virtex2.h> -#include <spartan2.h> -#include <spartan3.h> - -#if (CONFIG_FPGA & CFG_FPGA_XILINX) - - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Local Static Functions */ -static int xilinx_validate (Xilinx_desc * desc, char *fn); - -/* ------------------------------------------------------------------------- */ - -int xilinx_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!xilinx_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else - switch (desc->family) { - case Xilinx_Spartan2: -#if (CONFIG_FPGA & CFG_SPARTAN2) - PRINTF ("%s: Launching the Spartan-II Loader...\n", - __FUNCTION__); - ret_val = Spartan2_load (desc, buf, bsize); -#else - printf ("%s: No support for Spartan-II devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Spartan3: -#if (CONFIG_FPGA & CFG_SPARTAN3) - PRINTF ("%s: Launching the Spartan-III Loader...\n", - __FUNCTION__); - ret_val = Spartan3_load (desc, buf, bsize); -#else - printf ("%s: No support for Spartan-III devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Virtex2: -#if (CONFIG_FPGA & CFG_VIRTEX2) - PRINTF ("%s: Launching the Virtex-II Loader...\n", - __FUNCTION__); - ret_val = Virtex2_load (desc, buf, bsize); -#else - printf ("%s: No support for Virtex-II devices.\n", - __FUNCTION__); -#endif - break; - - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - - return ret_val; -} - -int xilinx_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!xilinx_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else - switch (desc->family) { - case Xilinx_Spartan2: -#if (CONFIG_FPGA & CFG_SPARTAN2) - PRINTF ("%s: Launching the Spartan-II Reader...\n", - __FUNCTION__); - ret_val = Spartan2_dump (desc, buf, bsize); -#else - printf ("%s: No support for Spartan-II devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Spartan3: -#if (CONFIG_FPGA & CFG_SPARTAN3) - PRINTF ("%s: Launching the Spartan-III Reader...\n", - __FUNCTION__); - ret_val = Spartan3_dump (desc, buf, bsize); -#else - printf ("%s: No support for Spartan-III devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Virtex2: -#if (CONFIG_FPGA & CFG_VIRTEX2) - PRINTF ("%s: Launching the Virtex-II Reader...\n", - __FUNCTION__); - ret_val = Virtex2_dump (desc, buf, bsize); -#else - printf ("%s: No support for Virtex-II devices.\n", - __FUNCTION__); -#endif - break; - - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - - return ret_val; -} - -int xilinx_info (Xilinx_desc * desc) -{ - int ret_val = FPGA_FAIL; - - if (xilinx_validate (desc, (char *)__FUNCTION__)) { - printf ("Family: \t"); - switch (desc->family) { - case Xilinx_Spartan2: - printf ("Spartan-II\n"); - break; - case Xilinx_Spartan3: - printf ("Spartan-III\n"); - break; - case Xilinx_Virtex2: - printf ("Virtex-II\n"); - break; - /* Add new family types here */ - default: - printf ("Unknown family type, %d\n", desc->family); - } - - printf ("Interface type:\t"); - switch (desc->iface) { - case slave_serial: - printf ("Slave Serial\n"); - break; - case master_serial: /* Not used */ - printf ("Master Serial\n"); - break; - case slave_parallel: - printf ("Slave Parallel\n"); - break; - case jtag_mode: /* Not used */ - printf ("JTAG Mode\n"); - break; - case slave_selectmap: - printf ("Slave SelectMap Mode\n"); - break; - case master_selectmap: - printf ("Master SelectMap Mode\n"); - break; - /* Add new interface types here */ - default: - printf ("Unsupported interface type, %d\n", desc->iface); - } - - printf ("Device Size: \t%d bytes\n" - "Cookie: \t0x%x (%d)\n", - desc->size, desc->cookie, desc->cookie); - - if (desc->iface_fns) { - printf ("Device Function Table @ 0x%p\n", desc->iface_fns); - switch (desc->family) { - case Xilinx_Spartan2: -#if (CONFIG_FPGA & CFG_SPARTAN2) - Spartan2_info (desc); -#else - /* just in case */ - printf ("%s: No support for Spartan-II devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Spartan3: -#if (CONFIG_FPGA & CFG_SPARTAN3) - Spartan3_info (desc); -#else - /* just in case */ - printf ("%s: No support for Spartan-III devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Virtex2: -#if (CONFIG_FPGA & CFG_VIRTEX2) - Virtex2_info (desc); -#else - /* just in case */ - printf ("%s: No support for Virtex-II devices.\n", - __FUNCTION__); -#endif - break; - /* Add new family types here */ - default: - /* we don't need a message here - we give one up above */ - ; - } - } else - printf ("No Device Function Table.\n"); - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } - - return ret_val; -} - -int xilinx_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!xilinx_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else - switch (desc->family) { - case Xilinx_Spartan2: -#if (CONFIG_FPGA & CFG_SPARTAN2) - ret_val = Spartan2_reloc (desc, reloc_offset); -#else - printf ("%s: No support for Spartan-II devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Spartan3: -#if (CONFIG_FPGA & CFG_SPARTAN3) - ret_val = Spartan3_reloc (desc, reloc_offset); -#else - printf ("%s: No support for Spartan-III devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Virtex2: -#if (CONFIG_FPGA & CFG_VIRTEX2) - ret_val = Virtex2_reloc (desc, reloc_offset); -#else - printf ("%s: No support for Virtex-II devices.\n", - __FUNCTION__); -#endif - break; - /* Add new family types here */ - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - - return ret_val; -} - - -/* ------------------------------------------------------------------------- */ - -static int xilinx_validate (Xilinx_desc * desc, char *fn) -{ - int ret_val = FALSE; - - if (desc) { - if ((desc->family > min_xilinx_type) && - (desc->family < max_xilinx_type)) { - if ((desc->iface > min_xilinx_iface_type) && - (desc->iface < max_xilinx_iface_type)) { - if (desc->size) { - ret_val = TRUE; - } else - printf ("%s: NULL part size\n", fn); - } else - printf ("%s: Invalid Interface type, %d\n", - fn, desc->iface); - } else - printf ("%s: Invalid family type, %d\n", fn, desc->family); - } else - printf ("%s: NULL descriptor!\n", fn); - - return ret_val; -} - -#endif /* CONFIG_FPGA & CFG_FPGA_XILINX */ diff --git a/common/xyzModem.c b/common/xyzModem.c deleted file mode 100644 index 92a7d543e9..0000000000 --- a/common/xyzModem.c +++ /dev/null @@ -1,842 +0,0 @@ -/* - *========================================================================== - * - * xyzModem.c - * - * RedBoot stream handler for xyzModem protocol - * - *========================================================================== - *####ECOSGPLCOPYRIGHTBEGIN#### - * ------------------------------------------- - * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. - * Copyright (C) 2002 Gary Thomas - * - * eCos is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 or (at your option) any later version. - * - * eCos is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with eCos; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * As a special exception, if other files instantiate templates or use macros - * or inline functions from this file, or you compile this file and link it - * with other works to produce a work based on this file, this file does not - * by itself cause the resulting work to be covered by the GNU General Public - * License. However the source code for this file must still be made available - * in accordance with section (3) of the GNU General Public License. - * - * This exception does not invalidate any other reasons why a work based on - * this file might be covered by the GNU General Public License. - * - * Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. - * at http: *sources.redhat.com/ecos/ecos-license/ - * ------------------------------------------- - *####ECOSGPLCOPYRIGHTEND#### - *========================================================================== - *#####DESCRIPTIONBEGIN#### - * - * Author(s): gthomas - * Contributors: gthomas, tsmith, Yoshinori Sato - * Date: 2000-07-14 - * Purpose: - * Description: - * - * This code is part of RedBoot (tm). - * - *####DESCRIPTIONEND#### - * - *========================================================================== - */ -#include <common.h> -#include <xyzModem.h> -#include <stdarg.h> -#include <crc.h> - -/* Assumption - run xyzModem protocol over the console port */ - -/* Values magic to the protocol */ -#define SOH 0x01 -#define STX 0x02 -#define EOT 0x04 -#define ACK 0x06 -#define BSP 0x08 -#define NAK 0x15 -#define CAN 0x18 -#define EOF 0x1A /* ^Z for DOS officionados */ - -#define USE_YMODEM_LENGTH - -/* Data & state local to the protocol */ -static struct -{ -#ifdef REDBOOT - hal_virtual_comm_table_t *__chan; -#else - int *__chan; -#endif - unsigned char pkt[1024], *bufp; - unsigned char blk, cblk, crc1, crc2; - unsigned char next_blk; /* Expected block */ - int len, mode, total_retries; - int total_SOH, total_STX, total_CAN; - bool crc_mode, at_eof, tx_ack; -#ifdef USE_YMODEM_LENGTH - unsigned long file_length, read_length; -#endif -} xyz; - -#define xyzModem_CHAR_TIMEOUT 2000 /* 2 seconds */ -#define xyzModem_MAX_RETRIES 20 -#define xyzModem_MAX_RETRIES_WITH_CRC 10 -#define xyzModem_CAN_COUNT 3 /* Wait for 3 CAN before quitting */ - - -#ifndef REDBOOT /*SB */ -typedef int cyg_int32; -int -CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c) -{ -#define DELAY 20 - unsigned long counter = 0; - while (!tstc () && (counter < xyzModem_CHAR_TIMEOUT * 1000 / DELAY)) - { - udelay (DELAY); - counter++; - } - if (tstc ()) - { - *c = getc (); - return 1; - } - return 0; -} - -void -CYGACC_COMM_IF_PUTC (char x, char y) -{ - putc (y); -} - -/* Validate a hex character */ -__inline__ static bool -_is_hex (char c) -{ - return (((c >= '0') && (c <= '9')) || - ((c >= 'A') && (c <= 'F')) || ((c >= 'a') && (c <= 'f'))); -} - -/* Convert a single hex nibble */ -__inline__ static int -_from_hex (char c) -{ - int ret = 0; - - if ((c >= '0') && (c <= '9')) - { - ret = (c - '0'); - } - else if ((c >= 'a') && (c <= 'f')) - { - ret = (c - 'a' + 0x0a); - } - else if ((c >= 'A') && (c <= 'F')) - { - ret = (c - 'A' + 0x0A); - } - return ret; -} - -/* Convert a character to lower case */ -__inline__ static char -_tolower (char c) -{ - if ((c >= 'A') && (c <= 'Z')) - { - c = (c - 'A') + 'a'; - } - return c; -} - -/* Parse (scan) a number */ -bool -parse_num (char *s, unsigned long *val, char **es, char *delim) -{ - bool first = true; - int radix = 10; - char c; - unsigned long result = 0; - int digit; - - while (*s == ' ') - s++; - while (*s) - { - if (first && (s[0] == '0') && (_tolower (s[1]) == 'x')) - { - radix = 16; - s += 2; - } - first = false; - c = *s++; - if (_is_hex (c) && ((digit = _from_hex (c)) < radix)) - { - /* Valid digit */ -#ifdef CYGPKG_HAL_MIPS - /* FIXME: tx49 compiler generates 0x2539018 for MUL which */ - /* isn't any good. */ - if (16 == radix) - result = result << 4; - else - result = 10 * result; - result += digit; -#else - result = (result * radix) + digit; -#endif - } - else - { - if (delim != (char *) 0) - { - /* See if this character is one of the delimiters */ - char *dp = delim; - while (*dp && (c != *dp)) - dp++; - if (*dp) - break; /* Found a good delimiter */ - } - return false; /* Malformatted number */ - } - } - *val = result; - if (es != (char **) 0) - { - *es = s; - } - return true; -} - -#endif - -#define USE_SPRINTF -#ifdef DEBUG -#ifndef USE_SPRINTF -/* - * Note: this debug setup only works if the target platform has two serial ports - * available so that the other one (currently only port 1) can be used for debug - * messages. - */ -static int -zm_dprintf (char *fmt, ...) -{ - int cur_console; - va_list args; - - va_start (args, fmt); -#ifdef REDBOOT - cur_console = - CYGACC_CALL_IF_SET_CONSOLE_COMM - (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - CYGACC_CALL_IF_SET_CONSOLE_COMM (1); -#endif - diag_vprintf (fmt, args); -#ifdef REDBOOT - CYGACC_CALL_IF_SET_CONSOLE_COMM (cur_console); -#endif -} - -static void -zm_flush (void) -{ -} - -#else -/* - * Note: this debug setup works by storing the strings in a fixed buffer - */ -#define FINAL -#ifdef FINAL -static char *zm_out = (char *) 0x00380000; -static char *zm_out_start = (char *) 0x00380000; -#else -static char zm_buf[8192]; -static char *zm_out = zm_buf; -static char *zm_out_start = zm_buf; - -#endif -static int -zm_dprintf (char *fmt, ...) -{ - int len; - va_list args; - - va_start (args, fmt); - len = diag_vsprintf (zm_out, fmt, args); - zm_out += len; - return len; -} - -static void -zm_flush (void) -{ -#ifdef REDBOOT - char *p = zm_out_start; - while (*p) - mon_write_char (*p++); -#endif - zm_out = zm_out_start; -} -#endif - -static void -zm_dump_buf (void *buf, int len) -{ -#ifdef REDBOOT - diag_vdump_buf_with_offset (zm_dprintf, buf, len, 0); -#else - -#endif -} - -static unsigned char zm_buf[2048]; -static unsigned char *zm_bp; - -static void -zm_new (void) -{ - zm_bp = zm_buf; -} - -static void -zm_save (unsigned char c) -{ - *zm_bp++ = c; -} - -static void -zm_dump (int line) -{ - zm_dprintf ("Packet at line: %d\n", line); - zm_dump_buf (zm_buf, zm_bp - zm_buf); -} - -#define ZM_DEBUG(x) x -#else -#define ZM_DEBUG(x) -#endif - -/* Wait for the line to go idle */ -static void -xyzModem_flush (void) -{ - int res; - char c; - while (true) - { - res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c); - if (!res) - return; - } -} - -static int -xyzModem_get_hdr (void) -{ - char c; - int res; - bool hdr_found = false; - int i, can_total, hdr_chars; - unsigned short cksum; - - ZM_DEBUG (zm_new ()); - /* Find the start of a header */ - can_total = 0; - hdr_chars = 0; - - if (xyz.tx_ack) - { - CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); - xyz.tx_ack = false; - } - while (!hdr_found) - { - res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c); - ZM_DEBUG (zm_save (c)); - if (res) - { - hdr_chars++; - switch (c) - { - case SOH: - xyz.total_SOH++; - case STX: - if (c == STX) - xyz.total_STX++; - hdr_found = true; - break; - case CAN: - xyz.total_CAN++; - ZM_DEBUG (zm_dump (__LINE__)); - if (++can_total == xyzModem_CAN_COUNT) - { - return xyzModem_cancel; - } - else - { - /* Wait for multiple CAN to avoid early quits */ - break; - } - case EOT: - /* EOT only supported if no noise */ - if (hdr_chars == 1) - { - CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); - ZM_DEBUG (zm_dprintf ("ACK on EOT #%d\n", __LINE__)); - ZM_DEBUG (zm_dump (__LINE__)); - return xyzModem_eof; - } - default: - /* Ignore, waiting for start of header */ - ; - } - } - else - { - /* Data stream timed out */ - xyzModem_flush (); /* Toss any current input */ - ZM_DEBUG (zm_dump (__LINE__)); - CYGACC_CALL_IF_DELAY_US ((cyg_int32) 250000); - return xyzModem_timeout; - } - } - - /* Header found, now read the data */ - res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.blk); - ZM_DEBUG (zm_save (xyz.blk)); - if (!res) - { - ZM_DEBUG (zm_dump (__LINE__)); - return xyzModem_timeout; - } - res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.cblk); - ZM_DEBUG (zm_save (xyz.cblk)); - if (!res) - { - ZM_DEBUG (zm_dump (__LINE__)); - return xyzModem_timeout; - } - xyz.len = (c == SOH) ? 128 : 1024; - xyz.bufp = xyz.pkt; - for (i = 0; i < xyz.len; i++) - { - res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c); - ZM_DEBUG (zm_save (c)); - if (res) - { - xyz.pkt[i] = c; - } - else - { - ZM_DEBUG (zm_dump (__LINE__)); - return xyzModem_timeout; - } - } - res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc1); - ZM_DEBUG (zm_save (xyz.crc1)); - if (!res) - { - ZM_DEBUG (zm_dump (__LINE__)); - return xyzModem_timeout; - } - if (xyz.crc_mode) - { - res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc2); - ZM_DEBUG (zm_save (xyz.crc2)); - if (!res) - { - ZM_DEBUG (zm_dump (__LINE__)); - return xyzModem_timeout; - } - } - ZM_DEBUG (zm_dump (__LINE__)); - /* Validate the message */ - if ((xyz.blk ^ xyz.cblk) != (unsigned char) 0xFF) - { - ZM_DEBUG (zm_dprintf - ("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk, - (xyz.blk ^ xyz.cblk))); - ZM_DEBUG (zm_dump_buf (xyz.pkt, xyz.len)); - xyzModem_flush (); - return xyzModem_frame; - } - /* Verify checksum/CRC */ - if (xyz.crc_mode) - { - cksum = cyg_crc16 (xyz.pkt, xyz.len); - if (cksum != ((xyz.crc1 << 8) | xyz.crc2)) - { - ZM_DEBUG (zm_dprintf ("CRC error - recvd: %02x%02x, computed: %x\n", - xyz.crc1, xyz.crc2, cksum & 0xFFFF)); - return xyzModem_cksum; - } - } - else - { - cksum = 0; - for (i = 0; i < xyz.len; i++) - { - cksum += xyz.pkt[i]; - } - if (xyz.crc1 != (cksum & 0xFF)) - { - ZM_DEBUG (zm_dprintf - ("Checksum error - recvd: %x, computed: %x\n", xyz.crc1, - cksum & 0xFF)); - return xyzModem_cksum; - } - } - /* If we get here, the message passes [structural] muster */ - return 0; -} - -int -xyzModem_stream_open (connection_info_t * info, int *err) -{ -#ifdef REDBOOT - int console_chan; -#endif - int stat = 0; - int retries = xyzModem_MAX_RETRIES; - int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; - -/* ZM_DEBUG(zm_out = zm_out_start); */ -#ifdef xyzModem_zmodem - if (info->mode == xyzModem_zmodem) - { - *err = xyzModem_noZmodem; - return -1; - } -#endif - -#ifdef REDBOOT - /* Set up the I/O channel. Note: this allows for using a different port in the future */ - console_chan = - CYGACC_CALL_IF_SET_CONSOLE_COMM - (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - if (info->chan >= 0) - { - CYGACC_CALL_IF_SET_CONSOLE_COMM (info->chan); - } - else - { - CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan); - } - xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS (); - - CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan); - CYGACC_COMM_IF_CONTROL (*xyz.__chan, __COMMCTL_SET_TIMEOUT, - xyzModem_CHAR_TIMEOUT); -#else -/* TODO: CHECK ! */ - int dummy; - xyz.__chan = &dummy; -#endif - xyz.len = 0; - xyz.crc_mode = true; - xyz.at_eof = false; - xyz.tx_ack = false; - xyz.mode = info->mode; - xyz.total_retries = 0; - xyz.total_SOH = 0; - xyz.total_STX = 0; - xyz.total_CAN = 0; -#ifdef USE_YMODEM_LENGTH - xyz.read_length = 0; - xyz.file_length = 0; -#endif - - CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - - if (xyz.mode == xyzModem_xmodem) - { - /* X-modem doesn't have an information header - exit here */ - xyz.next_blk = 1; - return 0; - } - - while (retries-- > 0) - { - stat = xyzModem_get_hdr (); - if (stat == 0) - { - /* Y-modem file information header */ - if (xyz.blk == 0) - { -#ifdef USE_YMODEM_LENGTH - /* skip filename */ - while (*xyz.bufp++); - /* get the length */ - parse_num ((char *) xyz.bufp, &xyz.file_length, NULL, " "); -#endif - /* The rest of the file name data block quietly discarded */ - xyz.tx_ack = true; - } - xyz.next_blk = 1; - xyz.len = 0; - return 0; - } - else if (stat == xyzModem_timeout) - { - if (--crc_retries <= 0) - xyz.crc_mode = false; - CYGACC_CALL_IF_DELAY_US (5 * 100000); /* Extra delay for startup */ - CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - xyz.total_retries++; - ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__)); - } - if (stat == xyzModem_cancel) - { - break; - } - } - *err = stat; - ZM_DEBUG (zm_flush ()); - return -1; -} - -int -xyzModem_stream_read (char *buf, int size, int *err) -{ - int stat, total, len; - int retries; - - total = 0; - stat = xyzModem_cancel; - /* Try and get 'size' bytes into the buffer */ - while (!xyz.at_eof && (size > 0)) - { - if (xyz.len == 0) - { - retries = xyzModem_MAX_RETRIES; - while (retries-- > 0) - { - stat = xyzModem_get_hdr (); - if (stat == 0) - { - if (xyz.blk == xyz.next_blk) - { - xyz.tx_ack = true; - ZM_DEBUG (zm_dprintf - ("ACK block %d (%d)\n", xyz.blk, __LINE__)); - xyz.next_blk = (xyz.next_blk + 1) & 0xFF; - -#if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH) - if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0) - { -#else - if (1) - { -#endif - /* Data blocks can be padded with ^Z (EOF) characters */ - /* This code tries to detect and remove them */ - if ((xyz.bufp[xyz.len - 1] == EOF) && - (xyz.bufp[xyz.len - 2] == EOF) && - (xyz.bufp[xyz.len - 3] == EOF)) - { - while (xyz.len - && (xyz.bufp[xyz.len - 1] == EOF)) - { - xyz.len--; - } - } - } - -#ifdef USE_YMODEM_LENGTH - /* - * See if accumulated length exceeds that of the file. - * If so, reduce size (i.e., cut out pad bytes) - * Only do this for Y-modem (and Z-modem should it ever - * be supported since it can fall back to Y-modem mode). - */ - if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length) - { - xyz.read_length += xyz.len; - if (xyz.read_length > xyz.file_length) - { - xyz.len -= (xyz.read_length - xyz.file_length); - } - } -#endif - break; - } - else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF)) - { - /* Just re-ACK this so sender will get on with it */ - CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); - continue; /* Need new header */ - } - else - { - stat = xyzModem_sequence; - } - } - if (stat == xyzModem_cancel) - { - break; - } - if (stat == xyzModem_eof) - { - CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); - ZM_DEBUG (zm_dprintf ("ACK (%d)\n", __LINE__)); - if (xyz.mode == xyzModem_ymodem) - { - CYGACC_COMM_IF_PUTC (*xyz.__chan, - (xyz.crc_mode ? 'C' : NAK)); - xyz.total_retries++; - ZM_DEBUG (zm_dprintf ("Reading Final Header\n")); - stat = xyzModem_get_hdr (); - CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); - ZM_DEBUG (zm_dprintf ("FINAL ACK (%d)\n", __LINE__)); - } - xyz.at_eof = true; - break; - } - CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - xyz.total_retries++; - ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__)); - } - if (stat < 0) - { - *err = stat; - xyz.len = -1; - return total; - } - } - /* Don't "read" data from the EOF protocol package */ - if (!xyz.at_eof) - { - len = xyz.len; - if (size < len) - len = size; - memcpy (buf, xyz.bufp, len); - size -= len; - buf += len; - total += len; - xyz.len -= len; - xyz.bufp += len; - } - } - return total; -} - -void -xyzModem_stream_close (int *err) -{ - diag_printf - ("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", - xyz.crc_mode ? "CRC" : "Cksum", xyz.total_SOH, xyz.total_STX, - xyz.total_CAN, xyz.total_retries); - ZM_DEBUG (zm_flush ()); -} - -/* Need to be able to clean out the input buffer, so have to take the */ -/* getc */ -void -xyzModem_stream_terminate (bool abort, int (*getc) (void)) -{ - int c; - - if (abort) - { - ZM_DEBUG (zm_dprintf ("!!!! TRANSFER ABORT !!!!\n")); - switch (xyz.mode) - { - case xyzModem_xmodem: - case xyzModem_ymodem: - /* The X/YMODEM Spec seems to suggest that multiple CAN followed by an equal */ - /* number of Backspaces is a friendly way to get the other end to abort. */ - CYGACC_COMM_IF_PUTC (*xyz.__chan, CAN); - CYGACC_COMM_IF_PUTC (*xyz.__chan, CAN); - CYGACC_COMM_IF_PUTC (*xyz.__chan, CAN); - CYGACC_COMM_IF_PUTC (*xyz.__chan, CAN); - CYGACC_COMM_IF_PUTC (*xyz.__chan, BSP); - CYGACC_COMM_IF_PUTC (*xyz.__chan, BSP); - CYGACC_COMM_IF_PUTC (*xyz.__chan, BSP); - CYGACC_COMM_IF_PUTC (*xyz.__chan, BSP); - /* Now consume the rest of what's waiting on the line. */ - ZM_DEBUG (zm_dprintf ("Flushing serial line.\n")); - xyzModem_flush (); - xyz.at_eof = true; - break; -#ifdef xyzModem_zmodem - case xyzModem_zmodem: - /* Might support it some day I suppose. */ -#endif - break; - } - } - else - { - ZM_DEBUG (zm_dprintf ("Engaging cleanup mode...\n")); - /* - * Consume any trailing crap left in the inbuffer from - * previous recieved blocks. Since very few files are an exact multiple - * of the transfer block size, there will almost always be some gunk here. - * If we don't eat it now, RedBoot will think the user typed it. - */ - ZM_DEBUG (zm_dprintf ("Trailing gunk:\n")); - while ((c = (*getc) ()) > -1); - ZM_DEBUG (zm_dprintf ("\n")); - /* - * Make a small delay to give terminal programs like minicom - * time to get control again after their file transfer program - * exits. - */ - CYGACC_CALL_IF_DELAY_US ((cyg_int32) 250000); - } -} - -char * -xyzModem_error (int err) -{ - switch (err) - { - case xyzModem_access: - return "Can't access file"; - break; - case xyzModem_noZmodem: - return "Sorry, zModem not available yet"; - break; - case xyzModem_timeout: - return "Timed out"; - break; - case xyzModem_eof: - return "End of file"; - break; - case xyzModem_cancel: - return "Cancelled"; - break; - case xyzModem_frame: - return "Invalid framing"; - break; - case xyzModem_cksum: - return "CRC/checksum error"; - break; - case xyzModem_sequence: - return "Block sequence error"; - break; - default: - return "Unknown error"; - break; - } -} - -/* - * RedBoot interface - */ |