diff --git a/doc/INSTALL.txt b/doc/INSTALL.txt
index 3732035f8ec2e644d59598e61273245186a44de5..5b8077ad201f869655b5b8195119369c783a1b5a 100644
--- a/doc/INSTALL.txt
+++ b/doc/INSTALL.txt
@@ -1,204 +1,204 @@
-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.
-
+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.
+
diff --git a/src/ecosboard.c b/src/ecosboard.c
index d11190032e872e77d7cfff4859a99474863d3ec0..182fc5c50e5a8580218cd7a551c335db85d03f54 100644
--- a/src/ecosboard.c
+++ b/src/ecosboard.c
@@ -1,2405 +1,2405 @@
-/***************************************************************************
- *   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;
-}
+/***************************************************************************
+ *   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;
+}
diff --git a/src/flash/at91sam7.c b/src/flash/at91sam7.c
index 3b51c07b32e933e4836549fafb2624db001481d6..44bedd96dbeee068f71780cd4f623405e17c2373 100644
--- a/src/flash/at91sam7.c
+++ b/src/flash/at91sam7.c
@@ -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;
 }
diff --git a/src/flash/at91sam7.h b/src/flash/at91sam7.h
index efc669e36d6a25e072aa712fd711ac3bc25d4f43..f57f36ec8cc156b6cd32f248eedf01d5716bdc35 100644
--- a/src/flash/at91sam7.h
+++ b/src/flash/at91sam7.h
@@ -26,95 +26,94 @@
 #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 */
diff --git a/src/flash/at91sam7_old.c b/src/flash/at91sam7_old.c
index db14da6e3d72d76452cb18c75feccb98e673e312..aa17e73d23b3e644c3802fde5b304dad71be712a 100644
--- a/src/flash/at91sam7_old.c
+++ b/src/flash/at91sam7_old.c
@@ -1,954 +1,954 @@
-/***************************************************************************
- *   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;
-}
+/***************************************************************************
+ *   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;
+}
diff --git a/src/flash/at91sam7_old.h b/src/flash/at91sam7_old.h
index 0850456542239a917dd62c79eb4cbc32695fa12d..75c881c2e35f91a130a8a400f541a7192e92b58b 100644
--- a/src/flash/at91sam7_old.h
+++ b/src/flash/at91sam7_old.h
@@ -1,98 +1,98 @@
-/***************************************************************************
- *   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 */
+/***************************************************************************
+ *   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 */
diff --git a/src/flash/flash.c b/src/flash/flash.c
index b2ebe0b79a0491f787feca8c4b38e59f6e951db8..5f09c72dd7b8f57497f1ac579d063a2c3873eb53 100644
--- a/src/flash/flash.c
+++ b/src/flash/flash.c
@@ -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;
 
diff --git a/src/flash/flash.h b/src/flash/flash.h
index 4ccbc047eeeccec03371d772fca1f12b3cc28601..817c60628320c53eb42d319aaf51e04c1cae6e7b 100644
--- a/src/flash/flash.h
+++ b/src/flash/flash.h
@@ -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 */
diff --git a/src/jtag/zy1000.c b/src/jtag/zy1000.c
index 8c10a9ffea1d3587ff943df12e69d7267276dede..5583032361c03c02c5f6dfd2b04d2e1234f290e2 100644
--- a/src/jtag/zy1000.c
+++ b/src/jtag/zy1000.c
@@ -1,739 +1,739 @@
-/***************************************************************************
- *   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;
-		}
-	}
-}
-
+/***************************************************************************
+ *   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;
+		}
+	}
+}
+
diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c
index 14a781cef3a96777e896934adb122c9324a714c2..7b65c8bdf370b9cea6bf7f7f4e873ce94a4448cf 100644
--- a/src/target/cortex_m3.c
+++ b/src/target/cortex_m3.c
@@ -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;