hosted: Add bmp_remote, remove old pc-hosted platform.

This commit is contained in:
Uwe Bonnes 2020-04-19 18:22:06 +02:00
parent 13c3c934d2
commit ab7991c3a6
13 changed files with 516 additions and 596 deletions

View File

@ -3,11 +3,16 @@ CFLAGS += -DENABLE_DEBUG -DPLATFORM_HAS_DEBUG
CFLAGS +=-I ./target -I./platforms/pc
LDFLAGS += -lusb-1.0
ifneq (, $(findstring mingw, $(SYS)))
SRC += serial_win.c
LDFLAGS += -lws2_32
else ifneq (, $(findstring cygwin, $(SYS)))
SRC += serial_win.c
LDFLAGS += -lws2_32
else
SRC += serial_unix.c
endif
VPATH += platforms/pc
SRC += timing.c cl_utils.c utils.c libusb_utils.c
SRC += stlinkv2.c
SRC += bmp_remote.c remote_swdptap.c remote_jtagtap.c
PC_HOSTED = 1

View File

@ -0,0 +1,147 @@
/*
* 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>
* Additions by Dave Marples <dave@marples.net>
* Additions by 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/>.
*/
#include "general.h"
#include "gdb_if.h"
#include "version.h"
#include "platform.h"
#include "remote.h"
#include "target.h"
#include "bmp_remote.h"
#include <assert.h>
#include <sys/time.h>
#include <sys/time.h>
#include <errno.h>
#include <string.h>
#include "adiv5.h"
int remote_init(void)
{
char construct[REMOTE_MAX_MSG_SIZE];
int c = snprintf(construct, REMOTE_MAX_MSG_SIZE, "%s", REMOTE_START_STR);
platform_buffer_write((uint8_t *)construct, c);
c = platform_buffer_read((uint8_t *)construct, REMOTE_MAX_MSG_SIZE);
if ((!c) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr,"Remote Start failed, error %s\n",
c ? (char *)&(construct[1]) : "unknown");
return -1;
}
printf("Remote is %s\n", &construct[1]);
return 0;
}
bool remote_target_get_power(void)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, "%s",
REMOTE_PWR_GET_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr," platform_target_get_power failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit (-1);
}
return (construct[1] == '1');
}
void remote_target_set_power(bool power)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_PWR_SET_STR,
power ? '1' : '0');
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "platform_target_set_power failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
}
void remote_srst_set_val(bool assert)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_SRST_SET_STR,
assert ? '1' : '0');
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "platform_srst_set_val failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
}
bool remote_srst_get_val(void)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,"%s",
REMOTE_SRST_GET_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "platform_srst_set_val failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
return (construct[1] == '1');
}
const char *remote_target_voltage(void)
{
static uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE," %s",
REMOTE_VOLTAGE_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "platform_target_voltage failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(- 1);
}
return (char *)&construct[1];
}

View File

@ -0,0 +1,39 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2020 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(__BMP_REMOTE_H_)
#define __BMP_REMOTE_H_
#include "swdptap.h"
#include "jtagtap.h"
#define REMOTE_MAX_MSG_SIZE (256)
int platform_buffer_write(const uint8_t *data, int size);
int platform_buffer_read(uint8_t *data, int size);
int remote_init(void);
int remote_swdptap_init(swd_proc_t *swd_proc);
int remote_jtagtap_init(jtag_proc_t *jtag_proc);
bool remote_target_get_power(void);
const char *remote_target_voltage(void);
void remote_target_set_power(bool power);
void remote_srst_set_val(bool assert);
bool remote_srst_get_val(void);
const char *platform_target_voltage(void);
#define __BMP_REMOTE_H_
#endif

View File

