Merge commit 'cda83d308490738b54df0405cca3c0c048809664' into sam-update

# Conflicts:
#	src/Makefile
This commit is contained in:
Jason Kotzin 2022-08-10 18:36:23 -07:00
commit 9e02c5f0cd
25 changed files with 242 additions and 143 deletions

View File

@ -119,7 +119,7 @@ clean: host_clean
all_platforms: all_platforms:
$(Q)set -e ;\ $(Q)set -e ;\
mkdir -p artifacts/$(shell git describe --tags --always) ;\ mkdir -p artifacts/$(shell git describe --always --dirty --tags) ;\
echo "<html><body><ul>" > artifacts/index.html ;\ echo "<html><body><ul>" > artifacts/index.html ;\
for i in platforms/*/Makefile.inc ; do \ for i in platforms/*/Makefile.inc ; do \
export DIRNAME=`dirname $$i` ;\ export DIRNAME=`dirname $$i` ;\
@ -140,7 +140,7 @@ all_platforms:
fi ;\ fi ;\
done ;\ done ;\
echo "</ul></body></html>" >> artifacts/index.html ;\ echo "</ul></body></html>" >> artifacts/index.html ;\
cp artifacts/*.bin artifacts/$(shell git describe --tags --always) cp artifacts/*.bin artifacts/$(shell git describe --always --dirty --tags)
command.c: include/version.h command.c: include/version.h

View File

@ -309,8 +309,10 @@ bool cmd_morse(target *t, int argc, char **argv)
(void)t; (void)t;
(void)argc; (void)argc;
(void)argv; (void)argv;
if(morse_msg) if(morse_msg) {
gdb_outf("%s\n", morse_msg); gdb_outf("%s\n", morse_msg);
DEBUG_WARN("%s\n", morse_msg);
}
return true; return true;
} }

View File

@ -38,9 +38,11 @@ blackmagic -V <file>.bin
``` ```
blackmagic -h" blackmagic -h"
``` ```
## Used libraries: ## Used shared libraries:
### libusb ### libusb
### libftdi, for FTDI support ### libftdi, for FTDI support
## Other used libraries:
### hidapi-libusb, for CMSIS-DAP support ### hidapi-libusb, for CMSIS-DAP support
## Compiling on windows ## Compiling on windows
@ -51,8 +53,21 @@ needed. For running, libftdi1.dll and libusb-1.0.dll are needed and
the executable must be able to find them. Mingw on cygwin does not provide the executable must be able to find them. Mingw on cygwin does not provide
a libftdi package yet. a libftdi package yet.
To prepare libusb access to the ftdi device, run zadig https://zadig.akeo.ie/. PC-hosted BMP for windows can also be built with [MSYS2](https://www.msys2.org/),
Choose WinUSB(libusb-1.0) for the BMP Ftdi device. in windows. Make sure to use the `mingw64` shell from msys2, otherwise,
you may get compilation errors. You will need to install the libusb
and libftdi libraries, and have the correct mingw compiler.
You can use these commands to install dependencies, and build PC-hosted BMP
from a mingw64 shell, from within the `src` directory:
```
pacman -S mingw-w64-x86_64-libusb --needed
pacman -S mingw-w64-x86_64-libftdi --needed
pacman -S mingw-w64-x86_64-gcc --needed
PROBE_HOST=hosted make
```
To prepare libusb access to the ftdi/stlink/jlink/cmsis-dap devices, run zadig
https://zadig.akeo.ie/. Choose WinUSB(libusb-1.0).
Running cygwin/blackmagic in a cygwin console, the program does not react Running cygwin/blackmagic in a cygwin console, the program does not react
on ^C. In another console, run "ps ax" to find the WINPID of the process on ^C. In another console, run "ps ax" to find the WINPID of the process

View File

@ -153,7 +153,7 @@ static uint32_t remote_adiv5_dp_read(ADIv5_DP_t *dp, uint16_t addr)
(void)dp; (void)dp;
uint8_t construct[REMOTE_MAX_MSG_SIZE]; uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_DP_READ_STR, int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_DP_READ_STR,
addr); dp->dp_jd_index, addr);
platform_buffer_write(construct, s); platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
@ -171,7 +171,7 @@ static uint32_t remote_adiv5_low_access(
(void)dp; (void)dp;
uint8_t construct[REMOTE_MAX_MSG_SIZE]; uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,
REMOTE_LOW_ACCESS_STR, RnW, addr, value); REMOTE_LOW_ACCESS_STR, dp->dp_jd_index, RnW, addr, value);
platform_buffer_write(construct, s); platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
@ -186,7 +186,7 @@ static uint32_t remote_adiv5_ap_read(ADIv5_AP_t *ap, uint16_t addr)
{ {
uint8_t construct[REMOTE_MAX_MSG_SIZE]; uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_AP_READ_STR, int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_AP_READ_STR,
ap->apsel, addr); ap->dp->dp_jd_index, ap->apsel, addr);
platform_buffer_write(construct, s); platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
@ -201,7 +201,7 @@ static void remote_adiv5_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value)
{ {
uint8_t construct[REMOTE_MAX_MSG_SIZE]; uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_AP_WRITE_STR, int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_AP_WRITE_STR,
ap->apsel, addr, value); ap->dp->dp_jd_index, ap->apsel, addr, value);
platform_buffer_write(construct, s); platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
@ -267,7 +267,7 @@ static void remote_ap_mem_read(
if (count > batchsize) if (count > batchsize)
count = batchsize; count = batchsize;
s = snprintf(construct, REMOTE_MAX_MSG_SIZE, s = snprintf(construct, REMOTE_MAX_MSG_SIZE,
REMOTE_AP_MEM_READ_STR, ap->apsel, ap->csw, src, count); REMOTE_AP_MEM_READ_STR, ap->dp->dp_jd_index, ap->apsel, ap->csw, src, count);
platform_buffer_write((uint8_t*)construct, s); platform_buffer_write((uint8_t*)construct, s);
s = platform_buffer_read((uint8_t*)construct, REMOTE_MAX_MSG_SIZE); s = platform_buffer_read((uint8_t*)construct, REMOTE_MAX_MSG_SIZE);
if ((s > 0) && (construct[0] == REMOTE_RESP_OK)) { if ((s > 0) && (construct[0] == REMOTE_RESP_OK)) {
@ -307,7 +307,7 @@ static void remote_ap_mem_write_sized(
count = batchsize; count = batchsize;
int s = snprintf(construct, REMOTE_MAX_MSG_SIZE, int s = snprintf(construct, REMOTE_MAX_MSG_SIZE,
REMOTE_AP_MEM_WRITE_SIZED_STR, REMOTE_AP_MEM_WRITE_SIZED_STR,
ap->apsel, ap->csw, align, dest, count); ap->dp->dp_jd_index, ap->apsel, ap->csw, align, dest, count);
char *p = construct + s; char *p = construct + s;
hexify(p, src, count); hexify(p, src, count);
p += 2 * count; p += 2 * count;
@ -340,22 +340,12 @@ void remote_adiv5_dp_defaults(ADIv5_DP_t *dp)
REMOTE_HL_CHECK_STR); REMOTE_HL_CHECK_STR);
platform_buffer_write(construct, s); platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { if ((!s) || (construct[0] == REMOTE_RESP_ERR) ||
((construct[1] - '0') < REMOTE_HL_VERSION)) {
DEBUG_WARN( DEBUG_WARN(
"Please update BMP firmware for substantial speed increase!\n"); "Please update BMP firmware for substantial speed increase!\n");
return; 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->low_access = remote_adiv5_low_access;
dp->dp_read = remote_adiv5_dp_read; dp->dp_read = remote_adiv5_dp_read;
dp->ap_write = remote_adiv5_ap_write; dp->ap_write = remote_adiv5_ap_write;

View File

@ -341,23 +341,27 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
goto error_2; goto error_2;
} }
assert(ftdic != NULL); assert(ftdic != NULL);
#ifdef _Ftdi_Pragma
err = ftdi_tcioflush(ftdic);
#else
err = ftdi_usb_purge_buffers(ftdic); err = ftdi_usb_purge_buffers(ftdic);
#endif
if (err != 0) { if (err != 0) {
fprintf(stderr, "ftdi_usb_purge_buffer: %d: %s\n", DEBUG_WARN("ftdi_tcioflush(ftdi_usb_purge_buffer): %d: %s\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
goto error_2; goto error_2;
} }
/* Reset MPSSE controller. */ /* Reset MPSSE controller. */
err = ftdi_set_bitmode(ftdic, 0, BITMODE_RESET); err = ftdi_set_bitmode(ftdic, 0, BITMODE_RESET);
if (err != 0) { if (err != 0) {
fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", DEBUG_WARN("ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
goto error_2; goto error_2;
} }
/* Enable MPSSE controller. Pin directions are set later.*/ /* Enable MPSSE controller. Pin directions are set later.*/
err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE); err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE);
if (err != 0) { if (err != 0) {
fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", DEBUG_WARN("ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
goto error_2; goto error_2;
} }

