+@node NAND Flash Commands
+@chapter NAND Flash Commands
+@cindex NAND
+
+Compared to NOR or SPI flash, NAND devices are inexpensive
+and high density. Today's NAND chips, and multi-chip modules,
+commonly hold multiple GigaBytes of data.
+
+NAND chips consist of a number of ``erase blocks'' of a given
+size (such as 128 KBytes), each of which is divided into a
+number of pages (of perhaps 512 or 2048 bytes each). Each
+page of a NAND flash has an ``out of band'' (OOB) area to hold
+Error Correcting Code (ECC) and other metadata, usually 16 bytes
+of OOB for every 512 bytes of page data.
+
+One key characteristic of NAND flash is that its error rate
+is higher than that of NOR flash. In normal operation, that
+ECC is used to correct and detect errors. However, NAND
+blocks can also wear out and become unusable; those blocks
+are then marked "bad". NAND chips are even shipped from the
+manufacturer with a few bad blocks. The highest density chips
+use a technology (MLC) that wears out more quickly, so ECC
+support is increasingly important as a way to detect blocks
+that have begun to fail, and help to preserve data integrity
+with techniques such as wear leveling.
+
+Software is used to manage the ECC. Some controllers don't
+support ECC directly; in those cases, software ECC is used.
+Other controllers speed up the ECC calculations with hardware.
+Single-bit error correction hardware is routine. Controllers
+geared for newer MLC chips may correct 4 or more errors for
+every 512 bytes of data.
+
+You will need to make sure that any data you write using
+OpenOCD includes the apppropriate kind of ECC. For example,
+that may mean passing the @code{oob_softecc} flag when
+writing NAND data, or ensuring that the correct hardware
+ECC mode is used.
+
+The basic steps for using NAND devices include:
+@enumerate
+@item Declare via the command @command{nand device}
+@* Do this in a board-specific configuration file,
+passing parameters as needed by the controller.
+@item Configure each device using @command{nand probe}.
+@* Do this only after the associated target is set up,
+such as in its reset-init script or in procures defined
+to access that device.
+@item Operate on the flash via @command{nand subcommand}
+@* Often commands to manipulate the flash are typed by a human, or run
+via a script in some automated way. Common task include writing a
+boot loader, operating system, or other data needed to initialize or
+de-brick a board.
+@end enumerate
+
+@b{NOTE:} At the time this text was written, the largest NAND
+flash fully supported by OpenOCD is 2 GiBytes (16 GiBits).
+This is because the variables used to hold offsets and lengths
+are only 32 bits wide.
+(Larger chips may work in some cases, unless an offset or length
+is larger than 0xffffffff, the largest 32-bit unsigned integer.)
+Some larger devices will work, since they are actually multi-chip
+modules with two smaller chips and individual chipselect lines.
+
+@section NAND Configuration Commands
+@cindex NAND configuration
+
+NAND chips must be declared in configuration scripts,
+plus some additional configuration that's done after
+OpenOCD has initialized.
+
+@deffn {Config Command} {nand device} controller target [configparams...]
+Declares a NAND device, which can be read and written to
+after it has been configured through @command{nand probe}.
+In OpenOCD, devices are single chips; this is unlike some
+operating systems, which may manage multiple chips as if
+they were a single (larger) device.
+In some cases, configuring a device will activate extra
+commands; see the controller-specific documentation.
+
+@b{NOTE:} This command is not available after OpenOCD
+initialization has completed. Use it in board specific
+configuration files, not interactively.
+
+@itemize @bullet
+@item @var{controller} ... identifies a the controller driver
+associated with the NAND device being declared.
+@xref{NAND Driver List}.
+@item @var{target} ... names the target used when issuing
+commands to the NAND controller.
+@comment Actually, it's currently a controller-specific parameter...
+@item @var{configparams} ... controllers may support, or require,
+additional parameters. See the controller-specific documentation
+for more information.
+@end itemize
+@end deffn
+
+@deffn Command {nand list}
+Prints a one-line summary of each device declared
+using @command{nand device}, numbered from zero.
+Note that un-probed devices show no details.
+@end deffn
+
+@deffn Command {nand probe} num
+Probes the specified device to determine key characteristics
+like its page and block sizes, and how many blocks it has.
+The @var{num} parameter is the value shown by @command{nand list}.
+You must (successfully) probe a device before you can use
+it with most other NAND commands.
+@end deffn
+
+@section Erasing, Reading, Writing to NAND Flash
+
+@deffn Command {nand dump} num filename offset length [oob_option]
+@cindex NAND reading
+Reads binary data from the NAND device and writes it to the file,
+starting at the specified offset.
+The @var{num} parameter is the value shown by @command{nand list}.
+
+Use a complete path name for @var{filename}, so you don't depend
+on the directory used to start the OpenOCD server.
+
+The @var{offset} and @var{length} must be exact multiples of the
+device's page size. They describe a data region; the OOB data
+associated with each such page may also be accessed.
+
+@b{NOTE:} At the time this text was written, no error correction
+was done on the data that's read, unless raw access was disabled
+and the underlying NAND controller driver had a @code{read_page}
+method which handled that error correction.
+
+By default, only page data is saved to the specified file.
+Use an @var{oob_option} parameter to save OOB data:
+@itemize @bullet
+@item no oob_* parameter
+@*Output file holds only page data; OOB is discarded.
+@item @code{oob_raw}
+@*Output file interleaves page data and OOB data;
+the file will be longer than "length" by the size of the
+spare areas associated with each data page.
+Note that this kind of "raw" access is different from
+what's implied by @command{nand raw_access}, which just
+controls whether a hardware-aware access method is used.
+@item @code{oob_only}
+@*Output file has only raw OOB data, and will
+be smaller than "length" since it will contain only the
+spare areas associated with each data page.
+@end itemize
+@end deffn
+
+@deffn Command {nand erase} num offset length
+@cindex NAND erasing
+Erases blocks on the specified NAND device, starting at the
+specified @var{offset} and continuing for @var{length} bytes.
+Both of those values must be exact multiples of the device's
+block size, and the region they specify must fit entirely in the chip.
+The @var{num} parameter is the value shown by @command{nand list}.
+
+@b{NOTE:} This command will try to erase bad blocks, when told
+to do so, which will probably invalidate the manufacturer's bad
+block marker.
+For the remainder of the current server session, @command{nand info}
+will still report that the block ``is'' bad.
+@end deffn
+
+@deffn Command {nand write} num filename offset [option...]
+@cindex NAND writing
+Writes binary data from the file into the specified NAND device,
+starting at the specified offset. Those pages should already
+have been erased; you can't change zero bits to one bits.
+The @var{num} parameter is the value shown by @command{nand list}.
+
+Use a complete path name for @var{filename}, so you don't depend
+on the directory used to start the OpenOCD server.
+
+The @var{offset} must be an exact multiple of the device's page size.
+All data in the file will be written, assuming it doesn't run
+past the end of the device.
+Only full pages are written, and any extra space in the last
+page will be filled with 0xff bytes. (That includes OOB data,
+if that's being written.)
+
+@b{NOTE:} At the time this text was written, bad blocks are
+ignored. That is, this routine will not skip bad blocks,
+but will instead try to write them. This can cause problems.
+
+Provide at most one @var{option} parameter. With some
+NAND drivers, the meanings of these parameters may change
+if @command{nand raw_access} was used to disable hardware ECC.
+@itemize @bullet
+@item no oob_* parameter
+@*File has only page data, which is written.
+If raw acccess is in use, the OOB area will not be written.
+Otherwise, if the underlying NAND controller driver has
+a @code{write_page} routine, that routine may write the OOB
+with hardware-computed ECC data.
+@item @code{oob_only}
+@*File has only raw OOB data, which is written to the OOB area.
+Each page's data area stays untouched. @i{This can be a dangerous
+option}, since it can invalidate the ECC data.
+You may need to force raw access to use this mode.
+@item @code{oob_raw}
+@*File interleaves data and OOB data, both of which are written
+If raw access is enabled, the data is written first, then the
+un-altered OOB.
+Otherwise, if the underlying NAND controller driver has
+a @code{write_page} routine, that routine may modify the OOB
+before it's written, to include hardware-computed ECC data.
+@item @code{oob_softecc}
+@*File has only page data, which is written.
+The OOB area is filled with 0xff, except for a standard 1-bit
+software ECC code stored in conventional locations.
+You might need to force raw access to use this mode, to prevent
+the underlying driver from applying hardware ECC.
+@item @code{oob_softecc_kw}
+@*File has only page data, which is written.
+The OOB area is filled with 0xff, except for a 4-bit software ECC
+specific to the boot ROM in Marvell Kirkwood SoCs.
+You might need to force raw access to use this mode, to prevent
+the underlying driver from applying hardware ECC.
+@end itemize
+@end deffn
+
+@section Other NAND commands
+@cindex NAND other commands
+
+@deffn Command {nand check_bad_blocks} [offset length]
+Checks for manufacturer bad block markers on the specified NAND
+device. If no parameters are provided, checks the whole
+device; otherwise, starts at the specified @var{offset} and
+continues for @var{length} bytes.
+Both of those values must be exact multiples of the device's
+block size, and the region they specify must fit entirely in the chip.
+The @var{num} parameter is the value shown by @command{nand list}.
+
+@b{NOTE:} Before using this command you should force raw access
+with @command{nand raw_access enable} to ensure that the underlying
+driver will not try to apply hardware ECC.
+@end deffn
+
+@deffn Command {nand info} num
+The @var{num} parameter is the value shown by @command{nand list}.
+This prints the one-line summary from "nand list", plus for
+devices which have been probed this also prints any known
+status for each block.
+@end deffn
+
+@deffn Command {nand raw_access} num <enable|disable>
+Sets or clears an flag affecting how page I/O is done.
+The @var{num} parameter is the value shown by @command{nand list}.
+
+This flag is cleared (disabled) by default, but changing that
+value won't affect all NAND devices. The key factor is whether
+the underlying driver provides @code{read_page} or @code{write_page}
+methods. If it doesn't provide those methods, the setting of
+this flag is irrelevant; all access is effectively ``raw''.
+
+When those methods exist, they are normally used when reading
+data (@command{nand dump} or reading bad block markers) or
+writing it (@command{nand write}). However, enabling
+raw access (setting the flag) prevents use of those methods,
+bypassing hardware ECC logic.
+@i{This can be a dangerous option}, since writing blocks
+with the wrong ECC data can cause them to be marked as bad.
+@end deffn
+
+@section NAND Drivers; Driver-specific Options and Commands
+@anchor{NAND Driver List}
+As noted above, the @command{nand device} command allows
+driver-specific options and behaviors.
+Some controllers also activate controller-specific commands.
+
+@deffn {NAND Driver} davinci
+This driver handles the NAND controllers found on DaVinci family
+chips from Texas Instruments.
+It takes three extra parameters:
+address of the NAND chip;
+hardware ECC mode to use (hwecc1, hwecc4, hwecc4_infix);
+address of the AEMIF controller on this processor.
+@example
+nand device davinci dm355.arm 0x02000000 hwecc4 0x01e10000
+@end example
+All DaVinci processors support the single-bit ECC hardware,
+and newer ones also support the four-bit ECC hardware.
+The @code{write_page} and @code{read_page} methods are used
+to implement those ECC modes, unless they are disabled using
+the @command{nand raw_access} command.
+@end deffn
+
+@deffn {NAND Driver} lpc3180
+These controllers require an extra @command{nand device}
+parameter: the clock rate used by the controller.
+@deffn Command {nand lpc3180 select} num [mlc|slc]
+Configures use of the MLC or SLC controller mode.
+MLC implies use of hardware ECC.
+The @var{num} parameter is the value shown by @command{nand list}.
+@end deffn
+
+At this writing, this driver includes @code{write_page}
+and @code{read_page} methods. Using @command{nand raw_access}
+to disable those methods will prevent use of hardware ECC
+in the MLC controller mode, but won't change SLC behavior.
+@end deffn
+@comment current lpc3180 code won't issue 5-byte address cycles
+
+@deffn {NAND Driver} orion
+These controllers require an extra @command{nand device}
+parameter: the address of the controller.
+@example
+nand device orion 0xd8000000
+@end example
+These controllers don't define any specialized commands.
+At this writing, their drivers don't include @code{write_page}
+or @code{read_page} methods, so @command{nand raw_access} won't
+change any behavior.
+@end deffn
+
+@deffn {NAND Driver} {s3c2410, s3c2412, s3c2440, s3c2443}
+These S3C24xx family controllers don't have any special
+@command{nand device} options, and don't define any
+specialized commands.
+At this writing, their drivers don't include @code{write_page}
+or @code{read_page} methods, so @command{nand raw_access} won't
+change any behavior.
+@end deffn
+