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)
1065 if (avr_core_sreg_get_bit (core, SREG_I))
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);
1193 avr_message (
"Executed %lld clock cycles.\n", avr_core_CK_get (core));
1195 (avr_core_CK_get (core) * 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);
int avr_core_inst_CKS_get(AvrCore *core)
Get the number of clock cycles remaining for the currently executing instruction. ...
void signal_watch_start(int signo)
Start watching for the occurrance of the given signal.
void avr_core_rampz_set(AvrCore *core, uint8_t v)
Set the value of the rampz register.
#define avr_new(type, count)
Macro for allocating memory.
void avr_core_dump_core(AvrCore *core, FILE *f_core)
Dump the contents of the entire CPU core.
DList * dlist_delete(DList *head, AvrClass *data, DListFP_Cmp cmp)
Conditionally delete a node from the list.
void avr_core_set_sleep_mode(AvrCore *core, int sleep_mode)
Sets the device to a sleep state.
void avr_core_attach_vdev(AvrCore *core, uint16_t addr, char *name, VDevice *vdev, int flags, uint8_t reset_value, uint8_t rd_mask, uint8_t wr_mask)
Attach a virtual device into the Memory.
int avr_core_get_state(AvrCore *core)
Returns the device's state (running, stopped, breakpoint, sleep).
DList * dlist_iterator(DList *head, DListFP_Iter func, void *user_data)
Iterate over all elements of the list.
VDevice * mem_get_vdevice_by_name(Memory *mem, char *name)
Find the VDevice associated with the given name.
int avr_core_step(AvrCore *core)
Process a single program instruction, all side effects and peripheral stimulii.
AvrClass * dlist_lookup(DList *head, AvrClass *data, DListFP_Cmp cmp)
Lookup an item in the list.
DevSuppDefn * dev_supp_lookup_device(char *dev_name)
Look up a device name in support list.
Flash * flash_new(int size)
Allocate a new Flash object.
AvrClass * dlist_get_head_data(DList *head)
Extract the data from the head of the list.
void avr_core_run(AvrCore *core)
Start the processing of instructions by the simulator.
void avr_core_reset(AvrCore *core)
Sets the simulated CPU back to its initial state.
void avr_core_irq_clear_all(AvrCore *core)
Removes all irqs from the irq_pending list.
uint64_t get_program_time(void)
Return the number of milliseconds of elapsed program time.
void avr_core_get_sizes(AvrCore *core, int *flash, int *sram, int *sram_start, int *eeprom)
Query the sizes of the 3 memory spaces: flash, sram, and eeprom.
void avr_core_async_cb_add(AvrCore *core, CallBack *cb)
Add a new asynchronous callback to list.
VDevice * avr_core_get_vdev_by_addr(AvrCore *core, int addr)
Returns the VDevice which handles the address addr.
int32_t avr_core_PC_size(AvrCore *core)
Returns the size of the Program Counter in bytes.
int avr_core_get_sleep_mode(AvrCore *core)
Return the device's sleepmode.
int avr_core_load_eeprom(AvrCore *core, char *file, int format)
Load a program from an input file.
void dlist_delete_all(DList *head)
Blow away the entire list.
void avr_core_enable_breakpoints(AvrCore *core)
Enable breakpoints.
void avr_core_clk_cb_exec(AvrCore *core)
Run all the callbacks in the list.
void class_ref(AvrClass *klass)
Increments the reference count for the klass object.
void avr_core_remove_breakpoint(AvrCore *core, int pc)
Removes a break point.
uint8_t avr_core_io_read(AvrCore *core, int reg)
Reads the value of a register.
HWStack * hwstack_new(int depth)
Allocate a new HWStack object.
VDevice * mem_get_vdevice_by_addr(Memory *mem, int addr)
Find the VDevice associated with the given address.
void avr_core_disable_breakpoints(AvrCore *core)
Disable breakpoints.
uint16_t flash_read(Flash *flash, int addr)
Reads a 16-bit word from flash.
void mem_io_fetch(Memory *mem, int addr, uint8_t *val, char *buf, int bufsiz)
Fetch the name and value of the io register (addr).
uint64_t avr_core_CK_get(AvrCore *core)
Get the current clock counter.
DList * dlist_add(DList *head, AvrClass *data, DListFP_Cmp cmp)
Add a new node to the end of the list.
void avr_core_irq_raise(AvrCore *core, unsigned int irq)
Raises an irq by adding it's data to the irq_pending list.
void class_destroy(void *klass)
Releases resources allocated by class's <klass>_new() function.
void avr_core_async_cb_exec(AvrCore *core)
Run all the asynchronous callbacks.
int avr_core_sreg_get_bit(AvrCore *core, int b)
Get the value of bit b of the status register.
void decode_init_lookup_table(void)
Initialize the decoder lookup table.
void flash_dump_core(Flash *flash, FILE *f_core)
Dump the contents of the flash to a file descriptor in text format.
#define avr_warning(fmt, args...)
Print a warning message to stderr.
AvrCore * avr_core_new(char *dev_name)
Allocate a new AvrCore object.
uint32_t avr_core_stack_pop(AvrCore *core, int bytes)
Pop 1-4 bytes off of the stack.
void avr_core_io_write(AvrCore *core, int reg, uint8_t val)
Writes the value of a register. See avr_core_io_read() for a discussion of reg.
void class_unref(AvrClass *klass)
Decrements the reference count for the klass object.
void avr_core_CK_incr(AvrCore *core)
Increment the clock counter.
void signal_watch_stop(int signo)
Stop watching signal.
void avr_core_irq_clear(AvrCore *core, IntVect *irq)
Calls the interrupt's callback to clear the flag.
uint8_t avr_core_rampz_get(AvrCore *core)
Get the value of the rampz register.
struct opcode_info * decode_opcode(uint16_t opcode)
Decode an opcode into the opcode handler function.
void port_add_ext_rd_wr(Port *p, PortFP_ExtRd ext_rd, PortFP_ExtWr ext_wr)
Attaches read and write functions to a particular port.
#define avr_error(fmt, args...)
Print an error message to stderr and terminate program.
void display_io_reg_name(int reg, char *name)
Specify a name for an IO register.
int global_debug_inst_output
Flag for enabling output of instruction debug messages.
int flash_load_from_file(Flash *flash, char *file, int format)
Load program data into flash from a file.
void avr_core_PC_incr(AvrCore *core, int val)
Increment the Program Counter by val.
void avr_core_clk_cb_add(AvrCore *core, CallBack *cb)
Add a new clock callback to list.
void avr_core_add_ext_rd_wr(AvrCore *core, int addr, PortFP_ExtRd ext_rd, PortFP_ExtWr ext_wr)
For adding external read and write callback functions.
void avr_core_io_display_names(AvrCore *core)
Displays all registers.
Memory * mem_new(int gpwr_end, int io_reg_end, int sram_end, int xram_end)
Allocates memory for a new memory object.
int avr_core_load_program(AvrCore *core, char *file, int format)
Load a program from an input file.
void avr_core_sreg_set_bit(AvrCore *core, int b, int v)
Set the value of bit b of the status register.
void mem_dump_core(Memory *mem, FILE *f_core)
Dump all the various memory locations to a file descriptor in text format.
int flash_get_size(Flash *flash)
Accessor method to get the size of a flash.
void display_clock(int clock)
Update the time in the display.
void avr_core_set_state(AvrCore *core, StateType state)
Sets the device's state (running, stopped, breakpoint, sleep).
void flash_write(Flash *flash, int addr, uint16_t val)
Reads a 16-bit word from flash.
void class_overload_destroy(AvrClass *klass, AvrClassFP_Destroy destroy)
Overload the default destroy method.
VDevice * avr_core_get_vdev_by_name(AvrCore *core, char *name)
Returns the VDevice with the name name.
int signal_has_occurred(int signo)
Check to see if a signal has occurred.
void avr_core_insert_breakpoint(AvrCore *core, int pc)
Inserts a break point.
void avr_core_stack_push(AvrCore *core, int bytes, uint32_t val)
Push 1-4 bytes onto the stack.
void mem_reset(Memory *mem)
Resets every device in the memory object.
MemStack * memstack_new(Memory *mem, int spl_addr)
Allocate a new MemStack object.
void class_construct(AvrClass *klass)
Initializes the AvrClass data structure.
void avr_core_inst_CKS_set(AvrCore *core, int val)
Set the number of clock cycles for the instruction being executed.
IntVect * avr_core_irq_get_pending(AvrCore *core)
Gets the first pending irq.
#define avr_message(fmt, args...)
Print an ordinary message to stdout.
void avr_core_destroy(void *core)
Destructor for the AvrCore class.