Merge commit 'd63e870e82ecbd73af2d14e6794d2985cb9bd0ad' into sam-update

This commit is contained in:
Jason Kotzin 2022-08-09 17:13:06 -07:00
commit 41449370b4
32 changed files with 766 additions and 400 deletions

View File

@ -442,7 +442,10 @@ int usbFeeder(void)
{ {
unsigned char *c=cbw; unsigned char *c=cbw;
if (options.dump) if (options.dump)
printf(cbw); {
cbw[size] = 0;
printf("%s", (char*)cbw);
}
else else
while (size--) while (size--)
_protocolPump(c++); _protocolPump(c++);

View File

@ -25,6 +25,7 @@
*/ */
#include "general.h" #include "general.h"
#include "ctype.h"
#include "hex_utils.h" #include "hex_utils.h"
#include "gdb_if.h" #include "gdb_if.h"
#include "gdb_packet.h" #include "gdb_packet.h"
@ -429,9 +430,37 @@ handle_v_packet(char *packet, int plen)
else else
gdb_putpacketz("E01"); gdb_putpacketz("E01");
} else if (!strcmp(packet, "vRun;")) { } else if (!strncmp(packet, "vRun", 4)) {
/* Parse command line for get_cmdline semihosting call */
char cmdline[83];
char *pbuf = cmdline;
char *tok = packet + 4;
if (*tok == ';') tok++;
*cmdline='\0';
while(*tok != '\0') {
if(strlen(cmdline)+3 >= sizeof(cmdline)) break;
if (*tok == ';') {
*pbuf++=' ';
*pbuf='\0';
tok++;
continue;
}
if (isxdigit(*tok) && isxdigit(*(tok+1))) {
unhexify(pbuf, tok, 2);
if ((*pbuf == ' ') || (*pbuf == '\\')) {
*(pbuf+1)=*pbuf;
*pbuf++='\\';
}
pbuf++;
tok+=2;
*pbuf='\0';
continue;
}
break;
}
/* Run target program. For us (embedded) this means reset. */ /* Run target program. For us (embedded) this means reset. */
if(cur_target) { if(cur_target) {
target_set_cmdline(cur_target, cmdline);
target_reset(cur_target); target_reset(cur_target);
gdb_putpacketz("T05"); gdb_putpacketz("T05");
} else if(last_target) { } else if(last_target) {
@ -440,6 +469,7 @@ handle_v_packet(char *packet, int plen)
/* If we were able to attach to the target again */ /* If we were able to attach to the target again */
if (cur_target) { if (cur_target) {
target_set_cmdline(cur_target, cmdline);
target_reset(cur_target); target_reset(cur_target);
gdb_putpacketz("T05"); gdb_putpacketz("T05");
} else gdb_putpacketz("E01"); } else gdb_putpacketz("E01");

View File

@ -80,6 +80,7 @@ void target_reset(target *t);
void target_halt_request(target *t); void target_halt_request(target *t);
enum target_halt_reason target_halt_poll(target *t, target_addr *watch); enum target_halt_reason target_halt_poll(target *t, target_addr *watch);
void target_halt_resume(target *t, bool step); void target_halt_resume(target *t, bool step);
void target_set_cmdline(target *t, char *cmdline);
/* Break-/watchpoint functions */ /* Break-/watchpoint functions */
enum target_breakwatch { enum target_breakwatch {

View File

@ -188,7 +188,7 @@ static const struct usb_endpoint_descriptor uart_data_endp[] = {{
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x03, .bEndpointAddress = 0x03,
.bmAttributes = USB_ENDPOINT_ATTR_BULK, .bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE, .wMaxPacketSize = CDCACM_PACKET_SIZE / 2,
.bInterval = 1, .bInterval = 1,
}, { }, {
.bLength = USB_DT_ENDPOINT_SIZE, .bLength = USB_DT_ENDPOINT_SIZE,

View File

@ -8,5 +8,5 @@ else ifneq (, $(findstring cygwin, $(SYS)))
LDFLAGS += -lusb-1.0 -lws2_32 LDFLAGS += -lusb-1.0 -lws2_32
endif endif
VPATH += platforms/pc VPATH += platforms/pc
SRC += timing.c cl_utils.c SRC += timing.c cl_utils.c utils.c
CFLAGS +=-I ./target -I./platforms/pc CFLAGS +=-I ./target -I./platforms/pc

View File

@ -290,34 +290,7 @@ int platform_buffer_read(uint8_t *data, int size)
return size; 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
const char *platform_target_voltage(void) const char *platform_target_voltage(void)
{ {
return "not supported"; return "not supported";
} }
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

@ -1,14 +1,15 @@
TARGET=blackmagic_hosted TARGET=blackmagic_hosted
SYS = $(shell $(CC) -dumpmachine) SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DPC_HOSTED -DNO_LIBOPENCM3 -DENABLE_DEBUG -I CFLAGS += -DPC_HOSTED -DNO_LIBOPENCM3 -DENABLE_DEBUG
CFLAGS += $(shell pkg-config --cflags libftdi1)
CFLAGS +=-I ./target -I./platforms/pc CFLAGS +=-I ./target -I./platforms/pc
LDFLAGS += $(shell pkg-config --libs libftdi1)
ifneq (, $(findstring mingw, $(SYS))) ifneq (, $(findstring mingw, $(SYS)))
LDFLAGS += -lusb-1.0 -lws2_32 SRC += serial_win.c
CFLAGS += -Wno-cast-function-type LDFLAGS += -lws2_32
else ifneq (, $(findstring cygwin, $(SYS))) else ifneq (, $(findstring cygwin, $(SYS)))
LDFLAGS += -lusb-1.0 -lws2_32 SRC += serial_win.c
LDFLAGS += -lws2_32
else
SRC += serial_unix.c
endif endif
VPATH += platforms/pc VPATH += platforms/pc
SRC += cl_utils.c timing.c SRC += cl_utils.c timing.c utils.c

View File

@ -98,7 +98,7 @@ void jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI
if(!ticks || !DI) return; if(!ticks || !DI) return;
/* Reduce the length of DI according to the bits we're transmitting */ /* Reduce the length of DI according to the bits we're transmitting */
DIl&=(1L<<(ticks+1))-1; 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); 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); platform_buffer_write(construct,s);
@ -111,8 +111,8 @@ void jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI
} }
if (DO) { if (DO) {
for (unsigned int i = 1; i*8 <= (unsigned int)ticks; i++) uint64_t DOl = remotehston(-1, (char *)&construct[1]);
DO[i - 1] = remotehston(2 , (char *)&construct[s - (i * 2)]); *(uint64_t *)DO = DOl;
} }
} }

View File

@ -25,77 +25,16 @@
#include "remote.h" #include "remote.h"
#include <assert.h> #include <assert.h>
#include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <string.h> #include <string.h>
#include <termios.h>
#include <unistd.h>
#include "cl_utils.h" #include "cl_utils.h"
static BMP_CL_OPTIONS_t cl_opts; /* Portable way to nullify the struct*/
/* Allow 100mS for responses to reach us */
#define RESP_TIMEOUT (100)
/* Define this to see the transactions across the link */
//#define DUMP_TRANSACTIONS
static int f; /* File descriptor for connection to GDB remote */
int set_interface_attribs (int fd, int speed, int parity)
/* A nice routine grabbed from
* https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c
*/
{
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
fprintf(stderr,"error %d from tcgetattr", errno);
return -1;
}
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0)
{
fprintf(stderr,"error %d from tcsetattr", errno);
return -1;
}
return 0;
}
void platform_init(int argc, char **argv) void platform_init(int argc, char **argv)
{ {
BMP_CL_OPTIONS_t cl_opts = {0};
cl_opts.opt_idstring = "Blackmagic Debug Probe Remote"; cl_opts.opt_idstring = "Blackmagic Debug Probe Remote";
cl_init(&cl_opts, argc, argv); cl_init(&cl_opts, argc, argv);
char construct[PLATFORM_MAX_MSG_SIZE]; char construct[PLATFORM_MAX_MSG_SIZE];
@ -105,18 +44,8 @@ void platform_init(int argc, char **argv)
printf("License GPLv3+: GNU GPL version 3 or later " printf("License GPLv3+: GNU GPL version 3 or later "
"<http://gnu.org/licenses/gpl.html>\n\n"); "<http://gnu.org/licenses/gpl.html>\n\n");
f=open(cl_opts.opt_serial,O_RDWR|O_SYNC|O_NOCTTY); if (serial_open(&cl_opts))
if (f<0)
{
fprintf(stderr,"Couldn't open serial port %s\n", cl_opts.opt_serial);
exit(-1); exit(-1);
}
if (set_interface_attribs (f, 115000, 0)<0)
{
exit(-1);
}
int c=snprintf(construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_START_STR); int c=snprintf(construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_START_STR);
platform_buffer_write((uint8_t *)construct,c); platform_buffer_write((uint8_t *)construct,c);
c=platform_buffer_read((uint8_t *)construct, PLATFORM_MAX_MSG_SIZE); c=platform_buffer_read((uint8_t *)construct, PLATFORM_MAX_MSG_SIZE);
@ -132,7 +61,7 @@ void platform_init(int argc, char **argv)
int ret = cl_execute(&cl_opts); int ret = cl_execute(&cl_opts);
if (cl_opts.opt_tpwr) if (cl_opts.opt_tpwr)
platform_target_set_power(0); platform_target_set_power(0);
close(f); serial_close();
exit(ret); exit(ret);
} else { } else {
assert(gdb_if_init() == 0); assert(gdb_if_init() == 0);
@ -217,110 +146,6 @@ void platform_buffer_flush(void)
} }
int platform_buffer_write(const uint8_t *data, int size)
{
int s;
#ifdef DUMP_TRANSACTIONS
printf("%s\n",data);
#endif
s=write(f,data,size);
if (s<0)
{
fprintf(stderr,"Failed to write\n");
exit(-2);
}
return size;
}
int platform_buffer_read(uint8_t *data, int maxsize)
{
uint8_t *c;
int s;
int ret;
uint32_t endTime;
fd_set rset;
struct timeval tv;
c=data;
tv.tv_sec=0;
endTime=platform_time_ms()+RESP_TIMEOUT;
tv.tv_usec=1000*(endTime-platform_time_ms());
/* Look for start of response */
do
{
FD_ZERO(&rset);
FD_SET(f, &rset);
ret = select(f + 1, &rset, NULL, NULL, &tv);
if (ret < 0)
{
fprintf(stderr,"Failed on select\n");
exit(-4);
}
if(ret == 0)
{
fprintf(stderr,"Timeout on read\n");
exit(-3);
}
s=read(f,c,1);
}
while ((s>0) && (*c!=REMOTE_RESP));
/* Now collect the response */
do
{
FD_ZERO(&rset);
FD_SET(f, &rset);
ret = select(f + 1, &rset, NULL, NULL, &tv);
if (ret < 0)
{
fprintf(stderr,"Failed on select\n");
exit(-4);
}
if(ret == 0)
{
fprintf(stderr,"Timeout on read\n");
exit(-3);
}
s=read(f,c,1);
if (*c==REMOTE_EOM)
{
*c=0;
#ifdef DUMP_TRANSACTIONS
printf(" %s\n",data);
#endif
return (c-data);
}
else
c++;
}
while ((s>=0) && (c-data<maxsize));
fprintf(stderr,"Failed to read\n");
exit(-3);
return 0;
}
#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
const char *platform_target_voltage(void) const char *platform_target_voltage(void)
{ {
@ -340,15 +165,3 @@ const char *platform_target_voltage(void)
return (char *)&construct[1]; return (char *)&construct[1];
} }
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

