void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v) { if (addr > avr->ramend) { AVR_LOG(avr, LOG_ERROR, "CORE: *** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x out of ram\n", avr->pc, _avr_sp_get(avr), avr->flash[avr->pc + 1] | (avr->flash[avr->pc]<<8), addr, v); CRASH(); } if (addr < 32) { AVR_LOG(avr, LOG_ERROR, "CORE: *** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x low registers\n", avr->pc, _avr_sp_get(avr), avr->flash[avr->pc + 1] | (avr->flash[avr->pc]<<8), addr, v); CRASH(); } #if AVR_STACK_WATCH /* * this checks that the current "function" is not doctoring the stack frame that is located * higher on the stack than it should be. It's a sign of code that has overrun it's stack * frame and is munching on it's own return address. */ if (avr->trace_data->stack_frame_index > 1 && addr > avr->trace_data->stack_frame[avr->trace_data->stack_frame_index-2].sp) { printf( FONT_RED "%04x : munching stack SP %04x, A=%04x <= %02x\n" FONT_DEFAULT, avr->pc, _avr_sp_get(avr), addr, v); } #endif if (avr->gdb) { avr_gdb_handle_watchpoints(avr, addr, AVR_GDB_WATCH_WRITE); } avr->data[addr] = v; }
void crash(avr_t* avr) { DUMP_REG(); printf("*** CYCLE %" PRI_avr_cycle_count "PC %04x\n", avr->cycle, avr->pc); for (int i = OLD_PC_SIZE-1; i > 0; i--) { int pci = (avr->trace_data->old_pci + i) & 0xf; printf(FONT_RED "*** %04x: %-25s RESET -%d; sp %04x\n" FONT_DEFAULT, avr->trace_data->old[pci].pc, avr->trace_data->codeline ? avr->trace_data->codeline[avr->trace_data->old[pci].pc>>1]->symbol : "unknown", OLD_PC_SIZE-i, avr->trace_data->old[pci].sp); } printf("Stack Ptr %04x/%04x = %d \n", _avr_sp_get(avr), avr->ramend, avr->ramend - _avr_sp_get(avr)); DUMP_STACK(); avr_sadly_crashed(avr, 0); }
uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr) { if (addr > avr->ramend) { AVR_LOG(avr, LOG_ERROR, FONT_RED "CORE: *** Invalid read address PC=%04x SP=%04x O=%04x Address %04x out of ram (%04x)\n" FONT_DEFAULT, avr->pc, _avr_sp_get(avr), avr->flash[avr->pc + 1] | (avr->flash[avr->pc]<<8), addr, avr->ramend); CRASH(); } if (avr->gdb) { avr_gdb_handle_watchpoints(avr, addr, AVR_GDB_WATCH_READ); } return avr->data[addr]; }