View File

@ -124,9 +124,6 @@ int jlink_swdp_scan(bmp_info_t *info)
{ {
swdptap_init(info); swdptap_init(info);
target_list_free(); target_list_free();
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (!dp) /* calloc failed: heap exhaustion */
return 0;
uint8_t cmd[44]; uint8_t cmd[44];
cmd[0] = CMD_HW_JTAG3; cmd[0] = CMD_HW_JTAG3;
cmd[1] = 0; cmd[1] = 0;
@ -178,6 +175,9 @@ int jlink_swdp_scan(bmp_info_t *info)
DEBUG_WARN( "Line reset failed\n"); DEBUG_WARN( "Line reset failed\n");
return 0; return 0;
} }
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (!dp) /* calloc failed: heap exhaustion */
return 0;
dp->idcode = jlink_adiv5_swdp_low_access(dp, 1, ADIV5_DP_IDCODE, 0); dp->idcode = jlink_adiv5_swdp_low_access(dp, 1, ADIV5_DP_IDCODE, 0);
dp->dp_read = jlink_adiv5_swdp_read; dp->dp_read = jlink_adiv5_swdp_read;
dp->error = jlink_adiv5_swdp_error; dp->error = jlink_adiv5_swdp_error;
@ -186,6 +186,8 @@ int jlink_swdp_scan(bmp_info_t *info)
jlink_adiv5_swdp_error(dp); jlink_adiv5_swdp_error(dp);
adiv5_dp_init(dp); adiv5_dp_init(dp);
if (!target_list)
free(dp);
return target_list?1:0; return target_list?1:0;
} }

View File