@ -41,10 +41,12 @@
#define SET_IDLE_STATE(state) #define SET_IDLE_STATE(state)
#define SET_ERROR_STATE(state) #define SET_ERROR_STATE(state)
/* Allow 100mS for responses to reach us */
#define RESP_TIMEOUT (100)
void platform_buffer_flush(void); void platform_buffer_flush(void);
int platform_buffer_write(const uint8_t *data, int size); int platform_buffer_write(const uint8_t *data, int size);
int platform_buffer_read(uint8_t *data, int size); int platform_buffer_read(uint8_t *data, int size);
static inline int platform_hwversion(void) static inline int platform_hwversion(void)
{ {
return 0; return 0;

View File

@ -9,5 +9,5 @@ else ifneq (, $(findstring cygwin, $(SYS)))
LDFLAGS += -lws2_32 LDFLAGS += -lws2_32
endif endif
VPATH += platforms/pc VPATH += platforms/pc
SRC += timing.c stlinkv2.c cl_utils.c SRC += timing.c stlinkv2.c cl_utils.c utils.c
OWN_HL = 1 OWN_HL = 1

View File

@ -69,29 +69,3 @@ int platform_buffer_read(uint8_t *data, int size)
(void) data; (void) data;
return size; 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

@ -38,6 +38,7 @@
#define O_BINARY 0 #define O_BINARY 0
#endif #endif
#if defined(_WIN32) || defined(__CYGWIN__) #if defined(_WIN32) || defined(__CYGWIN__)
# include <windows.h>
#else #else
# include <sys/mman.h> # include <sys/mman.h>
#endif #endif
@ -52,6 +53,9 @@ struct mmap_data {
int fd; int fd;
#endif #endif
}; };
int cl_debuglevel;
static struct mmap_data map; /* Portable way way to nullify the struct!*/
static int bmp_mmap(char *file, struct mmap_data *map) static int bmp_mmap(char *file, struct mmap_data *map)
{ {
@ -115,6 +119,7 @@ static void cl_help(char **argv, BMP_CL_OPTIONS_t *opt)
printf("Usage: %s [options]\n", argv[0]); printf("Usage: %s [options]\n", argv[0]);
printf("\t-h\t\t: This help.\n"); printf("\t-h\t\t: This help.\n");
printf("\t-v[1|2]\t\t: Increasing verbosity\n"); printf("\t-v[1|2]\t\t: Increasing verbosity\n");
printf("\t-d \"path\"\t: Use serial device at \"path\"\n");
printf("\t-s \"string\"\t: Use dongle with (partial) " printf("\t-s \"string\"\t: Use dongle with (partial) "
"serial number \"string\"\n"); "serial number \"string\"\n");
printf("\t-c \"string\"\t: Use ftdi dongle with type \"string\"\n"); printf("\t-c \"string\"\t: Use ftdi dongle with type \"string\"\n");
@ -144,7 +149,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
opt->opt_target_dev = 1; opt->opt_target_dev = 1;
opt->opt_flash_start = 0x08000000; opt->opt_flash_start = 0x08000000;
opt->opt_flash_size = 16 * 1024 *1024; opt->opt_flash_size = 16 * 1024 *1024;
while((c = getopt(argc, argv, "Ehv::s:c:CnN:tVta:S:jprR")) != -1) { while((c = getopt(argc, argv, "Ehv::d:s:c:CnN:tVta:S:jprR")) != -1) {
switch(c) { switch(c) {
case 'c': case 'c':
if (optarg) if (optarg)
@ -155,7 +160,9 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
break; break;
case 'v': case 'v':
if (optarg) if (optarg)
opt->opt_debuglevel = strtol(optarg, NULL, 0); cl_debuglevel = strtol(optarg, NULL, 0);
else
cl_debuglevel = -1;
break; break;
case 'j': case 'j':
opt->opt_usejtag = true; opt->opt_usejtag = true;
@ -166,6 +173,10 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
case 'n': case 'n':
opt->opt_no_wait = true; opt->opt_no_wait = true;
break; break;
case 'd':
if (optarg)
opt->opt_device = optarg;
break;
case 's': case 's':
if (optarg) if (optarg)
opt->opt_serial = optarg; opt->opt_serial = optarg;
@ -253,6 +264,7 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
platform_srst_set_val(opt->opt_connect_under_reset); platform_srst_set_val(opt->opt_connect_under_reset);
if (opt->opt_mode == BMP_MODE_TEST) if (opt->opt_mode == BMP_MODE_TEST)
printf("Running in Test Mode\n"); printf("Running in Test Mode\n");
printf("Target voltage: %s Volt\n", platform_target_voltage());
if (opt->opt_usejtag) { if (opt->opt_usejtag) {
num_targets = jtag_scan(NULL); num_targets = jtag_scan(NULL);
} else { } else {
@ -276,7 +288,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
goto target_detach; goto target_detach;
} }
int read_file = -1; int read_file = -1;
struct mmap_data map = {0};
if ((opt->opt_mode == BMP_MODE_FLASH_WRITE) || if ((opt->opt_mode == BMP_MODE_FLASH_WRITE) ||
(opt->opt_mode == BMP_MODE_FLASH_VERIFY)) { (opt->opt_mode == BMP_MODE_FLASH_VERIFY)) {
int mmap_res = bmp_mmap(opt->opt_flash_file, &map); int mmap_res = bmp_mmap(opt->opt_flash_file, &map);

View File

@ -41,6 +41,7 @@ typedef struct BMP_CL_OPTIONS_s {
bool opt_tpwr; bool opt_tpwr;
bool opt_connect_under_reset; bool opt_connect_under_reset;
char *opt_flash_file; char *opt_flash_file;
char *opt_device;
char *opt_serial; char *opt_serial;
char *opt_cable; char *opt_cable;
int opt_debuglevel; int opt_debuglevel;
@ -52,4 +53,6 @@ typedef struct BMP_CL_OPTIONS_s {
void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv); void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv);
int cl_execute(BMP_CL_OPTIONS_t *opt); int cl_execute(BMP_CL_OPTIONS_t *opt);
int serial_open(BMP_CL_OPTIONS_t *opt);
void serial_close(void);
#endif #endif

View File

@ -0,0 +1,214 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2019 Dave Marples <dave@marples.net>
* with additions from 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 <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include "general.h"
#include "remote.h"
#include "cl_utils.h"
static int fd; /* File descriptor for connection to GDB remote */
extern int cl_debuglevel;
/* A nice routine grabbed from
* https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c
*/
static int set_interface_attribs(void)
{
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0) {
fprintf(stderr,"error %d from tcgetattr", errno);
return -1;
}
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0) {
fprintf(stderr,"error %d from tcsetattr", errno);
return -1;
}
return 0;
}
#define BMP_IDSTRING "usb-Black_Sphere_Technologies_Black_Magic_Probe"
#define DEVICE_BY_ID "/dev/serial/by-id/"
int serial_open(BMP_CL_OPTIONS_t *opt)
{
char name[4096];
if (!opt->opt_device) {
/* Try to find some BMP if0*/
struct dirent *dp;
DIR *dir = opendir(DEVICE_BY_ID);
if (!dir) {
fprintf(stderr, "No serial device found\n");
return -1;
}
int num_devices = 0;
int num_total = 0;
while ((dp = readdir(dir)) != NULL) {
if ((strstr(dp->d_name, BMP_IDSTRING)) &&
(strstr(dp->d_name, "-if00"))) {
num_total++;
if (((opt->opt_serial) &&
(!strstr(dp->d_name, opt->opt_serial))))
continue;
num_devices++;
strcpy(name, DEVICE_BY_ID);
strncat(name, dp->d_name, sizeof(name) - strlen(name) - 1);
}
}
closedir(dir);
if ((num_devices == 0) && (num_total == 0)){
fprintf(stderr, "No BMP probe found\n");
return -1;
} else if (num_devices != 1) {
fprintf(stderr, "Available Probes:\n");
dir = opendir(DEVICE_BY_ID);
if (dir) {
while ((dp = readdir(dir)) != NULL) {
if ((strstr(dp->d_name, BMP_IDSTRING)) &&
(strstr(dp->d_name, "-if00")))
fprintf(stderr, "%s\n", dp->d_name);
}
closedir(dir);
if (opt->opt_serial)
fprintf(stderr, "Do no match given serial \"%s\"\n", opt->opt_serial);
else
fprintf(stderr, "Select Probe with -s <(Partial) Serial Number\n");
} else {
fprintf(stderr, "Could not opendir %s: %s\n", name, strerror(errno));
}
return -1;
}
} else {
strncpy(name, opt->opt_device, sizeof(name) - 1);
}
fd = open(name, O_RDWR | O_SYNC | O_NOCTTY);
if (fd < 0) {
fprintf(stderr,"Couldn't open serial port %s\n", name);
return -1;
}
/* BMP only offers an USB-Serial connection with no real serial
* line in between. No need for baudrate or parity.!
*/
return set_interface_attribs();
}
void serial_close(void)
{
close(fd);
}
int platform_buffer_write(const uint8_t *data, int size)
{
int s;
if (cl_debuglevel)
printf("%s\n",data);
s = write(fd, data, size);
if (s < 0) {
fprintf(stderr, "Failed to write\n");
exit(-2);
}
return size;
}
int platform_buffer_read(uint8_t *data, int maxsize)
{
uint8_t *c;
int s;
int ret;
uint32_t endTime;
fd_set rset;
struct timeval tv;
c = data;
tv.tv_sec = 0;
endTime = platform_time_ms() + RESP_TIMEOUT;
tv.tv_usec = 1000 * (endTime - platform_time_ms());
/* Look for start of response */
do {
FD_ZERO(&rset);
FD_SET(fd, &rset);
ret = select(fd + 1, &rset, NULL, NULL, &tv);
if (ret < 0) {
fprintf(stderr,"Failed on select\n");
exit(-4);
}
if(ret == 0) {
fprintf(stderr,"Timeout on read RESP\n");
exit(-3);
}
s = read(fd, c, 1);
}
while ((s > 0) && (*c != REMOTE_RESP));
/* Now collect the response */
do {
FD_ZERO(&rset);
FD_SET(fd, &rset);
ret = select(fd + 1, &rset, NULL, NULL, &tv);
if (ret < 0) {
fprintf(stderr,"Failed on select\n");
exit(-4);
}
if(ret == 0) {
fprintf(stderr,"Timeout on read\n");
exit(-3);
}
s = read(fd, c, 1);
if (*c==REMOTE_EOM) {
*c = 0;
if (cl_debuglevel)
printf(" %s\n",data);
return (c - data);
} else {
c++;
}
}while ((s >= 0) && ((c - data) < maxsize));
fprintf(stderr,"Failed to read\n");
exit(-3);
return 0;
}

View File

@ -0,0 +1,139 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include "general.h"
#include <windows.h>
#include "remote.h"
#include "cl_utils.h"
HANDLE hComm;
extern int cl_debuglevel;
int serial_open(BMP_CL_OPTIONS_t *opt)
{
if (!opt->opt_device) {
fprintf(stderr,"Specify the serial device to use!\n");
return -1;
}
char device[256];
if (strstr(opt->opt_device, "\\\\.\\")) {
strncpy(device, opt->opt_device, sizeof(device) - 1);
} else {
strcpy(device, "\\\\.\\");
strncat(device, opt->opt_device, sizeof(device) - strlen(device) - 1);
}
hComm = CreateFile(device, //port name
GENERIC_READ | GENERIC_WRITE, //Read/Write
0, // No Sharing
NULL, // No Security
OPEN_EXISTING,// Open existing port only
0, // Non Overlapped I/O
NULL); // Null for Comm Devices}
if (hComm == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Could not open %s: %ld\n", device,
GetLastError());
return -1;
}
DCB dcbSerialParams;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hComm, &dcbSerialParams)) {
fprintf(stderr, "GetCommState failed %ld\n", GetLastError());
return -1;
}
dcbSerialParams.ByteSize = 8;
if (!SetCommState(hComm, &dcbSerialParams)) {
fprintf(stderr, "SetCommState failed %ld\n", GetLastError());
return -1;
}
COMMTIMEOUTS timeouts = {0};
timeouts.ReadIntervalTimeout = 10;
timeouts.ReadTotalTimeoutConstant = 10;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 10;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hComm, &timeouts)) {
fprintf(stderr, "SetCommTimeouts failed %ld\n", GetLastError());
return -1;
}
return 0;
}
void serial_close(void)
{
CloseHandle(hComm);
}
int platform_buffer_write(const uint8_t *data, int size)
{
if (cl_debuglevel)
printf("%s\n",data);
int s = 0;
do {
DWORD written;
if (!WriteFile(hComm, data + s, size - s, &written, NULL)) {
fprintf(stderr, "Serial write failed %ld, written %d\n",
GetLastError(), s);
return -1;
}
s += written;
} while (s < size);
return 0;
}
int platform_buffer_read(uint8_t *data, int maxsize)
{
DWORD s;
uint8_t response = 0;
uint32_t startTime = platform_time_ms();
uint32_t endTime = platform_time_ms() + RESP_TIMEOUT;
do {
if (!ReadFile(hComm, &response, 1, &s, NULL)) {
fprintf(stderr,"ERROR on read RESP\n");
exit(-3);
}
if (platform_time_ms() > endTime) {
fprintf(stderr,"Timeout on read RESP\n");
exit(-4);
}
} while (response != REMOTE_RESP);
uint8_t *c = data;
do {
if (!ReadFile(hComm, c, 1, &s, NULL)) {
fprintf(stderr,"Error on read\n");
exit(-3);
}
if (s > 0 ) {
if (cl_debuglevel)
printf("%c", *c);
if (*c == REMOTE_EOM) {
*c = 0;
if (cl_debuglevel)
printf("\n");
return (c - data);
} else {
c++;
}
}
} while (((c - data) < maxsize) && (platform_time_ms() < endTime));
fprintf(stderr,"Failed to read EOM at %d\n",
platform_time_ms() - startTime);
exit(-3);
return 0;
}

55
src/platforms/pc/utils.c Normal file
View File

@ -0,0 +1,55 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
* Base on code:
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* and others.
*
* 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 deduplicates codes used in several pc-hosted platforms
*/
#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#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

@ -39,6 +39,7 @@ uint8_t running_status;
uint16_t led_idle_run; uint16_t led_idle_run;
uint16_t srst_pin; uint16_t srst_pin;
static uint32_t rev; static uint32_t rev;
static void adc_init(void);
int platform_hwversion(void) int platform_hwversion(void)
{ {
@ -85,6 +86,7 @@ void platform_init(void)
/* Don't enable UART if we're being debugged. */ /* Don't enable UART if we're being debugged. */
if (!(SCS_DEMCR & SCS_DEMCR_TRCENA)) if (!(SCS_DEMCR & SCS_DEMCR_TRCENA))
usbuart_init(); usbuart_init();
adc_init();
} }
void platform_srst_set_val(bool assert) void platform_srst_set_val(bool assert)
@ -105,7 +107,52 @@ bool platform_srst_get_val()
return gpio_get(SRST_PORT, srst_pin) == 0; return gpio_get(SRST_PORT, srst_pin) == 0;
} }
static void adc_init(void)
{
rcc_periph_clock_enable(RCC_ADC1);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_ANALOG, GPIO0);
adc_power_off(ADC1);
adc_disable_scan_mode(ADC1);
adc_set_single_conversion_mode(ADC1);
adc_disable_external_trigger_regular(ADC1);
adc_set_right_aligned(ADC1);
adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC);
adc_enable_temperature_sensor();
adc_power_on(ADC1);
/* Wait for ADC starting up. */
for (int i = 0; i < 800000; i++) /* Wait a bit. */
__asm__("nop");
adc_reset_calibration(ADC1);
adc_calibrate(ADC1);
}
const char *platform_target_voltage(void) const char *platform_target_voltage(void)
{ {
return "unknown"; static char ret[] = "0.00V";
const uint8_t channel = 0;
adc_set_regular_sequence(ADC1, 1, (uint8_t*)&channel);
adc_start_conversion_direct(ADC1);
/* Wait for end of conversion. */
while (!adc_eoc(ADC1));
uint32_t platform_adc_value = adc_read_regular(ADC1);
const uint8_t ref_channel = 17;
adc_set_regular_sequence(ADC1, 1, (uint8_t*)&ref_channel);
adc_start_conversion_direct(ADC1);
/* Wait for end of conversion. */
while (!adc_eoc(ADC1));
uint32_t vrefint_value = adc_read_regular(ADC1);
/* Value in mV*/
uint32_t val = (platform_adc_value * 2400) / vrefint_value;
ret[0] = '0' + val / 1000;
ret[2] = '0' + (val / 100) % 10;
ret[3] = '0' + (val / 10) % 10;
return ret;
} }

