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:
Valmantas Paliksa 2019-12-17 15:09:49 +02:00 committed by Uwe Bonnes
parent 921c23eb74
commit b06c0ba8d5
11 changed files with 465 additions and 57 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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);
}