diff --git a/src/Makefile b/src/Makefile
index c054a4dc..2fe79232 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -126,8 +126,8 @@ all_platforms:
export PROBE_HOST=`basename $$DIRNAME` ;\
export CFLAGS=-Werror ;\
echo "Building for hardware platform: $$PROBE_HOST" ;\
- $(MAKE) $(MAKEFLAGS) clean ;\
- $(MAKE) $(MAKEFLAGS);\
+ $(MAKE) clean ;\
+ $(MAKE);\
if [ -f blackmagic.bin ]; then \
mv blackmagic.bin artifacts/blackmagic-$$PROBE_HOST.bin ;\
echo "
$$PROBE_HOST"\
diff --git a/src/command.c b/src/command.c
index ee18ab07..a0d98bf8 100644
--- a/src/command.c
+++ b/src/command.c
@@ -158,7 +158,9 @@ bool cmd_version(target *t, int argc, char **argv)
(void)argv;
gdb_out(BOARD_IDENT);
#if PC_HOSTED == 1
- gdb_outf("\n for %s, %s\n", info.manufacturer, info.product);
+ char ident[256];
+ gdb_ident(ident, sizeof(ident));
+ gdb_outf("\n for %s\n", ident);
#else
gdb_outf(", Hardware Version %d\n", platform_hwversion());
#endif
diff --git a/src/platforms/hosted/Makefile.inc b/src/platforms/hosted/Makefile.inc
index ddaec7ba..b73f6d75 100644
--- a/src/platforms/hosted/Makefile.inc
+++ b/src/platforms/hosted/Makefile.inc
@@ -2,6 +2,14 @@ SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DENABLE_DEBUG -DPLATFORM_HAS_DEBUG
CFLAGS +=-I ./target -I./platforms/pc
+# Define HOSTED_BMP_ONLY to '1' in order to build the hosted blackmagic
+# executable with support for native BMP probes only. This makes
+# linking against the libftdi and libusb libraries unnecessary. This can
+# be useful to minimize external dependencies, and make building on
+# windows systems easier.
+HOSTED_BMP_ONLY ?= 0
+CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY)
+
ifneq (, $(findstring linux, $(SYS)))
SRC += serial_unix.c
ifeq ($(ASAN), 1)
@@ -9,10 +17,16 @@ CFLAGS += -fsanitize=address
LDFLAGS += -lasan
endif
else ifneq (, $(findstring mingw, $(SYS)))
+# Build for windows versions Vista, and above, where the
+# 'SetupDiGetDevicePropertyW()' function is available
+CFLAGS += -D_WIN32_WINNT=0x600
SRC += serial_win.c
LDFLAGS += -lws2_32
LDFLAGS += -lsetupapi
else ifneq (, $(findstring cygwin, $(SYS)))
+# Build for windows versions Vista, and above, where the
+# 'SetupDiGetDevicePropertyW()' function is available
+CFLAGS += -D_WIN32_WINNT=0x600
SRC += serial_win.c
LDFLAGS += -lws2_32
LDFLAGS += -lsetupapi
@@ -24,27 +38,32 @@ LDFLAGS += -framework CoreFoundation
CFLAGS += -Ihidapi/hidapi
endif
+ifneq ($(HOSTED_BMP_ONLY), 1)
LDFLAGS += -lusb-1.0
CFLAGS += $(shell pkg-config --cflags libftdi1)
LDFLAGS += $(shell pkg-config --libs libftdi1)
CFLAGS += -Wno-missing-field-initializers
+endif
-ifneq (, $(findstring mingw, $(SYS)))
- SRC += cmsis_dap.c dap.c hid.c
+ifneq ($(HOSTED_BMP_ONLY), 1)
CFLAGS += -DCMSIS_DAP
-else
- ifeq ($(shell pkg-config --exists hidapi-libusb && echo 0), 0)
+ SRC += cmsis_dap.c dap.c
+ ifneq (, $(findstring mingw, $(SYS)))
+ SRC += hid.c
+ else
CFLAGS += $(shell pkg-config --cflags hidapi-libusb)
LDFLAGS += $(shell pkg-config --libs hidapi-libusb)
- CFLAGS += -DCMSIS_DAP
- SRC += cmsis_dap.c dap.c
endif
endif
VPATH += platforms/pc
-SRC += timing.c cl_utils.c utils.c libusb_utils.c
-SRC += stlinkv2.c
+SRC += timing.c cl_utils.c utils.c
SRC += bmp_remote.c remote_swdptap.c remote_jtagtap.c
+ifneq ($(HOSTED_BMP_ONLY), 1)
+SRC += bmp_libusb.c stlinkv2.c
SRC += ftdi_bmp.c libftdi_swdptap.c libftdi_jtagtap.c
SRC += jlink.c jlink_adiv5_swdp.c jlink_jtagtap.c
+else
+SRC += bmp_serial.c
+endif
PC_HOSTED = 1
diff --git a/src/platforms/hosted/bmp_hosted.h b/src/platforms/hosted/bmp_hosted.h
new file mode 100644
index 00000000..861971c4
--- /dev/null
+++ b/src/platforms/hosted/bmp_hosted.h
@@ -0,0 +1,48 @@
+#if !defined(__BMP_LIBUSB_H)
+#define __BMP_LIBUSB_H
+
+#include "cl_utils.h"
+
+#if HOSTED_BMP_ONLY != 1
+# include
+struct trans_ctx {
+#define TRANS_FLAGS_IS_DONE (1 << 0)
+#define TRANS_FLAGS_HAS_ERROR (1 << 1)
+ volatile unsigned long flags;
+};
+
+typedef struct usb_link_s {
+ libusb_context *ul_libusb_ctx;
+ libusb_device_handle *ul_libusb_device_handle;
+ unsigned char ep_tx;
+ unsigned char ep_rx;
+ struct libusb_transfer* req_trans;
+ struct libusb_transfer* rep_trans;
+ void *priv;
+} usb_link_t;
+
+int send_recv(usb_link_t *link, uint8_t *txbuf, size_t txsize,
+ uint8_t *rxbuf, size_t rxsize);
+#endif
+typedef struct bmp_info_s {
+ bmp_type_t bmp_type;
+ char dev;
+ char serial[64];
+ char manufacturer[128];
+ char product[128];
+ char version[128];
+#if HOSTED_BMP_ONLY != 1
+ libusb_context *libusb_ctx;
+ struct ftdi_context *ftdic;
+ usb_link_t *usb_link;
+ unsigned int vid;
+ unsigned int pid;
+#endif
+} bmp_info_t;
+
+extern bmp_info_t info;
+void bmp_ident(bmp_info_t *info);
+int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info);
+void libusb_exit_function(bmp_info_t *info);
+
+#endif
diff --git a/src/platforms/hosted/bmp_libusb.c b/src/platforms/hosted/bmp_libusb.c
new file mode 100644
index 00000000..e24bdda6
--- /dev/null
+++ b/src/platforms/hosted/bmp_libusb.c
@@ -0,0 +1,397 @@
+/*
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/* Find all known usb connected debuggers */
+#include "general.h"
+#include "libusb-1.0/libusb.h"
+#include "cl_utils.h"
+#include "ftdi_bmp.h"
+#include "version.h"
+
+#define VENDOR_ID_STLINK 0x0483
+#define PRODUCT_ID_STLINK_MASK 0xffe0
+#define PRODUCT_ID_STLINK_GROUP 0x3740
+#define PRODUCT_ID_STLINKV1 0x3744
+#define PRODUCT_ID_STLINKV2 0x3748
+#define PRODUCT_ID_STLINKV21 0x374b
+#define PRODUCT_ID_STLINKV21_MSD 0x3752
+#define PRODUCT_ID_STLINKV3 0x374f
+#define PRODUCT_ID_STLINKV3E 0x374e
+
+#define VENDOR_ID_SEGGER 0x1366
+
+void bmp_ident(bmp_info_t *info)
+{
+ DEBUG_INFO("BMP hosted %s\n for ST-Link V2/3, CMSIS_DAP, JLINK and "
+ "LIBFTDI/MPSSE\n", FIRMWARE_VERSION);
+ if (info && info->vid && info->pid)
+ DEBUG_INFO("Using %04x:%04x %s %s\n %s\n", info->vid, info->pid,
+ info->serial,
+ info->manufacturer,
+ info->product);
+}
+
+void libusb_exit_function(bmp_info_t *info)
+{
+ if (!info->usb_link)
+ return;
+ libusb_free_transfer(info->usb_link->req_trans);
+ libusb_free_transfer(info->usb_link->rep_trans);
+ if (info->usb_link->ul_libusb_device_handle) {
+ libusb_release_interface (
+ info->usb_link->ul_libusb_device_handle, 0);
+ libusb_close(info->usb_link->ul_libusb_device_handle);
+ }
+}
+
+int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
+{
+ libusb_device **devs;
+ int res = libusb_init(&info->libusb_ctx);
+ if (res) {
+ DEBUG_WARN( "Fatal: Failed to get USB context: %s\n",
+ libusb_strerror(res));
+ exit(-1);
+ }
+ res = libusb_init(&info->libusb_ctx);
+ if (res) {
+ DEBUG_WARN( "Fatal: Failed to get USB context: %s\n",
+ libusb_strerror(res));
+ exit(-1);
+ }
+ if (cl_opts->opt_cable) {
+ if ((!strcmp(cl_opts->opt_cable, "list")) ||
+ (!strcmp(cl_opts->opt_cable, "l"))) {
+ cable_desc_t *cable = &cable_desc[0];
+ DEBUG_WARN("Available cables:\n");
+ for (; cable->name; cable++) {
+ DEBUG_WARN("\t%s\n", cable->name);
+ }
+ exit(0);
+ }
+ info->bmp_type = BMP_TYPE_LIBFTDI;
+ }
+ int n_devs = libusb_get_device_list(info->libusb_ctx, &devs);
+ if (n_devs < 0) {
+ DEBUG_WARN( "WARN:libusb_get_device_list() failed");
+ return -1;
+ }
+ bool report = false;
+ int found_debuggers;
+ struct libusb_device_descriptor desc;
+ char serial[64];
+ char manufacturer[128];
+ char product[128];
+ bmp_type_t type;
+ bool access_problems = false;
+ char *active_cable = NULL;
+ bool ftdi_unknown = false;
+ rescan:
+ type = BMP_TYPE_NONE;
+ found_debuggers = 0;
+ serial[0] = 0;
+ manufacturer[0] = 0;
+ product[0] = 0;
+ access_problems = false;
+ active_cable = NULL;
+ ftdi_unknown = false;
+ for (int i = 0; devs[i]; i++) {
+ libusb_device *dev = devs[i];
+ int res = libusb_get_device_descriptor(dev, &desc);
+ if (res < 0) {
+ DEBUG_WARN( "WARN: libusb_get_device_descriptor() failed: %s",
+ libusb_strerror(res));
+ libusb_free_device_list(devs, 1);
+ continue;
+ }
+ /* Exclude hubs from testing. Probably more classes could be excluded here!*/
+ if (desc.bDeviceClass == LIBUSB_CLASS_HUB) {
+ continue;
+ }
+ libusb_device_handle *handle;
+ res = libusb_open(dev, &handle);
+ if (res != LIBUSB_SUCCESS) {
+ if (!access_problems) {
+ DEBUG_INFO("INFO: Open USB %04x:%04x class %2x failed\n",
+ desc.idVendor, desc.idProduct, desc.bDeviceClass);
+ access_problems = true;
+ }
+ continue;
+ }
+ res = libusb_get_string_descriptor_ascii(
+ handle, desc.iSerialNumber, (uint8_t*)serial,
+ sizeof(serial));
+ if (cl_opts->opt_serial && ((res <= 0) ||
+ !strstr(serial, cl_opts->opt_serial))) {
+ libusb_close(handle);
+ continue;
+ }
+ res = libusb_get_string_descriptor_ascii(
+ handle, desc.iManufacturer, (uint8_t*)manufacturer,
+ sizeof(manufacturer));
+ if (res > 0) {
+ res = libusb_get_string_descriptor_ascii(
+ handle, desc.iProduct, (uint8_t*)product,
+ sizeof(product));
+ if (res <= 0) {
+ DEBUG_WARN( "WARN:"
+ "libusb_get_string_descriptor_ascii "
+ "for ident_string failed: %s\n",
+ libusb_strerror(res));
+ libusb_close(handle);
+ continue;
+ }
+ } else {
+ libusb_close(handle);
+ continue;
+ }
+ libusb_close(handle);
+ if (cl_opts->opt_ident_string) {
+ char *match_manu = NULL;
+ char *match_product = NULL;
+ match_manu = strstr(manufacturer, cl_opts->opt_ident_string);
+ match_product = strstr(product, cl_opts->opt_ident_string);
+ if (!match_manu && !match_product) {
+ continue;
+ }
+ }
+ /* Either serial and/or ident_string match or are not given.
+ * Check type.*/
+ if (desc.idVendor == VENDOR_ID_BMP) {
+ if (desc.idProduct == PRODUCT_ID_BMP) {
+ type = BMP_TYPE_BMP;
+ } else if (desc.idProduct == PRODUCT_ID_BMP_BL) {
+ DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n");
+ continue;
+ }
+ } else if ((strstr(manufacturer, "CMSIS")) || (strstr(product, "CMSIS"))) {
+ type = BMP_TYPE_CMSIS_DAP;
+ } else if (desc.idVendor == VENDOR_ID_STLINK) {
+ if ((desc.idProduct == PRODUCT_ID_STLINKV2) ||
+ (desc.idProduct == PRODUCT_ID_STLINKV21) ||
+ (desc.idProduct == PRODUCT_ID_STLINKV21_MSD) ||
+ (desc.idProduct == PRODUCT_ID_STLINKV3) ||
+ (desc.idProduct == PRODUCT_ID_STLINKV3E)) {
+ type = BMP_TYPE_STLINKV2;
+ } else {
+ if (desc.idProduct == PRODUCT_ID_STLINKV1)
+ DEBUG_WARN( "INFO: STLINKV1 not supported\n");
+ continue;
+ }
+ } else if (desc.idVendor == VENDOR_ID_SEGGER) {
+ type = BMP_TYPE_JLINK;
+ } else {
+ cable_desc_t *cable = &cable_desc[0];
+ for (; cable->name; cable++) {
+ bool found = false;
+ if ((cable->vendor != desc.idVendor) || (cable->product != desc.idProduct))
+ continue; /* VID/PID do not match*/
+ if (cl_opts->opt_cable) {
+ if (strcmp(cable->name, cl_opts->opt_cable))
+ continue; /* cable names do not match*/
+ else
+ found = true;
+ }
+ if (cable->description) {
+ if (strcmp(cable->description, product))
+ continue; /* discriptions do not match*/
+ else
+ found = true;
+ } else { /* VID/PID fits, but no cl_opts->opt_cable and no description*/
+ if ((cable->vendor == 0x0403) && /* FTDI*/
+ ((cable->product == 0x6010) || /* FT2232C/D/H*/
+ (cable->product == 0x6011) || /* FT4232H Quad HS USB-UART/FIFO IC */
+ (cable->product == 0x6014))) { /* FT232H Single HS USB-UART/FIFO IC */
+ ftdi_unknown = true;
+ continue; /* Cable name is needed */
+ }
+ }
+ if (found) {
+ active_cable = cable->name;
+ type = BMP_TYPE_LIBFTDI;
+ break;
+ }
+ }
+ if (!cable->name)
+ continue;
+ }
+ if (report) {
+ DEBUG_WARN("%2d: %s, %s, %s\n", found_debuggers + 1,
+ serial,
+ manufacturer,product);
+ }
+ info->vid = desc.idVendor;
+ info->pid = desc.idProduct;
+ info->bmp_type = type;
+ strncpy(info->serial, serial, sizeof(info->serial));
+ strncpy(info->product, product, sizeof(info->product));
+ strncpy(info->manufacturer, manufacturer, sizeof(info->manufacturer));
+ if (cl_opts->opt_position &&
+ (cl_opts->opt_position == (found_debuggers + 1))) {
+ found_debuggers = 1;
+ break;
+ } else {
+ found_debuggers++;
+ }
+ }
+ if ((found_debuggers == 0) && ftdi_unknown)
+ DEBUG_WARN("Generic FTDI MPSSE VID/PID found. Please specify exact type with \"-c \" !\n");
+ if ((found_debuggers == 1) && !cl_opts->opt_cable && (type == BMP_TYPE_LIBFTDI))
+ cl_opts->opt_cable = active_cable;
+ if (!found_debuggers && cl_opts->opt_list_only)
+ DEBUG_WARN("No usable debugger found\n");
+ if ((found_debuggers > 1) ||
+ ((found_debuggers == 1) && (cl_opts->opt_list_only))) {
+ if (!report) {
+ if (found_debuggers > 1)
+ DEBUG_WARN("%d debuggers found!\nSelect with -P , "
+ "-s <(partial)serial no.> "
+ "and/or -S <(partial)description>\n",
+ found_debuggers);
+ report = true;
+ goto rescan;
+ } else {
+ if (found_debuggers > 0)
+ access_problems = false;
+ found_debuggers = 0;
+ }
+ }
+ if (!found_debuggers && access_problems)
+ DEBUG_WARN(
+ "No debugger found. Please check access rights to USB devices!\n");
+ libusb_free_device_list(devs, 1);
+ return (found_debuggers == 1) ? 0 : -1;
+}
+static void LIBUSB_CALL on_trans_done(struct libusb_transfer *trans)
+{
+ struct trans_ctx * const ctx = trans->user_data;
+
+ if (trans->status != LIBUSB_TRANSFER_COMPLETED)
+ {
+ DEBUG_WARN("on_trans_done: ");
+ if(trans->status == LIBUSB_TRANSFER_TIMED_OUT) {
+ DEBUG_WARN(" Timeout\n");
+ } else if (trans->status == LIBUSB_TRANSFER_CANCELLED) {
+ DEBUG_WARN(" cancelled\n");
+ } else if (trans->status == LIBUSB_TRANSFER_NO_DEVICE) {
+ DEBUG_WARN(" no device\n");
+ } else {
+ DEBUG_WARN(" unknown\n");
+ }
+ ctx->flags |= TRANS_FLAGS_HAS_ERROR;
+ }
+ ctx->flags |= TRANS_FLAGS_IS_DONE;
+}
+
+static int submit_wait(usb_link_t *link, struct libusb_transfer *trans) {
+ struct trans_ctx trans_ctx;
+ enum libusb_error error;
+
+ trans_ctx.flags = 0;
+
+ /* brief intrusion inside the libusb interface */
+ trans->callback = on_trans_done;
+ trans->user_data = &trans_ctx;
+
+ if ((error = libusb_submit_transfer(trans))) {
+ DEBUG_WARN("libusb_submit_transfer(%d): %s\n", error,
+ libusb_strerror(error));
+ exit(-1);
+ }
+
+ uint32_t start_time = platform_time_ms();
+ while (trans_ctx.flags == 0) {
+ struct timeval timeout;
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ if (libusb_handle_events_timeout(link->ul_libusb_ctx, &timeout)) {
+ DEBUG_WARN("libusb_handle_events()\n");
+ return -1;
+ }
+ uint32_t now = platform_time_ms();
+ if (now - start_time > 1000) {
+ libusb_cancel_transfer(trans);
+ DEBUG_WARN("libusb_handle_events() timeout\n");
+ return -1;
+ }
+ }
+ if (trans_ctx.flags & TRANS_FLAGS_HAS_ERROR) {
+ DEBUG_WARN("libusb_handle_events() | has_error\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* One USB transaction */
+int send_recv(usb_link_t *link,
+ uint8_t *txbuf, size_t txsize,
+ uint8_t *rxbuf, size_t rxsize)
+{
+ int res = 0;
+ if( txsize) {
+ int txlen = txsize;
+ libusb_fill_bulk_transfer(link->req_trans,
+ link->ul_libusb_device_handle,
+ link->ep_tx | LIBUSB_ENDPOINT_OUT,
+ txbuf, txlen,
+ NULL, NULL, 0);
+ int i = 0;
+ DEBUG_WIRE(" Send (%3d): ", txlen);
+ for (; i < txlen; i++) {
+ DEBUG_WIRE("%02x", txbuf[i]);
+ if ((i & 7) == 7)
+ DEBUG_WIRE(".");
+ if ((i & 31) == 31)
+ DEBUG_WIRE("\n ");
+ }
+ if (!(i & 31))
+ DEBUG_WIRE("\n");
+ if (submit_wait(link, link->req_trans)) {
+ libusb_clear_halt(link->ul_libusb_device_handle, link->ep_tx);
+ return -1;
+ }
+ }
+ /* send_only */
+ if (rxsize != 0) {
+ /* read the response */
+ libusb_fill_bulk_transfer(link->rep_trans, link->ul_libusb_device_handle,
+ link->ep_rx | LIBUSB_ENDPOINT_IN,
+ rxbuf, rxsize, NULL, NULL, 0);
+
+ if (submit_wait(link, link->rep_trans)) {
+ DEBUG_WARN("clear 1\n");
+ libusb_clear_halt(link->ul_libusb_device_handle, link->ep_rx);
+ return -1;
+ }
+ res = link->rep_trans->actual_length;
+ if (res >0) {
+ int i;
+ uint8_t *p = rxbuf;
+ DEBUG_WIRE(" Rec (%zu/%d)", rxsize, res);
+ for (i = 0; i < res && i < 32 ; i++) {
+ if ( i && ((i & 7) == 0))
+ DEBUG_WIRE(".");
+ DEBUG_WIRE("%02x", p[i]);
+ }
+ }
+ }
+ DEBUG_WIRE("\n");
+ return res;
+}
diff --git a/src/platforms/hosted/bmp_serial.c b/src/platforms/hosted/bmp_serial.c
new file mode 100644
index 00000000..098c1477
--- /dev/null
+++ b/src/platforms/hosted/bmp_serial.c
@@ -0,0 +1,281 @@
+/*
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/* Find all known serial connected debuggers */
+
+#include
+#include
+#include
+#include "general.h"
+#include "platform.h"
+#include "bmp_hosted.h"
+#include "version.h"
+
+void bmp_ident(bmp_info_t *info)
+{
+ (void) info;
+ DEBUG_INFO("BMP hosted (BMP Only) %s\n", FIRMWARE_VERSION);
+}
+
+void libusb_exit_function(bmp_info_t *info) {(void)info;};
+
+
+#ifdef __APPLE__
+int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
+{
+ (void)cl_opts;
+ (void)info;
+ return -1;
+}
+#elif defined(__WIN32__) || defined(__CYGWIN__)
+
+
+/* This source has been used as an example:
+ * https://stackoverflow.com/questions/3438366/setupdigetdeviceproperty-usage-example */
+
+#include
+#include
+#include // for MAX_DEVICE_ID_LEN, CM_Get_Parent and CM_Get_Device_ID
+#include
+#include
+
+/* include DEVPKEY_Device_BusReportedDeviceDesc from WinDDK\7600.16385.1\inc\api\devpropdef.h */
+#ifdef DEFINE_DEVPROPKEY
+#undef DEFINE_DEVPROPKEY
+#endif
+#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) const DEVPROPKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
+
+/* include DEVPKEY_Device_BusReportedDeviceDesc from WinDDK\7600.16385.1\inc\api\devpkey.h */
+DEFINE_DEVPROPKEY(DEVPKEY_Device_BusReportedDeviceDesc, 0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 4); // DEVPROP_TYPE_STRING
+
+/* List all USB devices with some additional information.
+ * Unfortunately, this code is quite ugly. */
+int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
+{
+ unsigned i;
+ DWORD dwSize;
+ DEVPROPTYPE ulPropertyType;
+ CONFIGRET status;
+ HDEVINFO hDevInfo;
+ SP_DEVINFO_DATA DeviceInfoData;
+ TCHAR szDeviceInstanceID [MAX_DEVICE_ID_LEN];
+ WCHAR busReportedDeviceSesc[4096];
+ int probes_found = 0;
+ bool is_printing_probes_info = cl_opts->opt_list_only != 0;
+
+ info->bmp_type = BMP_TYPE_BMP;
+
+ hDevInfo = SetupDiGetClassDevs (0, "USB", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
+ if (hDevInfo == INVALID_HANDLE_VALUE)
+ return -1;
+print_probes_info:
+ for (i = 0; ; i++) {
+ char serial_number[sizeof info->serial];
+ DeviceInfoData.cbSize = sizeof (DeviceInfoData);
+ if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
+ break;
+
+ status = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID , MAX_PATH, 0);
+ if (status != CR_SUCCESS)
+ continue;
+
+ if (!sscanf(szDeviceInstanceID, "USB\\VID_1D50&PID_6018\\%s", serial_number))
+ continue;
+
+ if (SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc,
+ &ulPropertyType, (BYTE*)busReportedDeviceSesc, sizeof busReportedDeviceSesc, &dwSize, 0))
+ {
+ probes_found ++;
+ if (is_printing_probes_info)
+ {
+ DEBUG_WARN("%2d: %s, %ls\n", probes_found,
+ serial_number, busReportedDeviceSesc);
+ }
+ else
+ {
+ bool probe_identified = true;
+ if ((cl_opts->opt_serial && strstr(serial_number, cl_opts->opt_serial)) ||
+ (cl_opts->opt_position && cl_opts->opt_position == probes_found) ||
+ /* Special case for the very first probe found. */
+ (probe_identified = false, probes_found == 1)) {
+
+ strncpy(info->serial, serial_number, sizeof info->serial);
+ strncpy(info->manufacturer, "BMP", sizeof info->manufacturer);
+ snprintf(info->product, sizeof info->product, "%ls", busReportedDeviceSesc);
+ /* Don't bother to parse the version string. It is a part of the
+ * product description string. It seems that at the moment it
+ * is only being used to print a version string in response
+ * to the 'monitor version' command, so it doesn't really matter
+ * if the version string is printed as a part of the product string,
+ * or as a separate string, the result is pretty much the same. */
+ info->version[0] = 0;
+ if (probe_identified)
+ return 0;
+ }
+ }
+ }
+ }
+ if (is_printing_probes_info)
+ return 1;
+ if (probes_found == 1)
+ /* Exactly one probe found. Its information has already been filled
+ * in the detection loop, so use this probe. */
+ return 0;
+ if (probes_found < 1) {
+ DEBUG_WARN("No BMP probe found\n");
+ return -1;
+ }
+ /* Otherwise, if this line is reached, then more than one probe has been found,
+ * and no probe was identified as selected by the user.
+ * Restart the identification loop, this time printing the probe information,
+ * and then return. */
+ DEBUG_WARN("%d debuggers found!\nSelect with -P , or "
+ "-s <(partial)serial no.>\n",
+ probes_found);
+ probes_found = 0;
+ is_printing_probes_info = true;
+ goto print_probes_info;
+}
+
+#else
+#define BMP_IDSTRING "usb-Black_Sphere_Technologies_Black_Magic_Probe"
+#define DEVICE_BY_ID "/dev/serial/by-id/"
+
+/*
+ * Extract type, version and serial from /dev/serial/by_id
+ * Return 0 on success
+ *
+ * Old versions have different strings. Try to cope!
+ */
+static int scan_linux_id(char *name, char *type, char *version, char *serial)
+{
+ name += strlen(BMP_IDSTRING) + 1;
+ while (*name == '_')
+ name++;
+ if (!*name) {
+ DEBUG_WARN("Unexpected end\n");
+ return -1;
+ }
+ char *p = strchr(name, '_');
+ if (!p) {
+ DEBUG_WARN("type not found\n");
+ return -1;
+ }
+ strncpy(type, name, p - name);
+ name = p;
+ while (*name != 'v')
+ name++;
+ if (!*name) {
+ DEBUG_WARN("Unexpected end after type\n");
+ return -1;
+ }
+ p = strchr(name, '_');
+ if (!p) {
+ DEBUG_WARN("version not found\n");
+ return -1;
+ }
+ strncpy(version, name, p - name);
+ name = p;
+ while (*name == '_')
+ name++;
+ if (!*name) {
+ DEBUG_WARN("Unexpected end after version\n");
+ return -1;
+ }
+ p = strchr(name, '-');
+ if (!p) {
+ DEBUG_WARN("Serial not found\n");
+ return -1;
+ }
+ strncpy(serial, name, p - name);
+ return 0;
+}
+
+int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
+{
+ char name[4096];
+ if (cl_opts->opt_device)
+ return 1;
+ info->bmp_type = BMP_TYPE_BMP;
+ DIR *dir = opendir(DEVICE_BY_ID);
+ if (!dir) {
+ DEBUG_WARN("Could not opendir %s: %s\n", name, strerror(errno));
+ return -1;
+ }
+ int found_bmps = 0;
+ struct dirent *dp;
+ int i = 0;
+ while ((dp = readdir(dir)) != NULL) {
+ if ((strstr(dp->d_name, BMP_IDSTRING)) &&
+ (strstr(dp->d_name, "-if00"))) {
+ i++;
+ char type[256], version[256], serial[256];
+ if (scan_linux_id(dp->d_name, type, version, serial)) {
+ DEBUG_WARN("Unexpected device name found \"%s\"\n",
+ dp->d_name);
+ }
+ if ((cl_opts->opt_serial && strstr(serial, cl_opts->opt_serial)) ||
+ (cl_opts->opt_position && cl_opts->opt_position == i)) {
+ /* With serial number given and partial match, we are done!*/
+ strncpy(info->serial, serial, sizeof(info->serial));
+ strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer));
+ strncpy(info->product, type, sizeof(info->product));
+ strncpy(info->version, version, sizeof(info->version));
+ found_bmps = 1;
+ break;
+ } else {
+ found_bmps++;
+ }
+ }
+ }
+ closedir(dir);
+ if (found_bmps < 1) {
+ DEBUG_WARN("No BMP probe found\n");
+ return -1;
+ } else if (found_bmps > 1) {
+ DEBUG_INFO("Available Probes:\n");
+ }
+ dir = opendir(DEVICE_BY_ID);
+ i = 0;
+ while ((dp = readdir(dir)) != NULL) {
+ if ((strstr(dp->d_name, BMP_IDSTRING)) &&
+ (strstr(dp->d_name, "-if00"))) {
+ i++;
+ char type[256], version[256], serial[256];
+ if (scan_linux_id(dp->d_name, type, version, serial)) {
+ DEBUG_WARN("Unexpected device name found \"%s\"\n",
+ dp->d_name);
+ } else if (found_bmps == 1) {
+ strncpy(info->serial, serial, sizeof(info->serial));
+ found_bmps = 1;
+ strncpy(info->serial, serial, sizeof(info->serial));
+ strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer));
+ strncpy(info->product, type, sizeof(info->product));
+ strncpy(info->version, version, sizeof(info->version));
+ break;
+ } else if (found_bmps > 1) {
+ DEBUG_WARN("%2d: %s, Black Sphere Technologies, Black Magic "
+ "Probe (%s), %s\n", i, serial, type, version);
+ }
+ }
+ }
+ closedir(dir);
+ return (found_bmps == 1) ? 0 : 1;
+}
+#endif
diff --git a/src/platforms/hosted/cmsis_dap.c b/src/platforms/hosted/cmsis_dap.c
index 4d2bb0bd..c1e9668f 100644
--- a/src/platforms/hosted/cmsis_dap.c
+++ b/src/platforms/hosted/cmsis_dap.c
@@ -34,6 +34,7 @@
#include
#include
+#include "bmp_hosted.h"
#include "dap.h"
#include "cmsis_dap.h"
@@ -55,18 +56,18 @@ int dap_init(bmp_info_t *info)
if (hid_init())
return -1;
int size = strlen(info->serial);
- wchar_t serial[size + 1], *wc = serial;
+ wchar_t serial[64] = {0}, *wc = serial;
for (int i = 0; i < size; i++)
*wc++ = info->serial[i];
*wc = 0;
- /* Blacklist devices that do not wirk with 513 byte report length
+ /* Blacklist devices that do not work with 513 byte report length
* FIXME: Find a solution to decipher from the device.
*/
if ((info->vid == 0x1fc9) && (info->pid == 0x0132)) {
DEBUG_WARN("Blacklist\n");
report_size = 64 + 1;
}
- handle = hid_open(info->vid, info->pid, serial);
+ handle = hid_open(info->vid, info->pid, (serial[0]) ? serial : NULL);
if (!handle)
return -1;
dap_disconnect();
diff --git a/src/platforms/hosted/ftdi_bmp.c b/src/platforms/hosted/ftdi_bmp.c
index 306e0259..d7ea3d7b 100644
--- a/src/platforms/hosted/ftdi_bmp.c
+++ b/src/platforms/hosted/ftdi_bmp.c
@@ -28,6 +28,7 @@
#include
#include "ftdi_bmp.h"
+#include
struct ftdi_context *ftdic;
diff --git a/src/platforms/hosted/ftdi_bmp.h b/src/platforms/hosted/ftdi_bmp.h
index fc2a8def..12c90223 100644
--- a/src/platforms/hosted/ftdi_bmp.h
+++ b/src/platforms/hosted/ftdi_bmp.h
@@ -26,6 +26,9 @@
#include "swdptap.h"
#include "jtagtap.h"
+#include "bmp_hosted.h"
+#include
+
typedef struct data_desc_s {
int16_t data_low;
int16_t ddr_low;
@@ -103,8 +106,22 @@ extern cable_desc_t *active_cable;
extern struct ftdi_context *ftdic;
extern data_desc_t active_state;
+#if HOSTED_BMP_ONLY == 1
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-parameter"
+int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) {return -1;};
+int libftdi_swdptap_init(swd_proc_t *swd_proc) {return -1;};
+int libftdi_jtagtap_init(jtag_proc_t *jtag_proc) {return 0;};
+void libftdi_buffer_flush(void) {};
+int libftdi_buffer_write(const uint8_t *data, int size) {return size;};
+int libftdi_buffer_read(uint8_t *data, int size) {return size;};
+const char *libftdi_target_voltage(void) {return "ERROR";};
+void libftdi_jtagtap_tdi_tdo_seq(
+ uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks) {};
+bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd) {return false;};
+# pragma GCC diagnostic pop
+#else
int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info);
-
int libftdi_swdptap_init(swd_proc_t *swd_proc);
int libftdi_jtagtap_init(jtag_proc_t *jtag_proc);
void libftdi_buffer_flush(void);
@@ -114,6 +131,7 @@ const char *libftdi_target_voltage(void);
void libftdi_jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks);
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd);
+#endif
#define MPSSE_SK 1
#define PIN0 1
diff --git a/src/platforms/hosted/jlink.h b/src/platforms/hosted/jlink.h
index 27e81bf1..c79b8683 100644
--- a/src/platforms/hosted/jlink.h
+++ b/src/platforms/hosted/jlink.h
@@ -19,6 +19,7 @@
#if !defined(__JLINK_H_)
#define __JLINK_H_
+#include "bmp_hosted.h"
#include "jtagtap.h"
/** @cond PRIVATE */
@@ -43,7 +44,17 @@
#define SELECT_IF_JTAG 0
#define SELECT_IF_SWD 1
-
+#if HOSTED_BMP_ONLY == 1
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-parameter"
+int jlink_init(bmp_info_t *info) {return -1;};
+int jlink_swdp_scan(bmp_info_t *info) {return 0;};
+int jlink_jtagtap_init(bmp_info_t *info, jtag_proc_t *jtag_proc) {return 0;};
+const char *jlink_target_voltage(bmp_info_t *info) {return "ERROR";};
+void jlink_srst_set_val(bmp_info_t *info, bool assert) {};
+bool jlink_srst_get_val(bmp_info_t *info) {return true;};
+# pragma GCC diagnostic pop
+#else
int jlink_init(bmp_info_t *info);
int jlink_swdp_scan(bmp_info_t *info);
int jlink_jtagtap_init(bmp_info_t *info, jtag_proc_t *jtag_proc);
@@ -51,3 +62,4 @@ const char *jlink_target_voltage(bmp_info_t *info);
void jlink_srst_set_val(bmp_info_t *info, bool assert);
bool jlink_srst_get_val(bmp_info_t *info);
#endif
+#endif
diff --git a/src/platforms/hosted/libftdi_jtagtap.c b/src/platforms/hosted/libftdi_jtagtap.c
index 7642129d..043467be 100644
--- a/src/platforms/hosted/libftdi_jtagtap.c
+++ b/src/platforms/hosted/libftdi_jtagtap.c
@@ -25,11 +25,12 @@
#include
#include
#include
-
#include
+#include
+#include "platform.h"
+#include "ftdi_bmp.h"
#include "general.h"
-#include "ftdi_bmp.h"
extern cable_desc_t *active_cable;
extern struct ftdi_context *ftdic;
diff --git a/src/platforms/hosted/libftdi_swdptap.c b/src/platforms/hosted/libftdi_swdptap.c
index 99ee0068..cd2cf50c 100644
--- a/src/platforms/hosted/libftdi_swdptap.c
+++ b/src/platforms/hosted/libftdi_swdptap.c
@@ -26,6 +26,8 @@
#include
#include "general.h"
+#include
+#include "platform.h"
#include "ftdi_bmp.h"
enum swdio_status{
diff --git a/src/platforms/hosted/platform.c b/src/platforms/hosted/platform.c
index f70ef859..8df0dbe5 100644
--- a/src/platforms/hosted/platform.c
+++ b/src/platforms/hosted/platform.c
@@ -32,40 +32,27 @@
#include
#include "bmp_remote.h"
+#include "bmp_hosted.h"
#include "stlinkv2.h"
#include "ftdi_bmp.h"
#include "jlink.h"
#include "cmsis_dap.h"
-#include "version.h"
-
-#define VENDOR_ID_STLINK 0x0483
-#define PRODUCT_ID_STLINK_MASK 0xffe0
-#define PRODUCT_ID_STLINK_GROUP 0x3740
-#define PRODUCT_ID_STLINKV1 0x3744
-#define PRODUCT_ID_STLINKV2 0x3748
-#define PRODUCT_ID_STLINKV21 0x374b
-#define PRODUCT_ID_STLINKV21_MSD 0x3752
-#define PRODUCT_ID_STLINKV3 0x374f
-#define PRODUCT_ID_STLINKV3E 0x374e
-
-#define VENDOR_ID_SEGGER 0x1366
+#include "cl_utils.h"
bmp_info_t info;
swd_proc_t swd_proc;
jtag_proc_t jtag_proc;
+void gdb_ident(char *p, int count)
+{
+ snprintf(p, count, "%s (%s), %s", info.manufacturer, info.product,
+ info.version);
+}
+
static void exit_function(void)
{
- if(info.usb_link) {
- libusb_free_transfer(info.usb_link->req_trans);
- libusb_free_transfer(info.usb_link->rep_trans);
- if (info.usb_link->ul_libusb_device_handle) {
- libusb_release_interface (
- info.usb_link->ul_libusb_device_handle, 0);
- libusb_close(info.usb_link->ul_libusb_device_handle);
- }
- }
+ libusb_exit_function(&info);
switch (info.bmp_type) {
case BMP_TYPE_CMSIS_DAP:
dap_exit_function();
@@ -83,231 +70,20 @@ static void sigterm_handler(int sig)
exit(0);
}
-static int find_debuggers( BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
-{
- libusb_device **devs;
- int n_devs = libusb_get_device_list(info->libusb_ctx, &devs);
- if (n_devs < 0) {
- DEBUG_WARN( "WARN:libusb_get_device_list() failed");
- return -1;
- }
- bool report = false;
- int found_debuggers;
- struct libusb_device_descriptor desc;
- char serial[64];
- char manufacturer[128];
- char product[128];
- bmp_type_t type = BMP_TYPE_NONE;
- bool access_problems = false;
- char *active_cable = NULL;
- bool ftdi_unknown = false;
- rescan:
- found_debuggers = 0;
- for (int i = 0; devs[i]; i++) {
- libusb_device *dev = devs[i];
- int res = libusb_get_device_descriptor(dev, &desc);
- if (res < 0) {
- DEBUG_WARN( "WARN: libusb_get_device_descriptor() failed: %s",
- libusb_strerror(res));
- libusb_free_device_list(devs, 1);
- continue;
- }
- /* Exclude hubs from testing. Probably more classes could be excluded here!*/
- if (desc.bDeviceClass == LIBUSB_CLASS_HUB) {
- continue;
- }
- libusb_device_handle *handle;
- res = libusb_open(dev, &handle);
- if (res != LIBUSB_SUCCESS) {
- if (!access_problems) {
- DEBUG_INFO("INFO: Open USB %04x:%04x class %2x failed\n",
- desc.idVendor, desc.idProduct, desc.bDeviceClass);
- access_problems = true;
- }
- continue;
- }
- res = libusb_get_string_descriptor_ascii(
- handle, desc.iSerialNumber, (uint8_t*)serial,
- sizeof(serial));
- if (res <= 0) {
- /* This can fail for many devices. Continue silent!*/
- libusb_close(handle);
- continue;
- }
- if (cl_opts->opt_serial && !strstr(serial, cl_opts->opt_serial)) {
- libusb_close(handle);
- continue;
- }
- res = libusb_get_string_descriptor_ascii(
- handle, desc.iManufacturer, (uint8_t*)manufacturer,
- sizeof(manufacturer));
- if (res > 0) {
- res = libusb_get_string_descriptor_ascii(
- handle, desc.iProduct, (uint8_t*)product,
- sizeof(product));
- if (res <= 0) {
- DEBUG_WARN( "WARN:"
- "libusb_get_string_descriptor_ascii "
- "for ident_string failed: %s\n",
- libusb_strerror(res));
- libusb_close(handle);
- continue;
- }
- }
- libusb_close(handle);
- if (cl_opts->opt_ident_string) {
- char *match_manu = NULL;
- char *match_product = NULL;
- match_manu = strstr(manufacturer, cl_opts->opt_ident_string);
- match_product = strstr(product, cl_opts->opt_ident_string);
- if (!match_manu && !match_product) {
- continue;
- }
- }
- /* Either serial and/or ident_string match or are not given.
- * Check type.*/
- if (desc.idVendor == VENDOR_ID_BMP) {
- if (desc.idProduct == PRODUCT_ID_BMP) {
- type = BMP_TYPE_BMP;
- } else if (desc.idProduct == PRODUCT_ID_BMP_BL) {
- DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n");
- continue;
- }
- } else if ((strstr(manufacturer, "CMSIS")) || (strstr(product, "CMSIS"))) {
- type = BMP_TYPE_CMSIS_DAP;
- } else if (desc.idVendor == VENDOR_ID_STLINK) {
- if ((desc.idProduct == PRODUCT_ID_STLINKV2) ||
- (desc.idProduct == PRODUCT_ID_STLINKV21) ||
- (desc.idProduct == PRODUCT_ID_STLINKV21_MSD) ||
- (desc.idProduct == PRODUCT_ID_STLINKV3) ||
- (desc.idProduct == PRODUCT_ID_STLINKV3E)) {
- type = BMP_TYPE_STLINKV2;
- } else {
- if (desc.idProduct == PRODUCT_ID_STLINKV1)
- DEBUG_WARN( "INFO: STLINKV1 not supported\n");
- continue;
- }
- } else if (desc.idVendor == VENDOR_ID_SEGGER) {
- type = BMP_TYPE_JLINK;
- } else {
- cable_desc_t *cable = &cable_desc[0];
- for (; cable->name; cable++) {
- bool found = false;
- if ((cable->vendor != desc.idVendor) || (cable->product != desc.idProduct))
- continue; /* VID/PID do not match*/
- if (cl_opts->opt_cable) {
- if (strcmp(cable->name, cl_opts->opt_cable))
- continue; /* cable names do not match*/
- else
- found = true;
- }
- if (cable->description) {
- if (strcmp(cable->description, product))
- continue; /* discriptions do not match*/
- else
- found = true;
- } else { /* VID/PID fits, but no cl_opts->opt_cable and no description*/
- if ((cable->vendor == 0x0403) && /* FTDI*/
- ((cable->product == 0x6010) || /* FT2232C/D/H*/
- (cable->product == 0x6011) || /* FT4232H Quad HS USB-UART/FIFO IC */
- (cable->product == 0x6014))) { /* FT232H Single HS USB-UART/FIFO IC */
- ftdi_unknown = true;
- continue; /* Cable name is needed */
- }
- }
- if (found) {
- active_cable = cable->name;
- type = BMP_TYPE_LIBFTDI;
- break;
- }
- }
- if (!cable->name)
- continue;
- }
- if (report) {
- DEBUG_WARN("%2d: %s, %s, %s\n", found_debuggers + 1,
- serial,
- manufacturer,product);
- }
- info->vid = desc.idVendor;
- info->pid = desc.idProduct;
- info->bmp_type = type;
- strncpy(info->serial, serial, sizeof(info->serial));
- strncpy(info->product, product, sizeof(info->product));
- strncpy(info->manufacturer, manufacturer, sizeof(info->manufacturer));
- if (cl_opts->opt_position &&
- (cl_opts->opt_position == (found_debuggers + 1))) {
- found_debuggers = 1;
- break;
- } else {
- found_debuggers++;
- }
- }
- if ((found_debuggers == 0) && ftdi_unknown)
- DEBUG_WARN("Generic FTDI MPSSE VID/PID found. Please specify exact type with \"-c \" !\n");
- if ((found_debuggers == 1) && !cl_opts->opt_cable && (type == BMP_TYPE_LIBFTDI))
- cl_opts->opt_cable = active_cable;
- if (!found_debuggers && cl_opts->opt_list_only)
- DEBUG_WARN("No usable debugger found\n");
- if ((found_debuggers > 1) ||
- ((found_debuggers == 1) && (cl_opts->opt_list_only))) {
- if (!report) {
- if (found_debuggers > 1)
- DEBUG_WARN("%d debuggers found!\nSelect with -P , "
- "-s <(partial)serial no.> "
- "and/or -S <(partial)description>\n",
- found_debuggers);
- report = true;
- goto rescan;
- } else {
- if (found_debuggers > 0)
- access_problems = false;
- found_debuggers = 0;
- }
- }
- if (!found_debuggers && access_problems)
- DEBUG_WARN(
- "No debugger found. Please check access rights to USB devices!\n");
- libusb_free_device_list(devs, 1);
- return (found_debuggers == 1) ? 0 : -1;
-}
-
static BMP_CL_OPTIONS_t cl_opts;
void platform_init(int argc, char **argv)
{
- cl_opts.opt_idstring = "Blackmagic PC-Hosted";
cl_init(&cl_opts, argc, argv);
atexit(exit_function);
signal(SIGTERM, sigterm_handler);
signal(SIGINT, sigterm_handler);
- int res = libusb_init(&info.libusb_ctx);
- if (res) {
- DEBUG_WARN( "Fatal: Failed to get USB context: %s\n",
- libusb_strerror(res));
- exit(-1);
- }
if (cl_opts.opt_device) {
info.bmp_type = BMP_TYPE_BMP;
- } else if (cl_opts.opt_cable) {
- if ((!strcmp(cl_opts.opt_cable, "list")) ||
- (!strcmp(cl_opts.opt_cable, "l"))) {
- cable_desc_t *cable = &cable_desc[0];
- DEBUG_WARN("Available cables:\n");
- for (; cable->name; cable++) {
- DEBUG_WARN("\t%s\n", cable->name);
- }
- exit(0);
- }
- info.bmp_type = BMP_TYPE_LIBFTDI;
} else if (find_debuggers(&cl_opts, &info)) {
exit(-1);
}
- DEBUG_INFO("BMP hosted %s\n for ST-Link V2/3, CMSIS_DAP, JLINK and "
- "LIBFTDI/MPSSE\n", FIRMWARE_VERSION);
- DEBUG_INFO("Using %04x:%04x %s %s\n %s\n", info.vid, info.pid, info.serial,
- info.manufacturer,
- info.product);
+ bmp_ident(&info);
switch (info.bmp_type) {
case BMP_TYPE_BMP:
if (serial_open(&cl_opts, info.serial))
diff --git a/src/platforms/hosted/platform.h b/src/platforms/hosted/platform.h
index d5f1860c..129686fa 100644
--- a/src/platforms/hosted/platform.h
+++ b/src/platforms/hosted/platform.h
@@ -1,10 +1,6 @@
#ifndef __PLATFORM_H
#define __PLATFORM_H
-#include
-#include "libusb_utils.h"
-#include
-
#include "timing.h"
char *platform_ident(void);
@@ -27,19 +23,5 @@ typedef enum bmp_type_s {
BMP_TYPE_JLINK
} bmp_type_t;
-typedef struct bmp_info_s {
- bmp_type_t bmp_type;
- libusb_context *libusb_ctx;
- struct ftdi_context *ftdic;
- usb_link_t *usb_link;
- unsigned int vid;
- unsigned int pid;
- char dev;
- char serial[64];
- char manufacturer[128];
- char product[128];
-} bmp_info_t;
-
-extern bmp_info_t info;
-
+void gdb_ident(char *p, int count);
#endif
diff --git a/src/platforms/hosted/stlinkv2.c b/src/platforms/hosted/stlinkv2.c
index 1ca7c156..60213522 100644
--- a/src/platforms/hosted/stlinkv2.c
+++ b/src/platforms/hosted/stlinkv2.c
@@ -27,6 +27,7 @@
#include "general.h"
#include "gdb_if.h"
#include "adiv5.h"
+#include "bmp_hosted.h"
#include "stlinkv2.h"
#include "exception.h"
#include "jtag_devs.h"
diff --git a/src/platforms/hosted/stlinkv2.h b/src/platforms/hosted/stlinkv2.h
index d42ec143..6f639bc3 100644
--- a/src/platforms/hosted/stlinkv2.h
+++ b/src/platforms/hosted/stlinkv2.h
@@ -24,16 +24,30 @@
#define STLINK_DEBUG_PORT_ACCESS 0xffff
+#if HOSTED_BMP_ONLY == 1
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-parameter"
+int stlink_init(bmp_info_t *info) {return -1;};
+int stlink_hwversion(void) {return -1;};
+const char *stlink_target_voltage(bmp_info_t *info) {return "ERROR";};
+void stlink_srst_set_val(bmp_info_t *info, bool assert) {};
+bool stlink_srst_get_val(void) {return true;};
+int stlink_enter_debug_swd(bmp_info_t *info, ADIv5_DP_t *dp) {return -1;};
+void stlink_adiv5_dp_defaults(ADIv5_DP_t *dp) {};
+int stlink_jtag_dp_init(ADIv5_DP_t *dp) {return false;};
+int jtag_scan_stlinkv2(bmp_info_t *info, const uint8_t *irlens) {return 0;};
+void stlink_exit_function(bmp_info_t *info) {};
+# pragma GCC diagnostic pop
+#else
int stlink_init(bmp_info_t *info);
int stlink_hwversion(void);
const char *stlink_target_voltage(bmp_info_t *info);
void stlink_srst_set_val(bmp_info_t *info, bool assert);
bool stlink_srst_get_val(void);
int stlink_enter_debug_swd(bmp_info_t *info, ADIv5_DP_t *dp);
-
-const char *stlink_target_voltage(bmp_info_t *info);
void stlink_adiv5_dp_defaults(ADIv5_DP_t *dp);
int stlink_jtag_dp_init(ADIv5_DP_t *dp);
int jtag_scan_stlinkv2(bmp_info_t *info, const uint8_t *irlens);
void stlink_exit_function(bmp_info_t *info);
#endif
+#endif
diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c
index a17154f2..e27fe59e 100644
--- a/src/platforms/pc/cl_utils.c
+++ b/src/platforms/pc/cl_utils.c
@@ -33,6 +33,7 @@
#include "target_internal.h"
#include "cl_utils.h"
+#include "bmp_hosted.h"
#ifndef O_BINARY
#define O_BINARY 0
@@ -113,17 +114,20 @@ static void bmp_munmap(struct mmap_data *map)
#endif
}
-static void cl_help(char **argv, BMP_CL_OPTIONS_t *opt)
+static void cl_help(char **argv)
{
- DEBUG_WARN("%s for: \n", opt->opt_idstring);
- DEBUG_WARN("\tBMP hosted %s\n\t\tfor ST-Link V2/3, CMSIS_DAP, JLINK and "
- "LIBFTDI/MPSSE\n\n", FIRMWARE_VERSION);
+ bmp_ident(NULL);
DEBUG_WARN("Usage: %s [options]\n", argv[0]);
DEBUG_WARN("\t-h\t\t: This help.\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("Probe selection arguments:\n");
- DEBUG_WARN("\t-d \"path\"\t: Use serial BMP device at \"path\"(Deprecated)\n");
+ DEBUG_WARN("\t-d \"path\"\t: Use serial BMP device at ");
+#if HOSTED_BMP_ONLY == 1 && defined(__APPLE__)
+ DEBUG_WARN("\n");
+#else
+ DEBUG_WARN(". Deprecated!\n");
+#endif
DEBUG_WARN("\t-P \t: Use debugger found at position \n");
DEBUG_WARN("\t-n \t: Use target device found at position \n");
DEBUG_WARN("\t-s \"serial\"\t: Use dongle with (partial) "
@@ -166,7 +170,8 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
opt->opt_cable = optarg;
break;
case 'h':
- cl_help(argv, opt);
+ cl_debuglevel = 3;
+ cl_help(argv);
break;
case 'H':
opt->opt_no_hl = true;
@@ -189,7 +194,6 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
opt->external_resistor_swd = true;
break;
case 'd':
- DEBUG_WARN("Deprecated!\n");
if (optarg)
opt->opt_device = optarg;
break;
diff --git a/src/platforms/pc/cl_utils.h b/src/platforms/pc/cl_utils.h
index 15606725..e7349c71 100644
--- a/src/platforms/pc/cl_utils.h
+++ b/src/platforms/pc/cl_utils.h
@@ -54,7 +54,6 @@ typedef struct BMP_CL_OPTIONS_s {
int opt_target_dev;
uint32_t opt_flash_start;
size_t opt_flash_size;
- char *opt_idstring;
}BMP_CL_OPTIONS_t;
void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv);
diff --git a/src/platforms/pc/libusb_utils.c b/src/platforms/pc/libusb_utils.c
deleted file mode 100644
index d7f31599..00000000
--- a/src/platforms/pc/libusb_utils.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * This file is part of the Black Magic Debug project.
- *
- * Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-#include "general.h"
-#include "cl_utils.h"
-
-static void LIBUSB_CALL on_trans_done(struct libusb_transfer *trans)
-{
- struct trans_ctx * const ctx = trans->user_data;
-
- if (trans->status != LIBUSB_TRANSFER_COMPLETED)
- {
- DEBUG_WARN("on_trans_done: ");
- if(trans->status == LIBUSB_TRANSFER_TIMED_OUT) {
- DEBUG_WARN(" Timeout\n");
- } else if (trans->status == LIBUSB_TRANSFER_CANCELLED) {
- DEBUG_WARN(" cancelled\n");
- } else if (trans->status == LIBUSB_TRANSFER_NO_DEVICE) {
- DEBUG_WARN(" no device\n");
- } else {
- DEBUG_WARN(" unknown\n");
- }
- ctx->flags |= TRANS_FLAGS_HAS_ERROR;
- }
- ctx->flags |= TRANS_FLAGS_IS_DONE;
-}
-
-static int submit_wait(usb_link_t *link, struct libusb_transfer *trans) {
- struct trans_ctx trans_ctx;
- enum libusb_error error;
-
- trans_ctx.flags = 0;
-
- /* brief intrusion inside the libusb interface */
- trans->callback = on_trans_done;
- trans->user_data = &trans_ctx;
-
- if ((error = libusb_submit_transfer(trans))) {
- DEBUG_WARN("libusb_submit_transfer(%d): %s\n", error,
- libusb_strerror(error));
- exit(-1);
- }
-
- uint32_t start_time = platform_time_ms();
- while (trans_ctx.flags == 0) {
- struct timeval timeout;
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
- if (libusb_handle_events_timeout(link->ul_libusb_ctx, &timeout)) {
- DEBUG_WARN("libusb_handle_events()\n");
- return -1;
- }
- uint32_t now = platform_time_ms();
- if (now - start_time > 1000) {
- libusb_cancel_transfer(trans);
- DEBUG_WARN("libusb_handle_events() timeout\n");
- return -1;
- }
- }
- if (trans_ctx.flags & TRANS_FLAGS_HAS_ERROR) {
- DEBUG_WARN("libusb_handle_events() | has_error\n");
- return -1;
- }
-
- return 0;
-}
-
-/* One USB transaction */
-int send_recv(usb_link_t *link,
- uint8_t *txbuf, size_t txsize,
- uint8_t *rxbuf, size_t rxsize)
-{
- int res = 0;
- if( txsize) {
- int txlen = txsize;
- libusb_fill_bulk_transfer(link->req_trans,
- link->ul_libusb_device_handle,
- link->ep_tx | LIBUSB_ENDPOINT_OUT,
- txbuf, txlen,
- NULL, NULL, 0);
- int i = 0;
- DEBUG_WIRE(" Send (%3d): ", txlen);
- for (; i < txlen; i++) {
- DEBUG_WIRE("%02x", txbuf[i]);
- if ((i & 7) == 7)
- DEBUG_WIRE(".");
- if ((i & 31) == 31)
- DEBUG_WIRE("\n ");
- }
- if (!(i & 31))
- DEBUG_WIRE("\n");
- if (submit_wait(link, link->req_trans)) {
- libusb_clear_halt(link->ul_libusb_device_handle, link->ep_tx);
- return -1;
- }
- }
- /* send_only */
- if (rxsize != 0) {
- /* read the response */
- libusb_fill_bulk_transfer(link->rep_trans, link->ul_libusb_device_handle,
- link->ep_rx | LIBUSB_ENDPOINT_IN,
- rxbuf, rxsize, NULL, NULL, 0);
-
- if (submit_wait(link, link->rep_trans)) {
- DEBUG_WARN("clear 1\n");
- libusb_clear_halt(link->ul_libusb_device_handle, link->ep_rx);
- return -1;
- }
- res = link->rep_trans->actual_length;
- if (res >0) {
- int i;
- uint8_t *p = rxbuf;
- DEBUG_WIRE(" Rec (%zu/%d)", rxsize, res);
- for (i = 0; i < res && i < 32 ; i++) {
- if ( i && ((i & 7) == 0))
- DEBUG_WIRE(".");
- DEBUG_WIRE("%02x", p[i]);
- }
- }
- }
- DEBUG_WIRE("\n");
- return res;
-}
diff --git a/src/platforms/pc/libusb_utils.h b/src/platforms/pc/libusb_utils.h
deleted file mode 100644
index 8f6d868c..00000000
--- a/src/platforms/pc/libusb_utils.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This file is part of the Black Magic Debug project.
- *
- * Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-#if !defined(__LIBUSB_UTILS_H)
-#define __LIBUSB_UTILS_H
-#include
-
-struct trans_ctx {
-#define TRANS_FLAGS_IS_DONE (1 << 0)
-#define TRANS_FLAGS_HAS_ERROR (1 << 1)
- volatile unsigned long flags;
-};
-
-typedef struct {
- libusb_context *ul_libusb_ctx;
- libusb_device_handle *ul_libusb_device_handle;
- unsigned char ep_tx;
- unsigned char ep_rx;
- struct libusb_transfer* req_trans;
- struct libusb_transfer* rep_trans;
- void *priv;
-} usb_link_t;
-
-int send_recv(usb_link_t *link, uint8_t *txbuf, size_t txsize,
- uint8_t *rxbuf, size_t rxsize);
-#endif
diff --git a/src/platforms/pc/serial_win.c b/src/platforms/pc/serial_win.c
index 86ac3643..57f78067 100644
--- a/src/platforms/pc/serial_win.c
+++ b/src/platforms/pc/serial_win.c
@@ -67,7 +67,6 @@ static char *find_bmp_by_serial(const char *serial)
int serial_open(BMP_CL_OPTIONS_t *cl_opts, char * serial)
{
- (void) serial; /* FIXME: Does Windows allow open with USB serial no? */
char device[256];
if (!cl_opts->opt_device)
cl_opts->opt_device = find_bmp_by_serial(serial);