Merge pull request #757 from UweBonnes/hosted

Hosted/Firmware: Fix Jtag high level #756
This commit is contained in:
UweBonnes 2020-10-16 20:11:12 +02:00 committed by GitHub
commit 1d707efa47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 155 additions and 77 deletions

View File

@ -45,6 +45,5 @@ bool platform_srst_get_val(void);
bool platform_target_get_power(void);
void platform_target_set_power(bool power);
void platform_request_boot(void);
#endif

View File

@ -336,8 +336,7 @@ static void remote_ap_mem_write_sized(
void remote_adiv5_dp_defaults(ADIv5_DP_t *dp)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, "%s",
REMOTE_HL_CHECK_STR);
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_HL_CHECK_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
@ -345,6 +344,17 @@ void remote_adiv5_dp_defaults(ADIv5_DP_t *dp)
"Please update BMP firmware for substantial speed increase!\n");
return;
}
if (dp->dp_jd_index < JTAG_MAX_DEVS) {
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_HL_JTAG_DEV_STR,
dp->dp_jd_index);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] != REMOTE_RESP_OK)) {
DEBUG_WARN(
"Please update BMP firmware to allow high level jtag commands!\n");
return;
}
}
dp->low_access = remote_adiv5_low_access;
dp->dp_read = remote_adiv5_dp_read;
dp->ap_write = remote_adiv5_ap_write;
@ -352,3 +362,20 @@ void remote_adiv5_dp_defaults(ADIv5_DP_t *dp)
dp->mem_read = remote_ap_mem_read;
dp->mem_write_sized = remote_ap_mem_write_sized;
}
void remote_add_jtag_dev(int i, const jtag_dev_t *jtag_dev)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,
REMOTE_JTAG_ADD_DEV_STR,
i,
jtag_dev->dr_prescan,
jtag_dev->dr_postscan,
jtag_dev->ir_len,
jtag_dev->ir_prescan,
jtag_dev->ir_postscan,
jtag_dev->current_ir);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
/* No check for error here. Done in remote_adiv5_dp_defaults!*/
}

View File

@ -39,5 +39,6 @@ void remote_srst_set_val(bool assert);
bool remote_srst_get_val(void);
const char *platform_target_voltage(void);
void remote_adiv5_dp_defaults(ADIv5_DP_t *dp);
void remote_add_jtag_dev(int i, const jtag_dev_t *jtag_dev);
#define __BMP_REMOTE_H_
#endif

View File