@ -111,12 +111,16 @@ static int find_debuggers( BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
libusb_free_device_list(devs, 1); libusb_free_device_list(devs, 1);
continue; continue;
} }
/* Exclude hubs from testing. Probably more classes could be excluded here!*/
if (desc.bDeviceClass == LIBUSB_CLASS_HUB) {
continue;
}
libusb_device_handle *handle; libusb_device_handle *handle;
res = libusb_open(dev, &handle); res = libusb_open(dev, &handle);
if (res != LIBUSB_SUCCESS) { if (res != LIBUSB_SUCCESS) {
if (!access_problems) { if (!access_problems) {
DEBUG_INFO("INFO: Open USB %04x:%04x failed\n", DEBUG_INFO("INFO: Open USB %04x:%04x class %2x failed\n",
desc.idVendor, desc.idProduct); desc.idVendor, desc.idProduct, desc.bDeviceClass);
access_problems = true; access_problems = true;
} }
continue; continue;
@ -347,7 +351,9 @@ int platform_adiv5_swdp_scan(void)
{ {
target_list_free(); target_list_free();
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (!stlink_enter_debug_swd(&info, dp)) { if (stlink_enter_debug_swd(&info, dp)) {
free(dp);
} else {
adiv5_dp_init(dp); adiv5_dp_init(dp);
if (target_list) if (target_list)
return 1; return 1;
@ -359,7 +365,9 @@ int platform_adiv5_swdp_scan(void)
{ {
target_list_free(); target_list_free();
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (!dap_enter_debug_swd(dp)) { if (dap_enter_debug_swd(dp)) {
free(dp);
} else {
adiv5_dp_init(dp); adiv5_dp_init(dp);
if (target_list) if (target_list)
return 1; return 1;

View File

@ -123,7 +123,7 @@ static void cl_help(char **argv, BMP_CL_OPTIONS_t *opt)
DEBUG_WARN("\t-v[bitmask]\t: Increasing verbosity. Bitmask:\n"); DEBUG_WARN("\t-v[bitmask]\t: Increasing verbosity. Bitmask:\n");
DEBUG_WARN("\t\t\t 1 = INFO, 2 = GDB, 4 = TARGET, 8 = PROBE, 16 = WIRE\n"); DEBUG_WARN("\t\t\t 1 = INFO, 2 = GDB, 4 = TARGET, 8 = PROBE, 16 = WIRE\n");
DEBUG_WARN("Probe selection arguments:\n"); DEBUG_WARN("Probe selection arguments:\n");
DEBUG_WARN("\t-d \"path\"\t: Use serial device at \"path\"\n"); DEBUG_WARN("\t-d \"path\"\t: Use serial BMP device at \"path\"(Deprecated)\n");
DEBUG_WARN("\t-P <pos>\t: Use debugger found at position <pos>\n"); DEBUG_WARN("\t-P <pos>\t: Use debugger found at position <pos>\n");
DEBUG_WARN("\t-n <num>\t: Use target device found at position <num>\n"); DEBUG_WARN("\t-n <num>\t: Use target device found at position <num>\n");
DEBUG_WARN("\t-s \"serial\"\t: Use dongle with (partial) " DEBUG_WARN("\t-s \"serial\"\t: Use dongle with (partial) "
@ -189,6 +189,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
opt->external_resistor_swd = true; opt->external_resistor_swd = true;
break; break;
case 'd': case 'd':
DEBUG_WARN("Deprecated!\n");
if (optarg) if (optarg)
opt->opt_device = optarg; opt->opt_device = optarg;
break; break;
@ -494,5 +495,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
target_detach: target_detach:
if (t) if (t)
target_detach(t); target_detach(t);
target_list_free();
return res; return res;
} }

View File

@ -61,11 +61,11 @@ void platform_init(void)
srst_pin = SRST_PIN_V2; srst_pin = SRST_PIN_V2;
} }
/* Setup GPIO ports */ /* Setup GPIO ports */
gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_INPUT_FLOAT, TMS_PIN); GPIO_CNF_INPUT_FLOAT, TMS_PIN);
gpio_set_mode(TCK_PORT, GPIO_MODE_OUTPUT_50_MHZ, gpio_set_mode(TCK_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, TCK_PIN); GPIO_CNF_OUTPUT_PUSHPULL, TCK_PIN);
gpio_set_mode(TDI_PORT, GPIO_MODE_OUTPUT_50_MHZ, gpio_set_mode(TDI_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, TDI_PIN); GPIO_CNF_OUTPUT_PUSHPULL, TDI_PIN);
platform_srst_set_val(false); platform_srst_set_val(false);
@ -90,7 +90,7 @@ void platform_init(void)
void platform_srst_set_val(bool assert) void platform_srst_set_val(bool assert)
{ {
if (assert) { if (assert) {
gpio_set_mode(SRST_PORT, GPIO_MODE_OUTPUT_50_MHZ, gpio_set_mode(SRST_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_OPENDRAIN, srst_pin); GPIO_CNF_OUTPUT_OPENDRAIN, srst_pin);
gpio_clear(SRST_PORT, srst_pin); gpio_clear(SRST_PORT, srst_pin);
} else { } else {

View File

@ -78,7 +78,7 @@ int usbuart_debug_write(const char *buf, size_t len);
# define SWD_CR_MULT (1 << ((14 - 8) << 2)) # define SWD_CR_MULT (1 << ((14 - 8) << 2))
#define TMS_SET_MODE() \ #define TMS_SET_MODE() \
gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, \ gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_2_MHZ, \
GPIO_CNF_OUTPUT_PUSHPULL, TMS_PIN); GPIO_CNF_OUTPUT_PUSHPULL, TMS_PIN);
#define SWDIO_MODE_FLOAT() do { \ #define SWDIO_MODE_FLOAT() do { \
uint32_t cr = SWD_CR; \ uint32_t cr = SWD_CR; \

View File

@ -67,11 +67,11 @@ void platform_init(void)
data |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF; data |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF;
AFIO_MAPR = data; AFIO_MAPR = data;
/* Setup JTAG GPIO ports */ /* Setup JTAG GPIO ports */
gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_INPUT_FLOAT, TMS_PIN); GPIO_CNF_INPUT_FLOAT, TMS_PIN);
gpio_set_mode(TCK_PORT, GPIO_MODE_OUTPUT_50_MHZ, gpio_set_mode(TCK_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, TCK_PIN); GPIO_CNF_OUTPUT_PUSHPULL, TCK_PIN);
gpio_set_mode(TDI_PORT, GPIO_MODE_OUTPUT_50_MHZ, gpio_set_mode(TDI_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, TDI_PIN); GPIO_CNF_OUTPUT_PUSHPULL, TDI_PIN);
gpio_set_mode(TDO_PORT, GPIO_MODE_INPUT, gpio_set_mode(TDO_PORT, GPIO_MODE_INPUT,
@ -118,7 +118,7 @@ void platform_srst_set_val(bool assert)
{ {
/* We reuse JSRST as SRST.*/ /* We reuse JSRST as SRST.*/
if (assert) { if (assert) {
gpio_set_mode(JRST_PORT, GPIO_MODE_OUTPUT_50_MHZ, gpio_set_mode(JRST_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_OPENDRAIN, JRST_PIN); GPIO_CNF_OUTPUT_OPENDRAIN, JRST_PIN);
/* Wait until requested value is active.*/ /* Wait until requested value is active.*/
while (gpio_get(JRST_PORT, JRST_PIN)) while (gpio_get(JRST_PORT, JRST_PIN))

View File

@ -72,7 +72,7 @@ int usbuart_debug_write(const char *buf, size_t len);
# define SWD_CR_MULT (1 << ((13 - 8) << 2)) # define SWD_CR_MULT (1 << ((13 - 8) << 2))
#define TMS_SET_MODE() \ #define TMS_SET_MODE() \
gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, \ gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_2_MHZ, \
GPIO_CNF_OUTPUT_PUSHPULL, TMS_PIN); GPIO_CNF_OUTPUT_PUSHPULL, TMS_PIN);
#define SWDIO_MODE_FLOAT() do { \ #define SWDIO_MODE_FLOAT() do { \
uint32_t cr = SWD_CR; \ uint32_t cr = SWD_CR; \

View File

@ -322,21 +322,16 @@ void remotePacketProcessHL(uint8_t i, char *packet)
/* Re-use packet buffer. Align to DWORD! */ /* Re-use packet buffer. Align to DWORD! */
void *src = (void *)(((uint32_t)packet + 7) & ~7); void *src = (void *)(((uint32_t)packet + 7) & ~7);
char index = packet[1]; char index = packet[1];
if (index == REMOTE_HL_CHECK) {
_respond(REMOTE_RESP_OK, REMOTE_HL_VERSION);
return;
}
packet += 2;
remote_dp.dp_jd_index = remotehston(2, packet);
packet += 2; packet += 2;
remote_ap.apsel = remotehston(2, packet); remote_ap.apsel = remotehston(2, packet);
remote_ap.dp = &remote_dp; remote_ap.dp = &remote_dp;
switch (index) { switch (index) {
case REMOTE_HL_CHECK: /* HC = Check availability of HL commands*/
_respond(REMOTE_RESP_OK, 0);
break;
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);
_respond(REMOTE_RESP_OK, 0);
}
break;
case REMOTE_DP_READ: /* Hd = Read from DP register */ case REMOTE_DP_READ: /* Hd = Read from DP register */
packet += 2; packet += 2;
uint16_t addr16 = remotehston(4, packet); uint16_t addr16 = remotehston(4, packet);

View File

@ -24,6 +24,8 @@
#include <inttypes.h> #include <inttypes.h>
#include "general.h" #include "general.h"
#define REMOTE_HL_VERSION 1
/* /*
* Commands to remote end, and responses * Commands to remote end, and responses
* ===================================== * =====================================
@ -86,7 +88,6 @@
/* High level protocol elements */ /* High level protocol elements */
#define REMOTE_HL_CHECK 'C' #define REMOTE_HL_CHECK 'C'
#define REMOTE_HL_JTAG_DEV 'J'
#define REMOTE_HL_PACKET 'H' #define REMOTE_HL_PACKET 'H'
#define REMOTE_DP_READ 'd' #define REMOTE_DP_READ 'd'
#define REMOTE_LOW_ACCESS 'L' #define REMOTE_LOW_ACCESS 'L'
@ -156,24 +157,21 @@
REMOTE_EOM, 0} REMOTE_EOM, 0}
#define REMOTE_HL_CHECK_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_HL_CHECK, 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, \ #define REMOTE_DP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_DP_READ, \
'f', 'f', '%', '0', '4', 'x', REMOTE_EOM, 0 } '%','0', '2', 'x', 'f', 'f', '%', '0', '4', 'x', REMOTE_EOM, 0 }
#define REMOTE_LOW_ACCESS_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_LOW_ACCESS, \ #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 } '%','0', '2', 'x', '%','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, \ #define REMOTE_AP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_READ, \
'%','0','2','x', '%', '0', '4', 'x', REMOTE_EOM, 0 } '%','0', '2', 'x', '%','0','2','x', '%', '0', '4', 'x', REMOTE_EOM, 0 }
#define REMOTE_AP_WRITE_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_WRITE, \ #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 } '%','0', '2', 'x', '%','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, \ #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 } '%','0', '2', 'x', '%','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, \ #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} '%','0', '2', 'x', '%', '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, \ #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} '%','0', '2', 'x', '%','0','2','x', HEX_U32(address), HEX_U32(count), 0}
uint64_t remotehston(uint32_t limit, char *s); uint64_t remotehston(uint32_t limit, char *s);
void remotePacketProcess(uint8_t i, char *packet); void remotePacketProcess(uint8_t i, char *packet);

View File

@ -263,13 +263,10 @@ static const struct {
extern bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base); extern bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base);
static void adiv5_dp_ref(ADIv5_DP_t *dp)
{
dp->refcnt++;
}
void adiv5_ap_ref(ADIv5_AP_t *ap) void adiv5_ap_ref(ADIv5_AP_t *ap)
{ {
if (ap->refcnt == 0)
ap->dp->refcnt++;
ap->refcnt++; ap->refcnt++;
} }
@ -404,23 +401,23 @@ static bool cortexm_prepare(ADIv5_AP_t *ap)
return true; return true;
} }
static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, int num_entry) /* Return true if we find a debuggable device.*/
static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, int num_entry)
{ {
(void) num_entry; (void) num_entry;
addr &= 0xfffff000; /* Mask out base address */ addr &= 0xfffff000; /* Mask out base address */
if (addr == 0) /* No rom table on this AP */ if (addr == 0) /* No rom table on this AP */
return false; return;
uint32_t cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET); uint32_t cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET);
if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE) { if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE) {
/* Maybe caused by a not halted CortexM */ /* Maybe caused by a not halted CortexM */
if (!ap->apsel && ((ap->idr & 0xf) == ARM_AP_TYPE_AHB)) { if ((ap->idr & 0xf) == ARM_AP_TYPE_AHB) {
if (!cortexm_prepare(ap)) if (!cortexm_prepare(ap))
return false; /* Halting failed! */ return; /* Halting failed! */
/* CPU now halted, read cidr again. */ /* CPU now halted, read cidr again. */
cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET); cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET);
} }
} }
bool res = false;
#if defined(ENABLE_DEBUG) #if defined(ENABLE_DEBUG)
char indent[recursion + 1]; char indent[recursion + 1];
@ -430,7 +427,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
if (adiv5_dp_error(ap->dp)) { if (adiv5_dp_error(ap->dp)) {
DEBUG_WARN("%sFault reading ID registers\n", indent); DEBUG_WARN("%sFault reading ID registers\n", indent);
return false; return;
} }
/* CIDR preamble sanity check */ /* CIDR preamble sanity check */
@ -438,7 +435,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
DEBUG_WARN("%s%d 0x%08" PRIx32": 0x%08" PRIx32 DEBUG_WARN("%s%d 0x%08" PRIx32": 0x%08" PRIx32
" <- does not match preamble (0x%X)\n", " <- does not match preamble (0x%X)\n",
indent + 1, num_entry, addr, cidr, CID_PREAMBLE); indent + 1, num_entry, addr, cidr, CID_PREAMBLE);
return false; return;
} }
uint64_t pidr = adiv5_ap_read_pidr(ap, addr); uint64_t pidr = adiv5_ap_read_pidr(ap, addr);
@ -465,10 +462,8 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
if (recursion == 0) { if (recursion == 0) {
ap->ap_designer = designer; ap->ap_designer = designer;
ap->ap_partno = partno; ap->ap_partno = partno;
if ((ap->ap_designer == AP_DESIGNER_ATMEL) && (ap->ap_partno == 0xcd0)) { if ((ap->ap_designer == AP_DESIGNER_ATMEL) && (ap->ap_partno == 0xcd0))
cortexm_probe(ap); cortexm_probe(ap);
return true;
}
} }
for (int i = 0; i < 960; i++) { for (int i = 0; i < 960; i++) {
adiv5_dp_error(ap->dp); adiv5_dp_error(ap->dp);
@ -501,7 +496,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
DEBUG_WARN("%s0x%" PRIx32 ": 0x%02" PRIx32 "%08" PRIx32 DEBUG_WARN("%s0x%" PRIx32 ": 0x%02" PRIx32 "%08" PRIx32
" <- does not match ARM JEP-106\n", " <- does not match ARM JEP-106\n",
indent, addr, (uint32_t)(pidr >> 32), (uint32_t)pidr); indent, addr, (uint32_t)(pidr >> 32), (uint32_t)pidr);
return false; return;
} }
/* ADIv6: For CoreSight components, read DEVTYPE and ARCHID */ /* ADIv6: For CoreSight components, read DEVTYPE and ARCHID */
@ -543,7 +538,6 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
cidc_debug_strings[cid_class], cidc_debug_strings[cid_class],
cidc_debug_strings[pidr_pn_bits[i].cidc]); cidc_debug_strings[pidr_pn_bits[i].cidc]);
} }
res = true;
switch (pidr_pn_bits[i].arch) { switch (pidr_pn_bits[i].arch) {
case aa_cortexm: case aa_cortexm:
DEBUG_INFO("%s-> cortexm_probe\n", indent + 1); DEBUG_INFO("%s-> cortexm_probe\n", indent + 1);
@ -567,7 +561,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
(uint32_t)(pidr >> 32), (uint32_t)pidr, dev_type, arch_id); (uint32_t)(pidr >> 32), (uint32_t)pidr, dev_type, arch_id);
} }
} }
return res; return;
} }
ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel) ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel)
@ -598,7 +592,6 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel)
} }
memcpy(ap, &tmpap, sizeof(*ap)); memcpy(ap, &tmpap, sizeof(*ap));
adiv5_dp_ref(dp);
ap->csw = adiv5_ap_read(ap, ADIV5_AP_CSW) & ap->csw = adiv5_ap_read(ap, ADIV5_AP_CSW) &
~(ADIV5_AP_CSW_SIZE_MASK | ADIV5_AP_CSW_ADDRINC_MASK); ~(ADIV5_AP_CSW_SIZE_MASK | ADIV5_AP_CSW_ADDRINC_MASK);
@ -612,6 +605,8 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel)
uint32_t cfg = adiv5_ap_read(ap, ADIV5_AP_CFG); uint32_t cfg = adiv5_ap_read(ap, ADIV5_AP_CFG);
DEBUG_INFO("AP %3d: IDR=%08"PRIx32" CFG=%08"PRIx32" BASE=%08" PRIx32 DEBUG_INFO("AP %3d: IDR=%08"PRIx32" CFG=%08"PRIx32" BASE=%08" PRIx32
" CSW=%08"PRIx32"\n", apsel, ap->idr, cfg, ap->base, ap->csw); " CSW=%08"PRIx32"\n", apsel, ap->idr, cfg, ap->base, ap->csw);
DEBUG_INFO("AP#0 IDR = 0x%08" PRIx32 " (AHB-AP var%x rev%x)\n",
ap->idr, (ap->idr >> 4) & 0xf, ap->idr >> 28);
#endif #endif
adiv5_ap_ref(ap); adiv5_ap_ref(ap);
return ap; return ap;
@ -619,8 +614,10 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel)
void adiv5_dp_init(ADIv5_DP_t *dp) void adiv5_dp_init(ADIv5_DP_t *dp)
{ {
DEBUG_INFO("DPIDR 0x%08" PRIx32 " (v%d %srev%d)\n", dp->idcode,
(dp->idcode >> 12) & 0xf,
(dp->idcode & 0x10000) ? "MINDP " : "", dp->idcode >> 28);
volatile uint32_t ctrlstat = 0; volatile uint32_t ctrlstat = 0;
adiv5_dp_ref(dp);
#if PC_HOSTED == 1 #if PC_HOSTED == 1
platform_adiv5_dp_defaults(dp); platform_adiv5_dp_defaults(dp);
if (!dp->ap_write) if (!dp->ap_write)
@ -663,6 +660,7 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
break; break;
if (platform_timeout_is_expired(&timeout)) { if (platform_timeout_is_expired(&timeout)) {
DEBUG_INFO("DEBUG Power-Up failed\n"); DEBUG_INFO("DEBUG Power-Up failed\n");
free(dp); /* No AP that referenced this DP so long*/
return; return;
} }
} }
@ -704,6 +702,7 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
/* Probe for APs on this DP */ /* Probe for APs on this DP */
uint32_t last_base = 0; uint32_t last_base = 0;
int void_aps = 0; int void_aps = 0;
dp->refcnt++;
for(int i = 0; (i < 256) && (void_aps < 8); i++) { for(int i = 0; (i < 256) && (void_aps < 8); i++) {
ADIv5_AP_t *ap = NULL; ADIv5_AP_t *ap = NULL;
#if PC_HOSTED == 1 #if PC_HOSTED == 1
@ -718,18 +717,20 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
if (dp->ap_cleanup) if (dp->ap_cleanup)
dp->ap_cleanup(i); dp->ap_cleanup(i);
#endif #endif
if (i == 0) if (i == 0) {
adiv5_dp_unref(dp);
return; return;
else } else {
continue; continue;
} }
}
if (ap->base == last_base) { if (ap->base == last_base) {
DEBUG_WARN("AP %d: Duplicate base\n", i); DEBUG_WARN("AP %d: Duplicate base\n", i);
#if PC_HOSTED == 1 #if PC_HOSTED == 1
if (dp->ap_cleanup) if (dp->ap_cleanup)
dp->ap_cleanup(i); dp->ap_cleanup(i);
#endif #endif
free(ap); adiv5_ap_unref(ap);
/* FIXME: Should we expect valid APs behind duplicate ones? */ /* FIXME: Should we expect valid APs behind duplicate ones? */
return; return;
} }
@ -749,7 +750,12 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
/* The rest should only be added after checking ROM table */ /* The rest should only be added after checking ROM table */
adiv5_component_probe(ap, ap->base, 0, 0); adiv5_component_probe(ap, ap->base, 0, 0);
adiv5_ap_unref(ap);
} }
/* We halted at least CortexM for Romtable scan.
* Release the devices now. Attach() will halt them again.*/
for (target *t = target_list; t; t = t->next)
target_halt_resume(t, false);
adiv5_dp_unref(dp); adiv5_dp_unref(dp);
} }

