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;
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)
// 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
#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
#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;\
* 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
{
#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));
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;
*/
#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()
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];
#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()
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();\
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);