aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2021-05-07 11:50:17 -0700
committerGitHub <noreply@github.com>2021-05-07 11:50:17 -0700
commitdd3dea88f70709103387458848240e07597c6f3c (patch)
tree5c77c5302f690918294351e486467a606fc81afa
parent703960cba799e38508944484095f2c2131bf933b (diff)
parent38eea2367cae855ba0a4be1fb188d61cbff23d91 (diff)
downloadriscv-openocd-dd3dea88f70709103387458848240e07597c6f3c.zip
riscv-openocd-dd3dea88f70709103387458848240e07597c6f3c.tar.gz
riscv-openocd-dd3dea88f70709103387458848240e07597c6f3c.tar.bz2
Merge pull request #600 from riscv/from_upstream
From upstream
-rw-r--r--configure.ac3
-rw-r--r--contrib/60-openocd.rules5
-rw-r--r--doc/openocd.texi1088
-rw-r--r--src/flash/nand/tcl.c4
-rw-r--r--src/flash/nor/Makefile.am1
-rw-r--r--src/flash/nor/drivers.c2
-rw-r--r--src/flash/nor/esirisc_flash.c4
-rw-r--r--src/flash/nor/nrf5.c21
-rw-r--r--src/flash/nor/numicro.c2
-rw-r--r--src/flash/nor/rp2040.c453
-rw-r--r--src/flash/nor/stm32f1x.c38
-rw-r--r--src/flash/nor/tcl.c3
-rw-r--r--src/helper/command.c827
-rw-r--r--src/helper/command.h102
-rw-r--r--src/helper/jim-nvp.c6
-rw-r--r--src/helper/replacements.h44
-rw-r--r--src/helper/system.h18
-rw-r--r--src/helper/types.h8
-rw-r--r--src/jtag/aice/aice_pipe.c2
-rw-r--r--src/jtag/aice/aice_transport.c5
-rw-r--r--src/jtag/aice/aice_usb.c9
-rw-r--r--src/jtag/drivers/cmsis_dap.c149
-rw-r--r--src/jtag/drivers/cmsis_dap_usb_bulk.c13
-rw-r--r--src/jtag/drivers/cmsis_dap_usb_hid.c1
-rw-r--r--src/jtag/drivers/ftdi.c27
-rw-r--r--src/jtag/drivers/libusb_helper.c10
-rw-r--r--src/jtag/drivers/libusb_helper.h2
-rw-r--r--src/jtag/drivers/mpsse.c12
-rw-r--r--src/jtag/drivers/remote_bitbang.c55
-rw-r--r--src/jtag/drivers/rlink.c14
-rw-r--r--src/jtag/drivers/stlink_usb.c2
-rw-r--r--src/jtag/drivers/ulink.c2
-rw-r--r--src/jtag/drivers/versaloon/versaloon.c5
-rw-r--r--src/jtag/drivers/versaloon/versaloon.h2
-rw-r--r--src/jtag/drivers/versaloon/versaloon_include.h1
-rw-r--r--src/jtag/drivers/vsllink.c4
-rw-r--r--src/jtag/drivers/xds110.c10
-rw-r--r--src/jtag/tcl.c24
-rw-r--r--src/openocd.c1
-rw-r--r--src/pld/pld.c3
-rw-r--r--src/rtos/FreeRTOS.c2
-rw-r--r--src/rtos/nuttx.c2
-rw-r--r--src/server/telnet_server.c248
-rw-r--r--src/target/aarch64.c12
-rw-r--r--src/target/adi_v5_swd.c8
-rw-r--r--src/target/arm_adi_v5.h18
-rw-r--r--src/target/arm_cti.c8
-rw-r--r--src/target/arm_dap.c8
-rw-r--r--src/target/arm_tpiu_swo.c17
-rw-r--r--src/target/armv7m.h14
-rw-r--r--src/target/cortex_m.c52
-rw-r--r--src/target/etm.c3
-rw-r--r--src/target/image.c351
-rw-r--r--src/target/image.h18
-rw-r--r--src/target/nds32_cmd.c20
-rw-r--r--src/target/riscv/riscv-013.c1
-rw-r--r--src/target/smp.c34
-rw-r--r--src/target/startup.tcl31
-rw-r--r--src/target/target.c61
-rw-r--r--tcl/board/icnova_imx53_sodimm.cfg2
-rw-r--r--tcl/board/imx53-m53evk.cfg2
-rw-r--r--tcl/board/imx53loco.cfg2
-rw-r--r--tcl/board/pico-debug.cfg11
-rw-r--r--tcl/chip/atmel/at91/sam9_smc.cfg32
-rw-r--r--tcl/target/imx8qm.cfg89
-rw-r--r--tcl/target/rp2040-core0.cfg38
66 files changed, 2628 insertions, 1438 deletions
diff --git a/configure.ac b/configure.ac
index f9185e7..19c6f77 100644
--- a/configure.ac
+++ b/configure.ac
@@ -45,6 +45,9 @@ AC_SEARCH_LIBS([openpty], [util])
AC_CHECK_HEADERS([sys/socket.h])
AC_CHECK_HEADERS([elf.h])
+AC_EGREP_HEADER(Elf64_Ehdr, [elf.h], [
+ AC_DEFINE([HAVE_ELF64], [1], [Define to 1 if the system has the type `Elf64_Ehdr'.])
+])
AC_CHECK_HEADERS([dirent.h])
AC_CHECK_HEADERS([fcntl.h])
AC_CHECK_HEADERS([malloc.h])
diff --git a/contrib/60-openocd.rules b/contrib/60-openocd.rules
index a3046be..1829f07 100644
--- a/contrib/60-openocd.rules
+++ b/contrib/60-openocd.rules
@@ -154,6 +154,11 @@ ATTRS{idVendor}=="138e", ATTRS{idProduct}=="9000", MODE="660", GROUP="plugdev",
# Debug Board for Neo1973
ATTRS{idVendor}=="1457", ATTRS{idProduct}=="5118", MODE="660", GROUP="plugdev", TAG+="uaccess"
+# OSBDM
+ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0042", MODE="660", GROUP="plugdev", TAG+="uaccess"
+ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0058", MODE="660", GROUP="plugdev", TAG+="uaccess"
+ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="005e", MODE="660", GROUP="plugdev", TAG+="uaccess"
+
# Olimex ARM-USB-OCD
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0003", MODE="660", GROUP="plugdev", TAG+="uaccess"
diff --git a/doc/openocd.texi b/doc/openocd.texi
index fc6b04d..74a2c58 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -2063,7 +2063,7 @@ a target has been successfully instantiated.
If you want to use those commands, you may need to force
entry to the run stage.
-@deffn {Config Command} init
+@deffn {Config Command} {init}
This command terminates the configuration stage and
enters the run stage. This helps when you need to have
the startup scripts manage tasks such as resetting the target,
@@ -2082,7 +2082,7 @@ read/write memory on your target, @command{init} must occur before
the memory read/write commands. This includes @command{nand probe}.
@end deffn
-@deffn {Overridable Procedure} jtag_init
+@deffn {Overridable Procedure} {jtag_init}
This is invoked at server startup to verify that it can talk
to the scan chain (list of TAPs) which has been configured.
@@ -2115,7 +2115,7 @@ If you disable all access through TCP/IP, you will need to
use the command line @option{-pipe} option.
@anchor{gdb_port}
-@deffn {Command} gdb_port [number]
+@deffn {Config Command} {gdb_port} [number]
@cindex GDB server
Normally gdb listens to a TCP/IP port, but GDB can also
communicate via pipes(stdin/out or named pipes). The name
@@ -2148,7 +2148,7 @@ gdb (with 'set remotetimeout') is recommended. An insufficient timeout may
cause initialization to fail with "Unknown remote qXfer reply: OK".
@end deffn
-@deffn {Command} tcl_port [number]
+@deffn {Config Command} {tcl_port} [number]
Specify or query the port used for a simplified RPC
connection that can be used by clients to issue TCL commands and get the
output from the Tcl engine.
@@ -2158,7 +2158,7 @@ the port @var{number} defaults to 6666.
When specified as "disabled", this service is not activated.
@end deffn
-@deffn {Command} telnet_port [number]
+@deffn {Config Command} {telnet_port} [number]
Specify or query the
port on which to listen for incoming telnet connections.
This port is intended for interaction with one human through TCL commands.
@@ -2177,7 +2177,7 @@ The ones listed here are static and global.
@xref{targetevents,,Target Events}, about configuring target-specific event handling.
@anchor{gdbbreakpointoverride}
-@deffn {Command} gdb_breakpoint_override [@option{hard}|@option{soft}|@option{disable}]
+@deffn {Command} {gdb_breakpoint_override} [@option{hard}|@option{soft}|@option{disable}]
Force breakpoint type for gdb @command{break} commands.
This option supports GDB GUIs which don't
distinguish hard versus soft breakpoints, if the default OpenOCD and
@@ -2186,13 +2186,13 @@ breakpoints if the memory map has been set up for flash regions.
@end deffn
@anchor{gdbflashprogram}
-@deffn {Config Command} gdb_flash_program (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb_flash_program} (@option{enable}|@option{disable})
Set to @option{enable} to cause OpenOCD to program the flash memory when a
vFlash packet is received.
The default behaviour is @option{enable}.
@end deffn
-@deffn {Config Command} gdb_memory_map (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb_memory_map} (@option{enable}|@option{disable})
Set to @option{enable} to cause OpenOCD to send the memory configuration to GDB when
requested. GDB will then know when to set hardware breakpoints, and program flash
using the GDB load command. @command{gdb_flash_program enable} must also be enabled
@@ -2201,26 +2201,26 @@ Default behaviour is @option{enable}.
@xref{gdbflashprogram,,gdb_flash_program}.
@end deffn
-@deffn {Config Command} gdb_report_data_abort (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb_report_data_abort} (@option{enable}|@option{disable})
Specifies whether data aborts cause an error to be reported
by GDB memory read packets.
The default behaviour is @option{disable};
use @option{enable} see these errors reported.
@end deffn
-@deffn {Config Command} gdb_report_register_access_error (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb_report_register_access_error} (@option{enable}|@option{disable})
Specifies whether register accesses requested by GDB register read/write
packets report errors or not.
The default behaviour is @option{disable};
use @option{enable} see these errors reported.
@end deffn
-@deffn {Config Command} gdb_target_description (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb_target_description} (@option{enable}|@option{disable})
Set to @option{enable} to cause OpenOCD to send the target descriptions to gdb via qXfer:features:read packet.
The default behaviour is @option{enable}.
@end deffn
-@deffn {Command} gdb_save_tdesc
+@deffn {Command} {gdb_save_tdesc}
Saves the target description file to the local file system.
The file name is @i{target_name}.xml.
@@ -2265,7 +2265,7 @@ to the various active targets.
There is a command to manage and monitor that polling,
which is normally done in the background.
-@deffn Command poll [@option{on}|@option{off}]
+@deffn {Command} {poll} [@option{on}|@option{off}]
Poll the current target for its current state.
(Also, @pxref{targetcurstate,,target curstate}.)
If that target is in debug mode, architecture
@@ -2339,11 +2339,11 @@ Use the adapter driver @var{name} to connect to the
target.
@end deffn
-@deffn Command {adapter list}
+@deffn {Command} {adapter list}
List the debug adapter drivers that have been built into
the running copy of OpenOCD.
@end deffn
-@deffn Command {adapter transports} transport_name+
+@deffn {Config Command} {adapter transports} transport_name+
Specifies the transports supported by this debug adapter.
The adapter driver builds-in similar knowledge; use this only
when external configuration (such as jumpering) changes what
@@ -2352,12 +2352,12 @@ the hardware can support.
-@deffn Command {adapter name}
+@deffn {Command} {adapter name}
Returns the name of the debug adapter driver being used.
@end deffn
@anchor{adapter_usb_location}
-@deffn Command {adapter usb location} [<bus>-<port>[.<port>]...]
+@deffn {Config Command} {adapter usb location} [<bus>-<port>[.<port>]...]
Displays or specifies the physical USB port of the adapter to use. The path
roots at @var{bus} and walks down the physical ports, with each
@var{port} option specifying a deeper level in the bus topology, the last
@@ -2383,7 +2383,7 @@ Specifies either the address of the I/O port (default: 0x378 for LPT1) or
the number of the @file{/dev/parport} device.
@end deffn
-@deffn {Config Command} rtck [@option{enable}|@option{disable}]
+@deffn {Config Command} {rtck} [@option{enable}|@option{disable}]
Displays status of RTCK option.
Optionally sets that option first.
@end deffn
@@ -2393,7 +2393,7 @@ Optionally sets that option first.
Olimex ARM-JTAG-EW USB adapter
This has one driver-specific command:
-@deffn Command {armjtagew_info}
+@deffn {Command} {armjtagew_info}
Logs some status
@end deffn
@end deffn
@@ -2517,19 +2517,6 @@ If not specified, serial numbers are not considered.
and are not restricted to containing only decimal digits.)
@end deffn
-@deffn {Config Command} {ftdi_location} <bus>-<port>[.<port>]...
-@emph{DEPRECATED -- avoid using this.
-Use the command @ref{adapter_usb_location,,adapter usb location} instead.}
-
-Specifies the physical USB port of the adapter to use. The path
-roots at @var{bus} and walks down the physical ports, with each
-@var{port} option specifying a deeper level in the bus topology, the last
-@var{port} denoting where the target adapter is actually plugged.
-The USB bus topology can be queried with the command @emph{lsusb -t}.
-
-This command is only available if your libusb1 is at least version 1.0.16.
-@end deffn
-
@deffn {Config Command} {ftdi_channel} channel
Selects the channel of the FTDI device to use for MPSSE operations. Most
adapters use the default, channel 0, but there are exceptions.
@@ -2544,7 +2531,7 @@ minimal impact on the target system. Avoid floating inputs, conflicting outputs
and initially asserted reset signals.
@end deffn
-@deffn {Config Command} {ftdi_layout_signal} name [@option{-data}|@option{-ndata} data_mask] [@option{-input}|@option{-ninput} input_mask] [@option{-oe}|@option{-noe} oe_mask] [@option{-alias}|@option{-nalias} name]
+@deffn {Command} {ftdi_layout_signal} name [@option{-data}|@option{-ndata} data_mask] [@option{-input}|@option{-ninput} input_mask] [@option{-oe}|@option{-noe} oe_mask] [@option{-alias}|@option{-nalias} name]
Creates a signal with the specified @var{name}, controlled by one or more FTDI
GPIO pins via a range of possible buffer connections. The masks are FTDI GPIO
register bitmasks to tell the driver the connection and type of the output
@@ -2775,13 +2762,13 @@ reset_config srst_only
@end example
@end deffn
-@deffn {Command} {usb_blaster_lowlevel_driver} (@option{ftdi}|@option{ublast2})
+@deffn {Config Command} {usb_blaster_lowlevel_driver} (@option{ftdi}|@option{ublast2})
Chooses the low level access method for the adapter. If not specified,
@option{ftdi} is selected unless it wasn't enabled during the
configure stage. USB-Blaster II needs @option{ublast2}.
@end deffn
-@deffn {Command} {usb_blaster_firmware} @var{path}
+@deffn {Config Command} {usb_blaster_firmware} @var{path}
This command specifies @var{path} to access USB-Blaster II firmware
image. To be used with USB-Blaster II only.
@end deffn
@@ -2873,7 +2860,7 @@ The following example shows how to read 4 bytes from the EMUCOM channel 0x0:
77a90000
@end example
@end deffn
-@deffn {Config} {jlink usb} <@option{0} to @option{3}>
+@deffn {Config Command} {jlink usb} <@option{0} to @option{3}>
Set the USB address of the interface, in case more than one adapter is connected
to the host. If not specified, USB addresses are not considered. Device
selection via USB address is not always unambiguous. It is recommended to use
@@ -2881,7 +2868,7 @@ the serial number instead, if possible.
As a configuration command, it can be used only before 'init'.
@end deffn
-@deffn {Config} {jlink serial} <serial number>
+@deffn {Config Command} {jlink serial} <serial number>
Set the serial number of the interface, in case more than one adapter is
connected to the host. If not specified, serial numbers are not considered.
@@ -2992,7 +2979,7 @@ When using PPDEV to access the parallel port, use the number of the parallel por
you may encounter a problem.
@end deffn
-@deffn Command {parport_toggling_time} [nanoseconds]
+@deffn {Config Command} {parport_toggling_time} [nanoseconds]
Displays how many nanoseconds the hardware needs to toggle TCK;
the parport driver uses this value to obey the
@command{adapter speed} configuration.
@@ -3283,12 +3270,12 @@ As noted earlier, depending on the version of OpenOCD you use,
and the debug adapter you are using,
several transports may be available to
communicate with debug targets (or perhaps to program flash memory).
-@deffn Command {transport list}
+@deffn {Command} {transport list}
displays the names of the transports supported by this
version of OpenOCD.
@end deffn
-@deffn Command {transport select} @option{transport_name}
+@deffn {Command} {transport select} @option{transport_name}
Select which of the supported transports to use in this OpenOCD session.
When invoked with @option{transport_name}, attempts to select the named
@@ -3335,12 +3322,12 @@ driver} (in which case the command is @command{transport select hla_swd})
or @ref{st_link_dap_interface,the st-link interface driver} (in which case
the command is @command{transport select dapdirect_swd}).
-@deffn Command {swd newdap} ...
+@deffn {Config Command} {swd newdap} ...
Declares a single DAP which uses SWD transport.
Parameters are currently the same as "jtag newtap" but this is
expected to change.
@end deffn
-@deffn Command {swd wcr trn prescale}
+@deffn {Command} {swd wcr trn prescale}
Updates TRN (turnaround delay) and prescaling.fields of the
Wire Control Register (WCR).
No parameters: displays current settings.
@@ -3415,7 +3402,7 @@ may not be the fastest solution.
instead of @command{adapter speed}, but only for (ARM) cores and boards
which support adaptive clocking.
-@deffn {Command} adapter speed max_speed_kHz
+@deffn {Command} {adapter speed} max_speed_kHz
A non-zero speed is in KHZ. Hence: 3000 is 3mhz.
JTAG interfaces usually support a limited number of
speeds. The speed actually used won't be faster
@@ -3585,32 +3572,32 @@ needing to cope with both architecture and board specific constraints.
@section Commands for Handling Resets
-@deffn {Command} adapter srst pulse_width milliseconds
+@deffn {Command} {adapter srst pulse_width} milliseconds
Minimum amount of time (in milliseconds) OpenOCD should wait
after asserting nSRST (active-low system reset) before
allowing it to be deasserted.
@end deffn
-@deffn {Command} adapter srst delay milliseconds
+@deffn {Command} {adapter srst delay} milliseconds
How long (in milliseconds) OpenOCD should wait after deasserting
nSRST (active-low system reset) before starting new JTAG operations.
When a board has a reset button connected to SRST line it will
probably have hardware debouncing, implying you should use this.
@end deffn
-@deffn {Command} jtag_ntrst_assert_width milliseconds
+@deffn {Command} {jtag_ntrst_assert_width} milliseconds
Minimum amount of time (in milliseconds) OpenOCD should wait
after asserting nTRST (active-low JTAG TAP reset) before
allowing it to be deasserted.
@end deffn
-@deffn {Command} jtag_ntrst_delay milliseconds
+@deffn {Command} {jtag_ntrst_delay} milliseconds
How long (in milliseconds) OpenOCD should wait after deasserting
nTRST (active-low JTAG TAP reset) before starting new JTAG operations.
@end deffn
@anchor{reset_config}
-@deffn {Command} reset_config mode_flag ...
+@deffn {Command} {reset_config} mode_flag ...
This command displays or modifies the reset configuration
of your combination of JTAG board and target in target
configuration scripts.
@@ -3745,7 +3732,7 @@ schemes. For example, on a multi-target board the standard
may need the ability to reset only one target at time and
thus want to avoid using the board-wide SRST signal.
-@deffn {Overridable Procedure} init_reset mode
+@deffn {Overridable Procedure} {init_reset} mode
This is invoked near the beginning of the @command{reset} command,
usually to provide as much of a cold (power-up) reset as practical.
By default it is also invoked from @command{jtag_init} if
@@ -3768,7 +3755,7 @@ This is done by calling @command{jtag arp_init}
(or @command{jtag arp_init-reset}).
@end deffn
-@deffn Command {jtag arp_init}
+@deffn {Command} {jtag arp_init}
This validates the scan chain using just the four
standard JTAG signals (TMS, TCK, TDI, TDO).
It starts by issuing a JTAG-only reset.
@@ -3781,7 +3768,7 @@ If these tests all pass, TAP @code{setup} events are
issued to all TAPs with handlers for that event.
@end deffn
-@deffn Command {jtag arp_init-reset}
+@deffn {Command} {jtag arp_init-reset}
This uses TRST and SRST to try resetting
everything on the JTAG scan chain
(and anything else connected to SRST).
@@ -3889,7 +3876,7 @@ Actual config files typically use a variable such as @code{$_CHIPNAME}
instead of literals like @option{str912}, to support more than one chip
of each type. @xref{Config File Guidelines}.
-@deffn Command {jtag names}
+@deffn {Command} {jtag names}
Returns the names of all current TAPs in the scan chain.
Use @command{jtag cget} or @command{jtag tapisenabled}
to examine attributes and state of each TAP.
@@ -3900,7 +3887,7 @@ foreach t [jtag names] @{
@end example
@end deffn
-@deffn Command {scan_chain}
+@deffn {Command} {scan_chain}
Displays the TAPs in the scan chain configuration,
and their status.
The set of TAPs listed by this command is fixed by
@@ -3933,8 +3920,7 @@ and underscores are OK; while others (including dots!) are not.
@section TAP Declaration Commands
-@c shouldn't this be(come) a {Config Command}?
-@deffn Command {jtag newtap} chipname tapname configparams...
+@deffn {Config Command} {jtag newtap} chipname tapname configparams...
Declares a new TAP with the dotted name @var{chipname}.@var{tapname},
and configured according to the various @var{configparams}.
@@ -4026,12 +4012,12 @@ devices do not set the ack bit until sometime later.
@section Other TAP commands
-@deffn Command {jtag cget} dotted.name @option{-idcode}
+@deffn {Command} {jtag cget} dotted.name @option{-idcode}
Get the value of the IDCODE found in hardware.
@end deffn
-@deffn Command {jtag cget} dotted.name @option{-event} event_name
-@deffnx Command {jtag configure} dotted.name @option{-event} event_name handler
+@deffn {Command} {jtag cget} dotted.name @option{-event} event_name
+@deffnx {Command} {jtag configure} dotted.name @option{-event} event_name handler
At this writing this TAP attribute
mechanism is limited and used mostly for event handling.
(It is not a direct analogue of the @code{cget}/@code{configure}
@@ -4152,7 +4138,7 @@ uses quotes to evaluate @code{$CHIP} when the event is configured.
Using brackets @{ @} would cause it to be evaluated later,
at runtime, when it might have a different value.
-@deffn Command {jtag tapdisable} dotted.name
+@deffn {Command} {jtag tapdisable} dotted.name
If necessary, disables the tap
by sending it a @option{tap-disable} event.
Returns the string "1" if the tap
@@ -4160,7 +4146,7 @@ specified by @var{dotted.name} is enabled,
and "0" if it is disabled.
@end deffn
-@deffn Command {jtag tapenable} dotted.name
+@deffn {Command} {jtag tapenable} dotted.name
If necessary, enables the tap
by sending it a @option{tap-enable} event.
Returns the string "1" if the tap
@@ -4168,7 +4154,7 @@ specified by @var{dotted.name} is enabled,
and "0" if it is disabled.
@end deffn
-@deffn Command {jtag tapisenabled} dotted.name
+@deffn {Command} {jtag tapisenabled} dotted.name
Returns the string "1" if the tap
specified by @var{dotted.name} is enabled,
and "0" if it is disabled.
@@ -4260,7 +4246,7 @@ instead of "@option{-chain-position} @var{dotted.name}" when the target is creat
The @command{dap} command group supports the following sub-commands:
-@deffn Command {dap create} dap_name @option{-chain-position} dotted.name configparams...
+@deffn {Command} {dap create} dap_name @option{-chain-position} dotted.name configparams...
Declare a DAP instance named @var{dap_name} linked to the JTAG tap
@var{dotted.name}. This also creates a new command (@command{dap_name})
which is used for various purposes including additional configuration.
@@ -4277,17 +4263,17 @@ devices do not set the ack bit until sometime later.
@end itemize
@end deffn
-@deffn Command {dap names}
+@deffn {Command} {dap names}
This command returns a list of all registered DAP objects. It it useful mainly
for TCL scripting.
@end deffn
-@deffn Command {dap info} [num]
+@deffn {Command} {dap info} [num]
Displays the ROM table for MEM-AP @var{num},
defaulting to the currently selected AP of the currently selected target.
@end deffn
-@deffn Command {dap init}
+@deffn {Command} {dap init}
Initialize all registered DAPs. This command is used internally
during initialization. It can be issued at any time after the
initialization, too.
@@ -4295,27 +4281,27 @@ initialization, too.
The following commands exist as subcommands of DAP instances:
-@deffn Command {$dap_name info} [num]
+@deffn {Command} {$dap_name info} [num]
Displays the ROM table for MEM-AP @var{num},
defaulting to the currently selected AP.
@end deffn
-@deffn Command {$dap_name apid} [num]
+@deffn {Command} {$dap_name apid} [num]
Displays ID register from AP @var{num}, defaulting to the currently selected AP.
@end deffn
@anchor{DAP subcommand apreg}
-@deffn Command {$dap_name apreg} ap_num reg [value]
+@deffn {Command} {$dap_name apreg} ap_num reg [value]
Displays content of a register @var{reg} from AP @var{ap_num}
or set a new value @var{value}.
@var{reg} is byte address of a word register, 0, 4, 8 ... 0xfc.
@end deffn
-@deffn Command {$dap_name apsel} [num]
+@deffn {Command} {$dap_name apsel} [num]
Select AP @var{num}, defaulting to 0.
@end deffn
-@deffn Command {$dap_name dpreg} reg [value]
+@deffn {Command} {$dap_name dpreg} reg [value]
Displays the content of DP register at address @var{reg}, or set it to a new
value @var{value}.
@@ -4327,18 +4313,18 @@ In case of JTAG it only assumes values 0, 4, 8 and 0xc.
background activity by OpenOCD while you are operating at such low-level.
@end deffn
-@deffn Command {$dap_name baseaddr} [num]
+@deffn {Command} {$dap_name baseaddr} [num]
Displays debug base address from MEM-AP @var{num},
defaulting to the currently selected AP.
@end deffn
-@deffn Command {$dap_name memaccess} [value]
+@deffn {Command} {$dap_name memaccess} [value]
Displays the number of extra tck cycles in the JTAG idle to use for MEM-AP
memory bus access [0-255], giving additional time to respond to reads.
If @var{value} is defined, first assigns that.
@end deffn
-@deffn Command {$dap_name apcsw} [value [mask]]
+@deffn {Command} {$dap_name apcsw} [value [mask]]
Displays or changes CSW bit pattern for MEM-AP transfers.
At the begin of each memory access the CSW pattern is extended (bitwise or-ed)
@@ -4381,7 +4367,7 @@ xxx.dap apcsw default
@end example
@end deffn
-@deffn Command {$dap_name ti_be_32_quirks} [@option{enable}]
+@deffn {Config Command} {$dap_name ti_be_32_quirks} [@option{enable}]
Set/get quirks mode for TI TMS450/TMS570 processors
Disabled by default
@end deffn
@@ -4430,11 +4416,11 @@ are examples; and there are many more.
Several commands let you examine the list of targets:
-@deffn Command {target current}
+@deffn {Command} {target current}
Returns the name of the current target.
@end deffn
-@deffn Command {target names}
+@deffn {Command} {target names}
Lists the names of all current targets in the list.
@example
foreach t [target names] @{
@@ -4446,7 +4432,7 @@ foreach t [target names] @{
@c yep, "target list" would have been better.
@c plus maybe "target setdefault".
-@deffn Command targets [name]
+@deffn {Command} {targets} [name]
@emph{Note: the name of this command is plural. Other target
command names are singular.}
@@ -4477,7 +4463,7 @@ It's easy to see what target types are supported,
since there's a command to list them.
@anchor{targettypes}
-@deffn Command {target types}
+@deffn {Command} {target types}
Lists all supported target types.
At this writing, the supported CPU types are:
@@ -4514,7 +4500,7 @@ a CPU, through which bus read and write cycles can be generated; it may be
useful for working with non-CPU hardware behind an AP or during development of
support for new CPUs.
It's possible to connect a GDB client to this target (the GDB port has to be
-specified, @xref{gdbportoverride,,option -gdb-port}), and a fake ARM core will
+specified, @xref{gdbportoverride,,option -gdb-port}.), and a fake ARM core will
be emulated to comply to GDB remote protocol.
@item @code{mips_m4k} -- a MIPS core.
@item @code{mips_mips64} -- a MIPS64 core.
@@ -4612,7 +4598,7 @@ That may be needed to let you write the boot loader into flash,
in order to ``de-brick'' your board; or to load programs into
external DDR memory without having run the boot loader.
-@deffn Command {target create} target_name type configparams...
+@deffn {Config Command} {target create} target_name type configparams...
This command creates a GDB debug target that refers to a specific JTAG tap.
It enters that target into a list, and creates a new
command (@command{@var{target_name}}) which is used for various
@@ -4637,7 +4623,7 @@ You @emph{must} set the @code{-chain-position @var{dotted.name}} or
@end itemize
@end deffn
-@deffn Command {$target_name configure} configparams...
+@deffn {Command} {$target_name configure} configparams...
The options accepted by this command may also be
specified as parameters to @command{target create}.
Their values can later be queried one at a time by
@@ -4760,18 +4746,18 @@ omap3530.cpu mww 0x5555 123
The commands supported by OpenOCD target objects are:
-@deffn Command {$target_name arp_examine} @option{allow-defer}
-@deffnx Command {$target_name arp_halt}
-@deffnx Command {$target_name arp_poll}
-@deffnx Command {$target_name arp_reset}
-@deffnx Command {$target_name arp_waitstate}
+@deffn {Command} {$target_name arp_examine} @option{allow-defer}
+@deffnx {Command} {$target_name arp_halt}
+@deffnx {Command} {$target_name arp_poll}
+@deffnx {Command} {$target_name arp_reset}
+@deffnx {Command} {$target_name arp_waitstate}
Internal OpenOCD scripts (most notably @file{startup.tcl})
use these to deal with specific reset cases.
They are not otherwise documented here.
@end deffn
-@deffn Command {$target_name array2mem} arrayname width address count
-@deffnx Command {$target_name mem2array} arrayname width address count
+@deffn {Command} {$target_name array2mem} arrayname width address count
+@deffnx {Command} {$target_name mem2array} arrayname width address count
These provide an efficient script-oriented interface to memory.
The @code{array2mem} primitive writes bytes, halfwords, or words;
while @code{mem2array} reads them.
@@ -4793,7 +4779,7 @@ and neither store nor return those values.
@end itemize
@end deffn
-@deffn Command {$target_name cget} queryparm
+@deffn {Command} {$target_name cget} queryparm
Each configuration parameter accepted by
@command{$target_name configure}
can be individually queried, to return its current value.
@@ -4826,7 +4812,7 @@ foreach name [target names] @{
@end deffn
@anchor{targetcurstate}
-@deffn Command {$target_name curstate}
+@deffn {Command} {$target_name curstate}
Displays the current target state:
@code{debug-running},
@code{halted},
@@ -4835,22 +4821,22 @@ Displays the current target state:
(Also, @pxref{eventpolling,,Event Polling}.)
@end deffn
-@deffn Command {$target_name eventlist}
+@deffn {Command} {$target_name eventlist}
Displays a table listing all event handlers
currently associated with this target.
@xref{targetevents,,Target Events}.
@end deffn
-@deffn Command {$target_name invoke-event} event_name
+@deffn {Command} {$target_name invoke-event} event_name
Invokes the handler for the event named @var{event_name}.
(This is primarily intended for use by OpenOCD framework
code, for example by the reset code in @file{startup.tcl}.)
@end deffn
-@deffn Command {$target_name mdd} [phys] addr [count]
-@deffnx Command {$target_name mdw} [phys] addr [count]
-@deffnx Command {$target_name mdh} [phys] addr [count]
-@deffnx Command {$target_name mdb} [phys] addr [count]
+@deffn {Command} {$target_name mdd} [phys] addr [count]
+@deffnx {Command} {$target_name mdw} [phys] addr [count]
+@deffnx {Command} {$target_name mdh} [phys] addr [count]
+@deffnx {Command} {$target_name mdb} [phys] addr [count]
Display contents of address @var{addr}, as
64-bit doublewords (@command{mdd}),
32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}),
@@ -4864,10 +4850,10 @@ If @var{count} is specified, displays that many units.
see the @code{mem2array} primitives.)
@end deffn
-@deffn Command {$target_name mwd} [phys] addr doubleword [count]
-@deffnx Command {$target_name mww} [phys] addr word [count]
-@deffnx Command {$target_name mwh} [phys] addr halfword [count]
-@deffnx Command {$target_name mwb} [phys] addr byte [count]
+@deffn {Command} {$target_name mwd} [phys] addr doubleword [count]
+@deffnx {Command} {$target_name mww} [phys] addr word [count]
+@deffnx {Command} {$target_name mwh} [phys] addr halfword [count]
+@deffnx {Command} {$target_name mwb} [phys] addr byte [count]
Writes the specified @var{doubleword} (64 bits), @var{word} (32 bits),
@var{halfword} (16 bits), or @var{byte} (8-bit) value,
at the specified address @var{addr}.
@@ -5105,20 +5091,20 @@ Use it in board specific configuration files, not interactively.
@end deffn
@comment less confusing would be: "flash list" (like "nand list")
-@deffn Command {flash banks}
+@deffn {Command} {flash banks}
Prints a one-line summary of each device that was
declared using @command{flash bank}, numbered from zero.
Note that this is the @emph{plural} form;
the @emph{singular} form is a very different command.
@end deffn
-@deffn Command {flash list}
+@deffn {Command} {flash list}
Retrieves a list of associative arrays for each device that was
declared using @command{flash bank}, numbered from zero.
This returned list can be manipulated easily from within scripts.
@end deffn
-@deffn Command {flash probe} num
+@deffn {Command} {flash probe} num
Identify the flash, or validate the parameters of the configured flash. Operation
depends on the flash type.
The @var{num} parameter is a value shown by @command{flash banks}.
@@ -5180,7 +5166,7 @@ Examples include CFI flash such as ``Intel Advanced Bootblock flash'',
and AT91SAM7 on-chip flash.
@xref{flashprotect,,flash protect}.
-@deffn Command {flash erase_sector} num first last
+@deffn {Command} {flash erase_sector} num first last
Erase sectors in bank @var{num}, starting at sector @var{first}
up to and including @var{last}.
Sector numbering starts at 0.
@@ -5189,7 +5175,7 @@ specifies "to the end of the flash bank".
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {flash erase_address} [@option{pad}] [@option{unlock}] address length
+@deffn {Command} {flash erase_address} [@option{pad}] [@option{unlock}] address length
Erase sectors starting at @var{address} for @var{length} bytes.
Unless @option{pad} is specified, @math{address} must begin a
flash sector, and @math{address + length - 1} must end a sector.
@@ -5203,10 +5189,10 @@ If @option{unlock} is specified, then the flash is unprotected
before erase starts.
@end deffn
-@deffn Command {flash filld} address double-word length
-@deffnx Command {flash fillw} address word length
-@deffnx Command {flash fillh} address halfword length
-@deffnx Command {flash fillb} address byte length
+@deffn {Command} {flash filld} address double-word length
+@deffnx {Command} {flash fillw} address word length
+@deffnx {Command} {flash fillh} address halfword length
+@deffnx {Command} {flash fillb} address byte length
Fills flash memory with the specified @var{double-word} (64 bits), @var{word} (32 bits),
@var{halfword} (16 bits), or @var{byte} (8-bit) pattern,
starting at @var{address} and continuing
@@ -5220,9 +5206,9 @@ each block, and the specified length must stay within that bank.
@end deffn
@comment no current checks for errors if fill blocks touch multiple banks!
-@deffn Command {flash mdw} addr [count]
-@deffnx Command {flash mdh} addr [count]
-@deffnx Command {flash mdb} addr [count]
+@deffn {Command} {flash mdw} addr [count]
+@deffnx {Command} {flash mdh} addr [count]
+@deffnx {Command} {flash mdb} addr [count]
Display contents of address @var{addr}, as
32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}),
or 8-bit bytes (@command{mdb}).
@@ -5233,14 +5219,14 @@ The flash bank to use is inferred from the @var{address} of
each block, and the specified length must stay within that bank.
@end deffn
-@deffn Command {flash write_bank} num filename [offset]
+@deffn {Command} {flash write_bank} num filename [offset]
Write the binary @file{filename} to flash bank @var{num},
starting at @var{offset} bytes from the beginning of the bank. If @var{offset}
is omitted, start at the beginning of the flash bank.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {flash read_bank} num filename [offset [length]]
+@deffn {Command} {flash read_bank} num filename [offset [length]]
Read @var{length} bytes from the flash bank @var{num} starting at @var{offset}
and write the contents to the binary @file{filename}. If @var{offset} is
omitted, start at the beginning of the flash bank. If @var{length} is omitted,
@@ -5248,14 +5234,14 @@ read the remaining bytes from the flash bank.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {flash verify_bank} num filename [offset]
+@deffn {Command} {flash verify_bank} num filename [offset]
Compare the contents of the binary file @var{filename} with the contents of the
flash bank @var{num} starting at @var{offset}. If @var{offset} is omitted,
start at the beginning of the flash bank. Fail if the contents do not match.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {flash write_image} [erase] [unlock] filename [offset] [type]
+@deffn {Command} {flash write_image} [erase] [unlock] filename [offset] [type]
Write the image @file{filename} to the current target's flash bank(s).
Only loadable sections from the image are written.
A relocation @var{offset} may be specified, in which case it is added
@@ -5292,7 +5278,7 @@ it has been removed by the @option{unlock} flag.
@end deffn
-@deffn Command {flash verify_image} filename [offset] [type]
+@deffn {Command} {flash verify_image} filename [offset] [type]
Verify the image @file{filename} to the current target's flash bank(s).
Parameters follow the description of 'flash write_image'.
In contrast to the 'verify_image' command, for banks with specific
@@ -5307,13 +5293,13 @@ check for successful programming.
@section Other Flash commands
@cindex flash protection
-@deffn Command {flash erase_check} num
+@deffn {Command} {flash erase_check} num
Check erase state of sectors in flash bank @var{num},
and display that status.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {flash info} num [sectors]
+@deffn {Command} {flash info} num [sectors]
Print info about flash bank @var{num}, a list of protection blocks
and their status. Use @option{sectors} to show a list of sectors instead.
@@ -5323,7 +5309,7 @@ and possibly stale information.
@end deffn
@anchor{flashprotect}
-@deffn Command {flash protect} num first last (@option{on}|@option{off})
+@deffn {Command} {flash protect} num first last (@option{on}|@option{off})
Enable (@option{on}) or disable (@option{off}) protection of flash blocks
in flash bank @var{num}, starting at protection block @var{first}
and continuing up to and including @var{last}.
@@ -5335,14 +5321,14 @@ Some devices may utilize a protection block distinct from flash sector.
See @command{flash info} for a list of protection blocks.
@end deffn
-@deffn Command {flash padded_value} num value
+@deffn {Command} {flash padded_value} num value
Sets the default value used for padding any image sections, This should
normally match the flash bank erased value. If not specified by this
command or the flash driver then it defaults to 0xff.
@end deffn
@anchor{program}
-@deffn Command {program} filename [preverify] [verify] [reset] [exit] [offset]
+@deffn {Command} {program} filename [preverify] [verify] [reset] [exit] [offset]
This is a helper script that simplifies using OpenOCD as a standalone
programmer. The only required parameter is @option{filename}, the others are optional.
@xref{Flash Programming}.
@@ -5354,7 +5340,7 @@ As noted above, the @command{flash bank} command requires a driver name,
and allows driver-specific options and behaviors.
Some drivers also activate driver-specific commands.
-@deffn {Flash Driver} virtual
+@deffn {Flash Driver} {virtual}
This is a special driver that maps a previously defined bank to another
address. All bank settings will be copied from the master physical bank.
@@ -5378,7 +5364,7 @@ flash bank vbank1 virtual 0x9fc00000 0 0 0 \
@subsection External Flash
-@deffn {Flash Driver} cfi
+@deffn {Flash Driver} {cfi}
@cindex Common Flash Interface
@cindex CFI
The ``Common Flash Interface'' (CFI) is the main standard for
@@ -5423,7 +5409,7 @@ flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME
@c "cfi part_id" disabled
@end deffn
-@deffn {Flash Driver} jtagspi
+@deffn {Flash Driver} {jtagspi}
@cindex Generic JTAG2SPI driver
@cindex SPI
@cindex jtagspi
@@ -5464,7 +5450,7 @@ flash bank $_FLASHNAME spi 0x0 0 0 0 \
@end example
@end deffn
-@deffn {Flash Driver} xcf
+@deffn {Flash Driver} {xcf}
@cindex Xilinx Platform flash driver
@cindex xcf
Xilinx FPGAs can be configured from specialized flash ICs named Platform Flash.
@@ -5473,7 +5459,7 @@ only difference is special registers controlling its FPGA specific behavior.
They must be properly configured for successful FPGA loading using
additional @var{xcf} driver command:
-@deffn Command {xcf ccb} <bank_id>
+@deffn {Command} {xcf ccb} <bank_id>
command accepts additional parameters:
@itemize
@item @var{external|internal} ... selects clock source.
@@ -5492,7 +5478,7 @@ every time you erase/program data sectors because it stores in
dedicated sector.
@end deffn
-@deffn Command {xcf configure} <bank_id>
+@deffn {Command} {xcf configure} <bank_id>
Initiates FPGA loading procedure. Useful if your board has no "configure"
button.
@example
@@ -5510,7 +5496,7 @@ only "bin" (raw binary, do not confuse it with "bit") and "mcs"
@end itemize
@end deffn
-@deffn {Flash Driver} lpcspifi
+@deffn {Flash Driver} {lpcspifi}
@cindex NXP SPI Flash Interface
@cindex SPIFI
@cindex lpcspifi
@@ -5534,7 +5520,7 @@ flash bank $_FLASHNAME lpcspifi 0x14000000 0 0 0 $_TARGETNAME
@end deffn
-@deffn {Flash Driver} stmsmi
+@deffn {Flash Driver} {stmsmi}
@cindex STMicroelectronics Serial Memory Interface
@cindex SMI
@cindex stmsmi
@@ -5562,7 +5548,7 @@ flash bank $_FLASHNAME stmsmi 0xf8000000 0 0 0 $_TARGETNAME
@end deffn
-@deffn {Flash Driver} stmqspi
+@deffn {Flash Driver} {stmqspi}
@cindex STMicroelectronics QuadSPI/OctoSPI Interface
@cindex QuadSPI
@cindex OctoSPI
@@ -5621,12 +5607,12 @@ flash bank $_FLASHNAME stmqspi 0x70000000 0 0 0 \
@end example
There are three specific commands
-@deffn Command {stmqspi mass_erase} bank_id
+@deffn {Command} {stmqspi mass_erase} bank_id
Clears sector protections and performs a mass erase. Works only if there is no
chip specific write protection engaged.
@end deffn
-@deffn Command {stmqspi set} bank_id name total_size page_size read_cmd fread_cmd pprg_cmd mass_erase_cmd sector_size sector_erase_cmd
+@deffn {Command} {stmqspi set} bank_id name total_size page_size read_cmd fread_cmd pprg_cmd mass_erase_cmd sector_size sector_erase_cmd
Set flash parameters: @var{name} human readable string, @var{total_size} size
in bytes, @var{page_size} is write page size. @var{read_cmd}, @var{fread_cmd} and @var{pprg_cmd}
are commands for reading and page programming. @var{fread_cmd} is used in DPI and QPI modes,
@@ -5640,7 +5626,7 @@ In dual mode parameters of both chips are set identically. The parameters refer
a single chip, so the whole bank gets twice the specified capacity etc.
@end deffn
-@deffn Command {stmqspi cmd} bank_id resp_num cmd_byte ...
+@deffn {Command} {stmqspi cmd} bank_id resp_num cmd_byte ...
If @var{resp_num} is zero, sends command @var{cmd_byte} and following data
bytes. In dual mode command byte is sent to @emph{both} chips but data bytes are
sent @emph{alternatingly} to chip 1 and 2, first to flash 1, second to flash 2, etc.,
@@ -5677,7 +5663,7 @@ should return the status register contents.
@end deffn
-@deffn {Flash Driver} mrvlqspi
+@deffn {Flash Driver} {mrvlqspi}
This driver supports QSPI flash controller of Marvell's Wireless
Microcontroller platform.
@@ -5690,7 +5676,7 @@ flash bank $_FLASHNAME mrvlqspi 0x0 0 0 0 $_TARGETNAME 0x46010000
@end deffn
-@deffn {Flash Driver} ath79
+@deffn {Flash Driver} {ath79}
@cindex Atheros ath79 SPI driver
@cindex ath79
Members of ATH79 SoC family from Atheros include a SPI interface with 3
@@ -5729,7 +5715,7 @@ flash bank flash2 ath79 0x20000000 0 0 0 $_TARGETNAME cs2
@end deffn
-@deffn {Flash Driver} fespi
+@deffn {Flash Driver} {fespi}
@cindex Freedom E SPI
@cindex fespi
@@ -5742,7 +5728,7 @@ flash bank $_FLASHNAME fespi 0x20000000 0 0 0 $_TARGETNAME
@subsection Internal Flash (Microcontrollers)
-@deffn {Flash Driver} aduc702x
+@deffn {Flash Driver} {aduc702x}
The ADUC702x analog microcontrollers from Analog Devices
include internal flash and use ARM7TDMI cores.
The aduc702x flash driver works with models ADUC7019 through ADUC7028.
@@ -5754,7 +5740,7 @@ flash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME
@end example
@end deffn
-@deffn {Flash Driver} ambiqmicro
+@deffn {Flash Driver} {ambiqmicro}
@cindex ambiqmicro
@cindex apollo
All members of the Apollo microcontroller family from
@@ -5787,13 +5773,13 @@ are available to the user.
The @var{ambiqmicro} driver adds some additional commands:
-@deffn Command {ambiqmicro mass_erase} <bank>
+@deffn {Command} {ambiqmicro mass_erase} <bank>
Erase entire bank.
@end deffn
-@deffn Command {ambiqmicro page_erase} <bank> <first> <last>
+@deffn {Command} {ambiqmicro page_erase} <bank> <first> <last>
Erase device pages.
@end deffn
-@deffn Command {ambiqmicro program_otp} <bank> <offset> <count>
+@deffn {Command} {ambiqmicro program_otp} <bank> <offset> <count>
Program OTP is a one time operation to create write protected flash.
The user writes sectors to SRAM starting at 0x10000010.
Program OTP will write these sectors from SRAM to flash, and write protect
@@ -5802,7 +5788,7 @@ the flash.
@end deffn
@anchor{at91samd}
-@deffn {Flash Driver} at91samd
+@deffn {Flash Driver} {at91samd}
@cindex at91samd
All members of the ATSAM D2x, D1x, D0x, ATSAMR, ATSAML and ATSAMC microcontroller
families from Atmel include internal flash and use ARM's Cortex-M0+ core.
@@ -5815,13 +5801,13 @@ The devices have one flash bank:
flash bank $_FLASHNAME at91samd 0x00000000 0 1 1 $_TARGETNAME
@end example
-@deffn Command {at91samd chip-erase}
+@deffn {Command} {at91samd chip-erase}
Issues a complete Flash erase via the Device Service Unit (DSU). This can be
used to erase a chip back to its factory state and does not require the
processor to be halted.
@end deffn
-@deffn Command {at91samd set-security}
+@deffn {Command} {at91samd set-security}
Secures the Flash via the Set Security Bit (SSB) command. This prevents access
to the Flash and can only be undone by using the chip-erase command which
erases the Flash contents and turns off the security bit. Warning: at this
@@ -5833,7 +5819,7 @@ at91samd set-security enable
@end example
@end deffn
-@deffn Command {at91samd eeprom}
+@deffn {Command} {at91samd eeprom}
Shows or sets the EEPROM emulation size configuration, stored in the User Row
of the Flash. When setting, the EEPROM size must be specified in bytes and it
must be one of the permitted sizes according to the datasheet. Settings are
@@ -5848,7 +5834,7 @@ at91samd eeprom 1024
@end example
@end deffn
-@deffn Command {at91samd bootloader}
+@deffn {Command} {at91samd bootloader}
Shows or sets the bootloader size configuration, stored in the User Row of the
Flash. This is called the BOOTPROT region. When setting, the bootloader size
must be specified in bytes and it must be one of the permitted sizes according
@@ -5861,13 +5847,13 @@ at91samd bootloader 16384
@end example
@end deffn
-@deffn Command {at91samd dsu_reset_deassert}
+@deffn {Command} {at91samd dsu_reset_deassert}
This command releases internal reset held by DSU
and prepares reset vector catch in case of reset halt.
Command is used internally in event reset-deassert-post.
@end deffn
-@deffn Command {at91samd nvmuserrow}
+@deffn {Command} {at91samd nvmuserrow}
Writes or reads the entire 64 bit wide NVM user row register which is located at
0x804000. This register includes various fuses lock-bits and factory calibration
data. Reading the register is done by invoking this command without any
@@ -5891,7 +5877,7 @@ NVMUSERROW: 0xFFFFFC5DD8E0C788
@end deffn
@anchor{at91sam3}
-@deffn {Flash Driver} at91sam3
+@deffn {Flash Driver} {at91sam3}
@cindex at91sam3
All members of the AT91SAM3 microcontroller family from
Atmel include internal flash and use ARM's Cortex-M3 core. The driver
@@ -5927,10 +5913,10 @@ to the @command{flash bank} command:
The AT91SAM3 driver adds some additional commands:
-@deffn Command {at91sam3 gpnvm}
-@deffnx Command {at91sam3 gpnvm clear} number
-@deffnx Command {at91sam3 gpnvm set} number
-@deffnx Command {at91sam3 gpnvm show} [@option{all}|number]
+@deffn {Command} {at91sam3 gpnvm}
+@deffnx {Command} {at91sam3 gpnvm clear} number
+@deffnx {Command} {at91sam3 gpnvm set} number
+@deffnx {Command} {at91sam3 gpnvm show} [@option{all}|number]
With no parameters, @command{show} or @command{show all},
shows the status of all GPNVM bits.
With @command{show} @var{number}, displays that bit.
@@ -5939,7 +5925,7 @@ With @command{set} @var{number} or @command{clear} @var{number},
modifies that GPNVM bit.
@end deffn
-@deffn Command {at91sam3 info}
+@deffn {Command} {at91sam3 info}
This command attempts to display information about the AT91SAM3
chip. @emph{First} it read the @code{CHIPID_CIDR} [address 0x400e0740, see
Section 28.2.1, page 505 of the AT91SAM3U 29/may/2009 datasheet,
@@ -5949,27 +5935,27 @@ believes the chip is configured. By default, the SLOWCLK is assumed to
be 32768 Hz, see the command @command{at91sam3 slowclk}.
@end deffn
-@deffn Command {at91sam3 slowclk} [value]
+@deffn {Command} {at91sam3 slowclk} [value]
This command shows/sets the slow clock frequency used in the
@command{at91sam3 info} command calculations above.
@end deffn
@end deffn
-@deffn {Flash Driver} at91sam4
+@deffn {Flash Driver} {at91sam4}
@cindex at91sam4
All members of the AT91SAM4 microcontroller family from
Atmel include internal flash and use ARM's Cortex-M4 core.
This driver uses the same command names/syntax as @xref{at91sam3}.
@end deffn
-@deffn {Flash Driver} at91sam4l
+@deffn {Flash Driver} {at91sam4l}
@cindex at91sam4l
All members of the AT91SAM4L microcontroller family from
Atmel include internal flash and use ARM's Cortex-M4 core.
This driver uses the same command names/syntax as @xref{at91sam3}.
The AT91SAM4L driver adds some additional commands:
-@deffn Command {at91sam4l smap_reset_deassert}
+@deffn {Command} {at91sam4l smap_reset_deassert}
This command releases internal reset held by SMAP
and prepares reset vector catch in case of reset halt.
Command is used internally in event reset-deassert-post.
@@ -5977,7 +5963,7 @@ Command is used internally in event reset-deassert-post.
@end deffn
@anchor{atsame5}
-@deffn {Flash Driver} atsame5
+@deffn {Flash Driver} {atsame5}
@cindex atsame5
All members of the SAM E54, E53, E51 and D51 microcontroller
families from Microchip (former Atmel) include internal flash
@@ -5991,7 +5977,7 @@ Bank swapping is not supported yet.
flash bank $_FLASHNAME atsame5 0x00000000 0 1 1 $_TARGETNAME
@end example
-@deffn Command {atsame5 bootloader}
+@deffn {Command} {atsame5 bootloader}
Shows or sets the bootloader size configuration, stored in the User Page of the
Flash. This is called the BOOTPROT region. When setting, the bootloader size
must be specified in bytes. The nearest bigger protection size is used.
@@ -6004,19 +5990,19 @@ atsame5 bootloader 16384
@end example
@end deffn
-@deffn Command {atsame5 chip-erase}
+@deffn {Command} {atsame5 chip-erase}
Issues a complete Flash erase via the Device Service Unit (DSU). This can be
used to erase a chip back to its factory state and does not require the
processor to be halted.
@end deffn
-@deffn Command {atsame5 dsu_reset_deassert}
+@deffn {Command} {atsame5 dsu_reset_deassert}
This command releases internal reset held by DSU
and prepares reset vector catch in case of reset halt.
Command is used internally in event reset-deassert-post.
@end deffn
-@deffn Command {atsame5 userpage}
+@deffn {Command} {atsame5 userpage}
Writes or reads the first 64 bits of NVM User Page which is located at
0x804000. This field includes various fuses.
Reading is done by invoking this command without any arguments.
@@ -6040,14 +6026,14 @@ USER PAGE: 0xAEECFF80FE9A9239
@end deffn
-@deffn {Flash Driver} atsamv
+@deffn {Flash Driver} {atsamv}
@cindex atsamv
All members of the ATSAMV7x, ATSAMS70, and ATSAME70 families from
Atmel include internal flash and use ARM's Cortex-M7 core.
This driver uses the same command names/syntax as @xref{at91sam3}.
@end deffn
-@deffn {Flash Driver} at91sam7
+@deffn {Flash Driver} {at91sam7}
All members of the AT91SAM7 microcontroller family from Atmel include
internal flash and use ARM7TDMI cores. The driver automatically
recognizes a number of these chips using the chip identification
@@ -6082,7 +6068,7 @@ However, there is an ``EraseAll`` command that can erase an entire flash
plane (of up to 256KB), and it will be used automatically when you issue
@command{flash erase_sector} or @command{flash erase_address} commands.
-@deffn Command {at91sam7 gpnvm} bitnum (@option{set}|@option{clear})
+@deffn {Command} {at91sam7 gpnvm} bitnum (@option{set}|@option{clear})
Set or clear a ``General Purpose Non-Volatile Memory'' (GPNVM)
bit for the processor. Each processor has a number of such bits,
used for controlling features such as brownout detection (so they
@@ -6094,13 +6080,13 @@ the appropriate at91sam7 target.
@end deffn
@end deffn
-@deffn {Flash Driver} avr
+@deffn {Flash Driver} {avr}
The AVR 8-bit microcontrollers from Atmel integrate flash memory.
@emph{The current implementation is incomplete.}
@comment - defines mass_erase ... pointless given flash_erase_address
@end deffn
-@deffn {Flash Driver} bluenrg-x
+@deffn {Flash Driver} {bluenrg-x}
STMicroelectronics BlueNRG-1, BlueNRG-2 and BlueNRG-LP Bluetooth low energy wireless system-on-chip. They include ARM Cortex-M0/M0+ core and internal flash memory.
The driver automatically recognizes these chips using
the chip identification registers, and autoconfigures itself.
@@ -6119,7 +6105,7 @@ flash erase_sector 0 0 last # It will perform a mass erase
Triggering a mass erase is also useful when users want to disable readout protection.
@end deffn
-@deffn {Flash Driver} cc26xx
+@deffn {Flash Driver} {cc26xx}
All versions of the SimpleLink CC13xx and CC26xx microcontrollers from Texas
Instruments include internal flash. The cc26xx flash driver supports both the
CC13xx and CC26xx family of devices. The driver automatically recognizes the
@@ -6131,7 +6117,7 @@ flash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME
@end example
@end deffn
-@deffn {Flash Driver} cc3220sf
+@deffn {Flash Driver} {cc3220sf}
The CC3220SF version of the SimpleLink CC32xx microcontrollers from Texas
Instruments includes 1MB of internal flash. The cc3220sf flash driver only
supports the internal flash. The serial flash on SimpleLink boards is
@@ -6145,7 +6131,7 @@ flash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME
@end example
@end deffn
-@deffn {Flash Driver} efm32
+@deffn {Flash Driver} {efm32}
All members of the EFM32 microcontroller family from Energy Micro include
internal flash and use ARM Cortex-M3 cores. The driver automatically recognizes
a number of these chips using the chip identification register, and
@@ -6165,7 +6151,7 @@ Note that in order for this command to take effect, the target needs to be reset
supported.}
@end deffn
-@deffn {Flash Driver} esirisc
+@deffn {Flash Driver} {esirisc}
Members of the eSi-RISC family may optionally include internal flash programmed
via the eSi-TSMC Flash interface. Additional parameters are required to
configure the driver: @option{cfg_address} is the base address of the
@@ -6177,17 +6163,17 @@ flash bank $_FLASHNAME esirisc base_address size_bytes 0 0 \
$_TARGETNAME cfg_address clock_hz wait_states
@end example
-@deffn Command {esirisc flash mass_erase} bank_id
+@deffn {Command} {esirisc flash mass_erase} bank_id
Erase all pages in data memory for the bank identified by @option{bank_id}.
@end deffn
-@deffn Command {esirisc flash ref_erase} bank_id
+@deffn {Command} {esirisc flash ref_erase} bank_id
Erase the reference cell for the bank identified by @option{bank_id}. @emph{This
is an uncommon operation.}
@end deffn
@end deffn
-@deffn {Flash Driver} fm3
+@deffn {Flash Driver} {fm3}
All members of the FM3 microcontroller family from Fujitsu
include internal flash and use ARM Cortex-M3 cores.
The @var{fm3} driver uses the @var{target} parameter to select the
@@ -6200,7 +6186,7 @@ flash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME
@end example
@end deffn
-@deffn {Flash Driver} fm4
+@deffn {Flash Driver} {fm4}
All members of the FM4 microcontroller family from Spansion (formerly Fujitsu)
include internal flash and use ARM Cortex-M4 cores.
The @var{fm4} driver uses a @var{family} parameter to select the
@@ -6220,7 +6206,7 @@ flash bank $@{_FLASHNAME@}1 fm4 0x00100000 0 0 0 \
nor is Chip Erase (only Sector Erase is implemented).}
@end deffn
-@deffn {Flash Driver} kinetis
+@deffn {Flash Driver} {kinetis}
@cindex kinetis
Kx, KLx, KVx and KE1x members of the Kinetis microcontroller family
from NXP (former Freescale) include
@@ -6238,13 +6224,13 @@ The @var{kinetis} driver defines option:
flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
@end example
-@deffn Command {kinetis create_banks}
+@deffn {Config Command} {kinetis create_banks}
Configuration command enables automatic creation of additional flash banks
based on real flash layout of device. Banks are created during device probe.
Use 'flash probe 0' to force probe.
@end deffn
-@deffn Command {kinetis fcf_source} [protection|write]
+@deffn {Command} {kinetis fcf_source} [protection|write]
Select what source is used when writing to a Flash Configuration Field.
@option{protection} mode builds FCF content from protection bits previously
set by 'flash protect' command.
@@ -6256,29 +6242,29 @@ with the rest of a flash image.
@emph{BEWARE: Incorrect flash configuration may permanently lock the device!}
@end deffn
-@deffn Command {kinetis fopt} [num]
+@deffn {Command} {kinetis fopt} [num]
Set value to write to FOPT byte of Flash Configuration Field.
Used in kinetis 'fcf_source protection' mode only.
@end deffn
-@deffn Command {kinetis mdm check_security}
+@deffn {Command} {kinetis mdm check_security}
Checks status of device security lock. Used internally in examine-end
and examine-fail event.
@end deffn
-@deffn Command {kinetis mdm halt}
+@deffn {Command} {kinetis mdm halt}
Issues a halt via the MDM-AP. This command can be used to break a watchdog reset
loop when connecting to an unsecured target.
@end deffn
-@deffn Command {kinetis mdm mass_erase}
+@deffn {Command} {kinetis mdm mass_erase}
Issues a complete flash erase via the MDM-AP. This can be used to erase a chip
back to its factory state, removing security. It does not require the processor
to be halted, however the target will remain in a halted state after this
command completes.
@end deffn
-@deffn Command {kinetis nvm_partition}
+@deffn {Command} {kinetis nvm_partition}
For FlexNVM devices only (KxxDX and KxxFX).
Command shows or sets data flash or EEPROM backup size in kilobytes,
sets two EEPROM blocks sizes in bytes and enables/disables loading
@@ -6308,18 +6294,18 @@ kinetis nvm_partition eebkp 16 1024 1024 off
@end example
@end deffn
-@deffn Command {kinetis mdm reset}
+@deffn {Command} {kinetis mdm reset}
Issues a reset via the MDM-AP. This causes the MCU to output a low pulse on the
RESET pin, which can be used to reset other hardware on board.
@end deffn
-@deffn Command {kinetis disable_wdog}
+@deffn {Command} {kinetis disable_wdog}
For Kx devices only (KLx has different COP watchdog, it is not supported).
Command disables watchdog timer.
@end deffn
@end deffn
-@deffn {Flash Driver} kinetis_ke
+@deffn {Flash Driver} {kinetis_ke}
@cindex kinetis_ke
KE0x and KEAx members of the Kinetis microcontroller family from NXP include
internal flash and use ARM Cortex-M0+. The driver automatically recognizes
@@ -6331,23 +6317,23 @@ Use kinetis (not kinetis_ke) driver for KE1x devices.
flash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME
@end example
-@deffn Command {kinetis_ke mdm check_security}
+@deffn {Command} {kinetis_ke mdm check_security}
Checks status of device security lock. Used internally in examine-end event.
@end deffn
-@deffn Command {kinetis_ke mdm mass_erase}
+@deffn {Command} {kinetis_ke mdm mass_erase}
Issues a complete Flash erase via the MDM-AP.
This can be used to erase a chip back to its factory state.
Command removes security lock from a device (use of SRST highly recommended).
It does not require the processor to be halted.
@end deffn
-@deffn Command {kinetis_ke disable_wdog}
+@deffn {Command} {kinetis_ke disable_wdog}
Command disables watchdog timer.
@end deffn
@end deffn
-@deffn {Flash Driver} lpc2000
+@deffn {Flash Driver} {lpc2000}
This is the driver to support internal flash of all members of the
LPC11(x)00 and LPC1300 microcontroller families and most members of
the LPC800, LPC1500, LPC1700, LPC1800, LPC2000, LPC4000, LPC54100,
@@ -6404,7 +6390,7 @@ the specified flash @var{bank}.
@end deffn
@end deffn
-@deffn {Flash Driver} lpc288x
+@deffn {Flash Driver} {lpc288x}
The LPC2888 microcontroller from NXP needs slightly different flash
support from its lpc2000 siblings.
The @var{lpc288x} driver defines one mandatory parameter,
@@ -6416,7 +6402,7 @@ flash bank $_FLASHNAME lpc288x 0 0 0 0 $_TARGETNAME 12000000
@end example
@end deffn
-@deffn {Flash Driver} lpc2900
+@deffn {Flash Driver} {lpc2900}
This driver supports the LPC29xx ARM968E based microcontroller family
from NXP.
@@ -6452,7 +6438,7 @@ Some @code{lpc2900}-specific commands are defined. In the following command list
the @var{bank} parameter is the bank number as obtained by the
@code{flash banks} command.
-@deffn Command {lpc2900 signature} bank
+@deffn {Command} {lpc2900 signature} bank
Calculates a 128-bit hash value, the @emph{signature}, from the whole flash
content. This is a hardware feature of the flash block, hence the calculation is
very fast. You may use this to verify the content of a programmed device against
@@ -6464,7 +6450,7 @@ lpc2900 signature 0
@end example
@end deffn
-@deffn Command {lpc2900 read_custom} bank filename
+@deffn {Command} {lpc2900 read_custom} bank filename
Reads the 912 bytes of customer information from the flash index sector, and
saves it to a file in binary format.
Example:
@@ -6478,7 +6464,7 @@ erased! In order to guard against unintentional write access, all following
commands need to be preceded by a successful call to the @code{password}
command:
-@deffn Command {lpc2900 password} bank password
+@deffn {Command} {lpc2900 password} bank password
You need to use this command right before each of the following commands:
@code{lpc2900 write_custom}, @code{lpc2900 secure_sector},
@code{lpc2900 secure_jtag}.
@@ -6491,7 +6477,7 @@ lpc2900 password 0 I_know_what_I_am_doing
@end example
@end deffn
-@deffn Command {lpc2900 write_custom} bank filename type
+@deffn {Command} {lpc2900 write_custom} bank filename type
Writes the content of the file into the customer info space of the flash index
sector. The filetype can be specified with the @var{type} field. Possible values
for @var{type} are: @var{bin} (binary), @var{ihex} (Intel hex format),
@@ -6507,7 +6493,7 @@ lpc2900 write_custom 0 /path_to/customer_info.bin bin
@end example
@end deffn
-@deffn Command {lpc2900 secure_sector} bank first last
+@deffn {Command} {lpc2900 secure_sector} bank first last
Secures the sector range from @var{first} to @var{last} (including) against
further program and erase operations. The sector security will be effective
after the next power cycle.
@@ -6526,7 +6512,7 @@ flash info 0
@end example
@end deffn
-@deffn Command {lpc2900 secure_jtag} bank
+@deffn {Command} {lpc2900 secure_jtag} bank
Irreversibly disable the JTAG port. The new JTAG security setting will be
effective after the next power cycle.
@quotation Attention
@@ -6539,7 +6525,7 @@ lpc2900 secure_jtag 0
@end deffn
@end deffn
-@deffn {Flash Driver} mdr
+@deffn {Flash Driver} {mdr}
This drivers handles the integrated NOR flash on Milandr Cortex-M
based controllers. A known limitation is that the Info memory can't be
read or verified as it's not memory mapped.
@@ -6567,7 +6553,7 @@ if @{ [info exists IMEMORY] && [string equal $IMEMORY true] @} @{
@end example
@end deffn
-@deffn {Flash Driver} msp432
+@deffn {Flash Driver} {msp432}
All versions of the SimpleLink MSP432 microcontrollers from Texas
Instruments include internal flash. The msp432 flash driver automatically
recognizes the specific version's flash parameters and autoconfigures itself.
@@ -6578,7 +6564,7 @@ MSP432P4 versions starts at address 0x200000.
flash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME
@end example
-@deffn Command {msp432 mass_erase} bank_id [main|all]
+@deffn {Command} {msp432 mass_erase} bank_id [main|all]
Performs a complete erase of flash. By default, @command{mass_erase} will erase
only the main program flash.
@@ -6587,7 +6573,7 @@ main program and information flash regions. To also erase the BSL in information
flash, the user must first use the @command{bsl} command.
@end deffn
-@deffn Command {msp432 bsl} bank_id [unlock|lock]
+@deffn {Command} {msp432 bsl} bank_id [unlock|lock]
On MSP432P4 versions, @command{bsl} unlocks and locks the bootstrap loader (BSL)
region in information flash so that flash commands can erase or write the BSL.
Leave the BSL locked to prevent accidentally corrupting the bootstrap loader.
@@ -6602,7 +6588,7 @@ msp432 bsl lock
@end deffn
@end deffn
-@deffn {Flash Driver} niietcm4
+@deffn {Flash Driver} {niietcm4}
This drivers handles the integrated NOR flash on NIIET Cortex-M4
based controllers. Flash size and sector layout are auto-configured by the driver.
Main flash memory is called "Bootflash" and has main region and info region.
@@ -6620,49 +6606,49 @@ flash bank $_FLASHNAME niietcm4 0 0 0 0 $_TARGETNAME
Some niietcm4-specific commands are defined:
-@deffn Command {niietcm4 uflash_read_byte} bank ('main'|'info') address
+@deffn {Command} {niietcm4 uflash_read_byte} bank ('main'|'info') address
Read byte from main or info userflash region.
@end deffn
-@deffn Command {niietcm4 uflash_write_byte} bank ('main'|'info') address value
+@deffn {Command} {niietcm4 uflash_write_byte} bank ('main'|'info') address value
Write byte to main or info userflash region.
@end deffn
-@deffn Command {niietcm4 uflash_full_erase} bank
+@deffn {Command} {niietcm4 uflash_full_erase} bank
Erase all userflash including info region.
@end deffn
-@deffn Command {niietcm4 uflash_erase} bank ('main'|'info') first_sector last_sector
+@deffn {Command} {niietcm4 uflash_erase} bank ('main'|'info') first_sector last_sector
Erase sectors of main or info userflash region, starting at sector first up to and including last.
@end deffn
-@deffn Command {niietcm4 uflash_protect_check} bank ('main'|'info')
+@deffn {Command} {niietcm4 uflash_protect_check} bank ('main'|'info')
Check sectors protect.
@end deffn
-@deffn Command {niietcm4 uflash_protect} bank ('main'|'info') first_sector last_sector ('on'|'off')
+@deffn {Command} {niietcm4 uflash_protect} bank ('main'|'info') first_sector last_sector ('on'|'off')
Protect sectors of main or info userflash region, starting at sector first up to and including last.
@end deffn
-@deffn Command {niietcm4 bflash_info_remap} bank ('on'|'off')
+@deffn {Command} {niietcm4 bflash_info_remap} bank ('on'|'off')
Enable remapping bootflash info region to 0x00000000 (or 0x40000000 if external memory boot used).
@end deffn
-@deffn Command {niietcm4 extmem_cfg} bank ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh') pin_num ('func1'|'func3')
+@deffn {Command} {niietcm4 extmem_cfg} bank ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh') pin_num ('func1'|'func3')
Configure external memory interface for boot.
@end deffn
-@deffn Command {niietcm4 service_mode_erase} bank
+@deffn {Command} {niietcm4 service_mode_erase} bank
Perform emergency erase of all flash (bootflash and userflash).
@end deffn
-@deffn Command {niietcm4 driver_info} bank
+@deffn {Command} {niietcm4 driver_info} bank
Show information about flash driver.
@end deffn
@end deffn
-@deffn {Flash Driver} nrf5
+@deffn {Flash Driver} {nrf5}
All members of the nRF51 microcontroller families from Nordic Semiconductor
include internal flash and use ARM Cortex-M0 core.
Also, the nRF52832 microcontroller from Nordic Semiconductor, which include
@@ -6674,20 +6660,20 @@ flash bank $_FLASHNAME nrf5 0 0x00000000 0 0 $_TARGETNAME
Some nrf5-specific commands are defined:
-@deffn Command {nrf5 mass_erase}
+@deffn {Command} {nrf5 mass_erase}
Erases the contents of the code memory and user information
configuration registers as well. It must be noted that this command
works only for chips that do not have factory pre-programmed region 0
code.
@end deffn
-@deffn Command {nrf5 info}
+@deffn {Command} {nrf5 info}
Decodes and shows information from FICR and UICR registers.
@end deffn
@end deffn
-@deffn {Flash Driver} ocl
+@deffn {Flash Driver} {ocl}
This driver is an implementation of the ``on chip flash loader''
protocol proposed by Pavel Chromy.
@@ -6701,7 +6687,7 @@ flash bank $_FLASHNAME ocl 0 0 0 0 $_TARGETNAME
@end example
@end deffn
-@deffn {Flash Driver} pic32mx
+@deffn {Flash Driver} {pic32mx}
The PIC32MX microcontrollers are based on the MIPS 4K cores,
and integrate flash memory.
@@ -6715,17 +6701,17 @@ flash bank $_FLASHNAME pix32mx 0x1d000000 0 0 0 $_TARGETNAME
@comment - lock, unlock ... pointless given protect on/off (yes?)
@comment - pgm_word ... shouldn't bank be deduced from address??
Some pic32mx-specific commands are defined:
-@deffn Command {pic32mx pgm_word} address value bank
+@deffn {Command} {pic32mx pgm_word} address value bank
Programs the specified 32-bit @var{value} at the given @var{address}
in the specified chip @var{bank}.
@end deffn
-@deffn Command {pic32mx unlock} bank
+@deffn {Command} {pic32mx unlock} bank
Unlock and erase specified chip @var{bank}.
This will remove any Code Protection.
@end deffn
@end deffn
-@deffn {Flash Driver} psoc4
+@deffn {Flash Driver} {psoc4}
All members of the PSoC 41xx/42xx microcontroller family from Cypress
include internal flash and use ARM Cortex-M0 cores.
The driver automatically recognizes a number of these chips using
@@ -6739,7 +6725,7 @@ flash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME
@end example
psoc4-specific commands
-@deffn Command {psoc4 flash_autoerase} num (on|off)
+@deffn {Command} {psoc4 flash_autoerase} num (on|off)
Enables or disables autoerase mode for a flash bank.
If flash_autoerase is off, use mass_erase before flash programming.
@@ -6752,14 +6738,14 @@ This mode is suitable for gdb load.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {psoc4 mass_erase} num
+@deffn {Command} {psoc4 mass_erase} num
Erases the contents of the flash memory, protection and security lock.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@end deffn
-@deffn {Flash Driver} psoc5lp
+@deffn {Flash Driver} {psoc5lp}
All members of the PSoC 5LP microcontroller family from Cypress
include internal program flash and use ARM Cortex-M3 cores.
The driver probes for a number of these chips and autoconfigures itself,
@@ -6779,13 +6765,13 @@ Writing to the ECC data bytes in ECC-disabled mode is not implemented.
Commands defined in the @var{psoc5lp} driver:
-@deffn Command {psoc5lp mass_erase}
+@deffn {Command} {psoc5lp mass_erase}
Erases all flash data and ECC/configuration bytes, all flash protection rows,
and all row latches in all flash arrays on the device.
@end deffn
@end deffn
-@deffn {Flash Driver} psoc5lp_eeprom
+@deffn {Flash Driver} {psoc5lp_eeprom}
All members of the PSoC 5LP microcontroller family from Cypress
include internal EEPROM and use ARM Cortex-M3 cores.
The driver probes for a number of these chips and autoconfigures itself,
@@ -6797,7 +6783,7 @@ flash bank $_CHIPNAME.eeprom psoc5lp_eeprom 0x40008000 0 0 0 \
@end example
@end deffn
-@deffn {Flash Driver} psoc5lp_nvl
+@deffn {Flash Driver} {psoc5lp_nvl}
All members of the PSoC 5LP microcontroller family from Cypress
include internal Nonvolatile Latches and use ARM Cortex-M3 cores.
The driver probes for a number of these chips and autoconfigures itself.
@@ -6822,7 +6808,7 @@ after successful write.
@end quotation
@end deffn
-@deffn {Flash Driver} psoc6
+@deffn {Flash Driver} {psoc6}
Supports PSoC6 (CY8C6xxx) family of Cypress microcontrollers.
PSoC6 is a dual-core device with CM0+ and CM4 cores. Both cores share
the same Flash/RAM/MMIO address space.
@@ -6875,7 +6861,7 @@ flash bank super_flash_toc2_cm4 psoc6 0x16007C00 0 0 0 \
@end example
psoc6-specific commands
-@deffn Command {psoc6 reset_halt}
+@deffn {Command} {psoc6 reset_halt}
Command can be used to simulate broken Vector Catch from gdbinit or tcl scripts.
When invoked for CM0+ target, it will set break point at application entry point
and issue SYSRESETREQ. This will reset both cores and all peripherals. CM0+ will
@@ -6883,14 +6869,25 @@ reset CM4 during boot anyway so this is safe. On CM4 target, VECTRESET is used
instead of SYSRESETREQ to avoid unwanted reset of CM0+;
@end deffn
-@deffn Command {psoc6 mass_erase} num
+@deffn {Command} {psoc6 mass_erase} num
Erases the contents given flash bank. The @var{num} parameter is a value shown
by @command{flash banks}.
Note: only Main and Work flash regions support Erase operation.
@end deffn
@end deffn
-@deffn {Flash Driver} sim3x
+@deffn {Flash Driver} {rp2040}
+Supports RP2040 "Raspberry Pi Pico" microcontroller.
+RP2040 is a dual-core device with two CM0+ cores. Both cores share the same
+Flash/RAM/MMIO address space. Non-volatile storage is achieved with an
+external QSPI flash; a Boot ROM provides helper functions.
+
+@example
+flash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME
+@end example
+@end deffn
+
+@deffn {Flash Driver} {sim3x}
All members of the SiM3 microcontroller family from Silicon Laboratories
include internal flash and use ARM Cortex-M3 cores. It supports both JTAG
and SWD interface.
@@ -6903,17 +6900,17 @@ flash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME
There are 2 commands defined in the @var{sim3x} driver:
-@deffn Command {sim3x mass_erase}
+@deffn {Command} {sim3x mass_erase}
Erases the complete flash. This is used to unlock the flash.
And this command is only possible when using the SWD interface.
@end deffn
-@deffn Command {sim3x lock}
+@deffn {Command} {sim3x lock}
Lock the flash. To unlock use the @command{sim3x mass_erase} command.
@end deffn
@end deffn
-@deffn {Flash Driver} stellaris
+@deffn {Flash Driver} {stellaris}
All members of the Stellaris LM3Sxxx, LM4x and Tiva C microcontroller
families from Texas Instruments include internal flash. The driver
automatically recognizes a number of these chips using the chip
@@ -6923,7 +6920,7 @@ identification register, and autoconfigures itself.
flash bank $_FLASHNAME stellaris 0 0 0 0 $_TARGETNAME
@end example
-@deffn Command {stellaris recover}
+@deffn {Command} {stellaris recover}
Performs the @emph{Recovering a "Locked" Device} procedure to restore
the flash and its associated nonvolatile registers to their factory
default values (erased). This is the only way to remove flash
@@ -6939,9 +6936,10 @@ applied to all of them.
@end deffn
@end deffn
-@deffn {Flash Driver} stm32f1x
+@deffn {Flash Driver} {stm32f1x}
All members of the STM32F0, STM32F1 and STM32F3 microcontroller families
-from STMicroelectronics include internal flash and use ARM Cortex-M0/M3/M4 cores.
+from STMicroelectronics and all members of the GD32F1x0 and GD32F3x0 microcontroller
+families from GigaDevice include internal flash and use ARM Cortex-M0/M3/M4 cores.
The driver automatically recognizes a number of these chips using
the chip identification register, and autoconfigures itself.
@@ -6965,35 +6963,35 @@ flash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME
Some stm32f1x-specific commands are defined:
-@deffn Command {stm32f1x lock} num
+@deffn {Command} {stm32f1x lock} num
Locks the entire stm32 device against reading.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32f1x unlock} num
+@deffn {Command} {stm32f1x unlock} num
Unlocks the entire stm32 device for reading. This command will cause
a mass erase of the entire stm32 device if previously locked.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32f1x mass_erase} num
+@deffn {Command} {stm32f1x mass_erase} num
Mass erases the entire stm32 device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32f1x options_read} num
+@deffn {Command} {stm32f1x options_read} num
Reads and displays active stm32 option bytes loaded during POR
or upon executing the @command{stm32f1x options_load} command.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32f1x options_write} num (@option{SWWDG}|@option{HWWDG}) (@option{RSTSTNDBY}|@option{NORSTSTNDBY}) (@option{RSTSTOP}|@option{NORSTSTOP}) (@option{USEROPT} user_data)
+@deffn {Command} {stm32f1x options_write} num (@option{SWWDG}|@option{HWWDG}) (@option{RSTSTNDBY}|@option{NORSTSTNDBY}) (@option{RSTSTOP}|@option{NORSTSTOP}) (@option{USEROPT} user_data)
Writes the stm32 option byte with the specified values.
The @var{num} parameter is a value shown by @command{flash banks}.
The @var{user_data} parameter is content of higher 16 bits of the option byte register (Data0 and Data1 as one 16bit number).
@end deffn
-@deffn Command {stm32f1x options_load} num
+@deffn {Command} {stm32f1x options_load} num
Generates a special kind of reset to re-load the stm32 option bytes written
by the @command{stm32f1x options_write} or @command{flash protect} commands
without having to power cycle the target. Not applicable to stm32f1x devices.
@@ -7001,7 +6999,7 @@ The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@end deffn
-@deffn {Flash Driver} stm32f2x
+@deffn {Flash Driver} {stm32f2x}
All members of the STM32F2, STM32F4 and STM32F7 microcontroller families from STMicroelectronics
include internal flash and use ARM Cortex-M3/M4/M7 cores.
The driver automatically recognizes a number of these chips using
@@ -7017,7 +7015,7 @@ as per the following example.
flash bank $_FLASHNAME stm32f2x 0x1FFF7800 0 0 0 $_TARGETNAME
@end example
-@deffn Command {stm32f2x otp } num (@option{enable}|@option{disable}|@option{show})
+@deffn {Command} {stm32f2x otp } num (@option{enable}|@option{disable}|@option{show})
Enables or disables OTP write commands for bank @var{num}.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@@ -7032,27 +7030,27 @@ flash bank $_FLASHNAME stm32f2x 0 0x20000 0 0 $_TARGETNAME
Some stm32f2x-specific commands are defined:
-@deffn Command {stm32f2x lock} num
+@deffn {Command} {stm32f2x lock} num
Locks the entire stm32 device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32f2x unlock} num
+@deffn {Command} {stm32f2x unlock} num
Unlocks the entire stm32 device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32f2x mass_erase} num
+@deffn {Command} {stm32f2x mass_erase} num
Mass erases the entire stm32f2x device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32f2x options_read} num
+@deffn {Command} {stm32f2x options_read} num
Reads and displays user options and (where implemented) boot_addr0, boot_addr1, optcr2.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32f2x options_write} num user_options boot_addr0 boot_addr1
+@deffn {Command} {stm32f2x options_write} num user_options boot_addr0 boot_addr1
Writes user options and (where implemented) boot_addr0 and boot_addr1 in raw format.
Warning: The meaning of the various bits depends on the device, always check datasheet!
The @var{num} parameter is a value shown by @command{flash banks}, @var{user_options} a
@@ -7060,13 +7058,13 @@ The @var{num} parameter is a value shown by @command{flash banks}, @var{user_opt
@var{boot_addr1} two halfwords (of FLASH_OPTCR1).
@end deffn
-@deffn Command {stm32f2x optcr2_write} num optcr2
+@deffn {Command} {stm32f2x optcr2_write} num optcr2
Writes FLASH_OPTCR2 options. Warning: Clearing PCROPi bits requires a full mass erase!
The @var{num} parameter is a value shown by @command{flash banks}, @var{optcr2} a 32-bit word.
@end deffn
@end deffn
-@deffn {Flash Driver} stm32h7x
+@deffn {Flash Driver} {stm32h7x}
All members of the STM32H7 microcontroller families from STMicroelectronics
include internal flash and use ARM Cortex-M7 core.
The driver automatically recognizes a number of these chips using
@@ -7086,22 +7084,22 @@ flash bank $_FLASHNAME stm32h7x 0 0x20000 0 0 $_TARGETNAME
Some stm32h7x-specific commands are defined:
-@deffn Command {stm32h7x lock} num
+@deffn {Command} {stm32h7x lock} num
Locks the entire stm32 device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32h7x unlock} num
+@deffn {Command} {stm32h7x unlock} num
Unlocks the entire stm32 device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32h7x mass_erase} num
+@deffn {Command} {stm32h7x mass_erase} num
Mass erases the entire stm32h7x device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32h7x option_read} num reg_offset
+@deffn {Command} {stm32h7x option_read} num reg_offset
Reads an option byte register from the stm32h7x device.
The @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset}
is the register offset of the option byte to read from the used bank registers' base.
@@ -7118,7 +7116,7 @@ stm32h7x option_read 1 0x38
@end example
@end deffn
-@deffn Command {stm32h7x option_write} num reg_offset value [reg_mask]
+@deffn {Command} {stm32h7x option_write} num reg_offset value [reg_mask]
Writes an option byte register of the stm32h7x device.
The @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset}
is the register offset of the option byte to write from the used bank register base,
@@ -7134,7 +7132,7 @@ stm32h7x option_write 0 0x20 0x8000000 0x8000000
@end deffn
@end deffn
-@deffn {Flash Driver} stm32lx
+@deffn {Flash Driver} {stm32lx}
All members of the STM32L0 and STM32L1 microcontroller families from STMicroelectronics
include internal flash and use ARM Cortex-M3 and Cortex-M0+ cores.
The driver automatically recognizes a number of these chips using
@@ -7156,17 +7154,17 @@ flash bank $_FLASHNAME stm32lx 0x08000000 0x20000 0 0 $_TARGETNAME
Some stm32lx-specific commands are defined:
-@deffn Command {stm32lx lock} num
+@deffn {Command} {stm32lx lock} num
Locks the entire stm32 device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32lx unlock} num
+@deffn {Command} {stm32lx unlock} num
Unlocks the entire stm32 device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32lx mass_erase} num
+@deffn {Command} {stm32lx mass_erase} num
Mass erases the entire stm32lx device (all flash banks and EEPROM
data). This is the only way to unlock a protected flash (unless RDP
Level is 2 which can't be unlocked at all).
@@ -7174,7 +7172,7 @@ The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@end deffn
-@deffn {Flash Driver} stm32l4x
+@deffn {Flash Driver} {stm32l4x}
All members of the STM32 G0, G4, L4, L4+, L5, WB and WL
microcontroller families from STMicroelectronics include internal flash
and use ARM Cortex-M0+, M4 and M33 cores.
@@ -7191,7 +7189,7 @@ as per the following example.
flash bank $_FLASHNAME stm32l4x 0x1FFF7000 0 0 0 $_TARGETNAME
@end example
-@deffn Command {stm32l4x otp} num (@option{enable}|@option{disable}|@option{show})
+@deffn {Command} {stm32l4x otp} num (@option{enable}|@option{disable}|@option{show})
Enables or disables OTP write commands for bank @var{num}.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@@ -7207,22 +7205,22 @@ flash bank $_FLASHNAME stm32l4x 0x08000000 0x40000 0 0 $_TARGETNAME
Some stm32l4x-specific commands are defined:
-@deffn Command {stm32l4x lock} num
+@deffn {Command} {stm32l4x lock} num
Locks the entire stm32 device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32l4x unlock} num
+@deffn {Command} {stm32l4x unlock} num
Unlocks the entire stm32 device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32l4x mass_erase} num
+@deffn {Command} {stm32l4x mass_erase} num
Mass erases the entire stm32l4x device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn Command {stm32l4x option_read} num reg_offset
+@deffn {Command} {stm32l4x option_read} num reg_offset
Reads an option byte register from the stm32l4x device.
The @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset}
is the register offset of the Option byte to read.
@@ -7239,7 +7237,7 @@ The above example will read out the FLASH_OPTR register which contains the RDP
option byte, Watchdog configuration, BOR level etc.
@end deffn
-@deffn Command {stm32l4x option_write} num reg_offset reg_mask
+@deffn {Command} {stm32l4x option_write} num reg_offset reg_mask
Write an option byte register of the stm32l4x device.
The @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset}
is the register offset of the Option byte to write, and @var{reg_mask} is the mask
@@ -7255,7 +7253,7 @@ Area A for bank 1. The above example set WRP1AR_END=255, WRP1AR_START=0.
This will effectively write protect all sectors in flash bank 1.
@end deffn
-@deffn Command {stm32l4x wrp_info} num [device_bank]
+@deffn {Command} {stm32l4x wrp_info} num [device_bank]
List the protected areas using WRP.
The @var{num} parameter is a value shown by @command{flash banks}.
@var{device_bank} parameter is optional, possible values 'bank1' or 'bank2',
@@ -7269,13 +7267,13 @@ write protected areas in a specific @var{device_bank}
@end deffn
-@deffn Command {stm32l4x option_load} num
+@deffn {Command} {stm32l4x option_load} num
Forces a re-load of the option byte registers. Will cause a system reset of the device.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@end deffn
-@deffn {Flash Driver} str7x
+@deffn {Flash Driver} {str7x}
All members of the STR7 microcontroller family from STMicroelectronics
include internal flash and use ARM7TDMI cores.
The @var{str7x} driver defines one mandatory parameter, @var{variant},
@@ -7286,13 +7284,13 @@ flash bank $_FLASHNAME str7x \
0x40000000 0x00040000 0 0 $_TARGETNAME STR71x
@end example
-@deffn Command {str7x disable_jtag} bank
+@deffn {Command} {str7x disable_jtag} bank
Activate the Debug/Readout protection mechanism
for the specified flash bank.
@end deffn
@end deffn
-@deffn {Flash Driver} str9x
+@deffn {Flash Driver} {str9x}
Most members of the STR9 microcontroller family from STMicroelectronics
include internal flash and use ARM966E cores.
The str9 needs the flash controller to be configured using
@@ -7303,7 +7301,7 @@ flash bank $_FLASHNAME str9x 0x40000000 0x00040000 0 0 $_TARGETNAME
str9x flash_config 0 4 2 0 0x80000
@end example
-@deffn Command {str9x flash_config} num bbsr nbbsr bbadr nbbadr
+@deffn {Command} {str9x flash_config} num bbsr nbbsr bbadr nbbadr
Configures the str9 flash controller.
The @var{num} parameter is a value shown by @command{flash banks}.
@@ -7317,7 +7315,7 @@ The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
-@deffn {Flash Driver} str9xpec
+@deffn {Flash Driver} {str9xpec}
@cindex str9xpec
Only use this driver for locking/unlocking the device or configuring the option bytes.
@@ -7364,55 +7362,55 @@ as mentioned above, just issue the commands above manually or from a telnet prom
Several str9xpec-specific commands are defined:
-@deffn Command {str9xpec disable_turbo} num
+@deffn {Command} {str9xpec disable_turbo} num
Restore the str9 into JTAG chain.
@end deffn
-@deffn Command {str9xpec enable_turbo} num
+@deffn {Command} {str9xpec enable_turbo} num
Enable turbo mode, will simply remove the str9 from the chain and talk
directly to the embedded flash controller.
@end deffn
-@deffn Command {str9xpec lock} num
+@deffn {Command} {str9xpec lock} num
Lock str9 device. The str9 will only respond to an unlock command that will
erase the device.
@end deffn
-@deffn Command {str9xpec part_id} num
+@deffn {Command} {str9xpec part_id} num
Prints the part identifier for bank @var{num}.
@end deffn
-@deffn Command {str9xpec options_cmap} num (@option{bank0}|@option{bank1})
+@deffn {Command} {str9xpec options_cmap} num (@option{bank0}|@option{bank1})
Configure str9 boot bank.
@end deffn
-@deffn Command {str9xpec options_lvdsel} num (@option{vdd}|@option{vdd_vddq})
+@deffn {Command} {str9xpec options_lvdsel} num (@option{vdd}|@option{vdd_vddq})
Configure str9 lvd source.
@end deffn
-@deffn Command {str9xpec options_lvdthd} num (@option{2.4v}|@option{2.7v})
+@deffn {Command} {str9xpec options_lvdthd} num (@option{2.4v}|@option{2.7v})
Configure str9 lvd threshold.
@end deffn
-@deffn Command {str9xpec options_lvdwarn} bank (@option{vdd}|@option{vdd_vddq})
+@deffn {Command} {str9xpec options_lvdwarn} bank (@option{vdd}|@option{vdd_vddq})
Configure str9 lvd reset warning source.
@end deffn
-@deffn Command {str9xpec options_read} num
+@deffn {Command} {str9xpec options_read} num
Read str9 option bytes.
@end deffn
-@deffn Command {str9xpec options_write} num
+@deffn {Command} {str9xpec options_write} num
Write str9 option bytes.
@end deffn
-@deffn Command {str9xpec unlock} num
+@deffn {Command} {str9xpec unlock} num
unlock str9 device.
@end deffn
@end deffn
-@deffn {Flash Driver} swm050
+@deffn {Flash Driver} {swm050}
@cindex swm050
All members of the swm050 microcontroller family from Foshan Synwit Tech.
@@ -7422,35 +7420,35 @@ flash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME
One swm050-specific command is defined:
-@deffn Command {swm050 mass_erase} bank_id
+@deffn {Command} {swm050 mass_erase} bank_id
Erases the entire flash bank.
@end deffn
@end deffn
-@deffn {Flash Driver} tms470
+@deffn {Flash Driver} {tms470}
Most members of the TMS470 microcontroller family from Texas Instruments
include internal flash and use ARM7TDMI cores.
This driver doesn't require the chip and bus width to be specified.
Some tms470-specific commands are defined:
-@deffn Command {tms470 flash_keyset} key0 key1 key2 key3
+@deffn {Command} {tms470 flash_keyset} key0 key1 key2 key3
Saves programming keys in a register, to enable flash erase and write commands.
@end deffn
-@deffn Command {tms470 osc_mhz} clock_mhz
+@deffn {Command} {tms470 osc_mhz} clock_mhz
Reports the clock speed, which is used to calculate timings.
@end deffn
-@deffn Command {tms470 plldis} (0|1)
+@deffn {Command} {tms470 plldis} (0|1)
Disables (@var{1}) or enables (@var{0}) use of the PLL to speed up
the flash clock.
@end deffn
@end deffn
-@deffn {Flash Driver} w600
+@deffn {Flash Driver} {w600}
W60x series Wi-Fi SoC from WinnerMicro
are designed with ARM Cortex-M3 and have 1M Byte QFLASH inside.
The @var{w600} driver uses the @var{target} parameter to select the
@@ -7461,22 +7459,22 @@ flash bank $_FLASHNAME w600 0x08000000 0 0 0 $_TARGETNAMEs
@end example
@end deffn
-@deffn {Flash Driver} xmc1xxx
+@deffn {Flash Driver} {xmc1xxx}
All members of the XMC1xxx microcontroller family from Infineon.
This driver does not require the chip and bus width to be specified.
@end deffn
-@deffn {Flash Driver} xmc4xxx
+@deffn {Flash Driver} {xmc4xxx}
All members of the XMC4xxx microcontroller family from Infineon.
This driver does not require the chip and bus width to be specified.
Some xmc4xxx-specific commands are defined:
-@deffn Command {xmc4xxx flash_password} bank_id passwd1 passwd2
+@deffn {Command} {xmc4xxx flash_password} bank_id passwd1 passwd2
Saves flash protection passwords which are used to lock the user flash
@end deffn
-@deffn Command {xmc4xxx flash_unprotect} bank_id user_level[0-1]
+@deffn {Command} {xmc4xxx flash_unprotect} bank_id user_level[0-1]
Removes Flash write protection from the selected user bank
@end deffn
@@ -7581,7 +7579,7 @@ for more information.
@end itemize
@end deffn
-@deffn Command {nand list}
+@deffn {Command} {nand list}
Prints a summary of each device declared
using @command{nand device}, numbered from zero.
Note that un-probed devices show no details.
@@ -7595,7 +7593,7 @@ Note that un-probed devices show no details.
@end example
@end deffn
-@deffn Command {nand probe} num
+@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}.
@@ -7605,7 +7603,7 @@ it with most other NAND commands.
@subsection Erasing, Reading, Writing to NAND Flash
-@deffn Command {nand dump} num filename offset length [oob_option]
+@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.
@@ -7642,7 +7640,7 @@ spare areas associated with each data page.
@end itemize
@end deffn
-@deffn Command {nand erase} num [offset length]
+@deffn {Command} {nand erase} num [offset length]
@cindex NAND erasing
@cindex NAND programming
Erases blocks on the specified NAND device, starting at the
@@ -7660,7 +7658,7 @@ 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...]
+@deffn {Command} {nand write} num filename offset [option...]
@cindex NAND writing
@cindex NAND programming
Writes binary data from the file into the specified NAND device,
@@ -7719,7 +7717,7 @@ the underlying driver from applying hardware ECC.
@end itemize
@end deffn
-@deffn Command {nand verify} num filename offset [option...]
+@deffn {Command} {nand verify} num filename offset [option...]
@cindex NAND verification
@cindex NAND programming
Verify the binary data in the file has been programmed to the
@@ -7748,7 +7746,7 @@ be removed in a future release.
@subsection Other NAND commands
@cindex NAND other commands
-@deffn Command {nand check_bad_blocks} num [offset length]
+@deffn {Command} {nand check_bad_blocks} num [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
@@ -7762,14 +7760,14 @@ 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
+@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 (@option{enable}|@option{disable})
+@deffn {Command} {nand raw_access} num (@option{enable}|@option{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}.
@@ -7794,7 +7792,7 @@ As noted above, the @command{nand device} command allows
driver-specific options and behaviors.
Some controllers also activate controller-specific commands.
-@deffn {NAND Driver} at91sam9
+@deffn {NAND Driver} {at91sam9}
This driver handles the NAND controllers found on AT91SAM9 family chips from
Atmel. It takes two extra parameters: address of the NAND chip;
address of the ECC controller.
@@ -7806,30 +7804,30 @@ AT91SAM9 chips support single-bit ECC hardware. The @code{write_page} and
disabled by using the @command{nand raw_access} command. There are four
additional commands that are needed to fully configure the AT91SAM9 NAND
controller. Two are optional; most boards use the same wiring for ALE/CLE:
-@deffn Command {at91sam9 cle} num addr_line
+@deffn {Config Command} {at91sam9 cle} num addr_line
Configure the address line used for latching commands. The @var{num}
parameter is the value shown by @command{nand list}.
@end deffn
-@deffn Command {at91sam9 ale} num addr_line
+@deffn {Config Command} {at91sam9 ale} num addr_line
Configure the address line used for latching addresses. The @var{num}
parameter is the value shown by @command{nand list}.
@end deffn
For the next two commands, it is assumed that the pins have already been
properly configured for input or output.
-@deffn Command {at91sam9 rdy_busy} num pio_base_addr pin
+@deffn {Config Command} {at91sam9 rdy_busy} num pio_base_addr pin
Configure the RDY/nBUSY input from the NAND device. The @var{num}
parameter is the value shown by @command{nand list}. @var{pio_base_addr}
is the base address of the PIO controller and @var{pin} is the pin number.
@end deffn
-@deffn Command {at91sam9 ce} num pio_base_addr pin
+@deffn {Config Command} {at91sam9 ce} num pio_base_addr pin
Configure the chip enable input to the NAND device. The @var{num}
parameter is the value shown by @command{nand list}. @var{pio_base_addr}
is the base address of the PIO controller and @var{pin} is the pin number.
@end deffn
@end deffn
-@deffn {NAND Driver} davinci
+@deffn {NAND Driver} {davinci}
This driver handles the NAND controllers found on DaVinci family
chips from Texas Instruments.
It takes three extra parameters:
@@ -7847,10 +7845,10 @@ to implement those ECC modes, unless they are disabled using
the @command{nand raw_access} command.
@end deffn
-@deffn {NAND Driver} lpc3180
+@deffn {NAND Driver} {lpc3180}
These controllers require an extra @command{nand device}
parameter: the clock rate used by the controller.
-@deffn Command {lpc3180 select} num [mlc|slc]
+@deffn {Command} {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}.
@@ -7863,12 +7861,12 @@ 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} mx3
+@deffn {NAND Driver} {mx3}
This driver handles the NAND controller in i.MX31. The mxc driver
should work for this chip as well.
@end deffn
-@deffn {NAND Driver} mxc
+@deffn {NAND Driver} {mxc}
This driver handles the NAND controller found in Freescale i.MX
chips. It has support for v1 (i.MX27 and i.MX31) and v2 (i.MX35).
The driver takes 3 extra arguments, chip (@option{mx27},
@@ -7878,13 +7876,13 @@ main area and spare area (@option{biswap}), defaults to off.
@example
nand device mx35.nand mxc imx35.cpu mx35 hwecc biswap
@end example
-@deffn Command {mxc biswap} bank_num [enable|disable]
+@deffn {Command} {mxc biswap} bank_num [enable|disable]
Turns on/off bad block information swapping from main area,
without parameter query status.
@end deffn
@end deffn
-@deffn {NAND Driver} orion
+@deffn {NAND Driver} {orion}
These controllers require an extra @command{nand device}
parameter: the address of the controller.
@example
@@ -7896,11 +7894,11 @@ or @code{read_page} methods, so @command{nand raw_access} won't
change any behavior.
@end deffn
-@deffn {NAND Driver} s3c2410
-@deffnx {NAND Driver} s3c2412
-@deffnx {NAND Driver} s3c2440
-@deffnx {NAND Driver} s3c2443
-@deffnx {NAND Driver} s3c6400
+@deffn {NAND Driver} {s3c2410}
+@deffnx {NAND Driver} {s3c2412}
+@deffnx {NAND Driver} {s3c2440}
+@deffnx {NAND Driver} {s3c2443}
+@deffnx {NAND Driver} {s3c6400}
These S3C family controllers don't have any special
@command{nand device} options, and don't define any
specialized commands.
@@ -7987,7 +7985,7 @@ Drivers may support PLD-specific options to the @command{pld device}
definition command, and may also define commands usable only with
that particular type of PLD.
-@deffn {FPGA Driver} virtex2 [no_jstart]
+@deffn {FPGA Driver} {virtex2} [no_jstart]
Virtex-II is a family of FPGAs sold by Xilinx.
It supports the IEEE 1532 standard for In-System Configuration (ISC).
@@ -8032,11 +8030,11 @@ port is 5555.
@section Server Commands
-@deffn {Command} exit
+@deffn {Command} {exit}
Exits the current telnet session.
@end deffn
-@deffn {Command} help [string]
+@deffn {Command} {help} [string]
With no parameters, prints help text for all commands.
Otherwise, prints each helptext containing @var{string}.
Not every command provides helptext.
@@ -8047,7 +8045,7 @@ In most cases, no such restriction is listed; this indicates commands
which are only available after the configuration stage has completed.
@end deffn
-@deffn Command sleep msec [@option{busy}]
+@deffn {Command} {sleep} msec [@option{busy}]
Wait for at least @var{msec} milliseconds before resuming.
If @option{busy} is passed, busy-wait instead of sleeping.
(This option is strongly discouraged.)
@@ -8055,7 +8053,7 @@ Useful in connection with script files
(@command{script} command and @command{target_name} configuration).
@end deffn
-@deffn Command shutdown [@option{error}]
+@deffn {Command} {shutdown} [@option{error}]
Close the OpenOCD server, disconnecting all clients (GDB, telnet,
other). If option @option{error} is used, OpenOCD will return a
non-zero exit code to the parent process.
@@ -8075,7 +8073,7 @@ or its replacement will be automatically executed before OpenOCD exits.
@end deffn
@anchor{debuglevel}
-@deffn Command debug_level [n]
+@deffn {Command} {debug_level} [n]
@cindex message level
Display debug level.
If @var{n} (from 0..4) is provided, then set it to that level.
@@ -8091,7 +8089,7 @@ file (which is normally the server's standard output).
@xref{Running}.
@end deffn
-@deffn Command echo [-n] message
+@deffn {Command} {echo} [-n] message
Logs a message at "user" priority.
Output @var{message} to stdout.
Option "-n" suppresses trailing newline.
@@ -8100,16 +8098,16 @@ echo "Downloading kernel -- please wait"
@end example
@end deffn
-@deffn Command log_output [filename | "default"]
+@deffn {Command} {log_output} [filename | "default"]
Redirect logging to @var{filename} or set it back to default output;
the default log output channel is stderr.
@end deffn
-@deffn Command add_script_search_dir [directory]
+@deffn {Command} {add_script_search_dir} [directory]
Add @var{directory} to the file/script search path.
@end deffn
-@deffn Command bindto [@var{name}]
+@deffn {Config Command} {bindto} [@var{name}]
Specify hostname or IPv4 address on which to listen for incoming
TCP/IP connections. By default, OpenOCD will listen on the loopback
interface only. If your network environment is safe, @code{bindto
@@ -8130,7 +8128,7 @@ various operations. The current target may be changed
by using @command{targets} command with the name of the
target which should become current.
-@deffn Command reg [(number|name) [(value|'force')]]
+@deffn {Command} {reg} [(number|name) [(value|'force')]]
Access a single register by @var{number} or by its @var{name}.
The target must generally be halted before access to CPU core
registers is allowed. Depending on the hardware, some other
@@ -8169,8 +8167,8 @@ Debug and trace infrastructure:
@end example
@end deffn
-@deffn Command halt [ms]
-@deffnx Command wait_halt [ms]
+@deffn {Command} {halt} [ms]
+@deffnx {Command} {wait_halt} [ms]
The @command{halt} command first sends a halt request to the target,
which @command{wait_halt} doesn't.
Otherwise these behave the same: wait up to @var{ms} milliseconds,
@@ -8204,22 +8202,22 @@ power consumption (because the CPU is needlessly clocked).
@end deffn
-@deffn Command resume [address]
+@deffn {Command} {resume} [address]
Resume the target at its current code position,
or the optional @var{address} if it is provided.
OpenOCD will wait 5 seconds for the target to resume.
@end deffn
-@deffn Command step [address]
+@deffn {Command} {step} [address]
Single-step the target at its current code position,
or the optional @var{address} if it is provided.
@end deffn
@anchor{resetcommand}
-@deffn Command reset
-@deffnx Command {reset run}
-@deffnx Command {reset halt}
-@deffnx Command {reset init}
+@deffn {Command} {reset}
+@deffnx {Command} {reset run}
+@deffnx {Command} {reset halt}
+@deffnx {Command} {reset init}
Perform as hard a reset as possible, using SRST if possible.
@emph{All defined targets will be reset, and target
events will fire during the reset sequence.}
@@ -8237,7 +8235,7 @@ The other options will not work on all systems.
@end itemize
@end deffn
-@deffn Command soft_reset_halt
+@deffn {Command} {soft_reset_halt}
Requesting target halt and executing a soft reset. This is often used
when a target cannot be reset and halted. The target, after reset is
released begins to execute code. OpenOCD attempts to stop the CPU and
@@ -8246,8 +8244,8 @@ the code that was executed may have left the hardware in an unknown
state.
@end deffn
-@deffn Command {adapter assert} [signal [assert|deassert signal]]
-@deffnx Command {adapter deassert} [signal [assert|deassert signal]]
+@deffn {Command} {adapter assert} [signal [assert|deassert signal]]
+@deffnx {Command} {adapter deassert} [signal [assert|deassert signal]]
Set values of reset signals.
Without parameters returns current status of the signals.
The @var{signal} parameter values may be
@@ -8293,10 +8291,10 @@ Please use their TARGET object siblings to avoid making assumptions
about what TAP is the current target, or about MMU configuration.
@end enumerate
-@deffn Command mdd [phys] addr [count]
-@deffnx Command mdw [phys] addr [count]
-@deffnx Command mdh [phys] addr [count]
-@deffnx Command mdb [phys] addr [count]
+@deffn {Command} {mdd} [phys] addr [count]
+@deffnx {Command} {mdw} [phys] addr [count]
+@deffnx {Command} {mdh} [phys] addr [count]
+@deffnx {Command} {mdb} [phys] addr [count]
Display contents of address @var{addr}, as
64-bit doublewords (@command{mdd}),
32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}),
@@ -8310,10 +8308,10 @@ If @var{count} is specified, displays that many units.
see the @code{mem2array} primitives.)
@end deffn
-@deffn Command mwd [phys] addr doubleword [count]
-@deffnx Command mww [phys] addr word [count]
-@deffnx Command mwh [phys] addr halfword [count]
-@deffnx Command mwb [phys] addr byte [count]
+@deffn {Command} {mwd} [phys] addr doubleword [count]
+@deffnx {Command} {mww} [phys] addr word [count]
+@deffnx {Command} {mwh} [phys] addr halfword [count]
+@deffnx {Command} {mwb} [phys] addr byte [count]
Writes the specified @var{doubleword} (64 bits), @var{word} (32 bits),
@var{halfword} (16 bits), or @var{byte} (8-bit) value,
at the specified address @var{addr}.
@@ -8329,17 +8327,17 @@ If @var{count} is specified, fills that many units of consecutive address.
@cindex image loading
@cindex image dumping
-@deffn Command {dump_image} filename address size
+@deffn {Command} {dump_image} filename address size
Dump @var{size} bytes of target memory starting at @var{address} to the
binary file named @var{filename}.
@end deffn
-@deffn Command {fast_load}
+@deffn {Command} {fast_load}
Loads an image stored in memory by @command{fast_load_image} to the
current target. Must be preceded by fast_load_image.
@end deffn
-@deffn Command {fast_load_image} filename address [@option{bin}|@option{ihex}|@option{elf}|@option{s19}]
+@deffn {Command} {fast_load_image} filename address [@option{bin}|@option{ihex}|@option{elf}|@option{s19}]
Normally you should be using @command{load_image} or GDB load. However, for
testing purposes or when I/O overhead is significant(OpenOCD running on an embedded
host), storing the image in memory and uploading the image to the target
@@ -8350,7 +8348,7 @@ target programming performance as I/O and target programming can easily be profi
separately.
@end deffn
-@deffn Command {load_image} filename address [[@option{bin}|@option{ihex}|@option{elf}|@option{s19}] @option{min_addr} @option{max_length}]
+@deffn {Command} {load_image} filename address [[@option{bin}|@option{ihex}|@option{elf}|@option{s19}] @option{min_addr} @option{max_length}]
Load image from file @var{filename} to target memory offset by @var{address} from its load address.
The file format may optionally be specified
(@option{bin}, @option{ihex}, @option{elf}, or @option{s19}).
@@ -8367,7 +8365,7 @@ proc load_image_bin @{fname foffset address length @} @{
@end example
@end deffn
-@deffn Command {test_image} filename [address [@option{bin}|@option{ihex}|@option{elf}]]
+@deffn {Command} {test_image} filename [address [@option{bin}|@option{ihex}|@option{elf}]]
Displays image section sizes and addresses
as if @var{filename} were loaded into target memory
starting at @var{address} (defaults to zero).
@@ -8375,14 +8373,14 @@ The file format may optionally be specified
(@option{bin}, @option{ihex}, or @option{elf})
@end deffn
-@deffn Command {verify_image} filename address [@option{bin}|@option{ihex}|@option{elf}]
+@deffn {Command} {verify_image} filename address [@option{bin}|@option{ihex}|@option{elf}]
Verify @var{filename} against target memory starting at @var{address}.
The file format may optionally be specified
(@option{bin}, @option{ihex}, or @option{elf})
This will first attempt a comparison using a CRC checksum, if this fails it will try a binary compare.
@end deffn
-@deffn Command {verify_image_checksum} filename address [@option{bin}|@option{ihex}|@option{elf}]
+@deffn {Command} {verify_image_checksum} filename address [@option{bin}|@option{ihex}|@option{elf}]
Verify @var{filename} against target memory starting at @var{address}.
The file format may optionally be specified
(@option{bin}, @option{ihex}, or @option{elf})
@@ -8399,7 +8397,7 @@ hardware support for a handful of code breakpoints and data
watchpoints.
In addition, CPUs almost always support software breakpoints.
-@deffn Command {bp} [address len [@option{hw}]]
+@deffn {Command} {bp} [address len [@option{hw}]]
With no parameters, lists all active breakpoints.
Else sets a breakpoint on code execution starting
at @var{address} for @var{length} bytes.
@@ -8410,15 +8408,15 @@ in which case it will be a hardware breakpoint.
for similar mechanisms that do not consume hardware breakpoints.)
@end deffn
-@deffn Command {rbp} @option{all} | address
+@deffn {Command} {rbp} @option{all} | address
Remove the breakpoint at @var{address} or all breakpoints.
@end deffn
-@deffn Command {rwp} address
+@deffn {Command} {rwp} address
Remove data watchpoint on @var{address}
@end deffn
-@deffn Command {wp} [address len [(@option{r}|@option{w}|@option{a}) [value [mask]]]]
+@deffn {Command} {wp} [address len [(@option{r}|@option{w}|@option{a}) [value [mask]]]]
With no parameters, lists all active watchpoints.
Else sets a data watchpoint on data from @var{address} for @var{length} bytes.
The watch point is an "access" watchpoint unless
@@ -8460,43 +8458,43 @@ Channels are exposed via raw TCP/IP connections. One or more RTT servers can be
assigned to each channel to make them accessible to an unlimited number
of TCP/IP connections.
-@deffn Command {rtt setup} address size ID
+@deffn {Command} {rtt setup} address size ID
Configure RTT for the currently selected target.
Once RTT is started, OpenOCD searches for a control block with the
identifier @var{ID} starting at the memory address @var{address} within the next
@var{size} bytes.
@end deffn
-@deffn Command {rtt start}
+@deffn {Command} {rtt start}
Start RTT.
If the control block location is not known, OpenOCD starts searching for it.
@end deffn
-@deffn Command {rtt stop}
+@deffn {Command} {rtt stop}
Stop RTT.
@end deffn
-@deffn Command {rtt polling_interval [interval]}
+@deffn {Command} {rtt polling_interval [interval]}
Display the polling interval.
If @var{interval} is provided, set the polling interval.
The polling interval determines (in milliseconds) how often the up-channels are
checked for new data.
@end deffn
-@deffn Command {rtt channels}
+@deffn {Command} {rtt channels}
Display a list of all channels and their properties.
@end deffn
-@deffn Command {rtt channellist}
+@deffn {Command} {rtt channellist}
Return a list of all channels and their properties as Tcl list.
The list can be manipulated easily from within scripts.
@end deffn
-@deffn Command {rtt server start} port channel
+@deffn {Command} {rtt server start} port channel
Start a TCP server on @var{port} for the channel @var{channel}.
@end deffn
-@deffn Command {rtt server stop} port
+@deffn {Command} {rtt server stop} port
Stop the TCP sever with port @var{port}.
@end deffn
@@ -8520,7 +8518,7 @@ TCP/IP port 9090.
@section Misc Commands
@cindex profiling
-@deffn Command {profile} seconds filename [start end]
+@deffn {Command} {profile} seconds filename [start end]
Profiling samples the CPU's program counter as quickly as possible,
which is useful for non-intrusive stochastic profiling.
Saves up to 10000 samples in @file{filename} using ``gmon.out''
@@ -8528,11 +8526,11 @@ format. Optional @option{start} and @option{end} parameters allow to
limit the address range.
@end deffn
-@deffn Command {version}
+@deffn {Command} {version}
Displays a string identifying the version of this OpenOCD server.
@end deffn
-@deffn Command {virt2phys} virtual_address
+@deffn {Command} {virt2phys} virtual_address
Requests the current target to map the specified @var{virtual_address}
to its corresponding physical address, and displays the result.
@end deffn
@@ -8641,21 +8639,21 @@ what CPU activities are traced.
@end quotation
@end deffn
-@deffn Command {etm info}
+@deffn {Command} {etm info}
Displays information about the current target's ETM.
This includes resource counts from the @code{ETM_CONFIG} register,
as well as silicon capabilities (except on rather old modules).
from the @code{ETM_SYS_CONFIG} register.
@end deffn
-@deffn Command {etm status}
+@deffn {Command} {etm status}
Displays status of the current target's ETM and trace port driver:
is the ETM idle, or is it collecting data?
Did trace data overflow?
Was it triggered?
@end deffn
-@deffn Command {etm tracemode} [type context_id_bits cycle_accurate branch_output]
+@deffn {Command} {etm tracemode} [type context_id_bits cycle_accurate branch_output]
Displays what data that ETM will collect.
If arguments are provided, first configures that data.
When the configuration changes, tracing is stopped
@@ -8679,7 +8677,7 @@ trace stream without an image of the code.
@end itemize
@end deffn
-@deffn Command {etm trigger_debug} (@option{enable}|@option{disable})
+@deffn {Command} {etm trigger_debug} (@option{enable}|@option{disable})
Displays whether ETM triggering debug entry (like a breakpoint) is
enabled or disabled, after optionally modifying that configuration.
The default behaviour is @option{disable}.
@@ -8726,28 +8724,28 @@ model with sequencer triggers which on entry and exit to the IRQ handler.
At this writing, September 2009, there are no Tcl utility
procedures to help set up any common tracing scenarios.
-@deffn Command {etm analyze}
+@deffn {Command} {etm analyze}
Reads trace data into memory, if it wasn't already present.
Decodes and prints the data that was collected.
@end deffn
-@deffn Command {etm dump} filename
+@deffn {Command} {etm dump} filename
Stores the captured trace data in @file{filename}.
@end deffn
-@deffn Command {etm image} filename [base_address] [type]
+@deffn {Command} {etm image} filename [base_address] [type]
Opens an image file.
@end deffn
-@deffn Command {etm load} filename
+@deffn {Command} {etm load} filename
Loads captured trace data from @file{filename}.
@end deffn
-@deffn Command {etm start}
+@deffn {Command} {etm start}
Starts trace data collection.
@end deffn
-@deffn Command {etm stop}
+@deffn {Command} {etm stop}
Stops trace data collection.
@end deffn
@@ -8756,7 +8754,7 @@ Stops trace data collection.
To use an ETM trace port it must be associated with a driver.
-@deffn {Trace Port Driver} dummy
+@deffn {Trace Port Driver} {dummy}
Use the @option{dummy} driver if you are configuring an ETM that's
not connected to anything (on-chip ETB or off-chip trace connector).
@emph{This driver lets OpenOCD talk to the ETM, but it does not expose
@@ -8766,14 +8764,14 @@ Associates the ETM for @var{target} with a dummy driver.
@end deffn
@end deffn
-@deffn {Trace Port Driver} etb
+@deffn {Trace Port Driver} {etb}
Use the @option{etb} driver if you are configuring an ETM
to use on-chip ETB memory.
@deffn {Config Command} {etb config} target etb_tap
Associates the ETM for @var{target} with the ETB at @var{etb_tap}.
You can see the ETB registers using the @command{reg} command.
@end deffn
-@deffn Command {etb trigger_percent} [percent]
+@deffn {Command} {etb trigger_percent} [percent]
This displays, or optionally changes, ETB behavior after the
ETM's configured @emph{trigger} event fires.
It controls how much more trace data is saved after the (single)
@@ -8808,7 +8806,7 @@ CTI is mandatory for core run control and each core has an individual
CTI instance attached to it. OpenOCD has limited support for CTI using
the @emph{cti} group of commands.
-@deffn Command {cti create} cti_name @option{-dap} dap_name @option{-ap-num} apn @option{-baseaddr} base_address
+@deffn {Command} {cti create} cti_name @option{-dap} dap_name @option{-ap-num} apn @option{-baseaddr} base_address
Creates a CTI instance @var{cti_name} on the DAP instance @var{dap_name} on MEM-AP
@var{apn}. The @var{base_address} must match the base address of the CTI
on the respective MEM-AP. All arguments are mandatory. This creates a
@@ -8816,37 +8814,37 @@ new command @command{$cti_name} which is used for various purposes
including additional configuration.
@end deffn
-@deffn Command {$cti_name enable} @option{on|off}
+@deffn {Command} {$cti_name enable} @option{on|off}
Enable (@option{on}) or disable (@option{off}) the CTI.
@end deffn
-@deffn Command {$cti_name dump}
+@deffn {Command} {$cti_name dump}
Displays a register dump of the CTI.
@end deffn
-@deffn Command {$cti_name write } @var{reg_name} @var{value}
+@deffn {Command} {$cti_name write } @var{reg_name} @var{value}
Write @var{value} to the CTI register with the symbolic name @var{reg_name}.
@end deffn
-@deffn Command {$cti_name read} @var{reg_name}
+@deffn {Command} {$cti_name read} @var{reg_name}
Print the value read from the CTI register with the symbolic name @var{reg_name}.
@end deffn
-@deffn Command {$cti_name ack} @var{event}
+@deffn {Command} {$cti_name ack} @var{event}
Acknowledge a CTI @var{event}.
@end deffn
-@deffn Command {$cti_name channel} @var{channel_number} @var{operation}
+@deffn {Command} {$cti_name channel} @var{channel_number} @var{operation}
Perform a specific channel operation, the possible operations are:
gate, ungate, set, clear and pulse
@end deffn
-@deffn Command {$cti_name testmode} @option{on|off}
+@deffn {Command} {$cti_name testmode} @option{on|off}
Enable (@option{on}) or disable (@option{off}) the integration test mode
of the CTI.
@end deffn
-@deffn Command {cti names}
+@deffn {Command} {cti names}
Prints a list of names of all CTI objects created. This command is mainly
useful in TCL scripting.
@end deffn
@@ -8858,7 +8856,7 @@ These commands should be available on all ARM processors.
They are available in addition to other core-specific
commands that may be available.
-@deffn Command {arm core_state} [@option{arm}|@option{thumb}]
+@deffn {Command} {arm core_state} [@option{arm}|@option{thumb}]
Displays the core_state, optionally changing it to process
either @option{arm} or @option{thumb} instructions.
The target may later be resumed in the currently set core_state.
@@ -8866,7 +8864,7 @@ The target may later be resumed in the currently set core_state.
that is not currently supported in OpenOCD.)
@end deffn
-@deffn Command {arm disassemble} address [count [@option{thumb}]]
+@deffn {Command} {arm disassemble} address [count [@option{thumb}]]
@cindex disassemble
Disassembles @var{count} instructions starting at @var{address}.
If @var{count} is not specified, a single instruction is disassembled.
@@ -8884,7 +8882,7 @@ with a handful of exceptions.
ThumbEE disassembly currently has no explicit support.
@end deffn
-@deffn Command {arm mcr} pX op1 CRn CRm op2 value
+@deffn {Command} {arm mcr} pX op1 CRn CRm op2 value
Write @var{value} to a coprocessor @var{pX} register
passing parameters @var{CRn},
@var{CRm}, opcodes @var{opc1} and @var{opc2},
@@ -8893,7 +8891,7 @@ and using the MCR instruction.
an ARM register.)
@end deffn
-@deffn Command {arm mrc} pX coproc op1 CRn CRm op2
+@deffn {Command} {arm mrc} pX coproc op1 CRn CRm op2
Read a coprocessor @var{pX} register passing parameters @var{CRn},
@var{CRm}, opcodes @var{opc1} and @var{opc2},
and the MRC instruction.
@@ -8902,12 +8900,12 @@ Returns the result so it can be manipulated by Jim scripts.
an ARM register.)
@end deffn
-@deffn Command {arm reg}
+@deffn {Command} {arm reg}
Display a table of all banked core registers, fetching the current value from every
core mode if necessary.
@end deffn
-@deffn Command {arm semihosting} [@option{enable}|@option{disable}]
+@deffn {Command} {arm semihosting} [@option{enable}|@option{disable}]
@cindex ARM semihosting
Display status of semihosting, after optionally changing that status.
@@ -8919,7 +8917,7 @@ requests by using a special SVC instruction that is trapped at the
Supervisor Call vector by OpenOCD.
@end deffn
-@deffn Command {arm semihosting_cmdline} [@option{enable}|@option{disable}]
+@deffn {Command} {arm semihosting_cmdline} [@option{enable}|@option{disable}]
@cindex ARM semihosting
Set the command line to be passed to the debugger.
@@ -8933,7 +8931,7 @@ standard C environment (argv[0]). Depending on the program (not much
programs look at argv[0]), argv0 is ignored and can be any string.
@end deffn
-@deffn Command {arm semihosting_fileio} [@option{enable}|@option{disable}]
+@deffn {Command} {arm semihosting_fileio} [@option{enable}|@option{disable}]
@cindex ARM semihosting
Display status of semihosting fileio, after optionally changing that
status.
@@ -8944,7 +8942,7 @@ interacting with remote files or displaying console messages in the
debugger.
@end deffn
-@deffn Command {arm semihosting_resexit} [@option{enable}|@option{disable}]
+@deffn {Command} {arm semihosting_resexit} [@option{enable}|@option{disable}]
@cindex ARM semihosting
Enable resumable SEMIHOSTING_SYS_EXIT.
@@ -8986,7 +8984,7 @@ ARM9TDMI, ARM920T or ARM926EJ-S.
They are available in addition to the ARM commands,
and any other core-specific commands that may be available.
-@deffn Command {arm7_9 dbgrq} [@option{enable}|@option{disable}]
+@deffn {Command} {arm7_9 dbgrq} [@option{enable}|@option{disable}]
Displays the value of the flag controlling use of the
EmbeddedIce DBGRQ signal to force entry into debug mode,
instead of breakpoints.
@@ -8998,7 +8996,7 @@ This feature is enabled by default on most ARM9 cores,
including ARM9TDMI, ARM920T, and ARM926EJ-S.
@end deffn
-@deffn Command {arm7_9 dcc_downloads} [@option{enable}|@option{disable}]
+@deffn {Command} {arm7_9 dcc_downloads} [@option{enable}|@option{disable}]
@cindex DCC
Displays the value of the flag controlling use of the debug communications
channel (DCC) to write larger (>128 byte) amounts of memory.
@@ -9009,7 +9007,7 @@ unsafe, especially with targets running at very low speeds. This command was int
with OpenOCD rev. 60, and requires a few bytes of working area.
@end deffn
-@deffn Command {arm7_9 fast_memory_access} [@option{enable}|@option{disable}]
+@deffn {Command} {arm7_9 fast_memory_access} [@option{enable}|@option{disable}]
Displays the value of the flag controlling use of memory writes and reads
that don't check completion of the operation.
If a boolean parameter is provided, first assigns that flag.
@@ -9032,7 +9030,7 @@ Such cores include the ARM920T, ARM926EJ-S, and ARM966.
@c versions have different rules about when they commit writes.
@anchor{arm9vectorcatch}
-@deffn Command {arm9 vector_catch} [@option{all}|@option{none}|list]
+@deffn {Command} {arm9 vector_catch} [@option{all}|@option{none}|list]
@cindex vector_catch
Vector Catch hardware provides a sort of dedicated breakpoint
for hardware events such as reset, interrupt, and abort.
@@ -9059,12 +9057,12 @@ built using the ARM9TDMI integer core.
They are available in addition to the ARM, ARM7/ARM9,
and ARM9 commands.
-@deffn Command {arm920t cache_info}
+@deffn {Command} {arm920t cache_info}
Print information about the caches found. This allows to see whether your target
is an ARM920T (2x16kByte cache) or ARM922T (2x8kByte cache).
@end deffn
-@deffn Command {arm920t cp15} regnum [value]
+@deffn {Command} {arm920t cp15} regnum [value]
Display cp15 register @var{regnum};
else if a @var{value} is provided, that value is written to that register.
This uses "physical access" and the register number is as
@@ -9072,11 +9070,11 @@ shown in bits 38..33 of table 9-9 in the ARM920T TRM.
(Not all registers can be written.)
@end deffn
-@deffn Command {arm920t read_cache} filename
+@deffn {Command} {arm920t read_cache} filename
Dump the content of ICache and DCache to a file named @file{filename}.
@end deffn
-@deffn Command {arm920t read_mmu} filename
+@deffn {Command} {arm920t read_mmu} filename
Dump the content of the ITLB and DTLB to a file named @file{filename}.
@end deffn
@@ -9092,7 +9090,7 @@ and ARM9 commands.
The Feroceon cores also support these commands, although
they are not built from ARM926ej-s designs.
-@deffn Command {arm926ejs cache_info}
+@deffn {Command} {arm926ejs cache_info}
Print information about the caches found.
@end deffn
@@ -9104,7 +9102,7 @@ which are implementations of the ARMv5TE architecture.
They are available in addition to the ARM, ARM7/ARM9,
and ARM9 commands.
-@deffn Command {arm966e cp15} regnum [value]
+@deffn {Command} {arm966e cp15} regnum [value]
Display cp15 register @var{regnum};
else if a @var{value} is provided, that value is written to that register.
The six bit @var{regnum} values are bits 37..32 from table 7-2 of the
@@ -9192,50 +9190,50 @@ length of four, or one watchpoint with a length greater than four.
These commands are available to XScale based CPUs,
which are implementations of the ARMv5TE architecture.
-@deffn Command {xscale analyze_trace}
+@deffn {Command} {xscale analyze_trace}
Displays the contents of the trace buffer.
@end deffn
-@deffn Command {xscale cache_clean_address} address
+@deffn {Command} {xscale cache_clean_address} address
Changes the address used when cleaning the data cache.
@end deffn
-@deffn Command {xscale cache_info}
+@deffn {Command} {xscale cache_info}
Displays information about the CPU caches.
@end deffn
-@deffn Command {xscale cp15} regnum [value]
+@deffn {Command} {xscale cp15} regnum [value]
Display cp15 register @var{regnum};
else if a @var{value} is provided, that value is written to that register.
@end deffn
-@deffn Command {xscale debug_handler} target address
+@deffn {Command} {xscale debug_handler} target address
Changes the address used for the specified target's debug handler.
@end deffn
-@deffn Command {xscale dcache} [@option{enable}|@option{disable}]
+@deffn {Command} {xscale dcache} [@option{enable}|@option{disable}]
Enables or disable the CPU's data cache.
@end deffn
-@deffn Command {xscale dump_trace} filename
+@deffn {Command} {xscale dump_trace} filename
Dumps the raw contents of the trace buffer to @file{filename}.
@end deffn
-@deffn Command {xscale icache} [@option{enable}|@option{disable}]
+@deffn {Command} {xscale icache} [@option{enable}|@option{disable}]
Enables or disable the CPU's instruction cache.
@end deffn
-@deffn Command {xscale mmu} [@option{enable}|@option{disable}]
+@deffn {Command} {xscale mmu} [@option{enable}|@option{disable}]
Enables or disable the CPU's memory management unit.
@end deffn
-@deffn Command {xscale trace_buffer} [@option{enable}|@option{disable} [@option{fill} [n] | @option{wrap}]]
+@deffn {Command} {xscale trace_buffer} [@option{enable}|@option{disable} [@option{fill} [n] | @option{wrap}]]
Displays the trace buffer status, after optionally
enabling or disabling the trace buffer
and modifying how it is emptied.
@end deffn
-@deffn Command {xscale trace_image} filename [offset [type]]
+@deffn {Command} {xscale trace_image} filename [offset [type]]
Opens a trace image from @file{filename}, optionally rebasing
its segment addresses by @var{offset}.
The image @var{type} may be one of
@@ -9245,7 +9243,7 @@ The image @var{type} may be one of
@end deffn
@anchor{xscalevectorcatch}
-@deffn Command {xscale vector_catch} [mask]
+@deffn {Command} {xscale vector_catch} [mask]
@cindex vector_catch
Display a bitmask showing the hardware vectors to catch.
If the optional parameter is provided, first set the bitmask to that value.
@@ -9263,7 +9261,7 @@ The mask bits correspond with bit 16..23 in the DCSR:
@end example
@end deffn
-@deffn Command {xscale vector_table} [(@option{low}|@option{high}) index value]
+@deffn {Command} {xscale vector_table} [(@option{low}|@option{high}) index value]
@cindex vector_table
Set an entry in the mini-IC vector table. There are two tables: one for
@@ -9282,7 +9280,7 @@ Without arguments, the current settings are displayed.
@subsection ARM11 specific commands
@cindex ARM11
-@deffn Command {arm11 memwrite burst} [@option{enable}|@option{disable}]
+@deffn {Command} {arm11 memwrite burst} [@option{enable}|@option{disable}]
Displays the value of the memwrite burst-enable flag,
which is enabled by default.
If a boolean parameter is provided, first assigns that flag.
@@ -9293,21 +9291,21 @@ instead of polling for a status flag to verify that completion.
This is usually safe, because JTAG runs much slower than the CPU.
@end deffn
-@deffn Command {arm11 memwrite error_fatal} [@option{enable}|@option{disable}]
+@deffn {Command} {arm11 memwrite error_fatal} [@option{enable}|@option{disable}]
Displays the value of the memwrite error_fatal flag,
which is enabled by default.
If a boolean parameter is provided, first assigns that flag.
When set, certain memory write errors cause earlier transfer termination.
@end deffn
-@deffn Command {arm11 step_irq_enable} [@option{enable}|@option{disable}]
+@deffn {Command} {arm11 step_irq_enable} [@option{enable}|@option{disable}]
Displays the value of the flag controlling whether
IRQs are enabled during single stepping;
they are disabled by default.
If a boolean parameter is provided, first assigns that.
@end deffn
-@deffn Command {arm11 vcr} [value]
+@deffn {Command} {arm11 vcr} [value]
@cindex vector_catch
Displays the value of the @emph{Vector Catch Register (VCR)},
coprocessor 14 register 7.
@@ -9327,39 +9325,39 @@ cores @emph{except the ARM1176} use the same six bits.
@subsection ARMv7-A specific commands
@cindex Cortex-A
-@deffn Command {cortex_a cache_info}
+@deffn {Command} {cortex_a cache_info}
display information about target caches
@end deffn
-@deffn Command {cortex_a dacrfixup [@option{on}|@option{off}]}
+@deffn {Command} {cortex_a dacrfixup [@option{on}|@option{off}]}
Work around issues with software breakpoints when the program text is
mapped read-only by the operating system. This option sets the CP15 DACR
to "all-manager" to bypass MMU permission checks on memory access.
Defaults to 'off'.
@end deffn
-@deffn Command {cortex_a dbginit}
+@deffn {Command} {cortex_a dbginit}
Initialize core debug
Enables debug by unlocking the Software Lock and clearing sticky powerdown indications
@end deffn
-@deffn Command {cortex_a smp} [on|off]
+@deffn {Command} {cortex_a smp} [on|off]
Display/set the current SMP mode
@end deffn
-@deffn Command {cortex_a smp_gdb} [core_id]
+@deffn {Command} {cortex_a smp_gdb} [core_id]
Display/set the current core displayed in GDB
@end deffn
-@deffn Command {cortex_a maskisr} [@option{on}|@option{off}]
+@deffn {Command} {cortex_a maskisr} [@option{on}|@option{off}]
Selects whether interrupts will be processed when single stepping
@end deffn
-@deffn Command {cache_config l2x} [base way]
+@deffn {Command} {cache_config l2x} [base way]
configure l2x cache
@end deffn
-@deffn Command {cortex_a mmu dump} [@option{0}|@option{1}|@option{addr} address [@option{num_entries}]]
+@deffn {Command} {cortex_a mmu dump} [@option{0}|@option{1}|@option{addr} address [@option{num_entries}]]
Dump the MMU translation table from TTB0 or TTB1 register, or from physical
memory location @var{address}. When dumping the table from @var{address}, print at most
@var{num_entries} page table entries. @var{num_entries} is optional, if omitted, the maximum
@@ -9369,12 +9367,12 @@ possible (4096) entries are printed.
@subsection ARMv7-R specific commands
@cindex Cortex-R
-@deffn Command {cortex_r dbginit}
+@deffn {Command} {cortex_r dbginit}
Initialize core debug
Enables debug by unlocking the Software Lock and clearing sticky powerdown indications
@end deffn
-@deffn Command {cortex_r maskisr} [@option{on}|@option{off}]
+@deffn {Command} {cortex_r maskisr} [@option{on}|@option{off}]
Selects whether interrupts will be processed when single stepping
@end deffn
@@ -9401,12 +9399,12 @@ The @command{tpiu} is used for either TPIU or SWO.
A convenient alias @command{swo} is available to help distinguish, in scripts,
the commands for SWO from the commands for TPIU.
-@deffn Command {swo} ...
+@deffn {Command} {swo} ...
Alias of @command{tpiu ...}. Can be used in scripts to distinguish the commands
for SWO from the commands for TPIU.
@end deffn
-@deffn Command {tpiu create} tpiu_name configparams...
+@deffn {Command} {tpiu create} tpiu_name configparams...
Creates a TPIU or a SWO object. The two commands are equivalent.
Add the object in a list and add new commands (@command{@var{tpiu_name}})
which are used for various purposes including additional configuration.
@@ -9422,23 +9420,23 @@ You @emph{must} set here the AP and MEM_AP base_address through @code{-dap @var{
@end itemize
@end deffn
-@deffn Command {tpiu names}
+@deffn {Command} {tpiu names}
Lists all the TPIU or SWO objects created so far. The two commands are equivalent.
@end deffn
-@deffn Command {tpiu init}
+@deffn {Command} {tpiu init}
Initialize all registered TPIU and SWO. The two commands are equivalent.
These commands are used internally during initialization. They can be issued
at any time after the initialization, too.
@end deffn
-@deffn Command {$tpiu_name cget} queryparm
+@deffn {Command} {$tpiu_name cget} queryparm
Each configuration parameter accepted by @command{$tpiu_name configure} can be
individually queried, to return its current value.
The @var{queryparm} is a parameter name accepted by that command, such as @code{-dap}.
@end deffn
-@deffn Command {$tpiu_name configure} configparams...
+@deffn {Command} {$tpiu_name configure} configparams...
The options accepted by this command may also be specified as parameters
to @command{tpiu create}. Their values can later be queried one at a time by
using the @command{$tpiu_name cget} command.
@@ -9504,7 +9502,7 @@ default value is @var{0}.
@end itemize
@end deffn
-@deffn Command {$tpiu_name enable}
+@deffn {Command} {$tpiu_name enable}
Uses the parameters specified by the previous @command{$tpiu_name configure}
to configure and enable the TPIU or the SWO.
If required, the adapter is also configured and enabled to receive the trace
@@ -9513,7 +9511,7 @@ This command can be used before @command{init}, but it will take effect only
after the @command{init}.
@end deffn
-@deffn Command {$tpiu_name disable}
+@deffn {Command} {$tpiu_name disable}
Disable the TPIU or the SWO, terminating the receiving of the trace data.
@end deffn
@@ -9561,19 +9559,19 @@ openocd -f interface/stlink.cfg \
@cindex ITM
@cindex ETM
-@deffn Command {itm port} @var{port} (@option{0}|@option{1}|@option{on}|@option{off})
+@deffn {Command} {itm port} @var{port} (@option{0}|@option{1}|@option{on}|@option{off})
Enable or disable trace output for ITM stimulus @var{port} (counting
from 0). Port 0 is enabled on target creation automatically.
@end deffn
-@deffn Command {itm ports} (@option{0}|@option{1}|@option{on}|@option{off})
+@deffn {Command} {itm ports} (@option{0}|@option{1}|@option{on}|@option{off})
Enable or disable trace output for all ITM stimulus ports.
@end deffn
@subsection Cortex-M specific commands
@cindex Cortex-M
-@deffn Command {cortex_m maskisr} (@option{auto}|@option{on}|@option{off}|@option{steponly})
+@deffn {Command} {cortex_m maskisr} (@option{auto}|@option{on}|@option{off}|@option{steponly})
Control masking (disabling) interrupts during target step/resume.
The @option{auto} option handles interrupts during stepping in a way that they
@@ -9596,7 +9594,7 @@ does.
Default is @option{auto}.
@end deffn
-@deffn Command {cortex_m vector_catch} [@option{all}|@option{none}|list]
+@deffn {Command} {cortex_m vector_catch} [@option{all}|@option{none}|list]
@cindex vector_catch
Vector Catch hardware provides dedicated breakpoints
for certain hardware events.
@@ -9623,7 +9621,7 @@ must also be explicitly enabled.
This finishes by listing the current vector catch configuration.
@end deffn
-@deffn Command {cortex_m reset_config} (@option{sysresetreq}|@option{vectreset})
+@deffn {Command} {cortex_m reset_config} (@option{sysresetreq}|@option{vectreset})
Control reset handling if hardware srst is not fitted
@xref{reset_config,,reset_config}.
@@ -9646,11 +9644,11 @@ instead.
@cindex ARMv8-A
@cindex aarch64
-@deffn Command {aarch64 cache_info}
+@deffn {Command} {aarch64 cache_info}
Display information about target caches
@end deffn
-@deffn Command {aarch64 dbginit}
+@deffn {Command} {aarch64 dbginit}
This command enables debugging by clearing the OS Lock and sticky power-down and reset
indications. It also establishes the expected, basic cross-trigger configuration the aarch64
target code relies on. In a configuration file, the command would typically be called from a
@@ -9658,25 +9656,25 @@ target code relies on. In a configuration file, the command would typically be c
However, normally it is not necessary to use the command at all.
@end deffn
-@deffn Command {aarch64 disassemble} address [count]
+@deffn {Command} {aarch64 disassemble} address [count]
@cindex disassemble
Disassembles @var{count} instructions starting at @var{address}.
If @var{count} is not specified, a single instruction is disassembled.
@end deffn
-@deffn Command {aarch64 smp} [on|off]
+@deffn {Command} {aarch64 smp} [on|off]
Display, enable or disable SMP handling mode. The state of SMP handling influences the way targets in an SMP group
are handled by the run control. With SMP handling enabled, issuing halt or resume to one core will trigger
halting or resuming of all cores in the group. The command @code{target smp} defines which targets are in the SMP
group. With SMP handling disabled, all targets need to be treated individually.
@end deffn
-@deffn Command {aarch64 maskisr} [@option{on}|@option{off}]
+@deffn {Command} {aarch64 maskisr} [@option{on}|@option{off}]
Selects whether interrupts will be processed when single stepping. The default configuration is
@option{on}.
@end deffn
-@deffn Command {$target_name catch_exc} [@option{off}|@option{sec_el1}|@option{sec_el3}|@option{nsec_el1}|@option{nsec_el2}]+
+@deffn {Command} {$target_name catch_exc} [@option{off}|@option{sec_el1}|@option{sec_el3}|@option{nsec_el1}|@option{nsec_el2}]+
Cause @command{$target_name} to halt when an exception is taken. Any combination of
Secure (sec) EL1/EL3 or Non-Secure (nsec) EL1/EL2 is valid. The target
@command{$target_name} will halt before taking the exception. In order to resume
@@ -9691,12 +9689,12 @@ provided by EnSilica. (See: @url{http://www.ensilica.com/risc-ip/}.)
@subsection eSi-RISC Configuration
-@deffn Command {esirisc cache_arch} (@option{harvard}|@option{von_neumann})
+@deffn {Command} {esirisc cache_arch} (@option{harvard}|@option{von_neumann})
Configure the caching architecture. Targets with the @code{UNIFIED_ADDRESS_SPACE}
option disabled employ a Harvard architecture. By default, @option{von_neumann} is assumed.
@end deffn
-@deffn Command {esirisc hwdc} (@option{all}|@option{none}|mask ...)
+@deffn {Command} {esirisc hwdc} (@option{all}|@option{none}|mask ...)
Configure hardware debug control. The HWDC register controls which exceptions return
control back to the debugger. Possible masks are @option{all}, @option{none},
@option{reset}, @option{interrupt}, @option{syscall}, @option{error}, and @option{debug}.
@@ -9705,7 +9703,7 @@ By default, @option{reset}, @option{error}, and @option{debug} are enabled.
@subsection eSi-RISC Operation
-@deffn Command {esirisc flush_caches}
+@deffn {Command} {esirisc flush_caches}
Flush instruction and data caches. This command requires that the target is halted
when the command is issued and configured with an instruction or data cache.
@end deffn
@@ -9736,22 +9734,22 @@ managed by enabling flow control, however this can impact timing-sensitive
software operation on the CPU.
@end quotation
-@deffn Command {esirisc trace buffer} address size [@option{wrap}]
+@deffn {Command} {esirisc trace buffer} address size [@option{wrap}]
Configure trace buffer using the provided address and size. If the @option{wrap}
option is specified, trace collection will continue once the end of the buffer
is reached. By default, wrap is disabled.
@end deffn
-@deffn Command {esirisc trace fifo} address
+@deffn {Command} {esirisc trace fifo} address
Configure trace FIFO using the provided address.
@end deffn
-@deffn Command {esirisc trace flow_control} (@option{enable}|@option{disable})
+@deffn {Command} {esirisc trace flow_control} (@option{enable}|@option{disable})
Enable or disable stalling the CPU to collect trace data. By default, flow
control is disabled.
@end deffn
-@deffn Command {esirisc trace format} (@option{full}|@option{branch}|@option{icache}) pc_bits
+@deffn {Command} {esirisc trace format} (@option{full}|@option{branch}|@option{icache}) pc_bits
Configure trace format and number of PC bits to be captured. @option{pc_bits}
must be within 1 and 31 as the LSB is not collected. If external tooling is used
to analyze collected trace data, these values must match.
@@ -9766,7 +9764,7 @@ addresses.
@end itemize
@end deffn
-@deffn Command {esirisc trace trigger start} (@option{condition}) [start_data start_mask]
+@deffn {Command} {esirisc trace trigger start} (@option{condition}) [start_data start_mask]
Configure trigger start condition using the provided start data and mask. A
brief description of each condition is provided below; for more detail on how
these values are used, see the eSi-RISC Architecture Manual.
@@ -9789,7 +9787,7 @@ data and mask.
@end itemize
@end deffn
-@deffn Command {esirisc trace trigger stop} (@option{condition}) [stop_data stop_mask]
+@deffn {Command} {esirisc trace trigger stop} (@option{condition}) [stop_data stop_mask]
Configure trigger stop condition using the provided stop data and mask. A brief
description of each condition is provided below; for more detail on how these
values are used, see the eSi-RISC Architecture Manual.
@@ -9810,7 +9808,7 @@ data and mask.
@end itemize
@end deffn
-@deffn Command {esirisc trace trigger delay} (@option{trigger}) [cycles]
+@deffn {Command} {esirisc trace trigger delay} (@option{trigger}) [cycles]
Configure trigger start/stop delay in clock cycles.
Supported triggers:
@@ -9825,36 +9823,36 @@ collection.
@subsection eSi-Trace Operation
-@deffn Command {esirisc trace init}
+@deffn {Command} {esirisc trace init}
Initialize trace collection. This command must be called any time the
configuration changes. If a trace buffer has been configured, the contents will
be overwritten when trace collection starts.
@end deffn
-@deffn Command {esirisc trace info}
+@deffn {Command} {esirisc trace info}
Display trace configuration.
@end deffn
-@deffn Command {esirisc trace status}
+@deffn {Command} {esirisc trace status}
Display trace collection status.
@end deffn
-@deffn Command {esirisc trace start}
+@deffn {Command} {esirisc trace start}
Start manual trace collection.
@end deffn
-@deffn Command {esirisc trace stop}
+@deffn {Command} {esirisc trace stop}
Stop manual trace collection.
@end deffn
-@deffn Command {esirisc trace analyze} [address size]
+@deffn {Command} {esirisc trace analyze} [address size]
Analyze collected trace data. This command may only be used if a trace buffer
has been configured. If a trace FIFO has been configured, trace data must be
copied to an in-memory buffer identified by the @option{address} and
@option{size} options using DMA.
@end deffn
-@deffn Command {esirisc trace dump} [address size] @file{filename}
+@deffn {Command} {esirisc trace dump} [address size] @file{filename}
Dump collected trace data to file. This command may only be used if a trace
buffer has been configured. If a trace FIFO has been configured, trace data must
be copied to an in-memory buffer identified by the @option{address} and
@@ -9878,27 +9876,27 @@ Useful docs are here: https://communities.intel.com/community/makers/documentati
The three main address spaces for x86 are memory, I/O and configuration space.
These commands allow a user to read and write to the 64Kbyte I/O address space.
-@deffn Command {x86_32 idw} address
+@deffn {Command} {x86_32 idw} address
Display the contents of a 32-bit I/O port from address range 0x0000 - 0xffff.
@end deffn
-@deffn Command {x86_32 idh} address
+@deffn {Command} {x86_32 idh} address
Display the contents of a 16-bit I/O port from address range 0x0000 - 0xffff.
@end deffn
-@deffn Command {x86_32 idb} address
+@deffn {Command} {x86_32 idb} address
Display the contents of a 8-bit I/O port from address range 0x0000 - 0xffff.
@end deffn
-@deffn Command {x86_32 iww} address
+@deffn {Command} {x86_32 iww} address
Write the contents of a 32-bit I/O port to address range 0x0000 - 0xffff.
@end deffn
-@deffn Command {x86_32 iwh} address
+@deffn {Command} {x86_32 iwh} address
Write the contents of a 16-bit I/O port to address range 0x0000 - 0xffff.
@end deffn
-@deffn Command {x86_32 iwb} address
+@deffn {Command} {x86_32 iwb} address
Write the contents of a 8-bit I/O port to address range 0x0000 - 0xffff.
@end deffn
@@ -9908,10 +9906,10 @@ The OpenRISC CPU is a soft core. It is used in a programmable SoC which can be
configured with any of the TAP / Debug Unit available.
@subsection TAP and Debug Unit selection commands
-@deffn Command {tap_select} (@option{vjtag}|@option{mohor}|@option{xilinx_bscan})
+@deffn {Command} {tap_select} (@option{vjtag}|@option{mohor}|@option{xilinx_bscan})
Select between the Altera Virtual JTAG , Xilinx Virtual JTAG and Mohor TAP.
@end deffn
-@deffn Command {du_select} (@option{adv}|@option{mohor}) [option]
+@deffn {Command} {du_select} (@option{adv}|@option{mohor}) [option]
Select between the Advanced Debug Interface and the classic one.
An option can be passed as a second argument to the debug unit.
@@ -9922,7 +9920,7 @@ between bytes while doing read or write bursts.
@end deffn
@subsection Registers commands
-@deffn Command {addreg} [name] [address] [feature] [reg_group]
+@deffn {Command} {addreg} [name] [address] [feature] [reg_group]
Add a new register in the cpu register list. This register will be
included in the generated target descriptor file.
@@ -9939,7 +9937,7 @@ addreg rtest 0x1234 org.gnu.gdb.or1k.group0 system
@end deffn
-@deffn Command {readgroup} (@option{group})
+@deffn {Command} {readgroup} (@option{group})
Display all registers in @emph{group}.
@emph{group} can be "system",
@@ -10001,14 +9999,14 @@ follows:
@subsection RISC-V Debug Configuration Commands
-@deffn Command {riscv dump_sample_buf} [base64]
+@deffn {Command} {riscv dump_sample_buf} [base64]
Dump and clear the contents of the sample buffer. Which samples are collected
is configured with @code{riscv memory_sample}. If the optional base64
argument is passed, the raw buffer is dumped in base64 format, so that
external tools can gather the data efficiently.
@end deffn
-@deffn Command {riscv expose_csrs} n[-m|=name] [...]
+@deffn {Command} {riscv expose_csrs} n[-m|=name] [...]
Configure which CSRs to expose in addition to the standard ones. The CSRs to expose
can be specified as individual register numbers or register ranges (inclusive). For the
individually listed CSRs, a human-readable name can optionally be set, which
@@ -10023,7 +10021,7 @@ command can be used if OpenOCD gets this wrong, or a target implements custom
CSRs.
@end deffn
-@deffn Command {riscv expose_custom} n[-m|=name] [...]
+@deffn {Command} {riscv expose_custom} n[-m|=name] [...]
The RISC-V Debug Specification allows targets to expose custom registers
through abstract commands. (See Section 3.5.1.1 in that document.) This command
configures individual registers or register ranges (inclusive) that shall be exposed.
@@ -10035,7 +10033,7 @@ be named custom<n>.
This command must be executed before `init`.
@end deffn
-@deffn Command {riscv memory_sample} bucket address|clear [size=4]
+@deffn {Command} {riscv memory_sample} bucket address|clear [size=4]
Configure OpenOCD to frequently read size bytes at the given addresses.
Execute the command with no arguments to see the current configuration. Use
clear to stop using a given bucket.
@@ -10045,28 +10043,28 @@ samples will be collected until it is emptied with @code{riscv
dump_sample_buf}.
@end deffn
-@deffn Command {riscv repeat_read} count address [size=4]
+@deffn {Command} {riscv repeat_read} count address [size=4]
Quickly read count words of the given size from address. This can be useful
to read out a buffer that's memory-mapped to be accessed through a single
address, or to sample a changing value in a memory-mapped device.
@end deffn
-@deffn Command {riscv set_command_timeout_sec} [seconds]
+@deffn {Command} {riscv set_command_timeout_sec} [seconds]
Set the wall-clock timeout (in seconds) for individual commands. The default
should work fine for all but the slowest targets (eg. simulators).
@end deffn
-@deffn Command {riscv set_reset_timeout_sec} [seconds]
+@deffn {Command} {riscv set_reset_timeout_sec} [seconds]
Set the maximum time to wait for a hart to come out of reset after reset is
deasserted.
@end deffn
-@deffn Command {riscv set_scratch_ram} none|[address]
+@deffn {Command} {riscv set_scratch_ram} none|[address]
Set the address of 16 bytes of scratch RAM the debugger can use, or 'none'.
This is used to access 64-bit floating point registers on 32-bit targets.
@end deffn
-@deffn Command {riscv set_prefer_sba} on|off
+@deffn {Command} {riscv set_prefer_sba} on|off
@emph{DEPRECATED -- avoid using this.
Use the command @command{riscv set_mem_access} instead.}
@@ -10080,19 +10078,19 @@ Specify which memory access methods shall be used, and in which order of priorit
Method can be one of: 'progbuf', 'sysbus' or 'abstract'. Default: all methods enabled, and in this order.
@end deffn
-@deffn Command {riscv set_enable_virtual} on|off
+@deffn {Command} {riscv set_enable_virtual} on|off
When on, memory accesses are performed on physical or virtual memory depending
on the current system configuration. When off (default), all memory accessses are performed
on physical memory.
@end deffn
-@deffn Command {riscv set_enable_virt2phys} on|off
+@deffn {Command} {riscv set_enable_virt2phys} on|off
When on (default), memory accesses are performed on physical or virtual memory
depending on the current satp configuration. When off, all memory accessses are
performed on physical memory.
@end deffn
-@deffn Command {riscv resume_order} normal|reversed
+@deffn {Command} {riscv resume_order} normal|reversed
Some software assumes all harts are executing nearly continuously. Such
software may be sensitive to the order that harts are resumed in. On harts
that don't support hasel, this option allows the user to choose the order the
@@ -10103,7 +10101,7 @@ Normal order is from lowest hart index to highest. This is the default
behavior. Reversed order is from highest hart index to lowest.
@end deffn
-@deffn Command {riscv set_ir} (@option{idcode}|@option{dtmcs}|@option{dmi}) [value]
+@deffn {Command} {riscv set_ir} (@option{idcode}|@option{dtmcs}|@option{dmi}) [value]
Set the IR value for the specified JTAG register. This is useful, for
example, when using the existing JTAG interface on a Xilinx FPGA by
way of BSCANE2 primitives that only permit a limited selection of IR
@@ -10114,7 +10112,7 @@ When utilizing version 0.11 of the RISC-V Debug Specification,
and DBUS registers, respectively.
@end deffn
-@deffn Command {riscv use_bscan_tunnel} value
+@deffn {Command} {riscv use_bscan_tunnel} value
Enable or disable use of a BSCAN tunnel to reach the Debug Module. Supply the
width of the DM transport TAP's instruction register to enable. Supply a
value of 0 to disable.
@@ -10134,17 +10132,17 @@ tunneled DR scan consists of:
@end deffn
-@deffn Command {riscv set_ebreakm} on|off
+@deffn {Command} {riscv set_ebreakm} on|off
Control dcsr.ebreakm. When on (default), M-mode ebreak instructions trap to
OpenOCD. When off, they generate a breakpoint exception handled internally.
@end deffn
-@deffn Command {riscv set_ebreaks} on|off
+@deffn {Command} {riscv set_ebreaks} on|off
Control dcsr.ebreaks. When on (default), S-mode ebreak instructions trap to
OpenOCD. When off, they generate a breakpoint exception handled internally.
@end deffn
-@deffn Command {riscv set_ebreaku} on|off
+@deffn {Command} {riscv set_ebreaku} on|off
Control dcsr.ebreaku. When on (default), U-mode ebreak instructions trap to
OpenOCD. When off, they generate a breakpoint exception handled internally.
@end deffn
@@ -10159,12 +10157,12 @@ set challenge [riscv authdata_read]
riscv authdata_write [expr $challenge + 1]
@end example
-@deffn Command {riscv authdata_read} [index=0]
+@deffn {Command} {riscv authdata_read} [index=0]
Return the 32-bit value read from authdata or authdata0 (index=0), or
authdata1 (index=1).
@end deffn
-@deffn Command {riscv authdata_write} [index=0] value
+@deffn {Command} {riscv authdata_write} [index=0] value
Write the 32-bit value to authdata or authdata0 (index=0), or authdata1
(index=1).
@end deffn
@@ -10174,11 +10172,11 @@ Write the 32-bit value to authdata or authdata0 (index=0), or authdata1
The following commands allow direct access to the Debug Module Interface, which
can be used to interact with custom debug features.
-@deffn Command {riscv dmi_read} address
+@deffn {Command} {riscv dmi_read} address
Perform a 32-bit DMI read at address, returning the value.
@end deffn
-@deffn Command {riscv dmi_write} address value
+@deffn {Command} {riscv dmi_write} address value
Perform a 32-bit DMI write of value at address.
@end deffn
@@ -10276,7 +10274,7 @@ startbit endbit}.
@deffn {Command} {arc get-reg-field} reg-name field-name
Returns value of bit-field in a register. Register must be ``struct'' register
-type, @xref{add-reg-type-struct} command definition.
+type, @xref{add-reg-type-struct}. command definition.
@end deffn
@deffn {Command} {arc set-reg-exists} reg-names...
@@ -10370,7 +10368,7 @@ This is not the same format used by @file{libdcc}.
Other software, such as the U-Boot boot loader, sometimes
does the same thing.
-@deffn Command {target_request debugmsgs} [@option{enable}|@option{disable}|@option{charmsg}]
+@deffn {Command} {target_request debugmsgs} [@option{enable}|@option{disable}|@option{charmsg}]
Displays current handling of target DCC message requests.
These messages may be sent to the debugger while the target is running.
The optional @option{enable} and @option{charmsg} parameters
@@ -10381,7 +10379,7 @@ as used by Linux with CONFIG_DEBUG_ICEDCC;
otherwise the libdcc format is used.
@end deffn
-@deffn Command {trace history} [@option{clear}|count]
+@deffn {Command} {trace history} [@option{clear}|count]
With no parameter, displays all the trace points that have triggered
in the order they triggered.
With the parameter @option{clear}, erases all current trace history records.
@@ -10389,7 +10387,7 @@ With a @var{count} parameter, allocates space for that many
history records.
@end deffn
-@deffn Command {trace point} [@option{clear}|identifier]
+@deffn {Command} {trace point} [@option{clear}|identifier]
With no parameter, displays all trace point identifiers and how many times
they have been triggered.
With the parameter @option{clear}, erases all current trace point counters.
@@ -10443,7 +10441,7 @@ JTAG router), you probably won't need to use these commands.
In a debug session that doesn't use JTAG for its transport protocol,
these commands are not available.
-@deffn Command {drscan} tap [numbits value]+ [@option{-endstate} tap_state]
+@deffn {Command} {drscan} tap [numbits value]+ [@option{-endstate} tap_state]
Loads the data register of @var{tap} with a series of bit fields
that specify the entire register.
Each field is @var{numbits} bits long with
@@ -10478,7 +10476,7 @@ the register accessed by the INTEST instruction
@end quotation
@end deffn
-@deffn Command {flush_count}
+@deffn {Command} {flush_count}
Returns the number of times the JTAG queue has been flushed.
This may be used for performance tuning.
@@ -10490,7 +10488,7 @@ tasks which waste bandwidth by flushing small transfers too often,
instead of batching them into larger operations.
@end deffn
-@deffn Command {irscan} [tap instruction]+ [@option{-endstate} tap_state]
+@deffn {Command} {irscan} [tap instruction]+ [@option{-endstate} tap_state]
For each @var{tap} listed, loads the instruction register
with its associated numeric @var{instruction}.
(The number of bits in that instruction may be displayed
@@ -10511,7 +10509,7 @@ portable scripts currently must issue only BYPASS instructions.
@end quotation
@end deffn
-@deffn Command {pathmove} start_state [next_state ...]
+@deffn {Command} {pathmove} start_state [next_state ...]
Start by moving to @var{start_state}, which
must be one of the @emph{stable} states.
Unless it is the only state given, this will often be the
@@ -10522,7 +10520,7 @@ each @var{next_state} in sequence, one per TCK cycle.
The final state must also be stable.
@end deffn
-@deffn Command {runtest} @var{num_cycles}
+@deffn {Command} {runtest} @var{num_cycles}
Move to the @sc{run/idle} state, and execute at least
@var{num_cycles} of the JTAG clock (TCK).
Instructions often need some time
@@ -10532,14 +10530,14 @@ to execute before they take effect.
@c tms_sequence (short|long)
@c ... temporary, debug-only, other than USBprog bug workaround...
-@deffn Command {verify_ircapture} (@option{enable}|@option{disable})
+@deffn {Command} {verify_ircapture} (@option{enable}|@option{disable})
Verify values captured during @sc{ircapture} and returned
during IR scans. Default is enabled, but this can be
overridden by @command{verify_jtag}.
This flag is ignored when validating JTAG chain configuration.
@end deffn
-@deffn Command {verify_jtag} (@option{enable}|@option{disable})
+@deffn {Command} {verify_jtag} (@option{enable}|@option{disable})
Enables verification of DR and IR scans, to help detect
programming errors. For IR scans, @command{verify_ircapture}
must also be enabled.
@@ -10613,7 +10611,7 @@ way to represent JTAG test patterns in text files.
In a debug session using JTAG for its transport protocol,
OpenOCD supports running such test files.
-@deffn Command {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{[-]quiet}] @
+@deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{[-]quiet}] @
[@option{[-]nil}] [@option{[-]progress}] [@option{[-]ignore_error}]
This issues a JTAG reset (Test-Logic-Reset) and then
runs the SVF script from @file{filename}.
@@ -10650,7 +10648,7 @@ OpenOCD supports running such test files.
Not all XSVF commands are supported.
@end quotation
-@deffn Command {xsvf} (tapname|@option{plain}) filename [@option{virt2}] [@option{quiet}]
+@deffn {Command} {xsvf} (tapname|@option{plain}) filename [@option{virt2}] [@option{quiet}]
This issues a JTAG reset (Test-Logic-Reset) and then
runs the XSVF script from @file{filename}.
When a @var{tapname} is specified, the commands are directed at
@@ -10708,24 +10706,24 @@ source [find tools/memtest.tcl]
to get access to the following facilities:
-@deffn Command {memTestDataBus} address
+@deffn {Command} {memTestDataBus} address
Test the data bus wiring in a memory region by performing a walking
1's test at a fixed address within that region.
@end deffn
-@deffn Command {memTestAddressBus} baseaddress size
+@deffn {Command} {memTestAddressBus} baseaddress size
Perform a walking 1's test on the relevant bits of the address and
check for aliasing. This test will find single-bit address failures
such as stuck-high, stuck-low, and shorted pins.
@end deffn
-@deffn Command {memTestDevice} baseaddress size
+@deffn {Command} {memTestDevice} baseaddress size
Test the integrity of a physical memory device by performing an
increment/decrement test over the entire region. In the process every
storage bit in the device is tested as zero and as one.
@end deffn
-@deffn Command {runAllMemTests} baseaddress size
+@deffn {Command} {runAllMemTests} baseaddress size
Run all of the above tests over a specified memory region.
@end deffn
@@ -11196,34 +11194,6 @@ OpenOCD commands can consist of two words, e.g. "flash banks". The
@file{startup.tcl} "unknown" proc will translate this into a Tcl proc
called "flash_banks".
-@section OpenOCD specific Global Variables
-
-Real Tcl has ::tcl_platform(), and platform::identify, and many other
-variables. JimTCL, as implemented in OpenOCD creates $ocd_HOSTOS which
-holds one of the following values:
-
-@itemize @bullet
-@item @b{cygwin} Running under Cygwin
-@item @b{darwin} Darwin (Mac-OS) is the underlying operating system.
-@item @b{freebsd} Running under FreeBSD
-@item @b{openbsd} Running under OpenBSD
-@item @b{netbsd} Running under NetBSD
-@item @b{linux} Linux is the underlying operating system
-@item @b{mingw32} Running under MingW32
-@item @b{winxx} Built using Microsoft Visual Studio
-@item @b{ecos} Running under eCos
-@item @b{other} Unknown, none of the above.
-@end itemize
-
-Note: 'winxx' was chosen because today (March-2009) no distinction is made between Win32 and Win64.
-
-@quotation Note
-We should add support for a variable like Tcl variable
-@code{tcl_platform(platform)}, it should be called
-@code{jim_platform} (because it
-is jim, not real tcl).
-@end quotation
-
@section Tcl RPC server
@cindex RPC
@@ -11257,7 +11227,7 @@ type target_state state [state-name]
type target_reset mode [reset-mode]
@end verbatim
-@deffn {Command} tcl_notifications [on/off]
+@deffn {Command} {tcl_notifications} [on/off]
Toggle output of target notifications to the current Tcl RPC server.
Only available from the Tcl RPC server.
Defaults to off.
@@ -11276,7 +11246,7 @@ Target trace data is emitted as a Tcl associative array in the following format.
type target_trace data [trace-data-hex-encoded]
@end verbatim
-@deffn {Command} tcl_trace [on/off]
+@deffn {Command} {tcl_trace} [on/off]
Toggle output of target trace data to the current Tcl RPC server.
Only available from the Tcl RPC server.
Defaults to off.
diff --git a/src/flash/nand/tcl.c b/src/flash/nand/tcl.c
index ca8b9da..9e0ca41 100644
--- a/src/flash/nand/tcl.c
+++ b/src/flash/nand/tcl.c
@@ -479,8 +479,8 @@ static 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);
+
+ return register_commands(cmd_ctx, "nand", nand_exec_command_handlers);
}
COMMAND_HANDLER(handle_nand_init_command)
diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index 771f21f..661cee9 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -52,6 +52,7 @@ NOR_DRIVERS = \
%D%/psoc5lp.c \
%D%/psoc6.c \
%D%/renesas_rpchf.c \
+ %D%/rp2040.c \
%D%/sfdp.c \
%D%/sh_qspi.c \
%D%/sim3x.c \
diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c
index 047b5f7..77403cd 100644
--- a/src/flash/nor/drivers.c
+++ b/src/flash/nor/drivers.c
@@ -68,6 +68,7 @@ extern const struct flash_driver psoc5lp_eeprom_flash;
extern const struct flash_driver psoc5lp_nvl_flash;
extern const struct flash_driver psoc6_flash;
extern const struct flash_driver renesas_rpchf_flash;
+extern const struct flash_driver rp2040_flash;
extern const struct flash_driver sh_qspi_flash;
extern const struct flash_driver sim3x_flash;
extern const struct flash_driver stellaris_flash;
@@ -141,6 +142,7 @@ static const struct flash_driver * const flash_drivers[] = {
&psoc5lp_nvl_flash,
&psoc6_flash,
&renesas_rpchf_flash,
+ &rp2040_flash,
&sh_qspi_flash,
&sim3x_flash,
&stellaris_flash,
diff --git a/src/flash/nor/esirisc_flash.c b/src/flash/nor/esirisc_flash.c
index 88f00bc..24e8117 100644
--- a/src/flash/nor/esirisc_flash.c
+++ b/src/flash/nor/esirisc_flash.c
@@ -109,7 +109,6 @@ static const struct command_registration esirisc_flash_command_handlers[];
FLASH_BANK_COMMAND_HANDLER(esirisc_flash_bank_command)
{
struct esirisc_flash_bank *esirisc_info;
- struct command *esirisc_cmd;
if (CMD_ARGC < 9)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -123,8 +122,7 @@ FLASH_BANK_COMMAND_HANDLER(esirisc_flash_bank_command)
bank->driver_priv = esirisc_info;
/* register commands using existing esirisc context */
- esirisc_cmd = command_find_in_context(CMD_CTX, "esirisc");
- register_commands(CMD_CTX, esirisc_cmd, esirisc_flash_command_handlers);
+ register_commands(CMD_CTX, "esirisc", esirisc_flash_command_handlers);
return ERROR_OK;
}
diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c
index 45d3d09..b9d567e 100644
--- a/src/flash/nor/nrf5.c
+++ b/src/flash/nor/nrf5.c
@@ -289,7 +289,7 @@ static const struct nrf5_device_package nrf5_packages_table[] = {
const struct flash_driver nrf5_flash, nrf51_flash;
-static int nrf5_bank_is_probed(struct flash_bank *bank)
+static bool nrf5_bank_is_probed(const struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
@@ -309,13 +309,10 @@ static int nrf5_get_probed_chip_if_halted(struct flash_bank *bank, struct nrf5_i
struct nrf5_bank *nbank = bank->driver_priv;
*chip = nbank->chip;
- int probed = nrf5_bank_is_probed(bank);
- if (probed < 0)
- return probed;
- else if (!probed)
- return nrf5_probe(bank);
- else
+ if (nrf5_bank_is_probed(bank))
return ERROR_OK;
+
+ return nrf5_probe(bank);
}
static int nrf5_wait_for_nvmc(struct nrf5_info *chip)
@@ -871,14 +868,10 @@ static int nrf5_probe(struct flash_bank *bank)
static int nrf5_auto_probe(struct flash_bank *bank)
{
- int probed = nrf5_bank_is_probed(bank);
-
- if (probed < 0)
- return probed;
- else if (probed)
+ if (nrf5_bank_is_probed(bank))
return ERROR_OK;
- else
- return nrf5_probe(bank);
+
+ return nrf5_probe(bank);
}
static int nrf5_erase_all(struct nrf5_info *chip)
diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c
index 1971daa..d9ea16d 100644
--- a/src/flash/nor/numicro.c
+++ b/src/flash/nor/numicro.c
@@ -1132,7 +1132,7 @@ static const struct numicro_cpu_type NuMicroParts[] = {
/* Private bank information for NuMicro. */
struct numicro_flash_bank {
struct working_area *write_algorithm;
- int probed;
+ bool probed;
const struct numicro_cpu_type *cpu;
};
diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c
new file mode 100644
index 0000000..5b4c16b
--- /dev/null
+++ b/src/flash/nor/rp2040.c
@@ -0,0 +1,453 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "imp.h"
+#include <helper/binarybuffer.h>
+#include <target/algorithm.h>
+#include <target/armv7m.h>
+#include "spi.h"
+
+/* NOTE THAT THIS CODE REQUIRES FLASH ROUTINES in BOOTROM WITH FUNCTION TABLE PTR AT 0x00000010
+ Your gdbinit should load the bootrom.elf if appropriate */
+
+/* this is 'M' 'u', 1 (version) */
+#define BOOTROM_MAGIC 0x01754d
+#define BOOTROM_MAGIC_ADDR 0x00000010
+
+/* Call a ROM function via the debug trampoline
+ Up to four arguments passed in r0...r3 as per ABI
+ Function address is passed in r7
+ the trampoline is needed because OpenOCD "algorithm" code insists on sw breakpoints. */
+
+#define MAKE_TAG(a, b) (((b)<<8) | a)
+#define FUNC_DEBUG_TRAMPOLINE MAKE_TAG('D', 'T')
+#define FUNC_DEBUG_TRAMPOLINE_END MAKE_TAG('D', 'E')
+#define FUNC_FLASH_EXIT_XIP MAKE_TAG('E', 'X')
+#define FUNC_CONNECT_INTERNAL_FLASH MAKE_TAG('I', 'F')
+#define FUNC_FLASH_RANGE_ERASE MAKE_TAG('R', 'E')
+#define FUNC_FLASH_RANGE_PROGRAM MAKE_TAG('R', 'P')
+#define FUNC_FLASH_FLUSH_CACHE MAKE_TAG('F', 'C')
+#define FUNC_FLASH_ENTER_CMD_XIP MAKE_TAG('C', 'X')
+
+struct rp2040_flash_bank {
+ /* flag indicating successful flash probe */
+ bool probed;
+ /* stack used by Boot ROM calls */
+ struct working_area *stack;
+ /* function jump table populated by rp2040_flash_probe() */
+ uint16_t jump_debug_trampoline;
+ uint16_t jump_debug_trampoline_end;
+ uint16_t jump_flash_exit_xip;
+ uint16_t jump_connect_internal_flash;
+ uint16_t jump_flash_range_erase;
+ uint16_t jump_flash_range_program;
+ uint16_t jump_flush_cache;
+ uint16_t jump_enter_cmd_xip;
+ /* detected model of SPI flash */
+ const struct flash_device *dev;
+};
+
+static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16_t *symbol)
+{
+ uint32_t magic;
+ int err = target_read_u32(target, BOOTROM_MAGIC_ADDR, &magic);
+ if (err != ERROR_OK)
+ return err;
+
+ magic &= 0xffffff; /* ignore bootrom version */
+ if (magic != BOOTROM_MAGIC) {
+ if (!((magic ^ BOOTROM_MAGIC)&0xffff))
+ LOG_ERROR("Incorrect RP2040 BOOT ROM version");
+ else
+ LOG_ERROR("RP2040 BOOT ROM not found");
+ return ERROR_FAIL;
+ }
+
+ /* dereference the table pointer */
+ uint16_t table_entry;
+ err = target_read_u16(target, BOOTROM_MAGIC_ADDR + 4, &table_entry);
+ if (err != ERROR_OK)
+ return err;
+
+ uint16_t entry_tag;
+ do {
+ err = target_read_u16(target, table_entry, &entry_tag);
+ if (err != ERROR_OK)
+ return err;
+ if (entry_tag == tag) {
+ /* 16 bit symbol is next */
+ return target_read_u16(target, table_entry + 2, symbol);
+ }
+ table_entry += 4;
+ } while (entry_tag);
+ return ERROR_FAIL;
+}
+
+static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank *priv,
+ uint16_t func_offset, uint32_t argdata[], unsigned int n_args)
+{
+ char *regnames[4] = { "r0", "r1", "r2", "r3" };
+
+ assert(n_args <= ARRAY_SIZE(regnames)); /* only allow register arguments */
+
+ if (!priv->stack) {
+ LOG_ERROR("no stack for flash programming code");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ target_addr_t stacktop = priv->stack->address + priv->stack->size;
+
+ LOG_DEBUG("Calling ROM func @0x%" PRIx16 " with %d arguments", func_offset, n_args);
+ LOG_DEBUG("Calling on core \"%s\"", target->cmd_name);
+
+ struct reg_param args[ARRAY_SIZE(regnames) + 2];
+ struct armv7m_algorithm alg_info;
+
+ for (unsigned int i = 0; i < n_args; ++i) {
+ init_reg_param(&args[i], regnames[i], 32, PARAM_OUT);
+ buf_set_u32(args[i].value, 0, 32, argdata[i]);
+ }
+ /* Pass function pointer in r7 */
+ init_reg_param(&args[n_args], "r7", 32, PARAM_OUT);
+ buf_set_u32(args[n_args].value, 0, 32, func_offset);
+ init_reg_param(&args[n_args + 1], "sp", 32, PARAM_OUT);
+ buf_set_u32(args[n_args + 1].value, 0, 32, stacktop);
+
+
+ for (unsigned int i = 0; i < n_args + 2; ++i)
+ LOG_DEBUG("Set %s = 0x%" PRIx32, args[i].reg_name, buf_get_u32(args[i].value, 0, 32));
+
+ /* Actually call the function */
+ alg_info.common_magic = ARMV7M_COMMON_MAGIC;
+ alg_info.core_mode = ARM_MODE_THREAD;
+ int err = target_run_algorithm(
+ target,
+ 0, NULL, /* No memory arguments */
+ n_args + 1, args, /* User arguments + r7 */
+ priv->jump_debug_trampoline, priv->jump_debug_trampoline_end,
+ 3000, /* 3s timeout */
+ &alg_info
+ );
+ for (unsigned int i = 0; i < n_args + 2; ++i)
+ destroy_reg_param(&args[i]);
+ if (err != ERROR_OK)
+ LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16 "\n", func_offset);
+ return err;
+
+}
+
+static int stack_grab_and_prep(struct flash_bank *bank)
+{
+ struct rp2040_flash_bank *priv = bank->driver_priv;
+
+ /* target_alloc_working_area always allocates multiples of 4 bytes, so no worry about alignment */
+ const int STACK_SIZE = 256;
+ int err = target_alloc_working_area(bank->target, STACK_SIZE, &priv->stack);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Could not allocate stack for flash programming code");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
+ LOG_DEBUG("Connecting internal flash");
+ err = rp2040_call_rom_func(bank->target, priv, priv->jump_connect_internal_flash, NULL, 0);
+ if (err != ERROR_OK) {
+ LOG_ERROR("RP2040 erase: failed to connect internal flash");
+ return err;
+ }
+
+ LOG_DEBUG("Kicking flash out of XIP mode");
+ err = rp2040_call_rom_func(bank->target, priv, priv->jump_flash_exit_xip, NULL, 0);
+ if (err != ERROR_OK) {
+ LOG_ERROR("RP2040 erase: failed to exit flash XIP mode");
+ return err;
+ }
+
+ return ERROR_OK;
+}
+
+static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
+{
+ LOG_DEBUG("Writing %d bytes starting at 0x%" PRIx32, count, offset);
+
+ struct rp2040_flash_bank *priv = bank->driver_priv;
+ struct target *target = bank->target;
+ struct working_area *bounce;
+
+ int err = stack_grab_and_prep(bank);
+ if (err != ERROR_OK)
+ return err;
+
+ const unsigned int chunk_size = target_get_working_area_avail(target);
+ if (target_alloc_working_area(target, chunk_size, &bounce) != ERROR_OK) {
+ LOG_ERROR("Could not allocate bounce buffer for flash programming. Can't continue");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
+ LOG_DEBUG("Allocated flash bounce buffer @" TARGET_ADDR_FMT, bounce->address);
+
+ while (count > 0) {
+ uint32_t write_size = count > chunk_size ? chunk_size : count;
+ LOG_DEBUG("Writing %d bytes to offset 0x%" PRIx32, write_size, offset);
+ err = target_write_buffer(target, bounce->address, write_size, buffer);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Could not load data into target bounce buffer");
+ break;
+ }
+ uint32_t args[3] = {
+ offset, /* addr */
+ bounce->address, /* data */
+ write_size /* count */
+ };
+ err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_program, args, ARRAY_SIZE(args));
+ if (err != ERROR_OK) {
+ LOG_ERROR("Failed to invoke flash programming code on target");
+ break;
+ }
+
+ buffer += write_size;
+ offset += write_size;
+ count -= write_size;
+ }
+ target_free_working_area(target, bounce);
+
+ if (err != ERROR_OK)
+ return err;
+
+ /* Flash is successfully programmed. We can now do a bit of poking to make the flash
+ contents visible to us via memory-mapped (XIP) interface in the 0x1... memory region */
+ LOG_DEBUG("Flushing flash cache after write behind");
+ err = rp2040_call_rom_func(bank->target, priv, priv->jump_flush_cache, NULL, 0);
+ if (err != ERROR_OK) {
+ LOG_ERROR("RP2040 write: failed to flush flash cache");
+ return err;
+ }
+ LOG_DEBUG("Configuring SSI for execute-in-place");
+ err = rp2040_call_rom_func(bank->target, priv, priv->jump_enter_cmd_xip, NULL, 0);
+ if (err != ERROR_OK)
+ LOG_ERROR("RP2040 write: failed to flush flash cache");
+ return err;
+}
+
+static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
+{
+ struct rp2040_flash_bank *priv = bank->driver_priv;
+ uint32_t start_addr = bank->sectors[first].offset;
+ uint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr;
+ LOG_DEBUG("RP2040 erase %d bytes starting at 0x%" PRIx32, length, start_addr);
+
+ int err = stack_grab_and_prep(bank);
+ if (err != ERROR_OK)
+ return err;
+
+ LOG_DEBUG("Remote call flash_range_erase");
+
+ uint32_t args[4] = {
+ bank->sectors[first].offset, /* addr */
+ bank->sectors[last].offset + bank->sectors[last].size - bank->sectors[first].offset, /* count */
+ priv->dev->sectorsize, /* block_size */
+ priv->dev->erase_cmd /* block_cmd */
+ };
+
+ /*
+ The RP2040 Boot ROM provides a _flash_range_erase() API call documented in Section 2.8.3.1.3:
+ https://datasheets.raspberrypi.org/rp2040/rp2040-datasheet.pdf
+ and the particular source code for said Boot ROM function can be found here:
+ https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c
+
+ In theory, the function algorithm provides for erasing both a smaller "sector" (4096 bytes) and
+ an optional larger "block" (size and command provided in args). OpenOCD's spi.c only uses "block" sizes.
+ */
+
+ err = rp2040_call_rom_func(bank->target, priv, priv->jump_flash_range_erase, args, ARRAY_SIZE(args));
+
+ return err;
+}
+
+/* -----------------------------------------------------------------------------
+ Driver probing etc */
+
+static int rp2040_ssel_active(struct target *target, bool active)
+{
+ const target_addr_t qspi_ctrl_addr = 0x4001800c;
+ const uint32_t qspi_ctrl_outover_low = 2UL << 8;
+ const uint32_t qspi_ctrl_outover_high = 3UL << 8;
+ uint32_t state = (active) ? qspi_ctrl_outover_low : qspi_ctrl_outover_high;
+ uint32_t val;
+
+ int err = target_read_u32(target, qspi_ctrl_addr, &val);
+ if (err != ERROR_OK)
+ return err;
+
+ val = (val & ~qspi_ctrl_outover_high) | state;
+
+ err = target_write_u32(target, qspi_ctrl_addr, val);
+ if (err != ERROR_OK)
+ return err;
+
+ return ERROR_OK;
+}
+
+static int rp2040_flash_probe(struct flash_bank *bank)
+{
+ struct rp2040_flash_bank *priv = bank->driver_priv;
+ struct target *target = bank->target;
+
+ int err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE, &priv->jump_debug_trampoline);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Debug trampoline not found in RP2040 ROM.");
+ return err;
+ }
+ priv->jump_debug_trampoline &= ~1u; /* mask off thumb bit */
+
+ err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE_END, &priv->jump_debug_trampoline_end);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Debug trampoline end not found in RP2040 ROM.");
+ return err;
+ }
+ priv->jump_debug_trampoline_end &= ~1u; /* mask off thumb bit */
+
+ err = rp2040_lookup_symbol(target, FUNC_FLASH_EXIT_XIP, &priv->jump_flash_exit_xip);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Function FUNC_FLASH_EXIT_XIP not found in RP2040 ROM.");
+ return err;
+ }
+
+ err = rp2040_lookup_symbol(target, FUNC_CONNECT_INTERNAL_FLASH, &priv->jump_connect_internal_flash);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Function FUNC_CONNECT_INTERNAL_FLASH not found in RP2040 ROM.");
+ return err;
+ }
+
+ err = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_ERASE, &priv->jump_flash_range_erase);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Function FUNC_FLASH_RANGE_ERASE not found in RP2040 ROM.");
+ return err;
+ }
+
+ err = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_PROGRAM, &priv->jump_flash_range_program);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Function FUNC_FLASH_RANGE_PROGRAM not found in RP2040 ROM.");
+ return err;
+ }
+
+ err = rp2040_lookup_symbol(target, FUNC_FLASH_FLUSH_CACHE, &priv->jump_flush_cache);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Function FUNC_FLASH_FLUSH_CACHE not found in RP2040 ROM.");
+ return err;
+ }
+
+ err = rp2040_lookup_symbol(target, FUNC_FLASH_ENTER_CMD_XIP, &priv->jump_enter_cmd_xip);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Function FUNC_FLASH_ENTER_CMD_XIP not found in RP2040 ROM.");
+ return err;
+ }
+
+ err = stack_grab_and_prep(bank);
+ if (err != ERROR_OK)
+ return err;
+
+ uint32_t device_id = 0;
+ const target_addr_t ssi_dr0 = 0x18000060;
+
+ err = rp2040_ssel_active(target, true);
+
+ /* write RDID request into SPI peripheral's FIFO */
+ for (int count = 0; (count < 4) && (err == ERROR_OK); count++)
+ err = target_write_u32(target, ssi_dr0, SPIFLASH_READ_ID);
+
+ /* by this time, there is a receive FIFO entry for every write */
+ for (int count = 0; (count < 4) && (err == ERROR_OK); count++) {
+ uint32_t status;
+ err = target_read_u32(target, ssi_dr0, &status);
+
+ device_id >>= 8;
+ device_id |= (status & 0xFF) << 24;
+ }
+ device_id >>= 8;
+
+ err = rp2040_ssel_active(target, false);
+ if (err != ERROR_OK) {
+ LOG_ERROR("SSEL inactive failed");
+ return err;
+ }
+
+ /* search for a SPI flash Device ID match */
+ priv->dev = NULL;
+ for (const struct flash_device *p = flash_devices; p->name ; p++)
+ if (p->device_id == device_id) {
+ priv->dev = p;
+ break;
+ }
+
+ if (!priv->dev) {
+ LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", device_id);
+ return ERROR_FAIL;
+ }
+
+ LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
+ priv->dev->name, priv->dev->device_id);
+
+ /* the Boot ROM flash_range_program() routine requires page alignment */
+ bank->write_start_alignment = priv->dev->pagesize;
+ bank->write_end_alignment = priv->dev->pagesize;
+
+ bank->size = priv->dev->size_in_bytes;
+
+ bank->num_sectors = bank->size / priv->dev->sectorsize;
+ LOG_INFO("RP2040 B0 Flash Probe: %d bytes @" TARGET_ADDR_FMT ", in %d sectors\n",
+ bank->size, bank->base, bank->num_sectors);
+ bank->sectors = alloc_block_array(0, priv->dev->sectorsize, bank->num_sectors);
+ if (!bank->sectors)
+ return ERROR_FAIL;
+
+ if (err == ERROR_OK)
+ priv->probed = true;
+
+ return err;
+}
+
+static int rp2040_flash_auto_probe(struct flash_bank *bank)
+{
+ struct rp2040_flash_bank *priv = bank->driver_priv;
+
+ if (priv->probed)
+ return ERROR_OK;
+
+ return rp2040_flash_probe(bank);
+}
+
+static void rp2040_flash_free_driver_priv(struct flash_bank *bank)
+{
+ free(bank->driver_priv);
+ bank->driver_priv = NULL;
+}
+
+/* -----------------------------------------------------------------------------
+ Driver boilerplate */
+
+FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command)
+{
+ struct rp2040_flash_bank *priv;
+ priv = malloc(sizeof(struct rp2040_flash_bank));
+ priv->probed = false;
+
+ /* Set up driver_priv */
+ bank->driver_priv = priv;
+
+ return ERROR_OK;
+}
+
+struct flash_driver rp2040_flash = {
+ .name = "rp2040_flash",
+ .commands = NULL,
+ .flash_bank_command = rp2040_flash_bank_command,
+ .erase = rp2040_flash_erase,
+ .write = rp2040_flash_write,
+ .read = default_flash_read,
+ .probe = rp2040_flash_probe,
+ .auto_probe = rp2040_flash_auto_probe,
+ .erase_check = default_flash_blank_check,
+ .free_driver_priv = rp2040_flash_free_driver_priv
+};
diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c
index 9cd282d..125f776 100644
--- a/src/flash/nor/stm32f1x.c
+++ b/src/flash/nor/stm32f1x.c
@@ -692,7 +692,7 @@ static int stm32x_probe(struct flash_bank *bank)
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
uint16_t flash_size_in_kb;
uint16_t max_flash_size_in_kb;
- uint32_t device_id;
+ uint32_t dbgmcu_idcode;
int page_size;
uint32_t base_address = 0x08000000;
@@ -705,14 +705,17 @@ static int stm32x_probe(struct flash_bank *bank)
stm32x_info->default_rdp = 0xA5;
/* read stm32 device id register */
- int retval = stm32x_get_device_id(bank, &device_id);
+ int retval = stm32x_get_device_id(bank, &dbgmcu_idcode);
if (retval != ERROR_OK)
return retval;
- LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
+ LOG_INFO("device id = 0x%08" PRIx32 "", dbgmcu_idcode);
+
+ uint16_t device_id = dbgmcu_idcode & 0xfff;
+ uint16_t rev_id = dbgmcu_idcode >> 16;
/* set page size, protection granularity and max flash size depending on family */
- switch (device_id & 0xfff) {
+ switch (device_id) {
case 0x440: /* stm32f05x */
page_size = 1024;
stm32x_info->ppage_size = 4;
@@ -754,6 +757,25 @@ static int stm32x_probe(struct flash_bank *bank)
page_size = 1024;
stm32x_info->ppage_size = 4;
max_flash_size_in_kb = 128;
+ /* GigaDevice GD32F1x0 & GD32F3x0 series devices share DEV_ID
+ with STM32F101/2/3 medium-density line,
+ however they use a REV_ID different from any STM32 device.
+ The main difference is another offset of user option bits
+ (like WDG_SW, nRST_STOP, nRST_STDBY) in option byte register
+ (FLASH_OBR/FMC_OBSTAT 0x4002201C).
+ This caused problems e.g. during flash block programming
+ because of unexpected active hardware watchog. */
+ switch (rev_id) {
+ case 0x1303: /* gd32f1x0 */
+ stm32x_info->user_data_offset = 16;
+ stm32x_info->option_offset = 6;
+ max_flash_size_in_kb = 64;
+ break;
+ case 0x1704: /* gd32f3x0 */
+ stm32x_info->user_data_offset = 16;
+ stm32x_info->option_offset = 6;
+ break;
+ }
break;
case 0x412: /* stm32f1x low-density */
page_size = 1024;
@@ -955,6 +977,14 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
rev_str = "A";
break;
+ case 0x1303: /* gd32f1x0 */
+ device_str = "GD32F1x0";
+ break;
+
+ case 0x1704: /* gd32f3x0 */
+ device_str = "GD32F3x0";
+ break;
+
case 0x2000:
rev_str = "B";
break;
diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c
index 0e0a924..7b23545 100644
--- a/src/flash/nor/tcl.c
+++ b/src/flash/nor/tcl.c
@@ -1249,8 +1249,7 @@ static int flash_init_drivers(struct command_context *cmd_ctx)
if (!flash_bank_list())
return ERROR_OK;
- struct command *parent = command_find_in_context(cmd_ctx, "flash");
- return register_commands(cmd_ctx, parent, flash_exec_command_handlers);
+ return register_commands(cmd_ctx, "flash", flash_exec_command_handlers);
}
COMMAND_HANDLER(handle_flash_bank_command)
diff --git a/src/helper/command.c b/src/helper/command.c
index fdf1bbe..4cda7c2 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -44,17 +44,33 @@
/* nice short description of source file */
#define __THIS__FILE__ "command.c"
-static int run_command(struct command_context *context,
- struct command *c, const char *words[], unsigned num_words);
-
struct log_capture_state {
Jim_Interp *interp;
Jim_Obj *output;
};
static int unregister_command(struct command_context *context,
- struct command *parent, const char *name);
-static char *command_name(struct command *c, char delim);
+ const char *cmd_prefix, const char *name);
+static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *argv);
+static int help_add_command(struct command_context *cmd_ctx,
+ const char *cmd_name, const char *help_text, const char *usage_text);
+static int help_del_command(struct command_context *cmd_ctx, const char *cmd_name);
+
+/* set of functions to wrap jimtcl internal data */
+static inline bool jimcmd_is_proc(Jim_Cmd *cmd)
+{
+ return cmd->isproc;
+}
+
+static inline bool jimcmd_is_ocd_command(Jim_Cmd *cmd)
+{
+ return !cmd->isproc && cmd->u.native.cmdProc == jim_command_dispatch;
+}
+
+static inline void *jimcmd_privdata(Jim_Cmd *cmd)
+{
+ return cmd->isproc ? NULL : cmd->u.native.privData;
+}
static void tcl_output(void *privData, const char *file, unsigned line,
const char *function, const char *string)
@@ -67,17 +83,21 @@ static struct log_capture_state *command_log_capture_start(Jim_Interp *interp)
{
/* capture log output and return it. A garbage collect can
* happen, so we need a reference count to this object */
- Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
- if (NULL == tclOutput)
+ Jim_Obj *jim_output = Jim_NewStringObj(interp, "", 0);
+ if (!jim_output)
return NULL;
+ Jim_IncrRefCount(jim_output);
+
struct log_capture_state *state = malloc(sizeof(*state));
- if (NULL == state)
+ if (!state) {
+ LOG_ERROR("Out of memory");
+ Jim_DecrRefCount(interp, jim_output);
return NULL;
+ }
state->interp = interp;
- Jim_IncrRefCount(tclOutput);
- state->output = tclOutput;
+ state->output = jim_output;
log_add_callback(tcl_output, state);
@@ -164,7 +184,7 @@ extern struct command_context *global_cmd_ctx;
/* dump a single line to the log for the command.
* Do nothing in case we are not at debug level 3 */
-void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const *argv)
+static void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const *argv)
{
if (debug_level < LOG_LVL_DEBUG)
return;
@@ -226,111 +246,28 @@ struct command_context *current_command_context(Jim_Interp *interp)
return cmd_ctx;
}
-static int script_command_run(Jim_Interp *interp,
- int argc, Jim_Obj * const *argv, struct command *c)
-{
- target_call_timer_callbacks_now(NULL);
- LOG_USER_N("%s", ""); /* Keep GDB connection alive*/
-
- unsigned nwords;
- char **words = script_command_args_alloc(argc, argv, &nwords);
- if (NULL == words)
- return JIM_ERR;
-
- struct command_context *cmd_ctx = current_command_context(interp);
- int retval = run_command(cmd_ctx, c, (const char **)words, nwords);
-
- script_command_args_free(words, nwords);
- return command_retval_set(interp, retval);
-}
-
-static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- /* the private data is stashed in the interp structure */
-
- struct command *c = interp->cmdPrivData;
- assert(c);
- script_debug(interp, argc, argv);
- return script_command_run(interp, argc, argv, c);
-}
-
-static struct command *command_root(struct command *c)
-{
- while (NULL != c->parent)
- c = c->parent;
- return c;
-}
-
/**
- * Find a command by name from a list of commands.
- * @returns Returns the named command if it exists in the list.
+ * Find a openocd command from fullname.
+ * @returns Returns the named command if it is registred in interp.
* Returns NULL otherwise.
*/
-static struct command *command_find(struct command *head, const char *name)
-{
- for (struct command *cc = head; cc; cc = cc->next) {
- if (strcmp(cc->name, name) == 0)
- return cc;
- }
- return NULL;
-}
-
-struct command *command_find_in_context(struct command_context *cmd_ctx,
- const char *name)
-{
- return command_find(cmd_ctx->commands, name);
-}
-
-/**
- * Add the command into the linked list, sorted by name.
- * @param head Address to head of command list pointer, which may be
- * updated if @c c gets inserted at the beginning of the list.
- * @param c The command to add to the list pointed to by @c head.
- */
-static void command_add_child(struct command **head, struct command *c)
-{
- assert(head);
- if (NULL == *head) {
- *head = c;
- return;
- }
-
- while ((*head)->next && (strcmp(c->name, (*head)->name) > 0))
- head = &(*head)->next;
-
- if (strcmp(c->name, (*head)->name) > 0) {
- c->next = (*head)->next;
- (*head)->next = c;
- } else {
- c->next = *head;
- *head = c;
- }
-}
-
-static struct command **command_list_for_parent(
- struct command_context *cmd_ctx, struct command *parent)
-{
- return parent ? &parent->children : &cmd_ctx->commands;
-}
-
-static void command_free(struct command *c)
+static struct command *command_find_from_name(Jim_Interp *interp, const char *name)
{
- /** @todo if command has a handler, unregister its jim command! */
+ if (!name)
+ return NULL;
- while (NULL != c->children) {
- struct command *tmp = c->children;
- c->children = tmp->next;
- command_free(tmp);
- }
+ Jim_Obj *jim_name = Jim_NewStringObj(interp, name, -1);
+ Jim_IncrRefCount(jim_name);
+ Jim_Cmd *cmd = Jim_GetCommand(interp, jim_name, JIM_NONE);
+ Jim_DecrRefCount(interp, jim_name);
+ if (!cmd || jimcmd_is_proc(cmd) || !jimcmd_is_ocd_command(cmd))
+ return NULL;
- free(c->name);
- free(c->help);
- free(c->usage);
- free(c);
+ return jimcmd_privdata(cmd);
}
static struct command *command_new(struct command_context *cmd_ctx,
- struct command *parent, const struct command_registration *cr)
+ const char *full_name, const struct command_registration *cr)
{
assert(cr->name);
@@ -341,96 +278,88 @@ static struct command *command_new(struct command_context *cmd_ctx,
* strlen(.usage) == 0 means that the command takes no
* arguments.
*/
- if ((cr->jim_handler == NULL) && (cr->usage == NULL)) {
- LOG_ERROR("BUG: command '%s%s%s' does not have the "
+ if (!cr->jim_handler && !cr->usage)
+ LOG_ERROR("BUG: command '%s' does not have the "
"'.usage' field filled out",
- parent && parent->name ? parent->name : "",
- parent && parent->name ? " " : "",
- cr->name);
- }
+ full_name);
struct command *c = calloc(1, sizeof(struct command));
if (NULL == c)
return NULL;
c->name = strdup(cr->name);
- if (cr->help)
- c->help = strdup(cr->help);
- if (cr->usage)
- c->usage = strdup(cr->usage);
-
- if (!c->name || (cr->help && !c->help) || (cr->usage && !c->usage))
- goto command_new_error;
+ if (!c->name) {
+ free(c);
+ return NULL;
+ }
- c->parent = parent;
c->handler = cr->handler;
c->jim_handler = cr->jim_handler;
c->mode = cr->mode;
- command_add_child(command_list_for_parent(cmd_ctx, parent), c);
+ if (cr->help || cr->usage)
+ help_add_command(cmd_ctx, full_name, cr->help, cr->usage);
return c;
-
-command_new_error:
- command_free(c);
- return NULL;
}
-static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
-
-static int register_command_handler(struct command_context *cmd_ctx,
- struct command *c)
+static void command_free(struct Jim_Interp *interp, void *priv)
{
- Jim_Interp *interp = cmd_ctx->interp;
-
-#if 0
- LOG_DEBUG("registering '%s'...", c->name);
-#endif
-
- Jim_CmdProc *func = c->handler ? &script_command : &command_unknown;
- int retval = Jim_CreateCommand(interp, c->name, func, c, NULL);
+ struct command *c = priv;
- return retval;
+ free(c->name);
+ free(c);
}
static struct command *register_command(struct command_context *context,
- struct command *parent, const struct command_registration *cr)
+ const char *cmd_prefix, const struct command_registration *cr)
{
+ char *full_name;
+
if (!context || !cr->name)
return NULL;
- const char *name = cr->name;
- struct command **head = command_list_for_parent(context, parent);
- struct command *c = command_find(*head, name);
- if (NULL != c) {
+ if (cmd_prefix)
+ full_name = alloc_printf("%s %s", cmd_prefix, cr->name);
+ else
+ full_name = strdup(cr->name);
+ if (!full_name)
+ return NULL;
+
+ struct command *c = command_find_from_name(context->interp, full_name);
+ if (c) {
/* TODO: originally we treated attempting to register a cmd twice as an error
* Sometimes we need this behaviour, such as with flash banks.
* http://www.mail-archive.com/openocd-development@lists.berlios.de/msg11152.html */
- LOG_DEBUG("command '%s' is already registered in '%s' context",
- name, parent ? parent->name : "<global>");
+ LOG_DEBUG("command '%s' is already registered", full_name);
+ free(full_name);
return c;
}
- c = command_new(context, parent, cr);
- if (NULL == c)
+ c = command_new(context, full_name, cr);
+ if (!c) {
+ free(full_name);
return NULL;
+ }
- int retval = JIM_OK;
- if (NULL != cr->jim_handler && NULL == parent) {
- retval = Jim_CreateCommand(context->interp, cr->name,
- cr->jim_handler, NULL, NULL);
- } else if (NULL != cr->handler || NULL != parent)
- retval = register_command_handler(context, command_root(c));
-
+ LOG_DEBUG("registering '%s'...", full_name);
+ int retval = Jim_CreateCommand(context->interp, full_name,
+ jim_command_dispatch, c, command_free);
if (retval != JIM_OK) {
- unregister_command(context, parent, name);
- c = NULL;
+ command_run_linef(context, "del_help_text {%s}", full_name);
+ command_run_linef(context, "del_usage_text {%s}", full_name);
+ free(c);
+ free(full_name);
+ return NULL;
}
+
+ free(full_name);
return c;
}
-int register_commands(struct command_context *cmd_ctx, struct command *parent,
- const struct command_registration *cmds)
+int __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix,
+ const struct command_registration *cmds, void *data,
+ struct target *override_target)
{
int retval = ERROR_OK;
unsigned i;
@@ -439,72 +368,120 @@ int register_commands(struct command_context *cmd_ctx, struct command *parent,
struct command *c = NULL;
if (NULL != cr->name) {
- c = register_command(cmd_ctx, parent, cr);
+ c = register_command(cmd_ctx, cmd_prefix, cr);
if (NULL == c) {
retval = ERROR_FAIL;
break;
}
+ c->jim_handler_data = data;
+ c->jim_override_target = override_target;
}
if (NULL != cr->chain) {
- struct command *p = c ? : parent;
- retval = register_commands(cmd_ctx, p, cr->chain);
+ if (cr->name) {
+ if (cmd_prefix) {
+ char *new_prefix = alloc_printf("%s %s", cmd_prefix, cr->name);
+ if (!new_prefix) {
+ retval = ERROR_FAIL;
+ break;
+ }
+ retval = __register_commands(cmd_ctx, new_prefix, cr->chain, data, override_target);
+ free(new_prefix);
+ } else {
+ retval = __register_commands(cmd_ctx, cr->name, cr->chain, data, override_target);
+ }
+ } else {
+ retval = __register_commands(cmd_ctx, cmd_prefix, cr->chain, data, override_target);
+ }
if (ERROR_OK != retval)
break;
}
}
if (ERROR_OK != retval) {
for (unsigned j = 0; j < i; j++)
- unregister_command(cmd_ctx, parent, cmds[j].name);
+ unregister_command(cmd_ctx, cmd_prefix, cmds[j].name);
}
return retval;
}
-int unregister_all_commands(struct command_context *context,
- struct command *parent)
+static __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)))
+int unregister_commands_match(struct command_context *cmd_ctx, const char *format, ...)
{
- if (context == NULL)
- return ERROR_OK;
+ Jim_Interp *interp = cmd_ctx->interp;
+ va_list ap;
- struct command **head = command_list_for_parent(context, parent);
- while (NULL != *head) {
- struct command *tmp = *head;
- *head = tmp->next;
- command_free(tmp);
- }
+ va_start(ap, format);
+ char *query = alloc_vprintf(format, ap);
+ va_end(ap);
+ if (!query)
+ return ERROR_FAIL;
- return ERROR_OK;
-}
+ char *query_cmd = alloc_printf("info commands {%s}", query);
+ free(query);
+ if (!query_cmd)
+ return ERROR_FAIL;
-static int unregister_command(struct command_context *context,
- struct command *parent, const char *name)
-{
- if ((!context) || (!name))
- return ERROR_COMMAND_SYNTAX_ERROR;
+ int retval = Jim_EvalSource(interp, __THIS__FILE__, __LINE__, query_cmd);
+ free(query_cmd);
+ if (retval != JIM_OK)
+ return ERROR_FAIL;
+
+ Jim_Obj *list = Jim_GetResult(interp);
+ Jim_IncrRefCount(list);
- struct command *p = NULL;
- struct command **head = command_list_for_parent(context, parent);
- for (struct command *c = *head; NULL != c; p = c, c = c->next) {
- if (strcmp(name, c->name) != 0)
+ int len = Jim_ListLength(interp, list);
+ for (int i = 0; i < len; i++) {
+ Jim_Obj *elem = Jim_ListGetIndex(interp, list, i);
+ Jim_IncrRefCount(elem);
+
+ const char *name = Jim_GetString(elem, NULL);
+ struct command *c = command_find_from_name(interp, name);
+ if (!c) {
+ /* not openocd command */
+ Jim_DecrRefCount(interp, elem);
continue;
+ }
+ LOG_DEBUG("delete command \"%s\"", name);
+#if JIM_VERSION >= 80
+ Jim_DeleteCommand(interp, elem);
+#else
+ Jim_DeleteCommand(interp, name);
+#endif
- if (p)
- p->next = c->next;
- else
- *head = c->next;
+ help_del_command(cmd_ctx, name);
- command_free(c);
- return ERROR_OK;
+ Jim_DecrRefCount(interp, elem);
}
+ Jim_DecrRefCount(interp, list);
return ERROR_OK;
}
-void command_set_handler_data(struct command *c, void *p)
+int unregister_all_commands(struct command_context *context,
+ const char *cmd_prefix)
+{
+ if (!context)
+ return ERROR_OK;
+
+ if (!cmd_prefix || !*cmd_prefix)
+ return unregister_commands_match(context, "*");
+
+ int retval = unregister_commands_match(context, "%s *", cmd_prefix);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return unregister_commands_match(context, "%s", cmd_prefix);
+}
+
+static int unregister_command(struct command_context *context,
+ const char *cmd_prefix, const char *name)
{
- if (NULL != c->handler || NULL != c->jim_handler)
- c->jim_handler_data = p;
- for (struct command *cc = c->children; NULL != cc; cc = cc->next)
- command_set_handler_data(cc, p);
+ if (!context || !name)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (!cmd_prefix || !*cmd_prefix)
+ return unregister_commands_match(context, "%s", name);
+
+ return unregister_commands_match(context, "%s %s", cmd_prefix, name);
}
void command_output_text(struct command_context *context, const char *data)
@@ -561,34 +538,7 @@ void command_print(struct command_invocation *cmd, const char *format, ...)
va_end(ap);
}
-static char *__command_name(struct command *c, char delim, unsigned extra)
-{
- char *name;
- unsigned len = strlen(c->name);
- if (NULL == c->parent) {
- /* allocate enough for the name, child names, and '\0' */
- name = malloc(len + extra + 1);
- if (!name) {
- LOG_ERROR("Out of memory");
- return NULL;
- }
- strcpy(name, c->name);
- } else {
- /* parent's extra must include both the space and name */
- name = __command_name(c->parent, delim, 1 + len + extra);
- char dstr[2] = { delim, 0 };
- strcat(name, dstr);
- strcat(name, c->name);
- }
- return name;
-}
-
-static char *command_name(struct command *c, char delim)
-{
- return __command_name(c, delim, 0);
-}
-
-static bool command_can_run(struct command_context *cmd_ctx, struct command *c)
+static bool command_can_run(struct command_context *cmd_ctx, struct command *c, const char *full_name)
{
if (c->mode == COMMAND_ANY || c->mode == cmd_ctx->mode)
return true;
@@ -607,19 +557,14 @@ static bool command_can_run(struct command_context *cmd_ctx, struct command *c)
when = "if Cthulhu is summoned by";
break;
}
- char *full_name = command_name(c, ' ');
LOG_ERROR("The '%s' command must be used %s 'init'.",
full_name ? full_name : c->name, when);
- free(full_name);
return false;
}
static int run_command(struct command_context *context,
- struct command *c, const char *words[], unsigned num_words)
+ struct command *c, const char **words, unsigned num_words)
{
- if (!command_can_run(context, c))
- return ERROR_FAIL;
-
struct command_invocation cmd = {
.ctx = context,
.current = c,
@@ -627,42 +572,20 @@ static int run_command(struct command_context *context,
.argc = num_words - 1,
.argv = words + 1,
};
- /* Black magic of overridden current target:
- * If the command we are going to handle has a target prefix,
- * override the current target temporarily for the time
- * of processing the command.
- * current_target_override is used also for event handlers
- * therefore we prevent touching it if command has no prefix.
- * Previous override is saved and restored back to ensure
- * correct work when run_command() is re-entered. */
- struct target *saved_target_override = context->current_target_override;
- if (c->jim_handler_data)
- context->current_target_override = c->jim_handler_data;
cmd.output = Jim_NewEmptyStringObj(context->interp);
Jim_IncrRefCount(cmd.output);
int retval = c->handler(&cmd);
-
- if (c->jim_handler_data)
- context->current_target_override = saved_target_override;
-
if (retval == ERROR_COMMAND_SYNTAX_ERROR) {
/* Print help for command */
- char *full_name = command_name(c, ' ');
- if (NULL != full_name) {
- command_run_linef(context, "usage %s", full_name);
- free(full_name);
- }
+ command_run_linef(context, "usage %s", words[0]);
} else if (retval == ERROR_COMMAND_CLOSE_CONNECTION) {
/* just fall through for a shutdown request */
} else {
- if (retval != ERROR_OK) {
- char *full_name = command_name(c, ' ');
+ if (retval != ERROR_OK)
LOG_DEBUG("Command '%s' failed with error code %d",
- full_name ? full_name : c->name, retval);
- free(full_name);
- }
+ words[0], retval);
/* Use the command output as the Tcl result */
Jim_SetResult(context->interp, cmd.output);
}
@@ -834,28 +757,22 @@ static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return retcode;
}
-static COMMAND_HELPER(command_help_find, struct command *head,
- struct command **out)
-{
- if (0 == CMD_ARGC)
- return ERROR_COMMAND_SYNTAX_ERROR;
- *out = command_find(head, CMD_ARGV[0]);
- if (NULL == *out)
- return ERROR_COMMAND_SYNTAX_ERROR;
- if (--CMD_ARGC == 0)
- return ERROR_OK;
- CMD_ARGV++;
- return CALL_COMMAND_HANDLER(command_help_find, (*out)->children, out);
-}
+struct help_entry {
+ struct list_head lh;
+ char *cmd_name;
+ char *help;
+ char *usage;
+};
-static COMMAND_HELPER(command_help_show, struct command *c, unsigned n,
+static COMMAND_HELPER(command_help_show, struct help_entry *c,
bool show_help, const char *cmd_match);
-static COMMAND_HELPER(command_help_show_list, struct command *head, unsigned n,
- bool show_help, const char *cmd_match)
+static COMMAND_HELPER(command_help_show_list, bool show_help, const char *cmd_match)
{
- for (struct command *c = head; NULL != c; c = c->next)
- CALL_COMMAND_HANDLER(command_help_show, c, n, show_help, cmd_match);
+ struct help_entry *entry;
+
+ list_for_each_entry(entry, CMD_CTX->help_list, lh)
+ CALL_COMMAND_HANDLER(command_help_show, entry, show_help, cmd_match);
return ERROR_OK;
}
@@ -886,26 +803,23 @@ static void command_help_show_wrap(const char *str, unsigned n, unsigned n2)
}
}
-static COMMAND_HELPER(command_help_show, struct command *c, unsigned n,
+static COMMAND_HELPER(command_help_show, struct help_entry *c,
bool show_help, const char *cmd_match)
{
- char *cmd_name = command_name(c, ' ');
- if (NULL == cmd_name)
- return ERROR_FAIL;
+ unsigned int n = 0;
+ for (const char *s = strchr(c->cmd_name, ' '); s; s = strchr(s + 1, ' '))
+ n++;
/* If the match string occurs anywhere, we print out
* stuff for this command. */
- bool is_match = (strstr(cmd_name, cmd_match) != NULL) ||
+ bool is_match = (strstr(c->cmd_name, cmd_match) != NULL) ||
((c->usage != NULL) && (strstr(c->usage, cmd_match) != NULL)) ||
((c->help != NULL) && (strstr(c->help, cmd_match) != NULL));
if (is_match) {
command_help_show_indent(n);
- LOG_USER_N("%s", cmd_name);
- }
- free(cmd_name);
+ LOG_USER_N("%s", c->cmd_name);
- if (is_match) {
if (c->usage && strlen(c->usage) > 0) {
LOG_USER_N(" ");
command_help_show_wrap(c->usage, 0, n + 5);
@@ -916,11 +830,30 @@ static COMMAND_HELPER(command_help_show, struct command *c, unsigned n,
if (is_match && show_help) {
char *msg;
+ /* TODO: factorize jim_command_mode() to avoid running jim command here */
+ char *request = alloc_printf("command mode %s", c->cmd_name);
+ if (!request) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+ int retval = Jim_Eval(CMD_CTX->interp, request);
+ free(request);
+ enum command_mode mode = COMMAND_UNKNOWN;
+ if (retval != JIM_ERR) {
+ const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL);
+ if (!strcmp(result, "any"))
+ mode = COMMAND_ANY;
+ else if (!strcmp(result, "config"))
+ mode = COMMAND_CONFIG;
+ else if (!strcmp(result, "exec"))
+ mode = COMMAND_EXEC;
+ }
+
/* Normal commands are runtime-only; highlight exceptions */
- if (c->mode != COMMAND_EXEC) {
+ if (mode != COMMAND_EXEC) {
const char *stage_msg = "";
- switch (c->mode) {
+ switch (mode) {
case COMMAND_CONFIG:
stage_msg = " (configuration command)";
break;
@@ -942,20 +875,13 @@ static COMMAND_HELPER(command_help_show, struct command *c, unsigned n,
return -ENOMEM;
}
- if (++n > 5) {
- LOG_ERROR("command recursion exceeded");
- return ERROR_FAIL;
- }
-
- return CALL_COMMAND_HANDLER(command_help_show_list,
- c->children, n, show_help, cmd_match);
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_help_command)
{
bool full = strcmp(CMD_NAME, "help") == 0;
int retval;
- struct command *c = CMD_CTX->commands;
char *cmd_match;
if (CMD_ARGC <= 0)
@@ -975,26 +901,12 @@ COMMAND_HANDLER(handle_help_command)
LOG_ERROR("unable to build search string");
return -ENOMEM;
}
- retval = CALL_COMMAND_HANDLER(command_help_show_list,
- c, 0, full, cmd_match);
+ retval = CALL_COMMAND_HANDLER(command_help_show_list, full, cmd_match);
free(cmd_match);
return retval;
}
-static int command_unknown_find(unsigned argc, Jim_Obj *const *argv,
- struct command *head, struct command **out)
-{
- if (0 == argc)
- return argc;
- const char *cmd_name = Jim_GetString(argv[0], NULL);
- struct command *c = command_find(head, cmd_name);
- if (NULL == c)
- return argc;
- *out = c;
- return command_unknown_find(--argc, ++argv, (*out)->children, out);
-}
-
static char *alloc_concatenate_strings(int argc, Jim_Obj * const *argv)
{
char *prev, *all;
@@ -1021,75 +933,75 @@ static char *alloc_concatenate_strings(int argc, Jim_Obj * const *argv)
return all;
}
-static int run_usage(Jim_Interp *interp, int argc_valid, int argc, Jim_Obj * const *argv)
+static int exec_command(Jim_Interp *interp, struct command_context *cmd_ctx,
+ struct command *c, int argc, Jim_Obj * const *argv)
{
- struct command_context *cmd_ctx = current_command_context(interp);
- char *command;
- int retval;
+ if (c->jim_handler)
+ return c->jim_handler(interp, argc, argv);
- assert(argc_valid >= 1);
- assert(argc >= argc_valid);
-
- command = alloc_concatenate_strings(argc_valid, argv);
- if (!command)
- return JIM_ERR;
-
- retval = command_run_linef(cmd_ctx, "usage %s", command);
- if (retval != ERROR_OK) {
- LOG_ERROR("unable to execute command \"usage %s\"", command);
+ /* use c->handler */
+ unsigned int nwords;
+ char **words = script_command_args_alloc(argc, argv, &nwords);
+ if (!words)
return JIM_ERR;
- }
-
- if (argc_valid == argc)
- LOG_ERROR("%s: command requires more arguments", command);
- else {
- free(command);
- command = alloc_concatenate_strings(argc - argc_valid, argv + argc_valid);
- if (!command)
- return JIM_ERR;
- LOG_ERROR("invalid subcommand \"%s\"", command);
- }
- free(command);
- return retval;
+ int retval = run_command(cmd_ctx, c, (const char **)words, nwords);
+ script_command_args_free(words, nwords);
+ return command_retval_set(interp, retval);
}
-static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
script_debug(interp, argc, argv);
- struct command_context *cmd_ctx = current_command_context(interp);
- struct command *c = cmd_ctx->commands;
- int remaining = command_unknown_find(argc, argv, c, &c);
- /* if nothing could be consumed, then it's really an unknown command */
- if (remaining == argc) {
- const char *cmd = Jim_GetString(argv[0], NULL);
- LOG_ERROR("Unknown command:\n %s", cmd);
- return JIM_OK;
+ /* check subcommands */
+ if (argc > 1) {
+ char *s = alloc_printf("%s %s", Jim_GetString(argv[0], NULL), Jim_GetString(argv[1], NULL));
+ Jim_Obj *js = Jim_NewStringObj(interp, s, -1);
+ Jim_IncrRefCount(js);
+ free(s);
+ Jim_Cmd *cmd = Jim_GetCommand(interp, js, JIM_NONE);
+ if (cmd) {
+ int retval = Jim_EvalObjPrefix(interp, js, argc - 2, argv + 2);
+ Jim_DecrRefCount(interp, js);
+ return retval;
+ }
+ Jim_DecrRefCount(interp, js);
}
- Jim_Obj *const *start;
- unsigned count;
- if (c->handler || c->jim_handler) {
- /* include the command name in the list */
- count = remaining + 1;
- start = argv + (argc - remaining - 1);
- } else {
- count = argc - remaining;
- start = argv;
- run_usage(interp, count, argc, start);
+ struct command *c = jim_to_command(interp);
+ if (!c->jim_handler && !c->handler) {
+ Jim_EvalObjPrefix(interp, Jim_NewStringObj(interp, "usage", -1), 1, argv);
return JIM_ERR;
}
- /* pass the command through to the intended handler */
- if (c->jim_handler) {
- if (!command_can_run(cmd_ctx, c))
- return JIM_ERR;
- interp->cmdPrivData = c->jim_handler_data;
- return (*c->jim_handler)(interp, count, start);
- }
+ struct command_context *cmd_ctx = current_command_context(interp);
+
+ if (!command_can_run(cmd_ctx, c, Jim_GetString(argv[0], NULL)))
+ return JIM_ERR;
+
+ target_call_timer_callbacks_now(NULL);
+
+ /*
+ * Black magic of overridden current target:
+ * If the command we are going to handle has a target prefix,
+ * override the current target temporarily for the time
+ * of processing the command.
+ * current_target_override is used also for event handlers
+ * therefore we prevent touching it if command has no prefix.
+ * Previous override is saved and restored back to ensure
+ * correct work when jim_command_dispatch() is re-entered.
+ */
+ struct target *saved_target_override = cmd_ctx->current_target_override;
+ if (c->jim_override_target)
+ cmd_ctx->current_target_override = c->jim_override_target;
+
+ int retval = exec_command(interp, cmd_ctx, c, argc, argv);
- return script_command_run(interp, count, start, c);
+ if (c->jim_override_target)
+ cmd_ctx->current_target_override = saved_target_override;
+
+ return retval;
}
static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -1098,14 +1010,27 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
enum command_mode mode;
if (argc > 1) {
- struct command *c = cmd_ctx->commands;
- int remaining = command_unknown_find(argc - 1, argv + 1, c, &c);
- /* if nothing could be consumed, then it's an unknown command */
- if (remaining == argc - 1) {
+ char *full_name = alloc_concatenate_strings(argc - 1, argv + 1);
+ if (!full_name)
+ return JIM_ERR;
+ Jim_Obj *s = Jim_NewStringObj(interp, full_name, -1);
+ Jim_IncrRefCount(s);
+ Jim_Cmd *cmd = Jim_GetCommand(interp, s, JIM_NONE);
+ Jim_DecrRefCount(interp, s);
+ free(full_name);
+ if (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_ocd_command(cmd))) {
Jim_SetResultString(interp, "unknown", -1);
return JIM_OK;
}
- mode = c->mode;
+
+ if (jimcmd_is_proc(cmd)) {
+ /* tcl proc */
+ mode = COMMAND_ANY;
+ } else {
+ struct command *c = jimcmd_privdata(cmd);
+
+ mode = c->mode;
+ }
} else
mode = cmd_ctx->mode;
@@ -1128,81 +1053,104 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return JIM_OK;
}
-int help_add_command(struct command_context *cmd_ctx, struct command *parent,
- const char *cmd_name, const char *help_text, const char *usage)
+int help_del_all_commands(struct command_context *cmd_ctx)
+{
+ struct help_entry *curr, *n;
+
+ list_for_each_entry_safe(curr, n, cmd_ctx->help_list, lh) {
+ list_del(&curr->lh);
+ free(curr->cmd_name);
+ free(curr->help);
+ free(curr->usage);
+ free(curr);
+ }
+ return ERROR_OK;
+}
+
+static int help_del_command(struct command_context *cmd_ctx, const char *cmd_name)
+{
+ struct help_entry *curr;
+
+ list_for_each_entry(curr, cmd_ctx->help_list, lh) {
+ if (!strcmp(cmd_name, curr->cmd_name)) {
+ list_del(&curr->lh);
+ free(curr->cmd_name);
+ free(curr->help);
+ free(curr->usage);
+ free(curr);
+ break;
+ }
+ }
+
+ return ERROR_OK;
+}
+
+static int help_add_command(struct command_context *cmd_ctx,
+ const char *cmd_name, const char *help_text, const char *usage_text)
{
- struct command **head = command_list_for_parent(cmd_ctx, parent);
- struct command *nc = command_find(*head, cmd_name);
- if (NULL == nc) {
- /* add a new command with help text */
- struct command_registration cr = {
- .name = cmd_name,
- .mode = COMMAND_ANY,
- .help = help_text,
- .usage = usage ? : "",
- };
- nc = register_command(cmd_ctx, parent, &cr);
- if (NULL == nc) {
- LOG_ERROR("failed to add '%s' help text", cmd_name);
+ int cmp = -1; /* add after curr */
+ struct help_entry *curr;
+
+ list_for_each_entry_reverse(curr, cmd_ctx->help_list, lh) {
+ cmp = strcmp(cmd_name, curr->cmd_name);
+ if (cmp >= 0)
+ break;
+ }
+
+ struct help_entry *entry;
+ if (cmp) {
+ entry = calloc(1, sizeof(*entry));
+ if (!entry) {
+ LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
- LOG_DEBUG("added '%s' help text", cmd_name);
- return ERROR_OK;
+ entry->cmd_name = strdup(cmd_name);
+ if (!entry->cmd_name) {
+ LOG_ERROR("Out of memory");
+ free(entry);
+ return ERROR_FAIL;
+ }
+ list_add(&entry->lh, &curr->lh);
+ } else {
+ entry = curr;
}
+
if (help_text) {
- bool replaced = false;
- if (nc->help) {
- free(nc->help);
- replaced = true;
+ char *text = strdup(help_text);
+ if (!text) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
}
- nc->help = strdup(help_text);
- if (replaced)
- LOG_INFO("replaced existing '%s' help", cmd_name);
- else
- LOG_DEBUG("added '%s' help text", cmd_name);
+ free(entry->help);
+ entry->help = text;
}
- if (usage) {
- bool replaced = false;
- if (nc->usage) {
- if (*nc->usage)
- replaced = true;
- free(nc->usage);
+
+ if (usage_text) {
+ char *text = strdup(usage_text);
+ if (!text) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
}
- nc->usage = strdup(usage);
- if (replaced)
- LOG_INFO("replaced existing '%s' usage", cmd_name);
- else
- LOG_DEBUG("added '%s' usage text", cmd_name);
+ free(entry->usage);
+ entry->usage = text;
}
+
return ERROR_OK;
}
COMMAND_HANDLER(handle_help_add_command)
{
- if (CMD_ARGC < 2) {
- LOG_ERROR("%s: insufficient arguments", CMD_NAME);
+ if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- }
- /* save help text and remove it from argument list */
- const char *str = CMD_ARGV[--CMD_ARGC];
- const char *help = !strcmp(CMD_NAME, "add_help_text") ? str : NULL;
- const char *usage = !strcmp(CMD_NAME, "add_usage_text") ? str : NULL;
+ const char *help = !strcmp(CMD_NAME, "add_help_text") ? CMD_ARGV[1] : NULL;
+ const char *usage = !strcmp(CMD_NAME, "add_usage_text") ? CMD_ARGV[1] : NULL;
if (!help && !usage) {
LOG_ERROR("command name '%s' is unknown", CMD_NAME);
return ERROR_COMMAND_SYNTAX_ERROR;
}
- /* likewise for the leaf command name */
- const char *cmd_name = CMD_ARGV[--CMD_ARGC];
-
- struct command *c = NULL;
- if (CMD_ARGC > 0) {
- c = CMD_CTX->commands;
- int retval = CALL_COMMAND_HANDLER(command_help_find, c, &c);
- if (ERROR_OK != retval)
- return retval;
- }
- return help_add_command(CMD_CTX, c, cmd_name, help, usage);
+ const char *cmd_name = CMD_ARGV[0];
+ return help_add_command(CMD_CTX, cmd_name, help, usage);
}
/* sleep command sleeps for <n> milliseconds
@@ -1329,10 +1277,13 @@ static const struct command_registration command_builtin_handlers[] = {
struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp)
{
struct command_context *context = calloc(1, sizeof(struct command_context));
- const char *HostOs;
context->mode = COMMAND_EXEC;
+ /* context can be duplicated. Put list head on separate mem-chunk to keep list consistent */
+ context->help_list = malloc(sizeof(*context->help_list));
+ INIT_LIST_HEAD(context->help_list);
+
/* Create a jim interpreter if we were not handed one */
if (interp == NULL) {
/* Create an interpreter */
@@ -1344,39 +1295,6 @@ struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp
context->interp = interp;
- /* Stick to lowercase for HostOS strings. */
-#if defined(_MSC_VER)
- /* WinXX - is generic, the forward
- * looking problem is this:
- *
- * "win32" or "win64"
- *
- * "winxx" is generic.
- */
- HostOs = "winxx";
-#elif defined(__linux__)
- HostOs = "linux";
-#elif defined(__APPLE__) || defined(__DARWIN__)
- HostOs = "darwin";
-#elif defined(__CYGWIN__)
- HostOs = "cygwin";
-#elif defined(__MINGW32__)
- HostOs = "mingw32";
-#elif defined(__ECOS)
- HostOs = "ecos";
-#elif defined(__FreeBSD__)
- HostOs = "freebsd";
-#elif defined(__NetBSD__)
- HostOs = "netbsd";
-#elif defined(__OpenBSD__)
- HostOs = "openbsd";
-#else
-#warning "Unrecognized host OS..."
- HostOs = "other";
-#endif
- Jim_SetGlobalVariableStr(interp, "ocd_HOSTOS",
- Jim_NewStringObj(interp, HostOs, strlen(HostOs)));
-
register_commands(context, NULL, command_builtin_handlers);
Jim_SetAssocData(interp, "context", NULL, context);
@@ -1397,6 +1315,7 @@ void command_exit(struct command_context *context)
return;
Jim_FreeInterp(context->interp);
+ free(context->help_list);
command_done(context);
}
diff --git a/src/helper/command.h b/src/helper/command.h
index b0c84bb..68f4c14 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -26,6 +26,7 @@
#include <stdbool.h>
#include <jim-nvp.h>
+#include <helper/list.h>
#include <helper/types.h>
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
@@ -41,6 +42,7 @@ enum command_mode {
COMMAND_EXEC,
COMMAND_CONFIG,
COMMAND_ANY,
+ COMMAND_UNKNOWN = -1, /* error condition */
};
struct command_context;
@@ -52,7 +54,6 @@ typedef int (*command_output_handler_t)(struct command_context *context,
struct command_context {
Jim_Interp *interp;
enum command_mode mode;
- struct command *commands;
struct target *current_target;
/* The target set by 'targets xx' command or the latest created */
struct target *current_target_override;
@@ -64,6 +65,7 @@ struct command_context {
*/
command_output_handler_t output_handler;
void *output_handler_priv;
+ struct list_head *help_list;
};
struct command;
@@ -179,23 +181,25 @@ typedef __COMMAND_HANDLER((*command_handler_t));
struct command {
char *name;
- char *help;
- char *usage;
- struct command *parent;
- struct command *children;
command_handler_t handler;
Jim_CmdProc *jim_handler;
void *jim_handler_data;
- /* Currently used only for target of target-prefixed cmd.
- * Native OpenOCD commands use jim_handler_data exclusively
- * as a target override.
- * Jim handlers outside of target cmd tree can use
- * jim_handler_data for any handler specific data */
+ /* Command handlers can use it for any handler specific data */
+ struct target *jim_override_target;
+ /* Used only for target of target-prefixed cmd */
enum command_mode mode;
- struct command *next;
};
/*
+ * Return the struct command pointer kept in private data
+ * Used to enforce check on data type
+ */
+static inline struct command *jim_to_command(Jim_Interp *interp)
+{
+ return Jim_CmdPrivData(interp);
+}
+
+/*
* Commands should be registered by filling in one or more of these
* structures and passing them to [un]register_commands().
*
@@ -233,6 +237,10 @@ struct command_registration {
/** Use this as the last entry in an array of command_registration records. */
#define COMMAND_REGISTRATION_DONE { .name = NULL, .chain = NULL }
+int __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix,
+ const struct command_registration *cmds, void *data,
+ struct target *override_target);
+
/**
* Register one or more commands in the specified context, as children
* of @c parent (or top-level commends, if NULL). In a registration's
@@ -241,37 +249,77 @@ struct command_registration {
* Otherwise, the chained commands are added as children of the command.
*
* @param cmd_ctx The command_context in which to register the command.
- * @param parent Register this command as a child of this, or NULL to
+ * @param cmd_prefix Register this command as a child of this, or NULL to
+ * register a top-level command.
+ * @param cmds Pointer to an array of command_registration records that
+ * contains the desired command parameters. The last record must have
+ * NULL for all fields.
+ * @returns ERROR_OK on success; ERROR_FAIL if any registration fails.
+ */
+static inline int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix,
+ const struct command_registration *cmds)
+{
+ return __register_commands(cmd_ctx, cmd_prefix, cmds, NULL, NULL);
+}
+
+/**
+ * Register one or more commands, as register_commands(), plus specify
+ * that command should override the current target
+ *
+ * @param cmd_ctx The command_context in which to register the command.
+ * @param cmd_prefix Register this command as a child of this, or NULL to
* register a top-level command.
* @param cmds Pointer to an array of command_registration records that
* contains the desired command parameters. The last record must have
* NULL for all fields.
+ * @param target The target that has to override current target.
* @returns ERROR_OK on success; ERROR_FAIL if any registration fails.
*/
-int register_commands(struct command_context *cmd_ctx, struct command *parent,
- const struct command_registration *cmds);
+static inline int register_commands_override_target(struct command_context *cmd_ctx,
+ const char *cmd_prefix, const struct command_registration *cmds,
+ struct target *target)
+{
+ return __register_commands(cmd_ctx, cmd_prefix, cmds, NULL, target);
+}
+
+/**
+ * Register one or more commands, as register_commands(), plus specify
+ * a pointer to command private data that would be accessible through
+ * the macro CMD_DATA. The private data will not be freed when command
+ * is unregistered.
+ *
+ * @param cmd_ctx The command_context in which to register the command.
+ * @param cmd_prefix Register this command as a child of this, or NULL to
+ * register a top-level command.
+ * @param cmds Pointer to an array of command_registration records that
+ * contains the desired command parameters. The last record must have
+ * NULL for all fields.
+ * @param data The command private data.
+ * @returns ERROR_OK on success; ERROR_FAIL if any registration fails.
+ */
+static inline int register_commands_with_data(struct command_context *cmd_ctx,
+ const char *cmd_prefix, const struct command_registration *cmds,
+ void *data)
+{
+ return __register_commands(cmd_ctx, cmd_prefix, cmds, data, NULL);
+}
/**
* Unregisters all commands from the specified context.
* @param cmd_ctx The context that will be cleared of registered commands.
- * @param parent If given, only clear commands from under this one command.
+ * @param cmd_prefix If given, only clear commands from under this one command.
* @returns ERROR_OK on success, or an error code.
*/
int unregister_all_commands(struct command_context *cmd_ctx,
- struct command *parent);
-
-struct command *command_find_in_context(struct command_context *cmd_ctx,
- const char *name);
+ const char *cmd_prefix);
/**
- * Update the private command data field for a command and all descendents.
- * This is used when creating a new hierarchy of commands that depends
- * on obtaining a dynamically created context. The value will be available
- * in command handlers by using the CMD_DATA macro.
- * @param c The command (group) whose data pointer(s) will be updated.
- * @param p The new data pointer to use for the command or its descendents.
+ * Unregisters the help for all commands. Used at exit to remove the help
+ * added through the commands 'add_help_text' and 'add_usage_text'.
+ * @param cmd_ctx The context that will be cleared of registered helps.
+ * @returns ERROR_OK on success, or an error code.
*/
-void command_set_handler_data(struct command *c, void *p);
+int help_del_all_commands(struct command_context *cmd_ctx);
void command_set_output_handler(struct command_context *context,
command_output_handler_t output_handler, void *priv);
@@ -408,6 +456,4 @@ COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label);
#define COMMAND_PARSE_ENABLE(in, out) \
COMMAND_PARSE_BOOL(in, out, "enable", "disable")
-void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const *argv);
-
#endif /* OPENOCD_HELPER_COMMAND_H */
diff --git a/src/helper/jim-nvp.c b/src/helper/jim-nvp.c
index d13bdfb..2caf18b 100644
--- a/src/helper/jim-nvp.c
+++ b/src/helper/jim-nvp.c
@@ -333,9 +333,3 @@ const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *a
return Jim_String(debug_string_obj);
}
-
-int Jim_nvpInit(Jim_Interp *interp)
-{
- /* This is really a helper library, not an extension, but this is the easy way */
- return JIM_OK;
-}
diff --git a/src/helper/replacements.h b/src/helper/replacements.h
index 1b6e5bd..5aecf41 100644
--- a/src/helper/replacements.h
+++ b/src/helper/replacements.h
@@ -242,13 +242,13 @@ static inline int socket_select(int max_fd,
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Off;
-typedef int32_t Elf32_Sword;
typedef uint32_t Elf32_Word;
typedef uint32_t Elf32_Size;
-typedef Elf32_Off Elf32_Hashelt;
+
+#define EI_NIDENT 16
typedef struct {
- unsigned char e_ident[16]; /* Magic number and other info */
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
@@ -290,6 +290,44 @@ typedef struct {
#endif /* HAVE_ELF_H */
+#ifndef HAVE_ELF64
+
+typedef uint64_t Elf64_Addr;
+typedef uint16_t Elf64_Half;
+typedef uint64_t Elf64_Off;
+typedef uint32_t Elf64_Word;
+typedef uint64_t Elf64_Xword;
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf64_Half e_type; /* Object file type */
+ Elf64_Half e_machine; /* Architecture */
+ Elf64_Word e_version; /* Object file version */
+ Elf64_Addr e_entry; /* Entry point virtual address */
+ Elf64_Off e_phoff; /* Program header table file offset */
+ Elf64_Off e_shoff; /* Section header table file offset */
+ Elf64_Word e_flags; /* Processor-specific flags */
+ Elf64_Half e_ehsize; /* ELF header size in bytes */
+ Elf64_Half e_phentsize; /* Program header table entry size */
+ Elf64_Half e_phnum; /* Program header table entry count */
+ Elf64_Half e_shentsize; /* Section header table entry size */
+ Elf64_Half e_shnum; /* Section header table entry count */
+ Elf64_Half e_shstrndx; /* Section header string table index */
+} Elf64_Ehdr;
+
+typedef struct {
+ Elf64_Word p_type; /* Segment type */
+ Elf64_Word p_flags; /* Segment flags */
+ Elf64_Off p_offset; /* Segment file offset */
+ Elf64_Addr p_vaddr; /* Segment virtual address */
+ Elf64_Addr p_paddr; /* Segment physical address */
+ Elf64_Xword p_filesz; /* Segment size in file */
+ Elf64_Xword p_memsz; /* Segment size in memory */
+ Elf64_Xword p_align; /* Segment alignment */
+} Elf64_Phdr;
+
+#endif /* HAVE_ELF64 */
+
#if defined HAVE_LIBUSB1 && !defined HAVE_LIBUSB_ERROR_NAME
const char *libusb_error_name(int error_code);
#endif /* defined HAVE_LIBUSB1 && !defined HAVE_LIBUSB_ERROR_NAME */
diff --git a/src/helper/system.h b/src/helper/system.h
index 1aaca3b..0d8be64 100644
--- a/src/helper/system.h
+++ b/src/helper/system.h
@@ -21,6 +21,15 @@
#ifndef OPENOCD_HELPER_SYSTEM_H
#define OPENOCD_HELPER_SYSTEM_H
+/* +++ platform specific headers +++ */
+#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+/* --- platform specific headers --- */
+
/* standard C library header files */
#include <stdio.h>
#include <stdlib.h>
@@ -34,15 +43,6 @@
#include <sys/time.h>
#endif
-/* +++ platform specific headers +++ */
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#endif
-/* --- platform specific headers --- */
-
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
diff --git a/src/helper/types.h b/src/helper/types.h
index f3d5e04..010529f 100644
--- a/src/helper/types.h
+++ b/src/helper/types.h
@@ -47,16 +47,10 @@
#ifndef __cplusplus
#define false 0
-#define true 1
+#define true 1
-typedef int _Bool;
-#else
-typedef bool _Bool;
#endif /* __cplusplus */
#endif /* HAVE__BOOL */
-
-#define bool _Bool
-
#endif /* HAVE_STDBOOL_H */
/// turns a macro argument into a string constant
diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c
index 2dd24b9..e464b86 100644
--- a/src/jtag/aice/aice_pipe.c
+++ b/src/jtag/aice/aice_pipe.c
@@ -19,6 +19,8 @@
#include "config.h"
#endif
+#include <helper/system.h>
+
#ifdef _WIN32
#include <windows.h>
#else
diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c
index 0c9f303..c02a42f 100644
--- a/src/jtag/aice/aice_transport.c
+++ b/src/jtag/aice/aice_transport.c
@@ -256,9 +256,8 @@ static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const
e = aice_init_reset(context);
if (e != ERROR_OK) {
- Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e);
- Jim_SetResultFormatted(goi.interp, "error: %#s", eObj);
- Jim_FreeNewObj(goi.interp, eObj);
+ Jim_Obj *obj = Jim_NewIntObj(goi.interp, e);
+ Jim_SetResultFormatted(goi.interp, "error: %#s", obj);
return JIM_ERR;
}
return JIM_OK;
diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c
index c5a0eb7..b59c8f9 100644
--- a/src/jtag/aice/aice_usb.c
+++ b/src/jtag/aice/aice_usb.c
@@ -19,6 +19,7 @@
#include "config.h"
#endif
+#include <helper/system.h>
#include <jtag/drivers/libusb_helper.h>
#include <helper/log.h>
#include <helper/time_support.h>
@@ -350,8 +351,8 @@ static void aice_unpack_dthmb(uint8_t *cmd_ack_code, uint8_t *target_id,
/* calls the given usb_bulk_* function, allowing for the data to
* trickle in with some timeouts */
static int usb_bulk_with_retries(
- int (*f)(libusb_device_handle *, int, char *, int, int, int *),
- libusb_device_handle *dev, int ep,
+ int (*f)(struct libusb_device_handle *, int, char *, int, int, int *),
+ struct libusb_device_handle *dev, int ep,
char *bytes, int size, int timeout, int *transferred)
{
int tries = 3, count = 0;
@@ -370,7 +371,7 @@ static int usb_bulk_with_retries(
return ERROR_OK;
}
-static int wrap_usb_bulk_write(libusb_device_handle *dev, int ep,
+static int wrap_usb_bulk_write(struct libusb_device_handle *dev, int ep,
char *buff, int size, int timeout, int *transferred)
{
@@ -380,7 +381,7 @@ static int wrap_usb_bulk_write(libusb_device_handle *dev, int ep,
return 0;
}
-static inline int usb_bulk_write_ex(libusb_device_handle *dev, int ep,
+static inline int usb_bulk_write_ex(struct libusb_device_handle *dev, int ep,
char *bytes, int size, int timeout)
{
int tr = 0;
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index 6d60b71..26e576b 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -137,6 +137,7 @@ static bool swd_mode;
/* CMSIS-DAP SWD Commands */
#define CMD_DAP_SWD_CONFIGURE 0x13
+#define CMD_DAP_SWD_SEQUENCE 0x1D
/* CMSIS-DAP JTAG Commands */
#define CMD_DAP_JTAG_SEQ 0x14
@@ -222,6 +223,8 @@ static uint8_t output_pins = SWJ_PIN_SRST | SWJ_PIN_TRST;
static struct cmsis_dap *cmsis_dap_handle;
+static int cmsis_dap_quit(void);
+
static int cmsis_dap_open(void)
{
const struct cmsis_dap_backend *backend = NULL;
@@ -280,6 +283,21 @@ static void cmsis_dap_close(struct cmsis_dap *dap)
}
}
+static void cmsis_dap_flush_read(struct cmsis_dap *dap)
+{
+ unsigned int i;
+ /* Some CMSIS-DAP adapters keep buffered packets over
+ * USB close/open so we need to flush up to 64 old packets
+ * to be sure all buffers are empty */
+ for (i = 0; i < 64; i++) {
+ int retval = dap->backend->read(dap, 10);
+ if (retval == ERROR_TIMEOUT_REACHED)
+ break;
+ }
+ if (i)
+ LOG_DEBUG("Flushed %u packets", i);
+}
+
/* Send a message and receive the reply */
static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
{
@@ -293,6 +311,7 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
pending_fifo_get_idx = 0;
}
+ uint8_t current_cmd = cmsis_dap_handle->command[0];
int retval = dap->backend->write(dap, txlen, USB_TIMEOUT);
if (retval < 0)
return retval;
@@ -302,6 +321,20 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
if (retval < 0)
return retval;
+ uint8_t *resp = cmsis_dap_handle->response;
+ if (resp[0] == DAP_ERROR) {
+ LOG_ERROR("CMSIS-DAP command 0x%" PRIx8 " not implemented", current_cmd);
+ return ERROR_NOT_IMPLEMENTED;
+ }
+
+ if (resp[0] != current_cmd) {
+ LOG_ERROR("CMSIS-DAP command mismatch. Sent 0x%" PRIx8
+ " received 0x%" PRIx8, current_cmd, resp[0]);
+
+ cmsis_dap_flush_read(dap);
+ return ERROR_FAIL;
+ }
+
return ERROR_OK;
}
@@ -511,6 +544,45 @@ static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us)
}
#endif
+static int cmsis_dap_metacmd_targetsel(uint32_t instance_id)
+{
+ int retval;
+ uint8_t *command = cmsis_dap_handle->command;
+ const uint32_t SEQ_RD = 0x80, SEQ_WR = 0x00;
+
+ /* SWD multi-drop requires a transfer ala CMD_DAP_TFER,
+ but with no expectation of an SWD ACK response. In
+ CMSIS-DAP v1.20 and v2.00, CMD_DAP_SWD_SEQUENCE was
+ added to allow this special sequence to be generated.
+ The purpose of this operation is to select the target
+ corresponding to the instance_id that is written */
+
+ size_t idx = 0;
+ command[idx++] = CMD_DAP_SWD_SEQUENCE;
+ command[idx++] = 3; /* sequence count */
+
+ /* sequence 0: packet request for TARGETSEL */
+ command[idx++] = SEQ_WR | 8;
+ command[idx++] = SWD_CMD_START | swd_cmd(false, false, DP_TARGETSEL) | SWD_CMD_STOP | SWD_CMD_PARK;
+
+ /* sequence 1: read Trn ACK Trn, no expectation for target to ACK */
+ command[idx++] = SEQ_RD | 5;
+
+ /* sequence 2: WDATA plus parity */
+ command[idx++] = SEQ_WR | (32 + 1);
+ h_u32_to_le(command + idx, instance_id);
+ idx += 4;
+ command[idx++] = parity_u32(instance_id);
+
+ retval = cmsis_dap_xfer(cmsis_dap_handle, idx);
+
+ if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
+ LOG_ERROR("CMSIS-DAP command SWD_Sequence failed.");
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+ return ERROR_OK;
+}
+
static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
{
uint8_t *command = cmsis_dap_handle->command;
@@ -606,6 +678,13 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms)
}
uint8_t *resp = dap->response;
+ if (resp[0] != CMD_DAP_TFER) {
+ LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%" PRIx8
+ " received 0x%" PRIx8, CMD_DAP_TFER, resp[0]);
+ queued_retval = ERROR_FAIL;
+ goto skip;
+ }
+
uint8_t transfer_count = resp[1];
uint8_t ack = resp[2] & 0x07;
if (resp[2] & 0x08) {
@@ -617,6 +696,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms)
LOG_DEBUG("SWD ack not OK @ %d %s", transfer_count,
ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK");
queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL;
+ /* TODO: use results of transfers completed before the error occurred? */
goto skip;
}
@@ -676,7 +756,10 @@ static int cmsis_dap_swd_run_queue(void)
static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
{
- if (pending_fifo[pending_fifo_put_idx].transfer_count == pending_queue_len) {
+ bool targetsel_cmd = swd_cmd(false, false, DP_TARGETSEL) == cmd;
+
+ if (pending_fifo[pending_fifo_put_idx].transfer_count == pending_queue_len
+ || targetsel_cmd) {
if (pending_fifo_block_count)
cmsis_dap_swd_read_process(cmsis_dap_handle, 0);
@@ -690,6 +773,11 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
if (queued_retval != ERROR_OK)
return;
+ if (targetsel_cmd) {
+ cmsis_dap_metacmd_targetsel(data);
+ return;
+ }
+
struct pending_request_block *block = &pending_fifo[pending_fifo_put_idx];
struct pending_transfer_result *transfer = &(block->transfers[block->transfer_count]);
transfer->data = data;
@@ -807,7 +895,7 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
switch (seq) {
case LINE_RESET:
- LOG_DEBUG("SWD line reset");
+ LOG_DEBUG_IO("SWD line reset");
s = swd_seq_line_reset;
s_len = swd_seq_line_reset_len;
break;
@@ -816,11 +904,26 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
s = swd_seq_jtag_to_swd;
s_len = swd_seq_jtag_to_swd_len;
break;
+ case JTAG_TO_DORMANT:
+ LOG_DEBUG("JTAG-to-DORMANT");
+ s = swd_seq_jtag_to_dormant;
+ s_len = swd_seq_jtag_to_dormant_len;
+ break;
case SWD_TO_JTAG:
LOG_DEBUG("SWD-to-JTAG");
s = swd_seq_swd_to_jtag;
s_len = swd_seq_swd_to_jtag_len;
break;
+ case SWD_TO_DORMANT:
+ LOG_DEBUG("SWD-to-DORMANT");
+ s = swd_seq_swd_to_dormant;
+ s_len = swd_seq_swd_to_dormant_len;
+ break;
+ case DORMANT_TO_SWD:
+ LOG_DEBUG("DORMANT-to-SWD");
+ s = swd_seq_dormant_to_swd;
+ s_len = swd_seq_dormant_to_swd_len;
+ break;
default:
LOG_ERROR("Sequence %d not supported", seq);
return ERROR_FAIL;
@@ -863,6 +966,8 @@ static int cmsis_dap_init(void)
if (retval != ERROR_OK)
return retval;
+ cmsis_dap_flush_read(cmsis_dap_handle);
+
retval = cmsis_dap_get_caps_info();
if (retval != ERROR_OK)
return retval;
@@ -901,7 +1006,7 @@ static int cmsis_dap_init(void)
/* INFO_ID_PKT_SZ - short */
retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_SZ, &data);
if (retval != ERROR_OK)
- return retval;
+ goto init_err;
if (data[0] == 2) { /* short */
uint16_t pkt_sz = data[1] + (data[2] << 8);
@@ -915,7 +1020,7 @@ static int cmsis_dap_init(void)
free(cmsis_dap_handle->packet_buffer);
retval = cmsis_dap_handle->backend->packet_buffer_alloc(cmsis_dap_handle, pkt_sz);
if (retval != ERROR_OK)
- return retval;
+ goto init_err;
LOG_DEBUG("CMSIS-DAP: Packet Size = %" PRIu16, pkt_sz);
}
@@ -924,7 +1029,7 @@ static int cmsis_dap_init(void)
/* INFO_ID_PKT_CNT - byte */
retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_CNT, &data);
if (retval != ERROR_OK)
- return retval;
+ goto init_err;
if (data[0] == 1) { /* byte */
int pkt_cnt = data[1];
@@ -939,43 +1044,40 @@ static int cmsis_dap_init(void)
pending_fifo[i].transfers = malloc(pending_queue_len * sizeof(struct pending_transfer_result));
if (!pending_fifo[i].transfers) {
LOG_ERROR("Unable to allocate memory for CMSIS-DAP queue");
- return ERROR_FAIL;
+ retval = ERROR_FAIL;
+ goto init_err;
}
}
-
- retval = cmsis_dap_get_status();
- if (retval != ERROR_OK)
- return ERROR_FAIL;
+ /* Intentionally not checked for error, just logs an info message
+ * not vital for further debugging */
+ (void)cmsis_dap_get_status();
/* Now try to connect to the target
* TODO: This is all SWD only @ present */
retval = cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz());
if (retval != ERROR_OK)
- return ERROR_FAIL;
+ goto init_err;
/* Ask CMSIS-DAP to automatically retry on receiving WAIT for
* up to 64 times. This must be changed to 0 if sticky
* overrun detection is enabled. */
retval = cmsis_dap_cmd_DAP_TFER_Configure(0, 64, 0);
if (retval != ERROR_OK)
- return ERROR_FAIL;
+ goto init_err;
if (swd_mode) {
/* Data Phase (bit 2) must be set to 1 if sticky overrun
* detection is enabled */
retval = cmsis_dap_cmd_DAP_SWD_Configure(0); /* 1 TRN, no Data Phase */
if (retval != ERROR_OK)
- return ERROR_FAIL;
+ goto init_err;
}
/* Both LEDs on */
- retval = cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_ON);
- if (retval != ERROR_OK)
- return ERROR_FAIL;
-
- retval = cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_ON);
- if (retval != ERROR_OK)
- return ERROR_FAIL;
+ /* Intentionally not checked for error, debugging will work
+ * without LEDs */
+ (void)cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_ON);
+ (void)cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_ON);
/* support connecting with srst asserted */
enum reset_types jtag_reset_config = jtag_get_reset_config();
@@ -984,13 +1086,16 @@ static int cmsis_dap_init(void)
if (jtag_reset_config & RESET_SRST_NO_GATING) {
retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, SWJ_PIN_SRST, 0, NULL);
if (retval != ERROR_OK)
- return ERROR_FAIL;
+ goto init_err;
LOG_INFO("Connecting under reset");
}
}
LOG_INFO("CMSIS-DAP: Interface ready");
-
return ERROR_OK;
+
+init_err:
+ cmsis_dap_quit();
+ return retval;
}
static int cmsis_dap_swd_init(void)
diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c
index 28f8e3a..a588b1b 100644
--- a/src/jtag/drivers/cmsis_dap_usb_bulk.c
+++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c
@@ -35,6 +35,7 @@
#include "config.h"
#endif
+#include <helper/system.h>
#include <libusb.h>
#include <helper/log.h>
#include <helper/replacements.h>
@@ -42,8 +43,8 @@
#include "cmsis_dap.h"
struct cmsis_dap_backend_data {
- libusb_context *usb_ctx;
- libusb_device_handle *dev_handle;
+ struct libusb_context *usb_ctx;
+ struct libusb_device_handle *dev_handle;
unsigned int ep_out;
unsigned int ep_in;
int interface;
@@ -57,8 +58,8 @@ static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz);
static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], char *serial)
{
int err;
- libusb_context *ctx;
- libusb_device **device_list;
+ struct libusb_context *ctx;
+ struct libusb_device **device_list;
err = libusb_init(&ctx);
if (err) {
@@ -74,7 +75,7 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
}
for (int i = 0; i < num_devices; i++) {
- libusb_device *dev = device_list[i];
+ struct libusb_device *dev = device_list[i];
struct libusb_device_descriptor dev_desc;
err = libusb_get_device_descriptor(dev, &dev_desc);
@@ -102,7 +103,7 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
if (dev_desc.iSerialNumber == 0 && serial && serial[0])
continue;
- libusb_device_handle *dev_handle = NULL;
+ struct libusb_device_handle *dev_handle = NULL;
err = libusb_open(dev, &dev_handle);
if (err) {
/* It's to be expected that most USB devices can't be opened
diff --git a/src/jtag/drivers/cmsis_dap_usb_hid.c b/src/jtag/drivers/cmsis_dap_usb_hid.c
index e83ad1f..38069f8 100644
--- a/src/jtag/drivers/cmsis_dap_usb_hid.c
+++ b/src/jtag/drivers/cmsis_dap_usb_hid.c
@@ -35,6 +35,7 @@
#include "config.h"
#endif
+#include <string.h>
#include <hidapi.h>
#include <helper/log.h>
diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c
index 11d46f2..457fc2f 100644
--- a/src/jtag/drivers/ftdi.c
+++ b/src/jtag/drivers/ftdi.c
@@ -547,7 +547,7 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
uint8_t last_bit = 0;
if (field->out_value)
bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);
- uint8_t tms_bits = 0x01;
+ uint8_t tms_bits = 0x03;
DO_CLOCK_TMS_CS(mpsse_ctx,
&tms_bits,
0,
@@ -557,13 +557,24 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
last_bit,
ftdi_jtag_mode);
tap_set_state(tap_state_transition(tap_get_state(), 1));
- DO_CLOCK_TMS_CS_OUT(mpsse_ctx,
- &tms_bits,
- 1,
- 1,
- last_bit,
- ftdi_jtag_mode);
- tap_set_state(tap_state_transition(tap_get_state(), 0));
+ if (tap_get_end_state() == TAP_IDLE) {
+ DO_CLOCK_TMS_CS_OUT(mpsse_ctx,
+ &tms_bits,
+ 1,
+ 2,
+ last_bit,
+ ftdi_jtag_mode);
+ tap_set_state(tap_state_transition(tap_get_state(), 1));
+ tap_set_state(tap_state_transition(tap_get_state(), 0));
+ } else {
+ DO_CLOCK_TMS_CS_OUT(mpsse_ctx,
+ &tms_bits,
+ 2,
+ 1,
+ last_bit,
+ ftdi_jtag_mode);
+ tap_set_state(tap_state_transition(tap_get_state(), 0));
+ }
} else
DO_CLOCK_DATA(mpsse_ctx,
field->out_value,
diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c
index 184882a..f0122d5 100644
--- a/src/jtag/drivers/libusb_helper.c
+++ b/src/jtag/drivers/libusb_helper.c
@@ -31,7 +31,7 @@
#define MAX_USB_PORTS 7
static struct libusb_context *jtag_libusb_context; /**< Libusb context **/
-static libusb_device **devs; /**< The usb device list **/
+static struct libusb_device **devs; /**< The usb device list **/
static int jtag_libusb_error(int err)
{
@@ -71,7 +71,7 @@ static bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc,
}
#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
-static bool jtag_libusb_location_equal(libusb_device *device)
+static bool jtag_libusb_location_equal(struct libusb_device *device)
{
uint8_t port_path[MAX_USB_PORTS];
uint8_t dev_bus;
@@ -88,7 +88,7 @@ static bool jtag_libusb_location_equal(libusb_device *device)
return jtag_usb_location_equal(dev_bus, port_path, path_len);
}
#else /* HAVE_LIBUSB_GET_PORT_NUMBERS */
-static bool jtag_libusb_location_equal(libusb_device *device)
+static bool jtag_libusb_location_equal(struct libusb_device *device)
{
return true;
}
@@ -96,7 +96,7 @@ static bool jtag_libusb_location_equal(libusb_device *device)
/* Returns true if the string descriptor indexed by str_index in device matches string */
-static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_index,
+static bool string_descriptor_equal(struct libusb_device_handle *device, uint8_t str_index,
const char *string)
{
int retval;
@@ -123,7 +123,7 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in
return matched;
}
-static bool jtag_libusb_match_serial(libusb_device_handle *device,
+static bool jtag_libusb_match_serial(struct libusb_device_handle *device,
struct libusb_device_descriptor *dev_desc, const char *serial,
adapter_get_alternate_serial_fn adapter_get_alternate_serial)
{
diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h
index 74bb23c..fa7d06e 100644
--- a/src/jtag/drivers/libusb_helper.h
+++ b/src/jtag/drivers/libusb_helper.h
@@ -24,7 +24,7 @@
/* this callback should return a non NULL value only when the serial could not
* be retrieved by the standard 'libusb_get_string_descriptor_ascii' */
-typedef char * (*adapter_get_alternate_serial_fn)(libusb_device_handle *device,
+typedef char * (*adapter_get_alternate_serial_fn)(struct libusb_device_handle *device,
struct libusb_device_descriptor *dev_desc);
int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c
index 39c49e7..9ba1e25 100644
--- a/src/jtag/drivers/mpsse.c
+++ b/src/jtag/drivers/mpsse.c
@@ -63,8 +63,8 @@
#define SIO_RESET_PURGE_TX 2
struct mpsse_ctx {
- libusb_context *usb_ctx;
- libusb_device_handle *usb_dev;
+ struct libusb_context *usb_ctx;
+ struct libusb_device_handle *usb_dev;
unsigned int usb_write_timeout;
unsigned int usb_read_timeout;
uint8_t in_ep;
@@ -86,7 +86,7 @@ struct mpsse_ctx {
};
/* Returns true if the string descriptor indexed by str_index in device matches string */
-static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_index,
+static bool string_descriptor_equal(struct libusb_device_handle *device, uint8_t str_index,
const char *string)
{
int retval;
@@ -100,7 +100,7 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in
return strncmp(string, desc_string, sizeof(desc_string)) == 0;
}
-static bool device_location_equal(libusb_device *device, const char *location)
+static bool device_location_equal(struct libusb_device *device, const char *location)
{
bool result = false;
#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
@@ -162,7 +162,7 @@ static bool device_location_equal(libusb_device *device, const char *location)
static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, const uint16_t *pid,
const char *product, const char *serial, const char *location)
{
- libusb_device **list;
+ struct libusb_device **list;
struct libusb_device_descriptor desc;
struct libusb_config_descriptor *config0;
int err;
@@ -172,7 +172,7 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con
LOG_ERROR("libusb_get_device_list() failed with %s", libusb_error_name(cnt));
for (ssize_t i = 0; i < cnt; i++) {
- libusb_device *device = list[i];
+ struct libusb_device *device = list[i];
err = libusb_get_device_descriptor(device, &desc);
if (err != LIBUSB_SUCCESS) {
diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c
index ef27056..f7b8830 100644
--- a/src/jtag/drivers/remote_bitbang.c
+++ b/src/jtag/drivers/remote_bitbang.c
@@ -35,7 +35,6 @@
static char *remote_bitbang_host;
static char *remote_bitbang_port;
-static FILE *remote_bitbang_file;
static int remote_bitbang_fd;
/* Circular buffer. When start == end, the buffer is empty. */
@@ -65,7 +64,7 @@ static int remote_bitbang_fill_buf(void)
contiguous_available_space = remote_bitbang_start -
remote_bitbang_end - 1;
}
- ssize_t count = read(remote_bitbang_fd,
+ ssize_t count = read_socket(remote_bitbang_fd,
remote_bitbang_buf + remote_bitbang_end,
contiguous_available_space);
if (count > 0) {
@@ -75,11 +74,14 @@ static int remote_bitbang_fill_buf(void)
} else if (count == 0) {
return ERROR_OK;
} else if (count < 0) {
+#ifdef _WIN32
+ if (WSAGetLastError() == WSAEWOULDBLOCK) {
+#else
if (errno == EAGAIN) {
+#endif
return ERROR_OK;
} else {
- LOG_ERROR("remote_bitbang_fill_buf: %s (%d)",
- strerror(errno), errno);
+ log_socket_error("remote_bitbang_fill_buf");
return ERROR_FAIL;
}
}
@@ -90,8 +92,10 @@ static int remote_bitbang_fill_buf(void)
static int remote_bitbang_putc(int c)
{
- if (EOF == fputc(c, remote_bitbang_file)) {
- LOG_ERROR("remote_bitbang_putc: %s", strerror(errno));
+ char buf = c;
+ ssize_t count = write_socket(remote_bitbang_fd, &buf, sizeof(buf));
+ if (count < 0) {
+ log_socket_error("remote_bitbang_putc");
return ERROR_FAIL;
}
return ERROR_OK;
@@ -99,20 +103,11 @@ static int remote_bitbang_putc(int c)
static int remote_bitbang_quit(void)
{
- if (EOF == fputc('Q', remote_bitbang_file)) {
- LOG_ERROR("fputs: %s", strerror(errno));
- return ERROR_FAIL;
- }
-
- if (EOF == fflush(remote_bitbang_file)) {
- LOG_ERROR("fflush: %s", strerror(errno));
+ if (remote_bitbang_putc('Q') == ERROR_FAIL)
return ERROR_FAIL;
- }
- /* We only need to close one of the FILE*s, because they both use the same */
- /* underlying file descriptor. */
- if (EOF == fclose(remote_bitbang_file)) {
- LOG_ERROR("fclose: %s", strerror(errno));
+ if (close_socket(remote_bitbang_fd) != 0) {
+ log_socket_error("close_socket");
return ERROR_FAIL;
}
@@ -140,21 +135,16 @@ static bb_value_t char_to_int(int c)
/* Get the next read response. */
static bb_value_t remote_bitbang_rread(void)
{
- if (EOF == fflush(remote_bitbang_file)) {
- remote_bitbang_quit();
- LOG_ERROR("fflush: %s", strerror(errno));
- return BB_ERROR;
- }
-
/* Enable blocking access. */
socket_block(remote_bitbang_fd);
char c;
- ssize_t count = read(remote_bitbang_fd, &c, 1);
+ ssize_t count = read_socket(remote_bitbang_fd, &c, 1);
if (count == 1) {
return char_to_int(c);
} else {
remote_bitbang_quit();
- LOG_ERROR("read: count=%d, error=%s", (int) count, strerror(errno));
+ LOG_ERROR("read_socket: count=%d", (int) count);
+ log_socket_error("read_socket");
return BB_ERROR;
}
}
@@ -240,7 +230,7 @@ static int remote_bitbang_init_tcp(void)
freeaddrinfo(result); /* No longer needed */
if (rp == NULL) { /* No address succeeded */
- LOG_ERROR("Failed to connect: %s", strerror(errno));
+ log_socket_error("Failed to connect");
return ERROR_FAIL;
}
@@ -257,7 +247,7 @@ static int remote_bitbang_init_unix(void)
LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
- LOG_ERROR("socket: %s", strerror(errno));
+ log_socket_error("socket");
return ERROR_FAIL;
}
@@ -267,7 +257,7 @@ static int remote_bitbang_init_unix(void)
addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
- LOG_ERROR("connect: %s", strerror(errno));
+ log_socket_error("connect");
return ERROR_FAIL;
}
@@ -290,13 +280,6 @@ static int remote_bitbang_init(void)
if (remote_bitbang_fd < 0)
return remote_bitbang_fd;
- remote_bitbang_file = fdopen(remote_bitbang_fd, "w+");
- if (remote_bitbang_file == NULL) {
- LOG_ERROR("fdopen: failed to open write stream");
- close(remote_bitbang_fd);
- return ERROR_FAIL;
- }
-
LOG_INFO("remote_bitbang driver initialized");
return ERROR_OK;
}
diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c
index 41f36c1..a88731f 100644
--- a/src/jtag/drivers/rlink.c
+++ b/src/jtag/drivers/rlink.c
@@ -97,14 +97,14 @@
#define ST7_PC_TDO ST7_PC_IO9
#define ST7_PA_DBGACK ST7_PA_IO10
-static libusb_device_handle *pHDev;
+static struct libusb_device_handle *pHDev;
/*
* ep1 commands are up to USB_EP1OUT_SIZE bytes in length.
* This function takes care of zeroing the unused bytes before sending the packet.
* Any reply packet is not handled by this function.
*/
-static int ep1_generic_commandl(libusb_device_handle *pHDev_param, size_t length, ...)
+static int ep1_generic_commandl(struct libusb_device_handle *pHDev_param, size_t length, ...)
{
uint8_t usb_buffer[USB_EP1OUT_SIZE];
uint8_t *usb_buffer_p;
@@ -144,7 +144,7 @@ static int ep1_generic_commandl(libusb_device_handle *pHDev_param, size_t length
#if 0
static ssize_t ep1_memory_read(
- libusb_device_handle *pHDev_param, uint16_t addr,
+ struct libusb_device_handle *pHDev_param, uint16_t addr,
size_t length, uint8_t *buffer)
{
uint8_t usb_buffer[USB_EP1OUT_SIZE];
@@ -203,7 +203,7 @@ static ssize_t ep1_memory_read(
}
#endif
-static ssize_t ep1_memory_write(libusb_device_handle *pHDev_param, uint16_t addr,
+static ssize_t ep1_memory_write(struct libusb_device_handle *pHDev_param, uint16_t addr,
size_t length, uint8_t const *buffer)
{
uint8_t usb_buffer[USB_EP1OUT_SIZE];
@@ -259,7 +259,7 @@ static ssize_t ep1_memory_write(libusb_device_handle *pHDev_param, uint16_t addr
#if 0
-static ssize_t ep1_memory_writel(libusb_device_handle *pHDev_param, uint16_t addr,
+static ssize_t ep1_memory_writel(struct libusb_device_handle *pHDev_param, uint16_t addr,
size_t length, ...)
{
uint8_t buffer[USB_EP1OUT_SIZE - 4];
@@ -296,7 +296,7 @@ static ssize_t ep1_memory_writel(libusb_device_handle *pHDev_param, uint16_t add
static uint8_t dtc_entry_download;
/* The buffer is specially formatted to represent a valid image to load into the DTC. */
-static int dtc_load_from_buffer(libusb_device_handle *pHDev_param, const uint8_t *buffer,
+static int dtc_load_from_buffer(struct libusb_device_handle *pHDev_param, const uint8_t *buffer,
size_t length)
{
struct header_s {
@@ -470,7 +470,7 @@ static int dtc_start_download(void)
}
static int dtc_run_download(
- libusb_device_handle *pHDev_param,
+ struct libusb_device_handle *pHDev_param,
uint8_t *command_buffer,
int command_buffer_size,
uint8_t *reply_buffer,
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index a43ef8e..60a2c31 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -3017,7 +3017,7 @@ static int stlink_close(void *handle)
* based on the length (0x1a = 26) we could easily decide if we have to fixup the serial
* and then we have just to convert the raw data into printable characters using sprintf
*/
-static char *stlink_usb_get_alternate_serial(libusb_device_handle *device,
+static char *stlink_usb_get_alternate_serial(struct libusb_device_handle *device,
struct libusb_device_descriptor *dev_desc)
{
int usb_retval;
diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c
index 1b773fa..fe95e7d 100644
--- a/src/jtag/drivers/ulink.c
+++ b/src/jtag/drivers/ulink.c
@@ -267,7 +267,7 @@ static int ulink_usb_open(struct ulink **device)
{
ssize_t num_devices, i;
bool found;
- libusb_device **usb_devices;
+ struct libusb_device **usb_devices;
struct libusb_device_descriptor usb_desc;
struct libusb_device_handle *usb_device_handle;
diff --git a/src/jtag/drivers/versaloon/versaloon.c b/src/jtag/drivers/versaloon/versaloon.c
index b517795..6fea888 100644
--- a/src/jtag/drivers/versaloon/versaloon.c
+++ b/src/jtag/drivers/versaloon/versaloon.c
@@ -19,11 +19,12 @@
#include "config.h"
#endif
+#include "versaloon_include.h"
+
#include <stdio.h>
#include <string.h>
#include <libusb.h>
-#include "versaloon_include.h"
#include "versaloon.h"
#include "versaloon_internal.h"
#include "usbtoxxx/usbtoxxx.h"
@@ -35,7 +36,7 @@ uint16_t versaloon_buf_size;
struct versaloon_pending_t versaloon_pending[VERSALOON_MAX_PENDING_NUMBER];
uint16_t versaloon_pending_idx;
-libusb_device_handle *versaloon_usb_device_handle;
+struct libusb_device_handle *versaloon_usb_device_handle;
static uint32_t versaloon_usb_to = VERSALOON_TIMEOUT;
static RESULT versaloon_init(void);
diff --git a/src/jtag/drivers/versaloon/versaloon.h b/src/jtag/drivers/versaloon/versaloon.h
index 9d92bca..fcf2235 100644
--- a/src/jtag/drivers/versaloon/versaloon.h
+++ b/src/jtag/drivers/versaloon/versaloon.h
@@ -107,6 +107,6 @@ struct versaloon_interface_t {
};
extern struct versaloon_interface_t versaloon_interface;
-extern libusb_device_handle *versaloon_usb_device_handle;
+extern struct libusb_device_handle *versaloon_usb_device_handle;
#endif /* OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H */
diff --git a/src/jtag/drivers/versaloon/versaloon_include.h b/src/jtag/drivers/versaloon/versaloon_include.h
index 9014025..4ca81d5 100644
--- a/src/jtag/drivers/versaloon/versaloon_include.h
+++ b/src/jtag/drivers/versaloon/versaloon_include.h
@@ -18,6 +18,7 @@
#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INCLUDE_H
#define OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INCLUDE_H
+#include "helper/system.h"
/* This file is used to include different header and macros */
/* according to different platform */
#include <jtag/interface.h>
diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c
index 9aaed36..f08fa91 100644
--- a/src/jtag/drivers/vsllink.c
+++ b/src/jtag/drivers/vsllink.c
@@ -812,7 +812,7 @@ static int vsllink_check_usb_strings(
static int vsllink_usb_open(struct vsllink *vsllink)
{
ssize_t num_devices, i;
- libusb_device **usb_devices;
+ struct libusb_device **usb_devices;
struct libusb_device_descriptor usb_desc;
struct libusb_device_handle *usb_device_handle;
int retval;
@@ -823,7 +823,7 @@ static int vsllink_usb_open(struct vsllink *vsllink)
return ERROR_FAIL;
for (i = 0; i < num_devices; i++) {
- libusb_device *device = usb_devices[i];
+ struct libusb_device *device = usb_devices[i];
retval = libusb_get_device_descriptor(device, &usb_desc);
if (retval != 0)
diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c
index df1ab65..c492807 100644
--- a/src/jtag/drivers/xds110.c
+++ b/src/jtag/drivers/xds110.c
@@ -213,8 +213,8 @@ struct scan_result {
struct xds110_info {
/* USB connection handles and data buffers */
- libusb_context *ctx;
- libusb_device_handle *dev;
+ struct libusb_context *ctx;
+ struct libusb_device_handle *dev;
unsigned char read_payload[USB_PAYLOAD_SIZE];
unsigned char write_packet[3];
unsigned char write_payload[USB_PAYLOAD_SIZE];
@@ -317,9 +317,9 @@ static inline uint16_t xds110_get_u16(uint8_t *buffer)
static bool usb_connect(void)
{
- libusb_context *ctx = NULL;
- libusb_device **list = NULL;
- libusb_device_handle *dev = NULL;
+ struct libusb_context *ctx = NULL;
+ struct libusb_device **list = NULL;
+ struct libusb_device_handle *dev = NULL;
struct libusb_device_descriptor desc;
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 2fa162e..8a52c0f 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -108,8 +108,6 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args
endstate = TAP_IDLE;
- script_debug(interp, argc, args);
-
/* validate arguments as numbers */
e = JIM_OK;
for (i = 2; i < argc; i += 2) {
@@ -234,8 +232,6 @@ static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *ar
return JIM_ERR;
}
- script_debug(interp, argc, args);
-
int i;
for (i = 0; i < argc-1; i++) {
const char *cp;
@@ -266,8 +262,6 @@ static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *ar
static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args)
{
- script_debug(interp, argc, args);
-
Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count()));
return JIM_OK;
@@ -693,10 +687,8 @@ static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
struct command_context *context = current_command_context(interp);
int e = jtag_init_inner(context);
if (e != ERROR_OK) {
- Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e);
- Jim_IncrRefCount(eObj);
- Jim_SetResultFormatted(goi.interp, "error: %#s", eObj);
- Jim_DecrRefCount(goi.interp, eObj);
+ Jim_Obj *obj = Jim_NewIntObj(goi.interp, e);
+ Jim_SetResultFormatted(goi.interp, "error: %#s", obj);
return JIM_ERR;
}
return JIM_OK;
@@ -718,10 +710,8 @@ static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const
e = swd_init_reset(context);
if (e != ERROR_OK) {
- Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e);
- Jim_IncrRefCount(eObj);
- Jim_SetResultFormatted(goi.interp, "error: %#s", eObj);
- Jim_DecrRefCount(goi.interp, eObj);
+ Jim_Obj *obj = Jim_NewIntObj(goi.interp, e);
+ Jim_SetResultFormatted(goi.interp, "error: %#s", obj);
return JIM_ERR;
}
return JIM_OK;
@@ -767,7 +757,8 @@ static bool jtag_tap_disable(struct jtag_tap *t)
int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
+ struct command *c = jim_to_command(interp);
+ const char *cmd_name = c->name;
Jim_GetOptInfo goi;
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
if (goi.argc != 1) {
@@ -804,7 +795,8 @@ int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
+ struct command *c = jim_to_command(interp);
+ const char *cmd_name = c->name;
Jim_GetOptInfo goi;
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
goi.isconfigure = !strcmp(cmd_name, "configure");
diff --git a/src/openocd.c b/src/openocd.c
index fcefdbe..32b68b6 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -361,6 +361,7 @@ int openocd_main(int argc, char *argv[])
server_free();
unregister_all_commands(cmd_ctx, NULL);
+ help_del_all_commands(cmd_ctx);
/* free all DAP and CTI objects */
dap_cleanup_all();
diff --git a/src/pld/pld.c b/src/pld/pld.c
index 6f4da12..66f5d44 100644
--- a/src/pld/pld.c
+++ b/src/pld/pld.c
@@ -188,8 +188,7 @@ static int pld_init(struct command_context *cmd_ctx)
if (!pld_devices)
return ERROR_OK;
- struct command *parent = command_find_in_context(cmd_ctx, "pld");
- return register_commands(cmd_ctx, parent, pld_exec_command_handlers);
+ return register_commands(cmd_ctx, "pld", pld_exec_command_handlers);
}
COMMAND_HANDLER(handle_pld_init_command)
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
index 5334b0d..7cb6f41 100644
--- a/src/rtos/FreeRTOS.c
+++ b/src/rtos/FreeRTOS.c
@@ -81,7 +81,7 @@ static int cortex_m_stacking(struct rtos *rtos, const struct rtos_register_stack
int cm4_fpu_enabled = 0;
struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);
if (is_armv7m(armv7m_target)) {
- if (armv7m_target->fp_feature == FPv4_SP) {
+ if (armv7m_target->fp_feature == FPV4_SP) {
/* Found ARM v7m target which includes a FPU */
uint32_t cpacr;
diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c
index e637d05..048f4af 100644
--- a/src/rtos/nuttx.c
+++ b/src/rtos/nuttx.c
@@ -350,7 +350,7 @@ static int nuttx_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
bool cm4_fpu_enabled = false;
struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);
if (is_armv7m(armv7m_target)) {
- if (armv7m_target->fp_feature == FPv4_SP) {
+ if (armv7m_target->fp_feature == FPV4_SP) {
/* Found ARM v7m target which includes a FPU */
uint32_t cpacr;
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index e9de4f0..d5e0353 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -29,6 +29,7 @@
#include "telnet_server.h"
#include <target/target_request.h>
#include <helper/configuration.h>
+#include <helper/list.h>
static char *telnet_port;
@@ -58,6 +59,13 @@ static int telnet_write(struct connection *connection, const void *data,
return ERROR_SERVER_REMOTE_CLOSED;
}
+/* output an audible bell */
+static int telnet_bell(struct connection *connection)
+{
+ /* ("\a" does not work, at least on windows) */
+ return telnet_write(connection, "\x07", 1);
+}
+
static int telnet_prompt(struct connection *connection)
{
struct telnet_connection *t_con = connection->priv;
@@ -366,6 +374,217 @@ static void telnet_move_cursor(struct connection *connection, size_t pos)
tc->line_cursor = pos;
}
+/* check buffer size leaving one spare character for string null termination */
+static inline bool telnet_can_insert(struct connection *connection, size_t len)
+{
+ struct telnet_connection *t_con = connection->priv;
+
+ return t_con->line_size + len < TELNET_LINE_MAX_SIZE;
+}
+
+/* write to telnet console, and update the telnet_connection members
+ * this function is capable of inserting in the middle of a line
+ * please ensure that data does not contain special characters (\n, \r, \t, \b ...)
+ *
+ * returns false when it fails to insert the requested data
+ */
+static bool telnet_insert(struct connection *connection, const void *data, size_t len)
+{
+ struct telnet_connection *t_con = connection->priv;
+
+ if (!telnet_can_insert(connection, len)) {
+ telnet_bell(connection);
+ return false;
+ }
+
+ if (t_con->line_cursor < t_con->line_size) {
+ /* we have some content after the cursor */
+ memmove(t_con->line + t_con->line_cursor + len,
+ t_con->line + t_con->line_cursor,
+ t_con->line_size - t_con->line_cursor);
+ }
+
+ strncpy(t_con->line + t_con->line_cursor, data, len);
+
+ telnet_write(connection,
+ t_con->line + t_con->line_cursor,
+ t_con->line_size + len - t_con->line_cursor);
+
+ t_con->line_size += len;
+ t_con->line_cursor += len;
+
+ for (size_t i = t_con->line_cursor; i < t_con->line_size; i++)
+ telnet_write(connection, "\b", 1);
+
+ return true;
+}
+
+static void telnet_auto_complete(struct connection *connection)
+{
+ struct telnet_connection *t_con = connection->priv;
+ struct command_context *command_context = connection->cmd_ctx;
+
+ struct cmd_match {
+ char *cmd;
+ struct list_head lh;
+ };
+
+ LIST_HEAD(matches);
+
+ /* user command sequence, either at line beginning
+ * or we start over after these characters ';', '[', '{' */
+ size_t seq_start = (t_con->line_cursor == 0) ? 0 : (t_con->line_cursor - 1);
+ while (seq_start > 0) {
+ char c = t_con->line[seq_start];
+ if (c == ';' || c == '[' || c == '{') {
+ seq_start++;
+ break;
+ }
+
+ seq_start--;
+ }
+
+ /* user command position in the line, ignore leading spaces */
+ size_t usr_cmd_pos = seq_start;
+ while ((usr_cmd_pos < t_con->line_cursor) && isspace(t_con->line[usr_cmd_pos]))
+ usr_cmd_pos++;
+
+ /* user command length */
+ size_t usr_cmd_len = t_con->line_cursor - usr_cmd_pos;
+
+ /* optimize multiple spaces in the user command,
+ * because info commands does not tolerate multiple spaces */
+ size_t optimized_spaces = 0;
+ char query[usr_cmd_len + 1];
+ for (size_t i = 0; i < usr_cmd_len; i++) {
+ if ((i < usr_cmd_len - 1) && isspace(t_con->line[usr_cmd_pos + i])
+ && isspace(t_con->line[usr_cmd_pos + i + 1])) {
+ optimized_spaces++;
+ continue;
+ }
+
+ query[i - optimized_spaces] = t_con->line[usr_cmd_pos + i];
+ }
+
+ usr_cmd_len -= optimized_spaces;
+ query[usr_cmd_len] = '\0';
+
+ /* filter commands */
+ char *query_cmd = alloc_printf("lsort [info commands {%s*}]", query);
+
+ if (!query_cmd) {
+ LOG_ERROR("Out of memory");
+ return;
+ }
+
+ int retval = Jim_EvalSource(command_context->interp, __FILE__, __LINE__, query_cmd);
+ free(query_cmd);
+ if (retval != JIM_OK)
+ return;
+
+ Jim_Obj *list = Jim_GetResult(command_context->interp);
+ Jim_IncrRefCount(list);
+
+ /* common prefix length of the matched commands */
+ size_t common_len = 0;
+ char *first_match = NULL; /* used to compute the common prefix length */
+
+ int len = Jim_ListLength(command_context->interp, list);
+ for (int i = 0; i < len; i++) {
+ Jim_Obj *elem = Jim_ListGetIndex(command_context->interp, list, i);
+ Jim_IncrRefCount(elem);
+
+ char *name = (char *)Jim_GetString(elem, NULL);
+
+ /* validate the command */
+ bool ignore_cmd = false;
+ Jim_Cmd *jim_cmd = Jim_GetCommand(command_context->interp, elem, JIM_NONE);
+
+ if (!jim_cmd)
+ ignore_cmd = true;
+ else {
+ if (!jim_cmd->isproc) {
+ /* ignore commands without handler
+ * and those with COMMAND_CONFIG mode */
+ /* FIXME it's better to use jimcmd_is_ocd_command(jim_cmd)
+ * or command_find_from_name(command_context->interp, name) */
+ struct command *cmd = jim_cmd->u.native.privData;
+ if (!cmd)
+ ignore_cmd = true;
+ /* make Valgrind happy by checking that cmd is not NULL */
+ else if (cmd != NULL && !cmd->handler && !cmd->jim_handler)
+ ignore_cmd = true;
+ else if (cmd != NULL && cmd->mode == COMMAND_CONFIG)
+ ignore_cmd = true;
+ }
+ }
+
+ /* save the command in the prediction list */
+ if (!ignore_cmd) {
+ struct cmd_match *match = calloc(1, sizeof(struct cmd_match));
+ if (!match) {
+ LOG_ERROR("Out of memory");
+ Jim_DecrRefCount(command_context->interp, elem);
+ break; /* break the for loop */
+ }
+
+ if (list_empty(&matches)) {
+ common_len = strlen(name);
+ first_match = name;
+ } else {
+ size_t new_common_len = usr_cmd_len; /* save some loops */
+
+ while (new_common_len < common_len && first_match[new_common_len] == name[new_common_len])
+ new_common_len++;
+
+ common_len = new_common_len;
+ }
+
+ match->cmd = name;
+ list_add_tail(&match->lh, &matches);
+ }
+
+ Jim_DecrRefCount(command_context->interp, elem);
+ }
+ /* end of command filtering */
+
+ /* proceed with auto-completion */
+ if (list_empty(&matches))
+ telnet_bell(connection);
+ else if (common_len == usr_cmd_len && list_is_singular(&matches) && t_con->line_cursor == t_con->line_size)
+ telnet_insert(connection, " ", 1);
+ else if (common_len > usr_cmd_len) {
+ int completion_size = common_len - usr_cmd_len;
+ if (telnet_insert(connection, first_match + usr_cmd_len, completion_size)) {
+ /* in bash this extra space is only added when the cursor in at the end of line */
+ if (list_is_singular(&matches) && t_con->line_cursor == t_con->line_size)
+ telnet_insert(connection, " ", 1);
+ }
+ } else if (!list_is_singular(&matches)) {
+ telnet_write(connection, "\n\r", 2);
+
+ struct cmd_match *match;
+ list_for_each_entry(match, &matches, lh) {
+ telnet_write(connection, match->cmd, strlen(match->cmd));
+ telnet_write(connection, "\n\r", 2);
+ }
+
+ telnet_prompt(connection);
+ telnet_write(connection, t_con->line, t_con->line_size);
+
+ /* restore the terminal visible cursor location */
+ for (size_t i = t_con->line_cursor; i < t_con->line_size; i++)
+ telnet_write(connection, "\b", 1);
+ }
+
+ /* destroy the command_list */
+ struct cmd_match *tmp, *match;
+ list_for_each_entry_safe(match, tmp, &matches, lh)
+ free(match);
+
+ Jim_DecrRefCount(command_context->interp, list);
+}
+
static int telnet_input(struct connection *connection)
{
int bytes_read;
@@ -391,30 +610,7 @@ static int telnet_input(struct connection *connection)
t_con->state = TELNET_STATE_IAC;
else {
if (isprint(*buf_p)) { /* printable character */
- /* watch buffer size leaving one spare character for
- * string null termination */
- if (t_con->line_size == TELNET_LINE_MAX_SIZE-1) {
- /* output audible bell if buffer is full
- * "\a" does not work, at least on windows */
- telnet_write(connection, "\x07", 1);
- } else if (t_con->line_cursor == t_con->line_size) {
- telnet_write(connection, buf_p, 1);
- t_con->line[t_con->line_size++] = *buf_p;
- t_con->line_cursor++;
- } else {
- size_t i;
- memmove(t_con->line + t_con->line_cursor + 1,
- t_con->line + t_con->line_cursor,
- t_con->line_size - t_con->line_cursor);
- t_con->line[t_con->line_cursor] = *buf_p;
- t_con->line_size++;
- telnet_write(connection,
- t_con->line + t_con->line_cursor,
- t_con->line_size - t_con->line_cursor);
- t_con->line_cursor++;
- for (i = t_con->line_cursor; i < t_con->line_size; i++)
- telnet_write(connection, "\b", 1);
- }
+ telnet_insert(connection, buf_p, 1);
} else { /* non-printable */
if (*buf_p == 0x1b) { /* escape */
t_con->state = TELNET_STATE_ESCAPE;
@@ -548,7 +744,9 @@ static int telnet_input(struct connection *connection)
t_con->line[t_con->line_cursor] = '\0';
t_con->line_size = t_con->line_cursor;
}
- } else
+ } else if (*buf_p == '\t')
+ telnet_auto_complete(connection);
+ else
LOG_DEBUG("unhandled nonprintable: %2.2x", *buf_p);
}
}
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index d6b12cd..4ba92c8 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -133,6 +133,7 @@ static int aarch64_mmu_modify(struct target *target, int enable)
struct aarch64_common *aarch64 = target_to_aarch64(target);
struct armv8_common *armv8 = &aarch64->armv8_common;
int retval = ERROR_OK;
+ enum arm_mode target_mode = ARM_MODE_ANY;
uint32_t instr = 0;
if (enable) {
@@ -158,6 +159,8 @@ static int aarch64_mmu_modify(struct target *target, int enable)
switch (armv8->arm.core_mode) {
case ARMV8_64_EL0T:
+ target_mode = ARMV8_64_EL1H;
+ /* fall through */
case ARMV8_64_EL1T:
case ARMV8_64_EL1H:
instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL1, 0);
@@ -184,9 +187,15 @@ static int aarch64_mmu_modify(struct target *target, int enable)
LOG_DEBUG("unknown cpu state 0x%x", armv8->arm.core_mode);
break;
}
+ if (target_mode != ARM_MODE_ANY)
+ armv8_dpm_modeswitch(&armv8->dpm, target_mode);
retval = armv8->dpm.instr_write_data_r0(&armv8->dpm, instr,
aarch64->system_control_reg_curr);
+
+ if (target_mode != ARM_MODE_ANY)
+ armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
+
return retval;
}
@@ -2957,6 +2966,7 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command)
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
+ struct command *c = jim_to_command(interp);
struct command_context *context;
struct target *target;
struct arm *arm;
@@ -2964,7 +2974,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
bool is_mcr = false;
int arg_cnt = 0;
- if (Jim_CompareStringImmediate(interp, argv[0], "mcr")) {
+ if (!strcmp(c->name, "mcr")) {
is_mcr = true;
arg_cnt = 7;
} else {
diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c
index b25181e..f1fca40 100644
--- a/src/target/adi_v5_swd.c
+++ b/src/target/adi_v5_swd.c
@@ -74,7 +74,7 @@ static void swd_clear_sticky_errors(struct adiv5_dap *dap)
const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
assert(swd);
- swd->write_reg(swd_cmd(false, false, DP_ABORT),
+ swd->write_reg(swd_cmd(false, false, DP_ABORT),
STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
}
@@ -174,7 +174,7 @@ static int swd_connect(struct adiv5_dap *dap)
dap->do_reconnect = false;
- swd->write_reg(swd_cmd(false, false, DP_ABORT),
+ swd->write_reg(swd_cmd(false, false, DP_ABORT),
DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
status = swd_run_inner(dap);
}
@@ -325,7 +325,7 @@ static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned reg,
if (retval != ERROR_OK)
return retval;
- swd->read_reg(swd_cmd(true, true, reg), dap->last_read, ap->memaccess_tck);
+ swd->read_reg(swd_cmd(true, true, reg), dap->last_read, ap->memaccess_tck);
dap->last_read = data;
return check_sync(dap);
@@ -347,7 +347,7 @@ static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned reg,
if (retval != ERROR_OK)
return retval;
- swd->write_reg(swd_cmd(false, true, reg), data, ap->memaccess_tck);
+ swd->write_reg(swd_cmd(false, true, reg), data, ap->memaccess_tck);
return check_sync(dap);
}
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index 8edfaa8..00e4ea2 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -85,6 +85,15 @@
#define CSYSPWRUPREQ (1UL << 30)
#define CSYSPWRUPACK (1UL << 31)
+#define DP_SELECT_APSEL 0xFF000000
+#define DP_SELECT_APBANK 0x000000F0
+#define DP_SELECT_DPBANK 0x0000000F
+#define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */
+
+#define DP_APSEL_MAX (255)
+#define DP_APSEL_INVALID (-1)
+
+
/* MEM-AP register addresses */
#define MEM_AP_REG_CSW 0x00
#define MEM_AP_REG_TAR 0x04
@@ -150,18 +159,11 @@
#define IDR_JEP106_ARM 0x04760000
-#define DP_SELECT_APSEL 0xFF000000
-#define DP_SELECT_APBANK 0x000000F0
-#define DP_SELECT_DPBANK 0x0000000F
-#define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */
-
-#define DP_APSEL_MAX (255)
-#define DP_APSEL_INVALID (-1)
-
/* FIXME: not SWD specific; should be renamed, e.g. adiv5_special_seq */
enum swd_special_seq {
LINE_RESET,
JTAG_TO_SWD,
+ JTAG_TO_DORMANT,
SWD_TO_JTAG,
SWD_TO_DORMANT,
DORMANT_TO_SWD,
diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c
index 689e9df..ee9d8aa 100644
--- a/src/target/arm_cti.c
+++ b/src/target/arm_cti.c
@@ -507,17 +507,13 @@ static int cti_create(Jim_GetOptInfo *goi)
},
COMMAND_REGISTRATION_DONE
};
- e = register_commands(cmd_ctx, NULL, cti_commands);
+ e = register_commands_with_data(cmd_ctx, NULL, cti_commands, cti);
if (ERROR_OK != e)
return JIM_ERR;
- struct command *c = command_find_in_context(cmd_ctx, cp);
- assert(c);
- command_set_handler_data(c, cti);
-
list_add_tail(&cti->lh, &all_cti);
- return (ERROR_OK == e) ? JIM_OK : JIM_ERR;
+ return JIM_OK;
}
static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c
index 56442f1..a9277e7 100644
--- a/src/target/arm_dap.c
+++ b/src/target/arm_dap.c
@@ -265,17 +265,13 @@ static int dap_create(Jim_GetOptInfo *goi)
if (transport_is_hla())
dap_commands[0].chain = NULL;
- e = register_commands(cmd_ctx, NULL, dap_commands);
+ e = register_commands_with_data(cmd_ctx, NULL, dap_commands, dap);
if (ERROR_OK != e)
return JIM_ERR;
- struct command *c = command_find_in_context(cmd_ctx, cp);
- assert(c);
- command_set_handler_data(c, dap);
-
list_add_tail(&dap->lh, &all_dap);
- return (ERROR_OK == e) ? JIM_OK : JIM_ERR;
+ return JIM_OK;
}
static int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c
index 2da52e8..f935086 100644
--- a/src/target/arm_tpiu_swo.c
+++ b/src/target/arm_tpiu_swo.c
@@ -550,16 +550,17 @@ err_no_params:
static int jim_arm_tpiu_swo_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
+ struct command *c = jim_to_command(interp);
Jim_GetOptInfo goi;
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
- goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure");
+ goi.isconfigure = !strcmp(c->name, "configure");
if (goi.argc < 1) {
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
"missing: -option ...");
return JIM_ERR;
}
- struct arm_tpiu_swo_object *obj = Jim_CmdPrivData(interp);
+ struct arm_tpiu_swo_object *obj = c->jim_handler_data;
return arm_tpiu_swo_configure(&goi, obj);
}
@@ -583,7 +584,8 @@ static int wrap_read_u32(struct target *target, struct adiv5_ap *tpiu_ap,
static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- struct arm_tpiu_swo_object *obj = Jim_CmdPrivData(interp);
+ struct command *c = jim_to_command(interp);
+ struct arm_tpiu_swo_object *obj = c->jim_handler_data;
struct command_context *cmd_ctx = current_command_context(interp);
struct adiv5_ap *tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num);
uint32_t value;
@@ -786,7 +788,8 @@ error_exit:
static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- struct arm_tpiu_swo_object *obj = Jim_CmdPrivData(interp);
+ struct command *c = jim_to_command(interp);
+ struct arm_tpiu_swo_object *obj = c->jim_handler_data;
if (argc != 1) {
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
@@ -883,14 +886,10 @@ static int arm_tpiu_swo_create(Jim_Interp *interp, struct arm_tpiu_swo_object *o
},
COMMAND_REGISTRATION_DONE
};
- e = register_commands(cmd_ctx, NULL, obj_commands);
+ e = register_commands_with_data(cmd_ctx, NULL, obj_commands, obj);
if (ERROR_OK != e)
return JIM_ERR;
- struct command *c = command_find_in_context(cmd_ctx, obj->name);
- assert(c);
- command_set_handler_data(c, obj);
-
list_add_tail(&obj->lh, &all_tpiu_swo);
return JIM_OK;
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index db6f8bc..652dbe7 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -164,18 +164,22 @@ enum {
/* Floating-point status register */
ARMV7M_FPSCR,
+ /* for convenience add registers' block delimiters */
ARMV7M_LAST_REG,
+ ARMV7M_CORE_FIRST_REG = ARMV7M_R0,
+ ARMV7M_CORE_LAST_REG = ARMV7M_xPSR,
+ ARMV7M_FPU_FIRST_REG = ARMV7M_D0,
+ ARMV7M_FPU_LAST_REG = ARMV7M_FPSCR,
};
enum {
FP_NONE = 0,
- FPv4_SP,
- FPv5_SP,
- FPv5_DP,
+ FPV4_SP,
+ FPV5_SP,
+ FPV5_DP,
};
-#define ARMV7M_NUM_CORE_REGS (ARMV7M_xPSR + 1)
-#define ARMV7M_NUM_CORE_REGS_NOFP (ARMV7M_CONTROL + 1)
+#define ARMV7M_NUM_CORE_REGS (ARMV7M_CORE_LAST_REG - ARMV7M_CORE_FIRST_REG + 1)
#define ARMV7M_COMMON_MAGIC 0x2A452A45
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 6dc33c8..2b38b4a 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -1596,6 +1596,35 @@ int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpo
return ERROR_OK;
}
+int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
+{
+ if (target->debug_reason != DBG_REASON_WATCHPOINT)
+ return ERROR_FAIL;
+
+ struct cortex_m_common *cortex_m = target_to_cm(target);
+
+ for (struct watchpoint *wp = target->watchpoints; wp; wp = wp->next) {
+ if (!wp->set)
+ continue;
+
+ unsigned int dwt_num = wp->set - 1;
+ struct cortex_m_dwt_comparator *comparator = cortex_m->dwt_comparator_list + dwt_num;
+
+ uint32_t dwt_function;
+ int retval = target_read_u32(target, comparator->dwt_comparator_address + 8, &dwt_function);
+ if (retval != ERROR_OK)
+ return ERROR_FAIL;
+
+ /* check the MATCHED bit */
+ if (dwt_function & BIT(24)) {
+ *hit_watchpoint = wp;
+ return ERROR_OK;
+ }
+ }
+
+ return ERROR_FAIL;
+}
+
void cortex_m_enable_watchpoints(struct target *target)
{
struct watchpoint *watchpoint = target->watchpoints;
@@ -2019,7 +2048,7 @@ int cortex_m_examine(struct target *target)
/* test for floating point feature on Cortex-M4 */
if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i);
- armv7m->fp_feature = FPv4_SP;
+ armv7m->fp_feature = FPV4_SP;
}
} else if (i == 7 || i == 33 || i == 35 || i == 55) {
target_read_u32(target, MVFR0, &mvfr0);
@@ -2028,29 +2057,21 @@ int cortex_m_examine(struct target *target)
/* test for floating point features on Cortex-M7 */
if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
LOG_DEBUG("Cortex-M%d floating point feature FPv5_SP found", i);
- armv7m->fp_feature = FPv5_SP;
+ armv7m->fp_feature = FPV5_SP;
} else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
LOG_DEBUG("Cortex-M%d floating point feature FPv5_DP found", i);
- armv7m->fp_feature = FPv5_DP;
+ armv7m->fp_feature = FPV5_DP;
}
} else if (i == 0) {
/* Cortex-M0 does not support unaligned memory access */
armv7m->arm.is_armv6m = true;
}
- if (armv7m->fp_feature == FP_NONE &&
- armv7m->arm.core_cache->num_regs > ARMV7M_NUM_CORE_REGS_NOFP) {
- /* free unavailable FPU registers */
- size_t idx;
+ /* Check for FPU, otherwise mark FPU register as non-existent */
+ if (armv7m->fp_feature == FP_NONE)
+ for (size_t idx = ARMV7M_FPU_FIRST_REG; idx <= ARMV7M_FPU_LAST_REG; idx++)
+ armv7m->arm.core_cache->reg_list[idx].exist = false;
- for (idx = ARMV7M_NUM_CORE_REGS_NOFP;
- idx < armv7m->arm.core_cache->num_regs;
- idx++) {
- free(armv7m->arm.core_cache->reg_list[idx].feature);
- free(armv7m->arm.core_cache->reg_list[idx].reg_data_type);
- }
- armv7m->arm.core_cache->num_regs = ARMV7M_NUM_CORE_REGS_NOFP;
- }
if (!armv7m->stlink) {
if (i == 3 || i == 4)
@@ -2531,6 +2552,7 @@ struct target_type cortexm_target = {
.remove_breakpoint = cortex_m_remove_breakpoint,
.add_watchpoint = cortex_m_add_watchpoint,
.remove_watchpoint = cortex_m_remove_watchpoint,
+ .hit_watchpoint = cortex_m_hit_watchpoint,
.commands = cortex_m_command_handlers,
.target_create = cortex_m_target_create,
diff --git a/src/target/etm.c b/src/target/etm.c
index 19f3691..6dc2bd4 100644
--- a/src/target/etm.c
+++ b/src/target/etm.c
@@ -2107,6 +2107,5 @@ static const struct command_registration etm_exec_command_handlers[] = {
static int etm_register_user_commands(struct command_context *cmd_ctx)
{
- struct command *etm_cmd = command_find_in_context(cmd_ctx, "etm");
- return register_commands(cmd_ctx, etm_cmd, etm_exec_command_handlers);
+ return register_commands(cmd_ctx, "etm", etm_exec_command_handlers);
}
diff --git a/src/target/image.c b/src/target/image.c
index e63cd0f..8f72329 100644
--- a/src/target/image.c
+++ b/src/target/image.c
@@ -11,6 +11,9 @@
* Copyright (C) 2009 by Franck Hereson *
* franck.hereson@secad.fr *
* *
+ * Copyright (C) 2018 by Advantest *
+ * florian.meister@advantest.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 *
@@ -42,6 +45,10 @@
((elf->endianness == ELFDATA2LSB) ? \
le_to_h_u32((uint8_t *)&field) : be_to_h_u32((uint8_t *)&field))
+#define field64(elf, field) \
+ ((elf->endianness == ELFDATA2LSB) ? \
+ le_to_h_u64((uint8_t *)&field) : be_to_h_u64((uint8_t *)&field))
+
static int autodetect_image_type(struct image *image, const char *url)
{
int retval;
@@ -49,7 +56,7 @@ static int autodetect_image_type(struct image *image, const char *url)
size_t read_bytes;
uint8_t buffer[9];
- /* read the first 4 bytes of image */
+ /* read the first 9 bytes of image */
retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY);
if (retval != ERROR_OK)
return retval;
@@ -350,22 +357,29 @@ static int image_ihex_buffer_complete(struct image *image)
return retval;
}
-static int image_elf_read_headers(struct image *image)
+static int image_elf32_read_headers(struct image *image)
{
struct image_elf *elf = image->type_private;
size_t read_bytes;
uint32_t i, j;
int retval;
- uint32_t nload, load_to_vaddr = 0;
+ uint32_t nload;
+ bool load_to_vaddr = false;
+
+ retval = fileio_seek(elf->fileio, 0);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("cannot seek to ELF file header, read failed");
+ return retval;
+ }
- elf->header = malloc(sizeof(Elf32_Ehdr));
+ elf->header32 = malloc(sizeof(Elf32_Ehdr));
- if (elf->header == NULL) {
- LOG_ERROR("insufficient memory to perform operation ");
+ if (elf->header32 == NULL) {
+ LOG_ERROR("insufficient memory to perform operation");
return ERROR_FILEIO_OPERATION_FAILED;
}
- retval = fileio_read(elf->fileio, sizeof(Elf32_Ehdr), (uint8_t *)elf->header, &read_bytes);
+ retval = fileio_read(elf->fileio, sizeof(Elf32_Ehdr), (uint8_t *)elf->header32, &read_bytes);
if (retval != ERROR_OK) {
LOG_ERROR("cannot read ELF file header, read failed");
return ERROR_FILEIO_OPERATION_FAILED;
@@ -375,47 +389,156 @@ static int image_elf_read_headers(struct image *image)
return ERROR_FILEIO_OPERATION_FAILED;
}
- if (strncmp((char *)elf->header->e_ident, ELFMAG, SELFMAG) != 0) {
- LOG_ERROR("invalid ELF file, bad magic number");
+ elf->segment_count = field16(elf, elf->header32->e_phnum);
+ if (elf->segment_count == 0) {
+ LOG_ERROR("invalid ELF file, no program headers");
return ERROR_IMAGE_FORMAT_ERROR;
}
- if (elf->header->e_ident[EI_CLASS] != ELFCLASS32) {
- LOG_ERROR("invalid ELF file, only 32bits files are supported");
- return ERROR_IMAGE_FORMAT_ERROR;
+
+ retval = fileio_seek(elf->fileio, field32(elf, elf->header32->e_phoff));
+ if (retval != ERROR_OK) {
+ LOG_ERROR("cannot seek to ELF program header table, read failed");
+ return retval;
}
- elf->endianness = elf->header->e_ident[EI_DATA];
- if ((elf->endianness != ELFDATA2LSB)
- && (elf->endianness != ELFDATA2MSB)) {
- LOG_ERROR("invalid ELF file, unknown endianness setting");
+ elf->segments32 = malloc(elf->segment_count*sizeof(Elf32_Phdr));
+ if (elf->segments32 == NULL) {
+ LOG_ERROR("insufficient memory to perform operation");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
+ retval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf32_Phdr),
+ (uint8_t *)elf->segments32, &read_bytes);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("cannot read ELF segment headers, read failed");
+ return retval;
+ }
+ if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr)) {
+ LOG_ERROR("cannot read ELF segment headers, only partially read");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
+ /* count useful segments (loadable), ignore BSS section */
+ image->num_sections = 0;
+ for (i = 0; i < elf->segment_count; i++)
+ if ((field32(elf,
+ elf->segments32[i].p_type) == PT_LOAD) &&
+ (field32(elf, elf->segments32[i].p_filesz) != 0))
+ image->num_sections++;
+
+ if (image->num_sections == 0) {
+ LOG_ERROR("invalid ELF file, no loadable segments");
return ERROR_IMAGE_FORMAT_ERROR;
}
- elf->segment_count = field16(elf, elf->header->e_phnum);
+ /**
+ * some ELF linkers produce binaries with *all* the program header
+ * p_paddr fields zero (there can be however one loadable segment
+ * that has valid physical address 0x0).
+ * If we have such a binary with more than
+ * one PT_LOAD header, then use p_vaddr instead of p_paddr
+ * (ARM ELF standard demands p_paddr = 0 anyway, and BFD
+ * library uses this approach to workaround zero-initialized p_paddrs
+ * when obtaining lma - look at elf.c of BDF)
+ */
+ for (nload = 0, i = 0; i < elf->segment_count; i++)
+ if (elf->segments32[i].p_paddr != 0)
+ break;
+ else if ((field32(elf,
+ elf->segments32[i].p_type) == PT_LOAD) &&
+ (field32(elf, elf->segments32[i].p_memsz) != 0))
+ ++nload;
+
+ if (i >= elf->segment_count && nload > 1)
+ load_to_vaddr = true;
+
+ /* alloc and fill sections array with loadable segments */
+ image->sections = malloc(image->num_sections * sizeof(struct imagesection));
+ if (image->sections == NULL) {
+ LOG_ERROR("insufficient memory to perform operation");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
+ for (i = 0, j = 0; i < elf->segment_count; i++) {
+ if ((field32(elf,
+ elf->segments32[i].p_type) == PT_LOAD) &&
+ (field32(elf, elf->segments32[i].p_filesz) != 0)) {
+ image->sections[j].size = field32(elf, elf->segments32[i].p_filesz);
+ if (load_to_vaddr)
+ image->sections[j].base_address = field32(elf,
+ elf->segments32[i].p_vaddr);
+ else
+ image->sections[j].base_address = field32(elf,
+ elf->segments32[i].p_paddr);
+ image->sections[j].private = &elf->segments32[i];
+ image->sections[j].flags = field32(elf, elf->segments32[i].p_flags);
+ j++;
+ }
+ }
+
+ image->start_address_set = true;
+ image->start_address = field32(elf, elf->header32->e_entry);
+
+ return ERROR_OK;
+}
+
+static int image_elf64_read_headers(struct image *image)
+{
+ struct image_elf *elf = image->type_private;
+ size_t read_bytes;
+ uint32_t i, j;
+ int retval;
+ uint32_t nload;
+ bool load_to_vaddr = false;
+
+ retval = fileio_seek(elf->fileio, 0);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("cannot seek to ELF file header, read failed");
+ return retval;
+ }
+
+ elf->header64 = malloc(sizeof(Elf64_Ehdr));
+
+ if (elf->header64 == NULL) {
+ LOG_ERROR("insufficient memory to perform operation");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
+ retval = fileio_read(elf->fileio, sizeof(Elf64_Ehdr), (uint8_t *)elf->header64, &read_bytes);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("cannot read ELF file header, read failed");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+ if (read_bytes != sizeof(Elf64_Ehdr)) {
+ LOG_ERROR("cannot read ELF file header, only partially read");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
+ elf->segment_count = field16(elf, elf->header64->e_phnum);
if (elf->segment_count == 0) {
LOG_ERROR("invalid ELF file, no program headers");
return ERROR_IMAGE_FORMAT_ERROR;
}
- retval = fileio_seek(elf->fileio, field32(elf, elf->header->e_phoff));
+ retval = fileio_seek(elf->fileio, field64(elf, elf->header64->e_phoff));
if (retval != ERROR_OK) {
LOG_ERROR("cannot seek to ELF program header table, read failed");
return retval;
}
- elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr));
- if (elf->segments == NULL) {
- LOG_ERROR("insufficient memory to perform operation ");
+ elf->segments64 = malloc(elf->segment_count*sizeof(Elf64_Phdr));
+ if (elf->segments64 == NULL) {
+ LOG_ERROR("insufficient memory to perform operation");
return ERROR_FILEIO_OPERATION_FAILED;
}
- retval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf32_Phdr),
- (uint8_t *)elf->segments, &read_bytes);
+ retval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf64_Phdr),
+ (uint8_t *)elf->segments64, &read_bytes);
if (retval != ERROR_OK) {
LOG_ERROR("cannot read ELF segment headers, read failed");
return retval;
}
- if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr)) {
+ if (read_bytes != elf->segment_count*sizeof(Elf64_Phdr)) {
LOG_ERROR("cannot read ELF segment headers, only partially read");
return ERROR_FILEIO_OPERATION_FAILED;
}
@@ -424,11 +547,14 @@ static int image_elf_read_headers(struct image *image)
image->num_sections = 0;
for (i = 0; i < elf->segment_count; i++)
if ((field32(elf,
- elf->segments[i].p_type) == PT_LOAD) &&
- (field32(elf, elf->segments[i].p_filesz) != 0))
+ elf->segments64[i].p_type) == PT_LOAD) &&
+ (field64(elf, elf->segments64[i].p_filesz) != 0))
image->num_sections++;
- assert(image->num_sections > 0);
+ if (image->num_sections == 0) {
+ LOG_ERROR("invalid ELF file, no loadable segments");
+ return ERROR_IMAGE_FORMAT_ERROR;
+ }
/**
* some ELF linkers produce binaries with *all* the program header
@@ -441,44 +567,95 @@ static int image_elf_read_headers(struct image *image)
* when obtaining lma - look at elf.c of BDF)
*/
for (nload = 0, i = 0; i < elf->segment_count; i++)
- if (elf->segments[i].p_paddr != 0)
+ if (elf->segments64[i].p_paddr != 0)
break;
else if ((field32(elf,
- elf->segments[i].p_type) == PT_LOAD) &&
- (field32(elf, elf->segments[i].p_memsz) != 0))
+ elf->segments64[i].p_type) == PT_LOAD) &&
+ (field64(elf, elf->segments64[i].p_memsz) != 0))
++nload;
if (i >= elf->segment_count && nload > 1)
- load_to_vaddr = 1;
+ load_to_vaddr = true;
/* alloc and fill sections array with loadable segments */
image->sections = malloc(image->num_sections * sizeof(struct imagesection));
+ if (image->sections == NULL) {
+ LOG_ERROR("insufficient memory to perform operation");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
for (i = 0, j = 0; i < elf->segment_count; i++) {
if ((field32(elf,
- elf->segments[i].p_type) == PT_LOAD) &&
- (field32(elf, elf->segments[i].p_filesz) != 0)) {
- image->sections[j].size = field32(elf, elf->segments[i].p_filesz);
+ elf->segments64[i].p_type) == PT_LOAD) &&
+ (field64(elf, elf->segments64[i].p_filesz) != 0)) {
+ image->sections[j].size = field64(elf, elf->segments64[i].p_filesz);
if (load_to_vaddr)
- image->sections[j].base_address = field32(elf,
- elf->segments[i].p_vaddr);
+ image->sections[j].base_address = field64(elf,
+ elf->segments64[i].p_vaddr);
else
- image->sections[j].base_address = field32(elf,
- elf->segments[i].p_paddr);
- image->sections[j].private = &elf->segments[i];
- image->sections[j].flags = field32(elf, elf->segments[i].p_flags);
+ image->sections[j].base_address = field64(elf,
+ elf->segments64[i].p_paddr);
+ image->sections[j].private = &elf->segments64[i];
+ image->sections[j].flags = field32(elf, elf->segments64[i].p_flags);
j++;
}
}
image->start_address_set = true;
- image->start_address = field32(elf, elf->header->e_entry);
+ image->start_address = field64(elf, elf->header64->e_entry);
return ERROR_OK;
}
-static int image_elf_read_section(struct image *image,
+static int image_elf_read_headers(struct image *image)
+{
+ struct image_elf *elf = image->type_private;
+ size_t read_bytes;
+ unsigned char e_ident[EI_NIDENT];
+ int retval;
+
+ retval = fileio_read(elf->fileio, EI_NIDENT, e_ident, &read_bytes);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("cannot read ELF file header, read failed");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+ if (read_bytes != EI_NIDENT) {
+ LOG_ERROR("cannot read ELF file header, only partially read");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
+ if (strncmp((char *)e_ident, ELFMAG, SELFMAG) != 0) {
+ LOG_ERROR("invalid ELF file, bad magic number");
+ return ERROR_IMAGE_FORMAT_ERROR;
+ }
+
+ elf->endianness = e_ident[EI_DATA];
+ if ((elf->endianness != ELFDATA2LSB)
+ && (elf->endianness != ELFDATA2MSB)) {
+ LOG_ERROR("invalid ELF file, unknown endianness setting");
+ return ERROR_IMAGE_FORMAT_ERROR;
+ }
+
+ switch (e_ident[EI_CLASS]) {
+ case ELFCLASS32:
+ LOG_DEBUG("ELF32 image detected.");
+ elf->is_64_bit = false;
+ return image_elf32_read_headers(image);
+
+ case ELFCLASS64:
+ LOG_DEBUG("ELF64 image detected.");
+ elf->is_64_bit = true;
+ return image_elf64_read_headers(image);
+
+ default:
+ LOG_ERROR("invalid ELF file, only 32/64 bit ELF files are supported");
+ return ERROR_IMAGE_FORMAT_ERROR;
+ }
+}
+
+static int image_elf32_read_section(struct image *image,
int section,
- uint32_t offset,
+ target_addr_t offset,
uint32_t size,
uint8_t *buffer,
size_t *size_read)
@@ -490,13 +667,13 @@ static int image_elf_read_section(struct image *image,
*size_read = 0;
- LOG_DEBUG("load segment %d at 0x%" PRIx32 " (sz = 0x%" PRIx32 ")", section, offset, size);
+ LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size);
/* read initialized data in current segment if any */
if (offset < field32(elf, segment->p_filesz)) {
/* maximal size present in file for the current segment */
read_size = MIN(size, field32(elf, segment->p_filesz) - offset);
- LOG_DEBUG("read elf: size = 0x%zx at 0x%" PRIx32 "", read_size,
+ LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size,
field32(elf, segment->p_offset) + offset);
/* read initialized area of the segment */
retval = fileio_seek(elf->fileio, field32(elf, segment->p_offset) + offset);
@@ -519,6 +696,64 @@ static int image_elf_read_section(struct image *image,
return ERROR_OK;
}
+static int image_elf64_read_section(struct image *image,
+ int section,
+ target_addr_t offset,
+ uint32_t size,
+ uint8_t *buffer,
+ size_t *size_read)
+{
+ struct image_elf *elf = image->type_private;
+ Elf64_Phdr *segment = (Elf64_Phdr *)image->sections[section].private;
+ size_t read_size, really_read;
+ int retval;
+
+ *size_read = 0;
+
+ LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size);
+
+ /* read initialized data in current segment if any */
+ if (offset < field64(elf, segment->p_filesz)) {
+ /* maximal size present in file for the current segment */
+ read_size = MIN(size, field64(elf, segment->p_filesz) - offset);
+ LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size,
+ field64(elf, segment->p_offset) + offset);
+ /* read initialized area of the segment */
+ retval = fileio_seek(elf->fileio, field64(elf, segment->p_offset) + offset);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("cannot find ELF segment content, seek failed");
+ return retval;
+ }
+ retval = fileio_read(elf->fileio, read_size, buffer, &really_read);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("cannot read ELF segment content, read failed");
+ return retval;
+ }
+ size -= read_size;
+ *size_read += read_size;
+ /* need more data ? */
+ if (!size)
+ return ERROR_OK;
+ }
+
+ return ERROR_OK;
+}
+
+static int image_elf_read_section(struct image *image,
+ int section,
+ target_addr_t offset,
+ uint32_t size,
+ uint8_t *buffer,
+ size_t *size_read)
+{
+ struct image_elf *elf = image->type_private;
+
+ if (elf->is_64_bit)
+ return image_elf64_read_section(image, section, offset, size, buffer, size_read);
+ else
+ return image_elf32_read_section(image, section, offset, size, buffer, size_read);
+}
+
static int image_mot_buffer_complete_inner(struct image *image,
char *lpszLine,
struct imagesection *section)
@@ -840,7 +1075,7 @@ int image_open(struct image *image, const char *url, const char *type_string)
int image_read_section(struct image *image,
int section,
- uint32_t offset,
+ target_addr_t offset,
uint32_t size,
uint8_t *buffer,
size_t *size_read)
@@ -850,7 +1085,7 @@ int image_read_section(struct image *image,
/* don't read past the end of a section */
if (offset + size > image->sections[section].size) {
LOG_DEBUG(
- "read past end of section: 0x%8.8" PRIx32 " + 0x%8.8" PRIx32 " > 0x%8.8" PRIx32 "",
+ "read past end of section: 0x%8.8" TARGET_PRIxADDR " + 0x%8.8" PRIx32 " > 0x%8.8" PRIx32 "",
offset,
size,
image->sections[section].size);
@@ -878,9 +1113,9 @@ int image_read_section(struct image *image,
*size_read = size;
return ERROR_OK;
- } else if (image->type == IMAGE_ELF)
+ } else if (image->type == IMAGE_ELF) {
return image_elf_read_section(image, section, offset, size, buffer, size_read);
- else if (image->type == IMAGE_MEMORY) {
+ } else if (image->type == IMAGE_MEMORY) {
struct image_memory *image_memory = image->type_private;
uint32_t address = image->sections[section].base_address + offset;
@@ -933,7 +1168,7 @@ int image_read_section(struct image *image,
return ERROR_OK;
}
-int image_add_section(struct image *image, uint32_t base, uint32_t size, int flags, uint8_t const *data)
+int image_add_section(struct image *image, target_addr_t base, uint32_t size, int flags, uint8_t const *data)
{
struct imagesection *section;
@@ -988,11 +1223,19 @@ void image_close(struct image *image)
fileio_close(image_elf->fileio);
- free(image_elf->header);
- image_elf->header = NULL;
+ if (image_elf->is_64_bit) {
+ free(image_elf->header64);
+ image_elf->header64 = NULL;
- free(image_elf->segments);
- image_elf->segments = NULL;
+ free(image_elf->segments64);
+ image_elf->segments64 = NULL;
+ } else {
+ free(image_elf->header32);
+ image_elf->header32 = NULL;
+
+ free(image_elf->segments32);
+ image_elf->segments32 = NULL;
+ }
} else if (image->type == IMAGE_MEMORY) {
struct image_memory *image_memory = image->type_private;
diff --git a/src/target/image.h b/src/target/image.h
index 59b6508..5b5d11f 100644
--- a/src/target/image.h
+++ b/src/target/image.h
@@ -8,6 +8,9 @@
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
+ * Copyright (C) 2018 by Advantest *
+ * florian.meister@advantest.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 *
@@ -81,8 +84,15 @@ struct image_memory {
struct image_elf {
struct fileio *fileio;
- Elf32_Ehdr *header;
- Elf32_Phdr *segments;
+ bool is_64_bit;
+ union {
+ Elf32_Ehdr *header32;
+ Elf64_Ehdr *header64;
+ };
+ union {
+ Elf32_Phdr *segments32;
+ Elf64_Phdr *segments64;
+ };
uint32_t segment_count;
uint8_t endianness;
};
@@ -93,11 +103,11 @@ struct image_mot {
};
int image_open(struct image *image, const char *url, const char *type_string);
-int image_read_section(struct image *image, int section, uint32_t offset,
+int image_read_section(struct image *image, int section, target_addr_t offset,
uint32_t size, uint8_t *buffer, size_t *size_read);
void image_close(struct image *image);
-int image_add_section(struct image *image, uint32_t base, uint32_t size,
+int image_add_section(struct image *image, target_addr_t base, uint32_t size,
int flags, uint8_t const *data);
int image_calculate_checksum(const uint8_t *buffer, uint32_t nbytes,
diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c
index 1684ea8..246dbd0 100644
--- a/src/target/nds32_cmd.c
+++ b/src/target/nds32_cmd.c
@@ -722,7 +722,9 @@ static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *a
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(goi.interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
int result;
result = target_write_buffer(target, address, count * 4, (const uint8_t *)data);
@@ -751,7 +753,9 @@ static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const *
if (e != JIM_OK)
return e;
- struct target *target = Jim_CmdPrivData(goi.interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
struct aice_port_s *aice = target_to_aice(target);
int result;
uint32_t address;
@@ -812,7 +816,9 @@ static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *ar
if (goi.argc != 0)
return JIM_ERR;
- struct target *target = Jim_CmdPrivData(goi.interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
uint32_t *data = malloc(count * sizeof(uint32_t));
int result;
result = target_read_buffer(target, address, count * 4, (uint8_t *)data);
@@ -863,7 +869,9 @@ static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *
else
return ERROR_FAIL;
- struct target *target = Jim_CmdPrivData(goi.interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
struct aice_port_s *aice = target_to_aice(target);
char data_str[11];
@@ -911,7 +919,9 @@ static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const
else
return ERROR_FAIL;
- struct target *target = Jim_CmdPrivData(goi.interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
struct aice_port_s *aice = target_to_aice(target);
aice_write_debug_reg(aice, edm_sr_number, value);
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 0c1c049..80fe5e5 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -2745,6 +2745,7 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
}
next_read = address + i * size + j * 4;
}
+ keep_alive();
}
uint32_t sbcs_read = 0;
diff --git a/src/target/smp.c b/src/target/smp.c
index acd4628..6501dc0 100644
--- a/src/target/smp.c
+++ b/src/target/smp.c
@@ -131,26 +131,6 @@ COMMAND_HANDLER(default_handle_smp_command)
return ERROR_COMMAND_SYNTAX_ERROR;
}
-COMMAND_HANDLER(deprecated_handle_smp_on_command)
-{
- const char *argv[] = {"on", NULL};
-
- LOG_WARNING("\'smp_on\' is deprecated, please use \'smp on\' instead.");
- CMD_ARGC = 1;
- CMD_ARGV = argv;
- return CALL_COMMAND_HANDLER(default_handle_smp_command);
-}
-
-COMMAND_HANDLER(deprecated_handle_smp_off_command)
-{
- const char *argv[] = {"off", NULL};
-
- LOG_WARNING("\'smp_off\' is deprecated, please use \'smp off\' instead.");
- CMD_ARGC = 1;
- CMD_ARGV = argv;
- return CALL_COMMAND_HANDLER(default_handle_smp_command);
-}
-
COMMAND_HANDLER(handle_smp_gdb_command)
{
struct target *target = get_current_target(CMD_CTX);
@@ -181,20 +161,6 @@ const struct command_registration smp_command_handlers[] = {
.usage = "[on|off]",
},
{
- .name = "smp_on",
- .handler = deprecated_handle_smp_on_command,
- .mode = COMMAND_EXEC,
- .help = "Restart smp handling",
- .usage = "",
- },
- {
- .name = "smp_off",
- .handler = deprecated_handle_smp_off_command,
- .mode = COMMAND_EXEC,
- .help = "Stop smp handling",
- .usage = "",
- },
- {
.name = "smp_gdb",
.handler = handle_smp_gdb_command,
.mode = COMMAND_EXEC,
diff --git a/src/target/startup.tcl b/src/target/startup.tcl
index a8f78ab..f128d3b 100644
--- a/src/target/startup.tcl
+++ b/src/target/startup.tcl
@@ -206,3 +206,34 @@ proc init_target_events {} {
# Additionally board config scripts can define a procedure init_board that will be executed after init and init_targets
proc init_board {} {
}
+
+# smp_on/smp_off were already DEPRECATED in v0.11.0 through http://openocd.zylin.com/4615
+proc "aarch64 smp_on" {args} {
+ echo "DEPRECATED! use 'aarch64 smp on' not 'aarch64 smp_on'"
+ eval aarch64 smp on $args
+}
+
+proc "aarch64 smp_off" {args} {
+ echo "DEPRECATED! use 'aarch64 smp off' not 'aarch64 smp_off'"
+ eval aarch64 smp off $args
+}
+
+proc "cortex_a smp_on" {args} {
+ echo "DEPRECATED! use 'cortex_a smp on' not 'cortex_a smp_on'"
+ eval cortex_a smp on $args
+}
+
+proc "cortex_a smp_off" {args} {
+ echo "DEPRECATED! use 'cortex_a smp off' not 'cortex_a smp_off'"
+ eval cortex_a smp off $args
+}
+
+proc "mips_m4k smp_on" {args} {
+ echo "DEPRECATED! use 'mips_m4k smp on' not 'mips_m4k smp_on'"
+ eval mips_m4k smp on $args
+}
+
+proc "mips_m4k smp_off" {args} {
+ echo "DEPRECATED! use 'mips_m4k smp off' not 'mips_m4k smp_off'"
+ eval mips_m4k smp off $args
+}
diff --git a/src/target/target.c b/src/target/target.c
index 84c74e5..3d98bd2 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -5229,30 +5229,37 @@ no_params:
static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
+ struct command *c = jim_to_command(interp);
Jim_GetOptInfo goi;
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
- goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure");
+ goi.isconfigure = !strcmp(c->name, "configure");
if (goi.argc < 1) {
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
"missing: -option ...");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(goi.interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
return target_configure(&goi, target);
}
static int jim_target_mem2array(Jim_Interp *interp,
int argc, Jim_Obj *const *argv)
{
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
return target_mem2array(interp, target, argc - 1, argv + 1);
}
static int jim_target_array2mem(Jim_Interp *interp,
int argc, Jim_Obj *const *argv)
{
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
return target_array2mem(interp, target, argc - 1, argv + 1);
}
@@ -5284,7 +5291,9 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv
allow_defer = true;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
@@ -5302,7 +5311,9 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv
static int jim_target_was_examined(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
Jim_SetResultBool(interp, target_was_examined(target));
return JIM_OK;
@@ -5310,7 +5321,9 @@ static int jim_target_was_examined(Jim_Interp *interp, int argc, Jim_Obj * const
static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
Jim_SetResultBool(interp, target->defer_examine);
return JIM_OK;
@@ -5322,7 +5335,9 @@ static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *arg
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT) != ERROR_OK)
return JIM_ERR;
@@ -5336,7 +5351,9 @@ static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
@@ -5373,7 +5390,9 @@ static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
if (e != JIM_OK)
return e;
- struct target *target = Jim_CmdPrivData(goi.interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
@@ -5406,7 +5425,9 @@ static int jim_target_halt(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
int e = target->type->halt(target);
@@ -5436,7 +5457,9 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a
e = Jim_GetOpt_Wide(&goi, &a);
if (e != JIM_OK)
return e;
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
@@ -5480,7 +5503,9 @@ static int jim_target_current_state(Jim_Interp *interp, int argc, Jim_Obj *const
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
Jim_SetResultString(interp, target_state_name(target), -1);
return JIM_OK;
}
@@ -5499,7 +5524,9 @@ static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const
Jim_GetOpt_NvpUnknown(&goi, nvp_target_event, 1);
return e;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
target_handle_event(target, n->value);
return JIM_OK;
}
@@ -5877,7 +5904,7 @@ static int target_create(Jim_GetOptInfo *goi)
},
COMMAND_REGISTRATION_DONE
};
- e = register_commands(cmd_ctx, NULL, target_commands);
+ e = register_commands_override_target(cmd_ctx, NULL, target_commands, target);
if (e != ERROR_OK) {
if (target->type->deinit_target)
target->type->deinit_target(target);
@@ -5890,10 +5917,6 @@ static int target_create(Jim_GetOptInfo *goi)
return JIM_ERR;
}
- struct command *c = command_find_in_context(cmd_ctx, cp);
- assert(c);
- command_set_handler_data(c, target);
-
/* append to end of list */
append_to_list_all_targets(target);
diff --git a/tcl/board/icnova_imx53_sodimm.cfg b/tcl/board/icnova_imx53_sodimm.cfg
index dce9c47..af98188 100644
--- a/tcl/board/icnova_imx53_sodimm.cfg
+++ b/tcl/board/icnova_imx53_sodimm.cfg
@@ -79,7 +79,7 @@ proc init_l2cc { } {
; #orr r0, r0, #(1 << 22) /* disable write allocate */
; #mcr 15, 1, r0, c9, c0, 2
- arm mcr 15 1 9 0 2 [expr 0xC4 | (1<<24) | (1<<23) | (1<22)]
+ arm mcr 15 1 9 0 2 [expr 0xC4 | (1<<24) | (1<<23) | (1<<22)]
}
diff --git a/tcl/board/imx53-m53evk.cfg b/tcl/board/imx53-m53evk.cfg
index baeb3cd..b529c49 100644
--- a/tcl/board/imx53-m53evk.cfg
+++ b/tcl/board/imx53-m53evk.cfg
@@ -75,7 +75,7 @@ proc init_l2cc { } {
; #orr r0, r0, #(1 << 22) /* disable write allocate */
; #mcr 15, 1, r0, c9, c0, 2
- arm mcr 15 1 9 0 2 [expr 0xC4 | (1<<24) | (1<<23) | (1<22)]
+ arm mcr 15 1 9 0 2 [expr 0xC4 | (1<<24) | (1<<23) | (1<<22)]
}
diff --git a/tcl/board/imx53loco.cfg b/tcl/board/imx53loco.cfg
index 18caca5..91c2601 100644
--- a/tcl/board/imx53loco.cfg
+++ b/tcl/board/imx53loco.cfg
@@ -80,7 +80,7 @@ proc init_l2cc { } {
; #orr r0, r0, #(1 << 22) /* disable write allocate */
; #mcr 15, 1, r0, c9, c0, 2
- arm mcr 15 1 9 0 2 [expr 0xC4 | (1<<24) | (1<<23) | (1<22)]
+ arm mcr 15 1 9 0 2 [expr 0xC4 | (1<<24) | (1<<23) | (1<<22)]
}
diff --git a/tcl/board/pico-debug.cfg b/tcl/board/pico-debug.cfg
new file mode 100644
index 0000000..c2fe7d3
--- /dev/null
+++ b/tcl/board/pico-debug.cfg
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# pico-debug is a virtual CMSIS-DAP debug adapter
+# it runs on the very same RP2040 target being debugged without additional hardware
+# https://github.com/majbthrd/pico-debug
+
+source [find interface/cmsis-dap.cfg]
+adapter speed 4000
+
+set CHIPNAME rp2040
+source [find target/rp2040-core0.cfg]
+
diff --git a/tcl/chip/atmel/at91/sam9_smc.cfg b/tcl/chip/atmel/at91/sam9_smc.cfg
index db943cb..0628d4d 100644
--- a/tcl/chip/atmel/at91/sam9_smc.cfg
+++ b/tcl/chip/atmel/at91/sam9_smc.cfg
@@ -26,30 +26,30 @@
# tdf_cycles
proc sam9_smc_config { cs smc_config } {
;# Setup Register for CS n
- set AT91_SMC_SETUP [expr ($::AT91_SMC + 0x00 + ((cs)*0x10))]
- set val [expr ($smc_config(nwe_setup) << 0)]
- set val [expr ($val | $smc_config(ncs_write_setup) << 8]
- set val [expr ($val | $smc_config(nrd_setup)) << 16]
- set val [expr ($val | $smc_config(ncs_read_setup) << 24]
+ set AT91_SMC_SETUP [expr {$::AT91_SMC + 0x00 + $cs * 0x10}]
+ set val [expr {$smc_config(nwe_setup) << 0}]
+ set val [expr {$val | $smc_config(ncs_write_setup) << 8}]
+ set val [expr {$val | $smc_config(nrd_setup)) << 16}]
+ set val [expr {$val | $smc_config(ncs_read_setup) << 24}]
mww $AT91_SMC_SETUP $val
;# Pulse Register for CS n
- set AT91_SMC_PULSE [expr ($::AT91_SMC + 0x04 + ((cs)*0x10))]
- set val [expr ($smc_config(nwe_pulse) << 0)]
- set val [expr ($val | $smc_config(ncs_write_pulse) << 8]
- set val [expr ($val | $smc_config(nrd_pulse) << 16]
- set val [expr ($val | $smc_config(ncs_read_pulse) << 24]
+ set AT91_SMC_PULSE [expr {$::AT91_SMC + 0x04 + $cs * 0x10}]
+ set val [expr {$smc_config(nwe_pulse) << 0}]
+ set val [expr {$val | $smc_config(ncs_write_pulse) << 8}]
+ set val [expr {$val | $smc_config(nrd_pulse) << 16}]
+ set val [expr {$val | $smc_config(ncs_read_pulse) << 24}]
mww $AT91_SMC_PULSE $val
;# Cycle Register for CS n
- set AT91_SMC_CYCLE [expr ($::AT91_SMC + 0x08 + ((cs)*0x10))]
- set val [expr ($smc_config(write_cycle) << 0)]
- set val [expr ($val | $smc_config(read_cycle) << 16]
+ set AT91_SMC_CYCLE [expr {$::AT91_SMC + 0x08 + $cs * 0x10}]
+ set val [expr {$smc_config(write_cycle) << 0}]
+ set val [expr {$val | $smc_config(read_cycle) << 16}]
mww $AT91_SMC_CYCLE $val
;# Mode Register for CS n
- set AT91_SMC_MODE [expr ($::AT91_SMC + 0x0c + ((cs)*0x10))]
- set val [expr ($smc_config(mode) << 0)]
- set val [expr ($val | $smc_config(tdf_cycles) << 16]
+ set AT91_SMC_MODE [expr {$::AT91_SMC + 0x0c + $cs * 0x10}]
+ set val [expr {$smc_config(mode) << 0}]
+ set val [expr {$val | $smc_config(tdf_cycles) << 16}]
mww $AT91_SMC_MODE $val
}
diff --git a/tcl/target/imx8qm.cfg b/tcl/target/imx8qm.cfg
new file mode 100644
index 0000000..08cb813
--- /dev/null
+++ b/tcl/target/imx8qm.cfg
@@ -0,0 +1,89 @@
+#
+# NXP i.MX8QuadMax
+#
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME imx8qm
+}
+
+# CoreSight Debug Access Port (DAP)
+if { [info exists DAP_TAPID] } {
+ set _DAP_TAPID $DAP_TAPID
+} else {
+ # TAPID is from FreeScale!
+ set _DAP_TAPID 0x1890101d
+}
+
+jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \
+ -expected-id $_DAP_TAPID
+
+dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
+
+# AXI: Main SOC bus on AP #0
+target create ${_CHIPNAME}.axi mem_ap -dap ${_CHIPNAME}.dap -ap-num 0
+
+# 4x Cortex-A53 on AP #6
+set _A53_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}
+set _A53_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}
+
+cti create $_CHIPNAME.a53_cti.0 -dap $_CHIPNAME.dap \
+ -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 0]
+cti create $_CHIPNAME.a53_cti.1 -dap $_CHIPNAME.dap \
+ -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 1]
+cti create $_CHIPNAME.a53_cti.2 -dap $_CHIPNAME.dap \
+ -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 2]
+cti create $_CHIPNAME.a53_cti.3 -dap $_CHIPNAME.dap \
+ -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 3]
+target create $_CHIPNAME.a53.0 aarch64 -dap $_CHIPNAME.dap \
+ -cti $_CHIPNAME.a53_cti.0 -dbgbase [lindex $_A53_DBGBASE 0]
+target create $_CHIPNAME.a53.1 aarch64 -dap $_CHIPNAME.dap \
+ -cti $_CHIPNAME.a53_cti.1 -dbgbase [lindex $_A53_DBGBASE 1] -defer-examine
+target create $_CHIPNAME.a53.2 aarch64 -dap $_CHIPNAME.dap \
+ -cti $_CHIPNAME.a53_cti.2 -dbgbase [lindex $_A53_DBGBASE 2] -defer-examine
+target create $_CHIPNAME.a53.3 aarch64 -dap $_CHIPNAME.dap \
+ -cti $_CHIPNAME.a53_cti.3 -dbgbase [lindex $_A53_DBGBASE 3] -defer-examine
+
+# 2x Cortex-A72 on AP #6
+set _A72_DBGBASE {0x80210000 0x80310000}
+set _A72_CTIBASE {0x80220000 0x80220000}
+
+cti create $_CHIPNAME.a72_cti.0 -dap $_CHIPNAME.dap \
+ -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 0]
+cti create $_CHIPNAME.a72_cti.1 -dap $_CHIPNAME.dap \
+ -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 1]
+target create $_CHIPNAME.a72.0 aarch64 -dap $_CHIPNAME.dap \
+ -cti $_CHIPNAME.a72_cti.0 -dbgbase [lindex $_A72_DBGBASE 0] -defer-examine
+target create $_CHIPNAME.a72.1 aarch64 -dap $_CHIPNAME.dap \
+ -cti $_CHIPNAME.a72_cti.1 -dbgbase [lindex $_A72_DBGBASE 1] -defer-examine
+
+# All Cortex-A in SMP
+target smp \
+ $_CHIPNAME.a53.0 \
+ $_CHIPNAME.a53.1 \
+ $_CHIPNAME.a53.2 \
+ $_CHIPNAME.a53.3 \
+ $_CHIPNAME.a72.0 \
+ $_CHIPNAME.a72.1
+
+# SCU: Cortex-M4 core
+# always running imx SC firmware
+target create ${_CHIPNAME}.scu cortex_m -dap ${_CHIPNAME}.dap -ap-num 1
+
+# AHB from SCU perspective
+target create ${_CHIPNAME}.scu_ahb mem_ap -dap ${_CHIPNAME}.dap -ap-num 4
+
+# Cortex-M4 M4_0 core on AP #2 (default off)
+target create ${_CHIPNAME}.m4_0 cortex_m -dap ${_CHIPNAME}.dap -ap-num 2 \
+ -defer-examine
+
+# Cortex-M4 M4_1 core on AP #3 (default off)
+target create ${_CHIPNAME}.m4_1 cortex_m -dap ${_CHIPNAME}.dap -ap-num 3 \
+ -defer-examine
+
+# Debug APB bus
+target create ${_CHIPNAME}.apb mem_ap -dap ${_CHIPNAME}.dap -ap-num 6
+
+# Default target is boot core a53.0
+targets $_CHIPNAME.a53.0
diff --git a/tcl/target/rp2040-core0.cfg b/tcl/target/rp2040-core0.cfg
new file mode 100644
index 0000000..e427083
--- /dev/null
+++ b/tcl/target/rp2040-core0.cfg
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+transport select swd
+
+source [find target/swj-dp.tcl]
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME rp2040
+}
+
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x10000
+}
+
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID 0x01002927
+}
+
+swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID
+dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap
+$_TARGETNAME configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE
+
+set _FLASHNAME $_CHIPNAME.flash
+set _FLASHSIZE 0x200000
+set _FLASHBASE 0x10000000
+flash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME
+
+# srst does not exist; use SYSRESETREQ to perform a soft reset
+cortex_m reset_config sysresetreq
+