@ -339,8 +339,7 @@ uint32_t dap_read_reg(ADIv5_DP_t *dp, uint8_t reg)
{
uint8_t buf[8];
uint8_t dap_index = 0;
if (dp->dev)
dap_index = dp->dev->dev;
dap_index = dp->dp_jd_index;
buf[0] = ID_DAP_TRANSFER;
buf[1] = dap_index;
buf[2] = 0x01; // Request size
@ -358,8 +357,7 @@ void dap_write_reg(ADIv5_DP_t *dp, uint8_t reg, uint32_t data)
buf[0] = ID_DAP_TRANSFER;
uint8_t dap_index = 0;
if (dp->dev)
dap_index = dp->dev->dev;
dap_index = dp->dp_jd_index;
buf[1] = dap_index;
buf[2] = 0x01; // Request size
buf[3] = reg & ~DAP_TRANSFER_RnW;;
@ -390,8 +388,7 @@ unsigned int dap_read_block(ADIv5_AP_t *ap, void *dest, uint32_t src,
uint8_t buf[1024];
unsigned int sz = len >> align;
uint8_t dap_index = 0;
if (ap->dp->dev)
dap_index = ap->dp->dev->dev;
dap_index = ap->dp->dp_jd_index;
buf[0] = ID_DAP_TRANSFER_BLOCK;
buf[1] = dap_index;
buf[2] = sz & 0xff;
@ -426,8 +423,7 @@ unsigned int dap_write_block(ADIv5_AP_t *ap, uint32_t dest, const void *src,
uint8_t buf[1024];
unsigned int sz = len >> align;
uint8_t dap_index = 0;
if (ap->dp->dev)
dap_index = ap->dp->dev->dev;
dap_index = ap->dp->dp_jd_index;
buf[0] = ID_DAP_TRANSFER_BLOCK;
buf[1] = dap_index;
buf[2] = sz & 0xff;
@ -527,8 +523,7 @@ static uint8_t *mem_access_setup(ADIv5_AP_t *ap, uint8_t *p,
break;
}
uint8_t dap_index = 0;
if (ap->dp->dev)
dap_index = ap->dp->dev->dev;
dap_index = ap->dp->dp_jd_index;
*p++ = ID_DAP_TRANSFER;
*p++ = dap_index;
*p++ = 3; /* Nr transfers */
@ -563,8 +558,7 @@ uint32_t dap_ap_read(ADIv5_AP_t *ap, uint16_t addr)
uint8_t buf[63], *p = buf;
buf[0] = ID_DAP_TRANSFER;
uint8_t dap_index = 0;
if (ap->dp->dev)
dap_index = ap->dp->dev->dev;
dap_index = ap->dp->dp_jd_index;
*p++ = ID_DAP_TRANSFER;
*p++ = dap_index;
*p++ = 2; /* Nr transfers */
@ -584,8 +578,7 @@ void dap_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value)
DEBUG_PROBE("dap_ap_write addr %04x value %08x\n", addr, value);
uint8_t buf[63], *p = buf;
uint8_t dap_index = 0;
if (ap->dp->dev)
dap_index = ap->dp->dev->dev;
dap_index = ap->dp->dp_jd_index;
*p++ = ID_DAP_TRANSFER;
*p++ = dap_index;
*p++ = 2; /* Nr transfers */

View File

@ -392,6 +392,12 @@ int platform_swdptap_init(void)
return -1;
}
void platform_add_jtag_dev(int i, const jtag_dev_t *jtag_dev)
{
if (info.bmp_type == BMP_TYPE_BMP)
remote_add_jtag_dev(i, jtag_dev);
}
int platform_jtag_scan(const uint8_t *lrlens)
{
switch (info.bmp_type) {

View File

@ -1041,13 +1041,13 @@ int jtag_scan_stlinkv2(bmp_info_t *info, const uint8_t *irlens)
jtag_dev_count = stlink_read_idcodes(info, idcodes);
/* Check for known devices and handle accordingly */
for(int i = 0; i < jtag_dev_count; i++)
jtag_devs[i].idcode = idcodes[i];
jtag_devs[i].jd_idcode = idcodes[i];
for(int i = 0; i < jtag_dev_count; i++)
for(int j = 0; dev_descr[j].idcode; j++)
if((jtag_devs[i].idcode & dev_descr[j].idmask) ==
if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) ==
dev_descr[j].idcode) {
if(dev_descr[j].handler)
dev_descr[j].handler(&jtag_devs[i]);
dev_descr[j].handler(i, dev_descr[j].idcode);
break;
}

View File

@ -126,12 +126,10 @@ static void _respondS(char respCode, const char *s)
}
static ADIv5_DP_t remote_dp = {
.dp_read = firmware_swdp_read,
.ap_read = firmware_ap_read,
.ap_write = firmware_ap_write,
.mem_read = firmware_mem_read,
.mem_write_sized = firmware_mem_write_sized,
.low_access = firmware_swdp_low_access,
};
@ -142,8 +140,10 @@ void remotePacketProcessSWD(uint8_t i, char *packet)
bool badParity;
switch (packet[1]) {
case REMOTE_INIT: /* SS = initialise ================================= */
case REMOTE_INIT: /* SS = initialise =============================== */
if (i==2) {
remote_dp.dp_read = firmware_swdp_read;
remote_dp.low_access = firmware_swdp_low_access;
swdptap_init();
_respond(REMOTE_RESP_OK, 0);
} else {
@ -151,26 +151,26 @@ void remotePacketProcessSWD(uint8_t i, char *packet)
}
break;
case REMOTE_IN_PAR: /* = In parity ================================== */
case REMOTE_IN_PAR: /* SI = In parity ============================= */
ticks=remotehston(2,&packet[2]);
badParity = swd_proc.swdptap_seq_in_parity(&param, ticks);
_respond(badParity?REMOTE_RESP_PARERR:REMOTE_RESP_OK,param);
break;
case REMOTE_IN: /* = In ========================================= */
case REMOTE_IN: /* Si = In ======================================= */
ticks=remotehston(2,&packet[2]);
param = swd_proc.swdptap_seq_in(ticks);
_respond(REMOTE_RESP_OK,param);
break;
case REMOTE_OUT: /* = Out ======================================== */
case REMOTE_OUT: /* So= Out ====================================== */
ticks=remotehston(2,&packet[2]);
param=remotehston(-1, &packet[4]);
swd_proc.swdptap_seq_out(param, ticks);
_respond(REMOTE_RESP_OK, 0);
break;
case REMOTE_OUT_PAR: /* = Out parity ================================= */
case REMOTE_OUT_PAR: /* SO = Out parity ========================== */
ticks=remotehston(2,&packet[2]);
param=remotehston(-1, &packet[4]);
swd_proc.swdptap_seq_out_parity(param, ticks);
@ -189,21 +189,21 @@ void remotePacketProcessJTAG(uint8_t i, char *packet)
uint64_t DO;
uint8_t ticks;
uint64_t DI;
jtag_dev_t jtag_dev;
switch (packet[1]) {
case REMOTE_INIT: /* = initialise ================================= */
jtagtap_init();
case REMOTE_INIT: /* JS = initialise ============================= */
remote_dp.dp_read = fw_adiv5_jtagdp_read;
remote_dp.low_access = fw_adiv5_jtagdp_low_access;
jtagtap_init();
_respond(REMOTE_RESP_OK, 0);
break;
case REMOTE_RESET: /* = reset ================================= */
case REMOTE_RESET: /* JR = reset ================================= */
jtag_proc.jtagtap_reset();
_respond(REMOTE_RESP_OK, 0);
break;
case REMOTE_TMS: /* = TMS Sequence ================================== */
case REMOTE_TMS: /* JT = TMS Sequence ============================ */
ticks=remotehston(2,&packet[2]);
MS=remotehston(2,&packet[4]);
@ -215,7 +215,7 @@ void remotePacketProcessJTAG(uint8_t i, char *packet)
}
break;
case REMOTE_TDITDO_TMS: /* = TDI/TDO ========================================= */
case REMOTE_TDITDO_TMS: /* JD = TDI/TDO ========================================= */
case REMOTE_TDITDO_NOTMS:
if (i<5) {
@ -232,7 +232,7 @@ void remotePacketProcessJTAG(uint8_t i, char *packet)
}
break;
case REMOTE_NEXT: /* = NEXT ======================================== */
case REMOTE_NEXT: /* JN = NEXT ======================================== */
if (i!=4) {
_respond(REMOTE_RESP_ERR,REMOTE_ERROR_WRONGLEN);
} else {
@ -241,6 +241,23 @@ void remotePacketProcessJTAG(uint8_t i, char *packet)
}
break;
case REMOTE_ADD_JTAG_DEV: /* JJ = fill firmware jtag_devs */
if (i < 22) {
_respond(REMOTE_RESP_ERR,REMOTE_ERROR_WRONGLEN);
} else {
memset(&jtag_dev, 0, sizeof(jtag_dev));
uint8_t index = remotehston(2, &packet[ 2]);
jtag_dev.dr_prescan = remotehston(2, &packet[ 4]);
jtag_dev.dr_postscan = remotehston(2, &packet[ 6]);
jtag_dev.ir_len = remotehston(2, &packet[ 8]);
jtag_dev.ir_prescan = remotehston(2, &packet[10]);
jtag_dev.ir_postscan = remotehston(2, &packet[12]);
jtag_dev.current_ir = remotehston(8, &packet[14]);
jtag_add_device(index, &jtag_dev);
_respond(REMOTE_RESP_OK, 0);
}
break;
default:
_respond(REMOTE_RESP_ERR,REMOTE_ERROR_UNRECOGNISED);
break;
@ -309,16 +326,24 @@ void remotePacketProcessHL(uint8_t i, char *packet)
remote_ap.apsel = remotehston(2, packet);
remote_ap.dp = &remote_dp;
switch (index) {
case REMOTE_HL_CHECK:
case REMOTE_HL_CHECK: /* HC = Check availability of HL commands*/
_respond(REMOTE_RESP_OK, 0);
break;
case REMOTE_DP_READ:
case REMOTE_HL_JTAG_DEV: /* HJ for jtag device to use */
if (i < 4) {
_respond(REMOTE_RESP_ERR,REMOTE_ERROR_WRONGLEN);
} else {
remote_dp.dp_jd_index = remotehston(2, &packet[2]);
_respond(REMOTE_RESP_OK, 0);
}
break;
case REMOTE_DP_READ: /* Hd = Read from DP register */
packet += 2;
uint16_t addr16 = remotehston(4, packet);
uint32_t data = adiv5_dp_read(&remote_dp, addr16);
_respond_buf(REMOTE_RESP_OK, (uint8_t*)&data, 4);
break;
case REMOTE_LOW_ACCESS:
case REMOTE_LOW_ACCESS: /* HL = Low level access */
packet += 2;
addr16 = remotehston(4, packet);
packet += 4;
@ -326,13 +351,13 @@ void remotePacketProcessHL(uint8_t i, char *packet)
data = remote_dp.low_access(&remote_dp, remote_ap.apsel, addr16, value);
_respond_buf(REMOTE_RESP_OK, (uint8_t*)&data, 4);
break;
case REMOTE_AP_READ:
case REMOTE_AP_READ: /* Ha = Read from AP register*/
packet += 2;
addr16 = remotehston(4, packet);
data = adiv5_ap_read(&remote_ap, addr16);
_respond_buf(REMOTE_RESP_OK, (uint8_t*)&data, 4);
break;
case REMOTE_AP_WRITE:
case REMOTE_AP_WRITE: /* Ha = Write to AP register*/
packet += 2;
addr16 = remotehston(4, packet);
packet += 4;
@ -340,12 +365,12 @@ void remotePacketProcessHL(uint8_t i, char *packet)
adiv5_ap_write(&remote_ap, addr16, value);
_respond(REMOTE_RESP_OK, 0);
break;
case REMOTE_AP_MEM_READ:
case REMOTE_AP_MEM_READ: /* HM = Read from Mem and set csw */
packet += 2;
remote_ap.csw = remotehston(8, packet);
packet += 6;
/*fall through*/
case REMOTE_MEM_READ:
case REMOTE_MEM_READ: /* Hh = Read from Mem */
packet += 2;
uint32_t address = remotehston(8, packet);
packet += 8;
@ -359,12 +384,12 @@ void remotePacketProcessHL(uint8_t i, char *packet)
_respond(REMOTE_RESP_ERR, 0);
remote_ap.dp->fault = 0;
break;
case REMOTE_AP_MEM_WRITE_SIZED:
case REMOTE_AP_MEM_WRITE_SIZED: /* Hm = Write to memory and set csw */
packet += 2;
remote_ap.csw = remotehston(8, packet);
packet += 6;
/*fall through*/
case REMOTE_MEM_WRITE_SIZED:
case REMOTE_MEM_WRITE_SIZED: /* HH = Write to memory*/
packet += 2;
enum align align = remotehston(2, packet);
packet += 2;

View File

@ -76,6 +76,7 @@
#define REMOTE_VOLTAGE 'V'
#define REMOTE_SRST_SET 'Z'
#define REMOTE_SRST_GET 'z'
#define REMOTE_ADD_JTAG_DEV 'J'
/* Protocol response options */
#define REMOTE_RESP_OK 'K'
@ -85,6 +86,7 @@
/* High level protocol elements */
#define REMOTE_HL_CHECK 'C'
#define REMOTE_HL_JTAG_DEV 'J'
#define REMOTE_HL_PACKET 'H'
#define REMOTE_DP_READ 'd'
#define REMOTE_LOW_ACCESS 'L'
@ -137,17 +139,29 @@
#define REMOTE_JTAG_NEXT (char []){ REMOTE_SOM, REMOTE_JTAG_PACKET, REMOTE_NEXT, \
'%','c','%','c',REMOTE_EOM, 0 }
/* HL protocol elements */
#define HEX '%', '0', '2', 'x'
#define HEX_U32(x) '%', '0', '8', 'x'
#define CHR(x) '%', 'c'
#define REMOTE_JTAG_ADD_DEV_STR (char []){ REMOTE_SOM, REMOTE_JTAG_PACKET,\
REMOTE_ADD_JTAG_DEV, \
'%','0','2','x', /* index */ \
'%','0','2','x', /* dr_prescan */ \
'%','0','2','x', /* dr_postscan */ \
'%','0','2','x', /* ir_len */ \
'%','0','2','x', /* ir_prescan */ \
'%','0','2','x', /* ir_postscan */ \
HEX_U32(current_ir), /* current_ir */ \
REMOTE_EOM, 0}
#define REMOTE_HL_CHECK_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_HL_CHECK, REMOTE_EOM, 0 }
#define REMOTE_HL_JTAG_DEV_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, \
REMOTE_HL_JTAG_DEV, '%', '0', '2', 'x', REMOTE_EOM, 0 }
#define REMOTE_MEM_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_MEM_READ, \
HEX_U32(address), HEX_U32(count), REMOTE_EOM, 0 }
#define REMOTE_DP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_DP_READ, \
'f', 'f','%', '0', '4', 'x', REMOTE_EOM, 0 }
'%', '0', '4', 'x', REMOTE_EOM, 0 }
#define REMOTE_LOW_ACCESS_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_LOW_ACCESS, \
'%','0', '2', 'x', '%', '0', '4', 'x', HEX_U32(csw), REMOTE_EOM, 0 }
#define REMOTE_AP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_READ, \