View File

@ -38,21 +38,12 @@ int adiv5_swdp_scan(void)
uint32_t ack; uint32_t ack;
target_list_free(); 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;
}
#if PC_HOSTED == 1 #if PC_HOSTED == 1
if (platform_swdptap_init()) { if (platform_swdptap_init()) {
free(dp);
exit(-1); exit(-1);
} }
#else #else
if (swdptap_init()) { if (swdptap_init()) {
free(dp);
return -1; return -1;
} }
#endif #endif
@ -71,12 +62,19 @@ int adiv5_swdp_scan(void)
* allow the ack to be checked here. */ * allow the ack to be checked here. */
swd_proc.swdptap_seq_out(0xA5, 8); swd_proc.swdptap_seq_out(0xA5, 8);
ack = swd_proc.swdptap_seq_in(3); ack = swd_proc.swdptap_seq_in(3);
if((ack != SWDP_ACK_OK) || swd_proc.swdptap_seq_in_parity(&dp->idcode, 32)) { uint32_t idcode;
if((ack != SWDP_ACK_OK) || swd_proc.swdptap_seq_in_parity(&idcode, 32)) {
DEBUG_WARN("Read SW-DP IDCODE failed %1" PRIx32 "\n", ack); DEBUG_WARN("Read SW-DP IDCODE failed %1" PRIx32 "\n", ack);
free(dp);
return -1; return -1;
} }
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (!dp) { /* calloc failed: heap exhaustion */
DEBUG_WARN("calloc: failed in %s\n", __func__);
return -1;
}
dp->idcode = idcode;
dp->dp_read = firmware_swdp_read; dp->dp_read = firmware_swdp_read;
dp->error = firmware_swdp_error; dp->error = firmware_swdp_error;
dp->low_access = firmware_swdp_low_access; dp->low_access = firmware_swdp_low_access;

