This is an automated email from Gerrit.

"Daniel Anselmi <danse...@gmx.ch>" just uploaded a new patch set to Gerrit, 
which you can find at https://review.openocd.org/c/openocd/+/7979

-- gerrit

commit 6b1c098872594539ab99e7c3074387c615f1c92c
Author: Daniel Anselmi <danse...@gmx.ch>
Date:   Sun Mar 12 01:43:32 2023 +0100

    ipdbg: split ipdbg start/stop cmd into command-chain
    
    To simplify adding additional commands to ipdbg.
    We split the ipdbg command using:
    command_registration.chain.
    
    Change-Id: I55f317542d01a7324990b2cacd496a41fa5ff875
    Signed-off-by: Daniel Anselmi <danse...@gmx.ch>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index c14ee9cb6a..d527522749 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -11990,12 +11990,11 @@ In a session using JTAG for its transport protocol, 
OpenOCD supports the functio
 of a JTAG-Host. The JTAG-Host is needed to connect the circuit over JTAG to the
 control-software. For more details see @url{http://ipdbg.org}.
 
-@deffn {Command} {ipdbg} [@option{-start|-stop}] @option{-tap @var{tapname}} 
@option{-hub @var{ir_value} [@var{dr_length}]} [@option{-vir [@var{vir_value} 
[@var{length} [@var{instr_code}]]]}] [@option{-port @var{number}}] 
[@option{-tool @var{number}}]
-Starts or stops a IPDBG JTAG-Host server. Arguments can be specified in any 
order.
+@deffn {Command} {ipdbg start} @option{-tap @var{tapname}} @option{-hub 
@var{ir_value} [@var{dr_length}]} [@option{-vir [@var{vir_value} [@var{length} 
[@var{instr_code}]]]}] [@option{-port @var{number}}] [@option{-tool 
@var{number}}]
+Starts a IPDBG JTAG-Host server. Arguments can be specified in any order.
 
 Command options:
 @itemize @bullet
-@item @option{-start|-stop} starts or stops a IPDBG JTAG-Host server (default: 
start).
 @item @option{-tap @var{tapname}} targeting the TAP @var{tapname}.
 @item @option{-hub @var{ir_value}} states that the JTAG hub is
 reachable with dr-scans while the JTAG instruction register has the value 
@var{ir_value}.
@@ -12009,10 +12008,10 @@ shift data through vir can be configured.
 @end itemize
 @end deffn
 or
-@deffn {Command} {ipdbg} [@option{-start|-stop}] @option{-pld @var{name} 
[@var{user}]} [@option{-port @var{number}}] [@option{-tool @var{number}}]
-Also starts or stops a IPDBG JTAG-Host server. The pld drivers are able to 
provide the tap and hub/IR for the IPDBG JTAG-Host server.
-With the @option{-pld @var{name} [@var{user}]} the information from the 
pld-driver is used and the options @option{-tap} and @option{-hub} are not 
required.
-The defined driver for the pld @var{name} gets selected. (The pld devices 
names can be shown by the command @command{pld devices}).
+@deffn {Command} {ipdbg start} @option{-pld @var{name} [@var{user}]} 
[@option{-port @var{number}}] [@option{-tool @var{number}}]
+Also starts a IPDBG JTAG-Host server. The pld drivers are able to provide the 
tap and hub/IR for the IPDBG JTAG-Host server.
+With the @option{-pld @var{num|name} [@var{user}]} the information from the 
pld-driver is used and the options @option{-tap} and @option{-hub} are not 
required.
+The defined driver @var{name} gets selected. (The pld devices names can be 
shown by the command @command{pld devices}).
 
 The @verb{|USERx|} instructions are vendor specific and don't change between 
families of the same vendor.
 So if there's a pld driver for your vendor it should work with your FPGA even 
when the driver is not compatible with your device for the remaining features. 
If your device/vendor is not supported you have to use the previous command.
@@ -12024,23 +12023,32 @@ The remaining options are described in the previous 
command.
 
 Examples:
 @example
-ipdbg -start -tap xc6s.tap -hub 0x02 -port 4242 -tool 4
+ipdbg start -tap xc6s.tap -hub 0x02 -port 4242 -tool 4
 @end example
 Starts a server listening on tcp-port 4242 which connects to tool 4.
 The connection is through the TAP of a Xilinx Spartan 6 on USER1 instruction 
(tested with a papillion pro board).
 
 @example
-ipdbg -start -tap 10m50.tap -hub 0x00C -vir -port 60000 -tool 1
+ipdbg start -tap 10m50.tap -hub 0x00C -vir -port 60000 -tool 1
 @end example
 Starts a server listening on tcp-port 60000 which connects to tool 1 
(data_up_1/data_down_1).
 The connection is through the TAP of a Intel MAX10 virtual jtag component 
(sld_instance_index is 0; sld_ir_width is smaller than 5).
 
 @example
-ipdbg -start -pld xc7.pld -port 5555 -tool 0
+ipdbg start -pld xc7.pld -port 5555 -tool 0
 @end example
 Starts a server listening on tcp-port 5555 which connects to tool 0 
(data_up_0/data_down_0).
 The TAP and ir value used to reach the JTAG Hub is given by the pld driver.
 
+@deffn {Command} {ipdbg stop} @option{-tap @var{tapname}} @option{-hub 
@var{ir_value}} [@option{-vir [@var{vir_value} [@var{length} 
[@var{instr_code}]]]}] [@option{-tool @var{number}}]
+Stops a IPDBG JTAG-Host server. Arguments can be specified in any order. For a 
description of the arguments look at @command{ipdbg start}.
+It is also possible to stop the IPDBG JTAG-Host server using the option 
@option{-pld @var{name} [@var{user}]}.
+@end deffn
+@example
+ipdbg stop -tap 10m50.tap -hub 0x00C -vir -port 60000 -tool 1
+@end example
+Stops the server for tool 1 (data_up_1/data_down_1).
+
 
 @node Utility Commands
 @chapter Utility Commands
diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl
index 4eca67771d..3f14dd75b6 100644
--- a/src/jtag/startup.tcl
+++ b/src/jtag/startup.tcl
@@ -1146,4 +1146,16 @@ proc "pld device" {driver tap_name {opt 0}} {
        }
 }
 
