From 59243c631fd53642073ddbe032236a1cd413ca3a Mon Sep 17 00:00:00 2001 From: Sami Liedes Date: Mon, 28 Feb 2011 22:02:06 +0200 Subject: [PATCH] Tweak struct avr_t to always include a pointer to trace data structure. Previously the size of struct avr_t was dependent on whether the preprocessor macro CONFIG_SIMAVR_TRACE was defined. This was problematic since it meant that applications that link to simavr need to define it the same way as it is defined in simavr Makefiles. Change it to a single pointer to a struct, which is allocated iff tracing is compiled in and a NULL pointer otherwise. Signed-off-by: Sami Liedes --- simavr/sim/sim_avr.c | 3 ++ simavr/sim/sim_avr.h | 66 +++++++++++++++++++++++-------------------- simavr/sim/sim_core.c | 32 ++++++++++----------- simavr/sim/sim_core.h | 12 ++++---- simavr/sim/sim_elf.c | 2 +- 5 files changed, 61 insertions(+), 54 deletions(-) diff --git a/simavr/sim/sim_avr.c b/simavr/sim/sim_avr.c index e13117d..b00cfc7 100644 --- a/simavr/sim/sim_avr.c +++ b/simavr/sim/sim_avr.c @@ -37,6 +37,9 @@ int avr_init(avr_t * avr) memset(avr->flash, 0xff, avr->flashend + 1); avr->data = malloc(avr->ramend + 1); memset(avr->data, 0, avr->ramend + 1); +#ifdef CONFIG_SIMAVR_TRACE + avr->trace_data = calloc(1, sizeof(struct avr_trace_data_t)); +#endif // cpu is in limbo before init is finished. avr->state = cpu_Limbo; diff --git a/simavr/sim/sim_avr.h b/simavr/sim/sim_avr.h index 3bb7eae..4ab0a38 100644 --- a/simavr/sim/sim_avr.h +++ b/simavr/sim/sim_avr.h @@ -75,6 +75,39 @@ enum { cpu_StepDone, // tell gdb it's all OK, and give it registers }; +// this is only ever used if CONFIG_SIMAVR_TRACE is defined +struct avr_trace_data_t { + struct avr_symbol_t ** codeline; + + /* DEBUG ONLY + * this keeps track of "jumps" ie, call,jmp,ret,reti and so on + * allows dumping of a meaningful data even if the stack is + * munched and so on + */ + #define OLD_PC_SIZE 32 + struct { + uint32_t pc; + uint16_t sp; + } old[OLD_PC_SIZE]; // catches reset.. + int old_pci; + +#if AVR_STACK_WATCH + #define STACK_FRAME_SIZE 32 + // this records the call/ret pairs, to try to catch + // code that munches the stack -under- their own frame + struct { + uint32_t pc; + uint16_t sp; + } stack_frame[STACK_FRAME_SIZE]; + int stack_frame_index; +#endif + + // DEBUG ONLY + // keeps track of which registers gets touched by instructions + // reset before each new instructions. Allows meaningful traces + uint32_t touched[256 / 32]; // debug +}; + /* * Main AVR instance. Some of these fields are set by the AVR "Core" definition files * the rest is runtime data (as little as possible) @@ -216,37 +249,8 @@ typedef struct avr_t { // DEBUG ONLY -- value ignored if CONFIG_SIMAVR_TRACE = 0 int trace; -#if CONFIG_SIMAVR_TRACE - struct avr_symbol_t ** codeline; - - /* DEBUG ONLY - * this keeps track of "jumps" ie, call,jmp,ret,reti and so on - * allows dumping of a meaningful data even if the stack is - * munched and so on - */ - #define OLD_PC_SIZE 32 - struct { - uint32_t pc; - uint16_t sp; - } old[OLD_PC_SIZE]; // catches reset.. - int old_pci; - -#if AVR_STACK_WATCH - #define STACK_FRAME_SIZE 32 - // this records the call/ret pairs, to try to catch - // code that munches the stack -under- their own frame - struct { - uint32_t pc; - uint16_t sp; - } stack_frame[STACK_FRAME_SIZE]; - int stack_frame_index; -#endif - - // DEBUG ONLY - // keeps track of which registers gets touched by instructions - // reset before each new instructions. Allows meaningful traces - uint32_t touched[256 / 32]; // debug -#endif + // Only used if CONFIG_SIMAVR_TRACE is defined + struct avr_trace_data_t *trace_data; // VALUE CHANGE DUMP file (waveforms) // this is the VCD file that gets allocated if the diff --git a/simavr/sim/sim_core.c b/simavr/sim/sim_core.c index 8ed2627..aa36220 100644 --- a/simavr/sim/sim_core.c +++ b/simavr/sim/sim_core.c @@ -40,8 +40,8 @@ const char * _sreg_bit_name = "cznvshti"; #define T(w) w -#define REG_TOUCH(a, r) (a)->touched[(r) >> 5] |= (1 << ((r) & 0x1f)) -#define REG_ISTOUCHED(a, r) ((a)->touched[(r) >> 5] & (1 << ((r) & 0x1f))) +#define REG_TOUCH(a, r) (a)->trace_data->touched[(r) >> 5] |= (1 << ((r) & 0x1f)) +#define REG_ISTOUCHED(a, r) ((a)->trace_data->touched[(r) >> 5] & (1 << ((r) & 0x1f))) /* * This allows a "special case" to skip indtruction tracing when in these @@ -63,8 +63,8 @@ int donttrace = 0; #define STATE(_f, args...) { \ if (avr->trace) {\ - if (avr->codeline && avr->codeline[avr->pc>>1]) {\ - const char * symn = avr->codeline[avr->pc>>1]->symbol; \ + if (avr->trace_data->codeline && avr->trace_data->codeline[avr->pc>>1]) {\ + const char * symn = avr->trace_data->codeline[avr->pc>>1]->symbol; \ int dont = 0 && dont_trace(symn);\ if (dont!=donttrace) { \ donttrace = dont;\ @@ -107,7 +107,7 @@ void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v) * 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->stack_frame_index > 1 && addr > avr->stack_frame[avr->stack_frame_index-2].sp) { + if (avr->trace_data->stack_frame_index > 1 && addr > avr->trace_data->stack_frame[avr->trace_data->stack_frame_index-2].sp) { printf("\e[31m%04x : munching stack SP %04x, A=%04x <= %02x\e[0m\n", avr->pc, _avr_sp_get(avr), addr, v); } #endif @@ -277,7 +277,7 @@ static void _avr_invalid_opcode(avr_t * avr) { #if CONFIG_SIMAVR_TRACE printf("\e[31m*** %04x: %-25s Invalid Opcode SP=%04x O=%04x \e[0m\n", - avr->pc, avr->codeline[avr->pc>>1]->symbol, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc+1]<<8)); + avr->pc, avr->trace_data->codeline[avr->pc>>1]->symbol, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc+1]<<8)); #else printf("\e[31m*** %04x: Invalid Opcode SP=%04x O=%04x \e[0m\n", avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc+1]<<8)); @@ -296,7 +296,7 @@ void avr_dump_state(avr_t * avr) int doit = 0; for (int r = 0; r < 3 && !doit; r++) - if (avr->touched[r]) + if (avr->trace_data->touched[r]) doit = 1; if (!doit) return; @@ -333,18 +333,18 @@ void avr_dump_state(avr_t * avr) */ #if CONFIG_SIMAVR_TRACE #define TRACE_JUMP()\ - avr->old[avr->old_pci].pc = avr->pc;\ - avr->old[avr->old_pci].sp = _avr_sp_get(avr);\ - avr->old_pci = (avr->old_pci + 1) & (OLD_PC_SIZE-1);\ + avr->trace_data->old[avr->trace_data->old_pci].pc = avr->pc;\ + avr->trace_data->old[avr->trace_data->old_pci].sp = _avr_sp_get(avr);\ + avr->trace_data->old_pci = (avr->trace_data->old_pci + 1) & (OLD_PC_SIZE-1);\ #if AVR_STACK_WATCH #define STACK_FRAME_PUSH()\ - avr->stack_frame[avr->stack_frame_index].pc = avr->pc;\ - avr->stack_frame[avr->stack_frame_index].sp = _avr_sp_get(avr);\ - avr->stack_frame_index++; + avr->trace_data->stack_frame[avr->trace_data->stack_frame_index].pc = avr->pc;\ + avr->trace_data->stack_frame[avr->trace_data->stack_frame_index].sp = _avr_sp_get(avr);\ + avr->trace_data->stack_frame_index++; #define STACK_FRAME_POP()\ - if (avr->stack_frame_index > 0) \ - avr->stack_frame_index--; + if (avr->trace_data->stack_frame_index > 0) \ + avr->trace_data->stack_frame_index--; #else #define STACK_FRAME_PUSH() #define STACK_FRAME_POP() @@ -457,7 +457,7 @@ uint16_t avr_run_one(avr_t * avr) STATE("RESET\n"); CRASH(); } - avr->touched[0] = avr->touched[1] = avr->touched[2] = 0; + avr->trace_data->touched[0] = avr->trace_data->touched[1] = avr->trace_data->touched[2] = 0; #endif uint32_t opcode = (avr->flash[avr->pc + 1] << 8) | avr->flash[avr->pc]; diff --git a/simavr/sim/sim_core.h b/simavr/sim/sim_core.h index 4642bb4..22f781f 100644 --- a/simavr/sim/sim_core.h +++ b/simavr/sim/sim_core.h @@ -62,12 +62,12 @@ void avr_dump_state(avr_t * avr); #if AVR_STACK_WATCH #define DUMP_STACK() \ - for (int i = avr->stack_frame_index; i; i--) {\ + for (int i = avr->trace_data->stack_frame_index; i; i--) {\ int pci = i-1;\ printf("\e[31m*** %04x: %-25s sp %04x\e[0m\n",\ - avr->stack_frame[pci].pc, \ - avr->codeline ? avr->codeline[avr->stack_frame[pci].pc>>1]->symbol : "unknown", \ - avr->stack_frame[pci].sp);\ + avr->trace_data->stack_frame[pci].pc, \ + avr->trace_data->codeline ? avr->trace_data->codeline[avr->trace_data->stack_frame[pci].pc>>1]->symbol : "unknown", \ + avr->trace_data->stack_frame[pci].sp);\ } #else #define DUMP_STACK() @@ -77,9 +77,9 @@ void avr_dump_state(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->old_pci + i) & 0xf;\ + int pci = (avr->trace_data->old_pci + i) & 0xf;\ printf("\e[31m*** %04x: %-25s RESET -%d; sp %04x\e[0m\n",\ - avr->old[pci].pc, avr->codeline ? avr->codeline[avr->old[pci].pc>>1]->symbol : "unknown", OLD_PC_SIZE-i, avr->old[pci].sp);\ + 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();\ diff --git a/simavr/sim/sim_elf.c b/simavr/sim/sim_elf.c index ab34c28..4f8cebb 100644 --- a/simavr/sim/sim_elf.c +++ b/simavr/sim/sim_elf.c @@ -43,7 +43,7 @@ void avr_load_firmware(avr_t * avr, elf_firmware_t * firmware) avr->avcc = firmware->avcc; avr->aref = firmware->aref; #if CONFIG_SIMAVR_TRACE - avr->codeline = firmware->codeline; + avr->trace_data->codeline = firmware->codeline; #endif avr_loadcode(avr, firmware->flash, firmware->flashsize, firmware->flashbase); -- 2.39.5