static void debug_getthreadinfo(struct gdbcontext *ctx, const char *threadid) { unsigned cpunum; char buf[128], xbuf[256]; size_t i; cpunum = getthreadid(threadid); if (cpunum >= cpu_numcpus()) { debug_send(ctx, "E00"); return; } /* * Send back string of whatever info we want. Since gdb * already fetches and prints the frame info, and fetches this * but doesn't seem to print it, I dunno what to send. */ snprintf(buf, sizeof(buf), "CPU %u", cpunum); /* Code as hex for transmission */ xbuf[0] = 0; for (i=0; buf[i]; i++) { printbyte(xbuf, sizeof(xbuf), (unsigned char)buf[i]); } debug_send(ctx, xbuf); }
static void debug_read_mem(struct gdbcontext *ctx, const char *spec) { uint32_t vaddr, length, i; uint32_t word; uint8_t byte; const char *curptr; char buf[BUFLEN]; vaddr = strtoul(spec, (char **)&curptr, 16); length = strtoul(curptr+1, NULL, 16); buf[0] = 0; for (i=0; i<length && (vaddr+i)%4 != 0; i++) { if (cpudebug_fetch_byte(debug_cpu, vaddr+i, &byte)) { debug_send(ctx, "E03"); return; } printbyte(buf, sizeof(buf), byte); } for (; i<length; i += 4) { if (cpudebug_fetch_word(debug_cpu, vaddr+i, &word)) { debug_send(ctx, "E03"); return; } printword(buf, sizeof(buf), word); } debug_send(ctx, buf); }
void SW_timer_handler() { char buffer[20]; uint8_t timnum; for(timnum=0;timnum<SWTIMERNUM;timnum++) { if(BitTst(SWtimerFlags,BitMsk(timnum))) { switch (timnum) { case 0 : LED_action(LED1,TOGGLE); break; case 1 : therm_read_temperature(buffer); debug_send(buffer); break; case 2 : LED_action(LED2,TOGGLE); break; case 3 : LED_action(LED3,TOGGLE); break; } BitClr(SWtimerFlags,BitMsk(timnum)); } } go_to_sleep(); }
void chipset_new_write_io(unsigned int addr, unsigned int data) { if ((addr & 0xF00) == CHIPSET_IO_PORT_NEW_INTERRUPT) { interrupt_do_write_lword(addr, data); } else if ((addr & 0xF00) == CHIPSET_IO_PORT_NEW_TIMER) { timer_do_write_lword(addr, data); } else if ((addr & 0xF00) == CHIPSET_IO_PORT_NEW_SPI_BASE) { //fprintf(stderr, "SPI write to addr 0x%X: 0x%X\n", addr, data); spi_new_handle_write(addr, data); } else if ((addr & 0xF00) == CHIPSET_IO_PORT_NEW_UART_BASE) { uart_handle_write(addr, data); } else if ((addr & 0xF00) == CHIPSET_IO_PORT_NEW_SOUND_BASE) { audio_io_write(addr, data); } else if((addr & 0xF00) == CHIPSET_IO_PORT_NEW_DEBUG) { //printf("debug send @0x%X 0x%X\n", addr, data); debug_send(data); } else if ((addr & 0xF00) == CHIPSET_IO_PORT_NEW_VGA_BASE) { vga_io_write(addr, data); } /*else if ((addr & 0xF00) == CHIPSET_IO_PORT_NEW_EXTINT) { if ((addr & 0xFC) == 0x4) chipset_int_set(0, !!(data & 1)); else if ((addr & 0xFC) == 0x8) { int i; for (i = 1; i < 8; i++) { if (data & (1 << i)) chipset_int_set(i, 0); } } }*/ }
/** * Print a number to the debug port. * * \param width string maximum length * \param base base number (16 for hex, 10 for decimal etc.) * \param n number value * * \return pointer to the formatted string */ uint8_t *debug_integer(uint8_t width, uint8_t base, int n) { uint8_t buffer[16]; uint8_t i; if (base == 16) { sprintf(buffer, "%X", (unsigned int) n); i = strlen(buffer) + 1; if ((i & 1) == 0) { while (i > 0) { buffer[i] = buffer[i-1]; i--; } buffer[0] = '0'; } } else { sprintf(buffer, "%d", n); } /* if (width > strlen(buffer)) { memmove(&buffer[width-strlen(buffer)], buffer, strlen(buffer)); memset(&buffer, '0', width-strlen(buffer)); }*/ debug_send(buffer, strlen(buffer) ); return buffer; }
static void debug_write_mem(struct gdbcontext *ctx, const char *spec) { uint32_t vaddr, length, i; uint8_t *bytes; const char *curptr; // AAAAAAA,LLL:DDDD // address,len,data vaddr = strtoul(spec, (char **) &curptr, 16); length = strtoul(curptr + 1, (char **)&curptr, 16); // curptr now points to the ':' which // delimits the length from the data // so we advance it a little curptr++; bytes = domalloc(length); for (i=0; i<length; i++) { bytes[i] = hexbyte(curptr, (char **) &curptr); } for (i=0; i<length && (vaddr+i)%4 != 0; i++) { if (cpudebug_store_byte(debug_cpu, vaddr+i, bytes[i])) { debug_send(ctx, "E03"); return; } } for (; i+4<=length; i+=4) { uint32_t word; memcpy(&word, bytes+i, sizeof(uint32_t)); if (cpudebug_store_word(debug_cpu, vaddr+i, ntohl(word))) { debug_send(ctx, "E03"); return; } } for (; i<length; i++) { if (cpudebug_store_byte(debug_cpu, vaddr+i, bytes[i])) { debug_send(ctx, "E03"); return; } } free(bytes); debug_send(ctx, "OK"); }
static void debug_checkthread(struct gdbcontext *ctx, const char *threadid) { unsigned cpunum; cpunum = getthreadid(threadid); if (cpunum >= cpu_numcpus()) { debug_send(ctx, "E00"); return; } if (!cpu_enabled(cpunum)) { debug_send(ctx, "E01"); return; } debug_send(ctx, "OK"); }
void debug_sendf(struct gdbcontext *ctx, const char *fmt, ...) { char buf[1024]; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); debug_send(ctx, buf); }
void chipset_write_io(unsigned int addr, unsigned int data, bool new_map) { unsigned int port = (addr & 0xFFFC)/4; //fprintf(stderr, "write_io %u 0x%X %u\n",port, addr, data); if (new_map) return chipset_new_write_io(addr, data); switch(port) { case CHIPSET_IO_PORT_INTERRUPT_ENABLE: //chipset_int_set(0, data & 1); return; case CHIPSET_IO_PORT_IRQ_ACK_SPI: //chipset_int_set(CHIPSET_INT_NUM_SPI_DONE, 0); return; case CHIPSET_IO_PORT_IRQ_ACK_VGA: //chipset_int_set(CHIPSET_INT_NUM_VGA_VSYNC, 0); return; case CHIPSET_IO_PORT_VGA_WINDOW_X: vga_state.reg.window_x = data & 0x3FF; return; case CHIPSET_IO_PORT_VGA_WINDOW_Y: vga_state.reg.window_y = data & 0x3FF; return; case CHIPSET_IO_PORT_VGA_SPRITE_X: vga_state.reg.sprite_x = data & 0x3FF; return; case CHIPSET_IO_PORT_VGA_SPRITE_Y: vga_state.reg.sprite_y = data & 0x3FF; return; case CHIPSET_IO_PORT_SPI_MEM_COUNTER: spi_state.mem_counter = data & 0x3FF; return; case CHIPSET_IO_PORT_SPI_LINE_SELECT: spi_state.line_select = data & 0x1F; return; case CHIPSET_IO_PORT_SPI_REG: spi_state.reg = data & 0xF; return; case CHIPSET_IO_PORT_DEBUG: debug_send(data); return; default: fprintf(stderr, "Wrote invalid IO-port 0x%X\n", addr); } return; }
static int log_write(struct inode* inode, void* buf, off_t pos, size_t size) { #if DEBUG ((char*) buf) [size] = 0; kprintf(LOG ""); for(char* p = buf; *p; p++) { debug_send(*p); if(*p == '\n' && p[1] != '\0') kprintf(LOG ""); } #endif return size; }
static void debug_register_print(struct gdbcontext *ctx) { uint32_t regs[256]; int i, nregs; char buf[BUFLEN]; cpudebug_getregs(debug_cpu, regs, 256, &nregs); Assert(nregs <= 256); buf[0] = 0; for (i=0; i<nregs; i++) { printword(buf, sizeof(buf), regs[i]); } debug_send(ctx, buf); }
int std_kprintf(const char *fmt, ...) { char buf[1024] = {0}; va_list args; va_start(args, fmt); int out = vsprintf(buf, fmt, args); mutex_lock(&mtx_kprintf); int i; for(i = 0; i < out; i++) debug_send(buf[i], LOG); mutex_unlock(&mtx_kprintf); va_end(args); return out; }
int kprintf(int flags, const char *fmt, ...) { KASSERT(flags < 16); char buf[1024] = {0}; va_list args; va_start(args, fmt); int out = vsprintf(buf, fmt, args); mutex_lock(&mtx_kprintf); int i; for(i = 0; i < out; i++) debug_send(buf[i], flags); mutex_unlock(&mtx_kprintf); va_end(args); return out; }
int main (void) { clock_setup(); //setup the main clock for 168MHz usart_setup(); //setup usart1 for debug messages debug_send("\n\n\n*************************************\n"); debug_send("* Lynx test starting up *\n"); debug_send("* Waveforms *\n"); debug_send("* Joe Roberts *\n"); debug_send("* UROP - Summer 2013 *\n"); debug_send("*************************************\n\n\n"); debug_send("ledpins_setup()\n"); ledpins_setup(); //setup the status led's gpio's debug_send("dac_setup()\n"); dac_setup(); //setup the dac gpio's debug_send("transmit_timer_setup(1)\n"); transmit_timer_setup(1); //setup the transmit timer and its interrupt debug_send("Starting the transmission timer\n"); timer_enable_counter(TIM2); while(1) { usart_wait_recv_ready(USART2); timer_disable_counter(TIM2); timer_set_counter(TIM2, 0); char message = usart_recv_blocking(USART2); debug_send("\nRecieved "); usart_send_blocking(USART2, message); bool done = false; char param; while(!done) { debug_send(": Send your parameter [0-9]\n"); usart_wait_recv_ready(USART2); param = usart_recv_blocking(USART2); if((param>47)&&(param<58)) { done = true; param = param-48; //ASCII to number } else debug_send("\nParameter must be [0-9] - try again\n"); } if(message=='n') n = 1000*param; if(message=='t') { transmit_timer_setup(10*param); timer_enable_counter(TIM2); } if(message=='w') set_waveform(param); } debug_send("We somehow escaped the for ever loop\n"); debug_send("..This is a little sad, there's not much you can do to fix this\n\n\n\n"); debug_send("goodbye, cruel world"); while(1); return 1; }
void cm3_assert_failed() { disable_interrupts(); debug_send("Assertion failed\n"); while(1); }
/* pkt is null-terminated */ void debug_exec(struct gdbcontext *ctx, const char *pkt) { char *cs; /* start of the checksum */ int i; int check = 0, scheck; #ifdef SHOW_PACKETS msg("Got packet %s", pkt); #endif if (pkt[0] != '$') { return; } cs = strchr(pkt, '#'); if (cs == NULL) { return; } *cs = 0; cs++; for (i=1; pkt[i]; i++) { check += pkt[i]; } scheck = strtoul(cs, NULL, 16); if (scheck != check % 256) { write(ctx->myfd, "-", 1); return; } else { write(ctx->myfd, "+", 1); } switch (pkt[1]) { case '!': /* * Enable extended mode -- extended mode is apparently * where gdb can ask to rerun the program. We can't do * that... although it could probably be arranged. * * Reply with "OK" if extended mode is enabled. */ debug_notsupp(ctx); break; case '?': /* Report why the target stopped. */ debug_send_stopinfo(ctx); break; case 'A': /* * Set argv[]. We can't do this, although it might make * sense if we grow support for reloading the kernel. */ debug_notsupp(ctx); break; case 'b': if (pkt[2] == 0) { /* Set serial bit rate; deprecated. */ debug_notsupp(ctx); break; } else if (pkt[2] == 'c') { /* Backward continue - resume executing, backwards */ } else if (pkt[2] == 's') { /* Backward single step - execute one insn backwards */ } else { /* ? */ } debug_notsupp(ctx); break; case 'B': /* Set or clear breakpoint; old, deprecated. */ debug_notsupp(ctx); break; case 'c': /* * Continue. If an address follows the 'c', continue * from that address. debug_restart() does that. */ debug_restart(ctx, pkt + 2); unset_breakcond(); break; case 'C': /* * Continue with signal. A signal number in hex * follows the C; that may be followed with a * semicolon and an address to continue at. We don't * have signals per se; in theory we could fake up * some mapping of signals to hardware traps, but that * would be difficult to arrange and not serve much * purpose. */ debug_notsupp(ctx); break; case 'd': /* Toggle debug flag (whatever that means); deprecated. */ debug_notsupp(ctx); break; case 'D': /* * Detach. With a process-id, detach only one process, * if the multiprocess extension is in use. */ debug_send(ctx, "OK"); unset_breakcond(); break; case 'F': /* * File I/O extension reply; for now at least we have * no use for this. */ debug_notsupp(ctx); break; case 'g': /* Read general-purpose registers */ debug_register_print(ctx); break; case 'G': /* * Write general-purpose registers. The G is followed * by a register dump in the same format as the 'g' * reply. */ // XXX gcc docs say this is required debug_notsupp(ctx); break; case 'H': /* * Hc followed by a thread ID sets the thread that * step and continue operations should affect; Hg * followed by a thread ID sets the thread that * other operations should affect. */ if (pkt[2] == 'c') { debug_notsupp(ctx); } else if (pkt[2] == 'g') { unsigned cpunum; cpunum = getthreadid(pkt+3); if (cpunum >= cpu_numcpus()) { debug_send(ctx, "E00"); break; } debug_cpu = cpunum; debug_send(ctx, "OK"); } else { debug_send(ctx, "OK"); } break; case 'i': /* Step by cycle count */ debug_notsupp(ctx); break; case 'I': /* Step by cycle count with signal (apparently) */ debug_notsupp(ctx); break; case 'k': /* Kill the target */ // don't do this - debugger hangs up and we get SIGPIPE //debug_send(ctx, "OK"); msg("Debugger requested kill"); reqdie(); // To continue running instead of dying, do this instead //unset_breakcond(); break; case 'm': /* Read target memory */ debug_read_mem(ctx, pkt + 2); break; case 'M': /* Write target memory */ debug_write_mem(ctx, pkt + 2); break; case 'p': /* read one register */ debug_notsupp(ctx); break; case 'P': /* write one register */ debug_notsupp(ctx); break; case 'q': /* General query */ if (strcmp(pkt + 2, "C") == 0) { /* Return current thread id */ debug_sendf(ctx,"QC%x", mkthreadid(debug_cpu)); } else if (!strcmp(pkt+2, "fThreadInfo")) { char buf[128]; unsigned i; strcpy(buf, "m"); for (i=0; i<cpu_numcpus(); i++) { if (!cpu_enabled(i)) { continue; } if (i > 0) { strcat(buf, ","); } printbyte(buf, sizeof(buf), mkthreadid(i)); } debug_send(ctx, buf); } else if (!strcmp(pkt+2, "sThreadInfo")) { debug_send(ctx, "l"); } else if (strcmp(pkt+2, "Offsets") == 0) { /* Return info about load-time relocations */ debug_notsupp(ctx); } else if (strcmp(pkt+2, "Supported") == 0) { /* Features handshake */ debug_notsupp(ctx); } else if (!strncmp(pkt+2, "ThreadExtraInfo,", 16)) { debug_getthreadinfo(ctx, pkt+2+16); } else { debug_notsupp(ctx); } break; case 'Q': /* General set mode (I think) */ debug_notsupp(ctx); break; case 'r': /* Reset target - deprecated */ debug_notsupp(ctx); break; case 'R': /* * Restart target (only with extended mode enabled). * Do not reply. */ break; case 's': /* Single step */ debug_restart(ctx, pkt + 2); onecycle(); debug_send_stopinfo(ctx); break; case 'S': /* Single step with signal */ debug_notsupp(ctx); break; case 't': /* search memory for a pattern (underdocumented) */ debug_notsupp(ctx); break; case 'T': /* check if a thread is alive (OK - yes; E.. - no) */ debug_checkthread(ctx, pkt + 2); break; case 'v': /* various longer commands */ debug_notsupp(ctx); break; case 'X': /* Write target memory with a more efficient encoding */ debug_notsupp(ctx); break; case 'z': case 'Z': /* insert (Z) or remove (z) one of the following: */ switch (pkt[2]) { case '0': /* set or clear memory breakpoint */ debug_notsupp(ctx); break; case '1': /* set or clear hardware breakpoint */ debug_notsupp(ctx); break; case '2': /* set or clear write watchpoint */ debug_notsupp(ctx); break; case '3': /* set or clear read watchpoint */ debug_notsupp(ctx); break; case '4': /* set or clear access watchpoint */ debug_notsupp(ctx); break; default: /* ? */ debug_notsupp(ctx); break; } break; default: debug_notsupp(ctx); break; } }