You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(75) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(70) |
Feb
(20) |
Mar
(52) |
Apr
(149) |
May
(387) |
Jun
(466) |
Jul
(133) |
Aug
(87) |
Sep
(122) |
Oct
(140) |
Nov
(185) |
Dec
(105) |
2010 |
Jan
(85) |
Feb
(45) |
Mar
(75) |
Apr
(17) |
May
(41) |
Jun
(52) |
Jul
(33) |
Aug
(29) |
Sep
(36) |
Oct
(15) |
Nov
(26) |
Dec
(34) |
2011 |
Jan
(26) |
Feb
(25) |
Mar
(26) |
Apr
(29) |
May
(20) |
Jun
(27) |
Jul
(15) |
Aug
(32) |
Sep
(13) |
Oct
(64) |
Nov
(60) |
Dec
(10) |
2012 |
Jan
(64) |
Feb
(63) |
Mar
(39) |
Apr
(43) |
May
(54) |
Jun
(11) |
Jul
(30) |
Aug
(45) |
Sep
(11) |
Oct
(70) |
Nov
(24) |
Dec
(23) |
2013 |
Jan
(17) |
Feb
(8) |
Mar
(35) |
Apr
(40) |
May
(20) |
Jun
(24) |
Jul
(36) |
Aug
(25) |
Sep
(42) |
Oct
(40) |
Nov
(9) |
Dec
(21) |
2014 |
Jan
(29) |
Feb
(24) |
Mar
(60) |
Apr
(22) |
May
(22) |
Jun
(46) |
Jul
(11) |
Aug
(23) |
Sep
(26) |
Oct
(10) |
Nov
(14) |
Dec
(2) |
2015 |
Jan
(28) |
Feb
(47) |
Mar
(33) |
Apr
(58) |
May
(5) |
Jun
(1) |
Jul
|
Aug
(8) |
Sep
(12) |
Oct
(25) |
Nov
(58) |
Dec
(21) |
2016 |
Jan
(12) |
Feb
(40) |
Mar
(2) |
Apr
(1) |
May
(67) |
Jun
(2) |
Jul
(5) |
Aug
(36) |
Sep
|
Oct
(24) |
Nov
(17) |
Dec
(50) |
2017 |
Jan
(14) |
Feb
(16) |
Mar
(2) |
Apr
(35) |
May
(14) |
Jun
(16) |
Jul
(3) |
Aug
(3) |
Sep
|
Oct
(19) |
Nov
|
Dec
(16) |
2018 |
Jan
(55) |
Feb
(11) |
Mar
(34) |
Apr
(14) |
May
(4) |
Jun
(20) |
Jul
(39) |
Aug
(16) |
Sep
(17) |
Oct
(16) |
Nov
(20) |
Dec
(30) |
2019 |
Jan
(29) |
Feb
(24) |
Mar
(37) |
Apr
(26) |
May
(19) |
Jun
(21) |
Jul
(2) |
Aug
(3) |
Sep
(9) |
Oct
(12) |
Nov
(12) |
Dec
(12) |
2020 |
Jan
(47) |
Feb
(36) |
Mar
(54) |
Apr
(44) |
May
(37) |
Jun
(19) |
Jul
(32) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(32) |
Dec
(11) |
2021 |
Jan
(14) |
Feb
(5) |
Mar
(40) |
Apr
(32) |
May
(42) |
Jun
(31) |
Jul
(29) |
Aug
(47) |
Sep
(38) |
Oct
(17) |
Nov
(74) |
Dec
(33) |
2022 |
Jan
(11) |
Feb
(15) |
Mar
(40) |
Apr
(21) |
May
(39) |
Jun
(44) |
Jul
(19) |
Aug
(46) |
Sep
(79) |
Oct
(35) |
Nov
(21) |
Dec
(15) |
2023 |
Jan
(56) |
Feb
(13) |
Mar
(43) |
Apr
(28) |
May
(60) |
Jun
(15) |
Jul
(29) |
Aug
(28) |
Sep
(32) |
Oct
(21) |
Nov
(42) |
Dec
(39) |
2024 |
Jan
(35) |
Feb
(17) |
Mar
(28) |
Apr
(7) |
May
(14) |
Jun
(35) |
Jul
(30) |
Aug
(35) |
Sep
(30) |
Oct
(28) |
Nov
(38) |
Dec
(18) |
2025 |
Jan
(21) |
Feb
(28) |
Mar
(36) |
Apr
(35) |
May
(34) |
Jun
(58) |
Jul
(9) |
Aug
(37) |
Sep
|
Oct
|
Nov
|
Dec
|
From: OpenOCD-Gerrit <ope...@us...> - 2022-02-14 20:25:53
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 254883597f2487f6e75e10c36991149679e21870 (commit) from 37d506ae55587ecb6f20f56bc9b5a6f5edc1872f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 254883597f2487f6e75e10c36991149679e21870 Author: Ben McMorran <bem...@mi...> Date: Thu Jan 27 14:45:16 2022 -0800 rtos: threadx: Add hla_target support for ThreadX Tested with an AZ3166 dev board (which uses the STM32F412ZGT6) running the Azure RTOS ThreadX demonstration system. Signed-off-by: Ben McMorran <bem...@mi...> Change-Id: I44c8f7701d9f1aaa872274166321cd7d34fb1855 Reviewed-on: https://review.openocd.org/c/openocd/+/6829 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c index 441b7abc5..4161e63fa 100644 --- a/src/rtos/ThreadX.c +++ b/src/rtos/ThreadX.c @@ -175,6 +175,18 @@ static const struct threadx_params threadx_params_list[] = { get_stacking_info_arm926ejs, /* fn_get_stacking_info */ is_thread_id_valid_arm926ejs, /* fn_is_thread_id_valid */ }, + { + "hla_target", /* target_name */ + 4, /* pointer_width; */ + 8, /* thread_stack_offset; */ + 40, /* thread_name_offset; */ + 48, /* thread_state_offset; */ + 136, /* thread_next_offset */ + &rtos_standard_cortex_m3_stacking, /* stacking_info */ + 1, /* stacking_info_nb */ + NULL, /* fn_get_stacking_info */ + NULL, /* fn_is_thread_id_valid */ + }, }; enum threadx_symbol_values { ----------------------------------------------------------------------- Summary of changes: src/rtos/ThreadX.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-02-14 15:18:39
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 37d506ae55587ecb6f20f56bc9b5a6f5edc1872f (commit) via 2c0a65baa2f17a15fcb5bb014e5dda33fecddaf8 (commit) via 7307fd0e3faa7b3e060a722775c532bcb7f70057 (commit) via f998a2aaf19c14b46fd7f7dd50607a0904f40bd3 (commit) via 2a2636f138dc40be3fff06cb7bf1f126d906e0a1 (commit) via 49c40a75292b1f76fa0d4bad91c993d9f7a618cf (commit) via a11fe473eaee235a51dba7900c08cc7629ed2794 (commit) via 16cc853bcfbcc8dba6eadd91b434c05387034c0a (commit) from 5ab74bde06541ce199390ead348a3e107ee9c0f4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 37d506ae55587ecb6f20f56bc9b5a6f5edc1872f Author: Antonio Borneo <bor...@gm...> Date: Wed Feb 2 23:55:50 2022 +0100 server: remove remaining crust from dropped eCos code Commit 39650e2273bc ("ecosboard: delete bit-rotted eCos code") has removed eCos code but has left some empty function that was used during non-eCos build to replace eCos mutex. Drop the functions and the file that contain them. Change-Id: I31bc0237ea699c11bd70921660f960ee406ffa80 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6835 Tested-by: jenkins Reviewed-by: Tomas Vanek <va...@fb...> diff --git a/src/server/Makefile.am b/src/server/Makefile.am index fb5248bfd..e3699f181 100644 --- a/src/server/Makefile.am +++ b/src/server/Makefile.am @@ -6,7 +6,6 @@ noinst_LTLIBRARIES += %D%/libserver.la %D%/server.h \ %D%/telnet_server.h \ %D%/gdb_server.h \ - %D%/server_stubs.c \ %D%/tcl_server.c \ %D%/tcl_server.h \ %D%/rtt_server.c \ diff --git a/src/server/server.c b/src/server/server.c index 3f579bfc6..1569f5a2c 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -487,10 +487,8 @@ int server_loop(struct command_context *command_context) timeout_ms = polling_period; tv.tv_usec = timeout_ms * 1000; /* Only while we're sleeping we'll let others run */ - openocd_sleep_prelude(); kept_alive(); retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); - openocd_sleep_postlude(); } if (retval == -1) { diff --git a/src/server/server.h b/src/server/server.h index de18d2b4b..bacd1116a 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -97,15 +97,6 @@ int server_register_commands(struct command_context *context); int connection_write(struct connection *connection, const void *data, int len); int connection_read(struct connection *connection, void *data, int len); -/** - * Used by server_loop(), defined in server_stubs.c - */ -void openocd_sleep_prelude(void); -/** - * Used by server_loop(), defined in server_stubs.c - */ -void openocd_sleep_postlude(void); - /** * Defines an extended command handler function declaration to enable * access to (and manipulation of) the server port number. diff --git a/src/server/server_stubs.c b/src/server/server_stubs.c deleted file mode 100644 index a4c017289..000000000 --- a/src/server/server_stubs.c +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch <zw...@su...> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "server.h" - -void openocd_sleep_prelude(void) -{ - /* no-op */ -} -void openocd_sleep_postlude(void) -{ - /* no-op */ -} commit 2c0a65baa2f17a15fcb5bb014e5dda33fecddaf8 Author: Tim Newsome <ti...@si...> Date: Thu Jan 27 10:00:06 2022 -0800 Fix small memory leak. See https://github.com/riscv/riscv-openocd/pull/672 Change-Id: Ia11ab9bcf860f770ea64ad867102c74b898f6b66 Signed-off-by: Tim Newsome <ti...@si...> Reviewed-on: https://review.openocd.org/c/openocd/+/6831 Tested-by: jenkins Reviewed-by: zapb <de...@za...> Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 7af460241..2b9179d53 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -2308,9 +2308,11 @@ static int init_target(struct command_context *cmd_ctx, generic_info->hart_count = &riscv013_hart_count; generic_info->data_bits = &riscv013_data_bits; generic_info->print_info = &riscv013_print_info; - generic_info->version_specific = calloc(1, sizeof(riscv013_info_t)); - if (!generic_info->version_specific) - return ERROR_FAIL; + if (!generic_info->version_specific) { + generic_info->version_specific = calloc(1, sizeof(riscv013_info_t)); + if (!generic_info->version_specific) + return ERROR_FAIL; + } generic_info->sample_memory = sample_memory; riscv013_info_t *info = get_info(target); commit 7307fd0e3faa7b3e060a722775c532bcb7f70057 Author: Ben McMorran <bem...@mi...> Date: Thu Jan 27 14:30:58 2022 -0800 gdb_server: Include thread name as XML attribute Explicitly providing a thread name in the "thread" element produces better thread visualizations in downstream tools like IDEs. Signed-off-by: Ben McMorran <bem...@mi...> Change-Id: I102c14ddb8b87757fa474de8e3a3f6a1cfe10d98 Reviewed-on: https://review.openocd.org/c/openocd/+/6828 Tested-by: jenkins Reviewed-by: zapb <de...@za...> Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 537670c52..95720e561 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -2619,8 +2619,14 @@ static int gdb_generate_thread_list(struct target *target, char **thread_list_ou if (!thread_detail->exists) continue; - xml_printf(&retval, &thread_list, &pos, &size, - "<thread id=\"%" PRIx64 "\">", thread_detail->threadid); + if (thread_detail->thread_name_str) + xml_printf(&retval, &thread_list, &pos, &size, + "<thread id=\"%" PRIx64 "\" name=\"%s\">", + thread_detail->threadid, + thread_detail->thread_name_str); + else + xml_printf(&retval, &thread_list, &pos, &size, + "<thread id=\"%" PRIx64 "\">", thread_detail->threadid); if (thread_detail->thread_name_str) xml_printf(&retval, &thread_list, &pos, &size, commit f998a2aaf19c14b46fd7f7dd50607a0904f40bd3 Author: Jacek Wuwer <jac...@gm...> Date: Tue Apr 6 20:08:11 2021 +0200 Cadence virtual debug interface (vdebug) integration Change-Id: I1bc105b3addc3f34161c2356c482ff3011e3f2cc Signed-off-by: Jacek Wuwer <jac...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6097 Tested-by: jenkins Reviewed-by: Oleksij Rempel <li...@re...> Reviewed-by: zapb <de...@za...> Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/configure.ac b/configure.ac index a178284ee..68fff45c1 100644 --- a/configure.ac +++ b/configure.ac @@ -274,6 +274,10 @@ AC_ARG_ENABLE([jtag_vpi], AS_HELP_STRING([--enable-jtag_vpi], [Enable building support for JTAG VPI]), [build_jtag_vpi=$enableval], [build_jtag_vpi=no]) +AC_ARG_ENABLE([vdebug], + AS_HELP_STRING([--enable-vdebug], [Enable building support for Cadence Virtual Debug Interface]), + [build_vdebug=$enableval], [build_vdebug=no]) + AC_ARG_ENABLE([jtag_dpi], AS_HELP_STRING([--enable-jtag_dpi], [Enable building support for JTAG DPI]), [build_jtag_dpi=$enableval], [build_jtag_dpi=no]) @@ -513,6 +517,12 @@ AS_IF([test "x$build_jtag_vpi" = "xyes"], [ AC_DEFINE([BUILD_JTAG_VPI], [0], [0 if you don't want JTAG VPI.]) ]) +AS_IF([test "x$build_vdebug" = "xyes"], [ + AC_DEFINE([BUILD_VDEBUG], [1], [1 if you want Cadence vdebug interface.]) +], [ + AC_DEFINE([BUILD_VDEBUG], [0], [0 if you don't want Cadence vdebug interface.]) +]) + AS_IF([test "x$build_jtag_dpi" = "xyes"], [ AC_DEFINE([BUILD_JTAG_DPI], [1], [1 if you want JTAG DPI.]) ], [ @@ -688,8 +698,9 @@ AM_CONDITIONAL([AT91RM9200], [test "x$build_at91rm9200" = "xyes"]) AM_CONDITIONAL([BCM2835GPIO], [test "x$build_bcm2835gpio" = "xyes"]) AM_CONDITIONAL([IMX_GPIO], [test "x$build_imx_gpio" = "xyes"]) AM_CONDITIONAL([BITBANG], [test "x$build_bitbang" = "xyes"]) -AM_CONDITIONAL([JTAG_VPI], [test "x$build_jtag_vpi" = "xyes" -o "x$build_jtag_vpi" = "xyes"]) -AM_CONDITIONAL([JTAG_DPI], [test "x$build_jtag_dpi" = "xyes" -o "x$build_jtag_dpi" = "xyes"]) +AM_CONDITIONAL([JTAG_VPI], [test "x$build_jtag_vpi" = "xyes"]) +AM_CONDITIONAL([VDEBUG], [test "x$build_vdebug" = "xyes"]) +AM_CONDITIONAL([JTAG_DPI], [test "x$build_jtag_dpi" = "xyes"]) AM_CONDITIONAL([USB_BLASTER_DRIVER], [test "x$enable_usb_blaster" != "xno" -o "x$enable_usb_blaster_2" != "xno"]) AM_CONDITIONAL([AMTJTAGACCEL], [test "x$build_amtjtagaccel" = "xyes"]) AM_CONDITIONAL([GW16012], [test "x$build_gw16012" = "xyes"]) diff --git a/doc/openocd.texi b/doc/openocd.texi index e2c495473..fd4a81da2 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -588,6 +588,12 @@ produced, PDF schematics are easily found and it is easy to make. @* A JTAG driver acting as a client for the JTAG VPI server interface. @* Link: @url{http://github.com/fjullien/jtag_vpi} +@item @b{vdebug} +@* A driver for Cadence virtual Debug Interface to emulated or simulated targets. +It implements a client connecting to the vdebug server, which in turn communicates +with the emulated or simulated RTL model through a transactor. The current version +supports only JTAG as a transport, but other virtual transports, like DAP are planned. + @item @b{jtag_dpi} @* A JTAG driver acting as a client for the SystemVerilog Direct Programming Interface (DPI) for JTAG devices. DPI allows OpenOCD to connect to the JTAG @@ -3345,6 +3351,41 @@ This value is only used with the standard variant. @end deffn +@deffn {Interface Driver} {vdebug} +Cadence Virtual Debug Interface driver. + +@deffn {Config Command} {vdebug server} host:port +Specifies the host and TCP port number where the vdebug server runs. +@end deffn + +@deffn {Config Command} {vdebug batching} value +Specifies the batching method for the vdebug request. Possible values are +0 for no batching +1 or wr to batch write transactions together (default) +2 or rw to batch both read and write transactions +@end deffn + +@deffn {Config Command} {vdebug polling} min max +Takes two values, representing the polling interval in ms. Lower values mean faster +debugger responsiveness, but lower emulation performance. The minimum should be +around 10, maximum should not exceed 1000, which is the default gdb and keepalive +timeout value. +@end deffn + +@deffn {Config Command} {vdebug bfm_path} path clk_period +Specifies the hierarchical path and input clk period of the vdebug BFM in the design. +The hierarchical path uses Verilog notation top.inst.inst +The clock period must include the unit, for instance 40ns. +@end deffn + +@deffn {Config Command} {vdebug mem_path} path base size +Specifies the hierarchical path to the design memory instance for backdoor access. +Up to 4 memories can be specified. The hierarchical path uses Verilog notation. +The base specifies start address in the design address space, size its size in bytes. +Both values can use hexadecimal notation with prefix 0x. +@end deffn +@end deffn + @deffn {Interface Driver} {jtag_dpi} SystemVerilog Direct Programming Interface (DPI) compatible driver for JTAG devices in emulation. The driver acts as a client for the SystemVerilog diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index c2161523d..887f99bcd 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -75,6 +75,9 @@ endif if JTAG_VPI DRIVERFILES += %D%/jtag_vpi.c endif +if VDEBUG +DRIVERFILES += %D%/vdebug.c +endif if JTAG_DPI DRIVERFILES += %D%/jtag_dpi.c endif diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c new file mode 100644 index 000000000..a81740cb1 --- /dev/null +++ b/src/jtag/drivers/vdebug.c @@ -0,0 +1,1076 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ +/*---------------------------------------------------------------------------- + * Copyright 2020-2021 Cadence Design Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + *---------------------------------------------------------------------------- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------- +*/ + +/*! + * @file + * + * @brief the virtual debug interface provides a connection between a sw debugger + * and the simulated, emulated core over a soft connection, implemented by DPI + * The vdebug debug driver currently supports JTAG transport + * TODO: implement support and test big endian platforms + * +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#else +#ifdef HAVE_UNISTD_H +#include <unistd.h> /* close */ +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#endif +#include <stdio.h> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <stdarg.h> +#include <string.h> +#include <errno.h> + +#include "jtag/interface.h" +#include "jtag/commands.h" +#include "transport/transport.h" +#include "helper/time_support.h" +#include "helper/replacements.h" +#include "helper/log.h" + +#define VD_VERSION 43 +#define VD_BUFFER_LEN 4024 +#define VD_CHEADER_LEN 24 +#define VD_SHEADER_LEN 16 + +#define VD_MAX_MEMORIES 4 +#define VD_POLL_INTERVAL 500 +#define VD_SCALE_PSTOMS 1000000000 + +/** + * @brief List of transactor types + */ +enum { + VD_BFM_JTDP = 0x0001, /* transactor DAP JTAG DP */ + VD_BFM_SWDP = 0x0002, /* transactor DAP SWD DP */ + VD_BFM_AHB = 0x0003, /* transactor AMBA AHB */ + VD_BFM_APB = 0x0004, /* transactor AMBA APB */ + VD_BFM_AXI = 0x0005, /* transactor AMBA AXI */ + VD_BFM_JTAG = 0x0006, /* transactor serial JTAG */ + VD_BFM_SWD = 0x0007, /* transactor serial SWD */ +}; + +/** + * @brief List of signals that can be read or written by the debugger + */ +enum { + VD_SIG_TCK = 0x0001, /* JTAG clock; tclk */ + VD_SIG_TDI = 0x0002, /* JTAG TDI; tdi */ + VD_SIG_TMS = 0x0004, /* JTAG TMS; tms */ + VD_SIG_RESET = 0x0008, /* DUT reset; rst */ + VD_SIG_TRST = 0x0010, /* JTAG Reset; trstn */ + VD_SIG_TDO = 0x0020, /* JTAG TDO; tdo */ + VD_SIG_POWER = 0x0100, /* BFM power; bfm_up */ + VD_SIG_TCKDIV = 0x0200, /* JTAG clock divider; tclkdiv */ + VD_SIG_BUF = 0x1000, /* memory buffer; mem */ +}; + +/** + * @brief List of errors + */ +enum { + VD_ERR_NONE = 0x0000, /* no error */ + VD_ERR_NOT_IMPL = 0x0100, /* feature not implemented */ + VD_ERR_USAGE = 0x0101, /* incorrect usage */ + VD_ERR_PARAM = 0x0102, /* incorrect parameter */ + VD_ERR_CONFIG = 0x0107, /* incorrect configuration */ + VD_ERR_NO_MEMORY = 0x0104, /* out of memory */ + VD_ERR_SHM_OPEN = 0x010a, /* cannot open shared memory */ + VD_ERR_SHM_MAP = 0x010b, /* cannot map shared memory */ + VD_ERR_SOC_OPEN = 0x011a, /* cannot open socket */ + VD_ERR_SOC_OPT = 0x011b, /* cannot set socket option */ + VD_ERR_SOC_ADDR = 0x011c, /* cannot resolve host address */ + VD_ERR_SOC_CONN = 0x011d, /* cannot connect to host */ + VD_ERR_SOC_SEND = 0x011e, /* error sending data on socket */ + VD_ERR_SOC_RECV = 0x011f, /* error receiving data from socket */ + VD_ERR_LOCKED = 0x0202, /* device locked */ + VD_ERR_NOT_RUN = 0x0204, /* transactor not running */ + VD_ERR_NOT_OPEN = 0x0205, /* transactor not open/connected */ + VD_ERR_LICENSE = 0x0206, /* cannot check out the license */ + VD_ERR_VERSION = 0x0207, /* transactor version mismatch */ + VD_ERR_TIME_OUT = 0x0301, /* time out, waiting */ + VD_ERR_NO_POWER = 0x0302, /* power out error */ + VD_ERR_BUS_ERROR = 0x0304, /* bus protocol error, like pslverr */ + VD_ERR_NO_ACCESS = 0x0306, /* no access to an object */ + VD_ERR_INV_HANDLE = 0x0307, /* invalid object handle */ + VD_ERR_INV_SCOPE = 0x0308, /* invalid scope */ +}; + +enum { + VD_CMD_OPEN = 0x01, + VD_CMD_CLOSE = 0x02, + VD_CMD_CONNECT = 0x04, + VD_CMD_DISCONNECT = 0x05, + VD_CMD_WAIT = 0x09, + VD_CMD_SIGSET = 0x0a, + VD_CMD_SIGGET = 0x0b, + VD_CMD_JTAGCLOCK = 0x0f, + VD_CMD_JTAGSHTAP = 0x1a, + VD_CMD_MEMOPEN = 0x21, + VD_CMD_MEMCLOSE = 0x22, + VD_CMD_MEMWRITE = 0x23, +}; + +enum { + VD_BATCH_NO = 0, + VD_BATCH_WO = 1, + VD_BATCH_WR = 2, +}; + +struct vd_shm { + struct { /* VD_CHEADER_LEN written by client */ + uint8_t cmd; /* 000; command */ + uint8_t type; /* 001; interface type */ + uint16_t waddr; /* 002; write pointer */ + uint16_t wbytes; /* 004; data bytes */ + uint16_t rbytes; /* 006; data bytes to read */ + uint16_t wwords; /* 008; data words */ + uint16_t rwords; /* 00a; data words to read */ + uint32_t rwdata; /* 00c; read/write data */ + uint32_t offset; /* 010; address offset */ + uint16_t offseth; /* 014; address offset 47:32 */ + uint16_t wid; /* 016; request id*/ + }; + union { /* 018; */ + uint8_t wd8[VD_BUFFER_LEN]; + uint16_t wd16[VD_BUFFER_LEN / 2]; + uint32_t wd32[VD_BUFFER_LEN / 4]; + uint64_t wd64[VD_BUFFER_LEN / 8]; + }; + struct { /* VD_SHEADER_LEN written by server */ + uint16_t rid; /* fd0: request id read */ + uint16_t awords; /* fd2: actual data words read back */ + int32_t status; /* fd4; */ + uint64_t duttime; /* fd8; */ + }; + union { /* fe0: */ + uint8_t rd8[VD_BUFFER_LEN]; + uint16_t rd16[VD_BUFFER_LEN / 2]; + uint32_t rd32[VD_BUFFER_LEN / 4]; + uint64_t rd64[VD_BUFFER_LEN / 8]; + }; + uint32_t state; /* 1f98; connection state */ + uint32_t count; /* 1f9c; */ + uint8_t dummy[96]; /* 1fa0; 48+40B+8B; */ +}; + +struct vd_client { + uint8_t trans_batch; + bool trans_first; + bool trans_last; + uint8_t mem_ndx; + uint8_t buf_width; + uint8_t addr_bits; + uint8_t bfm_type; + uint16_t sig_read; + uint16_t sig_write; + uint32_t bfm_period; + uint32_t mem_base[VD_MAX_MEMORIES]; + uint32_t mem_size[VD_MAX_MEMORIES]; + uint32_t mem_width[VD_MAX_MEMORIES]; + uint32_t mem_depth[VD_MAX_MEMORIES]; + uint16_t server_port; + uint32_t poll_cycles; + uint32_t poll_min; + uint32_t poll_max; + uint32_t targ_time; + int hsocket; + char server_name[32]; + char bfm_path[128]; + char mem_path[VD_MAX_MEMORIES][128]; + uint8_t *tdo; +}; + +struct vd_jtag_hdr { + uint64_t tlen:24; + uint64_t post:3; + uint64_t pre:3; + uint64_t cmd:2; + uint64_t wlen:16; + uint64_t rlen:16; +}; + +static struct vd_shm *pbuf; +static struct vd_client vdc; + +static int vdebug_socket_error(void) +{ +#ifdef _WIN32 + return WSAGetLastError(); +#else + return errno; +#endif +} + +static int vdebug_socket_open(char *server_addr, uint32_t port) +{ + int hsock; + int rc = 0; + uint32_t buflen = sizeof(struct vd_shm); /* size of the send and rcv buffer */ + struct addrinfo *ainfo = NULL; + struct addrinfo ahint = { 0, AF_INET, SOCK_STREAM, 0, 0, NULL, NULL, NULL }; + +#ifdef _WIN32 + hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + if (hsock == INVALID_SOCKET) + rc = vdebug_socket_error(); +#else + uint32_t rcvwat = VD_SHEADER_LEN; /* size of the rcv header, as rcv min watermark */ + hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + if (hsock < 0) + rc = errno; + else if (setsockopt(hsock, SOL_SOCKET, SO_RCVLOWAT, &rcvwat, sizeof(rcvwat)) < 0) + rc = errno; +#endif + else if (setsockopt(hsock, SOL_SOCKET, SO_SNDBUF, (const char *)&buflen, sizeof(buflen)) < 0) + rc = vdebug_socket_error(); + else if (setsockopt(hsock, SOL_SOCKET, SO_RCVBUF, (const char *)&buflen, sizeof(buflen)) < 0) + rc = vdebug_socket_error(); + + if (rc) { + LOG_ERROR("socket_open: cannot set socket option, error %d", rc); + } else if (getaddrinfo(server_addr, NULL, &ahint, &ainfo) != 0) { + LOG_ERROR("socket_open: cannot resolve address %s, error %d", server_addr, vdebug_socket_error()); + rc = VD_ERR_SOC_ADDR; + } else { + ((struct sockaddr_in *)(ainfo->ai_addr))->sin_port = htons(port); + if (connect(hsock, ainfo->ai_addr, sizeof(struct sockaddr)) < 0) { + LOG_ERROR("socket_open: cannot connect to %s:%d, error %d", server_addr, port, vdebug_socket_error()); + rc = VD_ERR_SOC_CONN; + } + } + + if (rc) { + close_socket(hsock); + hsock = 0; + } + + if (ainfo) + freeaddrinfo(ainfo); + + return hsock; +} + +static int vdebug_socket_receive(int hsock, struct vd_shm *pmem) +{ + int rc; + int dreceived = 0; + int offset = (uint8_t *)&pmem->rid - &pmem->cmd; + int to_receive = VD_SHEADER_LEN + pmem->rbytes; + char *pb = (char *)pmem; + + do { + rc = recv(hsock, pb + offset, to_receive, 0); + if (rc <= 0) { + LOG_WARNING("socket_receive: recv failed, error %d", rc < 0 ? vdebug_socket_error() : 0); + return rc; + } + to_receive -= rc; + offset += rc; + LOG_DEBUG_IO("socket_receive: received %d, to receive %d", rc, to_receive); + dreceived += rc; + } while (to_receive); + + return dreceived; +} + +static int vdebug_socket_send(int hsock, struct vd_shm *pmem) +{ + int rc = send(hsock, (const char *)&pmem->cmd, VD_CHEADER_LEN + pmem->wbytes, 0); + if (rc <= 0) + LOG_WARNING("socket_send: send failed, error %d", vdebug_socket_error()); + else + LOG_DEBUG_IO("socket_send: sent %d, to send 0", rc); + + return rc; +} + +static uint32_t vdebug_wait_server(int hsock, struct vd_shm *pmem) +{ + if (!hsock) + return VD_ERR_SOC_OPEN; + int st = vdebug_socket_send(hsock, pmem); + if (st <= 0) + return VD_ERR_SOC_SEND; + + int rd = vdebug_socket_receive(hsock, pmem); + if (rd <= 0) + return VD_ERR_SOC_RECV; + + int rc = pmem->status; + LOG_DEBUG_IO("wait_server: cmd %02" PRIx8 " done, sent %d, rcvd %d, status %d", + pmem->cmd, st, rd, rc); + + return rc; +} + +int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count) +{ + uint8_t num_pre, num_post, tdi, tms; + unsigned int num, anum, bytes, hwords, words; + unsigned int req, waddr, rwords; + int64_t ts, te; + uint8_t *tdo; + int rc; + struct vd_jtag_hdr *hdr; + + req = 0; /* beginning of request */ + waddr = 0; + rwords = 0; + pm->wbytes = pm->wwords * vdc.buf_width; + pm->rbytes = pm->rwords * vdc.buf_width; + ts = timeval_ms(); + rc = vdebug_wait_server(hsock, pm); + while (!rc && (req < count)) { /* loop over requests to read data and print out */ + hdr = (struct vd_jtag_hdr *)&pm->wd8[waddr * 4]; + hwords = hdr->wlen; + words = hdr->rlen; + anum = hdr->tlen; + num_pre = hdr->pre; + num_post = hdr->post; + if (num_post) + num = anum - num_pre - num_post + 1; + else + num = anum - num_pre; + bytes = (num + 7) / 8; + vdc.trans_last = (req + 1) < count ? 0 : 1; + vdc.trans_first = waddr ? 0 : 1; + if (hdr->cmd == 3) { /* read */ + tdo = vdc.tdo; + for (unsigned int j = 0; j < bytes; j++) { + tdo[j] = (pm->rd8[rwords * 8 + j] >> num_pre) | (pm->rd8[rwords * 8 + j + 1] << (8 - num_pre)); + LOG_DEBUG_IO("%04x D0[%02x]:%02x", pm->wid - count + req, j, tdo[j]); + } + rwords += words; /* read data offset */ + } else { + tdo = NULL; + } + waddr += sizeof(struct vd_jtag_hdr) / 4; /* waddr past header */ + tdi = (pm->wd8[waddr * 4] >> num_pre) | (pm->wd8[waddr * 4 + 1] << (8 - num_pre)); + tms = (pm->wd8[waddr * 4 + 4] >> num_pre) | (pm->wd8[waddr * 4 + 4 + 1] << (8 - num_pre)); + LOG_DEBUG("%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x", + pm->wid - count + req, num, (vdc.trans_first << 14) | (vdc.trans_last << 15), + waddr - 2, tdi, tms, (tdo ? tdo[0] : 0xdd)); + waddr += hwords * 2; /* start of next request */ + req += 1; + } + + if (rc) { + LOG_ERROR("0x%x executing transaction", rc); + rc = ERROR_FAIL; + } + + te = timeval_ms(); + vdc.targ_time += (uint32_t)(te - ts); + pm->offseth = 0; /* reset buffer write address */ + pm->offset = 0; + pm->rwords = 0; + pm->waddr = 0; + + return rc; +} + +static int vdebug_open(int hsock, struct vd_shm *pm, const char *path, + uint8_t type, uint32_t period_ps, uint32_t sig_mask) +{ + int rc = VD_ERR_NOT_OPEN; + + pm->cmd = VD_CMD_OPEN; + pm->wid = VD_VERSION; /* client version */ + pm->wbytes = 0; + pm->rbytes = 0; + pm->wwords = 0; + pm->rwords = 0; + rc = vdebug_wait_server(hsock, pm); + if (rc != 0) { /* communication problem */ + LOG_ERROR("0x%x connecting to server", rc); + } else if (pm->rid < pm->wid) { + LOG_ERROR("server version %d too old for the client %d", pm->rid, pm->wid); + pm->cmd = VD_CMD_CLOSE; /* let server close the connection */ + vdebug_wait_server(hsock, pm); + rc = VD_ERR_VERSION; + } else { + pm->cmd = VD_CMD_CONNECT; + pm->type = type; /* BFM type to connect to, here JTAG */ + pm->rwdata = sig_mask | VD_SIG_BUF | (VD_SIG_BUF << 16); + pm->wbytes = strlen(path) + 1; + pm->rbytes = 12; + pm->wid = 0; /* reset wid for transaction ID */ + pm->wwords = 0; + pm->rwords = 0; + memcpy(pm->wd8, path, pm->wbytes + 1); + rc = vdebug_wait_server(hsock, pm); + vdc.sig_read = pm->rwdata >> 16; /* signal read mask */ + vdc.sig_write = pm->rwdata; /* signal write mask */ + vdc.bfm_period = period_ps; + vdc.buf_width = pm->rd32[0] / 8;/* access width in bytes */ + vdc.addr_bits = pm->rd32[2]; /* supported address bits */ + } + + if (rc) { + LOG_ERROR("0x%x connecting to BFM %s", rc, path); + return ERROR_FAIL; + } + + LOG_DEBUG("%s type %0x, period %dps, buffer %dx%dB signals r%04xw%04x", + path, type, vdc.bfm_period, VD_BUFFER_LEN / vdc.buf_width, + vdc.buf_width, vdc.sig_read, vdc.sig_write); + + return ERROR_OK; +} + +static int vdebug_close(int hsock, struct vd_shm *pm, uint8_t type) +{ + pm->cmd = VD_CMD_DISCONNECT; + pm->type = type; /* BFM type, here JTAG */ + pm->wbytes = 0; + pm->rbytes = 0; + pm->wwords = 0; + pm->rwords = 0; + vdebug_wait_server(hsock, pm); + pm->cmd = VD_CMD_CLOSE; + pm->wid = VD_VERSION; /* client version */ + pm->wbytes = 0; + pm->rbytes = 0; + pm->wwords = 0; + pm->rwords = 0; + vdebug_wait_server(hsock, pm); + LOG_DEBUG("type %0x", type); + + return ERROR_OK; +} + +static int vdebug_wait(int hsock, struct vd_shm *pm, uint32_t cycles) +{ + if (cycles) { + pm->cmd = VD_CMD_WAIT; + pm->wbytes = 0; + pm->rbytes = 0; + pm->rwdata = cycles; /* clock sycles to wait */ + int rc = vdebug_wait_server(hsock, pm); + if (rc) { + LOG_ERROR("0x%x waiting %" PRIx32 " cycles", rc, cycles); + return ERROR_FAIL; + } + LOG_DEBUG("%d cycles", cycles); + } + + return ERROR_OK; +} + +static int vdebug_sig_set(int hsock, struct vd_shm *pm, uint32_t write_mask, uint32_t value) +{ + pm->cmd = VD_CMD_SIGSET; + pm->wbytes = 0; + pm->rbytes = 0; + pm->rwdata = (write_mask << 16) | (value & 0xffff); /* mask and value of signals to set */ + int rc = vdebug_wait_server(hsock, pm); + if (rc) { + LOG_ERROR("0x%x setting signals %04" PRIx32, rc, write_mask); + return ERROR_FAIL; + } + + LOG_DEBUG("setting signals %04" PRIx32 " to %04" PRIx32, write_mask, value); + + return ERROR_OK; +} + +static int vdebug_jtag_clock(int hsock, struct vd_shm *pm, uint32_t value) +{ + pm->cmd = VD_CMD_JTAGCLOCK; + pm->wbytes = 0; + pm->rbytes = 0; + pm->rwdata = value; /* divider value */ + int rc = vdebug_wait_server(hsock, pm); + if (rc) { + LOG_ERROR("0x%x setting jtag_clock", rc); + return ERROR_FAIL; + } + + LOG_DEBUG("setting jtag clock divider to %" PRIx32, value); + + return ERROR_OK; +} + +static int vdebug_jtag_shift_tap(int hsock, struct vd_shm *pm, uint8_t num_pre, + const uint8_t tms_pre, uint32_t num, const uint8_t *tdi, + uint8_t num_post, const uint8_t tms_post, uint8_t *tdo, + uint8_t f_last) +{ + const uint32_t tobits = 8; + uint16_t bytes, hwords, anum, words, waddr; + int rc = 0; + + pm->cmd = VD_CMD_JTAGSHTAP; + vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO) || tdo; + if (vdc.trans_first) + waddr = 0; /* reset buffer offset */ + else + waddr = pm->offseth; /* continue from the previous transaction */ + if (num_post) /* actual number of bits to shift */ + anum = num + num_pre + num_post - 1; + else + anum = num + num_pre; + hwords = (anum + 4 * vdc.buf_width - 1) / (4 * vdc.buf_width); /* in 4B TDI/TMS words */ + words = (hwords + 1) / 2; /* in 8B TDO words to read */ + bytes = (num + 7) / 8; /* data only portion in bytes */ + /* buffer overflow check and flush */ + if (4 * waddr + sizeof(struct vd_jtag_hdr) + 8 * hwords + 64 > VD_BUFFER_LEN) { + vdc.trans_last = 1; /* force flush within 64B of buffer end */ + } else if (4 * waddr + sizeof(struct vd_jtag_hdr) + 8 * hwords > VD_BUFFER_LEN) { + /* this req does not fit, discard it */ + LOG_ERROR("%04x L:%02d O:%05x @%04x too many bits to shift", + pm->wid, anum, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr); + rc = ERROR_FAIL; + } + + if (!rc && anum) { + uint16_t i, j; + struct vd_jtag_hdr *hdr = (struct vd_jtag_hdr *)&pm->wd8[4 * waddr]; /* 8 bytes header */ + hdr->cmd = (tdo ? 3 : 1); /* R and W bits */ + hdr->pre = num_pre; + hdr->post = num_post; + hdr->tlen = anum; + hdr->wlen = hwords; + hdr->rlen = words; + pm->wid++; /* transaction ID */ + waddr += 2; /* waddr past header */ + /* TDI/TMS data follows as 32 bit word pairs {TMS,TDI} */ + pm->wd8[4 * waddr] = (tdi ? (tdi[0] << num_pre) : 0); + pm->wd8[4 * waddr + 4] = tms_pre; /* init with tms_pre */ + if (num + num_pre <= 8) /* and tms_post for num <=4 */ + pm->wd8[4 * waddr + 4] |= (tms_post << (num + num_pre - 1)); + for (i = 1, j = 4 * waddr; i < bytes; i++) { + if (i == bytes - 1 && num + num_pre <= bytes * tobits) + pm->wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8); + else + pm->wd8[j + i + 4] = 0x0;/* placing 4 bytes of TMS bits into high word */ + if (!tdi) /* placing 4 bytes of TDI bits into low word */ + pm->wd8[j + i] = 0x0; + else + pm->wd8[j + i] = (tdi[i] << num_pre) | (tdi[i - 1] >> (8 - num_pre)); + if (i % 4 == 3) + j += 4; + } + + if (tdi) + if (num + num_pre > bytes * tobits) /* in case 1 additional byte needed for TDI */ + pm->wd8[j + i] = (tdi[i - 1] >> (8 - num_pre)); /* put last TDI bits there */ + + if (num + num_pre <= bytes * tobits) { /* in case no or 1 additional byte needed */ + pm->wd8[j + i + 4] = tms_post >> (8 - (num + num_pre - 1) % 8); /* may need to add higher part */ + /* in case exactly 1 additional byte needed */ + } else if (num + num_pre > bytes * tobits && anum <= (bytes + 1) * tobits) { + pm->wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8); /* add whole tms_post */ + } else { /* in case 2 additional bytes, tms_post split */ + pm->wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8);/* add lower part of tms_post */ + if (i % 4 == 3) /* next byte is in the next 32b word */ + pm->wd8[j + i + 4 + 5] = tms_post >> (8 - (num + num_pre - 1) % 8); /* and higher part */ + else /* next byte is in the same 32b word */ + pm->wd8[j + i + 4 + 1] = tms_post >> (8 - (num + num_pre - 1) % 8); /* and higher part */ + } + + if (tdo) { + pm->rwords += words; /* keep track of the words to read */ + vdc.tdo = tdo; + } + pm->wwords = waddr / 2 + hwords; /* payload size *2 to include both TDI and TMS data */ + pm->waddr++; + } + + if (!waddr) /* flush issued, but buffer empty */ + ; + else if (!vdc.trans_last) /* buffered request */ + pm->offseth = waddr + hwords * 2; /* offset for next transaction, must be even */ + else /* execute batch of requests */ + rc = vdebug_run_jtag_queue(hsock, pm, pm->waddr); + vdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */ + + return rc; +} + +static int vdebug_mem_open(int hsock, struct vd_shm *pm, const char *path, uint8_t ndx) +{ + int rc; + + if (!path) + return ERROR_OK; + + pm->cmd = VD_CMD_MEMOPEN; + pm->wbytes = strlen(path) + 1; /* includes terminating 0 */ + pm->rbytes = 8; + pm->wwords = 0; + pm->rwords = 0; + memcpy(pm->wd8, path, pm->wbytes); + rc = vdebug_wait_server(hsock, pm); + if (rc) { + LOG_ERROR("0x%x opening memory %s", rc, path); + } else if (ndx != pm->rd16[1]) { + LOG_WARNING("Invalid memory index %" PRIu16 " returned. Direct memory access disabled", pm->rd16[1]); + } else { + vdc.mem_width[ndx] = pm->rd16[0] / 8; /* memory width in bytes */ + vdc.mem_depth[ndx] = pm->rd32[1]; /* memory depth in words */ + LOG_DEBUG("%" PRIx8 ": %s memory %" PRIu32 "x%" PRIu32 "B, buffer %" PRIu32 "x%" PRIu32 "B", ndx, path, + vdc.mem_depth[ndx], vdc.mem_width[ndx], VD_BUFFER_LEN / vdc.mem_width[ndx], vdc.mem_width[ndx]); + } + + return ERROR_OK; +} + +static void vdebug_mem_close(int hsock, struct vd_shm *pm, uint8_t ndx) +{ + pm->cmd = VD_CMD_MEMCLOSE; + pm->rwdata = ndx; /* which memory */ + pm->wbytes = 0; + pm->rbytes = 0; + pm->wwords = 0; + pm->rwords = 0; + vdebug_wait_server(hsock, pm); + LOG_DEBUG("%" PRIx8 ": %s", ndx, vdc.mem_path[ndx]); +} + +static int vdebug_init(void) +{ + vdc.hsocket = vdebug_socket_open(vdc.server_name, vdc.server_port); + pbuf = calloc(1, sizeof(struct vd_shm)); + if (!pbuf) { + close_socket(vdc.hsocket); + vdc.hsocket = 0; + LOG_ERROR("cannot allocate %lu bytes", sizeof(struct vd_shm)); + return ERROR_FAIL; + } + if (vdc.hsocket <= 0) { + free(pbuf); + pbuf = NULL; + LOG_ERROR("cannot connect to vdebug server %s:%" PRIu16, + vdc.server_name, vdc.server_port); + return ERROR_FAIL; + } + vdc.trans_first = 1; + vdc.poll_cycles = vdc.poll_max; + uint32_t sig_mask = VD_SIG_RESET | VD_SIG_TRST | VD_SIG_TCKDIV; + int rc = vdebug_open(vdc.hsocket, pbuf, vdc.bfm_path, vdc.bfm_type, vdc.bfm_period, sig_mask); + if (rc != 0) { + LOG_ERROR("cannot connect to %s, rc 0x%x", vdc.bfm_path, rc); + close_socket(vdc.hsocket); + vdc.hsocket = 0; + free(pbuf); + pbuf = NULL; + } else { + for (uint8_t i = 0; i < vdc.mem_ndx; i++) { + rc = vdebug_mem_open(vdc.hsocket, pbuf, vdc.mem_path[i], i); + if (rc != 0) + LOG_ERROR("cannot connect to %s, rc 0x%x", vdc.mem_path[i], rc); + } + + LOG_INFO("vdebug %d connected to %s through %s:%" PRIu16, + VD_VERSION, vdc.bfm_path, vdc.server_name, vdc.server_port); + } + + return rc; +} + +static int vdebug_quit(void) +{ + for (uint8_t i = 0; i < vdc.mem_ndx; i++) + if (vdc.mem_width[i]) + vdebug_mem_close(vdc.hsocket, pbuf, i); + int rc = vdebug_close(vdc.hsocket, pbuf, vdc.bfm_type); + LOG_INFO("vdebug %d disconnected from %s through %s:%" PRIu16 " rc:%d", VD_VERSION, + vdc.bfm_path, vdc.server_name, vdc.server_port, rc); + if (vdc.hsocket) + close_socket(vdc.hsocket); + free(pbuf); + pbuf = NULL; + + return ERROR_OK; +} + +static int vdebug_reset(int trst, int srst) +{ + uint16_t sig_val = 0xffff; + uint16_t sig_mask = 0; + + sig_mask |= VD_SIG_RESET; + if (srst) + sig_val &= ~VD_SIG_RESET;/* active low */ + if (transport_is_jtag()) { + sig_mask |= VD_SIG_TRST; + if (trst) + sig_val &= ~VD_SIG_TRST; /* active low */ + } + + LOG_INFO("rst trst:%d srst:%d mask:%" PRIx16 " val:%" PRIx16, trst, srst, sig_mask, sig_val); + int rc = vdebug_sig_set(vdc.hsocket, pbuf, sig_mask, sig_val); + if (rc == 0) + rc = vdebug_wait(vdc.hsocket, pbuf, 20); /* 20 clock cycles pulse */ + + return rc; +} + +static int vdebug_jtag_tms_seq(const uint8_t *tms, int num, uint8_t f_flush) +{ + LOG_INFO("tms len:%d tms:%x", num, *(const uint32_t *)tms); + + return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num, *tms, 0, NULL, 0, 0, NULL, f_flush); +} + +static int vdebug_jtag_path_move(struct pathmove_command *cmd, uint8_t f_flush) +{ + uint8_t tms[DIV_ROUND_UP(cmd->num_states, 8)]; + LOG_INFO("path num states %d", cmd->num_states); + + memset(tms, 0, DIV_ROUND_UP(cmd->num_states, 8)); + + for (uint8_t i = 0; i < cmd->num_states; i++) { + if (tap_state_transition(tap_get_state(), true) == cmd->path[i]) + buf_set_u32(tms, i, 1, 1); + tap_set_state(cmd->path[i]); + } + + return vdebug_jtag_tms_seq(tms, cmd->num_states, f_flush); +} + +static int vdebug_jtag_tlr(tap_state_t state, uint8_t f_flush) +{ + int rc = ERROR_OK; + + uint8_t cur = tap_get_state(); + uint8_t tms_pre = tap_get_tms_path(cur, state); + uint8_t num_pre = tap_get_tms_path_len(cur, state); + LOG_INFO("tlr from %" PRIx8 " to %" PRIx8, cur, state); + if (cur != state) { + rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, 0, NULL, 0, 0, NULL, f_flush); + tap_set_state(state); + } + + return rc; +} + +static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush) +{ + int rc = ERROR_OK; + + uint8_t cur = tap_get_state(); + uint8_t state = cmd->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT; + uint8_t tms_pre = tap_get_tms_path(cur, state); + uint8_t num_pre = tap_get_tms_path_len(cur, state); + uint8_t tms_post = tap_get_tms_path(state, cmd->end_state); + uint8_t num_post = tap_get_tms_path_len(state, cmd->end_state); + int num_bits = jtag_scan_size(cmd); + LOG_DEBUG("scan len:%d fields:%d ir/!dr:%d state cur:%x end:%x", + num_bits, cmd->num_fields, cmd->ir_scan, cur, cmd->end_state); + for (int i = 0; i < cmd->num_fields; i++) { + uint8_t cur_num_pre = i == 0 ? num_pre : 0; + uint8_t cur_tms_pre = i == 0 ? tms_pre : 0; + uint8_t cur_num_post = i == cmd->num_fields - 1 ? num_post : 0; + uint8_t cur_tms_post = i == cmd->num_fields - 1 ? tms_post : 0; + uint8_t cur_flush = i == cmd->num_fields - 1 ? f_flush : 0; + rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, cur_num_pre, cur_tms_pre, + cmd->fields[i].num_bits, cmd->fields[i].out_value, cur_num_post, cur_tms_post, + cmd->fields[i].in_value, cur_flush); + if (rc) + break; + } + + if (cur != cmd->end_state) + tap_set_state(cmd->end_state); + + return rc; +} + +static int vdebug_jtag_runtest(int cycles, tap_state_t state, uint8_t f_flush) +{ + uint8_t cur = tap_get_state(); + uint8_t tms_pre = tap_get_tms_path(cur, state); + uint8_t num_pre = tap_get_tms_path_len(cur, state); + LOG_DEBUG("idle len:%d state cur:%x end:%x", cycles, cur, state); + int rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, cycles, NULL, 0, 0, NULL, f_flush); + if (cur != state) + tap_set_state(state); + + return rc; +} + +static int vdebug_jtag_stableclocks(int num, uint8_t f_flush) +{ + LOG_INFO("stab len:%d state cur:%x", num, tap_get_state()); + + return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, 0, 0, num, NULL, 0, 0, NULL, f_flush); +} + +static int vdebug_sleep(int us) +{ + LOG_INFO("sleep %d us", us); + + return vdebug_wait(vdc.hsocket, pbuf, us / 1000); +} + +static int vdebug_jtag_speed(int speed) +{ + unsigned int clkmax = VD_SCALE_PSTOMS / (vdc.bfm_period * 2); /* kHz */ + unsigned int divval = clkmax / speed; + LOG_INFO("jclk speed:%d kHz set, BFM divider %u", speed, divval); + + return vdebug_jtag_clock(vdc.hsocket, pbuf, divval); +} + +static int vdebug_jtag_khz(int khz, int *jtag_speed) +{ + unsigned int clkmax = VD_SCALE_PSTOMS / (vdc.bfm_period * 2); /* kHz */ + unsigned int divval = khz ? clkmax / khz : 1; + *jtag_speed = clkmax / divval; + LOG_DEBUG("khz speed:%d from khz:%d", *jtag_speed, khz); + + return ERROR_OK; +} + +static int vdebug_jtag_div(int speed, int *khz) +{ + *khz = speed; + LOG_DEBUG("div khz:%d from speed:%d", *khz, speed); + + return ERROR_OK; +} + +static int vdebug_jtag_execute_queue(void) +{ + int rc = ERROR_OK; + + for (struct jtag_command *cmd = jtag_command_queue; rc == ERROR_OK && cmd; cmd = cmd->next) { + switch (cmd->type) { + case JTAG_RUNTEST: + rc = vdebug_jtag_runtest(cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state, !cmd->next); + break; + case JTAG_STABLECLOCKS: + rc = vdebug_jtag_stableclocks(cmd->cmd.stableclocks->num_cycles, !cmd->next); + break; + case JTAG_TLR_RESET: + rc = vdebug_jtag_tlr(cmd->cmd.statemove->end_state, !cmd->next); + break; + case JTAG_PATHMOVE: + rc = vdebug_jtag_path_move(cmd->cmd.pathmove, !cmd->next); + break; + case JTAG_TMS: + rc = vdebug_jtag_tms_seq(cmd->cmd.tms->bits, cmd->cmd.tms->num_bits, !cmd->next); + break; + case JTAG_SLEEP: + rc = vdebug_sleep(cmd->cmd.sleep->us); + break; + case JTAG_SCAN: + rc = vdebug_jtag_scan(cmd->cmd.scan, !cmd->next); + break; + default: + LOG_ERROR("Unknown JTAG command type 0x%x encountered", cmd->type); + rc = ERROR_FAIL; + } + } + + return rc; +} + +COMMAND_HANDLER(vdebug_set_server) +{ + if ((CMD_ARGC != 1) || !strchr(CMD_ARGV[0], ':')) + return ERROR_COMMAND_SYNTAX_ERROR; + + char *pchar = strchr(CMD_ARGV[0], ':'); + *pchar = '\0'; + strncpy(vdc.server_name, CMD_ARGV[0], sizeof(vdc.server_name) - 1); + int port = atoi(++pchar); + if (port < 0 || port > UINT16_MAX) { + LOG_ERROR("invalid port number %d specified", port); + return ERROR_COMMAND_SYNTAX_ERROR; + } + vdc.server_port = port; + LOG_DEBUG("server: %s port %u", vdc.server_name, vdc.server_port); + + return ERROR_OK; +} + +COMMAND_HANDLER(vdebug_set_bfm) +{ + char prefix; + + if ((CMD_ARGC != 2) || (sscanf(CMD_ARGV[1], "%u%c", &vdc.bfm_period, &prefix) != 2)) + return ERROR_COMMAND_SYNTAX_ERROR; + + strncpy(vdc.bfm_path, CMD_ARGV[0], sizeof(vdc.bfm_path) - 1); + switch (prefix) { + case 'u': + vdc.bfm_period *= 1000000; + break; + case 'n': + vdc.bfm_period *= 1000; + break; + case 'p': + default: + break; + } + vdc.bfm_type = VD_BFM_JTAG; + LOG_DEBUG("bfm_path: %s clk_period %ups", vdc.bfm_path, vdc.bfm_period); + + return ERROR_OK; +} + +COMMAND_HANDLER(vdebug_set_mem) +{ + if (CMD_ARGC != 3) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (vdc.mem_ndx >= VD_MAX_MEMORIES) { + LOG_ERROR("mem_path declared more than %d allowed times", VD_MAX_MEMORIES); + return ERROR_FAIL; + } + + strncpy(vdc.mem_path[vdc.mem_ndx], CMD_ARGV[0], sizeof(vdc.mem_path[vdc.mem_ndx]) - 1); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], vdc.mem_base[vdc.mem_ndx]); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], vdc.mem_size[vdc.mem_ndx]); + LOG_DEBUG("mem_path: set %s @ 0x%08x+0x%08x", vdc.mem_path[vdc.mem_ndx], + vdc.mem_base[vdc.mem_ndx], vdc.mem_size[vdc.mem_ndx]); + vdc.mem_ndx++; + + return ERROR_OK; +} + +COMMAND_HANDLER(vdebug_set_batching) +{ + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (isdigit((unsigned char)CMD_ARGV[0][0])) + vdc.trans_batch = (CMD_ARGV[0][0] == '0' ? 0 : (CMD_ARGV[0][0] == '1' ? 1 : 2)); + else if (CMD_ARGV[0][0] == 'r') + vdc.trans_batch = VD_BATCH_WR; + else if (CMD_ARGV[0][0] == 'w') + vdc.trans_batch = VD_BATCH_WO; + else + vdc.trans_batch = VD_BATCH_NO; + LOG_DEBUG("batching: set to %u", vdc.trans_batch); + + return ERROR_OK; +} + +COMMAND_HANDLER(vdebug_set_polling) +{ + if (CMD_ARGC != 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + vdc.poll_min = atoi(CMD_ARGV[0]); + vdc.poll_max = atoi(CMD_ARGV[1]); + LOG_DEBUG("polling: set min %u max %u", vdc.poll_min, vdc.poll_max); + + return ERROR_OK; +} + +static const struct command_registration vdebug_command_handlers[] = { + { + .name = "server", + .handler = &vdebug_set_server, + .mode = COMMAND_CONFIG, + .help = "set the vdebug server name or address", + .usage = "<host:port>", + }, + { + .name = "bfm_path", + .handler = &vdebug_set_bfm, + .mode = COMMAND_CONFIG, + .help = "set the vdebug BFM hierarchical path", + .usage = "<path> <clk_period[p|n|u]s>", + }, + { + .name = "mem_path", + .handler = &vdebug_set_mem, + .mode = COMMAND_ANY, + .help = "set the design memory for the code load", + .usage = "<path> <base_address> <size>", + }, + { + .name = "batching", + .handler = &vdebug_set_batching, + .mode = COMMAND_CONFIG, + .help = "set the transaction batching no|wr|rd [0|1|2]", + .usage = "<level>", + }, + { + .name = "polling", + .handler = &vdebug_set_polling, + .mode = COMMAND_CONFIG, + .help = "set the polling pause, executing hardware cycles between min and max", + .usage = "<min cycles> <max cycles>", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration vdebug_command[] = { + { + .name = "vdebug", + .chain = vdebug_command_handlers, + .mode = COMMAND_ANY, + .help = "vdebug command group", + .usage = "", + }, + COMMAND_REGISTRATION_DONE +}; + +static struct jtag_interface vdebug_jtag_ops = { + .supported = DEBUG_CAP_TMS_SEQ, + .execute_queue = vdebug_jtag_execute_queue, +}; + +struct adapter_driver vdebug_adapter_driver = { + .name = "vdebug", + .transports = jtag_only, + .speed = vdebug_jtag_speed, + .khz = vdebug_jtag_khz, + .speed_div = vdebug_jtag_div, + .commands = vdebug_command, + .init = vdebug_init, + .quit = vdebug_quit, + .reset = vdebug_reset, + .jtag_ops = &vdebug_jtag_ops, +}; diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index 63faa9561..ddf70cc24 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -57,6 +57,9 @@ extern struct adapter_driver usb_blaster_adapter_driver; #if BUILD_JTAG_VPI == 1 extern struct adapter_driver jtag_vpi_adapter_driver; #endif +#if BUILD_VDEBUG == 1 +extern struct adapter_driver vdebug_adapter_driver; +#endif #if BUILD_JTAG_DPI == 1 extern struct adapter_driver jtag_dpi_adapter_driver; #endif @@ -168,6 +171,9 @@ struct adapter_driver *adapter_drivers[] = { #if BUILD_JTAG_VPI == 1 &jtag_vpi_adapter_driver, #endif +#if BUILD_VDEBUG == 1 + &vdebug_adapter_driver, +#endif #if BUILD_JTAG_DPI == 1 &jtag_dpi_adapter_driver, #endif diff --git a/tcl/board/vd_a53x2_jtag.cfg b/tcl/board/vd_a53x2_jtag.cfg new file mode 100644 index 000000000..869bc4db0 --- /dev/null +++ b/tcl/board/vd_a53x2_jtag.cfg @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Cadence virtual debug interface +# Arm Cortex A53x2 through JTAG + +source [find interface/vdebug.cfg] + +set _CORES 2 +set _CHIPNAME a53 +set _MEMSTART 0x00000000 +set _MEMSIZE 0x1000000 +set _CPUTAPID 0x5ba00477 + +# vdebug select transport +#transport select jtag + +# JTAG reset config, frequency and reset delay +reset_config trst_and_srst +adapter speed 50000 +adapter srst delay 5 + +# BFM hierarchical path and input clk period +vdebug bfm_path tbench.u_vd_jtag_bfm 10ns + +# DMA Memories to access backdoor (up to 4) +vdebug mem_path tbench.u_memory.mem_array $_MEMSTART $_MEMSIZE + +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +jtag arp_init-reset + +source [find target/vd_aarch64.cfg] diff --git a/tcl/board/vd_m4_jtag.cfg b/tcl/board/vd_m4_jtag.cfg new file mode 100644 index 000000000..ca21476d2 --- /dev/null +++ b/tcl/board/vd_m4_jtag.cfg @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Cadence virtual debug interface +# Arm Cortex m4 through JTAG + +source [find interface/vdebug.cfg] + +set _CHIPNAME m4 +set _MEMSTART 0x00000000 +set _MEMSIZE 0x10000 +set _CPUTAPID 0x4ba00477 + +# vdebug select transport +#transport select jtag + +# JTAG reset config, frequency and reset delay +reset_config trst_and_srst +adapter speed 25000 +adapter srst delay 5 + +# BFM hierarchical path and input clk period +vdebug bfm_path tbench.u_vd_jtag_bfm 20ns + +# DMA Memories to access backdoor (up to 4) +vdebug mem_path tbench.u_mcu.u_sys.u_rom.rom $_MEMSTART $_MEMSIZE + +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +jtag arp_init-reset + +source [find target/vd_cortex_m.cfg] diff --git a/tcl/board/vd_pulpissimo_jtag.cfg b/tcl/board/vd_pulpissimo_jtag.cfg new file mode 100644 index 000000000..69dd9e6db --- /dev/null +++ b/tcl/board/vd_pulpissimo_jtag.cfg @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Cadence virtual debug interface +# RISCV Ibex core with Pulpissimo through JTAG + +source [find interface/vdebug.cfg] + +set _CHIPNAME ibex +set _HARTID 0x20 +set _CPUTAPID 0x249511c3 + +# vdebug select transport +#transport select jtag + +# JTAG reset config, frequency and reset delay +reset_config trst_and_srst +adapter speed 12500 +adapter srst delay 10 + +# BFM hierarchical path and input clk period +vdebug bfm_path tbench.u_vd_jtag_bfm 40ns + +# DMA Memories to access backdoor (up to 4) +vdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\[0\].sram_i.mem_array 0x1c000000 0x8000 +vdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\[1\].sram_i.mem_array 0x1c008000 0x8000 +vdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2\[0\].sram_i.mem_array 0x1c010000 0x80000 + +# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01 +jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x05 -irmask 0x1f -expected-id $_CPUTAPID + +jtag arp_init-reset + +source [find target/vd_riscv.cfg] diff --git a/tcl/board/vd_swerv_jtag.cfg b/tcl/board/vd_swerv_jtag.cfg new file mode 100644 index 000000000..ff6c6835f --- /dev/null +++ b/tcl/board/vd_swerv_jtag.cfg @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Cadence virtual debug interface +# RISCV swerv core with Swerv through JTAG + +source [find interface/vdebug.cfg] + +set _CHIPNAME rv32 +set _HARTID 0x00 +set _CPUTAPID 0x1000008b +set _MEMSTART 0x00000000 +set _MEMSIZE 0x10000 + +# vdebug select transport +#transport select jtag + +# JTAG reset config, frequency and reset delay +reset_config trst_and_srst +adapter speed 50000 +adapter srst delay 5 + +# BFM hierarchical path and input clk period +vdebug bfm_path tbench.u_vd_jtag_bfm 10ns + +# DMA Memories to access backdoor (up to 4) +vdebug mem_path tbench.i_ahb_ic.mem $_MEMSTART $_MEMSIZE + +# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01 +jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID + +jtag arp_init-reset + +source [find target/vd_riscv.cfg] diff --git a/tcl/interface/vdebug.cfg b/tcl/interface/vdebug.cfg new file mode 100644 index 000000000..9cca6aaab --- /dev/null +++ b/tcl/interface/vdebug.cfg @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Cadence virtual debug interface + +if { [info exists VDEBUGHOST] } { + set _VDEBUGHOST $VDEBUGHOST +} else { + set _VDEBUGHOST localhost +} +if { [info exists VDEBUGPORT] } { + set _VDEBUGPORT $VDEBUGPORT +} else { + set _VDEBUGPORT 8192 +} + +adapter driver vdebug +# vdebug server:port +vdebug server $_VDEBUGHOST:$_VDEBUGPORT + +# example config debug level and log +#debug_level 3 +#log_output vd_ocd.log + +# example config listen on all interfaces, disable tcl/telnet server +bindto 0.0.0.0 +#gdb_port 3333 +#telnet_port disabled +tcl_port disabled + +# transaction batching: 0 - no batching, 1 - (default) wr, 2 - rw +vdebug batching 1 + +# Polling values +vdebug polling 100 1000 \ No newline at end of file diff --git a/tcl/target/vd_aarch64.cfg b/tcl/target/vd_aarch64.cfg new file mode 100644 index 000000000..619134aa6 --- /dev/null +++ b/tcl/target/vd_aarch64.cfg @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Cadence virtual debug interface +# Arm v8 64b Cortex A + +if {![info exists _CORES]} { + set _CORES 1 +} +if {![info exists _CHIPNAME]} { + set _CHIPNAME aarch64 +} +set _TARGETNAME $_CHIPNAME.cpu +set _CTINAME $_CHIPNAME.cti + +set DBGBASE {0x80810000 0x80910000} +set CTIBASE {0x80820000 0x80920000} + +dap create $_CHIPNAME.dap -chain-position $_TARGETNAME +$_CHIPNAME.dap apsel 1 + +for { set _core 0 } { $_core < $_CORES } { incr _core } \ +{ + cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 -baseaddr [lindex $CTIBASE $_core] + set _command "target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \ + -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core -coreid $_core" + if { $_core != 0 } { + # non-boot core examination may fail + set _command "$_command -defer-examine" + set _smp_command "$_smp_command $_TARGETNAME.$_core" + } else { + set _smp_command "target smp $_TARGETNAME.$_core" + } + eval $_command +} +eval $_smp_command + +# default target is core 0 +targets $_TARGETNAME.0 diff --git a/tcl/target/vd_cortex_m.cfg b/tcl/target/vd_cortex_m.cfg new file mode 100644 index 000000000..4d7b0df26 --- /dev/null +++ b/tcl/target/vd_cortex_m.cfg @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Cadence virtual debug interface +# ARM Cortex M + +if {![info exists _CHIPNAME]} { + set _CHIPNAME cortex_m +} +set _TARGETNAME $_CHIPNAME.cpu + +dap create $_CHIPNAME.dap -chain-position $_TARGETNAME + +target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap diff --git a/tcl/target/vd_riscv.cfg b/tcl/target/vd_riscv.cfg new file mode 100644 index 000000000..b42b25a3a --- /dev/null +++ b/tcl/target/vd_riscv.cfg @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Cadence virtual debug interface +# RISCV core + +if {![info exists _HARTID]} { + set _HARTID 0x00 +} +if {![info exists _CHIPNAME]} { + set _CHIPNAME riscv +} +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid $_HARTID + +riscv set_reset_timeout_sec 120 +riscv set_command_timeout_sec 120 +# prefer to use sba for system bus access +riscv set_prefer_sba on commit 2a2636f138dc40be3fff06cb7bf1f126d906e0a1 Author: Antonio Borneo <bor...@gm...> Date: Sun Jan 23 00:37:10 2022 +0100 doxygen: fix some function prototype description Change-Id: I49311a643ea73143839d2f6bde976cfd76f8c67f Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6830 Tested-by: jenkins diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index fdf4ae778..5c218742b 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -114,8 +114,6 @@ static int jlink_flush(void); * @param in A pointer to store TDO data to, if NULL the data will be discarded. * @param in_offset A bit offset for TDO data. * @param length Amount of bits to transfer out and in. - * - * @retval This function doesn't return any value. */ static void jlink_clock_data(const uint8_t *out, unsigned out_offset, const uint8_t *tms_out, unsigned tms_offset, diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index 3ae5cac62..20a036a78 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -604,8 +604,6 @@ static int ulink_get_queue_size(struct ulink *device, * Clear the OpenULINK command queue. * * @param device pointer to struct ulink identifying ULINK driver instance. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL */ static void ulink_clear_queue(struct ulink *device) { diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index def594ee3..4ec2f1e31 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -546,7 +546,8 @@ int jtag_srst_asserted(int *srst_asserted); * @param field Pointer to scan field. * @param value Pointer to scan value. * @param mask Pointer to scan mask; may be NULL. - * @returns Nothing, but calls jtag_set_error() on any error. + * + * returns Nothing, but calls jtag_set_error() on any error. */ void jtag_check_value_mask(struct scan_field *field, uint8_t *value, uint8_t *mask); commit 49c40a75292b1f76fa0d4bad91c993d9f7a618cf Author: Tim Newsome <ti...@si...> Date: Thu Dec 16 12:54:35 2021 +0100 target/riscv: revive 'riscv resume_order' This functionality was lost in [1], which was merged as commit 615709d14049 ("Upstream a whole host of RISC-V changes."). Now it works as expected again. Add convenience macro foreach_smp_target_direction(). Link: [1] https://github.com/riscv/riscv-openocd/pull/567 Change-Id: I1545fa6b45b8a07e27c8ff9dcdcfa2fc4f950cd1 Signed-off-by: Tim Newsome <ti...@si...> Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6785 Tested-by: jenkins diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 931f76290..367506dde 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1472,14 +1472,16 @@ int riscv_resume( int result = ERROR_OK; if (target->smp && !single_hart) { struct target_list *tlist; - foreach_smp_target(tlist, target->smp_targets) { + foreach_smp_target_direction(resume_order == RO_NORMAL, + tlist, target->smp_targets) { struct target *t = tlist->target; if (resume_prep(t, current, address, handle_breakpoints, debug_execution) != ERROR_OK) result = ERROR_FAIL; } - foreach_smp_target(tlist, target->smp_targets) { + foreach_smp_target_direction(resume_order == RO_NORMAL, + tlist, target->smp_targets) { struct target *t = tlist->target; riscv_info_t *i = riscv_info(t); if (i->prepped) { @@ -1489,7 +1491,8 @@ int riscv_resume( } } - foreach_smp_target(tlist, target->smp_targets) { + foreach_smp_target_direction(resume_order == RO_NORMAL, + tlist, target->smp_targets) { struct target *t = tlist->target; if (resume_finish(t) != ERROR_OK) return ERROR_FAIL; diff --git a/src/target/smp.h b/src/target/smp.h index 46fc55f75..490a49310 100644 --- a/src/target/smp.h +++ b/src/target/smp.h @@ -25,6 +25,9 @@ #define foreach_smp_target(pos, head) \ list_for_each_entry(pos, head, lh) +#define foreach_smp_target_direction(forward, pos, head) \ + list_for_each_entry_direction(forward, pos, head, lh) + extern const struct command_registration smp_command_handlers[]; int gdb_read_smp_packet(struct connection *connection, commit a11fe473eaee235a51dba7900c08cc7629ed2794 Author: Antonio Borneo <bor...@gm...> Date: Thu Dec 16 11:25:32 2021 +0100 helper/list: add list_for_each_entry_direction() Use a bool flag to specify if the list should be forward or backward iterated. Change-Id: Ied19d049f46cdcb7f50137d459cc7c02014526bc S... [truncated message content] |
From: OpenOCD-Gerrit <ope...@us...> - 2022-02-05 21:41:09
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 5ab74bde06541ce199390ead348a3e107ee9c0f4 (commit) from dbbac5f11d662ab0827a997aa5d173fd62c51708 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5ab74bde06541ce199390ead348a3e107ee9c0f4 Author: Zoltán Dudás <ze...@gm...> Date: Wed Nov 24 17:13:50 2021 +0100 semihosting: User defined operation, Tcl command exec on host Enabling a portion (0x100 - 0x107) of the user defined semihosting operation number range (0x100 - 0x1FF) to be processed with the help of the existing target event mechanism, to implement a general-purpose Tcl interface for the target available on the host, via semihosting interface. Example usage: - The user configures a Tcl command as a callback for one of the newly defined events (semihosting-user-cmd-0x10X) in the configuration file. - The target can make a semihosting call with <opnum>, passing optional parameters for the call. If there is no callback registered to the user defined operation number, nothing happens. Example usage: Configure RTT automatically with the exact, linked control block location from target. Signed-off-by: Zoltán Dudás <ze...@gm...> Change-Id: I10e1784b1fecd4e630d78df81cb44bf1aa2fc247 Reviewed-on: https://review.openocd.org/c/openocd/+/6748 Tested-by: jenkins Reviewed-by: Oleksij Rempel <li...@re...> Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/doc/openocd.texi b/doc/openocd.texi index ed92eb4ec..e2c495473 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5185,6 +5185,22 @@ when reset disables PLLs needed to use a fast clock. @* After single-step has completed @item @b{trace-config} @* After target hardware trace configuration was changed +@item @b{semihosting-user-cmd-0x100} +@* The target made a semihosting call with user-defined operation number 0x100 +@item @b{semihosting-user-cmd-0x101} +@* The target made a semihosting call with user-defined operation number 0x101 +@item @b{semihosting-user-cmd-0x102} +@* The target made a semihosting call with user-defined operation number 0x102 +@item @b{semihosting-user-cmd-0x103} +@* The target made a semihosting call with user-defined operation number 0x103 +@item @b{semihosting-user-cmd-0x104} +@* The target made a semihosting call with user-defined operation number 0x104 +@item @b{semihosting-user-cmd-0x105} +@* The target made a semihosting call with user-defined operation number 0x105 +@item @b{semihosting-user-cmd-0x106} +@* The target made a semihosting call with user-defined operation number 0x106 +@item @b{semihosting-user-cmd-0x107} +@* The target made a semihosting call with user-defined operation number 0x107 @end itemize @quotation Note @@ -9241,6 +9257,17 @@ To make the SEMIHOSTING_SYS_EXIT call return normally, enable this option (default: disabled). @end deffn +@deffn {Command} {arm semihosting_read_user_param} +@cindex ARM semihosting +Read parameter of the semihosting call from the target. Usable in +semihosting-user-cmd-0x10* event handlers, returning a string. + +When the target makes semihosting call with operation number from range 0x100- +0x107, an optional string parameter can be passed to the server. This parameter +is valid during the run of the event handlers and is accessible with this +command. +@end deffn + @section ARMv4 and ARMv5 Architecture @cindex ARMv4 @cindex ARMv5 diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c index 792474acf..507d1cd2c 100644 --- a/src/target/arm_semihosting.c +++ b/src/target/arm_semihosting.c @@ -367,10 +367,13 @@ int arm_semihosting(struct target *target, int *retval) } /* Check for ARM operation numbers. */ - if (semihosting->op >= 0 && semihosting->op <= 0x31) { + if ((semihosting->op >= 0 && semihosting->op <= 0x31) || + (semihosting->op >= 0x100 && semihosting->op <= 0x107)) { + *retval = semihosting_common(target); if (*retval != ERROR_OK) { - LOG_ERROR("Failed semihosting operation (0x%02X)", semihosting->op); + LOG_ERROR("Failed semihosting operation (0x%02X)", + semihosting->op); return 0; } } else { diff --git a/src/target/riscv/riscv_semihosting.c b/src/target/riscv/riscv_semihosting.c index b347212d3..1dd8e7791 100644 --- a/src/target/riscv/riscv_semihosting.c +++ b/src/target/riscv/riscv_semihosting.c @@ -140,7 +140,9 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval) semihosting->word_size_bytes = riscv_xlen(target) / 8; /* Check for ARM operation numbers. */ - if (semihosting->op >= 0 && semihosting->op <= 0x31) { + if ((semihosting->op >= 0 && semihosting->op <= 0x31) || + (semihosting->op >= 0x100 && semihosting->op <= 0x107)) { + *retval = semihosting_common(target); if (*retval != ERROR_OK) { LOG_ERROR("Failed semihosting operation (0x%02X)", semihosting->op); diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 8d3f66ca5..9e60de572 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -154,6 +154,12 @@ int semihosting_common_init(struct target *target, void *setup, return ERROR_OK; } +/** + * User operation parameter string storage buffer. Contains valid data when the + * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running. + */ +static char *semihosting_user_op_params; + /** * Portable implementation of ARM semihosting calls. * Performs the currently pending semihosting operation @@ -183,7 +189,7 @@ int semihosting_common(struct target *target) /* Enough space to hold 4 long words. */ uint8_t fields[4*8]; - LOG_DEBUG("op=0x%x, param=0x%" PRIx64, (int)semihosting->op, + LOG_DEBUG("op=0x%x, param=0x%" PRIx64, semihosting->op, semihosting->param); switch (semihosting->op) { @@ -1278,6 +1284,71 @@ int semihosting_common(struct target *target) } break; + case SEMIHOSTING_USER_CMD_0x100 ... SEMIHOSTING_USER_CMD_0x107: + /** + * This is a user defined operation (while user cmds 0x100-0x1ff + * are possible, only 0x100-0x107 are currently implemented). + * + * Reads the user operation parameters from target, then fires the + * corresponding target event. When the target callbacks returned, + * cleans up the command parameter buffer. + * + * Entry + * On entry, the PARAMETER REGISTER contains a pointer to a + * two-field data block: + * - field 1 Contains a pointer to the bound command parameter + * string + * - field 2 Contains the command parameter string length + * + * Return + * On exit, the RETURN REGISTER contains the return status. + */ + { + assert(!semihosting_user_op_params); + + retval = semihosting_read_fields(target, 2, fields); + if (retval != ERROR_OK) { + LOG_ERROR("Failed to read fields for user defined command" + " op=0x%x", semihosting->op); + return retval; + } + + uint64_t addr = semihosting_get_field(target, 0, fields); + + size_t len = semihosting_get_field(target, 1, fields); + if (len > SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH) { + LOG_ERROR("The maximum length for user defined command " + "parameter is %u, received length is %zu (op=0x%x)", + SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH, + len, + semihosting->op); + return ERROR_FAIL; + } + + semihosting_user_op_params = malloc(len + 1); + if (!semihosting_user_op_params) + return ERROR_FAIL; + semihosting_user_op_params[len] = 0; + + retval = target_read_buffer(target, addr, len, + (uint8_t *)(semihosting_user_op_params)); + if (retval != ERROR_OK) { + LOG_ERROR("Failed to read from target, semihosting op=0x%x", + semihosting->op); + free(semihosting_user_op_params); + semihosting_user_op_params = NULL; + return retval; + } + + target_handle_event(target, semihosting->op); + free(semihosting_user_op_params); + semihosting_user_op_params = NULL; + + semihosting->result = 0; + break; + } + + case SEMIHOSTING_SYS_ELAPSED: /* 0x30 */ /* * Returns the number of elapsed target ticks since execution @@ -1624,6 +1695,30 @@ COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command) return ERROR_OK; } +COMMAND_HANDLER(handle_common_semihosting_read_user_param_command) +{ + struct target *target = get_current_target(CMD_CTX); + struct semihosting *semihosting = target->semihosting; + + if (CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (!semihosting->is_active) { + LOG_ERROR("semihosting not yet enabled for current target"); + return ERROR_FAIL; + } + + if (!semihosting_user_op_params) { + LOG_ERROR("This command is usable only from a registered user " + "semihosting event callback."); + return ERROR_FAIL; + } + + command_print_sameline(CMD, "%s", semihosting_user_op_params); + + return ERROR_OK; +} + const struct command_registration semihosting_common_handlers[] = { { "semihosting", @@ -1653,5 +1748,12 @@ const struct command_registration semihosting_common_handlers[] = { .usage = "['enable'|'disable']", .help = "activate support for semihosting resumable exit", }, + { + "semihosting_read_user_param", + .handler = handle_common_semihosting_read_user_param_command, + .mode = COMMAND_EXEC, + .usage = "", + .help = "read parameters in semihosting-user-cmd-0x10X callbacks", + }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h index b83464ed5..6eb9ca252 100644 --- a/src/target/semihosting_common.h +++ b/src/target/semihosting_common.h @@ -75,8 +75,14 @@ enum semihosting_operation_numbers { SEMIHOSTING_SYS_WRITE = 0x05, SEMIHOSTING_SYS_WRITEC = 0x03, SEMIHOSTING_SYS_WRITE0 = 0x04, + SEMIHOSTING_USER_CMD_0x100 = 0x100, /* First user cmd op code */ + SEMIHOSTING_USER_CMD_0x107 = 0x107, /* Last supported user cmd op code */ + SEMIHOSTING_USER_CMD_0x1FF = 0x1FF, /* Last user cmd op code */ }; +/** Maximum allowed Tcl command segment length in bytes*/ +#define SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH (1024 * 1024) + /* * Codes used by SEMIHOSTING_SYS_EXIT (formerly * SEMIHOSTING_REPORT_EXCEPTION). diff --git a/src/target/target.c b/src/target/target.c index 7cdd8d830..acfbd3df5 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -236,6 +236,15 @@ static const struct jim_nvp nvp_target_event[] = { { .value = TARGET_EVENT_TRACE_CONFIG, .name = "trace-config" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x100, .name = "semihosting-user-cmd-0x100" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x101, .name = "semihosting-user-cmd-0x101" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x102, .name = "semihosting-user-cmd-0x102" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x103, .name = "semihosting-user-cmd-0x103" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x104, .name = "semihosting-user-cmd-0x104" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x105, .name = "semihosting-user-cmd-0x105" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x106, .name = "semihosting-user-cmd-0x106" }, + { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x107, .name = "semihosting-user-cmd-0x107" }, + { .name = NULL, .value = -1 } }; diff --git a/src/target/target.h b/src/target/target.h index 6ef8f10e0..974630f17 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -294,6 +294,15 @@ enum target_event { TARGET_EVENT_GDB_FLASH_WRITE_END, TARGET_EVENT_TRACE_CONFIG, + + TARGET_EVENT_SEMIHOSTING_USER_CMD_0x100 = 0x100, /* semihosting allows user cmds from 0x100 to 0x1ff */ + TARGET_EVENT_SEMIHOSTING_USER_CMD_0x101 = 0x101, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0x102 = 0x102, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0x103 = 0x103, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0x104 = 0x104, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0x105 = 0x105, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0x106 = 0x106, + TARGET_EVENT_SEMIHOSTING_USER_CMD_0x107 = 0x107, }; struct target_event_action { ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 27 +++++++++ src/target/arm_semihosting.c | 7 ++- src/target/riscv/riscv_semihosting.c | 4 +- src/target/semihosting_common.c | 104 ++++++++++++++++++++++++++++++++++- src/target/semihosting_common.h | 6 ++ src/target/target.c | 9 +++ src/target/target.h | 9 +++ 7 files changed, 162 insertions(+), 4 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-29 18:25:48
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via dbbac5f11d662ab0827a997aa5d173fd62c51708 (commit) from 6541233aa78d40200092920ec4a72e3917ae3b6d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dbbac5f11d662ab0827a997aa5d173fd62c51708 Author: Pavel Kirienko <pav...@gm...> Date: Sun Jan 9 23:18:13 2022 +0200 semihosting: use open mode flags from GDB, not from sys/stat.h Values defined in sys/stat.h are not guaranteed to match the constants defined by the GDB remote protocol, which are defined in https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags. On my local system (Manjaro 21.2.1 x86_64), for example, O_TRUNC is defined as 0x40, whereas GDB requires it to be 0x400, causing all "w" file open modes to misbehave. This patch has been tested with STM32F446. Change-Id: Ifb2c740fd689e71d6f1a4bde1edaecd76fdca910 Signed-off-by: Pavel Kirienko <pav...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6804 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 1b65e126c..8d3f66ca5 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -52,19 +52,35 @@ #include <helper/log.h> #include <sys/stat.h> +/** + * It is not possible to use O_... flags defined in sys/stat.h because they + * are not guaranteed to match the values defined by the GDB Remote Protocol. + * See https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags + */ +enum { + TARGET_O_RDONLY = 0x000, + TARGET_O_WRONLY = 0x001, + TARGET_O_RDWR = 0x002, + TARGET_O_APPEND = 0x008, + TARGET_O_CREAT = 0x200, + TARGET_O_TRUNC = 0x400, + /* O_EXCL=0x800 is not required in this implementation. */ +}; + +/* GDB remote protocol does not differentiate between text and binary open modes. */ static const int open_modeflags[12] = { - O_RDONLY, - O_RDONLY | O_BINARY, - O_RDWR, - O_RDWR | O_BINARY, - O_WRONLY | O_CREAT | O_TRUNC, - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, - O_RDWR | O_CREAT | O_TRUNC, - O_RDWR | O_CREAT | O_TRUNC | O_BINARY, - O_WRONLY | O_CREAT | O_APPEND, - O_WRONLY | O_CREAT | O_APPEND | O_BINARY, - O_RDWR | O_CREAT | O_APPEND, - O_RDWR | O_CREAT | O_APPEND | O_BINARY + TARGET_O_RDONLY, + TARGET_O_RDONLY, + TARGET_O_RDWR, + TARGET_O_RDWR, + TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC, + TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC, + TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_TRUNC, + TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_TRUNC, + TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND, + TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND, + TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_APPEND, + TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_APPEND }; static int semihosting_common_fileio_info(struct target *target, ----------------------------------------------------------------------- Summary of changes: src/target/semihosting_common.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-29 18:25:30
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 6541233aa78d40200092920ec4a72e3917ae3b6d (commit) from 93f2276cdd99ad9e9d844150553621ea5d8524dd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6541233aa78d40200092920ec4a72e3917ae3b6d Author: Tim Newsome <ti...@si...> Date: Thu Jul 8 17:43:00 2021 -0700 Combine register lists of smp targets. This is helpful when you want to pretend to gdb that your heterogeneous multicore system is homogeneous, because gdb cannot handle heterogeneous systems. This won't always works, but works fine if e.g. one of the cores has an FPU while the other does not. (Specifically, HiFive Unleashed has 1 core with no FPU, plus 4 cores with an FPU.) Signed-off-by: Tim Newsome <ti...@si...> Change-Id: I05ff4c28646778fbc00327bc510be064bfe6c9f0 Reviewed-on: https://review.openocd.org/c/openocd/+/6362 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 7c853730f..b6f4a8264 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -2259,6 +2259,108 @@ static int get_reg_features_list(struct target *target, char const **feature_lis return ERROR_OK; } +/* Create a register list that's the union of all the registers of the SMP + * group this target is in. If the target is not part of an SMP group, this + * returns the same as target_get_gdb_reg_list_noread(). + */ +static int smp_reg_list_noread(struct target *target, + struct reg **combined_list[], int *combined_list_size, + enum target_register_class reg_class) +{ + if (!target->smp) + return target_get_gdb_reg_list_noread(target, combined_list, + combined_list_size, REG_CLASS_ALL); + + unsigned int combined_allocated = 256; + *combined_list = malloc(combined_allocated * sizeof(struct reg *)); + if (*combined_list == NULL) { + LOG_ERROR("malloc(%zu) failed", combined_allocated * sizeof(struct reg *)); + return ERROR_FAIL; + } + *combined_list_size = 0; + + struct target_list *head; + foreach_smp_target(head, target->head) { + struct reg **reg_list = NULL; + int reg_list_size; + int result = target_get_gdb_reg_list_noread(head->target, ®_list, + ®_list_size, reg_class); + if (result != ERROR_OK) { + free(*combined_list); + return result; + } + for (int i = 0; i < reg_list_size; i++) { + bool found = false; + struct reg *a = reg_list[i]; + if (a->exist) { + /* Nested loop makes this O(n^2), but this entire function with + * 5 RISC-V targets takes just 2ms on my computer. Fast enough + * for me. */ + for (int j = 0; j < *combined_list_size; j++) { + struct reg *b = (*combined_list)[j]; + if (!strcmp(a->name, b->name)) { + found = true; + if (a->size != b->size) { + LOG_ERROR("SMP register %s is %d bits on one " + "target, but %d bits on another target.", + a->name, a->size, b->size); + free(reg_list); + free(*combined_list); + return ERROR_FAIL; + } + break; + } + } + if (!found) { + LOG_DEBUG("[%s] %s not found in combined list", target_name(target), a->name); + if (*combined_list_size >= (int) combined_allocated) { + combined_allocated *= 2; + *combined_list = realloc(*combined_list, combined_allocated * sizeof(struct reg *)); + if (*combined_list == NULL) { + LOG_ERROR("realloc(%zu) failed", combined_allocated * sizeof(struct reg *)); + return ERROR_FAIL; + } + } + (*combined_list)[*combined_list_size] = a; + (*combined_list_size)++; + } + } + } + free(reg_list); + } + + /* Now warn the user about any registers that weren't found in every target. */ + foreach_smp_target(head, target->head) { + struct reg **reg_list = NULL; + int reg_list_size; + int result = target_get_gdb_reg_list_noread(head->target, ®_list, + ®_list_size, reg_class); + if (result != ERROR_OK) { + free(*combined_list); + return result; + } + for (int i = 0; i < *combined_list_size; i++) { + bool found = false; + struct reg *a = (*combined_list)[i]; + for (int j = 0; j < reg_list_size; j++) { + struct reg *b = reg_list[j]; + if (b->exist && !strcmp(a->name, b->name)) { + found = true; + break; + } + } + if (!found) { + LOG_WARNING("Register %s does not exist in %s, which is part of an SMP group where " + "this register does exist.", + a->name, target_name(head->target)); + } + } + free(reg_list); + } + + return ERROR_OK; +} + static int gdb_generate_target_description(struct target *target, char **tdesc_out) { int retval = ERROR_OK; @@ -2272,8 +2374,8 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o int size = 0; - retval = target_get_gdb_reg_list_noread(target, ®_list, - ®_list_size, REG_CLASS_ALL); + retval = smp_reg_list_noread(target, ®_list, ®_list_size, + REG_CLASS_ALL); if (retval != ERROR_OK) { LOG_ERROR("get register list failed"); ----------------------------------------------------------------------- Summary of changes: src/server/gdb_server.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-29 18:22:53
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 93f2276cdd99ad9e9d844150553621ea5d8524dd (commit) from 5e0cc43838b898a125d7028ee1ec3c033c3b24c1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 93f2276cdd99ad9e9d844150553621ea5d8524dd Author: Julien Massot <jul...@io...h> Date: Wed Jan 12 09:41:13 2022 +0100 aarch64: support for aarch32 ARM_MODE_UND Fix: unrecognized psr mode: 0x1b cannot read system control register in this mode: (UNRECOGNIZED : 0x1b) Change-Id: I4dc3e72f90d57e52c0fe63cb59a7529a398757b3 Signed-off-by: Julien Massot <jul...@io...h> Change-Id: Ifa5d21ae97492fde9e8c79ee7d99d8a2a871b1b5 Reviewed-on: https://review.openocd.org/c/openocd/+/6808 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 30ef54792..d11fd943b 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -102,6 +102,7 @@ static int aarch64_restore_system_control_reg(struct target *target) case ARM_MODE_FIQ: case ARM_MODE_IRQ: case ARM_MODE_HYP: + case ARM_MODE_UND: case ARM_MODE_SYS: instr = ARMV4_5_MCR(15, 0, 0, 1, 0, 0); break; @@ -180,6 +181,7 @@ static int aarch64_mmu_modify(struct target *target, int enable) case ARM_MODE_FIQ: case ARM_MODE_IRQ: case ARM_MODE_HYP: + case ARM_MODE_UND: case ARM_MODE_SYS: instr = ARMV4_5_MCR(15, 0, 0, 1, 0, 0); break; @@ -1049,6 +1051,7 @@ static int aarch64_post_debug_entry(struct target *target) case ARM_MODE_FIQ: case ARM_MODE_IRQ: case ARM_MODE_HYP: + case ARM_MODE_UND: case ARM_MODE_SYS: instr = ARMV4_5_MRC(15, 0, 0, 1, 0, 0); break; diff --git a/src/target/armv8.c b/src/target/armv8.c index 26116bb33..2de115712 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -77,6 +77,10 @@ static const struct { .name = "HYP", .psr = ARM_MODE_HYP, }, + { + .name = "UND", + .psr = ARM_MODE_UND, + }, { .name = "SYS", .psr = ARM_MODE_SYS, ----------------------------------------------------------------------- Summary of changes: src/target/aarch64.c | 3 +++ src/target/armv8.c | 4 ++++ 2 files changed, 7 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-29 18:20:35
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 5e0cc43838b898a125d7028ee1ec3c033c3b24c1 (commit) from efb0b116dac19f511003a28e4cec9723693b9c2b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5e0cc43838b898a125d7028ee1ec3c033c3b24c1 Author: Hans-Erik Floryd <han...@rt...> Date: Fri Jan 21 12:13:12 2022 +0100 tcl/board: Add EVB-LAN9255 config Config for EVB-LAN9255, tested using Atmel-ICE debugger on J10 connector. Signed-off-by: Hans-Erik Floryd <han...@rt...> Change-Id: I8bcf779e9363499a98aa0b7d10819c53da6a19e7 Reviewed-on: https://review.openocd.org/c/openocd/+/6812 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/tcl/board/evb-lan9255.cfg b/tcl/board/evb-lan9255.cfg new file mode 100644 index 000000000..3fd6f603b --- /dev/null +++ b/tcl/board/evb-lan9255.cfg @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Microchip LAN9255 evaluation board +# https://www.microchip.com/en-us/development-tool/EV25Y25A +# + +set CHIPNAME same53 + +source [find target/atsame5x.cfg] + +reset_config srst_only ----------------------------------------------------------------------- Summary of changes: tcl/board/evb-lan9255.cfg | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tcl/board/evb-lan9255.cfg hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-29 18:20:05
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via efb0b116dac19f511003a28e4cec9723693b9c2b (commit) from 666ff828b2024235694e4a0b47bf360b6ce6bcd7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit efb0b116dac19f511003a28e4cec9723693b9c2b Author: Hans-Erik Floryd <han...@rt...> Date: Fri Jan 21 12:07:56 2022 +0100 flash/nor/atsame5: add LAN9255 devices Support Microchip LAN9255 devices with embedded SAME53J MCU. Signed-off-by: Hans-Erik Floryd <han...@rt...> Change-Id: Ia811c593bf7cf73e588d32873c68eb67c6fafad7 Reviewed-on: https://review.openocd.org/c/openocd/+/6811 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Tomas Vanek <va...@fb...> diff --git a/src/flash/nor/atsame5.c b/src/flash/nor/atsame5.c index 9ab0e8113..fbf0fb2ed 100644 --- a/src/flash/nor/atsame5.c +++ b/src/flash/nor/atsame5.c @@ -146,6 +146,9 @@ static const struct samd_part same53_parts[] = { { 0x04, "SAME53J20A", 1024, 256 }, { 0x05, "SAME53J19A", 512, 192 }, { 0x06, "SAME53J18A", 256, 128 }, + { 0x55, "LAN9255/ZMX020", 1024, 256 }, + { 0x56, "LAN9255/ZMX019", 512, 192 }, + { 0x57, "LAN9255/ZMX018", 256, 128 }, }; /* Known SAME54 parts. */ ----------------------------------------------------------------------- Summary of changes: src/flash/nor/atsame5.c | 3 +++ 1 file changed, 3 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-22 10:20:42
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 666ff828b2024235694e4a0b47bf360b6ce6bcd7 (commit) from e3bda57982ed87bd4d5faace5ea669848f3fe556 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 666ff828b2024235694e4a0b47bf360b6ce6bcd7 Author: Adrien Grassein <adr...@gm...> Date: Thu Jan 6 19:06:47 2022 +0100 jtag: Add an option to ignore the bypass bit Some CPU wrongly indicate the bypas bit in the codeid. It's the case of the NanoXplore NG-ULTRA chip that export a configurable (and potentially invalid) ID for one of its component. Add an option to ignore it. Signed-off-by: Adrien Grassein <adr...@gm...> Change-Id: Ic59743f23bfc4d4e23da0e8535fec8ca9e87ff1a Reviewed-on: https://review.openocd.org/c/openocd/+/6802 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Oleksij Rempel <li...@re...> diff --git a/doc/openocd.texi b/doc/openocd.texi index cee54ebf7..ed92eb4ec 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4153,6 +4153,10 @@ option. When vendors put out multiple versions of a chip, or use the same JTAG-level ID for several largely-compatible chips, it may be more practical to ignore the version field than to update config files to handle all of the various chip IDs. The version field is defined as bit 28-31 of the IDCODE. +@item @code{-ignore-bypass} +@*Specify this to ignore the 'bypass' bit of the idcode. Some vendor put +an invalid idcode regarding this bit. Specify this to ignore this bit and +to not consider this tap in bypass mode. @item @code{-ircapture} @var{NUMBER} @*The bit pattern loaded by the TAP into the JTAG shift register on entry to the @sc{ircapture} state, such as 0x01. diff --git a/src/jtag/core.c b/src/jtag/core.c index 29ab6cc1c..bbc9877ee 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1273,7 +1273,7 @@ static int jtag_examine_chain(void) jtag_tap_init(tap); } - if ((idcode & 1) == 0) { + if ((idcode & 1) == 0 && !tap->ignore_bypass) { /* Zero for LSB indicates a device in bypass */ LOG_INFO("TAP %s does not have valid IDCODE (idcode=0x%" PRIx32 ")", tap->dotted_name, idcode); diff --git a/src/jtag/hla/hla_tcl.c b/src/jtag/hla/hla_tcl.c index 5aa330145..6b206d231 100644 --- a/src/jtag/hla/hla_tcl.c +++ b/src/jtag/hla/hla_tcl.c @@ -59,6 +59,7 @@ static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi #define NTAP_OPT_DISABLED 4 #define NTAP_OPT_EXPECTED_ID 5 #define NTAP_OPT_VERSION 6 +#define NTAP_OPT_BYPASS 7 static int jim_hl_newtap_cmd(struct jim_getopt_info *goi) { @@ -75,6 +76,7 @@ static int jim_hl_newtap_cmd(struct jim_getopt_info *goi) { .name = "-disable", .value = NTAP_OPT_DISABLED }, { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID }, { .name = "-ignore-version", .value = NTAP_OPT_VERSION }, + { .name = "-ignore-bypass", .value = NTAP_OPT_BYPASS }, { .name = NULL, .value = -1}, }; diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index d7d7d977c..def594ee3 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -135,6 +135,9 @@ struct jtag_tap { /** Flag saying whether to ignore version field in expected_ids[] */ bool ignore_version; + /** Flag saying whether to ignore the bypass bit in the code */ + bool ignore_bypass; + /** current instruction */ uint8_t *cur_instr; /** Bypass register selected */ diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 566c406b9..e6e976d77 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -470,6 +470,7 @@ static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi #define NTAP_OPT_DISABLED 4 #define NTAP_OPT_EXPECTED_ID 5 #define NTAP_OPT_VERSION 6 +#define NTAP_OPT_BYPASS 7 static int jim_newtap_ir_param(struct jim_nvp *n, struct jim_getopt_info *goi, struct jtag_tap *tap) @@ -532,6 +533,7 @@ static int jim_newtap_cmd(struct jim_getopt_info *goi) { .name = "-disable", .value = NTAP_OPT_DISABLED }, { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID }, { .name = "-ignore-version", .value = NTAP_OPT_VERSION }, + { .name = "-ignore-bypass", .value = NTAP_OPT_BYPASS }, { .name = NULL, .value = -1 }, }; @@ -617,6 +619,9 @@ static int jim_newtap_cmd(struct jim_getopt_info *goi) case NTAP_OPT_VERSION: tap->ignore_version = true; break; + case NTAP_OPT_BYPASS: + tap->ignore_bypass = true; + break; } /* switch (n->value) */ } /* while (goi->argc) */ @@ -887,6 +892,7 @@ static const struct command_registration jtag_subcommand_handlers[] = { "['-enable'|'-disable'] " "['-expected_id' number] " "['-ignore-version'] " + "['-ignore-bypass'] " "['-ircapture' number] " "['-mask' number]", }, ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 4 ++++ src/jtag/core.c | 2 +- src/jtag/hla/hla_tcl.c | 2 ++ src/jtag/jtag.h | 3 +++ src/jtag/tcl.c | 6 ++++++ 5 files changed, 16 insertions(+), 1 deletion(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-22 10:20:19
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via e3bda57982ed87bd4d5faace5ea669848f3fe556 (commit) from 492ac453ab6b97280030fe6161dfcac3d84b36ce (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e3bda57982ed87bd4d5faace5ea669848f3fe556 Author: Antonio Borneo <bor...@gm...> Date: Thu Dec 23 11:05:56 2021 +0100 target: use target_event_name() We have the API target_event_name(). Use it to improve code readability. Change-Id: Ic48d2227bdefe9af05aff99a871a45e0612e5254 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6790 Tested-by: jenkins diff --git a/src/target/target.c b/src/target/target.c index e9cbe39b7..7cdd8d830 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1834,7 +1834,7 @@ int target_call_event_callbacks(struct target *target, enum target_event event) } LOG_DEBUG("target event %i (%s) for core %s", event, - jim_nvp_value2name_simple(nvp_target_event, event)->name, + target_event_name(event), target_name(target)); target_handle_event(target, event); @@ -4816,7 +4816,7 @@ void target_handle_event(struct target *target, enum target_event e) target_name(target), target_type_name(target), e, - jim_nvp_value2name_simple(nvp_target_event, e)->name, + target_event_name(e), Jim_GetString(teap->body, NULL)); /* Override current target by the target an event @@ -4840,7 +4840,7 @@ void target_handle_event(struct target *target, enum target_event e) if (retval != JIM_OK) { Jim_MakeErrorMessage(teap->interp); LOG_USER("Error executing event %s on target %s:\n%s", - jim_nvp_value2name_simple(nvp_target_event, e)->name, + target_event_name(e), target_name(target), Jim_GetString(Jim_GetResult(teap->interp), NULL)); /* clean both error code and stacktrace before return */ @@ -5503,9 +5503,9 @@ COMMAND_HANDLER(handle_target_event_list) command_print(CMD, "------------------------- | " "----------------------------------------"); while (teap) { - struct jim_nvp *opt = jim_nvp_value2name_simple(nvp_target_event, teap->event); command_print(CMD, "%-25s | %s", - opt->name, Jim_GetString(teap->body, NULL)); + target_event_name(teap->event), + Jim_GetString(teap->body, NULL)); teap = teap->next; } command_print(CMD, "***END***"); ----------------------------------------------------------------------- Summary of changes: src/target/target.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-22 10:18:54
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 492ac453ab6b97280030fe6161dfcac3d84b36ce (commit) from 1536e249f2c23399f3443f8351647ea3faa5112e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 492ac453ab6b97280030fe6161dfcac3d84b36ce Author: Antonio Borneo <bor...@gm...> Date: Fri Dec 24 15:15:18 2021 +0100 log: fix memory leak when log to file is enabled When log to file is enabled, the file is not closed by OpenOCD at exit. This is reported by Valgrind as a memory leak that is still reachable, as the internal buffers of 'FILE *log_output' are freed by the automatic fclose() at exit. Close the log file before exit. Change-Id: Id472c0d04462035254a9b49ecb0a4037263c6f6f Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6789 Tested-by: jenkins diff --git a/src/helper/log.c b/src/helper/log.c index caa0a66bf..686560742 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -302,6 +302,15 @@ void log_init(void) start = last_time = timeval_ms(); } +void log_exit(void) +{ + if (log_output && log_output != stderr) { + /* Close log file, if it was open and wasn't stderr. */ + fclose(log_output); + } + log_output = NULL; +} + int set_log_output(struct command_context *cmd_ctx, FILE *output) { log_output = output; diff --git a/src/helper/log.h b/src/helper/log.h index 621d467b4..f0378ae79 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -72,6 +72,7 @@ __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6))); * Initialize logging module. Call during program startup. */ void log_init(void); +void log_exit(void); int set_log_output(struct command_context *cmd_ctx, FILE *output); int log_register_commands(struct command_context *cmd_ctx); diff --git a/src/openocd.c b/src/openocd.c index 0292ba445..3c96d3214 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -437,6 +437,8 @@ int openocd_main(int argc, char *argv[]) rtt_exit(); free_config(); + log_exit(); + if (ret == ERROR_FAIL) return EXIT_FAILURE; else if (ret != ERROR_OK) ----------------------------------------------------------------------- Summary of changes: src/helper/log.c | 9 +++++++++ src/helper/log.h | 1 + src/openocd.c | 2 ++ 3 files changed, 12 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-22 10:15:38
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 1536e249f2c23399f3443f8351647ea3faa5112e (commit) from 5a8d32fcb92f179445da6d3f7b0ceeec4efbcc6f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1536e249f2c23399f3443f8351647ea3faa5112e Author: Antonio Borneo <bor...@gm...> Date: Sun Nov 14 22:36:46 2021 +0100 aarch64: dump a message when CTI is missing If the CTI is not specified OpenOCD fails target's examination without indicating the reason. Drop an error message about the missing CTI. Change-Id: I344537fb21cf38785796ba938e71890e04135509 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6788 Tested-by: jenkins diff --git a/src/target/aarch64.c b/src/target/aarch64.c index fc6bd6b30..30ef54792 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2635,8 +2635,10 @@ static int aarch64_examine_first(struct target *target) LOG_DEBUG("ttypr = 0x%08" PRIx64, ttypr); LOG_DEBUG("debug = 0x%08" PRIx64, debug); - if (!pc->cti) + if (!pc->cti) { + LOG_TARGET_ERROR(target, "CTI not specified"); return ERROR_FAIL; + } armv8->cti = pc->cti; ----------------------------------------------------------------------- Summary of changes: src/target/aarch64.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-22 10:14:56
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 5a8d32fcb92f179445da6d3f7b0ceeec4efbcc6f (commit) from aad87180586a43500f8af1cf79255c7293bb258b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5a8d32fcb92f179445da6d3f7b0ceeec4efbcc6f Author: Antonio Borneo <bor...@gm...> Date: Wed Jan 12 17:59:12 2022 +0100 doc: use the new jimtcl syntax for 'expr' With jimtcl 0.81 the syntax of the TCL command 'expr' requires the multiple arguments to be within curly brackets. Update the examples in the documentation to follow the new syntax. While there, split one example to avoid it to exceed the line size during pdf document generation. Change-Id: I91cca419f8273415ccb0c2ce369fc6ac476e34e5 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6809 Tested-by: jenkins diff --git a/doc/manual/primer/tcl.txt b/doc/manual/primer/tcl.txt index 868a75ba0..eba2f552d 100644 --- a/doc/manual/primer/tcl.txt +++ b/doc/manual/primer/tcl.txt @@ -174,7 +174,7 @@ them. It is similar to this bash statement. EXPORT vn=`date` LINE 2 & 3 - set $vn [expr (1024 * $x)] + set $vn [expr {1024 * $x}] global $vn In line 1, we dynamically created a variable name. Here, we are diff --git a/doc/openocd.texi b/doc/openocd.texi index 4d5a844af..cee54ebf7 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2009,9 +2009,9 @@ proc setc15 @{regs value@} @{ echo [format "set p15 0x%04x, 0x%08x" $regs $value] - arm mcr 15 [expr ($regs>>12)&0x7] \ - [expr ($regs>>0)&0xf] [expr ($regs>>4)&0xf] \ - [expr ($regs>>8)&0x7] $value + arm mcr 15 [expr @{($regs >> 12) & 0x7@}] \ + [expr @{($regs >> 0) & 0xf@}] [expr @{($regs >> 4) & 0xf@}] \ + [expr @{($regs >> 8) & 0x7@}] $value @} @end example @@ -3157,7 +3157,9 @@ the target's supply voltage. The result can be converted to Volts (ignoring the most significant bytes, always zero) @example > set a [st-link cmd 8 0xf7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] -> echo [expr 2*1.2*([lindex $a 4]+256*[lindex $a 5])/([lindex $a 0]+256*[lindex $a 1])] +> set n [expr @{[lindex $a 4] + 256 * [lindex $a 5]@}] +> set d [expr @{[lindex $a 0] + 256 * [lindex $a 1]@}] +> echo [expr @{2 * 1.2 * $n / $d@}] 3.24891518738 @end example @end deffn @@ -4523,13 +4525,13 @@ where the mask bit is 1. The following example sets HPROT3 (cacheable) and leaves the rest of the pattern intact. It configures memory access through DCache on Cortex-M7. @example -set CSW_HPROT3_CACHEABLE [expr 1 << 27] +set CSW_HPROT3_CACHEABLE [expr @{1 << 27@}] samv.dap apcsw $CSW_HPROT3_CACHEABLE $CSW_HPROT3_CACHEABLE @end example Another example clears SPROT bit and leaves the rest of pattern intact: @example -set CSW_SPROT [expr 1 << 30] +set CSW_SPROT [expr @{1 << 30@}] samv.dap apcsw 0 $CSW_SPROT @end example @@ -8620,7 +8622,7 @@ In addition the following arguments may be specified: proc load_image_bin @{fname foffset address length @} @{ # Load data from fname filename at foffset offset to # target at address. Load at most length bytes. - load_image $fname [expr $address - $foffset] bin \ + load_image $fname [expr @{$address - $foffset@}] bin \ $address $length @} @end example @@ -10402,7 +10404,7 @@ trivial challenge-response protocol could be implemented as follows in a configuration file, immediately following @command{init}: @example set challenge [riscv authdata_read] -riscv authdata_write [expr $challenge + 1] +riscv authdata_write [expr @{$challenge + 1@}] @end example @deffn {Command} {riscv authdata_read} @@ -12111,7 +12113,7 @@ it reads a file and executes as a script. @example set x 6 set y 7 - puts [format "The answer: %d" [expr $x * $y]] + puts [format "The answer: %d" [expr @{$x * $y@}]] @end example @enumerate @item The SET command creates 2 variables, X and Y. @@ -12182,13 +12184,13 @@ proc myproc @{ @} @{ @b{Dynamic variable creation} @example # Dynamically create a bunch of variables. -for @{ set x 0 @} @{ $x < 32 @} @{ set x [expr $x + 1]@} @{ +for @{ set x 0 @} @{ $x < 32 @} @{ set x [expr @{$x + 1@}]@} @{ # Create var name set vn [format "BIT%d" $x] # Make it a global global $vn # Set it. - set $vn [expr (1 << $x)] + set $vn [expr @{1 << $x@}] @} @end example @b{Dynamic proc/command creation} ----------------------------------------------------------------------- Summary of changes: doc/manual/primer/tcl.txt | 2 +- doc/openocd.texi | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2022-01-05 17:59:03
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via aad87180586a43500f8af1cf79255c7293bb258b (commit) from d27d66bc1bdbef0cbfe43d88597576e173317c01 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aad87180586a43500f8af1cf79255c7293bb258b Author: Doug Brunner <dou...@gm...> Date: Mon Oct 25 10:15:07 2021 -0700 flash/nor/efr32: fixed lockbits and user data Changed flash driver to support writing to the user data page, as well as to any portion of the lockbits page above 512 bytes (the amount used for the actual page lock words). The top part of the lockbits page is used on at least the EFR32xG1 chips for the SiLabs bootloader encryption keys. As presented to the user, the lockbits page is the same size as the other pages, but any attempt to write to its low 512 bytes is an error. To enforce this, efr32x_write is renamed to efm32x_priv_write and a wrapper function is provided in its place. If the user erases the lockbits page, the driver rewrites the cached lock words after the erase. When the driver erases the lockbits page in order to update the lock words, it first takes a copy of anything stored in the top part of the page, and re-programs it after the erase operation. There are now multiple instances of flash_bank for each target, and the flash_bank instances must share their cached lock words to operate as intended. Therefore, when a bank is created, the global flash bank list is used to find any other banks that share the same target. Since some banks in the global list are invalid at the time free_driver_priv is called, reference counting is used to decide when to free driver_priv. To avoid the need to find the lockbits flash_bank from another flash_bank, efm32x_priv_write and efm32x_erase_page now take an absolute address. There didn't seem to be any reason to prohibit unprotecting individual flash pages, so that limitation is removed from efm32x_protect(). This addresses ticket #185. Valgrind-clean, except for 2x 4kiB not freed/still reachable blocks that were allocated by libudev. No new Clang analyzer warnings, no new sanitizer warnings. Signed-off-by: Doug Brunner <dou...@gm...> Change-Id: Ifb22e6149939d893f386706e99b928691ec1d41b Reviewed-on: https://review.openocd.org/c/openocd/+/6665 Tested-by: jenkins Reviewed-by: Fredrik Hederstierna <fre...@gm...> Reviewed-by: Tomas Vanek <va...@fb...> diff --git a/doc/openocd.texi b/doc/openocd.texi index 8e5058538..4d5a844af 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6351,13 +6351,22 @@ flash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME @end deffn @deffn {Flash Driver} {efm32} -All members of the EFM32 microcontroller family from Energy Micro include -internal flash and use ARM Cortex-M3 cores. The driver automatically recognizes -a number of these chips using the chip identification register, and +All members of the EFM32/EFR32 microcontroller family from Energy Micro (now Silicon Labs) +include internal flash and use Arm Cortex-M3 or Cortex-M4 cores. The driver automatically +recognizes a number of these chips using the chip identification register, and autoconfigures itself. @example flash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME @end example +It supports writing to the user data page, as well as the portion of the lockbits page +past 512 bytes on chips with larger page sizes. The latter is used by the SiLabs +bootloader/AppLoader system for encryption keys. Setting protection on these pages is +currently not supported. +@example +flash bank userdata.flash efm32 0x0FE00000 0 0 0 $_TARGETNAME +flash bank lockbits.flash efm32 0x0FE04000 0 0 0 $_TARGETNAME +@end example + A special feature of efm32 controllers is that it is possible to completely disable the debug interface by writing the correct values to the 'Debug Lock Word'. OpenOCD supports this via the following command: diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c index fb4b09624..653878ae7 100644 --- a/src/flash/nor/efm32.c +++ b/src/flash/nor/efm32.c @@ -14,6 +14,9 @@ * Copyright (C) 2014 Nemui Trinomius * * nem...@li... * * * + * Copyright (C) 2021 Doug Brunner * + * dou...@gm... * + * * * 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 * @@ -45,13 +48,16 @@ #define EFM32_FLASH_WDATAREADY_TMO 100 #define EFM32_FLASH_WRITE_TMO 100 +#define EFM32_FLASH_BASE 0 + /* size in bytes, not words; must fit all Gecko devices */ -#define LOCKBITS_PAGE_SZ 512 +#define LOCKWORDS_SZ 512 #define EFM32_MSC_INFO_BASE 0x0fe00000 #define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE #define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000) +#define EFM32_MSC_LOCK_BITS_EXTRA (EFM32_MSC_LOCK_BITS+LOCKWORDS_SZ) #define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000) /* PAGE_SIZE is not present in Zero, Happy and the original Gecko MCU */ @@ -83,6 +89,27 @@ #define EFM32_MSC_REG_LOCK_SERIES1 0x040 #define EFM32_MSC_LOCK_LOCKKEY 0x1b71 +enum efm32_bank_index { + EFM32_BANK_INDEX_MAIN, + EFM32_BANK_INDEX_USER_DATA, + EFM32_BANK_INDEX_LOCK_BITS, + EFM32_N_BANKS +}; + +static int efm32x_get_bank_index(target_addr_t base) +{ + switch (base) { + case EFM32_FLASH_BASE: + return EFM32_BANK_INDEX_MAIN; + case EFM32_MSC_USER_DATA: + return EFM32_BANK_INDEX_USER_DATA; + case EFM32_MSC_LOCK_BITS: + return EFM32_BANK_INDEX_LOCK_BITS; + default: + return ERROR_FAIL; + } +} + struct efm32_family_data { int family_id; const char *name; @@ -98,13 +125,6 @@ struct efm32_family_data { uint32_t msc_regbase; }; -struct efm32x_flash_bank { - bool probed; - uint32_t lb_page[LOCKBITS_PAGE_SZ/4]; - uint32_t reg_base; - uint32_t reg_lock; -}; - struct efm32_info { const struct efm32_family_data *family_data; uint16_t flash_sz_kib; @@ -115,6 +135,15 @@ struct efm32_info { uint16_t page_size; }; +struct efm32x_flash_chip { + struct efm32_info info; + bool probed[EFM32_N_BANKS]; + uint32_t lb_page[LOCKWORDS_SZ/4]; + uint32_t reg_base; + uint32_t reg_lock; + uint32_t refcount; +}; + static const struct efm32_family_data efm32_families[] = { { 16, "EFR32MG1P Mighty", .series = 1 }, { 17, "EFR32MG1B Mighty", .series = 1 }, @@ -175,9 +204,12 @@ static const struct efm32_family_data efm32_families[] = { { 122, "EZR32HG Happy", .series = 0, .page_size = 1024 }, }; +const struct flash_driver efm32_flash; -static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count); +static int efm32x_priv_write(struct flash_bank *bank, const uint8_t *buffer, + uint32_t addr, uint32_t count); + +static int efm32x_write_only_lockbits(struct flash_bank *bank); static int efm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_sz) { @@ -207,7 +239,7 @@ static int efm32x_get_prod_rev(struct flash_bank *bank, uint8_t *prev) static int efm32x_read_reg_u32(struct flash_bank *bank, target_addr_t offset, uint32_t *value) { - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; uint32_t base = efm32x_info->reg_base; return target_read_u32(bank->target, base + offset, value); @@ -216,18 +248,18 @@ static int efm32x_read_reg_u32(struct flash_bank *bank, target_addr_t offset, static int efm32x_write_reg_u32(struct flash_bank *bank, target_addr_t offset, uint32_t value) { - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; uint32_t base = efm32x_info->reg_base; return target_write_u32(bank->target, base + offset, value); } -static int efm32x_read_info(struct flash_bank *bank, - struct efm32_info *efm32_info) +static int efm32x_read_info(struct flash_bank *bank) { int ret; uint32_t cpuid = 0; - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; + struct efm32_info *efm32_info = &(efm32x_info->info); memset(efm32_info, 0, sizeof(struct efm32_info)); @@ -327,20 +359,61 @@ static int efm32x_read_info(struct flash_bank *bank, /* flash bank efm32 <base> <size> 0 0 <target#> */ FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command) { - struct efm32x_flash_bank *efm32x_info; + struct efm32x_flash_chip *efm32x_info = NULL; if (CMD_ARGC < 6) return ERROR_COMMAND_SYNTAX_ERROR; - efm32x_info = malloc(sizeof(struct efm32x_flash_bank)); + int bank_index = efm32x_get_bank_index(bank->base); + if (bank_index < 0) { + LOG_ERROR("Flash bank with base address %" PRIx32 " is not supported", + (uint32_t) bank->base); + return ERROR_FAIL; + } + /* look for an existing flash structure matching target */ + for (struct flash_bank *bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) { + if (bank_iter->driver == &efm32_flash + && bank_iter->target == bank->target + && bank->driver_priv) { + efm32x_info = bank->driver_priv; + break; + } + } + + if (!efm32x_info) { + /* target not matched, make a new one */ + efm32x_info = calloc(1, sizeof(struct efm32x_flash_chip)); + + memset(efm32x_info->lb_page, 0xff, LOCKWORDS_SZ); + } + + ++efm32x_info->refcount; bank->driver_priv = efm32x_info; - efm32x_info->probed = false; - memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ); return ERROR_OK; } +/** + * Remove flash structure corresponding to this bank, + * if and only if it's not used by any others + */ +static void efm32x_free_driver_priv(struct flash_bank *bank) +{ + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; + + if (efm32x_info) { + /* Use ref count to determine if it can be freed; scanning bank list doesn't work, + * because this function can be called after some banks in the list have been + * already destroyed */ + --efm32x_info->refcount; + if (efm32x_info->refcount == 0) { + free(efm32x_info); + bank->driver_priv = NULL; + } + } +} + /* set or reset given bits in a register */ static int efm32x_set_reg_bits(struct flash_bank *bank, uint32_t reg, uint32_t bitmask, int set) @@ -368,7 +441,7 @@ static int efm32x_set_wren(struct flash_bank *bank, int write_enable) static int efm32x_msc_lock(struct flash_bank *bank, int lock) { - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; return efm32x_write_reg_u32(bank, efm32x_info->reg_lock, (lock ? 0 : EFM32_MSC_LOCK_LOCKKEY)); } @@ -416,7 +489,6 @@ static int efm32x_erase_page(struct flash_bank *bank, uint32_t addr) */ int ret = 0; uint32_t status = 0; - addr += bank->base; LOG_DEBUG("erasing flash page at 0x%08" PRIx32, addr); ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_ADDRB, addr); @@ -470,20 +542,28 @@ static int efm32x_erase(struct flash_bank *bank, unsigned int first, } for (unsigned int i = first; i <= last; i++) { - ret = efm32x_erase_page(bank, bank->sectors[i].offset); + ret = efm32x_erase_page(bank, bank->base + bank->sectors[i].offset); if (ret != ERROR_OK) LOG_ERROR("Failed to erase page %d", i); } ret = efm32x_set_wren(bank, 0); efm32x_msc_lock(bank, 1); + if (ret != ERROR_OK) + return ret; + + if (bank->base == EFM32_MSC_LOCK_BITS) { + ret = efm32x_write_only_lockbits(bank); + if (ret != ERROR_OK) + LOG_ERROR("Failed to restore lockbits after erase"); + } return ret; } static int efm32x_read_lock_data(struct flash_bank *bank) { - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; struct target *target = bank->target; int data_size = 0; uint32_t *ptr = NULL; @@ -557,35 +637,84 @@ static int efm32x_read_lock_data(struct flash_bank *bank) return ERROR_OK; } +static int efm32x_write_only_lockbits(struct flash_bank *bank) +{ + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; + return efm32x_priv_write(bank, (uint8_t *)efm32x_info->lb_page, EFM32_MSC_LOCK_BITS, LOCKWORDS_SZ); +} + static int efm32x_write_lock_data(struct flash_bank *bank) { - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; int ret = 0; + /* Preserve any data written to the high portion of the lockbits page */ + assert(efm32x_info->info.page_size >= LOCKWORDS_SZ); + uint32_t extra_bytes = efm32x_info->info.page_size - LOCKWORDS_SZ; + uint8_t *extra_data = NULL; + if (extra_bytes) { + extra_data = malloc(extra_bytes); + ret = target_read_buffer(bank->target, EFM32_MSC_LOCK_BITS_EXTRA, extra_bytes, extra_data); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to read extra contents of LB page"); + free(extra_data); + return ret; + } + } + ret = efm32x_erase_page(bank, EFM32_MSC_LOCK_BITS); if (ret != ERROR_OK) { LOG_ERROR("Failed to erase LB page"); + if (extra_data) + free(extra_data); return ret; } - return efm32x_write(bank, (uint8_t *)efm32x_info->lb_page, EFM32_MSC_LOCK_BITS, - LOCKBITS_PAGE_SZ); + if (extra_data) { + ret = efm32x_priv_write(bank, extra_data, EFM32_MSC_LOCK_BITS_EXTRA, extra_bytes); + free(extra_data); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to restore extra contents of LB page"); + return ret; + } + } + + return efm32x_write_only_lockbits(bank); } static int efm32x_get_page_lock(struct flash_bank *bank, size_t page) { - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; - uint32_t dw = efm32x_info->lb_page[page >> 5]; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; + uint32_t dw = 0; uint32_t mask = 0; - mask = 1 << (page & 0x1f); + switch (bank->base) { + case EFM32_FLASH_BASE: + dw = efm32x_info->lb_page[page >> 5]; + mask = 1 << (page & 0x1f); + break; + case EFM32_MSC_USER_DATA: + dw = efm32x_info->lb_page[126]; + mask = 0x1; + break; + case EFM32_MSC_LOCK_BITS: + dw = efm32x_info->lb_page[126]; + mask = 0x2; + break; + } return (dw & mask) ? 0 : 1; } static int efm32x_set_page_lock(struct flash_bank *bank, size_t page, int set) { - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; + + if (bank->base != EFM32_FLASH_BASE) { + LOG_ERROR("Locking user and lockbits pages is not supported yet"); + return ERROR_FAIL; + } + uint32_t *dw = &efm32x_info->lb_page[page >> 5]; uint32_t mask = 0; @@ -605,11 +734,6 @@ static int efm32x_protect(struct flash_bank *bank, int set, unsigned int first, struct target *target = bank->target; int ret = 0; - if (!set) { - LOG_ERROR("Erase device data to reset page locks"); - return ERROR_FAIL; - } - if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; @@ -633,16 +757,15 @@ static int efm32x_protect(struct flash_bank *bank, int set, unsigned int first, } static int efm32x_write_block(struct flash_bank *bank, const uint8_t *buf, - uint32_t offset, uint32_t count) + uint32_t address, uint32_t count) { struct target *target = bank->target; uint32_t buffer_size = 16384; struct working_area *write_algorithm; struct working_area *source; - uint32_t address = bank->base + offset; struct reg_param reg_params[5]; struct armv7m_algorithm armv7m_info; - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; int ret = ERROR_OK; /* see contrib/loaders/flash/efm32.S for src */ @@ -864,8 +987,8 @@ static int efm32x_write_word(struct flash_bank *bank, uint32_t addr, return ERROR_OK; } -static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) +static int efm32x_priv_write(struct flash_bank *bank, const uint8_t *buffer, + uint32_t addr, uint32_t count) { struct target *target = bank->target; uint8_t *new_buffer = NULL; @@ -875,9 +998,9 @@ static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer, return ERROR_TARGET_NOT_HALTED; } - if (offset & 0x3) { - LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-byte " - "alignment", offset); + if (addr & 0x3) { + LOG_ERROR("addr 0x%" PRIx32 " breaks required 4-byte " + "alignment", addr); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } @@ -906,7 +1029,7 @@ static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer, goto cleanup; /* try using a block write */ - retval = efm32x_write_block(bank, buffer, offset, words_remaining); + retval = efm32x_write_block(bank, buffer, addr, words_remaining); if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { /* if block write failed (no sufficient working area), @@ -918,13 +1041,13 @@ static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t value; memcpy(&value, buffer, sizeof(uint32_t)); - retval = efm32x_write_word(bank, offset, value); + retval = efm32x_write_word(bank, addr, value); if (retval != ERROR_OK) goto reset_pg_and_lock; words_remaining--; buffer += 4; - offset += 4; + addr += 4; } } @@ -939,63 +1062,77 @@ cleanup: return retval; } +static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + if (bank->base == EFM32_MSC_LOCK_BITS && offset < LOCKWORDS_SZ) { + LOG_ERROR("Cannot write to lock words"); + return ERROR_FAIL; + } + return efm32x_priv_write(bank, buffer, bank->base + offset, count); +} + static int efm32x_probe(struct flash_bank *bank) { - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; - struct efm32_info efm32_mcu_info; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; + struct efm32_info *efm32_mcu_info = &(efm32x_info->info); int ret; - uint32_t base_address = 0x00000000; - efm32x_info->probed = false; - memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ); + int bank_index = efm32x_get_bank_index(bank->base); + assert(bank_index >= 0); - ret = efm32x_read_info(bank, &efm32_mcu_info); + efm32x_info->probed[bank_index] = false; + memset(efm32x_info->lb_page, 0xff, LOCKWORDS_SZ); + + ret = efm32x_read_info(bank); if (ret != ERROR_OK) return ret; LOG_INFO("detected part: %s Gecko, rev %d", - efm32_mcu_info.family_data->name, efm32_mcu_info.prod_rev); - LOG_INFO("flash size = %dkbytes", efm32_mcu_info.flash_sz_kib); - LOG_INFO("flash page size = %dbytes", efm32_mcu_info.page_size); - - assert(efm32_mcu_info.page_size != 0); - - int num_pages = efm32_mcu_info.flash_sz_kib * 1024 / - efm32_mcu_info.page_size; + efm32_mcu_info->family_data->name, efm32_mcu_info->prod_rev); + LOG_INFO("flash size = %dkbytes", efm32_mcu_info->flash_sz_kib); + LOG_INFO("flash page size = %dbytes", efm32_mcu_info->page_size); - assert(num_pages > 0); + assert(efm32_mcu_info->page_size != 0); free(bank->sectors); bank->sectors = NULL; - bank->base = base_address; - bank->size = (num_pages * efm32_mcu_info.page_size); - bank->num_sectors = num_pages; - - ret = efm32x_read_lock_data(bank); - if (ret != ERROR_OK) { - LOG_ERROR("Failed to read LB data"); - return ret; - } - - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); + if (bank->base == EFM32_FLASH_BASE) { + bank->num_sectors = efm32_mcu_info->flash_sz_kib * 1024 / + efm32_mcu_info->page_size; + assert(bank->num_sectors > 0); - for (int i = 0; i < num_pages; i++) { - bank->sectors[i].offset = i * efm32_mcu_info.page_size; - bank->sectors[i].size = efm32_mcu_info.page_size; + ret = efm32x_read_lock_data(bank); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to read LB data"); + return ret; + } + } else + bank->num_sectors = 1; + bank->size = bank->num_sectors * efm32_mcu_info->page_size; + bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + + for (uint32_t i = 0; i < bank->num_sectors; i++) { + bank->sectors[i].offset = i * efm32_mcu_info->page_size; + bank->sectors[i].size = efm32_mcu_info->page_size; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } - efm32x_info->probed = true; + efm32x_info->probed[bank_index] = true; return ERROR_OK; } static int efm32x_auto_probe(struct flash_bank *bank) { - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; - if (efm32x_info->probed) + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; + + int bank_index = efm32x_get_bank_index(bank->base); + assert(bank_index >= 0); + + if (efm32x_info->probed[bank_index]) return ERROR_OK; return efm32x_probe(bank); } @@ -1026,16 +1163,17 @@ static int efm32x_protect_check(struct flash_bank *bank) static int get_efm32x_info(struct flash_bank *bank, struct command_invocation *cmd) { - struct efm32_info info; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; int ret; - ret = efm32x_read_info(bank, &info); + ret = efm32x_read_info(bank); if (ret != ERROR_OK) { LOG_ERROR("Failed to read EFM32 info"); return ret; } - command_print_sameline(cmd, "%s Gecko, rev %d", info.family_data->name, info.prod_rev); + command_print_sameline(cmd, "%s Gecko, rev %d", efm32x_info->info.family_data->name, + efm32x_info->info.prod_rev); return ERROR_OK; } @@ -1051,7 +1189,7 @@ COMMAND_HANDLER(efm32x_handle_debuglock_command) if (retval != ERROR_OK) return retval; - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; + struct efm32x_flash_chip *efm32x_info = bank->driver_priv; target = bank->target; @@ -1110,5 +1248,5 @@ const struct flash_driver efm32_flash = { .erase_check = default_flash_blank_check, .protect_check = efm32x_protect_check, .info = get_efm32x_info, - .free_driver_priv = default_flash_free_driver_priv, + .free_driver_priv = efm32x_free_driver_priv, }; diff --git a/tcl/target/efm32.cfg b/tcl/target/efm32.cfg index c789efc72..d2e4eb329 100644 --- a/tcl/target/efm32.cfg +++ b/tcl/target/efm32.cfg @@ -43,6 +43,8 @@ $_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME +flash bank userdata.flash efm32 0x0FE00000 0 0 0 $_TARGETNAME +flash bank lockbits.flash efm32 0x0FE04000 0 0 0 $_TARGETNAME if {![using_hla]} { # if srst is not fitted use SYSRESETREQ to ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 15 ++- src/flash/nor/efm32.c | 304 ++++++++++++++++++++++++++++++++++++-------------- tcl/target/efm32.cfg | 2 + 3 files changed, 235 insertions(+), 86 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-24 15:13:42
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via d27d66bc1bdbef0cbfe43d88597576e173317c01 (commit) from 0cbb0c3ccc0143ab8f4154cad2d9d78cc6f86ea8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d27d66bc1bdbef0cbfe43d88597576e173317c01 Author: Tim Newsome <ti...@si...> Date: Mon Jan 25 11:27:23 2021 -0800 Document how vector registers are exposed to gdb. See https://github.com/riscv/riscv-openocd/pull/570 Change-Id: Ie7cdef3717e107a9df0b48316cfbc547dea9a7fd Signed-off-by: Tim Newsome <ti...@si...> Reviewed-on: https://review.openocd.org/c/openocd/+/6776 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/doc/openocd.texi b/doc/openocd.texi index 61d398738..8e5058538 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -10212,6 +10212,43 @@ A @emph{hart} is a hardware thread. A hart may share resources (eg. FPU) with another hart, or may be a separate core. RISC-V treats those the same, and OpenOCD exposes each hart as a separate core. +@subsection Vector Registers + +For harts that implement the vector extension, OpenOCD provides access to the +relevant CSRs, as well as the vector registers (v0-v31). The size of each +vector register is dependent on the value of vlenb. RISC-V allows each vector +register to be divided into selected-width elements, and this division can be +changed at run-time. Because OpenOCD cannot update register definitions at +run-time, it exposes each vector register to gdb as a union of fields of +vectors so that users can easily access individual bytes, shorts, words, +longs, and quads inside each vector register. It is left to gdb or +higher-level debuggers to present this data in a more intuitive format. + +In the XML register description, the vector registers (when vlenb=16) look as +follows: + +@example +<feature name="org.gnu.gdb.riscv.vector"> +<vector id="bytes" type="uint8" count="16"/> +<vector id="shorts" type="uint16" count="8"/> +<vector id="words" type="uint32" count="4"/> +<vector id="longs" type="uint64" count="2"/> +<vector id="quads" type="uint128" count="1"/> +<union id="riscv_vector"> +<field name="b" type="bytes"/> +<field name="s" type="shorts"/> +<field name="w" type="words"/> +<field name="l" type="longs"/> +<field name="q" type="quads"/> +</union> +<reg name="v0" bitsize="128" regnum="4162" save-restore="no" + type="riscv_vector" group="vector"/> +... +<reg name="v31" bitsize="128" regnum="4193" save-restore="no" + type="riscv_vector" group="vector"/> +</feature> +@end example + @subsection RISC-V Debug Configuration Commands @deffn {Config Command} {riscv expose_csrs} n[-m|=name] [...] ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-24 15:13:03
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 0cbb0c3ccc0143ab8f4154cad2d9d78cc6f86ea8 (commit) from 3ba21e5f007a81b42be194a663cb6f15f150b245 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0cbb0c3ccc0143ab8f4154cad2d9d78cc6f86ea8 Author: Marc Schink <de...@za...> Date: Thu Dec 16 10:12:42 2021 +0100 contrib/udev: Add missing J-Link USB PID See libjaylink/contrib/99-libjaylink.rules Change-Id: I36733e18eb4bc11828c5fa563c687d28be9e34bd Signed-off-by: Marc Schink <de...@za...> Reviewed-on: https://review.openocd.org/c/openocd/+/6778 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/contrib/60-openocd.rules b/contrib/60-openocd.rules index 4ecb485b1..34defada0 100644 --- a/contrib/60-openocd.rules +++ b/contrib/60-openocd.rules @@ -154,7 +154,9 @@ ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1015", MODE="660", GROUP="plugdev", ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1016", MODE="660", GROUP="plugdev", TAG+="uaccess" ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1017", MODE="660", GROUP="plugdev", TAG+="uaccess" ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1018", MODE="660", GROUP="plugdev", TAG+="uaccess" +ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1020", MODE="660", GROUP="plugdev", TAG+="uaccess" ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1051", MODE="660", GROUP="plugdev", TAG+="uaccess" +ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1055", MODE="660", GROUP="plugdev", TAG+="uaccess" ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1061", MODE="660", GROUP="plugdev", TAG+="uaccess" # Raisonance RLink ----------------------------------------------------------------------- Summary of changes: contrib/60-openocd.rules | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-24 15:10:46
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 3ba21e5f007a81b42be194a663cb6f15f150b245 (commit) from 9828c0a440364fac11eb80fdea5dfaaaee42ab2d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3ba21e5f007a81b42be194a663cb6f15f150b245 Author: Tim Newsome <ti...@si...> Date: Tue Nov 2 09:55:07 2021 -0700 target/riscv: calloc() memory per register. This replaces a static array with 8 bytes per register. When there are vector registers larger than 8 bytes, they would end up clobbering each other's values. I can't believe I didn't catch this earlier. See https://github.com/riscv/riscv-openocd/pull/658 Change-Id: I9df4eaf05617a2c8df3140fff9fe53f61ab2b261 Signed-off-by: Tim Newsome <ti...@si...> Reviewed-on: https://review.openocd.org/c/openocd/+/6775 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Tomas Vanek <va...@fb...> diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 407b7e279..c9840fe50 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -476,6 +476,8 @@ static void riscv_free_registers(struct target *target) /* Free the ones we allocated separately. */ for (unsigned i = GDB_REGNO_COUNT; i < target->reg_cache->num_regs; i++) free(target->reg_cache->reg_list[i].arch_info); + for (unsigned int i = 0; i < target->reg_cache->num_regs; i++) + free(target->reg_cache->reg_list[i].value); free(target->reg_cache->reg_list); } free(target->reg_cache); @@ -1749,8 +1751,8 @@ static int riscv_get_gdb_reg_list_internal(struct target *target, enum target_register_class reg_class, bool read) { RISCV_INFO(r); - LOG_DEBUG("current_hartid=%d, reg_class=%d, read=%d", - r->current_hartid, reg_class, read); + LOG_DEBUG("[%s] {%d} reg_class=%d, read=%d", + target_name(target), r->current_hartid, reg_class, read); if (!target->reg_cache) { LOG_ERROR("Target not initialized. Return ERROR_FAIL."); @@ -4479,7 +4481,7 @@ int riscv_init_registers(struct target *target) assert(reg_name < info->reg_names + target->reg_cache->num_regs * max_reg_name_len); } - r->value = info->reg_cache_values[number]; + r->value = calloc(1, DIV_ROUND_UP(r->size, 8)); } return ERROR_OK; diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index d0f4f6ec0..0ae8945da 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -96,11 +96,6 @@ typedef struct { * every function than an actual */ int current_hartid; - /* OpenOCD's register cache points into here. This is not per-hart because - * we just invalidate the entire cache when we change which hart is - * selected. Use an array of 8 uint8_t per register. */ - uint8_t reg_cache_values[RISCV_MAX_REGISTERS][8]; - /* Single buffer that contains all register names, instead of calling * malloc for each register. Needs to be freed when reg_list is freed. */ char *reg_names; ----------------------------------------------------------------------- Summary of changes: src/target/riscv/riscv.c | 8 +++++--- src/target/riscv/riscv.h | 5 ----- 2 files changed, 5 insertions(+), 8 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-24 15:08:27
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 9828c0a440364fac11eb80fdea5dfaaaee42ab2d (commit) from 5795f4d3ef938172e3d7a942ed57023572650037 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9828c0a440364fac11eb80fdea5dfaaaee42ab2d Author: Antonio Borneo <bor...@gm...> Date: Fri Dec 17 00:53:11 2021 +0100 semihosting: use macro COMMAND_HANDLER We have the macro #define COMMAND_HANDLER(name) \ static __COMMAND_HANDLER(name) Use it! Change-Id: I0e5385cb54197c743348f0d2ce215c93b8e396a4 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6786 Tested-by: jenkins diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 5c96e1cd6..1b65e126c 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -1474,7 +1474,7 @@ static void semihosting_set_field(struct target *target, uint64_t value, /* ------------------------------------------------------------------------- * Common semihosting commands handlers. */ -static __COMMAND_HANDLER(handle_common_semihosting_command) +COMMAND_HANDLER(handle_common_semihosting_command) { struct target *target = get_current_target(CMD_CTX); @@ -1515,7 +1515,7 @@ static __COMMAND_HANDLER(handle_common_semihosting_command) return ERROR_OK; } -static __COMMAND_HANDLER(handle_common_semihosting_fileio_command) +COMMAND_HANDLER(handle_common_semihosting_fileio_command) { struct target *target = get_current_target(CMD_CTX); @@ -1545,7 +1545,7 @@ static __COMMAND_HANDLER(handle_common_semihosting_fileio_command) return ERROR_OK; } -static __COMMAND_HANDLER(handle_common_semihosting_cmdline) +COMMAND_HANDLER(handle_common_semihosting_cmdline) { struct target *target = get_current_target(CMD_CTX); unsigned int i; @@ -1578,7 +1578,7 @@ static __COMMAND_HANDLER(handle_common_semihosting_cmdline) return ERROR_OK; } -static __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command) +COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command) { struct target *target = get_current_target(CMD_CTX); ----------------------------------------------------------------------- Summary of changes: src/target/semihosting_common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-18 17:27:15
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 5795f4d3ef938172e3d7a942ed57023572650037 (commit) from 29e689ede680f0b3bd106b80b9844c45459265e4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5795f4d3ef938172e3d7a942ed57023572650037 Author: Antonio Borneo <bor...@gm...> Date: Sat Dec 4 18:38:56 2021 +0100 gdb_server: fix a comment in gdb_new_connection() On 2008-03-05, before git's age, commit 6d9501467441 adds a comment about unobserved ACK supposedly sent by GDB at connection. The ACK is sent since GDB 3.95 (1999-05-04), but a bug introduced in GDB 6.5 (2006-06-21) and fixed in GDB 7.0 (2009-10-06) makes GDB sending the query for "supported packets" before sending the ACK. Due to the bug, the author of the commit failed to see the ACK. Change-Id: I574a8013e7d159d1c71087af83b7c2ce92be86bd Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6769 Tested-by: jenkins diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 0d2d1ae2c..7c853730f 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1006,16 +1006,19 @@ static int gdb_new_connection(struct connection *connection) breakpoint_clear_target(target); watchpoint_clear_target(target); - /* remove the initial ACK from the incoming buffer */ + /* Since version 3.95 (gdb-19990504), with the exclusion of 6.5~6.8, GDB + * sends an ACK at connection with the following comment in its source code: + * "Ack any packet which the remote side has already sent." + * LLDB does the same since the first gdb-remote implementation. + * Remove the initial ACK from the incoming buffer. + */ retval = gdb_get_char(connection, &initial_ack); if (retval != ERROR_OK) return retval; - /* FIX!!!??? would we actually ever receive a + here??? - * Not observed. - */ if (initial_ack != '+') gdb_putback_char(connection, initial_ack); + target_call_event_callbacks(target, TARGET_EVENT_GDB_ATTACH); if (target->rtos) { ----------------------------------------------------------------------- Summary of changes: src/server/gdb_server.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-18 17:26:38
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 29e689ede680f0b3bd106b80b9844c45459265e4 (commit) from 33fa237b2ffdfc24b7e0c0861ac7708b21431c8c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 29e689ede680f0b3bd106b80b9844c45459265e4 Author: Antonio Borneo <bor...@gm...> Date: Thu Dec 9 17:55:46 2021 +0100 openocd: add keep_alive during command sleep The command sleep holds the host CPU until it completes. Send keep_alive to GDB, so it will not timeout. Change-Id: I92e9c5fc871b4e6a7695cdc449ca9fb3c1f1d9ec Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6770 Tested-by: jenkins Reviewed-by: Jan Matyas <ma...@co...> diff --git a/src/helper/command.c b/src/helper/command.c index 53ee2508a..1e769d719 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -1145,6 +1145,7 @@ COMMAND_HANDLER(handle_sleep_command) int64_t then = timeval_ms(); while (timeval_ms() - then < (int64_t)duration) { target_call_timer_callbacks_now(); + keep_alive(); usleep(1000); } } else ----------------------------------------------------------------------- Summary of changes: src/helper/command.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-18 17:23:35
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 33fa237b2ffdfc24b7e0c0861ac7708b21431c8c (commit) from 1e07079dee083255eb84fdebdfd4ed4c30e82812 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 33fa237b2ffdfc24b7e0c0861ac7708b21431c8c Author: Tomas Vanek <va...@fb...> Date: Wed Dec 8 22:11:32 2021 +0100 target/cortex_m: minor refactoring in cortex_m_store_core_reg_u32() Unlike cortex_m_load_core_reg_u32() storing core register uses the same code pattern around DHCSR read as offered by the convenience helper cortex_m_read_dhcsr_atomic_sticky(). Use the helper. Change-Id: Ia947204944a8b549f3c2be7fb2f717aad18970c4 SeeAlso: 65d762918328 (cortex_m: poll S_REGRDY on register r/w) SeeAlso: 0dcf95c7171b (target/cortex_m: cumulate DHCSR sticky bits) Signed-off-by: Tomas Vanek <va...@fb...> Reviewed-on: https://review.openocd.org/c/openocd/+/6767 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 5605dd080..7125e9e83 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -397,11 +397,9 @@ static int cortex_m_store_core_reg_u32(struct target *target, /* check if value is written into register */ then = timeval_ms(); while (1) { - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, - &cortex_m->dcb_dhcsr); + retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) return retval; - cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr); if (cortex_m->dcb_dhcsr & S_REGRDY) break; if (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) { ----------------------------------------------------------------------- Summary of changes: src/target/cortex_m.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-18 17:23:15
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 1e07079dee083255eb84fdebdfd4ed4c30e82812 (commit) from fdf17dba569ac8aca0771c28b661e3722d776541 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1e07079dee083255eb84fdebdfd4ed4c30e82812 Author: Tomas Vanek <va...@fb...> Date: Wed Dec 8 17:46:34 2021 +0100 jtag/drivers/vsllink: fix memory leak Close libusb context in vsllink_quit() Change-Id: I85da8d7228b1b2b033a32b2f9ae9ed0726546b55 Signed-off-by: Tomas Vanek <va...@fb...> Reviewed-on: https://review.openocd.org/c/openocd/+/6766 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index f59a7033e..dbbdef4ba 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -273,6 +273,7 @@ static int vsllink_quit(void) vsllink_free_buffer(); vsllink_usb_close(vsllink_handle); + libusb_exit(vsllink_handle->libusb_ctx); free(vsllink_handle); return ERROR_OK; ----------------------------------------------------------------------- Summary of changes: src/jtag/drivers/vsllink.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-11 17:50:11
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via fdf17dba569ac8aca0771c28b661e3722d776541 (commit) from 71ca3a134916c74bb9199d1da0941a77670c914a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fdf17dba569ac8aca0771c28b661e3722d776541 Author: Jaehoon Park <524...@us...> Date: Wed Jun 24 04:39:27 2020 +0900 flash/nor/spi: add micron MT25QU01G 1Gbit SPI flash on VCU118 Rev. 2.0 Contributed to riscv-openocd in https://github.com/riscv/riscv-openocd/pull/487 Signed-off-by: Tim Newsome <ti...@si...> Change-Id: I93447dd970d9901a671567fe8ab9e407432f8db9 Reviewed-on: https://review.openocd.org/c/openocd/+/6764 Reviewed-by: Tomas Vanek <va...@fb...> Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c index 937c194e6..f8d581992 100644 --- a/src/flash/nor/spi.c +++ b/src/flash/nor/spi.c @@ -96,6 +96,7 @@ const struct flash_device flash_devices[] = { FLASH_ID("micron n25q256 1.8v", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0019bb20, 0x100, 0x10000, 0x2000000), FLASH_ID("micron mt25ql512", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0020ba20, 0x100, 0x10000, 0x4000000), FLASH_ID("micron mt25ql01", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0021ba20, 0x100, 0x10000, 0x8000000), + FLASH_ID("micron mt25qu01", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0021bb20, 0x100, 0x10000, 0x8000000), FLASH_ID("micron mt25ql02", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0022ba20, 0x100, 0x10000, 0x10000000), FLASH_ID("win w25q80bv", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001440ef, 0x100, 0x10000, 0x100000), FLASH_ID("win w25q16jv", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001540ef, 0x100, 0x10000, 0x200000), ----------------------------------------------------------------------- Summary of changes: src/flash/nor/spi.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-11 17:49:56
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 71ca3a134916c74bb9199d1da0941a77670c914a (commit) from c892f1055ddd25257457a194a017f3547d547aaa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 71ca3a134916c74bb9199d1da0941a77670c914a Author: Bohdan Tymkiv <boh...@gm...> Date: Thu Dec 2 10:08:33 2021 +0200 target/arm_jtag.h: fix wrong comparison in arm_jtag_set_instr Change [1] introduced a regression that results in comparison in arm_jtag_set_instr() to be always true if the length of the IR register is not 8 bit. The value on the left side of the != operator contains only tap->ir_length number of bits while value on the right is full 8-bit instruction code. This forces OpenOCD to update the JTAG IR register on each transaction even if the instruction in the JTAG IR register is correct. This causes noticeable performance degradation, especially with slow JTAG adapters. [1] https://review.openocd.org/c/openocd/+/6285 time ./src/openocd -s tcl/ -f interface/cmsis-dap.cfg \ -c "transport select jtag" -f target/psoc6.cfg \ -c "init; load_image data.bin 0x08000000; exit" Without this change: real 0m4,863s user 0m0,074s sys 0m0,128s With this change: real 0m3,083s user 0m0,038s sys 0m0,098s Signed-off-by: Bohdan Tymkiv <boh...@gm...> Change-Id: Iaded83a04ecc7e65f18256afae582267ccc1fc59 Reviewed-on: https://review.openocd.org/c/openocd/+/6762 Tested-by: jenkins Reviewed-by: Tomas Vanek <va...@fb...> Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/target/arm_jtag.h b/src/target/arm_jtag.h index bf5b83748..f3e0bc2a3 100644 --- a/src/target/arm_jtag.h +++ b/src/target/arm_jtag.h @@ -23,6 +23,7 @@ #define OPENOCD_TARGET_ARM_JTAG_H #include <jtag/jtag.h> +#include <helper/bits.h> struct arm_jtag { struct jtag_tap *tap; @@ -42,7 +43,7 @@ static inline int arm_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, void *no_verify_capture, tap_state_t end_state) { /* inline most common code path */ - if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) + if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (new_instr & (BIT(tap->ir_length) - 1))) return arm_jtag_set_instr_inner(tap, new_instr, no_verify_capture, end_state); return ERROR_OK; ----------------------------------------------------------------------- Summary of changes: src/target/arm_jtag.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- Main OpenOCD repository |
From: OpenOCD-Gerrit <ope...@us...> - 2021-12-11 17:46:34
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via c892f1055ddd25257457a194a017f3547d547aaa (commit) from d674018432033ba28f43f22b55d9cd84d3268387 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c892f1055ddd25257457a194a017f3547d547aaa Author: Laszlo Sitzer <dls...@gm...> Date: Thu Nov 18 13:10:39 2021 +0100 linuxgpiod: Allow using multiple GPIO chips. Allow passing optional gpiochip number before gpio number. If no optional chip number is passed, the one from the 'gpiochip' configuration directive is used. Change-Id: I16933d81581d9af4d1600c5f9fdbc832ef3fda94 Signed-off-by: Laszlo Sitzer <dls...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6742 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/jtag/drivers/linuxgpiod.c b/src/jtag/drivers/linuxgpiod.c index 75f6152be..9f9f27a9f 100644 --- a/src/jtag/drivers/linuxgpiod.c +++ b/src/jtag/drivers/linuxgpiod.c @@ -29,8 +29,26 @@ static int swclk_gpio = -1; static int swdio_gpio = -1; static int led_gpio = -1; static int gpiochip = -1; +static int tck_gpiochip = -1; +static int tms_gpiochip = -1; +static int tdi_gpiochip = -1; +static int tdo_gpiochip = -1; +static int trst_gpiochip = -1; +static int srst_gpiochip = -1; +static int swclk_gpiochip = -1; +static int swdio_gpiochip = -1; +static int led_gpiochip = -1; + +static struct gpiod_chip *gpiod_chip_tck; +static struct gpiod_chip *gpiod_chip_tms; +static struct gpiod_chip *gpiod_chip_tdi; +static struct gpiod_chip *gpiod_chip_tdo; +static struct gpiod_chip *gpiod_chip_trst; +static struct gpiod_chip *gpiod_chip_srst; +static struct gpiod_chip *gpiod_chip_swclk; +static struct gpiod_chip *gpiod_chip_swdio; +static struct gpiod_chip *gpiod_chip_led; -static struct gpiod_chip *gpiod_chip; static struct gpiod_line *gpiod_tck; static struct gpiod_line *gpiod_tms; static struct gpiod_line *gpiod_tdi; @@ -273,12 +291,31 @@ static int linuxgpiod_quit(void) helper_release(gpiod_tdi); helper_release(gpiod_tdo); - gpiod_chip_close(gpiod_chip); + if (gpiod_chip_led != NULL) + gpiod_chip_close(gpiod_chip_led); + if (gpiod_chip_srst != NULL) + gpiod_chip_close(gpiod_chip_srst); + if (gpiod_chip_swdio != NULL) + gpiod_chip_close(gpiod_chip_swdio); + if (gpiod_chip_swclk != NULL) + gpiod_chip_close(gpiod_chip_swclk); + if (gpiod_chip_trst != NULL) + gpiod_chip_close(gpiod_chip_trst); + if (gpiod_chip_tms != NULL) + gpiod_chip_close(gpiod_chip_tms); + if (gpiod_chip_tck != NULL) + gpiod_chip_close(gpiod_chip_tck); + if (gpiod_chip_tdi != NULL) + gpiod_chip_close(gpiod_chip_tdi); + if (gpiod_chip_tdo != NULL) + gpiod_chip_close(gpiod_chip_tdo); return ERROR_OK; } -static struct gpiod_line *helper_get_line(const char *label, unsigned int offset, int val, int dir, int flags) +static struct gpiod_line *helper_get_line(const char *label, + struct gpiod_chip *gpiod_chip, unsigned int offset, + int val, int dir, int flags) { struct gpiod_line *line; int retval; @@ -304,19 +341,25 @@ static struct gpiod_line *helper_get_line(const char *label, unsigned int offset return line; } -static struct gpiod_line *helper_get_input_line(const char *label, unsigned int offset) +static struct gpiod_line *helper_get_input_line(const char *label, + struct gpiod_chip *gpiod_chip, unsigned int offset) { - return helper_get_line(label, offset, 0, GPIOD_LINE_REQUEST_DIRECTION_INPUT, 0); + return helper_get_line(label, gpiod_chip, offset, 0, + GPIOD_LINE_REQUEST_DIRECTION_INPUT, 0); } -static struct gpiod_line *helper_get_output_line(const char *label, unsigned int offset, int val) +static struct gpiod_line *helper_get_output_line(const char *label, + struct gpiod_chip *gpiod_chip, unsigned int offset, int val) { - return helper_get_line(label, offset, val, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0); + return helper_get_line(label, gpiod_chip, offset, val, + GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0); } -static struct gpiod_line *helper_get_open_drain_output_line(const char *label, unsigned int offset, int val) +static struct gpiod_line *helper_get_open_drain_output_line(const char *label, + struct gpiod_chip *gpiod_chip, unsigned int offset, int val) { - return helper_get_line(label, offset, val, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN); + return helper_get_line(label, gpiod_chip, offset, val, + GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN); } static int linuxgpiod_init(void) @@ -325,12 +368,6 @@ static int linuxgpiod_init(void) bitbang_interface = &linuxgpiod_bitbang; - gpiod_chip = gpiod_chip_open_by_number(gpiochip); - if (!gpiod_chip) { - LOG_ERROR("Cannot open LinuxGPIOD gpiochip %d", gpiochip); - return ERROR_JTAG_INIT_FAILED; - } - /* * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. @@ -343,27 +380,54 @@ static int linuxgpiod_init(void) goto out_error; } - gpiod_tdo = helper_get_input_line("tdo", tdo_gpio); + gpiod_chip_tdo = gpiod_chip_open_by_number(tdo_gpiochip); + if (!gpiod_chip_tdo) { + LOG_ERROR("Cannot open LinuxGPIOD tdo_gpiochip %d", tdo_gpiochip); + goto out_error; + } + gpiod_chip_tdi = gpiod_chip_open_by_number(tdi_gpiochip); + if (!gpiod_chip_tdi) { + LOG_ERROR("Cannot open LinuxGPIOD tdi_gpiochip %d", tdi_gpiochip); + goto out_error; + } + gpiod_chip_tck = gpiod_chip_open_by_number(tck_gpiochip); + if (!gpiod_chip_tck) { + LOG_ERROR("Cannot open LinuxGPIOD tck_gpiochip %d", tck_gpiochip); + goto out_error; + } + gpiod_chip_tms = gpiod_chip_open_by_number(tms_gpiochip); + if (!gpiod_chip_tms) { + LOG_ERROR("Cannot open LinuxGPIOD tms_gpiochip %d", tms_gpiochip); + goto out_error; + } + + gpiod_tdo = helper_get_input_line("tdo", gpiod_chip_tdo, tdo_gpio); if (!gpiod_tdo) goto out_error; - gpiod_tdi = helper_get_output_line("tdi", tdi_gpio, 0); + gpiod_tdi = helper_get_output_line("tdi", gpiod_chip_tdi, tdi_gpio, 0); if (!gpiod_tdi) goto out_error; - gpiod_tck = helper_get_output_line("tck", tck_gpio, 0); + gpiod_tck = helper_get_output_line("tck", gpiod_chip_tck, tck_gpio, 0); if (!gpiod_tck) goto out_error; - gpiod_tms = helper_get_output_line("tms", tms_gpio, 1); + gpiod_tms = helper_get_output_line("tms", gpiod_chip_tms, tms_gpio, 1); if (!gpiod_tms) goto out_error; if (is_gpio_valid(trst_gpio)) { + gpiod_chip_trst = gpiod_chip_open_by_number(trst_gpiochip); + if (!gpiod_chip_trst) { + LOG_ERROR("Cannot open LinuxGPIOD trst_gpiochip %d", trst_gpiochip); + goto out_error; + } + if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN) - gpiod_trst = helper_get_open_drain_output_line("trst", trst_gpio, 1); + gpiod_trst = helper_get_open_drain_output_line("trst", gpiod_chip_trst, trst_gpio, 1); else - gpiod_trst = helper_get_output_line("trst", trst_gpio, 1); + gpiod_trst = helper_get_output_line("trst", gpiod_chip_trst, trst_gpio, 1); if (!gpiod_trst) goto out_error; @@ -376,27 +440,50 @@ static int linuxgpiod_init(void) goto out_error; } - gpiod_swclk = helper_get_output_line("swclk", swclk_gpio, 1); + gpiod_chip_swclk = gpiod_chip_open_by_number(swclk_gpiochip); + if (!gpiod_chip_swclk) { + LOG_ERROR("Cannot open LinuxGPIOD swclk_gpiochip %d", swclk_gpiochip); + goto out_error; + } + gpiod_chip_swdio = gpiod_chip_open_by_number(swdio_gpiochip); + if (!gpiod_chip_swdio) { + LOG_ERROR("Cannot open LinuxGPIOD swdio_gpiochip %d", swdio_gpiochip); + goto out_error; + } + + gpiod_swclk = helper_get_output_line("swclk", gpiod_chip_swclk, swclk_gpio, 1); if (!gpiod_swclk) goto out_error; - gpiod_swdio = helper_get_output_line("swdio", swdio_gpio, 1); + gpiod_swdio = helper_get_output_line("swdio", gpiod_chip_swdio, swdio_gpio, 1); if (!gpiod_swdio) goto out_error; } if (is_gpio_valid(srst_gpio)) { + gpiod_chip_srst = gpiod_chip_open_by_number(srst_gpiochip); + if (!gpiod_chip_srst) { + LOG_ERROR("Cannot open LinuxGPIOD srst_gpiochip %d", srst_gpiochip); + goto out_error; + } + if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL) - gpiod_srst = helper_get_output_line("srst", srst_gpio, 1); + gpiod_srst = helper_get_output_line("srst", gpiod_chip_srst, srst_gpio, 1); else - gpiod_srst = helper_get_open_drain_output_line("srst", srst_gpio, 1); + gpiod_srst = helper_get_open_drain_output_line("srst", gpiod_chip_srst, srst_gpio, 1); if (!gpiod_srst) goto out_error; } if (is_gpio_valid(led_gpio)) { - gpiod_led = helper_get_output_line("led", led_gpio, 0); + gpiod_chip_led = gpiod_chip_open_by_number(led_gpiochip); + if (!gpiod_chip_led) { + LOG_ERROR("Cannot open LinuxGPIOD led_gpiochip %d", led_gpiochip); + goto out_error; + } + + gpiod_led = helper_get_output_line("led", gpiod_chip_led, led_gpio, 0); if (!gpiod_led) goto out_error; } @@ -409,6 +496,21 @@ out_error: return ERROR_JTAG_INIT_FAILED; } +COMMAND_HELPER(linuxgpiod_helper_gpionum, const char *name, int *chip, int *line) +{ + int i = 0; + if (CMD_ARGC > 2) + return ERROR_COMMAND_SYNTAX_ERROR; + if (CMD_ARGC == 2) { + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], *chip); + i = 1; + } + if (CMD_ARGC > 0) + COMMAND_PARSE_NUMBER(int, CMD_ARGV[i], *line); + command_print(CMD, "LinuxGPIOD %s: chip = %d, num = %d", name, *chip, *line); + return ERROR_OK; +} + COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionums) { if (CMD_ARGC == 4) { @@ -429,56 +531,38 @@ COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionums) COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tck) { - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - - command_print(CMD, "LinuxGPIOD num: tck = %d", tck_gpio); - return ERROR_OK; + return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tck", &tck_gpiochip, + &tck_gpio); } COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tms) { - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio); - - command_print(CMD, "LinuxGPIOD num: tms = %d", tms_gpio); - return ERROR_OK; + return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tms", &tms_gpiochip, + &tms_gpio); } COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdo) { - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio); - - command_print(CMD, "LinuxGPIOD num: tdo = %d", tdo_gpio); - return ERROR_OK; + return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdo", &tdo_gpiochip, + &tdo_gpio); } COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdi) { - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio); - - command_print(CMD, "LinuxGPIOD num: tdi = %d", tdi_gpio); - return ERROR_OK; + return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdi", &tdi_gpiochip, + &tdi_gpio); } COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_srst) { - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio); - - command_print(CMD, "LinuxGPIOD num: srst = %d", srst_gpio); - return ERROR_OK; + return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "srst", &srst_gpiochip, + &srst_gpio); } COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_trst) { - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio); - - command_print(CMD, "LinuxGPIOD num: trst = %d", trst_gpio); - return ERROR_OK; + return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "trst", &trst_gpiochip, + &trst_gpio); } COMMAND_HANDLER(linuxgpiod_handle_swd_gpionums) @@ -499,35 +583,36 @@ COMMAND_HANDLER(linuxgpiod_handle_swd_gpionums) COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swclk) { - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - - command_print(CMD, "LinuxGPIOD num: swclk = %d", swclk_gpio); - return ERROR_OK; + return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swclk", &swclk_gpiochip, + &swclk_gpio); } COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio) { - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio); - - command_print(CMD, "LinuxGPIOD num: swdio = %d", swdio_gpio); - return ERROR_OK; + return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swdio", &swdio_gpiochip, + &swdio_gpio); } COMMAND_HANDLER(linuxgpiod_handle_gpionum_led) { - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], led_gpio); - - command_print(CMD, "LinuxGPIOD num: led = %d", led_gpio); - return ERROR_OK; + return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "led", &led_gpiochip, + &led_gpio); } COMMAND_HANDLER(linuxgpiod_handle_gpiochip) { - if (CMD_ARGC == 1) + if (CMD_ARGC == 1) { COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], gpiochip); + tck_gpiochip = gpiochip; + tms_gpiochip = gpiochip; + tdi_gpiochip = gpiochip; + tdo_gpiochip = gpiochip; + trst_gpiochip = gpiochip; + srst_gpiochip = gpiochip; + swclk_gpiochip = gpiochip; + swdio_gpiochip = gpiochip; + led_gpiochip = gpiochip; + } command_print(CMD, "LinuxGPIOD gpiochip = %d", gpiochip); return ERROR_OK; @@ -545,43 +630,43 @@ static const struct command_registration linuxgpiod_subcommand_handlers[] = { .name = "tck_num", .handler = linuxgpiod_handle_jtag_gpionum_tck, .mode = COMMAND_CONFIG, - .help = "gpio number for tck.", - .usage = "tck", + .help = "gpio chip number (optional) and gpio number for tck.", + .usage = "[chip] tck", }, { .name = "tms_num", .handler = linuxgpiod_handle_jtag_gpionum_tms, .mode = COMMAND_CONFIG, - .help = "gpio number for tms.", - .usage = "tms", + .help = "gpio chip number (optional) and gpio number for tms.", + .usage = "[chip] tms", }, { .name = "tdo_num", .handler = linuxgpiod_handle_jtag_gpionum_tdo, .mode = COMMAND_CONFIG, - .help = "gpio number for tdo.", - .usage = "tdo", + .help = "gpio chip number (optional) and gpio number for tdo.", + .usage = "[chip] tdo", }, { .name = "tdi_num", .handler = linuxgpiod_handle_jtag_gpionum_tdi, .mode = COMMAND_CONFIG, - .help = "gpio number for tdi.", - .usage = "tdi", + .help = "gpio chip number (optional) and gpio number for tdi.", + .usage = "[chip] tdi", }, { .name = "srst_num", .handler = linuxgpiod_handle_jtag_gpionum_srst, .mode = COMMAND_CONFIG, - .help = "gpio number for srst.", - .usage = "srst", + .help = "gpio chip number (optional) and gpio number for srst.", + .usage = "[chip] srst", }, { .name = "trst_num", .handler = linuxgpiod_handle_jtag_gpionum_trst, .mode = COMMAND_CONFIG, - .help = "gpio number for trst.", - .usage = "trst", + .help = "gpio chip number (optional) and gpio number for trst.", + .usage = "[chip] trst", }, { .name = "swd_nums", @@ -594,22 +679,22 @@ static const struct command_registration linuxgpiod_subcommand_handlers[] = { .name = "swclk_num", .handler = linuxgpiod_handle_swd_gpionum_swclk, .mode = COMMAND_CONFIG, - .help = "gpio number for swclk.", - .usage = "swclk", + .help = "gpio chip number (optional) and gpio number for swclk.", + .usage = "[chip] swclk", }, { .name = "swdio_num", .handler = linuxgpiod_handle_swd_gpionum_swdio, .mode = COMMAND_CONFIG, - .help = "gpio number for swdio.", - .usage = "swdio", + .help = "gpio chip number (optional) and gpio number for swdio.", + .usage = "[chip] swdio", }, { .name = "led_num", .handler = linuxgpiod_handle_gpionum_led, .mode = COMMAND_CONFIG, - .help = "gpio number for LED.", - .usage = "led", + .help = "gpio chip number (optional) and gpio number for LED.", + .usage = "[chip] led", }, { .name = "gpiochip", ----------------------------------------------------------------------- Summary of changes: src/jtag/drivers/linuxgpiod.c | 265 ++++++++++++++++++++++++++++-------------- 1 file changed, 175 insertions(+), 90 deletions(-) hooks/post-receive -- Main OpenOCD repository |