View File

@ -20,7 +20,8 @@
#include "morse.h" #include "morse.h"
#include <libopencm3/cm3/systick.h> #include <libopencm3/cm3/systick.h>
#include <libopencm3/cm3/scb.h> #include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/rcc.h>
uint8_t running_status; uint8_t running_status;
static volatile uint32_t time_ms; static volatile uint32_t time_ms;
@ -29,9 +30,10 @@ void platform_timing_init(void)
{ {
/* Setup heartbeat timer */ /* Setup heartbeat timer */
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
systick_set_reload(900000); /* Interrupt us at 10 Hz */ /* Interrupt us at 10 Hz */
SCB_SHPR(11) &= ~((15 << 4) & 0xff); systick_set_reload(rcc_ahb_frequency / (8 * 10) );
SCB_SHPR(11) |= ((14 << 4) & 0xff); /* SYSTICK_IRQ with low priority */
nvic_set_priority(NVIC_SYSTICK_IRQ, 14 << 4);
systick_interrupt_enable(); systick_interrupt_enable();
systick_counter_enable(); systick_counter_enable();
} }

View File

@ -61,7 +61,7 @@ static void _respond(char respCode, uint64_t param)
/* Send response to far end */ /* Send response to far end */
{ {
char buf[34]; char buf[35]; /*Response, code, EOM and 2*16 hex nibbles*/
char *p=buf; char *p=buf;
gdb_if_putchar(REMOTE_RESP,0); gdb_if_putchar(REMOTE_RESP,0);
@ -185,7 +185,7 @@ void remotePacketProcessJTAG(uint8_t i, char *packet)
jtagtap_tdi_tdo_seq((void *)&DO, (packet[1]==REMOTE_TDITDO_TMS), (void *)&DI, ticks); jtagtap_tdi_tdo_seq((void *)&DO, (packet[1]==REMOTE_TDITDO_TMS), (void *)&DI, ticks);
/* Mask extra bits on return value... */ /* Mask extra bits on return value... */
DO&=(1<<(ticks+1))-1; DO &= (1LL << (ticks + 1)) - 1;
_respond(REMOTE_RESP_OK, DO); _respond(REMOTE_RESP_OK, DO);
} }

