ipdbg/pld: ipdbg can get tap and hub/ir from pld driver.
To start a ipdbg server one needs to know the tap and the instruction code to reach the IPDBG-Hub. This instruction is vendor/family specific. Knowledge which can be provided by the pld driver. Change-Id: I13eeb9fee895d65cd48544da4704fcc9b528b869 Signed-off-by: Daniel Anselmi <danselmi@gmx.ch> Reviewed-on: https://review.openocd.org/c/openocd/+/7369 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
committed by
Antonio Borneo
parent
373d7eaa70
commit
a27907aed1
+79
-1
@@ -16,13 +16,29 @@
|
||||
|
||||
#define PROGRAM 0x4
|
||||
#define ENTERUSER 0x7
|
||||
#define USER1 0x8
|
||||
#define USER2 0x9
|
||||
#define USER3 0xa
|
||||
#define USER4 0xb
|
||||
|
||||
enum efinix_family_e {
|
||||
EFINIX_TRION,
|
||||
EFINIX_TITANIUM,
|
||||
EFINIX_UNKNOWN
|
||||
};
|
||||
|
||||
#define TRAILING_ZEROS 4000
|
||||
#define RUNTEST_START_CYCLES 100
|
||||
#define RUNTEST_FINISH_CYCLES 100
|
||||
|
||||
struct efinix_device {
|
||||
uint32_t idcode;
|
||||
int num_user;
|
||||
};
|
||||
|
||||
struct efinix_pld_device {
|
||||
struct jtag_tap *tap;
|
||||
enum efinix_family_e family;
|
||||
};
|
||||
|
||||
static int efinix_read_bit_file(struct raw_bit_file *bit_file, const char *filename)
|
||||
@@ -188,9 +204,54 @@ static int efinix_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 efinix_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 (pld_device_info->family == EFINIX_UNKNOWN) {
|
||||
LOG_ERROR("family unknown, please specify for 'pld create'");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
int num_user = 2; /* trion */
|
||||
if (pld_device_info->family == EFINIX_TITANIUM)
|
||||
num_user = 4;
|
||||
|
||||
if (user_num > num_user) {
|
||||
LOG_ERROR("Devices has only user register 1 to %d", num_user);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
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 %d", num_user);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
PLD_CREATE_COMMAND_HANDLER(efinix_pld_create_command)
|
||||
{
|
||||
if (CMD_ARGC != 4)
|
||||
if (CMD_ARGC != 4 && CMD_ARGC != 6)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
|
||||
@@ -202,12 +263,28 @@ PLD_CREATE_COMMAND_HANDLER(efinix_pld_create_command)
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
enum efinix_family_e family = EFINIX_UNKNOWN;
|
||||
if (CMD_ARGC == 6) {
|
||||
if (strcmp(CMD_ARGV[4], "-family") != 0)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
if (strcmp(CMD_ARGV[5], "trion") == 0) {
|
||||
family = EFINIX_TRION;
|
||||
} else if (strcmp(CMD_ARGV[5], "titanium") == 0) {
|
||||
family = EFINIX_TITANIUM;
|
||||
} else {
|
||||
command_print(CMD, "unknown family");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
struct efinix_pld_device *efinix_info = malloc(sizeof(struct efinix_pld_device));
|
||||
if (!efinix_info) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
efinix_info->tap = tap;
|
||||
efinix_info->family = family;
|
||||
|
||||
pld->driver_priv = efinix_info;
|
||||
|
||||
@@ -218,4 +295,5 @@ struct pld_driver efinix_pld = {
|
||||
.name = "efinix",
|
||||
.pld_create_command = &efinix_pld_create_command,
|
||||
.load = &efinix_load,
|
||||
.get_ipdbg_hub = efinix_get_ipdbg_hub,
|
||||
};
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#define ERASE_FLASH 0x75
|
||||
#define ENABLE_2ND_FLASH 0x78
|
||||
|
||||
#define USER1 0x42
|
||||
#define USER2 0x43
|
||||
|
||||
#define STAUS_MASK_MEMORY_ERASE BIT(5)
|
||||
#define STAUS_MASK_SYSTEM_EDIT_MODE BIT(7)
|
||||
|
||||
@@ -449,6 +452,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)
|
||||
{
|
||||
if (CMD_ARGC != 1)
|
||||
@@ -568,4 +594,5 @@ struct pld_driver gowin_pld = {
|
||||
.commands = gowin_command_handler,
|
||||
.pld_create_command = &gowin_pld_create_command,
|
||||
.load = &gowin_load_to_sram,
|
||||
.get_ipdbg_hub = gowin_get_ipdbg_hub,
|
||||
};
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "raw_bit.h"
|
||||
|
||||
#define BYPASS 0x3FF
|
||||
#define USER0 0x00C
|
||||
#define USER1 0x00E
|
||||
|
||||
enum intel_family_e {
|
||||
INTEL_CYCLONEIII,
|
||||
@@ -337,6 +339,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 == 0) {
|
||||
hub->user_ir_code = USER0;
|
||||
} else if (user_num == 1) {
|
||||
hub->user_ir_code = USER1;
|
||||
} else {
|
||||
LOG_ERROR("intel devices only have user register 0 & 1");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(intel_set_bscan_command_handler)
|
||||
{
|
||||
unsigned int boundary_scan_length;
|
||||
@@ -472,4 +497,5 @@ struct pld_driver intel_pld = {
|
||||
.commands = intel_command_handler,
|
||||
.pld_create_command = &intel_pld_create_command,
|
||||
.load = &intel_load,
|
||||
.get_ipdbg_hub = intel_get_ipdbg_hub,
|
||||
};
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
#include "certus.h"
|
||||
|
||||
#define PRELOAD 0x1C
|
||||
#define USER1 0x32
|
||||
#define USER2 0x38
|
||||
|
||||
|
||||
struct lattice_devices_elem {
|
||||
uint32_t id;
|
||||
@@ -316,6 +319,29 @@ static int lattice_load_command(struct pld_device *pld_device, const char *filen
|
||||
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;
|
||||
}
|
||||
|
||||
PLD_CREATE_COMMAND_HANDLER(lattice_pld_create_command)
|
||||
{
|
||||
if (CMD_ARGC != 4 && CMD_ARGC != 6)
|
||||
@@ -524,4 +550,5 @@ struct pld_driver lattice_pld = {
|
||||
.commands = lattice_command_handler,
|
||||
.pld_create_command = &lattice_pld_create_command,
|
||||
.load = &lattice_load_command,
|
||||
.get_ipdbg_hub = lattice_get_ipdbg_hub,
|
||||
};
|
||||
|
||||
@@ -15,11 +15,17 @@ struct pld_device;
|
||||
#define __PLD_CREATE_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_CREATE_COMMAND((*pld_create_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_CREATE_COMMAND_HANDLER(name) \
|
||||
|
||||
@@ -306,6 +306,26 @@ COMMAND_HANDLER(virtex2_handle_read_stat_command)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int xilinx_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;
|
||||
if (user_num < 1 || (unsigned int)user_num > pld_device_info->command_set.num_user) {
|
||||
LOG_ERROR("device has only user register 1 to %d", pld_device_info->command_set.num_user);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
hub->user_ir_code = pld_device_info->command_set.user[user_num - 1];
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(virtex2_handle_set_instuction_codes_command)
|
||||
{
|
||||
if (CMD_ARGC < 6 || CMD_ARGC > (6 + VIRTEX2_MAX_USER_INSTRUCTIONS))
|
||||
@@ -439,4 +459,5 @@ struct pld_driver virtex2_pld = {
|
||||
.commands = virtex2_command_handler,
|
||||
.pld_create_command = &virtex2_pld_create_command,
|
||||
.load = &virtex2_load,
|
||||
.get_ipdbg_hub = xilinx_get_ipdbg_hub,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user