Add pc_stlinkv2 platform, running on host, talking to original StlinkV2/3.
Stlink firmware needs to be recent.
This commit is contained in:
parent
fd3af639b0
commit
9ed26645d3
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue