git-svn-id: svn://svn.berlios.de/openocd/trunk@64 b42882b7-edfa-0310-969c-e2dbd0fdcd60tags/v0.1.0
@@ -0,0 +1 @@ | |||
Dominic Rath <Dominic.Rath@gmx.de> |
@@ -0,0 +1,340 @@ | |||
GNU GENERAL PUBLIC LICENSE | |||
Version 2, June 1991 | |||
Copyright (C) 1989, 1991 Free Software Foundation, Inc. | |||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
Everyone is permitted to copy and distribute verbatim copies | |||
of this license document, but changing it is not allowed. | |||
Preamble | |||
The licenses for most software are designed to take away your | |||
freedom to share and change it. By contrast, the GNU General Public | |||
License is intended to guarantee your freedom to share and change free | |||
software--to make sure the software is free for all its users. This | |||
General Public License applies to most of the Free Software | |||
Foundation's software and to any other program whose authors commit to | |||
using it. (Some other Free Software Foundation software is covered by | |||
the GNU Library General Public License instead.) You can apply it to | |||
your programs, too. | |||
When we speak of free software, we are referring to freedom, not | |||
price. Our General Public Licenses are designed to make sure that you | |||
have the freedom to distribute copies of free software (and charge for | |||
this service if you wish), that you receive source code or can get it | |||
if you want it, that you can change the software or use pieces of it | |||
in new free programs; and that you know you can do these things. | |||
To protect your rights, we need to make restrictions that forbid | |||
anyone to deny you these rights or to ask you to surrender the rights. | |||
These restrictions translate to certain responsibilities for you if you | |||
distribute copies of the software, or if you modify it. | |||
For example, if you distribute copies of such a program, whether | |||
gratis or for a fee, you must give the recipients all the rights that | |||
you have. You must make sure that they, too, receive or can get the | |||
source code. And you must show them these terms so they know their | |||
rights. | |||
We protect your rights with two steps: (1) copyright the software, and | |||
(2) offer you this license which gives you legal permission to copy, | |||
distribute and/or modify the software. | |||
Also, for each author's protection and ours, we want to make certain | |||
that everyone understands that there is no warranty for this free | |||
software. If the software is modified by someone else and passed on, we | |||
want its recipients to know that what they have is not the original, so | |||
that any problems introduced by others will not reflect on the original | |||
authors' reputations. | |||
Finally, any free program is threatened constantly by software | |||
patents. We wish to avoid the danger that redistributors of a free | |||
program will individually obtain patent licenses, in effect making the | |||
program proprietary. To prevent this, we have made it clear that any | |||
patent must be licensed for everyone's free use or not licensed at all. | |||
The precise terms and conditions for copying, distribution and | |||
modification follow. | |||
GNU GENERAL PUBLIC LICENSE | |||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |||
0. This License applies to any program or other work which contains | |||
a notice placed by the copyright holder saying it may be distributed | |||
under the terms of this General Public License. The "Program", below, | |||
refers to any such program or work, and a "work based on the Program" | |||
means either the Program or any derivative work under copyright law: | |||
that is to say, a work containing the Program or a portion of it, | |||
either verbatim or with modifications and/or translated into another | |||
language. (Hereinafter, translation is included without limitation in | |||
the term "modification".) Each licensee is addressed as "you". | |||
Activities other than copying, distribution and modification are not | |||
covered by this License; they are outside its scope. The act of | |||
running the Program is not restricted, and the output from the Program | |||
is covered only if its contents constitute a work based on the | |||
Program (independent of having been made by running the Program). | |||
Whether that is true depends on what the Program does. | |||
1. You may copy and distribute verbatim copies of the Program's | |||
source code as you receive it, in any medium, provided that you | |||
conspicuously and appropriately publish on each copy an appropriate | |||
copyright notice and disclaimer of warranty; keep intact all the | |||
notices that refer to this License and to the absence of any warranty; | |||
and give any other recipients of the Program a copy of this License | |||
along with the Program. | |||
You may charge a fee for the physical act of transferring a copy, and | |||
you may at your option offer warranty protection in exchange for a fee. | |||
2. You may modify your copy or copies of the Program or any portion | |||
of it, thus forming a work based on the Program, and copy and | |||
distribute such modifications or work under the terms of Section 1 | |||
above, provided that you also meet all of these conditions: | |||
a) You must cause the modified files to carry prominent notices | |||
stating that you changed the files and the date of any change. | |||
b) You must cause any work that you distribute or publish, that in | |||
whole or in part contains or is derived from the Program or any | |||
part thereof, to be licensed as a whole at no charge to all third | |||
parties under the terms of this License. | |||
c) If the modified program normally reads commands interactively | |||
when run, you must cause it, when started running for such | |||
interactive use in the most ordinary way, to print or display an | |||
announcement including an appropriate copyright notice and a | |||
notice that there is no warranty (or else, saying that you provide | |||
a warranty) and that users may redistribute the program under | |||
these conditions, and telling the user how to view a copy of this | |||
License. (Exception: if the Program itself is interactive but | |||
does not normally print such an announcement, your work based on | |||
the Program is not required to print an announcement.) | |||
These requirements apply to the modified work as a whole. If | |||
identifiable sections of that work are not derived from the Program, | |||
and can be reasonably considered independent and separate works in | |||
themselves, then this License, and its terms, do not apply to those | |||
sections when you distribute them as separate works. But when you | |||
distribute the same sections as part of a whole which is a work based | |||
on the Program, the distribution of the whole must be on the terms of | |||
this License, whose permissions for other licensees extend to the | |||
entire whole, and thus to each and every part regardless of who wrote it. | |||
Thus, it is not the intent of this section to claim rights or contest | |||
your rights to work written entirely by you; rather, the intent is to | |||
exercise the right to control the distribution of derivative or | |||
collective works based on the Program. | |||
In addition, mere aggregation of another work not based on the Program | |||
with the Program (or with a work based on the Program) on a volume of | |||
a storage or distribution medium does not bring the other work under | |||
the scope of this License. | |||
3. You may copy and distribute the Program (or a work based on it, | |||
under Section 2) in object code or executable form under the terms of | |||
Sections 1 and 2 above provided that you also do one of the following: | |||
a) Accompany it with the complete corresponding machine-readable | |||
source code, which must be distributed under the terms of Sections | |||
1 and 2 above on a medium customarily used for software interchange; or, | |||
b) Accompany it with a written offer, valid for at least three | |||
years, to give any third party, for a charge no more than your | |||
cost of physically performing source distribution, a complete | |||
machine-readable copy of the corresponding source code, to be | |||
distributed under the terms of Sections 1 and 2 above on a medium | |||
customarily used for software interchange; or, | |||
c) Accompany it with the information you received as to the offer | |||
to distribute corresponding source code. (This alternative is | |||
allowed only for noncommercial distribution and only if you | |||
received the program in object code or executable form with such | |||
an offer, in accord with Subsection b above.) | |||
The source code for a work means the preferred form of the work for | |||
making modifications to it. For an executable work, complete source | |||
code means all the source code for all modules it contains, plus any | |||
associated interface definition files, plus the scripts used to | |||
control compilation and installation of the executable. However, as a | |||
special exception, the source code distributed need not include | |||
anything that is normally distributed (in either source or binary | |||
form) with the major components (compiler, kernel, and so on) of the | |||
operating system on which the executable runs, unless that component | |||
itself accompanies the executable. | |||
If distribution of executable or object code is made by offering | |||
access to copy from a designated place, then offering equivalent | |||
access to copy the source code from the same place counts as | |||
distribution of the source code, even though third parties are not | |||
compelled to copy the source along with the object code. | |||
4. You may not copy, modify, sublicense, or distribute the Program | |||
except as expressly provided under this License. Any attempt | |||
otherwise to copy, modify, sublicense or distribute the Program is | |||
void, and will automatically terminate your rights under this License. | |||
However, parties who have received copies, or rights, from you under | |||
this License will not have their licenses terminated so long as such | |||
parties remain in full compliance. | |||
5. You are not required to accept this License, since you have not | |||
signed it. However, nothing else grants you permission to modify or | |||
distribute the Program or its derivative works. These actions are | |||
prohibited by law if you do not accept this License. Therefore, by | |||
modifying or distributing the Program (or any work based on the | |||
Program), you indicate your acceptance of this License to do so, and | |||
all its terms and conditions for copying, distributing or modifying | |||
the Program or works based on it. | |||
6. Each time you redistribute the Program (or any work based on the | |||
Program), the recipient automatically receives a license from the | |||
original licensor to copy, distribute or modify the Program subject to | |||
these terms and conditions. You may not impose any further | |||
restrictions on the recipients' exercise of the rights granted herein. | |||
You are not responsible for enforcing compliance by third parties to | |||
this License. | |||
7. If, as a consequence of a court judgment or allegation of patent | |||
infringement or for any other reason (not limited to patent issues), | |||
conditions are imposed on you (whether by court order, agreement or | |||
otherwise) that contradict the conditions of this License, they do not | |||
excuse you from the conditions of this License. If you cannot | |||
distribute so as to satisfy simultaneously your obligations under this | |||
License and any other pertinent obligations, then as a consequence you | |||
may not distribute the Program at all. For example, if a patent | |||
license would not permit royalty-free redistribution of the Program by | |||
all those who receive copies directly or indirectly through you, then | |||
the only way you could satisfy both it and this License would be to | |||
refrain entirely from distribution of the Program. | |||
If any portion of this section is held invalid or unenforceable under | |||
any particular circumstance, the balance of the section is intended to | |||
apply and the section as a whole is intended to apply in other | |||
circumstances. | |||
It is not the purpose of this section to induce you to infringe any | |||
patents or other property right claims or to contest validity of any | |||
such claims; this section has the sole purpose of protecting the | |||
integrity of the free software distribution system, which is | |||
implemented by public license practices. Many people have made | |||
generous contributions to the wide range of software distributed | |||
through that system in reliance on consistent application of that | |||
system; it is up to the author/donor to decide if he or she is willing | |||
to distribute software through any other system and a licensee cannot | |||
impose that choice. | |||
This section is intended to make thoroughly clear what is believed to | |||
be a consequence of the rest of this License. | |||
8. If the distribution and/or use of the Program is restricted in | |||
certain countries either by patents or by copyrighted interfaces, the | |||
original copyright holder who places the Program under this License | |||
may add an explicit geographical distribution limitation excluding | |||
those countries, so that distribution is permitted only in or among | |||
countries not thus excluded. In such case, this License incorporates | |||
the limitation as if written in the body of this License. | |||
9. The Free Software Foundation may publish revised and/or new versions | |||
of the General Public License from time to time. Such new versions will | |||
be similar in spirit to the present version, but may differ in detail to | |||
address new problems or concerns. | |||
Each version is given a distinguishing version number. If the Program | |||
specifies a version number of this License which applies to it and "any | |||
later version", you have the option of following the terms and conditions | |||
either of that version or of any later version published by the Free | |||
Software Foundation. If the Program does not specify a version number of | |||
this License, you may choose any version ever published by the Free Software | |||
Foundation. | |||
10. If you wish to incorporate parts of the Program into other free | |||
programs whose distribution conditions are different, write to the author | |||
to ask for permission. For software which is copyrighted by the Free | |||
Software Foundation, write to the Free Software Foundation; we sometimes | |||
make exceptions for this. Our decision will be guided by the two goals | |||
of preserving the free status of all derivatives of our free software and | |||
of promoting the sharing and reuse of software generally. | |||
NO WARRANTY | |||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |||
REPAIR OR CORRECTION. | |||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGES. | |||
END OF TERMS AND CONDITIONS | |||
How to Apply These Terms to Your New Programs | |||
If you develop a new program, and you want it to be of the greatest | |||
possible use to the public, the best way to achieve this is to make it | |||
free software which everyone can redistribute and change under these terms. | |||
To do so, attach the following notices to the program. It is safest | |||
to attach them to the start of each source file to most effectively | |||
convey the exclusion of warranty; and each file should have at least | |||
the "copyright" line and a pointer to where the full notice is found. | |||
<one line to give the program's name and a brief idea of what it does.> | |||
Copyright (C) <year> <name of author> | |||
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 | |||
Also add information on how to contact you by electronic and paper mail. | |||
If the program is interactive, make it output a short notice like this | |||
when it starts in an interactive mode: | |||
Gnomovision version 69, Copyright (C) year name of author | |||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |||
This is free software, and you are welcome to redistribute it | |||
under certain conditions; type `show c' for details. | |||
The hypothetical commands `show w' and `show c' should show the appropriate | |||
parts of the General Public License. Of course, the commands you use may | |||
be called something other than `show w' and `show c'; they could even be | |||
mouse-clicks or menu items--whatever suits your program. | |||
You should also get your employer (if you work as a programmer) or your | |||
school, if any, to sign a "copyright disclaimer" for the program, if | |||
necessary. Here is a sample; alter the names: | |||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program | |||
`Gnomovision' (which makes passes at compilers) written by James Hacker. | |||
<signature of Ty Coon>, 1 April 1989 | |||
Ty Coon, President of Vice | |||
This General Public License does not permit incorporating your program into | |||
proprietary programs. If your program is a subroutine library, you may | |||
consider it more useful to permit linking proprietary applications with the | |||
library. If this is what you want to do, use the GNU Library General | |||
Public License instead of this License. |
@@ -0,0 +1,7 @@ | |||
2005-07-03 Dominic Rath <Dominic.Rath@gmx.net> | |||
* First public release | |||
2005-10-27 Dominic Rath <Dominic.Rath@gmx.net> | |||
* First release of new codebase |
@@ -0,0 +1,194 @@ | |||
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) | |||
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-ftdi2232 --enable-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. | |||
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. | |||
@@ -0,0 +1,5 @@ | |||
# not a GNU package. You can remove this line, if | |||
# have all needed files, that a GNU package needs | |||
AUTOMAKE_OPTIONS = foreign 1.4 | |||
SUBDIRS = src |
@@ -0,0 +1,49 @@ | |||
openocd | |||
Free and Open On-Chip Debugging, In-System Programming | |||
and Boundary-Scan Testing | |||
Copyright (c) 2004, 2005 Dominic Rath | |||
The debugger uses an IEEE 1149-1 compliant JTAG TAP bus master to access on-chip | |||
debug functionality available on ARM7 and ARM9 based microcontrollers / | |||
system-on-chip solutions. | |||
User interaction is realized through a telnet command line interface and a gdb | |||
(The GNU Debugger) remote protocol server. | |||
Initially, support for two JTAG TAP bus master interfaces with public hardware | |||
schematics will be included, but support of additional hardware is an expressed | |||
goal. | |||
1. JTAG hardware | |||
Currently, openocd contains support for Wiggler-compatible paralell port | |||
dongles and a USB interface based on the FTDI FT2232, called USBJTAG-1. | |||
A new version of the USB interface, USB-JTAG v1.2, is available with complete | |||
schematics (http://www.fh-augsburg.de/~hhoegl/proj/volksmikro/usb-jtag/050910/). | |||
It was tested using Amontec's (www.amontec.com) Chameleon POD in it's | |||
Wiggler configuration, but homemade wigglers should work just as well. | |||
In order to use the reset functionality (warm-reset, debug from reset, reset | |||
and init), the choosen Wiggler has to connect the nSRST line. | |||
USBJTAG-1 is based on a FTDI DLP2232M module and a few additional parts. | |||
Schematics are freely available. USB-JTAG v1.2 doesn't use the DLP2232M, but | |||
has the FTDI chip soldered directly on the PCB. There are two drivers for these | |||
modules implemented, one using the open source libftdi, the other using FTDI's | |||
proprietary FTD2XX library. | |||
2. Supported cores | |||
This version of openocd supports the following cores: | |||
- ARM7TDMI | |||
- ARM9TDMI | |||
Support for cores with MMUs (ARM720t, ARM920t) is currently being merged. | |||
3. Licensing | |||
openocd is licensed under the terms of the GNU General Public License, see the | |||
file COPYING for details. | |||
@@ -0,0 +1,7 @@ | |||
- Additional cores. ARM9E(J)-S, ARM7TDMI-S, TI925, ... | |||
- Testing. | |||
- Additional jtag interfaces. Currently, only Wiggler style interfaces and | |||
USBJTAG-1 are supported. | |||
- Testing. | |||
- Handle endianess. The configuration variable is there, but that's about it. | |||
Currently, only little-endian targets and little-endian hosts are supported. |
@@ -0,0 +1,4 @@ | |||
aclocal \ | |||
&& autoheader \ | |||
&& automake --gnu --add-missing \ | |||
&& autoconf |
@@ -0,0 +1,112 @@ | |||
AC_INIT(configure.in) | |||
AC_SEARCH_LIBS([ioperm], [ioperm]) | |||
AC_CANONICAL_HOST | |||
build_bitbang=no | |||
is_cygwin=no | |||
AC_ARG_ENABLE(parport, | |||
AS_HELP_STRING([--enable-parport], [Enable building the pc parallel port driver]), | |||
[build_parport=$enableval], [build_parport=no]) | |||
AC_ARG_ENABLE(parport_ppdev, | |||
AS_HELP_STRING([--enable-parport_ppdev], [Enable use of ppdev (/dev/parportN) for parport]), | |||
[parport_use_ppdev=$enableval], [parport_use_ppdev=no]) | |||
AC_ARG_ENABLE(ftdi2232, | |||
AS_HELP_STRING([--enable-ftdi2232], [Enable building the libftdi ft2232c driver]), | |||
[build_ftdi2232=$enableval], [build_ftdi2232=no]) | |||
AC_ARG_ENABLE(ftd2xx, | |||
AS_HELP_STRING([--enable-ftd2xx], [Enable building the ftd2xx ft2232c driver]), | |||
[build_ftd2xx=$enableval], [build_ftd2xx=no]) | |||
AC_ARG_ENABLE(amtjtagaccel, | |||
AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]), | |||
[build_amtjtagaccel=$enableval], [build_amtjtagaccel=no]) | |||
AC_ARG_ENABLE(ep93xx, | |||
AS_HELP_STRING([--enable-ep93xx], [Enable building support for EP93xx based SBCs]), | |||
[build_ep93xx=$enableval], [build_ep93xx=no]) | |||
AC_ARG_WITH(ftd2xx, | |||
[AS_HELP_STRING(--with-ftd2xx, | |||
[Where libftd2xx can be found <default=search>])], | |||
[], | |||
with_ftd2xx=search) | |||
if test $build_parport = yes; then | |||
build_bitbang=yes | |||
AC_DEFINE(BUILD_PARPORT, 1, [1 if you want parport.]) | |||
else | |||
AC_DEFINE(BUILD_PARPORT, 0, [0 if you don't want parport.]) | |||
fi | |||
if test $build_ep93xx = yes; then | |||
build_bitbang=yes | |||
AC_DEFINE(BUILD_EP93XX, 1, [1 if you want ep93xx.]) | |||
else | |||
AC_DEFINE(BUILD_EP93XX, 0, [0 if you don't want ep93xx.]) | |||
fi | |||
if test $parport_use_ppdev = yes; then | |||
AC_DEFINE(PARPORT_USE_PPDEV, 1, [1 if you want parport to use ppdev.]) | |||
else | |||
AC_DEFINE(PARPORT_USE_PPDEV, 0, [0 if you don't want parport to use ppdev.]) | |||
fi | |||
if test $build_bitbang = yes; then | |||
AC_DEFINE(BUILD_BITBANG, 1, [1 if you want a bitbang interface.]) | |||
else | |||
AC_DEFINE(BUILD_BITBANG, 0, [0 if you don't want a bitbang interface.]) | |||
fi | |||
if test $build_ftdi2232 = yes; then | |||
AC_DEFINE(BUILD_FTDI2232, 1, [1 if you want libftdi ft2232.]) | |||
else | |||
AC_DEFINE(BUILD_FTDI2232, 0, [0 if you don't want libftdi ft2232.]) | |||
fi | |||
if test $build_ftd2xx = yes; then | |||
AC_DEFINE(BUILD_FTD2XX, 1, [1 if you want ftd2xx ft2232.]) | |||
else | |||
AC_DEFINE(BUILD_FTD2XX, 0, [0 if you don't want ftd2xx ft2232.]) | |||
fi | |||
if test $build_amtjtagaccel = yes; then | |||
AC_DEFINE(BUILD_AMTJTAGACCEL, 1, [1 if you want the Amontec JTAG-Accelerator driver.]) | |||
else | |||
AC_DEFINE(BUILD_AMTJTAGACCEL, 0, [0 if you don't want the Amontec JTAG-Accelerator driver.]) | |||
fi | |||
case $host in | |||
*-*-cygwin*) | |||
is_cygwin=yes | |||
AC_DEFINE(IS_CYGWIN, 1, [1 if building for Cygwin.]) | |||
;; | |||
*) | |||
AC_DEFINE(IS_CYGWIN, 0, [0 if not building for Cygwin.]) | |||
;; | |||
esac | |||
AM_CONFIG_HEADER(config.h) | |||
AM_INIT_AUTOMAKE(openocd, 0.1) | |||
AM_CONDITIONAL(PARPORT, test $build_parport = yes) | |||
AM_CONDITIONAL(EP93XX, test $build_ep93xx = yes) | |||
AM_CONDITIONAL(BITBANG, test $build_bitbang = yes) | |||
AM_CONDITIONAL(FTDI2232, test $build_ftdi2232 = yes) | |||
AM_CONDITIONAL(FTD2XX, test $build_ftd2xx = yes) | |||
AM_CONDITIONAL(AMTJTAGACCEL, test $build_amtjtagaccel = yes) | |||
AM_CONDITIONAL(IS_CYGWIN, test $is_cygwin = yes) | |||
AM_CONDITIONAL(FTD2XXDIR, test $with_ftd2xx != search) | |||
AC_LANG_C | |||
AC_PROG_CC | |||
AC_PROG_RANLIB | |||
AC_SUBST(WITH_FTD2XX, $with_ftd2xx) | |||
AC_OUTPUT(Makefile src/Makefile src/helper/Makefile src/jtag/Makefile src/xsvf/Makefile src/target/Makefile src/server/Makefile src/flash/Makefile) |
@@ -0,0 +1,26 @@ | |||
#daemon configuration | |||
telnet_port 4444 | |||
gdb_port 3333 | |||
#interface | |||
interface ftdi2232 | |||
jtag_speed 0 | |||
#use combined on interfaces or targets that can't set TRST/SRST separately | |||
reset_config trst_and_srst srst_pulls_trst | |||
#jtag scan chain | |||
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) | |||
jtag_device 4 0x1 0xf 0xe | |||
#target configuration | |||
daemon_startup reset | |||
#target <type> <startup mode> | |||
#target arm7tdmi <reset mode> <chainpos> <endianness> <variant> | |||
target arm7tdmi little run_and_halt 0 arm7tdmi-s_r4 | |||
target_script 0 reset h2294_init.script | |||
run_and_halt_time 0 30 | |||
working_area 0 0x40000000 0x40000 nobackup | |||
#flash configuration | |||
flash bank lpc2000 0x0 0x40000 0 0 lpc2000_v1 0 14765 calc_checksum | |||
flash bank cfi 0x80000000 0x400000 2 2 0 |
@@ -0,0 +1,29 @@ | |||
#daemon configuration | |||
telnet_port 4444 | |||
gdb_port 3333 | |||
#interface | |||
interface ftd2xx | |||
ftd2xx_device_desc "Amontec JTAGkey A" | |||
ftd2xx_layout jtagkey | |||
ftd2xx_vid_pid 0x0403 0xcff8 | |||
jtag_speed 2 | |||
#use combined on interfaces or targets that can't set TRST/SRST separately | |||
reset_config trst_and_srst srst_pulls_trst | |||
#jtag scan chain | |||
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) | |||
jtag_device 4 0x1 0xf 0xe | |||
#target configuration | |||
daemon_startup reset | |||
#target <type> <startup mode> | |||
#target arm7tdmi <reset mode> <chainpos> <endianness> <variant> | |||
target arm7tdmi little run_and_halt 0 arm7tdmi-s_r4 | |||
target_script 0 reset h2294_init.script | |||
run_and_halt_time 0 30 | |||
working_area 0 0x40000000 0x40000 nobackup | |||
#flash configuration | |||
flash bank lpc2000 0x0 0x40000 0 0 lpc2000_v1 0 14765 calc_checksum | |||
flash bank cfi 0x80000000 0x400000 2 2 0 |
@@ -0,0 +1,28 @@ | |||
#daemon configuration | |||
telnet_port 4444 | |||
gdb_port 3333 | |||
#interface | |||
interface parport | |||
parport_port 0x378 | |||
parport_cable wiggler | |||
jtag_speed 0 | |||
#use combined on interfaces or targets that can't set TRST/SRST separately | |||
reset_config trst_and_srst srst_pulls_trst | |||
#jtag scan chain | |||
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) | |||
jtag_device 4 0x1 0xf 0xe | |||
#target configuration | |||
daemon_startup reset | |||
#target <type> <startup mode> | |||
#target arm7tdmi <reset mode> <chainpos> <endianness> <variant> | |||
target arm7tdmi little run_and_halt 0 arm7tdmi-s_r4 | |||
target_script 0 reset h2294_init.script | |||
run_and_halt_time 0 30 | |||
working_area 0 0x40000000 0x40000 nobackup | |||
#flash configuration | |||
flash bank lpc2000 0x0 0x40000 0 0 lpc2000_v1 0 14765 calc_checksum | |||
flash bank cfi 0x80000000 0x400000 2 2 0 |
@@ -0,0 +1,28 @@ | |||
#daemon configuration | |||
telnet_port 4444 | |||
gdb_port 3333 | |||
#interface | |||
interface ftd2xx | |||
ftd2xx_device_desc "Amontec JTAGkey A" | |||
ftd2xx_layout "jtagkey" | |||
ftd2xx_vid_pid 0x0403 0xcff8 | |||
jtag_speed 1 | |||
#use combined on interfaces or targets that can't set TRST/SRST separately | |||
reset_config trst_and_srst | |||
#jtag scan chain | |||
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) | |||
jtag_device 4 0x1 0xf 0xe | |||
#target configuration | |||
daemon_startup reset | |||
#target <type> <endianess> <reset mode> | |||
target arm9tdmi little reset_halt 0 arm920t | |||
working_area 0 0x200000 0x4000 backup | |||
run_and_halt_time 0 5000 | |||
#flash configuration | |||
#flash bank <driver> <base> <size> <chip_width> <bus_width> [driver_options ...] | |||
flash bank cfi 0x10000000 0x800000 2 2 0 | |||
@@ -0,0 +1,12 @@ | |||
#daemon configuration | |||
telnet_port 4444 | |||
gdb_port 3333 | |||
#interface | |||
interface parport | |||
parport_cable chameleon | |||
jtag_speed 0 | |||
#jtag scan chain | |||
# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) | |||
jtag_device 5 0x01 0x1f 0x01 |
@@ -0,0 +1,40 @@ | |||
bin_PROGRAMS = openocd | |||
openocd_SOURCES = openocd.c | |||
# set the include path found by configure | |||
INCLUDES = -I$(top_srcdir)/src/helper \ | |||
-I$(top_srcdir)/src/jtag -I$(top_srcdir)/src/target -I$(top_srcdir)/src/xsvf -I$(top_srcdir)/src/server \ | |||
-I$(top_srcdir)/src/flash $(all_includes) | |||
# the library search path. | |||
openocd_LDFLAGS = $(all_libraries) | |||
SUBDIRS = helper jtag xsvf target server flash | |||
if FTDI2232 | |||
FTDI2232LIB = -lftdi | |||
else | |||
FTDI2232LIB = | |||
endif | |||
if IS_CYGWIN | |||
if FTD2XXDIR | |||
FTD2XXLDADD = @WITH_FTD2XX@/FTD2XX.lib | |||
else | |||
FTD2XXLDADD = -lftd2xx | |||
endif | |||
else | |||
FTD2XXLDADD = -lftd2xx | |||
endif | |||
if FTD2XX | |||
FTD2XXLIB = $(FTD2XXLDADD) | |||
else | |||
FTD2XXLIB = | |||
endif | |||
openocd_LDADD = $(top_builddir)/src/xsvf/libxsvf.a \ | |||
$(top_builddir)/src/target/libtarget.a $(top_builddir)/src/jtag/libjtag.a \ | |||
$(top_builddir)/src/helper/libhelper.a \ | |||
$(top_builddir)/src/server/libserver.a $(top_builddir)/src/helper/libhelper.a \ | |||
$(top_builddir)/src/flash/libflash.a $(top_builddir)/src/target/libtarget.a \ | |||
$(FTDI2232LIB) $(FTD2XXLIB) |
@@ -0,0 +1,5 @@ | |||
INCLUDES = -I$(top_srcdir)/src/helper -I$(top_srcdir)/src/jtag -I$(top_srcdir)/src/target $(all_includes) | |||
METASOURCES = AUTO | |||
noinst_LIBRARIES = libflash.a | |||
libflash_a_SOURCES = flash.c lpc2000.c cfi.c at91sam7.c str7x.c | |||
noinst_HEADERS = flash.h lpc2000.h cfi.h at91sam7.h str7x.h |
@@ -0,0 +1,632 @@ | |||
/*************************************************************************** | |||
* 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 | |||
* | |||
***************************************************************************/ | |||
#include "at91sam7.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_register_commands(struct command_context_s *cmd_ctx); | |||
int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank); | |||
int at91sam7_erase(struct flash_bank_s *bank, int first, int last); | |||
int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last); | |||
int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count); | |||
int at91sam7_probe(struct flash_bank_s *bank); | |||
int at91sam7_erase_check(struct flash_bank_s *bank); | |||
int at91sam7_protect_check(struct flash_bank_s *bank); | |||
int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size); | |||
u32 at91sam7_get_flash_status(flash_bank_t *bank); | |||
void at91sam7_set_flash_mode(flash_bank_t *bank,int mode); | |||
u8 at91sam7_wait_status_busy(flash_bank_t *bank, int timeout); | |||
int at91sam7_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
flash_driver_t at91sam7_flash = | |||
{ | |||
.name = "at91sam7", | |||
.register_commands = at91sam7_register_commands, | |||
.flash_bank_command = at91sam7_flash_bank_command, | |||
.erase = at91sam7_erase, | |||
.protect = at91sam7_protect, | |||
.write = at91sam7_write, | |||
.probe = at91sam7_probe, | |||
.erase_check = at91sam7_erase_check, | |||
.protect_check = at91sam7_protect_check, | |||
.info = at91sam7_info | |||
}; | |||
char * EPROC[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"}; | |||
long NVPSIZ[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[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 */ | |||
}; | |||
u32 at91sam7_get_flash_status(flash_bank_t *bank) | |||
{ | |||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; | |||
target_t *target = at91sam7_info->target; | |||
long fsr; | |||
target->type->read_memory(target, MC_FSR, 4, 1, (u8 *)&fsr); | |||
return fsr; | |||
} | |||
/* Setup the timimg registers for nvbits or normal flash */ | |||
void at91sam7_set_flash_mode(flash_bank_t *bank,int mode) | |||
{ | |||
u32 fmcn, fmr; | |||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; | |||
target_t *target = at91sam7_info->target; | |||
if (mode != at91sam7_info->flashmode) { | |||
/* mainf contains the number of main clocks in approx 500uS */ | |||
if (mode==1) | |||
/* main clocks in 1uS */ | |||
fmcn = (at91sam7_info->mainf>>9)+1; | |||
else | |||
/* main clocks in 1.5uS */ | |||
fmcn = (at91sam7_info->mainf>>9)+(at91sam7_info->mainf>>10)+1; | |||
DEBUG("fmcn: %i", fmcn); | |||
fmr = fmcn<<16; | |||
target->type->write_memory(target, MC_FSR, 4, 1, (u8 *)&fmr); | |||
at91sam7_info->flashmode = mode; | |||
} | |||
} | |||
u8 at91sam7_wait_status_busy(flash_bank_t *bank, int timeout) | |||
{ | |||
u32 status; | |||
while ((!((status = at91sam7_get_flash_status(bank)) & 0x01)) && (timeout-- > 0)) | |||
{ | |||
DEBUG("status: 0x%x", status); | |||
usleep(1000); | |||
} | |||
DEBUG("status: 0x%x", status); | |||
if (status&0x0C) | |||
{ | |||
ERROR("status register: 0x%x", status); | |||
if (status & 0x4) | |||
ERROR("Lock Error Bit Detected, Operation Abort"); | |||
if (status & 0x8) | |||
ERROR("Invalid command and/or bad keyword, Operation Abort"); | |||
if (status & 0x10) | |||
ERROR("Security Bit Set, Operation Abort"); | |||
} | |||
return status; | |||
} | |||
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 = at91sam7_info->target; | |||
fcr = (0x5A<<24) | (pagen<<8) | cmd; | |||
target->type->write_memory(target, MC_FCR, 4, 1, (u8 *)&fcr); | |||
DEBUG("Flash command: 0x%x, pagenumber:", fcr, pagen); | |||
if (at91sam7_wait_status_busy(bank, 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) | |||
{ | |||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; | |||
target_t *target = at91sam7_info->target; | |||
unsigned long cidr, mcfr, status; | |||
if (at91sam7_info->target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
/* Read and parse chip identification register */ | |||
target->type->read_memory(target, DBGU_CIDR, 4, 1, (u8 *)&cidr); | |||
if (cidr == 0) | |||
{ | |||
WARNING("Cannot identify target as an AT91SAM"); | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
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; | |||
bank->size = NVPSIZ[at91sam7_info->cidr_nvpsiz]; | |||
DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch ); | |||
/* Read main clock freqency register */ | |||
target->type->read_memory(target, CKGR_MCFR, 4, 1, (u8 *)&mcfr); | |||
if (mcfr&0x10000) | |||
{ | |||
at91sam7_info->mainrdy = 1; | |||
at91sam7_info->mainf = mcfr&0xFFFF; | |||
at91sam7_info->usec_clocks = mcfr>>9; | |||
} | |||
else | |||
{ | |||
at91sam7_info->mainrdy = 0; | |||
at91sam7_info->mainf = 0; | |||
at91sam7_info->usec_clocks = 0; | |||
} | |||
status = at91sam7_get_flash_status(bank); | |||
at91sam7_info->lockbits = status>>16; | |||
at91sam7_info->securitybit = (status>>4)&0x01; | |||
if (at91sam7_info->cidr_arch == 0x70 ) { | |||
at91sam7_info->num_nvmbits = 2; | |||
at91sam7_info->nvmbits = (status>>8)&0x03; | |||
bank->base = 0x100000; | |||
bank->bus_width = 4; | |||
if (bank->size==0x40000) /* AT91SAM7S256 */ | |||
{ | |||
at91sam7_info->num_lockbits = 16; | |||
at91sam7_info->pagesize = 256; | |||
at91sam7_info->pages_in_lockregion = 64; | |||
at91sam7_info->num_pages = 16*64; | |||
} | |||
if (bank->size==0x20000) /* AT91SAM7S128 */ | |||
{ | |||
at91sam7_info->num_lockbits = 8; | |||
at91sam7_info->pagesize = 256; | |||
at91sam7_info->pages_in_lockregion = 64; | |||
at91sam7_info->num_pages = 8*64; | |||
} | |||
if (bank->size==0x10000) /* AT91SAM7S64 */ | |||
{ | |||
at91sam7_info->num_lockbits = 16; | |||
at91sam7_info->pagesize = 128; | |||
at91sam7_info->pages_in_lockregion = 32; | |||
at91sam7_info->num_pages = 16*32; | |||
} | |||
if (bank->size==0x08000) /* AT91SAM7S321/32 */ | |||
{ | |||
at91sam7_info->num_lockbits = 8; | |||
at91sam7_info->pagesize = 128; | |||
at91sam7_info->pages_in_lockregion = 32; | |||
at91sam7_info->num_pages = 8*32; | |||
} | |||
return ERROR_OK; | |||
} | |||
if (at91sam7_info->cidr_arch == 0x71 ) { | |||
at91sam7_info->num_nvmbits = 2; | |||
at91sam7_info->nvmbits = (status>>8)&0x03; | |||
bank->base = 0x100000; | |||
bank->bus_width = 4; | |||
if (bank->size==0x40000) /* AT91SAM7XC256 */ | |||
{ | |||
at91sam7_info->num_lockbits = 16; | |||
at91sam7_info->pagesize = 256; | |||
at91sam7_info->pages_in_lockregion = 64; | |||
at91sam7_info->num_pages = 16*64; | |||
} | |||
if (bank->size==0x20000) /* AT91SAM7XC128 */ | |||
{ | |||
at91sam7_info->num_lockbits = 8; | |||
at91sam7_info->pagesize = 256; | |||
at91sam7_info->pages_in_lockregion = 64; | |||
at91sam7_info->num_pages = 8*64; | |||
} | |||
return ERROR_OK; | |||
} | |||
if (at91sam7_info->cidr_arch == 0x75 ) { | |||
at91sam7_info->num_nvmbits = 3; | |||
at91sam7_info->nvmbits = (status>>8)&0x07; | |||
bank->base = 0x100000; | |||
bank->bus_width = 4; | |||
if (bank->size==0x40000) /* AT91SAM7X256 */ | |||
{ | |||
at91sam7_info->num_lockbits = 16; | |||
at91sam7_info->pagesize = 256; | |||
at91sam7_info->pages_in_lockregion = 64; | |||
at91sam7_info->num_pages = 16*64; | |||
} | |||
if (bank->size==0x20000) /* AT91SAM7X128 */ | |||
{ | |||
at91sam7_info->num_lockbits = 8; | |||
at91sam7_info->pagesize = 256; | |||
at91sam7_info->pages_in_lockregion = 64; | |||
at91sam7_info->num_pages = 8*64; | |||
} | |||
return ERROR_OK; | |||
} | |||
if (at91sam7_info->cidr_arch != 0x70 ) | |||
{ | |||
WARNING("at91sam7 flash only tested for AT91SAM7Sxx series"); | |||
} | |||
return ERROR_OK; | |||
} | |||
int at91sam7_erase_check(struct flash_bank_s *bank) | |||
{ | |||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; | |||
target_t *target = at91sam7_info->target; | |||
int i; | |||
if (!at91sam7_info->working_area_size) | |||
{ | |||
} | |||
else | |||
{ | |||
} | |||
return ERROR_OK; | |||
} | |||
int at91sam7_protect_check(struct flash_bank_s *bank) | |||
{ | |||
u32 status; | |||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; | |||
target_t *target = at91sam7_info->target; | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
at91sam7_read_part_info(bank); | |||
} | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
WARNING("Cannot identify target as an AT91SAM"); | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
status = at91sam7_get_flash_status(bank); | |||
at91sam7_info->lockbits = status>>16; | |||
return ERROR_OK; | |||
} | |||
int at91sam7_register_commands(struct command_context_s *cmd_ctx) | |||
{ | |||
command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "cfi", NULL, COMMAND_ANY, NULL); | |||
return ERROR_OK; | |||
} | |||
int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) | |||
{ | |||
at91sam7_flash_bank_t *at91sam7_info; | |||
if (argc < 6) | |||
{ | |||
WARNING("incomplete flash_bank at91sam7 configuration"); | |||
return ERROR_FLASH_BANK_INVALID; | |||
} | |||
at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t)); | |||
bank->driver_priv = at91sam7_info; | |||
at91sam7_info->target = get_target_by_num(strtoul(args[5], NULL, 0)); | |||
if (!at91sam7_info->target) | |||
{ | |||
ERROR("no target '%i' configured", args[5]); | |||
exit(-1); | |||
} | |||
/* part wasn't probed for info yet */ | |||
at91sam7_info->cidr = 0; | |||
return ERROR_OK; | |||
} | |||
int at91sam7_erase(struct flash_bank_s *bank, int first, int last) | |||
{ | |||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; | |||
if (at91sam7_info->target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
at91sam7_read_part_info(bank); | |||
} | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
WARNING("Cannot identify target as an AT91SAM"); | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits)) | |||
{ | |||
return ERROR_FLASH_SECTOR_INVALID; | |||
} | |||
if ((first == 0) && (last == (at91sam7_info->num_lockbits-1))) | |||
{ | |||
return at91sam7_flash_command(bank, EA, 0); | |||
} | |||
WARNING("Can only erase the whole flash area, pages are autoerased on write"); | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last) | |||
{ | |||
u32 cmd, pagen, status; | |||
int lockregion; | |||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; | |||
target_t *target = at91sam7_info->target; | |||
if (at91sam7_info->target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits)) | |||
{ | |||
return ERROR_FLASH_SECTOR_INVALID; | |||
} | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
at91sam7_read_part_info(bank); | |||
} | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
WARNING("Cannot identify target as an AT91SAM"); | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
/* Configure the flash controller timing */ | |||
at91sam7_set_flash_mode(bank,1); | |||
for (lockregion=first;lockregion<=last;lockregion++) | |||
{ | |||
pagen = lockregion*at91sam7_info->pages_in_lockregion; | |||
if (set) | |||
cmd = SLB; | |||
else | |||
cmd = CLB; | |||
if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK) | |||
{ | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
} | |||
status = at91sam7_get_flash_status(bank); | |||
at91sam7_info->lockbits = status>>16; | |||
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 = at91sam7_info->target; | |||
u32 dst_min_alignment, wcount, bytes_remaining = count; | |||
u32 first_page, last_page, pagen, buffer_pos; | |||
u32 fcr; | |||
if (at91sam7_info->target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
at91sam7_read_part_info(bank); | |||
} | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
WARNING("Cannot identify target as an AT91SAM"); | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
if (offset + count > bank->size) | |||
return ERROR_FLASH_DST_OUT_OF_BANK; | |||
dst_min_alignment = at91sam7_info->pagesize; | |||
if (offset % dst_min_alignment) | |||
{ | |||
WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment); | |||
return ERROR_FLASH_DST_BREAKS_ALIGNMENT; | |||
} | |||
if (offset + count > bank->size) | |||
return ERROR_FLASH_DST_OUT_OF_BANK; | |||
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); | |||
DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count); | |||
/* Configure the flash controller timing */ | |||
at91sam7_set_flash_mode(bank,2); | |||
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, 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; | |||
} | |||
DEBUG("Flash command: 0x%x, pagenumber:", fcr, 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; | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
at91sam7_read_part_info(bank); | |||
} | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
WARNING("Cannot identify target as an AT91SAM"); | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
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; | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
at91sam7_read_part_info(bank); | |||
} | |||
if (at91sam7_info->cidr == 0) | |||
{ | |||
printed = snprintf(buf, buf_size, "Cannot identify target as an AT91SAM\n"); | |||
buf += printed; | |||
buf_size -= printed; | |||
return ERROR_FLASH_OPERATION_FAILED; | |||
} | |||
printed = snprintf(buf, buf_size, "\nat91sam7 information:\n"); | |||
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); | |||
buf += printed; | |||
buf_size -= printed; | |||
printed = snprintf(buf, buf_size, "main clock(estimated): %ikHz \n", at91sam7_info->mainf*2); | |||
buf += printed; | |||
buf_size -= printed; | |||
if (at91sam7_info->num_lockbits>0) { | |||
printed = snprintf(buf, buf_size, "pagesize: %i, lockbits: %i 0x%4.4x, pages in lock region: %i \n", at91sam7_info->pagesize, at91sam7_info->num_lockbits, at91sam7_info->lockbits,at91sam7_info->num_pages/at91sam7_info->num_lockbits); | |||
buf += printed; | |||
buf_size -= printed; | |||
} | |||
printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->nvmbits); | |||
buf += printed; | |||
buf_size -= printed; | |||
return ERROR_OK; | |||
} |
@@ -0,0 +1,83 @@ | |||
/*************************************************************************** | |||
* 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_H | |||
#define AT91SAM7_H | |||
#include "flash.h" | |||
#include "target.h" | |||
typedef struct at91sam7_flash_bank_s | |||
{ | |||
struct target_s *target; | |||
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; | |||
/* flash geometry */ | |||
u16 num_pages; | |||
u16 pagesize; | |||
u16 pages_in_lockregion; | |||
u8 num_erase_regions; | |||
u32 *erase_region_info; | |||
/* nv memory bits */ | |||
u16 num_lockbits; | |||
u16 lockbits; | |||
u16 num_nvmbits; | |||
u16 nvmbits; | |||
u8 securitybit; | |||
u8 flashmode; /* 0: not init, 1: fmcn for nvbits (1uS), 2: fmcn for flash (1.5uS) */ | |||
/* main clock status */ | |||
u8 mainrdy; | |||
u16 mainf; | |||
u16 usec_clocks; | |||
} at91sam7_flash_bank_t; | |||
/* AT91SAM7 control registers */ | |||
#define DBGU_CIDR 0xFFFFF240 | |||
#define CKGR_MCFR 0xFFFFFC24 | |||
#define MC_FMR 0xFFFFFF60 | |||
#define MC_FCR 0xFFFFFF64 | |||
#define MC_FSR 0xFFFFFF68 | |||
/* 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 | |||
#endif /* AT91SAM7_H */ |
@@ -0,0 +1,86 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2005 by Dominic Rath * | |||
* Dominic.Rath@gmx.de * | |||
* * | |||
* 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 CFI_H | |||
#define CFI_H | |||
#include "flash.h" | |||
#include "target.h" | |||
typedef struct cfi_flash_bank_s | |||
{ | |||
struct target_s *target; | |||
working_area_t *write_algorithm; | |||
working_area_t *erase_check_algorithm; | |||
char qry[3]; | |||
/* identification string */ | |||
u16 pri_id; | |||
u16 pri_addr; | |||
u16 alt_id; | |||
u16 alt_addr; | |||
/* device-system interface */ | |||
u8 vcc_min; | |||
u8 vcc_max; | |||
u8 vpp_min; | |||
u8 vpp_max; | |||
u8 word_write_timeout_typ; | |||
u8 buf_write_timeout_typ; | |||
u8 block_erase_timeout_typ; | |||
u8 chip_erase_timeout_typ; | |||
u8 word_write_timeout_max; | |||
u8 buf_write_timeout_max; | |||
u8 block_erase_timeout_max; | |||
u8 chip_erase_timeout_max; | |||
/* flash geometry */ | |||
u8 dev_size; | |||
u16 interface_desc; | |||
u16 max_buf_write_size; | |||
u8 num_erase_regions; | |||
u32 *erase_region_info; | |||
void *pri_ext; | |||
void *alt_ext; | |||
} cfi_flash_bank_t; | |||
/* Intel primary extended query table | |||
* as defined for the Advanced+ Boot Block Flash Memory (C3) | |||
* and used by the linux kernel cfi driver (as of 2.6.14) | |||
*/ | |||
typedef struct cfi_intel_pri_ext_s | |||
{ | |||
char pri[3]; | |||
u8 major_version; | |||
u8 minor_version; | |||
u32 feature_support; | |||
u8 suspend_cmd_support; | |||
u16 blk_status_reg_mask; | |||
u8 vcc_optimal; | |||
u8 vpp_optimal; | |||
u8 num_protection_fields; | |||
u16 prot_reg_addr; | |||
u8 fact_prot_reg_size; | |||
u8 user_prot_reg_size; | |||
u8 extra[0]; | |||
} cfi_intel_pri_ext_t; | |||
#endif /* CFI_H */ |
@@ -0,0 +1,556 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2005 by Dominic Rath * | |||
* Dominic.Rath@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include "flash.h" | |||
#include "command.h" | |||
#include "log.h" | |||
#include "target.h" | |||
#include <string.h> | |||
#include <unistd.h> | |||
#include <stdlib.h> | |||
#include <sys/types.h> | |||
#include <sys/stat.h> | |||
#include <errno.h> | |||
/* command handlers */ | |||
int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); | |||
/* flash drivers | |||
*/ | |||
extern flash_driver_t lpc2000_flash; | |||
extern flash_driver_t cfi_flash; | |||
extern flash_driver_t at91sam7_flash; | |||
extern flash_driver_t str7x_flash; | |||
flash_driver_t *flash_drivers[] = | |||
{ | |||
&lpc2000_flash, | |||
&cfi_flash, | |||
&at91sam7_flash, | |||
&str7x_flash, | |||
NULL, | |||
}; | |||
flash_bank_t *flash_banks; | |||
static command_t *flash_cmd; | |||
int flash_register_commands(struct command_context_s *cmd_ctx) | |||
{ | |||
flash_cmd = register_command(cmd_ctx, NULL, "flash", NULL, COMMAND_ANY, NULL); | |||
register_command(cmd_ctx, flash_cmd, "bank", handle_flash_bank_command, COMMAND_CONFIG, NULL); | |||
return ERROR_OK; | |||
} | |||
int flash_init(struct command_context_s *cmd_ctx) | |||
{ | |||
if (flash_banks) | |||
{ | |||
register_command(cmd_ctx, flash_cmd, "banks", handle_flash_banks_command, COMMAND_EXEC, | |||
"list configured flash banks "); | |||
register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC, | |||
"print info about flash bank <num>"); | |||
register_command(cmd_ctx, flash_cmd, "probe", handle_flash_probe_command, COMMAND_EXEC, | |||
"identify flash bank <num>"); | |||
register_command(cmd_ctx, flash_cmd, "erase_check", handle_flash_erase_check_command, COMMAND_EXEC, | |||
"check erase state of sectors in flash bank <num>"); | |||
register_command(cmd_ctx, flash_cmd, "protect_check", handle_flash_protect_check_command, COMMAND_EXEC, | |||
"check protection state of sectors in flash bank <num>"); | |||
register_command(cmd_ctx, flash_cmd, "erase", handle_flash_erase_command, COMMAND_EXEC, | |||
"erase sectors at <bank> <first> <last>"); | |||
register_command(cmd_ctx, flash_cmd, "write", handle_flash_write_command, COMMAND_EXEC, | |||
"write binary <bank> <file> <offset>"); | |||
register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC, | |||
"set protection of sectors at <bank> <first> <last> <on|off>"); | |||
} | |||
return ERROR_OK; | |||
} | |||
flash_bank_t *get_flash_bank_by_num(int num) | |||
{ | |||
flash_bank_t *p; | |||
int i = 0; | |||
for (p = flash_banks; p; p = p->next) | |||
{ | |||
if (i++ == num) | |||
{ | |||
return p; | |||
} | |||
} | |||
return NULL; | |||
} | |||
/* flash_bank <driver> <base> <size> <chip_width> <bus_width> [driver_options ...] | |||
*/ | |||
int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) | |||
{ | |||
int i; | |||
int found = 0; | |||
if (argc < 5) | |||
{ | |||
WARNING("incomplete flash_bank configuration"); | |||
return ERROR_OK; | |||
} | |||
for (i = 0; flash_drivers[i]; i++) | |||
{ | |||
if (strcmp(args[0], flash_drivers[i]->name) == 0) | |||
{ | |||
flash_bank_t *p, *c; | |||
/* register flash specific commands */ | |||
if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK) | |||
{ | |||
ERROR("couldn't register '%s' commands", args[0]); | |||
exit(-1); | |||
} | |||
c = malloc(sizeof(flash_bank_t)); | |||
c->driver = flash_drivers[i]; | |||
c->driver_priv = NULL; | |||
c->base = strtoul(args[1], NULL, 0); | |||
c->size = strtoul(args[2], NULL, 0); | |||
c->chip_width = strtoul(args[3], NULL, 0); | |||
c->bus_width = strtoul(args[4], NULL, 0); | |||
c->next = NULL; | |||
if (flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c) != ERROR_OK) | |||
{ | |||
ERROR("'%s' driver rejected flash bank at 0x%8.8x", args[0], c->base); | |||
free(c); | |||
return ERROR_OK; | |||
} | |||
/* put flash bank in linked list */ | |||
if (flash_banks) | |||
{ | |||
/* find last flash bank */ | |||
for (p = flash_banks; p && p->next; p = p->next); | |||
if (p) | |||
p->next = c; | |||
} | |||
else | |||
{ | |||
flash_banks = c; | |||
} | |||
found = 1; | |||
} | |||
} | |||
/* no matching flash driver found */ | |||
if (!found) | |||
{ | |||
ERROR("flash driver '%s' not found", args[0]); | |||
exit(-1); | |||
} | |||
return ERROR_OK; | |||
} | |||
int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) | |||
{ | |||
flash_bank_t *p; | |||
int i = 0; | |||
if (!flash_banks) | |||
{ | |||
command_print(cmd_ctx, "no flash banks configured"); | |||
return ERROR_OK; | |||
} | |||
for (p = flash_banks; p; p = p->next) | |||
{ | |||
command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i", | |||
i++, p->driver->name, p->base, p->size, p->bus_width, p->chip_width); | |||
} | |||
return ERROR_OK; | |||
} | |||
int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) | |||
{ | |||
flash_bank_t *p; | |||
int i = 0; | |||
int j = 0; | |||
if (argc != 1) | |||
{ | |||
command_print(cmd_ctx, "usage: flash info <num>"); | |||
return ERROR_OK; | |||
} | |||
for (p = flash_banks; p; p = p->next) | |||
{ | |||
if (i++ == strtoul(args[0], NULL, 0)) | |||
{ | |||
char buf[1024]; | |||
command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i", | |||
i, p->driver->name, p->base, p->size, p->bus_width, p->chip_width); | |||
for (j = 0; j < p->num_sectors; j++) | |||
{ | |||
char *erase_state, *protect_state; | |||
if (p->sectors[j].is_erased == 0) | |||
erase_state = "not erased"; | |||
else if (p->sectors[j].is_erased == 1) | |||
erase_state = "erased"; | |||
else | |||
erase_state = "erase state unknown"; | |||
if (p->sectors[j].is_protected == 0) | |||
protect_state = "not protected"; | |||
else if (p->sectors[j].is_protected == 1) | |||
protect_state = "protected"; | |||
else | |||
protect_state = "protection state unknown"; | |||
command_print(cmd_ctx, "\t#%i: 0x%8.8x (0x%xkB) %s, %s", | |||
j, p->sectors[j].offset, p->sectors[j].size, | |||
erase_state, protect_state); | |||
} | |||
p->driver->info(p, buf, 1024); | |||
command_print(cmd_ctx, "%s", buf); | |||
} | |||
} | |||
return ERROR_OK; | |||
} | |||
int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) | |||
{ | |||
flash_bank_t *p; | |||
int retval; | |||
if (argc != 1) | |||
{ | |||
command_print(cmd_ctx, "usage: flash probe <num>"); | |||
return ERROR_OK; | |||
} | |||
p = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); | |||
if (p) | |||
{ | |||
if ((retval = p->driver->probe(p)) == ERROR_OK) | |||
{ | |||
command_print(cmd_ctx, "flash '%s' found at 0x%8.8x", p->driver->name, p->base); | |||
} | |||
else if (retval == ERROR_FLASH_BANK_INVALID) | |||
{ | |||
command_print(cmd_ctx, "probing failed for flash bank '#%s' at 0x%8.8x", | |||
args[0], p->base); | |||
} | |||
else | |||
{ | |||
command_print(cmd_ctx, "unknown error when probing flash bank '#%s' at 0x%8.8x", | |||
args[0], p->base); | |||
} | |||
} | |||
else | |||
{ | |||
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); | |||
} | |||
return ERROR_OK; | |||
} | |||
int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) | |||
{ | |||
flash_bank_t *p; | |||
int retval; | |||
if (argc != 1) | |||
{ | |||
command_print(cmd_ctx, "usage: flash erase_check <num>"); | |||
return ERROR_OK; | |||
} | |||
p = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); | |||
if (p) | |||
{ | |||
if ((retval = p->driver->erase_check(p)) == ERROR_OK) | |||
{ | |||
command_print(cmd_ctx, "successfully checked erase state", p->driver->name, p->base); | |||
} | |||
else | |||
{ | |||
command_print(cmd_ctx, "unknown error when checking erase state of flash bank #%s at 0x%8.8x", | |||
args[0], p->base); | |||
} | |||
} | |||
else | |||
{ | |||
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); | |||
} | |||
return ERROR_OK; | |||
} | |||
int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) | |||
{ | |||
flash_bank_t *p; | |||
int retval; | |||
if (argc != 1) | |||
{ | |||
command_print(cmd_ctx, "usage: flash protect_check <num>"); | |||
return ERROR_OK; | |||
} | |||