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/+/7369

-- gerrit

commit d599cc818038b70ab39b0113439a6047223820fb
Author: Daniel Anselmi <danse...@gmx.ch>
Date:   Mon Nov 21 04:15:02 2022 +0100

    ipdbg/pld: ipdbg can get tap and hub/ir from pld driver.
    
    Change-Id: I13eeb9fee895d65cd48544da4704fcc9b528b869
    Signed-off-by: Daniel Anselmi <danse...@gmx.ch>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index f1081d51fc..b8ac705b6e 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -11624,7 +11624,7 @@ 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{-port @var{number}}] 
[@option{-tool @var{number}}] [@option{-vir [@var{vir_value} [@var{length} 
[@var{instr_code}]]]}]
+@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.
 
 Command options:
@@ -11633,15 +11633,28 @@ Command options:
 @item @option{-tap @var{tapname}} targeting the TAP @var{tapname}.
 @item @option{-hub @var{ir_value}} states that the JTAG hub is
 reachable with dr-scans while the JTAG instruction register has the value 
@var{ir_value}.
-@item @option{-port @var{number}} tcp port number where the JTAG-Host is 
listening.
-@item @option{-tool @var{number}} number of the tool/feature. These 
corresponds to the ports "data_(up/down)_(0..6)" at the JtagHub.
-@item @option{-vir [@var{vir_value} [@var{length} [@var{instr_code}]]]} On 
some devices, the user data-register is only reachable if there is a
+@item @option{-port @var{number}} tcp port number where the JTAG-Host will 
listen. The default is 4242 which is used when the option is not given.
+@item @option{-tool @var{number}} number of the tool/feature. These 
corresponds to the ports "data_(up/down)_(0..6)" at the JtagHub. The default is 
1 which is used when the option is not given.
+@item @option{-vir [@var{vir_value} [@var{length} [@var{instr_code}]]]} On 
some devices, the user data-register is reachable if there is a
 specific value in a second dr. This second dr is called vir (virtual ir). With 
this parameter given, the IPDBG satisfies this condition prior an
 access to the IPDBG-Hub. The value shifted into the vir is given by the first 
parameter @var{vir_value} (default: 0x11). The second
 parameter @var{length} is the length of the vir data register (default: 5). 
With the @var{instr_code} (default: 0x00e) parameter the ir value to
 shift data through vir can be configured.
 @end itemize
 @end deffn
