From de9f70375c1967c9d24f9181b66bbb949afee47f Mon Sep 17 00:00:00 2001 From: Jakob Gruber Date: Wed, 18 Jul 2012 12:37:50 +0200 Subject: [PATCH] gdb: Read/write SREG values correctly Accessing SREG through gdb seems to have been broken since SREG is no longer synthesized at each instruction (2f67001d). As a quick fix, make SREG accessors public and use them in sim_gdb. Note that invalid avr->sreg values no longer trigger the CRASH macro. --- simavr/sim/sim_core.c | 11 ++--------- simavr/sim/sim_core.h | 20 ++++++++++++++++++++ simavr/sim/sim_gdb.c | 9 +++++++-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/simavr/sim/sim_core.c b/simavr/sim/sim_core.c index f3106ef..33073c8 100644 --- a/simavr/sim/sim_core.c +++ b/simavr/sim/sim_core.c @@ -155,8 +155,7 @@ static inline void _avr_set_r(avr_t * avr, uint8_t r, uint8_t v) if (r == R_SREG) { avr->data[R_SREG] = v; // unsplit the SREG - for (int i = 0; i < 8; i++) - avr->sreg[i] = (v & (1 << i)) != 0; + SET_SREG_FROM(avr, v); SREG(); } if (r > 31) { @@ -209,13 +208,7 @@ static inline uint8_t _avr_get_ram(avr_t * avr, uint16_t addr) * SREG is special it's reconstructed when read * while the core itself uses the "shortcut" array */ - avr->data[R_SREG] = 0; - for (int i = 0; i < 8; i++) - if (avr->sreg[i] > 1) { - printf("** Invalid SREG!!\n"); - CRASH(); - } else if (avr->sreg[i]) - avr->data[R_SREG] |= (1 << i); + READ_SREG_INTO(avr, avr->data[R_SREG]); } else if (addr > 31 && addr < 256) { uint8_t io = AVR_DATA_TO_IO(addr); diff --git a/simavr/sim/sim_core.h b/simavr/sim/sim_core.h index 9f83654..a3a4c28 100644 --- a/simavr/sim/sim_core.h +++ b/simavr/sim/sim_core.h @@ -95,6 +95,26 @@ void avr_dump_state(avr_t * avr); #endif +/** + * Reconstructs the SREG value from avr->sreg into dst. + */ +#define READ_SREG_INTO(avr, dst) { \ + dst = 0; \ + for (int i = 0; i < 8; i++) \ + if (avr->sreg[i] > 1) { \ + printf("** Invalid SREG!!\n"); \ + } else if (avr->sreg[i]) \ + dst |= (1 << i); \ + } + +/** + * Splits the SREG value from src into the avr->sreg array. + */ +#define SET_SREG_FROM(avr, src) { \ + for (int i = 0; i < 8; i++) \ + avr->sreg[i] = (src & (1 << i)) != 0; \ + } + #ifdef __cplusplus }; #endif diff --git a/simavr/sim/sim_gdb.c b/simavr/sim/sim_gdb.c index d5313fd..ac6d068 100644 --- a/simavr/sim/sim_gdb.c +++ b/simavr/sim/sim_gdb.c @@ -32,6 +32,7 @@ #include #include #include "sim_avr.h" +#include "sim_core.h" // for SET_SREG_FROM, READ_SREG_INTO #include "sim_hex.h" #include "avr_eeprom.h" #include "sim_gdb.h" @@ -210,6 +211,7 @@ static int gdb_write_register(avr_gdb_t * g, int regi, uint8_t * src) return 1; case 32: g->avr->data[R_SREG] = *src; + SET_SREG_FROM(g->avr, *src); return 1; case 33: g->avr->data[R_SPL] = src[0]; @@ -228,8 +230,11 @@ static int gdb_read_register(avr_gdb_t * g, int regi, char * rep) case 0 ... 31: sprintf(rep, "%02x", g->avr->data[regi]); break; - case 32: - sprintf(rep, "%02x", g->avr->data[R_SREG]); + case 32: { + uint8_t sreg; + READ_SREG_INTO(g->avr, sreg); + sprintf(rep, "%02x", sreg); + } break; case 33: sprintf(rep, "%02x%02x", g->avr->data[R_SPL], g->avr->data[R_SPH]); -- 2.39.5