@ -31,6 +31,8 @@
#include "cl_utils.h"
#include "gdb_if.h"
#include <signal.h>
#include "bmp_remote.h"
#include "stlinkv2.h"
#define VENDOR_ID_BMP 0x1d50
@ -220,6 +222,11 @@ void platform_init(int argc, char **argv)
info.manufacturer,
info.product);
switch (info.bmp_type) {
case BMP_TYPE_BMP:
if (serial_open(&cl_opts, info.serial))
exit(-1);
remote_init();
break;
case BMP_TYPE_STLINKV2:
if (stlink_init( &info))
exit(-1);
@ -240,6 +247,7 @@ void platform_init(int argc, char **argv)
int platform_adiv5_swdp_scan(void)
{
switch (info.bmp_type) {
case BMP_TYPE_BMP:
case BMP_TYPE_STLINKV2:
{
target_list_free();
@ -261,6 +269,8 @@ int platform_adiv5_swdp_scan(void)
int platform_swdptap_init(void)
{
switch (info.bmp_type) {
case BMP_TYPE_BMP:
return remote_swdptap_init(&swd_proc);
case BMP_TYPE_STLINKV2:
return 0;
break;
@ -273,6 +283,7 @@ int platform_swdptap_init(void)
int platform_jtag_scan(const uint8_t *lrlens)
{
switch (info.bmp_type) {
case BMP_TYPE_BMP:
case BMP_TYPE_STLINKV2:
return jtag_scan_stlinkv2(&info, lrlens);
default:
@ -284,6 +295,8 @@ int platform_jtag_scan(const uint8_t *lrlens)
int platform_jtagtap_init(void)
{
switch (info.bmp_type) {
case BMP_TYPE_BMP:
return remote_jtagtap_init(&jtag_proc);
case BMP_TYPE_STLINKV2:
return 0;
default:
@ -305,10 +318,11 @@ void platform_adiv5_dp_defaults(ADIv5_DP_t *dp)
int platform_jtag_dp_init(ADIv5_DP_t *dp)
{
switch (info.bmp_type) {
case BMP_TYPE_BMP:
case BMP_TYPE_STLINKV2:
return stlink_jtag_dp_init(dp);
default:
return -1;
return 0;
}
return 0;
}
@ -322,7 +336,7 @@ char *platform_ident(void)
return "BMP";
case BMP_TYPE_STLINKV2:
return "STLINKV2";
case BMP_TYPE_LIBFTDI:
case BMP_TYPE_LIBFTDI:
return "LIBFTDI";
case BMP_TYPE_CMSIS_DAP:
return "CMSIS_DAP";
@ -335,10 +349,12 @@ char *platform_ident(void)
const char *platform_target_voltage(void)
{
switch (info.bmp_type) {
case BMP_TYPE_BMP:
return remote_target_voltage();
case BMP_TYPE_STLINKV2:
return stlink_target_voltage(&info);
default:
break;;
break;
}
return NULL;
}
@ -348,6 +364,8 @@ void platform_srst_set_val(bool assert)
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
return stlink_srst_set_val(&info, assert);
case BMP_TYPE_BMP:
return remote_srst_set_val(assert);
default:
break;
}
@ -356,6 +374,8 @@ void platform_srst_set_val(bool assert)
bool platform_srst_get_val(void)
{
switch (info.bmp_type) {
case BMP_TYPE_BMP:
return remote_srst_get_val();
case BMP_TYPE_STLINKV2:
return stlink_srst_get_val();
default:
@ -364,4 +384,10 @@ bool platform_srst_get_val(void)
return false;
}
void platform_buffer_flush(void) {}
void platform_buffer_flush(void)
{
switch (info.bmp_type) {
default:
break;
}
}

View File

@ -1,7 +1,9 @@
#ifndef __PLATFORM_H
#define __PLATFORM_H
#include <libusb-1.0/libusb.h>
#include "libusb_utils.h"
#include <libftdi1/ftdi.h>
#include "timing.h"

View File

@ -0,0 +1,165 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2008 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Modified by Dave Marples <dave@marples.net>
*
* 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/>.
*/
/* Low level JTAG implementation using FT2232 with libftdi.
*
* Issues:
* Should share interface with swdptap.c or at least clean up...
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include "general.h"
#include "remote.h"
#include "jtagtap.h"
#include "bmp_remote.h"
static void jtagtap_reset(void);
static void jtagtap_tms_seq(uint32_t MS, int ticks);
static void jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks);
static void jtagtap_tdi_seq(
const uint8_t final_tms, const uint8_t *DI, int ticks);
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI);
int remote_jtagtap_init(jtag_proc_t *jtag_proc)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, "%s",
REMOTE_JTAG_INIT_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "jtagtap_init failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
jtag_proc->jtagtap_reset = jtagtap_reset;
jtag_proc->jtagtap_next =jtagtap_next;
jtag_proc->jtagtap_tms_seq = jtagtap_tms_seq;
jtag_proc->jtagtap_tdi_tdo_seq = jtagtap_tdi_tdo_seq;
jtag_proc->jtagtap_tdi_seq = jtagtap_tdi_seq;
return 0;
}
/* See remote.c/.h for protocol information */
static void jtagtap_reset(void)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, "%s",
REMOTE_JTAG_RESET_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "jtagtap_reset failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
}
static void jtagtap_tms_seq(uint32_t MS, int ticks)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,
REMOTE_JTAG_TMS_STR, ticks, MS);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "jtagtap_tms_seq failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
}
static void jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
uint64_t DIl=*(uint64_t *)DI;
if(!ticks || !DI) return;
/* Reduce the length of DI according to the bits we're transmitting */
DIl &= (1LL << (ticks + 1))-1;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,
REMOTE_JTAG_TDIDO_STR,
final_tms ? REMOTE_TDITDO_TMS : REMOTE_TDITDO_NOTMS,
ticks, DIl);
platform_buffer_write(construct,s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "jtagtap_tms_seq failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
if (DO) {
uint64_t DOl = remotehston(-1, (char *)&construct[1]);
*(uint64_t *)DO = DOl;
}
}
static void jtagtap_tdi_seq(
const uint8_t final_tms, const uint8_t *DI, int ticks)
{
return jtagtap_tdi_tdo_seq(NULL, final_tms, DI, ticks);
}
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_JTAG_NEXT,
dTMS ? '1' : '0', dTDI ? '1' : '0');
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "jtagtap_next failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
return remotehston(-1, (char *)&construct[1]);
}

View File

@ -0,0 +1,128 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2018 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Modified by Dave Marples <dave@marples.net>
*
* 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/>.
*/
/* MPSSE bit-banging SW-DP interface over FTDI with loop unrolled.
* Speed is sensible.
*/
#include <stdio.h>
#include <assert.h>
#include "general.h"
#include "remote.h"
#include "bmp_remote.h"
static bool swdptap_seq_in_parity(uint32_t *res, int ticks);
static uint32_t swdptap_seq_in(int ticks);
static void swdptap_seq_out(uint32_t MS, int ticks);
static void swdptap_seq_out_parity(uint32_t MS, int ticks);
int remote_swdptap_init(swd_proc_t *swd_proc)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = sprintf((char *)construct,"%s", REMOTE_SWDP_INIT_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "swdptap_init failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
swd_proc->swdptap_seq_in = swdptap_seq_in;
swd_proc->swdptap_seq_in_parity = swdptap_seq_in_parity;
swd_proc->swdptap_seq_out = swdptap_seq_out;
swd_proc->swdptap_seq_out_parity = swdptap_seq_out_parity;
return 0;
}
static bool swdptap_seq_in_parity(uint32_t *res, int ticks)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = sprintf((char *)construct, REMOTE_SWDP_IN_PAR_STR, ticks);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s<2) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "swdptap_seq_in_parity failed, error %s\n",
s ? (char *)&(construct[1]) : "short response");
exit(-1);
}
*res=remotehston(-1, (char *)&construct[1]);
return (construct[0] != REMOTE_RESP_OK);
}
static uint32_t swdptap_seq_in(int ticks)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = sprintf((char *)construct, REMOTE_SWDP_IN_STR, ticks);
platform_buffer_write(construct,s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s<2) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "swdptap_seq_in failed, error %s\n",
s ? (char *)&(construct[1]) : "short response");
exit(-1);
}
return remotehston(-1,(char *)&construct[1]);
}
static void swdptap_seq_out(uint32_t MS, int ticks)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = sprintf((char *)construct,REMOTE_SWDP_OUT_STR, ticks, MS);
platform_buffer_write(construct, s);
s=platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
fprintf(stderr, "swdptap_seq_out failed, error %s\n",
s ? (char *)&(construct[1]) : "short response");
exit(-1);
}
}
static void swdptap_seq_out_parity(uint32_t MS, int ticks)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = sprintf((char *)construct, REMOTE_SWDP_OUT_PAR_STR, ticks, MS);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[1] == REMOTE_RESP_ERR)){
fprintf(stderr, "swdptap_seq_out_parity failed, error %s\n",
s ? (char *)&(construct[2]) : "short response");
exit(-1);
}
}

