39 #include "avrmalloc.h"
74 typedef struct _BreakPt BreakPt;
84 static BreakPt *brk_pt_new (
int pc, uint16_t opcode);
85 static void brk_pt_construct (BreakPt *bp,
int pc, uint16_t opcode);
86 static void brk_pt_destroy (
void *bp);
89 brk_pt_new (
int pc, uint16_t opcode)
94 brk_pt_construct (bp, pc, opcode);
101 brk_pt_construct (BreakPt *bp,
int pc, uint16_t opcode)
113 brk_pt_destroy (
void *bp)
115 BreakPt *_bp = (BreakPt *)bp;
123 static DList *brk_pt_list_add (DList *head,
int pc, uint16_t opcode);
124 static DList *brk_pt_list_delete (DList *head,
int pc);
125 static BreakPt *brk_pt_list_lookup (DList *head,
int pc);
126 static int brk_pt_cmp (AvrClass *d1, AvrClass *d2);
131 brk_pt_cmp (AvrClass *d1, AvrClass *d2)
133 return ((BreakPt *)d1)->pc - ((BreakPt *)d2)->pc;
137 brk_pt_list_add (DList *head,
int pc, uint16_t opcode)
139 BreakPt *bp = brk_pt_new (pc, opcode);
141 return dlist_add (head, (AvrClass *)bp, brk_pt_cmp);
145 brk_pt_list_delete (DList *head,
int pc)
147 BreakPt *bp = brk_pt_new (pc, 0);
156 brk_pt_list_lookup (DList *head,
int pc)
159 BreakPt *bp = brk_pt_new (pc, 0);
161 found = (BreakPt *)
dlist_lookup (head, (AvrClass *)bp, brk_pt_cmp);
168 brk_pt_iterator (DList *head, DListFP_Iter func,
void *user_data)
181 typedef struct _Irq Irq;
190 unsigned int sleep_mode;
195 static Irq *irq_new (IntVect *vector,
int state,
196 unsigned int sleep_mode);
197 static void irq_construct (Irq *irq, IntVect *vector,
int state,
198 unsigned int sleep_mode);
199 static void irq_destroy (
void *irq);
202 irq_new (IntVect *vector,
int state,
unsigned int sleep_mode)
207 irq_construct (irq, vector, state, sleep_mode);
214 irq_construct (Irq *irq, IntVect *vector,
int state,
unsigned int sleep_mode)
221 irq->vector = vector;
223 irq->sleep_mode = sleep_mode;
227 irq_destroy (
void *irq)
229 Irq *_irq = (Irq *)irq;
237 static DList *irq_list_add (DList *head, IntVect *vector);
238 static DList *irq_list_delete (DList *head, IntVect *vector);
240 static Irq *irq_list_lookup_addr (DList *head, IntVect *vector);
242 static int irq_cmp_addr (AvrClass *d1, AvrClass *d2);
243 static int irq_cmp_pending (AvrClass *d1, AvrClass *d2);
248 irq_cmp_addr (AvrClass *d1, AvrClass *d2)
250 return ((Irq *)d1)->vector->addr - ((Irq *)d2)->vector->addr;
254 irq_list_add (DList *head, IntVect *vector)
256 Irq *irq = irq_new (vector, 0, 0);
258 return dlist_add (head, (AvrClass *)irq, irq_cmp_addr);
262 irq_list_delete (DList *head, IntVect *vector)
264 Irq *irq = irq_new (vector, 0, 0);
266 head =
dlist_delete (head, (AvrClass *)irq, irq_cmp_addr);
274 irq_list_lookup_addr (DList *head, IntVect *vector)
277 Irq *irq = irq_new (vector, 0, 0);
279 found = (Irq *)
dlist_lookup (head, (AvrClass *)irq, irq_cmp_addr);
287 irq_cmp_pending (AvrClass *d1, AvrClass *d2)
291 int state = ((Irq *)d2)->state;
293 unsigned int sleep_mode = ((Irq *)d2)->sleep_mode;
299 if (state == STATE_SLEEP)
304 if (sleep_mode & i1->vector->can_wake)
321 irq_get_pending_vector (DList *head,
int state,
unsigned int sleep_mode)
324 Irq *irq = irq_new (NULL, state, sleep_mode);
326 found = (Irq *)
dlist_lookup (head, (AvrClass *)irq, irq_cmp_pending);
329 return found->vector;
334 irq_get_head_vector (DList *head)
346 static void avr_core_construct (AvrCore *core, DevSuppDefn *dev);
357 AvrCore *core = NULL;
362 fprintf (stderr,
"\nSimulating a %s device.\n\n", dev_name);
365 avr_core_construct (core, dev);
375 avr_core_construct (AvrCore *core, DevSuppDefn *dev)
377 int flash_sz = dev_supp_get_flash_sz (dev);
378 int PC_sz = dev_supp_get_PC_sz (dev);
379 int stack_sz = dev_supp_get_stack_sz (dev);
380 int sram_sz = dev_supp_get_sram_sz (dev);
381 int eeprom_sz = dev_supp_get_eeprom_sz (dev);
382 int xram_sz = dev_supp_get_xram_sz (dev);
383 int vtab_idx = dev_supp_get_vtab_idx (dev);
384 int xram_end, sram_end;
392 core->state = STATE_STOPPED;
393 core->sleep_mode = 0;
395 core->PC_size = PC_sz;
396 core->PC_max = flash_sz / 2;
401 core->breakpoints = NULL;
403 core->irq_pending = NULL;
404 core->irq_vtable = (IntVect *)(global_vtable_list[vtab_idx]);
405 core->irq_offset = 0;
411 core->async_cb = NULL;
414 if (dev_supp_has_ext_io_reg (dev))
415 sram_end = 0xff + sram_sz;
417 sram_end = 0x5f + sram_sz;
422 if (dev_supp_has_ext_io_reg (dev))
423 core->mem =
mem_new (0x1f, 0xff, sram_end, xram_end);
425 core->mem =
mem_new (0x1f, 0x5f, sram_end, xram_end);
429 core->gpwr = gpwr_new ();
430 for (addr = 0; addr < 0x20; addr++)
432 static char *reg_name[] = {
"r00",
"r01",
"r02",
"r03",
"r04",
"r05",
433 "r06",
"r07",
"r08",
"r09",
"r10",
"r11",
434 "r12",
"r13",
"r14",
"r15",
"r16",
"r17",
435 "r18",
"r19",
"r20",
"r21",
"r22",
"r23",
436 "r24",
"r25",
"r26",
"r27",
"r28",
"r29",
440 (VDevice *)core->gpwr, 0, 0, 0xff, 0xff);
447 core->eeprom = eeprom_new (eeprom_sz, mask_EERE | mask_EEWE | mask_EEMWE);
454 dev_supp_attach_io_regs (core, dev);
488 if (dev_supp_has_ext_io_reg (dev))
489 base = SRAM_EXTENDED_IO_BASE;
493 core->sram = sram_new (base, sram_sz);
494 sram = (VDevice *)core->sram;
496 avr_message (
"attach: Internal SRAM from 0x%04x to 0x%04x\n", base,
497 (base + sram_sz - 1));
499 for (addr = base; addr < (base + sram_sz); addr++)
515 if (dev_supp_has_ext_io_reg (dev))
516 base = SRAM_EXTENDED_IO_BASE + sram_sz;
518 base = SRAM_BASE + sram_sz;
520 core->xram = sram_new (base, xram_sz);
521 xram = (VDevice *)core->xram;
523 avr_message (
"attach: External SRAM from 0x%04x to 0x%04x\n", base,
524 (base + xram_sz - 1));
526 for (addr = base; addr < (base + xram_sz); addr++)
551 AvrCore *_core = (AvrCore *)core;
579 *sram = sram_get_size (core->sram);
580 *sram_start = sram_get_base (core->sram);
589 *eeprom = eeprom_get_size (core->eeprom);
596 char *name, VDevice *vdev,
597 int flags, uint8_t reset_value,
598 uint8_t rd_mask, uint8_t wr_mask);
628 static uint16_t avr_core_flash_read (AvrCore *core,
int addr);
631 static void avr_core_flash_write (AvrCore *core,
int addr,
640 static void avr_core_flash_write_lo8 (AvrCore *core,
int addr,
649 static void avr_core_flash_write_hi8 (AvrCore *core,
int addr,
662 static uint8_t avr_core_mem_read (AvrCore *core,
int addr);
668 static void avr_core_mem_write (AvrCore *core,
int addr, uint8_t val);
678 static uint8_t avr_core_sreg_get (AvrCore *core);
682 static void avr_core_sreg_set (AvrCore *core, uint8_t v);
715 static uint8_t avr_core_gpwr_get (AvrCore *core,
int reg);
718 static void avr_core_gpwr_set (AvrCore *core,
int reg, uint8_t val);
739 for (i = IO_REG_ADDR_BEGIN; i < IO_REG_ADDR_END; i++)
741 mem_io_fetch (core->mem, i, &val, name, sizeof (name) - 1);
759 static void avr_core_io_fetch (AvrCore *core,
int reg, uint8_t * val,
760 char *buf,
int bufsiz);
798 static int32_t avr_core_PC_max (AvrCore *core);
801 static int32_t avr_core_PC_get (AvrCore *core);
808 static void avr_core_PC_set (AvrCore *core, int32_t val);
848 return irq_get_pending_vector (core->irq_pending, core->state,
856 IntVect *irq_ptr = &core->irq_vtable[irq];
858 #if !defined(DISABLE_IRQ_MESSAGES)
859 avr_message (
"Raising irq # %u [%s at 0x%x]\n", irq, irq_ptr->name,
862 core->irq_pending = irq_list_add (core->irq_pending, irq_ptr);
869 core->irq_pending = irq_list_delete (core->irq_pending, irq);
886 #define BREAK_OPCODE 0x9598
890 core->breakpoints = brk_pt_list_add (core->breakpoints, pc, insn);
902 bp = brk_pt_list_lookup (core->breakpoints, pc);
905 uint16_t insn = bp->opcode;
907 core->breakpoints = brk_pt_list_delete (core->breakpoints, pc);
915 struct bp_enable_data
924 iter_enable_breakpoint (AvrClass *data,
void *user_data)
926 BreakPt *bp = (BreakPt *)data;
927 struct bp_enable_data *bed = (
struct bp_enable_data *)user_data;
931 uint16_t insn =
flash_read (bed->core->flash, bp->pc);
933 if (insn != BREAK_OPCODE)
937 flash_write (bed->core->flash, bp->pc, BREAK_OPCODE);
943 flash_write (bed->core->flash, bp->pc, bp->opcode);
957 struct bp_enable_data bed = { core, 0 };
960 brk_pt_iterator (core->breakpoints, iter_enable_breakpoint, &bed);
970 struct bp_enable_data bed = { core, 1 };
973 brk_pt_iterator (core->breakpoints, iter_enable_breakpoint, &bed);
990 exec_next_instruction (AvrCore *core)
994 struct opcode_info *opi;
996 pc = avr_core_PC_get (core);
1005 result = opi->func (core, opcode, opi->arg1, opi->arg2);
1008 fprintf (stderr,
"0x%06x (0x%06x) : 0x%04x : %s\n", pc, pc * 2,
1009 opcode, global_opcode_name[result]);
1042 avr_core_check_interrupts (AvrCore *core)
1046 if (core->irq_pending)
1052 if (irq->name == NULL)
1054 avr_error (
"Raised an invalid irq for device");
1057 if (irq->addr == IRQ_RESET_ADDR)
1067 int pc = avr_core_PC_get (core);
1073 #if !defined(DISABLE_IRQ_MESSAGES)
1074 avr_message (
"Vectoring to irq at addr:0x%x offset:0x%x\n",
1075 irq->addr * 2, core->irq_offset * 2);
1078 avr_core_PC_set (core, irq->addr + core->irq_offset);
1100 if (state != STATE_SLEEP)
1103 res = exec_next_instruction (core);
1107 while (core->inst_CKS > 0)
1126 if (res != opcode_RETI)
1127 avr_core_check_interrupts (core);
1154 uint64_t start_time, run_time;
1158 core->state = STATE_RUNNING;
1166 while (core->state == STATE_RUNNING)
1173 if (res == BREAK_POINT)
1183 if (run_time == 0) run_time = 1;
1185 avr_message (
"Run time was %lld.%03lld seconds.\n", run_time / 1000,
1191 avr_message (
"Executed %lld instructions.\n", cnt);
1192 avr_message (
" %lld insns/sec\n", (cnt * 1000) / run_time);
1206 avr_core_PC_set (core, 0);
1245 PortFP_ExtWr ext_wr)
1251 avr_warning (
"Device does not have vdevice at 0x%04x.\n", addr);
1296 unsigned int pc = avr_core_PC_get (core);
1298 fprintf (f_core,
"PC = 0x%06x (PC*2 = 0x%06x)\n\n", pc, pc * 2);
1318 return eeprom_load_from_file (ee, file, format);