View File

@ -210,6 +210,7 @@ static const struct {
{0xc09, aa_cortexa, cidc_dc, PIDR_PN_BIT_STRINGS("Cortex-A9 Debug", "(Debug Unit)")}, {0xc09, aa_cortexa, cidc_dc, PIDR_PN_BIT_STRINGS("Cortex-A9 Debug", "(Debug Unit)")},
{0xc0f, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-A15 Debug", "(Debug Unit)")}, /* support? */ {0xc0f, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-A15 Debug", "(Debug Unit)")}, /* support? */
{0xc14, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-R4 Debug", "(Debug Unit)")}, /* support? */ {0xc14, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-R4 Debug", "(Debug Unit)")}, /* support? */
{0xcd0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Atmel DSU", "(Device Service Unit)")},
{0xd21, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M33", "()")}, /* support? */ {0xd21, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M33", "()")}, /* support? */
{0xfff, aa_end, cidc_unknown, PIDR_PN_BIT_STRINGS("end", "end")} {0xfff, aa_end, cidc_unknown, PIDR_PN_BIT_STRINGS("end", "end")}
}; };
@ -252,12 +253,29 @@ static uint32_t adiv5_mem_read32(ADIv5_AP_t *ap, uint32_t addr)
return ret; return ret;
} }
static uint32_t adiv5_ap_read_id(ADIv5_AP_t *ap, uint32_t addr)
{
uint32_t res = 0;
for (int i = 0; i < 4; i++) {
uint32_t x = adiv5_mem_read32(ap, addr + 4 * i);
res |= (x & 0xff) << (i * 8);
}
return res;
}
uint64_t adiv5_ap_read_pidr(ADIv5_AP_t *ap, uint32_t addr)
{
uint64_t pidr = adiv5_ap_read_id(ap, addr + PIDR4_OFFSET);
pidr = pidr << 32 | adiv5_ap_read_id(ap, addr + PIDR0_OFFSET);
return pidr;
}
static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, int num_entry) static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, int num_entry)
{ {
(void) num_entry; (void) num_entry;
addr &= ~3; addr &= ~3;
uint64_t pidr = 0; uint64_t pidr = adiv5_ap_read_pidr(ap, addr);
uint32_t cidr = 0; uint32_t cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET);
bool res = false; bool res = false;
#if defined(ENABLE_DEBUG) && defined(PLATFORM_HAS_DEBUG) #if defined(ENABLE_DEBUG) && defined(PLATFORM_HAS_DEBUG)
char indent[recursion + 1]; char indent[recursion + 1];
@ -266,22 +284,6 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
indent[recursion] = 0; indent[recursion] = 0;
#endif #endif
/* Assemble logical Product ID register value. */
for (int i = 0; i < 4; i++) {
uint32_t x = adiv5_mem_read32(ap, addr + PIDR0_OFFSET + 4*i);
pidr |= (x & 0xff) << (i * 8);
}
{
uint32_t x = adiv5_mem_read32(ap, addr + PIDR4_OFFSET);
pidr |= (uint64_t)x << 32;
}
/* Assemble logical Component ID register value. */
for (int i = 0; i < 4; i++) {
uint32_t x = adiv5_mem_read32(ap, addr + CIDR0_OFFSET + 4*i);
cidr |= ((uint64_t)(x & 0xff)) << (i * 8);
}
if (adiv5_dp_error(ap->dp)) { if (adiv5_dp_error(ap->dp)) {
DEBUG("%sFault reading ID registers\n", indent); DEBUG("%sFault reading ID registers\n", indent);
return false; return false;
@ -376,7 +378,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
cortexm_probe(ap, false); cortexm_probe(ap, false);
break; break;
case aa_cortexa: case aa_cortexa:
DEBUG("%s-> cortexa_probe\n", indent + 1); DEBUG("\n -> cortexa_probe\n");
cortexa_probe(ap, addr); cortexa_probe(ap, addr);
break; break;
default: default:

View File

@ -198,5 +198,5 @@ void adiv5_mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len);
void adiv5_mem_write(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len); void adiv5_mem_write(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len);
void adiv5_mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src, void adiv5_mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src,
size_t len, enum align align); size_t len, enum align align);
uint64_t adiv5_ap_read_pidr(ADIv5_AP_t *ap, uint32_t addr);
#endif #endif

