Add pc_stlinkv2 platform, running on host, talking to original StlinkV2/3.

Stlink firmware needs to be recent.
This commit is contained in:
Uwe Bonnes 2019-04-13 19:32:55 +02:00
parent fd3af639b0
commit 9ed26645d3
10 changed files with 1604 additions and 3 deletions

View File

@ -1,5 +1,5 @@
SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DLIBFTDI
CFLAGS += -DLIBFTDI -DENABLE_DEBUG
LDFLAGS += -lftdi1
ifneq (, $(findstring mingw, $(SYS)))
LDFLAGS += -lusb-1.0 -lws2_32

View File

@ -0,0 +1,15 @@
TARGET=blackmagic_stlinkv2
SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DLIBFTDI -DSTLINKV2 -DJTAG_HL -DENABLE_DEBUG
CFLAGS +=-I ./target
LDFLAGS += -lusb-1.0
ifneq (, $(findstring mingw, $(SYS)))
LDFLAGS += -lws2_32
CFLAGS += -Wno-cast-function-type
else ifneq (, $(findstring cygwin, $(SYS)))
LDFLAGS += -lws2_32
endif
VPATH += platforms/pc
SRC += timing.c stlinkv2.c
SWD_HL = 1
JTAG_HL = 1

View File

@ -0,0 +1,16 @@
Stlink V2/3 with original STM firmware as Blackmagic Debug Probes
Recent STM Stlink firmware revision (V3 and V2 >= J32) expose nearly all
functionality that BMP needs. This branch implements blackmagic debug probe
for the STM Stlink as a proof of concept.
Use at your own risk, but report or better fix problems.
Run the resulting blackmagic_stlinkv2 executabel to start the gdb server
CrosscCompling for windows with mingw succeeds.
Drawback: JTAG does not work for chains with multiple devices.
This branch may get forced push. In case of problems:
- git reset --hard master
- git rebase

View File

@ -0,0 +1,73 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
*/
/* This file implements a subset of JTAG-DP specific functions of the
* ARM Debug Interface v5 Architecure Specification, ARM doc IHI0031A
* used in BMP.
*/
#include "general.h"
#include "target.h"
#include "adiv5.h"
#include "stlinkv2.h"
#include "jtag_devs.h"
struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1];
int jtag_dev_count;
int jtag_scan(const uint8_t *irlens)
{
uint32_t idcodes[JTAG_MAX_DEVS+1];
(void) *irlens;
target_list_free();
jtag_dev_count = 0;
memset(&jtag_devs, 0, sizeof(jtag_devs));
if (stlink_enter_debug_jtag())
return 0;
jtag_dev_count = stlink_read_idcodes(idcodes);
/* Check for known devices and handle accordingly */
for(int i = 0; i < jtag_dev_count; i++)
jtag_devs[i].idcode = idcodes[i];
for(int i = 0; i < jtag_dev_count; i++)
for(int j = 0; dev_descr[j].idcode; j++)
if((jtag_devs[i].idcode & dev_descr[j].idmask) ==
dev_descr[j].idcode) {
if(dev_descr[j].handler)
dev_descr[j].handler(&jtag_devs[i]);
break;
}
return jtag_dev_count;
}
void adiv5_jtag_dp_handler(jtag_dev_t *dev)
{
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
dp->dev = dev;
dp->idcode = dev->idcode;
dp->dp_read = stlink_dp_read;
dp->error = stlink_dp_error;
dp->low_access = stlink_dp_low_access;
dp->abort = stlink_dp_abort;
adiv5_dp_init(dp);
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
*/
/* This file implements the SW-DP specific functions of the
* ARM Debug Interface v5 Architecure Specification, ARM doc IHI0031A.
*/
#include "general.h"
#include "target.h"
#include "target_internal.h"
#include "adiv5.h"
#include "stlinkv2.h"
int adiv5_swdp_scan(void)
{
target_list_free();
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (stlink_enter_debug_swd())
return 0;
dp->idcode = stlink_read_coreid();
dp->dp_read = stlink_dp_read;
dp->error = stlink_dp_error;
dp->low_access = stlink_dp_low_access;
dp->abort = stlink_dp_abort;
stlink_dp_error(dp);
adiv5_dp_init(dp);
return target_list?1:0;
return 0;
}

View File

@ -0,0 +1,97 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2019 2019 Uwe Bonnes
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "general.h"
#include "gdb_if.h"
#include "version.h"
#include "platform.h"
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include "adiv5.h"
#include "stlinkv2.h"
int platform_hwversion(void)
{
return stlink_hwversion();
}
const char *platform_target_voltage(void)
{
return stlink_target_voltage();
}
void platform_init(int argc, char **argv)
{
stlink_init(argc, argv);
}
static bool srst_status = false;
void platform_srst_set_val(bool assert)
{
stlink_srst_set_val(assert);
srst_status = assert;
}
bool platform_srst_get_val(void) { return srst_status; }
void platform_buffer_flush(void)
{
}
int platform_buffer_write(const uint8_t *data, int size)
{
(void) data;
(void) size;
return size;
}
int platform_buffer_read(uint8_t *data, int size)
{
(void) data;
return size;
}
#if defined(_WIN32) && !defined(__MINGW32__)
#warning "This vasprintf() is dubious!"
int vasprintf(char **strp, const char *fmt, va_list ap)
{
int size = 128, ret = 0;
*strp = malloc(size);
while(*strp && ((ret = vsnprintf(*strp, size, fmt, ap)) == size))
*strp = realloc(*strp, size <<= 1);
return ret;
}
#endif
void platform_delay(uint32_t ms)
{
usleep(ms * 1000);
}
uint32_t platform_time_ms(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
}

View File

@ -0,0 +1,46 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __PLATFORM_H
#define __PLATFORM_H
#include <libusb-1.0/libusb.h>
#include "timing.h"
#ifndef _WIN32
# include <alloca.h>
#else
# ifndef alloca
# define alloca __builtin_alloca
# endif
#endif
#define PLATFORM_HAS_DEBUG
#define SET_RUN_STATE(state)
#define SET_IDLE_STATE(state)
//#define SET_ERROR_STATE(state)
void platform_buffer_flush(void);
int platform_buffer_write(const uint8_t *data, int size);
int platform_buffer_read(uint8_t *data, int size);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2019 Uwe Bonnes
*
* 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 <http://www.gnu.org/licenses/>.
*/
#if !defined(__STLINKV2_H_)
#define STLINK_ERROR_FAIL -1
#define STLINK_ERROR_OK 0
#define STLINK_ERROR_WAIT 1
#define STLINK_DEBUG_PORT_ACCESS 0xffff
void stlink_init(int argc, char **argv);
int stlink_hwversion(void);
void stlink_leave_state(void);
const char *stlink_target_voltage(void);
void stlink_srst_set_val(bool assert);
int stlink_enter_debug_swd(void);
int stlink_enter_debug_jtag(void);
int stlink_read_idcodes(uint32_t *);
uint32_t stlink_read_coreid(void);
int stlink_read_dp_register(uint16_t port, uint16_t addr, uint32_t *res);
int stlink_write_dp_register(uint16_t port, uint16_t addr, uint32_t val);
uint32_t stlink_dp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value);
uint32_t stlink_dp_read(ADIv5_DP_t *dp, uint16_t addr);
uint32_t stlink_dp_error(ADIv5_DP_t *dp);
void stlink_dp_abort(ADIv5_DP_t *dp, uint32_t abort);
int stlink_open_ap(uint8_t ap);
void stlink_close_ap(uint8_t ap);
int stlink_usb_get_rw_status(void);
void stlink_regs_read(void *data);
uint32_t stlink_reg_read(int idx);
void stlink_reg_write(int num, uint32_t val);
extern int debug_level;
# define DEBUG_STLINK if (debug_level > 0) printf
# define DEBUG_USB if (debug_level > 1) printf
#endif