View File

@ -174,15 +174,8 @@ typedef struct ADIv5_DP_s {
void (*mem_read)(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len);
void (*mem_write_sized)(ADIv5_AP_t *ap, uint32_t dest, const void *src,
size_t len, enum align align);
#if PC_HOSTED == 1
jtag_dev_t *dev;
uint8_t dp_jd_index;
uint8_t fault;
#else
union {
jtag_dev_t *dev;
uint8_t fault;
};
#endif
} ADIv5_DP_t;
struct ADIv5_AP_s {
@ -267,10 +260,12 @@ void adiv5_dp_write(ADIv5_DP_t *dp, uint16_t addr, uint32_t value);
void adiv5_dp_init(ADIv5_DP_t *dp);
void platform_adiv5_dp_defaults(ADIv5_DP_t *dp);
ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel);
void remote_jtag_dev(const jtag_dev_t *jtag_dev);
void adiv5_ap_ref(ADIv5_AP_t *ap);
void adiv5_ap_unref(ADIv5_AP_t *ap);
void platform_add_jtag_dev(const int dev_index, const jtag_dev_t *jtag_dev);
void adiv5_jtag_dp_handler(jtag_dev_t *dev);
void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode);
int platform_jtag_dp_init(ADIv5_DP_t *dp);
void adiv5_mem_write(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len);

