Merge commit '1a83bc68920ad20ad044e9110c3599e3ac1f76c0' into sam-update

# Conflicts:
#	src/command.c
This commit is contained in:
Jason Kotzin 2022-08-09 17:22:19 -07:00
commit 81cfa0a380
14 changed files with 317 additions and 68 deletions

View File

@ -60,6 +60,7 @@ static bool cmd_target_power(target *t, int argc, const char **argv);
#ifdef PLATFORM_HAS_TRACESWO
static bool cmd_traceswo(target *t, int argc, const char **argv);
#endif
static bool cmd_heapinfo(target *t, int argc, const char **argv);
#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED)
static bool cmd_debug_bmp(target *t, int argc, const char **argv);
#endif
@ -94,6 +95,7 @@ const struct command_s cmd_list[] = {
{"traceswo", (cmd_handler)cmd_traceswo, "Start trace capture, Manchester mode" },
#endif
#endif
{"heapinfo", (cmd_handler)cmd_heapinfo, "Set semihosting heapinfo" },
#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)"},
#endif
@ -479,3 +481,18 @@ bool cmd_serial(target *t, int argc, char **argv)
return true;
}
#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;
}

View File

@ -81,6 +81,8 @@ void target_halt_request(target *t);
enum target_halt_reason target_halt_poll(target *t, target_addr *watch);
void target_halt_resume(target *t, bool step);
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 */
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);
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 {
TARGET_EPERM = 1,
TARGET_ENOENT = 2,
TARGET_EINTR = 4,
TARGET_EIO = 5,
TARGET_EBADF = 9,
TARGET_EACCES = 13,
TARGET_EFAULT = 14,
@ -111,13 +114,15 @@ enum target_errno {
TARGET_ENOTDIR = 20,
TARGET_EISDIR = 21,
TARGET_EINVAL = 22,
TARGET_EMFILE = 24,
TARGET_ENFILE = 23,
TARGET_EMFILE = 24,
TARGET_EFBIG = 27,
TARGET_ENOSPC = 28,
TARGET_ESPIPE = 29,
TARGET_EROFS = 30,
TARGET_ENAMETOOLONG = 36,
TARGET_ENOSYS = 88,
TARGET_ENAMETOOLONG = 91,
TARGET_EUNKNOWN = 9999,
};
enum target_open_flags {

View File

@ -153,11 +153,37 @@ static inline int platform_hwversion(void)
return 0;
}
/* Use newlib provided integer only stdio functions */
#define sscanf siscanf
#define sprintf siprintf
#define vasprintf vasiprintf
#define snprintf sniprintf
/*
* Use newlib provided integer only stdio functions
*/
/* 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

View File

@ -153,11 +153,38 @@ static inline int platform_hwversion(void)
return 0;
}
/* Use newlib provided integer only stdio functions */
/*
* Use newlib provided integer only stdio functions
*/
/* 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

View File

@ -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_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
#else
#define sscanf siscanf
#endif
/* sprintf */
#ifdef sprintf
#undef sprintf
#define sprintf siprintf
#define snprintf sniprintf
#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

View File

@ -148,11 +148,39 @@ extern uint16_t led_idle_run;
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
#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

View File

@ -154,11 +154,38 @@ extern void set_idle_state(int state);
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
#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

View File

@ -1110,12 +1110,12 @@ static int cortexm_hostio_request(target *t)
break;
case SYS_READ: /* read */
ret = tc_read(t, params[0] - 1, params[1], params[2]);
if (ret > 0)
if (ret >= 0)
ret = params[2] - ret;
break;
case SYS_WRITE: /* write */
ret = tc_write(t, params[0] - 1, params[1], params[2]);
if (ret > 0)
if (ret >= 0)
ret = params[2] - ret;
break;
case SYS_WRITEC: /* writec */
@ -1141,17 +1141,19 @@ static int cortexm_hostio_request(target *t)
ret = tc_isatty(t, params[0] - 1);
break;
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;
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);
break;
case SYS_REMOVE:/* unlink */
ret = tc_unlink(t, params[0] - 1, params[1] + 1);
ret = tc_unlink(t, params[0], params[1] + 1);
break;
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;
case SYS_FLEN:
@ -1180,27 +1182,39 @@ static int cortexm_hostio_request(target *t)
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;
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);
struct __attribute__((packed, aligned(4))) {
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_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[] */
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 */
uint32_t sec = __builtin_bswap32(fio_timeval.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;
}
case SYS_READC: { /* readc */
uint8_t ch;
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);
@ -1208,7 +1222,7 @@ static int cortexm_hostio_request(target *t)
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 */
int rc = tc_read(t, STDIN_FILENO, (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;
@ -1223,7 +1237,11 @@ static int cortexm_hostio_request(target *t)
case SYS_EXIT: /* _exit() */
tc_printf(t, "_exit(0x%x)\n", params[0]);
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;
case SYS_GET_CMDLINE: { /* get_cmdline */
@ -1240,13 +1258,59 @@ static int cortexm_hostio_request(target *t)
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_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_ISERROR: /* iserror */
case SYS_TICKFREQ: /* tickfreq */
case SYS_TMPNAM: /* tmpnam */
ret = -1;
break;

View File

@ -584,7 +584,7 @@ static efm32_device_t const * efm32_get_device(size_t index)
/**
* Probe
*/
char variant_string[60];
static char efm32_variant_string[60];
bool efm32_probe(target *t)
{
uint8_t di_version = 1;
@ -636,13 +636,13 @@ bool efm32_probe(target *t)
uint32_t ram_size = ram_kib * 0x400;
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,
device->name, part_number, flash_kib, device->description);
/* Setup Target */
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);
target_add_ram (t, SRAM_BASE, ram_size);
efm32_add_flash(t, 0x00000000, flash_size, flash_page_size);

View File

@ -380,6 +380,7 @@ struct samd_descr samd_parse_device_id(uint32_t did)
}
break;
case 3: samd.series = 11; break;
default: samd.series = 0; break;
}
/* 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);
}
char variant_string[60];
static char samd_variant_string[60];
bool samd_probe(target *t)
{
ADIv5_AP_t *ap = cortexm_ap(t);
@ -467,14 +468,14 @@ bool samd_probe(target *t)
/* Part String */
if (protected) {
sprintf(variant_string,
sprintf(samd_variant_string,
"Atmel SAM%c%d%c%d%c%s (rev %c) (PROT=1)",
samd.family,
samd.series, samd.pin, samd.mem,
samd.variant,
samd.package, samd.revision);
} else {
sprintf(variant_string,
sprintf(samd_variant_string,
"Atmel SAM%c%d%c%d%c%s (rev %c)",
samd.family,
samd.series, samd.pin, samd.mem,
@ -483,7 +484,7 @@ bool samd_probe(target *t)
}
/* Setup Target */
t->driver = variant_string;
t->driver = samd_variant_string;
t->reset = samd_reset;
if (samd.series == 20 && samd.revision == 'B') {

View File

@ -344,7 +344,7 @@ static void samx5x_add_flash(target *t, uint32_t addr, size_t length,
target_add_flash(t, f);
}
char variant_string[60];
static char samx5x_variant_string[60];
bool samx5x_probe(target *t)
{
ADIv5_AP_t *ap = cortexm_ap(t);
@ -371,19 +371,19 @@ bool samx5x_probe(target *t)
/* Part String */
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)",
samx5x.series_letter, samx5x.series_number,
samx5x.pin, samx5x.mem, samx5x.revision);
} else {
snprintf(variant_string, sizeof(variant_string),
snprintf(samx5x_variant_string, sizeof(samx5x_variant_string),
"Microchip SAM%c%d%c%dA (rev %c)",
samx5x.series_letter, samx5x.series_number,
samx5x.pin, samx5x.mem, samx5x.revision);
}
/* Setup Target */
t->driver = variant_string;
t->driver = samx5x_variant_string;
t->reset = samx5x_reset;
if (protected) {

View File

@ -83,9 +83,14 @@ static int stm32f4_flash_write(struct target_flash *f,
#define FLASH_OPTCR_OPTLOCK (1 << 0)
#define FLASH_OPTCR_OPTSTRT (1 << 1)
#define FLASH_OPTCR_WDG_SW (1 << 5)
#define FLASH_OPTCR_nDBANK (1 << 29)
#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 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)
{
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, OPTKEY2);
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] | 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 */
while(target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
if(target_check_error(t))
while(target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY) {
platform_delay(100);
tc_printf(t, "\b%c", spinner[spinindex++ % 4]);
if(target_check_error(t)) {
tc_printf(t, " failed\n");
return false;
}
}
tc_printf(t, "\n");
target_mem_write32(t, FLASH_OPTCR, FLASH_OPTCR_OPTLOCK);
/* Reset target to reload option bits.*/
target_reset(t);
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[])
{
uint32_t start = 0x1FFFC000, val[3];
uint32_t val[3];
int count = 0, readcount = 1;
switch (t->idcode) {
@ -628,8 +657,6 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
/* fall through.*/
case ID_STM32F74X:
case ID_STM32F76X:
/* F7 Devices have option bytes at 0x1FFF0000. */
start = 0x1FFF0000;
readcount++;
break;
case ID_STM32F42X:
@ -637,17 +664,17 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
readcount++;
}
if ((argc == 2) && !strcmp(argv[1], "erase")) {
if ((argc == 2) && !strncasecmp(argv[1], "erase", 1)) {
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);
count++;
if (argc > 2) {
if (argc > 3) {
val[1] = strtoul(argv[3], NULL, 0);
count ++;
}
if (argc > 3) {
if (argc > 4) {
val[2] = strtoul(argv[4], NULL, 0);
count ++;
}
@ -665,22 +692,11 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[])
tc_printf(t, "\n");
}
val[0] = (target_mem_read32(t, start + 8) & 0xffff) << 16;
val[0] |= (target_mem_read32(t, start ) & 0xffff);
if (readcount > 1) {
if (start == 0x1FFFC000) /* F4 */ {
val[1] = target_mem_read32(t, 0x1ffec008);
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);
}
val[0] = target_mem_read32(t, FLASH_OPTCR);
if (readcount > 1)
val[1] = target_mem_read32(t, FLASH_OPTCR + 4);
if (readcount > 2)
val[2] = target_mem_read32(t, FLASH_OPTCR + 8);
optcr_mask(t, val);
tc_printf(t, "OPTCR: 0x%08X ", val[0]);
if (readcount > 1)

View File

@ -410,6 +410,16 @@ void target_set_cmdline(target *t, char *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 */
int target_breakwatch_set(target *t,
enum target_breakwatch type, target_addr addr, size_t len)

View File

@ -121,6 +121,7 @@ struct target_s {
const char *driver;
const char *core;
char cmdline[MAX_CMDLINE];
target_addr heapinfo[4];
struct target_command_s *commands;
struct target_s *next;