From 7cad6f9b651144cbb3a5c1bd75cbf2ae75cf513d Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Wed, 11 Apr 2012 21:59:28 +0100 Subject: [PATCH] core: Ensure we can run in >64K flash From an original patch from alex Bondarenko Reworked to add a new type for flash addresses. Signed-off-by: Michel Pollet --- simavr/sim/sim_avr.c | 7 +++---- simavr/sim/sim_avr.h | 6 ++++-- simavr/sim/sim_core.c | 14 +++++++------- simavr/sim/sim_core.h | 2 +- simavr/sim/sim_gdb.c | 9 +++++---- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/simavr/sim/sim_avr.c b/simavr/sim/sim_avr.c index 5ebd540..de3ea41 100644 --- a/simavr/sim/sim_avr.c +++ b/simavr/sim/sim_avr.c @@ -163,7 +163,7 @@ void avr_set_console_register(avr_t * avr, avr_io_addr_t addr) avr_register_io_write(avr, addr, _avr_io_console_write, NULL); } -void avr_loadcode(avr_t * avr, uint8_t * code, uint32_t size, uint32_t address) +void avr_loadcode(avr_t * avr, uint8_t * code, uint32_t size, avr_flashaddr_t address) { if (size > avr->flashend+1) { fprintf(stderr, "avr_loadcode(): Attempted to load code of size %d but flash size is only %d.\n", @@ -192,7 +192,7 @@ void avr_callback_run_gdb(avr_t * avr) if (step) avr->state = cpu_Running; - uint16_t new_pc = avr->pc; + avr_flashaddr_t new_pc = avr->pc; if (avr->state == cpu_Running) { new_pc = avr_run_one(avr); @@ -245,8 +245,7 @@ void avr_callback_sleep_raw(avr_t * avr, avr_cycle_count_t howLong) void avr_callback_run_raw(avr_t * avr) { - - uint16_t new_pc = avr->pc; + avr_flashaddr_t new_pc = avr->pc; if (avr->state == cpu_Running) { new_pc = avr_run_one(avr); diff --git a/simavr/sim/sim_avr.h b/simavr/sim/sim_avr.h index bcc5898..dcc8f5c 100644 --- a/simavr/sim/sim_avr.h +++ b/simavr/sim/sim_avr.h @@ -30,6 +30,8 @@ extern "C" { #include "sim_interrupts.h" #include "sim_cycle_timers.h" +typedef uint32_t avr_flashaddr_t; + struct avr_t; typedef uint8_t (*avr_io_read_t)( struct avr_t * avr, @@ -181,7 +183,7 @@ typedef struct avr_t { * this is why you will see >>1 and <<1 in the decoder to handle jumps. * It CAN be a little confusing, so concentrate, young grasshopper. */ - uint32_t pc; + avr_flashaddr_t pc; /* * callback when specific IO registers are read/written. @@ -312,7 +314,7 @@ avr_loadcode( avr_t * avr, uint8_t * code, uint32_t size, - uint32_t address); + avr_flashaddr_t address); /* * these are accessors for avr->data but allows watchpoints to be set for gdb diff --git a/simavr/sim/sim_core.c b/simavr/sim/sim_core.c index e056974..29f8c0e 100644 --- a/simavr/sim/sim_core.c +++ b/simavr/sim/sim_core.c @@ -426,7 +426,7 @@ get_compare_overflow (uint8_t res, uint8_t rd, uint8_t rr) return (rd & ~rr & ~res) | (~rd & rr & res); } -static inline int _avr_is_instruction_32_bits(avr_t * avr, uint32_t pc) +static inline int _avr_is_instruction_32_bits(avr_t * avr, avr_flashaddr_t pc) { uint16_t o = (avr->flash[pc] | (avr->flash[pc+1] << 8)) & 0xfc0f; return o == 0x9200 || // STS ! Store Direct to Data Space @@ -454,7 +454,7 @@ static inline int _avr_is_instruction_32_bits(avr_t * avr, uint32_t pc) * The nunber of cycles taken by instruction has been added, but might not be * entirely accurate. */ -uint16_t avr_run_one(avr_t * avr) +avr_flashaddr_t avr_run_one(avr_t * avr) { #if CONFIG_SIMAVR_TRACE /* @@ -468,9 +468,9 @@ uint16_t avr_run_one(avr_t * avr) 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]; - uint32_t new_pc = avr->pc + 2; // future "default" pc - int cycle = 1; + uint32_t opcode = (avr->flash[avr->pc + 1] << 8) | avr->flash[avr->pc]; + avr_flashaddr_t new_pc = avr->pc + 2; // future "default" pc + int cycle = 1; switch (opcode & 0xf000) { case 0x0000: { @@ -1135,7 +1135,7 @@ uint16_t avr_run_one(avr_t * avr) } break; case 0x940c: case 0x940d: { // JMP Long Call to sub, 32 bits - uint32_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1); + avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1); uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc]; a = (a << 16) | x; STATE("jmp 0x%06x\n", a); @@ -1145,7 +1145,7 @@ uint16_t avr_run_one(avr_t * avr) } break; case 0x940e: case 0x940f: { // CALL Long Call to sub, 32 bits - uint32_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1); + avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1); uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc]; a = (a << 16) | x; STATE("call 0x%06x\n", a); diff --git a/simavr/sim/sim_core.h b/simavr/sim/sim_core.h index 22f781f..7aa3585 100644 --- a/simavr/sim/sim_core.h +++ b/simavr/sim/sim_core.h @@ -29,7 +29,7 @@ extern "C" { /* * Instruction decoder, run ONE instruction */ -uint16_t avr_run_one(avr_t * avr); +avr_flashaddr_t avr_run_one(avr_t * avr); /* * These are for internal access to the stack (for interrupts) diff --git a/simavr/sim/sim_gdb.c b/simavr/sim/sim_gdb.c index 4b699bf..455c56e 100644 --- a/simavr/sim/sim_gdb.c +++ b/simavr/sim/sim_gdb.c @@ -45,7 +45,7 @@ typedef struct avr_gdb_t { uint32_t watchmap; struct { - uint32_t pc; + avr_flashaddr_t pc; uint32_t len; int kind; } watch[32]; @@ -78,7 +78,7 @@ static void gdb_send_quick_status(avr_gdb_t * g, uint8_t signal) gdb_send_reply(g, cmd); } -static int gdb_change_breakpoint(avr_gdb_t * g, int set, int kind, uint32_t addr, uint32_t len) +static int gdb_change_breakpoint(avr_gdb_t * g, int set, int kind, avr_flashaddr_t addr, uint32_t len) { DBG(printf("set %d kind %d addr %08x len %d (map %08x)\n", set, kind, addr, len, g->watchmap);) if (set) { @@ -193,10 +193,11 @@ static void gdb_handle_command(avr_gdb_t * g, char * cmd) gdb_send_reply(g, "OK"); } break; case 'm': { // read memory - uint32_t addr, len; + avr_flashaddr_t addr; + uint32_t len; sscanf(cmd, "%x,%x", &addr, &len); uint8_t * src = NULL; - if (addr < 0xffff) { + if (addr < avr->flashend) { src = avr->flash + addr; } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) { src = avr->data + addr - 0x800000; -- 2.39.5