View File

@ -3,10 +3,10 @@
* *
* Copyright (C) 2012 Black Sphere Technologies Ltd. * Copyright (C) 2012 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz> * Written by Gareth McMullin <gareth@blacksphere.co.nz>
* and Koen De Vleeschauwer.
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under tSchreibe Objekte: 100% (21/21), 3.20 KiB | 3.20 MiB/s, Fertig. * it under the terms of the GNU General Public License as published by
he terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
@ -1009,11 +1009,14 @@ static bool cortexm_vector_catch(target *t, int argc, char *argv[])
#endif #endif
/* Semihosting support */ /* Semihosting support */
/* ARM Semihosting syscall numbers, from ARM doc DUI0471C, Chapter 8 */ /* ARM Semihosting syscall numbers, from "Semihosting for AArch32 and AArch64 Version 3.0" */
#define SYS_CLOSE 0x02
#define SYS_CLOCK 0x10 #define SYS_CLOCK 0x10
#define SYS_CLOSE 0x02
#define SYS_ELAPSED 0x30 #define SYS_ELAPSED 0x30
#define SYS_ERRNO 0x13 #define SYS_ERRNO 0x13
#define SYS_EXIT 0x18
#define SYS_EXIT_EXTENDED 0x20
#define SYS_FLEN 0x0C #define SYS_FLEN 0x0C
#define SYS_GET_CMDLINE 0x15 #define SYS_GET_CMDLINE 0x15
#define SYS_HEAPINFO 0x16 #define SYS_HEAPINFO 0x16
@ -1033,6 +1036,28 @@ static bool cortexm_vector_catch(target *t, int argc, char *argv[])
#define SYS_WRITEC 0x03 #define SYS_WRITEC 0x03
#define SYS_WRITE0 0x04 #define SYS_WRITE0 0x04
#if !defined(PC_HOSTED)
/* probe memory access functions */
static void probe_mem_read(target *t __attribute__((unused)), void *probe_dest, target_addr target_src, size_t len)
{
uint8_t *dst = (uint8_t *)probe_dest;
uint8_t *src = (uint8_t *)target_src;
DEBUG("probe_mem_read\n");
while (len--) *dst++=*src++;
return;
}
static void probe_mem_write(target *t __attribute__((unused)), target_addr target_dest, const void *probe_src, size_t len)
{
uint8_t *dst = (uint8_t *)target_dest;
uint8_t *src = (uint8_t *)probe_src;
DEBUG("probe_mem_write\n");
while (len--) *dst++=*src++;
return;
}
#endif
static int cortexm_hostio_request(target *t) static int cortexm_hostio_request(target *t)
{ {
uint32_t arm_regs[t->regs_size]; uint32_t arm_regs[t->regs_size];
@ -1073,6 +1098,7 @@ static int cortexm_hostio_request(target *t)
ret++; ret++;
break; break;
} }
/* FIXME handle requests for special filename ':semihosting-features' */
ret = tc_open(t, params[0], params[2] + 1, pflag, 0644); ret = tc_open(t, params[0], params[2] + 1, pflag, 0644);
if (ret != -1) if (ret != -1)
@ -1093,8 +1119,24 @@ static int cortexm_hostio_request(target *t)
ret = params[2] - ret; ret = params[2] - ret;
break; break;
case SYS_WRITEC: /* writec */ case SYS_WRITEC: /* writec */
ret = tc_write(t, 2, arm_regs[1], 1); ret = tc_write(t, STDERR_FILENO, arm_regs[1], 1);
break; break;
case SYS_WRITE0:{ /* write0 */
ret = -1;
target_addr str_begin = arm_regs[1];
target_addr str_end = str_begin;
while (target_mem_read8(t, str_end) != 0) {
if (target_check_error(t)) break;
str_end++;
}
int len = str_end - str_begin;
if (len != 0) {
int rc = tc_write(t, STDERR_FILENO, str_begin, len);
if (rc != len) break;
}
ret = 0;
break;
}
case SYS_ISTTY: /* isatty */ case SYS_ISTTY: /* isatty */
ret = tc_isatty(t, params[0] - 1); ret = tc_isatty(t, params[0] - 1);
break; break;
@ -1112,17 +1154,102 @@ static int cortexm_hostio_request(target *t)
ret = tc_system(t, params[0] - 1, params[1] + 1); ret = tc_system(t, params[0] - 1, params[1] + 1);
break; break;
case SYS_FLEN: /* Not supported, fake success */ case SYS_FLEN:
#if defined(PC_HOSTED)
t->tc->errno_ = 0; t->tc->errno_ = 0;
break; break;
#else
{ /* file length */
ret = -1;
uint32_t fio_stat[16]; /* same size as fio_stat in gdb/include/gdb/fileio.h */
//DEBUG("SYS_FLEN fio_stat addr %p\n", fio_stat);
void (*saved_mem_read)(target *t, void *dest, target_addr src, size_t len);
void (*saved_mem_write)(target *t, target_addr dest, const void *src, size_t len);
saved_mem_read = t->mem_read;
saved_mem_write = t->mem_write;
t->mem_read = probe_mem_read;
t->mem_write = probe_mem_write;
int rc = tc_fstat(t, params[0] - 1, (target_addr)fio_stat); /* write fstat() result in fio_stat[] */
t->mem_read = saved_mem_read;
t->mem_write = saved_mem_write;
if (rc) break; /* tc_fstat() failed */
uint32_t fst_size_msw = fio_stat[7]; /* most significant 32 bits of fst_size in fio_stat */
uint32_t fst_size_lsw = fio_stat[8]; /* least significant 32 bits of fst_size in fio_stat */
if (fst_size_msw != 0) break; /* file size too large for uint32_t return type */
ret = __builtin_bswap32(fst_size_lsw); /* convert from bigendian to target order */
break;
}
case SYS_TIME: { /* gettimeofday */
ret = -1;
uint32_t fio_timeval[3]; /* same size as fio_timeval in gdb/include/gdb/fileio.h */
//DEBUG("SYS_TIME fio_timeval addr %p\n", fio_timeval);
void (*saved_mem_read)(target *t, void *dest, target_addr src, size_t len);
void (*saved_mem_write)(target *t, target_addr dest, const void *src, size_t len);
saved_mem_read = t->mem_read;
saved_mem_write = t->mem_write;
t->mem_read = probe_mem_read;
t->mem_write = probe_mem_write;
int rc = tc_gettimeofday(t, (target_addr) fio_timeval, (target_addr) NULL); /* write gettimeofday() result in fio_timeval[] */
t->mem_read = saved_mem_read;
t->mem_write = saved_mem_write;
if (rc) break; /* tc_gettimeofday() failed */
uint32_t ftv_sec = fio_timeval[0]; /* time in seconds, first field in fio_timeval */
ret = __builtin_bswap32(ftv_sec); /* convert from bigendian to target order */
break;
}
case SYS_READC: { /* readc */
uint8_t ch;
//DEBUG("SYS_READC ch addr %p\n", &ch);
void (*saved_mem_read)(target *t, void *dest, target_addr src, size_t len);
void (*saved_mem_write)(target *t, target_addr dest, const void *src, size_t len);
saved_mem_read = t->mem_read;
saved_mem_write = t->mem_write;
t->mem_read = probe_mem_read;
t->mem_write = probe_mem_write;
int rc = tc_read(t, params[0] - 1, (target_addr) &ch, 1); /* read a character in ch */
t->mem_read = saved_mem_read;
t->mem_write = saved_mem_write;
if (rc == 1) ret = ch;
else ret = -1;
break;
}
#endif
case SYS_ERRNO: /* Return last errno from GDB */ case SYS_ERRNO: /* Return last errno from GDB */
ret = t->tc->errno_; ret = t->tc->errno_;
break; break;
case SYS_TIME: /* gettimeofday */ case SYS_EXIT: /* _exit() */
/* FIXME How do we use gdb's gettimeofday? */ tc_printf(t, "_exit(0x%x)\n", params[0]);
target_halt_resume(t, 1);
ret = 0;
break; break;
case SYS_GET_CMDLINE: { /* get_cmdline */
uint32_t retval[2];
ret = -1;
target_addr buf_ptr = params[0];
target_addr buf_len = params[1];
if (strlen(t->cmdline)+1 > buf_len) break;
if(target_mem_write(t, buf_ptr, t->cmdline, strlen(t->cmdline)+1)) break;
retval[0] = buf_ptr;
retval[1] = strlen(t->cmdline)+1;
if(target_mem_write(t, arm_regs[1], retval, sizeof(retval))) break;
ret = 0;
break;
}
// not implemented yet:
case SYS_HEAPINFO: /* heapinfo */
case SYS_CLOCK: /* clock */
case SYS_ELAPSED: /* elapsed */
case SYS_ISERROR: /* iserror */
case SYS_TICKFREQ: /* tickfreq */
case SYS_TMPNAM: /* tmpnam */
ret = -1;
break;
} }
arm_regs[0] = ret; arm_regs[0] = ret;

