From 966f360515e387fb79223a75986aa7b79878268a Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sun, 25 Sep 2016 15:55:30 -0700 Subject: [PATCH 1/2] debug: Use semihosting if available or output via usbuart. --- src/exception.c | 1 + src/platforms/native/Makefile.inc | 8 +++- src/platforms/native/platform.c | 61 +++++++++++++++++++++++++++++++ src/platforms/native/platform.h | 4 +- src/platforms/stm32/usbuart.c | 39 ++++---------------- 5 files changed, 78 insertions(+), 35 deletions(-) diff --git a/src/exception.c b/src/exception.c index 3d43f99..0242cec 100644 --- a/src/exception.c +++ b/src/exception.c @@ -26,6 +26,7 @@ struct exception *innermost_exception; void raise_exception(uint32_t type, const char *msg) { struct exception *e; + DEBUG("Exception: %s\n", msg); for (e = innermost_exception; e; e = e->outer) { if (e->mask & type) { e->type = type; diff --git a/src/platforms/native/Makefile.inc b/src/platforms/native/Makefile.inc index ba08e71..63b24de 100644 --- a/src/platforms/native/Makefile.inc +++ b/src/platforms/native/Makefile.inc @@ -7,11 +7,17 @@ CFLAGS += -Istm32/include -mcpu=cortex-m3 -mthumb \ -Iplatforms/stm32 LDFLAGS_BOOT := $(LDFLAGS) -lopencm3_stm32f1 -Wl,--defsym,_stack=0x20005000 \ - -Wl,-T,platforms/stm32/blackmagic.ld -nostartfiles -lc -lnosys \ + -Wl,-T,platforms/stm32/blackmagic.ld -nostartfiles -lc \ -Wl,-Map=mapfile -mthumb -mcpu=cortex-m3 -Wl,-gc-sections \ -L../libopencm3/lib LDFLAGS = $(LDFLAGS_BOOT) -Wl,-Ttext=0x8002000 +ifeq ($(ENABLE_DEBUG), 1) +LDFLAGS += --specs=rdimon.specs +else +LDFLAGS += --specs=nosys.specs +endif + VPATH += platforms/stm32 SRC += cdcacm.c \ diff --git a/src/platforms/native/platform.c b/src/platforms/native/platform.c index c8c3edf..8e0cde3 100644 --- a/src/platforms/native/platform.c +++ b/src/platforms/native/platform.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -89,6 +90,12 @@ int platform_hwversion(void) void platform_init(void) { + SCS_DEMCR |= SCS_DEMCR_VC_MON_EN; +#ifdef ENABLE_DEBUG + void initialise_monitor_handles(void); + initialise_monitor_handles(); +#endif + rcc_clock_setup_in_hse_8mhz_out_72mhz(); /* Enable peripherals */ @@ -287,3 +294,57 @@ static void setup_vbus_irq(void) exti15_10_isr(); } +#ifdef ENABLE_DEBUG +enum { + RDI_SYS_OPEN = 0x01, + RDI_SYS_WRITE = 0x05, + RDI_SYS_ISTTY = 0x09, +}; + +int rdi_write(int fn, const char *buf, size_t len) +{ + (void)fn; + if (debug_bmp) + return len - usbuart_debug_write(buf, len); + + return 0; +} + +struct ex_frame { + union { + int syscall; + int retval; + }; + const int *params; + uint32_t r2, r3, r12, lr, pc; +}; + +void debug_monitor_handler_c(struct ex_frame *sp) +{ + /* Return to after breakpoint instruction */ + sp->pc += 2; + + switch (sp->syscall) { + case RDI_SYS_OPEN: + sp->retval = 1; + break; + case RDI_SYS_WRITE: + sp->retval = rdi_write(sp->params[0], (void*)sp->params[1], sp->params[2]); + break; + case RDI_SYS_ISTTY: + sp->retval = 1; + break; + default: + sp->retval = -1; + } + +} + +asm(".globl debug_monitor_handler\n" + ".thumb_func\n" + "debug_monitor_handler: \n" + " mov r0, sp\n" + " b debug_monitor_handler_c\n"); + +#endif + diff --git a/src/platforms/native/platform.h b/src/platforms/native/platform.h index 282b767..9062e27 100644 --- a/src/platforms/native/platform.h +++ b/src/platforms/native/platform.h @@ -149,9 +149,9 @@ #ifdef ENABLE_DEBUG extern bool debug_bmp; -void usbuart_debug_outf(const char *fmt, ...); +int usbuart_debug_write(const char *buf, size_t len); -#define DEBUG(...) if (debug_bmp) {usbuart_debug_outf("bmp: ");usbuart_debug_outf(__VA_ARGS__);} +#define DEBUG printf #else #define DEBUG(...) #endif diff --git a/src/platforms/stm32/usbuart.c b/src/platforms/stm32/usbuart.c index 17d02c1..77c959b 100644 --- a/src/platforms/stm32/usbuart.c +++ b/src/platforms/stm32/usbuart.c @@ -193,44 +193,19 @@ void usbuart_usb_out_cb(usbd_device *dev, uint8_t ep) } #ifdef USBUART_DEBUG -#include - -/* Function to output debug data to usbuart port (ttyACM1 on linux) */ -void usbuart_debug_outf(const char *fmt, ...) +int usbuart_debug_write(const char *buf, size_t len) { - va_list ap; - char *buf, *tmp; - - va_start(ap, fmt); - if (vasprintf(&buf, fmt, ap) < 0) - return; - tmp = buf; - while( *tmp != 0 ) - { - if( *tmp == '\n' && *(tmp-1) != '\r' ) - { - /* insert into FIFO */ + for (size_t i = 0; i < len; i++) { + if (buf[i] == '\n') { buf_rx[buf_rx_in++] = '\r'; - - /* wrap out pointer */ - if (buf_rx_in >= FIFO_SIZE) - { - buf_rx_in = 0; - } - } - /* insert into FIFO */ - buf_rx[buf_rx_in++] = *(tmp++); - - /* wrap out pointer */ - if (buf_rx_in >= FIFO_SIZE) - { - buf_rx_in = 0; + buf_rx_in %= FIFO_SIZE; } + buf_rx[buf_rx_in++] = buf[i]; + buf_rx_in %= FIFO_SIZE; } /* enable deferred processing if we put data in the FIFO */ timer_enable_irq(USBUSART_TIM, TIM_DIER_UIE); - free(buf); - va_end(ap); + return len; } #endif From 9a8cef04e016d009da62f278a4e3080e9096592f Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sun, 25 Sep 2016 16:07:01 -0700 Subject: [PATCH 2/2] Clean up debug format strings. --- src/target/adiv5.c | 12 +++++++----- src/target/cortexa.c | 11 ++++++----- src/target/cortexm.c | 4 ++-- src/target/sam3x.c | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 8a38057..d530ecb 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -270,7 +270,8 @@ static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr) /* CIDR preamble sanity check */ if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE) { - DEBUG("0x%X: 0x%X <- does not match preamble (0x%X)\n", addr, cidr, CID_PREAMBLE); + DEBUG("0x%"PRIx32": 0x%"PRIx32" <- does not match preamble (0x%X)\n", + addr, cidr, CID_PREAMBLE); return; } @@ -293,7 +294,8 @@ static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr) * any components by other designers. */ if ((pidr & ~(PIDR_REV_MASK | PIDR_PN_MASK)) != PIDR_ARM_BITS) { - DEBUG("0x%X: 0x%"PRIx64" <- does not match ARM JEP-106\n", addr, pidr); + DEBUG("0x%"PRIx32": 0x%"PRIx64" <- does not match ARM JEP-106\n", + addr, pidr); return; } @@ -305,7 +307,7 @@ static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr) int i; for (i = 0; pidr_pn_bits[i].arch != aa_end; i++) { if (pidr_pn_bits[i].part_number == part_number) { - DEBUG("0x%X: %s - %s %s\n", addr, + DEBUG("0x%"PRIx32": %s - %s %s\n", addr, cidc_debug_strings[cid_class], pidr_pn_bits[i].type, pidr_pn_bits[i].full); @@ -334,7 +336,7 @@ static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr) } } if (pidr_pn_bits[i].arch == aa_end) { - DEBUG("0x%X: %s - Unknown (PIDR = 0x%"PRIx64")\n", addr, + DEBUG("0x%"PRIx32": %s - Unknown (PIDR = 0x%"PRIx64")\n", addr, cidc_debug_strings[cid_class], pidr); } } @@ -377,7 +379,7 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel) ap->csw &= ~ADIV5_AP_CSW_TRINPROG; } - DEBUG(" AP %3d: IDR=%08X CFG=%08X BASE=%08X CSW=%08X\n", + DEBUG(" AP %3d: IDR=%08"PRIx32" CFG=%08"PRIx32" BASE=%08"PRIx32" CSW=%08"PRIx32"\n", apsel, ap->idr, ap->cfg, ap->base, ap->csw); return ap; diff --git a/src/target/cortexa.c b/src/target/cortexa.c index a9c8593..3c7916a 100644 --- a/src/target/cortexa.c +++ b/src/target/cortexa.c @@ -211,7 +211,8 @@ static uint32_t va_to_pa(target *t, uint32_t va) if (par & 1) priv->mmu_fault = true; uint32_t pa = (par & ~0xfff) | (va & 0xfff); - DEBUG("%s: VA = 0x%08X, PAR = 0x%08X, PA = 0x%08X\n", __func__, va, par, pa); + DEBUG("%s: VA = 0x%08"PRIx32", PAR = 0x%08"PRIx32", PA = 0x%08"PRIX32"\n", + __func__, va, par, pa); return pa; } @@ -412,7 +413,7 @@ bool cortexa_attach(target *t) dbgdscr |= DBGDSCR_HDBGEN | DBGDSCR_ITREN; dbgdscr = (dbgdscr & ~DBGDSCR_EXTDCCMODE_MASK) | DBGDSCR_EXTDCCMODE_STALL; apb_write(t, DBGDSCR, dbgdscr); - DEBUG("DBGDSCR = 0x%08x\n", dbgdscr); + DEBUG("DBGDSCR = 0x%08"PRIx32"\n", dbgdscr); target_halt_request(t); tries = 10; @@ -604,7 +605,7 @@ static enum target_halt_reason cortexa_halt_poll(target *t, target_addr *watch) if (!(dbgdscr & DBGDSCR_HALTED)) /* Not halted */ return TARGET_HALT_RUNNING; - DEBUG("%s: DBGDSCR = 0x%08x\n", __func__, dbgdscr); + DEBUG("%s: DBGDSCR = 0x%08"PRIx32"\n", __func__, dbgdscr); /* Reenable DBGITR */ dbgdscr |= DBGDSCR_ITREN; apb_write(t, DBGDSCR, dbgdscr); @@ -631,7 +632,7 @@ void cortexa_halt_resume(target *t, bool step) if (step) { uint32_t addr = priv->reg_cache.r[15]; uint32_t bas = bp_bas(addr, (priv->reg_cache.cpsr & CPSR_THUMB) ? 2 : 4); - DEBUG("step 0x%08x %x\n", addr, bas); + DEBUG("step 0x%08"PRIx32" %"PRIx32"\n", addr, bas); /* Set match any breakpoint */ apb_write(t, DBGBVR(0), priv->reg_cache.r[15] & ~3); apb_write(t, DBGBCR(0), DBGBCR_INST_MISMATCH | bas | @@ -658,7 +659,7 @@ void cortexa_halt_resume(target *t, bool step) do { apb_write(t, DBGDRCR, DBGDRCR_CSE | DBGDRCR_RRQ); dbgdscr = apb_read(t, DBGDSCR); - DEBUG("%s: DBGDSCR = 0x%08x\n", __func__, dbgdscr); + DEBUG("%s: DBGDSCR = 0x%08"PRIx32"\n", __func__, dbgdscr); } while (!(dbgdscr & DBGDSCR_RESTARTED)); } diff --git a/src/target/cortexm.c b/src/target/cortexm.c index d768fde..96c8fde 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -841,8 +841,8 @@ static int cortexm_hostio_request(target *t) uint32_t syscall = arm_regs[0]; int32_t ret = 0; - DEBUG("syscall 0x%x (%x %x %x %x)\n", syscall, - params[0], params[1], params[2], params[3]); + DEBUG("syscall 0"PRIx32"%"PRIx32" (%"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32")\n", + syscall, params[0], params[1], params[2], params[3]); switch (syscall) { case SYS_OPEN:{ /* open */ /* Translate stupid fopen modes to open flags. diff --git a/src/target/sam3x.c b/src/target/sam3x.c index 0f990d0..0a96308 100644 --- a/src/target/sam3x.c +++ b/src/target/sam3x.c @@ -254,7 +254,7 @@ bool sam3x_probe(target *t) static int sam3x_flash_cmd(target *t, uint32_t base, uint8_t cmd, uint16_t arg) { - DEBUG("%s: base = 0x%08x cmd = 0x%02X, arg = 0x%06X\n", + DEBUG("%s: base = 0x%08"PRIx32" cmd = 0x%02X, arg = 0x%06X\n", __func__, base, cmd, arg); target_mem_write32(t, EEFC_FCR(base), EEFC_FCR_FKEY | cmd | ((uint32_t)arg << 8));