forked from auracaster/openocd
Compare commits
453 Commits
v0.2.0
...
v0.3.0-rc0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70f735007d | ||
|
|
ce88e8adf7 | ||
|
|
4d17541a2c | ||
|
|
053a763aa6 | ||
|
|
0b882951b7 | ||
|
|
e8dc384be9 | ||
|
|
07c85e41a4 | ||
|
|
c970d03ddb | ||
|
|
eb9790dc91 | ||
|
|
89c1bea931 | ||
|
|
76afa936ba | ||
|
|
39dd68bca6 | ||
|
|
993fe4ab63 | ||
|
|
ad5192a2b9 | ||
|
|
68937cadfb | ||
|
|
068a6c7895 | ||
|
|
ee8e93cb83 | ||
|
|
1020569b9f | ||
|
|
0b476c9f4c | ||
|
|
4a26390eec | ||
|
|
4a91b070ff | ||
|
|
ddade10d4a | ||
|
|
8f3b28ff41 | ||
|
|
d87ee640c7 | ||
|
|
eaebc6cd69 | ||
|
|
592e021543 | ||
|
|
8b30f22dec | ||
|
|
6cb1d10cda | ||
|
|
0cac8b67be | ||
|
|
a07422c26c | ||
|
|
d785f552ee | ||
|
|
19b84dafb0 | ||
|
|
e98817c463 | ||
|
|
2a8aa3b7ef | ||
|
|
0b436497e0 | ||
|
|
75cdc8a260 | ||
|
|
bfefe85645 | ||
|
|
cb854323c9 | ||
|
|
0a1356c9cc | ||
|
|
18aad44f71 | ||
|
|
79f71fad58 | ||
|
|
814183a5c4 | ||
|
|
517e812de3 | ||
|
|
f593ff0a3d | ||
|
|
344bed2f7e | ||
|
|
3537c368fe | ||
|
|
fcf1301e52 | ||
|
|
e996452089 | ||
|
|
1e5daf5886 | ||
|
|
2d45a10dfd | ||
|
|
85bf1627cd | ||
|
|
2783cba810 | ||
|
|
818cedaff3 | ||
|
|
69a6037ce6 | ||
|
|
e895246966 | ||
|
|
a4a1de4dd1 | ||
|
|
62525792e0 | ||
|
|
a02411a15f | ||
|
|
7556a93aed | ||
|
|
a1609e5ad1 | ||
|
|
79e257a209 | ||
|
|
ad75639611 | ||
|
|
e4dba30b63 | ||
|
|
6907ef9d50 | ||
|
|
c70073ef67 | ||
|
|
d243e641d3 | ||
|
|
3cc147efd9 | ||
|
|
53979244b1 | ||
|
|
fb61f52731 | ||
|
|
0388a9c0e5 | ||
|
|
6ec1026bbb | ||
|
|
6726b78707 | ||
|
|
97166327db | ||
|
|
113679ff59 | ||
|
|
557d1b6490 | ||
|
|
89a8a37998 | ||
|
|
76b4ee8935 | ||
|
|
990f50a73b | ||
|
|
5cf0af002c | ||
|
|
73349dc5ac | ||
|
|
c9fbfbd95c | ||
|
|
05d6716936 | ||
|
|
cb7965da15 | ||
|
|
a61b57a87f | ||
|
|
510db585fd | ||
|
|
bc792857a5 | ||
|
|
dd54981702 | ||
|
|
a894c2d8b2 | ||
|
|
4490a42a09 | ||
|
|
44e9200d0a | ||
|
|
1ee8ef4210 | ||
|
|
7afc181e42 | ||
|
|
9b9bc78ef1 | ||
|
|
ed1e45b388 | ||
|
|
5535399a46 | ||
|
|
6a2fd7cad5 | ||
|
|
bc0cc62afd | ||
|
|
79bf27da71 | ||
|
|
4d32b6eee9 | ||
|
|
20c8f64f0a | ||
|
|
1f917bdc0c | ||
|
|
f8cd850c4d | ||
|
|
86cbbe8a4a | ||
|
|
b6c4d1006f | ||
|
|
85398ccdcf | ||
|
|
23c629a85e | ||
|
|
407061eaa6 | ||
|
|
35affce085 | ||
|
|
0ca473468c | ||
|
|
165e3a1468 | ||
|
|
bbd7e22f0b | ||
|
|
b5b4fee811 | ||
|
|
5e837387aa | ||
|
|
9f6c23f479 | ||
|
|
026559068d | ||
|
|
c8d935ab7c | ||
|
|
b23b096c8e | ||
|
|
2d924a59db | ||
|
|
688003cb23 | ||
|
|
8b3bfcfc5b | ||
|
|
5aba621b55 | ||
|
|
a0b1e05b53 | ||
|
|
456ec36795 | ||
|
|
dbf7440148 | ||
|
|
bc13c12be9 | ||
|
|
c3428f5b7a | ||
|
|
8f09c5df85 | ||
|
|
20a3b14828 | ||
|
|
bffe824df6 | ||
|
|
60e24aa597 | ||
|
|
6160a946ec | ||
|
|
5b352c9e79 | ||
|
|
7b650a6abe | ||
|
|
41c1af7c67 | ||
|
|
a8234af06c | ||
|
|
40c9668b70 | ||
|
|
22aff82cae | ||
|
|
4aacf01e19 | ||
|
|
cf7eae176e | ||
|
|
f525f2ef0d | ||
|
|
d75b9ec697 | ||
|
|
6efaa95c44 | ||
|
|
37e9f65f5a | ||
|
|
7252a72465 | ||
|
|
8a162e5e06 | ||
|
|
03c9e48f88 | ||
|
|
cdc33b3808 | ||
|
|
246ff4f601 | ||
|
|
7035b37e71 | ||
|
|
4c450b5c6b | ||
|
|
55f4e430e8 | ||
|
|
f8c8d8bc72 | ||
|
|
f2dc1eeef1 | ||
|
|
b83d79a42f | ||
|
|
dc871f422d | ||
|
|
71bca7640a | ||
|
|
616c154866 | ||
|
|
b4e4532dd2 | ||
|
|
40ac8d7753 | ||
|
|
53dea2f952 | ||
|
|
e4cc19521b | ||
|
|
b1f7b35983 | ||
|
|
a343b18bfb | ||
|
|
0da2f750a1 | ||
|
|
60f8770502 | ||
|
|
7d78021efa | ||
|
|
4119cd6db2 | ||
|
|
39b57471bf | ||
|
|
a2886fe3c6 | ||
|
|
00f2c9e062 | ||
|
|
0d3632adff | ||
|
|
64ec7f66a8 | ||
|
|
7280a52e69 | ||
|
|
7a57c31619 | ||
|
|
7c7467b34f | ||
|
|
16a7ad5799 | ||
|
|
3aa9fabfe9 | ||
|
|
c6b24fb4f0 | ||
|
|
f87985b614 | ||
|
|
16742b529b | ||
|
|
49f3497bfa | ||
|
|
1b90a9f5eb | ||
|
|
84dabdcc72 | ||
|
|
c74ede4248 | ||
|
|
1033633321 | ||
|
|
d340906476 | ||
|
|
e3d82fe24d | ||
|
|
1beb24a61c | ||
|
|
eccd9059d3 | ||
|
|
740fd107f2 | ||
|
|
14be119906 | ||
|
|
7b9f01e0ae | ||
|
|
8624535b80 | ||
|
|
32599fab1a | ||
|
|
aaf1daa056 | ||
|
|
54c16fc56e | ||
|
|
642519649e | ||
|
|
e4de4251fe | ||
|
|
6d4cdddbe2 | ||
|
|
4297209ac9 | ||
|
|
bde4a40422 | ||
|
|
d96e3eae23 | ||
|
|
afc3a5cc6f | ||
|
|
f4fce92f28 | ||
|
|
035b6ba84b | ||
|
|
9bdbffb8cc | ||
|
|
c5949a03a7 | ||
|
|
e3a0647558 | ||
|
|
62b7e1ce64 | ||
|
|
cbe34d0819 | ||
|
|
9a4e650083 | ||
|
|
817ea3f4e4 | ||
|
|
fbbd3066ff | ||
|
|
5c3c4af88f | ||
|
|
2329ae9306 | ||
|
|
f64e924ba9 | ||
|
|
2e210ee48f | ||
|
|
ad43374c7f | ||
|
|
43b3807878 | ||
|
|
1c262c8826 | ||
|
|
37755ffdb6 | ||
|
|
23e22b6ec4 | ||
|
|
22045fa6f2 | ||
|
|
d9ce8a2f60 | ||
|
|
a6d858ebcd | ||
|
|
7393fcfc90 | ||
|
|
6521b75ec2 | ||
|
|
a2a3620d35 | ||
|
|
50b94628ae | ||
|
|
6cba486356 | ||
|
|
b11d79110e | ||
|
|
71af49ca7f | ||
|
|
86a7d813a1 | ||
|
|
0bcf5a6b76 | ||
|
|
108028112f | ||
|
|
d20103cd93 | ||
|
|
48e96a18ed | ||
|
|
24df719b09 | ||
|
|
0c4b119d3f | ||
|
|
75581ffea6 | ||
|
|
965b331d0b | ||
|
|
781997f556 | ||
|
|
01735c515f | ||
|
|
3e87fc20ab | ||
|
|
2d3bcddf04 | ||
|
|
74ae645623 | ||
|
|
7b3be0e21e | ||
|
|
631b2ab244 | ||
|
|
358263f484 | ||
|
|
e961bd14d9 | ||
|
|
9536577c02 | ||
|
|
9655c5b093 | ||
|
|
84f51bf50c | ||
|
|
1dd302883d | ||
|
|
016e7ebbfa | ||
|
|
cb7ad25c04 | ||
|
|
e18bd3b55e | ||
|
|
9b11eebf33 | ||
|
|
45f03dd9b5 | ||
|
|
9542318312 | ||
|
|
6d2473b65b | ||
|
|
f0ddb40ced | ||
|
|
7e4f9ac697 | ||
|
|
388e94d5c1 | ||
|
|
379386743a | ||
|
|
45674af63a | ||
|
|
d4e4d65d28 | ||
|
|
14dc22612b | ||
|
|
5a6980869b | ||
|
|
8e39f86ef4 | ||
|
|
9816f2ecda | ||
|
|
772d8d06ea | ||
|
|
d4607c1f7c | ||
|
|
c4ee12ea77 | ||
|
|
a17eb667a3 | ||
|
|
40f361dd94 | ||
|
|
c993d75d1f | ||
|
|
f6a29d438e | ||
|
|
4f7761828c | ||
|
|
ec3015db1a | ||
|
|
25f9a466ca | ||
|
|
00e900f8a1 | ||
|
|
f89d1cbfd6 | ||
|
|
0dcfbec7fb | ||
|
|
58b78818e0 | ||
|
|
6dd8f37e6d | ||
|
|
9b1a938a22 | ||
|
|
c5f54c5333 | ||
|
|
49d0ea2126 | ||
|
|
9262e0dbdf | ||
|
|
3bade442b1 | ||
|
|
b4acbee47f | ||
|
|
7b5ddb4a58 | ||
|
|
983f5a1ae9 | ||
|
|
aa46b15377 | ||
|
|
8b2b0071a9 | ||
|
|
857c06ca8b | ||
|
|
f6a5749c1b | ||
|
|
5dae4753ff | ||
|
|
57e12b7e45 | ||
|
|
2c76cd7171 | ||
|
|
a690ee3c0c | ||
|
|
0b11e4dbb4 | ||
|
|
b13dbc80e0 | ||
|
|
982ac083f0 | ||
|
|
2e29131f2b | ||
|
|
81b57a3fb6 | ||
|
|
ee329275d3 | ||
|
|
51be978b43 | ||
|
|
ce89c7bf65 | ||
|
|
76b78feef1 | ||
|
|
a89dd2ca65 | ||
|
|
3878b12793 | ||
|
|
cde17a42e9 | ||
|
|
f7f38fa70d | ||
|
|
fbf775c0b7 | ||
|
|
a41725c788 | ||
|
|
bb5f713e44 | ||
|
|
0dd669f2a7 | ||
|
|
2a86a53c3f | ||
|
|
072d6d3db6 | ||
|
|
fbe1c23c12 | ||
|
|
98ae6c24f0 | ||
|
|
ab30d5203c | ||
|
|
d879faa3cb | ||
|
|
4b9bdd664a | ||
|
|
69b8b5e0aa | ||
|
|
ed8fd94d7c | ||
|
|
efef05870d | ||
|
|
a5d02116a6 | ||
|
|
997d5284cb | ||
|
|
ae17ce23eb | ||
|
|
c5145ceb19 | ||
|
|
bb000a6f77 | ||
|
|
32a2c70d3e | ||
|
|
641c574425 | ||
|
|
327ba6cb0a | ||
|
|
e921fead94 | ||
|
|
01000e988a | ||
|
|
fc7cd1d85e | ||
|
|
56a04a3413 | ||
|
|
f36d0083de | ||
|
|
56b346447b | ||
|
|
dce1cdc9fb | ||
|
|
0de530067f | ||
|
|
c87357a33f | ||
|
|
9a9ebfb924 | ||
|
|
11856bcffc | ||
|
|
a5354ff5cb | ||
|
|
34e8c67b1f | ||
|
|
bc075606b7 | ||
|
|
24f011ebb4 | ||
|
|
86b49612a6 | ||
|
|
6f359fba68 | ||
|
|
bd7cbd01e8 | ||
|
|
0c41395fc3 | ||
|
|
7a1ac49ac9 | ||
|
|
8e1d516927 | ||
|
|
696ed5fdc4 | ||
|
|
d11c8e3c8e | ||
|
|
14f2189e1a | ||
|
|
fd4c0f33b1 | ||
|
|
ae4c224459 | ||
|
|
41bb41bb93 | ||
|
|
9df861b0c0 | ||
|
|
1d0b276c9f | ||
|
|
6f7491c1c1 | ||
|
|
0ed5f5afd9 | ||
|
|
bf5f21e39a | ||
|
|
332c8d78d8 | ||
|
|
6336ebb05c | ||
|
|
5c50cf802c | ||
|
|
0a7158140a | ||
|
|
8b73ec8d64 | ||
|
|
afae28fb2c | ||
|
|
ef30f22fd3 | ||
|
|
028e535604 | ||
|
|
c2f593bdc1 | ||
|
|
18d8ac5267 | ||
|
|
57578b4ea3 | ||
|
|
69dd81dcf8 | ||
|
|
1b092a27f0 | ||
|
|
a6f9c5a796 | ||
|
|
a634b5d52e | ||
|
|
bb5086b83e | ||
|
|
7b4428df97 | ||
|
|
ed22097a55 | ||
|
|
a4c7e2dd96 | ||
|
|
5badd9b29a | ||
|
|
35e5e07127 | ||
|
|
1d96a84f06 | ||
|
|
ad23cb97b2 | ||
|
|
2a0e491d9a | ||
|
|
a33e272abd | ||
|
|
b747da2663 | ||
|
|
59b295dbbe | ||
|
|
720c39ba2f | ||
|
|
732df6fea0 | ||
|
|
ad800b1c02 | ||
|
|
84903467ec | ||
|
|
d40fd9e0f4 | ||
|
|
1ee32a8fa1 | ||
|
|
398f60af56 | ||
|
|
9b29b729f3 | ||
|
|
5a824c934f | ||
|
|
e9b919fbc6 | ||
|
|
e31e6a10de | ||
|
|
49e2267f1f | ||
|
|
3bcf8a8a25 | ||
|
|
fc318c0298 | ||
|
|
67dbf35896 | ||
|
|
ad3a24f944 | ||
|
|
431925a452 | ||
|
|
50aa561796 | ||
|
|
31b520c379 | ||
|
|
c7565cc381 | ||
|
|
30b1bbceea | ||
|
|
7986ed5ac2 | ||
|
|
a7a1ae032b | ||
|
|
d460a7cd6c | ||
|
|
4da019edeb | ||
|
|
eea0486263 | ||
|
|
cd0ca916b3 | ||
|
|
55b1ea1d8e | ||
|
|
f703322b3f | ||
|
|
8b994145b8 | ||
|
|
14cbd545bf | ||
|
|
bd4377194e | ||
|
|
4deb8530c6 | ||
|
|
4ebd353ae1 | ||
|
|
1af6b72fc1 | ||
|
|
16e17ab1b3 | ||
|
|
0c2ff267aa | ||
|
|
fdfd434c24 | ||
|
|
00adcc773a | ||
|
|
930269b483 | ||
|
|
421b8e133a | ||
|
|
889bd3e716 | ||
|
|
84e86e9aee | ||
|
|
d2088f0d29 | ||
|
|
f163d0009d | ||
|
|
0165ae4405 | ||
|
|
8b89224c6e | ||
|
|
b71e3aff6d | ||
|
|
309870e414 | ||
|
|
2ff59c9aaf | ||
|
|
e76fe13a95 | ||
|
|
d78d79aff6 | ||
|
|
8b82de60c7 | ||
|
|
1df358855a | ||
|
|
197a195191 | ||
|
|
4eb2e50e4d | ||
|
|
f9c65b5cd5 |
65
.gitignore
vendored
Normal file
65
.gitignore
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# stuff "git status" should ignore
|
||||
|
||||
# build output
|
||||
.libs
|
||||
.deps
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
*.in
|
||||
|
||||
# editor files
|
||||
*.swp
|
||||
|
||||
startup_tcl.c
|
||||
xscale_debug.h
|
||||
|
||||
bin2char
|
||||
bin2char.exe
|
||||
|
||||
doc/openocd.aux
|
||||
doc/openocd.cp
|
||||
doc/openocd.cps
|
||||
doc/openocd.fn
|
||||
doc/openocd.fns
|
||||
doc/openocd.html
|
||||
doc/openocd.info
|
||||
doc/openocd.info-1
|
||||
doc/openocd.info-2
|
||||
doc/openocd.ky
|
||||
doc/openocd.log
|
||||
doc/openocd.pdf
|
||||
doc/openocd.pg
|
||||
doc/openocd.toc
|
||||
doc/openocd.tp
|
||||
doc/openocd.vr
|
||||
doc/texinfo.tex
|
||||
doc/version.texi
|
||||
src/openocd
|
||||
src/openocd.exe
|
||||
|
||||
# configure/autotools output
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.*
|
||||
configure
|
||||
depcomp
|
||||
doxygen
|
||||
doxygen.log
|
||||
Doxyfile
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
Makefile
|
||||
mdate-sh
|
||||
missing
|
||||
stamp-h1
|
||||
stamp-vti
|
||||
INSTALL
|
||||
NOTES
|
||||
|
||||
# Eclipse stuff
|
||||
.project
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "tools/git2cl"]
|
||||
path = tools/git2cl
|
||||
url = git://repo.or.cz/git2cl.git
|
||||
11
BUGS
11
BUGS
@@ -22,7 +22,7 @@ that may be important.
|
||||
- If the report is for a regression:
|
||||
- Include logs for both working and broken versions.
|
||||
- Find the precise version that caused the regression by binary search.
|
||||
For example: if testing version 550 works but 600 fail, then try 575, etc.
|
||||
You can use "git bisect" to expedite this binary search.
|
||||
|
||||
If possible, please develop and attach a patch that helps to expose or
|
||||
solve the reported problem. See the PATCHES file for more information
|
||||
@@ -34,8 +34,15 @@ in total.
|
||||
|
||||
@section bugscrashdump Obtaining Crash Backtraces
|
||||
|
||||
If OpenOCD is crashing, you can use GDB to get a trace:@par
|
||||
If OpenOCD is crashing, there are two very effective things you can do to
|
||||
improve your chances of getting help on the development mailing list.
|
||||
|
||||
Try to reproduce the problem using the dummy JTAG interface to allow other developers to replicate
|
||||
your problem robustly and use GDB to get a trace:@par
|
||||
@code
|
||||
% OPENOCDSRC/configure --enable-dummy ...
|
||||
% openocd -f interface/dummy.cfg -f target/xxx.cfg
|
||||
=> SEGFAULT
|
||||
% gdb --args openocd ....
|
||||
(gdb) run
|
||||
(gdb) bt
|
||||
|
||||
106
NEWS
106
NEWS
@@ -1,79 +1,57 @@
|
||||
The OpenOCD 0.2.0 source archive release includes numerous improvements
|
||||
that were made since the initial 0.1.0 source archive release. Many
|
||||
contributors helped make this release a great success, and the community
|
||||
of developers and maintainers look forward to any response.
|
||||
|
||||
In addition to the list of changes below, countless bug fixing and
|
||||
cleaning was performed across the tree. Various TCL command parameters
|
||||
must past stricter value checks, and many more error conditions have
|
||||
been handled correctly. These efforts helped to make the 0.2.0 release
|
||||
more stable and robust, though some changes may expose latent bugs in
|
||||
your existing configuration scripts.
|
||||
|
||||
This release does not maintain backward compatibility in all respects,
|
||||
so some target or configuration scripts may need to be updated. In some
|
||||
cases, you may also see warnings; resolve those, because they indicate
|
||||
commands that will be removed in the future.
|
||||
|
||||
The following areas of OpenOCD functionality changed in this release:
|
||||
This file should include highlights of the changes made in the
|
||||
OpenOCD openocd-0.3.0 source archive release. See the repository
|
||||
history for details about what changed, including bugfixes and
|
||||
other issues not mentioned here.
|
||||
|
||||
JTAG Layer:
|
||||
- Improves modularity: core, TCL, driver commands, and interface have
|
||||
been separated, encapsulated, and documented for developers. Mostly.
|
||||
- Improves JTAG TAP transition tables:
|
||||
* Makes TAP paths variable length, rather than being fixed at 7 steps.
|
||||
* Fixes problems with some targets that did not like longer paths.
|
||||
- Improves JTAG driver/minidriver modularity and encapsulation.
|
||||
- New drivers:
|
||||
* Adds stub minidriver for developing new embedded JTAG interfaces.
|
||||
- Improves drivers:
|
||||
* ft2232+ftd2xx:
|
||||
+ Adds initial high-speed device support: --enable-ftd2xx-highspeed
|
||||
+ Supports more types of FTDI-based devices.
|
||||
* jlink:
|
||||
+ Works with more versions of the firmware (v3 and newer)
|
||||
+ Supports dynamically detects device capabilities and limits
|
||||
* vsllink:
|
||||
+ Supports very long scan chains
|
||||
* amtjtagaccel:
|
||||
+ Fixes broken ID code detection problems.
|
||||
FT2232H (high speed USB) support doesn't need separate configuration
|
||||
New reset_config options for SRST gating the JTAG clock (or not)
|
||||
TAP declaration no longer requires ircapture and mask attributes
|
||||
New "post-reset" event handler for TAP-invariant setup code
|
||||
Overridable Tcl "init_reset" and "jtag_init" procedures
|
||||
|
||||
Target Layer:
|
||||
- New devices: AVR, FA526
|
||||
- Improved support: ARM ADI, ARM11, MIPS
|
||||
- Numerous other bug fixes and improvements
|
||||
New commands for use with Cortex-M3 processors:
|
||||
"cortex_m3 disassemble" ... Thumb2 disassembly (UAL format)
|
||||
"cortex_m3 vector_catch" ... traps certain hardware faults
|
||||
without tying up breakpoint resources
|
||||
If you're willing to help debug it
|
||||
VERY EARLY Cortex-A8 and ARMv7A support
|
||||
Updated BeagleBoard.org hardware support
|
||||
New commands for use with XScale processors: "xscale vector_table"
|
||||
ARM9
|
||||
name change: "arm9 vector_catch" not "arm9tdmi vector_catch"
|
||||
ARM11
|
||||
single stepping support for i.MX31
|
||||
bugfix for missing "arm11" prefix on "arm11 memwrite ..."
|
||||
ETM support
|
||||
Unavailable registers are not listed
|
||||
|
||||
Flash Layer:
|
||||
- Improved drivers: mflash
|
||||
- New drivers: AT91SAM3, AVR, Davinci NAND
|
||||
The lpc2000 driver handles the new NXP LPC1700 (Cortex-M3) chips
|
||||
New lpc2900 driver for NXP LPC2900 chips (ARM968 based)
|
||||
New "last" flag for NOR "flash erase_sector" and "flash protect"
|
||||
The "nand erase N" command now erases all of bank N
|
||||
|
||||
Board, Interface, and Target Configuration Scripts:
|
||||
- Many new and improved targets and boards are now available.
|
||||
- Better separation of "board" and "target" configuration
|
||||
- Moved all TCL files to top-level "tcl" directory in the source tree
|
||||
- Installation moved from '$pkglibdir/' to '$pkgdatadir/scripts/'.
|
||||
- Site-specific files should be installed under '$pkgdatadir/site/';
|
||||
files that exist this tree will be used in preference to default
|
||||
distribution configurations in '$pkgdatadir/scripts/'.
|
||||
Board, Target, and Interface Configuration Scripts:
|
||||
Amontec JTAGkey2 support
|
||||
Cleanup and additions for the TI/Luminary Stellaris scripts
|
||||
LPC1768 target (and flash) support
|
||||
Keil MCB1700 eval board
|
||||
Samsung s3c2450
|
||||
Mini2440 board
|
||||
Numeric TAP and Target identifiers now trigger warnings
|
||||
PXA255 partially enumerates
|
||||
|
||||
Documentation:
|
||||
- Updated User Guide: http://openocd.berlios.de/doc/html/index.html
|
||||
* Partially re-written and re-organized.
|
||||
* Standardized presentation for all commands.
|
||||
* Covers many drivers and commands that were previously omitted.
|
||||
* New index for commands and drivers.
|
||||
- Added Developer Manual: http://openocd.berlios.de/doc/doxygen/index.html
|
||||
* Now includes architecture, technical primers, style guides, and more.
|
||||
* Available in-tree and on-line.
|
||||
Capture more debugging and setup advice
|
||||
Notes on target source code changes that may help debugging
|
||||
|
||||
Build and Release:
|
||||
- Increased configuration and compilation warning coverage.
|
||||
* Use --disable-werror to work around build errors caused by warnings.
|
||||
- Use libtool to produce helper libraries as a step toward "libopenocd".
|
||||
- New processes and scripting to facilitate future source releases.
|
||||
|
||||
For more details about what has changed since 0.1.0, see the ChangeLog
|
||||
associated with this release.
|
||||
For more details about what has changed since the last release,
|
||||
see the ChangeLog associated with this source archive. For older NEWS,
|
||||
see the NEWS files associated with each release (i.e. NEWS-<version>).
|
||||
|
||||
For more information about contributing test reports, bug fixes, or new
|
||||
features and device support, please read the new Developer Manual (or
|
||||
|
||||
80
NEWS-0.2.0
Normal file
80
NEWS-0.2.0
Normal file
@@ -0,0 +1,80 @@
|
||||
The OpenOCD 0.2.0 source archive release includes numerous improvements
|
||||
that were made since the initial 0.1.0 source archive release. Many
|
||||
contributors helped make this release a great success, and the community
|
||||
of developers and maintainers look forward to any response.
|
||||
|
||||
In addition to the list of changes below, countless bug fixing and
|
||||
cleaning was performed across the tree. Various TCL command parameters
|
||||
must past stricter value checks, and many more error conditions have
|
||||
been handled correctly. These efforts helped to make the 0.2.0 release
|
||||
more stable and robust, though some changes may expose latent bugs in
|
||||
your existing configuration scripts.
|
||||
|
||||
This release does not maintain backward compatibility in all respects,
|
||||
so some target or configuration scripts may need to be updated. In some
|
||||
cases, you may also see warnings; resolve those, because they indicate
|
||||
commands that will be removed in the future.
|
||||
|
||||
The following areas of OpenOCD functionality changed in this release:
|
||||
|
||||
JTAG Layer:
|
||||
- Improves modularity: core, TCL, driver commands, and interface have
|
||||
been separated, encapsulated, and documented for developers. Mostly.
|
||||
- Improves JTAG TAP transition tables:
|
||||
* Makes TAP paths variable length, rather than being fixed at 7 steps.
|
||||
* Fixes problems with some targets that did not like longer paths.
|
||||
- Improves JTAG driver/minidriver modularity and encapsulation.
|
||||
- New drivers:
|
||||
* Adds stub minidriver for developing new embedded JTAG interfaces.
|
||||
- Improves drivers:
|
||||
* ft2232+ftd2xx:
|
||||
+ Adds initial high-speed device support: --enable-ftd2xx-highspeed
|
||||
+ Supports more types of FTDI-based devices.
|
||||
* jlink:
|
||||
+ Works with more versions of the firmware (v3 and newer)
|
||||
+ Supports dynamically detects device capabilities and limits
|
||||
* vsllink:
|
||||
+ Supports very long scan chains
|
||||
* amtjtagaccel:
|
||||
+ Fixes broken ID code detection problems.
|
||||
|
||||
Target Layer:
|
||||
- New devices: AVR, FA526
|
||||
- Improved support: ARM ADI, ARM11, MIPS
|
||||
- Numerous other bug fixes and improvements
|
||||
|
||||
Flash Layer:
|
||||
- Improved drivers: mflash
|
||||
- New drivers: AT91SAM3, AVR, Davinci NAND
|
||||
|
||||
Board, Interface, and Target Configuration Scripts:
|
||||
- Many new and improved targets and boards are now available.
|
||||
- Better separation of "board" and "target" configuration
|
||||
- Moved all TCL files to top-level "tcl" directory in the source tree
|
||||
- Installation moved from '$pkglibdir/' to '$pkgdatadir/scripts/'.
|
||||
- Site-specific files should be installed under '$pkgdatadir/site/';
|
||||
files that exist this tree will be used in preference to default
|
||||
distribution configurations in '$pkgdatadir/scripts/'.
|
||||
|
||||
Documentation:
|
||||
- Updated User Guide: http://openocd.berlios.de/doc/html/index.html
|
||||
* Partially re-written and re-organized.
|
||||
* Standardized presentation for all commands.
|
||||
* Covers many drivers and commands that were previously omitted.
|
||||
* New index for commands and drivers.
|
||||
- Added Developer Manual: http://openocd.berlios.de/doc/doxygen/index.html
|
||||
* Now includes architecture, technical primers, style guides, and more.
|
||||
* Available in-tree and on-line.
|
||||
|
||||
Build and Release:
|
||||
- Increased configuration and compilation warning coverage.
|
||||
* Use --disable-werror to work around build errors caused by warnings.
|
||||
- Use libtool to produce helper libraries as a step toward "libopenocd".
|
||||
- New processes and scripting to facilitate future source releases.
|
||||
|
||||
For more details about what has changed since 0.1.0, see the ChangeLog
|
||||
associated with this release.
|
||||
|
||||
For more information about contributing test reports, bug fixes, or new
|
||||
features and device support, please read the new Developer Manual (or
|
||||
the BUGS and PATCHES files in the source archive).
|
||||
16
PATCHES
16
PATCHES
@@ -9,9 +9,8 @@ you're a member, despite what the list info page says.
|
||||
|
||||
@section Patch Guidelines in a Nutshell
|
||||
|
||||
The patch should be against svn trunk using an SVN
|
||||
diff. If you use git-svn, a git diff or patch is OK
|
||||
too; likewise a quilt patch, if you use quilt.
|
||||
Your patches should be against git mainline. Submit output
|
||||
of "git diff"; equivalently, quilt patches are OK.
|
||||
|
||||
It should be a "good patch": focus it on a single
|
||||
issue, and make it be easily reviewable. Don't make
|
||||
@@ -34,18 +33,9 @@ Add yourself to the GPL copyright for non-trivial changes.
|
||||
|
||||
To create a patch from the command line:
|
||||
@code
|
||||
svn diff >mypatch.txt
|
||||
git diff >mypatch.txt
|
||||
@endcode
|
||||
|
||||
See: @par
|
||||
http://svnbook.red-bean.com/en/1.0/re09.html
|
||||
|
||||
Remember to use "svn add" on new files first: @par
|
||||
http://svnbook.red-bean.com/en/1.0/re01.html
|
||||
|
||||
If you have a decent SVN GUI, then that should be
|
||||
able to create and apply patches as well...
|
||||
|
||||
@section More Information on Patching
|
||||
|
||||
The @ref primerpatches provides a more complete guide to creating,
|
||||
|
||||
89
README
89
README
@@ -64,17 +64,23 @@ you can build the in-tree documentation.
|
||||
Installing OpenOCD
|
||||
==================
|
||||
|
||||
On Linux, you may have permissions problems to address. The best
|
||||
way to do this is to use the contrib/udev.rules file. It probably
|
||||
belongs somewhere in /etc/udev/rules.d, but consult your operating
|
||||
system documentation to be sure. In particular, make sure that it
|
||||
matches the syntax used by your operating system's version of udev.
|
||||
|
||||
A Note to OpenOCD Users
|
||||
-----------------------
|
||||
|
||||
If you would rather be working "with" OpenOCD rather than "on" it, your
|
||||
operating system or interface supplier may provide binaries for you in a
|
||||
convenient package.
|
||||
operating system or JTAG interface supplier may provide binaries for
|
||||
you in a convenient-enough package.
|
||||
|
||||
Such packages should be more stable than SVN trunk, where bleeding-edge
|
||||
Such packages may be more stable than git mainline, where bleeding-edge
|
||||
development takes place. These "Packagers" produce binary releases of
|
||||
OpenOCD after the developers produces new "stable" versions of the
|
||||
source code. Previous versions of OpenOCD cannot be used to diagnosed
|
||||
OpenOCD after the developers produces new "release" versions of the
|
||||
source code. Previous versions of OpenOCD cannot be used to diagnose
|
||||
problems with the current release, so users are encouraged to keep in
|
||||
contact with their distribution package maintainers or interface vendors
|
||||
to ensure suitable upgrades appear regularly.
|
||||
@@ -119,7 +125,7 @@ Building OpenOCD
|
||||
The INSTALL file contains generic instructions for running 'configure'
|
||||
and compiling the OpenOCD source code. That file is provided by default
|
||||
for all GNU automake packages. If you are not familiar with the GNU
|
||||
autotools, then you should read those instructions first.
|
||||
autotools, then you should read those instructions first.
|
||||
|
||||
The remainder of this document tries to provide some instructions for
|
||||
those looking for a quick-install.
|
||||
@@ -157,7 +163,7 @@ To build OpenOCD (on both Linux and Cygwin), use the following sequence
|
||||
of commands:
|
||||
|
||||
./configure [with some options listed in the next section]
|
||||
make
|
||||
make
|
||||
make install
|
||||
|
||||
The 'configure' step generates the Makefiles required to build OpenOCD,
|
||||
@@ -174,7 +180,7 @@ the 'configure' script. For example, you can configure OpenOCD to
|
||||
cross-compile on a x86 Linux host to run on Windows (MinGW32), you could
|
||||
use the following configuration options:
|
||||
|
||||
./configure --build=i686-pc-linux-gnu --host=i586-mingw32msvc ...
|
||||
./configure --build=i686-pc-linux-gnu --host=i586-mingw32msvc ...
|
||||
|
||||
Likewise, the following options allow OpenOCD to be cross-compiled for
|
||||
an ARM target on the same x86 host:
|
||||
@@ -199,7 +205,7 @@ options may be available there:
|
||||
|
||||
--enable-maintainer-mode enable make rules and dependencies not useful
|
||||
(and sometimes confusing) to the casual installer
|
||||
NOTE: This option is *required* for SVN builds!
|
||||
NOTE: This option is *required* for GIT builds!
|
||||
It should *not* be used to build a release.
|
||||
|
||||
--enable-dummy Enable building the dummy JTAG port driver
|
||||
@@ -209,9 +215,6 @@ options may be available there:
|
||||
FTD2XX
|
||||
--enable-ft2232_ftd2xx Enable building support for FT2232 based devices
|
||||
using the FTD2XX driver from ftdichip.com
|
||||
--enable-ftd2xx-highspeed
|
||||
Enable building support for FT2232H and
|
||||
FT4232H-based devices (requires >=libftd2xx-0.4.16)
|
||||
|
||||
--enable-gw16012 Enable building support for the Gateworks GW16012
|
||||
JTAG Programmer
|
||||
@@ -295,12 +298,12 @@ have to use both the --enable-parport AND the --enable-parport-giveio
|
||||
option if you want to use giveio instead of ioperm parallel port access
|
||||
method.
|
||||
|
||||
FT2232C Based USB Dongles
|
||||
FT2232C Based USB Dongles
|
||||
-------------------------
|
||||
|
||||
There are 2 methods of using the FTD2232, either (1) using the
|
||||
FTDICHIP.COM closed source driver, or (2) the open (and free) driver
|
||||
libftdi.
|
||||
libftdi.
|
||||
|
||||
Using LIBFTDI
|
||||
-------------
|
||||
@@ -314,7 +317,7 @@ installed. To use the newer FT2232H chips, supporting RTCK and USB high
|
||||
speed (480 Mbps), you need libftdi version 0.16 or newer. Many Linux
|
||||
distributions provide suitable packages for these libraries.
|
||||
|
||||
For Windows, libftdi is supported with versions 0.14 and later.
|
||||
For Windows, libftdi is supported with versions 0.14 and later.
|
||||
|
||||
With these prerequisites met, configure the libftdi solution like this:
|
||||
|
||||
@@ -325,7 +328,7 @@ Then type ``make'', and perhaps ``make install''.
|
||||
Using FTDI's FTD2XX
|
||||
-------------------
|
||||
|
||||
Some claim the (closed) FTDICHIP.COM solution is faster, which
|
||||
The (closed source) FTDICHIP.COM solution is faster on MS-Windows. That
|
||||
is the motivation for supporting it even though its licensing restricts
|
||||
it to non-redistributable OpenOCD binaries, and it is not available for
|
||||
all operating systems used with OpenOCD. You may, however, build such
|
||||
@@ -334,7 +337,7 @@ copies for personal use.
|
||||
The FTDICHIP drivers come as either a (win32) ZIP file, or a (Linux)
|
||||
TAR.GZ file. You must unpack them ``some where'' convient. As of this
|
||||
writing FTDICHIP does not supply means to install these files "in an
|
||||
appropriate place."
|
||||
appropriate place."
|
||||
|
||||
If your distribution does not package these, there are several
|
||||
'./configure' options to solve this problem:
|
||||
@@ -355,7 +358,7 @@ Windows or Linux FTD2xx drivers from the following location:
|
||||
Remember, this library is binary-only, while OpenOCD is licenced
|
||||
according to GNU GPLv2 without any exceptions. That means that
|
||||
_distributing_ copies of OpenOCD built with the FTDI code would violate
|
||||
the OpenOCD licensing terms.
|
||||
the OpenOCD licensing terms.
|
||||
|
||||
Linux Notes
|
||||
***********
|
||||
@@ -370,32 +373,48 @@ the following:
|
||||
--with-ft2xx-linux-tardir=../libftd2xx0.4.16 \
|
||||
... other options ...
|
||||
|
||||
=================================
|
||||
Obtaining OpenOCD From Subversion
|
||||
---------------------------------
|
||||
Note that on Linux there is no good reason to use these FTDI binaries;
|
||||
they are no faster (on Linux) than libftdi, and cause licensing issues.
|
||||
|
||||
You can download the current SVN version with an SVN client of your
|
||||
choice from the following repositories:
|
||||
==========================
|
||||
Obtaining OpenOCD From GIT
|
||||
==========================
|
||||
|
||||
svn://svn.berlios.de/openocd/trunk
|
||||
or
|
||||
http://svn.berlios.de/svnroot/repos/openocd/trunk
|
||||
You can download the current GIT version with a GIT client of your
|
||||
choice from the main repository:
|
||||
|
||||
Using the SVN command line client, you can use the following command to
|
||||
fetch the latest version (make sure there is no (non-svn) directory
|
||||
called "openocd" in the current directory):
|
||||
git://openocd.git.sourceforge.net/gitroot/openocd/openocd
|
||||
|
||||
svn checkout svn://svn.berlios.de/openocd/trunk openocd
|
||||
You may prefer to use a mirror:
|
||||
|
||||
If you prefer GIT based tools, the git-svn package works too:
|
||||
http://repo.or.cz/r/openocd.git
|
||||
git://repo.or.cz/openocd.git
|
||||
|
||||
git svn clone -s svn://svn.berlios.de/openocd
|
||||
Using the GIT command line client, you might use the following command
|
||||
to set up a local copy of the current repository (make sure there is no
|
||||
directory called "openocd" in the current directory):
|
||||
|
||||
Tips For Building From The Subversion Repository
|
||||
************************************************
|
||||
git clone git://openocd.git.sourceforge.net/gitroot/openocd/openocd
|
||||
|
||||
Then you can update that at your convenience using
|
||||
|
||||
git pull
|
||||
|
||||
There is also a gitweb interface, which you can use either to browse
|
||||
the repository or to downlad arbitrary snapshots using HTTP:
|
||||
|
||||
http://openocd.git.sourceforge.net/git/gitweb.cgi?p=openocd/openocd
|
||||
http://repo.or.cz/w/openocd.git
|
||||
|
||||
Snapshots are compressed tarballs of the source tree, about 1.3 MBytes
|
||||
each at this writing.
|
||||
|
||||
|
||||
Tips For Building From a GIT Repository
|
||||
---------------------------------------
|
||||
|
||||
Building OpenOCD from a repository requires a recent version of the GNU
|
||||
autotools (autoconf >= 2.59 and automake >= 1.9).
|
||||
autotools (autoconf >= 2.59 and automake >= 1.9).
|
||||
|
||||
1) Run './bootstrap' to create the 'configure' script and prepare
|
||||
the build process for your host system.
|
||||
|
||||
@@ -40,7 +40,8 @@ Take note that different Linux distributions often have different MinGW
|
||||
installation directory. Some of them also put the library and include
|
||||
into a separate sys-root directory.
|
||||
|
||||
If there is a new svn version of libusb-win32, you can build it as well.
|
||||
When the libusb-win32 repository is more current than its release code,
|
||||
you could build that instead.
|
||||
|
||||
These are the instruction from the libusb-win32 Makefile:
|
||||
|
||||
@@ -93,5 +94,5 @@ To use ftd2xx:
|
||||
--with-ftd2xx-win32-zipdir=/path/to/libftd2xx-win32 \
|
||||
... other options ...
|
||||
|
||||
If you are using the SVN repository, see the README file for additional
|
||||
If you are using the GIT repository, see the README file for additional
|
||||
instructions about configuring and building OpenOCD.
|
||||
|
||||
99
TODO
99
TODO
@@ -23,6 +23,10 @@ This section provides possible things to improve with OpenOCD's TCL support.
|
||||
- provide more directory structure for boards/targets?
|
||||
- factor configurations into layers (encapsulation and re-use)
|
||||
|
||||
- Fix handling of variables between multiple command line "-c" and "-f"
|
||||
parameters. Currently variables assigned through one such parameter
|
||||
command/script are unset before the next one is invoked.
|
||||
|
||||
- Isolate all TCL command support:
|
||||
- Pure C CLI implementations using --disable-builtin-tcl.
|
||||
- Allow developers to build new dongles using OpenOCD's JTAG core.
|
||||
@@ -39,22 +43,48 @@ This section list issues that need to be resolved in the JTAG layer.
|
||||
|
||||
@subsection thelistjtagcore JTAG Core
|
||||
|
||||
The following tasks have been suggeted for cleaning up the JTAG layer:
|
||||
The following tasks have been suggested for cleaning up the JTAG layer:
|
||||
|
||||
- use tap_set_state everywhere to allow logging TAP state transitions
|
||||
- rename other tap_states to use standard JTAG names (suggested by ML)
|
||||
- Encapsulate cmd_queue_cur_state and related varaible handling.
|
||||
- add slick 32 bit versions of jtag_add_xxx_scan() that avoids
|
||||
buf_set_u32() calls and other evidence of poor impedance match between
|
||||
API and calling code. New API should cut down # of lines in calling
|
||||
code by 100's and make things clearer. Also potentially be supported
|
||||
directly in minidriver API for better embedded host performance.
|
||||
|
||||
The following tasks have been suggested for adding new core JTAG support:
|
||||
|
||||
- autodetect devices present on the scan chain
|
||||
- implement 'discover_taps' command
|
||||
- Improve autodetection of TAPs by supporting tcl escape procedures that
|
||||
can configure discovered TAPs based on IDCODE value ... they could:
|
||||
- Remove guessing for irlen
|
||||
- Allow non-default irmask/ircapture values
|
||||
- SPI/UART emulation:
|
||||
- (ab)use bit-banging JTAG interfaces to emulate SPI/UART
|
||||
- allow SPI to program flash, MCUs, etc.
|
||||
|
||||
@subsection thelistjtaginterfaces JTAG Interfaces
|
||||
|
||||
There are some known bugs to fix in JTAG adapter drivers:
|
||||
|
||||
- For JTAG_STATEMOVE to TAP_RESET, all drivers must ignore the current
|
||||
recorded state. The tap_get_state() call won't necessarily return
|
||||
the correct value, especially at server startup. Fix is easy: in
|
||||
that case, always issue five clocks with TMS high.
|
||||
- amt_jtagaccel.c
|
||||
- arm-jtag-ew.c
|
||||
- bitbang.c
|
||||
- bitq.c
|
||||
- gw16012.c
|
||||
- jlink.c
|
||||
- usbprog.c
|
||||
- vsllink.c
|
||||
- rlink/rlink.c
|
||||
- bug: USBprog is broken with new tms sequence; it needs 7-clock cycles.
|
||||
Fix promised from Peter Denison openwrt at marshadder.org
|
||||
Workaround: use "tms_sequence long" @par
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-July/009426.html
|
||||
|
||||
The following tasks have been suggeted for improving OpenOCD's JTAG
|
||||
interface support:
|
||||
|
||||
@@ -64,12 +94,21 @@ interface support:
|
||||
- J-Link driver:
|
||||
- fix to work with long scan chains, such as R.Doss's svf test.
|
||||
- FT2232 (libftdi):
|
||||
- make performance comparable to alternatives
|
||||
- make performance comparable to alternatives (on Win32, D2XX is faster)
|
||||
- make usability comparable to alternatives
|
||||
- Autodetect USB based adapters; this should be easy on Linux. If there's
|
||||
more than one, list the options; otherwise, just select that one.
|
||||
|
||||
The following tasks have been suggested for adding new JTAG interfaces:
|
||||
|
||||
- TCP driver: allow client/server for remote JTAG interface control.
|
||||
This requires a client and a server. The server is built into the
|
||||
normal OpenOCD and takes commands from the client and executes
|
||||
them on the interface returning the result of TCP/IP. The client
|
||||
is an OpenOCD which is built with a TCP/IP minidriver. The use
|
||||
of a minidriver is required to capture all the jtag_add_xxx()
|
||||
fn's at a high enough level and repackage these cmd's as
|
||||
TCP/IP packets handled by the server.
|
||||
|
||||
@section thelistswd Serial Wire Debug
|
||||
|
||||
@@ -98,24 +137,38 @@ Once the above are completed:
|
||||
|
||||
@section thelisttargets Target Support
|
||||
|
||||
- Many common ARM cores could be autodetected using IDCODE
|
||||
- general layer cleanup: @par
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-May/006590.html
|
||||
- regression: xscale does not place debug_handler.bin into the right spot. workaround:
|
||||
use -s option on command line to place xscale/debug_handler.bin in search path @par
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-July/009338.html
|
||||
- bug: either USBprog is broken with new tms sequence or there is a general
|
||||
problem with XScale and the new tms sequence. Workaround: use "tms_sequence long"
|
||||
@par
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-July/009426.html
|
||||
- regression: "reset halt" between 729(works) and 788(fails): @par
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-July/009206.html
|
||||
- ARM923EJS:
|
||||
- ARM7/9:
|
||||
- clean up "arm9tdmi vector_catch". Available for some arm7 cores? @par
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-October/011488.html
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-October/011506.html
|
||||
- add reset option to allow programming embedded ice while srst is asserted.
|
||||
Some CPUs will gate the JTAG clock when srst is asserted and in this case,
|
||||
it is necessary to program embedded ice and then assert srst afterwards.
|
||||
- ARM926EJS:
|
||||
- reset run/halt/step is not robust; needs testing to map out problems.
|
||||
- ARM11 improvements (MB?)
|
||||
- fix single stepping (reported by <20>H)
|
||||
- add support for asserting srst to reset the core.
|
||||
- Single stepping works, but should automatically
|
||||
use hardware stepping if available.
|
||||
- mdb can return garbage data if read byte operation fails for
|
||||
a memory region(16 & 32 byte access modes may be supported). Is this
|
||||
a bug in the .MX31 PDK init script? Try on i.MX31 PDK:
|
||||
mdw 0xb80005f0 0x8, mdh 0xb80005f0 0x10, mdb 0xb80005f0 0x20. mdb returns
|
||||
garabage.
|
||||
- implement missing functionality (grep FNC_INFO_NOTIMPLEMENTED ...)
|
||||
- thumb support is missing: ISTR ARMv6 requires Thumb.
|
||||
ARM1156 has Thumb2; ARM1136 doesn't.
|
||||
- Cortex A8 support (ML)
|
||||
- add target implementation (ML)
|
||||
- Generic ARM run_algorithm() interface
|
||||
- tagged struct wrapping ARM instructions and metadata
|
||||
- not revision-specific (current: ARMv4+ARMv5 -or- ARMv6 -or- ARMv7)
|
||||
- usable with at least arm_nandwrite() and generic CFI drivers
|
||||
- MC1322x support (JW/DE?)
|
||||
- integrate and test support from JW (and DE?)
|
||||
- get working with a known good interface (i.e. not today's jlink)
|
||||
@@ -144,14 +197,6 @@ https://lists.berlios.de/pipermail/openocd-development/2009-July/009206.html
|
||||
|
||||
@section thelistflash Flash Support
|
||||
|
||||
- aduc702x segfault reported by Thomas A Moulton
|
||||
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-July/009186.html
|
||||
|
||||
- aduc7024 programming w/working area does not work:
|
||||
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-July/009337.html
|
||||
|
||||
- finish documentation for the following flash drivers:
|
||||
- avr
|
||||
- ecosflash
|
||||
@@ -164,12 +209,19 @@ https://lists.berlios.de/pipermail/openocd-development/2009-July/009337.html
|
||||
- finish implementing bus width/chip width handling (suggested by NC)
|
||||
- factor vendor-specific code into separate source files
|
||||
- add new callback interface for vendor-specific code
|
||||
- investigate/implement "thin wrapper" to use eCos CFI drivers (<EFBFBD>H)
|
||||
- investigate/implement "thin wrapper" to use eCos CFI drivers (ØH)
|
||||
|
||||
@section thelistdebug Debugger Support
|
||||
|
||||
- add support for masks in watchpoints? @par
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-October/011507.html
|
||||
- breakpoints can get lost in some circumstances: @par
|
||||
https://lists.berlios.de/pipermail/openocd-development/2009-June/008853.html
|
||||
- add support for masks in watchpoints. The trick is that GDB does not
|
||||
support a breakpoint mask in the remote protocol. One way to work around
|
||||
this is to add a separate command "watchpoint_mask add/rem <addr> <mask>", that
|
||||
is run to register a list of masks that the gdb_server knows to use with
|
||||
a particular watchpoint address.
|
||||
- integrate Keil AGDI interface to OpenOCD? (submitted by Dario Vecchio)
|
||||
|
||||
@section thelisttesting Testing Suite
|
||||
@@ -282,3 +334,4 @@ to complete:
|
||||
/** @file
|
||||
This file contains the @ref thelist page.
|
||||
*/
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ autoheader
|
||||
automake --gnu --add-missing --copy
|
||||
)
|
||||
|
||||
# AM_MAINTAINER_MODE requires SVN users provide --enable-maintainer-mode
|
||||
# AM_MAINTAINER_MODE requires --enable-maintainer-mode from everyone using
|
||||
# current source snapshots (working from GIT, or some source snapshot, etc)
|
||||
# otherwise the documentation will fail to build due to missing version.texi
|
||||
echo "Bootstrap complete; you can './configure --enable-maintainer-mode ....'"
|
||||
|
||||
127
configure.in
127
configure.in
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT([openocd], [0.2.0],
|
||||
AC_INIT([openocd], [0.3.0-rc0],
|
||||
[OpenOCD Mailing List <openocd-development@lists.berlios.de>])
|
||||
AC_CONFIG_SRCDIR([src/openocd.c])
|
||||
|
||||
@@ -128,7 +128,7 @@ then
|
||||
# Nonstandard --prefix and/or --exec-prefix
|
||||
# We have an override of some sort.
|
||||
# use build specific install library dir
|
||||
|
||||
|
||||
LDFLAGS="$LDFLAGS -L$OCDxprefix/lib"
|
||||
# RPATH becomes an issue on Linux only
|
||||
if test $host_os = linux-gnu || test $host_os = linux ; then
|
||||
@@ -146,7 +146,7 @@ cat << __EOF__
|
||||
|
||||
The option: --with-ftd2xx=<PATH> has been removed.
|
||||
On Linux, the new option is:
|
||||
|
||||
|
||||
--with-ftd2xx-linux-tardir=/path/to/files
|
||||
|
||||
Where <path> is the path the the directory where the "tar.gz" file
|
||||
@@ -245,7 +245,7 @@ debug_usb_comms=no
|
||||
|
||||
AC_ARG_ENABLE(verbose,
|
||||
AS_HELP_STRING([--enable-verbose],
|
||||
[Enable verbose JTAG I/O messages (for debugging).]),
|
||||
[Enable verbose JTAG I/O messages (for debugging).]),
|
||||
[
|
||||
debug_jtag_io=$enableval
|
||||
debug_usb_io=$enableval
|
||||
@@ -254,15 +254,15 @@ AC_ARG_ENABLE(verbose,
|
||||
|
||||
AC_ARG_ENABLE(verbose_jtag_io,
|
||||
AS_HELP_STRING([--enable-verbose-jtag-io],
|
||||
[Enable verbose JTAG I/O messages (for debugging).]),
|
||||
[Enable verbose JTAG I/O messages (for debugging).]),
|
||||
[debug_jtag_io=$enableval], [])
|
||||
AC_ARG_ENABLE(verbose_usb_io,
|
||||
AS_HELP_STRING([--enable-verbose-usb-io],
|
||||
[Enable verbose USB I/O messages (for debugging)]),
|
||||
[Enable verbose USB I/O messages (for debugging)]),
|
||||
[debug_usb_io=$enableval], [])
|
||||
AC_ARG_ENABLE(verbose_usb_comms,
|
||||
AS_HELP_STRING([--enable-verbose-usb-comms],
|
||||
[Enable verbose USB communication messages (for debugging)]),
|
||||
[Enable verbose USB communication messages (for debugging)]),
|
||||
[debug_usb_comms=$enableval], [])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable verbose JTAG I/O messages]);
|
||||
@@ -287,7 +287,7 @@ fi
|
||||
debug_malloc=no
|
||||
AC_ARG_ENABLE(malloc_logging,
|
||||
AS_HELP_STRING([--enable-malloc-logging],
|
||||
[Include free space in logging messages (requires malloc.h).]),
|
||||
[Include free space in logging messages (requires malloc.h).]),
|
||||
[debug_malloc=$enableval], [])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable malloc free space logging]);
|
||||
@@ -298,67 +298,63 @@ fi
|
||||
|
||||
|
||||
AC_ARG_ENABLE(dummy,
|
||||
AS_HELP_STRING([--enable-dummy], [Enable building the dummy port driver]),
|
||||
AS_HELP_STRING([--enable-dummy], [Enable building the dummy port driver]),
|
||||
[build_dummy=$enableval], [build_dummy=no])
|
||||
|
||||
AC_ARG_ENABLE(parport,
|
||||
AS_HELP_STRING([--enable-parport], [Enable building the pc parallel port driver]),
|
||||
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([--disable-parport-ppdev],
|
||||
[Disable use of ppdev (/dev/parportN) for parport (for x86 only)]),
|
||||
[Disable use of ppdev (/dev/parportN) for parport (for x86 only)]),
|
||||
[parport_use_ppdev=$enableval], [parport_use_ppdev=yes])
|
||||
|
||||
AC_ARG_ENABLE(parport_giveio,
|
||||
AS_HELP_STRING([--enable-parport-giveio],
|
||||
[Enable use of giveio for parport (for CygWin only)]),
|
||||
[Enable use of giveio for parport (for CygWin only)]),
|
||||
[parport_use_giveio=$enableval], [parport_use_giveio=])
|
||||
|
||||
|
||||
AC_ARG_ENABLE(ft2232_libftdi,
|
||||
AS_HELP_STRING([--enable-ft2232_libftdi], [Enable building support for FT2232 based devices using the libftdi driver, opensource alternate of FTD2XX]),
|
||||
AS_HELP_STRING([--enable-ft2232_libftdi], [Enable building support for FT2232 based devices using the libftdi driver, opensource alternate of FTD2XX]),
|
||||
[build_ft2232_libftdi=$enableval], [build_ft2232_libftdi=no])
|
||||
|
||||
AC_ARG_ENABLE(ft2232_ftd2xx,
|
||||
AS_HELP_STRING([--enable-ft2232_ftd2xx], [Enable building support for FT2232 based devices using the FTD2XX driver from ftdichip.com]),
|
||||
AS_HELP_STRING([--enable-ft2232_ftd2xx], [Enable building support for FT2232 based devices using the FTD2XX driver from ftdichip.com]),
|
||||
[build_ft2232_ftd2xx=$enableval], [build_ft2232_ftd2xx=no])
|
||||
|
||||
AC_ARG_ENABLE(ftd2xx_highspeed,
|
||||
AS_HELP_STRING([--enable-ftd2xx-highspeed], [Enable building support for FT2232H and FT4232H-based devices (requires >=libftd2xx-0.4.16)]),
|
||||
[want_ftd2xx_highspeed=$enableval], [want_ftd2xx_highspeed=no])
|
||||
|
||||
AC_ARG_ENABLE(amtjtagaccel,
|
||||
AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]),
|
||||
AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]),
|
||||
[build_amtjtagaccel=$enableval], [build_amtjtagaccel=no])
|
||||
|
||||
AC_ARG_ENABLE(ecosboard,
|
||||
AS_HELP_STRING([--enable-ecosboard], [Enable building support for eCos based JTAG debugger]),
|
||||
AS_HELP_STRING([--enable-ecosboard], [Enable building support for eCos based JTAG debugger]),
|
||||
[build_ecosboard=$enableval], [build_ecosboard=no])
|
||||
|
||||
AC_ARG_ENABLE(zy1000,
|
||||
AS_HELP_STRING([--enable-zy1000], [Enable ZY1000 interface]),
|
||||
AS_HELP_STRING([--enable-zy1000], [Enable ZY1000 interface]),
|
||||
[build_zy1000=$enableval], [build_zy1000=no])
|
||||
|
||||
AC_ARG_ENABLE(ioutil,
|
||||
AS_HELP_STRING([--enable-ioutil], [Enable ioutil functions - useful for standalone OpenOCD implementations]),
|
||||
AS_HELP_STRING([--enable-ioutil], [Enable ioutil functions - useful for standalone OpenOCD implementations]),
|
||||
[build_ioutil=$enableval], [build_ioutil=no])
|
||||
|
||||
AC_ARG_ENABLE(httpd,
|
||||
AS_HELP_STRING([--enable-httpd], [Enable builtin httpd server - useful for standalone OpenOCD implementations]),
|
||||
AS_HELP_STRING([--enable-httpd], [Enable builtin httpd server - useful for standalone OpenOCD implementations]),
|
||||
[build_httpd=$enableval], [build_httpd=no])
|
||||
|
||||
case "${host_cpu}" in
|
||||
case "${host_cpu}" in
|
||||
arm*)
|
||||
AC_ARG_ENABLE(ep93xx,
|
||||
AS_HELP_STRING([--enable-ep93xx], [Enable building support for EP93xx based SBCs]),
|
||||
AS_HELP_STRING([--enable-ep93xx], [Enable building support for EP93xx based SBCs]),
|
||||
[build_ep93xx=$enableval], [build_ep93xx=no])
|
||||
|
||||
AC_ARG_ENABLE(at91rm9200,
|
||||
AS_HELP_STRING([--enable-at91rm9200], [Enable building support for AT91RM9200 based SBCs]),
|
||||
[build_at91rm9200=$enableval], [build_at91rm9200=no])
|
||||
;;
|
||||
|
||||
*)
|
||||
|
||||
*)
|
||||
build_ep93xx=no
|
||||
build_at91rm9200=no
|
||||
;;
|
||||
@@ -381,7 +377,8 @@ AC_ARG_ENABLE(usbprog,
|
||||
[build_usbprog=$enableval], [build_usbprog=no])
|
||||
|
||||
AC_ARG_ENABLE(oocd_trace,
|
||||
AS_HELP_STRING([--enable-oocd_trace], [Enable building support for the OpenOCD+trace ETM capture device]),
|
||||
AS_HELP_STRING([--enable-oocd_trace],
|
||||
[Enable building support for some prototype OpenOCD+trace ETM capture hardware]),
|
||||
[build_oocd_trace=$enableval], [build_oocd_trace=no])
|
||||
|
||||
AC_ARG_ENABLE(jlink,
|
||||
@@ -439,10 +436,10 @@ else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
case "${host_cpu}" in
|
||||
case "${host_cpu}" in
|
||||
i?86|x86*)
|
||||
;;
|
||||
*)
|
||||
*)
|
||||
if test x$parport_use_ppdev = xno; then
|
||||
AC_MSG_WARN([--disable-parport-ppdev is not supported by the host CPU])
|
||||
fi
|
||||
@@ -450,9 +447,10 @@ case "${host_cpu}" in
|
||||
;;
|
||||
esac
|
||||
|
||||
case $host in
|
||||
*-cygwin*)
|
||||
case $host in
|
||||
*-cygwin*)
|
||||
is_win32=yes
|
||||
parport_use_ppdev=no
|
||||
|
||||
AC_COMPILE_IFELSE(AC_LANG_PROGRAM([],[return __MINGW32__;]),
|
||||
[is_mingw=yes],[is_mingw=no])
|
||||
@@ -466,24 +464,31 @@ case $host in
|
||||
else
|
||||
is_cygwin=yes
|
||||
AC_DEFINE(IS_CYGWIN, 1, [1 if building for Cygwin.])
|
||||
# sys/io.h needed under cygwin for parport access
|
||||
if test $build_parport = yes; then
|
||||
AC_CHECK_HEADERS(sys/io.h,[],AC_MSG_ERROR([Please install the cygwin ioperm package]))
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
AC_DEFINE(IS_WIN32, 1, [1 if building for Win32.])
|
||||
AC_DEFINE(IS_DARWIN, 0, [0 if not building for Darwin.])
|
||||
;;
|
||||
*-mingw*)
|
||||
;;
|
||||
*-mingw*)
|
||||
is_mingw=yes
|
||||
is_win32=yes
|
||||
parport_use_ppdev=no
|
||||
|
||||
if test x$parport_use_giveio = xno; then
|
||||
AC_MSG_WARN([--disable-parport-giveio is not supported by MinGW32 hosts])
|
||||
fi
|
||||
parport_use_giveio=yes
|
||||
|
||||
CFLAGS="$CFLAGS -D__USE_MINGW_ANSI_STDIO"
|
||||
|
||||
AC_DEFINE(IS_MINGW, 1, [1 if building for MinGW.])
|
||||
AC_DEFINE(IS_WIN32, 1, [1 if building for Win32.])
|
||||
AC_DEFINE(IS_DARWIN, 0, [0 if not building for Darwin.])
|
||||
;;
|
||||
;;
|
||||
*darwin*)
|
||||
is_darwin=yes
|
||||
|
||||
@@ -496,7 +501,7 @@ case $host in
|
||||
AC_DEFINE(IS_WIN32, 0, [0 if not building for Win32.])
|
||||
AC_DEFINE(IS_DARWIN, 1, [1 if building for Darwin.])
|
||||
;;
|
||||
*)
|
||||
*)
|
||||
if test x$parport_use_giveio = xyes; then
|
||||
AC_MSG_WARN([--enable-parport-giveio cannot be used by ]$host[ hosts])
|
||||
fi
|
||||
@@ -828,11 +833,8 @@ main( int argc, char **argv )
|
||||
AC_MSG_RESULT([Skipping as we are cross-compiling])
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([whether to build ftd2xx highspeed device support])
|
||||
AC_MSG_RESULT([$want_ftd2xx_highspeed])
|
||||
if test $want_ftd2xx_highspeed != no; then
|
||||
AC_MSG_CHECKING([for ftd2xx highspeed device support])
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_MSG_CHECKING([for ftd2xx highspeed device support])
|
||||
AC_COMPILE_IFELSE([
|
||||
#include "confdefs.h"
|
||||
#if IS_WIN32
|
||||
#include "windows.h"
|
||||
@@ -841,18 +843,17 @@ if test $want_ftd2xx_highspeed != no; then
|
||||
#include <ftd2xx.h>
|
||||
DWORD x = FT_DEVICE_4232H;
|
||||
], [
|
||||
AC_DEFINE(BUILD_FTD2XX_HIGHSPEED, [1],
|
||||
[Support FT2232H/FT4232HS with FTD2XX.])
|
||||
build_ftd2xx_highspeed=yes
|
||||
AC_DEFINE(BUILD_FT2232_HIGHSPEED, [1],
|
||||
[Support FT2232H/FT4232HS with FTD2XX or libftdi.])
|
||||
build_ft2232_highspeed=yes
|
||||
], [
|
||||
build_ftd2xx_highspeed=no
|
||||
build_ft2232_highspeed=no
|
||||
])
|
||||
AC_MSG_RESULT([$build_ftd2xx_highspeed])
|
||||
AC_MSG_RESULT([$build_ft2232_highspeed])
|
||||
|
||||
if test $want_ftd2xx_highspeed = yes -a $build_ftd2xx_highspeed = no; then
|
||||
AC_MSG_ERROR([You need a newer FTD2XX driver (version 0.4.16 or later).])
|
||||
if test $build_ft2232_highspeed = no; then
|
||||
AC_MSG_WARN([You need a newer FTD2XX driver (version 2.04.16 or later).])
|
||||
fi
|
||||
fi
|
||||
|
||||
LDFLAGS=$LDFLAGS_SAVE
|
||||
CFLAGS=$CFLAGS_SAVE
|
||||
@@ -862,7 +863,7 @@ if test $build_ft2232_libftdi = yes ; then
|
||||
# We assume: the package is preinstalled in the proper place
|
||||
# these present as 2 libraries..
|
||||
LIBS="$LIBS -lftdi -lusb"
|
||||
#
|
||||
#
|
||||
# Try to build a small program.
|
||||
AC_MSG_CHECKING([Build & Link with libftdi...])
|
||||
|
||||
@@ -897,6 +898,24 @@ main( int argc, char **argv )
|
||||
AC_MSG_RESULT([Skipping as we are cross-compiling])
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([for libftdi highspeed device support])
|
||||
AC_COMPILE_IFELSE([
|
||||
#include <stdio.h>
|
||||
#include <ftdi.h>
|
||||
enum ftdi_chip_type x = TYPE_2232H;
|
||||
], [
|
||||
AC_DEFINE(BUILD_FT2232_HIGHSPEED, [1],
|
||||
[Support FT2232H/FT4232HS with FTD2XX or libftdi.])
|
||||
build_ft2232_highspeed=yes
|
||||
], [
|
||||
build_ft2232_highspeed=no
|
||||
])
|
||||
AC_MSG_RESULT([$build_ft2232_highspeed])
|
||||
|
||||
if test $build_ft2232_highspeed = no; then
|
||||
AC_MSG_WARN([You need a newer libftdi version (0.16 or later).])
|
||||
fi
|
||||
|
||||
# Restore the 'unexpanded ldflags'
|
||||
LDFLAGS=$LDFLAGS_SAVE
|
||||
CFLAGS=$CFLAGS_SAVE
|
||||
@@ -905,7 +924,7 @@ fi
|
||||
# check for usb.h when a driver will require it
|
||||
if test $build_jlink = yes -o $build_vsllink = yes -o $build_usbprog = yes -o \
|
||||
$build_rlink = yes -o $build_armjtagew = yes
|
||||
then
|
||||
then
|
||||
AC_CHECK_HEADERS([usb.h],[],
|
||||
[AC_MSG_ERROR([usb.h is required to build some OpenOCD driver(s)])])
|
||||
fi
|
||||
@@ -970,7 +989,7 @@ int main(int argc, char **argv) { char **ep = environ; }
|
||||
])
|
||||
|
||||
if test "${has_environ}" != "yes" ; then
|
||||
AC_MSG_FAILURE([Could not find 'environ' in unistd.h or available libraries.])
|
||||
AC_MSG_FAILURE([Could not find 'environ' in unistd.h or available libraries.])
|
||||
fi
|
||||
|
||||
AC_DEFINE([_GNU_SOURCE],[1],[Use GNU C library extensions (e.g. stdndup).])
|
||||
|
||||
@@ -99,7 +99,7 @@ void dbg_write_u16(const unsigned short *val, long len)
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
dcc_data = val[0]
|
||||
dcc_data = val[0]
|
||||
| ((len > 1) ? val[1] << 16: 0x0000);
|
||||
|
||||
dbg_write(dcc_data);
|
||||
@@ -145,7 +145,7 @@ void dbg_write_str(const char *msg)
|
||||
| ((len > 2) ? msg[2] << 16 : 0x00)
|
||||
| ((len > 3) ? msg[3] << 24 : 0x00);
|
||||
dbg_write(dcc_data);
|
||||
|
||||
|
||||
msg += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@
|
||||
#include "dcc_stdio.h"
|
||||
|
||||
/* enable openocd debugmsg at the gdb prompt:
|
||||
* monitor target_request debugmsgs enable
|
||||
*
|
||||
* monitor target_request debugmsgs enable
|
||||
*
|
||||
* create a trace point:
|
||||
* monitor trace point 1
|
||||
*
|
||||
*
|
||||
* to show how often the trace point was hit:
|
||||
* monitor trace point
|
||||
*/
|
||||
|
||||
@@ -16,7 +16,7 @@ possible using a Cygwin host.
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
OpenOCD is distributed without autotools generated files, i.e. without a
|
||||
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.
|
||||
|
||||
@@ -77,7 +77,7 @@ The simplest way to compile this package is:
|
||||
documentation.
|
||||
|
||||
4. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'.
|
||||
source code directory by typing `make clean'.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
@@ -7,7 +7,7 @@ FMI, etc.).
|
||||
|
||||
The Flash module provides the following APIs:
|
||||
|
||||
- @subpage flashcfi
|
||||
- @subpage flashcfi
|
||||
- @subpage flashnand
|
||||
- @subpage flashtarget
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ asynchronous transactions.
|
||||
- includes the Cable/TAP API (commands starting with @c tap_)
|
||||
|
||||
- @subpage jtagdriver
|
||||
- @b private minidriver API
|
||||
- @b private minidriver API
|
||||
- declared in @c src/jtag/minidriver.h
|
||||
- used @a only by the core and minidriver implementations:
|
||||
- @c jtag_driver.c (in-tree OpenOCD drivers)
|
||||
|
||||
@@ -22,14 +22,14 @@ cases, a fresh bootstrap may be still required.
|
||||
@subsection primerbootstrapcures Problems Solved By Bootstrap
|
||||
|
||||
For example, the build system can fail in unexpected ways after running
|
||||
<code>svn update</code>. Here, the <code>make maintainer-clean</code>
|
||||
<code>git pull</code>. Here, the <code>make maintainer-clean</code>
|
||||
should be used to remove all of the files generated by the @c bootstrap
|
||||
script and subsequent build processes.
|
||||
|
||||
In this particular case, one may also need to remove stray files by hand
|
||||
after running this command to ensure everything is rebuilt properly.
|
||||
This step should be necessary only if the @c maintainer-clean was run
|
||||
@b after altering the build system files with Subversion. If it is run
|
||||
@b after altering the build system files with git. If it is run
|
||||
@b before any updates, the build system should never leave artifacts
|
||||
in the tree.
|
||||
|
||||
@@ -61,7 +61,7 @@ experience errors when running @c make that some files cannot be found
|
||||
the problems. The isssue is well-known and expected, if unfortunate.
|
||||
|
||||
The OpenOCD project requires that all developers building from the
|
||||
Subversion repository use the @c --enable-maintainer-mode option when
|
||||
git repository use the @c --enable-maintainer-mode option when
|
||||
running the @c configure script. This option ensures that certain files
|
||||
are created during the build process that would normally be packaged in
|
||||
the distribution tarball. The @c bootstrap script will remind you of
|
||||
@@ -144,7 +144,7 @@ implement new checks.
|
||||
The <code>make distcheck</code> command produces an archive of the
|
||||
project deliverables (using <code>make dist</code>) and verifies its
|
||||
integrity for distribution by attemptng to use the package in the same
|
||||
manner as a user.
|
||||
manner as a user.
|
||||
|
||||
These checks includes the following steps:
|
||||
-# Unpack the project archive into its expected directory.
|
||||
|
||||
@@ -90,7 +90,7 @@ provide detailed documentation for each option.
|
||||
To support out-of-tree building of the documentation, the @c Doxyfile.in
|
||||
@c INPUT values will have all instances of the string @c "@srcdir@"
|
||||
replaced with the current value of the make variable
|
||||
<code>$(srcdir)</code>. The Makefile uses a rule to convert
|
||||
<code>$(srcdir)</code>. The Makefile uses a rule to convert
|
||||
@c Doxyfile.in into the @c Doxyfile used by <code>make doxygen</code>.
|
||||
|
||||
@section primerdoxyoocd OpenOCD Input Files
|
||||
@@ -105,7 +105,7 @@ that can be found under the @c doc/manual directory in the project tree.
|
||||
New files containing valid Doxygen markup that are placed in or under
|
||||
that directory will be detected and included in The Manual automatically.
|
||||
|
||||
@section primerdoxyman Doxygen Reference Manual
|
||||
@section primerdoxyman Doxygen Reference Manual
|
||||
|
||||
The full documentation for Doxygen can be referenced on-line at the project
|
||||
home page: http://www.doxygen.org/index.html. In HTML versions of this
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/** @page primerjtag OpenOCD JTAG Primer
|
||||
|
||||
JTAG is unnecessarily confusing, because JTAG is often confused with
|
||||
JTAG is unnecessarily confusing, because JTAG is often confused with
|
||||
boundary scan, which is just one of its possible functions.
|
||||
|
||||
JTAG is simply a communication interface designed to allow communication
|
||||
to functions contained on devices, for the designed purposes of
|
||||
initialisation, programming, testing, debugging, and anything else you
|
||||
JTAG is simply a communication interface designed to allow communication
|
||||
to functions contained on devices, for the designed purposes of
|
||||
initialisation, programming, testing, debugging, and anything else you
|
||||
want to use it for (as a chip designer).
|
||||
|
||||
Think of JTAG as I2C for testing. It doesn't define what it can do,
|
||||
Think of JTAG as I2C for testing. It doesn't define what it can do,
|
||||
just a logical interface that allows a uniform channel for communication.
|
||||
|
||||
See @par
|
||||
@@ -17,42 +17,42 @@ See @par
|
||||
and @par
|
||||
http://www.inaccessnetworks.com/projects/ianjtag/jtag-intro/jtag-state-machine-large.png
|
||||
|
||||
The first page (among other things) shows a logical representation
|
||||
describing how multiple devices are wired up using JTAG. JTAG does not
|
||||
specify, data rates or interface levels (3.3V/1.8V, etc) each device can
|
||||
support different data rates/interface logic levels. How to wire them
|
||||
The first page (among other things) shows a logical representation
|
||||
describing how multiple devices are wired up using JTAG. JTAG does not
|
||||
specify, data rates or interface levels (3.3V/1.8V, etc) each device can
|
||||
support different data rates/interface logic levels. How to wire them
|
||||
in a compatible way is an exercise for an engineer.
|
||||
|
||||
Basically TMS controls which shift register is placed on the device,
|
||||
between TDI and TDO. The second diagram shows the state transitions on
|
||||
Basically TMS controls which shift register is placed on the device,
|
||||
between TDI and TDO. The second diagram shows the state transitions on
|
||||
TMS which will select different shift registers.
|
||||
|
||||
The first thing you need to do is reset the state machine, because when
|
||||
you connect to a chip you do not know what state the controller is in,you need
|
||||
to clock TMS as 1, at least 7 times. This will put you into "Test Logic
|
||||
Reset" State. Knowing this, you can, once reset, then track what each
|
||||
transition on TMS will do, and hence know what state the JTAG state
|
||||
The first thing you need to do is reset the state machine, because when
|
||||
you connect to a chip you do not know what state the controller is in,you need
|
||||
to clock TMS as 1, at least 7 times. This will put you into "Test Logic
|
||||
Reset" State. Knowing this, you can, once reset, then track what each
|
||||
transition on TMS will do, and hence know what state the JTAG state
|
||||
machine is in.
|
||||
|
||||
There are 2 "types" of shift registers. The Instruction shift register
|
||||
and the data shift register. The sizes of these are undefined, and can
|
||||
change from chip to chip. The Instruction register is used to select
|
||||
which Data register/data register function is used, and the data
|
||||
There are 2 "types" of shift registers. The Instruction shift register
|
||||
and the data shift register. The sizes of these are undefined, and can
|
||||
change from chip to chip. The Instruction register is used to select
|
||||
which Data register/data register function is used, and the data
|
||||
register is used to read data from that function or write data to it.
|
||||
|
||||
Each of the states control what happens to either the data register or
|
||||
Each of the states control what happens to either the data register or
|
||||
instruction register.
|
||||
|
||||
For example, one of the data registers will be known as "bypass" this is
|
||||
(usually) a single bit which has no function and is used to bypass the
|
||||
chip. Assume we have 3 identical chips, wired up like the picture
|
||||
and each has a 3 bit instruction register, and there are 2 known
|
||||
instructions (110 = bypass, 010 = some other function) if we want to use
|
||||
"some other function", on the second chip in the line, and not change
|
||||
For example, one of the data registers will be known as "bypass" this is
|
||||
(usually) a single bit which has no function and is used to bypass the
|
||||
chip. Assume we have 3 identical chips, wired up like the picture
|
||||
and each has a 3 bit instruction register, and there are 2 known
|
||||
instructions (110 = bypass, 010 = some other function) if we want to use
|
||||
"some other function", on the second chip in the line, and not change
|
||||
the other chips we would do the following transitions.
|
||||
|
||||
From Test Logic Reset, TMS goes:
|
||||
|
||||
|
||||
0 1 1 0 0
|
||||
|
||||
which puts every chip in the chain into the "Shift IR state"
|
||||
@@ -60,7 +60,7 @@ Then (while holding TMS as 0) TDI goes:
|
||||
|
||||
0 1 1 0 1 0 0 1 1
|
||||
|
||||
which puts the following values in the instruction shift register for
|
||||
which puts the following values in the instruction shift register for
|
||||
each chip [110] [010] [110]
|
||||
|
||||
The order is reversed, because we shift out the least significant bit
|
||||
@@ -70,18 +70,18 @@ first. Then we transition TMS:
|
||||
|
||||
which puts us in the "Shift DR state".
|
||||
|
||||
Now when we clock data onto TDI (again while holding TMS to 0) , the
|
||||
data shifts through the data registers, and because of the instruction
|
||||
registers we selected (some other function has 8 bits in its data
|
||||
Now when we clock data onto TDI (again while holding TMS to 0) , the
|
||||
data shifts through the data registers, and because of the instruction
|
||||
registers we selected (some other function has 8 bits in its data
|
||||
register), our total data register in the chain looks like this:
|
||||
|
||||
0 00000000 0
|
||||
|
||||
The first and last bit are in the "bypassed" chips, so values read from
|
||||
them are irrelevant and data written to them is ignored. But we need to
|
||||
The first and last bit are in the "bypassed" chips, so values read from
|
||||
them are irrelevant and data written to them is ignored. But we need to
|
||||
write bits for those registers, because they are in the chain.
|
||||
|
||||
If we wanted to write 0xF5 to the data register we would clock out of
|
||||
If we wanted to write 0xF5 to the data register we would clock out of
|
||||
TDI (holding TMS to 0):
|
||||
|
||||
0 1 0 1 0 1 1 1 1 0
|
||||
@@ -91,13 +91,13 @@ clock TMS:
|
||||
|
||||
1 1 0
|
||||
|
||||
which updates the selected data register with the value 0xF5 and returns
|
||||
which updates the selected data register with the value 0xF5 and returns
|
||||
us to run test idle.
|
||||
|
||||
If we needed to read the data register before over-writing it with F5,
|
||||
no sweat, that's already done, because the TDI/TDO are set up as a
|
||||
circular shift register, so if you write enough bits to fill the shift
|
||||
register, you will receive the "captured" contents of the data registers
|
||||
If we needed to read the data register before over-writing it with F5,
|
||||
no sweat, that's already done, because the TDI/TDO are set up as a
|
||||
circular shift register, so if you write enough bits to fill the shift
|
||||
register, you will receive the "captured" contents of the data registers
|
||||
simultaneously on TDO.
|
||||
|
||||
That's JTAG in a nutshell. On top of this, you need to get specs for
|
||||
|
||||
@@ -6,10 +6,10 @@ for OpenOCD contributors who are unfamiliar with the process.
|
||||
@section primerpatchintro Introduction to Patching
|
||||
|
||||
The standard method for creating patches requires developers to:
|
||||
- checkout the Subversion repository (or bring a copy up-to-date),
|
||||
- checkout the git repository (or bring a copy up-to-date),
|
||||
- make the necessary modifications to a working copy,
|
||||
- check with 'svn status' to see which files will be modified/added, and
|
||||
- use 'svn diff' to review the changes and produce a patch.
|
||||
- check with 'git status' to see which files will be modified/added, and
|
||||
- use 'git diff' to review the changes and produce a patch.
|
||||
|
||||
It is important to minimize the changes to only those lines that contain
|
||||
important differences; do not allow stray whitespace changes into your
|
||||
@@ -20,7 +20,7 @@ patches, and keep the focus to a single logical change.
|
||||
You can create a patch (from the root of your working copy) with a
|
||||
command like the following example: @par
|
||||
@verbatim
|
||||
svn diff > patch-name.patch
|
||||
git diff > patch-name.patch
|
||||
@endverbatim
|
||||
|
||||
where @a patch-name should be something that is descriptive and unique.
|
||||
@@ -29,8 +29,8 @@ The above command will create a patch containing all of the changes in
|
||||
the working copy; if you want to obtain a subset, simply provide the
|
||||
list of files to the command: @par
|
||||
@verbatim
|
||||
svn diff doc > <patch-name>-doc.patch
|
||||
svn diff src > <patch-name>-src.patch
|
||||
git diff doc > <patch-name>-doc.patch
|
||||
git diff src > <patch-name>-src.patch
|
||||
@endverbatim
|
||||
|
||||
This will create two patches, each containing only those changes present
|
||||
@@ -56,65 +56,20 @@ submission, sending your patch to the bit bucket on accident.
|
||||
@section primerpatchpreflight Developer Review
|
||||
|
||||
Before sending in patches, please make sure you have updated to the
|
||||
latest version of the trunk (using <code>svn up</code>) before creating
|
||||
latest version of the trunk (using <code>git pull</code>) before creating
|
||||
your patch. This helps to increase the chances that it will apply
|
||||
cleanly to the trunk. However, the content matters most.
|
||||
|
||||
When creating a patch using "<code>svn diff</code>", Subversion will
|
||||
When creating a patch using "<code>git diff</code>", git will
|
||||
produce a patch that contains all of the changes in your working copy.
|
||||
To manage multiple changes at once, you either need one working copy per
|
||||
patch, or you can specified specific files and directories when using
|
||||
<code>svn diff</code>. Overlapping patches will be discussed in the
|
||||
<code>git diff</code>. Overlapping patches will be discussed in the
|
||||
next section.
|
||||
|
||||
The remainder of this section provides
|
||||
|
||||
@subsection primerpatchprops Subversion Properties
|
||||
|
||||
The Subversion attributes of files can be examined with commands like the
|
||||
following: @par
|
||||
@verbatim
|
||||
$ svn pl README
|
||||
Properties on 'README':
|
||||
svn:eol-style
|
||||
$ svn pl tools/rlink_make_speed_table/rlink_make_speed_table.pl
|
||||
Properties on 'tools/rlink_make_speed_table/rlink_make_speed_table.pl':
|
||||
svn:executable
|
||||
svn:eol-style
|
||||
$
|
||||
@endverbatim
|
||||
|
||||
@subsection primerpatchpropcrlf Native Line-endings
|
||||
|
||||
Subversion checks out files marked with the attribute @c svn:eol-style
|
||||
set to @c native such that these files contain the default line ending
|
||||
style of the current host ('\\n' or '\\r\\n'). By using the proper line
|
||||
endings for different platforms, two different byte streams for the same
|
||||
file will be produced.
|
||||
|
||||
@subsection primerpatchwincrlf Windows Patching Problems
|
||||
|
||||
Because of the line-ending functionality, it may be correct when a fresh
|
||||
patch does not apply cleanly on the Windows platform. This is because
|
||||
patches are created by SVN with UNIX line endings, so the context and
|
||||
changes will not appear to match the files with Windows line endings.
|
||||
|
||||
In other words, the following command may @b not succeed because @c foo
|
||||
has its @c svn:eol-style property set to @c native: @par
|
||||
@code
|
||||
svn diff foo | patch -R
|
||||
@endcode
|
||||
|
||||
The following series of commands will work: @par
|
||||
@code
|
||||
svn diff foo | unix2dos | patch -R
|
||||
@endcode
|
||||
|
||||
This is not a bug.
|
||||
|
||||
@todo Does Subversion's treatment of line-endings for files marked with
|
||||
svn:eol-style=native continue to pose the problems described here, or
|
||||
has this been magically solved?
|
||||
@todo Does git's treatment of line-endings behave sanely?
|
||||
Basically, the repository should use newlines internally,
|
||||
and convert to/from CRLF on Windows etc.
|
||||
|
||||
@section primerpatchseries Patch Series
|
||||
|
||||
@@ -132,9 +87,8 @@ simply a matter of taste or familiarity; your mileage may vary.
|
||||
|
||||
Packages such as @c patchutils, @c diffutils, and @c quilt are among
|
||||
those that have proved themselves invaluable for these type of tasks.
|
||||
Others take their patch management a step further, tracking the
|
||||
Subversion repository with git-svn and employing GIT conventions and
|
||||
methodologies for development.
|
||||
Others take their patch management a step further, using stkgit or
|
||||
some other framework on top of git.
|
||||
|
||||
@subsection primerpatchseriesinterdiff Using @c interdiff
|
||||
|
||||
@@ -144,22 +98,22 @@ patches. This command can be used to manage the creation of trivial
|
||||
patch series. For example, the following sequence of commands will
|
||||
produce three patches: @par
|
||||
@verbatim
|
||||
$ cd openocd-head/
|
||||
$ svn up && svn st
|
||||
At revision NNNN.
|
||||
$ cd openocd/
|
||||
$ git pull
|
||||
...
|
||||
$ <<<start changes for patch #1>>>
|
||||
...
|
||||
$ <<<finish changes for patch #1>>>
|
||||
$ svn diff > series-1.patch # patch #1 is easy
|
||||
$ git diff > series-1.patch # patch #1 is easy
|
||||
$ <<<start changes for patch #2>>>
|
||||
...
|
||||
$ <<<finish changes for patch #2>>>
|
||||
$ svn diff > series-1+2.patch # create patch 1+2
|
||||
$ git diff > series-1+2.patch # create patch 1+2
|
||||
$ interdiff series-1{,+2}.patch > series-2.patch # 1 ~ 1+2 => #2
|
||||
$ <<<start changes for patch #3>>>
|
||||
...
|
||||
$ <<<finish changes for patch #3>>>
|
||||
$ svn diff > series-1+2+3.patch # create patch 1+2+3
|
||||
$ git diff > series-1+2+3.patch # create patch 1+2+3
|
||||
$ interdiff series-1+2{,+3}.patch > series-3.patch # 1+2 ~ 1+2+3 => 3
|
||||
@endverbatim
|
||||
|
||||
@@ -173,19 +127,14 @@ efficiently than can be managed by hand. For out-of-tree work projects
|
||||
that require such patch management, @c quilt provides an indispensable
|
||||
tool for solving the problem.
|
||||
|
||||
@subsection primerpatchseriesgit Using @c git
|
||||
|
||||
The @c git revision control system provides a tool for tracking
|
||||
Subversion repositories.
|
||||
|
||||
@section primerpatchsubmit Submitting Patches
|
||||
|
||||
Write access to the OpenOCD Subversion repository is limited to
|
||||
Write access to the OpenOCD git repository is limited to
|
||||
contributors that have demonstrated the ability to produce clear,
|
||||
consistent, and frequent patches. These individuals are responsible
|
||||
for maintaining the integrity of the repository for the community.
|
||||
|
||||
Thus, commits to the Subversion repository must be handled by one of
|
||||
Thus, commits to the git repository must be handled by one of
|
||||
these maintainers.
|
||||
|
||||
Patches must be sent to the OpenOCD developer mailing list:
|
||||
|
||||
@@ -115,7 +115,7 @@ Exception: The arrays.
|
||||
|
||||
set x "2 * 6"
|
||||
set foo([expr $x]) "twelve"
|
||||
|
||||
|
||||
**************************************************
|
||||
***************************************************
|
||||
=== TCL TOUR ===
|
||||
@@ -133,7 +133,7 @@ This means it is evaluated when the file is parsed.
|
||||
In TCL, "FOR" is a funny thing, it is not what you think it is.
|
||||
|
||||
Syntactically - FOR is a just a command, it is not language
|
||||
construct like for(;;) in C...
|
||||
construct like for(;;) in C...
|
||||
|
||||
The "for" command takes 4 parameters.
|
||||
(1) The "initial command" to execute.
|
||||
@@ -215,7 +215,7 @@ All memory regions must have 2 things:
|
||||
(2) NAME( array )
|
||||
And the array must have some specific names:
|
||||
( <idx>, THING )
|
||||
Where: THING is one of:
|
||||
Where: THING is one of:
|
||||
CHIPSELECT
|
||||
BASE
|
||||
LEN
|
||||
@@ -224,7 +224,7 @@ All memory regions must have 2 things:
|
||||
RWX - the access ability.
|
||||
WIDTH - the accessible width.
|
||||
|
||||
ie: Some regions of memory are not 'word'
|
||||
ie: Some regions of memory are not 'word'
|
||||
accessible.
|
||||
|
||||
The function "address_info" - given an address should
|
||||
@@ -237,14 +237,14 @@ tell you about the address.
|
||||
MAJOR FUNCTION:
|
||||
==
|
||||
|
||||
proc memread32 { ADDR }
|
||||
proc memread16 { ADDR }
|
||||
proc memread8 { ADDR }
|
||||
proc memread32 { ADDR }
|
||||
proc memread16 { ADDR }
|
||||
proc memread8 { ADDR }
|
||||
|
||||
All read memory - and return the contents.
|
||||
|
||||
[ FIXME: 7/5/2008 - I need to create "memwrite" functions]
|
||||
|
||||
|
||||
**************************************************
|
||||
***************************************************
|
||||
=== TCL TOUR ===
|
||||
@@ -265,13 +265,13 @@ In a makefile or shell script you may have seen this:
|
||||
FOO_linux = "Penguins rule"
|
||||
FOO_winXP = "Broken Glass"
|
||||
FOO_mac = "I like cat names"
|
||||
|
||||
|
||||
# Pick one
|
||||
BUILD = linux
|
||||
#BUILD = winXP
|
||||
#BUILD = mac
|
||||
FOO = ${FOO_${BUILD}}
|
||||
|
||||
|
||||
The "double [set] square bracket" thing is the TCL way, nothing more.
|
||||
|
||||
----
|
||||
@@ -290,7 +290,7 @@ Notice this IF COMMAND - (not statement) is like this:
|
||||
The "IF" command expects either 2 params, or 4 params.
|
||||
|
||||
=== Sidebar: About "commands" ===
|
||||
|
||||
|
||||
Take a look at the internals of "jim.c"
|
||||
Look for the function: Jim_IfCoreCommand()
|
||||
And all those other "CoreCommands"
|
||||
@@ -298,10 +298,10 @@ The "IF" command expects either 2 params, or 4 params.
|
||||
You'll notice - they all have "argc" and "argv"
|
||||
|
||||
Yea, the entire thing is done that way.
|
||||
|
||||
|
||||
IF is a command. SO is "FOR" and "WHILE" and "DO" and the
|
||||
others. That is why I keep using the phase it is a "command"
|
||||
|
||||
|
||||
=== END: Sidebar: About "commands" ===
|
||||
|
||||
Parameter 1 to the IF command is expected to be an expression.
|
||||
@@ -315,7 +315,7 @@ CATCH - is an error catcher.
|
||||
You give CATCH 1 or 2 parameters.
|
||||
The first 1st parameter is the "code to execute"
|
||||
The 2nd (optional) is where to put the error message.
|
||||
|
||||
|
||||
CATCH returns 0 on success, 1 for failure.
|
||||
The "![catch command]" is self explaintory.
|
||||
|
||||
@@ -325,7 +325,7 @@ above, the IF command can take many parameters they just have to
|
||||
be joined by exactly the words "else" or "elseif".
|
||||
|
||||
The 4th parameter contains:
|
||||
|
||||
|
||||
"error [format STRING....]"
|
||||
|
||||
This lets me modify the previous lower level error by tacking more
|
||||
@@ -346,7 +346,7 @@ string, then using "dlopen()" and "dlsym()" to look it up - and get a
|
||||
function pointer - and calling the function pointer.
|
||||
|
||||
In this case - I execute a dynamic command. You can do some cool
|
||||
tricks with interpretors.
|
||||
tricks with interpretors.
|
||||
|
||||
----------
|
||||
|
||||
@@ -380,7 +380,7 @@ Some assumptions:
|
||||
|
||||
The "CHIP" file has defined some variables in a proper form.
|
||||
|
||||
ie: AT91C_BASE_US0 - for usart0,
|
||||
ie: AT91C_BASE_US0 - for usart0,
|
||||
AT91C_BASE_US1 - for usart1
|
||||
... And so on ...
|
||||
|
||||
@@ -419,9 +419,9 @@ with the generated list of commands for the entire USART.
|
||||
With that little bit of code - I now have a bunch of functions like:
|
||||
|
||||
show_US0, show_US1, show_US2, .... etc ...
|
||||
|
||||
|
||||
And show_US0_MR, show_US0_IMR ... etc...
|
||||
|
||||
|
||||
And - I have this for every USART... without having to create tons of
|
||||
boiler plate yucky code.
|
||||
|
||||
|
||||
@@ -14,35 +14,35 @@ This page provides an introduction to the OpenOCD Release Processes:
|
||||
|
||||
@section releasewhy Why Produce Releases?
|
||||
|
||||
The OpenOCD maintainers should produce <i>releases</i> periodically. This
|
||||
section gives several reasons to explain the reasons for making releases
|
||||
on a regular basis. These reasons lead to motivation for developing and
|
||||
following a set of <i>release processes</i>. The actual processes are
|
||||
described in the remainder of the @ref releases sections.
|
||||
The OpenOCD maintainers produce <i>releases</i> periodically for many
|
||||
reasons. This section provides the key reasons for making releases on a
|
||||
regular basis and why a set of <i>release processes</i> should be used
|
||||
to produce them.
|
||||
|
||||
At any time, a "source archives" can be produced by running 'make dist'
|
||||
in the OpenOCD project tree. With the 0.2.0 release, this command will
|
||||
produce openocd-\<version\>.{tar.gz,tar.bz2,zip} archives. These files
|
||||
will be suitable for being released when produced properly.
|
||||
At any time, <i>source archives</i> can be produced by running
|
||||
<code>make dist</code> in the OpenOCD project tree. With the 0.2.0
|
||||
release, this command will package the tree into several popular archive
|
||||
formats: <code>openocd-\<version\>.{tar.gz,tar.bz2,zip}</code>. If
|
||||
produced properly, these files are suitable for release to the public.
|
||||
|
||||
When released for users, these archives present several important
|
||||
advantages when contrasted to using the Subversion repository:
|
||||
advantages when contrasted to using the git repository:
|
||||
|
||||
-# They allow others to package and distribute the code to users.
|
||||
-# They allow others to package and distribute the code.
|
||||
-# They build easier for developers, because they contain
|
||||
a working configure script that was produced by the Release Manager.
|
||||
-# They prevent users from trying a random HEAD revision of the trunk.
|
||||
-# They free developers from answering questions about trunk breakage.
|
||||
-# They prevent users from trying a random work-in-process revision.
|
||||
-# They free developers from answering questions about mainline breakage.
|
||||
|
||||
Hopefully, this shows several good reasons to produce regular releases,
|
||||
but these release processes were developed with some additional design
|
||||
but the release processes were developed with some additional design
|
||||
goals in mind. Specifically, the releases processes should have the
|
||||
following properties:
|
||||
|
||||
-# Produce successive sets of release archives cleanly and consistently.
|
||||
-# Implementable as a script that automates the critical release steps.
|
||||
-# Prevent human operators from producing bad releases, when possible.
|
||||
-# Allow scheduling and automation of release process milestones.
|
||||
-# Produce successive sets of archives cleanly and consistently.
|
||||
-# Implementable as a script that automates the critical steps.
|
||||
-# Prevent human operators from producing broken packages, when possible.
|
||||
-# Allow scheduling and automation of building and publishing milestones.
|
||||
|
||||
The current release processes are documented in the following sections.
|
||||
They attempt to meet these design goals, but there may improvements
|
||||
@@ -59,27 +59,50 @@ For a <i>bug-fix</i> release, the micro version number will be non-zero
|
||||
number will be zero (<code>z = 0</code>). For a <i>major releases</i>,
|
||||
the minor version will @a also be zero (<code>y = 0, z = 0</code>).
|
||||
|
||||
The trunk and all branches should have the tag '-in-development' in
|
||||
@subsection releaseversiontags Version Tags
|
||||
|
||||
After these required numeric components, the version string may contain
|
||||
one or more <i>version tags</i>, such as '-rc1' or '-dev'.
|
||||
|
||||
Mainline and all branches should have the tag '-dev' in
|
||||
their version number. This tag helps developers identify reports
|
||||
created from the Subversion repository, and it can be detected and
|
||||
created from the git repository, and it can be detected and
|
||||
manipulated by the release script. Specifically, this tag will be
|
||||
removed and re-added during the release process; it should never be
|
||||
manipulated by developers in submitted patches.
|
||||
|
||||
@subsection releaseversionsdist Patched Versions
|
||||
The 'rc' tags indicate a "release candidate" version of the package.
|
||||
This tag will also be manipulated by the automated release process.
|
||||
|
||||
Distributors of patched versions of OpenOCD are encouraged to extend
|
||||
the version string when producing external releases, as this helps to
|
||||
identify your particular distribution series.
|
||||
Additional tags may be used as necessary.
|
||||
|
||||
@subsection releaseversionsdist Version Processes
|
||||
@subsection releaseversionsdist Packager Versions
|
||||
|
||||
Distributors of patched versions of OpenOCD are encouraged to extend the
|
||||
version string with a unique version tag when producing external
|
||||
releases, as this helps to identify your particular distribution series.
|
||||
|
||||
For example, the following command will add a 'foo1' tag to the
|
||||
configure.in script of a local copy of the source tree:
|
||||
|
||||
@code
|
||||
tools/release.sh version bump tag foo
|
||||
@endcode
|
||||
|
||||
This command will modify the configure.in script in your working copy
|
||||
only. After running the @c bootstrap sequence, the tree can be patched
|
||||
and used to produce your own derived versions. The same command can be
|
||||
used each time the derived package is released, incrementing the tag's
|
||||
version to facilitate tracking the changes you have distributed.
|
||||
|
||||
@subsection releaseversionhow Version Processes
|
||||
|
||||
The release process includes version number manipulations to the tree
|
||||
being released, ensuring that all numbers are incremented at the right
|
||||
time and in the proper locations of the repository.
|
||||
|
||||
The version numbers for any branch should monotonically
|
||||
increase to the next successive integer, except when reset to zero
|
||||
The version numbers for any branch should increase monotonically
|
||||
to the next successive integer, except when reset to zero
|
||||
during major or minor releases. The community should decide when
|
||||
major and minor milestones will be released.
|
||||
|
||||
@@ -113,7 +136,7 @@ tags and incrementing the version.
|
||||
|
||||
The OpenOCD release process must be carried out on a periodic basis, so
|
||||
the project can realize the benefits presented in answer to the question,
|
||||
@ref releasewhy.
|
||||
@ref releasewhy.
|
||||
|
||||
Starting with the 0.2.0 release, the OpenOCD project should produce a
|
||||
new minor release every month or two, with a major release once a year.
|
||||
@@ -132,12 +155,12 @@ beginning of the development cycle through the delivery of the new
|
||||
release. This section presents guidelines for scheduling key points
|
||||
where the community must be informed of changing conditions.
|
||||
|
||||
If T is the time of the next release, then the following schedule
|
||||
If T is the time of the next release, then the following schedule
|
||||
might describe some of the key milestones of the new release cycle:
|
||||
|
||||
- T minus one month: start of new development cycle
|
||||
- T minus two weeks: announce pending trunk closure to new work
|
||||
- T minus one week: close trunk to new work, begin testing phase
|
||||
- T minus two weeks: announce pending mainline closure to new work
|
||||
- T minus one week: close mainline to new work, begin testing phase
|
||||
- T minus two days: call for final bug fixes
|
||||
- T minus one day: produce -rc packages and distribute to testers
|
||||
- T minus one hour: produce final packages and post on-line
|
||||
@@ -169,7 +192,7 @@ than allowing the release cycle to be delayed while waiting for them.
|
||||
|
||||
Despite any assurances this schedule may appear to give, the Release
|
||||
Manager cannot schedule the work that will be done on the project,
|
||||
when it will be submitted, review, and deemed suitable to be committed.
|
||||
when it will be submitted, reviewed, and deemed suitable to be committed.
|
||||
In this way, the RM cannot act as a priest in a cathedral; OpenOCD uses
|
||||
the bazaar development model. The release schedule must adapt
|
||||
continuously in response to changes in the rate of churn.
|
||||
@@ -179,7 +202,7 @@ expectation of a fairly high rate of development. Fewer releases may be
|
||||
required if developers contribute less patches, and more releases may be
|
||||
desirable if the project continues to grow and experience high rates of
|
||||
community contribution. During each cycle, the RM should be tracking
|
||||
the situation and gathering feedback from the community .
|
||||
the situation and gathering feedback from the community.
|
||||
|
||||
@section releasehow Release Process: Step-by-Step
|
||||
|
||||
@@ -189,45 +212,47 @@ Even with the release script, some steps require clear user intervention
|
||||
|
||||
The following steps should be followed to produce each release:
|
||||
|
||||
-# Produce final patches to the trunk (or release branch):
|
||||
-# Finalize @c NEWS file to describe the changes in the release
|
||||
-# Produce final manual patches to mainline (or release branch):
|
||||
-# Finalize @c NEWS file to describe the changes in the release
|
||||
- This file is Used to automatically post "blurbs" about the project.
|
||||
- This material should be produced during the development cycle.
|
||||
- Add a new item for each @c NEWS-worthy contribution, when committed.
|
||||
-# bump library version if our API changed (not yet required)
|
||||
-# Remove -in-development tag from package version:
|
||||
- For major/minor releases, remove version tag from trunk, @a or
|
||||
- For bug-fix releases, remove version tag from release branch.
|
||||
-# Branch or tag the required tree in the Subversion repository:
|
||||
- Tags and branches for releases must be named consistently: @par
|
||||
"${PACKAGE_TARNAME}-${PACKAGE_VERSION}"
|
||||
- For a major/minor release from the main trunk, the code should be
|
||||
branched and tagged in the repository:
|
||||
-# Bump library version if our API changed (not yet required)
|
||||
-# Produce and tag the final revision in the git repository:
|
||||
- Update and commit the final package version in @c configure.in :
|
||||
-# Remove @c -dev tag.
|
||||
-# Remove @c -rc tag, if producing the final release from an -rc series.
|
||||
- Tags must be named consistently:
|
||||
@verbatim
|
||||
svn cp .../trunk .../branches/${RELEASE_BRANCH}
|
||||
svn cp .../branches/${RELEASE_BRANCH} .../tags/${RELEASE_TAG}
|
||||
@endverbatim
|
||||
- For bug-fix releases produced in their respective branch, a tag
|
||||
should be created in the repository:
|
||||
- Tag the final commit with a consistent GIT tag name and message:
|
||||
@verbatim
|
||||
svn cp .../branches/${RELEASE_BRANCH} .../tags/${RELEASE_TAG}
|
||||
PACKAGE_VERSION="x.y.z"
|
||||
PACKAGE_TAG="v${PACKAGE_VERSION}"
|
||||
git tag -m "The openocd-${PACKAGE_VERSION} release." "${PACKAGE_TAG}"
|
||||
@endverbatim
|
||||
-# Prepare to resume normal development activities:
|
||||
- Archive @c NEWS file as <code>doc/news/NEWS-${PACKAGE_VERSION}</code>.
|
||||
- Create a new @c NEWS file for the next release
|
||||
- For major/minor release from the trunk:
|
||||
-# Bump major or minor package version in trunk.
|
||||
-# Restore version tag to trunk and release branch.
|
||||
- For bug-fix releases from a release branch:
|
||||
-# Bump bug-fix version in release branch.
|
||||
-# Restore version tag to release branch.
|
||||
-# Prepare to resume normal development on the branch:
|
||||
- Restore @c -dev and -@c -rc0 version tags.
|
||||
- To start a new major (or minor) release cycle on the @c master branch:
|
||||
- Bump major (or minor) package version, zeroing sub-components.
|
||||
- Add -rc0 version tag:
|
||||
- This insures casual releases from GIT always increase monotonically.
|
||||
- For example, a major increment after releasing 1.2.3 starts 2.0.0-rc0-dev.
|
||||
- Archive @c NEWS file as "<code>doc/news/NEWS-${PACKAGE_VERSION}</code>".
|
||||
- Create a new @c NEWS file for the next release
|
||||
- To start a bug-fix release on a non-master branch:
|
||||
-# Bump bug-fix version.
|
||||
- To start another release candidate on a major or minor branch:
|
||||
-# Bump rc tag.
|
||||
-# Produce the package source archives:
|
||||
-# Start with a clean working copy, used for producing releases only.
|
||||
-# Switch to release tag branch: svn switch .../${RELEASE_TAG}
|
||||
-# produce a ChangeLog for the release (using svn2cl).
|
||||
-# Checkout the appropriate tag:
|
||||
<code>git checkout $(git tag ) "${PACKAGE_VERSION}"</code>
|
||||
-# Produce a ChangeLog for the release (using @c git2cl).
|
||||
-# @c bootstrap, @c configure, and @c make the package.
|
||||
-# Run <code>make distcheck</code> to produce the distribution archives.
|
||||
-# Run <code>make maintainer-clean</code> verify the repository is empty.
|
||||
-# Create signature files using @c md5sum, @c sha1sum, etc.
|
||||
-# Publish documentation for the release:
|
||||
- Allow users to access the documentation for each of our releases.
|
||||
- Place static copies of the following files on the project website:
|
||||
@@ -235,12 +260,21 @@ svn cp .../branches/${RELEASE_BRANCH} .../tags/${RELEASE_TAG}
|
||||
- @c ChangeLog: to show exactly what has been changed
|
||||
- User Guide, Developer Manual: to allow easy on-line viewing
|
||||
-# Upload packages and post announcements of their availability:
|
||||
-# Release packages into files section of berliOS project site:
|
||||
-# Release packages into files section of project sites:
|
||||
- SF.net:
|
||||
-# Create a new folder named "${PACKAGE_VERSION}"
|
||||
-# Select new folder as the target for uploads.
|
||||
-# Upload files via Web interface into new
|
||||
-# Set platform types for each archive:
|
||||
- .tar.bz2: Linux, Mac
|
||||
- .tar.gz: BSD, Solaris, Others
|
||||
- .zip: Windows
|
||||
- Berlios:
|
||||
-# Create the new release for the new version.
|
||||
-# Provide @c NEWS and ChangeLog files, as requested.
|
||||
-# Upload files via FTP to ftp://ftp.berlios.de/incoming/
|
||||
-# Edit descriptions for each file.
|
||||
-# Send E-mail Release Notice
|
||||
-# Click button to send E-mail Release Notice.
|
||||
-# Post announcement e-mail to the openocd-development list.
|
||||
-# Announce updates on freshmeat.net and other trackers.
|
||||
-# Submit big updates to news feeds (e.g. Digg, Reddit, etc.).
|
||||
@@ -251,7 +285,7 @@ Many of the processes described in the last section are no longer
|
||||
entrusted to humans. Instead, the @c release.sh script provides
|
||||
automation of the mechanical steps.
|
||||
|
||||
Presently, the @c release.sh script automates steps 1(c) through 4,
|
||||
Presently, the @c release.sh script automates steps 2 through 4,
|
||||
allowing the Release Manager from perform these tasks in easy steps.
|
||||
|
||||
The following task still need to be automated:
|
||||
@@ -261,61 +295,34 @@ The following task still need to be automated:
|
||||
- Step 6(b): package announcement e-mail process.
|
||||
- Step 6(c): post files and announce them using releaseforge.
|
||||
|
||||
In addition, support for '-rc' releases needs to be added.
|
||||
|
||||
@subsection releasescriptcmds Release Script Commands
|
||||
|
||||
The following output was taken from the release script:
|
||||
@verbatim
|
||||
usage: tools/release.sh [options] <command>
|
||||
The release script can be used for two tasks:
|
||||
- Creating releases and starting a new release cycle:
|
||||
@code
|
||||
git checkout master
|
||||
tools/release.sh --type=minor --final --start-rc release
|
||||
@endcode
|
||||
- Creating a development branch from a tagged release:
|
||||
@code
|
||||
git checkout 'v0.2.0'
|
||||
tools/release.sh --type=micro branch
|
||||
@endcode
|
||||
|
||||
Main Commands:
|
||||
info Show a summary of the next pending release.
|
||||
release Release the current tree as an archive.
|
||||
upload Upload archives to berliOS project site
|
||||
Both of these variations make automatic commits and tags in your
|
||||
repository, so you should be sure to run it on a cloned copy before
|
||||
proceding with a live release.
|
||||
|
||||
Build Commands:
|
||||
bootstrap Prepare the working copy for configuration and building.
|
||||
configure Configures the package; runs bootstrap, if needed.
|
||||
build Compiles the project; runs configure, if needed.
|
||||
|
||||
Packaging Commands:
|
||||
changelog Generate a new ChangeLog using svn2cl.
|
||||
package Produce new distributable source archives.
|
||||
stage Move archives to staging area for upload.
|
||||
|
||||
Repository Commands:
|
||||
commit Perform branch and tag, as appropriate for the version.
|
||||
branch Create a release branch from the project trunk.
|
||||
tag Create a tag for the current release branch.
|
||||
|
||||
Other Commands:
|
||||
version ... Perform version number and tag manipulations.
|
||||
clean Forces regeneration of results.
|
||||
clean_all Removes all traces of the release process.
|
||||
help Provides this list of commands.
|
||||
|
||||
For more information about this script, see the Release Processes page
|
||||
in the OpenOCD Developer's Manual (doc/manual/release.txt).
|
||||
|
||||
WARNING: This script should be used by the Release Manager ONLY.
|
||||
@endverbatim
|
||||
|
||||
Run <code>tools/release.sh help</code> for current command support.
|
||||
|
||||
@subsection releasescriptenv Release Script Options
|
||||
@subsection releasescriptopts Release Script Options
|
||||
|
||||
The @c release.sh script recognizes some command-line options that
|
||||
affect its behavior:
|
||||
|
||||
- @c --live : Use this option to perform a live release.
|
||||
When this option has been given, the release commands will affect
|
||||
the repository; otherwise, the script reports the actions to take,
|
||||
and it produces archives that are unsuitable for public release.
|
||||
|
||||
@note Only the Release Manager should use the @c --live option, as
|
||||
it will make permanent changes to the Subversion repository that
|
||||
cannot be undone.
|
||||
- The @c --start-rc indicates that the new development release cycle
|
||||
should start with @c -rc0. Without this, the @c -rc tag will be omitted,
|
||||
leading to non-monotonic versioning of the in-tree version numbers.
|
||||
- The @c --final indicates that the release should drop the @c -rc tag,
|
||||
to going from @c x.y.z-rcN-dev to x.y.z.
|
||||
|
||||
@subsection releasescriptenv Release Script Environment
|
||||
|
||||
@@ -327,66 +334,9 @@ affect its behavior:
|
||||
|
||||
@section releasetutorial Release Tutorials
|
||||
|
||||
This section provides tutorials for using the Release Script to perform
|
||||
common release tasks.
|
||||
|
||||
@subsection releasetutorialsetup Release Tutorial Setup
|
||||
|
||||
The tutorials in this section assume the following environment
|
||||
variables have been set properly:
|
||||
@verbatim
|
||||
SVN_USER="maintainer"
|
||||
SVN_URL="https://${SVN_USER}@svn.berlios.de/svnroot/repos/openocd"
|
||||
@endverbatim
|
||||
|
||||
@subsection releasetutorialminor Minor Release Tutorial
|
||||
|
||||
This section provides a step-by-step tutorial for a Release Manager to
|
||||
use to run the @c release.sh script to produce a minor release.
|
||||
|
||||
If the proper environment has been set, the following steps will produce
|
||||
a new minor release:
|
||||
|
||||
-# Check out (or update) the project trunk from the berliOS repository:
|
||||
@code
|
||||
svn checkout "${SVN_URL}/trunk" openocd-trunk
|
||||
@endcode
|
||||
-# Change to the new working copy directory:
|
||||
@code
|
||||
cd openocd-trunk
|
||||
@endcode
|
||||
-# Run @c release.sh to produce the minor release:
|
||||
@code
|
||||
tools/release.sh all
|
||||
@endcode
|
||||
|
||||
@subsection releasetutorialmicro Bug-Fix Release Tutorial
|
||||
|
||||
This section provides a step-by-step tutorial for a Release Manager to
|
||||
use to run the @c release.sh script to produce a bug-fix release.
|
||||
|
||||
In addition to the environment variables described in the introduction
|
||||
to these tutorials, the following variables are also used in the
|
||||
instructions for this section:
|
||||
@verbatim
|
||||
PACKAGE_BRANCH_VERSION="x.y.z"
|
||||
PACKAGE_BRANCH="openocd-${PACKAGE_BRANCH_VERSION}"
|
||||
@endverbatim
|
||||
|
||||
If the proper environment has been set, the following steps will produce
|
||||
a new bug-fix release:
|
||||
|
||||
-# Check out (or update) the release branch from the project repository:
|
||||
@code
|
||||
svn checkout "${SVN_URL}/branches/${PACKAGE_BRANCH}" "${PACKAGE_BRANCH}"
|
||||
@endcode
|
||||
@code
|
||||
cd "${PACKAGE_BRANCH}"
|
||||
@endcode
|
||||
-# Run @c release.sh to produce the bug-fix release:
|
||||
@code
|
||||
tools/release.sh all
|
||||
@endcode
|
||||
This section should contain a brief tutorial for using the Release
|
||||
Script to perform release tasks, but the new script needs to be
|
||||
used for 0.3.0.
|
||||
|
||||
@section releasetodo Release Script Shortcomings
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
The scripting support is intended for developers of OpenOCD.
|
||||
It is not the intention that normal OpenOCD users will
|
||||
use tcl scripting extensively, write lots of clever scripts,
|
||||
or contribute back to OpenOCD.
|
||||
or contribute back to OpenOCD.
|
||||
|
||||
Target scripts can contain new procedures that end users may
|
||||
tinker to their needs without really understanding tcl.
|
||||
@@ -15,7 +15,7 @@ language, the choice of language is not terribly important
|
||||
to those same end users.
|
||||
|
||||
Jim Tcl was chosen as it was easy to integrate, works
|
||||
great in an embedded environment and Øyvind Harboe
|
||||
great in an embedded environment and Øyvind Harboe
|
||||
had experience with it.
|
||||
|
||||
@section scriptinguses Uses of scripting
|
||||
@@ -31,7 +31,7 @@ Default implementation of procedures in tcl/procedures.tcl.
|
||||
file format and structure of serialnumber. Tcl allows
|
||||
an argument to consist of e.g. a list so the structure of
|
||||
the serial number is not limited to a single string.
|
||||
- reset handling. Precise control of how srst, trst &
|
||||
- reset handling. Precise control of how srst, trst &
|
||||
tms is handled.
|
||||
- replace some parts of the current command line handler.
|
||||
This is only to simplify the implementation of OpenOCD
|
||||
@@ -42,7 +42,7 @@ Default implementation of procedures in tcl/procedures.tcl.
|
||||
that return machine readable output. These low level tcl
|
||||
functions constitute the tcl api. flash_banks is such
|
||||
a low level tcl proc. "flash banks" is an example of
|
||||
a command that has human readable output. The human
|
||||
a command that has human readable output. The human
|
||||
readable output is expected to change inbetween versions
|
||||
of OpenOCD. The output from flash_banks may not be
|
||||
in the preferred form for the client. The client then
|
||||
@@ -50,8 +50,8 @@ Default implementation of procedures in tcl/procedures.tcl.
|
||||
or b) write a small piece of tcl to output the
|
||||
flash_banks output to a more suitable form. The latter may
|
||||
be simpler.
|
||||
|
||||
|
||||
|
||||
|
||||
@section scriptingexternal External scripting
|
||||
|
||||
The embedded Jim Tcl interpreter in OpenOCD is very limited
|
||||
|
||||
@@ -32,14 +32,14 @@ high-level interface to OpenOCD, because they only had two choices:
|
||||
- the ablity to write a complex internal commands: native 'commands'
|
||||
inside of OpenOCD was complicated.
|
||||
|
||||
Fundamentally, the basic problem with both of those would be solved
|
||||
Fundamentally, the basic problem with both of those would be solved
|
||||
with a script language:
|
||||
|
||||
-# <b>Internal</b>: simple, small, and self-contained.
|
||||
-# <b>Cross Language</b>: script friendly front-end
|
||||
-# <b>Cross Host</b>: GUI Host interface
|
||||
-# <b>Cross Debugger</b>: GUI-like interface
|
||||
|
||||
|
||||
What follows hopefully shows how the plans to solve these problems
|
||||
materialized and help to explain the grand roadmap plan.
|
||||
|
||||
@@ -64,7 +64,7 @@ file, allowing OpenOCD to avoid the spider web of dependent packages.
|
||||
|
||||
The TCL Server port was added in mid-2008. With embedded TCL, we can
|
||||
write scripts internally to help things, or we can write "C" code that
|
||||
interfaces well with TCL.
|
||||
interfaces well with TCL.
|
||||
|
||||
From there, the developers wanted to create an external front-end that
|
||||
would be @a very usable and that that @a any language could utilize,
|
||||
@@ -81,7 +81,7 @@ terse, simple ASCII protocols that are emensely parsable by a script.
|
||||
Thus, the TCL server -- a 'machine' type socket interface -- was added
|
||||
with the hope was it would output simple "name-value" pair type
|
||||
data. At the time, simple name/value pairs seemed reasonably easier to
|
||||
do at the time, though Maybe it should output JSON;
|
||||
do at the time, though Maybe it should output JSON;
|
||||
|
||||
See here:
|
||||
|
||||
@@ -101,17 +101,17 @@ How do we solve that problem?
|
||||
For example, Cygwin can be painful, Cygwin GUI packages want X11
|
||||
to be present, crossing the barrier between MinGW and Cygwin is
|
||||
painful, let alone getting the GUI front end to work on MacOS, and
|
||||
Linux, yuck yuck yuck. Painful. very very painful.
|
||||
Linux, yuck yuck yuck. Painful. very very painful.
|
||||
|
||||
What works easier and is less work is what is already present in every
|
||||
platform? The answer: A web browser. In other words, OpenOCD could
|
||||
serve out embedded web pages via "localhost" to your browser.
|
||||
serve out embedded web pages via "localhost" to your browser.
|
||||
|
||||
Long before OpenOCD had a TCL command line, Zylin AS built their ZY1000
|
||||
devince with a built-in HTTP server. Later, they were willing to both
|
||||
contribute and integrate most of that work into the main tree.
|
||||
|
||||
@subsection serverdocsother Other Options Concidered
|
||||
@subsection serverdocsother Other Options Considered
|
||||
|
||||
What if a web browser is not acceptable ie: You want to write your own
|
||||
front gadget in Eclipse, or KDevelop, or PerlTK, Ruby, or what ever
|
||||
@@ -169,7 +169,7 @@ the Socket Approach is used.
|
||||
|
||||
During 2008, Duane Ellis created some TCL scripts to display peripheral
|
||||
register contents. For example, look at the sam7 TCL scripts, and the
|
||||
stm32 TCL scripts. The hope was others would create more.
|
||||
stm32 TCL scripts. The hope was others would create more.
|
||||
|
||||
|
||||
A good example of this is display/view the peripheral registers on
|
||||
@@ -215,7 +215,7 @@ One reason might be, this adds one more host side requirement to make
|
||||
use of the feature. In other words, one could write a Python/TK
|
||||
front-end, but it is only useable if you have Python/TK installed.
|
||||
Maybe this can be done via Ecllipse, but not all developers use Ecplise.
|
||||
Many devlopers use Emacs (possibly with GUD mode) or vim and will not
|
||||
Many devlopers use Emacs (possibly with GUD mode) or vim and will not
|
||||
accept such an interface. The next developer reading this might be
|
||||
using Insight (GDB-TK) - and somebody else - DDD..
|
||||
|
||||
@@ -311,6 +311,15 @@ This section needs to be expanded.
|
||||
|
||||
/** @page serverhttp OpenOCD HTTP Server API
|
||||
|
||||
This section needs to be expanded.
|
||||
|
||||
Smoketest:
|
||||
|
||||
configure --enable-httpd --enable-dummy --enable-ioutil
|
||||
|
||||
openocd -s /usr/local/share/openocd -f httpd/httpd.tcl -f interface/dummy.cfg -f target/lpc2148.cfg
|
||||
|
||||
Navigate to: http://localhost:8888/
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
@@ -49,7 +49,7 @@ OpenOCD project.
|
||||
- limit adjacent empty lines to at most two (2).
|
||||
- remove any trailing empty lines at the end of source files
|
||||
- do not "comment out" code from the tree; instead, one should either:
|
||||
-# remove it entirely (Subversion can retrieve the old version), or
|
||||
-# remove it entirely (git can retrieve the old version), or
|
||||
-# use an @c \#if/\#endif block.
|
||||
|
||||
Finally, try to avoid lines of code that are longer than than 72-80 columns:
|
||||
@@ -149,7 +149,7 @@ comments.
|
||||
* in blocks such as the one in which this example appears in the Style
|
||||
* Guide. See the Doxygen Manual for the full list of commands.
|
||||
*
|
||||
* @param foo For a function, describe the parameters (e.g. @a foo).
|
||||
* @param foo For a function, describe the parameters (e.g. @a foo).
|
||||
* @returns The value(s) returned, or possible error conditions.
|
||||
*/
|
||||
@endverbatim
|
||||
@@ -229,7 +229,7 @@ This file contains the @ref pagename page.
|
||||
@endverbatim
|
||||
|
||||
For an example, the Doxygen source for this Style Guide can be found in
|
||||
@c doc/manual/style.txt, alongside other parts of The Manual.
|
||||
@c doc/manual/style.txt, alongside other parts of The Manual.
|
||||
|
||||
*/
|
||||
/** @page styletexinfo Texinfo Style Guide
|
||||
@@ -344,7 +344,7 @@ Likewise, the @ref primerlatex for using this guide needs to be completed.
|
||||
This page provides some style guidelines for using Perl, a scripting
|
||||
language used by several small tools in the tree:
|
||||
|
||||
-# Ensure all Perl scripts use the proper suffix (@c .pl for scripts, and
|
||||
-# Ensure all Perl scripts use the proper suffix (@c .pl for scripts, and
|
||||
@c .pm for modules)
|
||||
-# Pass files as script parameters or piped as input:
|
||||
- Do NOT code paths to files in the tree, as this breaks out-of-tree builds.
|
||||
@@ -358,10 +358,8 @@ perl script.pl
|
||||
|
||||
Maintainers must also be sure to follow additional guidelines:
|
||||
-# Ensure that Perl scripts are committed as executables:
|
||||
- Use "<code>chmod +x script.pl</code>"
|
||||
@a before using "<code>svn add script.pl</code>", or
|
||||
- Use "<code>svn ps svn:executable '*' script.pl</code>"
|
||||
@a after using "<code>svn add script.pl</code>".
|
||||
Use "<code>chmod +x script.pl</code>"
|
||||
@a before using "<code>git add script.pl</code>"
|
||||
|
||||
*/
|
||||
/** @page styleautotools Autotools Style Guide
|
||||
|
||||
@@ -37,7 +37,7 @@ mailing list
|
||||
@section targetnotarmsupport Target Support
|
||||
|
||||
target.h is relatively CPU agnostic and
|
||||
the intention is to move in the direction of less
|
||||
the intention is to move in the direction of less
|
||||
instruction set specific.
|
||||
|
||||
Non-CPU targets are also supported, but there isn't
|
||||
@@ -56,7 +56,7 @@ OpenOCD does not today have targets that use non-JTAG.
|
||||
The actual physical layer is a relatively modest part
|
||||
of the total OpenOCD system.
|
||||
|
||||
|
||||
|
||||
@section targetnotarmppc PowerPC
|
||||
|
||||
there exists open source implementations of powerpc
|
||||
|
||||
@@ -8,19 +8,19 @@ boundary\-scan testing tool for ARM and MIPS systems
|
||||
.B OpenOCD
|
||||
is an on\-chip debugging, in\-system programming and boundary\-scan
|
||||
testing tool for various ARM and MIPS systems.
|
||||
.PP
|
||||
.PP
|
||||
The debugger uses an IEEE 1149\-1 compliant JTAG TAP bus master to access
|
||||
on\-chip debug functionality available on ARM based microcontrollers or
|
||||
system-on-chip solutions. For MIPS systems the EJTAG interface is supported.
|
||||
.PP
|
||||
.PP
|
||||
User interaction is realized through a telnet command line interface,
|
||||
a gdb (the GNU debugger) remote protocol server, and a simplified RPC
|
||||
connection that can be used to interface with OpenOCD's Jim Tcl engine.
|
||||
.PP
|
||||
.PP
|
||||
OpenOCD supports various different types of JTAG interfaces/programmers,
|
||||
please check the \fIopenocd\fR info page for the complete list.
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
.TP
|
||||
.B "\-f, \-\-file <filename>"
|
||||
Use configuration file
|
||||
.BR <filename> .
|
||||
@@ -29,43 +29,43 @@ In order to specify multiple config files, you can use multiple
|
||||
arguments. If this option is omitted, the config file
|
||||
.B openocd.cfg
|
||||
in the current working directory will be used.
|
||||
.TP
|
||||
.TP
|
||||
.B "\-s, \-\-search <dirname>"
|
||||
Search for config files and scripts in the directory
|
||||
.BR <dirname> .
|
||||
If this option is omitted, OpenOCD searches for config files and scripts
|
||||
in the current directory.
|
||||
.TP
|
||||
.TP
|
||||
.B "\-d, \-\-debug <debuglevel>"
|
||||
Set debug level. Possible values are:
|
||||
.br
|
||||
.br
|
||||
.RB " * " 0 " (errors)"
|
||||
.br
|
||||
.br
|
||||
.RB " * " 1 " (warnings)"
|
||||
.br
|
||||
.br
|
||||
.RB " * " 2 " (informational messages)"
|
||||
.br
|
||||
.br
|
||||
.RB " * " 3 " (debug messages)"
|
||||
.br
|
||||
.br
|
||||
The default level is
|
||||
.BR 2 .
|
||||
.TP
|
||||
.TP
|
||||
.B "\-l, \-\-log_output <filename>"
|
||||
Redirect log output to the file
|
||||
.BR <filename> .
|
||||
Per default the log output is printed on
|
||||
.BR stderr .
|
||||
.TP
|
||||
.TP
|
||||
.B "\-c, \-\-command <cmd>"
|
||||
Run the command
|
||||
.BR <cmd> .
|
||||
.TP
|
||||
.TP
|
||||
.B "\-p, \-\-pipe"
|
||||
Use pipes when talking to gdb.
|
||||
.TP
|
||||
.TP
|
||||
.B "\-h, \-\-help"
|
||||
Show a help text and exit.
|
||||
.TP
|
||||
.TP
|
||||
.B "\-v, \-\-version"
|
||||
Show version information and exit.
|
||||
.SH "BUGS"
|
||||
@@ -95,6 +95,6 @@ Also, the OpenOCD wiki contains some more information and examples:
|
||||
.B http://openfacts.berlios.de/index-en.phtml?title=Open_On-Chip_Debugger
|
||||
.SH "AUTHORS"
|
||||
Please see the file AUTHORS.
|
||||
.PP
|
||||
.PP
|
||||
This manual page was written by Uwe Hermann <uwe@hermann\-uwe.de>.
|
||||
It is licensed under the terms of the GNU GPL (version 2 or later).
|
||||
|
||||
1452
doc/openocd.texi
1452
doc/openocd.texi
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
#####ECOSGPLCOPYRIGHTBEGIN####
|
||||
## -------------------------------------------
|
||||
## This file is part of eCos, the Embedded Configurable Operating System.
|
||||
## Copyright (C) 2008 Øyvind Harboe
|
||||
## Copyright (C) 2008 Øyvind Harboe
|
||||
##
|
||||
## eCos is free software; you can redistribute it and/or modify it under
|
||||
## the terms of the GNU General Public License as published by the Free
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#####ECOSGPLCOPYRIGHTBEGIN####
|
||||
## -------------------------------------------
|
||||
## This file is part of eCos, the Embedded Configurable Operating System.
|
||||
## Copyright (C) 2008 Øyvind Harboe
|
||||
## Copyright (C) 2008 Øyvind Harboe
|
||||
##
|
||||
## eCos is free software; you can redistribute it and/or modify it under
|
||||
## the terms of the GNU General Public License as published by the Free
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#####ECOSGPLCOPYRIGHTBEGIN####
|
||||
## -------------------------------------------
|
||||
## This file is part of eCos, the Embedded Configurable Operating System.
|
||||
## Copyright (C) 2008 Øyvind Harboe
|
||||
## Copyright (C) 2008 Øyvind Harboe
|
||||
##
|
||||
## eCos is free software; you can redistribute it and/or modify it under
|
||||
## the terms of the GNU General Public License as published by the Free
|
||||
@@ -53,7 +53,7 @@ int init()
|
||||
*t=0;
|
||||
}
|
||||
return flash_init((_printf *)&myprintf);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -68,15 +68,15 @@ int checkFlash(void *addr, int len)
|
||||
}
|
||||
|
||||
|
||||
int erase(void *address, int len)
|
||||
int erase(void *address, int len)
|
||||
{
|
||||
int retval;
|
||||
void *failAddress;
|
||||
|
||||
|
||||
retval=checkFlash(address, len);
|
||||
if (retval!=0)
|
||||
return retval;
|
||||
|
||||
|
||||
retval=init();
|
||||
if (retval!=0)
|
||||
return retval;
|
||||
@@ -88,14 +88,14 @@ int erase(void *address, int len)
|
||||
extern char _end;
|
||||
|
||||
// Data follows immediately after program, long word aligned.
|
||||
int program(void *buffer, void *address, int len)
|
||||
int program(void *buffer, void *address, int len)
|
||||
{
|
||||
int retval;
|
||||
void *failAddress;
|
||||
retval=checkFlash(address, len);
|
||||
if (retval!=0)
|
||||
return retval;
|
||||
|
||||
|
||||
retval=init();
|
||||
if (retval!=0)
|
||||
return retval;
|
||||
|
||||
83
guess-rev.sh
83
guess-rev.sh
@@ -1,8 +1,83 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
#
|
||||
# This scripts adds local version information from the version
|
||||
# control systems git, mercurial (hg) and subversion (svn).
|
||||
#
|
||||
# Copied from Linux 2.6.32 scripts/setlocalversion and modified
|
||||
# slightly to work better for OpenOCD.
|
||||
#
|
||||
|
||||
REV=unknown
|
||||
usage() {
|
||||
echo "Usage: $0 [srctree]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
which svnversion > /dev/null 2>&1 && REV=`svnversion -n "$1"`
|
||||
cd "${1:-.}" || usage
|
||||
|
||||
echo -n $REV
|
||||
# Check for git and a git repo.
|
||||
if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
|
||||
|
||||
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore it,
|
||||
# because this version is defined in the top level Makefile.
|
||||
if [ -z "`git describe --exact-match 2>/dev/null`" ]; then
|
||||
|
||||
# If we are past a tagged commit (like "v2.6.30-rc5-302-g72357d5"),
|
||||
# we pretty print it.
|
||||
if atag="`git describe 2>/dev/null`"; then
|
||||
echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
|
||||
|
||||
# If we don't have a tag at all we print -g{commitish}.
|
||||
else
|
||||
printf '%s%s' -g $head
|
||||
fi
|
||||
fi
|
||||
|
||||
# Is this git on svn?
|
||||
if git config --get svn-remote.svn.url >/dev/null; then
|
||||
printf -- '-svn%s' "`git svn find-rev $head`"
|
||||
fi
|
||||
|
||||
# Update index only on r/w media
|
||||
[ -w . ] && git update-index --refresh --unmerged > /dev/null
|
||||
|
||||
# Check for uncommitted changes
|
||||
if git diff-index --name-only HEAD | grep -v "^scripts/package" \
|
||||
| read dummy; then
|
||||
printf '%s' -dirty
|
||||
fi
|
||||
|
||||
# All done with git
|
||||
exit
|
||||
fi
|
||||
|
||||
# Check for mercurial and a mercurial repo.
|
||||
if hgid=`hg id 2>/dev/null`; then
|
||||
tag=`printf '%s' "$hgid" | cut -d' ' -f2`
|
||||
|
||||
# Do we have an untagged version?
|
||||
if [ -z "$tag" -o "$tag" = tip ]; then
|
||||
id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
|
||||
printf '%s%s' -hg "$id"
|
||||
fi
|
||||
|
||||
# Are there uncommitted changes?
|
||||
# These are represented by + after the changeset id.
|
||||
case "$hgid" in
|
||||
*+|*+\ *) printf '%s' -dirty ;;
|
||||
esac
|
||||
|
||||
# All done with mercurial
|
||||
exit
|
||||
fi
|
||||
|
||||
# Check for svn and a svn repo.
|
||||
if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
|
||||
rev=`echo $rev | awk '{print $NF}'`
|
||||
printf -- '-svn%s' "$rev"
|
||||
|
||||
# All done with svn
|
||||
exit
|
||||
fi
|
||||
|
||||
# There's no reecognized repository; we must be a snapshot.
|
||||
printf -- '-snapshot'
|
||||
|
||||
@@ -9,7 +9,7 @@ else
|
||||
MAINFILE = main.c
|
||||
endif
|
||||
|
||||
openocd_SOURCES = $(MAINFILE)
|
||||
openocd_SOURCES = $(MAINFILE)
|
||||
openocd_LDADD = libopenocd.la
|
||||
|
||||
libopenocd_la_SOURCES = openocd.c
|
||||
@@ -28,20 +28,22 @@ AM_CPPFLAGS = \
|
||||
|
||||
libopenocd_la_CPPFLAGS = -DPKGBLDDATE=\"`date +%F-%R`\"
|
||||
|
||||
# banner output includes RELSTR appended to $VERSION from the configure script
|
||||
# guess-rev.sh returns either a repository version ID or "-snapshot"
|
||||
if RELEASE
|
||||
libopenocd_la_CPPFLAGS += -DRELSTR=\"Release\" -DPKGBLDREV=\"\"
|
||||
libopenocd_la_CPPFLAGS += -DRELSTR=\"\"
|
||||
else
|
||||
libopenocd_la_CPPFLAGS += -DRELSTR=\"svn:\" -DPKGBLDREV=\"`$(top_srcdir)/guess-rev.sh $(top_srcdir)`\"
|
||||
libopenocd_la_CPPFLAGS += -DRELSTR=\"`$(top_srcdir)/guess-rev.sh $(top_srcdir)`\"
|
||||
endif
|
||||
|
||||
# add default CPPFLAGS
|
||||
libopenocd_la_CPPFLAGS += $(AM_CPPFLAGS) $(CPPFLAGS)
|
||||
|
||||
# the library search path.
|
||||
libopenocd_la_LDFLAGS = $(all_libraries)
|
||||
libopenocd_la_LDFLAGS = $(all_libraries)
|
||||
|
||||
if IS_MINGW
|
||||
MINGWLDADD = -lwsock32
|
||||
MINGWLDADD = -lws2_32
|
||||
else
|
||||
MINGWLDADD =
|
||||
endif
|
||||
@@ -97,6 +99,6 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
|
||||
# assumption is: You are only rebuilding the EXE.... and everything
|
||||
# else is/was previously installed.
|
||||
#
|
||||
# use at your own risk
|
||||
# use at your own risk
|
||||
quick: all install-binPROGRAMS
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007-2008 by <EFBFBD>yvind Harboe *
|
||||
* 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 *
|
||||
@@ -155,8 +155,8 @@ 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("Rebooting in 500 ticks..\n");
|
||||
cyg_thread_delay(500);
|
||||
diag_printf("Unmounting /config..\n");
|
||||
umount("/config");
|
||||
diag_printf("Rebooting..\n");
|
||||
@@ -328,6 +328,7 @@ void openocd_sleep_postlude(void)
|
||||
|
||||
void format(void)
|
||||
{
|
||||
#ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
|
||||
diag_printf("Formatting JFFS2...\n");
|
||||
|
||||
cyg_io_handle_t handle;
|
||||
@@ -365,6 +366,7 @@ void format(void)
|
||||
}
|
||||
|
||||
diag_printf("Flash formatted successfully\n");
|
||||
#endif
|
||||
|
||||
reboot();
|
||||
}
|
||||
@@ -503,7 +505,7 @@ static void zylinjtag_startNetwork(void)
|
||||
|
||||
Jim_CreateCommand(httpstate.jim_interp, "log", zylinjtag_Jim_Command_log,
|
||||
NULL, NULL);
|
||||
Jim_CreateCommand(httpstate.jim_interp, "reboot",
|
||||
Jim_CreateCommand(httpstate.jim_interp, "zy1000_reboot",
|
||||
zylinjtag_Jim_Command_reboot, NULL, NULL);
|
||||
Jim_CreateCommand(httpstate.jim_interp, "threads",
|
||||
zylinjtag_Jim_Command_threads, NULL, NULL);
|
||||
@@ -623,6 +625,9 @@ void setNoDelay(int session, int flag)
|
||||
#endif
|
||||
}
|
||||
|
||||
#define TEST_TCPIP() 0
|
||||
|
||||
#if TEST_TCPIP
|
||||
struct
|
||||
{
|
||||
int req;
|
||||
@@ -631,6 +636,7 @@ struct
|
||||
int actual2;
|
||||
} tcpipSent[512 * 1024];
|
||||
int cur;
|
||||
#endif
|
||||
|
||||
static void zylinjtag_uart(cyg_addrword_t data)
|
||||
{
|
||||
@@ -695,7 +701,9 @@ static void zylinjtag_uart(cyg_addrword_t data)
|
||||
size_t pos, pos2;
|
||||
pos = 0;
|
||||
pos2 = 0;
|
||||
#if TEST_TCPIP
|
||||
cur = 0;
|
||||
#endif
|
||||
for (;;)
|
||||
{
|
||||
fd_set write_fds;
|
||||
@@ -796,6 +804,7 @@ static void zylinjtag_uart(cyg_addrword_t data)
|
||||
}
|
||||
y2 = written;
|
||||
}
|
||||
#if TEST_TCPIP
|
||||
if (cur < 1024)
|
||||
{
|
||||
tcpipSent[cur].req = x;
|
||||
@@ -804,11 +813,12 @@ static void zylinjtag_uart(cyg_addrword_t data)
|
||||
tcpipSent[cur].actual2 = y2;
|
||||
cur++;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
closeSession: close(session);
|
||||
close(serHandle);
|
||||
|
||||
#if TEST_TCPIP
|
||||
int i;
|
||||
for (i = 0; i < 1024; i++)
|
||||
{
|
||||
@@ -816,6 +826,7 @@ static void zylinjtag_uart(cyg_addrword_t data)
|
||||
tcpipSent[i].req2, tcpipSent[i].actual2);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
close(fd);
|
||||
|
||||
@@ -918,7 +929,7 @@ command_context_t *setup_command_handler(void);
|
||||
|
||||
static const char *zylin_config_dir="/config/settings";
|
||||
|
||||
int add_default_dirs(void)
|
||||
static int add_default_dirs(void)
|
||||
{
|
||||
add_script_search_dir(zylin_config_dir);
|
||||
add_script_search_dir("/rom/lib/openocd");
|
||||
|
||||
@@ -6,8 +6,11 @@ AM_CPPFLAGS = \
|
||||
METASOURCES = AUTO
|
||||
noinst_LTLIBRARIES = libflash.la
|
||||
libflash_la_SOURCES = \
|
||||
arm_nandio.c \
|
||||
flash.c \
|
||||
lpc2000.c \
|
||||
lpc288x.c \
|
||||
lpc2900.c \
|
||||
cfi.c \
|
||||
non_cfi.c \
|
||||
at91sam7.c \
|
||||
@@ -31,15 +34,19 @@ libflash_la_SOURCES = \
|
||||
s3c2412_nand.c \
|
||||
s3c2440_nand.c \
|
||||
s3c2443_nand.c \
|
||||
lpc288x.c \
|
||||
ocl.c \
|
||||
mflash.c \
|
||||
pic32mx.c \
|
||||
avrf.c
|
||||
avrf.c \
|
||||
faux.c \
|
||||
mx3_nand.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
arm_nandio.h \
|
||||
flash.h \
|
||||
lpc2000.h \
|
||||
lpc288x.h \
|
||||
lpc2900.h \
|
||||
cfi.h \
|
||||
non_cfi.h \
|
||||
at91sam7.h \
|
||||
@@ -54,10 +61,10 @@ noinst_HEADERS = \
|
||||
tms470.h \
|
||||
s3c24xx_nand.h \
|
||||
s3c24xx_regs_nand.h \
|
||||
lpc288x.h \
|
||||
mflash.h \
|
||||
ocl.h \
|
||||
pic32mx.h \
|
||||
avrf.h
|
||||
avrf.h \
|
||||
mx3_nand.h
|
||||
|
||||
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
|
||||
|
||||
134
src/flash/arm_nandio.c
Normal file
134
src/flash/arm_nandio.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2009 by Marvell Semiconductors, Inc.
|
||||
* Written by Nicolas Pitre <nico at marvell.com>
|
||||
*
|
||||
* Copyright (C) 2009 by David Brownell
|
||||
*
|
||||
* 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 "arm_nandio.h"
|
||||
#include "armv4_5.h"
|
||||
|
||||
|
||||
/*
|
||||
* ARM-specific bulk write from buffer to address of 8-bit wide NAND.
|
||||
* For now this only supports ARMv4 and ARMv5 cores.
|
||||
*
|
||||
* Enhancements to target_run_algorithm() could enable:
|
||||
* - ARMv6 and ARMv7 cores in ARM mode
|
||||
*
|
||||
* Different code fragments could handle:
|
||||
* - Thumb2 cores like Cortex-M (needs different byteswapping)
|
||||
* - 16-bit wide data (needs different setup too)
|
||||
*/
|
||||
int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size)
|
||||
{
|
||||
target_t *target = nand->target;
|
||||
armv4_5_algorithm_t algo;
|
||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||
reg_param_t reg_params[3];
|
||||
uint32_t target_buf;
|
||||
uint32_t exit = 0;
|
||||
int retval;
|
||||
|
||||
/* Inputs:
|
||||
* r0 NAND data address (byte wide)
|
||||
* r1 buffer address
|
||||
* r2 buffer length
|
||||
*/
|
||||
static const uint32_t code[] = {
|
||||
0xe4d13001, /* s: ldrb r3, [r1], #1 */
|
||||
0xe5c03000, /* strb r3, [r0] */
|
||||
0xe2522001, /* subs r2, r2, #1 */
|
||||
0x1afffffb, /* bne s */
|
||||
|
||||
/* exit: ARMv4 needs hardware breakpoint */
|
||||
0xe1200070, /* e: bkpt #0 */
|
||||
};
|
||||
|
||||
if (!nand->copy_area) {
|
||||
uint8_t code_buf[sizeof(code)];
|
||||
unsigned i;
|
||||
|
||||
/* make sure we have a working area */
|
||||
if (target_alloc_working_area(target,
|
||||
sizeof(code) + nand->chunk_size,
|
||||
&nand->copy_area) != ERROR_OK) {
|
||||
LOG_DEBUG("%s: no %d byte buffer",
|
||||
__FUNCTION__,
|
||||
(int) sizeof(code) + nand->chunk_size);
|
||||
return ERROR_NAND_NO_BUFFER;
|
||||
}
|
||||
|
||||
/* buffer code in target endianness */
|
||||
for (i = 0; i < sizeof(code) / 4; i++)
|
||||
target_buffer_set_u32(target, code_buf + i * 4, code[i]);
|
||||
|
||||
/* copy code to work area */
|
||||
retval = target_write_memory(target,
|
||||
nand->copy_area->address,
|
||||
4, sizeof(code) / 4, code_buf);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* copy data to work area */
|
||||
target_buf = nand->copy_area->address + sizeof(code);
|
||||
retval = target_bulk_write_memory(target, target_buf, size / 4, data);
|
||||
if (retval == ERROR_OK && (size & 3) != 0)
|
||||
retval = target_write_memory(target,
|
||||
target_buf + (size & ~3),
|
||||
1, size & 3, data + (size & ~3));
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
/* set up algorithm and parameters */
|
||||
algo.common_magic = ARMV4_5_COMMON_MAGIC;
|
||||
algo.core_mode = ARMV4_5_MODE_SVC;
|
||||
algo.core_state = ARMV4_5_STATE_ARM;
|
||||
|
||||
init_reg_param(®_params[0], "r0", 32, PARAM_IN);
|
||||
init_reg_param(®_params[1], "r1", 32, PARAM_IN);
|
||||
init_reg_param(®_params[2], "r2", 32, PARAM_IN);
|
||||
|
||||
buf_set_u32(reg_params[0].value, 0, 32, nand->data);
|
||||
buf_set_u32(reg_params[1].value, 0, 32, target_buf);
|
||||
buf_set_u32(reg_params[2].value, 0, 32, size);
|
||||
|
||||
/* armv4 must exit using a hardware breakpoint */
|
||||
if (armv4_5->is_armv4)
|
||||
exit = nand->copy_area->address + sizeof(code) - 4;
|
||||
|
||||
/* use alg to write data from work area to NAND chip */
|
||||
retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
|
||||
nand->copy_area->address, exit, 1000, &algo);
|
||||
if (retval != ERROR_OK)
|
||||
LOG_ERROR("error executing hosted NAND write");
|
||||
|
||||
destroy_reg_param(®_params[0]);
|
||||
destroy_reg_param(®_params[1]);
|
||||
destroy_reg_param(®_params[2]);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* REVISIT do the same for bulk *read* too ... */
|
||||
|
||||
25
src/flash/arm_nandio.h
Normal file
25
src/flash/arm_nandio.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __ARM_NANDIO_H
|
||||
#define __ARM_NANDIO_H
|
||||
|
||||
#include "nand.h"
|
||||
#include "binarybuffer.h"
|
||||
|
||||
struct arm_nand_data {
|
||||
/* target is proxy for some ARM core */
|
||||
struct target_s *target;
|
||||
|
||||
/* copy_area holds write-to-NAND loop and data to write */
|
||||
struct working_area_s *copy_area;
|
||||
|
||||
/* chunk_size == page or ECC unit */
|
||||
unsigned chunk_size;
|
||||
|
||||
/* data == where to write the data */
|
||||
uint32_t data;
|
||||
|
||||
/* currently implicit: data width == 8 bits (not 16) */
|
||||
};
|
||||
|
||||
int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size);
|
||||
|
||||
#endif /* __ARM_NANDIO_H */
|
||||
@@ -1609,7 +1609,7 @@ static int
|
||||
sam3_protect_check(struct flash_bank_s *bank)
|
||||
{
|
||||
int r;
|
||||
uint32_t v;
|
||||
uint32_t v=0;
|
||||
unsigned x;
|
||||
struct sam3_bank_private *pPrivate;
|
||||
|
||||
|
||||
@@ -20,20 +20,30 @@
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************************************************************************************************************************
|
||||
/***************************************************************************
|
||||
*
|
||||
* New flash setup command:
|
||||
*
|
||||
* flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]
|
||||
* flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_id>
|
||||
* [<chip_type> <banks>
|
||||
* <sectors_per_bank> <pages_per_sector>
|
||||
* <page_size> <num_nvmbits>
|
||||
* <ext_freq_khz>]
|
||||
*
|
||||
* <ext_freq_khz> - MUST be used if clock is from external source,
|
||||
* CAN be used if main oscillator frequency is known (recomended)
|
||||
* CAN be used if main oscillator frequency is known (recommended)
|
||||
* Examples:
|
||||
* flash bank at91sam7 0x00100000 0 0 4 0 0 AT91SAM7XC256 1 16 64 256 3 25000 ==== RECOMENDED ============
|
||||
* flash bank at91sam7 0 0 0 0 0 0 0 0 0 0 0 0 25000 (auto-detection, except for clock) ==== RECOMENDED ============
|
||||
* flash bank at91sam7 0x00100000 0 0 4 0 0 AT91SAM7XC256 1 16 64 256 3 0 ==== NOT RECOMENDED !!! ====
|
||||
* flash bank at91sam7 0 0 0 0 0 (old style, full auto-detection) ==== NOT RECOMENDED !!! ====
|
||||
****************************************************************************************************************************************************************************************/
|
||||
* ==== RECOMMENDED (covers clock speed) ============
|
||||
* flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 25000
|
||||
* (if auto-detect fails; provides clock spec)
|
||||
* flash bank at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 25000
|
||||
* (auto-detect everything except the clock)
|
||||
* ==== NOT RECOMMENDED !!! (clock speed is not configured) ====
|
||||
* flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 0
|
||||
* (if auto-detect fails)
|
||||
* flash bank at91sam7 0 0 0 0 $_TARGETNAME
|
||||
* (old style, auto-detect everything)
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@@ -734,16 +744,6 @@ static int at91sam7_protect_check(struct flash_bank_s *bank)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************************************************************************************************************************
|
||||
# flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]
|
||||
# <ext_freq_khz> - MUST be used if clock is from external source
|
||||
# CAN be used if main oscillator frequency is known
|
||||
# Examples:
|
||||
# flash bank at91sam7 0x00100000 0 0 4 0 0 AT91SAM7XC256 1 16 64 256 3 25000 ==== RECOMENDED ============
|
||||
# flash bank at91sam7 0 0 0 0 0 0 0 0 0 0 0 0 25000 (auto-detection, except for clock) ==== RECOMENDED ============
|
||||
# flash bank at91sam7 0x00100000 0 0 4 0 0 AT91SAM7XC256 1 16 64 256 3 0 ==== NOT RECOMENDED !!! ====
|
||||
# flash bank at91sam7 0 0 0 0 0 (old style, full auto-detection) ==== NOT RECOMENDED !!! ====
|
||||
****************************************************************************************************************************************************************************************/
|
||||
static 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;
|
||||
|
||||
187
src/flash/cfi.c
187
src/flash/cfi.c
@@ -74,7 +74,7 @@ static void cfi_fixup_0002_unlock_addresses(flash_bank_t *flash, void *param);
|
||||
static void cfi_fixup_atmel_reversed_erase_regions(flash_bank_t *flash, void *param);
|
||||
|
||||
/* fixup after reading cmdset 0002 primary query table */
|
||||
static cfi_fixup_t cfi_0002_fixups[] = {
|
||||
static const cfi_fixup_t cfi_0002_fixups[] = {
|
||||
{CFI_MFR_SST, 0x00D4, cfi_fixup_0002_unlock_addresses, &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},
|
||||
{CFI_MFR_SST, 0x00D5, cfi_fixup_0002_unlock_addresses, &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},
|
||||
{CFI_MFR_SST, 0x00D6, cfi_fixup_0002_unlock_addresses, &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},
|
||||
@@ -90,14 +90,14 @@ static cfi_fixup_t cfi_0002_fixups[] = {
|
||||
};
|
||||
|
||||
/* fixup after reading cmdset 0001 primary query table */
|
||||
static cfi_fixup_t cfi_0001_fixups[] = {
|
||||
static const cfi_fixup_t cfi_0001_fixups[] = {
|
||||
{0, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static void cfi_fixup(flash_bank_t *bank, cfi_fixup_t *fixups)
|
||||
static void cfi_fixup(flash_bank_t *bank, const cfi_fixup_t *fixups)
|
||||
{
|
||||
cfi_flash_bank_t *cfi_info = bank->driver_priv;
|
||||
cfi_fixup_t *f;
|
||||
const cfi_fixup_t *f;
|
||||
|
||||
for (f = fixups; f->fixup; f++)
|
||||
{
|
||||
@@ -1125,11 +1125,11 @@ static int cfi_intel_write_block(struct flash_bank_s *bank, uint8_t *buffer, uin
|
||||
armv4_5_info.core_state = ARMV4_5_STATE_ARM;
|
||||
|
||||
/* If we are setting up the write_algorith, we need target_code_src */
|
||||
/* if not we only need target_code_size. */
|
||||
/* */
|
||||
/* However, we don't want to create multiple code paths, so we */
|
||||
/* do the unecessary evaluation of target_code_src, which the */
|
||||
/* compiler will probably nicely optimize away if not needed */
|
||||
/* if not we only need target_code_size. */
|
||||
|
||||
/* However, we don't want to create multiple code paths, so we */
|
||||
/* do the unecessary evaluation of target_code_src, which the */
|
||||
/* compiler will probably nicely optimize away if not needed */
|
||||
|
||||
/* prepare algorithm code for target endian */
|
||||
switch (bank->bus_width)
|
||||
@@ -1384,6 +1384,31 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
|
||||
0xeafffffe /* b 81ac <sp_16_done> */
|
||||
};
|
||||
|
||||
static const uint32_t word_16_code_dq7only[] = {
|
||||
/* <sp_16_code>: */
|
||||
0xe0d050b2, /* ldrh r5, [r0], #2 */
|
||||
0xe1c890b0, /* strh r9, [r8] */
|
||||
0xe1cab0b0, /* strh r11, [r10] */
|
||||
0xe1c830b0, /* strh r3, [r8] */
|
||||
0xe1c150b0, /* strh r5, [r1] */
|
||||
0xe1a00000, /* nop (mov r0,r0) */
|
||||
/* */
|
||||
/* <sp_16_busy>: */
|
||||
0xe1d160b0, /* ldrh r6, [r1] */
|
||||
0xe0257006, /* eor r7, r5, r6 */
|
||||
0xe2177080, /* ands r7, #0x80 */
|
||||
0x1afffffb, /* bne 8168 <sp_16_busy> */
|
||||
/* */
|
||||
0xe2522001, /* subs r2, r2, #1 ; 0x1 */
|
||||
0x03a05080, /* moveq r5, #128 ; 0x80 */
|
||||
0x0a000001, /* beq 81ac <sp_16_done> */
|
||||
0xe2811002, /* add r1, r1, #2 ; 0x2 */
|
||||
0xeafffff0, /* b 8158 <sp_16_code> */
|
||||
/* */
|
||||
/* 000081ac <sp_16_done>: */
|
||||
0xeafffffe /* b 81ac <sp_16_done> */
|
||||
};
|
||||
|
||||
static const uint32_t word_8_code[] = {
|
||||
/* 000081b0 <sp_16_code_end>: */
|
||||
0xe4d05001, /* ldrb r5, [r0], #1 */
|
||||
@@ -1422,34 +1447,46 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
|
||||
armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
|
||||
armv4_5_info.core_state = ARMV4_5_STATE_ARM;
|
||||
|
||||
int target_code_size;
|
||||
const uint32_t *target_code_src;
|
||||
|
||||
switch (bank->bus_width)
|
||||
{
|
||||
case 1 :
|
||||
target_code_src = word_8_code;
|
||||
target_code_size = sizeof(word_8_code);
|
||||
break;
|
||||
case 2 :
|
||||
/* Check for DQ5 support */
|
||||
if( cfi_info->status_poll_mask & (1 << 5) )
|
||||
{
|
||||
target_code_src = word_16_code;
|
||||
target_code_size = sizeof(word_16_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No DQ5 support. Use DQ7 DATA# polling only. */
|
||||
target_code_src = word_16_code_dq7only;
|
||||
target_code_size = sizeof(word_16_code_dq7only);
|
||||
}
|
||||
break;
|
||||
case 4 :
|
||||
target_code_src = word_32_code;
|
||||
target_code_size = sizeof(word_32_code);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", bank->bus_width);
|
||||
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
/* flash write code */
|
||||
if (!cfi_info->write_algorithm)
|
||||
{
|
||||
uint8_t *target_code;
|
||||
int target_code_size;
|
||||
const uint32_t *src;
|
||||
|
||||
/* convert bus-width dependent algorithm code to correct endiannes */
|
||||
switch (bank->bus_width)
|
||||
{
|
||||
case 1:
|
||||
src = word_8_code;
|
||||
target_code_size = sizeof(word_8_code);
|
||||
break;
|
||||
case 2:
|
||||
src = word_16_code;
|
||||
target_code_size = sizeof(word_16_code);
|
||||
break;
|
||||
case 4:
|
||||
src = word_32_code;
|
||||
target_code_size = sizeof(word_32_code);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", bank->bus_width);
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
target_code = malloc(target_code_size);
|
||||
cfi_fix_code_endian(target, target_code, src, target_code_size / 4);
|
||||
cfi_fix_code_endian(target, target_code, target_code_src, target_code_size / 4);
|
||||
|
||||
/* allocate working area */
|
||||
retval = target_alloc_working_area(target, target_code_size,
|
||||
@@ -1515,7 +1552,7 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
|
||||
|
||||
retval = target_run_algorithm(target, 0, NULL, 10, reg_params,
|
||||
cfi_info->write_algorithm->address,
|
||||
cfi_info->write_algorithm->address + ((24 * 4) - 4),
|
||||
cfi_info->write_algorithm->address + ((target_code_size) - 4),
|
||||
10000, &armv4_5_info);
|
||||
|
||||
status = buf_get_u32(reg_params[5].value, 0, 32);
|
||||
@@ -1532,7 +1569,7 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
|
||||
count -= thisrun_count;
|
||||
}
|
||||
|
||||
target_free_working_area(target, source);
|
||||
target_free_all_working_areas(target);
|
||||
|
||||
destroy_reg_param(®_params[0]);
|
||||
destroy_reg_param(®_params[1]);
|
||||
@@ -2106,6 +2143,45 @@ static void cfi_fixup_0002_unlock_addresses(flash_bank_t *bank, void *param)
|
||||
pri_ext->_unlock2 = unlock_addresses->unlock2;
|
||||
}
|
||||
|
||||
|
||||
static int cfi_query_string(struct flash_bank_s *bank, int address)
|
||||
{
|
||||
cfi_flash_bank_t *cfi_info = bank->driver_priv;
|
||||
target_t *target = bank->target;
|
||||
int retval;
|
||||
uint8_t command[8];
|
||||
|
||||
cfi_command(bank, 0x98, command);
|
||||
if ((retval = target_write_memory(target, flash_address(bank, 0, address), bank->bus_width, 1, command)) != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
cfi_info->qry[0] = cfi_query_u8(bank, 0, 0x10);
|
||||
cfi_info->qry[1] = cfi_query_u8(bank, 0, 0x11);
|
||||
cfi_info->qry[2] = cfi_query_u8(bank, 0, 0x12);
|
||||
|
||||
LOG_DEBUG("CFI qry returned: 0x%2.2x 0x%2.2x 0x%2.2x", cfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2]);
|
||||
|
||||
if ((cfi_info->qry[0] != 'Q') || (cfi_info->qry[1] != 'R') || (cfi_info->qry[2] != 'Y'))
|
||||
{
|
||||
cfi_command(bank, 0xf0, command);
|
||||
if ((retval = target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command)) != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
cfi_command(bank, 0xff, command);
|
||||
if ((retval = target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command)) != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
LOG_ERROR("Could not probe bank: no QRY");
|
||||
return ERROR_FLASH_BANK_INVALID;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cfi_probe(struct flash_bank_s *bank)
|
||||
{
|
||||
cfi_flash_bank_t *cfi_info = bank->driver_priv;
|
||||
@@ -2172,7 +2248,7 @@ static int cfi_probe(struct flash_bank_s *bank)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
if ((retval = target_read_u16(target, flash_address(bank, 0, 0x02), &cfi_info->device_id)) != ERROR_OK)
|
||||
if ((retval = target_read_u16(target, flash_address(bank, 0, 0x01), &cfi_info->device_id)) != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
@@ -2199,6 +2275,8 @@ static int cfi_probe(struct flash_bank_s *bank)
|
||||
*/
|
||||
if (cfi_info->not_cfi == 0)
|
||||
{
|
||||
int retval;
|
||||
|
||||
/* enter CFI query mode
|
||||
* according to JEDEC Standard No. 68.01,
|
||||
* a single bus sequence with address = 0x55, data = 0x98 should put
|
||||
@@ -2206,33 +2284,21 @@ static int cfi_probe(struct flash_bank_s *bank)
|
||||
*
|
||||
* SST flashes clearly violate this, and we will consider them incompatbile for now
|
||||
*/
|
||||
cfi_command(bank, 0x98, command);
|
||||
if ((retval = target_write_memory(target, flash_address(bank, 0, 0x55), bank->bus_width, 1, command)) != ERROR_OK)
|
||||
|
||||
retval = cfi_query_string(bank, 0x55);
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
/*
|
||||
* Spansion S29WS-N CFI query fix is to try 0x555 if 0x55 fails. Should
|
||||
* be harmless enough:
|
||||
*
|
||||
* http://www.infradead.org/pipermail/linux-mtd/2005-September/013618.html
|
||||
*/
|
||||
LOG_USER("Try workaround w/0x555 instead of 0x55 to get QRY.");
|
||||
retval = cfi_query_string(bank, 0x555);
|
||||
}
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
|
||||
cfi_info->qry[0] = cfi_query_u8(bank, 0, 0x10);
|
||||
cfi_info->qry[1] = cfi_query_u8(bank, 0, 0x11);
|
||||
cfi_info->qry[2] = cfi_query_u8(bank, 0, 0x12);
|
||||
|
||||
LOG_DEBUG("CFI qry returned: 0x%2.2x 0x%2.2x 0x%2.2x", cfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2]);
|
||||
|
||||
if ((cfi_info->qry[0] != 'Q') || (cfi_info->qry[1] != 'R') || (cfi_info->qry[2] != 'Y'))
|
||||
{
|
||||
cfi_command(bank, 0xf0, command);
|
||||
if ((retval = target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command)) != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
cfi_command(bank, 0xff, command);
|
||||
if ((retval = target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command)) != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
LOG_ERROR("Could not probe bank: no QRY");
|
||||
return ERROR_FLASH_BANK_INVALID;
|
||||
}
|
||||
|
||||
cfi_info->pri_id = cfi_query_u16(bank, 0, 0x13);
|
||||
cfi_info->pri_addr = cfi_query_u16(bank, 0, 0x15);
|
||||
@@ -2383,9 +2449,10 @@ static int cfi_probe(struct flash_bank_s *bank)
|
||||
sector++;
|
||||
}
|
||||
}
|
||||
if (offset != cfi_info->dev_size)
|
||||
if (offset != (cfi_info->dev_size * bank->bus_width / bank->chip_width))
|
||||
{
|
||||
LOG_WARNING("CFI size is 0x%" PRIx32 ", but total sector size is 0x%" PRIx32 "", cfi_info->dev_size, offset);
|
||||
LOG_WARNING("CFI size is 0x%" PRIx32 ", but total sector size is 0x%" PRIx32 "", \
|
||||
(cfi_info->dev_size * bank->bus_width / bank->chip_width), offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "nand.h"
|
||||
#include "arm_nandio.h"
|
||||
|
||||
|
||||
enum ecc {
|
||||
@@ -51,6 +51,9 @@ struct davinci_nand {
|
||||
uint32_t cmd; /* with CLE */
|
||||
uint32_t addr; /* with ALE */
|
||||
|
||||
/* write acceleration */
|
||||
struct arm_nand_data io;
|
||||
|
||||
/* page i/o for the relevant flavor of hardware ECC */
|
||||
int (*read_page)(struct nand_device_s *nand, uint32_t page,
|
||||
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
|
||||
@@ -181,7 +184,7 @@ static int davinci_read_data(struct nand_device_s *nand, void *data)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* REVISIT a bit of native code should let block I/O be MUCH faster */
|
||||
/* REVISIT a bit of native code should let block reads be MUCH faster */
|
||||
|
||||
static int davinci_read_block_data(struct nand_device_s *nand,
|
||||
uint8_t *data, int data_size)
|
||||
@@ -223,10 +226,17 @@ static int davinci_write_block_data(struct nand_device_s *nand,
|
||||
target_t *target = info->target;
|
||||
uint32_t nfdata = info->data;
|
||||
uint32_t tmp;
|
||||
int status;
|
||||
|
||||
if (!halted(target, "write_block"))
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
|
||||
/* try the fast way first */
|
||||
status = arm_nandwrite(&info->io, data, data_size);
|
||||
if (status != ERROR_NAND_NO_BUFFER)
|
||||
return status;
|
||||
|
||||
/* else do it slowly */
|
||||
while (data_size >= 4) {
|
||||
tmp = le_to_h_u32(data);
|
||||
target_write_u32(target, nfdata, tmp);
|
||||
@@ -285,6 +295,12 @@ static int davinci_write_page(struct nand_device_s *nand, uint32_t page,
|
||||
memset(oob, 0x0ff, oob_size);
|
||||
}
|
||||
|
||||
/* REVISIT avoid wasting SRAM: unless nand->use_raw is set,
|
||||
* use 512 byte chunks. Read side support will often want
|
||||
* to include oob_size ...
|
||||
*/
|
||||
info->io.chunk_size = nand->page_size;
|
||||
|
||||
status = info->write_page(nand, page, data, data_size, oob, oob_size);
|
||||
free(ooballoc);
|
||||
return status;
|
||||
@@ -365,7 +381,7 @@ static int davinci_write_page_ecc1(struct nand_device_s *nand, uint32_t page,
|
||||
struct davinci_nand *info = nand->controller_priv;
|
||||
target_t *target = info->target;
|
||||
const uint32_t fcr_addr = info->aemif + NANDFCR;
|
||||
const uint32_t ecc1_addr = info->aemif + NANDFECC + info->chipsel;
|
||||
const uint32_t ecc1_addr = info->aemif + NANDFECC + (4 * info->chipsel);
|
||||
uint32_t fcr, ecc1;
|
||||
|
||||
/* Write contiguous ECC bytes starting at specified offset.
|
||||
@@ -663,7 +679,7 @@ static int davinci_nand_device_command(struct command_context_s *cmd_ctx,
|
||||
}
|
||||
|
||||
aemif = strtoul(argv[4], &ep, 0);
|
||||
if (*ep || chip == 0 || chip == ULONG_MAX) {
|
||||
if (*ep || aemif == 0 || aemif == ULONG_MAX) {
|
||||
LOG_ERROR("Invalid AEMIF controller address %s", argv[4]);
|
||||
goto fail;
|
||||
}
|
||||
@@ -676,11 +692,11 @@ static int davinci_nand_device_command(struct command_context_s *cmd_ctx,
|
||||
|| aemif == 0x01e10000 /* dm335, dm355 */
|
||||
|| aemif == 0x01d10000 /* dm365 */
|
||||
) {
|
||||
if (chip < 0x0200000 || chip >= 0x0a000000) {
|
||||
if (chip < 0x02000000 || chip >= 0x0a000000) {
|
||||
LOG_ERROR("NAND address %08lx out of range?", chip);
|
||||
goto fail;
|
||||
}
|
||||
chipsel = (chip - 0x02000000) >> 21;
|
||||
chipsel = (chip - 0x02000000) >> 25;
|
||||
} else {
|
||||
LOG_ERROR("unrecognized AEMIF controller address %08lx", aemif);
|
||||
goto fail;
|
||||
@@ -700,6 +716,9 @@ static int davinci_nand_device_command(struct command_context_s *cmd_ctx,
|
||||
|
||||
nand->controller_priv = info;
|
||||
|
||||
info->io.target = target;
|
||||
info->io.data = info->data;
|
||||
|
||||
/* NOTE: for now we don't do any error correction on read.
|
||||
* Nothing else in OpenOCD currently corrects read errors,
|
||||
* and in any case it's *writing* that we care most about.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -148,7 +148,7 @@ static int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char
|
||||
info->driverPath = strdup(args[6]);
|
||||
|
||||
/* eCos flash sector sizes are not exposed to OpenOCD, use 0x10000 as
|
||||
* a way to improve impeadance matach between OpenOCD and eCos flash
|
||||
* a way to improve impedance match between OpenOCD and eCos flash
|
||||
* driver.
|
||||
*/
|
||||
int i = 0;
|
||||
|
||||
153
src/flash/faux.c
Normal file
153
src/flash/faux.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* 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 "flash.h"
|
||||
#include "image.h"
|
||||
|
||||
|
||||
static int faux_register_commands(struct command_context_s *cmd_ctx);
|
||||
static int faux_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
|
||||
static int faux_erase(struct flash_bank_s *bank, int first, int last);
|
||||
static int faux_protect(struct flash_bank_s *bank, int set, int first, int last);
|
||||
static int faux_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
|
||||
static int faux_probe(struct flash_bank_s *bank);
|
||||
static int faux_protect_check(struct flash_bank_s *bank);
|
||||
static int faux_info(struct flash_bank_s *bank, char *buf, int buf_size);
|
||||
|
||||
flash_driver_t faux_flash =
|
||||
{
|
||||
.name = "faux",
|
||||
.register_commands = faux_register_commands,
|
||||
.flash_bank_command = faux_flash_bank_command,
|
||||
.erase = faux_erase,
|
||||
.protect = faux_protect,
|
||||
.write = faux_write,
|
||||
.probe = faux_probe,
|
||||
.auto_probe = faux_probe,
|
||||
.erase_check = default_flash_blank_check,
|
||||
.protect_check = faux_protect_check,
|
||||
.info = faux_info
|
||||
};
|
||||
|
||||
typedef struct faux_flash_bank_s
|
||||
{
|
||||
struct target_s *target;
|
||||
uint8_t *memory;
|
||||
uint32_t start_address;
|
||||
} faux_flash_bank_t;
|
||||
|
||||
static const int sectorSize = 0x10000;
|
||||
|
||||
|
||||
/* flash bank faux <base> <size> <chip_width> <bus_width> <target#> <driverPath>
|
||||
*/
|
||||
static int faux_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
|
||||
{
|
||||
faux_flash_bank_t *info;
|
||||
|
||||
if (argc < 6)
|
||||
{
|
||||
LOG_WARNING("incomplete flash_bank faux configuration");
|
||||
return ERROR_FLASH_BANK_INVALID;
|
||||
}
|
||||
|
||||
info = malloc(sizeof(faux_flash_bank_t));
|
||||
if (info == NULL)
|
||||
{
|
||||
LOG_ERROR("no memory for flash bank info");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
info->memory = malloc(bank->size);
|
||||
if (info == NULL)
|
||||
{
|
||||
free(info);
|
||||
LOG_ERROR("no memory for flash bank info");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
bank->driver_priv = info;
|
||||
|
||||
/* Use 0x10000 as a fixed sector size. */
|
||||
int i = 0;
|
||||
uint32_t offset = 0;
|
||||
bank->num_sectors = bank->size/sectorSize;
|
||||
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
|
||||
for (i = 0; i < bank->num_sectors; i++)
|
||||
{
|
||||
bank->sectors[i].offset = offset;
|
||||
bank->sectors[i].size = sectorSize;
|
||||
offset += bank->sectors[i].size;
|
||||
bank->sectors[i].is_erased = -1;
|
||||
bank->sectors[i].is_protected = 0;
|
||||
}
|
||||
|
||||
info->target = get_target(args[5]);
|
||||
if (info->target == NULL)
|
||||
{
|
||||
LOG_ERROR("target '%s' not defined", args[5]);
|
||||
free(info->memory);
|
||||
free(info);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int faux_register_commands(struct command_context_s *cmd_ctx)
|
||||
{
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int faux_erase(struct flash_bank_s *bank, int first, int last)
|
||||
{
|
||||
faux_flash_bank_t *info = bank->driver_priv;
|
||||
memset(info->memory + first*sectorSize, 0xff, sectorSize*(last-first + 1));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int faux_protect(struct flash_bank_s *bank, int set, int first, int last)
|
||||
{
|
||||
LOG_USER("set protection sector %d to %d to %s", first, last, set?"on":"off");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int faux_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
|
||||
{
|
||||
faux_flash_bank_t *info = bank->driver_priv;
|
||||
memcpy(info->memory + offset, buffer, count);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int faux_protect_check(struct flash_bank_s *bank)
|
||||
{
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int faux_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
||||
{
|
||||
snprintf(buf, buf_size, "faux flash driver");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int faux_probe(struct flash_bank_s *bank)
|
||||
{
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
@@ -43,10 +43,13 @@ static int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, ch
|
||||
static int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
static int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
static int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
static int flash_write_unlock(target_t *target, image_t *image, uint32_t *written, int erase, bool unlock);
|
||||
|
||||
/* flash drivers
|
||||
*/
|
||||
extern flash_driver_t lpc2000_flash;
|
||||
extern flash_driver_t lpc288x_flash;
|
||||
extern flash_driver_t lpc2900_flash;
|
||||
extern flash_driver_t cfi_flash;
|
||||
extern flash_driver_t at91sam3_flash;
|
||||
extern flash_driver_t at91sam7_flash;
|
||||
@@ -58,13 +61,15 @@ extern flash_driver_t str9xpec_flash;
|
||||
extern flash_driver_t stm32x_flash;
|
||||
extern flash_driver_t tms470_flash;
|
||||
extern flash_driver_t ecosflash_flash;
|
||||
extern flash_driver_t lpc288x_flash;
|
||||
extern flash_driver_t ocl_flash;
|
||||
extern flash_driver_t pic32mx_flash;
|
||||
extern flash_driver_t avr_flash;
|
||||
extern flash_driver_t faux_flash;
|
||||
|
||||
flash_driver_t *flash_drivers[] = {
|
||||
&lpc2000_flash,
|
||||
&lpc288x_flash,
|
||||
&lpc2900_flash,
|
||||
&cfi_flash,
|
||||
&at91sam7_flash,
|
||||
&at91sam3_flash,
|
||||
@@ -76,10 +81,10 @@ flash_driver_t *flash_drivers[] = {
|
||||
&stm32x_flash,
|
||||
&tms470_flash,
|
||||
&ecosflash_flash,
|
||||
&lpc288x_flash,
|
||||
&ocl_flash,
|
||||
&pic32mx_flash,
|
||||
&avr_flash,
|
||||
&faux_flash,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -197,7 +202,7 @@ int flash_init_drivers(struct command_context_s *cmd_ctx)
|
||||
register_command(cmd_ctx, flash_cmd, "write_bank", handle_flash_write_bank_command, COMMAND_EXEC,
|
||||
"write binary data to <bank> <file> <offset>");
|
||||
register_command(cmd_ctx, flash_cmd, "write_image", handle_flash_write_image_command, COMMAND_EXEC,
|
||||
"write_image [erase] <file> [offset] [type]");
|
||||
"write_image [erase] [unlock] <file> [offset] [type]");
|
||||
register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC,
|
||||
"set protection of sectors at <bank> <first> <last> <on | off>");
|
||||
}
|
||||
@@ -557,82 +562,122 @@ static int handle_flash_protect_check_command(struct command_context_s *cmd_ctx,
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||
static int flash_check_sector_parameters(struct command_context_s *cmd_ctx,
|
||||
uint32_t first, uint32_t last, uint32_t num_sectors)
|
||||
{
|
||||
if (argc > 2)
|
||||
{
|
||||
int first = strtoul(args[1], NULL, 0);
|
||||
int last = strtoul(args[2], NULL, 0);
|
||||
int retval;
|
||||
flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
|
||||
duration_t duration;
|
||||
char *duration_text;
|
||||
|
||||
duration_start_measure(&duration);
|
||||
|
||||
if (!p)
|
||||
{
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK)
|
||||
{
|
||||
if ((retval = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
command_print(cmd_ctx, "erased sectors %i through %i on flash bank %li in %s",
|
||||
first, last, strtoul(args[0], 0, 0), duration_text);
|
||||
free(duration_text);
|
||||
}
|
||||
if (!(first <= last)) {
|
||||
command_print(cmd_ctx, "ERROR: "
|
||||
"first sector must be <= last sector");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
if (!(last <= (num_sectors - 1))) {
|
||||
command_print(cmd_ctx, "ERROR: last sector must be <= %d",
|
||||
(int) num_sectors - 1);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||
static int handle_flash_erase_command(struct command_context_s *cmd_ctx,
|
||||
char *cmd, char **args, int argc)
|
||||
{
|
||||
if (argc > 2)
|
||||
{
|
||||
uint32_t bank_nr;
|
||||
uint32_t first;
|
||||
uint32_t last;
|
||||
int retval;
|
||||
|
||||
if ((retval = parse_u32(args[0], &bank_nr)) != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
flash_bank_t *p = get_flash_bank_by_num(bank_nr);
|
||||
if (!p)
|
||||
return ERROR_OK;
|
||||
|
||||
if ((retval = parse_u32(args[1], &first)) != ERROR_OK)
|
||||
return retval;
|
||||
if (strcmp(args[2], "last") == 0)
|
||||
last = p->num_sectors - 1;
|
||||
else
|
||||
if ((retval = parse_u32(args[2], &last)) != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
if ((retval = flash_check_sector_parameters(cmd_ctx,
|
||||
first, last, p->num_sectors)) != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
duration_t duration;
|
||||
char *duration_text;
|
||||
duration_start_measure(&duration);
|
||||
|
||||
if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK) {
|
||||
if ((retval = duration_stop_measure(&duration,
|
||||
&duration_text)) != ERROR_OK)
|
||||
return retval;
|
||||
command_print(cmd_ctx, "erased sectors %i through %i "
|
||||
"on flash bank %i in %s",
|
||||
(int) first, (int) last, (int) bank_nr,
|
||||
duration_text);
|
||||
free(duration_text);
|
||||
}
|
||||
}
|
||||
else
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int handle_flash_protect_command(struct command_context_s *cmd_ctx,
|
||||
char *cmd, char **args, int argc)
|
||||
{
|
||||
if (argc > 3)
|
||||
{
|
||||
int first = strtoul(args[1], NULL, 0);
|
||||
int last = strtoul(args[2], NULL, 0);
|
||||
int set;
|
||||
uint32_t bank_nr;
|
||||
uint32_t first;
|
||||
uint32_t last;
|
||||
int retval;
|
||||
flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
|
||||
int set;
|
||||
|
||||
if ((retval = parse_u32(args[0], &bank_nr)) != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
flash_bank_t *p = get_flash_bank_by_num(bank_nr);
|
||||
if (!p)
|
||||
{
|
||||
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
if ((retval = parse_u32(args[1], &first)) != ERROR_OK)
|
||||
return retval;
|
||||
if (strcmp(args[2], "last") == 0)
|
||||
last = p->num_sectors - 1;
|
||||
else
|
||||
if ((retval = parse_u32(args[2], &last)) != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
if (strcmp(args[3], "on") == 0)
|
||||
set = 1;
|
||||
else if (strcmp(args[3], "off") == 0)
|
||||
set = 0;
|
||||
else
|
||||
{
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
if ((retval = flash_check_sector_parameters(cmd_ctx,
|
||||
first, last, p->num_sectors)) != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = flash_driver_protect(p, set, first, last);
|
||||
if (retval == ERROR_OK)
|
||||
{
|
||||
command_print(cmd_ctx, "%s protection for sectors %i through %i on flash bank %li",
|
||||
(set) ? "set" : "cleared", first,
|
||||
last, strtoul(args[0], 0, 0));
|
||||
if (retval == ERROR_OK) {
|
||||
command_print(cmd_ctx, "%s protection for sectors %i "
|
||||
"through %i on flash bank %i",
|
||||
(set) ? "set" : "cleared", (int) first,
|
||||
(int) last, (int) bank_nr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
@@ -655,13 +700,26 @@ static int handle_flash_write_image_command(struct command_context_s *cmd_ctx, c
|
||||
|
||||
/* flash auto-erase is disabled by default*/
|
||||
int auto_erase = 0;
|
||||
bool auto_unlock = false;
|
||||
|
||||
if (strcmp(args[0], "erase") == 0)
|
||||
for (;;)
|
||||
{
|
||||
auto_erase = 1;
|
||||
args++;
|
||||
argc--;
|
||||
command_print(cmd_ctx, "auto erase enabled");
|
||||
if (strcmp(args[0], "erase") == 0)
|
||||
{
|
||||
auto_erase = 1;
|
||||
args++;
|
||||
argc--;
|
||||
command_print(cmd_ctx, "auto erase enabled");
|
||||
} else if (strcmp(args[0], "unlock") == 0)
|
||||
{
|
||||
auto_unlock = true;
|
||||
args++;
|
||||
argc--;
|
||||
command_print(cmd_ctx, "auto unlock enabled");
|
||||
} else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 1)
|
||||
@@ -696,7 +754,7 @@ static int handle_flash_write_image_command(struct command_context_s *cmd_ctx, c
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = flash_write(target, &image, &written, auto_erase);
|
||||
retval = flash_write_unlock(target, &image, &written, auto_erase, auto_unlock);
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
image_close(&image);
|
||||
@@ -708,15 +766,16 @@ static int handle_flash_write_image_command(struct command_context_s *cmd_ctx, c
|
||||
image_close(&image);
|
||||
return retvaltemp;
|
||||
}
|
||||
if (retval == ERROR_OK)
|
||||
{
|
||||
command_print(cmd_ctx,
|
||||
"wrote %" PRIu32 " byte from file %s in %s (%f kb/s)",
|
||||
written,
|
||||
args[0],
|
||||
duration_text,
|
||||
(float)written / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
|
||||
}
|
||||
|
||||
float speed;
|
||||
|
||||
speed = written / 1024.0;
|
||||
speed /= ((float)duration.duration.tv_sec
|
||||
+ ((float)duration.duration.tv_usec / 1000000.0));
|
||||
command_print(cmd_ctx,
|
||||
"wrote %" PRIu32 " byte from file %s in %s (%f kb/s)",
|
||||
written, args[0], duration_text, speed);
|
||||
|
||||
free(duration_text);
|
||||
|
||||
image_close(&image);
|
||||
@@ -828,18 +887,15 @@ static int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cm
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (err == ERROR_OK)
|
||||
{
|
||||
float speed;
|
||||
speed = wrote / 1024.0;
|
||||
speed/=((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0));
|
||||
command_print(cmd_ctx,
|
||||
"wrote %" PRId32 " bytes to 0x%8.8" PRIx32 " in %s (%f kb/s)",
|
||||
count*wordsize,
|
||||
address,
|
||||
duration_text,
|
||||
speed);
|
||||
}
|
||||
float speed;
|
||||
|
||||
speed = wrote / 1024.0;
|
||||
speed /= ((float)duration.duration.tv_sec
|
||||
+ ((float)duration.duration.tv_usec / 1000000.0));
|
||||
command_print(cmd_ctx,
|
||||
"wrote %" PRIu32 " bytes to 0x%8.8" PRIx32 " in %s (%f kb/s)",
|
||||
wrote, address, duration_text, speed);
|
||||
|
||||
free(duration_text);
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -954,7 +1010,8 @@ flash_bank_t *get_flash_bank_by_addr(target_t *target, uint32_t addr)
|
||||
}
|
||||
|
||||
/* erase given flash region, selects proper bank according to target and address */
|
||||
int flash_erase_address_range(target_t *target, uint32_t addr, uint32_t length)
|
||||
static int flash_iterate_address_range(target_t *target, uint32_t addr, uint32_t length,
|
||||
int (*callback)(struct flash_bank_s *bank, int first, int last))
|
||||
{
|
||||
flash_bank_t *c;
|
||||
int first = -1;
|
||||
@@ -976,7 +1033,7 @@ int flash_erase_address_range(target_t *target, uint32_t addr, uint32_t length)
|
||||
if (addr != c->base)
|
||||
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
|
||||
|
||||
return flash_driver_erase(c, 0, c->num_sectors - 1);
|
||||
return callback(c, 0, c->num_sectors - 1);
|
||||
}
|
||||
|
||||
/* check whether it fits */
|
||||
@@ -999,11 +1056,29 @@ int flash_erase_address_range(target_t *target, uint32_t addr, uint32_t length)
|
||||
if (first == -1 || last == -1)
|
||||
return ERROR_OK;
|
||||
|
||||
return flash_driver_erase(c, first, last);
|
||||
return callback(c, first, last);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int flash_erase_address_range(target_t *target, uint32_t addr, uint32_t length)
|
||||
{
|
||||
return flash_iterate_address_range(target, addr, length, &flash_driver_erase);
|
||||
}
|
||||
|
||||
static int flash_driver_unprotect(struct flash_bank_s *bank, int first, int last)
|
||||
{
|
||||
return flash_driver_protect(bank, 0, first, last);
|
||||
}
|
||||
|
||||
static int flash_unlock_address_range(target_t *target, uint32_t addr, uint32_t length)
|
||||
{
|
||||
return flash_iterate_address_range(target, addr, length, &flash_driver_unprotect);
|
||||
}
|
||||
|
||||
|
||||
/* write (optional verify) an image to flash memory of the given target */
|
||||
int flash_write(target_t *target, image_t *image, uint32_t *written, int erase)
|
||||
static int flash_write_unlock(target_t *target, image_t *image, uint32_t *written, int erase, bool unlock)
|
||||
{
|
||||
int retval = ERROR_OK;
|
||||
|
||||
@@ -1126,10 +1201,17 @@ int flash_write(target_t *target, image_t *image, uint32_t *written, int erase)
|
||||
|
||||
retval = ERROR_OK;
|
||||
|
||||
if (erase)
|
||||
if (unlock)
|
||||
{
|
||||
/* calculate and erase sectors */
|
||||
retval = flash_erase_address_range(target, run_address, run_size);
|
||||
retval = flash_unlock_address_range(target, run_address, run_size);
|
||||
}
|
||||
if (retval == ERROR_OK)
|
||||
{
|
||||
if (erase)
|
||||
{
|
||||
/* calculate and erase sectors */
|
||||
retval = flash_erase_address_range(target, run_address, run_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == ERROR_OK)
|
||||
@@ -1155,6 +1237,11 @@ int flash_write(target_t *target, image_t *image, uint32_t *written, int erase)
|
||||
return retval;
|
||||
}
|
||||
|
||||
int flash_write(target_t *target, image_t *image, uint32_t *written, int erase)
|
||||
{
|
||||
return flash_write_unlock(target, image, written, erase, false);
|
||||
}
|
||||
|
||||
int default_flash_mem_blank_check(struct flash_bank_s *bank)
|
||||
{
|
||||
target_t *target = bank->target;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* LPC1700 support Copyright (C) 2009 by Audrius Urmanavicius *
|
||||
* didele.deze@gmail.com *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -24,13 +27,14 @@
|
||||
|
||||
#include "lpc2000.h"
|
||||
#include "armv4_5.h"
|
||||
#include "armv7m.h"
|
||||
#include "binarybuffer.h"
|
||||
|
||||
|
||||
/* flash programming support for Philips LPC2xxx devices
|
||||
/* flash programming support for NXP LPC17xx and LPC2xxx devices
|
||||
* currently supported devices:
|
||||
* variant 1 (lpc2000_v1):
|
||||
* - 2104 | 5|6
|
||||
* - 2104 | 5 | 6
|
||||
* - 2114 | 9
|
||||
* - 2124 | 9
|
||||
* - 2194
|
||||
@@ -40,9 +44,13 @@
|
||||
* variant 2 (lpc2000_v2):
|
||||
* - 213x
|
||||
* - 214x
|
||||
* - 2101 | 2|3
|
||||
* - 2364 | 6|8
|
||||
* - 2101 | 2 | 3
|
||||
* - 2364 | 6 | 8
|
||||
* - 2378
|
||||
*
|
||||
* lpc1700:
|
||||
* - 175x
|
||||
* - 176x (tested with LPC1768)
|
||||
*/
|
||||
|
||||
static int lpc2000_register_commands(struct command_context_s *cmd_ctx);
|
||||
@@ -85,15 +93,14 @@ static int lpc2000_register_commands(struct command_context_s *cmd_ctx)
|
||||
static int lpc2000_build_sector_list(struct flash_bank_s *bank)
|
||||
{
|
||||
lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
|
||||
int i;
|
||||
uint32_t offset = 0;
|
||||
|
||||
/* default to a 4096 write buffer */
|
||||
lpc2000_info->cmd51_max_buffer = 4096;
|
||||
|
||||
if (lpc2000_info->variant == 1)
|
||||
if (lpc2000_info->variant == lpc2000_v1)
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t offset = 0;
|
||||
|
||||
/* variant 1 has different layout for 128kb and 256kb flashes */
|
||||
if (bank->size == 128 * 1024)
|
||||
{
|
||||
@@ -144,41 +151,37 @@ static int lpc2000_build_sector_list(struct flash_bank_s *bank)
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else if (lpc2000_info->variant == 2)
|
||||
else if (lpc2000_info->variant == lpc2000_v2)
|
||||
{
|
||||
int num_sectors;
|
||||
int i;
|
||||
uint32_t offset = 0;
|
||||
|
||||
/* variant 2 has a uniform layout, only number of sectors differs */
|
||||
switch (bank->size)
|
||||
{
|
||||
case 4 * 1024:
|
||||
lpc2000_info->cmd51_max_buffer = 1024;
|
||||
num_sectors = 1;
|
||||
bank->num_sectors = 1;
|
||||
break;
|
||||
case 8 * 1024:
|
||||
lpc2000_info->cmd51_max_buffer = 1024;
|
||||
num_sectors = 2;
|
||||
bank->num_sectors = 2;
|
||||
break;
|
||||
case 16 * 1024:
|
||||
num_sectors = 4;
|
||||
bank->num_sectors = 4;
|
||||
break;
|
||||
case 32 * 1024:
|
||||
num_sectors = 8;
|
||||
bank->num_sectors = 8;
|
||||
break;
|
||||
case 64 * 1024:
|
||||
num_sectors = 9;
|
||||
bank->num_sectors = 9;
|
||||
break;
|
||||
case 128 * 1024:
|
||||
num_sectors = 11;
|
||||
bank->num_sectors = 11;
|
||||
break;
|
||||
case 256 * 1024:
|
||||
num_sectors = 15;
|
||||
bank->num_sectors = 15;
|
||||
break;
|
||||
case 512 * 1024:
|
||||
case 500 * 1024:
|
||||
num_sectors = 27;
|
||||
bank->num_sectors = 27;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("BUG: unknown bank->size encountered");
|
||||
@@ -186,10 +189,9 @@ static int lpc2000_build_sector_list(struct flash_bank_s *bank)
|
||||
break;
|
||||
}
|
||||
|
||||
bank->num_sectors = num_sectors;
|
||||
bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
|
||||
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
|
||||
|
||||
for (i = 0; i < num_sectors; i++)
|
||||
for (i = 0; i < bank->num_sectors; i++)
|
||||
{
|
||||
if ((i >= 0) && (i < 8))
|
||||
{
|
||||
@@ -217,6 +219,42 @@ static int lpc2000_build_sector_list(struct flash_bank_s *bank)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (lpc2000_info->variant == lpc1700)
|
||||
{
|
||||
switch(bank->size)
|
||||
{
|
||||
case 32 * 1024:
|
||||
bank->num_sectors = 8;
|
||||
break;
|
||||
case 64 * 1024:
|
||||
bank->num_sectors = 16;
|
||||
break;
|
||||
case 128 * 1024:
|
||||
bank->num_sectors = 18;
|
||||
break;
|
||||
case 256 * 1024:
|
||||
bank->num_sectors = 22;
|
||||
break;
|
||||
case 512 * 1024:
|
||||
bank->num_sectors = 30;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("BUG: unknown bank->size encountered");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
|
||||
|
||||
for(i = 0; i < bank->num_sectors; i++)
|
||||
{
|
||||
bank->sectors[i].offset = offset;
|
||||
/* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx devices */
|
||||
bank->sectors[i].size = (i < 16)? 4 * 1024 : 32 * 1024;
|
||||
offset += bank->sectors[i].size;
|
||||
bank->sectors[i].is_erased = -1;
|
||||
bank->sectors[i].is_protected = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
|
||||
@@ -226,22 +264,24 @@ static int lpc2000_build_sector_list(struct flash_bank_s *bank)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* call LPC2000 IAP function
|
||||
* uses 172 bytes working area
|
||||
/* call LPC1700/LPC2000 IAP function
|
||||
* uses 180 bytes working area
|
||||
* 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
|
||||
* 0x8 to 0x1f: command parameter table
|
||||
* 0x20 to 0x2b: command result table
|
||||
* 0x2c to 0xac: stack (only 128b needed)
|
||||
* 0x8 to 0x1f: command parameter table (1+5 words)
|
||||
* 0x20 to 0x33: command result table (1+4 words)
|
||||
* 0x34 to 0xb3: stack (only 128b needed)
|
||||
*/
|
||||
static int lpc2000_iap_call(flash_bank_t *bank, int code, uint32_t param_table[5], uint32_t result_table[2])
|
||||
static int lpc2000_iap_call(flash_bank_t *bank, int code, uint32_t param_table[5], uint32_t result_table[4])
|
||||
{
|
||||
int retval;
|
||||
lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
|
||||
target_t *target = bank->target;
|
||||
mem_param_t mem_params[2];
|
||||
reg_param_t reg_params[5];
|
||||
armv4_5_algorithm_t armv4_5_info;
|
||||
uint32_t status_code;
|
||||
armv4_5_algorithm_t armv4_5_info; /* for LPC2000 */
|
||||
armv7m_algorithm_t armv7m_info; /* for LPC1700 */
|
||||
uint32_t status_code;
|
||||
uint32_t iap_entry_point = 0; /* to make compiler happier */
|
||||
|
||||
/* regrab previously allocated working_area, or allocate a new one */
|
||||
if (!lpc2000_info->iap_working_area)
|
||||
@@ -249,60 +289,116 @@ static int lpc2000_iap_call(flash_bank_t *bank, int code, uint32_t param_table[5
|
||||
uint8_t jump_gate[8];
|
||||
|
||||
/* make sure we have a working area */
|
||||
if (target_alloc_working_area(target, 172, &lpc2000_info->iap_working_area) != ERROR_OK)
|
||||
if (target_alloc_working_area(target, 180, &lpc2000_info->iap_working_area) != ERROR_OK)
|
||||
{
|
||||
LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
/* write IAP code to working area */
|
||||
target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
|
||||
target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
|
||||
switch(lpc2000_info->variant)
|
||||
{
|
||||
case lpc1700:
|
||||
target_buffer_set_u32(target, jump_gate, ARMV7M_T_BX(12));
|
||||
target_buffer_set_u32(target, jump_gate + 4, ARMV7M_T_B(0xfffffe));
|
||||
break;
|
||||
case lpc2000_v1:
|
||||
case lpc2000_v2:
|
||||
target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
|
||||
target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("BUG: unknown bank->size encountered");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ((retval = target_write_memory(target, lpc2000_info->iap_working_area->address, 4, 2, jump_gate)) != ERROR_OK)
|
||||
{
|
||||
LOG_ERROR("Write memory at address 0x%8.8" PRIx32 " failed (check work_area definition)", lpc2000_info->iap_working_area->address);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
|
||||
armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
|
||||
armv4_5_info.core_state = ARMV4_5_STATE_ARM;
|
||||
switch(lpc2000_info->variant)
|
||||
{
|
||||
case lpc1700:
|
||||
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
|
||||
armv7m_info.core_mode = ARMV7M_MODE_ANY;
|
||||
iap_entry_point = 0x1fff1ff1;
|
||||
break;
|
||||
case lpc2000_v1:
|
||||
case lpc2000_v2:
|
||||
armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
|
||||
armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
|
||||
armv4_5_info.core_state = ARMV4_5_STATE_ARM;
|
||||
iap_entry_point = 0x7ffffff1;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("BUG: unknown lpc2000->variant encountered");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* command parameter table */
|
||||
init_mem_param(&mem_params[0], lpc2000_info->iap_working_area->address + 8, 4 * 6, PARAM_OUT);
|
||||
init_mem_param(&mem_params[0], lpc2000_info->iap_working_area->address + 8, 6 * 4, PARAM_OUT);
|
||||
target_buffer_set_u32(target, mem_params[0].value, code);
|
||||
target_buffer_set_u32(target, mem_params[0].value + 0x4, param_table[0]);
|
||||
target_buffer_set_u32(target, mem_params[0].value + 0x8, param_table[1]);
|
||||
target_buffer_set_u32(target, mem_params[0].value + 0xc, param_table[2]);
|
||||
target_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]);
|
||||
target_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]);
|
||||
target_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]);
|
||||
target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);
|
||||
target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);
|
||||
|
||||
init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
|
||||
buf_set_u32(reg_params[0].value, 0, 32, lpc2000_info->iap_working_area->address + 0x8);
|
||||
buf_set_u32(reg_params[0].value, 0, 32, lpc2000_info->iap_working_area->address + 0x08);
|
||||
|
||||
/* command result table */
|
||||
init_mem_param(&mem_params[1], lpc2000_info->iap_working_area->address + 0x20, 4 * 3, PARAM_IN);
|
||||
init_mem_param(&mem_params[1], lpc2000_info->iap_working_area->address + 0x20, 5 * 4, PARAM_IN);
|
||||
|
||||
init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
|
||||
buf_set_u32(reg_params[1].value, 0, 32, lpc2000_info->iap_working_area->address + 0x20);
|
||||
|
||||
/* IAP entry point */
|
||||
init_reg_param(®_params[2], "r12", 32, PARAM_OUT);
|
||||
buf_set_u32(reg_params[2].value, 0, 32, 0x7ffffff1);
|
||||
buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point);
|
||||
|
||||
/* IAP stack */
|
||||
init_reg_param(®_params[3], "r13_svc", 32, PARAM_OUT);
|
||||
buf_set_u32(reg_params[3].value, 0, 32, lpc2000_info->iap_working_area->address + 0xac);
|
||||
switch(lpc2000_info->variant)
|
||||
{
|
||||
case lpc1700:
|
||||
/* IAP stack */
|
||||
init_reg_param(®_params[3], "sp", 32, PARAM_OUT);
|
||||
buf_set_u32(reg_params[3].value, 0, 32, lpc2000_info->iap_working_area->address + 0xb4);
|
||||
|
||||
/* return address */
|
||||
init_reg_param(®_params[4], "lr_svc", 32, PARAM_OUT);
|
||||
buf_set_u32(reg_params[4].value, 0, 32, lpc2000_info->iap_working_area->address + 0x4);
|
||||
/* return address */
|
||||
init_reg_param(®_params[4], "lr", 32, PARAM_OUT);
|
||||
buf_set_u32(reg_params[4].value, 0, 32, (lpc2000_info->iap_working_area->address + 0x04) | 1); /* bit0 of LR = 1 to return in Thumb mode */
|
||||
|
||||
target_run_algorithm(target, 2, mem_params, 5, reg_params, lpc2000_info->iap_working_area->address, lpc2000_info->iap_working_area->address + 0x4, 10000, &armv4_5_info);
|
||||
target_run_algorithm(target, 2, mem_params, 5, reg_params, lpc2000_info->iap_working_area->address, lpc2000_info->iap_working_area->address + 0x4, 10000, &armv7m_info);
|
||||
break;
|
||||
case lpc2000_v1:
|
||||
case lpc2000_v2:
|
||||
/* IAP stack */
|
||||
init_reg_param(®_params[3], "r13_svc", 32, PARAM_OUT);
|
||||
buf_set_u32(reg_params[3].value, 0, 32, lpc2000_info->iap_working_area->address + 0xb4);
|
||||
|
||||
status_code = buf_get_u32(mem_params[1].value, 0, 32);
|
||||
result_table[0] = target_buffer_get_u32(target, mem_params[1].value);
|
||||
result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 4);
|
||||
/* return address */
|
||||
init_reg_param(®_params[4], "lr_svc", 32, PARAM_OUT);
|
||||
buf_set_u32(reg_params[4].value, 0, 32, lpc2000_info->iap_working_area->address + 0x04);
|
||||
|
||||
target_run_algorithm(target, 2, mem_params, 5, reg_params, lpc2000_info->iap_working_area->address, lpc2000_info->iap_working_area->address + 0x4, 10000, &armv4_5_info);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("BUG: unknown lpc2000->variant encountered");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
status_code = target_buffer_get_u32(target, mem_params[1].value);
|
||||
result_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04);
|
||||
result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08);
|
||||
result_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c);
|
||||
result_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10);
|
||||
|
||||
LOG_DEBUG("IAP command = %i (0x%8.8" PRIx32", 0x%8.8" PRIx32", 0x%8.8" PRIx32", 0x%8.8" PRIx32", 0x%8.8" PRIx32") completed with result = %8.8" PRIx32,
|
||||
code, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code);
|
||||
|
||||
destroy_mem_param(&mem_params[0]);
|
||||
destroy_mem_param(&mem_params[1]);
|
||||
@@ -319,7 +415,7 @@ static int lpc2000_iap_call(flash_bank_t *bank, int code, uint32_t param_table[5
|
||||
static int lpc2000_iap_blank_check(struct flash_bank_s *bank, int first, int last)
|
||||
{
|
||||
uint32_t param_table[5];
|
||||
uint32_t result_table[2];
|
||||
uint32_t result_table[4];
|
||||
int status_code;
|
||||
int i;
|
||||
|
||||
@@ -349,7 +445,7 @@ static int lpc2000_iap_blank_check(struct flash_bank_s *bank, int first, int las
|
||||
return ERROR_FLASH_BUSY;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("BUG: unknown LPC2000 status code");
|
||||
LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
@@ -357,7 +453,8 @@ static int lpc2000_iap_blank_check(struct flash_bank_s *bank, int first, int las
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
|
||||
/*
|
||||
* flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
|
||||
*/
|
||||
static int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
|
||||
{
|
||||
@@ -374,21 +471,31 @@ static int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *c
|
||||
|
||||
if (strcmp(args[6], "lpc2000_v1") == 0)
|
||||
{
|
||||
lpc2000_info->variant = 1;
|
||||
lpc2000_info->variant = lpc2000_v1;
|
||||
lpc2000_info->cmd51_dst_boundary = 512;
|
||||
lpc2000_info->cmd51_can_256b = 0;
|
||||
lpc2000_info->cmd51_can_8192b = 1;
|
||||
lpc2000_info->checksum_vector = 5;
|
||||
}
|
||||
else if (strcmp(args[6], "lpc2000_v2") == 0)
|
||||
{
|
||||
lpc2000_info->variant = 2;
|
||||
lpc2000_info->variant = lpc2000_v2;
|
||||
lpc2000_info->cmd51_dst_boundary = 256;
|
||||
lpc2000_info->cmd51_can_256b = 1;
|
||||
lpc2000_info->cmd51_can_8192b = 0;
|
||||
lpc2000_info->checksum_vector = 5;
|
||||
}
|
||||
else if (strcmp(args[6], "lpc1700") == 0)
|
||||
{
|
||||
lpc2000_info->variant = lpc1700;
|
||||
lpc2000_info->cmd51_dst_boundary = 256;
|
||||
lpc2000_info->cmd51_can_256b = 1;
|
||||
lpc2000_info->cmd51_can_8192b = 0;
|
||||
lpc2000_info->checksum_vector = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("unknown LPC2000 variant");
|
||||
LOG_ERROR("unknown LPC2000 variant: %s", args[6]);
|
||||
free(lpc2000_info);
|
||||
return ERROR_FLASH_BANK_INVALID;
|
||||
}
|
||||
@@ -411,7 +518,7 @@ static int lpc2000_erase(struct flash_bank_s *bank, int first, int last)
|
||||
{
|
||||
lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
|
||||
uint32_t param_table[5];
|
||||
uint32_t result_table[2];
|
||||
uint32_t result_table[4];
|
||||
int status_code;
|
||||
|
||||
if (bank->target->state != TARGET_HALTED)
|
||||
@@ -475,7 +582,7 @@ static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t of
|
||||
int first_sector = 0;
|
||||
int last_sector = 0;
|
||||
uint32_t param_table[5];
|
||||
uint32_t result_table[2];
|
||||
uint32_t result_table[4];
|
||||
int status_code;
|
||||
int i;
|
||||
working_area_t *download_area;
|
||||
@@ -490,10 +597,7 @@ static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t of
|
||||
if (offset + count > bank->size)
|
||||
return ERROR_FLASH_DST_OUT_OF_BANK;
|
||||
|
||||
if (lpc2000_info->cmd51_can_256b)
|
||||
dst_min_alignment = 256;
|
||||
else
|
||||
dst_min_alignment = 512;
|
||||
dst_min_alignment = lpc2000_info->cmd51_dst_boundary;
|
||||
|
||||
if (offset % dst_min_alignment)
|
||||
{
|
||||
@@ -515,25 +619,25 @@ static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t of
|
||||
if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum)
|
||||
{
|
||||
uint32_t checksum = 0;
|
||||
int i = 0;
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
LOG_DEBUG("0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
|
||||
if (i != 5)
|
||||
LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
|
||||
if (i != lpc2000_info->checksum_vector)
|
||||
checksum += buf_get_u32(buffer + (i * 4), 0, 32);
|
||||
}
|
||||
checksum = 0 - checksum;
|
||||
LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum);
|
||||
|
||||
uint32_t original_value = buf_get_u32(buffer + (5 * 4), 0, 32);
|
||||
uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32);
|
||||
if (original_value != checksum)
|
||||
{
|
||||
LOG_WARNING("Verification will fail since checksum in image(0x%8.8" PRIx32 ") written to flash was different from calculated vector checksum(0x%8.8" PRIx32 ").",
|
||||
LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is different from calculated vector checksum (0x%8.8" PRIx32 ").",
|
||||
original_value, checksum);
|
||||
LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.");
|
||||
}
|
||||
|
||||
buf_set_u32(buffer + 0x14, 0, 32, checksum);
|
||||
buf_set_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum);
|
||||
}
|
||||
|
||||
/* allocate a working area */
|
||||
@@ -590,10 +694,8 @@ static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t of
|
||||
else
|
||||
{
|
||||
uint8_t *last_buffer = malloc(thisrun_bytes);
|
||||
uint32_t i;
|
||||
memcpy(last_buffer, buffer + bytes_written, bytes_remaining);
|
||||
for (i = bytes_remaining; i < thisrun_bytes; i++)
|
||||
last_buffer[i] = 0xff;
|
||||
memset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining);
|
||||
target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);
|
||||
free(last_buffer);
|
||||
}
|
||||
@@ -667,7 +769,7 @@ static int lpc2000_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
||||
{
|
||||
lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
|
||||
|
||||
snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 , lpc2000_info->variant, lpc2000_info->cclk);
|
||||
snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz" , lpc2000_info->variant, lpc2000_info->cclk);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -676,7 +778,7 @@ static int lpc2000_handle_part_id_command(struct command_context_s *cmd_ctx, cha
|
||||
{
|
||||
flash_bank_t *bank;
|
||||
uint32_t param_table[5];
|
||||
uint32_t result_table[2];
|
||||
uint32_t result_table[4];
|
||||
int status_code;
|
||||
|
||||
if (argc < 1)
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* LPC1700 support Copyright (C) 2009 by Audrius Urmanavicius *
|
||||
* didele.deze@gmail.com *
|
||||
* *
|
||||
* 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 *
|
||||
@@ -22,9 +25,16 @@
|
||||
|
||||
#include "flash.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
lpc2000_v1,
|
||||
lpc2000_v2,
|
||||
lpc1700
|
||||
} lpc2000_variant;
|
||||
|
||||
typedef struct lpc2000_flash_bank_s
|
||||
{
|
||||
int variant;
|
||||
lpc2000_variant variant;
|
||||
struct working_area_s *iap_working_area;
|
||||
uint32_t cclk;
|
||||
int cmd51_dst_boundary;
|
||||
@@ -32,6 +42,7 @@ typedef struct lpc2000_flash_bank_s
|
||||
int cmd51_can_8192b;
|
||||
int calc_checksum;
|
||||
uint32_t cmd51_max_buffer;
|
||||
int checksum_vector;
|
||||
} lpc2000_flash_bank_t;
|
||||
|
||||
enum lpc2000_status_codes
|
||||
@@ -47,7 +58,16 @@ enum lpc2000_status_codes
|
||||
LPC2000_SECTOR_NOT_BLANK = 8,
|
||||
LPC2000_SECTOR_NOT_PREPARED = 9,
|
||||
LPC2000_COMPARE_ERROR = 10,
|
||||
LPC2000_BUSY = 11
|
||||
LPC2000_BUSY = 11,
|
||||
LPC2000_PARAM_ERROR = 12,
|
||||
LPC2000_ADDR_ERROR = 13,
|
||||
LPC2000_ADDR_NOT_MAPPED = 14,
|
||||
LPC2000_CMD_NOT_LOCKED = 15,
|
||||
LPC2000_INVALID_CODE = 16,
|
||||
LPC2000_INVALID_BAUD_RATE = 17,
|
||||
LPC2000_INVALID_STOP_BIT = 18,
|
||||
LPC2000_CRP_ENABLED = 19
|
||||
|
||||
};
|
||||
|
||||
#endif /* LPC2000_H */
|
||||
|
||||
@@ -214,8 +214,8 @@ static int lpc288x_flash_bank_command(struct command_context_s *cmd_ctx, char *c
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
|
||||
* This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.
|
||||
/* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
|
||||
* This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.
|
||||
* AHB = 12 MHz ?
|
||||
* 12000000/66000 = 182
|
||||
* CLK_DIV = 60 ? */
|
||||
|
||||
1928
src/flash/lpc2900.c
Normal file
1928
src/flash/lpc2900.c
Normal file
File diff suppressed because it is too large
Load Diff
27
src/flash/lpc2900.h
Normal file
27
src/flash/lpc2900.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009 by *
|
||||
* Rolf Meeser <rolfm_9dq@yahoo.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 lpc2900_H
|
||||
#define lpc2900_H
|
||||
|
||||
#include "flash.h"
|
||||
|
||||
|
||||
#endif /* lpc2900_H */
|
||||
@@ -474,8 +474,8 @@ static int mg_mflash_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt
|
||||
residue = sect_cnt % 256;
|
||||
|
||||
for (i = 0; i < quotient; i++) {
|
||||
LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : 0x%0lx", sect_num,
|
||||
(unsigned long)buff_ptr);
|
||||
LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p",
|
||||
sect_num, buff_ptr);
|
||||
ret = mg_mflash_do_read_sects(buff_ptr, sect_num, 256);
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
@@ -485,8 +485,8 @@ static int mg_mflash_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt
|
||||
}
|
||||
|
||||
if (residue) {
|
||||
LOG_DEBUG("mflash: sect num : %" PRIx32 " buff : %0lx", sect_num,
|
||||
(unsigned long)buff_ptr);
|
||||
LOG_DEBUG("mflash: sect num : %" PRIx32 " buff : %p",
|
||||
sect_num, buff_ptr);
|
||||
return mg_mflash_do_read_sects(buff_ptr, sect_num, residue);
|
||||
}
|
||||
|
||||
|
||||
902
src/flash/mx3_nand.c
Normal file
902
src/flash/mx3_nand.c
Normal file
@@ -0,0 +1,902 @@
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009 by Alexei Babich *
|
||||
* Rezonans plc., Chelyabinsk, Russia *
|
||||
* impatt@mail.ru *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Freescale iMX3* OpenOCD NAND Flash controller support.
|
||||
*
|
||||
* Many thanks to Ben Dooks for writing s3c24xx driver.
|
||||
*/
|
||||
|
||||
/*
|
||||
driver tested with STMicro NAND512W3A @imx31
|
||||
tested "nand probe #", "nand erase # 0 #", "nand dump # file 0 #", "nand write # file 0"
|
||||
get_next_halfword_from_sram_buffer() not tested
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "mx3_nand.h"
|
||||
|
||||
static const char target_not_halted_err_msg[] =
|
||||
"target must be halted to use mx3 NAND flash controller";
|
||||
static const char data_block_size_err_msg[] =
|
||||
"minimal granularity is one half-word, %" PRId32 " is incorrect";
|
||||
static const char sram_buffer_bounds_err_msg[] =
|
||||
"trying to access out of SRAM buffer bound (addr=0x%" PRIx32 ")";
|
||||
static const char get_status_register_err_msg[] = "can't get NAND status";
|
||||
static uint32_t in_sram_address;
|
||||
unsigned char sign_of_sequental_byte_read;
|
||||
|
||||
static int test_iomux_settings (target_t * target, uint32_t value,
|
||||
uint32_t mask, const char *text);
|
||||
static int initialize_nf_controller (struct nand_device_s *device);
|
||||
static int get_next_byte_from_sram_buffer (target_t * target, uint8_t * value);
|
||||
static int get_next_halfword_from_sram_buffer (target_t * target,
|
||||
uint16_t * value);
|
||||
static int poll_for_complete_op (target_t * target, const char *text);
|
||||
static int validate_target_state (struct nand_device_s *device);
|
||||
static int do_data_output (struct nand_device_s *device);
|
||||
|
||||
static int imx31_nand_device_command (struct command_context_s *cmd_ctx,
|
||||
char *cmd, char **args, int argc,
|
||||
struct nand_device_s *device);
|
||||
static int imx31_init (struct nand_device_s *device);
|
||||
static int imx31_read_data (struct nand_device_s *device, void *data);
|
||||
static int imx31_write_data (struct nand_device_s *device, uint16_t data);
|
||||
static int imx31_nand_ready (struct nand_device_s *device, int timeout);
|
||||
static int imx31_register_commands (struct command_context_s *cmd_ctx);
|
||||
static int imx31_reset (struct nand_device_s *device);
|
||||
static int imx31_command (struct nand_device_s *device, uint8_t command);
|
||||
static int imx31_address (struct nand_device_s *device, uint8_t address);
|
||||
static int imx31_controller_ready (struct nand_device_s *device, int tout);
|
||||
static int imx31_write_page (struct nand_device_s *device, uint32_t page,
|
||||
uint8_t * data, uint32_t data_size, uint8_t * oob,
|
||||
uint32_t oob_size);
|
||||
static int imx31_read_page (struct nand_device_s *device, uint32_t page,
|
||||
uint8_t * data, uint32_t data_size, uint8_t * oob,
|
||||
uint32_t oob_size);
|
||||
|
||||
nand_flash_controller_t imx31_nand_flash_controller = {
|
||||
.name = "imx31",
|
||||
.nand_device_command = imx31_nand_device_command,
|
||||
.register_commands = imx31_register_commands,
|
||||
.init = imx31_init,
|
||||
.reset = imx31_reset,
|
||||
.command = imx31_command,
|
||||
.address = imx31_address,
|
||||
.write_data = imx31_write_data,
|
||||
.read_data = imx31_read_data,
|
||||
.write_page = imx31_write_page,
|
||||
.read_page = imx31_read_page,
|
||||
.controller_ready = imx31_controller_ready,
|
||||
.nand_ready = imx31_nand_ready,
|
||||
};
|
||||
|
||||
static int imx31_nand_device_command (struct command_context_s *cmd_ctx,
|
||||
char *cmd, char **args, int argc,
|
||||
struct nand_device_s *device)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info;
|
||||
mx3_nf_info = malloc (sizeof (mx3_nf_controller_t));
|
||||
if (mx3_nf_info == NULL)
|
||||
{
|
||||
LOG_ERROR ("no memory for nand controller");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
device->controller_priv = mx3_nf_info;
|
||||
|
||||
mx3_nf_info->target = get_target (args[1]);
|
||||
if (mx3_nf_info->target == NULL)
|
||||
{
|
||||
LOG_ERROR ("target '%s' not defined", args[1]);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
if (argc < 3)
|
||||
{
|
||||
LOG_ERROR ("use \"nand device imx31 target noecc|hwecc\"");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
/*
|
||||
* check hwecc requirements
|
||||
*/
|
||||
{
|
||||
int hwecc_needed;
|
||||
hwecc_needed = strcmp (args[2], "hwecc");
|
||||
if (hwecc_needed == 0)
|
||||
{
|
||||
mx3_nf_info->flags.hw_ecc_enabled = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mx3_nf_info->flags.hw_ecc_enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE;
|
||||
mx3_nf_info->fin = MX3_NF_FIN_NONE;
|
||||
mx3_nf_info->flags.target_little_endian =
|
||||
(mx3_nf_info->target->endianness == TARGET_LITTLE_ENDIAN);
|
||||
/*
|
||||
* testing host endianess
|
||||
*/
|
||||
{
|
||||
int x = 1;
|
||||
if (*(char *) &x == 1)
|
||||
{
|
||||
mx3_nf_info->flags.host_little_endian = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mx3_nf_info->flags.host_little_endian = 0;
|
||||
}
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int imx31_init (struct nand_device_s *device)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
|
||||
{
|
||||
/*
|
||||
* validate target state
|
||||
*/
|
||||
int validate_target_result;
|
||||
validate_target_result = validate_target_state (device);
|
||||
if (validate_target_result != ERROR_OK)
|
||||
{
|
||||
return validate_target_result;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
uint16_t buffsize_register_content;
|
||||
target_read_u16 (target, MX3_NF_BUFSIZ, &buffsize_register_content);
|
||||
mx3_nf_info->flags.one_kb_sram = !(buffsize_register_content & 0x000f);
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t pcsr_register_content;
|
||||
target_read_u32 (target, MX3_PCSR, &pcsr_register_content);
|
||||
if (!device->bus_width)
|
||||
{
|
||||
device->bus_width =
|
||||
(pcsr_register_content & 0x80000000) ? 16 : 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcsr_register_content |=
|
||||
((device->bus_width == 16) ? 0x80000000 : 0x00000000);
|
||||
target_write_u32 (target, MX3_PCSR, pcsr_register_content);
|
||||
}
|
||||
|
||||
if (!device->page_size)
|
||||
{
|
||||
device->page_size =
|
||||
(pcsr_register_content & 0x40000000) ? 2048 : 512;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcsr_register_content |=
|
||||
((device->page_size == 2048) ? 0x40000000 : 0x00000000);
|
||||
target_write_u32 (target, MX3_PCSR, pcsr_register_content);
|
||||
}
|
||||
if (mx3_nf_info->flags.one_kb_sram && (device->page_size == 2048))
|
||||
{
|
||||
LOG_ERROR
|
||||
("NAND controller have only 1 kb SRAM, so pagesize 2048 is incompatible with it");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t cgr_register_content;
|
||||
target_read_u32 (target, MX3_CCM_CGR2, &cgr_register_content);
|
||||
if (!(cgr_register_content & 0x00000300))
|
||||
{
|
||||
LOG_ERROR ("clock gating to EMI disabled");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t gpr_register_content;
|
||||
target_read_u32 (target, MX3_GPR, &gpr_register_content);
|
||||
if (gpr_register_content & 0x00000060)
|
||||
{
|
||||
LOG_ERROR ("pins mode overrided by GPR");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
* testing IOMUX settings; must be in "functional-mode output and
|
||||
* functional-mode input" mode
|
||||
*/
|
||||
int test_iomux;
|
||||
test_iomux = ERROR_OK;
|
||||
test_iomux |=
|
||||
test_iomux_settings (target, 0x43fac0c0, 0x7f7f7f00, "d0,d1,d2");
|
||||
test_iomux |=
|
||||
test_iomux_settings (target, 0x43fac0c4, 0x7f7f7f7f, "d3,d4,d5,d6");
|
||||
test_iomux |=
|
||||
test_iomux_settings (target, 0x43fac0c8, 0x0000007f, "d7");
|
||||
if (device->bus_width == 16)
|
||||
{
|
||||
test_iomux |=
|
||||
test_iomux_settings (target, 0x43fac0c8, 0x7f7f7f00,
|
||||
"d8,d9,d10");
|
||||
test_iomux |=
|
||||
test_iomux_settings (target, 0x43fac0cc, 0x7f7f7f7f,
|
||||
"d11,d12,d13,d14");
|
||||
test_iomux |=
|
||||
test_iomux_settings (target, 0x43fac0d0, 0x0000007f, "d15");
|
||||
}
|
||||
test_iomux |=
|
||||
test_iomux_settings (target, 0x43fac0d0, 0x7f7f7f00,
|
||||
"nfwp,nfce,nfrb");
|
||||
test_iomux |=
|
||||
test_iomux_settings (target, 0x43fac0d4, 0x7f7f7f7f,
|
||||
"nfwe,nfre,nfale,nfcle");
|
||||
if (test_iomux != ERROR_OK)
|
||||
{
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
initialize_nf_controller (device);
|
||||
|
||||
{
|
||||
int retval;
|
||||
uint16_t nand_status_content;
|
||||
retval = ERROR_OK;
|
||||
retval |= imx31_command (device, NAND_CMD_STATUS);
|
||||
retval |= imx31_address (device, 0x00);
|
||||
retval |= do_data_output (device);
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
LOG_ERROR (get_status_register_err_msg);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
target_read_u16 (target, MX3_NF_MAIN_BUFFER0, &nand_status_content);
|
||||
if (!(nand_status_content & 0x0080))
|
||||
{
|
||||
/*
|
||||
* is host-big-endian correctly ??
|
||||
*/
|
||||
LOG_INFO ("NAND read-only");
|
||||
mx3_nf_info->flags.nand_readonly = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mx3_nf_info->flags.nand_readonly = 0;
|
||||
}
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int imx31_read_data (struct nand_device_s *device, void *data)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
{
|
||||
/*
|
||||
* validate target state
|
||||
*/
|
||||
int validate_target_result;
|
||||
validate_target_result = validate_target_state (device);
|
||||
if (validate_target_result != ERROR_OK)
|
||||
{
|
||||
return validate_target_result;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
* get data from nand chip
|
||||
*/
|
||||
int try_data_output_from_nand_chip;
|
||||
try_data_output_from_nand_chip = do_data_output (device);
|
||||
if (try_data_output_from_nand_chip != ERROR_OK)
|
||||
{
|
||||
return try_data_output_from_nand_chip;
|
||||
}
|
||||
}
|
||||
|
||||
if (device->bus_width == 16)
|
||||
{
|
||||
get_next_halfword_from_sram_buffer (target, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_next_byte_from_sram_buffer (target, data);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int imx31_write_data (struct nand_device_s *device, uint16_t data)
|
||||
{
|
||||
LOG_ERROR ("write_data() not implemented");
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
static int imx31_nand_ready (struct nand_device_s *device, int timeout)
|
||||
{
|
||||
return imx31_controller_ready (device, timeout);
|
||||
}
|
||||
|
||||
static int imx31_register_commands (struct command_context_s *cmd_ctx)
|
||||
{
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int imx31_reset (struct nand_device_s *device)
|
||||
{
|
||||
/*
|
||||
* validate target state
|
||||
*/
|
||||
int validate_target_result;
|
||||
validate_target_result = validate_target_state (device);
|
||||
if (validate_target_result != ERROR_OK)
|
||||
{
|
||||
return validate_target_result;
|
||||
}
|
||||
initialize_nf_controller (device);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int imx31_command (struct nand_device_s *device, uint8_t command)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
{
|
||||
/*
|
||||
* validate target state
|
||||
*/
|
||||
int validate_target_result;
|
||||
validate_target_result = validate_target_state (device);
|
||||
if (validate_target_result != ERROR_OK)
|
||||
{
|
||||
return validate_target_result;
|
||||
}
|
||||
}
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case NAND_CMD_READOOB:
|
||||
command = NAND_CMD_READ0;
|
||||
in_sram_address = MX3_NF_SPARE_BUFFER0; /* set read point for
|
||||
* data_read() and
|
||||
* read_block_data() to
|
||||
* spare area in SRAM
|
||||
* buffer */
|
||||
break;
|
||||
case NAND_CMD_READ1:
|
||||
command = NAND_CMD_READ0;
|
||||
/*
|
||||
* offset == one half of page size
|
||||
*/
|
||||
in_sram_address =
|
||||
MX3_NF_MAIN_BUFFER0 + (device->page_size >> 1);
|
||||
default:
|
||||
in_sram_address = MX3_NF_MAIN_BUFFER0;
|
||||
}
|
||||
|
||||
target_write_u16 (target, MX3_NF_FCMD, command);
|
||||
/*
|
||||
* start command input operation (set MX3_NF_BIT_OP_DONE==0)
|
||||
*/
|
||||
target_write_u16 (target, MX3_NF_CFG2, MX3_NF_BIT_OP_FCI);
|
||||
{
|
||||
int poll_result;
|
||||
poll_result = poll_for_complete_op (target, "command");
|
||||
if (poll_result != ERROR_OK)
|
||||
{
|
||||
return poll_result;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* reset cursor to begin of the buffer
|
||||
*/
|
||||
sign_of_sequental_byte_read = 0;
|
||||
switch (command)
|
||||
{
|
||||
case NAND_CMD_READID:
|
||||
mx3_nf_info->optype = MX3_NF_DATAOUT_NANDID;
|
||||
mx3_nf_info->fin = MX3_NF_FIN_DATAOUT;
|
||||
break;
|
||||
case NAND_CMD_STATUS:
|
||||
mx3_nf_info->optype = MX3_NF_DATAOUT_NANDSTATUS;
|
||||
mx3_nf_info->fin = MX3_NF_FIN_DATAOUT;
|
||||
break;
|
||||
case NAND_CMD_READ0:
|
||||
mx3_nf_info->fin = MX3_NF_FIN_DATAOUT;
|
||||
mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE;
|
||||
break;
|
||||
default:
|
||||
mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int imx31_address (struct nand_device_s *device, uint8_t address)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
{
|
||||
/*
|
||||
* validate target state
|
||||
*/
|
||||
int validate_target_result;
|
||||
validate_target_result = validate_target_state (device);
|
||||
if (validate_target_result != ERROR_OK)
|
||||
{
|
||||
return validate_target_result;
|
||||
}
|
||||
}
|
||||
|
||||
target_write_u16 (target, MX3_NF_FADDR, address);
|
||||
/*
|
||||
* start address input operation (set MX3_NF_BIT_OP_DONE==0)
|
||||
*/
|
||||
target_write_u16 (target, MX3_NF_CFG2, MX3_NF_BIT_OP_FAI);
|
||||
{
|
||||
int poll_result;
|
||||
poll_result = poll_for_complete_op (target, "address");
|
||||
if (poll_result != ERROR_OK)
|
||||
{
|
||||
return poll_result;
|
||||
}
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int imx31_controller_ready (struct nand_device_s *device, int tout)
|
||||
{
|
||||
uint16_t poll_complete_status;
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
|
||||
{
|
||||
/*
|
||||
* validate target state
|
||||
*/
|
||||
int validate_target_result;
|
||||
validate_target_result = validate_target_state (device);
|
||||
if (validate_target_result != ERROR_OK)
|
||||
{
|
||||
return validate_target_result;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
target_read_u16 (target, MX3_NF_CFG2, &poll_complete_status);
|
||||
if (poll_complete_status & MX3_NF_BIT_OP_DONE)
|
||||
{
|
||||
return tout;
|
||||
}
|
||||
alive_sleep (1);
|
||||
}
|
||||
while (tout-- > 0);
|
||||
return tout;
|
||||
}
|
||||
|
||||
static int imx31_write_page (struct nand_device_s *device, uint32_t page,
|
||||
uint8_t * data, uint32_t data_size, uint8_t * oob,
|
||||
uint32_t oob_size)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
|
||||
if (data_size % 2)
|
||||
{
|
||||
LOG_ERROR (data_block_size_err_msg, data_size);
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
if (oob_size % 2)
|
||||
{
|
||||
LOG_ERROR (data_block_size_err_msg, oob_size);
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
if (!data)
|
||||
{
|
||||
LOG_ERROR ("nothing to program");
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
{
|
||||
/*
|
||||
* validate target state
|
||||
*/
|
||||
int retval;
|
||||
retval = validate_target_state (device);
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
{
|
||||
int retval = ERROR_OK;
|
||||
retval |= imx31_command (device, NAND_CMD_SEQIN);
|
||||
retval |= imx31_address (device, 0x00);
|
||||
retval |= imx31_address (device, page & 0xff);
|
||||
retval |= imx31_address (device, (page >> 8) & 0xff);
|
||||
if (device->address_cycles >= 4)
|
||||
{
|
||||
retval |= imx31_address (device, (page >> 16) & 0xff);
|
||||
if (device->address_cycles >= 5)
|
||||
{
|
||||
retval |= imx31_address (device, (page >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
target_write_buffer (target, MX3_NF_MAIN_BUFFER0, data_size, data);
|
||||
if (oob)
|
||||
{
|
||||
if (mx3_nf_info->flags.hw_ecc_enabled)
|
||||
{
|
||||
/*
|
||||
* part of spare block will be overrided by hardware
|
||||
* ECC generator
|
||||
*/
|
||||
LOG_DEBUG
|
||||
("part of spare block will be overrided by hardware ECC generator");
|
||||
}
|
||||
target_write_buffer (target, MX3_NF_SPARE_BUFFER0, oob_size,
|
||||
oob);
|
||||
}
|
||||
/*
|
||||
* start data input operation (set MX3_NF_BIT_OP_DONE==0)
|
||||
*/
|
||||
target_write_u16 (target, MX3_NF_CFG2, MX3_NF_BIT_OP_FDI);
|
||||
{
|
||||
int poll_result;
|
||||
poll_result = poll_for_complete_op (target, "data input");
|
||||
if (poll_result != ERROR_OK)
|
||||
{
|
||||
return poll_result;
|
||||
}
|
||||
}
|
||||
retval |= imx31_command (device, NAND_CMD_PAGEPROG);
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* check status register
|
||||
*/
|
||||
{
|
||||
uint16_t nand_status_content;
|
||||
retval = ERROR_OK;
|
||||
retval |= imx31_command (device, NAND_CMD_STATUS);
|
||||
retval |= imx31_address (device, 0x00);
|
||||
retval |= do_data_output (device);
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
LOG_ERROR (get_status_register_err_msg);
|
||||
return retval;
|
||||
}
|
||||
target_read_u16 (target, MX3_NF_MAIN_BUFFER0, &nand_status_content);
|
||||
if (nand_status_content & 0x0001)
|
||||
{
|
||||
/*
|
||||
* is host-big-endian correctly ??
|
||||
*/
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int imx31_read_page (struct nand_device_s *device, uint32_t page,
|
||||
uint8_t * data, uint32_t data_size, uint8_t * oob,
|
||||
uint32_t oob_size)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
|
||||
if (data_size % 2)
|
||||
{
|
||||
LOG_ERROR (data_block_size_err_msg, data_size);
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
if (oob_size % 2)
|
||||
{
|
||||
LOG_ERROR (data_block_size_err_msg, oob_size);
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
* validate target state
|
||||
*/
|
||||
int retval;
|
||||
retval = validate_target_state (device);
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
{
|
||||
int retval = ERROR_OK;
|
||||
retval |= imx31_command (device, NAND_CMD_READ0);
|
||||
retval |= imx31_address (device, 0x00);
|
||||
retval |= imx31_address (device, page & 0xff);
|
||||
retval |= imx31_address (device, (page >> 8) & 0xff);
|
||||
if (device->address_cycles >= 4)
|
||||
{
|
||||
retval |= imx31_address (device, (page >> 16) & 0xff);
|
||||
if (device->address_cycles >= 5)
|
||||
{
|
||||
retval |= imx31_address (device, (page >> 24) & 0xff);
|
||||
retval |= imx31_command (device, NAND_CMD_READSTART);
|
||||
}
|
||||
}
|
||||
retval |= do_data_output (device);
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (data)
|
||||
{
|
||||
target_read_buffer (target, MX3_NF_MAIN_BUFFER0, data_size,
|
||||
data);
|
||||
}
|
||||
if (oob)
|
||||
{
|
||||
target_read_buffer (target, MX3_NF_SPARE_BUFFER0, oob_size,
|
||||
oob);
|
||||
}
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int test_iomux_settings (target_t * target, uint32_t address,
|
||||
uint32_t mask, const char *text)
|
||||
{
|
||||
uint32_t register_content;
|
||||
target_read_u32 (target, address, ®ister_content);
|
||||
if ((register_content & mask) != (0x12121212 & mask))
|
||||
{
|
||||
LOG_ERROR ("IOMUX for {%s} is bad", text);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int initialize_nf_controller (struct nand_device_s *device)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
/*
|
||||
* resets NAND flash controller in zero time ? I dont know.
|
||||
*/
|
||||
target_write_u16 (target, MX3_NF_CFG1, MX3_NF_BIT_RESET_EN);
|
||||
{
|
||||
uint16_t work_mode;
|
||||
work_mode = MX3_NF_BIT_INT_DIS; /* disable interrupt */
|
||||
if (target->endianness == TARGET_BIG_ENDIAN)
|
||||
{
|
||||
work_mode |= MX3_NF_BIT_BE_EN;
|
||||
}
|
||||
if (mx3_nf_info->flags.hw_ecc_enabled)
|
||||
{
|
||||
work_mode |= MX3_NF_BIT_ECC_EN;
|
||||
}
|
||||
target_write_u16 (target, MX3_NF_CFG1, work_mode);
|
||||
}
|
||||
/*
|
||||
* unlock SRAM buffer for write; 2 mean "Unlock", other values means "Lock"
|
||||
*/
|
||||
target_write_u16 (target, MX3_NF_BUFCFG, 2);
|
||||
{
|
||||
uint16_t temp;
|
||||
target_read_u16 (target, MX3_NF_FWP, &temp);
|
||||
if ((temp & 0x0007) == 1)
|
||||
{
|
||||
LOG_ERROR ("NAND flash is tight-locked, reset needed");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* unlock NAND flash for write
|
||||
*/
|
||||
target_write_u16 (target, MX3_NF_FWP, 4);
|
||||
target_write_u16 (target, MX3_NF_LOCKSTART, 0x0000);
|
||||
target_write_u16 (target, MX3_NF_LOCKEND, 0xFFFF);
|
||||
/*
|
||||
* 0x0000 means that first SRAM buffer @0xB800_0000 will be used
|
||||
*/
|
||||
target_write_u16 (target, MX3_NF_BUFADDR, 0x0000);
|
||||
/*
|
||||
* address of SRAM buffer
|
||||
*/
|
||||
in_sram_address = MX3_NF_MAIN_BUFFER0;
|
||||
sign_of_sequental_byte_read = 0;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int get_next_byte_from_sram_buffer (target_t * target, uint8_t * value)
|
||||
{
|
||||
static uint8_t even_byte = 0;
|
||||
/*
|
||||
* host-big_endian ??
|
||||
*/
|
||||
if (sign_of_sequental_byte_read == 0)
|
||||
{
|
||||
even_byte = 0;
|
||||
}
|
||||
if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR)
|
||||
{
|
||||
LOG_ERROR (sram_buffer_bounds_err_msg, in_sram_address);
|
||||
*value = 0;
|
||||
sign_of_sequental_byte_read = 0;
|
||||
even_byte = 0;
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t temp;
|
||||
target_read_u16 (target, in_sram_address, &temp);
|
||||
if (even_byte)
|
||||
{
|
||||
*value = temp >> 8;
|
||||
even_byte = 0;
|
||||
in_sram_address += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*value = temp & 0xff;
|
||||
even_byte = 1;
|
||||
}
|
||||
}
|
||||
sign_of_sequental_byte_read = 1;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int get_next_halfword_from_sram_buffer (target_t * target,
|
||||
uint16_t * value)
|
||||
{
|
||||
if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR)
|
||||
{
|
||||
LOG_ERROR (sram_buffer_bounds_err_msg, in_sram_address);
|
||||
*value = 0;
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
target_read_u16 (target, in_sram_address, value);
|
||||
in_sram_address += 2;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int poll_for_complete_op (target_t * target, const char *text)
|
||||
{
|
||||
uint16_t poll_complete_status;
|
||||
for (int poll_cycle_count = 0; poll_cycle_count < 100; poll_cycle_count++)
|
||||
{
|
||||
usleep (25);
|
||||
target_read_u16 (target, MX3_NF_CFG2, &poll_complete_status);
|
||||
if (poll_complete_status & MX3_NF_BIT_OP_DONE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!(poll_complete_status & MX3_NF_BIT_OP_DONE))
|
||||
{
|
||||
LOG_ERROR ("%s sending timeout", text);
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int validate_target_state (struct nand_device_s *device)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
|
||||
if (target->state != TARGET_HALTED)
|
||||
{
|
||||
LOG_ERROR (target_not_halted_err_msg);
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
if (mx3_nf_info->flags.target_little_endian !=
|
||||
(target->endianness == TARGET_LITTLE_ENDIAN))
|
||||
{
|
||||
/*
|
||||
* endianness changed after NAND controller probed
|
||||
*/
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int do_data_output (struct nand_device_s *device)
|
||||
{
|
||||
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
|
||||
target_t *target = mx3_nf_info->target;
|
||||
switch (mx3_nf_info->fin)
|
||||
{
|
||||
case MX3_NF_FIN_DATAOUT:
|
||||
/*
|
||||
* start data output operation (set MX3_NF_BIT_OP_DONE==0)
|
||||
*/
|
||||
target_write_u16 (target, MX3_NF_CFG2,
|
||||
MX3_NF_BIT_DATAOUT_TYPE (mx3_nf_info->
|
||||
optype));
|
||||
{
|
||||
int poll_result;
|
||||
poll_result = poll_for_complete_op (target, "data output");
|
||||
if (poll_result != ERROR_OK)
|
||||
{
|
||||
return poll_result;
|
||||
}
|
||||
}
|
||||
mx3_nf_info->fin = MX3_NF_FIN_NONE;
|
||||
/*
|
||||
* ECC stuff
|
||||
*/
|
||||
if ((mx3_nf_info->optype == MX3_NF_DATAOUT_PAGE)
|
||||
&& mx3_nf_info->flags.hw_ecc_enabled)
|
||||
{
|
||||
uint16_t ecc_status;
|
||||
target_read_u16 (target, MX3_NF_ECCSTATUS, &ecc_status);
|
||||
switch (ecc_status & 0x000c)
|
||||
{
|
||||
case 1 << 2:
|
||||
LOG_DEBUG
|
||||
("main area readed with 1 (correctable) error");
|
||||
break;
|
||||
case 2 << 2:
|
||||
LOG_DEBUG
|
||||
("main area readed with more than 1 (incorrectable) error");
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
break;
|
||||
}
|
||||
switch (ecc_status & 0x0003)
|
||||
{
|
||||
case 1:
|
||||
LOG_DEBUG
|
||||
("spare area readed with 1 (correctable) error");
|
||||
break;
|
||||
case 2:
|
||||
LOG_DEBUG
|
||||
("main area readed with more than 1 (incorrectable) error");
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MX3_NF_FIN_NONE:
|
||||
break;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
117
src/flash/mx3_nand.h
Normal file
117
src/flash/mx3_nand.h
Normal file
@@ -0,0 +1,117 @@
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009 by Alexei Babich *
|
||||
* Rezonans plc., Chelyabinsk, Russia *
|
||||
* impatt@mail.ru *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Freescale iMX3* OpenOCD NAND Flash controller support.
|
||||
*
|
||||
* Many thanks to Ben Dooks for writing s3c24xx driver.
|
||||
*/
|
||||
#include <nand.h>
|
||||
|
||||
#define MX3_NF_BASE_ADDR 0xb8000000
|
||||
#define MX3_NF_BUFSIZ (MX3_NF_BASE_ADDR + 0xe00)
|
||||
#define MX3_NF_BUFADDR (MX3_NF_BASE_ADDR + 0xe04)
|
||||
#define MX3_NF_FADDR (MX3_NF_BASE_ADDR + 0xe06)
|
||||
#define MX3_NF_FCMD (MX3_NF_BASE_ADDR + 0xe08)
|
||||
#define MX3_NF_BUFCFG (MX3_NF_BASE_ADDR + 0xe0a)
|
||||
#define MX3_NF_ECCSTATUS (MX3_NF_BASE_ADDR + 0xe0c)
|
||||
#define MX3_NF_ECCMAINPOS (MX3_NF_BASE_ADDR + 0xe0e)
|
||||
#define MX3_NF_ECCSPAREPOS (MX3_NF_BASE_ADDR + 0xe10)
|
||||
#define MX3_NF_FWP (MX3_NF_BASE_ADDR + 0xe12)
|
||||
#define MX3_NF_LOCKSTART (MX3_NF_BASE_ADDR + 0xe14)
|
||||
#define MX3_NF_LOCKEND (MX3_NF_BASE_ADDR + 0xe16)
|
||||
#define MX3_NF_FWPSTATUS (MX3_NF_BASE_ADDR + 0xe18)
|
||||
/*
|
||||
* all bits not marked as self-clearing bit
|
||||
*/
|
||||
#define MX3_NF_CFG1 (MX3_NF_BASE_ADDR + 0xe1a)
|
||||
#define MX3_NF_CFG2 (MX3_NF_BASE_ADDR + 0xe1c)
|
||||
|
||||
#define MX3_NF_MAIN_BUFFER0 (MX3_NF_BASE_ADDR + 0x0000)
|
||||
#define MX3_NF_MAIN_BUFFER1 (MX3_NF_BASE_ADDR + 0x0200)
|
||||
#define MX3_NF_MAIN_BUFFER2 (MX3_NF_BASE_ADDR + 0x0400)
|
||||
#define MX3_NF_MAIN_BUFFER3 (MX3_NF_BASE_ADDR + 0x0600)
|
||||
#define MX3_NF_SPARE_BUFFER0 (MX3_NF_BASE_ADDR + 0x0800)
|
||||
#define MX3_NF_SPARE_BUFFER1 (MX3_NF_BASE_ADDR + 0x0810)
|
||||
#define MX3_NF_SPARE_BUFFER2 (MX3_NF_BASE_ADDR + 0x0820)
|
||||
#define MX3_NF_SPARE_BUFFER3 (MX3_NF_BASE_ADDR + 0x0830)
|
||||
#define MX3_NF_MAIN_BUFFER_LEN 512
|
||||
#define MX3_NF_SPARE_BUFFER_LEN 16
|
||||
#define MX3_NF_LAST_BUFFER_ADDR ((MX3_NF_SPARE_BUFFER3) + MX3_NF_SPARE_BUFFER_LEN - 2)
|
||||
|
||||
/* bits in MX3_NF_CFG1 register */
|
||||
#define MX3_NF_BIT_SPARE_ONLY_EN (1<<2)
|
||||
#define MX3_NF_BIT_ECC_EN (1<<3)
|
||||
#define MX3_NF_BIT_INT_DIS (1<<4)
|
||||
#define MX3_NF_BIT_BE_EN (1<<5)
|
||||
#define MX3_NF_BIT_RESET_EN (1<<6)
|
||||
#define MX3_NF_BIT_FORCE_CE (1<<7)
|
||||
|
||||
/* bits in MX3_NF_CFG2 register */
|
||||
|
||||
/*Flash Command Input*/
|
||||
#define MX3_NF_BIT_OP_FCI (1<<0)
|
||||
/*
|
||||
* Flash Address Input
|
||||
*/
|
||||
#define MX3_NF_BIT_OP_FAI (1<<1)
|
||||
/*
|
||||
* Flash Data Input
|
||||
*/
|
||||
#define MX3_NF_BIT_OP_FDI (1<<2)
|
||||
|
||||
/* see "enum mx_dataout_type" below */
|
||||
#define MX3_NF_BIT_DATAOUT_TYPE(x) ((x)<<3)
|
||||
#define MX3_NF_BIT_OP_DONE (1<<15)
|
||||
|
||||
#define MX3_CCM_CGR2 0x53f80028
|
||||
#define MX3_GPR 0x43fac008
|
||||
#define MX3_PCSR 0x53f8000c
|
||||
|
||||
enum mx_dataout_type
|
||||
{
|
||||
MX3_NF_DATAOUT_PAGE = 1,
|
||||
MX3_NF_DATAOUT_NANDID = 2,
|
||||
MX3_NF_DATAOUT_NANDSTATUS = 4,
|
||||
};
|
||||
enum mx_nf_finalize_action
|
||||
{
|
||||
MX3_NF_FIN_NONE,
|
||||
MX3_NF_FIN_DATAOUT,
|
||||
};
|
||||
|
||||
struct mx3_nf_flags
|
||||
{
|
||||
unsigned host_little_endian:1;
|
||||
unsigned target_little_endian:1;
|
||||
unsigned nand_readonly:1;
|
||||
unsigned one_kb_sram:1;
|
||||
unsigned hw_ecc_enabled:1;
|
||||
};
|
||||
|
||||
typedef struct mx3_nf_controller_s
|
||||
{
|
||||
struct target_s *target;
|
||||
enum mx_dataout_type optype;
|
||||
enum mx_nf_finalize_action fin;
|
||||
struct mx3_nf_flags flags;
|
||||
} mx3_nf_controller_t;
|
||||
@@ -52,6 +52,7 @@ extern nand_flash_controller_t s3c2410_nand_controller;
|
||||
extern nand_flash_controller_t s3c2412_nand_controller;
|
||||
extern nand_flash_controller_t s3c2440_nand_controller;
|
||||
extern nand_flash_controller_t s3c2443_nand_controller;
|
||||
extern nand_flash_controller_t imx31_nand_flash_controller;
|
||||
|
||||
/* extern nand_flash_controller_t boundary_scan_nand_controller; */
|
||||
|
||||
@@ -64,6 +65,7 @@ static nand_flash_controller_t *nand_flash_controllers[] =
|
||||
&s3c2412_nand_controller,
|
||||
&s3c2440_nand_controller,
|
||||
&s3c2443_nand_controller,
|
||||
&imx31_nand_flash_controller,
|
||||
/* &boundary_scan_nand_controller, */
|
||||
NULL
|
||||
};
|
||||
@@ -307,8 +309,9 @@ int nand_init(struct command_context_s *cmd_ctx)
|
||||
"identify NAND flash device <num>");
|
||||
register_command(cmd_ctx, nand_cmd, "check_bad_blocks", handle_nand_check_bad_blocks_command, COMMAND_EXEC,
|
||||
"check NAND flash device <num> for bad blocks [<offset> <length>]");
|
||||
register_command(cmd_ctx, nand_cmd, "erase", handle_nand_erase_command, COMMAND_EXEC,
|
||||
"erase blocks on NAND flash device <num> <offset> <length>");
|
||||
register_command(cmd_ctx, nand_cmd, "erase",
|
||||
handle_nand_erase_command, COMMAND_EXEC,
|
||||
"erase blocks on NAND flash device <num> [<offset> <length>]");
|
||||
register_command(cmd_ctx, nand_cmd, "dump", handle_nand_dump_command, COMMAND_EXEC,
|
||||
"dump from NAND flash device <num> <filename> "
|
||||
"<offset> <length> [oob_raw | oob_only]");
|
||||
@@ -635,7 +638,7 @@ int nand_probe(struct nand_device_s *device)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int nand_erase(struct nand_device_s *device, int first_block, int last_block)
|
||||
static int nand_erase(struct nand_device_s *device, int first_block, int last_block)
|
||||
{
|
||||
int i;
|
||||
uint32_t page;
|
||||
@@ -710,8 +713,11 @@ int nand_erase(struct nand_device_s *device, int first_block, int last_block)
|
||||
|
||||
if (status & 0x1)
|
||||
{
|
||||
LOG_ERROR("erase operation didn't pass, status: 0x%2.2x", status);
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
LOG_ERROR("didn't erase %sblock %d; status: 0x%2.2x",
|
||||
(device->blocks[i].is_bad == 1)
|
||||
? "bad " : "",
|
||||
i, status);
|
||||
/* continue; other blocks might still be erasable */
|
||||
}
|
||||
|
||||
device->blocks[i].is_erased = 1;
|
||||
@@ -1073,8 +1079,12 @@ int handle_nand_list_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||
for (p = nand_devices, i = 0; p; p = p->next, i++)
|
||||
{
|
||||
if (p->device)
|
||||
command_print(cmd_ctx, "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i",
|
||||
i, p->device->name, p->manufacturer->name, p->page_size, p->bus_width, p->erase_size);
|
||||
command_print(cmd_ctx, "#%i: %s (%s) "
|
||||
"pagesize: %i, buswidth: %i,\n\t"
|
||||
"blocksize: %i, blocks: %i",
|
||||
i, p->device->name, p->manufacturer->name,
|
||||
p->page_size, p->bus_width,
|
||||
p->erase_size, p->num_blocks);
|
||||
else
|
||||
command_print(cmd_ctx, "#%i: not probed", i);
|
||||
}
|
||||
@@ -1195,7 +1205,7 @@ static int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cm
|
||||
nand_device_t *p;
|
||||
int retval;
|
||||
|
||||
if (argc != 3)
|
||||
if (argc != 1 && argc != 3)
|
||||
{
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
@@ -1208,27 +1218,37 @@ static int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cm
|
||||
unsigned long offset;
|
||||
unsigned long length;
|
||||
|
||||
offset = strtoul(args[1], &cp, 0);
|
||||
if (*cp || offset == ULONG_MAX || offset % p->erase_size)
|
||||
{
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
offset /= p->erase_size;
|
||||
/* erase specified part of the chip; or else everything */
|
||||
if (argc == 3) {
|
||||
unsigned long size = p->erase_size * p->num_blocks;
|
||||
|
||||
length = strtoul(args[2], &cp, 0);
|
||||
if (*cp || length == ULONG_MAX || length % p->erase_size)
|
||||
{
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
length -= 1;
|
||||
length /= p->erase_size;
|
||||
offset = strtoul(args[1], &cp, 0);
|
||||
if (*cp || (offset == ULONG_MAX)
|
||||
|| (offset % p->erase_size) != 0
|
||||
|| offset >= size)
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
retval = nand_erase(p, offset, offset + length);
|
||||
length = strtoul(args[2], &cp, 0);
|
||||
if (*cp || (length == ULONG_MAX)
|
||||
|| (length == 0)
|
||||
|| (length % p->erase_size) != 0
|
||||
|| (length + offset) > size)
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
offset /= p->erase_size;
|
||||
length /= p->erase_size;
|
||||
} else {
|
||||
offset = 0;
|
||||
length = p->num_blocks;
|
||||
}
|
||||
|
||||
retval = nand_erase(p, offset, offset + length - 1);
|
||||
if (retval == ERROR_OK)
|
||||
{
|
||||
command_print(cmd_ctx, "successfully erased blocks "
|
||||
"%lu to %lu on NAND flash device '%s'",
|
||||
offset, offset + length, p->device->name);
|
||||
command_print(cmd_ctx, "erased blocks %lu to %lu "
|
||||
"on NAND flash device #%s '%s'",
|
||||
offset, offset + length,
|
||||
args[0], p->device->name);
|
||||
}
|
||||
else if (retval == ERROR_NAND_OPERATION_FAILED)
|
||||
{
|
||||
|
||||
@@ -223,5 +223,6 @@ extern int nand_init(struct command_context_s *cmd_ctx);
|
||||
#define ERROR_NAND_OPERATION_NOT_SUPPORTED (-1103)
|
||||
#define ERROR_NAND_DEVICE_NOT_PROBED (-1104)
|
||||
#define ERROR_NAND_ERROR_CORRECTION_FAILED (-1105)
|
||||
#define ERROR_NAND_NO_BUFFER (-1106)
|
||||
|
||||
#endif /* NAND_H */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright (C) 2009 Marvell Semiconductor, Inc.
|
||||
*
|
||||
* Authors: Lennert Buytenhek <buytenh@wantstofly.org>
|
||||
* Nicolas Pitre <nico@cam.org>
|
||||
* Nicolas Pitre <nico@fluxnic.net>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define ERASE_REGION(num, size) (((size/256) << 16) | (num-1))
|
||||
|
||||
/* non-CFI compatible flashes */
|
||||
non_cfi_t non_cfi_flashes[] = {
|
||||
static non_cfi_t non_cfi_flashes[] = {
|
||||
{
|
||||
.mfr = CFI_MFR_SST,
|
||||
.id = 0xd4,
|
||||
@@ -140,7 +140,10 @@ non_cfi_t non_cfi_flashes[] = {
|
||||
|
||||
/* SST 39VF* do not support DQ5 status polling - this currently is
|
||||
only supported by the host algorithm, not by the target code using
|
||||
the work area. */
|
||||
the work area.
|
||||
Only true for 8-bit and 32-bit wide memories. 16-bit wide memories
|
||||
without DQ5 status polling are supported by the target code.
|
||||
*/
|
||||
{
|
||||
.mfr = CFI_MFR_SST,
|
||||
.id = 0x2782, /* SST39xF160 */
|
||||
|
||||
@@ -35,7 +35,6 @@ typedef struct non_cfi_s
|
||||
uint8_t status_poll_mask;
|
||||
} non_cfi_t;
|
||||
|
||||
extern non_cfi_t non_cfi_flashes[];
|
||||
extern void cfi_fixup_non_cfi(flash_bank_t *bank);
|
||||
|
||||
#endif /* NON_CFI_H */
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2006 by Michael Fischer. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* 3. Neither the name of the author nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************
|
||||
@@ -94,11 +94,11 @@ SECTIONS
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__bss_end = .);
|
||||
|
||||
|
||||
. = ALIGN(256);
|
||||
|
||||
|
||||
PROVIDE (__stack_start = .);
|
||||
|
||||
|
||||
PROVIDE (__stack_fiq_start = .);
|
||||
. += FIQ_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
@@ -124,9 +124,9 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_svc_end = .);
|
||||
PROVIDE (__stack_end = .);
|
||||
PROVIDE (__heap_start = .);
|
||||
PROVIDE (__heap_start = .);
|
||||
} > ram
|
||||
|
||||
|
||||
}
|
||||
/*** EOF ***/
|
||||
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2006 by Michael Fischer. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* 3. Neither the name of the author nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************
|
||||
@@ -33,14 +33,14 @@
|
||||
*
|
||||
* 18.12.06 mifi First Version
|
||||
* The hardware initialization is based on the startup file
|
||||
* crtat91sam7x256_rom.S from NutOS 4.2.1.
|
||||
* crtat91sam7x256_rom.S from NutOS 4.2.1.
|
||||
* Therefore partial copyright by egnite Software GmbH.
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Some defines for the program status registers
|
||||
*/
|
||||
ARM_MODE_USER = 0x10 /* Normal User Mode */
|
||||
ARM_MODE_USER = 0x10 /* Normal User Mode */
|
||||
ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */
|
||||
ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */
|
||||
ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */
|
||||
@@ -48,10 +48,10 @@
|
||||
ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */
|
||||
ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */
|
||||
ARM_MODE_MASK = 0x1F
|
||||
|
||||
|
||||
I_BIT = 0x80 /* disable IRQ when I bit is set */
|
||||
F_BIT = 0x40 /* disable IRQ when I bit is set */
|
||||
|
||||
|
||||
/*
|
||||
* Register Base Address
|
||||
*/
|
||||
@@ -70,10 +70,10 @@
|
||||
MC_BASE = 0xFFFFFF00
|
||||
MC_FMR_OFF = 0x00000060
|
||||
MC_FWS_1FWS = 0x00480100
|
||||
|
||||
|
||||
.section .vectors,"ax"
|
||||
.code 32
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Vector table and reset entry */
|
||||
/****************************************************************************/
|
||||
@@ -101,7 +101,7 @@ FIQAddr: .word FIQHandler
|
||||
|
||||
.section .init, "ax"
|
||||
.code 32
|
||||
|
||||
|
||||
.global ResetHandler
|
||||
.global ExitFunction
|
||||
.extern main
|
||||
@@ -116,7 +116,7 @@ ResetHandler:
|
||||
ldr r0, =WDT_WDDIS
|
||||
str r0, [r1, #WDT_MR_OFF]
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Enable user reset: assertion length programmed to 1ms
|
||||
*/
|
||||
@@ -124,7 +124,7 @@ ResetHandler:
|
||||
ldr r1, =RSTC_MR
|
||||
str r0, [r1, #0]
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Use 2 cycles for flash access.
|
||||
*/
|
||||
@@ -141,22 +141,22 @@ ResetHandler:
|
||||
str r0, [r1, #AIC_EOICR_OFF]
|
||||
str r0, [r1, #AIC_IDCR_OFF]
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Setup a stack for each mode
|
||||
*/
|
||||
msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */
|
||||
*/
|
||||
msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */
|
||||
ldr sp, =__stack_und_end
|
||||
|
||||
|
||||
msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */
|
||||
ldr sp, =__stack_abt_end
|
||||
|
||||
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */
|
||||
ldr sp, =__stack_fiq_end
|
||||
|
||||
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */
|
||||
ldr sp, =__stack_irq_end
|
||||
|
||||
|
||||
msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */
|
||||
ldr sp, =__stack_svc_end
|
||||
|
||||
@@ -171,27 +171,27 @@ bss_clear_loop:
|
||||
cmp r1, r2
|
||||
strne r3, [r1], #+4
|
||||
bne bss_clear_loop
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Jump to main
|
||||
*/
|
||||
mrs r0, cpsr
|
||||
bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */
|
||||
msr cpsr, r0
|
||||
|
||||
|
||||
mov r0, #0 /* No arguments */
|
||||
mov r1, #0 /* No arguments */
|
||||
ldr r2, =main
|
||||
mov lr, pc
|
||||
bx r2 /* And jump... */
|
||||
|
||||
|
||||
ExitFunction:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
b ExitFunction
|
||||
|
||||
b ExitFunction
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Default interrupt handler */
|
||||
@@ -199,7 +199,7 @@ ExitFunction:
|
||||
|
||||
UndefHandler:
|
||||
b UndefHandler
|
||||
|
||||
|
||||
SWIHandler:
|
||||
b SWIHandler
|
||||
|
||||
@@ -208,13 +208,13 @@ PAbortHandler:
|
||||
|
||||
DAbortHandler:
|
||||
b DAbortHandler
|
||||
|
||||
|
||||
IRQHandler:
|
||||
b IRQHandler
|
||||
|
||||
|
||||
FIQHandler:
|
||||
b FIQHandler
|
||||
|
||||
|
||||
.weak ExitFunction
|
||||
.weak UndefHandler, PAbortHandler, DAbortHandler
|
||||
.weak IRQHandler, FIQHandler
|
||||
|
||||
@@ -13,19 +13,19 @@ OBJDUMP = $(TRGT)objdump
|
||||
MCU = arm7tdmi
|
||||
|
||||
# List all default C defines here, like -D_DEBUG=1
|
||||
DDEFS =
|
||||
DDEFS =
|
||||
|
||||
# List all default ASM defines here, like -D_DEBUG=1
|
||||
DADEFS =
|
||||
DADEFS =
|
||||
|
||||
# List all default directories to look for include files here
|
||||
DINCDIR =
|
||||
DINCDIR =
|
||||
|
||||
# List the default directory to look for the libraries here
|
||||
DLIBDIR =
|
||||
|
||||
# List all default libraries here
|
||||
DLIBS =
|
||||
DLIBS =
|
||||
|
||||
#
|
||||
# End of default section
|
||||
@@ -42,10 +42,10 @@ PROJECT = at91sam7x_ocl
|
||||
LDSCRIPT= at91sam7x_ram.ld
|
||||
|
||||
# List all user C define here, like -D_DEBUG=1
|
||||
UDEFS =
|
||||
UDEFS =
|
||||
|
||||
# Define ASM defines here
|
||||
UADEFS =
|
||||
UADEFS =
|
||||
|
||||
# List C source files here
|
||||
SRC = main.c dcc.c samflash.c
|
||||
@@ -60,7 +60,7 @@ UINCDIR =
|
||||
ULIBDIR =
|
||||
|
||||
# List all user libraries here
|
||||
ULIBS =
|
||||
ULIBS =
|
||||
|
||||
# Define optimisation level here
|
||||
OPT = -O2
|
||||
@@ -122,7 +122,7 @@ clean:
|
||||
-rm -f $(ASRC:.s=.lst)
|
||||
-rm -fR .dep
|
||||
|
||||
#
|
||||
#
|
||||
# Include the dependency files, should be the last of the makefile
|
||||
#
|
||||
#-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
@@ -26,15 +26,15 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "nand.h"
|
||||
#include "arm_nandio.h"
|
||||
#include "armv4_5.h"
|
||||
#include "binarybuffer.h"
|
||||
|
||||
|
||||
typedef struct orion_nand_controller_s
|
||||
{
|
||||
struct target_s *target;
|
||||
working_area_t *copy_area;
|
||||
|
||||
struct arm_nand_data io;
|
||||
|
||||
uint32_t cmd;
|
||||
uint32_t addr;
|
||||
@@ -99,78 +99,14 @@ static int orion_nand_slow_block_write(struct nand_device_s *device, uint8_t *da
|
||||
static int orion_nand_fast_block_write(struct nand_device_s *device, uint8_t *data, int size)
|
||||
{
|
||||
orion_nand_controller_t *hw = device->controller_priv;
|
||||
target_t *target = hw->target;
|
||||
armv4_5_algorithm_t algo;
|
||||
reg_param_t reg_params[3];
|
||||
uint32_t target_buf;
|
||||
int retval;
|
||||
|
||||
static const uint32_t code[] = {
|
||||
0xe4d13001, /* ldrb r3, [r1], #1 */
|
||||
0xe5c03000, /* strb r3, [r0] */
|
||||
0xe2522001, /* subs r2, r2, #1 */
|
||||
0x1afffffb, /* bne 0 */
|
||||
0xeafffffe, /* b . */
|
||||
};
|
||||
int code_size = sizeof(code);
|
||||
hw->io.chunk_size = device->page_size;
|
||||
|
||||
if (!hw->copy_area) {
|
||||
uint8_t code_buf[code_size];
|
||||
int i;
|
||||
retval = arm_nandwrite(&hw->io, data, size);
|
||||
if (retval == ERROR_NAND_NO_BUFFER)
|
||||
retval = orion_nand_slow_block_write(device, data, size);
|
||||
|
||||
/* make sure we have a working area */
|
||||
if (target_alloc_working_area(target,
|
||||
code_size + device->page_size,
|
||||
&hw->copy_area) != ERROR_OK)
|
||||
{
|
||||
return orion_nand_slow_block_write(device, data, size);
|
||||
}
|
||||
|
||||
/* copy target instructions to target endianness */
|
||||
for (i = 0; i < code_size/4; i++)
|
||||
target_buffer_set_u32(target, code_buf + i*4, code[i]);
|
||||
|
||||
/* write code to working area */
|
||||
retval = target_write_memory(target,
|
||||
hw->copy_area->address,
|
||||
4, code_size/4, code_buf);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* copy data to target's memory */
|
||||
target_buf = hw->copy_area->address + code_size;
|
||||
retval = target_bulk_write_memory(target, target_buf, size/4, data);
|
||||
if (retval == ERROR_OK && size & 3) {
|
||||
retval = target_write_memory(target,
|
||||
target_buf + (size & ~3),
|
||||
1, size & 3, data + (size & ~3));
|
||||
}
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
algo.common_magic = ARMV4_5_COMMON_MAGIC;
|
||||
algo.core_mode = ARMV4_5_MODE_SVC;
|
||||
algo.core_state = ARMV4_5_STATE_ARM;
|
||||
|
||||
init_reg_param(®_params[0], "r0", 32, PARAM_IN);
|
||||
init_reg_param(®_params[1], "r1", 32, PARAM_IN);
|
||||
init_reg_param(®_params[2], "r2", 32, PARAM_IN);
|
||||
|
||||
buf_set_u32(reg_params[0].value, 0, 32, hw->data);
|
||||
buf_set_u32(reg_params[1].value, 0, 32, target_buf);
|
||||
buf_set_u32(reg_params[2].value, 0, 32, size);
|
||||
|
||||
retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
|
||||
hw->copy_area->address,
|
||||
hw->copy_area->address + code_size - 4,
|
||||
1000, &algo);
|
||||
if (retval != ERROR_OK)
|
||||
LOG_ERROR("error executing hosted NAND write");
|
||||
|
||||
destroy_reg_param(®_params[0]);
|
||||
destroy_reg_param(®_params[1]);
|
||||
destroy_reg_param(®_params[2]);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -198,7 +134,7 @@ int orion_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||
uint8_t ale, cle;
|
||||
|
||||
if (argc != 3) {
|
||||
LOG_ERROR("arguments must be: <target_number> <NAND_address>\n");
|
||||
LOG_ERROR("arguments must be: <target_id> <NAND_address>\n");
|
||||
return ERROR_NAND_DEVICE_INVALID;
|
||||
}
|
||||
|
||||
@@ -224,6 +160,9 @@ int orion_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||
hw->cmd = base + (1 << cle);
|
||||
hw->addr = base + (1 << ale);
|
||||
|
||||
hw->io.target = hw->target;
|
||||
hw->io.data = hw->data;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -257,7 +257,10 @@ static int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char
|
||||
/* part wasn't probed for info yet */
|
||||
stellaris_info->did1 = 0;
|
||||
|
||||
/* TODO Use an optional main oscillator clock rate in kHz from arg[6] */
|
||||
/* TODO Specify the main crystal speed in kHz using an optional
|
||||
* argument; ditto, the speed of an external oscillator used
|
||||
* instead of a crystal. Avoid programming flash using IOSC.
|
||||
*/
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
@@ -294,7 +297,8 @@ static int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
||||
}
|
||||
printed = snprintf(buf,
|
||||
buf_size,
|
||||
"\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
|
||||
"\nTI/LMI Stellaris information: Chip is "
|
||||
"class %i (%s) %s rev %c%i\n",
|
||||
device_class,
|
||||
StellarisClassname[device_class],
|
||||
stellaris_info->target_name,
|
||||
@@ -305,10 +309,11 @@ static int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
||||
|
||||
printed = snprintf(buf,
|
||||
buf_size,
|
||||
"did1: 0x%8.8" PRIx32 ", arch: 0x%4.4" PRIx32 ", eproc: %s, ramsize:%ik, flashsize: %ik\n",
|
||||
"did1: 0x%8.8" PRIx32 ", arch: 0x%4.4" PRIx32
|
||||
", eproc: %s, ramsize: %ik, flashsize: %ik\n",
|
||||
stellaris_info->did1,
|
||||
stellaris_info->did1,
|
||||
"ARMV7M",
|
||||
"ARMv7M",
|
||||
(int)((1 + ((stellaris_info->dc0 >> 16) & 0xFFFF))/4),
|
||||
(int)((1 + (stellaris_info->dc0 & 0xFFFF))*2));
|
||||
buf += printed;
|
||||
@@ -316,9 +321,12 @@ static int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
||||
|
||||
printed = snprintf(buf,
|
||||
buf_size,
|
||||
"master clock(estimated): %ikHz, rcc is 0x%" PRIx32 " \n",
|
||||
"master clock: %ikHz%s, "
|
||||
"rcc is 0x%" PRIx32 ", rcc2 is 0x%" PRIx32 "\n",
|
||||
(int)(stellaris_info->mck_freq / 1000),
|
||||
stellaris_info->rcc);
|
||||
stellaris_info->mck_desc,
|
||||
stellaris_info->rcc,
|
||||
stellaris_info->rcc2);
|
||||
buf += printed;
|
||||
buf_size -= printed;
|
||||
|
||||
@@ -353,38 +361,103 @@ static uint32_t stellaris_get_flash_status(flash_bank_t *bank)
|
||||
|
||||
/** Read clock configuration and set stellaris_info->usec_clocks*/
|
||||
|
||||
static const unsigned rcc_xtal[32] = {
|
||||
[0x00] = 1000000, /* no pll */
|
||||
[0x01] = 1843200, /* no pll */
|
||||
[0x02] = 2000000, /* no pll */
|
||||
[0x03] = 2457600, /* no pll */
|
||||
|
||||
[0x04] = 3579545,
|
||||
[0x05] = 3686400,
|
||||
[0x06] = 4000000, /* usb */
|
||||
[0x07] = 4096000,
|
||||
|
||||
[0x08] = 4915200,
|
||||
[0x09] = 5000000, /* usb */
|
||||
[0x0a] = 5120000,
|
||||
[0x0b] = 6000000, /* (reset) usb */
|
||||
|
||||
[0x0c] = 6144000,
|
||||
[0x0d] = 7372800,
|
||||
[0x0e] = 8000000, /* usb */
|
||||
[0x0f] = 8192000,
|
||||
|
||||
/* parts before DustDevil use just 4 bits for xtal spec */
|
||||
|
||||
[0x10] = 10000000, /* usb */
|
||||
[0x11] = 12000000, /* usb */
|
||||
[0x12] = 12288000,
|
||||
[0x13] = 13560000,
|
||||
|
||||
[0x14] = 14318180,
|
||||
[0x15] = 16000000, /* usb */
|
||||
[0x16] = 16384000,
|
||||
};
|
||||
|
||||
static void stellaris_read_clock_info(flash_bank_t *bank)
|
||||
{
|
||||
stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
|
||||
target_t *target = bank->target;
|
||||
uint32_t rcc, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;
|
||||
uint32_t rcc, rcc2, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;
|
||||
unsigned xtal;
|
||||
unsigned long mainfreq;
|
||||
|
||||
target_read_u32(target, SCB_BASE | RCC, &rcc);
|
||||
LOG_DEBUG("Stellaris RCC %" PRIx32 "", rcc);
|
||||
|
||||
target_read_u32(target, SCB_BASE | RCC2, &rcc2);
|
||||
LOG_DEBUG("Stellaris RCC2 %" PRIx32 "", rcc);
|
||||
|
||||
target_read_u32(target, SCB_BASE | PLLCFG, &pllcfg);
|
||||
LOG_DEBUG("Stellaris PLLCFG %" PRIx32 "", pllcfg);
|
||||
|
||||
stellaris_info->rcc = rcc;
|
||||
stellaris_info->rcc = rcc2;
|
||||
|
||||
sysdiv = (rcc >> 23) & 0xF;
|
||||
usesysdiv = (rcc >> 22) & 0x1;
|
||||
bypass = (rcc >> 11) & 0x1;
|
||||
oscsrc = (rcc >> 4) & 0x3;
|
||||
/* xtal = (rcc >> 6)&0xF; */
|
||||
xtal = (rcc >> 6) & stellaris_info->xtal_mask;
|
||||
|
||||
/* NOTE: post-Sandstorm parts have RCC2 which may override
|
||||
* parts of RCC ... with more sysdiv options, option for
|
||||
* 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
|
||||
* as zero, so the "use RCC2" flag is always clear.
|
||||
*/
|
||||
if (rcc2 & (1 << 31)) {
|
||||
sysdiv = (rcc2 >> 23) & 0x3F;
|
||||
bypass = (rcc2 >> 11) & 0x1;
|
||||
oscsrc = (rcc2 >> 4) & 0x7;
|
||||
|
||||
/* FIXME Tempest parts have an additional lsb for
|
||||
* fractional sysdiv (200 MHz / 2.5 == 80 MHz)
|
||||
*/
|
||||
}
|
||||
|
||||
stellaris_info->mck_desc = "";
|
||||
|
||||
switch (oscsrc)
|
||||
{
|
||||
case 0:
|
||||
mainfreq = 6000000; /* Default xtal */
|
||||
case 0: /* MOSC */
|
||||
mainfreq = rcc_xtal[xtal];
|
||||
break;
|
||||
case 1:
|
||||
mainfreq = 22500000; /* Internal osc. 15 MHz +- 50% */
|
||||
case 1: /* IOSC */
|
||||
mainfreq = stellaris_info->iosc_freq;
|
||||
stellaris_info->mck_desc = stellaris_info->iosc_desc;
|
||||
break;
|
||||
case 2:
|
||||
mainfreq = 5625000; /* Internal osc. / 4 */
|
||||
case 2: /* IOSC/4 */
|
||||
mainfreq = stellaris_info->iosc_freq / 4;
|
||||
stellaris_info->mck_desc = stellaris_info->iosc_desc;
|
||||
break;
|
||||
case 3:
|
||||
LOG_WARNING("Invalid oscsrc (3) in rcc register");
|
||||
mainfreq = 6000000;
|
||||
case 3: /* lowspeed */
|
||||
/* Sandstorm doesn't have this 30K +/- 30% osc */
|
||||
mainfreq = 30000;
|
||||
stellaris_info->mck_desc = " (±30%)";
|
||||
break;
|
||||
case 8: /* hibernation osc */
|
||||
/* not all parts support hibernation */
|
||||
mainfreq = 32768;
|
||||
break;
|
||||
|
||||
default: /* NOTREACHED */
|
||||
@@ -392,8 +465,11 @@ static void stellaris_read_clock_info(flash_bank_t *bank)
|
||||
break;
|
||||
}
|
||||
|
||||
/* PLL is used if it's not bypassed; its output is 200 MHz
|
||||
* even when it runs at 400 MHz (adds divide-by-two stage).
|
||||
*/
|
||||
if (!bypass)
|
||||
mainfreq = 200000000; /* PLL out frec */
|
||||
mainfreq = 200000000;
|
||||
|
||||
if (usesysdiv)
|
||||
stellaris_info->mck_freq = mainfreq/(1 + sysdiv);
|
||||
@@ -487,6 +563,48 @@ static int stellaris_read_part_info(struct flash_bank_s *bank)
|
||||
LOG_WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
|
||||
}
|
||||
|
||||
/* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
|
||||
* is 12 MHz, but some older parts have 15 MHz. A few data sheets
|
||||
* even give _both_ numbers! We'll use current numbers; IOSC is
|
||||
* always approximate.
|
||||
*
|
||||
* For Tempest: IOSC is calibrated, 16 MHz
|
||||
*/
|
||||
stellaris_info->iosc_freq = 12000000;
|
||||
stellaris_info->iosc_desc = " (±30%)";
|
||||
stellaris_info->xtal_mask = 0x0f;
|
||||
|
||||
switch ((did0 >> 28) & 0x7) {
|
||||
case 0: /* Sandstorm */
|
||||
/*
|
||||
* Current (2009-August) parts seem to be rev C2 and use 12 MHz.
|
||||
* Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
|
||||
* (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
|
||||
*/
|
||||
if (((did0 >> 8) & 0xff) < 2) {
|
||||
stellaris_info->iosc_freq = 15000000;
|
||||
stellaris_info->iosc_desc = " (±50%)";
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch ((did0 >> 16) & 0xff) {
|
||||
case 1: /* Fury */
|
||||
break;
|
||||
case 4: /* Tempest */
|
||||
stellaris_info->iosc_freq = 16000000; /* +/- 1% */
|
||||
stellaris_info->iosc_desc = " (±1%)";
|
||||
/* FALL THROUGH */
|
||||
case 3: /* DustDevil */
|
||||
stellaris_info->xtal_mask = 0x1f;
|
||||
break;
|
||||
default:
|
||||
LOG_WARNING("Unknown did0 class");
|
||||
}
|
||||
default:
|
||||
break;
|
||||
LOG_WARNING("Unknown did0 version");
|
||||
}
|
||||
|
||||
for (i = 0; StellarisParts[i].partno; i++)
|
||||
{
|
||||
if (StellarisParts[i].partno == ((did1 >> 16) & 0xFF))
|
||||
@@ -547,7 +665,7 @@ static int stellaris_protect_check(struct flash_bank_s *bank)
|
||||
|
||||
if (stellaris_info->did1 == 0)
|
||||
{
|
||||
LOG_WARNING("Cannot identify target as an AT91SAM");
|
||||
LOG_WARNING("Cannot identify target as Stellaris");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
@@ -799,8 +917,8 @@ static int stellaris_write_block(struct flash_bank_s *bank, uint8_t *buffer, uin
|
||||
buf_set_u32(reg_params[0].value, 0, 32, source->address);
|
||||
buf_set_u32(reg_params[1].value, 0, 32, address);
|
||||
buf_set_u32(reg_params[2].value, 0, 32, 4*thisrun_count);
|
||||
LOG_INFO("Algorithm flash write %" PRIi32 " words to 0x%" PRIx32 ", %" PRIi32 " remaining", thisrun_count, address, wcount);
|
||||
LOG_DEBUG("Algorithm flash write %" PRIi32 " words to 0x%" PRIx32 ", %" PRIi32 " remaining", thisrun_count, address, wcount);
|
||||
LOG_INFO("Algorithm flash write %" PRIi32 " words to 0x%" PRIx32 ", %" PRIi32 " remaining", thisrun_count, address, (wcount - thisrun_count));
|
||||
LOG_DEBUG("Algorithm flash write %" PRIi32 " words to 0x%" PRIx32 ", %" PRIi32 " remaining", thisrun_count, address, (wcount - thisrun_count));
|
||||
if ((retval = target_run_algorithm(target, 0, NULL, 3, reg_params, write_algorithm->address, write_algorithm->address + sizeof(stellaris_write_code)-10, 10000, &armv7m_info)) != ERROR_OK)
|
||||
{
|
||||
LOG_ERROR("error executing stellaris flash write algorithm");
|
||||
|
||||
@@ -45,8 +45,13 @@ typedef struct stellaris_flash_bank_s
|
||||
|
||||
/* main clock status */
|
||||
uint32_t rcc;
|
||||
uint32_t rcc2;
|
||||
uint8_t mck_valid;
|
||||
uint8_t xtal_mask;
|
||||
uint32_t iosc_freq;
|
||||
uint32_t mck_freq;
|
||||
const char *iosc_desc;
|
||||
const char *mck_desc;
|
||||
} stellaris_flash_bank_t;
|
||||
|
||||
/* STELLARIS control registers */
|
||||
@@ -62,6 +67,7 @@ typedef struct stellaris_flash_bank_s
|
||||
#define RIS 0x050
|
||||
#define RCC 0x060
|
||||
#define PLLCFG 0x064
|
||||
#define RCC2 0x070
|
||||
|
||||
#define FMPRE 0x130
|
||||
#define FMPPE 0x134
|
||||
|
||||
@@ -410,7 +410,7 @@ static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int las
|
||||
|
||||
if ((first && (first % stm32x_info->ppage_size)) || ((last + 1) && (last + 1) % stm32x_info->ppage_size))
|
||||
{
|
||||
LOG_WARNING("sector start/end incorrect - stm32 has %dK sector protection", stm32x_info->ppage_size);
|
||||
LOG_WARNING("Error: start and end sectors must be on a %d sector boundary", stm32x_info->ppage_size);
|
||||
return ERROR_FLASH_SECTOR_INVALID;
|
||||
}
|
||||
|
||||
|
||||
@@ -1254,7 +1254,8 @@ static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
|
||||
return ERROR_FAIL;
|
||||
|
||||
/* exit turbo mode via RESET */
|
||||
str9xpec_set_instr(tap, ISC_NOOP, TAP_RESET);
|
||||
str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
|
||||
jtag_add_tlr();
|
||||
jtag_execute_queue();
|
||||
|
||||
/* restore previous scan chain */
|
||||
|
||||
@@ -7,9 +7,9 @@ METASOURCES = AUTO
|
||||
noinst_LTLIBRARIES = libhelper.la
|
||||
|
||||
if ECOSBOARD
|
||||
CONFIGFILES =
|
||||
CONFIGFILES =
|
||||
else
|
||||
CONFIGFILES = options.c jim.c jim-eventloop.c
|
||||
CONFIGFILES = options.c jim.c jim-eventloop.c
|
||||
endif
|
||||
|
||||
|
||||
@@ -52,12 +52,16 @@ noinst_HEADERS = \
|
||||
startup.tcl \
|
||||
bin2char.c
|
||||
|
||||
bin2char$(EXEEXT_FOR_BUILD): bin2char.c
|
||||
BIN2C = bin2char$(EXEEXT_FOR_BUILD)
|
||||
|
||||
BUILT_SOURCES = $(BIN2C)
|
||||
|
||||
$(BIN2C): bin2char.c
|
||||
${CC_FOR_BUILD} ${CFLAGS_FOR_BUILD} $(srcdir)/bin2char.c -o $@
|
||||
|
||||
# Convert .tcl to cfile
|
||||
startup_tcl.c: startup.tcl bin2char$(EXEEXT_FOR_BUILD)
|
||||
./bin2char$(EXEEXT_FOR_BUILD) startup_tcl < $(srcdir)/startup.tcl > $@
|
||||
startup_tcl.c: startup.tcl $(BIN2C)
|
||||
./$(BIN2C) startup_tcl < $(srcdir)/startup.tcl > $@
|
||||
|
||||
# add startup_tcl.c to make clean list
|
||||
CLEANFILES = startup_tcl.c bin2char$(EXEEXT_FOR_BUILD)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -86,7 +86,7 @@ extern char* buf_to_str(const uint8_t *buf, int size, int radix);
|
||||
struct scan_field_s;
|
||||
extern int buf_to_u32_handler(uint8_t *in_buf, void *priv, struct scan_field_s *field);
|
||||
|
||||
#define CEIL(m, n) ((m + n - 1) / n)
|
||||
#define CEIL(m, n) (((m) + (n) - 1) / (n))
|
||||
|
||||
/* read a uint32_t from a buffer in target memory endianness */
|
||||
static inline uint32_t fast_target_buffer_get_u32(const uint8_t *buffer, int little)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 <EFBFBD>yvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008, Duane Ellis *
|
||||
@@ -117,6 +117,10 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
words[i] = strdup(w);
|
||||
if (words[i] == NULL)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < i; j++)
|
||||
free(words[j]);
|
||||
free(words);
|
||||
return JIM_ERR;
|
||||
}
|
||||
}
|
||||
@@ -740,8 +744,6 @@ command_context_t* command_init()
|
||||
interp->cb_fflush = openocd_jim_fflush;
|
||||
interp->cb_fgets = openocd_jim_fgets;
|
||||
|
||||
add_default_dirs();
|
||||
|
||||
#if !BUILD_ECOSBOARD
|
||||
Jim_EventLoopOnLoad(interp);
|
||||
#endif
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -35,6 +35,15 @@
|
||||
#include "jim.h"
|
||||
#endif
|
||||
|
||||
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
|
||||
* used for __attribute__((format( ... ))), with GCC v4.4 or later
|
||||
*/
|
||||
#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))
|
||||
#define PRINTF_ATTRIBUTE_FORMAT gnu_printf
|
||||
#else
|
||||
#define PRINTF_ATTRIBUTE_FORMAT printf
|
||||
#endif
|
||||
|
||||
enum command_mode
|
||||
{
|
||||
COMMAND_EXEC,
|
||||
@@ -85,12 +94,12 @@ extern command_context_t* command_init(void);
|
||||
extern int command_done(command_context_t *context);
|
||||
|
||||
extern void command_print(command_context_t *context, const char *format, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
|
||||
extern void command_print_sameline(command_context_t *context, const char *format, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
|
||||
extern int command_run_line(command_context_t *context, char *line);
|
||||
extern int command_run_linef(command_context_t *context, const char *format, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
|
||||
extern void command_output_text(command_context_t *context, const char *data);
|
||||
|
||||
extern void process_jim_events(void);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -32,6 +32,5 @@ extern void add_script_search_dir (const char *dir);
|
||||
extern int configuration_output_handler(struct command_context_s *context, const char* line);
|
||||
extern FILE *open_file_from_path (char *file, char *mode);
|
||||
extern char *find_file(const char *name);
|
||||
int add_default_dirs(void);
|
||||
|
||||
#endif /* CONFIGURATION_H */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2007 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2007 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007-2008 by Øyvind Harboe *
|
||||
* 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 *
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
|
||||
* Copyright 2005 Clemens Hintze <c.hintze@gmx.net>
|
||||
* Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>
|
||||
* Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
|
||||
* Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
|
||||
* Copyright 2008 Andrew Lunn <andrew@lunn.ch>
|
||||
* Copyright 2008 Duane Ellis <openocd@duaneellis.com>
|
||||
* Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
|
||||
@@ -52,8 +52,7 @@
|
||||
#define __JIM_EVENTLOOP_CORE__
|
||||
#ifdef __ECOS
|
||||
#include <pkgconf/jimtcl.h>
|
||||
#endif
|
||||
#ifdef __ECOS
|
||||
#include <sys/time.h>
|
||||
#include <cyg/jimtcl/jim.h>
|
||||
#include <cyg/jimtcl/jim-eventloop.h>
|
||||
#else
|
||||
@@ -498,7 +497,7 @@ static int JimELAfterCommand(Jim_Interp *interp, int argc,
|
||||
int tlen ;
|
||||
jim_wide remain = 0;
|
||||
const char *tok = Jim_GetString(argv[2], &tlen);
|
||||
if (sscanf(tok,"after#%lld",&id) == 1) {
|
||||
if (sscanf(tok,"after#%" JIM_WIDE_MODIFIER, &id) == 1) {
|
||||
remain = Jim_DeleteTimeHandler(interp, id);
|
||||
if (remain > -2) {
|
||||
Jim_SetResult(interp, Jim_NewIntObj(interp, remain));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
|
||||
* Copyright 2005 Clemens Hintze <c.hintze@gmx.net>
|
||||
* Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>
|
||||
* Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
|
||||
* Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
|
||||
* Copyright 2008 Andrew Lunn <andrew@lunn.ch>
|
||||
* Copyright 2008 Duane Ellis <openocd@duaneellis.com>
|
||||
* Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
* Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
|
||||
* Copyright 2005 Clemens Hintze <c.hintze@gmx.net>
|
||||
* Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>
|
||||
* Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
|
||||
* Copyright 2008,2009 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
|
||||
* Copyright 2008 Andrew Lunn <andrew@lunn.ch>
|
||||
* Copyright 2008 Duane Ellis <openocd@duaneellis.com>
|
||||
* Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
|
||||
* Copyright 2008 Steve Bennett <steveb@workware.net.au>
|
||||
* Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>
|
||||
* Copyright 2009 Zachary T Welch zw@superlucidity.net
|
||||
* Copyright 2009 David Brownell
|
||||
*
|
||||
* The FreeBSD license
|
||||
*
|
||||
@@ -50,6 +53,9 @@
|
||||
#include <pkgconf/jimtcl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef CYG_ADDRWORD intptr_t;
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
@@ -2828,6 +2834,9 @@ void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
|
||||
int i;
|
||||
struct ScriptObj *script = (void*) objPtr->internalRep.ptr;
|
||||
|
||||
if (!script)
|
||||
return;
|
||||
|
||||
script->inUse--;
|
||||
if (script->inUse != 0) return;
|
||||
for (i = 0; i < script->len; i++) {
|
||||
@@ -3232,7 +3241,7 @@ int Jim_CreateProcedure(Jim_Interp *interp, const char *cmdName,
|
||||
Jim_InitHashTable(cmdPtr->staticVars, getJimVariablesHashTableType(),
|
||||
interp);
|
||||
for (i = 0; i < len; i++) {
|
||||
Jim_Obj *objPtr, *initObjPtr, *nameObjPtr;
|
||||
Jim_Obj *objPtr=NULL, *initObjPtr=NULL, *nameObjPtr=NULL;
|
||||
Jim_Var *varPtr;
|
||||
int subLen;
|
||||
|
||||
@@ -4748,7 +4757,7 @@ const char *Jim_GetSharedString(Jim_Interp *interp, const char *str)
|
||||
Jim_AddHashEntry(&interp->sharedStrings, strCopy, (void*)1);
|
||||
return strCopy;
|
||||
} else {
|
||||
long refCount = (long) he->val;
|
||||
intptr_t refCount = (intptr_t) he->val;
|
||||
|
||||
refCount++;
|
||||
he->val = (void*) refCount;
|
||||
@@ -4758,13 +4767,13 @@ const char *Jim_GetSharedString(Jim_Interp *interp, const char *str)
|
||||
|
||||
void Jim_ReleaseSharedString(Jim_Interp *interp, const char *str)
|
||||
{
|
||||
long refCount;
|
||||
intptr_t refCount;
|
||||
Jim_HashEntry *he = Jim_FindHashEntry(&interp->sharedStrings, str);
|
||||
|
||||
if (he == NULL)
|
||||
Jim_Panic(interp,"Jim_ReleaseSharedString called with "
|
||||
"unknown shared string '%s'", str);
|
||||
refCount = (long) he->val;
|
||||
refCount = (intptr_t) he->val;
|
||||
refCount--;
|
||||
if (refCount == 0) {
|
||||
Jim_DeleteHashEntry(&interp->sharedStrings, str);
|
||||
@@ -7736,7 +7745,7 @@ Jim_Obj *Jim_ScanString(Jim_Interp *interp, Jim_Obj *strObjPtr,
|
||||
int scanned = 1;
|
||||
const char *str = Jim_GetString(strObjPtr, 0);
|
||||
Jim_Obj *resultList = 0;
|
||||
Jim_Obj **resultVec;
|
||||
Jim_Obj **resultVec =NULL;
|
||||
int resultc;
|
||||
Jim_Obj *emptyStr = 0;
|
||||
ScanFmtStringObj *fmtObj;
|
||||
@@ -8820,9 +8829,9 @@ int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc,
|
||||
}
|
||||
|
||||
for (i = 0; i < num_args; i++) {
|
||||
Jim_Obj *argObjPtr;
|
||||
Jim_Obj *nameObjPtr;
|
||||
Jim_Obj *valueObjPtr;
|
||||
Jim_Obj *argObjPtr=NULL;
|
||||
Jim_Obj *nameObjPtr=NULL;
|
||||
Jim_Obj *valueObjPtr=NULL;
|
||||
|
||||
Jim_ListIndex(interp, cmd->argListObjPtr, i, &argObjPtr, JIM_NONE);
|
||||
if (i + 1 >= cmd->arityMin) {
|
||||
@@ -8846,7 +8855,7 @@ int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc,
|
||||
}
|
||||
/* Set optional arguments */
|
||||
if (cmd->arityMax == -1) {
|
||||
Jim_Obj *listObjPtr, *objPtr;
|
||||
Jim_Obj *listObjPtr=NULL, *objPtr=NULL;
|
||||
|
||||
i++;
|
||||
listObjPtr = Jim_NewListObj(interp, argv + i, argc-i);
|
||||
@@ -9418,7 +9427,7 @@ static Jim_Obj *JimCommandsList(Jim_Interp *interp, Jim_Obj *patternObjPtr)
|
||||
Jim_HashEntry *he;
|
||||
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
|
||||
const char *pattern;
|
||||
int patternLen;
|
||||
int patternLen=0;
|
||||
|
||||
pattern = patternObjPtr ? Jim_GetString(patternObjPtr, &patternLen) : NULL;
|
||||
htiter = Jim_GetHashTableIterator(&interp->commands);
|
||||
@@ -9444,7 +9453,7 @@ static Jim_Obj *JimVariablesList(Jim_Interp *interp, Jim_Obj *patternObjPtr,
|
||||
Jim_HashEntry *he;
|
||||
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
|
||||
const char *pattern;
|
||||
int patternLen;
|
||||
int patternLen=0;
|
||||
|
||||
pattern = patternObjPtr ? Jim_GetString(patternObjPtr, &patternLen) : NULL;
|
||||
if (mode == JIM_VARLIST_GLOBALS) {
|
||||
@@ -9813,7 +9822,7 @@ static int Jim_WhileCoreCommand(Jim_Interp *interp, int argc,
|
||||
exprLen = expr->len;
|
||||
|
||||
if (exprLen == 1) {
|
||||
jim_wide wideValue;
|
||||
jim_wide wideValue=0;
|
||||
|
||||
if (expr->opcode[0] == JIM_EXPROP_VARIABLE) {
|
||||
varAObjPtr = expr->obj[0];
|
||||
@@ -9853,7 +9862,7 @@ static int Jim_WhileCoreCommand(Jim_Interp *interp, int argc,
|
||||
if (varAObjPtr)
|
||||
Jim_DecrRefCount(interp, varAObjPtr);
|
||||
} else if (exprLen == 3) {
|
||||
jim_wide wideValueA, wideValueB, cmpRes = 0;
|
||||
jim_wide wideValueA, wideValueB=0, cmpRes = 0;
|
||||
int cmpType = expr->opcode[2];
|
||||
|
||||
varAObjPtr = expr->obj[0];
|
||||
@@ -9980,7 +9989,7 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc,
|
||||
{
|
||||
ScriptObj *initScript, *incrScript;
|
||||
ExprByteCode *expr;
|
||||
jim_wide start, stop, currentVal;
|
||||
jim_wide start, stop=0, currentVal;
|
||||
unsigned jim_wide procEpoch = interp->procEpoch;
|
||||
Jim_Obj *varNamePtr, *stopVarNamePtr = NULL, *objPtr;
|
||||
int cmpType;
|
||||
@@ -11010,7 +11019,7 @@ static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc,
|
||||
if (argListLen) {
|
||||
const char *str;
|
||||
int len;
|
||||
Jim_Obj *argPtr;
|
||||
Jim_Obj *argPtr=NULL;
|
||||
|
||||
/* Check for 'args' and adjust arityMin and arityMax if necessary */
|
||||
Jim_ListIndex(interp, argv[2], argListLen-1, &argPtr, JIM_NONE);
|
||||
@@ -11129,7 +11138,7 @@ static Jim_Obj *JimStringMap(Jim_Interp *interp, Jim_Obj *mapListObjPtr,
|
||||
value = Jim_Alloc(sizeof(Jim_Obj*)*numMaps);
|
||||
resultObjPtr = Jim_NewStringObj(interp, "", 0);
|
||||
for (i = 0; i < numMaps; i++) {
|
||||
Jim_Obj *eleObjPtr;
|
||||
Jim_Obj *eleObjPtr=NULL;
|
||||
|
||||
Jim_ListIndex(interp, mapListObjPtr, i*2, &eleObjPtr, JIM_NONE);
|
||||
key[i] = Jim_GetString(eleObjPtr, &keyLen[i]);
|
||||
@@ -11852,7 +11861,7 @@ static int Jim_JoinCoreCommand(Jim_Interp *interp, int argc,
|
||||
resObjPtr = Jim_NewStringObj(interp, NULL, 0);
|
||||
/* Split */
|
||||
for (i = 0; i < listLen; i++) {
|
||||
Jim_Obj *objPtr;
|
||||
Jim_Obj *objPtr=NULL;
|
||||
|
||||
Jim_ListIndex(interp, argv[1], i, &objPtr, JIM_NONE);
|
||||
Jim_AppendObj(interp, resObjPtr, objPtr);
|
||||
@@ -12116,7 +12125,7 @@ static int Jim_RangeCoreCommand(Jim_Interp *interp, int argc,
|
||||
static int Jim_RandCoreCommand(Jim_Interp *interp, int argc,
|
||||
Jim_Obj *const *argv)
|
||||
{
|
||||
jim_wide min = 0, max, len, maxMul;
|
||||
jim_wide min = 0, max =0, len, maxMul;
|
||||
|
||||
if (argc < 1 || argc > 3) {
|
||||
Jim_WrongNumArgs(interp, 1, argv, "?min? max");
|
||||
@@ -12308,7 +12317,7 @@ void Jim_PrintErrorMessage(Jim_Interp *interp)
|
||||
Jim_GetString(interp->result, NULL));
|
||||
Jim_ListLength(interp, interp->stackTrace, &len);
|
||||
for (i = len-3; i >= 0; i-= 3) {
|
||||
Jim_Obj *objPtr;
|
||||
Jim_Obj *objPtr=NULL;
|
||||
const char *proc, *file, *line;
|
||||
|
||||
Jim_ListIndex(interp, interp->stackTrace, i, &objPtr, JIM_NONE);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
|
||||
* Copyright 2005 Clemens Hintze <c.hintze@gmx.net>
|
||||
* Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>
|
||||
* Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
|
||||
* Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
|
||||
* Copyright 2008 Andrew Lunn <andrew@lunn.ch>
|
||||
* Copyright 2008 Duane Ellis <openocd@duaneellis.com>
|
||||
* Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
|
||||
@@ -87,7 +87,7 @@ extern "C" {
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* Long Long type and related issues */
|
||||
#ifdef HAVE_LONG_LONG_INT
|
||||
#if !defined(__ECOS) && defined(HAVE_LONG_LONG_INT)
|
||||
# ifdef _MSC_VER /* MSC compiler */
|
||||
# define jim_wide _int64
|
||||
# ifndef LLONG_MAX
|
||||
@@ -119,8 +119,8 @@ extern "C" {
|
||||
* LIBC specific fixes
|
||||
* ---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef HAVE_LONG_LONG_INT
|
||||
# if defined(_MSC_VER) || defined(__MSVCRT__)
|
||||
#if !defined(__ECOS) && defined(HAVE_LONG_LONG_INT)
|
||||
# if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__MINGW32__)
|
||||
# define JIM_WIDE_MODIFIER "I64d"
|
||||
# else
|
||||
# define JIM_WIDE_MODIFIER "lld"
|
||||
|
||||
102
src/helper/log.c
102
src/helper/log.c
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
@@ -64,6 +64,95 @@ static char *log_strings[5] =
|
||||
|
||||
static int count = 0;
|
||||
|
||||
|
||||
static struct store_log_forward * log_head = NULL;
|
||||
static int log_forward_count = 0;
|
||||
|
||||
struct store_log_forward
|
||||
{
|
||||
struct store_log_forward * next;
|
||||
const char * file;
|
||||
int line;
|
||||
const char * function;
|
||||
const char * string;
|
||||
};
|
||||
|
||||
/* either forward the log to the listeners or store it for possible forwarding later */
|
||||
static void log_forward(const char *file, int line, const char *function, const char *string)
|
||||
{
|
||||
if (log_forward_count==0)
|
||||
{
|
||||
log_callback_t *cb, *next;
|
||||
cb = log_callbacks;
|
||||
/* DANGER!!!! the log callback can remove itself!!!! */
|
||||
while (cb)
|
||||
{
|
||||
next = cb->next;
|
||||
cb->fn(cb->priv, file, line, function, string);
|
||||
cb = next;
|
||||
}
|
||||
} else
|
||||
{
|
||||
struct store_log_forward *log = malloc(sizeof (struct store_log_forward));
|
||||
log->file = strdup(file);
|
||||
log->line = line;
|
||||
log->function = strdup(function);
|
||||
log->string = strdup(string);
|
||||
log->next = NULL;
|
||||
if (log_head==NULL)
|
||||
log_head = log;
|
||||
else
|
||||
{
|
||||
/* append to tail */
|
||||
struct store_log_forward * t;
|
||||
t = log_head;
|
||||
while (t->next!=NULL)
|
||||
{
|
||||
t = t->next;
|
||||
}
|
||||
t->next = log;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void log_try(void)
|
||||
{
|
||||
log_forward_count++;
|
||||
}
|
||||
|
||||
void log_catch(void)
|
||||
{
|
||||
assert(log_forward_count>0);
|
||||
log_forward_count--;
|
||||
}
|
||||
|
||||
void log_rethrow(void)
|
||||
{
|
||||
log_catch();
|
||||
if (log_forward_count==0)
|
||||
{
|
||||
struct store_log_forward *log;
|
||||
|
||||
log = log_head;
|
||||
while (log != NULL)
|
||||
{
|
||||
log_forward(log->file, log->line, log->function, log->string);
|
||||
|
||||
struct store_log_forward *t=log;
|
||||
log = log->next;
|
||||
|
||||
free((void *)t->file);
|
||||
free((void *)t->function);
|
||||
free((void *)t->string);
|
||||
free(t);
|
||||
|
||||
}
|
||||
|
||||
log_head = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* The log_puts() serves to somewhat different goals:
|
||||
*
|
||||
* - logging
|
||||
@@ -131,18 +220,11 @@ static void log_puts(enum log_levels level, const char *file, int line, const ch
|
||||
/* Never forward LOG_LVL_DEBUG, too verbose and they can be found in the log if need be */
|
||||
if (level <= LOG_LVL_INFO)
|
||||
{
|
||||
log_callback_t *cb, *next;
|
||||
cb = log_callbacks;
|
||||
/* DANGER!!!! the log callback can remove itself!!!! */
|
||||
while (cb)
|
||||
{
|
||||
next = cb->next;
|
||||
cb->fn(cb->priv, file, line, function, string);
|
||||
cb = next;
|
||||
}
|
||||
log_forward(file, line, function, string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
|
||||
{
|
||||
char *string;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
@@ -28,6 +28,15 @@
|
||||
|
||||
#include "command.h"
|
||||
|
||||
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
|
||||
* used for __attribute__((format( ... ))), with GCC v4.4 or later
|
||||
*/
|
||||
#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))
|
||||
#define PRINTF_ATTRIBUTE_FORMAT gnu_printf
|
||||
#else
|
||||
#define PRINTF_ATTRIBUTE_FORMAT printf
|
||||
#endif
|
||||
|
||||
/* logging priorities
|
||||
* LOG_LVL_SILENT - turn off all output. In lieu of try + catch this can be used as a
|
||||
* feeble ersatz.
|
||||
@@ -52,10 +61,10 @@ enum log_levels
|
||||
|
||||
extern void log_printf(enum log_levels level, const char *file, int line,
|
||||
const char *function, const char *format, ...)
|
||||
__attribute__ ((format (printf, 5, 6)));
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6)));
|
||||
extern void log_printf_lf(enum log_levels level, const char *file, int line,
|
||||
const char *function, const char *format, ...)
|
||||
__attribute__ ((format (printf, 5, 6)));
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6)));
|
||||
extern int log_register_commands(struct command_context_s *cmd_ctx);
|
||||
extern int log_init(struct command_context_s *cmd_ctx);
|
||||
extern int set_log_output(struct command_context_s *cmd_ctx, FILE *output);
|
||||
@@ -64,6 +73,15 @@ extern void kept_alive(void);
|
||||
extern void alive_sleep(int ms);
|
||||
extern void busy_sleep(int ms);
|
||||
|
||||
|
||||
/* log entries can be paused and replayed roughly according to the try/catch/rethrow
|
||||
* concepts in C++
|
||||
*/
|
||||
void log_try(void);
|
||||
void log_catch(void);
|
||||
void log_rethrow(void);
|
||||
|
||||
|
||||
typedef void (*log_callback_fn)(void *priv, const char *file, int line,
|
||||
const char *function, const char *string);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -38,7 +38,7 @@ static struct option long_options[] =
|
||||
{"help", no_argument, &help_flag, 1},
|
||||
{"version", no_argument, &version_flag, 1},
|
||||
{"debug", optional_argument, 0, 'd'},
|
||||
{"file", required_argument, 0, 'f'},
|
||||
{"file", required_argument, 0, 'f'},
|
||||
{"search", required_argument, 0, 's'},
|
||||
{"log_output", required_argument, 0, 'l'},
|
||||
{"command", required_argument, 0, 'c'},
|
||||
@@ -53,7 +53,7 @@ int configuration_output_handler(struct command_context_s *context, const char*
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int add_default_dirs(void)
|
||||
static void add_default_dirs(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* Add the parent of the directory where openocd.exe resides to the
|
||||
@@ -106,7 +106,6 @@ int add_default_dirs(void)
|
||||
add_script_search_dir(PKGDATADIR "/site");
|
||||
add_script_search_dir(PKGDATADIR "/scripts");
|
||||
#endif
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[])
|
||||
@@ -196,5 +195,10 @@ int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[]
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* paths specified on the command line take precedence over these
|
||||
* built-in paths
|
||||
*/
|
||||
add_default_dirs();
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
@@ -169,7 +169,7 @@ int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct time
|
||||
/* build an array of handles for non-sockets */
|
||||
for (i = 0; i < max_fd; i++) {
|
||||
if (SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) || SAFE_FD_ISSET(i, efds)) {
|
||||
long handle = _get_osfhandle(i);
|
||||
intptr_t handle = (intptr_t) _get_osfhandle(i);
|
||||
handles[n_handles] = (HANDLE)handle;
|
||||
if (handles[n_handles] == INVALID_HANDLE_VALUE) {
|
||||
/* socket */
|
||||
@@ -244,7 +244,7 @@ int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct time
|
||||
if (WAIT_OBJECT_0 == WaitForSingleObject(handles[i], 0)) {
|
||||
if (SAFE_FD_ISSET(handle_slot_to_fd[i], rfds)) {
|
||||
DWORD dwBytes;
|
||||
long handle = _get_osfhandle(handle_slot_to_fd[i]);
|
||||
intptr_t handle = (intptr_t) _get_osfhandle(handle_slot_to_fd[i]);
|
||||
|
||||
if (PeekNamedPipe((HANDLE)handle, NULL, 0, NULL, &dwBytes, NULL))
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
|
||||
@@ -24,16 +24,16 @@ proc get_help_text {} {
|
||||
|
||||
# Show flash in human readable form
|
||||
# This is an example of a human readable form of a low level fn
|
||||
proc flash_banks {} {
|
||||
set i 0
|
||||
proc flash_banks {} {
|
||||
set i 0
|
||||
set result ""
|
||||
foreach {a} [ocd_flash_banks] {
|
||||
if {$i > 0} {
|
||||
set result "$result\n"
|
||||
}
|
||||
set result [format "$result#%d: %s at 0x%08x, size 0x%08x, buswidth %d, chipwidth %d" $i $a(name) $a(base) $a(size) $a(bus_width) $a(chip_width)]
|
||||
set i [expr $i+1]
|
||||
}
|
||||
set i [expr $i+1]
|
||||
}
|
||||
return $result
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ proc help {args} {
|
||||
set n 0
|
||||
while 1 {
|
||||
if {$n > [string length $h]} {break}
|
||||
|
||||
|
||||
set next_a [expr $n+$w]
|
||||
if {[string length $h]>$n+$w} {
|
||||
set xxxx [string range $h $n [expr $n+$w]]
|
||||
@@ -67,8 +67,8 @@ proc help {args} {
|
||||
set next_a [expr $lastpos+$n+1]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
puts [format "%-25s %s" $cmdname [string range $h $n [expr $next_a-1]] ]
|
||||
set cmdname ""
|
||||
set n [expr $next_a]
|
||||
@@ -128,22 +128,53 @@ add_help_text script "<filename> - filename of OpenOCD script (tcl) to run"
|
||||
# Handle GDB 'R' packet. Can be overriden by configuration script,
|
||||
# but it's not something one would expect target scripts to do
|
||||
# normally
|
||||
proc ocd_gdb_restart {target_num} {
|
||||
proc ocd_gdb_restart {target_id} {
|
||||
# Fix!!! we're resetting all targets here! Really we should reset only
|
||||
# one target
|
||||
reset halt
|
||||
}
|
||||
|
||||
# If RCLK is not supported, use fallback_speed_khz
|
||||
proc jtag_rclk {fallback_speed_khz} {
|
||||
if {[catch {jtag_khz 0}]!=0} {
|
||||
jtag_khz $fallback_speed_khz
|
||||
|
||||
# This reset logic may be overridden by board/target/... scripts as needed
|
||||
# to provide a reset that, if possible, is close to a power-up reset.
|
||||
#
|
||||
# Exit requirements include: (a) JTAG must be working, (b) the scan
|
||||
# chain was validated with "jtag arp_init" (or equivalent), (c) nothing
|
||||
# stays in reset. No TAP-specific scans were performed. It's OK if
|
||||
# some targets haven't been reset yet; they may need TAP-specific scans.
|
||||
#
|
||||
# The "mode" values include: halt, init, run (from "reset" command);
|
||||
# startup (at OpenOCD server startup, when JTAG may not yet work); and
|
||||
# potentially more (for reset types like cold, warm, etc)
|
||||
proc init_reset { mode } {
|
||||
jtag arp_init-reset
|
||||
}
|
||||
|
||||
|
||||
global in_process_reset
|
||||
set in_process_reset 0
|
||||
|
||||
# Catch reset recursion
|
||||
proc ocd_process_reset { MODE } {
|
||||
global in_process_reset
|
||||
if {$in_process_reset} {
|
||||
set in_process_reset 0
|
||||
return -code error "'reset' can not be invoked recursively"
|
||||
}
|
||||
|
||||
set in_process_reset 1
|
||||
set success [expr [catch {ocd_process_reset_inner $MODE} result]==0]
|
||||
set in_process_reset 0
|
||||
|
||||
if {$success} {
|
||||
return $result
|
||||
} else {
|
||||
return -code error $result
|
||||
}
|
||||
}
|
||||
|
||||
add_help_text jtag_rclk "fallback_speed_khz - set JTAG speed to RCLK or use fallback speed"
|
||||
|
||||
proc ocd_process_reset { MODE } {
|
||||
proc ocd_process_reset_inner { MODE } {
|
||||
set targets [target names]
|
||||
|
||||
# If this target must be halted...
|
||||
set halt -1
|
||||
@@ -162,47 +193,63 @@ proc ocd_process_reset { MODE } {
|
||||
|
||||
# Target event handlers *might* change which TAPs are enabled
|
||||
# or disabled, so we fire all of them. But don't issue any
|
||||
# of the "arp_*" commands, which may issue JTAG transactions,
|
||||
# target "arp_*" commands, which may issue JTAG transactions,
|
||||
# unless we know the underlying TAP is active.
|
||||
#
|
||||
# NOTE: ARP == "Advanced Reset Process" ... "advanced" is
|
||||
# relative to a previous restrictive scheme
|
||||
|
||||
foreach t [ target names ] {
|
||||
foreach t $targets {
|
||||
# New event script.
|
||||
$t invoke-event reset-start
|
||||
}
|
||||
|
||||
# Init the tap controller.
|
||||
jtag arp_init-reset
|
||||
# Use TRST or TMS/TCK operations to reset all the tap controllers.
|
||||
# TAP reset events get reported; they might enable some taps.
|
||||
init_reset $MODE
|
||||
|
||||
# Examine all targets on enabled taps.
|
||||
foreach t [ target names ] {
|
||||
foreach t $targets {
|
||||
if {[jtag tapisenabled [$t cget -chain-position]]} {
|
||||
$t arp_examine
|
||||
}
|
||||
}
|
||||
|
||||
# Let the C code know we are asserting reset.
|
||||
foreach t [ target names ] {
|
||||
# Assert SRST, and report the pre/post events.
|
||||
# Note: no target sees SRST before "pre" or after "post".
|
||||
foreach t $targets {
|
||||
$t invoke-event reset-assert-pre
|
||||
}
|
||||
foreach t $targets {
|
||||
# C code needs to know if we expect to 'halt'
|
||||
if {[jtag tapisenabled [$t cget -chain-position]]} {
|
||||
$t arp_reset assert $halt
|
||||
}
|
||||
}
|
||||
foreach t $targets {
|
||||
$t invoke-event reset-assert-post
|
||||
}
|
||||
|
||||
# Now de-assert reset.
|
||||
foreach t [ target names ] {
|
||||
# Now de-assert SRST, and report the pre/post events.
|
||||
# Note: no target sees !SRST before "pre" or after "post".
|
||||
foreach t $targets {
|
||||
$t invoke-event reset-deassert-pre
|
||||
# Again, de-assert code needs to know..
|
||||
}
|
||||
foreach t $targets {
|
||||
# Again, de-assert code needs to know if we 'halt'
|
||||
if {[jtag tapisenabled [$t cget -chain-position]]} {
|
||||
$t arp_reset deassert $halt
|
||||
}
|
||||
}
|
||||
foreach t $targets {
|
||||
$t invoke-event reset-deassert-post
|
||||
}
|
||||
|
||||
# Pass 1 - Now try to halt.
|
||||
# Pass 1 - Now wait for any halt (requested as part of reset
|
||||
# assert/deassert) to happen. Ideally it takes effect without
|
||||
# first executing any instructions.
|
||||
if { $halt } {
|
||||
foreach t [target names] {
|
||||
foreach t $targets {
|
||||
if {[jtag tapisenabled [$t cget -chain-position]] == 0} {
|
||||
continue
|
||||
}
|
||||
@@ -211,13 +258,13 @@ proc ocd_process_reset { MODE } {
|
||||
# the JTAG tap reset signal might be hooked to a slow
|
||||
# resistor/capacitor circuit - and it might take a while
|
||||
# to charge
|
||||
|
||||
|
||||
# Catch, but ignore any errors.
|
||||
catch { $t arp_waitstate halted 1000 }
|
||||
|
||||
|
||||
# Did we succeed?
|
||||
set s [$t curstate]
|
||||
|
||||
|
||||
if { 0 != [string compare $s "halted" ] } {
|
||||
return -error [format "TARGET: %s - Not halted" $t]
|
||||
}
|
||||
@@ -226,7 +273,7 @@ proc ocd_process_reset { MODE } {
|
||||
|
||||
#Pass 2 - if needed "init"
|
||||
if { 0 == [string compare init $MODE] } {
|
||||
foreach t [target names] {
|
||||
foreach t $targets {
|
||||
if {[jtag tapisenabled [$t cget -chain-position]] == 0} {
|
||||
continue
|
||||
}
|
||||
@@ -234,69 +281,20 @@ proc ocd_process_reset { MODE } {
|
||||
set err [catch "$t arp_waitstate halted 5000"]
|
||||
# Did it halt?
|
||||
if { $err == 0 } {
|
||||
$t invoke-event reset-init
|
||||
$t invoke-event reset-init
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach t [ target names ] {
|
||||
foreach t $targets {
|
||||
$t invoke-event reset-end
|
||||
}
|
||||
}
|
||||
|
||||
# stubs for targets scripts that do not have production procedure
|
||||
proc production_info {} {
|
||||
return "Imagine an explanation here..."
|
||||
}
|
||||
add_help_text production_info "Displays information on production procedure for target script. Implement this procedure in target script."
|
||||
#########
|
||||
|
||||
proc production {firmwarefile serialnumber} {
|
||||
puts "Imagine production procedure running successfully. Programmed $firmwarefile with serial number $serialnumber"
|
||||
}
|
||||
|
||||
add_help_text production "<serialnumber> - Runs production procedure. Throws exception if procedure failed. Prints progress messages. Implement this procedure in the target script."
|
||||
|
||||
proc production_test {} {
|
||||
puts "Imagine nifty test procedure having run to completion here."
|
||||
}
|
||||
add_help_text production "Runs test procedure. Throws exception if procedure failed. Prints progress messages. Implement in target script."
|
||||
|
||||
add_help_text cpu "<name> - prints out target options and a comment on CPU which matches name"
|
||||
|
||||
# A list of names of CPU and options required
|
||||
set ocd_cpu_list {
|
||||
{
|
||||
name IXP42x
|
||||
options {xscale -variant IXP42x}
|
||||
comment {IXP42x cpu}
|
||||
}
|
||||
{
|
||||
name arm7
|
||||
options {arm7tdmi -variant arm7tdmi}
|
||||
comment {vanilla ARM7}
|
||||
}
|
||||
}
|
||||
|
||||
# Invoked from Tcl code
|
||||
proc ocd_cpu {args} {
|
||||
set name $args
|
||||
set result ""
|
||||
global ocd_cpu_list
|
||||
foreach a [lsort $ocd_cpu_list] {
|
||||
if {[string length $args]==0||[string first [string toupper $name] [string toupper "$a(name)$a(options)$a(comment)"]]!=-1} {
|
||||
lappend result $a
|
||||
}
|
||||
}
|
||||
return $result
|
||||
}
|
||||
|
||||
proc cpu {args} {
|
||||
# 0123456789012345678901234567890123456789012345678901234567890123456789
|
||||
puts "CPU Options Comment"
|
||||
foreach a [lsort [ocd_cpu $args]] {
|
||||
puts [format "%-20s%-40s%s" $a(name) $a(options) $a(comment)]
|
||||
}
|
||||
}
|
||||
# REVISIT power_restore, power_dropout, srst_deasserted, srst_asserted
|
||||
# are currently neither documented nor supported except on ZY1000.
|
||||
|
||||
proc power_restore {} {
|
||||
puts "Sensed power restore."
|
||||
@@ -319,10 +317,22 @@ proc srst_asserted {} {
|
||||
puts "Sensed nSRST asserted."
|
||||
}
|
||||
|
||||
#########
|
||||
|
||||
# catch any exceptions, capture output and return output
|
||||
proc capture_catch {a} {
|
||||
catch {
|
||||
capture {uplevel $a}
|
||||
} result
|
||||
return $result
|
||||
return $result
|
||||
}
|
||||
|
||||
|
||||
# Executed during "init". Can be overridden
|
||||
# by board/target/... scripts
|
||||
proc jtag_init {} {
|
||||
if {[catch {jtag arp_init} err]!=0} {
|
||||
# try resetting additionally
|
||||
init_reset startup
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -123,13 +123,14 @@ static inline void h_u16_to_be(uint8_t* buf, int val)
|
||||
buf[1] = (uint8_t) (val >> 0);
|
||||
}
|
||||
|
||||
#ifdef __ECOS
|
||||
#if defined(__ECOS)
|
||||
|
||||
/* eCos plain lacks these definition... A series of upstream patches
|
||||
* could probably repair it, but it seems like too much work to be
|
||||
* worth it.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(_STDINT_H)
|
||||
#define PRIx32 "x"
|
||||
#define PRId32 "d"
|
||||
#define SCNx32 "x"
|
||||
@@ -151,8 +152,19 @@ typedef uint64_t uintmax_t;
|
||||
#define INT64_MAX 0x7fffffffffffffffLL
|
||||
#define INT64_MIN (-INT64_MAX - 1LL)
|
||||
#define UINT64_MAX (__CONCAT(INT64_MAX, U) * 2ULL + 1ULL)
|
||||
#endif
|
||||
|
||||
#ifndef LLONG_MAX
|
||||
#define ULLONG_MAX UINT64_C(0xFFFFFFFFFFFFFFFF)
|
||||
#define LLONG_MAX INT64_C(0x7FFFFFFFFFFFFFFF)
|
||||
#define LLONG_MIN ULLONG_MAX
|
||||
#endif
|
||||
|
||||
|
||||
#define ULLONG_MAX 18446744073709551615
|
||||
|
||||
/* C99, eCos is C90 compliant (with bits of C99) */
|
||||
#define isblank(c) ((c) == ' ' || (c) == '\t')
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -374,7 +374,7 @@ static int amt_jtagaccel_execute_queue(void)
|
||||
break;
|
||||
case JTAG_SLEEP:
|
||||
#ifdef _DEBUG_JTAG_IO_
|
||||
LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
|
||||
LOG_DEBUG("sleep %" PRIi32, cmd->cmd.sleep->us);
|
||||
#endif
|
||||
jtag_sleep(cmd->cmd.sleep->us);
|
||||
break;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@@ -46,12 +46,12 @@ bitbang_interface_t *bitbang_interface;
|
||||
* Set this to 1 and str912 reset halt will fail.
|
||||
*
|
||||
* If someone can submit a patch with an explanation it will be greatly
|
||||
* appreciated, but as far as I can tell (ØH) DCLK is generated upon
|
||||
* appreciated, but as far as I can tell (ØH) DCLK is generated upon
|
||||
* clk = 0 in TAP_IDLE. Good luck deducing that from the ARM documentation!
|
||||
* The ARM documentation uses the term "DCLK is asserted while in the TAP_IDLE
|
||||
* state". With hardware there is no such thing as *while* in a state. There
|
||||
* are only edges. So clk => 0 is in fact a very subtle state transition that
|
||||
* happens *while* in the TAP_IDLE state. "#&¤"#¤&"#&"#&
|
||||
* happens *while* in the TAP_IDLE state. "#&¤"#¤&"#&"#&
|
||||
*
|
||||
* For "reset halt" the last thing that happens before srst is asserted
|
||||
* is that the breakpoint is set up. If DCLK is not wiggled one last
|
||||
@@ -308,7 +308,7 @@ int bitbang_execute_queue(void)
|
||||
break;
|
||||
case JTAG_SLEEP:
|
||||
#ifdef _DEBUG_JTAG_IO_
|
||||
LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
|
||||
LOG_DEBUG("sleep %" PRIi32, cmd->cmd.sleep->us);
|
||||
#endif
|
||||
jtag_sleep(cmd->cmd.sleep->us);
|
||||
break;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
|
||||
@@ -184,36 +184,37 @@ int jtag_build_buffer(const scan_command_t *cmd, uint8_t **buffer)
|
||||
|
||||
bit_count = 0;
|
||||
|
||||
#ifdef _DEBUG_JTAG_IO_
|
||||
LOG_DEBUG("%s num_fields: %i", cmd->ir_scan ? "IRSCAN" : "DRSCAN", cmd->num_fields);
|
||||
#endif
|
||||
DEBUG_JTAG_IO("%s num_fields: %i",
|
||||
cmd->ir_scan ? "IRSCAN" : "DRSCAN",
|
||||
cmd->num_fields);
|
||||
|
||||
for (i = 0; i < cmd->num_fields; i++)
|
||||
{
|
||||
if (cmd->fields[i].out_value)
|
||||
{
|
||||
#ifdef _DEBUG_JTAG_IO_
|
||||
char* char_buf = buf_to_str(cmd->fields[i].out_value, (cmd->fields[i].num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : cmd->fields[i].num_bits, 16);
|
||||
#endif
|
||||
buf_set_buf(cmd->fields[i].out_value, 0, *buffer, bit_count, cmd->fields[i].num_bits);
|
||||
#ifdef _DEBUG_JTAG_IO_
|
||||
LOG_DEBUG("fields[%i].out_value[%i]: 0x%s", i, cmd->fields[i].num_bits, char_buf);
|
||||
char *char_buf = buf_to_str(cmd->fields[i].out_value,
|
||||
(cmd->fields[i].num_bits > DEBUG_JTAG_IOZ)
|
||||
? DEBUG_JTAG_IOZ
|
||||
: cmd->fields[i].num_bits, 16);
|
||||
|
||||
LOG_DEBUG("fields[%i].out_value[%i]: 0x%s", i,
|
||||
cmd->fields[i].num_bits, char_buf);
|
||||
free(char_buf);
|
||||
#endif
|
||||
buf_set_buf(cmd->fields[i].out_value, 0, *buffer,
|
||||
bit_count, cmd->fields[i].num_bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _DEBUG_JTAG_IO_
|
||||
LOG_DEBUG("fields[%i].out_value[%i]: NULL", i, cmd->fields[i].num_bits);
|
||||
#endif
|
||||
DEBUG_JTAG_IO("fields[%i].out_value[%i]: NULL",
|
||||
i, cmd->fields[i].num_bits);
|
||||
}
|
||||
|
||||
bit_count += cmd->fields[i].num_bits;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_JTAG_IO_
|
||||
//LOG_DEBUG("bit_count totalling: %i", bit_count);
|
||||
#endif
|
||||
//DEBUG_JTAG_IO("bit_count totalling: %i", bit_count);
|
||||
|
||||
return bit_count;
|
||||
}
|
||||
@@ -238,8 +239,13 @@ int jtag_read_buffer(uint8_t *buffer, const scan_command_t *cmd)
|
||||
uint8_t *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits);
|
||||
|
||||
#ifdef _DEBUG_JTAG_IO_
|
||||
char *char_buf = buf_to_str(captured, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16);
|
||||
LOG_DEBUG("fields[%i].in_value[%i]: 0x%s", i, num_bits, char_buf);
|
||||
char *char_buf = buf_to_str(captured,
|
||||
(num_bits > DEBUG_JTAG_IOZ)
|
||||
? DEBUG_JTAG_IOZ
|
||||
: num_bits, 16);
|
||||
|
||||
LOG_DEBUG("fields[%i].in_value[%i]: 0x%s",
|
||||
i, num_bits, char_buf);
|
||||
free(char_buf);
|
||||
#endif
|
||||
|
||||
|
||||
922
src/jtag/core.c
922
src/jtag/core.c
File diff suppressed because it is too large
Load Diff
@@ -489,6 +489,11 @@ void interface_jtag_add_callback4(jtag_callback_t callback, jtag_callback_data_t
|
||||
|
||||
int interface_jtag_execute_queue(void)
|
||||
{
|
||||
static int reentry = 0;
|
||||
|
||||
assert(reentry==0);
|
||||
reentry++;
|
||||
|
||||
int retval = default_interface_jtag_execute_queue();
|
||||
if (retval == ERROR_OK)
|
||||
{
|
||||
@@ -504,6 +509,8 @@ int interface_jtag_execute_queue(void)
|
||||
jtag_command_queue_reset();
|
||||
jtag_callback_queue_reset();
|
||||
|
||||
reentry--;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Øyvind Harboe *
|
||||
* Copyright (C) 2008 by Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
|
||||
1248
src/jtag/ft2232.c
1248
src/jtag/ft2232.c
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2009 SoftPLC Corporation *
|
||||
@@ -73,20 +73,23 @@ tap_state_t tap_get_end_state()
|
||||
|
||||
int tap_move_ndx(tap_state_t astate)
|
||||
{
|
||||
/* given a stable state, return the index into the tms_seqs[] array within tap_get_tms_path() */
|
||||
/* given a stable state, return the index into the tms_seqs[]
|
||||
* array within tap_get_tms_path()
|
||||
*/
|
||||
|
||||
int ndx;
|
||||
|
||||
switch (astate)
|
||||
{
|
||||
case TAP_RESET: ndx = 0; break;
|
||||
case TAP_IDLE: ndx = 1; break;
|
||||
case TAP_DRSHIFT: ndx = 2; break;
|
||||
case TAP_DRPAUSE: ndx = 3; break;
|
||||
case TAP_IDLE: ndx = 1; break;
|
||||
case TAP_IRSHIFT: ndx = 4; break;
|
||||
case TAP_IRPAUSE: ndx = 5; break;
|
||||
default:
|
||||
LOG_ERROR("fatal: unstable state \"%s\" used in tap_move_ndx()", tap_state_name(astate));
|
||||
LOG_ERROR("FATAL: unstable state \"%s\" in tap_move_ndx()",
|
||||
tap_state_name(astate));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -95,12 +98,7 @@ int tap_move_ndx(tap_state_t astate)
|
||||
|
||||
|
||||
/* tap_move[i][j]: tap movement command to go from state i to state j
|
||||
* 0: Test-Logic-Reset
|
||||
* 1: Run-Test/Idle
|
||||
* 2: Shift-DR
|
||||
* 3: Pause-DR
|
||||
* 4: Shift-IR
|
||||
* 5: Pause-IR
|
||||
* encodings of i and j are what tap_move_ndx() reports.
|
||||
*
|
||||
* DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code
|
||||
*/
|
||||
@@ -108,7 +106,6 @@ struct tms_sequences
|
||||
{
|
||||
uint8_t bits;
|
||||
uint8_t bit_count;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -133,13 +130,10 @@ static const struct tms_sequences old_tms_seqs[6][6] = /* [from_state_ndx][to_
|
||||
{
|
||||
/* value clocked to TMS to move from one of six stable states to another.
|
||||
* N.B. OOCD clocks TMS from LSB first, so read these right-to-left.
|
||||
* N.B. These values are tightly bound to the table in tap_get_tms_path_len().
|
||||
* N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable.
|
||||
* These extra ones cause no TAP state problem, because we go into reset and stay in reset.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* to state: */
|
||||
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
|
||||
{ B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */
|
||||
@@ -168,24 +162,33 @@ static const struct tms_sequences short_tms_seqs[6][6] = /* [from_state_ndx][t
|
||||
|
||||
state specific comments:
|
||||
------------------------
|
||||
*->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to
|
||||
*->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to
|
||||
work better on ARM9 with ft2232 driver. (Dick)
|
||||
|
||||
RESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing.
|
||||
needed on ARM9 with ft2232 driver. (Dick)
|
||||
(For a total of *THREE* extra clocks in RESET; NOP.)
|
||||
|
||||
RESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing.
|
||||
needed on ARM9 with ft2232 driver. (Dick)
|
||||
(For a total of *TWO* extra clocks in RESET; NOP.)
|
||||
|
||||
RESET->* always adds one or more clocks in the target state,
|
||||
which should be NOPS; except shift states which (as
|
||||
noted above) add those clocks in RESET.
|
||||
|
||||
The X-to-X transitions always add clocks; from *SHIFT, they go
|
||||
via IDLE and thus *DO HAVE SIDE EFFECTS* (capture and update).
|
||||
*/
|
||||
|
||||
/* to state: */
|
||||
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
|
||||
{ B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */
|
||||
{ B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */
|
||||
{ B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */
|
||||
{ B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */
|
||||
{ B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */
|
||||
{ B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1) } /* IRPAUSE */
|
||||
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
|
||||
{ B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */
|
||||
{ B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */
|
||||
{ B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */
|
||||
{ B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */
|
||||
{ B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */
|
||||
{ B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1)} /* IRPAUSE */
|
||||
|
||||
};
|
||||
|
||||
@@ -327,43 +330,54 @@ tap_state_t tap_state_transition(tap_state_t cur_state, bool tms)
|
||||
return new_state;
|
||||
}
|
||||
|
||||
const char* tap_state_name(tap_state_t state)
|
||||
|
||||
/* NOTE: do not change these state names. They're documented,
|
||||
* and we rely on them to match SVF input (except for "RUN/IDLE").
|
||||
*/
|
||||
static const struct name_mapping {
|
||||
enum tap_state symbol;
|
||||
const char *name;
|
||||
} tap_name_mapping[] = {
|
||||
{ TAP_RESET, "RESET", },
|
||||
{ TAP_IDLE, "RUN/IDLE", },
|
||||
{ TAP_DRSELECT, "DRSELECT", },
|
||||
{ TAP_DRCAPTURE,"DRCAPTURE", },
|
||||
{ TAP_DRSHIFT, "DRSHIFT", },
|
||||
{ TAP_DREXIT1, "DREXIT1", },
|
||||
{ TAP_DRPAUSE, "DRPAUSE", },
|
||||
{ TAP_DREXIT2, "DREXIT2", },
|
||||
{ TAP_DRUPDATE, "DRUPDATE", },
|
||||
{ TAP_IRSELECT, "IRSELECT", },
|
||||
{ TAP_IRCAPTURE,"IRCAPTURE", },
|
||||
{ TAP_IRSHIFT, "IRSHIFT", },
|
||||
{ TAP_IREXIT1, "IREXIT1", },
|
||||
{ TAP_IRPAUSE, "IRPAUSE", },
|
||||
{ TAP_IREXIT2, "IREXIT2", },
|
||||
{ TAP_IRUPDATE, "IRUPDATE", },
|
||||
|
||||
/* only for input: accept standard SVF name */
|
||||
{ TAP_IDLE, "IDLE", },
|
||||
};
|
||||
|
||||
const char *tap_state_name(tap_state_t state)
|
||||
{
|
||||
const char* ret;
|
||||
unsigned i;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case TAP_RESET: ret = "RESET"; break;
|
||||
case TAP_IDLE: ret = "RUN/IDLE"; break;
|
||||
case TAP_DRSELECT: ret = "DRSELECT"; break;
|
||||
case TAP_DRCAPTURE: ret = "DRCAPTURE"; break;
|
||||
case TAP_DRSHIFT: ret = "DRSHIFT"; break;
|
||||
case TAP_DREXIT1: ret = "DREXIT1"; break;
|
||||
case TAP_DRPAUSE: ret = "DRPAUSE"; break;
|
||||
case TAP_DREXIT2: ret = "DREXIT2"; break;
|
||||
case TAP_DRUPDATE: ret = "DRUPDATE"; break;
|
||||
case TAP_IRSELECT: ret = "IRSELECT"; break;
|
||||
case TAP_IRCAPTURE: ret = "IRCAPTURE"; break;
|
||||
case TAP_IRSHIFT: ret = "IRSHIFT"; break;
|
||||
case TAP_IREXIT1: ret = "IREXIT1"; break;
|
||||
case TAP_IRPAUSE: ret = "IRPAUSE"; break;
|
||||
case TAP_IREXIT2: ret = "IREXIT2"; break;
|
||||
case TAP_IRUPDATE: ret = "IRUPDATE"; break;
|
||||
default: ret = "???";
|
||||
for (i = 0; i < DIM(tap_name_mapping); i++) {
|
||||
if (tap_name_mapping[i].symbol == state)
|
||||
return tap_name_mapping[i].name;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return "???";
|
||||
}
|
||||
|
||||
tap_state_t tap_state_by_name(const char *name)
|
||||
{
|
||||
tap_state_t x;
|
||||
unsigned i;
|
||||
|
||||
for (x = 0 ; x < TAP_NUM_STATES ; x++) {
|
||||
for (i = 0; i < DIM(tap_name_mapping); i++) {
|
||||
/* be nice to the human */
|
||||
if (0 == strcasecmp(name, tap_state_name(x))) {
|
||||
return x;
|
||||
}
|
||||
if (strcasecmp(name, tap_name_mapping[i].name) == 0)
|
||||
return tap_name_mapping[i].symbol;
|
||||
}
|
||||
/* not found */
|
||||
return TAP_INVALID;
|
||||
|
||||
@@ -160,9 +160,6 @@ bool tap_is_state_stable(tap_state_t astate);
|
||||
*/
|
||||
tap_state_t tap_state_transition(tap_state_t current_state, bool tms);
|
||||
|
||||
/// Provides user-friendly name lookup of TAP states.
|
||||
tap_state_t tap_state_by_name(const char *name);
|
||||
|
||||
/// Allow switching between old and new TMS tables. @see tap_get_tms_path
|
||||
void tap_use_new_tms_table(bool use_new);
|
||||
/// @returns True if new TMS table is active; false otherwise.
|
||||
|
||||
@@ -314,7 +314,7 @@ static int jlink_init(void)
|
||||
LOG_ERROR("Cannot find jlink Interface! Please check connection and permissions.");
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The next three instructions were added after discovering a problem while using an oscilloscope. For the V8
|
||||
* SAM-ICE dongle (and likely other j-link device variants), the reset line to the target microprocessor was found to
|
||||
@@ -324,7 +324,7 @@ static int jlink_init(void)
|
||||
* following a new USB session. Keeping the processor in reset during the first read collecting version information
|
||||
* seems to prevent errant "J-Link command EMU_CMD_VERSION failed" issues.
|
||||
*/
|
||||
|
||||
|
||||
LOG_INFO("J-Link initialization started / target CPU reset initiated");
|
||||
jlink_simple_command(EMU_CMD_HW_TRST0);
|
||||
jlink_simple_command(EMU_CMD_HW_RESET0);
|
||||
@@ -499,12 +499,10 @@ static void jlink_reset(int trst, int srst)
|
||||
{
|
||||
jlink_simple_command(EMU_CMD_HW_TRST0);
|
||||
}
|
||||
|
||||
if (trst == 0)
|
||||
{
|
||||
jlink_simple_command(EMU_CMD_HW_TRST1);
|
||||
jtag_sleep(5000);
|
||||
jlink_end_state(TAP_RESET);
|
||||
jlink_state_move();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,7 +881,7 @@ static jlink_jtag_t* jlink_usb_open()
|
||||
|
||||
if (result->usb_handle)
|
||||
{
|
||||
|
||||
|
||||
/* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS AREA!!!!!!!!!!!
|
||||
* The behavior of libusb is not completely consistent across Windows, Linux, and Mac OS X platforms. The actions taken
|
||||
* in the following compiler conditionals may not agree with published documentation for libusb, but were found
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user