Compare commits

...

1211 Commits

Author SHA1 Message Date
David Brownell
56e74908d1 Label builds as OpenOCD v0.4.0
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-21 12:20:13 -08:00
David Brownell
4aa0a4d811 User's Guide mentions OS-specific installation
Specifically the Linux issue of needing "udev" rules, and MS-Windows
needing driver configuration.

Also, update the existing udev note to use the correct name of that
rules file in the source tree.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-21 09:29:24 -08:00
David Brownell
bb4cb7935e arm920t line length cleanup
The recent patch to fixbreakpoints and dcache handling added
a bunch of overlong lines (80+ chars) ... shrink them, and do
the same to a few lines which were already overlong.

Also add a few FIXME comments to nudge (a) replacement of some
magic numbers with opcode macros, which will be much better at
showing what's actually going on, and (b) correct return codes.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-20 20:47:38 -08:00
David Brownell
57d5673dea CSB337 board cleanup (quasi-regression)
Get rid of new nasty warning:

NOTE! Severe performance degradation without fast memory access enabled...

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-20 20:47:38 -08:00
David Brownell
d2a2c14d20 FreeBSD buildfix
Fix an unused variable warning seen when building the parport driver
under FreeBSD.

Using information from Xiaofan Chen <xiaofanc@gmail.com>

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-20 11:11:43 -08:00
Marc Pignat
3f30563c88 atm920t : fix breakpoints and data cache handling
Breakpoints did not work because the data cache was not flushed
properly.

As a bonus add capability to write to memory marked as read only
by the MMU, which allows software breakpoints in such memory
regions.
2010-02-19 08:18:12 +01:00
David Brownell
aa8db989b9 ARM920T scanchain 15 comments/cleanup
For folk who don't know the ARM920 JTAG interface very well, the
two modes of scan chain 15 access to CP15 are confusing.

Make those parts of the ARM920 code less opaque, by:

 - Adding comments referencing the relevant parts of the TRM,
   catching up to similar updates in the User's Guide.

 - Replacing magic numbers in physical access clients with
   symbolic equivalents.

No functional change.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-16 18:50:16 -08:00
Øyvind Harboe
fa1cfc2d4d gpl: fix GPL startup message
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-02-15 22:59:41 +01:00
David Brownell
5869992314 LPC1768.cfg -- partial fixes for bogus reset-init handler
Cortex-M targets don't support ARM instructions.

Leave the NVIC.VTOR setup alone, but comment how the whole
routine looks like one big bug...

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-15 13:39:16 -08:00
Mathias Kuester
52d4ba3467 fix crash with DSP563XX
When a DSP563xx-aware GDB asks OpenOCD for target registers,
the result should be a GDB with register data ... not an
OpenOCD crash.

(Note that mainline GDB doesn't currently support this core,
so for now, this requires a GDB with FreeScale patches.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-14 12:59:10 -08:00
David Brownell
a2ce3a51df NEWS: mention removal of obsolete commands
Removed remaining support for various commands, like advice for
migrating old-style TAP declarations.

The documentation no longer describes them either ... so if users have
been delaying config updates, they may need to consult older releases.

ALL this stuff has been clearly marked as "do not use" for at least a
year now, so anyone still using it hasn't been holding up their end.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-13 20:14:49 -08:00
David Brownell
4c4ec09110 Restore "-dev" version suffix (0.4.0-rc2-dev)
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-13 15:28:05 -08:00
David Brownell
a0a1be5cd6 v4.0-rc2 milestone
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-13 14:47:17 -08:00
Spencer Oliver
f7a6e62776 STR9xpec: issue warning when unlocking device
Issue warning to user when unlocking or writing the option bytes.
The new settings will not take effect until a target reset.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-02-12 10:49:18 +00:00
Spencer Oliver
747a607aef STM32x: issue warning when unlocking device (bug #16)
Issue warning to user when unlocking or writing the option bytes.
The new settings will not take effect until a target reset.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-02-12 10:49:11 +00:00
Øyvind Harboe
d4d4b11a77 arm720t: virt2phys callback added
This is a copy and paste of arm926ejs. Not tested, but
ready for testing at least. There is a good chance that
it will work if the generic armv4_5 fn's are robust enough...

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-02-12 08:39:56 +01:00
Marc Pignat
ff404da155 arm920: add virt2phys fn
Copy of the 926ejs function. I have tested it only using
my rtems application (where virtual address mapping == physical).

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-02-12 08:31:06 +01:00
Viktar Palstsiuk
32188c5004 target library: configuration files for openocd tested with Atmel SAM-ICE V6 JTAG.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-02-11 21:10:51 +01:00
David Brownell
527e073bba User's Guide: "#" in filesystems names is bad
Sometimes MS-Windows users try to use filesystem names which include
the "#" character.  That's generally unwise, since it begins Tcl
comments.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-10 16:42:37 -08:00
Øyvind Harboe
65cc81ddb6 arm11: fix another infinite loop bug
reset init would get stuck in an infinite loop when
e.g. khz was too high. Added timeout. This is a copy
of paste of a number of such bugfixes in the arm11
code.

Arm11 code reviewed for further such infinite loop bugs
and I couldn't find any more. Xing fingers it's the last
one...

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-02-10 22:54:06 +01:00
David Brownell
84ac6bb0d9 User's Guide: clarify jtag_rclk advice
Not all cores and boards support adaptive clocking, so qualify
all advice to use it to depend on core and board support.

It's primarily ARM cores which support this; and many of the
newer ones (like Cortex-M series) don't.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-10 11:27:48 -08:00
Øyvind Harboe
c646b76797 target: add todo in target_write_memory() about alignment
target_write_buffer() does not align "buffer" in host
memory passed to target_write_memory().

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-02-09 21:57:23 +01:00
Spencer Oliver
f899c2aa97 str730.cfg: fix incorrect mem regions
- update str73x mem regions to correct values.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-02-09 14:49:47 +00:00
David Brownell
885a2f5b96 Re-title Developer's Guide
The Doxygen output was previously titled "OpenOCD Reference Manual",
which was quite misleading ... the User's Guide is the reference
manual which folk should consult about how to use the software.

Just rename it to match how it's been discussed previously, and to
bring out its intended audience:  developers of this software.  As a
rule, Doxygen is only for folk who work with the code it documents.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-06 19:19:25 -08:00
David Brownell
6f262b69f4 ADIv5: doxygen
Provide doxygen for many of the public ADIv5 interfaces (i.e. the ones
called from Cortex core support code).

Add FIXMEs (and a TODO) to help resolve implementation issues which
became more apparent when trying to document this code:

 - Error-prone context-sensitivity (queued/nonqueued) in many procedures.

 - Procedures that lie by ignoring errors and wrongly claiming success.

Also, there was no point in a return from dap_ap_select(); it can't fail,
and no caller checks its return status.  Clean that up, make it void.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-06 19:16:21 -08:00
Øyvind Harboe
41d0901115 zy1000: complete zy1000_uart to jim command switch
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-02-05 14:38:26 +01:00
David Brownell
ff5deeeeaa ARMv7-M: make DAP commands verify target is an ARMv7-M
Init the ARMv7-M magic number.  Define predicate verifying it.
Use it to resolve a lurking bug/FIXME:  make sure the ARMv7-M
specific DAP ops reject non-ARMv7-M targets.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-04 14:39:51 -08:00
David Brownell
3ea9e62189 Documentation: mention bug database
Have the User's Guide and BUG handling notes both reference
the fact that we now have a bug database at SourceForge.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-04 11:10:15 -08:00
David Brownell
e380930478 JLink: reference protocol documentation
Segger publishes some documentation on this protocol;
reference it, so future maintainers can know it exists.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-04 10:50:24 -08:00
Spencer Oliver
709f08f17a CMD: duplicate cmd error msg
When registering cmds we report duplicate attempts to register a cmd
as a LOG_ERROR.
Some situations need this, such as when registering dual flash banks.
http://www.mail-archive.com/openocd-development@lists.berlios.de/msg11152.html

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-02-04 10:33:33 +00:00
Ethan Eade
8b049fdba5 scripts: Phytec/LPC2350 config scripts
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-02-04 10:25:44 +01:00
Spencer Oliver
95ed9c4393 JTAG: fix bug when no interface connected
- fix coredump when OpenOCD is started without a jtag interface connected.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-02-03 13:09:24 +00:00
Harald Kipp
18969466c9 AT91R40008/Ethernut 3 configuration
Moved board specific settings from target/at91r40008.cfg to a new
file board/ethernut3.cfg.

Set correct CPUTAPID.  Reset delay increased, see MIC2775 data sheet.
Increased work area size from 16k to 128k.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-02 11:09:53 -08:00
David Brownell
5750e899e0 NOR: User's Guide updates
Remove long-obsolete text about "erase_check" affecting "flash info" output.
Move parts of that text to "protect_check", where it's still relevant; and
update the "flash info" description to mention the issue.

(This is still awkward.  It might be best to make "protect_check" mirror
"erase_check" by dumping what it finds, so "flash info" doesn't dump any
potentially-stale cache info.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-02 10:53:13 -08:00
Edgar Grimberg
cc440ca1d4 tcl/str7x: Reset init unlocks the flash
For STR7x flash, the device cannot be queried for the protect status.
The solution is to remove the protection on reset init. The driver
also initialises the sector protect field to unprotected.

[dbrownell@users.sourceforge.net: line length shrinkage]

Signed-off-by: Edgar Grimberg <edgar.grimberg@zylin.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-02 09:30:33 -08:00
Edgar Grimberg
503f6139c7 flash/str7x: After reset init the flash is unlocked
The default state of the STR7 flash after a reset init is unlocked.
The information in the flash driver now reflects this.

The information about the lock status cannot be read from the
flash chip, so the user is informed that flash info might not
contain accurate information.

[dbrownell@users.sourceforge.net: line length shrinkage]

Signed-off-by: Edgar Grimberg <edgar.grimberg@zylin.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-02-02 09:30:33 -08:00
Nicolas Pitre
3d2d5dcc9c ARM semihosting: fix EOF handling with SYS_READ
The semihosting interface has a strange convention for read/write where
the unused amount of buffer must be returned.  We failed to return the
total buffer size when the local read() call returned 0.

Signed-off-by: Nicolas Pitre <nico@marvell.com>
2010-02-02 00:05:42 -05:00
Edgar Grimberg
bef37ceba2 Test cases ran on v0.4.0-rc1
Test cases ran on v0.4.0-rc1 for a number of targets:
AT91FR40162
LPC2148
SAM7
STR710
STR912

The goal of the testing session was to prove basic functionality of OpenOCD for different targets.

Signed-off-by: Edgar Grimberg <edgar.grimberg@zylin.com>
2010-02-01 15:44:06 +01:00
Øyvind Harboe
91e3268737 gdb: restore behavior from 0.3.1 for srst_asserted and power_restore
srst_asserted and power_restore can now be overriden to do
nothing. By default they will "reset init" the targets and
halt gdb.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-02-01 13:45:09 +01:00
David Brownell
82f2492138 ADIv5: more messaging cleanup, docs
When the TAR cache was explicitly invalidated, don't bother
printing it; the actual hardware status is more informative.

Provide some doxygen for the MEM-AP setup routine.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-31 14:16:53 -08:00
Øyvind Harboe
02731cf78b build: fix problems with "struct stat" not being defined under eCos
Include <sys/stat.h> according to
http://www.opengroup.org/onlinepubs/000095399/functions/stat.html

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-31 15:48:14 +01:00
Øyvind Harboe
f68dff6690 telnet: fix strage blank spaces at beginning of telnet lines
Sometimes we saw two strange blank spaces at the beginning
of the telnet lines.

progress
  ogress
>

This patch fixes this problem:

progress
progress
>

The code changes are *reasonably* clean, but perhaps it could be
made a bit more elegant, but I didn't want to change things after
I finished diagnosis/testing & submitting the patch.

The problem was that logging can send the text and the newline
separately in two different requests and the telnet code would
incorrectly remove the prompt from the end of a line.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-31 15:06:02 +01:00
David Brownell
e11ce3e6b0 Subject: ADIv5: fix more diagnostics
If the MEM-AP cache is invalid, don't display it; just report that
invalidity as an error.  (This bug has been observed with "mdw 0 32"
after just a "reset halt".  Some code is being wrongly bypassed...)

If it's valid, display that cache at DEBUG level, not ERROR.  Also,
don't assume it's an AHB-AP; it could be another flavor of MEM-AP.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-31 00:26:21 -08:00
David Brownell
695666d294 ADIv5 error checking for Tcl commands
Reject invalid AP numbers (256+) as Tcl operation parameters.
Shrink one of the overlong lines.

Add my copyright to the ADIv5 code (multiple contributions).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-30 22:46:00 -08:00
David Brownell
46b6d5bfe6 ARM ADIv5: fix diagnostics for block writes
They were reporting "read" errors, not "write" errors.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-30 18:08:19 -08:00
David Brownell
3d3128a8f5 ADIv5: cleanup, rename swjdp_transaction_endcheck()
Make messages reference "DAP" if they're actually transport-agnostic, or
"JTAG-DP" when they're JTAG-specific.  Saying SWJ-DP is often wrong (on
most Cortex-A8 chips) and is confusing even if correct (since we don't
yet support SWD).

Rename a JTAG-specific routine to jtagdp_transaction_endcheck() to highlight
that it's JTAG-specific, and that identify DAP clients undesirably depending
on JTAG.  (They will all need to change for SWD support.)

Shrink a few overlong lines of code.  Copy a comment from code removed
in a previous patch (for the ARMv7-M "dap baseaddr" command).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-29 14:31:19 -08:00
David Brownell
2248c387f2 ARMv7-M: use command handler for "dap baseaddr".
Make the ARMv7-M DAP code reuse the command handler for "dap baseaddr".
For some reason, this DAP command wasn't converted earlier.

This is a code shrink and simplification; it also removes a needless
transport dependency on JTAG.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-29 14:16:14 -08:00
David Brownell
303b493c22 NOR: cleanup driver decls
Fix goofy struct indents.  Function names *are* their addresses.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-29 13:52:08 -08:00
Alex Austin
cd3017cffa Clang buildfixes
Building with clang took a few very small changes. The change to
helper/log.h is because clang doesn't like an expression where the
result is unused. In helper/system.h, I just defined true and false
since clang doesn't have them builtin.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-29 00:02:12 -08:00
David Brownell
804c0b2ad3 doc clarifications for server flags
The "-f" is a shortcut for "-c" ... and providing any "-c" options
means the "openocd.cfg" file isn't implicitly used.  Both the User's
Guide and the manual page were weak on these points, which has led
to some confusion.

Also update the manual page to include highlights of the search path
mechanism, including the facts that it exists and that "-s" adds to it.
Stop saying only the current directory is involved; the OpenOCD
script library is quite significant.

(Missing: complete manpage coverage of the search path, including a
FILES section listing all components and saying where the script
library is found.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-28 14:03:29 -08:00
David Brownell
5dcf7898f6 ARM: reference DPM defn from v6/v7 arch spec
The term "DPM" is probably not well known ("Device Power Management"?),
so identify its source in the current ARM architecture specification.
It's relevant to ARMv6, ARMv7-A, and ARMv7-R ... but not "M" profiles.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-28 13:58:20 -08:00
Spencer Oliver
75cfda4cd1 ARM semihosting: win32 and cygwin fixes
Cygwin would fail to reopen a previously written file if the mode is
not given.

Simplified converting the open flags and made sure the win32 O_BINARY
bit is set.

Added define for systems that do not support O_BINARY.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-28 21:05:09 +00:00
Spencer Oliver
465a06dfdc ARM semihosting: fix writing to stdout
SYS_FLEN would be called before a write on a descriptor to check its size.
Currently lseek would fail with -1 when given the stdout/stderr descriptor.
Changing to use fstat seems to be the standard way of handling this.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-28 20:21:31 +00:00
David Brownell
3172be80a3 Cortex-M3: report lockup, and recover
ARMv7-M defines a "lockup" state that's entered in certain double
fault sequences which can't be recovered from without external help.
OpenOCD has previously ignored this.

Issue a diagnostic saying the chip has locked up, and force exit
from this state by halting the core.  It's not clear this is the
best way to handle lockup; but there should now be less confusion.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-27 13:47:48 -08:00
David Brownell
d44f1aaeff ARM ADIv5: messaging tweaks
Add space missing after the invalid ACK value.  On init, say
which AP is being used, and don't assume it's an AHP-AP.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-27 13:40:05 -08:00
David Brownell
2b5c444a32 Cortex-A8: debug messaging tweaks
Make that "TODO" message say what needs to be done.
Say what part of examining failed.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-27 13:24:21 -08:00
David Brownell
30365886da various: don't mention wiki
The openfacts.berlios wiki isn't particularly current, and isn't
publicly editable.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-26 18:13:10 -08:00
David Brownell
9e52957efc cygwin buildfix
isspace() parameter must be an integer, else a 'char' gets
used as an array index (sigh).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-26 17:54:49 -08:00
simon qian
33fc60befc SVF: all content between parentheses is one parameter
More SVF fixes:

 * Treat all content between parentheses as part of the same
   parameter; don't (wrongly) treat whitespace as a delimiter.

 * Use isspace() to catch that whitespace; it's not all single
   spaces, newlines etc are also valid.

 * When parsing bitstrings, strip leading whitespace too.

So for example, these are equivalent and should (now) be OK:

  "TDI( 1234 )"
  "TDI( 1 2 3 4 )"
  "TDI(00 12 34 )"
  "TDI(
  	00 12
	34)"

[dbrownell@users.sourceforge.net: comment updates; trivial cleanup]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-25 13:06:46 -08:00
Edgar Grimberg
1dad2ee602 core arm11: Silence logs at level 3 if there is no activity
If the target and openocd are idling, the log should normally
be silent at level 3.  (Given no verbose logging options.)

Signed-off-by: Edgar Grimberg <edgar.grimberg@zylin.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-25 12:19:52 -08:00
simon qian
9ff16575d2 SVF: insert space before '(' and after ')'
See http://forum.sparkfun.com/viewtopic.php?p=90983#90983 for discussion;
basically, the SVF parser wrongly expects "TDI (123)" but the space is
optional and it should accept "TDI(123)" too.

In the same way, "TDI(123)TDO(456)" should work too.

Rather than update the command parsing, this just makes sure the expected
spaces are present.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-23 14:24:10 -08:00
David Brownell
718ee762e7 EmbeddedICE - fix Feroceon/Dragonite message
The breakpoint/watchpoint message was wrong for Feroceon and
Dragonite, which have only one working watchpoint unit.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-22 22:54:39 -08:00
David Brownell
82c3c47825 NEWS updates
Summarize most ARM11 and Cortex-A8 updates as "acting much more
like other ARMs", and mention code sharing.

Clarify a few other points, including support for "reset-assert"
on all ARMs except Cortex-M (which doesn't exactly need it).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-22 22:49:42 -08:00
David Brownell
b7fa16eeac ARM11: fix breakpoints with GDB
This fixes a bug whereby GDB's breakpoints weren't activated.
The root cause is a confused interface to resume().  Fix by
almost ignoring the "handle breakpoints" parameter; it only
seems related to the case of skipping breakpoint-at-PC.

Update a few coments to clarify what's happening.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-22 22:37:15 -08:00
David Brownell
4960c9018f Various doc/comment updates
Doxygen: don't be needlessly verbose; alphabetically sort members
TODO: add random bits; clarify which manuals are referenced
ARM disassembler: mention a few opcodes that still aren't handled

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-21 16:45:00 -08:00
David Brownell
08b0be94b5 User's Guide secton on target hardware setup
Highlight the needs to properly jumper development boards; to
make the OpenOCD configuration match the jumpering; and to have
a usable "reset-init" method when debugging early boot code.

Specific mention of the "ATX Mode" that seems useful on
many i.MX boards, forcing NAND boot.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-21 16:15:41 -08:00
David Brownell
f06148612b ADIv5 header cleanup (+ #defines)
Update the comments about DP registers and some of the bitfields.
Remove inappropriate (and unused) DP_ZERO declaration.

Add some (currently unused) #defines needed for SWD protocol support,
based on previous patches from Andreas Fritiofson and Simon Qian.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-21 13:39:22 -08:00
Øyvind Harboe
98f7c2127b target: print reason why GDB halts
If GDB halts unexpectedly, print reason: srst assert or power
out detected.

If polling fails, then things are a bit trickier. We do not
want to spam telnet or the log with polling failed messages.
Leave that case be w/a comment in a code for now.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-21 16:20:58 +01:00
Edgar Grimberg
dfba7fa949 interface: Changed parport address to LPT1
Changed the parport address to LPT1, since it's the most obvious default value.

Signed-off-by: Edgar Grimberg <edgar.grimberg@zylin.com>
2010-01-21 15:58:59 +01:00
Edgar Grimberg
bc088b302b target: Fixed format problem for mdh
Fixed format problem for mdh. It needs to display 4 chars.

Signed-off-by: Edgar Grimberg <edgar.grimberg@zylin.com>
2010-01-21 15:58:59 +01:00
Øyvind Harboe
1350b6aad0 gdb_server: handle stepi/continue packet while target is running with more grace
Rather than issuing a halt and then stepi/resume, just
wait for target to halt.

Issue a sterner warning via gdb console that any gdb
register changes will be ignored in this case.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-21 15:57:30 +01:00
Øyvind Harboe
60cb5bdd30 ecos: add missing PRId8 definition
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-21 08:11:39 +01:00
Spencer Oliver
dbecb13b24 BUILD: remove cygwin gcc 3.4.4 build warnings
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-20 23:11:25 +00:00
David Brownell
2a0c9b08d7 Cortex-M3 vector_catch testing support
The "cm3-ftest.cfg" can be used to verify that OpenOCD handles
certain faults correctly:

 - Test #1: it ignores faults that it wasn't told to catch
 - Test #2: if vector_catch is told to catch, it catches

The "fault.c" generates ASM code to trigger faults, while the
config script loads and runs pre-compiled code.

This covers most, but not all, of the vector_catch options.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-20 11:07:42 -08:00
David Brownell
22d25e6921 board configs -- unique names for flash chips
Don't give the same names to both flash chips on two OMAP boards.

For OSK, enable DCC downloads (removing a warning).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-20 10:46:53 -08:00
David Brownell
6f2b88448f gdb_server: correctly report flash sector sizes
Report each region of same-size sectors separately, instead of
incorrectly reporting that every sector has the same size.

This is a longstanding bug on NOR flash chips with non-uniform
sector sizes.  It was largely hidden by other bugs in flash
handling.  When some of those were recently fixed, this one was
exposed as a regression on str710.

[oyvind.harboe@zylin.com: update the loop to behave on str7 ]

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-20 10:43:32 -08:00
Michael Grzeschik
d036f17001 tcl/target/at91sam3u4e.cfg: changed case in dependent file
openocd does not start with the target configfile due to the case in the
dependent config file.

Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-20 10:32:53 -08:00
Øyvind Harboe
87cb29dcfe testing: fix str710 test case now builds
Make the test case easily adjustable in size. str710
has very peculiar flash sector layout, nice for testing,
but a larget test_rom.elf is required.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-20 15:12:31 +01:00
Øyvind Harboe
ff976cdb29 arm7/9: add nags upon reset about options to improve performance
arm7_9 fast_memory_access and working area nags added.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-20 14:51:17 +01:00
Spencer Oliver
0c3a4b4d81 ARMV7M: handle bkpt instruction on resume/step
Skip over a bkpt instruction if found on resume/step.
Only software breakpoints known to OpenOCD are currently handled.

So this handles the special case of either a user added bkpt
or library added, eg. semi-hosting support.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-20 09:07:55 +00:00
David Brownell
20d1ef70e8 User's guide: mention lpc2000 checksum issue
Folk almost certainly want to have OpenOCD compute the checksum
when they modify the vector table.  However, that almost guarantees
that "verify_image" will fail.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-20 00:04:17 -08:00
David Brownell
44aaba3d08 gdb_server -- subroutinize memory map logic
Put the memory map logic into its own subroutine.
This will make it a bit easier to package bugfixes,
and simplifies the query packet handling.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-19 23:32:54 -08:00
David Brownell
bf1e9a83c8 gdb_server -- symbol cleanup
Make most methods static; net minor object code shrink.
Likewise various data symbols; no net change.
Shrink some overlong lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-19 23:30:36 -08:00
Andreas Fritiofson
4f310aa0c9 update win32 script search path
The default script search path on Windows is out of date with
the current layout (from installation and documentation), which
makes the standard script library not be found after a normal

	./configure && make && make install

under msys/MinGW. The same should hold true for cygwin native builds
(not verified).

Update search path to ../share/openocd/scripts not ../lib/openocd,
relative to the openocd executable.

Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-19 15:02:15 -08:00
David Brownell
fb4239866c NOR: fix diagnostic
The "NOR: last_addr also needs correction when checking alignment"
patch omitted a necessary update to the key diagnostic; fix.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-19 13:56:33 -08:00
Øyvind Harboe
924bf27596 zy1000: flush jtag buffer before changing speed
It is conceivable that there could be commands in the
queue when a speed change request comes in. Flush the
hw queue before changing speed. Not observed, found by
inspection.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-19 10:58:48 +01:00
Øyvind Harboe
c795b0d8f1 zy1000: print out PCB revision upon boot
Simplify debugging a bit.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-19 10:58:48 +01:00
Øyvind Harboe
cdcb9b0885 flash: add error messages upon incorrect arguments to flash iteration
According to OpenOCD error handling rules the error is
logged at where it occurs(same site where an exception
would have been thrown).

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-19 10:58:48 +01:00
David Brownell
5ab34b28ce vsllink -- add comment
Previous patch deserved *inline* comment, not just
in git revision history.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-18 13:18:33 -08:00
Øyvind Harboe
56d2c86500 commands: allow scan_chain command to be executed during config
Adding taps and then dumping them is quite reasonable thing
to do in a config script.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-18 21:42:34 +01:00
simon qian
0b641dac71 read target voltage first in vsllink
The very first command after init command should be "read target voltage".

This is a tweak for the Old Versaloon firmware.  Without this, in most
most cases, it works.   Under Ubuntu9.04, there is a chance that the USB
will fail.  The problem disappears if I read target voltage first.

For the lastest Versaloon firmware, it's OK.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-17 23:37:15 -08:00
richard vegh
daa1ff3535 NAND: lpc3180 crashes on LPC3250
The LPC3180 NAND driver was crashing on some large page chips.
Fix:

 - Crash and related functionality (don't memset too much OOB data)
 - Some debug messages
 - Command handling now works

[dbrownell@users.sourceforge.net: whitespace/linelength/message cleanup]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-16 12:27:45 -08:00
David Brownell
183765707f ADIv5 improved diagnostic
Don't just complain about an invalid ACK; say what the
value was, to help troubleshooting.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-15 13:02:45 -08:00
David Brownell
6c4a643d63 ARM DPM: disable some nyet-ready breakpoint code
Until we manage breakpoints at runtime (patches not ready for 0.4)
the only way this code should touch them is to disable them at server
startup (a previous debug session may have left them active).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-15 12:53:26 -08:00
David Brownell
187ccb60ee NEWS: include s3c64xx NAND driver
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-15 09:36:01 -08:00
David Brownell
0f7cea2847 jtag.h whitespace/comment cleanup
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-14 14:38:24 -08:00
David Brownell
8e1b5c3138 ARM ADIv5: add comments
Add doxygen and other comments for what's more or less the lowest
level JDAG-DP primitive, to access JTAG_DP_{A,D}PACC registers.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-14 12:58:39 -08:00
David Brownell
1d140c4dcd ARM7/ARM9: improved reset support
Teach most remaining ARM cores how to use the "reset-assert" event.

Same model as elsewhere:  iff a handler is provided for that event,
use that instead of trying to assert SRST (which may be unavailable,
or inappropriate since it resets too much).  Else no change.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-14 12:46:33 -08:00
Peter Korsgaard
000a1cfd01 nand flash support for s3c64xx
Identical to the existing 2412/2443 support except for the base address
and NFCONF value (bit 2 is reserved and should be written as 1 ref UM).

Tested on a s3c6410 board, but controller is identical in 6400/6410
except for 8bit MLC ECC support in 6410 which isn't supported by the
driver.

Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-14 21:07:46 +01:00
Laurentiu Cocanu
24653c950a str9x.c: remove optimization when erasing the whole bank
Using the erase bank command will cause a time out error. Replacing
this with the erase sector bank will provide a slower but safer and
stable method to erase the flash.

Signed-off-by: Laurentiu Cocanu <laurentiu.cocanu@zylin.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-14 15:07:24 +01:00
David Brownell
e1679a29f0 ARM7/9 minor cleanups
Shrink some overlong lines.  Add my 2009 copyright.
Move a declaration to the beginning of its block.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-14 03:16:07 -08:00
Spencer Oliver
e2d3266ff1 GDB: change gdb_breakpoint_override to COMMAND_ANY
- enable gdb_breakpoint_override to be used within config script.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-14 09:35:33 +00:00
David Brownell
b60dd35e33 User's Guide updates
Capture various bits of useful information that have come up on the
list but haven't yet gotten into the documentation:

 - Watchdog timers firing during JTAG debug need attention;

 - Some chips have special registers to help JTAG debug;

 - Cortex-M3 stepping example with IRQs and maskisr;

 - Clarifications re adaptive clocking:  not all ARMs do it, and
   explain it a bit better.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-13 23:33:53 -08:00
David Brownell
73566405b6 NOR: add optional "flash erase_address" sector padding
Add a NOR flash mechanism where erase_address ranges can be padded
out to sector boundaries, triggering a diagnostic:

  > flash erase_address 0x0001f980 16
  address range 0x0001f980 .. 0x0001f98f is not sector-aligned
  Command handler execution failed
  in procedure 'flash' called at file "command.c", line 647
  called at file "command.c", line 361
  >

  > flash erase_address pad 0x0001f980 16
  Adding extra erase range, 0x0001f800 to 0x0001f97f
  Adding extra erase range, 0x0001f990 to 0x0001fbff
  erased address 0x0001f980 (length 16) in 0.095975s (0.163 kb/s)
  >

This addresses what would otherwise be something of a functional
regression.  An earlier version of the interface had a dangerous
problem:  it would silently erase data outside the range it was
told to erase.  Fixing that bug turned up some folk who relied on
that unsafe behavior.  (The classic problem with interface bugs!)
Now they can get that behavior again.  If they really need it,
just specify "pad".

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-13 23:33:25 -08:00
David Brownell
d91941d5a0 Cortex-M3: improved core exception handling
This updates three aspects of debugger/exception interactions:

 - Save the user's "vector_catch" setting, and restore it after reset.
   Previously, it was obliterated (rather annoyingly) each time.

 - Don't catch BusFault and HardFault exceptions unless the user says
   to do so.  Target firmware may need to handle them.

 - Don't modify SHCSR to prevent escalating BusFault to HardFault.
   Target firmware may expect to handle it as a HardFault.

Those simplifications fix several bugs.  In one annoying case, OpenOCD
would cause the target to lock up on ome faults which triggered after
the debugger disconnected.

NOTE:  a known remaining issue is that OpenOCD can still leave DEMCR
set after an otherwise-clean OpenOCD shutdown.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-13 03:17:23 -08:00
Øyvind Harboe
b8e930e3bf arm7/9: enable check that DCC downloads have been enabled
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-13 12:00:02 +01:00
Øyvind Harboe
ee519ab356 arm7/9: add fn to check if dcc downloads have been enabled
DCC downloads should be enabled for any self repecting
openocd config file for arm7/9. Print out note about
it otherwise.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-13 12:00:02 +01:00
Øyvind Harboe
dc793455e9 target: add check_reset hook
Allow targets to run checks post reset. Used to check
that e.g. DCC downloads have been enabled.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-13 12:00:02 +01:00
Øyvind Harboe
3e33393078 gdbserver: fix typo that broke read/write watchpoint
It looks like a bugfix from normal breakpoints was not
copied over.

Do not use clever mathematics and assumptions to convert from
GDB enum for break/watchpoints to OpenOCD enum.

Drop connection upon unknown breakpoint type, this code path
was not really considered by the previous code I think.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-13 12:00:02 +01:00
Øyvind Harboe
6c75f5249c debug: make logging of commands terser
one line / command instead of one line per argument.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-13 08:32:15 +01:00
David Brownell
b4a4d5c731 ARM: bugfix for "movt" disassembly
Use the correct bitfield to specify the register whose
top halfword gets replaced.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-12 12:40:39 -08:00
Vladimir Zapolskiy
1de107a5a2 Added Openmoko USB JTAG interface config file.
Added interface config file for JTAG/RS232 debug board originally
integrated to Neo 1973 and Neo FreeRunner phones.
Adapter was tested with i.MX31, S3C2410 and AT91SAM9260 processors.

Signed-off-by: Vladimir Zapolskiy <vzapolskiy@gmail.com>
2010-01-11 15:58:13 +01:00
Øyvind Harboe
e5349bfb49 target: return JIM_OK instead of ERROR_OK
No change in actual binary as JIM_OK == ERROR_OK,
but JIM_OK is correct here.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-11 15:01:02 +01:00
Øyvind Harboe
fb71a0a0dd reset: better error messages
Use correct tcl syntax to throw exception.

the syntax is "return -code error" not "return -error"

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-11 12:58:06 +01:00
Øyvind Harboe
6d8604de37 commands: make error messages a bit more terse
we don't need to know the build path of command.c when
reading normal user level error messages.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-11 12:58:06 +01:00
Øyvind Harboe
c74ca40e09 zy1000: reset bugfix
flush JTAG FIFO before reset. Fixes RCLK problems observed
w/lpc2148, but really fixes a wider range of problems.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-11 10:25:13 +01:00
David Brownell
8c730aaee2 Doxygen file comments
Add file comments to a few files.  Make the GDB server use
more conventional (pointer-free) hex digit conversion.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-11 00:16:57 -08:00
Øyvind Harboe
88907cc7f9 shutdown: more graceful shutdown
Shutdown is not an error condition, do not return error
from main.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-11 08:13:17 +01:00
Spencer Oliver
d746dee833 build: doxygen build
- Fix for building doxygen out of tree

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-10 21:00:48 +00:00
David Brownell
c8267930c7 FreeBSD build fixes
Based on notes from Tomek Cedro <tomek.cedro@gmail.com> and
Steve Franks <bahamasfranks@gmail.com>.

In the User's Guide, sort the list of operating systems reported
through Tcl with $ocd_HOSTOS ... and include FreeBSD.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-10 10:06:58 -08:00
David Brownell
5e221fa3a7 Presto: doxygen fix
Newline needed.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-09 22:24:43 -08:00
David Brownell
ab4307e693 jtag/tcl help/usage fixups
The usual: expand several helptexts to be more correct and to use
full sentences; make the usage messages use the same EBNF as the
User's Guide; use function names for their addresses.

Also add a comment about that odd jtag_command_handlers_to_move[] thing.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-09 22:15:57 -08:00
David Brownell
5cb1dcfad3 ZY1000 help/usage fixups
The usual:  same EBNF as in the User's Guide, full sentence helptext,
function names *are* their addresses.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-09 22:14:08 -08:00
David Brownell
0811f6b192 jtag: presto, parport help/usage updates
Presto: add doxygen file comment.

Parport: note a couple gaps in layout config.

Both: use the uniform EBNF for usage, bugfix helptexts, use function
name as its address not "&name".

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-09 22:09:08 -08:00
David Brownell
ad5fd39063 jtag/gw16012 usage/help updates
Use standard BNF.  Improve/correct helptext for its "parport_port"
command.  Function address is just its name.
2010-01-09 22:05:55 -08:00
David Brownell
ff647e6bb4 parport (mostly) doc fixes
The "parport_port" commands generally don't *require* a port_number;
they're of the "apply any parameter, then print result" variety.  Update
the User's Guide accordingly.

Some of those commands are intended to be write-once: parport_port,
and parport_cable.  Say so.

Use proper EBNF for the parport_write_on_exit parameter.

Parport address 0xc8b8 is evidently mutant.  Say so in the "parport.cfg"
file, to avoid breaking anyone with that mutant config.  But update the
User's Guide to include a sane example for the LP2 port.

Finally document the "presto_serial" command.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-09 21:56:11 -08:00
David Brownell
1dd5277ba3 src/helper: usage/help updates
Make "usage" messages use the same EBNF as the User's Guide;
no angle brackets.  Improve and correct various helptexts.

Don't use "&function"; a function's name is its address.
Fix some whitespace glitches, shrink a few overlong lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-09 13:32:08 -08:00
David Brownell
1c5c57ec8e src/flash/nor: usage/help/doc updates
Make "usage" messages use the same EBNF as the User's Guide;
no angle brackets.  Improve and correct various helptexts.

Don't use "&function"; a function's name is its address.
Remove a couple instances of pointless whitespace; shrink a
few overlong lines; fix some bad indents.

Add TODO list entry re full support for NAND/NOR bank names.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-09 10:25:03 -08:00
Spencer Oliver
70738bd75d MIPS: update arch_info access to match other targets
- add target_to_mips32 and target_to_m4k to match test of codebase.
 - mips32_arch_state now shows if processer is running mips16e isa.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-09 13:37:02 +00:00
David Brownell
fc9a2d0e6f src/server: usage/help/doc updates
Make "usage" messages use the same EBNF as the User's Guide;
no angle brackets.  Improve and correct various helptexts.

Specifically for the port commands, clarify that the number
is optional, and omitting it causes the current number to be
displayed.

Don't use "&function"; a function's name is its address.
Remove a couple instances of pointless whitespace; shrink a
few overlong lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-09 00:55:41 -08:00
Masaki Muranaka
aafd3877e6 buildfix on MacOS
Recent Apple gcc versions use __APPLE__ instead of __DARWIN__; accept
that too.

Also use #warning, not #warn; neither is standard, but most CPP versions
require it to be spelled out.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-09 00:10:18 -08:00
David Brownell
973cd9a299 PLD: usage/help updates
Make "usage" messages use the same EBNF as the User's Guide;
no angle brackets.  Improve and correct various helptexts.

Don't use "&function"; a function's name is its address.
Remove a couple instances of pointless whitespace, shrink
a few overlong lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-08 23:23:55 -08:00
David Brownell
2a76c1bcf9 NAND: help/usage/doc updates
Usage messages should use the same EBNF as the User's Guide;
no angle brackets.  Be more complete too ... some params were
missing.  Improve and correct various helptexts.

Make user's guide refer to the NAND "driver" name, not the
controller name; that's a bit more precise.

Don't use "&function"; its name is its address.  Line up struct
initializers properly.  Remove some blank lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-08 23:18:46 -08:00
David Brownell
ae71005929 Doc/examples: clarify usage messages
Update/bugfix the "hello" example; emphasize using EBNF syntax,
matching the User's Guide.  Correct the Texinfo style guide to
say EBNF, not BNF.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-08 23:13:39 -08:00
David Brownell
b800eb0336 *SVF: help/usage updates
Usage messages should use the same EBNF as the User's Guide;
no angle brackets.  Be more complete too ... some params were
missing.

Don't use "&function"; its name is its address.

Unrelated: fix typo in one "target.c" usage message.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-08 20:16:05 -08:00
David Brownell
1a2c258ed4 MFLASH: help/usage updates
Make "usage" messages use the same EBNF as the User's Guide;
no angle brackets.  Improve and correct various helptexts.

Don't use "&function"; a function's name is its address.
Remove a couple instances of pointless whitespace.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-08 20:12:18 -08:00
David Brownell
c1cb20971e Coexist with quilt: rename PATCHES --> PATCHES.txt
The issues is on Win32, which ignores case in filesystem
and thus doesn't tolerate the quilt "patches" directory.

Rename, and add "patches" to .gitignore so that developers
can choose to use quilt for local patch management.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-08 17:20:47 -08:00
David Brownell
296a011db5 NOR: add FIXMEs for writing ones
It can invalidate ECC codes, and in general is not guaranteed
to work.  (However on some chips it _appears_ to behave.)  Just
don't do it; don't write in those cases.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-08 16:47:58 -08:00
David Brownell
12c143d594 misc ARM help/usage updates
Usage syntax messages have the same EBNF as the User's Guide;
there should be no angle brackets in either place.

Uupdate some helptext to be more accurate.

Don't use "&function"; functions are like arrays, their address
is their name.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 16:41:42 -08:00
David Brownell
82c0fb5277 ARM966: help/usage updates
Usage syntax messages have the same EBNF as the User's Guide;
there should be no angle brackets in either place.

Fix the User's Guide to say where the magic CP15 bits are defined;
and add comments in case someone provides mcr/mrc methods.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 16:39:32 -08:00
David Brownell
e7965cd3eb Xscale: User's Guide updates
Fix some EBNF goofs ... these commands have *optional* params, etc

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 16:34:44 -08:00
David Brownell
a42bea654c ARM720: help/usage updates
Deprecate the "pass an instruction opcode" flavor of cp15
access in favor of the "arm mcr ..." and "arm mrc ..."
commands, which offer fewer ways to break things.

Use the same EBNF syntax in the code as for the user's guide.

Update User's Guide to say where to find those magic values
(which table in the ARM920 TRM).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 16:30:09 -08:00
David Brownell
e0b6e5deef ARM720: help/usage updates
Deprecate the "pass an instruction opcode" flavor of cp15 access
in favor of the "arm mcr ..." and "arm mrc ..." commands, which
offer fewer ways to break things.

Use the same EBNF syntax in the code as for the user's guide.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 16:25:03 -08:00
David Brownell
199abf49ea ARM11: help/usage updates
Usage syntax messages have the same EBNF as the User's Guide;
there should be no angle brackets in either place.

Uupdate some helptext to be more accurate.

Fix the User's Guide in a few places to be more consistent (mostly
to use brackets not parentheses) and to recognize that parameter may
be entirely optional (in which case the command just displays output,
and changes nothing).  Also reference NXP, not Philips, for LPC chips.

Don't use "&function"; functions are like arrays, their address
is their name.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 16:21:24 -08:00
David Brownell
48d51e1719 ARM7/ARM9: help/usage updates
Provide helptext which was sometimes missing; update some of it
to be more accurate.

Usage syntax messages have the same EBNF as the User's Guide;
there should be no angle brackets in either place.

Fix the User's Guide in a few places to be more consistent (mostly
to use brackets not parentheses) and to recognize that parameter may
be entirely optional (in which case the command just displays output,
and changes nothing).  Also reference NXP, not Philips, for LPC chips.

Don't use "&function"; functions are like arrays, their address
is their name.  Shrink some overlong lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 16:20:14 -08:00
David Brownell
17921f51ab ARMv7: help/usage updates
Provide helptext which was sometimes missing; update some of it
to be more accurate.

Usage syntax messages have the same EBNF as the User's Guide;
there should be no angle brackets in either place.

Don't use "&function"; functions are like arrays, their address
is their name.  Shrink some overlong lines, remove some empties.

Add a couple comments about things that should change:  those
extra TCK cycles for MEM-AP reads are in the wrong place (that
might explain some problems we've seen); the DAP command tables
should be shared, not copied.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 16:18:01 -08:00
David Brownell
e19fe9ad09 ARM ETM/ETB/trace: help/usage updates
Provide helptext which was sometimes missing; update some of it
to be more accurate.

Usage syntax messages have the same EBNF as the User's Guide;
no angle brackets in either place.

Don't use "&function"; functions are like arrays, their address
is their name.  Shrink some overlong lines, remove some empties.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 15:22:41 -08:00
David Brownell
dd8f679aa2 target misc: help/usage updates
Provide helptext which was sometimes missing; update some of it
to be more accurate.

Usage syntax messages have the same EBNF as the User's Guide.

Don't use "&function"; functions are like arrays, their address
is their name.  Shrink some overlong lines; remove some empties.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 15:05:26 -08:00
David Brownell
7c3aee96b2 XScale: help/usage updates
Provide helptext which was sometimes missing; update some of it
to be more accurate (mostly they display something w/no args).

Usage syntax messages have the same EBNF as the User's Guide.
In some cases, *exactly* what the user's guide shows... e.g.
talking about "offset" not "address" for trace_image.

Don't use "&function"; functions are like arrays, their name
is their address.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-07 14:51:59 -08:00
Spencer Oliver
991d030fcc MIPS: change bulk_write_memory fallback msg to LOG_DEBUG
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-07 22:39:35 +00:00
Spencer Oliver
c68c2751f3 MIPS: whitespace cleanup
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-07 20:56:07 +00:00
Spencer Oliver
2d450b9033 MIPS: fastdata bulk write fallback
If fastdata access fails, then fallback to default mips_m4k_write_memory
Remove unnecessary fastdata loader verify check

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-06 20:24:31 +00:00
David Brownell
2bc7446bb8 buildfix with -DNDEBUG
Don't save that state unless its only user, an assertion,
is compiled.  Saving it broke a cygwin build.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-05 14:11:03 -08:00
David Brownell
844b5eb49d don't require 'openocd.cfg' to start
Starting the daemon with with just a bare "openocd" I saw:

	Can't find openocd.cfg

That's not an error; don't treat it as if it were.  There may
be an error later -- like, "no interface set up" -- but let
messages only report real errors, not fake ones.
2010-01-05 13:32:39 -08:00
David Brownell
fccb812f82 ARM: add #defines for JTAG ack codes
JTAG has only two possible JTAG ack codes for APACC and DPACC
register reads/writes.  Define them, and remove empty "else"
clause in the code which now uses those codes.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-05 13:03:27 -08:00
David Brownell
adf2a9a267 ARM: add comments re DAP assumptions
I think some of these assumptions are not well-founded.
Related, that swjdp_transaction_endcheck() is a bit iffy.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-05 12:55:46 -08:00
Spencer Oliver
9d83df72dc MIPS: pracc access tweaks
reorder the pracc access so we can save a few access cycles

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-05 19:54:37 +00:00
Spencer Oliver
ba96fc3e9d PIC32: enable ram execution
add reset-init script to allow ram execution from reset, this is required for ejtag fastdata access.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-05 19:54:37 +00:00
Spencer Oliver
f6412d9c7b MIPS: optimize pracc access
remove unnecessary nops when accessing ejtag pracc
general fastdata patch cleanup

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-05 19:54:36 +00:00
Spencer Oliver
faad9e5923 parport: output port as hex rather than dec
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-05 19:54:36 +00:00
David Claffey
03e8649bc6 MIPS: merge mips fast_data patch from David N. Claffey
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2010-01-05 19:54:35 +00:00
Øyvind Harboe
95f86e8e05 gdb: fix regression in gdb_port command
The gdb_port command can be invoked during normal execution
to report the port used for gdb, whereas it was listed as
CONFIG stage only, which caused an error when excuting
it to return the reported error.

Also in line with the grander goal of making more commands
available during all "modes" (perhaps retiring config mode),
there is no particular reason to limit gdb_port to the
config stage.

Regression was introduced in:

b3bf1d12b2 aka
v0.4.0-rc1-32-gb3bf1d1

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2010-01-05 15:28:23 +01:00
Johannes Stezenbach
6d4abe906f update udev rules for new udev version
New versions of udev (148+) emit the following warnings:

udevd[425]: BUS= will be removed in a future udev version,
  please use SUBSYSTEM= to match the event device, or
  SUBSYSTEMS= to match a parent device, in /lib/udev/rules.d/60-openocd.rules:1
udevd[425]: SYSFS{}= will be removed in a future udev version,
  please use ATTR{}= to match the event device, or
  ATTRS{}= to match a parent device, in /lib/udev/rules.d/60-openocd.rules:4
udevd[425]: SYSFS{}= will be removed in a future udev version,
  please use ATTR{}= to match the event device, or
  ATTRS{}= to match a parent device, in /lib/udev/rules.d/60-openocd.rules:7
...

See also http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=560141

[dbrownell@users.sourceforge.net: add IDs for Stellaris ICDI, Olimex Tiny-H]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-05 01:54:06 -08:00
David Brownell
1b3f15d51e ARMv7-M: use AP_REG_* symbol
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-04 22:11:34 -08:00
David Brownell
237a707f96 FT2232: fix doc typo
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-03 15:02:51 -08:00
David Brownell
e1258c703b JTAG/drivers: ft2232 docs
Add doxyegen description for this driver.

Correct the helptext (configures *or* displays based on #params),
and usage (use the same BNF as the User's Guide).

Remove superfluous #include

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-03 14:54:52 -08:00
David Brownell
50fb3a5129 JTAG/Drivers: Amontec JTAG accelerator fixes
Remove superfluous #include.

Correct the helptext (configures *or* displays based on #params),
and usage (use the same BNF as the User's Guide).

Add doxygen -- file-level description and a @todo for doing
RTCK correctly.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-03 14:51:01 -08:00
David Brownell
4aedb02fcd JTAG: Amontec JTAG accelerater "rtck" is back
The command processing conversion a while back lost the
"rtck" enable/disable command; restore it.

NOTE that having such a command is wrong; there's a standard
way to enable adaptive clocking ("speed 0").

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-03 13:30:06 -08:00
David Brownell
e0338293b8 JTAG/drivers: cleanup jtag_interface structs
Get rid of excess indents.
Ditto superfluous "&" before function pointers.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-03 13:07:18 -08:00
David Brownell
d9508b30e0 JTAG/drivers: amt_jtagaccel fixes + cleanup
Build fixes:  it failed abysmally with PPDEV enabled.  Swapped
a build-time error with a FIXME comment in the affected macros.

Cleanup: remove "&" before function pointers, and excess indent,
for the interface struct declaration.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-03 12:59:51 -08:00
David Brownell
4ed5b45097 ARM: ADIv5 JTAG symbol cleanup
Rename DAP_IR_* as JTAG_DP_* since those symbols are specifically
for JTAG-DP (or SWJ-DP in JTAG mode), and won't work with SWD.
Define the JTAG ABORT and IDCODE instructions for completeness;
add a comment about where to (someday) use ABORT.

Fix messaging which assumes everything is an SWJ-DP; say "JTAG-DP"
instead, it's at least more appropriate for all JTAG transports.

Shrink the affected lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-02 15:53:33 -08:00
David Brownell
858226aae2 ARM: dap info fix + tweaks
Fix: don't print the BASE address except if it's a MEM-AP;
that's an unlikely error, but there's no point getting it wrong.
Tweaks: comments, capitalization.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-02 15:53:18 -08:00
David Brownell
6105f2bc4a ARM: ADIv5 export cleanup
Make some private functions "static".  Remove their public declarations,
and what is now an obviously unused function.  Shrinks this object's size
(about 5% on x86_64) while making the code's scope easier to understand.
Shrink the affected lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-02 15:53:06 -08:00
David Brownell
e60c164cdb ARM: ADIv5 symbol and comment cleanup
Instead of magic numbers, use their AP_REG_* constants.  Rename
the ROM address symbol as BASE to match ARM's documentation.

Comment various other symbols in the header; add some missing ones.
Remove an unused struct.  Add some doxygen for stuff including the
DAP structure and initialization.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-02 15:53:03 -08:00
David Brownell
ec88ccc51c Cortex-M3: minor breakpoint cleanup
Shrink some lines, add some comments, simplify some tests.
During debug startup, log the core revision level too.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-02 15:52:52 -08:00
David Brownell
b3bf1d12b2 streamline and document helptext mode displays
Most commands are usable only at runtime; so don't bother saying
that, it's noise.  Moreover, tokens like EXEC are cryptic.  Be
more clear: highlight only the commands which may (also) be used
during the config stage, thus matching the docs more closely.
There are

 - Configuration commands (per documentation)
 - And also some commands that valid at *any* time.

Update the docs to note that "help" now shows this mode info.

This also highlighted a few mistakes in command configuration,
mostly commands listed as "valid at any time" which shouldn't
have been.  This just fixes ones I noted when sanity testing.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-02 15:52:35 -08:00
Dean Glazeski
9d167d62f2 Fix usage/help search for subcommands.
This makes it so that the usage/help command properly uses the whole command,
including subcommand, in the search for help information.  This previously
caused erroneous output from the usage command handler.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-02 02:10:55 -08:00
Dean Glazeski
be01786186 Add the current command to the command information
I wanted to make it so I can be ignorant of a commands invocation string, so
I tried to use CMD_CURRENT (aka cmd->current) which is supposed to house a
pointer to the current command.  It turns out that this wasn't being set.

This patch adds the current command structure to the command invocation
structure before sending it along to the command handler.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-02 01:50:57 -08:00
Antonio Borneo
668f20d0ab Added ST FlashLINK interface config file.
The relevant cable config is already in OpenOCD, but not a config for
the JTAG adapter.  I have tested with FlashLINK on ARM926.

Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2010-01-02 01:50:57 -08:00
David Brownell
384e9193e9 User's Guide: warn about the forum
Namely, that developers don't hang out; it's a users-only club.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-31 03:09:03 -08:00
Dean Glazeski
7cef6d650c Remove some more Eclipse stuff from Git's eyes.
This adds the .settings folder and the .cproject file put down
by Eclipse from the eyes of Git.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-30 23:26:16 -08:00
Antonio Borneo
3ed254c18a ARM7_9: Fix segfaults
Handlers for commands
 - arm7_9 semihosting <enable | disable>
 - $_TARGETNAME arp_reset assert 1
didn't check if target has already been examined, and could
segfault when using the NULL pointer "arm7_9->eice_cache".

Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-30 16:58:27 -08:00
Antonio Borneo
7c5acf8660 whitespace cleanup, mostly for docs
Remove useless space/tab at end of lines.
Remove spaces in indentation and replace with tab.

Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-30 11:51:29 -08:00
Antonio Borneo
17fb7ead4b ARM9TDMI: Fix segfault.
The handler for "arm9tdmi vector_catch ..." did not check
if target has already been examined.  Without this fix it
segfaults when using NULL pointer "arm7_9->eice_cache".

Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-30 11:51:29 -08:00
Antonio Borneo
c116d8f6bc Fix parport_dcl5 config file.
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
2009-12-30 19:07:44 +01:00
Øyvind Harboe
20354a66b9 zy1000: add zy1000_ prefix to uart command
less polution of the general namespace(preventive action,
no problems reported).

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-30 13:13:31 +01:00
Øyvind Harboe
2cf6d47375 zy1000: unlock flash upon startup for revc
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-30 12:36:22 +01:00
Øyvind Harboe
272c33c190 zy1000: reconfigure FPGA upon reset instead of just the CPU
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-30 12:12:32 +01:00
Øyvind Harboe
bd3700e89d zy1000: firmware upgrade fixes for revc
Use ecos firmwareutil upgrade utilities

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-30 12:12:24 +01:00
Øyvind Harboe
12618e4c6d zy1000: less warnings
use inline for static functions in header files to
avoid warnings about fn not being used.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-30 12:11:33 +01:00
Piotr Esden-Tempski
d4bef466c3 Added Open-BLDC board config file. 2009-12-29 12:41:43 +01:00
Piotr Esden-Tempski
aa81462618 Added floss-jtag interface config file. 2009-12-29 12:41:43 +01:00
Freddie Chopin
6b1eeb92fe MinGW build fixes
Print "ssize_t" as "%ld" (+ cast to long) not as "%zu".
Official MinGW (gcc 3.4.5) doesn't understand "z" flag.

Signed-off-by: Freddie Chopin <freddie_chopin@op.pl>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-28 13:09:31 -08:00
Freddie Chopin
37cc6c495f stm32x commands get "usage"
Add .usage fields to stm32x command_registration,
so that "help stm32x" shows required parameters.

Signed-off-by: Freddie Chopin <freddie_chopin@op.pl>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-28 13:05:50 -08:00
David Brownell
ec297e4bf1 Fix Luminary FT2232 layout docs/configs
Most of this patch updates documentation and comments for various
Luminary boards, supporting two bug fixes by helping to make sense
of the current mess:

 - Recent rev C lm3s811 eval boards didn't work.  They must use
   the ICDI layout, which sets up some signals that the older
   boards didn't need.  This is actually safe and appropriate
   for *all* recent boards ... so just make "luminary.cfg" use
   the ICDI layout.

 - "luminary-lm3s811.cfg", was previously unusable!  No VID/PID;
   and the wrong vendor string.  Make it work, but reserve it
   for older boards where the ICDI layout is wrong.

 - Default the LM3748 eval board to "luminary.cfg", like the
   other boards.  If someone uses an external JTAG adapter, all
   boards will use the same workaround (override that default).

The difference between the two FT2232 layouts is that eventually
the EVB layout will fail cleanly when asked to enable SWO trace,
but the ICDI layout will as cleanly be able to enable it.  Folk
using "luminary.cfg" with Rev B boards won't see anything going
wrong until SWO support is (someday) added.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-28 12:59:47 -08:00
Piotr Esden-Tempski
cba1813d5c NOR: last_addr also needs correction when checking alignment
Otherwise the new alignment checking algorithm thinks that the
address is not aligned, because it is way beyond the last sector.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-28 12:31:47 -08:00
David Brownell
3ace333663 create tcl/board/dm365evm.cfg
This config is only lightly tested, and doesn't work well yet;
but it's a start.

 * Notably missing is PLL configuration, since each DaVinci
   does that just a bit differently; and thus DDR2 setup.

 * The SRST workaround needed for the goof in the CPLD's VHDL
   depends on at least the not-yet-merged patch letting ARM9
   (and ARM7) chips perform resets that don't use SRST.

So this isn't yet suitable for debugging U-Boot.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-27 12:16:55 -08:00
David Brownell
155a6a2c0b NOR: make flash_write_unlock() pad to sector end
Resolve a regression when using newish automagic "write_image"
modes, by always padding to the end of affected sectors.

Also document some issues associated with those automagic options,
in the User's Guide and also some related code comments.

We might need similar padding at the *beginning* of some sectors,
but this is a minimalist fix for the problems which have currently
been reported (plus doc updates).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-27 11:34:31 -08:00
Catalin Patulea
84dbf8ab5a Driver for USB-JTAG, Altera USB-Blaster and compatibles
The 10-pin JTAG layout used with these adapters is used by
a variety of platforms including AVR.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-26 15:05:06 -08:00
Dean Glazeski
900d745567 Olimex SAM9-L9260 board configuration update.
This updates the board configuration for the SAM9-L9260 board with the
configuration for the on-board NAND and dataflash.  Included are commands
for configuring the AT91SAM9 NAND flash driver.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-26 13:08:24 -08:00
David Brownell
3a84436afb ARM: add comment re register exports
Modern versions of GDB can understand VFP3 and iwMMXt hardware.
2009-12-26 11:25:44 -08:00
David Brownell
e7f81c11c9 User's Guide: update GDB info
Advise leaving background polling enabled; fix broken URL;
add simple program startup example.
2009-12-26 10:35:24 -08:00
David Brownell
df58812b52 NOR: messaging fix
Fix syntax error:  default to "wrote N bytes"; writing a
single byte is an unusual case, not the normal one.
2009-12-26 10:24:39 -08:00
David Brownell
396b0f3012 NOR: Allocate the right amount of memory
Switch to calloc() to simplify review and initialization.
2009-12-26 10:22:28 -08:00
David Brownell
08a890e4aa cygwin 1.7 build fixes
It's less accepting of signed char ... insisting that e.g. tolower()
not receive one as a parameter.

It's probably good to phase out such usage, given the number of bugs
that lurk in the vicinity (assumptions that char is unsigned), so fix
these even though such usage is actually legal.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-26 10:19:19 -08:00
Antonio Borneo
f9d203d1e6 PARPORT code cleanup:
Align elements in array.

Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
2009-12-26 10:19:57 +01:00
David Brownell
4e2b15fc93 Restore "-dev" version suffix
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-21 14:49:36 -08:00
David Brownell
0c55017a22 v0.4.0-rc1 milestone
Winter Solstice, 2009.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-21 14:45:52 -08:00
David Brownell
07c06ec5e2 Packaging fix, NEWS update
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-21 12:50:17 -08:00
David Brownell
b963e17be7 Packaging fix
Don't forget to list target/arm_opcodes.h

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-21 12:31:12 -08:00
Oyvind Harboe
b5962b23d8 help: list all commands that match string
Restore behavior where help lists all commands that
match string passed to help.

Signed-off-by: Oyvind Harboe <oyvind.harboe@zylin.com>
2009-12-21 11:19:42 +01:00
David Brownell
34bbbe7961 Cortex-M3: cleanup
Misc:
 - Introduce some "struct reg" temporaries, for clarity
 - Shorten lines
 - Add some missing whitespace
 - Clean up comments
 - Add notes about some fault handling issues
 - Most of these errata workarounds are for *OLD* chip revisions

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-20 16:33:00 -08:00
David Brownell
abf01895ae ARM11: recognize ARM11 MPCore
And add my copyright.  MPCore is untested, but it's the
only other ARM11 core to care about.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-20 11:11:54 -08:00
Antonio Borneo
0df5d1eb3c arm7_9: Support VINITHI signal
Command "reset halt" checks if PC properly resets, issueing warning:
"PC was not 0. Does this target need srst_pulls_trst?".
Checking PC against 0 is not always correct.

Removed PC value check, as suggested by Øyvind Harboe.

Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Signed-off-by: U-PROPRIET-28D9DF\PROPRIETAIRE <PROPRIETAIRE@propriet-28d9df.(none)>
2009-12-20 19:06:52 +01:00
David Brownell
b72bfabf0d cygwin build fixes
and shrink some too-long lines

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-19 15:43:55 -08:00
Dean Glazeski
3ac2a44041 AT91SAM9 NAND flash driver.
This creates the TCL interface for configuring an AT91SAM9 NAND flash
controller and implements the necessary functions to correctly work with
a NAND flash device connected to the chip.  This includes updates to the
driver list and the Makefile.am to support building the driver and also
houses the documentation update in openocd.texi.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-19 13:26:33 -08:00
David Brownell
28f8e9dfb7 oocd_trace buildfixes
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-19 13:24:59 -08:00
David Brownell
abe8b43755 ETM: add "etm trigger_debug" command
In conjunction with manual register setup, this lets the ETM trigger
cause entry to debug state.   It should make it easier to test and
bugfix the ETM code, by enabling non-trace usage and isolating bugs
specific to thef ETM support.  (One current issue being that trace
data collection using the ETB doesn't yet behave.)

For example, many ARM9 cores with an ETM should be able to implement
four more (simple) breakpoints and two more (simple) watchpoints than
the EmbeddedICE supports.  Or, they should be able to support complex
breakpoints, incorporating ETM sequencer, counters, and/or subroutine
entry/exit criteria int criteria used to trigger debug entry.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-19 13:09:19 -08:00
David Brownell
64934d9204 ETM: more ETM_CTRL bit cleanup
Change handling of the CYCLE_ACCURATE, BRANCH_OUTPUT, and
TRACE_* flags; also the CONTEXTID size values.

 - Convert to symbols matching the actual register bits, instead of
   some random *other* bits (and then correcting that abuse).

 - Get rid of a now-needless enum.

 - Keep those values in etm->control, and remove etm->tracemode.

These values all affect the trace data that's recorded by a trace
pod or in the ETB.  I modified the file format used to dump ETB
data; since it's fairly clear nobody can use this mechanism now,
this can't cause anyone trouble.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-19 13:07:26 -08:00
David Brownell
e25819645e ETM: start cleaning up ETM_CTRL bit handling
Provide better comments for the ETM_CTRL bits; use the correct bit
for half/full clock mode; and define a few more of the bits available
from the earliest ETM versions.

The new bit defintions use ETM_CTRL_* names to match their register
(instead of ETM_PORT_* or ETMV1_*).  For clarity, and better matching
to docs, they are defined with bitshifting not pre-computed masks.

Stop abusing typdefs for ETM_CTRL values; such values are not limited
to the enumerated set of individual bit values.

Rename etm->portmode to etm->control ... and start morphing it into a
single generic shadow of ETM_CTRL.  Eventually etm->tracemode should
vanish, so we can just write etm->control to ETM_CTRL.

Restore an "if" that somehow got dropped.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-19 13:07:25 -08:00
David Brownell
9abad965ab ETM trigger_percent becomes an ETB command
This command was misplaced; it's not generic to all traceport drivers,
only the ETB supports this kind of configuration.  So move it, and
update the relevant documentation.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-19 13:06:46 -08:00
David Brownell
bfadd79965 NEWS: mention libftdi 0.17 2009-12-19 13:01:30 -08:00
David Brownell
3f18900b19 NOR FLASH: only erase/unlock whole sectors
Much to my surprise, I observed a "flash erase_address ..."
command erasing data which I said should not be erased.

The issue turns out to be generic NOR flash code which was
silently, and rather dangerously, morphing partial-sector
references into unrequested whole-sector ones.

This patch removes that low-level morphing.  If desired, it
can and should be done in higher level code.  (We might need
to fix some stuff in the GDB server code.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-18 10:16:52 -08:00
David Brownell
013b05f7f8 Subject: flash fill[bwh] should use bulk i/o
It's currently allocating a big buffer but writing it out in
units of sizeof(host's pointer) ... sub-optimal.

Plus fix a couple minor coding style goofs.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-18 10:09:35 -08:00
David Brownell
7641934197 stellaris: fix min buffer length checks
Word count == size/4; cope.  And increase buf_min so it's large
enough to cover the overhead in my tests.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-18 09:59:40 -08:00
David Brownell
12b8c7b89b XScale: better {read,write}_phys()
We can actually do the right thing if the MMU is off; save
the error message for the phys-but-MMU-enabled path, which
is what isn't yet supported.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-18 09:53:59 -08:00
David Brownell
85a4136d0b dsp563xx: cygwin build fixes
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-18 03:08:49 -08:00
David Brownell
e40f638063 stellaris: update bulk flash writes
Try to right-size the SRAM buffers, by not:
 - using them for very small writes
 - giving up when a large buffer isn't available
 - allocating buffers much larger than their data

Also don't:
 - bother loading the code unless we allocate the writebuffer too
 - be so verbose with messaging:
    * be more concise
    * reduce importance (e.g. DEBUG not WARNING)
    * remove duplication

The minimum buffer size is something of a guess.  It's eight
times smaller than before, almost the same size as the code
being downloaded.  It probably deserves some tuning.

Also, note an erratum affecting flash protection on some chips;
and narrow many over-wide lines affected by the above changes.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-18 01:33:19 -08:00
Dean Glazeski
ef4fbd36d4 NAND write data page refactoring.
Refactored the write page raw function into two new functions
for writing data to a NAND device and then another function to
finish up a write to a NAND device.  This includes some new
updates to introduce more error checking to existing code.

[dbrownell@users.sourceforge.net: fix fault handling, whitespace]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-18 01:33:19 -08:00
Dean Glazeski
b8b4bb0745 NAND read data page refactor.
Added a new function to encapsulate reading a page of data from
a NAND device using either the read_block_data function of a NAND
controller or to use direct reading of data from the NAND device.

This also adds some performance enhancements and uses the read_data
function if the read_block_data function fails safely (because it
can't allocate a buffer in the working area).

[dbrownell@users.sourceforge.net: fix fault handling, whitespace]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-18 01:33:19 -08:00
Spencer Oliver
3616b93eee target.cfg: update to use new flash configuration syntax
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2009-12-17 11:39:09 +00:00
David Brownell
960ad2f776 Remove duplicate Olimex-"tiny" interface
We already have tcl/interface/olimex-jtag-tiny.cfg and
don't need a clone of it.
2009-12-16 14:21:06 -08:00
David Brownell
2c3e413d49 JTAG: shrink "scan_chain" output
Tweak the "scan_chain" output by removing column separators.  Also
remove the "current instruction" state ... which changes constantly.

Now its style resembles the "targets" output, and can even fit on
one line in standard terminals and in the PDF docs.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-16 14:19:44 -08:00
David Brownell
d265c219b9 stellaris: comments
Someday revisit various issues:  Tempest parts support writing
more than one word at a time; for some target firmware it might
be necessary to save and restore flash IRQ configuration.  (The
safest policy is likely to always reset after flash updates.)

Plus swap some undesirable TAB characters with SPACE.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-16 14:17:31 -08:00
David Brownell
1cd7b3b49b stellaris: probe() cleanups
Fix potential memory leak:  make sure the per-bank data
structures are only allocated in probe(), and that calling
probe() multiple times is a NOP.  Use it for auto_probe().

Require probe() to have done its thing:  don't make access
routines cope with it not having been called.  Shrink a
bunch of failure paths; and in some cases, correct them.

Don't needlessly insist on a halted target for probe().

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-16 14:17:31 -08:00
David Brownell
6f2b9ea9e1 stellaris: remove needless code
No point in reading and discarding a status value when fetching
part description data.  Or having that needless "#if 0" code.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-16 14:17:31 -08:00
David Brownell
f85dc92d2a stellaris: avoid chip writes
Previously "reading" clock info (and part info) also, as a side
effect, wrote the flash timing register.  Instead, be more safe:
"reading" should only read.  Write paths still refresh timing,
coping with changes the application code may have made.

Also rename the routine which sets flash timing, indicating what
it's really doing; it's got nothing to do with a "mode".

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-16 14:17:31 -08:00
David Brownell
47998a55e0 NOR: bugfix "flash fill[bwh] ..." helptext
These commands don't have a "bank" parameter.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-16 11:57:59 -08:00
Øyvind Harboe
fcd3c52611 zy1000: removed some redundant include
spotted by lint.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-16 14:52:22 +01:00
Øyvind Harboe
c8b8a34bb5 ecos: crisper implementation of timeval_ms()
A crisper/faster implementation under eCos that makes profiling a
tad easier.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-16 08:15:05 +01:00
Øyvind Harboe
74ce435d97 server: server loop will exhaust data inputs before sleeping
By exhausting data on input, the performance will be more
consistent + the code more clearly distinguishes between
polling and processing. A test showed gdb packet load
performance go from ~1550kByte/s to 1650kBytes/s + being
more stable.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-16 08:09:35 +01:00
David Brownell
4a2f4e3433 more tcl/{board,target} cleanup
Remove more remnants of the old "jtag_device" syntax.

Don't [format "%s.cpu" $_CHIPNAME] ... it's needless complexity.

Remove various non-supported "-variant" target options; they're not
needed often at all.

Flag some of the board files as needing to have and use target files
for the TAP and target declarations.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-15 14:45:26 -08:00
David Brownell
80a757d82e testing/examples/.../*cfg: rm jtag_device calls
That syntax has been obsolete forever and is now gone; remove a few
remaining references.  Shows how seldom this stuff gets used.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-15 14:45:26 -08:00
David Brownell
fc99287b09 XScale: use all-ones for BYPASS, not five-ones
PXA3xx has more than five bits in IR.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-15 14:45:26 -08:00
mkdorg@users.sourceforge.net
646ce814b4 target: add basic dsp563xx support 2009-12-15 18:38:52 +01:00
Øyvind Harboe
4639366947 zy1000: keep up with command.h cleanup
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-15 13:24:28 +01:00
Øyvind Harboe
dca173053b command: retire obsolete macro
COMMAND_REGISTER() was only used transiently during
code conversion.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-15 13:23:07 +01:00
Øyvind Harboe
d6aff79f1a imx31: move srst delay into config script
reset init/run now works again.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-15 07:55:20 +01:00
David Brownell
bb77e5d32f ARM11: improved reset support
Teach ARM11 how to use:

 - the new "reset-assert" event
 - vector catch to implement "reset halt"
 - use SRST more like other cores do
 - ... including leaving post-SRST delays up to config scripts

This gives OMAP2420 the ability to reset, and doesn't seem to
cause new iMX31 problems.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-14 19:56:36 -08:00
David Brownell
27b13e3377 ARM: disassemble STM correctly
There is no "STMMIDA" instruction.  There is however "STMDAMI".

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-14 19:53:10 -08:00
David Brownell
c86a64dff7 lm3748: use new Stellaris config file
Use the new file, and remove the old target/lm3s3748.cfg one.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-14 16:29:53 -08:00
Yegor Yefremov
a1009509fb Common target file for Stellaris chips
Common target.cfg file for LM3S CPU family

[dbrownell@users.sourceforge.net: rename, generalize more]

Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-14 16:29:31 -08:00
Eric Wetzel
36dec1b319 stellaris: device IDs
I added the remaining devices and device IDs to stellaris.c, and
removed several devices that don't exist on the Stellaris web page.

Additionally, I found a few devices with duplicate IDs ... the DID1
Version Number for LM3Sxxx parts have DID1 Version = 0x0, and for
LM3Sxxxx have DID1 Version = 0x1. So I extended the comparison to
use the VER and FAM fields from DID1 also.

ID=0x33: LM3S812 (DID1v0) and LM3S2616 (DID1v1)
ID=0x39: LM3S808 (DID1v0) and LM3S2276 (DID1v1)

These are the parts I removed from the file for lack of documentation
(no data sheet to confirm part ID):

  LM3S318,
  LM3S1101, LM3S1108,
  LM3S1615, LM3S1616,
  LM3S2016,
  LM3S2101, LM3S2108,
  LM3S3759, LM3S3768,
  LM3S5757, LM3S5767, LM3S5768, LM3S5769,
  LM3S6815, LM3S6816,
  LM3S6915, LM3S6916,
  LM3S6111, LM3S6118.

Also, sort devices according to part number.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-14 15:59:01 -08:00
David Brownell
af79925eb1 jtag: add '-ignore-version' option
Add a "-ignore-version" to "jtag newtap" which makes the IDCODE
comparison logic optionally ignore version differences.

Update the "scan_chain" command to illustrate this by showing
the "*" character instead of the (ignored) version nibble.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-14 15:55:51 -08:00
David Brownell
6f929dbd93 target files shouldn't #include <target/...h>
Make these ".h" files adopt the same policy the ".c" files already
follow:  don't use <subsystem/...h> syntax for private interfaces.

If we ever get reviewed/supported "public" interfaces they should
come exclusively from some include/... directory; that'll be the
time to switch to <...> syntax for any subsystem's own interfaces.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-13 12:52:23 -08:00
David Brownell
38e376d232 target: further shrink Jim-awareness
Don't include <helper/jim.h> from target.h ... not everything
which touches targets needs to be able to talk to Jim.  Plus,
most files include this header by another path.

Also, switch the affected files to use the classic sequence
for #included files:  all <framework/headers.h> first, then
the "local_headers.h".  This helps prevent growth of problematic
layering, by minimizing entanglement.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-13 12:52:23 -08:00
David Brownell
0a9d7cab6d LPC2000: rename "r13_svc" as "sp_svc"
This driver didn't get updated when the name changed.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-12 15:43:02 -08:00
David Brownell
b3e64566ab ARM11: avoid pointless status returns
For some routines that only returned ERROR_OK and where the
caller never checked ... don't bother.  Remove some noise,
and bugfix some comments.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-11 20:55:12 -08:00
Zachary T Welch
75892bfc6e add missing call to add new NAND devices
I forgot to add a call to the newly factored nand_device_add(), along
with its forward declaration.
2009-12-11 18:45:34 -08:00
Zachary T Welch
8438dee786 fix 'write_image' usage information
The 'flash write_image' command erroneously listed the bank number,
when it actually uses target addresses to do that lookup for the user.
2009-12-11 18:45:34 -08:00
David Brownell
75c706cc04 ARM DPM: support updating HW breakpoints
Abstract the DPM breakpoint and watchpoint data structures to
have a shared core for housekeeping.

Abstract the code updating the watchpoint registers so that it
can be used to update breakpoint registers.  Then do so, when
something has set up the breakpoint state used by this code.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-11 15:26:10 -08:00
David Brownell
838d41af29 ARM: disassembly fixes for LDC/STC/MRRC/MCRR
Properly detect all of these, including the "2" variants;
and bugfix parameter display for LDC and STC.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-11 15:24:08 -08:00
David Brownell
cfd79e96a6 ARM11: minor cleanup, mostly ITR comments
ITR register handling seemed to be giving me problems, so I updated
the comments to better say what the code is trying to do ... and to
note the preconditions (one of which seems to be an issue) as listed
in the ARM1136 TRM.

Also removed the unused "ARM11_TAP_DEFAULT" from the ITR scan code;
all the callers already specify an exit path, since this register
isn't usable with such vague semantics.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-11 15:24:08 -08:00
Spencer Oliver
08589462ad server: add server_preinit which is called before config file is parsed.
This fixes the issue under native win32 of the socket interface not being
enabled (via WSAStartup) before init is called from a script.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2009-12-11 10:26:15 +00:00
Spencer Oliver
6b9c14e908 build: fix cygwin build warnings
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2009-12-11 10:26:14 +00:00
Øyvind Harboe
97996214f5 gdb_server: use more local variables in inner loop of fetching packetstiny refactoring to allow optimisation of inner loops
Some profiling information for arm7 16MHz GDB load operation shows
gdb_get_packet_inner() near the very top.

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls  Ts/call  Ts/call  name
 52.91      2.27     2.27                             embeddedice_write_dcc
 11.89      2.78     0.51                             gdb_get_packet_inner
  8.86      3.16     0.38                             memcpy
  3.26      3.30     0.14                             idle_thread_main(unsigned int)
  3.03      3.43     0.13                             cyg_in_cksum

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-11 09:17:23 +01:00
Øyvind Harboe
1c42606aea gdb_server: make struct gdb_connection private
it is only used inside gdb_server.c

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-11 09:17:23 +01:00
Øyvind Harboe
ac46e072df optimisation: tiny optimisation for embedded ice
use two shift operations instead of three to set embedded
ice register.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-11 09:17:23 +01:00
Øyvind Harboe
068626fde4 embedded hosts: optimize common code path for core arm operations
avoid fn call for the if check on whether anything needs
to be done.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-11 09:17:23 +01:00
David Brownell
a34345451d anotyer cygwin compile fix
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-10 17:42:20 -08:00
Øyvind Harboe
134df4b701 zy1000: revc FPGA now works
remove kludge code.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-10 13:52:07 +01:00
David Brownell
29a8cdc3b0 ARM: update arm_opcodes.h copyright
I neglected to copy Magnus' copyright when I moved several
declarations from the ARMv7-M header.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-09 21:43:23 -08:00
David Brownell
3d9cb516c2 stellaris: flash protection updates, minor fixes
Bugfix the read side of flash protection:
 - read the right register(s)!
 - handle more than 64K
 - record the results in the right places
 - don't display garbage.

Partially bugfix the write side:
 - use 2KB lock regions instead of 1KB pages (!)
 - validate input range
 - don't try to _remove_ protection (it's write-once)
 - #define values we'll need to commit writes.
 - ... still doesn't handle pages over 64KB mark, or commit writes

And minor cleanup and fixes:
 - get rid of some forward decls
 - properly locate a doxygen comment
 - fix some bad indentation
 - remove superfluous #include
 - add a new part ID (many are still missing)
 - make the downloaded algorithm code be read-only

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-09 21:16:09 -08:00
David Brownell
910dd664ce Comment and doxygen fixes
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-09 10:25:52 -08:00
Spencer Oliver
26d7ed08f9 ETM: only include oocd_trace.h when tracing enabled.
Fixes build issue on systems that do not have <termios.h>, eg native win32.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2009-12-09 10:35:30 +00:00
Rafael Campos Las Heras
733ced125a Fix compilation error with gcc 4.4.1
Signed-off-by: Rafael Campos Las Heras <methril@gmail.com>
2009-12-08 22:58:23 +01:00
David Brownell
f0da635e55 target: remove more exit() calls
These were all basically "can't happen" cases ... like having
state be corrupted by an alpha particle after the previous check
for whether a value was in-range.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-08 13:09:38 -08:00
David Brownell
cbea1ed71f target: remove needless "extern"s
Most of these happened to be in the target.h file.

Some of those are associated with symbols that could be
removed at some point ... e.g. NVP_ASSERT/true and its
sibling NVP_DEASSERT/false.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-08 13:06:41 -08:00
David Brownell
e7acbdf5db target: move 'extern' decls to *.h files
The exception being declarations for drivers.  Those should
be split out in some clean way -- like driver add/remove calls
made by initialization code -- but that's for another day.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-08 13:06:41 -08:00
David Brownell
ac19fc0da7 ARM: cygwin complile fixes
It's as if despite integers being 32-bits, GCC refuses to
convert a "uint32_t" to one of them.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-08 02:00:35 -08:00
Øyvind Harboe
96d2b61c04 zy1000: some background info on the zy1000 file.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-08 10:40:47 +01:00
Øyvind Harboe
97de520bc0 minidriver: fix inline capability of minidriver
Low latency low CPU processing power systems(embedded)
will benefit greatly from being able to inline certain
jtag_add_xxx() fn's. The trick is that this has to be
done in such a way as to allow implementing an OpenOCD
API with a shared library(eventually) on a PC hosted
OpenOCD.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-08 10:29:58 +01:00
Øyvind Harboe
304af6e7d8 zy1000: remove unecessary include
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-08 10:16:25 +01:00
Øyvind Harboe
eb1bc657ae build: add build/src to include path
This allows including generated include files.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-08 10:16:10 +01:00
David Brownell
456ec016c2 ARM: cope with stupidheaded compiler
Some versions of GCC don't understand that if you mask with 0x3
then have cases 0-3, it's not possible for a variable assigned in
all those branches to have no value at end-of-case.  Feh.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 18:14:46 -08:00
David Brownell
81aec6be04 ARM: list number of HW breakpoints/watchpoints
When starting up, say how many hardware breakpoints and watchpoints
are available on various targets.

This makes it easier to tell GDB how many of those resources exist.
Its remote protocol currently has no way to ask OpenOCD for that
information, so it must configured by hand (or not at all).

Update the docs to mention this; remove obsolete "don't do this" info.
Presentation of GDB setup information is still a mess, but at least
it calls out the three components that need setup.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:44 -08:00
David Brownell
bbb754aa39 target: add debug_reason_name()
Provide and use debug_reason_name() instead of expecting targets
to call Jim_Nvp_value2name_simple().  Less dependency on Jim, and
the code becomes more clear too.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:44 -08:00
David Brownell
19ad7f828b ARM: don't clone arm_arch_state() code
Have various ARM cores delegate to arm_arch_state() to display
basic information, instead of duplicating that logic.

This shrinks the code, makes them all report when semihosting
is active, and highlights which data are specific to this core.
(Like ARM720 not having separate instruction and data caches.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:44 -08:00
David Brownell
927ae6899d User's Guide: add quickie setup notes
Add a brief "setup with no customization" note showing the
how easily things can work if standard OpenOCD config scripts
already exist.  We've had some new users comment that this
information is needlessly hard to find, so that starting to
use OpenOCD is more difficult than it should be.

Plus describe a few other issues that come up when setting
up an OpenOCD server.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:44 -08:00
David Brownell
0a1b7dcfc4 ARM: use <target/arm.h> not armv4_5.h
Move most declarations in <target/armv4_5.h> to <target/arm.h>
and update users.

What's left in the older file is stuff that I think should be
removed ... the old register cache access stuff, which makes it
awkward to support microcontroller profile (Cortex-M) cores.

The armv4_5_run_algorithm() declaration was moved too, even
though it's not yet as generic as it probably ought to be.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:44 -08:00
David Brownell
0529c14bfe ARM: rename some generic routines
Rename some (mostly) generic ARM functions:

    armv4_5_arch_state()       --> arm_arch_state()
    armv4_5_get_gdb_reg_list() --> arm_get_gdb_reg_list()
    armv4_5_init_arch_info()   --> arm_init_arch_info()

Cores using the microcontroller profile may want a different
arch_state() routine though.

(Also fix strange indentation in arm_arch_state: use tabs only!
And update a call to it, removing assignment-in-conditional.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:44 -08:00
David Brownell
a4a2808c2a ARM: move opcode macros to <target/arm_opcodes.h>
Move the ARM opcode macros from <target/armv4_5.h>, and a few
Thumb2 ones from <target/armv7m.h>, to more appropriate homes
in a new <target/arm_opcodes.h> file.

Removed duplicate opcodes from that v7m/Thumb2 set.  Protected
a few macro argument references by adding missing parentheses.

Tightening up some of the line lengths turned up a curious artifact:
the macros for the Thumb opcodes are all 32 bits wide, not 16 bits.
There's currently no explanation for why it's done that way...

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:43 -08:00
David Brownell
7b0314c377 ARM: remove mrc_opcode(), use MRC() or MCR()
Get rid of mrc_opcode() in favor of ARMV4_5_MRC() or, where
arm*20t should have used it, ARMV4_5_MCR() instead.

Basically, *writing* coprocessor registers shouldn't have
used the *read* opcode ... and both should stick to standard
opcode constructors, not rearranging parameter sequence any
more than already needed.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:43 -08:00
David Brownell
7936ab16da ARM: disassemble two more v6+ instructions
The SRS and RFE instructions speed exception entry/exit by
making it easy to save and restore PC and SPSR.  This handles
both ARM and Thumb2 encodings.

Fix minor PLD goofage; that "should never reach this point"
can't happen, so remove it.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:43 -08:00
David Brownell
efb93efd6f ARM DPM: don't write low bits of watchpoint value
The low two bits are defined as should-be-zero-or-presereved.
We'll take the zero option, it's easier to enforce.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:43 -08:00
David Brownell
ecd709fa55 OMAP2420: define reset-assert event
Behave like OMAP3530:  force global software reset.  Given the
patch to teach ARM11 how to use these events, and use VCR to
catch the reset vector, this works better than either the
current reset logic or than using SRST.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:43 -08:00
David Brownell
5da53f17f0 User's Guide: mention ETM on ARM11 comes up too
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-07 14:57:43 -08:00
Zachary T Welch
30a6e683b8 add 'flash list', rewrite 'flash banks'
Rename the existing 'flash banks' implementation as 'flash list', and
replace the broken 'flash_banks' TCL wrapper with a new command handler.

Adds documentation for the new 'flash list' command in the user guide.
2009-12-06 21:39:35 -08:00
Zachary T Welch
2bc4dee7e6 allow 'flash_banks' command to give GDB output
The 'flash banks' command produces a list that needs to be formatted
properly for GDB's 'mem info' to work properly.  The flash_banks TCL
wrapper provided this formatting, but wrappers no longer work for
second-level commands as they did in the past.  With this patch,
the 'flash_banks' command can be used with the new command syntax
and display the required information.
2009-12-06 20:19:18 -08:00
Zachary T Welch
56c5f6361e fix NOR flash regression
When factoring the bank setup command into flash_bank_add(), I forgot
to include a call to the new helper.
2009-12-06 20:15:08 -08:00
David Brownell
dd9d1a3459 misc code review updates
More updates from the code review by Steve Grubb <sgrubb@redhat.com>.
The Jim float-comparision bug just gets a comment not a fix, though.

Cc: Steve Grubb <sgrubb@redhat.com>.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-05 14:40:06 -08:00
Mathias Kuester
12b67a2b41 NOR: add 29LV400BC flash device
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-05 11:12:59 -08:00
Nicolas Pitre
ec8c3b5a67 ARM semihosting: use breakpoint on ARM7
Fall back to software breakpoint when vector catch isn't available.

Possible enhancements:

 - add extra optional command parameter to select high vectors
 - add extra optional command parameter to select hardware breakpoint

Signed-off-by: Nicolas Pitre <nico@marvell.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 23:07:10 -08:00
Nicolas Pitre
e8599cc3d8 ARM semihosting: work with both low and high vectors
Signed-off-by: Nicolas Pitre <nico@marvell.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 23:07:10 -08:00
Zachary T Welch
899c9975e7 rename nand.h to flash//nand/core.h
Rename nand.h as flash/nand/core.h, chase consumers.  The public APIs
need to be sorted out with imp.h, but this allows other changes to
begin improving the separation between policy and mechanism.

Moves #include <target/target.h> and #include "driver.h" into the
internal headers or source files, removing it from <flash/nand/core.h>.
2009-12-04 22:26:25 -08:00
Zachary T Welch
da3bcb392e move remaining nand helper files
Move remaining NAND implementation files into src/flash/nand/.
2009-12-04 21:47:47 -08:00
Zachary T Welch
747d6f2286 split nand.c into nand/{core,fileio,tcl}.c
Moves commands into nand/tcl.c and core implementation to 'nand/core.c'
and 'nand/fileio.c'.  Eliminates 'flash/nand.c'.

Adds 'nand/imp.h' to share routines between TCL commands and core.
2009-12-04 21:41:23 -08:00
Zachary T Welch
a7fd30c07f split NAND driver handling into nand/driver.[ch]
This work parallels the NOR directory, encapsulating the NAND drivers
into a separate file.  This takes an extra step by encapsulating the
type of data structure used to manage the drivers, allowing it to be
changed from an array to a dynamic list in the future.
2009-12-04 21:41:23 -08:00
David Brownell
af1d7590ed ARM: doc updates for main header
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 20:44:29 -08:00
David Brownell
3edcff8b8e ARM: rename armv4_5_build_reg_cache() as arm_*()
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 20:33:02 -08:00
David Brownell
c2cc677056 ARM: rename armv4_5_algorithm as arm_algorithm
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 20:19:49 -08:00
David Brownell
340e2eb762 ARM: misc generic cleanup
Remove an undesirable use of the CPSR symbol ... it needs to vanish.
Flag mode-to-number stuff as obsolete; say why ... should also vanish.

Get rid of no-longer-used mode and state typedefs.

Comment a few of the implicit ties to "classic ARM".

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 20:14:46 -08:00
David Brownell
e51b9a4ac7 ARM: ARMV4_5_COMMON_MAGIC --> ARM_COMMON_MAGIC
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 19:46:44 -08:00
David Brownell
87589043fa ARM: switch target_to_armv4_5() to target_to_arm()
And remove that old symbol.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 19:43:03 -08:00
David Brownell
56e0171420 ARM: rename armv4_5_state_* as arm_state_*
And make arm_state_strings[] be const.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 19:39:25 -08:00
David Brownell
d4d16f1036 ARM: rename armv4_5_mode_* AS arm_mode_*
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 19:33:33 -08:00
David Brownell
0073e7a69e ARM: rename ARMV4_5_MODE_* as ARM_MODE_*
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 19:21:14 -08:00
David Brownell
31e3ea7c19 ARM: rename ARMV4_5_STATE_* as ARM_STATE_*
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 19:14:48 -08:00
David Brownell
f67f6fe5bb ARM11: report watchpoint trigger insn
As with Cortex-A8, the WFAR register holds useful information
that should be recorded and, where relevant, displayed.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 18:57:31 -08:00
David Brownell
a0edb8a328 ARM11: basic watchpoint support
Use the DPM watchpoint support; remove old incomplete stubs.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 18:57:31 -08:00
David Brownell
f4651c869f ARM11: tweak TAP ops and debugging
Tweak scanchain 7 debug messaging:

 - show register addresses in decimal, matching ARM docs;
 - remove some pointless noise

Avoid some needless roundtrips:

 - skip SCAN_N when SCREG already holds that number (speeds up
   polling and other common operations)
 - avoid zeroing vcr twice on resume

Show the IR opcode as a label ("RESTART") too; and in decimal,
matching ARM docs.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 18:57:30 -08:00
Zachary T Welch
87a0119fa2 reorder build order of src directory
Descend into the library modules in order, from bottom-to-top.
2009-12-04 16:56:24 -08:00
Zachary T Welch
f3e6f584f1 remove flash.h from tree
Remove the now vestigial <flash/flash.h> header from the tree,
replacing a few references with <flash/nor/core.h>
2009-12-04 16:56:24 -08:00
Zachary T Welch
ae6374e25d split flash.h into into flash/nor/*.h
Move the bulk of the flash.h file into flash/nor/core.h, leaving an
empty husk that will be removed in the next patch.

The NOR driver structure is an implementation detail, so move it into
its own private header file <flash/nor/driver.h> along with helper
declaration for finding them by name.
2009-12-04 16:56:24 -08:00
Zachary T Welch
d9dc604a4d remove target.h from flash.h
The flash.h header does not require the target.h header file, but
its implementation source files do.  Move it to flash/nor/imp.h.
2009-12-04 16:56:23 -08:00
Zachary T Welch
1527272fb2 split NOR and NAND flash headers
Moves common flash errors to <flash/common.h> to decouple these two
mostly unrelated trees of code.
2009-12-04 16:56:23 -08:00
Zachary T Welch
5fdee60fd4 eliminate src/flash/flash.c
Move remaining NOR flash implemenation into flash/nor/core.c
Removes flash.c from the build, leaving only its header to split.
2009-12-04 16:56:23 -08:00
Zachary T Welch
c90702eaa7 add flash/nor/drivers.c
Encapsulates access to the flash_drivers array, providing a base
of operations for future dynamic driver module loading features.
2009-12-04 16:56:23 -08:00
Zachary T Welch
04ee41de52 move more nor flash implementation details
Splits the exec mode commands out of flash.c into the flash/nor/ files.
The routines used by these high-level commands are moved into nor/core.c,
with their internal declarations placed in nor/imp.h.

Fixes distribution of <flash/nor/core.h> header.
2009-12-04 16:56:23 -08:00
David Brownell
32f961daba ARM: semihosting entry cleanup
Clean up arm_semihosting() entry a bit, comment some issues and just
which SVC opcodes are getting intercepted.  Microcontroller profile
cores will need a new entry, since they use BKPT instead (and don't
have either SVC mode or an SPSR register).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 16:51:48 -08:00
David Brownell
bdde9460b9 ARM: remove semihosting globals
Store a flag and errno in in "struct arm".
Have "poll" output report when semihosting is active.
Shrink some of the affected lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 16:51:48 -08:00
David Brownell
acd6d33994 User's Guide: more semihosting info
List it in the concept index, in the section about target software
changes a project might want to consider, and in the section about
debug messaging.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 10:11:31 -08:00
Øyvind Harboe
146e841fc9 bootstrap: stop execution upon error
When tools are not installed, exit immediately. This makes
the error messages clearer.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-04 12:46:45 +01:00
Zachary T Welch
c65d94f7d0 add flash/nor/core.[ch]
The newly moved flash TCL routines access the internals of the module
too much.  Fix the layering issues by adding new core NOR flash APIs:

<flash/nor/core.h>:
  - flash_driver_find_by_name() - self-descriptive

<flash/nor/imp.h>:
  - flash_bank_add()            - encapsulates adding banks to bank list
  - flash_bank_list()           - encapsulates retreiving bank list

This allows the externs in flash/nor/imp.h to be removed, and
these mechanisms may now be re-used by other flash module code.
2009-12-04 03:34:33 -08:00
Zachary T Welch
3cb0b56005 add flash/nor/{tcl.c,imp.h} from flash/flash.c
Moves the top-level 'flash' command handlers into flash/nor/tcl.c,
with flash/nor/imp.h providing an internal implementation header
to share non-public API components.
2009-12-04 03:34:33 -08:00
Zachary T Welch
79a73a786e separate Jim from jtag/core.c
After previous efforts, only one Jim routine remained in jtag/core.c,
and moving it to jtag/tcl.c painlessly finishes separating these layers.
The headers need separating, but the implementation is clean.
2009-12-04 03:34:32 -08:00
Zachary T Welch
b58c1d808f switch 'rm' command away from using Jim
Commands that do not need to use Jim should be registered as
high-level command handlers.
2009-12-04 03:34:32 -08:00
Zachary T Welch
c5eb8e29bd check top-level command registrations
When calling module_register_commands, the return value needs to be
checked for failures.  Instead of duplicating code, use an array of
function pointers to the identical registration functions to iterate
over during startup.
2009-12-04 03:29:15 -08:00
Zachary T Welch
eae56d27c3 allow 'jtag init' to be run in any mode
Help alleviate further potential problems with interactive startup.
2009-12-04 03:29:15 -08:00
David Brownell
a535d2f643 target: cygwin build fixes
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-04 00:42:36 -08:00
Øyvind Harboe
24551b7b92 zy1000: FPGA revC wip
The bug in revC register memory access is pretty much
cornered now.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-04 08:21:25 +01:00
Nicolas Pitre
ed59dfc80a basic ARM semihosting support
Semihosting enables code running on an ARM target to use the
I/O facilities on the host computer. The target application must
be linked against a library that forwards operation requests by
using the SVC instruction that is trapped at the Supervisor Call
vector by the debugger.  The "hosted" library version provided
with CodeSourcery's Sourcery G++ Lite for ARM EABI is one example.

This is currently available for ARM9 processors, but any ARM
variant should be able to support this with little additional work.

Tested using binaries compiled with Sourcery G++ Lite 2009q1-161
and ARM RVCT 3.0.

[dbrownell@users.sourceforge.net: doc tweaks, NEWS]

Signed-off-by: Nicolas Pitre <nico@marvell.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 18:42:01 -08:00
David Brownell
f62c035c52 doxygen: remove some warnings
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 18:31:38 -08:00
Dean Glazeski
cf2cb0fc84 Make ARM NAND I/O operations aware of last op
Updates the ARM NAND I/O code to look at and update the op
field of arm_nand_data to reflect the last operation performed.
It uses this field to copy the correct code to the target in the
case where the struct is used for reads and writes.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 17:29:42 -08:00
Dean Glazeski
66985bb306 ARM NAND I/O interface update
Modify the arm_nand_data struct to better support both read and
write operations while using the same struct.  An additional
field was added, and initialized, to record the last operation
so that the correct code can be loaded to the working area.

[dbrownell@users.sourceforge.net: merge init patch, tweak GPL note]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 17:29:41 -08:00
Dean Glazeski
9a51b8b0e3 NAND page command refactoring.
Created a new function that handles sending a command and the address
information for pages to a NAND device.

[dbrownell@users.sourceforge.net: tweaked line lengths, name 'oob_only']

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 16:44:27 -08:00
David Brownell
7e2dffbbff ARMv7-A: tweak arch_state()
Punt to the armv4_5_arch_state() for all the common stuff, to
shrink code and so we will get any improvements it provides.

Don't hide watchpoint status if we happen to be in "abort" mode.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 16:18:24 -08:00
David Brownell
ea7a49cb9b ARM DPM: share debug reason logic
No point in both ARM11 and Cortex-A8 having private copies
of the logic sorting out e.g. DBG_REASON_WATCHPOINT.

Add and use a shared routine for this ... there's actually
a bunch more debug entry logic that could be shared, this
is just a start on that.  Note that this routine fixes a
bug observed in the ARM11 code, where some abort mode quirks
were displayed as being an unknown debug reason; and also
silences needless ARM11 chatter.

Likewise with private copies of DSCR ... add one to the DPM
struct.  Save it as part of setting DBG_REASON_* so later
patches can switch over to using that copy.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 16:08:04 -08:00
David Brownell
6eee0729d7 ARM11: use shared DSCR bit names
For the bits now defined in "arm_dpm.h", switch to the
shared DSCR_* symbol and remove the ARM11_DSCR_* version.

Define DSCR_INT_DIS and use it instead of the ARM11_DSCR_*
sibling symbol.  (Note:  for both ARM11 and Cortex-A8, this
should arguably be enabled by default when single stepping.)

Remove some other unused declarations in "arm11.h".

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 16:08:04 -08:00
David Brownell
eb6c880ddc ARM DPM: make DSCR bit defs sharable
Move the symbols for these bits from "armv7a.h" to "arm_dpm.h",
where they can be seen and used not just by Cortex-A but also
by the ARM11 (armv6) code.

Change them from bit numbers to bit masks ... this matches the
usage in ARM11 code, and also makes it easier to read.

Rename DSCR_EXT_INT_EN as DSCR_ITR_EN to match the docs; it's
enabling ITR functionality, not external interrupts, so this
changes the name to be less misleading.  (There *IS* a bit
affecting interrupts, and this isn't it.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 16:08:04 -08:00
David Brownell
adbf40a045 fix another init regression
This makes Beagle work again, instead of losing horribly because
the JTAG event handlers are no longer able to e.g. "runtest".  I
get the previous quirky behavior ... comes up OK but "reset halt"
somewhat mysteriously makes it all better.  (Instead of nothing
being able to work at all...)  However, I'm still seeing:

 The 'init' command must be used before 'init'.

That seems to come from invoking "jtag init", sometime after it
gets mapped to "ocd_jtag init", according to debug message traces.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-03 14:44:03 -08:00
Zachary T Welch
de27ebfa83 fix double 'init' regression
To prevent regression in the behavior of 'init', we allow it to run in
any mode.  If provided with -c init and with -c noinit, then the second
init at startup caused a spurious mode failure.  Let 'init' handle it.
2009-12-03 05:28:51 -08:00
Zachary T Welch
23f07d08e3 fix regressions with GDB port numbers
Use a separate variable for iterating GDB service port numbers than
the one set by the user.  Restores the behavior of returning the
original port number and only incrementing the port used on success.
2009-12-03 05:28:51 -08:00
Øyvind Harboe
434f570e51 zy1000: include files have moved about
now compiles again after include files were moved about
to reduce -I usage and stop using quotes but rather
angle brackets for include files.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-03 13:47:25 +01:00
Zachary T Welch
822c06d9e3 remove tertiary include paths
With all #include directives converted, we only need to have the
top-level src/ directory in the search path.
2009-12-03 04:24:50 -08:00
Zachary T Welch
f7bd1e8f3a change #include "../hello.h" to "hello.h"
Before we can -I the top-level src/ directory alone, references to
"hello.h" must be updated.  This is an internal header, so it does
not need angle brackets.
2009-12-03 04:24:50 -08:00
Zachary T Welch
12499f97fd change #include "xsvf.h" to <xsvf/xsvf.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "xsvf.h"

the following form should be used.

	#include <xsvf/xsvf.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:49 -08:00
Zachary T Welch
66e45ba611 change #include "svf.h" to <svf/svf.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "svf.h"

the following form should be used.

	#include <svf/svf.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:49 -08:00
Zachary T Welch
49675db972 change #include "pld.h" to <pld/pld.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "pld.h"

the following form should be used.

	#include <pld/pld.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:49 -08:00
Zachary T Welch
8256a792c5 change #include "telnet_server.h" to <server/telnet_server.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "telnet_server.h"

the following form should be used.

	#include <server/telnet_server.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:49 -08:00
Zachary T Welch
c538a830cd change #include "server.h" to <server/server.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "server.h"

the following form should be used.

	#include <server/server.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:49 -08:00
Zachary T Welch
6db3ed48c6 change #include "httpd.h" to <server/httpd.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "httpd.h"

the following form should be used.

	#include <server/httpd.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:49 -08:00
Zachary T Welch
5e7369d99a change #include "gdb_server.h" to <server/gdb_server.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "gdb_server.h"

the following form should be used.

	#include <server/gdb_server.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:49 -08:00
Zachary T Welch
2a402ae2c7 change #include "s3c24xx_regs.h" to <flash/nand/s3c24xx_regs.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "s3c24xx_regs.h"

the following form should be used.

	#include <flash/nand/s3c24xx_regs.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:49 -08:00
Zachary T Welch
afb6d38bd5 change #include "ocl.h" to <flash/nor/ocl.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "ocl.h"

the following form should be used.

	#include <flash/nor/ocl.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:49 -08:00
Zachary T Welch
450ceda9ae change #include "nand.h" to <flash/nand.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "nand.h"

the following form should be used.

	#include <flash/nand.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:42 -08:00
Zachary T Welch
9cbab8d3a6 change #include "mflash.h" to <flash/mflash.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "mflash.h"

the following form should be used.

	#include <flash/mflash.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:42 -08:00
Zachary T Welch
2b2d5ec1e3 change #include "flash.h" to <flash/flash.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "flash.h"

the following form should be used.

	#include <flash/flash.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:42 -08:00
Zachary T Welch
eac262e5d2 change #include "arm_nandio.h" to <flash/arm_nandio.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "arm_nandio.h"

the following form should be used.

	#include <flash/arm_nandio.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:42 -08:00
Zachary T Welch
7a4f4457e5 change #include "trace.h" to <target/trace.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "trace.h"

the following form should be used.

	#include <target/trace.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:42 -08:00
Zachary T Welch
5a94612148 change #include "target_request.h" to <target/target_request.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "target_request.h"

the following form should be used.

	#include <target/target_request.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:42 -08:00
Zachary T Welch
c6dd6a576d change #include "target.h" to <target/target.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "target.h"

the following form should be used.

	#include <target/target.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:42 -08:00
Zachary T Welch
fa43bdff54 change #include "register.h" to <target/register.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "register.h"

the following form should be used.

	#include <target/register.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
aaf948a6be change #include "mips_ejtag.h" to <target/mips_ejtag.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "mips_ejtag.h"

the following form should be used.

	#include <target/mips_ejtag.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
36e53978b9 change #include "mips32_pracc.h" to <target/mips32_pracc.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "mips32_pracc.h"

the following form should be used.

	#include <target/mips32_pracc.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
a8880f0b5a change #include "mips32.h" to <target/mips32.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "mips32.h"

the following form should be used.

	#include <target/mips32.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
7da02a8330 change #include "image.h" to <target/image.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "image.h"

the following form should be used.

	#include <target/image.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
0241b1e105 change #include "etm.h" to <target/etm.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "etm.h"

the following form should be used.

	#include <target/etm.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
1650ab3a22 change #include "embeddedice.h" to <target/embeddedice.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "embeddedice.h"

the following form should be used.

	#include <target/embeddedice.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
26e4fac57e change #include "breakpoints.h" to <target/breakpoints.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "breakpoints.h"

the following form should be used.

	#include <target/breakpoints.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
54063d7294 change #include "avrt.h" to <target/avrt.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "avrt.h"

the following form should be used.

	#include <target/avrt.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
f52a596860 change #include "armv7m.h" to <target/armv7m.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "armv7m.h"

the following form should be used.

	#include <target/armv7m.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
a1c40f5120 change #include "armv7a.h" to <target/armv7a.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "armv7a.h"

the following form should be used.

	#include <target/armv7a.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
377c5504b9 change #include "armv4_5_mmu.h" to <target/armv4_5_mmu.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "armv4_5_mmu.h"

the following form should be used.

	#include <target/armv4_5_mmu.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
56adfadb5d change #include "armv4_5_cache.h" to <target/armv4_5_cache.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "armv4_5_cache.h"

the following form should be used.

	#include <target/armv4_5_cache.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
ddea033043 change #include "armv4_5.h" to <target/armv4_5.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "armv4_5.h"

the following form should be used.

	#include <target/armv4_5.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:41 -08:00
Zachary T Welch
15accefbe2 change #include "arm_jtag.h" to <target/arm_jtag.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "arm_jtag.h"

the following form should be used.

	#include <target/arm_jtag.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
98eea5680b change #include "arm_dpm.h" to <target/arm_dpm.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "arm_dpm.h"

the following form should be used.

	#include <target/arm_dpm.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
0c1bc6703c change #include "arm_adi_v5.h" to <target/arm_adi_v5.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "arm_adi_v5.h"

the following form should be used.

	#include <target/arm_adi_v5.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
2c35b35e11 change #include "arm9tdmi.h" to <target/arm9tdmi.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "arm9tdmi.h"

the following form should be used.

	#include <target/arm9tdmi.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
41e92d8a7a change #include "arm966e.h" to <target/arm966e.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "arm966e.h"

the following form should be used.

	#include <target/arm966e.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
447f0896dd change #include "arm7tdmi.h" to <target/arm7tdmi.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "arm7tdmi.h"

the following form should be used.

	#include <target/arm7tdmi.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
9e3136a5f8 change #include "arm7_9_common.h" to <target/arm7_9_common.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "arm7_9_common.h"

the following form should be used.

	#include <target/arm7_9_common.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
28b1794505 change #include "arm11.h" to <target/arm11.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "arm11.h"

the following form should be used.

	#include <target/arm11.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
2958665f6b change #include "algorithm.h" to <target/algorithm.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "algorithm.h"

the following form should be used.

	#include <target/algorithm.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
2641fd9576 change #include "minidriver.h" to <jtag/minidriver.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "minidriver.h"

the following form should be used.

	#include <jtag/minidriver.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:40 -08:00
Zachary T Welch
cb4a475f6c change #include "jtag.h" to <jtag/jtag.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "jtag.h"

the following form should be used.

	#include <jtag/jtag.h>

The exception is from .c files in the same directory.
2009-12-03 04:24:33 -08:00
Zachary T Welch
165fb9309d change #include "interface.h" to <jtag/interface.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "interface.h"

the following form should be used.

	#include <jtag/interface.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:52 -08:00
Zachary T Welch
c9e448222c change #include "commands.h" to <jtag/commands.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "commands.h"

the following form should be used.

	#include <jtag/commands.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:52 -08:00
Zachary T Welch
df0e90ec8c change #include "types.h" to <helper/types.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "types.h"

the following form should be used.

	#include <helper/types.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:52 -08:00
Zachary T Welch
6512e5e36b change #include "time_support.h" to <helper/time_support.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "time_support.h"

the following form should be used.

	#include <helper/time_support.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:52 -08:00
Zachary T Welch
ba00ba47d2 change #include "replacements.h" to <helper/replacements.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "replacements.h"

the following form should be used.

	#include <helper/replacements.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:52 -08:00
Zachary T Welch
6c3a28ca26 change #include "membuf.h" to <helper/membuf.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "membuf.h"

the following form should be used.

	#include <helper/membuf.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:52 -08:00
Zachary T Welch
c79cca04be change #include "log.h" to <helper/log.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "log.h"

the following form should be used.

	#include <helper/log.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:52 -08:00
Zachary T Welch
35f1a40f6f change #include "jim.h" to <helper/jim.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "jim.h"

the following form should be used.

	#include <helper/jim.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:52 -08:00
Zachary T Welch
2fc071c6e1 change #include "ioutil.h" to <helper/ioutil.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "ioutil.h"

the following form should be used.

	#include <helper/ioutil.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:52 -08:00
Zachary T Welch
14ed20967f change #include "fileio.h" to <helper/fileio.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "fileio.h"

the following form should be used.

	#include <helper/fileio.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:51 -08:00
Zachary T Welch
0b7720d2ff change #include "configuration.h" to <helper/configuration.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "configuration.h"

the following form should be used.

	#include <helper/configuration.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:51 -08:00
Zachary T Welch
264d24495d change #include "command.h" to <helper/command.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "command.h"

the following form should be used.

	#include <helper/command.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:48 -08:00
Zachary T Welch
d1bc4375e9 change #include "binarybuffer.h" to <helper/binarybuffer.h>
Changes from the flat namespace to heirarchical one.  Instead of writing:

	#include "binarybuffer.h"

the following form should be used.

	#include <helper/binarybuffer.h>

The exception is from .c files in the same directory.
2009-12-03 04:22:17 -08:00
Zachary T Welch
5d57cad001 normalize headers to make changing easier
These headers need minor tweaks to paves the way for wholesale
scripted coversion of the header files.
2009-12-03 04:20:31 -08:00
Zachary T Welch
4bbe7d174f change autoconf #include in configure.in
Updates "system.h" and "replacements.h" with <helpers/system.h> and
<helpers/replacements.h> respectively.
2009-12-03 01:59:24 -08:00
Zachary T Welch
896ac8d4ef allow #include directives to use module name
Includes the src directory in the search path, so header files may be
migrated from:

  #include "foo.h"

to
  #include <module/foo.h>

which is more conducive for installation.
2009-12-03 01:54:15 -08:00
Nicolas Pitre
a976ce2dd4 feroceon.c should be part of ARM7_9_SRC
The Feroceon and Dragonite cores are similar to the ARM926 and ARM966
cores respectively.

Signed-off-by: Nicolas Pitre <nico@marvell.com>
2009-12-03 09:57:17 +01:00
Zachary T Welch
879a04cc6b remove #if HAVE_JTAG_INTERFACE_H from minidriver.h
Adds two "minidriver_imp.h" files, so the right one is allowed to be
"#included" by the Makefile logic.
2009-12-02 23:27:09 -08:00
Zachary T Welch
865efd828a move jtag drivers to src/jtag/drivers
Moves JTAG interface drivers to src/jtag/drivers/,
Adds src/jtag/drivers/Makefile.am.
Builds libocdjtagdrivers.la.

Flattens the rlink driver files into the drivers/ directory, adding
the 'rlink_' prefix or '.rlink' suffix as appropriate.
2009-12-02 23:27:09 -08:00
Zachary T Welch
fe9228a32d move nor drivers to src/flash/nor
Moves NOR flash drivers to 'src/flash/nor/'.
Adds 'src/flash/nor/Makefile.am'.
Builds 'libocdflashnor.la'.
2009-12-02 23:27:09 -08:00
Zachary T Welch
e1ec02bb05 move nand drivers to src/flash/nand/
Moves NAND drivers to src/flash/nand/.
Adds src/flash/nand/Makefile.am.
Builds libocdflashnand.la.
2009-12-02 23:27:09 -08:00
David Brownell
d5e4e23f9a ARM11: don't expose DSCR
Remove the remaining extra copy of DSCR, and the register cache
of which it was a part.  That cache wasn't a very safe, or even
necessary, idea; it was essentialy letting debugger-private state
be manipulated by Tcl code that couldn't know how to do it right.

This makes the "reg" output of an ARM11 resemble what most other
ARM cores produce ... forward motion in the "make ARM11 work like
the rest of the ARM cores" Jihad!
2009-12-02 23:08:43 -08:00
David Brownell
f0c3e7011f ARM11: store a clean copy of DSCR
Just store a clean copy of DSCR in the per-CPU struct, so we
trivially pass a pointer to a recent copy.  This replaces the
previous "last_dscr" and cleans up most of the related calling
conventions ... but it doesn't remove the other DSCR copy.
2009-12-02 23:08:43 -08:00
David Brownell
62dd15d78f ARM11: don't expose WDTR
Don't expose the WDTR register through the register cache any
more.  If anyone wants Tcl scripts to be able to use DCC based
communication with app code in the target, this wouldn't do it.

Bugfix:  don't trust the Tcl-accessible version of DSCR to
flag whether WDTR needs to be restored when resuming.
2009-12-02 23:08:42 -08:00
David Brownell
7e18d96d03 ARM11: don't expose RDTR
Don't expose the RDTR register through the register cache any
more.  If anyone wants Tcl scripts to be able to use DCC based
communication with app code in the target, this wouldn't do it.

Bugfix:  don't trust the Tcl-accessible version of DSCR to
flag whether RDTR needs to be restored when resuming.
2009-12-02 23:08:42 -08:00
David Brownell
6ec5b9c674 ARM11: streamline debug entry
Streamline arm11_on_enter_debug_state() entry:

 - It should handle the standard updates:
    * target->debug_reason
    * target->state

 - Don't waste time re-reading DSCR; just pass it in

Also rename the routine to "arm11_debug_entry()", matching the
convention used elsewhere in OpenOCD.
2009-12-02 23:08:42 -08:00
David Brownell
1d29440a9c ARM11: remove arm11->target
Don't need/want arm11->target; we have arm11->arm.target instead.
Also remove some unused watchpoint stuff.
2009-12-02 23:08:42 -08:00
David Brownell
c2af99d471 ARM DPM: tweak initialization
Move the initial breakpoint/watchpoint disable calls to
arm_dpm_initialize(), and start using that routine.  This
split helps with arm11 support.
2009-12-02 23:08:42 -08:00
Zachary T Welch
b123fd3cd9 fix configure problem when building w/o USB
If building OpenOCD without any USB drivers, a warning would appear
because $build_usb is never set to a sane default.  This fixes it.
2009-12-02 22:32:08 -08:00
Zachary T Welch
f4a1070dcf adding files required for distribution
Add headers missing from Makefile rules to pass 'make distcheck'.
These were included in the tree but were not added with those commits.
2009-12-02 18:29:05 -08:00
Zachary T Welch
4c43afce85 fix 'target init' command registration
The command handler registration was put at the top level, rather
than as a subcommand.  Move it to where it belongs.
2009-12-02 16:16:54 -08:00
David Brownell
a79b76d893 stubs: buildfix
The new stubs for httpd and ioutil gave errors like:

  ioutil_stubs.c: In function ‘ioutil_init’:
  ioutil_stubs.c:27: error: implicit declaration of function ‘LOG_DEBUG’
  ioutil_stubs.c:28: error: ‘ERROR_OK’ undeclared (first use in this function)
  ioutil_stubs.c:28: error: (Each undeclared identifier is reported only once
  ioutil_stubs.c:28: error: for each function it appears in.)

Fix.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-02 15:24:14 -08:00
Zachary T Welch
6ec526e706 remove #if BUILD_HTTPD
Add httpd_stubs.c to provide no-op implementations of httpd_start()
and httpd_stop().

Allows these routines to be called unconditionally and ensures the
libocdserver ABI remains unchanged regardless of whether this feature
was built-in or not.

Prints a DEBUG message when the stub implementation is included.
2009-12-02 13:26:26 -08:00
Zachary T Welch
eaf10f69de remove BUILD_IOUTIL symbol
Add ioutil_stubs.c to provide an empty ioutil_init() routine.
Add ioutil.h to prevent applications from needing to declare it.

Allows unconditionally calling that function during startup, and the
resulting libocdhelper library API is now more stable.

Prints a DEBUG message when the stub implementation is included.
2009-12-02 13:26:26 -08:00
Zachary T Welch
34654359a9 remove #if logic for openocd_sleep_*lude
Adds server_stubs.c to hold these routines, using automake logic to
ensure it gets included under the right conditions.
2009-12-02 13:26:26 -08:00
Zachary T Welch
62fbb0f545 target: factor init to 'target init'
Adds 'target init' command handler, called as part of 'init'.
2009-12-02 13:26:23 -08:00
Zachary T Welch
e03f3c57a5 target: factor target_init() into pieces
Moves body of target initialization loop into a helper function,
cleaning up its visual flow in the process.
2009-12-02 13:26:23 -08:00
Zachary T Welch
ac1887c703 jtag: factor init into 'jtag init'
Adds 'jtag init' command handler, which can be called as part of a
fine-grained 'init' process.
2009-12-02 13:26:22 -08:00
Zachary T Welch
37201c019f flash: factor init to 'flash init'
Split flash initialiation into 'flash init', called from 'init'.
2009-12-02 13:26:22 -08:00
Zachary T Welch
1de0b9d351 mflash: factor init to 'mflash init'
Splits mflash initialiation to 'mflash init', called from 'init'.
2009-12-02 13:26:22 -08:00
Zachary T Welch
747f8af672 nand: factor init to 'nand init'
Split NAND initialization into 'nand init', which gets called from
the main 'init' command.
2009-12-02 13:26:22 -08:00
Zachary T Welch
682910fdc2 pld: factor init to 'pld init'
Split PLD initialization into 'pld init', which gets called from 'init'.
2009-12-02 13:26:22 -08:00
David Brownell
55eeea7fce ARMv7a/Cortex-A8: report watchpoint trigger insn
Save and display the address of the instruction which triggered the
watchpoint.  Because of pipelining, that's well behind the PC value
when debug entry completes.  (Example in a subroutine that had been
returned from...)

Remove unused A8 stuff, mostly watchpoint hooks from the header.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-02 11:31:32 -08:00
David Brownell
03c103d56a ARM: label SP and LR correctly
Except for USR/SYS mode, the labels for the shadowed SP and LR
registers were reversed.  LR is r14; SP is r13.  Fix.

This would not affect GDB users; GDB references are positional.
Only folk working directly with OpenOCD register values would
have noticed this bug.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-02 11:31:32 -08:00
Øyvind Harboe
d84fead487 zy1000: keep up with startup refactoring work.
keep up with server_init() introduction.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-02 12:45:12 +01:00
David Brownell
f4b52e1ceb Cortex-A8: basic watchpoint support
Actually this should handle both breakpoints and watchpoints ... but
the DPM framework only handles watchpoints for now.  Works on Beagle.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 21:47:45 -08:00
David Brownell
66ca84b581 ARM: core DPM support for watchpoints
This is a NOP unless the underlying core exposes two new methods, and
neither of the two cores using this (ARM11xx, Cortex-A8) do so yet.

This patch only updates those cores so they pass a flag saying whether
or not to update breakpoint and watchpoint status before resuming; and
removing some now-needless anti-segfault code from ARM11.  Cortex-A8
didn't have that code ... yes, it segfaulted when setting watchpoints.

NOTE:  this uses a slightly different strategy for setting/clearing
breakpoints than the ARM7/ARM9/etc code uses.  It leaves them alone
unless it's *got* to change something, to speed halt/resume cycles
(including single stepping).

ALSO NOTE:  this under-delivers for Cortex-A8, where regions with size
up to 2 GBytes can be watched ... it handles watchpoints which ARM11 can
also handle (size 1/2/4 bytes).  Should get fixed later.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 21:47:45 -08:00
David Brownell
1c7d3d200c ARMv7a: move constants out of Cortex-A8 header
These are architecturally defined, not core-specific.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 20:39:58 -08:00
David Brownell
a65e75ea34 Tcl and doc: update to match new 'arm mcr ...' etc
Make them match the C code.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 01:10:19 -08:00
Øyvind Harboe
48edd58c39 target: at91eb40a.cfg is a board, not a target.
Also updated to use target name when creating flash
and set jtag_khz to 16000.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-01 10:06:40 +01:00
Øyvind Harboe
445da543d8 zy1000: keep up with latest changes to command handling
Keep up with Jim Tcl interpreter creation cleanup.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-01 09:53:23 +01:00
Øyvind Harboe
5576a6240a command: the Jim interpreter can now be provided rather than created
In embedded hosts, the Jim interpreter can come from the
existing context rather than be created by OpenOCD.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-01 09:53:23 +01:00
David Brownell
63dc352876 ARM11: remove previous mcr()/mrc() methods
We don't need this code, now that the DPM code handles it.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 00:49:16 -08:00
David Brownell
5949a3b3a5 Cortex-A8: remove previous mcr()/mrc() methods
We don't need this code, now that the DPM code handles it.
Neither do we need the ARMv7-A CP15 operations; remove their
remnants too.  And disable a mostly-needless diagnostic.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 00:49:11 -08:00
David Brownell
563d937c3c ARM: implement mrc()/mcr() as DPM ops
Instead of having separate ARM11 and Cortex-A8 implementations of
this code, have one shared implementation which just builds on the
existing "run instruction via R0" support.

This enables followup patches to remove that now-unused code from
those two drivers.  (Patches to move the "mrc" and "mcr" code into
"struct arm" are due too ... MIPS and other cores do not support
those ARM-specific concepts.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 00:49:04 -08:00
David Brownell
177bbd8891 target: "mcr" and "mrc" are ARM-specific
Switch "mrc" and "mcr" commands to be toplevel ARM operations,
as they should initially have been.

Correct the usage message for both commands:  it matches ARM
documentation (as one wants!) instead of reordering them to
match the funky mrc() and mcr() method usage (sigh).

For Cortex-A8: restore a line that got accidentally dropped,
so the secure monitor mode shadow registers will show again.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 00:48:53 -08:00
David Brownell
209a0197f0 ARMv7-A: stop using CP15 ops
The ARMv7-A code uses read_cp15() to access fault registers.
Instead, use DPM operations directly, passing in the relevant
MRC instructions.

This eliminates per-operation overhead (though it'll be hard
to observe, this is uncommon) and helps eliminate read_cp15().

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 00:48:40 -08:00
David Brownell
fb984a477d Cortex-A8: stop using CP15 ops
There were two chunks of Cortex-A8 code which called the
ARMv7-A CP15 operations; get rid of them, helping prepare
to remove those methods completely:

 - post_debug_entry() can use the mrc() method to read
   its two registers.

 - write_memory() can use dpm->instr_write_data_r0() to
   flush the ICache and DCache ... doing it this way is
   actually faster since it reduces per-write overhead.

Note that the mrc() method parameters are re-ordered with
respect to the ARM instruction documentation, so that part
can be confusing.

Cleaned up the layout and comments in those areas a bit.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-12-01 00:48:40 -08:00
Øyvind Harboe
51e9b25c9a main: invoke jtag_interface_quit() explicitly
There is no particular reason to invoke jtag_interface_quit()
on the atexit() handler, it just makes the code more obtuse
and stops other legitimate usage of atexit().

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-12-01 07:51:26 +01:00
Zachary T Welch
330733eadf improve command prohibition error report
Ensures that the correct information gets displayed, depending on the
mode of the command being denied.  Fixes misreporting all commands as
needing to run "before 'init'".
2009-11-30 20:54:40 -08:00
David Brownell
892604bc7e XScale: restore_context() cleanup
Clean up two aspects to this routine:  bad naming, since it
doesn't restore the context, just the banked registers; and
excess indentation for the bulk of the code.

Also make some of its call sites stash the function's return
code; someday they should use it for error checking.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-30 19:14:19 -08:00
David Brownell
da7c202b57 XScale: context restore, cleanup/bugfix
This "loop over all registers" routine shared the same mess as
full_context() in terms of dozens of needless number_to_mode()
calls.  Fix that, and comments, with related cleanup.

The misnamed xscale_restore_context() had a related bug.  It
was restoring the *WRONG REGISTERS* ... always from whatever
the current mode was, instead of using the copy from whichever
register bank it was trying to restore.  (But it marked the
intended register as having been restored...)  Fixed that.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-30 19:14:19 -08:00
Zachary T Welch
8fc5a9a5e9 remove interp global variable!
Finish removing references to the 'interp' global variable from the
command module, encapsulating all reference via command_context.

Eliminates use of the global entirely, so it can be removed.  Hurrah!
2009-11-30 16:29:34 -08:00
Zachary T Welch
cbc894ed7b command output capture: do not use interp global
Adds a log_capture_state structure to pass to the log capture
callback used by the command module.  Ensures that the capture occurs
in the proper context.
2009-11-30 16:29:34 -08:00
Zachary T Welch
7b2906de24 do not extern 'interp' from command.c
Adds 'interp' field to command_context, chasing the few remaining
references to the global variable outside of the command module.
2009-11-30 16:29:34 -08:00
Zachary T Welch
8e8a359af2 target: avoid using interp global variable
Adds 'interp' to target_event_action structure to avoid using the
global variable of the same name.
2009-11-30 16:29:34 -08:00
Zachary T Welch
e1ee270265 jtag: avoid using interp global variable
Adds 'interp' field to jtag_tap_event_action structure to avoid
using the global variable of same name.
2009-11-30 16:29:34 -08:00
Zachary T Welch
be65f497f5 fix foo command group help messages
Splits the old help strings to provide proper usage as well.
2009-11-30 16:29:34 -08:00
Zachary T Welch
5dd6457d2c make syntax errors respond with 'usage'
The 'help' text will become more verbose, so its entire text will be
far more than desired when you only borked your syntax.  The usage
still allows the commands to be looked up for more help.
2009-11-30 16:29:34 -08:00
Zachary T Welch
3d204ec66a move improperly located documentation
Somehow, the comment block for command handlers ended up associated
with the output_handler.  Move it to the command_handler_t declaration.
2009-11-30 16:29:34 -08:00
Zachary T Welch
bc9ae74073 improve command_done() API and docs
command_done() does not need to return an error, but it needed
Doxygen comment.  Provide some for copy_command_context as well.

Note: this audit revealed some potential bugs with the command context
implementation.  There was a reason that commands were added at the
end of the list.  Shallow copying of command_context means that
the list is shared between them.  And commands added at the top-level
before the pre-existing commands will not be available in the shared
context as they were before.  Yikes!

Fortunately, this does not seem to occur in general use, as
'add_help_text' gets registered in startup.tcl and claims the first slot
in my own test cases.  Thus, it seems that we have been masking the issue
for now, but it shows the need for further architectural improvement in
the core command module.
2009-11-30 16:29:34 -08:00
Zachary T Welch
c0630d8a58 only display usable commands in help
With the ability to defer 'init', users can access the help system while
still in CONFIG mode.  This patch omits commands from the help and usage
list when they cannot be run in the current command mode, making it much
easier to see what can be done at a given time.
2009-11-30 16:29:24 -08:00
Zachary T Welch
cee1f39f18 allow deferal of init
Adds 'noinit' command to prevent OpenOCD from running 'init' at the end
up startup, allowing it to be given from telnet or TCL.  This provides
the old behavior by default, and users can add this command to their
scripts to get the new behavior.
2009-11-30 16:29:24 -08:00
Zachary T Welch
64653b0bbb move server_init() to openocd_main()
Moves the telnet and TCL server startup to server_init(), moving their
respective command registration in to server_register_commands().
Adds proper error checking for these particular startup processes.

Moves the core server startup to openocd_main(), improving related error
checking and preparing to defer 'init'.
2009-11-30 16:29:24 -08:00
Zachary T Welch
ec6c1962c2 improve gdb_init() sequence
Rework gdb_init to create flexible APIs (gdb_target_add_{one,all}) and
static helper (gdb_target_start) for starting GDB services.  Eliminates
duplicated code and provides general mechanisms for adding GDB services.
The 'init' command is updated to call the new API, and later patches can
decouple its policy of adding all targets therein.

Provides the new capability to use both piped and TCP servers when
multiple targets are defined.  The first target fills the pipe, and
others will be started on TCP ports (unless disabled, i.e. gdb_port=0).
2009-11-30 16:29:24 -08:00
Øyvind Harboe
2264270fe4 zy1000: keep up with changes to command structure
Add missing COMMAND_REGISTRATION_DONE.

For now the command syntax for zy1000 needs to be compatible
across 0.3/0.4, the world outside OpenOCD interfaces to
zy1000 using the old syntax. Post 0.4 release(0.4.1 even)
I'll switch to subcommand scheme.

Switch to subcommands post 0.3 lifecycle.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-30 08:54:52 +01:00
David Brownell
5219b35be6 XScale: clean up full_context() (#2)
Streamline the loop by continuing as soon as we know there's no
work to be done; this lets us un-indent almost everything.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-29 13:06:12 -08:00
David Brownell
8c8e53baf6 XScale: clean up full_context() (#1)
When fetching all the registers, XScale was doing various stupid
things like calling number_to_mode() a few dozen times instead of
just once, and mapping access to each register three times (again,
instead of just once).  Stop that.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-29 13:04:56 -08:00
David Brownell
e456da073a XScale: debug entry uses new register mapping
Use the new mapping interfaces in the debug entry path.
SPSR and the banked registers now have smaller and faster
accessors ... use them.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-29 12:58:30 -08:00
Marek Vasut
8c2846ed45 create target/pxa3xx.cfg
[dbrownell@users.sourceforge.net; remove pxa255 comment]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-29 12:57:05 -08:00
Marek Vasut
17b7600a59 XScale: initial PXA3xx support
[dbrownell@users.sourceforge.net: user's guide; variant param is optional]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-29 12:57:05 -08:00
David Brownell
73ec6d9b89 ARM11: fix warning on cygwin
Previous version of JTAG_DEBUG() macro hid this bug.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-29 09:14:52 -08:00
David Brownell
3debd59c5e bugfix: 'init' changes state, not main()
Code other than main() may invoke "init".  When it does so,
customized handlers may need to run ... so make sure the
command context state is updated before they do so.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-28 23:11:31 -08:00
lementec fabien
b0858e89c7 fix s3c24xx device command helper
Returns the common structure for the s3c24xx device, which was
somehow nuked during past cleaning efforts.
2009-11-28 15:52:03 -08:00
David Brownell
a398c85de7 Cortex-M3: don't chain "struct arm" commands
Those commands presume support for the "classic" set of CPU
modes (FIQ, supervisor, IRQ, etc) ... which aren't supported
by the ARMv7-M or ARMv6-M architectures.  They also presume
a "struct arm" base type, which this code doesn't use.

We haven't cleaned up the register handling enough to be able
to share any of those "base" methods.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-28 14:19:45 -08:00
Zachary T Welch
01f93137c4 add 'nonce' nand driver
The nonce NAND driver provides a no-op implementation useful for
testing the system independently of any driver side-effects.
2009-11-28 13:00:39 -08:00
Zachary T Welch
cdfdcb2854 add more stub handlers to testee target
Prevent everything from crashing when exercising various commands.
2009-11-28 13:00:39 -08:00
Zachary T Welch
070259cadb explode tcl_target_func into many handlers
Eliminate the monolithic tcl_target_func by registering each of its
commands using the new chained command registration mechanism.

Also chains the target's commands under the CPU command, though these
may not work properly without some further modification.
2009-11-28 13:00:39 -08:00
Zachary T Welch
cb8d567b75 split jim_target into multiple handlers
The 'target' command group was implemented using its own command
dispatching, which can be eliminated by using the new chained command
registration mechanism.  This patch splits the jim_target() function
into individual handlers, which makes them to be visible to the help and
usage commands.  These one-trick handlers are much easier to understand.
2009-11-28 13:00:39 -08:00
Zachary T Welch
f8a62fb9c6 split jim_newtap_cmd into pieces
Moves the ID and IR-related option parsing to static helpers, removing
two levels of indent.
2009-11-28 13:00:39 -08:00
Zachary T Welch
7124be8247 improve jtag_tap_configure
Splits bulk of the jtag_tap_configure into jtag_tap_configure_event,
removing three or four levels of indentation in the process.
The resulting code was stylistically improved in other ways, but it
should be functionally identical.
2009-11-28 13:00:39 -08:00
Zachary T Welch
4ff5eda576 improve jtag_tap_handle_event indentation
Use 'continue' to reduce identation levels and superfluous logic.
2009-11-28 13:00:39 -08:00
Zachary T Welch
0377e5b54d begin moving JTAG jim handlers/helpers
Moves the tertiary jim handlers and required static helpers to the top
of tcl.c, defining them in a new registration array that is chained in
both the top-level context and under the jtag command.  The top-level
commands can be removed at some point in the future to reduce clutter.
2009-11-28 13:00:39 -08:00
Zachary T Welch
c4992c6d86 split jim_jtag_command into multiple handlers
Explodes the 'jtag' into separate command handlers, which are easier
to understand and extend.  Makes the code much easier to understand,
though further simplifications are possible.  This patch tries to
minimize the noise when viewed with 'git diff -w'.

Gives these commands improved built-in help and usage information.
2009-11-28 13:00:39 -08:00
Zachary T Welch
2da2864632 remove redundant 'rm' command handler
Two 'rm' commands were implemented and registered.  This removes the
version that would have never been called prior to refactoring the
command registration.
2009-11-28 13:00:39 -08:00
Zachary T Welch
8795b8f9df add error checking in command_new
Adds checks for memory allocation failures.  Started to use calloc()
instead of malloc()/memset(), but I got carried away.  This kind of work
should be done throughout the tree, but it's almost hopeless at present.
2009-11-28 13:00:39 -08:00
Zachary T Welch
42e00bb379 include mode information in help text.
Extends the help output to list the valid modes for each commands.
Fixes a memory leak of the returned command_name() string.
2009-11-28 13:00:39 -08:00
Zachary T Welch
fd343bea7f refactor command mode detection
Splits the check for a command's ability to run into a helper.

This also fixes a bug whereby commands that specified COMMAND_EXEC
were allowed to run during the configuration stage.  This allowed
problematic commands to be called before 'init', defeating the intention
of specifying that command mode.  With this change, the run_command()
helper denies access to handlers that should run only after 'init'
during the configuration stage.
2009-11-28 13:00:39 -08:00
Zachary T Welch
933b4579f0 add command private data setter/accessor
Presently, commands registration taks a static handler data pointer.
This patch adds support for commands that require a dynamic pointer,
such as those registered in a dynamic context (e.g. subcommands for a
user-created 'foo.cpu' command).  The command_set_handler_data will
update a command (group) to use a new context pointer, while the
CMD_DATA macro allows command handlers to access the value.
Jim handlers should find this value in interp->cmdPrivData.
2009-11-28 13:00:39 -08:00
Zachary T Welch
3b5751a4d4 add 'command mode' introspective handler
Allows scripts to behave different depending on the current mode.
Also allows introspection of the mode required for commands.
2009-11-28 13:00:39 -08:00
Zachary T Welch
89fa493a3b remove unknown handler
Updates command registration to provide top-level handlers for all
commands, rather than falling back onto the 'unknown' command. Instead,
that same handler is registered for placeholders, providing the same
functionality under the root verb command name instead.  This permits
users to implement their own 'unknown' function, and it resolves some
mind-bending breakage related to function object lookup while recursing.

Changes 'ocd_bounce' to call 'ocd_command' and 'ocd_help' from the
wrapper directly, rather than bouncing through their wrappers. This
prevents endless recursion caused by the above changes, whereby the
'command' wrapper's type check would blow the stack to hell and gone.
2009-11-28 13:00:39 -08:00
Zachary T Welch
df22f0f9ca improve command handler wrapper script
Adds 'ocd_bouncer' in startup.tcl that is called as a helper for
all command handlers, shrinking the embedded C wrapper to a mere stub.

Jim handlers are called directly, simple handlers get called with the
wrapper to capture and discard their output on error, and placeholders
call help directly (though the unknown handler still does this too).
It attempts to improve the quality of the error messages as well.
2009-11-28 13:00:38 -08:00
Zachary T Welch
37dd5a685a add 'command type' introspective handler
Adds the 'command' group handler, with the 'type' command producing
a string that tells whether the given command is 'native' (for Jim-based
command handlers), 'simple' (for simple built-in commands), 'group'
for command group placeholders, and 'unknown' if not found in the
command registration tables (e.g. core built-ins functions).
2009-11-28 12:58:35 -08:00
David Brownell
5f0223423d ARM11: fix warning on amd64
Previous version of JTAG_DEBUG() macro hid this bug.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-28 11:55:00 -08:00
David Brownell
30f6142fc8 ARM11: fix dbgtap JTAG_DEBUG
There is no DEBUG() macro; don't call one!  Always at
least *parse* debug code, to help prevent such errors.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-28 11:28:17 -08:00
David Brownell
acbe054a38 target: uplevel add_{break,watch}point() error checks
In target_type.h it's documented that the target must be
halted for add_breakpoint() ... and with slight ambiguity,
also for its add_watchpoint() sibling.  So rather than
verifying that constraint in the CPU drivers, do it in the
target_add_{break,watch}point() routines.

Add minor paranoia on the remove_*point() paths too:  save
the return value, and print it out in in the LOG_DEBUG message
in case it's nonzero.

Note that with some current cores, like all ARMv7 ones I've
looked at, there's no technical issue preventing watchpoint or
breakpoint add/remove operations on active cores.  This model
seems deeply wired into OpenOCD though.

ALSO:  the ARM targets were fairly "good" about enforcing that
constraint themselves.  The MIPS ones were relied on other code
to catch such stuff, but it's not clear such code existed ...
keep an eye out for new issues on MIPS.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-28 10:40:26 -08:00
David Brownell
68889ea02f target: remove unused TARGET_EVENT_OLD_* symbols
Just two *_OLD_* symbols left...

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-28 10:36:32 -08:00
David Brownell
5782999f60 NEWS: mention new reset-assert event
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-27 18:53:43 -08:00
David Brownell
ddce517e3a omap3530.cfg: use new "reset-assert" event
Replaces previous "reset-assert-pre" workaround.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-27 18:50:31 -08:00
David Brownell
e0cb27df6b Cortex-A8: support "reset-assert" event
Use the new "reset-assert" event; else SRST; else fail.
Tested on an OMAP3, using the event.

NOTE:  still doesn't handle "reset halt".  For some reason
neither VCR nor PRCR seemed effective; they held the value
that was written, but VCR didn't trigger debug entry when
the reset vector fired (maybe the vector needs configuring?)
and PRCR refused to hold the chip in reset until deassert()
could force the core into debug state.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-27 18:50:26 -08:00
David Brownell
4e56a2303b target: groundwork for "reset-assert" event
This defines a "reset-assert" event and a supporting utility
routine, and documents both how targets should implement it
and how config scripts should use it.  Core-specific updates
are needed to make this work.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-27 18:50:20 -08:00
David Brownell
4d2750e571 ARM11: write_memory() avoids increment check
When writing to a chip's "reset yourself" register, the ARM11 code
was reporting a spurious failure.  Just don't bother checking for
correctly incremented pointers given single-unit writes ... it's
a bit faster that way too.  (Reads should likely do the same thing.
For that matter, such checks are usually just a waste...)

Shrink an overlong parameter name, and associated lines'o'code.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-27 18:40:37 -08:00
Zachary T Welch
77aa7ca8d6 fix regression causing duplicated output
The command refactoring caused subcommand handlers to produce duplicate
output when run.  The problem was introduced by failing to ensure all
such invocations went through a top-level "catcher" script, prefixing
the command name with the 'ocd_' prefix and consuming its results.

The fix is to ensure such a top-level "catcher" script gets created
for each top-level command, regardless of whether it has a handler.
Indeed, this patch removes all command registrations for sub-commands,
which would not have worked in the new registration scheme anyway.

For now, dispatch of subcommands continues to be handled by the new
'unknown' command handler, which gets fixed here to strip the 'ocd_'
prefix if searching for the top-level command name fails initially.
Some Jim commands may be registered with this prefix, and that situation
seems to require the current fallback approach.  Otherwise, that prefix
could be stripped unconditionally and the logic made a little simpler.
The same problem must be handled by the 'help' command handler too,
so its lookup process works as intended.

Overall, the command dispatching remains more complicated than desired,
but this patch fixes the immediate regressions.
2009-11-27 14:30:26 -08:00
Øyvind Harboe
a0d983ab06 zy1000: keep up with new command registration stuff
jim and classic style commands are both supported.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-27 20:41:06 +01:00
Zachary T Welch
6ce3a299f3 update minidummy interface driver command handling
Changes the interface definition field reference from register_commands
to commands, which allows the module to compile.
2009-11-27 11:11:26 -08:00
Zachary T Welch
f31dfffdef fix 'nand info' command
Move device argument parsing after check for number of arguments;
otherwise, calling this command without any arguments would access
argv[0] before checking whether it even existed.
2009-11-27 11:11:26 -08:00
Øyvind Harboe
46ed068bac zy1000: keep up with changes to log_init()
fn's and return value for log_init() changed to void.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-27 19:42:38 +01:00
Øyvind Harboe
bd3ef5ca3d minidummy: fix compilation error
during refactoring a search and replace error crept in

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-27 09:10:37 +01:00
Dean Glazeski
2221a03744 ARM NAND I/O header documentation update.
Fixed the header file to properly specify the doxygen documentation for the
items defined in it.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-26 23:57:56 -08:00
Dean Glazeski
8f3c728273 ARM NAND I/O documentation update.
This updates the functions in the file to all have doxygen comments
describing what they do.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-26 23:56:58 -08:00
Dean Glazeski
05a5f682c6 ARM NAND I/O refactor code copying.
Created a function for copying code to the working area on
a target.  The NAND write and read functions are updated to
include use of this function.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-26 23:55:40 -08:00
Dean Glazeski
ffc704fdeb ARM NAND I/O read function.
Implementation of the NAND read function for ARM NAND I/O that
includes running a local algorithm on a device to increase the
performance of block reads.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-26 23:52:52 -08:00
Dean Glazeski
7c9cd47893 NAND Flash documentation update.
Updated doxygen comments for different interface structures for
the NAND interface.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-26 23:45:41 -08:00
David Brownell
fd5f53f035 XScale: add stub {read,write}_phys routines
Just make these fail, instead of letting them write over
potentially random memory.  Users should be able to work
around the lack of real implementations by disbling the
MMU by hand ... until someone provides a Real Fix.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-26 12:00:56 -08:00
Uwe Hermann
e07ad30577 update bug reporting information
The Berlios bug-tracker is disabled, bug reports go to the list.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-26 10:12:58 -08:00
Uwe Hermann
cfc02ccca2 fix typos in documentation
Fixes some minor typos in the top-level documentation files.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-26 10:12:22 -08:00
Uwe Hermann
1240ae459f fix typos in source files
Correct some spelling errors in source comments and printed output.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-26 10:11:26 -08:00
Øyvind Harboe
060980357d styleguide: add some embedded style rules.
Embedded and pthreads rely on modest and predictable
stack usage.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-26 17:35:55 +01:00
Eric Wetzel
3f8aa3cb03 fix 'flash protect' and 'flash erase_sector'
Command upgrading introduced two off-by-one bugs in the flash commands.
This patch fixes the 'flash {protect,erase_sector}' commands to check
that they have been passed the correct number of arguments.

Ammended during commit to fix help text for 'erase_address' too.
2009-11-26 07:57:51 -08:00
David Brownell
2653b80307 target: create and use target_name()
Several of the sites now using target_type_name() really
ought to be using an instance-specific name.  Create a
function called target_name(), accessing the instance's
own (command) name.

Use it in several places that really should be displaying
instance-specific names.  Also in several places which
were already doing so, but which had no wrapper to call.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-25 16:38:08 -08:00
David Brownell
b715a81f5b target: target_get_name() --> target_type_name()
There are two names that may matter on a per-target basis.
One is a per-instance name (for example, "at91sam7s.cpu").
The other is the name of its type (for example, "arm7tdmi"),
which is shared among multiple targets.

Currently target_get_name() returns the type name, which is
misleading and is rarely appropriate for target diagnostics.
Rename that as target_type_name().

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-25 16:38:08 -08:00
David Brownell
ac06d41fc7 omap3530.cfg: yes we have SRAM!
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-25 16:19:53 -08:00
David Brownell
cc53ad81d3 ARM: minor armv4/armv5 cleanup
Lines of 300+ characters are still bad; debug tweaks.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-25 16:18:22 -08:00
David Brownell
21378f58b6 ARM: comment tweaks in ADIv5
"OptimoDE DESS" is ARM's semicustom DSPish stuff.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-25 16:14:45 -08:00
David Brownell
5d244b85e2 ARM7/9: shrink run_algorithm_inner() lines
300+ characters is unreasonable.  So is half that.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-25 16:11:26 -08:00
David Brownell
83568b6b62 NEWS updates
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-25 16:05:35 -08:00
Zachary T Welch
49036463db update NEWS with recent developments
Mention changes to flash bank command syntax, 'nand verify' command,
command error handling and reporting, and help/usage command upgrades.
2009-11-25 12:08:06 -08:00
Zachary T Welch
4946925bea use ARRAY_SIZE macro
Search and destroy lingering cases where the ARRAY_SIZE macro should
be used to convey more intrinsic meaning in the OpenOCD code.
2009-11-25 10:32:00 -08:00
Zachary T Welch
a3d81eed4d support OPENOCD_DEBUG_LEVEL environment setting
Detect the OPENOCD_DEBUG_LEVEL setting in log_init(), allowing the
very early startup phases to be debugged.
2009-11-25 10:29:06 -08:00
Zachary T Welch
be482a5335 log: improve initialization
Removes redundant assignment of start_ms from log_register_commands().
Eliminates command_context parameter and return value.
Adds Doxygen comment block for this API call.
2009-11-25 10:29:06 -08:00
Zachary T Welch
ed90b6659f update command handler documentation
Adds sections on command registration and chaining, giving an overview
to developers that want to use these features.
2009-11-25 10:29:06 -08:00
Zachary T Welch
9d4c89f37f add 'testee' target type
Alliteration aside, this should provide the final piece of the puzzle
for developers that want to get started writing a new target type.
In this way, it also seeks to complement the 'dummy' interface driver
and 'faux' NOR flash driver.
2009-11-25 10:29:06 -08:00
Zachary T Welch
a93b404161 improve command handling examples
Removes hello and foo commands from top-level registration.  Instead,
the dummy interface driver and faux flash driver have been augmented
to register these commands as sub-commands.
2009-11-25 10:29:05 -08:00
Zachary T Welch
d89c631014 add script_command_run helper
Eliminates duplicated code in script_command and handle_unknown_command.
Fixes bug with duplicated help output generated by placeholder commands.
2009-11-25 10:29:05 -08:00
Zachary T Welch
9e5d8a94f1 encapsulate and re-use log capture, retval setup
Factors log capture while running script commands, eliminating
duplicated code between script_command and jim_capture.  Factors
setting a command's Jim "retval" into a new helper as well.

Using these new helpers in the new unknown command handler's
fixes possible regressions caused by these bits being missing.
2009-11-25 10:29:05 -08:00
Zachary T Welch
910bb250c4 combine help and usage command handlers
Remove duplicated handler code by checking the running command name.
2009-11-25 10:29:05 -08:00
Zachary T Welch
c297a14f70 improve usage and help command output
Rewrite formatting code in C, removing last remenants of TCL help code.
Sinificantly improves the readability by using smarter indent and wrap.
2009-11-24 21:37:37 -08:00
Zachary T Welch
6b066cd170 allow scripts to update usage information
The add_usage_text command uses the same C handler, which was updated
to support its new polymorphic role.  This patch updates the two script
commands that needed this support: 'find' and 'script'.
2009-11-24 21:37:37 -08:00
Zachary T Welch
8f5ff3ddcf httpd: use register_commands()
Updates httpd_start() to use register_commands() for 'readform' and
'writeform' commands.  Adds server/httpd.h to export the new signatures
for this function (and httpd_stop), which allows removing the obsoleted
declarations inside openocd.c.
2009-11-24 21:37:37 -08:00
Zachary T Welch
17a9dea53a add jim_handler to command_registration
Adding jim_handler field to command_registration allows removing the
register_jim helper.  All command registrations now go through the
register_command{,s}() functions.
2009-11-24 21:37:37 -08:00
Zachary T Welch
cd7e76ebf0 refactor command_new to use command_registration
Save stack space: use a struct.  Makes it easier to add new parameters.
2009-11-24 21:37:37 -08:00
Zachary T Welch
f74e2e033a remove register_commands from etm_capture_driver
Converts callback to an array of command_registration records.
Moves oocd_trace driver definition to end of file to eliminate
useless forward declaration.
2009-11-24 21:37:36 -08:00
Zachary T Welch
66ee303456 remove target_type register_command callback
Uses chaining of command_registration structures to eliminate all
target_type register_callback routines.  Exports the command_handler
registration arrays for those target types that are used by others.
2009-11-24 21:37:36 -08:00
Zachary T Welch
144e3678bd xscale: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
8a41656391 trace: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
5f6962b34f target_request: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
4e67912fb0 target: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
c3800b5e67 oocd_trace: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
a17caa387c etm_dummy: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
dd063d9914 etm: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
8161fd3163 etb: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
97fbd793b3 cortex_m3: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
28300bbf6f cortex_a8: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
df95fe25a4 armv7m: use register_commands() 2009-11-24 21:37:36 -08:00
Zachary T Welch
d79176e1bc armv7a: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
84c03168a5 armv4_5: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
d1eca9a74c arm9tdmi: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
69908ddbd0 arm966e: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
11061486b5 arm926ejs: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
509fe82b07 arm920t: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
e232dea176 arm7_9_common: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
e905fe6e75 arm720t: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
b40f265f9c arm11: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
90d09e35e4 remove nand_controller->register_callbacks
Replace flash_driver callback with pointer to command_registration.
Eliminates all related routines and allows drivers to omit commands.
2009-11-24 21:37:35 -08:00
Zachary T Welch
ad090413a8 remove flash_driver->register_callbacks
Replace flash_driver callback with pointer to command_registration.
Eliminates all related routines and allows drivers to omit commands.
2009-11-24 21:37:35 -08:00
Zachary T Welch
6b9bb584a5 tms470: use register_commands() 2009-11-24 21:37:35 -08:00
Zachary T Welch
b4e95c3720 str9xpec: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
5e977b46c3 str9x: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
dfa856ca18 str7x: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
f9606a6cb7 stm32x: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
737f8f2735 stellaris: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
0ff0dbba49 pic32mx: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
ccae9ae020 nand: use register_commands()
Eliminates 'nand_cmd' global variable.
2009-11-24 21:37:34 -08:00
Zachary T Welch
1bf7462edb mflash: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
7609e1091a lpc3180_nand_controller: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
1cbe3ec6f1 lpc2900: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
a12a29c28a lpc2000: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
b90bf52be3 flash: use register_commands()
Eliminates 'flash_cmd' global variable.
2009-11-24 21:37:34 -08:00
Zachary T Welch
1765b10304 ecos: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
b595ab8b97 cfi: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
c4aa2fd6e7 avrf: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
bdae918dcd at91sam7: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
2a4a94b7ac at91sam3: use register_commands() 2009-11-24 21:37:34 -08:00
Zachary T Welch
8d46720cda remove register_callbacks from jtag interface
Changes the jtag_interface->register_callbacks field to a list of
commands to be registered.  Changes callback to invocation of
register_commands() with that command registration list.  Removes all
JTAG interface driver register_command callback functions, which the
previous commits had converted into identical calls.
2009-11-24 21:37:33 -08:00
Zachary T Welch
fc2d9f8761 vsllink: use register_commands()
Use register_commands() with command registration array.
2009-11-24 21:37:33 -08:00
Zachary T Welch
355a673032 jtag: use register_commands()
Use register commands with command registration array.
2009-11-24 21:37:33 -08:00
Zachary T Welch
9a31d66b3f presto: use register_commands()
Use register_commands() with command registration array.
2009-11-24 21:37:33 -08:00
Zachary T Welch
339e08baa5 parport: use register_commands()
Use register_commands() with a command registration array.
2009-11-24 21:37:33 -08:00
Zachary T Welch
b1d034bf2f jlink: use register_commands()
Use register_commands() with command registration array.
2009-11-24 21:37:33 -08:00
Zachary T Welch
779bdbe797 gw16012: use register_commands()
Use register_commands() with command registration array.
2009-11-24 21:37:33 -08:00
Zachary T Welch
3ab599a7e4 ft2232: use register_commands()
Use register_commands() with a command registration array.
2009-11-24 21:37:33 -08:00
Zachary T Welch
30be874de8 at91rm9200: use register_commands()
Use register_commands() with command registration array.
---
This module was broken by previous changes, but no one has complained.
Are there still users for this modules?
2009-11-24 21:37:33 -08:00
Zachary T Welch
0af32bb938 arm-jtag-ew: use register_commands()
Uses register_commands() with command registration array.
2009-11-24 21:37:33 -08:00
Zachary T Welch
48429dcfad amt_jtagaccel: use register_commands()
Use register_commands() with command_registration array.
2009-11-24 21:37:33 -08:00
Zachary T Welch
e2f23c5437 pld: use static registration instead of callback
Remove register_callbacks from pld_device structure, using an array
of command_registration records instead.
2009-11-24 21:37:33 -08:00
Zachary T Welch
76b89755c9 pld: use register_commands()
Updates core PLD and virtex2 commands to use register_commands().
2009-11-24 21:37:33 -08:00
Zachary T Welch
75e37b5348 {,x}svf: use register_commands()
Use register_commands() for registering {,x}svf commands.
2009-11-24 21:37:33 -08:00
Zachary T Welch
b4c4b5f71e server: use register_commands
Converts server directory to use new command registration paradigm.
2009-11-24 21:37:32 -08:00
Zachary T Welch
29772ec372 log: use register_commands()
Use register_commands() for logging callbacks.  Improve help and add
proper usage.
2009-11-24 21:37:32 -08:00
Zachary T Welch
8de1e7bd9e ioutil: use register_commands()
Use table instead of individual calls.  Add proper usage information.
2009-11-24 21:37:32 -08:00
Zachary T Welch
1595fd7c4b openocd: use register_commands()
Use register_commands() for top-level version and init command.
2009-11-24 21:37:32 -08:00
Zachary T Welch
16e0404777 demonstrate chaining with foo commands
Use the new command registration chaining capabilities to eliminate
the foo_register_commands helper, folding its remaining command
handler setup into the hello_command_handlers registration array.
2009-11-24 21:37:32 -08:00
Zachary T Welch
e7fd1d3d50 hello: use register_commands()
Use new register_commands() with command registration table.
2009-11-24 21:37:32 -08:00
Zachary T Welch
62e5649600 rewrite 'unknown' command dispatching in C
Rewrite the magical 'unknown' command in C as a Jim handler, allowing
it to dispatch commands to any level in the tree.
2009-11-24 21:37:30 -08:00
Zachary T Welch
769fbfa058 add public API for locating commands
Allow other modules to find a command, primarily for the purpose of
registering and unregistering subcommands.
2009-11-24 21:37:30 -08:00
Zachary T Welch
4c54c27da7 refactor script_command context grabbing
Move command context acquisition to current_command_context() for re-use.
2009-11-24 21:37:30 -08:00
Zachary T Welch
60ba4641d6 add command registration chaining
Adds the ability to chain registration structures.  Modules can define a
command with the 'chain' and 'num_chain' fields defined in their
registration table, and the register_commands() function will initialize
these commands.  If the registration record creates a new command, then
the chained commands are created under it; otherwise, they are created
in the same context as the other commands (i.e. the parent argument).
2009-11-24 21:37:30 -08:00
Zachary T Welch
607634f967 more command registration refactoring
Split out the handler registration into its own function, and add a
few obviously missing NULL pointer error checking.
2009-11-24 21:37:30 -08:00
Zachary T Welch
25a7ac2c75 command: use register_commands for handlers
Use register_commands() to register low-level command handlers,
adding a builtin_command_handlers declaration that is easy to understand.
Splits help and usage information into their appropriate fields.
2009-11-24 21:37:30 -08:00
Zachary T Welch
d107f71c50 add command usage, separate from help
Adds the usage command, to display usage information for commands.
The output for this command will remain erronenously empty until
commands are updated to use these new coventions.
2009-11-24 21:37:29 -08:00
Zachary T Welch
2461855494 add register_commands for batch registration
The register_commands API takes multiple commands in one call, allowing
modules to declare and pass a much simpler (and more explicit) array of
command_registration records.
2009-11-24 21:37:29 -08:00
Zachary T Welch
69076057dd add struct command_registration
Add a structure to encapsulate command registration information, rather
than passing them all as parameters.  Enables further API changes that
require additional required or optional parameters.

Updates the register_command API and COMMAND_REGISTER macro to use it,
along with their documentation.
2009-11-24 21:37:29 -08:00
Zachary T Welch
833e7f5248 use COMMAND_REGISTER macro
Replaces direct calls to register_command() with a macro, to allow
its parameters to be changed and callers updated in phases.
2009-11-24 21:37:29 -08:00
Zachary T Welch
f7e1f2df74 add COMMAND_REGISTER macro
Provides a migration path for the widely used register_command API,
which needs to be updated to provide new functionality.

This macro allows the API to change without having to update all of its
callers at the same time.
2009-11-24 21:37:29 -08:00
Zachary T Welch
47cb10217a improve startup tcl scripts
Fix a couple of layering violations missed in the last round.
Add missing comment headers.
2009-11-24 21:37:29 -08:00
David Brownell
b6210907ea Cortex-A8: avoid DSCR reads
There was a lot of needless handshaking overhead in the current
Cortex-A8 DCC/ITR operations, since the status read by each step
was discarded rather than letting the next step know it.

This shrinks the handshaking by:  (a) passing status along from
previous steps, avoiding re-fetching; which enables the big win
(b) relying on a useful invariant:  that the DSCR_INSTR_COMP bit
is set after every call to a DPM method.

A "reg sp_usr" call previously took 17 flushes; now it takes just 9.
This visibly speeds common operations like entry to debug state and
stepping, as well as "arm reg" and so on.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 21:24:44 -08:00
David Brownell
e109bb6af2 Cortex-A8: hook up DPM
This replaces two versions of register access functions.  One
was commented out, and seemed to have uncertain intent.  The
other was fairly new, and helped motivate the DPM framework
once I observed that the ARM11 was doing the very same ops.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 21:24:44 -08:00
David Brownell
c008d30fe8 Cortex-A8: implement DPM
This implements the DPM interface for Cortex-A8 cores.  It
also adds a synchronization operation to the DPM framework,
which is needed by the Cortex-A8 after CPSR writes.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 21:24:44 -08:00
David Brownell
991daa03eb Cortex-A8: minor cleanup
Make various functions static, add some comments, report
vector catch as a flavor of DBG_REASON_BREAKPOINT, get
rid of needless/undesirable ARMV4_5_CORE_REG_MODE, etc.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 21:24:44 -08:00
Andreas Fritiofson
338a674faa improve alloc_vprintf
The previous implementation was unnecessarily complex. Get rid of the loops,
let vsnprintf() tell us directly how much storage we need and allocate that. A
second pass writes the actual string. Also add a va_end() that was missing.
This should be much faster for large strings and less wasteful for small ones.

A quirk that has been retained is that some callers patch in a newline at the
end of the returned string and depend on alloc_vprintf to allocate at least
one byte extra.

Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-24 12:48:02 -08:00
Zachary T Welch
5507b5f430 fix doxygen build
Update build rules to skip the PDF unless the TeX has been created.
Also, fixes a warning regarding pattern rules being a GNU make trick.
2009-11-24 09:17:52 -08:00
Zachary T Welch
96f0ab894a jlink: rewrite to use jtag_usb_open
Rewrite jlink_usb_open to use jtag_usb_open helper.
2009-11-24 07:30:20 -08:00
Zachary T Welch
31fc1586a0 jlink: remove superfluous indentation
Rewrite logic to remove indentation in jlink_usb_open, in prep
for further surgery.
2009-11-24 07:30:20 -08:00
Zachary T Welch
9a21ef7614 rlink: use jtag_usb_open helper
Rewrite rlink_init routine to use jtag_usb_open helper.  Eliminates
some spurious calls to exit().

Wraps a tremendously long line of comment to fit 80 columns too.
2009-11-24 07:30:20 -08:00
Zachary T Welch
ec5e484fd6 rlink: eliminate spurious indentation
Rework rlink_init to use less indentation.  Best viewed with diff -w.
2009-11-24 07:30:19 -08:00
Zachary T Welch
de9a182ca6 vsllink: rewrite to use jtag_usb_open
Rewrite vsllink_usb_open to use jtag_usb_open helper.

Eliminates spurious calls to exit().
2009-11-24 07:30:19 -08:00
Zachary T Welch
0f544f4310 usbprog: use jtag_usb_open
Rewrite usbprob_jtag_open to use jtag_usb_open helper.
2009-11-24 07:30:19 -08:00
Zachary T Welch
d836b079b4 arm-jtag-ew: use jtag_usb_open
Rewrite armjtagwe_usb_open to use jtag_usb_open.
2009-11-24 07:30:19 -08:00
Zachary T Welch
3a660e2293 add jtag/usb_common.[ch] files
Begins to consolidate code used by several USB JTAG interfaces.
This first patch provides the required build system changes and
a common jtag_usb_open routine, which will replace the guts for
probing the busses and devices for possible VID/PID matches.
The following patches convert each driver to use it.
2009-11-24 07:30:19 -08:00
David Brownell
3efc99b34a ARM11: remove old R0..R15/CPSR code
This finishes the basic switchover to the new register code,
for everything except the debug registers.  (And maybe we
shouldn't have a cache for *those* which works this way...)

The context save/restore code now uses the new code, but
it's in a slightly different sequence.  That should be fine
since the R0/PC/CPSR stuff is all that really matters (and
if we can update those, we can update the rest).

Now there's no longer a way any code can be confused about
which copy of "r1" (etc) to use.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 01:27:29 -08:00
David Brownell
ec64acf536 ARM11: use standard run_algorithm()
As with single stepping, the previous stuff was needed because
the ARM11 code wasn't using the standard ARM base type and
register access ... but now those mechanisms work, so we can
switch out that special-purpose glue, in favor of the more
thoroughly tested/capable "standard" code.

Fixes a bug in the resume() implementation:  it wasn't handling
two of its arguments correctly, preventing the "flash erase_check"
algorithm from working.  (This code needs a *subsequent* update
for correct register handling, though... removing the confusion
about which "r2", for example, to use.)

This should resolve some "FIXME" comments too, for Thumb and
processor mode support.  It also gets rid of a nasty exit()
call; servers should only have *clean* shutdown paths.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 01:27:24 -08:00
David Brownell
bf3abc48f0 ARM11: use standard single step simulation
The previous stuff was needed because the ARM11 code wasn't using
the standard ARM base type and register access ... but now those
mechanisms work, so we can switch out that special-purpose glue.

This should resolve all the "FIXME -- handle Thumb single stepping"
comments too, and properly handle the processor's mode.  (Modulo
the issue that this code doesn't yet handle two-byte breakpoints.)

Clarify the comments about the the hardware single stepping.  When
we eventually share breakpoint code with Cortex-A8, we can just make
that be the default on cores which support it.  We may still want an
override command, not just to facilitate testing but to cope with
"instruction address mismatch" not quite being true single-step.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 01:27:21 -08:00
David Brownell
5eb893ec41 ARM11: partial support for standard ARM register interfaces.
This provides "standard" ARM register support -- with twenty or
more shadow registers on top of what this code now handles, but
properly associated with the various core modes -- parallel to
the current register code.  That is, the current code is stilil
managing the "current" registers; the new code shadows them.

You can see all the registers with "arm reg", modify the shadows
like "r8_fiq" or "sp_abt" with "reg", and see them get properly
written back when you step.  (Just don't do that with any of the
registers managed by the "old" code ...)

It also switches to using more standard code, relying on those
standard registers, in two places:  (a) the poll status display,
which now shows core state (ARM/Thumb/...) and mode (Supervisor,
IRQ, etc); and (b) GDB register access.

So it's not a full migration, there are warts -- every place that
touches the old register cache is a potential bug -- but it's a
small more-or-less-comprehensible step that's even somewhat useful.
Later patches complete the migration.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 01:27:16 -08:00
David Brownell
6ff33a4ee8 ARM11: remove register "history" debug stuff
This was a private mechanism to snapshot registers before leaving
debug state, and then on reentry to optionally display what changed.
It was coupled to the private register cache, which won't be sticking
around in that form for much longer.  Remove (instead of teaching
it how to handle *all* the registers).

(The idea is interesting, but we ought to be able to implement
this in a generic way.  Ideally through Tcl scripts that can
automatically be invoked following debug entry...)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 00:14:15 -08:00
David Brownell
caf827ee81 ARM11: implement provider for new DPM interface
This is a very thin layer over some of the current ARM11
debug TAP utilities.  The layer isn't yet hooked up.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 00:14:06 -08:00
David Brownell
e6dc927e97 ARM: new DPM interface
First version of interface for sharing code between ARMv6 and ARMv7a
debug modules ... now the architecture includes debug support.  (Not
the same as for the trimmed-down v7m or v6m though!)  This is a first
version of an interface that will let the ARM11 and Cortex-A8 support
share code, features, and bugfixes.  Based on existing code from both
of those cores.

The ARM v7-AR architecture specification calls this commonality the
"Debug Programmer's Model (DPM)", which seemed to be an appropriate
acronym -- a TLA even! -- for use in our code.  Made it so.  :)

The initial scope of this just supports register access, and is geared
towards supporting top level "struct arm" mechanisms.  Later, things
like breakpoint and watchpoint support should be included.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 00:13:58 -08:00
David Brownell
ad75af0b17 target: cope with *any* error setting a breakpoint
It's wrong to map unrecognized failure codes to success.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-24 00:13:43 -08:00
Andreas Fritiofson
0583cb0a0d support for scripts in $HOME/.openocd
Add $HOME/.openocd as the first default script search directory, allowing
the user to override the standard scripts.

Update the user guide with information on where OpenOCD expects to find
configuration files and scripts. Also fixed some minor formatting issues.

Add entry to NEWS as well.

Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-24 08:57:02 +01:00
Jerry Ling
0d06a06f8b mips: fix gaffe when removing dynamic array allocation
Classic sizeof() gaffe.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-24 08:26:30 +01:00
Øyvind Harboe
828d006a9d arm926ejs: fix gaffe when converting from arm926ejs cp15 to mcr
the first arg is the register number 15 = cp15.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-23 18:23:10 +01:00
Øyvind Harboe
eeb4276deb arm926ejs: retire cp15 commands, handled by mrc/mcr.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-23 14:02:03 +01:00
David Brownell
b8b1353dd7 ARM11: remove unused state and exports
For now there's no point in saving this stuff after examine()
checks it out as OK.  Ditto exporting symbols that aren't
used outside of the module which defines them.  In fact, those
two things needlessly complicate the code...

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 15:51:16 -08:00
David Brownell
fa9b0e2167 ARM11: macro cleanup
Make this code look more like the rest of the OpenOCD code.

 - Use calloc() directly, not NEW() ... and fix some potential
   memory leaks while we're at it.

 - Remove FNC_INFO ... it's a NOP that just clutters things,
   and it's trivial for developers to add tracing as needed.

 - Replace FNC_INFO_NOTIMPLEMENTED with LOG_WARNING calls;
   ditto.  And stop having those call sites wrongly succeed!

 - Waste less space with the CHECK_RETVAL() macro.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 15:50:24 -08:00
Øyvind Harboe
af7f6891e9 mips: remove dynamic arrays - reduces stack usage
Allocate working memory dynamically.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 20:23:34 +01:00
Øyvind Harboe
2d6829d698 mips: use const for code sequences
This will allow data to be allocated in read only
memory instead of on the stack. Speeds things up
and reduces stack usage.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 20:18:26 +01:00
Øyvind Harboe
5985dee35d arm11: do not use dynamic arrays
Allocate working memory dynamically, caught by checkstack.pl

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 19:57:57 +01:00
Øyvind Harboe
bcebce3ce2 arm926ejs: fix warnings
buf_set_u32() operated on an uninitialized stack
variable with non-byte boundaries, which led to
warnings about reading uninitialized stack.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 19:52:37 +01:00
David Brownell
dc22fd899e TODO: ref 'checkstack.pl' not 'checkpatch.pl'
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 10:28:19 -08:00
David Brownell
b404b9ab57 ARM: use arm_reg_current()
Start using the arm_reg_current() call.  This shrinks and speeds
the affected code.  It can also prevent some coredumps coming from
invalid CPSR values ... the ARMV4_5_CORE_REG_MODE() macro returns
bogus registers if e.g. "Secure Monitor" mode isn't supported by
the current CPU.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 10:27:29 -08:00
David Brownell
fa618cc74d ARM11: remove needless string format #ifdeffery
We don't need to use size_t in these places; so it's easy
to be rid of the need for this #ifdef and its MS-derived
portability problems.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 10:27:29 -08:00
David Brownell
1c619a2f12 target: make register flags "bool"
Mostly for clarity, but it also saves code and data space.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 10:27:29 -08:00
David Brownell
ab5ac33fd4 ARM: remove 'armv4_5_common_s' migration #define
Finish migrating from the old symbol to the new one.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 10:27:29 -08:00
Øyvind Harboe
5416c525d4 flash: dynamically allocate working storage
Allocate working memory rather than using stack.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 19:14:06 +01:00
Øyvind Harboe
aacc5b583c target: reduce stack usage
4096 byte buffer allocated dynamically. Better
for embedded OS's.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 18:58:42 +01:00
Øyvind Harboe
7daec5a0ce todo: add tip on how to identify excessive stack usage
Use dynamic allocations for working memory rather than stack.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 18:50:57 +01:00
Øyvind Harboe
5c4a73d0d8 zy1000: un-break uart command after command handler refactoring
Switched it to jim command to insulate it from command refactoring.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 13:46:42 +01:00
Øyvind Harboe
700a60ec57 embedded: reduce stack usage
Allocate working structures on stack to avoid issues with
path lengths + reduce stack usage.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 13:38:42 +01:00
Øyvind Harboe
964c3639e2 embedded: do not allocate large temporary structures on stack
With -O3 when inlining aggressively the total stack usage will
be the sum of many fn's, which can easily get out of hand.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 13:38:42 +01:00
Øyvind Harboe
31da0003dc embedded: save stack
and also do not recaluate the crc32_table upon
every invocation.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 13:38:42 +01:00
Øyvind Harboe
808e53368c zy1000: fix breakage in command parsing code for power command
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 13:38:42 +01:00
Øyvind Harboe
d1fbcc3589 build: fix breakage in building bin2char
bin2char build relied on $(builddir) which is not defined
for arm-elf X builds at least.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-22 13:35:13 +01:00
David Brownell
dd9894f481 ARM: arm_set_cpsr() handles T and J bits
Have arm_set_cpsr() handle the two core state flags, updating
the CPU state.  This eliminates code in various debug_entry()
paths, and marginally improves handling of the J bit.

Catch and comment a few holes in the handling of the J bit on
ARM926ejs cores ... it's unlikely our users will care about
Jazelle mode, but we can at least warn of Impending Doom.  If
anyone does use it, these breadcrumbs may help them to find
the right path through the code.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 03:41:14 -08:00
David Brownell
ff810723e0 ARM: define two register utilities
Define arm_reg_current() ... returning handle to a given register,
and encapsulating the current mode's register shadowing.  It's got
one current use, for reporting the current register set to GDB.
This will let later patches clean up much ARMV4_5_CORE_REG_MODE()
nastiness, saving a bit of code.

Define and use arm_set_cpsr() ... initially it updates the cached
CPSR and sets up state used by arm_reg_current(), plus any SPSR
handle.   (Later: can also set up for T and J bits.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 03:38:34 -08:00
David Brownell
5706fd7860 ARM: simplify CPSR handling
Stash a pointer to the CPSR in the "struct arm", to help get rid
of the (common) references to its index in the register cache.

This removes almost all references to CPSR offsets outside of the
toplevel ARM code ... except a pair related to the current ARM11
"simulator" logic (which should be removable soonish).

This is a net minor code shrink of a few hundred bytes of object
code, and also makes the code more readable.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 03:37:21 -08:00
David Brownell
60a2d85af1 ARM11: remove disabled register hooks
Minor cleanup of ARM11 register handling:  remove disabled
register hooks.  This should all be handled by shared code,
and this stuff is just clutter.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-22 03:36:24 -08:00
Zachary T Welch
b58239e4c0 jtag: remove useless forward declarations
Removes some more useless forward declarations from a few JTAG drivers.
Moves interface and bit-bang structure defitions below their callbacks.
2009-11-21 10:20:56 -08:00
Zachary T Welch
c46c2d77e6 allow jtag interfaces to lack commands
Allow JTAG interface drivers to skip registering an register_commands
callback when it will just be empty.
2009-11-21 10:19:47 -08:00
Andreas Fritiofson
425e43d9d1 show script search dirs in debug log
Add this to ease debugging why the standard scripts aren't
found on the default script search path in some build/install
enviroments. Especially on Windows it's not straight forward
where openocd actually looks for the scripts.

Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-21 09:30:09 -08:00
David Brownell
69c7519562 ARM: pass 'struct reg *' to register r/w routines
Implementations need to access the register struct they modify;
make it easier and less error-prone to identify the instance.
(This removes over 10% of the ARMV4_5_CORE_REG_MODE nastiness...)

Plus some minor fixes noted when making these updates:  ARM7/ARM9
accessor methods should be static; don't leave CPSR wrongly marked
"dirty"; note significant XScale omissions in register handling;
and have armv4_5_build_reg_cache() record its result.

Rename "struct armv4_5_core_reg" as "struct arm_reg"; it's used
for more than those older architecture generations.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-20 16:27:24 -08:00
David Brownell
85fe1506a2 ARM7/ARM9: remove old "debug commands"
Remove two commands that were documented as "debug commands"
and where "you probably don't want to use this".   We never
intended to support them, and at least one problem report
boiled down to using this when it shouldn't have been used.

Update the docs on the existing register commands to talk a
bit more about register access and cache behavior.  (Those
debug commands existed largely to *bypass* the cache.)  And
fix some minor doc goofs that snuck in with recent changes,
renaming "armv4_5" as "arm" and "arm9tdmi" as "arm9".

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-20 16:21:29 -08:00
Zachary T Welch
7a67aae93c maintain command lists in sorted order
Use insertion sort to the command link lists.  The only practical effect
of this is to order the output of the new 'help' command.
2009-11-20 15:03:41 -08:00
Zachary T Welch
a19aaf9136 add add_help_text command handler
Rewrite means for scripts to register help text for commands.  These
cause the new commands to be stored in the command heirarchy, with
built-in commands; however, they will never be invoked there because
they do not receive a command handler.  The same trick is used for
the Jim commands.

Remove the old helpers that were used to register commands.
2009-11-20 15:03:35 -08:00
Zachary T Welch
e5b0a69ba9 provide command context during cmd_init
For the startup.tcl code to use built-in commands, the context must be
associated with the interpreter temporarily.  This will be required to
add help text.
2009-11-20 14:52:56 -08:00
Zachary T Welch
5458fef43c improve 'help' command
Rewrites 'help' command in C, using new 'cmd_help' for display.  Adds the
built-in 'help' COMMAND_HANDLER to provide better output than the
TCL-based script command (e.g. heirarchical listing of commands).

The help string is stored in the command structure, though it conitnues
to be pushed into the Jim environment.  The current idiomatic usage
suggests the addition of a usage field as well, to provide two levels
of detail for users to consume (i.e. terse usage list, or verbose help).
2009-11-20 14:52:56 -08:00
Zachary T Welch
82449e2d60 factor help script command into parts
Creates a helper function, cmd_help, which displays the help string
for a single command.  Presently, it is called from the loop in help.

The routine has been extended to allow indentation of command groups,
so an improved help command can improve the display of information.
2009-11-20 14:52:56 -08:00
Zachary T Welch
9e9633c6b9 refactor command registration
Refactors the command registration to use helpers to simplify the code.
The unregistration routines were made more flexible by allowing them
to operate on a single command, such that one can remove all of a
commands children in one step (perhaps before adding back a 'config'
subcommand that allows getting the others back).  Eliminates a bit
of duplicated code and adds full API documentation for these routines.
2009-11-20 14:52:56 -08:00
Zachary T Welch
73c6e3bb18 change command_find helper interface
Avoid requiring double pointers where a single would suffice.
2009-11-20 14:52:56 -08:00
Zachary T Welch
67c29d9935 factor script_command argv allocation
Splits argument allocation out from script command, reusing free() code.
2009-11-20 14:52:56 -08:00
David Brownell
7b77b3c5d1 target.cfg: TAP id for Hilscher netX 500
Based on email from "Martin Kaul <martin.kaul@leuze.de>".

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-20 12:21:00 -08:00
Zachary T Welch
153848e6cc fix flash/nand name parsing
Start driver.num check from end, and make sure the numeric part is
actually a number.  Fix problems trying to parse bank names.
2009-11-20 07:10:55 -08:00
David Brownell
a1777fc649 Cortex-A8: better context restore
The previous version never wrote dirty registers
for non-current CPU modes ... fix that.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-19 19:03:12 -08:00
David Brownell
d7760352e8 Cortex-A8: mode support
We *should* be able to read and write registers in any core mode,
instead of being stuck with whatever mode the core was when we
entered debug state.  This patch makes them work.

Note that the current restore_context() only handles the current
mode; writing to other-mode registers is a NOP without a followup
patch fixing that.  Also, that SPSR access needed some bugfixes;
it was confused with CPSR.

Secure monitor mode also seems dubious; there's probably more to
be done before that's sufficiently understood by the debugger.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-19 19:03:02 -08:00
David Brownell
71cde5e359 target: create/use register_cache_invalidate()
Create a generic register_cache_invalidate(), and use it to
replace three all-but-identical core-specific routines:

 - armv4_5_invalidate_core_regs()
 - armv7m_invalidate_core_regs
 - mips32_invalidate_core_regs() too.

Make cache->num_regs be unsigned, avoiding various errors.

Net code shrink and simplification.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-19 19:02:10 -08:00
Dean Glazeski
31fb7788a6 NAND verify doesn't advance.
Fix to move the device address up as the contents are verified.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-19 15:25:18 -08:00
Zachary T Welch
4b18ef15a3 document new flash syntax
Updates the user documentation with the new syntax for defining
flash and nand banks.
2009-11-19 13:39:42 -08:00
Zachary T Welch
3e1f5e7c64 update 'nand device' usage in scripts
Add $_FLASHNAME variable to update 'nand device' command syntax.
2009-11-19 13:39:41 -08:00
Zachary T Welch
664ba309d5 add support for naming NAND banks
Requires users to name their nand banks, allowing them to be used
instead of bank numbers in script commands.
2009-11-19 13:39:41 -08:00
Zachary T Welch
59d4466b55 refactor handle_nand_device_command
Move bulk of for-loop to a new static command helper function.

Adds handle_nand_list_drivers command handler, registered as
'nand drivers'.

Improves command help text and error reporting.
2009-11-19 13:39:41 -08:00
Zachary T Welch
2dfa5e9c84 update 'flash bank' usage in scripts
Sets $_FLASHNAME to "$_CHIPNAME.flash" and passes it as the
first argument to 'flash bank'.
2009-11-19 13:39:41 -08:00
Zachary T Welch
fd654c8a3e add support for naming flash banks
Requires users to name their flash banks, allowing them to be used
instead of bank numbers in script commands.
2009-11-19 13:39:41 -08:00
Zachary T Welch
dd44ae18b4 refactor handle_flash_bank_command
Move variables to point of first use, reducing their scope.
Add driver_name temporary to help arguments be changed later.

Eliminates the useless 'found' variable, changing the code to terminate
the loop immediate and return its success.
2009-11-19 13:39:41 -08:00
Zachary T Welch
ff25e76bad rename flash and nand command helpers
After adding support for referencing banks by name, renames
the COMMAND_HELPERs appropriately:
flash_command_get_bank_by_num  -> flash_command_get_bank
nand_command_get_device_by_num -> flash_command_get_device
2009-11-19 13:39:41 -08:00
Zachary T Welch
870b8c0455 allow flash/nand banks commands to accept names
Add get_flash_bank_by_name (and get_nand_device_by_name) helpers
to retrieves struct flash_bank * (struct nand_device *) given a
driver name and an (optional) driver-specific bank index.

These are used to extend flash_command_get_bank_by_num (and
nand_command_get_device_by_num) to allow all flash (nand) commands to
reference defined banks by name, not just by number.

To avoid some code duplication, add the flash/common.[ch] files to hold
functionality common to both types driver.  The first two methods are
helpers for the above routines to find a bank specified by a "name" or
"name.index" string.  get_flash_name_index() finds the '.index' portion,
while flash_driver_name_matches() performs the string portion matching.
2009-11-19 13:39:41 -08:00
David Brownell
8f446fcf67 ARM: remove per-register malloc
Just pre-allocate memory for the cached register value.
Shrinks heap overhead; increases locality-of-reference.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-19 13:23:49 -08:00
David Brownell
cbc13187c3 ARM: streamline register init
Combine register names with other per-register data into a
single template structure.  This saves space, and makes it
easier to change how registers get handled (by shrinking
the number of places that care about cache indices).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-19 13:23:08 -08:00
David Brownell
e3ed06579b Cortex-A8: parts of examine() run just once
The examine() method has some conceptual breakage.  Cope
with it by manually splitting out the run-once parts from
the after-each-reset parts ... this gets rid of memory
leaks and speeds up resets after the first one.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-19 10:47:31 -08:00
Dean Glazeski
c049033fde nand_fileio_parse_args parses wrong param for size
This changes the size parameter from argv[2] to argv[3], which is what it's
supposed to be.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-19 07:00:30 -08:00
David Brownell
195ce5eb27 ARMv7-A: use standard ARM core states
We don't want an ARMv7-specific core state enumeration just to
add ThumbEE state.  Update the generic stuff to handle that,
and replace the V7-specific bits with it.

For Cortex-A8:  on debug entry, check both the T and J bits
instead of just the T bit.  When the J bit is set, set the
right state and warn appropriately.

(And while we're at it, move the generic arm struct to the front
of the v7a structure, for somewhat better code generation.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-19 02:33:01 -08:00
David Brownell
f320b12289 ARMv7-A: use standard ARM core_mode symbols
The only way ARMv7-A modes differ from ARMv4/ARMv5 flavors
is that v7-A is allowed to include "Secure monitor" support.
That's now handled by our standard top-level ARM code ... so
phase out the stuff that's specific to ARMv7-A.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-19 02:31:34 -08:00
Zachary T Welch
f382ebae10 fix zy1000 command handler
Rewrite ZY1000 power command handler to use new macros, simplify logic.

Remove unused port command handler declaration.
2009-11-18 15:51:07 -08:00
Zachary T Welch
c0d14dc7f1 remove fast command and jim_global_long
Removing the fast command eliminates the fast_and_dangerous global,
which was used only by arm7_9_common as an initializer.  The command
is not called in the tree; instead, more explicit commands are used.

The jim_global_long function was not used anywhere in the tree.
2009-11-18 15:51:07 -08:00
Zachary T Welch
20218b8de6 update src/hello.c with parsing examples
Adds the foo/bar commands to provide more working examples of command
argument parsing, including the new handle_command_parse_bool helper.

Updates hello command help text to provide useful information.
2009-11-18 15:51:07 -08:00
Zachary T Welch
4d8d1d32d0 change all bool parsers to accept any value
This patch changes the behavior of all boolean parsing callers to
accept any one of "true/enable/on/yes/1" or "false/disable/off/no/0".

Since one particular pair will be most appropriate in any given
situation, the specific macros should continue to be used in
order to display the most informative error messages possible.
2009-11-18 15:51:07 -08:00
Zachary T Welch
7e4adfe1c5 add handle_command_parse_bool command helper
Rewrite arm11_handle_bool to provide a generic on/off command helper.

Refactors COMMAND_PARSE_BOOL to use new command_parse_bool helper,
which gets reused by the new command_parse_bool_any helper.
This later helper is called by the new command helper function to
accepts any on/off, enable/disable, true/false, yes/no, or 0/1 parameter.
2009-11-18 15:51:07 -08:00
Zachary T Welch
410fab9ea8 use COMMAND_PARSE_ENABLE macro where appropriate
Updates all command parsing of simple "enable" and "disable" arguments.
A few case in the tree use a tri-state or extended arguments, which
cannot use this simple macro.

Simlifies the xscale icache/dcache command handler logic.
2009-11-18 15:51:07 -08:00
Zachary T Welch
75a37eb5b3 use COMMAND_PARSE_ON_OFF where appropriate
Updates all command parsing of "on" and "off" arguments.
2009-11-18 15:51:07 -08:00
Zachary T Welch
bd5a1799ea add COMMAND_PARSE_BOOL macro and friends
Adds several macros similar to COMMAND_PARSE_NUMBER, but for parsing
boolean command arguments.  Two flavors are provided to provide
drop-in compatibility with existing code, allow for the elimination
of a lot of code bloat while improving the error checking and reporting.

COMMAND_PARSE_ON_OFF parses "on"/"off" command parameters.
COMMAND_PARSE_ENABLE parses "enable"/"disable" command parameters.

Both print the error and return an error out of the calling function.
2009-11-18 15:51:07 -08:00
David Brownell
bd9d05e14b ARM: rework "arm reg" output for new mode
Change the layout to show the "Secure Monitor" registers too,
when they're present.

Instead of lining registers for each of six (or seven) modes up
in adjacent vertical columns, display each mode's registers (or
shadows) in a single block, avoiding duplicate value displays.

This also lets us shrink the line length to fits in standard 80
character lines ... six or seven 18-character columns can't fit.

Relabel "r13" as "sp", so it's more meaningful.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-18 15:31:24 -08:00
David Brownell
f0c9e89e1a Cortex-A8: xPSR handling updates
When we read the CPSR on debug entry, update the CPSR cache in all
cases, not just when the current processor state is User or System.

Plus minor cleanup of how the (too-many) other registers' cache
entries get updated.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-18 15:04:58 -08:00
David Brownell
94dba42313 ARM: add a default full_context() method
If the core doesn't provide an optimized version of this
method, provide one without core-specific optimizations.
Use this to make Cortex-A8 support the "arm reg" command.

Related: make the two register access methods properly static,
have the "set" log a "not halted" error too, and make sure
that the "valid" flag is set on successful reads.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-18 14:49:22 -08:00
David Brownell
f5093e1605 ARM: simplify ARMv7-A register handling
ARMv7-A doesn't need to duplicate all the standard ARM code
for register handling.

 - Switch Cortex-A8 to use the standard register code
 - Remove duplicated infrastructure from ARMv7-A
 - Have ARMv7-A arch_state() show CPSR, like other ARMs

Add comments to show where the Cortex-A8 isn't actually doing
the right thing for register reads/writes, unless core happens
to be in the right mode to start with.  (Looks like maybe there
may be generic confusion between saved/current PSR values in all
the ARM code ...)

Make related ARMv7-A and Cortex-A8 symbols properly static.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-18 14:46:14 -08:00
David Brownell
8a6d4ced4c ARM: setup "secure monitor mode" shadow regs
Teach the "armv4_5" register code to understand about the
secure monitor mode:

 - Add the other three shadowed registers to the arrays
 - Support another internal mode number (sigh) in mappings
 - Catch malloc/calloc failures building that register cache

This should kick in for Cortex-A8 and ARM1176.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-18 13:23:00 -08:00
David Brownell
bbebfd9e13 ARM: add "core_type" field to "struct arm"
It's used to flag cores with the "TrustZone" extension,
and is used in subsequent patches to set up support for
the registers shadowed by its new secure monitor mode.

The ARM1176 and Cortex-A8 both support this new mode.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-18 13:22:27 -08:00
Zachary T Welch
9b1f9810b0 fix segfault at startup
The previous changes to move the startup TCL code resulted in segfaults
during startup.  This seemingly innocuous patch fixes the problem.
I would explain why changing from 'foo[]' to '*foo' caused this issue,
but the difference seems superficial.  For now, this hot fix will do,
but this issue might bear further scrutiny.
2009-11-18 11:56:24 -08:00
Zachary T Welch
5e229bbf87 pass startup_tcl to command_init
Removes external linkage from helper module, making the startup
code a parameter to a new command context's initialization routine.
2009-11-18 07:22:22 -08:00
Zachary T Welch
cb7dbc1af4 split startup.tcl file across modules
Moves definitions for each layer into their own file, eliminating
layering violations in the built-in TCL code.  Updates src/Makefile.am
rules to include all files in the final startup.tcl input file, and
others Makefile.am rules to distribute the new files in our packages.
2009-11-18 07:21:42 -08:00
Zachary T Welch
903daa796a move startup.c to libopenocd
Moves the creation of startup_tcl.c from src/helper/ to src/.
Prepares to split the startup.tcl file into its per-module parts.
2009-11-18 03:59:14 -08:00
Zachary T Welch
59f32cbe53 fix regression in md/mw commands
The recent migration broke them, the fixes broken them in a new way,
but this should restore them to working order.  Eliminates the
temporary variable, as the CMD_NAME macro can once again be use
in routines that increment CMD_ARGV without nasty side-effects.
2009-11-18 03:34:52 -08:00
Øyvind Harboe
6e95f16d0a jtag-api: get rid of unecessary buf_set_u23() that make code obtuse.
Also, this is on the path to increasing the word size for
bit vectors from 8 to something wider(32? natural host machine
width?)

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-18 09:24:28 +01:00
David Brownell
181d401d59 ARM: add is_arm_mode()
Add a new is_arm_mode() predicate, and use it to replace almost
all calls to current armv4_5_mode_to_number().

Eventually those internal mode numbers should vanish... along
with their siblings in the armv7a.c file.

Remove a handful of superfluous checks ... e.g. the mode number
was just initialized, or (debug entry methods) already validated.

Move one of the macros using internal mode numbers into the only
file which uses that macro.  Make the tables manipulated with
those numbers be read-only and, where possible, static so they're
not confused with part of the generic ARM interface.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-17 23:50:26 -08:00
David Brownell
ec93209f51 ARM: add arm_mode_name()
Add and use arm_mode_name() to map from PSR bits to user
meaningful names.   It uses a new table which, later, can
be used to hold other mode-coupled data.

Add definitions for the "Secure Monitor" mode, as seen on
some ARM11 cores (like ARM1176) and on Cortex-A8.  The
previous mode name scheme didn't understand that mode.

Remove the old mechanism ... there were two copies, caused
by Cortex-A8 needing to add "Secure Monitor" mode support.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-17 23:50:23 -08:00
David Brownell
d6c8945662 ARM: only use one set of dummy FPA registers
All ARM cores need to provide obsolete FPA registers in their
GDB register dumps.  (Even though cores with floating point
support now generally use some version of VFP...)

Clean up that support a bit by sharing the same dummy registers,
and removing the duplicate copies.  Eventually we shouldn't need
to export those dummies.

(This makes the ARMv7-M support include the armv4_5 header, and
cleans up related #includes, but doesn't yet use anything from
there except those dummies.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-17 23:50:17 -08:00
Zachary T Welch
0091e59d2a allow documentation to be configured
Add --disable-doxygen-html and --enable-doxygen-pdf options to the
configure script, allowing user to change the defaults.  These
update the proess of munging the Doxygen configuration file to
use the settings thusly provided.  Add options in README.
2009-11-17 11:42:48 -08:00
Zachary T Welch
94975c96d4 update doxygen configuration to produce a PDF
A single PDF file for the developer manual allows accessing a single
index, browsing, and searching.  It takes significantly more time to
build this way, but this patch allows others to look at the results.

Migration Tip: If you have previously built the HTML Doxygen
documentatation, rename your 'doxygen' directory to 'doxygen/html'
to prevent needlessly rebuilding those files.
2009-11-17 11:42:48 -08:00
Zachary T Welch
789d47c180 update command_handler documentation
Improve the developer manual and primer sections which talk about
writing command handlers.  Notably, it documents the new CMD_* macros.
2009-11-17 11:40:21 -08:00
Zachary T Welch
cfaf7bdd0a remove unused variable from run_command 2009-11-17 11:40:21 -08:00
Zachary T Welch
cffc98ad80 add CMD_NAME variable in command_invocation
Update CMD_NAME from its migratory home in CMD_ARGV[-1] to cmd->name.
Allows CMD_ARGV++ idiom to be used safely in command handlers.
2009-11-17 11:40:21 -08:00
Zachary T Welch
be084414ba add struct command_invocation for COMMAND_HANDLER
Adds the command_invocation structure to encapsulate parameters for
all COMMAND_HANDLER routines.  Rather than passing several arguments
to each successive subroutine, a single pointer may be passed around.

Changes the CMD_* macros to reference the new fields.

Updates run_command to create an instance and pass it to the handler.
2009-11-17 11:40:21 -08:00
Zachary T Welch
2861877b32 command_handler: change 'cmd_ctx' to CMD_CTX
Convert all command handler 'cmd_ctx' parameter usage with CMD_CTX.
2009-11-17 11:40:06 -08:00
Zachary T Welch
23402315ce command_handler: change 'args' to CMD_ARGV
This patch converts all instances of 'args' in COMMAND_HANDLER routines
to use CMD_ARGV macro.
2009-11-17 11:38:07 -08:00
Zachary T Welch
7bf1a86e47 command_handler: change to 'argc' to CMD_ARGC
This patch converts all instances of 'argc' in COMMAND_HANDLER routines
to use CMD_ARGC.
2009-11-17 11:38:06 -08:00
Zachary T Welch
5b9899d6ea add more command_handler conversion macros
Add additional macros to allow command handling to be migrated easily:
CMD_CTX, CMD_ARGC, and CMD_ARGV.  Updates CMD_NAME to use CMD_ARGV.

In addition to making the remaining patches of this series cleaner,
this introduces easily sed-able symbols that could allow us to retire
these once the command handler infrastructure matures (i.e. pre-1.0).
2009-11-17 11:38:06 -08:00
David Brownell
f4788652e4 target: simplify register get/set ops
No need to indirect from registered integers to pointers.
Just stash the pointers directly in the register struct,
and don't even bother registering.

This is a small code shrink, speeds register access just
a smidgeon, and gets rid of another rude exit() path.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-17 09:06:45 -08:00
Øyvind Harboe
959b373f8c jtag_registers: Avalon bridge flushing tweaks
The code is now much more explicit. It flushes every
N writes. For now flush every time, but tinkering with
the bridge FIFO size and how often we flush clearly
points in the direction of the Avalon write FIFO full
being the culprit.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-17 15:39:05 +01:00
Øyvind Harboe
741cd3c3ab zy1000: revC UART forwarding
Name of serial device differs between revB/C.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-17 15:04:17 +01:00
Øyvind Harboe
ca32f25638 zy1000: add version command to print FPGA version and timestamps
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-17 15:04:17 +01:00
Øyvind Harboe
83104648e6 zy1000: fix bug when running on non-arm CPU
Shifting by more than 32 is undefined for 32 bit integers according
to the C standard. Robust solution is conditional code.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-17 15:04:17 +01:00
Øyvind Harboe
b888b63fe9 zy1000: fix trivial syntax error introduced by latest refactorings
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-17 15:01:48 +01:00
David Brownell
0181296f61 ARM9TDMI: remove now-needless "struct arm9tdmi"
And move the rest of the vector_catch stuff into the C file;
it's not part of the module interface.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-17 01:09:50 -08:00
David Brownell
812ab89f58 ARM7TDMI: remove now-needless "struct arm7tdmi"
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-17 01:09:06 -08:00
David Brownell
a2df544fd9 target: remove some more duplicate includes
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-17 01:06:16 -08:00
David Brownell
e722396890 ARMv7-A: no exit() calls
Also, switch integrity check over to the correct magic number,
and remove duplicate v4/v5 #define.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 17:58:58 -08:00
David Brownell
36a538c6d7 Cortex-A8: no exit() calls, add missing v7-A init
Eventually there should be a v7a init routine, but for now
all that is inlined here.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 17:57:12 -08:00
David Brownell
c5e0026836 XScale: fewere exit() calls
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 17:55:49 -08:00
David Brownell
1d4a09c2ef MIPS: no exit() calls
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 17:55:30 -08:00
David Brownell
1f3e067b86 ARMv7-M: no exit() calls
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 17:54:51 -08:00
David Brownell
9d57f4d5a1 ARMv4/ARMv5: no exit() calls
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 17:52:50 -08:00
David Brownell
6030f2ca03 ARM11: fewer exit() calls
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 17:51:55 -08:00
David Brownell
47f2305229 Cortex-M3: don't exit()
Get rid of undesirable and needless exit() calls
from the Cortex-M3 support.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 16:42:51 -08:00
David Brownell
56adbaffd0 ARMv7A: use standard disassembler
We no longer need v7A-specific code for this.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 16:36:21 -08:00
David Brownell
d7d857a189 ARM11: register (most) standard ARM commands
Have ARM11 register the "standard" ARM commands.  For now, only
disassembly really works.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 16:36:12 -08:00
David Brownell
f86137066a ARM: "armv4_5" command prefix becomes "arm"
Rename the "armv4_5" command prefix to straight "arm" so it makes
more sense for newer cores.  Add a simple compatibility script.

Make sure all the commands give the same "not an ARM" diagnostic
message (and fail properly) when called against non-ARM targets.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 16:36:09 -08:00
David Brownell
7c393679c0 JTAG: fix autoprobe failure.
Fix bug noted by Øyvind: terminate the IR length autoscan when
the IR is too long, or otherwise broken.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 16:36:03 -08:00
Zachary T Welch
51862bb98c fileio: improve API types
Use size_t instead of uint32_t when specifying file sizes.  Update all
consumers up through the layers to use size_t when required.  These
changes should be safe, but the higher-levels will need to be updated
further to receive the intended benefits (i.e. large file support).

Add error checking for fileio_read and file_write.  Previously, all
errors were being silently ignored, so this change might cause some
problems for some people in some cases.  However, it gives us the chance
to handle any errors that do occur at higher-levels, rather than burying
our heads in the sand.
2009-11-16 15:47:09 -08:00
Zachary T Welch
69df712d1d struct fileio: improve member types
Add const keyword to file url and cast to free().

Make size an ssize_t and chase all format strings that use it.
2009-11-16 15:47:09 -08:00
Zachary T Welch
9763aef76a helper/log: improve API parameter types
Uses unsigned type to pass line numbers.

Use uint64_t to pass sleep routines their milliseconds.  Updates sleep
routines to use this type and improve whitespace.
2009-11-16 15:47:09 -08:00
Zachary T Welch
df9b12695f use Jim_CmdProc in jim_register
The jim_register command just needed to use the type defined by jim.h.
2009-11-16 15:47:08 -08:00
Zachary T Welch
0a9daddc2e improve constness of open_file_from_path 2009-11-16 15:47:08 -08:00
Zachary T Welch
ccf59123b7 make command line options const
The getopt_long call allows a const struct option, so mark ours
const too.
2009-11-16 15:47:08 -08:00
David Brownell
91ac164d95 ARM: standard disassembler uses Thumb2 entry
Tweak "standard" ARM disassembler diagnostics to fail if the target
is not "an ARM" (vs. not "an ARMV4/5"), so it makes more sense for
cores inheriting this as the "generic" disassembler.

Also, to use the Thumb2 entry instead of the original Thumb entry.
This makes it work better for both newer cores (which support those
added instructions) and for BL and BLX instructions on older cores.
(Those instructions are 32-bits, which requires curious state-aware
code to go through a 16-bit decode interface...)

Plus minor cleanups, notably to have fewer exit paths and to make
sure they all return failure codes.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 15:29:14 -08:00
David Brownell
bf97237401 target: don't include "log.h" from "armv4_5.h"
No point in multiple includes, and that file doesn't
use its functions any more.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 15:27:40 -08:00
David Brownell
2fb58116a5 ARM: move mode functions out of header
They're really too big to inline, at least for code that's
not in any performance-critical loops.

Also move the associated string table to the rodata section.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 15:27:36 -08:00
David Brownell
a7c04a0e49 JTAG: no LOG_WARNING() for taps without IDCODE
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 15:18:55 -08:00
David Brownell
b6e0f2e1c3 binarybuffer: regression fix
The "improve inline binarybuffer helpers" mis-handled bytes
with the high bit set; treat them as unsigned, not signed.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 14:50:07 -08:00
David Brownell
66300d5966 "types.h" doxygen fix
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 10:42:01 -08:00
David Brownell
9a98e83b49 target: less implicit inclusion of "etm.h"
Don't include it in more headers than necessary; just
use it in the few files that actually need it.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 10:19:33 -08:00
Zachary T Welch
dc1685ca25 move ARRAY_SIZE macro to types.h
The ARRAY_SIZE macro was defined in several target files, so move it
to types.h.

This patch also removes two other identical macros: DIM (from jtag.h)
and asizeof (from arm11.h).
2009-11-16 09:58:11 -08:00
Zachary T Welch
10cce4a5fe armv7m: make core reg read/write use unsigned
Eliminate redundant check that gets covered by using unsigned type.
Created to eliminate noise from subsequent patches, but this kind of
conversion will be beneficial in similar ways throughout the tree.
2009-11-16 09:58:11 -08:00
Zachary T Welch
0535a92456 remove TAP_SCAN_BYTES macro
Use DIV_ROUND_UP(n, 8) instead of TAP_SCAN_BYTES macro.
2009-11-16 09:58:11 -08:00
Zachary T Welch
a94748ec6d rename CEIL as DIV_ROUND_UP
Improves the name of this macro, moves it to types.h, and adds a block
of Doxygen comments to describe what it does.
2009-11-16 09:58:11 -08:00
Zachary T Welch
f0ce88b3af move container_of to types.h
The container_of macro is useful as a general solution.  It belongs
in types.h, rather than target.h where it was introduced.  Requires
the offsetof macro, which comes from <stddef.h> (moved as well).
2009-11-16 09:57:59 -08:00
Zachary T Welch
cbc0578372 nand_command_get_device_by_num: make COMMAND_HELPER
Use COMMAND_HELPER macro to define nand_command_get_device_by_num.
Use CALL_COMMAND_HANDLER to invoke it.
2009-11-16 08:44:38 -08:00
Zachary T Welch
e84849f5ed flash_command_get_bank_by_num: make COMMAND_HELPER
Use COMMAND_HELPER macro to declare flash_command_get_bank_by_num.
This is required for COMMAND_PARSE_NUMBER macro.
2009-11-16 08:44:38 -08:00
Zachary T Welch
d7a0dfa4dc cleanup jtag minidrivers
Remove two vestigial externs from our JTAG minidriver source files.
Also, removes many extra blank lines from the minidummy driver.
2009-11-16 05:30:51 -08:00
Zachary T Welch
555757175e Add 'nand verify' command
Add the 'nand verify' command to perform a dump and fake-write
simultaneously, checking the read bits against those generated by the
write process.  Appropriate user documentation for this command has
been added to the user guide as well.

The algorithm presently makes a relatively naive comparison.  Some chips
that use ECC may not verify correctly using this implementation, but the
new documentation provides details about this limitation.
2009-11-16 01:38:19 -08:00
Zachary T Welch
da4cb3c029 Add FILEIO_NONE access mode.
In some cases, the FILEIO_NONE access mode may be useful as a parameter
to indicate that file access should be disabled.  High-level routines can
use it to skip file access calls, as 'fileio_open' will fail presently
if called to open a file using this mode.
2009-11-16 01:38:19 -08:00
Zachary T Welch
51cd370b39 Use nand_fileio_* in write/dump commands.
This patch eliminates duplicated code in the the NAND 'dump' and 'write'
by using the new static helper functions.

These changes also fix a possible memory leak in nand dump command, in
the case that the dump file failed to open.

Overall, the changes should be functionally equivalent, but the
resulting code will be easier to improve and extend further.
2009-11-16 01:38:19 -08:00
Zachary T Welch
23cc85b307 Add nand_fileio_* helper APIs.
This patch provides helpers APIs that will eliminate duplicated code in
the the NAND 'dump' and 'write' commands by factoring their common code
into static helper functions.  These helpers may be useful for creating
new commands, as shown in the final patch to 'verify' flash from a file.

Several previously unreported error conditions now generate messages and
propogate the return codes, such as when the file fails to open and bad
arguments are given.  These changes will fix a possible memory leak in
nand dump command, in the case that the dump file failed to open.

Overall, the changes should be functionally equivalent, but the
resulting code will be easier to improve and extend consistently.
2009-11-16 01:38:19 -08:00
Zachary T Welch
45527ee82c binarybuffer: add API documentation
Adds Doxygen documentation for a number of the binarybuffer APIs,
including "unexpected" behavior exposed during review on the list.
2009-11-16 01:25:47 -08:00
Zachary T Welch
d6348d4316 improve inline binarybuffer helpers
Use void*, unsigned, and bool types with inline helpers.
2009-11-16 00:46:34 -08:00
Zachary T Welch
21b452cf67 improve buf_set_buf helper
Use void * and unsigned types for buffer and their sizes.
Allows it to be used with more than uint8_t * without casts.
2009-11-16 00:46:34 -08:00
Zachary T Welch
d8d8c5d8c3 improve buf_set_ones
Use memset instead of loop. Improve types, using void * and unsigned.
2009-11-16 00:46:34 -08:00
Zachary T Welch
d09e308130 improve buf_cpy helper
Use memcpy for bulk of copy, improve final byte handling.
Improve types by using void * for buffers and unsigned for size.
2009-11-16 00:46:34 -08:00
Zachary T Welch
e4ee891759 improve buf_cmp and buf_cmp_mask helpers
Rewrite buf_cmp to use memcpy for bulk of comparison.  Add static
helper to perform comparison of trailing byte, which uses another
static helper to perform a maksed comparison.  The masked comparison
helper is used by the buf_cmp_mask to simplify its loop.
Improve types to use void *, unsigned, and return bool.
2009-11-16 00:46:33 -08:00
Zachary T Welch
d50caa97d1 improve str_to_buf and buf_to_str helpers
Improve types: use void * and unsigned.  Move all variables to point of
first use.  Move radix guessing logic to new str_radix_guess helper.
2009-11-16 00:46:33 -08:00
Zachary T Welch
5a43bd2e18 binarybuffer: move variables to point of first use
Reduce some noise from subsequent patches.
2009-11-16 00:46:33 -08:00
Zachary T Welch
82fc2f9628 binarybuffer: fix whitespace related issues
Add inter-operator whitespace.  Improve existing documentation.
2009-11-16 00:46:33 -08:00
David Brownell
b695cb7522 #include "target.h" less wildly
Don't include "target.h" from more headers than necessary.  This
avoids needless interdependencies and duplicated include paths.

Don't needlessly include it in source files, either.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 00:35:24 -08:00
David Brownell
8193f17c3a target: no implicit #includes of "register.h"
Same deal:  "register.h" got needlessly included all over the
place because of being in a few widely included headers.

So take it out of the header files which included it, and put
it in files which use it ... reduce needless interdependencies.

Also, don't need that extra "types.h" inclusion.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 00:35:14 -08:00
David Brownell
1186f7efa7 target: less implicit inclusion of "command.h"
Lots of files still include it, often through needless
duplicate inclusion of "log.h"; sigh.

This cleans up the inclusion graph a bunch, so there are
fewer inclusion paths, but it doesn't change much otherwise.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 00:35:11 -08:00
David Brownell
db094c2e60 target: don't implicitly include "algorithm.h"
Most files in the tree seem to have ended up including this,
and *quite* needlessly ... only code implementing or using
downloadable algorithms actually needs these declarations.

So take it out of the header files which included it, and put
it in files which use it ... reduce needless interdependencies.

Also: "algorithm.h" doesn't need to include "types.h" again;
it already comes from a different header.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 00:35:05 -08:00
David Brownell
aa7c449600 target: don't implicitly include "breakpoint.h"
Most files in the tree seem to have ended up including this,
and *quite* needlessly ... only code implementing or using
breakpoints actually needs these declarations.

So take it out of the header files which included it, and put
it in files which use it ... reduce needless interdependencies.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-16 00:34:57 -08:00
David Brownell
5d1a9033ab ARM11: use now-generic memory utils
Now the ARM11 cores can use the renamed arm_checksum_memory()
and arm_blank_check_memory() routines ... do so.

Sanity checked with "flash erase_check" of both NOR banks on an
OMAP2420 ... the algorithm code dumped four lines of of "poll"
status after each of almost 520 blocks (yes, *very* annoying) but
gave plausible results after producing that spam.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-15 10:35:47 -08:00
David Brownell
2280ddeea5 ARM11: fixup method table
Three changes:  remove ARM11_HANDLER() in favor of normal structure
initialization syntax; fix goofy indentation in that structure; and
don't needlessly export arm11_register_commands(), it's only called
through that method table.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-15 10:35:41 -08:00
David Brownell
269040bbad ARM: memory utils aren't ARM7/ARM9 dependent
The arm7_9_checksum_memory() and arm7_9_blank_check_memory()
routines are not actually specific to the ARM7 and ARM9 core
generations ... they can work for any core which can run
algorithms using basic ARM (not Thumb) instructions.

Rename them; move the declarations to a more generic site;
likewise move the code (and tidy it a bit in the process).

NOTE:  the blank_check() method falsely returned a success
status (0) on one error path, when the algorithm failed.
Fixed this bug.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-15 10:35:34 -08:00
David Brownell
9ac7cdec82 target: make "examined" flag be per-target
Previously this flag was stored in "target_type", so that for example
if there were two ARM7TDMI targets in a scan chain, both would claim
to have been examined although only the first one actually had its
examine() method called.

Move this state to where it should have been in the first place, and
hide a method that didn't need exposure ... the flag is write-once.

Provide some doxygen.  The examine() method is confusing, since it
isn't separating one-time setup from the after-each-reset stuff.  And
the ARM7/ARM9 version is, somewhat undesirably, not leaving the debug
state alone after reset ... probably more of an issue for trace setup
than for watchpoints and breakpoints.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-15 10:35:25 -08:00
Zachary T Welch
f30136603e arm-jtag-ew,jlink: switch to COMMAND_HANDLER
These drivers were overlooked during the recent upgrade.  Convert them,
moving their registration routines to eliminate their declarations.
2009-11-15 09:12:44 -08:00
Zachary T Welch
6731968873 rlink: fix overzealous sed
Fix an instance where my cleanup when awry.
2009-11-15 09:11:29 -08:00
Zachary T Welch
a502676df7 remove unused arm_jtag_buf_to_* helpers
Removes unused arm_jtag_buf_* helpers from arm_jtag.[ch].  These could
reappear if patches are provided to conver the tree to use them, but
this code should not be in the master tree until that series is ready.
2009-11-14 18:21:02 -08:00
Zachary T Welch
bc07ee82fb remove unused buf_to_u32_handler
Purge an unused routine from the tree and remove a layering violation.
If this code is needed, it should reappear somwhere in src/jtag/,
where struct scan_field gets defined.
2009-11-14 18:21:02 -08:00
Zachary T Welch
4d4b2958a5 struct scan_field_s -> struct scan_field
Remove obsolete suffix from struct scan_field.  Somehow, these
definitions did not get updated but did not cause any errors.
2009-11-14 18:21:02 -08:00
Krzysztof Dziuba
c2edc7908f Fix for md* commands, similar to mw*. 2009-11-14 17:39:27 -08:00
David Brownell
ecc659d44d lpc2900.h -- remove from Makefile.am too
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-14 14:58:14 -08:00
David Brownell
dd47bba6f8 flash: remove needless lpc2900.h header
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-14 14:53:19 -08:00
David Brownell
7f48f463a1 remove annoying $URL$ startup message
It's completely unused; the obnoxious "DANGER!!!" comments
don't even explain what it was doing (shorthand SVN magic).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-14 12:42:50 -08:00
Dean Glazeski
c93ae60bce Invalid command syntax errors with MWW.
This fixes an issue due to the new command handler syntax caused by the mw handler playing with the args pointer before
using the CMD_NAME macro.  Fix is to move this call above the lines changing args.
2009-11-14 10:58:35 -08:00
Zachary T Welch
4088b1e622 add openocd.h for top-level declarations
Create src/openocd.h to hold declarations previously made internally
by src/main.c and src/server/server.c.  This ensures all functions
are verified to be in-sync at compile time (rather than at link),
making it easier to track down bugs.
2009-11-14 07:29:16 -08:00
Ferdinand Postema
ab3bdfb2cb compile with cygwin (32-bit)
Changed some printf format strings..

[dbrownell@users.sourceforge.net: shrink lines, fix indents]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-14 02:22:37 -08:00
David Brownell
ecab0cfe25 ARM11: ETM + ETB support
Kick in ETM (and ETB) support for ARM11.  Tested on OMAP 2420,
so update that configuration.  (That's an ARM1136ejs, ETB,
OpenGL ES1.1, C55x DSP, etc.)

Also update the other ARM11 ETM + ETB targets in the tree
to set up these modules.  (Not tested.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 16:58:14 -08:00
David Brownell
817bf74302 ARM11: revert etmr/etmw commands
These aren't desirable, given "standard" ETM support.
Also remove the now-unused arm11_find_target().

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 16:56:11 -08:00
David Brownell
44d6a531f7 iMX2* + ETB targets: hook up ETM and ETB
ARM9 cores with an ETB will have a matching ETM.
Hook them both up by default.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 16:56:11 -08:00
David Brownell
aafb916bea ARM7/ARM9: use shared examine() method
No point in having two identical examine methods for the
ARM7TDMI and ARM9TDMI drivers; move, rename, shrink, share.

Add a bit of doxygen; stop needlessly exporting a method.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 16:26:39 -08:00
David Brownell
78c6b922e2 ETM: simplify ETM initialization code paths
Return NULL from etm_build_reg_cache() not ERROR_OK; and share
code on that fault path.

Let ETM code handle any tracking of its cache -- not callers.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 16:26:39 -08:00
David Brownell
a7f5cdf999 ARM11: switch to new "arm" base type
This will enable reusing many common ARM utilities, in
particular the ETM and ETB support.  The ARM11 support
can still be much simplified after this patch, though.

Note:  none of those common utilities kick in yet...

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 16:22:36 -08:00
David Brownell
04b514707f target: remove unused "bitfield" infrastructure
We have too many different registers, and too many version and
context dependent interpretations, for this type of bitfield
management to be scalable.

(Anyone who really wants bitfield interpretation *can* do that
in Tcl code...)

There are ... quite a few copies of the same ARM dummy registers.
There should eventually be one copy; this many is craziness.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 16:22:36 -08:00
David Brownell
38e8d60f79 target.cfg: label ETBs correctly
Various cores with an ETB have its TAP misnamed ... either as a
boundary scan TAP or as the iMX "Secure JTAG Controller" (which
is, among other things, a JRC that could be used to shorten
scan chains).

Use the correct name for these TAPs, which we can recognize since
their IDs were assigned by ARM and these chips all document the
presence of an ETB.  The 0x2b900f0f is ETB11; the 0x1b900f0f
is an older module, just called "ETB".

Also shrink the ETB's IR configuration; the default IR-Capture
value is fine, and the mask can specify that all four bits are
safe to check (per ARM documentation).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 13:44:50 -08:00
David Brownell
afe0298399 ARM7/9: rm arm7_9_get_arch_pointers()
Remove the last external user of arm7_9_get_arch_pointers(), and
that annoying downcast utility.  Add an is_arm7_9() predicate.

Stop returning specious success codes on various failure paths
in the ARM7/ARM9 commands which used that downcast utility.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 13:44:50 -08:00
Zachary T Welch
6435e75e14 update developer manual for new types
Update the style guide and chase obvious references to structures
that have been renamed.
2009-11-13 13:38:35 -08:00
Zachary T Welch
ef746e27c5 command_t -> struct command
Remove misleading typedef and redundant suffix from struct command.
2009-11-13 13:30:50 -08:00
Zachary T Welch
98723c4ecd command_context_t -> struct command_context
Remove misleading typedef and redundant suffix from struct command_context.
2009-11-13 13:25:47 -08:00
Zachary T Welch
d16968e24f remove rlink structure typedefs
Remove useless typedefs from the rlink driver.  Improve whitespace.
2009-11-13 12:19:39 -08:00
Zachary T Welch
96b62996d2 flash_bank_t -> struct flash_bank
Remove misleading typedef and redundant suffix from struct flash_bank.
2009-11-13 11:58:14 -08:00
Zachary T Welch
2f6e56e383 nand_device_t -> struct nand_device
Remove misleading typedef and redundant suffix from struct nand_device.
2009-11-13 11:58:14 -08:00
Zachary T Welch
0f1163e823 target_t -> struct target
Remove misleading typedef and redundant suffix from struct target.
2009-11-13 11:58:14 -08:00
Zachary T Welch
d0dee7ccaf reg_t -> struct reg
Remove misleading typedef and redundant suffix from struct reg.
2009-11-13 11:58:13 -08:00
Zachary T Welch
ac927559c3 target_type_t -> struct target_type
Remove misleading typedef and redundant suffix from struct target_type.
2009-11-13 11:58:13 -08:00
Zachary T Welch
d64a873db4 improve mips32_pracc_context
Use struct mips32_pracc_context instead of a typedef.
2009-11-13 11:58:13 -08:00
Zachary T Welch
dfecfd5fd4 image_t -> struct image
Remove misleading typedef and redundant suffix from struct image.

Also removes the typedef from enum image_type, as it is used in
image.h only.
2009-11-13 11:58:13 -08:00
Zachary T Welch
af949b2531 armv4_5_common_t -> struct arm
Remove misleading typedef and just use struct arm.
2009-11-13 11:58:13 -08:00
Zachary T Welch
d0c19e0a9d etm_context_t -> struct etm_context
Remove misleading typedef and redundant suffix from struct etm_context.
2009-11-13 11:58:13 -08:00
Zachary T Welch
6421c2075c etb_t -> struct etb
Remove misleading typedef and redundant suffix from struct etb.
2009-11-13 11:58:13 -08:00
Zachary T Welch
4952eadd8f trace_t -> struct trace
Remove misleading typedef and redundant suffix from struct trace.
2009-11-13 11:58:13 -08:00
Zachary T Welch
d90063ffc5 image_elf_t -> struct image_elf
Remove misleading typedef and redundant suffix from struct image_elf.
2009-11-13 11:58:13 -08:00
Zachary T Welch
2ec440588f cortex_m3_dwt_comparator_t -> struct cortex_m3_dwt_comparator
Remove misleading typedef and redundant suffix from struct cortex_m3_dwt_comparator.
2009-11-13 11:58:13 -08:00
Zachary T Welch
cdd2d9c2d0 cortex_m3_fp_comparator_t -> struct cortex_m3_fp_comparator
Remove misleading typedef and redundant suffix from struct cortex_m3_fp_comparator.
2009-11-13 11:58:13 -08:00
Zachary T Welch
d727f97889 cortex_a8_wrp_t -> struct cortex_a8_wrp
Remove misleading typedef and redundant suffix from struct cortex_a8_wrp.
2009-11-13 11:58:13 -08:00
Zachary T Welch
42fb6b8876 cortex_a8_brp_t -> struct cortex_a8_brp
Remove misleading typedef and redundant suffix from struct cortex_a8_brp.
2009-11-13 11:58:13 -08:00
Zachary T Welch
53c05c8b1d breakpoint_t -> struct breakpoint
Remove misleading typedef and redundant suffix from struct breakpoint.
2009-11-13 11:58:13 -08:00
Zachary T Welch
1e51cf049c xscale_trace_t -> struct xscale_trace
Remove misleading typedef and redundant suffix from struct xscale_trace.
2009-11-13 11:58:13 -08:00
Zachary T Welch
e76d085603 xscale_trace_entry_t -> struct xscale_trace_entry
Remove misleading typedef and redundant suffix from struct xscale_trace_entry.
2009-11-13 11:58:13 -08:00
Zachary T Welch
abd7b40408 target_event_action_t -> struct target_event_action
Remove misleading typedef and redundant suffix from struct target_event_action.
2009-11-13 11:58:13 -08:00
Zachary T Welch
55edfdf2ab arm_instruction_t -> struct arm_instruction
Remove misleading typedef and redundant suffix from struct arm_instruction.
2009-11-13 11:58:12 -08:00
Zachary T Welch
22f6a4cef5 arm9tdmi_vector_t -> struct arm9tdmi_vector
Remove misleading typedef and redundant suffix from struct arm9tdmi_vector.

Renames enum arm9tdmi_vector as enum arm9tdmi_vector_bit.
2009-11-13 11:58:12 -08:00
Zachary T Welch
18475360b2 xscale_reg_t -> struct xscale_reg
Remove misleading typedef and redundant suffix from struct xscale_reg.
2009-11-13 11:58:12 -08:00
Zachary T Welch
1f87cf4e80 xscale_common_t -> struct xscale_common
Remove misleading typedef and redundant suffix from struct xscale_common.
2009-11-13 11:58:12 -08:00
Zachary T Welch
ea34dc988f xscale_trace_data_t -> struct xscale_trace_data
Remove misleading typedef and redundant suffix from struct xscale_trace_data.
2009-11-13 11:58:12 -08:00
Zachary T Welch
73ad5cbb1a trace_point_t -> struct trace_point
Remove misleading typedef and redundant suffix from struct trace_point.
2009-11-13 11:58:12 -08:00
Zachary T Welch
151347585a debug_msg_receiver_t -> struct debug_msg_receiver
Remove misleading typedef and redundant suffix from struct debug_msg_receiver.
2009-11-13 11:58:12 -08:00
Zachary T Welch
93459582fd target_timer_callback_t -> struct target_timer_callback
Remove misleading typedef and redundant suffix from struct target_timer_callback.
2009-11-13 11:58:12 -08:00
Zachary T Welch
2d5767201b target_event_callback_t -> struct target_event_callback
Remove misleading typedef and redundant suffix from struct target_event_callback.
2009-11-13 11:58:12 -08:00
Zachary T Welch
46fc1d57ac working_area_t -> struct working_area
Remove misleading typedef and redundant suffix from struct working_area.
2009-11-13 11:58:12 -08:00
Zachary T Welch
c2b5d8a6fa reg_arch_type_t -> struct reg_arch_type
Remove misleading typedef and redundant suffix from struct reg_arch_type.
2009-11-13 11:58:12 -08:00
Zachary T Welch
74d09617b9 reg_cache_t -> struct reg_cache
Remove misleading typedef and redundant suffix from struct reg_cache.
2009-11-13 11:58:12 -08:00
Zachary T Welch
de3fb2f3bc bitfield_desc_t -> struct bitfield_desc
Remove misleading typedef and redundant suffix from struct bitfield_desc.
2009-11-13 11:58:12 -08:00
Zachary T Welch
f4e03e3b90 oocd_trace_t -> struct oocd_trace
Remove misleading typedef and redundant suffix from struct oocd_trace.
2009-11-13 11:58:12 -08:00
Zachary T Welch
b87f07110a mips_m4k_common_t -> struct mips_m4k_common
Remove misleading typedef and redundant suffix from struct mips_m4k_common.
2009-11-13 11:58:12 -08:00
Zachary T Welch
a8141cafde mips_ejtag_t -> struct mips_ejtag
Remove misleading typedef and redundant suffix from struct mips_ejtag.
2009-11-13 11:58:11 -08:00
Zachary T Welch
ccde06a08f mips32_core_reg_t -> struct mips32_core_reg
Remove misleading typedef and redundant suffix from struct mips32_core_reg.
2009-11-13 11:58:11 -08:00
Zachary T Welch
3b7aee21b5 mips32_common_t -> struct mips32_common
Remove misleading typedef and redundant suffix from struct mips32_common.
2009-11-13 11:58:11 -08:00
Zachary T Welch
1bd7a78d92 mips32_comparator_t -> struct mips32_comparator
Remove misleading typedef and redundant suffix from struct mips32_comparator.
2009-11-13 11:58:11 -08:00
Zachary T Welch
ef36a7fb3b image_mot_t -> struct image_mot
Remove misleading typedef and redundant suffix from struct image_mot.
2009-11-13 11:58:11 -08:00
Zachary T Welch
b154972bdb image_memory_t -> struct image_memory
Remove misleading typedef and redundant suffix from struct image_memory.
2009-11-13 11:58:11 -08:00
Zachary T Welch
1a4ff43a7c image_ihex_t -> struct image_ihex
Remove misleading typedef and redundant suffix from struct image_ihex.
2009-11-13 11:58:11 -08:00
Zachary T Welch
a87faf5b66 image_binary_t -> struct image_binary
Remove misleading typedef and redundant suffix from struct image_binary.
2009-11-13 11:58:11 -08:00
Zachary T Welch
24df46d067 image_section_t -> struct image_section
Remove misleading typedef and redundant suffix from struct image_section.
2009-11-13 11:58:11 -08:00
Zachary T Welch
99614219ad etmv1_trace_data_t -> struct etmv1_trace_data
Remove misleading typedef and redundant suffix from struct etmv1_trace_data.
2009-11-13 11:58:11 -08:00
Zachary T Welch
e2001ba211 etm_capture_driver_t -> struct etm_capture_driver
Remove misleading typedef and redundant suffix from struct etm_capture_driver.
2009-11-13 11:58:11 -08:00
Zachary T Welch
63242c6d45 etm_reg_t -> struct etm_reg
Remove misleading typedef and redundant suffix from struct etm_reg.
2009-11-13 11:58:11 -08:00
Zachary T Welch
01f9dc18fc etb_reg_t -> struct etb_reg
Remove misleading typedef and redundant suffix from struct etb_reg.
2009-11-13 11:58:11 -08:00
Zachary T Welch
2f7fc2921d embeddedice_reg_t -> struct embeddedice_reg
Remove misleading typedef and redundant suffix from struct embeddedice_reg.
2009-11-13 11:58:11 -08:00
Zachary T Welch
26a99ed740 cortex_m3_common_t -> struct cortex_m3_common
Remove misleading typedef and redundant suffix from struct cortex_m3_common.
2009-11-13 11:58:11 -08:00
Zachary T Welch
a1971ecacf cortex_a8_common_t -> struct cortex_a8_common
Remove misleading typedef and redundant suffix from struct cortex_a8_common.
2009-11-13 11:58:11 -08:00
Zachary T Welch
72b421418f watchpoint_t -> struct watchpoint
Remove misleading typedef and redundant suffix from struct watchpoint.
2009-11-13 11:58:11 -08:00
Zachary T Welch
e7f65c5a11 avr_common_t -> struct avr_common
Remove misleading typedef and redundant suffix from struct avr_common.
2009-11-13 11:58:10 -08:00
Zachary T Welch
4bc80e5a65 mcu_jtag_t -> struct mcu_jtag
Remove misleading typedef and redundant suffix from struct mcu_jtag.
2009-11-13 11:58:10 -08:00
Zachary T Welch
94f5ed90f1 armv7m_core_reg_t -> struct armv7m_core_reg
Remove misleading typedef and redundant suffix from struct armv7m_core_reg.
2009-11-13 11:58:10 -08:00
Zachary T Welch
5e43565ab5 armv7m_algorithm_t -> struct armv7m_algorithm
Remove misleading typedef and redundant suffix from struct armv7m_algorithm.
2009-11-13 11:58:10 -08:00
Zachary T Welch
e8a6e3b2f4 armv7m_common_t -> struct armv7m_common
Remove misleading typedef and redundant suffix from struct armv7m_common.
2009-11-13 11:58:10 -08:00
Zachary T Welch
2744a031cb armv7a_core_reg_t -> struct armv7a_core_reg
Remove misleading typedef and redundant suffix from struct armv7a_core_reg.
2009-11-13 11:58:10 -08:00
Zachary T Welch
5415d07139 armv7a_algorithm_t -> struct armv7a_algorithm
Remove misleading typedef and redundant suffix from struct armv7a_algorithm.
2009-11-13 11:58:10 -08:00
Zachary T Welch
248448ee3a armv7a_common_t -> struct armv7a_common
Remove misleading typedef and redundant suffix from struct armv7a_common.
2009-11-13 11:58:10 -08:00
Zachary T Welch
f6dae0cf84 armv4_5_mmu_common_t -> struct armv4_5_mmu_common
Remove misleading typedef and redundant suffix from struct armv4_5_mmu_common.
2009-11-13 11:58:10 -08:00
Zachary T Welch
405a5df786 armv4_5_cache_common_t -> struct armv4_5_cache_common
Remove misleading typedef and redundant suffix from struct armv4_5_cache_common.
2009-11-13 11:58:10 -08:00
Zachary T Welch
e976786d55 armv4_5_cachesize_t -> struct armv4_5_cachesize
Remove misleading typedef and redundant suffix from struct armv4_5_cachesize.
2009-11-13 11:58:10 -08:00
Zachary T Welch
2dd9c5e1da armv4_5_core_reg_t -> struct armv4_5_core_reg
Remove misleading typedef and redundant suffix from struct armv4_5_core_reg.
2009-11-13 11:58:10 -08:00
Zachary T Welch
15e8e45308 armv4_5_algorithm_t -> struct armv4_5_algorithm
Remove misleading typedef and redundant suffix from struct armv4_5_algorithm.
2009-11-13 11:58:10 -08:00
Zachary T Welch
056fcdb540 arm_jtag_t -> struct arm_jtag
Remove misleading typedef and redundant suffix from struct arm_jtag.
2009-11-13 11:58:10 -08:00
Zachary T Welch
c25e00b528 arm_load_store_multiple_instr_t -> struct arm_load_store_multiple_instr
Remove misleading typedef and redundant suffix from struct arm_load_store_multiple_instr.
2009-11-13 11:58:10 -08:00
Zachary T Welch
7de3c44320 arm_load_store_instr_t -> struct arm_load_store_instr
Remove misleading typedef and redundant suffix from struct arm_load_store_instr.
2009-11-13 11:58:10 -08:00
Zachary T Welch
f9e091a2d3 arm_data_proc_instr_t -> struct arm_data_proc_instr
Remove misleading typedef and redundant suffix from struct arm_data_proc_instr.
2009-11-13 11:58:10 -08:00
Zachary T Welch
67f2f83937 arm_b_bl_bx_blx_instr_t -> struct arm_b_bl_bx_blx_instr
Remove misleading typedef and redundant suffix from struct arm_b_bl_bx_blx_instr.
2009-11-13 11:58:09 -08:00
Zachary T Welch
f96d6054e6 swjdp_common_t -> struct swjdp_common
Remove misleading typedef and redundant suffix from struct swjdp_common.
2009-11-13 11:58:09 -08:00
Zachary T Welch
6ba48a1b44 swjdp_reg_t -> struct swjdp_reg
Remove misleading typedef and redundant suffix from struct swjdp_reg.
2009-11-13 11:58:09 -08:00
Zachary T Welch
785115a6a0 arm9tdmi_common_t -> struct arm9tdmi_common
Remove misleading typedef and redundant suffix from struct arm9tdmi_common.
2009-11-13 11:58:09 -08:00
Zachary T Welch
1ad4ee2deb arm966e_common_t -> struct arm966e_common
Remove misleading typedef and redundant suffix from struct arm966e_common.
2009-11-13 11:58:09 -08:00
Zachary T Welch
5f68f45186 arm926ejs_common_t -> struct arm926ejs_common
Remove misleading typedef and redundant suffix from struct arm926ejs_common.
2009-11-13 11:58:09 -08:00
Zachary T Welch
16487e7085 arm920t_tlb_entry_t -> struct arm920t_tlb_entry
Remove misleading typedef and redundant suffix from struct arm920t_tlb_entry.
2009-11-13 11:58:09 -08:00
Zachary T Welch
b174a0d75e arm920t_cache_line_t -> struct arm920t_cache_line
Remove misleading typedef and redundant suffix from struct arm920t_cache_line.
2009-11-13 11:58:09 -08:00
Zachary T Welch
8e77975b92 arm7tdmi_common_t -> struct arm7tdmi_common
Remove misleading typedef and redundant suffix from struct arm7tdmi_common.
2009-11-13 11:58:09 -08:00
Zachary T Welch
8012b3963f arm7_9_common_t -> struct arm7_9_common
Remove misleading typedef and redundant suffix from struct arm7_9_common.
2009-11-13 11:58:09 -08:00
Zachary T Welch
bcb18b2044 arm720t_common_t -> struct arm720t_common
Remove misleading typedef and redundant suffix from struct arm720t_common.
2009-11-13 11:58:09 -08:00
Zachary T Welch
f3b3752a9e arm11_sc7_action_t -> struct arm11_sc7_action
Remove misleading typedef and redundant suffix from struct arm11_sc7_action.
2009-11-13 11:58:09 -08:00
Zachary T Welch
3bcd9ad9d0 arm11_reg_state_t -> struct arm11_reg_state
Remove misleading typedef and redundant suffix from struct arm11_reg_state.
2009-11-13 11:58:09 -08:00
Zachary T Welch
55926f576f arm11_common_t -> struct arm11_common
Remove misleading typedef and redundant suffix from struct arm11_common.
2009-11-13 11:58:09 -08:00
Zachary T Welch
0eae94879d arm11_reg_defs_t -> struct arm11_reg_defs
Remove misleading typedef and redundant suffix from struct arm11_reg_defs.
2009-11-13 11:58:09 -08:00
Zachary T Welch
b1de5eb9a0 reg_param_t -> struct reg_param
Remove misleading typedef and redundant suffix from struct reg_param.
2009-11-13 11:58:09 -08:00
Zachary T Welch
6c965a3da9 mem_param_t -> struct mem_param
Remove misleading typedef and redundant suffix from struct mem_param.
2009-11-13 11:58:09 -08:00
Zachary T Welch
996613522d arm920t_common_t -> struct arm920t_common
Remove misleading typedef and redundant suffix from struct arm920t_common.
2009-11-13 11:58:08 -08:00
Zachary T Welch
52bc6cad87 arm11_register_history_t -> struct arm11_register_history
Remove misleading typedef and redundant suffix from struct arm11_register_history.
2009-11-13 11:58:08 -08:00
Zachary T Welch
ea49f2e3ff remove typedef keyword from svf structures
Removes all misleading typedef keywords from structures in svf.c.
2009-11-13 11:58:08 -08:00
Zachary T Welch
95bf461c0a pld_device_t -> struct pld_device
Remove misleading typedef and redundant suffix from struct pld_device.
2009-11-13 11:58:08 -08:00
Zachary T Welch
db08ab8a79 virtex2_pld_device_t -> struct virtex2_pld_device
Remove misleading typedef and redundant suffix from struct virtex2_pld_device.
2009-11-13 11:58:08 -08:00
Zachary T Welch
cd4c059806 xilinx_bit_file_t -> struct xilinx_bit_file
Remove misleading typedef and redundant suffix from struct xilinx_bit_file.
2009-11-13 11:58:08 -08:00
Zachary T Welch
db2086897a pld_driver_t -> struct pld_driver
Remove misleading typedef and redundant suffix from struct pld_driver.
2009-11-13 11:58:08 -08:00
Zachary T Welch
38d826cec1 connection_t -> struct connection
Remove misleading typedef and redundant suffix from struct connection.
2009-11-13 11:58:08 -08:00
Zachary T Welch
f7cd2aa0ef telnet_connection_t -> struct telnet_connection
Remove misleading typedef and redundant suffix from struct telnet_connection.
2009-11-13 11:58:08 -08:00
Zachary T Welch
f2cbaba3cc tcl_connection_t -> struct tcl_connection
Remove misleading typedef and redundant suffix from struct tcl_connection.
2009-11-13 11:58:08 -08:00
Zachary T Welch
8775a0f663 service_t -> struct service
Remove misleading typedef and redundant suffix from struct service.
2009-11-13 11:58:08 -08:00
Zachary T Welch
e01a0be576 telnet_service_t -> struct telnet_service
Remove misleading typedef and redundant suffix from struct telnet_service.
2009-11-13 11:58:08 -08:00
Zachary T Welch
45a165a432 gdb_service_t -> struct gdb_service
Remove misleading typedef and redundant suffix from struct gdb_service.
2009-11-13 11:58:08 -08:00
Zachary T Welch
53bfd73591 gdb_connection_t -> struct gdb_connection
Remove misleading typedef and redundant suffix from struct gdb_connection.
2009-11-13 11:58:08 -08:00
Zachary T Welch
43483e5054 remove unused aduc702x structure.
The ADUC702x_FLASH_MMIO structure was completely used, so it must die.
2009-11-13 11:58:08 -08:00
Zachary T Welch
a03c9a8dce aduc702x_flash_bank_t -> struct aduc702x_flash_bank
Remove misleading typedef and redundant suffix from struct
aduc702x_flash_bank.
2009-11-13 11:58:08 -08:00
Zachary T Welch
6a374afe71 tms470_flash_bank_t -> struct tms470_flash_bank
Remove misleading typedef and redundant suffix from struct tms470_flash_bank.
2009-11-13 11:58:08 -08:00
Zachary T Welch
3c9afaa645 pic32mx_mem_layout_t -> struct pic32mx_mem_layout
Remove misleading typedef and redundant suffix from struct pic32mx_mem_layout.
2009-11-13 11:58:08 -08:00
Zachary T Welch
54be77bc79 non_cfi_t -> struct non_cfi
Remove misleading typedef and redundant suffix from struct non_cfi.
2009-11-13 11:58:08 -08:00
Zachary T Welch
d0dfec33b6 nand_block_t -> struct nand_block
Remove misleading typedef and redundant suffix from struct nand_block.
2009-11-13 11:58:07 -08:00
Zachary T Welch
92fc7a6fde str9xpec_flash_controller_t -> struct str9xpec_flash_controller
Remove misleading typedef and redundant suffix from struct str9xpec_flash_controller.
2009-11-13 11:58:07 -08:00
Zachary T Welch
6aa82891b6 str9x_flash_bank_t -> struct str9x_flash_bank
Remove misleading typedef and redundant suffix from struct str9x_flash_bank.
2009-11-13 11:58:07 -08:00
Zachary T Welch
774d71f2cf str7x_mem_layout_t -> struct str7x_mem_layout
Remove misleading typedef and redundant suffix from struct str7x_mem_layout.
2009-11-13 11:58:07 -08:00
Zachary T Welch
3b09560ae8 str7x_flash_bank_t -> struct str7x_flash_bank
Remove misleading typedef and redundant suffix from struct str7x_flash_bank.
2009-11-13 11:58:07 -08:00
Zachary T Welch
01b10d65bf stm32x_mem_layout_t -> struct stm32x_mem_layout
Remove misleading typedef and redundant suffix from struct stm32x_mem_layout.
2009-11-13 11:58:07 -08:00
Zachary T Welch
c7b2cad52d stm32x_flash_bank_t -> struct stm32x_flash_bank
Remove misleading typedef and redundant suffix from struct stm32x_flash_bank.
2009-11-13 11:58:07 -08:00
Zachary T Welch
40273967bf stm32x_options_t -> struct stm32x_options
Remove misleading typedef and redundant suffix from struct stm32x_options.
2009-11-13 11:58:07 -08:00
Zachary T Welch
9059f9f28e stellaris_flash_bank_t -> struct stellaris_flash_bank
Remove misleading typedef and redundant suffix from struct stellaris_flash_bank.
2009-11-13 11:58:07 -08:00
Zachary T Welch
ed9c4ef3c4 s3c24xx_nand_controller_t -> struct s3c24xx_nand_controller
Remove misleading typedef and redundant suffix from struct s3c24xx_nand_controller.
2009-11-13 11:58:07 -08:00
Zachary T Welch
eba5608b52 pic32mx_flash_bank_t -> struct pic32mx_flash_bank
Remove misleading typedef and redundant suffix from struct pic32mx_flash_bank.
2009-11-13 11:58:07 -08:00
Zachary T Welch
5948e66ee8 orion_nand_controller_t -> struct orion_nand_controller
Remove misleading typedef and redundant suffix from struct orion_nand_controller.
2009-11-13 11:58:07 -08:00
Zachary T Welch
c7b96a4dc1 ocl_priv_t -> struct ocl_priv
Remove misleading typedef and redundant suffix from struct ocl_priv.
2009-11-13 11:58:07 -08:00
Zachary T Welch
958ff04b08 nand_info_t -> struct nand_info
Remove misleading typedef and redundant suffix from struct nand_info.
2009-11-13 11:58:07 -08:00
Zachary T Welch
f7ca047213 nand_manufacturer_t -> struct nand_manufacturer
Remove misleading typedef and redundant suffix from struct nand_manufacturer.
2009-11-13 11:58:07 -08:00
Zachary T Welch
8f4860d13f nand_ecclayout_t -> struct nand_ecclayout
Remove misleading typedef and redundant suffix from struct nand_ecclayout.
2009-11-13 11:58:07 -08:00
Zachary T Welch
8605352387 nand_flash_controller_t -> struct nand_flash_controller
Remove misleading typedef and redundant suffix from struct nand_flash_controller.
2009-11-13 11:58:07 -08:00
Zachary T Welch
4bc46d61ca mx3_nf_controller_t -> struct mx3_nf_controller
Remove misleading typedef and redundant suffix from struct mx3_nf_controller.
2009-11-13 11:58:07 -08:00
Zachary T Welch
79338ec6c2 mflash_bank_t -> struct mflash_bank
Remove misleading typedef and redundant suffix from struct mflash_bank.
2009-11-13 11:58:07 -08:00
Zachary T Welch
bb6b9988cb mg_drv_info_t -> struct mg_drv_info
Remove misleading typedef and redundant suffix from struct mg_drv_info.
2009-11-13 11:58:07 -08:00
Zachary T Welch
fc01dd6a13 mflash_gpio_drv_t -> struct mflash_gpio_drv
Remove misleading typedef and redundant suffix from struct mflash_gpio_drv.
2009-11-13 11:58:06 -08:00
Zachary T Welch
a043632a52 mflash_gpio_num_t -> struct mflash_gpio_num
Remove misleading typedef and redundant suffix from struct mflash_gpio_num.
2009-11-13 11:58:06 -08:00
Zachary T Welch
ed1aed8dd9 lpc3180_nand_controller_t -> struct lpc3180_nand_controller
Remove misleading typedef and redundant suffix from struct lpc3180_nand_controller.
2009-11-13 11:58:06 -08:00
Zachary T Welch
b712a4e8b8 lpc2900_flash_bank_t -> struct lpc2900_flash_bank
Remove misleading typedef and redundant suffix from struct lpc2900_flash_bank.
2009-11-13 11:58:06 -08:00
Zachary T Welch
12f83f0429 lpc288x_flash_bank_t -> struct lpc288x_flash_bank
Remove misleading typedef and redundant suffix from struct lpc288x_flash_bank.
2009-11-13 11:58:06 -08:00
Zachary T Welch
a15d4cc75e lpc2000_flash_bank_t -> struct lpc2000_flash_bank
Remove misleading typedef and redundant suffix from struct lpc2000_flash_bank.
2009-11-13 11:58:06 -08:00
Zachary T Welch
632fd663a8 flash_driver_t -> struct flash_driver
Remove misleading typedef and redundant suffix from struct flash_driver.
2009-11-13 11:58:06 -08:00
Zachary T Welch
fb59ec739a flash_sector_t -> struct flash_sector
Remove misleading typedef and redundant suffix from struct flash_sector.
2009-11-13 11:58:06 -08:00
Zachary T Welch
98d7ed8523 faux_flash_bank_t -> struct faux_flash_bank
Remove misleading typedef and redundant suffix from struct faux_flash_bank.
2009-11-13 11:58:06 -08:00
Zachary T Welch
de1781b7fa ecosflash_flash_bank_t -> struct ecosflash_flash_bank
Remove misleading typedef and redundant suffix from struct ecosflash_flash_bank.
2009-11-13 11:58:06 -08:00
Zachary T Welch
453a103f48 cfi_fixup_t -> struct cfi_fixup
Remove misleading typedef and redundant suffix from struct cfi_fixup.
2009-11-13 11:58:06 -08:00
Zachary T Welch
4c28cc68ed cfi_unlock_addresses_t -> struct cfi_unlock_addresses
Remove misleading typedef and redundant suffix from struct cfi_unlock_addresses.
2009-11-13 11:58:06 -08:00
Zachary T Welch
0139e7d51a cfi_spansion_pri_ext_t -> struct cfi_spansion_pri_ext
Remove misleading typedef and redundant suffix from struct cfi_spansion_pri_ext.
2009-11-13 11:58:06 -08:00
Zachary T Welch
2ded74115d cfi_atmel_pri_ext_t -> struct cfi_atmel_pri_ext
Remove misleading typedef and redundant suffix from struct cfi_atmel_pri_ext.
2009-11-13 11:58:06 -08:00
Zachary T Welch
1f328f2885 cfi_intel_pri_ext_t -> struct cfi_intel_pri_ext
Remove misleading typedef and redundant suffix from struct cfi_intel_pri_ext.
2009-11-13 11:58:06 -08:00
Zachary T Welch
3be0edbc5e cfi_flash_bank_t -> struct cfi_flash_bank
Remove misleading typedef and redundant suffix from struct cfi_flash_bank.
2009-11-13 11:58:06 -08:00
Zachary T Welch
a7a8a1c9e2 avrf_flash_bank_t -> struct avrf_flash_bank
Remove misleading typedef and redundant suffix from struct avrf_flash_bank.
2009-11-13 11:58:06 -08:00
Zachary T Welch
6ca63ee756 avrf_type_t -> struct avrf_type
Remove misleading typedef and redundant suffix from struct avrf_type.
2009-11-13 11:58:06 -08:00
Zachary T Welch
3877201581 at91sam7_flash_bank_t -> struct at91sam7_flash_bank
Remove misleading typedef and redundant suffix from struct at91sam7_flash_bank.
2009-11-13 11:58:05 -08:00
Zachary T Welch
246068fd89 jtag_command_t -> struct jtag_command
Remove useless typedef from struct jtag_command.
2009-11-13 11:58:05 -08:00
Zachary T Welch
1053c32d9e jtag_command_container_t -> union jtag_command_container
Remove misleading typedef from union jtag_container.
2009-11-13 11:58:05 -08:00
Zachary T Welch
22b220ad7f sleep_command_t -> struct sleep_command
Remove misleading typedef from struct sleep_command.
2009-11-13 11:58:05 -08:00
Zachary T Welch
cf2e402d71 end_state_command_t -> struct end_state_command
Remove misleading typedef from struct end_state_command.
2009-11-13 11:58:05 -08:00
Zachary T Welch
8cc8c0544f reset_command_t -> struct reset_command
Remove misleading typedef from struct reset_command.
2009-11-13 11:58:05 -08:00
Zachary T Welch
2fecae46f6 stableclocks_command_t -> struct stableclocks_command
Remove misleading typedef from struct stableclocks_command.
2009-11-13 11:58:05 -08:00
Zachary T Welch
5f6d8ecf8c runtest_command_t -> struct runtest_command
Remove misleading typedef from struct runtest_command.
2009-11-13 11:58:05 -08:00
Zachary T Welch
c07f0600ff pathmove_command_t -> struct pathmove_command
Remove misleading typedef from struct pathmove_command.
2009-11-13 11:58:05 -08:00
Zachary T Welch
af3f4a0bbe statemove_command_t -> struct statemove_command
Remove misleading typedef from struct statemove_command.
2009-11-13 11:58:05 -08:00
Zachary T Welch
e11c5a3b42 cmd_queue_page_t -> struct cmd_queue_page
Remove misleading typedef from struct cmd_queue_page.
2009-11-13 11:58:05 -08:00
Zachary T Welch
2ddeec9db5 scan_command_t -> struct scan_command
Remove misleading typedef on struct scan_command.
2009-11-13 11:58:05 -08:00
Zachary T Welch
4a29f8e21d more vsllink typedef cleanup
Remove useless typedef for struct insert_insignification_operation.
2009-11-13 11:58:05 -08:00
Zachary T Welch
7c0ba75eae vsllink_jtag_t -> struct vsllink
Remove misleading typedef and redundant suffix.
2009-11-13 11:58:05 -08:00
Zachary T Welch
ffc77b61dd presto_t -> struct presto
Remove useless typedef.
2009-11-13 11:58:05 -08:00
Zachary T Welch
a3f1c87eb7 ft2232_device_t -> struct ft2232_device
Remove misleading typedef from ft2232_device; it was barely used.
2009-11-13 11:58:05 -08:00
Zachary T Welch
4bc155398e jlink_jtag_t -> struct jlink
Remove misleading typedef and redundant suffix.
2009-11-13 11:58:05 -08:00
Zachary T Welch
9036fdd589 cable_t -> struct cable
Remove useless typedef and redundant suffix from parport struct cable.
2009-11-13 11:58:05 -08:00
Zachary T Welch
e1c26950c0 pending_scan_result_t -> struct pending_scan_result
Remove misleading typedef from struct struct pending_scan_result.
Future patches need to remove these duplicated types and code.
2009-11-13 11:58:04 -08:00
Zachary T Welch
8bbb279c28 armjtagew_jtag_t -> struct armjtagew
Remove useless typedef and redundant suffix from struct armjtatew_jtag.
2009-11-13 11:58:04 -08:00
Zachary T Welch
5874d5f2ea use struct jtag_tap_event_action
Remove useless typedef and redundant suffix from jtag_tap_event_action.
2009-11-13 11:58:04 -08:00
Zachary T Welch
363d72a484 jtag_event_callback_t -> struct jtag_event_callback
Remove useless typedef and redundant suffix from jtag_event_callback.
Add documentation for the structure.
2009-11-13 11:58:04 -08:00
Zachary T Welch
9f535f9af7 jtag_interface_t -> struct jtag_interface
Remove useless typedef and redundant suffix from struct jtag_interface.
2009-11-13 11:58:04 -08:00
Zachary T Welch
bee796b5b0 bitbang_interface_t -> struct bitbang_interface
Removes another useless typedef and suffix.
2009-11-13 11:58:04 -08:00
Zachary T Welch
c20b779b89 bitq_interface_t -> struct biq_interface
Remove useless typedef and redundant suffix.
2009-11-13 11:58:04 -08:00
Zachary T Welch
ff3150922b encapsulate bitq_state structure
Move the bitq_state structure from the header to source file, as it
is used internally.

Also removes its silly typedef.
2009-11-13 11:58:04 -08:00
Zachary T Welch
d0809ac060 scan_field_t -> struct scan_field
Remove useless structure typedef.
2009-11-13 11:58:04 -08:00
Zachary T Welch
42ef503d37 jtag_tap_t -> struct jtag_tap
Search and destroy the jtag_tap_t typedef.  This also cleans up a
layering violation, removing the declaration from types.h.
2009-11-13 11:58:04 -08:00
Zachary T Welch
9f212b01be fileio_t -> struct fileio
Remove useless structure typedef.
2009-11-13 11:58:04 -08:00
Zachary T Welch
f59ec2043b log_callback_t -> struct log_callback
Removes useless and confusing typedef for log callback structure.
Types with _t should be suitable for passing by-value as arguments.
2009-11-13 11:58:04 -08:00
Zachary T Welch
99b57b6dcc remove accidental artifact
Somehow I managed to slip a temporary build file into the tree.
Remove it and update the .gitignore file so it doesn't happen again.
2009-11-13 11:52:53 -08:00
Zachary T Welch
ebbc762182 add documention for writing built-in commands
This documentation update provides an introduction to the command
handling facilities provided by command.[ch].  A primer walks the user
through the elements of a pointedly pedantic module: src/hello.c.

A summary of the API is provided in the OpenOCD Architecture section.
2009-11-13 11:02:22 -08:00
Zachary T Welch
89870c86e7 add src/hello.c to augment new command tutorial
The hello module provides the 'hello' command, printing a greetings
to the command console.  It can grow to serve as pedagogical example
of services that OpenOCD developers should use: a runnable style guide.
2009-11-13 10:57:57 -08:00
Zachary T Welch
f973320cbb command_handler_t: make cmd an indirect parameter
This patch removes 'cmd' from the list of direct parameters, moving
that pointer to args[-1] (by way of the new CMD_NAME macro).
2009-11-13 10:56:55 -08:00
Zachary T Welch
deede35c27 command_handler_t: make args parameter const
This patch prevents command handlers from modifying the strings passed
in the 'args' array.
2009-11-13 10:55:27 -08:00
Zachary T Welch
cc63d6e72b command_handler_t: make cmd parameter const
Prevents the command name from being modified in command handlers.
Again, this has cascading effects, but the patches are fairly minimal.
2009-11-13 10:55:27 -08:00
Zachary T Welch
d22270e0ed command_handler_t: make argc unsigned
The number of command arguments will always be 0 or more, so use
the right type in handlers.  This has a cascading effect up through
the layers, but the new COMMAND_HANDLER macros prevented total chaos.
2009-11-13 10:55:27 -08:00
Zachary T Welch
a585bdf726 add CMD_NAME macro for command handlers
By introducing the CMD_NAME macro, this parameter may be integrated
as args[-1] in command.[ch], without touching any other call sites.
2009-11-13 10:55:00 -08:00
Zachary T Welch
5b6df55a1e use CALL_COMMAND_HANDLER instead of direct calls
By using CALL_COMMAND_HANDLER, parameters can be reordered, added, or
even removed in inherited signatures, without requiring revisiting
all of the various call sites.
2009-11-13 10:51:46 -08:00
Zachary T Welch
1df5cc18f5 add PLD_DEVICE_COMMAND_HANDLER macro
Update virtex module to use abstracted PLD command handling.
2009-11-13 10:51:46 -08:00
Zachary T Welch
670f999e7a nand: add NAND_DEVICE_COMMAND_HANDLER macro
Abstracts the extended NAND command handling to allow the function
signature to be controlled by __COMMAND_HANDLER.
2009-11-13 10:51:46 -08:00
Zachary T Welch
0796dfff89 use FLASH_BANK_COMMAND_HANDLER macro
Defines all flash_bank_command handlers using the new macro.
2009-11-13 10:51:46 -08:00
Zachary T Welch
57c5c5f463 add FLASH_BANK_COMMAND_HANDLER macro
The FLASH_BANK_COMMAND_HANDLER provides an extended command handler
using the __COMMAND_HANDLER macro, whereby changing that macro is
sufficient to update flash handlers with the new signature.  It also
enforces uniform style and scope when implementing this handler.
2009-11-13 10:51:46 -08:00
Zachary T Welch
76868e0713 s3c24xx: use COMMAND_HANDLER with command helper
Add S3C24XX_DEVICE_COMMAND macros to abstract common command handler
conventions.
2009-11-13 10:51:46 -08:00
Zachary T Welch
d02fee197f arm_adi,armv7[am]: use COMMAND_HELPER for helpers
Rewrites the dap_* command helpers to use the COMMAND_HELPER paradigm.
Uses CALL_COMMAND_HELPER to hide inherited calling conventions.
2009-11-13 10:51:46 -08:00
Zachary T Welch
63a26b421b use COMMAND_HELPER for command helper functions
Define the numerous helpers that inherit command handler parameters
using the COMMAND_HELPER macro.
2009-11-13 10:51:45 -08:00
Zachary T Welch
cfc4d5c6b7 use COMMAND_HANDLER macro to define all commands 2009-11-13 10:51:45 -08:00
Zachary T Welch
ddb6138ed4 add command_handler_t type
This patch adds new typedefs for command handler callback functions.
Users of this type signature were updated to use these new types.
It uses the new __COMMAND_HANDLER macro to prevent duplication.
2009-11-13 10:51:45 -08:00
Zachary T Welch
3f9fd4e2a6 add COMMAND_HANDLER and COMMAND_HELPER macros
The COMMAND_HANDLER and COMMAND_HELPER macros allow commands to be
defined in a manner that decouples them from the exact order and type of
their parameters.  Once converted, incremental changes to the command
handler type can be addressed in incremental patches that do not need to
touch the entire tree.

These macros' implementation, __COMMAND_HANDLER, is used to define the
new command_handler_t type, and additional patches will use it to derive
new macros to define extended command types (e.g. flash, nand, pld).
The CALL_COMMAND_HANDLER provides a means of calling helpers or nested
handlers from withing a command handler.

This patch uses C99 varadic macro expansion.  Please report compilers
that cannot handle this code.
2009-11-13 10:51:45 -08:00
Zachary T Welch
1ae4d93c3c add command_output_handler_t
Add a typedef for command output handler function type, simplifying
the appearance of functions that use it and eliminating duplicate code.
2009-11-13 10:51:45 -08:00
David Brownell
5eb638c71e Cortex-A8: fix indent
The "remove (forward) declarations" patch goofed indentation on the
"cortexa8_target" struct; fix.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-13 08:45:20 -08:00
Zachary T Welch
e8e94ab245 nand: rename device to nand
To be more informative (and consistent with flash and pld trees), change
'device' parameter name to 'nand' in NAND source files.  This change
eliminates confusing 'device->device->' instance from the code, and
it simplifies the forthcoming command handler patches.
2009-11-12 22:25:55 -08:00
David Brownell
d47764ff71 ETM: start support for ETMv2+
ARM11 and newer cores include updated ETM modules.  Recognize
their version codes and some key config differences.  Sanity
checked on an OMAP2, with an ETM11RV r0p1 (ETMv3.1).

This still handles only scan chain 6, with at most 128 registers.
Newer cores (mostly, Cortex) will need to use the DAP instead.

Note that the newer ETM modules don't quite fit the quirky config
model of the older ones ... having more port widths is easy, but
the modes aren't the same.  That still needs to change.

Fix a curious bug ... how did the register cache NOT get saved??

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-12 20:24:41 -08:00
Liam Redmond
26849ad60d WinXP-x64: find right D2XX libraries
This trivial patch allows the config script to find the correct
FTDI2xx libraries under Windows XP x64 using msys.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-12 12:50:41 -08:00
Jonas Horberg
de735d375b parport: add support for the jtag_khz command.
Add the khz and speed_div functions to the parport interface driver.
Add the parport_toggling_time function that tells the parport driver
how long (in nanoseconds) it takes for the hardware to toggle TCK.

[dbrownell@users.sourceforge.net: tweak doc for clarity, mention
multimeter, and whitespace fixes]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-12 12:39:37 -08:00
David Brownell
5723e54fa9 ETM: remove old mid-level ETM handle
Now that nothing uses the old ETM handle any more, remove it.
Add minimal header tweaks, letting non-ARM7 and non-ARM9 cores
access ETM facilities.

Now ARM11 could support standard ETM (and ETB) access as soon as
it derives from "struct arm" ... its scanchain 6 is used access
the ETM, just like ARM7 and ARM9.

The Cortex parts (both M3 and A8) will need modified access methods
(via ETM init parameters), so they use the DAP.  Our first A8 target
(OMAP3) needs that for both ETM and ETB, but the M3 ETM isn't very
useful without SWO trace support (it's painfully stripped down), so
that support won't be worth adding for a while.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-11 21:57:44 -08:00
David Brownell
e740536568 ETM: use new toplevel ETM handle
Make ETM itself use the new toplevel ETM handle, instead
of the to-be-removed lower level one.  As of this patch,
nothing should be using the old ARM7/ARM9-specific handle.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-11 21:55:19 -08:00
David Brownell
9855a11edd ETM: update port drivers
Make both useful ETM port drivers (etb, etm_dummy) use the new
toplevel ETM handle, instead of the to-be-removed lower level one.

Do the same for the "oocd-trace" prototype too; and fix its
error reporting paths:  return failure codes, don't exit(), etc

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-11 21:52:02 -08:00
David Brownell
3ae4401901 ETM: update arm[79]tdmi_examine()
Make ARM7 and ARM9 cores use the new toplevel ETM handle to
trigger ETM setup, not the to-be-removed lower level one.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-11 21:50:10 -08:00
David Brownell
4b20ed6b5c ARM: start generalized base type
Rename "struct armv4_5_common_s" as "struct arm".  It needs
a bit more work to be properly generic, and to move out of
this header, but it's the best start we have on that today.

Add and initialize an optional ETM pointer, since that will
be the first thing that gets generalized.

The intent being:  all ARMs should eventually derive from
this "struct arm", so they can reuse the current ETM logic.
(And later, more.)  Currently the ARM cores that *don't* so
derive are only ARMv7-M (and thus Cortex-M3) and ARM11.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-11 21:49:14 -08:00
Zachary T Welch
5e1b500b17 fix 'jtag interface' behavior
Without this patch, running "openocd -c 'jtag interface'" segfaults.
Now, it returns the string "undefined" when the interface is unset.
2009-11-11 14:04:06 -08:00
Zachary T Welch
158698e333 improve command registration
Eliminate duplicate code for linking commands into a list.

Adds a check to ensure the command does not already exist;
if it does, return that one instead of creating a duplicate.
2009-11-11 13:50:28 -08:00
Zachary T Welch
46d9ba4c8b add help regardless of callback
Add help for commands regardless of whether a handler is involved.
With this, all sorts of new commands can be found in 'help' text.
Hopefully, all of them have been documented....

Sadly, the lsort function appears to handle nested lists poorly, such
that sub-commands do not group with their parents.
2009-11-11 12:15:39 -08:00
Zachary T Welch
a1a3ee579c eliminate duplicate helptext management
Add helpers to manage adding entries to the helptext list.
Adds support for arbitrarily nested commands.
2009-11-11 12:15:39 -08:00
Zachary T Welch
2d3cc1eac1 add command_name helper
The command_name function returns a malloced string for a given
command and its parents.  This can be used to display a message
to the user, but it is used internally to handle registration
and syntax errors.  This helps permit arbitrary command nesting.
2009-11-11 12:15:39 -08:00
Zachary T Welch
f93c98081f wrap help command
Use continuation characters to wrap the help command into 80 columns.
2009-11-11 12:15:39 -08:00
Zachary T Welch
2821115ab8 remove obsolete doxygen comments
Documenting command handler parameters is redundant and pointless.
2009-11-11 11:53:22 -08:00
Zachary T Welch
39ab1c1a41 remove more useless declarations
Removes forward declarations by moving command registration after
defintion of the command handlers.
2009-11-11 11:53:22 -08:00
Zachary T Welch
e997431602 cortex_a8: remove declarations, use static keyword 2009-11-11 11:53:22 -08:00
Zachary T Welch
ca594adb5a add const keyword to some APIs
Add 'const' keyword to 'char *' parameters to allow command handlers to
pass constant string arguments.  These changes allow the 'args' command
handler to be changed to 'const' in a subsequent patch.
2009-11-11 11:53:22 -08:00
Zachary T Welch
9741e126fd change argv to args in command handlers
Subsequent patches expect all command handlers to use a uniform
parameter naming scheme.  In the entire tree, these two files used
standard 'argv' instead of our non-standard 'args'.  This patch opts
to reduces the noise required to unify the command handlers, using
dominant 'args' form.

A future patch may be used to convert us back to the standard argv, but
that requires coordination with all developers to minimize disruptions.
2009-11-11 11:50:36 -08:00
Zachary T Welch
e09d8938f5 script_debug(): improve types
Use unsigned type for number of arguments.
2009-11-11 05:40:48 -08:00
Zachary T Welch
c942969377 command.c: make private routines static
This patch also improves the signature of run_command function.
2009-11-11 05:40:48 -08:00
Zachary T Welch
6a2e83c017 log: improve log_callback_fn signature
Use unsigned type for line number in log_callback_fn signature.
2009-11-11 05:40:48 -08:00
Zachary T Welch
0cd414c7d6 time_support: improve use of types
Update timeval_add_time to use long int; implement timeval_add with it.
Update timeval_ms to check gettimeofday return value, return int64_t.
2009-11-11 05:40:48 -08:00
Zachary T Welch
b7b4efcdf1 makefiles: improve build order
Separates various groups of files to be built in logical succession.
In each layer, the core module (target.c, nand.c, etc.) is built _after_
their helper modules (e.g. image.c, nand_ecc.c) but _before_ any of
their drivers (e.g. arm966e.c, mx3_nand.c).

This allows problems introduced at the bottom of the stack to result
in build failures as soon as possible, as the helpers and core should
wrap portions of them.
2009-11-11 05:40:48 -08:00
David Brownell
d796ce0e4d ETM cleanup
Various cleanups of ETM related code.

 - Saner error return paths
 - Simplify arm7_9 init ... no need for extra zeroing!
 - Shrink some lines
 - Tweak some diagnostics
 - Use shorter name for ETM struct type.
 - Don't exit()

and similar.  The diagnostics look forward to having
this ETM code work with more than just ARM7/ARM9.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-11 04:42:50 -08:00
Zachary T Welch
583a293a32 fix bug in ARM720: bugfix 2009-11-10 21:02:30 -08:00
David Brownell
d570e4f6f6 ARM720: bugfix
The "ARM720 uses the new inheritance/nesting scheme" patch
wrongly scrubbed a calloc() from arm720t_target_create().

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-10 19:06:10 -08:00
David Brownell
61af6a6816 target: MMU-aware init for memory read/write
Start switching MMU handling over to a more sensible scheme.
Having an mmu() method enables MMU-aware behaviors.  Not having
one kicks in simpler ones, with no distinction between virtual
and physical addresses.

Currently only a handful of targets have methods to read/write
physical memory:  just arm720, arm920, and arm926.  They should
all initialize OK now, but the arm*20 parts don't do the "extra"
stuff arm926 does (which should arguably be target-generic).

Also simplify how target_init() loops over all targets by making
it be a normal "for" loop, instead of scattering its three parts
to the four winds.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-10 11:58:31 -08:00
David Brownell
6881c1b6d6 target.cfg: (re)move some bogus reset_config lines
General rule, this is all board-specific and doesn't belong
in target config files.  Some of these were just cosmetic.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-10 09:25:26 -08:00
Thomas Kindler
85944d4144 stm32.cfg: remove reset_config
Here's a patch for the double-reset problem on STM32.  I've tested
downloading and debugging with GDB and Eclipse, and everything seems
to work fine.

This effectively sets reset_config to none. trst_only would also
be ok, but that's better left to a board configuration file since
not all boards wire it up.

The NVIC is used to trigger reset, which at least on this chip also
pulses nSRST so the whole system does get rest -- exactly once.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-10 09:16:12 -08:00
Michael Bruck
627bd19768 arm11: add etmr/etmw registers to access ETM via DBGTAP scan chain
First cut of these commands. Øyvind tinkered a bit with
the number parsing to bring it up to speed + rebased it.
Ready for testing.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-10 14:00:24 +01:00
Øyvind Harboe
c202ba7d34 ARM11: remove old mrc/mcr commands
Switch to new commands in config scripts

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-10 13:13:13 +01:00
Øyvind Harboe
1f357869c1 telo.cfg: fix search paths
Add the missing "target/" prefix for scripts in the
target folder.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-10 13:11:17 +01:00
David Brownell
2a4d3c03cd Target: minor cleanup
- improve some names -- a "default" prefix is not descriptive
 - add doxygen @todo entries for some issues
 - avr8 isn't ever going to need those MMU hooks

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-10 02:01:20 -08:00
David Brownell
508e5c803f ARM920: implement basic MMU ops
mmu() works; virt2phys() fails and logs an error.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-10 01:36:59 -08:00
David Brownell
65e3471d78 ARM720: implement basic MMU ops
mmu() works; virt2phys() fails and logs an error.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-10 01:35:50 -08:00
David Brownell
0df56714a0 Target: fix bad error messages
And shrink a few too-long lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-10 01:33:59 -08:00
Øyvind Harboe
031591ead5 httpd: fix warnings, more robust error handling, improved MIME handling
The httpd is work in progress...

No mime type set by default. Let the browser guess.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-10 08:50:06 +01:00
Øyvind Harboe
151a270695 tcl: HostOs now picks up eCos as well during compile time
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-10 08:36:19 +01:00
Zachary T Welch
db6c2871dd svf,xsvf,arm7_9_common: trim forard declarations
Remove forward declarations by reordering command registration.
2009-11-09 21:39:46 -08:00
Zachary T Welch
841721929a command.c: make commands static
Removes useless declarations, moving the handler functions to appear
before their use in the (much bigger) command registriation function.
2009-11-09 21:39:46 -08:00
Zachary T Welch
23d88e5774 server: remove useless declarations
Remove server command declarations, make handler routines static.
2009-11-09 21:39:46 -08:00
Zachary T Welch
8d6dcb9d39 jtag: remove useless declarations
Contrary to my previous assessment, some opportunities to remove forward
declarations were overlooked.  Remove them by moving the definitions
of the command registration and interface structure to the end of files.
2009-11-09 21:39:28 -08:00
Zachary T Welch
ef6387a0c9 target.c: remove useless declarations
This patch removes the last batch of forward references from the tree,
moving the target command registration routines to the end of the file.
2009-11-09 19:24:06 -08:00
Zachary T Welch
2351641b8f {pic32m,stm32}x.c: remove useless declarations
Remove useless forward declarations.
Moves command registrations to end of files.
Moves flash structure definitions to end of files.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-09 18:42:48 -08:00
Zachary T Welch
6cd97f48d0 str{7,9}x*.c: remove useless forward declarations
Remove useless forward declarations.
Moves command registrations to end of files.
Moves flash structure definitions to end of files.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-09 18:42:47 -08:00
Zachary T Welch
041c319d9d flash/<various>.c: remove useless declarations
Remove useless forward declarations.
Moves flash structure definitions to end of files.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-09 18:42:47 -08:00
Zachary T Welch
712d3fc0fb flash/<assorted>.c: remove useless declarations
Remove useless forward declarations.
Moves command registrations to end of files.
Moves flash structure definitions to end of files.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-09 18:42:47 -08:00
Zachary T Welch
4cd02c63e9 flash/at91sam[37].c: remove useless declarations
Remove useless forward declarations.
Moves command registration to end of file.
Moves flash structure definitions to end of files.

Changes a few references to global flash structure to local refs.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-09 18:42:47 -08:00
Zachary T Welch
770716e9e0 flash/lpc2???.c: remove useless declarations
Remove useless forward declarations.
Moves command registrations to end of files.
Moves flash structure definitions to end of files.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-09 18:42:47 -08:00
Zachary T Welch
8b5c5c054d flash/*nand*.c: remove useless declarations
Remove useless forward declarations.
Moves command registration to end of files.
Moves flash structure definition to end of files.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-09 18:42:47 -08:00
Zachary T Welch
5c95741df7 flash/flash.c: remove forward declarations
Remove useless forward declarations.
Moves command registration to end of file.
Moves flash structure definition to end of file.

Signed-off-by: Zachary T Welch <zw@superlucidity.net>
2009-11-09 18:42:47 -08:00
David Brownell
7269ba5eb6 Revert "target: add target->type->has_mmu fn"
This patch introduced a bug preventing flash writes from working
on Cortex-M3 targets like the STM32.  Moreover, it's the wrong
approach for handling no-MMU targets.

The right way to handle no-MMU targets is to provide accessors
for physical addresses, and use them everywhere; and any code
which tries to work with virtual-to-physical mappings should use
a identity mapping (which can be defaulted).

And ... we can tell if a target has an MMU by seeing if it's
got an mmu() method.  No such methood means no MMU.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-09 14:46:23 -08:00
David Brownell
d70d9634bf finish removing deprecated/obsolete commands
It's been about a year since these were deprecated and, in most
cases, removed.  There's no point in carrying that documentation,
or backwards compatibility for "jtag_device" and "jtag_speed",
around forever.  (Or a few remnants of obsolete code...)

Removed a few obsolete uses of "jtag_speed":

 - The Calao stuff hasn't worked since July 2008.  (Those Atmel
   targets need to work with a 32KHz core clock after reset until
   board-specific init-reset code sets up the PLL and enables a
   faster JTAg clock.)
 - Parport speed controls don't actually work (tops out at about
   1 MHz on typical HW).
 - In general, speed controls need to live in board.cfg files (or
   sometimes target.cfg files), not interface.cfg ...

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-09 13:16:32 -08:00
David Brownell
9253ce9bae User's Guide: Flash/NAND doc tweaks
Rename the "Drivers, Options, and Commands" sections to be
just "Driver List" matching the earlier reference.  Add an
example of parallel CFI flash.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-09 12:02:23 -08:00
Zachary T Welch
3885ab5a5a src/target: remove 'extern' and wrap headers
Remove extern keywords from function prototypes and wrap long lines.
2009-11-09 09:44:33 -08:00
Zachary T Welch
42cafc9369 target.h: remove extern keyword and wrap
Removes 'extern' keyword from function prototypes and wraps long lines.
2009-11-09 09:44:33 -08:00
Zachary T Welch
994a63c3fe src/{server,pld,svf,xsvf}: remove 'extern' keyword
Removes 'extern' keyword from function declarations in header filess.
2009-11-09 09:44:33 -08:00
Zachary T Welch
81fbc63718 src/flash: remove 'extern' and wrap headers
Removes 'extern' keywords from function prototypes in the flash headers.
Wraps long lines to fit into 80 columns.

Adds multiple inclusion protection for s3c2xx_nand.h.
2009-11-09 09:44:33 -08:00
Zachary T Welch
5e9d18f027 src/jtag: remove 'extern' and wrap headers.
Removes the 'extern' keyword from function declarations.
Wraps long prototypes to fit into 80 columns.

Fixes documentation for jtag_tap_s::{,has}idcode fields.
2009-11-09 09:44:33 -08:00
Zachary T Welch
1712d7835e src/helper: wrap and clean headers.
Remove all useless 'extern' keywords from function prototypes.
Wraps long lines for readability.
2009-11-09 09:44:33 -08:00
David Brownell
4882647f3e User's Guide: bugfix global state info
The "$ocd_HOSTOS" variable was wrongly documented.  Fix its
documentation, and its value on Linux.

Shrink a few of the too-long lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-09 09:40:55 -08:00
David Brownell
526347f959 EmbeddedICE: minor cleanups
Add comments (Doxygen and normal), remove unused code,
shrink some overlong lines.  Get rid of a forward decl.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-09 09:34:51 -08:00
Zachary T Welch
2689f58f2a Overhaul time support API
This patch changes the duration_* API in several ways.  First, it
updates the API to use better names.  Second, string formatting has
been removed from the API (with its associated malloc).  Finally, a
new function added to convert the time into seconds, which can be
used (or formatted) by the caller.  This eliminates hidden calls to
malloc that require associated calls to free().

This patch also removes the useless extern keyword from prototypes,
and it eliminates the duration_t typedef (use 'struct duration').
These API also allows proper error checking, as it is possible for
gettimeofday to fail in certain circumstances.

The consumers have all been chased to use this new API as well, as
there were relatively few cases doing this type of measurement.
In most cases, the code performs additional checks for errors, but
the calling code looks much cleaner in every case.
2009-11-09 01:21:50 -08:00
Zachary T Welch
da3196bf5e Add private header for ARM11 internals.
Reduces confusion about location of associated routines and
reduces clutter in the arm11 header.

Removes extra whitespace around the lines touched by these changes.
2009-11-08 15:47:04 -08:00
Zachary T Welch
e41147bf75 ARM11: remove exports and forward decls
Unneeded exports cause confusion about the module interfaces.
Make almost everything static in the arm11.c module.
2009-11-08 15:47:04 -08:00
David Brownell
b2d01a9e6a ARM: minor simulator cleanup
Make several functions be static.  Shrink some of the overlong
lines.  Use pure tab indents in some places that mixed in spaces.
This gives a minor object code shrink (about 2% on amd64).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-08 12:44:28 -08:00
David Brownell
7d9df4b134 Cortex-M3: fix (debug) message priority
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-08 12:23:17 -08:00
David Brownell
3e6f9e8d1e target.cfg: remove "-work-area-virt 0"
The semantics of "-work-area-virt 0" (or phys) changed with
the patch to require specifying physical or virtrual work
area addresses.  Specifying zero was previously a NOP.  Now
it means that address zero is valid.

This patch addresses three related issues:

 - MMU-less processors should never specify work-area-virt;
   remove those specifications.  Such processors include
   ARM7TDMI, Cortex-M3, and ARM966.

 - MMU-equipped processors *can* specify work-area-virt...
   but zero won't be appropriate, except in mischievous
   contexts (which hide null pointer exceptions).

   Remove those specs from those processors too.  If any of
   those mappings is valid, someone will need to submit a
   patch adding it ... along with a comment saying what OS
   provides the mapping, and in which context.  Example,
   say "works with Linux 2.6.30+, in kernel mode".  (Note
   that ARM Linux doesn't map kernel memory to zero ...)

 - Clarify docs on that "-virt" and other work area stuff.

Seems to me work-area-virt is quite problematic; not every
operating system provides such static mappings; if they do,
they're not in every MMU context...

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-08 08:52:40 -08:00
Zachary T Welch
2b1bd97508 Fix vsllink bulk out endpoint parsing. 2009-11-07 13:36:47 -08:00
David Brownell
fb50efc6e7 Merge branch 'master' of ssh://dbrownell@openocd.git.sourceforge.net/gitroot/openocd/openocd 2009-11-06 15:01:46 -08:00
David Brownell
a9abfa7d06 target: don't swap MMU/no-MMU work areas
Resolve serious bug inserted by the "target: require working
area for physical/virtual addresses to be specified" patch.
It forced use of (invalid) virtual addresses when the MMU
was disabled, and vice versa.

Observed to break at least Cortex-M3, ARM926, ARM7TDMI whenever
work areas are used, such as during bulk writes to flash, DDR2,
SRAM, and so on.

Also, fix overlong lines and whitespace goofs.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-06 14:57:21 -08:00
Zachary T Welch
ca00483a95 Simplify nand indentation.
Removes check covered by new nand_command_get_device_by_num helper.
Reverses logic of probe check to further reduce indentation.
2009-11-06 02:52:56 -08:00
Zachary T Welch
ff61e6a37c Improve flash indentation.
Removes redundant tests and reverses backwards logic to reduce the
indentation level in flash.c.
2009-11-06 02:52:51 -08:00
Zachary T Welch
c5f56437c0 Fix arm11 vcr command parsing. 2009-11-06 02:36:56 -08:00
David Brownell
6a0af06bd9 ARM: shrink offsets
Move various embedded target structs to the beginnings of
their containers ... pretty much the way C++ or Obj-C
would for single inheritance.

This shrinks code that accesses those embedded structs by
letting common offsets use smaller instructions.  Sample
before/after sizes (on amd64):

  17181	    312	      0	  17493	   4455	arm920t.o
  16810	    312	      0	  17122	   42e2	arm920t.o

Where the "after" is the smaller number, with this patch
over the ones leveraging that embedding knowledge.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:04:25 -08:00
David Brownell
03ac53a2cf ARM: other code uses the new inheritance/nesting scheme
Remove most remaining uses of target->arch_info from ARM
infrastructure, where it hasn't already been updated.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:04:22 -08:00
David Brownell
a81df55f39 Cortex-A8: use the new inheritance/nesting scheme
Use target_to_armv7a() etc, replacing needless pointer traversals.
Stop using X->arch_info scheme in most ARMv7-A and Cortex-A8 code.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:04:13 -08:00
David Brownell
fec3c4763a ARM7TDMI uses the new inheritance/nesting scheme
Use target_to_arm7_9(), replacing needless pointer traversals.

Also:  remove now-useless contents of arm7tdmi struct; it's
almost ready to be removed.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:04:04 -08:00
David Brownell
11fe2ec62e ARM720 uses the new inheritance/nesting scheme
Use target_to_arm720(), replacing needless pointer traversals
and simplifying a bunch of nasty code.  Stop setting arch_info
for arm720 type parts, it's not used any longer.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:03:56 -08:00
David Brownell
6cf956fa9d XScale uses the new inheritance/nesting scheme
Use target_to_xscale(), replacing needless pointer traversals
and simplifying a bunch of code.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:03:45 -08:00
David Brownell
178c758096 ARM9TDMI uses the new inheritance/nesting scheme
Replace needless pointer traversals and simplify.  Also remove most
remaining contents from arm9tdmi struct; it's almost removable.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:03:40 -08:00
David Brownell
865ed6ed81 ARM966 uses the new inheritance/nesting scheme
Use target_to_arm966(), replacing needless pointer traversals.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:03:33 -08:00
David Brownell
1fcb351de6 ARM926 uses the new inheritance/nesting scheme
Use target_to_arm926(), replacing needless pointer traversals
and simplifying a bunch of code.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:03:30 -08:00
David Brownell
6e08573efd FA526 uses the new inheritance/nesting scheme
Replace needless pointer traversals, simplify.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:03:24 -08:00
David Brownell
9be533566e ARM920 uses the new inheritance/nesting scheme
Use target_to_arm920(), replacing needless pointer traversals
and simplifying.  Stop setting arm9tdmi->arch_info for arm920
type parts, it's not used any longer.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 22:03:13 -08:00
David Brownell
da739aa257 Cortex-M3: use the new inheritance/nesting scheme
Use new target_to_cm3() and target_to_armv7m() inlines,
instead of a series of x->arch_info conversions.  Remove
arch_info, since nothing uses it.

Also fix an omission:  the Cortex-M3 commands didn't verify
that they were operating on that kind of target.  Add comment
about the ARMv7M version of that omission.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 21:59:45 -08:00
David Brownell
db116b1ea3 target: provide container_of()
Provide a cleaner way to handle single inheritance of targets
in C, using the same model Linux does:  structs containing other
structs, un-nested via calls to a "container_of()" macro that
are packaged in typesafe inline functions.

Targets already use this containment idiom, but make it much
more complicated because they un-nest using embedded "void *"
pointers ... in chains of up to five per target, which is all
pure needless complication.  (Example: arm92x core, arm9tdmi,
arm7_9, armv4_5 ... on top of the base "target" class.)

Applying this scheme consistently simplifies things, and gets
rid of many error-prone untyped pointers.  It won't change any
part of the type model though -- it just simplifies things.
(And facilitates more cleanup later on.)

Rule of thumb:  where there's an X->arch_info void* pointer,
access to that pointer can and should be removed.  It may be
convenient to set up pointers to some of the embedded structs;
and shrink their current "*_common" names (annoyingly long).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 21:59:39 -08:00
David Brownell
b7e4c26b9b ARM7TDMI: remove forward decls
The forward decls are just code clutter; remove them, by moving
their references after definitions.  This is another file which
never needed even one internal forward declaration.

Also shrink a few overly-long lines with function declarations
or definitions;  get rid of arm7tdmi_register_commands(), it's
not needed (just delegated); minor whitespace declutter.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 20:36:42 -08:00
David Brownell
1e57376c1a ARM720: remove exports and forward decls
Unneeded exports cause confusion about the module interfaces.
Make all functions static.  Add a short header comment.

The forward decls are just code clutter; remove them, by moving
their references after definitions.  This is another file which
never needed even one internal forward declaration.

Remove unneeded indirection for the write_memory() method.  Make
a table static, remove a can't-happen case with nasty exit().

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 20:36:27 -08:00
David Brownell
dd96b2c28e FA526: remove exports and forward decls
Unneeded exports cause confusion about the module interfaces.
Make most functions static.

The forward decls are just code clutter; remove them, by moving
their references after definitions.  This is another file which
never needed even one internal forward declaration.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 20:36:18 -08:00
David Brownell
b52fa7492c ARM9TDMI: remove forward decls
The forward decls are just code clutter; remove them, by moving
their references after definitions.  This is another file which
never needed even one internal forward declaration.

Also shrink a few overly-long lines with function declarations
or definitions.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 20:36:09 -08:00
David Brownell
20ff0a9682 ARM966: remove exports and forward decls
Unneeded exports cause confusion about the module interfaces.
Make most functions static.

The forward decls are just code clutter; remove them, by moving
their references after definitions.  This is another file which
never needed even one internal forward declaration.

Also remove needless arm966e_init_target(), in favor of the
arm9tdmi routine to which it delegates its work.

This saved over 100 bytes of code on x86_32.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 20:35:53 -08:00
David Brownell
ed9ac9b6fe ARM926: more cleanup
An init_target() wrapper isn't needed, and target_create()
can shrink a bit.  Add a header comment and some doxygen.

Remove arm926ejs_catch_broken_irscan() which has been a NOP
for quite a few months now, and in any case duplicates logic
in the JTAG core to validate IR capture data.  But force the
capture mask to 0x0f, so those tests are most effective.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 20:35:47 -08:00
David Brownell
aab023570b ARM920: remove exports and forward decls
Unneeded exports cause confusion about the module interfaces.
Make most functions static.  Add a short header comment.

The forward decls are just code clutter; remove them, by moving
their references after definitions.  This is another file which
never needed even one internal forward declaration.

This saved almost 900 bytes of code on x86_32; it seems the
compiler can leverage its knowledge that these functions are
not called from the outside world...

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 20:35:37 -08:00
Zachary T Welch
36b4ac90e4 Improve str9xpec command argument parsing. 2009-11-05 18:19:19 -08:00
Zachary T Welch
fa9e5d1027 Improve str9x config command argument parsing. 2009-11-05 18:19:19 -08:00
Zachary T Welch
111b7a6a9d Improve str7x config command argument parsing. 2009-11-05 18:19:19 -08:00
Zachary T Welch
aa9351ba46 Improve stm32x.c command argument parsing. 2009-11-05 18:19:19 -08:00
Zachary T Welch
786106d725 Improve stellaris.c erase argument parsing. 2009-11-05 18:19:19 -08:00
Zachary T Welch
fc116380bf Improve pic32mx.c command argument parsing. 2009-11-05 18:19:18 -08:00
Zachary T Welch
ee4723c494 Improve mflash.c command argument parsing. 2009-11-05 18:19:18 -08:00
Zachary T Welch
c63671e4f7 Improve lpc3180_nand_controller.c parsing.
This fixes a memory leak in lpc3180_nand_device_command by
reordering the malloc to occur after all parsing has completed.
2009-11-05 18:19:18 -08:00
Zachary T Welch
7b2d8d93e6 Improve lpc2900.c command argument parsing. 2009-11-05 18:19:18 -08:00
Zachary T Welch
0004691e91 Improve lpc288x.c command argument parsing. 2009-11-05 18:19:18 -08:00
Zachary T Welch
7f6ad49d12 Improve lpc2000.c command argument parsing. 2009-11-05 18:19:18 -08:00
Zachary T Welch
680e22c4d7 Improve cfi.c command argument parsing. 2009-11-05 18:19:18 -08:00
Zachary T Welch
7b3d54a127 Improve avrf.c command argument parsing. 2009-11-05 18:19:18 -08:00
Zachary T Welch
266c423bbd Improve orion_nand.c command argument parsing. 2009-11-05 18:19:18 -08:00
Zachary T Welch
7b49739790 Improve davinci_nand.c command argument parsing. 2009-11-05 18:19:18 -08:00
Zachary T Welch
75b601b1f3 Improve at91sam7.c command argument parsing. 2009-11-05 18:19:13 -08:00
Zachary T Welch
5e0ee6ab08 Improve at91sam3.c command argument parsing. 2009-11-05 18:03:20 -08:00
Zachary T Welch
93ab9ce888 Improve nand.c command argument parsing. 2009-11-05 18:03:20 -08:00
Zachary T Welch
e9566a4a6a Improve flash.c command argument parsing. 2009-11-05 18:03:20 -08:00
Zachary T Welch
11e545f560 Add Flash/NAND bank command argument helpers.
This eliminates redundant code for parsing and retreiving the bank
specified from a script command argument.  This patch was written to
replace existing functionality; however, the parsing logic can be
updated later to allow flash commands to accept bank names as well as
their numbers.
2009-11-05 18:03:20 -08:00
Zachary T Welch
4189fdad28 Improve ETM tracemode update command. 2009-11-05 18:03:20 -08:00
Zachary T Welch
d660721ba8 Improve etm command argument parsing. 2009-11-05 18:03:20 -08:00
Zachary T Welch
04b8a2a6f3 Improve trace command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
a8886cdfee Improve arm_adi_v5 command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
9b3781e5a4 Improve cortex_m3 command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
af84cd33a2 Improve xscale command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
4d67b0974f Improve arm11 command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
b699aef4c0 Improve arm966e command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
f8f1ac8865 Improve arm926ejs command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
714d92a954 Improve arm920t command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
0442bda216 Improve arm720t command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
11a0afc932 Improve arm7_9_common command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
3541ed3aa3 Improve armv7m command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
3dd5c59d7d Improve armv7a command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
b62ee5a3c5 Improve armv4_5 command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
ab33bdd46c Improve xscale command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
6e542407e7 Improve pld command argument parsing. 2009-11-05 18:03:19 -08:00
Zachary T Welch
2b78a4e82b Update all server port command to use new helper. 2009-11-05 18:03:19 -08:00
Zachary T Welch
ae5732b9e4 Add server port command helper function. 2009-11-05 18:03:18 -08:00
Zachary T Welch
653ea7b25c Improve target.c command argument parsing.
Passes cmd_ctx into parse_load_image_command_args for reporting the
parsing errors therein.
2009-11-05 18:03:18 -08:00
Zachary T Welch
b7b561aae8 Improve jtag command argument parsing. 2009-11-05 18:03:18 -08:00
Zachary T Welch
f6f1dbfafd Improve debug_level command argument parsing. 2009-11-05 18:03:18 -08:00
Zachary T Welch
36a3646c22 Add macro for parsing numeric command arguments.
This helper eliminates significant amount of redundant code in command
handler functions throughout the system.  It wraps the lower-level
parse_* macros to implement a policy for reporting parse errors to the
active command context (cmd_ctx).  If errors do occur, this macro causes
the calling function to abort with the proper return code.
2009-11-05 17:27:25 -08:00
Zachary T Welch
68785af4da Add stringify macros in src/helper/types.h. 2009-11-05 17:20:18 -08:00
Øyvind Harboe
0f3117c19d arm920t: add mrcmcr interface fn's.
The arm920t has a concept of read modify write cycles
that may have to be represented in the mrcmcr interface
eventually.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 23:57:49 +01:00
Øyvind Harboe
dc98c64d71 arm11: check if target is halted before executing mrc/mcr commands.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 23:57:49 +01:00
Øyvind Harboe
051eaf7950 target: fix ordering of arguments to mcr and mrc commands
Now matches machine code syntax and old arm11 syntax.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 23:57:49 +01:00
Øyvind Harboe
4e3c2676f1 target: check args to mrc/mcr.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 23:57:49 +01:00
Øyvind Harboe
4441c1ffdc ARM11: added mrc/mcr support to arm11 code.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 23:57:49 +01:00
Øyvind Harboe
cca7cf1e74 TODO: Wrote up list of remaining tasks for target->type->mrc/mcr
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 23:56:37 +01:00
Øyvind Harboe
b64503e37f target: Only register mrc mcr commands when one of the targets support them.
This avoids polluting help for targets that can never support mrc/mcr

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 23:56:37 +01:00
Øyvind Harboe
1ebdc24494 cortex_a8: add mrc mcr interface.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 23:56:37 +01:00
David Brownell
afed39c0fe User's Guide: TAP setup tweakage
Highlight that the "-expected-id" probably comes from vendor
documentation, and that it *should* be used where possible.

Don't use ircapture/irmask in examples, to help discourage
use of those params when they're not required.  Explain a
bit better about why/when those params get used.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 11:31:32 -08:00
David Brownell
98788d7a75 watchpoint_add() cleanup
Fail watchpoint_add() if it's the same address but the
parameters are different ... don't just assume having
the same address means the same watchpoint!  (Note that
overlapping watchpoints aren't detected...)

Handle unrecognized return codes more sanely; don't exit()!
And describe command params right.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 01:47:44 -08:00
David Brownell
16b4b8cf54 Cortex-M3: expose most DWT registers
Expose most DWT registers via Tcl; there are a few more, but
those are mostly for profiling along with the ITM.  Having
this set available enables operations which aren't possible
with just the standard watchpoint operations.

The cycle counter may be interesting.  Turn it on after reset
by setting the LSB of the dwt_ctrl register, and it counts
CPU clocks.  You can program the comparator 0 watchpoint to
trigger on a given cycle count, rather than a data address.

Likewise, comparator 1 may be able to match data values given
address matches from one or two other comparators.  (Not all
hardware supports this capability though; try it.  That is
something the standard watchpoint methods should eventually
handle, for the single address case.)

Minor cleanup:  remove needless functional indirection for
exposing the v7m architctural registers.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 01:04:08 -08:00
David Brownell
8fb2baaa6b Cortex-M3: minor cleanup
There's no reason to read which interrupts are enabled from
the NVIC; that state isn't used.  Plus, it's highly dynamic
since firmware can change it at any time; remove the support
for those state records.

Remove duplicate definition of DWT_CTRL address; shrink a line.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 01:03:54 -08:00
David Brownell
7acb2607ff Cortex-M3: DWT cleanup/fixes
Fix the watchpoint error checks, and do them in add(), not later
in set() when it's mostly too late.  Support the full range of
watchpoint sizes (1 to 32K bytes each), and check alignments.

Minor cleanup of DWT access:  shrink lines, use "+" for address
calculations, comment a few issues.  Add debug message reporting
DWT capabilities, matching the message for FBP, and some minor
code and spec review comments.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 01:03:17 -08:00
David Brownell
ff50caa8fa ARMv7M: add docs, remove exports
Add Doxygen for the exported ARMv7-M interfaces.

Make the non-exported stuff static.  Remove functions and
data which are now observably unused.

Add comment about a small speedup that the run_algorithm()
logic could use.  Shrink a few too-long lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-05 01:02:52 -08:00
Øyvind Harboe
d269122f91 target: add target->type->has_mmu fn.
improve default target->read/write_phys_memory, produce
more sensible error messages if the mmu interface
functions have not been implemented yet vs. will
not be implemented(e.g. cortex m3).

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 09:53:31 +01:00
Øyvind Harboe
972924b2ad Make default implementation of mdw/mmw phys return error 'not implemented' 2009-11-05 09:26:08 +01:00
Øyvind Harboe
af66678c9a target: remove unused interface fn that clutters code
The quit entry point was not being invoked. Just a source
of confusion at this point. XScale ran 100x reset upon
quit, but that code made no sense, wasn't commented
and never invoke.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 09:07:56 +01:00
Øyvind Harboe
acff2521fb debug interface: get rid of unused pre_debug fn
Removing unused code makes it much less mysterius.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 09:05:10 +01:00
Øyvind Harboe
a5e396b964 warnings: remove
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-05 09:03:24 +01:00
David Brownell
2d9863e121 ft2232: cleanup
Previous patch somehow made GCC lose some of its cookies;
work around, zero-init that struct.

Clean up code from the previous patch.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-04 21:41:08 -08:00
Krzysztof Kajstura
2970696e89 JTAG: support KT-LINK adapter
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-04 21:20:44 -08:00
David Brownell
fd108f5737 PXA255: support Intel "Lubbock" platform
Config for Intel's "Lubbock" PXA255 development board.  Even more
so than the PXA255 itself, this is obsolete.  AFAIK this was the
first generally available development platform for PXA255.  Intel
stopped providing these after other devel boards became available.

One interesting thing about this board from the OpenOCD perspective
is probably its flash configuration.  Each bank is 32 bits wide,
built from two 16-bit StrataFlash chips wired in parallel.  This
doubles throughput ... it reads/writes 32 bits in the time a single
chip takes to write just 16 bits.

This conf mostly works, given XScale bugfixes, but has some issues
(notably: no access to the on-board SDRAM) flagged by FIXMEs.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-04 21:11:44 -08:00
David Brownell
067501b0c7 Version 0.4.0-dev
Add "-dev" tag.  Update minor version number.
Archive old NEWS file, start a new one.
2009-11-04 19:44:36 -08:00
David Brownell
1d5a3a6bcd Version 0.3.0
Remove -dev tag, remove -rc tag.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-04 19:39:59 -08:00
David Brownell
ecd9c0d8bf Release docs: fix notes
We currently do something unusual:  version codes in config.in get
updated after the release, which means that "git describe" won't
match up to development version labels.  Comment that trouble spot.

We can fix this by switching away from the major/minor/micro type
release numbering, as various other projects have done.  The major
numbers basically don't tend to change, and doing a good job with
micro versions is so annoying that they rarely change either.
2009-11-04 17:49:06 -08:00
David Brownell
6455ae4a59 Doc: fix broken link
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-04 17:12:53 -08:00
David Brownell
efa7f8b4bb NEWS: mention switch to git! 2009-11-04 17:03:20 -08:00
David Brownell
16f485aca2 Other files: stop referring to ChangeLog too
The ChangeLog idiom is redundant given any decent SCM.
Time to phase it out here.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-04 16:46:27 -08:00
David Brownell
0e37ea6499 NEWS refs repository history, not ChangeLog
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-04 15:54:33 -08:00
David Brownell
1c51f342d7 Tweak release docs
Contrast releases to git snapshot tarballs.  Mention that
releases have some quality-improvement focus, with special
non-"dev" version IDs.  Explain more about version IDs,
using "openocd -v" to see them, etc;

Make release milestone info be less specific about timing,
and presume we have both a merge window and an RC stage.

Rework the release process information to match reality a
bit more closely.  Reference the version.sh script (in one
place the wrong script was referenced).  Bugfix branches
get special treatment, while non-bugfix releases are more
or less what *defines* being the mainline branch.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-04 15:38:06 -08:00
David Brownell
333601da4b Release scripts: comments, run on Ubuntu
The "source" command isn't accepted by ASH; easy to fix.
Failures with "-e" are harder to fix.  Remove the "-e"
(for now) and force bash, for safety.

Un-obfuscate the release steps, by using names instead
of numbers.  Comment the version-number manipulation.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-04 15:20:18 -08:00
Øyvind Harboe
b8e7408b92 configure: fix build problems with eCos
Various include files require some other include files
to be included first. Copied solution from net/if.h.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-04 19:27:53 +01:00
Øyvind Harboe
099e5b6920 docs: add reference to git bisect docs on BUGS page
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-04 19:25:20 +01:00
Øyvind Harboe
1b60ce8d5b target: 20 second timeout/megabyte for CRC check
There was a fixed 20 second timeout which is too little
for large, slow timeout checks.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-03 15:38:09 +01:00
Øyvind Harboe
f37c9b8d15 arm920t: memory writes were broken when MMU was disabled
To support breakpoints, flush data cache line and invalidate
instruction cache when 4 and 2 byte words are written.

The previous code was trying to write directly to the physical
memory, which was buggy and had a number of other situations
that were not handled.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-03 12:28:00 +01:00
Øyvind Harboe
b5ce7fe812 target: require working area for physical/virtual addresses to be specified
Fixed bug: if virtual address for working memory was not specified
and MMU was enabled, then address 0 would be used.

Require working address to be specified for both MMU enabled
and disabled case.

For some completely inexplicable reason this fixes the regression
in svn 2646 for flash write in arm926ejs target. The logs showed
that MMU was disabled in the case below:

https://lists.berlios.de/pipermail/openocd-development/2009-November/011882.html

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
2009-11-03 11:56:05 +01:00
Dimitar Dimitrov
e901cee72f FT2232: increase read retry counts
This change is necessary to debug AT91SAM9260 on my PC with a
FT2232H dongle.

Signed-off-by: Dimitar Dimitrov <dinuxbg@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-01 19:56:51 -08:00
David Brownell
72210fe3a3 User's Guide: more init info, autoprobing, etc
Mention the autoprobing as a tool that may be useful when
figuring out how to set up; and add a section showing how
to use that mechanism (with an example).

Strengthen the differences between config and run stage
descriptions; add a section for the latter.

Mention Dragonite.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-01 17:54:47 -08:00
David Brownell
13e264426c doxygen: avoid most internals
For some reason, all the interals are documented by default.
This is wrong for two basic reasons:

 - We need to focus on public interfaces, since those are
   the architectural interfaces and relationships.

 - Since virtually nothing has doxygen support yet, this
   maximizes the noise, and minimizes the usefulness of
   doxygen output.

So don't expose so much by default.
2009-11-01 17:34:52 -08:00
Freddie Chopin
2120231afd remove "-ircapture 0x1 -irmask 0x1" from stm32.cfg
Gets rid of the runtime warning "stm32.bs: nonstandard IR mask"

[dbrownell@users.sourceforge.net: line lengths, note issue, section ref]

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-11-01 07:02:23 -08:00
David Brownell
c352c96f74 arm9tdmi: more correct fix for vector_catch
Just use the array of names we're given, ignoring indices.
The "reserved means don't use" patch missed that change.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-10-31 18:03:54 -07:00
Freddie Chopin
0da0bfd40a target.cfg: use $_TARGETNAME for flash
This gets rid of runtime warnings from the use of numbers.
STM32 and LPC2103 were tested.  Other LPC updates are the
same, and so are safe.  The CFI updates match other tested
changes now in the tree.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-10-31 11:13:10 -07:00
David Brownell
8152106419 NEWS: more info
There were a few more changes worth mentioning, including support
for more JTAG adapters, boundary scan improvements, another NAND
driver, and the Win64 stuff.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-10-30 20:21:31 -07:00
David Brownell
54c3cab266 ARM926: fix arm926ejs_mmu() reading from bad pointer
I'm suspecting this code can never have worked, since the
original commit (svn #335) in early 2008.

Fix is just copy/paste from another (working) function.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-10-30 17:29:38 -07:00
Spencer Oliver
e8a5092f1e bin2char: for win32 set stdin/stdout to binary mode
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
2009-10-30 11:59:57 +00:00
Michael Roth
a53c72cdab SVF: fix checking bit pattern against length
The code works like follow (N = bit_len):

	N	-1	%4	2<<	-1	~ (binary)
	--------------------------------------------------
	1	0	0	2	1	1111 1110
	2	1	1	4	3	1111 1100
	3	2	2	8	7	1111 1000
	4	3	3	16	15	1111 0000
	5	4	0	2	1	1111 1110
	6	5	1	4	3	1111 1100
	7	6	2	8	7	1111 1000
	8	7	3	16	15	1111 0000
	...	...	...	...	...	...

Addresses a bug reported by FangfangLi <ffli@syntest.com.cn>.

[dbrownell@users.sourceforge.net: fix spelling bug too]

Signed-off-by: Michael Roth <mroth@nessie.de>
Cc: FangfangLi <ffli@syntest.com.cn>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-10-29 15:39:03 -07:00
Dimitar Dimitrov
517049dca5 Olimex FT2232H JTAG adapters
Add interface configs for two new high speed JTAG
adapters from Olimex.  They need some other speed
related tweaks to work well at high speed.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-10-29 15:39:03 -07:00
David Brownell
0c4d5b8b1f XSVF: bugfix handling state paths
Implement XSVF support for detailed state path transitions,
by collecting sequences of XSTATE transitions into paths
and then calling pathmove().

It seems that the Xilinx tools want to force state-by-state
transitions instead of relying on the standardized SVF paths.
Like maybe there are XSVF tools not implementing SVF paths,
which are all that we support using svf_statemove().

So from IRPAUSE, instead of just issuing "XSTATE DRPAUSE"
they will issue XSTATES for each intermediate state: first
IREXIT2, then IRUPDATE, DRSELECT, DRCAPTURE, DREXIT1, and
finally DRPAUSE.  This works now.

Handling of paths that go *through* reset is a trifle dodgey,
but it should be safe.

Tested-by: Wookey <wookey@wookware.org>

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
2009-10-29 12:42:41 -07:00
Zachary T Welch
b628207ea6 Bump rc version and add -dev tag.
Bump rc package version number: 0.3.0-rc0 -> 0.3.0-rc1
Add '-dev' version tag: 0.3.0-rc1 -> 0.3.0-rc1-dev
2009-10-28 21:23:17 -07:00
456 changed files with 42424 additions and 26056 deletions

12
.gitignore vendored
View File

@@ -4,14 +4,20 @@
.libs
.deps
*.o
*.o.??????
*.a
*.lo
*.la
*.in
# generated source files
src/jtag/minidriver_imp.h
src/jtag/jtag_minidriver.h
# editor files
*.swp
src/startup.tcl
startup_tcl.c
xscale_debug.h
@@ -60,6 +66,10 @@ stamp-vti
INSTALL
NOTES
# coexist with quilt
patches
# Eclipse stuff
.project
.cproject
.settings

17
BUGS
View File

@@ -1,4 +1,4 @@
// This file is part of the Doyxgen Developer Manual
// This file is part of the Doxygen Developer Manual
/** @page bugs Bug Reporting
Please report bugs by subscribing to the OpenOCD mailing list and
@@ -6,6 +6,12 @@ posting a message with your report:
openocd-development@lists.berlios.de
Also, please check the Trac bug database to see if a ticket for
the bug has already been opened. You might be asked to open
such a ticket, or to update an existing ticket with more data.
https://sourceforge.net/apps/trac/openocd/
To minimize work for OpenOCD developers, you should try to include
all of the information listed below. If you feel that some of the
items below are unnecessary for a clear bug report, you may leave
@@ -22,11 +28,12 @@ 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.
You can use "git bisect" to expedite this binary search.
You can use "git bisect" to expedite this binary search:
http://www.kernel.org/pub/software/scm/git/docs/git-bisect.html
If possible, please develop and attach a patch that helps to expose or
solve the reported problem. See the PATCHES file for more information
for that process.
solve the reported problem. See the PATCHES.txt file for information
about that process.
Attach all files directly to your posting. The mailing list knows to
transform attachments to links, but attachments must be less than 300KB
@@ -35,7 +42,7 @@ in total.
@section bugscrashdump Obtaining Crash Backtraces
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.
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

View File

@@ -1 +1 @@
Retired in favour of SVN log.
Retired in favor of git log.

View File

@@ -38,7 +38,7 @@ PROJECT_NUMBER =
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY =
OUTPUT_DIRECTORY = doxygen
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@@ -307,13 +307,13 @@ EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
EXTRACT_STATIC = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_CLASSES = NO
# This flag is only useful for Objective-C code. When set to YES local
# methods, which are defined in the implementation section but not in
@@ -384,7 +384,7 @@ HIDE_SCOPE_NAMES = NO
# will put a list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
SHOW_INCLUDE_FILES = NO
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
@@ -403,7 +403,7 @@ SORT_MEMBER_DOCS = YES
# by member name. If set to NO (the default) the members will appear in
# declaration order.
SORT_BRIEF_DOCS = NO
SORT_BRIEF_DOCS = YES
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
# hierarchy of group names into alphabetical order. If set to NO (the default)
@@ -567,9 +567,9 @@ WARN_LOGFILE =
INPUT = @srcdir@/doc/manual \
@srcdir@/TODO \
@srcdir@/BUGS \
@srcdir@/PATCHES \
@srcdir@/PATCHES.txt \
@srcdir@/src \
@srcdir@/config.h
@builddir@/config.h
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -692,13 +692,13 @@ SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = YES
INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = NO
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES
# then for each documented function all documented
@@ -764,13 +764,13 @@ IGNORE_PREFIX =
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
GENERATE_HTML = @doxygen_as_html@
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = doxygen
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
@@ -981,7 +981,7 @@ FORMULA_FONTSIZE = 10
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
GENERATE_LATEX = @doxygen_as_pdf@
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
@@ -992,7 +992,7 @@ LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked. If left blank `latex' will be used as the default command name.
LATEX_CMD_NAME = latex
LATEX_CMD_NAME = pdflatex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
# generate index for LaTeX. If left blank `makeindex' will be used as the
@@ -1004,7 +1004,7 @@ MAKEINDEX_CMD_NAME = makeindex
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
COMPACT_LATEX = YES
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, a4wide, letter, legal and
@@ -1029,20 +1029,20 @@ LATEX_HEADER =
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
PDF_HYPERLINKS = YES
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
USE_PDFLATEX = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
LATEX_BATCHMODE = YES
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
# include the index chapters (such as File Index, Compound Index, etc.)

View File

@@ -25,12 +25,27 @@ Doxyfile: $(srcdir)/Doxyfile.in
@( \
echo "### @@@ -= DO NOT EDIT THIS FILE =- @@@ ###" && \
echo "### @@@ Make changes to Doxyfile.in @@@ ###" && \
sed -e 's,@srcdir\@,$(srcdir),' $< \
sed -e 's,@srcdir\@,$(srcdir),' \
-e 's,@builddir\@,$(builddir),' \
-e 's,@doxygen_as_html\@,$(doxygen_as_html),' \
-e 's,@doxygen_as_pdf\@,$(doxygen_as_pdf),' $< \
) > $@
THE_MANUAL = doxygen/latex/refman.pdf
doxygen::
$(MAKE) Doxyfile
doxygen Doxyfile 2>&1 | perl $(srcdir)/tools/logger.pl > doxygen.log
@if [ -f doxygen/latex/refman.tex ]; then \
echo "Creating $(THE_MANUAL)..."; \
$(MAKE) $(THE_MANUAL); \
else \
echo "Skipping Doxygen PDF..."; \
fi
$(THE_MANUAL): %.pdf: %.tex
-cd $$(dirname $*) && pdflatex $$(basename $*)
-cd $$(dirname $*) && pdflatex $$(basename $*)
TCL_PATH = tcl
# command to find paths of script files, relative to TCL_PATH

122
NEWS
View File

@@ -1,58 +1,98 @@
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.
This file includes highlights of the changes made in the
OpenOCD 0.4.0 source archive release. See the repository
history for details about what changed, including bugfixes
and other issues not mentioned here.
JTAG Layer:
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
Support KT-Link JTAG adapter.
Support USB-JTAG, Altera USB-Blaster and compatibles.
Boundary Scan:
Target Layer:
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
General
- Removed commands which have been obsolete for at least
a year (from both documentation and, sometimes, code).
- new "reset-assert" event, for systems without SRST
ARM
- supports "reset-assert" event (except on Cortex-M3)
- renamed "armv4_5" command prefix as "arm"
- recognize TrustZone "Secure Monitor" mode
- "arm regs" command output changed
- register names use "sp" not "r13"
- add top-level "mcr" and "mrc" commands, replacing
various core-specific operations
- basic semihosting support (ARM7/ARM9 only, for now)
ARM11
- Should act much more like other ARM cores:
* Preliminary ETM and ETB hookup
* accelerated "flash erase_check"
* accelerated GDB memory checksum
* support "arm regs" command
* can access all core modes and registers
* watchpoint support
- Shares some core debug code with Cortex-A8
Cortex-A8
- Should act much more like other ARM cores:
* support "arm regs" command
* can access all core modes and registers
* watchpoint support
- Shares some core debug code with ARM11
Cortex-M3
- Exposed DWT registers like cycle counter
- vector_catch settings not clobbered by resets
- no longer interferes with firmware's fault handling
ETM, ETB
- "trigger_percent" command moved ETM --> ETB
- "etm trigger_debug" command added
MIPS
- use fastdata writes
Freescale DSP563xx cores (partial support)
Flash Layer:
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
'flash bank' and 'nand device' take <bank_name> as first argument.
With this, flash/NAND commands allow referencing banks by name:
- <bank_name>: reference the bank with its defined name
- <driver_name>[.N]: reference the driver's Nth bank
New 'nand verify' command to check bank against an image file.
The "flash erase_address" command now rejects partial sectors;
previously it would silently erase extra data. If you
want to erase the rest of the first and/or last sectors
instead of failing, you must pass an explicit "pad" flag.
New at91sam9 NAND controller driver.
New s3c64xx NAND controller driver.
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
ARM9
- ETM and ETB hookup for iMX2* targets
Add $HOME/.openocd to the search path.
Handle Rev C of LM3S811 eval boards.
- use "luminary-lm3s811.cfg" for older boards
- use "luminary.cfg" for RevC and newer
Core Jim/TCL Scripting:
New 'usage' command to provide terse command help.
Improved command 'help' command output (sorted and indented).
Improved command handling:
- Most boolean settings now accept any of the following:
on/off, enable/disable, true/false, yes/no, 1/0
- More error checking and reporting.
Documentation:
Capture more debugging and setup advice
Notes on target source code changes that may help debugging
New built-in command development documentation and primer.
Build and Release:
Use --enable-doxygen-pdf to build PDF developer documentation.
Consider upgrading to libftdi 0.17 if you use that library; it
includes bugfixes which improve FT2232H support.
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>).
see the git repository history. With gitweb, you can browse that
in various levels of detail.
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
the BUGS and PATCHES files in the source archive).
the BUGS and PATCHES.txt files in the source archive).

View File

@@ -9,7 +9,7 @@ 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
@@ -20,7 +20,7 @@ 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:
- 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.

82
NEWS-0.3.0 Normal file
View File

@@ -0,0 +1,82 @@
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:
FT2232H (high speed USB) support doesn't need separate configuration
New FT2232H JTAG adapters: Amontec, Olimex, Signalyzer
New reset_config options for SRST gating the JTAG clock (or not)
TAP declaration no longer requires ircapture and mask attributes
Scan chain setup should be more robust, with better diagnostics
New TAP events:
"post-reset" for TAP-invariant setup code (TAPs not usable yet)
"setup" for use once TAPs are addressable (e.g. with ICEpick)
Overridable Tcl "init_reset" and "jtag_init" procedures
Simple "autoprobe" mechanism to help simplify server setup
Boundary Scan:
SVF bugfixes ... parsing fixes, better STATE switch conformance
XSVF bugfixes ... be more correct, handle Xilinx tool output
Target Layer:
Warn on use of obsolete numeric target IDs
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
you may need to explicitly "reset" after connect-to-Beagle
New commands for use with XScale processors: "xscale vector_table"
ARM
bugfixes to single-stepping Thumb code
ETM: unavailable registers are not listed
ETB, ETM: report actual hardware status
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 ..."
GDB support
gdb_attach command is gone
Flash Layer:
The lpc2000 driver handles the new NXP LPC1700 (Cortex-M3) chips
New drivers:
lpc2900, for NXP LPC2900 chips (ARM968 based)
mx3_nand, for imx31
New "last" flag for NOR "flash erase_sector" and "flash protect"
The "nand erase N" command now erases all of bank N
Speed up davinci_nand by about 3x
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:
Capture more debugging and setup advice
Notes on target source code changes that may help debugging
Build and Release:
Repository moved from SVN at Berlios to GIT at SourceForge
Clean builds on (32-bit) Cygwin
Clean builds on 64-bit MinGW
For more details about what has changed since the last release,
see the git repository history. With gitweb, you can browse that
in various levels of detail.
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
the BUGS and PATCHES files in the source archive).

20
NEWTAPS
View File

@@ -30,7 +30,7 @@ Version Number Changes:
not a big deal. Please do report this information. We'd like to
know about it.
For example
For example
Error: ERROR: Tap: s3c4510.cpu - Expected id: 0x3f0f0f0f, Got: 0x1f0f0f0f
Error: ERROR: expected: mfg: 0x787, part: 0xf0f0, ver: 0x3
@@ -39,7 +39,7 @@ Error: ERROR: got: mfg: 0x787, part: 0xf0f0, ver: 0x1
========================================
Updating the Tap ID number your self
Why do this? You just want the warning to go away. And don't want
to update your version/instance of OpenOCD.
@@ -79,11 +79,11 @@ Examples:
0x3f0f0f0f - is a newer ARM7TDMI
0x3ba00477 - is an ARM cortex M3
Some chips have multiple JTAG taps - be sure to list
Some chips have multiple JTAG taps - be sure to list
each one individually - ORDER is important!
========================================
B) The maker of the part
B) The maker of the part
Examples:
Xilinx, Atmel, ST Micro Systems, Freescale
@@ -94,7 +94,7 @@ C) The family of parts it belongs to
Examples:
"NXP LPC Series"
"Atmel SAM7 Series"
========================================
D) The actual part number on the package
@@ -121,7 +121,7 @@ For example: A consumer GPS unit or a cellphone
ie: Olimex, LogicPD, Freescale(eval board)
========================================
(G) Identifying information on the board.
Not good: "iar red ST eval board"
@@ -135,3 +135,11 @@ For example: A consumer GPS unit or a cellphone
ie: An FPGA or CPLD ...
========================================
(I) What target config files need updating?
In fact it's best if you submit a patch with those
updates. Most of the other information listed here
is just to help create a good patch.
========================================

View File

@@ -1,4 +1,4 @@
// This file is part of the Doyxgen Developer Manual
// This file is part of the Doxygen Developer Manual
/** @page patchguide Patch Guidelines
Please mail patches to: @par
@@ -32,7 +32,7 @@ in response to feedback.
Add yourself to the GPL copyright for non-trivial changes.
To create a patch from the command line:
@code
@code
git diff >mypatch.txt
@endcode

11
README
View File

@@ -64,8 +64,8 @@ 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
On Linux, you may have permissions problems to address. The best way
to do this is to use the contrib/openocd.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.
@@ -258,6 +258,9 @@ options may be available there:
--enable-httpd Enable builtin httpd server - useful for standalone
OpenOCD implementations
--disable-doxygen-html Disable building Doxygen manual as HTML.
--enable-doxygen-pdf Enable building Doxygen manual as PDF.
Miscellaneous Configure Options
-------------------------------
@@ -335,7 +338,7 @@ all operating systems used with OpenOCD. You may, however, build such
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
TAR.GZ file. You must unpack them ``some where'' convenient. As of this
writing FTDICHIP does not supply means to install these files "in an
appropriate place."
@@ -401,7 +404,7 @@ 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:
the repository or to download arbitrary snapshots using HTTP:
http://openocd.git.sourceforge.net/git/gitweb.cgi?p=openocd/openocd
http://repo.or.cz/w/openocd.git

View File

@@ -27,8 +27,8 @@ based JTAG debuggers.
http://sourceforge.net/projects/libusb-win32/
You need to download the libusb-win32-device-bin-0.1.12.2.tar.gz
package. Extract this file into a temp directory.
You need to download the libusb-win32-device-bin-0.1.12.2.tar.gz
package. Extract this file into a temp directory.
Copy the file libusb-win32-device-bin-0.1.12.2\include\usb.h
to your MinGW include directory.
@@ -59,10 +59,10 @@ released source tarball or the git tree.
If you are using the git tree, the following are the instructions from
README.mingw. You will need to have the cmake utility installed.
- Edit Toolchain-mingw32.cmake to point to the correct MinGW
- Edit Toolchain-mingw32.cmake to point to the correct MinGW
installation.
- Create a build directory like "mkdir build-win32", e.g in ../libftdi/
- cd into that directory and run
- cd into that directory and run
"cmake -DCMAKE_TOOLCHAIN_FILE=../Toolchain-mingw32.cmake .."
- Copy src/ftdi.h to your MinGW include directory.
- Copy build-win32/src/*.a to your MinGW lib directory.

78
TODO
View File

@@ -1,4 +1,4 @@
// This file is part of the Doyxgen Developer Manual
// This file is part of the Doxygen Developer Manual
/** @page tasks Pending and Open Tasks
This page lists pending and open tasks being considered or worked upon
@@ -27,8 +27,8 @@ This section provides possible things to improve with OpenOCD's TCL support.
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.
- Isolate all TCL command support:
- Pure C CLI implementations using --disable-builtin-tcl.
- Allow developers to build new dongles using OpenOCD's JTAG core.
- At first, provide only low-level JTAG support; target layer and
above rely heavily on scripting event mechanisms.
@@ -46,7 +46,7 @@ This section list issues that need to be resolved in 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
- Encapsulate cmd_queue_cur_state and related varaible handling.
- Encapsulate cmd_queue_cur_state and related variable 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
@@ -85,7 +85,7 @@ There are some known bugs to fix in JTAG adapter drivers:
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
The following tasks have been suggested for improving OpenOCD's JTAG
interface support:
- rework USB communication to be more robust. Two possible options are:
@@ -112,7 +112,7 @@ TCP/IP packets handled by the server.
@section thelistswd Serial Wire Debug
- implement Serial Wire Debug interface
- implement Serial Wire Debug interface
@section thelistbs Boundary Scan Support
@@ -142,6 +142,14 @@ Once the above are completed:
https://lists.berlios.de/pipermail/openocd-development/2009-May/006590.html
- regression: "reset halt" between 729(works) and 788(fails): @par
https://lists.berlios.de/pipermail/openocd-development/2009-July/009206.html
- registers
- add flush-value operation, call them all on resume/reset
- mcr/mrc target->type support
- missing from ARM920t, ARM966e, XScale.
It's possible that the current syntax is unable to support read-modify-write
operations(see arm966e).
- mcr/mrc - retire cp15 commands when there the mrc/mrc commands have been
tested from: arm926ejs, arm720t, cortex_a8
- ARM7/9:
- clean up "arm9tdmi vector_catch". Available for some arm7 cores? @par
https://lists.berlios.de/pipermail/openocd-development/2009-October/011488.html
@@ -157,18 +165,25 @@ https://lists.berlios.de/pipermail/openocd-development/2009-October/011506.html
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:
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.
- Thumb2 single stepping: ARM1156T2 needs simulator support
- Cortex A8 support (ML)
- add target implementation (ML)
- Cortex M3 support
- when stepping, only write dirtied registers (be faster)
- when connecting to halted core, fetch registers (startup is quirky)
- 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
- ETM
- don't show FIFOFULL registers if they're not supported
- use comparators to get more breakpoints and watchpoints
- add "etm drivers" command
- trace driver init() via examine() paths only, not setup()/reset
- 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)
@@ -192,8 +207,8 @@ https://lists.berlios.de/pipermail/openocd-development/2009-October/011506.html
@section thelistsvf SVF/XSVF
- develop SVF unit tests
- develop XSVF unit tests
- develop SVF unit tests
- develop XSVF unit tests
@section thelistflash Flash Support
@@ -204,6 +219,16 @@ https://lists.berlios.de/pipermail/openocd-development/2009-October/011506.html
- ocl
- str9xpec
- Don't expect writing all-ones to be a safe way to write without
changing bit values. Minimally it loses on flash modules with
internal ECC, where it may change the ECC.
- NOR flash_write_unlock() does that between sectors
- there may be other cases too
- Make sure all commands accept either a bank name or a bank number,
and be sure both identifiers show up in "flash banks" and "nand list".
Right now the user-friendly names are pretty much hidden...
@subsection thelistflashcfi CFI
- finish implementing bus width/chip width handling (suggested by NC)
@@ -285,11 +310,11 @@ These ideas were first introduced here: @par
- automatically detect the features that are available, unless
options were specifically provided to configure
- provide a report of the drivers that will be build at the end of
running configure, so the users can verify which driverswill be
running configure, so the users can verify which drivers will be
built during 'make' (and their options) .
- eliminate sources of confusion in @c bootstrap script:
-# Make @c bootstrap call 'configure --enable-maintainer-mode \<opts\>'?
-# Add @c buildstrap script to assist with boostrap and configure steps.
-# Add @c buildstrap script to assist with bootstrap and configure steps.
- automatically build tool-chains required for cross-compiling
- produce mingw32, arm-elf, others using in-tree scripts
- build all required target code from sources
@@ -300,13 +325,30 @@ These ideas were first introduced here: @par
The following architectural tasks need to be accomplished and should be
fairly easy to complete:
- use dynamic allocations for working memory. Scan & fix code
for excessive stack allocations. take linux/scripts/checkstack.pl and
see what the worst offenders are. Dynamic stack allocations are found
at the bottom of the list below. Example, on amd64:
$ objdump -d | checkstack.pl | head -10
0x004311e3 image_open [openocd]: 13464
0x00431301 image_open [openocd]: 13464
0x004237a4 target_array2mem [openocd]: 4376
0x0042382b target_array2mem [openocd]: 4376
0x00423e74 target_mem2array [openocd]: 4360
0x00423ef9 target_mem2array [openocd]: 4360
0x00404aed handle_svf_command [openocd]: 2248
0x00404b7e handle_svf_command [openocd]: 2248
0x00413581 handle_flash_fill_command [openocd]: 2200
0x004135fa handle_flash_fill_command [openocd]: 2200
- clean-up code to match style guides
- factor code to eliminate duplicated functionality
- rewrite code that uses casts to access 16-bit and larger types
from unaligned memory addresses
- libopenocd support: @par
https://lists.berlios.de/pipermail/openocd-development/2009-May/006405.html
- review and clean up interface/target/flash APIs
- review and clean up interface/target/flash APIs
The following strategic tasks will require ambition, knowledge, and time
to complete:
@@ -324,9 +366,11 @@ to complete:
- Develop milestone and release guidelines, processes, and scripts.
- Develop "style" guidelines (and scripts) for maintainers:
- reviewing patches
- committing to Subversion
- Review The Guide for OpenOCD Users for documentation errors or omissions
- Update The Manual for OpenOCD Developerrs:
- committing to git
- Review Users' Guide for documentation errors or omissions
- "capture" and "ocd_find" commands
- "ocd_" prefix on various stuff
- Update Developer's Manual (doxygen output)
- Add documentation describing the architecture of each module
- Provide more Technical Primers to bootstrap contributor knowledge

View File

@@ -1,6 +1,9 @@
#!/bin/sh -e
# Run the autotools bootstrap sequence to create the configure script
# Stop execution as soon as we have an unknown command
set -e
if libtoolize --version >/dev/null 2>&1; then
libtoolize="libtoolize"
elif glibtoolize --version >/dev/null 2>&1; then

View File

@@ -1,5 +1,5 @@
AC_PREREQ(2.60)
AC_INIT([openocd], [0.3.0-rc0],
AC_INIT([openocd], [0.4.0],
[OpenOCD Mailing List <openocd-development@lists.berlios.de>])
AC_CONFIG_SRCDIR([src/openocd.c])
@@ -8,8 +8,8 @@ AM_MAINTAINER_MODE
AM_CONFIG_HEADER(config.h)
AH_BOTTOM([
#include "system.h"
#include "replacements.h"
#include <helper/system.h>
#include <helper/replacements.h>
])
AC_LANG_C
@@ -35,27 +35,78 @@ AC_TYPE_LONG_LONG_INT
AC_SEARCH_LIBS([ioperm], [ioperm])
AC_SEARCH_LIBS([dlopen], [dl])
AC_CHECK_HEADERS(arpa/inet.h)
AC_CHECK_HEADERS(sys/socket.h)
AC_CHECK_HEADERS(arpa/inet.h, [], [], [dnl
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])
AC_CHECK_HEADERS(elf.h)
AC_CHECK_HEADERS(dirent.h)
AC_CHECK_HEADERS(fcntl.h)
AC_CHECK_HEADERS(ifaddrs.h)
AC_CHECK_HEADERS(ifaddrs.h, [], [], [dnl
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])
AC_CHECK_HEADERS(malloc.h)
AC_CHECK_HEADERS(netdb.h)
AC_CHECK_HEADERS(netinet/in.h)
AC_CHECK_HEADERS(netinet/tcp.h)
AC_CHECK_HEADERS([netinet/in.h], [], [], [dnl
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])
AC_CHECK_HEADERS(netinet/tcp.h, [], [], [dnl
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])
AC_CHECK_HEADERS(pthread.h)
AC_CHECK_HEADERS(strings.h)
AC_CHECK_HEADERS(sys/ioctl.h)
AC_CHECK_HEADERS(sys/param.h)
AC_CHECK_HEADERS(sys/poll.h)
AC_CHECK_HEADERS(sys/select.h)
AC_CHECK_HEADERS(sys/socket.h)
AC_CHECK_HEADERS(sys/stat.h)
AC_CHECK_HEADERS(sys/time.h)
AC_CHECK_HEADERS(sys/types.h)
AC_CHECK_HEADERS(unistd.h)
AC_CHECK_HEADERS([net/if.h], [], [], [dnl
#include <stdio.h>
#ifdef STDC_HEADERS
@@ -226,6 +277,24 @@ AC_ARG_WITH(ftd2xx-lib,
with_ftd2xx_lib=static
])
AC_ARG_ENABLE(doxygen-html,
AS_HELP_STRING([--disable-doxygen-html],
[Disable building Doxygen manual as HTML.]),
[doxygen_as_html=$enableval], [doxygen_as_html=yes])
AC_SUBST(doxygen_as_html)
AC_MSG_CHECKING([whether to build Doxygen as HTML])
AC_MSG_RESULT($doxygen_as_html)
AC_ARG_ENABLE(doxygen-pdf,
AS_HELP_STRING([--enable-doxygen-pdf],
[Enable building Doxygen manual as PDF.]),
[doxygen_as_pdf=$enableval], [doxygen_as_pdf=no])
AC_SUBST(doxygen_as_pdf)
AC_MSG_CHECKING([whether to build Doxygen as PDF])
AC_MSG_RESULT($doxygen_as_pdf)
AC_ARG_ENABLE(gccwarnings,
AS_HELP_STRING([--disable-gccwarnings], [Disable compiler warnings]),
[gcc_warnings=$enableval], [gcc_warnings=yes])
@@ -323,6 +392,14 @@ 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]),
[build_ft2232_ftd2xx=$enableval], [build_ft2232_ftd2xx=no])
AC_ARG_ENABLE(usb_blaster_libftdi,
AS_HELP_STRING([--enable-usb_blaster_libftdi], [Enable building support for the Altera USB-Blaster using the libftdi driver, opensource alternate of FTD2XX]),
[build_usb_blaster_libftdi=$enableval], [build_usb_blaster_libftdi=no])
AC_ARG_ENABLE(usb_blaster_ftd2xx,
AS_HELP_STRING([--enable-usb_blaster_ftd2xx], [Enable building support for the Altera USB-Blaster using the FTD2XX driver from ftdichip.com]),
[build_usb_blaster_ftd2xx=$enableval], [build_usb_blaster_ftd2xx=no])
AC_ARG_ENABLE(amtjtagaccel,
AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]),
[build_amtjtagaccel=$enableval], [build_amtjtagaccel=no])
@@ -482,7 +559,7 @@ case $host in
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.])
@@ -545,18 +622,6 @@ else
AC_DEFINE(BUILD_ZY1000, 0, [0 if you don't want ZY1000.])
fi
if test $build_ioutil = yes; then
AC_DEFINE(BUILD_IOUTIL, 1, [1 if you want ioutils.])
else
AC_DEFINE(BUILD_IOUTIL, 0, [0 if you don't want ioutils.])
fi
if test $build_httpd = yes; then
AC_DEFINE(BUILD_HTTPD, 1, [1 if you want httpd.])
else
AC_DEFINE(BUILD_HTTPD, 0, [0 if you don't want httpd.])
fi
if test $build_at91rm9200 = yes; then
build_bitbang=yes
AC_DEFINE(BUILD_AT91RM9200, 1, [1 if you want at91rm9200.])
@@ -594,6 +659,20 @@ else
AC_DEFINE(BUILD_FT2232_FTD2XX, 0, [0 if you don't want ftd2xx ft2232.])
fi
if test $build_usb_blaster_libftdi = yes; then
build_bitbang=yes
AC_DEFINE(BUILD_USB_BLASTER_LIBFTDI, 1, [1 if you want libftdi usb_blaster.])
else
AC_DEFINE(BUILD_USB_BLASTER_LIBFTDI, 0, [0 if you don't want libftdi usb_blaster.])
fi
if test $build_usb_blaster_ftd2xx = yes; then
build_bitbang=yes
AC_DEFINE(BUILD_USB_BLASTER_FTD2XX, 1, [1 if you want ftd2xx usb_blaster.])
else
AC_DEFINE(BUILD_USB_BLASTER_FTD2XX, 0, [0 if you don't want ftd2xx usb_blaster.])
fi
if test $build_amtjtagaccel = yes; then
AC_DEFINE(BUILD_AMTJTAGACCEL, 1, [1 if you want the Amontec JTAG-Accelerator driver.])
else
@@ -670,7 +749,7 @@ then
AC_MSG_ERROR([The option: with_ftd2xx_linux_tardir is for LINUX only.])
fi
if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes ; then
if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then
AC_MSG_CHECKING([for ftd2xx.lib exists (win32)])
# if we are given a zipdir...
@@ -685,12 +764,12 @@ if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes ; then
# And calculate the LDFLAGS for the machine
case "$host_cpu" in
i?86|x86_*)
i?86|x86_32)
LDFLAGS="$LDFLAGS -L$with_ftd2xx_win32_zipdir/i386"
LIBS="$LIBS -lftd2xx"
f=$with_ftd2xx_win32_zipdir/i386/ftd2xx.lib
;;
amd64)
amd64|x86_64)
LDFLAGS="$LDFLAGS -L$with_ftd2xx_win32_zipdir/amd64"
LIBS="$LIBS -lftd2xx"
f=$with_ftd2xx_win32_zipdir/amd64/ftd2xx.lib
@@ -922,11 +1001,13 @@ enum ftdi_chip_type x = TYPE_2232H;
fi
# check for usb.h when a driver will require it
build_usb=no
if test $build_jlink = yes -o $build_vsllink = yes -o $build_usbprog = yes -o \
$build_rlink = yes -o $build_armjtagew = yes
then
AC_CHECK_HEADERS([usb.h],[],
[AC_MSG_ERROR([usb.h is required to build some OpenOCD driver(s)])])
build_usb=yes
fi
AM_CONDITIONAL(RELEASE, test $build_release = yes)
@@ -942,6 +1023,8 @@ AM_CONDITIONAL(AT91RM9200, test $build_at91rm9200 = yes)
AM_CONDITIONAL(BITBANG, test $build_bitbang = yes)
AM_CONDITIONAL(FT2232_LIBFTDI, test $build_ft2232_libftdi = yes)
AM_CONDITIONAL(FT2232_DRIVER, test $build_ft2232_ftd2xx = yes -o $build_ft2232_libftdi = yes)
AM_CONDITIONAL(USB_BLASTER_LIBFTDI, test $build_usb_blaster_libftdi = yes)
AM_CONDITIONAL(USB_BLASTER_DRIVER, test $build_usb_blaster_ftd2xx = yes -o $build_usb_blaster_libftdi = yes)
AM_CONDITIONAL(AMTJTAGACCEL, test $build_amtjtagaccel = yes)
AM_CONDITIONAL(GW16012, test $build_gw16012 = yes)
AM_CONDITIONAL(PRESTO_LIBFTDI, test $build_presto_libftdi = yes)
@@ -952,6 +1035,7 @@ AM_CONDITIONAL(JLINK, test $build_jlink = yes)
AM_CONDITIONAL(VSLLINK, test $build_vsllink = yes)
AM_CONDITIONAL(RLINK, test $build_rlink = yes)
AM_CONDITIONAL(ARMJTAGEW, test $build_armjtagew = yes)
AM_CONDITIONAL(USB, test $build_usb = yes)
AM_CONDITIONAL(IS_CYGWIN, test $is_cygwin = yes)
AM_CONDITIONAL(IS_MINGW, test $is_mingw = yes)
AM_CONDITIONAL(IS_WIN32, test $is_win32 = yes)
@@ -1057,11 +1141,14 @@ AC_OUTPUT(dnl
src/Makefile dnl
src/helper/Makefile dnl
src/jtag/Makefile dnl
src/jtag/drivers/Makefile dnl
src/xsvf/Makefile dnl
src/svf/Makefile dnl
src/target/Makefile dnl
src/server/Makefile dnl
src/flash/Makefile dnl
src/flash/nor/Makefile dnl
src/flash/nand/Makefile dnl
src/pld/Makefile dnl
doc/Makefile dnl
)

View File

@@ -1,60 +1,68 @@
BUS!="usb", ACTION!="add", SUBSYSTEM!=="usb_device", GOTO="openocd_rules_end"
ACTION!="add|change", GOTO="openocd_rules_end"
SUBSYSTEM!="usb", GOTO="openocd_rules_end"
ENV{DEVTYPE}!="usb_device", GOTO="openocd_rules_end"
# Olimex ARM-USB-OCD
SYSFS{idVendor}=="15ba", SYSFS{idProduct}=="0003", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0003", MODE="664", GROUP="plugdev"
# Olimex ARM-USB-OCD-TINY
SYSFS{idVendor}=="15ba", SYSFS{idProduct}=="0004", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0004", MODE="664", GROUP="plugdev"
# Olimex ARM-JTAG-EW
SYSFS{idVendor}=="15ba", SYSFS{idProduct}=="001e", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="001e", MODE="664", GROUP="plugdev"
# Olimex ARM-USB-OCD-TINY-H
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="002a", MODE="664", GROUP="plugdev"
# USBprog with OpenOCD firmware
SYSFS{idVendor}=="1781", SYSFS{idProduct}=="0c63", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c63", MODE="664", GROUP="plugdev"
# Amontec JTAGkey and JTAGkey-tiny
SYSFS{idVendor}=="0403", SYSFS{idProduct}=="cff8", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="cff8", MODE="664", GROUP="plugdev"
# Amontec JTAGkey-HiSpeed
SYSFS{idVendor}=="0fbb", SYSFS{idProduct}=="1000", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0fbb", ATTRS{idProduct}=="1000", MODE="664", GROUP="plugdev"
# Axiom AXM-0432 Link (Symphony SoundBite?)
# Calao Systems USB-A9260-C01
# TinCanTools Flyswatter
# OOCD-Link
# Marvell Sheevaplug (early development versions)
SYSFS{idVendor}=="0403", SYSFS{idProduct}=="6010", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="664", GROUP="plugdev"
# Calao Systems USB-A9260-C02
SYSFS{idVendor}=="0403", SYSFS{idProduct}=="6001", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="664", GROUP="plugdev"
# IAR J-Link USB
SYSFS{idVendor}=="1366", SYSFS{idProduct}=="0101", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0101", MODE="664", GROUP="plugdev"
# Raisonance RLink
SYSFS{idVendor}=="138e", SYSFS{idProduct}=="9000", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="138e", ATTRS{idProduct}=="9000", MODE="664", GROUP="plugdev"
# Hitex STR9-comStick
SYSFS{idVendor}=="0640", SYSFS{idProduct}=="002c", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002c", MODE="664", GROUP="plugdev"
# Hitex STM32-PerformanceStick
SYSFS{idVendor}=="0640", SYSFS{idProduct}=="002d", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002d", MODE="664", GROUP="plugdev"
# Luminary Micro Stellaris/LM3S811
SYSFS{idVendor}=="0403", SYSFS{idProduct}=="bcd9", MODE="664", GROUP="plugdev"
# TI/Luminary Stellaris Evaluation Board (several)
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcd9", MODE="664", GROUP="plugdev"
# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcda", MODE="664", GROUP="plugdev"
# Xverve Signalyzer Tool (DT-USB-ST)
SYSFS{idVendor}=="0403", SYSFS{idProduct}=="bca0", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca0", MODE="664", GROUP="plugdev"
# egnite Turtelizer 2
SYSFS{idVendor}=="0403", SYSFS{idProduct}=="bdc8", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bdc8", MODE="664", GROUP="plugdev"
# Marvell Sheevaplug
SYSFS{idVendor}=="9e88", SYSFS{idProduct}=="9e8f", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", MODE="664", GROUP="plugdev"
# Section5 ICEbear
SYSFS{idVendor}=="0403", SYSFS{idProduct}=="c140", MODE="664", GROUP="plugdev"
SYSFS{idVendor}=="0403", SYSFS{idProduct}=="c141", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c140", MODE="664", GROUP="plugdev"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c141", MODE="664", GROUP="plugdev"
LABEL="openocd_rules_end"

View File

@@ -31,7 +31,95 @@ This section needs to be expanded to describe OpenOCD's Jim API.
/** @page helpercommand OpenOCD Command API
This section needs to be expanded to describe OpenOCD's Command API.
OpenOCD's command API allows modules to register callbacks that are then
available to the scripting services. It provides the mechanism for
these commands to be dispatched to the modlue using a standard
interfaces. It provides macros for defining functions that use and
extend this interface.
@section helpercmdhandler Command Handlers
Command handlers are functions with a particular signature, which can
be extended by modules for passing additional parameters to helpers or
another layer of handlers.
@subsection helpercmdhandlerdef Defining and Calling Command Handlers
These functions should be defined using the @c COMMAND_HANDLER macro.
These methods must be defined as static, as their principle entry point
should be the run_command dispatch mechanism.
Command helper functions that require access to the full set of
parameters should be defined using the @c COMMAND_HELPER. These must be
declared static by you, as sometimes you might want to share a helper
among several files (e.g. @c s3c24xx_nand.h).
Both types of routines must be called using the @c CALL_COMMAND_HANDLER macro.
Calls using this macro to normal handlers require the name of the command
handler (which can a name or function pointer). Calls to helpers and
derived handlers must pass those extra parameters specified by their
definitions; however, lexical capture is used for the core parameters.
This dirty trick is being used as a stop-gap measure while the API is
migrated to one that passes a pointer to a structure containing the
same ingredients. At that point, this macro will be removed and callers
will be able to use direct invocations.
Thus, the following macros can be used to define and call command
handlers or helpers:
- @c COMMAND_HANDLER - declare or define a command handler.
- @c COMMAND_HELPER - declare or define a derived command handler or helper.
- @c CALL_COMMAND_COMMAND - call a command handler/helper.
@subsection helpercmdhandlermacros Command Handler Macros
In addition, the following macros may be used in the context of
command handlers and helpers:
- @c CMD_CTX - the current @c command_context
- @c CMD_NAME - invoked command name
- @c CMD_ARGC - the number of command arguments
- @c CMD_ARGV - array of command argument strings
@section helpercmdregister Command Registration
In order to use a command handler, it must be registered with the
command subsystem. All commands are registered with command_registration
structures, specifying the name of the command, its handler, its allowed
mode(s) of execution, and strings that provide usage and help text.
A single handler may be registered using multiple names, but any name
may have only one handler associated with it.
The @c register_commands() and @c register_commands() functions provide
registration, while the @c unregister_command() and
@c unregister_all_commands() functions will remove existing commands.
These may be called at any time, allowing the command set to change in
response to system actions.
@subsection helpercmdjim Jim Command Registration
The command_registration structure provides support for registering
native Jim command handlers (@c jim_handler) too. For these handlers,
the module can provide help and usage support; however, this mechanism
allows Jim handlers to be called as sub-commands of other commands.
These commands may be registered with a private data value (@c
jim_handler_data) that will be available when called, as with low-level
Jim command registration.
A command may have a normal @c handler or a @c jim_handler, but not both.
@subsection helpercmdregisterchains Command Chaining
When using register_commands(), the array of commands may reference
other arrays. When the @c chain field is filled in a
command_registration record, the commands on in the chained list will
added in one of two places. If the record defines a new command, then
the chained commands are added under it; otherwise, the commands are
added in the same context as the other commands in the array.
@section helpercmdprimer Command Development Primer
This @ref primercommand provides details about the @c hello module,
showing how the pieces desrcribed on this page fit together.
*/

View File

@@ -1,6 +1,6 @@
/** @mainpage OpenOCD Reference Manual
/** @mainpage OpenOCD Developer's Guide
Welcome to the OpenOCD Reference Manual -- the developer's resource for
Welcome to the OpenOCD Developer's Guide -- the developer's resource for
learning about the internal architecture of the OpenOCD project. @par
In addition, this document contains the tactical and strategic plans
@@ -42,11 +42,17 @@ associated with the fundamental technologies used by OpenOCD.
- @subpage primertcl
- @subpage primerjtag
These documents should bridge any "ancillary" gaps in contributor
The above documents should bridge any "ancillary" gaps in contributor
knowledge, without having to learn the complete languages or technology.
They should provide enough information for experienced developers to
learn how to make "correct" changes when creating patches.
Beyond the fundamentals, the following primers provide introductory
tutorials for OpenOCD's sub-systems. These complement the @ref oocd
pages that provide more high-level perspective on related topics.
- @subpage primercommand
In all cases, these Primers should use idiomatic conventions that the
community has agreed are the "right way of doing things". In this
respect, these documents typically assume some familiarity with the

View File

@@ -0,0 +1,138 @@
/** @page primercommand Command Development Primer
This page provides a primer for writing commands by introducing @c hello
module. The full source code used in this example can be found in
hello.c, and the @ref primercmdcode section shows how to use it.
A summary of this information can be found in @ref helpercommand .
@section primercmdhandler Command Handlers
Defining new commands and their helpers is easy. The following code
defines a simple command handler that delegates its argument parsing:
@code
COMMAND_HANDLER(handle_hello_command)
{
const char *sep, *name;
int retval = CALL_COMMAND_HANDLER(handle_hello_args);
if (ERROR_OK == retval)
command_print(CMD_CTX, "Greetings%s%s!", sep, name);
return retval;
}
@endcode
Here, the @c COMMAND_HANDLER macro establishes the function signature,
see in command.h by the @c __COMMAND_HANDLER macro.
The COMMAND_HELPER macro function allows defining functions with an
extended version of the base signature. These helper functions can be
called (with the appropriate parameters), the @c CALL_COMMAND_HANDLER
macro to pass any e as parameters to the following helper function:
The subsequent blocks of code are a normal C function that can do
anything, so only complex commands deserve should use comamnd helper
functions. In this respect, this example uses one to demonstrate how --
not when -- they should be used.
@code
static COMMAND_HELPER(handle_hello_args, const char **sep, const char **name)
{
if (argc > 1)
{
LOG_ERROR("%s: too many arguments", CMD_NAME);
return ERROR_COMMAND_SYNTAX_ERROR;
}
if (1 == CMD_ARGC)
{
*sep = ", ";
*name = CMD_ARGV[0];
}
else
*sep = *name = "";
return ERROR_OK;
}
@endcode
Of course, you may also call other macros or functions, but that extends
beyond the scope of this tutorial on writing commands.
@section primercmdreg Command Registration
Before this new function can be used, it must be registered somehow.
For a new module, registering should be done in a new function for
the purpose, which must be called from @c openocd.c:
@code
static const struct command_registration hello_command_handlers[] = {
{
.name = "hello",
.mode = COMMAND_ANY,
.handler = handle_hello_command,
.help = "print a warm greeting",
.usage = "[name]",
},
{
.chain = foo_command_handlers,
}
COMMAND_REGISTRATION_DONE
};
int hello_register_commands(struct command_context_s *cmd_ctx)
{
return register_commands(cmd_ctx, NULL, handle_command_handlers);
}
@endcode
Note that the "usage" text should use the same EBNF that's found
in the User's Guide: literals in 'single quotes', sequences of
optional parameters in [square brackets], and alternatives in
(parentheses|with|vertical bars), and so forth. No angle brackets.
That's it! The command should now be registered and available to scripts.
@section primercmdchain Command Chaining
This example also shows how to chain command handler registration, so
your modules can "inherit" commands provided by other (sub)modules.
Here, the hello module includes the foo commands in the same context
that the 'hello' command will be registered.
If the @c chain field had been put in the 'hello' command, then the
@c foo module commands would be registered under it. Indeed, that
technique is used to define the 'foo bar' and 'foo baz' commands,
as well as for the example drivers that use these modules.
The code for the 'foo' command handlers can be found in @c hello.c.
@section primercmdcode Trying These Example Commands
These commands have been inherited by the dummy interface, faux flash,
and testee target drivers. The easiest way to test these is by using the
dummy interface.
Once OpenOCD has been built with this example code, the following command
demonstrates the abilities that the @c hello module provides:
@code
openocd -c 'interface dummy' \
-c 'dummy hello' \
-c 'dummy hello World' \
-c 'dummy hello {John Doe}' \
-c 'dummy hello John Doe' # error: too many arguments
@endcode
If saved in @c hello.cfg, then running <code>openocd -f hello.cfg</code>
should produce the following output before displaying the help text and
exiting:
@code
Greetings!
Greetings, World!
Greetings, John Doe!
Error: hello: too many arguments
Runtime error, file "openocd.cfg", line 14:
hello: too many arguments
dummy hello [<name>]
prints a warm welcome
@endcode
*/

View File

@@ -10,7 +10,7 @@ This page provides an introduction to the OpenOCD Release Processes:
activities for each release cycle.
- @ref releasehow - Outlines all of the steps for the
processes used to produce and release the package source archives.
- @ref releasescript - Introduces the automated @c release.sh script.
- @ref releasescriptcmds - Introduces the automated @c release.sh script.
@section releasewhy Why Produce Releases?
@@ -25,14 +25,21 @@ 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 git repository:
When properly versioned and released for users, these archives present
several important advantages compared to using the source repository
(including snapshots downloaded from that repository using gitweb):
-# 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 work-in-process revision.
-# They free developers from answering questions about mainline breakage.
-# They allow others to package and distribute the code using
consistent version labels. Users won't normally need to care
whose package they use, just the version of OpenOCD.
-# They contain a working configure script and makefiles, which
were produced as part of creating the archive.
-# Because they have been formally released by the project, users
don't need to try a random work-in-process revision. Releasing
involves spending some time specifically on quality improvments,
including bugfixing source code and documentation.
-# They provide developers with the flexibility needed to address
larger issues, which sometimes involves temporary breakage.
Hopefully, this shows several good reasons to produce regular releases,
but the release processes were developed with some additional design
@@ -45,66 +52,112 @@ following properties:
-# 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
remaining to be made toward automating the process.
They attempt to meet these design goals, but improvements may still
need to be made.
@section releaseversions Release Versions
@subsection version_labels Version Labels
Users can display the OpenOCD version string in at least two
ways. The command line <code>openocd -v</code> invocation
displays it; as does the Tcl <code>version</code> command.
Labels for released versions look like <em>0.3.0</em>, or
<em>0.3.0-rc1</em> for a preliminary release.
Non-released (developer) versions look like <em>0.3.0-dev</em>,
or <em>0.3.0-rc1-dev</em>.
In all cases, additional tags may be appended to those base
release version labels.
The <code>tools/release/version.sh</code> script is used to
manipulate version IDs found in the source tree.
@subsubsection releaseversions Release Versions and Tags
The OpenOCD version string is composed of three numeric components
separated by two decimal points: @c x.y.z, where @c x is the @a major
version number, @c y is the @a minor number, and @c z is the @a micro.
For a <i>bug-fix</i> release, the micro version number will be non-zero
For any <em>bug-fix</em> release, the micro version number will be non-zero
(<code>z > 0</code>). For a <i>minor release</i>, the micro version
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>).
@subsection releaseversiontags Version Tags
After these required numeric components, release version strings
may contain tags such as as <em>-rc1</em> or <em>-rc2</em>.
These 'rc' tags indicate "release candidate" versions of the package.
Like the major/minor/micro numbers, these tags will be manipulated
by the automated release process.
After these required numeric components, the version string may contain
one or more <i>version tags</i>, such as '-rc1' or '-dev'.
The release process includes version number manipulations to the tree
being released, ensuring that all numbers are incremented (or rolled
over) at the right time and in the proper locations of the repository.
One of those manipulations creates a repository tag matching that
release's version label.
Mainline and all branches should have the tag '-dev' in
their version number. This tag helps developers identify reports
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.
The 'rc' tags indicate a "release candidate" version of the package.
This tag will also be manipulated by the automated release process.
Additional tags may be used as necessary.
@subsection releaseversionsdist Packager Versions
@subsubsection 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.
Knowing that a release has such patches can be essential to tracking
down and fixing bugs.
For example, the following command will add a 'foo1' tag to the
configure.in script of a local copy of the source tree:
Packager version tags should always be suffixes to the version
code from the OpenOCD project, signifying modifications to the
original code base. Each packager release should have a unique
version.
For example, the following command will add a 'foo' tag to the
configure.in script of a local copy of the source tree, giving
a version label like <em>0.3.0-foo</em>:
@code
tools/release.sh version bump tag foo
tools/release/version.sh version tag add 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
and used to produce your own derived versions. You might check that
change into a private branch of your git tree, along with the other
patches you are providing.
You can also "bump" those tags (so "foo1" becomes "foo2" etc)
each time a derived package is released, incrementing the tag's
version to facilitate tracking the changes you have distributed.
@subsection releaseversionhow Version Processes
@code
tools/release/version.sh version bump tag foo
@endcode
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.
Of course, any patches in your branches must be provided to
your customers, and be in conformance with the GPL. In most
cases you should also work to merge your improvements to the
mainline tree.
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.
@subsubsection version_tags Development Versions and Tags
Everything except formal releases should have the tag <em>-dev</em>
in their version number. This helps developers identify reports
created from non-release versions, 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.
Versions built from developer trees may have additional tags.
Trees built from git snapshots have <em>snapshot</em> tags.
When built from a "live" git tree, tags specify
specific git revisions:
0.3.0-rc1-dev-00015-gf37c9b8-dirty
indicates a development tree based on git revison f37c9b8
(a truncated version of a SHA1 hash) with some non-git
patches applied (the <em>dirty</em> tag). This information
can be useful when tracking down bugs.
(Note that at this writing, the tags do not directly
correspond to <code>git describe</code> output. The
hash ID can be used with <code>git show</code>, but
the relevant repository tag isn't <em>0.3.0-rc1-dev</em>;
this might change in the future.)
@section releasewho Release Manager
@@ -132,14 +185,23 @@ the changes to the package version, though the release tools should
manage the tasks of adding or removing any required development branch
tags and incrementing the version.
These responsibilities matter most towards the end of the release
cycle, when the RM creates the first RC and all contributors enter
a quality-improvement mode. The RM works with other contributors
to make sure everyone knows what kinds of fixes should merge, the
status of major issues, and the release timetable.
In particular, the RM has the final decision on whether a given
bug should block the release.
@section releasewhen Release Schedule
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.
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.
Starting with the 0.2.0 release, the OpenOCD project expects to produce
new releases every few months.
Bug fix releases could be provided more frequently. These release
schedule goals may be adjusted in the future, after the project
maintainers and distributors receive feedback and experience.
@@ -155,16 +217,26 @@ 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
might describe some of the key milestones of the new release cycle:
If Tn is the time of release n, then the following schedule
might describe some key T0-to-T1 release cycle milestones.
- T minus one month: start of new development cycle
- 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
- T minus zero: Announce the release to our mailing list and the world.
- T0 ... End of T0 release cycle. T1 cycle starts, with merge
window opening. Developers begin to merge queued work.
- <em>... several weeks of merge window ...</em>
- RC1 ... Close mainline to new work. Produce RC1
release, begin testing phase; developers are in "bugfix mode",
all other work is queued; send out planned endgame schedule.
- RC2 ... Produce RC2 and send schedule update to
mailing list, listing priorities for remaining fixes
- <em>... more RC milestones, until ready ...</em>
- T1: End of T1 release cycle. T2 cycle starts, with merge
window opening. Developers begin to merge queued work.
Note that until it happens, any date for T1 is just a goal.
Critical bugs prevent releases from happening. We are just
beginning to use this window-plus-RCs process, so the lengths
of the merge windows versus the RC phase is subject to change.
Most projects have RC phases of a month or more.
Some additional supplemental communication will be desirable. The above
list omits the step-by-step instructions to daily release management.
@@ -176,29 +248,21 @@ The next section explains why the OpenOCD project allows significant
flexibility in the part of the development that precedes the release
process.
@note The OpenOCD project does not presently produce -rc packages. As
such, the step suggested in the list above should be read as trying to
stimulate others to test the project build and packaging on as many
platforms as possible. This proposition will be palatable once release
management tools have been committed to the tree.
@subsection releasewhenflex Schedule Flexibility
The Release Manager should attempt to follow the guidelines in this
document, but the process of scheduling each release milestone should be
community driven at the start. By the end, missing features that were
scheduled for a release must be dropped by the Release Manager, rather
than allowing the release cycle to be delayed while waiting for them.
community driven at the start. Features that don't complete before
the merge window closes can be held (perhaps in some branch) until
the next merge window opens, rather than delaying the release cycle.
Despite any assurances this schedule may appear to give, the Release
The Release
Manager cannot schedule the work that will be done on the project,
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
That is, 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.
In particular, the suggested period of "one or two month" reflects some
expectation of a fairly high rate of development. Fewer releases may be
continuously in response to changes in the rate of work.
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
@@ -206,49 +270,52 @@ the situation and gathering feedback from the community.
@section releasehow Release Process: Step-by-Step
The release process may require a few iterations to work out any bugs.
Even with the release script, some steps require clear user intervention
-- and not only by the Release Manager.
The release process is not final; it may need more iterations
to work out bugs.
While there are release scripts, key steps require community
support; the Release Manager isn't the only participant.
The following steps should be followed to produce each release:
-# Produce final manual patches to mainline (or release branch):
-# Produce final patches to mainline (or a release branch). Nobody
except the RM should be committing anything.
-# Finalize @c NEWS file to describe the changes in the release
- This file is Used to automatically post "blurbs" about the project.
- 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)
-# 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
@endverbatim
- Tag the final commit with a consistent GIT tag name and message:
-# Update and commit the final package version in @c configure.in:
<code>tools/release/version.sh</code> may help ensure the versions
are named consistently:
-# Remove @c -dev tag.
-# Update the @c -rc tag:
- If producing the final release from an -rc series, remove it
- If producing the first RC in a series, add rc1
- If producing the next RC in a series, bump the rc number
-# Commit that version change.
-# Create a git tag for the final commit, with a tag name matching
the version string in <code>configure.in</code> (including <em>-rcN</em>
where relevant):
@verbatim
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 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.
-# Prepare to resume normal development on mainline (major or minor release)
- Update the version label
- Restore @c -dev version tag.
- For a new minor release cycle, increment the release's minor number
- For a new major release cycle, increment the release's major number
and zero its minor number
- Archive @c NEWS file as "<code>doc/news/NEWS-${PACKAGE_VERSION}</code>".
- Create a new @c NEWS file for the next release
- Commit those changes, and push the commit and the release tag
to mainline.
-# Produce the package source archives:
-# Start with a clean working copy, used for producing releases only.
-# <em>Start with a new clone of the source tree</em>, with the
release's tag. This is used only for producing these packages.
-# Checkout the appropriate tag:
<code>git checkout $(git tag ) "${PACKAGE_VERSION}"</code>
-# Produce a ChangeLog for the release (using @c git2cl).
<code>git checkout "${PACKAGE_VERSION}"</code>
-# @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.
@@ -257,8 +324,7 @@ git tag -m "The openocd-${PACKAGE_VERSION} release." "${PACKAGE_TAG}"
- Allow users to access the documentation for each of our releases.
- Place static copies of the following files on the project website:
- @c NEWS: to provide a blurb for each release
- @c ChangeLog: to show exactly what has been changed
- User Guide, Developer Manual: to allow easy on-line viewing
- User's Guide, Developer Manual: to allow easy on-line viewing
-# Upload packages and post announcements of their availability:
-# Release packages into files section of project sites:
- SF.net:
@@ -271,7 +337,7 @@ git tag -m "The openocd-${PACKAGE_VERSION} release." "${PACKAGE_TAG}"
- .zip: Windows
- Berlios:
-# Create the new release for the new version.
-# Provide @c NEWS and ChangeLog files, as requested.
-# Provide @c NEWS file, as requested.
-# Upload files via FTP to ftp://ftp.berlios.de/incoming/
-# Edit descriptions for each file.
-# Click button to send E-mail Release Notice.
@@ -279,24 +345,23 @@ git tag -m "The openocd-${PACKAGE_VERSION} release." "${PACKAGE_TAG}"
-# Announce updates on freshmeat.net and other trackers.
-# Submit big updates to news feeds (e.g. Digg, Reddit, etc.).
@section releasescript The Release Script
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 2 through 4,
allowing the Release Manager from perform these tasks in easy steps.
The following task still need to be automated:
- Step 5: produce documentation for website using released source archive.
- Step 6(a): package archive upload process.
- Step 6(b): package announcement e-mail process.
- Step 6(c): post files and announce them using releaseforge.
To start a bug-fix release branch:
-# Create a new branch, starting from a major or
minor release tag
-# Restore @c -dev version tag.
-# Bump micro version number in configure.in
-# Backport bugfix patches from mainline into that branch.
(Always be sure mainline has the fix first, so it's hard
to just lose a bugfix.)
-# Commit and push those patches.
-# When desired, release as above ... except note that the next
release of a bugfix branch is never a new major or minor release
@subsection releasescriptcmds Release Script Commands
The @c release.sh script automates some of the steps involved
in making releases, simplifying the Release Manager's work.
The release script can be used for two tasks:
- Creating releases and starting a new release cycle:
@code
@@ -334,7 +399,7 @@ affect its behavior:
@section releasetutorial Release Tutorials
This section should contain a brief tutorial for using the Release
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.

View File

@@ -320,6 +320,6 @@ openocd -s /usr/local/share/openocd -f httpd/httpd.tcl -f interface/dummy.cfg -f
Navigate to: http://localhost:8888/
*/

View File

@@ -66,8 +66,9 @@ Finally, try to avoid lines of code that are longer than than 72-80 columns:
- most identifiers must use lower-case letters (and digits) only.
- macros must use upper-case letters (and digits) only.
- OpenOCD identifiers should NEVER use @c MixedCaps.
- structure names must end with the '_s' suffix.
- typedef names must end with the '_t' suffix.
- @c typedef names must end with the '_t' suffix.
- This should be reserved for types that should be passed by value.
- Do @b not mix the typedef keyword with @c struct.
- use underline characters between consecutive words in identifiers
(e.g. @c more_than_one_word).
@@ -77,8 +78,11 @@ Finally, try to avoid lines of code that are longer than than 72-80 columns:
- @c // comments -- in new code, prefer these for single-line comments
- trailing comma allowed in enum declarations
- designated initializers (@{ .field = value @})
- variables declarations may be mixed with code
- variables declarations should occur at the point of first use
- new block scopes for selection and iteration statements
- use malloc() to create dynamic arrays. Do @b not use @c alloca
or variable length arrays on the stack. non-MMU hosts(uClinux) and
pthreads require modest and predictable stack usage.
@section styletypes Type Guidelines
- use native types (@c int or @c unsigned) if the type is not important
@@ -176,7 +180,7 @@ The following guidelines apply to all Doxygen comment blocks:
-# @c function_name() can be used to reference functions
(e.g. flash_set_dirty()).
-# @c struct_name::member_name should be used to reference structure
fields in the documentation (e.g. @c flash_driver_s::name).
fields in the documentation (e.g. @c flash_driver::name).
-# URLS get converted to markup automatically, without any extra effort.
-# new pages can be linked into the heirarchy by using the @c \@subpage
command somewhere the page(s) under which they should be linked:
@@ -304,7 +308,7 @@ For technical reference material:
- Else it's a "Config Command" if it must be used before the
configuration stage completes.
- For a "Driver", list its name.
- Use BNF style regular expressions to define parameters:
- Use EBNF style regular expressions to define parameters:
brackets around zero-or-one choices, parentheses around
exactly-one choices.
- Use \@option, \@file, \@var and other mechanisms where appropriate.

View File

@@ -1,4 +1,4 @@
.TH "OPENOCD" "1" "January 08, 2009"
.TH "OPENOCD" "1" "November 24, 2009"
.SH "NAME"
openocd \- A free and open on\-chip debugging, in\-system programming and
boundary\-scan testing tool for ARM and MIPS systems
@@ -22,19 +22,23 @@ please check the \fIopenocd\fR info page for the complete list.
.SH "OPTIONS"
.TP
.B "\-f, \-\-file <filename>"
Use configuration file
.BR <filename> .
This is a shortcut for a \fB\-c "[script \fI<filename>\fB]"\fR
command, using a search path to load the configuration file
.IR <filename> .
In order to specify multiple config files, you can use multiple
.B \-\-file
arguments. If this option is omitted, the config file
arguments. If no such \fB\-c\fR
options are included, the first config file
.B openocd.cfg
in the current working directory will be used.
in the search path will be used.
.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.
Add
.I <dirname>
to the search path used for config files and scripts.
The search path begins with the current directory,
then includes these additional directories before other
components such as the standard OpenOCD script libraries.
.TP
.B "\-d, \-\-debug <debuglevel>"
Set debug level. Possible values are:
@@ -52,13 +56,17 @@ The default level is
.TP
.B "\-l, \-\-log_output <filename>"
Redirect log output to the file
.BR <filename> .
.IR <filename> .
Per default the log output is printed on
.BR stderr .
.TP
.B "\-c, \-\-command <cmd>"
Run the command
.BR <cmd> .
Add the command
.I <cmd>
to a list of commands executed on server startup.
Note that you will need to explicitly invoke
.I init
if the command requires access to a target or flash.
.TP
.B "\-p, \-\-pipe"
Use pipes when talking to gdb.
@@ -69,9 +77,7 @@ Show a help text and exit.
.B "\-v, \-\-version"
Show version information and exit.
.SH "BUGS"
Please report any bugs at
.B http://developer.berlios.de/bugs/?group_id=4148
or on the mailing list
Please report any bugs on the mailing list at
.BR openocd\-development@lists.berlios.de .
.SH "LICENCE"
.B OpenOCD
@@ -90,9 +96,6 @@ and
programs are properly installed at your site, the command
.B info openocd
should give you access to the complete manual.
.PP
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

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
Some of these binaries are build & linked using eCos.
Some of these binaries are build & linked using eCos.
For source for the flash drivers, see:

View File

@@ -1,4 +1,12 @@
SUBDIRS = helper jtag xsvf svf target server flash pld
SUBDIRS = \
helper \
jtag \
target \
flash \
svf \
xsvf \
pld \
server
lib_LTLIBRARIES = libopenocd.la
bin_PROGRAMS = openocd
@@ -12,19 +20,20 @@ endif
openocd_SOURCES = $(MAINFILE)
openocd_LDADD = libopenocd.la
libopenocd_la_SOURCES = openocd.c
libopenocd_la_SOURCES = \
hello.c \
openocd.c \
startup_tcl.c
noinst_HEADERS = \
hello.h \
openocd.h
# set the include path found by configure
AM_CPPFLAGS = \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/helper \
-I$(top_srcdir)/src/jtag \
-I$(top_srcdir)/src/target \
-I$(top_srcdir)/src/xsvf \
-I$(top_srcdir)/src/svf \
-I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/flash \
-I$(top_srcdir)/src/pld
-I$(top_builddir)/src
libopenocd_la_CPPFLAGS = -DPKGBLDDATE=\"`date +%F-%R`\"
@@ -51,12 +60,16 @@ endif
if FT2232_LIBFTDI
FTDI2232LIB = -lftdi -lusb
else
if USB_BLASTER_LIBFTDI
FTDI2232LIB = -lftdi -lusb
else
if PRESTO_LIBFTDI
FTDI2232LIB = -lftdi -lusb
else
FTDI2232LIB =
endif
endif
endif
if USBPROG
LIBUSB = -lusb
@@ -91,6 +104,30 @@ if HTTPD
libopenocd_la_LIBADD += -lmicrohttpd
endif
STARTUP_TCL_SRCS = \
$(srcdir)/helper/startup.tcl \
$(srcdir)/jtag/startup.tcl \
$(srcdir)/target/startup.tcl \
$(srcdir)/flash/startup.tcl \
$(srcdir)/server/startup.tcl
EXTRA_DIST = $(STARTUP_TCL_SRCS)
BUILT_SOURCES = startup.tcl
startup.tcl: $(STARTUP_TCL_SRCS)
cat $^ > $@
BIN2C = $(top_builddir)/src/helper/bin2char$(EXEEXT_FOR_BUILD)
# Convert .tcl to cfile
startup_tcl.c: startup.tcl $(BIN2C)
$(BIN2C) openocd_startup_tcl < $< > $@ || rm -f $@
# add startup_tcl.c to make clean list
CLEANFILES = startup.tcl startup_tcl.c
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
# The "quick" target builds executables & reinstalls the executables

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2007-2008 by Øyvind Harboe *
* Copyright (C) 2007-2009 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 *
@@ -21,23 +21,18 @@
#include "config.h"
#endif
#include "log.h"
#include "types.h"
#include "jtag.h"
#include "configuration.h"
#include "xsvf.h"
#include "svf.h"
#include "target.h"
#include "flash.h"
#include "nand.h"
#include "pld.h"
#include <helper/types.h>
#include <jtag/jtag.h>
#include <helper/ioutil.h>
#include <helper/configuration.h>
#include "command.h"
#include "server.h"
#include "telnet_server.h"
#include "gdb_server.h"
#include <server/server.h>
#include <server/telnet_server.h>
#include <server/gdb_server.h>
#include <openocd.h>
#include <helper/time_support.h>
#include <time_support.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
@@ -59,29 +54,20 @@
#include <cyg/athttpd/cgi.h>
#include <cyg/athttpd/forms.h>
#include <cyg/discover/discover.h>
#include <cyg/hal/hal_diag.h>
#include <cyg/kernel/kapi.h>
#include <cyg/io/serialio.h>
#include <cyg/io/io.h>
#include <cyg/io/serialio.h>
#include <netinet/tcp.h>
#include "rom.h"
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <ifaddrs.h>
#include <string.h>
#include <cyg/hal/hal_diag.h>
#include <unistd.h>
#include <stdio.h>
#include "rom.h"
#ifdef CYGPKG_HAL_NIOS2
#include <cyg/hal/io.h>
#define ZY1000_SER_DEV "/dev/uart_0"
#else
#define ZY1000_SER_DEV "/dev/ser0"
#endif
#define MAX_IFS 64
@@ -114,8 +100,8 @@ static bool writeLog = true;
char hwaddr[512];
extern flash_driver_t *flash_drivers[];
extern target_type_t *target_types[];
extern struct flash_driver *flash_drivers[];
extern struct target_type *target_types[];
#ifdef CYGPKG_PROFILE_GPROF
#include <cyg/profile/profile.h>
@@ -160,7 +146,14 @@ static void zylinjtag_reboot(cyg_addrword_t data)
diag_printf("Unmounting /config..\n");
umount("/config");
diag_printf("Rebooting..\n");
#ifdef CYGPKG_HAL_NIOS2
/* This will reboot & reconfigure the FPGA from the bootloader
* and on.
*/
IOWR(REMOTE_UPDATE_BASE, 0x20, 0x1);
#else
HAL_PLATFORM_RESET();
#endif
}
static cyg_thread zylinjtag_thread_object;
static cyg_handle_t zylinjtag_thread_handle;
@@ -229,7 +222,7 @@ void reboot_port(void)
cyg_thread_resume(zylinjtag_reboot_port_thread_handle);
}
int configuration_output_handler(struct command_context_s *context,
int configuration_output_handler(struct command_context *context,
const char* line)
{
diag_printf("%s", line);
@@ -237,7 +230,7 @@ int configuration_output_handler(struct command_context_s *context,
return ERROR_OK;
}
int zy1000_configuration_output_handler_log(struct command_context_s *context,
int zy1000_configuration_output_handler_log(struct command_context *context,
const char* line)
{
LOG_USER_N("%s", line);
@@ -246,11 +239,21 @@ int zy1000_configuration_output_handler_log(struct command_context_s *context,
}
#ifdef CYGPKG_PROFILE_GPROF
//extern int64_t totaltime;
int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
static int zylinjtag_Jim_Command_profile(Jim_Interp *interp, int argc,
Jim_Obj * const *argv)
{
command_print(cmd_ctx, "Profiling started");
start_profile();
if ((argc == 2) && (strcmp(Jim_GetString(argv[1], NULL), "stats")==0))
{
// profile_off();
//LOG_USER("Stats %dms sleeping in select()", (int)totaltime);
} else
{
LOG_USER("Profiling started");
start_profile();
//totaltime = 0;
}
return ERROR_OK;
}
@@ -258,7 +261,7 @@ int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s *cmd_ctx
externC void phi_init_all_network_interfaces(void);
command_context_t *cmd_ctx;
struct command_context *cmd_ctx;
static bool webRunning = false;
@@ -474,7 +477,6 @@ static int zylinjtag_Jim_Command_reboot(Jim_Interp *interp, int argc,
return JIM_OK;
}
static void zylinjtag_startNetwork(void)
{
// Bring TCP/IP up immediately before we're ready to accept commands.
@@ -501,8 +503,6 @@ static void zylinjtag_startNetwork(void)
cyg_httpd_init_tcl_interpreter();
interp = httpstate.jim_interp;
Jim_CreateCommand(httpstate.jim_interp, "log", zylinjtag_Jim_Command_log,
NULL, NULL);
Jim_CreateCommand(httpstate.jim_interp, "zy1000_reboot",
@@ -591,6 +591,7 @@ static void print_exception_handler(cyg_addrword_t data, cyg_code_t exception,
}
#ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
static void setHandler(cyg_code_t exception)
{
cyg_exception_handler_t *old_handler;
@@ -599,6 +600,7 @@ static void setHandler(cyg_code_t exception)
cyg_exception_set_handler(exception, print_exception_handler, 0,
&old_handler, &old_data);
}
#endif
static cyg_thread zylinjtag_uart_thread_object;
static cyg_handle_t zylinjtag_uart_thread_handle;
@@ -686,7 +688,7 @@ static void zylinjtag_uart(cyg_addrword_t data)
int oldopts = fcntl(session, F_GETFL, 0);
fcntl(session, F_SETFL, oldopts | O_NONBLOCK); //
int serHandle = open("/dev/ser0", O_RDWR | O_NONBLOCK);
int serHandle = open(ZY1000_SER_DEV, O_RDWR | O_NONBLOCK);
if (serHandle < 0)
{
close(session);
@@ -748,7 +750,6 @@ static void zylinjtag_uart(cyg_addrword_t data)
pos2 = 0;
}
size_t x = actual2;
size_t y = 0;
if (actual2 > 0)
{
@@ -778,7 +779,6 @@ static void zylinjtag_uart(cyg_addrword_t data)
actual += t;
}
int x2 = actual;
int y2 = 0;
if (actual > 0)
{
@@ -841,21 +841,25 @@ void startUart(void)
cyg_thread_resume(zylinjtag_uart_thread_handle);
}
int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd,
char **args, int argc)
static int zylinjtag_Jim_Command_uart(Jim_Interp *interp, int argc,
Jim_Obj * const *argv)
{
static int current_baud = 38400;
if (argc == 0)
if (argc == 1)
{
command_print(cmd_ctx, "%d", current_baud);
return ERROR_OK;
Jim_SetResult(interp, Jim_NewIntObj(interp, current_baud));
return JIM_OK;
}
else if (argc != 1)
else if (argc != 2)
{
return ERROR_INVALID_ARGUMENTS;
return JIM_ERR;
}
current_baud = atol(args[0]);
long new_baudrate;
if (Jim_GetLong(interp, argv[1], &new_baudrate) != JIM_OK)
return JIM_ERR;
current_baud = new_baudrate;
int baud;
switch (current_baud)
@@ -879,8 +883,8 @@ int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd,
baud = CYGNUM_SERIAL_BAUD_230400;
break;
default:
command_print(cmd_ctx, "unsupported baudrate");
return ERROR_INVALID_ARGUMENTS;
Jim_SetResult(interp, Jim_NewStringObj(interp, "unsupported baudrate", -1));
return JIM_ERR;
}
cyg_serial_info_t buf;
@@ -890,11 +894,11 @@ int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd,
int err;
cyg_io_handle_t serial_handle;
err = cyg_io_lookup("/dev/ser0", &serial_handle);
err = cyg_io_lookup(ZY1000_SER_DEV, &serial_handle);
if (err != ENOERR)
{
LOG_ERROR("/dev/ser0 not found\n");
return ERROR_FAIL;
Jim_SetResult(interp, Jim_NewStringObj(interp, "Could not open serial port", -1));
return JIM_ERR;
}
err = cyg_io_get_config(serial_handle,
@@ -903,8 +907,8 @@ int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd,
&len);
if (err != ENOERR)
{
command_print(cmd_ctx, "Failed to get serial port settings %d", err);
return ERROR_OK;
Jim_SetResult(interp, Jim_NewStringObj(interp, "Failed to get serial port settings", -1));
return JIM_ERR;
}
buf.baud = baud;
@@ -912,11 +916,11 @@ int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd,
&len);
if (err != ENOERR)
{
command_print(cmd_ctx, "Failed to set serial port settings %d", err);
return ERROR_OK;
Jim_SetResult(interp, Jim_NewStringObj(interp, "Failed to set serial port settings", -1));
return JIM_ERR;
}
return ERROR_OK;
return JIM_OK;
}
bool logAllToSerial = false;
@@ -925,8 +929,6 @@ bool logAllToSerial = false;
int boolParam(char *var);
command_context_t *setup_command_handler(void);
static const char *zylin_config_dir="/config/settings";
static int add_default_dirs(void)
@@ -937,8 +939,6 @@ static int add_default_dirs(void)
return ERROR_OK;
}
int ioutil_init(struct command_context_s *cmd_ctx);
int main(int argc, char *argv[])
{
/* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
@@ -956,7 +956,11 @@ int main(int argc, char *argv[])
diag_init_putc(_zylinjtag_diag_write_char);
// We want this in the log.
diag_printf("Zylin ZY1000.\n");
#ifdef CYGPKG_HAL_NIOS2
diag_printf("Zylin ZY1000 PCB revc.\n");
#else
diag_printf("Zylin ZY1000 PCB revb.\n");
#endif
err = mount("", "/ram", "ramfs");
if (err < 0)
@@ -995,6 +999,20 @@ int main(int argc, char *argv[])
copydir("/rom", "/ram/cgi");
#ifdef CYGPKG_HAL_NIOS2
cyg_flashaddr_t err_address;
#define UNCACHED_EXT_FLASH_BASE (0x80000000 + EXT_FLASH_BASE)
/* The revc flash is locked upon reset, unlock it */
#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
if ((err = flash_unlock((void *) UNCACHED_EXT_FLASH_BASE, EXT_FLASH_SPAN,
(void **) &err_address)) != 0)
{
diag_printf("Error: could not unlock flash\n");
}
#endif
#endif
err = mount("/dev/flash1", "/config", "jffs2");
if (err < 0)
{
@@ -1069,34 +1087,24 @@ int main(int argc, char *argv[])
add_default_dirs();
/* initialize commandline interface */
command_context_t * cmd_ctx;
cmd_ctx = setup_command_handler();
struct command_context * cmd_ctx;
struct command_context *setup_command_handler(Jim_Interp *interp);
cmd_ctx = setup_command_handler(httpstate.jim_interp);
command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
command_context_mode(cmd_ctx, COMMAND_CONFIG);
#if BUILD_IOUTIL
if (ioutil_init(cmd_ctx) != ERROR_OK)
{
return EXIT_FAILURE;
}
#endif
#ifdef CYGPKG_PROFILE_GPROF
register_command(cmd_ctx, NULL, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command,
COMMAND_ANY, NULL);
Jim_CreateCommand(httpstate.jim_interp, "zy1000_profile", zylinjtag_Jim_Command_profile,
NULL, NULL);
#endif
register_command(cmd_ctx, NULL, "uart", handle_uart_command, COMMAND_ANY,
"uart <baud> - forward uart on port 5555");
Jim_CreateCommand(httpstate.jim_interp, "zy1000_uart", zylinjtag_Jim_Command_uart, NULL, NULL);
int errVal;
errVal = log_init(cmd_ctx);
if (errVal != ERROR_OK)
{
diag_printf("log_init() failed %d\n", errVal);
exit(-1);
}
log_init();
set_log_output(cmd_ctx, log);
@@ -1113,6 +1121,11 @@ int main(int argc, char *argv[])
command_run_linef(cmd_ctx, "script /rom/openocd.cfg");
int ret;
ret = server_init(cmd_ctx);
if (ERROR_OK != ret)
return EXIT_FAILURE;
/* we MUST always run the init command as it will launch telnet sessions */
command_run_line(cmd_ctx, "init");

View File

@@ -1,70 +1,25 @@
SUBDIRS = \
nor \
nand
AM_CPPFLAGS = \
-I$(top_srcdir)/src/helper \
-I$(top_srcdir)/src/jtag \
-I$(top_srcdir)/src/target
-I$(top_srcdir)/src \
-I$(top_builddir)/src
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 \
at91sam3.c \
davinci_nand.c \
str7x.c \
str9x.c \
aduc702x.c \
nand.c \
nand_ecc.c \
nand_ecc_kw.c \
lpc3180_nand_controller.c \
stellaris.c \
str9xpec.c \
stm32x.c \
tms470.c \
ecos.c \
orion_nand.c \
s3c24xx_nand.c \
s3c2410_nand.c \
s3c2412_nand.c \
s3c2440_nand.c \
s3c2443_nand.c \
ocl.c \
mflash.c \
pic32mx.c \
avrf.c \
faux.c \
mx3_nand.c
common.c \
mflash.c
libflash_la_LIBADD = \
$(top_builddir)/src/flash/nor/libocdflashnor.la \
$(top_builddir)/src/flash/nand/libocdflashnand.la
noinst_HEADERS = \
arm_nandio.h \
flash.h \
lpc2000.h \
lpc288x.h \
lpc2900.h \
cfi.h \
non_cfi.h \
at91sam7.h \
at91sam3.h \
str7x.h \
str9x.h \
nand.h \
lpc3180_nand_controller.h \
stellaris.h \
str9xpec.h \
stm32x.h \
tms470.h \
s3c24xx_nand.h \
s3c24xx_regs_nand.h \
mflash.h \
ocl.h \
pic32mx.h \
avrf.h \
mx3_nand.h
common.h \
mflash.h
EXTRA_DIST = startup.tcl
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in

View File

@@ -1,134 +0,0 @@
/*
* 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(&reg_params[0], "r0", 32, PARAM_IN);
init_reg_param(&reg_params[1], "r1", 32, PARAM_IN);
init_reg_param(&reg_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(&reg_params[0]);
destroy_reg_param(&reg_params[1]);
destroy_reg_param(&reg_params[2]);
return retval;
}
/* REVISIT do the same for bulk *read* too ... */

View File

@@ -1,25 +0,0 @@
#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 */

48
src/flash/common.c Normal file
View File

@@ -0,0 +1,48 @@
/***************************************************************************
* Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
* *
* 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 "common.h"
#include <helper/log.h>
unsigned get_flash_name_index(const char *name)
{
const char *index = strrchr(name, '.');
if (NULL == index)
return 0;
if (index[1] < '0' || index[1] > '9')
return ~0U;
unsigned requested;
int retval = parse_uint(index + 1, &requested);
// detect parsing error by forcing past end of bank list
return (ERROR_OK == retval) ? requested : ~0U;
}
bool flash_driver_name_matches(const char *name, const char *expected)
{
unsigned blen = strlen(name);
// only match up to the length of the driver name...
if (strncmp(name, expected, blen) != 0)
return false;
// ...then check that name terminates at this spot.
return expected[blen] == '.' || expected[blen] == '\0';
}

48
src/flash/common.h Normal file
View File

@@ -0,0 +1,48 @@
/***************************************************************************
* Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
* *
* 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 FLASH_COMMON_H
#define FLASH_COMMON_H
#include <helper/log.h>
/**
* Parses the optional '.index' portion of a flash bank identifier.
* @param name The desired driver name, passed by the user.
* @returns The parsed index request, or 0 if not present. If the
* name provides a suffix but it does not parse as an unsigned integer,
* the routine returns ~0U. This will prevent further matching.
*/
unsigned get_flash_name_index(const char *name);
/**
* Attempt to match the @c expected name with the @c name of a driver.
* @param name The name of the driver (from the bank's device structure).
* @param expected The expected driver name, passed by the user.
*/
bool flash_driver_name_matches(const char *name, const char *expected);
#define ERROR_FLASH_BANK_INVALID -900
#define ERROR_FLASH_SECTOR_INVALID -901
#define ERROR_FLASH_OPERATION_FAILED -902
#define ERROR_FLASH_DST_OUT_OF_BANK -903
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT -904
#define ERROR_FLASH_BUSY -905
#define ERROR_FLASH_SECTOR_NOT_ERASED -906
#define ERROR_FLASH_BANK_NOT_PROBED -907
#endif // FLASH_COMMON_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,339 +0,0 @@
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
* 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 FLASH_H
#define FLASH_H
#include "target.h"
#include "log.h"
struct image_s;
#define FLASH_MAX_ERROR_STR (128)
/**
* Describes the geometry and status of a single flash sector
* within a flash bank. A single bank typically consists of multiple
* sectors, each of which can be erased and protected independently.
*/
typedef struct flash_sector_s
{
/// Bus offset from start of the flash chip (in bytes).
uint32_t offset;
/// Number of bytes in this flash sector.
uint32_t size;
/**
* Indication of erasure status: 0 = not erased, 1 = erased,
* other = unknown. Set by @c flash_driver_s::erase_check.
*/
int is_erased;
/**
* Indication of protection status: 0 = unprotected/unlocked,
* 1 = protected/locked, other = unknown. Set by
* @c flash_driver_s::protect_check.
*/
int is_protected;
} flash_sector_t;
struct flash_bank_s;
/**
* @brief Provides the implementation-independent structure that defines
* all of the callbacks required by OpenOCD flash drivers.
*
* Driver authors must implement the routines defined here, providing an
* instance with the fields filled out. After that, the instance must
* be registered in flash.c, so it can be used by the driver lookup system.
*
* Specifically, the user can issue the command: @par
* @code
* flash bank DRIVERNAME ...parameters...
* @endcode
*
* OpenOCD will search for the driver with a @c flash_driver_s::name
* that matches @c DRIVERNAME.
*
* The flash subsystem calls some of the other drivers routines a using
* corresponding static <code>flash_driver_<i>callback</i>()</code>
* routine in flash.c.
*/
typedef struct flash_driver_s
{
/**
* Gives a human-readable name of this flash driver,
* This field is used to select and initialize the driver.
*/
char *name;
/**
* Registers driver-specific commands. When called (during the
* "flash bank" command), the driver may register addition
* commands to support new flash chip functions.
*
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*register_commands)(struct command_context_s *cmd_ctx);
/**
* Finish the "flash bank" command for @a bank. The
* @a bank parameter will have been filled in by the core flash
* layer when this routine is called, and the driver can store
* additional information in its flash_bank_t::driver_priv field.
*
* @param cmd_ctx - the command context
* @param cmd - the command, in this case 'flash'
* @param args - parameters, see below
* @param argc - number of parameters on command line
* @param bank - new filled in flash bank.
*
* The args are: @par
* @code
* args[0] = bank
* args[1] = drivername {name above}
* args[2] = baseaddress
* args[3] = lengthbytes
* args[4] = chip_width_in bytes
* args[5] = bus_width_bytes
* args[6] = driver-specific parameters
* @endcode
*
* For example, args[4] = 16 bit flash, args[5] = 32bit bus.
*
* If extra arguments are provided (@a argc > 6), they will
* start in @a args[6]. These can be used to implement
* driver-specific extensions.
*
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*flash_bank_command)(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
/**
* Bank/sector erase routine (target-specific). When
* called, the flash driver should erase the specified sectors
* using whatever means are at its disposal.
*
* @param bank The bank of flash to be erased.
* @param first The number of the first sector to erase, typically 0.
* @param last The number of the last sector to erase, typically N-1.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*erase)(struct flash_bank_s *bank, int first, int last);
/**
* Bank/sector protection routine (target-specific).
* When called, the driver should disable 'flash write' bits (or
* enable 'erase protection' bits) for the given @a bank and @a
* sectors.
*
* @param bank The bank to protect or unprotect.
* @param set If non-zero, enable protection; if 0, disable it.
* @param first The first sector to (un)protect, typicaly 0.
* @param last The last sector to (un)project, typically N-1.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*protect)(struct flash_bank_s *bank, int set, int first, int last);
/**
* Program data into the flash. Note CPU address will be
* "bank->base + offset", while the physical address is
* dependent upon current target MMU mappings.
*
* @param bank The bank to program
* @param buffer The data bytes to write.
* @param offset The offset into the chip to program.
* @param count The number of bytes to write.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*write)(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
/**
* Probe to determine what kind of flash is present.
* This is invoked by the "probe" script command.
*
* @param bank The bank to probe
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*probe)(struct flash_bank_s *bank);
/**
* Check the erasure status of a flash bank.
* When called, the driver routine must perform the required
* checks and then set the @c flash_sector_s::is_erased field
* for each of the flash banks's sectors.
*
* @param bank The bank to check
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*erase_check)(struct flash_bank_s *bank);
/**
* Determine if the specific bank is "protected" or not.
* When called, the driver routine must must perform the
* required protection check(s) and then set the @c
* flash_sector_s::is_protected field for each of the flash
* bank's sectors.
*
* @param bank - the bank to check
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*protect_check)(struct flash_bank_s *bank);
/**
* Display human-readable information about the flash
* bank into the given buffer. Drivers must be careful to avoid
* overflowing the buffer.
*
* @param bank - the bank to get info about
* @param char - where to put the text for the human to read
* @param buf_size - the size of the human buffer.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*info)(struct flash_bank_s *bank, char *buf, int buf_size);
/**
* A more gentle flavor of filash_driver_s::probe, performing
* setup with less noise. Generally, driver routines should test
* to seee if the bank has already been probed; if it has, the
* driver probably should not perform its probe a second time.
*
* This callback is often called from the inside of other
* routines (e.g. GDB flash downloads) to autoprobe the flash as
* it is programing the flash.
*
* @param bank - the bank to probe
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*auto_probe)(struct flash_bank_s *bank);
} flash_driver_t;
/**
* Provides details of a flash bank, available either on-chip or through
* a major interface.
*
* This structure will be passed as a parameter to the callbacks in the
* flash_driver_s structure, some of which may modify the contents of
* this structure of the area of flash that it defines. Driver writers
* may use the @c driver_priv member to store additional data on a
* per-bank basis, if required.
*/
typedef struct flash_bank_s
{
struct target_s *target; /**< Target to which this bank belongs. */
flash_driver_t *driver; /**< Driver for this bank. */
void *driver_priv; /**< Private driver storage pointer */
int bank_number; /**< The 'bank' (or chip number) of this instance. */
uint32_t base; /**< The base address of this bank */
uint32_t size; /**< The size of this chip bank, in bytes */
int chip_width; /**< Width of the chip in bytes (1,2,4 bytes) */
int bus_width; /**< Maximum bus width, in bytes (1,2,4 bytes) */
/**
* The number of sectors on this chip. This value will
* be set intially to 0, and the flash driver must set this to
* some non-zero value during "probe()" or "auto_probe()".
*/
int num_sectors;
/// Array of sectors, allocated and initilized by the flash driver
flash_sector_t *sectors;
struct flash_bank_s *next; /**< The next flash bank on this chip */
} flash_bank_t;
/// Registers the 'flash' subsystem commands
extern int flash_register_commands(struct command_context_s *cmd_ctx);
/// Initializes the 'flash' subsystem drivers
extern int flash_init_drivers(struct command_context_s *cmd_ctx);
/**
* Erases @a length bytes in the @a target flash, starting at @a addr.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
extern int flash_erase_address_range(struct target_s *target, uint32_t addr, uint32_t length);
/**
* Writes @a image into the @a target flash. The @a written parameter
* will contain the
* @param target The target with the flash to be programmed.
* @param image The image that will be programmed to flash.
* @param written On return, contains the number of bytes written.
* @param erase If non-zero, indicates the flash driver should first
* erase the corresponding banks or sectors before programming.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
extern int flash_write(struct target_s *target, struct image_s *image, uint32_t *written, int erase);
/**
* Forces targets to re-examine their erase/protection state.
* This routine must be called when the system may modify the status.
*/
extern void flash_set_dirty(void);
/// @returns The number of flash banks currently defined.
extern int flash_get_bank_count(void);
/**
* Provides default erased-bank check handling. Checks to see if
* the flash driver knows they are erased; if things look uncertain,
* this routine will call default_flash_mem_blank_check() to confirm.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
extern int default_flash_blank_check(struct flash_bank_s *bank);
/**
* Provides a default blank flash memory check. Ensures the contents
* of the given bank have truly been erased.
* @param bank The flash bank.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
extern int default_flash_mem_blank_check(struct flash_bank_s *bank);
/**
* Returns a flash bank by the specified flash_bank_s bank_number, @a num.
* @param num The flash bank number.
* @returns A flash_bank_t for flash bank @a num, or NULL
*/
extern flash_bank_t *get_flash_bank_by_num(int num);
/**
* Returns the flash bank like get_flash_bank_by_num(), without probing.
* @param num The flash bank number.
* @returns A flash_bank_t for flash bank @a num, or NULL.
*/
extern flash_bank_t *get_flash_bank_by_num_noprobe(int num);
/**
* Returns the flash bank located at a specified address.
* @param target The target, presumed to contain one or more banks.
* @param addr An address that is within the range of the bank.
* @returns The flash_bank_t located at @a addr, or NULL.
*/
extern flash_bank_t *get_flash_bank_by_addr(struct target_s *target, uint32_t addr);
#define ERROR_FLASH_BANK_INVALID (-900)
#define ERROR_FLASH_SECTOR_INVALID (-901)
#define ERROR_FLASH_OPERATION_FAILED (-902)
#define ERROR_FLASH_DST_OUT_OF_BANK (-903)
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT (-904)
#define ERROR_FLASH_BUSY (-905)
#define ERROR_FLASH_SECTOR_NOT_ERASED (-906)
#define ERROR_FLASH_BANK_NOT_PROBED (-907)
#endif /* FLASH_H */

View File

@@ -22,33 +22,32 @@
#endif
#include "mflash.h"
#include "time_support.h"
#include "fileio.h"
#include "log.h"
#include <target/target.h>
#include <helper/time_support.h>
#include <helper/fileio.h>
#include <helper/log.h>
static int s3c2440_set_gpio_to_output (mflash_gpio_num_t gpio);
static int s3c2440_set_gpio_output_val (mflash_gpio_num_t gpio, uint8_t val);
static int pxa270_set_gpio_to_output (mflash_gpio_num_t gpio);
static int pxa270_set_gpio_output_val (mflash_gpio_num_t gpio, uint8_t val);
static int s3c2440_set_gpio_to_output (struct mflash_gpio_num gpio);
static int s3c2440_set_gpio_output_val (struct mflash_gpio_num gpio, uint8_t val);
static int pxa270_set_gpio_to_output (struct mflash_gpio_num gpio);
static int pxa270_set_gpio_output_val (struct mflash_gpio_num gpio, uint8_t val);
static command_t *mflash_cmd;
static struct mflash_bank *mflash_bank;
static mflash_bank_t *mflash_bank;
static mflash_gpio_drv_t pxa270_gpio = {
static struct mflash_gpio_drv pxa270_gpio = {
.name = "pxa270",
.set_gpio_to_output = pxa270_set_gpio_to_output,
.set_gpio_output_val = pxa270_set_gpio_output_val
};
static mflash_gpio_drv_t s3c2440_gpio = {
static struct mflash_gpio_drv s3c2440_gpio = {
.name = "s3c2440",
.set_gpio_to_output = s3c2440_set_gpio_to_output,
.set_gpio_output_val = s3c2440_set_gpio_output_val
};
static mflash_gpio_drv_t *mflash_gpio[] =
static struct mflash_gpio_drv *mflash_gpio[] =
{
&pxa270_gpio,
&s3c2440_gpio,
@@ -64,10 +63,10 @@ static mflash_gpio_drv_t *mflash_gpio[] =
#define PXA270_GPSR0 0x40E00018
#define PXA270_GPCR0 0x40E00024
static int pxa270_set_gpio_to_output (mflash_gpio_num_t gpio)
static int pxa270_set_gpio_to_output (struct mflash_gpio_num gpio)
{
uint32_t addr, value, mask;
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
int ret;
/* remove alternate function. */
@@ -101,10 +100,10 @@ static int pxa270_set_gpio_to_output (mflash_gpio_num_t gpio)
return ret;
}
static int pxa270_set_gpio_output_val (mflash_gpio_num_t gpio, uint8_t val)
static int pxa270_set_gpio_output_val (struct mflash_gpio_num gpio, uint8_t val)
{
uint32_t addr, value, mask;
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
int ret;
mask = 0x1u << (gpio.num & 0x1F);
@@ -130,10 +129,10 @@ static int pxa270_set_gpio_output_val (mflash_gpio_num_t gpio, uint8_t val)
#define S3C2440_GPJCON 0x560000d0
#define S3C2440_GPJDAT 0x560000d4
static int s3c2440_set_gpio_to_output (mflash_gpio_num_t gpio)
static int s3c2440_set_gpio_to_output (struct mflash_gpio_num gpio)
{
uint32_t data, mask, gpio_con;
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
int ret;
if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h') {
@@ -162,10 +161,10 @@ static int s3c2440_set_gpio_to_output (mflash_gpio_num_t gpio)
return ret;
}
static int s3c2440_set_gpio_output_val (mflash_gpio_num_t gpio, uint8_t val)
static int s3c2440_set_gpio_output_val (struct mflash_gpio_num gpio, uint8_t val)
{
uint32_t data, mask, gpio_dat;
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
int ret;
if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h') {
@@ -199,7 +198,7 @@ static int mg_hdrst(uint8_t level)
static int mg_init_gpio (void)
{
int ret;
mflash_gpio_drv_t *gpio_drv = mflash_bank->gpio_drv;
struct mflash_gpio_drv *gpio_drv = mflash_bank->gpio_drv;
ret = gpio_drv->set_gpio_to_output(mflash_bank->rst_pin);
if (ret != ERROR_OK)
@@ -213,13 +212,13 @@ static int mg_init_gpio (void)
static int mg_dsk_wait(mg_io_type_wait wait, uint32_t time)
{
uint8_t status, error;
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
duration_t duration;
int ret;
long long t = 0;
duration_start_measure(&duration);
struct duration bench;
duration_start(&bench);
while (time) {
@@ -275,10 +274,11 @@ static int mg_dsk_wait(mg_io_type_wait wait, uint32_t time)
}
}
duration_stop_measure(&duration, NULL);
t = duration.duration.tv_usec/1000;
t += duration.duration.tv_sec*1000;
ret = duration_measure(&bench);
if (ERROR_OK == ret)
t = duration_elapsed(&bench) * 1000.0;
else
LOG_ERROR("mflash: duration measurement failed: %d", ret);
if (t > time)
break;
@@ -290,7 +290,7 @@ static int mg_dsk_wait(mg_io_type_wait wait, uint32_t time)
static int mg_dsk_srst(uint8_t on)
{
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
uint8_t value;
int ret;
@@ -310,7 +310,7 @@ static int mg_dsk_srst(uint8_t on)
static int mg_dsk_io_cmd(uint32_t sect_num, uint32_t cnt, uint8_t cmd)
{
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
uint8_t value;
int ret;
@@ -335,22 +335,24 @@ static int mg_dsk_io_cmd(uint32_t sect_num, uint32_t cnt, uint8_t cmd)
static int mg_dsk_drv_info(void)
{
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
uint32_t mg_buff = mflash_bank->base + MG_BUFFER_OFFSET;
int ret;
if ((ret = mg_dsk_io_cmd(0, 1, mg_io_cmd_identify)) != ERROR_OK)
return ret;
if ((ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL)) != ERROR_OK)
ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
if (ret != ERROR_OK)
return ret;
LOG_INFO("mflash: read drive info");
if (! mflash_bank->drv_info)
mflash_bank->drv_info = malloc(sizeof(mg_drv_info_t));
mflash_bank->drv_info = malloc(sizeof(struct mg_drv_info));
target_read_memory(target, mg_buff, 2, sizeof(mg_io_type_drv_info) >> 1,
ret = target_read_memory(target, mg_buff, 2,
sizeof(mg_io_type_drv_info) >> 1,
(uint8_t *)&mflash_bank->drv_info->drv_id);
if (ret != ERROR_OK)
return ret;
@@ -407,14 +409,14 @@ static int mg_mflash_probe(void)
return mg_dsk_drv_info();
}
static int mg_probe_cmd(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(mg_probe_cmd)
{
int ret;
ret = mg_mflash_probe();
if (ret == ERROR_OK) {
command_print(cmd_ctx, "mflash (total %" PRIu32 " sectors) found at 0x%8.8" PRIx32 "",
command_print(CMD_CTX, "mflash (total %" PRIu32 " sectors) found at 0x%8.8" PRIx32 "",
mflash_bank->drv_info->tot_sects, mflash_bank->base);
}
@@ -425,16 +427,16 @@ static int mg_mflash_do_read_sects(void *buff, uint32_t sect_num, uint32_t sect_
{
uint32_t i, address;
int ret;
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
uint8_t *buff_ptr = buff;
duration_t duration;
if ((ret = mg_dsk_io_cmd(sect_num, sect_cnt, mg_io_cmd_read)) != ERROR_OK)
return ret;
address = mflash_bank->base + MG_BUFFER_OFFSET;
duration_start_measure(&duration);
struct duration bench;
duration_start(&bench);
for (i = 0; i < sect_cnt; i++) {
ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
@@ -453,11 +455,10 @@ static int mg_mflash_do_read_sects(void *buff, uint32_t sect_num, uint32_t sect_
LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector read", sect_num + i, (sect_num + i) * MG_MFLASH_SECTOR_SIZE);
duration_stop_measure(&duration, NULL);
if ((duration.duration.tv_sec * 1000 + duration.duration.tv_usec / 1000) > 3000) {
ret = duration_measure(&bench);
if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) {
LOG_INFO("mflash: read %" PRIu32 "'th sectors", sect_num + i);
duration_start_measure(&duration);
duration_start(&bench);
}
}
@@ -498,16 +499,16 @@ static int mg_mflash_do_write_sects(void *buff, uint32_t sect_num, uint32_t sect
{
uint32_t i, address;
int ret;
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
uint8_t *buff_ptr = buff;
duration_t duration;
if ((ret = mg_dsk_io_cmd(sect_num, sect_cnt, cmd)) != ERROR_OK)
return ret;
address = mflash_bank->base + MG_BUFFER_OFFSET;
duration_start_measure(&duration);
struct duration bench;
duration_start(&bench);
for (i = 0; i < sect_cnt; i++) {
ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
@@ -526,11 +527,10 @@ static int mg_mflash_do_write_sects(void *buff, uint32_t sect_num, uint32_t sect
LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector write", sect_num + i, (sect_num + i) * MG_MFLASH_SECTOR_SIZE);
duration_stop_measure(&duration, NULL);
if ((duration.duration.tv_sec * 1000 + duration.duration.tv_usec / 1000) > 3000) {
ret = duration_measure(&bench);
if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) {
LOG_INFO("mflash: wrote %" PRIu32 "'th sectors", sect_num + i);
duration_start_measure(&duration);
duration_start(&bench);
}
}
@@ -703,22 +703,20 @@ static int mg_mflash_write(uint32_t addr, uint8_t *buff, uint32_t len)
return ret;
}
static int mg_write_cmd(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(mg_write_cmd)
{
uint32_t address, buf_cnt, cnt, res, i;
uint32_t address, cnt, res, i;
uint8_t *buffer;
fileio_t fileio;
duration_t duration;
char *duration_text;
struct fileio fileio;
int ret;
if (argc != 3) {
if (CMD_ARGC != 3) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
address = strtoul(args[2], NULL, 0);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
ret = fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY);
ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);
if (ret != ERROR_OK)
return ret;
@@ -731,8 +729,10 @@ static int mg_write_cmd(struct command_context_s *cmd_ctx, char *cmd, char **arg
cnt = fileio.size / MG_FILEIO_CHUNK;
res = fileio.size % MG_FILEIO_CHUNK;
duration_start_measure(&duration);
struct duration bench;
duration_start(&bench);
size_t buf_cnt;
for (i = 0; i < cnt; i++) {
if ((ret = fileio_read(&fileio, MG_FILEIO_CHUNK, buffer, &buf_cnt)) !=
ERROR_OK)
@@ -749,44 +749,40 @@ static int mg_write_cmd(struct command_context_s *cmd_ctx, char *cmd, char **arg
goto mg_write_cmd_err;
}
duration_stop_measure(&duration, &duration_text);
if (duration_measure(&bench) == ERROR_OK)
{
command_print(CMD_CTX, "wrote %ld bytes from file %s "
"in %fs (%0.3f kB/s)", (long)fileio.size, CMD_ARGV[1],
duration_elapsed(&bench), duration_kbps(&bench, fileio.size));
}
command_print(cmd_ctx, "wrote %lli byte from file %s in %s (%f kB/s)",
fileio.size, args[1], duration_text,
(float)fileio.size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
free(duration_text);
free(buffer);
fileio_close(&fileio);
return ERROR_OK;
mg_write_cmd_err:
duration_stop_measure(&duration, &duration_text);
free(duration_text);
free(buffer);
free(buffer);
fileio_close(&fileio);
return ret;
}
static int mg_dump_cmd(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(mg_dump_cmd)
{
uint32_t address, size_written, size, cnt, res, i;
uint32_t address, size, cnt, res, i;
uint8_t *buffer;
fileio_t fileio;
duration_t duration;
char *duration_text;
struct fileio fileio;
int ret;
if (argc != 4) {
if (CMD_ARGC != 4) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
address = strtoul(args[2], NULL, 0);
size = strtoul(args[3], NULL, 0);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], size);
ret = fileio_open(&fileio, args[1], FILEIO_WRITE, FILEIO_BINARY);
ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY);
if (ret != ERROR_OK)
return ret;
@@ -799,8 +795,10 @@ static int mg_dump_cmd(struct command_context_s *cmd_ctx, char *cmd, char **args
cnt = size / MG_FILEIO_CHUNK;
res = size % MG_FILEIO_CHUNK;
duration_start_measure(&duration);
struct duration bench;
duration_start(&bench);
size_t size_written;
for (i = 0; i < cnt; i++) {
if ((ret = mg_mflash_read(address, buffer, MG_FILEIO_CHUNK)) != ERROR_OK)
goto mg_dump_cmd_err;
@@ -817,22 +815,21 @@ static int mg_dump_cmd(struct command_context_s *cmd_ctx, char *cmd, char **args
goto mg_dump_cmd_err;
}
duration_stop_measure(&duration, &duration_text);
if (duration_measure(&bench) == ERROR_OK)
{
command_print(CMD_CTX, "dump image (address 0x%8.8" PRIx32 " "
"size %" PRIu32 ") to file %s in %fs (%0.3f kB/s)",
address, size, CMD_ARGV[1],
duration_elapsed(&bench), duration_kbps(&bench, size));
}
command_print(cmd_ctx, "dump image (address 0x%8.8" PRIx32 " size %" PRIu32 ") to file %s in %s (%f kB/s)",
address, size, args[1], duration_text,
(float)size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
free(duration_text);
free(buffer);
fileio_close(&fileio);
return ERROR_OK;
mg_dump_cmd_err:
duration_stop_measure(&duration, &duration_text);
free(duration_text);
free(buffer);
free(buffer);
fileio_close(&fileio);
return ret;
@@ -840,7 +837,7 @@ mg_dump_cmd_err:
static int mg_set_feature(mg_feature_id feature, mg_feature_val config)
{
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
int ret;
@@ -959,7 +956,7 @@ static int mg_verify_interface(void)
uint16_t buff[MG_MFLASH_SECTOR_SIZE >> 1];
uint16_t i, j;
uint32_t address = mflash_bank->base + MG_BUFFER_OFFSET;
target_t *target = mflash_bank->target;
struct target *target = mflash_bank->target;
int ret;
for (j = 0; j < 10; j++) {
@@ -1214,8 +1211,7 @@ static int mg_erase_nand(void)
return ret;
}
int mg_config_cmd(struct command_context_s *cmd_ctx, char *cmd,
char **args, int argc)
COMMAND_HANDLER(mg_config_cmd)
{
double fin, fout;
mg_pll_t pll;
@@ -1227,18 +1223,20 @@ int mg_config_cmd(struct command_context_s *cmd_ctx, char *cmd,
if ((ret = mg_mflash_rst()) != ERROR_OK)
return ret;
switch (argc) {
switch (CMD_ARGC) {
case 2:
if (!strcmp(args[1], "boot"))
if (!strcmp(CMD_ARGV[1], "boot"))
return mg_boot_config();
else if (!strcmp(args[1], "storage"))
else if (!strcmp(CMD_ARGV[1], "storage"))
return mg_storage_config();
else
return ERROR_COMMAND_NOTFOUND;
break;
case 3:
if (!strcmp(args[1], "pll")) {
fin = strtoul(args[2], NULL, 0);
if (!strcmp(CMD_ARGV[1], "pll")) {
unsigned long freq;
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], freq);
fin = freq;
if (fin > MG_PLL_CLK_OUT) {
LOG_ERROR("mflash: input freq. is too large");
@@ -1270,64 +1268,131 @@ int mg_config_cmd(struct command_context_s *cmd_ctx, char *cmd,
}
}
int mflash_init_drivers(struct command_context_s *cmd_ctx)
{
if (mflash_bank) {
register_command(cmd_ctx, mflash_cmd, "probe", mg_probe_cmd, COMMAND_EXEC, NULL);
register_command(cmd_ctx, mflash_cmd, "write", mg_write_cmd, COMMAND_EXEC,
"mflash write <num> <file> <address>");
register_command(cmd_ctx, mflash_cmd, "dump", mg_dump_cmd, COMMAND_EXEC,
"mflash dump <num> <file> <address> <size>");
register_command(cmd_ctx, mflash_cmd, "config", mg_config_cmd,
COMMAND_EXEC, "mflash config <num> <stage>");
}
static const struct command_registration mflash_exec_command_handlers[] = {
{
.name = "probe",
.handler = mg_probe_cmd,
.mode = COMMAND_EXEC,
.help = "Detect bank configuration information",
},
{
.name = "write",
.handler = mg_write_cmd,
.mode = COMMAND_EXEC,
/* FIXME bank_num is unused */
.usage = "bank_num filename address",
.help = "Write binary file at the specified address.",
},
{
.name = "dump",
.handler = mg_dump_cmd,
.mode = COMMAND_EXEC,
/* FIXME bank_num is unused */
.usage = "bank_num filename address size",
.help = "Write specified number of bytes from a binary file "
"to the specified, address.",
},
{
.name = "config",
.handler = mg_config_cmd,
.mode = COMMAND_EXEC,
.help = "Configure MFLASH options.",
.usage = "('boot'|'storage'|'pll' frequency)",
},
COMMAND_REGISTRATION_DONE
};
return ERROR_OK;
int mflash_init_drivers(struct command_context *cmd_ctx)
{
if (!mflash_bank)
return ERROR_OK;
return register_commands(cmd_ctx, NULL, mflash_exec_command_handlers);
}
static int mg_bank_cmd(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(handle_mflash_init_command)
{
target_t *target;
char *str;
if (CMD_ARGC != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
static bool mflash_initialized = false;
if (mflash_initialized)
{
LOG_INFO("'mflash init' has already been called");
return ERROR_OK;
}
mflash_initialized = true;
LOG_DEBUG("Initializing mflash devices...");
return mflash_init_drivers(CMD_CTX);
}
COMMAND_HANDLER(mg_bank_cmd)
{
struct target *target;
int i;
if (argc < 4)
if (CMD_ARGC < 4)
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
if ((target = get_target(args[3])) == NULL)
if ((target = get_target(CMD_ARGV[3])) == NULL)
{
LOG_ERROR("target '%s' not defined", args[3]);
LOG_ERROR("target '%s' not defined", CMD_ARGV[3]);
return ERROR_FAIL;
}
mflash_bank = calloc(sizeof(mflash_bank_t), 1);
mflash_bank->base = strtoul(args[1], NULL, 0);
mflash_bank->rst_pin.num = strtoul(args[2], &str, 0);
mflash_bank = calloc(sizeof(struct mflash_bank), 1);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], mflash_bank->base);
/// @todo Verify how this parsing should work, then document it.
char *str;
mflash_bank->rst_pin.num = strtoul(CMD_ARGV[2], &str, 0);
if (*str)
mflash_bank->rst_pin.port[0] = (uint16_t)tolower(str[0]);
mflash_bank->rst_pin.port[0] = (uint16_t)
tolower((unsigned)str[0]);
mflash_bank->target = target;
for (i = 0; mflash_gpio[i] ; i++) {
if (! strcmp(mflash_gpio[i]->name, args[0])) {
if (! strcmp(mflash_gpio[i]->name, CMD_ARGV[0])) {
mflash_bank->gpio_drv = mflash_gpio[i];
}
}
if (! mflash_bank->gpio_drv) {
LOG_ERROR("%s is unsupported soc", args[0]);
LOG_ERROR("%s is unsupported soc", CMD_ARGV[0]);
return ERROR_MG_UNSUPPORTED_SOC;
}
return ERROR_OK;
}
int mflash_register_commands(struct command_context_s *cmd_ctx)
static const struct command_registration mflash_config_command_handlers[] = {
{
.name = "bank",
.handler = mg_bank_cmd,
.mode = COMMAND_CONFIG,
.help = "configure a mflash device bank",
.usage = "soc_type base_addr pin_id target",
},
{
.name = "init",
.mode = COMMAND_CONFIG,
.handler = handle_mflash_init_command,
.help = "initialize mflash devices",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration mflash_command_handler[] = {
{
.name = "mflash",
.mode = COMMAND_ANY,
.help = "mflash command group",
.chain = mflash_config_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
int mflash_register_commands(struct command_context *cmd_ctx)
{
mflash_cmd = register_command(cmd_ctx, NULL, "mflash", NULL, COMMAND_ANY, NULL);
register_command(cmd_ctx, mflash_cmd, "bank", mg_bank_cmd, COMMAND_CONFIG,
"mflash bank <soc> <base> <RST pin> <target #>");
return ERROR_OK;
return register_commands(cmd_ctx, NULL, mflash_command_handler);
}

View File

@@ -20,24 +20,24 @@
#ifndef _MFLASH_H
#define _MFLASH_H
#include "target.h"
struct command_context;
typedef unsigned long mg_io_uint32;
typedef unsigned short mg_io_uint16;
typedef unsigned char mg_io_uint8;
typedef struct mflash_gpio_num_s
struct mflash_gpio_num
{
char port[2];
signed short num;
} mflash_gpio_num_t;
};
typedef struct mflash_gpio_drv_s
struct mflash_gpio_drv
{
char *name;
int (*set_gpio_to_output) (mflash_gpio_num_t gpio);
int (*set_gpio_output_val) (mflash_gpio_num_t gpio, uint8_t val);
} mflash_gpio_drv_t;
int (*set_gpio_to_output) (struct mflash_gpio_num gpio);
int (*set_gpio_output_val) (struct mflash_gpio_num gpio, uint8_t val);
};
typedef struct _mg_io_type_drv_info {
@@ -125,24 +125,24 @@ typedef struct _mg_pll_t
unsigned char output_div; /* 2bit divider */
} mg_pll_t;
typedef struct mg_drv_info_s {
struct mg_drv_info {
mg_io_type_drv_info drv_id;
uint32_t tot_sects;
} mg_drv_info_t;
};
typedef struct mflash_bank_s
struct mflash_bank
{
uint32_t base;
mflash_gpio_num_t rst_pin;
struct mflash_gpio_num rst_pin;
mflash_gpio_drv_t *gpio_drv;
target_t *target;
mg_drv_info_t *drv_info;
} mflash_bank_t;
struct mflash_gpio_drv *gpio_drv;
struct target *target;
struct mg_drv_info *drv_info;
};
extern int mflash_register_commands(struct command_context_s *cmd_ctx);
extern int mflash_init_drivers(struct command_context_s *cmd_ctx);
int mflash_register_commands(struct command_context *cmd_ctx);
int mflash_init_drivers(struct command_context *cmd_ctx);
#define MG_MFLASH_SECTOR_SIZE (0x200) /* 512Bytes = 2^9 */
#define MG_MFLASH_SECTOR_SIZE_MASK (0x200-1)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src \
-I$(top_builddir)/src
noinst_LTLIBRARIES = libocdflashnand.la
libocdflashnand_la_SOURCES = \
ecc.c \
ecc_kw.c \
core.c \
fileio.c \
tcl.c \
arm_io.c \
$(NAND_DRIVERS) \
driver.c
NAND_DRIVERS = \
nonce.c \
davinci.c \
lpc3180.c \
mx3.c \
orion.c \
s3c24xx.c \
s3c2410.c \
s3c2412.c \
s3c2440.c \
s3c2443.c \
s3c6400.c \
at91sam9.c
noinst_HEADERS = \
arm_io.h \
core.h \
driver.h \
fileio.h \
imp.h \
lpc3180.h \
mx3.h \
s3c24xx.h \
s3c24xx_regs.h
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in

249
src/flash/nand/arm_io.c Normal file
View File

@@ -0,0 +1,249 @@
/*
* 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 "core.h"
#include "arm_io.h"
#include <helper/binarybuffer.h>
#include <target/arm.h>
#include <target/algorithm.h>
/**
* Copies code to a working area. This will allocate room for the code plus the
* additional amount requested if the working area pointer is null.
*
* @param target Pointer to the target to copy code to
* @param code Pointer to the code area to be copied
* @param code_size Size of the code being copied
* @param additional Size of the additional area to be allocated in addition to
* code
* @param area Pointer to a pointer to a working area to copy code to
* @return Success or failure of the operation
*/
int arm_code_to_working_area(struct target *target,
const uint32_t *code, unsigned code_size,
unsigned additional, struct working_area **area)
{
uint8_t code_buf[code_size];
unsigned i;
int retval;
unsigned size = code_size + additional;
/* REVISIT this assumes size doesn't ever change.
* That's usually correct; but there are boards with
* both large and small page chips, where it won't be...
*/
/* make sure we have a working area */
if (NULL == *area) {
retval = target_alloc_working_area(target, size, area);
if (retval != ERROR_OK) {
LOG_DEBUG("%s: no %d byte buffer", __FUNCTION__, (int) size);
return ERROR_NAND_NO_BUFFER;
}
}
/* buffer code in target endianness */
for (i = 0; i < code_size / 4; i++)
target_buffer_set_u32(target, code_buf + i * 4, code[i]);
/* copy code to work area */
retval = target_write_memory(target, (*area)->address,
4, code_size / 4, code_buf);
return retval;
}
/**
* 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)
*
* @param nand Pointer to the arm_nand_data struct that defines the I/O
* @param data Pointer to the data to be copied to flash
* @param size Size of the data being copied
* @return Success or failure of the operation
*/
int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size)
{
struct target *target = nand->target;
struct arm_algorithm algo;
struct arm *armv4_5 = target->arch_info;
struct reg_param 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->op != ARM_NAND_WRITE || !nand->copy_area) {
retval = arm_code_to_working_area(target, code, sizeof(code),
nand->chunk_size, &nand->copy_area);
if (retval != ERROR_OK) {
return retval;
}
}
nand->op = ARM_NAND_WRITE;
/* 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 = ARM_COMMON_MAGIC;
algo.core_mode = ARM_MODE_SVC;
algo.core_state = ARM_STATE_ARM;
init_reg_param(&reg_params[0], "r0", 32, PARAM_IN);
init_reg_param(&reg_params[1], "r1", 32, PARAM_IN);
init_reg_param(&reg_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(&reg_params[0]);
destroy_reg_param(&reg_params[1]);
destroy_reg_param(&reg_params[2]);
return retval;
}
/**
* Uses an on-chip algorithm for an ARM device to read from a NAND device and
* store the data into the host machine's memory.
*
* @param nand Pointer to the arm_nand_data struct that defines the I/O
* @param data Pointer to the data buffer to store the read data
* @param size Amount of data to be stored to the buffer.
* @return Success or failure of the operation
*/
int arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size)
{
struct target *target = nand->target;
struct arm_algorithm algo;
struct arm *armv4_5 = target->arch_info;
struct reg_param reg_params[3];
uint32_t target_buf;
uint32_t exit = 0;
int retval;
/* Inputs:
* r0 buffer address
* r1 NAND data address (byte wide)
* r2 buffer length
*/
static const uint32_t code[] = {
0xe5d13000, /* s: ldrb r3, [r1] */
0xe4c03001, /* strb r3, [r0], #1 */
0xe2522001, /* subs r2, r2, #1 */
0x1afffffb, /* bne s */
/* exit: ARMv4 needs hardware breakpoint */
0xe1200070, /* e: bkpt #0 */
};
/* create the copy area if not yet available */
if (nand->op != ARM_NAND_READ || !nand->copy_area) {
retval = arm_code_to_working_area(target, code, sizeof(code),
nand->chunk_size, &nand->copy_area);
if (retval != ERROR_OK) {
return retval;
}
}
nand->op = ARM_NAND_READ;
target_buf = nand->copy_area->address + sizeof(code);
/* set up algorithm and parameters */
algo.common_magic = ARM_COMMON_MAGIC;
algo.core_mode = ARM_MODE_SVC;
algo.core_state = ARM_STATE_ARM;
init_reg_param(&reg_params[0], "r0", 32, PARAM_IN);
init_reg_param(&reg_params[1], "r1", 32, PARAM_IN);
init_reg_param(&reg_params[2], "r2", 32, PARAM_IN);
buf_set_u32(reg_params[0].value, 0, 32, target_buf);
buf_set_u32(reg_params[1].value, 0, 32, nand->data);
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 NAND chip to work area */
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 read");
destroy_reg_param(&reg_params[0]);
destroy_reg_param(&reg_params[1]);
destroy_reg_param(&reg_params[2]);
/* read from work area to the host's memory */
retval = target_read_buffer(target, target_buf, size, data);
return retval;
}

57
src/flash/nand/arm_io.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* 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.
*/
#ifndef __ARM_NANDIO_H
#define __ARM_NANDIO_H
/**
* Available operational states the arm_nand_data struct can be in.
*/
enum arm_nand_op {
ARM_NAND_NONE, /**< No operation performed. */
ARM_NAND_READ, /**< Read operation performed. */
ARM_NAND_WRITE, /**< Write operation performed. */
};
/**
* The arm_nand_data struct is used for defining NAND I/O operations on an ARM
* core.
*/
struct arm_nand_data {
/** Target is proxy for some ARM core. */
struct target *target;
/** The copy area holds code loop and data for I/O operations. */
struct working_area *copy_area;
/** The chunk size is the page size or ECC chunk. */
unsigned chunk_size;
/** Where data is read from or written to. */
uint32_t data;
/** Last operation executed using this struct. */
enum arm_nand_op op;
/* currently implicit: data width == 8 bits (not 16) */
};
int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size);
int arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size);
#endif /* __ARM_NANDIO_H */

756
src/flash/nand/at91sam9.c Normal file
View File

@@ -0,0 +1,756 @@
/*
* Copyright (C) 2009 by Dean Glazeski
* dnglaze@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
* (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 <target/arm.h>
#include <helper/log.h>
#include "imp.h"
#include "arm_io.h"
#define AT91C_PIOx_SODR (0x30) /**< Offset to PIO SODR. */
#define AT91C_PIOx_CODR (0x34) /**< Offset to PIO CODR. */
#define AT91C_PIOx_PDSR (0x3C) /**< Offset to PIO PDSR. */
#define AT91C_ECCx_CR (0x00) /**< Offset to ECC CR. */
#define AT91C_ECCx_SR (0x08) /**< Offset to ECC SR. */
#define AT91C_ECCx_PR (0x0C) /**< Offset to ECC PR. */
#define AT91C_ECCx_NPR (0x10) /**< Offset to ECC NPR. */
/**
* Representation of a pin on an AT91SAM9 chip.
*/
struct at91sam9_pin {
/** Target this pin is on. */
struct target *target;
/** Address of the PIO controller. */
uint32_t pioc;
/** Pin number. */
uint32_t num;
};
/**
* Private data for the controller that is stored in the NAND device structure.
*/
struct at91sam9_nand {
/** Target the NAND is attached to. */
struct target *target;
/** Address of the ECC controller for NAND. */
uint32_t ecc;
/** Address data is written to. */
uint32_t data;
/** Address commands are written to. */
uint32_t cmd;
/** Address addresses are written to. */
uint32_t addr;
/** I/O structure for hosted reads/writes. */
struct arm_nand_data io;
/** Pin representing the ready/~busy line. */
struct at91sam9_pin busy;
/** Pin representing the chip enable. */
struct at91sam9_pin ce;
};
/**
* Checks if the target is halted and prints an error message if it isn't.
*
* @param target Target to be checked.
* @param label String label for where function is called from.
* @return True if the target is halted.
*/
static int at91sam9_halted(struct target *target, const char *label)
{
if (target->state == TARGET_HALTED)
return true;
LOG_ERROR("Target must be halted to use NAND controller (%s)", label);
return false;
}
/**
* Initialize the AT91SAM9 NAND controller.
*
* @param nand NAND device the controller is attached to.
* @return Success or failure of initialization.
*/
static int at91sam9_init(struct nand_device *nand)
{
struct at91sam9_nand *info = nand->controller_priv;
struct target *target = info->target;
if (!at91sam9_halted(target, "init")) {
return ERROR_NAND_OPERATION_FAILED;
}
return ERROR_OK;
}
/**
* Enable NAND device attached to a controller.
*
* @param info NAND controller information for controlling NAND device.
* @return Success or failure of the enabling.
*/
static int at91sam9_enable(struct at91sam9_nand *info)
{
struct target *target = info->target;
return target_write_u32(target, info->ce.pioc + AT91C_PIOx_CODR, 1 << info->ce.num);
}
/**
* Disable NAND device attached to a controller.
*
* @param info NAND controller information for controlling NAND device.
* @return Success or failure of the disabling.
*/
static int at91sam9_disable(struct at91sam9_nand *info)
{
struct target *target = info->target;
return target_write_u32(target, info->ce.pioc + AT91C_PIOx_SODR, 1 << info->ce.num);
}
/**
* Send a command to the NAND device.
*
* @param nand NAND device to write the command to.
* @param command Command to be written.
* @return Success or failure of writing the command.
*/
static int at91sam9_command(struct nand_device *nand, uint8_t command)
{
struct at91sam9_nand *info = nand->controller_priv;
struct target *target = info->target;
if (!at91sam9_halted(target, "command")) {
return ERROR_NAND_OPERATION_FAILED;
}
at91sam9_enable(info);
return target_write_u8(target, info->cmd, command);
}
/**
* Reset the AT91SAM9 NAND controller.
*
* @param nand NAND device to be reset.
* @return Success or failure of reset.
*/
static int at91sam9_reset(struct nand_device *nand)
{
struct at91sam9_nand *info = nand->controller_priv;
if (!at91sam9_halted(info->target, "reset")) {
return ERROR_NAND_OPERATION_FAILED;
}
return at91sam9_disable(info);
}
/**
* Send an address to the NAND device attached to an AT91SAM9 NAND controller.
*
* @param nand NAND device to send the address to.
* @param address Address to be sent.
* @return Success or failure of sending the address.
*/
static int at91sam9_address(struct nand_device *nand, uint8_t address)
{
struct at91sam9_nand *info = nand->controller_priv;
struct target *target = info->target;
if (!at91sam9_halted(info->target, "address")) {
return ERROR_NAND_OPERATION_FAILED;
}
return target_write_u8(target, info->addr, address);
}
/**
* Read data directly from the NAND device attached to an AT91SAM9 NAND
* controller.
*
* @param nand NAND device to read from.
* @param data Pointer to where the data should be put.
* @return Success or failure of reading the data.
*/
static int at91sam9_read_data(struct nand_device *nand, void *data)
{
struct at91sam9_nand *info = nand->controller_priv;
struct target *target = info->target;
if (!at91sam9_halted(info->target, "read data")) {
return ERROR_NAND_OPERATION_FAILED;
}
return target_read_u8(target, info->data, data);
}
/**
* Write data directly to the NAND device attached to an AT91SAM9 NAND
* controller.
*
* @param nand NAND device to be written to.
* @param data Data to be written.
* @return Success or failure of the data write.
*/
static int at91sam9_write_data(struct nand_device *nand, uint16_t data)
{
struct at91sam9_nand *info = nand->controller_priv;
struct target *target = info->target;
if (!at91sam9_halted(target, "write data")) {
return ERROR_NAND_OPERATION_FAILED;
}
return target_write_u8(target, info->data, data);
}
/**
* Determine if the NAND device is ready by looking at the ready/~busy pin.
*
* @param nand NAND device to check.
* @param timeout Time in milliseconds to wait for NAND to be ready.
* @return True if the NAND is ready in the timeout period.
*/
static int at91sam9_nand_ready(struct nand_device *nand, int timeout)
{
struct at91sam9_nand *info = nand->controller_priv;
struct target *target = info->target;
uint32_t status;
if (!at91sam9_halted(target, "nand ready")) {
return 0;
}
do {
target_read_u32(target, info->busy.pioc + AT91C_PIOx_PDSR, &status);
if (status & (1 << info->busy.num)) {
return 1;
}
alive_sleep(1);
} while (timeout-- > 0);
return 0;
}
/**
* Read a block of data from the NAND device attached to an AT91SAM9. This
* utilizes the ARM hosted NAND read function.
*
* @param nand NAND device to read from.
* @param data Pointer to where the read data should be placed.
* @param size Size of the data being read.
* @return Success or failure of the hosted read.
*/
static int at91sam9_read_block_data(struct nand_device *nand, uint8_t *data, int size)
{
struct at91sam9_nand *info = nand->controller_priv;
struct arm_nand_data *io = &info->io;
int status;
if (!at91sam9_halted(info->target, "read block")) {
return ERROR_NAND_OPERATION_FAILED;
}
io->chunk_size = nand->page_size;
status = arm_nandread(io, data, size);
return status;
}
/**
* Write a block of data to a NAND device attached to an AT91SAM9. This uses
* the ARM hosted write function to write the data.
*
* @param nand NAND device to write to.
* @param data Data to be written to device.
* @param size Size of the data being written.
* @return Success or failure of the hosted write.
*/
static int at91sam9_write_block_data(struct nand_device *nand, uint8_t *data, int size)
{
struct at91sam9_nand *info = nand->controller_priv;
struct arm_nand_data *io = &info->io;
int status;
if (!at91sam9_halted(info->target, "write block")) {
return ERROR_NAND_OPERATION_FAILED;
}
io->chunk_size = nand->page_size;
status = arm_nandwrite(io, data, size);
return status;
}
/**
* Initialize the ECC controller on the AT91SAM9.
*
* @param target Target to configure ECC on.
* @param info NAND controller information for where the ECC is.
* @return Success or failure of initialization.
*/
static int at91sam9_ecc_init(struct target *target, struct at91sam9_nand *info)
{
if (!info->ecc) {
LOG_ERROR("ECC controller address must be set when not reading raw NAND data");
return ERROR_NAND_OPERATION_FAILED;
}
// reset ECC parity registers
return target_write_u32(target, info->ecc + AT91C_ECCx_CR, 1);
}
/**
* Initialize an area for the OOB based on whether a user is requesting the OOB
* data. This determines the size of the OOB and allocates the space in case
* the user has not requested the OOB data.
*
* @param nand NAND device we are creating an OOB for.
* @param oob Pointer to the user supplied OOB area.
* @param size Size of the OOB.
* @return Pointer to an area to store OOB data.
*/
static uint8_t * at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint32_t *size)
{
if (!oob) {
// user doesn't want OOB, allocate it
if (nand->page_size == 512) {
*size = 16;
} else if (nand->page_size == 2048) {
*size = 64;
}
oob = malloc(*size);
if (!oob) {
LOG_ERROR("Unable to allocate space for OOB");
}
memset(oob, 0xFF, *size);
}
return oob;
}
/**
* Reads a page from an AT91SAM9 NAND controller and verifies using 1-bit ECC
* controller on chip. This makes an attempt to correct any errors that are
* encountered while reading the page of data.
*
* @param nand NAND device to read from
* @param page Page to be read.
* @param data Pointer to where data should be read to.
* @param data_size Size of the data to be read.
* @param oob Pointer to where OOB data should be read to.
* @param oob_size Size of the OOB data to be read.
* @return Success or failure of reading the NAND page.
*/
static int at91sam9_read_page(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
int retval;
struct at91sam9_nand *info = nand->controller_priv;
struct target *target = info->target;
uint8_t *oob_data;
uint32_t status;
retval = at91sam9_ecc_init(target, info);
if (ERROR_OK != retval) {
return retval;
}
retval = nand_page_command(nand, page, NAND_CMD_READ0, !data);
if (ERROR_OK != retval) {
return retval;
}
if (data) {
retval = nand_read_data_page(nand, data, data_size);
if (ERROR_OK != retval) {
return retval;
}
}
oob_data = at91sam9_oob_init(nand, oob, &oob_size);
retval = nand_read_data_page(nand, oob_data, oob_size);
if (ERROR_OK == retval && data) {
target_read_u32(target, info->ecc + AT91C_ECCx_SR, &status);
if (status & 1) {
LOG_ERROR("Error detected!");
if (status & 4) {
LOG_ERROR("Multiple errors encountered; unrecoverable!");
} else {
// attempt recovery
uint32_t parity;
target_read_u32(target,
info->ecc + AT91C_ECCx_PR,
&parity);
uint32_t word = (parity & 0x0000FFF0) >> 4;
uint32_t bit = parity & 0x0F;
data[word] ^= (0x1) << bit;
LOG_INFO("Data word %d, bit %d corrected.",
(unsigned) word,
(unsigned) bit);
}
}
if (status & 2) {
// we could write back correct ECC data
LOG_ERROR("Error in ECC bytes detected");
}
}
if (!oob) {
// if it wasn't asked for, free it
free(oob_data);
}
return retval;
}
/**
* Write a page of data including 1-bit ECC information to a NAND device
* attached to an AT91SAM9 controller. If there is OOB data to be written,
* this will ignore the computed ECC from the ECC controller.
*
* @param nand NAND device to write to.
* @param page Page to write.
* @param data Pointer to data being written.
* @param data_size Size of the data being written.
* @param oob Pointer to OOB data being written.
* @param oob_size Size of the OOB data.
* @return Success or failure of the page write.
*/
static int at91sam9_write_page(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
struct at91sam9_nand *info = nand->controller_priv;
struct target *target = info->target;
int retval;
uint8_t *oob_data = oob;
uint32_t parity, nparity;
retval = at91sam9_ecc_init(target, info);
if (ERROR_OK != retval) {
return retval;
}
retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);
if (ERROR_OK != retval) {
return retval;
}
if (data) {
retval = nand_write_data_page(nand, data, data_size);
if (ERROR_OK != retval) {
LOG_ERROR("Unable to write data to NAND device");
return retval;
}
}
oob_data = at91sam9_oob_init(nand, oob, &oob_size);
if (!oob) {
// no OOB given, so read in the ECC parity from the ECC controller
target_read_u32(target, info->ecc + AT91C_ECCx_PR, &parity);
target_read_u32(target, info->ecc + AT91C_ECCx_NPR, &nparity);
oob_data[0] = (uint8_t) parity;
oob_data[1] = (uint8_t) (parity >> 8);
oob_data[2] = (uint8_t) nparity;
oob_data[3] = (uint8_t) (nparity >> 8);
}
retval = nand_write_data_page(nand, oob_data, oob_size);
if (!oob) {
free(oob_data);
}
if (ERROR_OK != retval) {
LOG_ERROR("Unable to write OOB data to NAND");
return retval;
}
retval = nand_write_finish(nand);
return retval;
}
/**
* Handle the initial NAND device command for AT91SAM9 controllers. This
* initializes much of the controller information struct to be ready for future
* reads and writes.
*/
NAND_DEVICE_COMMAND_HANDLER(at91sam9_nand_device_command)
{
struct target *target = NULL;
unsigned long chip = 0, ecc = 0;
struct at91sam9_nand *info = NULL;
LOG_DEBUG("AT91SAM9 NAND Device Command\n");
if (CMD_ARGC < 3 || CMD_ARGC > 4) {
LOG_ERROR("parameters: %s target chip_addr", CMD_ARGV[0]);
return ERROR_NAND_OPERATION_FAILED;
}
target = get_target(CMD_ARGV[1]);
if (!target) {
LOG_ERROR("invalid target: %s", CMD_ARGV[1]);
return ERROR_NAND_OPERATION_FAILED;
}
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip);
if (chip == 0) {
LOG_ERROR("invalid NAND chip address: %s", CMD_ARGV[2]);
return ERROR_NAND_OPERATION_FAILED;
}
if (CMD_ARGC == 4) {
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[3], ecc);
if (ecc == 0) {
LOG_ERROR("invalid ECC controller address: %s", CMD_ARGV[3]);
return ERROR_NAND_OPERATION_FAILED;
}
}
info = calloc(1, sizeof(*info));
if (!info) {
LOG_ERROR("unable to allocate space for controller private data");
return ERROR_NAND_OPERATION_FAILED;
}
info->target = target;
info->data = chip;
info->cmd = chip | (1 << 22);
info->addr = chip | (1 << 21);
info->ecc = ecc;
nand->controller_priv = info;
info->io.target = target;
info->io.data = info->data;
info->io.op = ARM_NAND_NONE;
return ERROR_OK;
}
/**
* Handle the AT91SAM9 CLE command for specifying the address line to use for
* writing commands to a NAND device.
*/
COMMAND_HANDLER(handle_at91sam9_cle_command)
{
struct nand_device *nand = NULL;
struct at91sam9_nand *info = NULL;
unsigned num, address_line;
if (CMD_ARGC != 2) {
command_print(CMD_CTX, "incorrect number of arguments for 'at91sam9 cle' command");
return ERROR_OK;
}
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
nand = get_nand_device_by_num(num);
if (!nand) {
command_print(CMD_CTX, "invalid nand device number: %s", CMD_ARGV[0]);
return ERROR_OK;
}
info = nand->controller_priv;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], address_line);
info->cmd = info->data | (1 << address_line);
return ERROR_OK;
}
/**
* Handle the AT91SAM9 ALE command for specifying the address line to use for
* writing addresses to the NAND device.
*/
COMMAND_HANDLER(handle_at91sam9_ale_command)
{
struct nand_device *nand = NULL;
struct at91sam9_nand *info = NULL;
unsigned num, address_line;
if (CMD_ARGC != 2) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
nand = get_nand_device_by_num(num);
if (!nand) {
command_print(CMD_CTX, "invalid nand device number: %s", CMD_ARGV[0]);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
info = nand->controller_priv;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], address_line);
info->addr = info->data | (1 << address_line);
return ERROR_OK;
}
/**
* Handle the AT91SAM9 RDY/~BUSY command for specifying the pin that watches the
* RDY/~BUSY line from the NAND device.
*/
COMMAND_HANDLER(handle_at91sam9_rdy_busy_command)
{
struct nand_device *nand = NULL;
struct at91sam9_nand *info = NULL;
unsigned num, base_pioc, pin_num;
if (CMD_ARGC != 3) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
nand = get_nand_device_by_num(num);
if (!nand) {
command_print(CMD_CTX, "invalid nand device number: %s", CMD_ARGV[0]);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
info = nand->controller_priv;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], base_pioc);
info->busy.pioc = base_pioc;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], pin_num);
info->busy.num = pin_num;
return ERROR_OK;
}
/**
* Handle the AT91SAM9 CE command for specifying the pin that is used to enable
* or disable the NAND device.
*/
COMMAND_HANDLER(handle_at91sam9_ce_command)
{
struct nand_device *nand = NULL;
struct at91sam9_nand *info = NULL;
unsigned num, base_pioc, pin_num;
if (CMD_ARGC != 3) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
nand = get_nand_device_by_num(num);
if (!nand) {
command_print(CMD_CTX, "invalid nand device number: %s", CMD_ARGV[0]);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
info = nand->controller_priv;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], base_pioc);
info->ce.pioc = base_pioc;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], pin_num);
info->ce.num = pin_num;
return ERROR_OK;
}
static const struct command_registration at91sam9_sub_command_handlers[] = {
{
.name = "cle",
.handler = handle_at91sam9_cle_command,
.mode = COMMAND_CONFIG,
.help = "set command latch enable address line (default is 22)",
.usage = "bank_id address_line",
},
{
.name = "ale",
.handler = handle_at91sam9_ale_command,
.mode = COMMAND_CONFIG,
.help = "set address latch enable address line (default is 21)",
.usage = "bank_id address_line",
},
{
.name = "rdy_busy",
.handler = handle_at91sam9_rdy_busy_command,
.mode = COMMAND_CONFIG,
.help = "set the GPIO input pin connected to "
"the RDY/~BUSY signal (no default)",
.usage = "bank_id pio_base_addr pin_num",
},
{
.name = "ce",
.handler = handle_at91sam9_ce_command,
.mode = COMMAND_CONFIG,
.help = "set the GPIO output pin connected to "
"the chip enable signal (no default)",
.usage = "bank_id pio_base_addr pin_num",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration at91sam9_command_handler[] = {
{
.name = "at91sam9",
.mode = COMMAND_ANY,
.help = "AT91SAM9 NAND flash controller commands",
.chain = at91sam9_sub_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
/**
* Structure representing the AT91SAM9 NAND controller.
*/
struct nand_flash_controller at91sam9_nand_controller = {
.name = "at91sam9",
.nand_device_command = at91sam9_nand_device_command,
.commands = at91sam9_command_handler,
.init = at91sam9_init,
.command = at91sam9_command,
.reset = at91sam9_reset,
.address = at91sam9_address,
.read_data = at91sam9_read_data,
.write_data = at91sam9_write_data,
.nand_ready = at91sam9_nand_ready,
.read_block_data = at91sam9_read_block_data,
.write_block_data = at91sam9_write_block_data,
.read_page = at91sam9_read_page,
.write_page = at91sam9_write_page,
};

899
src/flash/nand/core.c Normal file
View File

@@ -0,0 +1,899 @@
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* Partially based on drivers/mtd/nand_ids.c from Linux. *
* *
* 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 "imp.h"
/* configured NAND devices and NAND Flash command handler */
struct nand_device *nand_devices = NULL;
void nand_device_add(struct nand_device *c)
{
if (nand_devices) {
struct nand_device *p = nand_devices;
while (p && p->next) p = p->next;
p->next = c;
} else
nand_devices = c;
}
/* Chip ID list
*
* Name, ID code, pagesize, chipsize in MegaByte, eraseblock size,
* options
*
* Pagesize; 0, 256, 512
* 0 get this information from the extended chip ID
* 256 256 Byte page size
* 512 512 Byte page size
*/
static struct nand_info nand_flash_ids[] =
{
/* start "museum" IDs */
{"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
{"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0},
{"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0},
{"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0},
{"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0},
{"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0},
{"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0},
{"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
{"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
{"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
{"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
{"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
{"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
{"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
/* end "museum" IDs */
{"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
{"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
{"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
{"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
{"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
{"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
{"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
{"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
{"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
{"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
{"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
{"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
{"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
{"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
{"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
{"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, LP_OPTIONS},
{"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, LP_OPTIONS},
{"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, LP_OPTIONS16},
{"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, LP_OPTIONS16},
{"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, LP_OPTIONS},
{"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, LP_OPTIONS},
{"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, LP_OPTIONS16},
{"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, LP_OPTIONS16},
{"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, LP_OPTIONS},
{"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, LP_OPTIONS},
{"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, LP_OPTIONS16},
{"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, LP_OPTIONS16},
{"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, LP_OPTIONS},
{"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, LP_OPTIONS},
{"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, LP_OPTIONS16},
{"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, LP_OPTIONS16},
{"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, LP_OPTIONS},
{"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, LP_OPTIONS},
{"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, LP_OPTIONS16},
{"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, LP_OPTIONS16},
{"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, LP_OPTIONS},
{"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, LP_OPTIONS},
{"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16},
{"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16},
{NULL, 0, 0, 0, 0, 0 }
};
/* Manufacturer ID list
*/
static struct nand_manufacturer nand_manuf_ids[] =
{
{0x0, "unknown"},
{NAND_MFR_TOSHIBA, "Toshiba"},
{NAND_MFR_SAMSUNG, "Samsung"},
{NAND_MFR_FUJITSU, "Fujitsu"},
{NAND_MFR_NATIONAL, "National"},
{NAND_MFR_RENESAS, "Renesas"},
{NAND_MFR_STMICRO, "ST Micro"},
{NAND_MFR_HYNIX, "Hynix"},
{NAND_MFR_MICRON, "Micron"},
{0x0, NULL},
};
/*
* Define default oob placement schemes for large and small page devices
*/
#if 0
static struct nand_ecclayout nand_oob_8 = {
.eccbytes = 3,
.eccpos = {0, 1, 2},
.oobfree = {
{.offset = 3,
.length = 2},
{.offset = 6,
.length = 2}}
};
#endif
struct nand_device *get_nand_device_by_name(const char *name)
{
unsigned requested = get_flash_name_index(name);
unsigned found = 0;
struct nand_device *nand;
for (nand = nand_devices; NULL != nand; nand = nand->next)
{
if (strcmp(nand->name, name) == 0)
return nand;
if (!flash_driver_name_matches(nand->controller->name, name))
continue;
if (++found < requested)
continue;
return nand;
}
return NULL;
}
struct nand_device *get_nand_device_by_num(int num)
{
struct nand_device *p;
int i = 0;
for (p = nand_devices; p; p = p->next)
{
if (i++ == num)
{
return p;
}
}
return NULL;
}
COMMAND_HELPER(nand_command_get_device, unsigned name_index,
struct nand_device **nand)
{
const char *str = CMD_ARGV[name_index];
*nand = get_nand_device_by_name(str);
if (*nand)
return ERROR_OK;
unsigned num;
COMMAND_PARSE_NUMBER(uint, str, num);
*nand = get_nand_device_by_num(num);
if (!*nand) {
command_print(CMD_CTX, "NAND flash device '%s' not found", str);
return ERROR_INVALID_ARGUMENTS;
}
return ERROR_OK;
}
int nand_build_bbt(struct nand_device *nand, int first, int last)
{
uint32_t page = 0x0;
int i;
uint8_t oob[6];
if ((first < 0) || (first >= nand->num_blocks))
first = 0;
if ((last >= nand->num_blocks) || (last == -1))
last = nand->num_blocks - 1;
for (i = first; i < last; i++)
{
nand_read_page(nand, page, NULL, 0, oob, 6);
if (((nand->device->options & NAND_BUSWIDTH_16) && ((oob[0] & oob[1]) != 0xff))
|| (((nand->page_size == 512) && (oob[5] != 0xff)) ||
((nand->page_size == 2048) && (oob[0] != 0xff))))
{
LOG_WARNING("bad block: %i", i);
nand->blocks[i].is_bad = 1;
}
else
{
nand->blocks[i].is_bad = 0;
}
page += (nand->erase_size / nand->page_size);
}
return ERROR_OK;
}
int nand_read_status(struct nand_device *nand, uint8_t *status)
{
if (!nand->device)
return ERROR_NAND_DEVICE_NOT_PROBED;
/* Send read status command */
nand->controller->command(nand, NAND_CMD_STATUS);
alive_sleep(1);
/* read status */
if (nand->device->options & NAND_BUSWIDTH_16)
{
uint16_t data;
nand->controller->read_data(nand, &data);
*status = data & 0xff;
}
else
{
nand->controller->read_data(nand, status);
}
return ERROR_OK;
}
static int nand_poll_ready(struct nand_device *nand, int timeout)
{
uint8_t status;
nand->controller->command(nand, NAND_CMD_STATUS);
do {
if (nand->device->options & NAND_BUSWIDTH_16) {
uint16_t data;
nand->controller->read_data(nand, &data);
status = data & 0xff;
} else {
nand->controller->read_data(nand, &status);
}
if (status & NAND_STATUS_READY)
break;
alive_sleep(1);
} while (timeout--);
return (status & NAND_STATUS_READY) != 0;
}
int nand_probe(struct nand_device *nand)
{
uint8_t manufacturer_id, device_id;
uint8_t id_buff[6];
int retval;
int i;
/* clear device data */
nand->device = NULL;
nand->manufacturer = NULL;
/* clear device parameters */
nand->bus_width = 0;
nand->address_cycles = 0;
nand->page_size = 0;
nand->erase_size = 0;
/* initialize controller (device parameters are zero, use controller default) */
if ((retval = nand->controller->init(nand) != ERROR_OK))
{
switch (retval)
{
case ERROR_NAND_OPERATION_FAILED:
LOG_DEBUG("controller initialization failed");
return ERROR_NAND_OPERATION_FAILED;
case ERROR_NAND_OPERATION_NOT_SUPPORTED:
LOG_ERROR("BUG: controller reported that it doesn't support default parameters");
return ERROR_NAND_OPERATION_FAILED;
default:
LOG_ERROR("BUG: unknown controller initialization failure");
return ERROR_NAND_OPERATION_FAILED;
}
}
nand->controller->command(nand, NAND_CMD_RESET);
nand->controller->reset(nand);
nand->controller->command(nand, NAND_CMD_READID);
nand->controller->address(nand, 0x0);
if (nand->bus_width == 8)
{
nand->controller->read_data(nand, &manufacturer_id);
nand->controller->read_data(nand, &device_id);
}
else
{
uint16_t data_buf;
nand->controller->read_data(nand, &data_buf);
manufacturer_id = data_buf & 0xff;
nand->controller->read_data(nand, &data_buf);
device_id = data_buf & 0xff;
}
for (i = 0; nand_flash_ids[i].name; i++)
{
if (nand_flash_ids[i].id == device_id)
{
nand->device = &nand_flash_ids[i];
break;
}
}
for (i = 0; nand_manuf_ids[i].name; i++)
{
if (nand_manuf_ids[i].id == manufacturer_id)
{
nand->manufacturer = &nand_manuf_ids[i];
break;
}
}
if (!nand->manufacturer)
{
nand->manufacturer = &nand_manuf_ids[0];
nand->manufacturer->id = manufacturer_id;
}
if (!nand->device)
{
LOG_ERROR("unknown NAND flash device found, manufacturer id: 0x%2.2x device id: 0x%2.2x",
manufacturer_id, device_id);
return ERROR_NAND_OPERATION_FAILED;
}
LOG_DEBUG("found %s (%s)", nand->device->name, nand->manufacturer->name);
/* initialize device parameters */
/* bus width */
if (nand->device->options & NAND_BUSWIDTH_16)
nand->bus_width = 16;
else
nand->bus_width = 8;
/* Do we need extended device probe information? */
if (nand->device->page_size == 0 ||
nand->device->erase_size == 0)
{
if (nand->bus_width == 8)
{
nand->controller->read_data(nand, id_buff + 3);
nand->controller->read_data(nand, id_buff + 4);
nand->controller->read_data(nand, id_buff + 5);
}
else
{
uint16_t data_buf;
nand->controller->read_data(nand, &data_buf);
id_buff[3] = data_buf;
nand->controller->read_data(nand, &data_buf);
id_buff[4] = data_buf;
nand->controller->read_data(nand, &data_buf);
id_buff[5] = data_buf >> 8;
}
}
/* page size */
if (nand->device->page_size == 0)
{
nand->page_size = 1 << (10 + (id_buff[4] & 3));
}
else if (nand->device->page_size == 256)
{
LOG_ERROR("NAND flashes with 256 byte pagesize are not supported");
return ERROR_NAND_OPERATION_FAILED;
}
else
{
nand->page_size = nand->device->page_size;
}
/* number of address cycles */
if (nand->page_size <= 512)
{
/* small page devices */
if (nand->device->chip_size <= 32)
nand->address_cycles = 3;
else if (nand->device->chip_size <= 8*1024)
nand->address_cycles = 4;
else
{
LOG_ERROR("BUG: small page NAND device with more than 8 GiB encountered");
nand->address_cycles = 5;
}
}
else
{
/* large page devices */
if (nand->device->chip_size <= 128)
nand->address_cycles = 4;
else if (nand->device->chip_size <= 32*1024)
nand->address_cycles = 5;
else
{
LOG_ERROR("BUG: large page NAND device with more than 32 GiB encountered");
nand->address_cycles = 6;
}
}
/* erase size */
if (nand->device->erase_size == 0)
{
switch ((id_buff[4] >> 4) & 3) {
case 0:
nand->erase_size = 64 << 10;
break;
case 1:
nand->erase_size = 128 << 10;
break;
case 2:
nand->erase_size = 256 << 10;
break;
case 3:
nand->erase_size =512 << 10;
break;
}
}
else
{
nand->erase_size = nand->device->erase_size;
}
/* initialize controller, but leave parameters at the controllers default */
if ((retval = nand->controller->init(nand) != ERROR_OK))
{
switch (retval)
{
case ERROR_NAND_OPERATION_FAILED:
LOG_DEBUG("controller initialization failed");
return ERROR_NAND_OPERATION_FAILED;
case ERROR_NAND_OPERATION_NOT_SUPPORTED:
LOG_ERROR("controller doesn't support requested parameters (buswidth: %i, address cycles: %i, page size: %i)",
nand->bus_width, nand->address_cycles, nand->page_size);
return ERROR_NAND_OPERATION_FAILED;
default:
LOG_ERROR("BUG: unknown controller initialization failure");
return ERROR_NAND_OPERATION_FAILED;
}
}
nand->num_blocks = (nand->device->chip_size * 1024) / (nand->erase_size / 1024);
nand->blocks = malloc(sizeof(struct nand_block) * nand->num_blocks);
for (i = 0; i < nand->num_blocks; i++)
{
nand->blocks[i].size = nand->erase_size;
nand->blocks[i].offset = i * nand->erase_size;
nand->blocks[i].is_erased = -1;
nand->blocks[i].is_bad = -1;
}
return ERROR_OK;
}
int nand_erase(struct nand_device *nand, int first_block, int last_block)
{
int i;
uint32_t page;
uint8_t status;
int retval;
if (!nand->device)
return ERROR_NAND_DEVICE_NOT_PROBED;
if ((first_block < 0) || (last_block > nand->num_blocks))
return ERROR_INVALID_ARGUMENTS;
/* make sure we know if a block is bad before erasing it */
for (i = first_block; i <= last_block; i++)
{
if (nand->blocks[i].is_bad == -1)
{
nand_build_bbt(nand, i, last_block);
break;
}
}
for (i = first_block; i <= last_block; i++)
{
/* Send erase setup command */
nand->controller->command(nand, NAND_CMD_ERASE1);
page = i * (nand->erase_size / nand->page_size);
/* Send page address */
if (nand->page_size <= 512)
{
/* row */
nand->controller->address(nand, page & 0xff);
nand->controller->address(nand, (page >> 8) & 0xff);
/* 3rd cycle only on devices with more than 32 MiB */
if (nand->address_cycles >= 4)
nand->controller->address(nand, (page >> 16) & 0xff);
/* 4th cycle only on devices with more than 8 GiB */
if (nand->address_cycles >= 5)
nand->controller->address(nand, (page >> 24) & 0xff);
}
else
{
/* row */
nand->controller->address(nand, page & 0xff);
nand->controller->address(nand, (page >> 8) & 0xff);
/* 3rd cycle only on devices with more than 128 MiB */
if (nand->address_cycles >= 5)
nand->controller->address(nand, (page >> 16) & 0xff);
}
/* Send erase confirm command */
nand->controller->command(nand, NAND_CMD_ERASE2);
retval = nand->controller->nand_ready ?
nand->controller->nand_ready(nand, 1000) :
nand_poll_ready(nand, 1000);
if (!retval) {
LOG_ERROR("timeout waiting for NAND flash block erase to complete");
return ERROR_NAND_OPERATION_TIMEOUT;
}
if ((retval = nand_read_status(nand, &status)) != ERROR_OK)
{
LOG_ERROR("couldn't read status");
return ERROR_NAND_OPERATION_FAILED;
}
if (status & 0x1)
{
LOG_ERROR("didn't erase %sblock %d; status: 0x%2.2x",
(nand->blocks[i].is_bad == 1)
? "bad " : "",
i, status);
/* continue; other blocks might still be erasable */
}
nand->blocks[i].is_erased = 1;
}
return ERROR_OK;
}
#if 0
static int nand_read_plain(struct nand_device *nand, uint32_t address, uint8_t *data, uint32_t data_size)
{
uint8_t *page;
if (!nand->device)
return ERROR_NAND_DEVICE_NOT_PROBED;
if (address % nand->page_size)
{
LOG_ERROR("reads need to be page aligned");
return ERROR_NAND_OPERATION_FAILED;
}
page = malloc(nand->page_size);
while (data_size > 0)
{
uint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size;
uint32_t page_address;
page_address = address / nand->page_size;
nand_read_page(nand, page_address, page, nand->page_size, NULL, 0);
memcpy(data, page, thisrun_size);
address += thisrun_size;
data += thisrun_size;
data_size -= thisrun_size;
}
free(page);
return ERROR_OK;
}
static int nand_write_plain(struct nand_device *nand, uint32_t address, uint8_t *data, uint32_t data_size)
{
uint8_t *page;
if (!nand->device)
return ERROR_NAND_DEVICE_NOT_PROBED;
if (address % nand->page_size)
{
LOG_ERROR("writes need to be page aligned");
return ERROR_NAND_OPERATION_FAILED;
}
page = malloc(nand->page_size);
while (data_size > 0)
{
uint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size;
uint32_t page_address;
memset(page, 0xff, nand->page_size);
memcpy(page, data, thisrun_size);
page_address = address / nand->page_size;
nand_write_page(nand, page_address, page, nand->page_size, NULL, 0);
address += thisrun_size;
data += thisrun_size;
data_size -= thisrun_size;
}
free(page);
return ERROR_OK;
}
#endif
int nand_write_page(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size,
uint8_t *oob, uint32_t oob_size)
{
uint32_t block;
if (!nand->device)
return ERROR_NAND_DEVICE_NOT_PROBED;
block = page / (nand->erase_size / nand->page_size);
if (nand->blocks[block].is_erased == 1)
nand->blocks[block].is_erased = 0;
if (nand->use_raw || nand->controller->write_page == NULL)
return nand_write_page_raw(nand, page, data, data_size, oob, oob_size);
else
return nand->controller->write_page(nand, page, data, data_size, oob, oob_size);
}
int nand_read_page(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size,
uint8_t *oob, uint32_t oob_size)
{
if (!nand->device)
return ERROR_NAND_DEVICE_NOT_PROBED;
if (nand->use_raw || nand->controller->read_page == NULL)
return nand_read_page_raw(nand, page, data, data_size, oob, oob_size);
else
return nand->controller->read_page(nand, page, data, data_size, oob, oob_size);
}
int nand_page_command(struct nand_device *nand, uint32_t page,
uint8_t cmd, bool oob_only)
{
if (!nand->device)
return ERROR_NAND_DEVICE_NOT_PROBED;
if (oob_only && NAND_CMD_READ0 == cmd && nand->page_size <= 512)
cmd = NAND_CMD_READOOB;
nand->controller->command(nand, cmd);
if (nand->page_size <= 512) {
/* small page device */
/* column (always 0, we start at the beginning of a page/OOB area) */
nand->controller->address(nand, 0x0);
/* row */
nand->controller->address(nand, page & 0xff);
nand->controller->address(nand, (page >> 8) & 0xff);
/* 4th cycle only on devices with more than 32 MiB */
if (nand->address_cycles >= 4)
nand->controller->address(nand, (page >> 16) & 0xff);
/* 5th cycle only on devices with more than 8 GiB */
if (nand->address_cycles >= 5)
nand->controller->address(nand, (page >> 24) & 0xff);
} else {
/* large page device */
/* column (0 when we start at the beginning of a page,
* or 2048 for the beginning of OOB area)
*/
nand->controller->address(nand, 0x0);
if (oob_only)
nand->controller->address(nand, 0x8);
else
nand->controller->address(nand, 0x0);
/* row */
nand->controller->address(nand, page & 0xff);
nand->controller->address(nand, (page >> 8) & 0xff);
/* 5th cycle only on devices with more than 128 MiB */
if (nand->address_cycles >= 5)
nand->controller->address(nand, (page >> 16) & 0xff);
/* large page devices need a start command if reading */
if (NAND_CMD_READ0 == cmd)
nand->controller->command(nand, NAND_CMD_READSTART);
}
if (nand->controller->nand_ready) {
if (!nand->controller->nand_ready(nand, 100))
return ERROR_NAND_OPERATION_TIMEOUT;
} else {
alive_sleep(1);
}
return ERROR_OK;
}
int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size)
{
int retval = ERROR_NAND_NO_BUFFER;
if (nand->controller->read_block_data != NULL)
retval = (nand->controller->read_block_data)(nand, data, size);
if (ERROR_NAND_NO_BUFFER == retval) {
uint32_t i;
int incr = (nand->device->options & NAND_BUSWIDTH_16) ? 2 : 1;
retval = ERROR_OK;
for (i = 0; retval == ERROR_OK && i < size; i += incr) {
retval = nand->controller->read_data(nand, data);
data += incr;
}
}
return retval;
}
int nand_read_page_raw(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size,
uint8_t *oob, uint32_t oob_size)
{
int retval;
retval = nand_page_command(nand, page, NAND_CMD_READ0, !data);
if (ERROR_OK != retval)
return retval;
if (data)
nand_read_data_page(nand, data, data_size);
if (oob)
nand_read_data_page(nand, oob, oob_size);
return ERROR_OK;
}
int nand_write_data_page(struct nand_device *nand, uint8_t *data, uint32_t size)
{
int retval = ERROR_NAND_NO_BUFFER;
if (nand->controller->write_block_data != NULL)
retval = (nand->controller->write_block_data)(nand, data, size);
if (ERROR_NAND_NO_BUFFER == retval) {
bool is16bit = nand->device->options & NAND_BUSWIDTH_16;
uint32_t incr = is16bit ? 2 : 1;
uint16_t write_data;
uint32_t i;
for (i = 0; i < size; i += incr) {
if (is16bit)
write_data = le_to_h_u16(data);
else
write_data = *data;
retval = nand->controller->write_data(nand, write_data);
if (ERROR_OK != retval)
break;
data += incr;
}
}
return retval;
}
int nand_write_finish(struct nand_device *nand)
{
int retval;
uint8_t status;
nand->controller->command(nand, NAND_CMD_PAGEPROG);
retval = nand->controller->nand_ready ?
nand->controller->nand_ready(nand, 100) :
nand_poll_ready(nand, 100);
if (!retval)
return ERROR_NAND_OPERATION_TIMEOUT;
retval = nand_read_status(nand, &status);
if (ERROR_OK != retval) {
LOG_ERROR("couldn't read status");
return ERROR_NAND_OPERATION_FAILED;
}
if (status & NAND_STATUS_FAIL) {
LOG_ERROR("write operation didn't pass, status: 0x%2.2x",
status);
return ERROR_NAND_OPERATION_FAILED;
}
return ERROR_OK;
}
int nand_write_page_raw(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size,
uint8_t *oob, uint32_t oob_size)
{
int retval;
retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);
if (ERROR_OK != retval)
return retval;
if (data) {
retval = nand_write_data_page(nand, data, data_size);
if (ERROR_OK != retval) {
LOG_ERROR("Unable to write data to NAND device");
return retval;
}
}
if (oob) {
retval = nand_write_data_page(nand, oob, oob_size);
if (ERROR_OK != retval) {
LOG_ERROR("Unable to write OOB data to NAND device");
return retval;
}
}
return nand_write_finish(nand);
}

View File

@@ -1,6 +1,6 @@
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* Partially based on linux/include/linux/mtd/nand.h *
* Copyright (C) 2000 David Woodhouse <dwmw2@mvhi.com> *
@@ -22,67 +22,57 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef NAND_H
#define NAND_H
#ifndef FLASH_NAND_CORE_H
#define FLASH_NAND_CORE_H
#include "flash.h"
#include <flash/common.h>
struct nand_device_s;
typedef struct nand_flash_controller_s
{
char *name;
int (*nand_device_command)(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);
int (*register_commands)(struct command_context_s *cmd_ctx);
int (*init)(struct nand_device_s *device);
int (*reset)(struct nand_device_s *device);
int (*command)(struct nand_device_s *device, uint8_t command);
int (*address)(struct nand_device_s *device, uint8_t address);
int (*write_data)(struct nand_device_s *device, uint16_t data);
int (*read_data)(struct nand_device_s *device, void *data);
int (*write_block_data)(struct nand_device_s *device, uint8_t *data, int size);
int (*read_block_data)(struct nand_device_s *device, uint8_t *data, int size);
int (*write_page)(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
int (*read_page)(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
int (*controller_ready)(struct nand_device_s *device, int timeout);
int (*nand_ready)(struct nand_device_s *device, int timeout);
} nand_flash_controller_t;
typedef struct nand_block_s
/**
* Representation of a single NAND block in a NAND device.
*/
struct nand_block
{
/** Offset to the block. */
uint32_t offset;
/** Size of the block. */
uint32_t size;
/** True if the block has been erased. */
int is_erased;
/** True if the block is bad. */
int is_bad;
} nand_block_t;
};
struct nand_oobfree {
int offset;
int length;
};
typedef struct nand_ecclayout_s {
struct nand_ecclayout {
int eccbytes;
int eccpos[64];
int oobavail;
struct nand_oobfree oobfree[2];
} nand_ecclayout_t;
};
typedef struct nand_device_s
struct nand_device
{
nand_flash_controller_t *controller;
char *name;
struct nand_flash_controller *controller;
void *controller_priv;
struct nand_manufacturer_s *manufacturer;
struct nand_info_s *device;
struct nand_manufacturer *manufacturer;
struct nand_info *device;
int bus_width;
int address_cycles;
int page_size;
int erase_size;
int use_raw;
int num_blocks;
nand_block_t *blocks;
struct nand_device_s *next;
} nand_device_t;
struct nand_block *blocks;
struct nand_device *next;
};
/* NAND Flash Manufacturer ID Codes
*/
@@ -98,13 +88,13 @@ enum
NAND_MFR_MICRON = 0x2c,
};
typedef struct nand_manufacturer_s
struct nand_manufacturer
{
int id;
char *name;
} nand_manufacturer_t;
};
typedef struct nand_info_s
struct nand_info
{
char *name;
int id;
@@ -112,7 +102,7 @@ typedef struct nand_info_s
int chip_size;
int erase_size;
int options;
} nand_info_t;
};
/* Option constants for bizarre disfunctionality and real features
*/
@@ -206,16 +196,46 @@ enum oob_formats
NAND_OOB_YAFFS2 = 0x100,/* when writing, use YAFFS2 OOB layout */
};
/* Function prototypes */
extern nand_device_t *get_nand_device_by_num(int num);
extern int nand_read_page_raw(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
extern int nand_write_page_raw(struct nand_device_s *device, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
extern int nand_read_status(struct nand_device_s *device, uint8_t *status);
extern int nand_calculate_ecc(struct nand_device_s *device, const uint8_t *dat, uint8_t *ecc_code);
extern int nand_calculate_ecc_kw(struct nand_device_s *device, const uint8_t *dat, uint8_t *ecc_code);
extern int nand_register_commands(struct command_context_s *cmd_ctx);
extern int nand_init(struct command_context_s *cmd_ctx);
/**
* Returns the flash bank specified by @a name, which matches the
* driver name and a suffix (option) specify the driver-specific
* bank number. The suffix consists of the '.' and the driver-specific
* bank number: when two davinci banks are defined, then 'davinci.1' refers
* to the second (e.g. DM355EVM).
*/
struct nand_device *get_nand_device_by_name(const char *name);
struct nand_device *get_nand_device_by_num(int num);
int nand_page_command(struct nand_device *nand, uint32_t page,
uint8_t cmd, bool oob_only);
int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size);
int nand_write_data_page(struct nand_device *nand,
uint8_t *data, uint32_t size);
int nand_write_finish(struct nand_device *nand);
int nand_read_page_raw(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
int nand_write_page_raw(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
int nand_read_status(struct nand_device *nand, uint8_t *status);
int nand_calculate_ecc(struct nand_device *nand,
const uint8_t *dat, uint8_t *ecc_code);
int nand_calculate_ecc_kw(struct nand_device *nand,
const uint8_t *dat, uint8_t *ecc_code);
int nand_register_commands(struct command_context *cmd_ctx);
int nand_init(struct command_context *cmd_ctx);
/// helper for parsing a nand device command argument string
COMMAND_HELPER(nand_command_get_device, unsigned name_index,
struct nand_device **nand);
#define ERROR_NAND_DEVICE_INVALID (-1100)
#define ERROR_NAND_OPERATION_FAILED (-1101)
@@ -225,4 +245,5 @@ extern int nand_init(struct command_context_s *cmd_ctx);
#define ERROR_NAND_ERROR_CORRECTION_FAILED (-1105)
#define ERROR_NAND_NO_BUFFER (-1106)
#endif /* NAND_H */
#endif // FLASH_NAND_CORE_H

View File

@@ -28,8 +28,9 @@
#include "config.h"
#endif
#include "arm_nandio.h"
#include "imp.h"
#include "arm_io.h"
#include <target/target.h>
enum ecc {
HWECC1, /* all controllers support 1-bit ECC */
@@ -38,7 +39,7 @@ enum ecc {
};
struct davinci_nand {
target_t *target;
struct target *target;
uint8_t chipsel; /* chipselect 0..3 == CS2..CS5 */
uint8_t eccmode;
@@ -55,9 +56,9 @@ struct davinci_nand {
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,
int (*read_page)(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
int (*write_page)(struct nand_device_s *nand, uint32_t page,
int (*write_page)(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
};
@@ -69,7 +70,7 @@ struct davinci_nand {
#define NANDERRADDR 0xd0 /* 4-bit ECC err addr, 1st of 2 */
#define NANDERRVAL 0xd8 /* 4-bit ECC err value, 1st of 2 */
static int halted(target_t *target, const char *label)
static int halted(struct target *target, const char *label)
{
if (target->state == TARGET_HALTED)
return true;
@@ -78,15 +79,10 @@ static int halted(target_t *target, const char *label)
return false;
}
static int davinci_register_commands(struct command_context_s *cmd_ctx)
{
return ERROR_OK;
}
static int davinci_init(struct nand_device_s *nand)
static int davinci_init(struct nand_device *nand)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
uint32_t nandfcr;
if (!halted(target, "init"))
@@ -108,15 +104,15 @@ static int davinci_init(struct nand_device_s *nand)
return ERROR_OK;
}
static int davinci_reset(struct nand_device_s *nand)
static int davinci_reset(struct nand_device *nand)
{
return ERROR_OK;
}
static int davinci_nand_ready(struct nand_device_s *nand, int timeout)
static int davinci_nand_ready(struct nand_device *nand, int timeout)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
uint32_t nandfsr;
/* NOTE: return code is zero/error, else success; not ERROR_* */
@@ -136,10 +132,10 @@ static int davinci_nand_ready(struct nand_device_s *nand, int timeout)
return 0;
}
static int davinci_command(struct nand_device_s *nand, uint8_t command)
static int davinci_command(struct nand_device *nand, uint8_t command)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
if (!halted(target, "command"))
return ERROR_NAND_OPERATION_FAILED;
@@ -148,10 +144,10 @@ static int davinci_command(struct nand_device_s *nand, uint8_t command)
return ERROR_OK;
}
static int davinci_address(struct nand_device_s *nand, uint8_t address)
static int davinci_address(struct nand_device *nand, uint8_t address)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
if (!halted(target, "address"))
return ERROR_NAND_OPERATION_FAILED;
@@ -160,10 +156,10 @@ static int davinci_address(struct nand_device_s *nand, uint8_t address)
return ERROR_OK;
}
static int davinci_write_data(struct nand_device_s *nand, uint16_t data)
static int davinci_write_data(struct nand_device *nand, uint16_t data)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
if (!halted(target, "write_data"))
return ERROR_NAND_OPERATION_FAILED;
@@ -172,10 +168,10 @@ static int davinci_write_data(struct nand_device_s *nand, uint16_t data)
return ERROR_OK;
}
static int davinci_read_data(struct nand_device_s *nand, void *data)
static int davinci_read_data(struct nand_device *nand, void *data)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
if (!halted(target, "read_data"))
return ERROR_NAND_OPERATION_FAILED;
@@ -186,11 +182,11 @@ static int davinci_read_data(struct nand_device_s *nand, void *data)
/* REVISIT a bit of native code should let block reads be MUCH faster */
static int davinci_read_block_data(struct nand_device_s *nand,
static int davinci_read_block_data(struct nand_device *nand,
uint8_t *data, int data_size)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
uint32_t nfdata = info->data;
uint32_t tmp;
@@ -219,11 +215,11 @@ static int davinci_read_block_data(struct nand_device_s *nand,
return ERROR_OK;
}
static int davinci_write_block_data(struct nand_device_s *nand,
static int davinci_write_block_data(struct nand_device *nand,
uint8_t *data, int data_size)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
uint32_t nfdata = info->data;
uint32_t tmp;
int status;
@@ -255,7 +251,7 @@ static int davinci_write_block_data(struct nand_device_s *nand,
return ERROR_OK;
}
static int davinci_write_page(struct nand_device_s *nand, uint32_t page,
static int davinci_write_page(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
struct davinci_nand *info = nand->controller_priv;
@@ -306,7 +302,7 @@ static int davinci_write_page(struct nand_device_s *nand, uint32_t page,
return status;
}
static int davinci_read_page(struct nand_device_s *nand, uint32_t page,
static int davinci_read_page(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
struct davinci_nand *info = nand->controller_priv;
@@ -319,10 +315,10 @@ static int davinci_read_page(struct nand_device_s *nand, uint32_t page,
return info->read_page(nand, page, data, data_size, oob, oob_size);
}
static void davinci_write_pagecmd(struct nand_device_s *nand, uint8_t cmd, uint32_t page)
static void davinci_write_pagecmd(struct nand_device *nand, uint8_t cmd, uint32_t page)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
int page3 = nand->address_cycles - (nand->page_size == 512);
/* write command ({page,otp}x{read,program} */
@@ -342,11 +338,11 @@ static void davinci_write_pagecmd(struct nand_device_s *nand, uint8_t cmd, uint3
target_write_u8(target, info->addr, page >> 24);
}
static int davinci_writepage_tail(struct nand_device_s *nand,
static int davinci_writepage_tail(struct nand_device *nand,
uint8_t *oob, uint32_t oob_size)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
uint8_t status;
if (oob_size)
@@ -374,12 +370,12 @@ static int davinci_writepage_tail(struct nand_device_s *nand,
/*
* All DaVinci family chips support 1-bit ECC on a per-chipselect basis.
*/
static int davinci_write_page_ecc1(struct nand_device_s *nand, uint32_t page,
static int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
unsigned oob_offset;
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
const uint32_t fcr_addr = info->aemif + NANDFCR;
const uint32_t ecc1_addr = info->aemif + NANDFECC + (4 * info->chipsel);
uint32_t fcr, ecc1;
@@ -441,7 +437,7 @@ static int davinci_write_page_ecc1(struct nand_device_s *nand, uint32_t page,
* is read first, so its ECC data can be used incrementally), but the
* manufacturer bad block markers are safe. Contrast: old "infix" style.
*/
static int davinci_write_page_ecc4(struct nand_device_s *nand, uint32_t page,
static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
static const uint8_t ecc512[] = {
@@ -467,7 +463,7 @@ static int davinci_write_page_ecc4(struct nand_device_s *nand, uint32_t page,
struct davinci_nand *info = nand->controller_priv;
const uint8_t *l;
target_t *target = info->target;
struct target *target = info->target;
const uint32_t fcr_addr = info->aemif + NANDFCR;
const uint32_t ecc4_addr = info->aemif + NAND4BITECC;
uint32_t fcr, ecc4;
@@ -543,11 +539,11 @@ static int davinci_write_page_ecc4(struct nand_device_s *nand, uint32_t page,
* older second stage loaders (ABL/U-Boot, etc) or other system software
* (MVL 4.x/5.x kernels, filesystems, etc) may need it more generally.
*/
static int davinci_write_page_ecc4infix(struct nand_device_s *nand, uint32_t page,
static int davinci_write_page_ecc4infix(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
struct davinci_nand *info = nand->controller_priv;
target_t *target = info->target;
struct target *target = info->target;
const uint32_t fcr_addr = info->aemif + NANDFCR;
const uint32_t ecc4_addr = info->aemif + NAND4BITECC;
uint32_t fcr, ecc4;
@@ -600,7 +596,7 @@ static int davinci_write_page_ecc4infix(struct nand_device_s *nand, uint32_t pag
return davinci_writepage_tail(nand, NULL, 0);
}
static int davinci_read_page_ecc4infix(struct nand_device_s *nand, uint32_t page,
static int davinci_read_page_ecc4infix(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
davinci_write_pagecmd(nand, NAND_CMD_READ0, page);
@@ -629,16 +625,13 @@ static int davinci_read_page_ecc4infix(struct nand_device_s *nand, uint32_t page
return ERROR_OK;
}
static int davinci_nand_device_command(struct command_context_s *cmd_ctx,
char *cmd, char **argv, int argc,
struct nand_device_s *nand)
NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command)
{
struct davinci_nand *info;
target_t *target;
struct target *target;
unsigned long chip, aemif;
enum ecc eccmode;
int chipsel;
char *ep;
/* arguments:
* - "davinci"
@@ -648,39 +641,39 @@ static int davinci_nand_device_command(struct command_context_s *cmd_ctx,
* - aemif address
* Plus someday, optionally, ALE and CLE masks.
*/
if (argc < 5) {
if (CMD_ARGC < 5) {
LOG_ERROR("parameters: %s target "
"chip_addr hwecc_mode aemif_addr",
argv[0]);
CMD_ARGV[0]);
goto fail;
}
target = get_target(argv[1]);
target = get_target(CMD_ARGV[1]);
if (!target) {
LOG_ERROR("invalid target %s", argv[1]);
LOG_ERROR("invalid target %s", CMD_ARGV[1]);
goto fail;
}
chip = strtoul(argv[2], &ep, 0);
if (*ep || chip == 0 || chip == ULONG_MAX) {
LOG_ERROR("Invalid NAND chip address %s", argv[2]);
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip);
if (chip == 0) {
LOG_ERROR("Invalid NAND chip address %s", CMD_ARGV[2]);
goto fail;
}
if (strcmp(argv[3], "hwecc1") == 0)
if (strcmp(CMD_ARGV[3], "hwecc1") == 0)
eccmode = HWECC1;
else if (strcmp(argv[3], "hwecc4") == 0)
else if (strcmp(CMD_ARGV[3], "hwecc4") == 0)
eccmode = HWECC4;
else if (strcmp(argv[3], "hwecc4_infix") == 0)
else if (strcmp(CMD_ARGV[3], "hwecc4_infix") == 0)
eccmode = HWECC4_INFIX;
else {
LOG_ERROR("Invalid ecc mode %s", argv[3]);
LOG_ERROR("Invalid ecc mode %s", CMD_ARGV[3]);
goto fail;
}
aemif = strtoul(argv[4], &ep, 0);
if (*ep || aemif == 0 || aemif == ULONG_MAX) {
LOG_ERROR("Invalid AEMIF controller address %s", argv[4]);
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[4], aemif);
if (aemif == 0) {
LOG_ERROR("Invalid AEMIF controller address %s", CMD_ARGV[4]);
goto fail;
}
@@ -718,6 +711,7 @@ static int davinci_nand_device_command(struct command_context_s *cmd_ctx,
info->io.target = target;
info->io.data = info->data;
info->io.op = ARM_NAND_NONE;
/* NOTE: for now we don't do any error correction on read.
* Nothing else in OpenOCD currently corrects read errors,
@@ -747,10 +741,9 @@ fail:
return ERROR_NAND_OPERATION_FAILED;
}
nand_flash_controller_t davinci_nand_controller = {
struct nand_flash_controller davinci_nand_controller = {
.name = "davinci",
.nand_device_command = davinci_nand_device_command,
.register_commands = davinci_register_commands,
.init = davinci_init,
.reset = davinci_reset,
.command = davinci_command,

83
src/flash/nand/driver.c Normal file
View File

@@ -0,0 +1,83 @@
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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 "core.h"
#include "driver.h"
/* NAND flash controller
*/
extern struct nand_flash_controller nonce_nand_controller;
extern struct nand_flash_controller davinci_nand_controller;
extern struct nand_flash_controller lpc3180_nand_controller;
extern struct nand_flash_controller orion_nand_controller;
extern struct nand_flash_controller s3c2410_nand_controller;
extern struct nand_flash_controller s3c2412_nand_controller;
extern struct nand_flash_controller s3c2440_nand_controller;
extern struct nand_flash_controller s3c2443_nand_controller;
extern struct nand_flash_controller s3c6400_nand_controller;
extern struct nand_flash_controller imx31_nand_flash_controller;
extern struct nand_flash_controller at91sam9_nand_controller;
/* extern struct nand_flash_controller boundary_scan_nand_controller; */
static struct nand_flash_controller *nand_flash_controllers[] =
{
&nonce_nand_controller,
&davinci_nand_controller,
&lpc3180_nand_controller,
&orion_nand_controller,
&s3c2410_nand_controller,
&s3c2412_nand_controller,
&s3c2440_nand_controller,
&s3c2443_nand_controller,
&s3c6400_nand_controller,
&imx31_nand_flash_controller,
&at91sam9_nand_controller,
/* &boundary_scan_nand_controller, */
NULL
};
struct nand_flash_controller *nand_driver_find_by_name(const char *name)
{
for (unsigned i = 0; nand_flash_controllers[i]; i++)
{
struct nand_flash_controller *controller = nand_flash_controllers[i];
if (strcmp(name, controller->name) == 0)
return controller;
}
return NULL;
}
int nand_driver_walk(nand_driver_walker_t f, void *x)
{
for (unsigned i = 0; nand_flash_controllers[i]; i++)
{
int retval = (*f)(nand_flash_controllers[i], x);
if (ERROR_OK != retval)
return retval;
}
return ERROR_OK;
}

106
src/flash/nand/driver.h Normal file
View File

@@ -0,0 +1,106 @@
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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 FLASH_NAND_DRIVER_H
#define FLASH_NAND_DRIVER_H
struct nand_device;
#define __NAND_DEVICE_COMMAND(name) \
COMMAND_HELPER(name, struct nand_device *nand)
/**
* Interface for NAND flash controllers. Not all of these functions are
* required for full functionality of the NAND driver, but better performance
* can be achieved by implementing each function.
*/
struct nand_flash_controller
{
/** Driver name that is used to select it from configuration files. */
char *name;
const struct command_registration *commands;
/** NAND device command called when driver is instantiated during configuration. */
__NAND_DEVICE_COMMAND((*nand_device_command));
/** Register controller specific commands as a TCL interface to the driver. */
int (*register_commands)(struct command_context *cmd_ctx);
/** Initialize the NAND device. */
int (*init)(struct nand_device *nand);
/** Reset the NAND device. */
int (*reset)(struct nand_device *nand);
/** Issue a command to the NAND device. */
int (*command)(struct nand_device *nand, uint8_t command);
/** Write an address to the NAND device. */
int (*address)(struct nand_device *nand, uint8_t address);
/** Write word of data to the NAND device. */
int (*write_data)(struct nand_device *nand, uint16_t data);
/** Read word of data from the NAND device. */
int (*read_data)(struct nand_device *nand, void *data);
/** Write a block of data to the NAND device. */
int (*write_block_data)(struct nand_device *nand, uint8_t *data, int size);
/** Read a block of data from the NAND device. */
int (*read_block_data)(struct nand_device *nand, uint8_t *data, int size);
/** Write a page to the NAND device. */
int (*write_page)(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
/** Read a page from the NAND device. */
int (*read_page)(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
/** Check if the controller is ready for more instructions with timeout. */
int (*controller_ready)(struct nand_device *nand, int timeout);
/** Check if the NAND device is ready for more instructions with timeout. */
int (*nand_ready)(struct nand_device *nand, int timeout);
};
#define NAND_DEVICE_COMMAND_HANDLER(name) static __NAND_DEVICE_COMMAND(name)
/**
* Find a NAND flash controller by name.
* @param name Identifies the NAND controller to find.
* @returns The nand_flash_controller named @c name, or NULL if not found.
*/
struct nand_flash_controller *nand_driver_find_by_name(const char *name);
/// Signature for callback functions passed to nand_driver_walk
typedef int (*nand_driver_walker_t)(struct nand_flash_controller *c, void*);
/**
* Walk the list of drivers, encapsulating the data structure type.
* Application state/context can be passed through the @c x pointer.
* @param f The callback function to invoke for each function.
* @param x For use as private data storate, passed directly to @c f.
* @returns ERROR_OK if successful, or the non-zero return value of @c f.
* This allows a walker to terminate the loop early.
*/
int nand_driver_walk(nand_driver_walker_t f, void *x);
#endif // FLASH_NAND_DRIVER_H

View File

@@ -41,7 +41,7 @@
#include "config.h"
#endif
#include "nand.h"
#include "core.h"
/*
* Pre-calculated 256-way 1 byte column parity
@@ -68,7 +68,7 @@ static const uint8_t nand_ecc_precalc_table[] = {
/*
* nand_calculate_ecc - Calculate 3-byte ECC for 256-byte block
*/
int nand_calculate_ecc(struct nand_device_s *device, const uint8_t *dat, uint8_t *ecc_code)
int nand_calculate_ecc(struct nand_device *nand, const uint8_t *dat, uint8_t *ecc_code)
{
uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
int i;

View File

@@ -20,9 +20,7 @@
#include "config.h"
#endif
#include <sys/types.h>
#include "nand.h"
#include "core.h"
/*****************************************************************************
* Arithmetic in GF(2^10) ("F") modulo x^10 + x^3 + 1.
@@ -100,7 +98,7 @@ static void gf_build_log_exp_table(void)
* expects the ECC to be computed backward, i.e. from the last byte down
* to the first one.
*/
int nand_calculate_ecc_kw(struct nand_device_s *device, const uint8_t *data, uint8_t *ecc)
int nand_calculate_ecc_kw(struct nand_device *nand, const uint8_t *data, uint8_t *ecc)
{
unsigned int r7, r6, r5, r4, r3, r2, r1, r0;
int i;

244
src/flash/nand/fileio.c Normal file
View File

@@ -0,0 +1,244 @@
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* Partially based on drivers/mtd/nand_ids.c from Linux. *
* *
* 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 "core.h"
#include "fileio.h"
static struct nand_ecclayout nand_oob_16 = {
.eccbytes = 6,
.eccpos = {0, 1, 2, 3, 6, 7},
.oobfree = {
{.offset = 8,
. length = 8}}
};
static struct nand_ecclayout nand_oob_64 = {
.eccbytes = 24,
.eccpos = {
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63},
.oobfree = {
{.offset = 2,
.length = 38}}
};
void nand_fileio_init(struct nand_fileio_state *state)
{
memset(state, 0, sizeof(*state));
state->oob_format = NAND_OOB_NONE;
}
int nand_fileio_start(struct command_context *cmd_ctx,
struct nand_device *nand, const char *filename, int filemode,
struct nand_fileio_state *state)
{
if (state->address % nand->page_size)
{
command_print(cmd_ctx, "only page-aligned addresses are supported");
return ERROR_COMMAND_SYNTAX_ERROR;
}
duration_start(&state->bench);
if (NULL != filename)
{
int retval = fileio_open(&state->fileio, filename, filemode, FILEIO_BINARY);
if (ERROR_OK != retval)
{
const char *msg = (FILEIO_READ == filemode) ? "read" : "write";
command_print(cmd_ctx, "failed to open '%s' for %s access",
filename, msg);
return retval;
}
state->file_opened = true;
}
if (!(state->oob_format & NAND_OOB_ONLY))
{
state->page_size = nand->page_size;
state->page = malloc(nand->page_size);
}
if (state->oob_format & (NAND_OOB_RAW | NAND_OOB_SW_ECC | NAND_OOB_SW_ECC_KW))
{
if (nand->page_size == 512)
{
state->oob_size = 16;
state->eccpos = nand_oob_16.eccpos;
}
else if (nand->page_size == 2048)
{
state->oob_size = 64;
state->eccpos = nand_oob_64.eccpos;
}
state->oob = malloc(state->oob_size);
}
return ERROR_OK;
}
int nand_fileio_cleanup(struct nand_fileio_state *state)
{
if (state->file_opened)
fileio_close(&state->fileio);
if (state->oob)
{
free(state->oob);
state->oob = NULL;
}
if (state->page)
{
free(state->page);
state->page = NULL;
}
return ERROR_OK;
}
int nand_fileio_finish(struct nand_fileio_state *state)
{
nand_fileio_cleanup(state);
return duration_measure(&state->bench);
}
COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state,
struct nand_device **dev, enum fileio_access filemode,
bool need_size, bool sw_ecc)
{
nand_fileio_init(state);
unsigned minargs = need_size ? 4 : 3;
if (CMD_ARGC < minargs)
return ERROR_COMMAND_SYNTAX_ERROR;
struct nand_device *nand;
int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &nand);
if (ERROR_OK != retval)
return retval;
if (NULL == nand->device)
{
command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]);
return ERROR_OK;
}
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], state->address);
if (need_size)
{
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], state->size);
if (state->size % nand->page_size)
{
command_print(CMD_CTX, "only page-aligned sizes are supported");
return ERROR_COMMAND_SYNTAX_ERROR;
}
}
if (CMD_ARGC > minargs)
{
for (unsigned i = minargs; i < CMD_ARGC; i++)
{
if (!strcmp(CMD_ARGV[i], "oob_raw"))
state->oob_format |= NAND_OOB_RAW;
else if (!strcmp(CMD_ARGV[i], "oob_only"))
state->oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;
else if (sw_ecc && !strcmp(CMD_ARGV[i], "oob_softecc"))
state->oob_format |= NAND_OOB_SW_ECC;
else if (sw_ecc && !strcmp(CMD_ARGV[i], "oob_softecc_kw"))
state->oob_format |= NAND_OOB_SW_ECC_KW;
else
{
command_print(CMD_CTX, "unknown option: %s", CMD_ARGV[i]);
return ERROR_COMMAND_SYNTAX_ERROR;
}
}
}
retval = nand_fileio_start(CMD_CTX, nand, CMD_ARGV[1], filemode, state);
if (ERROR_OK != retval)
return retval;
if (!need_size)
state->size = state->fileio.size;
*dev = nand;
return ERROR_OK;
}
/**
* @returns If no error occurred, returns number of bytes consumed;
* otherwise, returns a negative error code.)
*/
int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s)
{
size_t total_read = 0;
size_t one_read;
if (NULL != s->page)
{
fileio_read(&s->fileio, s->page_size, s->page, &one_read);
if (one_read < s->page_size)
memset(s->page + one_read, 0xff, s->page_size - one_read);
total_read += one_read;
}
if (s->oob_format & NAND_OOB_SW_ECC)
{
uint8_t ecc[3];
memset(s->oob, 0xff, s->oob_size);
for (uint32_t i = 0, j = 0; i < s->page_size; i += 256)
{
nand_calculate_ecc(nand, s->page + i, ecc);
s->oob[s->eccpos[j++]] = ecc[0];
s->oob[s->eccpos[j++]] = ecc[1];
s->oob[s->eccpos[j++]] = ecc[2];
}
}
else if (s->oob_format & NAND_OOB_SW_ECC_KW)
{
/*
* In this case eccpos is not used as
* the ECC data is always stored contigously
* at the end of the OOB area. It consists
* of 10 bytes per 512-byte data block.
*/
uint8_t *ecc = s->oob + s->oob_size - s->page_size / 512 * 10;
memset(s->oob, 0xff, s->oob_size);
for (uint32_t i = 0; i < s->page_size; i += 512)
{
nand_calculate_ecc_kw(nand, s->page + i, ecc);
ecc += 10;
}
}
else if (NULL != s->oob)
{
fileio_read(&s->fileio, s->oob_size, s->oob, &one_read);
if (one_read < s->oob_size)
memset(s->oob + one_read, 0xff, s->oob_size - one_read);
total_read += one_read;
}
return total_read;
}

57
src/flash/nand/fileio.h Normal file
View File

@@ -0,0 +1,57 @@
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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 FLASH_NAND_FILEIO_H
#define FLASH_NAND_FILEIO_H
#include <helper/time_support.h>
#include <helper/fileio.h>
struct nand_fileio_state {
uint32_t address;
uint32_t size;
uint8_t *page;
uint32_t page_size;
enum oob_formats oob_format;
uint8_t *oob;
uint32_t oob_size;
const int *eccpos;
bool file_opened;
struct fileio fileio;
struct duration bench;
};
void nand_fileio_init(struct nand_fileio_state *state);
int nand_fileio_start(struct command_context *cmd_ctx,
struct nand_device *nand, const char *filename, int filemode,
struct nand_fileio_state *state);
int nand_fileio_cleanup(struct nand_fileio_state *state);
int nand_fileio_finish(struct nand_fileio_state *state);
COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state,
struct nand_device **dev, enum fileio_access filemode,
bool need_size, bool sw_ecc);
int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s);
#endif // FLASH_NAND_FILEIO_H

39
src/flash/nand/imp.h Normal file
View File

@@ -0,0 +1,39 @@
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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 FLASH_NAND_IMP_H
#define FLASH_NAND_IMP_H
#include "core.h"
#include "driver.h"
void nand_device_add(struct nand_device *c);
int nand_write_page(struct nand_device *nand,
uint32_t page, uint8_t *data, uint32_t data_size,
uint8_t *oob, uint32_t oob_size);
int nand_read_page(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size,
uint8_t *oob, uint32_t oob_size);
int nand_probe(struct nand_device *nand);
int nand_erase(struct nand_device *nand, int first_block, int last_block);
int nand_build_bbt(struct nand_device *nand, int first, int last);
#endif // FLASH_NAND_IMP_H

View File

@@ -21,64 +21,41 @@
#include "config.h"
#endif
#include "lpc3180_nand_controller.h"
#include "nand.h"
#include "imp.h"
#include "lpc3180.h"
#include <target/target.h>
static int lpc3180_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);
static int lpc3180_register_commands(struct command_context_s *cmd_ctx);
static int lpc3180_init(struct nand_device_s *device);
static int lpc3180_reset(struct nand_device_s *device);
static int lpc3180_command(struct nand_device_s *device, uint8_t command);
static int lpc3180_address(struct nand_device_s *device, uint8_t address);
static int lpc3180_write_data(struct nand_device_s *device, uint16_t data);
static int lpc3180_read_data(struct nand_device_s *device, void *data);
static int lpc3180_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 lpc3180_read_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 lpc3180_controller_ready(struct nand_device_s *device, int timeout);
static int lpc3180_nand_ready(struct nand_device_s *device, int timeout);
static int handle_lpc3180_select_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
nand_flash_controller_t lpc3180_nand_controller =
{
.name = "lpc3180",
.nand_device_command = lpc3180_nand_device_command,
.register_commands = lpc3180_register_commands,
.init = lpc3180_init,
.reset = lpc3180_reset,
.command = lpc3180_command,
.address = lpc3180_address,
.write_data = lpc3180_write_data,
.read_data = lpc3180_read_data,
.write_page = lpc3180_write_page,
.read_page = lpc3180_read_page,
.controller_ready = lpc3180_controller_ready,
.nand_ready = lpc3180_nand_ready,
};
static int lpc3180_reset(struct nand_device *nand);
static int lpc3180_controller_ready(struct nand_device *nand, int timeout);
/* nand device lpc3180 <target#> <oscillator_frequency>
*/
static int lpc3180_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device)
NAND_DEVICE_COMMAND_HANDLER(lpc3180_nand_device_command)
{
lpc3180_nand_controller_t *lpc3180_info;
if (argc < 3)
if (CMD_ARGC < 3)
{
LOG_WARNING("incomplete 'lpc3180' nand flash configuration");
return ERROR_FLASH_BANK_INVALID;
}
lpc3180_info = malloc(sizeof(lpc3180_nand_controller_t));
device->controller_priv = lpc3180_info;
lpc3180_info->target = get_target(args[1]);
if (!lpc3180_info->target)
struct target *target = get_target(CMD_ARGV[1]);
if (NULL == target)
{
LOG_ERROR("target '%s' not defined", args[1]);
LOG_ERROR("target '%s' not defined", CMD_ARGV[1]);
return ERROR_NAND_DEVICE_INVALID;
}
lpc3180_info->osc_freq = strtoul(args[2], NULL, 0);
uint32_t osc_freq;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], osc_freq);
struct lpc3180_nand_controller *lpc3180_info;
lpc3180_info = malloc(sizeof(struct lpc3180_nand_controller));
nand->controller_priv = lpc3180_info;
lpc3180_info->target = target;
lpc3180_info->osc_freq = osc_freq;
if ((lpc3180_info->osc_freq < 1000) || (lpc3180_info->osc_freq > 20000))
{
LOG_WARNING("LPC3180 oscillator frequency should be between 1000 and 20000 kHz, was %i", lpc3180_info->osc_freq);
@@ -91,15 +68,6 @@ static int lpc3180_nand_device_command(struct command_context_s *cmd_ctx, char *
return ERROR_OK;
}
static int lpc3180_register_commands(struct command_context_s *cmd_ctx)
{
command_t *lpc3180_cmd = register_command(cmd_ctx, NULL, "lpc3180", NULL, COMMAND_ANY, "commands specific to the LPC3180 NAND flash controllers");
register_command(cmd_ctx, lpc3180_cmd, "select", handle_lpc3180_select_command, COMMAND_EXEC, "select <'mlc'|'slc'> controller (default is mlc)");
return ERROR_OK;
}
static int lpc3180_pll(int fclkin, uint32_t pll_ctrl)
{
int bypass = (pll_ctrl & 0x8000) >> 15;
@@ -128,9 +96,9 @@ static int lpc3180_pll(int fclkin, uint32_t pll_ctrl)
return (m / (2 * p)) * (fclkin / n);
}
static float lpc3180_cycle_time(lpc3180_nand_controller_t *lpc3180_info)
static float lpc3180_cycle_time(struct lpc3180_nand_controller *lpc3180_info)
{
target_t *target = lpc3180_info->target;
struct target *target = lpc3180_info->target;
uint32_t sysclk_ctrl, pwr_ctrl, hclkdiv_ctrl, hclkpll_ctrl;
int sysclk;
int hclk;
@@ -178,13 +146,13 @@ static float lpc3180_cycle_time(lpc3180_nand_controller_t *lpc3180_info)
return cycle;
}
static int lpc3180_init(struct nand_device_s *device)
static int lpc3180_init(struct nand_device *nand)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
int bus_width = (device->bus_width) ? (device->bus_width) : 8;
int address_cycles = (device->address_cycles) ? (device->address_cycles) : 3;
int page_size = (device->page_size) ? (device->page_size) : 512;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
int bus_width = nand->bus_width ? : 8;
int address_cycles = nand->address_cycles ? : 3;
int page_size = nand->page_size ? : 512;
if (target->state != TARGET_HALTED)
{
@@ -208,7 +176,7 @@ static int lpc3180_init(struct nand_device_s *device)
}
/* inform calling code about selected bus width */
device->bus_width = bus_width;
nand->bus_width = bus_width;
if ((address_cycles != 3) && (address_cycles != 4))
{
@@ -274,7 +242,7 @@ static int lpc3180_init(struct nand_device_s *device)
((trp & 0xf) << 8) | ((treh & 0xf) << 12) | ((trhz & 0x7) << 16) |
((trbwb & 0x1f) << 19) | ((tcea & 0x3) << 24));
lpc3180_reset(device);
lpc3180_reset(nand);
}
else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
{
@@ -302,16 +270,16 @@ static int lpc3180_init(struct nand_device_s *device)
((r_width & 0xf) << 8) | ((r_rdy & 0xf) << 12) | ((w_setup & 0xf) << 16) |
((w_hold & 0xf) << 20) | ((w_width & 0xf) << 24) | ((w_rdy & 0xf) << 28));
lpc3180_reset(device);
lpc3180_reset(nand);
}
return ERROR_OK;
}
static int lpc3180_reset(struct nand_device_s *device)
static int lpc3180_reset(struct nand_device *nand)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
if (target->state != TARGET_HALTED)
{
@@ -329,7 +297,7 @@ static int lpc3180_reset(struct nand_device_s *device)
/* MLC_CMD = 0xff (reset controller and NAND device) */
target_write_u32(target, 0x200b8000, 0xff);
if (!lpc3180_controller_ready(device, 100))
if (!lpc3180_controller_ready(nand, 100))
{
LOG_ERROR("LPC3180 NAND controller timed out after reset");
return ERROR_NAND_OPERATION_TIMEOUT;
@@ -340,7 +308,7 @@ static int lpc3180_reset(struct nand_device_s *device)
/* SLC_CTRL = 0x6 (ECC_CLEAR, SW_RESET) */
target_write_u32(target, 0x20020010, 0x6);
if (!lpc3180_controller_ready(device, 100))
if (!lpc3180_controller_ready(nand, 100))
{
LOG_ERROR("LPC3180 NAND controller timed out after reset");
return ERROR_NAND_OPERATION_TIMEOUT;
@@ -350,10 +318,10 @@ static int lpc3180_reset(struct nand_device_s *device)
return ERROR_OK;
}
static int lpc3180_command(struct nand_device_s *device, uint8_t command)
static int lpc3180_command(struct nand_device *nand, uint8_t command)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
if (target->state != TARGET_HALTED)
{
@@ -380,10 +348,10 @@ static int lpc3180_command(struct nand_device_s *device, uint8_t command)
return ERROR_OK;
}
static int lpc3180_address(struct nand_device_s *device, uint8_t address)
static int lpc3180_address(struct nand_device *nand, uint8_t address)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
if (target->state != TARGET_HALTED)
{
@@ -410,10 +378,10 @@ static int lpc3180_address(struct nand_device_s *device, uint8_t address)
return ERROR_OK;
}
static int lpc3180_write_data(struct nand_device_s *device, uint16_t data)
static int lpc3180_write_data(struct nand_device *nand, uint16_t data)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
if (target->state != TARGET_HALTED)
{
@@ -440,10 +408,10 @@ static int lpc3180_write_data(struct nand_device_s *device, uint16_t data)
return ERROR_OK;
}
static int lpc3180_read_data(struct nand_device_s *device, void *data)
static int lpc3180_read_data(struct nand_device *nand, void *data)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
if (target->state != TARGET_HALTED)
{
@@ -459,12 +427,12 @@ static int lpc3180_read_data(struct nand_device_s *device, void *data)
else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
{
/* data = MLC_DATA, use sized access */
if (device->bus_width == 8)
if (nand->bus_width == 8)
{
uint8_t *data8 = data;
target_read_u8(target, 0x200b0000, data8);
}
else if (device->bus_width == 16)
else if (nand->bus_width == 16)
{
uint16_t *data16 = data;
target_read_u16(target, 0x200b0000, data16);
@@ -482,12 +450,12 @@ static int lpc3180_read_data(struct nand_device_s *device, void *data)
/* data = SLC_DATA, must use 32-bit access */
target_read_u32(target, 0x20020000, &data32);
if (device->bus_width == 8)
if (nand->bus_width == 8)
{
uint8_t *data8 = data;
*data8 = data32 & 0xff;
}
else if (device->bus_width == 16)
else if (nand->bus_width == 16)
{
uint16_t *data16 = data;
*data16 = data32 & 0xffff;
@@ -502,10 +470,10 @@ static int lpc3180_read_data(struct nand_device_s *device, void *data)
return ERROR_OK;
}
static int lpc3180_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 lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
int retval;
uint8_t status;
@@ -532,13 +500,14 @@ static int lpc3180_write_page(struct nand_device_s *device, uint32_t page, uint8
return ERROR_NAND_OPERATION_NOT_SUPPORTED;
}
if (oob && (oob_size > 6))
if (oob && (oob_size > 24))
{
LOG_ERROR("LPC3180 MLC controller can't write more than 6 bytes of OOB data");
LOG_ERROR("LPC3180 MLC controller can't write more "
"than 6 bytes for each quarter's OOB data");
return ERROR_NAND_OPERATION_NOT_SUPPORTED;
}
if (data_size > (uint32_t)device->page_size)
if (data_size > (uint32_t)nand->page_size)
{
LOG_ERROR("data size exceeds page size");
return ERROR_NAND_OPERATION_NOT_SUPPORTED;
@@ -550,7 +519,7 @@ static int lpc3180_write_page(struct nand_device_s *device, uint32_t page, uint8
page_buffer = malloc(512);
oob_buffer = malloc(6);
if (device->page_size == 512)
if (nand->page_size == 512)
{
/* MLC_ADDR = 0x0 (one column cycle) */
target_write_u32(target, 0x200b8004, 0x0);
@@ -559,7 +528,7 @@ static int lpc3180_write_page(struct nand_device_s *device, uint32_t page, uint8
target_write_u32(target, 0x200b8004, page & 0xff);
target_write_u32(target, 0x200b8004, (page >> 8) & 0xff);
if (device->address_cycles == 4)
if (nand->address_cycles == 4)
target_write_u32(target, 0x200b8004, (page >> 16) & 0xff);
}
else
@@ -576,7 +545,7 @@ static int lpc3180_write_page(struct nand_device_s *device, uint32_t page, uint8
/* when using the MLC controller, we have to treat a large page device
* as being made out of four quarters, each the size of a small page device
*/
num_quarters = (device->page_size == 2048) ? 4 : 1;
num_quarters = (nand->page_size == 2048) ? 4 : 1;
for (quarter = 0; quarter < num_quarters; quarter++)
{
@@ -591,10 +560,10 @@ static int lpc3180_write_page(struct nand_device_s *device, uint32_t page, uint8
data += thisrun_data_size;
}
memset(oob_buffer, 0xff, (device->page_size == 512) ? 6 : 24);
memset(oob_buffer, 0xff, 6);
if (oob)
{
memcpy(page_buffer, oob, thisrun_oob_size);
memcpy(oob_buffer, oob, thisrun_oob_size);
oob_size -= thisrun_oob_size;
oob += thisrun_oob_size;
}
@@ -602,13 +571,15 @@ static int lpc3180_write_page(struct nand_device_s *device, uint32_t page, uint8
/* write MLC_ECC_ENC_REG to start encode cycle */
target_write_u32(target, 0x200b8008, 0x0);
target_write_memory(target, 0x200a8000, 4, 128, page_buffer + (quarter * 512));
target_write_memory(target, 0x200a8000, 1, 6, oob_buffer + (quarter * 6));
target_write_memory(target, 0x200a8000,
4, 128, page_buffer);
target_write_memory(target, 0x200a8000,
1, 6, oob_buffer);
/* write MLC_ECC_AUTO_ENC_REG to start auto encode */
target_write_u32(target, 0x200b8010, 0x0);
if (!lpc3180_controller_ready(device, 1000))
if (!lpc3180_controller_ready(nand, 1000))
{
LOG_ERROR("timeout while waiting for completion of auto encode cycle");
return ERROR_NAND_OPERATION_FAILED;
@@ -618,7 +589,7 @@ static int lpc3180_write_page(struct nand_device_s *device, uint32_t page, uint8
/* MLC_CMD = auto program command */
target_write_u32(target, 0x200b8000, NAND_CMD_PAGEPROG);
if ((retval = nand_read_status(device, &status)) != ERROR_OK)
if ((retval = nand_read_status(nand, &status)) != ERROR_OK)
{
LOG_ERROR("couldn't read status");
return ERROR_NAND_OPERATION_FAILED;
@@ -635,16 +606,16 @@ static int lpc3180_write_page(struct nand_device_s *device, uint32_t page, uint8
}
else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
{
return nand_write_page_raw(device, page, data, data_size, oob, oob_size);
return nand_write_page_raw(nand, page, data, data_size, oob, oob_size);
}
return ERROR_OK;
}
static int lpc3180_read_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 lpc3180_read_page(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
if (target->state != TARGET_HALTED)
{
@@ -673,13 +644,13 @@ static int lpc3180_read_page(struct nand_device_s *device, uint32_t page, uint8_
}
#endif
if (data_size > (uint32_t)device->page_size)
if (data_size > (uint32_t)nand->page_size)
{
LOG_ERROR("data size exceeds page size");
return ERROR_NAND_OPERATION_NOT_SUPPORTED;
}
if (device->page_size == 2048)
if (nand->page_size == 2048)
{
page_buffer = malloc(2048);
oob_buffer = malloc(64);
@@ -705,7 +676,7 @@ static int lpc3180_read_page(struct nand_device_s *device, uint32_t page, uint8_
target_write_u32(target, 0x200b8000, NAND_CMD_READ0);
}
if (device->page_size == 512)
if (nand->page_size == 512)
{
/* small page device */
/* MLC_ADDR = 0x0 (one column cycle) */
@@ -715,7 +686,7 @@ static int lpc3180_read_page(struct nand_device_s *device, uint32_t page, uint8_
target_write_u32(target, 0x200b8004, page & 0xff);
target_write_u32(target, 0x200b8004, (page >> 8) & 0xff);
if (device->address_cycles == 4)
if (nand->address_cycles == 4)
target_write_u32(target, 0x200b8004, (page >> 16) & 0xff);
}
else
@@ -733,12 +704,12 @@ static int lpc3180_read_page(struct nand_device_s *device, uint32_t page, uint8_
target_write_u32(target, 0x200b8000, NAND_CMD_READSTART);
}
while (page_bytes_done < (uint32_t)device->page_size)
while (page_bytes_done < (uint32_t)nand->page_size)
{
/* MLC_ECC_AUTO_DEC_REG = dummy */
target_write_u32(target, 0x200b8014, 0xaa55aa55);
if (!lpc3180_controller_ready(device, 1000))
if (!lpc3180_controller_ready(nand, 1000))
{
LOG_ERROR("timeout while waiting for completion of auto decode cycle");
return ERROR_NAND_OPERATION_FAILED;
@@ -782,17 +753,16 @@ static int lpc3180_read_page(struct nand_device_s *device, uint32_t page, uint8_
}
else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
{
return nand_read_page_raw(device, page, data, data_size, oob, oob_size);
return nand_read_page_raw(nand, page, data, data_size, oob, oob_size);
}
return ERROR_OK;
}
static int lpc3180_controller_ready(struct nand_device_s *device, int timeout)
static int lpc3180_controller_ready(struct nand_device *nand, int timeout)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
uint8_t status = 0x0;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
if (target->state != TARGET_HALTED)
{
@@ -800,20 +770,35 @@ static int lpc3180_controller_ready(struct nand_device_s *device, int timeout)
return ERROR_NAND_OPERATION_FAILED;
}
LOG_DEBUG("lpc3180_controller_ready count start=%d", timeout);
do
{
if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
{
uint8_t status;
/* Read MLC_ISR, wait for controller to become ready */
target_read_u8(target, 0x200b8048, &status);
if (status & 2)
if (status & 2) {
LOG_DEBUG("lpc3180_controller_ready count=%d",
timeout);
return 1;
}
}
else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
{
/* we pretend that the SLC controller is always ready */
return 1;
uint32_t status;
/* Read SLC_STAT and check READY bit */
target_read_u32(target, 0x20020018, &status);
if (status & 1) {
LOG_DEBUG("lpc3180_controller_ready count=%d",
timeout);
return 1;
}
}
alive_sleep(1);
@@ -822,10 +807,10 @@ static int lpc3180_controller_ready(struct nand_device_s *device, int timeout)
return 0;
}
static int lpc3180_nand_ready(struct nand_device_s *device, int timeout)
static int lpc3180_nand_ready(struct nand_device *nand, int timeout)
{
lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
target_t *target = lpc3180_info->target;
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
if (target->state != TARGET_HALTED)
{
@@ -833,6 +818,8 @@ static int lpc3180_nand_ready(struct nand_device_s *device, int timeout)
return ERROR_NAND_OPERATION_FAILED;
}
LOG_DEBUG("lpc3180_nand_ready count start=%d", timeout);
do
{
if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
@@ -842,8 +829,11 @@ static int lpc3180_nand_ready(struct nand_device_s *device, int timeout)
/* Read MLC_ISR, wait for NAND flash device to become ready */
target_read_u8(target, 0x200b8048, &status);
if (status & 1)
if (status & 1) {
LOG_DEBUG("lpc3180_nand_ready count end=%d",
timeout);
return 1;
}
}
else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
{
@@ -852,8 +842,11 @@ static int lpc3180_nand_ready(struct nand_device_s *device, int timeout)
/* Read SLC_STAT and check READY bit */
target_read_u32(target, 0x20020018, &status);
if (status & 1)
if (status & 1) {
LOG_DEBUG("lpc3180_nand_ready count end=%d",
timeout);
return 1;
}
}
alive_sleep(1);
@@ -862,36 +855,37 @@ static int lpc3180_nand_ready(struct nand_device_s *device, int timeout)
return 0;
}
static int handle_lpc3180_select_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(handle_lpc3180_select_command)
{
nand_device_t *device = NULL;
lpc3180_nand_controller_t *lpc3180_info = NULL;
struct lpc3180_nand_controller *lpc3180_info = NULL;
char *selected[] =
{
"no", "mlc", "slc"
};
if ((argc < 1) || (argc > 2))
if ((CMD_ARGC < 1) || (CMD_ARGC > 2))
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
device = get_nand_device_by_num(strtoul(args[0], NULL, 0));
if (!device)
unsigned num;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
struct nand_device *nand = get_nand_device_by_num(num);
if (!nand)
{
command_print(cmd_ctx, "nand device '#%s' is out of bounds", args[0]);
command_print(CMD_CTX, "nand device '#%s' is out of bounds", CMD_ARGV[0]);
return ERROR_OK;
}
lpc3180_info = device->controller_priv;
lpc3180_info = nand->controller_priv;
if (argc == 2)
if (CMD_ARGC == 2)
{
if (strcmp(args[1], "mlc") == 0)
if (strcmp(CMD_ARGV[1], "mlc") == 0)
{
lpc3180_info->selected_controller = LPC3180_MLC_CONTROLLER;
}
else if (strcmp(args[1], "slc") == 0)
else if (strcmp(CMD_ARGV[1], "slc") == 0)
{
lpc3180_info->selected_controller = LPC3180_SLC_CONTROLLER;
}
@@ -901,7 +895,43 @@ static int handle_lpc3180_select_command(struct command_context_s *cmd_ctx, char
}
}
command_print(cmd_ctx, "%s controller selected", selected[lpc3180_info->selected_controller]);
command_print(CMD_CTX, "%s controller selected", selected[lpc3180_info->selected_controller]);
return ERROR_OK;
}
static const struct command_registration lpc3180_exec_command_handlers[] = {
{
.name = "select",
.handler = handle_lpc3180_select_command,
.mode = COMMAND_EXEC,
.help = "select MLC or SLC controller (default is MLC)",
.usage = "bank_id ['mlc'|'slc']",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration lpc3180_command_handler[] = {
{
.name = "lpc3180",
.mode = COMMAND_ANY,
.help = "LPC3180 NAND flash controller commands",
.chain = lpc3180_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
struct nand_flash_controller lpc3180_nand_controller = {
.name = "lpc3180",
.commands = lpc3180_command_handler,
.nand_device_command = lpc3180_nand_device_command,
.init = lpc3180_init,
.reset = lpc3180_reset,
.command = lpc3180_command,
.address = lpc3180_address,
.write_data = lpc3180_write_data,
.read_data = lpc3180_read_data,
.write_page = lpc3180_write_page,
.read_page = lpc3180_read_page,
.controller_ready = lpc3180_controller_ready,
.nand_ready = lpc3180_nand_ready,
};

View File

@@ -20,8 +20,6 @@
#ifndef LPC3180_NAND_CONTROLLER_H
#define LPC3180_NAND_CONTROLLER_H
#include "target.h"
enum lpc3180_selected_controller
{
LPC3180_NO_CONTROLLER,
@@ -29,14 +27,14 @@ enum lpc3180_selected_controller
LPC3180_SLC_CONTROLLER,
};
typedef struct lpc3180_nand_controller_s
struct lpc3180_nand_controller
{
struct target_s *target;
struct target *target;
int osc_freq;
enum lpc3180_selected_controller selected_controller;
int sw_write_protection;
uint32_t sw_wp_lower_bound;
uint32_t sw_wp_upper_bound;
} lpc3180_nand_controller_t;
};
#endif /*LPC3180_NAND_CONTROLLER_H */

View File

@@ -35,7 +35,9 @@ get_next_halfword_from_sram_buffer() not tested
#include "config.h"
#endif
#include "mx3_nand.h"
#include "imp.h"
#include "mx3.h"
#include <target/target.h>
static const char target_not_halted_err_msg[] =
"target must be halted to use mx3 NAND flash controller";
@@ -47,72 +49,39 @@ 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,
static int test_iomux_settings (struct target * 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,
static int initialize_nf_controller (struct nand_device *nand);
static int get_next_byte_from_sram_buffer (struct target * target, uint8_t * value);
static int get_next_halfword_from_sram_buffer (struct target * 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 poll_for_complete_op (struct target * target, const char *text);
static int validate_target_state (struct nand_device *nand);
static int do_data_output (struct nand_device *nand);
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);
static int imx31_command (struct nand_device *nand, uint8_t command);
static int imx31_address (struct nand_device *nand, uint8_t address);
static int imx31_controller_ready (struct nand_device *nand, int tout);
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)
NAND_DEVICE_COMMAND_HANDLER(imx31_nand_device_command)
{
mx3_nf_controller_t *mx3_nf_info;
mx3_nf_info = malloc (sizeof (mx3_nf_controller_t));
struct mx3_nf_controller *mx3_nf_info;
mx3_nf_info = malloc (sizeof (struct mx3_nf_controller));
if (mx3_nf_info == NULL)
{
LOG_ERROR ("no memory for nand controller");
return ERROR_FAIL;
}
device->controller_priv = mx3_nf_info;
nand->controller_priv = mx3_nf_info;
mx3_nf_info->target = get_target (args[1]);
mx3_nf_info->target = get_target (CMD_ARGV[1]);
if (mx3_nf_info->target == NULL)
{
LOG_ERROR ("target '%s' not defined", args[1]);
LOG_ERROR ("target '%s' not defined", CMD_ARGV[1]);
return ERROR_FAIL;
}
if (argc < 3)
if (CMD_ARGC < 3)
{
LOG_ERROR ("use \"nand device imx31 target noecc|hwecc\"");
return ERROR_FAIL;
@@ -122,7 +91,7 @@ static int imx31_nand_device_command (struct command_context_s *cmd_ctx,
*/
{
int hwecc_needed;
hwecc_needed = strcmp (args[2], "hwecc");
hwecc_needed = strcmp (CMD_ARGV[2], "hwecc");
if (hwecc_needed == 0)
{
mx3_nf_info->flags.hw_ecc_enabled = 1;
@@ -154,17 +123,17 @@ static int imx31_nand_device_command (struct command_context_s *cmd_ctx,
return ERROR_OK;
}
static int imx31_init (struct nand_device_s *device)
static int imx31_init (struct nand_device *nand)
{
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
target_t *target = mx3_nf_info->target;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
{
/*
* validate target state
*/
int validate_target_result;
validate_target_result = validate_target_state (device);
validate_target_result = validate_target_state(nand);
if (validate_target_result != ERROR_OK)
{
return validate_target_result;
@@ -180,30 +149,30 @@ static int imx31_init (struct nand_device_s *device)
{
uint32_t pcsr_register_content;
target_read_u32 (target, MX3_PCSR, &pcsr_register_content);
if (!device->bus_width)
if (!nand->bus_width)
{
device->bus_width =
nand->bus_width =
(pcsr_register_content & 0x80000000) ? 16 : 8;
}
else
{
pcsr_register_content |=
((device->bus_width == 16) ? 0x80000000 : 0x00000000);
((nand->bus_width == 16) ? 0x80000000 : 0x00000000);
target_write_u32 (target, MX3_PCSR, pcsr_register_content);
}
if (!device->page_size)
if (!nand->page_size)
{
device->page_size =
nand->page_size =
(pcsr_register_content & 0x40000000) ? 2048 : 512;
}
else
{
pcsr_register_content |=
((device->page_size == 2048) ? 0x40000000 : 0x00000000);
((nand->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))
if (mx3_nf_info->flags.one_kb_sram && (nand->page_size == 2048))
{
LOG_ERROR
("NAND controller have only 1 kb SRAM, so pagesize 2048 is incompatible with it");
@@ -243,7 +212,7 @@ static int imx31_init (struct nand_device_s *device)
test_iomux_settings (target, 0x43fac0c4, 0x7f7f7f7f, "d3,d4,d5,d6");
test_iomux |=
test_iomux_settings (target, 0x43fac0c8, 0x0000007f, "d7");
if (device->bus_width == 16)
if (nand->bus_width == 16)
{
test_iomux |=
test_iomux_settings (target, 0x43fac0c8, 0x7f7f7f00,
@@ -266,15 +235,15 @@ static int imx31_init (struct nand_device_s *device)
}
}
initialize_nf_controller (device);
initialize_nf_controller (nand);
{
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);
retval |= imx31_command (nand, NAND_CMD_STATUS);
retval |= imx31_address (nand, 0x00);
retval |= do_data_output (nand);
if (retval != ERROR_OK)
{
LOG_ERROR (get_status_register_err_msg);
@@ -297,16 +266,16 @@ static int imx31_init (struct nand_device_s *device)
return ERROR_OK;
}
static int imx31_read_data (struct nand_device_s *device, void *data)
static int imx31_read_data (struct nand_device *nand, void *data)
{
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
target_t *target = mx3_nf_info->target;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
{
/*
* validate target state
*/
int validate_target_result;
validate_target_result = validate_target_state (device);
validate_target_result = validate_target_state (nand);
if (validate_target_result != ERROR_OK)
{
return validate_target_result;
@@ -318,14 +287,14 @@ static int imx31_read_data (struct nand_device_s *device, void *data)
* get data from nand chip
*/
int try_data_output_from_nand_chip;
try_data_output_from_nand_chip = do_data_output (device);
try_data_output_from_nand_chip = do_data_output (nand);
if (try_data_output_from_nand_chip != ERROR_OK)
{
return try_data_output_from_nand_chip;
}
}
if (device->bus_width == 16)
if (nand->bus_width == 16)
{
get_next_halfword_from_sram_buffer (target, data);
}
@@ -337,47 +306,42 @@ static int imx31_read_data (struct nand_device_s *device, void *data)
return ERROR_OK;
}
static int imx31_write_data (struct nand_device_s *device, uint16_t data)
static int imx31_write_data (struct nand_device *nand, 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)
static int imx31_nand_ready (struct nand_device *nand, int timeout)
{
return imx31_controller_ready (device, timeout);
return imx31_controller_ready (nand, timeout);
}
static int imx31_register_commands (struct command_context_s *cmd_ctx)
{
return ERROR_OK;
}
static int imx31_reset (struct nand_device_s *device)
static int imx31_reset (struct nand_device *nand)
{
/*
* validate target state
*/
int validate_target_result;
validate_target_result = validate_target_state (device);
validate_target_result = validate_target_state (nand);
if (validate_target_result != ERROR_OK)
{
return validate_target_result;
}
initialize_nf_controller (device);
initialize_nf_controller (nand);
return ERROR_OK;
}
static int imx31_command (struct nand_device_s *device, uint8_t command)
static int imx31_command (struct nand_device *nand, uint8_t command)
{
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
target_t *target = mx3_nf_info->target;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
{
/*
* validate target state
*/
int validate_target_result;
validate_target_result = validate_target_state (device);
validate_target_result = validate_target_state (nand);
if (validate_target_result != ERROR_OK)
{
return validate_target_result;
@@ -400,7 +364,7 @@ static int imx31_command (struct nand_device_s *device, uint8_t command)
* offset == one half of page size
*/
in_sram_address =
MX3_NF_MAIN_BUFFER0 + (device->page_size >> 1);
MX3_NF_MAIN_BUFFER0 + (nand->page_size >> 1);
default:
in_sram_address = MX3_NF_MAIN_BUFFER0;
}
@@ -442,16 +406,16 @@ static int imx31_command (struct nand_device_s *device, uint8_t command)
return ERROR_OK;
}
static int imx31_address (struct nand_device_s *device, uint8_t address)
static int imx31_address (struct nand_device *nand, uint8_t address)
{
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
target_t *target = mx3_nf_info->target;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
{
/*
* validate target state
*/
int validate_target_result;
validate_target_result = validate_target_state (device);
validate_target_result = validate_target_state (nand);
if (validate_target_result != ERROR_OK)
{
return validate_target_result;
@@ -474,18 +438,18 @@ static int imx31_address (struct nand_device_s *device, uint8_t address)
return ERROR_OK;
}
static int imx31_controller_ready (struct nand_device_s *device, int tout)
static int imx31_controller_ready (struct nand_device *nand, int tout)
{
uint16_t poll_complete_status;
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
target_t *target = mx3_nf_info->target;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
{
/*
* validate target state
*/
int validate_target_result;
validate_target_result = validate_target_state (device);
validate_target_result = validate_target_state (nand);
if (validate_target_result != ERROR_OK)
{
return validate_target_result;
@@ -505,12 +469,12 @@ static int imx31_controller_ready (struct nand_device_s *device, int tout)
return tout;
}
static int imx31_write_page (struct nand_device_s *device, uint32_t page,
static int imx31_write_page (struct nand_device *nand, 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;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
if (data_size % 2)
{
@@ -532,7 +496,7 @@ static int imx31_write_page (struct nand_device_s *device, uint32_t page,
* validate target state
*/
int retval;
retval = validate_target_state (device);
retval = validate_target_state (nand);
if (retval != ERROR_OK)
{
return retval;
@@ -540,16 +504,16 @@ static int imx31_write_page (struct nand_device_s *device, uint32_t page,
}
{
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_command(nand, NAND_CMD_SEQIN);
retval |= imx31_address(nand, 0x00);
retval |= imx31_address(nand, page & 0xff);
retval |= imx31_address(nand, (page >> 8) & 0xff);
if (nand->address_cycles >= 4)
{
retval |= imx31_address (device, (page >> 16) & 0xff);
if (device->address_cycles >= 5)
retval |= imx31_address (nand, (page >> 16) & 0xff);
if (nand->address_cycles >= 5)
{
retval |= imx31_address (device, (page >> 24) & 0xff);
retval |= imx31_address (nand, (page >> 24) & 0xff);
}
}
target_write_buffer (target, MX3_NF_MAIN_BUFFER0, data_size, data);
@@ -579,7 +543,7 @@ static int imx31_write_page (struct nand_device_s *device, uint32_t page,
return poll_result;
}
}
retval |= imx31_command (device, NAND_CMD_PAGEPROG);
retval |= imx31_command (nand, NAND_CMD_PAGEPROG);
if (retval != ERROR_OK)
{
return retval;
@@ -591,9 +555,9 @@ static int imx31_write_page (struct nand_device_s *device, uint32_t page,
{
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);
retval |= imx31_command(nand, NAND_CMD_STATUS);
retval |= imx31_address(nand, 0x00);
retval |= do_data_output(nand);
if (retval != ERROR_OK)
{
LOG_ERROR (get_status_register_err_msg);
@@ -612,12 +576,12 @@ static int imx31_write_page (struct nand_device_s *device, uint32_t page,
return ERROR_OK;
}
static int imx31_read_page (struct nand_device_s *device, uint32_t page,
static int imx31_read_page (struct nand_device *nand, 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;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
if (data_size % 2)
{
@@ -635,7 +599,7 @@ static int imx31_read_page (struct nand_device_s *device, uint32_t page,
* validate target state
*/
int retval;
retval = validate_target_state (device);
retval = validate_target_state(nand);
if (retval != ERROR_OK)
{
return retval;
@@ -643,20 +607,20 @@ static int imx31_read_page (struct nand_device_s *device, uint32_t page,
}
{
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_command(nand, NAND_CMD_READ0);
retval |= imx31_address(nand, 0x00);
retval |= imx31_address(nand, page & 0xff);
retval |= imx31_address(nand, (page >> 8) & 0xff);
if (nand->address_cycles >= 4)
{
retval |= imx31_address (device, (page >> 16) & 0xff);
if (device->address_cycles >= 5)
retval |= imx31_address(nand, (page >> 16) & 0xff);
if (nand->address_cycles >= 5)
{
retval |= imx31_address (device, (page >> 24) & 0xff);
retval |= imx31_command (device, NAND_CMD_READSTART);
retval |= imx31_address(nand, (page >> 24) & 0xff);
retval |= imx31_command(nand, NAND_CMD_READSTART);
}
}
retval |= do_data_output (device);
retval |= do_data_output (nand);
if (retval != ERROR_OK)
{
return retval;
@@ -676,7 +640,7 @@ static int imx31_read_page (struct nand_device_s *device, uint32_t page,
return ERROR_OK;
}
static int test_iomux_settings (target_t * target, uint32_t address,
static int test_iomux_settings (struct target * target, uint32_t address,
uint32_t mask, const char *text)
{
uint32_t register_content;
@@ -689,10 +653,10 @@ static int test_iomux_settings (target_t * target, uint32_t address,
return ERROR_OK;
}
static int initialize_nf_controller (struct nand_device_s *device)
static int initialize_nf_controller (struct nand_device *nand)
{
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
target_t *target = mx3_nf_info->target;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
/*
* resets NAND flash controller in zero time ? I dont know.
*/
@@ -742,7 +706,7 @@ static int initialize_nf_controller (struct nand_device_s *device)
return ERROR_OK;
}
static int get_next_byte_from_sram_buffer (target_t * target, uint8_t * value)
static int get_next_byte_from_sram_buffer (struct target * target, uint8_t * value)
{
static uint8_t even_byte = 0;
/*
@@ -780,7 +744,7 @@ static int get_next_byte_from_sram_buffer (target_t * target, uint8_t * value)
return ERROR_OK;
}
static int get_next_halfword_from_sram_buffer (target_t * target,
static int get_next_halfword_from_sram_buffer (struct target * target,
uint16_t * value)
{
if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR)
@@ -797,7 +761,7 @@ static int get_next_halfword_from_sram_buffer (target_t * target,
return ERROR_OK;
}
static int poll_for_complete_op (target_t * target, const char *text)
static int poll_for_complete_op (struct target * target, const char *text)
{
uint16_t poll_complete_status;
for (int poll_cycle_count = 0; poll_cycle_count < 100; poll_cycle_count++)
@@ -817,10 +781,10 @@ static int poll_for_complete_op (target_t * target, const char *text)
return ERROR_OK;
}
static int validate_target_state (struct nand_device_s *device)
static int validate_target_state (struct nand_device *nand)
{
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
target_t *target = mx3_nf_info->target;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
if (target->state != TARGET_HALTED)
{
@@ -839,10 +803,10 @@ static int validate_target_state (struct nand_device_s *device)
return ERROR_OK;
}
static int do_data_output (struct nand_device_s *device)
static int do_data_output (struct nand_device *nand)
{
mx3_nf_controller_t *mx3_nf_info = device->controller_priv;
target_t *target = mx3_nf_info->target;
struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
struct target *target = mx3_nf_info->target;
switch (mx3_nf_info->fin)
{
case MX3_NF_FIN_DATAOUT:
@@ -900,3 +864,18 @@ static int do_data_output (struct nand_device_s *device)
}
return ERROR_OK;
}
struct nand_flash_controller imx31_nand_flash_controller = {
.name = "imx31",
.nand_device_command = &imx31_nand_device_command,
.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,
};

View File

@@ -25,7 +25,6 @@
*
* 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)
@@ -108,10 +107,10 @@ struct mx3_nf_flags
unsigned hw_ecc_enabled:1;
};
typedef struct mx3_nf_controller_s
struct mx3_nf_controller
{
struct target_s *target;
struct target *target;
enum mx_dataout_type optype;
enum mx_nf_finalize_action fin;
struct mx3_nf_flags flags;
} mx3_nf_controller_t;
};

83
src/flash/nand/nonce.c Normal file
View File

@@ -0,0 +1,83 @@
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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 "imp.h"
#include "hello.h"
static int nonce_nand_command(struct nand_device *nand, uint8_t command)
{
return ERROR_OK;
}
static int nonce_nand_address(struct nand_device *nand, uint8_t address)
{
return ERROR_OK;
}
static int nonce_nand_read(struct nand_device *nand, void *data)
{
return ERROR_OK;
}
static int nonce_nand_write(struct nand_device *nand, uint16_t data)
{
return ERROR_OK;
}
static int nonce_nand_fast_block_write(struct nand_device *nand,
uint8_t *data, int size)
{
return ERROR_OK;
}
static int nonce_nand_reset(struct nand_device *nand)
{
return nonce_nand_command(nand, NAND_CMD_RESET);
}
static int nonce_nand_controller_ready(struct nand_device *nand, int timeout)
{
return true;
}
NAND_DEVICE_COMMAND_HANDLER(nonce_nand_device_command)
{
return ERROR_OK;
}
static int nonce_nand_init(struct nand_device *nand)
{
return ERROR_OK;
}
struct nand_flash_controller nonce_nand_controller =
{
.name = "nonce",
.commands = hello_command_handlers,
.nand_device_command = &nonce_nand_device_command,
.init = &nonce_nand_init,
.reset = &nonce_nand_reset,
.command = &nonce_nand_command,
.address = &nonce_nand_address,
.read_data = &nonce_nand_read,
.write_data = &nonce_nand_write,
.write_block_data = &nonce_nand_fast_block_write,
.controller_ready = &nonce_nand_controller_ready,
};

View File

@@ -26,20 +26,21 @@
#include "config.h"
#endif
#include "arm_nandio.h"
#include "armv4_5.h"
#include "imp.h"
#include "arm_io.h"
#include <target/arm.h>
typedef struct orion_nand_controller_s
struct orion_nand_controller
{
struct target_s *target;
struct target *target;
struct arm_nand_data io;
uint32_t cmd;
uint32_t addr;
uint32_t data;
} orion_nand_controller_t;
};
#define CHECK_HALTED \
do { \
@@ -49,91 +50,84 @@ typedef struct orion_nand_controller_s
} \
} while (0)
static int orion_nand_command(struct nand_device_s *device, uint8_t command)
static int orion_nand_command(struct nand_device *nand, uint8_t command)
{
orion_nand_controller_t *hw = device->controller_priv;
target_t *target = hw->target;
struct orion_nand_controller *hw = nand->controller_priv;
struct target *target = hw->target;
CHECK_HALTED;
target_write_u8(target, hw->cmd, command);
return ERROR_OK;
}
static int orion_nand_address(struct nand_device_s *device, uint8_t address)
static int orion_nand_address(struct nand_device *nand, uint8_t address)
{
orion_nand_controller_t *hw = device->controller_priv;
target_t *target = hw->target;
struct orion_nand_controller *hw = nand->controller_priv;
struct target *target = hw->target;
CHECK_HALTED;
target_write_u8(target, hw->addr, address);
return ERROR_OK;
}
static int orion_nand_read(struct nand_device_s *device, void *data)
static int orion_nand_read(struct nand_device *nand, void *data)
{
orion_nand_controller_t *hw = device->controller_priv;
target_t *target = hw->target;
struct orion_nand_controller *hw = nand->controller_priv;
struct target *target = hw->target;
CHECK_HALTED;
target_read_u8(target, hw->data, data);
return ERROR_OK;
}
static int orion_nand_write(struct nand_device_s *device, uint16_t data)
static int orion_nand_write(struct nand_device *nand, uint16_t data)
{
orion_nand_controller_t *hw = device->controller_priv;
target_t *target = hw->target;
struct orion_nand_controller *hw = nand->controller_priv;
struct target *target = hw->target;
CHECK_HALTED;
target_write_u8(target, hw->data, data);
return ERROR_OK;
}
static int orion_nand_slow_block_write(struct nand_device_s *device, uint8_t *data, int size)
static int orion_nand_slow_block_write(struct nand_device *nand, uint8_t *data, int size)
{
while (size--)
orion_nand_write(device, *data++);
orion_nand_write(nand, *data++);
return ERROR_OK;
}
static int orion_nand_fast_block_write(struct nand_device_s *device, uint8_t *data, int size)
static int orion_nand_fast_block_write(struct nand_device *nand, uint8_t *data, int size)
{
orion_nand_controller_t *hw = device->controller_priv;
struct orion_nand_controller *hw = nand->controller_priv;
int retval;
hw->io.chunk_size = device->page_size;
hw->io.chunk_size = nand->page_size;
retval = arm_nandwrite(&hw->io, data, size);
if (retval == ERROR_NAND_NO_BUFFER)
retval = orion_nand_slow_block_write(device, data, size);
retval = orion_nand_slow_block_write(nand, data, size);
return retval;
}
static int orion_nand_reset(struct nand_device_s *device)
static int orion_nand_reset(struct nand_device *nand)
{
return orion_nand_command(device, NAND_CMD_RESET);
return orion_nand_command(nand, NAND_CMD_RESET);
}
static int orion_nand_controller_ready(struct nand_device_s *device, int timeout)
static int orion_nand_controller_ready(struct nand_device *nand, int timeout)
{
return 1;
}
static int orion_nand_register_commands(struct command_context_s *cmd_ctx)
NAND_DEVICE_COMMAND_HANDLER(orion_nand_device_command)
{
return ERROR_OK;
}
int orion_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
char **args, int argc,
struct nand_device_s *device)
{
orion_nand_controller_t *hw;
struct orion_nand_controller *hw;
uint32_t base;
uint8_t ale, cle;
if (argc != 3) {
if (CMD_ARGC != 3) {
LOG_ERROR("arguments must be: <target_id> <NAND_address>\n");
return ERROR_NAND_DEVICE_INVALID;
}
@@ -144,15 +138,15 @@ int orion_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
return ERROR_NAND_DEVICE_INVALID;
}
device->controller_priv = hw;
hw->target = get_target(args[1]);
nand->controller_priv = hw;
hw->target = get_target(CMD_ARGV[1]);
if (!hw->target) {
LOG_ERROR("target '%s' not defined", args[1]);
LOG_ERROR("target '%s' not defined", CMD_ARGV[1]);
free(hw);
return ERROR_NAND_DEVICE_INVALID;
}
base = strtoul(args[2], NULL, 0);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], base);
cle = 0;
ale = 1;
@@ -162,16 +156,17 @@ int orion_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
hw->io.target = hw->target;
hw->io.data = hw->data;
hw->io.op = ARM_NAND_NONE;
return ERROR_OK;
}
static int orion_nand_init(struct nand_device_s *device)
static int orion_nand_init(struct nand_device *nand)
{
return ERROR_OK;
}
nand_flash_controller_t orion_nand_controller =
struct nand_flash_controller orion_nand_controller =
{
.name = "orion",
.command = orion_nand_command,
@@ -182,7 +177,6 @@ nand_flash_controller_t orion_nand_controller =
.reset = orion_nand_reset,
.controller_ready = orion_nand_controller_ready,
.nand_device_command = orion_nand_device_command,
.register_commands = orion_nand_register_commands,
.init = orion_nand_init,
};

View File

@@ -28,42 +28,12 @@
#include "config.h"
#endif
#include "s3c24xx_nand.h"
#include "s3c24xx.h"
static int s3c2410_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);
static int s3c2410_init(struct nand_device_s *device);
static int s3c2410_read_data(struct nand_device_s *device, void *data);
static int s3c2410_write_data(struct nand_device_s *device, uint16_t data);
static int s3c2410_nand_ready(struct nand_device_s *device, int timeout);
nand_flash_controller_t s3c2410_nand_controller =
NAND_DEVICE_COMMAND_HANDLER(s3c2410_nand_device_command)
{
.name = "s3c2410",
.nand_device_command = s3c2410_nand_device_command,
.register_commands = s3c24xx_register_commands,
.init = s3c2410_init,
.reset = s3c24xx_reset,
.command = s3c24xx_command,
.address = s3c24xx_address,
.write_data = s3c2410_write_data,
.read_data = s3c2410_read_data,
.write_page = s3c24xx_write_page,
.read_page = s3c24xx_read_page,
.controller_ready = s3c24xx_controller_ready,
.nand_ready = s3c2410_nand_ready,
};
static int s3c2410_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
char **args, int argc,
struct nand_device_s *device)
{
s3c24xx_nand_controller_t *info;
info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device);
if (info == NULL) {
return ERROR_NAND_DEVICE_INVALID;
}
struct s3c24xx_nand_controller *info;
CALL_S3C24XX_DEVICE_COMMAND(nand, &info);
/* fill in the address fields for the core device */
info->cmd = S3C2410_NFCMD;
@@ -74,10 +44,10 @@ static int s3c2410_nand_device_command(struct command_context_s *cmd_ctx, char *
return ERROR_OK;
}
static int s3c2410_init(struct nand_device_s *device)
static int s3c2410_init(struct nand_device *nand)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
target_write_u32(target, S3C2410_NFCONF,
S3C2410_NFCONF_EN | S3C2410_NFCONF_TACLS(3) |
@@ -86,10 +56,10 @@ static int s3c2410_init(struct nand_device_s *device)
return ERROR_OK;
}
static int s3c2410_write_data(struct nand_device_s *device, uint16_t data)
static int s3c2410_write_data(struct nand_device *nand, uint16_t data)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("target must be halted to use S3C24XX NAND flash controller");
@@ -100,10 +70,10 @@ static int s3c2410_write_data(struct nand_device_s *device, uint16_t data)
return ERROR_OK;
}
static int s3c2410_read_data(struct nand_device_s *device, void *data)
static int s3c2410_read_data(struct nand_device *nand, void *data)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("target must be halted to use S3C24XX NAND flash controller");
@@ -114,10 +84,10 @@ static int s3c2410_read_data(struct nand_device_s *device, void *data)
return ERROR_OK;
}
static int s3c2410_nand_ready(struct nand_device_s *device, int timeout)
static int s3c2410_nand_ready(struct nand_device *nand, int timeout)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
uint8_t status;
if (target->state != TARGET_HALTED) {
@@ -136,3 +106,18 @@ static int s3c2410_nand_ready(struct nand_device_s *device, int timeout)
return 0;
}
struct nand_flash_controller s3c2410_nand_controller = {
.name = "s3c2410",
.nand_device_command = &s3c2410_nand_device_command,
.init = &s3c2410_init,
.reset = &s3c24xx_reset,
.command = &s3c24xx_command,
.address = &s3c24xx_address,
.write_data = &s3c2410_write_data,
.read_data = &s3c2410_read_data,
.write_page = s3c24xx_write_page,
.read_page = s3c24xx_read_page,
.controller_ready = &s3c24xx_controller_ready,
.nand_ready = &s3c2410_nand_ready,
};

View File

@@ -28,41 +28,12 @@
#include "config.h"
#endif
#include "s3c24xx_nand.h"
#include "s3c24xx.h"
static int s3c2412_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);
static int s3c2412_init(struct nand_device_s *device);
nand_flash_controller_t s3c2412_nand_controller =
NAND_DEVICE_COMMAND_HANDLER(s3c2412_nand_device_command)
{
.name = "s3c2412",
.nand_device_command = s3c2412_nand_device_command,
.register_commands = s3c24xx_register_commands,
.init = s3c2412_init,
.reset = s3c24xx_reset,
.command = s3c24xx_command,
.address = s3c24xx_address,
.write_data = s3c24xx_write_data,
.read_data = s3c24xx_read_data,
.write_page = s3c24xx_write_page,
.read_page = s3c24xx_read_page,
.write_block_data = s3c2440_write_block_data,
.read_block_data = s3c2440_read_block_data,
.controller_ready = s3c24xx_controller_ready,
.nand_ready = s3c2440_nand_ready,
};
static int s3c2412_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
char **args, int argc,
struct nand_device_s *device)
{
s3c24xx_nand_controller_t *info;
info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device);
if (info == NULL) {
return ERROR_NAND_DEVICE_INVALID;
}
struct s3c24xx_nand_controller *info;
CALL_S3C24XX_DEVICE_COMMAND(nand, &info);
/* fill in the address fields for the core device */
info->cmd = S3C2440_NFCMD;
@@ -73,10 +44,10 @@ static int s3c2412_nand_device_command(struct command_context_s *cmd_ctx, char *
return ERROR_OK;
}
static int s3c2412_init(struct nand_device_s *device)
static int s3c2412_init(struct nand_device *nand)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
target_write_u32(target, S3C2410_NFCONF,
S3C2440_NFCONF_TACLS(3) |
@@ -89,3 +60,20 @@ static int s3c2412_init(struct nand_device_s *device)
return ERROR_OK;
}
struct nand_flash_controller s3c2412_nand_controller = {
.name = "s3c2412",
.nand_device_command = &s3c2412_nand_device_command,
.init = &s3c2412_init,
.reset = &s3c24xx_reset,
.command = &s3c24xx_command,
.address = &s3c24xx_address,
.write_data = &s3c24xx_write_data,
.read_data = &s3c24xx_read_data,
.write_page = s3c24xx_write_page,
.read_page = s3c24xx_read_page,
.write_block_data = &s3c2440_write_block_data,
.read_block_data = &s3c2440_read_block_data,
.controller_ready = &s3c24xx_controller_ready,
.nand_ready = &s3c2440_nand_ready,
};

View File

@@ -28,42 +28,13 @@
#include "config.h"
#endif
#include "s3c24xx_nand.h"
#include "s3c24xx.h"
static int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);
static int s3c2440_init(struct nand_device_s *device);
//static int s3c2440_nand_ready(struct nand_device_s *device, int timeout);
nand_flash_controller_t s3c2440_nand_controller =
NAND_DEVICE_COMMAND_HANDLER(s3c2440_nand_device_command)
{
.name = "s3c2440",
.nand_device_command = s3c2440_nand_device_command,
.register_commands = s3c24xx_register_commands,
.init = s3c2440_init,
.reset = s3c24xx_reset,
.command = s3c24xx_command,
.address = s3c24xx_address,
.write_data = s3c24xx_write_data,
.read_data = s3c24xx_read_data,
.write_page = s3c24xx_write_page,
.read_page = s3c24xx_read_page,
.write_block_data = s3c2440_write_block_data,
.read_block_data = s3c2440_read_block_data,
.controller_ready = s3c24xx_controller_ready,
.nand_ready = s3c2440_nand_ready,
};
static int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
char **args, int argc,
struct nand_device_s *device)
{
s3c24xx_nand_controller_t *info;
info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device);
if (info == NULL) {
return ERROR_NAND_DEVICE_INVALID;
}
struct s3c24xx_nand_controller *info;
CALL_S3C24XX_DEVICE_COMMAND(nand, &info);
/* fill in the address fields for the core device */
info->cmd = S3C2440_NFCMD;
@@ -74,10 +45,10 @@ static int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *
return ERROR_OK;
}
static int s3c2440_init(struct nand_device_s *device)
static int s3c2440_init(struct nand_device *nand)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
target_write_u32(target, S3C2410_NFCONF,
S3C2440_NFCONF_TACLS(3) |
@@ -90,10 +61,10 @@ static int s3c2440_init(struct nand_device_s *device)
return ERROR_OK;
}
int s3c2440_nand_ready(struct nand_device_s *device, int timeout)
int s3c2440_nand_ready(struct nand_device *nand, int timeout)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
uint8_t status;
if (target->state != TARGET_HALTED) {
@@ -116,14 +87,14 @@ int s3c2440_nand_ready(struct nand_device_s *device, int timeout)
/* use the fact we can read/write 4 bytes in one go via a single 32bit op */
int s3c2440_read_block_data(struct nand_device_s *device, uint8_t *data, int data_size)
int s3c2440_read_block_data(struct nand_device *nand, uint8_t *data, int data_size)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
uint32_t nfdata = s3c24xx_info->data;
uint32_t tmp;
LOG_INFO("%s: reading data: %p, %p, %d\n", __func__, device, data, data_size);
LOG_INFO("%s: reading data: %p, %p, %d\n", __func__, nand, data, data_size);
if (target->state != TARGET_HALTED) {
LOG_ERROR("target must be halted to use S3C24XX NAND flash controller");
@@ -152,10 +123,10 @@ int s3c2440_read_block_data(struct nand_device_s *device, uint8_t *data, int dat
return ERROR_OK;
}
int s3c2440_write_block_data(struct nand_device_s *device, uint8_t *data, int data_size)
int s3c2440_write_block_data(struct nand_device *nand, uint8_t *data, int data_size)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
uint32_t nfdata = s3c24xx_info->data;
uint32_t tmp;
@@ -181,3 +152,20 @@ int s3c2440_write_block_data(struct nand_device_s *device, uint8_t *data, int da
return ERROR_OK;
}
struct nand_flash_controller s3c2440_nand_controller = {
.name = "s3c2440",
.nand_device_command = &s3c2440_nand_device_command,
.init = &s3c2440_init,
.reset = &s3c24xx_reset,
.command = &s3c24xx_command,
.address = &s3c24xx_address,
.write_data = &s3c24xx_write_data,
.read_data = &s3c24xx_read_data,
.write_page = s3c24xx_write_page,
.read_page = s3c24xx_read_page,
.write_block_data = &s3c2440_write_block_data,
.read_block_data = &s3c2440_read_block_data,
.controller_ready = &s3c24xx_controller_ready,
.nand_ready = &s3c2440_nand_ready,
};

View File

@@ -28,41 +28,13 @@
#include "config.h"
#endif
#include "s3c24xx_nand.h"
#include "s3c24xx.h"
static int s3c2443_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);
static int s3c2443_init(struct nand_device_s *device);
nand_flash_controller_t s3c2443_nand_controller =
NAND_DEVICE_COMMAND_HANDLER(s3c2443_nand_device_command)
{
.name = "s3c2443",
.nand_device_command = s3c2443_nand_device_command,
.register_commands = s3c24xx_register_commands,
.init = s3c2443_init,
.reset = s3c24xx_reset,
.command = s3c24xx_command,
.address = s3c24xx_address,
.write_data = s3c24xx_write_data,
.read_data = s3c24xx_read_data,
.write_page = s3c24xx_write_page,
.read_page = s3c24xx_read_page,
.write_block_data = s3c2440_write_block_data,
.read_block_data = s3c2440_read_block_data,
.controller_ready = s3c24xx_controller_ready,
.nand_ready = s3c2440_nand_ready,
};
static int s3c2443_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
char **args, int argc,
struct nand_device_s *device)
{
s3c24xx_nand_controller_t *info;
info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device);
if (info == NULL) {
return ERROR_NAND_DEVICE_INVALID;
}
struct s3c24xx_nand_controller *info;
CALL_S3C24XX_DEVICE_COMMAND(nand, &info);
/* fill in the address fields for the core device */
info->cmd = S3C2440_NFCMD;
@@ -73,10 +45,10 @@ static int s3c2443_nand_device_command(struct command_context_s *cmd_ctx, char *
return ERROR_OK;
}
static int s3c2443_init(struct nand_device_s *device)
static int s3c2443_init(struct nand_device *nand)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
target_write_u32(target, S3C2410_NFCONF,
S3C2440_NFCONF_TACLS(3) |
@@ -89,3 +61,20 @@ static int s3c2443_init(struct nand_device_s *device)
return ERROR_OK;
}
struct nand_flash_controller s3c2443_nand_controller = {
.name = "s3c2443",
.nand_device_command = &s3c2443_nand_device_command,
.init = &s3c2443_init,
.reset = &s3c24xx_reset,
.command = &s3c24xx_command,
.address = &s3c24xx_address,
.write_data = &s3c24xx_write_data,
.read_data = &s3c24xx_read_data,
.write_page = s3c24xx_write_page,
.read_page = s3c24xx_read_page,
.write_block_data = &s3c2440_write_block_data,
.read_block_data = &s3c2440_read_block_data,
.controller_ready = &s3c24xx_controller_ready,
.nand_ready = &s3c2440_nand_ready,
};

View File

@@ -28,42 +28,37 @@
#include "config.h"
#endif
#include "s3c24xx_nand.h"
#include "s3c24xx.h"
s3c24xx_nand_controller_t *
s3c24xx_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
char **args, int argc,
struct nand_device_s *device)
S3C24XX_DEVICE_COMMAND()
{
s3c24xx_nand_controller_t *s3c24xx_info;
*info = NULL;
s3c24xx_info = malloc(sizeof(s3c24xx_nand_controller_t));
struct s3c24xx_nand_controller *s3c24xx_info;
s3c24xx_info = malloc(sizeof(struct s3c24xx_nand_controller));
if (s3c24xx_info == NULL) {
LOG_ERROR("no memory for nand controller\n");
return NULL;
return -ENOMEM;
}
device->controller_priv = s3c24xx_info;
nand->controller_priv = s3c24xx_info;
s3c24xx_info->target = get_target(args[1]);
s3c24xx_info->target = get_target(CMD_ARGV[1]);
if (s3c24xx_info->target == NULL) {
LOG_ERROR("target '%s' not defined", args[1]);
return NULL;
LOG_ERROR("target '%s' not defined", CMD_ARGV[1]);
return ERROR_COMMAND_SYNTAX_ERROR;
}
return s3c24xx_info;
}
*info = s3c24xx_info;
int s3c24xx_register_commands(struct command_context_s *cmd_ctx)
{
return ERROR_OK;
}
int s3c24xx_reset(struct nand_device_s *device)
int s3c24xx_reset(struct nand_device *nand)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("target must be halted to use S3C24XX NAND flash controller");
@@ -75,10 +70,10 @@ int s3c24xx_reset(struct nand_device_s *device)
return ERROR_OK;
}
int s3c24xx_command(struct nand_device_s *device, uint8_t command)
int s3c24xx_command(struct nand_device *nand, uint8_t command)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("target must be halted to use S3C24XX NAND flash controller");
@@ -90,10 +85,10 @@ int s3c24xx_command(struct nand_device_s *device, uint8_t command)
}
int s3c24xx_address(struct nand_device_s *device, uint8_t address)
int s3c24xx_address(struct nand_device *nand, uint8_t address)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("target must be halted to use S3C24XX NAND flash controller");
@@ -104,10 +99,10 @@ int s3c24xx_address(struct nand_device_s *device, uint8_t address)
return ERROR_OK;
}
int s3c24xx_write_data(struct nand_device_s *device, uint16_t data)
int s3c24xx_write_data(struct nand_device *nand, uint16_t data)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("target must be halted to use S3C24XX NAND flash controller");
@@ -118,10 +113,10 @@ int s3c24xx_write_data(struct nand_device_s *device, uint16_t data)
return ERROR_OK;
}
int s3c24xx_read_data(struct nand_device_s *device, void *data)
int s3c24xx_read_data(struct nand_device *nand, void *data)
{
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
target_t *target = s3c24xx_info->target;
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("target must be halted to use S3C24XX NAND flash controller");
@@ -132,7 +127,7 @@ int s3c24xx_read_data(struct nand_device_s *device, void *data)
return ERROR_OK;
}
int s3c24xx_controller_ready(struct nand_device_s *device, int timeout)
int s3c24xx_controller_ready(struct nand_device *nand, int timeout)
{
return 1;
}

View File

@@ -18,46 +18,68 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef S3C24xx_NAND_H
#define S3C24xx_NAND_H
/*
* S3C24XX Series OpenOCD NAND Flash controller support.
*
* Many thanks to Simtec Electronics for sponsoring this work.
*/
#include "nand.h"
#include "s3c24xx_regs_nand.h"
#include "imp.h"
#include "s3c24xx_regs.h"
#include <target/target.h>
typedef struct s3c24xx_nand_controller_s
struct s3c24xx_nand_controller
{
struct target_s *target;
struct target *target;
/* register addresses */
uint32_t cmd;
uint32_t addr;
uint32_t data;
uint32_t nfstat;
} s3c24xx_nand_controller_t;
};
/* Default to using the un-translated NAND register based address */
#undef S3C2410_NFREG
#define S3C2410_NFREG(x) ((x) + 0x4e000000)
extern s3c24xx_nand_controller_t *s3c24xx_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);
#define S3C24XX_DEVICE_COMMAND() \
COMMAND_HELPER(s3c24xx_nand_device_command, \
struct nand_device *nand, \
struct s3c24xx_nand_controller **info)
extern int s3c24xx_register_commands(struct command_context_s *cmd_ctx);
extern int s3c24xx_reset(struct nand_device_s *device);
extern int s3c24xx_command(struct nand_device_s *device, uint8_t command);
extern int s3c24xx_address(struct nand_device_s *device, uint8_t address);
extern int s3c24xx_write_data(struct nand_device_s *device, uint16_t data);
extern int s3c24xx_read_data(struct nand_device_s *device, void *data);
extern int s3c24xx_controller_ready(struct nand_device_s *device, int tout);
S3C24XX_DEVICE_COMMAND();
#define CALL_S3C24XX_DEVICE_COMMAND(d, i) \
do { \
int retval = CALL_COMMAND_HANDLER(s3c24xx_nand_device_command, d, i); \
if (ERROR_OK != retval) \
return retval; \
} while (0)
int s3c24xx_reset(struct nand_device *nand);
int s3c24xx_command(struct nand_device *nand, uint8_t command);
int s3c24xx_address(struct nand_device *nand, uint8_t address);
int s3c24xx_write_data(struct nand_device *nand, uint16_t data);
int s3c24xx_read_data(struct nand_device *nand, void *data);
int s3c24xx_controller_ready(struct nand_device *nand, int tout);
#define s3c24xx_write_page NULL
#define s3c24xx_read_page NULL
/* code shared between different controllers */
extern int s3c2440_nand_ready(struct nand_device_s *device, int timeout);
int s3c2440_nand_ready(struct nand_device *nand, int timeout);
extern int s3c2440_read_block_data(struct nand_device_s *, uint8_t *data, int data_size);
extern int s3c2440_write_block_data(struct nand_device_s *, uint8_t *data, int data_size);
int s3c2440_read_block_data(struct nand_device *nand,
uint8_t *data, int data_size);
int s3c2440_write_block_data(struct nand_device *nand,
uint8_t *data, int data_size);
#endif // S3C24xx_NAND_H

76
src/flash/nand/s3c6400.c Normal file
View File

@@ -0,0 +1,76 @@
/***************************************************************************
* Copyright (C) 2010 by Peter Korsgaard <jacmet@sunsite.dk> *
* Heavily based on s3c2412.c by Ben Dooks <ben@fluff.org> *
* *
* 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 "s3c24xx.h"
/* s3c64xx uses another base address for the nand controller than 24xx */
#undef S3C2410_NFREG
#define S3C2410_NFREG(x) ((x) + 0x70200000)
NAND_DEVICE_COMMAND_HANDLER(s3c6400_nand_device_command)
{
struct s3c24xx_nand_controller *info;
CALL_S3C24XX_DEVICE_COMMAND(nand, &info);
/* fill in the address fields for the core device */
info->cmd = S3C2440_NFCMD;
info->addr = S3C2440_NFADDR;
info->data = S3C2440_NFDATA;
info->nfstat = S3C2412_NFSTAT;
return ERROR_OK;
}
static int s3c6400_init(struct nand_device *nand)
{
struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
struct target *target = s3c24xx_info->target;
target_write_u32(target, S3C2410_NFCONF,
S3C2440_NFCONF_TACLS(3) |
S3C2440_NFCONF_TWRPH0(7) |
S3C2440_NFCONF_TWRPH1(7) | 4);
target_write_u32(target, S3C2440_NFCONT,
S3C2412_NFCONT_INIT_MAIN_ECC |
S3C2440_NFCONT_ENABLE);
return ERROR_OK;
}
struct nand_flash_controller s3c6400_nand_controller = {
.name = "s3c6400",
.nand_device_command = &s3c6400_nand_device_command,
.init = &s3c6400_init,
.reset = &s3c24xx_reset,
.command = &s3c24xx_command,
.address = &s3c24xx_address,
.write_data = &s3c24xx_write_data,
.read_data = &s3c24xx_read_data,
.write_page = s3c24xx_write_page,
.read_page = s3c24xx_read_page,
.write_block_data = &s3c2440_write_block_data,
.read_block_data = &s3c2440_read_block_data,
.controller_ready = &s3c24xx_controller_ready,
.nand_ready = &s3c2440_nand_ready,
};

647
src/flash/nand/tcl.c Normal file
View File

@@ -0,0 +1,647 @@
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* Partially based on drivers/mtd/nand_ids.c from Linux. *
* *
* 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 "core.h"
#include "imp.h"
#include "fileio.h"
// to be removed
extern struct nand_device *nand_devices;
COMMAND_HANDLER(handle_nand_list_command)
{
struct nand_device *p;
int i;
if (!nand_devices)
{
command_print(CMD_CTX, "no NAND flash devices configured");
return ERROR_OK;
}
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,\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);
}
return ERROR_OK;
}
COMMAND_HANDLER(handle_nand_info_command)
{
int i = 0;
int j = 0;
int first = -1;
int last = -1;
switch (CMD_ARGC) {
default:
return ERROR_COMMAND_SYNTAX_ERROR;
case 1:
first = 0;
last = INT32_MAX;
break;
case 2:
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], i);
first = last = i;
i = 0;
break;
case 3:
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last);
break;
}
struct nand_device *p;
int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
if (ERROR_OK != retval)
return retval;
if (NULL == p->device)
{
command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]);
return ERROR_OK;
}
if (first >= p->num_blocks)
first = p->num_blocks - 1;
if (last >= p->num_blocks)
last = p->num_blocks - 1;
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);
for (j = first; j <= last; j++)
{
char *erase_state, *bad_state;
if (p->blocks[j].is_erased == 0)
erase_state = "not erased";
else if (p->blocks[j].is_erased == 1)
erase_state = "erased";
else
erase_state = "erase state unknown";
if (p->blocks[j].is_bad == 0)
bad_state = "";
else if (p->blocks[j].is_bad == 1)
bad_state = " (marked bad)";
else
bad_state = " (block condition unknown)";
command_print(CMD_CTX,
"\t#%i: 0x%8.8" PRIx32 " (%" PRId32 "kB) %s%s",
j,
p->blocks[j].offset,
p->blocks[j].size / 1024,
erase_state,
bad_state);
}
return ERROR_OK;
}
COMMAND_HANDLER(handle_nand_probe_command)
{
if (CMD_ARGC != 1)
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
struct nand_device *p;
int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
if (ERROR_OK != retval)
return retval;
if ((retval = nand_probe(p)) == ERROR_OK)
{
command_print(CMD_CTX, "NAND flash device '%s' found", p->device->name);
}
else if (retval == ERROR_NAND_OPERATION_FAILED)
{
command_print(CMD_CTX, "probing failed for NAND flash device");
}
else
{
command_print(CMD_CTX, "unknown error when probing NAND flash device");
}
return ERROR_OK;
}
COMMAND_HANDLER(handle_nand_erase_command)
{
if (CMD_ARGC != 1 && CMD_ARGC != 3)
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
struct nand_device *p;
int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
if (ERROR_OK != retval)
return retval;
unsigned long offset;
unsigned long length;
/* erase specified part of the chip; or else everything */
if (CMD_ARGC == 3) {
unsigned long size = p->erase_size * p->num_blocks;
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset);
if ((offset % p->erase_size) != 0 || offset >= size)
return ERROR_INVALID_ARGUMENTS;
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length);
if ((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, "erased blocks %lu to %lu "
"on NAND flash device #%s '%s'",
offset, offset + length,
CMD_ARGV[0], p->device->name);
}
else if (retval == ERROR_NAND_OPERATION_FAILED)
{
command_print(CMD_CTX, "erase failed");
}
else
{
command_print(CMD_CTX, "unknown error when erasing NAND flash device");
}
return ERROR_OK;
}
COMMAND_HANDLER(handle_nand_check_bad_blocks_command)
{
int first = -1;
int last = -1;
if ((CMD_ARGC < 1) || (CMD_ARGC > 3) || (CMD_ARGC == 2))
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
struct nand_device *p;
int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
if (ERROR_OK != retval)
return retval;
if (CMD_ARGC == 3)
{
unsigned long offset;
unsigned long length;
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset);
if (offset % p->erase_size)
return ERROR_INVALID_ARGUMENTS;
offset /= p->erase_size;
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length);
if (length % p->erase_size)
return ERROR_INVALID_ARGUMENTS;
length -= 1;
length /= p->erase_size;
first = offset;
last = offset + length;
}
retval = nand_build_bbt(p, first, last);
if (retval == ERROR_OK)
{
command_print(CMD_CTX, "checked NAND flash device for bad blocks, "
"use \"nand info\" command to list blocks");
}
else if (retval == ERROR_NAND_OPERATION_FAILED)
{
command_print(CMD_CTX, "error when checking for bad blocks on "
"NAND flash device");
}
else
{
command_print(CMD_CTX, "unknown error when checking for bad "
"blocks on NAND flash device");
}
return ERROR_OK;
}
COMMAND_HANDLER(handle_nand_write_command)
{
struct nand_device *nand = NULL;
struct nand_fileio_state s;
int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,
&s, &nand, FILEIO_READ, false, true);
if (ERROR_OK != retval)
return retval;
uint32_t total_bytes = s.size;
while (s.size > 0)
{
int bytes_read = nand_fileio_read(nand, &s);
if (bytes_read <= 0)
{
command_print(CMD_CTX, "error while reading file");
return nand_fileio_cleanup(&s);
}
s.size -= bytes_read;
retval = nand_write_page(nand, s.address / nand->page_size,
s.page, s.page_size, s.oob, s.oob_size);
if (ERROR_OK != retval)
{
command_print(CMD_CTX, "failed writing file %s "
"to NAND flash %s at offset 0x%8.8" PRIx32,
CMD_ARGV[1], CMD_ARGV[0], s.address);
return nand_fileio_cleanup(&s);
}
s.address += s.page_size;
}
if (nand_fileio_finish(&s))
{
command_print(CMD_CTX, "wrote file %s to NAND flash %s up to "
"offset 0x%8.8" PRIx32 " in %fs (%0.3f kb/s)",
CMD_ARGV[1], CMD_ARGV[0], s.address, duration_elapsed(&s.bench),
duration_kbps(&s.bench, total_bytes));
}
return ERROR_OK;
}
COMMAND_HANDLER(handle_nand_verify_command)
{
struct nand_device *nand = NULL;
struct nand_fileio_state file;
int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,
&file, &nand, FILEIO_READ, false, true);
if (ERROR_OK != retval)
return retval;
struct nand_fileio_state dev;
nand_fileio_init(&dev);
dev.address = file.address;
dev.size = file.size;
dev.oob_format = file.oob_format;
retval = nand_fileio_start(CMD_CTX, nand, NULL, FILEIO_NONE, &dev);
if (ERROR_OK != retval)
return retval;
while (file.size > 0)
{
int retval = nand_read_page(nand, dev.address / dev.page_size,
dev.page, dev.page_size, dev.oob, dev.oob_size);
if (ERROR_OK != retval)
{
command_print(CMD_CTX, "reading NAND flash page failed");
nand_fileio_cleanup(&dev);
return nand_fileio_cleanup(&file);
}
int bytes_read = nand_fileio_read(nand, &file);
if (bytes_read <= 0)
{
command_print(CMD_CTX, "error while reading file");
nand_fileio_cleanup(&dev);
return nand_fileio_cleanup(&file);
}
if ((dev.page && memcmp(dev.page, file.page, dev.page_size)) ||
(dev.oob && memcmp(dev.oob, file.oob, dev.oob_size)) )
{
command_print(CMD_CTX, "NAND flash contents differ "
"at 0x%8.8" PRIx32, dev.address);
nand_fileio_cleanup(&dev);
return nand_fileio_cleanup(&file);
}
file.size -= bytes_read;
dev.address += nand->page_size;
}
if (nand_fileio_finish(&file) == ERROR_OK)
{
command_print(CMD_CTX, "verified file %s in NAND flash %s "
"up to offset 0x%8.8" PRIx32 " in %fs (%0.3f kb/s)",
CMD_ARGV[1], CMD_ARGV[0], dev.address, duration_elapsed(&file.bench),
duration_kbps(&file.bench, dev.size));
}
return nand_fileio_cleanup(&dev);
}
COMMAND_HANDLER(handle_nand_dump_command)
{
struct nand_device *nand = NULL;
struct nand_fileio_state s;
int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,
&s, &nand, FILEIO_WRITE, true, false);
if (ERROR_OK != retval)
return retval;
while (s.size > 0)
{
size_t size_written;
int retval = nand_read_page(nand, s.address / nand->page_size,
s.page, s.page_size, s.oob, s.oob_size);
if (ERROR_OK != retval)
{
command_print(CMD_CTX, "reading NAND flash page failed");
return nand_fileio_cleanup(&s);
}
if (NULL != s.page)
fileio_write(&s.fileio, s.page_size, s.page, &size_written);
if (NULL != s.oob)
fileio_write(&s.fileio, s.oob_size, s.oob, &size_written);
s.size -= nand->page_size;
s.address += nand->page_size;
}
if (nand_fileio_finish(&s) == ERROR_OK)
{
command_print(CMD_CTX, "dumped %ld bytes in %fs (%0.3f kb/s)",
(long)s.fileio.size, duration_elapsed(&s.bench),
duration_kbps(&s.bench, s.fileio.size));
}
return ERROR_OK;
}
COMMAND_HANDLER(handle_nand_raw_access_command)
{
if ((CMD_ARGC < 1) || (CMD_ARGC > 2))
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
struct nand_device *p;
int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
if (ERROR_OK != retval)
return retval;
if (NULL == p->device)
{
command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]);
return ERROR_OK;
}
if (CMD_ARGC == 2)
COMMAND_PARSE_ENABLE(CMD_ARGV[1], p->use_raw);
const char *msg = p->use_raw ? "enabled" : "disabled";
command_print(CMD_CTX, "raw access is %s", msg);
return ERROR_OK;
}
static const struct command_registration nand_exec_command_handlers[] = {
{
.name = "list",
.handler = handle_nand_list_command,
.mode = COMMAND_EXEC,
.help = "list configured NAND flash devices",
},
{
.name = "info",
.handler = handle_nand_info_command,
.mode = COMMAND_EXEC,
.usage = "[banknum | first_bank_num last_bank_num]",
.help = "print info about one or more NAND flash devices",
},
{
.name = "probe",
.handler = handle_nand_probe_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "identify NAND flash device",
},
{
.name = "check_bad_blocks",
.handler = handle_nand_check_bad_blocks_command,
.mode = COMMAND_EXEC,
.usage = "bank_id [offset length]",
.help = "check all or part of NAND flash device for bad blocks",
},
{
.name = "erase",
.handler = handle_nand_erase_command,
.mode = COMMAND_EXEC,
.usage = "bank_id [offset length]",
.help = "erase all or subset of blocks on NAND flash device",
},
{
.name = "dump",
.handler = handle_nand_dump_command,
.mode = COMMAND_EXEC,
.usage = "bank_id filename offset length "
"['oob_raw'|'oob_only']",
.help = "dump from NAND flash device",
},
{
.name = "verify",
.handler = handle_nand_verify_command,
.mode = COMMAND_EXEC,
.usage = "bank_id filename offset "
"['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']",
.help = "verify NAND flash device",
},
{
.name = "write",
.handler = handle_nand_write_command,
.mode = COMMAND_EXEC,
.usage = "bank_id filename offset "
"['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']",
.help = "write to NAND flash device",
},
{
.name = "raw_access",
.handler = handle_nand_raw_access_command,
.mode = COMMAND_EXEC,
.usage = "bank_id ['enable'|'disable']",
.help = "raw access to NAND flash device",
},
COMMAND_REGISTRATION_DONE
};
int nand_init(struct command_context *cmd_ctx)
{
if (!nand_devices)
return ERROR_OK;
struct command *parent = command_find_in_context(cmd_ctx, "nand");
return register_commands(cmd_ctx, parent, nand_exec_command_handlers);
}
COMMAND_HANDLER(handle_nand_init_command)
{
if (CMD_ARGC != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
static bool nand_initialized = false;
if (nand_initialized)
{
LOG_INFO("'nand init' has already been called");
return ERROR_OK;
}
nand_initialized = true;
LOG_DEBUG("Initializing NAND devices...");
return nand_init(CMD_CTX);
}
int nand_list_walker(struct nand_flash_controller *c, void *x)
{
struct command_context *cmd_ctx = (struct command_context *)x;
command_print(cmd_ctx, " %s", c->name);
return ERROR_OK;
}
COMMAND_HANDLER(handle_nand_list_drivers)
{
command_print(CMD_CTX, "Available NAND flash controller drivers:");
return nand_driver_walk(&nand_list_walker, CMD_CTX);
}
static COMMAND_HELPER(create_nand_device, const char *bank_name,
struct nand_flash_controller *controller)
{
if (NULL != controller->commands)
{
int retval = register_commands(CMD_CTX, NULL,
controller->commands);
if (ERROR_OK != retval)
return retval;
}
struct nand_device *c = malloc(sizeof(struct nand_device));
c->name = strdup(bank_name);
c->controller = controller;
c->controller_priv = NULL;
c->manufacturer = NULL;
c->device = NULL;
c->bus_width = 0;
c->address_cycles = 0;
c->page_size = 0;
c->use_raw = 0;
c->next = NULL;
int retval = CALL_COMMAND_HANDLER(controller->nand_device_command, c);
if (ERROR_OK != retval)
{
LOG_ERROR("'%s' driver rejected nand flash", controller->name);
free(c);
return ERROR_OK;
}
nand_device_add(c);
return ERROR_OK;
}
COMMAND_HANDLER(handle_nand_device_command)
{
if (CMD_ARGC < 1)
{
LOG_ERROR("incomplete nand device configuration");
return ERROR_FLASH_BANK_INVALID;
}
// save name and increment (for compatibility) with drivers
const char *bank_name = *CMD_ARGV++;
CMD_ARGC--;
const char *driver_name = CMD_ARGV[0];
struct nand_flash_controller *controller;
controller = nand_driver_find_by_name(CMD_ARGV[0]);
if (NULL == controller)
{
LOG_ERROR("No valid NAND flash driver found (%s)", driver_name);
return CALL_COMMAND_HANDLER(handle_nand_list_drivers);
}
return CALL_COMMAND_HANDLER(create_nand_device, bank_name, controller);
}
static const struct command_registration nand_config_command_handlers[] = {
{
.name = "device",
.handler = &handle_nand_device_command,
.mode = COMMAND_CONFIG,
.help = "defines a new NAND bank",
.usage = "bank_id driver target [driver_options ...]",
},
{
.name = "drivers",
.handler = &handle_nand_list_drivers,
.mode = COMMAND_ANY,
.help = "lists available NAND drivers",
},
{
.name = "init",
.mode = COMMAND_CONFIG,
.handler = &handle_nand_init_command,
.help = "initialize NAND devices",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration nand_command_handlers[] = {
{
.name = "nand",
.mode = COMMAND_ANY,
.help = "NAND flash command group",
.chain = nand_config_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
int nand_register_commands(struct command_context *cmd_ctx)
{
return register_commands(cmd_ctx, NULL, nand_command_handlers);
}

53
src/flash/nor/Makefile.am Normal file
View File

@@ -0,0 +1,53 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src \
-I$(top_builddir)/src
noinst_LTLIBRARIES = libocdflashnor.la
libocdflashnor_la_SOURCES = \
core.c \
tcl.c \
$(NOR_DRIVERS) \
drivers.c
NOR_DRIVERS = \
aduc702x.c \
at91sam3.c \
at91sam7.c \
avrf.c \
cfi.c \
ecos.c \
faux.c \
lpc2000.c \
lpc288x.c \
lpc2900.c \
non_cfi.c \
ocl.c \
pic32mx.c \
stellaris.c \
stm32x.c \
str7x.c \
str9x.c \
str9xpec.c \
tms470.c
noinst_HEADERS = \
at91sam7.h \
at91sam3.h \
avrf.h \
core.h \
cfi.h \
driver.h \
imp.h \
lpc2000.h \
lpc288x.h \
non_cfi.h \
ocl.h \
pic32mx.h \
stellaris.h \
stm32x.h \
str7x.h \
str9x.h \
str9xpec.h \
tms470.h
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in

View File

@@ -23,25 +23,16 @@
#include "config.h"
#endif
#include "flash.h"
#include "armv4_5.h"
#include "binarybuffer.h"
#include "time_support.h"
#include "imp.h"
#include <helper/binarybuffer.h>
#include <helper/time_support.h>
#include <target/algorithm.h>
#include <target/arm.h>
static int aduc702x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int aduc702x_register_commands(struct command_context_s *cmd_ctx);
static int aduc702x_erase(struct flash_bank_s *bank, int first, int last);
static int aduc702x_protect(struct flash_bank_s *bank, int set, int first, int last);
static int aduc702x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int aduc702x_write_single(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int aduc702x_probe(struct flash_bank_s *bank);
static int aduc702x_info(struct flash_bank_s *bank, char *buf, int buf_size);
static int aduc702x_protect_check(struct flash_bank_s *bank);
static int aduc702x_build_sector_list(struct flash_bank_s *bank);
static int aduc702x_check_flash_completion(target_t* target, unsigned int timeout_ms);
static int aduc702x_set_write_enable(target_t *target, int enable);
static int aduc702x_build_sector_list(struct flash_bank *bank);
static int aduc702x_check_flash_completion(struct target* target, unsigned int timeout_ms);
static int aduc702x_set_write_enable(struct target *target, int enable);
#define ADUC702x_FLASH 0xfffff800
#define ADUC702x_FLASH_FEESTA (0*4)
@@ -53,49 +44,17 @@ static int aduc702x_set_write_enable(target_t *target, int enable);
#define ADUC702x_FLASH_FEEPRO (6*4)
#define ADUC702x_FLASH_FEEHIDE (7*4)
typedef struct {
uint32_t feesta;
uint32_t feemod;
uint32_t feecon;
uint32_t feedat;
uint32_t feeadr;
uint32_t feesign;
uint32_t feepro;
uint32_t feehide;
} ADUC702x_FLASH_MMIO;
typedef struct
{
working_area_t *write_algorithm;
} aduc702x_flash_bank_t;
flash_driver_t aduc702x_flash =
{
.name = "aduc702x",
.register_commands = aduc702x_register_commands,
.flash_bank_command = aduc702x_flash_bank_command,
.erase = aduc702x_erase,
.protect = aduc702x_protect,
.write = aduc702x_write,
.probe = aduc702x_probe,
.auto_probe = aduc702x_probe,
.erase_check = default_flash_blank_check,
.protect_check = aduc702x_protect_check,
.info = aduc702x_info
struct aduc702x_flash_bank {
struct working_area *write_algorithm;
};
static int aduc702x_register_commands(struct command_context_s *cmd_ctx)
{
return ERROR_OK;
}
/* flash bank aduc702x 0 0 0 0 <target#>
* The ADC7019-28 devices all have the same flash layout */
static int aduc702x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
FLASH_BANK_COMMAND_HANDLER(aduc702x_flash_bank_command)
{
aduc702x_flash_bank_t *nbank;
struct aduc702x_flash_bank *nbank;
nbank = malloc(sizeof(aduc702x_flash_bank_t));
nbank = malloc(sizeof(struct aduc702x_flash_bank));
bank->base = 0x80000;
bank->size = 0xF800; // top 4k not accessible
@@ -106,16 +65,16 @@ static int aduc702x_flash_bank_command(struct command_context_s *cmd_ctx, char *
return ERROR_OK;
}
static int aduc702x_build_sector_list(struct flash_bank_s *bank)
static int aduc702x_build_sector_list(struct flash_bank *bank)
{
//aduc7026_flash_bank_t *aduc7026_info = bank->driver_priv;
//aduc7026_struct flash_bank *aduc7026_info = bank->driver_priv;
int i = 0;
uint32_t offset = 0;
// sector size is 512
bank->num_sectors = bank->size / 512;
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
for (i = 0; i < bank->num_sectors; ++i)
{
bank->sectors[i].offset = offset;
@@ -128,19 +87,19 @@ static int aduc702x_build_sector_list(struct flash_bank_s *bank)
return ERROR_OK;
}
static int aduc702x_protect_check(struct flash_bank_s *bank)
static int aduc702x_protect_check(struct flash_bank *bank)
{
printf("aduc702x_protect_check not implemented yet.\n");
return ERROR_OK;
}
static int aduc702x_erase(struct flash_bank_s *bank, int first, int last)
static int aduc702x_erase(struct flash_bank *bank, int first, int last)
{
//int res;
int x;
int count;
//uint32_t v;
target_t *target = bank->target;
struct target *target = bank->target;
aduc702x_set_write_enable(target, 1);
@@ -187,7 +146,7 @@ static int aduc702x_erase(struct flash_bank_s *bank, int first, int last)
return ERROR_OK;
}
static int aduc702x_protect(struct flash_bank_s *bank, int set, int first, int last)
static int aduc702x_protect(struct flash_bank *bank, int set, int first, int last)
{
printf("aduc702x_protect not implemented yet.\n");
return ERROR_FLASH_OPERATION_FAILED;
@@ -198,15 +157,15 @@ static int aduc702x_protect(struct flash_bank_s *bank, int set, int first, int l
*
* Caller should not check for other return values specifically
*/
static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int aduc702x_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
aduc702x_flash_bank_t *aduc702x_info = bank->driver_priv;
target_t *target = bank->target;
struct aduc702x_flash_bank *aduc702x_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t buffer_size = 7000;
working_area_t *source;
struct working_area *source;
uint32_t address = bank->base + offset;
reg_param_t reg_params[6];
armv4_5_algorithm_t armv4_5_info;
struct reg_param reg_params[6];
struct arm_algorithm armv4_5_info;
int retval = ERROR_OK;
if (((count%2)!=0)||((offset%2)!=0))
@@ -282,9 +241,9 @@ static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint
}
}
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;
armv4_5_info.common_magic = ARM_COMMON_MAGIC;
armv4_5_info.core_mode = ARM_MODE_SVC;
armv4_5_info.core_state = ARM_STATE_ARM;
init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
@@ -343,11 +302,11 @@ static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint
/* All-JTAG, single-access method. Very slow. Used only if there is no
* working area available. */
static int aduc702x_write_single(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int aduc702x_write_single(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
uint32_t x;
uint8_t b;
target_t *target = bank->target;
struct target *target = bank->target;
aduc702x_set_write_enable(target, 1);
@@ -384,7 +343,7 @@ static int aduc702x_write_single(struct flash_bank_s *bank, uint8_t *buffer, uin
return ERROR_OK;
}
int aduc702x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
int aduc702x_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
int retval;
@@ -408,12 +367,12 @@ int aduc702x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset,
return retval;
}
static int aduc702x_probe(struct flash_bank_s *bank)
static int aduc702x_probe(struct flash_bank *bank)
{
return ERROR_OK;
}
static int aduc702x_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int aduc702x_info(struct flash_bank *bank, char *buf, int buf_size)
{
snprintf(buf, buf_size, "aduc702x flash driver info");
return ERROR_OK;
@@ -421,7 +380,7 @@ static int aduc702x_info(struct flash_bank_s *bank, char *buf, int buf_size)
/* sets FEEMOD bit 3
* enable = 1 enables writes & erases, 0 disables them */
static int aduc702x_set_write_enable(target_t *target, int enable)
static int aduc702x_set_write_enable(struct target *target, int enable)
{
// don't bother to preserve int enable bit here
target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEMOD, enable ? 8 : 0);
@@ -434,7 +393,7 @@ static int aduc702x_set_write_enable(target_t *target, int enable)
*
* this function sleeps 1ms between checks (after the first one),
* so in some cases may slow things down without a usleep after the first read */
static int aduc702x_check_flash_completion(target_t* target, unsigned int timeout_ms)
static int aduc702x_check_flash_completion(struct target* target, unsigned int timeout_ms)
{
uint8_t v = 4;
@@ -452,3 +411,15 @@ static int aduc702x_check_flash_completion(target_t* target, unsigned int timeou
else return ERROR_OK;
}
struct flash_driver aduc702x_flash = {
.name = "aduc702x",
.flash_bank_command = aduc702x_flash_bank_command,
.erase = aduc702x_erase,
.protect = aduc702x_protect,
.write = aduc702x_write,
.probe = aduc702x_probe,
.auto_probe = aduc702x_probe,
.erase_check = default_flash_blank_check,
.protect_check = aduc702x_protect_check,
.info = aduc702x_info
};

View File

@@ -57,16 +57,10 @@
#endif
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include "log.h"
#include "types.h"
#include "flash.h"
#include "target.h"
#include "membuf.h"
#include "imp.h"
#include "at91sam3.h"
#include "time_support.h"
#include <helper/membuf.h>
#include <helper/time_support.h>
#define REG_NAME_WIDTH (12)
@@ -175,7 +169,7 @@ struct sam3_bank_private {
// so we can find the chip we belong to
struct sam3_chip *pChip;
// so we can find the orginal bank pointer
flash_bank_t *pBank;
struct flash_bank *pBank;
unsigned bank_number;
uint32_t controller_address;
uint32_t base_address;
@@ -215,7 +209,7 @@ struct sam3_chip {
// this is "initialized" from the global const structure
struct sam3_chip_details details;
target_t *target;
struct target *target;
struct sam3_cfg cfg;
struct membuf *mbuf;
@@ -231,9 +225,9 @@ struct sam3_reg_list {
static struct sam3_chip *all_sam3_chips;
static struct sam3_chip *
get_current_sam3(struct command_context_s *cmd_ctx)
get_current_sam3(struct command_context *cmd_ctx)
{
target_t *t;
struct target *t;
static struct sam3_chip *p;
t = get_current_target(cmd_ctx);
@@ -1393,7 +1387,7 @@ sam3_explain_mckr(struct sam3_chip *pChip)
#if 0
static struct sam3_chip *
target2sam3(target_t *pTarget)
target2sam3(struct target *pTarget)
{
struct sam3_chip *pChip;
@@ -1456,7 +1450,7 @@ static const struct sam3_reg_list sam3_all_regs[] = {
static struct sam3_bank_private *
get_sam3_bank_private(flash_bank_t *bank)
get_sam3_bank_private(struct flash_bank *bank)
{
return (struct sam3_bank_private *)(bank->driver_priv);
}
@@ -1582,7 +1576,7 @@ sam3_GetInfo(struct sam3_chip *pChip)
static int
sam3_erase_check(struct flash_bank_s *bank)
sam3_erase_check(struct flash_bank *bank)
{
int x;
@@ -1606,7 +1600,7 @@ sam3_erase_check(struct flash_bank_s *bank)
}
static int
sam3_protect_check(struct flash_bank_s *bank)
sam3_protect_check(struct flash_bank *bank)
{
int r;
uint32_t v=0;
@@ -1641,12 +1635,7 @@ sam3_protect_check(struct flash_bank_s *bank)
return ERROR_OK;
}
static int
sam3_flash_bank_command(struct command_context_s *cmd_ctx,
char *cmd,
char **args,
int argc,
struct flash_bank_s *bank)
FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command)
{
struct sam3_chip *pChip;
@@ -1714,7 +1703,7 @@ sam3_GetDetails(struct sam3_bank_private *pPrivate)
const struct sam3_chip_details *pDetails;
struct sam3_chip *pChip;
void *vp;
flash_bank_t *saved_banks[SAM3_MAX_FLASH_BANKS];
struct flash_bank *saved_banks[SAM3_MAX_FLASH_BANKS];
unsigned x;
const char *cp;
@@ -1782,7 +1771,7 @@ sam3_GetDetails(struct sam3_bank_private *pPrivate)
static int
_sam3_probe(struct flash_bank_s *bank, int noise)
_sam3_probe(struct flash_bank *bank, int noise)
{
unsigned x;
int r;
@@ -1866,13 +1855,13 @@ _sam3_probe(struct flash_bank_s *bank, int noise)
}
static int
sam3_probe(struct flash_bank_s *bank)
sam3_probe(struct flash_bank *bank)
{
return _sam3_probe(bank, 1);
}
static int
sam3_auto_probe(struct flash_bank_s *bank)
sam3_auto_probe(struct flash_bank *bank)
{
return _sam3_probe(bank, 0);
}
@@ -1880,7 +1869,7 @@ sam3_auto_probe(struct flash_bank_s *bank)
static int
sam3_erase(struct flash_bank_s *bank, int first, int last)
sam3_erase(struct flash_bank *bank, int first, int last)
{
struct sam3_bank_private *pPrivate;
int r;
@@ -1912,7 +1901,7 @@ sam3_erase(struct flash_bank_s *bank, int first, int last)
}
static int
sam3_protect(struct flash_bank_s *bank, int set, int first, int last)
sam3_protect(struct flash_bank *bank, int set, int first, int last)
{
struct sam3_bank_private *pPrivate;
int r;
@@ -1941,7 +1930,7 @@ sam3_protect(struct flash_bank_s *bank, int set, int first, int last)
static int
sam3_info(flash_bank_t *bank, char *buf, int buf_size)
sam3_info(struct flash_bank *bank, char *buf, int buf_size)
{
if (bank->target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
@@ -2109,7 +2098,7 @@ sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, uint8_t *b
static int
sam3_write(struct flash_bank_s *bank,
sam3_write(struct flash_bank *bank,
uint8_t *buffer,
uint32_t offset,
uint32_t count)
@@ -2266,8 +2255,7 @@ sam3_write(struct flash_bank_s *bank,
return r;
}
static int
sam3_handle_info_command(struct command_context_s *cmd_ctx, char *cmd, char **argv, int argc)
COMMAND_HANDLER(sam3_handle_info_command)
{
struct sam3_chip *pChip;
void *vp;
@@ -2275,7 +2263,7 @@ sam3_handle_info_command(struct command_context_s *cmd_ctx, char *cmd, char **ar
unsigned x;
int r;
pChip = get_current_sam3(cmd_ctx);
pChip = get_current_sam3(CMD_CTX);
if (!pChip) {
return ERROR_OK;
}
@@ -2286,7 +2274,7 @@ sam3_handle_info_command(struct command_context_s *cmd_ctx, char *cmd, char **ar
if (pChip->details.bank[0].pBank == NULL) {
x = 0;
need_define:
command_print(cmd_ctx,
command_print(CMD_CTX,
"Please define bank %d via command: flash bank %s ... ",
x,
at91sam3_flash.name);
@@ -2300,7 +2288,7 @@ sam3_handle_info_command(struct command_context_s *cmd_ctx, char *cmd, char **ar
return ERROR_FAIL;
}
}
// above garentees the "chip details" structure is valid
// above guarantees the "chip details" structure is valid
// and thus, bank private areas are valid
// and we have a SAM3 chip, what a concept!
@@ -2337,21 +2325,19 @@ sam3_handle_info_command(struct command_context_s *cmd_ctx, char *cmd, char **ar
// print results
cp = membuf_strtok(pChip->mbuf, "\n", &vp);
while (cp) {
command_print(cmd_ctx,"%s", cp);
command_print(CMD_CTX,"%s", cp);
cp = membuf_strtok(NULL, "\n", &vp);
}
return ERROR_OK;
}
static int
sam3_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **argv, int argc)
COMMAND_HANDLER(sam3_handle_gpnvm_command)
{
unsigned x,v;
uint32_t v32;
int r,who;
struct sam3_chip *pChip;
pChip = get_current_sam3(cmd_ctx);
pChip = get_current_sam3(CMD_CTX);
if (!pChip) {
return ERROR_OK;
}
@@ -2363,7 +2349,7 @@ sam3_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **a
if (pChip->details.bank[0].pBank == NULL) {
command_print(cmd_ctx, "Bank0 must be defined first via: flash bank %s ...",
command_print(CMD_CTX, "Bank0 must be defined first via: flash bank %s ...",
at91sam3_flash.name);
return ERROR_FAIL;
}
@@ -2375,9 +2361,9 @@ sam3_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **a
}
switch (argc) {
switch (CMD_ARGC) {
default:
command_print(cmd_ctx,"Too many parameters\n");
command_print(CMD_CTX,"Too many parameters\n");
return ERROR_COMMAND_SYNTAX_ERROR;
break;
case 0:
@@ -2388,144 +2374,142 @@ sam3_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **a
who = -1;
break;
case 2:
if ((0 == strcmp(argv[0], "show")) && (0 == strcmp(argv[1], "all"))) {
if ((0 == strcmp(CMD_ARGV[0], "show")) && (0 == strcmp(CMD_ARGV[1], "all"))) {
who = -1;
} else {
r = parse_u32(argv[1], &v32);
if (r != ERROR_OK) {
command_print(cmd_ctx, "Not a number: %s", argv[1]);
return r;
}
uint32_t v32;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);
who = v32;
}
break;
}
if (0 == strcmp("show", argv[0])) {
if (0 == strcmp("show", CMD_ARGV[0])) {
if (who == -1) {
showall:
showall:
r = ERROR_OK;
for (x = 0 ; x < pChip->details.n_gpnvms ; x++) {
r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), x, &v);
if (r != ERROR_OK) {
break;
}
command_print(cmd_ctx, "sam3-gpnvm%u: %u", x, v);
command_print(CMD_CTX, "sam3-gpnvm%u: %u", x, v);
}
return r;
}
if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) {
r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v);
command_print(cmd_ctx, "sam3-gpnvm%u: %u", who, v);
command_print(CMD_CTX, "sam3-gpnvm%u: %u", who, v);
return r;
} else {
command_print(cmd_ctx, "sam3-gpnvm invalid GPNVM: %u", who);
command_print(CMD_CTX, "sam3-gpnvm invalid GPNVM: %u", who);
return ERROR_COMMAND_SYNTAX_ERROR;
}
}
if (who == -1) {
command_print(cmd_ctx, "Missing GPNVM number");
command_print(CMD_CTX, "Missing GPNVM number");
return ERROR_COMMAND_SYNTAX_ERROR;
}
if (0 == strcmp("set", argv[0])) {
if (0 == strcmp("set", CMD_ARGV[0])) {
r = FLASHD_SetGPNVM(&(pChip->details.bank[0]), who);
} else if ((0 == strcmp("clr", argv[0])) ||
(0 == strcmp("clear", argv[0]))) { // quietly accept both
} else if ((0 == strcmp("clr", CMD_ARGV[0])) ||
(0 == strcmp("clear", CMD_ARGV[0]))) { // quietly accept both
r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who);
} else {
command_print(cmd_ctx, "Unkown command: %s", argv[0]);
command_print(CMD_CTX, "Unkown command: %s", CMD_ARGV[0]);
r = ERROR_COMMAND_SYNTAX_ERROR;
}
return r;
}
static int
sam3_handle_slowclk_command(struct command_context_s *cmd_ctx, char *cmd, char **argv, int argc)
COMMAND_HANDLER(sam3_handle_slowclk_command)
{
uint32_t v;
int r;
struct sam3_chip *pChip;
pChip = get_current_sam3(cmd_ctx);
pChip = get_current_sam3(CMD_CTX);
if (!pChip) {
return ERROR_OK;
}
switch (argc) {
switch (CMD_ARGC) {
case 0:
// show
break;
case 1:
{
// set
r = parse_u32(argv[0], &v);
uint32_t v;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v);
if (v > 200000) {
// absurd slow clock of 200Khz?
command_print(cmd_ctx,"Absurd/illegal slow clock freq: %d\n", (int)(v));
command_print(CMD_CTX,"Absurd/illegal slow clock freq: %d\n", (int)(v));
return ERROR_COMMAND_SYNTAX_ERROR;
}
pChip->cfg.slow_freq = v;
break;
}
default:
// error
command_print(cmd_ctx,"Too many parameters");
command_print(CMD_CTX,"Too many parameters");
return ERROR_COMMAND_SYNTAX_ERROR;
break;
}
command_print(cmd_ctx, "Slowclk freq: %d.%03dkhz",
command_print(CMD_CTX, "Slowclk freq: %d.%03dkhz",
(int)(pChip->cfg.slow_freq/ 1000),
(int)(pChip->cfg.slow_freq% 1000));
return ERROR_OK;
}
static int sam3_registered;
static int
sam3_register_commands(struct command_context_s *cmd_ctx)
{
command_t *pCmd;
// only register once
if (!sam3_registered) {
sam3_registered++;
pCmd = register_command(cmd_ctx, NULL, "at91sam3", NULL, COMMAND_ANY, NULL);
register_command(cmd_ctx, pCmd,
"gpnvm",
sam3_handle_gpnvm_command,
COMMAND_EXEC,
"at91sam3 gpnvm [action [<BIT>], by default 'show', otherwise set | clear BIT");
register_command(cmd_ctx, pCmd,
"info",
sam3_handle_info_command,
COMMAND_EXEC,
"at91sam3 info - print information about the current sam3 chip");
register_command(cmd_ctx, pCmd,
"slowclk",
sam3_handle_slowclk_command,
COMMAND_EXEC,
"at91sam3 slowclk [VALUE] set the slowclock frequency (default 32768hz)");
}
return ERROR_OK;
}
flash_driver_t at91sam3_flash =
{
.name = "at91sam3",
.register_commands = sam3_register_commands,
.flash_bank_command = sam3_flash_bank_command,
.erase = sam3_erase,
.protect = sam3_protect,
.write = sam3_write,
.probe = sam3_probe,
.auto_probe = sam3_auto_probe,
.erase_check = sam3_erase_check,
.protect_check = sam3_protect_check,
.info = sam3_info
static const struct command_registration at91sam3_exec_command_handlers[] = {
{
.name = "gpnvm",
.handler = sam3_handle_gpnvm_command,
.mode = COMMAND_EXEC,
.usage = "[('clr'|'set'|'show') bitnum]",
.help = "Without arguments, shows all bits in the gpnvm "
"register. Otherwise, clears, sets, or shows one "
"General Purpose Non-Volatile Memory (gpnvm) bit.",
},
{
.name = "info",
.handler = sam3_handle_info_command,
.mode = COMMAND_EXEC,
.help = "Print information about the current at91sam3 chip"
"and its flash configuration.",
},
{
.name = "slowclk",
.handler = sam3_handle_slowclk_command,
.mode = COMMAND_EXEC,
.usage = "[clock_hz]",
.help = "Display or set the slowclock frequency "
"(default 32768 Hz).",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration at91sam3_command_handlers[] = {
{
.name = "at91sam3",
.mode = COMMAND_ANY,
.help = "at91sam3 flash command group",
.chain = at91sam3_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
struct flash_driver at91sam3_flash = {
.name = "at91sam3",
.commands = at91sam3_command_handlers,
.flash_bank_command = sam3_flash_bank_command,
.erase = sam3_erase,
.protect = sam3_protect,
.write = sam3_write,
.probe = sam3_probe,
.auto_probe = sam3_auto_probe,
.erase_check = sam3_erase_check,
.protect_check = sam3_protect_check,
.info = sam3_info,
};

View File

@@ -20,4 +20,4 @@
// nothing to do here other then export this.
extern flash_driver_t at91sam3_flash;
extern struct flash_driver at91sam3_flash;

View File

@@ -49,41 +49,17 @@
#include "config.h"
#endif
#include "imp.h"
#include "at91sam7.h"
#include "binarybuffer.h"
#include <helper/binarybuffer.h>
static int at91sam7_protect_check(struct flash_bank *bank);
static int at91sam7_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int at91sam7_register_commands(struct command_context_s *cmd_ctx);
static int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int at91sam7_erase(struct flash_bank_s *bank, int first, int last);
static int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last);
static int at91sam7_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int at91sam7_probe(struct flash_bank_s *bank);
//static int at91sam7_auto_probe(struct flash_bank_s *bank);
static int at91sam7_erase_check(struct flash_bank_s *bank);
static int at91sam7_protect_check(struct flash_bank_s *bank);
static int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size);
static uint32_t at91sam7_get_flash_status(target_t *target, int bank_number);
static void at91sam7_set_flash_mode(flash_bank_t *bank, int mode);
static uint32_t at91sam7_wait_status_busy(flash_bank_t *bank, uint32_t waitbits, int timeout);
static int at91sam7_flash_command(struct flash_bank_s *bank, uint8_t cmd, uint16_t pagen);
static int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
flash_driver_t at91sam7_flash =
{
.name = "at91sam7",
.register_commands = at91sam7_register_commands,
.flash_bank_command = at91sam7_flash_bank_command,
.erase = at91sam7_erase,
.protect = at91sam7_protect,
.write = at91sam7_write,
.probe = at91sam7_probe,
.auto_probe = at91sam7_probe,
.erase_check = at91sam7_erase_check,
.protect_check = at91sam7_protect_check,
.info = at91sam7_info
};
static uint32_t at91sam7_get_flash_status(struct target *target, int bank_number);
static void at91sam7_set_flash_mode(struct flash_bank *bank, int mode);
static uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout);
static int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen);
static uint32_t MC_FMR[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
static uint32_t MC_FCR[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
@@ -112,16 +88,8 @@ static long SRAMSIZ[16] = {
};
#endif
static int at91sam7_register_commands(struct command_context_s *cmd_ctx)
{
command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "at91sam7", NULL, COMMAND_ANY, NULL);
register_command(cmd_ctx, at91sam7_cmd, "gpnvm", at91sam7_handle_gpnvm_command, COMMAND_EXEC,
"at91sam7 gpnvm <bit> set | clear, set or clear one gpnvm bit");
return ERROR_OK;
}
static uint32_t at91sam7_get_flash_status(target_t *target, int bank_number)
static uint32_t at91sam7_get_flash_status(struct target *target, int bank_number)
{
uint32_t fsr;
target_read_u32(target, MC_FSR[bank_number], &fsr);
@@ -130,10 +98,10 @@ static uint32_t at91sam7_get_flash_status(target_t *target, int bank_number)
}
/* Read clock configuration and set at91sam7_info->mck_freq */
static void at91sam7_read_clock_info(flash_bank_t *bank)
static void at91sam7_read_clock_info(struct flash_bank *bank)
{
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
target_t *target = bank->target;
struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t mckr, mcfr, pllr, mor;
unsigned long tmp = 0, mainfreq;
@@ -209,11 +177,11 @@ static void at91sam7_read_clock_info(flash_bank_t *bank)
}
/* Setup the timimg registers for nvbits or normal flash */
static void at91sam7_set_flash_mode(flash_bank_t *bank, int mode)
static void at91sam7_set_flash_mode(struct flash_bank *bank, int mode)
{
uint32_t fmr, fmcn = 0, fws = 0;
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
target_t *target = bank->target;
struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
struct target *target = bank->target;
if (mode && (mode != at91sam7_info->flashmode))
{
@@ -257,7 +225,7 @@ static void at91sam7_set_flash_mode(flash_bank_t *bank, int mode)
at91sam7_info->flashmode = mode;
}
static uint32_t at91sam7_wait_status_busy(flash_bank_t *bank, uint32_t waitbits, int timeout)
static uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout)
{
uint32_t status;
@@ -284,11 +252,11 @@ static uint32_t at91sam7_wait_status_busy(flash_bank_t *bank, uint32_t waitbits,
}
/* Send one command to the AT91SAM flash controller */
static int at91sam7_flash_command(struct flash_bank_s *bank, uint8_t cmd, uint16_t pagen)
static int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen)
{
uint32_t fcr;
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
target_t *target = bank->target;
struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
struct target *target = bank->target;
fcr = (0x5A << 24) | ((pagen&0x3FF) << 8) | cmd;
target_write_u32(target, MC_FCR[bank->bank_number], fcr);
@@ -313,11 +281,11 @@ static int at91sam7_flash_command(struct flash_bank_s *bank, uint8_t cmd, uint16
}
/* Read device id register, main clock frequency register and fill in driver info structure */
static int at91sam7_read_part_info(struct flash_bank_s *bank)
static int at91sam7_read_part_info(struct flash_bank *bank)
{
flash_bank_t *t_bank = bank;
at91sam7_flash_bank_t *at91sam7_info;
target_t *target = t_bank->target;
struct flash_bank *t_bank = bank;
struct at91sam7_flash_bank *at91sam7_info;
struct target *target = t_bank->target;
uint16_t bnk, sec;
uint16_t arch;
@@ -337,7 +305,7 @@ static int at91sam7_read_part_info(struct flash_bank_s *bank)
if (at91sam7_info->cidr != 0)
{
/* flash already configured, update clock and check for protected sectors */
flash_bank_t *fb = bank;
struct flash_bank *fb = bank;
t_bank = fb;
while (t_bank)
@@ -369,7 +337,7 @@ static int at91sam7_read_part_info(struct flash_bank_s *bank)
if (at91sam7_info->flash_autodetection == 0)
{
/* banks and sectors are already created, based on data from input file */
flash_bank_t *fb = bank;
struct flash_bank *fb = bank;
t_bank = fb;
while (t_bank)
{
@@ -565,10 +533,10 @@ static int at91sam7_read_part_info(struct flash_bank_s *bank)
if (bnk > 0)
{
/* create a new flash bank element */
flash_bank_t *fb = malloc(sizeof(flash_bank_t));
struct flash_bank *fb = malloc(sizeof(struct flash_bank));
fb->target = target;
fb->driver = &at91sam7_flash;
fb->driver_priv = malloc(sizeof(at91sam7_flash_bank_t));
fb->driver = bank->driver;
fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
fb->next = NULL;
/* link created bank in 'flash_banks' list and redirect t_bank */
@@ -584,7 +552,7 @@ static int at91sam7_read_part_info(struct flash_bank_s *bank)
t_bank->num_sectors = sectors_num;
/* allocate sectors */
t_bank->sectors = malloc(sectors_num * sizeof(flash_sector_t));
t_bank->sectors = malloc(sectors_num * sizeof(struct flash_sector));
for (sec = 0; sec < sectors_num; sec++)
{
t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
@@ -628,9 +596,9 @@ static int at91sam7_read_part_info(struct flash_bank_s *bank)
return ERROR_OK;
}
static int at91sam7_erase_check(struct flash_bank_s *bank)
static int at91sam7_erase_check(struct flash_bank *bank)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint16_t retval;
uint32_t blank;
uint16_t fast_check;
@@ -694,12 +662,12 @@ static int at91sam7_erase_check(struct flash_bank_s *bank)
return ERROR_OK;
}
static int at91sam7_protect_check(struct flash_bank_s *bank)
static int at91sam7_protect_check(struct flash_bank *bank)
{
uint8_t lock_pos, gpnvm_pos;
uint32_t status;
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
if (at91sam7_info->cidr == 0)
{
@@ -744,15 +712,15 @@ static int at91sam7_protect_check(struct flash_bank_s *bank)
return ERROR_OK;
}
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_COMMAND_HANDLER(at91sam7_flash_bank_command)
{
flash_bank_t *t_bank = bank;
at91sam7_flash_bank_t *at91sam7_info;
target_t *target = t_bank->target;
struct flash_bank *t_bank = bank;
struct at91sam7_flash_bank *at91sam7_info;
struct target *target = t_bank->target;
uint32_t base_address;
uint32_t bank_size;
uint32_t ext_freq;
uint32_t ext_freq = 0;
int chip_width;
int bus_width;
@@ -767,7 +735,7 @@ static int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *
int bnk, sec;
at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
at91sam7_info = malloc(sizeof(struct at91sam7_flash_bank));
t_bank->driver_priv = at91sam7_info;
/* part wasn't probed for info yet */
@@ -776,35 +744,39 @@ static int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *
at91sam7_info->ext_freq = 0;
at91sam7_info->flash_autodetection = 0;
if (argc == 14)
{
ext_freq = atol(args[13]) * 1000;
at91sam7_info->ext_freq = ext_freq;
}
if ((argc != 14) ||
(atoi(args[4]) == 0) || /* bus width */
(atoi(args[8]) == 0) || /* banks number */
(atoi(args[9]) == 0) || /* sectors per bank */
(atoi(args[10]) == 0) || /* pages per sector */
(atoi(args[11]) == 0) || /* page size */
(atoi(args[12]) == 0)) /* nvmbits number */
if (CMD_ARGC < 13)
{
at91sam7_info->flash_autodetection = 1;
return ERROR_OK;
}
base_address = strtoul(args[1], NULL, 0);
chip_width = atoi(args[3]);
bus_width = atoi(args[4]);
banks_num = atoi(args[8]);
num_sectors = atoi(args[9]);
pages_per_sector = atoi(args[10]);
page_size = atoi(args[11]);
num_nvmbits = atoi(args[12]);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], base_address);
target_name = calloc(strlen(args[7]) + 1, sizeof(char));
strcpy(target_name, args[7]);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], chip_width);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], bus_width);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[8], banks_num);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[9], num_sectors);
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[10], pages_per_sector);
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[11], page_size);
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[12], num_nvmbits);
if (CMD_ARGC == 14) {
unsigned long freq;
COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[13], freq);
ext_freq = freq * 1000;
at91sam7_info->ext_freq = ext_freq;
}
if ((bus_width == 0) || (banks_num == 0) || (num_sectors == 0) ||
(pages_per_sector == 0) || (page_size == 0) || (num_nvmbits == 0))
{
at91sam7_info->flash_autodetection = 1;
return ERROR_OK;
}
target_name = calloc(strlen(CMD_ARGV[7]) + 1, sizeof(char));
strcpy(target_name, CMD_ARGV[7]);
/* calculate bank size */
bank_size = num_sectors * pages_per_sector * page_size;
@@ -814,10 +786,10 @@ static int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *
if (bnk > 0)
{
/* create a new bank element */
flash_bank_t *fb = malloc(sizeof(flash_bank_t));
struct flash_bank *fb = malloc(sizeof(struct flash_bank));
fb->target = target;
fb->driver = &at91sam7_flash;
fb->driver_priv = malloc(sizeof(at91sam7_flash_bank_t));
fb->driver = bank->driver;
fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
fb->next = NULL;
/* link created bank in 'flash_banks' list and redirect t_bank */
@@ -833,7 +805,7 @@ static int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *
t_bank->num_sectors = num_sectors;
/* allocate sectors */
t_bank->sectors = malloc(num_sectors * sizeof(flash_sector_t));
t_bank->sectors = malloc(num_sectors * sizeof(struct flash_sector));
for (sec = 0; sec < num_sectors; sec++)
{
t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
@@ -856,9 +828,9 @@ static int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *
return ERROR_OK;
}
static int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
static int at91sam7_erase(struct flash_bank *bank, int first, int last)
{
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
int sec;
uint32_t nbytes, pos;
uint8_t *buffer;
@@ -924,13 +896,13 @@ static int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
return ERROR_OK;
}
static int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
static int at91sam7_protect(struct flash_bank *bank, int set, int first, int last)
{
uint32_t cmd;
int sector;
uint32_t pagen;
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
if (at91sam7_info->cidr == 0)
{
@@ -974,11 +946,11 @@ static int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int l
return ERROR_OK;
}
static int at91sam7_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int at91sam7_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
int retval;
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
target_t *target = bank->target;
struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t dst_min_alignment, wcount, bytes_remaining = count;
uint32_t first_page, last_page, pagen, buffer_pos;
@@ -1008,7 +980,7 @@ static int at91sam7_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t o
return ERROR_FLASH_BANK_NOT_PROBED;
first_page = offset/dst_min_alignment;
last_page = CEIL(offset + count, dst_min_alignment);
last_page = DIV_ROUND_UP(offset + count, dst_min_alignment);
LOG_DEBUG("first_page: %i, last_page: %i, count %i", (int)first_page, (int)last_page, (int)count);
@@ -1026,7 +998,7 @@ static int at91sam7_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t o
/* Write one block to the PageWriteBuffer */
buffer_pos = (pagen-first_page)*dst_min_alignment;
wcount = CEIL(count,4);
wcount = DIV_ROUND_UP(count,4);
if ((retval = target_write_memory(target, bank->base + pagen*dst_min_alignment, 4, wcount, buffer + buffer_pos)) != ERROR_OK)
{
return retval;
@@ -1043,7 +1015,7 @@ static int at91sam7_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t o
return ERROR_OK;
}
static int at91sam7_probe(struct flash_bank_s *bank)
static int at91sam7_probe(struct flash_bank *bank)
{
/* we can't probe on an at91sam7
* if this is an at91sam7, it has the configured flash */
@@ -1062,10 +1034,10 @@ static int at91sam7_probe(struct flash_bank_s *bank)
return ERROR_OK;
}
static int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int at91sam7_info(struct flash_bank *bank, char *buf, int buf_size)
{
int printed;
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
if (at91sam7_info->cidr == 0)
{
@@ -1127,18 +1099,18 @@ static int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
* The maximum number of write/erase cycles for Non volatile Memory bits is 100. this includes
* Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
*/
static int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(at91sam7_handle_gpnvm_command)
{
flash_bank_t *bank;
struct flash_bank *bank;
int bit;
uint8_t flashcmd;
uint32_t status;
at91sam7_flash_bank_t *at91sam7_info;
struct at91sam7_flash_bank *at91sam7_info;
int retval;
if (argc != 2)
if (CMD_ARGC != 2)
{
command_print(cmd_ctx, "at91sam7 gpnvm <bit> <set | clear>");
command_print(CMD_CTX, "at91sam7 gpnvm <bit> <set | clear>");
return ERROR_OK;
}
@@ -1147,9 +1119,9 @@ static int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char
{
return ERROR_FLASH_BANK_INVALID;
}
if (bank->driver != &at91sam7_flash)
if (strcmp(bank->driver->name, "at91sam7"))
{
command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]);
command_print(CMD_CTX, "not an at91sam7 flash bank '%s'", CMD_ARGV[0]);
return ERROR_FLASH_BANK_INVALID;
}
if (bank->target->state != TARGET_HALTED)
@@ -1158,11 +1130,11 @@ static int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char
return ERROR_TARGET_NOT_HALTED;
}
if (strcmp(args[1], "set") == 0)
if (strcmp(CMD_ARGV[1], "set") == 0)
{
flashcmd = SGPB;
}
else if (strcmp(args[1], "clear") == 0)
else if (strcmp(CMD_ARGV[1], "clear") == 0)
{
flashcmd = CGPB;
}
@@ -1181,10 +1153,10 @@ static int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char
}
}
bit = atoi(args[0]);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], bit);
if ((bit < 0) || (bit >= at91sam7_info->num_nvmbits))
{
command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[0], at91sam7_info->target_name);
command_print(CMD_CTX, "gpnvm bit '#%s' is out of bounds for target %s", CMD_ARGV[0], at91sam7_info->target_name);
return ERROR_OK;
}
@@ -1206,3 +1178,38 @@ static int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char
return ERROR_OK;
}
static const struct command_registration at91sam7_exec_command_handlers[] = {
{
.name = "gpnvm",
.handler = at91sam7_handle_gpnvm_command,
.mode = COMMAND_EXEC,
.help = "set or clear one General Purpose Non-Volatile Memory "
"(gpnvm) bit",
.usage = "bitnum ('set'|'clear')",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration at91sam7_command_handlers[] = {
{
.name = "at91sam7",
.mode = COMMAND_ANY,
.help = "at91sam7 flash command group",
.chain = at91sam7_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
struct flash_driver at91sam7_flash = {
.name = "at91sam7",
.commands = at91sam7_command_handlers,
.flash_bank_command = at91sam7_flash_bank_command,
.erase = at91sam7_erase,
.protect = at91sam7_protect,
.write = at91sam7_write,
.probe = at91sam7_probe,
.auto_probe = at91sam7_probe,
.erase_check = at91sam7_erase_check,
.protect_check = at91sam7_protect_check,
.info = at91sam7_info,
};

View File

@@ -23,9 +23,7 @@
#ifndef AT91SAM7_H
#define AT91SAM7_H
#include "flash.h"
typedef struct at91sam7_flash_bank_s
struct at91sam7_flash_bank
{
/* chip id register */
uint32_t cidr;
@@ -67,7 +65,7 @@ typedef struct at91sam7_flash_bank_s
/* external clock frequency */
uint32_t ext_freq;
} at91sam7_flash_bank_t;
};
/* AT91SAM7 control registers */

View File

@@ -21,9 +21,9 @@
#include "config.h"
#endif
#include "imp.h"
#include "avrf.h"
#include "avrt.h"
#include "flash.h"
#include <target/avrt.h>
/* AVR_JTAG_Instructions */
@@ -50,55 +50,27 @@
#define AVR_JTAG_REG_ProgrammingCommand_Len 15
#define AVR_JTAG_REG_FlashDataByte_Len 16
avrf_type_t avft_chips_info[] =
struct avrf_type avft_chips_info[] =
{
// name, chip_id, flash_page_size, flash_page_num, eeprom_page_size, eeprom_page_num
{"atmega128", 0x9702, 256, 512, 8, 512},
};
static int avrf_register_commands(struct command_context_s *cmd_ctx);
static int avrf_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int avrf_erase(struct flash_bank_s *bank, int first, int last);
static int avrf_protect(struct flash_bank_s *bank, int set, int first, int last);
static int avrf_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int avrf_probe(struct flash_bank_s *bank);
static int avrf_auto_probe(struct flash_bank_s *bank);
//static int avrf_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int avrf_protect_check(struct flash_bank_s *bank);
static int avrf_info(struct flash_bank_s *bank, char *buf, int buf_size);
int avr_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out);
int avr_jtag_senddat(struct jtag_tap *tap, uint32_t *dr_in, uint32_t dr_out, int len);
static int avrf_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
extern int avr_jtag_sendinstr(jtag_tap_t *tap, uint8_t *ir_in, uint8_t ir_out);
extern int avr_jtag_senddat(jtag_tap_t *tap, uint32_t *dr_in, uint32_t dr_out, int len);
extern int mcu_write_ir(jtag_tap_t *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len, int rti);
extern int mcu_write_dr(jtag_tap_t *tap, uint8_t *ir_in, uint8_t *ir_out, int dr_len, int rti);
extern int mcu_write_ir_u8(jtag_tap_t *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti);
extern int mcu_write_dr_u8(jtag_tap_t *tap, uint8_t *ir_in, uint8_t ir_out, int dr_len, int rti);
extern int mcu_write_ir_u16(jtag_tap_t *tap, uint16_t *ir_in, uint16_t ir_out, int ir_len, int rti);
extern int mcu_write_dr_u16(jtag_tap_t *tap, uint16_t *ir_in, uint16_t ir_out, int dr_len, int rti);
extern int mcu_write_ir_u32(jtag_tap_t *tap, uint32_t *ir_in, uint32_t ir_out, int ir_len, int rti);
extern int mcu_write_dr_u32(jtag_tap_t *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len, int rti);
extern int mcu_execute_queue(void);
flash_driver_t avr_flash =
{
.name = "avr",
.register_commands = avrf_register_commands,
.flash_bank_command = avrf_flash_bank_command,
.erase = avrf_erase,
.protect = avrf_protect,
.write = avrf_write,
.probe = avrf_probe,
.auto_probe = avrf_auto_probe,
.erase_check = default_flash_mem_blank_check,
.protect_check = avrf_protect_check,
.info = avrf_info
};
int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len, int rti);
int mcu_write_dr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int dr_len, int rti);
int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti);
int mcu_write_dr_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int dr_len, int rti);
int mcu_write_ir_u16(struct jtag_tap *tap, uint16_t *ir_in, uint16_t ir_out, int ir_len, int rti);
int mcu_write_dr_u16(struct jtag_tap *tap, uint16_t *ir_in, uint16_t ir_out, int dr_len, int rti);
int mcu_write_ir_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int ir_len, int rti);
int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len, int rti);
int mcu_execute_queue(void);
/* avr program functions */
static int avr_jtag_reset(avr_common_t *avr, uint32_t reset)
static int avr_jtag_reset(struct avr_common *avr, uint32_t reset)
{
avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_AVR_RESET);
avr_jtag_senddat(avr->jtag_info.tap, NULL, reset ,AVR_JTAG_REG_Reset_Len);
@@ -106,7 +78,7 @@ static int avr_jtag_reset(avr_common_t *avr, uint32_t reset)
return ERROR_OK;
}
static int avr_jtag_read_jtagid(avr_common_t *avr, uint32_t *id)
static int avr_jtag_read_jtagid(struct avr_common *avr, uint32_t *id)
{
avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_IDCODE);
avr_jtag_senddat(avr->jtag_info.tap, id, 0, AVR_JTAG_REG_JTAGID_Len);
@@ -114,7 +86,7 @@ static int avr_jtag_read_jtagid(avr_common_t *avr, uint32_t *id)
return ERROR_OK;
}
static int avr_jtagprg_enterprogmode(avr_common_t *avr)
static int avr_jtagprg_enterprogmode(struct avr_common *avr)
{
avr_jtag_reset(avr, 1);
@@ -124,7 +96,7 @@ static int avr_jtagprg_enterprogmode(avr_common_t *avr)
return ERROR_OK;
}
static int avr_jtagprg_leaveprogmode(avr_common_t *avr)
static int avr_jtagprg_leaveprogmode(struct avr_common *avr)
{
avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);
avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2300, AVR_JTAG_REG_ProgrammingCommand_Len);
@@ -138,7 +110,7 @@ static int avr_jtagprg_leaveprogmode(avr_common_t *avr)
return ERROR_OK;
}
static int avr_jtagprg_chiperase(avr_common_t *avr)
static int avr_jtagprg_chiperase(struct avr_common *avr)
{
uint32_t poll_value;
@@ -161,7 +133,7 @@ static int avr_jtagprg_chiperase(avr_common_t *avr)
return ERROR_OK;
}
static int avr_jtagprg_writeflashpage(avr_common_t *avr, uint8_t *page_buf, uint32_t buf_size, uint32_t addr, uint32_t page_size)
static int avr_jtagprg_writeflashpage(struct avr_common *avr, uint8_t *page_buf, uint32_t buf_size, uint32_t addr, uint32_t page_size)
{
uint32_t i, poll_value;
@@ -208,28 +180,17 @@ static int avr_jtagprg_writeflashpage(avr_common_t *avr, uint8_t *page_buf, uint
return ERROR_OK;
}
/* interface command */
static int avrf_register_commands(struct command_context_s *cmd_ctx)
FLASH_BANK_COMMAND_HANDLER(avrf_flash_bank_command)
{
command_t *avr_cmd = register_command(cmd_ctx, NULL, "avr", NULL, COMMAND_ANY, "avr flash specific commands");
struct avrf_flash_bank *avrf_info;
register_command(cmd_ctx, avr_cmd, "mass_erase", avrf_handle_mass_erase_command, COMMAND_EXEC,
"mass erase device");
return ERROR_OK;
}
static int avrf_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
{
avrf_flash_bank_t *avrf_info;
if (argc < 6)
if (CMD_ARGC < 6)
{
LOG_WARNING("incomplete flash_bank avr configuration");
return ERROR_FLASH_BANK_INVALID;
}
avrf_info = malloc(sizeof(avrf_flash_bank_t));
avrf_info = malloc(sizeof(struct avrf_flash_bank));
bank->driver_priv = avrf_info;
avrf_info->probed = 0;
@@ -237,22 +198,22 @@ static int avrf_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd,
return ERROR_OK;
}
static int avrf_erase(struct flash_bank_s *bank, int first, int last)
static int avrf_erase(struct flash_bank *bank, int first, int last)
{
LOG_INFO("%s", __FUNCTION__);
return ERROR_OK;
}
static int avrf_protect(struct flash_bank_s *bank, int set, int first, int last)
static int avrf_protect(struct flash_bank *bank, int set, int first, int last)
{
LOG_INFO("%s", __FUNCTION__);
return ERROR_OK;
}
static int avrf_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int avrf_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
target_t *target = bank->target;
avr_common_t *avr = target->arch_info;
struct target *target = bank->target;
struct avr_common *avr = target->arch_info;
uint32_t cur_size, cur_buffer_size, page_size;
if (bank->target->state != TARGET_HALTED)
@@ -300,12 +261,12 @@ static int avrf_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offse
#define EXTRACT_MFG(X) (((X) & 0xffe) >> 1)
#define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)
#define EXTRACT_VER(X) (((X) & 0xf0000000) >> 28)
static int avrf_probe(struct flash_bank_s *bank)
static int avrf_probe(struct flash_bank *bank)
{
target_t *target = bank->target;
avrf_flash_bank_t *avrf_info = bank->driver_priv;
avr_common_t *avr = target->arch_info;
avrf_type_t *avr_info = NULL;
struct target *target = bank->target;
struct avrf_flash_bank *avrf_info = bank->driver_priv;
struct avr_common *avr = target->arch_info;
struct avrf_type *avr_info = NULL;
int i;
uint32_t device_id;
@@ -329,7 +290,7 @@ static int avrf_probe(struct flash_bank_s *bank)
LOG_ERROR("0x%" PRIx32 " is invalid Manufacturer for avr, 0x%X is expected", EXTRACT_MFG(device_id), 0x1F);
}
for (i = 0; i < (int)(sizeof(avft_chips_info) / sizeof(avft_chips_info[0])); i++)
for (i = 0; i < (int)ARRAY_SIZE(avft_chips_info); i++)
{
if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id))
{
@@ -345,7 +306,7 @@ static int avrf_probe(struct flash_bank_s *bank)
bank->base = 0x00000000;
bank->size = (avr_info->flash_page_size * avr_info->flash_page_num);
bank->num_sectors = avr_info->flash_page_num;
bank->sectors = malloc(sizeof(flash_sector_t) * avr_info->flash_page_num);
bank->sectors = malloc(sizeof(struct flash_sector) * avr_info->flash_page_num);
for (i = 0; i < avr_info->flash_page_num; i++)
{
@@ -368,25 +329,25 @@ static int avrf_probe(struct flash_bank_s *bank)
}
}
static int avrf_auto_probe(struct flash_bank_s *bank)
static int avrf_auto_probe(struct flash_bank *bank)
{
avrf_flash_bank_t *avrf_info = bank->driver_priv;
struct avrf_flash_bank *avrf_info = bank->driver_priv;
if (avrf_info->probed)
return ERROR_OK;
return avrf_probe(bank);
}
static int avrf_protect_check(struct flash_bank_s *bank)
static int avrf_protect_check(struct flash_bank *bank)
{
LOG_INFO("%s", __FUNCTION__);
return ERROR_OK;
}
static int avrf_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int avrf_info(struct flash_bank *bank, char *buf, int buf_size)
{
target_t *target = bank->target;
avr_common_t *avr = target->arch_info;
avrf_type_t *avr_info = NULL;
struct target *target = bank->target;
struct avr_common *avr = target->arch_info;
struct avrf_type *avr_info = NULL;
int i;
uint32_t device_id;
@@ -408,7 +369,7 @@ static int avrf_info(struct flash_bank_s *bank, char *buf, int buf_size)
LOG_ERROR("0x%" PRIx32 " is invalid Manufacturer for avr, 0x%X is expected", EXTRACT_MFG(device_id), 0x1F);
}
for (i = 0; i < (int)(sizeof(avft_chips_info) / sizeof(avft_chips_info[0])); i++)
for (i = 0; i < (int)ARRAY_SIZE(avft_chips_info); i++)
{
if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id))
{
@@ -433,10 +394,10 @@ static int avrf_info(struct flash_bank_s *bank, char *buf, int buf_size)
}
}
static int avrf_mass_erase(struct flash_bank_s *bank)
static int avrf_mass_erase(struct flash_bank *bank)
{
target_t *target = bank->target;
avr_common_t *avr = target->arch_info;
struct target *target = bank->target;
struct avr_common *avr = target->arch_info;
if (target->state != TARGET_HALTED)
{
@@ -454,23 +415,20 @@ static int avrf_mass_erase(struct flash_bank_s *bank)
return ERROR_OK;
}
static int avrf_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(avrf_handle_mass_erase_command)
{
flash_bank_t *bank;
int i;
if (argc < 1)
if (CMD_ARGC < 1)
{
command_print(cmd_ctx, "avr mass_erase <bank>");
command_print(CMD_CTX, "avr mass_erase <bank>");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
if (avrf_mass_erase(bank) == ERROR_OK)
{
@@ -480,13 +438,46 @@ static int avrf_handle_mass_erase_command(struct command_context_s *cmd_ctx, cha
bank->sectors[i].is_erased = 1;
}
command_print(cmd_ctx, "avr mass erase complete");
command_print(CMD_CTX, "avr mass erase complete");
}
else
{
command_print(cmd_ctx, "avr mass erase failed");
command_print(CMD_CTX, "avr mass erase failed");
}
LOG_DEBUG("%s", __FUNCTION__);
return ERROR_OK;
}
static const struct command_registration avrf_exec_command_handlers[] = {
{
.name = "mass_erase",
.handler = avrf_handle_mass_erase_command,
.mode = COMMAND_EXEC,
.help = "erase entire device",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration avrf_command_handlers[] = {
{
.name = "avrf",
.mode = COMMAND_ANY,
.help = "AVR flash command group",
.chain = avrf_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
struct flash_driver avr_flash = {
.name = "avr",
.commands = avrf_command_handlers,
.flash_bank_command = avrf_flash_bank_command,
.erase = avrf_erase,
.protect = avrf_protect,
.write = avrf_write,
.probe = avrf_probe,
.auto_probe = avrf_auto_probe,
.erase_check = default_flash_mem_blank_check,
.protect_check = avrf_protect_check,
.info = avrf_info,
};

View File

@@ -20,9 +20,7 @@
#ifndef AVRF_H
#define AVRF_H
#include "types.h"
typedef struct avrf_type_s
struct avrf_type
{
char name[15];
uint16_t chip_id;
@@ -30,12 +28,12 @@ typedef struct avrf_type_s
int flash_page_num;
int eeprom_page_size;
int eeprom_page_num;
} avrf_type_t;
};
typedef struct avrf_flash_bank_s
struct avrf_flash_bank
{
int ppage_size;
int probed;
} avrf_flash_bank_t;
};
#endif /* AVRF_H */

View File

@@ -23,58 +23,33 @@
#include "config.h"
#endif
#include "imp.h"
#include "cfi.h"
#include "non_cfi.h"
#include "armv4_5.h"
#include "binarybuffer.h"
#include <target/arm.h>
#include <helper/binarybuffer.h>
#include <target/algorithm.h>
static int cfi_register_commands(struct command_context_s *cmd_ctx);
static int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int cfi_erase(struct flash_bank_s *bank, int first, int last);
static int cfi_protect(struct flash_bank_s *bank, int set, int first, int last);
static int cfi_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int cfi_probe(struct flash_bank_s *bank);
static int cfi_auto_probe(struct flash_bank_s *bank);
static int cfi_protect_check(struct flash_bank_s *bank);
static int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size);
//static int cfi_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
#define CFI_MAX_BUS_WIDTH 4
#define CFI_MAX_CHIP_WIDTH 4
/* defines internal maximum size for code fragment in cfi_intel_write_block() */
#define CFI_MAX_INTEL_CODESIZE 256
flash_driver_t cfi_flash =
{
.name = "cfi",
.register_commands = cfi_register_commands,
.flash_bank_command = cfi_flash_bank_command,
.erase = cfi_erase,
.protect = cfi_protect,
.write = cfi_write,
.probe = cfi_probe,
.auto_probe = cfi_auto_probe,
.erase_check = default_flash_blank_check,
.protect_check = cfi_protect_check,
.info = cfi_info
};
static cfi_unlock_addresses_t cfi_unlock_addresses[] =
static struct cfi_unlock_addresses cfi_unlock_addresses[] =
{
[CFI_UNLOCK_555_2AA] = { .unlock1 = 0x555, .unlock2 = 0x2aa },
[CFI_UNLOCK_5555_2AAA] = { .unlock1 = 0x5555, .unlock2 = 0x2aaa },
};
/* CFI fixups foward declarations */
static void cfi_fixup_0002_erase_regions(flash_bank_t *flash, void *param);
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);
static void cfi_fixup_0002_erase_regions(struct flash_bank *flash, void *param);
static void cfi_fixup_0002_unlock_addresses(struct flash_bank *flash, void *param);
static void cfi_fixup_atmel_reversed_erase_regions(struct flash_bank *flash, void *param);
/* fixup after reading cmdset 0002 primary query table */
static const cfi_fixup_t cfi_0002_fixups[] = {
static const struct cfi_fixup 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 +65,14 @@ static const cfi_fixup_t cfi_0002_fixups[] = {
};
/* fixup after reading cmdset 0001 primary query table */
static const cfi_fixup_t cfi_0001_fixups[] = {
static const struct cfi_fixup cfi_0001_fixups[] = {
{0, 0, NULL, NULL}
};
static void cfi_fixup(flash_bank_t *bank, const cfi_fixup_t *fixups)
static void cfi_fixup(struct flash_bank *bank, const struct cfi_fixup *fixups)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
const cfi_fixup_t *f;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
const struct cfi_fixup *f;
for (f = fixups; f->fixup; f++)
{
@@ -109,10 +84,10 @@ static void cfi_fixup(flash_bank_t *bank, const cfi_fixup_t *fixups)
}
}
/* inline uint32_t flash_address(flash_bank_t *bank, int sector, uint32_t offset) */
static __inline__ uint32_t flash_address(flash_bank_t *bank, int sector, uint32_t offset)
/* inline uint32_t flash_address(struct flash_bank *bank, int sector, uint32_t offset) */
static __inline__ uint32_t flash_address(struct flash_bank *bank, int sector, uint32_t offset)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
if (cfi_info->x16_as_x8) offset *= 2;
@@ -131,7 +106,7 @@ static __inline__ uint32_t flash_address(flash_bank_t *bank, int sector, uint32_
}
static void cfi_command(flash_bank_t *bank, uint8_t cmd, uint8_t *cmd_buf)
static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf)
{
int i;
@@ -161,9 +136,9 @@ static void cfi_command(flash_bank_t *bank, uint8_t cmd, uint8_t *cmd_buf)
* flash banks are expected to be made of similar chips
* the query result should be the same for all
*/
static uint8_t cfi_query_u8(flash_bank_t *bank, int sector, uint32_t offset)
static uint8_t cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint8_t data[CFI_MAX_BUS_WIDTH];
target_read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 1, data);
@@ -178,9 +153,9 @@ static uint8_t cfi_query_u8(flash_bank_t *bank, int sector, uint32_t offset)
* in case of a bank made of multiple chips,
* the individual values are ORed
*/
static uint8_t cfi_get_u8(flash_bank_t *bank, int sector, uint32_t offset)
static uint8_t cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint8_t data[CFI_MAX_BUS_WIDTH];
int i;
@@ -203,10 +178,10 @@ static uint8_t cfi_get_u8(flash_bank_t *bank, int sector, uint32_t offset)
}
}
static uint16_t cfi_query_u16(flash_bank_t *bank, int sector, uint32_t offset)
static uint16_t cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset)
{
target_t *target = bank->target;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct target *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
uint8_t data[CFI_MAX_BUS_WIDTH * 2];
if (cfi_info->x16_as_x8)
@@ -225,10 +200,10 @@ static uint16_t cfi_query_u16(flash_bank_t *bank, int sector, uint32_t offset)
return data[bank->bus_width - 1] | data[(2 * bank->bus_width) - 1] << 8;
}
static uint32_t cfi_query_u32(flash_bank_t *bank, int sector, uint32_t offset)
static uint32_t cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset)
{
target_t *target = bank->target;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct target *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
uint8_t data[CFI_MAX_BUS_WIDTH * 4];
if (cfi_info->x16_as_x8)
@@ -248,9 +223,9 @@ static uint32_t cfi_query_u32(flash_bank_t *bank, int sector, uint32_t offset)
data[(3 * bank->bus_width) - 1] << 16 | data[(4 * bank->bus_width) - 1] << 24;
}
static void cfi_intel_clear_status_register(flash_bank_t *bank)
static void cfi_intel_clear_status_register(struct flash_bank *bank)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint8_t command[8];
if (target->state != TARGET_HALTED)
@@ -263,7 +238,7 @@ static void cfi_intel_clear_status_register(flash_bank_t *bank)
target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
}
uint8_t cfi_intel_wait_status_busy(flash_bank_t *bank, int timeout)
uint8_t cfi_intel_wait_status_busy(struct flash_bank *bank, int timeout)
{
uint8_t status;
@@ -304,10 +279,10 @@ uint8_t cfi_intel_wait_status_busy(flash_bank_t *bank, int timeout)
return status;
}
int cfi_spansion_wait_status_busy(flash_bank_t *bank, int timeout)
int cfi_spansion_wait_status_busy(struct flash_bank *bank, int timeout)
{
uint8_t status, oldstatus;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
oldstatus = cfi_get_u8(bank, 0, 0x0);
@@ -339,12 +314,12 @@ int cfi_spansion_wait_status_busy(flash_bank_t *bank, int timeout)
return(ERROR_FLASH_BUSY);
}
static int cfi_read_intel_pri_ext(flash_bank_t *bank)
static int cfi_read_intel_pri_ext(struct flash_bank *bank)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_intel_pri_ext_t *pri_ext = malloc(sizeof(cfi_intel_pri_ext_t));
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_intel_pri_ext *pri_ext = malloc(sizeof(struct cfi_intel_pri_ext));
struct target *target = bank->target;
uint8_t command[8];
cfi_info->pri_ext = pri_ext;
@@ -405,12 +380,12 @@ static int cfi_read_intel_pri_ext(flash_bank_t *bank)
return ERROR_OK;
}
static int cfi_read_spansion_pri_ext(flash_bank_t *bank)
static int cfi_read_spansion_pri_ext(struct flash_bank *bank)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));
struct target *target = bank->target;
uint8_t command[8];
cfi_info->pri_ext = pri_ext;
@@ -470,13 +445,13 @@ static int cfi_read_spansion_pri_ext(flash_bank_t *bank)
return ERROR_OK;
}
static int cfi_read_atmel_pri_ext(flash_bank_t *bank)
static int cfi_read_atmel_pri_ext(struct flash_bank *bank)
{
int retval;
cfi_atmel_pri_ext_t atmel_pri_ext;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
target_t *target = bank->target;
struct cfi_atmel_pri_ext atmel_pri_ext;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));
struct target *target = bank->target;
uint8_t command[8];
/* ATMEL devices use the same CFI primary command set (0x2) as AMD/Spansion,
@@ -484,7 +459,7 @@ static int cfi_read_atmel_pri_ext(flash_bank_t *bank)
* We read the atmel table, and prepare a valid AMD/Spansion query table.
*/
memset(pri_ext, 0, sizeof(cfi_spansion_pri_ext_t));
memset(pri_ext, 0, sizeof(struct cfi_spansion_pri_ext));
cfi_info->pri_ext = pri_ext;
@@ -537,9 +512,9 @@ static int cfi_read_atmel_pri_ext(flash_bank_t *bank)
return ERROR_OK;
}
static int cfi_read_0002_pri_ext(flash_bank_t *bank)
static int cfi_read_0002_pri_ext(struct flash_bank *bank)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
if (cfi_info->manufacturer == CFI_MFR_ATMEL)
{
@@ -551,11 +526,11 @@ static int cfi_read_0002_pri_ext(flash_bank_t *bank)
}
}
static int cfi_spansion_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int cfi_spansion_info(struct flash_bank *bank, char *buf, int buf_size)
{
int printed;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
printed = snprintf(buf, buf_size, "\nSpansion primary algorithm extend information:\n");
buf += printed;
@@ -586,11 +561,11 @@ static int cfi_spansion_info(struct flash_bank_s *bank, char *buf, int buf_size)
return ERROR_OK;
}
static int cfi_intel_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int cfi_intel_info(struct flash_bank *bank, char *buf, int buf_size)
{
int printed;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext;
printed = snprintf(buf, buf_size, "\nintel primary algorithm extend information:\n");
buf += printed;
@@ -615,40 +590,30 @@ static int cfi_intel_info(struct flash_bank_s *bank, char *buf, int buf_size)
return ERROR_OK;
}
static int cfi_register_commands(struct command_context_s *cmd_ctx)
{
/*command_t *cfi_cmd = */
register_command(cmd_ctx, NULL, "cfi", NULL, COMMAND_ANY, "flash bank cfi <base> <size> <chip_width> <bus_width> <targetNum> [jedec_probe/x16_as_x8]");
/*
register_command(cmd_ctx, cfi_cmd, "part_id", cfi_handle_part_id_command, COMMAND_EXEC,
"print part id of cfi flash bank <num>");
*/
return ERROR_OK;
}
/* flash_bank cfi <base> <size> <chip_width> <bus_width> <target#> [options]
*/
static int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
FLASH_BANK_COMMAND_HANDLER(cfi_flash_bank_command)
{
cfi_flash_bank_t *cfi_info;
int i;
(void) cmd_ctx;
(void) cmd;
struct cfi_flash_bank *cfi_info;
if (argc < 6)
if (CMD_ARGC < 6)
{
LOG_WARNING("incomplete flash_bank cfi configuration");
return ERROR_FLASH_BANK_INVALID;
}
if ((strtoul(args[4], NULL, 0) > CFI_MAX_CHIP_WIDTH)
|| (strtoul(args[3], NULL, 0) > CFI_MAX_BUS_WIDTH))
uint16_t chip_width, bus_width;
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[3], bus_width);
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[4], chip_width);
if ((chip_width > CFI_MAX_CHIP_WIDTH)
|| (bus_width > CFI_MAX_BUS_WIDTH))
{
LOG_ERROR("chip and bus width have to specified in bytes");
return ERROR_FLASH_BANK_INVALID;
}
cfi_info = malloc(sizeof(cfi_flash_bank_t));
cfi_info = malloc(sizeof(struct cfi_flash_bank));
cfi_info->probed = 0;
bank->driver_priv = cfi_info;
@@ -658,13 +623,13 @@ static int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd,
cfi_info->jedec_probe = 0;
cfi_info->not_cfi = 0;
for (i = 6; i < argc; i++)
for (unsigned i = 6; i < CMD_ARGC; i++)
{
if (strcmp(args[i], "x16_as_x8") == 0)
if (strcmp(CMD_ARGV[i], "x16_as_x8") == 0)
{
cfi_info->x16_as_x8 = 1;
}
else if (strcmp(args[i], "jedec_probe") == 0)
else if (strcmp(CMD_ARGV[i], "jedec_probe") == 0)
{
cfi_info->jedec_probe = 1;
}
@@ -678,11 +643,11 @@ static int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd,
return ERROR_OK;
}
static int cfi_intel_erase(struct flash_bank_s *bank, int first, int last)
static int cfi_intel_erase(struct flash_bank *bank, int first, int last)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct target *target = bank->target;
uint8_t command[8];
int i;
@@ -722,12 +687,12 @@ static int cfi_intel_erase(struct flash_bank_s *bank, int first, int last)
}
static int cfi_spansion_erase(struct flash_bank_s *bank, int first, int last)
static int cfi_spansion_erase(struct flash_bank *bank, int first, int last)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
struct target *target = bank->target;
uint8_t command[8];
int i;
@@ -788,9 +753,9 @@ static int cfi_spansion_erase(struct flash_bank_s *bank, int first, int last)
return target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
}
static int cfi_erase(struct flash_bank_s *bank, int first, int last)
static int cfi_erase(struct flash_bank *bank, int first, int last)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
if (bank->target->state != TARGET_HALTED)
{
@@ -823,12 +788,12 @@ static int cfi_erase(struct flash_bank_s *bank, int first, int last)
return ERROR_OK;
}
static int cfi_intel_protect(struct flash_bank_s *bank, int set, int first, int last)
static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int last)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext;
struct target *target = bank->target;
uint8_t command[8];
int retry = 0;
int i;
@@ -940,9 +905,9 @@ static int cfi_intel_protect(struct flash_bank_s *bank, int set, int first, int
return target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
}
static int cfi_protect(struct flash_bank_s *bank, int set, int first, int last)
static int cfi_protect(struct flash_bank *bank, int set, int first, int last)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
if (bank->target->state != TARGET_HALTED)
{
@@ -973,9 +938,9 @@ static int cfi_protect(struct flash_bank_s *bank, int set, int first, int last)
}
/* FIXME Replace this by a simple memcpy() - still unsure about sideeffects */
static void cfi_add_byte(struct flash_bank_s *bank, uint8_t *word, uint8_t byte)
static void cfi_add_byte(struct flash_bank *bank, uint8_t *word, uint8_t byte)
{
/* target_t *target = bank->target; */
/* struct target *target = bank->target; */
int i;
@@ -1008,7 +973,7 @@ static void cfi_add_byte(struct flash_bank_s *bank, uint8_t *word, uint8_t byte)
/* Convert code image to target endian */
/* FIXME create general block conversion fcts in target.c?) */
static void cfi_fix_code_endian(target_t *target, uint8_t *dest, const uint32_t *src, uint32_t count)
static void cfi_fix_code_endian(struct target *target, uint8_t *dest, const uint32_t *src, uint32_t count)
{
uint32_t i;
for (i = 0; i< count; i++)
@@ -1019,9 +984,9 @@ static void cfi_fix_code_endian(target_t *target, uint8_t *dest, const uint32_t
}
}
static uint32_t cfi_command_val(flash_bank_t *bank, uint8_t cmd)
static uint32_t cfi_command_val(struct flash_bank *bank, uint8_t cmd)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint8_t buf[CFI_MAX_BUS_WIDTH];
cfi_command(bank, cmd, buf);
@@ -1042,13 +1007,13 @@ static uint32_t cfi_command_val(flash_bank_t *bank, uint8_t cmd)
}
}
static int cfi_intel_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t address, uint32_t count)
static int cfi_intel_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t address, uint32_t count)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
reg_param_t reg_params[7];
armv4_5_algorithm_t armv4_5_info;
working_area_t *source;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct target *target = bank->target;
struct reg_param reg_params[7];
struct arm_algorithm armv4_5_info;
struct working_area *source;
uint32_t buffer_size = 32768;
uint32_t write_command_val, busy_pattern_val, error_pattern_val;
@@ -1120,9 +1085,9 @@ static int cfi_intel_write_block(struct flash_bank_s *bank, uint8_t *buffer, uin
cfi_intel_clear_status_register(bank);
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;
armv4_5_info.common_magic = ARM_COMMON_MAGIC;
armv4_5_info.core_mode = ARM_MODE_SVC;
armv4_5_info.core_state = ARM_STATE_ARM;
/* If we are setting up the write_algorith, we need target_code_src */
/* if not we only need target_code_size. */
@@ -1286,14 +1251,14 @@ cleanup:
return retval;
}
static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t address, uint32_t count)
static int cfi_spansion_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t address, uint32_t count)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
target_t *target = bank->target;
reg_param_t reg_params[10];
armv4_5_algorithm_t armv4_5_info;
working_area_t *source;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
struct target *target = bank->target;
struct reg_param reg_params[10];
struct arm_algorithm armv4_5_info;
struct working_area *source;
uint32_t buffer_size = 32768;
uint32_t status;
int retval, retvaltemp;
@@ -1443,9 +1408,9 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
0xeafffffe /* b 8204 <sp_8_done> */
};
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;
armv4_5_info.common_magic = ARM_COMMON_MAGIC;
armv4_5_info.core_mode = ARM_MODE_SVC;
armv4_5_info.core_state = ARM_STATE_ARM;
int target_code_size;
const uint32_t *target_code_src;
@@ -1585,11 +1550,11 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
return exit_code;
}
static int cfi_intel_write_word(struct flash_bank_s *bank, uint8_t *word, uint32_t address)
static int cfi_intel_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct target *target = bank->target;
uint8_t command[8];
cfi_intel_clear_status_register(bank);
@@ -1619,11 +1584,11 @@ static int cfi_intel_write_word(struct flash_bank_s *bank, uint8_t *word, uint32
return ERROR_OK;
}
static int cfi_intel_write_words(struct flash_bank_s *bank, uint8_t *word, uint32_t wordcount, uint32_t address)
static int cfi_intel_write_words(struct flash_bank *bank, uint8_t *word, uint32_t wordcount, uint32_t address)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct target *target = bank->target;
uint8_t command[8];
/* Calculate buffer size and boundary mask */
@@ -1712,12 +1677,12 @@ static int cfi_intel_write_words(struct flash_bank_s *bank, uint8_t *word, uint3
return ERROR_OK;
}
static int cfi_spansion_write_word(struct flash_bank_s *bank, uint8_t *word, uint32_t address)
static int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
struct target *target = bank->target;
uint8_t command[8];
cfi_command(bank, 0xaa, command);
@@ -1758,13 +1723,13 @@ static int cfi_spansion_write_word(struct flash_bank_s *bank, uint8_t *word, uin
return ERROR_OK;
}
static int cfi_spansion_write_words(struct flash_bank_s *bank, uint8_t *word, uint32_t wordcount, uint32_t address)
static int cfi_spansion_write_words(struct flash_bank *bank, uint8_t *word, uint32_t wordcount, uint32_t address)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct target *target = bank->target;
uint8_t command[8];
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
/* Calculate buffer size and boundary mask */
uint32_t buffersize = (1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width);
@@ -1850,9 +1815,9 @@ static int cfi_spansion_write_words(struct flash_bank_s *bank, uint8_t *word, ui
return ERROR_OK;
}
static int cfi_write_word(struct flash_bank_s *bank, uint8_t *word, uint32_t address)
static int cfi_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
switch (cfi_info->pri_id)
{
@@ -1871,9 +1836,9 @@ static int cfi_write_word(struct flash_bank_s *bank, uint8_t *word, uint32_t add
return ERROR_FLASH_OPERATION_FAILED;
}
static int cfi_write_words(struct flash_bank_s *bank, uint8_t *word, uint32_t wordcount, uint32_t address)
static int cfi_write_words(struct flash_bank *bank, uint8_t *word, uint32_t wordcount, uint32_t address)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
switch (cfi_info->pri_id)
{
@@ -1892,10 +1857,10 @@ static int cfi_write_words(struct flash_bank_s *bank, uint8_t *word, uint32_t wo
return ERROR_FLASH_OPERATION_FAILED;
}
int cfi_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t address = bank->base + offset; /* address of first byte to be programmed */
uint32_t write_p, copy_p;
int align; /* number of unaligned bytes */
@@ -2101,20 +2066,20 @@ int cfi_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint3
return target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, current_word);
}
static void cfi_fixup_atmel_reversed_erase_regions(flash_bank_t *bank, void *param)
static void cfi_fixup_atmel_reversed_erase_regions(struct flash_bank *bank, void *param)
{
(void) param;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
pri_ext->_reversed_geometry = 1;
}
static void cfi_fixup_0002_erase_regions(flash_bank_t *bank, void *param)
static void cfi_fixup_0002_erase_regions(struct flash_bank *bank, void *param)
{
int i;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
(void) param;
if ((pri_ext->_reversed_geometry) || (pri_ext->TopBottom == 3))
@@ -2133,21 +2098,21 @@ static void cfi_fixup_0002_erase_regions(flash_bank_t *bank, void *param)
}
}
static void cfi_fixup_0002_unlock_addresses(flash_bank_t *bank, void *param)
static void cfi_fixup_0002_unlock_addresses(struct flash_bank *bank, void *param)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
cfi_unlock_addresses_t *unlock_addresses = param;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
struct cfi_unlock_addresses *unlock_addresses = param;
pri_ext->_unlock1 = unlock_addresses->unlock1;
pri_ext->_unlock2 = unlock_addresses->unlock2;
}
static int cfi_query_string(struct flash_bank_s *bank, int address)
static int cfi_query_string(struct flash_bank *bank, int address)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct target *target = bank->target;
int retval;
uint8_t command[8];
@@ -2182,10 +2147,10 @@ static int cfi_query_string(struct flash_bank_s *bank, int address)
return ERROR_OK;
}
static int cfi_probe(struct flash_bank_s *bank)
static int cfi_probe(struct flash_bank *bank)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct target *target = bank->target;
uint8_t command[8];
int num_sectors = 0;
int i;
@@ -2417,7 +2382,7 @@ static int cfi_probe(struct flash_bank_s *bank)
{
/* a device might have only one erase block, spanning the whole device */
bank->num_sectors = 1;
bank->sectors = malloc(sizeof(flash_sector_t));
bank->sectors = malloc(sizeof(struct flash_sector));
bank->sectors[sector].offset = 0x0;
bank->sectors[sector].size = bank->size;
@@ -2434,7 +2399,7 @@ static int cfi_probe(struct flash_bank_s *bank)
}
bank->num_sectors = num_sectors;
bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
for (i = 0; i < cfi_info->num_erase_regions; i++)
{
@@ -2461,21 +2426,21 @@ static int cfi_probe(struct flash_bank_s *bank)
return ERROR_OK;
}
static int cfi_auto_probe(struct flash_bank_s *bank)
static int cfi_auto_probe(struct flash_bank *bank)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
if (cfi_info->probed)
return ERROR_OK;
return cfi_probe(bank);
}
static int cfi_intel_protect_check(struct flash_bank_s *bank)
static int cfi_intel_protect_check(struct flash_bank *bank)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext;
struct target *target = bank->target;
uint8_t command[CFI_MAX_BUS_WIDTH];
int i;
@@ -2503,12 +2468,12 @@ static int cfi_intel_protect_check(struct flash_bank_s *bank)
return target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
}
static int cfi_spansion_protect_check(struct flash_bank_s *bank)
static int cfi_spansion_protect_check(struct flash_bank *bank)
{
int retval;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
target_t *target = bank->target;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
struct target *target = bank->target;
uint8_t command[8];
int i;
@@ -2544,9 +2509,9 @@ static int cfi_spansion_protect_check(struct flash_bank_s *bank)
return target_write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
}
static int cfi_protect_check(struct flash_bank_s *bank)
static int cfi_protect_check(struct flash_bank *bank)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
if (bank->target->state != TARGET_HALTED)
{
@@ -2574,10 +2539,10 @@ static int cfi_protect_check(struct flash_bank_s *bank)
return ERROR_OK;
}
static int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int cfi_info(struct flash_bank *bank, char *buf, int buf_size)
{
int printed;
cfi_flash_bank_t *cfi_info = bank->driver_priv;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
if (cfi_info->qry[0] == (char)-1)
{
@@ -2651,3 +2616,16 @@ static int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size)
return ERROR_OK;
}
struct flash_driver cfi_flash = {
.name = "cfi",
.flash_bank_command = cfi_flash_bank_command,
.erase = cfi_erase,
.protect = cfi_protect,
.write = cfi_write,
.probe = cfi_probe,
.auto_probe = cfi_auto_probe,
.erase_check = default_flash_blank_check,
.protect_check = cfi_protect_check,
.info = cfi_info,
};

View File

@@ -20,14 +20,12 @@
#ifndef CFI_H
#define CFI_H
#include "flash.h"
#define CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7 0xE0 /* DQ5..DQ7 */
#define CFI_STATUS_POLL_MASK_DQ6_DQ7 0xC0 /* DQ6..DQ7 */
typedef struct cfi_flash_bank_s
struct cfi_flash_bank
{
working_area_t *write_algorithm;
struct working_area *write_algorithm;
int x16_as_x8;
int jedec_probe;
@@ -70,13 +68,13 @@ typedef struct cfi_flash_bank_s
void *pri_ext;
void *alt_ext;
} cfi_flash_bank_t;
};
/* Intel primary extended query table
* as defined for the Advanced+ Boot Block Flash Memory (C3)
* and used by the linux kernel cfi driver (as of 2.6.14)
*/
typedef struct cfi_intel_pri_ext_s
struct cfi_intel_pri_ext
{
char pri[3];
uint8_t major_version;
@@ -91,12 +89,12 @@ typedef struct cfi_intel_pri_ext_s
uint8_t fact_prot_reg_size;
uint8_t user_prot_reg_size;
uint8_t extra[0];
} cfi_intel_pri_ext_t;
};
/* Spansion primary extended query table as defined for and used by
* the linux kernel cfi driver (as of 2.6.15)
*/
typedef struct cfi_spansion_pri_ext_s
struct cfi_spansion_pri_ext
{
uint8_t pri[3];
uint8_t major_version;
@@ -115,12 +113,12 @@ typedef struct cfi_spansion_pri_ext_s
int _reversed_geometry;
uint32_t _unlock1;
uint32_t _unlock2;
} cfi_spansion_pri_ext_t;
};
/* Atmel primary extended query table as defined for and used by
* the linux kernel cfi driver (as of 2.6.20+)
*/
typedef struct cfi_atmel_pri_ext_s
struct cfi_atmel_pri_ext
{
uint8_t pri[3];
uint8_t major_version;
@@ -129,26 +127,26 @@ typedef struct cfi_atmel_pri_ext_s
uint8_t bottom_boot;
uint8_t burst_mode;
uint8_t page_mode;
} cfi_atmel_pri_ext_t;
};
enum {
CFI_UNLOCK_555_2AA,
CFI_UNLOCK_5555_2AAA,
};
typedef struct cfi_unlock_addresses_s
struct cfi_unlock_addresses
{
uint32_t unlock1;
uint32_t unlock2;
} cfi_unlock_addresses_t;
};
typedef struct cfi_fixup_s
struct cfi_fixup
{
uint16_t mfr;
uint16_t id;
void (*fixup)(flash_bank_t *flash, void *param);
void (*fixup)(struct flash_bank *flash, void *param);
void *param;
} cfi_fixup_t;
};
#define CFI_MFR_AMD 0x0001
#define CFI_MFR_FUJITSU 0x0004

659
src/flash/nor/core.c Normal file
View File

@@ -0,0 +1,659 @@
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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/common.h>
#include <flash/nor/core.h>
#include <flash/nor/imp.h>
#include <target/image.h>
/**
* @file
* Upper level of NOR flash framework.
* The lower level interfaces are to drivers. These upper level ones
* primarily support access from Tcl scripts or from GDB.
*/
struct flash_bank *flash_banks;
int flash_driver_erase(struct flash_bank *bank, int first, int last)
{
int retval;
retval = bank->driver->erase(bank, first, last);
if (retval != ERROR_OK)
{
LOG_ERROR("failed erasing sectors %d to %d (%d)", first, last, retval);
}
return retval;
}
int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
{
int retval;
retval = bank->driver->protect(bank, set, first, last);
if (retval != ERROR_OK)
{
LOG_ERROR("failed setting protection for areas %d to %d (%d)", first, last, retval);
}
return retval;
}
int flash_driver_write(struct flash_bank *bank,
uint8_t *buffer, uint32_t offset, uint32_t count)
{
int retval;
retval = bank->driver->write(bank, buffer, offset, count);
if (retval != ERROR_OK)
{
LOG_ERROR("error writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32 " (%d)",
bank->base, offset, retval);
}
return retval;
}
void flash_bank_add(struct flash_bank *bank)
{
/* put flash bank in linked list */
unsigned bank_num = 0;
if (flash_banks)
{
/* find last flash bank */
struct flash_bank *p = flash_banks;
while (NULL != p->next)
{
bank_num += 1;
p = p->next;
}
p->next = bank;
bank_num += 1;
}
else
flash_banks = bank;
bank->bank_number = bank_num;
}
struct flash_bank *flash_bank_list(void)
{
return flash_banks;
}
struct flash_bank *get_flash_bank_by_num_noprobe(int num)
{
struct flash_bank *p;
int i = 0;
for (p = flash_banks; p; p = p->next)
{
if (i++ == num)
{
return p;
}
}
LOG_ERROR("flash bank %d does not exist", num);
return NULL;
}
int flash_get_bank_count(void)
{
struct flash_bank *p;
int i = 0;
for (p = flash_banks; p; p = p->next)
{
i++;
}
return i;
}
struct flash_bank *get_flash_bank_by_name(const char *name)
{
unsigned requested = get_flash_name_index(name);
unsigned found = 0;
struct flash_bank *bank;
for (bank = flash_banks; NULL != bank; bank = bank->next)
{
if (strcmp(bank->name, name) == 0)
return bank;
if (!flash_driver_name_matches(bank->driver->name, name))
continue;
if (++found < requested)
continue;
return bank;
}
return NULL;
}
struct flash_bank *get_flash_bank_by_num(int num)
{
struct flash_bank *p = get_flash_bank_by_num_noprobe(num);
int retval;
if (p == NULL)
return NULL;
retval = p->driver->auto_probe(p);
if (retval != ERROR_OK)
{
LOG_ERROR("auto_probe failed %d\n", retval);
return NULL;
}
return p;
}
/* lookup flash bank by address */
struct flash_bank *get_flash_bank_by_addr(struct target *target, uint32_t addr)
{
struct flash_bank *c;
/* cycle through bank list */
for (c = flash_banks; c; c = c->next)
{
int retval;
retval = c->driver->auto_probe(c);
if (retval != ERROR_OK)
{
LOG_ERROR("auto_probe failed %d\n", retval);
return NULL;
}
/* check whether address belongs to this flash bank */
if ((addr >= c->base) && (addr <= c->base + (c->size - 1)) && target == c->target)
return c;
}
LOG_ERROR("No flash at address 0x%08" PRIx32 "\n", addr);
return NULL;
}
int default_flash_mem_blank_check(struct flash_bank *bank)
{
struct target *target = bank->target;
const int buffer_size = 1024;
int i;
uint32_t nBytes;
int retval = ERROR_OK;
if (bank->target->state != TARGET_HALTED)
{
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
uint8_t *buffer = malloc(buffer_size);
for (i = 0; i < bank->num_sectors; i++)
{
uint32_t j;
bank->sectors[i].is_erased = 1;
for (j = 0; j < bank->sectors[i].size; j += buffer_size)
{
uint32_t chunk;
chunk = buffer_size;
if (chunk > (j - bank->sectors[i].size))
{
chunk = (j - bank->sectors[i].size);
}
retval = target_read_memory(target, bank->base + bank->sectors[i].offset + j, 4, chunk/4, buffer);
if (retval != ERROR_OK)
{
goto done;
}
for (nBytes = 0; nBytes < chunk; nBytes++)
{
if (buffer[nBytes] != 0xFF)
{
bank->sectors[i].is_erased = 0;
break;
}
}
}
}
done:
free(buffer);
return retval;
}
int default_flash_blank_check(struct flash_bank *bank)
{
struct target *target = bank->target;
int i;
int retval;
int fast_check = 0;
uint32_t blank;
if (bank->target->state != TARGET_HALTED)
{
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
for (i = 0; i < bank->num_sectors; i++)
{
uint32_t address = bank->base + bank->sectors[i].offset;
uint32_t size = bank->sectors[i].size;
if ((retval = target_blank_check_memory(target, address, size, &blank)) != ERROR_OK)
{
fast_check = 0;
break;
}
if (blank == 0xFF)
bank->sectors[i].is_erased = 1;
else
bank->sectors[i].is_erased = 0;
fast_check = 1;
}
if (!fast_check)
{
LOG_USER("Running slow fallback erase check - add working memory");
return default_flash_mem_blank_check(bank);
}
return ERROR_OK;
}
/* Manipulate given flash region, selecting the bank according to target
* and address. Maps an address range to a set of sectors, and issues
* the callback() on that set ... e.g. to erase or unprotect its members.
*
* (Note a current bad assumption: that protection operates on the same
* size sectors as erase operations use.)
*
* The "pad_reason" parameter is a kind of boolean: when it's NULL, the
* range must fit those sectors exactly. This is clearly safe; it can't
* erase data which the caller said to leave alone, for example. If it's
* non-NULL, rather than failing, extra data in the first and/or last
* sectors will be added to the range, and that reason string is used when
* warning about those additions.
*/
static int flash_iterate_address_range(struct target *target,
char *pad_reason, uint32_t addr, uint32_t length,
int (*callback)(struct flash_bank *bank, int first, int last))
{
struct flash_bank *c;
uint32_t last_addr = addr + length; /* first address AFTER end */
int first = -1;
int last = -1;
int i;
if ((c = get_flash_bank_by_addr(target, addr)) == NULL)
return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */
if (c->size == 0 || c->num_sectors == 0)
{
LOG_ERROR("Bank is invalid");
return ERROR_FLASH_BANK_INVALID;
}
if (length == 0)
{
/* special case, erase whole bank when length is zero */
if (addr != c->base)
{
LOG_ERROR("Whole bank access must start at beginning of bank.");
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
}
return callback(c, 0, c->num_sectors - 1);
}
/* check whether it all fits in this bank */
if (addr + length - 1 > c->base + c->size - 1)
{
LOG_ERROR("Flash access does not fit into bank.");
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
}
/** @todo: handle erasures that cross into adjacent banks */
addr -= c->base;
last_addr -= c->base;
for (i = 0; i < c->num_sectors; i++)
{
struct flash_sector *f = c->sectors + i;
uint32_t end = f->offset + f->size;
/* start only on a sector boundary */
if (first < 0) {
/* scanned past the first sector? */
if (addr < f->offset)
break;
/* is this the first sector? */
if (addr == f->offset)
first = i;
/* Does this need head-padding? If so, pad and warn;
* or else force an error.
*
* Such padding can make trouble, since *WE* can't
* ever know if that data was in use. The warning
* should help users sort out messes later.
*/
else if (addr < end && pad_reason) {
/* FIXME say how many bytes (e.g. 80 KB) */
LOG_WARNING("Adding extra %s range, "
"%#8.8x to %#8.8x",
pad_reason,
(unsigned) f->offset,
(unsigned) addr - 1);
first = i;
} else
continue;
}
/* is this (also?) the last sector? */
if (last_addr == end) {
last = i;
break;
}
/* Does this need tail-padding? If so, pad and warn;
* or else force an error.
*/
if (last_addr < end && pad_reason) {
/* FIXME say how many bytes (e.g. 80 KB) */
LOG_WARNING("Adding extra %s range, "
"%#8.8x to %#8.8x",
pad_reason,
(unsigned) last_addr,
(unsigned) end - 1);
last = i;
break;
}
/* MUST finish on a sector boundary */
if (last_addr <= f->offset)
break;
}
/* invalid start or end address? */
if (first == -1 || last == -1) {
LOG_ERROR("address range 0x%8.8x .. 0x%8.8x "
"is not sector-aligned",
(unsigned) (c->base + addr),
(unsigned) (c->base + last_addr - 1));
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
}
/* The NOR driver may trim this range down, based on what
* sectors are already erased/unprotected. GDB currently
* blocks such optimizations.
*/
return callback(c, first, last);
}
int flash_erase_address_range(struct target *target,
bool pad, uint32_t addr, uint32_t length)
{
return flash_iterate_address_range(target, pad ? "erase" : NULL,
addr, length, &flash_driver_erase);
}
static int flash_driver_unprotect(struct flash_bank *bank, int first, int last)
{
return flash_driver_protect(bank, 0, first, last);
}
static int flash_unlock_address_range(struct target *target, uint32_t addr, uint32_t length)
{
/* By default, pad to sector boundaries ... the real issue here
* is that our (only) caller *permanently* removes protection,
* and doesn't restore it.
*/
return flash_iterate_address_range(target, "unprotect",
addr, length, &flash_driver_unprotect);
}
int flash_write_unlock(struct target *target, struct image *image,
uint32_t *written, int erase, bool unlock)
{
int retval = ERROR_OK;
int section;
uint32_t section_offset;
struct flash_bank *c;
int *padding;
/* REVISIT do_pad should perhaps just be another parameter.
* GDB wouldn't ever need it, since it erases separately.
* But "flash write_image" commands might want that option.
*/
bool do_pad = false;
section = 0;
section_offset = 0;
if (written)
*written = 0;
if (erase)
{
/* assume all sectors need erasing - stops any problems
* when flash_write is called multiple times */
flash_set_dirty();
}
/* allocate padding array */
padding = calloc(image->num_sections, sizeof(*padding));
/* loop until we reach end of the image */
while (section < image->num_sections)
{
uint32_t buffer_size;
uint8_t *buffer;
int section_first;
int section_last;
uint32_t run_address = image->sections[section].base_address + section_offset;
uint32_t run_size = image->sections[section].size - section_offset;
int pad_bytes = 0;
if (image->sections[section].size == 0)
{
LOG_WARNING("empty section %d", section);
section++;
section_offset = 0;
continue;
}
/* find the corresponding flash bank */
if ((c = get_flash_bank_by_addr(target, run_address)) == NULL)
{
section++; /* and skip it */
section_offset = 0;
continue;
}
/* collect consecutive sections which fall into the same bank */
section_first = section;
section_last = section;
padding[section] = 0;
while ((run_address + run_size - 1 < c->base + c->size - 1)
&& (section_last + 1 < image->num_sections))
{
if (image->sections[section_last + 1].base_address < (run_address + run_size))
{
LOG_DEBUG("section %d out of order "
"(surprising, but supported)",
section_last + 1);
/* REVISIT this can break with autoerase ...
* clobbering data after it's written.
*/
break;
}
/* FIXME This needlessly touches sectors BETWEEN the
* sections it's writing. Without auto erase, it just
* writes ones. That WILL INVALIDATE data in cases
* like Stellaris Tempest chips, corrupting internal
* ECC codes; and at least FreeScale suggests issues
* with that approach (in HC11 documentation).
*
* With auto erase enabled, data in those sectors will
* be needlessly destroyed; and some of the limited
* number of flash erase cycles will be wasted...
*
* In both cases, the extra writes slow things down.
*/
/* if we have multiple sections within our image,
* flash programming could fail due to alignment issues
* attempt to rebuild a consecutive buffer for the flash loader */
pad_bytes = (image->sections[section_last + 1].base_address) - (run_address + run_size);
if ((run_address + run_size + pad_bytes) > (c->base + c->size))
break;
padding[section_last] = pad_bytes;
run_size += image->sections[++section_last].size;
run_size += pad_bytes;
LOG_INFO("Padding image section %d with %d bytes", section_last-1, pad_bytes);
}
/* fit the run into bank constraints */
if (run_address + run_size - 1 > c->base + c->size - 1)
{
/* REVISIT isn't this superfluous, given the while()
* loop conditions above??
*/
LOG_WARNING("writing %d bytes only - as image section is %d bytes and bank is only %d bytes", \
(int)(c->base + c->size - run_address), (int)(run_size), (int)(c->size));
run_size = c->base + c->size - run_address;
}
/* If we're applying any sector automagic, then pad this
* (maybe-combined) segment to the end of its last sector.
*/
if (unlock || erase) {
int sector;
uint32_t offset_start = run_address - c->base;
uint32_t offset_end = offset_start + run_size;
uint32_t end = offset_end, delta;
for (sector = 0; sector < c->num_sectors; sector++) {
end = c->sectors[sector].offset
+ c->sectors[sector].size;
if (offset_end <= end)
break;
}
delta = end - offset_end;
padding[section_last] += delta;
run_size += delta;
}
/* allocate buffer */
buffer = malloc(run_size);
buffer_size = 0;
/* read sections to the buffer */
while (buffer_size < run_size)
{
size_t size_read;
size_read = run_size - buffer_size;
if (size_read > image->sections[section].size - section_offset)
size_read = image->sections[section].size - section_offset;
if ((retval = image_read_section(image, section, section_offset,
size_read, buffer + buffer_size, &size_read)) != ERROR_OK || size_read == 0)
{
free(buffer);
free(padding);
return retval;
}
/* see if we need to pad the section */
while (padding[section]--)
(buffer + buffer_size)[size_read++] = 0xff;
buffer_size += size_read;
section_offset += size_read;
if (section_offset >= image->sections[section].size)
{
section++;
section_offset = 0;
}
}
retval = ERROR_OK;
if (unlock)
{
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,
do_pad, run_address, run_size);
}
}
if (retval == ERROR_OK)
{
/* write flash sectors */
retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
}
free(buffer);
if (retval != ERROR_OK)
{
free(padding);
return retval; /* abort operation */
}
if (written != NULL)
*written += run_size; /* add run size to total written counter */
}
free(padding);
return retval;
}
int flash_write(struct target *target, struct image *image,
uint32_t *written, int erase)
{
return flash_write_unlock(target, image, written, erase, false);
}

187
src/flash/nor/core.h Normal file
View File

@@ -0,0 +1,187 @@
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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 FLASH_NOR_CORE_H
#define FLASH_NOR_CORE_H
#include <flash/common.h>
/**
* @file
* Upper level NOR flash interfaces.
*/
struct image;
#define FLASH_MAX_ERROR_STR (128)
/**
* Describes the geometry and status of a single flash sector
* within a flash bank. A single bank typically consists of multiple
* sectors, each of which can be erased and protected independently.
*/
struct flash_sector
{
/// Bus offset from start of the flash chip (in bytes).
uint32_t offset;
/// Number of bytes in this flash sector.
uint32_t size;
/**
* Indication of erasure status: 0 = not erased, 1 = erased,
* other = unknown. Set by @c flash_driver_s::erase_check.
*/
int is_erased;
/**
* Indication of protection status: 0 = unprotected/unlocked,
* 1 = protected/locked, other = unknown. Set by
* @c flash_driver_s::protect_check.
*/
int is_protected;
};
/**
* Provides details of a flash bank, available either on-chip or through
* a major interface.
*
* This structure will be passed as a parameter to the callbacks in the
* flash_driver_s structure, some of which may modify the contents of
* this structure of the area of flash that it defines. Driver writers
* may use the @c driver_priv member to store additional data on a
* per-bank basis, if required.
*/
struct flash_bank
{
char *name;
struct target *target; /**< Target to which this bank belongs. */
struct flash_driver *driver; /**< Driver for this bank. */
void *driver_priv; /**< Private driver storage pointer */
int bank_number; /**< The 'bank' (or chip number) of this instance. */
uint32_t base; /**< The base address of this bank */
uint32_t size; /**< The size of this chip bank, in bytes */
int chip_width; /**< Width of the chip in bytes (1,2,4 bytes) */
int bus_width; /**< Maximum bus width, in bytes (1,2,4 bytes) */
/**
* The number of sectors on this chip. This value will
* be set intially to 0, and the flash driver must set this to
* some non-zero value during "probe()" or "auto_probe()".
*/
int num_sectors;
/// Array of sectors, allocated and initilized by the flash driver
struct flash_sector *sectors;
struct flash_bank *next; /**< The next flash bank on this chip */
};
/// Registers the 'flash' subsystem commands
int flash_register_commands(struct command_context *cmd_ctx);
/// Initializes the 'flash' subsystem drivers
int flash_init_drivers(struct command_context *cmd_ctx);
/**
* Erases @a length bytes in the @a target flash, starting at @a addr.
* The range @a addr to @a addr + @a length - 1 must be strictly
* sector aligned, unless @a pad is true. Setting @a pad true extends
* the range, at beginning and/or end, if needed for sector alignment.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int flash_erase_address_range(struct target *target,
bool pad, uint32_t addr, uint32_t length);
/**
* Writes @a image into the @a target flash. The @a written parameter
* will contain the
* @param target The target with the flash to be programmed.
* @param image The image that will be programmed to flash.
* @param written On return, contains the number of bytes written.
* @param erase If non-zero, indicates the flash driver should first
* erase the corresponding banks or sectors before programming.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int flash_write(struct target *target,
struct image *image, uint32_t *written, int erase);
/**
* Forces targets to re-examine their erase/protection state.
* This routine must be called when the system may modify the status.
*/
void flash_set_dirty(void);
/// @returns The number of flash banks currently defined.
int flash_get_bank_count(void);
/**
* Provides default erased-bank check handling. Checks to see if
* the flash driver knows they are erased; if things look uncertain,
* this routine will call default_flash_mem_blank_check() to confirm.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int default_flash_blank_check(struct flash_bank *bank);
/**
* Provides a default blank flash memory check. Ensures the contents
* of the given bank have truly been erased.
* @param bank The flash bank.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int default_flash_mem_blank_check(struct flash_bank *bank);
/**
* Returns the flash bank specified by @a name, which matches the
* driver name and a suffix (option) specify the driver-specific
* bank number. The suffix consists of the '.' and the driver-specific
* bank number: when two str9x banks are defined, then 'str9x.1' refers
* to the second.
*/
struct flash_bank *get_flash_bank_by_name(const char *name);
/**
* Returns a flash bank by the specified flash_bank_s bank_number, @a num.
* @param num The flash bank number.
* @returns A struct flash_bank for flash bank @a num, or NULL
*/
struct flash_bank *get_flash_bank_by_num(int num);
/**
* Retreives @a bank from a command argument, reporting errors parsing
* the bank identifier or retreiving the specified bank. The bank
* may be identified by its bank number or by @c name.instance, where
* @a instance is driver-specific.
* @param name_index The index to the string in args containing the
* bank identifier.
* @param bank On output, contians a pointer to the bank or NULL.
* @returns ERROR_OK on success, or an error indicating the problem.
*/
COMMAND_HELPER(flash_command_get_bank, unsigned name_index,
struct flash_bank **bank);
/**
* Returns the flash bank like get_flash_bank_by_num(), without probing.
* @param num The flash bank number.
* @returns A struct flash_bank for flash bank @a num, or NULL.
*/
struct flash_bank *get_flash_bank_by_num_noprobe(int num);
/**
* Returns the flash bank located at a specified address.
* @param target The target, presumed to contain one or more banks.
* @param addr An address that is within the range of the bank.
* @returns The struct flash_bank located at @a addr, or NULL.
*/
struct flash_bank *get_flash_bank_by_addr(struct target *target, uint32_t addr);
#endif // FLASH_NOR_CORE_H

201
src/flash/nor/driver.h Normal file
View File

@@ -0,0 +1,201 @@
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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 FLASH_NOR_DRIVER_H
#define FLASH_NOR_DRIVER_H
struct flash_bank;
#define __FLASH_BANK_COMMAND(name) \
COMMAND_HELPER(name, struct flash_bank *bank)
/**
* @brief Provides the implementation-independent structure that defines
* all of the callbacks required by OpenOCD flash drivers.
*
* Driver authors must implement the routines defined here, providing an
* instance with the fields filled out. After that, the instance must
* be registered in flash.c, so it can be used by the driver lookup system.
*
* Specifically, the user can issue the command: @par
* @code
* flash bank DRIVERNAME ...parameters...
* @endcode
*
* OpenOCD will search for the driver with a @c flash_driver_s::name
* that matches @c DRIVERNAME.
*
* The flash subsystem calls some of the other drivers routines a using
* corresponding static <code>flash_driver_<i>callback</i>()</code>
* routine in flash.c.
*/
struct flash_driver
{
/**
* Gives a human-readable name of this flash driver,
* This field is used to select and initialize the driver.
*/
char *name;
/**
* An array of driver-specific commands to register. When called
* during the "flash bank" command, the driver can register addition
* commands to support new flash chip functions.
*/
const struct command_registration *commands;
/**
* Finish the "flash bank" command for @a bank. The
* @a bank parameter will have been filled in by the core flash
* layer when this routine is called, and the driver can store
* additional information in its struct flash_bank::driver_priv field.
*
* The CMD_ARGV are: @par
* @code
* CMD_ARGV[0] = bank
* CMD_ARGV[1] = drivername {name above}
* CMD_ARGV[2] = baseaddress
* CMD_ARGV[3] = lengthbytes
* CMD_ARGV[4] = chip_width_in bytes
* CMD_ARGV[5] = bus_width_bytes
* CMD_ARGV[6] = driver-specific parameters
* @endcode
*
* For example, CMD_ARGV[4] = 16 bit flash, CMD_ARGV[5] = 32bit bus.
*
* If extra arguments are provided (@a CMD_ARGC > 6), they will
* start in @a CMD_ARGV[6]. These can be used to implement
* driver-specific extensions.
*
* @returns ERROR_OK if successful; otherwise, an error code.
*/
__FLASH_BANK_COMMAND((*flash_bank_command));
/**
* Bank/sector erase routine (target-specific). When
* called, the flash driver should erase the specified sectors
* using whatever means are at its disposal.
*
* @param bank The bank of flash to be erased.
* @param first The number of the first sector to erase, typically 0.
* @param last The number of the last sector to erase, typically N-1.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*erase)(struct flash_bank *bank, int first, int last);
/**
* Bank/sector protection routine (target-specific).
* When called, the driver should disable 'flash write' bits (or
* enable 'erase protection' bits) for the given @a bank and @a
* sectors.
*
* @param bank The bank to protect or unprotect.
* @param set If non-zero, enable protection; if 0, disable it.
* @param first The first sector to (un)protect, typicaly 0.
* @param last The last sector to (un)project, typically N-1.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*protect)(struct flash_bank *bank, int set, int first, int last);
/**
* Program data into the flash. Note CPU address will be
* "bank->base + offset", while the physical address is
* dependent upon current target MMU mappings.
*
* @param bank The bank to program
* @param buffer The data bytes to write.
* @param offset The offset into the chip to program.
* @param count The number of bytes to write.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*write)(struct flash_bank *bank,
uint8_t *buffer, uint32_t offset, uint32_t count);
/**
* Probe to determine what kind of flash is present.
* This is invoked by the "probe" script command.
*
* @param bank The bank to probe
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*probe)(struct flash_bank *bank);
/**
* Check the erasure status of a flash bank.
* When called, the driver routine must perform the required
* checks and then set the @c flash_sector_s::is_erased field
* for each of the flash banks's sectors.
*
* @param bank The bank to check
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*erase_check)(struct flash_bank *bank);
/**
* Determine if the specific bank is "protected" or not.
* When called, the driver routine must must perform the
* required protection check(s) and then set the @c
* flash_sector_s::is_protected field for each of the flash
* bank's sectors.
*
* @param bank - the bank to check
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*protect_check)(struct flash_bank *bank);
/**
* Display human-readable information about the flash
* bank into the given buffer. Drivers must be careful to avoid
* overflowing the buffer.
*
* @param bank - the bank to get info about
* @param char - where to put the text for the human to read
* @param buf_size - the size of the human buffer.
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*info)(struct flash_bank *bank, char *buf, int buf_size);
/**
* A more gentle flavor of filash_driver_s::probe, performing
* setup with less noise. Generally, driver routines should test
* to seee if the bank has already been probed; if it has, the
* driver probably should not perform its probe a second time.
*
* This callback is often called from the inside of other
* routines (e.g. GDB flash downloads) to autoprobe the flash as
* it is programing the flash.
*
* @param bank - the bank to probe
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*auto_probe)(struct flash_bank *bank);
};
#define FLASH_BANK_COMMAND_HANDLER(name) static __FLASH_BANK_COMMAND(name)
/**
* Find a NOR flash driver by its name.
* @param name The name of the requested driver.
* @returns The flash_driver called @c name, or NULL if not found.
*/
struct flash_driver *flash_driver_find_by_name(const char *name);
#endif // FLASH_NOR_DRIVER_H

77
src/flash/nor/drivers.c Normal file
View File

@@ -0,0 +1,77 @@
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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 "imp.h"
extern struct flash_driver lpc2000_flash;
extern struct flash_driver lpc288x_flash;
extern struct flash_driver lpc2900_flash;
extern struct flash_driver cfi_flash;
extern struct flash_driver at91sam3_flash;
extern struct flash_driver at91sam7_flash;
extern struct flash_driver str7x_flash;
extern struct flash_driver str9x_flash;
extern struct flash_driver aduc702x_flash;
extern struct flash_driver stellaris_flash;
extern struct flash_driver str9xpec_flash;
extern struct flash_driver stm32x_flash;
extern struct flash_driver tms470_flash;
extern struct flash_driver ecosflash_flash;
extern struct flash_driver ocl_flash;
extern struct flash_driver pic32mx_flash;
extern struct flash_driver avr_flash;
extern struct flash_driver faux_flash;
/**
* The list of built-in flash drivers.
* @todo Make this dynamically extendable with loadable modules.
*/
struct flash_driver *flash_drivers[] = {
&lpc2000_flash,
&lpc288x_flash,
&lpc2900_flash,
&cfi_flash,
&at91sam7_flash,
&at91sam3_flash,
&str7x_flash,
&str9x_flash,
&aduc702x_flash,
&stellaris_flash,
&str9xpec_flash,
&stm32x_flash,
&tms470_flash,
&ecosflash_flash,
&ocl_flash,
&pic32mx_flash,
&avr_flash,
&faux_flash,
NULL,
};
struct flash_driver *flash_driver_find_by_name(const char *name)
{
for (unsigned i = 0; flash_drivers[i]; i++)
{
if (strcmp(name, flash_drivers[i]->name) == 0)
return flash_drivers[i];
}
return NULL;
}

View File

@@ -21,50 +21,27 @@
#include "config.h"
#endif
#include "flash.h"
#include "embeddedice.h"
#include "image.h"
#include "imp.h"
#include <target/embeddedice.h>
#include <target/algorithm.h>
#include <target/image.h>
static int ecosflash_register_commands(struct command_context_s *cmd_ctx);
static int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int ecosflash_erase(struct flash_bank_s *bank, int first, int last);
static int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last);
static int ecosflash_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int ecosflash_probe(struct flash_bank_s *bank);
static int ecosflash_protect_check(struct flash_bank_s *bank);
static int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size);
#if 0
static uint32_t ecosflash_get_flash_status(flash_bank_t *bank);
static void ecosflash_set_flash_mode(flash_bank_t *bank,int mode);
static uint32_t ecosflash_wait_status_busy(flash_bank_t *bank, uint32_t waitbits, int timeout);
static int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static uint32_t ecosflash_get_flash_status(struct flash_bank *bank);
static void ecosflash_set_flash_mode(struct flash_bank *bank,int mode);
static uint32_t ecosflash_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout);
static int ecosflash_handle_gpnvm_command(struct command_context *cmd_ctx, char *cmd, char **args, int argc);
#endif
flash_driver_t ecosflash_flash =
struct ecosflash_flash_bank
{
.name = "ecosflash",
.register_commands = ecosflash_register_commands,
.flash_bank_command = ecosflash_flash_bank_command,
.erase = ecosflash_erase,
.protect = ecosflash_protect,
.write = ecosflash_write,
.probe = ecosflash_probe,
.auto_probe = ecosflash_probe,
.erase_check = default_flash_blank_check,
.protect_check = ecosflash_protect_check,
.info = ecosflash_info
};
typedef struct ecosflash_flash_bank_s
{
struct target_s *target;
working_area_t *write_algorithm;
working_area_t *erase_check_algorithm;
struct target *target;
struct working_area *write_algorithm;
struct working_area *erase_check_algorithm;
char *driverPath;
uint32_t start_address;
} ecosflash_flash_bank_t;
};
static const int sectorSize = 0x10000;
@@ -128,24 +105,24 @@ flash_errmsg(int err)
/* flash bank ecosflash <base> <size> <chip_width> <bus_width> <target#> <driverPath>
*/
static int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
FLASH_BANK_COMMAND_HANDLER(ecosflash_flash_bank_command)
{
ecosflash_flash_bank_t *info;
struct ecosflash_flash_bank *info;
if (argc < 7)
if (CMD_ARGC < 7)
{
LOG_WARNING("incomplete flash_bank ecosflash configuration");
return ERROR_FLASH_BANK_INVALID;
}
info = malloc(sizeof(ecosflash_flash_bank_t));
info = malloc(sizeof(struct ecosflash_flash_bank));
if (info == NULL)
{
LOG_ERROR("no memory for flash bank info");
exit(-1);
}
bank->driver_priv = info;
info->driverPath = strdup(args[6]);
info->driverPath = strdup(CMD_ARGV[6]);
/* eCos flash sector sizes are not exposed to OpenOCD, use 0x10000 as
* a way to improve impedance match between OpenOCD and eCos flash
@@ -154,7 +131,7 @@ static int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char
int i = 0;
uint32_t offset = 0;
bank->num_sectors = bank->size/sectorSize;
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
for (i = 0; i < bank->num_sectors; i++)
{
bank->sectors[i].offset = offset;
@@ -164,24 +141,24 @@ static int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char
bank->sectors[i].is_protected = 0;
}
info->target = get_target(args[5]);
info->target = get_target(CMD_ARGV[5]);
if (info->target == NULL)
{
LOG_ERROR("target '%s' not defined", args[5]);
LOG_ERROR("target '%s' not defined", CMD_ARGV[5]);
return ERROR_FAIL;
}
return ERROR_OK;
}
static int loadDriver(ecosflash_flash_bank_t *info)
static int loadDriver(struct ecosflash_flash_bank *info)
{
uint32_t buf_cnt;
uint32_t image_size;
image_t image;
size_t buf_cnt;
size_t image_size;
struct image image;
image.base_address_set = 0;
image.start_address_set = 0;
target_t *target = info->target;
struct target *target = info->target;
int retval;
if ((retval = image_open(&image, info->driverPath, NULL)) != ERROR_OK)
@@ -205,7 +182,8 @@ static int loadDriver(ecosflash_flash_bank_t *info)
}
target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer);
image_size += buf_cnt;
LOG_DEBUG("%" PRIu32 " byte written at address 0x%8.8" PRIx32 "", buf_cnt, image.sections[i].base_address);
LOG_DEBUG("%zu bytes written at address 0x%8.8" PRIx32 "",
buf_cnt, image.sections[i].base_address);
free(buffer);
}
@@ -222,19 +200,19 @@ static int const OFFSET_FLASH_SIZE = 0x8;
static int const OFFSET_GET_WORKAREA = 0x18;
static int const OFFSET_GET_WORKAREA_SIZE = 0x4;
static int runCode(ecosflash_flash_bank_t *info,
static int runCode(struct ecosflash_flash_bank *info,
uint32_t codeStart, uint32_t codeStop, uint32_t r0, uint32_t r1, uint32_t r2,
uint32_t *result,
/* timeout in ms */
int timeout)
{
target_t *target = info->target;
struct target *target = info->target;
reg_param_t reg_params[3];
armv4_5_algorithm_t armv4_5_info;
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;
struct reg_param reg_params[3];
struct arm_algorithm armv4_5_info;
armv4_5_info.common_magic = ARM_COMMON_MAGIC;
armv4_5_info.core_mode = ARM_MODE_SVC;
armv4_5_info.core_state = ARM_STATE_ARM;
init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
@@ -263,7 +241,7 @@ static int runCode(ecosflash_flash_bank_t *info,
return ERROR_OK;
}
static int eCosBoard_erase(ecosflash_flash_bank_t *info, uint32_t address, uint32_t len)
static int eCosBoard_erase(struct ecosflash_flash_bank *info, uint32_t address, uint32_t len)
{
int retval;
int timeout = (len / 20480 + 1) * 1000; /*asume 20 KB/s*/
@@ -294,9 +272,9 @@ static int eCosBoard_erase(ecosflash_flash_bank_t *info, uint32_t address, uint3
return ERROR_OK;
}
static int eCosBoard_flash(ecosflash_flash_bank_t *info, void *data, uint32_t address, uint32_t len)
static int eCosBoard_flash(struct ecosflash_flash_bank *info, void *data, uint32_t address, uint32_t len)
{
target_t *target = info->target;
struct target *target = info->target;
const int chunk = 8192;
int retval = ERROR_OK;
int timeout = (chunk / 20480 + 1) * 1000; /*asume 20 KB/s + 1 second*/
@@ -353,22 +331,15 @@ static int eCosBoard_flash(ecosflash_flash_bank_t *info, void *data, uint32_t ad
return ERROR_OK;
}
static int ecosflash_probe(struct flash_bank_s *bank)
static int ecosflash_probe(struct flash_bank *bank)
{
return ERROR_OK;
}
static int ecosflash_register_commands(struct command_context_s *cmd_ctx)
{
register_command(cmd_ctx, NULL, "ecosflash", NULL, COMMAND_ANY, NULL);
return ERROR_OK;
}
#if 0
static void command(flash_bank_t *bank, uint8_t cmd, uint8_t *cmd_buf)
static void command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf)
{
ecosflash_flash_bank_t *info = bank->driver_priv;
struct ecosflash_flash_bank *info = bank->driver_priv;
int i;
if (info->target->endianness == TARGET_LITTLE_ENDIAN)
@@ -389,7 +360,7 @@ static void command(flash_bank_t *bank, uint8_t cmd, uint8_t *cmd_buf)
#endif
#if 0
static uint32_t ecosflash_address(struct flash_bank_s *bank, uint32_t address)
static uint32_t ecosflash_address(struct flash_bank *bank, uint32_t address)
{
uint32_t retval = 0;
switch (bank->bus_width)
@@ -406,55 +377,68 @@ static uint32_t ecosflash_address(struct flash_bank_s *bank, uint32_t address)
}
#endif
static int ecosflash_erase(struct flash_bank_s *bank, int first, int last)
static int ecosflash_erase(struct flash_bank *bank, int first, int last)
{
struct flash_bank_s *c = bank;
ecosflash_flash_bank_t *info = bank->driver_priv;
struct flash_bank *c = bank;
struct ecosflash_flash_bank *info = bank->driver_priv;
return eCosBoard_erase(info, c->base + first*sectorSize, sectorSize*(last-first + 1));
}
static int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last)
static int ecosflash_protect(struct flash_bank *bank, int set, int first, int last)
{
return ERROR_OK;
}
static int ecosflash_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int ecosflash_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
ecosflash_flash_bank_t *info = bank->driver_priv;
struct flash_bank_s *c = bank;
struct ecosflash_flash_bank *info = bank->driver_priv;
struct flash_bank *c = bank;
return eCosBoard_flash(info, buffer, c->base + offset, count);
}
static int ecosflash_protect_check(struct flash_bank_s *bank)
static int ecosflash_protect_check(struct flash_bank *bank)
{
return ERROR_OK;
}
static int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int ecosflash_info(struct flash_bank *bank, char *buf, int buf_size)
{
ecosflash_flash_bank_t *info = bank->driver_priv;
struct ecosflash_flash_bank *info = bank->driver_priv;
snprintf(buf, buf_size, "eCos flash driver: %s", info->driverPath);
return ERROR_OK;
}
#if 0
static uint32_t ecosflash_get_flash_status(flash_bank_t *bank)
static uint32_t ecosflash_get_flash_status(struct flash_bank *bank)
{
return ERROR_OK;
}
static void ecosflash_set_flash_mode(flash_bank_t *bank,int mode)
static void ecosflash_set_flash_mode(struct flash_bank *bank,int mode)
{
}
static uint32_t ecosflash_wait_status_busy(flash_bank_t *bank, uint32_t waitbits, int timeout)
static uint32_t ecosflash_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout)
{
return ERROR_OK;
}
static int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
static int ecosflash_handle_gpnvm_command(struct command_context *cmd_ctx, char *cmd, char **args, int argc)
{
return ERROR_OK;
}
#endif
struct flash_driver ecosflash_flash = {
.name = "ecosflash",
.flash_bank_command = ecosflash_flash_bank_command,
.erase = ecosflash_erase,
.protect = ecosflash_protect,
.write = ecosflash_write,
.probe = ecosflash_probe,
.auto_probe = ecosflash_probe,
.erase_check = default_flash_blank_check,
.protect_check = ecosflash_protect_check,
.info = ecosflash_info
};

View File

@@ -21,57 +21,34 @@
#include "config.h"
#endif
#include "flash.h"
#include "image.h"
#include "imp.h"
#include <target/image.h>
#include "hello.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 =
struct faux_flash_bank
{
.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;
struct target *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)
FLASH_BANK_COMMAND_HANDLER(faux_flash_bank_command)
{
faux_flash_bank_t *info;
struct faux_flash_bank *info;
if (argc < 6)
if (CMD_ARGC < 6)
{
LOG_WARNING("incomplete flash_bank faux configuration");
return ERROR_FLASH_BANK_INVALID;
}
info = malloc(sizeof(faux_flash_bank_t));
info = malloc(sizeof(struct faux_flash_bank));
if (info == NULL)
{
LOG_ERROR("no memory for flash bank info");
@@ -90,7 +67,7 @@ static int faux_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd,
int i = 0;
uint32_t offset = 0;
bank->num_sectors = bank->size/sectorSize;
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
for (i = 0; i < bank->num_sectors; i++)
{
bank->sectors[i].offset = offset;
@@ -100,10 +77,10 @@ static int faux_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd,
bank->sectors[i].is_protected = 0;
}
info->target = get_target(args[5]);
info->target = get_target(CMD_ARGV[5]);
if (info->target == NULL)
{
LOG_ERROR("target '%s' not defined", args[5]);
LOG_ERROR("target '%s' not defined", CMD_ARGV[5]);
free(info->memory);
free(info);
return ERROR_FAIL;
@@ -111,43 +88,62 @@ static int faux_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd,
return ERROR_OK;
}
static int faux_register_commands(struct command_context_s *cmd_ctx)
static int faux_erase(struct flash_bank *bank, int first, int last)
{
return ERROR_OK;
}
static int faux_erase(struct flash_bank_s *bank, int first, int last)
{
faux_flash_bank_t *info = bank->driver_priv;
struct faux_flash_bank *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)
static int faux_protect(struct flash_bank *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)
static int faux_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
faux_flash_bank_t *info = bank->driver_priv;
struct faux_flash_bank *info = bank->driver_priv;
memcpy(info->memory + offset, buffer, count);
return ERROR_OK;
}
static int faux_protect_check(struct flash_bank_s *bank)
static int faux_protect_check(struct flash_bank *bank)
{
return ERROR_OK;
}
static int faux_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int faux_info(struct flash_bank *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)
static int faux_probe(struct flash_bank *bank)
{
return ERROR_OK;
}
static const struct command_registration faux_command_handlers[] = {
{
.name = "faux",
.mode = COMMAND_ANY,
.help = "faux flash command group",
.chain = hello_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
struct flash_driver faux_flash = {
.name = "faux",
.commands = faux_command_handlers,
.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
};

48
src/flash/nor/imp.h Normal file
View File

@@ -0,0 +1,48 @@
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* 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 FLASH_NOR_IMP_H
#define FLASH_NOR_IMP_H
// this is an internal header
#include "core.h"
#include "driver.h"
// almost all drivers will need this file
#include <target/target.h>
/**
* Adds a new NOR bank to the global list of banks.
* @param bank The bank that should be added.
*/
void flash_bank_add(struct flash_bank *bank);
/**
* @return The first bank in the global list.
*/
struct flash_bank *flash_bank_list(void);
int flash_driver_erase(struct flash_bank *bank, int first, int last);
int flash_driver_protect(struct flash_bank *bank, int set, int first, int last);
int flash_driver_write(struct flash_bank *bank,
uint8_t *buffer, uint32_t offset, uint32_t count);
/* write (optional verify) an image to flash memory of the given target */
int flash_write_unlock(struct target *target, struct image *image,
uint32_t *written, int erase, bool unlock);
#endif // FLASH_NOR_IMP_H

View File

@@ -25,10 +25,12 @@
#include "config.h"
#endif
#include "imp.h"
#include "lpc2000.h"
#include "armv4_5.h"
#include "armv7m.h"
#include "binarybuffer.h"
#include <helper/binarybuffer.h>
#include <target/algorithm.h>
#include <target/arm_opcodes.h>
#include <target/armv7m.h>
/* flash programming support for NXP LPC17xx and LPC2xxx devices
@@ -53,46 +55,9 @@
* - 176x (tested with LPC1768)
*/
static int lpc2000_register_commands(struct command_context_s *cmd_ctx);
static int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int lpc2000_erase(struct flash_bank_s *bank, int first, int last);
static int lpc2000_protect(struct flash_bank_s *bank, int set, int first, int last);
static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int lpc2000_probe(struct flash_bank_s *bank);
static int lpc2000_erase_check(struct flash_bank_s *bank);
static int lpc2000_protect_check(struct flash_bank_s *bank);
static int lpc2000_info(struct flash_bank_s *bank, char *buf, int buf_size);
static int lpc2000_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
flash_driver_t lpc2000_flash =
static int lpc2000_build_sector_list(struct flash_bank *bank)
{
.name = "lpc2000",
.register_commands = lpc2000_register_commands,
.flash_bank_command = lpc2000_flash_bank_command,
.erase = lpc2000_erase,
.protect = lpc2000_protect,
.write = lpc2000_write,
.probe = lpc2000_probe,
.auto_probe = lpc2000_probe,
.erase_check = lpc2000_erase_check,
.protect_check = lpc2000_protect_check,
.info = lpc2000_info
};
static int lpc2000_register_commands(struct command_context_s *cmd_ctx)
{
command_t *lpc2000_cmd = register_command(cmd_ctx, NULL, "lpc2000", NULL, COMMAND_ANY, NULL);
register_command(cmd_ctx, lpc2000_cmd, "part_id", lpc2000_handle_part_id_command, COMMAND_EXEC,
"print part id of lpc2000 flash bank <num>");
return ERROR_OK;
}
static int lpc2000_build_sector_list(struct flash_bank_s *bank)
{
lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
int i;
uint32_t offset = 0;
@@ -105,7 +70,7 @@ static int lpc2000_build_sector_list(struct flash_bank_s *bank)
if (bank->size == 128 * 1024)
{
bank->num_sectors = 16;
bank->sectors = malloc(sizeof(flash_sector_t) * 16);
bank->sectors = malloc(sizeof(struct flash_sector) * 16);
for (i = 0; i < 16; i++)
{
bank->sectors[i].offset = offset;
@@ -118,7 +83,7 @@ static int lpc2000_build_sector_list(struct flash_bank_s *bank)
else if (bank->size == 256 * 1024)
{
bank->num_sectors = 18;
bank->sectors = malloc(sizeof(flash_sector_t) * 18);
bank->sectors = malloc(sizeof(struct flash_sector) * 18);
for (i = 0; i < 8; i++)
{
@@ -189,7 +154,7 @@ static int lpc2000_build_sector_list(struct flash_bank_s *bank)
break;
}
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
for (i = 0; i < bank->num_sectors; i++)
{
@@ -243,7 +208,7 @@ static int lpc2000_build_sector_list(struct flash_bank_s *bank)
exit(-1);
}
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
for(i = 0; i < bank->num_sectors; i++)
{
@@ -271,15 +236,15 @@ static int lpc2000_build_sector_list(struct flash_bank_s *bank)
* 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[4])
static int lpc2000_iap_call(struct flash_bank *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; /* for LPC2000 */
armv7m_algorithm_t armv7m_info; /* for LPC1700 */
struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
struct target *target = bank->target;
struct mem_param mem_params[2];
struct reg_param reg_params[5];
struct arm_algorithm armv4_5_info; /* for LPC2000 */
struct armv7m_algorithm armv7m_info; /* for LPC1700 */
uint32_t status_code;
uint32_t iap_entry_point = 0; /* to make compiler happier */
@@ -299,8 +264,10 @@ static int lpc2000_iap_call(flash_bank_t *bank, int code, uint32_t param_table[5
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));
target_buffer_set_u32(target, jump_gate,
ARMV4_5_T_BX(12));
target_buffer_set_u32(target, jump_gate + 4,
ARMV4_5_T_B(0xfffffe));
break;
case lpc2000_v1:
case lpc2000_v2:
@@ -328,9 +295,9 @@ static int lpc2000_iap_call(flash_bank_t *bank, int code, uint32_t param_table[5
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;
armv4_5_info.common_magic = ARM_COMMON_MAGIC;
armv4_5_info.core_mode = ARM_MODE_SVC;
armv4_5_info.core_state = ARM_STATE_ARM;
iap_entry_point = 0x7ffffff1;
break;
default:
@@ -376,7 +343,7 @@ static int lpc2000_iap_call(flash_bank_t *bank, int code, uint32_t param_table[5
case lpc2000_v1:
case lpc2000_v2:
/* IAP stack */
init_reg_param(&reg_params[3], "r13_svc", 32, PARAM_OUT);
init_reg_param(&reg_params[3], "sp_svc", 32, PARAM_OUT);
buf_set_u32(reg_params[3].value, 0, 32, lpc2000_info->iap_working_area->address + 0xb4);
/* return address */
@@ -412,7 +379,7 @@ static int lpc2000_iap_call(flash_bank_t *bank, int code, uint32_t param_table[5
return status_code;
}
static int lpc2000_iap_blank_check(struct flash_bank_s *bank, int first, int last)
static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last)
{
uint32_t param_table[5];
uint32_t result_table[4];
@@ -456,20 +423,20 @@ static int lpc2000_iap_blank_check(struct flash_bank_s *bank, int first, int las
/*
* 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)
FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
{
lpc2000_flash_bank_t *lpc2000_info;
struct lpc2000_flash_bank *lpc2000_info;
if (argc < 8)
if (CMD_ARGC < 8)
{
LOG_WARNING("incomplete flash_bank lpc2000 configuration");
return ERROR_FLASH_BANK_INVALID;
}
lpc2000_info = malloc(sizeof(lpc2000_flash_bank_t));
lpc2000_info = malloc(sizeof(struct lpc2000_flash_bank));
bank->driver_priv = lpc2000_info;
if (strcmp(args[6], "lpc2000_v1") == 0)
if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0)
{
lpc2000_info->variant = lpc2000_v1;
lpc2000_info->cmd51_dst_boundary = 512;
@@ -477,7 +444,7 @@ static int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *c
lpc2000_info->cmd51_can_8192b = 1;
lpc2000_info->checksum_vector = 5;
}
else if (strcmp(args[6], "lpc2000_v2") == 0)
else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0)
{
lpc2000_info->variant = lpc2000_v2;
lpc2000_info->cmd51_dst_boundary = 256;
@@ -485,7 +452,7 @@ static int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *c
lpc2000_info->cmd51_can_8192b = 0;
lpc2000_info->checksum_vector = 5;
}
else if (strcmp(args[6], "lpc1700") == 0)
else if (strcmp(CMD_ARGV[6], "lpc1700") == 0)
{
lpc2000_info->variant = lpc1700;
lpc2000_info->cmd51_dst_boundary = 256;
@@ -495,28 +462,28 @@ static int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *c
}
else
{
LOG_ERROR("unknown LPC2000 variant: %s", args[6]);
LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]);
free(lpc2000_info);
return ERROR_FLASH_BANK_INVALID;
}
lpc2000_info->iap_working_area = NULL;
lpc2000_info->cclk = strtoul(args[7], NULL, 0);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);
lpc2000_info->calc_checksum = 0;
lpc2000_build_sector_list(bank);
if (argc >= 9)
if (CMD_ARGC >= 9)
{
if (strcmp(args[8], "calc_checksum") == 0)
if (strcmp(CMD_ARGV[8], "calc_checksum") == 0)
lpc2000_info->calc_checksum = 1;
}
return ERROR_OK;
}
static int lpc2000_erase(struct flash_bank_s *bank, int first, int last)
static int lpc2000_erase(struct flash_bank *bank, int first, int last)
{
lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
uint32_t param_table[5];
uint32_t result_table[4];
int status_code;
@@ -566,16 +533,16 @@ static int lpc2000_erase(struct flash_bank_s *bank, int first, int last)
return ERROR_OK;
}
static int lpc2000_protect(struct flash_bank_s *bank, int set, int first, int last)
static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last)
{
/* can't protect/unprotect on the lpc2000 */
return ERROR_OK;
}
static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int lpc2000_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
target_t *target = bank->target;
struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t dst_min_alignment;
uint32_t bytes_remaining = count;
uint32_t bytes_written = 0;
@@ -585,7 +552,7 @@ static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t of
uint32_t result_table[4];
int status_code;
int i;
working_area_t *download_area;
struct working_area *download_area;
int retval = ERROR_OK;
if (bank->target->state != TARGET_HALTED)
@@ -609,7 +576,7 @@ static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t of
{
if (offset >= bank->sectors[i].offset)
first_sector = i;
if (offset + CEIL(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
last_sector = i;
}
@@ -740,7 +707,7 @@ static int lpc2000_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t of
return retval;
}
static int lpc2000_probe(struct flash_bank_s *bank)
static int lpc2000_probe(struct flash_bank *bank)
{
/* we can't probe on an lpc2000
* if this is an lpc2xxx, it has the configured flash
@@ -748,7 +715,7 @@ static int lpc2000_probe(struct flash_bank_s *bank)
return ERROR_OK;
}
static int lpc2000_erase_check(struct flash_bank_s *bank)
static int lpc2000_erase_check(struct flash_bank *bank)
{
if (bank->target->state != TARGET_HALTED)
{
@@ -759,39 +726,36 @@ static int lpc2000_erase_check(struct flash_bank_s *bank)
return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);
}
static int lpc2000_protect_check(struct flash_bank_s *bank)
static int lpc2000_protect_check(struct flash_bank *bank)
{
/* sectors are always protected */
return ERROR_OK;
}
static int lpc2000_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
{
lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv;
struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz" , lpc2000_info->variant, lpc2000_info->cclk);
return ERROR_OK;
}
static int lpc2000_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(lpc2000_handle_part_id_command)
{
flash_bank_t *bank;
uint32_t param_table[5];
uint32_t result_table[4];
int status_code;
if (argc < 1)
if (CMD_ARGC < 1)
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
if (bank->target->state != TARGET_HALTED)
{
@@ -803,15 +767,48 @@ static int lpc2000_handle_part_id_command(struct command_context_s *cmd_ctx, cha
{
if (status_code == ERROR_FLASH_OPERATION_FAILED)
{
command_print(cmd_ctx, "no sufficient working area specified, can't access LPC2000 IAP interface");
command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface");
return ERROR_OK;
}
command_print(cmd_ctx, "lpc2000 IAP returned status code %i", status_code);
command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code);
}
else
{
command_print(cmd_ctx, "lpc2000 part id: 0x%8.8" PRIx32 , result_table[0]);
command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32 , result_table[0]);
}
return ERROR_OK;
}
static const struct command_registration lpc2000_exec_command_handlers[] = {
{
.name = "part_id",
.handler = lpc2000_handle_part_id_command,
.mode = COMMAND_EXEC,
.help = "print part id of lpc2000 flash bank <num>",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration lpc2000_command_handlers[] = {
{
.name = "lpc2000",
.mode = COMMAND_ANY,
.help = "lpc2000 flash command group",
.chain = lpc2000_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
struct flash_driver lpc2000_flash = {
.name = "lpc2000",
.commands = lpc2000_command_handlers,
.flash_bank_command = lpc2000_flash_bank_command,
.erase = lpc2000_erase,
.protect = lpc2000_protect,
.write = lpc2000_write,
.probe = lpc2000_probe,
.auto_probe = lpc2000_probe,
.erase_check = lpc2000_erase_check,
.protect_check = lpc2000_protect_check,
.info = lpc2000_info,
};

View File

@@ -23,8 +23,6 @@
#ifndef LPC2000_H
#define LPC2000_H
#include "flash.h"
typedef enum
{
lpc2000_v1,
@@ -32,10 +30,10 @@ typedef enum
lpc1700
} lpc2000_variant;
typedef struct lpc2000_flash_bank_s
struct lpc2000_flash_bank
{
lpc2000_variant variant;
struct working_area_s *iap_working_area;
struct working_area *iap_working_area;
uint32_t cclk;
int cmd51_dst_boundary;
int cmd51_can_256b;
@@ -43,7 +41,7 @@ typedef struct lpc2000_flash_bank_s
int calc_checksum;
uint32_t cmd51_max_buffer;
int checksum_vector;
} lpc2000_flash_bank_t;
};
enum lpc2000_status_codes
{

View File

@@ -31,8 +31,9 @@
#include "config.h"
#endif
#include "imp.h"
#include "lpc288x.h"
#include "binarybuffer.h"
#include <helper/binarybuffer.h>
#define LOAD_TIMER_ERASE 0
@@ -84,44 +85,15 @@
/* F_CLK_TIME */
#define FCT_CLK_DIV_MASK 0x0FFF
static int lpc288x_register_commands(struct command_context_s *cmd_ctx);
static int lpc288x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int lpc288x_erase(struct flash_bank_s *bank, int first, int last);
static int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int last);
static int lpc288x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int lpc288x_probe(struct flash_bank_s *bank);
static int lpc288x_erase_check(struct flash_bank_s *bank);
static int lpc288x_protect_check(struct flash_bank_s *bank);
static int lpc288x_info(struct flash_bank_s *bank, char *buf, int buf_size);
static uint32_t lpc288x_wait_status_busy(flash_bank_t *bank, int timeout);
static void lpc288x_load_timer(int erase, struct target_s *target);
static void lpc288x_set_flash_clk(struct flash_bank_s *bank);
static uint32_t lpc288x_system_ready(struct flash_bank_s *bank);
static uint32_t lpc288x_wait_status_busy(struct flash_bank *bank, int timeout);
static void lpc288x_load_timer(int erase, struct target *target);
static void lpc288x_set_flash_clk(struct flash_bank *bank);
static uint32_t lpc288x_system_ready(struct flash_bank *bank);
flash_driver_t lpc288x_flash =
{
.name = "lpc288x",
.register_commands = lpc288x_register_commands,
.flash_bank_command = lpc288x_flash_bank_command,
.erase = lpc288x_erase,
.protect = lpc288x_protect,
.write = lpc288x_write,
.probe = lpc288x_probe,
.auto_probe = lpc288x_probe,
.erase_check = lpc288x_erase_check,
.protect_check = lpc288x_protect_check,
.info = lpc288x_info
};
static int lpc288x_register_commands(struct command_context_s *cmd_ctx)
{
return ERROR_OK;
}
static uint32_t lpc288x_wait_status_busy(flash_bank_t *bank, int timeout)
static uint32_t lpc288x_wait_status_busy(struct flash_bank *bank, int timeout)
{
uint32_t status;
target_t *target = bank->target;
struct target *target = bank->target;
do
{
alive_sleep(1);
@@ -138,10 +110,10 @@ static uint32_t lpc288x_wait_status_busy(flash_bank_t *bank, int timeout)
}
/* Read device id register and fill in driver info structure */
static int lpc288x_read_part_info(struct flash_bank_s *bank)
static int lpc288x_read_part_info(struct flash_bank *bank)
{
lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
target_t *target = bank->target;
struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t cidr;
int i = 0;
@@ -166,7 +138,7 @@ static int lpc288x_read_part_info(struct flash_bank_s *bank)
/* setup the sector info... */
offset = bank->base;
bank->num_sectors = 23;
bank->sectors = malloc(sizeof(flash_sector_t) * 23);
bank->sectors = malloc(sizeof(struct flash_sector) * 23);
for (i = 0; i < 15; i++)
{
@@ -188,28 +160,28 @@ static int lpc288x_read_part_info(struct flash_bank_s *bank)
return ERROR_OK;
}
static int lpc288x_protect_check(struct flash_bank_s *bank)
static int lpc288x_protect_check(struct flash_bank *bank)
{
return ERROR_OK;
}
/* flash_bank LPC288x 0 0 0 0 <target#> <cclk> */
static int lpc288x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
FLASH_BANK_COMMAND_HANDLER(lpc288x_flash_bank_command)
{
lpc288x_flash_bank_t *lpc288x_info;
struct lpc288x_flash_bank *lpc288x_info;
if (argc < 6)
if (CMD_ARGC < 6)
{
LOG_WARNING("incomplete flash_bank LPC288x configuration");
return ERROR_FLASH_BANK_INVALID;
}
lpc288x_info = malloc(sizeof(lpc288x_flash_bank_t));
lpc288x_info = malloc(sizeof(struct lpc288x_flash_bank));
bank->driver_priv = lpc288x_info;
/* part wasn't probed for info yet */
lpc288x_info->cidr = 0;
lpc288x_info->cclk = strtoul(args[6], NULL, 0);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], lpc288x_info->cclk);
return ERROR_OK;
}
@@ -219,10 +191,10 @@ static int lpc288x_flash_bank_command(struct command_context_s *cmd_ctx, char *c
* AHB = 12 MHz ?
* 12000000/66000 = 182
* CLK_DIV = 60 ? */
static void lpc288x_set_flash_clk(struct flash_bank_s *bank)
static void lpc288x_set_flash_clk(struct flash_bank *bank)
{
uint32_t clk_time;
lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
clk_time = (lpc288x_info->cclk / 66000) / 3;
target_write_u32(bank->target, F_CTRL, FC_CS | FC_WEN);
target_write_u32(bank->target, F_CLK_TIME, clk_time);
@@ -234,7 +206,7 @@ static void lpc288x_set_flash_clk(struct flash_bank_s *bank)
* LOAD_TIMER_WRITE FPT_TIME = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512
* = 23 (75) (AN10548 72 - is this wrong?)
* TODO: Sort out timing calcs ;) */
static void lpc288x_load_timer(int erase, struct target_s *target)
static void lpc288x_load_timer(int erase, struct target *target)
{
if (erase == LOAD_TIMER_ERASE)
{
@@ -246,9 +218,9 @@ static void lpc288x_load_timer(int erase, struct target_s *target)
}
}
static uint32_t lpc288x_system_ready(struct flash_bank_s *bank)
static uint32_t lpc288x_system_ready(struct flash_bank *bank)
{
lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
if (lpc288x_info->cidr == 0)
{
return ERROR_FLASH_BANK_NOT_PROBED;
@@ -262,7 +234,7 @@ static uint32_t lpc288x_system_ready(struct flash_bank_s *bank)
return ERROR_OK;
}
static int lpc288x_erase_check(struct flash_bank_s *bank)
static int lpc288x_erase_check(struct flash_bank *bank)
{
uint32_t status = lpc288x_system_ready(bank); /* probed? halted? */
if (status != ERROR_OK)
@@ -274,11 +246,11 @@ static int lpc288x_erase_check(struct flash_bank_s *bank)
return ERROR_OK;
}
static int lpc288x_erase(struct flash_bank_s *bank, int first, int last)
static int lpc288x_erase(struct flash_bank *bank, int first, int last)
{
uint32_t status;
int sector;
target_t *target = bank->target;
struct target *target = bank->target;
status = lpc288x_system_ready(bank); /* probed? halted? */
if (status != ERROR_OK)
@@ -315,11 +287,11 @@ static int lpc288x_erase(struct flash_bank_s *bank, int first, int last)
return ERROR_OK;
}
static int lpc288x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int lpc288x_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
uint8_t page_buffer[FLASH_PAGE_SIZE];
uint32_t status, source_offset,dest_offset;
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t bytes_remaining = count;
uint32_t first_sector, last_sector, sector, page;
int i;
@@ -431,10 +403,10 @@ static int lpc288x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t of
return ERROR_OK;
}
static int lpc288x_probe(struct flash_bank_s *bank)
static int lpc288x_probe(struct flash_bank *bank)
{
/* we only deal with LPC2888 so flash config is fixed */
lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
int retval;
if (lpc288x_info->cidr != 0)
@@ -454,17 +426,17 @@ static int lpc288x_probe(struct flash_bank_s *bank)
return ERROR_OK;
}
static int lpc288x_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int lpc288x_info(struct flash_bank *bank, char *buf, int buf_size)
{
snprintf(buf, buf_size, "lpc288x flash driver");
return ERROR_OK;
}
static int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int last)
static int lpc288x_protect(struct flash_bank *bank, int set, int first, int last)
{
int lockregion, status;
uint32_t value;
target_t *target = bank->target;
struct target *target = bank->target;
/* probed? halted? */
status = lpc288x_system_ready(bank);
@@ -499,3 +471,16 @@ static int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int la
return ERROR_OK;
}
struct flash_driver lpc288x_flash = {
.name = "lpc288x",
.flash_bank_command = lpc288x_flash_bank_command,
.erase = lpc288x_erase,
.protect = lpc288x_protect,
.write = lpc288x_write,
.probe = lpc288x_probe,
.auto_probe = lpc288x_probe,
.erase_check = lpc288x_erase_check,
.protect_check = lpc288x_protect_check,
.info = lpc288x_info,
};

View File

@@ -21,9 +21,7 @@
#ifndef lpc288x_H
#define lpc288x_H
#include "flash.h"
typedef struct lpc288x_flash_bank_s
struct lpc288x_flash_bank
{
uint32_t working_area;
uint32_t working_area_size;
@@ -34,6 +32,6 @@ typedef struct lpc288x_flash_bank_s
uint32_t cclk;
uint32_t sector_size_break;
} lpc288x_flash_bank_t;
};
#endif /* lpc288x_H */

View File

@@ -23,11 +23,11 @@
#endif
#include "image.h"
#include "lpc2900.h"
#include "binarybuffer.h"
#include "armv4_5.h"
#include "imp.h"
#include <helper/binarybuffer.h>
#include <target/algorithm.h>
#include <target/arm.h>
#include <target/image.h>
/* 1024 bytes */
@@ -129,7 +129,7 @@
/**
* Private data for \c lpc2900 flash driver.
*/
typedef struct lpc2900_flash_bank_s
struct lpc2900_flash_bank
{
/**
* Holds the value read from CHIPID register.
@@ -168,32 +168,17 @@ typedef struct lpc2900_flash_bank_s
*/
uint32_t max_ram_block;
} lpc2900_flash_bank_t;
};
static int lpc2900_register_commands(struct command_context_s *cmd_ctx);
static int lpc2900_flash_bank_command(struct command_context_s *cmd_ctx,
char *cmd, char **args, int argc,
struct flash_bank_s *bank);
static int lpc2900_erase(struct flash_bank_s *bank, int first, int last);
static int lpc2900_protect(struct flash_bank_s *bank, int set, int first, int last);
static int lpc2900_write(struct flash_bank_s *bank,
uint8_t *buffer, uint32_t offset, uint32_t count);
static int lpc2900_probe(struct flash_bank_s *bank);
static int lpc2900_erase_check(struct flash_bank_s *bank);
static int lpc2900_protect_check(struct flash_bank_s *bank);
static int lpc2900_info(struct flash_bank_s *bank, char *buf, int buf_size);
static uint32_t lpc2900_wait_status(flash_bank_t *bank, uint32_t mask, int timeout);
static void lpc2900_setup(struct flash_bank_s *bank);
static uint32_t lpc2900_is_ready(struct flash_bank_s *bank);
static uint32_t lpc2900_read_security_status(struct flash_bank_s *bank);
static uint32_t lpc2900_run_bist128(struct flash_bank_s *bank,
static uint32_t lpc2900_wait_status(struct flash_bank *bank, uint32_t mask, int timeout);
static void lpc2900_setup(struct flash_bank *bank);
static uint32_t lpc2900_is_ready(struct flash_bank *bank);
static uint32_t lpc2900_read_security_status(struct flash_bank *bank);
static uint32_t lpc2900_run_bist128(struct flash_bank *bank,
uint32_t addr_from, uint32_t addr_to,
uint32_t (*signature)[4] );
static uint32_t lpc2900_address2sector(struct flash_bank_s *bank, uint32_t offset);
static uint32_t lpc2900_address2sector(struct flash_bank *bank, uint32_t offset);
static uint32_t lpc2900_calc_tr( uint32_t clock, uint32_t time );
@@ -209,12 +194,12 @@ static uint32_t lpc2900_calc_tr( uint32_t clock, uint32_t time );
* @param[in] mask Mask to be used for INT_STATUS
* @param[in] timeout Timeout in ms
*/
static uint32_t lpc2900_wait_status( flash_bank_t *bank,
static uint32_t lpc2900_wait_status( struct flash_bank *bank,
uint32_t mask,
int timeout )
{
uint32_t int_status;
target_t *target = bank->target;
struct target *target = bank->target;
do
@@ -243,10 +228,10 @@ static uint32_t lpc2900_wait_status( flash_bank_t *bank,
*
* @param bank Pointer to the flash bank descriptor
*/
static void lpc2900_setup( struct flash_bank_s *bank )
static void lpc2900_setup( struct flash_bank *bank )
{
uint32_t fcra;
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
/* Power up the flash block */
@@ -266,9 +251,9 @@ static void lpc2900_setup( struct flash_bank_s *bank )
* Must have been successfully probed.
* Must be halted.
*/
static uint32_t lpc2900_is_ready( struct flash_bank_s *bank )
static uint32_t lpc2900_is_ready( struct flash_bank *bank )
{
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
if( lpc2900_info->chipid != EXPECTED_CHIPID )
{
@@ -290,7 +275,7 @@ static uint32_t lpc2900_is_ready( struct flash_bank_s *bank )
*
* @param bank Pointer to the flash bank descriptor
*/
static uint32_t lpc2900_read_security_status( struct flash_bank_s *bank )
static uint32_t lpc2900_read_security_status( struct flash_bank *bank )
{
uint32_t status;
if( (status = lpc2900_is_ready( bank )) != ERROR_OK )
@@ -298,7 +283,7 @@ static uint32_t lpc2900_read_security_status( struct flash_bank_s *bank )
return status;
}
target_t *target = bank->target;
struct target *target = bank->target;
/* Enable ISS access */
target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB | FCTR_FS_ISS);
@@ -371,12 +356,12 @@ static uint32_t lpc2900_read_security_status( struct flash_bank_s *bank )
* @param addr_to
* @param signature
*/
static uint32_t lpc2900_run_bist128(struct flash_bank_s *bank,
static uint32_t lpc2900_run_bist128(struct flash_bank *bank,
uint32_t addr_from,
uint32_t addr_to,
uint32_t (*signature)[4] )
{
target_t *target = bank->target;
struct target *target = bank->target;
/* Clear END_OF_MISR interrupt status */
target_write_u32( target, INT_CLR_STATUS, INTSRC_END_OF_MISR );
@@ -408,7 +393,7 @@ static uint32_t lpc2900_run_bist128(struct flash_bank_s *bank,
* @param bank Pointer to the flash bank descriptor
* @param offset Offset address relative to bank start
*/
static uint32_t lpc2900_address2sector( struct flash_bank_s *bank,
static uint32_t lpc2900_address2sector( struct flash_bank *bank,
uint32_t offset )
{
uint32_t address = bank->base + offset;
@@ -439,7 +424,7 @@ static uint32_t lpc2900_address2sector( struct flash_bank_s *bank,
* @param pagenum Page number (0...7)
* @param page Page array (FLASH_PAGE_SIZE bytes)
*/
static int lpc2900_write_index_page( struct flash_bank_s *bank,
static int lpc2900_write_index_page( struct flash_bank *bank,
int pagenum,
uint8_t (*page)[FLASH_PAGE_SIZE] )
{
@@ -451,7 +436,7 @@ static int lpc2900_write_index_page( struct flash_bank_s *bank,
}
/* Get target, and check if it's halted */
target_t *target = bank->target;
struct target *target = bank->target;
if( target->state != TARGET_HALTED )
{
LOG_ERROR( "Target not halted" );
@@ -459,7 +444,7 @@ static int lpc2900_write_index_page( struct flash_bank_s *bank,
}
/* Private info */
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
/* Enable flash block and set the correct CRA clock of 66 kHz */
lpc2900_setup( bank );
@@ -545,33 +530,23 @@ static uint32_t lpc2900_calc_tr( uint32_t clock, uint32_t time )
*
* Uses the Built-In-Self-Test (BIST) to generate a 128-bit hash value
* of the flash content.
*
* @param cmd_ctx
* @param cmd
* @param args
* @param argc
*/
static int lpc2900_handle_signature_command( struct command_context_s *cmd_ctx,
char *cmd, char **args, int argc )
COMMAND_HANDLER(lpc2900_handle_signature_command)
{
flash_bank_t *bank;
uint32_t status;
uint32_t signature[4];
if( argc < 1 )
if( CMD_ARGC < 1 )
{
LOG_WARNING( "Too few arguments. Call: lpc2900 signature <bank#>" );
return ERROR_FLASH_BANK_INVALID;
}
/* Get the bank descriptor */
bank = get_flash_bank_by_num( strtoul(args[0], NULL, 0) );
if( !bank )
{
command_print( cmd_ctx, "flash bank '#%s' is out of bounds", args[0] );
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
if( bank->target->state != TARGET_HALTED )
{
@@ -589,7 +564,7 @@ static int lpc2900_handle_signature_command( struct command_context_s *cmd_ctx,
return status;
}
command_print( cmd_ctx, "signature: 0x%8.8" PRIx32
command_print( CMD_CTX, "signature: 0x%8.8" PRIx32
":0x%8.8" PRIx32
":0x%8.8" PRIx32
":0x%8.8" PRIx32,
@@ -605,35 +580,24 @@ static int lpc2900_handle_signature_command( struct command_context_s *cmd_ctx,
*
* Read customer info from index sector, and store that block of data into
* a disk file. The format is binary.
*
* @param cmd_ctx
* @param cmd
* @param args
* @param argc
*/
static int lpc2900_handle_read_custom_command( struct command_context_s *cmd_ctx,
char *cmd, char **args, int argc )
COMMAND_HANDLER(lpc2900_handle_read_custom_command)
{
flash_bank_t *bank;
if( argc < 2 )
if( CMD_ARGC < 2 )
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
/* Get the bank descriptor */
bank = get_flash_bank_by_num( strtoul(args[0], NULL, 0) );
if( !bank )
{
command_print( cmd_ctx, "flash bank '#%s' is out of bounds", args[0] );
return ERROR_OK;
}
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
lpc2900_info->risky = 0;
/* Get target, and check if it's halted */
target_t *target = bank->target;
struct target *target = bank->target;
if( target->state != TARGET_HALTED )
{
LOG_ERROR( "Target not halted" );
@@ -658,8 +622,8 @@ static int lpc2900_handle_read_custom_command( struct command_context_s *cmd_ctx
target_write_u32( target, FCTR, FCTR_FS_CS | FCTR_FS_WEB );
/* Try and open the file */
fileio_t fileio;
char *filename = args[1];
struct fileio fileio;
const char *filename = CMD_ARGV[1];
int ret = fileio_open( &fileio, filename, FILEIO_WRITE, FILEIO_BINARY );
if( ret != ERROR_OK )
{
@@ -667,7 +631,7 @@ static int lpc2900_handle_read_custom_command( struct command_context_s *cmd_ctx
return ret;
}
uint32_t nwritten;
size_t nwritten;
ret = fileio_write( &fileio, sizeof(customer),
(const uint8_t *)customer, &nwritten );
if( ret != ERROR_OK )
@@ -687,43 +651,32 @@ static int lpc2900_handle_read_custom_command( struct command_context_s *cmd_ctx
/**
* Enter password to enable potentially dangerous options.
*
* @param cmd_ctx
* @param cmd
* @param args
* @param argc
*/
static int lpc2900_handle_password_command(struct command_context_s *cmd_ctx,
char *cmd, char **args, int argc)
COMMAND_HANDLER(lpc2900_handle_password_command)
{
flash_bank_t *bank;
if (argc < 2)
if (CMD_ARGC < 2)
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
/* Get the bank descriptor */
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
#define ISS_PASSWORD "I_know_what_I_am_doing"
lpc2900_info->risky = !strcmp( args[1], ISS_PASSWORD );
lpc2900_info->risky = !strcmp( CMD_ARGV[1], ISS_PASSWORD );
if( !lpc2900_info->risky )
{
command_print(cmd_ctx, "Wrong password (use '%s')", ISS_PASSWORD);
command_print(CMD_CTX, "Wrong password (use '%s')", ISS_PASSWORD);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
command_print(cmd_ctx,
command_print(CMD_CTX,
"Potentially dangerous operation allowed in next command!");
return ERROR_OK;
@@ -733,39 +686,31 @@ static int lpc2900_handle_password_command(struct command_context_s *cmd_ctx,
/**
* Write customer info from file to the index sector.
*
* @param cmd_ctx
* @param cmd
* @param args
* @param argc
*/
static int lpc2900_handle_write_custom_command( struct command_context_s *cmd_ctx,
char *cmd, char **args, int argc )
COMMAND_HANDLER(lpc2900_handle_write_custom_command)
{
if (argc < 2)
if (CMD_ARGC < 2)
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
/* Get the bank descriptor */
flash_bank_t *bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
/* Check if command execution is allowed. */
if( !lpc2900_info->risky )
{
command_print( cmd_ctx, "Command execution not allowed!" );
command_print( CMD_CTX, "Command execution not allowed!" );
return ERROR_COMMAND_ARGUMENT_INVALID;
}
lpc2900_info->risky = 0;
/* Get target, and check if it's halted */
target_t *target = bank->target;
struct target *target = bank->target;
if (target->state != TARGET_HALTED)
{
LOG_ERROR("Target not halted");
@@ -773,14 +718,14 @@ static int lpc2900_handle_write_custom_command( struct command_context_s *cmd_ct
}
/* The image will always start at offset 0 */
image_t image;
struct image image;
image.base_address_set = 1;
image.base_address = 0;
image.start_address_set = 0;
char *filename = args[1];
char *type = (argc >= 3) ? args[2] : NULL;
int retval = image_open(&image, filename, type);
const char *filename = CMD_ARGV[1];
const char *type = (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL;
retval = image_open(&image, filename, type);
if (retval != ERROR_OK)
{
return retval;
@@ -810,7 +755,7 @@ static int lpc2900_handle_write_custom_command( struct command_context_s *cmd_ct
/* Page 4 */
uint32_t offset = ISS_CUSTOMER_START1 % FLASH_PAGE_SIZE;
memset( page, 0xff, FLASH_PAGE_SIZE );
uint32_t size_read;
size_t size_read;
retval = image_read_section( &image, 0, 0,
ISS_CUSTOMER_SIZE1, &page[offset], &size_read);
if( retval != ERROR_OK )
@@ -851,52 +796,45 @@ static int lpc2900_handle_write_custom_command( struct command_context_s *cmd_ct
/**
* Activate 'sector security' for a range of sectors.
*
* @param cmd_ctx
* @param cmd
* @param args
* @param argc
*/
static int lpc2900_handle_secure_sector_command(struct command_context_s *cmd_ctx,
char *cmd, char **args, int argc)
COMMAND_HANDLER(lpc2900_handle_secure_sector_command)
{
if (argc < 3)
if (CMD_ARGC < 3)
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
/* Get the bank descriptor */
flash_bank_t *bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
/* Check if command execution is allowed. */
if( !lpc2900_info->risky )
{
command_print( cmd_ctx, "Command execution not allowed! "
command_print( CMD_CTX, "Command execution not allowed! "
"(use 'password' command first)");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
lpc2900_info->risky = 0;
/* Read sector range, and do a sanity check. */
int first = strtoul(args[1], NULL, 0);
int last = strtoul(args[2], NULL, 0);
int first, last;
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last);
if( (first >= bank->num_sectors) ||
(last >= bank->num_sectors) ||
(first > last) )
{
command_print( cmd_ctx, "Illegal sector range" );
command_print( CMD_CTX, "Illegal sector range" );
return ERROR_COMMAND_ARGUMENT_INVALID;
}
uint8_t page[FLASH_PAGE_SIZE];
int sector;
int retval;
/* Sectors in page 6 */
if( (first <= 4) || (last >= 8) )
@@ -940,7 +878,7 @@ static int lpc2900_handle_secure_sector_command(struct command_context_s *cmd_ct
}
}
command_print( cmd_ctx,
command_print( CMD_CTX,
"Sectors security will become effective after next power cycle");
/* Update the sector security status */
@@ -957,33 +895,26 @@ static int lpc2900_handle_secure_sector_command(struct command_context_s *cmd_ct
/**
* Activate JTAG protection.
*
* @param cmd_ctx
* @param cmd
* @param args
* @param argc
*/
static int lpc2900_handle_secure_jtag_command(struct command_context_s *cmd_ctx,
char *cmd, char **args, int argc)
COMMAND_HANDLER(lpc2900_handle_secure_jtag_command)
{
if (argc < 1)
if (CMD_ARGC < 1)
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
/* Get the bank descriptor */
flash_bank_t *bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
/* Check if command execution is allowed. */
if( !lpc2900_info->risky )
{
command_print( cmd_ctx, "Command execution not allowed! "
command_print( CMD_CTX, "Command execution not allowed! "
"(use 'password' command first)");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
@@ -1001,7 +932,6 @@ static int lpc2900_handle_secure_jtag_command(struct command_context_s *cmd_ctx,
page[0x30 + 3] = 0x7F;
/* Write to page 5 */
int retval;
if( (retval = lpc2900_write_index_page( bank, 5, &page ))
!= ERROR_OK )
{
@@ -1018,106 +948,86 @@ static int lpc2900_handle_secure_jtag_command(struct command_context_s *cmd_ctx,
/*********************** Flash interface functions **************************/
static const struct command_registration lpc2900_exec_command_handlers[] = {
{
.name = "signature",
.handler = lpc2900_handle_signature_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "Calculate and display signature of flash bank.",
},
{
.name = "read_custom",
.handler = lpc2900_handle_read_custom_command,
.mode = COMMAND_EXEC,
.usage = "bank_id filename",
.help = "Copies 912 bytes of customer information "
"from index sector into file.",
},
{
.name = "password",
.handler = lpc2900_handle_password_command,
.mode = COMMAND_EXEC,
.usage = "bank_id password",
.help = "Enter fixed password to enable 'dangerous' options.",
},
{
.name = "write_custom",
.handler = lpc2900_handle_write_custom_command,
.mode = COMMAND_EXEC,
.usage = "bank_id filename ('bin'|'ihex'|'elf'|'s19')",
.help = "Copies 912 bytes of customer info from file "
"to index sector.",
},
{
.name = "secure_sector",
.handler = lpc2900_handle_secure_sector_command,
.mode = COMMAND_EXEC,
.usage = "bank_id first_sector last_sector",
.help = "Activate sector security for a range of sectors. "
"It will be effective after a power cycle.",
},
{
.name = "secure_jtag",
.handler = lpc2900_handle_secure_jtag_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "Disable the JTAG port. "
"It will be effective after a power cycle.",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration lpc2900_command_handlers[] = {
{
.name = "lpc2900",
.mode = COMMAND_ANY,
.help = "LPC2900 flash command group",
.chain = lpc2900_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
/**
* Register private command handlers.
*
* @param cmd_ctx
*/
static int lpc2900_register_commands(struct command_context_s *cmd_ctx)
/// Evaluate flash bank command.
FLASH_BANK_COMMAND_HANDLER(lpc2900_flash_bank_command)
{
command_t *lpc2900_cmd = register_command(cmd_ctx, NULL, "lpc2900",
NULL, COMMAND_ANY, NULL);
struct lpc2900_flash_bank *lpc2900_info;
register_command(
cmd_ctx,
lpc2900_cmd,
"signature",
lpc2900_handle_signature_command,
COMMAND_EXEC,
"<bank> | "
"print device signature of flash bank");
register_command(
cmd_ctx,
lpc2900_cmd,
"read_custom",
lpc2900_handle_read_custom_command,
COMMAND_EXEC,
"<bank> <filename> | "
"read customer information from index sector to file");
register_command(
cmd_ctx,
lpc2900_cmd,
"password",
lpc2900_handle_password_command,
COMMAND_EXEC,
"<bank> <password> | "
"enter password to enable 'dangerous' options");
register_command(
cmd_ctx,
lpc2900_cmd,
"write_custom",
lpc2900_handle_write_custom_command,
COMMAND_EXEC,
"<bank> <filename> [<type>] | "
"write customer info from file to index sector");
register_command(
cmd_ctx,
lpc2900_cmd,
"secure_sector",
lpc2900_handle_secure_sector_command,
COMMAND_EXEC,
"<bank> <first> <last> | "
"activate sector security for a range of sectors");
register_command(
cmd_ctx,
lpc2900_cmd,
"secure_jtag",
lpc2900_handle_secure_jtag_command,
COMMAND_EXEC,
"<bank> <level> | "
"activate JTAG security");
return ERROR_OK;
}
/**
* Evaluate flash bank command.
*
* Syntax: flash bank lpc2900 0 0 0 0 target# system_base_clock
*
* @param cmd_ctx
* @param cmd
* @param args
* @param argc
* @param bank Pointer to the flash bank descriptor
*/
static int lpc2900_flash_bank_command(struct command_context_s *cmd_ctx,
char *cmd, char **args, int argc,
struct flash_bank_s *bank)
{
lpc2900_flash_bank_t *lpc2900_info;
if (argc < 6)
if (CMD_ARGC < 6)
{
LOG_WARNING("incomplete flash_bank LPC2900 configuration");
return ERROR_FLASH_BANK_INVALID;
}
lpc2900_info = malloc(sizeof(lpc2900_flash_bank_t));
lpc2900_info = malloc(sizeof(struct lpc2900_flash_bank));
bank->driver_priv = lpc2900_info;
/* Get flash clock.
* Reject it if we can't meet the requirements for program time
* (if clock too slow), or for erase time (clock too fast).
*/
lpc2900_info->clk_sys_fmc = strtoul(args[6], NULL, 0) * 1000;
uint32_t clk_sys_fmc;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], clk_sys_fmc);
lpc2900_info->clk_sys_fmc = clk_sys_fmc * 1000;
uint32_t clock_limit;
/* Check program time limit */
@@ -1152,13 +1062,13 @@ static int lpc2900_flash_bank_command(struct command_context_s *cmd_ctx,
* @param first First sector to be erased
* @param last Last sector (including) to be erased
*/
static int lpc2900_erase(struct flash_bank_s *bank, int first, int last)
static int lpc2900_erase(struct flash_bank *bank, int first, int last)
{
uint32_t status;
int sector;
int last_unsecured_sector;
target_t *target = bank->target;
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct target *target = bank->target;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
status = lpc2900_is_ready(bank);
@@ -1259,7 +1169,7 @@ static int lpc2900_erase(struct flash_bank_s *bank, int first, int last)
static int lpc2900_protect(struct flash_bank_s *bank, int set, int first, int last)
static int lpc2900_protect(struct flash_bank *bank, int set, int first, int last)
{
/* This command is not supported.
* "Protection" in LPC2900 terms is handled transparently. Sectors will
@@ -1281,14 +1191,14 @@ static int lpc2900_protect(struct flash_bank_s *bank, int set, int first, int la
* @param offset Start address (relative to bank start)
* @param count Number of bytes to be programmed
*/
static int lpc2900_write(struct flash_bank_s *bank, uint8_t *buffer,
static int lpc2900_write(struct flash_bank *bank, uint8_t *buffer,
uint32_t offset, uint32_t count)
{
uint8_t page[FLASH_PAGE_SIZE];
uint32_t status;
uint32_t num_bytes;
target_t *target = bank->target;
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
struct target *target = bank->target;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
int sector;
int retval;
@@ -1376,7 +1286,7 @@ static int lpc2900_write(struct flash_bank_s *bank, uint8_t *buffer,
/* Try working area allocation. Start with a large buffer, and try with
reduced size if that fails. */
working_area_t *warea;
struct working_area *warea;
uint32_t buffer_size = lpc2900_info->max_ram_block - 1 * KiB;
while( (retval = target_alloc_working_area(target,
buffer_size + target_code_size,
@@ -1395,8 +1305,8 @@ static int lpc2900_write(struct flash_bank_s *bank, uint8_t *buffer,
if( warea )
{
reg_param_t reg_params[5];
armv4_5_algorithm_t armv4_5_info;
struct reg_param reg_params[5];
struct arm_algorithm armv4_5_info;
/* We can use target mode. Download the algorithm. */
retval = target_write_buffer( target,
@@ -1517,9 +1427,9 @@ static int lpc2900_write(struct flash_bank_s *bank, uint8_t *buffer,
buf_set_u32(reg_params[4].value, 0, 32, FPTR_EN_T | prog_time);
/* Execute algorithm, assume breakpoint for last instruction */
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;
armv4_5_info.common_magic = ARM_COMMON_MAGIC;
armv4_5_info.core_mode = ARM_MODE_SVC;
armv4_5_info.core_state = ARM_STATE_ARM;
retval = target_run_algorithm(target, 0, NULL, 5, reg_params,
(warea->address) + buffer_size,
@@ -1630,10 +1540,10 @@ static int lpc2900_write(struct flash_bank_s *bank, uint8_t *buffer,
*
* @param bank Pointer to the flash bank descriptor
*/
static int lpc2900_probe(struct flash_bank_s *bank)
static int lpc2900_probe(struct flash_bank *bank)
{
lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv;
target_t *target = bank->target;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
struct target *target = bank->target;
int i = 0;
uint32_t offset;
@@ -1784,7 +1694,7 @@ static int lpc2900_probe(struct flash_bank_s *bank)
* the logical flash number are translated into the physical flash numbers
* of the device.
*/
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
offset = 0;
for (i = 0; i < bank->num_sectors; i++)
@@ -1833,7 +1743,7 @@ static int lpc2900_probe(struct flash_bank_s *bank)
*
* @param bank Pointer to the flash bank descriptor
*/
static int lpc2900_erase_check(struct flash_bank_s *bank)
static int lpc2900_erase_check(struct flash_bank *bank)
{
uint32_t status = lpc2900_is_ready(bank);
if (status != ERROR_OK)
@@ -1891,7 +1801,7 @@ static int lpc2900_erase_check(struct flash_bank_s *bank)
*
* @param bank Pointer to the flash bank descriptor
*/
static int lpc2900_protect_check(struct flash_bank_s *bank)
static int lpc2900_protect_check(struct flash_bank *bank)
{
return lpc2900_read_security_status(bank);
}
@@ -1904,7 +1814,7 @@ static int lpc2900_protect_check(struct flash_bank_s *bank)
* @param buf Buffer to take the string
* @param buf_size Maximum number of characters that the buffer can take
*/
static int lpc2900_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int lpc2900_info(struct flash_bank *bank, char *buf, int buf_size)
{
snprintf(buf, buf_size, "lpc2900 flash driver");
@@ -1912,10 +1822,10 @@ static int lpc2900_info(struct flash_bank_s *bank, char *buf, int buf_size)
}
flash_driver_t lpc2900_flash =
struct flash_driver lpc2900_flash =
{
.name = "lpc2900",
.register_commands = lpc2900_register_commands,
.commands = lpc2900_command_handlers,
.flash_bank_command = lpc2900_flash_bank_command,
.erase = lpc2900_erase,
.protect = lpc2900_protect,

View File

@@ -23,8 +23,9 @@
#include "config.h"
#endif
#include "non_cfi.h"
#include "imp.h"
#include "cfi.h"
#include "non_cfi.h"
#define KB 1024
@@ -32,7 +33,7 @@
#define ERASE_REGION(num, size) (((size/256) << 16) | (num-1))
/* non-CFI compatible flashes */
static non_cfi_t non_cfi_flashes[] = {
static struct non_cfi non_cfi_flashes[] = {
{
.mfr = CFI_MFR_SST,
.id = 0xd4,
@@ -279,6 +280,23 @@ static non_cfi_t non_cfi_flashes[] = {
ERASE_REGION(15, 64*KB)
}
},
{
.mfr = CFI_MFR_FUJITSU,
.id = 0xba, /* 29LV400BC */
.pri_id = 0x02,
.dev_size = 512*KB,
.interface_desc = 0x1, /* x8 or x16 device w/ nBYTE */
.max_buf_write_size = 0x00,
.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
.num_erase_regions = 4,
.erase_region_info =
{
ERASE_REGION(1, 16*KB),
ERASE_REGION(2, 8*KB),
ERASE_REGION(1, 32*KB),
ERASE_REGION(7, 64*KB)
}
},
{
.mfr = CFI_MFR_AMIC,
.id = 0xb31a, /* A29L800A */
@@ -403,10 +421,10 @@ static non_cfi_t non_cfi_flashes[] = {
}
};
void cfi_fixup_non_cfi(flash_bank_t *bank)
void cfi_fixup_non_cfi(struct flash_bank *bank)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
non_cfi_t *non_cfi = non_cfi_flashes;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
struct non_cfi *non_cfi = non_cfi_flashes;
for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
{
@@ -456,7 +474,7 @@ void cfi_fixup_non_cfi(flash_bank_t *bank)
if (cfi_info->pri_id == 0x2)
{
cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));
pri_ext->pri[0] = 'P';
pri_ext->pri[1] = 'R';

View File

@@ -20,9 +20,7 @@
#ifndef NON_CFI_H
#define NON_CFI_H
#include "flash.h"
typedef struct non_cfi_s
struct non_cfi
{
uint16_t mfr;
uint16_t id;
@@ -33,8 +31,8 @@ typedef struct non_cfi_s
uint8_t num_erase_regions;
uint32_t erase_region_info[6];
uint8_t status_poll_mask;
} non_cfi_t;
};
extern void cfi_fixup_non_cfi(flash_bank_t *bank);
void cfi_fixup_non_cfi(struct flash_bank *bank);
#endif /* NON_CFI_H */

View File

@@ -21,77 +21,45 @@
#include "config.h"
#endif
#include "imp.h"
#include "ocl.h"
#include "flash.h"
#include "embeddedice.h"
#include <target/embeddedice.h>
static int ocl_register_commands(struct command_context_s *cmd_ctx);
static int ocl_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int ocl_erase(struct flash_bank_s *bank, int first, int last);
static int ocl_protect(struct flash_bank_s *bank, int set, int first, int last);
static int ocl_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int ocl_probe(struct flash_bank_s *bank);
static int ocl_erase_check(struct flash_bank_s *bank);
static int ocl_protect_check(struct flash_bank_s *bank);
static int ocl_info(struct flash_bank_s *bank, char *buf, int buf_size);
static int ocl_auto_probe(struct flash_bank_s *bank);
flash_driver_t ocl_flash =
struct ocl_priv
{
.name = "ocl",
.register_commands = ocl_register_commands,
.flash_bank_command = ocl_flash_bank_command,
.erase = ocl_erase,
.protect = ocl_protect,
.write = ocl_write,
.probe = ocl_probe,
.erase_check = ocl_erase_check,
.protect_check = ocl_protect_check,
.info = ocl_info,
.auto_probe = ocl_auto_probe
};
typedef struct ocl_priv_s
{
arm_jtag_t *jtag_info;
struct arm_jtag *jtag_info;
unsigned int buflen;
unsigned int bufalign;
} ocl_priv_t;
};
static int ocl_register_commands(struct command_context_s *cmd_ctx)
static int ocl_erase_check(struct flash_bank *bank)
{
return ERROR_OK;
}
static int ocl_erase_check(struct flash_bank_s *bank)
{
return ERROR_OK;
}
static int ocl_protect_check(struct flash_bank_s *bank)
static int ocl_protect_check(struct flash_bank *bank)
{
return ERROR_OK;
}
/* flash_bank ocl 0 0 0 0 <target#> */
static int ocl_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
FLASH_BANK_COMMAND_HANDLER(ocl_flash_bank_command)
{
int retval;
armv4_5_common_t *armv4_5;
arm7_9_common_t *arm7_9;
ocl_priv_t *ocl;
struct arm7_9_common *arm7_9;
struct ocl_priv *ocl;
if (argc < 6)
if (CMD_ARGC < 6)
{
LOG_WARNING("incomplete flash_bank ocl configuration");
return ERROR_FLASH_BANK_INVALID;
}
if ((retval = arm7_9_get_arch_pointers(bank->target, &armv4_5, &arm7_9)) != ERROR_OK)
return retval;
arm7_9 = target_to_arm7_9(bank->target);
if (!is_arm7_9(arm7_9))
return ERROR_TARGET_INVALID;
ocl = bank->driver_priv = malloc(sizeof(ocl_priv_t));
ocl = bank->driver_priv = malloc(sizeof(struct ocl_priv));
ocl->jtag_info = &arm7_9->jtag_info;
ocl->buflen = 0;
ocl->bufalign = 1;
@@ -99,9 +67,9 @@ static int ocl_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd,
return ERROR_OK;
}
static int ocl_erase(struct flash_bank_s *bank, int first, int last)
static int ocl_erase(struct flash_bank *bank, int first, int last)
{
ocl_priv_t *ocl = bank->driver_priv;
struct ocl_priv *ocl = bank->driver_priv;
int retval;
uint32_t dcc_buffer[3];
@@ -154,14 +122,14 @@ static int ocl_erase(struct flash_bank_s *bank, int first, int last)
return ERROR_OK;
}
static int ocl_protect(struct flash_bank_s *bank, int set, int first, int last)
static int ocl_protect(struct flash_bank *bank, int set, int first, int last)
{
return ERROR_OK;
}
static int ocl_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int ocl_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
ocl_priv_t *ocl = bank->driver_priv;
struct ocl_priv *ocl = bank->driver_priv;
int retval;
uint32_t *dcc_buffer;
uint32_t *dcc_bufptr;
@@ -266,9 +234,9 @@ static int ocl_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset
return ERROR_OK;
}
static int ocl_probe(struct flash_bank_s *bank)
static int ocl_probe(struct flash_bank *bank)
{
ocl_priv_t *ocl = bank->driver_priv;
struct ocl_priv *ocl = bank->driver_priv;
int retval;
uint32_t dcc_buffer[1];
int sectsize;
@@ -321,7 +289,7 @@ static int ocl_probe(struct flash_bank_s *bank)
ocl->buflen = dcc_buffer[0] & 0xffff;
ocl->bufalign = dcc_buffer[0] >> 16;
bank->sectors = realloc(bank->sectors, sizeof(flash_sector_t)*bank->num_sectors);
bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector)*bank->num_sectors);
if (bank->num_sectors == 0)
{
LOG_ERROR("number of sectors shall be non zero value");
@@ -364,17 +332,30 @@ static int ocl_probe(struct flash_bank_s *bank)
return ERROR_OK;
}
static int ocl_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int ocl_info(struct flash_bank *bank, char *buf, int buf_size)
{
return ERROR_OK;
}
static int ocl_auto_probe(struct flash_bank_s *bank)
static int ocl_auto_probe(struct flash_bank *bank)
{
ocl_priv_t *ocl = bank->driver_priv;
struct ocl_priv *ocl = bank->driver_priv;
if (ocl->buflen == 0 || ocl->bufalign == 0)
return ERROR_FLASH_BANK_NOT_PROBED;
return ERROR_OK;
}
struct flash_driver ocl_flash = {
.name = "ocl",
.flash_bank_command = ocl_flash_bank_command,
.erase = ocl_erase,
.protect = ocl_protect,
.write = ocl_write,
.probe = ocl_probe,
.erase_check = ocl_erase_check,
.protect_check = ocl_protect_check,
.info = ocl_info,
.auto_probe = ocl_auto_probe,
};

View File

@@ -27,8 +27,9 @@
#include "config.h"
#endif
#include "imp.h"
#include "pic32mx.h"
#include "mips32.h"
#include <target/mips32.h>
static
@@ -57,72 +58,22 @@ struct pic32mx_devs_s {
{ 0x00, NULL, 0 }
};
static int pic32mx_register_commands(struct command_context_s *cmd_ctx);
static int pic32mx_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int pic32mx_erase(struct flash_bank_s *bank, int first, int last);
static int pic32mx_protect(struct flash_bank_s *bank, int set, int first, int last);
static int pic32mx_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int pic32mx_write_row(struct flash_bank_s *bank, uint32_t address, uint32_t srcaddr);
static int pic32mx_write_word(struct flash_bank_s *bank, uint32_t address, uint32_t word);
static int pic32mx_probe(struct flash_bank_s *bank);
static int pic32mx_auto_probe(struct flash_bank_s *bank);
//static int pic32mx_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int pic32mx_protect_check(struct flash_bank_s *bank);
static int pic32mx_info(struct flash_bank_s *bank, char *buf, int buf_size);
#if 0
int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int pic32mx_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
#endif
static int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
//static int pic32mx_chip_erase(struct flash_bank_s *bank);
flash_driver_t pic32mx_flash =
{
.name = "pic32mx",
.register_commands = pic32mx_register_commands,
.flash_bank_command = pic32mx_flash_bank_command,
.erase = pic32mx_erase,
.protect = pic32mx_protect,
.write = pic32mx_write,
.probe = pic32mx_probe,
.auto_probe = pic32mx_auto_probe,
.erase_check = default_flash_mem_blank_check,
.protect_check = pic32mx_protect_check,
.info = pic32mx_info
};
static int pic32mx_register_commands(struct command_context_s *cmd_ctx)
{
command_t *pic32mx_cmd = register_command(cmd_ctx, NULL, "pic32mx", NULL, COMMAND_ANY, "pic32mx flash specific commands");
#if 0
register_command(cmd_ctx, pic32mx_cmd, "lock", pic32mx_handle_lock_command, COMMAND_EXEC,
"lock device");
register_command(cmd_ctx, pic32mx_cmd, "unlock", pic32mx_handle_unlock_command, COMMAND_EXEC,
"unlock protected device");
#endif
register_command(cmd_ctx, pic32mx_cmd, "chip_erase", pic32mx_handle_chip_erase_command, COMMAND_EXEC,
"erase device");
register_command(cmd_ctx, pic32mx_cmd, "pgm_word", pic32mx_handle_pgm_word_command, COMMAND_EXEC,
"program a word");
return ERROR_OK;
}
static int pic32mx_write_row(struct flash_bank *bank, uint32_t address, uint32_t srcaddr);
static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word);
/* flash bank pic32mx <base> <size> 0 0 <target#>
*/
static int pic32mx_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
FLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command)
{
pic32mx_flash_bank_t *pic32mx_info;
struct pic32mx_flash_bank *pic32mx_info;
if (argc < 6)
if (CMD_ARGC < 6)
{
LOG_WARNING("incomplete flash_bank pic32mx configuration");
return ERROR_FLASH_BANK_INVALID;
}
pic32mx_info = malloc(sizeof(pic32mx_flash_bank_t));
pic32mx_info = malloc(sizeof(struct pic32mx_flash_bank));
bank->driver_priv = pic32mx_info;
pic32mx_info->write_algorithm = NULL;
@@ -131,9 +82,9 @@ static int pic32mx_flash_bank_command(struct command_context_s *cmd_ctx, char *c
return ERROR_OK;
}
static uint32_t pic32mx_get_flash_status(flash_bank_t *bank)
static uint32_t pic32mx_get_flash_status(struct flash_bank *bank)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t status;
target_read_u32(target, PIC32MX_NVMCON, &status);
@@ -141,7 +92,7 @@ static uint32_t pic32mx_get_flash_status(flash_bank_t *bank)
return status;
}
static uint32_t pic32mx_wait_status_busy(flash_bank_t *bank, int timeout)
static uint32_t pic32mx_wait_status_busy(struct flash_bank *bank, int timeout)
{
uint32_t status;
@@ -157,9 +108,9 @@ static uint32_t pic32mx_wait_status_busy(flash_bank_t *bank, int timeout)
return status;
}
static int pic32mx_nvm_exec(struct flash_bank_s *bank, uint32_t op, uint32_t timeout)
static int pic32mx_nvm_exec(struct flash_bank *bank, uint32_t op, uint32_t timeout)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t status;
target_write_u32(target, PIC32MX_NVMCON, NVMCON_NVMWREN | op);
@@ -179,9 +130,9 @@ static int pic32mx_nvm_exec(struct flash_bank_s *bank, uint32_t op, uint32_t tim
return status;
}
static int pic32mx_protect_check(struct flash_bank_s *bank)
static int pic32mx_protect_check(struct flash_bank *bank)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t devcfg0;
int s;
@@ -213,9 +164,9 @@ static int pic32mx_protect_check(struct flash_bank_s *bank)
return ERROR_OK;
}
static int pic32mx_erase(struct flash_bank_s *bank, int first, int last)
static int pic32mx_erase(struct flash_bank *bank, int first, int last)
{
target_t *target = bank->target;
struct target *target = bank->target;
int i;
uint32_t status;
@@ -255,10 +206,10 @@ static int pic32mx_erase(struct flash_bank_s *bank, int first, int last)
return ERROR_OK;
}
static int pic32mx_protect(struct flash_bank_s *bank, int set, int first, int last)
static int pic32mx_protect(struct flash_bank *bank, int set, int first, int last)
{
pic32mx_flash_bank_t *pic32mx_info = NULL;
target_t *target = bank->target;
struct pic32mx_flash_bank *pic32mx_info = NULL;
struct target *target = bank->target;
#if 0
uint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
int i, reg, bit;
@@ -348,16 +299,16 @@ static int pic32mx_protect(struct flash_bank_s *bank, int set, int first, int la
#endif
}
static int pic32mx_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int pic32mx_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t buffer_size = 512;
working_area_t *source;
struct working_area *source;
uint32_t address = bank->base + offset;
int retval = ERROR_OK;
#if 0
pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
armv7m_algorithm_t armv7m_info;
struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
struct armv7m_algorithm armv7m_info;
uint8_t pic32mx_flash_write_code[] = {
/* write: */
@@ -477,9 +428,9 @@ static int pic32mx_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint3
return retval;
}
static int pic32mx_write_word(struct flash_bank_s *bank, uint32_t address, uint32_t word)
static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word)
{
target_t *target = bank->target;
struct target *target = bank->target;
if (bank->base >= PIC32MX_KSEG1_PGM_FLASH)
target_write_u32(target, PIC32MX_NVMADDR, KS1Virt2Phys(address));
@@ -493,9 +444,9 @@ static int pic32mx_write_word(struct flash_bank_s *bank, uint32_t address, uint3
/*
* Write a 128 word (512 byte) row to flash address from RAM srcaddr.
*/
static int pic32mx_write_row(struct flash_bank_s *bank, uint32_t address, uint32_t srcaddr)
static int pic32mx_write_row(struct flash_bank *bank, uint32_t address, uint32_t srcaddr)
{
target_t *target = bank->target;
struct target *target = bank->target;
LOG_DEBUG("addr: 0x%08" PRIx32 " srcaddr: 0x%08" PRIx32 "", address, srcaddr);
@@ -511,7 +462,7 @@ static int pic32mx_write_row(struct flash_bank_s *bank, uint32_t address, uint32
return pic32mx_nvm_exec(bank, NVMCON_OP_ROW_PROG, 100);
}
static int pic32mx_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int pic32mx_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
uint32_t words_remaining = (count / 4);
uint32_t bytes_remaining = (count & 0x00000003);
@@ -589,12 +540,12 @@ static int pic32mx_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t of
return ERROR_OK;
}
static int pic32mx_probe(struct flash_bank_s *bank)
static int pic32mx_probe(struct flash_bank *bank)
{
target_t *target = bank->target;
pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
mips32_common_t *mips32 = target->arch_info;
mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
struct target *target = bank->target;
struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
struct mips32_common *mips32 = target->arch_info;
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
int i;
uint16_t num_pages = 0;
uint32_t device_id;
@@ -657,7 +608,7 @@ static int pic32mx_probe(struct flash_bank_s *bank)
bank->num_sectors = num_pages;
bank->chip_width = 4;
bank->bus_width = 4;
bank->sectors = malloc(sizeof(flash_sector_t) * num_pages);
bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
for (i = 0; i < num_pages; i++)
{
@@ -672,26 +623,26 @@ static int pic32mx_probe(struct flash_bank_s *bank)
return ERROR_OK;
}
static int pic32mx_auto_probe(struct flash_bank_s *bank)
static int pic32mx_auto_probe(struct flash_bank *bank)
{
pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
if (pic32mx_info->probed)
return ERROR_OK;
return pic32mx_probe(bank);
}
#if 0
static int pic32mx_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(pic32mx_handle_part_id_command)
{
return ERROR_OK;
}
#endif
static int pic32mx_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int pic32mx_info(struct flash_bank *bank, char *buf, int buf_size)
{
target_t *target = bank->target;
mips32_common_t *mips32 = target->arch_info;
mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
struct target *target = bank->target;
struct mips32_common *mips32 = target->arch_info;
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
uint32_t device_id;
int printed = 0, i;
@@ -722,24 +673,21 @@ static int pic32mx_info(struct flash_bank_s *bank, char *buf, int buf_size)
}
#if 0
int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(pic32mx_handle_lock_command)
{
flash_bank_t *bank;
target_t *target = NULL;
pic32mx_flash_bank_t *pic32mx_info = NULL;
struct target *target = NULL;
struct pic32mx_flash_bank *pic32mx_info = NULL;
if (argc < 1)
if (CMD_ARGC < 1)
{
command_print(cmd_ctx, "pic32mx lock <bank>");
command_print(CMD_CTX, "pic32mx lock <bank>");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
pic32mx_info = bank->driver_priv;
@@ -753,7 +701,7 @@ int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, ch
if (pic32mx_erase_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "pic32mx failed to erase options");
command_print(CMD_CTX, "pic32mx failed to erase options");
return ERROR_OK;
}
@@ -762,33 +710,30 @@ int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, ch
if (pic32mx_write_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "pic32mx failed to lock device");
command_print(CMD_CTX, "pic32mx failed to lock device");
return ERROR_OK;
}
command_print(cmd_ctx, "pic32mx locked");
command_print(CMD_CTX, "pic32mx locked");
return ERROR_OK;
}
int pic32mx_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(pic32mx_handle_unlock_command)
{
flash_bank_t *bank;
target_t *target = NULL;
pic32mx_flash_bank_t *pic32mx_info = NULL;
struct target *target = NULL;
struct pic32mx_flash_bank *pic32mx_info = NULL;
if (argc < 1)
if (CMD_ARGC < 1)
{
command_print(cmd_ctx, "pic32mx unlock <bank>");
command_print(CMD_CTX, "pic32mx unlock <bank>");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
pic32mx_info = bank->driver_priv;
@@ -802,26 +747,26 @@ int pic32mx_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd,
if (pic32mx_erase_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "pic32mx failed to unlock device");
command_print(CMD_CTX, "pic32mx failed to unlock device");
return ERROR_OK;
}
if (pic32mx_write_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "pic32mx failed to lock device");
command_print(CMD_CTX, "pic32mx failed to lock device");
return ERROR_OK;
}
command_print(cmd_ctx, "pic32mx unlocked");
command_print(CMD_CTX, "pic32mx unlocked");
return ERROR_OK;
}
#endif
#if 0
static int pic32mx_chip_erase(struct flash_bank_s *bank)
static int pic32mx_chip_erase(struct flash_bank *bank)
{
target_t *target = bank->target;
struct target *target = bank->target;
#if 0
uint32_t status;
#endif
@@ -864,24 +809,21 @@ static int pic32mx_chip_erase(struct flash_bank_s *bank)
}
#endif
static int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(pic32mx_handle_chip_erase_command)
{
#if 0
flash_bank_t *bank;
int i;
if (argc != 0)
if (CMD_ARGC != 0)
{
command_print(cmd_ctx, "pic32mx chip_erase");
command_print(CMD_CTX, "pic32mx chip_erase");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
if (pic32mx_chip_erase(bank) == ERROR_OK)
{
@@ -891,41 +833,39 @@ static int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx,
bank->sectors[i].is_erased = 1;
}
command_print(cmd_ctx, "pic32mx chip erase complete");
command_print(CMD_CTX, "pic32mx chip erase complete");
}
else
{
command_print(cmd_ctx, "pic32mx chip erase failed");
command_print(CMD_CTX, "pic32mx chip erase failed");
}
#endif
return ERROR_OK;
}
static int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
{
flash_bank_t *bank;
uint32_t address, value;
int status, res;
if (argc != 3)
if (CMD_ARGC != 3)
{
command_print(cmd_ctx, "pic32mx pgm_word <addr> <value> <bank>");
command_print(CMD_CTX, "pic32mx pgm_word <addr> <value> <bank>");
return ERROR_OK;
}
address = strtoul(args[0], NULL, 0);
value = strtoul(args[1], NULL, 0);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 2, &bank);
if (ERROR_OK != retval)
return retval;
bank = get_flash_bank_by_num(strtoul(args[2], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[2]);
return ERROR_OK;
}
if (address < bank->base || address >= (bank->base + bank->size))
{
command_print(cmd_ctx, "flash address '%s' is out of bounds", args[0]);
command_print(CMD_CTX, "flash address '%s' is out of bounds", CMD_ARGV[0]);
return ERROR_OK;
}
@@ -937,9 +877,47 @@ static int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, ch
res = ERROR_FLASH_OPERATION_FAILED;
if (res == ERROR_OK)
command_print(cmd_ctx, "pic32mx pgm word complete");
command_print(CMD_CTX, "pic32mx pgm word complete");
else
command_print(cmd_ctx, "pic32mx pgm word failed (status = 0x%x)", status);
command_print(CMD_CTX, "pic32mx pgm word failed (status = 0x%x)", status);
return ERROR_OK;
}
static const struct command_registration pic32mx_exec_command_handlers[] = {
{
.name = "chip_erase",
.handler = pic32mx_handle_chip_erase_command,
.mode = COMMAND_EXEC,
.help = "erase device",
},
{
.name = "pgm_word",
.handler = pic32mx_handle_pgm_word_command,
.mode = COMMAND_EXEC,
.help = "program a word",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration pic32mx_command_handlers[] = {
{
.name = "pic32mx",
.mode = COMMAND_ANY,
.help = "pic32mx flash command group",
.chain = pic32mx_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
struct flash_driver pic32mx_flash = {
.name = "pic32mx",
.commands = pic32mx_command_handlers,
.flash_bank_command = pic32mx_flash_bank_command,
.erase = pic32mx_erase,
.protect = pic32mx_protect,
.write = pic32mx_write,
.probe = pic32mx_probe,
.auto_probe = pic32mx_auto_probe,
.erase_check = default_flash_mem_blank_check,
.protect_check = pic32mx_protect_check,
.info = pic32mx_info,
};

View File

@@ -26,15 +26,13 @@
#ifndef PIC32MX_H
#define PIC32MX_H
#include "flash.h"
typedef struct pic32mx_flash_bank_s
struct pic32mx_flash_bank
{
working_area_t *write_algorithm;
struct working_area *write_algorithm;
int devid;
int ppage_size;
int probed;
} pic32mx_flash_bank_t;
};
#define PIC32MX_MANUF_ID 0x029
@@ -104,10 +102,10 @@ typedef struct pic32mx_flash_bank_s
#define NVMKEY1 0xAA996655
#define NVMKEY2 0x556699AA
typedef struct pic32mx_mem_layout_s {
struct pic32mx_mem_layout {
uint32_t sector_start;
uint32_t sector_size;
} pic32mx_mem_layout_t;
};
#endif /* PIC32MX_H */

File diff suppressed because it is too large Load Diff

View File

@@ -20,9 +20,7 @@
#ifndef STELLARIS_FLASH_H
#define STELLARIS_FLASH_H
#include "flash.h"
typedef struct stellaris_flash_bank_s
struct stellaris_flash_bank
{
/* chip id register */
uint32_t did0;
@@ -41,7 +39,6 @@ typedef struct stellaris_flash_bank_s
/* nv memory bits */
uint16_t num_lockbits;
uint32_t lockbits;
/* main clock status */
uint32_t rcc;
@@ -52,25 +49,32 @@ typedef struct stellaris_flash_bank_s
uint32_t mck_freq;
const char *iosc_desc;
const char *mck_desc;
} stellaris_flash_bank_t;
};
/* STELLARIS control registers */
#define SCB_BASE 0x400FE000
#define DID0 0x000
#define DID1 0x004
#define DC0 0x008
#define DC1 0x010
#define DC2 0x014
#define DC3 0x018
#define DC4 0x01C
#define DID0 0x000
#define DID1 0x004
#define DC0 0x008
#define DC1 0x010
#define DC2 0x014
#define DC3 0x018
#define DC4 0x01C
#define RIS 0x050
#define RCC 0x060
#define PLLCFG 0x064
#define RCC2 0x070
#define RIS 0x050
#define RCC 0x060
#define PLLCFG 0x064
#define RCC2 0x070
#define NVMSTAT 0x1a0
/* "legacy" flash memory protection registers (64KB max) */
#define FMPRE 0x130
#define FMPPE 0x134
/* new flash memory protection registers (for more than 64KB) */
#define FMPRE0 0x200 /* PRE1 = PRE0 + 4, etc */
#define FMPPE0 0x400 /* PPE1 = PPE0 + 4, etc */
#define USECRL 0x140
#define FLASH_CONTROL_BASE 0x400FD000
@@ -96,4 +100,8 @@ typedef struct stellaris_flash_bank_s
/* STELLARIS constants */
/* values to write in FMA to commit write-"once" values */
#define FLASH_FMA_PRE(x) (2 * (x)) /* for FMPPREx */
#define FLASH_FMA_PPE(x) (2 * (x) + 1) /* for FMPPPEx */
#endif /* STELLARIS_H */

View File

@@ -24,74 +24,28 @@
#include "config.h"
#endif
#include "imp.h"
#include "stm32x.h"
#include "armv7m.h"
#include "binarybuffer.h"
#include <helper/binarybuffer.h>
#include <target/algorithm.h>
#include <target/armv7m.h>
static int stm32x_register_commands(struct command_context_s *cmd_ctx);
static int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int stm32x_erase(struct flash_bank_s *bank, int first, int last);
static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int last);
static int stm32x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int stm32x_probe(struct flash_bank_s *bank);
static int stm32x_auto_probe(struct flash_bank_s *bank);
//static int stm32x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int stm32x_protect_check(struct flash_bank_s *bank);
static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size);
static int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int stm32x_mass_erase(struct flash_bank_s *bank);
flash_driver_t stm32x_flash =
{
.name = "stm32x",
.register_commands = stm32x_register_commands,
.flash_bank_command = stm32x_flash_bank_command,
.erase = stm32x_erase,
.protect = stm32x_protect,
.write = stm32x_write,
.probe = stm32x_probe,
.auto_probe = stm32x_auto_probe,
.erase_check = default_flash_mem_blank_check,
.protect_check = stm32x_protect_check,
.info = stm32x_info
};
static int stm32x_register_commands(struct command_context_s *cmd_ctx)
{
command_t *stm32x_cmd = register_command(cmd_ctx, NULL, "stm32x", NULL, COMMAND_ANY, "stm32x flash specific commands");
register_command(cmd_ctx, stm32x_cmd, "lock", stm32x_handle_lock_command, COMMAND_EXEC,
"lock device");
register_command(cmd_ctx, stm32x_cmd, "unlock", stm32x_handle_unlock_command, COMMAND_EXEC,
"unlock protected device");
register_command(cmd_ctx, stm32x_cmd, "mass_erase", stm32x_handle_mass_erase_command, COMMAND_EXEC,
"mass erase device");
register_command(cmd_ctx, stm32x_cmd, "options_read", stm32x_handle_options_read_command, COMMAND_EXEC,
"read device option bytes");
register_command(cmd_ctx, stm32x_cmd, "options_write", stm32x_handle_options_write_command, COMMAND_EXEC,
"write device option bytes");
return ERROR_OK;
}
static int stm32x_mass_erase(struct flash_bank *bank);
/* flash bank stm32x <base> <size> 0 0 <target#>
*/
static int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)
{
stm32x_flash_bank_t *stm32x_info;
struct stm32x_flash_bank *stm32x_info;
if (argc < 6)
if (CMD_ARGC < 6)
{
LOG_WARNING("incomplete flash_bank stm32x configuration");
return ERROR_FLASH_BANK_INVALID;
}
stm32x_info = malloc(sizeof(stm32x_flash_bank_t));
stm32x_info = malloc(sizeof(struct stm32x_flash_bank));
bank->driver_priv = stm32x_info;
stm32x_info->write_algorithm = NULL;
@@ -100,9 +54,9 @@ static int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cm
return ERROR_OK;
}
static uint32_t stm32x_get_flash_status(flash_bank_t *bank)
static uint32_t stm32x_get_flash_status(struct flash_bank *bank)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t status;
target_read_u32(target, STM32_FLASH_SR, &status);
@@ -110,9 +64,9 @@ static uint32_t stm32x_get_flash_status(flash_bank_t *bank)
return status;
}
static uint32_t stm32x_wait_status_busy(flash_bank_t *bank, int timeout)
static uint32_t stm32x_wait_status_busy(struct flash_bank *bank, int timeout)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t status;
/* wait for busy to clear */
@@ -129,11 +83,11 @@ static uint32_t stm32x_wait_status_busy(flash_bank_t *bank, int timeout)
return status;
}
static int stm32x_read_options(struct flash_bank_s *bank)
static int stm32x_read_options(struct flash_bank *bank)
{
uint32_t optiondata;
stm32x_flash_bank_t *stm32x_info = NULL;
target_t *target = bank->target;
struct stm32x_flash_bank *stm32x_info = NULL;
struct target *target = bank->target;
stm32x_info = bank->driver_priv;
@@ -157,10 +111,10 @@ static int stm32x_read_options(struct flash_bank_s *bank)
return ERROR_OK;
}
static int stm32x_erase_options(struct flash_bank_s *bank)
static int stm32x_erase_options(struct flash_bank *bank)
{
stm32x_flash_bank_t *stm32x_info = NULL;
target_t *target = bank->target;
struct stm32x_flash_bank *stm32x_info = NULL;
struct target *target = bank->target;
uint32_t status;
stm32x_info = bank->driver_priv;
@@ -194,10 +148,10 @@ static int stm32x_erase_options(struct flash_bank_s *bank)
return ERROR_OK;
}
static int stm32x_write_options(struct flash_bank_s *bank)
static int stm32x_write_options(struct flash_bank *bank)
{
stm32x_flash_bank_t *stm32x_info = NULL;
target_t *target = bank->target;
struct stm32x_flash_bank *stm32x_info = NULL;
struct target *target = bank->target;
uint32_t status;
stm32x_info = bank->driver_priv;
@@ -278,10 +232,10 @@ static int stm32x_write_options(struct flash_bank_s *bank)
return ERROR_OK;
}
static int stm32x_protect_check(struct flash_bank_s *bank)
static int stm32x_protect_check(struct flash_bank *bank)
{
target_t *target = bank->target;
stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
struct target *target = bank->target;
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
uint32_t protection;
int i, s;
@@ -350,9 +304,9 @@ static int stm32x_protect_check(struct flash_bank_s *bank)
return ERROR_OK;
}
static int stm32x_erase(struct flash_bank_s *bank, int first, int last)
static int stm32x_erase(struct flash_bank *bank, int first, int last)
{
target_t *target = bank->target;
struct target *target = bank->target;
int i;
uint32_t status;
@@ -391,10 +345,10 @@ static int stm32x_erase(struct flash_bank_s *bank, int first, int last)
return ERROR_OK;
}
static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int last)
static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
{
stm32x_flash_bank_t *stm32x_info = NULL;
target_t *target = bank->target;
struct stm32x_flash_bank *stm32x_info = NULL;
struct target *target = bank->target;
uint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
int i, reg, bit;
int status;
@@ -478,15 +432,15 @@ static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int las
return stm32x_write_options(bank);
}
static int stm32x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
target_t *target = bank->target;
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t buffer_size = 16384;
working_area_t *source;
struct working_area *source;
uint32_t address = bank->base + offset;
reg_param_t reg_params[4];
armv7m_algorithm_t armv7m_info;
struct reg_param reg_params[4];
struct armv7m_algorithm armv7m_info;
int retval = ERROR_OK;
uint8_t stm32x_flash_write_code[] = {
@@ -597,9 +551,9 @@ static int stm32x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32
return retval;
}
static int stm32x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int stm32x_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t words_remaining = (count / 2);
uint32_t bytes_remaining = (count & 0x00000001);
uint32_t address = bank->base + offset;
@@ -702,10 +656,10 @@ static int stm32x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t off
return ERROR_OK;
}
static int stm32x_probe(struct flash_bank_s *bank)
static int stm32x_probe(struct flash_bank *bank)
{
target_t *target = bank->target;
stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
struct target *target = bank->target;
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
int i;
uint16_t num_pages;
uint32_t device_id;
@@ -804,7 +758,7 @@ static int stm32x_probe(struct flash_bank_s *bank)
bank->base = 0x08000000;
bank->size = (num_pages * page_size);
bank->num_sectors = num_pages;
bank->sectors = malloc(sizeof(flash_sector_t) * num_pages);
bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
for (i = 0; i < num_pages; i++)
{
@@ -819,24 +773,24 @@ static int stm32x_probe(struct flash_bank_s *bank)
return ERROR_OK;
}
static int stm32x_auto_probe(struct flash_bank_s *bank)
static int stm32x_auto_probe(struct flash_bank *bank)
{
stm32x_flash_bank_t *stm32x_info = bank->driver_priv;
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
if (stm32x_info->probed)
return ERROR_OK;
return stm32x_probe(bank);
}
#if 0
static int stm32x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(stm32x_handle_part_id_command)
{
return ERROR_OK;
}
#endif
static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t device_id;
int printed;
@@ -940,24 +894,21 @@ static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size)
return ERROR_OK;
}
static int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(stm32x_handle_lock_command)
{
flash_bank_t *bank;
target_t *target = NULL;
stm32x_flash_bank_t *stm32x_info = NULL;
struct target *target = NULL;
struct stm32x_flash_bank *stm32x_info = NULL;
if (argc < 1)
if (CMD_ARGC < 1)
{
command_print(cmd_ctx, "stm32x lock <bank>");
command_print(CMD_CTX, "stm32x lock <bank>");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
stm32x_info = bank->driver_priv;
@@ -971,7 +922,7 @@ static int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *c
if (stm32x_erase_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "stm32x failed to erase options");
command_print(CMD_CTX, "stm32x failed to erase options");
return ERROR_OK;
}
@@ -980,33 +931,30 @@ static int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *c
if (stm32x_write_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "stm32x failed to lock device");
command_print(CMD_CTX, "stm32x failed to lock device");
return ERROR_OK;
}
command_print(cmd_ctx, "stm32x locked");
command_print(CMD_CTX, "stm32x locked");
return ERROR_OK;
}
static int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(stm32x_handle_unlock_command)
{
flash_bank_t *bank;
target_t *target = NULL;
stm32x_flash_bank_t *stm32x_info = NULL;
struct target *target = NULL;
struct stm32x_flash_bank *stm32x_info = NULL;
if (argc < 1)
if (CMD_ARGC < 1)
{
command_print(cmd_ctx, "stm32x unlock <bank>");
command_print(CMD_CTX, "stm32x unlock <bank>");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
stm32x_info = bank->driver_priv;
@@ -1020,40 +968,39 @@ static int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char
if (stm32x_erase_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "stm32x failed to unlock device");
command_print(CMD_CTX, "stm32x failed to unlock device");
return ERROR_OK;
}
if (stm32x_write_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "stm32x failed to lock device");
command_print(CMD_CTX, "stm32x failed to lock device");
return ERROR_OK;
}
command_print(cmd_ctx, "stm32x unlocked");
command_print(CMD_CTX, "stm32x unlocked.\n"
"INFO: a reset or power cycle is required "
"for the new settings to take effect.");
return ERROR_OK;
}
static int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(stm32x_handle_options_read_command)
{
flash_bank_t *bank;
uint32_t optionbyte;
target_t *target = NULL;
stm32x_flash_bank_t *stm32x_info = NULL;
struct target *target = NULL;
struct stm32x_flash_bank *stm32x_info = NULL;
if (argc < 1)
if (CMD_ARGC < 1)
{
command_print(cmd_ctx, "stm32x options_read <bank>");
command_print(CMD_CTX, "stm32x options_read <bank>");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
stm32x_info = bank->driver_priv;
@@ -1066,53 +1013,50 @@ static int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx,
}
target_read_u32(target, STM32_FLASH_OBR, &optionbyte);
command_print(cmd_ctx, "Option Byte: 0x%" PRIx32 "", optionbyte);
command_print(CMD_CTX, "Option Byte: 0x%" PRIx32 "", optionbyte);
if (buf_get_u32((uint8_t*)&optionbyte, OPT_ERROR, 1))
command_print(cmd_ctx, "Option Byte Complement Error");
command_print(CMD_CTX, "Option Byte Complement Error");
if (buf_get_u32((uint8_t*)&optionbyte, OPT_READOUT, 1))
command_print(cmd_ctx, "Readout Protection On");
command_print(CMD_CTX, "Readout Protection On");
else
command_print(cmd_ctx, "Readout Protection Off");
command_print(CMD_CTX, "Readout Protection Off");
if (buf_get_u32((uint8_t*)&optionbyte, OPT_RDWDGSW, 1))
command_print(cmd_ctx, "Software Watchdog");
command_print(CMD_CTX, "Software Watchdog");
else
command_print(cmd_ctx, "Hardware Watchdog");
command_print(CMD_CTX, "Hardware Watchdog");
if (buf_get_u32((uint8_t*)&optionbyte, OPT_RDRSTSTOP, 1))
command_print(cmd_ctx, "Stop: No reset generated");
command_print(CMD_CTX, "Stop: No reset generated");
else
command_print(cmd_ctx, "Stop: Reset generated");
command_print(CMD_CTX, "Stop: Reset generated");
if (buf_get_u32((uint8_t*)&optionbyte, OPT_RDRSTSTDBY, 1))
command_print(cmd_ctx, "Standby: No reset generated");
command_print(CMD_CTX, "Standby: No reset generated");
else
command_print(cmd_ctx, "Standby: Reset generated");
command_print(CMD_CTX, "Standby: Reset generated");
return ERROR_OK;
}
static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(stm32x_handle_options_write_command)
{
flash_bank_t *bank;
target_t *target = NULL;
stm32x_flash_bank_t *stm32x_info = NULL;
struct target *target = NULL;
struct stm32x_flash_bank *stm32x_info = NULL;
uint16_t optionbyte = 0xF8;
if (argc < 4)
if (CMD_ARGC < 4)
{
command_print(cmd_ctx, "stm32x options_write <bank> <SWWDG | HWWDG> <RSTSTNDBY | NORSTSTNDBY> <RSTSTOP | NORSTSTOP>");
command_print(CMD_CTX, "stm32x options_write <bank> <SWWDG | HWWDG> <RSTSTNDBY | NORSTSTNDBY> <RSTSTOP | NORSTSTOP>");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
stm32x_info = bank->driver_priv;
@@ -1124,36 +1068,43 @@ static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx
return ERROR_TARGET_NOT_HALTED;
}
if (strcmp(args[1], "SWWDG") == 0)
/* REVISIT: ignores some options which we will display...
* and doesn't insist on the specified syntax.
*/
/* OPT_RDWDGSW */
if (strcmp(CMD_ARGV[1], "SWWDG") == 0)
{
optionbyte |= (1 << 0);
}
else
else /* REVISIT must be "HWWDG" then ... */
{
optionbyte &= ~(1 << 0);
}
if (strcmp(args[2], "NORSTSTNDBY") == 0)
/* OPT_RDRSTSTDBY */
if (strcmp(CMD_ARGV[2], "NORSTSTNDBY") == 0)
{
optionbyte |= (1 << 1);
}
else
else /* REVISIT must be "RSTSTNDBY" then ... */
{
optionbyte &= ~(1 << 1);
}
if (strcmp(args[3], "NORSTSTOP") == 0)
/* OPT_RDRSTSTOP */
if (strcmp(CMD_ARGV[3], "NORSTSTOP") == 0)
{
optionbyte |= (1 << 2);
}
else
else /* REVISIT must be "RSTSTOP" then ... */
{
optionbyte &= ~(1 << 2);
}
if (stm32x_erase_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "stm32x failed to erase options");
command_print(CMD_CTX, "stm32x failed to erase options");
return ERROR_OK;
}
@@ -1161,18 +1112,20 @@ static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx
if (stm32x_write_options(bank) != ERROR_OK)
{
command_print(cmd_ctx, "stm32x failed to write options");
command_print(CMD_CTX, "stm32x failed to write options");
return ERROR_OK;
}
command_print(cmd_ctx, "stm32x write options complete");
command_print(CMD_CTX, "stm32x write options complete.\n"
"INFO: a reset or power cycle is required "
"for the new settings to take effect.");
return ERROR_OK;
}
static int stm32x_mass_erase(struct flash_bank_s *bank)
static int stm32x_mass_erase(struct flash_bank *bank)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t status;
if (target->state != TARGET_HALTED)
@@ -1208,23 +1161,20 @@ static int stm32x_mass_erase(struct flash_bank_s *bank)
return ERROR_OK;
}
static int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(stm32x_handle_mass_erase_command)
{
flash_bank_t *bank;
int i;
if (argc < 1)
if (CMD_ARGC < 1)
{
command_print(cmd_ctx, "stm32x mass_erase <bank>");
command_print(CMD_CTX, "stm32x mass_erase <bank>");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
if (stm32x_mass_erase(bank) == ERROR_OK)
{
@@ -1234,12 +1184,76 @@ static int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, c
bank->sectors[i].is_erased = 1;
}
command_print(cmd_ctx, "stm32x mass erase complete");
command_print(CMD_CTX, "stm32x mass erase complete");
}
else
{
command_print(cmd_ctx, "stm32x mass erase failed");
command_print(CMD_CTX, "stm32x mass erase failed");
}
return ERROR_OK;
}
static const struct command_registration stm32x_exec_command_handlers[] = {
{
.name = "lock",
.handler = stm32x_handle_lock_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "Lock entire flash device.",
},
{
.name = "unlock",
.handler = stm32x_handle_unlock_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "Unlock entire protected flash device.",
},
{
.name = "mass_erase",
.handler = stm32x_handle_mass_erase_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "Erase entire flash device.",
},
{
.name = "options_read",
.handler = stm32x_handle_options_read_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "Read and display device option byte.",
},
{
.name = "options_write",
.handler = stm32x_handle_options_write_command,
.mode = COMMAND_EXEC,
.usage = "bank_id ('SWWDG'|'HWWDG') "
"('RSTSTNDBY'|'NORSTSTNDBY') "
"('RSTSTOP'|'NORSTSTOP')",
.help = "Replace bits in device option byte.",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration stm32x_command_handlers[] = {
{
.name = "stm32x",
.mode = COMMAND_ANY,
.help = "stm32x flash command group",
.chain = stm32x_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
struct flash_driver stm32x_flash = {
.name = "stm32x",
.commands = stm32x_command_handlers,
.flash_bank_command = stm32x_flash_bank_command,
.erase = stm32x_erase,
.protect = stm32x_protect,
.write = stm32x_write,
.probe = stm32x_probe,
.auto_probe = stm32x_auto_probe,
.erase_check = default_flash_mem_blank_check,
.protect_check = stm32x_protect_check,
.info = stm32x_info,
};

View File

@@ -23,22 +23,20 @@
#ifndef STM32X_H
#define STM32X_H
#include "flash.h"
typedef struct stm32x_options_s
struct stm32x_options
{
uint16_t RDP;
uint16_t user_options;
uint16_t protection[4];
} stm32x_options_t;
};
typedef struct stm32x_flash_bank_s
struct stm32x_flash_bank
{
stm32x_options_t option_bytes;
working_area_t *write_algorithm;
struct stm32x_options option_bytes;
struct working_area *write_algorithm;
int ppage_size;
int probed;
} stm32x_flash_bank_t;
};
/* stm32x register locations */
@@ -93,9 +91,9 @@ typedef struct stm32x_flash_bank_s
#define KEY1 0x45670123
#define KEY2 0xCDEF89AB
typedef struct stm32x_mem_layout_s {
struct stm32x_mem_layout {
uint32_t sector_start;
uint32_t sector_size;
} stm32x_mem_layout_t;
};
#endif /* STM32X_H */

View File

@@ -24,12 +24,14 @@
#include "config.h"
#endif
#include "imp.h"
#include "str7x.h"
#include "armv4_5.h"
#include "binarybuffer.h"
#include <target/arm.h>
#include <helper/binarybuffer.h>
#include <target/algorithm.h>
str7x_mem_layout_t mem_layout_str7bank0[] = {
struct str7x_mem_layout mem_layout_str7bank0[] = {
{0x00000000, 0x02000, 0x01},
{0x00002000, 0x02000, 0x02},
{0x00004000, 0x02000, 0x04},
@@ -40,57 +42,20 @@ str7x_mem_layout_t mem_layout_str7bank0[] = {
{0x00030000, 0x10000, 0x80}
};
str7x_mem_layout_t mem_layout_str7bank1[] = {
struct str7x_mem_layout mem_layout_str7bank1[] = {
{0x00000000, 0x02000, 0x10000},
{0x00002000, 0x02000, 0x20000}
};
static int str7x_register_commands(struct command_context_s *cmd_ctx);
static int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
static int str7x_erase(struct flash_bank_s *bank, int first, int last);
static int str7x_protect(struct flash_bank_s *bank, int set, int first, int last);
static int str7x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
static int str7x_probe(struct flash_bank_s *bank);
//static int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int str7x_protect_check(struct flash_bank_s *bank);
static int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size);
static int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
flash_driver_t str7x_flash =
static int str7x_get_flash_adr(struct flash_bank *bank, uint32_t reg)
{
.name = "str7x",
.register_commands = str7x_register_commands,
.flash_bank_command = str7x_flash_bank_command,
.erase = str7x_erase,
.protect = str7x_protect,
.write = str7x_write,
.probe = str7x_probe,
.auto_probe = str7x_probe,
.erase_check = default_flash_blank_check,
.protect_check = str7x_protect_check,
.info = str7x_info
};
static int str7x_register_commands(struct command_context_s *cmd_ctx)
{
command_t *str7x_cmd = register_command(cmd_ctx, NULL, "str7x", NULL, COMMAND_ANY, NULL);
register_command(cmd_ctx, str7x_cmd, "disable_jtag", str7x_handle_disable_jtag_command, COMMAND_EXEC,
"disable jtag access");
return ERROR_OK;
}
static int str7x_get_flash_adr(struct flash_bank_s *bank, uint32_t reg)
{
str7x_flash_bank_t *str7x_info = bank->driver_priv;
struct str7x_flash_bank *str7x_info = bank->driver_priv;
return (str7x_info->register_base | reg);
}
static int str7x_build_block_list(struct flash_bank_s *bank)
static int str7x_build_block_list(struct flash_bank *bank)
{
str7x_flash_bank_t *str7x_info = bank->driver_priv;
struct str7x_flash_bank *str7x_info = bank->driver_priv;
int i;
int num_sectors;
@@ -118,7 +83,7 @@ static int str7x_build_block_list(struct flash_bank_s *bank)
num_sectors = b0_sectors + b1_sectors;
bank->num_sectors = num_sectors;
bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
str7x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
num_sectors = 0;
@@ -128,7 +93,10 @@ static int str7x_build_block_list(struct flash_bank_s *bank)
bank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start;
bank->sectors[num_sectors].size = mem_layout_str7bank0[i].sector_size;
bank->sectors[num_sectors].is_erased = -1;
bank->sectors[num_sectors].is_protected = 1;
/* the reset_init handler marks all the sectors unprotected,
* matching hardware after reset; keep the driver in sync
*/
bank->sectors[num_sectors].is_protected = 0;
str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit;
}
@@ -137,7 +105,10 @@ static int str7x_build_block_list(struct flash_bank_s *bank)
bank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start;
bank->sectors[num_sectors].size = mem_layout_str7bank1[i].sector_size;
bank->sectors[num_sectors].is_erased = -1;
bank->sectors[num_sectors].is_protected = 1;
/* the reset_init handler marks all the sectors unprotected,
* matching hardware after reset; keep the driver in sync
*/
bank->sectors[num_sectors].is_protected = 0;
str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit;
}
@@ -146,40 +117,40 @@ static int str7x_build_block_list(struct flash_bank_s *bank)
/* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
*/
static int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
FLASH_BANK_COMMAND_HANDLER(str7x_flash_bank_command)
{
str7x_flash_bank_t *str7x_info;
struct str7x_flash_bank *str7x_info;
if (argc < 7)
if (CMD_ARGC < 7)
{
LOG_WARNING("incomplete flash_bank str7x configuration");
return ERROR_FLASH_BANK_INVALID;
}
str7x_info = malloc(sizeof(str7x_flash_bank_t));
str7x_info = malloc(sizeof(struct str7x_flash_bank));
bank->driver_priv = str7x_info;
/* set default bits for str71x flash */
str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0);
str7x_info->disable_bit = (1 << 1);
if (strcmp(args[6], "STR71x") == 0)
if (strcmp(CMD_ARGV[6], "STR71x") == 0)
{
str7x_info->register_base = 0x40100000;
}
else if (strcmp(args[6], "STR73x") == 0)
else if (strcmp(CMD_ARGV[6], "STR73x") == 0)
{
str7x_info->register_base = 0x80100000;
str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA0);
}
else if (strcmp(args[6], "STR75x") == 0)
else if (strcmp(CMD_ARGV[6], "STR75x") == 0)
{
str7x_info->register_base = 0x20100000;
str7x_info->disable_bit = (1 << 0);
}
else
{
LOG_ERROR("unknown STR7x variant: '%s'", args[6]);
LOG_ERROR("unknown STR7x variant: '%s'", CMD_ARGV[6]);
free(str7x_info);
return ERROR_FLASH_BANK_INVALID;
}
@@ -191,9 +162,9 @@ static int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd
return ERROR_OK;
}
static uint32_t str7x_status(struct flash_bank_s *bank)
static uint32_t str7x_status(struct flash_bank *bank)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t retval;
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
@@ -201,9 +172,9 @@ static uint32_t str7x_status(struct flash_bank_s *bank)
return retval;
}
static uint32_t str7x_result(struct flash_bank_s *bank)
static uint32_t str7x_result(struct flash_bank *bank)
{
target_t *target = bank->target;
struct target *target = bank->target;
uint32_t retval;
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
@@ -211,10 +182,10 @@ static uint32_t str7x_result(struct flash_bank_s *bank)
return retval;
}
static int str7x_protect_check(struct flash_bank_s *bank)
static int str7x_protect_check(struct flash_bank *bank)
{
str7x_flash_bank_t *str7x_info = bank->driver_priv;
target_t *target = bank->target;
struct str7x_flash_bank *str7x_info = bank->driver_priv;
struct target *target = bank->target;
int i;
uint32_t retval;
@@ -238,10 +209,10 @@ static int str7x_protect_check(struct flash_bank_s *bank)
return ERROR_OK;
}
static int str7x_erase(struct flash_bank_s *bank, int first, int last)
static int str7x_erase(struct flash_bank *bank, int first, int last)
{
str7x_flash_bank_t *str7x_info = bank->driver_priv;
target_t *target = bank->target;
struct str7x_flash_bank *str7x_info = bank->driver_priv;
struct target *target = bank->target;
int i;
uint32_t cmd;
@@ -291,10 +262,10 @@ static int str7x_erase(struct flash_bank_s *bank, int first, int last)
return ERROR_OK;
}
static int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
static int str7x_protect(struct flash_bank *bank, int set, int first, int last)
{
str7x_flash_bank_t *str7x_info = bank->driver_priv;
target_t *target = bank->target;
struct str7x_flash_bank *str7x_info = bank->driver_priv;
struct target *target = bank->target;
int i;
uint32_t cmd;
uint32_t retval;
@@ -345,15 +316,15 @@ static int str7x_protect(struct flash_bank_s *bank, int set, int first, int last
return ERROR_OK;
}
static int str7x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int str7x_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
str7x_flash_bank_t *str7x_info = bank->driver_priv;
target_t *target = bank->target;
struct str7x_flash_bank *str7x_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t buffer_size = 8192;
working_area_t *source;
struct working_area *source;
uint32_t address = bank->base + offset;
reg_param_t reg_params[6];
armv4_5_algorithm_t armv4_5_info;
struct reg_param reg_params[6];
struct arm_algorithm armv4_5_info;
int retval = ERROR_OK;
uint32_t str7x_flash_write_code[] = {
@@ -406,9 +377,9 @@ static int str7x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_
}
}
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;
armv4_5_info.common_magic = ARM_COMMON_MAGIC;
armv4_5_info.core_mode = ARM_MODE_SVC;
armv4_5_info.core_state = ARM_STATE_ARM;
init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
@@ -460,10 +431,10 @@ static int str7x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_
return retval;
}
static int str7x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
static int str7x_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
target_t *target = bank->target;
str7x_flash_bank_t *str7x_info = bank->driver_priv;
struct target *target = bank->target;
struct str7x_flash_bank *str7x_info = bank->driver_priv;
uint32_t dwords_remaining = (count / 8);
uint32_t bytes_remaining = (count & 0x00000007);
uint32_t address = bank->base + offset;
@@ -620,47 +591,49 @@ static int str7x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offs
return ERROR_OK;
}
static int str7x_probe(struct flash_bank_s *bank)
static int str7x_probe(struct flash_bank *bank)
{
return ERROR_OK;
}
#if 0
static int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(str7x_handle_part_id_command)
{
return ERROR_OK;
}
#endif
static int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
static int str7x_info(struct flash_bank *bank, char *buf, int buf_size)
{
snprintf(buf, buf_size, "str7x flash driver info");
/* STR7x flash doesn't support sector protection interrogation.
* FLASH_NVWPAR acts as a write only register; its read value
* doesn't reflect the actual protection state of the sectors.
*/
LOG_WARNING("STR7x flash lock information might not be correct "
"due to hardware limitations.");
return ERROR_OK;
}
static int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
COMMAND_HANDLER(str7x_handle_disable_jtag_command)
{
flash_bank_t *bank;
target_t *target = NULL;
str7x_flash_bank_t *str7x_info = NULL;
struct target *target = NULL;
struct str7x_flash_bank *str7x_info = NULL;
uint32_t flash_cmd;
uint32_t retval;
uint16_t ProtectionLevel = 0;
uint16_t ProtectionRegs;
if (argc < 1)
if (CMD_ARGC < 1)
{
command_print(cmd_ctx, "str7x disable_jtag <bank>");
command_print(CMD_CTX, "str7x disable_jtag <bank>");
return ERROR_OK;
}
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "str7x disable_jtag <bank> ok");
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
str7x_info = bank->driver_priv;
@@ -673,15 +646,16 @@ static int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx,
}
/* first we get protection status */
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &retval);
uint32_t reg;
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &reg);
if (!(retval & str7x_info->disable_bit))
if (!(reg & str7x_info->disable_bit))
{
ProtectionLevel = 1;
}
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &retval);
ProtectionRegs = ~(retval >> 16);
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &reg);
ProtectionRegs = ~(reg >> 16);
while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
{
@@ -710,3 +684,36 @@ static int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx,
return ERROR_OK;
}
static const struct command_registration str7x_exec_command_handlers[] = {
{
.name = "disable_jtag",
.handler = str7x_handle_disable_jtag_command,
.mode = COMMAND_EXEC,
.help = "disable jtag access",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration str7x_command_handlers[] = {
{
.name = "str7x",
.mode = COMMAND_ANY,
.help = "str7x flash command group",
.chain = str7x_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
struct flash_driver str7x_flash = {
.name = "str7x",
.commands = str7x_command_handlers,
.flash_bank_command = str7x_flash_bank_command,
.erase = str7x_erase,
.protect = str7x_protect,
.write = str7x_write,
.probe = str7x_probe,
.auto_probe = str7x_probe,
.erase_check = default_flash_blank_check,
.protect_check = str7x_protect_check,
.info = str7x_info,
};

View File

@@ -23,16 +23,14 @@
#ifndef STR7X_H
#define STR7X_H
#include "flash.h"
typedef struct str7x_flash_bank_s
struct str7x_flash_bank
{
uint32_t *sector_bits;
uint32_t disable_bit;
uint32_t busy_bits;
uint32_t register_base;
working_area_t *write_algorithm;
} str7x_flash_bank_t;
struct working_area *write_algorithm;
};
enum str7x_status_codes
{
@@ -101,10 +99,10 @@ enum str7x_status_codes
#define FLASH_ERER 0x00000002
#define FLASH_ERR 0x00000001
typedef struct str7x_mem_layout_s {
struct str7x_mem_layout {
uint32_t sector_start;
uint32_t sector_size;
uint32_t sector_bit;
} str7x_mem_layout_t;
};
#endif /* STR7X_H */

Some files were not shown because too many files have changed in this diff Show More