View File

@ -1,16 +0,0 @@
TARGET=blackmagic_hosted
SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DENABLE_DEBUG
CFLAGS +=-I ./target -I./platforms/pc
ifneq (, $(findstring mingw, $(SYS)))
SRC += serial_win.c
LDFLAGS += -lws2_32
else ifneq (, $(findstring cygwin, $(SYS)))
SRC += serial_win.c
LDFLAGS += -lws2_32
else
SRC += serial_unix.c
endif
VPATH += platforms/pc
SRC += cl_utils.c timing.c utils.c
PC_HOSTED = 1

View File

@ -1,40 +0,0 @@
PC Hosted variant
THIS IS INCOMPLETE - ONLY SUPPORTS SWD AT THE MOMENT
This variant will use any BMP probe with recent firmware as a remote
actuator, with the actual probe code running on the PC. The BMP itself
is 'dumb' and doesn't do anything (although any secondary serial port
remains available).
To use it, compile for the pc-hosted target and then connect to your normal
BMP GDB port;
src/blackmagic -s /dev/ttyACM0
...you can then connect your gdb session to localhost:2000 for all your
debugging goodness;
$arm-eabi-none-gdb
(gdb) monitor swdp_scan
Target voltage: not supported
Available Targets:
No. Att Driver
1 STM32F1 medium density M3/M4
(gdb) attach 1
Attaching to program: Builds/blackmagic/src/blackmagic, Remote target
0x08001978 in ?? ()
(gdb) file src/blackmagic
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Load new symbol table from "src/blackmagic"? (y or n) y
Reading symbols from src/blackmagic...
(gdb) load
Loading section .text, size 0x1201c lma 0x8002000
Loading section .data, size 0xd8 lma 0x801401c
Start address 0x800d9fc, load size 73972
Transfer rate: 2 KB/sec, 960 bytes/write.
(gdb)
...note that the speed of the probe in this way is about 10 times less than
running native. This build is intended for debug and development only.