View File

@ -297,42 +297,41 @@ bool cortexm_probe(ADIv5_AP_t *ap)
* that is, the actual values are found in the Technical Reference Manual * that is, the actual values are found in the Technical Reference Manual
* for each Cortex-M core. * for each Cortex-M core.
*/ */
uint32_t cpuid = target_mem_read32(t, CORTEXM_CPUID); t->cpuid = target_mem_read32(t, CORTEXM_CPUID);
uint16_t partno = (cpuid >> 4) & 0xfff; uint32_t cpuid_partno = t->cpuid & CPUID_PARTNO_MASK;
switch (cpuid_partno) {
switch (partno) { case CORTEX_M33:
case 0xd21:
t->core = "M33"; t->core = "M33";
break; break;
case CORTEX_M23:
case 0xd20:
t->core = "M23"; t->core = "M23";
break; break;
case CORTEX_M3:
case 0xc23:
t->core = "M3"; t->core = "M3";
break; break;
case CORTEX_M4:
case 0xc24:
t->core = "M4"; t->core = "M4";
break; break;
case CORTEX_M7:
case 0xc27:
t->core = "M7"; t->core = "M7";
if ((((cpuid >> 20) & 0xf) == 0) && (((cpuid >> 0) & 0xf) < 2)) { if (((t->cpuid & CPUID_REVISION_MASK) == 0) &&
(t->cpuid & CPUID_PATCH_MASK) < 2) {
DEBUG_WARN("Silicon bug: Single stepping will enter pending " DEBUG_WARN("Silicon bug: Single stepping will enter pending "
"exception handler with this M7 core revision!\n"); "exception handler with this M7 core revision!\n");
} }
break; break;
case CORTEX_M0P:
case 0xc60:
t->core = "M0+"; t->core = "M0+";
break; break;
case CORTEX_M0:
case 0xc20:
t->core = "M0"; t->core = "M0";
break; break;
default:
DEBUG_WARN("Unexpected CortexM CPUID partno %04x\n", cpuid_partno);
} }
DEBUG_INFO("CPUID 0x%08" PRIx32 " (%s var %x rev %x)\n", t->cpuid,
t->core, (t->cpuid & CPUID_REVISION_MASK) >> 20,
t->cpuid & CPUID_PATCH_MASK);
t->attach = cortexm_attach; t->attach = cortexm_attach;
t->detach = cortexm_detach; t->detach = cortexm_detach;
@ -439,8 +438,11 @@ bool cortexm_probe(ADIv5_AP_t *ap)
PROBE(lpc11xx_probe); /* LPC24C11 */ PROBE(lpc11xx_probe); /* LPC24C11 */
PROBE(lpc43xx_probe); PROBE(lpc43xx_probe);
} }
else if (ap->ap_partno == 0x4c4) /* Cortex-M4 ROM */ else if (ap->ap_partno == 0x4c4) { /* Cortex-M4 ROM */
PROBE(lpc43xx_probe); PROBE(lpc43xx_probe);
PROBE(lpc546xx_probe);
PROBE(kinetis_probe); /* Older K-series */
}
/* Info on PIDR of these parts wanted! */ /* Info on PIDR of these parts wanted! */
PROBE(sam3x_probe); PROBE(sam3x_probe);
PROBE(lpc15xx_probe); PROBE(lpc15xx_probe);
@ -835,6 +837,8 @@ static void cortexm_halt_resume(target *t, bool step)
target_mem_write32(t, CORTEXM_ICIALLU, 0); target_mem_write32(t, CORTEXM_ICIALLU, 0);
target_mem_write32(t, CORTEXM_DHCSR, dhcsr); target_mem_write32(t, CORTEXM_DHCSR, dhcsr);
/* Add some clock cycles to get the CPU running again.*/
target_mem_read32(t, 0);
} }
static int cortexm_fault_unwind(target *t) static int cortexm_fault_unwind(target *t)

