- convert spaces to tabs in at91sam7.[ch]
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sat, 27 Sep 2008 13:00:01 +0000 (13:00 +0000)
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sat, 27 Sep 2008 13:00:01 +0000 (13:00 +0000)
- add missing svn props

git-svn-id: svn://svn.berlios.de/openocd/trunk@1009 b42882b7-edfa-0310-969c-e2dbd0fdcd60

doc/INSTALL.txt
src/ecosboard.c
src/flash/at91sam7.c
src/flash/at91sam7.h
src/flash/at91sam7_old.c
src/flash/at91sam7_old.h
src/flash/flash.c
src/flash/flash.h
src/jtag/zy1000.c
src/target/cortex_m3.c

index 3732035f8ec2e644d59598e61273245186a44de5..5b8077ad201f869655b5b8195119369c783a1b5a 100644 (file)
-TODO!!! this should be merged into openocd.texi!!!\r
-\r
-\r
-Prerequisites\r
-=============\r
-\r
-When building with support for FTDI FT2232 based devices, you need at least\r
-one of the following libraries:\r
-\r
-- libftdi (http://www.intra2net.com/opensource/ftdi/)\r
-- libftd2xx (http://www.ftdichip.com/Drivers/D2XX.htm)\r
-\r
-On Windows, you need either Cygwin or MinGW, but compilation for MinGW is also\r
-possible using a Cygwin host.\r
-\r
-Basic Installation\r
-==================\r
-\r
-   OpenOCD is distributed without autotools generated files, i.e. without a \r
-configure script. Run ./bootstrap in the openocd directory to have all\r
-necessary files generated.\r
-\r
-   You have to explicitly enable desired JTAG interfaces during configure:\r
-\r
-./configure --enable-parport --enable-ft2232-libftdi (OR  --enable-ft2232-ftd2xx) \\r
-            --enable-amtjtagaccel\r
-\r
-   Under Windows/Cygwin, only the ftd2xx driver is supported for FT2232 based\r
-devices. You have to specify the location of the FTDI driver package with the\r
---with-ftd2xx=/full/path/name option.\r
-\r
-Under Linux you can choose to build the parport driver with support for\r
-/dev/parportN instead of the default access with direct port I/O using\r
---enable-parport_ppdev. This has the advantage of running OpenOCD without root\r
-privileges at the expense of a slight performance decrease. This is also\r
-available on FreeBSD using PPI, but the naming of the devices is different.\r
-\r
-Generic installation instructions\r
-=================================\r
-\r
-   These are generic installation instructions.\r
-\r
-   The `configure' shell script attempts to guess correct values for\r
-various system-dependent variables used during compilation.  It uses\r
-those values to create a `Makefile' in each directory of the package.\r
-It may also create one or more `.h' files containing system-dependent\r
-definitions.  Finally, it creates a shell script `config.status' that\r
-you can run in the future to recreate the current configuration, a file\r
-`config.cache' that saves the results of its tests to speed up\r
-reconfiguring, and a file `config.log' containing compiler output\r
-(useful mainly for debugging `configure').\r
-\r
-   If you need to do unusual things to compile the package, please try\r
-to figure out how `configure' could check whether to do them, and mail\r
-diffs or instructions to the address given in the `README' so they can\r
-be considered for the next release.  If at some point `config.cache'\r
-contains results you don't want to keep, you may remove or edit it.\r
-\r
-   The file `configure.in' is used to create `configure' by a program\r
-called `autoconf'.  You only need `configure.in' if you want to change\r
-it or regenerate `configure' using a newer version of `autoconf'.\r
-\r
-The simplest way to compile this package is:\r
-\r
-  1. `cd' to the directory containing the package's source code and type\r
-     `./configure' to configure the package for your system.  If you're\r
-     using `csh' on an old version of System V, you might need to type\r
-     `sh ./configure' instead to prevent `csh' from trying to execute\r
-     `configure' itself.\r
-\r
-     Running `configure' takes a while.  While running, it prints some\r
-     messages telling which features it is checking for.\r
-\r
-  2. Type `make' to compile the package.\r
-\r
-  3. Type `make install' to install the programs and any data files and\r
-     documentation.\r
-\r
-  4. You can remove the program binaries and object files from the\r
-     source code directory by typing `make clean'.  \r
-\r
-Compilers and Options\r
-=====================\r
-\r
-   Some systems require unusual options for compilation or linking that\r
-the `configure' script does not know about.  You can give `configure'\r
-initial values for variables by setting them in the environment.  Using\r
-a Bourne-compatible shell, you can do that on the command line like\r
-this:\r
-     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure\r
-\r
-Or on systems that have the `env' program, you can do it like this:\r
-     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure\r
-\r
-Compiling For Multiple Architectures\r
-====================================\r
-\r
-   You can compile the package for more than one kind of computer at the\r
-same time, by placing the object files for each architecture in their\r
-own directory.  To do this, you must use a version of `make' that\r
-supports the `VPATH' variable, such as GNU `make'.  `cd' to the\r
-directory where you want the object files and executables to go and run\r
-the `configure' script.  `configure' automatically checks for the\r
-source code in the directory that `configure' is in and in `..'.\r
-\r
-   If you have to use a `make' that does not supports the `VPATH'\r
-variable, you have to compile the package for one architecture at a time\r
-in the source code directory.  After you have installed the package for\r
-one architecture, use `make distclean' before reconfiguring for another\r
-architecture.\r
-\r
-Installation Names\r
-==================\r
-\r
-   By default, `make install' will install the package's files in\r
-`/usr/local/bin', `/usr/local/man', etc.  You can specify an\r
-installation prefix other than `/usr/local' by giving `configure' the\r
-option `--prefix=PATH'.\r
-\r
-   You can specify separate installation prefixes for\r
-architecture-specific files and architecture-independent files.  If you\r
-give `configure' the option `--exec-prefix=PATH', the package will use\r
-PATH as the prefix for installing programs and libraries.\r
-Documentation and other data files will still use the regular prefix.\r
-\r
-   If the package supports it, you can cause programs to be installed\r
-with an extra prefix or suffix on their names by giving `configure' the\r
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.\r
-\r
-Optional Features\r
-=================\r
-\r
-   Some packages pay attention to `--enable-FEATURE' options to\r
-`configure', where FEATURE indicates an optional part of the package.\r
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE\r
-is something like `gnu-as' or `x' (for the X Window System).  The\r
-`README' should mention any `--enable-' and `--with-' options that the\r
-package recognizes.\r
-\r
-   For packages that use the X Window System, `configure' can usually\r
-find the X include and library files automatically, but if it doesn't,\r
-you can use the `configure' options `--x-includes=DIR' and\r
-`--x-libraries=DIR' to specify their locations.\r
-\r
-Specifying the System Type\r
-==========================\r
-\r
-   There may be some features `configure' can not figure out\r
-automatically, but needs to determine by the type of host the package\r
-will run on.  Usually `configure' can figure that out, but if it prints\r
-a message saying it can not guess the host type, give it the\r
-`--host=TYPE' option.  TYPE can either be a short name for the system\r
-type, such as `sun4', or a canonical name with three fields:\r
-     CPU-COMPANY-SYSTEM\r
-\r
-See the file `config.sub' for the possible values of each field.  If\r
-`config.sub' isn't included in this package, then this package doesn't\r
-need to know the host type.\r
-\r
-   If you are building compiler tools for cross-compiling, you can also\r
-use the `--target=TYPE' option to select the type of system they will\r
-produce code for and the `--build=TYPE' option to select the type of\r
-system on which you are compiling the package.\r
-\r
-Sharing Defaults\r
-================\r
-\r
-   If you want to set default values for `configure' scripts to share,\r
-you can create a site shell script called `config.site' that gives\r
-default values for variables like `CC', `cache_file', and `prefix'.\r
-`configure' looks for `PREFIX/share/config.site' if it exists, then\r
-`PREFIX/etc/config.site' if it exists.  Or, you can set the\r
-`CONFIG_SITE' environment variable to the location of the site script.\r
-A warning: not all `configure' scripts look for a site script.\r
-\r
-Operation Controls\r
-==================\r
-\r
-   `configure' recognizes the following options to control how it\r
-operates.\r
-\r
-`--cache-file=FILE'\r
-     Use and save the results of the tests in FILE instead of\r
-     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for\r
-     debugging `configure'.\r
-\r
-`--help'\r
-     Print a summary of the options to `configure', and exit.\r
-\r
-`--quiet'\r
-`--silent'\r
-`-q'\r
-     Do not print messages saying which checks are being made.\r
-\r
-`--srcdir=DIR'\r
-     Look for the package's source code in directory DIR.  Usually\r
-     `configure' can determine that directory automatically.\r
-\r
-`--version'\r
-     Print the version of Autoconf used to generate the `configure'\r
-     script, and exit.\r
-\r
-`configure' also accepts some other, not widely useful, options.\r
-\r
+TODO!!! this should be merged into openocd.texi!!!
+
+
+Prerequisites
+=============
+
+When building with support for FTDI FT2232 based devices, you need at least
+one of the following libraries:
+
+- libftdi (http://www.intra2net.com/opensource/ftdi/)
+- libftd2xx (http://www.ftdichip.com/Drivers/D2XX.htm)
+
+On Windows, you need either Cygwin or MinGW, but compilation for MinGW is also
+possible using a Cygwin host.
+
+Basic Installation
+==================
+
+   OpenOCD is distributed without autotools generated files, i.e. without a 
+configure script. Run ./bootstrap in the openocd directory to have all
+necessary files generated.
+
+   You have to explicitly enable desired JTAG interfaces during configure:
+
+./configure --enable-parport --enable-ft2232-libftdi (OR  --enable-ft2232-ftd2xx) \
+            --enable-amtjtagaccel
+
+   Under Windows/Cygwin, only the ftd2xx driver is supported for FT2232 based
+devices. You have to specify the location of the FTDI driver package with the
+--with-ftd2xx=/full/path/name option.
+
+Under Linux you can choose to build the parport driver with support for
+/dev/parportN instead of the default access with direct port I/O using
+--enable-parport_ppdev. This has the advantage of running OpenOCD without root
+privileges at the expense of a slight performance decrease. This is also
+available on FreeBSD using PPI, but the naming of the devices is different.
+
+Generic installation instructions
+=================================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes a while.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Type `make install' to install the programs and any data files and
+     documentation.
+
+  4. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
index d11190032e872e77d7cfff4859a99474863d3ec0..182fc5c50e5a8580218cd7a551c335db85d03f54 100644 (file)
-/***************************************************************************\r
- *   Copyright (C) 2007-2008 by Ã˜yvind Harboe                              *\r
- *                                                                         *\r
- *   This program is free software; you can redistribute it and/or modify  *\r
- *   it under the terms of the GNU General Public License as published by  *\r
- *   the Free Software Foundation; either version 2 of the License, or     *\r
- *   (at your option) any later version.                                   *\r
- *                                                                         *\r
- *   This program is distributed in the hope that it will be useful,       *\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
- *   GNU General Public License for more details.                          *\r
- *                                                                         *\r
- *   You should have received a copy of the GNU General Public License     *\r
- *   along with this program; if not, write to the                         *\r
- *   Free Software Foundation, Inc.,                                       *\r
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
- ***************************************************************************/\r
-\r
-#ifdef HAVE_CONFIG_H\r
-#include "config.h"\r
-#endif\r
-\r
-#include "log.h"\r
-#include "types.h"\r
-#include "jtag.h"\r
-#include "configuration.h"\r
-#include "xsvf.h"\r
-#include "target.h"\r
-#include "flash.h"\r
-#include "nand.h"\r
-#include "pld.h"\r
-\r
-#include "command.h"\r
-#include "server.h"\r
-#include "telnet_server.h"\r
-#include "gdb_server.h"\r
-\r
-#include <time_support.h>\r
-#include <sys/time.h>\r
-#include <sys/types.h>\r
-#include <strings.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <unistd.h>\r
-#include <errno.h>\r
-\r
-#include <cyg/io/flash.h>\r
-#include <pkgconf/fs_jffs2.h>  // Address of JFFS2\r
-#include <network.h>\r
-\r
-#include <fcntl.h>\r
-#include <sys/stat.h>\r
-#include <cyg/fileio/fileio.h>\r
-#include <dirent.h>\r
-#include <cyg/athttpd/http.h>\r
-#include <cyg/athttpd/socket.h>\r
-#include <cyg/athttpd/handler.h>\r
-#include <cyg/athttpd/cgi.h>\r
-#include <cyg/athttpd/forms.h>\r
-#include <cyg/hal/hal_diag.h>\r
-#include <cyg/kernel/kapi.h>\r
-#include <cyg/io/serialio.h>\r
-#include <cyg/io/io.h>\r
-#include <netinet/tcp.h>\r
-#include "rom.h"\r
-#include <sys/ioctl.h>\r
-#include <sys/socket.h>\r
-#include <netinet/in.h>\r
-#include <net/if.h>\r
-#include <arpa/inet.h>\r
-#include <sys/types.h>\r
-#include <sys/socket.h>\r
-#include <netdb.h>\r
-#include <netinet/in.h>\r
-#include <unistd.h>\r
-#include <arpa/inet.h>\r
-#include <stdio.h>\r
-#include <ifaddrs.h>\r
-#include <string.h>\r
-\r
-#include <unistd.h>\r
-#include <stdio.h>\r
-#define MAX_IFS 64\r
-#if defined(CYGPKG_NET_FREEBSD_STACK)\r
-#include <tftp_support.h>\r
-/* posix compatibility broken*/\r
-struct tftpd_fileops fileops =\r
-{\r
-       (int (*)(const char *, int))open,\r
-       close,\r
-       (int (*)(int, const void *, int))write,\r
-       ( int (*)(int, void *, int))read\r
-};\r
-\r
-#endif\r
-\r
-#define ZYLIN_VERSION "1.43"\r
-#define ZYLIN_DATE __DATE__\r
-#define ZYLIN_TIME __TIME__\r
-/* hmmm....  we can't pick up the right # during build if we've checked this out\r
- * in Eclipse... arrggghh...*/\r
-#define ZYLIN_OPENOCD 1005\r
-#define ZYLIN_OPENOCD_VERSION "Zylin JTAG ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE " " ZYLIN_TIME\r
-#define ZYLIN_CONFIG_DIR "/config/settings"\r
-\r
-void diag_write(char *buf, int len)\r
-{\r
-       int j;\r
-       for (j = 0; j < len; j++)\r
-       {\r
-               diag_printf("%c", buf[j]);\r
-       }\r
-}\r
-\r
-static bool serialLog = true;\r
-static bool writeLog = true;\r
-\r
-\r
-struct FastLoad\r
-{\r
-       u32 address;\r
-       u8 *data;\r
-       int length;\r
-\r
-};\r
-\r
-static int fastload_num;\r
-static struct FastLoad *fastload;\r
-\r
-static void free_fastload()\r
-{\r
-       if (fastload!=NULL)\r
-       {\r
-               int i;\r
-               for (i=0; i<fastload_num; i++)\r
-               {\r
-                       if (fastload[i].data)\r
-                               free(fastload[i].data);\r
-               }\r
-               free(fastload);\r
-               fastload=NULL;\r
-       }\r
-}\r
-\r
-\r
-int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       u8 *buffer;\r
-       u32 buf_cnt;\r
-       u32 image_size;\r
-       u32 min_address=0;\r
-       u32 max_address=0xffffffff;\r
-       int i;\r
-       int retval;\r
-\r
-       image_t image;\r
-\r
-       duration_t duration;\r
-       char *duration_text;\r
-\r
-       if ((argc < 1)||(argc > 5))\r
-       {\r
-               return ERROR_COMMAND_SYNTAX_ERROR;\r
-       }\r
-\r
-       /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */\r
-       if (argc >= 2)\r
-       {\r
-               image.base_address_set = 1;\r
-               image.base_address = strtoul(args[1], NULL, 0);\r
-       }\r
-       else\r
-       {\r
-               image.base_address_set = 0;\r
-       }\r
-\r
-\r
-       image.start_address_set = 0;\r
-\r
-       if (argc>=4)\r
-       {\r
-               min_address=strtoul(args[3], NULL, 0);\r
-       }\r
-       if (argc>=5)\r
-       {\r
-               max_address=strtoul(args[4], NULL, 0)+min_address;\r
-       }\r
-\r
-       if (min_address>max_address)\r
-       {\r
-               return ERROR_COMMAND_SYNTAX_ERROR;\r
-       }\r
-\r
-       duration_start_measure(&duration);\r
-\r
-       if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)\r
-       {\r
-               return ERROR_OK;\r
-       }\r
-\r
-       image_size = 0x0;\r
-       retval = ERROR_OK;\r
-       fastload_num=image.num_sections;\r
-       fastload=(struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);\r
-       if (fastload==NULL)\r
-       {\r
-               image_close(&image);\r
-               return ERROR_FAIL;\r
-       }\r
-       memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);\r
-       for (i = 0; i < image.num_sections; i++)\r
-       {\r
-               buffer = malloc(image.sections[i].size);\r
-               if (buffer == NULL)\r
-               {\r
-                       command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);\r
-                       break;\r
-               }\r
-\r
-               if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)\r
-               {\r
-                       free(buffer);\r
-                       break;\r
-               }\r
-\r
-               u32 offset=0;\r
-               u32 length=buf_cnt;\r
-\r
-\r
-               /* DANGER!!! beware of unsigned comparision here!!! */\r
-\r
-               if ((image.sections[i].base_address+buf_cnt>=min_address)&&\r
-                               (image.sections[i].base_address<max_address))\r
-               {\r
-                       if (image.sections[i].base_address<min_address)\r
-                       {\r
-                               /* clip addresses below */\r
-                               offset+=min_address-image.sections[i].base_address;\r
-                               length-=offset;\r
-                       }\r
-\r
-                       if (image.sections[i].base_address+buf_cnt>max_address)\r
-                       {\r
-                               length-=(image.sections[i].base_address+buf_cnt)-max_address;\r
-                       }\r
-\r
-                       fastload[i].address=image.sections[i].base_address+offset;\r
-                       fastload[i].data=malloc(length);\r
-                       if (fastload[i].data==NULL)\r
-                       {\r
-                               free(buffer);\r
-                               break;\r
-                       }\r
-                       memcpy(fastload[i].data, buffer+offset, length);\r
-                       fastload[i].length=length;\r
-\r
-                       image_size += length;\r
-                       command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);\r
-               }\r
-\r
-               free(buffer);\r
-       }\r
-\r
-       duration_stop_measure(&duration, &duration_text);\r
-       if (retval==ERROR_OK)\r
-       {\r
-               command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);\r
-       }\r
-       free(duration_text);\r
-\r
-       image_close(&image);\r
-\r
-       if (retval!=ERROR_OK)\r
-       {\r
-               free_fastload();\r
-       }\r
-\r
-       return retval;\r
-}\r
-\r
-int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       if (argc>0)\r
-               return ERROR_COMMAND_SYNTAX_ERROR;\r
-       if (fastload==NULL)\r
-       {\r
-               LOG_ERROR("No image in memory");\r
-               return ERROR_FAIL;\r
-       }\r
-       int i;\r
-       int ms=timeval_ms();\r
-       int size=0;\r
-       for (i=0; i<fastload_num;i++)\r
-       {\r
-               int retval;\r
-               target_t *target = get_current_target(cmd_ctx);\r
-               if ((retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data)) != ERROR_OK)\r
-               {\r
-                       return retval;\r
-               }\r
-               size+=fastload[i].length;\r
-       }\r
-       int after=timeval_ms();\r
-       command_print(cmd_ctx, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-/* Give TELNET a way to find out what version this is */\r
-int handle_zy1000_version_command(struct command_context_s *cmd_ctx, char *cmd,\r
-               char **args, int argc)\r
-{\r
-       if (argc > 1)\r
-       {\r
-               return ERROR_COMMAND_SYNTAX_ERROR;\r
-       }\r
-       if (argc == 0)\r
-       {\r
-               command_print(cmd_ctx, ZYLIN_OPENOCD_VERSION);\r
-       } else if (strcmp("openocd", args[0])==0)\r
-       {\r
-               command_print(cmd_ctx, "%d", ZYLIN_OPENOCD);\r
-       } else if (strcmp("zy1000", args[0])==0)\r
-       {\r
-               command_print(cmd_ctx, "%s", ZYLIN_VERSION);\r
-       } else if (strcmp("date", args[0])==0)\r
-       {\r
-               command_print(cmd_ctx, "%s", ZYLIN_DATE);\r
-       } else\r
-       {\r
-               return ERROR_COMMAND_SYNTAX_ERROR;\r
-       }\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-extern flash_driver_t *flash_drivers[];\r
-extern target_type_t *target_types[];\r
-\r
-#ifdef CYGPKG_PROFILE_GPROF\r
-#include <cyg/profile/profile.h>\r
-\r
-extern char _stext, _etext; // Defined by the linker\r
-\r
-void start_profile(void)\r
-{\r
-       // This starts up the system-wide profiling, gathering\r
-       // profile information on all of the code, with a 16 byte\r
-       // "bucket" size, at a rate of 100us/profile hit.\r
-       // Note: a bucket size of 16 will give pretty good function\r
-       //       resolution.  Much smaller and the buffer becomes\r
-       //       much too large for very little gain.\r
-       // Note: a timer period of 100us is also a reasonable\r
-       //       compromise.  Any smaller and the overhead of\r
-       //       handling the timter (profile) interrupt could\r
-       //       swamp the system.  A fast processor might get\r
-       //       by with a smaller value, but a slow one could\r
-       //       even be swamped by this value.  If the value is\r
-       //       too large, the usefulness of the profile is reduced.\r
-\r
-       // no more interrupts than 1/10ms.\r
-       //    profile_on(&_stext, &_etext, 16, 10000); // DRAM\r
-       //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM\r
-       profile_on(0, &_etext, 16, 10000); // SRAM & DRAM\r
-}\r
-#endif\r
-\r
-// launch GDB server if a config file exists\r
-bool zylinjtag_parse_config_file(struct command_context_s *cmd_ctx, const char *config_file_name)\r
-{\r
-       bool foundFile = false;\r
-       FILE *config_file = NULL;\r
-       command_print(cmd_ctx, "executing config file %s", config_file_name);\r
-       config_file = fopen(config_file_name, "r");\r
-       if (config_file)\r
-       {\r
-               fclose(config_file);\r
-               int retval;\r
-               retval = command_run_linef(cmd_ctx, "script %s", config_file_name);\r
-               if (retval == ERROR_OK)\r
-               {\r
-                       foundFile = true;\r
-               }\r
-               else\r
-               {\r
-                       command_print(cmd_ctx, "Failed executing %s %d", config_file_name, retval);\r
-               }\r
-       }\r
-       else\r
-       {\r
-               command_print(cmd_ctx, "No %s found", config_file_name);\r
-       }\r
-\r
-       return foundFile;\r
-}\r
-\r
-extern int eth0_up;\r
-static FILE *log;\r
-\r
-static char reboot_stack[2048];\r
-\r
-\r
-static void\r
-zylinjtag_reboot(cyg_addrword_t data)\r
-{\r
-       serialLog = true;\r
-       diag_printf("Rebooting in 100 ticks..\n");\r
-       cyg_thread_delay(100);\r
-       diag_printf("Unmounting /config..\n");\r
-       umount("/config");\r
-       diag_printf("Rebooting..\n");\r
-       HAL_PLATFORM_RESET();\r
-}\r
-static cyg_thread zylinjtag_thread_object;\r
-static cyg_handle_t zylinjtag_thread_handle;\r
-\r
-void reboot(void)\r
-{\r
-    cyg_thread_create(1,\r
-                      zylinjtag_reboot,\r
-                      (cyg_addrword_t)0,\r
-                      "reboot Thread",\r
-                      (void *)reboot_stack,\r
-                      sizeof(reboot_stack),\r
-                      &zylinjtag_thread_handle,\r
-                      &zylinjtag_thread_object);\r
-       cyg_thread_resume(zylinjtag_thread_handle);\r
-}\r
-\r
-int configuration_output_handler(struct command_context_s *context, const char* line)\r
-{\r
-       diag_printf("%s", line);\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-int zy1000_configuration_output_handler_log(struct command_context_s *context, const char* line)\r
-{\r
-       LOG_USER_N("%s", line);\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-int handle_rm_command(struct command_context_s *cmd_ctx, char *cmd,\r
-               char **args, int argc)\r
-{\r
-       if (argc != 1)\r
-       {\r
-               command_print(cmd_ctx, "rm <filename>");\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-\r
-       if (unlink(args[0]) != 0)\r
-       {\r
-               command_print(cmd_ctx, "failed: %d", errno);\r
-       }\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-int loadFile(const char *fileName, void **data, int *len);\r
-\r
-int handle_cat_command(struct command_context_s *cmd_ctx, char *cmd,\r
-               char **args, int argc)\r
-{\r
-       if (argc != 1)\r
-       {\r
-               command_print(cmd_ctx, "cat <filename>");\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-\r
-       // NOTE!!! we only have line printing capability so we print the entire file as a single line.\r
-       void *data;\r
-       int len;\r
-\r
-       int retval = loadFile(args[0], &data, &len);\r
-       if (retval == ERROR_OK)\r
-       {\r
-               command_print(cmd_ctx, "%s", data);\r
-               free(data);\r
-       }\r
-       else\r
-       {\r
-               command_print(cmd_ctx, "%s not found %d", args[0], retval);\r
-       }\r
-\r
-       return ERROR_OK;\r
-}\r
-int handle_trunc_command(struct command_context_s *cmd_ctx, char *cmd,\r
-               char **args, int argc)\r
-{\r
-       if (argc != 1)\r
-       {\r
-               command_print(cmd_ctx, "trunc <filename>");\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-\r
-       FILE *config_file = NULL;\r
-       config_file = fopen(args[0], "w");\r
-       if (config_file != NULL)\r
-               fclose(config_file);\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-int handle_meminfo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       static int prev = 0;\r
-       struct mallinfo info;\r
-\r
-       if (argc != 0)\r
-       {\r
-               command_print(cmd_ctx, "meminfo");\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-\r
-       info = mallinfo();\r
-\r
-       if (prev > 0)\r
-       {\r
-               command_print(cmd_ctx, "Diff:            %d", prev - info.fordblks);\r
-       }\r
-       prev = info.fordblks;\r
-\r
-       command_print(cmd_ctx, "Available ram:   %d", info.fordblks );\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-static bool savePower;\r
-\r
-static void setPower(bool power)\r
-{\r
-       savePower = power;\r
-       if (power)\r
-       {\r
-               HAL_WRITE_UINT32(0x08000014, 0x8);\r
-       } else\r
-       {\r
-               HAL_WRITE_UINT32(0x08000010, 0x8);\r
-       }\r
-}\r
-\r
-int handle_power_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       if (argc > 1)\r
-       {\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-\r
-       if (argc == 1)\r
-       {\r
-               if (strcmp(args[0], "on") == 0)\r
-               {\r
-                       setPower(1);\r
-               }\r
-               else if (strcmp(args[0], "off") == 0)\r
-               {\r
-                       setPower(0);\r
-               } else\r
-               {\r
-                       command_print(cmd_ctx, "arg is \"on\" or \"off\"");\r
-                       return ERROR_INVALID_ARGUMENTS;\r
-               }\r
-       }\r
-\r
-       command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off");\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-int handle_append_command(struct command_context_s *cmd_ctx, char *cmd,\r
-               char **args, int argc)\r
-{\r
-       if (argc < 1)\r
-       {\r
-               command_print(cmd_ctx,\r
-                               "append <filename> [<string1>, [<string2>, ...]]");\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-\r
-       FILE *config_file = NULL;\r
-       config_file = fopen(args[0], "a");\r
-       if (config_file != NULL)\r
-       {\r
-               int i;\r
-               fseek(config_file, 0, SEEK_END);\r
-\r
-               for (i = 1; i < argc; i++)\r
-               {\r
-                       fwrite(args[i], strlen(args[i]), 1, config_file);\r
-                       if (i != argc - 1)\r
-                       {\r
-                               fwrite(" ", 1, 1, config_file);\r
-                       }\r
-               }\r
-               fwrite("\n", 1, 1, config_file);\r
-               fclose(config_file);\r
-       }\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-extern int telnet_socket;\r
-\r
-int readMore(int fd, void *data, int length)\r
-{\r
-       /* used in select() */\r
-       fd_set read_fds;\r
-\r
-       /* monitor sockets for acitvity */\r
-       int fd_max = 1;\r
-       FD_ZERO(&read_fds);\r
-       /* listen for new connections */\r
-       FD_SET(fd, &read_fds);\r
-\r
-       // Maximum 5 seconds.\r
-       struct timeval tv;\r
-       tv.tv_sec = 5;\r
-       tv.tv_usec = 0;\r
-\r
-       int retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);\r
-       if (retval == 0)\r
-       {\r
-               diag_printf("Timed out waiting for binary payload\n");\r
-               return -1;\r
-       }\r
-       if (retval != 1)\r
-               return -1;\r
-\r
-       return read_socket(fd, data, length);\r
-}\r
-\r
-int readAll(int fd, void *data, int length)\r
-{\r
-       int pos = 0;\r
-       for (;;)\r
-       {\r
-               int actual = readMore(fd, ((char *) data) + pos, length - pos);\r
-               //              diag_printf("Read %d bytes(pos=%d, length=%d)\n", actual, pos, length);\r
-               if (actual <= 0)\r
-                       return -1;\r
-               pos += actual;\r
-               if (pos == length)\r
-                       break;\r
-       }\r
-       return length;\r
-}\r
-\r
-int handle_peek_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       cyg_uint32 value;\r
-       if (argc != 1)\r
-       {\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-       HAL_READ_UINT32(strtoul(args[0], NULL, 0), value);\r
-       command_print(cmd_ctx, "0x%x : 0x%x", strtoul(args[0], NULL, 0), value);\r
-       return ERROR_OK;\r
-}\r
-\r
-int handle_poke_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       if (argc != 2)\r
-       {\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-       HAL_WRITE_UINT32(strtoul(args[0], NULL, 0), strtoul(args[1], NULL, 0));\r
-       return ERROR_OK;\r
-}\r
-\r
-int handle_cp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       if (argc != 2)\r
-       {\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-\r
-       // NOTE!!! we only have line printing capability so we print the entire file as a single line.\r
-       void *data;\r
-       int len;\r
-\r
-       int retval = loadFile(args[0], &data, &len);\r
-       if (retval != ERROR_OK)\r
-               return retval;\r
-\r
-       FILE *f = fopen(args[1], "wb");\r
-       if (f == NULL)\r
-               retval = ERROR_INVALID_ARGUMENTS;\r
-\r
-       int pos = 0;\r
-       for (;;)\r
-       {\r
-               int chunk = len - pos;\r
-               static const int maxChunk = 512 * 1024; // ~1/sec\r
-               if (chunk > maxChunk)\r
-               {\r
-                       chunk = maxChunk;\r
-               }\r
-\r
-               if ((retval==ERROR_OK)&&(fwrite(((char *)data)+pos, 1, chunk, f)!=chunk))\r
-                       retval = ERROR_INVALID_ARGUMENTS;\r
-\r
-               if (retval != ERROR_OK)\r
-               {\r
-                       break;\r
-               }\r
-\r
-               command_print(cmd_ctx, "%d", len - pos);\r
-\r
-               pos += chunk;\r
-\r
-               if (pos == len)\r
-                       break;\r
-       }\r
-\r
-       if (retval == ERROR_OK)\r
-       {\r
-               command_print(cmd_ctx, "Copied %s to %s", args[0], args[1]);\r
-       } else\r
-       {\r
-               command_print(cmd_ctx, "Failed: %d", retval);\r
-       }\r
-\r
-       if (data != NULL)\r
-               free(data);\r
-       if (f != NULL)\r
-               fclose(f);\r
-\r
-       if (retval != ERROR_OK)\r
-               unlink(args[1]);\r
-\r
-       return retval;\r
-}\r
-\r
-#ifdef CYGPKG_PROFILE_GPROF\r
-extern void start_profile();\r
-\r
-int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       command_print(cmd_ctx, "Profiling started");\r
-       start_profile();\r
-       return ERROR_OK;\r
-}\r
-\r
-#endif\r
-\r
-externC void phi_init_all_network_interfaces();\r
-\r
-command_context_t *cmd_ctx;\r
-\r
-static bool webRunning = false;\r
-\r
-void keep_webserver()\r
-{\r
-       // Target initialisation is only attempted at startup, so we sleep forever and\r
-       // let the http server bail us out(i.e. get config files set up).\r
-       diag_printf("OpenOCD has invoked exit().\n"\r
-               "Use web server to correct any configuration settings and reboot.\n");\r
-       if (!webRunning)\r
-               reboot();\r
-\r
-       // exit() will terminate the current thread and we we'll then sleep eternally or\r
-       // we'll have a reboot scheduled.\r
-}\r
-\r
-extern void printDccChar(char c);\r
-\r
-static char logBuffer[128 * 1024];\r
-static const int logSize = sizeof(logBuffer);\r
-int writePtr = 0;\r
-int logCount = 0;\r
-\r
-void _zylinjtag_diag_write_char(char c, void **param)\r
-{\r
-       if (writeLog)\r
-       {\r
-               logBuffer[writePtr] = c;\r
-               writePtr = (writePtr + 1) % logSize;\r
-               logCount++;\r
-       }\r
-       if (serialLog)\r
-       {\r
-               if (c == '\n')\r
-               {\r
-                       HAL_DIAG_WRITE_CHAR('\r');\r
-               }\r
-               HAL_DIAG_WRITE_CHAR(c);\r
-       }\r
-\r
-       printDccChar(c);\r
-}\r
-\r
-#define SHOW_RESULT(a, b) diag_printf(#a " failed %d\n", (int)b)\r
-\r
-#define IOSIZE 512\r
-static void copyfile(char *name2, char *name1)\r
-{\r
-\r
-       int err;\r
-       char buf[IOSIZE];\r
-       int fd1, fd2;\r
-       ssize_t done, wrote;\r
-\r
-       fd1 = open(name1, O_WRONLY | O_CREAT);\r
-       if (fd1 < 0)\r
-               SHOW_RESULT( open, fd1 );\r
-\r
-       fd2 = open(name2, O_RDONLY);\r
-       if (fd2 < 0)\r
-               SHOW_RESULT( open, fd2 );\r
-\r
-       for (;;)\r
-       {\r
-               done = read(fd2, buf, IOSIZE );\r
-               if (done < 0)\r
-               {\r
-                       SHOW_RESULT( read, done );\r
-                       break;\r
-               }\r
-\r
-        if( done == 0 ) break;\r
-\r
-               wrote = write(fd1, buf, done);\r
-        if( wrote != done ) SHOW_RESULT( write, wrote );\r
-\r
-        if( wrote != done ) break;\r
-       }\r
-\r
-       err = close(fd1);\r
-    if( err < 0 ) SHOW_RESULT( close, err );\r
-\r
-       err = close(fd2);\r
-    if( err < 0 ) SHOW_RESULT( close, err );\r
-\r
-}\r
-static void copydir(char *name)\r
-{\r
-       int err;\r
-       DIR *dirp;\r
-\r
-       mkdir("/ram/cgi", 0777);\r
-\r
-       dirp = opendir(name);\r
-    if( dirp == NULL ) SHOW_RESULT( opendir, -1 );\r
-\r
-       for (;;)\r
-       {\r
-               struct dirent *entry = readdir(dirp);\r
-\r
-               if (entry == NULL)\r
-                       break;\r
-\r
-               if (strcmp(entry->d_name, ".") == 0)\r
-                       continue;\r
-               if (strcmp(entry->d_name, "..") == 0)\r
-                       continue;\r
-\r
-               bool isDir = false;\r
-               struct stat buf;\r
-               char fullPath[PATH_MAX];\r
-               strncpy(fullPath, name, PATH_MAX);\r
-               strcat(fullPath, "/");\r
-               strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));\r
-\r
-               if (stat(fullPath, &buf) == -1)\r
-               {\r
-                       diag_printf("unable to read status from %s", fullPath);\r
-                       break;\r
-               }\r
-               isDir = S_ISDIR(buf.st_mode) != 0;\r
-\r
-               if (isDir)\r
-                       continue;\r
-\r
-               //        diag_printf("<INFO>: entry %14s",entry->d_name);\r
-               char fullname[PATH_MAX];\r
-               char fullname2[PATH_MAX];\r
-\r
-               strcpy(fullname, name);\r
-               strcat(fullname, entry->d_name);\r
-\r
-               strcpy(fullname2, "/ram/cgi/");\r
-               strcat(fullname2, entry->d_name);\r
-               //        diag_printf("from %s to %s\n", fullname, fullname2);\r
-               copyfile(fullname, fullname2);\r
-\r
-               //       diag_printf("\n");\r
-       }\r
-\r
-       err = closedir(dirp);\r
-    if( err < 0 ) SHOW_RESULT( stat, err );\r
-}\r
-\r
-#if 0\r
-MTAB_ENTRY( romfs_mte1,\r
-               "/rom",\r
-               "romfs",\r
-               "",\r
-               (CYG_ADDRWORD) &filedata[0] );\r
-#endif\r
-\r
-void openocd_sleep_prelude()\r
-{\r
-       cyg_mutex_unlock(&httpstate.jim_lock);\r
-}\r
-\r
-void openocd_sleep_postlude()\r
-{\r
-       cyg_mutex_lock(&httpstate.jim_lock);\r
-}\r
-\r
-static int\r
-zylinjtag_Jim_Command_rm(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       int del;\r
-       if (argc != 2)\r
-       {\r
-               Jim_WrongNumArgs(interp, 1, argv, "rm ?dirorfile?");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       del = 0;\r
-       if (unlink(Jim_GetString(argv[1], NULL)) == 0)\r
-               del = 1;\r
-       if (rmdir(Jim_GetString(argv[1], NULL)) == 0)\r
-               del = 1;\r
-\r
-       return del ? JIM_OK : JIM_ERR;\r
-}\r
-\r
-static int\r
-zylinjtag_Jim_Command_ls(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       if (argc != 2)\r
-       {\r
-               Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       char *name = (char*) Jim_GetString(argv[1], NULL);\r
-\r
-       DIR *dirp = NULL;\r
-       dirp = opendir(name);\r
-       if (dirp == NULL)\r
-       {\r
-               return JIM_ERR;\r
-       }\r
-       Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);\r
-\r
-       for (;;)\r
-       {\r
-               struct dirent *entry = NULL;\r
-               entry = readdir(dirp);\r
-               if (entry == NULL)\r
-                       break;\r
-\r
-               if ((strcmp(".", entry->d_name)==0)||(strcmp("..", entry->d_name)==0))\r
-                       continue;\r
-\r
-        Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name)));\r
-       }\r
-       closedir(dirp);\r
-\r
-       Jim_SetResult(interp, objPtr);\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-\r
-static int\r
-zylinjtag_Jim_Command_getmem(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       if (argc != 3)\r
-       {\r
-               Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       long address;\r
-       long length;\r
-       if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)\r
-               return JIM_ERR;\r
-       if (Jim_GetLong(interp, argv[2], &length) != JIM_OK)\r
-               return JIM_ERR;\r
-\r
-       if (length < 0 && length > (4096 * 1024))\r
-       {\r
-               Jim_WrongNumArgs(interp, 1, argv, "getmem ?dir?");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       void *mem = malloc(length);\r
-       if (mem == NULL)\r
-               return JIM_ERR;\r
-\r
-       target_t *target = get_current_target(cmd_ctx);\r
-\r
-       int retval;\r
-       int size = 1;\r
-       int count = length;\r
-       if ((address % 4 == 0) && (count % 4 == 0))\r
-       {\r
-               size = 4;\r
-               count /= 4;\r
-       }\r
-\r
-       if ((retval  = target->type->read_memory(target, address, size, count, mem)) != ERROR_OK)\r
-       {\r
-               free(mem);\r
-               return JIM_ERR;\r
-       }\r
-\r
-       Jim_Obj *objPtr = Jim_NewStringObj(interp, mem, length);\r
-       Jim_SetResult(interp, objPtr);\r
-\r
-       free(mem);\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-static int\r
-zylinjtag_Jim_Command_peek(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       if (argc != 2)\r
-       {\r
-               Jim_WrongNumArgs(interp, 1, argv, "peek ?address?");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       long address;\r
-       if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)\r
-               return JIM_ERR;\r
-\r
-       int value = *((volatile int *) address);\r
-\r
-       Jim_SetResult(interp, Jim_NewIntObj(interp, value));\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-static int\r
-zylinjtag_Jim_Command_poke(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       if (argc != 3)\r
-       {\r
-               Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       long address;\r
-       if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)\r
-               return JIM_ERR;\r
-       long value;\r
-       if (Jim_GetLong(interp, argv[2], &value) != JIM_OK)\r
-               return JIM_ERR;\r
-\r
-       *((volatile int *) address) = value;\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-\r
-\r
-static int\r
-zylinjtag_Jim_Command_flash(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       int retval;\r
-       u32 base = 0;\r
-       flash_bank_t *t = get_flash_bank_by_num_noprobe(0);\r
-       if (t != NULL)\r
-       {\r
-               base = t->base;\r
-               retval = JIM_OK;\r
-    } else\r
-       {\r
-               retval = JIM_ERR;\r
-       }\r
-\r
-       if (retval == JIM_OK)\r
-       {\r
-               Jim_SetResult(interp, Jim_NewIntObj(interp, base));\r
-       }\r
-\r
-       return retval;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-static int\r
-zylinjtag_Jim_Command_log(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);\r
-\r
-       if (logCount >= logSize)\r
-       {\r
-       Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer+logCount%logSize, logSize-logCount%logSize);\r
-       }\r
-       Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer, writePtr);\r
-\r
-       Jim_SetResult(interp, tclOutput);\r
-       return JIM_OK;\r
-}\r
-\r
-static int\r
-zylinjtag_Jim_Command_reboot(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       reboot();\r
-       return JIM_OK;\r
-}\r
-\r
-static int\r
-zylinjtag_Jim_Command_mac(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       int s;\r
-       struct ifreq ifr;\r
-       s = socket(AF_INET, SOCK_DGRAM, 0);\r
-       if (s >= 0)\r
-       {\r
-               strcpy(ifr.ifr_name, "eth0");\r
-               int res;\r
-               res = ioctl(s, SIOCGIFHWADDR, &ifr);\r
-               close(s);\r
-\r
-               if (res < 0)\r
-               {\r
-                       return JIM_OK;\r
-               }\r
-       }\r
-\r
-       Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);\r
-\r
-       char hwaddr[512];\r
-       sprintf(hwaddr, "%02x:%02x:%02x:%02x:%02x:%02x",\r
-                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[0],\r
-                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[1],\r
-                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[2],\r
-                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[3],\r
-                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[4],\r
-                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[5]);\r
-\r
-       Jim_AppendString(httpstate.jim_interp, tclOutput, hwaddr, strlen(hwaddr));\r
-\r
-       Jim_SetResult(interp, tclOutput);\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-static int\r
-zylinjtag_Jim_Command_ip(Jim_Interp *interp,\r
-                                   int argc,\r
-               Jim_Obj * const *argv)\r
-{\r
-       Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);\r
-\r
-       struct ifaddrs *ifa = NULL, *ifp = NULL;\r
-\r
-       if (getifaddrs(&ifp) < 0)\r
-       {\r
-               return JIM_ERR;\r
-       }\r
-\r
-       for (ifa = ifp; ifa; ifa = ifa->ifa_next)\r
-       {\r
-               char ip[200];\r
-               socklen_t salen;\r
-\r
-               if (ifa->ifa_addr->sa_family == AF_INET)\r
-                       salen = sizeof(struct sockaddr_in);\r
-               else if (ifa->ifa_addr->sa_family == AF_INET6)\r
-                       salen = sizeof(struct sockaddr_in6);\r
-               else\r
-                       continue;\r
-\r
-               if (getnameinfo(ifa->ifa_addr, salen, ip, sizeof(ip), NULL, 0,\r
-                               NI_NUMERICHOST) < 0)\r
-               {\r
-                       continue;\r
-               }\r
-\r
-               Jim_AppendString(httpstate.jim_interp, tclOutput, ip, strlen(ip));\r
-               break;\r
-\r
-       }\r
-\r
-       freeifaddrs(ifp);\r
-\r
-       Jim_SetResult(interp, tclOutput);\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-extern Jim_Interp *interp;\r
-\r
-static void zylinjtag_startNetwork()\r
-{\r
-       // Bring TCP/IP up immediately before we're ready to accept commands.\r
-       //\r
-       // That is as soon as a PING responds, we're accepting telnet sessions.\r
-#if defined(CYGPKG_NET_FREEBSD_STACK)\r
-       phi_init_all_network_interfaces();\r
-#else\r
-       lwip_init();\r
-#endif\r
-       if (!eth0_up)\r
-       {\r
-               diag_printf("Network not up and running\n");\r
-               exit(-1);\r
-       }\r
-#if defined(CYGPKG_NET_FREEBSD_STACK)\r
-       /*start TFTP*/\r
-       tftpd_start(69, &fileops);\r
-#endif\r
-\r
-       cyg_httpd_init_tcl_interpreter();\r
-\r
-       interp = httpstate.jim_interp;\r
-\r
-    Jim_CreateCommand(httpstate.jim_interp, "log", zylinjtag_Jim_Command_log, NULL, NULL);\r
-    Jim_CreateCommand(httpstate.jim_interp, "reboot", zylinjtag_Jim_Command_reboot, NULL, NULL);\r
-    Jim_CreateCommand(httpstate.jim_interp, "peek", zylinjtag_Jim_Command_peek, NULL, NULL);\r
-    Jim_CreateCommand(httpstate.jim_interp, "zy1000_flash", zylinjtag_Jim_Command_flash, NULL, NULL);\r
-    Jim_CreateCommand(httpstate.jim_interp, "poke", zylinjtag_Jim_Command_poke, NULL, NULL);\r
-    Jim_CreateCommand(httpstate.jim_interp, "ls", zylinjtag_Jim_Command_ls, NULL, NULL);\r
-    Jim_CreateCommand(httpstate.jim_interp, "getmem", zylinjtag_Jim_Command_getmem, NULL, NULL);\r
-    Jim_CreateCommand(httpstate.jim_interp, "mac", zylinjtag_Jim_Command_mac, NULL, NULL);\r
-    Jim_CreateCommand(httpstate.jim_interp, "ip", zylinjtag_Jim_Command_ip, NULL, NULL);\r
-    Jim_CreateCommand(httpstate.jim_interp, "rm", zylinjtag_Jim_Command_rm, NULL, NULL);\r
-\r
-       cyg_httpd_start();\r
-\r
-       webRunning = true;\r
-\r
-       diag_printf("Web server running\n");\r
-}\r
-\r
-static bool readPowerDropout()\r
-{\r
-       cyg_uint32 state;\r
-       // sample and clear power dropout\r
-       HAL_WRITE_UINT32(0x08000010, 0x80);\r
-       HAL_READ_UINT32(0x08000010, state);\r
-       bool powerDropout;\r
-       powerDropout = (state & 0x80) != 0;\r
-       return powerDropout;\r
-}\r
-\r
-bool readSRST()\r
-{\r
-       cyg_uint32 state;\r
-       // sample and clear SRST sensing\r
-       HAL_WRITE_UINT32(0x08000010, 0x00000040);\r
-       HAL_READ_UINT32(0x08000010, state);\r
-       bool srstAsserted;\r
-       srstAsserted = (state & 0x40) != 0;\r
-       return srstAsserted;\r
-}\r
-\r
-// every 300ms we check for reset & powerdropout and issue a "reset halt" if\r
-// so.\r
-\r
-\r
-static int sense_handler(void *priv)\r
-{\r
-       struct command_context_s *cmd_ctx;\r
-       cmd_ctx = (struct command_context_s *) priv;\r
-\r
-       static bool prevSrstAsserted = false;\r
-       static bool prevPowerdropout = false;\r
-\r
-       bool powerDropout;\r
-       powerDropout = readPowerDropout();\r
-\r
-       bool powerRestored;\r
-       powerRestored = prevPowerdropout && !powerDropout;\r
-       if (powerRestored)\r
-       {\r
-               LOG_USER("Sensed power restore.");\r
-       }\r
-\r
-       cyg_tick_count_t current = cyg_current_time();\r
-       static cyg_tick_count_t lastPower = 0;\r
-       bool waitMore = lastPower + 200 > current;\r
-       if (powerDropout && !waitMore)\r
-       {\r
-               LOG_USER("Sensed power dropout.");\r
-               lastPower = current;\r
-       }\r
-\r
-       bool srstAsserted = readSRST();\r
-\r
-       bool srstDeasserted;\r
-       srstDeasserted = prevSrstAsserted && !srstAsserted;\r
-\r
-       static cyg_tick_count_t lastSrst = 0;\r
-       waitMore = lastSrst + 200 > current;\r
-       if (srstDeasserted && !waitMore)\r
-       {\r
-               LOG_USER("Sensed nSRST deasserted");\r
-               lastSrst = current;\r
-       }\r
-\r
-       if (!prevSrstAsserted && srstAsserted)\r
-       {\r
-               LOG_USER("Sensed nSRST asserted");\r
-       }\r
-\r
-       prevSrstAsserted = srstAsserted;\r
-       prevPowerdropout = powerDropout;\r
-\r
-       if (srstDeasserted || powerRestored)\r
-       {\r
-               /* Other than logging the event we can't do anything here.\r
-                * Issuing a reset is a particularly bad idea as we might\r
-                * be inside a reset already.\r
-                */\r
-       }\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-\r
-static void\r
-print_exception_handler(cyg_addrword_t data, cyg_code_t exception, cyg_addrword_t info)\r
-{\r
-       writeLog = false;\r
-       serialLog = true;\r
-       char *infoStr = "unknown";\r
-       switch (exception)\r
-       {\r
-       case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION:\r
-               infoStr = "undefined instruction";\r
-               break;\r
-       case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT:\r
-               infoStr = "software interrupt";\r
-               break;\r
-       case CYGNUM_HAL_VECTOR_ABORT_PREFETCH:\r
-               infoStr = "abort prefetch";\r
-               break;\r
-       case CYGNUM_HAL_VECTOR_ABORT_DATA:\r
-               infoStr = "abort data";\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-\r
-       diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);\r
-\r
-       diag_printf("Dumping log\n---\n");\r
-       if (logCount >= logSize)\r
-       {\r
-               diag_write(logBuffer + logCount % logSize, logSize - logCount % logSize);\r
-       }\r
-       diag_write(logBuffer, writePtr);\r
-\r
-       diag_printf("---\nLogdump complete.\n");\r
-       diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);\r
-       diag_printf("\n---\nRebooting\n");\r
-       HAL_PLATFORM_RESET();\r
-\r
-}\r
-\r
-static void setHandler(cyg_code_t exception)\r
-{\r
-       cyg_exception_handler_t *old_handler;\r
-       cyg_addrword_t old_data;\r
-\r
-       cyg_exception_set_handler(exception,\r
-       print_exception_handler,\r
-       0,\r
-       &old_handler,\r
-       &old_data);\r
-}\r
-\r
-static cyg_thread zylinjtag_uart_thread_object;\r
-static cyg_handle_t zylinjtag_uart_thread_handle;\r
-static char uart_stack[4096];\r
-\r
-static char forwardBuffer[1024]; // NB! must be smaller than a TCP/IP packet!!!!!\r
-static char backwardBuffer[1024];\r
-\r
-static cyg_io_handle_t serial_handle;\r
-\r
-void setNoDelay(int session, int flag)\r
-{\r
-#if 1\r
-       // This decreases latency dramatically for e.g. GDB load which\r
-       // does not have a sliding window protocol\r
-       //\r
-       // Can cause *lots* of TCP/IP packets to be sent and it would have\r
-       // to be enabled/disabled on the fly to avoid the CPU being\r
-       // overloaded...\r
-       setsockopt(session, /* socket affected */\r
-       IPPROTO_TCP, /* set option at TCP level */\r
-       TCP_NODELAY, /* name of option */\r
-       (char *) &flag, /* the cast is historical\r
-        cruft */\r
-       sizeof(int)); /* length of option value */\r
-#endif\r
-}\r
-\r
-struct\r
-{\r
-       int req;\r
-       int actual;\r
-       int req2;\r
-       int actual2;\r
-} tcpipSent[512 * 1024];\r
-int cur;\r
-\r
-static void\r
-zylinjtag_uart(cyg_addrword_t data)\r
-{\r
-       int so_reuseaddr_option = 1;\r
-\r
-       int fd;\r
-       if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)\r
-       {\r
-               LOG_ERROR("error creating socket: %s", strerror(errno));\r
-               exit(-1);\r
-       }\r
-\r
-       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));\r
-\r
-       struct sockaddr_in sin;\r
-       unsigned int address_size;\r
-       address_size = sizeof(sin);\r
-       memset(&sin, 0, sizeof(sin));\r
-       sin.sin_family = AF_INET;\r
-       sin.sin_addr.s_addr = INADDR_ANY;\r
-       sin.sin_port = htons(5555);\r
-\r
-       if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)\r
-       {\r
-               LOG_ERROR("couldn't bind to socket: %s", strerror(errno));\r
-               exit(-1);\r
-       }\r
-\r
-       if (listen(fd, 1) == -1)\r
-       {\r
-               LOG_ERROR("couldn't listen on socket: %s", strerror(errno));\r
-               exit(-1);\r
-       }\r
-       //      socket_nonblock(fd);\r
-\r
-\r
-       for (;;)\r
-       {\r
-               int session = accept(fd, (struct sockaddr *) &sin, &address_size);\r
-               if (session < 0)\r
-               {\r
-                       continue;\r
-               }\r
-\r
-               setNoDelay(session, 1);\r
-               int oldopts = fcntl(session, F_GETFL, 0);\r
-               fcntl(session, F_SETFL, oldopts | O_NONBLOCK); //\r
-\r
-               int serHandle = open("/dev/ser0", O_RDWR | O_NONBLOCK);\r
-               if (serHandle < 0)\r
-               {\r
-                       close(session);\r
-                       continue;\r
-               }\r
-\r
-               start_profile();\r
-               int actual = 0;\r
-               int actual2 = 0;\r
-               int pos, pos2;\r
-               pos = 0;\r
-               pos2 = 0;\r
-               cur = 0;\r
-               for (;;)\r
-               {\r
-                       fd_set write_fds;\r
-                       fd_set read_fds;\r
-                       FD_ZERO(&write_fds);\r
-                       FD_ZERO(&read_fds);\r
-                       int fd_max = -1;\r
-                       FD_SET(session, &read_fds);\r
-                       fd_max = session;\r
-                       FD_SET(serHandle, &read_fds);\r
-                       if (serHandle > fd_max)\r
-                       {\r
-                               fd_max = serHandle;\r
-                       }\r
-                       /* Wait... */\r
-\r
-                       cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received\r
-                       if ((actual == 0) && (actual2 == 0))\r
-                       {\r
-                               int retval = select(fd_max + 1, &read_fds, NULL, NULL, NULL);\r
-                               if (retval <= 0)\r
-                               {\r
-                                       break;\r
-                               }\r
-                       }\r
-\r
-                       if (actual2 <= 0)\r
-                       {\r
-                               memset(backwardBuffer, 's', sizeof(backwardBuffer));\r
-                               actual2=read(serHandle, backwardBuffer, sizeof(backwardBuffer));\r
-                               if (actual2 < 0)\r
-                               {\r
-                                       if (errno != EAGAIN)\r
-                                       {\r
-                                               goto closeSession;\r
-                                       }\r
-                                       actual2 = 0;\r
-                               }\r
-                               pos2 = 0;\r
-                       }\r
-\r
-                       int x = actual2;\r
-                       int y = 0;\r
-                       if (actual2 > 0)\r
-                       {\r
-                               int written = write(session, backwardBuffer + pos2, actual2);\r
-                               if (written <= 0)\r
-                                       goto closeSession;\r
-                               actual2 -= written;\r
-                               pos2 += written;\r
-                               y = written;\r
-                       }\r
-\r
-                       if (FD_ISSET(session, &read_fds)&&(sizeof(forwardBuffer)>actual))\r
-                       {\r
-                               // NB! Here it is important that we empty the TCP/IP read buffer\r
-                               // to make transmission tick right\r
-                               memmove(forwardBuffer, forwardBuffer + pos, actual);\r
-                               pos = 0;\r
-                               int t;\r
-                               // this will block if there is no data at all\r
-                               t=read_socket(session, forwardBuffer+actual, sizeof(forwardBuffer)-actual);\r
-                               if (t <= 0)\r
-                               {\r
-                                       goto closeSession;\r
-                               }\r
-                               actual += t;\r
-                       }\r
-\r
-                       int x2 = actual;\r
-                       int y2 = 0;\r
-                       if (actual > 0)\r
-                       {\r
-                               /* Do not put things into the serial buffer if it has something to send\r
-                                * as that can cause a single byte to be sent at the time.\r
-                                *\r
-                                *\r
-                                */\r
-                               int written = write(serHandle, forwardBuffer + pos, actual);\r
-                               if (written < 0)\r
-                               {\r
-                                       if (errno != EAGAIN)\r
-                                       {\r
-                                               goto closeSession;\r
-                                       }\r
-                                       // The serial buffer is full\r
-                                       written = 0;\r
-                               } else\r
-                               {\r
-                                       actual -= written;\r
-                                       pos += written;\r
-                               }\r
-                               y2 = written;\r
-                       }\r
-                       if (cur < 1024)\r
-                       {\r
-                               tcpipSent[cur].req = x;\r
-                               tcpipSent[cur].actual = y;\r
-                               tcpipSent[cur].req2 = x2;\r
-                               tcpipSent[cur].actual2 = y2;\r
-                               cur++;\r
-                       }\r
-\r
-               }\r
-           closeSession:\r
-           close(session);\r
-               close(serHandle);\r
-\r
-               int i;\r
-               for (i = 0; i < 1024; i++)\r
-               {\r
-               diag_printf("%d %d %d %d\n", tcpipSent[i].req, tcpipSent[i].actual, tcpipSent[i].req2, tcpipSent[i].actual2);\r
-\r
-               }\r
-       }\r
-       close(fd);\r
-\r
-}\r
-\r
-void startUart(void)\r
-{\r
-    cyg_thread_create(1,\r
-                      zylinjtag_uart,\r
-                      (cyg_addrword_t)0,\r
-                      "uart thread",\r
-                      (void *)uart_stack,\r
-                      sizeof(uart_stack),\r
-                      &zylinjtag_uart_thread_handle,\r
-                      &zylinjtag_uart_thread_object);\r
-       cyg_thread_set_priority(zylinjtag_uart_thread_handle, 1); // low priority as it sits in a busy loop\r
-       cyg_thread_resume(zylinjtag_uart_thread_handle);\r
-}\r
-\r
-\r
-\r
-int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       if (argc != 1)\r
-       {\r
-               command_print(cmd_ctx, "usage: uart <baudrate>");\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-\r
-       int baud = atol(args[0]);\r
-\r
-       switch (baud)\r
-       {\r
-       case 9600:\r
-               baud = CYGNUM_SERIAL_BAUD_9600;\r
-               break;\r
-       case 19200:\r
-               baud = CYGNUM_SERIAL_BAUD_19200;\r
-               break;\r
-       case 38400:\r
-               baud = CYGNUM_SERIAL_BAUD_38400;\r
-               break;\r
-       case 57600:\r
-               baud = CYGNUM_SERIAL_BAUD_57600;\r
-               break;\r
-       case 115200:\r
-               baud = CYGNUM_SERIAL_BAUD_115200;\r
-               break;\r
-       case 230400:\r
-               baud = CYGNUM_SERIAL_BAUD_230400;\r
-               break;\r
-       default:\r
-               command_print(cmd_ctx, "unsupported baudrate");\r
-               return ERROR_INVALID_ARGUMENTS;\r
-       }\r
-\r
-       cyg_serial_info_t buf;\r
-       cyg_uint32 len = 1;\r
-       //get existing serial configuration\r
-       len = sizeof(cyg_serial_info_t);\r
-       int err;\r
-       err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buf, &len);\r
-       err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &buf, &len);\r
-       if (err != ENOERR)\r
-       {\r
-               command_print(cmd_ctx, "Failed to get serial port settings %d", err);\r
-               return ERROR_OK;\r
-       }\r
-       buf.baud = baud;\r
-\r
-       err = cyg_io_set_config(serial_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &buf, &len);\r
-       if (err != ENOERR)\r
-       {\r
-               command_print(cmd_ctx, "Failed to set serial port settings %d", err);\r
-               return ERROR_OK;\r
-       }\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-bool logAllToSerial = false;\r
-\r
-/* boolean parameter stored on config */\r
-bool boolParam(char *var)\r
-{\r
-       bool result = false;\r
-       char *name = alloc_printf(ZYLIN_CONFIG_DIR "/%s", var);\r
-       if (name == NULL)\r
-               return result;\r
-\r
-       void *data;\r
-       int len;\r
-       if (loadFile(name, &data, &len) == ERROR_OK)\r
-       {\r
-               if (len > 1)\r
-                       len = 1;\r
-               result = strncmp((char *) data, "1", len) == 0;\r
-               free(data);\r
-       }\r
-       free(name);\r
-       return result;\r
-}\r
-\r
-command_context_t *setup_command_handler();\r
-\r
-int add_default_dirs(void)\r
-{\r
-       add_script_search_dir(ZYLIN_CONFIG_DIR);\r
-       add_script_search_dir("/rom/lib/openocd");\r
-       add_script_search_dir("/rom");\r
-       return ERROR_OK;\r
-}\r
-\r
-int main(int argc, char *argv[])\r
-{\r
-       setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION);\r
-       setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH);\r
-       setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA);\r
-\r
-       int err;\r
-       err = cyg_io_lookup("/dev/ser0", &serial_handle);\r
-       if (err != ENOERR)\r
-       {\r
-               diag_printf("/dev/ser0 not found\n");\r
-               reboot();\r
-       }\r
-\r
-       setPower(true); // on by default\r
-\r
-       atexit(keep_webserver);\r
-\r
-       err = mount("", "/ram", "ramfs");\r
-       if (err < 0)\r
-       {\r
-               diag_printf("unable to mount ramfs\n");\r
-       }\r
-       chdir("/ram");\r
-\r
-       char address[16];\r
-       sprintf(address, "%p", &filedata[0]);\r
-       err = mount(address, "/rom", "romfs");\r
-       if (err < 0)\r
-       {\r
-               diag_printf("unable to mount /rom\n");\r
-       }\r
-\r
-       err = mount("", "/log", "logfs");\r
-       if (err < 0)\r
-       {\r
-               diag_printf("unable to mount logfs\n");\r
-       }\r
-\r
-       err = mount("", "/tftp", "tftpfs");\r
-       if (err < 0)\r
-       {\r
-               diag_printf("unable to mount logfs\n");\r
-       }\r
-\r
-       log = fopen("/log/log", "w");\r
-       if (log == NULL)\r
-       {\r
-               diag_printf("Could not open log file /ram/log\n");\r
-               exit(-1);\r
-       }\r
-\r
-       diag_init_putc(_zylinjtag_diag_write_char);\r
-\r
-       // We want this in the log.\r
-       diag_printf("Zylin ZY1000. Copyright Zylin AS 2007-2008.\n");\r
-       diag_printf("%s\n", ZYLIN_OPENOCD_VERSION);\r
-\r
-       copydir("/rom/");\r
-\r
-       err = mount("/dev/flash1", "/config", "jffs2");\r
-       if (err < 0)\r
-       {\r
-               diag_printf("unable to mount jffs\n");\r
-       }\r
-\r
-\r
-       mkdir(ZYLIN_CONFIG_DIR, 0777);\r
-       mkdir(ZYLIN_CONFIG_DIR "/target", 0777);\r
-       mkdir(ZYLIN_CONFIG_DIR "/event", 0777);\r
-\r
-       logAllToSerial = boolParam("logserial");\r
-\r
-       // We need the network & web server in case there is something wrong with\r
-       // the config files that invoke exit()\r
-       zylinjtag_startNetwork();\r
-\r
-       /* we're going to access the jim interpreter from here on... */\r
-       openocd_sleep_postlude();\r
-       startUart();\r
-\r
-       add_default_dirs();\r
-\r
-       /* initialize commandline interface */\r
-       command_context_t *cmd_ctx;\r
-       cmd_ctx = setup_command_handler();\r
-       command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);\r
-       command_context_mode(cmd_ctx, COMMAND_CONFIG);\r
-\r
-\r
-       register_command(cmd_ctx, NULL, "zy1000_version", handle_zy1000_version_command,\r
-                       COMMAND_EXEC, "show zy1000 version numbers");\r
-\r
-       register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,\r
-                       "rm <filname>");\r
-\r
-       register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,\r
-                       "same args as load_image, image stored in memory");\r
-\r
-       register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,\r
-                       "loads active fast load image to current target");\r
-\r
-       register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,\r
-                       "cat <filname>");\r
-\r
-       register_command(cmd_ctx, NULL, "trunc", handle_trunc_command, COMMAND_ANY,\r
-                       "trunc <filname>");\r
-\r
-       register_command(cmd_ctx, NULL, "append_file", handle_append_command,\r
-                       COMMAND_ANY, "append <filname>");\r
-\r
-       register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY,\r
-                       "power <on/off> - turn power switch to target on/off. No arguments - print status.");\r
-\r
-       register_command(cmd_ctx, NULL, "meminfo", handle_meminfo_command,\r
-                       COMMAND_ANY, "meminfo");\r
-\r
-       register_command(cmd_ctx, NULL, "cp", handle_cp_command,\r
-                                        COMMAND_ANY, "cp <from> <to>");\r
-\r
-#ifdef CYGPKG_PROFILE_GPROF\r
-       register_command(cmd_ctx, NULL, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command,\r
-                       COMMAND_ANY, NULL);\r
-#endif\r
-       register_command(cmd_ctx, NULL, "uart", handle_uart_command,\r
-                                        COMMAND_ANY, "uart <baud>  - forward uart on port 5555");\r
-\r
-\r
-       int errVal;\r
-       errVal = log_init(cmd_ctx);\r
-       if (errVal != ERROR_OK)\r
-       {\r
-               diag_printf("log_init() failed %d\n", errVal);\r
-               exit(-1);\r
-       }\r
-\r
-       set_log_output(cmd_ctx, log);\r
-\r
-       LOG_DEBUG("log init complete");\r
-\r
-       //      diag_printf("Executing config files\n");\r
-\r
-       if (logAllToSerial)\r
-       {\r
-               diag_printf(ZYLIN_CONFIG_DIR "/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n");\r
-               command_run_line(cmd_ctx, "debug_level 3");\r
-       }\r
-\r
-       zylinjtag_parse_config_file(cmd_ctx, "/rom/openocd.cfg");\r
-\r
-       target_register_timer_callback(sense_handler, 200, 1, cmd_ctx);\r
-\r
-       // FIX!!!  Yuk!\r
-       // diag_printf() is really invoked from many more places than we trust it\r
-       // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).\r
-       //\r
-       // Disabling it here is safe and gives us enough logged debug output for now. Crossing\r
-       // fingers that it doesn't cause any crashes.\r
-       diag_printf("Init complete, GDB & telnet servers launched.\n");\r
-       command_set_output_handler(cmd_ctx, zy1000_configuration_output_handler_log, NULL);\r
-       if (!logAllToSerial)\r
-       {\r
-               serialLog = false;\r
-       }\r
-\r
-       /* handle network connections */\r
-       server_loop(cmd_ctx);\r
-       openocd_sleep_prelude();\r
-\r
-       /* shut server down */\r
-       server_quit();\r
-\r
-       /* free commandline interface */\r
-       command_done(cmd_ctx);\r
-       umount("/config");\r
-\r
-       exit(0);\r
-       for (;;);\r
-}\r
-\r
-\r
-\r
-cyg_int32\r
-cyg_httpd_exec_cgi_tcl(char *file_name);\r
-cyg_int32 homeForm(CYG_HTTPD_STATE *p)\r
-{\r
-       cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");\r
-       return 0;\r
-}\r
-\r
-CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label, "/", homeForm);\r
-\r
-CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label, "text", "text/plain");\r
-CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label, "bin", "application/octet-stream");\r
-\r
-#include <pkgconf/system.h>\r
-#include <pkgconf/hal.h>\r
-#include <pkgconf/kernel.h>\r
-#include <pkgconf/io_fileio.h>\r
-#include <pkgconf/fs_rom.h>\r
-\r
-#include <cyg/kernel/ktypes.h>         // base kernel types\r
-#include <cyg/infra/cyg_trac.h>        // tracing macros\r
-#include <cyg/infra/cyg_ass.h>         // assertion macros\r
-#include <unistd.h>\r
-#include <sys/types.h>\r
-#include <fcntl.h>\r
-#include <sys/stat.h>\r
-#include <errno.h>\r
-#include <dirent.h>\r
-\r
-#include <stdarg.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-#include <cyg/fileio/fileio.h>\r
-\r
-#include <cyg/kernel/kapi.h>\r
-#include <cyg/infra/diag.h>\r
-\r
-//==========================================================================\r
-// Eventually we want to eXecute In Place from the ROM in a protected\r
-// environment, so we'll need executables to be aligned to a boundary\r
-// suitable for MMU protection. A suitable boundary would be the 4k\r
-// boundary in all the CPU architectures I am currently aware of.\r
-\r
-// Forward definitions\r
-\r
-// Filesystem operations\r
-static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);\r
-static int tftpfs_umount(cyg_mtab_entry *mte);\r
-static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,\r
-               int mode, cyg_file *fte);\r
-static int tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);\r
-static int tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);\r
-\r
-// File operations\r
-static int tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);\r
-static int tftpfs_fo_close(struct CYG_FILE_TAG *fp);\r
-static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence);\r
-\r
-//==========================================================================\r
-// Filesystem table entries\r
-\r
-// -------------------------------------------------------------------------\r
-// Fstab entry.\r
-// This defines the entry in the filesystem table.\r
-// For simplicity we use _FILESYSTEM synchronization for all accesses since\r
-// we should never block in any filesystem operations.\r
-#if 1\r
-FSTAB_ENTRY( tftpfs_fste, "tftpfs", 0,\r
-               CYG_SYNCMODE_NONE,\r
-               tftpfs_mount,\r
-               tftpfs_umount,\r
-               tftpfs_open,\r
-               (cyg_fsop_unlink *)cyg_fileio_erofs,\r
-               (cyg_fsop_mkdir *)cyg_fileio_erofs,\r
-               (cyg_fsop_rmdir *)cyg_fileio_erofs,\r
-               (cyg_fsop_rename *)cyg_fileio_erofs,\r
-               (cyg_fsop_link *)cyg_fileio_erofs,\r
-               (cyg_fsop_opendir *)cyg_fileio_erofs,\r
-               (cyg_fsop_chdir *)cyg_fileio_erofs,\r
-               (cyg_fsop_stat *)cyg_fileio_erofs,\r
-               (cyg_fsop_getinfo *)cyg_fileio_erofs,\r
-               (cyg_fsop_setinfo *)cyg_fileio_erofs);\r
-#endif\r
-\r
-// -------------------------------------------------------------------------\r
-// mtab entry.\r
-// This defines a single ROMFS loaded into ROM at the configured address\r
-//\r
-// MTAB_ENTRY( rom_mte,        // structure name\r
-//             "/rom",         // mount point\r
-//             "romfs",        // FIlesystem type\r
-//             "",             // hardware device\r
-//  (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS  // Address in ROM\r
-//           );\r
-\r
-\r
-// -------------------------------------------------------------------------\r
-// File operations.\r
-// This set of file operations are used for normal open files.\r
-\r
-static cyg_fileops tftpfs_fileops =\r
-{\r
-       tftpfs_fo_read,\r
-       tftpfs_fo_write,\r
-       tftpfs_fo_lseek,\r
-       (cyg_fileop_ioctl *)cyg_fileio_erofs,\r
-    cyg_fileio_seltrue,\r
-    tftpfs_fo_fsync,\r
-    tftpfs_fo_close,\r
-               (cyg_fileop_fstat *) cyg_fileio_erofs,\r
-               (cyg_fileop_getinfo *) cyg_fileio_erofs,\r
-       (cyg_fileop_setinfo *)cyg_fileio_erofs,\r
-};\r
-\r
-// -------------------------------------------------------------------------\r
-// tftpfs_mount()\r
-// Process a mount request. This mainly finds root for the\r
-// filesystem.\r
-\r
-static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)\r
-{\r
-       return ENOERR;\r
-}\r
-\r
-static int tftpfs_umount(cyg_mtab_entry *mte)\r
-{\r
-       return ENOERR;\r
-}\r
-\r
-struct Tftp\r
-{\r
-       int write;\r
-       int readFile;\r
-       cyg_uint8 *mem;\r
-       int actual;\r
-       char *server;\r
-       char *file;\r
-};\r
-\r
-static void freeTftp(struct Tftp *t)\r
-{\r
-       if (t == NULL)\r
-               return;\r
-       if (t->mem)\r
-               free(t->mem);\r
-       if (t->server)\r
-               free(t->server);\r
-       if (t->file)\r
-               free(t->file);\r
-       free(t);\r
-}\r
-\r
-static const int tftpMaxSize = 8192 * 1024;\r
-static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,\r
-               int mode, cyg_file *file)\r
-{\r
-       struct Tftp *tftp;\r
-       tftp = malloc(sizeof(struct Tftp));\r
-       if (tftp == NULL)\r
-               return EMFILE;\r
-       memset(tftp, 0, sizeof(struct Tftp));\r
-\r
-       file->f_flag |= mode & CYG_FILE_MODE_MASK;\r
-       file->f_type = CYG_FILE_TYPE_FILE;\r
-       file->f_ops = &tftpfs_fileops;\r
-       file->f_offset = 0;\r
-       file->f_data = 0;\r
-       file->f_xops = 0;\r
-\r
-       tftp->mem = malloc(tftpMaxSize);\r
-       if (tftp->mem == NULL)\r
-       {\r
-               freeTftp(tftp);\r
-               return EMFILE;\r
-       }\r
-\r
-       char *server = strchr(name, '/');\r
-       if (server == NULL)\r
-       {\r
-               freeTftp(tftp);\r
-               return EMFILE;\r
-       }\r
-\r
-       tftp->server = malloc(server - name + 1);\r
-       if (tftp->server == NULL)\r
-       {\r
-               freeTftp(tftp);\r
-               return EMFILE;\r
-       }\r
-       strncpy(tftp->server, name, server - name);\r
-       tftp->server[server - name] = 0;\r
-\r
-       tftp->file = strdup(server + 1);\r
-       if (tftp->file == NULL)\r
-       {\r
-               freeTftp(tftp);\r
-               return EMFILE;\r
-       }\r
-\r
-       file->f_data = (CYG_ADDRWORD) tftp;\r
-\r
-       return ENOERR;\r
-}\r
-\r
-static int fetchTftp(struct Tftp *tftp)\r
-{\r
-       if (!tftp->readFile)\r
-       {\r
-               int err;\r
-           tftp->actual = tftp_client_get( tftp->file, tftp->server, 0, tftp->mem, tftpMaxSize,   TFTP_OCTET, &err);\r
-\r
-               if (tftp->actual < 0)\r
-               {\r
-                       return EMFILE;\r
-               }\r
-               tftp->readFile = 1;\r
-       }\r
-       return ENOERR;\r
-}\r
-\r
-// -------------------------------------------------------------------------\r
-// tftpfs_fo_write()\r
-// Read data from file.\r
-\r
-static int\r
-tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)\r
-{\r
-       struct Tftp *tftp = (struct Tftp *) fp->f_data;\r
-\r
-       if (fetchTftp(tftp) != ENOERR)\r
-               return EMFILE;\r
-\r
-       int i;\r
-       off_t pos = fp->f_offset;\r
-       int resid = 0;\r
-       for (i = 0; i < uio->uio_iovcnt; i++)\r
-       {\r
-               cyg_iovec *iov = &uio->uio_iov[i];\r
-               char *buf = (char *) iov->iov_base;\r
-               off_t len = iov->iov_len;\r
-\r
-               if (len + pos > tftp->actual)\r
-               {\r
-                       len = tftp->actual - pos;\r
-               }\r
-               resid += iov->iov_len - len;\r
-\r
-               memcpy(buf, tftp->mem + pos, len);\r
-               pos += len;\r
-\r
-       }\r
-       uio->uio_resid = resid;\r
-       fp->f_offset = pos;\r
-\r
-       return ENOERR;\r
-}\r
-\r
-\r
-static int\r
-tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)\r
-{\r
-       struct Tftp *tftp = (struct Tftp *) fp->f_data;\r
-\r
-       int i;\r
-       off_t pos = fp->f_offset;\r
-       int resid = 0;\r
-       for (i = 0; i < uio->uio_iovcnt; i++)\r
-       {\r
-               cyg_iovec *iov = &uio->uio_iov[i];\r
-               char *buf = (char *) iov->iov_base;\r
-               off_t len = iov->iov_len;\r
-\r
-               if (len + pos > tftpMaxSize)\r
-               {\r
-                       len = tftpMaxSize - pos;\r
-               }\r
-               resid += iov->iov_len - len;\r
-\r
-               memcpy(tftp->mem + pos, buf, len);\r
-               pos += len;\r
-\r
-       }\r
-       uio->uio_resid = resid;\r
-       fp->f_offset = pos;\r
-\r
-       tftp->write = 1;\r
-\r
-       return ENOERR;\r
-}\r
-\r
-static int\r
-tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)\r
-{\r
-       int error = ENOERR;\r
-       return error;\r
-}\r
-\r
-// -------------------------------------------------------------------------\r
-// romfs_fo_close()\r
-// Close a file. We just clear out the data pointer.\r
-\r
-static int tftpfs_fo_close(struct CYG_FILE_TAG *fp)\r
-{\r
-       struct Tftp *tftp = (struct Tftp *) fp->f_data;\r
-       int error = ENOERR;\r
-\r
-       if (tftp->write)\r
-       {\r
-           tftp_client_put( tftp->file, tftp->server, 0, tftp->mem, fp->f_offset,   TFTP_OCTET, &error);\r
-       }\r
-\r
-       freeTftp(tftp);\r
-       fp->f_data = 0;\r
-       return error;\r
-}\r
-\r
-// -------------------------------------------------------------------------\r
-// romfs_fo_lseek()\r
-// Seek to a new file position.\r
-\r
-static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence)\r
-{\r
-       struct Tftp *tftp = (struct Tftp *) fp->f_data;\r
-       off_t pos = *apos;\r
-\r
-       if (fetchTftp(tftp) != ENOERR)\r
-               return EMFILE;\r
-\r
-       switch (whence)\r
-       {\r
-       case SEEK_SET:\r
-               // Pos is already where we want to be.\r
-               break;\r
-\r
-       case SEEK_CUR:\r
-               // Add pos to current offset.\r
-               pos += fp->f_offset;\r
-               break;\r
-\r
-       case SEEK_END:\r
-               // Add pos to file size.\r
-               pos += tftp->actual;\r
-               break;\r
-\r
-       default:\r
-               return EINVAL;\r
-       }\r
-\r
-       // Check that pos is still within current file size, or at the\r
-       // very end.\r
-       if (pos < 0 || pos > tftp->actual)\r
-               return EINVAL;\r
-\r
-       // All OK, set fp offset and return new position.\r
-       *apos = fp->f_offset = pos;\r
-\r
-       return ENOERR;\r
-}\r
-\r
-void usleep(int us)\r
-{\r
-       if (us > 10000)\r
-               cyg_thread_delay(us / 10000 + 1);\r
-       else\r
-               HAL_DELAY_US(us);\r
-}\r
-\r
-// Chunked version.\r
-cyg_int32\r
-show_log_entry(CYG_HTTPD_STATE *phttpstate)\r
-{\r
-       cyg_httpd_start_chunked("text");\r
-       if (logCount >= logSize)\r
-       {\r
-        cyg_httpd_write_chunked(logBuffer+logCount%logSize, logSize-logCount%logSize);\r
-       }\r
-       cyg_httpd_write_chunked(logBuffer, writePtr);\r
-       cyg_httpd_end_chunked();\r
-       return -1;\r
-}\r
-\r
-CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log, "/ram/log", show_log_entry);\r
-\r
-// Filesystem operations\r
-static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);\r
-static int logfs_umount(cyg_mtab_entry *mte);\r
-static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,\r
-               int mode, cyg_file *fte);\r
-static int\r
-logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);\r
-\r
-// File operations\r
-static int logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);\r
-static int logfs_fo_close(struct CYG_FILE_TAG *fp);\r
-\r
-//==========================================================================\r
-// Filesystem table entries\r
-\r
-// -------------------------------------------------------------------------\r
-// Fstab entry.\r
-// This defines the entry in the filesystem table.\r
-// For simplicity we use _FILESYSTEM synchronization for all accesses since\r
-// we should never block in any filesystem operations.\r
-FSTAB_ENTRY( logfs_fste, "logfs", 0,\r
-               CYG_SYNCMODE_FILE_FILESYSTEM|CYG_SYNCMODE_IO_FILESYSTEM,\r
-               logfs_mount,\r
-               logfs_umount,\r
-               logfs_open,\r
-               (cyg_fsop_unlink *)cyg_fileio_erofs,\r
-               (cyg_fsop_mkdir *)cyg_fileio_erofs,\r
-               (cyg_fsop_rmdir *)cyg_fileio_erofs,\r
-               (cyg_fsop_rename *)cyg_fileio_erofs,\r
-               (cyg_fsop_link *)cyg_fileio_erofs,\r
-               (cyg_fsop_opendir *)cyg_fileio_erofs,\r
-               (cyg_fsop_chdir *)cyg_fileio_erofs,\r
-               (cyg_fsop_stat *)cyg_fileio_erofs,\r
-               (cyg_fsop_getinfo *)cyg_fileio_erofs,\r
-               (cyg_fsop_setinfo *)cyg_fileio_erofs);\r
-\r
-// -------------------------------------------------------------------------\r
-// File operations.\r
-// This set of file operations are used for normal open files.\r
-\r
-static cyg_fileops logfs_fileops =\r
-{\r
-       (cyg_fileop_read *)cyg_fileio_erofs,\r
-    (cyg_fileop_write *)logfs_fo_write,\r
-               (cyg_fileop_lseek *) cyg_fileio_erofs,\r
-       (cyg_fileop_ioctl *)cyg_fileio_erofs,\r
-    cyg_fileio_seltrue,\r
-    logfs_fo_fsync,\r
-    logfs_fo_close,\r
-       (cyg_fileop_fstat *)cyg_fileio_erofs,\r
-               (cyg_fileop_getinfo *) cyg_fileio_erofs,\r
-       (cyg_fileop_setinfo *)cyg_fileio_erofs,\r
-};\r
-\r
-// -------------------------------------------------------------------------\r
-// logfs_mount()\r
-// Process a mount request. This mainly finds root for the\r
-// filesystem.\r
-\r
-static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)\r
-{\r
-       return ENOERR;\r
-}\r
-\r
-static int logfs_umount(cyg_mtab_entry *mte)\r
-{\r
-       return ENOERR;\r
-}\r
-\r
-static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,\r
-               int mode, cyg_file *file)\r
-{\r
-       file->f_flag |= mode & CYG_FILE_MODE_MASK;\r
-       file->f_type = CYG_FILE_TYPE_FILE;\r
-       file->f_ops = &logfs_fileops;\r
-       file->f_offset = 0;\r
-       file->f_data = 0;\r
-       file->f_xops = 0;\r
-       return ENOERR;\r
-}\r
-\r
-// -------------------------------------------------------------------------\r
-// logfs_fo_write()\r
-// Write data to file.\r
-\r
-static int\r
-logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)\r
-{\r
-       int i;\r
-       for (i = 0; i < uio->uio_iovcnt; i++)\r
-       {\r
-               cyg_iovec *iov = &uio->uio_iov[i];\r
-               char *buf = (char *) iov->iov_base;\r
-               off_t len = iov->iov_len;\r
-\r
-               diag_write(buf, len);\r
-       }\r
-       uio->uio_resid = 0;\r
-\r
-       return ENOERR;\r
-}\r
-static int\r
-logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)\r
-{\r
-       return ENOERR;\r
-}\r
-\r
-// -------------------------------------------------------------------------\r
-// romfs_fo_close()\r
-// Close a file. We just clear out the data pointer.\r
-\r
-static int logfs_fo_close(struct CYG_FILE_TAG *fp)\r
-{\r
-       return ENOERR;\r
-}\r
+/***************************************************************************
+ *   Copyright (C) 2007-2008 by Ã˜yvind Harboe                              *
+ *                                                                         *
+ *   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.             *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "log.h"
+#include "types.h"
+#include "jtag.h"
+#include "configuration.h"
+#include "xsvf.h"
+#include "target.h"
+#include "flash.h"
+#include "nand.h"
+#include "pld.h"
+
+#include "command.h"
+#include "server.h"
+#include "telnet_server.h"
+#include "gdb_server.h"
+
+#include <time_support.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <cyg/io/flash.h>
+#include <pkgconf/fs_jffs2.h>  // Address of JFFS2
+#include <network.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <cyg/fileio/fileio.h>
+#include <dirent.h>
+#include <cyg/athttpd/http.h>
+#include <cyg/athttpd/socket.h>
+#include <cyg/athttpd/handler.h>
+#include <cyg/athttpd/cgi.h>
+#include <cyg/athttpd/forms.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/kernel/kapi.h>
+#include <cyg/io/serialio.h>
+#include <cyg/io/io.h>
+#include <netinet/tcp.h>
+#include "rom.h"
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <ifaddrs.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#define MAX_IFS 64
+#if defined(CYGPKG_NET_FREEBSD_STACK)
+#include <tftp_support.h>
+/* posix compatibility broken*/
+struct tftpd_fileops fileops =
+{
+       (int (*)(const char *, int))open,
+       close,
+       (int (*)(int, const void *, int))write,
+       ( int (*)(int, void *, int))read
+};
+
+#endif
+
+#define ZYLIN_VERSION "1.43"
+#define ZYLIN_DATE __DATE__
+#define ZYLIN_TIME __TIME__
+/* hmmm....  we can't pick up the right # during build if we've checked this out
+ * in Eclipse... arrggghh...*/
+#define ZYLIN_OPENOCD 1005
+#define ZYLIN_OPENOCD_VERSION "Zylin JTAG ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE " " ZYLIN_TIME
+#define ZYLIN_CONFIG_DIR "/config/settings"
+
+void diag_write(char *buf, int len)
+{
+       int j;
+       for (j = 0; j < len; j++)
+       {
+               diag_printf("%c", buf[j]);
+       }
+}
+
+static bool serialLog = true;
+static bool writeLog = true;
+
+
+struct FastLoad
+{
+       u32 address;
+       u8 *data;
+       int length;
+
+};
+
+static int fastload_num;
+static struct FastLoad *fastload;
+
+static void free_fastload()
+{
+       if (fastload!=NULL)
+       {
+               int i;
+               for (i=0; i<fastload_num; i++)
+               {
+                       if (fastload[i].data)
+                               free(fastload[i].data);
+               }
+               free(fastload);
+               fastload=NULL;
+       }
+}
+
+
+int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       u8 *buffer;
+       u32 buf_cnt;
+       u32 image_size;
+       u32 min_address=0;
+       u32 max_address=0xffffffff;
+       int i;
+       int retval;
+
+       image_t image;
+
+       duration_t duration;
+       char *duration_text;
+
+       if ((argc < 1)||(argc > 5))
+       {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
+       if (argc >= 2)
+       {
+               image.base_address_set = 1;
+               image.base_address = strtoul(args[1], NULL, 0);
+       }
+       else
+       {
+               image.base_address_set = 0;
+       }
+
+
+       image.start_address_set = 0;
+
+       if (argc>=4)
+       {
+               min_address=strtoul(args[3], NULL, 0);
+       }
+       if (argc>=5)
+       {
+               max_address=strtoul(args[4], NULL, 0)+min_address;
+       }
+
+       if (min_address>max_address)
+       {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       duration_start_measure(&duration);
+
+       if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
+       {
+               return ERROR_OK;
+       }
+
+       image_size = 0x0;
+       retval = ERROR_OK;
+       fastload_num=image.num_sections;
+       fastload=(struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
+       if (fastload==NULL)
+       {
+               image_close(&image);
+               return ERROR_FAIL;
+       }
+       memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
+       for (i = 0; i < image.num_sections; i++)
+       {
+               buffer = malloc(image.sections[i].size);
+               if (buffer == NULL)
+               {
+                       command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
+                       break;
+               }
+
+               if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
+               {
+                       free(buffer);
+                       break;
+               }
+
+               u32 offset=0;
+               u32 length=buf_cnt;
+
+
+               /* DANGER!!! beware of unsigned comparision here!!! */
+
+               if ((image.sections[i].base_address+buf_cnt>=min_address)&&
+                               (image.sections[i].base_address<max_address))
+               {
+                       if (image.sections[i].base_address<min_address)
+                       {
+                               /* clip addresses below */
+                               offset+=min_address-image.sections[i].base_address;
+                               length-=offset;
+                       }
+
+                       if (image.sections[i].base_address+buf_cnt>max_address)
+                       {
+                               length-=(image.sections[i].base_address+buf_cnt)-max_address;
+                       }
+
+                       fastload[i].address=image.sections[i].base_address+offset;
+                       fastload[i].data=malloc(length);
+                       if (fastload[i].data==NULL)
+                       {
+                               free(buffer);
+                               break;
+                       }
+                       memcpy(fastload[i].data, buffer+offset, length);
+                       fastload[i].length=length;
+
+                       image_size += length;
+                       command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
+               }
+
+               free(buffer);
+       }
+
+       duration_stop_measure(&duration, &duration_text);
+       if (retval==ERROR_OK)
+       {
+               command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);
+       }
+       free(duration_text);
+
+       image_close(&image);
+
+       if (retval!=ERROR_OK)
+       {
+               free_fastload();
+       }
+
+       return retval;
+}
+
+int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc>0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       if (fastload==NULL)
+       {
+               LOG_ERROR("No image in memory");
+               return ERROR_FAIL;
+       }
+       int i;
+       int ms=timeval_ms();
+       int size=0;
+       for (i=0; i<fastload_num;i++)
+       {
+               int retval;
+               target_t *target = get_current_target(cmd_ctx);
+               if ((retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data)) != ERROR_OK)
+               {
+                       return retval;
+               }
+               size+=fastload[i].length;
+       }
+       int after=timeval_ms();
+       command_print(cmd_ctx, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
+       return ERROR_OK;
+}
+
+
+/* Give TELNET a way to find out what version this is */
+int handle_zy1000_version_command(struct command_context_s *cmd_ctx, char *cmd,
+               char **args, int argc)
+{
+       if (argc > 1)
+       {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+       if (argc == 0)
+       {
+               command_print(cmd_ctx, ZYLIN_OPENOCD_VERSION);
+       } else if (strcmp("openocd", args[0])==0)
+       {
+               command_print(cmd_ctx, "%d", ZYLIN_OPENOCD);
+       } else if (strcmp("zy1000", args[0])==0)
+       {
+               command_print(cmd_ctx, "%s", ZYLIN_VERSION);
+       } else if (strcmp("date", args[0])==0)
+       {
+               command_print(cmd_ctx, "%s", ZYLIN_DATE);
+       } else
+       {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       return ERROR_OK;
+}
+
+extern flash_driver_t *flash_drivers[];
+extern target_type_t *target_types[];
+
+#ifdef CYGPKG_PROFILE_GPROF
+#include <cyg/profile/profile.h>
+
+extern char _stext, _etext; // Defined by the linker
+
+void start_profile(void)
+{
+       // This starts up the system-wide profiling, gathering
+       // profile information on all of the code, with a 16 byte
+       // "bucket" size, at a rate of 100us/profile hit.
+       // Note: a bucket size of 16 will give pretty good function
+       //       resolution.  Much smaller and the buffer becomes
+       //       much too large for very little gain.
+       // Note: a timer period of 100us is also a reasonable
+       //       compromise.  Any smaller and the overhead of
+       //       handling the timter (profile) interrupt could
+       //       swamp the system.  A fast processor might get
+       //       by with a smaller value, but a slow one could
+       //       even be swamped by this value.  If the value is
+       //       too large, the usefulness of the profile is reduced.
+
+       // no more interrupts than 1/10ms.
+       //    profile_on(&_stext, &_etext, 16, 10000); // DRAM
+       //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
+       profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
+}
+#endif
+
+// launch GDB server if a config file exists
+bool zylinjtag_parse_config_file(struct command_context_s *cmd_ctx, const char *config_file_name)
+{
+       bool foundFile = false;
+       FILE *config_file = NULL;
+       command_print(cmd_ctx, "executing config file %s", config_file_name);
+       config_file = fopen(config_file_name, "r");
+       if (config_file)
+       {
+               fclose(config_file);
+               int retval;
+               retval = command_run_linef(cmd_ctx, "script %s", config_file_name);
+               if (retval == ERROR_OK)
+               {
+                       foundFile = true;
+               }
+               else
+               {
+                       command_print(cmd_ctx, "Failed executing %s %d", config_file_name, retval);
+               }
+       }
+       else
+       {
+               command_print(cmd_ctx, "No %s found", config_file_name);
+       }
+
+       return foundFile;
+}
+
+extern int eth0_up;
+static FILE *log;
+
+static char reboot_stack[2048];
+
+
+static void
+zylinjtag_reboot(cyg_addrword_t data)
+{
+       serialLog = true;
+       diag_printf("Rebooting in 100 ticks..\n");
+       cyg_thread_delay(100);
+       diag_printf("Unmounting /config..\n");
+       umount("/config");
+       diag_printf("Rebooting..\n");
+       HAL_PLATFORM_RESET();
+}
+static cyg_thread zylinjtag_thread_object;
+static cyg_handle_t zylinjtag_thread_handle;
+
+void reboot(void)
+{
+    cyg_thread_create(1,
+                      zylinjtag_reboot,
+                      (cyg_addrword_t)0,
+                      "reboot Thread",
+                      (void *)reboot_stack,
+                      sizeof(reboot_stack),
+                      &zylinjtag_thread_handle,
+                      &zylinjtag_thread_object);
+       cyg_thread_resume(zylinjtag_thread_handle);
+}
+
+int configuration_output_handler(struct command_context_s *context, const char* line)
+{
+       diag_printf("%s", line);
+
+       return ERROR_OK;
+}
+
+int zy1000_configuration_output_handler_log(struct command_context_s *context, const char* line)
+{
+       LOG_USER_N("%s", line);
+
+       return ERROR_OK;
+}
+
+int handle_rm_command(struct command_context_s *cmd_ctx, char *cmd,
+               char **args, int argc)
+{
+       if (argc != 1)
+       {
+               command_print(cmd_ctx, "rm <filename>");
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       if (unlink(args[0]) != 0)
+       {
+               command_print(cmd_ctx, "failed: %d", errno);
+       }
+
+       return ERROR_OK;
+}
+
+int loadFile(const char *fileName, void **data, int *len);
+
+int handle_cat_command(struct command_context_s *cmd_ctx, char *cmd,
+               char **args, int argc)
+{
+       if (argc != 1)
+       {
+               command_print(cmd_ctx, "cat <filename>");
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       // NOTE!!! we only have line printing capability so we print the entire file as a single line.
+       void *data;
+       int len;
+
+       int retval = loadFile(args[0], &data, &len);
+       if (retval == ERROR_OK)
+       {
+               command_print(cmd_ctx, "%s", data);
+               free(data);
+       }
+       else
+       {
+               command_print(cmd_ctx, "%s not found %d", args[0], retval);
+       }
+
+       return ERROR_OK;
+}
+int handle_trunc_command(struct command_context_s *cmd_ctx, char *cmd,
+               char **args, int argc)
+{
+       if (argc != 1)
+       {
+               command_print(cmd_ctx, "trunc <filename>");
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       FILE *config_file = NULL;
+       config_file = fopen(args[0], "w");
+       if (config_file != NULL)
+               fclose(config_file);
+
+       return ERROR_OK;
+}
+
+
+int handle_meminfo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       static int prev = 0;
+       struct mallinfo info;
+
+       if (argc != 0)
+       {
+               command_print(cmd_ctx, "meminfo");
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       info = mallinfo();
+
+       if (prev > 0)
+       {
+               command_print(cmd_ctx, "Diff:            %d", prev - info.fordblks);
+       }
+       prev = info.fordblks;
+
+       command_print(cmd_ctx, "Available ram:   %d", info.fordblks );
+
+       return ERROR_OK;
+}
+
+static bool savePower;
+
+static void setPower(bool power)
+{
+       savePower = power;
+       if (power)
+       {
+               HAL_WRITE_UINT32(0x08000014, 0x8);
+       } else
+       {
+               HAL_WRITE_UINT32(0x08000010, 0x8);
+       }
+}
+
+int handle_power_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc > 1)
+       {
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       if (argc == 1)
+       {
+               if (strcmp(args[0], "on") == 0)
+               {
+                       setPower(1);
+               }
+               else if (strcmp(args[0], "off") == 0)
+               {
+                       setPower(0);
+               } else
+               {
+                       command_print(cmd_ctx, "arg is \"on\" or \"off\"");
+                       return ERROR_INVALID_ARGUMENTS;
+               }
+       }
+
+       command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off");
+
+       return ERROR_OK;
+}
+
+int handle_append_command(struct command_context_s *cmd_ctx, char *cmd,
+               char **args, int argc)
+{
+       if (argc < 1)
+       {
+               command_print(cmd_ctx,
+                               "append <filename> [<string1>, [<string2>, ...]]");
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       FILE *config_file = NULL;
+       config_file = fopen(args[0], "a");
+       if (config_file != NULL)
+       {
+               int i;
+               fseek(config_file, 0, SEEK_END);
+
+               for (i = 1; i < argc; i++)
+               {
+                       fwrite(args[i], strlen(args[i]), 1, config_file);
+                       if (i != argc - 1)
+                       {
+                               fwrite(" ", 1, 1, config_file);
+                       }
+               }
+               fwrite("\n", 1, 1, config_file);
+               fclose(config_file);
+       }
+
+       return ERROR_OK;
+}
+
+extern int telnet_socket;
+
+int readMore(int fd, void *data, int length)
+{
+       /* used in select() */
+       fd_set read_fds;
+
+       /* monitor sockets for acitvity */
+       int fd_max = 1;
+       FD_ZERO(&read_fds);
+       /* listen for new connections */
+       FD_SET(fd, &read_fds);
+
+       // Maximum 5 seconds.
+       struct timeval tv;
+       tv.tv_sec = 5;
+       tv.tv_usec = 0;
+
+       int retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
+       if (retval == 0)
+       {
+               diag_printf("Timed out waiting for binary payload\n");
+               return -1;
+       }
+       if (retval != 1)
+               return -1;
+
+       return read_socket(fd, data, length);
+}
+
+int readAll(int fd, void *data, int length)
+{
+       int pos = 0;
+       for (;;)
+       {
+               int actual = readMore(fd, ((char *) data) + pos, length - pos);
+               //              diag_printf("Read %d bytes(pos=%d, length=%d)\n", actual, pos, length);
+               if (actual <= 0)
+                       return -1;
+               pos += actual;
+               if (pos == length)
+                       break;
+       }
+       return length;
+}
+
+int handle_peek_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       cyg_uint32 value;
+       if (argc != 1)
+       {
+               return ERROR_INVALID_ARGUMENTS;
+       }
+       HAL_READ_UINT32(strtoul(args[0], NULL, 0), value);
+       command_print(cmd_ctx, "0x%x : 0x%x", strtoul(args[0], NULL, 0), value);
+       return ERROR_OK;
+}
+
+int handle_poke_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc != 2)
+       {
+               return ERROR_INVALID_ARGUMENTS;
+       }
+       HAL_WRITE_UINT32(strtoul(args[0], NULL, 0), strtoul(args[1], NULL, 0));
+       return ERROR_OK;
+}
+
+int handle_cp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc != 2)
+       {
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       // NOTE!!! we only have line printing capability so we print the entire file as a single line.
+       void *data;
+       int len;
+
+       int retval = loadFile(args[0], &data, &len);
+       if (retval != ERROR_OK)
+               return retval;
+
+       FILE *f = fopen(args[1], "wb");
+       if (f == NULL)
+               retval = ERROR_INVALID_ARGUMENTS;
+
+       int pos = 0;
+       for (;;)
+       {
+               int chunk = len - pos;
+               static const int maxChunk = 512 * 1024; // ~1/sec
+               if (chunk > maxChunk)
+               {
+                       chunk = maxChunk;
+               }
+
+               if ((retval==ERROR_OK)&&(fwrite(((char *)data)+pos, 1, chunk, f)!=chunk))
+                       retval = ERROR_INVALID_ARGUMENTS;
+
+               if (retval != ERROR_OK)
+               {
+                       break;
+               }
+
+               command_print(cmd_ctx, "%d", len - pos);
+
+               pos += chunk;
+
+               if (pos == len)
+                       break;
+       }
+
+       if (retval == ERROR_OK)
+       {
+               command_print(cmd_ctx, "Copied %s to %s", args[0], args[1]);
+       } else
+       {
+               command_print(cmd_ctx, "Failed: %d", retval);
+       }
+
+       if (data != NULL)
+               free(data);
+       if (f != NULL)
+               fclose(f);
+
+       if (retval != ERROR_OK)
+               unlink(args[1]);
+
+       return retval;
+}
+
+#ifdef CYGPKG_PROFILE_GPROF
+extern void start_profile();
+
+int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       command_print(cmd_ctx, "Profiling started");
+       start_profile();
+       return ERROR_OK;
+}
+
+#endif
+
+externC void phi_init_all_network_interfaces();
+
+command_context_t *cmd_ctx;
+
+static bool webRunning = false;
+
+void keep_webserver()
+{
+       // Target initialisation is only attempted at startup, so we sleep forever and
+       // let the http server bail us out(i.e. get config files set up).
+       diag_printf("OpenOCD has invoked exit().\n"
+               "Use web server to correct any configuration settings and reboot.\n");
+       if (!webRunning)
+               reboot();
+
+       // exit() will terminate the current thread and we we'll then sleep eternally or
+       // we'll have a reboot scheduled.
+}
+
+extern void printDccChar(char c);
+
+static char logBuffer[128 * 1024];
+static const int logSize = sizeof(logBuffer);
+int writePtr = 0;
+int logCount = 0;
+
+void _zylinjtag_diag_write_char(char c, void **param)
+{
+       if (writeLog)
+       {
+               logBuffer[writePtr] = c;
+               writePtr = (writePtr + 1) % logSize;
+               logCount++;
+       }
+       if (serialLog)
+       {
+               if (c == '\n')
+               {
+                       HAL_DIAG_WRITE_CHAR('\r');
+               }
+               HAL_DIAG_WRITE_CHAR(c);
+       }
+
+       printDccChar(c);
+}
+
+#define SHOW_RESULT(a, b) diag_printf(#a " failed %d\n", (int)b)
+
+#define IOSIZE 512
+static void copyfile(char *name2, char *name1)
+{
+
+       int err;
+       char buf[IOSIZE];
+       int fd1, fd2;
+       ssize_t done, wrote;
+
+       fd1 = open(name1, O_WRONLY | O_CREAT);
+       if (fd1 < 0)
+               SHOW_RESULT( open, fd1 );
+
+       fd2 = open(name2, O_RDONLY);
+       if (fd2 < 0)
+               SHOW_RESULT( open, fd2 );
+
+       for (;;)
+       {
+               done = read(fd2, buf, IOSIZE );
+               if (done < 0)
+               {
+                       SHOW_RESULT( read, done );
+                       break;
+               }
+
+        if( done == 0 ) break;
+
+               wrote = write(fd1, buf, done);
+        if( wrote != done ) SHOW_RESULT( write, wrote );
+
+        if( wrote != done ) break;
+       }
+
+       err = close(fd1);
+    if( err < 0 ) SHOW_RESULT( close, err );
+
+       err = close(fd2);
+    if( err < 0 ) SHOW_RESULT( close, err );
+
+}
+static void copydir(char *name)
+{
+       int err;
+       DIR *dirp;
+
+       mkdir("/ram/cgi", 0777);
+
+       dirp = opendir(name);
+    if( dirp == NULL ) SHOW_RESULT( opendir, -1 );
+
+       for (;;)
+       {
+               struct dirent *entry = readdir(dirp);
+
+               if (entry == NULL)
+                       break;
+
+               if (strcmp(entry->d_name, ".") == 0)
+                       continue;
+               if (strcmp(entry->d_name, "..") == 0)
+                       continue;
+
+               bool isDir = false;
+               struct stat buf;
+               char fullPath[PATH_MAX];
+               strncpy(fullPath, name, PATH_MAX);
+               strcat(fullPath, "/");
+               strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));
+
+               if (stat(fullPath, &buf) == -1)
+               {
+                       diag_printf("unable to read status from %s", fullPath);
+                       break;
+               }
+               isDir = S_ISDIR(buf.st_mode) != 0;
+
+               if (isDir)
+                       continue;
+
+               //        diag_printf("<INFO>: entry %14s",entry->d_name);
+               char fullname[PATH_MAX];
+               char fullname2[PATH_MAX];
+
+               strcpy(fullname, name);
+               strcat(fullname, entry->d_name);
+
+               strcpy(fullname2, "/ram/cgi/");
+               strcat(fullname2, entry->d_name);
+               //        diag_printf("from %s to %s\n", fullname, fullname2);
+               copyfile(fullname, fullname2);
+
+               //       diag_printf("\n");
+       }
+
+       err = closedir(dirp);
+    if( err < 0 ) SHOW_RESULT( stat, err );
+}
+
+#if 0
+MTAB_ENTRY( romfs_mte1,
+               "/rom",
+               "romfs",
+               "",
+               (CYG_ADDRWORD) &filedata[0] );
+#endif
+
+void openocd_sleep_prelude()
+{
+       cyg_mutex_unlock(&httpstate.jim_lock);
+}
+
+void openocd_sleep_postlude()
+{
+       cyg_mutex_lock(&httpstate.jim_lock);
+}
+
+static int
+zylinjtag_Jim_Command_rm(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       int del;
+       if (argc != 2)
+       {
+               Jim_WrongNumArgs(interp, 1, argv, "rm ?dirorfile?");
+               return JIM_ERR;
+       }
+
+       del = 0;
+       if (unlink(Jim_GetString(argv[1], NULL)) == 0)
+               del = 1;
+       if (rmdir(Jim_GetString(argv[1], NULL)) == 0)
+               del = 1;
+
+       return del ? JIM_OK : JIM_ERR;
+}
+
+static int
+zylinjtag_Jim_Command_ls(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       if (argc != 2)
+       {
+               Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
+               return JIM_ERR;
+       }
+
+       char *name = (char*) Jim_GetString(argv[1], NULL);
+
+       DIR *dirp = NULL;
+       dirp = opendir(name);
+       if (dirp == NULL)
+       {
+               return JIM_ERR;
+       }
+       Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
+
+       for (;;)
+       {
+               struct dirent *entry = NULL;
+               entry = readdir(dirp);
+               if (entry == NULL)
+                       break;
+
+               if ((strcmp(".", entry->d_name)==0)||(strcmp("..", entry->d_name)==0))
+                       continue;
+
+        Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name)));
+       }
+       closedir(dirp);
+
+       Jim_SetResult(interp, objPtr);
+
+       return JIM_OK;
+}
+
+
+static int
+zylinjtag_Jim_Command_getmem(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       if (argc != 3)
+       {
+               Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
+               return JIM_ERR;
+       }
+
+       long address;
+       long length;
+       if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
+               return JIM_ERR;
+       if (Jim_GetLong(interp, argv[2], &length) != JIM_OK)
+               return JIM_ERR;
+
+       if (length < 0 && length > (4096 * 1024))
+       {
+               Jim_WrongNumArgs(interp, 1, argv, "getmem ?dir?");
+               return JIM_ERR;
+       }
+
+       void *mem = malloc(length);
+       if (mem == NULL)
+               return JIM_ERR;
+
+       target_t *target = get_current_target(cmd_ctx);
+
+       int retval;
+       int size = 1;
+       int count = length;
+       if ((address % 4 == 0) && (count % 4 == 0))
+       {
+               size = 4;
+               count /= 4;
+       }
+
+       if ((retval  = target->type->read_memory(target, address, size, count, mem)) != ERROR_OK)
+       {
+               free(mem);
+               return JIM_ERR;
+       }
+
+       Jim_Obj *objPtr = Jim_NewStringObj(interp, mem, length);
+       Jim_SetResult(interp, objPtr);
+
+       free(mem);
+
+       return JIM_OK;
+}
+
+static int
+zylinjtag_Jim_Command_peek(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       if (argc != 2)
+       {
+               Jim_WrongNumArgs(interp, 1, argv, "peek ?address?");
+               return JIM_ERR;
+       }
+
+       long address;
+       if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
+               return JIM_ERR;
+
+       int value = *((volatile int *) address);
+
+       Jim_SetResult(interp, Jim_NewIntObj(interp, value));
+
+       return JIM_OK;
+}
+
+static int
+zylinjtag_Jim_Command_poke(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       if (argc != 3)
+       {
+               Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?");
+               return JIM_ERR;
+       }
+
+       long address;
+       if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
+               return JIM_ERR;
+       long value;
+       if (Jim_GetLong(interp, argv[2], &value) != JIM_OK)
+               return JIM_ERR;
+
+       *((volatile int *) address) = value;
+
+       return JIM_OK;
+}
+
+
+
+static int
+zylinjtag_Jim_Command_flash(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       int retval;
+       u32 base = 0;
+       flash_bank_t *t = get_flash_bank_by_num_noprobe(0);
+       if (t != NULL)
+       {
+               base = t->base;
+               retval = JIM_OK;
+    } else
+       {
+               retval = JIM_ERR;
+       }
+
+       if (retval == JIM_OK)
+       {
+               Jim_SetResult(interp, Jim_NewIntObj(interp, base));
+       }
+
+       return retval;
+}
+
+
+
+
+
+static int
+zylinjtag_Jim_Command_log(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
+
+       if (logCount >= logSize)
+       {
+       Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer+logCount%logSize, logSize-logCount%logSize);
+       }
+       Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer, writePtr);
+
+       Jim_SetResult(interp, tclOutput);
+       return JIM_OK;
+}
+
+static int
+zylinjtag_Jim_Command_reboot(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       reboot();
+       return JIM_OK;
+}
+
+static int
+zylinjtag_Jim_Command_mac(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       int s;
+       struct ifreq ifr;
+       s = socket(AF_INET, SOCK_DGRAM, 0);
+       if (s >= 0)
+       {
+               strcpy(ifr.ifr_name, "eth0");
+               int res;
+               res = ioctl(s, SIOCGIFHWADDR, &ifr);
+               close(s);
+
+               if (res < 0)
+               {
+                       return JIM_OK;
+               }
+       }
+
+       Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
+
+       char hwaddr[512];
+       sprintf(hwaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
+                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[0],
+                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[1],
+                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[2],
+                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[3],
+                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[4],
+                       (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[5]);
+
+       Jim_AppendString(httpstate.jim_interp, tclOutput, hwaddr, strlen(hwaddr));
+
+       Jim_SetResult(interp, tclOutput);
+
+       return JIM_OK;
+}
+
+static int
+zylinjtag_Jim_Command_ip(Jim_Interp *interp,
+                                   int argc,
+               Jim_Obj * const *argv)
+{
+       Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
+
+       struct ifaddrs *ifa = NULL, *ifp = NULL;
+
+       if (getifaddrs(&ifp) < 0)
+       {
+               return JIM_ERR;
+       }
+
+       for (ifa = ifp; ifa; ifa = ifa->ifa_next)
+       {
+               char ip[200];
+               socklen_t salen;
+
+               if (ifa->ifa_addr->sa_family == AF_INET)
+                       salen = sizeof(struct sockaddr_in);
+               else if (ifa->ifa_addr->sa_family == AF_INET6)
+                       salen = sizeof(struct sockaddr_in6);
+               else
+                       continue;
+
+               if (getnameinfo(ifa->ifa_addr, salen, ip, sizeof(ip), NULL, 0,
+                               NI_NUMERICHOST) < 0)
+               {
+                       continue;
+               }
+
+               Jim_AppendString(httpstate.jim_interp, tclOutput, ip, strlen(ip));
+               break;
+
+       }
+
+       freeifaddrs(ifp);
+
+       Jim_SetResult(interp, tclOutput);
+
+       return JIM_OK;
+}
+
+extern Jim_Interp *interp;
+
+static void zylinjtag_startNetwork()
+{
+       // Bring TCP/IP up immediately before we're ready to accept commands.
+       //
+       // That is as soon as a PING responds, we're accepting telnet sessions.
+#if defined(CYGPKG_NET_FREEBSD_STACK)
+       phi_init_all_network_interfaces();
+#else
+       lwip_init();
+#endif
+       if (!eth0_up)
+       {
+               diag_printf("Network not up and running\n");
+               exit(-1);
+       }
+#if defined(CYGPKG_NET_FREEBSD_STACK)
+       /*start TFTP*/
+       tftpd_start(69, &fileops);
+#endif
+
+       cyg_httpd_init_tcl_interpreter();
+
+       interp = httpstate.jim_interp;
+
+    Jim_CreateCommand(httpstate.jim_interp, "log", zylinjtag_Jim_Command_log, NULL, NULL);
+    Jim_CreateCommand(httpstate.jim_interp, "reboot", zylinjtag_Jim_Command_reboot, NULL, NULL);
+    Jim_CreateCommand(httpstate.jim_interp, "peek", zylinjtag_Jim_Command_peek, NULL, NULL);
+    Jim_CreateCommand(httpstate.jim_interp, "zy1000_flash", zylinjtag_Jim_Command_flash, NULL, NULL);
+    Jim_CreateCommand(httpstate.jim_interp, "poke", zylinjtag_Jim_Command_poke, NULL, NULL);
+    Jim_CreateCommand(httpstate.jim_interp, "ls", zylinjtag_Jim_Command_ls, NULL, NULL);
+    Jim_CreateCommand(httpstate.jim_interp, "getmem", zylinjtag_Jim_Command_getmem, NULL, NULL);
+    Jim_CreateCommand(httpstate.jim_interp, "mac", zylinjtag_Jim_Command_mac, NULL, NULL);
+    Jim_CreateCommand(httpstate.jim_interp, "ip", zylinjtag_Jim_Command_ip, NULL, NULL);
+    Jim_CreateCommand(httpstate.jim_interp, "rm", zylinjtag_Jim_Command_rm, NULL, NULL);
+
+       cyg_httpd_start();
+
+       webRunning = true;
+
+       diag_printf("Web server running\n");
+}
+
+static bool readPowerDropout()
+{
+       cyg_uint32 state;
+       // sample and clear power dropout
+       HAL_WRITE_UINT32(0x08000010, 0x80);
+       HAL_READ_UINT32(0x08000010, state);
+       bool powerDropout;
+       powerDropout = (state & 0x80) != 0;
+       return powerDropout;
+}
+
+bool readSRST()
+{
+       cyg_uint32 state;
+       // sample and clear SRST sensing
+       HAL_WRITE_UINT32(0x08000010, 0x00000040);
+       HAL_READ_UINT32(0x08000010, state);
+       bool srstAsserted;
+       srstAsserted = (state & 0x40) != 0;
+       return srstAsserted;
+}
+
+// every 300ms we check for reset & powerdropout and issue a "reset halt" if
+// so.
+
+
+static int sense_handler(void *priv)
+{
+       struct command_context_s *cmd_ctx;
+       cmd_ctx = (struct command_context_s *) priv;
+
+       static bool prevSrstAsserted = false;
+       static bool prevPowerdropout = false;
+
+       bool powerDropout;
+       powerDropout = readPowerDropout();
+
+       bool powerRestored;
+       powerRestored = prevPowerdropout && !powerDropout;
+       if (powerRestored)
+       {
+               LOG_USER("Sensed power restore.");
+       }
+
+       cyg_tick_count_t current = cyg_current_time();
+       static cyg_tick_count_t lastPower = 0;
+       bool waitMore = lastPower + 200 > current;
+       if (powerDropout && !waitMore)
+       {
+               LOG_USER("Sensed power dropout.");
+               lastPower = current;
+       }
+
+       bool srstAsserted = readSRST();
+
+       bool srstDeasserted;
+       srstDeasserted = prevSrstAsserted && !srstAsserted;
+
+       static cyg_tick_count_t lastSrst = 0;
+       waitMore = lastSrst + 200 > current;
+       if (srstDeasserted && !waitMore)
+       {
+               LOG_USER("Sensed nSRST deasserted");
+               lastSrst = current;
+       }
+
+       if (!prevSrstAsserted && srstAsserted)
+       {
+               LOG_USER("Sensed nSRST asserted");
+       }
+
+       prevSrstAsserted = srstAsserted;
+       prevPowerdropout = powerDropout;
+
+       if (srstDeasserted || powerRestored)
+       {
+               /* Other than logging the event we can't do anything here.
+                * Issuing a reset is a particularly bad idea as we might
+                * be inside a reset already.
+                */
+       }
+
+       return ERROR_OK;
+}
+
+
+
+static void
+print_exception_handler(cyg_addrword_t data, cyg_code_t exception, cyg_addrword_t info)
+{
+       writeLog = false;
+       serialLog = true;
+       char *infoStr = "unknown";
+       switch (exception)
+       {
+       case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION:
+               infoStr = "undefined instruction";
+               break;
+       case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT:
+               infoStr = "software interrupt";
+               break;
+       case CYGNUM_HAL_VECTOR_ABORT_PREFETCH:
+               infoStr = "abort prefetch";
+               break;
+       case CYGNUM_HAL_VECTOR_ABORT_DATA:
+               infoStr = "abort data";
+               break;
+       default:
+               break;
+       }
+
+       diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
+
+       diag_printf("Dumping log\n---\n");
+       if (logCount >= logSize)
+       {
+               diag_write(logBuffer + logCount % logSize, logSize - logCount % logSize);
+       }
+       diag_write(logBuffer, writePtr);
+
+       diag_printf("---\nLogdump complete.\n");
+       diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
+       diag_printf("\n---\nRebooting\n");
+       HAL_PLATFORM_RESET();
+
+}
+
+static void setHandler(cyg_code_t exception)
+{
+       cyg_exception_handler_t *old_handler;
+       cyg_addrword_t old_data;
+
+       cyg_exception_set_handler(exception,
+       print_exception_handler,
+       0,
+       &old_handler,
+       &old_data);
+}
+
+static cyg_thread zylinjtag_uart_thread_object;
+static cyg_handle_t zylinjtag_uart_thread_handle;
+static char uart_stack[4096];
+
+static char forwardBuffer[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
+static char backwardBuffer[1024];
+
+static cyg_io_handle_t serial_handle;
+
+void setNoDelay(int session, int flag)
+{
+#if 1
+       // This decreases latency dramatically for e.g. GDB load which
+       // does not have a sliding window protocol
+       //
+       // Can cause *lots* of TCP/IP packets to be sent and it would have
+       // to be enabled/disabled on the fly to avoid the CPU being
+       // overloaded...
+       setsockopt(session, /* socket affected */
+       IPPROTO_TCP, /* set option at TCP level */
+       TCP_NODELAY, /* name of option */
+       (char *) &flag, /* the cast is historical
+        cruft */
+       sizeof(int)); /* length of option value */
+#endif
+}
+
+struct
+{
+       int req;
+       int actual;
+       int req2;
+       int actual2;
+} tcpipSent[512 * 1024];
+int cur;
+
+static void
+zylinjtag_uart(cyg_addrword_t data)
+{
+       int so_reuseaddr_option = 1;
+
+       int fd;
+       if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+       {
+               LOG_ERROR("error creating socket: %s", strerror(errno));
+               exit(-1);
+       }
+
+       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
+
+       struct sockaddr_in sin;
+       unsigned int address_size;
+       address_size = sizeof(sin);
+       memset(&sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+       sin.sin_addr.s_addr = INADDR_ANY;
+       sin.sin_port = htons(5555);
+
+       if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
+       {
+               LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
+               exit(-1);
+       }
+
+       if (listen(fd, 1) == -1)
+       {
+               LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
+               exit(-1);
+       }
+       //      socket_nonblock(fd);
+
+
+       for (;;)
+       {
+               int session = accept(fd, (struct sockaddr *) &sin, &address_size);
+               if (session < 0)
+               {
+                       continue;
+               }
+
+               setNoDelay(session, 1);
+               int oldopts = fcntl(session, F_GETFL, 0);
+               fcntl(session, F_SETFL, oldopts | O_NONBLOCK); //
+
+               int serHandle = open("/dev/ser0", O_RDWR | O_NONBLOCK);
+               if (serHandle < 0)
+               {
+                       close(session);
+                       continue;
+               }
+
+               start_profile();
+               int actual = 0;
+               int actual2 = 0;
+               int pos, pos2;
+               pos = 0;
+               pos2 = 0;
+               cur = 0;
+               for (;;)
+               {
+                       fd_set write_fds;
+                       fd_set read_fds;
+                       FD_ZERO(&write_fds);
+                       FD_ZERO(&read_fds);
+                       int fd_max = -1;
+                       FD_SET(session, &read_fds);
+                       fd_max = session;
+                       FD_SET(serHandle, &read_fds);
+                       if (serHandle > fd_max)
+                       {
+                               fd_max = serHandle;
+                       }
+                       /* Wait... */
+
+                       cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
+                       if ((actual == 0) && (actual2 == 0))
+                       {
+                               int retval = select(fd_max + 1, &read_fds, NULL, NULL, NULL);
+                               if (retval <= 0)
+                               {
+                                       break;
+                               }
+                       }
+
+                       if (actual2 <= 0)
+                       {
+                               memset(backwardBuffer, 's', sizeof(backwardBuffer));
+                               actual2=read(serHandle, backwardBuffer, sizeof(backwardBuffer));
+                               if (actual2 < 0)
+                               {
+                                       if (errno != EAGAIN)
+                                       {
+                                               goto closeSession;
+                                       }
+                                       actual2 = 0;
+                               }
+                               pos2 = 0;
+                       }
+
+                       int x = actual2;
+                       int y = 0;
+                       if (actual2 > 0)
+                       {
+                               int written = write(session, backwardBuffer + pos2, actual2);
+                               if (written <= 0)
+                                       goto closeSession;
+                               actual2 -= written;
+                               pos2 += written;
+                               y = written;
+                       }
+
+                       if (FD_ISSET(session, &read_fds)&&(sizeof(forwardBuffer)>actual))
+                       {
+                               // NB! Here it is important that we empty the TCP/IP read buffer
+                               // to make transmission tick right
+                               memmove(forwardBuffer, forwardBuffer + pos, actual);
+                               pos = 0;
+                               int t;
+                               // this will block if there is no data at all
+                               t=read_socket(session, forwardBuffer+actual, sizeof(forwardBuffer)-actual);
+                               if (t <= 0)
+                               {
+                                       goto closeSession;
+                               }
+                               actual += t;
+                       }
+
+                       int x2 = actual;
+                       int y2 = 0;
+                       if (actual > 0)
+                       {
+                               /* Do not put things into the serial buffer if it has something to send
+                                * as that can cause a single byte to be sent at the time.
+                                *
+                                *
+                                */
+                               int written = write(serHandle, forwardBuffer + pos, actual);
+                               if (written < 0)
+                               {
+                                       if (errno != EAGAIN)
+                                       {
+                                               goto closeSession;
+                                       }
+                                       // The serial buffer is full
+                                       written = 0;
+                               } else
+                               {
+                                       actual -= written;
+                                       pos += written;
+                               }
+                               y2 = written;
+                       }
+                       if (cur < 1024)
+                       {
+                               tcpipSent[cur].req = x;
+                               tcpipSent[cur].actual = y;
+                               tcpipSent[cur].req2 = x2;
+                               tcpipSent[cur].actual2 = y2;
+                               cur++;
+                       }
+
+               }
+           closeSession:
+           close(session);
+               close(serHandle);
+
+               int i;
+               for (i = 0; i < 1024; i++)
+               {
+               diag_printf("%d %d %d %d\n", tcpipSent[i].req, tcpipSent[i].actual, tcpipSent[i].req2, tcpipSent[i].actual2);
+
+               }
+       }
+       close(fd);
+
+}
+
+void startUart(void)
+{
+    cyg_thread_create(1,
+                      zylinjtag_uart,
+                      (cyg_addrword_t)0,
+                      "uart thread",
+                      (void *)uart_stack,
+                      sizeof(uart_stack),
+                      &zylinjtag_uart_thread_handle,
+                      &zylinjtag_uart_thread_object);
+       cyg_thread_set_priority(zylinjtag_uart_thread_handle, 1); // low priority as it sits in a busy loop
+       cyg_thread_resume(zylinjtag_uart_thread_handle);
+}
+
+
+
+int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc != 1)
+       {
+               command_print(cmd_ctx, "usage: uart <baudrate>");
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       int baud = atol(args[0]);
+
+       switch (baud)
+       {
+       case 9600:
+               baud = CYGNUM_SERIAL_BAUD_9600;
+               break;
+       case 19200:
+               baud = CYGNUM_SERIAL_BAUD_19200;
+               break;
+       case 38400:
+               baud = CYGNUM_SERIAL_BAUD_38400;
+               break;
+       case 57600:
+               baud = CYGNUM_SERIAL_BAUD_57600;
+               break;
+       case 115200:
+               baud = CYGNUM_SERIAL_BAUD_115200;
+               break;
+       case 230400:
+               baud = CYGNUM_SERIAL_BAUD_230400;
+               break;
+       default:
+               command_print(cmd_ctx, "unsupported baudrate");
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       cyg_serial_info_t buf;
+       cyg_uint32 len = 1;
+       //get existing serial configuration
+       len = sizeof(cyg_serial_info_t);
+       int err;
+       err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buf, &len);
+       err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &buf, &len);
+       if (err != ENOERR)
+       {
+               command_print(cmd_ctx, "Failed to get serial port settings %d", err);
+               return ERROR_OK;
+       }
+       buf.baud = baud;
+
+       err = cyg_io_set_config(serial_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &buf, &len);
+       if (err != ENOERR)
+       {
+               command_print(cmd_ctx, "Failed to set serial port settings %d", err);
+               return ERROR_OK;
+       }
+
+       return ERROR_OK;
+}
+
+bool logAllToSerial = false;
+
+/* boolean parameter stored on config */
+bool boolParam(char *var)
+{
+       bool result = false;
+       char *name = alloc_printf(ZYLIN_CONFIG_DIR "/%s", var);
+       if (name == NULL)
+               return result;
+
+       void *data;
+       int len;
+       if (loadFile(name, &data, &len) == ERROR_OK)
+       {
+               if (len > 1)
+                       len = 1;
+               result = strncmp((char *) data, "1", len) == 0;
+               free(data);
+       }
+       free(name);
+       return result;
+}
+
+command_context_t *setup_command_handler();
+
+int add_default_dirs(void)
+{
+       add_script_search_dir(ZYLIN_CONFIG_DIR);
+       add_script_search_dir("/rom/lib/openocd");
+       add_script_search_dir("/rom");
+       return ERROR_OK;
+}
+
+int main(int argc, char *argv[])
+{
+       setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION);
+       setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH);
+       setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA);
+
+       int err;
+       err = cyg_io_lookup("/dev/ser0", &serial_handle);
+       if (err != ENOERR)
+       {
+               diag_printf("/dev/ser0 not found\n");
+               reboot();
+       }
+
+       setPower(true); // on by default
+
+       atexit(keep_webserver);
+
+       err = mount("", "/ram", "ramfs");
+       if (err < 0)
+       {
+               diag_printf("unable to mount ramfs\n");
+       }
+       chdir("/ram");
+
+       char address[16];
+       sprintf(address, "%p", &filedata[0]);
+       err = mount(address, "/rom", "romfs");
+       if (err < 0)
+       {
+               diag_printf("unable to mount /rom\n");
+       }
+
+       err = mount("", "/log", "logfs");
+       if (err < 0)
+       {
+               diag_printf("unable to mount logfs\n");
+       }
+
+       err = mount("", "/tftp", "tftpfs");
+       if (err < 0)
+       {
+               diag_printf("unable to mount logfs\n");
+       }
+
+       log = fopen("/log/log", "w");
+       if (log == NULL)
+       {
+               diag_printf("Could not open log file /ram/log\n");
+               exit(-1);
+       }
+
+       diag_init_putc(_zylinjtag_diag_write_char);
+
+       // We want this in the log.
+       diag_printf("Zylin ZY1000. Copyright Zylin AS 2007-2008.\n");
+       diag_printf("%s\n", ZYLIN_OPENOCD_VERSION);
+
+       copydir("/rom/");
+
+       err = mount("/dev/flash1", "/config", "jffs2");
+       if (err < 0)
+       {
+               diag_printf("unable to mount jffs\n");
+       }
+
+
+       mkdir(ZYLIN_CONFIG_DIR, 0777);
+       mkdir(ZYLIN_CONFIG_DIR "/target", 0777);
+       mkdir(ZYLIN_CONFIG_DIR "/event", 0777);
+
+       logAllToSerial = boolParam("logserial");
+
+       // We need the network & web server in case there is something wrong with
+       // the config files that invoke exit()
+       zylinjtag_startNetwork();
+
+       /* we're going to access the jim interpreter from here on... */
+       openocd_sleep_postlude();
+       startUart();
+
+       add_default_dirs();
+
+       /* initialize commandline interface */
+       command_context_t *cmd_ctx;
+       cmd_ctx = setup_command_handler();
+       command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
+       command_context_mode(cmd_ctx, COMMAND_CONFIG);
+
+
+       register_command(cmd_ctx, NULL, "zy1000_version", handle_zy1000_version_command,
+                       COMMAND_EXEC, "show zy1000 version numbers");
+
+       register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
+                       "rm <filname>");
+
+       register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
+                       "same args as load_image, image stored in memory");
+
+       register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
+                       "loads active fast load image to current target");
+
+       register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
+                       "cat <filname>");
+
+       register_command(cmd_ctx, NULL, "trunc", handle_trunc_command, COMMAND_ANY,
+                       "trunc <filname>");
+
+       register_command(cmd_ctx, NULL, "append_file", handle_append_command,
+                       COMMAND_ANY, "append <filname>");
+
+       register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY,
+                       "power <on/off> - turn power switch to target on/off. No arguments - print status.");
+
+       register_command(cmd_ctx, NULL, "meminfo", handle_meminfo_command,
+                       COMMAND_ANY, "meminfo");
+
+       register_command(cmd_ctx, NULL, "cp", handle_cp_command,
+                                        COMMAND_ANY, "cp <from> <to>");
+
+#ifdef CYGPKG_PROFILE_GPROF
+       register_command(cmd_ctx, NULL, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command,
+                       COMMAND_ANY, NULL);
+#endif
+       register_command(cmd_ctx, NULL, "uart", handle_uart_command,
+                                        COMMAND_ANY, "uart <baud>  - forward uart on port 5555");
+
+
+       int errVal;
+       errVal = log_init(cmd_ctx);
+       if (errVal != ERROR_OK)
+       {
+               diag_printf("log_init() failed %d\n", errVal);
+               exit(-1);
+       }
+
+       set_log_output(cmd_ctx, log);
+
+       LOG_DEBUG("log init complete");
+
+       //      diag_printf("Executing config files\n");
+
+       if (logAllToSerial)
+       {
+               diag_printf(ZYLIN_CONFIG_DIR "/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n");
+               command_run_line(cmd_ctx, "debug_level 3");
+       }
+
+       zylinjtag_parse_config_file(cmd_ctx, "/rom/openocd.cfg");
+
+       target_register_timer_callback(sense_handler, 200, 1, cmd_ctx);
+
+       // FIX!!!  Yuk!
+       // diag_printf() is really invoked from many more places than we trust it
+       // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
+       //
+       // Disabling it here is safe and gives us enough logged debug output for now. Crossing
+       // fingers that it doesn't cause any crashes.
+       diag_printf("Init complete, GDB & telnet servers launched.\n");
+       command_set_output_handler(cmd_ctx, zy1000_configuration_output_handler_log, NULL);
+       if (!logAllToSerial)
+       {
+               serialLog = false;
+       }
+
+       /* handle network connections */
+       server_loop(cmd_ctx);
+       openocd_sleep_prelude();
+
+       /* shut server down */
+       server_quit();
+
+       /* free commandline interface */
+       command_done(cmd_ctx);
+       umount("/config");
+
+       exit(0);
+       for (;;);
+}
+
+
+
+cyg_int32
+cyg_httpd_exec_cgi_tcl(char *file_name);
+cyg_int32 homeForm(CYG_HTTPD_STATE *p)
+{
+       cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
+       return 0;
+}
+
+CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label, "/", homeForm);
+
+CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label, "text", "text/plain");
+CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label, "bin", "application/octet-stream");
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/io_fileio.h>
+#include <pkgconf/fs_rom.h>
+
+#include <cyg/kernel/ktypes.h>         // base kernel types
+#include <cyg/infra/cyg_trac.h>        // tracing macros
+#include <cyg/infra/cyg_ass.h>         // assertion macros
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <dirent.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cyg/fileio/fileio.h>
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/infra/diag.h>
+
+//==========================================================================
+// Eventually we want to eXecute In Place from the ROM in a protected
+// environment, so we'll need executables to be aligned to a boundary
+// suitable for MMU protection. A suitable boundary would be the 4k
+// boundary in all the CPU architectures I am currently aware of.
+
+// Forward definitions
+
+// Filesystem operations
+static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
+static int tftpfs_umount(cyg_mtab_entry *mte);
+static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+               int mode, cyg_file *fte);
+static int tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
+static int tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
+
+// File operations
+static int tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
+static int tftpfs_fo_close(struct CYG_FILE_TAG *fp);
+static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence);
+
+//==========================================================================
+// Filesystem table entries
+
+// -------------------------------------------------------------------------
+// Fstab entry.
+// This defines the entry in the filesystem table.
+// For simplicity we use _FILESYSTEM synchronization for all accesses since
+// we should never block in any filesystem operations.
+#if 1
+FSTAB_ENTRY( tftpfs_fste, "tftpfs", 0,
+               CYG_SYNCMODE_NONE,
+               tftpfs_mount,
+               tftpfs_umount,
+               tftpfs_open,
+               (cyg_fsop_unlink *)cyg_fileio_erofs,
+               (cyg_fsop_mkdir *)cyg_fileio_erofs,
+               (cyg_fsop_rmdir *)cyg_fileio_erofs,
+               (cyg_fsop_rename *)cyg_fileio_erofs,
+               (cyg_fsop_link *)cyg_fileio_erofs,
+               (cyg_fsop_opendir *)cyg_fileio_erofs,
+               (cyg_fsop_chdir *)cyg_fileio_erofs,
+               (cyg_fsop_stat *)cyg_fileio_erofs,
+               (cyg_fsop_getinfo *)cyg_fileio_erofs,
+               (cyg_fsop_setinfo *)cyg_fileio_erofs);
+#endif
+
+// -------------------------------------------------------------------------
+// mtab entry.
+// This defines a single ROMFS loaded into ROM at the configured address
+//
+// MTAB_ENTRY( rom_mte,        // structure name
+//             "/rom",         // mount point
+//             "romfs",        // FIlesystem type
+//             "",             // hardware device
+//  (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS  // Address in ROM
+//           );
+
+
+// -------------------------------------------------------------------------
+// File operations.
+// This set of file operations are used for normal open files.
+
+static cyg_fileops tftpfs_fileops =
+{
+       tftpfs_fo_read,
+       tftpfs_fo_write,
+       tftpfs_fo_lseek,
+       (cyg_fileop_ioctl *)cyg_fileio_erofs,
+    cyg_fileio_seltrue,
+    tftpfs_fo_fsync,
+    tftpfs_fo_close,
+               (cyg_fileop_fstat *) cyg_fileio_erofs,
+               (cyg_fileop_getinfo *) cyg_fileio_erofs,
+       (cyg_fileop_setinfo *)cyg_fileio_erofs,
+};
+
+// -------------------------------------------------------------------------
+// tftpfs_mount()
+// Process a mount request. This mainly finds root for the
+// filesystem.
+
+static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
+{
+       return ENOERR;
+}
+
+static int tftpfs_umount(cyg_mtab_entry *mte)
+{
+       return ENOERR;
+}
+
+struct Tftp
+{
+       int write;
+       int readFile;
+       cyg_uint8 *mem;
+       int actual;
+       char *server;
+       char *file;
+};
+
+static void freeTftp(struct Tftp *t)
+{
+       if (t == NULL)
+               return;
+       if (t->mem)
+               free(t->mem);
+       if (t->server)
+               free(t->server);
+       if (t->file)
+               free(t->file);
+       free(t);
+}
+
+static const int tftpMaxSize = 8192 * 1024;
+static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+               int mode, cyg_file *file)
+{
+       struct Tftp *tftp;
+       tftp = malloc(sizeof(struct Tftp));
+       if (tftp == NULL)
+               return EMFILE;
+       memset(tftp, 0, sizeof(struct Tftp));
+
+       file->f_flag |= mode & CYG_FILE_MODE_MASK;
+       file->f_type = CYG_FILE_TYPE_FILE;
+       file->f_ops = &tftpfs_fileops;
+       file->f_offset = 0;
+       file->f_data = 0;
+       file->f_xops = 0;
+
+       tftp->mem = malloc(tftpMaxSize);
+       if (tftp->mem == NULL)
+       {
+               freeTftp(tftp);
+               return EMFILE;
+       }
+
+       char *server = strchr(name, '/');
+       if (server == NULL)
+       {
+               freeTftp(tftp);
+               return EMFILE;
+       }
+
+       tftp->server = malloc(server - name + 1);
+       if (tftp->server == NULL)
+       {
+               freeTftp(tftp);
+               return EMFILE;
+       }
+       strncpy(tftp->server, name, server - name);
+       tftp->server[server - name] = 0;
+
+       tftp->file = strdup(server + 1);
+       if (tftp->file == NULL)
+       {
+               freeTftp(tftp);
+               return EMFILE;
+       }
+
+       file->f_data = (CYG_ADDRWORD) tftp;
+
+       return ENOERR;
+}
+
+static int fetchTftp(struct Tftp *tftp)
+{
+       if (!tftp->readFile)
+       {
+               int err;
+           tftp->actual = tftp_client_get( tftp->file, tftp->server, 0, tftp->mem, tftpMaxSize,   TFTP_OCTET, &err);
+
+               if (tftp->actual < 0)
+               {
+                       return EMFILE;
+               }
+               tftp->readFile = 1;
+       }
+       return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+// tftpfs_fo_write()
+// Read data from file.
+
+static int
+tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
+{
+       struct Tftp *tftp = (struct Tftp *) fp->f_data;
+
+       if (fetchTftp(tftp) != ENOERR)
+               return EMFILE;
+
+       int i;
+       off_t pos = fp->f_offset;
+       int resid = 0;
+       for (i = 0; i < uio->uio_iovcnt; i++)
+       {
+               cyg_iovec *iov = &uio->uio_iov[i];
+               char *buf = (char *) iov->iov_base;
+               off_t len = iov->iov_len;
+
+               if (len + pos > tftp->actual)
+               {
+                       len = tftp->actual - pos;
+               }
+               resid += iov->iov_len - len;
+
+               memcpy(buf, tftp->mem + pos, len);
+               pos += len;
+
+       }
+       uio->uio_resid = resid;
+       fp->f_offset = pos;
+
+       return ENOERR;
+}
+
+
+static int
+tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
+{
+       struct Tftp *tftp = (struct Tftp *) fp->f_data;
+
+       int i;
+       off_t pos = fp->f_offset;
+       int resid = 0;
+       for (i = 0; i < uio->uio_iovcnt; i++)
+       {
+               cyg_iovec *iov = &uio->uio_iov[i];
+               char *buf = (char *) iov->iov_base;
+               off_t len = iov->iov_len;
+
+               if (len + pos > tftpMaxSize)
+               {
+                       len = tftpMaxSize - pos;
+               }
+               resid += iov->iov_len - len;
+
+               memcpy(tftp->mem + pos, buf, len);
+               pos += len;
+
+       }
+       uio->uio_resid = resid;
+       fp->f_offset = pos;
+
+       tftp->write = 1;
+
+       return ENOERR;
+}
+
+static int
+tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
+{
+       int error = ENOERR;
+       return error;
+}
+
+// -------------------------------------------------------------------------
+// romfs_fo_close()
+// Close a file. We just clear out the data pointer.
+
+static int tftpfs_fo_close(struct CYG_FILE_TAG *fp)
+{
+       struct Tftp *tftp = (struct Tftp *) fp->f_data;
+       int error = ENOERR;
+
+       if (tftp->write)
+       {
+           tftp_client_put( tftp->file, tftp->server, 0, tftp->mem, fp->f_offset,   TFTP_OCTET, &error);
+       }
+
+       freeTftp(tftp);
+       fp->f_data = 0;
+       return error;
+}
+
+// -------------------------------------------------------------------------
+// romfs_fo_lseek()
+// Seek to a new file position.
+
+static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence)
+{
+       struct Tftp *tftp = (struct Tftp *) fp->f_data;
+       off_t pos = *apos;
+
+       if (fetchTftp(tftp) != ENOERR)
+               return EMFILE;
+
+       switch (whence)
+       {
+       case SEEK_SET:
+               // Pos is already where we want to be.
+               break;
+
+       case SEEK_CUR:
+               // Add pos to current offset.
+               pos += fp->f_offset;
+               break;
+
+       case SEEK_END:
+               // Add pos to file size.
+               pos += tftp->actual;
+               break;
+
+       default:
+               return EINVAL;
+       }
+
+       // Check that pos is still within current file size, or at the
+       // very end.
+       if (pos < 0 || pos > tftp->actual)
+               return EINVAL;
+
+       // All OK, set fp offset and return new position.
+       *apos = fp->f_offset = pos;
+
+       return ENOERR;
+}
+
+void usleep(int us)
+{
+       if (us > 10000)
+               cyg_thread_delay(us / 10000 + 1);
+       else
+               HAL_DELAY_US(us);
+}
+
+// Chunked version.
+cyg_int32
+show_log_entry(CYG_HTTPD_STATE *phttpstate)
+{
+       cyg_httpd_start_chunked("text");
+       if (logCount >= logSize)
+       {
+        cyg_httpd_write_chunked(logBuffer+logCount%logSize, logSize-logCount%logSize);
+       }
+       cyg_httpd_write_chunked(logBuffer, writePtr);
+       cyg_httpd_end_chunked();
+       return -1;
+}
+
+CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log, "/ram/log", show_log_entry);
+
+// Filesystem operations
+static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
+static int logfs_umount(cyg_mtab_entry *mte);
+static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+               int mode, cyg_file *fte);
+static int
+logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
+
+// File operations
+static int logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
+static int logfs_fo_close(struct CYG_FILE_TAG *fp);
+
+//==========================================================================
+// Filesystem table entries
+
+// -------------------------------------------------------------------------
+// Fstab entry.
+// This defines the entry in the filesystem table.
+// For simplicity we use _FILESYSTEM synchronization for all accesses since
+// we should never block in any filesystem operations.
+FSTAB_ENTRY( logfs_fste, "logfs", 0,
+               CYG_SYNCMODE_FILE_FILESYSTEM|CYG_SYNCMODE_IO_FILESYSTEM,
+               logfs_mount,
+               logfs_umount,
+               logfs_open,
+               (cyg_fsop_unlink *)cyg_fileio_erofs,
+               (cyg_fsop_mkdir *)cyg_fileio_erofs,
+               (cyg_fsop_rmdir *)cyg_fileio_erofs,
+               (cyg_fsop_rename *)cyg_fileio_erofs,
+               (cyg_fsop_link *)cyg_fileio_erofs,
+               (cyg_fsop_opendir *)cyg_fileio_erofs,
+               (cyg_fsop_chdir *)cyg_fileio_erofs,
+               (cyg_fsop_stat *)cyg_fileio_erofs,
+               (cyg_fsop_getinfo *)cyg_fileio_erofs,
+               (cyg_fsop_setinfo *)cyg_fileio_erofs);
+
+// -------------------------------------------------------------------------
+// File operations.
+// This set of file operations are used for normal open files.
+
+static cyg_fileops logfs_fileops =
+{
+       (cyg_fileop_read *)cyg_fileio_erofs,
+    (cyg_fileop_write *)logfs_fo_write,
+               (cyg_fileop_lseek *) cyg_fileio_erofs,
+       (cyg_fileop_ioctl *)cyg_fileio_erofs,
+    cyg_fileio_seltrue,
+    logfs_fo_fsync,
+    logfs_fo_close,
+       (cyg_fileop_fstat *)cyg_fileio_erofs,
+               (cyg_fileop_getinfo *) cyg_fileio_erofs,
+       (cyg_fileop_setinfo *)cyg_fileio_erofs,
+};
+
+// -------------------------------------------------------------------------
+// logfs_mount()
+// Process a mount request. This mainly finds root for the
+// filesystem.
+
+static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
+{
+       return ENOERR;
+}
+
+static int logfs_umount(cyg_mtab_entry *mte)
+{
+       return ENOERR;
+}
+
+static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+               int mode, cyg_file *file)
+{
+       file->f_flag |= mode & CYG_FILE_MODE_MASK;
+       file->f_type = CYG_FILE_TYPE_FILE;
+       file->f_ops = &logfs_fileops;
+       file->f_offset = 0;
+       file->f_data = 0;
+       file->f_xops = 0;
+       return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+// logfs_fo_write()
+// Write data to file.
+
+static int
+logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
+{
+       int i;
+       for (i = 0; i < uio->uio_iovcnt; i++)
+       {
+               cyg_iovec *iov = &uio->uio_iov[i];
+               char *buf = (char *) iov->iov_base;
+               off_t len = iov->iov_len;
+
+               diag_write(buf, len);
+       }
+       uio->uio_resid = 0;
+
+       return ENOERR;
+}
+static int
+logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
+{
+       return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+// romfs_fo_close()
+// Close a file. We just clear out the data pointer.
+
+static int logfs_fo_close(struct CYG_FILE_TAG *fp)
+{
+       return ENOERR;
+}
index 3b51c07b32e933e4836549fafb2624db001481d6..44bedd96dbeee068f71780cd4f623405e17c2373 100644 (file)
@@ -72,20 +72,19 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
 
 flash_driver_t at91sam7_flash =
 {
-    .name = "at91sam7_new",
-    .register_commands = at91sam7_register_commands,
-    .flash_bank_command = at91sam7_flash_bank_command,
-    .erase = at91sam7_erase,
-    .protect = at91sam7_protect,
-    .write = at91sam7_write,
-    .probe = at91sam7_probe,
-    .auto_probe = at91sam7_probe,
-    .erase_check = at91sam7_erase_check,
-    .protect_check = at91sam7_protect_check,
-    .info = at91sam7_info
+       .name = "at91sam7_new",
+       .register_commands = at91sam7_register_commands,
+       .flash_bank_command = at91sam7_flash_bank_command,
+       .erase = at91sam7_erase,
+       .protect = at91sam7_protect,
+       .write = at91sam7_write,
+       .probe = at91sam7_probe,
+       .auto_probe = at91sam7_probe,
+       .erase_check = at91sam7_erase_check,
+       .protect_check = at91sam7_protect_check,
+       .info = at91sam7_info
 };
 
-
 u32 MC_FMR[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
 u32 MC_FCR[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
 u32 MC_FSR[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
@@ -93,657 +92,654 @@ u32 MC_FSR[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
 char * EPROC[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
 
 long SRAMSIZ[16] = {
-        -1,
-    0x0400,   /*  1K */
-    0x0800,   /*  2K */ 
-        -1, 
-   0x1c000,   /* 112K */
-    0x1000,   /*   4K */
-   0x14000,   /*  80K */
-   0x28000,   /* 160K */
-    0x2000,   /*   8K */
-    0x4000,   /*  16K */
-    0x8000,   /*  32K */
-   0x10000,   /*  64K */
-   0x20000,   /* 128K */
-   0x40000,   /* 256K */
-   0x18000,   /*  96K */
-   0x80000,   /* 512K */
+       -1,
+       0x0400,         /*  1K */
+       0x0800,         /*  2K */ 
+       -1, 
+       0x1c000,        /* 112K */
+       0x1000,         /*   4K */
+       0x14000,        /*  80K */
+       0x28000,        /* 160K */
+       0x2000,         /*   8K */
+       0x4000,         /*  16K */
+       0x8000,         /*  32K */
+       0x10000,        /*  64K */
+       0x20000,        /* 128K */
+       0x40000,        /* 256K */
+       0x18000,        /*  96K */
+       0x80000,        /* 512K */
 };
 
 int at91sam7_register_commands(struct command_context_s *cmd_ctx)
 {
-    command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "at91sam7_new", NULL, COMMAND_ANY, NULL);
+       command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "at91sam7_new", NULL, COMMAND_ANY, NULL);
 
-    register_command(cmd_ctx, at91sam7_cmd, "gpnvm", at91sam7_handle_gpnvm_command, COMMAND_EXEC,
-                     "at91sam7 gpnvm <bit> set|clear, set or clear one gpnvm bit");
-    return ERROR_OK;
+       register_command(cmd_ctx, at91sam7_cmd, "gpnvm", at91sam7_handle_gpnvm_command, COMMAND_EXEC,
+                                       "at91sam7 gpnvm <bit> set|clear, set or clear one gpnvm bit");
+       return ERROR_OK;
 }
 
 u32 at91sam7_get_flash_status(target_t *target, int bank_number)
 {
-    u32 fsr;
-    target_read_u32(target, MC_FSR[bank_number], &fsr);
+       u32 fsr;
+       target_read_u32(target, MC_FSR[bank_number], &fsr);
 
-    return fsr;
+       return fsr;
 }
 
 /* Read clock configuration and set at91sam7_info->mck_freq */
 void at91sam7_read_clock_info(flash_bank_t *bank)
 {
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-    target_t *target = bank->target;
-    u32 mckr, mcfr, pllr, mor;
-    unsigned long tmp = 0, mainfreq;
-
-    /* Read Clock Generator Main Oscillator Register */
-    target_read_u32(target, CKGR_MOR, &mor);
-    /* Read Clock Generator Main Clock Frequency Register */
-    target_read_u32(target, CKGR_MCFR, &mcfr);
-    /* Read Master Clock Register*/
-    target_read_u32(target, PMC_MCKR, &mckr);
-    /* Read Clock Generator PLL Register  */
-    target_read_u32(target, CKGR_PLLR, &pllr);
-
-    at91sam7_info->mck_valid = 0;
-    at91sam7_info->mck_freq = 0;
-    switch (mckr & PMC_MCKR_CSS) 
-    {
-        case 0:         /* Slow Clock */
-            at91sam7_info->mck_valid = 1;
-            tmp = RC_FREQ;
-            break;
-
-        case 1:         /* Main Clock */
-            if ((mcfr & CKGR_MCFR_MAINRDY) && 
-                (at91sam7_info->ext_freq == 0))
-            {
-                at91sam7_info->mck_valid = 1;
-                tmp = RC_FREQ / 16ul * (mcfr & 0xffff);
-            }
-            else if (at91sam7_info->ext_freq != 0)
-            {
-                at91sam7_info->mck_valid = 1;
-                tmp = at91sam7_info->ext_freq;
-            }
-            break;
-
-        case 2:         /* Reserved */
-            break;
-
-        case 3:         /* PLL Clock */
-            if ((mcfr & CKGR_MCFR_MAINRDY) && 
-                (at91sam7_info->ext_freq == 0)) 
-            {
-                target_read_u32(target, CKGR_PLLR, &pllr);
-                if (!(pllr & CKGR_PLLR_DIV))
-                    break; /* 0 Hz */
-                at91sam7_info->mck_valid = 1;
-                mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
-                /* Integer arithmetic should have sufficient precision
-                   as long as PLL is properly configured. */
-                tmp = mainfreq / (pllr & CKGR_PLLR_DIV)*
-                     (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
-            }
-            else if ((at91sam7_info->ext_freq != 0) &&
-                    ((pllr&CKGR_PLLR_DIV) != 0))
-            {
-                at91sam7_info->mck_valid = 1;
-                tmp = at91sam7_info->ext_freq / (pllr&CKGR_PLLR_DIV)*
-                                 (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
-            }
-            break;
-    }
-
-    /* Prescaler adjust */
-    if ( (((mckr & PMC_MCKR_PRES) >> 2) == 7) || (tmp == 0) )
-    {
-        at91sam7_info->mck_valid = 0;
-        at91sam7_info->mck_freq = 0;
-    }
-    else if (((mckr & PMC_MCKR_PRES) >> 2) != 0)
-        at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);
-    else
-        at91sam7_info->mck_freq = tmp;
+       at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+       target_t *target = bank->target;
+       u32 mckr, mcfr, pllr, mor;
+       unsigned long tmp = 0, mainfreq;
+
+       /* Read Clock Generator Main Oscillator Register */
+       target_read_u32(target, CKGR_MOR, &mor);
+       /* Read Clock Generator Main Clock Frequency Register */
+       target_read_u32(target, CKGR_MCFR, &mcfr);
+       /* Read Master Clock Register*/
+       target_read_u32(target, PMC_MCKR, &mckr);
+       /* Read Clock Generator PLL Register  */
+       target_read_u32(target, CKGR_PLLR, &pllr);
+       
+       at91sam7_info->mck_valid = 0;
+       at91sam7_info->mck_freq = 0;
+       switch (mckr & PMC_MCKR_CSS) 
+       {
+               case 0:                 /* Slow Clock */
+                       at91sam7_info->mck_valid = 1;
+                       tmp = RC_FREQ;
+                       break;
+
+               case 1:                 /* Main Clock */
+                       if ((mcfr & CKGR_MCFR_MAINRDY) && 
+                               (at91sam7_info->ext_freq == 0))
+                       {
+                               at91sam7_info->mck_valid = 1;
+                               tmp = RC_FREQ / 16ul * (mcfr & 0xffff);
+                       }
+                       else if (at91sam7_info->ext_freq != 0)
+                       {
+                               at91sam7_info->mck_valid = 1;
+                               tmp = at91sam7_info->ext_freq;
+                       }
+                       break;
+
+               case 2:                 /* Reserved */
+                       break;
+
+               case 3:                 /* PLL Clock */
+                       if ((mcfr & CKGR_MCFR_MAINRDY) && 
+                               (at91sam7_info->ext_freq == 0)) 
+                       {
+                               target_read_u32(target, CKGR_PLLR, &pllr);
+                               if (!(pllr & CKGR_PLLR_DIV))
+                                       break; /* 0 Hz */
+                               at91sam7_info->mck_valid = 1;
+                               mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
+                               /* Integer arithmetic should have sufficient precision
+                                * as long as PLL is properly configured. */
+                               tmp = mainfreq / (pllr & CKGR_PLLR_DIV)*
+                                       (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
+                       }
+                       else if ((at91sam7_info->ext_freq != 0) &&
+                               ((pllr&CKGR_PLLR_DIV) != 0))
+                       {
+                               at91sam7_info->mck_valid = 1;
+                               tmp = at91sam7_info->ext_freq / (pllr&CKGR_PLLR_DIV)*
+                                       (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
+                       }
+                       break;
+       }
+
+       /* Prescaler adjust */
+       if ( (((mckr & PMC_MCKR_PRES) >> 2) == 7) || (tmp == 0) )
+       {
+               at91sam7_info->mck_valid = 0;
+               at91sam7_info->mck_freq = 0;
+       }
+       else if (((mckr & PMC_MCKR_PRES) >> 2) != 0)
+               at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);
+       else
+               at91sam7_info->mck_freq = tmp;
 }
 
 /* Setup the timimg registers for nvbits or normal flash */
 void at91sam7_set_flash_mode(flash_bank_t *bank, int mode)
 {
-    u32 fmr, fmcn = 0, fws = 0;
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-    target_t *target = bank->target;
-
-    if (mode && (mode != at91sam7_info->flashmode))
-    {
-        /* Always round up (ceil) */
-        if (mode == FMR_TIMING_NVBITS)
-        {
-            if (at91sam7_info->cidr_arch == 0x60)
-            {
-                /* AT91SAM7A3 uses master clocks in 100 ns */
-                fmcn = (at91sam7_info->mck_freq/10000000ul)+1;
-            }
-            else
-            {
-                /* master clocks in 1uS for ARCH 0x7 types */
-                fmcn = (at91sam7_info->mck_freq/1000000ul)+1;
-            }
-        }
-        else if (mode == FMR_TIMING_FLASH)
-        {
-            /* main clocks in 1.5uS */
-            fmcn = (at91sam7_info->mck_freq/1000000ul)+
-                   (at91sam7_info->mck_freq/2000000ul)+1;
-        }
-
-        /* hard overclocking */
-        if (fmcn > 0xFF)
-            fmcn = 0xFF;
-
-        /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
-        if (at91sam7_info->mck_freq <= 33333ul)
-            fmcn = 0;
-        /* Only allow fws=0 if clock frequency is < 30 MHz. */
-        if (at91sam7_info->mck_freq > 30000000ul)
-            fws = 1;
-
-        LOG_DEBUG("fmcn[%i]: %i", bank->bank_number, fmcn);
-        fmr = fmcn << 16 | fws << 8;
-        target_write_u32(target, MC_FMR[bank->bank_number], fmr);
-    }
-
-    at91sam7_info->flashmode = mode;
+       u32 fmr, fmcn = 0, fws = 0;
+       at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+       target_t *target = bank->target;
+
+       if (mode && (mode != at91sam7_info->flashmode))
+       {
+               /* Always round up (ceil) */
+               if (mode == FMR_TIMING_NVBITS)
+               {
+                       if (at91sam7_info->cidr_arch == 0x60)
+                       {
+                               /* AT91SAM7A3 uses master clocks in 100 ns */
+                               fmcn = (at91sam7_info->mck_freq/10000000ul)+1;
+                       }
+                       else
+                       {
+                               /* master clocks in 1uS for ARCH 0x7 types */
+                               fmcn = (at91sam7_info->mck_freq/1000000ul)+1;
+                       }
+               }
+               else if (mode == FMR_TIMING_FLASH)
+               {
+                       /* main clocks in 1.5uS */
+                       fmcn = (at91sam7_info->mck_freq/1000000ul)+
+                               (at91sam7_info->mck_freq/2000000ul)+1;
+               }
+
+               /* hard overclocking */
+               if (fmcn > 0xFF)
+                       fmcn = 0xFF;
+
+               /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
+               if (at91sam7_info->mck_freq <= 33333ul)
+                       fmcn = 0;
+               /* Only allow fws=0 if clock frequency is < 30 MHz. */
+               if (at91sam7_info->mck_freq > 30000000ul)
+                       fws = 1;
+
+               LOG_DEBUG("fmcn[%i]: %i", bank->bank_number, fmcn);
+               fmr = fmcn << 16 | fws << 8;
+               target_write_u32(target, MC_FMR[bank->bank_number], fmr);
+       }
+
+       at91sam7_info->flashmode = mode;
 }
 
 u32 at91sam7_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
 {
-    u32 status;
-
-    while ((!((status = at91sam7_get_flash_status(bank->target, bank->bank_number)) & waitbits)) && (timeout-- > 0))
-    {
-        LOG_DEBUG("status[%i]: 0x%x", bank->bank_number, status);
-        alive_sleep(1);
-    }
-
-    LOG_DEBUG("status[%i]: 0x%x", bank->bank_number, status);
-
-    if (status & 0x0C)
-    {
-        LOG_ERROR("status register: 0x%x", status);
-        if (status & 0x4)
-            LOG_ERROR("Lock Error Bit Detected, Operation Abort");
-        if (status & 0x8)
-            LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
-        if (status & 0x10)
-            LOG_ERROR("Security Bit Set, Operation Abort");
-    }
-
-    return status;
+       u32 status;
+
+       while ((!((status = at91sam7_get_flash_status(bank->target, bank->bank_number)) & waitbits)) && (timeout-- > 0))
+       {
+               LOG_DEBUG("status[%i]: 0x%x", bank->bank_number, status);
+               alive_sleep(1);
+       }
+
+       LOG_DEBUG("status[%i]: 0x%x", bank->bank_number, status);
+
+       if (status & 0x0C)
+       {
+               LOG_ERROR("status register: 0x%x", status);
+               if (status & 0x4)
+                       LOG_ERROR("Lock Error Bit Detected, Operation Abort");
+               if (status & 0x8)
+                       LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
+               if (status & 0x10)
+                       LOG_ERROR("Security Bit Set, Operation Abort");
+       }
+
+       return status;
 }
 
 /* Send one command to the AT91SAM flash controller */
 int at91sam7_flash_command(struct flash_bank_s *bank, u8 cmd, u16 pagen)
 {
-    u32 fcr;
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-    target_t *target = bank->target;
-
-    fcr = (0x5A<<24) | ((pagen&0x3FF)<<8) | cmd; 
-    target_write_u32(target, MC_FCR[bank->bank_number], fcr);
-    LOG_DEBUG("Flash command: 0x%x, flash bank: %i, page number: %u", fcr, bank->bank_number+1, pagen);
-
-    if ((at91sam7_info->cidr_arch == 0x60)&&((cmd==SLB)|(cmd==CLB)))
-    {
-        /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
-        if (at91sam7_wait_status_busy(bank, MC_FSR_EOL, 10)&0x0C)
-        {
-            return ERROR_FLASH_OPERATION_FAILED;
-        }
-        return ERROR_OK;
-    }
-
-    if (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C) 
-    {
-        return ERROR_FLASH_OPERATION_FAILED;
-    }
-
-    return ERROR_OK;
+       u32 fcr;
+       at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+       target_t *target = bank->target;
+
+       fcr = (0x5A<<24) | ((pagen&0x3FF)<<8) | cmd; 
+       target_write_u32(target, MC_FCR[bank->bank_number], fcr);
+       LOG_DEBUG("Flash command: 0x%x, flash bank: %i, page number: %u", fcr, bank->bank_number+1, pagen);
+
+       if ((at91sam7_info->cidr_arch == 0x60)&&((cmd==SLB)|(cmd==CLB)))
+       {
+               /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
+               if (at91sam7_wait_status_busy(bank, MC_FSR_EOL, 10)&0x0C)
+               {
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }
+               return ERROR_OK;
+       }
+
+       if (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C) 
+       {
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+
+       return ERROR_OK;
 }
 
 /* Read device id register, main clock frequency register and fill in driver info structure */
 int at91sam7_read_part_info(struct flash_bank_s *bank)
 {
-    flash_bank_t *t_bank = bank;
-    at91sam7_flash_bank_t *at91sam7_info;
-    target_t *target = t_bank->target;
-
-    u16 bnk, sec;
-    u16 arch;
-    u32 cidr, status;
-    u8 banks_num;
-    u16 num_nvmbits;
-    u16 sectors_num;
-    u16 pages_per_sector;
-    u16 page_size;
-    u32 ext_freq;
-    u32 bank_size;
-    u32 base_address = 0;
-    char *target_name = "Unknown";
-
-    at91sam7_info = t_bank->driver_priv;
-
-    if (at91sam7_info->cidr != 0)
-    {
-        /* flash already configured, update clock and check for protected sectors */
-        flash_bank_t *fb = bank;
-        t_bank = fb;
-
-        while (t_bank)
-        {
-            /* re-calculate master clock frequency */
-            at91sam7_read_clock_info(t_bank);
-
-            /* no timming */
-            at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
-
-            /* check protect state */
-            at91sam7_protect_check(t_bank);
-
-            t_bank = fb->next;
-            fb = t_bank;
-        }
-
-        return ERROR_OK;
-    }
-
-    /* Read and parse chip identification register */
-    target_read_u32(target, DBGU_CIDR, &cidr);
-    if (cidr == 0)
-    {
-        LOG_WARNING("Cannot identify target as an AT91SAM");
-        return ERROR_FLASH_OPERATION_FAILED;
-    }
-
-    if (at91sam7_info->flash_autodetection == 0)
-    {
-        /* banks and sectors are already created, based on data from input file */
-        flash_bank_t *fb = bank;
-        t_bank = fb;
-        while (t_bank)
-        {
-            at91sam7_info = t_bank->driver_priv;
-
-            at91sam7_info->cidr = cidr;
-            at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
-            at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
-            at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
-            at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
-            at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
-            at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
-            at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
-            at91sam7_info->cidr_version = cidr&0x001F;
-
-            /* calculate master clock frequency */
-            at91sam7_read_clock_info(t_bank);
-
-            /* no timming */
-            at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
-
-            /* check protect state */
-            at91sam7_protect_check(t_bank);
-
-            t_bank = fb->next;
-            fb = t_bank;
-        }
-
-        return ERROR_OK;
-    }
-
-    arch = (cidr>>20)&0x00FF;
-
-    /* check flash size */
-    switch ((cidr>>8)&0x000F)
-    {
-        case FLASH_SIZE_8KB:
-            break;
-
-        case FLASH_SIZE_16KB:
-            banks_num = 1;
-            sectors_num = 8;
-            pages_per_sector = 32;
-            page_size  = 64;
-            base_address = 0x00100000;
-            if (arch == 0x70)
-            {
-                num_nvmbits = 2;
-                target_name = "AT91SAM7S161/16";
-            }
-            break;
-
-        case FLASH_SIZE_32KB:
-            banks_num = 1;
-            sectors_num = 8;
-            pages_per_sector = 32;
-            page_size  = 128;
-            base_address = 0x00100000;
-            if (arch == 0x70)
-            {
-                num_nvmbits = 2;
-                target_name = "AT91SAM7S321/32";
-            }
-            if (arch == 0x72)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7SE32";
-            }
-            break;
-
-        case FLASH_SIZE_64KB:
-            banks_num = 1;
-            sectors_num = 16;
-            pages_per_sector = 32;
-            page_size  = 128;
-            base_address = 0x00100000;
-            if (arch == 0x70)
-            {
-                num_nvmbits = 2;
-                target_name = "AT91SAM7S64";
-            }
-            break;
-
-        case FLASH_SIZE_128KB:
-            banks_num = 1;
-            sectors_num = 8;
-            pages_per_sector = 64;
-            page_size  = 256;
-            base_address = 0x00100000;
-            if (arch == 0x70)
-            {
-                num_nvmbits = 2;
-                target_name = "AT91SAM7S128";
-            }
-            if (arch == 0x71)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7XC128";
-            }
-            if (arch == 0x72)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7SE128";
-            }
-            if (arch == 0x75)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7X128";
-            }
-            break;
-
-        case FLASH_SIZE_256KB:
-            banks_num = 1;
-            sectors_num = 16;
-            pages_per_sector = 64;
-            page_size  = 256;
-            base_address = 0x00100000;
-            if (arch == 0x60)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7A3";
-            }           
-            if (arch == 0x70)
-            {
-                num_nvmbits = 2;
-                target_name = "AT91SAM7S256";
-            }
-            if (arch == 0x71)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7XC256";
-            }
-            if (arch == 0x72)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7SE256";
-            }
-            if (arch == 0x75)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7X256";
-            }
-            break;
-
-        case FLASH_SIZE_512KB:
-            banks_num = 2;
-            sectors_num = 16;
-            pages_per_sector = 64;
-            page_size  = 256;
-            base_address = 0x00100000;
-            if (arch == 0x70)
-            {
-                num_nvmbits = 2;
-                target_name = "AT91SAM7S512";
-            }
-            if (arch == 0x71)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7XC512";
-            }
-            if (arch == 0x72)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7SE512";
-            }
-            if (arch == 0x75)
-            {
-                num_nvmbits = 3;
-                target_name = "AT91SAM7X512";
-            }
-            break;
-
-        case FLASH_SIZE_1024KB:
-            break;
-
-        case FLASH_SIZE_2048KB:
-            break;
-    }
-
-    if (strcmp(target_name, "Unknown") == 0)
-    {
-        LOG_ERROR("Target autodetection failed! Please specify target parameters in configuration file");
-        return ERROR_FLASH_OPERATION_FAILED;
-    }
-
-    ext_freq = at91sam7_info->ext_freq;
-
-    /* calculate bank size  */
-    bank_size = sectors_num * pages_per_sector * page_size;
-
-    for (bnk=0; bnk<banks_num; bnk++)
-    {
-        if (bnk > 0)
-        {
-            /* create a new flash bank element */
-            flash_bank_t *fb = malloc(sizeof(flash_bank_t));
-            fb->target = target;
-            fb->driver = &at91sam7_flash;
-            fb->driver_priv = malloc(sizeof(at91sam7_flash_bank_t));
-            fb->next = NULL;
-
-            /* link created bank in 'flash_banks' list and redirect t_bank */
-            t_bank->next = fb;
-            t_bank = fb;
-        }
-
-        t_bank->bank_number = bnk;
-        t_bank->base = base_address + bnk * bank_size;
-        t_bank->size = bank_size;
-        t_bank->chip_width = 0;
-        t_bank->bus_width = 4;
-        t_bank->num_sectors = sectors_num;
-
-        /* allocate sectors */
-        t_bank->sectors = malloc(sectors_num * sizeof(flash_sector_t));
-        for (sec=0; sec<sectors_num; sec++)
-        {
-            t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
-            t_bank->sectors[sec].size = pages_per_sector * page_size;
-            t_bank->sectors[sec].is_erased = -1;
-            t_bank->sectors[sec].is_protected = -1;
-        }
-
-        at91sam7_info = t_bank->driver_priv;
-
-        at91sam7_info->cidr = cidr;
-        at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
-        at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
-        at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
-        at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
-        at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
-        at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
-        at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
-        at91sam7_info->cidr_version = cidr&0x001F;
-
-        at91sam7_info->target_name  = target_name;
-        at91sam7_info->flashmode = 0;
-        at91sam7_info->ext_freq = ext_freq;
-        at91sam7_info->num_nvmbits = num_nvmbits;
-        at91sam7_info->num_nvmbits_on = 0;
-        at91sam7_info->pagesize = page_size;
-        at91sam7_info->pages_per_sector = pages_per_sector;
-
-        /* calculate master clock frequency */
-        at91sam7_read_clock_info(t_bank);
-
-        /* no timming */
-        at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
-
-        /* check protect state */       
-        at91sam7_protect_check(t_bank);
-    }
-
-    LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
-
-    return ERROR_OK;
+       flash_bank_t *t_bank = bank;
+       at91sam7_flash_bank_t *at91sam7_info;
+       target_t *target = t_bank->target;
+
+       u16 bnk, sec;
+       u16 arch;
+       u32 cidr;
+       u8 banks_num;
+       u16 num_nvmbits;
+       u16 sectors_num;
+       u16 pages_per_sector;
+       u16 page_size;
+       u32 ext_freq;
+       u32 bank_size;
+       u32 base_address = 0;
+       char *target_name = "Unknown";
+
+       at91sam7_info = t_bank->driver_priv;
+
+       if (at91sam7_info->cidr != 0)
+       {
+               /* flash already configured, update clock and check for protected sectors */
+               flash_bank_t *fb = bank;
+               t_bank = fb;
+
+               while (t_bank)
+               {
+                       /* re-calculate master clock frequency */
+                       at91sam7_read_clock_info(t_bank);
+
+                       /* no timming */
+                       at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
+
+                       /* check protect state */
+                       at91sam7_protect_check(t_bank);
+
+                       t_bank = fb->next;
+                       fb = t_bank;
+               }
+
+               return ERROR_OK;
+       }
+
+       /* Read and parse chip identification register */
+       target_read_u32(target, DBGU_CIDR, &cidr);
+       if (cidr == 0)
+       {
+               LOG_WARNING("Cannot identify target as an AT91SAM");
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+
+       if (at91sam7_info->flash_autodetection == 0)
+       {
+               /* banks and sectors are already created, based on data from input file */
+               flash_bank_t *fb = bank;
+               t_bank = fb;
+               while (t_bank)
+               {
+                       at91sam7_info = t_bank->driver_priv;
+
+                       at91sam7_info->cidr = cidr;
+                       at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
+                       at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
+                       at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
+                       at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
+                       at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
+                       at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
+                       at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
+                       at91sam7_info->cidr_version = cidr&0x001F;
+
+                       /* calculate master clock frequency */
+                       at91sam7_read_clock_info(t_bank);
+
+                       /* no timming */
+                       at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
+
+                       /* check protect state */
+                       at91sam7_protect_check(t_bank);
+
+                       t_bank = fb->next;
+                       fb = t_bank;
+               }
+
+               return ERROR_OK;
+       }
+
+       arch = (cidr>>20)&0x00FF;
+
+       /* check flash size */
+       switch ((cidr>>8)&0x000F)
+       {
+               case FLASH_SIZE_8KB:
+                       break;
+
+               case FLASH_SIZE_16KB:
+                       banks_num = 1;
+                       sectors_num = 8;
+                       pages_per_sector = 32;
+                       page_size  = 64;
+                       base_address = 0x00100000;
+                       if (arch == 0x70)
+                       {
+                               num_nvmbits = 2;
+                               target_name = "AT91SAM7S161/16";
+                       }
+                       break;
+
+               case FLASH_SIZE_32KB:
+                       banks_num = 1;
+                       sectors_num = 8;
+                       pages_per_sector = 32;
+                       page_size  = 128;
+                       base_address = 0x00100000;
+                       if (arch == 0x70)
+                       {
+                               num_nvmbits = 2;
+                               target_name = "AT91SAM7S321/32";
+                       }
+                       if (arch == 0x72)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7SE32";
+                       }
+                       break;
+
+               case FLASH_SIZE_64KB:
+                       banks_num = 1;
+                       sectors_num = 16;
+                       pages_per_sector = 32;
+                       page_size  = 128;
+                       base_address = 0x00100000;
+                       if (arch == 0x70)
+                       {
+                               num_nvmbits = 2;
+                               target_name = "AT91SAM7S64";
+                       }
+                       break;
+
+               case FLASH_SIZE_128KB:
+                       banks_num = 1;
+                       sectors_num = 8;
+                       pages_per_sector = 64;
+                       page_size  = 256;
+                       base_address = 0x00100000;
+                       if (arch == 0x70)
+                       {
+                               num_nvmbits = 2;
+                               target_name = "AT91SAM7S128";
+                       }
+                       if (arch == 0x71)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7XC128";
+                       }
+                       if (arch == 0x72)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7SE128";
+                       }
+                       if (arch == 0x75)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7X128";
+                       }
+                       break;
+
+               case FLASH_SIZE_256KB:
+                       banks_num = 1;
+                       sectors_num = 16;
+                       pages_per_sector = 64;
+                       page_size  = 256;
+                       base_address = 0x00100000;
+                       if (arch == 0x60)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7A3";
+                       }
+                       if (arch == 0x70)
+                       {
+                               num_nvmbits = 2;
+                               target_name = "AT91SAM7S256";
+                       }
+                       if (arch == 0x71)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7XC256";
+                       }
+                       if (arch == 0x72)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7SE256";
+                       }
+                       if (arch == 0x75)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7X256";
+                       }
+                       break;
+
+               case FLASH_SIZE_512KB:
+                       banks_num = 2;
+                       sectors_num = 16;
+                       pages_per_sector = 64;
+                       page_size  = 256;
+                       base_address = 0x00100000;
+                       if (arch == 0x70)
+                       {
+                               num_nvmbits = 2;
+                               target_name = "AT91SAM7S512";
+                       }
+                       if (arch == 0x71)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7XC512";
+                       }
+                       if (arch == 0x72)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7SE512";
+                       }
+                       if (arch == 0x75)
+                       {
+                               num_nvmbits = 3;
+                               target_name = "AT91SAM7X512";
+                       }
+                       break;
+
+               case FLASH_SIZE_1024KB:
+                       break;
+
+               case FLASH_SIZE_2048KB:
+                       break;
+       }
+
+       if (strcmp(target_name, "Unknown") == 0)
+       {
+               LOG_ERROR("Target autodetection failed! Please specify target parameters in configuration file");
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+
+       ext_freq = at91sam7_info->ext_freq;
+
+       /* calculate bank size  */
+       bank_size = sectors_num * pages_per_sector * page_size;
+
+       for (bnk=0; bnk<banks_num; bnk++)
+       {
+               if (bnk > 0)
+               {
+                       /* create a new flash bank element */
+                       flash_bank_t *fb = malloc(sizeof(flash_bank_t));
+                       fb->target = target;
+                       fb->driver = &at91sam7_flash;
+                       fb->driver_priv = malloc(sizeof(at91sam7_flash_bank_t));
+                       fb->next = NULL;
+
+                       /* link created bank in 'flash_banks' list and redirect t_bank */
+                       t_bank->next = fb;
+                       t_bank = fb;
+               }
+
+               t_bank->bank_number = bnk;
+               t_bank->base = base_address + bnk * bank_size;
+               t_bank->size = bank_size;
+               t_bank->chip_width = 0;
+               t_bank->bus_width = 4;
+               t_bank->num_sectors = sectors_num;
+
+               /* allocate sectors */
+               t_bank->sectors = malloc(sectors_num * sizeof(flash_sector_t));
+               for (sec=0; sec<sectors_num; sec++)
+               {
+                       t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
+                       t_bank->sectors[sec].size = pages_per_sector * page_size;
+                       t_bank->sectors[sec].is_erased = -1;
+                       t_bank->sectors[sec].is_protected = -1;
+               }
+
+               at91sam7_info = t_bank->driver_priv;
+
+               at91sam7_info->cidr = cidr;
+               at91sam7_info->cidr_ext = (cidr>>31)&0x0001;
+               at91sam7_info->cidr_nvptyp = (cidr>>28)&0x0007;
+               at91sam7_info->cidr_arch = (cidr>>20)&0x00FF;
+               at91sam7_info->cidr_sramsiz = (cidr>>16)&0x000F;
+               at91sam7_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
+               at91sam7_info->cidr_nvpsiz = (cidr>>8)&0x000F;
+               at91sam7_info->cidr_eproc = (cidr>>5)&0x0007;
+               at91sam7_info->cidr_version = cidr&0x001F;
+
+               at91sam7_info->target_name  = target_name;
+               at91sam7_info->flashmode = 0;
+               at91sam7_info->ext_freq = ext_freq;
+               at91sam7_info->num_nvmbits = num_nvmbits;
+               at91sam7_info->num_nvmbits_on = 0;
+               at91sam7_info->pagesize = page_size;
+               at91sam7_info->pages_per_sector = pages_per_sector;
+
+               /* calculate master clock frequency */
+               at91sam7_read_clock_info(t_bank);
+
+               /* no timming */
+               at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
+
+               /* check protect state */
+               at91sam7_protect_check(t_bank);
+       }
+
+       LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch );
+
+       return ERROR_OK;
 }
 
 int at91sam7_erase_check(struct flash_bank_s *bank)
 {
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-
-    target_t *target = bank->target;
-    u16 retval;
-    u32 blank;
-    u16 fast_check;
-    u8 *buffer;
-    u16 nSector;
-    u16 nByte;
-
-    if (bank->target->state != TARGET_HALTED)
-    {
-        LOG_ERROR("Target not halted");
-        return ERROR_TARGET_NOT_HALTED;
-    }
-
-    /* Configure the flash controller timing */
-    at91sam7_read_clock_info(bank); 
-    at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
-
-    fast_check = 1;
-    for (nSector=0; nSector<bank->num_sectors; nSector++)
-    {
-        retval = target_blank_check_memory(target, bank->base+bank->sectors[nSector].offset,
-                                bank->sectors[nSector].size, &blank);
-        if (retval != ERROR_OK)
-        {
-            fast_check = 0;
-            break;
-        }
-        if (blank == 0xFF)
-            bank->sectors[nSector].is_erased = 1;
-        else
-            bank->sectors[nSector].is_erased = 0;
-    }
-
-    if (fast_check)
-    {
-        return ERROR_OK;
-    }
-
-    LOG_USER("Running slow fallback erase check - add working memory");
-    
-    buffer = malloc(bank->sectors[0].size);
-    for (nSector=0; nSector<bank->num_sectors; nSector++)
-    {
-
-        bank->sectors[nSector].is_erased = 1;
-        retval = target->type->read_memory(target, bank->base+bank->sectors[nSector].offset, 4,
-                                           bank->sectors[nSector].size/4, buffer);
-        if (retval != ERROR_OK)
-            return retval;
-
-        for (nByte=0; nByte<bank->sectors[nSector].size; nByte++)
-        {
-            if (buffer[nByte] != 0xFF)
-            {
-                bank->sectors[nSector].is_erased = 0;
-                break;
-            }
-        }
-    }
-    free(buffer);
-
-    return ERROR_OK;
+       target_t *target = bank->target;
+       u16 retval;
+       u32 blank;
+       u16 fast_check;
+       u8 *buffer;
+       u16 nSector;
+       u16 nByte;
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       /* Configure the flash controller timing */
+       at91sam7_read_clock_info(bank); 
+       at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
+
+       fast_check = 1;
+       for (nSector=0; nSector<bank->num_sectors; nSector++)
+       {
+               retval = target_blank_check_memory(target, bank->base+bank->sectors[nSector].offset,
+                       bank->sectors[nSector].size, &blank);
+               if (retval != ERROR_OK)
+               {
+                       fast_check = 0;
+                       break;
+               }
+               if (blank == 0xFF)
+                       bank->sectors[nSector].is_erased = 1;
+               else
+                       bank->sectors[nSector].is_erased = 0;
+       }
+
+       if (fast_check)
+       {
+               return ERROR_OK;
+       }
+
+       LOG_USER("Running slow fallback erase check - add working memory");
+
+       buffer = malloc(bank->sectors[0].size);
+       for (nSector=0; nSector<bank->num_sectors; nSector++)
+       {
+               bank->sectors[nSector].is_erased = 1;
+               retval = target->type->read_memory(target, bank->base+bank->sectors[nSector].offset, 4,
+                       bank->sectors[nSector].size/4, buffer);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               for (nByte=0; nByte<bank->sectors[nSector].size; nByte++)
+               {
+                       if (buffer[nByte] != 0xFF)
+                       {
+                               bank->sectors[nSector].is_erased = 0;
+                               break;
+                       }
+               }
+       }
+       free(buffer);
+
+       return ERROR_OK;
 }
 
 int at91sam7_protect_check(struct flash_bank_s *bank)
 {
-    u8 lock_pos, gpnvm_pos;
-    u32 status;
-
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-
-    if (at91sam7_info->cidr == 0)
-    {
-        return ERROR_FLASH_BANK_NOT_PROBED;
-    }
-    if (bank->target->state != TARGET_HALTED)
-    {
-        LOG_ERROR("Target not halted");
-        return ERROR_TARGET_NOT_HALTED;
-    }
-
-    status = at91sam7_get_flash_status(bank->target, bank->bank_number);
-    at91sam7_info->lockbits = (status>>16);
-
-    at91sam7_info->num_lockbits_on = 0;
-    for (lock_pos=0; lock_pos<bank->num_sectors; lock_pos++)
-    {
-        if ( ((status>>(16+lock_pos))&(0x0001)) == 1)
-        {
-            at91sam7_info->num_lockbits_on++;
-            bank->sectors[lock_pos].is_protected = 1;
-        }
-        else
-            bank->sectors[lock_pos].is_protected = 0;
-    }
-
-    /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
-    status = at91sam7_get_flash_status(bank->target, 0);
-
-    at91sam7_info->securitybit = (status>>4)&0x01;
-    at91sam7_info->nvmbits = (status>>8)&0xFF;
-
-    at91sam7_info->num_nvmbits_on = 0;
-    for (gpnvm_pos=0; gpnvm_pos<at91sam7_info->num_nvmbits; gpnvm_pos++)
-    {
-        if ( ((status>>(8+gpnvm_pos))&(0x01)) == 1)
-        {
-            at91sam7_info->num_nvmbits_on++;
-        }
-    }
-
-    return ERROR_OK;
+       u8 lock_pos, gpnvm_pos;
+       u32 status;
+
+       at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+
+       if (at91sam7_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       status = at91sam7_get_flash_status(bank->target, bank->bank_number);
+       at91sam7_info->lockbits = (status>>16);
+
+       at91sam7_info->num_lockbits_on = 0;
+       for (lock_pos=0; lock_pos<bank->num_sectors; lock_pos++)
+       {
+               if ( ((status>>(16+lock_pos))&(0x0001)) == 1)
+               {
+                       at91sam7_info->num_lockbits_on++;
+                       bank->sectors[lock_pos].is_protected = 1;
+               }
+               else
+                       bank->sectors[lock_pos].is_protected = 0;
+       }
+
+       /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
+       status = at91sam7_get_flash_status(bank->target, 0);
+
+       at91sam7_info->securitybit = (status>>4)&0x01;
+       at91sam7_info->nvmbits = (status>>8)&0xFF;
+
+       at91sam7_info->num_nvmbits_on = 0;
+       for (gpnvm_pos=0; gpnvm_pos<at91sam7_info->num_nvmbits; gpnvm_pos++)
+       {
+               if ( ((status>>(8+gpnvm_pos))&(0x01)) == 1)
+               {
+                       at91sam7_info->num_nvmbits_on++;
+               }
+       }
+
+       return ERROR_OK;
 }
 
 /***************************************************************************************************************************************************************************************
@@ -758,368 +754,366 @@ int at91sam7_protect_check(struct flash_bank_s *bank)
 ****************************************************************************************************************************************************************************************/
 int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
 {
-    flash_bank_t *t_bank = bank;
-    at91sam7_flash_bank_t *at91sam7_info;
-    target_t *target = t_bank->target;
-
-    u32 base_address;
-    u32 bank_size;
-    u32 ext_freq;
-
-    int chip_width;
-    int bus_width;
-    int banks_num;
-    int num_sectors;
-
-    u16 pages_per_sector;
-    u16 page_size;
-    u16 num_nvmbits;
-
-    char *target_name;
-
-    int bnk, sec;
-
-    at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
-    t_bank->driver_priv = at91sam7_info;
-
-    /* part wasn't probed for info yet */
-    at91sam7_info->cidr = 0;
-    at91sam7_info->flashmode = 0;
-    at91sam7_info->ext_freq = 0;
-    at91sam7_info->flash_autodetection = 0;
-
-    if (argc == 14)
-    {
-        ext_freq = atol(args[13]) * 1000;
-        at91sam7_info->ext_freq = ext_freq;
-    }
-
-    if ((argc != 14)                ||
-        (atoi(args[4]) == 0)        ||  /* bus width */
-        (atoi(args[8]) == 0)        ||  /* banks number */
-        (atoi(args[9]) == 0)        ||  /* sectors per bank */
-        (atoi(args[10]) == 0)       ||  /* pages per sector */
-        (atoi(args[11]) == 0)       ||  /* page size */
-        (atoi(args[12]) == 0))          /* nvmbits number */
-    {
-        at91sam7_info->flash_autodetection = 1;
-        return ERROR_OK;
-    }
-
-    base_address = strtoul(args[1], NULL, 0);
-    chip_width = atoi(args[3]);
-    bus_width = atoi(args[4]);
-    banks_num = atoi(args[8]);
-    num_sectors = atoi(args[9]);
-    pages_per_sector = atoi(args[10]);
-    page_size = atoi(args[11]);
-    num_nvmbits = atoi(args[12]);
-
-    target_name = calloc(strlen(args[7])+1, sizeof(char));
-    strcpy(target_name, args[7]);
-
-    /* calculate bank size  */
-    bank_size = num_sectors * pages_per_sector * page_size;
-
-    for (bnk=0; bnk<banks_num; bnk++)
-    {
-        if (bnk > 0)
-        {
-            /* create a new bank element */
-            flash_bank_t *fb = malloc(sizeof(flash_bank_t));
-            fb->target = target;
-            fb->driver = &at91sam7_flash;
-            fb->driver_priv = malloc(sizeof(at91sam7_flash_bank_t));
-            fb->next = NULL;
-
-            /* link created bank in 'flash_banks' list and redirect t_bank */
-            t_bank->next = fb;
-            t_bank = fb;
-        }
-
-        t_bank->bank_number = bnk;
-        t_bank->base = base_address + bnk * bank_size;
-        t_bank->size = bank_size;
-        t_bank->chip_width = chip_width;
-        t_bank->bus_width = bus_width;
-        t_bank->num_sectors = num_sectors;
-
-        /* allocate sectors */
-        t_bank->sectors = malloc(num_sectors * sizeof(flash_sector_t));
-        for (sec=0; sec<num_sectors; sec++)
-        {
-            t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
-            t_bank->sectors[sec].size = pages_per_sector * page_size;
-            t_bank->sectors[sec].is_erased = -1;
-            t_bank->sectors[sec].is_protected = -1;
-        }
-
-        at91sam7_info = t_bank->driver_priv;
-
-        at91sam7_info->target_name  = target_name;
-        at91sam7_info->flashmode = 0;
-        at91sam7_info->ext_freq  = ext_freq;
-        at91sam7_info->num_nvmbits = num_nvmbits;
-        at91sam7_info->num_nvmbits_on = 0;
-        at91sam7_info->pagesize = page_size;
-        at91sam7_info->pages_per_sector = pages_per_sector;
-    }
-
-    return ERROR_OK;
+       flash_bank_t *t_bank = bank;
+       at91sam7_flash_bank_t *at91sam7_info;
+       target_t *target = t_bank->target;
+
+       u32 base_address;
+       u32 bank_size;
+       u32 ext_freq;
+
+       int chip_width;
+       int bus_width;
+       int banks_num;
+       int num_sectors;
+
+       u16 pages_per_sector;
+       u16 page_size;
+       u16 num_nvmbits;
+
+       char *target_name;
+
+       int bnk, sec;
+
+       at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
+       t_bank->driver_priv = at91sam7_info;
+
+       /* part wasn't probed for info yet */
+       at91sam7_info->cidr = 0;
+       at91sam7_info->flashmode = 0;
+       at91sam7_info->ext_freq = 0;
+       at91sam7_info->flash_autodetection = 0;
+
+       if (argc == 14)
+       {
+               ext_freq = atol(args[13]) * 1000;
+               at91sam7_info->ext_freq = ext_freq;
+       }
+
+       if ((argc != 14)                ||
+               (atoi(args[4]) == 0)        ||  /* bus width */
+               (atoi(args[8]) == 0)        ||  /* banks number */
+               (atoi(args[9]) == 0)        ||  /* sectors per bank */
+               (atoi(args[10]) == 0)       ||  /* pages per sector */
+               (atoi(args[11]) == 0)       ||  /* page size */
+               (atoi(args[12]) == 0))          /* nvmbits number */
+       {
+               at91sam7_info->flash_autodetection = 1;
+               return ERROR_OK;
+       }
+
+       base_address = strtoul(args[1], NULL, 0);
+       chip_width = atoi(args[3]);
+       bus_width = atoi(args[4]);
+       banks_num = atoi(args[8]);
+       num_sectors = atoi(args[9]);
+       pages_per_sector = atoi(args[10]);
+       page_size = atoi(args[11]);
+       num_nvmbits = atoi(args[12]);
+
+       target_name = calloc(strlen(args[7])+1, sizeof(char));
+       strcpy(target_name, args[7]);
+
+       /* calculate bank size  */
+       bank_size = num_sectors * pages_per_sector * page_size;
+
+       for (bnk=0; bnk<banks_num; bnk++)
+       {
+               if (bnk > 0)
+               {
+                       /* create a new bank element */
+                       flash_bank_t *fb = malloc(sizeof(flash_bank_t));
+                       fb->target = target;
+                       fb->driver = &at91sam7_flash;
+                       fb->driver_priv = malloc(sizeof(at91sam7_flash_bank_t));
+                       fb->next = NULL;
+
+                       /* link created bank in 'flash_banks' list and redirect t_bank */
+                       t_bank->next = fb;
+                       t_bank = fb;
+               }
+
+               t_bank->bank_number = bnk;
+               t_bank->base = base_address + bnk * bank_size;
+               t_bank->size = bank_size;
+               t_bank->chip_width = chip_width;
+               t_bank->bus_width = bus_width;
+               t_bank->num_sectors = num_sectors;
+
+               /* allocate sectors */
+               t_bank->sectors = malloc(num_sectors * sizeof(flash_sector_t));
+               for (sec=0; sec<num_sectors; sec++)
+               {
+                       t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
+                       t_bank->sectors[sec].size = pages_per_sector * page_size;
+                       t_bank->sectors[sec].is_erased = -1;
+                       t_bank->sectors[sec].is_protected = -1;
+               }
+
+               at91sam7_info = t_bank->driver_priv;
+
+               at91sam7_info->target_name  = target_name;
+               at91sam7_info->flashmode = 0;
+               at91sam7_info->ext_freq  = ext_freq;
+               at91sam7_info->num_nvmbits = num_nvmbits;
+               at91sam7_info->num_nvmbits_on = 0;
+               at91sam7_info->pagesize = page_size;
+               at91sam7_info->pages_per_sector = pages_per_sector;
+       }
+
+       return ERROR_OK;
 }
 
 int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
 {
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-    int sec;
-    u32 nbytes, pos;
-    u8 *buffer;
-    u8 erase_all;
-
-    if (at91sam7_info->cidr == 0)
-    {
-        return ERROR_FLASH_BANK_NOT_PROBED;
-    }
-
-    if (bank->target->state != TARGET_HALTED)
-    {
-        LOG_ERROR("Target not halted");
-        return ERROR_TARGET_NOT_HALTED;
-    }
-
-    if ((first < 0) || (last < first) || (last >= bank->num_sectors))
-    {
-        return ERROR_FLASH_SECTOR_INVALID;
-    }
-
-    erase_all = 0;
-    if ((first == 0) && (last == (bank->num_sectors-1)))
-    {
-        erase_all = 1;
-    }
-
-    /* Configure the flash controller timing */
-    at91sam7_read_clock_info(bank);
-    at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
-
-    if(erase_all)
-    {
-        if (at91sam7_flash_command(bank, EA, 0) != ERROR_OK) 
-        {
-            return ERROR_FLASH_OPERATION_FAILED;
-        }
-    }
-    else
-    {
-        /* allocate and clean buffer  */
-        nbytes = (last - first + 1) * bank->sectors[first].size;
-        buffer = malloc(nbytes * sizeof(u8));
-        for (pos=0; pos<nbytes; pos++)
-        {
-             buffer[pos] = 0xFF;
-        }
-
-        if ( at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK)
-        {
-            return ERROR_FLASH_OPERATION_FAILED;
-        }
-
-        free(buffer);
-    }
-
-    /* mark erased sectors */
-    for (sec=first; sec<=last; sec++)
-    {
-        bank->sectors[sec].is_erased = 1;
-    }
-
-    return ERROR_OK;
+       at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+       int sec;
+       u32 nbytes, pos;
+       u8 *buffer;
+       u8 erase_all;
+
+       if (at91sam7_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       if ((first < 0) || (last < first) || (last >= bank->num_sectors))
+       {
+               return ERROR_FLASH_SECTOR_INVALID;
+       }
+
+       erase_all = 0;
+       if ((first == 0) && (last == (bank->num_sectors-1)))
+       {
+               erase_all = 1;
+       }
+
+       /* Configure the flash controller timing */
+       at91sam7_read_clock_info(bank);
+       at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
+
+       if(erase_all)
+       {
+               if (at91sam7_flash_command(bank, EA, 0) != ERROR_OK) 
+               {
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }
+       }
+       else
+       {
+               /* allocate and clean buffer  */
+               nbytes = (last - first + 1) * bank->sectors[first].size;
+               buffer = malloc(nbytes * sizeof(u8));
+               for (pos=0; pos<nbytes; pos++)
+               {
+                       buffer[pos] = 0xFF;
+               }
+
+               if ( at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK)
+               {
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }
+
+               free(buffer);
+       }
+
+       /* mark erased sectors */
+       for (sec=first; sec<=last; sec++)
+       {
+               bank->sectors[sec].is_erased = 1;
+       }
+
+       return ERROR_OK;
 }
 
 int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
 {
-    u32 cmd;
-    u32 sector, pagen;
-
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-
-    if (at91sam7_info->cidr == 0)
-    {
-        return ERROR_FLASH_BANK_NOT_PROBED;
-    }
-
-    if (bank->target->state != TARGET_HALTED)
-    {
-        LOG_ERROR("Target not halted");
-        return ERROR_TARGET_NOT_HALTED;
-    }
-
-    if ((first < 0) || (last < first) || (last >= bank->num_sectors))
-    {
-        return ERROR_FLASH_SECTOR_INVALID;
-    }
-
-    /* Configure the flash controller timing */
-    at91sam7_read_clock_info(bank);
-    at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
-
-    for (sector=first; sector<=last; sector++)
-    {
-        if (set)
-             cmd = SLB;
-        else
-             cmd = CLB;
-
-        /* if we lock a page from one sector then entire sector will be locked, also,
-           if we unlock a page from a locked sector, entire sector will be unlocked   */
-        pagen = sector * at91sam7_info->pages_per_sector;
-
-        if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK)
-        {
-            return ERROR_FLASH_OPERATION_FAILED;
-        }
-    }
-
-    at91sam7_protect_check(bank);
-
-    return ERROR_OK;
+       u32 cmd;
+       u32 sector, pagen;
+
+       at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+
+       if (at91sam7_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       if ((first < 0) || (last < first) || (last >= bank->num_sectors))
+       {
+               return ERROR_FLASH_SECTOR_INVALID;
+       }
+
+       /* Configure the flash controller timing */
+       at91sam7_read_clock_info(bank);
+       at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
+
+       for (sector=first; sector<=last; sector++)
+       {
+               if (set)
+                       cmd = SLB;
+               else
+                       cmd = CLB;
+
+               /* if we lock a page from one sector then entire sector will be locked, also,
+                * if we unlock a page from a locked sector, entire sector will be unlocked   */
+               pagen = sector * at91sam7_info->pages_per_sector;
+
+               if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK)
+               {
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }
+       }
+
+       at91sam7_protect_check(bank);
+
+       return ERROR_OK;
 }
 
 int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
 {
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-    target_t *target = bank->target;
-    u32 dst_min_alignment, wcount, bytes_remaining = count;
-    u32 first_page, last_page, pagen, buffer_pos;
-
-    if (at91sam7_info->cidr == 0)
-    {
-        return ERROR_FLASH_BANK_NOT_PROBED;
-    }
-
-    if (bank->target->state != TARGET_HALTED)
-    {
-        LOG_ERROR("Target not halted");
-        return ERROR_TARGET_NOT_HALTED;
-    }
-
-    if (offset + count > bank->size)
-        return ERROR_FLASH_DST_OUT_OF_BANK;
-
-    dst_min_alignment = at91sam7_info->pagesize;
-
-    if (offset % dst_min_alignment)
-    {
-        LOG_WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);
-        return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
-    }
-
-    if (at91sam7_info->cidr_arch == 0)
-        return ERROR_FLASH_BANK_NOT_PROBED;
-
-    first_page = offset/dst_min_alignment;
-    last_page = CEIL(offset + count, dst_min_alignment);
-
-    LOG_DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
-
-    /* Configure the flash controller timing */
-    at91sam7_read_clock_info(bank);
-    at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
-
-    for (pagen=first_page; pagen<last_page; pagen++)
-    {
-        if (bytes_remaining<dst_min_alignment)
-            count = bytes_remaining;
-        else
-            count = dst_min_alignment;
-        bytes_remaining -= count;
-
-        /* Write one block to the PageWriteBuffer */
-        buffer_pos = (pagen-first_page)*dst_min_alignment;
-        wcount = CEIL(count,4);
-        target->type->write_memory(target, bank->base+pagen*dst_min_alignment, 4, wcount, buffer+buffer_pos);
-
-        /* Send Write Page command to Flash Controller */
-        if (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK)
-        {
-            return ERROR_FLASH_OPERATION_FAILED;
-        }
-        LOG_DEBUG("Write flash bank:%i page number:%i", bank->bank_number, pagen);
-    }
-
-    return ERROR_OK;
+       at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+       target_t *target = bank->target;
+       u32 dst_min_alignment, wcount, bytes_remaining = count;
+       u32 first_page, last_page, pagen, buffer_pos;
+
+       if (at91sam7_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       if (offset + count > bank->size)
+               return ERROR_FLASH_DST_OUT_OF_BANK;
+
+       dst_min_alignment = at91sam7_info->pagesize;
+
+       if (offset % dst_min_alignment)
+       {
+               LOG_WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);
+               return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+       }
+
+       if (at91sam7_info->cidr_arch == 0)
+               return ERROR_FLASH_BANK_NOT_PROBED;
+
+       first_page = offset/dst_min_alignment;
+       last_page = CEIL(offset + count, dst_min_alignment);
+
+       LOG_DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
+
+       /* Configure the flash controller timing */
+       at91sam7_read_clock_info(bank);
+       at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
+
+       for (pagen=first_page; pagen<last_page; pagen++)
+       {
+               if (bytes_remaining<dst_min_alignment)
+                       count = bytes_remaining;
+               else
+                       count = dst_min_alignment;
+               bytes_remaining -= count;
+
+               /* Write one block to the PageWriteBuffer */
+               buffer_pos = (pagen-first_page)*dst_min_alignment;
+               wcount = CEIL(count,4);
+               target->type->write_memory(target, bank->base+pagen*dst_min_alignment, 4, wcount, buffer+buffer_pos);
+
+               /* Send Write Page command to Flash Controller */
+               if (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK)
+               {
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }
+               LOG_DEBUG("Write flash bank:%i page number:%i", bank->bank_number, pagen);
+       }
+
+       return ERROR_OK;
 }
 
 int at91sam7_probe(struct flash_bank_s *bank)
 {
-    /* we can't probe on an at91sam7
-     * if this is an at91sam7, it has the configured flash
-     */
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-    int retval;
-
-    if (bank->target->state != TARGET_HALTED)
-    {
-        LOG_ERROR("Target not halted");
-        return ERROR_TARGET_NOT_HALTED;
-    }
-
-    retval = at91sam7_read_part_info(bank);
-    if (retval != ERROR_OK)
-        return retval;
-
-    return ERROR_OK;
+       /* we can't probe on an at91sam7
+        * if this is an at91sam7, it has the configured flash */
+       int retval;
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       retval = at91sam7_read_part_info(bank);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
 }
 
 int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
 {
-    int printed;
-    at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+       int printed;
+       at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
 
-    if (at91sam7_info->cidr == 0)
-    {
-        return ERROR_FLASH_BANK_NOT_PROBED;
-    }
+       if (at91sam7_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
 
-    printed = snprintf(buf, buf_size,
-            "\n at91sam7 driver information: Chip is %s\n",
-            at91sam7_info->target_name);
+       printed = snprintf(buf, buf_size,
+               "\n at91sam7 driver information: Chip is %s\n",
+               at91sam7_info->target_name);
 
-    buf += printed;
-    buf_size -= printed;
+       buf += printed;
+       buf_size -= printed;
 
-    printed = snprintf(buf, buf_size,
-            " Cidr: 0x%8.8x | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | Flashsize: 0x%8.8x\n",
-            at91sam7_info->cidr, at91sam7_info->cidr_arch, EPROC[at91sam7_info->cidr_eproc],
-            at91sam7_info->cidr_version, bank->size);
+       printed = snprintf(buf, buf_size,
+               " Cidr: 0x%8.8x | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | Flashsize: 0x%8.8x\n",
+               at91sam7_info->cidr, at91sam7_info->cidr_arch, EPROC[at91sam7_info->cidr_eproc],
+               at91sam7_info->cidr_version, bank->size);
 
-    buf += printed;
-    buf_size -= printed;
+       buf += printed;
+       buf_size -= printed;
 
-    printed = snprintf(buf, buf_size,
-            " Master clock (estimated): %li KHz | External clock: %li KHz\n",
-            at91sam7_info->mck_freq / 1000, at91sam7_info->ext_freq / 1000);
+       printed = snprintf(buf, buf_size,
+               " Master clock (estimated): %li KHz | External clock: %li KHz\n",
+               at91sam7_info->mck_freq / 1000, at91sam7_info->ext_freq / 1000);
 
-    buf += printed;
-    buf_size -= printed;
+       buf += printed;
+       buf_size -= printed;
 
-    printed = snprintf(buf, buf_size,
-            " Pagesize: %i bytes | Lockbits(%i): %i 0x%4.4x | Pages in lock region: %i \n",
-            at91sam7_info->pagesize, bank->num_sectors, at91sam7_info->num_lockbits_on,
-            at91sam7_info->lockbits, at91sam7_info->pages_per_sector*at91sam7_info->num_lockbits_on);
+       printed = snprintf(buf, buf_size,
+               " Pagesize: %i bytes | Lockbits(%i): %i 0x%4.4x | Pages in lock region: %i \n",
+               at91sam7_info->pagesize, bank->num_sectors, at91sam7_info->num_lockbits_on,
+               at91sam7_info->lockbits, at91sam7_info->pages_per_sector*at91sam7_info->num_lockbits_on);
 
-    buf += printed;
-    buf_size -= printed;
+       buf += printed;
+       buf_size -= printed;
 
-    printed = snprintf(buf, buf_size,
-            " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n",
-            at91sam7_info->securitybit, at91sam7_info->num_nvmbits,
-            at91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits);
+       printed = snprintf(buf, buf_size,
+               " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n",
+               at91sam7_info->securitybit, at91sam7_info->num_nvmbits,
+               at91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits);
 
-    buf += printed;
-    buf_size -= printed;
+       buf += printed;
+       buf_size -= printed;
 
-    return ERROR_OK;
+       return ERROR_OK;
 }
 
 /* 
@@ -1134,80 +1128,80 @@ int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
 */
 int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-    flash_bank_t *bank;
-    int bit;
-    u8  flashcmd;
-    u32 status;
-    at91sam7_flash_bank_t *at91sam7_info;
-    int retval;
-
-    if (argc != 2)
-    {
-        command_print(cmd_ctx, "at91sam7 gpnvm <bit> <set|clear>");
-        return ERROR_OK;
-    }
-
-    bank = get_flash_bank_by_num_noprobe(0);
-    if (bank ==  NULL)
-    {
-        return ERROR_FLASH_BANK_INVALID;
-    }
-    if (bank->driver != &at91sam7_flash)
-    {
-        command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]);
-        return ERROR_FLASH_BANK_INVALID;
-    }
-    if (bank->target->state != TARGET_HALTED)
-    {
-        LOG_ERROR("target has to be halted to perform flash operation");
-        return ERROR_TARGET_NOT_HALTED;
-    }
-
-    if (strcmp(args[1], "set") == 0)
-    {
-        flashcmd = SGPB;
-    }
-    else if (strcmp(args[1], "clear") == 0)
-    {
-        flashcmd = CGPB;
-    }
-    else
-    {
-        return ERROR_COMMAND_SYNTAX_ERROR;
-    }
-
-    at91sam7_info = bank->driver_priv;
-    if (at91sam7_info->cidr == 0)
-    {
-        retval = at91sam7_read_part_info(bank);
-        if (retval != ERROR_OK)
-        {
-            return retval;
-        }
-    }
-
-    bit = atoi(args[0]);
-    if ((bit < 0) || (bit >= at91sam7_info->num_nvmbits))
-    {
-        command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[0], at91sam7_info->target_name);
-        return ERROR_OK;
-    }
-
-    /* Configure the flash controller timing */
-    at91sam7_read_clock_info(bank);
-    at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
-
-    if (at91sam7_flash_command(bank, flashcmd, bit) != ERROR_OK)
-    {
-        return ERROR_FLASH_OPERATION_FAILED;
-    }
-
-    /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
-    status = at91sam7_get_flash_status(bank->target, 0);
-    LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n", flashcmd, bit, status);
-
-    /* check protect state */
-    at91sam7_protect_check(bank);
-
-    return ERROR_OK;
+       flash_bank_t *bank;
+       int bit;
+       u8  flashcmd;
+       u32 status;
+       at91sam7_flash_bank_t *at91sam7_info;
+       int retval;
+
+       if (argc != 2)
+       {
+               command_print(cmd_ctx, "at91sam7 gpnvm <bit> <set|clear>");
+               return ERROR_OK;
+       }
+
+       bank = get_flash_bank_by_num_noprobe(0);
+       if (bank ==  NULL)
+       {
+               return ERROR_FLASH_BANK_INVALID;
+       }
+       if (bank->driver != &at91sam7_flash)
+       {
+               command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]);
+               return ERROR_FLASH_BANK_INVALID;
+       }
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("target has to be halted to perform flash operation");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       if (strcmp(args[1], "set") == 0)
+       {
+               flashcmd = SGPB;
+       }
+       else if (strcmp(args[1], "clear") == 0)
+       {
+               flashcmd = CGPB;
+       }
+       else
+       {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       at91sam7_info = bank->driver_priv;
+       if (at91sam7_info->cidr == 0)
+       {
+               retval = at91sam7_read_part_info(bank);
+               if (retval != ERROR_OK)
+               {
+                       return retval;
+               }
+       }
+
+       bit = atoi(args[0]);
+       if ((bit < 0) || (bit >= at91sam7_info->num_nvmbits))
+       {
+               command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[0], at91sam7_info->target_name);
+               return ERROR_OK;
+       }
+
+       /* Configure the flash controller timing */
+       at91sam7_read_clock_info(bank);
+       at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
+       
+       if (at91sam7_flash_command(bank, flashcmd, bit) != ERROR_OK)
+       {
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+
+       /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
+       status = at91sam7_get_flash_status(bank->target, 0);
+       LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n", flashcmd, bit, status);
+
+       /* check protect state */
+       at91sam7_protect_check(bank);
+       
+       return ERROR_OK;
 }
index efc669e36d6a25e072aa712fd711ac3bc25d4f43..f57f36ec8cc156b6cd32f248eedf01d5716bdc35 100644 (file)
 #include "flash.h"
 #include "target.h"
 
-
 typedef struct at91sam7_flash_bank_s
 {
-    /* chip id register */
-    u32 cidr;
-    u16 cidr_ext;
-    u16 cidr_nvptyp;
-    u16 cidr_arch;
-    u16 cidr_sramsiz;
-    u16 cidr_nvpsiz;
-    u16 cidr_nvpsiz2;
-    u16 cidr_eproc;
-    u16 cidr_version;
-    char *target_name;
-
-    /* flash auto-detection */
-    u8  flash_autodetection;
-
-    /* flash geometry */
-    u16 pages_per_sector;
-    u16 pagesize;
-    u16 pages_in_lockregion;
-
-    /* nv memory bits */
-    u16 num_lockbits_on;
-    u16 lockbits;
-    u16 num_nvmbits;
-    u16 num_nvmbits_on;
-    u16 nvmbits;
-    u8  securitybit;
-
-    /* 0: not init
-       1: fmcn for nvbits (1uS)
-       2: fmcn for flash (1.5uS) */
-    u8  flashmode;
-
-    /* main clock status */
-    u8  mck_valid;
-    u32 mck_freq;
-
-    /* external clock frequency */
-    u32 ext_freq;
+       /* chip id register */
+       u32 cidr;
+       u16 cidr_ext;
+       u16 cidr_nvptyp;
+       u16 cidr_arch;
+       u16 cidr_sramsiz;
+       u16 cidr_nvpsiz;
+       u16 cidr_nvpsiz2;
+       u16 cidr_eproc;
+       u16 cidr_version;
+       char *target_name;
+
+       /* flash auto-detection */
+       u8  flash_autodetection;
+
+       /* flash geometry */
+       u16 pages_per_sector;
+       u16 pagesize;
+       u16 pages_in_lockregion;
+
+       /* nv memory bits */
+       u16 num_lockbits_on;
+       u16 lockbits;
+       u16 num_nvmbits;
+       u16 num_nvmbits_on;
+       u16 nvmbits;
+       u8  securitybit;
+
+       /* 0: not init
+        * 1: fmcn for nvbits (1uS)
+        * 2: fmcn for flash (1.5uS) */
+       u8  flashmode;
+
+       /* main clock status */
+       u8  mck_valid;
+       u32 mck_freq;
+
+       /* external clock frequency */
+       u32 ext_freq;
 
 } at91sam7_flash_bank_t;
 
 
 /* AT91SAM7 control registers */
-#define DBGU_CIDR           0xFFFFF240
-#define CKGR_MCFR           0xFFFFFC24
-#define CKGR_MOR            0xFFFFFC20
-#define CKGR_MCFR_MAINRDY      0x10000
-#define CKGR_PLLR           0xFFFFFC2c
-#define CKGR_PLLR_DIV             0xff
-#define CKGR_PLLR_MUL       0x07ff0000
-#define PMC_MCKR            0xFFFFFC30
-#define PMC_MCKR_CSS              0x03
-#define PMC_MCKR_PRES             0x1c
+#define DBGU_CIDR                      0xFFFFF240
+#define CKGR_MCFR                      0xFFFFFC24
+#define CKGR_MOR                       0xFFFFFC20
+#define CKGR_MCFR_MAINRDY      0x10000
+#define CKGR_PLLR                      0xFFFFFC2c
+#define CKGR_PLLR_DIV          0xff
+#define CKGR_PLLR_MUL          0x07ff0000
+#define PMC_MCKR                       0xFFFFFC30
+#define PMC_MCKR_CSS           0x03
+#define PMC_MCKR_PRES          0x1c
 
 /* Flash Controller Commands */
-#define WP      0x01
-#define SLB     0x02
-#define WPL     0x03
-#define CLB     0x04
-#define EA      0x08
-#define SGPB    0x0B
-#define CGPB    0x0D
-#define SSB     0x0F
+#define WP             0x01
+#define SLB            0x02
+#define WPL            0x03
+#define CLB            0x04
+#define EA             0x08
+#define SGPB   0x0B
+#define CGPB   0x0D
+#define SSB            0x0F
 
 /* MC_FSR bit definitions */
-#define MC_FSR_FRDY         1
-#define MC_FSR_EOL          2
+#define MC_FSR_FRDY                    1
+#define MC_FSR_EOL                     2
 
 /* AT91SAM7 constants */
-#define RC_FREQ         32000
+#define RC_FREQ                                32000
 
 /* Flash timing modes */
-#define FMR_TIMING_NONE     0
-#define FMR_TIMING_NVBITS   1
-#define FMR_TIMING_FLASH    2
+#define FMR_TIMING_NONE                0
+#define FMR_TIMING_NVBITS      1
+#define FMR_TIMING_FLASH       2
 
 /* Flash size constants */
-#define FLASH_SIZE_8KB      1
-#define FLASH_SIZE_16KB     2
-#define FLASH_SIZE_32KB     3
-#define FLASH_SIZE_64KB     5
-#define FLASH_SIZE_128KB    7
-#define FLASH_SIZE_256KB    9
-#define FLASH_SIZE_512KB    10
-#define FLASH_SIZE_1024KB   12
-#define FLASH_SIZE_2048KB   14
+#define FLASH_SIZE_8KB         1
+#define FLASH_SIZE_16KB                2
+#define FLASH_SIZE_32KB                3
+#define FLASH_SIZE_64KB                5
+#define FLASH_SIZE_128KB       7
+#define FLASH_SIZE_256KB       9
+#define FLASH_SIZE_512KB       10
+#define FLASH_SIZE_1024KB      12
+#define FLASH_SIZE_2048KB      14
 
 #endif /* AT91SAM7_H */
index db14da6e3d72d76452cb18c75feccb98e673e312..aa17e73d23b3e644c3802fde5b304dad71be712a 100644 (file)
-/***************************************************************************\r
- *   Copyright (C) 2006 by Magnus Lundin                                   *\r
- *   lundin@mlu.mine.nu                                                    *\r
- *                                                                         *\r
- *   This program is free software; you can redistribute it and/or modify  *\r
- *   it under the terms of the GNU General Public License as published by  *\r
- *   the Free Software Foundation; either version 2 of the License, or     *\r
- *   (at your option) any later version.                                   *\r
- *                                                                         *\r
- *   This program is distributed in the hope that it will be useful,       *\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
- *   GNU General Public License for more details.                          *\r
- *                                                                         *\r
- *   You should have received a copy of the GNU General Public License     *\r
- *   along with this program; if not, write to the                         *\r
- *   Free Software Foundation, Inc.,                                       *\r
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
- ***************************************************************************/\r
-\r
-/***************************************************************************\r
-There are some things to notice\r
-\r
-* AT91SAM7S64 is tested\r
-* All AT91SAM7Sxx  and  AT91SAM7Xxx should work but is not tested\r
-* All parameters are identified from onchip configuartion registers \r
-*\r
-* The flash controller handles erases automatically on a page (128/265 byte) basis\r
-* Only an EraseAll command is supported by the controller\r
-* Partial erases can be implemented in software by writing one 0xFFFFFFFF word to \r
-* some location in every page in the region to be erased\r
-*  \r
-* Lock regions (sectors) are 32 or 64 pages\r
-*\r
- ***************************************************************************/\r
-#ifdef HAVE_CONFIG_H\r
-#include "config.h"\r
-#endif\r
-\r
-#include "replacements.h"\r
-\r
-#include "at91sam7_old.h"\r
-\r
-#include "flash.h"\r
-#include "target.h"\r
-#include "log.h"\r
-#include "binarybuffer.h"\r
-#include "types.h"\r
-\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <unistd.h>\r
-\r
-int at91sam7_old_register_commands(struct command_context_s *cmd_ctx);\r
-int at91sam7_old_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);\r
-int at91sam7_old_erase(struct flash_bank_s *bank, int first, int last);\r
-int at91sam7_old_protect(struct flash_bank_s *bank, int set, int first, int last);\r
-int at91sam7_old_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);\r
-int at91sam7_old_probe(struct flash_bank_s *bank);\r
-int at91sam7_old_auto_probe(struct flash_bank_s *bank);\r
-int at91sam7_old_erase_check(struct flash_bank_s *bank);\r
-int at91sam7_old_protect_check(struct flash_bank_s *bank);\r
-int at91sam7_old_info(struct flash_bank_s *bank, char *buf, int buf_size);\r
-\r
-u32 at91sam7_old_get_flash_status(flash_bank_t *bank, u8 flashplane);\r
-void at91sam7_old_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode);\r
-u32 at91sam7_old_wait_status_busy(flash_bank_t *bank, u8 flashplane, u32 waitbits, int timeout);\r
-int at91sam7_old_flash_command(struct flash_bank_s *bank, u8 flashplane, u8 cmd, u16 pagen); \r
-int at91sam7_old_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
-\r
-flash_driver_t at91sam7_old_flash =\r
-{\r
-       .name = "at91sam7",\r
-       .register_commands = at91sam7_old_register_commands,\r
-       .flash_bank_command = at91sam7_old_flash_bank_command,\r
-       .erase = at91sam7_old_erase,\r
-       .protect = at91sam7_old_protect,\r
-       .write = at91sam7_old_write,\r
-       .probe = at91sam7_old_probe,\r
-       .auto_probe = at91sam7_old_probe,\r
-       .erase_check = at91sam7_old_erase_check,\r
-       .protect_check = at91sam7_old_protect_check,\r
-       .info = at91sam7_old_info\r
-};\r
-\r
-u32 MC_FMR_old[4] =    { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };\r
-u32 MC_FCR_old[4] =    { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };\r
-u32 MC_FSR_old[4] =    { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };\r
-\r
-char * EPROC_old[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};\r
-long NVPSIZ_old[16] = {\r
-   0,\r
-   0x2000, /*  8K */\r
-   0x4000, /* 16K */ \r
-   0x8000, /* 32K */\r
-   -1,\r
-   0x10000, /* 64K */\r
-   -1,\r
-   0x20000, /* 128K */\r
-   -1,\r
-   0x40000, /* 256K */\r
-   0x80000, /* 512K */\r
-   -1,\r
-   0x100000, /* 1024K */\r
-   -1,\r
-   0x200000, /* 2048K */\r
-   -1\r
-};\r
-\r
-long SRAMSIZ_old[16] = {\r
-   -1,\r
-   0x0400, /*  1K */\r
-   0x0800, /*  2K */ \r
-   -1, \r
-   0x1c000,  /* 112K */\r
-   0x1000,  /*   4K */\r
-   0x14000, /*  80K */\r
-   0x28000, /* 160K */\r
-   0x2000,  /*   8K */\r
-   0x4000,  /*  16K */\r
-   0x8000,  /*  32K */\r
-   0x10000, /*  64K */\r
-   0x20000, /* 128K */\r
-   0x40000, /* 256K */\r
-   0x18000, /* 96K */\r
-   0x80000, /* 512K */\r
-};\r
-\r
-int at91sam7_old_register_commands(struct command_context_s *cmd_ctx)\r
-{\r
-       command_t *at91sam7_old_cmd = register_command(cmd_ctx, NULL, "at91sam7", NULL, COMMAND_ANY, NULL);\r
-       register_command(cmd_ctx, at91sam7_old_cmd, "gpnvm", at91sam7_old_handle_gpnvm_command, COMMAND_EXEC,\r
-                       "at91sam7 gpnvm <num> <bit> set|clear, set or clear at91sam7 gpnvm bit");\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-u32 at91sam7_old_get_flash_status(flash_bank_t *bank, u8 flashplane)\r
-{\r
-       target_t *target = bank->target;\r
-       u32 fsr;\r
-       \r
-       target_read_u32(target, MC_FSR_old[flashplane], &fsr);\r
-       \r
-       return fsr;\r
-}\r
-\r
-/* Read clock configuration and set at91sam7_old_info->usec_clocks*/\r
-void at91sam7_old_read_clock_info(flash_bank_t *bank)\r
-{\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       target_t *target = bank->target;\r
-       u32 mckr, mcfr, pllr;\r
-       unsigned long tmp = 0, mainfreq;\r
-       int flashplane;\r
-\r
-       /* Read main clock freqency register */\r
-       target_read_u32(target, CKGR_MCFR_old, &mcfr);\r
-       /* Read master clock register */\r
-       target_read_u32(target, PMC_MCKR_old, &mckr);\r
-       /* Read Clock Generator PLL Register  */\r
-       target_read_u32(target, CKGR_PLLR_old, &pllr);\r
-\r
-       at91sam7_old_info->mck_valid = 0;\r
-       switch (mckr & PMC_MCKR_CSS_old) \r
-       {\r
-               case 0:                 /* Slow Clock */\r
-                       at91sam7_old_info->mck_valid = 1;\r
-                       mainfreq = RC_FREQ_old / 16ul * (mcfr & 0xffff);\r
-                       tmp = mainfreq;\r
-                       break;\r
-               case 1:                 /* Main Clock */\r
-                       if (mcfr & CKGR_MCFR_MAINRDY_old) \r
-                       {\r
-                               at91sam7_old_info->mck_valid = 1;\r
-                               mainfreq = RC_FREQ_old / 16ul * (mcfr & 0xffff);\r
-                               tmp = mainfreq;\r
-                       }\r
-                       break;\r
-\r
-               case 2:                 /* Reserved */\r
-                       break;\r
-               case 3:                 /* PLL Clock */\r
-                       if (mcfr & CKGR_MCFR_MAINRDY_old) \r
-                       {\r
-                               target_read_u32(target, CKGR_PLLR_old, &pllr);\r
-                               if (!(pllr & CKGR_PLLR_DIV_old))\r
-                                       break; /* 0 Hz */\r
-                               at91sam7_old_info->mck_valid = 1;\r
-                               mainfreq = RC_FREQ_old / 16ul * (mcfr & 0xffff);\r
-                               /* Integer arithmetic should have sufficient precision\r
-                                  as long as PLL is properly configured. */\r
-                               tmp = mainfreq / (pllr & CKGR_PLLR_DIV_old) *\r
-                                 (((pllr & CKGR_PLLR_MUL_old) >> 16) + 1);\r
-                       }\r
-                       break;\r
-       }\r
-       \r
-       /* Prescaler adjust */\r
-       if (((mckr & PMC_MCKR_PRES_old) >> 2) == 7)\r
-               at91sam7_old_info->mck_valid = 0;\r
-       else\r
-               at91sam7_old_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES_old) >> 2);\r
-\r
-       /* Forget old flash timing */\r
-       for (flashplane = 0; flashplane<at91sam7_old_info->num_planes; flashplane++)\r
-       {\r
-               at91sam7_old_set_flash_mode(bank, flashplane, FMR_TIMING_NONE_old);\r
-       }\r
-}\r
-\r
-/* Setup the timimg registers for nvbits or normal flash */\r
-void at91sam7_old_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode)\r
-{\r
-       u32 fmr, fmcn = 0, fws = 0;\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       target_t *target = bank->target;\r
-       \r
-       if (mode && (mode != at91sam7_old_info->flashmode[flashplane]))\r
-       {\r
-               /* Always round up (ceil) */\r
-               if (mode==FMR_TIMING_NVBITS_old)\r
-               {\r
-                       if (at91sam7_old_info->cidr_arch == 0x60)\r
-                       {\r
-                               /* AT91SAM7A3 uses master clocks in 100 ns */\r
-                               fmcn = (at91sam7_old_info->mck_freq/10000000ul)+1;\r
-                       }\r
-                       else\r
-                       {\r
-                               /* master clocks in 1uS for ARCH 0x7 types */\r
-                               fmcn = (at91sam7_old_info->mck_freq/1000000ul)+1;\r
-                       }\r
-               }\r
-               else if (mode==FMR_TIMING_FLASH_old)\r
-                       /* main clocks in 1.5uS */\r
-                       fmcn = (at91sam7_old_info->mck_freq/666666ul)+1;\r
-\r
-               /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */\r
-               if (at91sam7_old_info->mck_freq <= 33333ul)\r
-                       fmcn = 0;\r
-               /* Only allow fws=0 if clock frequency is < 30 MHz. */\r
-               if (at91sam7_old_info->mck_freq > 30000000ul)\r
-                       fws = 1;\r
-\r
-               LOG_DEBUG("fmcn[%i]: %i", flashplane, fmcn); \r
-               fmr = fmcn << 16 | fws << 8;\r
-               target_write_u32(target, MC_FMR_old[flashplane], fmr);\r
-       }\r
-       \r
-       at91sam7_old_info->flashmode[flashplane] = mode;                \r
-}\r
-\r
-u32 at91sam7_old_wait_status_busy(flash_bank_t *bank, u8 flashplane, u32 waitbits, int timeout)\r
-{\r
-       u32 status;\r
-       \r
-       while ((!((status = at91sam7_old_get_flash_status(bank,flashplane)) & waitbits)) && (timeout-- > 0))\r
-       {\r
-               LOG_DEBUG("status[%i]: 0x%x", flashplane, status);\r
-               alive_sleep(1);\r
-       }\r
-       \r
-       LOG_DEBUG("status[%i]: 0x%x", flashplane, status);\r
-\r
-       if (status & 0x0C)\r
-       {\r
-               LOG_ERROR("status register: 0x%x", status);\r
-               if (status & 0x4)\r
-                       LOG_ERROR("Lock Error Bit Detected, Operation Abort");\r
-               if (status & 0x8)\r
-                       LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");\r
-               if (status & 0x10)\r
-                       LOG_ERROR("Security Bit Set, Operation Abort");\r
-       }\r
-       \r
-       return status;\r
-}\r
-\r
-\r
-/* Send one command to the AT91SAM flash controller */\r
-int at91sam7_old_flash_command(struct flash_bank_s *bank, u8 flashplane, u8 cmd, u16 pagen) \r
-{\r
-       u32 fcr;\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       target_t *target = bank->target;\r
-\r
-       fcr = (0x5A<<24) | ((pagen&0x3FF)<<8) | cmd; \r
-       target_write_u32(target, MC_FCR_old[flashplane], fcr);\r
-       LOG_DEBUG("Flash command: 0x%x, flashplane: %i, pagenumber:%u", fcr, flashplane, pagen);\r
-\r
-       if ((at91sam7_old_info->cidr_arch == 0x60)&&((cmd==SLB_old)|(cmd==CLB_old)))\r
-       {\r
-               /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */\r
-               if (at91sam7_old_wait_status_busy(bank, flashplane, MC_FSR_EOL_old, 10)&0x0C) \r
-               {\r
-                       return ERROR_FLASH_OPERATION_FAILED;\r
-               }\r
-               return ERROR_OK;\r
-       }\r
-\r
-       if (at91sam7_old_wait_status_busy(bank, flashplane, MC_FSR_FRDY_old, 10)&0x0C) \r
-       {\r
-               return ERROR_FLASH_OPERATION_FAILED;\r
-       }\r
-       return ERROR_OK;\r
-}\r
-\r
-/* Read device id register, main clock frequency register and fill in driver info structure */\r
-int at91sam7_old_read_part_info(struct flash_bank_s *bank)\r
-{\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       target_t *target = bank->target;\r
-       u32 cidr, status;\r
-       int sectornum;\r
-\r
-       if (at91sam7_old_info->cidr != 0)\r
-               return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */\r
-       \r
-       /* Read and parse chip identification register */\r
-       target_read_u32(target, DBGU_CIDR_old, &cidr);\r
-       \r
-       if (cidr == 0)\r
-       {\r
-               LOG_WARNING("Cannot identify target as an AT91SAM");\r
-               return ERROR_FLASH_OPERATION_FAILED;\r
-       }\r
-       \r
-       at91sam7_old_info->cidr = cidr;\r
-       at91sam7_old_info->cidr_ext = (cidr>>31)&0x0001;\r
-       at91sam7_old_info->cidr_nvptyp = (cidr>>28)&0x0007;\r
-       at91sam7_old_info->cidr_arch = (cidr>>20)&0x00FF;\r
-       at91sam7_old_info->cidr_sramsiz = (cidr>>16)&0x000F;\r
-       at91sam7_old_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;\r
-       at91sam7_old_info->cidr_nvpsiz = (cidr>>8)&0x000F;\r
-       at91sam7_old_info->cidr_eproc = (cidr>>5)&0x0007;\r
-       at91sam7_old_info->cidr_version = cidr&0x001F;\r
-       bank->size = NVPSIZ_old[at91sam7_old_info->cidr_nvpsiz];\r
-       at91sam7_old_info->target_name = "Unknown";\r
-\r
-       /* Support just for bulk erase of a single flash plane, whole device if flash size <= 256k */\r
-       if (NVPSIZ_old[at91sam7_old_info->cidr_nvpsiz]<0x80000)  /* Flash size less than 512K, one flash plane */\r
-       {\r
-               bank->num_sectors = 1;\r
-               bank->sectors = malloc(sizeof(flash_sector_t));\r
-               bank->sectors[0].offset = 0;\r
-               bank->sectors[0].size = bank->size;\r
-               bank->sectors[0].is_erased = -1;\r
-               bank->sectors[0].is_protected = -1;\r
-       }\r
-       else    /* Flash size 512K or larger, several flash planes */\r
-       {\r
-               bank->num_sectors = NVPSIZ_old[at91sam7_old_info->cidr_nvpsiz]/0x40000;\r
-               bank->sectors = malloc(bank->num_sectors*sizeof(flash_sector_t));\r
-               for (sectornum=0; sectornum<bank->num_sectors; sectornum++)\r
-               {\r
-                       bank->sectors[sectornum].offset = sectornum*0x40000;\r
-                       bank->sectors[sectornum].size = 0x40000;\r
-                       bank->sectors[sectornum].is_erased = -1;\r
-                       bank->sectors[sectornum].is_protected = -1;\r
-               }\r
-       }\r
-               \r
-       \r
-\r
-       LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_old_info->cidr_nvptyp, at91sam7_old_info->cidr_arch );\r
-\r
-       /* Read main and master clock freqency register */\r
-       at91sam7_old_read_clock_info(bank);\r
-       \r
-       at91sam7_old_info->num_planes = 1;\r
-       status = at91sam7_old_get_flash_status(bank, 0);\r
-       at91sam7_old_info->securitybit = (status>>4)&0x01;\r
-       at91sam7_old_protect_check(bank);   /* TODO Check the protect check */\r
-       \r
-       if (at91sam7_old_info->cidr_arch == 0x70 )\r
-       {\r
-               at91sam7_old_info->num_nvmbits = 2;\r
-               at91sam7_old_info->nvmbits = (status>>8)&0x03;\r
-               bank->base = 0x100000;\r
-               bank->bus_width = 4;\r
-               if (bank->size==0x80000)  /* AT91SAM7S512 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7S512";\r
-                       at91sam7_old_info->num_planes = 2;\r
-                       if (at91sam7_old_info->num_planes != bank->num_sectors)\r
-                               LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;\r
-                       at91sam7_old_info->num_lockbits = 2*16;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 2*16*64;\r
-               }\r
-               if (bank->size==0x40000)  /* AT91SAM7S256 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7S256";\r
-                       at91sam7_old_info->num_lockbits = 16;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 16*64;\r
-               }\r
-               if (bank->size==0x20000)  /* AT91SAM7S128 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7S128";\r
-                       at91sam7_old_info->num_lockbits = 8;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 8*64;\r
-               }\r
-               if (bank->size==0x10000)  /* AT91SAM7S64 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7S64";\r
-                       at91sam7_old_info->num_lockbits = 16;\r
-                       at91sam7_old_info->pagesize = 128;\r
-                       at91sam7_old_info->pages_in_lockregion = 32;\r
-                       at91sam7_old_info->num_pages = 16*32;\r
-               }\r
-               if (bank->size==0x08000)  /* AT91SAM7S321/32 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7S321/32";\r
-                       at91sam7_old_info->num_lockbits = 8;\r
-                       at91sam7_old_info->pagesize = 128;\r
-                       at91sam7_old_info->pages_in_lockregion = 32;\r
-                       at91sam7_old_info->num_pages = 8*32;\r
-               }\r
-               \r
-               return ERROR_OK;\r
-       }\r
-\r
-       if (at91sam7_old_info->cidr_arch == 0x71 )\r
-       {\r
-               at91sam7_old_info->num_nvmbits = 3;\r
-               at91sam7_old_info->nvmbits = (status>>8)&0x07;\r
-               bank->base = 0x100000;\r
-               bank->bus_width = 4;\r
-               if (bank->size==0x80000)  /* AT91SAM7XC512 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7XC512";\r
-                       at91sam7_old_info->num_planes = 2;\r
-                       if (at91sam7_old_info->num_planes != bank->num_sectors)\r
-                               LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;\r
-                       at91sam7_old_info->num_lockbits = 2*16;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 2*16*64;\r
-               }\r
-               if (bank->size==0x40000)  /* AT91SAM7XC256 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7XC256";\r
-                       at91sam7_old_info->num_lockbits = 16;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 16*64;\r
-               }\r
-               if (bank->size==0x20000)  /* AT91SAM7XC128 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7XC128";\r
-                       at91sam7_old_info->num_lockbits = 8;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 8*64;\r
-               }\r
-               \r
-               return ERROR_OK;\r
-       }\r
-       \r
-       if (at91sam7_old_info->cidr_arch == 0x72 )\r
-       {\r
-               at91sam7_old_info->num_nvmbits = 3;\r
-               at91sam7_old_info->nvmbits = (status>>8)&0x07;\r
-               bank->base = 0x100000;\r
-               bank->bus_width = 4;\r
-               if (bank->size==0x80000) /* AT91SAM7SE512 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7SE512";\r
-                       at91sam7_old_info->num_planes = 2;\r
-                       if (at91sam7_old_info->num_planes != bank->num_sectors)\r
-                               LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;\r
-                       at91sam7_old_info->num_lockbits = 32;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 32*64;\r
-               }\r
-               if (bank->size==0x40000)\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7SE256";\r
-                       at91sam7_old_info->num_lockbits = 16;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 16*64;\r
-               }\r
-               if (bank->size==0x08000)\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7SE32";\r
-                       at91sam7_old_info->num_lockbits = 8;\r
-                       at91sam7_old_info->pagesize = 128;\r
-                       at91sam7_old_info->pages_in_lockregion = 32;\r
-                       at91sam7_old_info->num_pages = 8*32;\r
-               }\r
-               \r
-               return ERROR_OK;\r
-       }\r
-       \r
-       if (at91sam7_old_info->cidr_arch == 0x75 )\r
-       {\r
-               at91sam7_old_info->num_nvmbits = 3;\r
-               at91sam7_old_info->nvmbits = (status>>8)&0x07;\r
-               bank->base = 0x100000;\r
-               bank->bus_width = 4;\r
-               if (bank->size==0x80000)  /* AT91SAM7X512 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7X512";\r
-                       at91sam7_old_info->num_planes = 2;\r
-                       if (at91sam7_old_info->num_planes != bank->num_sectors)\r
-                               LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;\r
-                       at91sam7_old_info->num_lockbits = 32;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 2*16*64;\r
-                       LOG_DEBUG("Support for AT91SAM7X512 is experimental in this version!");\r
-               }\r
-               if (bank->size==0x40000)  /* AT91SAM7X256 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7X256";\r
-                       at91sam7_old_info->num_lockbits = 16;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 16*64;\r
-               }\r
-               if (bank->size==0x20000)  /* AT91SAM7X128 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7X128";\r
-                       at91sam7_old_info->num_lockbits = 8;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 64;\r
-                       at91sam7_old_info->num_pages = 8*64;\r
-               }\r
-       \r
-               return ERROR_OK;\r
-       }\r
-       \r
-       if (at91sam7_old_info->cidr_arch == 0x60 )\r
-       {\r
-               at91sam7_old_info->num_nvmbits = 3;\r
-               at91sam7_old_info->nvmbits = (status>>8)&0x07;\r
-               bank->base = 0x100000;\r
-               bank->bus_width = 4;\r
-               \r
-               if (bank->size == 0x40000)  /* AT91SAM7A3 */\r
-               {\r
-                       at91sam7_old_info->target_name = "AT91SAM7A3";\r
-                       at91sam7_old_info->num_lockbits = 16;\r
-                       at91sam7_old_info->pagesize = 256;\r
-                       at91sam7_old_info->pages_in_lockregion = 16;\r
-                       at91sam7_old_info->num_pages = 16*64;\r
-               }\r
-               return ERROR_OK;\r
-       }\r
-       \r
-       LOG_WARNING("at91sam7_old flash only tested for AT91SAM7Sxx series");\r
-       return ERROR_OK;\r
-}\r
-\r
-int at91sam7_old_erase_check(struct flash_bank_s *bank)\r
-{\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       \r
-       if (!at91sam7_old_info->working_area_size)\r
-       {\r
-       }\r
-       else\r
-       {       \r
-       }\r
-       \r
-       return ERROR_OK;\r
-}\r
-\r
-int at91sam7_old_protect_check(struct flash_bank_s *bank)\r
-{\r
-       u32 status;\r
-       int flashplane;\r
-       \r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-\r
-       if (at91sam7_old_info->cidr == 0)\r
-       {\r
-               return ERROR_FLASH_BANK_NOT_PROBED;\r
-       }\r
-\r
-       if (bank->target->state != TARGET_HALTED)\r
-       {\r
-               LOG_ERROR("Target not halted");\r
-               return ERROR_TARGET_NOT_HALTED;\r
-       }\r
-\r
-       for (flashplane=0;flashplane<at91sam7_old_info->num_planes;flashplane++)\r
-       {\r
-               status = at91sam7_old_get_flash_status(bank, flashplane);\r
-               at91sam7_old_info->lockbits[flashplane] = (status >> 16);\r
-       }\r
-       \r
-       return ERROR_OK;\r
-}\r
-\r
-/* flash_bank at91sam7_old 0 0 0 0 <target#>\r
- */\r
-int at91sam7_old_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)\r
-{\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info;\r
-       int i;\r
-       \r
-       if (argc < 6)\r
-       {\r
-               LOG_WARNING("incomplete flash_bank at91sam7_old configuration");\r
-               return ERROR_FLASH_BANK_INVALID;\r
-       }\r
-       \r
-       at91sam7_old_info = malloc(sizeof(at91sam7_old_flash_bank_t));\r
-       bank->driver_priv = at91sam7_old_info;\r
-       \r
-       /* part wasn't probed for info yet */\r
-       at91sam7_old_info->cidr = 0;\r
-       for (i=0;i<4;i++)\r
-               at91sam7_old_info->flashmode[i]=0;\r
-       \r
-       return ERROR_OK;\r
-}\r
-\r
-int at91sam7_old_erase(struct flash_bank_s *bank, int first, int last)\r
-{\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       u8 flashplane;\r
-\r
-       if (at91sam7_old_info->cidr == 0)\r
-       {\r
-               return ERROR_FLASH_BANK_NOT_PROBED;\r
-       }\r
-\r
-       if (bank->target->state != TARGET_HALTED)\r
-       {\r
-               LOG_ERROR("Target not halted");\r
-               return ERROR_TARGET_NOT_HALTED;\r
-       }\r
-       \r
-       if ((first < 0) || (last < first) || (last >= bank->num_sectors))\r
-       {\r
-               if ((first == 0) && (last == (at91sam7_old_info->num_lockbits-1)))\r
-               {\r
-                       LOG_WARNING("Sector numbers based on lockbit count, probably a deprecated script");\r
-                       last = bank->num_sectors-1;\r
-               }\r
-               else return ERROR_FLASH_SECTOR_INVALID;\r
-       }\r
-\r
-       /* Configure the flash controller timing */\r
-       at91sam7_old_read_clock_info(bank);     \r
-       for (flashplane = first; flashplane<=last; flashplane++)\r
-       {\r
-               /* Configure the flash controller timing */\r
-               at91sam7_old_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH_old);\r
-               if (at91sam7_old_flash_command(bank, flashplane, EA_old, 0) != ERROR_OK) \r
-               {\r
-                       return ERROR_FLASH_OPERATION_FAILED;\r
-               }       \r
-       }\r
-       return ERROR_OK;\r
-\r
-}\r
-\r
-int at91sam7_old_protect(struct flash_bank_s *bank, int set, int first, int last)\r
-{\r
-       u32 cmd, pagen;\r
-       u8 flashplane;\r
-       int lockregion;\r
-       \r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       \r
-       if (at91sam7_old_info->cidr == 0)\r
-       {\r
-               return ERROR_FLASH_BANK_NOT_PROBED;\r
-       }\r
-\r
-       if (bank->target->state != TARGET_HALTED)\r
-       {\r
-               LOG_ERROR("Target not halted");\r
-               return ERROR_TARGET_NOT_HALTED;\r
-       }\r
-       \r
-       if ((first < 0) || (last < first) || (last >= at91sam7_old_info->num_lockbits))\r
-       {\r
-               return ERROR_FLASH_SECTOR_INVALID;\r
-       }\r
-       \r
-       at91sam7_old_read_clock_info(bank);     \r
-       \r
-       for (lockregion=first;lockregion<=last;lockregion++) \r
-       {\r
-               pagen = lockregion*at91sam7_old_info->pages_in_lockregion;\r
-               flashplane = (pagen>>10)&0x03;\r
-               /* Configure the flash controller timing */\r
-               at91sam7_old_set_flash_mode(bank, flashplane, FMR_TIMING_NVBITS_old);\r
-               \r
-               if (set)\r
-                        cmd = SLB_old; \r
-               else\r
-                        cmd = CLB_old;                 \r
-\r
-               if (at91sam7_old_flash_command(bank, flashplane, cmd, pagen) != ERROR_OK) \r
-               {\r
-                       return ERROR_FLASH_OPERATION_FAILED;\r
-               }       \r
-       }\r
-       \r
-       at91sam7_old_protect_check(bank);\r
-               \r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-int at91sam7_old_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)\r
-{\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       target_t *target = bank->target;\r
-       u32 dst_min_alignment, wcount, bytes_remaining = count;\r
-       u32 first_page, last_page, pagen, buffer_pos;\r
-       u8 flashplane;\r
-       \r
-       if (at91sam7_old_info->cidr == 0)\r
-       {\r
-               return ERROR_FLASH_BANK_NOT_PROBED;\r
-       }\r
-\r
-       if (bank->target->state != TARGET_HALTED)\r
-       {\r
-               LOG_ERROR("Target not halted");\r
-               return ERROR_TARGET_NOT_HALTED;\r
-       }\r
-\r
-       if (offset + count > bank->size)\r
-               return ERROR_FLASH_DST_OUT_OF_BANK;\r
-       \r
-       dst_min_alignment = at91sam7_old_info->pagesize;\r
-\r
-       if (offset % dst_min_alignment)\r
-       {\r
-               LOG_WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);\r
-               return ERROR_FLASH_DST_BREAKS_ALIGNMENT;\r
-       }\r
-       \r
-       if (at91sam7_old_info->cidr_arch == 0)\r
-               return ERROR_FLASH_BANK_NOT_PROBED;\r
-\r
-       first_page = offset/dst_min_alignment;\r
-       last_page = CEIL(offset + count, dst_min_alignment);\r
-       \r
-       LOG_DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);\r
-       \r
-       at91sam7_old_read_clock_info(bank);     \r
-\r
-       for (pagen=first_page; pagen<last_page; pagen++) \r
-       {\r
-               if (bytes_remaining<dst_min_alignment)\r
-                       count = bytes_remaining;\r
-               else\r
-                       count = dst_min_alignment;\r
-               bytes_remaining -= count;\r
-               \r
-               /* Write one block to the PageWriteBuffer */\r
-               buffer_pos = (pagen-first_page)*dst_min_alignment;\r
-               wcount = CEIL(count,4);\r
-               target->type->write_memory(target, bank->base+pagen*dst_min_alignment, 4, wcount, buffer+buffer_pos);\r
-               flashplane = (pagen>>10)&0x3;\r
-               \r
-               /* Configure the flash controller timing */     \r
-               at91sam7_old_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH_old);\r
-               /* Send Write Page command to Flash Controller */\r
-               if (at91sam7_old_flash_command(bank, flashplane, WP_old, pagen) != ERROR_OK) \r
-               {\r
-                               return ERROR_FLASH_OPERATION_FAILED;\r
-               }\r
-               LOG_DEBUG("Write flash plane:%i page number:%i", flashplane, pagen);\r
-       }\r
-       \r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-int at91sam7_old_probe(struct flash_bank_s *bank)\r
-{\r
-       /* we can't probe on an at91sam7_old\r
-        * if this is an at91sam7_old, it has the configured flash\r
-        */\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       int retval;\r
-       \r
-       if (at91sam7_old_info->cidr != 0)\r
-       {\r
-               return ERROR_OK; /* already probed */\r
-       }\r
-\r
-       if (bank->target->state != TARGET_HALTED)\r
-       {\r
-               LOG_ERROR("Target not halted");\r
-               return ERROR_TARGET_NOT_HALTED;\r
-       }\r
-\r
-       retval = at91sam7_old_read_part_info(bank);\r
-       if (retval != ERROR_OK)\r
-               return retval;\r
-       \r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-int at91sam7_old_info(struct flash_bank_s *bank, char *buf, int buf_size)\r
-{\r
-       int printed, flashplane;\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;\r
-       \r
-       if (at91sam7_old_info->cidr == 0)\r
-       {\r
-               return ERROR_FLASH_BANK_NOT_PROBED;\r
-       }\r
-       \r
-       printed = snprintf(buf, buf_size, "\nat91sam7_old information: Chip is %s\n",at91sam7_old_info->target_name);\r
-       buf += printed;\r
-       buf_size -= printed;\r
-       \r
-       printed = snprintf(buf, buf_size, "cidr: 0x%8.8x, arch: 0x%4.4x, eproc: %s, version:0x%3.3x,  flashsize: 0x%8.8x\n",\r
-                 at91sam7_old_info->cidr, at91sam7_old_info->cidr_arch, EPROC_old[at91sam7_old_info->cidr_eproc], at91sam7_old_info->cidr_version, bank->size);\r
-       buf += printed;\r
-       buf_size -= printed;\r
-                       \r
-       printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz \n", at91sam7_old_info->mck_freq / 1000);\r
-       buf += printed;\r
-       buf_size -= printed;\r
-       \r
-       if (at91sam7_old_info->num_planes>1) {          \r
-               printed = snprintf(buf, buf_size, "flashplanes: %i, pagesize: %i, lock regions: %i, pages in lock region: %i \n", \r
-                          at91sam7_old_info->num_planes, at91sam7_old_info->pagesize, at91sam7_old_info->num_lockbits, at91sam7_old_info->num_pages/at91sam7_old_info->num_lockbits);\r
-               buf += printed;\r
-               buf_size -= printed;\r
-               for (flashplane=0; flashplane<at91sam7_old_info->num_planes; flashplane++)\r
-               {\r
-                       printed = snprintf(buf, buf_size, "lockbits[%i]: 0x%4.4x,  ", flashplane, at91sam7_old_info->lockbits[flashplane]);\r
-                       buf += printed;\r
-                       buf_size -= printed;\r
-               }\r
-       }\r
-       else\r
-       if (at91sam7_old_info->num_lockbits>0) {                \r
-               printed = snprintf(buf, buf_size, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n", \r
-                          at91sam7_old_info->pagesize, at91sam7_old_info->num_lockbits, at91sam7_old_info->lockbits[0], at91sam7_old_info->num_pages/at91sam7_old_info->num_lockbits);\r
-               buf += printed;\r
-               buf_size -= printed;\r
-       }\r
-                       \r
-       printed = snprintf(buf, buf_size, "securitybit: %i,  nvmbits(%i): 0x%1.1x\n", at91sam7_old_info->securitybit, at91sam7_old_info->num_nvmbits, at91sam7_old_info->nvmbits);\r
-       buf += printed;\r
-       buf_size -= printed;\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-/* \r
-* On AT91SAM7S: When the gpnvm bits are set with \r
-* > at91sam7_old gpnvm 0 bitnr set\r
-* the changes are not visible in the flash controller status register MC_FSR_old \r
-* until the processor has been reset.\r
-* On the Olimex board this requires a power cycle.\r
-* Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):\r
-*      The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes\r
-*      Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.\r
-*/\r
-int at91sam7_old_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       flash_bank_t *bank;\r
-       int bit;\r
-       u8  flashcmd;\r
-       u32 status;\r
-       char *value;\r
-       at91sam7_old_flash_bank_t *at91sam7_old_info;\r
-       int retval;\r
-\r
-       if (argc < 3)\r
-       {\r
-               command_print(cmd_ctx, "at91sam7_old gpnvm <num> <bit> <set|clear>");\r
-               return ERROR_OK;\r
-       }\r
-       \r
-       bank = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));\r
-       bit = atoi(args[1]);\r
-       value = args[2];\r
-\r
-       if (bank ==  NULL)\r
-       {\r
-               return ERROR_FLASH_BANK_INVALID;\r
-       }\r
-\r
-       if (bank->driver != &at91sam7_old_flash)\r
-       {\r
-               command_print(cmd_ctx, "not an at91sam7_old flash bank '%s'", args[0]);\r
-               return ERROR_FLASH_BANK_INVALID;\r
-       }\r
-\r
-       if (strcmp(value, "set") == 0)\r
-       {\r
-               flashcmd = SGPB_old;\r
-       }\r
-       else if (strcmp(value, "clear") == 0)\r
-       {\r
-               flashcmd = CGPB_old;\r
-       }\r
-       else\r
-       {\r
-               return ERROR_COMMAND_SYNTAX_ERROR;\r
-       }\r
-\r
-       at91sam7_old_info = bank->driver_priv;\r
-\r
-       if (bank->target->state != TARGET_HALTED)\r
-       {\r
-               LOG_ERROR("target has to be halted to perform flash operation");\r
-               return ERROR_TARGET_NOT_HALTED;\r
-       }\r
-       \r
-       if (at91sam7_old_info->cidr == 0)\r
-       {\r
-               retval = at91sam7_old_read_part_info(bank);\r
-               if (retval != ERROR_OK) {\r
-                       return retval;\r
-               }\r
-       }\r
-\r
-       if ((bit<0) || (at91sam7_old_info->num_nvmbits <= bit))\r
-       { \r
-               command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_old_info->target_name);\r
-               return ERROR_OK;\r
-       }\r
-\r
-       /* Configure the flash controller timing */\r
-       at91sam7_old_read_clock_info(bank);     \r
-       at91sam7_old_set_flash_mode(bank, 0, FMR_TIMING_NVBITS_old);\r
-       \r
-       if (at91sam7_old_flash_command(bank, 0, flashcmd, (u16)(bit)) != ERROR_OK) \r
-       {\r
-               return ERROR_FLASH_OPERATION_FAILED;\r
-       }       \r
-\r
-       status = at91sam7_old_get_flash_status(bank, 0);\r
-       LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status);\r
-       at91sam7_old_info->nvmbits = (status>>8)&((1<<at91sam7_old_info->num_nvmbits)-1);\r
-\r
-       return ERROR_OK;\r
-}\r
+/***************************************************************************
+ *   Copyright (C) 2006 by Magnus Lundin                                   *
+ *   lundin@mlu.mine.nu                                                    *
+ *                                                                         *
+ *   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.             *
+ ***************************************************************************/
+
+/***************************************************************************
+There are some things to notice
+
+* AT91SAM7S64 is tested
+* All AT91SAM7Sxx  and  AT91SAM7Xxx should work but is not tested
+* All parameters are identified from onchip configuartion registers 
+*
+* The flash controller handles erases automatically on a page (128/265 byte) basis
+* Only an EraseAll command is supported by the controller
+* Partial erases can be implemented in software by writing one 0xFFFFFFFF word to 
+* some location in every page in the region to be erased
+*  
+* Lock regions (sectors) are 32 or 64 pages
+*
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
+
+#include "at91sam7_old.h"
+
+#include "flash.h"
+#include "target.h"
+#include "log.h"
+#include "binarybuffer.h"
+#include "types.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int at91sam7_old_register_commands(struct command_context_s *cmd_ctx);
+int at91sam7_old_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
+int at91sam7_old_erase(struct flash_bank_s *bank, int first, int last);
+int at91sam7_old_protect(struct flash_bank_s *bank, int set, int first, int last);
+int at91sam7_old_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
+int at91sam7_old_probe(struct flash_bank_s *bank);
+int at91sam7_old_auto_probe(struct flash_bank_s *bank);
+int at91sam7_old_erase_check(struct flash_bank_s *bank);
+int at91sam7_old_protect_check(struct flash_bank_s *bank);
+int at91sam7_old_info(struct flash_bank_s *bank, char *buf, int buf_size);
+
+u32 at91sam7_old_get_flash_status(flash_bank_t *bank, u8 flashplane);
+void at91sam7_old_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode);
+u32 at91sam7_old_wait_status_busy(flash_bank_t *bank, u8 flashplane, u32 waitbits, int timeout);
+int at91sam7_old_flash_command(struct flash_bank_s *bank, u8 flashplane, u8 cmd, u16 pagen); 
+int at91sam7_old_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
+flash_driver_t at91sam7_old_flash =
+{
+       .name = "at91sam7",
+       .register_commands = at91sam7_old_register_commands,
+       .flash_bank_command = at91sam7_old_flash_bank_command,
+       .erase = at91sam7_old_erase,
+       .protect = at91sam7_old_protect,
+       .write = at91sam7_old_write,
+       .probe = at91sam7_old_probe,
+       .auto_probe = at91sam7_old_probe,
+       .erase_check = at91sam7_old_erase_check,
+       .protect_check = at91sam7_old_protect_check,
+       .info = at91sam7_old_info
+};
+
+u32 MC_FMR_old[4] =    { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
+u32 MC_FCR_old[4] =    { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
+u32 MC_FSR_old[4] =    { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
+
+char * EPROC_old[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
+long NVPSIZ_old[16] = {
+   0,
+   0x2000, /*  8K */
+   0x4000, /* 16K */ 
+   0x8000, /* 32K */
+   -1,
+   0x10000, /* 64K */
+   -1,
+   0x20000, /* 128K */
+   -1,
+   0x40000, /* 256K */
+   0x80000, /* 512K */
+   -1,
+   0x100000, /* 1024K */
+   -1,
+   0x200000, /* 2048K */
+   -1
+};
+
+long SRAMSIZ_old[16] = {
+   -1,
+   0x0400, /*  1K */
+   0x0800, /*  2K */ 
+   -1, 
+   0x1c000,  /* 112K */
+   0x1000,  /*   4K */
+   0x14000, /*  80K */
+   0x28000, /* 160K */
+   0x2000,  /*   8K */
+   0x4000,  /*  16K */
+   0x8000,  /*  32K */
+   0x10000, /*  64K */
+   0x20000, /* 128K */
+   0x40000, /* 256K */
+   0x18000, /* 96K */
+   0x80000, /* 512K */
+};
+
+int at91sam7_old_register_commands(struct command_context_s *cmd_ctx)
+{
+       command_t *at91sam7_old_cmd = register_command(cmd_ctx, NULL, "at91sam7", NULL, COMMAND_ANY, NULL);
+       register_command(cmd_ctx, at91sam7_old_cmd, "gpnvm", at91sam7_old_handle_gpnvm_command, COMMAND_EXEC,
+                       "at91sam7 gpnvm <num> <bit> set|clear, set or clear at91sam7 gpnvm bit");
+
+       return ERROR_OK;
+}
+
+u32 at91sam7_old_get_flash_status(flash_bank_t *bank, u8 flashplane)
+{
+       target_t *target = bank->target;
+       u32 fsr;
+       
+       target_read_u32(target, MC_FSR_old[flashplane], &fsr);
+       
+       return fsr;
+}
+
+/* Read clock configuration and set at91sam7_old_info->usec_clocks*/
+void at91sam7_old_read_clock_info(flash_bank_t *bank)
+{
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       target_t *target = bank->target;
+       u32 mckr, mcfr, pllr;
+       unsigned long tmp = 0, mainfreq;
+       int flashplane;
+
+       /* Read main clock freqency register */
+       target_read_u32(target, CKGR_MCFR_old, &mcfr);
+       /* Read master clock register */
+       target_read_u32(target, PMC_MCKR_old, &mckr);
+       /* Read Clock Generator PLL Register  */
+       target_read_u32(target, CKGR_PLLR_old, &pllr);
+
+       at91sam7_old_info->mck_valid = 0;
+       switch (mckr & PMC_MCKR_CSS_old) 
+       {
+               case 0:                 /* Slow Clock */
+                       at91sam7_old_info->mck_valid = 1;
+                       mainfreq = RC_FREQ_old / 16ul * (mcfr & 0xffff);
+                       tmp = mainfreq;
+                       break;
+               case 1:                 /* Main Clock */
+                       if (mcfr & CKGR_MCFR_MAINRDY_old) 
+                       {
+                               at91sam7_old_info->mck_valid = 1;
+                               mainfreq = RC_FREQ_old / 16ul * (mcfr & 0xffff);
+                               tmp = mainfreq;
+                       }
+                       break;
+
+               case 2:                 /* Reserved */
+                       break;
+               case 3:                 /* PLL Clock */
+                       if (mcfr & CKGR_MCFR_MAINRDY_old) 
+                       {
+                               target_read_u32(target, CKGR_PLLR_old, &pllr);
+                               if (!(pllr & CKGR_PLLR_DIV_old))
+                                       break; /* 0 Hz */
+                               at91sam7_old_info->mck_valid = 1;
+                               mainfreq = RC_FREQ_old / 16ul * (mcfr & 0xffff);
+                               /* Integer arithmetic should have sufficient precision
+                                  as long as PLL is properly configured. */
+                               tmp = mainfreq / (pllr & CKGR_PLLR_DIV_old) *
+                                 (((pllr & CKGR_PLLR_MUL_old) >> 16) + 1);
+                       }
+                       break;
+       }
+       
+       /* Prescaler adjust */
+       if (((mckr & PMC_MCKR_PRES_old) >> 2) == 7)
+               at91sam7_old_info->mck_valid = 0;
+       else
+               at91sam7_old_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES_old) >> 2);
+
+       /* Forget old flash timing */
+       for (flashplane = 0; flashplane<at91sam7_old_info->num_planes; flashplane++)
+       {
+               at91sam7_old_set_flash_mode(bank, flashplane, FMR_TIMING_NONE_old);
+       }
+}
+
+/* Setup the timimg registers for nvbits or normal flash */
+void at91sam7_old_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode)
+{
+       u32 fmr, fmcn = 0, fws = 0;
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       target_t *target = bank->target;
+       
+       if (mode && (mode != at91sam7_old_info->flashmode[flashplane]))
+       {
+               /* Always round up (ceil) */
+               if (mode==FMR_TIMING_NVBITS_old)
+               {
+                       if (at91sam7_old_info->cidr_arch == 0x60)
+                       {
+                               /* AT91SAM7A3 uses master clocks in 100 ns */
+                               fmcn = (at91sam7_old_info->mck_freq/10000000ul)+1;
+                       }
+                       else
+                       {
+                               /* master clocks in 1uS for ARCH 0x7 types */
+                               fmcn = (at91sam7_old_info->mck_freq/1000000ul)+1;
+                       }
+               }
+               else if (mode==FMR_TIMING_FLASH_old)
+                       /* main clocks in 1.5uS */
+                       fmcn = (at91sam7_old_info->mck_freq/666666ul)+1;
+
+               /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
+               if (at91sam7_old_info->mck_freq <= 33333ul)
+                       fmcn = 0;
+               /* Only allow fws=0 if clock frequency is < 30 MHz. */
+               if (at91sam7_old_info->mck_freq > 30000000ul)
+                       fws = 1;
+
+               LOG_DEBUG("fmcn[%i]: %i", flashplane, fmcn); 
+               fmr = fmcn << 16 | fws << 8;
+               target_write_u32(target, MC_FMR_old[flashplane], fmr);
+       }
+       
+       at91sam7_old_info->flashmode[flashplane] = mode;                
+}
+
+u32 at91sam7_old_wait_status_busy(flash_bank_t *bank, u8 flashplane, u32 waitbits, int timeout)
+{
+       u32 status;
+       
+       while ((!((status = at91sam7_old_get_flash_status(bank,flashplane)) & waitbits)) && (timeout-- > 0))
+       {
+               LOG_DEBUG("status[%i]: 0x%x", flashplane, status);
+               alive_sleep(1);
+       }
+       
+       LOG_DEBUG("status[%i]: 0x%x", flashplane, status);
+
+       if (status & 0x0C)
+       {
+               LOG_ERROR("status register: 0x%x", status);
+               if (status & 0x4)
+                       LOG_ERROR("Lock Error Bit Detected, Operation Abort");
+               if (status & 0x8)
+                       LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
+               if (status & 0x10)
+                       LOG_ERROR("Security Bit Set, Operation Abort");
+       }
+       
+       return status;
+}
+
+
+/* Send one command to the AT91SAM flash controller */
+int at91sam7_old_flash_command(struct flash_bank_s *bank, u8 flashplane, u8 cmd, u16 pagen) 
+{
+       u32 fcr;
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       target_t *target = bank->target;
+
+       fcr = (0x5A<<24) | ((pagen&0x3FF)<<8) | cmd; 
+       target_write_u32(target, MC_FCR_old[flashplane], fcr);
+       LOG_DEBUG("Flash command: 0x%x, flashplane: %i, pagenumber:%u", fcr, flashplane, pagen);
+
+       if ((at91sam7_old_info->cidr_arch == 0x60)&&((cmd==SLB_old)|(cmd==CLB_old)))
+       {
+               /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
+               if (at91sam7_old_wait_status_busy(bank, flashplane, MC_FSR_EOL_old, 10)&0x0C) 
+               {
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }
+               return ERROR_OK;
+       }
+
+       if (at91sam7_old_wait_status_busy(bank, flashplane, MC_FSR_FRDY_old, 10)&0x0C) 
+       {
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+       return ERROR_OK;
+}
+
+/* Read device id register, main clock frequency register and fill in driver info structure */
+int at91sam7_old_read_part_info(struct flash_bank_s *bank)
+{
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       target_t *target = bank->target;
+       u32 cidr, status;
+       int sectornum;
+
+       if (at91sam7_old_info->cidr != 0)
+               return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */
+       
+       /* Read and parse chip identification register */
+       target_read_u32(target, DBGU_CIDR_old, &cidr);
+       
+       if (cidr == 0)
+       {
+               LOG_WARNING("Cannot identify target as an AT91SAM");
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+       
+       at91sam7_old_info->cidr = cidr;
+       at91sam7_old_info->cidr_ext = (cidr>>31)&0x0001;
+       at91sam7_old_info->cidr_nvptyp = (cidr>>28)&0x0007;
+       at91sam7_old_info->cidr_arch = (cidr>>20)&0x00FF;
+       at91sam7_old_info->cidr_sramsiz = (cidr>>16)&0x000F;
+       at91sam7_old_info->cidr_nvpsiz2 = (cidr>>12)&0x000F;
+       at91sam7_old_info->cidr_nvpsiz = (cidr>>8)&0x000F;
+       at91sam7_old_info->cidr_eproc = (cidr>>5)&0x0007;
+       at91sam7_old_info->cidr_version = cidr&0x001F;
+       bank->size = NVPSIZ_old[at91sam7_old_info->cidr_nvpsiz];
+       at91sam7_old_info->target_name = "Unknown";
+
+       /* Support just for bulk erase of a single flash plane, whole device if flash size <= 256k */
+       if (NVPSIZ_old[at91sam7_old_info->cidr_nvpsiz]<0x80000)  /* Flash size less than 512K, one flash plane */
+       {
+               bank->num_sectors = 1;
+               bank->sectors = malloc(sizeof(flash_sector_t));
+               bank->sectors[0].offset = 0;
+               bank->sectors[0].size = bank->size;
+               bank->sectors[0].is_erased = -1;
+               bank->sectors[0].is_protected = -1;
+       }
+       else    /* Flash size 512K or larger, several flash planes */
+       {
+               bank->num_sectors = NVPSIZ_old[at91sam7_old_info->cidr_nvpsiz]/0x40000;
+               bank->sectors = malloc(bank->num_sectors*sizeof(flash_sector_t));
+               for (sectornum=0; sectornum<bank->num_sectors; sectornum++)
+               {
+                       bank->sectors[sectornum].offset = sectornum*0x40000;
+                       bank->sectors[sectornum].size = 0x40000;
+                       bank->sectors[sectornum].is_erased = -1;
+                       bank->sectors[sectornum].is_protected = -1;
+               }
+       }
+               
+       
+
+       LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_old_info->cidr_nvptyp, at91sam7_old_info->cidr_arch );
+
+       /* Read main and master clock freqency register */
+       at91sam7_old_read_clock_info(bank);
+       
+       at91sam7_old_info->num_planes = 1;
+       status = at91sam7_old_get_flash_status(bank, 0);
+       at91sam7_old_info->securitybit = (status>>4)&0x01;
+       at91sam7_old_protect_check(bank);   /* TODO Check the protect check */
+       
+       if (at91sam7_old_info->cidr_arch == 0x70 )
+       {
+               at91sam7_old_info->num_nvmbits = 2;
+               at91sam7_old_info->nvmbits = (status>>8)&0x03;
+               bank->base = 0x100000;
+               bank->bus_width = 4;
+               if (bank->size==0x80000)  /* AT91SAM7S512 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7S512";
+                       at91sam7_old_info->num_planes = 2;
+                       if (at91sam7_old_info->num_planes != bank->num_sectors)
+                               LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
+                       at91sam7_old_info->num_lockbits = 2*16;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 2*16*64;
+               }
+               if (bank->size==0x40000)  /* AT91SAM7S256 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7S256";
+                       at91sam7_old_info->num_lockbits = 16;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 16*64;
+               }
+               if (bank->size==0x20000)  /* AT91SAM7S128 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7S128";
+                       at91sam7_old_info->num_lockbits = 8;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 8*64;
+               }
+               if (bank->size==0x10000)  /* AT91SAM7S64 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7S64";
+                       at91sam7_old_info->num_lockbits = 16;
+                       at91sam7_old_info->pagesize = 128;
+                       at91sam7_old_info->pages_in_lockregion = 32;
+                       at91sam7_old_info->num_pages = 16*32;
+               }
+               if (bank->size==0x08000)  /* AT91SAM7S321/32 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7S321/32";
+                       at91sam7_old_info->num_lockbits = 8;
+                       at91sam7_old_info->pagesize = 128;
+                       at91sam7_old_info->pages_in_lockregion = 32;
+                       at91sam7_old_info->num_pages = 8*32;
+               }
+               
+               return ERROR_OK;
+       }
+
+       if (at91sam7_old_info->cidr_arch == 0x71 )
+       {
+               at91sam7_old_info->num_nvmbits = 3;
+               at91sam7_old_info->nvmbits = (status>>8)&0x07;
+               bank->base = 0x100000;
+               bank->bus_width = 4;
+               if (bank->size==0x80000)  /* AT91SAM7XC512 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7XC512";
+                       at91sam7_old_info->num_planes = 2;
+                       if (at91sam7_old_info->num_planes != bank->num_sectors)
+                               LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
+                       at91sam7_old_info->num_lockbits = 2*16;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 2*16*64;
+               }
+               if (bank->size==0x40000)  /* AT91SAM7XC256 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7XC256";
+                       at91sam7_old_info->num_lockbits = 16;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 16*64;
+               }
+               if (bank->size==0x20000)  /* AT91SAM7XC128 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7XC128";
+                       at91sam7_old_info->num_lockbits = 8;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 8*64;
+               }
+               
+               return ERROR_OK;
+       }
+       
+       if (at91sam7_old_info->cidr_arch == 0x72 )
+       {
+               at91sam7_old_info->num_nvmbits = 3;
+               at91sam7_old_info->nvmbits = (status>>8)&0x07;
+               bank->base = 0x100000;
+               bank->bus_width = 4;
+               if (bank->size==0x80000) /* AT91SAM7SE512 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7SE512";
+                       at91sam7_old_info->num_planes = 2;
+                       if (at91sam7_old_info->num_planes != bank->num_sectors)
+                               LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
+                       at91sam7_old_info->num_lockbits = 32;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 32*64;
+               }
+               if (bank->size==0x40000)
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7SE256";
+                       at91sam7_old_info->num_lockbits = 16;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 16*64;
+               }
+               if (bank->size==0x08000)
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7SE32";
+                       at91sam7_old_info->num_lockbits = 8;
+                       at91sam7_old_info->pagesize = 128;
+                       at91sam7_old_info->pages_in_lockregion = 32;
+                       at91sam7_old_info->num_pages = 8*32;
+               }
+               
+               return ERROR_OK;
+       }
+       
+       if (at91sam7_old_info->cidr_arch == 0x75 )
+       {
+               at91sam7_old_info->num_nvmbits = 3;
+               at91sam7_old_info->nvmbits = (status>>8)&0x07;
+               bank->base = 0x100000;
+               bank->bus_width = 4;
+               if (bank->size==0x80000)  /* AT91SAM7X512 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7X512";
+                       at91sam7_old_info->num_planes = 2;
+                       if (at91sam7_old_info->num_planes != bank->num_sectors)
+                               LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");;
+                       at91sam7_old_info->num_lockbits = 32;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 2*16*64;
+                       LOG_DEBUG("Support for AT91SAM7X512 is experimental in this version!");
+               }
+               if (bank->size==0x40000)  /* AT91SAM7X256 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7X256";
+                       at91sam7_old_info->num_lockbits = 16;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 16*64;
+               }
+               if (bank->size==0x20000)  /* AT91SAM7X128 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7X128";
+                       at91sam7_old_info->num_lockbits = 8;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 64;
+                       at91sam7_old_info->num_pages = 8*64;
+               }
+       
+               return ERROR_OK;
+       }
+       
+       if (at91sam7_old_info->cidr_arch == 0x60 )
+       {
+               at91sam7_old_info->num_nvmbits = 3;
+               at91sam7_old_info->nvmbits = (status>>8)&0x07;
+               bank->base = 0x100000;
+               bank->bus_width = 4;
+               
+               if (bank->size == 0x40000)  /* AT91SAM7A3 */
+               {
+                       at91sam7_old_info->target_name = "AT91SAM7A3";
+                       at91sam7_old_info->num_lockbits = 16;
+                       at91sam7_old_info->pagesize = 256;
+                       at91sam7_old_info->pages_in_lockregion = 16;
+                       at91sam7_old_info->num_pages = 16*64;
+               }
+               return ERROR_OK;
+       }
+       
+       LOG_WARNING("at91sam7_old flash only tested for AT91SAM7Sxx series");
+       return ERROR_OK;
+}
+
+int at91sam7_old_erase_check(struct flash_bank_s *bank)
+{
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       
+       if (!at91sam7_old_info->working_area_size)
+       {
+       }
+       else
+       {       
+       }
+       
+       return ERROR_OK;
+}
+
+int at91sam7_old_protect_check(struct flash_bank_s *bank)
+{
+       u32 status;
+       int flashplane;
+       
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+
+       if (at91sam7_old_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       for (flashplane=0;flashplane<at91sam7_old_info->num_planes;flashplane++)
+       {
+               status = at91sam7_old_get_flash_status(bank, flashplane);
+               at91sam7_old_info->lockbits[flashplane] = (status >> 16);
+       }
+       
+       return ERROR_OK;
+}
+
+/* flash_bank at91sam7_old 0 0 0 0 <target#>
+ */
+int at91sam7_old_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
+{
+       at91sam7_old_flash_bank_t *at91sam7_old_info;
+       int i;
+       
+       if (argc < 6)
+       {
+               LOG_WARNING("incomplete flash_bank at91sam7_old configuration");
+               return ERROR_FLASH_BANK_INVALID;
+       }
+       
+       at91sam7_old_info = malloc(sizeof(at91sam7_old_flash_bank_t));
+       bank->driver_priv = at91sam7_old_info;
+       
+       /* part wasn't probed for info yet */
+       at91sam7_old_info->cidr = 0;
+       for (i=0;i<4;i++)
+               at91sam7_old_info->flashmode[i]=0;
+       
+       return ERROR_OK;
+}
+
+int at91sam7_old_erase(struct flash_bank_s *bank, int first, int last)
+{
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       u8 flashplane;
+
+       if (at91sam7_old_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+       
+       if ((first < 0) || (last < first) || (last >= bank->num_sectors))
+       {
+               if ((first == 0) && (last == (at91sam7_old_info->num_lockbits-1)))
+               {
+                       LOG_WARNING("Sector numbers based on lockbit count, probably a deprecated script");
+                       last = bank->num_sectors-1;
+               }
+               else return ERROR_FLASH_SECTOR_INVALID;
+       }
+
+       /* Configure the flash controller timing */
+       at91sam7_old_read_clock_info(bank);     
+       for (flashplane = first; flashplane<=last; flashplane++)
+       {
+               /* Configure the flash controller timing */
+               at91sam7_old_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH_old);
+               if (at91sam7_old_flash_command(bank, flashplane, EA_old, 0) != ERROR_OK) 
+               {
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }       
+       }
+       return ERROR_OK;
+
+}
+
+int at91sam7_old_protect(struct flash_bank_s *bank, int set, int first, int last)
+{
+       u32 cmd, pagen;
+       u8 flashplane;
+       int lockregion;
+       
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       
+       if (at91sam7_old_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+       
+       if ((first < 0) || (last < first) || (last >= at91sam7_old_info->num_lockbits))
+       {
+               return ERROR_FLASH_SECTOR_INVALID;
+       }
+       
+       at91sam7_old_read_clock_info(bank);     
+       
+       for (lockregion=first;lockregion<=last;lockregion++) 
+       {
+               pagen = lockregion*at91sam7_old_info->pages_in_lockregion;
+               flashplane = (pagen>>10)&0x03;
+               /* Configure the flash controller timing */
+               at91sam7_old_set_flash_mode(bank, flashplane, FMR_TIMING_NVBITS_old);
+               
+               if (set)
+                        cmd = SLB_old; 
+               else
+                        cmd = CLB_old;                 
+
+               if (at91sam7_old_flash_command(bank, flashplane, cmd, pagen) != ERROR_OK) 
+               {
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }       
+       }
+       
+       at91sam7_old_protect_check(bank);
+               
+       return ERROR_OK;
+}
+
+
+int at91sam7_old_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
+{
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       target_t *target = bank->target;
+       u32 dst_min_alignment, wcount, bytes_remaining = count;
+       u32 first_page, last_page, pagen, buffer_pos;
+       u8 flashplane;
+       
+       if (at91sam7_old_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       if (offset + count > bank->size)
+               return ERROR_FLASH_DST_OUT_OF_BANK;
+       
+       dst_min_alignment = at91sam7_old_info->pagesize;
+
+       if (offset % dst_min_alignment)
+       {
+               LOG_WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment);
+               return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+       }
+       
+       if (at91sam7_old_info->cidr_arch == 0)
+               return ERROR_FLASH_BANK_NOT_PROBED;
+
+       first_page = offset/dst_min_alignment;
+       last_page = CEIL(offset + count, dst_min_alignment);
+       
+       LOG_DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count);
+       
+       at91sam7_old_read_clock_info(bank);     
+
+       for (pagen=first_page; pagen<last_page; pagen++) 
+       {
+               if (bytes_remaining<dst_min_alignment)
+                       count = bytes_remaining;
+               else
+                       count = dst_min_alignment;
+               bytes_remaining -= count;
+               
+               /* Write one block to the PageWriteBuffer */
+               buffer_pos = (pagen-first_page)*dst_min_alignment;
+               wcount = CEIL(count,4);
+               target->type->write_memory(target, bank->base+pagen*dst_min_alignment, 4, wcount, buffer+buffer_pos);
+               flashplane = (pagen>>10)&0x3;
+               
+               /* Configure the flash controller timing */     
+               at91sam7_old_set_flash_mode(bank, flashplane, FMR_TIMING_FLASH_old);
+               /* Send Write Page command to Flash Controller */
+               if (at91sam7_old_flash_command(bank, flashplane, WP_old, pagen) != ERROR_OK) 
+               {
+                               return ERROR_FLASH_OPERATION_FAILED;
+               }
+               LOG_DEBUG("Write flash plane:%i page number:%i", flashplane, pagen);
+       }
+       
+       return ERROR_OK;
+}
+
+
+int at91sam7_old_probe(struct flash_bank_s *bank)
+{
+       /* we can't probe on an at91sam7_old
+        * if this is an at91sam7_old, it has the configured flash
+        */
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       int retval;
+       
+       if (at91sam7_old_info->cidr != 0)
+       {
+               return ERROR_OK; /* already probed */
+       }
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       retval = at91sam7_old_read_part_info(bank);
+       if (retval != ERROR_OK)
+               return retval;
+       
+       return ERROR_OK;
+}
+
+
+int at91sam7_old_info(struct flash_bank_s *bank, char *buf, int buf_size)
+{
+       int printed, flashplane;
+       at91sam7_old_flash_bank_t *at91sam7_old_info = bank->driver_priv;
+       
+       if (at91sam7_old_info->cidr == 0)
+       {
+               return ERROR_FLASH_BANK_NOT_PROBED;
+       }
+       
+       printed = snprintf(buf, buf_size, "\nat91sam7_old information: Chip is %s\n",at91sam7_old_info->target_name);
+       buf += printed;
+       buf_size -= printed;
+       
+       printed = snprintf(buf, buf_size, "cidr: 0x%8.8x, arch: 0x%4.4x, eproc: %s, version:0x%3.3x,  flashsize: 0x%8.8x\n",
+                 at91sam7_old_info->cidr, at91sam7_old_info->cidr_arch, EPROC_old[at91sam7_old_info->cidr_eproc], at91sam7_old_info->cidr_version, bank->size);
+       buf += printed;
+       buf_size -= printed;
+                       
+       printed = snprintf(buf, buf_size, "master clock(estimated): %ikHz \n", at91sam7_old_info->mck_freq / 1000);
+       buf += printed;
+       buf_size -= printed;
+       
+       if (at91sam7_old_info->num_planes>1) {          
+               printed = snprintf(buf, buf_size, "flashplanes: %i, pagesize: %i, lock regions: %i, pages in lock region: %i \n", 
+                          at91sam7_old_info->num_planes, at91sam7_old_info->pagesize, at91sam7_old_info->num_lockbits, at91sam7_old_info->num_pages/at91sam7_old_info->num_lockbits);
+               buf += printed;
+               buf_size -= printed;
+               for (flashplane=0; flashplane<at91sam7_old_info->num_planes; flashplane++)
+               {
+                       printed = snprintf(buf, buf_size, "lockbits[%i]: 0x%4.4x,  ", flashplane, at91sam7_old_info->lockbits[flashplane]);
+                       buf += printed;
+                       buf_size -= printed;
+               }
+       }
+       else
+       if (at91sam7_old_info->num_lockbits>0) {                
+               printed = snprintf(buf, buf_size, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n", 
+                          at91sam7_old_info->pagesize, at91sam7_old_info->num_lockbits, at91sam7_old_info->lockbits[0], at91sam7_old_info->num_pages/at91sam7_old_info->num_lockbits);
+               buf += printed;
+               buf_size -= printed;
+       }
+                       
+       printed = snprintf(buf, buf_size, "securitybit: %i,  nvmbits(%i): 0x%1.1x\n", at91sam7_old_info->securitybit, at91sam7_old_info->num_nvmbits, at91sam7_old_info->nvmbits);
+       buf += printed;
+       buf_size -= printed;
+
+       return ERROR_OK;
+}
+
+/* 
+* On AT91SAM7S: When the gpnvm bits are set with 
+* > at91sam7_old gpnvm 0 bitnr set
+* the changes are not visible in the flash controller status register MC_FSR_old 
+* until the processor has been reset.
+* On the Olimex board this requires a power cycle.
+* Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
+*      The maximum number of write/erase cycles for Non Volatile Memory bits is 100. This includes
+*      Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
+*/
+int at91sam7_old_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       int bit;
+       u8  flashcmd;
+       u32 status;
+       char *value;
+       at91sam7_old_flash_bank_t *at91sam7_old_info;
+       int retval;
+
+       if (argc < 3)
+       {
+               command_print(cmd_ctx, "at91sam7_old gpnvm <num> <bit> <set|clear>");
+               return ERROR_OK;
+       }
+       
+       bank = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
+       bit = atoi(args[1]);
+       value = args[2];
+
+       if (bank ==  NULL)
+       {
+               return ERROR_FLASH_BANK_INVALID;
+       }
+
+       if (bank->driver != &at91sam7_old_flash)
+       {
+               command_print(cmd_ctx, "not an at91sam7_old flash bank '%s'", args[0]);
+               return ERROR_FLASH_BANK_INVALID;
+       }
+
+       if (strcmp(value, "set") == 0)
+       {
+               flashcmd = SGPB_old;
+       }
+       else if (strcmp(value, "clear") == 0)
+       {
+               flashcmd = CGPB_old;
+       }
+       else
+       {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       at91sam7_old_info = bank->driver_priv;
+
+       if (bank->target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("target has to be halted to perform flash operation");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+       
+       if (at91sam7_old_info->cidr == 0)
+       {
+               retval = at91sam7_old_read_part_info(bank);
+               if (retval != ERROR_OK) {
+                       return retval;
+               }
+       }
+
+       if ((bit<0) || (at91sam7_old_info->num_nvmbits <= bit))
+       { 
+               command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_old_info->target_name);
+               return ERROR_OK;
+       }
+
+       /* Configure the flash controller timing */
+       at91sam7_old_read_clock_info(bank);     
+       at91sam7_old_set_flash_mode(bank, 0, FMR_TIMING_NVBITS_old);
+       
+       if (at91sam7_old_flash_command(bank, 0, flashcmd, (u16)(bit)) != ERROR_OK) 
+       {
+               return ERROR_FLASH_OPERATION_FAILED;
+       }       
+
+       status = at91sam7_old_get_flash_status(bank, 0);
+       LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status);
+       at91sam7_old_info->nvmbits = (status>>8)&((1<<at91sam7_old_info->num_nvmbits)-1);
+
+       return ERROR_OK;
+}
index 0850456542239a917dd62c79eb4cbc32695fa12d..75c881c2e35f91a130a8a400f541a7192e92b58b 100644 (file)
@@ -1,98 +1,98 @@
-/***************************************************************************\r
- *   Copyright (C) 2006 by Magnus Lundin                                   *\r
- *   lundin@mlu.mine.nu                                                    *\r
- *                                                                         *\r
- *   This program is free software; you can redistribute it and/or modify  *\r
- *   it under the terms of the GNU General Public License as published by  *\r
- *   the Free Software Foundation; either version 2 of the License, or     *\r
- *   (at your option) any later version.                                   *\r
- *                                                                         *\r
- *   This program is distributed in the hope that it will be useful,       *\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
- *   GNU General Public License for more details.                          *\r
- *                                                                         *\r
- *   You should have received a copy of the GNU General Public License     *\r
- *   along with this program; if not, write to the                         *\r
- *   Free Software Foundation, Inc.,                                       *\r
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
- ***************************************************************************/\r
-#ifndef AT91SAM7_OLD_H\r
-#define AT91SAM7_OLD_H\r
-\r
-#include "flash.h"\r
-#include "target.h"\r
-\r
-typedef struct at91sam7_old_flash_bank_s\r
-{\r
-       u32 working_area;\r
-       u32 working_area_size;\r
-\r
-       /* chip id register */\r
-       u32 cidr;\r
-       u16 cidr_ext;\r
-       u16 cidr_nvptyp;\r
-       u16 cidr_arch;\r
-       u16 cidr_sramsiz;\r
-       u16 cidr_nvpsiz;\r
-       u16 cidr_nvpsiz2;\r
-       u16 cidr_eproc;\r
-       u16 cidr_version;\r
-       char * target_name;\r
-\r
-       /* flash geometry */\r
-       u16 num_pages;\r
-       u16 pagesize;\r
-       u16 pages_in_lockregion;\r
-       u8 num_erase_regions;\r
-       u8 num_planes;\r
-       u32 *erase_region_info;\r
-\r
-       /* nv memory bits */\r
-       u16 num_lockbits;\r
-       u16 lockbits[4];\r
-       u16 num_nvmbits;\r
-       u16 nvmbits;\r
-       u8  securitybit;\r
-       u8  flashmode[4];         /* 0: not init, 1: fmcn for nvbits (1uS), 2: fmcn for flash (1.5uS) */\r
-\r
-       /* main clock status */\r
-       u8  mck_valid;\r
-       u32 mck_freq;\r
-\r
-} at91sam7_old_flash_bank_t;\r
-\r
-/* AT91SAM7 control registers */\r
-#define DBGU_CIDR_old 0xFFFFF240\r
-#define CKGR_MCFR_old 0xFFFFFC24\r
-#define CKGR_MCFR_MAINRDY_old  0x10000\r
-#define CKGR_PLLR_old 0xFFFFFC2c\r
-#define CKGR_PLLR_DIV_old 0xff\r
-#define CKGR_PLLR_MUL_old 0x07ff0000\r
-#define PMC_MCKR_old  0xFFFFFC30\r
-#define PMC_MCKR_CSS_old  0x03\r
-#define PMC_MCKR_PRES_old 0x1c\r
-\r
-/* Flash Controller Commands */\r
-#define  WP_old   0x01\r
-#define  SLB_old  0x02\r
-#define  WPL_old  0x03\r
-#define  CLB_old  0x04\r
-#define  EA_old   0x08\r
-#define  SGPB_old 0x0B\r
-#define  CGPB_old 0x0D\r
-#define  SSB_old  0x0F\r
-\r
-/* MC_FSR bit definitions */\r
-#define        MC_FSR_FRDY_old 1\r
-#define        MC_FSR_EOL_old 2\r
-\r
-/* AT91SAM7 constants */\r
-#define RC_FREQ_old  32000\r
-\r
-/*  FLASH_TIMING_MODES */\r
-#define  FMR_TIMING_NONE_old    0\r
-#define  FMR_TIMING_NVBITS_old  1\r
-#define  FMR_TIMING_FLASH_old   2\r
-\r
-#endif /* AT91SAM7_OLD_H */\r
+/***************************************************************************
+ *   Copyright (C) 2006 by Magnus Lundin                                   *
+ *   lundin@mlu.mine.nu                                                    *
+ *                                                                         *
+ *   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.             *
+ ***************************************************************************/
+#ifndef AT91SAM7_OLD_H
+#define AT91SAM7_OLD_H
+
+#include "flash.h"
+#include "target.h"
+
+typedef struct at91sam7_old_flash_bank_s
+{
+       u32 working_area;
+       u32 working_area_size;
+
+       /* chip id register */
+       u32 cidr;
+       u16 cidr_ext;
+       u16 cidr_nvptyp;
+       u16 cidr_arch;
+       u16 cidr_sramsiz;
+       u16 cidr_nvpsiz;
+       u16 cidr_nvpsiz2;
+       u16 cidr_eproc;
+       u16 cidr_version;
+       char * target_name;
+
+       /* flash geometry */
+       u16 num_pages;
+       u16 pagesize;
+       u16 pages_in_lockregion;
+       u8 num_erase_regions;
+       u8 num_planes;
+       u32 *erase_region_info;
+
+       /* nv memory bits */
+       u16 num_lockbits;
+       u16 lockbits[4];
+       u16 num_nvmbits;
+       u16 nvmbits;
+       u8  securitybit;
+       u8  flashmode[4];         /* 0: not init, 1: fmcn for nvbits (1uS), 2: fmcn for flash (1.5uS) */
+
+       /* main clock status */
+       u8  mck_valid;
+       u32 mck_freq;
+
+} at91sam7_old_flash_bank_t;
+
+/* AT91SAM7 control registers */
+#define DBGU_CIDR_old 0xFFFFF240
+#define CKGR_MCFR_old 0xFFFFFC24
+#define CKGR_MCFR_MAINRDY_old  0x10000
+#define CKGR_PLLR_old 0xFFFFFC2c
+#define CKGR_PLLR_DIV_old 0xff
+#define CKGR_PLLR_MUL_old 0x07ff0000
+#define PMC_MCKR_old  0xFFFFFC30
+#define PMC_MCKR_CSS_old  0x03
+#define PMC_MCKR_PRES_old 0x1c
+
+/* Flash Controller Commands */
+#define  WP_old   0x01
+#define  SLB_old  0x02
+#define  WPL_old  0x03
+#define  CLB_old  0x04
+#define  EA_old   0x08
+#define  SGPB_old 0x0B
+#define  CGPB_old 0x0D
+#define  SSB_old  0x0F
+
+/* MC_FSR bit definitions */
+#define        MC_FSR_FRDY_old 1
+#define        MC_FSR_EOL_old 2
+
+/* AT91SAM7 constants */
+#define RC_FREQ_old  32000
+
+/*  FLASH_TIMING_MODES */
+#define  FMR_TIMING_NONE_old    0
+#define  FMR_TIMING_NVBITS_old  1
+#define  FMR_TIMING_FLASH_old   2
+
+#endif /* AT91SAM7_OLD_H */
index b2ebe0b79a0491f787feca8c4b38e59f6e951db8..5f09c72dd7b8f57497f1ac579d063a2c3873eb53 100644 (file)
@@ -80,25 +80,23 @@ extern flash_driver_t lpc288x_flash;
 extern flash_driver_t ocl_flash;
 
 flash_driver_t *flash_drivers[] = {
-        &lpc2000_flash,
-        &cfi_flash,
-        &at91sam7_flash,
-        &at91sam7_old_flash,
-        &str7x_flash,
-        &str9x_flash,
-        &aduc702x_flash,
-        &stellaris_flash,
-        &str9xpec_flash,
-        &stm32x_flash,
-        &tms470_flash,
-        &ecosflash_flash,
-        &lpc288x_flash,
-        &ocl_flash,
-        NULL,
+       &lpc2000_flash,
+       &cfi_flash,
+       &at91sam7_flash,
+       &at91sam7_old_flash,
+       &str7x_flash,
+       &str9x_flash,
+       &aduc702x_flash,
+       &stellaris_flash,
+       &str9xpec_flash,
+       &stm32x_flash,
+       &tms470_flash,
+       &ecosflash_flash,
+       &lpc288x_flash,
+       &ocl_flash,
+       NULL,
 };
 
-
-
 flash_bank_t *flash_banks;
 static         command_t *flash_cmd;
 
index 4ccbc047eeeccec03371d772fca1f12b3cc28601..817c60628320c53eb42d319aaf51e04c1cae6e7b 100644 (file)
@@ -92,13 +92,13 @@ extern flash_bank_t *get_flash_bank_by_num(int num);
 extern flash_bank_t *get_flash_bank_by_num_noprobe(int num);
 extern flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr);
 
-#define    ERROR_FLASH_BANK_INVALID            (-900)
-#define    ERROR_FLASH_SECTOR_INVALID          (-901)
-#define    ERROR_FLASH_OPERATION_FAILED        (-902)
-#define    ERROR_FLASH_DST_OUT_OF_BANK         (-903)
-#define    ERROR_FLASH_DST_BREAKS_ALIGNMENT    (-904)
-#define    ERROR_FLASH_BUSY                    (-905)
-#define    ERROR_FLASH_SECTOR_NOT_ERASED       (-906)
-#define    ERROR_FLASH_BANK_NOT_PROBED         (-907)
+#define ERROR_FLASH_BANK_INVALID                       (-900)
+#define ERROR_FLASH_SECTOR_INVALID                     (-901)
+#define ERROR_FLASH_OPERATION_FAILED           (-902)
+#define ERROR_FLASH_DST_OUT_OF_BANK                    (-903)
+#define ERROR_FLASH_DST_BREAKS_ALIGNMENT       (-904)
+#define ERROR_FLASH_BUSY                                       (-905)
+#define ERROR_FLASH_SECTOR_NOT_ERASED          (-906)
+#define ERROR_FLASH_BANK_NOT_PROBED                    (-907)
 
 #endif /* FLASH_H */
index 8c10a9ffea1d3587ff943df12e69d7267276dede..5583032361c03c02c5f6dfd2b04d2e1234f290e2 100644 (file)
-/***************************************************************************\r
- *   Copyright (C) 2007-2008 by Ã˜yvind Harboe                              *\r
- *                                                                         *\r
- *   This program is free software; you can redistribute it and/or modify  *\r
- *   it under the terms of the GNU General Public License as published by  *\r
- *   the Free Software Foundation; either version 2 of the License, or     *\r
- *   (at your option) any later version.                                   *\r
- *                                                                         *\r
- *   This program is distributed in the hope that it will be useful,       *\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
- *   GNU General Public License for more details.                          *\r
- *                                                                         *\r
- *   You should have received a copy of the GNU General Public License     *\r
- *   along with this program; if not, write to the                         *\r
- *   Free Software Foundation, Inc.,                                       *\r
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
- ***************************************************************************/\r
-#ifdef HAVE_CONFIG_H\r
-#include "config.h"\r
-#endif\r
-\r
-\r
-#include "log.h"\r
-#include "jtag.h"\r
-#include "bitbang.h"\r
-#include "../target/embeddedice.h"\r
-\r
-\r
-#include <cyg/hal/hal_io.h>             // low level i/o\r
-#include <cyg/hal/var_io.h>             // common registers\r
-#include <cyg/hal/plf_io.h>             // platform registers\r
-#include <cyg/hal/hal_diag.h>\r
-\r
-#include <stdlib.h>\r
-\r
-\r
-extern int jtag_error;\r
-\r
-/* low level command set\r
- */\r
-int eCosBoard_read(void);\r
-static void eCosBoard_write(int tck, int tms, int tdi);\r
-void eCosBoard_reset(int trst, int srst);\r
-\r
-\r
-int eCosBoard_speed(int speed);\r
-int eCosBoard_register_commands(struct command_context_s *cmd_ctx);\r
-int eCosBoard_init(void);\r
-int eCosBoard_quit(void);\r
-\r
-/* interface commands */\r
-int eCosBoard_handle_eCosBoard_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
-\r
-static int eCosBoard_khz(int khz, int *jtag_speed)\r
-{\r
-       if (khz==0)\r
-       {\r
-               *jtag_speed=0;\r
-       }\r
-       else\r
-       {\r
-               *jtag_speed=64000/khz;\r
-       }\r
-       return ERROR_OK;\r
-}\r
-\r
-static int eCosBoard_speed_div(int speed, int *khz)\r
-{\r
-       if (speed==0)\r
-       {\r
-               *khz = 0;\r
-       }\r
-       else\r
-       {\r
-               *khz=64000/speed;\r
-       }\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-jtag_interface_t eCosBoard_interface =\r
-{\r
-       .name = "ZY1000",\r
-       .execute_queue = bitbang_execute_queue,\r
-       .speed = eCosBoard_speed,\r
-       .register_commands = eCosBoard_register_commands,\r
-       .init = eCosBoard_init,\r
-       .quit = eCosBoard_quit,\r
-       .khz = eCosBoard_khz,\r
-       .speed_div = eCosBoard_speed_div,\r
-};\r
-\r
-bitbang_interface_t eCosBoard_bitbang =\r
-{\r
-       .read = eCosBoard_read,\r
-       .write = eCosBoard_write,\r
-       .reset = eCosBoard_reset\r
-};\r
-\r
-\r
-\r
-static void eCosBoard_write(int tck, int tms, int tdi)\r
-{\r
-\r
-}\r
-\r
-int eCosBoard_read(void)\r
-{\r
-       return -1;\r
-}\r
-\r
-extern bool readSRST();\r
-\r
-void eCosBoard_reset(int trst, int srst)\r
-{\r
-       LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);\r
-       if(!srst)\r
-       {\r
-               ZY1000_POKE(0x08000014, 0x00000001);\r
-       }\r
-       else\r
-       {\r
-               /* Danger!!! if clk!=0 when in\r
-                * idle in TAP_RTI, reset halt on str912 will fail.\r
-                */\r
-               ZY1000_POKE(0x08000010, 0x00000001);\r
-       }\r
-\r
-       if(!trst)\r
-       {\r
-               ZY1000_POKE(0x08000014, 0x00000002);\r
-       }\r
-       else\r
-       {\r
-               /* assert reset */\r
-               ZY1000_POKE(0x08000010, 0x00000002);\r
-       }\r
-       \r
-       if (trst||(srst&&(jtag_reset_config & RESET_SRST_PULLS_TRST)))\r
-       {\r
-               waitIdle();\r
-               /* we're now in the TLR state until trst is deasserted */\r
-               ZY1000_POKE(0x08000020, TAP_TLR);\r
-       } else\r
-       {\r
-               /* We'll get RCLK failure when we assert TRST, so clear any false positives here */\r
-               ZY1000_POKE(0x08000014, 0x400);         \r
-       }\r
-\r
-       /* wait for srst to float back up */\r
-       if (!srst)\r
-       {\r
-               int i;\r
-               for (i=0; i<1000; i++)\r
-               {\r
-                       // We don't want to sense our own reset, so we clear here.\r
-                       // There is of course a timing hole where we could loose\r
-                       // a "real" reset.\r
-                       if (!readSRST())\r
-                               break;\r
-\r
-                       /* wait 1ms */\r
-                       alive_sleep(1);\r
-               }\r
-\r
-               if (i==1000)\r
-               {\r
-                       LOG_USER("SRST didn't deassert after %dms", i);\r
-               } else if (i>1)\r
-               {\r
-                       LOG_USER("SRST took %dms to deassert", i);\r
-               }\r
-       }\r
-}\r
-\r
-int eCosBoard_speed(int speed)\r
-{\r
-       if(speed == 0)\r
-       {\r
-               /*0 means RCLK*/\r
-               speed = 0;\r
-               ZY1000_POKE(0x08000010, 0x100);\r
-               LOG_DEBUG("jtag_speed using RCLK");\r
-       }\r
-       else\r
-       {\r
-               if(speed > 8190 || speed < 2)\r
-               {\r
-                       LOG_ERROR("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz");\r
-                       return ERROR_INVALID_ARGUMENTS;\r
-               }\r
-\r
-               LOG_USER("jtag_speed %d => JTAG clk=%f", speed, 64.0/(float)speed);\r
-               ZY1000_POKE(0x08000014, 0x100);\r
-               ZY1000_POKE(0x0800001c, speed&~1);\r
-       }\r
-       return ERROR_OK;\r
-}\r
-\r
-int eCosBoard_register_commands(struct command_context_s *cmd_ctx)\r
-{\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-int eCosBoard_init(void)\r
-{\r
-       ZY1000_POKE(0x08000010, 0x30); // Turn on LED1 & LED2\r
-\r
-        /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */\r
-       eCosBoard_reset(0, 0);\r
-       eCosBoard_speed(jtag_speed);\r
-\r
-       bitbang_interface = &eCosBoard_bitbang;\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-int eCosBoard_quit(void)\r
-{\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-\r
-/* loads a file and returns a pointer to it in memory. The file contains\r
- * a 0 byte(sentinel) after len bytes - the length of the file. */\r
-int loadFile(const char *fileName, void **data, int *len)\r
-{\r
-       FILE * pFile;\r
-       pFile = fopen (fileName,"rb");\r
-       if (pFile==NULL)\r
-       {\r
-               LOG_ERROR("Can't open %s\n", fileName);\r
-               return ERROR_JTAG_DEVICE_ERROR;\r
-       }\r
-    if (fseek (pFile, 0, SEEK_END)!=0)\r
-    {\r
-               LOG_ERROR("Can't open %s\n", fileName);\r
-               fclose(pFile);\r
-               return ERROR_JTAG_DEVICE_ERROR;\r
-    }\r
-    *len=ftell (pFile);\r
-    if (*len==-1)\r
-    {\r
-               LOG_ERROR("Can't open %s\n", fileName);\r
-               fclose(pFile);\r
-               return ERROR_JTAG_DEVICE_ERROR;\r
-    }\r
-\r
-    if (fseek (pFile, 0, SEEK_SET)!=0)\r
-    {\r
-               LOG_ERROR("Can't open %s\n", fileName);\r
-               fclose(pFile);\r
-               return ERROR_JTAG_DEVICE_ERROR;\r
-    }\r
-    *data=malloc(*len+1);\r
-    if (*data==NULL)\r
-    {\r
-               LOG_ERROR("Can't open %s\n", fileName);\r
-               fclose(pFile);\r
-               return ERROR_JTAG_DEVICE_ERROR;\r
-    }\r
-\r
-    if (fread(*data, 1, *len, pFile)!=*len)\r
-    {\r
-               fclose(pFile);\r
-       free(*data);\r
-               LOG_ERROR("Can't open %s\n", fileName);\r
-               return ERROR_JTAG_DEVICE_ERROR;\r
-    }\r
-    fclose (pFile);\r
-    *(((char *)(*data))+*len)=0; /* sentinel */\r
-\r
-    return ERROR_OK;\r
-\r
-\r
-\r
-}\r
-\r
-\r
-\r
-\r
-int interface_jtag_execute_queue(void)\r
-{\r
-       cyg_uint32 empty;\r
-\r
-       waitIdle();\r
-       ZY1000_PEEK(0x08000010, empty);\r
-       /* clear JTAG error register */\r
-       ZY1000_POKE(0x08000014, 0x400);\r
-\r
-       if ((empty&0x400)!=0)\r
-       {\r
-               LOG_WARNING("RCLK timeout");\r
-               /* the error is informative only as we don't want to break the firmware if there\r
-                * is a false positive.\r
-                */\r
-//             return ERROR_FAIL;\r
-       }\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-static cyg_uint32 getShiftValue()\r
-{\r
-       cyg_uint32 value;\r
-       waitIdle();\r
-       ZY1000_PEEK(0x0800000c, value);\r
-       VERBOSE(LOG_INFO("getShiftValue %08x", value));\r
-       return value;\r
-}\r
-#if 0\r
-static cyg_uint32 getShiftValueFlip()\r
-{\r
-       cyg_uint32 value;\r
-       waitIdle();\r
-       ZY1000_PEEK(0x08000018, value);\r
-       VERBOSE(LOG_INFO("getShiftValue %08x (flipped)", value));\r
-       return value;\r
-}\r
-#endif\r
-\r
-#if 0\r
-static void shiftValueInnerFlip(const enum tap_state state, const enum tap_state endState, int repeat, cyg_uint32 value)\r
-{\r
-       VERBOSE(LOG_INFO("shiftValueInner %s %s %d %08x (flipped)", tap_state_strings[state], tap_state_strings[endState], repeat, value));\r
-       cyg_uint32 a,b;\r
-       a=state;\r
-       b=endState;\r
-       ZY1000_POKE(0x0800000c, value);\r
-       ZY1000_POKE(0x08000008, (1<<15)|(repeat<<8)|(a<<4)|b);\r
-       VERBOSE(getShiftValueFlip());\r
-}\r
-#endif\r
-\r
-extern int jtag_check_value(u8 *captured, void *priv);\r
-\r
-static void gotoEndState()\r
-{\r
-       setCurrentState(cmd_queue_end_state);\r
-}\r
-\r
-static __inline void scanFields(int num_fields, scan_field_t *fields, enum tap_state shiftState, int pause)\r
-{\r
-       int i;\r
-       int j;\r
-       int k;\r
-\r
-       for (i = 0; i < num_fields; i++)\r
-       {\r
-               cyg_uint32 value;\r
-\r
-               static u8 *in_buff=NULL; /* pointer to buffer for scanned data */\r
-               static int in_buff_size=0;\r
-               u8 *inBuffer=NULL;\r
-\r
-\r
-               // figure out where to store the input data\r
-               int num_bits=fields[i].num_bits;\r
-               if (fields[i].in_value!=NULL)\r
-               {\r
-                       inBuffer=fields[i].in_value;\r
-               } else if (fields[i].in_handler!=NULL)\r
-               {\r
-                       if (in_buff_size*8<num_bits)\r
-                       {\r
-                               // we need more space\r
-                               if (in_buff!=NULL)\r
-                                       free(in_buff);\r
-                               in_buff=NULL;\r
-                               in_buff_size=(num_bits+7)/8;\r
-                               in_buff=malloc(in_buff_size);\r
-                               if (in_buff==NULL)\r
-                               {\r
-                                       LOG_ERROR("Out of memory");\r
-                                       jtag_error=ERROR_JTAG_QUEUE_FAILED;\r
-                                       return;\r
-                               }\r
-                       }\r
-                       inBuffer=in_buff;\r
-               }\r
-\r
-               // here we shuffle N bits out/in\r
-               j=0;\r
-               while (j<num_bits)\r
-               {\r
-                       enum tap_state pause_state;\r
-                       int l;\r
-                       k=num_bits-j;\r
-                       pause_state=(shiftState==TAP_SD)?TAP_SD:TAP_SI;\r
-                       if (k>32)\r
-                       {\r
-                               k=32;\r
-                               /* we have more to shift out */\r
-                       } else if (pause&&(i == num_fields-1))\r
-                       {\r
-                               /* this was the last to shift out this time */\r
-                               pause_state=(shiftState==TAP_SD)?TAP_PD:TAP_PI;\r
-                       }\r
-\r
-                       // we have (num_bits+7)/8 bytes of bits to toggle out.\r
-                       // bits are pushed out LSB to MSB\r
-                       value=0;\r
-                       if (fields[i].out_value!=NULL)\r
-                       {\r
-                               for (l=0; l<k; l+=8)\r
-                               {\r
-                                       value|=fields[i].out_value[(j+l)/8]<<l;\r
-                               }\r
-                       }\r
-                       /* mask away unused bits for easier debugging */\r
-                       value&=~(((u32)0xffffffff)<<k);\r
-\r
-                       shiftValueInner(shiftState, pause_state, k, value);\r
-\r
-                       if (inBuffer!=NULL)\r
-                       {\r
-                               // data in, LSB to MSB\r
-                               value=getShiftValue();\r
-                               // we're shifting in data to MSB, shift data to be aligned for returning the value\r
-                               value >>= 32-k;\r
-\r
-                               for (l=0; l<k; l+=8)\r
-                               {\r
-                                       inBuffer[(j+l)/8]=(value>>l)&0xff;\r
-                               }\r
-                       }\r
-                       j+=k;\r
-               }\r
-\r
-               if (fields[i].in_handler!=NULL)\r
-               {\r
-                       // invoke callback\r
-                       int r=fields[i].in_handler(inBuffer, fields[i].in_handler_priv, fields+i);\r
-                       if (r!=ERROR_OK)\r
-                       {\r
-                           /* this will cause jtag_execute_queue() to return an error */\r
-                               jtag_error=r;\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-int interface_jtag_add_end_state(enum tap_state state)\r
-{\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-int interface_jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)\r
-{\r
-\r
-       int i, j;\r
-       int scan_size = 0;\r
-       jtag_device_t *device;\r
-\r
-       for (i=0; i < jtag_num_devices; i++)\r
-       {\r
-               int pause=i==(jtag_num_devices-1);\r
-               int found = 0;\r
-               device = jtag_get_device(i);\r
-               scan_size = device->ir_length;\r
-\r
-               /* search the list */\r
-               for (j=0; j < num_fields; j++)\r
-               {\r
-                       if (i == fields[j].device)\r
-                       {\r
-                               found = 1;\r
-\r
-                               if ((jtag_verify_capture_ir)&&(fields[j].in_handler==NULL))\r
-                               {\r
-                                       jtag_set_check_value(fields+j, device->expected, device->expected_mask, NULL);\r
-                               } else if (jtag_verify_capture_ir)\r
-                               {\r
-                                       fields[j].in_check_value = device->expected;\r
-                                       fields[j].in_check_mask = device->expected_mask;\r
-                               }\r
-\r
-                               scanFields(1, fields+j, TAP_SI, pause);\r
-                               /* update device information */\r
-                               buf_cpy(fields[j].out_value, jtag_get_device(i)->cur_instr, scan_size);\r
-\r
-                               device->bypass = 0;\r
-                               break;\r
-                       }\r
-               }\r
-\r
-               if (!found)\r
-               {\r
-                       /* if a device isn't listed, set it to BYPASS */\r
-                       u8 ones[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};\r
-\r
-                       scan_field_t tmp;\r
-                       memset(&tmp, 0, sizeof(tmp));\r
-                       tmp.out_value = ones;\r
-                       tmp.num_bits = scan_size;\r
-                       scanFields(1, &tmp, TAP_SI, pause);\r
-                       /* update device information */\r
-                       buf_cpy(tmp.out_value, jtag_get_device(i)->cur_instr, scan_size);\r
-                       device->bypass = 1;\r
-               }\r
-       }\r
-       gotoEndState();\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-int interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)\r
-{\r
-       scanFields(num_fields, fields, TAP_SI, 1);\r
-       gotoEndState();\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-/*extern jtag_command_t **jtag_get_last_command_p(void);*/\r
-\r
-int interface_jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)\r
-{\r
-       int i, j;\r
-       for (i=0; i < jtag_num_devices; i++)\r
-       {\r
-               int found = 0;\r
-               int pause = (i==(jtag_num_devices-1));\r
-\r
-               for (j=0; j < num_fields; j++)\r
-               {\r
-                       if (i == fields[j].device)\r
-                       {\r
-                               found = 1;\r
-\r
-                               scanFields(1, fields+j, TAP_SD, pause);\r
-                       }\r
-               }\r
-               if (!found)\r
-               {\r
-#ifdef _DEBUG_JTAG_IO_\r
-                       /* if a device isn't listed, the BYPASS register should be selected */\r
-                       if (!jtag_get_device(i)->bypass)\r
-                       {\r
-                               LOG_ERROR("BUG: no scan data for a device not in BYPASS");\r
-                               exit(-1);\r
-                       }\r
-#endif\r
-\r
-                       scan_field_t tmp;\r
-                       /* program the scan field to 1 bit length, and ignore it's value */\r
-                       tmp.num_bits = 1;\r
-                       tmp.out_value = NULL;\r
-                       tmp.out_mask = NULL;\r
-                       tmp.in_value = NULL;\r
-                       tmp.in_check_value = NULL;\r
-                       tmp.in_check_mask = NULL;\r
-                       tmp.in_handler = NULL;\r
-                       tmp.in_handler_priv = NULL;\r
-\r
-                       scanFields(1, &tmp, TAP_SD, pause);\r
-               }\r
-               else\r
-               {\r
-#ifdef _DEBUG_JTAG_IO_\r
-                       /* if a device is listed, the BYPASS register must not be selected */\r
-                       if (jtag_get_device(i)->bypass)\r
-                       {\r
-                               LOG_WARNING("scan data for a device in BYPASS");\r
-                       }\r
-#endif\r
-               }\r
-       }\r
-       gotoEndState();\r
-       return ERROR_OK;\r
-}\r
-\r
-int interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)\r
-{\r
-       scanFields(num_fields, fields, TAP_SD, 1);\r
-       gotoEndState();\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-int interface_jtag_add_tlr()\r
-{\r
-       setCurrentState(TAP_TLR);\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-\r
-\r
-extern int jtag_nsrst_delay;\r
-extern int jtag_ntrst_delay;\r
-\r
-int interface_jtag_add_reset(int req_trst, int req_srst)\r
-{\r
-       eCosBoard_reset(req_trst, req_srst);\r
-       return ERROR_OK;\r
-}\r
-\r
-int interface_jtag_add_runtest(int num_cycles, enum tap_state state)\r
-{\r
-       /* num_cycles can be 0 */\r
-       setCurrentState(TAP_RTI);\r
-\r
-       /* execute num_cycles, 32 at the time. */\r
-       int i;\r
-       for (i=0; i<num_cycles; i+=32)\r
-       {\r
-               int num;\r
-               num=32;\r
-               if (num_cycles-i<num)\r
-               {\r
-                       num=num_cycles-i;\r
-               }\r
-               shiftValueInner(TAP_RTI, TAP_RTI, num, 0);\r
-       }\r
-\r
-#if !TEST_MANUAL()\r
-       /* finish in end_state */\r
-       setCurrentState(state);\r
-#else\r
-       enum tap_state t=TAP_RTI;\r
-       /* test manual drive code on any target */\r
-       int tms;\r
-       u8 tms_scan = TAP_MOVE(t, state);\r
-       \r
-       for (i = 0; i < 7; i++)\r
-       {\r
-               tms = (tms_scan >> i) & 1;\r
-               waitIdle();\r
-               ZY1000_POKE(0x08000028,  tms);\r
-       }\r
-       waitIdle();\r
-       ZY1000_POKE(0x08000020, state); \r
-#endif\r
-\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-int interface_jtag_add_sleep(u32 us)\r
-{\r
-       jtag_sleep(us);\r
-       return ERROR_OK;\r
-}\r
-\r
-int interface_jtag_add_pathmove(int num_states, enum tap_state *path)\r
-{\r
-       int state_count;\r
-       int tms = 0;\r
-\r
-       /*wait for the fifo to be empty*/\r
-       waitIdle();\r
-\r
-       state_count = 0;\r
-\r
-       enum tap_state cur_state=cmd_queue_cur_state;\r
-\r
-       while (num_states)\r
-       {\r
-               if (tap_transitions[cur_state].low == path[state_count])\r
-               {\r
-                       tms = 0;\r
-               }\r
-               else if (tap_transitions[cur_state].high == path[state_count])\r
-               {\r
-                       tms = 1;\r
-               }\r
-               else\r
-               {\r
-                       LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[path[state_count]]);\r
-                       exit(-1);\r
-               }\r
-\r
-               waitIdle();\r
-               ZY1000_POKE(0x08000028,  tms);\r
-\r
-               cur_state = path[state_count];\r
-               state_count++;\r
-               num_states--;\r
-       }\r
-\r
-       waitIdle();\r
-       ZY1000_POKE(0x08000020,  cur_state);\r
-       return ERROR_OK;\r
-}\r
-\r
-\r
-\r
-void embeddedice_write_dcc(int chain_pos, int reg_addr, u8 *buffer, int little, int count)\r
-{\r
-//     static int const reg_addr=0x5;\r
-       enum tap_state end_state=cmd_queue_end_state;\r
-       if (jtag_num_devices==1)\r
-       {\r
-               /* better performance via code duplication */\r
-               if (little)\r
-               {\r
-                       int i;\r
-                       for (i = 0; i < count; i++)\r
-                       {\r
-                               shiftValueInner(TAP_SD, TAP_SD, 32, fast_target_buffer_get_u32(buffer, 1));\r
-                               shiftValueInner(TAP_SD, end_state, 6, reg_addr|(1<<5));\r
-                               buffer+=4;\r
-                       }\r
-               } else\r
-               {\r
-                       int i;\r
-                       for (i = 0; i < count; i++)\r
-                       {\r
-                               shiftValueInner(TAP_SD, TAP_SD, 32, fast_target_buffer_get_u32(buffer, 0));\r
-                               shiftValueInner(TAP_SD, end_state, 6, reg_addr|(1<<5));\r
-                               buffer+=4;\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-               int i;\r
-               for (i = 0; i < count; i++)\r
-               {\r
-                       embeddedice_write_reg_inner(chain_pos, reg_addr, fast_target_buffer_get_u32(buffer, little));\r
-                       buffer += 4;\r
-               }\r
-       }\r
-}\r
-\r
+/***************************************************************************
+ *   Copyright (C) 2007-2008 by Ã˜yvind Harboe                              *
+ *                                                                         *
+ *   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.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "log.h"
+#include "jtag.h"
+#include "bitbang.h"
+#include "../target/embeddedice.h"
+
+
+#include <cyg/hal/hal_io.h>             // low level i/o
+#include <cyg/hal/var_io.h>             // common registers
+#include <cyg/hal/plf_io.h>             // platform registers
+#include <cyg/hal/hal_diag.h>
+
+#include <stdlib.h>
+
+
+extern int jtag_error;
+
+/* low level command set
+ */
+int eCosBoard_read(void);
+static void eCosBoard_write(int tck, int tms, int tdi);
+void eCosBoard_reset(int trst, int srst);
+
+
+int eCosBoard_speed(int speed);
+int eCosBoard_register_commands(struct command_context_s *cmd_ctx);
+int eCosBoard_init(void);
+int eCosBoard_quit(void);
+
+/* interface commands */
+int eCosBoard_handle_eCosBoard_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
+static int eCosBoard_khz(int khz, int *jtag_speed)
+{
+       if (khz==0)
+       {
+               *jtag_speed=0;
+       }
+       else
+       {
+               *jtag_speed=64000/khz;
+       }
+       return ERROR_OK;
+}
+
+static int eCosBoard_speed_div(int speed, int *khz)
+{
+       if (speed==0)
+       {
+               *khz = 0;
+       }
+       else
+       {
+               *khz=64000/speed;
+       }
+
+       return ERROR_OK;
+}
+
+
+jtag_interface_t eCosBoard_interface =
+{
+       .name = "ZY1000",
+       .execute_queue = bitbang_execute_queue,
+       .speed = eCosBoard_speed,
+       .register_commands = eCosBoard_register_commands,
+       .init = eCosBoard_init,
+       .quit = eCosBoard_quit,
+       .khz = eCosBoard_khz,
+       .speed_div = eCosBoard_speed_div,
+};
+
+bitbang_interface_t eCosBoard_bitbang =
+{
+       .read = eCosBoard_read,
+       .write = eCosBoard_write,
+       .reset = eCosBoard_reset
+};
+
+
+
+static void eCosBoard_write(int tck, int tms, int tdi)
+{
+
+}
+
+int eCosBoard_read(void)
+{
+       return -1;
+}
+
+extern bool readSRST();
+
+void eCosBoard_reset(int trst, int srst)
+{
+       LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
+       if(!srst)
+       {
+               ZY1000_POKE(0x08000014, 0x00000001);
+       }
+       else
+       {
+               /* Danger!!! if clk!=0 when in
+                * idle in TAP_RTI, reset halt on str912 will fail.
+                */
+               ZY1000_POKE(0x08000010, 0x00000001);
+       }
+
+       if(!trst)
+       {
+               ZY1000_POKE(0x08000014, 0x00000002);
+       }
+       else
+       {
+               /* assert reset */
+               ZY1000_POKE(0x08000010, 0x00000002);
+       }
+       
+       if (trst||(srst&&(jtag_reset_config & RESET_SRST_PULLS_TRST)))
+       {
+               waitIdle();
+               /* we're now in the TLR state until trst is deasserted */
+               ZY1000_POKE(0x08000020, TAP_TLR);
+       } else
+       {
+               /* We'll get RCLK failure when we assert TRST, so clear any false positives here */
+               ZY1000_POKE(0x08000014, 0x400);         
+       }
+
+       /* wait for srst to float back up */
+       if (!srst)
+       {
+               int i;
+               for (i=0; i<1000; i++)
+               {
+                       // We don't want to sense our own reset, so we clear here.
+                       // There is of course a timing hole where we could loose
+                       // a "real" reset.
+                       if (!readSRST())
+                               break;
+
+                       /* wait 1ms */
+                       alive_sleep(1);
+               }
+
+               if (i==1000)
+               {
+                       LOG_USER("SRST didn't deassert after %dms", i);
+               } else if (i>1)
+               {
+                       LOG_USER("SRST took %dms to deassert", i);
+               }
+       }
+}
+
+int eCosBoard_speed(int speed)
+{
+       if(speed == 0)
+       {
+               /*0 means RCLK*/
+               speed = 0;
+               ZY1000_POKE(0x08000010, 0x100);
+               LOG_DEBUG("jtag_speed using RCLK");
+       }
+       else
+       {
+               if(speed > 8190 || speed < 2)
+               {
+                       LOG_ERROR("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz");
+                       return ERROR_INVALID_ARGUMENTS;
+               }
+
+               LOG_USER("jtag_speed %d => JTAG clk=%f", speed, 64.0/(float)speed);
+               ZY1000_POKE(0x08000014, 0x100);
+               ZY1000_POKE(0x0800001c, speed&~1);
+       }
+       return ERROR_OK;
+}
+
+int eCosBoard_register_commands(struct command_context_s *cmd_ctx)
+{
+       return ERROR_OK;
+}
+
+
+int eCosBoard_init(void)
+{
+       ZY1000_POKE(0x08000010, 0x30); // Turn on LED1 & LED2
+
+        /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
+       eCosBoard_reset(0, 0);
+       eCosBoard_speed(jtag_speed);
+
+       bitbang_interface = &eCosBoard_bitbang;
+
+       return ERROR_OK;
+}
+
+int eCosBoard_quit(void)
+{
+
+       return ERROR_OK;
+}
+
+
+
+/* loads a file and returns a pointer to it in memory. The file contains
+ * a 0 byte(sentinel) after len bytes - the length of the file. */
+int loadFile(const char *fileName, void **data, int *len)
+{
+       FILE * pFile;
+       pFile = fopen (fileName,"rb");
+       if (pFile==NULL)
+       {
+               LOG_ERROR("Can't open %s\n", fileName);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+    if (fseek (pFile, 0, SEEK_END)!=0)
+    {
+               LOG_ERROR("Can't open %s\n", fileName);
+               fclose(pFile);
+               return ERROR_JTAG_DEVICE_ERROR;
+    }
+    *len=ftell (pFile);
+    if (*len==-1)
+    {
+               LOG_ERROR("Can't open %s\n", fileName);
+               fclose(pFile);
+               return ERROR_JTAG_DEVICE_ERROR;
+    }
+
+    if (fseek (pFile, 0, SEEK_SET)!=0)
+    {
+               LOG_ERROR("Can't open %s\n", fileName);
+               fclose(pFile);
+               return ERROR_JTAG_DEVICE_ERROR;
+    }
+    *data=malloc(*len+1);
+    if (*data==NULL)
+    {
+               LOG_ERROR("Can't open %s\n", fileName);
+               fclose(pFile);
+               return ERROR_JTAG_DEVICE_ERROR;
+    }
+
+    if (fread(*data, 1, *len, pFile)!=*len)
+    {
+               fclose(pFile);
+       free(*data);
+               LOG_ERROR("Can't open %s\n", fileName);
+               return ERROR_JTAG_DEVICE_ERROR;
+    }
+    fclose (pFile);
+    *(((char *)(*data))+*len)=0; /* sentinel */
+
+    return ERROR_OK;
+
+
+
+}
+
+
+
+
+int interface_jtag_execute_queue(void)
+{
+       cyg_uint32 empty;
+
+       waitIdle();
+       ZY1000_PEEK(0x08000010, empty);
+       /* clear JTAG error register */
+       ZY1000_POKE(0x08000014, 0x400);
+
+       if ((empty&0x400)!=0)
+       {
+               LOG_WARNING("RCLK timeout");
+               /* the error is informative only as we don't want to break the firmware if there
+                * is a false positive.
+                */
+//             return ERROR_FAIL;
+       }
+       return ERROR_OK;
+}
+
+
+
+
+
+static cyg_uint32 getShiftValue()
+{
+       cyg_uint32 value;
+       waitIdle();
+       ZY1000_PEEK(0x0800000c, value);
+       VERBOSE(LOG_INFO("getShiftValue %08x", value));
+       return value;
+}
+#if 0
+static cyg_uint32 getShiftValueFlip()
+{
+       cyg_uint32 value;
+       waitIdle();
+       ZY1000_PEEK(0x08000018, value);
+       VERBOSE(LOG_INFO("getShiftValue %08x (flipped)", value));
+       return value;
+}
+#endif
+
+#if 0
+static void shiftValueInnerFlip(const enum tap_state state, const enum tap_state endState, int repeat, cyg_uint32 value)
+{
+       VERBOSE(LOG_INFO("shiftValueInner %s %s %d %08x (flipped)", tap_state_strings[state], tap_state_strings[endState], repeat, value));
+       cyg_uint32 a,b;
+       a=state;
+       b=endState;
+       ZY1000_POKE(0x0800000c, value);
+       ZY1000_POKE(0x08000008, (1<<15)|(repeat<<8)|(a<<4)|b);
+       VERBOSE(getShiftValueFlip());
+}
+#endif
+
+extern int jtag_check_value(u8 *captured, void *priv);
+
+static void gotoEndState()
+{
+       setCurrentState(cmd_queue_end_state);
+}
+
+static __inline void scanFields(int num_fields, scan_field_t *fields, enum tap_state shiftState, int pause)
+{
+       int i;
+       int j;
+       int k;
+
+       for (i = 0; i < num_fields; i++)
+       {
+               cyg_uint32 value;
+
+               static u8 *in_buff=NULL; /* pointer to buffer for scanned data */
+               static int in_buff_size=0;
+               u8 *inBuffer=NULL;
+
+
+               // figure out where to store the input data
+               int num_bits=fields[i].num_bits;
+               if (fields[i].in_value!=NULL)
+               {
+                       inBuffer=fields[i].in_value;
+               } else if (fields[i].in_handler!=NULL)
+               {
+                       if (in_buff_size*8<num_bits)
+                       {
+                               // we need more space
+                               if (in_buff!=NULL)
+                                       free(in_buff);
+                               in_buff=NULL;
+                               in_buff_size=(num_bits+7)/8;
+                               in_buff=malloc(in_buff_size);
+                               if (in_buff==NULL)
+                               {
+                                       LOG_ERROR("Out of memory");
+                                       jtag_error=ERROR_JTAG_QUEUE_FAILED;
+                                       return;
+                               }
+                       }
+                       inBuffer=in_buff;
+               }
+
+               // here we shuffle N bits out/in
+               j=0;
+               while (j<num_bits)
+               {
+                       enum tap_state pause_state;
+                       int l;
+                       k=num_bits-j;
+                       pause_state=(shiftState==TAP_SD)?TAP_SD:TAP_SI;
+                       if (k>32)
+                       {
+                               k=32;
+                               /* we have more to shift out */
+                       } else if (pause&&(i == num_fields-1))
+                       {
+                               /* this was the last to shift out this time */
+                               pause_state=(shiftState==TAP_SD)?TAP_PD:TAP_PI;
+                       }
+
+                       // we have (num_bits+7)/8 bytes of bits to toggle out.
+                       // bits are pushed out LSB to MSB
+                       value=0;
+                       if (fields[i].out_value!=NULL)
+                       {
+                               for (l=0; l<k; l+=8)
+                               {
+                                       value|=fields[i].out_value[(j+l)/8]<<l;
+                               }
+                       }
+                       /* mask away unused bits for easier debugging */
+                       value&=~(((u32)0xffffffff)<<k);
+
+                       shiftValueInner(shiftState, pause_state, k, value);
+
+                       if (inBuffer!=NULL)
+                       {
+                               // data in, LSB to MSB
+                               value=getShiftValue();
+                               // we're shifting in data to MSB, shift data to be aligned for returning the value
+                               value >>= 32-k;
+
+                               for (l=0; l<k; l+=8)
+                               {
+                                       inBuffer[(j+l)/8]=(value>>l)&0xff;
+                               }
+                       }
+                       j+=k;
+               }
+
+               if (fields[i].in_handler!=NULL)
+               {
+                       // invoke callback
+                       int r=fields[i].in_handler(inBuffer, fields[i].in_handler_priv, fields+i);
+                       if (r!=ERROR_OK)
+                       {
+                           /* this will cause jtag_execute_queue() to return an error */
+                               jtag_error=r;
+                       }
+               }
+       }
+}
+
+int interface_jtag_add_end_state(enum tap_state state)
+{
+       return ERROR_OK;
+}
+
+
+int interface_jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+{
+
+       int i, j;
+       int scan_size = 0;
+       jtag_device_t *device;
+
+       for (i=0; i < jtag_num_devices; i++)
+       {
+               int pause=i==(jtag_num_devices-1);
+               int found = 0;
+               device = jtag_get_device(i);
+               scan_size = device->ir_length;
+
+               /* search the list */
+               for (j=0; j < num_fields; j++)
+               {
+                       if (i == fields[j].device)
+                       {
+                               found = 1;
+
+                               if ((jtag_verify_capture_ir)&&(fields[j].in_handler==NULL))
+                               {
+                                       jtag_set_check_value(fields+j, device->expected, device->expected_mask, NULL);
+                               } else if (jtag_verify_capture_ir)
+                               {
+                                       fields[j].in_check_value = device->expected;
+                                       fields[j].in_check_mask = device->expected_mask;
+                               }
+
+                               scanFields(1, fields+j, TAP_SI, pause);
+                               /* update device information */
+                               buf_cpy(fields[j].out_value, jtag_get_device(i)->cur_instr, scan_size);
+
+                               device->bypass = 0;
+                               break;
+                       }
+               }
+
+               if (!found)
+               {
+                       /* if a device isn't listed, set it to BYPASS */
+                       u8 ones[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+
+                       scan_field_t tmp;
+                       memset(&tmp, 0, sizeof(tmp));
+                       tmp.out_value = ones;
+                       tmp.num_bits = scan_size;
+                       scanFields(1, &tmp, TAP_SI, pause);
+                       /* update device information */
+                       buf_cpy(tmp.out_value, jtag_get_device(i)->cur_instr, scan_size);
+                       device->bypass = 1;
+               }
+       }
+       gotoEndState();
+
+       return ERROR_OK;
+}
+
+
+
+
+
+int interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+{
+       scanFields(num_fields, fields, TAP_SI, 1);
+       gotoEndState();
+
+       return ERROR_OK;
+}
+
+/*extern jtag_command_t **jtag_get_last_command_p(void);*/
+
+int interface_jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+{
+       int i, j;
+       for (i=0; i < jtag_num_devices; i++)
+       {
+               int found = 0;
+               int pause = (i==(jtag_num_devices-1));
+
+               for (j=0; j < num_fields; j++)
+               {
+                       if (i == fields[j].device)
+                       {
+                               found = 1;
+
+                               scanFields(1, fields+j, TAP_SD, pause);
+                       }
+               }
+               if (!found)
+               {
+#ifdef _DEBUG_JTAG_IO_
+                       /* if a device isn't listed, the BYPASS register should be selected */
+                       if (!jtag_get_device(i)->bypass)
+                       {
+                               LOG_ERROR("BUG: no scan data for a device not in BYPASS");
+                               exit(-1);
+                       }
+#endif
+
+                       scan_field_t tmp;
+                       /* program the scan field to 1 bit length, and ignore it's value */
+                       tmp.num_bits = 1;
+                       tmp.out_value = NULL;
+                       tmp.out_mask = NULL;
+                       tmp.in_value = NULL;
+                       tmp.in_check_value = NULL;
+                       tmp.in_check_mask = NULL;
+                       tmp.in_handler = NULL;
+                       tmp.in_handler_priv = NULL;
+
+                       scanFields(1, &tmp, TAP_SD, pause);
+               }
+               else
+               {
+#ifdef _DEBUG_JTAG_IO_
+                       /* if a device is listed, the BYPASS register must not be selected */
+                       if (jtag_get_device(i)->bypass)
+                       {
+                               LOG_WARNING("scan data for a device in BYPASS");
+                       }
+#endif
+               }
+       }
+       gotoEndState();
+       return ERROR_OK;
+}
+
+int interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+{
+       scanFields(num_fields, fields, TAP_SD, 1);
+       gotoEndState();
+       return ERROR_OK;
+}
+
+
+int interface_jtag_add_tlr()
+{
+       setCurrentState(TAP_TLR);
+       return ERROR_OK;
+}
+
+
+
+
+extern int jtag_nsrst_delay;
+extern int jtag_ntrst_delay;
+
+int interface_jtag_add_reset(int req_trst, int req_srst)
+{
+       eCosBoard_reset(req_trst, req_srst);
+       return ERROR_OK;
+}
+
+int interface_jtag_add_runtest(int num_cycles, enum tap_state state)
+{
+       /* num_cycles can be 0 */
+       setCurrentState(TAP_RTI);
+
+       /* execute num_cycles, 32 at the time. */
+       int i;
+       for (i=0; i<num_cycles; i+=32)
+       {
+               int num;
+               num=32;
+               if (num_cycles-i<num)
+               {
+                       num=num_cycles-i;
+               }
+               shiftValueInner(TAP_RTI, TAP_RTI, num, 0);
+       }
+
+#if !TEST_MANUAL()
+       /* finish in end_state */
+       setCurrentState(state);
+#else
+       enum tap_state t=TAP_RTI;
+       /* test manual drive code on any target */
+       int tms;
+       u8 tms_scan = TAP_MOVE(t, state);
+       
+       for (i = 0; i < 7; i++)
+       {
+               tms = (tms_scan >> i) & 1;
+               waitIdle();
+               ZY1000_POKE(0x08000028,  tms);
+       }
+       waitIdle();
+       ZY1000_POKE(0x08000020, state); 
+#endif
+
+
+       return ERROR_OK;
+}
+
+int interface_jtag_add_sleep(u32 us)
+{
+       jtag_sleep(us);
+       return ERROR_OK;
+}
+
+int interface_jtag_add_pathmove(int num_states, enum tap_state *path)
+{
+       int state_count;
+       int tms = 0;
+
+       /*wait for the fifo to be empty*/
+       waitIdle();
+
+       state_count = 0;
+
+       enum tap_state cur_state=cmd_queue_cur_state;
+
+       while (num_states)
+       {
+               if (tap_transitions[cur_state].low == path[state_count])
+               {
+                       tms = 0;
+               }
+               else if (tap_transitions[cur_state].high == path[state_count])
+               {
+                       tms = 1;
+               }
+               else
+               {
+                       LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[path[state_count]]);
+                       exit(-1);
+               }
+
+               waitIdle();
+               ZY1000_POKE(0x08000028,  tms);
+
+               cur_state = path[state_count];
+               state_count++;
+               num_states--;
+       }
+
+       waitIdle();
+       ZY1000_POKE(0x08000020,  cur_state);
+       return ERROR_OK;
+}
+
+
+
+void embeddedice_write_dcc(int chain_pos, int reg_addr, u8 *buffer, int little, int count)
+{
+//     static int const reg_addr=0x5;
+       enum tap_state end_state=cmd_queue_end_state;
+       if (jtag_num_devices==1)
+       {
+               /* better performance via code duplication */
+               if (little)
+               {
+                       int i;
+                       for (i = 0; i < count; i++)
+                       {
+                               shiftValueInner(TAP_SD, TAP_SD, 32, fast_target_buffer_get_u32(buffer, 1));
+                               shiftValueInner(TAP_SD, end_state, 6, reg_addr|(1<<5));
+                               buffer+=4;
+                       }
+               } else
+               {
+                       int i;
+                       for (i = 0; i < count; i++)
+                       {
+                               shiftValueInner(TAP_SD, TAP_SD, 32, fast_target_buffer_get_u32(buffer, 0));
+                               shiftValueInner(TAP_SD, end_state, 6, reg_addr|(1<<5));
+                               buffer+=4;
+                       }
+               }
+       }
+       else
+       {
+               int i;
+               for (i = 0; i < count; i++)
+               {
+                       embeddedice_write_reg_inner(chain_pos, reg_addr, fast_target_buffer_get_u32(buffer, little));
+                       buffer += 4;
+               }
+       }
+}
+
index 14a781cef3a96777e896934adb122c9324a714c2..7b65c8bdf370b9cea6bf7f7f4e873ce94a4448cf 100644 (file)
@@ -106,14 +106,14 @@ int cortex_m3_clear_halt(target_t *target)
        armv7m_common_t *armv7m = target->arch_info;
        cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
        swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
-    
-    /* Read Debug Fault Status Register */
-    ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
-    /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
-    ahbap_write_system_atomic_u32(swjdp, NVIC_DFSR, cortex_m3->nvic_dfsr);
-    LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3->nvic_dfsr);
-
-    return ERROR_OK;
+       
+       /* Read Debug Fault Status Register */
+       ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
+       /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
+       ahbap_write_system_atomic_u32(swjdp, NVIC_DFSR, cortex_m3->nvic_dfsr);
+       LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3->nvic_dfsr);
+
+       return ERROR_OK;
 }
 
 int cortex_m3_single_step_core(target_t *target)
@@ -287,8 +287,8 @@ int cortex_m3_examine_exception_reason(target_t *target)
                        break;
        }
        swjdp_transaction_endcheck(swjdp);
-    LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m->exception_number), \
-       shcsr, except_sr, cfsr, except_ar);
+       LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m->exception_number), \
+               shcsr, except_sr, cfsr, except_ar);
        return ERROR_OK;
 }
 
@@ -363,9 +363,9 @@ int cortex_m3_debug_entry(target_t *target)
        }
 
        LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", 
-                 armv7m_mode_strings[armv7m->core_mode],
-                 *(u32*)(armv7m->core_cache->reg_list[15].value), 
-                 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
+               armv7m_mode_strings[armv7m->core_mode],
+               *(u32*)(armv7m->core_cache->reg_list[15].value), 
+               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
 
        if (armv7m->post_debug_entry)
                armv7m->post_debug_entry(target);
@@ -439,7 +439,7 @@ int cortex_m3_poll(target_t *target)
        */
 
 #if 0
-    /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script  */
+       /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script  */
        ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
        LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, Jim_Nvp_value2name( nvp_target_state, target->state )->name );
 #endif
@@ -455,7 +455,7 @@ int cortex_m3_halt(target_t *target)
        swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
        
        LOG_DEBUG("target->state: %s", 
-                 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
        
        if (target->state == TARGET_HALTED)
        {
@@ -518,7 +518,7 @@ int cortex_m3_soft_reset_halt(struct target_s *target)
                retval = ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
                if (retval == ERROR_OK)
                {
-                   ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
+                       ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
                        if ((dcb_dhcsr & S_HALT) && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
                        {
                                LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr, cortex_m3->nvic_dfsr);
@@ -563,11 +563,9 @@ int cortex_m3_resume(struct target_s *target, int current, u32 address, int hand
        if (debug_execution)
        {
                /* Disable interrupts */
-               /* 
-                  We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
-                  This is probably the same inssue as Cortex-M3 Errata 377493: 
-                  C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
-               */
+               /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
+                * This is probably the same inssue as Cortex-M3 Errata 377493: 
+                * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
                buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
                /* Make sure we are in Thumb mode */
                buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32, 
@@ -654,7 +652,7 @@ int cortex_m3_step(struct target_s *target, int current, u32 address, int handle
        armv7m_restore_context(target);
        
        target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
-    
+       
        if (cortex_m3->dcb_dhcsr & C_MASKINTS)
                ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN );
        ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY| C_STEP | C_DEBUGEN);
@@ -683,7 +681,7 @@ int cortex_m3_assert_reset(target_t *target)
        int assert_srst = 1;
        
        LOG_DEBUG("target->state: %s", 
-                 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
        
        if (!(jtag_reset_config & RESET_HAS_SRST))
        {
@@ -765,10 +763,10 @@ int cortex_m3_assert_reset(target_t *target)
 
                {
                        /* I do not know why this is necessary, but it fixes strange effects
-                      (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
+                        * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
                        u32 tmp;
                        ahbap_read_system_atomic_u32(swjdp, NVIC_AIRCR, &tmp );
-       }
+               }
        }
        
        target->state = TARGET_RESET;
@@ -776,12 +774,12 @@ int cortex_m3_assert_reset(target_t *target)
        
        armv7m_invalidate_core_regs(target);
 
-    if (target->reset_halt)
-    {
-       int retval;
+       if (target->reset_halt)
+       {
+               int retval;
                if ((retval = target_halt(target))!=ERROR_OK)
                        return retval;
-    }
+       }
        
        return ERROR_OK;
 }
@@ -789,7 +787,7 @@ int cortex_m3_assert_reset(target_t *target)
 int cortex_m3_deassert_reset(target_t *target)
 {              
        LOG_DEBUG("target->state: %s", 
-                 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
+               Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
        
        /* deassert reset lines */
        jtag_add_reset(0, 0);
@@ -826,7 +824,7 @@ int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
                LOG_WARNING("breakpoint already set");
                return ERROR_OK;
        }
-    
+       
        if (cortex_m3->auto_bp_type)
        {
                breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)