View File

@ -100,6 +100,13 @@ bool lmi_probe(target *t)
lmi_add_flash(t, 0x10000); lmi_add_flash(t, 0x10000);
t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; t->target_options |= CORTEXM_TOPT_INHIBIT_SRST;
return true; return true;
case 0x101F: /* TM4C1294NCPDT */
t->driver = lmi_driver_str;
target_add_ram(t, 0x20000000, 0x40000);
lmi_add_flash(t, 0x100000);
t->target_options |= CORTEXM_TOPT_INHIBIT_SRST;
return true;
} }
return false; return false;
} }

View File

@ -118,6 +118,11 @@ lpc11xx_probe(target *t)
target_add_ram(t, 0x10000000, 0x1000); target_add_ram(t, 0x10000000, 0x1000);
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x1000);
return true; return true;
case 0x1000002b: // FX LPC11U6 32 kB SRAM/256 kB flash (max)
t->driver = "LPC11U6";
target_add_ram(t, 0x10000000, 0x8000);
lpc11xx_add_flash(t, 0x00000000, 0x40000, 0x1000);
return true;
case 0x3000002B: case 0x3000002B:
case 0x3D00002B: case 0x3D00002B:
t->driver = "LPC1343"; t->driver = "LPC1343";

View File

@ -134,6 +134,7 @@ bool nrf51_probe(target *t)
uint32_t ram_size = target_mem_read32(t, NRF52_INFO_RAM); uint32_t ram_size = target_mem_read32(t, NRF52_INFO_RAM);
t->idcode = info_part; t->idcode = info_part;
t->driver = "Nordic nRF52"; t->driver = "Nordic nRF52";
t->target_options |= CORTEXM_TOPT_INHIBIT_SRST;
target_add_ram(t, 0x20000000, ram_size * 1024); target_add_ram(t, 0x20000000, ram_size * 1024);
nrf51_add_flash(t, 0, page_size * code_size, page_size); nrf51_add_flash(t, 0, page_size * code_size, page_size);
nrf51_add_flash(t, NRF51_UICR, page_size, page_size); nrf51_add_flash(t, NRF51_UICR, page_size, page_size);
@ -145,6 +146,7 @@ bool nrf51_probe(target *t)
* IDCODE is kept as '0', as deciphering is hard and * IDCODE is kept as '0', as deciphering is hard and
* there is later no usage.*/ * there is later no usage.*/
target_add_ram(t, 0x20000000, 0x8000); target_add_ram(t, 0x20000000, 0x8000);
t->target_options |= CORTEXM_TOPT_INHIBIT_SRST;
nrf51_add_flash(t, 0, page_size * code_size, page_size); nrf51_add_flash(t, 0, page_size * code_size, page_size);
nrf51_add_flash(t, NRF51_UICR, page_size, page_size); nrf51_add_flash(t, NRF51_UICR, page_size, page_size);
target_add_commands(t, nrf51_cmd_list, "nRF51"); target_add_commands(t, nrf51_cmd_list, "nRF51");

View File