View File

@ -171,6 +171,19 @@ extern long cortexm_wait_timeout;
#define CORTEXM_TOPT_INHIBIT_SRST (1 << 2) #define CORTEXM_TOPT_INHIBIT_SRST (1 << 2)
enum cortexm_types {
CORTEX_M0 = 0xc200,
CORTEX_M0P = 0xc600,
CORTEX_M3 = 0xc230,
CORTEX_M4 = 0xc240,
CORTEX_M7 = 0xc270,
CORTEX_M23 = 0xd200,
CORTEX_M33 = 0xd210,
};
#define CPUID_PARTNO_MASK 0xfff0
#define CPUID_REVISION_MASK 0x00f00000
#define CPUID_PATCH_MASK 0xf
bool cortexm_probe(ADIv5_AP_t *ap); bool cortexm_probe(ADIv5_AP_t *ap);
ADIv5_AP_t *cortexm_ap(target *t); ADIv5_AP_t *cortexm_ap(target *t);

View File

@ -261,6 +261,71 @@ bool kinetis_probe(target *t)
kl_gen_add_flash(t, 0, 0x80000, 0x1000, K64_WRITE_LEN); kl_gen_add_flash(t, 0, 0x80000, 0x1000, K64_WRITE_LEN);
kl_gen_add_flash(t, 0x80000, 0x80000, 0x1000, K64_WRITE_LEN); kl_gen_add_flash(t, 0x80000, 0x80000, 0x1000, K64_WRITE_LEN);
break; break;
case 0x000: /* Older K-series */
switch(sdid & 0xff0) {
case 0x000: /* K10 Family, DIEID=0x0 */
case 0x080: /* K10 Family, DIEID=0x1 */
case 0x100: /* K10 Family, DIEID=0x2 */
case 0x180: /* K10 Family, DIEID=0x3 */
case 0x220: /* K11 Family, DIEID=0x4 */
return false;
case 0x200: /* K12 Family, DIEID=0x4 */
switch((fcfg1 >> 24) & 0x0f) {
/* K12 Sub-Family Reference Manual, K12P80M50SF4RM, Rev. 4, February 2013 */
case 0x7:
t->driver = "MK12DX128Vxx5";
target_add_ram(t, 0x1fffc000, 0x00004000); /* SRAM_L, 16 KB */
target_add_ram(t, 0x20000000, 0x00004000); /* SRAM_H, 16 KB */
kl_gen_add_flash(t, 0x00000000, 0x00020000, 0x800, KL_WRITE_LEN); /* P-Flash, 128 KB, 2 KB Sectors */
kl_gen_add_flash(t, 0x10000000, 0x00010000, 0x800, KL_WRITE_LEN); /* FlexNVM, 64 KB, 2 KB Sectors */
break;
case 0x9:
t->driver = "MK12DX256Vxx5";
target_add_ram(t, 0x1fffc000, 0x00004000); /* SRAM_L, 16 KB */
target_add_ram(t, 0x20000000, 0x00004000); /* SRAM_H, 16 KB */
kl_gen_add_flash(t, 0x00000000, 0x00040000, 0x800, KL_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */
kl_gen_add_flash(t, 0x10000000, 0x00010000, 0x800, KL_WRITE_LEN); /* FlexNVM, 64 KB, 2 KB Sectors */
break;
case 0xb:
t->driver = "MK12DN512Vxx5";
target_add_ram(t, 0x1fff8000, 0x00008000); /* SRAM_L, 32 KB */
target_add_ram(t, 0x20000000, 0x00008000); /* SRAM_H, 32 KB */
kl_gen_add_flash(t, 0x00000000, 0x00040000, 0x800, KL_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */
kl_gen_add_flash(t, 0x00040000, 0x00040000, 0x800, KL_WRITE_LEN); /* FlexNVM, 256 KB, 2 KB Sectors */
break;
default:
return false;
}
break;
case 0x010: /* K20 Family, DIEID=0x0 */
case 0x090: /* K20 Family, DIEID=0x1 */
case 0x110: /* K20 Family, DIEID=0x2 */
case 0x190: /* K20 Family, DIEID=0x3 */
case 0x230: /* K21 Family, DIEID=0x4 */
case 0x330: /* K21 Family, DIEID=0x6 */
case 0x210: /* K22 Family, DIEID=0x4 */
case 0x310: /* K22 Family, DIEID=0x6 */
case 0x0a0: /* K30 Family, DIEID=0x1 */
case 0x120: /* K30 Family, DIEID=0x2 */
case 0x0b0: /* K40 Family, DIEID=0x1 */
case 0x130: /* K40 Family, DIEID=0x2 */
case 0x0e0: /* K50 Family, DIEID=0x1 */
case 0x0f0: /* K51 Family, DIEID=0x1 */
case 0x170: /* K53 Family, DIEID=0x2 */
case 0x140: /* K60 Family, DIEID=0x2 */
case 0x1c0: /* K60 Family, DIEID=0x3 */
case 0x1d0: /* K70 Family, DIEID=0x3 */
default:
return false;
}
break;
case 0x118: /* S32K118 */
t->driver = "S32K118";
target_add_ram(t, 0x1ffffc00, 0x00000400); /* SRAM_L, 1 KB */
target_add_ram(t, 0x20000000, 0x00005800); /* SRAM_H, 22 KB */
kl_gen_add_flash(t, 0x00000000, 0x00040000, 0x800, K64_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */
kl_gen_add_flash(t, 0x10000000, 0x00008000, 0x800, K64_WRITE_LEN); /* FlexNVM, 32 KB, 2 KB Sectors */
break;
default: default:
return false; return false;
} }

View File

@ -32,9 +32,6 @@
#define IAP_ENTRYPOINT 0x1FFF1FF1 #define IAP_ENTRYPOINT 0x1FFF1FF1
#define IAP_RAM_BASE 0x10000000 #define IAP_RAM_BASE 0x10000000
#define ARM_CPUID 0xE000ED00
#define CORTEX_M3_CPUID 0x412FC230 // Cortex-M3 r2p0
#define CORTEX_M3_CPUID_MASK 0xFF00FFF0
#define MEMMAP 0x400FC040 #define MEMMAP 0x400FC040
#define LPC17xx_JTAG_IDCODE 0x4BA00477 #define LPC17xx_JTAG_IDCODE 0x4BA00477
#define LPC17xx_SWDP_IDCODE 0x2BA01477 #define LPC17xx_SWDP_IDCODE 0x2BA01477
@ -82,8 +79,7 @@ lpc17xx_probe(target *t)
return false; return false;
} }
uint32_t cpuid = target_mem_read32(t, ARM_CPUID); if ((t->cpuid & CPUID_PARTNO_MASK) == CORTEX_M3) {
if (((cpuid & CORTEX_M3_CPUID_MASK) == (CORTEX_M3_CPUID & CORTEX_M3_CPUID_MASK))) {
/* /*
* Now that we're sure it's a Cortex-M3, we need to halt the * Now that we're sure it's a Cortex-M3, we need to halt the
* target and make an IAP call to get the part number. * target and make an IAP call to get the part number.

View File

@ -25,7 +25,6 @@
#include "lpc_common.h" #include "lpc_common.h"
#define LPC43XX_CHIPID 0x40043200 #define LPC43XX_CHIPID 0x40043200
#define ARM_CPUID 0xE000ED00
#define IAP_ENTRYPOINT_LOCATION 0x10400100 #define IAP_ENTRYPOINT_LOCATION 0x10400100
@ -80,19 +79,18 @@ void lpc43xx_add_flash(target *t, uint32_t iap_entry,
bool lpc43xx_probe(target *t) bool lpc43xx_probe(target *t)
{ {
uint32_t chipid, cpuid; uint32_t chipid;
uint32_t iap_entry; uint32_t iap_entry;
chipid = target_mem_read32(t, LPC43XX_CHIPID); chipid = target_mem_read32(t, LPC43XX_CHIPID);
cpuid = target_mem_read32(t, ARM_CPUID);
switch(chipid) { switch(chipid) {
case 0x4906002B: /* Parts with on-chip flash */ case 0x4906002B: /* Parts with on-chip flash */
case 0x7906002B: /* LM43S?? - Undocumented? */ case 0x7906002B: /* LM43S?? - Undocumented? */
switch (cpuid & 0xFF00FFF0) { switch (t->cpuid & 0xFF00FFF0) {
case 0x4100C240: case 0x4100C240:
t->driver = "LPC43xx Cortex-M4"; t->driver = "LPC43xx Cortex-M4";
if (cpuid == 0x410FC241) if (t->cpuid == 0x410FC241)
{ {
/* LPC4337 */ /* LPC4337 */
iap_entry = target_mem_read32(t, iap_entry = target_mem_read32(t,
@ -121,7 +119,7 @@ bool lpc43xx_probe(target *t)
return true; return true;
case 0x5906002B: /* Flashless parts */ case 0x5906002B: /* Flashless parts */
case 0x6906002B: case 0x6906002B:
switch (cpuid & 0xFF00FFF0) { switch (t->cpuid & 0xFF00FFF0) {
case 0x4100C240: case 0x4100C240:
t->driver = "LPC43xx Cortex-M4"; t->driver = "LPC43xx Cortex-M4";
break; break;

View File

@ -140,7 +140,7 @@ bool lpc546xx_probe(target *t)
target_add_commands(t, lpc546xx_cmd_list, "Lpc546xx"); target_add_commands(t, lpc546xx_cmd_list, "Lpc546xx");
t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; t->target_options |= CORTEXM_TOPT_INHIBIT_SRST;
return false; return true;
} }
/* Reset all major systems _except_ debug */ /* Reset all major systems _except_ debug */

View File

@ -118,7 +118,10 @@ static void stm32f1_add_flash(target *t,
bool stm32f1_probe(target *t) bool stm32f1_probe(target *t)
{ {
if (t->t_designer == AP_DESIGNER_ARM) uint16_t stored_idcode = t->idcode;
if ((t->cpuid & CPUID_PARTNO_MASK) == CORTEX_M0)
t->idcode = target_mem_read32(t, DBGMCU_IDCODE_F0) & 0xfff;
else
t->idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xfff; t->idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xfff;
size_t flash_size; size_t flash_size;
size_t block_size = 0x400; size_t block_size = 0x400;
@ -191,6 +194,7 @@ bool stm32f1_probe(target *t)
block_size = 0x800; block_size = 0x800;
break; break;
default: /* NONE */ default: /* NONE */
t->idcode = stored_idcode;
return false; return false;
} }

View File

@ -106,7 +106,6 @@ static int stm32f4_flash_write(struct target_flash *f,
#define DBGMCU_IDCODE 0xE0042000 #define DBGMCU_IDCODE 0xE0042000
#define DBGMCU_CR 0xE0042004 #define DBGMCU_CR 0xE0042004
#define DBG_SLEEP (1 << 0) #define DBG_SLEEP (1 << 0)
#define ARM_CPUID 0xE000ED00
#define AXIM_BASE 0x8000000 #define AXIM_BASE 0x8000000
#define ITCM_BASE 0x0200000 #define ITCM_BASE 0x0200000
@ -208,8 +207,7 @@ bool stm32f4_probe(target *t)
/* F405 revision A have a wrong IDCODE, use ARM_CPUID to make the /* F405 revision A have a wrong IDCODE, use ARM_CPUID to make the
* distinction with F205. Revision is also wrong (0x2000 instead * distinction with F205. Revision is also wrong (0x2000 instead
* of 0x1000). See F40x/F41x errata. */ * of 0x1000). See F40x/F41x errata. */
uint32_t cpuid = target_mem_read32(t, ARM_CPUID); if ((t->cpuid & 0xFFF0) == CORTEX_M4)
if ((cpuid & 0xFFF0) == 0xC240)
t->idcode = ID_STM32F40X; t->idcode = ID_STM32F40X;
} }
switch(t->idcode) { switch(t->idcode) {

View File

@ -120,7 +120,8 @@ struct target_s {
/* Other stuff */ /* Other stuff */
const char *driver; const char *driver;
const char *core; uint32_t cpuid;
char *core;
char cmdline[MAX_CMDLINE]; char cmdline[MAX_CMDLINE];
target_addr heapinfo[4]; target_addr heapinfo[4];
struct target_command_s *commands; struct target_command_s *commands;