View File

@ -1,161 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2008 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Modified by Dave Marples <dave@marples.net>
*
* 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/>.
*/
/* Low level JTAG implementation using FT2232 with libftdi.
*
* Issues:
* Should share interface with swdptap.c or at least clean up...
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include "general.h"
#include "remote.h"
#include "jtagtap.h"
jtag_proc_t jtag_proc;
static void jtagtap_reset(void);
static void jtagtap_tms_seq(uint32_t MS, int ticks);
static void jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks);
static void jtagtap_tdi_seq(
const uint8_t final_tms, const uint8_t *DI, int ticks);
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI);
int platform_jtagtap_init(void)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_JTAG_INIT_STR);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"jtagtap_init failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
jtag_proc.jtagtap_reset = jtagtap_reset;
jtag_proc.jtagtap_next =jtagtap_next;
jtag_proc.jtagtap_tms_seq = jtagtap_tms_seq;
jtag_proc.jtagtap_tdi_tdo_seq = jtagtap_tdi_tdo_seq;
jtag_proc.jtagtap_tdi_seq = jtagtap_tdi_seq;
return 0;
}
/* See remote.c/.h for protocol information */
static void jtagtap_reset(void)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_JTAG_RESET_STR);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"jtagtap_reset failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
}
static void jtagtap_tms_seq(uint32_t MS, int ticks)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,REMOTE_JTAG_TMS_STR,ticks,MS);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"jtagtap_tms_seq failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
}
static void jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
uint64_t DIl=*(uint64_t *)DI;
if(!ticks || !DI) return;
/* Reduce the length of DI according to the bits we're transmitting */
DIl &= (1LL << (ticks + 1)) - 1;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,REMOTE_JTAG_TDIDO_STR,final_tms?REMOTE_TDITDO_TMS:REMOTE_TDITDO_NOTMS,ticks,DIl);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"jtagtap_tms_seq failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
if (DO) {
uint64_t DOl = remotehston(-1, (char *)&construct[1]);
*(uint64_t *)DO = DOl;
}
}
static void jtagtap_tdi_seq(
const uint8_t final_tms, const uint8_t *DI, int ticks)
{
return jtagtap_tdi_tdo_seq(NULL, final_tms, DI, ticks);
}
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,REMOTE_JTAG_NEXT,dTMS?'1':'0',dTDI?'1':'0');
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"jtagtap_next failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
return remotehston(-1,(char *)&construct[1]);
}