View File

@ -433,8 +433,17 @@ enum { DB_DHCSR, DB_DCRSR, DB_DCRDR, DB_DEMCR };
static void cortexm_regs_read(target *t, void *data)
{
ADIv5_AP_t *ap = cortexm_ap(t);
uint32_t *regs = data;
#if defined(STLINKV2)
extern void stlink_regs_read(void *data);
extern uint32_t stlink_reg_read(int idx);
stlink_regs_read(data);
regs += sizeof(regnum_cortex_m);
if (t->target_options & TOPT_FLAVOUR_V7MF)
for(size_t t = 0; t < sizeof(regnum_cortex_mf) / 4; t++)
*regs++ = stlink_reg_read(regnum_cortex_mf[t]);
#else
ADIv5_AP_t *ap = cortexm_ap(t);
unsigned i;
/* FIXME: Describe what's really going on here */
@ -460,12 +469,25 @@ static void cortexm_regs_read(target *t, void *data)
regnum_cortex_mf[i]);
*regs++ = adiv5_dp_read(ap->dp, ADIV5_AP_DB(DB_DCRDR));
}
#endif
}
static void cortexm_regs_write(target *t, const void *data)
{
ADIv5_AP_t *ap = cortexm_ap(t);
const uint32_t *regs = data;
#if defined(STLINKV2)
extern void stlink_reg_write(int num, uint32_t val);
for(size_t z = 1; z < sizeof(regnum_cortex_m) / 4; z++) {
stlink_reg_write(regnum_cortex_m[z], *regs);
regs++;
if (t->target_options & TOPT_FLAVOUR_V7MF)
for(size_t z = 0; z < sizeof(regnum_cortex_mf) / 4; z++) {
stlink_reg_write(regnum_cortex_mf[z], *regs);
regs++;
}
}
#else
ADIv5_AP_t *ap = cortexm_ap(t);
unsigned i;
/* FIXME: Describe what's really going on here */
@ -494,6 +516,7 @@ static void cortexm_regs_write(target *t, const void *data)
ADIV5_AP_DB(DB_DCRSR),
0x10000 | regnum_cortex_mf[i]);
}
#endif
}
int cortexm_mem_write_sized(