Merge branch 'master' into from_upstream
Conflicts: .github/workflows/snapshot.yml .gitignore src/rtos/FreeRTOS.c src/server/gdb_server.c src/target/riscv/riscv.c src/target/target.c src/target/target.h src/target/target_type.h Change-Id: I09fb737fe515349bef662872385b9a2a39c6c2f9
This commit is contained in:
commit
c8ebd050a2
|
@ -55,28 +55,23 @@ doc/openocd.toc
|
|||
doc/openocd.tp
|
||||
doc/openocd.vr
|
||||
doc/version.texi
|
||||
texinfo.tex
|
||||
src/openocd
|
||||
src/openocd.exe
|
||||
|
||||
# configure/autotools output
|
||||
m4
|
||||
/build-aux/
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.*
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
depcomp
|
||||
doxygen
|
||||
doxygen.log
|
||||
Doxyfile
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
Makefile
|
||||
!contrib/loaders/**/Makefile
|
||||
mdate-sh
|
||||
missing
|
||||
stamp-h1
|
||||
stamp-vti
|
||||
INSTALL
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
Valid-License-Identifier: MIT
|
||||
SPDX-URL: https://spdx.org/licenses/MIT.html
|
||||
Usage-Guide:
|
||||
To use the MIT License put the following SPDX tag/value pair into a
|
||||
comment according to the placement guidelines in the licensing rules
|
||||
documentation:
|
||||
SPDX-License-Identifier: MIT
|
||||
License-Text:
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
|
@ -2,6 +2,8 @@
|
|||
# have all needed files, that a GNU package needs
|
||||
AUTOMAKE_OPTIONS = gnu 1.6
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
# make sure we pass the correct jimtcl flags to distcheck
|
||||
DISTCHECK_CONFIGURE_FLAGS = --disable-install-jim
|
||||
|
||||
|
@ -57,6 +59,7 @@ EXTRA_DIST += \
|
|||
LICENSES/preferred/GFDL-1.2 \
|
||||
LICENSES/preferred/gfdl-1.2.texi.readme \
|
||||
LICENSES/preferred/GPL-2.0 \
|
||||
LICENSES/preferred/MIT \
|
||||
LICENSES/stand-alone/GPL-3.0 \
|
||||
tools/logger.pl \
|
||||
tools/rlink_make_speed_table \
|
||||
|
|
|
@ -1,17 +1,3 @@
|
|||
dnl
|
||||
dnl If needed, define the m4_ifblank and m4_ifnblank macros from autoconf 2.64
|
||||
dnl This allows us to run with earlier Autoconfs as well.
|
||||
ifdef([m4_ifblank],[],[
|
||||
m4_define([m4_ifblank],
|
||||
[m4_if(m4_translit([[$1]], [ ][ ][
|
||||
]), [], [$2], [$3])])])
|
||||
dnl
|
||||
ifdef([m4_ifnblank],[],[
|
||||
m4_define([m4_ifnblank],
|
||||
[m4_if(m4_translit([[$1]], [ ][ ][
|
||||
]), [], [$3], [$2])])])
|
||||
dnl
|
||||
|
||||
dnl AC_CONFIG_SUBDIRS does not allow configure options to be passed
|
||||
dnl to subdirs, this function allows that by creating a configure.gnu
|
||||
dnl script that prepends configure options and then calls the real
|
||||
|
|
24
configure.ac
24
configure.ac
|
@ -2,7 +2,7 @@ AC_PREREQ([2.69])
|
|||
AC_INIT([openocd], [0.11.0+dev],
|
||||
[OpenOCD Mailing List <openocd-devel@lists.sourceforge.net>])
|
||||
AC_CONFIG_SRCDIR([src/openocd.c])
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
m4_include([config_subdir.m4])dnl
|
||||
|
||||
|
@ -149,6 +149,9 @@ m4_define([LIBJAYLINK_ADAPTERS],
|
|||
m4_define([PCIE_ADAPTERS],
|
||||
[[[xlnx_pcie_xvc], [Xilinx XVC/PCIe], [XLNX_PCIE_XVC]]])
|
||||
|
||||
m4_define([SERIAL_PORT_ADAPTERS],
|
||||
[[[buspirate], [Bus Pirate], [BUS_PIRATE]]])
|
||||
|
||||
m4_define([OPTIONAL_LIBRARIES],
|
||||
[[[capstone], [Use Capstone disassembly framework], []]])
|
||||
|
||||
|
@ -250,6 +253,7 @@ AC_ARG_ADAPTERS([
|
|||
LIBFTDI_ADAPTERS,
|
||||
LIBFTDI_USB1_ADAPTERS
|
||||
LIBGPIOD_ADAPTERS,
|
||||
SERIAL_PORT_ADAPTERS,
|
||||
LIBJAYLINK_ADAPTERS
|
||||
],[auto])
|
||||
|
||||
|
@ -312,10 +316,6 @@ AC_ARG_ENABLE([gw16012],
|
|||
AS_HELP_STRING([--enable-gw16012], [Enable building support for the Gateworks GW16012 JTAG Programmer]),
|
||||
[build_gw16012=$enableval], [build_gw16012=no])
|
||||
|
||||
AC_ARG_ENABLE([buspirate],
|
||||
AS_HELP_STRING([--enable-buspirate], [Enable building support for the Buspirate]),
|
||||
[build_buspirate=$enableval], [build_buspirate=no])
|
||||
|
||||
AC_ARG_ENABLE([sysfsgpio],
|
||||
AS_HELP_STRING([--enable-sysfsgpio], [Enable building support for programming driven via sysfs gpios.]),
|
||||
[build_sysfsgpio=$enableval], [build_sysfsgpio=no])
|
||||
|
@ -400,10 +400,13 @@ AS_CASE([$host],
|
|||
])
|
||||
parport_use_giveio=yes
|
||||
|
||||
AS_IF([test "x$build_buspirate" = "xyes"], [
|
||||
AS_IF([test "x$enable_buspirate" = "xyes"], [
|
||||
AC_MSG_ERROR([buspirate currently not supported by MinGW32 hosts])
|
||||
])
|
||||
|
||||
# In case enable_buspirate=auto, make sure it will not be built.
|
||||
enable_buspirate=no
|
||||
|
||||
AC_SUBST([HOST_CPPFLAGS], [-D__USE_MINGW_ANSI_STDIO])
|
||||
],
|
||||
[*darwin*], [
|
||||
|
@ -530,7 +533,7 @@ AS_IF([test "x$build_gw16012" = "xyes"], [
|
|||
AC_DEFINE([BUILD_GW16012], [0], [0 if you don't want the Gateworks GW16012 driver.])
|
||||
])
|
||||
|
||||
AS_IF([test "x$build_buspirate" = "xyes"], [
|
||||
AS_IF([test "x$enable_buspirate" != "xno"], [
|
||||
AC_DEFINE([BUILD_BUSPIRATE], [1], [1 if you want the Buspirate JTAG driver.])
|
||||
], [
|
||||
AC_DEFINE([BUILD_BUSPIRATE], [0], [0 if you don't want the Buspirate JTAG driver.])
|
||||
|
@ -635,6 +638,7 @@ m4_define([PROCESS_ADAPTERS], [
|
|||
AC_MSG_ERROR([$3 is required for the ADAPTER_DESC([adapter])])
|
||||
])
|
||||
ADAPTER_VAR([adapter])=no
|
||||
AC_DEFINE([BUILD_]ADAPTER_SYM([adapter]), [0], [0 if you do not want the ]ADAPTER_DESC([adapter]).)
|
||||
])
|
||||
AM_CONDITIONAL(ADAPTER_SYM([adapter]), [test "x$ADAPTER_VAR([adapter])" != "xno"])
|
||||
])
|
||||
|
@ -694,7 +698,7 @@ AM_CONDITIONAL([USB_BLASTER_DRIVER], [test "x$enable_usb_blaster" != "xno" -o "x
|
|||
AM_CONDITIONAL([AMTJTAGACCEL], [test "x$build_amtjtagaccel" = "xyes"])
|
||||
AM_CONDITIONAL([GW16012], [test "x$build_gw16012" = "xyes"])
|
||||
AM_CONDITIONAL([REMOTE_BITBANG], [test "x$build_remote_bitbang" = "xyes"])
|
||||
AM_CONDITIONAL([BUSPIRATE], [test "x$build_buspirate" = "xyes"])
|
||||
AM_CONDITIONAL([BUSPIRATE], [test "x$enable_buspirate" != "xno"])
|
||||
AM_CONDITIONAL([SYSFSGPIO], [test "x$build_sysfsgpio" = "xyes"])
|
||||
AM_CONDITIONAL([XLNX_PCIE_XVC], [test "x$build_xlnx_pcie_xvc" = "xyes"])
|
||||
AM_CONDITIONAL([USE_LIBUSB1], [test "x$use_libusb1" = "xyes"])
|
||||
|
@ -754,6 +758,8 @@ AS_IF([test "x${gcc_wextra}" = "xyes"], [
|
|||
GCC_WARNINGS="${GCC_WARNINGS} -Wcast-align"
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Wredundant-decls"
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Wpointer-arith"
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Wundef"
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Wno-error=deprecated-declarations"
|
||||
])
|
||||
AS_IF([test "x${gcc_werror}" = "xyes"], [
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Werror"
|
||||
|
@ -779,7 +785,7 @@ m4_foreach([adapter], [USB1_ADAPTERS,
|
|||
HIDAPI_ADAPTERS, HIDAPI_USB1_ADAPTERS, LIBFTDI_ADAPTERS,
|
||||
LIBFTDI_USB1_ADAPTERS,
|
||||
LIBGPIOD_ADAPTERS,
|
||||
LIBJAYLINK_ADAPTERS, PCIE_ADAPTERS,
|
||||
LIBJAYLINK_ADAPTERS, PCIE_ADAPTERS, SERIAL_PORT_ADAPTERS,
|
||||
OPTIONAL_LIBRARIES],
|
||||
[s=m4_format(["%-40s"], ADAPTER_DESC([adapter]))
|
||||
AS_CASE([$ADAPTER_VAR([adapter])],
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* Copyright (C) 2021 by Andreas Fritiofson <andreas.fritiofson@gmail.com> */
|
||||
|
||||
/*
|
||||
* Simple example of using a circular doubly linked list through list.h
|
||||
*
|
||||
* gcc -I ../src/ list_example.c -o list_example
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <helper/list.h>
|
||||
|
||||
static LIST_HEAD(threads);
|
||||
|
||||
struct thread {
|
||||
int id;
|
||||
uint64_t tcb_address;
|
||||
struct list_head lh;
|
||||
};
|
||||
|
||||
void insert(struct thread *t)
|
||||
{
|
||||
list_add_tail(&t->lh, &threads);
|
||||
}
|
||||
|
||||
void remove(struct thread *t)
|
||||
{
|
||||
list_del(&t->lh);
|
||||
}
|
||||
|
||||
struct thread *lookup_id(int id)
|
||||
{
|
||||
struct thread *t;
|
||||
list_for_each_entry(t, &threads, lh) {
|
||||
if (t->id == id)
|
||||
return t;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct thread *lookup_tcb(uint64_t addr)
|
||||
{
|
||||
struct thread *t;
|
||||
list_for_each_entry(t, &threads, lh) {
|
||||
if (t->tcb_address == addr)
|
||||
return t;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct thread t1 = { .id = 1, .tcb_address = 111111111 };
|
||||
struct thread t2 = { .id = 2, .tcb_address = 222222222 };
|
||||
struct thread t3 = { .id = 3, .tcb_address = 333333333 };
|
||||
|
||||
insert(&t1);
|
||||
insert(&t2);
|
||||
assert(lookup_id(1) == &t1);
|
||||
assert(lookup_tcb(111111111) == &t1);
|
||||
assert(lookup_id(2) == &t2);
|
||||
assert(lookup_id(42) == NULL);
|
||||
remove(&t1);
|
||||
assert(lookup_id(1) == NULL);
|
||||
insert(&t3);
|
||||
remove(&t2);
|
||||
assert(lookup_id(3) == &t3);
|
||||
assert(lookup_tcb(333333333) == &t3);
|
||||
assert(lookup_id(2) == NULL);
|
||||
remove(&t3);
|
||||
assert(list_empty(&threads));
|
||||
}
|
|
@ -48,9 +48,55 @@ OpenOCD project.
|
|||
- use Unix line endings ('\\n'); do NOT use DOS endings ('\\r\\n')
|
||||
- limit adjacent empty lines to at most two (2).
|
||||
- remove any trailing empty lines at the end of source files
|
||||
- do not "comment out" code from the tree; instead, one should either:
|
||||
-# remove it entirely (git can retrieve the old version), or
|
||||
-# use an @c \#if/\#endif block.
|
||||
- do not "comment out" code from the tree nor put it within a block
|
||||
@code
|
||||
#if 0
|
||||
...
|
||||
#endif
|
||||
@endcode
|
||||
otherwise it would never be checked at compile time and when new
|
||||
patches get merged it could be not compilable anymore.
|
||||
Code that is not fully working nor ready for submission should
|
||||
instead be removed entirely (git can retrieve the old version).
|
||||
For exceptional cases that require keeping some unused code, let
|
||||
the compiler check it by putting it in a block
|
||||
@code
|
||||
if (false) {
|
||||
/* explain why this code should be kept here */
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
- in a @c switch statement align the @c switch with the @c case label
|
||||
@code
|
||||
switch (dev_id) {
|
||||
case 0x0123:
|
||||
size = 0x10000;
|
||||
break;
|
||||
case 0x0412:
|
||||
size = 0x20000;
|
||||
break;
|
||||
default:
|
||||
size = 0x40000;
|
||||
break;
|
||||
}
|
||||
@endcode
|
||||
- in an <tt> if / then / else </tt> statement, if only one of the conditions
|
||||
require curly brackets due to multi-statement block, put the curly brackets
|
||||
also to the other condition
|
||||
@code
|
||||
if (x > 0)
|
||||
a = 12 + x;
|
||||
else
|
||||
a = 24;
|
||||
@endcode
|
||||
@code
|
||||
if (x > 0) {
|
||||
a = 12 + x;
|
||||
} else {
|
||||
a = 24;
|
||||
x = 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Finally, try to avoid lines of code that are longer than 72-80 columns:
|
||||
|
||||
|
@ -60,6 +106,7 @@ Finally, try to avoid lines of code that are longer than 72-80 columns:
|
|||
- a few lines may be wider than this limit (typically format strings), but:
|
||||
- all C compilers will concatenate series of string constants.
|
||||
- all long string constants should be split across multiple lines.
|
||||
- do never exceed 120 columns.
|
||||
|
||||
@section stylenames Naming Rules
|
||||
|
||||
|
@ -104,11 +151,15 @@ or variable length arrays on the stack. non-MMU hosts(uClinux) and
|
|||
pthreads require modest and predictable stack usage.
|
||||
|
||||
@section styletypes Type Guidelines
|
||||
- use native types (@c int or @c unsigned) if the type is not important
|
||||
- use native types (@c int or <tt> unsigned int </tt>) if the type is not important
|
||||
- if size matters, use the types from \<stdint.h\> or \<inttypes.h\>:
|
||||
- @c int8_t, @c int16_t, @c int32_t, or @c int64_t: signed types of specified size
|
||||
- @c uint8_t, @c uint16_t, @c uint32_t, or @c uint64_t: unsigned types of specified size
|
||||
- use the associated @c printf and @c scanf formatting strings for these types
|
||||
(e.g. @c PRId8, PRIx16, SCNu8, ...)
|
||||
- do @b NOT redefine @c uN types from "types.h"
|
||||
- use type @c target_addr_t for target's address values
|
||||
- prefer type <tt> unsigned int </tt> to type @c unsigned
|
||||
|
||||
@section stylefunc Functions
|
||||
|
||||
|
@ -143,6 +194,20 @@ More directly, do @b not combine these kinds of statements:
|
|||
// Combined statements should be avoided
|
||||
if ((result = foo()) != ERROR_OK)
|
||||
return result;
|
||||
@endcode
|
||||
- Do not compare @c bool values with @c true or @c false but use the
|
||||
value directly
|
||||
@code
|
||||
if (!is_enabled)
|
||||
...
|
||||
@endcode
|
||||
- Avoid comparing pointers with @c NULL
|
||||
@code
|
||||
buf = malloc(buf_size);
|
||||
if (!buf) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
@endcode
|
||||
|
||||
*/
|
||||
|
@ -341,7 +406,7 @@ For technical reference material:
|
|||
vice versa.
|
||||
- Alphabetize the \@defn declarations for all commands in each
|
||||
section.
|
||||
- Keep the per-command documentation focussed on exactly what that
|
||||
- Keep the per-command documentation focused on exactly what that
|
||||
command does, not motivation, advice, suggestions, or big examples.
|
||||
When commands deserve such expanded text, it belongs elsewhere.
|
||||
Solutions might be using a \@section explaining a cluster of related
|
||||
|
|
123
doc/openocd.texi
123
doc/openocd.texi
|
@ -315,7 +315,7 @@ There are several things you should keep in mind when choosing a dongle.
|
|||
|
||||
@enumerate
|
||||
@item @b{Transport} Does it support the kind of communication that you need?
|
||||
OpenOCD focusses mostly on JTAG. Your version may also support
|
||||
OpenOCD focuses mostly on JTAG. Your version may also support
|
||||
other ways to communicate with target devices.
|
||||
@item @b{Voltage} What voltage is your target - 1.8, 2.8, 3.3, or 5V?
|
||||
Does your dongle support it? You might need a level converter.
|
||||
|
@ -3264,6 +3264,68 @@ Specifies the TCP/IP address of the SystemVerilog DPI server interface.
|
|||
@end deffn
|
||||
|
||||
|
||||
@deffn {Interface Driver} {buspirate}
|
||||
|
||||
This driver is for the Bus Pirate (see @url{http://dangerousprototypes.com/docs/Bus_Pirate}) and compatible devices.
|
||||
It uses a simple data protocol over a serial port connection.
|
||||
|
||||
Most hardware development boards have a UART, a real serial port, or a virtual USB serial device, so this driver
|
||||
allows you to start building your own JTAG adapter without the complexity of a custom USB connection.
|
||||
|
||||
@deffn {Config Command} {buspirate_port} serial_port
|
||||
Specify the serial port's filename. For example:
|
||||
@example
|
||||
buspirate_port /dev/ttyUSB0
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Config Command} {buspirate_speed} (normal|fast)
|
||||
Set the communication speed to 115k (normal) or 1M (fast). For example:
|
||||
@example
|
||||
buspirate_mode normal
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Config Command} {buspirate_mode} (normal|open-drain)
|
||||
Set the Bus Pirate output mode.
|
||||
@itemize @minus
|
||||
@item In normal mode (push/pull), do not enable the pull-ups, and do not connect I/O header pin VPU to JTAG VREF.
|
||||
@item In open drain mode, you will then need to enable the pull-ups.
|
||||
@end itemize
|
||||
For example:
|
||||
@example
|
||||
buspirate_mode normal
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Config Command} {buspirate_pullup} (0|1)
|
||||
Whether to connect (1) or not (0) the I/O header pin VPU (JTAG VREF)
|
||||
to the pull-up/pull-down resistors on MOSI (JTAG TDI), CLK (JTAG TCK), MISO (JTAG TDO) and CS (JTAG TMS).
|
||||
For example:
|
||||
@example
|
||||
buspirate_pullup 0
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Config Command} {buspirate_vreg} (0|1)
|
||||
Whether to enable (1) or disable (0) the built-in voltage regulator,
|
||||
which can be used to supply power to a test circuit through
|
||||
I/O header pins +3V3 and +5V. For example:
|
||||
@example
|
||||
buspirate_vreg 0
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Command} {buspirate_led} (0|1)
|
||||
Turns the Bus Pirate's LED on (1) or off (0). For example:
|
||||
@end deffn
|
||||
@example
|
||||
buspirate_led 1
|
||||
@end example
|
||||
|
||||
@end deffn
|
||||
|
||||
|
||||
@section Transport Configuration
|
||||
@cindex Transport
|
||||
As noted earlier, depending on the version of OpenOCD you use,
|
||||
|
@ -4681,7 +4743,7 @@ The value should normally correspond to a static mapping for the
|
|||
@var{rtos_type} can be one of @option{auto}, @option{eCos},
|
||||
@option{ThreadX}, @option{FreeRTOS}, @option{linux}, @option{ChibiOS},
|
||||
@option{embKernel}, @option{mqx}, @option{uCOS-III}, @option{nuttx},
|
||||
@option{RIOT}
|
||||
@option{RIOT}, @option{Zephyr}
|
||||
@xref{gdbrtossupport,,RTOS Support}.
|
||||
|
||||
@item @code{-defer-examine} -- skip target examination at initial JTAG chain
|
||||
|
@ -5577,7 +5639,7 @@ flash driver infers all parameters from current controller register values when
|
|||
'flash probe @var{bank_id}' is executed.
|
||||
|
||||
Normal OpenOCD commands like @command{mdw} can be used to display the flash content,
|
||||
but only after proper controller initialization as decribed above. However,
|
||||
but only after proper controller initialization as described above. However,
|
||||
due to a silicon bug in some devices, attempting to access the very last word
|
||||
should be avoided.
|
||||
|
||||
|
@ -10680,6 +10742,49 @@ If @emph{xsvfdump} shows a file is using those opcodes, it
|
|||
probably will not be usable with other XSVF tools.
|
||||
|
||||
|
||||
@section IPDBG: JTAG-Host server
|
||||
@cindex IPDBG JTAG-Host server
|
||||
@cindex IPDBG
|
||||
|
||||
IPDBG is a set of tools to debug IP-Cores. It comprises, among others, a logic analyzer and an arbitrary
|
||||
waveform generator. These are synthesize-able hardware descriptions of
|
||||
logic circuits in addition to software for control, visualization and further analysis.
|
||||
In a session using JTAG for its transport protocol, OpenOCD supports the function
|
||||
of a JTAG-Host. The JTAG-Host is needed to connect the circuit over JTAG to the
|
||||
control-software. For more details see @url{http://ipdbg.org}.
|
||||
|
||||
@deffn {Command} {ipdbg} [@option{-start|-stop}] @option{-tap @var{tapname}} @option{-hub @var{ir_value} [@var{dr_length}]} [@option{-port @var{number}}] [@option{-tool @var{number}}] [@option{-vir [@var{vir_value} [@var{length} [@var{instr_code}]]]}]
|
||||
Starts or stops a IPDBG JTAG-Host server. Arguments can be specified in any order.
|
||||
|
||||
Command options:
|
||||
@itemize @bullet
|
||||
@item @option{-start|-stop} starts or stops a IPDBG JTAG-Host server (default: start).
|
||||
@item @option{-tap @var{tapname}} targeting the TAP @var{tapname}.
|
||||
@item @option{-hub @var{ir_value}} states that the JTAG hub is
|
||||
reachable with dr-scans while the JTAG instruction register has the value @var{ir_value}.
|
||||
@item @option{-port @var{number}} tcp port number where the JTAG-Host is listening.
|
||||
@item @option{-tool @var{number}} number of the tool/feature. These corresponds to the ports "data_(up/down)_(0..6)" at the JtagHub.
|
||||
@item @option{-vir [@var{vir_value} [@var{length} [@var{instr_code}]]]} On some devices, the user data-register is only reachable if there is a
|
||||
specific value in a second dr. This second dr is called vir (virtual ir). With this parameter given, the IPDBG satisfies this condition prior an
|
||||
access to the IPDBG-Hub. The value shifted into the vir is given by the first parameter @var{vir_value} (default: 0x11). The second
|
||||
parameter @var{length} is the length of the vir data register (default: 5). With the @var{instr_code} (default: 0x00e) parameter the ir value to
|
||||
shift data through vir can be configured.
|
||||
@end itemize
|
||||
@end deffn
|
||||
|
||||
Examples:
|
||||
@example
|
||||
ipdbg -start -tap xc6s.tap -hub 0x02 -port 4242 -tool 4
|
||||
@end example
|
||||
Starts a server listening on tcp-port 4242 which connects to tool 4.
|
||||
The connection is through the TAP of a Xilinx Spartan 6 on USER1 instruction (tested with a papillion pro board).
|
||||
|
||||
@example
|
||||
ipdbg -start -tap 10m50.tap -hub 0x00C -vir -port 60000 -tool 1
|
||||
@end example
|
||||
Starts a server listening on tcp-port 60000 which connects to tool 1 (data_up_1/data_down_1).
|
||||
The connection is through the TAP of a Intel MAX10 virtual jtag component (sld_instance_index is 0; sld_ir_width is smaller than 5).
|
||||
|
||||
@node Utility Commands
|
||||
@chapter Utility Commands
|
||||
@cindex Utility Commands
|
||||
|
@ -11002,6 +11107,7 @@ Currently supported rtos's include:
|
|||
@item @option{nuttx}
|
||||
@item @option{RIOT}
|
||||
@item @option{hwthread} (This is not an actual RTOS. @xref{usingopenocdsmpwithgdb,,Using OpenOCD SMP with GDB}.)
|
||||
@item @option{Zephyr}
|
||||
@end itemize
|
||||
|
||||
Before an RTOS can be detected, it must export certain symbols; otherwise, it cannot
|
||||
|
@ -11036,12 +11142,17 @@ g_readytorun, g_tasklisttable.
|
|||
sched_threads, sched_num_threads, sched_active_pid, max_threads,
|
||||
_tcb_name_offset.
|
||||
@end raggedright
|
||||
@item Zephyr symbols
|
||||
_kernel, _kernel_openocd_offsets, _kernel_openocd_size_t_size
|
||||
@end table
|
||||
|
||||
For most RTOS supported the above symbols will be exported by default. However for
|
||||
some, eg. FreeRTOS and uC/OS-III, extra steps must be taken.
|
||||
some, eg. FreeRTOS, uC/OS-III and Zephyr, extra steps must be taken.
|
||||
|
||||
These RTOSes may require additional OpenOCD-specific file to be linked
|
||||
Zephyr must be compiled with the DEBUG_THREAD_INFO option. This will generate some symbols
|
||||
with information needed in order to build the list of threads.
|
||||
|
||||
FreeRTOS and uC/OS-III RTOSes may require additional OpenOCD-specific file to be linked
|
||||
along with the project:
|
||||
|
||||
@table @code
|
||||
|
@ -11438,7 +11549,7 @@ your C code, do the same - artificially push some zeros onto the stack,
|
|||
remember to pop them off when the ISR is done.
|
||||
|
||||
@b{Also note:} If you have a multi-threaded operating system, they
|
||||
often do not @b{in the intrest of saving memory} waste these few
|
||||
often do not @b{in the interest of saving memory} waste these few
|
||||
bytes. Painful...
|
||||
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ struct nand_info {
|
|||
const char *name;
|
||||
};
|
||||
|
||||
/* Option constants for bizarre disfunctionality and real features
|
||||
/* Option constants for bizarre dysfunctionality and real features
|
||||
*/
|
||||
enum {
|
||||
/* Chip can not auto increment pages */
|
||||
|
|
|
@ -139,9 +139,9 @@ static int lpc3180_init(struct nand_device *nand)
|
|||
{
|
||||
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
|
||||
struct target *target = nand->target;
|
||||
int bus_width = nand->bus_width ? : 8;
|
||||
int address_cycles = nand->address_cycles ? : 3;
|
||||
int page_size = nand->page_size ? : 512;
|
||||
int bus_width = nand->bus_width ? nand->bus_width : 8;
|
||||
int address_cycles = nand->address_cycles ? nand->address_cycles : 3;
|
||||
int page_size = nand->page_size ? nand->page_size : 512;
|
||||
|
||||
if (target->state != TARGET_HALTED) {
|
||||
LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
|
||||
|
|
|
@ -191,9 +191,9 @@ static int lpc32xx_init(struct nand_device *nand)
|
|||
{
|
||||
struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;
|
||||
struct target *target = nand->target;
|
||||
int bus_width = nand->bus_width ? : 8;
|
||||
int address_cycles = nand->address_cycles ? : 3;
|
||||
int page_size = nand->page_size ? : 512;
|
||||
int bus_width = nand->bus_width ? nand->bus_width : 8;
|
||||
int address_cycles = nand->address_cycles ? nand->address_cycles : 3;
|
||||
int page_size = nand->page_size ? nand->page_size : 512;
|
||||
int retval;
|
||||
|
||||
if (target->state != TARGET_HALTED) {
|
||||
|
|
|
@ -183,7 +183,7 @@ static int nuc910_nand_init(struct nand_device *nand)
|
|||
{
|
||||
struct nuc910_nand_controller *nuc910_nand = nand->controller_priv;
|
||||
struct target *target = nand->target;
|
||||
int bus_width = nand->bus_width ? : 8;
|
||||
int bus_width = nand->bus_width ? nand->bus_width : 8;
|
||||
int result;
|
||||
|
||||
result = validate_target_state(nand);
|
||||
|
|
|
@ -2803,7 +2803,7 @@ static int kinetis_blank_check(struct flash_bank *bank)
|
|||
struct kinetis_chip *k_chip = k_bank->k_chip;
|
||||
int result;
|
||||
|
||||
/* suprisingly blank check does not work in VLPR and HSRUN modes */
|
||||
/* surprisingly blank check does not work in VLPR and HSRUN modes */
|
||||
result = kinetis_check_run_mode(k_chip);
|
||||
if (result != ERROR_OK)
|
||||
return result;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#define QSPI_W_EN (0x1)
|
||||
#define QSPI_SS_DISABLE (0x0)
|
||||
#define QSPI_SS_ENABLE (0x1)
|
||||
#define WRITE_DISBALE (0x0)
|
||||
#define WRITE_DISABLE (0x0)
|
||||
#define WRITE_ENABLE (0x1)
|
||||
|
||||
#define QSPI_TIMEOUT (1000)
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#define P4_SECTOR_LENGTH 0x1000
|
||||
#define P4_ALGO_ENTRY_ADDR 0x01000110
|
||||
|
||||
/* MSP432E4 flash paramters */
|
||||
/* MSP432E4 flash parameters */
|
||||
#define E4_FLASH_BASE FLASH_BASE
|
||||
#define E4_FLASH_SIZE 0x100000
|
||||
#define E4_SECTOR_LENGTH 0x4000
|
||||
|
|
|
@ -1037,7 +1037,7 @@ static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer,
|
|||
* RM reads: Code running from code region 1 will not be able to write
|
||||
* to code region 0.
|
||||
* Unfortunately the flash loader running from RAM can write to both
|
||||
* code regions whithout any hint the protection is violated.
|
||||
* code regions without any hint the protection is violated.
|
||||
*
|
||||
* Update protection state and check if any flash sector to be written
|
||||
* is protected. */
|
||||
|
|
|
@ -335,7 +335,7 @@ static int psoc4_sysreq(struct flash_bank *bank, uint8_t cmd,
|
|||
|
||||
/* Execute wait code */
|
||||
retval = target_run_algorithm(target, 0, NULL,
|
||||
sizeof(reg_params) / sizeof(*reg_params), reg_params,
|
||||
ARRAY_SIZE(reg_params), reg_params,
|
||||
sysreq_wait_algorithm->address, 0, 1000, &armv7m_info);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("sysreq wait code execution failed");
|
||||
|
|
|
@ -1351,8 +1351,10 @@ static int stm32l4_probe(struct flash_bank *bank)
|
|||
device_id = stm32l4_info->idcode & 0xFFF;
|
||||
|
||||
for (unsigned int n = 0; n < ARRAY_SIZE(stm32l4_parts); n++) {
|
||||
if (device_id == stm32l4_parts[n].id)
|
||||
if (device_id == stm32l4_parts[n].id) {
|
||||
stm32l4_info->part_info = &stm32l4_parts[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stm32l4_info->part_info) {
|
||||
|
|
|
@ -533,8 +533,8 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
|
|||
buf_set_u32(reg_params[2].value, 0, 32, this_count / 4);
|
||||
|
||||
/* 5: Execute the bunch of code */
|
||||
retval = target_run_algorithm(target, 0, NULL, sizeof(reg_params)
|
||||
/ sizeof(*reg_params), reg_params,
|
||||
retval = target_run_algorithm(target, 0, NULL,
|
||||
ARRAY_SIZE(reg_params), reg_params,
|
||||
write_algorithm->address, 0, 10000, &armv7m_info);
|
||||
if (retval != ERROR_OK)
|
||||
break;
|
||||
|
|
|
@ -175,7 +175,7 @@ struct stmqspi_flash_bank {
|
|||
bool octo;
|
||||
struct flash_device dev;
|
||||
uint32_t io_base;
|
||||
uint32_t saved_cr; /* in particalar FSEL, DFM bit mask in QUADSPI_CR *AND* OCTOSPI_CR */
|
||||
uint32_t saved_cr; /* in particular FSEL, DFM bit mask in QUADSPI_CR *AND* OCTOSPI_CR */
|
||||
uint32_t saved_ccr; /* different meaning for QUADSPI and OCTOSPI */
|
||||
uint32_t saved_tcr; /* only for OCTOSPI */
|
||||
uint32_t saved_ir; /* only for OCTOSPI */
|
||||
|
|
|
@ -169,7 +169,7 @@ static int isc_enter(struct flash_bank *bank)
|
|||
jtag_execute_queue();
|
||||
|
||||
status = read_status(bank);
|
||||
if (false == status.isc_mode) {
|
||||
if (!status.isc_mode) {
|
||||
LOG_ERROR("*** XCF: FAILED to enter ISC mode");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ static int isc_leave(struct flash_bank *bank)
|
|||
|
||||
struct xcf_status status = read_status(bank);
|
||||
|
||||
if (false == status.isc_mode)
|
||||
if (!status.isc_mode)
|
||||
return ERROR_OK;
|
||||
else {
|
||||
struct scan_field scan;
|
||||
|
@ -199,7 +199,7 @@ static int isc_leave(struct flash_bank *bank)
|
|||
alive_sleep(1); /* device needs 50 uS to leave ISC mode */
|
||||
|
||||
status = read_status(bank);
|
||||
if (true == status.isc_mode) {
|
||||
if (status.isc_mode) {
|
||||
LOG_ERROR("*** XCF: FAILED to leave ISC mode");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ static int isc_set_register(struct flash_bank *bank, const uint8_t *cmd,
|
|||
scan.in_value = NULL;
|
||||
jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);
|
||||
|
||||
if (0 == timeout_ms)
|
||||
if (timeout_ms == 0)
|
||||
return jtag_execute_queue();
|
||||
else
|
||||
return isc_wait_erase_program(bank, timeout_ms);
|
||||
|
@ -311,7 +311,7 @@ static int isc_program_register(struct flash_bank *bank, const uint8_t *cmd,
|
|||
scan.in_value = NULL;
|
||||
jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
|
||||
|
||||
if (0 == timeout_ms)
|
||||
if (timeout_ms == 0)
|
||||
return jtag_execute_queue();
|
||||
else
|
||||
return isc_wait_erase_program(bank, timeout_ms);
|
||||
|
@ -409,7 +409,7 @@ static bool need_bit_reverse(const uint8_t *buffer)
|
|||
reference[18] = 0xAA;
|
||||
reference[19] = 0x66;
|
||||
|
||||
if (0 == memcmp(reference, buffer, L))
|
||||
if (memcmp(reference, buffer, L) == 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
@ -444,7 +444,7 @@ static int read_write_data(struct flash_bank *bank, const uint8_t *w_buffer,
|
|||
goto EXIT;
|
||||
}
|
||||
|
||||
if ((write_flag) && (0 == offset) && (count >= XCF_PAGE_SIZE))
|
||||
if ((write_flag) && (offset == 0) && (count >= XCF_PAGE_SIZE))
|
||||
revbit = need_bit_reverse(w_buffer);
|
||||
|
||||
while (count > 0) {
|
||||
|
@ -585,7 +585,7 @@ static int xcf_info(struct flash_bank *bank, char *buf, int buf_size)
|
|||
{
|
||||
const struct xcf_priv *priv = bank->driver_priv;
|
||||
|
||||
if (false == priv->probed) {
|
||||
if (!priv->probed) {
|
||||
snprintf(buf, buf_size, "\nXCF flash bank not probed yet\n");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -598,7 +598,7 @@ static int xcf_probe(struct flash_bank *bank)
|
|||
struct xcf_priv *priv = bank->driver_priv;
|
||||
uint32_t id;
|
||||
|
||||
if (true == priv->probed)
|
||||
if (priv->probed)
|
||||
free(bank->sectors);
|
||||
priv->probed = false;
|
||||
|
||||
|
@ -629,7 +629,7 @@ static int xcf_probe(struct flash_bank *bank)
|
|||
}
|
||||
|
||||
bank->sectors = malloc(bank->num_sectors * sizeof(struct flash_sector));
|
||||
if (NULL == bank->sectors) {
|
||||
if (bank->sectors == NULL) {
|
||||
LOG_ERROR("No memory for sector table");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -652,7 +652,7 @@ static int xcf_auto_probe(struct flash_bank *bank)
|
|||
{
|
||||
struct xcf_priv *priv = bank->driver_priv;
|
||||
|
||||
if (true == priv->probed)
|
||||
if (priv->probed)
|
||||
return ERROR_OK;
|
||||
else
|
||||
return xcf_probe(bank);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
# optional args: verify, reset, exit and address
|
||||
#
|
||||
|
||||
lappend _telnet_autocomplete_skip program_error
|
||||
proc program_error {description exit} {
|
||||
if {$exit == 1} {
|
||||
echo $description
|
||||
|
|
|
@ -62,12 +62,12 @@ static inline bool jimcmd_is_proc(Jim_Cmd *cmd)
|
|||
return cmd->isproc;
|
||||
}
|
||||
|
||||
static inline bool jimcmd_is_ocd_command(Jim_Cmd *cmd)
|
||||
bool jimcmd_is_oocd_command(Jim_Cmd *cmd)
|
||||
{
|
||||
return !cmd->isproc && cmd->u.native.cmdProc == jim_command_dispatch;
|
||||
}
|
||||
|
||||
static inline void *jimcmd_privdata(Jim_Cmd *cmd)
|
||||
void *jimcmd_privdata(Jim_Cmd *cmd)
|
||||
{
|
||||
return cmd->isproc ? NULL : cmd->u.native.privData;
|
||||
}
|
||||
|
@ -144,12 +144,13 @@ static void command_log_capture_finish(struct log_capture_state *state)
|
|||
* Use the internal jimtcl API Jim_CreateCommandObj, not exported by jim.h,
|
||||
* and override the bugged API through preprocessor's macro.
|
||||
* This workaround works only when jimtcl is compiled as OpenOCD submodule.
|
||||
* It's broken on macOS, so it's currently restricted on Linux only.
|
||||
* If jimtcl is linked-in from a precompiled library, either static or dynamic,
|
||||
* the symbol Jim_CreateCommandObj is not exported and the build will use the
|
||||
* bugged API.
|
||||
* To be removed when OpenOCD will switch to jimtcl 0.81
|
||||
*/
|
||||
#if JIM_VERSION == 80
|
||||
#if JIM_VERSION == 80 && defined __linux__
|
||||
static int workaround_createcommand(Jim_Interp *interp, const char *cmdName,
|
||||
Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc);
|
||||
int Jim_CreateCommandObj(Jim_Interp *interp, Jim_Obj *cmdNameObj,
|
||||
|
@ -168,7 +169,7 @@ static int workaround_createcommand(Jim_Interp *interp, const char *cmdName,
|
|||
return retval;
|
||||
}
|
||||
#define Jim_CreateCommand workaround_createcommand
|
||||
#endif /* JIM_VERSION == 80 */
|
||||
#endif /* JIM_VERSION == 80 && defined __linux__*/
|
||||
/* FIXME: end of workaround for memory leak in jimtcl 0.80 */
|
||||
|
||||
static int command_retval_set(Jim_Interp *interp, int retval)
|
||||
|
@ -260,7 +261,7 @@ static struct command *command_find_from_name(Jim_Interp *interp, const char *na
|
|||
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))
|
||||
if (!cmd || jimcmd_is_proc(cmd) || !jimcmd_is_oocd_command(cmd))
|
||||
return NULL;
|
||||
|
||||
return jimcmd_privdata(cmd);
|
||||
|
@ -342,7 +343,8 @@ static struct command *register_command(struct command_context *context,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
LOG_DEBUG("registering '%s'...", full_name);
|
||||
if (false) /* too noisy with debug_level 3 */
|
||||
LOG_DEBUG("registering '%s'...", full_name);
|
||||
int retval = Jim_CreateCommand(context->interp, full_name,
|
||||
jim_command_dispatch, c, command_free);
|
||||
if (retval != JIM_OK) {
|
||||
|
@ -440,7 +442,8 @@ int unregister_commands_match(struct command_context *cmd_ctx, const char *forma
|
|||
Jim_DecrRefCount(interp, elem);
|
||||
continue;
|
||||
}
|
||||
LOG_DEBUG("delete command \"%s\"", name);
|
||||
if (false) /* too noisy with debug_level 3 */
|
||||
LOG_DEBUG("delete command \"%s\"", name);
|
||||
#if JIM_VERSION >= 80
|
||||
Jim_DeleteCommand(interp, elem);
|
||||
#else
|
||||
|
@ -817,14 +820,13 @@ static COMMAND_HELPER(command_help_show, struct help_entry *c,
|
|||
((c->help != NULL) && (strstr(c->help, cmd_match) != NULL));
|
||||
|
||||
if (is_match) {
|
||||
command_help_show_indent(n);
|
||||
LOG_USER_N("%s", c->cmd_name);
|
||||
|
||||
if (c->usage && strlen(c->usage) > 0) {
|
||||
LOG_USER_N(" ");
|
||||
command_help_show_wrap(c->usage, 0, n + 5);
|
||||
} else
|
||||
LOG_USER_N("\n");
|
||||
char *msg = alloc_printf("%s %s", c->cmd_name, c->usage);
|
||||
command_help_show_wrap(msg, n, n + 5);
|
||||
free(msg);
|
||||
} else {
|
||||
command_help_show_wrap(c->cmd_name, n, n + 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_match && show_help) {
|
||||
|
@ -864,9 +866,9 @@ static COMMAND_HELPER(command_help_show, struct help_entry *c,
|
|||
stage_msg = " (?mode error?)";
|
||||
break;
|
||||
}
|
||||
msg = alloc_printf("%s%s", c->help ? : "", stage_msg);
|
||||
msg = alloc_printf("%s%s", c->help ? c->help : "", stage_msg);
|
||||
} else
|
||||
msg = alloc_printf("%s", c->help ? : "");
|
||||
msg = alloc_printf("%s", c->help ? c->help : "");
|
||||
|
||||
if (NULL != msg) {
|
||||
command_help_show_wrap(msg, n + 3, n + 3);
|
||||
|
@ -1018,7 +1020,7 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
|||
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))) {
|
||||
if (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_oocd_command(cmd))) {
|
||||
Jim_SetResultString(interp, "unknown", -1);
|
||||
return JIM_OK;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,17 @@ struct command_invocation {
|
|||
Jim_Obj *output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true if the command @c cmd is registered by OpenOCD.
|
||||
*/
|
||||
bool jimcmd_is_oocd_command(Jim_Cmd *cmd);
|
||||
|
||||
/**
|
||||
* Return the pointer to the command's private data specified during the
|
||||
* registration of command @a cmd .
|
||||
*/
|
||||
void *jimcmd_privdata(Jim_Cmd *cmd);
|
||||
|
||||
/**
|
||||
* Command handlers may be defined with more parameters than the base
|
||||
* set provided by command.c. This macro uses C99 magic to allow
|
||||
|
@ -426,6 +437,48 @@ DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t);
|
|||
#define COMMAND_PARSE_ADDRESS(in, out) \
|
||||
COMMAND_PARSE_NUMBER(target_addr, in, out)
|
||||
|
||||
/**
|
||||
* @brief parses the command argument at position @a argn into @a out
|
||||
* as a @a type, or prints a command error referring to @a name_str
|
||||
* and passes the error code to the caller. @a argn will be incremented
|
||||
* if no error occurred. Otherwise the calling function will return
|
||||
* the error code produced by the parsing function.
|
||||
*
|
||||
* This function may cause the calling function to return immediately,
|
||||
* so it should be used carefully to avoid leaking resources. In most
|
||||
* situations, parsing should be completed in full before proceeding
|
||||
* to allocate resources, and this strategy will most prevents leaks.
|
||||
*/
|
||||
#define COMMAND_PARSE_ADDITIONAL_NUMBER(type, argn, out, name_str) \
|
||||
do { \
|
||||
if (argn+1 >= CMD_ARGC || CMD_ARGV[argn+1][0] == '-') { \
|
||||
command_print(CMD, "no " name_str " given"); \
|
||||
return ERROR_FAIL; \
|
||||
} \
|
||||
++argn; \
|
||||
COMMAND_PARSE_NUMBER(type, CMD_ARGV[argn], out); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief parses the command argument at position @a argn into @a out
|
||||
* as a @a type if the argument @a argn does not start with '-'.
|
||||
* and passes the error code to the caller. @a argn will be incremented
|
||||
* if no error occurred. Otherwise the calling function will return
|
||||
* the error code produced by the parsing function.
|
||||
*
|
||||
* This function may cause the calling function to return immediately,
|
||||
* so it should be used carefully to avoid leaking resources. In most
|
||||
* situations, parsing should be completed in full before proceeding
|
||||
* to allocate resources, and this strategy will most prevents leaks.
|
||||
*/
|
||||
#define COMMAND_PARSE_OPTIONAL_NUMBER(type, argn, out) \
|
||||
do { \
|
||||
if (argn+1 < CMD_ARGC && CMD_ARGV[argn+1][0] != '-') { \
|
||||
++argn; \
|
||||
COMMAND_PARSE_NUMBER(type, CMD_ARGV[argn], out); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Parse the string @c as a binary parameter, storing the boolean value
|
||||
* in @c out. The strings @c on and @c off are used to match different
|
||||
|
|
|
@ -44,59 +44,59 @@
|
|||
#include <string.h>
|
||||
#include <jim-nvp.h>
|
||||
|
||||
int Jim_GetNvp(Jim_Interp *interp,
|
||||
Jim_Obj *objPtr, const Jim_Nvp *nvp_table, const Jim_Nvp **result)
|
||||
int jim_get_nvp(Jim_Interp *interp,
|
||||
Jim_Obj *objptr, const struct jim_nvp *nvp_table, const struct jim_nvp **result)
|
||||
{
|
||||
Jim_Nvp *n;
|
||||
struct jim_nvp *n;
|
||||
int e;
|
||||
|
||||
e = Jim_Nvp_name2value_obj(interp, nvp_table, objPtr, &n);
|
||||
e = jim_nvp_name2value_obj(interp, nvp_table, objptr, &n);
|
||||
if (e == JIM_ERR)
|
||||
return e;
|
||||
|
||||
/* Success? found? */
|
||||
if (n->name) {
|
||||
/* remove const */
|
||||
*result = (Jim_Nvp *) n;
|
||||
*result = (struct jim_nvp *)n;
|
||||
return JIM_OK;
|
||||
} else
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
Jim_Nvp *Jim_Nvp_name2value_simple(const Jim_Nvp *p, const char *name)
|
||||
struct jim_nvp *jim_nvp_name2value_simple(const struct jim_nvp *p, const char *name)
|
||||
{
|
||||
while (p->name) {
|
||||
if (0 == strcmp(name, p->name))
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
return (Jim_Nvp *) (p);
|
||||
return (struct jim_nvp *)p;
|
||||
}
|
||||
|
||||
Jim_Nvp *Jim_Nvp_name2value_nocase_simple(const Jim_Nvp *p, const char *name)
|
||||
struct jim_nvp *jim_nvp_name2value_nocase_simple(const struct jim_nvp *p, const char *name)
|
||||
{
|
||||
while (p->name) {
|
||||
if (0 == strcasecmp(name, p->name))
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
return (Jim_Nvp *) (p);
|
||||
return (struct jim_nvp *)p;
|
||||
}
|
||||
|
||||
int Jim_Nvp_name2value_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **result)
|
||||
int jim_nvp_name2value_obj(Jim_Interp *interp, const struct jim_nvp *p, Jim_Obj *o, struct jim_nvp **result)
|
||||
{
|
||||
return Jim_Nvp_name2value(interp, p, Jim_String(o), result);
|
||||
return jim_nvp_name2value(interp, p, Jim_String(o), result);
|
||||
}
|
||||
|
||||
int Jim_Nvp_name2value(Jim_Interp *interp, const Jim_Nvp *_p, const char *name, Jim_Nvp **result)
|
||||
int jim_nvp_name2value(Jim_Interp *interp, const struct jim_nvp *_p, const char *name, struct jim_nvp **result)
|
||||
{
|
||||
const Jim_Nvp *p;
|
||||
const struct jim_nvp *p;
|
||||
|
||||
p = Jim_Nvp_name2value_simple(_p, name);
|
||||
p = jim_nvp_name2value_simple(_p, name);
|
||||
|
||||
/* result */
|
||||
if (result)
|
||||
*result = (Jim_Nvp *) (p);
|
||||
*result = (struct jim_nvp *)p;
|
||||
|
||||
/* found? */
|
||||
if (p->name)
|
||||
|
@ -105,23 +105,23 @@ int Jim_Nvp_name2value(Jim_Interp *interp, const Jim_Nvp *_p, const char *name,
|
|||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp,
|
||||
const Jim_Nvp *p,
|
||||
int jim_nvp_name2value_obj_nocase(Jim_Interp *interp,
|
||||
const struct jim_nvp *p,
|
||||
Jim_Obj *o,
|
||||
Jim_Nvp **puthere)
|
||||
struct jim_nvp **puthere)
|
||||
{
|
||||
return Jim_Nvp_name2value_nocase(interp, p, Jim_String(o), puthere);
|
||||
return jim_nvp_name2value_nocase(interp, p, Jim_String(o), puthere);
|
||||
}
|
||||
|
||||
int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const Jim_Nvp *_p, const char *name,
|
||||
Jim_Nvp **puthere)
|
||||
int jim_nvp_name2value_nocase(Jim_Interp *interp, const struct jim_nvp *_p, const char *name,
|
||||
struct jim_nvp **puthere)
|
||||
{
|
||||
const Jim_Nvp *p;
|
||||
const struct jim_nvp *p;
|
||||
|
||||
p = Jim_Nvp_name2value_nocase_simple(_p, name);
|
||||
p = jim_nvp_name2value_nocase_simple(_p, name);
|
||||
|
||||
if (puthere)
|
||||
*puthere = (Jim_Nvp *) (p);
|
||||
*puthere = (struct jim_nvp *)p;
|
||||
/* found */
|
||||
if (p->name)
|
||||
return JIM_OK;
|
||||
|
@ -129,7 +129,7 @@ int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const Jim_Nvp *_p, const char
|
|||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int Jim_Nvp_value2name_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **result)
|
||||
int jim_nvp_value2name_obj(Jim_Interp *interp, const struct jim_nvp *p, Jim_Obj *o, struct jim_nvp **result)
|
||||
{
|
||||
int e;
|
||||
jim_wide w;
|
||||
|
@ -138,27 +138,27 @@ int Jim_Nvp_value2name_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim
|
|||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
return Jim_Nvp_value2name(interp, p, w, result);
|
||||
return jim_nvp_value2name(interp, p, w, result);
|
||||
}
|
||||
|
||||
Jim_Nvp *Jim_Nvp_value2name_simple(const Jim_Nvp *p, int value)
|
||||
struct jim_nvp *jim_nvp_value2name_simple(const struct jim_nvp *p, int value)
|
||||
{
|
||||
while (p->name) {
|
||||
if (value == p->value)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
return (Jim_Nvp *) (p);
|
||||
return (struct jim_nvp *)p;
|
||||
}
|
||||
|
||||
int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *_p, int value, Jim_Nvp **result)
|
||||
int jim_nvp_value2name(Jim_Interp *interp, const struct jim_nvp *_p, int value, struct jim_nvp **result)
|
||||
{
|
||||
const Jim_Nvp *p;
|
||||
const struct jim_nvp *p;
|
||||
|
||||
p = Jim_Nvp_value2name_simple(_p, value);
|
||||
p = jim_nvp_value2name_simple(_p, value);
|
||||
|
||||
if (result)
|
||||
*result = (Jim_Nvp *) (p);
|
||||
*result = (struct jim_nvp *)p;
|
||||
|
||||
if (p->name)
|
||||
return JIM_OK;
|
||||
|
@ -166,7 +166,7 @@ int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *_p, int value, Jim_Nvp
|
|||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Setup(Jim_GetOptInfo *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
int jim_getopt_setup(struct jim_getopt_info *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->interp = interp;
|
||||
|
@ -176,7 +176,7 @@ int Jim_GetOpt_Setup(Jim_GetOptInfo *p, Jim_Interp *interp, int argc, Jim_Obj *c
|
|||
return JIM_OK;
|
||||
}
|
||||
|
||||
void Jim_GetOpt_Debug(Jim_GetOptInfo *p)
|
||||
void jim_getopt_debug(struct jim_getopt_info *p)
|
||||
{
|
||||
int x;
|
||||
|
||||
|
@ -186,7 +186,7 @@ void Jim_GetOpt_Debug(Jim_GetOptInfo *p)
|
|||
fprintf(stderr, "-------\n");
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere)
|
||||
int jim_getopt_obj(struct jim_getopt_info *goi, Jim_Obj **puthere)
|
||||
{
|
||||
Jim_Obj *o;
|
||||
|
||||
|
@ -205,13 +205,13 @@ int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere)
|
|||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len)
|
||||
int jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len)
|
||||
{
|
||||
int r;
|
||||
Jim_Obj *o;
|
||||
const char *cp;
|
||||
|
||||
r = Jim_GetOpt_Obj(goi, &o);
|
||||
r = jim_getopt_obj(goi, &o);
|
||||
if (r == JIM_OK) {
|
||||
cp = Jim_GetString(o, len);
|
||||
if (puthere) {
|
||||
|
@ -221,7 +221,7 @@ int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len)
|
|||
return r;
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere)
|
||||
int jim_getopt_double(struct jim_getopt_info *goi, double *puthere)
|
||||
{
|
||||
int r;
|
||||
Jim_Obj *o;
|
||||
|
@ -230,7 +230,7 @@ int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere)
|
|||
if (puthere == NULL)
|
||||
puthere = &_safe;
|
||||
|
||||
r = Jim_GetOpt_Obj(goi, &o);
|
||||
r = jim_getopt_obj(goi, &o);
|
||||
if (r == JIM_OK) {
|
||||
r = Jim_GetDouble(goi->interp, o, puthere);
|
||||
if (r != JIM_OK)
|
||||
|
@ -239,7 +239,7 @@ int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere)
|
|||
return r;
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere)
|
||||
int jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere)
|
||||
{
|
||||
int r;
|
||||
Jim_Obj *o;
|
||||
|
@ -248,37 +248,37 @@ int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere)
|
|||
if (puthere == NULL)
|
||||
puthere = &_safe;
|
||||
|
||||
r = Jim_GetOpt_Obj(goi, &o);
|
||||
r = jim_getopt_obj(goi, &o);
|
||||
if (r == JIM_OK)
|
||||
r = Jim_GetWide(goi->interp, o, puthere);
|
||||
return r;
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *nvp, Jim_Nvp **puthere)
|
||||
int jim_getopt_nvp(struct jim_getopt_info *goi, const struct jim_nvp *nvp, struct jim_nvp **puthere)
|
||||
{
|
||||
Jim_Nvp *_safe;
|
||||
struct jim_nvp *_safe;
|
||||
Jim_Obj *o;
|
||||
int e;
|
||||
|
||||
if (puthere == NULL)
|
||||
puthere = &_safe;
|
||||
|
||||
e = Jim_GetOpt_Obj(goi, &o);
|
||||
e = jim_getopt_obj(goi, &o);
|
||||
if (e == JIM_OK)
|
||||
e = Jim_Nvp_name2value_obj(goi->interp, nvp, o, puthere);
|
||||
e = jim_nvp_name2value_obj(goi->interp, nvp, o, puthere);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *nvptable, int hadprefix)
|
||||
void jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *nvptable, int hadprefix)
|
||||
{
|
||||
if (hadprefix)
|
||||
Jim_SetResult_NvpUnknown(goi->interp, goi->argv[-2], goi->argv[-1], nvptable);
|
||||
jim_set_result_nvp_unknown(goi->interp, goi->argv[-2], goi->argv[-1], nvptable);
|
||||
else
|
||||
Jim_SetResult_NvpUnknown(goi->interp, NULL, goi->argv[-1], nvptable);
|
||||
jim_set_result_nvp_unknown(goi->interp, NULL, goi->argv[-1], nvptable);
|
||||
}
|
||||
|
||||
int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere)
|
||||
int jim_getopt_enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere)
|
||||
{
|
||||
int _safe;
|
||||
Jim_Obj *o;
|
||||
|
@ -286,14 +286,14 @@ int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere
|
|||
|
||||
if (puthere == NULL)
|
||||
puthere = &_safe;
|
||||
e = Jim_GetOpt_Obj(goi, &o);
|
||||
e = jim_getopt_obj(goi, &o);
|
||||
if (e == JIM_OK)
|
||||
e = Jim_GetEnum(goi->interp, o, lookup, puthere, "option", JIM_ERRMSG);
|
||||
return e;
|
||||
}
|
||||
|
||||
void Jim_SetResult_NvpUnknown(Jim_Interp *interp,
|
||||
Jim_Obj *param_name, Jim_Obj *param_value, const Jim_Nvp *nvp)
|
||||
void jim_set_result_nvp_unknown(Jim_Interp *interp,
|
||||
Jim_Obj *param_name, Jim_Obj *param_value, const struct jim_nvp *nvp)
|
||||
{
|
||||
if (param_name)
|
||||
Jim_SetResultFormatted(interp,
|
||||
|
@ -318,7 +318,7 @@ void Jim_SetResult_NvpUnknown(Jim_Interp *interp,
|
|||
}
|
||||
}
|
||||
|
||||
const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
const char *jim_debug_argv_string(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
static Jim_Obj *debug_string_obj;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
*
|
||||
* Example:
|
||||
* \code
|
||||
* const Jim_Nvp yn[] = {
|
||||
* const struct jim_nvp yn[] = {
|
||||
* { "yes", 1 },
|
||||
* { "no" , 0 },
|
||||
* { "yep", 1 },
|
||||
|
@ -70,60 +70,60 @@
|
|||
* { NULL, -1 },
|
||||
* };
|
||||
*
|
||||
* Jim_Nvp *result
|
||||
* e = Jim_Nvp_name2value(interp, yn, "y", &result);
|
||||
* struct jim_nvp *result
|
||||
* e = jim_nvp_name2value(interp, yn, "y", &result);
|
||||
* returns &yn[0];
|
||||
* e = Jim_Nvp_name2value(interp, yn, "n", &result);
|
||||
* e = jim_nvp_name2value(interp, yn, "n", &result);
|
||||
* returns &yn[1];
|
||||
* e = Jim_Nvp_name2value(interp, yn, "Blah", &result);
|
||||
* e = jim_nvp_name2value(interp, yn, "Blah", &result);
|
||||
* returns &yn[4];
|
||||
* \endcode
|
||||
*
|
||||
* During the number2name operation, the first matching value is returned.
|
||||
*/
|
||||
typedef struct {
|
||||
struct jim_nvp {
|
||||
const char *name;
|
||||
int value;
|
||||
} Jim_Nvp;
|
||||
};
|
||||
|
||||
int Jim_GetNvp(Jim_Interp *interp,
|
||||
Jim_Obj *objPtr,
|
||||
const Jim_Nvp *nvp_table,
|
||||
const Jim_Nvp **result);
|
||||
int jim_get_nvp(Jim_Interp *interp,
|
||||
Jim_Obj *objptr,
|
||||
const struct jim_nvp *nvp_table,
|
||||
const struct jim_nvp **result);
|
||||
|
||||
/* Name Value Pairs Operations */
|
||||
Jim_Nvp *Jim_Nvp_name2value_simple(const Jim_Nvp *nvp_table, const char *name);
|
||||
Jim_Nvp *Jim_Nvp_name2value_nocase_simple(const Jim_Nvp *nvp_table, const char *name);
|
||||
Jim_Nvp *Jim_Nvp_value2name_simple(const Jim_Nvp *nvp_table, int v);
|
||||
struct jim_nvp *jim_nvp_name2value_simple(const struct jim_nvp *nvp_table, const char *name);
|
||||
struct jim_nvp *jim_nvp_name2value_nocase_simple(const struct jim_nvp *nvp_table, const char *name);
|
||||
struct jim_nvp *jim_nvp_value2name_simple(const struct jim_nvp *nvp_table, int v);
|
||||
|
||||
int Jim_Nvp_name2value(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
int jim_nvp_name2value(Jim_Interp *interp,
|
||||
const struct jim_nvp *nvp_table,
|
||||
const char *name,
|
||||
Jim_Nvp **result);
|
||||
int Jim_Nvp_name2value_nocase(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
struct jim_nvp **result);
|
||||
int jim_nvp_name2value_nocase(Jim_Interp *interp,
|
||||
const struct jim_nvp *nvp_table,
|
||||
const char *name,
|
||||
Jim_Nvp **result);
|
||||
int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *nvp_table, int value, Jim_Nvp **result);
|
||||
struct jim_nvp **result);
|
||||
int jim_nvp_value2name(Jim_Interp *interp, const struct jim_nvp *nvp_table, int value, struct jim_nvp **result);
|
||||
|
||||
int Jim_Nvp_name2value_obj(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
int jim_nvp_name2value_obj(Jim_Interp *interp,
|
||||
const struct jim_nvp *nvp_table,
|
||||
Jim_Obj *name_obj,
|
||||
Jim_Nvp **result);
|
||||
int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
struct jim_nvp **result);
|
||||
int jim_nvp_name2value_obj_nocase(Jim_Interp *interp,
|
||||
const struct jim_nvp *nvp_table,
|
||||
Jim_Obj *name_obj,
|
||||
Jim_Nvp **result);
|
||||
int Jim_Nvp_value2name_obj(Jim_Interp *interp,
|
||||
const Jim_Nvp *nvp_table,
|
||||
struct jim_nvp **result);
|
||||
int jim_nvp_value2name_obj(Jim_Interp *interp,
|
||||
const struct jim_nvp *nvp_table,
|
||||
Jim_Obj *value_obj,
|
||||
Jim_Nvp **result);
|
||||
struct jim_nvp **result);
|
||||
|
||||
/** prints a nice 'unknown' parameter error message to the 'result' */
|
||||
void Jim_SetResult_NvpUnknown(Jim_Interp *interp,
|
||||
void jim_set_result_nvp_unknown(Jim_Interp *interp,
|
||||
Jim_Obj *param_name,
|
||||
Jim_Obj *param_value,
|
||||
const Jim_Nvp *nvp_table);
|
||||
const struct jim_nvp *nvp_table);
|
||||
|
||||
/** Debug: convert argc/argv into a printable string for printf() debug
|
||||
*
|
||||
|
@ -142,7 +142,7 @@ void Jim_SetResult_NvpUnknown(Jim_Interp *interp,
|
|||
* fclose(fp);
|
||||
* \endcode
|
||||
*/
|
||||
const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||
const char *jim_debug_argv_string(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||
|
||||
|
||||
/** A TCL -ish GetOpt like code.
|
||||
|
@ -157,25 +157,25 @@ const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *a
|
|||
* Only supports tcl type options, like "-foo 123"
|
||||
*/
|
||||
|
||||
typedef struct jim_getopt {
|
||||
struct jim_getopt_info {
|
||||
Jim_Interp *interp;
|
||||
int argc;
|
||||
Jim_Obj *const *argv;
|
||||
int isconfigure; /* non-zero if configure */
|
||||
} Jim_GetOptInfo;
|
||||
};
|
||||
|
||||
/** GetOpt - how to.
|
||||
*
|
||||
* Example (short and incomplete):
|
||||
* \code
|
||||
* Jim_GetOptInfo goi;
|
||||
* struct jim_getopt_info goi;
|
||||
*
|
||||
* Jim_GetOpt_Setup(&goi, interp, argc, argv);
|
||||
* jim_getopt_setup(&goi, interp, argc, argv);
|
||||
*
|
||||
* while (goi.argc) {
|
||||
* e = Jim_GetOpt_Nvp(&goi, nvp_options, &n);
|
||||
* e = jim_getopt_nvp(&goi, nvp_options, &n);
|
||||
* if (e != JIM_OK) {
|
||||
* Jim_GetOpt_NvpUnknown(&goi, nvp_options, 0);
|
||||
* jim_getopt_nvp_unknown(&goi, nvp_options, 0);
|
||||
* return e;
|
||||
* }
|
||||
*
|
||||
|
@ -187,16 +187,16 @@ typedef struct jim_getopt {
|
|||
* if (goi.argc < 1) {
|
||||
* .. not enough args error ..
|
||||
* }
|
||||
* Jim_GetOpt_String(&goi, &cp, NULL);
|
||||
* jim_getopt_string(&goi, &cp, NULL);
|
||||
* printf("FIRSTNAME: %s\n", cp);
|
||||
* case AGE:
|
||||
* Jim_GetOpt_Wide(&goi, &w);
|
||||
* jim_getopt_wide(&goi, &w);
|
||||
* printf("AGE: %d\n", (int)(w));
|
||||
* break;
|
||||
* case POLITICS:
|
||||
* e = Jim_GetOpt_Nvp(&goi, nvp_politics, &n);
|
||||
* e = jim_getopt_nvp(&goi, nvp_politics, &n);
|
||||
* if (e != JIM_OK) {
|
||||
* Jim_GetOpt_NvpUnknown(&goi, nvp_politics, 1);
|
||||
* jim_getopt_nvp_unknown(&goi, nvp_politics, 1);
|
||||
* return e;
|
||||
* }
|
||||
* }
|
||||
|
@ -214,13 +214,13 @@ typedef struct jim_getopt {
|
|||
* \param argv - argv (will be copied)
|
||||
*
|
||||
* \code
|
||||
* Jim_GetOptInfo goi;
|
||||
* struct jim_getopt_info goi;
|
||||
*
|
||||
* Jim_GetOptSetup(&goi, interp, argc, argv);
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
int Jim_GetOpt_Setup(Jim_GetOptInfo *goi,
|
||||
int jim_getopt_setup(struct jim_getopt_info *goi,
|
||||
Jim_Interp *interp,
|
||||
int argc,
|
||||
Jim_Obj *const *argv);
|
||||
|
@ -229,7 +229,7 @@ int Jim_GetOpt_Setup(Jim_GetOptInfo *goi,
|
|||
/** Debug - Dump parameters to stderr
|
||||
* \param goi - current parameters
|
||||
*/
|
||||
void Jim_GetOpt_Debug(Jim_GetOptInfo *goi);
|
||||
void jim_getopt_debug(struct jim_getopt_info *goi);
|
||||
|
||||
/** Remove argv[0] from the list.
|
||||
*
|
||||
|
@ -237,7 +237,7 @@ void Jim_GetOpt_Debug(Jim_GetOptInfo *goi);
|
|||
* \param puthere - where param is put
|
||||
*
|
||||
*/
|
||||
int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere);
|
||||
int jim_getopt_obj(struct jim_getopt_info *goi, Jim_Obj **puthere);
|
||||
|
||||
/** Remove argv[0] as string.
|
||||
*
|
||||
|
@ -245,7 +245,7 @@ int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere);
|
|||
* \param puthere - where param is put
|
||||
* \param len - return its length
|
||||
*/
|
||||
int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len);
|
||||
int jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len);
|
||||
|
||||
/** Remove argv[0] as double.
|
||||
*
|
||||
|
@ -253,14 +253,14 @@ int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len);
|
|||
* \param puthere - where param is put.
|
||||
*
|
||||
*/
|
||||
int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere);
|
||||
int jim_getopt_double(struct jim_getopt_info *goi, double *puthere);
|
||||
|
||||
/** Remove argv[0] as wide.
|
||||
*
|
||||
* \param goi - get opt info
|
||||
* \param puthere - where param is put.
|
||||
*/
|
||||
int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere);
|
||||
int jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere);
|
||||
|
||||
/** Remove argv[0] as NVP.
|
||||
*
|
||||
|
@ -269,7 +269,7 @@ int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere);
|
|||
* \param puthere - where param is put.
|
||||
*
|
||||
*/
|
||||
int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, Jim_Nvp **puthere);
|
||||
int jim_getopt_nvp(struct jim_getopt_info *goi, const struct jim_nvp *lookup, struct jim_nvp **puthere);
|
||||
|
||||
/** Create an appropriate error message for an NVP.
|
||||
*
|
||||
|
@ -289,20 +289,20 @@ int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, Jim_Nvp **puthere
|
|||
*
|
||||
* while (goi.argc) {
|
||||
* // Get the next option
|
||||
* e = Jim_GetOpt_Nvp(&goi, cmd_options, &n);
|
||||
* e = jim_getopt_nvp(&goi, cmd_options, &n);
|
||||
* if (e != JIM_OK) {
|
||||
* // option was not recognized
|
||||
* // pass 'hadprefix = 0' because there is no prefix
|
||||
* Jim_GetOpt_NvpUnknown(&goi, cmd_options, 0);
|
||||
* jim_getopt_nvp_unknown(&goi, cmd_options, 0);
|
||||
* return e;
|
||||
* }
|
||||
*
|
||||
* switch (n->value) {
|
||||
* case OPT_SEX:
|
||||
* // handle: --sex male | female | lots | needmore
|
||||
* e = Jim_GetOpt_Nvp(&goi, &nvp_sex, &n);
|
||||
* e = jim_getopt_nvp(&goi, &nvp_sex, &n);
|
||||
* if (e != JIM_OK) {
|
||||
* Jim_GetOpt_NvpUnknown(&ogi, nvp_sex, 1);
|
||||
* jim_getopt_nvp_unknown(&ogi, nvp_sex, 1);
|
||||
* return e;
|
||||
* }
|
||||
* printf("Code: (%d) is %s\n", n->value, n->name);
|
||||
|
@ -314,7 +314,7 @@ int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, Jim_Nvp **puthere
|
|||
* \endcode
|
||||
*
|
||||
*/
|
||||
void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, int hadprefix);
|
||||
void jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *lookup, int hadprefix);
|
||||
|
||||
|
||||
/** Remove argv[0] as Enum
|
||||
|
@ -324,6 +324,146 @@ void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, int hadpr
|
|||
* \param puthere - where param is put.
|
||||
*
|
||||
*/
|
||||
int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere);
|
||||
int jim_getopt_enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere);
|
||||
|
||||
/*
|
||||
* DEPRECATED API
|
||||
* Do not use these API anymore, as they do not comply with OpenOCD coding style
|
||||
* They are listed here to avoid breaking build after merge of patches already queued in gerrit
|
||||
*/
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
return jim_debug_argv_string(interp, argc, argv);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_GetNvp(Jim_Interp *interp, Jim_Obj *objptr, const struct jim_nvp *nvp_table, const struct jim_nvp **result)
|
||||
{
|
||||
return jim_get_nvp(interp, objptr, nvp_table, result);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
void Jim_GetOpt_Debug(struct jim_getopt_info *goi)
|
||||
{
|
||||
jim_getopt_debug(goi);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_GetOpt_Double(struct jim_getopt_info *goi, double *puthere)
|
||||
{
|
||||
return jim_getopt_double(goi, puthere);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_GetOpt_Enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere)
|
||||
{
|
||||
return jim_getopt_enum(goi, lookup, puthere);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_GetOpt_Nvp(struct jim_getopt_info *goi, const struct jim_nvp *lookup, struct jim_nvp **puthere)
|
||||
{
|
||||
return jim_getopt_nvp(goi, lookup, puthere);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
void Jim_GetOpt_NvpUnknown(struct jim_getopt_info *goi, const struct jim_nvp *lookup, int hadprefix)
|
||||
{
|
||||
jim_getopt_nvp_unknown(goi, lookup, hadprefix);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_GetOpt_Obj(struct jim_getopt_info *goi, Jim_Obj **puthere)
|
||||
{
|
||||
return jim_getopt_obj(goi, puthere);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_GetOpt_Setup(struct jim_getopt_info *goi, Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
return jim_getopt_setup(goi, interp, argc, argv);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_GetOpt_String(struct jim_getopt_info *goi, const char **puthere, int *len)
|
||||
{
|
||||
return jim_getopt_string(goi, puthere, len);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_GetOpt_Wide(struct jim_getopt_info *goi, jim_wide *puthere)
|
||||
{
|
||||
return jim_getopt_wide(goi, puthere);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_Nvp_name2value(Jim_Interp *interp, const struct jim_nvp *nvp_table, const char *name, struct jim_nvp **result)
|
||||
{
|
||||
return jim_nvp_name2value(interp, nvp_table, name, result);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const struct jim_nvp *nvp_table, const char *name,
|
||||
struct jim_nvp **result)
|
||||
{
|
||||
return jim_nvp_name2value_nocase(interp, nvp_table, name, result);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
struct jim_nvp *Jim_Nvp_name2value_nocase_simple(const struct jim_nvp *nvp_table, const char *name)
|
||||
{
|
||||
return jim_nvp_name2value_nocase_simple(nvp_table, name);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_Nvp_name2value_obj(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *name_obj,
|
||||
struct jim_nvp **result)
|
||||
{
|
||||
return jim_nvp_name2value_obj(interp, nvp_table, name_obj, result);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *name_obj,
|
||||
struct jim_nvp **result)
|
||||
{
|
||||
return jim_nvp_name2value_obj_nocase(interp, nvp_table, name_obj, result);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
struct jim_nvp *Jim_Nvp_name2value_simple(const struct jim_nvp *nvp_table, const char *name)
|
||||
{
|
||||
return jim_nvp_name2value_simple(nvp_table, name);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_Nvp_value2name(Jim_Interp *interp, const struct jim_nvp *nvp_table, int value, struct jim_nvp **result)
|
||||
{
|
||||
return jim_nvp_value2name(interp, nvp_table, value, result);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
int Jim_Nvp_value2name_obj(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *value_obj,
|
||||
struct jim_nvp **result)
|
||||
{
|
||||
return jim_nvp_value2name_obj(interp, nvp_table, value_obj, result);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
struct jim_nvp *Jim_Nvp_value2name_simple(const struct jim_nvp *nvp_table, int v)
|
||||
{
|
||||
return jim_nvp_value2name_simple(nvp_table, v);
|
||||
}
|
||||
|
||||
static inline __attribute__ ((deprecated))
|
||||
void Jim_SetResult_NvpUnknown(Jim_Interp *interp, Jim_Obj *param_name, Jim_Obj *param_value,
|
||||
const struct jim_nvp *nvp_table)
|
||||
{
|
||||
jim_set_result_nvp_unknown(interp, param_name, param_value, nvp_table);
|
||||
}
|
||||
|
||||
typedef struct jim_getopt_info Jim_GetOptInfo __attribute__ ((deprecated));
|
||||
typedef struct jim_nvp Jim_Nvp __attribute__ ((deprecated));
|
||||
|
||||
#endif /* OPENOCD_HELPER_JIM_NVP_H */
|
||||
|
|
|
@ -1,26 +1,43 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* The content of this file is mainly copied/inspired from Linux kernel
|
||||
* code in include/linux/list.h, include/linux/types.h
|
||||
* Last aligned with kernel v5.12:
|
||||
* - skip the functions hlist_unhashed_lockless() and __list_del_clearprev()
|
||||
* that are relevant only in kernel;
|
||||
* - Remove non-standard GCC extension "omitted conditional operand" from
|
||||
* list_prepare_entry;
|
||||
* - expand READ_ONCE, WRITE_ONCE, smp_load_acquire, smp_store_release;
|
||||
* - make comments compatible with doxygen.
|
||||
*
|
||||
* There is an example of using this file in contrib/list_example.c.
|
||||
*/
|
||||
|
||||
#ifndef OPENOCD_HELPER_LIST_H
|
||||
#define OPENOCD_HELPER_LIST_H
|
||||
|
||||
/* begin local changes */
|
||||
#include <helper/types.h>
|
||||
|
||||
#define prefetch(x) ((void)x)
|
||||
#define LIST_POISON1 NULL
|
||||
#define LIST_POISON2 NULL
|
||||
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
|
||||
struct hlist_head {
|
||||
struct hlist_node *first;
|
||||
};
|
||||
|
||||
struct hlist_node {
|
||||
struct hlist_node *next, **pprev;
|
||||
};
|
||||
/* end local changes */
|
||||
|
||||
/*
|
||||
* Simple doubly linked list implementation.
|
||||
* Circular doubly linked list implementation.
|
||||
*
|
||||
* Some of the internal functions ("__xxx") are useful when
|
||||
* manipulating whole lists rather than single entries, as
|
||||
|
@ -31,36 +48,58 @@ struct hlist_node {
|
|||
|
||||
#define LIST_HEAD_INIT(name) { &(name), &(name) }
|
||||
|
||||
#define LIST_HEAD(name) \
|
||||
#define LIST_HEAD(name) \
|
||||
struct list_head name = LIST_HEAD_INIT(name)
|
||||
|
||||
/**
|
||||
* INIT_LIST_HEAD - Initialize a list_head structure
|
||||
* @param list list_head structure to be initialized.
|
||||
*
|
||||
* Initializes the list_head to point to itself. If it is a list header,
|
||||
* the result is an empty list.
|
||||
*/
|
||||
static inline void INIT_LIST_HEAD(struct list_head *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_LIST
|
||||
extern bool __list_add_valid(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next);
|
||||
extern bool __list_del_entry_valid(struct list_head *entry);
|
||||
#else
|
||||
static inline bool __list_add_valid(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static inline bool __list_del_entry_valid(struct list_head *entry)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Insert a new entry between two known consecutive entries.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
#ifndef CONFIG_DEBUG_LIST
|
||||
static inline void __list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
if (!__list_add_valid(new, prev, next))
|
||||
return;
|
||||
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
#else
|
||||
extern void __list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* list_add - add a new entry
|
||||
|
@ -102,28 +141,28 @@ static inline void __list_del(struct list_head *prev, struct list_head *next)
|
|||
prev->next = next;
|
||||
}
|
||||
|
||||
/* Ignore kernel __list_del_clearprev() */
|
||||
|
||||
static inline void __list_del_entry(struct list_head *entry)
|
||||
{
|
||||
if (!__list_del_entry_valid(entry))
|
||||
return;
|
||||
|
||||
__list_del(entry->prev, entry->next);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del - deletes entry from list.
|
||||
* @param entry the element to delete from the list.
|
||||
* Note: list_empty() on entry does not return true after this, the entry is
|
||||
* in an undefined state.
|
||||
*/
|
||||
#ifndef CONFIG_DEBUG_LIST
|
||||
static inline void __list_del_entry(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
}
|
||||
|
||||
static inline void list_del(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
__list_del_entry(entry);
|
||||
entry->next = LIST_POISON1;
|
||||
entry->prev = LIST_POISON2;
|
||||
}
|
||||
#else
|
||||
extern void __list_del_entry(struct list_head *entry);
|
||||
extern void list_del(struct list_head *entry);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* list_replace - replace old entry by new one
|
||||
|
@ -133,7 +172,7 @@ extern void list_del(struct list_head *entry);
|
|||
* If @a old was empty, it will be overwritten.
|
||||
*/
|
||||
static inline void list_replace(struct list_head *old,
|
||||
struct list_head *new)
|
||||
struct list_head *new)
|
||||
{
|
||||
new->next = old->next;
|
||||
new->next->prev = new;
|
||||
|
@ -141,13 +180,37 @@ static inline void list_replace(struct list_head *old,
|
|||
new->prev->next = new;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_replace_init - replace old entry by new one and initialize the old one
|
||||
* @param old the element to be replaced
|
||||
* @param new the new element to insert
|
||||
*
|
||||
* If @a old was empty, it will be overwritten.
|
||||
*/
|
||||
static inline void list_replace_init(struct list_head *old,
|
||||
struct list_head *new)
|
||||
struct list_head *new)
|
||||
{
|
||||
list_replace(old, new);
|
||||
INIT_LIST_HEAD(old);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_swap - replace entry1 with entry2 and re-add entry1 at entry2's position
|
||||
* @param entry1 the location to place entry2
|
||||
* @param entry2 the location to place entry1
|
||||
*/
|
||||
static inline void list_swap(struct list_head *entry1,
|
||||
struct list_head *entry2)
|
||||
{
|
||||
struct list_head *pos = entry2->prev;
|
||||
|
||||
list_del(entry2);
|
||||
list_replace(entry1, entry2);
|
||||
if (pos == entry1)
|
||||
pos = entry2;
|
||||
list_add(entry1, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del_init - deletes entry from list and reinitialize it.
|
||||
* @param entry the element to delete from the list.
|
||||
|
@ -175,19 +238,53 @@ static inline void list_move(struct list_head *list, struct list_head *head)
|
|||
* @param head the head that will follow our entry
|
||||
*/
|
||||
static inline void list_move_tail(struct list_head *list,
|
||||
struct list_head *head)
|
||||
struct list_head *head)
|
||||
{
|
||||
__list_del_entry(list);
|
||||
list_add_tail(list, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_bulk_move_tail - move a subsection of a list to its tail
|
||||
* @param head the head that will follow our entry
|
||||
* @param first the first entry to move
|
||||
* @param last the last entry to move, can be the same as first
|
||||
*
|
||||
* Move all entries between @a first and including @a last before @a head.
|
||||
* All three entries must belong to the same linked list.
|
||||
*/
|
||||
static inline void list_bulk_move_tail(struct list_head *head,
|
||||
struct list_head *first,
|
||||
struct list_head *last)
|
||||
{
|
||||
first->prev->next = last->next;
|
||||
last->next->prev = first->prev;
|
||||
|
||||
head->prev->next = first;
|
||||
first->prev = head->prev;
|
||||
|
||||
last->next = head;
|
||||
head->prev = last;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_is_first -- tests whether @a list is the first entry in list @a head
|
||||
* @param list the entry to test
|
||||
* @param head the head of the list
|
||||
*/
|
||||
static inline int list_is_first(const struct list_head *list,
|
||||
const struct list_head *head)
|
||||
{
|
||||
return list->prev == head;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_is_last - tests whether @a list is the last entry in list @a head
|
||||
* @param list the entry to test
|
||||
* @param head the head of the list
|
||||
*/
|
||||
static inline int list_is_last(const struct list_head *list,
|
||||
const struct list_head *head)
|
||||
const struct list_head *head)
|
||||
{
|
||||
return list->next == head;
|
||||
}
|
||||
|
@ -201,6 +298,24 @@ static inline int list_empty(const struct list_head *head)
|
|||
return head->next == head;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del_init_careful - deletes entry from list and reinitialize it.
|
||||
* @param entry the element to delete from the list.
|
||||
*
|
||||
* This is the same as list_del_init(), except designed to be used
|
||||
* together with list_empty_careful() in a way to guarantee ordering
|
||||
* of other memory operations.
|
||||
*
|
||||
* Any memory operations done before a list_del_init_careful() are
|
||||
* guaranteed to be visible after a list_empty_careful() test.
|
||||
*/
|
||||
static inline void list_del_init_careful(struct list_head *entry)
|
||||
{
|
||||
__list_del_entry(entry);
|
||||
entry->prev = entry;
|
||||
entry->next = entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_empty_careful - tests whether a list is empty and not being modified
|
||||
* @param head the list to test
|
||||
|
@ -234,6 +349,24 @@ static inline void list_rotate_left(struct list_head *head)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list_rotate_to_front() - Rotate list to specific item.
|
||||
* @param list The desired new front of the list.
|
||||
* @param head The head of the list.
|
||||
*
|
||||
* Rotates list so that @a list becomes the new front of the list.
|
||||
*/
|
||||
static inline void list_rotate_to_front(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
/*
|
||||
* Deletes the list head from the list denoted by @a head and
|
||||
* places it as the tail of @a list, this effectively rotates the
|
||||
* list so that @a list is at the front.
|
||||
*/
|
||||
list_move_tail(head, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_is_singular - tests whether a list has just one entry.
|
||||
* @param head the list to test.
|
||||
|
@ -244,7 +377,7 @@ static inline int list_is_singular(const struct list_head *head)
|
|||
}
|
||||
|
||||
static inline void __list_cut_position(struct list_head *list,
|
||||
struct list_head *head, struct list_head *entry)
|
||||
struct list_head *head, struct list_head *entry)
|
||||
{
|
||||
struct list_head *new_first = entry->next;
|
||||
list->next = head->next;
|
||||
|
@ -270,12 +403,12 @@ static inline void __list_cut_position(struct list_head *list,
|
|||
*
|
||||
*/
|
||||
static inline void list_cut_position(struct list_head *list,
|
||||
struct list_head *head, struct list_head *entry)
|
||||
struct list_head *head, struct list_head *entry)
|
||||
{
|
||||
if (list_empty(head))
|
||||
return;
|
||||
if (list_is_singular(head) &&
|
||||
(head->next != entry && head != entry))
|
||||
(head->next != entry && head != entry))
|
||||
return;
|
||||
if (entry == head)
|
||||
INIT_LIST_HEAD(list);
|
||||
|
@ -283,9 +416,39 @@ static inline void list_cut_position(struct list_head *list,
|
|||
__list_cut_position(list, head, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_cut_before - cut a list into two, before given entry
|
||||
* @param list a new list to add all removed entries
|
||||
* @param head a list with entries
|
||||
* @param entry an entry within head, could be the head itself
|
||||
*
|
||||
* This helper moves the initial part of @a head, up to but
|
||||
* excluding @a entry, from @a head to @a list. You should pass
|
||||
* in @a entry an element you know is on @a head. @a list should
|
||||
* be an empty list or a list you do not care about losing
|
||||
* its data.
|
||||
* If @a entry == @a head, all entries on @a head are moved to
|
||||
* @a list.
|
||||
*/
|
||||
static inline void list_cut_before(struct list_head *list,
|
||||
struct list_head *head,
|
||||
struct list_head *entry)
|
||||
{
|
||||
if (head->next == entry) {
|
||||
INIT_LIST_HEAD(list);
|
||||
return;
|
||||
}
|
||||
list->next = head->next;
|
||||
list->next->prev = list;
|
||||
list->prev = entry->prev;
|
||||
list->prev->next = list;
|
||||
head->next = entry;
|
||||
entry->prev = head;
|
||||
}
|
||||
|
||||
static inline void __list_splice(const struct list_head *list,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
struct list_head *first = list->next;
|
||||
struct list_head *last = list->prev;
|
||||
|
@ -303,7 +466,7 @@ static inline void __list_splice(const struct list_head *list,
|
|||
* @param head the place to add it in the first list.
|
||||
*/
|
||||
static inline void list_splice(const struct list_head *list,
|
||||
struct list_head *head)
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list))
|
||||
__list_splice(list, head, head->next);
|
||||
|
@ -315,7 +478,7 @@ static inline void list_splice(const struct list_head *list,
|
|||
* @param head the place to add it in the first list.
|
||||
*/
|
||||
static inline void list_splice_tail(struct list_head *list,
|
||||
struct list_head *head)
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list))
|
||||
__list_splice(list, head->prev, head);
|
||||
|
@ -329,7 +492,7 @@ static inline void list_splice_tail(struct list_head *list,
|
|||
* The list at @a list is reinitialised
|
||||
*/
|
||||
static inline void list_splice_init(struct list_head *list,
|
||||
struct list_head *head)
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list)) {
|
||||
__list_splice(list, head, head->next);
|
||||
|
@ -346,7 +509,7 @@ static inline void list_splice_init(struct list_head *list,
|
|||
* The list at @a list is reinitialised
|
||||
*/
|
||||
static inline void list_splice_tail_init(struct list_head *list,
|
||||
struct list_head *head)
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list)) {
|
||||
__list_splice(list, head->prev, head);
|
||||
|
@ -358,7 +521,7 @@ static inline void list_splice_tail_init(struct list_head *list,
|
|||
* list_entry - get the struct for this entry
|
||||
* @param ptr the &struct list_head pointer.
|
||||
* @param type the type of the struct this is embedded in.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*/
|
||||
#define list_entry(ptr, type, member) \
|
||||
container_of(ptr, type, member)
|
||||
|
@ -367,34 +530,71 @@ static inline void list_splice_tail_init(struct list_head *list,
|
|||
* list_first_entry - get the first element from a list
|
||||
* @param ptr the list head to take the element from.
|
||||
* @param type the type of the struct this is embedded in.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Note, that list is expected to be not empty.
|
||||
*/
|
||||
#define list_first_entry(ptr, type, member) \
|
||||
list_entry((ptr)->next, type, member)
|
||||
|
||||
/**
|
||||
* list_last_entry - get the last element from a list
|
||||
* @param ptr the list head to take the element from.
|
||||
* @param type the type of the struct this is embedded in.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Note, that list is expected to be not empty.
|
||||
*/
|
||||
#define list_last_entry(ptr, type, member) \
|
||||
list_entry((ptr)->prev, type, member)
|
||||
|
||||
/**
|
||||
* list_first_entry_or_null - get the first element from a list
|
||||
* @param ptr the list head to take the element from.
|
||||
* @param type the type of the struct this is embedded in.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Note that if the list is empty, it returns NULL.
|
||||
*/
|
||||
#define list_first_entry_or_null(ptr, type, member) ({ \
|
||||
struct list_head *head__ = (ptr); \
|
||||
struct list_head *pos__ = head__->next; \
|
||||
pos__ != head__ ? list_entry(pos__, type, member) : NULL; \
|
||||
})
|
||||
|
||||
/**
|
||||
* list_next_entry - get the next element in list
|
||||
* @param pos the type * to cursor
|
||||
* @param member the name of the list_head within the struct.
|
||||
*/
|
||||
#define list_next_entry(pos, member) \
|
||||
list_entry((pos)->member.next, typeof(*(pos)), member)
|
||||
|
||||
/**
|
||||
* list_prev_entry - get the prev element in list
|
||||
* @param pos the type * to cursor
|
||||
* @param member the name of the list_head within the struct.
|
||||
*/
|
||||
#define list_prev_entry(pos, member) \
|
||||
list_entry((pos)->member.prev, typeof(*(pos)), member)
|
||||
|
||||
/**
|
||||
* list_for_each - iterate over a list
|
||||
* @param pos the &struct list_head to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
*/
|
||||
#define list_for_each(pos, head) \
|
||||
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
|
||||
pos = pos->next)
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
/**
|
||||
* __list_for_each - iterate over a list
|
||||
* list_for_each_continue - continue iteration over a list
|
||||
* @param pos the &struct list_head to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
*
|
||||
* This variant differs from list_for_each() in that it's the
|
||||
* simplest possible list iteration code, no prefetching is done.
|
||||
* Use this for code that knows the list to be very short (empty
|
||||
* or 1 entry) most of the time.
|
||||
* Continue to iterate over a list, continuing after the current position.
|
||||
*/
|
||||
#define __list_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
#define list_for_each_continue(pos, head) \
|
||||
for (pos = pos->next; pos != (head); pos = pos->next)
|
||||
|
||||
/**
|
||||
* list_for_each_prev - iterate over a list backwards
|
||||
|
@ -402,8 +602,7 @@ static inline void list_splice_tail_init(struct list_head *list,
|
|||
* @param head the head for your list.
|
||||
*/
|
||||
#define list_for_each_prev(pos, head) \
|
||||
for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
|
||||
pos = pos->prev)
|
||||
for (pos = (head)->prev; pos != (head); pos = pos->prev)
|
||||
|
||||
/**
|
||||
* list_for_each_safe - iterate over a list safe against removal of list entry
|
||||
|
@ -413,7 +612,7 @@ static inline void list_splice_tail_init(struct list_head *list,
|
|||
*/
|
||||
#define list_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
pos = n, n = pos->next)
|
||||
|
||||
/**
|
||||
* list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
|
||||
|
@ -422,148 +621,170 @@ static inline void list_splice_tail_init(struct list_head *list,
|
|||
* @param head the head for your list.
|
||||
*/
|
||||
#define list_for_each_prev_safe(pos, n, head) \
|
||||
for (pos = (head)->prev, n = pos->prev; \
|
||||
prefetch(pos->prev), pos != (head); \
|
||||
for (pos = (head)->prev, n = pos->prev; \
|
||||
pos != (head); \
|
||||
pos = n, n = pos->prev)
|
||||
|
||||
/**
|
||||
* list_entry_is_head - test if the entry points to the head of the list
|
||||
* @param pos the type * to cursor
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*/
|
||||
#define list_entry_is_head(pos, head, member) \
|
||||
(&pos->member == (head))
|
||||
|
||||
/**
|
||||
* list_for_each_entry - iterate over list of given type
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*/
|
||||
#define list_for_each_entry(pos, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
||||
prefetch(pos->member.next), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
for (pos = list_first_entry(head, typeof(*pos), member); \
|
||||
!list_entry_is_head(pos, head, member); \
|
||||
pos = list_next_entry(pos, member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_reverse - iterate backwards over list of given type.
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*/
|
||||
#define list_for_each_entry_reverse(pos, head, member) \
|
||||
for (pos = list_entry((head)->prev, typeof(*pos), member); \
|
||||
prefetch(pos->member.prev), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.prev, typeof(*pos), member))
|
||||
for (pos = list_last_entry(head, typeof(*pos), member); \
|
||||
!list_entry_is_head(pos, head, member); \
|
||||
pos = list_prev_entry(pos, member))
|
||||
|
||||
/**
|
||||
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
|
||||
* @param pos the type * to use as a start point
|
||||
* @param head the head of the list
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Prepares a pos entry for use as a start point in list_for_each_entry_continue().
|
||||
*/
|
||||
#define list_prepare_entry(pos, head, member) \
|
||||
((pos) ? : list_entry(head, typeof(*pos), member))
|
||||
((pos) ? (pos) : list_entry(head, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_continue - continue iteration over list of given type
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Continue to iterate over list of given type, continuing after
|
||||
* the current position.
|
||||
*/
|
||||
#define list_for_each_entry_continue(pos, head, member) \
|
||||
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
prefetch(pos->member.next), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
#define list_for_each_entry_continue(pos, head, member) \
|
||||
for (pos = list_next_entry(pos, member); \
|
||||
!list_entry_is_head(pos, head, member); \
|
||||
pos = list_next_entry(pos, member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_continue_reverse - iterate backwards from the given point
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Start to iterate over list of given type backwards, continuing after
|
||||
* the current position.
|
||||
*/
|
||||
#define list_for_each_entry_continue_reverse(pos, head, member) \
|
||||
for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
|
||||
prefetch(pos->member.prev), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.prev, typeof(*pos), member))
|
||||
for (pos = list_prev_entry(pos, member); \
|
||||
!list_entry_is_head(pos, head, member); \
|
||||
pos = list_prev_entry(pos, member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_from - iterate over list of given type from the current point
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Iterate over list of given type, continuing from current position.
|
||||
*/
|
||||
#define list_for_each_entry_from(pos, head, member) \
|
||||
for (; prefetch(pos->member.next), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
for (; !list_entry_is_head(pos, head, member); \
|
||||
pos = list_next_entry(pos, member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_from_reverse - iterate backwards over list of given type
|
||||
* from the current point
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Iterate backwards over list of given type, continuing from current position.
|
||||
*/
|
||||
#define list_for_each_entry_from_reverse(pos, head, member) \
|
||||
for (; !list_entry_is_head(pos, head, member); \
|
||||
pos = list_prev_entry(pos, member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param n another type * to use as temporary storage
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*/
|
||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
for (pos = list_first_entry(head, typeof(*pos), member), \
|
||||
n = list_next_entry(pos, member); \
|
||||
!list_entry_is_head(pos, head, member); \
|
||||
pos = n, n = list_next_entry(n, member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_continue - continue list iteration safe against removal
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param n another type * to use as temporary storage
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Iterate over list of given type, continuing after current point,
|
||||
* safe against removal of list entry.
|
||||
*/
|
||||
#define list_for_each_entry_safe_continue(pos, n, head, member) \
|
||||
for (pos = list_entry(pos->member.next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
#define list_for_each_entry_safe_continue(pos, n, head, member) \
|
||||
for (pos = list_next_entry(pos, member), \
|
||||
n = list_next_entry(pos, member); \
|
||||
!list_entry_is_head(pos, head, member); \
|
||||
pos = n, n = list_next_entry(n, member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_from - iterate over list from current point safe against removal
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param n another type * to use as temporary storage
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Iterate over list of given type from current point, safe against
|
||||
* removal of list entry.
|
||||
*/
|
||||
#define list_for_each_entry_safe_from(pos, n, head, member) \
|
||||
for (n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
for (n = list_next_entry(pos, member); \
|
||||
!list_entry_is_head(pos, head, member); \
|
||||
pos = n, n = list_next_entry(n, member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param n another type * to use as temporary storage
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* Iterate backwards over list of given type, safe against removal
|
||||
* of list entry.
|
||||
*/
|
||||
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->prev, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.prev, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
|
||||
for (pos = list_last_entry(head, typeof(*pos), member), \
|
||||
n = list_prev_entry(pos, member); \
|
||||
!list_entry_is_head(pos, head, member); \
|
||||
pos = n, n = list_prev_entry(n, member))
|
||||
|
||||
/**
|
||||
* list_safe_reset_next - reset a stale list_for_each_entry_safe loop
|
||||
* @param pos the loop cursor used in the list_for_each_entry_safe loop
|
||||
* @param n temporary storage used in list_for_each_entry_safe
|
||||
* @param member the name of the list_struct within the struct.
|
||||
* @param member the name of the list_head within the struct.
|
||||
*
|
||||
* list_safe_reset_next is not safe to use in general if the list may be
|
||||
* modified concurrently (eg. the lock is dropped in the loop body). An
|
||||
|
@ -572,7 +793,7 @@ static inline void list_splice_tail_init(struct list_head *list,
|
|||
* completing the current iteration of the loop body.
|
||||
*/
|
||||
#define list_safe_reset_next(pos, n, member) \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member)
|
||||
n = list_next_entry(pos, member)
|
||||
|
||||
/*
|
||||
* Double linked lists with a single pointer list head.
|
||||
|
@ -590,11 +811,25 @@ static inline void INIT_HLIST_NODE(struct hlist_node *h)
|
|||
h->pprev = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_unhashed - Has node been removed from list and reinitialized?
|
||||
* @param h Node to be checked
|
||||
*
|
||||
* Not that not all removal functions will leave a node in unhashed
|
||||
* state. For example, hlist_nulls_del_init_rcu() does leave the
|
||||
* node in unhashed state, but hlist_nulls_del() does not.
|
||||
*/
|
||||
static inline int hlist_unhashed(const struct hlist_node *h)
|
||||
{
|
||||
return !h->pprev;
|
||||
}
|
||||
|
||||
/* Ignore kernel hlist_unhashed_lockless() */
|
||||
|
||||
/**
|
||||
* hlist_empty - Is the specified hlist_head structure an empty hlist?
|
||||
* @param h Structure to check.
|
||||
*/
|
||||
static inline int hlist_empty(const struct hlist_head *h)
|
||||
{
|
||||
return !h->first;
|
||||
|
@ -604,11 +839,19 @@ static inline void __hlist_del(struct hlist_node *n)
|
|||
{
|
||||
struct hlist_node *next = n->next;
|
||||
struct hlist_node **pprev = n->pprev;
|
||||
|
||||
*pprev = next;
|
||||
if (next)
|
||||
next->pprev = pprev;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_del - Delete the specified hlist_node from its list
|
||||
* @param n Node to delete.
|
||||
*
|
||||
* Note that this function leaves the node in hashed state. Use
|
||||
* hlist_del_init() or similar instead to unhash @a n.
|
||||
*/
|
||||
static inline void hlist_del(struct hlist_node *n)
|
||||
{
|
||||
__hlist_del(n);
|
||||
|
@ -616,6 +859,12 @@ static inline void hlist_del(struct hlist_node *n)
|
|||
n->pprev = LIST_POISON2;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_del_init - Delete the specified hlist_node from its list and initialize
|
||||
* @param n Node to delete.
|
||||
*
|
||||
* Note that this function leaves the node in unhashed state.
|
||||
*/
|
||||
static inline void hlist_del_init(struct hlist_node *n)
|
||||
{
|
||||
if (!hlist_unhashed(n)) {
|
||||
|
@ -624,6 +873,14 @@ static inline void hlist_del_init(struct hlist_node *n)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_add_head - add a new entry at the beginning of the hlist
|
||||
* @param n new entry to be added
|
||||
* @param h hlist head to add it after
|
||||
*
|
||||
* Insert a new entry after the specified head.
|
||||
* This is good for implementing stacks.
|
||||
*/
|
||||
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
||||
{
|
||||
struct hlist_node *first = h->first;
|
||||
|
@ -634,9 +891,13 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
|||
n->pprev = &h->first;
|
||||
}
|
||||
|
||||
/* next must be != NULL */
|
||||
/**
|
||||
* hlist_add_before - add a new entry before the one specified
|
||||
* @param n new entry to be added
|
||||
* @param next hlist node to add it before, which must be non-NULL
|
||||
*/
|
||||
static inline void hlist_add_before(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
struct hlist_node *next)
|
||||
{
|
||||
n->pprev = next->pprev;
|
||||
n->next = next;
|
||||
|
@ -644,29 +905,68 @@ static inline void hlist_add_before(struct hlist_node *n,
|
|||
*(n->pprev) = n;
|
||||
}
|
||||
|
||||
static inline void hlist_add_after(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
/**
|
||||
* hlist_add_behind - add a new entry after the one specified
|
||||
* @param n new entry to be added
|
||||
* @param prev hlist node to add it after, which must be non-NULL
|
||||
*/
|
||||
static inline void hlist_add_behind(struct hlist_node *n,
|
||||
struct hlist_node *prev)
|
||||
{
|
||||
next->next = n->next;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
n->next = prev->next;
|
||||
prev->next = n;
|
||||
n->pprev = &prev->next;
|
||||
|
||||
if (next->next)
|
||||
next->next->pprev = &next->next;
|
||||
if (n->next)
|
||||
n->next->pprev = &n->next;
|
||||
}
|
||||
|
||||
/* after that we'll appear to be on some hlist and hlist_del will work */
|
||||
/**
|
||||
* hlist_add_fake - create a fake hlist consisting of a single headless node
|
||||
* @param n Node to make a fake list out of
|
||||
*
|
||||
* This makes @a n appear to be its own predecessor on a headless hlist.
|
||||
* The point of this is to allow things like hlist_del() to work correctly
|
||||
* in cases where there is no list.
|
||||
*/
|
||||
static inline void hlist_add_fake(struct hlist_node *n)
|
||||
{
|
||||
n->pprev = &n->next;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* hlist_fake: Is this node a fake hlist?
|
||||
* @param h Node to check for being a self-referential fake hlist.
|
||||
*/
|
||||
static inline bool hlist_fake(struct hlist_node *h)
|
||||
{
|
||||
return h->pprev == &h->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_is_singular_node - is node the only element of the specified hlist?
|
||||
* @param n Node to check for singularity.
|
||||
* @param h Header for potentially singular list.
|
||||
*
|
||||
* Check whether the node is the only node of the head without
|
||||
* accessing head, thus avoiding unnecessary cache misses.
|
||||
*/
|
||||
static inline bool
|
||||
hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h)
|
||||
{
|
||||
return !n->next && n->pprev == &h->first;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_move_list - Move an hlist
|
||||
* @param old hlist_head for old list.
|
||||
* @param new hlist_head for new list.
|
||||
*
|
||||
* Move a list from one list head to another. Fixup the pprev
|
||||
* reference of the first entry if it exists.
|
||||
*/
|
||||
static inline void hlist_move_list(struct hlist_head *old,
|
||||
struct hlist_head *new)
|
||||
struct hlist_head *new)
|
||||
{
|
||||
new->first = old->first;
|
||||
if (new->first)
|
||||
|
@ -677,61 +977,57 @@ static inline void hlist_move_list(struct hlist_head *old,
|
|||
#define hlist_entry(ptr, type, member) container_of(ptr, type, member)
|
||||
|
||||
#define hlist_for_each(pos, head) \
|
||||
for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
|
||||
pos = pos->next)
|
||||
for (pos = (head)->first; pos ; pos = pos->next)
|
||||
|
||||
#define hlist_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
|
||||
pos = n)
|
||||
|
||||
#define hlist_entry_safe(ptr, type, member) \
|
||||
({ typeof(ptr) ____ptr = (ptr); \
|
||||
____ptr ? hlist_entry(____ptr, type, member) : NULL; \
|
||||
})
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry - iterate over list of given type
|
||||
* @param tpos the type * to use as a loop cursor.
|
||||
* @param pos the &struct hlist_node to use as a loop cursor.
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry(tpos, pos, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ prefetch(pos->next); 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
|
||||
pos = pos->next)
|
||||
#define hlist_for_each_entry(pos, head, member) \
|
||||
for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
|
||||
pos; \
|
||||
pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_continue - iterate over a hlist continuing after current point
|
||||
* @param tpos the type * to use as a loop cursor.
|
||||
* @param pos the &struct hlist_node to use as a loop cursor.
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param member the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_continue(tpos, pos, member) \
|
||||
for (pos = (pos)->next; \
|
||||
pos && ({ prefetch(pos->next); 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
|
||||
pos = pos->next)
|
||||
#define hlist_for_each_entry_continue(pos, member) \
|
||||
for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\
|
||||
pos; \
|
||||
pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_from - iterate over a hlist continuing from current point
|
||||
* @param tpos the type * to use as a loop cursor.
|
||||
* @param pos the &struct hlist_node to use as a loop cursor.
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param member the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_from(tpos, pos, member) \
|
||||
for (; pos && ({ prefetch(pos->next); 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
|
||||
pos = pos->next)
|
||||
#define hlist_for_each_entry_from(pos, member) \
|
||||
for (; pos; \
|
||||
pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||
* @param tpos the type * to use as a loop cursor.
|
||||
* @param pos the &struct hlist_node to use as a loop cursor.
|
||||
* @param n another &struct hlist_node to use as temporary storage
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param n a &struct hlist_node to use as temporary storage
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ n = pos->next; 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
|
||||
pos = n)
|
||||
#define hlist_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\
|
||||
pos && ({ n = pos->member.next; 1; }); \
|
||||
pos = hlist_entry_safe(n, typeof(*pos), member))
|
||||
|
||||
#endif /* OPENOCD_HELPER_LIST_H */
|
||||
|
|
|
@ -518,3 +518,16 @@ void log_socket_error(const char *socket_desc)
|
|||
LOG_ERROR("Error on socket '%s': errno==%d, message: %s.", socket_desc, error_code, strerror(error_code));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first non-printable character in the char buffer, return a pointer to it.
|
||||
* If no such character exists, return NULL.
|
||||
*/
|
||||
char *find_nonprint_char(char *buf, unsigned buf_len)
|
||||
{
|
||||
for (unsigned int i = 0; i < buf_len; i++) {
|
||||
if (!isprint(buf[i]))
|
||||
return buf + i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,8 @@ char *alloc_vprintf(const char *fmt, va_list ap);
|
|||
char *alloc_printf(const char *fmt, ...)
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 2)));
|
||||
|
||||
char *find_nonprint_char(char *buf, unsigned buf_len);
|
||||
|
||||
extern int debug_level;
|
||||
|
||||
/* Avoid fn call and building parameter list if we're not outputting the information.
|
||||
|
|
|
@ -46,7 +46,7 @@ struct duration {
|
|||
|
||||
/** Update the duration->start field to start the @a duration measurement. */
|
||||
int duration_start(struct duration *duration);
|
||||
/** Update the duration->elapsed field to finish the @a duration measurment. */
|
||||
/** Update the duration->elapsed field to finish the @a duration measurement. */
|
||||
int duration_measure(struct duration *duration);
|
||||
|
||||
/** @returns Elapsed time in seconds. */
|
||||
|
|
|
@ -47,8 +47,8 @@ const char * const jtag_only[] = { "jtag", NULL };
|
|||
|
||||
static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc-1, argv + 1);
|
||||
|
||||
/* return the name of the interface */
|
||||
/* TCL code might need to know the exact type... */
|
||||
|
@ -58,7 +58,7 @@ static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
|||
return JIM_ERR;
|
||||
}
|
||||
const char *name = adapter_driver ? adapter_driver->name : NULL;
|
||||
Jim_SetResultString(goi.interp, name ? : "undefined", -1);
|
||||
Jim_SetResultString(goi.interp, name ? name : "undefined", -1);
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
|
@ -580,7 +580,7 @@ static const struct command_registration adapter_command_handlers[] = {
|
|||
.handler = adapter_transports_command,
|
||||
.mode = COMMAND_CONFIG,
|
||||
.help = "Declare transports the adapter supports.",
|
||||
.usage = "transport ... ",
|
||||
.usage = "transport ...",
|
||||
},
|
||||
{
|
||||
.name = "usb",
|
||||
|
|
|
@ -436,7 +436,7 @@ static const struct command_registration aice_subcommand_handlers[] = {
|
|||
.handler = &aice_handle_aice_desc_command,
|
||||
.mode = COMMAND_CONFIG,
|
||||
.help = "set the aice device description",
|
||||
.usage = "[desciption string]",
|
||||
.usage = "[description string]",
|
||||
},
|
||||
{
|
||||
.name = "serial",
|
||||
|
|
|
@ -30,11 +30,11 @@
|
|||
#include <string.h>
|
||||
|
||||
/* */
|
||||
static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
|
||||
static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi,
|
||||
struct jtag_tap *pTap)
|
||||
{
|
||||
jim_wide w;
|
||||
int e = Jim_GetOpt_Wide(goi, &w);
|
||||
int e = jim_getopt_wide(goi, &w);
|
||||
if (e != JIM_OK) {
|
||||
Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
|
||||
n->name);
|
||||
|
@ -63,14 +63,14 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
|
|||
#define NTAP_OPT_EXPECTED_ID 0
|
||||
|
||||
/* */
|
||||
static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi)
|
||||
static int jim_aice_newtap_cmd(struct jim_getopt_info *goi)
|
||||
{
|
||||
struct jtag_tap *pTap;
|
||||
int x;
|
||||
int e;
|
||||
Jim_Nvp *n;
|
||||
struct jim_nvp *n;
|
||||
char *cp;
|
||||
const Jim_Nvp opts[] = {
|
||||
const struct jim_nvp opts[] = {
|
||||
{.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID},
|
||||
{.name = NULL, .value = -1},
|
||||
};
|
||||
|
@ -92,10 +92,10 @@ static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi)
|
|||
}
|
||||
|
||||
const char *tmp;
|
||||
Jim_GetOpt_String(goi, &tmp, NULL);
|
||||
jim_getopt_string(goi, &tmp, NULL);
|
||||
pTap->chip = strdup(tmp);
|
||||
|
||||
Jim_GetOpt_String(goi, &tmp, NULL);
|
||||
jim_getopt_string(goi, &tmp, NULL);
|
||||
pTap->tapname = strdup(tmp);
|
||||
|
||||
/* name + dot + name + null */
|
||||
|
@ -108,9 +108,9 @@ static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi)
|
|||
pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);
|
||||
|
||||
while (goi->argc) {
|
||||
e = Jim_GetOpt_Nvp(goi, opts, &n);
|
||||
e = jim_getopt_nvp(goi, opts, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(goi, opts, 0);
|
||||
jim_getopt_nvp_unknown(goi, opts, 0);
|
||||
free(cp);
|
||||
free(pTap);
|
||||
return e;
|
||||
|
@ -138,8 +138,8 @@ static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi)
|
|||
/* */
|
||||
static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
return jim_aice_newtap_cmd(&goi);
|
||||
}
|
||||
|
||||
|
@ -246,8 +246,8 @@ static int aice_init_reset(struct command_context *cmd_ctx)
|
|||
static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
||||
{
|
||||
int e = ERROR_OK;
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
if (goi.argc != 0) {
|
||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv - 1, "(no params)");
|
||||
return JIM_ERR;
|
||||
|
@ -265,8 +265,8 @@ static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const
|
|||
|
||||
static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
if (goi.argc != 0) {
|
||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
|
||||
return JIM_ERR;
|
||||
|
|
|
@ -2628,7 +2628,7 @@ static int aice_usb_halt(uint32_t coreid)
|
|||
|
||||
if (core_info[coreid].debug_under_dex_on) {
|
||||
if (core_info[coreid].dex_use_psw_on == false) {
|
||||
/* under debug 'debug mode', force $psw to 'debug mode' bahavior */
|
||||
/* under debug 'debug mode', force $psw to 'debug mode' behavior */
|
||||
/* !!!NOTICE!!! this is workaround for debug 'debug mode'.
|
||||
* it is only for debugging 'debug exception handler' purpose.
|
||||
* after openocd detaches from target, target behavior is
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
#include "svf/svf.h"
|
||||
#include "xsvf/xsvf.h"
|
||||
|
||||
/* ipdbg are utilities to debug IP-cores. It uses JTAG for transport. */
|
||||
#include "server/ipdbg.h"
|
||||
|
||||
/** The number of JTAG queue flushes (for profiling and debugging purposes). */
|
||||
static int jtag_flush_queue_count;
|
||||
|
||||
|
@ -487,7 +490,7 @@ void jtag_add_tlr(void)
|
|||
|
||||
/**
|
||||
* If supported by the underlying adapter, this clocks a raw bit sequence
|
||||
* onto TMS for switching betwen JTAG and SWD modes.
|
||||
* onto TMS for switching between JTAG and SWD modes.
|
||||
*
|
||||
* DO NOT use this to bypass the integrity checks and logging provided
|
||||
* by the jtag_add_pathmove() and jtag_add_statemove() calls.
|
||||
|
@ -1340,7 +1343,7 @@ static int jtag_validate_ircapture(void)
|
|||
int chain_pos = 0;
|
||||
int retval;
|
||||
|
||||
/* when autoprobing, accomodate huge IR lengths */
|
||||
/* when autoprobing, accommodate huge IR lengths */
|
||||
for (tap = NULL, total_ir_length = 0;
|
||||
(tap = jtag_tap_next_enabled(tap)) != NULL;
|
||||
total_ir_length += tap->ir_length) {
|
||||
|
@ -1452,7 +1455,7 @@ void jtag_tap_init(struct jtag_tap *tap)
|
|||
unsigned ir_len_bytes;
|
||||
|
||||
/* if we're autoprobing, cope with potentially huge ir_length */
|
||||
ir_len_bits = tap->ir_length ? : JTAG_IRLEN_MAX;
|
||||
ir_len_bits = tap->ir_length ? tap->ir_length : JTAG_IRLEN_MAX;
|
||||
ir_len_bytes = DIV_ROUND_UP(ir_len_bits, 8);
|
||||
|
||||
tap->expected = calloc(1, ir_len_bytes);
|
||||
|
@ -1975,7 +1978,12 @@ static int jtag_select(struct command_context *ctx)
|
|||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return xsvf_register_commands(ctx);
|
||||
retval = xsvf_register_commands(ctx);
|
||||
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return ipdbg_register_commands(ctx);
|
||||
}
|
||||
|
||||
static struct transport jtag_transport = {
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2021 by Adrian Negreanu *
|
||||
* groleo@gmail.com *
|
||||
* *
|
||||
* Copyright (C) 2018 by Mickaël Thomas *
|
||||
* mickael9@gmail.com *
|
||||
* *
|
||||
|
@ -41,6 +44,7 @@
|
|||
#include <jtag/interface.h>
|
||||
#include <jtag/commands.h>
|
||||
#include <jtag/tcl.h>
|
||||
#include <target/cortex_m.h>
|
||||
|
||||
#include "cmsis_dap.h"
|
||||
|
||||
|
@ -96,9 +100,12 @@ static bool swd_mode;
|
|||
#define INFO_ID_CAPS 0xf0 /* byte */
|
||||
#define INFO_ID_PKT_CNT 0xfe /* byte */
|
||||
#define INFO_ID_PKT_SZ 0xff /* short */
|
||||
#define INFO_ID_SWO_BUF_SZ 0xfd /* word */
|
||||
|
||||
#define INFO_CAPS_SWD 0x01
|
||||
#define INFO_CAPS_JTAG 0x02
|
||||
#define INFO_CAPS_SWD BIT(0)
|
||||
#define INFO_CAPS_JTAG BIT(1)
|
||||
#define INFO_CAPS_SWO_UART BIT(2)
|
||||
#define INFO_CAPS_SWO_MANCHESTER BIT(3)
|
||||
|
||||
/* CMD_LED */
|
||||
#define LED_ID_CONNECT 0x00
|
||||
|
@ -163,12 +170,44 @@ static bool swd_mode;
|
|||
#define DAP_OK 0
|
||||
#define DAP_ERROR 0xFF
|
||||
|
||||
/* CMSIS-DAP SWO Commands */
|
||||
#define CMD_DAP_SWO_TRANSPORT 0x17
|
||||
#define CMD_DAP_SWO_MODE 0x18
|
||||
#define CMD_DAP_SWO_BAUDRATE 0x19
|
||||
#define CMD_DAP_SWO_CONTROL 0x1A
|
||||
#define CMD_DAP_SWO_STATUS 0x1B
|
||||
#define CMD_DAP_SWO_DATA 0x1C
|
||||
#define CMD_DAP_SWO_EX_STATUS 0x1E
|
||||
|
||||
/* SWO transport mode for reading trace data */
|
||||
#define DAP_SWO_TRANSPORT_NONE 0
|
||||
#define DAP_SWO_TRANSPORT_DATA 1
|
||||
#define DAP_SWO_TRANSPORT_WINUSB 2
|
||||
|
||||
/* SWO trace capture mode */
|
||||
#define DAP_SWO_MODE_OFF 0
|
||||
#define DAP_SWO_MODE_UART 1
|
||||
#define DAP_SWO_MODE_MANCHESTER 2
|
||||
|
||||
/* SWO trace data capture */
|
||||
#define DAP_SWO_CONTROL_STOP 0
|
||||
#define DAP_SWO_CONTROL_START 1
|
||||
|
||||
/* SWO trace status */
|
||||
#define DAP_SWO_STATUS_CAPTURE_INACTIVE 0
|
||||
#define DAP_SWO_STATUS_CAPTURE_ACTIVE 1
|
||||
#define DAP_SWO_STATUS_CAPTURE_MASK BIT(0)
|
||||
#define DAP_SWO_STATUS_STREAM_ERROR_MASK BIT(6)
|
||||
#define DAP_SWO_STATUS_BUFFER_OVERRUN_MASK BIT(7)
|
||||
|
||||
/* CMSIS-DAP Vendor Commands
|
||||
* None as yet... */
|
||||
|
||||
static const char * const info_caps_str[] = {
|
||||
"SWD Supported",
|
||||
"JTAG Supported"
|
||||
"JTAG Supported",
|
||||
"SWO-UART Supported",
|
||||
"SWO-MANCHESTER Supported"
|
||||
};
|
||||
|
||||
struct pending_transfer_result {
|
||||
|
@ -338,9 +377,8 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay, uint8_t *input)
|
||||
static int cmsis_dap_cmd_dap_swj_pins(uint8_t pins, uint8_t mask, uint32_t delay, uint8_t *input)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_SWJ_PINS;
|
||||
|
@ -348,8 +386,7 @@ static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay
|
|||
command[2] = mask;
|
||||
h_u32_to_le(&command[3], delay);
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 7);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 7);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_PINS failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
|
@ -361,9 +398,8 @@ static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock)
|
||||
static int cmsis_dap_cmd_dap_swj_clock(uint32_t swj_clock)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
/* set clock in Hz */
|
||||
|
@ -372,8 +408,7 @@ static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock)
|
|||
command[0] = CMD_DAP_SWJ_CLOCK;
|
||||
h_u32_to_le(&command[1], swj_clock);
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 5);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 5);
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_CLOCK failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
|
@ -383,9 +418,8 @@ static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock)
|
|||
}
|
||||
|
||||
/* clock a sequence of bits out on TMS, to change JTAG states */
|
||||
static int cmsis_dap_cmd_DAP_SWJ_Sequence(uint8_t s_len, const uint8_t *sequence)
|
||||
static int cmsis_dap_cmd_dap_swj_sequence(uint8_t s_len, const uint8_t *sequence)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
#ifdef CMSIS_DAP_JTAG_DEBUG
|
||||
|
@ -400,23 +434,21 @@ static int cmsis_dap_cmd_DAP_SWJ_Sequence(uint8_t s_len, const uint8_t *sequence
|
|||
command[1] = s_len;
|
||||
bit_copy(&command[2], 0, sequence, 0, s_len);
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 2 + DIV_ROUND_UP(s_len, 8));
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 2 + DIV_ROUND_UP(s_len, 8));
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK)
|
||||
return ERROR_FAIL;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_cmd_DAP_Info(uint8_t info, uint8_t **data)
|
||||
static int cmsis_dap_cmd_dap_info(uint8_t info, uint8_t **data)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_INFO;
|
||||
command[1] = info;
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 2);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 2);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command CMD_INFO failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
|
@ -427,17 +459,15 @@ static int cmsis_dap_cmd_DAP_Info(uint8_t info, uint8_t **data)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_cmd_DAP_LED(uint8_t led, uint8_t state)
|
||||
static int cmsis_dap_cmd_dap_led(uint8_t led, uint8_t state)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_LED;
|
||||
command[1] = led;
|
||||
command[2] = state;
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 3);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 3);
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command CMD_LED failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
|
@ -446,16 +476,14 @@ static int cmsis_dap_cmd_DAP_LED(uint8_t led, uint8_t state)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_cmd_DAP_Connect(uint8_t mode)
|
||||
static int cmsis_dap_cmd_dap_connect(uint8_t mode)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_CONNECT;
|
||||
command[1] = mode;
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 2);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 2);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command CMD_CONNECT failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
|
@ -469,15 +497,13 @@ static int cmsis_dap_cmd_DAP_Connect(uint8_t mode)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_cmd_DAP_Disconnect(void)
|
||||
static int cmsis_dap_cmd_dap_disconnect(void)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_DISCONNECT;
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 1);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 1);
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command CMD_DISCONNECT failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
|
@ -486,9 +512,8 @@ static int cmsis_dap_cmd_DAP_Disconnect(void)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t retry_count, uint16_t match_retry)
|
||||
static int cmsis_dap_cmd_dap_tfer_configure(uint8_t idle, uint16_t retry_count, uint16_t match_retry)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_TFER_CONFIGURE;
|
||||
|
@ -496,8 +521,7 @@ static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t retry_count,
|
|||
h_u16_to_le(&command[2], retry_count);
|
||||
h_u16_to_le(&command[4], match_retry);
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 6);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 6);
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command CMD_TFER_Configure failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
|
@ -506,16 +530,14 @@ static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t retry_count,
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_cmd_DAP_SWD_Configure(uint8_t cfg)
|
||||
static int cmsis_dap_cmd_dap_swd_configure(uint8_t cfg)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_SWD_CONFIGURE;
|
||||
command[1] = cfg;
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 2);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 2);
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command CMD_SWD_Configure failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
|
@ -525,16 +547,14 @@ static int cmsis_dap_cmd_DAP_SWD_Configure(uint8_t cfg)
|
|||
}
|
||||
|
||||
#if 0
|
||||
static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us)
|
||||
static int cmsis_dap_cmd_dap_delay(uint16_t delay_us)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_DELAY;
|
||||
h_u16_to_le(&command[1], delay_us);
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, 3);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 3);
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command CMD_Delay failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
|
@ -546,7 +566,6 @@ static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us)
|
|||
|
||||
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;
|
||||
|
||||
|
@ -574,12 +593,171 @@ static int cmsis_dap_metacmd_targetsel(uint32_t instance_id)
|
|||
idx += 4;
|
||||
command[idx++] = parity_u32(instance_id);
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, idx);
|
||||
|
||||
int 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SWO transport mode.
|
||||
* @param[in] transport The transport mode. Can be None, SWO_Data or
|
||||
* WinUSB (requires CMSIS-DAP v2).
|
||||
*/
|
||||
static int cmsis_dap_cmd_dap_swo_transport(uint8_t transport)
|
||||
{
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_SWO_TRANSPORT;
|
||||
command[1] = transport;
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 2);
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
|
||||
LOG_ERROR("CMSIS-DAP: command CMD_SWO_Transport(%d) failed.", transport);
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SWO trace capture mode.
|
||||
* @param[in] mode Trace capture mode. Can be UART or MANCHESTER.
|
||||
*/
|
||||
static int cmsis_dap_cmd_dap_swo_mode(uint8_t mode)
|
||||
{
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_SWO_MODE;
|
||||
command[1] = mode;
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 2);
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
|
||||
LOG_ERROR("CMSIS-DAP: command CMD_SWO_Mode(%d) failed.", mode);
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the baudrate for capturing SWO trace data.
|
||||
* Can be called iteratively to determine supported baudrates.
|
||||
* @param[in] in_baudrate Requested baudrate.
|
||||
* @param[out] dev_baudrate Actual baudrate or 0 (baudrate not configured).
|
||||
* When requested baudrate is not achievable the
|
||||
* closest configured baudrate can be returned or
|
||||
* 0 which indicates that baudrate was not configured.
|
||||
*/
|
||||
static int cmsis_dap_cmd_dap_swo_baudrate(
|
||||
uint32_t in_baudrate,
|
||||
uint32_t *dev_baudrate)
|
||||
{
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_SWO_BAUDRATE;
|
||||
h_u32_to_le(&command[1], in_baudrate);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 4);
|
||||
uint32_t rvbr = le_to_h_u32(&cmsis_dap_handle->response[1]);
|
||||
if (retval != ERROR_OK || rvbr == 0) {
|
||||
LOG_ERROR("CMSIS-DAP: command CMD_SWO_Baudrate(%u) -> %u failed.", in_baudrate, rvbr);
|
||||
if (dev_baudrate)
|
||||
*dev_baudrate = 0;
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (dev_baudrate)
|
||||
*dev_baudrate = rvbr;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls the SWO trace data capture.
|
||||
* @param[in] control Start or stop a trace. Starting capture automatically
|
||||
* flushes any existing trace data in buffers which has
|
||||
* not yet been read.
|
||||
*/
|
||||
static int cmsis_dap_cmd_dap_swo_control(uint8_t control)
|
||||
{
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_SWO_CONTROL;
|
||||
command[1] = control;
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 2);
|
||||
if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {
|
||||
LOG_ERROR("CMSIS-DAP: command CMD_SWO_Control(%d) failed.", control);
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the SWO trace status.
|
||||
* @param[out] trace_status The trace's status.
|
||||
* Bit0: Trace Capture (1 - active, 0 - inactive).
|
||||
* Bit6: Trace Stream Error.
|
||||
* Bit7: Trace Buffer Overrun.
|
||||
* @param[out] trace_count Number of bytes in Trace Buffer (not yet read).
|
||||
*/
|
||||
static int cmsis_dap_cmd_dap_swo_status(
|
||||
uint8_t *trace_status,
|
||||
size_t *trace_count)
|
||||
{
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_SWO_STATUS;
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 1);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("CMSIS-DAP: command CMD_SWO_Status failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (trace_status)
|
||||
*trace_status = cmsis_dap_handle->response[1];
|
||||
if (trace_count)
|
||||
*trace_count = le_to_h_u32(&cmsis_dap_handle->response[2]);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the captured SWO trace data from Trace Buffer.
|
||||
* @param[in] max_trace_count Maximum number of Trace Data bytes to read.
|
||||
* @param[out] trace_status The trace's status.
|
||||
* @param[out] trace_count Number of Trace Data bytes read.
|
||||
* @param[out] data Trace Data bytes read.
|
||||
*/
|
||||
static int cmsis_dap_cmd_dap_swo_data(
|
||||
size_t max_trace_count,
|
||||
uint8_t *trace_status,
|
||||
size_t *trace_count,
|
||||
uint8_t *data)
|
||||
{
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
command[0] = CMD_DAP_SWO_DATA;
|
||||
h_u16_to_le(&command[1], max_trace_count);
|
||||
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, 3);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("CMSIS-DAP: command CMD_SWO_Data failed.");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
*trace_status = cmsis_dap_handle->response[1];
|
||||
*trace_count = le_to_h_u16(&cmsis_dap_handle->response[2]);
|
||||
|
||||
if (*trace_count > 0)
|
||||
memcpy(data, &cmsis_dap_handle->response[4], *trace_count);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -620,8 +798,8 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
|
|||
* able to automatically retry anything (because ARM
|
||||
* has forgotten to implement sticky error flags
|
||||
* clearing). See also comments regarding
|
||||
* cmsis_dap_cmd_DAP_TFER_Configure() and
|
||||
* cmsis_dap_cmd_DAP_SWD_Configure() in
|
||||
* cmsis_dap_cmd_dap_tfer_configure() and
|
||||
* cmsis_dap_cmd_dap_swd_configure() in
|
||||
* cmsis_dap_init().
|
||||
*/
|
||||
if (!(cmd & SWD_CMD_RnW) &&
|
||||
|
@ -640,7 +818,6 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
|
|||
}
|
||||
|
||||
int retval = dap->backend->write(dap, idx, USB_TIMEOUT);
|
||||
|
||||
if (retval < 0) {
|
||||
queued_retval = retval;
|
||||
goto skip;
|
||||
|
@ -679,8 +856,8 @@ 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]);
|
||||
LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%x received 0x%" PRIx8,
|
||||
CMD_DAP_TFER, resp[0]);
|
||||
queued_retval = ERROR_FAIL;
|
||||
goto skip;
|
||||
}
|
||||
|
@ -805,7 +982,7 @@ static int cmsis_dap_get_serial_info(void)
|
|||
{
|
||||
uint8_t *data;
|
||||
|
||||
int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_SERNUM, &data);
|
||||
int retval = cmsis_dap_cmd_dap_info(INFO_ID_SERNUM, &data);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
|
@ -820,7 +997,7 @@ static int cmsis_dap_get_version_info(void)
|
|||
uint8_t *data;
|
||||
|
||||
/* INFO_ID_FW_VER - string */
|
||||
int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_FW_VER, &data);
|
||||
int retval = cmsis_dap_cmd_dap_info(INFO_ID_FW_VER, &data);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
|
@ -835,7 +1012,7 @@ static int cmsis_dap_get_caps_info(void)
|
|||
uint8_t *data;
|
||||
|
||||
/* INFO_ID_CAPS - byte */
|
||||
int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_CAPS, &data);
|
||||
int retval = cmsis_dap_cmd_dap_info(INFO_ID_CAPS, &data);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
|
@ -848,16 +1025,39 @@ static int cmsis_dap_get_caps_info(void)
|
|||
LOG_INFO("CMSIS-DAP: %s", info_caps_str[0]);
|
||||
if (caps & INFO_CAPS_JTAG)
|
||||
LOG_INFO("CMSIS-DAP: %s", info_caps_str[1]);
|
||||
if (caps & INFO_CAPS_SWO_UART)
|
||||
LOG_INFO("CMSIS-DAP: %s", info_caps_str[2]);
|
||||
if (caps & INFO_CAPS_SWO_MANCHESTER)
|
||||
LOG_INFO("CMSIS-DAP: %s", info_caps_str[3]);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_get_swo_buf_sz(uint32_t *swo_buf_sz)
|
||||
{
|
||||
uint8_t *data;
|
||||
|
||||
/* INFO_ID_SWO_BUF_SZ - word */
|
||||
int retval = cmsis_dap_cmd_dap_info(INFO_ID_SWO_BUF_SZ, &data);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
if (data[0] != 4)
|
||||
return ERROR_FAIL;
|
||||
|
||||
*swo_buf_sz = le_to_h_u32(&data[1]);
|
||||
|
||||
LOG_INFO("CMSIS-DAP: SWO Trace Buffer Size = %u bytes", *swo_buf_sz);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cmsis_dap_get_status(void)
|
||||
{
|
||||
uint8_t d;
|
||||
|
||||
int retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, 0, 0, &d);
|
||||
int retval = cmsis_dap_cmd_dap_swj_pins(0, 0, 0, &d);
|
||||
|
||||
if (retval == ERROR_OK) {
|
||||
LOG_INFO("SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d",
|
||||
|
@ -884,11 +1084,11 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
|
|||
* Reconnecting would break connecting under reset. */
|
||||
|
||||
/* First disconnect before connecting, Atmel EDBG needs it for SAMD/R/L/C */
|
||||
cmsis_dap_cmd_DAP_Disconnect();
|
||||
cmsis_dap_cmd_dap_disconnect();
|
||||
|
||||
/* When we are reconnecting, DAP_Connect needs to be rerun, at
|
||||
* least on Keil ULINK-ME */
|
||||
retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD);
|
||||
retval = cmsis_dap_cmd_dap_connect(CONNECT_SWD);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
|
@ -929,25 +1129,23 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
|
|||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
retval = cmsis_dap_cmd_DAP_SWJ_Sequence(s_len, s);
|
||||
retval = cmsis_dap_cmd_dap_swj_sequence(s_len, s);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
/* Atmel EDBG needs renew clock setting after SWJ_Sequence
|
||||
* otherwise default frequency is used */
|
||||
return cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz());
|
||||
return cmsis_dap_cmd_dap_swj_clock(jtag_get_speed_khz());
|
||||
}
|
||||
|
||||
static int cmsis_dap_swd_open(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) {
|
||||
LOG_ERROR("CMSIS-DAP: SWD not supported");
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD);
|
||||
int retval = cmsis_dap_cmd_dap_connect(CONNECT_SWD);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
|
@ -959,10 +1157,9 @@ static int cmsis_dap_swd_open(void)
|
|||
|
||||
static int cmsis_dap_init(void)
|
||||
{
|
||||
int retval;
|
||||
uint8_t *data;
|
||||
|
||||
retval = cmsis_dap_open();
|
||||
int retval = cmsis_dap_open();
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
|
@ -991,7 +1188,7 @@ static int cmsis_dap_init(void)
|
|||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
retval = cmsis_dap_cmd_DAP_Connect(CONNECT_JTAG);
|
||||
retval = cmsis_dap_cmd_dap_connect(CONNECT_JTAG);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
|
@ -1004,7 +1201,7 @@ static int cmsis_dap_init(void)
|
|||
pending_queue_len = 12;
|
||||
|
||||
/* INFO_ID_PKT_SZ - short */
|
||||
retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_SZ, &data);
|
||||
retval = cmsis_dap_cmd_dap_info(INFO_ID_PKT_SZ, &data);
|
||||
if (retval != ERROR_OK)
|
||||
goto init_err;
|
||||
|
||||
|
@ -1027,7 +1224,7 @@ static int cmsis_dap_init(void)
|
|||
}
|
||||
|
||||
/* INFO_ID_PKT_CNT - byte */
|
||||
retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_CNT, &data);
|
||||
retval = cmsis_dap_cmd_dap_info(INFO_ID_PKT_CNT, &data);
|
||||
if (retval != ERROR_OK)
|
||||
goto init_err;
|
||||
|
||||
|
@ -1055,36 +1252,36 @@ static int cmsis_dap_init(void)
|
|||
|
||||
/* 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());
|
||||
retval = cmsis_dap_cmd_dap_swj_clock(jtag_get_speed_khz());
|
||||
if (retval != ERROR_OK)
|
||||
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);
|
||||
retval = cmsis_dap_cmd_dap_tfer_configure(0, 64, 0);
|
||||
if (retval != ERROR_OK)
|
||||
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 */
|
||||
retval = cmsis_dap_cmd_dap_swd_configure(0); /* 1 TRN, no Data Phase */
|
||||
if (retval != ERROR_OK)
|
||||
goto init_err;
|
||||
}
|
||||
/* Both LEDs on */
|
||||
/* 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);
|
||||
(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();
|
||||
|
||||
if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
|
||||
if (jtag_reset_config & RESET_SRST_NO_GATING) {
|
||||
retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, SWJ_PIN_SRST, 0, NULL);
|
||||
retval = cmsis_dap_cmd_dap_swj_pins(0, SWJ_PIN_SRST, 0, NULL);
|
||||
if (retval != ERROR_OK)
|
||||
goto init_err;
|
||||
LOG_INFO("Connecting under reset");
|
||||
|
@ -1106,10 +1303,11 @@ static int cmsis_dap_swd_init(void)
|
|||
|
||||
static int cmsis_dap_quit(void)
|
||||
{
|
||||
cmsis_dap_cmd_DAP_Disconnect();
|
||||
cmsis_dap_cmd_dap_disconnect();
|
||||
|
||||
/* Both LEDs off */
|
||||
cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_OFF);
|
||||
cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_OFF);
|
||||
cmsis_dap_cmd_dap_led(LED_ID_RUN, LED_OFF);
|
||||
cmsis_dap_cmd_dap_led(LED_ID_CONNECT, LED_OFF);
|
||||
|
||||
cmsis_dap_close(cmsis_dap_handle);
|
||||
|
||||
|
@ -1127,7 +1325,7 @@ static int cmsis_dap_reset(int trst, int srst)
|
|||
if (!trst)
|
||||
output_pins |= SWJ_PIN_TRST;
|
||||
|
||||
int retval = cmsis_dap_cmd_DAP_SWJ_Pins(output_pins,
|
||||
int retval = cmsis_dap_cmd_dap_swj_pins(output_pins,
|
||||
SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL);
|
||||
if (retval != ERROR_OK)
|
||||
LOG_ERROR("CMSIS-DAP: Interface reset failed");
|
||||
|
@ -1137,7 +1335,7 @@ static int cmsis_dap_reset(int trst, int srst)
|
|||
static void cmsis_dap_execute_sleep(struct jtag_command *cmd)
|
||||
{
|
||||
#if 0
|
||||
int retval = cmsis_dap_cmd_DAP_Delay(cmd->cmd.sleep->us);
|
||||
int retval = cmsis_dap_cmd_dap_delay(cmd->cmd.sleep->us);
|
||||
if (retval != ERROR_OK)
|
||||
#endif
|
||||
jtag_sleep(cmd->cmd.sleep->us);
|
||||
|
@ -1148,10 +1346,11 @@ static int cmsis_dap_execute_tlr_reset(struct jtag_command *cmd)
|
|||
{
|
||||
LOG_INFO("cmsis-dap JTAG TLR_RESET");
|
||||
uint8_t seq = 0xff;
|
||||
int ret = cmsis_dap_cmd_DAP_SWJ_Sequence(8, &seq);
|
||||
if (ret == ERROR_OK)
|
||||
|
||||
int retval = cmsis_dap_cmd_dap_swj_sequence(8, &seq);
|
||||
if (retval == ERROR_OK)
|
||||
tap_set_state(TAP_RESET);
|
||||
return ret;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Set new end state */
|
||||
|
@ -1369,11 +1568,8 @@ static void cmsis_dap_add_tms_sequence(const uint8_t *sequence, int s_len)
|
|||
/* Move to the end state by queuing a sequence to clock into TMS */
|
||||
static void cmsis_dap_state_move(void)
|
||||
{
|
||||
uint8_t tms_scan;
|
||||
uint8_t tms_scan_bits;
|
||||
|
||||
tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
|
||||
tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
|
||||
uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
|
||||
uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
|
||||
|
||||
LOG_DEBUG_IO("state move from %s to %s: %d clocks, %02X on tms",
|
||||
tap_state_name(tap_get_state()), tap_state_name(tap_get_end_state()),
|
||||
|
@ -1488,11 +1684,10 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd)
|
|||
|
||||
static void cmsis_dap_pathmove(int num_states, tap_state_t *path)
|
||||
{
|
||||
int i;
|
||||
uint8_t tms0 = 0x00;
|
||||
uint8_t tms1 = 0xff;
|
||||
|
||||
for (i = 0; i < num_states; i++) {
|
||||
for (int i = 0; i < num_states; i++) {
|
||||
if (path[i] == tap_state_transition(tap_get_state(), false))
|
||||
cmsis_dap_add_tms_sequence(&tms0, 1);
|
||||
else if (path[i] == tap_state_transition(tap_get_state(), true))
|
||||
|
@ -1520,12 +1715,10 @@ static void cmsis_dap_execute_pathmove(struct jtag_command *cmd)
|
|||
|
||||
static void cmsis_dap_stableclocks(int num_cycles)
|
||||
{
|
||||
int i;
|
||||
|
||||
uint8_t tms = tap_get_state() == TAP_RESET;
|
||||
/* TODO: Perform optimizations? */
|
||||
/* Execute num_cycles. */
|
||||
for (i = 0; i < num_cycles; i++)
|
||||
for (int i = 0; i < num_cycles; i++)
|
||||
cmsis_dap_add_tms_sequence(&tms, 1);
|
||||
}
|
||||
|
||||
|
@ -1565,7 +1758,7 @@ static void cmsis_dap_execute_stableclocks(struct jtag_command *cmd)
|
|||
static void cmsis_dap_execute_tms(struct jtag_command *cmd)
|
||||
{
|
||||
LOG_DEBUG_IO("TMS: %d bits", cmd->cmd.tms->num_bits);
|
||||
cmsis_dap_cmd_DAP_SWJ_Sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
|
||||
cmsis_dap_cmd_dap_swj_sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
|
||||
}
|
||||
|
||||
/* TODO: Is there need to call cmsis_dap_flush() for the JTAG_PATHMOVE,
|
||||
|
@ -1623,7 +1816,7 @@ static int cmsis_dap_speed(int speed)
|
|||
return ERROR_JTAG_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return cmsis_dap_cmd_DAP_SWJ_Clock(speed);
|
||||
return cmsis_dap_cmd_dap_swj_clock(speed);
|
||||
}
|
||||
|
||||
static int cmsis_dap_speed_div(int speed, int *khz)
|
||||
|
@ -1638,6 +1831,157 @@ static int cmsis_dap_khz(int khz, int *jtag_speed)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static bool calculate_swo_prescaler(unsigned int traceclkin_freq,
|
||||
uint32_t trace_freq, uint16_t *prescaler)
|
||||
{
|
||||
unsigned int presc = (traceclkin_freq + trace_freq / 2) / trace_freq;
|
||||
if (presc == 0 || presc > TPIU_ACPR_MAX_SWOSCALER + 1)
|
||||
return false;
|
||||
|
||||
/* Probe's UART speed must be within 3% of the TPIU's SWO baud rate. */
|
||||
unsigned int max_deviation = (traceclkin_freq * 3) / 100;
|
||||
if (presc * trace_freq < traceclkin_freq - max_deviation ||
|
||||
presc * trace_freq > traceclkin_freq + max_deviation)
|
||||
return false;
|
||||
|
||||
*prescaler = presc;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see adapter_driver::config_trace
|
||||
*/
|
||||
static int cmsis_dap_config_trace(
|
||||
bool trace_enabled,
|
||||
enum tpiu_pin_protocol pin_protocol,
|
||||
uint32_t port_size,
|
||||
unsigned int *swo_freq,
|
||||
unsigned int traceclkin_hz,
|
||||
uint16_t *swo_prescaler)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!trace_enabled) {
|
||||
if (cmsis_dap_handle->trace_enabled) {
|
||||
retval = cmsis_dap_cmd_dap_swo_control(DAP_SWO_CONTROL_STOP);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("Failed to disable the SWO-trace.");
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
cmsis_dap_handle->trace_enabled = false;
|
||||
LOG_INFO("SWO-trace disabled.");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
if (!(cmsis_dap_handle->caps & INFO_CAPS_SWO_UART) &&
|
||||
!(cmsis_dap_handle->caps & INFO_CAPS_SWO_MANCHESTER)) {
|
||||
LOG_ERROR("SWO-trace is not supported by the device.");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
uint8_t swo_mode;
|
||||
if (pin_protocol == TPIU_PIN_PROTOCOL_ASYNC_UART &&
|
||||
(cmsis_dap_handle->caps & INFO_CAPS_SWO_UART)) {
|
||||
swo_mode = DAP_SWO_MODE_UART;
|
||||
} else if (pin_protocol == TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER &&
|
||||
(cmsis_dap_handle->caps & INFO_CAPS_SWO_MANCHESTER)) {
|
||||
swo_mode = DAP_SWO_MODE_MANCHESTER;
|
||||
} else {
|
||||
LOG_ERROR("Selected pin protocol is not supported.");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (*swo_freq == 0) {
|
||||
LOG_INFO("SWO-trace frequency autodetection not implemented.");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
retval = cmsis_dap_cmd_dap_swo_control(DAP_SWO_CONTROL_STOP);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
cmsis_dap_handle->trace_enabled = false;
|
||||
|
||||
retval = cmsis_dap_get_swo_buf_sz(&cmsis_dap_handle->swo_buf_sz);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cmsis_dap_cmd_dap_swo_transport(DAP_SWO_TRANSPORT_DATA);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cmsis_dap_cmd_dap_swo_mode(swo_mode);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cmsis_dap_cmd_dap_swo_baudrate(*swo_freq, swo_freq);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
if (!calculate_swo_prescaler(traceclkin_hz, *swo_freq,
|
||||
swo_prescaler)) {
|
||||
LOG_ERROR("SWO frequency is not suitable. Please choose a "
|
||||
"different frequency or use auto-detection.");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
LOG_INFO("SWO frequency: %u Hz.", *swo_freq);
|
||||
LOG_INFO("SWO prescaler: %u.", *swo_prescaler);
|
||||
|
||||
retval = cmsis_dap_cmd_dap_swo_control(DAP_SWO_CONTROL_START);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
cmsis_dap_handle->trace_enabled = true;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see adapter_driver::poll_trace
|
||||
*/
|
||||
static int cmsis_dap_poll_trace(uint8_t *buf, size_t *size)
|
||||
{
|
||||
uint8_t trace_status;
|
||||
size_t trace_count;
|
||||
|
||||
if (!cmsis_dap_handle->trace_enabled) {
|
||||
*size = 0;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int retval = cmsis_dap_cmd_dap_swo_status(&trace_status, &trace_count);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
if ((trace_status & DAP_SWO_STATUS_CAPTURE_MASK) != DAP_SWO_STATUS_CAPTURE_ACTIVE)
|
||||
return ERROR_FAIL;
|
||||
|
||||
*size = trace_count < *size ? trace_count : *size;
|
||||
size_t read_so_far = 0;
|
||||
do {
|
||||
size_t rb = 0;
|
||||
uint32_t packet_size = cmsis_dap_handle->packet_size - 4 /*data-reply*/;
|
||||
uint32_t remaining = *size - read_so_far;
|
||||
if (remaining < packet_size)
|
||||
packet_size = remaining;
|
||||
retval = cmsis_dap_cmd_dap_swo_data(
|
||||
packet_size,
|
||||
&trace_status,
|
||||
&rb,
|
||||
&buf[read_so_far]);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
if ((trace_status & DAP_SWO_STATUS_CAPTURE_MASK) != DAP_SWO_STATUS_CAPTURE_ACTIVE)
|
||||
return ERROR_FAIL;
|
||||
|
||||
read_so_far += rb;
|
||||
} while (read_so_far < *size);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(cmsis_dap_handle_info_command)
|
||||
{
|
||||
if (cmsis_dap_get_version_info() == ERROR_OK)
|
||||
|
@ -1648,14 +1992,12 @@ COMMAND_HANDLER(cmsis_dap_handle_info_command)
|
|||
|
||||
COMMAND_HANDLER(cmsis_dap_handle_cmd_command)
|
||||
{
|
||||
int retval;
|
||||
unsigned i;
|
||||
uint8_t *command = cmsis_dap_handle->command;
|
||||
|
||||
for (i = 0; i < CMD_ARGC; i++)
|
||||
for (unsigned i = 0; i < CMD_ARGC; i++)
|
||||
command[i] = strtoul(CMD_ARGV[i], NULL, 16);
|
||||
|
||||
retval = cmsis_dap_xfer(cmsis_dap_handle, CMD_ARGC);
|
||||
int retval = cmsis_dap_xfer(cmsis_dap_handle, CMD_ARGC);
|
||||
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("CMSIS-DAP command failed.");
|
||||
|
@ -1763,7 +2105,7 @@ static const struct command_registration cmsis_dap_command_handlers[] = {
|
|||
.handler = &cmsis_dap_handle_vid_pid_command,
|
||||
.mode = COMMAND_CONFIG,
|
||||
.help = "the vendor ID and product ID of the CMSIS-DAP device",
|
||||
.usage = "(vid pid)* ",
|
||||
.usage = "(vid pid)*",
|
||||
},
|
||||
{
|
||||
.name = "cmsis_dap_serial",
|
||||
|
@ -1817,6 +2159,8 @@ struct adapter_driver cmsis_dap_adapter_driver = {
|
|||
.speed = cmsis_dap_speed,
|
||||
.khz = cmsis_dap_khz,
|
||||
.speed_div = cmsis_dap_speed_div,
|
||||
.config_trace = cmsis_dap_config_trace,
|
||||
.poll_trace = cmsis_dap_poll_trace,
|
||||
|
||||
.jtag_ops = &cmsis_dap_interface,
|
||||
.swd_ops = &cmsis_dap_swd_driver,
|
||||
|
|
|
@ -18,6 +18,8 @@ struct cmsis_dap {
|
|||
uint8_t *response;
|
||||
uint8_t caps;
|
||||
uint8_t mode;
|
||||
uint32_t swo_buf_sz;
|
||||
bool trace_enabled;
|
||||
};
|
||||
|
||||
struct cmsis_dap_backend {
|
||||
|
|
|
@ -262,7 +262,7 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
|
|||
* - config asked explicitly for an interface number
|
||||
* - the device has only one interface
|
||||
* The later two cases should be honored only if we know
|
||||
* we are on the rigt device */
|
||||
* we are on the right device */
|
||||
bool intf_identified_reliably = cmsis_dap_in_interface_str
|
||||
|| (device_identified_reliably &&
|
||||
(cmsis_dap_usb_interface != -1
|
||||
|
|
|
@ -1253,22 +1253,22 @@ COMMAND_HANDLER(ftdi_handle_vid_pid_command)
|
|||
|
||||
COMMAND_HANDLER(ftdi_handle_tdo_sample_edge_command)
|
||||
{
|
||||
Jim_Nvp *n;
|
||||
static const Jim_Nvp nvp_ftdi_jtag_modes[] = {
|
||||
struct jim_nvp *n;
|
||||
static const struct jim_nvp nvp_ftdi_jtag_modes[] = {
|
||||
{ .name = "rising", .value = JTAG_MODE },
|
||||
{ .name = "falling", .value = JTAG_MODE_ALT },
|
||||
{ .name = NULL, .value = -1 },
|
||||
};
|
||||
|
||||
if (CMD_ARGC > 0) {
|
||||
n = Jim_Nvp_name2value_simple(nvp_ftdi_jtag_modes, CMD_ARGV[0]);
|
||||
n = jim_nvp_name2value_simple(nvp_ftdi_jtag_modes, CMD_ARGV[0]);
|
||||
if (n->name == NULL)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
ftdi_jtag_mode = n->value;
|
||||
|
||||
}
|
||||
|
||||
n = Jim_Nvp_value2name_simple(nvp_ftdi_jtag_modes, ftdi_jtag_mode);
|
||||
n = jim_nvp_value2name_simple(nvp_ftdi_jtag_modes, ftdi_jtag_mode);
|
||||
command_print(CMD, "ftdi samples TDO on %s edge of TCK", n->name);
|
||||
|
||||
return ERROR_OK;
|
||||
|
@ -1345,7 +1345,7 @@ static const struct command_registration ftdi_command_handlers[] = {
|
|||
.handler = &ftdi_handle_vid_pid_command,
|
||||
.mode = COMMAND_CONFIG,
|
||||
.help = "the vendor ID and product ID of the FTDI device",
|
||||
.usage = "(vid pid)* ",
|
||||
.usage = "(vid pid)*",
|
||||
},
|
||||
{
|
||||
.name = "ftdi_tdo_sample_edge",
|
||||
|
|
|
@ -282,7 +282,7 @@ static int jlink_execute_command(struct jtag_command *cmd)
|
|||
jlink_execute_sleep(cmd);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("BUG: Unknown JTAG command type encountered.");
|
||||
LOG_ERROR("BUG: Unknown JTAG command type encountered");
|
||||
return ERROR_JTAG_QUEUE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -316,7 +316,7 @@ static int jlink_speed(int speed)
|
|||
ret = jaylink_get_speeds(devh, &tmp);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_get_speeds() failed: %s.",
|
||||
LOG_ERROR("jaylink_get_speeds() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
@ -329,13 +329,13 @@ static int jlink_speed(int speed)
|
|||
|
||||
if (!speed) {
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ADAPTIVE_CLOCKING)) {
|
||||
LOG_ERROR("Adaptive clocking is not supported by the device.");
|
||||
LOG_ERROR("Adaptive clocking is not supported by the device");
|
||||
return ERROR_JTAG_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
speed = JAYLINK_SPEED_ADAPTIVE_CLOCKING;
|
||||
} else if (speed > max_speed) {
|
||||
LOG_INFO("Reduced speed from %d kHz to %d kHz (maximum).", speed,
|
||||
LOG_INFO("Reduced speed from %d kHz to %d kHz (maximum)", speed,
|
||||
max_speed);
|
||||
speed = max_speed;
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ static int jlink_speed(int speed)
|
|||
ret = jaylink_set_speed(devh, speed);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_set_speed() failed: %s.",
|
||||
LOG_ERROR("jaylink_set_speed() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_JTAG_DEVICE_ERROR;
|
||||
}
|
||||
|
@ -372,7 +372,7 @@ static bool read_device_config(struct device_config *cfg)
|
|||
ret = jaylink_read_raw_config(devh, (uint8_t *)cfg);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_read_raw_config() failed: %s.",
|
||||
LOG_ERROR("jaylink_read_raw_config() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ static int select_interface(void)
|
|||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SELECT_TIF)) {
|
||||
if (iface != JAYLINK_TIF_JTAG) {
|
||||
LOG_ERROR("Device supports JTAG transport only.");
|
||||
LOG_ERROR("Device supports JTAG transport only");
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
||||
|
@ -403,20 +403,20 @@ static int select_interface(void)
|
|||
ret = jaylink_get_available_interfaces(devh, &interfaces);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_get_available_interfaces() failed: %s.",
|
||||
LOG_ERROR("jaylink_get_available_interfaces() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
||||
if (!(interfaces & (1 << iface))) {
|
||||
LOG_ERROR("Selected transport is not supported by the device.");
|
||||
LOG_ERROR("Selected transport is not supported by the device");
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
||||
ret = jaylink_select_interface(devh, iface, NULL);
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_ERROR("jaylink_select_interface() failed: %s.",
|
||||
LOG_ERROR("jaylink_select_interface() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ static int jlink_register(void)
|
|||
ret = jaylink_register(devh, &conn, connlist, &count);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_register() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_register() failed: %s", jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
@ -452,7 +452,7 @@ static int jlink_register(void)
|
|||
|
||||
if (!handle_found) {
|
||||
LOG_ERROR("Registration failed: maximum number of connections on the "
|
||||
"device reached.");
|
||||
"device reached");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
@ -475,13 +475,13 @@ static bool adjust_swd_buffer_size(void)
|
|||
ret = jaylink_get_free_memory(devh, &tmp);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_get_free_memory() failed: %s.",
|
||||
LOG_ERROR("jaylink_get_free_memory() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tmp < 143) {
|
||||
LOG_ERROR("Not enough free device internal memory: %" PRIu32 " bytes.", tmp);
|
||||
LOG_ERROR("Not enough free device internal memory: %" PRIu32 " bytes", tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,7 @@ static bool adjust_swd_buffer_size(void)
|
|||
|
||||
if (tmp != swd_buffer_size) {
|
||||
swd_buffer_size = tmp;
|
||||
LOG_DEBUG("Adjusted SWD transaction buffer size to %u bytes.",
|
||||
LOG_DEBUG("Adjusted SWD transaction buffer size to %u bytes",
|
||||
swd_buffer_size);
|
||||
}
|
||||
|
||||
|
@ -542,7 +542,7 @@ static bool jlink_usb_location_equal(struct jaylink_device *dev)
|
|||
if (retval == JAYLINK_ERR_NOT_SUPPORTED) {
|
||||
return false;
|
||||
} else if (retval != JAYLINK_OK) {
|
||||
LOG_WARNING("jaylink_device_get_usb_bus_ports() failed: %s.",
|
||||
LOG_WARNING("jaylink_device_get_usb_bus_ports() failed: %s",
|
||||
jaylink_strerror(retval));
|
||||
return false;
|
||||
}
|
||||
|
@ -558,7 +558,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device)
|
|||
{
|
||||
int ret = jaylink_discovery_scan(jayctx, ifaces);
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_discovery_scan() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_discovery_scan() failed: %s", jaylink_strerror(ret));
|
||||
jaylink_exit(jayctx);
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device)
|
|||
ret = jaylink_get_devices(jayctx, &devs, &num_devices);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_get_devices() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_get_devices() failed: %s", jaylink_strerror(ret));
|
||||
jaylink_exit(jayctx);
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
@ -576,7 +576,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device)
|
|||
use_usb_location = (jtag_usb_get_location() != NULL);
|
||||
|
||||
if (!use_serial_number && !use_usb_address && !use_usb_location && num_devices > 1) {
|
||||
LOG_ERROR("Multiple devices found, specify the desired device.");
|
||||
LOG_ERROR("Multiple devices found, specify the desired device");
|
||||
jaylink_free_devices(devs, true);
|
||||
jaylink_exit(jayctx);
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
|
@ -594,7 +594,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device)
|
|||
if (ret == JAYLINK_ERR_NOT_AVAILABLE) {
|
||||
continue;
|
||||
} else if (ret != JAYLINK_OK) {
|
||||
LOG_WARNING("jaylink_device_get_serial_number() failed: %s.",
|
||||
LOG_WARNING("jaylink_device_get_serial_number() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
continue;
|
||||
}
|
||||
|
@ -610,7 +610,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device)
|
|||
if (ret == JAYLINK_ERR_NOT_SUPPORTED) {
|
||||
continue;
|
||||
} else if (ret != JAYLINK_OK) {
|
||||
LOG_WARNING("jaylink_device_get_usb_address() failed: %s.",
|
||||
LOG_WARNING("jaylink_device_get_usb_address() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
continue;
|
||||
}
|
||||
|
@ -629,7 +629,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device)
|
|||
break;
|
||||
}
|
||||
|
||||
LOG_ERROR("Failed to open device: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("Failed to open device: %s", jaylink_strerror(ret));
|
||||
}
|
||||
|
||||
jaylink_free_devices(devs, true);
|
||||
|
@ -645,25 +645,25 @@ static int jlink_init(void)
|
|||
struct jaylink_hardware_status hwstatus;
|
||||
size_t length;
|
||||
|
||||
LOG_DEBUG("Using libjaylink %s (compiled with %s).",
|
||||
LOG_DEBUG("Using libjaylink %s (compiled with %s)",
|
||||
jaylink_version_package_get_string(), JAYLINK_VERSION_PACKAGE_STRING);
|
||||
|
||||
if (!jaylink_library_has_cap(JAYLINK_CAP_HIF_USB) && use_usb_address) {
|
||||
LOG_ERROR("J-Link driver does not support USB devices.");
|
||||
LOG_ERROR("J-Link driver does not support USB devices");
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
||||
ret = jaylink_init(&jayctx);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_init() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_init() failed: %s", jaylink_strerror(ret));
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
||||
ret = jaylink_log_set_callback(jayctx, &jaylink_log_handler, NULL);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_log_set_callback() failed: %s.",
|
||||
LOG_ERROR("jaylink_log_set_callback() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
jaylink_exit(jayctx);
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
|
@ -681,7 +681,7 @@ static int jlink_init(void)
|
|||
}
|
||||
|
||||
if (!found_device) {
|
||||
LOG_ERROR("No J-Link device found.");
|
||||
LOG_ERROR("No J-Link device found");
|
||||
jaylink_exit(jayctx);
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
}
|
||||
|
@ -694,7 +694,7 @@ static int jlink_init(void)
|
|||
ret = jaylink_get_firmware_version(devh, &firmware_version, &length);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_get_firmware_version() failed: %s.",
|
||||
LOG_ERROR("jaylink_get_firmware_version() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
jaylink_close(devh);
|
||||
jaylink_exit(jayctx);
|
||||
|
@ -703,14 +703,14 @@ static int jlink_init(void)
|
|||
LOG_INFO("%s", firmware_version);
|
||||
free(firmware_version);
|
||||
} else {
|
||||
LOG_WARNING("Device responds empty firmware version string.");
|
||||
LOG_WARNING("Device responds empty firmware version string");
|
||||
}
|
||||
|
||||
memset(caps, 0, JAYLINK_DEV_EXT_CAPS_SIZE);
|
||||
ret = jaylink_get_caps(devh, caps);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_get_caps() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_get_caps() failed: %s", jaylink_strerror(ret));
|
||||
jaylink_close(devh);
|
||||
jaylink_exit(jayctx);
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
|
@ -720,7 +720,7 @@ static int jlink_init(void)
|
|||
ret = jaylink_get_extended_caps(devh, caps);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_get_extended_caps() failed: %s.",
|
||||
LOG_ERROR("jaylink_get_extended_caps() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
jaylink_close(devh);
|
||||
jaylink_exit(jayctx);
|
||||
|
@ -734,7 +734,7 @@ static int jlink_init(void)
|
|||
ret = jaylink_get_hardware_version(devh, &hwver);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("Failed to retrieve hardware version: %s.",
|
||||
LOG_ERROR("Failed to retrieve hardware version: %s",
|
||||
jaylink_strerror(ret));
|
||||
jaylink_close(devh);
|
||||
jaylink_exit(jayctx);
|
||||
|
@ -763,7 +763,7 @@ static int jlink_init(void)
|
|||
|
||||
if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {
|
||||
if (!read_device_config(&config)) {
|
||||
LOG_ERROR("Failed to read device configuration data.");
|
||||
LOG_ERROR("Failed to read device configuration data");
|
||||
jaylink_close(devh);
|
||||
jaylink_exit(jayctx);
|
||||
return ERROR_JTAG_INIT_FAILED;
|
||||
|
@ -775,7 +775,7 @@ static int jlink_init(void)
|
|||
ret = jaylink_get_hardware_status(devh, &hwstatus);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_get_hardware_status() failed: %s.",
|
||||
LOG_ERROR("jaylink_get_hardware_status() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
jaylink_close(devh);
|
||||
jaylink_exit(jayctx);
|
||||
|
@ -837,14 +837,14 @@ static int jlink_quit(void)
|
|||
ret = jaylink_swo_stop(devh);
|
||||
|
||||
if (ret != JAYLINK_OK)
|
||||
LOG_ERROR("jaylink_swo_stop() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_swo_stop() failed: %s", jaylink_strerror(ret));
|
||||
}
|
||||
|
||||
if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER)) {
|
||||
ret = jaylink_unregister(devh, &conn, connlist, &count);
|
||||
|
||||
if (ret != JAYLINK_OK)
|
||||
LOG_ERROR("jaylink_unregister() failed: %s.",
|
||||
LOG_ERROR("jaylink_unregister() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
}
|
||||
|
||||
|
@ -892,7 +892,7 @@ static void jlink_path_move(int num_states, tap_state_t *path)
|
|||
else if (path[i] == tap_state_transition(tap_get_state(), true))
|
||||
jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1);
|
||||
else {
|
||||
LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition.",
|
||||
LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
|
||||
tap_state_name(tap_get_state()), tap_state_name(path[i]));
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -935,7 +935,7 @@ static void jlink_runtest(int num_cycles)
|
|||
|
||||
static void jlink_reset(int trst, int srst)
|
||||
{
|
||||
LOG_DEBUG("TRST: %i, SRST: %i.", trst, srst);
|
||||
LOG_DEBUG("TRST: %i, SRST: %i", trst, srst);
|
||||
|
||||
/* Signals are active low. */
|
||||
if (srst == 0)
|
||||
|
@ -963,17 +963,17 @@ COMMAND_HANDLER(jlink_usb_command)
|
|||
int tmp;
|
||||
|
||||
if (CMD_ARGC != 1) {
|
||||
command_print(CMD, "Need exactly one argument for jlink usb.");
|
||||
command_print(CMD, "Need exactly one argument for jlink usb");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) {
|
||||
command_print(CMD, "Invalid USB address: %s.", CMD_ARGV[0]);
|
||||
command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (tmp < JAYLINK_USB_ADDRESS_0 || tmp > JAYLINK_USB_ADDRESS_3) {
|
||||
command_print(CMD, "Invalid USB address: %s.", CMD_ARGV[0]);
|
||||
command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
@ -990,17 +990,17 @@ COMMAND_HANDLER(jlink_serial_command)
|
|||
int ret;
|
||||
|
||||
if (CMD_ARGC != 1) {
|
||||
command_print(CMD, "Need exactly one argument for jlink serial.");
|
||||
command_print(CMD, "Need exactly one argument for jlink serial");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
ret = jaylink_parse_serial_number(CMD_ARGV[0], &serial_number);
|
||||
|
||||
if (ret == JAYLINK_ERR) {
|
||||
command_print(CMD, "Invalid serial number: %s.", CMD_ARGV[0]);
|
||||
command_print(CMD, "Invalid serial number: %s", CMD_ARGV[0]);
|
||||
return ERROR_FAIL;
|
||||
} else if (ret != JAYLINK_OK) {
|
||||
command_print(CMD, "jaylink_parse_serial_number() failed: %s.",
|
||||
command_print(CMD, "jaylink_parse_serial_number() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -1019,7 +1019,7 @@ COMMAND_HANDLER(jlink_handle_hwstatus_command)
|
|||
ret = jaylink_get_hardware_status(devh, &status);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
command_print(CMD, "jaylink_get_hardware_status() failed: %s.",
|
||||
command_print(CMD, "jaylink_get_hardware_status() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -1032,7 +1032,7 @@ COMMAND_HANDLER(jlink_handle_hwstatus_command)
|
|||
status.tres, status.trst);
|
||||
|
||||
if (status.target_voltage < 1500)
|
||||
command_print(CMD, "Target voltage too low. Check target power.");
|
||||
command_print(CMD, "Target voltage too low. Check target power");
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -1044,19 +1044,19 @@ COMMAND_HANDLER(jlink_handle_free_memory_command)
|
|||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_FREE_MEMORY)) {
|
||||
command_print(CMD, "Retrieval of free memory is not supported by "
|
||||
"the device.");
|
||||
"the device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
ret = jaylink_get_free_memory(devh, &tmp);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
command_print(CMD, "jaylink_get_free_memory() failed: %s.",
|
||||
command_print(CMD, "jaylink_get_free_memory() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
command_print(CMD, "Device has %" PRIu32 " bytes of free memory.", tmp);
|
||||
command_print(CMD, "Device has %" PRIu32 " bytes of free memory", tmp);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -1081,7 +1081,7 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
|
|||
command_print(CMD, "JTAG command version: %i", version);
|
||||
} else if (CMD_ARGC == 1) {
|
||||
if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) {
|
||||
command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]);
|
||||
command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1093,11 +1093,11 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
|
|||
jtag_command_version = JAYLINK_JTAG_VERSION_3;
|
||||
break;
|
||||
default:
|
||||
command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]);
|
||||
command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
} else {
|
||||
command_print(CMD, "Need exactly one argument for jlink jtag.");
|
||||
command_print(CMD, "Need exactly one argument for jlink jtag");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1110,14 +1110,13 @@ COMMAND_HANDLER(jlink_handle_target_power_command)
|
|||
int enable;
|
||||
|
||||
if (CMD_ARGC != 1) {
|
||||
command_print(CMD, "Need exactly one argument for jlink "
|
||||
"targetpower.");
|
||||
command_print(CMD, "Need exactly one argument for jlink targetpower");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) {
|
||||
command_print(CMD, "Target power supply is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -1126,14 +1125,14 @@ COMMAND_HANDLER(jlink_handle_target_power_command)
|
|||
} else if (!strcmp(CMD_ARGV[0], "off")) {
|
||||
enable = false;
|
||||
} else {
|
||||
command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]);
|
||||
command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
ret = jaylink_set_target_power(devh, enable);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
command_print(CMD, "jaylink_set_target_power() failed: %s.",
|
||||
command_print(CMD, "jaylink_set_target_power() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -1240,7 +1239,7 @@ static int poll_trace(uint8_t *buf, size_t *size)
|
|||
ret = jaylink_swo_read(devh, buf, &length);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_swo_read() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_swo_read() failed: %s", jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
@ -1260,7 +1259,7 @@ static uint32_t calculate_trace_buffer_size(void)
|
|||
ret = jaylink_get_free_memory(devh, &tmp);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_get_free_memory() failed: %s.",
|
||||
LOG_ERROR("jaylink_get_free_memory() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -1334,14 +1333,14 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
|
|||
if (!enabled)
|
||||
return ERROR_OK;
|
||||
|
||||
LOG_ERROR("Trace capturing is not supported by the device.");
|
||||
LOG_ERROR("Trace capturing is not supported by the device");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
ret = jaylink_swo_stop(devh);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_swo_stop() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_swo_stop() failed: %s", jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
@ -1357,21 +1356,21 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
|
|||
}
|
||||
|
||||
if (pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART) {
|
||||
LOG_ERROR("Selected pin protocol is not supported.");
|
||||
LOG_ERROR("Selected pin protocol is not supported");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
buffer_size = calculate_trace_buffer_size();
|
||||
|
||||
if (!buffer_size) {
|
||||
LOG_ERROR("Not enough free device memory to start trace capturing.");
|
||||
LOG_ERROR("Not enough free device memory to start trace capturing");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
ret = jaylink_swo_get_speeds(devh, JAYLINK_SWO_MODE_UART, &speed);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_swo_get_speeds() failed: %s.",
|
||||
LOG_ERROR("jaylink_swo_get_speeds() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -1382,49 +1381,49 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
|
|||
max_freq = speed.freq / speed.min_div;
|
||||
|
||||
if (*trace_freq > max_freq) {
|
||||
LOG_INFO("Given SWO frequency too high, using %" PRIu32 " Hz instead.",
|
||||
LOG_INFO("Given SWO frequency too high, using %" PRIu32 " Hz instead",
|
||||
max_freq);
|
||||
*trace_freq = max_freq;
|
||||
} else if (*trace_freq < min_freq) {
|
||||
LOG_INFO("Given SWO frequency too low, using %" PRIu32 " Hz instead.",
|
||||
LOG_INFO("Given SWO frequency too low, using %" PRIu32 " Hz instead",
|
||||
min_freq);
|
||||
*trace_freq = min_freq;
|
||||
} else if (*trace_freq != speed.freq / divider) {
|
||||
*trace_freq = speed.freq / divider;
|
||||
|
||||
LOG_INFO("Given SWO frequency is not supported by the device, "
|
||||
"using %u Hz instead.", *trace_freq);
|
||||
"using %u Hz instead", *trace_freq);
|
||||
}
|
||||
|
||||
if (!calculate_swo_prescaler(traceclkin_freq, *trace_freq,
|
||||
prescaler)) {
|
||||
LOG_ERROR("SWO frequency is not suitable. Please choose a "
|
||||
"different frequency or use auto-detection.");
|
||||
"different frequency or use auto-detection");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
} else {
|
||||
LOG_INFO("Trying to auto-detect SWO frequency.");
|
||||
LOG_INFO("Trying to auto-detect SWO frequency");
|
||||
|
||||
if (!detect_swo_freq_and_prescaler(speed, traceclkin_freq, trace_freq,
|
||||
prescaler)) {
|
||||
LOG_ERROR("Maximum permitted frequency deviation of %.02f %% "
|
||||
"could not be achieved.", SWO_MAX_FREQ_DEV);
|
||||
LOG_ERROR("Auto-detection of SWO frequency failed.");
|
||||
"could not be achieved", SWO_MAX_FREQ_DEV);
|
||||
LOG_ERROR("Auto-detection of SWO frequency failed");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
LOG_INFO("Using SWO frequency of %u Hz.", *trace_freq);
|
||||
LOG_INFO("Using SWO frequency of %u Hz", *trace_freq);
|
||||
}
|
||||
|
||||
ret = jaylink_swo_start(devh, JAYLINK_SWO_MODE_UART, *trace_freq,
|
||||
buffer_size);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_start_swo() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_start_swo() failed: %s", jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
LOG_DEBUG("Using %" PRIu32 " bytes device memory for trace capturing.",
|
||||
LOG_DEBUG("Using %" PRIu32 " bytes device memory for trace capturing",
|
||||
buffer_size);
|
||||
|
||||
/*
|
||||
|
@ -1443,7 +1442,7 @@ COMMAND_HANDLER(jlink_handle_config_usb_address_command)
|
|||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {
|
||||
command_print(CMD, "Reading configuration is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -1451,19 +1450,18 @@ COMMAND_HANDLER(jlink_handle_config_usb_address_command)
|
|||
show_config_usb_address(CMD);
|
||||
} else if (CMD_ARGC == 1) {
|
||||
if (sscanf(CMD_ARGV[0], "%" SCNd8, &tmp) != 1) {
|
||||
command_print(CMD, "Invalid USB address: %s.", CMD_ARGV[0]);
|
||||
command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (tmp > JAYLINK_USB_ADDRESS_3) {
|
||||
command_print(CMD, "Invalid USB address: %u.", tmp);
|
||||
command_print(CMD, "Invalid USB address: %u", tmp);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
tmp_config.usb_address = tmp;
|
||||
} else {
|
||||
command_print(CMD, "Need exactly one argument for jlink config "
|
||||
"usb.");
|
||||
command_print(CMD, "Need exactly one argument for jlink config usb");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1476,13 +1474,13 @@ COMMAND_HANDLER(jlink_handle_config_target_power_command)
|
|||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {
|
||||
command_print(CMD, "Reading configuration is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) {
|
||||
command_print(CMD, "Target power supply is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -1494,14 +1492,14 @@ COMMAND_HANDLER(jlink_handle_config_target_power_command)
|
|||
} else if (!strcmp(CMD_ARGV[0], "off")) {
|
||||
enable = false;
|
||||
} else {
|
||||
command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]);
|
||||
command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
tmp_config.target_power = enable;
|
||||
} else {
|
||||
command_print(CMD, "Need exactly one argument for jlink config "
|
||||
"targetpower.");
|
||||
"targetpower");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1517,13 +1515,13 @@ COMMAND_HANDLER(jlink_handle_config_mac_address_command)
|
|||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {
|
||||
command_print(CMD, "Reading configuration is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) {
|
||||
command_print(CMD, "Ethernet connectivity is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -1534,7 +1532,7 @@ COMMAND_HANDLER(jlink_handle_config_mac_address_command)
|
|||
|
||||
if ((strlen(str) != 17) || (str[2] != ':' || str[5] != ':' ||
|
||||
str[8] != ':' || str[11] != ':' || str[14] != ':')) {
|
||||
command_print(CMD, "Invalid MAC address format.");
|
||||
command_print(CMD, "Invalid MAC address format");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1544,19 +1542,18 @@ COMMAND_HANDLER(jlink_handle_config_mac_address_command)
|
|||
}
|
||||
|
||||
if (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) {
|
||||
command_print(CMD, "Invalid MAC address: zero address.");
|
||||
command_print(CMD, "Invalid MAC address: zero address");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
if (!(0x01 & addr[0])) {
|
||||
command_print(CMD, "Invalid MAC address: multicast address.");
|
||||
command_print(CMD, "Invalid MAC address: multicast address");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
memcpy(tmp_config.mac_address, addr, sizeof(addr));
|
||||
} else {
|
||||
command_print(CMD, "Need exactly one argument for jlink config "
|
||||
" mac.");
|
||||
command_print(CMD, "Need exactly one argument for jlink config mac");
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1605,13 +1602,13 @@ COMMAND_HANDLER(jlink_handle_config_ip_address_command)
|
|||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {
|
||||
command_print(CMD, "Reading configuration is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) {
|
||||
command_print(CMD, "Ethernet connectivity is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -1662,44 +1659,44 @@ COMMAND_HANDLER(jlink_handle_config_write_command)
|
|||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {
|
||||
command_print(CMD, "Reading configuration is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_WRITE_CONFIG)) {
|
||||
command_print(CMD, "Writing configuration is not supported by the "
|
||||
"device.");
|
||||
"device");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
if (!memcmp(&config, &tmp_config, sizeof(struct device_config))) {
|
||||
command_print(CMD, "Operation not performed due to no changes in "
|
||||
"the configuration.");
|
||||
"the configuration");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
ret = jaylink_write_raw_config(devh, (const uint8_t *)&tmp_config);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_write_raw_config() failed: %s.",
|
||||
LOG_ERROR("jaylink_write_raw_config() failed: %s",
|
||||
jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (!read_device_config(&config)) {
|
||||
LOG_ERROR("Failed to read device configuration for verification.");
|
||||
LOG_ERROR("Failed to read device configuration for verification");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (memcmp(&config, &tmp_config, sizeof(struct device_config))) {
|
||||
LOG_ERROR("Verification of device configuration failed. Please check "
|
||||
"your device.");
|
||||
"your device");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
memcpy(&tmp_config, &config, sizeof(struct device_config));
|
||||
command_print(CMD, "The new device configuration applies after power "
|
||||
"cycling the J-Link device.");
|
||||
"cycling the J-Link device");
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -1707,7 +1704,7 @@ COMMAND_HANDLER(jlink_handle_config_write_command)
|
|||
COMMAND_HANDLER(jlink_handle_config_command)
|
||||
{
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {
|
||||
command_print(CMD, "Device doesn't support reading configuration.");
|
||||
command_print(CMD, "Device doesn't support reading configuration");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -1730,7 +1727,7 @@ COMMAND_HANDLER(jlink_handle_emucom_write_command)
|
|||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
|
||||
LOG_ERROR("Device does not support EMUCOM.");
|
||||
LOG_ERROR("Device does not support EMUCOM");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
@ -1739,21 +1736,21 @@ COMMAND_HANDLER(jlink_handle_emucom_write_command)
|
|||
tmp = strlen(CMD_ARGV[1]);
|
||||
|
||||
if (tmp % 2 != 0) {
|
||||
LOG_ERROR("Data must be encoded as hexadecimal pairs.");
|
||||
LOG_ERROR("Data must be encoded as hexadecimal pairs");
|
||||
return ERROR_COMMAND_ARGUMENT_INVALID;
|
||||
}
|
||||
|
||||
buf = malloc(tmp / 2);
|
||||
|
||||
if (!buf) {
|
||||
LOG_ERROR("Failed to allocate buffer.");
|
||||
LOG_ERROR("Failed to allocate buffer");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
dummy = unhexify(buf, CMD_ARGV[1], tmp / 2);
|
||||
|
||||
if (dummy != (tmp / 2)) {
|
||||
LOG_ERROR("Data must be encoded as hexadecimal pairs.");
|
||||
LOG_ERROR("Data must be encoded as hexadecimal pairs");
|
||||
free(buf);
|
||||
return ERROR_COMMAND_ARGUMENT_INVALID;
|
||||
}
|
||||
|
@ -1764,15 +1761,15 @@ COMMAND_HANDLER(jlink_handle_emucom_write_command)
|
|||
free(buf);
|
||||
|
||||
if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
|
||||
LOG_ERROR("Channel not supported by the device.");
|
||||
LOG_ERROR("Channel not supported by the device");
|
||||
return ERROR_FAIL;
|
||||
} else if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("Failed to write to channel: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("Failed to write to channel: %s", jaylink_strerror(ret));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (length != (tmp / 2))
|
||||
LOG_WARNING("Only %" PRIu32 " bytes written to the channel.", length);
|
||||
LOG_WARNING("Only %" PRIu32 " bytes written to the channel", length);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -1789,7 +1786,7 @@ COMMAND_HANDLER(jlink_handle_emucom_read_command)
|
|||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
|
||||
LOG_ERROR("Device does not support EMUCOM.");
|
||||
LOG_ERROR("Device does not support EMUCOM");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
@ -1799,23 +1796,23 @@ COMMAND_HANDLER(jlink_handle_emucom_read_command)
|
|||
buf = malloc(length * 3 + 1);
|
||||
|
||||
if (!buf) {
|
||||
LOG_ERROR("Failed to allocate buffer.");
|
||||
LOG_ERROR("Failed to allocate buffer");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
ret = jaylink_emucom_read(devh, channel, buf, &length);
|
||||
|
||||
if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
|
||||
LOG_ERROR("Channel is not supported by the device.");
|
||||
LOG_ERROR("Channel is not supported by the device");
|
||||
free(buf);
|
||||
return ERROR_FAIL;
|
||||
} else if (ret == JAYLINK_ERR_DEV_NOT_AVAILABLE) {
|
||||
LOG_ERROR("Channel is not available for the requested amount of data. "
|
||||
"%" PRIu32 " bytes are available.", length);
|
||||
"%" PRIu32 " bytes are available", length);
|
||||
free(buf);
|
||||
return ERROR_FAIL;
|
||||
} else if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("Failed to read from channel: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("Failed to read from channel: %s", jaylink_strerror(ret));
|
||||
free(buf);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -1823,7 +1820,7 @@ COMMAND_HANDLER(jlink_handle_emucom_read_command)
|
|||
tmp = hexify((char *)buf + length, buf, length, 2 * length + 1);
|
||||
|
||||
if (tmp != 2 * length) {
|
||||
LOG_ERROR("Failed to convert data into hexadecimal string.");
|
||||
LOG_ERROR("Failed to convert data into hexadecimal string");
|
||||
free(buf);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -2081,7 +2078,7 @@ static int jlink_flush(void)
|
|||
tap_length, jtag_command_version);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_jtag_io() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_jtag_io() failed: %s", jaylink_strerror(ret));
|
||||
jlink_tap_init();
|
||||
return ERROR_JTAG_QUEUE_FAILED;
|
||||
}
|
||||
|
@ -2092,7 +2089,7 @@ static int jlink_flush(void)
|
|||
buf_set_buf(tdo_buffer, p->first, p->buffer,
|
||||
p->buffer_offset, p->length);
|
||||
|
||||
LOG_DEBUG_IO("Pending scan result, length = %d.", p->length);
|
||||
LOG_DEBUG_IO("Pending scan result, length = %d", p->length);
|
||||
}
|
||||
|
||||
jlink_tap_init();
|
||||
|
@ -2157,7 +2154,7 @@ static int jlink_swd_switch_seq(enum swd_special_seq seq)
|
|||
s_len = swd_seq_swd_to_jtag_len;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Sequence %d not supported.", seq);
|
||||
LOG_ERROR("Sequence %d not supported", seq);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
@ -2171,10 +2168,10 @@ static int jlink_swd_run_queue(void)
|
|||
int i;
|
||||
int ret;
|
||||
|
||||
LOG_DEBUG("Executing %d queued transactions.", pending_scan_results_length);
|
||||
LOG_DEBUG("Executing %d queued transactions", pending_scan_results_length);
|
||||
|
||||
if (queued_retval != ERROR_OK) {
|
||||
LOG_DEBUG("Skipping due to previous errors: %d.", queued_retval);
|
||||
LOG_DEBUG("Skipping due to previous errors: %d", queued_retval);
|
||||
goto skip;
|
||||
}
|
||||
|
||||
|
@ -2187,7 +2184,7 @@ static int jlink_swd_run_queue(void)
|
|||
ret = jaylink_swd_io(devh, tms_buffer, tdi_buffer, tdo_buffer, tap_length);
|
||||
|
||||
if (ret != JAYLINK_OK) {
|
||||
LOG_ERROR("jaylink_swd_io() failed: %s.", jaylink_strerror(ret));
|
||||
LOG_ERROR("jaylink_swd_io() failed: %s", jaylink_strerror(ret));
|
||||
goto skip;
|
||||
}
|
||||
|
||||
|
@ -2204,7 +2201,7 @@ static int jlink_swd_run_queue(void)
|
|||
int parity = buf_get_u32(tdo_buffer, 3 + 32 + pending_scan_results_buffer[i].first, 1);
|
||||
|
||||
if (parity != parity_u32(data)) {
|
||||
LOG_ERROR("SWD: Read data parity mismatch.");
|
||||
LOG_ERROR("SWD: Read data parity mismatch");
|
||||
queued_retval = ERROR_FAIL;
|
||||
goto skip;
|
||||
}
|
||||
|
|
|
@ -301,7 +301,7 @@ static int jtag_dpi_init(void)
|
|||
serv_addr.sin_addr.s_addr = inet_addr(server_address);
|
||||
|
||||
if (serv_addr.sin_addr.s_addr == INADDR_NONE) {
|
||||
LOG_ERROR("inet_addr error occured");
|
||||
LOG_ERROR("inet_addr error occurred");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
|
|
@ -844,11 +844,11 @@ static int nulink_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
|
|||
/* the nulink only supports 8/32bit memory read/writes
|
||||
* honour 32bit, all others will be handled as 8bit access */
|
||||
if (size == 4) {
|
||||
/* When in jtag mode the nulink uses the auto-increment functinality.
|
||||
/* When in jtag mode the nulink uses the auto-increment functionality.
|
||||
* However it expects us to pass the data correctly, this includes
|
||||
* alignment and any page boundaries. We already do this as part of the
|
||||
* adi_v5 implementation, but the nulink is a hla adapter and so this
|
||||
* needs implementiong manually.
|
||||
* needs implementing manually.
|
||||
* currently this only affects jtag mode, they do single
|
||||
* access in SWD mode - but this may change and so we do it for both modes */
|
||||
|
||||
|
@ -909,11 +909,11 @@ static int nulink_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
|
|||
/* the nulink only supports 8/32bit memory read/writes
|
||||
* honour 32bit, all others will be handled as 8bit access */
|
||||
if (size == 4) {
|
||||
/* When in jtag mode the nulink uses the auto-increment functinality.
|
||||
/* When in jtag mode the nulink uses the auto-increment functionality.
|
||||
* However it expects us to pass the data correctly, this includes
|
||||
* alignment and any page boundaries. We already do this as part of the
|
||||
* adi_v5 implementation, but the nulink is a hla adapter and so this
|
||||
* needs implementiong manually.
|
||||
* needs implementing manually.
|
||||
* currently this only affects jtag mode, do single
|
||||
* access in SWD mode - but this may change and so we do it for both modes */
|
||||
|
||||
|
|
|
@ -413,17 +413,17 @@ static inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, i
|
|||
* Map the relevant features, quirks and workaround for specific firmware
|
||||
* version of stlink
|
||||
*/
|
||||
#define STLINK_F_HAS_TRACE BIT(0)
|
||||
#define STLINK_F_HAS_SWD_SET_FREQ BIT(1)
|
||||
#define STLINK_F_HAS_JTAG_SET_FREQ BIT(2)
|
||||
#define STLINK_F_HAS_MEM_16BIT BIT(3)
|
||||
#define STLINK_F_HAS_GETLASTRWSTATUS2 BIT(4)
|
||||
#define STLINK_F_HAS_DAP_REG BIT(5)
|
||||
#define STLINK_F_QUIRK_JTAG_DP_READ BIT(6)
|
||||
#define STLINK_F_HAS_AP_INIT BIT(7)
|
||||
#define STLINK_F_HAS_DPBANKSEL BIT(8)
|
||||
#define STLINK_F_HAS_RW8_512BYTES BIT(9)
|
||||
#define STLINK_F_FIX_CLOSE_AP BIT(10)
|
||||
#define STLINK_F_HAS_TRACE BIT(0) /* v2>=j13 || v3 */
|
||||
#define STLINK_F_HAS_GETLASTRWSTATUS2 BIT(1) /* v2>=j15 || v3 */
|
||||
#define STLINK_F_HAS_SWD_SET_FREQ BIT(2) /* v2>=j22 */
|
||||
#define STLINK_F_HAS_JTAG_SET_FREQ BIT(3) /* v2>=j24 */
|
||||
#define STLINK_F_QUIRK_JTAG_DP_READ BIT(4) /* v2>=j24 && v2<j32 */
|
||||
#define STLINK_F_HAS_DAP_REG BIT(5) /* v2>=j24 || v3 */
|
||||
#define STLINK_F_HAS_MEM_16BIT BIT(6) /* v2>=j26 || v3 */
|
||||
#define STLINK_F_HAS_AP_INIT BIT(7) /* v2>=j28 || v3 */
|
||||
#define STLINK_F_FIX_CLOSE_AP BIT(8) /* v2>=j29 || v3 */
|
||||
#define STLINK_F_HAS_DPBANKSEL BIT(9) /* v2>=j32 || v3>=j2 */
|
||||
#define STLINK_F_HAS_RW8_512BYTES BIT(10) /* v3>=j6 */
|
||||
|
||||
/* aliases */
|
||||
#define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE
|
||||
|
@ -3904,7 +3904,7 @@ static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg,
|
|||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
data = data ? : &dummy;
|
||||
data = data ? data : &dummy;
|
||||
if (stlink_dap_handle->version.flags & STLINK_F_QUIRK_JTAG_DP_READ
|
||||
&& stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG) {
|
||||
/* Quirk required in JTAG. Read RDBUFF to get the data */
|
||||
|
@ -3969,7 +3969,7 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned reg,
|
|||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
data = data ? : &dummy;
|
||||
data = data ? data : &dummy;
|
||||
retval = stlink_read_dap_register(stlink_dap_handle, ap->ap_num, reg,
|
||||
data);
|
||||
dap->stlink_flush_ap_write = false;
|
||||
|
|
|
@ -561,8 +561,8 @@ static int ublast_read_byteshifted_tdos(uint8_t *buf, int nb_bytes)
|
|||
* - first bit is stored in byte0, bit0 (LSB)
|
||||
* - second bit is stored in byte0, bit 1
|
||||
* ...
|
||||
* - eight bit is sotred in byte0, bit 7
|
||||
* - ninth bit is sotred in byte1, bit 0
|
||||
* - eight bit is stored in byte0, bit 7
|
||||
* - ninth bit is stored in byte1, bit 0
|
||||
* - etc ...
|
||||
*
|
||||
* Returns ERROR_OK if OK, ERROR_xxx if a read error occurred
|
||||
|
|
|
@ -124,7 +124,7 @@ void versaloon_free_want_pos(void)
|
|||
}
|
||||
versaloon_want_pos = NULL;
|
||||
|
||||
for (i = 0; i < dimof(versaloon_pending); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(versaloon_pending); i++) {
|
||||
tmp = versaloon_pending[i].pos;
|
||||
while (tmp != NULL) {
|
||||
free_tmp = tmp;
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#define PARAM_CHECK 1
|
||||
|
||||
#define sleep_ms(ms) jtag_sleep((ms) * 1000)
|
||||
#define dimof(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#define TO_STR(name) #name
|
||||
|
||||
#define RESULT int
|
||||
|
|
|
@ -356,7 +356,7 @@ static bool usb_connect(void)
|
|||
/* Check for device vid/pid match */
|
||||
libusb_get_device_descriptor(list[i], &desc);
|
||||
match = false;
|
||||
for (device = 0; device < sizeof(vids)/sizeof(vids[0]); device++) {
|
||||
for (device = 0; device < ARRAY_SIZE(vids); device++) {
|
||||
if (desc.idVendor == vids[device] &&
|
||||
desc.idProduct == pids[device]) {
|
||||
match = true;
|
||||
|
|
|
@ -359,7 +359,7 @@ static const struct command_registration hl_interface_command_handlers[] = {
|
|||
.handler = &hl_interface_handle_vid_pid_command,
|
||||
.mode = COMMAND_CONFIG,
|
||||
.help = "the vendor and product ID of the adapter",
|
||||
.usage = "(vid pid)* ",
|
||||
.usage = "(vid pid)*",
|
||||
},
|
||||
{
|
||||
.name = "hla_stlink_backend",
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
#include <transport/transport.h>
|
||||
#include <helper/time_support.h>
|
||||
|
||||
static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
|
||||
static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi,
|
||||
struct jtag_tap *pTap)
|
||||
{
|
||||
jim_wide w;
|
||||
int e = Jim_GetOpt_Wide(goi, &w);
|
||||
int e = jim_getopt_wide(goi, &w);
|
||||
if (e != JIM_OK) {
|
||||
Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
|
||||
n->name);
|
||||
|
@ -60,14 +60,14 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
|
|||
#define NTAP_OPT_EXPECTED_ID 5
|
||||
#define NTAP_OPT_VERSION 6
|
||||
|
||||
static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi)
|
||||
static int jim_hl_newtap_cmd(struct jim_getopt_info *goi)
|
||||
{
|
||||
struct jtag_tap *pTap;
|
||||
int x;
|
||||
int e;
|
||||
Jim_Nvp *n;
|
||||
struct jim_nvp *n;
|
||||
char *cp;
|
||||
const Jim_Nvp opts[] = {
|
||||
const struct jim_nvp opts[] = {
|
||||
{ .name = "-irlen", .value = NTAP_OPT_IRLEN },
|
||||
{ .name = "-irmask", .value = NTAP_OPT_IRMASK },
|
||||
{ .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE },
|
||||
|
@ -95,10 +95,10 @@ static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi)
|
|||
}
|
||||
|
||||
const char *tmp;
|
||||
Jim_GetOpt_String(goi, &tmp, NULL);
|
||||
jim_getopt_string(goi, &tmp, NULL);
|
||||
pTap->chip = strdup(tmp);
|
||||
|
||||
Jim_GetOpt_String(goi, &tmp, NULL);
|
||||
jim_getopt_string(goi, &tmp, NULL);
|
||||
pTap->tapname = strdup(tmp);
|
||||
|
||||
/* name + dot + name + null */
|
||||
|
@ -111,9 +111,9 @@ static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi)
|
|||
pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);
|
||||
|
||||
while (goi->argc) {
|
||||
e = Jim_GetOpt_Nvp(goi, opts, &n);
|
||||
e = jim_getopt_nvp(goi, opts, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(goi, opts, 0);
|
||||
jim_getopt_nvp_unknown(goi, opts, 0);
|
||||
free(cp);
|
||||
free(pTap);
|
||||
return e;
|
||||
|
@ -132,7 +132,7 @@ static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi)
|
|||
case NTAP_OPT_IRMASK:
|
||||
case NTAP_OPT_IRCAPTURE:
|
||||
/* dummy read to ignore the next argument */
|
||||
Jim_GetOpt_Wide(goi, NULL);
|
||||
jim_getopt_wide(goi, NULL);
|
||||
break;
|
||||
} /* switch (n->value) */
|
||||
} /* while (goi->argc) */
|
||||
|
@ -146,7 +146,7 @@ static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi)
|
|||
|
||||
int jim_hl_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
return jim_hl_newtap_cmd(&goi);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ hl_transport_jtag_subcommand_handlers[] = {
|
|||
.help = "Create a new TAP instance named basename.tap_type, "
|
||||
"and appends it to the scan chain.",
|
||||
.usage = "basename tap_type '-irlen' count "
|
||||
"['-expected_id' number] ",
|
||||
"['-expected_id' number]",
|
||||
},
|
||||
{
|
||||
.name = "init",
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* interface functions, instead of the built-in asynchronous driver
|
||||
* module that is used by the standard JTAG interface drivers.
|
||||
*
|
||||
* In addtion to the functions defined in the @c minidriver.h file, the
|
||||
* In addition to the functions defined in the @c minidriver.h file, the
|
||||
* @c jtag_minidriver.h file must declare the following functions (or
|
||||
* define static inline versions of them):
|
||||
* - jtag_add_callback
|
||||
|
|
|
@ -81,9 +81,10 @@ proc srst_asserted {} {
|
|||
# measure actual JTAG clock
|
||||
proc measure_clk {} {
|
||||
set start_time [ms];
|
||||
set iterations 10000000;
|
||||
set iterations 10000000;
|
||||
runtest $iterations;
|
||||
echo "Running at more than [expr $iterations.0 / ([ms]-$start_time)] kHz";
|
||||
set speed [expr "$iterations.0 / ([ms] - $start_time)"]
|
||||
echo "Running at more than $speed kHz";
|
||||
}
|
||||
|
||||
add_help_text measure_clk "Runs a test to measure the JTAG clk. Useful with RCLK / RTCK."
|
||||
|
@ -119,6 +120,7 @@ proc jtag_ntrst_assert_width args {
|
|||
#
|
||||
# FIXME phase these aids out after some releases
|
||||
#
|
||||
lappend _telnet_autocomplete_skip jtag_reset
|
||||
proc jtag_reset args {
|
||||
echo "DEPRECATED! use 'adapter \[de\]assert' not 'jtag_reset'"
|
||||
switch $args {
|
||||
|
@ -135,51 +137,61 @@ proc jtag_reset args {
|
|||
}
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip adapter_khz
|
||||
proc adapter_khz args {
|
||||
echo "DEPRECATED! use 'adapter speed' not 'adapter_khz'"
|
||||
eval adapter speed $args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip adapter_name
|
||||
proc adapter_name args {
|
||||
echo "DEPRECATED! use 'adapter name' not 'adapter_name'"
|
||||
eval adapter name $args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip adapter_nsrst_delay
|
||||
proc adapter_nsrst_delay args {
|
||||
echo "DEPRECATED! use 'adapter srst delay' not 'adapter_nsrst_delay'"
|
||||
eval adapter srst delay $args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip adapter_nsrst_assert_width
|
||||
proc adapter_nsrst_assert_width args {
|
||||
echo "DEPRECATED! use 'adapter srst pulse_width' not 'adapter_nsrst_assert_width'"
|
||||
eval adapter srst pulse_width $args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip interface
|
||||
proc interface args {
|
||||
echo "DEPRECATED! use 'adapter driver' not 'interface'"
|
||||
eval adapter driver $args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip interface_transports
|
||||
proc interface_transports args {
|
||||
echo "DEPRECATED! use 'adapter transports' not 'interface_transports'"
|
||||
eval adapter transports $args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip interface_list
|
||||
proc interface_list args {
|
||||
echo "DEPRECATED! use 'adapter list' not 'interface_list'"
|
||||
eval adapter list $args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip ftdi_location
|
||||
proc ftdi_location args {
|
||||
echo "DEPRECATED! use 'adapter usb location' not 'ftdi_location'"
|
||||
eval adapter usb location $args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip xds110_serial
|
||||
proc xds110_serial args {
|
||||
echo "DEPRECATED! use 'xds110 serial' not 'xds110_serial'"
|
||||
eval xds110 serial $args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip xds110_supply_voltage
|
||||
proc xds110_supply_voltage args {
|
||||
echo "DEPRECATED! use 'xds110 supply' not 'xds110_supply_voltage'"
|
||||
eval xds110 supply $args
|
||||
|
@ -189,6 +201,7 @@ proc hla {cmd args} {
|
|||
tailcall "hla $cmd" {*}$args
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip "hla newtap"
|
||||
proc "hla newtap" {args} {
|
||||
echo "DEPRECATED! use 'swj_newdap' not 'hla newtap'"
|
||||
eval swj_newdap $args
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
* Holds support for accessing JTAG-specific mechanisms from TCl scripts.
|
||||
*/
|
||||
|
||||
static const Jim_Nvp nvp_jtag_tap_event[] = {
|
||||
static const struct jim_nvp nvp_jtag_tap_event[] = {
|
||||
{ .value = JTAG_TRST_ASSERTED, .name = "post-reset" },
|
||||
{ .value = JTAG_TAP_EVENT_SETUP, .name = "setup" },
|
||||
{ .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" },
|
||||
|
@ -310,24 +310,24 @@ enum jtag_tap_cfg_param {
|
|||
JCFG_IDCODE,
|
||||
};
|
||||
|
||||
static Jim_Nvp nvp_config_opts[] = {
|
||||
static struct jim_nvp nvp_config_opts[] = {
|
||||
{ .name = "-event", .value = JCFG_EVENT },
|
||||
{ .name = "-idcode", .value = JCFG_IDCODE },
|
||||
|
||||
{ .name = NULL, .value = -1 }
|
||||
};
|
||||
|
||||
static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap *tap)
|
||||
static int jtag_tap_configure_event(struct jim_getopt_info *goi, struct jtag_tap *tap)
|
||||
{
|
||||
if (goi->argc == 0) {
|
||||
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event <event-name> ...");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
Jim_Nvp *n;
|
||||
int e = Jim_GetOpt_Nvp(goi, nvp_jtag_tap_event, &n);
|
||||
struct jim_nvp *n;
|
||||
int e = jim_getopt_nvp(goi, nvp_jtag_tap_event, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(goi, nvp_jtag_tap_event, 1);
|
||||
jim_getopt_nvp_unknown(goi, nvp_jtag_tap_event, 1);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -369,7 +369,7 @@ static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap *tap)
|
|||
jteap->event = n->value;
|
||||
|
||||
Jim_Obj *o;
|
||||
Jim_GetOpt_Obj(goi, &o);
|
||||
jim_getopt_obj(goi, &o);
|
||||
jteap->body = Jim_DuplicateObj(goi->interp, o);
|
||||
Jim_IncrRefCount(jteap->body);
|
||||
|
||||
|
@ -386,16 +386,16 @@ static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap *tap)
|
|||
return JIM_OK;
|
||||
}
|
||||
|
||||
static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap *tap)
|
||||
static int jtag_tap_configure_cmd(struct jim_getopt_info *goi, struct jtag_tap *tap)
|
||||
{
|
||||
/* parse config or cget options */
|
||||
while (goi->argc > 0) {
|
||||
Jim_SetEmptyResult(goi->interp);
|
||||
|
||||
Jim_Nvp *n;
|
||||
int e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
|
||||
struct jim_nvp *n;
|
||||
int e = jim_getopt_nvp(goi, nvp_config_opts, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
|
||||
jim_getopt_nvp_unknown(goi, nvp_config_opts, 0);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -439,11 +439,11 @@ static int is_bad_irval(int ir_length, jim_wide w)
|
|||
return (w & v) != 0;
|
||||
}
|
||||
|
||||
static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
|
||||
static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi,
|
||||
struct jtag_tap *pTap)
|
||||
{
|
||||
jim_wide w;
|
||||
int e = Jim_GetOpt_Wide(goi, &w);
|
||||
int e = jim_getopt_wide(goi, &w);
|
||||
if (e != JIM_OK) {
|
||||
Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name);
|
||||
return e;
|
||||
|
@ -470,11 +470,11 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
|
|||
#define NTAP_OPT_EXPECTED_ID 5
|
||||
#define NTAP_OPT_VERSION 6
|
||||
|
||||
static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi,
|
||||
static int jim_newtap_ir_param(struct jim_nvp *n, struct jim_getopt_info *goi,
|
||||
struct jtag_tap *pTap)
|
||||
{
|
||||
jim_wide w;
|
||||
int e = Jim_GetOpt_Wide(goi, &w);
|
||||
int e = jim_getopt_wide(goi, &w);
|
||||
if (e != JIM_OK) {
|
||||
Jim_SetResultFormatted(goi->interp,
|
||||
"option: %s bad parameter", n->name);
|
||||
|
@ -516,14 +516,14 @@ static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi,
|
|||
return JIM_OK;
|
||||
}
|
||||
|
||||
static int jim_newtap_cmd(Jim_GetOptInfo *goi)
|
||||
static int jim_newtap_cmd(struct jim_getopt_info *goi)
|
||||
{
|
||||
struct jtag_tap *pTap;
|
||||
int x;
|
||||
int e;
|
||||
Jim_Nvp *n;
|
||||
struct jim_nvp *n;
|
||||
char *cp;
|
||||
const Jim_Nvp opts[] = {
|
||||
const struct jim_nvp opts[] = {
|
||||
{ .name = "-irlen", .value = NTAP_OPT_IRLEN },
|
||||
{ .name = "-irmask", .value = NTAP_OPT_IRMASK },
|
||||
{ .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE },
|
||||
|
@ -550,10 +550,10 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
|
|||
}
|
||||
|
||||
const char *tmp;
|
||||
Jim_GetOpt_String(goi, &tmp, NULL);
|
||||
jim_getopt_string(goi, &tmp, NULL);
|
||||
pTap->chip = strdup(tmp);
|
||||
|
||||
Jim_GetOpt_String(goi, &tmp, NULL);
|
||||
jim_getopt_string(goi, &tmp, NULL);
|
||||
pTap->tapname = strdup(tmp);
|
||||
|
||||
/* name + dot + name + null */
|
||||
|
@ -580,9 +580,9 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
|
|||
pTap->ir_capture_value = 0x01;
|
||||
|
||||
while (goi->argc) {
|
||||
e = Jim_GetOpt_Nvp(goi, opts, &n);
|
||||
e = jim_getopt_nvp(goi, opts, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(goi, opts, 0);
|
||||
jim_getopt_nvp_unknown(goi, opts, 0);
|
||||
free(cp);
|
||||
free(pTap);
|
||||
return e;
|
||||
|
@ -644,7 +644,7 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)
|
|||
if (jteap->event != e)
|
||||
continue;
|
||||
|
||||
Jim_Nvp *nvp = Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e);
|
||||
struct jim_nvp *nvp = jim_nvp_value2name_simple(nvp_jtag_tap_event, e);
|
||||
LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
|
||||
tap->dotted_name, e, nvp->name,
|
||||
Jim_GetString(jteap->body, NULL));
|
||||
|
@ -678,8 +678,8 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)
|
|||
|
||||
static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc-1, argv + 1);
|
||||
if (goi.argc != 0) {
|
||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
|
||||
return JIM_ERR;
|
||||
|
@ -697,8 +697,8 @@ static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
|||
static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
int e = ERROR_OK;
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc-1, argv + 1);
|
||||
if (goi.argc != 0) {
|
||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
|
||||
return JIM_ERR;
|
||||
|
@ -719,8 +719,8 @@ static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const
|
|||
|
||||
int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc-1, argv + 1);
|
||||
return jim_newtap_cmd(&goi);
|
||||
}
|
||||
|
||||
|
@ -759,8 +759,8 @@ int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
|||
{
|
||||
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);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc-1, argv + 1);
|
||||
if (goi.argc != 1) {
|
||||
Jim_SetResultFormatted(goi.interp, "usage: %s <name>", cmd_name);
|
||||
return JIM_ERR;
|
||||
|
@ -797,8 +797,8 @@ int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
|||
{
|
||||
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);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc-1, argv + 1);
|
||||
goi.isconfigure = !strcmp(cmd_name, "configure");
|
||||
if (goi.argc < 2 + goi.isconfigure) {
|
||||
Jim_WrongNumArgs(goi.interp, 0, NULL,
|
||||
|
@ -809,7 +809,7 @@ int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
|||
struct jtag_tap *t;
|
||||
|
||||
Jim_Obj *o;
|
||||
Jim_GetOpt_Obj(&goi, &o);
|
||||
jim_getopt_obj(&goi, &o);
|
||||
t = jtag_tap_by_jim_obj(goi.interp, o);
|
||||
if (t == NULL)
|
||||
return JIM_ERR;
|
||||
|
@ -819,8 +819,8 @@ int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
|||
|
||||
static int jim_jtag_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc-1, argv + 1);
|
||||
if (goi.argc != 0) {
|
||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
|
||||
return JIM_ERR;
|
||||
|
@ -887,7 +887,7 @@ static const struct command_registration jtag_subcommand_handlers[] = {
|
|||
"['-expected_id' number] "
|
||||
"['-ignore-version'] "
|
||||
"['-ircapture' number] "
|
||||
"['-mask' number] ",
|
||||
"['-mask' number]",
|
||||
},
|
||||
{
|
||||
.name = "tapisenabled",
|
||||
|
@ -1353,7 +1353,7 @@ static const struct command_registration jtag_command_handlers[] = {
|
|||
.mode = COMMAND_ANY,
|
||||
.help = "Wait for an SRST deassert. "
|
||||
"Useful for cases where you need something to happen within ms "
|
||||
"of an srst deassert. Timeout in ms ",
|
||||
"of an srst deassert. Timeout in ms",
|
||||
.usage = "ms",
|
||||
},
|
||||
{
|
||||
|
|
|
@ -205,8 +205,6 @@ static const struct FreeRTOS_params FreeRTOS_params_list[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#define FREERTOS_NUM_PARAMS ((int)(sizeof(FreeRTOS_params_list)/sizeof(struct FreeRTOS_params)))
|
||||
|
||||
static bool FreeRTOS_detect_rtos(struct target *target);
|
||||
static int FreeRTOS_create(struct target *target);
|
||||
static int FreeRTOS_update_threads(struct rtos *rtos);
|
||||
|
@ -878,12 +876,12 @@ static bool FreeRTOS_detect_rtos(struct target *target)
|
|||
|
||||
static int FreeRTOS_create(struct target *target)
|
||||
{
|
||||
int i = 0;
|
||||
while ((i < FREERTOS_NUM_PARAMS) &&
|
||||
(0 != strcmp(FreeRTOS_params_list[i].target_name, target->type->name))) {
|
||||
unsigned int i = 0;
|
||||
while (i < ARRAY_SIZE(FreeRTOS_params_list) &&
|
||||
strcmp(FreeRTOS_params_list[i].target_name, target->type->name) != 0) {
|
||||
i++;
|
||||
}
|
||||
if (i >= FREERTOS_NUM_PARAMS) {
|
||||
if (i >= ARRAY_SIZE(FreeRTOS_params_list)) {
|
||||
LOG_ERROR("Could not find target in FreeRTOS compatibility list");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -905,5 +903,5 @@ static int FreeRTOS_create(struct target *target)
|
|||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ noinst_LTLIBRARIES += %D%/librtos.la
|
|||
%D%/uCOS-III.c \
|
||||
%D%/nuttx.c \
|
||||
%D%/hwthread.c \
|
||||
%D%/zephyr.c \
|
||||
%D%/riot.c \
|
||||
%D%/rtos.h \
|
||||
%D%/rtos_standard_stackings.h \
|
||||
|
|
|
@ -65,7 +65,7 @@ static const struct ThreadX_thread_state ThreadX_thread_states[] = {
|
|||
{ 13, "Waiting - Mutex" },
|
||||
};
|
||||
|
||||
#define THREADX_NUM_STATES (sizeof(ThreadX_thread_states)/sizeof(struct ThreadX_thread_state))
|
||||
#define THREADX_NUM_STATES ARRAY_SIZE(ThreadX_thread_states)
|
||||
|
||||
#define ARM926EJS_REGISTERS_SIZE_SOLICITED (11 * 4)
|
||||
static const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_solicited[] = {
|
||||
|
@ -177,8 +177,6 @@ static const struct ThreadX_params ThreadX_params_list[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#define THREADX_NUM_PARAMS ((int)(sizeof(ThreadX_params_list)/sizeof(struct ThreadX_params)))
|
||||
|
||||
enum ThreadX_symbol_values {
|
||||
ThreadX_VAL_tx_thread_current_ptr = 0,
|
||||
ThreadX_VAL_tx_thread_created_ptr = 1,
|
||||
|
@ -597,18 +595,14 @@ static int ThreadX_get_thread_detail(struct rtos *rtos,
|
|||
|
||||
static int ThreadX_create(struct target *target)
|
||||
{
|
||||
int i = 0;
|
||||
while ((i < THREADX_NUM_PARAMS) &&
|
||||
(0 != strcmp(ThreadX_params_list[i].target_name, target->type->name))) {
|
||||
i++;
|
||||
}
|
||||
if (i >= THREADX_NUM_PARAMS) {
|
||||
LOG_ERROR("Could not find target in ThreadX compatibility list");
|
||||
return -1;
|
||||
}
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(ThreadX_params_list); i++)
|
||||
if (strcmp(ThreadX_params_list[i].target_name, target->type->name) == 0) {
|
||||
target->rtos->rtos_specific_params = (void *)&ThreadX_params_list[i];
|
||||
target->rtos->current_thread = 0;
|
||||
target->rtos->thread_details = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
target->rtos->rtos_specific_params = (void *) &ThreadX_params_list[i];
|
||||
target->rtos->current_thread = 0;
|
||||
target->rtos->thread_details = NULL;
|
||||
return 0;
|
||||
LOG_ERROR("Could not find target in ThreadX compatibility list");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ static const char * const chibios_thread_states[] = { "READY", "CURRENT",
|
|||
"WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "FINAL"
|
||||
};
|
||||
|
||||
#define CHIBIOS_NUM_STATES (sizeof(chibios_thread_states)/sizeof(char *))
|
||||
#define CHIBIOS_NUM_STATES ARRAY_SIZE(chibios_thread_states)
|
||||
|
||||
/* Maximum ChibiOS thread name. There is no real limit set by ChibiOS but 64
|
||||
* chars ought to be enough.
|
||||
|
@ -100,7 +100,6 @@ static struct chibios_params chibios_params_list[] = {
|
|||
NULL, /* stacking_info */
|
||||
}
|
||||
};
|
||||
#define CHIBIOS_NUM_PARAMS ((int)(sizeof(chibios_params_list)/sizeof(struct chibios_params)))
|
||||
|
||||
static bool chibios_detect_rtos(struct target *target);
|
||||
static int chibios_create(struct target *target);
|
||||
|
@ -529,17 +528,13 @@ static bool chibios_detect_rtos(struct target *target)
|
|||
|
||||
static int chibios_create(struct target *target)
|
||||
{
|
||||
int i = 0;
|
||||
while ((i < CHIBIOS_NUM_PARAMS) &&
|
||||
(0 != strcmp(chibios_params_list[i].target_name, target->type->name))) {
|
||||
i++;
|
||||
}
|
||||
if (i >= CHIBIOS_NUM_PARAMS) {
|
||||
LOG_WARNING("Could not find target \"%s\" in ChibiOS compatibility "
|
||||
"list", target->type->name);
|
||||
return -1;
|
||||
}
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(chibios_params_list); i++)
|
||||
if (strcmp(chibios_params_list[i].target_name, target->type->name) == 0) {
|
||||
target->rtos->rtos_specific_params = (void *)&chibios_params_list[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
target->rtos->rtos_specific_params = (void *) &chibios_params_list[i];
|
||||
return 0;
|
||||
LOG_WARNING("Could not find target \"%s\" in ChibiOS compatibility "
|
||||
"list", target->type->name);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ static const struct eCos_thread_state eCos_thread_states[] = {
|
|||
{ 16, "Exited" }
|
||||
};
|
||||
|
||||
#define ECOS_NUM_STATES (sizeof(eCos_thread_states)/sizeof(struct eCos_thread_state))
|
||||
#define ECOS_NUM_STATES ARRAY_SIZE(eCos_thread_states)
|
||||
|
||||
struct eCos_params {
|
||||
const char *target_name;
|
||||
|
@ -73,8 +73,6 @@ static const struct eCos_params eCos_params_list[] = {
|
|||
}
|
||||
};
|
||||
|
||||
#define ECOS_NUM_PARAMS ((int)(sizeof(eCos_params_list)/sizeof(struct eCos_params)))
|
||||
|
||||
enum eCos_symbol_values {
|
||||
eCos_VAL_thread_list = 0,
|
||||
eCos_VAL_current_thread_ptr = 1
|
||||
|
@ -375,18 +373,14 @@ static bool eCos_detect_rtos(struct target *target)
|
|||
|
||||
static int eCos_create(struct target *target)
|
||||
{
|
||||
int i = 0;
|
||||
while ((i < ECOS_NUM_PARAMS) &&
|
||||
(0 != strcmp(eCos_params_list[i].target_name, target->type->name))) {
|
||||
i++;
|
||||
}
|
||||
if (i >= ECOS_NUM_PARAMS) {
|
||||
LOG_ERROR("Could not find target in eCos compatibility list");
|
||||
return -1;
|
||||
}
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(eCos_params_list); i++)
|
||||
if (strcmp(eCos_params_list[i].target_name, target->type->name) == 0) {
|
||||
target->rtos->rtos_specific_params = (void *)&eCos_params_list[i];
|
||||
target->rtos->current_thread = 0;
|
||||
target->rtos->thread_details = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
target->rtos->rtos_specific_params = (void *) &eCos_params_list[i];
|
||||
target->rtos->current_thread = 0;
|
||||
target->rtos->thread_details = NULL;
|
||||
return 0;
|
||||
LOG_ERROR("Could not find target in eCos compatibility list");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ static int mqx_is_scheduler_running(
|
|||
return ERROR_FAIL;
|
||||
}
|
||||
/* check first member, the '_mqx_kernel_data->ADDRESSING_CAPABILITY'.
|
||||
it supose to be set to value 8 */
|
||||
it suppose to be set to value 8 */
|
||||
if (capability_value != 8) {
|
||||
LOG_WARNING("MQX RTOS - value of '_mqx_kernel_data->ADDRESSING_CAPABILITY' contains invalid value");
|
||||
return ERROR_FAIL;
|
||||
|
@ -267,8 +267,7 @@ static int mqx_create(
|
|||
)
|
||||
{
|
||||
/* check target name against supported architectures */
|
||||
int mqx_params_list_num = (sizeof(mqx_params_list)/sizeof(struct mqx_params));
|
||||
for (int i = 0; i < mqx_params_list_num; i++) {
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(mqx_params_list); i++) {
|
||||
if (0 == strcmp(mqx_params_list[i].target_name, target->type->name)) {
|
||||
target->rtos->rtos_specific_params = (void *)&mqx_params_list[i];
|
||||
/* LOG_DEBUG("MQX RTOS - valid architecture: %s", target->type->name); */
|
||||
|
@ -351,7 +350,7 @@ static int mqx_update_threads(
|
|||
uint8_t task_name[MQX_THREAD_NAME_LENGTH + 1];
|
||||
uint32_t task_addr = 0, task_template = 0, task_state = 0;
|
||||
uint32_t task_name_addr = 0, task_id = 0, task_errno = 0;
|
||||
uint32_t state_index = 0, state_max = 0;
|
||||
uint32_t state_index = 0;
|
||||
uint32_t extra_info_length = 0;
|
||||
char *state_name = "Unknown";
|
||||
|
||||
|
@ -412,8 +411,7 @@ static int mqx_update_threads(
|
|||
}
|
||||
task_state &= MQX_TASK_STATE_MASK;
|
||||
/* and search for defined state */
|
||||
state_max = (sizeof(mqx_states)/sizeof(struct mqx_state));
|
||||
for (state_index = 0; (state_index < state_max); state_index++) {
|
||||
for (state_index = 0; state_index < ARRAY_SIZE(mqx_states); state_index++) {
|
||||
if (mqx_states[state_index].state == task_state) {
|
||||
state_name = mqx_states[state_index].name;
|
||||
break;
|
||||
|
|
|
@ -312,7 +312,7 @@ static int nuttx_update_threads(struct rtos *rtos)
|
|||
|
||||
state = tcb.dat[state_offset - 8];
|
||||
thread->extra_info_str = NULL;
|
||||
if (state < sizeof(task_state_str)/sizeof(char *)) {
|
||||
if (state < ARRAY_SIZE(task_state_str)) {
|
||||
thread->extra_info_str = malloc(256);
|
||||
snprintf(thread->extra_info_str, 256, "pid:%d, %s",
|
||||
tcb.dat[pid_offset - 8] |
|
||||
|
|
|
@ -39,6 +39,7 @@ extern struct rtos_type uCOS_III_rtos;
|
|||
extern struct rtos_type nuttx_rtos;
|
||||
extern struct rtos_type hwthread_rtos;
|
||||
extern struct rtos_type riot_rtos;
|
||||
extern struct rtos_type zephyr_rtos;
|
||||
|
||||
static struct rtos_type *rtos_types[] = {
|
||||
&ThreadX_rtos,
|
||||
|
@ -52,6 +53,7 @@ static struct rtos_type *rtos_types[] = {
|
|||
&uCOS_III_rtos,
|
||||
&nuttx_rtos,
|
||||
&riot_rtos,
|
||||
&zephyr_rtos,
|
||||
/* keep this as last, as it always matches with rtos auto */
|
||||
&hwthread_rtos,
|
||||
NULL
|
||||
|
@ -126,7 +128,7 @@ static int os_alloc_create(struct target *target, struct rtos_type *ostype,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int rtos_create(Jim_GetOptInfo *goi, struct target *target)
|
||||
int rtos_create(struct jim_getopt_info *goi, struct target *target)
|
||||
{
|
||||
int x;
|
||||
const char *cp;
|
||||
|
@ -142,7 +144,7 @@ int rtos_create(Jim_GetOptInfo *goi, struct target *target)
|
|||
|
||||
os_free(target);
|
||||
|
||||
e = Jim_GetOpt_String(goi, &cp, NULL);
|
||||
e = jim_getopt_string(goi, &cp, NULL);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ struct rtos_register_stacking {
|
|||
|
||||
#define GDB_THREAD_PACKET_NOT_CONSUMED (-40)
|
||||
|
||||
int rtos_create(Jim_GetOptInfo *goi, struct target *target);
|
||||
int rtos_create(struct jim_getopt_info *goi, struct target *target);
|
||||
void rtos_destroy(struct target *target);
|
||||
int rtos_set_reg(struct connection *connection, int reg_num,
|
||||
uint8_t *reg_value);
|
||||
|
|
|
@ -0,0 +1,788 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2017 by Intel Corporation
|
||||
* Leandro Pereira <leandro.pereira@intel.com>
|
||||
* Daniel Glöckner <dg@emlix.com>*
|
||||
* Copyright (C) 2021 by Synopsys, Inc.
|
||||
* Evgeniy Didin <didin@synopsys.com>
|
||||
* *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <helper/time_support.h>
|
||||
#include <jtag/jtag.h>
|
||||
|
||||
#include "helper/log.h"
|
||||
#include "helper/types.h"
|
||||
#include "rtos.h"
|
||||
#include "rtos_standard_stackings.h"
|
||||
#include "target/target.h"
|
||||
#include "target/target_type.h"
|
||||
#include "target/armv7m.h"
|
||||
#include "target/arc.h"
|
||||
|
||||
#define UNIMPLEMENTED 0xFFFFFFFFU
|
||||
|
||||
/* ARC specific defines */
|
||||
#define ARC_AUX_SEC_BUILD_REG 0xdb
|
||||
#define ARC_REG_NUM 38
|
||||
|
||||
/* ARM specific defines */
|
||||
#define ARM_XPSR_OFFSET 28
|
||||
|
||||
struct zephyr_thread {
|
||||
uint32_t ptr, next_ptr;
|
||||
uint32_t entry;
|
||||
uint32_t stack_pointer;
|
||||
uint8_t state;
|
||||
uint8_t user_options;
|
||||
int8_t prio;
|
||||
char name[64];
|
||||
};
|
||||
|
||||
enum zephyr_offsets {
|
||||
OFFSET_VERSION,
|
||||
OFFSET_K_CURR_THREAD,
|
||||
OFFSET_K_THREADS,
|
||||
OFFSET_T_ENTRY,
|
||||
OFFSET_T_NEXT_THREAD,
|
||||
OFFSET_T_STATE,
|
||||
OFFSET_T_USER_OPTIONS,
|
||||
OFFSET_T_PRIO,
|
||||
OFFSET_T_STACK_POINTER,
|
||||
OFFSET_T_NAME,
|
||||
OFFSET_T_ARCH,
|
||||
OFFSET_T_PREEMPT_FLOAT,
|
||||
OFFSET_T_COOP_FLOAT,
|
||||
OFFSET_MAX
|
||||
};
|
||||
|
||||
struct zephyr_params {
|
||||
const char *target_name;
|
||||
uint8_t size_width;
|
||||
uint8_t pointer_width;
|
||||
uint32_t num_offsets;
|
||||
uint32_t offsets[OFFSET_MAX];
|
||||
const struct rtos_register_stacking *callee_saved_stacking;
|
||||
const struct rtos_register_stacking *cpu_saved_nofp_stacking;
|
||||
const struct rtos_register_stacking *cpu_saved_fp_stacking;
|
||||
int (*get_cpu_state)(struct rtos *rtos, target_addr_t *addr,
|
||||
struct zephyr_params *params,
|
||||
struct rtos_reg *callee_saved_reg_list,
|
||||
struct rtos_reg **reg_list, int *num_regs);
|
||||
};
|
||||
|
||||
static const struct stack_register_offset arm_callee_saved[] = {
|
||||
{ ARMV7M_R13, 32, 32 },
|
||||
{ ARMV7M_R4, 0, 32 },
|
||||
{ ARMV7M_R5, 4, 32 },
|
||||
{ ARMV7M_R6, 8, 32 },
|
||||
{ ARMV7M_R7, 12, 32 },
|
||||
{ ARMV7M_R8, 16, 32 },
|
||||
{ ARMV7M_R9, 20, 32 },
|
||||
{ ARMV7M_R10, 24, 32 },
|
||||
{ ARMV7M_R11, 28, 32 },
|
||||
};
|
||||
|
||||
static const struct stack_register_offset arc_callee_saved[] = {
|
||||
{ ARC_R13, 0, 32 },
|
||||
{ ARC_R14, 4, 32 },
|
||||
{ ARC_R15, 8, 32 },
|
||||
{ ARC_R16, 12, 32 },
|
||||
{ ARC_R17, 16, 32 },
|
||||
{ ARC_R18, 20, 32 },
|
||||
{ ARC_R19, 24, 32 },
|
||||
{ ARC_R20, 28, 32 },
|
||||
{ ARC_R21, 32, 32 },
|
||||
{ ARC_R22, 36, 32 },
|
||||
{ ARC_R23, 40, 32 },
|
||||
{ ARC_R24, 44, 32 },
|
||||
{ ARC_R25, 48, 32 },
|
||||
{ ARC_GP, 52, 32 },
|
||||
{ ARC_FP, 56, 32 },
|
||||
{ ARC_R30, 60, 32 }
|
||||
};
|
||||
static const struct rtos_register_stacking arm_callee_saved_stacking = {
|
||||
.stack_registers_size = 36,
|
||||
.stack_growth_direction = -1,
|
||||
.num_output_registers = ARRAY_SIZE(arm_callee_saved),
|
||||
.register_offsets = arm_callee_saved,
|
||||
};
|
||||
|
||||
static const struct rtos_register_stacking arc_callee_saved_stacking = {
|
||||
.stack_registers_size = 64,
|
||||
.stack_growth_direction = -1,
|
||||
.num_output_registers = ARRAY_SIZE(arc_callee_saved),
|
||||
.register_offsets = arc_callee_saved,
|
||||
};
|
||||
|
||||
static const struct stack_register_offset arm_cpu_saved[] = {
|
||||
{ ARMV7M_R0, 0, 32 },
|
||||
{ ARMV7M_R1, 4, 32 },
|
||||
{ ARMV7M_R2, 8, 32 },
|
||||
{ ARMV7M_R3, 12, 32 },
|
||||
{ ARMV7M_R4, -1, 32 },
|
||||
{ ARMV7M_R5, -1, 32 },
|
||||
{ ARMV7M_R6, -1, 32 },
|
||||
{ ARMV7M_R7, -1, 32 },
|
||||
{ ARMV7M_R8, -1, 32 },
|
||||
{ ARMV7M_R9, -1, 32 },
|
||||
{ ARMV7M_R10, -1, 32 },
|
||||
{ ARMV7M_R11, -1, 32 },
|
||||
{ ARMV7M_R12, 16, 32 },
|
||||
{ ARMV7M_R13, -2, 32 },
|
||||
{ ARMV7M_R14, 20, 32 },
|
||||
{ ARMV7M_PC, 24, 32 },
|
||||
{ ARMV7M_xPSR, 28, 32 },
|
||||
};
|
||||
|
||||
static struct stack_register_offset arc_cpu_saved[] = {
|
||||
{ ARC_R0, -1, 32 },
|
||||
{ ARC_R1, -1, 32 },
|
||||
{ ARC_R2, -1, 32 },
|
||||
{ ARC_R3, -1, 32 },
|
||||
{ ARC_R4, -1, 32 },
|
||||
{ ARC_R5, -1, 32 },
|
||||
{ ARC_R6, -1, 32 },
|
||||
{ ARC_R7, -1, 32 },
|
||||
{ ARC_R8, -1, 32 },
|
||||
{ ARC_R9, -1, 32 },
|
||||
{ ARC_R10, -1, 32 },
|
||||
{ ARC_R11, -1, 32 },
|
||||
{ ARC_R12, -1, 32 },
|
||||
{ ARC_R13, -1, 32 },
|
||||
{ ARC_R14, -1, 32 },
|
||||
{ ARC_R15, -1, 32 },
|
||||
{ ARC_R16, -1, 32 },
|
||||
{ ARC_R17, -1, 32 },
|
||||
{ ARC_R18, -1, 32 },
|
||||
{ ARC_R19, -1, 32 },
|
||||
{ ARC_R20, -1, 32 },
|
||||
{ ARC_R21, -1, 32 },
|
||||
{ ARC_R22, -1, 32 },
|
||||
{ ARC_R23, -1, 32 },
|
||||
{ ARC_R24, -1, 32 },
|
||||
{ ARC_R25, -1, 32 },
|
||||
{ ARC_GP, -1, 32 },
|
||||
{ ARC_FP, -1, 32 },
|
||||
{ ARC_SP, -1, 32 },
|
||||
{ ARC_ILINK, -1, 32 },
|
||||
{ ARC_R30, -1, 32 },
|
||||
{ ARC_BLINK, 0, 32 },
|
||||
{ ARC_LP_COUNT, -1, 32 },
|
||||
{ ARC_PCL, -1, 32 },
|
||||
{ ARC_PC, -1, 32 },
|
||||
{ ARC_LP_START, -1, 32 },
|
||||
{ ARC_LP_END, -1, 32 },
|
||||
{ ARC_STATUS32, 4, 32 }
|
||||
};
|
||||
|
||||
|
||||
enum zephyr_symbol_values {
|
||||
ZEPHYR_VAL__KERNEL,
|
||||
ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS,
|
||||
ZEPHYR_VAL__KERNEL_OPENOCD_SIZE_T_SIZE,
|
||||
ZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS,
|
||||
ZEPHYR_VAL_COUNT
|
||||
};
|
||||
|
||||
static int64_t zephyr_cortex_m_stack_align(struct target *target,
|
||||
const uint8_t *stack_data,
|
||||
const struct rtos_register_stacking *stacking, int64_t stack_ptr)
|
||||
{
|
||||
return rtos_Cortex_M_stack_align(target, stack_data, stacking,
|
||||
stack_ptr, ARM_XPSR_OFFSET);
|
||||
}
|
||||
|
||||
static const struct rtos_register_stacking arm_cpu_saved_nofp_stacking = {
|
||||
.stack_registers_size = 32,
|
||||
.stack_growth_direction = -1,
|
||||
.num_output_registers = ARRAY_SIZE(arm_cpu_saved),
|
||||
.calculate_process_stack = zephyr_cortex_m_stack_align,
|
||||
.register_offsets = arm_cpu_saved,
|
||||
};
|
||||
|
||||
static const struct rtos_register_stacking arm_cpu_saved_fp_stacking = {
|
||||
.stack_registers_size = 32 + 18 * 4,
|
||||
.stack_growth_direction = -1,
|
||||
.num_output_registers = ARRAY_SIZE(arm_cpu_saved),
|
||||
.calculate_process_stack = zephyr_cortex_m_stack_align,
|
||||
.register_offsets = arm_cpu_saved,
|
||||
};
|
||||
|
||||
/* stack_registers_size is 8 because besides caller registers
|
||||
* there are only blink and Status32 registers on stack left */
|
||||
static struct rtos_register_stacking arc_cpu_saved_stacking = {
|
||||
.stack_registers_size = 8,
|
||||
.stack_growth_direction = -1,
|
||||
.num_output_registers = ARRAY_SIZE(arc_cpu_saved),
|
||||
.register_offsets = arc_cpu_saved,
|
||||
};
|
||||
|
||||
/* ARCv2 specific implementation */
|
||||
static int zephyr_get_arc_state(struct rtos *rtos, target_addr_t *addr,
|
||||
struct zephyr_params *params,
|
||||
struct rtos_reg *callee_saved_reg_list,
|
||||
struct rtos_reg **reg_list, int *num_regs)
|
||||
{
|
||||
|
||||
uint32_t real_stack_addr;
|
||||
int retval = 0;
|
||||
int num_callee_saved_regs;
|
||||
const struct rtos_register_stacking *stacking;
|
||||
|
||||
/* Getting real stack address from Kernel thread struct */
|
||||
retval = target_read_u32(rtos->target, *addr, &real_stack_addr);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
/* Getting callee registers */
|
||||
retval = rtos_generic_stack_read(rtos->target,
|
||||
params->callee_saved_stacking,
|
||||
real_stack_addr, &callee_saved_reg_list,
|
||||
&num_callee_saved_regs);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
stacking = params->cpu_saved_nofp_stacking;
|
||||
|
||||
/* Getting blink and status32 registers */
|
||||
retval = rtos_generic_stack_read(rtos->target, stacking,
|
||||
real_stack_addr + num_callee_saved_regs * 4,
|
||||
reg_list, num_regs);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
for (int i = 0; i < num_callee_saved_regs; i++)
|
||||
buf_cpy(callee_saved_reg_list[i].value,
|
||||
(*reg_list)[callee_saved_reg_list[i].number].value,
|
||||
callee_saved_reg_list[i].size);
|
||||
|
||||
/* The blink, sp, pc offsets in arc_cpu_saved structure may be changed,
|
||||
* but the registers number shall not. So the next code searches the
|
||||
* offsetst of these registers in arc_cpu_saved structure. */
|
||||
unsigned short blink_offset = 0, pc_offset = 0, sp_offset = 0;
|
||||
for (size_t i = 0; i < ARRAY_SIZE(arc_cpu_saved); i++) {
|
||||
if (arc_cpu_saved[i].number == ARC_BLINK)
|
||||
blink_offset = i;
|
||||
if (arc_cpu_saved[i].number == ARC_SP)
|
||||
sp_offset = i;
|
||||
if (arc_cpu_saved[i].number == ARC_PC)
|
||||
pc_offset = i;
|
||||
}
|
||||
|
||||
if (blink_offset == 0 || sp_offset == 0 || pc_offset == 0) {
|
||||
LOG_ERROR("Basic registers offsets are missing, check <arc_cpu_saved> struct");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
/* Put blink value into PC */
|
||||
buf_cpy((*reg_list)[blink_offset].value,
|
||||
(*reg_list)[pc_offset].value, sizeof((*reg_list)[blink_offset].value));
|
||||
|
||||
/* Put address after callee/caller in SP. */
|
||||
int64_t stack_top;
|
||||
|
||||
stack_top = real_stack_addr + num_callee_saved_regs * 4
|
||||
+ arc_cpu_saved_stacking.stack_registers_size;
|
||||
buf_cpy(&stack_top, (*reg_list)[sp_offset].value, sizeof(stack_top));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* ARM Cortex-M-specific implementation */
|
||||
static int zephyr_get_arm_state(struct rtos *rtos, target_addr_t *addr,
|
||||
struct zephyr_params *params,
|
||||
struct rtos_reg *callee_saved_reg_list,
|
||||
struct rtos_reg **reg_list, int *num_regs)
|
||||
{
|
||||
|
||||
int retval = 0;
|
||||
int num_callee_saved_regs;
|
||||
const struct rtos_register_stacking *stacking;
|
||||
|
||||
retval = rtos_generic_stack_read(rtos->target,
|
||||
params->callee_saved_stacking,
|
||||
*addr, &callee_saved_reg_list,
|
||||
&num_callee_saved_regs);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
*addr = target_buffer_get_u32(rtos->target,
|
||||
callee_saved_reg_list[0].value);
|
||||
|
||||
if (params->offsets[OFFSET_T_PREEMPT_FLOAT] != UNIMPLEMENTED)
|
||||
stacking = params->cpu_saved_fp_stacking;
|
||||
else
|
||||
stacking = params->cpu_saved_nofp_stacking;
|
||||
|
||||
retval = rtos_generic_stack_read(rtos->target, stacking, *addr, reg_list,
|
||||
num_regs);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
for (int i = 1; i < num_callee_saved_regs; i++)
|
||||
buf_cpy(callee_saved_reg_list[i].value,
|
||||
(*reg_list)[callee_saved_reg_list[i].number].value,
|
||||
callee_saved_reg_list[i].size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct zephyr_params zephyr_params_list[] = {
|
||||
{
|
||||
.target_name = "cortex_m",
|
||||
.pointer_width = 4,
|
||||
.callee_saved_stacking = &arm_callee_saved_stacking,
|
||||
.cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking,
|
||||
.cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking,
|
||||
.get_cpu_state = &zephyr_get_arm_state,
|
||||
},
|
||||
{
|
||||
.target_name = "hla_target",
|
||||
.pointer_width = 4,
|
||||
.callee_saved_stacking = &arm_callee_saved_stacking,
|
||||
.cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking,
|
||||
.cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking,
|
||||
.get_cpu_state = &zephyr_get_arm_state,
|
||||
|
||||
},
|
||||
{
|
||||
.target_name = "arcv2",
|
||||
.pointer_width = 4,
|
||||
.callee_saved_stacking = &arc_callee_saved_stacking,
|
||||
.cpu_saved_nofp_stacking = &arc_cpu_saved_stacking,
|
||||
.get_cpu_state = &zephyr_get_arc_state,
|
||||
},
|
||||
{
|
||||
.target_name = NULL
|
||||
}
|
||||
};
|
||||
|
||||
static const struct symbol_table_elem zephyr_symbol_list[] = {
|
||||
{
|
||||
.symbol_name = "_kernel",
|
||||
.optional = false
|
||||
},
|
||||
{
|
||||
.symbol_name = "_kernel_openocd_offsets",
|
||||
.optional = false
|
||||
},
|
||||
{
|
||||
.symbol_name = "_kernel_openocd_size_t_size",
|
||||
.optional = false
|
||||
},
|
||||
{
|
||||
.symbol_name = "_kernel_openocd_num_offsets",
|
||||
.optional = true
|
||||
},
|
||||
{
|
||||
.symbol_name = NULL
|
||||
}
|
||||
};
|
||||
|
||||
static bool zephyr_detect_rtos(struct target *target)
|
||||
{
|
||||
if (target->rtos->symbols == NULL) {
|
||||
LOG_INFO("Zephyr: no symbols while detecting RTOS");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (enum zephyr_symbol_values symbol = ZEPHYR_VAL__KERNEL;
|
||||
symbol != ZEPHYR_VAL_COUNT; symbol++) {
|
||||
LOG_INFO("Zephyr: does it have symbol %d (%s)?", symbol,
|
||||
target->rtos->symbols[symbol].optional ? "optional" : "mandatory");
|
||||
|
||||
if (target->rtos->symbols[symbol].optional)
|
||||
continue;
|
||||
if (target->rtos->symbols[symbol].address == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("Zephyr: all mandatory symbols found");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int zephyr_create(struct target *target)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = target_type_name(target);
|
||||
|
||||
LOG_INFO("Zephyr: looking for target: %s", name);
|
||||
|
||||
/* ARC specific, check if EM target has security subsystem
|
||||
* In case of ARC_HAS_SECURE zephyr option enabled
|
||||
* the thread stack contains blink,sec_stat,status32 register
|
||||
* values. If ARC_HAS_SECURE is disabled, only blink and status32
|
||||
* register values are saved on stack. */
|
||||
if (!strcmp(name, "arcv2")) {
|
||||
uint32_t value;
|
||||
struct arc_common *arc = target_to_arc(target);
|
||||
/* Reading SEC_BUILD bcr */
|
||||
CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, ARC_AUX_SEC_BUILD_REG, &value));
|
||||
if (value != 0) {
|
||||
LOG_DEBUG("ARC EM board has security subsystem, changing offsets");
|
||||
arc_cpu_saved[ARC_REG_NUM - 1].offset = 8;
|
||||
/* After reading callee registers in stack
|
||||
* now blink,sec_stat,status32 registers
|
||||
* are located. */
|
||||
arc_cpu_saved_stacking.stack_registers_size = 12;
|
||||
}
|
||||
}
|
||||
|
||||
for (struct zephyr_params *p = zephyr_params_list; p->target_name; p++) {
|
||||
if (!strcmp(p->target_name, name)) {
|
||||
LOG_INFO("Zephyr: target known, params at %p", p);
|
||||
target->rtos->rtos_specific_params = p;
|
||||
return ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR("Could not find target in Zephyr compatibility list");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
struct zephyr_array {
|
||||
void *ptr;
|
||||
size_t elements;
|
||||
};
|
||||
|
||||
static void zephyr_array_init(struct zephyr_array *array)
|
||||
{
|
||||
array->ptr = NULL;
|
||||
array->elements = 0;
|
||||
}
|
||||
|
||||
static void zephyr_array_free(struct zephyr_array *array)
|
||||
{
|
||||
free(array->ptr);
|
||||
zephyr_array_init(array);
|
||||
}
|
||||
|
||||
static void *zephyr_array_append(struct zephyr_array *array, size_t size)
|
||||
{
|
||||
if (!(array->elements % 16)) {
|
||||
void *ptr = realloc(array->ptr, (array->elements + 16) * size);
|
||||
|
||||
if (!ptr) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
array->ptr = ptr;
|
||||
}
|
||||
|
||||
return (unsigned char *)array->ptr + (array->elements++) * size;
|
||||
}
|
||||
|
||||
static void *zephyr_array_detach_ptr(struct zephyr_array *array)
|
||||
{
|
||||
void *ptr = array->ptr;
|
||||
|
||||
zephyr_array_init(array);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static uint32_t zephyr_kptr(const struct rtos *rtos, enum zephyr_offsets off)
|
||||
{
|
||||
const struct zephyr_params *params = rtos->rtos_specific_params;
|
||||
|
||||
return rtos->symbols[ZEPHYR_VAL__KERNEL].address + params->offsets[off];
|
||||
}
|
||||
|
||||
static int zephyr_fetch_thread(const struct rtos *rtos,
|
||||
struct zephyr_thread *thread, uint32_t ptr)
|
||||
{
|
||||
const struct zephyr_params *param = rtos->rtos_specific_params;
|
||||
int retval;
|
||||
|
||||
thread->ptr = ptr;
|
||||
|
||||
retval = target_read_u32(rtos->target, ptr + param->offsets[OFFSET_T_ENTRY],
|
||||
&thread->entry);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = target_read_u32(rtos->target,
|
||||
ptr + param->offsets[OFFSET_T_NEXT_THREAD],
|
||||
&thread->next_ptr);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = target_read_u32(rtos->target,
|
||||
ptr + param->offsets[OFFSET_T_STACK_POINTER],
|
||||
&thread->stack_pointer);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = target_read_u8(rtos->target, ptr + param->offsets[OFFSET_T_STATE],
|
||||
&thread->state);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = target_read_u8(rtos->target,
|
||||
ptr + param->offsets[OFFSET_T_USER_OPTIONS],
|
||||
&thread->user_options);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
uint8_t prio;
|
||||
retval = target_read_u8(rtos->target,
|
||||
ptr + param->offsets[OFFSET_T_PRIO], &prio);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
thread->prio = prio;
|
||||
|
||||
thread->name[0] = '\0';
|
||||
if (param->offsets[OFFSET_T_NAME] != UNIMPLEMENTED) {
|
||||
retval = target_read_buffer(rtos->target,
|
||||
ptr + param->offsets[OFFSET_T_NAME],
|
||||
sizeof(thread->name) - 1, (uint8_t *)thread->name);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
thread->name[sizeof(thread->name) - 1] = '\0';
|
||||
}
|
||||
|
||||
LOG_DEBUG("Fetched thread%" PRIx32 ": {entry@0x%" PRIx32
|
||||
", state=%" PRIu8 ", useropts=%" PRIu8 ", prio=%" PRId8 "}",
|
||||
ptr, thread->entry, thread->state, thread->user_options, thread->prio);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int zephyr_fetch_thread_list(struct rtos *rtos, uint32_t current_thread)
|
||||
{
|
||||
struct zephyr_array thread_array;
|
||||
struct zephyr_thread thread;
|
||||
struct thread_detail *td;
|
||||
int64_t curr_id = -1;
|
||||
uint32_t curr;
|
||||
int retval;
|
||||
|
||||
retval = target_read_u32(rtos->target, zephyr_kptr(rtos, OFFSET_K_THREADS),
|
||||
&curr);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("Could not fetch current thread pointer");
|
||||
return retval;
|
||||
}
|
||||
|
||||
zephyr_array_init(&thread_array);
|
||||
|
||||
for (; curr; curr = thread.next_ptr) {
|
||||
retval = zephyr_fetch_thread(rtos, &thread, curr);
|
||||
if (retval != ERROR_OK)
|
||||
goto error;
|
||||
|
||||
td = zephyr_array_append(&thread_array, sizeof(*td));
|
||||
if (!td)
|
||||
goto error;
|
||||
|
||||
td->threadid = thread.ptr;
|
||||
td->exists = true;
|
||||
|
||||
if (thread.name[0])
|
||||
td->thread_name_str = strdup(thread.name);
|
||||
else
|
||||
td->thread_name_str = alloc_printf("thr_%" PRIx32 "_%" PRIx32,
|
||||
thread.entry, thread.ptr);
|
||||
td->extra_info_str = alloc_printf("prio:%" PRId8 ",useropts:%" PRIu8,
|
||||
thread.prio, thread.user_options);
|
||||
if (!td->thread_name_str || !td->extra_info_str)
|
||||
goto error;
|
||||
|
||||
if (td->threadid == current_thread)
|
||||
curr_id = (int64_t)thread_array.elements - 1;
|
||||
}
|
||||
|
||||
LOG_DEBUG("Got information for %zu threads", thread_array.elements);
|
||||
|
||||
rtos_free_threadlist(rtos);
|
||||
|
||||
rtos->thread_count = (int)thread_array.elements;
|
||||
rtos->thread_details = zephyr_array_detach_ptr(&thread_array);
|
||||
|
||||
rtos->current_threadid = curr_id;
|
||||
rtos->current_thread = current_thread;
|
||||
|
||||
return ERROR_OK;
|
||||
|
||||
error:
|
||||
td = thread_array.ptr;
|
||||
for (size_t i = 0; i < thread_array.elements; i++) {
|
||||
free(td[i].thread_name_str);
|
||||
free(td[i].extra_info_str);
|
||||
}
|
||||
|
||||
zephyr_array_free(&thread_array);
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static int zephyr_update_threads(struct rtos *rtos)
|
||||
{
|
||||
struct zephyr_params *param;
|
||||
int retval;
|
||||
|
||||
if (!rtos->rtos_specific_params)
|
||||
return ERROR_FAIL;
|
||||
|
||||
param = (struct zephyr_params *)rtos->rtos_specific_params;
|
||||
|
||||
if (!rtos->symbols) {
|
||||
LOG_ERROR("No symbols for Zephyr");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (rtos->symbols[ZEPHYR_VAL__KERNEL].address == 0) {
|
||||
LOG_ERROR("Can't obtain kernel struct from Zephyr");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS].address == 0) {
|
||||
LOG_ERROR("Please build Zephyr with CONFIG_OPENOCD option set");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
retval = target_read_u8(rtos->target,
|
||||
rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_SIZE_T_SIZE].address,
|
||||
¶m->size_width);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("Couldn't determine size of size_t from host");
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (param->size_width != 4) {
|
||||
LOG_ERROR("Only size_t of 4 bytes are supported");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS].address) {
|
||||
retval = target_read_u32(rtos->target,
|
||||
rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS].address,
|
||||
¶m->num_offsets);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("Couldn't not fetch number of offsets from Zephyr");
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (param->num_offsets <= OFFSET_T_STACK_POINTER) {
|
||||
LOG_ERROR("Number of offsets too small");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
} else {
|
||||
retval = target_read_u32(rtos->target,
|
||||
rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS].address,
|
||||
¶m->offsets[OFFSET_VERSION]);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("Couldn't not fetch offsets from Zephyr");
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (param->offsets[OFFSET_VERSION] > 1) {
|
||||
LOG_ERROR("Unexpected OpenOCD support version %" PRIu32,
|
||||
param->offsets[OFFSET_VERSION]);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
switch (param->offsets[OFFSET_VERSION]) {
|
||||
case 0:
|
||||
param->num_offsets = OFFSET_T_STACK_POINTER + 1;
|
||||
break;
|
||||
case 1:
|
||||
param->num_offsets = OFFSET_T_COOP_FLOAT + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* We can fetch the whole array for version 0, as they're supposed
|
||||
* to grow only */
|
||||
uint32_t address;
|
||||
address = rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS].address;
|
||||
for (size_t i = 0; i < OFFSET_MAX; i++, address += param->size_width) {
|
||||
if (i >= param->num_offsets) {
|
||||
param->offsets[i] = UNIMPLEMENTED;
|
||||
continue;
|
||||
}
|
||||
|
||||
retval = target_read_u32(rtos->target, address, ¶m->offsets[i]);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("Could not fetch offsets from Zephyr");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("Zephyr OpenOCD support version %" PRId32,
|
||||
param->offsets[OFFSET_VERSION]);
|
||||
|
||||
uint32_t current_thread;
|
||||
retval = target_read_u32(rtos->target,
|
||||
zephyr_kptr(rtos, OFFSET_K_CURR_THREAD), ¤t_thread);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("Could not obtain current thread ID");
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = zephyr_fetch_thread_list(rtos, current_thread);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("Could not obtain thread list");
|
||||
return retval;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int zephyr_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
|
||||
struct rtos_reg **reg_list, int *num_regs)
|
||||
{
|
||||
struct zephyr_params *params;
|
||||
struct rtos_reg *callee_saved_reg_list = NULL;
|
||||
target_addr_t addr;
|
||||
int retval;
|
||||
|
||||
LOG_INFO("Getting thread %" PRId64 " reg list", thread_id);
|
||||
|
||||
if (rtos == NULL)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (thread_id == 0)
|
||||
return ERROR_FAIL;
|
||||
|
||||
params = rtos->rtos_specific_params;
|
||||
if (params == NULL)
|
||||
return ERROR_FAIL;
|
||||
|
||||
addr = thread_id + params->offsets[OFFSET_T_STACK_POINTER]
|
||||
- params->callee_saved_stacking->register_offsets[0].offset;
|
||||
|
||||
retval = params->get_cpu_state(rtos, &addr, params, callee_saved_reg_list, reg_list, num_regs);
|
||||
|
||||
free(callee_saved_reg_list);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int zephyr_get_symbol_list_to_lookup(struct symbol_table_elem **symbol_list)
|
||||
{
|
||||
*symbol_list = malloc(sizeof(zephyr_symbol_list));
|
||||
if (!*symbol_list) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
memcpy(*symbol_list, zephyr_symbol_list, sizeof(zephyr_symbol_list));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
struct rtos_type zephyr_rtos = {
|
||||
.name = "Zephyr",
|
||||
|
||||
.detect_rtos = zephyr_detect_rtos,
|
||||
.create = zephyr_create,
|
||||
.update_threads = zephyr_update_threads,
|
||||
.get_thread_reg_list = zephyr_get_thread_reg_list,
|
||||
.get_symbol_list_to_lookup = zephyr_get_symbol_list_to_lookup,
|
||||
};
|
|
@ -10,7 +10,9 @@ noinst_LTLIBRARIES += %D%/libserver.la
|
|||
%D%/tcl_server.c \
|
||||
%D%/tcl_server.h \
|
||||
%D%/rtt_server.c \
|
||||
%D%/rtt_server.h
|
||||
%D%/rtt_server.h \
|
||||
%D%/ipdbg.c \
|
||||
%D%/ipdbg.h
|
||||
|
||||
%C%_libserver_la_CFLAGS = $(AM_CFLAGS)
|
||||
if IS_MINGW
|
||||
|
|
|
@ -357,12 +357,50 @@ static int gdb_write(struct connection *connection, void *data, int len)
|
|||
return ERROR_SERVER_REMOTE_CLOSED;
|
||||
}
|
||||
|
||||
static void gdb_log_incoming_packet(char *packet)
|
||||
{
|
||||
if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
|
||||
return;
|
||||
|
||||
/* Avoid dumping non-printable characters to the terminal */
|
||||
const unsigned packet_len = strlen(packet);
|
||||
const char *nonprint = find_nonprint_char(packet, packet_len);
|
||||
if (nonprint) {
|
||||
/* Does packet at least have a prefix that is printable?
|
||||
* Look within the first 50 chars of the packet. */
|
||||
const char *colon = memchr(packet, ':', MIN(50, packet_len));
|
||||
const bool packet_has_prefix = (colon != NULL);
|
||||
const bool packet_prefix_printable = (packet_has_prefix && nonprint > colon);
|
||||
|
||||
if (packet_prefix_printable) {
|
||||
const unsigned int prefix_len = colon - packet + 1; /* + 1 to include the ':' */
|
||||
const unsigned int payload_len = packet_len - prefix_len;
|
||||
LOG_DEBUG("received packet: %.*s<binary-data-%u-bytes>", prefix_len, packet, payload_len);
|
||||
} else {
|
||||
LOG_DEBUG("received packet: <binary-data-%u-bytes>", packet_len);
|
||||
}
|
||||
} else {
|
||||
/* All chars printable, dump the packet as is */
|
||||
LOG_DEBUG("received packet: %s", packet);
|
||||
}
|
||||
}
|
||||
|
||||
static void gdb_log_outgoing_packet(char *packet_buf, unsigned int packet_len, unsigned char checksum)
|
||||
{
|
||||
if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
|
||||
return;
|
||||
|
||||
if (find_nonprint_char(packet_buf, packet_len))
|
||||
LOG_DEBUG("sending packet: $<binary-data-%u-bytes>#%2.2x", packet_len, checksum);
|
||||
else
|
||||
LOG_DEBUG("sending packet: $%.*s#%2.2x'", packet_len, packet_buf, checksum);
|
||||
}
|
||||
|
||||
static int gdb_put_packet_inner(struct connection *connection,
|
||||
char *buffer, int len)
|
||||
{
|
||||
int i;
|
||||
unsigned char my_checksum = 0;
|
||||
char *debug_buffer;
|
||||
int reply;
|
||||
int retval;
|
||||
struct gdb_connection *gdb_con = connection->priv;
|
||||
|
@ -400,9 +438,7 @@ static int gdb_put_packet_inner(struct connection *connection,
|
|||
#endif
|
||||
|
||||
while (1) {
|
||||
debug_buffer = strndup(buffer, len);
|
||||
LOG_DEBUG("sending packet '$%s#%2.2x'", debug_buffer, my_checksum);
|
||||
free(debug_buffer);
|
||||
gdb_log_outgoing_packet(buffer, len, my_checksum);
|
||||
|
||||
char local_buffer[1024];
|
||||
local_buffer[0] = '$';
|
||||
|
@ -3360,25 +3396,7 @@ static int gdb_input_inner(struct connection *connection)
|
|||
/* terminate with zero */
|
||||
gdb_packet_buffer[packet_size] = '\0';
|
||||
|
||||
if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
|
||||
char buf[64];
|
||||
unsigned offset = 0;
|
||||
int i = 0;
|
||||
while (i < packet_size && offset < 56) {
|
||||
if (packet[i] == '\\') {
|
||||
buf[offset++] = '\\';
|
||||
buf[offset++] = '\\';
|
||||
} else if (isprint(packet[i])) {
|
||||
buf[offset++] = packet[i];
|
||||
} else {
|
||||
sprintf(buf + offset, "\\x%02x", (unsigned char) packet[i]);
|
||||
offset += 4;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
buf[offset] = 0;
|
||||
LOG_DEBUG("received packet: '%s'%s", buf, i < packet_size ? "..." : "");
|
||||
}
|
||||
gdb_log_incoming_packet(gdb_packet_buffer);
|
||||
|
||||
if (packet_size > 0) {
|
||||
retval = ERROR_OK;
|
||||
|
@ -3423,7 +3441,7 @@ static int gdb_input_inner(struct connection *connection)
|
|||
/* '?' is sent after the eventual '!' */
|
||||
if (!warn_use_ext && !gdb_con->extended_protocol) {
|
||||
warn_use_ext = true;
|
||||
LOG_WARNING("Prefer GDB command \"target extended-remote %s\" instead of \"target remote %s\"",
|
||||
LOG_WARNING("Prefer GDB command \"target extended-remote :%s\" instead of \"target remote :%s\"",
|
||||
connection->service->port, connection->service->port);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,782 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* Copyright (C) 2020 by Daniel Anselmi <danselmi@gmx.ch> */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <helper/bits.h>
|
||||
#include <helper/time_support.h>
|
||||
#include <jtag/jtag.h>
|
||||
#include <server/server.h>
|
||||
#include <target/target.h>
|
||||
|
||||
#include "ipdbg.h"
|
||||
|
||||
#define IPDBG_BUFFER_SIZE 16384
|
||||
#define IPDBG_MIN_NUM_OF_OPTIONS 4
|
||||
#define IPDBG_MAX_NUM_OF_OPTIONS 14
|
||||
#define IPDBG_MIN_DR_LENGTH 11
|
||||
#define IPDBG_MAX_DR_LENGTH 13
|
||||
#define IPDBG_TCP_PORT_STR_MAX_LENGTH 6
|
||||
|
||||
/* private connection data for IPDBG */
|
||||
struct ipdbg_fifo {
|
||||
size_t count;
|
||||
size_t rd_idx;
|
||||
char buffer[IPDBG_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
struct ipdbg_connection {
|
||||
struct ipdbg_fifo dn_fifo;
|
||||
struct ipdbg_fifo up_fifo;
|
||||
bool closed;
|
||||
};
|
||||
|
||||
struct ipdbg_service {
|
||||
struct ipdbg_hub *hub;
|
||||
struct ipdbg_service *next;
|
||||
uint16_t port;
|
||||
struct ipdbg_connection connection;
|
||||
uint8_t tool;
|
||||
};
|
||||
|
||||
struct ipdbg_virtual_ir_info {
|
||||
uint32_t instruction;
|
||||
uint32_t length;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
struct ipdbg_hub {
|
||||
uint32_t user_instruction;
|
||||
uint32_t max_tools;
|
||||
uint32_t active_connections;
|
||||
uint32_t active_services;
|
||||
uint32_t valid_mask;
|
||||
uint32_t xoff_mask;
|
||||
uint32_t tool_mask;
|
||||
uint32_t last_dn_tool;
|
||||
struct ipdbg_hub *next;
|
||||
struct jtag_tap *tap;
|
||||
struct connection **connections;
|
||||
uint8_t data_register_length;
|
||||
uint8_t dn_xoff;
|
||||
struct ipdbg_virtual_ir_info *virtual_ir;
|
||||
};
|
||||
|
||||
static struct ipdbg_hub *ipdbg_first_hub;
|
||||
|
||||
static struct ipdbg_service *ipdbg_first_service;
|
||||
|
||||
static void ipdbg_init_fifo(struct ipdbg_fifo *fifo)
|
||||
{
|
||||
fifo->count = 0;
|
||||
fifo->rd_idx = 0;
|
||||
}
|
||||
|
||||
static bool ipdbg_fifo_is_empty(struct ipdbg_fifo *fifo)
|
||||
{
|
||||
return fifo->count == 0;
|
||||
}
|
||||
|
||||
static bool ipdbg_fifo_is_full(struct ipdbg_fifo *fifo)
|
||||
{
|
||||
return fifo->count == IPDBG_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo)
|
||||
{
|
||||
if (fifo->rd_idx == 0)
|
||||
return;
|
||||
|
||||
size_t ri = fifo->rd_idx;
|
||||
for (size_t idx = 0 ; idx < fifo->count ; ++idx)
|
||||
fifo->buffer[idx] = fifo->buffer[ri++];
|
||||
fifo->rd_idx = 0;
|
||||
}
|
||||
|
||||
static void ipdbg_append_to_fifo(struct ipdbg_fifo *fifo, char data)
|
||||
{
|
||||
if (ipdbg_fifo_is_full(fifo))
|
||||
return;
|
||||
|
||||
ipdbg_zero_rd_idx(fifo);
|
||||
fifo->buffer[fifo->count++] = data;
|
||||
}
|
||||
|
||||
static char ipdbg_get_from_fifo(struct ipdbg_fifo *fifo)
|
||||
{
|
||||
if (ipdbg_fifo_is_empty(fifo))
|
||||
return 0;
|
||||
|
||||
fifo->count--;
|
||||
return fifo->buffer[fifo->rd_idx++];
|
||||
}
|
||||
|
||||
static int ipdbg_move_buffer_to_connection(struct connection *conn, struct ipdbg_fifo *fifo)
|
||||
{
|
||||
if (ipdbg_fifo_is_empty(fifo))
|
||||
return ERROR_OK;
|
||||
|
||||
struct ipdbg_connection *connection = conn->priv;
|
||||
if (connection->closed)
|
||||
return ERROR_SERVER_REMOTE_CLOSED;
|
||||
|
||||
ipdbg_zero_rd_idx(fifo);
|
||||
size_t bytes_written = connection_write(conn, fifo->buffer, fifo->count);
|
||||
if (bytes_written != fifo->count) {
|
||||
LOG_ERROR("error during write: %zu != %zu", bytes_written, fifo->count);
|
||||
connection->closed = true;
|
||||
return ERROR_SERVER_REMOTE_CLOSED;
|
||||
}
|
||||
|
||||
fifo->count -= bytes_written;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ipdbg_max_tools_from_data_register_length(uint8_t data_register_length)
|
||||
{
|
||||
int max_tools = 1;
|
||||
data_register_length -= 10; /* 8 bit payload, 1 xoff-flag, 1 valid-flag; remaining bits used to select tool*/
|
||||
while (data_register_length--)
|
||||
max_tools *= 2;
|
||||
|
||||
/* last tool is used to reset JtagCDC and transfer "XON" to host*/
|
||||
return max_tools - 1;
|
||||
}
|
||||
|
||||
static struct ipdbg_service *ipdbg_find_service(struct ipdbg_hub *hub, uint8_t tool)
|
||||
{
|
||||
struct ipdbg_service *service;
|
||||
for (service = ipdbg_first_service ; service ; service = service->next) {
|
||||
if (service->hub == hub && service->tool == tool)
|
||||
break;
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
static void ipdbg_add_service(struct ipdbg_service *service)
|
||||
{
|
||||
struct ipdbg_service *iservice;
|
||||
if (ipdbg_first_service) {
|
||||
for (iservice = ipdbg_first_service ; iservice->next; iservice = iservice->next)
|
||||
;
|
||||
iservice->next = service;
|
||||
} else
|
||||
ipdbg_first_service = service;
|
||||
}
|
||||
|
||||
static int ipdbg_create_service(struct ipdbg_hub *hub, uint8_t tool, struct ipdbg_service **service, uint16_t port)
|
||||
{
|
||||
*service = calloc(1, sizeof(struct ipdbg_service));
|
||||
if (!*service) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
(*service)->hub = hub;
|
||||
(*service)->tool = tool;
|
||||
(*service)->port = port;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ipdbg_remove_service(struct ipdbg_service *service)
|
||||
{
|
||||
if (!ipdbg_first_service)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (service == ipdbg_first_service) {
|
||||
ipdbg_first_service = ipdbg_first_service->next;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
for (struct ipdbg_service *iservice = ipdbg_first_service ; iservice->next ; iservice = iservice->next) {
|
||||
if (service == iservice->next) {
|
||||
iservice->next = service->next;
|
||||
return ERROR_OK;
|
||||
}
|
||||
}
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static struct ipdbg_hub *ipdbg_find_hub(struct jtag_tap *tap,
|
||||
uint32_t user_instruction, struct ipdbg_virtual_ir_info *virtual_ir)
|
||||
{
|
||||
struct ipdbg_hub *hub = NULL;
|
||||
for (hub = ipdbg_first_hub ; hub ; hub = hub->next) {
|
||||
if (hub->tap == tap && hub->user_instruction == user_instruction) {
|
||||
if ((!virtual_ir && !hub->virtual_ir) ||
|
||||
(virtual_ir && hub->virtual_ir &&
|
||||
virtual_ir->instruction == hub->virtual_ir->instruction &&
|
||||
virtual_ir->length == hub->virtual_ir->length &&
|
||||
virtual_ir->value == hub->virtual_ir->value)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hub;
|
||||
}
|
||||
|
||||
static void ipdbg_add_hub(struct ipdbg_hub *hub)
|
||||
{
|
||||
struct ipdbg_hub *ihub;
|
||||
if (ipdbg_first_hub) {
|
||||
for (ihub = ipdbg_first_hub ; ihub->next; ihub = ihub->next)
|
||||
;
|
||||
ihub->next = hub;
|
||||
} else
|
||||
ipdbg_first_hub = hub;
|
||||
}
|
||||
|
||||
static int ipdbg_create_hub(struct jtag_tap *tap, uint32_t user_instruction, uint8_t data_register_length,
|
||||
struct ipdbg_virtual_ir_info *virtual_ir, struct ipdbg_hub **hub)
|
||||
{
|
||||
*hub = NULL;
|
||||
struct ipdbg_hub *new_hub = calloc(1, sizeof(struct ipdbg_hub));
|
||||
if (!new_hub) {
|
||||
free(virtual_ir);
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
new_hub->max_tools = ipdbg_max_tools_from_data_register_length(data_register_length);
|
||||
new_hub->connections = calloc(new_hub->max_tools, sizeof(struct connection *));
|
||||
if (!new_hub->connections) {
|
||||
free(virtual_ir);
|
||||
free(new_hub);
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
new_hub->tap = tap;
|
||||
new_hub->user_instruction = user_instruction;
|
||||
new_hub->data_register_length = data_register_length;
|
||||
new_hub->valid_mask = BIT(data_register_length - 1);
|
||||
new_hub->xoff_mask = BIT(data_register_length - 2);
|
||||
new_hub->tool_mask = (new_hub->xoff_mask - 1) >> 8;
|
||||
new_hub->last_dn_tool = new_hub->tool_mask;
|
||||
new_hub->virtual_ir = virtual_ir;
|
||||
|
||||
*hub = new_hub;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static void ipdbg_free_hub(struct ipdbg_hub *hub)
|
||||
{
|
||||
if (!hub)
|
||||
return;
|
||||
free(hub->connections);
|
||||
free(hub->virtual_ir);
|
||||
free(hub);
|
||||
}
|
||||
|
||||
static int ipdbg_remove_hub(struct ipdbg_hub *hub)
|
||||
{
|
||||
if (!ipdbg_first_hub)
|
||||
return ERROR_FAIL;
|
||||
if (hub == ipdbg_first_hub) {
|
||||
ipdbg_first_hub = ipdbg_first_hub->next;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
for (struct ipdbg_hub *ihub = ipdbg_first_hub ; ihub->next ; ihub = ihub->next) {
|
||||
if (hub == ihub->next) {
|
||||
ihub->next = hub->next;
|
||||
return ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static void ipdbg_init_scan_field(struct scan_field *fields, uint8_t *in_value, int num_bits, const uint8_t *out_value)
|
||||
{
|
||||
fields->check_mask = NULL;
|
||||
fields->check_value = NULL;
|
||||
fields->in_value = in_value;
|
||||
fields->num_bits = num_bits;
|
||||
fields->out_value = out_value;
|
||||
}
|
||||
|
||||
static int ipdbg_shift_instr(struct ipdbg_hub *hub, uint32_t instr)
|
||||
{
|
||||
if (!hub)
|
||||
return ERROR_FAIL;
|
||||
|
||||
struct jtag_tap *tap = hub->tap;
|
||||
if (!tap)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == instr) {
|
||||
/* there is already the requested instruction in the ir */
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
uint8_t *ir_out_val = calloc(DIV_ROUND_UP(tap->ir_length, 8), 1);
|
||||
buf_set_u32(ir_out_val, 0, tap->ir_length, instr);
|
||||
|
||||
struct scan_field fields;
|
||||
ipdbg_init_scan_field(&fields, NULL, tap->ir_length, ir_out_val);
|
||||
jtag_add_ir_scan(tap, &fields, TAP_IDLE);
|
||||
int retval = jtag_execute_queue();
|
||||
|
||||
free(ir_out_val);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int ipdbg_shift_vir(struct ipdbg_hub *hub)
|
||||
{
|
||||
if (!hub)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (!hub->virtual_ir)
|
||||
return ERROR_OK;
|
||||
|
||||
int retval = ipdbg_shift_instr(hub, hub->virtual_ir->instruction);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
struct jtag_tap *tap = hub->tap;
|
||||
if (!tap)
|
||||
return ERROR_FAIL;
|
||||
|
||||
uint8_t *dr_out_val = calloc(DIV_ROUND_UP(hub->virtual_ir->length, 8), 1);
|
||||
buf_set_u32(dr_out_val, 0, hub->virtual_ir->length, hub->virtual_ir->value);
|
||||
|
||||
struct scan_field fields;
|
||||
ipdbg_init_scan_field(&fields, NULL, hub->virtual_ir->length, dr_out_val);
|
||||
jtag_add_dr_scan(tap, 1, &fields, TAP_IDLE);
|
||||
retval = jtag_execute_queue();
|
||||
|
||||
free(dr_out_val);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int ipdbg_shift_data(struct ipdbg_hub *hub, uint32_t dn_data, uint32_t *up_data)
|
||||
{
|
||||
if (!hub)
|
||||
return ERROR_FAIL;
|
||||
|
||||
struct jtag_tap *tap = hub->tap;
|
||||
if (!tap)
|
||||
return ERROR_FAIL;
|
||||
|
||||
uint8_t *dr_out_val = calloc(DIV_ROUND_UP(hub->data_register_length, 8), 1);
|
||||
buf_set_u32(dr_out_val, 0, hub->data_register_length, dn_data);
|
||||
uint8_t *dr_in_val = up_data ? calloc(DIV_ROUND_UP(hub->data_register_length, 8), 1) : NULL;
|
||||
|
||||
struct scan_field fields;
|
||||
ipdbg_init_scan_field(&fields, dr_in_val, hub->data_register_length, dr_out_val);
|
||||
jtag_add_dr_scan(tap, 1, &fields, TAP_IDLE);
|
||||
int retval = jtag_execute_queue();
|
||||
|
||||
if (up_data && retval == ERROR_OK)
|
||||
*up_data = buf_get_u32(dr_in_val, 0, hub->data_register_length);
|
||||
|
||||
free(dr_out_val);
|
||||
free(dr_in_val);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int ipdbg_distribute_data_from_hub(struct ipdbg_hub *hub, uint32_t up)
|
||||
{
|
||||
const bool valid_up_data = up & hub->valid_mask;
|
||||
if (!valid_up_data)
|
||||
return ERROR_OK;
|
||||
|
||||
const size_t tool = (up >> 8) & hub->tool_mask;
|
||||
if (tool == hub->tool_mask) {
|
||||
const uint8_t xon_cmd = up & 0x00ff;
|
||||
hub->dn_xoff &= ~xon_cmd;
|
||||
LOG_INFO("received xon cmd: %d\n", xon_cmd);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
struct connection *conn = hub->connections[tool];
|
||||
if (conn) {
|
||||
struct ipdbg_connection *connection = conn->priv;
|
||||
if (ipdbg_fifo_is_full(&connection->up_fifo)) {
|
||||
int retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
ipdbg_append_to_fifo(&connection->up_fifo, up);
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ipdbg_jtag_transfer_byte(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection)
|
||||
{
|
||||
uint32_t dn = hub->valid_mask | ((tool & hub->tool_mask) << 8) |
|
||||
(0x00fful & ipdbg_get_from_fifo(&connection->dn_fifo));
|
||||
uint32_t up = 0;
|
||||
int ret = ipdbg_shift_data(hub, dn, &up);
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
|
||||
ret = ipdbg_distribute_data_from_hub(hub, up);
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
|
||||
if ((up & hub->xoff_mask) && (hub->last_dn_tool != hub->max_tools)) {
|
||||
hub->dn_xoff |= BIT(hub->last_dn_tool);
|
||||
LOG_INFO("tool %d sent xoff", hub->last_dn_tool);
|
||||
}
|
||||
|
||||
hub->last_dn_tool = tool;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ipdbg_polling_callback(void *priv)
|
||||
{
|
||||
struct ipdbg_hub *hub = priv;
|
||||
|
||||
int ret = ipdbg_shift_vir(hub);
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
|
||||
ret = ipdbg_shift_instr(hub, hub->user_instruction);
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
|
||||
/* transfer dn buffers to jtag-hub */
|
||||
unsigned int num_transfers = 0;
|
||||
for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) {
|
||||
struct connection *conn = hub->connections[tool];
|
||||
if (conn && conn->priv) {
|
||||
struct ipdbg_connection *connection = conn->priv;
|
||||
while (((hub->dn_xoff & BIT(tool)) == 0) && !ipdbg_fifo_is_empty(&connection->dn_fifo)) {
|
||||
ret = ipdbg_jtag_transfer_byte(hub, tool, connection);
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
++num_transfers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* some transfers to get data from jtag-hub in case there is no dn data */
|
||||
while (num_transfers++ < hub->max_tools) {
|
||||
uint32_t dn = 0;
|
||||
uint32_t up = 0;
|
||||
|
||||
int retval = ipdbg_shift_data(hub, dn, &up);
|
||||
if (retval != ERROR_OK)
|
||||
return ret;
|
||||
|
||||
retval = ipdbg_distribute_data_from_hub(hub, up);
|
||||
if (retval != ERROR_OK)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* write from up fifos to sockets */
|
||||
for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) {
|
||||
struct connection *conn = hub->connections[tool];
|
||||
if (conn && conn->priv) {
|
||||
struct ipdbg_connection *connection = conn->priv;
|
||||
int retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ipdbg_start_polling(struct ipdbg_service *service, struct connection *connection)
|
||||
{
|
||||
struct ipdbg_hub *hub = service->hub;
|
||||
hub->connections[service->tool] = connection;
|
||||
hub->active_connections++;
|
||||
if (hub->active_connections > 1) {
|
||||
/* hub is already initialized */
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
const uint32_t reset_hub = hub->valid_mask | ((hub->max_tools) << 8);
|
||||
|
||||
int ret = ipdbg_shift_vir(hub);
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
|
||||
ret = ipdbg_shift_instr(hub, hub->user_instruction);
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
|
||||
ret = ipdbg_shift_data(hub, reset_hub, NULL);
|
||||
hub->last_dn_tool = hub->tool_mask;
|
||||
hub->dn_xoff = 0;
|
||||
if (ret != ERROR_OK)
|
||||
return ret;
|
||||
|
||||
LOG_INFO("IPDBG start_polling");
|
||||
|
||||
const int time_ms = 20;
|
||||
const int periodic = 1;
|
||||
return target_register_timer_callback(ipdbg_polling_callback, time_ms, periodic, hub);
|
||||
}
|
||||
|
||||
static int ipdbg_stop_polling(struct ipdbg_service *service)
|
||||
{
|
||||
struct ipdbg_hub *hub = service->hub;
|
||||
hub->connections[service->tool] = NULL;
|
||||
hub->active_connections--;
|
||||
if (hub->active_connections == 0) {
|
||||
LOG_INFO("IPDBG stop_polling");
|
||||
|
||||
return target_unregister_timer_callback(ipdbg_polling_callback, hub);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ipdbg_on_new_connection(struct connection *connection)
|
||||
{
|
||||
struct ipdbg_service *service = connection->service->priv;
|
||||
connection->priv = &service->connection;
|
||||
/* initialize ipdbg connection information */
|
||||
ipdbg_init_fifo(&service->connection.up_fifo);
|
||||
ipdbg_init_fifo(&service->connection.dn_fifo);
|
||||
|
||||
int retval = ipdbg_start_polling(service, connection);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("BUG: ipdbg_start_polling failed");
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct ipdbg_connection *conn = connection->priv;
|
||||
conn->closed = false;
|
||||
|
||||
LOG_INFO("New IPDBG Connection");
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ipdbg_on_connection_input(struct connection *connection)
|
||||
{
|
||||
struct ipdbg_connection *conn = connection->priv;
|
||||
struct ipdbg_fifo *fifo = &conn->dn_fifo;
|
||||
|
||||
if (ipdbg_fifo_is_full(fifo))
|
||||
return ERROR_OK;
|
||||
|
||||
ipdbg_zero_rd_idx(fifo);
|
||||
int bytes_read = connection_read(connection, fifo->buffer + fifo->count, IPDBG_BUFFER_SIZE - fifo->count);
|
||||
if (bytes_read <= 0) {
|
||||
if (bytes_read < 0)
|
||||
LOG_ERROR("error during read: %s", strerror(errno));
|
||||
return ERROR_SERVER_REMOTE_CLOSED;
|
||||
}
|
||||
|
||||
fifo->count += bytes_read;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ipdbg_on_connection_closed(struct connection *connection)
|
||||
{
|
||||
struct ipdbg_connection *conn = connection->priv;
|
||||
conn->closed = true;
|
||||
LOG_INFO("Closed IPDBG Connection");
|
||||
|
||||
return ipdbg_stop_polling(connection->service->priv);
|
||||
}
|
||||
|
||||
static int ipdbg_start(uint16_t port, struct jtag_tap *tap, uint32_t user_instruction,
|
||||
uint8_t data_register_length, struct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool)
|
||||
{
|
||||
LOG_INFO("starting ipdbg service on port %d for tool %d", port, tool);
|
||||
|
||||
struct ipdbg_hub *hub = ipdbg_find_hub(tap, user_instruction, virtual_ir);
|
||||
if (hub) {
|
||||
free(virtual_ir);
|
||||
if (hub->data_register_length != data_register_length) {
|
||||
LOG_DEBUG("hub must have the same data_register_length for all tools");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
} else {
|
||||
int retval = ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, &hub);
|
||||
if (retval != ERROR_OK) {
|
||||
free(virtual_ir);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
struct ipdbg_service *service = NULL;
|
||||
int retval = ipdbg_create_service(hub, tool, &service, port);
|
||||
|
||||
if (retval != ERROR_OK || !service) {
|
||||
if (hub->active_services == 0 && hub->active_connections == 0)
|
||||
ipdbg_free_hub(hub);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
|
||||
snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", port);
|
||||
retval = add_service("ipdbg", port_str_buffer, 1, &ipdbg_on_new_connection,
|
||||
&ipdbg_on_connection_input, &ipdbg_on_connection_closed, service);
|
||||
if (retval == ERROR_OK) {
|
||||
ipdbg_add_service(service);
|
||||
if (hub->active_services == 0 && hub->active_connections == 0)
|
||||
ipdbg_add_hub(hub);
|
||||
hub->active_services++;
|
||||
} else {
|
||||
if (hub->active_services == 0 && hub->active_connections == 0)
|
||||
ipdbg_free_hub(hub);
|
||||
free(service);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int ipdbg_stop(struct jtag_tap *tap, uint32_t user_instruction,
|
||||
struct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool)
|
||||
{
|
||||
struct ipdbg_hub *hub = ipdbg_find_hub(tap, user_instruction, virtual_ir);
|
||||
free(virtual_ir);
|
||||
if (!hub)
|
||||
return ERROR_FAIL;
|
||||
|
||||
struct ipdbg_service *service = ipdbg_find_service(hub, tool);
|
||||
if (!service)
|
||||
return ERROR_FAIL;
|
||||
|
||||
int retval = ipdbg_remove_service(service);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("BUG: ipdbg_remove_service failed");
|
||||
return retval;
|
||||
}
|
||||
|
||||
char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
|
||||
snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", service->port);
|
||||
retval = remove_service("ipdbg", port_str_buffer);
|
||||
/* The ipdbg_service structure is freed by server.c:remove_service().
|
||||
There the "priv" pointer is freed.*/
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("BUG: remove_service failed");
|
||||
return retval;
|
||||
}
|
||||
hub->active_services--;
|
||||
if (hub->active_connections == 0 && hub->active_services == 0) {
|
||||
retval = ipdbg_remove_hub(hub);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("BUG: ipdbg_remove_hub failed");
|
||||
return retval;
|
||||
}
|
||||
ipdbg_free_hub(hub);
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_ipdbg_command)
|
||||
{
|
||||
struct jtag_tap *tap = NULL;
|
||||
uint16_t port = 4242;
|
||||
uint8_t tool = 1;
|
||||
uint32_t user_instruction = 0x00;
|
||||
uint8_t data_register_length = IPDBG_MAX_DR_LENGTH;
|
||||
bool start = true;
|
||||
bool hub_configured = false;
|
||||
bool has_virtual_ir = false;
|
||||
uint32_t virtual_ir_instruction = 0x00e;
|
||||
uint32_t virtual_ir_length = 5;
|
||||
uint32_t virtual_ir_value = 0x11;
|
||||
struct ipdbg_virtual_ir_info *virtual_ir = NULL;
|
||||
|
||||
if ((CMD_ARGC < IPDBG_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > IPDBG_MAX_NUM_OF_OPTIONS))
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
for (unsigned int i = 0; i < CMD_ARGC; ++i) {
|
||||
if (strcmp(CMD_ARGV[i], "-tap") == 0) {
|
||||
if (i + 1 >= CMD_ARGC || CMD_ARGV[i + 1][0] == '-') {
|
||||
command_print(CMD, "no TAP given");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
tap = jtag_tap_by_string(CMD_ARGV[i + 1]);
|
||||
if (!tap) {
|
||||
command_print(CMD, "Tap %s unknown", CMD_ARGV[i + 1]);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
++i;
|
||||
} else if (strcmp(CMD_ARGV[i], "-hub") == 0) {
|
||||
COMMAND_PARSE_ADDITIONAL_NUMBER(u32, i, user_instruction, "ir_value to select hub");
|
||||
hub_configured = true;
|
||||
COMMAND_PARSE_OPTIONAL_NUMBER(u8, i, data_register_length);
|
||||
if (data_register_length < IPDBG_MIN_DR_LENGTH ||
|
||||
data_register_length > IPDBG_MAX_DR_LENGTH) {
|
||||
command_print(CMD, "length of \"user\"-data register must be at least %d and at most %d.",
|
||||
IPDBG_MIN_DR_LENGTH, IPDBG_MAX_DR_LENGTH);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
} else if (strcmp(CMD_ARGV[i], "-vir") == 0) {
|
||||
COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_value);
|
||||
COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_length);
|
||||
COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_instruction);
|
||||
has_virtual_ir = true;
|
||||
} else if (strcmp(CMD_ARGV[i], "-port") == 0) {
|
||||
COMMAND_PARSE_ADDITIONAL_NUMBER(u16, i, port, "port number");
|
||||
} else if (strcmp(CMD_ARGV[i], "-tool") == 0) {
|
||||
COMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, tool, "tool");
|
||||
} else if (strcmp(CMD_ARGV[i], "-stop") == 0) {
|
||||
start = false;
|
||||
} else if (strcmp(CMD_ARGV[i], "-start") == 0) {
|
||||
start = true;
|
||||
} else {
|
||||
command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tap) {
|
||||
command_print(CMD, "no valid tap selected");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (!hub_configured) {
|
||||
command_print(CMD, "hub not configured correctly");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (tool >= ipdbg_max_tools_from_data_register_length(data_register_length)) {
|
||||
command_print(CMD, "Tool: %d is invalid", tool);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (has_virtual_ir) {
|
||||
virtual_ir = calloc(1, sizeof(struct ipdbg_virtual_ir_info));
|
||||
if (!virtual_ir) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
virtual_ir->instruction = virtual_ir_instruction;
|
||||
virtual_ir->length = virtual_ir_length;
|
||||
virtual_ir->value = virtual_ir_value;
|
||||
}
|
||||
|
||||
if (start)
|
||||
return ipdbg_start(port, tap, user_instruction, data_register_length, virtual_ir, tool);
|
||||
else
|
||||
return ipdbg_stop(tap, user_instruction, virtual_ir, tool);
|
||||
}
|
||||
|
||||
static const struct command_registration ipdbg_command_handlers[] = {
|
||||
{
|
||||
.name = "ipdbg",
|
||||
.handler = handle_ipdbg_command,
|
||||
.mode = COMMAND_EXEC,
|
||||
.help = "Starts or stops an IPDBG JTAG-Host server.",
|
||||
.usage = "[-start|-stop] -tap device.tap -hub ir_value [dr_length]"
|
||||
" [-port number] [-tool number] [-vir [vir_value [length [instr_code]]]]",
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
int ipdbg_register_commands(struct command_context *cmd_ctx)
|
||||
{
|
||||
return register_commands(cmd_ctx, NULL, ipdbg_command_handlers);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* Copyright (C) 2020 by Daniel Anselmi <danselmi@gmx.ch> */
|
||||
|
||||
#ifndef OPENOCD_IPDBG_IPDBG_H
|
||||
#define OPENOCD_IPDBG_IPDBG_H
|
||||
|
||||
#include <helper/command.h>
|
||||
|
||||
int ipdbg_register_commands(struct command_context *cmd_ctx);
|
||||
|
||||
#endif /* OPENOCD_IPDBG_IPDBG_H */
|
|
@ -9,6 +9,9 @@ proc ocd_gdb_restart {target_id} {
|
|||
reset halt
|
||||
}
|
||||
|
||||
lappend _telnet_autocomplete_skip prevent_cps
|
||||
lappend _telnet_autocomplete_skip POST
|
||||
lappend _telnet_autocomplete_skip Host:
|
||||
proc prevent_cps {} {
|
||||
echo "Possible SECURITY ATTACK detected."
|
||||
echo "It looks like somebody is sending POST or Host: commands to OpenOCD."
|
||||
|
@ -19,3 +22,20 @@ proc prevent_cps {} {
|
|||
|
||||
proc POST {args} { prevent_cps }
|
||||
proc Host: {args} { prevent_cps }
|
||||
|
||||
# list of commands we don't want to appear in autocomplete
|
||||
lappend _telnet_autocomplete_skip _telnet_autocomplete_helper
|
||||
|
||||
# helper for telnet autocomplete
|
||||
proc _telnet_autocomplete_helper pattern {
|
||||
set cmds [info commands $pattern]
|
||||
|
||||
# skip matches in variable '_telnet_autocomplete_skip'
|
||||
foreach skip $::_telnet_autocomplete_skip {
|
||||
foreach n [lsearch -all -regexp $cmds "^$skip\$"] {
|
||||
set cmds [lreplace $cmds $n $n]
|
||||
}
|
||||
}
|
||||
|
||||
return [lsort $cmds]
|
||||
}
|
||||
|
|
|
@ -470,7 +470,7 @@ static void telnet_auto_complete(struct connection *connection)
|
|||
query[usr_cmd_len] = '\0';
|
||||
|
||||
/* filter commands */
|
||||
char *query_cmd = alloc_printf("lsort [info commands {%s*}]", query);
|
||||
char *query_cmd = alloc_printf("_telnet_autocomplete_helper {%s*}", query);
|
||||
|
||||
if (!query_cmd) {
|
||||
LOG_ERROR("Out of memory");
|
||||
|
@ -500,22 +500,18 @@ static void telnet_auto_complete(struct connection *connection)
|
|||
bool ignore_cmd = false;
|
||||
Jim_Cmd *jim_cmd = Jim_GetCommand(command_context->interp, elem, JIM_NONE);
|
||||
|
||||
if (!jim_cmd)
|
||||
if (!jim_cmd) {
|
||||
/* Why we are here? Let's ignore it! */
|
||||
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;
|
||||
} else if (jimcmd_is_oocd_command(jim_cmd)) {
|
||||
struct command *cmd = jimcmd_privdata(jim_cmd);
|
||||
|
||||
if (cmd && !cmd->handler && !cmd->jim_handler) {
|
||||
/* Initial part of a multi-word command. Ignore it! */
|
||||
ignore_cmd = true;
|
||||
} else if (cmd && cmd->mode == COMMAND_CONFIG) {
|
||||
/* Not executable after config phase. Ignore it! */
|
||||
ignore_cmd = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -988,25 +988,26 @@ static int aarch64_debug_entry(struct target *target)
|
|||
/* Examine debug reason */
|
||||
armv8_dpm_report_dscr(dpm, dscr);
|
||||
|
||||
/* save address of instruction that triggered the watchpoint? */
|
||||
/* save the memory address that triggered the watchpoint */
|
||||
if (target->debug_reason == DBG_REASON_WATCHPOINT) {
|
||||
uint32_t tmp;
|
||||
uint64_t wfar = 0;
|
||||
|
||||
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
|
||||
armv8->debug_base + CPUV8_DBG_WFAR1,
|
||||
&tmp);
|
||||
armv8->debug_base + CPUV8_DBG_EDWAR0, &tmp);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
wfar = tmp;
|
||||
wfar = (wfar << 32);
|
||||
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
|
||||
armv8->debug_base + CPUV8_DBG_WFAR0,
|
||||
&tmp);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
wfar |= tmp;
|
||||
armv8_dpm_report_wfar(&armv8->dpm, wfar);
|
||||
target_addr_t edwar = tmp;
|
||||
|
||||
/* EDWAR[63:32] has unknown content in aarch32 state */
|
||||
if (core_state == ARM_STATE_AARCH64) {
|
||||
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
|
||||
armv8->debug_base + CPUV8_DBG_EDWAR1, &tmp);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
edwar |= ((target_addr_t)tmp) << 32;
|
||||
}
|
||||
|
||||
armv8->dpm.wp_addr = edwar;
|
||||
}
|
||||
|
||||
retval = armv8_dpm_read_current_registers(&armv8->dpm);
|
||||
|
@ -1853,31 +1854,19 @@ int aarch64_hit_watchpoint(struct target *target,
|
|||
|
||||
struct armv8_common *armv8 = target_to_armv8(target);
|
||||
|
||||
uint64_t exception_address;
|
||||
target_addr_t exception_address;
|
||||
struct watchpoint *wp;
|
||||
|
||||
exception_address = armv8->dpm.wp_pc;
|
||||
exception_address = armv8->dpm.wp_addr;
|
||||
|
||||
if (exception_address == 0xFFFFFFFF)
|
||||
return ERROR_FAIL;
|
||||
|
||||
/**********************************************************/
|
||||
/* see if a watchpoint address matches a value read from */
|
||||
/* the EDWAR register. Testing shows that on some ARM CPUs*/
|
||||
/* the EDWAR value needs to have 8 added to it so we add */
|
||||
/* that check as well not sure if that is a core bug) */
|
||||
/**********************************************************/
|
||||
for (exception_address = armv8->dpm.wp_pc; exception_address <= (armv8->dpm.wp_pc + 8);
|
||||
exception_address += 8) {
|
||||
for (wp = target->watchpoints; wp; wp = wp->next) {
|
||||
if ((exception_address >= wp->address) && (exception_address < (wp->address + wp->length))) {
|
||||
*hit_watchpoint = wp;
|
||||
if (exception_address != armv8->dpm.wp_pc)
|
||||
LOG_DEBUG("watchpoint hit required EDWAR to be increased by 8");
|
||||
return ERROR_OK;
|
||||
}
|
||||
for (wp = target->watchpoints; wp; wp = wp->next)
|
||||
if (exception_address >= wp->address && exception_address < (wp->address + wp->length)) {
|
||||
*hit_watchpoint = wp;
|
||||
return ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -2796,15 +2785,15 @@ enum aarch64_cfg_param {
|
|||
CFG_CTI,
|
||||
};
|
||||
|
||||
static const Jim_Nvp nvp_config_opts[] = {
|
||||
static const struct jim_nvp nvp_config_opts[] = {
|
||||
{ .name = "-cti", .value = CFG_CTI },
|
||||
{ .name = NULL, .value = -1 }
|
||||
};
|
||||
|
||||
static int aarch64_jim_configure(struct target *target, Jim_GetOptInfo *goi)
|
||||
static int aarch64_jim_configure(struct target *target, struct jim_getopt_info *goi)
|
||||
{
|
||||
struct aarch64_private_config *pc;
|
||||
Jim_Nvp *n;
|
||||
struct jim_nvp *n;
|
||||
int e;
|
||||
|
||||
pc = (struct aarch64_private_config *)target->private_config;
|
||||
|
@ -2835,12 +2824,12 @@ static int aarch64_jim_configure(struct target *target, Jim_GetOptInfo *goi)
|
|||
Jim_SetEmptyResult(goi->interp);
|
||||
|
||||
/* check first if topmost item is for us */
|
||||
e = Jim_Nvp_name2value_obj(goi->interp, nvp_config_opts,
|
||||
e = jim_nvp_name2value_obj(goi->interp, nvp_config_opts,
|
||||
goi->argv[0], &n);
|
||||
if (e != JIM_OK)
|
||||
return JIM_CONTINUE;
|
||||
|
||||
e = Jim_GetOpt_Obj(goi, NULL);
|
||||
e = jim_getopt_obj(goi, NULL);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
|
@ -2849,7 +2838,7 @@ static int aarch64_jim_configure(struct target *target, Jim_GetOptInfo *goi)
|
|||
if (goi->isconfigure) {
|
||||
Jim_Obj *o_cti;
|
||||
struct arm_cti *cti;
|
||||
e = Jim_GetOpt_Obj(goi, &o_cti);
|
||||
e = jim_getopt_obj(goi, &o_cti);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
cti = cti_instance_by_jim_obj(goi->interp, o_cti);
|
||||
|
@ -2941,15 +2930,15 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command)
|
|||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct aarch64_common *aarch64 = target_to_aarch64(target);
|
||||
|
||||
static const Jim_Nvp nvp_maskisr_modes[] = {
|
||||
static const struct jim_nvp nvp_maskisr_modes[] = {
|
||||
{ .name = "off", .value = AARCH64_ISRMASK_OFF },
|
||||
{ .name = "on", .value = AARCH64_ISRMASK_ON },
|
||||
{ .name = NULL, .value = -1 },
|
||||
};
|
||||
const Jim_Nvp *n;
|
||||
const struct jim_nvp *n;
|
||||
|
||||
if (CMD_ARGC > 0) {
|
||||
n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
|
||||
n = jim_nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
|
||||
if (n->name == NULL) {
|
||||
LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]);
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
@ -2958,7 +2947,7 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command)
|
|||
aarch64->isrmasking_mode = n->value;
|
||||
}
|
||||
|
||||
n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, aarch64->isrmasking_mode);
|
||||
n = jim_nvp_value2name_simple(nvp_maskisr_modes, aarch64->isrmasking_mode);
|
||||
command_print(CMD, "aarch64 interrupt mask %s", n->name);
|
||||
|
||||
return ERROR_OK;
|
||||
|
|
|
@ -574,6 +574,13 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
|
|||
retval = ERROR_JTAG_DEVICE_ERROR;
|
||||
break;
|
||||
}
|
||||
LOG_INFO("DAP transaction stalled during replay (WAIT) - resending");
|
||||
/* clear the sticky overrun condition */
|
||||
retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
|
||||
DP_CTRL_STAT, DPAP_WRITE,
|
||||
dap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);
|
||||
if (retval != ERROR_OK)
|
||||
break;
|
||||
} while (timeval_ms() - time_now < 1000);
|
||||
|
||||
if (retval == ERROR_OK) {
|
||||
|
|
|
@ -1467,7 +1467,7 @@ static int arc_configure_actionpoint(struct target *target, uint32_t ap_num,
|
|||
if (control_tt != AP_AC_TT_DISABLE) {
|
||||
|
||||
if (arc->actionpoints_num_avail < 1) {
|
||||
LOG_ERROR("No free actionpoints, maximim amount is %u",
|
||||
LOG_ERROR("No free actionpoints, maximum amount is %u",
|
||||
arc->actionpoints_num);
|
||||
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
||||
}
|
||||
|
|
|
@ -206,7 +206,7 @@ struct arc_common {
|
|||
bool dcache_invalidated;
|
||||
bool l2cache_invalidated;
|
||||
|
||||
/* Indicate if cach was built (for deinit function) */
|
||||
/* Indicate if cache was built (for deinit function) */
|
||||
bool core_aux_cache_built;
|
||||
bool bcr_cache_built;
|
||||
/* Closely Coupled memory(CCM) regions for performance-critical
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
static int arc_cmd_jim_get_uint32(Jim_GetOptInfo *goi, uint32_t *value)
|
||||
static int arc_cmd_jim_get_uint32(struct jim_getopt_info *goi, uint32_t *value)
|
||||
{
|
||||
jim_wide value_wide;
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_Wide(goi, &value_wide));
|
||||
JIM_CHECK_RETVAL(jim_getopt_wide(goi, &value_wide));
|
||||
*value = (uint32_t)value_wide;
|
||||
return JIM_OK;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ enum add_reg_type_flags {
|
|||
CFG_ADD_REG_TYPE_FLAGS_FLAG,
|
||||
};
|
||||
|
||||
static Jim_Nvp nvp_add_reg_type_flags_opts[] = {
|
||||
static struct jim_nvp nvp_add_reg_type_flags_opts[] = {
|
||||
{ .name = "-name", .value = CFG_ADD_REG_TYPE_FLAGS_NAME },
|
||||
{ .name = "-flag", .value = CFG_ADD_REG_TYPE_FLAGS_FLAG },
|
||||
{ .name = NULL, .value = -1 }
|
||||
|
@ -64,7 +64,7 @@ static const char *validate_register(const struct arc_reg_desc * const reg, bool
|
|||
|
||||
/* Helper function to read the name of register type or register from
|
||||
* configure files */
|
||||
static int jim_arc_read_reg_name_field(Jim_GetOptInfo *goi,
|
||||
static int jim_arc_read_reg_name_field(struct jim_getopt_info *goi,
|
||||
const char **name, int *name_len)
|
||||
{
|
||||
int e = JIM_OK;
|
||||
|
@ -73,12 +73,12 @@ static int jim_arc_read_reg_name_field(Jim_GetOptInfo *goi,
|
|||
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-name <name> ...");
|
||||
return JIM_ERR;
|
||||
}
|
||||
e = Jim_GetOpt_String(goi, name, name_len);
|
||||
e = jim_getopt_string(goi, name, name_len);
|
||||
return e;
|
||||
}
|
||||
|
||||
/* Helper function to read bitfields/flags of register type. */
|
||||
static int jim_arc_read_reg_type_field(Jim_GetOptInfo *goi, const char **field_name, int *field_name_len,
|
||||
static int jim_arc_read_reg_type_field(struct jim_getopt_info *goi, const char **field_name, int *field_name_len,
|
||||
struct arc_reg_bitfield *bitfields, int cur_field, int type)
|
||||
{
|
||||
jim_wide start_pos, end_pos;
|
||||
|
@ -90,12 +90,12 @@ static int jim_arc_read_reg_type_field(Jim_GetOptInfo *goi, const char **field_n
|
|||
return JIM_ERR;
|
||||
}
|
||||
|
||||
e = Jim_GetOpt_String(goi, field_name, field_name_len);
|
||||
e = jim_getopt_string(goi, field_name, field_name_len);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
/* read start position of bitfield/flag */
|
||||
e = Jim_GetOpt_Wide(goi, &start_pos);
|
||||
e = jim_getopt_wide(goi, &start_pos);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
|
@ -108,7 +108,7 @@ static int jim_arc_read_reg_type_field(Jim_GetOptInfo *goi, const char **field_n
|
|||
* than bitfields[cur_field].end remains start */
|
||||
if ((strcmp(Jim_String(goi->argv[0]), "-flag") && type == CFG_ADD_REG_TYPE_FLAG)
|
||||
|| (type == CFG_ADD_REG_TYPE_STRUCT)) {
|
||||
e = Jim_GetOpt_Wide(goi, &end_pos);
|
||||
e = jim_getopt_wide(goi, &end_pos);
|
||||
if (e != JIM_OK) {
|
||||
Jim_SetResultFormatted(goi->interp, "Error reading end position");
|
||||
return e;
|
||||
|
@ -125,8 +125,8 @@ static int jim_arc_read_reg_type_field(Jim_GetOptInfo *goi, const char **field_n
|
|||
static int jim_arc_add_reg_type_flags(Jim_Interp *interp, int argc,
|
||||
Jim_Obj * const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1));
|
||||
struct jim_getopt_info goi;
|
||||
JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1));
|
||||
|
||||
LOG_DEBUG("-");
|
||||
|
||||
|
@ -179,10 +179,10 @@ static int jim_arc_add_reg_type_flags(Jim_Interp *interp, int argc,
|
|||
flags->size = 4; /* For now ARC has only 32-bit registers */
|
||||
|
||||
while (goi.argc > 0 && e == JIM_OK) {
|
||||
Jim_Nvp *n;
|
||||
e = Jim_GetOpt_Nvp(&goi, nvp_add_reg_type_flags_opts, &n);
|
||||
struct jim_nvp *n;
|
||||
e = jim_getopt_nvp(&goi, nvp_add_reg_type_flags_opts, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(&goi, nvp_add_reg_type_flags_opts, 0);
|
||||
jim_getopt_nvp_unknown(&goi, nvp_add_reg_type_flags_opts, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ enum add_reg_type_struct {
|
|||
CFG_ADD_REG_TYPE_STRUCT_BITFIELD,
|
||||
};
|
||||
|
||||
static Jim_Nvp nvp_add_reg_type_struct_opts[] = {
|
||||
static struct jim_nvp nvp_add_reg_type_struct_opts[] = {
|
||||
{ .name = "-name", .value = CFG_ADD_REG_TYPE_STRUCT_NAME },
|
||||
{ .name = "-bitfield", .value = CFG_ADD_REG_TYPE_STRUCT_BITFIELD },
|
||||
{ .name = NULL, .value = -1 }
|
||||
|
@ -286,8 +286,8 @@ static int jim_arc_set_aux_reg(Jim_Interp *interp, int argc, Jim_Obj * const *ar
|
|||
uint32_t regnum;
|
||||
uint32_t value;
|
||||
|
||||
Jim_GetOptInfo goi;
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1));
|
||||
struct jim_getopt_info goi;
|
||||
JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1));
|
||||
|
||||
if (goi.argc != 2) {
|
||||
Jim_SetResultFormatted(goi.interp,
|
||||
|
@ -325,8 +325,8 @@ static int jim_arc_get_aux_reg(Jim_Interp *interp, int argc, Jim_Obj * const *ar
|
|||
uint32_t regnum;
|
||||
uint32_t value;
|
||||
|
||||
Jim_GetOptInfo goi;
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1));
|
||||
struct jim_getopt_info goi;
|
||||
JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1));
|
||||
|
||||
if (goi.argc != 1) {
|
||||
Jim_SetResultFormatted(goi.interp,
|
||||
|
@ -362,8 +362,8 @@ static int jim_arc_get_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *a
|
|||
uint32_t regnum;
|
||||
uint32_t value;
|
||||
|
||||
Jim_GetOptInfo goi;
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1));
|
||||
struct jim_getopt_info goi;
|
||||
JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1));
|
||||
|
||||
if (goi.argc != 1) {
|
||||
Jim_SetResultFormatted(goi.interp,
|
||||
|
@ -405,8 +405,8 @@ static int jim_arc_set_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *a
|
|||
uint32_t regnum;
|
||||
uint32_t value;
|
||||
|
||||
Jim_GetOptInfo goi;
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1));
|
||||
struct jim_getopt_info goi;
|
||||
JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1));
|
||||
|
||||
if (goi.argc != 2) {
|
||||
Jim_SetResultFormatted(goi.interp,
|
||||
|
@ -491,8 +491,8 @@ static const struct command_registration arc_jtag_command_group[] = {
|
|||
static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc,
|
||||
Jim_Obj * const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1));
|
||||
struct jim_getopt_info goi;
|
||||
JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1));
|
||||
|
||||
LOG_DEBUG("-");
|
||||
|
||||
|
@ -545,10 +545,10 @@ static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc,
|
|||
struct_type->size = 4; /* For now ARC has only 32-bit registers */
|
||||
|
||||
while (goi.argc > 0 && e == JIM_OK) {
|
||||
Jim_Nvp *n;
|
||||
e = Jim_GetOpt_Nvp(&goi, nvp_add_reg_type_struct_opts, &n);
|
||||
struct jim_nvp *n;
|
||||
e = jim_getopt_nvp(&goi, nvp_add_reg_type_struct_opts, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(&goi, nvp_add_reg_type_struct_opts, 0);
|
||||
jim_getopt_nvp_unknown(&goi, nvp_add_reg_type_struct_opts, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -642,7 +642,7 @@ enum opts_add_reg {
|
|||
CFG_ADD_REG_GENERAL,
|
||||
};
|
||||
|
||||
static Jim_Nvp opts_nvp_add_reg[] = {
|
||||
static struct jim_nvp opts_nvp_add_reg[] = {
|
||||
{ .name = "-name", .value = CFG_ADD_REG_NAME },
|
||||
{ .name = "-num", .value = CFG_ADD_REG_ARCH_NUM },
|
||||
{ .name = "-core", .value = CFG_ADD_REG_IS_CORE },
|
||||
|
@ -662,8 +662,8 @@ void free_reg_desc(struct arc_reg_desc *r)
|
|||
|
||||
static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1));
|
||||
struct jim_getopt_info goi;
|
||||
JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1));
|
||||
|
||||
struct arc_reg_desc *reg = calloc(1, sizeof(*reg));
|
||||
if (!reg) {
|
||||
|
@ -692,10 +692,10 @@ static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
|||
|
||||
/* Parse options. */
|
||||
while (goi.argc > 0) {
|
||||
Jim_Nvp *n;
|
||||
e = Jim_GetOpt_Nvp(&goi, opts_nvp_add_reg, &n);
|
||||
struct jim_nvp *n;
|
||||
e = jim_getopt_nvp(&goi, opts_nvp_add_reg, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(&goi, opts_nvp_add_reg, 0);
|
||||
jim_getopt_nvp_unknown(&goi, opts_nvp_add_reg, 0);
|
||||
free_reg_desc(reg);
|
||||
return e;
|
||||
}
|
||||
|
@ -732,7 +732,7 @@ static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
|||
return JIM_ERR;
|
||||
}
|
||||
|
||||
e = Jim_GetOpt_Wide(&goi, &archnum);
|
||||
e = jim_getopt_wide(&goi, &archnum);
|
||||
if (e != JIM_OK) {
|
||||
free_reg_desc(reg);
|
||||
return e;
|
||||
|
@ -845,12 +845,12 @@ COMMAND_HANDLER(arc_set_reg_exists)
|
|||
* Reads struct type register field */
|
||||
static int jim_arc_get_reg_field(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
struct jim_getopt_info goi;
|
||||
const char *reg_name, *field_name;
|
||||
uint32_t value;
|
||||
int retval;
|
||||
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1));
|
||||
JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1));
|
||||
|
||||
LOG_DEBUG("Reading register field");
|
||||
if (goi.argc != 2) {
|
||||
|
@ -863,8 +863,8 @@ static int jim_arc_get_reg_field(Jim_Interp *interp, int argc, Jim_Obj * const *
|
|||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_String(&goi, ®_name, NULL));
|
||||
JIM_CHECK_RETVAL(Jim_GetOpt_String(&goi, &field_name, NULL));
|
||||
JIM_CHECK_RETVAL(jim_getopt_string(&goi, ®_name, NULL));
|
||||
JIM_CHECK_RETVAL(jim_getopt_string(&goi, &field_name, NULL));
|
||||
assert(reg_name);
|
||||
assert(field_name);
|
||||
|
||||
|
@ -932,8 +932,8 @@ COMMAND_HANDLER(arc_l2_cache_disable_auto_cmd)
|
|||
static int jim_handle_actionpoints_num(Jim_Interp *interp, int argc,
|
||||
Jim_Obj * const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
|
||||
LOG_DEBUG("-");
|
||||
|
||||
|
|
|
@ -355,8 +355,7 @@ static int arm11_arch_state(struct target *target)
|
|||
/* REVISIT also display ARM11-specific MMU and cache status ... */
|
||||
|
||||
if (target->debug_reason == DBG_REASON_WATCHPOINT)
|
||||
LOG_USER("Watchpoint triggered at PC %#08x",
|
||||
(unsigned) arm11->dpm.wp_pc);
|
||||
LOG_USER("Watchpoint triggered at PC " TARGET_ADDR_FMT, arm11->dpm.wp_addr);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* This file implements support for the ARM Debug Interface version 5 (ADIv5)
|
||||
* debugging architecture. Compared with previous versions, this includes
|
||||
* a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message
|
||||
* transport, and focusses on memory mapped resources as defined by the
|
||||
* transport, and focuses on memory mapped resources as defined by the
|
||||
* CoreSight architecture.
|
||||
*
|
||||
* A key concept in ADIv5 is the Debug Access Port, or DAP. A DAP has two
|
||||
|
@ -1500,7 +1500,7 @@ enum adiv5_cfg_param {
|
|||
CFG_CTIBASE, /* DEPRECATED */
|
||||
};
|
||||
|
||||
static const Jim_Nvp nvp_config_opts[] = {
|
||||
static const struct jim_nvp nvp_config_opts[] = {
|
||||
{ .name = "-dap", .value = CFG_DAP },
|
||||
{ .name = "-ap-num", .value = CFG_AP_NUM },
|
||||
{ .name = "-baseaddr", .value = CFG_BASEADDR },
|
||||
|
@ -1508,7 +1508,7 @@ static const Jim_Nvp nvp_config_opts[] = {
|
|||
{ .name = NULL, .value = -1 }
|
||||
};
|
||||
|
||||
static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi,
|
||||
static int adiv5_jim_spot_configure(struct jim_getopt_info *goi,
|
||||
struct adiv5_dap **dap_p, int *ap_num_p, uint32_t *base_p)
|
||||
{
|
||||
if (!goi->argc)
|
||||
|
@ -1516,8 +1516,8 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi,
|
|||
|
||||
Jim_SetEmptyResult(goi->interp);
|
||||
|
||||
Jim_Nvp *n;
|
||||
int e = Jim_Nvp_name2value_obj(goi->interp, nvp_config_opts,
|
||||
struct jim_nvp *n;
|
||||
int e = jim_nvp_name2value_obj(goi->interp, nvp_config_opts,
|
||||
goi->argv[0], &n);
|
||||
if (e != JIM_OK)
|
||||
return JIM_CONTINUE;
|
||||
|
@ -1526,7 +1526,7 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi,
|
|||
if (!base_p && (n->value == CFG_BASEADDR || n->value == CFG_CTIBASE))
|
||||
return JIM_CONTINUE;
|
||||
|
||||
e = Jim_GetOpt_Obj(goi, NULL);
|
||||
e = jim_getopt_obj(goi, NULL);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
|
@ -1535,7 +1535,7 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi,
|
|||
if (goi->isconfigure) {
|
||||
Jim_Obj *o_t;
|
||||
struct adiv5_dap *dap;
|
||||
e = Jim_GetOpt_Obj(goi, &o_t);
|
||||
e = jim_getopt_obj(goi, &o_t);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
dap = dap_instance_by_jim_obj(goi->interp, o_t);
|
||||
|
@ -1563,7 +1563,7 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi,
|
|||
case CFG_AP_NUM:
|
||||
if (goi->isconfigure) {
|
||||
jim_wide ap_num;
|
||||
e = Jim_GetOpt_Wide(goi, &ap_num);
|
||||
e = jim_getopt_wide(goi, &ap_num);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
if (ap_num < 0 || ap_num > DP_APSEL_MAX) {
|
||||
|
@ -1588,7 +1588,7 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi,
|
|||
case CFG_BASEADDR:
|
||||
if (goi->isconfigure) {
|
||||
jim_wide base;
|
||||
e = Jim_GetOpt_Wide(goi, &base);
|
||||
e = jim_getopt_wide(goi, &base);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
*base_p = (uint32_t)base;
|
||||
|
@ -1607,7 +1607,7 @@ err_no_param:
|
|||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi)
|
||||
int adiv5_jim_configure(struct target *target, struct jim_getopt_info *goi)
|
||||
{
|
||||
struct adiv5_private_config *pc;
|
||||
int e;
|
||||
|
@ -1651,7 +1651,7 @@ int adiv5_verify_config(struct adiv5_private_config *pc)
|
|||
}
|
||||
|
||||
int adiv5_jim_mem_ap_spot_configure(struct adiv5_mem_ap_spot *cfg,
|
||||
Jim_GetOptInfo *goi)
|
||||
struct jim_getopt_info *goi)
|
||||
{
|
||||
return adiv5_jim_spot_configure(goi, &cfg->dap, &cfg->ap_num, &cfg->base);
|
||||
}
|
||||
|
|
|
@ -602,7 +602,7 @@ struct adiv5_private_config {
|
|||
};
|
||||
|
||||
extern int adiv5_verify_config(struct adiv5_private_config *pc);
|
||||
extern int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi);
|
||||
extern int adiv5_jim_configure(struct target *target, struct jim_getopt_info *goi);
|
||||
|
||||
struct adiv5_mem_ap_spot {
|
||||
struct adiv5_dap *dap;
|
||||
|
@ -612,6 +612,6 @@ struct adiv5_mem_ap_spot {
|
|||
|
||||
extern int adiv5_mem_ap_spot_init(struct adiv5_mem_ap_spot *p);
|
||||
extern int adiv5_jim_mem_ap_spot_configure(struct adiv5_mem_ap_spot *cfg,
|
||||
Jim_GetOptInfo *goi);
|
||||
struct jim_getopt_info *goi);
|
||||
|
||||
#endif /* OPENOCD_TARGET_ARM_ADI_V5_H */
|
||||
|
|
|
@ -430,7 +430,7 @@ static const struct command_registration cti_instance_command_handlers[] = {
|
|||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
static int cti_configure(Jim_GetOptInfo *goi, struct arm_cti *cti)
|
||||
static int cti_configure(struct jim_getopt_info *goi, struct arm_cti *cti)
|
||||
{
|
||||
/* parse config or cget options ... */
|
||||
while (goi->argc > 0) {
|
||||
|
@ -446,7 +446,7 @@ static int cti_configure(Jim_GetOptInfo *goi, struct arm_cti *cti)
|
|||
|
||||
return JIM_OK;
|
||||
}
|
||||
static int cti_create(Jim_GetOptInfo *goi)
|
||||
static int cti_create(struct jim_getopt_info *goi)
|
||||
{
|
||||
struct command_context *cmd_ctx;
|
||||
static struct arm_cti *cti;
|
||||
|
@ -463,7 +463,7 @@ static int cti_create(Jim_GetOptInfo *goi)
|
|||
return JIM_ERR;
|
||||
}
|
||||
/* COMMAND */
|
||||
Jim_GetOpt_Obj(goi, &new_cmd);
|
||||
jim_getopt_obj(goi, &new_cmd);
|
||||
/* does this command exist? */
|
||||
cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
|
||||
if (cmd) {
|
||||
|
@ -518,8 +518,8 @@ static int cti_create(Jim_GetOptInfo *goi)
|
|||
|
||||
static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
if (goi.argc < 2) {
|
||||
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
|
||||
"<name> [<cti_options> ...]");
|
||||
|
|
|
@ -156,31 +156,31 @@ enum dap_cfg_param {
|
|||
CFG_IGNORE_SYSPWRUPACK,
|
||||
};
|
||||
|
||||
static const Jim_Nvp nvp_config_opts[] = {
|
||||
static const struct jim_nvp nvp_config_opts[] = {
|
||||
{ .name = "-chain-position", .value = CFG_CHAIN_POSITION },
|
||||
{ .name = "-ignore-syspwrupack", .value = CFG_IGNORE_SYSPWRUPACK },
|
||||
{ .name = NULL, .value = -1 }
|
||||
};
|
||||
|
||||
static int dap_configure(Jim_GetOptInfo *goi, struct arm_dap_object *dap)
|
||||
static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap)
|
||||
{
|
||||
struct jtag_tap *tap = NULL;
|
||||
Jim_Nvp *n;
|
||||
struct jim_nvp *n;
|
||||
int e;
|
||||
|
||||
/* parse config or cget options ... */
|
||||
while (goi->argc > 0) {
|
||||
Jim_SetEmptyResult(goi->interp);
|
||||
|
||||
e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
|
||||
e = jim_getopt_nvp(goi, nvp_config_opts, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
|
||||
jim_getopt_nvp_unknown(goi, nvp_config_opts, 0);
|
||||
return e;
|
||||
}
|
||||
switch (n->value) {
|
||||
case CFG_CHAIN_POSITION: {
|
||||
Jim_Obj *o_t;
|
||||
e = Jim_GetOpt_Obj(goi, &o_t);
|
||||
e = jim_getopt_obj(goi, &o_t);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
tap = jtag_tap_by_jim_obj(goi->interp, o_t);
|
||||
|
@ -210,7 +210,7 @@ static int dap_configure(Jim_GetOptInfo *goi, struct arm_dap_object *dap)
|
|||
return JIM_OK;
|
||||
}
|
||||
|
||||
static int dap_create(Jim_GetOptInfo *goi)
|
||||
static int dap_create(struct jim_getopt_info *goi)
|
||||
{
|
||||
struct command_context *cmd_ctx;
|
||||
static struct arm_dap_object *dap;
|
||||
|
@ -227,7 +227,7 @@ static int dap_create(Jim_GetOptInfo *goi)
|
|||
return JIM_ERR;
|
||||
}
|
||||
/* COMMAND */
|
||||
Jim_GetOpt_Obj(goi, &new_cmd);
|
||||
jim_getopt_obj(goi, &new_cmd);
|
||||
/* does this command exist? */
|
||||
cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
|
||||
if (cmd) {
|
||||
|
@ -276,8 +276,8 @@ static int dap_create(Jim_GetOptInfo *goi)
|
|||
|
||||
static int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
if (goi.argc < 2) {
|
||||
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
|
||||
"<name> [<dap_options> ...]");
|
||||
|
|
|
@ -1010,7 +1010,7 @@ void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr)
|
|||
/* ?? */
|
||||
break;
|
||||
}
|
||||
dpm->wp_pc = addr;
|
||||
dpm->wp_addr = addr;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
@ -1088,9 +1088,11 @@ int arm_dpm_setup(struct arm_dpm *dpm)
|
|||
target->type->remove_breakpoint = dpm_remove_breakpoint;
|
||||
}
|
||||
|
||||
/* watchpoint setup */
|
||||
target->type->add_watchpoint = dpm_add_watchpoint;
|
||||
target->type->remove_watchpoint = dpm_remove_watchpoint;
|
||||
/* watchpoint setup -- optional until it works everywhere */
|
||||
if (!target->type->add_watchpoint) {
|
||||
target->type->add_watchpoint = dpm_add_watchpoint;
|
||||
target->type->remove_watchpoint = dpm_remove_watchpoint;
|
||||
}
|
||||
|
||||
/* FIXME add vector catch support */
|
||||
|
||||
|
|
|
@ -137,8 +137,12 @@ struct arm_dpm {
|
|||
struct dpm_bp *dbp;
|
||||
struct dpm_wp *dwp;
|
||||
|
||||
/** Address of the instruction which triggered a watchpoint. */
|
||||
target_addr_t wp_pc;
|
||||
/**
|
||||
* Target dependent watchpoint address.
|
||||
* Either the address of the instruction which triggered a watchpoint
|
||||
* or the memory address whose access triggered a watchpoint.
|
||||
*/
|
||||
target_addr_t wp_addr;
|
||||
|
||||
/** Recent value of DSCR. */
|
||||
uint32_t dscr;
|
||||
|
|
|
@ -73,7 +73,7 @@ enum arm_tpiu_swo_event {
|
|||
TPIU_SWO_EVENT_POST_DISABLE,
|
||||
};
|
||||
|
||||
static const Jim_Nvp nvp_arm_tpiu_swo_event[] = {
|
||||
static const struct jim_nvp nvp_arm_tpiu_swo_event[] = {
|
||||
{ .value = TPIU_SWO_EVENT_PRE_ENABLE, .name = "pre-enable" },
|
||||
{ .value = TPIU_SWO_EVENT_POST_ENABLE, .name = "post-enable" },
|
||||
{ .value = TPIU_SWO_EVENT_PRE_DISABLE, .name = "pre-disable" },
|
||||
|
@ -168,7 +168,7 @@ static void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_
|
|||
|
||||
LOG_DEBUG("TPIU/SWO: %s event: %s (%d) action : %s",
|
||||
obj->name,
|
||||
Jim_Nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name,
|
||||
jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name,
|
||||
event,
|
||||
Jim_GetString(ea->body, NULL));
|
||||
|
||||
|
@ -185,7 +185,7 @@ static void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_
|
|||
|
||||
Jim_MakeErrorMessage(ea->interp);
|
||||
LOG_USER("Error executing event %s on TPIU/SWO %s:\n%s",
|
||||
Jim_Nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name,
|
||||
jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name,
|
||||
obj->name,
|
||||
Jim_GetString(Jim_GetResult(ea->interp), NULL));
|
||||
/* clean both error code and stacktrace before return */
|
||||
|
@ -297,7 +297,7 @@ COMMAND_HANDLER(handle_arm_tpiu_swo_event_list)
|
|||
"----------------------------------------");
|
||||
|
||||
for (struct arm_tpiu_swo_event_action *ea = obj->event_action; ea; ea = ea->next) {
|
||||
Jim_Nvp *opt = Jim_Nvp_value2name_simple(nvp_arm_tpiu_swo_event, ea->event);
|
||||
struct jim_nvp *opt = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, ea->event);
|
||||
command_print(CMD, "%-25s | %s",
|
||||
opt->name, Jim_GetString(ea->body, NULL));
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ enum arm_tpiu_swo_cfg_param {
|
|||
CFG_EVENT,
|
||||
};
|
||||
|
||||
static const Jim_Nvp nvp_arm_tpiu_swo_config_opts[] = {
|
||||
static const struct jim_nvp nvp_arm_tpiu_swo_config_opts[] = {
|
||||
{ .name = "-port-width", .value = CFG_PORT_WIDTH },
|
||||
{ .name = "-protocol", .value = CFG_PROTOCOL },
|
||||
{ .name = "-formatter", .value = CFG_FORMATTER },
|
||||
|
@ -323,21 +323,21 @@ static const Jim_Nvp nvp_arm_tpiu_swo_config_opts[] = {
|
|||
{ .name = "-pin-freq", .value = CFG_BITRATE },
|
||||
{ .name = "-output", .value = CFG_OUTFILE },
|
||||
{ .name = "-event", .value = CFG_EVENT },
|
||||
/* handled by mem_ap_spot, added for Jim_GetOpt_NvpUnknown() */
|
||||
/* handled by mem_ap_spot, added for jim_getopt_nvp_unknown() */
|
||||
{ .name = "-dap", .value = -1 },
|
||||
{ .name = "-ap-num", .value = -1 },
|
||||
{ .name = "-baseaddr", .value = -1 },
|
||||
{ .name = NULL, .value = -1 },
|
||||
};
|
||||
|
||||
static const Jim_Nvp nvp_arm_tpiu_swo_protocol_opts[] = {
|
||||
static const struct jim_nvp nvp_arm_tpiu_swo_protocol_opts[] = {
|
||||
{ .name = "sync", .value = TPIU_SPPR_PROTOCOL_SYNC },
|
||||
{ .name = "uart", .value = TPIU_SPPR_PROTOCOL_UART },
|
||||
{ .name = "manchester", .value = TPIU_SPPR_PROTOCOL_MANCHESTER },
|
||||
{ .name = NULL, .value = -1 },
|
||||
};
|
||||
|
||||
static const Jim_Nvp nvp_arm_tpiu_swo_bool_opts[] = {
|
||||
static const struct jim_nvp nvp_arm_tpiu_swo_bool_opts[] = {
|
||||
{ .name = "on", .value = 1 },
|
||||
{ .name = "yes", .value = 1 },
|
||||
{ .name = "1", .value = 1 },
|
||||
|
@ -349,7 +349,7 @@ static const Jim_Nvp nvp_arm_tpiu_swo_bool_opts[] = {
|
|||
{ .name = NULL, .value = -1 },
|
||||
};
|
||||
|
||||
static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_object *obj)
|
||||
static int arm_tpiu_swo_configure(struct jim_getopt_info *goi, struct arm_tpiu_swo_object *obj)
|
||||
{
|
||||
assert(obj != NULL);
|
||||
|
||||
|
@ -368,10 +368,10 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec
|
|||
if (e == JIM_ERR)
|
||||
return e;
|
||||
|
||||
Jim_Nvp *n;
|
||||
e = Jim_GetOpt_Nvp(goi, nvp_arm_tpiu_swo_config_opts, &n);
|
||||
struct jim_nvp *n;
|
||||
e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_config_opts, &n);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(goi, nvp_arm_tpiu_swo_config_opts, 0);
|
||||
jim_getopt_nvp_unknown(goi, nvp_arm_tpiu_swo_config_opts, 0);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -379,7 +379,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec
|
|||
case CFG_PORT_WIDTH:
|
||||
if (goi->isconfigure) {
|
||||
jim_wide port_width;
|
||||
e = Jim_GetOpt_Wide(goi, &port_width);
|
||||
e = jim_getopt_wide(goi, &port_width);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
if (port_width < 1 || port_width > 32) {
|
||||
|
@ -395,16 +395,16 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec
|
|||
break;
|
||||
case CFG_PROTOCOL:
|
||||
if (goi->isconfigure) {
|
||||
Jim_Nvp *p;
|
||||
e = Jim_GetOpt_Nvp(goi, nvp_arm_tpiu_swo_protocol_opts, &p);
|
||||
struct jim_nvp *p;
|
||||
e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_protocol_opts, &p);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
obj->pin_protocol = p->value;
|
||||
} else {
|
||||
if (goi->argc)
|
||||
goto err_no_params;
|
||||
Jim_Nvp *p;
|
||||
e = Jim_Nvp_value2name(goi->interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p);
|
||||
struct jim_nvp *p;
|
||||
e = jim_nvp_value2name(goi->interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p);
|
||||
if (e != JIM_OK) {
|
||||
Jim_SetResultString(goi->interp, "protocol error", -1);
|
||||
return JIM_ERR;
|
||||
|
@ -414,16 +414,16 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec
|
|||
break;
|
||||
case CFG_FORMATTER:
|
||||
if (goi->isconfigure) {
|
||||
Jim_Nvp *p;
|
||||
e = Jim_GetOpt_Nvp(goi, nvp_arm_tpiu_swo_bool_opts, &p);
|
||||
struct jim_nvp *p;
|
||||
e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_bool_opts, &p);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
obj->en_formatter = p->value;
|
||||
} else {
|
||||
if (goi->argc)
|
||||
goto err_no_params;
|
||||
Jim_Nvp *p;
|
||||
e = Jim_Nvp_value2name(goi->interp, nvp_arm_tpiu_swo_bool_opts, obj->en_formatter, &p);
|
||||
struct jim_nvp *p;
|
||||
e = jim_nvp_value2name(goi->interp, nvp_arm_tpiu_swo_bool_opts, obj->en_formatter, &p);
|
||||
if (e != JIM_OK) {
|
||||
Jim_SetResultString(goi->interp, "formatter error", -1);
|
||||
return JIM_ERR;
|
||||
|
@ -434,7 +434,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec
|
|||
case CFG_TRACECLKIN:
|
||||
if (goi->isconfigure) {
|
||||
jim_wide clk;
|
||||
e = Jim_GetOpt_Wide(goi, &clk);
|
||||
e = jim_getopt_wide(goi, &clk);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
obj->traceclkin_freq = clk;
|
||||
|
@ -447,7 +447,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec
|
|||
case CFG_BITRATE:
|
||||
if (goi->isconfigure) {
|
||||
jim_wide clk;
|
||||
e = Jim_GetOpt_Wide(goi, &clk);
|
||||
e = jim_getopt_wide(goi, &clk);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
obj->swo_pin_freq = clk;
|
||||
|
@ -460,7 +460,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec
|
|||
case CFG_OUTFILE:
|
||||
if (goi->isconfigure) {
|
||||
const char *s;
|
||||
e = Jim_GetOpt_String(goi, &s, NULL);
|
||||
e = jim_getopt_string(goi, &s, NULL);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
if (s[0] == ':') {
|
||||
|
@ -498,13 +498,13 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec
|
|||
}
|
||||
|
||||
{
|
||||
Jim_Nvp *p;
|
||||
struct jim_nvp *p;
|
||||
Jim_Obj *o;
|
||||
struct arm_tpiu_swo_event_action *ea = obj->event_action;
|
||||
|
||||
e = Jim_GetOpt_Nvp(goi, nvp_arm_tpiu_swo_event, &p);
|
||||
e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_event, &p);
|
||||
if (e != JIM_OK) {
|
||||
Jim_GetOpt_NvpUnknown(goi, nvp_arm_tpiu_swo_event, 1);
|
||||
jim_getopt_nvp_unknown(goi, nvp_arm_tpiu_swo_event, 1);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -529,7 +529,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec
|
|||
Jim_DecrRefCount(ea->interp, ea->body);
|
||||
ea->event = p->value;
|
||||
ea->interp = goi->interp;
|
||||
Jim_GetOpt_Obj(goi, &o);
|
||||
jim_getopt_obj(goi, &o);
|
||||
ea->body = Jim_DuplicateObj(goi->interp, o);
|
||||
Jim_IncrRefCount(ea->body);
|
||||
} else {
|
||||
|
@ -551,9 +551,9 @@ 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;
|
||||
struct jim_getopt_info goi;
|
||||
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
goi.isconfigure = !strcmp(c->name, "configure");
|
||||
if (goi.argc < 1) {
|
||||
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
|
||||
|
@ -670,8 +670,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
|
|||
value = 0;
|
||||
}
|
||||
if (!value) {
|
||||
Jim_Nvp *p;
|
||||
Jim_Nvp_value2name(interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p);
|
||||
struct jim_nvp *p;
|
||||
jim_nvp_value2name(interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p);
|
||||
LOG_ERROR("%s does not support protocol %s", obj->name, p->name);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
@ -897,8 +897,8 @@ static int arm_tpiu_swo_create(Jim_Interp *interp, struct arm_tpiu_swo_object *o
|
|||
|
||||
static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
if (goi.argc < 1) {
|
||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv, "?name? ..options...");
|
||||
return JIM_ERR;
|
||||
|
@ -915,7 +915,7 @@ static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const
|
|||
obj->port_width = 1;
|
||||
|
||||
Jim_Obj *n;
|
||||
Jim_GetOpt_Obj(&goi, &n);
|
||||
jim_getopt_obj(&goi, &n);
|
||||
obj->name = strdup(Jim_GetString(n, NULL));
|
||||
if (!obj->name) {
|
||||
LOG_ERROR("Out of memory");
|
||||
|
|
|
@ -1149,7 +1149,7 @@ static const struct command_registration arm_exec_command_handlers[] = {
|
|||
.handler = handle_arm_disassemble_command,
|
||||
.mode = COMMAND_EXEC,
|
||||
.usage = "address [count ['thumb']]",
|
||||
.help = "disassemble instructions ",
|
||||
.help = "disassemble instructions",
|
||||
},
|
||||
{
|
||||
.name = "mcr",
|
||||
|
|
|
@ -570,9 +570,6 @@ int armv7a_arch_state(struct target *target)
|
|||
|
||||
if (arm->core_mode == ARM_MODE_ABT)
|
||||
armv7a_show_fault_registers(target);
|
||||
if (target->debug_reason == DBG_REASON_WATCHPOINT)
|
||||
LOG_USER("Watchpoint triggered at PC %#08x",
|
||||
(unsigned) armv7a->dpm.wp_pc);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
|
|
@ -325,7 +325,7 @@ static const struct command_registration arm7a_l2x_cache_commands[] = {
|
|||
.name = "conf",
|
||||
.handler = armv7a_l2x_cache_conf_cmd,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "configure l2x cache ",
|
||||
.help = "configure l2x cache",
|
||||
.usage = "<base_addr> <number_of_way>",
|
||||
},
|
||||
{
|
||||
|
|
|
@ -125,6 +125,29 @@ static const struct {
|
|||
{ ARMV7M_FAULTMASK, "faultmask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
{ ARMV7M_CONTROL, "control", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
|
||||
/* ARMv8-M specific registers */
|
||||
{ ARMV8M_MSP_NS, "msp_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
|
||||
{ ARMV8M_PSP_NS, "psp_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
|
||||
{ ARMV8M_MSP_S, "msp_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
|
||||
{ ARMV8M_PSP_S, "psp_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
|
||||
{ ARMV8M_MSPLIM_S, "msplim_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
|
||||
{ ARMV8M_PSPLIM_S, "psplim_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
|
||||
{ ARMV8M_MSPLIM_NS, "msplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
|
||||
{ ARMV8M_PSPLIM_NS, "psplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
|
||||
|
||||
{ ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S, "pmsk_bpri_fltmsk_ctrl_s", 32, REG_TYPE_INT, NULL, NULL },
|
||||
{ ARMV8M_PRIMASK_S, "primask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
{ ARMV8M_BASEPRI_S, "basepri_s", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
{ ARMV8M_FAULTMASK_S, "faultmask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
{ ARMV8M_CONTROL_S, "control_s", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
|
||||
{ ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS, "pmsk_bpri_fltmsk_ctrl_ns", 32, REG_TYPE_INT, NULL, NULL },
|
||||
{ ARMV8M_PRIMASK_NS, "primask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
{ ARMV8M_BASEPRI_NS, "basepri_ns", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
{ ARMV8M_FAULTMASK_NS, "faultmask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
{ ARMV8M_CONTROL_NS, "control_ns", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
|
||||
|
||||
/* FPU registers */
|
||||
{ ARMV7M_D0, "d0", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" },
|
||||
{ ARMV7M_D1, "d1", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" },
|
||||
{ ARMV7M_D2, "d2", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" },
|
||||
|
@ -243,6 +266,15 @@ static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id)
|
|||
case ARMV7M_PMSK_BPRI_FLTMSK_CTRL:
|
||||
return ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL;
|
||||
|
||||
case ARMV8M_MSP_NS...ARMV8M_PSPLIM_NS:
|
||||
return arm_reg_id - ARMV8M_MSP_NS + ARMV8M_REGSEL_MSP_NS;
|
||||
|
||||
case ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S:
|
||||
return ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_S;
|
||||
|
||||
case ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS:
|
||||
return ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_NS;
|
||||
|
||||
case ARMV7M_FPSCR:
|
||||
return ARMV7M_REGSEL_FPSCR;
|
||||
|
||||
|
@ -258,28 +290,26 @@ static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id)
|
|||
static bool armv7m_map_reg_packing(unsigned int arm_reg_id,
|
||||
unsigned int *reg32_id, uint32_t *offset)
|
||||
{
|
||||
|
||||
switch (arm_reg_id) {
|
||||
|
||||
case ARMV7M_PRIMASK:
|
||||
case ARMV7M_PRIMASK...ARMV7M_CONTROL:
|
||||
*reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
|
||||
*offset = 0;
|
||||
*offset = arm_reg_id - ARMV7M_PRIMASK;
|
||||
return true;
|
||||
case ARMV7M_BASEPRI:
|
||||
*reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
|
||||
*offset = 1;
|
||||
case ARMV8M_PRIMASK_S...ARMV8M_CONTROL_S:
|
||||
*reg32_id = ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S;
|
||||
*offset = arm_reg_id - ARMV8M_PRIMASK_S;
|
||||
return true;
|
||||
case ARMV7M_FAULTMASK:
|
||||
*reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
|
||||
*offset = 2;
|
||||
return true;
|
||||
case ARMV7M_CONTROL:
|
||||
*reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
|
||||
*offset = 3;
|
||||
case ARMV8M_PRIMASK_NS...ARMV8M_CONTROL_NS:
|
||||
*reg32_id = ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS;
|
||||
*offset = arm_reg_id - ARMV8M_PRIMASK_NS;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int armv7m_read_core_reg(struct target *target, struct reg *r,
|
||||
|
@ -299,11 +329,17 @@ static int armv7m_read_core_reg(struct target *target, struct reg *r,
|
|||
|
||||
if (r->size <= 8) {
|
||||
/* any 8-bit or shorter register is packed */
|
||||
uint32_t offset = 0; /* silence false gcc warning */
|
||||
uint32_t offset;
|
||||
unsigned int reg32_id;
|
||||
|
||||
bool is_packed = armv7m_map_reg_packing(num, ®32_id, &offset);
|
||||
assert(is_packed);
|
||||
if (!is_packed) {
|
||||
/* We should not get here as all 8-bit or shorter registers
|
||||
* are packed */
|
||||
assert(false);
|
||||
/* assert() does nothing if NDEBUG is defined */
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
struct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id];
|
||||
|
||||
/* Read 32-bit container register if not cached */
|
||||
|
@ -364,11 +400,17 @@ static int armv7m_write_core_reg(struct target *target, struct reg *r,
|
|||
|
||||
if (r->size <= 8) {
|
||||
/* any 8-bit or shorter register is packed */
|
||||
uint32_t offset = 0; /* silence false gcc warning */
|
||||
uint32_t offset;
|
||||
unsigned int reg32_id;
|
||||
|
||||
bool is_packed = armv7m_map_reg_packing(num, ®32_id, &offset);
|
||||
assert(is_packed);
|
||||
if (!is_packed) {
|
||||
/* We should not get here as all 8-bit or shorter registers
|
||||
* are packed */
|
||||
assert(false);
|
||||
/* assert() does nothing if NDEBUG is defined */
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
struct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id];
|
||||
|
||||
if (!r32->valid) {
|
||||
|
@ -743,7 +785,8 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target)
|
|||
reg_list[i].value = arch_info[i].value;
|
||||
reg_list[i].dirty = false;
|
||||
reg_list[i].valid = false;
|
||||
reg_list[i].hidden = i == ARMV7M_PMSK_BPRI_FLTMSK_CTRL;
|
||||
reg_list[i].hidden = (i == ARMV7M_PMSK_BPRI_FLTMSK_CTRL ||
|
||||
i == ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS || i == ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S);
|
||||
reg_list[i].type = &armv7m_reg_type;
|
||||
reg_list[i].arch_info = &arch_info[i];
|
||||
|
||||
|
|
|
@ -60,7 +60,18 @@ enum {
|
|||
ARMV7M_REGSEL_MSP,
|
||||
ARMV7M_REGSEL_PSP,
|
||||
|
||||
ARMV8M_REGSEL_MSP_NS = 0x18,
|
||||
ARMV8M_REGSEL_PSP_NS,
|
||||
ARMV8M_REGSEL_MSP_S,
|
||||
ARMV8M_REGSEL_PSP_S,
|
||||
ARMV8M_REGSEL_MSPLIM_S,
|
||||
ARMV8M_REGSEL_PSPLIM_S,
|
||||
ARMV8M_REGSEL_MSPLIM_NS,
|
||||
ARMV8M_REGSEL_PSPLIM_NS,
|
||||
|
||||
ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL = 0x14,
|
||||
ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_S = 0x22,
|
||||
ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_NS = 0x23,
|
||||
ARMV7M_REGSEL_FPSCR = 0x21,
|
||||
|
||||
/* 32bit Floating-point registers */
|
||||
|
@ -129,6 +140,8 @@ enum {
|
|||
|
||||
/* following indices are arbitrary, do not match DCRSR.REGSEL selectors */
|
||||
|
||||
/* A block of container and contained registers follows:
|
||||
* THE ORDER IS IMPORTANT to the end of the block ! */
|
||||
/* working register for packing/unpacking special regs, hidden from gdb */
|
||||
ARMV7M_PMSK_BPRI_FLTMSK_CTRL,
|
||||
|
||||
|
@ -142,6 +155,35 @@ enum {
|
|||
ARMV7M_BASEPRI,
|
||||
ARMV7M_FAULTMASK,
|
||||
ARMV7M_CONTROL,
|
||||
/* The end of block of container and contained registers */
|
||||
|
||||
/* ARMv8-M specific registers */
|
||||
ARMV8M_MSP_NS,
|
||||
ARMV8M_PSP_NS,
|
||||
ARMV8M_MSP_S,
|
||||
ARMV8M_PSP_S,
|
||||
ARMV8M_MSPLIM_S,
|
||||
ARMV8M_PSPLIM_S,
|
||||
ARMV8M_MSPLIM_NS,
|
||||
ARMV8M_PSPLIM_NS,
|
||||
|
||||
/* A block of container and contained registers follows:
|
||||
* THE ORDER IS IMPORTANT to the end of the block ! */
|
||||
ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S,
|
||||
ARMV8M_PRIMASK_S,
|
||||
ARMV8M_BASEPRI_S,
|
||||
ARMV8M_FAULTMASK_S,
|
||||
ARMV8M_CONTROL_S,
|
||||
/* The end of block of container and contained registers */
|
||||
|
||||
/* A block of container and contained registers follows:
|
||||
* THE ORDER IS IMPORTANT to the end of the block ! */
|
||||
ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS,
|
||||
ARMV8M_PRIMASK_NS,
|
||||
ARMV8M_BASEPRI_NS,
|
||||
ARMV8M_FAULTMASK_NS,
|
||||
ARMV8M_CONTROL_NS,
|
||||
/* The end of block of container and contained registers */
|
||||
|
||||
/* 64bit Floating-point registers */
|
||||
ARMV7M_D0,
|
||||
|
@ -170,6 +212,8 @@ enum {
|
|||
ARMV7M_CORE_LAST_REG = ARMV7M_xPSR,
|
||||
ARMV7M_FPU_FIRST_REG = ARMV7M_D0,
|
||||
ARMV7M_FPU_LAST_REG = ARMV7M_FPSCR,
|
||||
ARMV8M_FIRST_REG = ARMV8M_MSP_NS,
|
||||
ARMV8M_LAST_REG = ARMV8M_CONTROL_NS,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -184,7 +228,7 @@ enum {
|
|||
#define ARMV7M_COMMON_MAGIC 0x2A452A45
|
||||
|
||||
struct armv7m_common {
|
||||
struct arm arm;
|
||||
struct arm arm;
|
||||
|
||||
int common_magic;
|
||||
int exception_number;
|
||||
|
|
|
@ -1025,7 +1025,7 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command)
|
|||
unsigned int argp = 0;
|
||||
int retval;
|
||||
|
||||
static const Jim_Nvp nvp_ecatch_modes[] = {
|
||||
static const struct jim_nvp nvp_ecatch_modes[] = {
|
||||
{ .name = "off", .value = 0 },
|
||||
{ .name = "nsec_el1", .value = (1 << 5) },
|
||||
{ .name = "nsec_el2", .value = (2 << 5) },
|
||||
|
@ -1035,7 +1035,7 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command)
|
|||
{ .name = "sec_el13", .value = (5 << 1) },
|
||||
{ .name = NULL, .value = -1 },
|
||||
};
|
||||
const Jim_Nvp *n;
|
||||
const struct jim_nvp *n;
|
||||
|
||||
if (CMD_ARGC == 0) {
|
||||
const char *sec = NULL, *nsec = NULL;
|
||||
|
@ -1045,11 +1045,11 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command)
|
|||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
n = Jim_Nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0x0f);
|
||||
n = jim_nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0x0f);
|
||||
if (n->name != NULL)
|
||||
sec = n->name;
|
||||
|
||||
n = Jim_Nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0xf0);
|
||||
n = jim_nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0xf0);
|
||||
if (n->name != NULL)
|
||||
nsec = n->name;
|
||||
|
||||
|
@ -1063,7 +1063,7 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command)
|
|||
}
|
||||
|
||||
while (CMD_ARGC > argp) {
|
||||
n = Jim_Nvp_name2value_simple(nvp_ecatch_modes, CMD_ARGV[argp]);
|
||||
n = jim_nvp_name2value_simple(nvp_ecatch_modes, CMD_ARGV[argp]);
|
||||
if (n->name == NULL) {
|
||||
LOG_ERROR("Unknown option: %s", CMD_ARGV[argp]);
|
||||
return ERROR_FAIL;
|
||||
|
@ -1169,8 +1169,7 @@ int armv8_arch_state(struct target *target)
|
|||
armv8_show_fault_registers(target);
|
||||
|
||||
if (target->debug_reason == DBG_REASON_WATCHPOINT)
|
||||
LOG_USER("Watchpoint triggered at PC %#08x",
|
||||
(unsigned) armv8->dpm.wp_pc);
|
||||
LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT, armv8->dpm.wp_addr);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
|
|
@ -257,8 +257,8 @@ static inline bool is_armv8(struct armv8_common *armv8)
|
|||
|
||||
#define CPUV8_DBG_EDESR 0x20
|
||||
#define CPUV8_DBG_EDECR 0x24
|
||||
#define CPUV8_DBG_WFAR0 0x30
|
||||
#define CPUV8_DBG_WFAR1 0x34
|
||||
#define CPUV8_DBG_EDWAR0 0x30
|
||||
#define CPUV8_DBG_EDWAR1 0x34
|
||||
#define CPUV8_DBG_DSCR 0x088
|
||||
#define CPUV8_DBG_DRCR 0x090
|
||||
#define CPUV8_DBG_ECCR 0x098
|
||||
|
|
|
@ -1279,27 +1279,6 @@ static int dpmv8_remove_watchpoint(struct target *target, struct watchpoint *wp)
|
|||
return retval;
|
||||
}
|
||||
|
||||
void armv8_dpm_report_wfar(struct arm_dpm *dpm, uint64_t addr)
|
||||
{
|
||||
switch (dpm->arm->core_state) {
|
||||
case ARM_STATE_ARM:
|
||||
case ARM_STATE_AARCH64:
|
||||
addr -= 8;
|
||||
break;
|
||||
case ARM_STATE_THUMB:
|
||||
case ARM_STATE_THUMB_EE:
|
||||
addr -= 4;
|
||||
break;
|
||||
case ARM_STATE_JAZELLE:
|
||||
/* ?? */
|
||||
break;
|
||||
default:
|
||||
LOG_DEBUG("Unknown core_state");
|
||||
break;
|
||||
}
|
||||
dpm->wp_pc = addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle exceptions taken in debug state. This happens mostly for memory
|
||||
* accesses that violated a MMU policy. Taking an exception while in debug
|
||||
|
|
|
@ -38,8 +38,6 @@ int armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode);
|
|||
|
||||
int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp);
|
||||
|
||||
void armv8_dpm_report_wfar(struct arm_dpm *dpm, uint64_t wfar);
|
||||
|
||||
/* DSCR bits; see ARMv7a arch spec section C10.3.1.
|
||||
* Not all v7 bits are valid in v6.
|
||||
*/
|
||||
|
|
|
@ -176,7 +176,7 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,
|
|||
*/
|
||||
if (addr & 3) {
|
||||
/*
|
||||
* mwa_read will read whole world, no nead to fiddle
|
||||
* mwa_read will read whole world, no need to fiddle
|
||||
* with address. It will be truncated in set_addr
|
||||
*/
|
||||
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
|
||||
|
@ -248,7 +248,7 @@ int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,
|
|||
*/
|
||||
if (addr & 3) {
|
||||
/*
|
||||
* mwa_read will read whole world, no nead to fiddle
|
||||
* mwa_read will read whole world, no need to fiddle
|
||||
* with address. It will be truncated in set_addr
|
||||
*/
|
||||
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
* Copyright (C) 2013 Kamal Dasu *
|
||||
* kdasu.kdev@gmail.com *
|
||||
* *
|
||||
* Copyright (C) 2016 Chengyu Zheng *
|
||||
* chengyu.zheng@polimi.it : watchpoint support *
|
||||
* *
|
||||
* 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 *
|
||||
|
@ -58,6 +61,7 @@
|
|||
#include "jtag/interface.h"
|
||||
#include "transport/transport.h"
|
||||
#include "smp.h"
|
||||
#include <helper/bits.h>
|
||||
#include <helper/time_support.h>
|
||||
|
||||
static int cortex_a_poll(struct target *target);
|
||||
|
@ -80,6 +84,16 @@ static int cortex_a_virt2phys(struct target *target,
|
|||
static int cortex_a_read_cpu_memory(struct target *target,
|
||||
uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
|
||||
|
||||
static unsigned int ilog2(unsigned int x)
|
||||
{
|
||||
unsigned int y = 0;
|
||||
x /= 2;
|
||||
while (x) {
|
||||
++y;
|
||||
x /= 2;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
/* restore cp15_control_reg at resume */
|
||||
static int cortex_a_restore_cp15_control_reg(struct target *target)
|
||||
|
@ -1658,6 +1672,200 @@ static int cortex_a_remove_breakpoint(struct target *target, struct breakpoint *
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a watchpoint for an Cortex-A target in one of the watchpoint units. It is
|
||||
* considered a bug to call this function when there are no available watchpoint
|
||||
* units.
|
||||
*
|
||||
* @param target Pointer to an Cortex-A target to set a watchpoint on
|
||||
* @param watchpoint Pointer to the watchpoint to be set
|
||||
* @return Error status if watchpoint set fails or the result of executing the
|
||||
* JTAG queue
|
||||
*/
|
||||
static int cortex_a_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
|
||||
{
|
||||
int retval = ERROR_OK;
|
||||
int wrp_i = 0;
|
||||
uint32_t control;
|
||||
uint32_t address;
|
||||
uint8_t address_mask;
|
||||
uint8_t byte_address_select;
|
||||
uint8_t load_store_access_control = 0x3;
|
||||
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
||||
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
|
||||
struct cortex_a_wrp *wrp_list = cortex_a->wrp_list;
|
||||
|
||||
if (watchpoint->set) {
|
||||
LOG_WARNING("watchpoint already set");
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* check available context WRPs */
|
||||
while (wrp_list[wrp_i].used && (wrp_i < cortex_a->wrp_num))
|
||||
wrp_i++;
|
||||
|
||||
if (wrp_i >= cortex_a->wrp_num) {
|
||||
LOG_ERROR("ERROR Can not find free Watchpoint Register Pair");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (watchpoint->length == 0 || watchpoint->length > 0x80000000U ||
|
||||
(watchpoint->length & (watchpoint->length - 1))) {
|
||||
LOG_WARNING("watchpoint length must be a power of 2");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (watchpoint->address & (watchpoint->length - 1)) {
|
||||
LOG_WARNING("watchpoint address must be aligned at length");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
/* FIXME: ARM DDI 0406C: address_mask is optional. What to do if it's missing? */
|
||||
/* handle wp length 1 and 2 through byte select */
|
||||
switch (watchpoint->length) {
|
||||
case 1:
|
||||
byte_address_select = BIT(watchpoint->address & 0x3);
|
||||
address = watchpoint->address & ~0x3;
|
||||
address_mask = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
byte_address_select = 0x03 << (watchpoint->address & 0x2);
|
||||
address = watchpoint->address & ~0x3;
|
||||
address_mask = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
byte_address_select = 0x0f;
|
||||
address = watchpoint->address;
|
||||
address_mask = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
byte_address_select = 0xff;
|
||||
address = watchpoint->address;
|
||||
address_mask = ilog2(watchpoint->length);
|
||||
break;
|
||||
}
|
||||
|
||||
watchpoint->set = wrp_i + 1;
|
||||
control = (address_mask << 24) |
|
||||
(byte_address_select << 5) |
|
||||
(load_store_access_control << 3) |
|
||||
(0x3 << 1) | 1;
|
||||
wrp_list[wrp_i].used = 1;
|
||||
wrp_list[wrp_i].value = address;
|
||||
wrp_list[wrp_i].control = control;
|
||||
|
||||
retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
|
||||
+ CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].WRPn,
|
||||
wrp_list[wrp_i].value);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
|
||||
+ CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].WRPn,
|
||||
wrp_list[wrp_i].control);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
LOG_DEBUG("wp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, wrp_i,
|
||||
wrp_list[wrp_i].control,
|
||||
wrp_list[wrp_i].value);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset an existing watchpoint and clear the used watchpoint unit.
|
||||
*
|
||||
* @param target Pointer to the target to have the watchpoint removed
|
||||
* @param watchpoint Pointer to the watchpoint to be removed
|
||||
* @return Error status while trying to unset the watchpoint or the result of
|
||||
* executing the JTAG queue
|
||||
*/
|
||||
static int cortex_a_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
|
||||
{
|
||||
int retval;
|
||||
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
||||
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
|
||||
struct cortex_a_wrp *wrp_list = cortex_a->wrp_list;
|
||||
|
||||
if (!watchpoint->set) {
|
||||
LOG_WARNING("watchpoint not set");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int wrp_i = watchpoint->set - 1;
|
||||
if (wrp_i < 0 || wrp_i >= cortex_a->wrp_num) {
|
||||
LOG_DEBUG("Invalid WRP number in watchpoint");
|
||||
return ERROR_OK;
|
||||
}
|
||||
LOG_DEBUG("wrp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, wrp_i,
|
||||
wrp_list[wrp_i].control, wrp_list[wrp_i].value);
|
||||
wrp_list[wrp_i].used = 0;
|
||||
wrp_list[wrp_i].value = 0;
|
||||
wrp_list[wrp_i].control = 0;
|
||||
retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
|
||||
+ CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].WRPn,
|
||||
wrp_list[wrp_i].control);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
|
||||
+ CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].WRPn,
|
||||
wrp_list[wrp_i].value);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
watchpoint->set = 0;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a watchpoint to an Cortex-A target. If there are no watchpoint units
|
||||
* available, an error response is returned.
|
||||
*
|
||||
* @param target Pointer to the Cortex-A target to add a watchpoint to
|
||||
* @param watchpoint Pointer to the watchpoint to be added
|
||||
* @return Error status while trying to add the watchpoint
|
||||
*/
|
||||
static int cortex_a_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
|
||||
{
|
||||
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
||||
|
||||
if (cortex_a->wrp_num_available < 1) {
|
||||
LOG_INFO("no hardware watchpoint available");
|
||||
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
int retval = cortex_a_set_watchpoint(target, watchpoint);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
cortex_a->wrp_num_available--;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a watchpoint from an Cortex-A target. The watchpoint will be unset and
|
||||
* the used watchpoint unit will be reopened.
|
||||
*
|
||||
* @param target Pointer to the target to remove a watchpoint from
|
||||
* @param watchpoint Pointer to the watchpoint to be removed
|
||||
* @return Result of trying to unset the watchpoint
|
||||
*/
|
||||
static int cortex_a_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
|
||||
{
|
||||
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
||||
|
||||
if (watchpoint->set) {
|
||||
cortex_a->wrp_num_available++;
|
||||
cortex_a_unset_watchpoint(target, watchpoint);
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Cortex-A Reset functions
|
||||
*/
|
||||
|
@ -2837,6 +3045,20 @@ static int cortex_a_examine_first(struct target *target)
|
|||
|
||||
LOG_DEBUG("Configured %i hw breakpoints", cortex_a->brp_num);
|
||||
|
||||
/* Setup Watchpoint Register Pairs */
|
||||
cortex_a->wrp_num = ((didr >> 28) & 0x0F) + 1;
|
||||
cortex_a->wrp_num_available = cortex_a->wrp_num;
|
||||
free(cortex_a->wrp_list);
|
||||
cortex_a->wrp_list = calloc(cortex_a->wrp_num, sizeof(struct cortex_a_wrp));
|
||||
for (i = 0; i < cortex_a->wrp_num; i++) {
|
||||
cortex_a->wrp_list[i].used = 0;
|
||||
cortex_a->wrp_list[i].value = 0;
|
||||
cortex_a->wrp_list[i].control = 0;
|
||||
cortex_a->wrp_list[i].WRPn = i;
|
||||
}
|
||||
|
||||
LOG_DEBUG("Configured %i hw watchpoints", cortex_a->wrp_num);
|
||||
|
||||
/* select debug_ap as default */
|
||||
swjdp->apsel = armv7a->debug_ap->ap_num;
|
||||
|
||||
|
@ -2959,6 +3181,7 @@ static void cortex_a_deinit_target(struct target *target)
|
|||
dscr & ~DSCR_HALT_DBG_MODE);
|
||||
}
|
||||
|
||||
free(cortex_a->wrp_list);
|
||||
free(cortex_a->brp_list);
|
||||
arm_free_reg_cache(dpm->arm);
|
||||
free(dpm->dbp);
|
||||
|
@ -3036,15 +3259,15 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
|
|||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
||||
|
||||
static const Jim_Nvp nvp_maskisr_modes[] = {
|
||||
static const struct jim_nvp nvp_maskisr_modes[] = {
|
||||
{ .name = "off", .value = CORTEX_A_ISRMASK_OFF },
|
||||
{ .name = "on", .value = CORTEX_A_ISRMASK_ON },
|
||||
{ .name = NULL, .value = -1 },
|
||||
};
|
||||
const Jim_Nvp *n;
|
||||
const struct jim_nvp *n;
|
||||
|
||||
if (CMD_ARGC > 0) {
|
||||
n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
|
||||
n = jim_nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
|
||||
if (n->name == NULL) {
|
||||
LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]);
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
@ -3053,7 +3276,7 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
|
|||
cortex_a->isrmasking_mode = n->value;
|
||||
}
|
||||
|
||||
n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode);
|
||||
n = jim_nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode);
|
||||
command_print(CMD, "cortex_a interrupt mask %s", n->name);
|
||||
|
||||
return ERROR_OK;
|
||||
|
@ -3064,22 +3287,22 @@ COMMAND_HANDLER(handle_cortex_a_dacrfixup_command)
|
|||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
||||
|
||||
static const Jim_Nvp nvp_dacrfixup_modes[] = {
|
||||
static const struct jim_nvp nvp_dacrfixup_modes[] = {
|
||||
{ .name = "off", .value = CORTEX_A_DACRFIXUP_OFF },
|
||||
{ .name = "on", .value = CORTEX_A_DACRFIXUP_ON },
|
||||
{ .name = NULL, .value = -1 },
|
||||
};
|
||||
const Jim_Nvp *n;
|
||||
const struct jim_nvp *n;
|
||||
|
||||
if (CMD_ARGC > 0) {
|
||||
n = Jim_Nvp_name2value_simple(nvp_dacrfixup_modes, CMD_ARGV[0]);
|
||||
n = jim_nvp_name2value_simple(nvp_dacrfixup_modes, CMD_ARGV[0]);
|
||||
if (n->name == NULL)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
cortex_a->dacrfixup_mode = n->value;
|
||||
|
||||
}
|
||||
|
||||
n = Jim_Nvp_value2name_simple(nvp_dacrfixup_modes, cortex_a->dacrfixup_mode);
|
||||
n = jim_nvp_value2name_simple(nvp_dacrfixup_modes, cortex_a->dacrfixup_mode);
|
||||
command_print(CMD, "cortex_a domain access control fixup %s", n->name);
|
||||
|
||||
return ERROR_OK;
|
||||
|
@ -3173,8 +3396,8 @@ struct target_type cortexa_target = {
|
|||
.add_context_breakpoint = cortex_a_add_context_breakpoint,
|
||||
.add_hybrid_breakpoint = cortex_a_add_hybrid_breakpoint,
|
||||
.remove_breakpoint = cortex_a_remove_breakpoint,
|
||||
.add_watchpoint = NULL,
|
||||
.remove_watchpoint = NULL,
|
||||
.add_watchpoint = cortex_a_add_watchpoint,
|
||||
.remove_watchpoint = cortex_a_remove_watchpoint,
|
||||
|
||||
.commands = cortex_a_command_handlers,
|
||||
.target_create = cortex_a_target_create,
|
||||
|
@ -3250,8 +3473,8 @@ struct target_type cortexr4_target = {
|
|||
.add_context_breakpoint = cortex_a_add_context_breakpoint,
|
||||
.add_hybrid_breakpoint = cortex_a_add_hybrid_breakpoint,
|
||||
.remove_breakpoint = cortex_a_remove_breakpoint,
|
||||
.add_watchpoint = NULL,
|
||||
.remove_watchpoint = NULL,
|
||||
.add_watchpoint = cortex_a_add_watchpoint,
|
||||
.remove_watchpoint = cortex_a_remove_watchpoint,
|
||||
|
||||
.commands = cortex_r4_command_handlers,
|
||||
.target_create = cortex_r4_target_create,
|
||||
|
|
|
@ -71,6 +71,13 @@ struct cortex_a_brp {
|
|||
uint8_t BRPn;
|
||||
};
|
||||
|
||||
struct cortex_a_wrp {
|
||||
int used;
|
||||
uint32_t value;
|
||||
uint32_t control;
|
||||
uint8_t WRPn;
|
||||
};
|
||||
|
||||
struct cortex_a_common {
|
||||
int common_magic;
|
||||
|
||||
|
@ -92,6 +99,9 @@ struct cortex_a_common {
|
|||
int brp_num;
|
||||
int brp_num_available;
|
||||
struct cortex_a_brp *brp_list;
|
||||
int wrp_num;
|
||||
int wrp_num_available;
|
||||
struct cortex_a_wrp *wrp_list;
|
||||
|
||||
uint32_t cpuid;
|
||||
uint32_t didr;
|
||||
|
|
|
@ -285,7 +285,6 @@ static int cortex_m_enable_fpb(struct target *target)
|
|||
|
||||
static int cortex_m_endreset_event(struct target *target)
|
||||
{
|
||||
int i;
|
||||
int retval;
|
||||
uint32_t dcb_demcr;
|
||||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||
|
@ -343,14 +342,14 @@ static int cortex_m_endreset_event(struct target *target)
|
|||
cortex_m->fpb_enabled = true;
|
||||
|
||||
/* Restore FPB registers */
|
||||
for (i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {
|
||||
for (unsigned int i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {
|
||||
retval = target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Restore DWT registers */
|
||||
for (i = 0; i < cortex_m->dwt_num_comp; i++) {
|
||||
for (unsigned int i = 0; i < cortex_m->dwt_num_comp; i++) {
|
||||
retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 0,
|
||||
dwt_list[i].comp);
|
||||
if (retval != ERROR_OK)
|
||||
|
@ -728,6 +727,11 @@ static int cortex_m_soft_reset_halt(struct target *target)
|
|||
* core, not the peripherals */
|
||||
LOG_DEBUG("soft_reset_halt is discouraged, please use 'reset halt' instead.");
|
||||
|
||||
if (!cortex_m->vectreset_supported) {
|
||||
LOG_ERROR("VECTRESET is not supported on this Cortex-M core");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
/* Set C_DEBUGEN */
|
||||
retval = cortex_m_write_debug_halt_mask(target, 0, C_STEP | C_MASKINTS);
|
||||
if (retval != ERROR_OK)
|
||||
|
@ -1266,7 +1270,7 @@ static int cortex_m_deassert_reset(struct target *target)
|
|||
int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
|
||||
{
|
||||
int retval;
|
||||
int fp_num = 0;
|
||||
unsigned int fp_num = 0;
|
||||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||
struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
|
||||
|
||||
|
@ -1353,7 +1357,7 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi
|
|||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||
struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
|
||||
|
||||
if (!breakpoint->set) {
|
||||
if (breakpoint->set <= 0) {
|
||||
LOG_WARNING("breakpoint not set");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -1366,8 +1370,8 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi
|
|||
breakpoint->set);
|
||||
|
||||
if (breakpoint->type == BKPT_HARD) {
|
||||
int fp_num = breakpoint->set - 1;
|
||||
if ((fp_num < 0) || (fp_num >= cortex_m->fp_num_code)) {
|
||||
unsigned int fp_num = breakpoint->set - 1;
|
||||
if (fp_num >= cortex_m->fp_num_code) {
|
||||
LOG_DEBUG("Invalid FP Comparator number in breakpoint");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -1413,7 +1417,7 @@ int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpo
|
|||
|
||||
static int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
|
||||
{
|
||||
int dwt_num = 0;
|
||||
unsigned int dwt_num = 0;
|
||||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||
|
||||
/* REVISIT Don't fully trust these "not used" records ... users
|
||||
|
@ -1498,21 +1502,20 @@ static int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *w
|
|||
{
|
||||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||
struct cortex_m_dwt_comparator *comparator;
|
||||
int dwt_num;
|
||||
|
||||
if (!watchpoint->set) {
|
||||
if (watchpoint->set <= 0) {
|
||||
LOG_WARNING("watchpoint (wpid: %d) not set",
|
||||
watchpoint->unique_id);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
dwt_num = watchpoint->set - 1;
|
||||
unsigned int dwt_num = watchpoint->set - 1;
|
||||
|
||||
LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
|
||||
watchpoint->unique_id, dwt_num,
|
||||
(unsigned) watchpoint->address);
|
||||
|
||||
if ((dwt_num < 0) || (dwt_num >= cortex_m->dwt_num_comp)) {
|
||||
if (dwt_num >= cortex_m->dwt_num_comp) {
|
||||
LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
@ -1851,7 +1854,7 @@ static void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target
|
|||
uint32_t dwtcr;
|
||||
struct reg_cache *cache;
|
||||
struct cortex_m_dwt_comparator *comparator;
|
||||
int reg, i;
|
||||
int reg;
|
||||
|
||||
target_read_u32(target, DWT_CTRL, &dwtcr);
|
||||
LOG_DEBUG("DWT_CTRL: 0x%" PRIx32, dwtcr);
|
||||
|
@ -1893,7 +1896,7 @@ fail1:
|
|||
dwt_base_regs + reg);
|
||||
|
||||
comparator = cm->dwt_comparator_list;
|
||||
for (i = 0; i < cm->dwt_num_comp; i++, comparator++) {
|
||||
for (unsigned int i = 0; i < cm->dwt_num_comp; i++, comparator++) {
|
||||
int j;
|
||||
|
||||
comparator->dwt_comparator_address = DWT_COMP0 + 0x10 * i;
|
||||
|
@ -1964,7 +1967,6 @@ int cortex_m_examine(struct target *target)
|
|||
{
|
||||
int retval;
|
||||
uint32_t cpuid, fpcr, mvfr0, mvfr1;
|
||||
int i;
|
||||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||
struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;
|
||||
struct armv7m_common *armv7m = target_to_armv7m(target);
|
||||
|
@ -2000,23 +2002,23 @@ int cortex_m_examine(struct target *target)
|
|||
return retval;
|
||||
|
||||
/* Get CPU Type */
|
||||
i = (cpuid >> 4) & 0xf;
|
||||
unsigned int core = (cpuid >> 4) & 0xf;
|
||||
|
||||
/* Check if it is an ARMv8-M core */
|
||||
armv7m->arm.is_armv8m = true;
|
||||
|
||||
switch (cpuid & ARM_CPUID_PARTNO_MASK) {
|
||||
case CORTEX_M23_PARTNO:
|
||||
i = 23;
|
||||
core = 23;
|
||||
break;
|
||||
case CORTEX_M33_PARTNO:
|
||||
i = 33;
|
||||
core = 33;
|
||||
break;
|
||||
case CORTEX_M35P_PARTNO:
|
||||
i = 35;
|
||||
core = 35;
|
||||
break;
|
||||
case CORTEX_M55_PARTNO:
|
||||
i = 55;
|
||||
core = 55;
|
||||
break;
|
||||
default:
|
||||
armv7m->arm.is_armv8m = false;
|
||||
|
@ -2025,9 +2027,9 @@ int cortex_m_examine(struct target *target)
|
|||
|
||||
|
||||
LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected",
|
||||
i, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
|
||||
core, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
|
||||
cortex_m->maskints_erratum = false;
|
||||
if (i == 7) {
|
||||
if (core == 7) {
|
||||
uint8_t rev, patch;
|
||||
rev = (cpuid >> 20) & 0xf;
|
||||
patch = (cpuid >> 0) & 0xf;
|
||||
|
@ -2038,47 +2040,50 @@ int cortex_m_examine(struct target *target)
|
|||
}
|
||||
LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
|
||||
|
||||
/* VECTRESET is supported only on ARMv7-M cores */
|
||||
cortex_m->vectreset_supported = !armv7m->arm.is_armv8m && !armv7m->arm.is_armv6m;
|
||||
|
||||
if (i == 4) {
|
||||
if (core == 4) {
|
||||
target_read_u32(target, MVFR0, &mvfr0);
|
||||
target_read_u32(target, MVFR1, &mvfr1);
|
||||
|
||||
/* 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);
|
||||
LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", core);
|
||||
armv7m->fp_feature = FPV4_SP;
|
||||
}
|
||||
} else if (i == 7 || i == 33 || i == 35 || i == 55) {
|
||||
} else if (core == 7 || core == 33 || core == 35 || core == 55) {
|
||||
target_read_u32(target, MVFR0, &mvfr0);
|
||||
target_read_u32(target, MVFR1, &mvfr1);
|
||||
|
||||
/* 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);
|
||||
LOG_DEBUG("Cortex-M%d floating point feature FPv5_SP found", core);
|
||||
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);
|
||||
LOG_DEBUG("Cortex-M%d floating point feature FPv5_DP found", core);
|
||||
armv7m->fp_feature = FPV5_DP;
|
||||
}
|
||||
} else if (i == 0) {
|
||||
} else if (core == 0) {
|
||||
/* Cortex-M0 does not support unaligned memory access */
|
||||
armv7m->arm.is_armv6m = true;
|
||||
}
|
||||
|
||||
/* VECTRESET is supported only on ARMv7-M cores */
|
||||
cortex_m->vectreset_supported = !armv7m->arm.is_armv8m && !armv7m->arm.is_armv6m;
|
||||
|
||||
/* 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;
|
||||
|
||||
if (!armv7m->arm.is_armv8m)
|
||||
for (size_t idx = ARMV8M_FIRST_REG; idx <= ARMV8M_LAST_REG; idx++)
|
||||
armv7m->arm.core_cache->reg_list[idx].exist = false;
|
||||
|
||||
if (!armv7m->stlink) {
|
||||
if (i == 3 || i == 4)
|
||||
if (core == 3 || core == 4)
|
||||
/* Cortex-M3/M4 have 4096 bytes autoincrement range,
|
||||
* s. ARM IHI 0031C: MEM-AP 7.2.2 */
|
||||
armv7m->debug_ap->tar_autoincr_block = (1 << 12);
|
||||
else if (i == 7)
|
||||
else if (core == 7)
|
||||
/* Cortex-M7 has only 1024 bytes autoincrement range */
|
||||
armv7m->debug_ap->tar_autoincr_block = (1 << 10);
|
||||
}
|
||||
|
@ -2119,7 +2124,7 @@ int cortex_m_examine(struct target *target)
|
|||
cortex_m->fp_num_code + cortex_m->fp_num_lit,
|
||||
sizeof(struct cortex_m_fp_comparator));
|
||||
cortex_m->fpb_enabled = fpcr & 1;
|
||||
for (i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {
|
||||
for (unsigned int i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {
|
||||
cortex_m->fp_comparator_list[i].type =
|
||||
(i < cortex_m->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
|
||||
cortex_m->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
|
||||
|
@ -2393,14 +2398,14 @@ COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command)
|
|||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||
int retval;
|
||||
|
||||
static const Jim_Nvp nvp_maskisr_modes[] = {
|
||||
static const struct jim_nvp nvp_maskisr_modes[] = {
|
||||
{ .name = "auto", .value = CORTEX_M_ISRMASK_AUTO },
|
||||
{ .name = "off", .value = CORTEX_M_ISRMASK_OFF },
|
||||
{ .name = "on", .value = CORTEX_M_ISRMASK_ON },
|
||||
{ .name = "steponly", .value = CORTEX_M_ISRMASK_STEPONLY },
|
||||
{ .name = NULL, .value = -1 },
|
||||
};
|
||||
const Jim_Nvp *n;
|
||||
const struct jim_nvp *n;
|
||||
|
||||
|
||||
retval = cortex_m_verify_pointer(CMD, cortex_m);
|
||||
|
@ -2413,14 +2418,14 @@ COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command)
|
|||
}
|
||||
|
||||
if (CMD_ARGC > 0) {
|
||||
n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
|
||||
n = jim_nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
|
||||
if (n->name == NULL)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
cortex_m->isrmasking_mode = n->value;
|
||||
cortex_m_set_maskints_for_halt(target);
|
||||
}
|
||||
|
||||
n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_m->isrmasking_mode);
|
||||
n = jim_nvp_value2name_simple(nvp_maskisr_modes, cortex_m->isrmasking_mode);
|
||||
command_print(CMD, "cortex_m interrupt mask %s", n->name);
|
||||
|
||||
return ERROR_OK;
|
||||
|
|
|
@ -196,15 +196,15 @@ struct cortex_m_common {
|
|||
uint32_t nvic_icsr; /* Interrupt Control State Register - shows active and pending IRQ */
|
||||
|
||||
/* Flash Patch and Breakpoint (FPB) */
|
||||
int fp_num_lit;
|
||||
int fp_num_code;
|
||||
unsigned int fp_num_lit;
|
||||
unsigned int fp_num_code;
|
||||
int fp_rev;
|
||||
bool fpb_enabled;
|
||||
struct cortex_m_fp_comparator *fp_comparator_list;
|
||||
|
||||
/* Data Watchpoint and Trace (DWT) */
|
||||
int dwt_num_comp;
|
||||
int dwt_comp_available;
|
||||
unsigned int dwt_num_comp;
|
||||
unsigned int dwt_comp_available;
|
||||
uint32_t dwt_devarch;
|
||||
struct cortex_m_dwt_comparator *dwt_comparator_list;
|
||||
struct reg_cache *dwt_cache;
|
||||
|
|
|
@ -2244,7 +2244,7 @@ static const struct command_registration dsp563xx_command_handlers[] = {
|
|||
.handler = dsp563xx_remove_watchpoint_command,
|
||||
.mode = COMMAND_EXEC,
|
||||
.help = "remove watchpoint custom",
|
||||
.usage = " ",
|
||||
.usage = "",
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
|
|
@ -106,7 +106,7 @@ int embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size);
|
|||
|
||||
int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout);
|
||||
|
||||
/* If many embeddedice_write_reg() follow eachother, then the >1 invocations can be
|
||||
/* If many embeddedice_write_reg() follow each other, then the >1 invocations can be
|
||||
* this faster version of embeddedice_write_reg
|
||||
*/
|
||||
static inline void embeddedice_write_reg_inner(struct jtag_tap *tap, int reg_addr, uint32_t value)
|
||||
|
|
|
@ -18,14 +18,16 @@
|
|||
|
||||
#include "target.h"
|
||||
#include "target_type.h"
|
||||
#include "arm.h"
|
||||
#include "arm_adi_v5.h"
|
||||
#include "register.h"
|
||||
|
||||
#include <jtag/jtag.h>
|
||||
|
||||
#define MEM_AP_COMMON_MAGIC 0x4DE4DA50
|
||||
|
||||
struct mem_ap {
|
||||
struct arm arm;
|
||||
int common_magic;
|
||||
struct adiv5_dap *dap;
|
||||
struct adiv5_ap *ap;
|
||||
int ap_num;
|
||||
};
|
||||
|
@ -51,8 +53,8 @@ static int mem_ap_target_create(struct target *target, Jim_Interp *interp)
|
|||
}
|
||||
|
||||
mem_ap->ap_num = pc->ap_num;
|
||||
mem_ap->arm.common_magic = ARM_COMMON_MAGIC;
|
||||
mem_ap->arm.dap = pc->dap;
|
||||
mem_ap->common_magic = MEM_AP_COMMON_MAGIC;
|
||||
mem_ap->dap = pc->dap;
|
||||
|
||||
target->arch_info = mem_ap;
|
||||
|
||||
|
@ -137,7 +139,7 @@ static int mem_ap_examine(struct target *target)
|
|||
struct mem_ap *mem_ap = target->arch_info;
|
||||
|
||||
if (!target_was_examined(target)) {
|
||||
mem_ap->ap = dap_ap(mem_ap->arm.dap, mem_ap->ap_num);
|
||||
mem_ap->ap = dap_ap(mem_ap->dap, mem_ap->ap_num);
|
||||
target_set_examined(target);
|
||||
target->state = TARGET_UNKNOWN;
|
||||
target->debug_reason = DBG_REASON_UNDEFINED;
|
||||
|
|
|
@ -681,8 +681,8 @@ static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *a
|
|||
{
|
||||
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
|
||||
if (goi.argc < 3) {
|
||||
Jim_SetResultFormatted(goi.interp,
|
||||
|
@ -692,12 +692,12 @@ static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *a
|
|||
|
||||
int e;
|
||||
jim_wide address;
|
||||
e = Jim_GetOpt_Wide(&goi, &address);
|
||||
e = jim_getopt_wide(&goi, &address);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
jim_wide count;
|
||||
e = Jim_GetOpt_Wide(&goi, &count);
|
||||
e = jim_getopt_wide(&goi, &count);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
|
@ -708,7 +708,7 @@ static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *a
|
|||
jim_wide i;
|
||||
for (i = 0; i < count; i++) {
|
||||
jim_wide tmp;
|
||||
e = Jim_GetOpt_Wide(&goi, &tmp);
|
||||
e = jim_getopt_wide(&goi, &tmp);
|
||||
if (e != JIM_OK) {
|
||||
free(data);
|
||||
return e;
|
||||
|
@ -738,8 +738,8 @@ static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const *
|
|||
{
|
||||
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
|
||||
if (goi.argc < 3) {
|
||||
Jim_SetResultFormatted(goi.interp,
|
||||
|
@ -749,7 +749,7 @@ static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const *
|
|||
|
||||
int e;
|
||||
jim_wide num_of_pairs;
|
||||
e = Jim_GetOpt_Wide(&goi, &num_of_pairs);
|
||||
e = jim_getopt_wide(&goi, &num_of_pairs);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
|
@ -765,12 +765,12 @@ static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const *
|
|||
aice_set_command_mode(aice, AICE_COMMAND_MODE_PACK);
|
||||
for (i = 0; i < num_of_pairs; i++) {
|
||||
jim_wide tmp;
|
||||
e = Jim_GetOpt_Wide(&goi, &tmp);
|
||||
e = jim_getopt_wide(&goi, &tmp);
|
||||
if (e != JIM_OK)
|
||||
break;
|
||||
address = (uint32_t)tmp;
|
||||
|
||||
e = Jim_GetOpt_Wide(&goi, &tmp);
|
||||
e = jim_getopt_wide(&goi, &tmp);
|
||||
if (e != JIM_OK)
|
||||
break;
|
||||
data = (uint32_t)tmp;
|
||||
|
@ -792,8 +792,8 @@ static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *ar
|
|||
{
|
||||
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
|
||||
if (goi.argc < 2) {
|
||||
Jim_SetResultFormatted(goi.interp,
|
||||
|
@ -803,12 +803,12 @@ static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *ar
|
|||
|
||||
int e;
|
||||
jim_wide address;
|
||||
e = Jim_GetOpt_Wide(&goi, &address);
|
||||
e = jim_getopt_wide(&goi, &address);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
jim_wide count;
|
||||
e = Jim_GetOpt_Wide(&goi, &count);
|
||||
e = jim_getopt_wide(&goi, &count);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
|
@ -840,8 +840,8 @@ static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *
|
|||
{
|
||||
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
|
||||
if (goi.argc < 1) {
|
||||
Jim_SetResultFormatted(goi.interp,
|
||||
|
@ -852,7 +852,7 @@ static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *
|
|||
int e;
|
||||
const char *edm_sr_name;
|
||||
int edm_sr_name_len;
|
||||
e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len);
|
||||
e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
|
@ -888,8 +888,8 @@ static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const
|
|||
{
|
||||
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||
|
||||
Jim_GetOptInfo goi;
|
||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
|
||||
struct jim_getopt_info goi;
|
||||
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
|
||||
|
||||
if (goi.argc < 2) {
|
||||
Jim_SetResultFormatted(goi.interp,
|
||||
|
@ -900,12 +900,12 @@ static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const
|
|||
int e;
|
||||
const char *edm_sr_name;
|
||||
int edm_sr_name_len;
|
||||
e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len);
|
||||
e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
jim_wide value;
|
||||
e = Jim_GetOpt_Wide(&goi, &value);
|
||||
e = jim_getopt_wide(&goi, &value);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue