core: Ensure we can run in >64K flash
authorMichel Pollet <buserror@gmail.com>
Wed, 11 Apr 2012 20:59:28 +0000 (21:59 +0100)
committerMichel Pollet <buserror@gmail.com>
Wed, 11 Apr 2012 20:59:28 +0000 (21:59 +0100)
From an original patch from alex Bondarenko <alexian79@gmail.com>
Reworked to add a new type for flash addresses.

Signed-off-by: Michel Pollet <buserror@gmail.com>
simavr/sim/sim_avr.c
simavr/sim/sim_avr.h
simavr/sim/sim_core.c
simavr/sim/sim_core.h
simavr/sim/sim_gdb.c

index 5ebd540..de3ea41 100644 (file)
@@ -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);
index bcc5898..dcc8f5c 100644 (file)
@@ -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
index e056974..29f8c0e 100644 (file)
@@ -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);
index 22f781f..7aa3585 100644 (file)
@@ -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)
index 4b699bf..455c56e 100644 (file)
@@ -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;