+or
+@deffn {Command} {ipdbg} [@option{-start|-stop}] @option{-pld @var{num} 
[@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{num} [@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{num} gets selected. (The number can be shown by the 
@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.
+
+With [@var{user}] one can select a different @verb{|USERx|}-Instruction. If 
the IPDBG JTAG-Hub is used without modification the default value of 0 which 
selects the first @verb{|USERx|} instruction is adequate.
+
+The remaining options are described in the previous command.
+@end deffn
 
 Examples:
 @example
diff --git a/src/pld/certus.c b/src/pld/certus.c
index 805b42de19..b8dd768e02 100644
--- a/src/pld/certus.c
+++ b/src/pld/certus.c
@@ -376,9 +376,11 @@ static const struct command_registration 
certus_command_handler[] = {
        COMMAND_REGISTRATION_DONE
 };
 
+
 struct pld_driver certus_pld = {
        .name = "certus",
        .commands = certus_command_handler,
        .pld_device_command = &certus_pld_device_command,
        .load = &certus_load_command,
+       .get_ipdbg_hub = lattice_get_ipdbg_hub,
 };
diff --git a/src/pld/ecp2_3.c b/src/pld/ecp2_3.c
index 987094c6dc..3eabab3b35 100644
--- a/src/pld/ecp2_3.c
+++ b/src/pld/ecp2_3.c
@@ -516,4 +516,5 @@ struct pld_driver ecp2_3_pld = {
        .commands = ecp2_3_command_handler,
        .pld_device_command = &ecp2_3_pld_device_command,
        .load = &ecp2_3_load,
+       .get_ipdbg_hub = lattice_get_ipdbg_hub,
 };
diff --git a/src/pld/ecp5.c b/src/pld/ecp5.c
index 11e0996ee9..d98d6ac06e 100644
--- a/src/pld/ecp5.c
+++ b/src/pld/ecp5.c
@@ -426,4 +426,5 @@ struct pld_driver ecp5_pld = {
        .commands = ecp5_command_handler,
        .pld_device_command = &ecp5_pld_device_command,
        .load = &ecp5_load_command,
+       .get_ipdbg_hub = lattice_get_ipdbg_hub,
 };
diff --git a/src/pld/efinix.c b/src/pld/efinix.c
index ae6f08bc55..7e16d1c4aa 100644
--- a/src/pld/efinix.c
+++ b/src/pld/efinix.c
@@ -17,6 +17,10 @@
 
 #define PROGRAM   0x4
 #define ENTERUSER 0x7
+#define USER1     0x8
+#define USER2     0x9
+#define USER3     0xa
+#define USER4     0xb
 
 #define NO_FORCE 0
 #define FORCE    1
@@ -201,6 +205,38 @@ static int trion_load(struct pld_device *pld_device, const 
char *filename)
        return retval;
 }
 
+static int efinix_get_ipdbg_hub(int user_num, struct pld_device *pld_device, 
struct pld_ipdbg_hub *hub)
+{
+       if (!pld_device)
+               return ERROR_FAIL;
+
+       struct trion_pld_device *pld_device_info = pld_device->driver_priv;
+
+       if (!pld_device_info || !pld_device_info->tap)
+               return ERROR_FAIL;
+
+       hub->tap = pld_device_info->tap;
+
+       switch (user_num) {
+       case 1:
+               hub->user_ir_code = USER1;
+               break;
+       case 2:
+               hub->user_ir_code = USER2;
+               break;
+       case 3:
+               hub->user_ir_code = USER3;
+               break;
+       case 4:
+               hub->user_ir_code = USER4;
+               break;
+       default:
+               LOG_ERROR("efinix devices only have user register 1 to 4");
+               return ERROR_FAIL;
+       }
+       return ERROR_OK;
+}
+
 PLD_DEVICE_COMMAND_HANDLER(trion_pld_device_command)
 {
        if (CMD_ARGC != 2)
@@ -239,4 +275,5 @@ struct pld_driver trion_pld = {
        .commands = trion_command_handler,
        .pld_device_command = &trion_pld_device_command,
        .load = &trion_load,
+       .get_ipdbg_hub = efinix_get_ipdbg_hub,
 };
diff --git a/src/pld/gowin.c b/src/pld/gowin.c
index 4b140f7563..8d55c40e20 100644
--- a/src/pld/gowin.c
+++ b/src/pld/gowin.c
@@ -28,6 +28,9 @@
 #define ERASE_FLASH                 0x75
 #define ENABLE_2ND_FLASH            0x78
 
+#define USER1                       0x42
+//#define USER2
+
 #define STAUS_MASK_MEMORY_ERASE        (0x00000001 <<  5)
 #define STAUS_MASK_SYSTEM_EDIT_MODE    (0x00000001 <<  7)
 
@@ -470,6 +473,29 @@ static int gowin_reload_command(struct pld_device 
*pld_device)
        return gowin_reload(gowin_info->tap);
 }
 
+static int gowin_get_ipdbg_hub(int user_num, struct pld_device *pld_device, 
struct pld_ipdbg_hub *hub)
+{
+       if (!pld_device)
+               return ERROR_FAIL;
+
+       struct gowin_pld_device *pld_device_info = pld_device->driver_priv;
+
+       if (!pld_device_info || !pld_device_info->tap)
+               return ERROR_FAIL;
+
+       hub->tap = pld_device_info->tap;
+
+       if (user_num == 1) {
+               hub->user_ir_code = USER1;
+//     } else if (user_num == 2) {
+//             hub->user_ir_code = USER2;
+       } else {
+               LOG_ERROR("gowin devices only have user register 1 & 2");
+               return ERROR_FAIL;
+       }
+       return ERROR_OK;
+}
+
 COMMAND_HANDLER(gowin_read_status_command_handler)
 {
        int dev_id;
@@ -603,4 +629,5 @@ struct pld_driver gowin_pld = {
        .commands = gowin_command_handler,
        .pld_device_command = &gowin_pld_device_command,
        .load = &gowin_load_to_sram,
+       .get_ipdbg_hub = gowin_get_ipdbg_hub,
 };
diff --git a/src/pld/intel.c b/src/pld/intel.c
index d13f49386a..e9b3176eb9 100644
--- a/src/pld/intel.c
+++ b/src/pld/intel.c
@@ -19,6 +19,8 @@
 #include "raw_bit.h"
 
 #define BYPASS 0x3FF
+#define USER1  0x00C
+#define USER2  0x00E
 
 enum family_e {cycloneiii,
                                cycloneiv,
@@ -339,6 +341,29 @@ static int intel_load(struct pld_device *pld_device, const 
char *filename)
        return jtag_execute_queue();
 }
 
+static int intel_get_ipdbg_hub(int user_num, struct pld_device *pld_device, 
struct pld_ipdbg_hub *hub)
+{
+       if (!pld_device)
+               return ERROR_FAIL;
+
+       struct intel_pld_device *pld_device_info = pld_device->driver_priv;
+
+       if (!pld_device_info || !pld_device_info->tap)
+               return ERROR_FAIL;
+
+       hub->tap = pld_device_info->tap;
+
+       if (user_num == 1) {
+               hub->user_ir_code = USER1;
+       } else if (user_num == 2) {
+               hub->user_ir_code = USER2;
+       } else {
+               LOG_ERROR("intel devices only have user register 1 & 2");
+               return ERROR_FAIL;
+       }
+       return ERROR_OK;
+}
+
 COMMAND_HANDLER(intel_set_bscan_command_handler)
 {
        int dev_id;
@@ -473,5 +498,6 @@ struct pld_driver intel_pld = {
        .commands = intel_command_handler,
        .pld_device_command = &intel_pld_device_command,
        .load = &intel_load,
+       .get_ipdbg_hub = intel_get_ipdbg_hub,
 };
 
diff --git a/src/pld/lattice.c b/src/pld/lattice.c
index db0ec2c52d..78dd923305 100644
--- a/src/pld/lattice.c
+++ b/src/pld/lattice.c
@@ -11,6 +11,9 @@
 
 #include "lattice.h"
 
+#define USER1 0x32
+#define USER2 0x38
+
 
 void lattice_set_instr(struct jtag_tap *tap, uint8_t new_instr, tap_state_t 
endstate)
 {
@@ -102,3 +105,26 @@ int lattice_preload(struct jtag_tap *tap, uint8_t 
preload_cmd, size_t length)
        free(buffer);
        return retval;
 }
+
+int lattice_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct 
pld_ipdbg_hub *hub)
+{
+       if (!pld_device)
+               return ERROR_FAIL;
+
+       struct lattice_pld_device *pld_device_info = pld_device->driver_priv;
+
+       if (!pld_device_info || !pld_device_info->tap)
+               return ERROR_FAIL;
+
+       hub->tap = pld_device_info->tap;
+
+       if (user_num == 1) {
+               hub->user_ir_code = USER1;
+       } else if (user_num == 2) {
+               hub->user_ir_code = USER2;
+       } else {
+               LOG_ERROR("lattice devices only have user register 1 & 2");
+               return ERROR_FAIL;
+       }
+       return ERROR_OK;
+}
diff --git a/src/pld/lattice.h b/src/pld/lattice.h
index 8f6f1ca882..95c09ddfc9 100644
--- a/src/pld/lattice.h
+++ b/src/pld/lattice.h
@@ -9,6 +9,7 @@
 #define OPENOCD_PLD_LATTICE_H
 
 #include <jtag/jtag.h>
+#include "pld.h"
 
 struct lattice_pld_device {
        struct jtag_tap *tap;
@@ -27,5 +28,5 @@ int lattice_read_u64_register(struct jtag_tap *tap, uint8_t 
cmd, uint64_t *in_va
 int lattice_get_preload_length(uint32_t id, const struct 
lattice_devices_preload_length_elem *elems,
                                                size_t num_elems, size_t 
*length);
 int lattice_preload(struct jtag_tap *tap, uint8_t preload_cmd, size_t length);
-
+int lattice_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct 
pld_ipdbg_hub *hub);
 #endif /* OPENOCD_PLD_LATTICE_H */
diff --git a/src/pld/pld.h b/src/pld/pld.h
index a7cd20f641..b3c102290d 100644
--- a/src/pld/pld.h
+++ b/src/pld/pld.h
@@ -15,11 +15,17 @@ struct pld_device;
 #define __PLD_DEVICE_COMMAND(name) \
        COMMAND_HELPER(name, struct pld_device *pld)
 
+struct pld_ipdbg_hub {
+       struct jtag_tap *tap;
+       unsigned int user_ir_code;
+};
+
 struct pld_driver {
        const char *name;
        __PLD_DEVICE_COMMAND((*pld_device_command));
        const struct command_registration *commands;
        int (*load)(struct pld_device *pld_device, const char *filename);
+       int (*get_ipdbg_hub)(int user_num, struct pld_device *pld_device, 
struct pld_ipdbg_hub *hub);
 };
 
 #define PLD_DEVICE_COMMAND_HANDLER(name) \
diff --git a/src/pld/virtex2.c b/src/pld/virtex2.c
index 98fd58adbb..8524f28826 100644
--- a/src/pld/virtex2.c
+++ b/src/pld/virtex2.c
@@ -13,6 +13,11 @@
 #include "xilinx_bit.h"
 #include "pld.h"
 
+#define USER1     0x02
+#define USER2     0x03
+#define USER3     0x22
+#define USER4     0x23
+
 static int virtex2_set_instr(struct jtag_tap *tap, uint32_t new_instr)
 {
        if (!tap)
@@ -162,6 +167,38 @@ static int virtex2_load(struct pld_device *pld_device, 
const char *filename)
        return ERROR_OK;
 }
 
+static int virtex2_get_ipdbg_hub(int user_num, struct pld_device *pld_device, 
struct pld_ipdbg_hub *hub)
+{
+       if (!pld_device)
+               return ERROR_FAIL;
+
+       struct virtex2_pld_device *pld_device_info = pld_device->driver_priv;
+
+       if (!pld_device_info || !pld_device_info->tap)
+               return ERROR_FAIL;
+
+       hub->tap = pld_device_info->tap;
+
+       switch (user_num) {
+       case 1:
+               hub->user_ir_code = USER1;
+               break;
+       case 2:
+               hub->user_ir_code = USER2;
+               break;
+       case 3:
+               hub->user_ir_code = USER3;
+               break;
+       case 4:
+               hub->user_ir_code = USER4;
+               break;
+       default:
+               LOG_ERROR("efinix devices only have user register 1 to 4");
+               return ERROR_FAIL;
+       }
+       return ERROR_OK;
+}
+
 COMMAND_HANDLER(virtex2_handle_read_stat_command)
 {
        struct pld_device *device;
@@ -238,4 +275,5 @@ struct pld_driver virtex2_pld = {
        .commands = virtex2_command_handler,
        .pld_device_command = &virtex2_pld_device_command,
        .load = &virtex2_load,
+       .get_ipdbg_hub = virtex2_get_ipdbg_hub,
 };
diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c
index f4a6f6cdcc..ec76bdaf9e 100644
--- a/src/server/ipdbg.c
+++ b/src/server/ipdbg.c
@@ -10,11 +10,12 @@
 #include <jtag/jtag.h>
 #include <server/server.h>
 #include <target/target.h>
+#include <pld/pld.h>
 
 #include "ipdbg.h"
 
 #define IPDBG_BUFFER_SIZE 16384
-#define IPDBG_MIN_NUM_OF_OPTIONS 4
+#define IPDBG_MIN_NUM_OF_OPTIONS 2
 #define IPDBG_MAX_NUM_OF_OPTIONS 14
 #define IPDBG_MIN_DR_LENGTH 11
 #define IPDBG_MAX_DR_LENGTH 13
@@ -90,7 +91,7 @@ static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo)
                return;
 
        size_t ri = fifo->rd_idx;
-       for (size_t idx = 0 ; idx < fifo->count ; ++idx)
+       for (size_t idx = 0; idx < fifo->count; ++idx)
                fifo->buffer[idx] = fifo->buffer[ri++];
        fifo->rd_idx = 0;
 }
@@ -149,7 +150,7 @@ static int 
ipdbg_max_tools_from_data_register_length(uint8_t data_register_lengt
 static struct ipdbg_service *ipdbg_find_service(struct ipdbg_hub *hub, uint8_t 
tool)
 {
        struct ipdbg_service *service;
-       for (service = ipdbg_first_service ; service ; service = service->next) 
{
+       for (service = ipdbg_first_service; service; service = service->next) {
                if (service->hub == hub && service->tool == tool)
                        break;
        }
@@ -160,7 +161,7 @@ static void ipdbg_add_service(struct ipdbg_service *service)
 {
        struct ipdbg_service *iservice;
        if (ipdbg_first_service) {
-               for (iservice = ipdbg_first_service ; iservice->next; iservice 
= iservice->next)
+               for (iservice = ipdbg_first_service; iservice->next; iservice = 
iservice->next)
                        ;
                iservice->next = service;
        } else
@@ -192,7 +193,7 @@ static int ipdbg_remove_service(struct ipdbg_service 
*service)
                return ERROR_OK;
        }
 
-       for (struct ipdbg_service *iservice = ipdbg_first_service ; 
iservice->next ; iservice = iservice->next) {
+       for (struct ipdbg_service *iservice = ipdbg_first_service; 
iservice->next; iservice = iservice->next) {
                if (service == iservice->next) {
                        iservice->next = service->next;
                        return ERROR_OK;
@@ -205,7 +206,7 @@ static struct ipdbg_hub *ipdbg_find_hub(struct jtag_tap 
*tap,
                                uint32_t user_instruction, struct 
ipdbg_virtual_ir_info *virtual_ir)
 {
        struct ipdbg_hub *hub = NULL;
-       for (hub = ipdbg_first_hub ; hub ; hub = hub->next) {
+       for (hub = ipdbg_first_hub; hub; hub = hub->next) {
                if (hub->tap == tap && hub->user_instruction == 
user_instruction) {
                        if ((!virtual_ir && !hub->virtual_ir) ||
                                 (virtual_ir && hub->virtual_ir &&
@@ -223,7 +224,7 @@ static void ipdbg_add_hub(struct ipdbg_hub *hub)
 {
        struct ipdbg_hub *ihub;
        if (ipdbg_first_hub) {
-               for (ihub = ipdbg_first_hub ; ihub->next; ihub = ihub->next)
+               for (ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next)
                        ;
                ihub->next = hub;
        } else
@@ -281,7 +282,7 @@ static int ipdbg_remove_hub(struct ipdbg_hub *hub)
                return ERROR_OK;
        }
 
-       for (struct ipdbg_hub *ihub = ipdbg_first_hub ; ihub->next ; ihub = 
ihub->next) {
+       for (struct ipdbg_hub *ihub = ipdbg_first_hub; ihub->next; ihub = 
ihub->next) {
                if (hub == ihub->next) {
                        ihub->next = hub->next;
                        return ERROR_OK;
@@ -447,7 +448,7 @@ static int ipdbg_polling_callback(void *priv)
 
        /* transfer dn buffers to jtag-hub */
        unsigned int num_transfers = 0;
-       for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) {
+       for (size_t tool = 0; tool < hub->max_tools; ++tool) {
                struct connection *conn = hub->connections[tool];
                if (conn && conn->priv) {
                        struct ipdbg_connection *connection = conn->priv;
@@ -475,7 +476,7 @@ static int ipdbg_polling_callback(void *priv)
        }
 
        /* write from up fifos to sockets */
-       for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) {
+       for (size_t tool = 0; tool < hub->max_tools; ++tool) {
                struct connection *conn = hub->connections[tool];
                if (conn && conn->priv) {
                        struct ipdbg_connection *connection = conn->priv;
@@ -695,6 +696,8 @@ COMMAND_HANDLER(handle_ipdbg_command)
        uint32_t virtual_ir_length = 5;
        uint32_t virtual_ir_value = 0x11;
        struct ipdbg_virtual_ir_info *virtual_ir = NULL;
+       int pld_dev_id;
+       int user_num = 1;
 
        if ((CMD_ARGC < IPDBG_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > 
IPDBG_MAX_NUM_OF_OPTIONS))
                return ERROR_COMMAND_SYNTAX_ERROR;
@@ -721,6 +724,28 @@ COMMAND_HANDLER(handle_ipdbg_command)
                                                        IPDBG_MIN_DR_LENGTH, 
IPDBG_MAX_DR_LENGTH);
                                return ERROR_FAIL;
                        }
+               } else if (strcmp(CMD_ARGV[i], "-pld") == 0) {
+                       COMMAND_PARSE_ADDITIONAL_NUMBER(int, i, pld_dev_id, 
"choose pld driver instance");
+                       COMMAND_PARSE_OPTIONAL_NUMBER(int, i, user_num);
+                       struct pld_device *device = 
get_pld_device_by_num(pld_dev_id);
+                       if (!device || !device->driver) {
+                               command_print(CMD, "pld device '#%s' is out of 
bounds", CMD_ARGV[i + 1]);
+                               return ERROR_FAIL;
+                       }
+                       struct pld_ipdbg_hub pld_hub;
+                       struct pld_driver *driver = device->driver;
+                       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;
+
                } 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);

-- 

Reply via email to