View File

@ -1,188 +0,0 @@
/*
* 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>
* Additions by Dave Marples <dave@marples.net>
*
* 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 "remote.h"
#include "target.h"
#include <assert.h>
#include <sys/time.h>
#include <sys/time.h>
#include <errno.h>
#include <string.h>
#include "cl_utils.h"
static BMP_CL_OPTIONS_t cl_opts; /* Portable way to nullify the struct*/
int platform_adiv5_swdp_scan(void)
{
return adiv5_swdp_scan();
}
int platform_jtag_scan(const uint8_t *lrlens)
{
return jtag_scan(lrlens);
}
int platform_jtag_dp_init()
{
return 0;
}
void platform_init(int argc, char **argv)
{
cl_opts.opt_idstring = "Blackmagic Debug Probe Remote";
cl_init(&cl_opts, argc, argv);
char construct[PLATFORM_MAX_MSG_SIZE];
printf("\nBlack Magic Probe (" FIRMWARE_VERSION ")\n");
printf("Copyright (C) 2019 Black Sphere Technologies Ltd.\n");
printf("License GPLv3+: GNU GPL version 3 or later "
"<http://gnu.org/licenses/gpl.html>\n\n");
if (serial_open(cl_opts.opt_device, cl_opts.opt_serial))
exit(-1);
int c=snprintf(construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_START_STR);
platform_buffer_write((uint8_t *)construct,c);
c=platform_buffer_read((uint8_t *)construct, PLATFORM_MAX_MSG_SIZE);
if ((!c) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"Remote Start failed, error %s\n",c?(char *)&(construct[1]):"unknown");
exit(-1);
}
printf("Remote is %s\n",&construct[1]);
if (cl_opts.opt_mode != BMP_MODE_DEBUG) {
int ret = cl_execute(&cl_opts);
if (cl_opts.opt_tpwr)
platform_target_set_power(0);
serial_close();
exit(ret);
} else {
assert(gdb_if_init() == 0);
}
}
bool platform_target_get_power(void)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_PWR_GET_STR);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"platform_target_get_power failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
return (construct[1]=='1');
}
void platform_target_set_power(bool power)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,REMOTE_PWR_SET_STR,power?'1':'0');
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"platform_target_set_power failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
}
void platform_srst_set_val(bool assert)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,REMOTE_SRST_SET_STR,assert?'1':'0');
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"platform_srst_set_val failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
}
bool platform_srst_get_val(void)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_SRST_GET_STR);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"platform_srst_set_val failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
return (construct[1]=='1');
}
void platform_buffer_flush(void)
{
}
const char *platform_target_voltage(void)
{
static uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_VOLTAGE_STR);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"platform_target_voltage failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
return (char *)&construct[1];
}
void platform_adiv5_dp_defaults(void *arg)
{
(void) arg;
}