+lappend _telnet_autocomplete_skip "ipdbg -start"
+proc "ipdbg -start" {args} {
+       echo "DEPRECATED! use 'ipdbg start ...', not 'ipdbg -start ...'"
+       eval ipdbg start $args
+}
+
+lappend _telnet_autocomplete_skip "ipdbg -stop"
+proc "ipdbg -stop" {args} {
+       echo "DEPRECATED! use 'ipdbg stop ...', not 'ipdbg -stop ...'"
+       eval ipdbg stop $args
+}
+
 # END MIGRATION AIDS
diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c
index c0933784f5..8e36441b36 100644
--- a/src/server/ipdbg.c
+++ b/src/server/ipdbg.c
@@ -16,7 +16,7 @@
 
 #define IPDBG_BUFFER_SIZE 16384
 #define IPDBG_MIN_NUM_OF_OPTIONS 2
-#define IPDBG_MAX_NUM_OF_OPTIONS 14
+#define IPDBG_MAX_NUM_OF_OPTIONS 13
 #define IPDBG_MIN_DR_LENGTH 11
 #define IPDBG_MAX_DR_LENGTH 13
 #define IPDBG_TCP_PORT_STR_MAX_LENGTH 6
@@ -24,6 +24,21 @@
 #define IPDBG_EMPTY_DOWN_TRANSFERS 1024
 #define IPDBG_CONSECUTIVE_UP_TRANSFERS 1024
 
