bmp_remote: Use high level functions.
Based on #570 (OpenOCD HLA interface driver for Blackmagic), but now usefull for bmp-remote.
This commit is contained in:
parent
921c23eb74
commit
b06c0ba8d5
|
@ -24,6 +24,8 @@
|
|||
# error "Include 'general.h' instead"
|
||||
#endif
|
||||
|
||||
#include "target.h"
|
||||
|
||||
#if PC_HOSTED == 1
|
||||
void platform_init(int argc, char **argv);
|
||||
#else
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "remote.h"
|
||||
#include "target.h"
|
||||
#include "bmp_remote.h"
|
||||
#include "cl_utils.h"
|
||||
#include "hex_utils.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -35,7 +37,7 @@
|
|||
|
||||
#include "adiv5.h"
|
||||
|
||||
int remote_init(void)
|
||||
int remote_init(bool verbose)
|
||||
{
|
||||
char construct[REMOTE_MAX_MSG_SIZE];
|
||||
int c = snprintf(construct, REMOTE_MAX_MSG_SIZE, "%s", REMOTE_START_STR);
|
||||
|
@ -47,8 +49,19 @@ int remote_init(void)
|
|||
c ? (char *)&(construct[1]) : "unknown");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Remote is %s\n", &construct[1]);
|
||||
if (verbose)
|
||||
printf("Remote is %s\n", &construct[1]);
|
||||
char *p = strstr(&construct[1], "(Firmware v");
|
||||
if (!p)
|
||||
return -1;
|
||||
int major = 0, minor = 0, step = 0;
|
||||
int res = sscanf(p, "(Firmware v%d.%d.%d", &major, &minor, &step);
|
||||
if (res !=3)
|
||||
return -1;
|
||||
uint32_t version = major * 10000 + minor * 100 + step;
|
||||
/* check that firmare is > 1.6.1 */
|
||||
if (version < 10602)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -145,3 +158,216 @@ const char *remote_target_voltage(void)
|
|||
}
|
||||
return (char *)&construct[1];
|
||||
}
|
||||
|
||||
static uint32_t remote_adiv5_dp_read(ADIv5_DP_t *dp, uint16_t addr)
|
||||
{
|
||||
(void)dp;
|
||||
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_DP_READ_STR,
|
||||
addr);
|
||||
platform_buffer_write(construct, s);
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||
printf("%s error %d\n", __func__, s);
|
||||
}
|
||||
uint32_t dest[1];
|
||||
unhexify(dest, (const char*)&construct[1], 4);
|
||||
if (cl_debuglevel & BMP_DEBUG_PLATFORM)
|
||||
printf("dp_read @ %04x: 0x%08" PRIx32 "\n", addr, dest[0]);
|
||||
return dest[0];
|
||||
}
|
||||
|
||||
static uint32_t remote_adiv5_low_access(ADIv5_DP_t *dp, uint8_t RnW, uint16_t addr, uint32_t value)
|
||||
{
|
||||
(void)dp;
|
||||
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_LOW_ACCESS_STR,
|
||||
RnW, addr, value);
|
||||
if (cl_debuglevel & BMP_DEBUG_PLATFORM)
|
||||
printf("Dp_write @ %04x: 0x%08" PRIx32 "\n", addr, value);
|
||||
platform_buffer_write(construct, s);
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||
printf("%s error %d\n", __func__, s);
|
||||
}
|
||||
uint32_t dest[1];
|
||||
unhexify(dest, (const char*)&construct[1], 4);
|
||||
if (cl_debuglevel & BMP_DEBUG_PLATFORM)
|
||||
printf("dp_read @ %04x: 0x%08" PRIx32 "\n", addr, dest[0]);
|
||||
return dest[0];
|
||||
}
|
||||
|
||||
static uint32_t remote_adiv5_ap_read(ADIv5_AP_t *ap, uint16_t addr)
|
||||
{
|
||||
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_AP_READ_STR,
|
||||
ap->apsel, addr);
|
||||
platform_buffer_write(construct, s);
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||
printf("%s error %d\n", __func__, s);
|
||||
}
|
||||
uint32_t dest[1];
|
||||
unhexify(dest, (const char*)&construct[1], 4);
|
||||
if (cl_debuglevel & BMP_DEBUG_PLATFORM)
|
||||
printf("ap_read @ %04x: 0x%08" PRIx32 "\n", addr, dest[0]);
|
||||
return dest[0];
|
||||
}
|
||||
|
||||
static void remote_adiv5_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value)
|
||||
{
|
||||
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_AP_WRITE_STR,
|
||||
ap->apsel, addr, value);
|
||||
if (cl_debuglevel & BMP_DEBUG_PLATFORM)
|
||||
printf("ap_write @ %04x: 0x%08" PRIx32 "\n", addr, value);
|
||||
platform_buffer_write(construct, s);
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||
printf("%s error %d\n", __func__, s);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void remote_mem_read(
|
||||
ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
|
||||
{
|
||||
(void)ap;
|
||||
if (len == 0)
|
||||
return;
|
||||
if (cl_debuglevel & BMP_DEBUG_PLATFORM)
|
||||
printf("memread @ %" PRIx32 " len %ld, start: \n",
|
||||
src, len);
|
||||
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s;
|
||||
int batchsize = (REMOTE_MAX_MSG_SIZE - 32) / 2;
|
||||
while(len) {
|
||||
int count = len;
|
||||
if (count > batchsize)
|
||||
count = batchsize;
|
||||
s = snprintf(construct, REMOTE_MAX_MSG_SIZE,
|
||||
REMOTE_MEM_READ_STR, src, count);
|
||||
platform_buffer_write(construct, s);
|
||||
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((s > 0) && (construct[0] == REMOTE_RESP_OK)) {
|
||||
unhexify(dest, (const char*)&construct[1], count);
|
||||
src += count;
|
||||
dest += count;
|
||||
len -= count;
|
||||
|
||||
continue;
|
||||
} else {
|
||||
if(construct[0] == REMOTE_RESP_ERR) {
|
||||
ap->dp->fault = 1;
|
||||
printf("%s returned REMOTE_RESP_ERR at addr: 0x%08x\n",
|
||||
__func__, src);
|
||||
break;
|
||||
} else {
|
||||
printf("%s error %d\n", __func__, s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void remote_ap_mem_read(
|
||||
ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
|
||||
{
|
||||
(void)ap;
|
||||
if (len == 0)
|
||||
return;
|
||||
if (cl_debuglevel & BMP_DEBUG_PLATFORM)
|
||||
printf("ap_memread @ %" PRIx32 " len %ld\n", src, len);
|
||||
char construct[REMOTE_MAX_MSG_SIZE];
|
||||
int batchsize = (REMOTE_MAX_MSG_SIZE - 0x20) / 2;
|
||||
while(len) {
|
||||
int s;
|
||||
int count = len;
|
||||
if (count > batchsize)
|
||||
count = batchsize;
|
||||
s = snprintf(construct, REMOTE_MAX_MSG_SIZE,
|
||||
REMOTE_AP_MEM_READ_STR, ap->apsel, ap->csw, src, count);
|
||||
platform_buffer_write((uint8_t*)construct, s);
|
||||
s = platform_buffer_read((uint8_t*)construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((s > 0) && (construct[0] == REMOTE_RESP_OK)) {
|
||||
unhexify(dest, (const char*)&construct[1], count);
|
||||
src += count;
|
||||
dest += count;
|
||||
len -= count;
|
||||
continue;
|
||||
} else {
|
||||
if(construct[0] == REMOTE_RESP_ERR) {
|
||||
ap->dp->fault = 1;
|
||||
printf("%s returned REMOTE_RESP_ERR at apsel %d, "
|
||||
"addr: 0x%08" PRIx32 "\n", __func__, ap->apsel, src);
|
||||
break;
|
||||
} else {
|
||||
printf("%s error %d around 0x%08" PRIx32 "\n",
|
||||
__func__, s, src);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void remote_ap_mem_write_sized(
|
||||
ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len,
|
||||
enum align align)
|
||||
{
|
||||
(void)ap;
|
||||
if (len == 0)
|
||||
return;
|
||||
if (cl_debuglevel & BMP_DEBUG_PLATFORM)
|
||||
printf("ap_mem_write_sized @ %" PRIx32 " len %ld, align %d\n",
|
||||
dest, len, 1 << align);
|
||||
char construct[REMOTE_MAX_MSG_SIZE];
|
||||
/* (5 * 1 (char)) + (2 * 2 (bytes)) + (3 * 8 (words)) */
|
||||
int batchsize = (REMOTE_MAX_MSG_SIZE - 0x30) / 2;
|
||||
while (len) {
|
||||
int count = len;
|
||||
if (count > batchsize)
|
||||
count = batchsize;
|
||||
int s = snprintf(construct, REMOTE_MAX_MSG_SIZE,
|
||||
REMOTE_AP_MEM_WRITE_SIZED_STR,
|
||||
ap->apsel, ap->csw, align, dest, count);
|
||||
char *p = construct + s;
|
||||
hexify(p, src, count);
|
||||
p += 2 * count;
|
||||
src += count;
|
||||
dest += count;
|
||||
len -= count;
|
||||
*p++ = REMOTE_EOM;
|
||||
*p = 0;
|
||||
platform_buffer_write((uint8_t*)construct, p - construct);
|
||||
|
||||
s = platform_buffer_read((uint8_t*)construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((s > 0) && (construct[0] == REMOTE_RESP_OK))
|
||||
continue;
|
||||
if ((s > 0) && (construct[0] == REMOTE_RESP_ERR)) {
|
||||
ap->dp->fault = 1;
|
||||
printf("%s returned REMOTE_RESP_ERR at apsel %d, "
|
||||
"addr: 0x%08x\n", __func__, ap->apsel, dest);
|
||||
} else {
|
||||
printf("%s error %d around address 0x%08" PRIx32 "\n",
|
||||
__func__, s, dest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void remote_adiv5_dp_defaults(ADIv5_DP_t *dp)
|
||||
{
|
||||
if (remote_init(false)) {
|
||||
printf("Please update BMP firmware for substantial speed increase!\n");
|
||||
return;
|
||||
}
|
||||
dp->low_access = remote_adiv5_low_access;
|
||||
dp->dp_read = remote_adiv5_dp_read;
|
||||
dp->ap_write = remote_adiv5_ap_write;
|
||||
dp->ap_read = remote_adiv5_ap_read;
|
||||
dp->mem_read = remote_ap_mem_read;
|
||||
dp->mem_write_sized = remote_ap_mem_write_sized;
|
||||
}
|
||||
|
|
|
@ -20,13 +20,16 @@
|
|||
#define __BMP_REMOTE_H_
|
||||
#include "swdptap.h"
|
||||
#include "jtagtap.h"
|
||||
#include "adiv5.h"
|
||||
#include "target.h"
|
||||
#include "target_internal.h"
|
||||
|
||||
#define REMOTE_MAX_MSG_SIZE (256)
|
||||
#define REMOTE_MAX_MSG_SIZE (1024)
|
||||
|
||||
int platform_buffer_write(const uint8_t *data, int size);
|
||||
int platform_buffer_read(uint8_t *data, int size);
|
||||
|
||||
int remote_init(void);
|
||||
int remote_init(bool verbose);
|
||||
int remote_swdptap_init(swd_proc_t *swd_proc);
|
||||
int remote_jtagtap_init(jtag_proc_t *jtag_proc);
|
||||
bool remote_target_get_power(void);
|
||||
|
@ -35,5 +38,6 @@ void remote_target_set_power(bool power);
|
|||
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);
|
||||
#define __BMP_REMOTE_H_
|
||||
#endif
|
||||
|
|
|
@ -244,7 +244,7 @@ void platform_init(int argc, char **argv)
|
|||
case BMP_TYPE_BMP:
|
||||
if (serial_open(&cl_opts, info.serial))
|
||||
exit(-1);
|
||||
remote_init();
|
||||
remote_init(true);
|
||||
break;
|
||||
case BMP_TYPE_STLINKV2:
|
||||
if (stlink_init( &info))
|
||||
|
@ -367,6 +367,8 @@ int platform_jtagtap_init(void)
|
|||
void platform_adiv5_dp_defaults(ADIv5_DP_t *dp)
|
||||
{
|
||||
switch (info.bmp_type) {
|
||||
case BMP_TYPE_BMP:
|
||||
return remote_adiv5_dp_defaults(dp);
|
||||
case BMP_TYPE_STLINKV2:
|
||||
return stlink_adiv5_dp_defaults(dp);
|
||||
case BMP_TYPE_CMSIS_DAP:
|
||||
|
|
|
@ -39,7 +39,6 @@ int remote_swdptap_init(swd_proc_t *swd_proc)
|
|||
{
|
||||
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s;
|
||||
|
||||
s = sprintf((char *)construct,"%s", REMOTE_SWDP_INIT_STR);
|
||||
platform_buffer_write(construct, s);
|
||||
|
||||
|
|
142
src/remote.c
142
src/remote.c
|
@ -25,7 +25,11 @@
|
|||
#include "jtagtap.h"
|
||||
#include "gdb_if.h"
|
||||
#include "version.h"
|
||||
#include "exception.h"
|
||||
#include <stdarg.h>
|
||||
#include "target/adiv5.h"
|
||||
#include "target.h"
|
||||
#include "hex_utils.h"
|
||||
|
||||
|
||||
#define NTOH(x) ((x<=9)?x+'0':'a'+x-10)
|
||||
|
@ -57,6 +61,30 @@ uint64_t remotehston(uint32_t limit, char *s)
|
|||
}
|
||||
|
||||
#if PC_HOSTED == 0
|
||||
static void _send_buf(uint8_t* buffer, size_t len)
|
||||
{
|
||||
uint8_t* p = buffer;
|
||||
char hex[2];
|
||||
do {
|
||||
hexify(hex, (const void*)p++, 1);
|
||||
|
||||
gdb_if_putchar(hex[0], 0);
|
||||
gdb_if_putchar(hex[1], 0);
|
||||
|
||||
} while (p<(buffer+len));
|
||||
}
|
||||
|
||||
static void _respond_buf(char respCode, uint8_t* buffer, size_t len)
|
||||
{
|
||||
gdb_if_putchar(REMOTE_RESP, 0);
|
||||
gdb_if_putchar(respCode, 0);
|
||||
|
||||
_send_buf(buffer, len);
|
||||
|
||||
gdb_if_putchar(REMOTE_EOM, 1);
|
||||
}
|
||||
|
||||
|
||||
static void _respond(char respCode, uint64_t param)
|
||||
|
||||
/* Send response to far end */
|
||||
|
@ -97,6 +125,16 @@ static void _respondS(char respCode, const char *s)
|
|||
gdb_if_putchar(REMOTE_EOM,1);
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
void remotePacketProcessSWD(uint8_t i, char *packet)
|
||||
{
|
||||
uint8_t ticks;
|
||||
|
@ -155,6 +193,8 @@ void remotePacketProcessJTAG(uint8_t i, char *packet)
|
|||
switch (packet[1]) {
|
||||
case REMOTE_INIT: /* = initialise ================================= */
|
||||
jtagtap_init();
|
||||
remote_dp.dp_read = fw_adiv5_jtagdp_read;
|
||||
remote_dp.low_access = fw_adiv5_jtagdp_low_access;
|
||||
_respond(REMOTE_RESP_OK, 0);
|
||||
break;
|
||||
|
||||
|
@ -255,6 +295,104 @@ void remotePacketProcessGEN(uint8_t i, char *packet)
|
|||
}
|
||||
}
|
||||
|
||||
void remotePacketProcessHL(uint8_t i, char *packet)
|
||||
|
||||
{
|
||||
(void)i;
|
||||
SET_IDLE_STATE(0);
|
||||
|
||||
ADIv5_AP_t remote_ap;
|
||||
/* Re-use packet buffer. Align to DWORD! */
|
||||
void *src = (void *)(((uint32_t)packet + 7) & ~7);
|
||||
char index = packet[1];
|
||||
packet += 2;
|
||||
remote_ap.apsel = remotehston(2, packet);
|
||||
remote_ap.dp = &remote_dp;
|
||||
switch (index) {
|
||||
case REMOTE_DP_READ:
|
||||
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:
|
||||
packet += 2;
|
||||
addr16 = remotehston(4, packet);
|
||||
packet += 4;
|
||||
uint32_t value = remotehston(8, 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:
|
||||
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:
|
||||
packet += 2;
|
||||
addr16 = remotehston(4, packet);
|
||||
packet += 4;
|
||||
value = remotehston(8, packet);
|
||||
adiv5_ap_write(&remote_ap, addr16, value);
|
||||
_respond(REMOTE_RESP_OK, 0);
|
||||
break;
|
||||
case REMOTE_AP_MEM_READ:
|
||||
packet += 2;
|
||||
remote_ap.csw = remotehston(8, packet);
|
||||
packet += 6;
|
||||
/*fall through*/
|
||||
case REMOTE_MEM_READ:
|
||||
packet += 2;
|
||||
uint32_t address = remotehston(8, packet);
|
||||
packet += 8;
|
||||
uint32_t count = remotehston(8, packet);
|
||||
packet += 8;
|
||||
adiv5_mem_read(&remote_ap, src, address, count);
|
||||
if (remote_ap.dp->fault == 0) {
|
||||
_respond_buf(REMOTE_RESP_OK, src, count);
|
||||
break;
|
||||
}
|
||||
_respond(REMOTE_RESP_ERR, 0);
|
||||
remote_ap.dp->fault = 0;
|
||||
break;
|
||||
case REMOTE_AP_MEM_WRITE_SIZED:
|
||||
packet += 2;
|
||||
remote_ap.csw = remotehston(8, packet);
|
||||
packet += 6;
|
||||
/*fall through*/
|
||||
case REMOTE_MEM_WRITE_SIZED:
|
||||
packet += 2;
|
||||
enum align align = remotehston(2, packet);
|
||||
packet += 2;
|
||||
uint32_t dest = remotehston(8, packet);
|
||||
packet+= 8;
|
||||
size_t len = remotehston(8, packet);
|
||||
packet += 8;
|
||||
if (len & ((1 << align) - 1)) {
|
||||
/* len and align do not fit*/
|
||||
_respond(REMOTE_RESP_ERR, 0);
|
||||
break;
|
||||
}
|
||||
/* Read as stream of hexified bytes*/
|
||||
unhexify(src, packet, len);
|
||||
adiv5_mem_write_sized(&remote_ap, dest, src, len, align);
|
||||
if (remote_ap.dp->fault) {
|
||||
/* Errors handles on hosted side.*/
|
||||
_respond(REMOTE_RESP_ERR, 0);
|
||||
remote_ap.dp->fault = 0;
|
||||
break;
|
||||
}
|
||||
_respond_buf(REMOTE_RESP_OK, src, len);
|
||||
break;
|
||||
default:
|
||||
_respond(REMOTE_RESP_ERR,REMOTE_ERROR_UNRECOGNISED);
|
||||
break;
|
||||
}
|
||||
SET_IDLE_STATE(1);
|
||||
}
|
||||
|
||||
|
||||
void remotePacketProcess(uint8_t i, char *packet)
|
||||
{
|
||||
switch (packet[0]) {
|
||||
|
@ -270,6 +408,10 @@ void remotePacketProcess(uint8_t i, char *packet)
|
|||
remotePacketProcessGEN(i,packet);
|
||||
break;
|
||||
|
||||
case REMOTE_HL_PACKET:
|
||||
remotePacketProcessHL(i, packet);
|
||||
break;
|
||||
|
||||
default: /* Oh dear, unrecognised, return an error */
|
||||
_respond(REMOTE_RESP_ERR,REMOTE_ERROR_UNRECOGNISED);
|
||||
break;
|
||||
|
|
34
src/remote.h
34
src/remote.h
|
@ -83,6 +83,18 @@
|
|||
#define REMOTE_RESP_ERR 'E'
|
||||
#define REMOTE_RESP_NOTSUP 'N'
|
||||
|
||||
/* High level protocol elements */
|
||||
#define REMOTE_HL_PACKET 'H'
|
||||
#define REMOTE_DP_READ 'd'
|
||||
#define REMOTE_LOW_ACCESS 'L'
|
||||
#define REMOTE_AP_READ 'a'
|
||||
#define REMOTE_AP_WRITE 'A'
|
||||
#define REMOTE_AP_MEM_READ 'M'
|
||||
#define REMOTE_MEM_READ 'h'
|
||||
#define REMOTE_MEM_WRITE_SIZED 'H'
|
||||
#define REMOTE_AP_MEM_WRITE_SIZED 'm'
|
||||
|
||||
|
||||
/* Generic protocol elements */
|
||||
#define REMOTE_GEN_PACKET 'G'
|
||||
|
||||
|
@ -125,6 +137,28 @@
|
|||
#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_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 }
|
||||
#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, \
|
||||
'%','0','2','x', '%', '0', '4', 'x', REMOTE_EOM, 0 }
|
||||
#define REMOTE_AP_WRITE_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_WRITE, \
|
||||
'%','0','2','x', '%', '0', '4', 'x', HEX_U32(csw), REMOTE_EOM, 0 }
|
||||
#define REMOTE_AP_MEM_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_MEM_READ, \
|
||||
'%','0','2','x',HEX_U32(csw), HEX_U32(address), HEX_U32(count), REMOTE_EOM, 0 }
|
||||
#define REMOTE_AP_MEM_WRITE_SIZED_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_MEM_WRITE_SIZED, \
|
||||
'%', '0', '2', 'x', HEX_U32(csw), '%', '0', '2', 'x', HEX_U32(address), HEX_U32(count), 0}
|
||||
#define REMOTE_MEM_WRITE_SIZED_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_MEM_WRITE_SIZED, \
|
||||
'%','0','2','x', HEX_U32(address), HEX_U32(count), 0}
|
||||
|
||||
uint64_t remotehston(uint32_t limit, char *s);
|
||||
void remotePacketProcess(uint8_t i, char *packet);
|
||||
|
||||
|
|
|
@ -439,11 +439,6 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel)
|
|||
return ap;
|
||||
}
|
||||
|
||||
static void ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value);
|
||||
static uint32_t ap_read(ADIv5_AP_t *ap, uint16_t addr);
|
||||
static void mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len);
|
||||
static void mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src,
|
||||
size_t len, enum align align);
|
||||
void adiv5_dp_init(ADIv5_DP_t *dp)
|
||||
{
|
||||
volatile bool probed = false;
|
||||
|
@ -452,18 +447,18 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
|
|||
#if PC_HOSTED == 1
|
||||
platform_adiv5_dp_defaults(dp);
|
||||
if (!dp->ap_write)
|
||||
dp->ap_write = ap_write;
|
||||
dp->ap_write = firmware_ap_write;
|
||||
if (!dp->ap_read)
|
||||
dp->ap_read = ap_read;
|
||||
dp->ap_read = firmware_ap_read;
|
||||
if (!dp->mem_read)
|
||||
dp->mem_read = mem_read;
|
||||
dp->mem_read = firmware_mem_read;
|
||||
if (!dp->mem_write_sized)
|
||||
dp->mem_write_sized = mem_write_sized;
|
||||
dp->mem_write_sized = firmware_mem_write_sized;
|
||||
#else
|
||||
dp->ap_write = ap_write;
|
||||
dp->ap_read = ap_read;
|
||||
dp->mem_read = mem_read;
|
||||
dp->mem_write_sized = mem_write_sized;
|
||||
dp->ap_write = firmware_ap_write;
|
||||
dp->ap_read = firmware_ap_read;
|
||||
dp->mem_read = firmware_mem_read;
|
||||
dp->mem_write_sized = firmware_mem_write_sized;
|
||||
#endif
|
||||
volatile struct exception e;
|
||||
TRY_CATCH (e, EXCEPTION_TIMEOUT) {
|
||||
|
@ -629,7 +624,7 @@ void * extract(void *dest, uint32_t src, uint32_t val, enum align align)
|
|||
return (uint8_t *)dest + (1 << align);
|
||||
}
|
||||
|
||||
static void mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
|
||||
void firmware_mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint32_t osrc = src;
|
||||
|
@ -659,7 +654,7 @@ static void mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
|
|||
extract(dest, src, tmp, align);
|
||||
}
|
||||
|
||||
static void mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src,
|
||||
void firmware_mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src,
|
||||
size_t len, enum align align)
|
||||
{
|
||||
uint32_t odest = dest;
|
||||
|
@ -694,14 +689,14 @@ static void mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src,
|
|||
}
|
||||
}
|
||||
|
||||
static void ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value)
|
||||
void firmware_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value)
|
||||
{
|
||||
adiv5_dp_write(ap->dp, ADIV5_DP_SELECT,
|
||||
((uint32_t)ap->apsel << 24)|(addr & 0xF0));
|
||||
adiv5_dp_write(ap->dp, addr, value);
|
||||
}
|
||||
|
||||
static uint32_t ap_read(ADIv5_AP_t *ap, uint16_t addr)
|
||||
uint32_t firmware_ap_read(ADIv5_AP_t *ap, uint16_t addr)
|
||||
{
|
||||
uint32_t ret;
|
||||
adiv5_dp_write(ap->dp, ADIV5_DP_SELECT,
|
||||
|
|
|
@ -240,4 +240,22 @@ 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);
|
||||
uint64_t adiv5_ap_read_pidr(ADIv5_AP_t *ap, uint32_t addr);
|
||||
void * extract(void *dest, uint32_t src, uint32_t val, enum align align);
|
||||
|
||||
void firmware_mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src,
|
||||
size_t len, enum align align);
|
||||
void firmware_mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src,
|
||||
size_t len);
|
||||
void firmware_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value);
|
||||
uint32_t firmware_ap_read(ADIv5_AP_t *ap, uint16_t addr);
|
||||
uint32_t firmware_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
||||
uint16_t addr, uint32_t value);
|
||||
uint32_t fw_adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
||||
uint16_t addr, uint32_t value);
|
||||
uint32_t firmware_swdp_read(ADIv5_DP_t *dp, uint16_t addr);
|
||||
uint32_t fw_adiv5_jtagdp_read(ADIv5_DP_t *dp, uint16_t addr);
|
||||
|
||||
uint32_t firmware_swdp_error(ADIv5_DP_t *dp);
|
||||
|
||||
void firmware_swdp_abort(ADIv5_DP_t *dp, uint32_t abort);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,13 +37,8 @@
|
|||
#define IR_DPACC 0xA
|
||||
#define IR_APACC 0xB
|
||||
|
||||
static uint32_t adiv5_jtagdp_read(ADIv5_DP_t *dp, uint16_t addr);
|
||||
|
||||
static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp);
|
||||
|
||||
static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
||||
uint16_t addr, uint32_t value);
|
||||
|
||||
static void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort);
|
||||
|
||||
void adiv5_jtag_dp_handler(jtag_dev_t *dev)
|
||||
|
@ -57,29 +52,29 @@ void adiv5_jtag_dp_handler(jtag_dev_t *dev)
|
|||
dp->dev = dev;
|
||||
if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) {
|
||||
dp->idcode = dev->idcode;
|
||||
dp->dp_read = adiv5_jtagdp_read;
|
||||
dp->dp_read = fw_adiv5_jtagdp_read;
|
||||
dp->error = adiv5_jtagdp_error;
|
||||
dp->low_access = adiv5_jtagdp_low_access;
|
||||
dp->low_access = fw_adiv5_jtagdp_low_access;
|
||||
dp->abort = adiv5_jtagdp_abort;
|
||||
}
|
||||
adiv5_dp_init(dp);
|
||||
}
|
||||
|
||||
static uint32_t adiv5_jtagdp_read(ADIv5_DP_t *dp, uint16_t addr)
|
||||
uint32_t fw_adiv5_jtagdp_read(ADIv5_DP_t *dp, uint16_t addr)
|
||||
{
|
||||
adiv5_jtagdp_low_access(dp, ADIV5_LOW_READ, addr, 0);
|
||||
return adiv5_jtagdp_low_access(dp, ADIV5_LOW_READ,
|
||||
fw_adiv5_jtagdp_low_access(dp, ADIV5_LOW_READ, addr, 0);
|
||||
return fw_adiv5_jtagdp_low_access(dp, ADIV5_LOW_READ,
|
||||
ADIV5_DP_RDBUFF, 0);
|
||||
}
|
||||
|
||||
static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp)
|
||||
{
|
||||
adiv5_jtagdp_low_access(dp, ADIV5_LOW_READ, ADIV5_DP_CTRLSTAT, 0);
|
||||
return adiv5_jtagdp_low_access(dp, ADIV5_LOW_WRITE,
|
||||
fw_adiv5_jtagdp_low_access(dp, ADIV5_LOW_READ, ADIV5_DP_CTRLSTAT, 0);
|
||||
return fw_adiv5_jtagdp_low_access(dp, ADIV5_LOW_WRITE,
|
||||
ADIV5_DP_CTRLSTAT, 0xF0000032) & 0x32;
|
||||
}
|
||||
|
||||
static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
||||
uint32_t fw_adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
||||
uint16_t addr, uint32_t value)
|
||||
{
|
||||
bool APnDP = addr & ADIV5_APnDP;
|
||||
|
|
|
@ -33,15 +33,6 @@
|
|||
#define SWDP_ACK_WAIT 0x02
|
||||
#define SWDP_ACK_FAULT 0x04
|
||||
|
||||
static uint32_t adiv5_swdp_read(ADIv5_DP_t *dp, uint16_t addr);
|
||||
|
||||
static uint32_t adiv5_swdp_error(ADIv5_DP_t *dp);
|
||||
|
||||
static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
||||
uint16_t addr, uint32_t value);
|
||||
|
||||
static void adiv5_swdp_abort(ADIv5_DP_t *dp, uint32_t abort);
|
||||
|
||||
int adiv5_swdp_scan(void)
|
||||
{
|
||||
uint32_t ack;
|
||||
|
@ -80,33 +71,33 @@ int adiv5_swdp_scan(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
dp->dp_read = adiv5_swdp_read;
|
||||
dp->error = adiv5_swdp_error;
|
||||
dp->low_access = adiv5_swdp_low_access;
|
||||
dp->abort = adiv5_swdp_abort;
|
||||
dp->dp_read = firmware_swdp_read;
|
||||
dp->error = firmware_swdp_error;
|
||||
dp->low_access = firmware_swdp_low_access;
|
||||
dp->abort = firmware_swdp_abort;
|
||||
|
||||
adiv5_swdp_error(dp);
|
||||
firmware_swdp_error(dp);
|
||||
adiv5_dp_init(dp);
|
||||
|
||||
return target_list?1:0;
|
||||
}
|
||||
|
||||
static uint32_t adiv5_swdp_read(ADIv5_DP_t *dp, uint16_t addr)
|
||||
uint32_t firmware_swdp_read(ADIv5_DP_t *dp, uint16_t addr)
|
||||
{
|
||||
if (addr & ADIV5_APnDP) {
|
||||
adiv5_dp_low_access(dp, ADIV5_LOW_READ, addr, 0);
|
||||
return adiv5_dp_low_access(dp, ADIV5_LOW_READ,
|
||||
ADIV5_DP_RDBUFF, 0);
|
||||
} else {
|
||||
return adiv5_swdp_low_access(dp, ADIV5_LOW_READ, addr, 0);
|
||||
return firmware_swdp_low_access(dp, ADIV5_LOW_READ, addr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t adiv5_swdp_error(ADIv5_DP_t *dp)
|
||||
uint32_t firmware_swdp_error(ADIv5_DP_t *dp)
|
||||
{
|
||||
uint32_t err, clr = 0;
|
||||
|
||||
err = adiv5_swdp_read(dp, ADIV5_DP_CTRLSTAT) &
|
||||
err = firmware_swdp_read(dp, ADIV5_DP_CTRLSTAT) &
|
||||
(ADIV5_DP_CTRLSTAT_STICKYORUN | ADIV5_DP_CTRLSTAT_STICKYCMP |
|
||||
ADIV5_DP_CTRLSTAT_STICKYERR | ADIV5_DP_CTRLSTAT_WDATAERR);
|
||||
|
||||
|
@ -125,7 +116,7 @@ static uint32_t adiv5_swdp_error(ADIv5_DP_t *dp)
|
|||
return err;
|
||||
}
|
||||
|
||||
static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
||||
uint32_t firmware_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
||||
uint16_t addr, uint32_t value)
|
||||
{
|
||||
bool APnDP = addr & ADIV5_APnDP;
|
||||
|
@ -183,7 +174,7 @@ static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
|||
return response;
|
||||
}
|
||||
|
||||
static void adiv5_swdp_abort(ADIv5_DP_t *dp, uint32_t abort)
|
||||
void firmware_swdp_abort(ADIv5_DP_t *dp, uint32_t abort)
|
||||
{
|
||||
adiv5_dp_write(dp, ADIV5_DP_ABORT, abort);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue