From upstream (#620)
* cortex_m: use unsigned int for FPB and DWT quantifiers related quantifiers are: - fp_num_lit - fp_num_code - dwt_num_comp - dwt_comp_available Change-Id: I07dec2d4aa21bc0e580be0d9fd0a6809f876c2a8 Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-on: http://openocd.zylin.com/6185 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> * telnet: allow hiding selected commands during auto-completion We have TCL procedure and commands that we do not want to show in the list of auto-completion. E.g. TCL wrappers for deprecated commands, internal procedures that are not supposed to be exposed to user, or even commands that the user decides to hide. Create a TCL procedure to be called by telnet auto-complete code in place of the hard-coded TCL command. The procedure will run the same command and will filter-out the unwanted command names. Initialize the list of commands to be filtered-out with the name of the TCL procedure above, as it is considered as internal. Change-Id: I2d83bbf8194502368c589c85cccb617e69128c69 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6194 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> * telnet/auto-complete: hide deprecated and internal commands For both: - TCL proc that redirect deprecated commands to the new commands, - TCL proc used internally and not supposed to be exposed to user, add their name to the list of commands that should be hide by the telnet auto-complete. Change-Id: I05237c6a79334b7d2b151dfb129fb57b2f40bba6 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6195 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> * startup.tcl: prepare for jimtcl 0.81 'expr' syntax change Jimtcl commit 1843b79a03dd ("expr: TIP 526, only support a single arg") drops the support for multi-argument syntax for the TCL command 'expr'. Modify the script startup.tcl compiled-in OpenOCD binary to comply with the new jimtcl. Change-Id: I520dcafacadaa289a815035f93f250447ca66ea0 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6158 Tested-by: jenkins Reviewed-by: Oleksij Rempel <linux@rempel-privat.de> Reviewed-by: Tomas Vanek <vanekt@fbl.cz> * tcl: [1/3] prepare for jimtcl 0.81 'expr' syntax change Jimtcl commit 1843b79a03dd ("expr: TIP 526, only support a single arg") drops the support for multi-argument syntax for the TCL command 'expr'. In the TCL scripts distributed with OpenOCD there are 1700+ lines that should be modified before switching to jimtcl 0.81. Apply the script below on every script in tcl folder. It fixes more than 92% of the lines %<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<--- #!/usr/bin/perl -Wpi my $re_sym = qr{[a-z_][a-z0-9_]*}i; my $re_var = qr{(?:\$|\$::)$re_sym}; my $re_const = qr{0x[0-9a-f]+|[0-9]+|[0-9]*\.[0-9]*}i; my $re_item = qr{(?:~\s*)?(?:$re_var|$re_const)}; my $re_op = qr{<<|>>|[+\-*/&|]}; my $re_expr = qr{( (?:\(\s*(?:$re_item|(?-1))\s*\)|$re_item) \s*$re_op\s* (?:$re_item|(?-1)|\(\s*(?:$re_item|(?-1))\s*\)) )}x; # [expr [dict get $regsC100 SYM] + HEXNUM] s/\[expr (\[dict get $re_var $re_sym\s*\] \+ *$re_const)\]/\[expr \{$1\}\]/; # [ expr (EXPR) ] # [ expr EXPR ] # note: $re_expr captures '$3' s/\[(\s*expr\s*)\((\s*$re_expr\s*)\)(\s*)\]/\[$1\{$2\}$4\]/; s/\[(\s*expr\s*)($re_expr)(\s*)\]/\[$1\{$2\}$4\]/; %<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<--- Change-Id: I0d6bddc6abf6dd29062f2b4e72b5a2b5080293b9 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6159 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> * tcl: [2/3] prepare for jimtcl 0.81 'expr' syntax change Jimtcl commit 1843b79a03dd ("expr: TIP 526, only support a single arg") drops the support for multi-argument syntax for the TCL command 'expr'. Enclose within double quote the argument of 'expr' when there is the need to concatenate strings. Change-Id: Ic0ea990ed37337a7e6c3a99670583685b570b8b1 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6160 Tested-by: jenkins * tcl: [3/3] prepare for jimtcl 0.81 'expr' syntax change Jimtcl commit 1843b79a03dd ("expr: TIP 526, only support a single arg") drops the support for multi-argument syntax for the TCL command 'expr'. Fix manually the remaining lines that don't match simple patterns and would require dedicated boring scripting. Remove the 'expr' command where appropriate. Change-Id: Ia75210c8447f88d38515addab4a836af9103096d Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6161 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> * target/stm8: Make 'stm8_command_handlers' static Change-Id: I5237a8f2a1ecba9383672e37bd56f8ccd17598b6 Signed-off-by: Marc Schink <dev@zapb.de> Reviewed-on: http://openocd.zylin.com/6200 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * target/riscv: Change 'authdata_read' output Use a constant output length and remove the line break to make the authentication data easier to parse. Change-Id: Iebbf1f171947ef89b0f360a2cb286a4ea15c6ba5 Signed-off-by: Marc Schink <dev@zapb.de> Reviewed-on: http://openocd.zylin.com/6199 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Tim Newsome <tim@sifive.com> * Enable adapter "Bus Pirate" by default. The Bus Pirate is now listed in the "OpenOCD configuration summary" too. Change-Id: Ieb7bf9134af456ebe9803f3108a243204fb2a62d Signed-off-by: R. Diez <rdiezmail-openocd@yahoo.de> Reviewed-on: http://openocd.zylin.com/5637 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * coding-style: additional style for C code To improve readability and to push more uniform code style. Prefer 'if (false) {...}' for unused code so it get checked by the compiler. Define preferred indentation for 'switch' statement. Require balanced brackets in 'if/else'. Report the max line length. Report the formatting strings for stdint/inttypes types. Report the type 'target_addr_t'. Prefer 'unsigned int' to 'unsigned'. Change-Id: I0192a4ed298f6c6c432764fdd156cffd4b13fc89 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6203 Reviewed-by: Tomas Vanek <vanekt@fbl.cz> Tested-by: jenkins Reviewed-by: Oleksij Rempel <linux@rempel-privat.de> Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-by: Marc Schink <dev@zapb.de> * Add IPDBG JtagHost functionality to OpenOCD IPDBG are utilities to debug IP-cores. It uses JTAG for transport to/from the FPGA. The different UIs use TCP/IP as transport. The JtagHost makes the bridge between these two. Comparable to the bridge between GDB and the in-circuit- debugging-unit of a micro controller. Change-Id: Ib1bc10dcbd4ea426e492bb7b2d85c1ed1b7a8d5a Signed-off-by: Daniel Anselmi <danselmi@gmx.ch> Reviewed-on: http://openocd.zylin.com/5938 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * flash/nor/xcf: Do not use 'Yoda conditions' Change-Id: I17308f5237338ce468e5b86289a0634429deaaa9 Signed-off-by: Marc Schink <dev@zapb.de> Reviewed-on: http://openocd.zylin.com/6201 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * cortex_m: add armv8m special registers Change-Id: I1942f375a5f4282ad1fe4a2ff3b8f3cbc64d8f7f Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-on: http://openocd.zylin.com/6016 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> * rtos: Add support for Zephyr RTOS With this patch, the Zephyr[1] RTOS is supported by OpenOCD. As usual with support for other RTOSes, 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. The current implementation is limited to Zephyr running on ARM Cortex-M processors. This is the only ARM variant supported by Zephyr at the moment and is used on most of the officially supported boards. [1] https://www.zephyrproject.org/ Change-Id: I22afdbec91562f3a22cf5b88cd4ea3a7a59ba0b4 Signed-off-by: Evgeniy Didin <didin@synopsys.com> Signed-off-by: Leandro Pereira <leandro.pereira@intel.com> Signed-off-by: Daniel Glöckner <dg@emlix.com> Reviewed-on: http://openocd.zylin.com/4988 Tested-by: jenkins Reviewed-by: Oleksij Rempel <linux@rempel-privat.de> Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * target/armv7m.h: [style] replace tab with space between variable type and name Change-Id: I9740c25857295a2a655d3046322a3f23f0ee7f78 Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-on: http://openocd.zylin.com/6230 Reviewed-by: Marc Schink <dev@zapb.de> Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * server: gdb_server: Add colon for target extended-remote Both GDB commands "target remote" and "target extended-remote" require to have ":" right before port number. e.g. (gdb) target extended-remote :3333 Add ":" to the warning message so that users can copy & past it. Change-Id: Id6d8ec1e4dfd3c12cb7f3b314064f2c35fa7ab55 Signed-off-by: Yasushi SHOJI <yashi@spacecubics.com> Reviewed-on: http://openocd.zylin.com/6237 Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Tested-by: jenkins Reviewed-by: Marc Schink <dev@zapb.de> Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * jimtcl: restrict memory leak workaround on Linux only The workaround for jimtcl 0.80 in commit36ae487ed0
("jimtcl: add temporary workaround for memory leak in jimtcl 0.80") issues a compile time error on macOS: ../src/helper/command.c:157:22: error: aliases are not supported on darwin __attribute__((weak, alias("workaround_createcommand"))); The OS is x86_64-apple-darwin19.6.0 and the compiler used is x86_64-apple-darwin13.4.0-clang. Restrict the workaround on Linux host only. The fix for 'expr' syntax change is already merged and the workaround will be dropped soon. Change-Id: I925109a9c57c05f8c95b70bc7d6604eb1172cd79 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reported-by: Adam Jeliński <ajelinski@users.sourceforge.net> Fixes:36ae487ed0
("jimtcl: add temporary workaround for memory leak in jimtcl 0.80") Fixes: https://sourceforge.net/p/openocd/tickets/304/ Reviewed-on: http://openocd.zylin.com/6241 Tested-by: jenkins * target/armv7m: fix static analyzer warning Despite of assert(is_packed) clang static analyser complains on use of the uninitialized offset variable. Cross compiling with latest x86_64-w64-mingw32-gcc hits warnings src/target/armv7m.c: In function ‘armv7m_read_core_reg’: src/target/armv7m.c:337:54: error: ‘reg32_id’ may be used uninitialized in this function [-Werror=maybe-uninitialized] It happens because mingw32 defines assert() without the attribute "noreturn", whatever NDEBUG is defined or not. Replace assert(is_packed) by if (is_packed) conditional and call assert(false) in the else branch. Change-Id: Id3c7dcccb65106e28be200b9a4d2b642f4d31019 Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-on: http://openocd.zylin.com/6256 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-by: Andrzej Sierżęga <asier70@gmail.com> * cmsis_dap: fix build on macOS Compile fails with error: src/jtag/drivers/cmsis_dap.c:683:28: error: format specifies type 'unsigned char' but the argument has type 'int' [-Werror,-Wformat] " received 0x%" PRIx8, CMD_DAP_TFER, resp[0]); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~ Fix the format specifier. Change-Id: I0a5a1a35452d634019989d14d849501fb8a7e93a Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6255 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> * cortex_m: do not perform soft_reset_halt on targets without VECTRESET Change-Id: Ib3df457e0afe4e342c82ad1af25e03aad6979d87 Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-on: http://openocd.zylin.com/6209 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Tomas Vanek <vanekt@fbl.cz> * cortex_m: fix VECTRESET detection for ARMv6-M cores VECTRESET check should be done after verifying if the core is an ARMv6-M core, and not before that. Fixes:2dc9c1df81
("cortex_m: [FIX] ARMv8-M does not support VECTRESET") Change-Id: I8306affd332b3a35cea69bba39ef24ca71244273 Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-on: http://openocd.zylin.com/6232 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * target/arm_dpm: rename 'wp_pc' as 'wp_addr' The field 'wp_pc' was originally introduced in commit55eeea7fce
("ARMv7a/Cortex-A8: report watchpoint trigger insn") in end 2009 to contain the address of the instruction which triggered a watchpoint. Later on with commit651b861d5d
("target/aarch64: Add watchpoint support") it has been reused in to hold directly the memory address that triggered a watchpoint. Rename 'wp_pc' as 'wp_addr' and change its doxygen description. While there, fix the format string to print the field. Change-Id: I2e5ced1497e4a6fb6b38f91e881807512e8d8c47 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6204 Tested-by: jenkins Reviewed-by: Liming Sun <limings@nvidia.com> * target/aarch64: fix watchpoint management The early documentation for armv8a report the debug register WFAR as containing the address of the instruction that triggered the watchpoint. More recent documentation report the register EDWAR as containing the data memory address that triggered the watchpoint. The name of macros CPUV8_DBG_WFAR0 and CPUV8_DBG_WFAR1 is not correct as they point to the debug register EDWAR, so reading such register returns directly the data memory address that triggered the watchpoint. The code incorrectly passes this address value to the function armv8_dpm_report_wfar(); this function is supposed to adjust the PC value, decrementing it to remove the effects of the CPU pipeline. This pipeline offset, that has no meaning on the value in EDWAR, caused commit651b861d5d
("target/aarch64: Add watchpoint support") to add back the offset while comparing the address with the watchpoint enabled. The upper 32 bits of EDWAR are not valid in aarch32 mode and have to be ignored. Rename CPUV8_DBG_WFAR0/1 as CPUV8_DBG_EDWAR0/1. Remove the function armv8_dpm_report_wfar(). Remove the offset while searching the matching watchpoint. Ignore the upper 32 bits of EDWAR in aarch32 mode. Fix a comment and the LOG text. Change-Id: I7cbdbeb766fa18e31cc72be098ca2bc501877ed1 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6205 Tested-by: jenkins Reviewed-by: Liming Sun <limings@nvidia.com> * flash/stm32l4x: add missing break statement this is not a bug fix, this for loop will issue only one match adding the break will save unnecessary more loops. Change-Id: Ic1484ea8cdea1b284eb570f9e3e7818e07daf5cd Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-on: http://openocd.zylin.com/6248 Reviewed-by: Oleksij Rempel <linux@rempel-privat.de> Tested-by: jenkins * github/action: create a permanent 'latest' release this commit extends the existing snapshot action to create a release named 'latest' with the built binaries for windows. this 'latest' release will be updated after every push to github. Change-Id: I75a64c598169241743add3ac9aa7a0337fbab7f2 Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-on: http://openocd.zylin.com/6127 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * tcl/rp2040: remove empty line at end of file Change-Id: I212a96b77282b151a8ecbd46a6436e2bbbda4161 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6221 Tested-by: jenkins * tcl: fix some minor typo Minor typos found by the new checkpatch boosted by the dictionary provided by 'codespell'. While there, fix one indentation. Change-Id: I72369ed26f363bacd760b40b8c83dd95e89d28a4 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6214 Tested-by: jenkins * flash: fix some minor typo Minor typos found by the new checkpatch boosted by the dictionary provided by 'codespell'. Change-Id: Ia5f134c91beb483fd865df9e4877e0ec3e789478 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6215 Tested-by: jenkins * jtag: fix some minor typo Minor typos found by the new checkpatch boosted by the dictionary provided by 'codespell'. Change-Id: I101c76a638805d77c1ff356cf0f027552389e5d3 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6216 Tested-by: jenkins * target: fix some minor typo Minor typos found by the new checkpatch boosted by the dictionary provided by 'codespell'. Change-Id: I548581247db72e683249749d1b8725035530b06e Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6217 Tested-by: jenkins * openocd: fix some minor typo Minor typos found by the new checkpatch boosted by the dictionary provided by 'codespell'. Change-Id: I7b4cae1798ff5ea048fcbc671a397af763fdc605 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6218 Tested-by: jenkins * Document the buspirate interface driver. Change-Id: Iaff13fc5187041a840f4f00eb6b4ee52880cf47e Signed-off-by: R. Diez <rdiezmail-openocd@yahoo.de> Reviewed-on: http://openocd.zylin.com/6231 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * Warn on undefined preprocessor symbols Preprocessor directives like "#if SYMBOL" silently replace undefined or misspelt symbols with 0, which makes configuration bugs hard to spot. Compiler flag "-Wundef" prevents such errors. Change-Id: I91b7ba2db02ef0c3c452d334601c53aebda4660e Signed-off-by: R. Diez <rdiezmail-openocd@yahoo.de> Reviewed-on: http://openocd.zylin.com/6238 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * Remove compatibility macros m4_ifblank and m4_ifnblank They are at least since Autoconf 2.67 present, and we are requiring version 2.69. Change-Id: I41b33d4ebe02198f03cdddcc4a3c1beedd993d78 Signed-off-by: R. Diez <rdiezmail-openocd@yahoo.de> Reviewed-on: http://openocd.zylin.com/6239 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * configure.ac: use a separate folder for Autoconf-generated files Autoconf generates several files in root folder of the project. Keep the root folder cleaner by specifying subfolder 'build-aux'. Align .gitignore accordingly. Signed-off-by: R. Diez <rdiezmail-openocd@yahoo.de> Change-Id: Ied87faba495d9eeb8f98e78c2e2b7e7e596febfb Reviewed-on: http://openocd.zylin.com/6236 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * helper/command: silent debug msg on command register/unregister Commite216186fab
("helper/command: register full-name commands in jim") and commita7d68878e4
("helper/command: unregister commands through their full-name") introduce a LOG_DEBUG() message each for command registration and unregistration. The messages above are quite noisy and pollute the log when debug_level is 3 or higher. They can be useful to debug the command registration logic, but for the other debug activities on OpenOCD are just noisy. Already commita03ac1ba30
("helper/command: disable logging of registered commands [RFC]") was merged to silent the first case that is now back with additional logs. Silent both log messages. Use 'if (false)' to silent them, making easy to re-enable it when or if someone needs it. Change-Id: Id8a067e60e822d4ecbddcb036d081298f7e6181f Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6220 Tested-by: jenkins * mem_ap: fix target arch_info type The target mem_ap appears as an ARM target, thus it allows the execution of ARM specific commands causing the crash of OpenOCD. E.g. 'arm mrc ...' can be executed and segfaults. Replace the incorrect ARM magic number with a dedicated one. While there, remove the 'struct arm', that is now holding only the mem_ap's dap, and replace it with a pointer to the dap. Change-Id: I881332d3fdf8d8f8271b8711607737b052a5699b Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6213 Tested-by: jenkins * riscv: drop unused variable The array newly_halted[] is assigned but its value is never used. Drop it! Change-Id: I678812a31c45a3ec03716e3eee6a30b8e8947926 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6257 Tested-by: jenkins Reviewed-by: Xiang W <wxjstz@126.com> Reviewed-by: Tim Newsome <tim@sifive.com> * riscv: replace macro DIM() with ARRAY_SIZE() OpenOCD already defines the macro ARRAY_SIZE, while riscv code uses a local macro DIM. Prefer using the macro ARRAY_SIZE() instead of DIM(). Not all the riscv code has been upstreamed, yes; this patch only covers the code already upstreamed. Change-Id: I89a58a6d91916d85c53ba5e4091b558271f8d618 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6258 Reviewed-by: Xiang W <wxjstz@126.com> Tested-by: jenkins Reviewed-by: Tim Newsome <tim@sifive.com> * target/zynqmp : Add AXI AP access port The Xilinx Zynq UltraScale+ SoC have an "AXI-AP" access port for direct memory accesses without halting CPUs. Change-Id: I6303331c217795657575de4759444938e775dee1 Signed-off-by: Olivier DANET <odanet@caramail.com> Reviewed-on: http://openocd.zylin.com/6263 Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * drivers/versaloon: use ARRAY_SIZE() Replace the custom macro dimof() with the OpenOCD macro ARRAY_SIZE(). Change-Id: I2fe638444f6c16f2a78c1fd558b21550f76282d6 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6259 Tested-by: jenkins Reviewed-by: Xiang W <wxjstz@126.com> * openocd: use macro ARRAY_SIZE() There are still few cases where the macro ARRAY_SIZE() should be used in place of custom code. Use ARRAY_SIZE() whenever possible. Change-Id: Iba0127a02357bc704fe639e08562a4f9aa7011df Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6260 Reviewed-by: Xiang W <wxjstz@126.com> Tested-by: jenkins * rtos: use ARRAY_SIZE() and simplify rtos_type.create() Use the existing macro ARRAY_SIZE(). Rewrite the functions rtos_type.create() to simplify the logic. Change-Id: I8833354767045d1642801d26944c9087a77add00 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6261 Tested-by: jenkins * tcl: remove remaining deprecated commands There are still few adapter_khz, ftdi_location, jtag_nsrst_delay and xds110_serial strolling around ... Change-Id: I3e8503dcc3875e3c92e6536f3d455a5e448d51ff Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6270 Tested-by: jenkins * help text: remove trailing space Some help text end with a useless space character. Remove it. Change-Id: I397e1194fac8042f0fab694222f925f906716de3 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6222 Tested-by: jenkins * help: fix line size in 'usage' output The implementation of command 'usage' is broken while checking the line limit of 76 chars per line (e.g. 'usage load_image') and the line wrapping is not correct. The same broken code is used for the first output line of command 'help' too. When call command_help_show_wrap(), include the command's name in the string so the whole text would be wrapped. Change-Id: Idece01ce54994db7e851d8522435ff764b11f3ac Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6223 Tested-by: jenkins * LICENSES: Add the MIT license Add the full text of the MIT license to the kernel tree. It was copied directly from: https://spdx.org/licenses/MIT.html#licenseText Add the required tags for reference and tooling. Change-Id: I94a5dea5ced6421809ea2a3448f8dda19a93f5c9 Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6219 Tested-by: jenkins * stlink: add comment of firmware version for each flag bit Change-Id: I7f7c7b9c9cfd88125f82662ed864a2c0715140b1 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6211 Tested-by: jenkins * stlink: reorder the flag macro by firmware release The corresponding bit for each macro is changed, but this is not relevant in the code. Change-Id: I7039464f5a3d55d008208f44952aadeb815bd5a3 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6212 Tested-by: jenkins * tcl/board: Add ST NUCLEO-8S208RB Change-Id: I384c6ad9b4cbabbc004160677f600d8c4bd3eb71 Signed-off-by: Marc Schink <dev@zapb.de> Reviewed-on: http://openocd.zylin.com/6268 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * target/arm_adi_v5: Fix clear sticky overrun flag during replay of commands When a WAIT occurs the commands after the WAIT are replayed and the STICKYORUN is cleared. However if another WAIT occurs during the command replay, the command itself is resent but the STICKYORUN bit shall also be cleared. If this is not done, the MEM-AP hangs. Change-Id: I14e8340cd5d8f58f4de31509da96cfa2ecb630d1 Signed-off-by: micbis <michele.bisogno.ct@renesas.com> Reviewed-on: http://openocd.zylin.com/6278 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de> * target/cortex_a: add support for watchpoints The current implementation of OpenOCD does not support watchpoints for cortex_a architecture. So, I replaced the add_watchpoint and remove_watchpoint with the specific implementation for the cortex a and using the breakpoint implementation and the arm documentation [1] as reference. In particular, I have made the following changes: * added the following functions - cortex_a_add_watchpoint This wrapper function check whether there are any watchpoint available on the target device by calling cortex_a_set_watchpoint. - cortex_a_set_watchpoint This function is responsible for settings the watchpoint register pair. In particular, it sets the WVR and the WCR registers with the cortex_a_dap command. - cortex_a_remove_watchpoint This wrapper function the selected watchpoint on the target device by calling cortex_a_unset_watchpoint. - cortex_a_unset_watchpoint This function sets both the WVR and the WCR registers to zero, thus unsetting the watchpoint. [1] http://infocenter.arm.com/help/topic/com.arm.doc.ddi0464f/BCGDHIEJ.html Change-Id: I86611dab474cb84836662af572b17636dc68e282 Signed-off-by: Chengyu Zheng <chengyu.zheng@polimi.it> Reviewed-on: http://openocd.zylin.com/3913 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de> Reviewed-by: Marc Schink <dev@zapb.de> Tested-by: jenkins * target/cortex_a: fix number of watchpoints Decrement the available watchpoints only when succeed setting it. Initialize the available watchpoint with the correct value. Change-Id: I0f93b347300b8ebedbcd9e718d4ba32b26cf6846 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6196 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de> * target/cortex_a: add support for watchpoint length of 1, 2 and 4 bytes Use byte address select for 1 and 2 bytes length. Use normal mode for 4 bytes length. Change-Id: I28d182f25145d0635de64d0361d456f1ad96640e Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6197 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de> * target/cortex_a: fix memory leak on watchpoints The memory allocated to hold the watchpoints is not freed at OpenOCD exit. Free the watchpoint memory at OpenOCD exit. Change-Id: I518c9ce0dc901cde2913d752e3154734f878b854 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6210 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de> * helper/jim-nvp: comply with coding style [1/2] The helper jim-nvp does not comply with OpenOCD coding style due to typedef of struct and CamelCase symbol names. While it's trivial fixing the helper and all its current use in the code, changing these APIs will potentially break a number of patches pending in gerrit. Gerrit will not trigger any alert, but the code will generate compile error after the merge. Add the compile flag "-Wno-error=deprecated-declarations" to keep as warning (not as error) the use of "deprecated" functions and types. Rename all the CamelCase symbols is lowercase and provide struct prototypes in place of the typedef. Add a DEPRECATED section to 'jim-nvp.h' where the old CamelCase symbols and the old typedef are re-declared with compile attribute 'deprecated'. With this change OpenOCD compiles, but generates warnings. The remaining changes allover OpenOCD code will be fixed in a separate patch for easier review. The patches merged later that still use the old deprecated API will compile with warnings. This will permit to identify and fix these cases. Change-Id: I786385d0f662dbb1be5be313ae42623156d68ce5 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6183 Tested-by: jenkins Reviewed-by: Marc Schink <dev@zapb.de> * helper/jim-nvp: comply with coding style [2/2] With the API fixed to comply with OpenOCD coding style, fix all the references in the code. Patch generated automatically with the script below. The list is in reverse order to replace a common prefix after the replacement of the symbols with the same prefix. %<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<--- (cat << EOF Jim_SetResult_NvpUnknown jim_set_result_nvp_unknown Jim_Nvp_value2name_simple jim_nvp_value2name_simple Jim_Nvp_value2name_obj jim_nvp_value2name_obj Jim_Nvp_value2name jim_nvp_value2name Jim_Nvp_name2value_simple jim_nvp_name2value_simple Jim_Nvp_name2value_obj_nocase jim_nvp_name2value_obj_nocase Jim_Nvp_name2value_obj jim_nvp_name2value_obj Jim_Nvp_name2value_nocase_simple jim_nvp_name2value_nocase_simple Jim_Nvp_name2value_nocase jim_nvp_name2value_nocase Jim_Nvp_name2value jim_nvp_name2value Jim_Nvp struct jim_nvp Jim_GetOpt_Wide jim_getopt_wide Jim_GetOpt_String jim_getopt_string Jim_GetOpt_Setup jim_getopt_setup Jim_GetOpt_Obj jim_getopt_obj Jim_GetOpt_NvpUnknown jim_getopt_nvp_unknown Jim_GetOpt_Nvp jim_getopt_nvp Jim_GetOpt_Enum jim_getopt_enum Jim_GetOpt_Double jim_getopt_double Jim_GetOpt_Debug jim_getopt_debug Jim_GetOptInfo struct jim_getopt_info Jim_GetNvp jim_get_nvp Jim_Debug_ArgvString jim_debug_argv_string EOF ) | while read a b; do sed -i "s/$a/$b/g" $(find src -type f ! -name jim-nvp.\? ) done %<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<---%<--- Change-Id: I10a12bd64bb8b17575fd9150482c989c92b298a2 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6184 Reviewed-by: Marc Schink <dev@zapb.de> Tested-by: jenkins * server/telnet: fix autocomplete for jimtcl commands Current autocomplete filters-out some command reported by "info commands". One of the filter rule concerns the command's private data. Every command registered by OpenOCD has its 'struct command' as private data. By ignoring commands without private data, we loose several TCL commands registered by jimtcl, e.g. 'foreach', 'llength'. By assuming that every command with non-NULL private data has 'struct command' as private data, we risk at best to access inconsistent data, at worst to trigger a segmentation fault. Export the already available functions: - to check if a command has been registered by OpenOCD and - to get the private data. While there, rename jimcmd_is_ocd_command() as jimcmd_is_oocd_command(). Don't filter-out jimtcl commands with no private data. Check the private data only on OpenOCD commands. Change-Id: Ib5bf8d2bc5c12440c0cfae438f637c38724a79b7 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6282 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> * helper/list.h: align file to Linux v5.12 Main improvement is in the doxygen comments. Minimize the delta with kernel file. Skip the functions hlist_unhashed_lockless() and __list_del_clearprev() that are relevant only in kernel. Remove gcc extension "omitted conditional operand". Change-Id: I2e9ddb54cfe2fa5f7cf18f44726acd144e1f98b9 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6276 Reviewed-by: <rdiezmail-openocd@yahoo.de> Tested-by: jenkins Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> * contrib: add an example of using list.h Change-Id: Ic3d399d7ad2e4d10677cf78d64968040941b74e5 Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6280 Tested-by: jenkins Reviewed-by: Tim Newsome <tim@sifive.com> * helper/list.h: add mention to the example in contrib Without such reference, it could be difficult to find the example. Change-Id: Ia9ffb06bc1a45446c2c7b53197ab3400e1d8a9e9 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6281 Tested-by: jenkins Reviewed-by: Tim Newsome <tim@sifive.com> * tcl/target/stm32f4x: fix hardcoded chip name Fixes:c945d6e616
("tcl/target: start using the new TPIU/SWO support") Change-Id: I4543c9a204f7b4b3b14e6eabc5042653106aff0e Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-on: http://openocd.zylin.com/6277 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Tested-by: jenkins * Makefile: add special target .DELETE_ON_ERROR The special .DELETE_ON_ERROR deletes the target file on recipe error. Otherwise, an incomplete output file may be considered up to date the next time around. .DELETE_ON_ERROR provides reasonable protection at virtually no cost. Signed-off-by: R. Diez <rdiezmail-openocd@yahoo.de> Change-Id: I67dca47ae5ddf3786993c87b9991b3046a85f00b Reviewed-on: http://openocd.zylin.com/6235 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * gdb_server: Log both incoming and outgoing GDB packets - Made sure that also outgoing GDB packets are logged, not only the incoming ones. - Improved the treatment of non-printable characters in the packets to make it more robust. Prior to this change: - Outgoing packets were not printed unless OpenOCD was re-compiled with _DEBUG_GDB_IO_. - Non-prinable characters were only treated in incoming 'X' packets. After this change: - Both incoming and outgoing GDB packets are logged on debug_level >= 3, so that both directions of the GDB channel are visible. - Non-printable characters are checked for in every packet so that hey do not interfere with the terminal. Change-Id: I0613e57ae5059b3279b0abcb71276cf5719a8699 Signed-off-by: Jan Matyas <matyas@codasip.com> Reviewed-on: http://openocd.zylin.com/6269 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * target/renesas_rz_g2: Introduce tcl config file for RZ/G2 devices Initial support for Renesas RZ/G2 MPU family Change-Id: I5ca74cddfd0c105a5307de56c3ade7084f9c28d2 Signed-off-by: micbis <michele.bisogno.ct@renesas.com> Reviewed-on: http://openocd.zylin.com/6250 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * drivers/jlink: Remove trailing dots This makes the messages consistent with most of the rest of the OpenOCD output. Change-Id: I915a01187e7fc317e02483ac0bbd39ec077d6321 Signed-off-by: Marc Schink <dev@zapb.de> Reviewed-on: http://openocd.zylin.com/6274 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * target: Use 'bool' for 'reset_halt' Change-Id: I974a6360ea7467067511541ac212f2e9d3de7895 Signed-off-by: Marc Schink <dev@zapb.de> Reviewed-on: http://openocd.zylin.com/6262 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * cmsis_dap: add support for swo commands Replaced mixed snake_case_CamelCase with snake_case. Define variables at first-use location. CMSIS-DAP SWO specification: https://arm-software.github.io/CMSIS_5/DAP/html/group__DAP__swo__gr.html Change-Id: Ieba79b16efd445143f964b614673d041aae74f92 Signed-off-by: Adrian Negreanu <adrian.negreanu@nxp.com> Reviewed-on: http://openocd.zylin.com/5820 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * Add target_data_bits(). This is used to compute memory block read alignment, and specifically allows 64-bit targets to ensure that memory block reads are only requested on 64-bit boundaries. Signed-off-by: Tim Newsome <tim@sifive.com> Change-Id: Idb1a27b9fc02c46245556bb0f3d6d94b368c4817 Reviewed-on: http://openocd.zylin.com/6249 Reviewed-by: Marc Schink <dev@zapb.de> Tested-by: jenkins Reviewed-by: Jan Matyas <matyas@codasip.com> Reviewed-by: Xiang W <wxjstz@126.com> Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * Avoid non-standard conditionals with omitted operands. Fixes bug #257. Change-Id: I05fc6468306d46399e769098e031e7e588798afc Signed-off-by: R. Diez <rdiezmail-openocd@yahoo.de> Reviewed-on: http://openocd.zylin.com/6271 Tested-by: jenkins Reviewed-by: Xiang W <wxjstz@126.com> Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * target/startup.tcl: Do not use 'Yoda conditions' Change-Id: I5e1bbaf032659dda1b365ef4ec6ea4a635d921ce Signed-off-by: Marc Schink <dev@zapb.de> Reviewed-on: http://openocd.zylin.com/6284 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> * Fix build. Change-Id: I4f2667db91f84f07af354691aac5d4c9e3aea3fa Signed-off-by: Tim Newsome <tim@sifive.com> Co-authored-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Co-authored-by: Antonio Borneo <borneo.antonio@gmail.com> Co-authored-by: Marc Schink <dev@zapb.de> Co-authored-by: R. Diez <rdiezmail-openocd@yahoo.de> Co-authored-by: Daniel Anselmi <danselmi@gmx.ch> Co-authored-by: Evgeniy Didin <didin@synopsys.com> Co-authored-by: Yasushi SHOJI <yashi@spacecubics.com> Co-authored-by: Tomas Vanek <vanekt@fbl.cz> Co-authored-by: Olivier DANET <odanet@caramail.com> Co-authored-by: Thomas Gleixner <tglx@linutronix.de> Co-authored-by: micbis <michele.bisogno.ct@renesas.com> Co-authored-by: Chengyu Zheng <chengyu.zheng@polimi.it> Co-authored-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Co-authored-by: Jan Matyas <matyas@codasip.com> Co-authored-by: Adrian Negreanu <adrian.negreanu@nxp.com>
This commit is contained in:
parent
ab0a2a38a3
commit
f4950b7c5d
|
@ -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 target_addr_t zephyr_cortex_m_stack_align(struct target *target,
|
||||
const uint8_t *stack_data,
|
||||
const struct rtos_register_stacking *stacking, target_addr_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