Merge commit '1a83bc68920ad20ad044e9110c3599e3ac1f76c0' into sam-update
# Conflicts: # src/command.c
This commit is contained in:
commit
81cfa0a380
@ -60,6 +60,7 @@ static bool cmd_target_power(target *t, int argc, const char **argv);
|
|||||||
#ifdef PLATFORM_HAS_TRACESWO
|
#ifdef PLATFORM_HAS_TRACESWO
|
||||||
static bool cmd_traceswo(target *t, int argc, const char **argv);
|
static bool cmd_traceswo(target *t, int argc, const char **argv);
|
||||||
#endif
|
#endif
|
||||||
|
static bool cmd_heapinfo(target *t, int argc, const char **argv);
|
||||||
#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED)
|
#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED)
|
||||||
static bool cmd_debug_bmp(target *t, int argc, const char **argv);
|
static bool cmd_debug_bmp(target *t, int argc, const char **argv);
|
||||||
#endif
|
#endif
|
||||||
@ -94,6 +95,7 @@ const struct command_s cmd_list[] = {
|
|||||||
{"traceswo", (cmd_handler)cmd_traceswo, "Start trace capture, Manchester mode" },
|
{"traceswo", (cmd_handler)cmd_traceswo, "Start trace capture, Manchester mode" },
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
{"heapinfo", (cmd_handler)cmd_heapinfo, "Set semihosting heapinfo" },
|
||||||
#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED)
|
#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED)
|
||||||
{"debug_bmp", (cmd_handler)cmd_debug_bmp, "Output BMP \"debug\" strings to the second vcom: (enable|disable)"},
|
{"debug_bmp", (cmd_handler)cmd_debug_bmp, "Output BMP \"debug\" strings to the second vcom: (enable|disable)"},
|
||||||
#endif
|
#endif
|
||||||
@ -479,3 +481,18 @@ bool cmd_serial(target *t, int argc, char **argv)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool cmd_heapinfo(target *t, int argc, const char **argv)
|
||||||
|
{
|
||||||
|
if (t == NULL) gdb_out("not attached\n");
|
||||||
|
else if (argc == 5) {
|
||||||
|
target_addr heap_base = strtoul(argv[1], NULL, 16);
|
||||||
|
target_addr heap_limit = strtoul(argv[2], NULL, 16);
|
||||||
|
target_addr stack_base = strtoul(argv[3], NULL, 16);
|
||||||
|
target_addr stack_limit = strtoul(argv[4], NULL, 16);
|
||||||
|
gdb_outf("heapinfo heap_base: %p heap_limit: %p stack_base: %p stack_limit: %p\n",
|
||||||
|
heap_base, heap_limit, stack_base, stack_limit);
|
||||||
|
target_set_heapinfo(t, heap_base, heap_limit, stack_base, stack_limit);
|
||||||
|
} else gdb_outf("heapinfo heap_base heap_limit stack_base stack_limit\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -81,6 +81,8 @@ 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);
|
void target_set_cmdline(target *t, char *cmdline);
|
||||||
|
void target_set_heapinfo(target *t, target_addr heap_base, target_addr heap_limit,
|
||||||
|
target_addr stack_base, target_addr stack_limit);
|
||||||
|
|
||||||
/* Break-/watchpoint functions */
|
/* Break-/watchpoint functions */
|
||||||
enum target_breakwatch {
|
enum target_breakwatch {
|
||||||
@ -97,11 +99,12 @@ int target_breakwatch_clear(target *t, enum target_breakwatch, target_addr, size
|
|||||||
void target_command_help(target *t);
|
void target_command_help(target *t);
|
||||||
int target_command(target *t, int argc, const char *argv[]);
|
int target_command(target *t, int argc, const char *argv[]);
|
||||||
|
|
||||||
|
/* keep target_errno in sync with errno values in gdb/include/gdb/fileio.h */
|
||||||
enum target_errno {
|
enum target_errno {
|
||||||
TARGET_EPERM = 1,
|
TARGET_EPERM = 1,
|
||||||
TARGET_ENOENT = 2,
|
TARGET_ENOENT = 2,
|
||||||
TARGET_EINTR = 4,
|
TARGET_EINTR = 4,
|
||||||
|
TARGET_EIO = 5,
|
||||||
TARGET_EBADF = 9,
|
TARGET_EBADF = 9,
|
||||||
TARGET_EACCES = 13,
|
TARGET_EACCES = 13,
|
||||||
TARGET_EFAULT = 14,
|
TARGET_EFAULT = 14,
|
||||||
@ -111,13 +114,15 @@ enum target_errno {
|
|||||||
TARGET_ENOTDIR = 20,
|
TARGET_ENOTDIR = 20,
|
||||||
TARGET_EISDIR = 21,
|
TARGET_EISDIR = 21,
|
||||||
TARGET_EINVAL = 22,
|
TARGET_EINVAL = 22,
|
||||||
TARGET_EMFILE = 24,
|
|
||||||
TARGET_ENFILE = 23,
|
TARGET_ENFILE = 23,
|
||||||
|
TARGET_EMFILE = 24,
|
||||||
TARGET_EFBIG = 27,
|
TARGET_EFBIG = 27,
|
||||||
TARGET_ENOSPC = 28,
|
TARGET_ENOSPC = 28,
|
||||||
TARGET_ESPIPE = 29,
|
TARGET_ESPIPE = 29,
|
||||||
TARGET_EROFS = 30,
|
TARGET_EROFS = 30,
|
||||||
TARGET_ENAMETOOLONG = 36,
|
TARGET_ENOSYS = 88,
|
||||||
|
TARGET_ENAMETOOLONG = 91,
|
||||||
|
TARGET_EUNKNOWN = 9999,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum target_open_flags {
|
enum target_open_flags {
|
||||||
|
@ -153,11 +153,37 @@ static inline int platform_hwversion(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use newlib provided integer only stdio functions */
|
/*
|
||||||
#define sscanf siscanf
|
* Use newlib provided integer only stdio functions
|
||||||
#define sprintf siprintf
|
*/
|
||||||
#define vasprintf vasiprintf
|
|
||||||
#define snprintf sniprintf
|
|
||||||
|
|
||||||
|
/* sscanf */
|
||||||
|
#ifdef sscanf
|
||||||
|
#undef sscanf
|
||||||
|
#define sscanf siscanf
|
||||||
|
#else
|
||||||
|
#define sscanf siscanf
|
||||||
|
#endif
|
||||||
|
/* sprintf */
|
||||||
|
#ifdef sprintf
|
||||||
|
#undef sprintf
|
||||||
|
#define sprintf siprintf
|
||||||
|
#else
|
||||||
|
#define sprintf siprintf
|
||||||
|
#endif
|
||||||
|
/* vasprintf */
|
||||||
|
#ifdef vasprintf
|
||||||
|
#undef vasprintf
|
||||||
|
#define vasprintf vasiprintf
|
||||||
|
#else
|
||||||
|
#define vasprintf vasiprintf
|
||||||
|
#endif
|
||||||
|
/* snprintf */
|
||||||
|
#ifdef snprintf
|
||||||
|
#undef snprintf
|
||||||
|
#define snprintf sniprintf
|
||||||
|
#else
|
||||||
|
#define snprintf sniprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -153,11 +153,38 @@ static inline int platform_hwversion(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use newlib provided integer only stdio functions */
|
/*
|
||||||
|
* Use newlib provided integer only stdio functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* sscanf */
|
||||||
|
#ifdef sscanf
|
||||||
|
#undef sscanf
|
||||||
#define sscanf siscanf
|
#define sscanf siscanf
|
||||||
|
#else
|
||||||
|
#define sscanf siscanf
|
||||||
|
#endif
|
||||||
|
/* sprintf */
|
||||||
|
#ifdef sprintf
|
||||||
|
#undef sprintf
|
||||||
#define sprintf siprintf
|
#define sprintf siprintf
|
||||||
|
#else
|
||||||
|
#define sprintf siprintf
|
||||||
|
#endif
|
||||||
|
/* vasprintf */
|
||||||
|
#ifdef vasprintf
|
||||||
|
#undef vasprintf
|
||||||
#define vasprintf vasiprintf
|
#define vasprintf vasiprintf
|
||||||
|
#else
|
||||||
|
#define vasprintf vasiprintf
|
||||||
|
#endif
|
||||||
|
/* snprintf */
|
||||||
|
#ifdef snprintf
|
||||||
|
#undef snprintf
|
||||||
#define snprintf sniprintf
|
#define snprintf sniprintf
|
||||||
|
#else
|
||||||
|
#define snprintf sniprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -178,10 +178,37 @@ int usbuart_debug_write(const char *buf, size_t len);
|
|||||||
#define SET_IDLE_STATE(state) {gpio_set_val(LED_PORT, LED_IDLE_RUN, state);}
|
#define SET_IDLE_STATE(state) {gpio_set_val(LED_PORT, LED_IDLE_RUN, state);}
|
||||||
#define SET_ERROR_STATE(state) {gpio_set_val(LED_PORT, LED_ERROR, state);}
|
#define SET_ERROR_STATE(state) {gpio_set_val(LED_PORT, LED_ERROR, state);}
|
||||||
|
|
||||||
/* Use newlib provided integer only stdio functions */
|
/*
|
||||||
|
* Use newlib provided integer only stdio functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* sscanf */
|
||||||
|
#ifdef sscanf
|
||||||
|
#undef sscanf
|
||||||
#define sscanf siscanf
|
#define sscanf siscanf
|
||||||
|
#else
|
||||||
|
#define sscanf siscanf
|
||||||
|
#endif
|
||||||
|
/* sprintf */
|
||||||
|
#ifdef sprintf
|
||||||
|
#undef sprintf
|
||||||
#define sprintf siprintf
|
#define sprintf siprintf
|
||||||
#define snprintf sniprintf
|
#else
|
||||||
|
#define sprintf siprintf
|
||||||
|
#endif
|
||||||
|
/* vasprintf */
|
||||||
|
#ifdef vasprintf
|
||||||
|
#undef vasprintf
|
||||||
#define vasprintf vasiprintf
|
#define vasprintf vasiprintf
|
||||||
|
#else
|
||||||
|
#define vasprintf vasiprintf
|
||||||
|
#endif
|
||||||
|
/* snprintf */
|
||||||
|
#ifdef snprintf
|
||||||
|
#undef snprintf
|
||||||
|
#define snprintf sniprintf
|
||||||
|
#else
|
||||||
|
#define snprintf sniprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -148,11 +148,39 @@ extern uint16_t led_idle_run;
|
|||||||
|
|
||||||
extern uint32_t detect_rev(void);
|
extern uint32_t detect_rev(void);
|
||||||
|
|
||||||
/* Use newlib provided integer only stdio functions */
|
/*
|
||||||
|
* Use newlib provided integer only stdio functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* sscanf */
|
||||||
|
#ifdef sscanf
|
||||||
|
#undef sscanf
|
||||||
#define sscanf siscanf
|
#define sscanf siscanf
|
||||||
|
#else
|
||||||
|
#define sscanf siscanf
|
||||||
|
#endif
|
||||||
|
/* sprintf */
|
||||||
|
#ifdef sprintf
|
||||||
|
#undef sprintf
|
||||||
#define sprintf siprintf
|
#define sprintf siprintf
|
||||||
|
#else
|
||||||
|
#define sprintf siprintf
|
||||||
|
#endif
|
||||||
|
/* vasprintf */
|
||||||
|
#ifdef vasprintf
|
||||||
|
#undef vasprintf
|
||||||
#define vasprintf vasiprintf
|
#define vasprintf vasiprintf
|
||||||
|
#else
|
||||||
|
#define vasprintf vasiprintf
|
||||||
|
#endif
|
||||||
|
/* snprintf */
|
||||||
|
#ifdef snprintf
|
||||||
|
#undef snprintf
|
||||||
#define snprintf sniprintf
|
#define snprintf sniprintf
|
||||||
|
#else
|
||||||
|
#define snprintf sniprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -154,11 +154,38 @@ extern void set_idle_state(int state);
|
|||||||
|
|
||||||
extern uint8_t detect_rev(void);
|
extern uint8_t detect_rev(void);
|
||||||
|
|
||||||
/* Use newlib provided integer only stdio functions */
|
/*
|
||||||
|
* Use newlib provided integer only stdio functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* sscanf */
|
||||||
|
#ifdef sscanf
|
||||||
|
#undef sscanf
|
||||||
#define sscanf siscanf
|
#define sscanf siscanf
|
||||||
|
#else
|
||||||
|
#define sscanf siscanf
|
||||||
|
#endif
|
||||||
|
/* sprintf */
|
||||||
|
#ifdef sprintf
|
||||||
|
#undef sprintf
|
||||||
#define sprintf siprintf
|
#define sprintf siprintf
|
||||||
|
#else
|
||||||
|
#define sprintf siprintf
|
||||||
|
#endif
|
||||||
|
/* vasprintf */
|
||||||
|
#ifdef vasprintf
|
||||||
|
#undef vasprintf
|
||||||
#define vasprintf vasiprintf
|
#define vasprintf vasiprintf
|
||||||
|
#else
|
||||||
|
#define vasprintf vasiprintf
|
||||||
|
#endif
|
||||||
|
/* snprintf */
|
||||||
|
#ifdef snprintf
|
||||||
|
#undef snprintf
|
||||||
#define snprintf sniprintf
|
#define snprintf sniprintf
|
||||||
|
#else
|
||||||
|
#define snprintf sniprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1110,12 +1110,12 @@ static int cortexm_hostio_request(target *t)
|
|||||||
break;
|
break;
|
||||||
case SYS_READ: /* read */
|
case SYS_READ: /* read */
|
||||||
ret = tc_read(t, params[0] - 1, params[1], params[2]);
|
ret = tc_read(t, params[0] - 1, params[1], params[2]);
|
||||||
if (ret > 0)
|
if (ret >= 0)
|
||||||
ret = params[2] - ret;
|
ret = params[2] - ret;
|
||||||
break;
|
break;
|
||||||
case SYS_WRITE: /* write */
|
case SYS_WRITE: /* write */
|
||||||
ret = tc_write(t, params[0] - 1, params[1], params[2]);
|
ret = tc_write(t, params[0] - 1, params[1], params[2]);
|
||||||
if (ret > 0)
|
if (ret >= 0)
|
||||||
ret = params[2] - ret;
|
ret = params[2] - ret;
|
||||||
break;
|
break;
|
||||||
case SYS_WRITEC: /* writec */
|
case SYS_WRITEC: /* writec */
|
||||||
@ -1141,17 +1141,19 @@ static int cortexm_hostio_request(target *t)
|
|||||||
ret = tc_isatty(t, params[0] - 1);
|
ret = tc_isatty(t, params[0] - 1);
|
||||||
break;
|
break;
|
||||||
case SYS_SEEK: /* lseek */
|
case SYS_SEEK: /* lseek */
|
||||||
ret = tc_lseek(t, params[0] - 1, params[1], TARGET_SEEK_SET);
|
if (tc_lseek(t, params[0] - 1, params[1], TARGET_SEEK_SET) == (long)params[1]) ret = 0;
|
||||||
|
else ret = -1;
|
||||||
break;
|
break;
|
||||||
case SYS_RENAME:/* rename */
|
case SYS_RENAME:/* rename */
|
||||||
ret = tc_rename(t, params[0] - 1, params[1] + 1,
|
ret = tc_rename(t, params[0], params[1] + 1,
|
||||||
params[2], params[3] + 1);
|
params[2], params[3] + 1);
|
||||||
break;
|
break;
|
||||||
case SYS_REMOVE:/* unlink */
|
case SYS_REMOVE:/* unlink */
|
||||||
ret = tc_unlink(t, params[0] - 1, params[1] + 1);
|
ret = tc_unlink(t, params[0], params[1] + 1);
|
||||||
break;
|
break;
|
||||||
case SYS_SYSTEM:/* system */
|
case SYS_SYSTEM:/* system */
|
||||||
ret = tc_system(t, params[0] - 1, params[1] + 1);
|
/* before use first enable system calls with the following gdb command: 'set remote system-call-allowed 1' */
|
||||||
|
ret = tc_system(t, params[0], params[1] + 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYS_FLEN:
|
case SYS_FLEN:
|
||||||
@ -1180,27 +1182,39 @@ static int cortexm_hostio_request(target *t)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SYS_TIME: { /* gettimeofday */
|
case SYS_CLOCK: /* clock */
|
||||||
|
case SYS_TIME: { /* time */
|
||||||
|
/* use same code for SYS_CLOCK and SYS_TIME, more compact */
|
||||||
ret = -1;
|
ret = -1;
|
||||||
uint32_t fio_timeval[3]; /* same size as fio_timeval in gdb/include/gdb/fileio.h */
|
struct __attribute__((packed, aligned(4))) {
|
||||||
//DEBUG("SYS_TIME fio_timeval addr %p\n", fio_timeval);
|
uint32_t ftv_sec;
|
||||||
|
uint64_t ftv_usec;
|
||||||
|
} fio_timeval;
|
||||||
|
//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_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);
|
void (*saved_mem_write)(target *t, target_addr dest, const void *src, size_t len);
|
||||||
saved_mem_read = t->mem_read;
|
saved_mem_read = t->mem_read;
|
||||||
saved_mem_write = t->mem_write;
|
saved_mem_write = t->mem_write;
|
||||||
t->mem_read = probe_mem_read;
|
t->mem_read = probe_mem_read;
|
||||||
t->mem_write = probe_mem_write;
|
t->mem_write = probe_mem_write;
|
||||||
int rc = tc_gettimeofday(t, (target_addr) fio_timeval, (target_addr) NULL); /* write gettimeofday() result in fio_timeval[] */
|
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_read = saved_mem_read;
|
||||||
t->mem_write = saved_mem_write;
|
t->mem_write = saved_mem_write;
|
||||||
if (rc) break; /* tc_gettimeofday() failed */
|
if (rc) break; /* tc_gettimeofday() failed */
|
||||||
uint32_t ftv_sec = fio_timeval[0]; /* time in seconds, first field in fio_timeval */
|
uint32_t sec = __builtin_bswap32(fio_timeval.ftv_sec); /* convert from bigendian to target order */
|
||||||
ret = __builtin_bswap32(ftv_sec); /* convert from bigendian to target order */
|
uint64_t usec = __builtin_bswap64(fio_timeval.ftv_usec);
|
||||||
|
if (syscall == SYS_TIME) { /* SYS_TIME: time in seconds */
|
||||||
|
ret = sec;
|
||||||
|
} else { /* SYS_CLOCK: time in hundredths of seconds */
|
||||||
|
uint64_t csec64 = (sec * 1000000ull + usec)/10000ull;
|
||||||
|
uint32_t csec = csec64 & 0x7fffffff;
|
||||||
|
ret = csec;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SYS_READC: { /* readc */
|
case SYS_READC: { /* readc */
|
||||||
uint8_t ch;
|
uint8_t ch='?';
|
||||||
//DEBUG("SYS_READC ch addr %p\n", &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_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);
|
void (*saved_mem_write)(target *t, target_addr dest, const void *src, size_t len);
|
||||||
@ -1208,7 +1222,7 @@ static int cortexm_hostio_request(target *t)
|
|||||||
saved_mem_write = t->mem_write;
|
saved_mem_write = t->mem_write;
|
||||||
t->mem_read = probe_mem_read;
|
t->mem_read = probe_mem_read;
|
||||||
t->mem_write = probe_mem_write;
|
t->mem_write = probe_mem_write;
|
||||||
int rc = tc_read(t, params[0] - 1, (target_addr) &ch, 1); /* read a character in ch */
|
int rc = tc_read(t, STDIN_FILENO, (target_addr) &ch, 1); /* read a character in ch */
|
||||||
t->mem_read = saved_mem_read;
|
t->mem_read = saved_mem_read;
|
||||||
t->mem_write = saved_mem_write;
|
t->mem_write = saved_mem_write;
|
||||||
if (rc == 1) ret = ch;
|
if (rc == 1) ret = ch;
|
||||||
@ -1223,7 +1237,11 @@ static int cortexm_hostio_request(target *t)
|
|||||||
case SYS_EXIT: /* _exit() */
|
case SYS_EXIT: /* _exit() */
|
||||||
tc_printf(t, "_exit(0x%x)\n", params[0]);
|
tc_printf(t, "_exit(0x%x)\n", params[0]);
|
||||||
target_halt_resume(t, 1);
|
target_halt_resume(t, 1);
|
||||||
ret = 0;
|
break;
|
||||||
|
|
||||||
|
case SYS_EXIT_EXTENDED: /* _exit() */
|
||||||
|
tc_printf(t, "_exit(0x%x%08x)\n", params[1], params[0]); /* exit() with 64bit exit value */
|
||||||
|
target_halt_resume(t, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYS_GET_CMDLINE: { /* get_cmdline */
|
case SYS_GET_CMDLINE: { /* get_cmdline */
|
||||||
@ -1240,13 +1258,59 @@ static int cortexm_hostio_request(target *t)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not implemented yet:
|
case SYS_ISERROR: { /* iserror */
|
||||||
|
int errorNo = params[0];
|
||||||
|
ret = (errorNo == TARGET_EPERM) ||
|
||||||
|
(errorNo == TARGET_ENOENT) ||
|
||||||
|
(errorNo == TARGET_EINTR) ||
|
||||||
|
(errorNo == TARGET_EIO) ||
|
||||||
|
(errorNo == TARGET_EBADF) ||
|
||||||
|
(errorNo == TARGET_EACCES) ||
|
||||||
|
(errorNo == TARGET_EFAULT) ||
|
||||||
|
(errorNo == TARGET_EBUSY) ||
|
||||||
|
(errorNo == TARGET_EEXIST) ||
|
||||||
|
(errorNo == TARGET_ENODEV) ||
|
||||||
|
(errorNo == TARGET_ENOTDIR) ||
|
||||||
|
(errorNo == TARGET_EISDIR) ||
|
||||||
|
(errorNo == TARGET_EINVAL) ||
|
||||||
|
(errorNo == TARGET_ENFILE) ||
|
||||||
|
(errorNo == TARGET_EMFILE) ||
|
||||||
|
(errorNo == TARGET_EFBIG) ||
|
||||||
|
(errorNo == TARGET_ENOSPC) ||
|
||||||
|
(errorNo == TARGET_ESPIPE) ||
|
||||||
|
(errorNo == TARGET_EROFS) ||
|
||||||
|
(errorNo == TARGET_ENOSYS) ||
|
||||||
|
(errorNo == TARGET_ENAMETOOLONG) ||
|
||||||
|
(errorNo == TARGET_EUNKNOWN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SYS_HEAPINFO: /* heapinfo */
|
case SYS_HEAPINFO: /* heapinfo */
|
||||||
case SYS_CLOCK: /* clock */
|
target_mem_write(t, arm_regs[1], &t->heapinfo, sizeof(t->heapinfo)); /* See newlib/libc/sys/arm/crt0.S */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYS_TMPNAM: { /* tmpnam */
|
||||||
|
/* Given a target identifier between 0 and 255, returns a temporary name.
|
||||||
|
* FIXME: add directory prefix */
|
||||||
|
target_addr buf_ptr = params[0];
|
||||||
|
int target_id = params[1];
|
||||||
|
int buf_size = params[2];
|
||||||
|
char fnam[]="tempXX.tmp";
|
||||||
|
ret = -1;
|
||||||
|
if (buf_ptr == 0) break;
|
||||||
|
if (buf_size <= 0) break;
|
||||||
|
if ((target_id < 0) || (target_id > 255)) break; /* target id out of range */
|
||||||
|
fnam[5]='A'+(target_id&0xF); /* create filename */
|
||||||
|
fnam[4]='A'+(target_id>>4&0xF);
|
||||||
|
if (strlen(fnam)+1>(uint32_t)buf_size) break; /* target buffer too small */
|
||||||
|
if(target_mem_write(t, buf_ptr, fnam, strlen(fnam)+1)) break; /* copy filename to target */
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not implemented yet:
|
||||||
case SYS_ELAPSED: /* elapsed */
|
case SYS_ELAPSED: /* elapsed */
|
||||||
case SYS_ISERROR: /* iserror */
|
|
||||||
case SYS_TICKFREQ: /* tickfreq */
|
case SYS_TICKFREQ: /* tickfreq */
|
||||||
case SYS_TMPNAM: /* tmpnam */
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -584,7 +584,7 @@ static efm32_device_t const * efm32_get_device(size_t index)
|
|||||||
/**
|
/**
|
||||||
* Probe
|
* Probe
|
||||||
*/
|
*/
|
||||||
char variant_string[60];
|
static char efm32_variant_string[60];
|
||||||
bool efm32_probe(target *t)
|
bool efm32_probe(target *t)
|
||||||
{
|
{
|
||||||
uint8_t di_version = 1;
|
uint8_t di_version = 1;
|
||||||
@ -636,13 +636,13 @@ bool efm32_probe(target *t)
|
|||||||
uint32_t ram_size = ram_kib * 0x400;
|
uint32_t ram_size = ram_kib * 0x400;
|
||||||
uint32_t flash_page_size = device->flash_page_size;
|
uint32_t flash_page_size = device->flash_page_size;
|
||||||
|
|
||||||
snprintf(variant_string, sizeof(variant_string), "%c\b%c\b%s %d F%d %s",
|
snprintf(efm32_variant_string, sizeof(efm32_variant_string), "%c\b%c\b%s %d F%d %s",
|
||||||
di_version + 48, (uint8_t)device_index + 32,
|
di_version + 48, (uint8_t)device_index + 32,
|
||||||
device->name, part_number, flash_kib, device->description);
|
device->name, part_number, flash_kib, device->description);
|
||||||
|
|
||||||
/* Setup Target */
|
/* Setup Target */
|
||||||
t->target_options |= CORTEXM_TOPT_INHIBIT_SRST;
|
t->target_options |= CORTEXM_TOPT_INHIBIT_SRST;
|
||||||
t->driver = variant_string;
|
t->driver = efm32_variant_string;
|
||||||
tc_printf(t, "flash size %d page size %d\n", flash_size, flash_page_size);
|
tc_printf(t, "flash size %d page size %d\n", flash_size, flash_page_size);
|
||||||
target_add_ram (t, SRAM_BASE, ram_size);
|
target_add_ram (t, SRAM_BASE, ram_size);
|
||||||
efm32_add_flash(t, 0x00000000, flash_size, flash_page_size);
|
efm32_add_flash(t, 0x00000000, flash_size, flash_page_size);
|
||||||
|
@ -380,6 +380,7 @@ struct samd_descr samd_parse_device_id(uint32_t did)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: samd.series = 11; break;
|
case 3: samd.series = 11; break;
|
||||||
|
default: samd.series = 0; break;
|
||||||
}
|
}
|
||||||
/* Revision */
|
/* Revision */
|
||||||
samd.revision = 'A' + revision;
|
samd.revision = 'A' + revision;
|
||||||
@ -440,7 +441,7 @@ static void samd_add_flash(target *t, uint32_t addr, size_t length)
|
|||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
char variant_string[60];
|
static char samd_variant_string[60];
|
||||||
bool samd_probe(target *t)
|
bool samd_probe(target *t)
|
||||||
{
|
{
|
||||||
ADIv5_AP_t *ap = cortexm_ap(t);
|
ADIv5_AP_t *ap = cortexm_ap(t);
|
||||||
@ -467,14 +468,14 @@ bool samd_probe(target *t)
|
|||||||
|
|
||||||
/* Part String */
|
/* Part String */
|
||||||
if (protected) {
|
if (protected) {
|
||||||
sprintf(variant_string,
|
sprintf(samd_variant_string,
|
||||||
"Atmel SAM%c%d%c%d%c%s (rev %c) (PROT=1)",
|
"Atmel SAM%c%d%c%d%c%s (rev %c) (PROT=1)",
|
||||||
samd.family,
|
samd.family,
|
||||||
samd.series, samd.pin, samd.mem,
|
samd.series, samd.pin, samd.mem,
|
||||||
samd.variant,
|
samd.variant,
|
||||||
samd.package, samd.revision);
|
samd.package, samd.revision);
|
||||||
} else {
|
} else {
|
||||||
sprintf(variant_string,
|
sprintf(samd_variant_string,
|
||||||
"Atmel SAM%c%d%c%d%c%s (rev %c)",
|
"Atmel SAM%c%d%c%d%c%s (rev %c)",
|
||||||
samd.family,
|
samd.family,
|
||||||
samd.series, samd.pin, samd.mem,
|
samd.series, samd.pin, samd.mem,
|
||||||
@ -483,7 +484,7 @@ bool samd_probe(target *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Setup Target */
|
/* Setup Target */
|
||||||
t->driver = variant_string;
|
t->driver = samd_variant_string;
|
||||||
t->reset = samd_reset;
|
t->reset = samd_reset;
|
||||||
|
|
||||||
if (samd.series == 20 && samd.revision == 'B') {
|
if (samd.series == 20 && samd.revision == 'B') {
|
||||||
|
@ -344,7 +344,7 @@ static void samx5x_add_flash(target *t, uint32_t addr, size_t length,
|
|||||||
target_add_flash(t, f);
|
target_add_flash(t, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
char variant_string[60];
|
static char samx5x_variant_string[60];
|
||||||
bool samx5x_probe(target *t)
|
bool samx5x_probe(target *t)
|
||||||
{
|
{
|
||||||
ADIv5_AP_t *ap = cortexm_ap(t);
|
ADIv5_AP_t *ap = cortexm_ap(t);
|
||||||
@ -371,19 +371,19 @@ bool samx5x_probe(target *t)
|
|||||||
|
|
||||||
/* Part String */
|
/* Part String */
|
||||||
if (protected) {
|
if (protected) {
|
||||||
snprintf(variant_string, sizeof(variant_string),
|
snprintf(samx5x_variant_string, sizeof(samx5x_variant_string),
|
||||||
"Microchip SAM%c%d%c%dA (rev %c) (PROT=1)",
|
"Microchip SAM%c%d%c%dA (rev %c) (PROT=1)",
|
||||||
samx5x.series_letter, samx5x.series_number,
|
samx5x.series_letter, samx5x.series_number,
|
||||||
samx5x.pin, samx5x.mem, samx5x.revision);
|
samx5x.pin, samx5x.mem, samx5x.revision);
|
||||||
} else {
|
} else {
|
||||||
snprintf(variant_string, sizeof(variant_string),
|
snprintf(samx5x_variant_string, sizeof(samx5x_variant_string),
|
||||||
"Microchip SAM%c%d%c%dA (rev %c)",
|
"Microchip SAM%c%d%c%dA (rev %c)",
|
||||||
samx5x.series_letter, samx5x.series_number,
|
samx5x.series_letter, samx5x.series_number,
|
||||||
samx5x.pin, samx5x.mem, samx5x.revision);
|
samx5x.pin, samx5x.mem, samx5x.revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup Target */
|
/* Setup Target */
|
||||||
t->driver = variant_string;
|
t->driver = samx5x_variant_string;
|
||||||
t->reset = samx5x_reset;
|
t->reset = samx5x_reset;
|
||||||
|
|
||||||
if (protected) {
|
if (protected) {
|
||||||
|
@ -83,9 +83,14 @@ static int stm32f4_flash_write(struct target_flash *f,
|
|||||||
|
|
||||||
#define FLASH_OPTCR_OPTLOCK (1 << 0)
|
#define FLASH_OPTCR_OPTLOCK (1 << 0)
|
||||||
#define FLASH_OPTCR_OPTSTRT (1 << 1)
|
#define FLASH_OPTCR_OPTSTRT (1 << 1)
|
||||||
|
#define FLASH_OPTCR_WDG_SW (1 << 5)
|
||||||
#define FLASH_OPTCR_nDBANK (1 << 29)
|
#define FLASH_OPTCR_nDBANK (1 << 29)
|
||||||
#define FLASH_OPTCR_DB1M (1 << 30)
|
#define FLASH_OPTCR_DB1M (1 << 30)
|
||||||
|
|
||||||
|
#define FLASH_OPTCR_PROT_MASK 0xff00
|
||||||
|
#define FLASH_OPTCR_PROT_L0 0xaa00
|
||||||
|
#define FLASH_OPTCR_PROT_L1 0xbb00
|
||||||
|
|
||||||
#define KEY1 0x45670123
|
#define KEY1 0x45670123
|
||||||
#define KEY2 0xCDEF89AB
|
#define KEY2 0xCDEF89AB
|
||||||
|
|
||||||
@ -561,6 +566,19 @@ static bool optcr_mask(target *t, uint32_t *val)
|
|||||||
|
|
||||||
static bool stm32f4_option_write(target *t, uint32_t *val, int count)
|
static bool stm32f4_option_write(target *t, uint32_t *val, int count)
|
||||||
{
|
{
|
||||||
|
val[0] &= ~(FLASH_OPTCR_OPTSTRT | FLASH_OPTCR_OPTLOCK);
|
||||||
|
uint32_t optcr = target_mem_read32(t, FLASH_OPTCR);
|
||||||
|
/* Check if watchdog and read protection is active.
|
||||||
|
* When both are active, watchdog will trigger when erasing
|
||||||
|
* to get back to level 0 protection and operation aborts!
|
||||||
|
*/
|
||||||
|
if (!(optcr & FLASH_OPTCR_WDG_SW) &&
|
||||||
|
((optcr & FLASH_OPTCR_PROT_MASK) != FLASH_OPTCR_PROT_L0) &&
|
||||||
|
((val[0] & FLASH_OPTCR_PROT_MASK) != FLASH_OPTCR_PROT_L1)) {
|
||||||
|
val[0] &= ~FLASH_OPTCR_PROT_MASK;
|
||||||
|
val[0] |= FLASH_OPTCR_PROT_L1;
|
||||||
|
tc_printf(t, "Keeping L1 protection while HW Watchdog fuse is set!\n");
|
||||||
|
}
|
||||||
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY1);
|
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY1);
|
||||||
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY2);
|
target_mem_write32(t, FLASH_OPTKEYR, OPTKEY2);
|
||||||
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
|
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
|
||||||
@ -578,11 +596,22 @@ static bool stm32f4_option_write(target *t, uint32_t *val, int count)
|
|||||||
|
|
||||||
target_mem_write32(t, FLASH_OPTCR, val[0]);
|
target_mem_write32(t, FLASH_OPTCR, val[0]);
|
||||||
target_mem_write32(t, FLASH_OPTCR, val[0] | FLASH_OPTCR_OPTSTRT);
|
target_mem_write32(t, FLASH_OPTCR, val[0] | FLASH_OPTCR_OPTSTRT);
|
||||||
|
const char spinner[] = "|/-\\";
|
||||||
|
int spinindex = 0;
|
||||||
|
tc_printf(t, "Erasing flash... This may take a few seconds. ");
|
||||||
/* Read FLASH_SR to poll for BSY bit */
|
/* Read FLASH_SR to poll for BSY bit */
|
||||||
while(target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
|
while(target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY) {
|
||||||
if(target_check_error(t))
|
platform_delay(100);
|
||||||
|
tc_printf(t, "\b%c", spinner[spinindex++ % 4]);
|
||||||
|
if(target_check_error(t)) {
|
||||||
|
tc_printf(t, " failed\n");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tc_printf(t, "\n");
|
||||||
target_mem_write32(t, FLASH_OPTCR, FLASH_OPTCR_OPTLOCK);
|
target_mem_write32(t, FLASH_OPTCR, FLASH_OPTCR_OPTLOCK);
|
||||||
|
/* Reset target to reload option bits.*/
|
||||||
|
target_reset(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,7 +648,7 @@ static bool stm32f4_option_write_default(target *t)
|
|||||||
|
|
||||||
static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
|
static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
uint32_t start = 0x1FFFC000, val[3];
|
uint32_t val[3];
|
||||||
int count = 0, readcount = 1;
|
int count = 0, readcount = 1;
|
||||||
|
|
||||||
switch (t->idcode) {
|
switch (t->idcode) {
|
||||||
@ -628,8 +657,6 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
|
|||||||
/* fall through.*/
|
/* fall through.*/
|
||||||
case ID_STM32F74X:
|
case ID_STM32F74X:
|
||||||
case ID_STM32F76X:
|
case ID_STM32F76X:
|
||||||
/* F7 Devices have option bytes at 0x1FFF0000. */
|
|
||||||
start = 0x1FFF0000;
|
|
||||||
readcount++;
|
readcount++;
|
||||||
break;
|
break;
|
||||||
case ID_STM32F42X:
|
case ID_STM32F42X:
|
||||||
@ -637,17 +664,17 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
|
|||||||
readcount++;
|
readcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((argc == 2) && !strcmp(argv[1], "erase")) {
|
if ((argc == 2) && !strncasecmp(argv[1], "erase", 1)) {
|
||||||
stm32f4_option_write_default(t);
|
stm32f4_option_write_default(t);
|
||||||
}
|
}
|
||||||
else if ((argc > 1) && !strcmp(argv[1], "write")) {
|
else if ((argc > 2) && !strncasecmp(argv[1], "write", 1)) {
|
||||||
val[0] = strtoul(argv[2], NULL, 0);
|
val[0] = strtoul(argv[2], NULL, 0);
|
||||||
count++;
|
count++;
|
||||||
if (argc > 2) {
|
if (argc > 3) {
|
||||||
val[1] = strtoul(argv[3], NULL, 0);
|
val[1] = strtoul(argv[3], NULL, 0);
|
||||||
count ++;
|
count ++;
|
||||||
}
|
}
|
||||||
if (argc > 3) {
|
if (argc > 4) {
|
||||||
val[2] = strtoul(argv[4], NULL, 0);
|
val[2] = strtoul(argv[4], NULL, 0);
|
||||||
count ++;
|
count ++;
|
||||||
}
|
}
|
||||||
@ -665,22 +692,11 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
|
|||||||
tc_printf(t, "\n");
|
tc_printf(t, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
val[0] = (target_mem_read32(t, start + 8) & 0xffff) << 16;
|
val[0] = target_mem_read32(t, FLASH_OPTCR);
|
||||||
val[0] |= (target_mem_read32(t, start ) & 0xffff);
|
if (readcount > 1)
|
||||||
if (readcount > 1) {
|
val[1] = target_mem_read32(t, FLASH_OPTCR + 4);
|
||||||
if (start == 0x1FFFC000) /* F4 */ {
|
if (readcount > 2)
|
||||||
val[1] = target_mem_read32(t, 0x1ffec008);
|
val[2] = target_mem_read32(t, FLASH_OPTCR + 8);
|
||||||
val[1] &= 0xffff;
|
|
||||||
val[1] <<= 16;
|
|
||||||
} else {
|
|
||||||
val[1] = (target_mem_read32(t, start + 0x18) & 0xffff) << 16;
|
|
||||||
val[1] |= (target_mem_read32(t, start + 0x10) & 0xffff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (readcount > 2) {
|
|
||||||
val[2] = (target_mem_read32(t, start + 0x28) & 0xffff) << 16;
|
|
||||||
val[2] |= (target_mem_read32(t, start + 0x20) & 0xffff);
|
|
||||||
}
|
|
||||||
optcr_mask(t, val);
|
optcr_mask(t, val);
|
||||||
tc_printf(t, "OPTCR: 0x%08X ", val[0]);
|
tc_printf(t, "OPTCR: 0x%08X ", val[0]);
|
||||||
if (readcount > 1)
|
if (readcount > 1)
|
||||||
|
@ -410,6 +410,16 @@ void target_set_cmdline(target *t, char *cmdline) {
|
|||||||
DEBUG("cmdline: >%s<\n", t->cmdline);
|
DEBUG("cmdline: >%s<\n", t->cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set heapinfo for semihosting */
|
||||||
|
void target_set_heapinfo(target *t, target_addr heap_base, target_addr heap_limit,
|
||||||
|
target_addr stack_base, target_addr stack_limit) {
|
||||||
|
if (t == NULL) return;
|
||||||
|
t->heapinfo[0] = heap_base;
|
||||||
|
t->heapinfo[1] = heap_limit;
|
||||||
|
t->heapinfo[2] = stack_base;
|
||||||
|
t->heapinfo[3] = stack_limit;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
|
@ -121,6 +121,7 @@ struct target_s {
|
|||||||
const char *driver;
|
const char *driver;
|
||||||
const char *core;
|
const char *core;
|
||||||
char cmdline[MAX_CMDLINE];
|
char cmdline[MAX_CMDLINE];
|
||||||
|
target_addr heapinfo[4];
|
||||||
struct target_command_s *commands;
|
struct target_command_s *commands;
|
||||||
|
|
||||||
struct target_s *next;
|
struct target_s *next;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user