View File

@ -1,54 +0,0 @@
/*
* 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>
* Additions by Dave Marples <dave@marples.net>
*
* 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 "timing.h"
#ifndef _WIN32
# include <alloca.h>
#else
# ifndef alloca
# define alloca __builtin_alloca
# endif
#endif
#define PLATFORM_HAS_POWER_SWITCH
#define PLATFORM_MAX_MSG_SIZE (256)
#define PLATFORM_IDENT() "PC-HOSTED"
#define BOARD_IDENT PLATFORM_IDENT
#define SET_RUN_STATE(state)
#define SET_IDLE_STATE(state)
#define SET_ERROR_STATE(state)
/* Allow 100mS for responses to reach us */
#define RESP_TIMEOUT (100)
void platform_buffer_flush(void);
int platform_buffer_write(const uint8_t *data, int size);
int platform_buffer_read(uint8_t *data, int size);
static inline int platform_hwversion(void)
{
return 0;
}
#endif

View File

@ -1,133 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2018 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Modified by Dave Marples <dave@marples.net>
*
* 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/>.
*/
/* MPSSE bit-banging SW-DP interface over FTDI with loop unrolled.
* Speed is sensible.
*/
#include <stdio.h>
#include <assert.h>
#include "general.h"
#include "swdptap.h"
#include "remote.h"
static bool swdptap_seq_in_parity(uint32_t *res, int ticks);
static uint32_t swdptap_seq_in(int ticks);
static void swdptap_seq_out(uint32_t MS, int ticks);
static void swdptap_seq_out_parity(uint32_t MS, int ticks);
swd_proc_t swd_proc;
int platform_swdptap_init(void)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=sprintf((char *)construct,"%s",REMOTE_SWDP_INIT_STR);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((!s) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"swdptap_init failed, error %s\n",s?(char *)&(construct[1]):"unknown");
exit(-1);
}
swd_proc.swdptap_seq_in = swdptap_seq_in;
swd_proc.swdptap_seq_in_parity = swdptap_seq_in_parity;
swd_proc.swdptap_seq_out = swdptap_seq_out;
swd_proc.swdptap_seq_out_parity = swdptap_seq_out_parity;
return 0;
}
static bool swdptap_seq_in_parity(uint32_t *res, int ticks)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=sprintf((char *)construct,REMOTE_SWDP_IN_PAR_STR,ticks);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((s<2) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"swdptap_seq_in_parity failed, error %s\n",s?(char *)&(construct[1]):"short response");
exit(-1);
}
*res=remotehston(-1,(char *)&construct[1]);
return (construct[0]!=REMOTE_RESP_OK);
}
static uint32_t swdptap_seq_in(int ticks)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=sprintf((char *)construct,REMOTE_SWDP_IN_STR,ticks);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((s<2) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"swdptap_seq_in failed, error %s\n",s?(char *)&(construct[1]):"short response");
exit(-1);
}
return remotehston(-1,(char *)&construct[1]);
}
static void swdptap_seq_out(uint32_t MS, int ticks)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=sprintf((char *)construct,REMOTE_SWDP_OUT_STR,ticks,MS);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((s<1) || (construct[0]==REMOTE_RESP_ERR))
{
fprintf(stderr,"swdptap_seq_out failed, error %s\n",s?(char *)&(construct[1]):"short response");
exit(-1);
}
}
static void swdptap_seq_out_parity(uint32_t MS, int ticks)
{
uint8_t construct[PLATFORM_MAX_MSG_SIZE];
int s;
s=sprintf((char *)construct,REMOTE_SWDP_OUT_PAR_STR,ticks,MS);
platform_buffer_write(construct,s);
s=platform_buffer_read(construct, PLATFORM_MAX_MSG_SIZE);
if ((s<1) || (construct[1]==REMOTE_RESP_ERR))
{
fprintf(stderr,"swdptap_seq_out_parity failed, error %s\n",s?(char *)&(construct[2]):"short response");
exit(-1);
}
}