@ -113,10 +113,8 @@ const struct command_s samd_cmd_list[] = {
#define SAMD_DSU_ADDRESS (SAMD_DSU_EXT_ACCESS + 0x4) #define SAMD_DSU_ADDRESS (SAMD_DSU_EXT_ACCESS + 0x4)
#define SAMD_DSU_LENGTH (SAMD_DSU_EXT_ACCESS + 0x8) #define SAMD_DSU_LENGTH (SAMD_DSU_EXT_ACCESS + 0x8)
#define SAMD_DSU_DID (SAMD_DSU_EXT_ACCESS + 0x018) #define SAMD_DSU_DID (SAMD_DSU_EXT_ACCESS + 0x018)
#define SAMD_DSU_PID(n) (SAMD_DSU + 0x1FE0 + \ #define SAMD_DSU_PID (SAMD_DSU + 0x1000)
(0x4 * (n % 4)) - (0x10 * (n / 4))) #define SAMD_DSU_CID (SAMD_DSU + 0x1010)
#define SAMD_DSU_CID(n) (SAMD_DSU + 0x1FF0 + \
(0x4 * (n % 4)))
/* Control and Status Register (CTRLSTAT) */ /* Control and Status Register (CTRLSTAT) */
#define SAMD_CTRL_CHIP_ERASE (1 << 4) #define SAMD_CTRL_CHIP_ERASE (1 << 4)
@ -221,35 +219,6 @@ static const struct samd_part samd_l22_parts[] = {
{0xFF, 0, 0, 0} {0xFF, 0, 0, 0}
}; };
/**
* Reads the SAM D20 Peripheral ID
*/
uint64_t samd_read_pid(target *t)
{
uint64_t pid = 0;
uint8_t i, j;
/* Five PID registers to read LSB first */
for (i = 0, j = 0; i < 5; i++, j += 8)
pid |= (target_mem_read32(t, SAMD_DSU_PID(i)) & 0xFF) << j;
return pid;
}
/**
* Reads the SAM D20 Component ID
*/
uint32_t samd_read_cid(target *t)
{
uint64_t cid = 0;
uint8_t i, j;
/* Four CID registers to read LSB first */
for (i = 0, j = 0; i < 4; i++, j += 8)
cid |= (target_mem_read32(t, SAMD_DSU_CID(i)) & 0xFF) << j;
return cid;
}
/** /**
* Overloads the default cortexm reset function with a version that * Overloads the default cortexm reset function with a version that
* removes the target from extended reset where required. * removes the target from extended reset where required.
@ -474,8 +443,9 @@ static void samd_add_flash(target *t, uint32_t addr, size_t length)
char variant_string[60]; char variant_string[60];
bool samd_probe(target *t) bool samd_probe(target *t)
{ {
uint32_t cid = samd_read_cid(t); ADIv5_AP_t *ap = cortexm_ap(t);
uint32_t pid = samd_read_pid(t); uint32_t cid = adiv5_ap_read_pidr(ap, SAMD_DSU_CID);
uint32_t pid = adiv5_ap_read_pidr(ap, SAMD_DSU_PID);
/* Check the ARM Coresight Component and Perhiperal IDs */ /* Check the ARM Coresight Component and Perhiperal IDs */
if ((cid != SAMD_CID_VALUE) || if ((cid != SAMD_CID_VALUE) ||

View File

@ -169,11 +169,8 @@ const struct command_s samx5x_protected_cmd_list[] = {
#define SAMX5X_DSU_LENGTH (SAMX5X_DSU_EXT_ACCESS + 0x08) #define SAMX5X_DSU_LENGTH (SAMX5X_DSU_EXT_ACCESS + 0x08)
#define SAMX5X_DSU_DATA (SAMX5X_DSU_EXT_ACCESS + 0x0C) #define SAMX5X_DSU_DATA (SAMX5X_DSU_EXT_ACCESS + 0x0C)
#define SAMX5X_DSU_DID (SAMX5X_DSU_EXT_ACCESS + 0x18) #define SAMX5X_DSU_DID (SAMX5X_DSU_EXT_ACCESS + 0x18)
#define SAMX5X_DSU_PID(n) (SAMX5X_DSU + 0x1FE0 + \ #define SAMX5X_DSU_PID (SAMX5X_DSU + 0x1000)
(0x4 * (n % 4)) - \ #define SAMX5X_DSU_CID (SAMX5X_DSU + 0x1010)
(0x10 * (n / 4)))
#define SAMX5X_DSU_CID(n) (SAMX5X_DSU + 0x1FF0 + \
(0x4 * (n % 4)))
/* Control and Status Register (CTRLSTAT) */ /* Control and Status Register (CTRLSTAT) */
#define SAMX5X_CTRL_CHIP_ERASE (1 << 4) #define SAMX5X_CTRL_CHIP_ERASE (1 << 4)
@ -219,23 +216,6 @@ const struct command_s samx5x_protected_cmd_list[] = {
/* Component ID */ /* Component ID */
#define SAMX5X_CID_VALUE 0xB105100D #define SAMX5X_CID_VALUE 0xB105100D
/**
* Reads the SAM D5x/E5x Peripheral ID
*
* (Reuses the SAM D1x/2x implementation as it is identical)
*/
extern uint64_t samd_read_pid(target *t);
#define samx5x_read_pid samd_read_pid
/**
* Reads the SAM D5x/E5x Component ID
*
* (Reuses the SAM D1x/2x implementation as it is identical)
*/
extern uint32_t samd_read_cid(target *t);
#define samx5x_read_cid samd_read_cid
/** /**
* Overloads the default cortexm reset function with a version that * Overloads the default cortexm reset function with a version that
* removes the target from extended reset where required. * removes the target from extended reset where required.
@ -367,8 +347,9 @@ static void samx5x_add_flash(target *t, uint32_t addr, size_t length,
char variant_string[60]; char variant_string[60];
bool samx5x_probe(target *t) bool samx5x_probe(target *t)
{ {
uint32_t cid = samx5x_read_cid(t); ADIv5_AP_t *ap = cortexm_ap(t);
uint32_t pid = samx5x_read_pid(t); uint32_t cid = adiv5_ap_read_pidr(ap, SAMX5X_DSU_CID);
uint32_t pid = adiv5_ap_read_pidr(ap, SAMX5X_DSU_PID);
/* Check the ARM Coresight Component and Perhiperal IDs */ /* Check the ARM Coresight Component and Perhiperal IDs */
if ((cid != SAMX5X_CID_VALUE) || if ((cid != SAMX5X_CID_VALUE) ||

View File

@ -159,31 +159,31 @@ static void stm32f4_add_flash(target *t,
char *stm32f4_get_chip_name(uint32_t idcode) char *stm32f4_get_chip_name(uint32_t idcode)
{ {
switch(idcode){ switch(idcode){
case ID_STM32F40X: case ID_STM32F40X: /* F40XxE/G */
return "STM32F40x"; return "STM32F40x";
case ID_STM32F42X: /* 427/437 */ case ID_STM32F42X: /* F42XxG/I */
return "STM32F42x"; return "STM32F42x";
case ID_STM32F46X: /* 469/479 */ case ID_STM32F46X: /* 469/479 xG/I*/
return "STM32F47x"; return "STM32F47x";
case ID_STM32F20X: /* F205 */ case ID_STM32F20X: /* F205 xB/C/E/G*/
return "STM32F2"; return "STM32F2";
case ID_STM32F446: /* F446 */ case ID_STM32F446: /* F446 xC/E*/
return "STM32F446"; return "STM32F446";
case ID_STM32F401C: /* F401 B/C RM0368 Rev.3 */ case ID_STM32F401C: /* F401 B/C RM0368 Rev.3 */
return "STM32F401C"; return "STM32F401C";
case ID_STM32F411: /* F411 RM0383 Rev.4 */ case ID_STM32F411: /* F411 xC/E RM0383 Rev.4 */
return "STM32F411"; return "STM32F411";
case ID_STM32F412: /* F412 RM0402 Rev.4, 256 kB Ram */ case ID_STM32F412: /* F412 xG/I RM0402 Rev.4, 256 kB Ram */
return "STM32F412"; return "STM32F412";
case ID_STM32F401E: /* F401 D/E RM0368 Rev.3 */ case ID_STM32F401E: /* F401 D/E RM0368 Rev.3 */
return "STM32F401E"; return "STM32F401E";
case ID_STM32F413: /* F413 RM0430 Rev.2, 320 kB Ram, 1.5 MB flash. */ case ID_STM32F413: /* F413xG/H RM0430 Rev.2, 320 kB Ram, 1.5 MB flash. */
return "STM32F413"; return "STM32F413";
case ID_STM32F74X: /* F74x RM0385 Rev.4 */ case ID_STM32F74X: /* F74XxG/I RM0385 Rev.4 */
return "STM32F74x"; return "STM32F74x";
case ID_STM32F76X: /* F76x F77x RM0410 */ case ID_STM32F76X: /* F76XxE/G F77x RM0410 */
return "STM32F76x"; return "STM32F76x";
case ID_STM32F72X: /* F72x F73x RM0431 */ case ID_STM32F72X: /* F72/3xC/E RM0431 */
return "STM32F72x"; return "STM32F72x";
default: default:
return NULL; return NULL;
@ -245,7 +245,7 @@ static bool stm32f4_attach(target *t)
bool has_ccmram = false; bool has_ccmram = false;
bool is_f7 = false; bool is_f7 = false;
bool large_sectors = false; bool large_sectors = false;
uint32_t flashsize_base = F4_FLASHSIZE; uint16_t max_flashsize;
if (!cortexm_attach(t)) if (!cortexm_attach(t))
return false; return false;
@ -253,50 +253,53 @@ static bool stm32f4_attach(target *t)
switch(t->idcode) { switch(t->idcode) {
case ID_STM32F40X: case ID_STM32F40X:
has_ccmram = true; has_ccmram = true;
max_flashsize = 1024;
break; break;
case ID_STM32F42X: /* 427/437 */ case ID_STM32F42X: /* 427/437 */
has_ccmram = true; has_ccmram = true;
dual_bank = true; dual_bank = true;
max_flashsize = 2048;
break; break;
case ID_STM32F46X: /* 469/479 */ case ID_STM32F46X: /* 469/479 */
has_ccmram = true; has_ccmram = true;
dual_bank = true; dual_bank = true;
break; max_flashsize = 512;
case ID_STM32F20X: /* F205 */
break;
case ID_STM32F446: /* F446 */
break; break;
case ID_STM32F401C: /* F401 B/C RM0368 Rev.3 */ case ID_STM32F401C: /* F401 B/C RM0368 Rev.3 */
break; max_flashsize = 256;
case ID_STM32F411: /* F411 RM0383 Rev.4 */
break;
case ID_STM32F412: /* F412 RM0402 Rev.4, 256 kB Ram */
break; break;
case ID_STM32F401E: /* F401 D/E RM0368 Rev.3 */ case ID_STM32F401E: /* F401 D/E RM0368 Rev.3 */
case ID_STM32F411: /* F411 RM0383 Rev.4 */
case ID_STM32F446: /* F446 */
max_flashsize = 512;
break;
case ID_STM32F20X: /* F205xB/C/E/G */
case ID_STM32F412: /* F412xE/G RM0402 Rev.4, 256 kB Ram */
max_flashsize = 1024;
break; break;
case ID_STM32F413: /* F413 RM0430 Rev.2, 320 kB Ram, 1.5 MB flash. */ case ID_STM32F413: /* F413 RM0430 Rev.2, 320 kB Ram, 1.5 MB flash. */
max_flashsize = 1536;
break; break;
case ID_STM32F74X: /* F74x RM0385 Rev.4 */ case ID_STM32F74X: /* F74x RM0385 Rev.4 */
is_f7 = true; is_f7 = true;
large_sectors = true; large_sectors = true;
flashsize_base = F7_FLASHSIZE; max_flashsize = 1024;
break; break;
case ID_STM32F76X: /* F76x F77x RM0410 */ case ID_STM32F76X: /* F76x F77x RM0410 */
is_f7 = true; is_f7 = true;
dual_bank = true; dual_bank = true;
large_sectors = true; large_sectors = true;
flashsize_base = F7_FLASHSIZE; max_flashsize = 2048;
break; break;
case ID_STM32F72X: /* F72x F73x RM0431 */ case ID_STM32F72X: /* F72x F73x RM0431 */
is_f7 = true; is_f7 = true;
flashsize_base = F72X_FLASHSIZE; max_flashsize = 512;
break; break;
default: default:
return false; return false;
} }
bool use_dual_bank = false; bool use_dual_bank = false;
target_mem_map_free(t); target_mem_map_free(t);
uint32_t flashsize = target_mem_read32(t, flashsize_base) & 0xffff;
if (is_f7) { if (is_f7) {
t->target_storage = target_mem_read32(t, DBGMCU_CR); t->target_storage = target_mem_read32(t, DBGMCU_CR);
target_mem_write32(t, DBGMCU_CR, DBG_SLEEP); target_mem_write32(t, DBGMCU_CR, DBG_SLEEP);
@ -314,7 +317,7 @@ static bool stm32f4_attach(target *t)
target_add_ram(t, 0x20000000, 0x50000); /* 320 k RAM */ target_add_ram(t, 0x20000000, 0x50000); /* 320 k RAM */
if (dual_bank) { if (dual_bank) {
use_dual_bank = true; use_dual_bank = true;
if (flashsize < 0x800) { if (max_flashsize < 0x800) {
/* Check Dual-bank on 1 Mbyte Flash memory devices*/ /* Check Dual-bank on 1 Mbyte Flash memory devices*/
uint32_t optcr; uint32_t optcr;
optcr = target_mem_read32(t, FLASH_OPTCR); optcr = target_mem_read32(t, FLASH_OPTCR);
@ -325,11 +328,11 @@ static bool stm32f4_attach(target *t)
int split = 0; int split = 0;
uint32_t banksize; uint32_t banksize;
if (use_dual_bank) { if (use_dual_bank) {
banksize = flashsize << 9; /* flash split on two sectors. */ banksize = max_flashsize << 9; /* flash split on two sectors. */
split = (flashsize == 0x400) ? 8 : 12; split = (max_flashsize == 0x400) ? 8 : 12;
} }
else else
banksize = flashsize << 10; banksize = max_flashsize << 10;
if (large_sectors) { if (large_sectors) {
uint32_t remains = banksize - 0x40000; uint32_t remains = banksize - 0x40000;
/* 256 k in small sectors.*/ /* 256 k in small sectors.*/
@ -345,11 +348,6 @@ static bool stm32f4_attach(target *t)
remains = banksize - 0x20000; /* 128 k in small sectors.*/ remains = banksize - 0x20000; /* 128 k in small sectors.*/
if (is_f7) { if (is_f7) {
stm32f4_add_flash(t, ITCM_BASE, 0x10000, 0x4000, 0, split); stm32f4_add_flash(t, ITCM_BASE, 0x10000, 0x4000, 0, split);
if (banksize > 0x10000) {
/* STM32F730 has only 64 kiB flash! */
stm32f4_add_flash(t, 0x0210000, 0x10000, 0x10000, 4, split);
stm32f4_add_flash(t, 0x0220000, remains, 0x20000, 5, split);
}
} }
stm32f4_add_flash(t, 0x8000000, 0x10000, 0x4000, 0, split); stm32f4_add_flash(t, 0x8000000, 0x10000, 0x4000, 0, split);
if (banksize > 0x10000) { if (banksize > 0x10000) {

View File

@ -213,14 +213,8 @@ static bool stm32h7_attach(target *t)
target_add_ram(t, 0x38000000, 0x01000); /* AHB SRAM4, 32 k */ target_add_ram(t, 0x38000000, 0x01000); /* AHB SRAM4, 32 k */
/* Add the flash to memory map. */ /* Add the flash to memory map. */
uint32_t flashsize = target_mem_read32(t, FLASH_SIZE_REG);
flashsize &= 0xffff;
if (flashsize == 128) { /* H750 has only 128 kByte!*/
stm32h7_add_flash(t, 0x8000000, FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE);
} else {
stm32h7_add_flash(t, 0x8000000, 0x100000, FLASH_SECTOR_SIZE); stm32h7_add_flash(t, 0x8000000, 0x100000, FLASH_SECTOR_SIZE);
stm32h7_add_flash(t, 0x8100000, 0x100000, FLASH_SECTOR_SIZE); stm32h7_add_flash(t, 0x8100000, 0x100000, FLASH_SECTOR_SIZE);
}
return true; return true;
} }

View File

@ -401,6 +401,15 @@ enum target_halt_reason target_halt_poll(target *t, target_addr *watch)
void target_halt_resume(target *t, bool step) { t->halt_resume(t, step); } void target_halt_resume(target *t, bool step) { t->halt_resume(t, step); }
/* Command line for semihosting get_cmdline */
void target_set_cmdline(target *t, char *cmdline) {
uint32_t len_dst;
len_dst = sizeof(t->cmdline)-1;
strncpy(t->cmdline, cmdline, len_dst -1);
t->cmdline[strlen(t->cmdline)]='\0';
DEBUG("cmdline: >%s<\n", t->cmdline);
}
/* Break-/watchpoint functions */ /* Break-/watchpoint functions */
int target_breakwatch_set(target *t, int target_breakwatch_set(target *t,
enum target_breakwatch type, target_addr addr, size_t len) enum target_breakwatch type, target_addr addr, size_t len)

View File

@ -72,6 +72,8 @@ struct breakwatch {
uint32_t reserved[4]; /* for use by the implementing driver */ uint32_t reserved[4]; /* for use by the implementing driver */
}; };
#define MAX_CMDLINE 81
struct target_s { struct target_s {
bool attached; bool attached;
struct target_controller *tc; struct target_controller *tc;
@ -118,6 +120,7 @@ struct target_s {
/* Other stuff */ /* Other stuff */
const char *driver; const char *driver;
const char *core; const char *core;
char cmdline[MAX_CMDLINE];
struct target_command_s *commands; struct target_command_s *commands;
struct target_s *next; struct target_s *next;