+/* parameters for starting / stopping ipdbg server */
+struct ipdbg_command_args {
+       struct jtag_tap *tap;
+       uint32_t user_instruction;
+       uint32_t virtual_ir_instruction;
+       uint32_t virtual_ir_length;
+       uint32_t virtual_ir_value;
+       uint16_t port;
+       uint8_t tool;
+       uint8_t data_register_length;
+       bool hub_configured;
+       bool has_virtual_ir;
+       int user_num;
+};
+
 /* private connection data for IPDBG */
 struct ipdbg_fifo {
        size_t count;
@@ -769,26 +784,28 @@ static const struct service_driver ipdbg_service_driver = 
{
        .keep_client_alive_handler = NULL,
 };
 
-static int ipdbg_start(uint16_t port, struct jtag_tap *tap, uint32_t 
user_instruction,
-                                       uint8_t data_register_length, struct 
ipdbg_virtual_ir_info *virtual_ir, uint8_t tool)
+static int ipdbg_start(struct ipdbg_command_args *command_args, struct 
ipdbg_virtual_ir_info *virtual_ir)
 {
-       LOG_INFO("starting ipdbg service on port %d for tool %d", port, tool);
+       LOG_INFO("starting ipdbg service on port %d for tool %d", 
command_args->port, command_args->tool);
 
-       struct ipdbg_hub *hub = ipdbg_find_hub(tap, user_instruction, 
virtual_ir);
+       struct ipdbg_hub *hub = ipdbg_find_hub(command_args->tap, 
command_args->user_instruction, virtual_ir);
        if (hub) {
                free(virtual_ir);
-               if (hub->data_register_length != data_register_length) {
+               if (hub->data_register_length != 
command_args->data_register_length) {
                        LOG_DEBUG("hub must have the same data_register_length 
for all tools");
                        return ERROR_FAIL;
                }
        } else {
-               int retval = ipdbg_create_hub(tap, user_instruction, 
data_register_length, virtual_ir, &hub);
-               if (retval != ERROR_OK)
+               int retval = ipdbg_create_hub(command_args->tap, 
command_args->user_instruction,
+                                                                               
command_args->data_register_length, virtual_ir, &hub);
+               if (retval != ERROR_OK) {
+                       free(virtual_ir);
                        return retval;
+               }
        }
 
        struct ipdbg_service *service = NULL;
-       int retval = ipdbg_create_service(hub, tool, &service, port);
+       int retval = ipdbg_create_service(hub, command_args->tool, &service, 
command_args->port);
 
        if (retval != ERROR_OK || !service) {
                if (hub->active_services == 0 && hub->active_connections == 0)
@@ -797,7 +814,7 @@ static int ipdbg_start(uint16_t port, struct jtag_tap *tap, 
uint32_t user_instru
        }
 
        char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
-       snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", port);
+       snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", 
command_args->port);
        retval = add_service(&ipdbg_service_driver, port_str_buffer, 1, 
service);
        if (retval == ERROR_OK) {
                ipdbg_add_service(service);
@@ -813,15 +830,13 @@ static int ipdbg_start(uint16_t port, struct jtag_tap 
*tap, uint32_t user_instru
        return retval;
 }
 
-static int ipdbg_stop(struct jtag_tap *tap, uint32_t user_instruction,
-                       struct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool)
+static int ipdbg_stop(struct ipdbg_command_args *command_args, struct 
ipdbg_virtual_ir_info *virtual_ir)
 {
-       struct ipdbg_hub *hub = ipdbg_find_hub(tap, user_instruction, 
virtual_ir);
-       free(virtual_ir);
+       struct ipdbg_hub *hub = ipdbg_find_hub(command_args->tap, 
command_args->user_instruction, virtual_ir);
        if (!hub)
                return ERROR_FAIL;
 
-       struct ipdbg_service *service = ipdbg_find_service(hub, tool);
+       struct ipdbg_service *service = ipdbg_find_service(hub, 
command_args->tool);
        if (!service)
                return ERROR_FAIL;
 
@@ -852,134 +867,225 @@ static int ipdbg_stop(struct jtag_tap *tap, uint32_t 
user_instruction,
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(handle_ipdbg_command)
+static int ipdbg_parse_tap(struct command_invocation *cmd, unsigned int i, 
struct jtag_tap **tap)
 {
-       struct jtag_tap *tap = NULL;
-       uint16_t port = 4242;
-       uint8_t tool = 1;
-       uint32_t user_instruction = 0x00;
-       uint8_t data_register_length = IPDBG_MAX_DR_LENGTH;
-       bool start = true;
-       bool hub_configured = false;
-       bool has_virtual_ir = false;
-       uint32_t virtual_ir_instruction = 0x00e;
-       uint32_t virtual_ir_length = 5;
-       uint32_t virtual_ir_value = 0x11;
-       struct ipdbg_virtual_ir_info *virtual_ir = NULL;
-       int user_num = 1;
+       if (i + 1 >= CMD_ARGC || CMD_ARGV[i + 1][0] == '-') {
+               command_print(CMD, "no TAP given");
+               return ERROR_FAIL;
+       }
+       *tap = jtag_tap_by_string(CMD_ARGV[i + 1]);
+       if (!(*tap)) {
+               command_print(CMD, "Tap %s unknown", CMD_ARGV[i + 1]);
+               return ERROR_FAIL;
+       }
+       return ERROR_OK;
+}
 
-       if ((CMD_ARGC < IPDBG_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > 
IPDBG_MAX_NUM_OF_OPTIONS))
-               return ERROR_COMMAND_SYNTAX_ERROR;
+static void ipdbg_init_command_arg_defaults(struct ipdbg_command_args 
*command_args)
+{
+       command_args->tap = NULL;
+       command_args->user_instruction = 0x00;
+       command_args->virtual_ir_instruction = 0x00e;
+       command_args->virtual_ir_value = 0x11;
+       command_args->virtual_ir_length = 5;
+       command_args->port = 4242;
+       command_args->tool = 1;
+       command_args->data_register_length = IPDBG_MAX_DR_LENGTH;
+       command_args->hub_configured = false;
+       command_args->has_virtual_ir = false;
+       command_args->user_num = 1;
+}
 
+static int ipdbg_get_hub_from_pld_drv(struct command_invocation *cmd, const 
char *pld_name,
+                                                                       struct 
ipdbg_command_args *command_args)
+{
+       struct pld_ipdbg_hub pld_hub;
+       struct pld_device *device = get_pld_device_by_name_or_numstr(pld_name);
+       if (!device || !device->driver) {
+               command_print(CMD, "pld device '#%s' is out of bounds or 
unknown", pld_name);
+               return ERROR_FAIL;
+       }
+       struct pld_driver *driver = device->driver;
+       if (!driver->get_ipdbg_hub) {
+               command_print(CMD, "pld driver has no ipdbg support");
+               return ERROR_FAIL;
+       }
+       if (driver->get_ipdbg_hub(command_args->user_num, device, &pld_hub) != 
ERROR_OK) {
+               command_print(CMD, "unable to retrieve hub from pld driver");
+               return ERROR_FAIL;
+       }
+       if (!pld_hub.tap) {
+               command_print(CMD, "no tap received from pld driver");
+               return ERROR_FAIL;
+       }
+
+       command_args->user_instruction = pld_hub.user_ir_code;
+       command_args->tap = pld_hub.tap;
+
+       return ERROR_OK;
+}
+
+static struct ipdbg_virtual_ir_info *ipdbg_alloc_virtual_ir(struct 
ipdbg_command_args *command_args)
+{
+       struct ipdbg_virtual_ir_info *virtual_ir = calloc(1, sizeof(struct 
ipdbg_virtual_ir_info));
+       if (virtual_ir) {
+               virtual_ir->instruction = command_args->virtual_ir_instruction;
+               virtual_ir->length      = command_args->virtual_ir_length;
+               virtual_ir->value       = command_args->virtual_ir_value;
+       }
+       return virtual_ir;
+}
+
+static int ipdbg_parse_options(struct command_invocation *cmd, struct 
ipdbg_command_args *command_args)
+{
+       int retval;
        for (unsigned int i = 0; i < CMD_ARGC; ++i) {
                if (strcmp(CMD_ARGV[i], "-tap") == 0) {
-                       if (i + 1 >= CMD_ARGC || CMD_ARGV[i + 1][0] == '-') {
-                               command_print(CMD, "no TAP given");
-                               return ERROR_FAIL;
-                       }
-                       tap = jtag_tap_by_string(CMD_ARGV[i + 1]);
-                       if (!tap) {
-                               command_print(CMD, "Tap %s unknown", CMD_ARGV[i 
+ 1]);
-                               return ERROR_FAIL;
-                       }
+                       retval = ipdbg_parse_tap(CMD, i, &command_args->tap);
+                       if (retval != ERROR_OK)
+                               return retval;
                        ++i;
                } else if (strcmp(CMD_ARGV[i], "-hub") == 0) {
-                       COMMAND_PARSE_ADDITIONAL_NUMBER(u32, i, 
user_instruction, "ir_value to select hub");
-                       hub_configured = true;
-                       COMMAND_PARSE_OPTIONAL_NUMBER(u8, i, 
data_register_length);
-                       if (data_register_length < IPDBG_MIN_DR_LENGTH ||
-                               data_register_length > IPDBG_MAX_DR_LENGTH) {
-                               command_print(CMD, "length of \"user\"-data 
register must be at least %d and at most %d.",
-                                                       IPDBG_MIN_DR_LENGTH, 
IPDBG_MAX_DR_LENGTH);
-                               return ERROR_FAIL;
-                       }
+                       COMMAND_PARSE_ADDITIONAL_NUMBER(u32, i, 
command_args->user_instruction, "ir_value to select hub");
+                       command_args->hub_configured = true;
+                       COMMAND_PARSE_OPTIONAL_NUMBER(u8, i, 
command_args->data_register_length);
                } else if (strcmp(CMD_ARGV[i], "-pld") == 0) {
                        ++i;
-                       if (i >= CMD_ARGC || CMD_ARGV[i][0] == '-')
-                               return ERROR_COMMAND_SYNTAX_ERROR;
-                       struct pld_device *device = 
get_pld_device_by_name_or_numstr(CMD_ARGV[i]);
-                       if (!device || !device->driver) {
-                               command_print(CMD, "pld device '#%s' is out of 
bounds or unknown", CMD_ARGV[i]);
-                               return ERROR_FAIL;
-                       }
-                       COMMAND_PARSE_OPTIONAL_NUMBER(int, i, user_num);
-                       struct pld_ipdbg_hub pld_hub;
-                       struct pld_driver *driver = device->driver;
-                       if (!driver->get_ipdbg_hub) {
-                               command_print(CMD, "pld driver has no ipdbg 
support");
-                               return ERROR_FAIL;
-                       }
-                       if (driver->get_ipdbg_hub(user_num, device, &pld_hub) 
!= ERROR_OK) {
-                               command_print(CMD, "unable to retrieve hub from 
pld driver");
-                               return ERROR_FAIL;
-                       }
-                       if (!pld_hub.tap) {
-                               command_print(CMD, "no tap received from pld 
driver");
-                               return ERROR_FAIL;
-                       }
-                       hub_configured = true;
-                       user_instruction = pld_hub.user_ir_code;
-                       tap = pld_hub.tap;
-
+                       const char *pld_name = CMD_ARGV[i];
+                       //COMMAND_PARSE_OPTIONAL_NUMBER(int, i, user_num);
+                       COMMAND_PARSE_OPTIONAL_NUMBER(int, i, 
command_args->user_num);
+                       retval = ipdbg_get_hub_from_pld_drv(CMD, pld_name, 
command_args);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       command_args->hub_configured = true;
                } else if (strcmp(CMD_ARGV[i], "-vir") == 0) {
-                       COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_value);
-                       COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, 
virtual_ir_length);
-                       COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, 
virtual_ir_instruction);
-                       has_virtual_ir = true;
+                       COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, 
command_args->virtual_ir_value);
+                       COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, 
command_args->virtual_ir_length);
+                       COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, 
command_args->virtual_ir_instruction);
+                       command_args->has_virtual_ir = true;
                } else if (strcmp(CMD_ARGV[i], "-port") == 0) {
-                       COMMAND_PARSE_ADDITIONAL_NUMBER(u16, i, port, "port 
number");
+                       COMMAND_PARSE_ADDITIONAL_NUMBER(u16, i, 
command_args->port, "port number");
                } else if (strcmp(CMD_ARGV[i], "-tool") == 0) {
-                       COMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, tool, "tool");
-               } else if (strcmp(CMD_ARGV[i], "-stop") == 0) {
-                       start = false;
-               } else if (strcmp(CMD_ARGV[i], "-start") == 0) {
-                       start = true;
+                       COMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, 
command_args->tool, "tool");
                } else {
                        command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
                        return ERROR_FAIL;
                }
        }
+       return ERROR_OK;
+}
 
-       if (!tap) {
+static int ipdbg_check_required_arguments(struct command_invocation *cmd, 
struct ipdbg_command_args *command_args)
+{
+       if (!command_args->tap) {
                command_print(CMD, "no valid tap selected");
                return ERROR_FAIL;
        }
 
-       if (!hub_configured) {
+       if (command_args->data_register_length < IPDBG_MIN_DR_LENGTH ||
+               command_args->data_register_length > IPDBG_MAX_DR_LENGTH) {
+               command_print(CMD, "length of \"user\"-data register must be at 
least %d and at most %d.",
+                                       IPDBG_MIN_DR_LENGTH, 
IPDBG_MAX_DR_LENGTH);
+               return ERROR_FAIL;
+       }
+
+       if (!command_args->hub_configured) {
                command_print(CMD, "hub not configured correctly");
                return ERROR_FAIL;
        }
 
-       if (tool >= 
ipdbg_max_tools_from_data_register_length(data_register_length)) {
-               command_print(CMD, "Tool: %d is invalid", tool);
+       if (command_args->tool >= 
ipdbg_max_tools_from_data_register_length(command_args->data_register_length)) {
+               command_print(CMD, "Tool: %d is invalid", command_args->tool);
                return ERROR_FAIL;
        }
 
-       if (has_virtual_ir) {
-               virtual_ir = calloc(1, sizeof(struct ipdbg_virtual_ir_info));
-               if (!virtual_ir) {
-                       LOG_ERROR("Out of memory");
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_ipdbg_start_command)
+{
+       int retval;
+       struct ipdbg_command_args command_args;
+       ipdbg_init_command_arg_defaults(&command_args);
+
+       if (CMD_ARGC < IPDBG_MIN_NUM_OF_OPTIONS || CMD_ARGC > 
IPDBG_MAX_NUM_OF_OPTIONS)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       retval = ipdbg_parse_options(CMD, &command_args);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = ipdbg_check_required_arguments(CMD, &command_args);
+       if (retval != ERROR_OK)
+               return retval;
+
+       struct ipdbg_virtual_ir_info *virtual_ir = NULL;
+       if (command_args.has_virtual_ir) {
+               virtual_ir = ipdbg_alloc_virtual_ir(&command_args);
+               if (!virtual_ir)
                        return ERROR_FAIL;
-               }
-               virtual_ir->instruction = virtual_ir_instruction;
-               virtual_ir->length      = virtual_ir_length;
-               virtual_ir->value       = virtual_ir_value;
        }
 
-       if (start)
-               return ipdbg_start(port, tap, user_instruction, 
data_register_length, virtual_ir, tool);
-       else
-               return ipdbg_stop(tap, user_instruction, virtual_ir, tool);
+       retval = ipdbg_start(&command_args, virtual_ir);
+       if (retval != ERROR_OK && virtual_ir)
+               free(virtual_ir);
+       return retval;
+}
+
+COMMAND_HANDLER(handle_ipdbg_stop_command)
+{
+       int retval;
+       struct ipdbg_command_args command_args;
+       ipdbg_init_command_arg_defaults(&command_args);
+
+       if (CMD_ARGC < IPDBG_MIN_NUM_OF_OPTIONS || CMD_ARGC > 
IPDBG_MAX_NUM_OF_OPTIONS)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       retval = ipdbg_parse_options(CMD, &command_args);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = ipdbg_check_required_arguments(CMD, &command_args);
+       if (retval != ERROR_OK)
+               return retval;
+
+       struct ipdbg_virtual_ir_info *virtual_ir = NULL;
+       if (command_args.has_virtual_ir) {
+               virtual_ir = ipdbg_alloc_virtual_ir(&command_args);
+               if (!virtual_ir)
+                       return ERROR_FAIL;
+       }
+       retval = ipdbg_stop(&command_args, virtual_ir);
+       free(virtual_ir);
+       return retval;
 }
 
+static const struct command_registration ipdbg_subcommand_handlers[] = {
+       {
+               .name = "start",
+               .handler = handle_ipdbg_start_command,
+               .mode = COMMAND_EXEC,
+               .help = "Starts an IPDBG JTAG-Host server.",
+               .usage = "-tap device.tap -hub ir_value [dr_length]"
+                                " [-port number] [-tool number] [-vir 
[vir_value [length [instr_code]]]]",
+       }, {
+               .name = "stop",
+               .handler = handle_ipdbg_stop_command,
+               .mode = COMMAND_EXEC,
+               .help = "Stops an IPDBG JTAG-Host server.",
+               .usage = "-tap device.tap -hub ir_value [dr_length]"
+                                " [-tool number] [-vir [vir_value [length 
[instr_code]]]]",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
 static const struct command_registration ipdbg_command_handlers[] = {
        {
                .name = "ipdbg",
-               .handler = handle_ipdbg_command,
                .mode = COMMAND_EXEC,
-               .help = "Starts or stops an IPDBG JTAG-Host server.",
-               .usage = "[-start|-stop] -tap device.tap -hub ir_value 
[dr_length]"
-                                " [-port number] [-tool number] [-vir 
[vir_value [length [instr_code]]]]",
+               .help = "Starts, stops or configures an IPDBG JTAG-Host 
server.",
+               .usage = "",
+               .chain = ipdbg_subcommand_handlers,
        },
        COMMAND_REGISTRATION_DONE
 };
diff --git a/tcl/board/bemicro_cycloneiii.cfg b/tcl/board/bemicro_cycloneiii.cfg
index bd1459adc4..d10e8ced20 100644
--- a/tcl/board/bemicro_cycloneiii.cfg
+++ b/tcl/board/bemicro_cycloneiii.cfg
@@ -17,7 +17,7 @@ source [find fpga/altera-cycloneiii.cfg]
 #quartus_cpf --option=bitstream_compression=off -c 
output_files\cycloneiii_blinker.sof cycloneiii_blinker.rbf
 
 #openocd -f board/bemicro_cycloneiii.cfg -c "init" -c "pld load cycloneiii.pld 
cycloneiii_blinker.rbf"
-# "ipdbg -start -tap cycloneiii.tap -hub 0x00e -tool 0 -port 5555"
+# "ipdbg start -tap cycloneiii.tap -hub 0x00e -tool 0 -port 5555"
 
 
 set JTAGSPI_CHAIN_ID cycloneiii.pld
diff --git a/tcl/board/digilent_cmod_s7.cfg b/tcl/board/digilent_cmod_s7.cfg
index c52ee9505b..16fda5f6b6 100644
--- a/tcl/board/digilent_cmod_s7.cfg
+++ b/tcl/board/digilent_cmod_s7.cfg
@@ -15,7 +15,7 @@ adapter speed 10000
 
 source [find cpld/xilinx-xc7.cfg]
 
-# "ipdbg -start -tap xc7.tap -hub 0x02 -tool 0 -port 5555"
+# "ipdbg start -tap xc7.tap -hub 0x02 -tool 0 -port 5555"
 #openocd -f board/digilent_cmod_s7.cfg -c "init" -c "pld load xc7.pld 
shared_folder/cmod_s7_fast.bit"
 
 set JTAGSPI_CHAIN_ID xc7.pld
diff --git a/tcl/board/ecp5_evaluation.cfg b/tcl/board/ecp5_evaluation.cfg
index dd663f79d8..0d3c993e1e 100644
--- a/tcl/board/ecp5_evaluation.cfg
+++ b/tcl/board/ecp5_evaluation.cfg
@@ -16,7 +16,7 @@ adapter speed 6000
 source [find fpga/lattice_ecp5.cfg]
 
 #openocd -f board/ecp5_evaluation.cfg -c "init" -c "pld load ecp5.pld 
shared_folder/ecp5_blinker_impl1.bit"
-#ipdbg -start -tap ecp5.tap -hub 0x32 -port 5555 -tool 0
+#ipdbg start -tap ecp5.tap -hub 0x32 -port 5555 -tool 0
 
 set JTAGSPI_CHAIN_ID ecp5.pld
 source [find cpld/jtagspi.cfg]
diff --git a/tcl/board/gowin_runber.cfg b/tcl/board/gowin_runber.cfg
index 9496c6f008..7c5afd4d76 100644
--- a/tcl/board/gowin_runber.cfg
+++ b/tcl/board/gowin_runber.cfg
@@ -14,6 +14,5 @@ adapter speed 6000
 
 source [find fpga/gowin_gw1n.cfg]
 
-
 #openocd -f board/gowin_runber.cfg  -c "init" -c "pld load 0 
impl/pnr/gw1n_blinker.fs"
-#ipdbg -start -tap gw1n.tap -hub 0x42 -port 5555 -tool 0
+#ipdbg start -tap gw1n.tap -hub 0x42 -port 5555 -tool 0
diff --git a/tcl/board/trion_t20_bga256.cfg b/tcl/board/trion_t20_bga256.cfg
index dc76d39104..5502435d5d 100644
--- a/tcl/board/trion_t20_bga256.cfg
+++ b/tcl/board/trion_t20_bga256.cfg
@@ -20,7 +20,7 @@ adapter speed 6000
 source [find fpga/efinix_trion.cfg]
 
 #openocd -f board/trion_t20_bga256.cfg -c "init" -c "pld load trion.pld 
outflow/trion_blinker.bit"
-#ipdbg -start -tap trion.tap -hub 0x8 -port 5555 -tool 0
+#ipdbg start -tap trion.tap -hub 0x8 -port 5555 -tool 0
 
 set JTAGSPI_CHAIN_ID trion.pld
 source [find cpld/jtagspi.cfg]

-- 

Reply via email to