View File

@ -41,7 +41,7 @@ static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp);
static void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort);
void adiv5_jtag_dp_handler(jtag_dev_t *dev)
void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode)
{
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (!dp) { /* calloc failed: heap exhaustion */
@ -49,9 +49,9 @@ void adiv5_jtag_dp_handler(jtag_dev_t *dev)
return;
}
dp->dev = dev;
dp->dp_jd_index = jd_index;
if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) {
dp->idcode = dev->idcode;
dp->idcode = j_idcode;
dp->dp_read = fw_adiv5_jtagdp_read;
dp->error = adiv5_jtagdp_error;
dp->low_access = fw_adiv5_jtagdp_low_access;
@ -85,11 +85,11 @@ uint32_t fw_adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
request = ((uint64_t)value << 3) | ((addr >> 1) & 0x06) | (RnW?1:0);
jtag_dev_write_ir(&jtag_proc, dp->dev, APnDP ? IR_APACC : IR_DPACC);
jtag_dev_write_ir(&jtag_proc, dp->dp_jd_index, APnDP ? IR_APACC : IR_DPACC);
platform_timeout_set(&timeout, 2000);
do {
jtag_dev_shift_dr(&jtag_proc, dp->dev, (uint8_t*)&response,
jtag_dev_shift_dr(&jtag_proc, dp->dp_jd_index, (uint8_t*)&response,
(uint8_t*)&request, 35);
ack = response & 0x07;
} while(!platform_timeout_is_expired(&timeout) && (ack == JTAGDP_ACK_WAIT));
@ -106,6 +106,6 @@ uint32_t fw_adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
static void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort)
{
uint64_t request = (uint64_t)abort << 3;
jtag_dev_write_ir(&jtag_proc, dp->dev, IR_ABORT);
jtag_dev_shift_dr(&jtag_proc, dp->dev, NULL, (const uint8_t*)&request, 35);
jtag_dev_write_ir(&jtag_proc, dp->dp_jd_index, IR_ABORT);
jtag_dev_shift_dr(&jtag_proc, dp->dp_jd_index, NULL, (const uint8_t*)&request, 35);
}

View File

@ -39,6 +39,7 @@ int adiv5_swdp_scan(void)
target_list_free();
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
dp->dp_jd_index = JTAG_MAX_DEVS; /* Tag for BMP_REMOTE */
if (!dp) { /* calloc failed: heap exhaustion */
DEBUG_WARN("calloc: failed in %s\n", __func__);
return -1;

View File

@ -22,7 +22,7 @@ typedef const struct jtag_dev_descr_s {
const uint32_t idcode;
const uint32_t idmask;
const char * const descr;
void (*const handler)(jtag_dev_t *dev);
void (*const handler)(uint8_t jd_index, uint32_t j_idcode);
} jtag_dev_descr_t;
extern jtag_dev_descr_t dev_descr[];

View File

@ -36,6 +36,16 @@ int jtag_dev_count;
/* bucket of ones for don't care TDI */
static const uint8_t ones[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
#if PC_HOSTED == 0
void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev)
{
if (dev_index == 0)
memset(&jtag_devs, 0, sizeof(jtag_devs));
memcpy(&jtag_devs[dev_index], jtag_dev, sizeof(jtag_dev_t));
jtag_dev_count = dev_index + 1;
}
#endif
/* Scan JTAG chain for devices, store IR length and IDCODE (if present).
* Reset TAP state machine.
* Select Shift-IR state.
@ -94,7 +104,7 @@ int jtag_scan(const uint8_t *irlens)
}
jtag_devs[jtag_dev_count].ir_len = *irlens;
jtag_devs[jtag_dev_count].ir_prescan = j;
jtag_devs[jtag_dev_count].dev = jtag_dev_count;
jtag_devs[jtag_dev_count].jd_dev = jtag_dev_count;
j += *irlens;
irlens++;
jtag_dev_count++;
@ -117,7 +127,7 @@ int jtag_scan(const uint8_t *irlens)
if(jtag_devs[jtag_dev_count].ir_len == 1) break;
jtag_devs[++jtag_dev_count].ir_len = 1;
jtag_devs[jtag_dev_count].ir_prescan = j;
jtag_devs[jtag_dev_count].dev = jtag_dev_count;
jtag_devs[jtag_dev_count].jd_dev = jtag_dev_count;
} else jtag_devs[jtag_dev_count].ir_len++;
j++;
}
@ -169,34 +179,40 @@ int jtag_scan(const uint8_t *irlens)
jtagtap_shift_dr();
for(i = 0; i < jtag_dev_count; i++) {
if(!jtag_proc.jtagtap_next(0, 1)) continue;
jtag_devs[i].idcode = 1;
jtag_devs[i].jd_idcode = 1;
for(j = 2; j; j <<= 1)
if(jtag_proc.jtagtap_next(0, 1)) jtag_devs[i].idcode |= j;
if(jtag_proc.jtagtap_next(0, 1)) jtag_devs[i].jd_idcode |= j;
}
DEBUG_INFO("Return to Run-Test/Idle\n");
jtag_proc.jtagtap_next(1, 1);
jtagtap_return_idle();
#if PC_HOSTED == 1
/*Transfer needed device information to firmware jtag_devs*/
for(i = 0; i < jtag_dev_count; i++)
platform_add_jtag_dev(i, &jtag_devs[i]);
#endif
/* Check for known devices and handle accordingly */
for(i = 0; i < jtag_dev_count; i++)
for(j = 0; dev_descr[j].idcode; j++)
if((jtag_devs[i].idcode & dev_descr[j].idmask) ==
if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) ==
dev_descr[j].idcode) {
jtag_devs[i].current_ir = -1;
/* Save description in table */
jtag_devs[i].descr = dev_descr[j].descr;
jtag_devs[i].jd_descr = dev_descr[j].descr;
/* Call handler to initialise/probe device further */
if(dev_descr[j].handler)
dev_descr[j].handler(&jtag_devs[i]);
dev_descr[j].handler(i, dev_descr[j].idcode);
break;
}
return jtag_dev_count;
}
void jtag_dev_write_ir(jtag_proc_t *jp, jtag_dev_t *d, uint32_t ir)
void jtag_dev_write_ir(jtag_proc_t *jp, uint8_t jd_index, uint32_t ir)
{
jtag_dev_t *d = &jtag_devs[jd_index];
if(ir == d->current_ir) return;
for(int i = 0; i < jtag_dev_count; i++)
jtag_devs[i].current_ir = -1;
@ -209,8 +225,9 @@ void jtag_dev_write_ir(jtag_proc_t *jp, jtag_dev_t *d, uint32_t ir)
jtagtap_return_idle();
}
void jtag_dev_shift_dr(jtag_proc_t *jp, jtag_dev_t *d, uint8_t *dout, const uint8_t *din, int ticks)
void jtag_dev_shift_dr(jtag_proc_t *jp, uint8_t jd_index, uint8_t *dout, const uint8_t *din, int ticks)
{
jtag_dev_t *d = &jtag_devs[jd_index];
jtagtap_shift_dr();
jp->jtagtap_tdi_seq(0, ones, d->dr_prescan);
if(dout)

View File

@ -27,7 +27,7 @@
typedef struct jtag_dev_s {
union {
uint8_t dev;
uint8_t jd_dev;
uint8_t dr_prescan;
};
uint8_t dr_postscan;
@ -35,16 +35,16 @@ typedef struct jtag_dev_s {
uint8_t ir_len;
uint8_t ir_prescan;
uint8_t ir_postscan;
uint32_t idcode;
const char *descr;
uint32_t jd_idcode;
const char *jd_descr;
uint32_t current_ir;
} jtag_dev_t;
extern struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1];
extern int jtag_dev_count;
void jtag_dev_write_ir(jtag_proc_t *jp, jtag_dev_t *dev, uint32_t ir);
void jtag_dev_shift_dr(jtag_proc_t *jp, jtag_dev_t *dev, uint8_t *dout, const uint8_t *din, int ticks);
void jtag_dev_write_ir(jtag_proc_t *jp, uint8_t jd_index, uint32_t ir);
void jtag_dev_shift_dr(jtag_proc_t *jp, uint8_t jd_index, uint8_t *dout, const uint8_t *din, int ticks);
void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev);
#endif