Main Page

- Main Page
- Related Pages
- Files

- File List
- Globals

avrcore.c
Go to the documentation of this file.
1 /*
2 * $Id: avrcore.c,v 1.88 2008/03/19 22:39:01 joerg_wunsch Exp $
3 *
4 ****************************************************************************
5 *
6 * simulavr - A simulator for the Atmel AVR family of microcontrollers.
7 * Copyright (C) 2001, 2002, 2003, 2004 Theodore A. Roth
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 ****************************************************************************
24 */
25
26 /**
27 * \file avrcore.c
28 * \brief Module for the core AvrCore object, which is the AVR CPU to be
29 * simulated.
30 */
31
32 #include <config.h>
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <signal.h>
37
38 #include "avrerror.h"
39 #include "avrmalloc.h"
40 #include "avrclass.h"
41 #include "utils.h"
42 #include "callback.h"
43 #include "op_names.h"
44
45 #include "storage.h"
46 #include "flash.h"
47
48 #include "vdevs.h"
49 #include "memory.h"
50 #include "stack.h"
51 #include "register.h"
52 #include "sram.h"
53 #include "eeprom.h"
54 #include "ports.h"
55
56 #include "avrcore.h"
57
58 #include "display.h"
59 #include "decoder.h"
60 #include "sig.h"
61 #include "devsupp.h"
62
63 /** \brief Flag for enabling output of instruction debug messages. */
64 int global_debug_inst_output = 0;
65
66 /***************************************************************************\
67 *
68 * BreakPt(AvrClass) Methods
69 *
70 \***************************************************************************/
71
72 #ifndef DOXYGEN /* don't expose to doxygen */
73
74 typedef struct _BreakPt BreakPt;
75 struct _BreakPt
76 {
77 AvrClass parent;
78 int pc;
79 uint16_t opcode;
80 };
81
82 #endif
83
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);
87
88 static BreakPt *
89 brk_pt_new (int pc, uint16_t opcode)
90 {
91 BreakPt *bp;
92
93 bp = avr_new (BreakPt, 1);
94 brk_pt_construct (bp, pc, opcode);
95 class_overload_destroy ((AvrClass *)bp, brk_pt_destroy);
96
97 return bp;
98 }
99
100 static void
101 brk_pt_construct (BreakPt *bp, int pc, uint16_t opcode)
102 {
103 if (bp == NULL)
104 avr_error ("passed null ptr");
105
106 class_construct ((AvrClass *)bp);
107
108 bp->pc = pc;
109 bp->opcode = opcode;
110 }
111
112 static void
113 brk_pt_destroy (void *bp)
114 {
115 BreakPt *_bp = (BreakPt *)bp;
116
117 if (_bp == NULL)
118 return;
119
120 class_destroy (bp);
121 }
122
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);
127
128 /* Compare function for break points. */
129
130 static int
131 brk_pt_cmp (AvrClass *d1, AvrClass *d2)
132 {
133 return ((BreakPt *)d1)->pc - ((BreakPt *)d2)->pc;
134 }
135
136 static DList *
137 brk_pt_list_add (DList *head, int pc, uint16_t opcode)
138 {
139 BreakPt *bp = brk_pt_new (pc, opcode);
140
141 return dlist_add (head, (AvrClass *)bp, brk_pt_cmp);
142 }
143
144 static DList *
145 brk_pt_list_delete (DList *head, int pc)
146 {
147 BreakPt *bp = brk_pt_new (pc, 0);
148
149 head = dlist_delete (head, (AvrClass *)bp, brk_pt_cmp);
150 class_unref ((AvrClass *)bp);
151
152 return head;
153 }
154
155 static BreakPt *
156 brk_pt_list_lookup (DList *head, int pc)
157 {
158 BreakPt *found;
159 BreakPt *bp = brk_pt_new (pc, 0);
160
161 found = (BreakPt *)dlist_lookup (head, (AvrClass *)bp, brk_pt_cmp);
162 class_unref ((AvrClass *)bp);
163
164 return found;
165 }
166
167 static DList *
168 brk_pt_iterator (DList *head, DListFP_Iter func, void *user_data)
169 {
170 return dlist_iterator (head, func, user_data);
171 }
172
173 /***************************************************************************\
174 *
175 * Irq(AvrClass) Methods: For managing the irq_pending list.
176 *
177 \***************************************************************************/
178
179 #ifndef DOXYGEN /* don't expose to doxygen */
180
181 typedef struct _Irq Irq;
182 struct _Irq
183 {
184 AvrClass parent;
185 IntVect *vector;
186
187 /* These are only used for storing lookup information. Copies of
188 core->{state,sleep_mode}. */
189 int state;
190 unsigned int sleep_mode;
191 };
192
193 #endif
194
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);
200
201 static Irq *
202 irq_new (IntVect *vector, int state, unsigned int sleep_mode)
203 {
204 Irq *irq;
205
206 irq = avr_new (Irq, 1);
207 irq_construct (irq, vector, state, sleep_mode);
208 class_overload_destroy ((AvrClass *)irq, irq_destroy);
209
210 return irq;
211 }
212
213 static void
214 irq_construct (Irq *irq, IntVect *vector, int state, unsigned int sleep_mode)
215 {
216 if (irq == NULL)
217 avr_error ("passed null ptr");
218
219 class_construct ((AvrClass *)irq);
220
221 irq->vector = vector;
222 irq->state = state;
223 irq->sleep_mode = sleep_mode;
224 }
225
226 static void
227 irq_destroy (void *irq)
228 {
229 Irq *_irq = (Irq *)irq;
230
231 if (_irq == NULL)
232 return;
233
234 class_destroy (irq);
235 }
236
237 static DList *irq_list_add (DList *head, IntVect *vector);
238 static DList *irq_list_delete (DList *head, IntVect *vector);
239 #if 0 /* TRoth/2002-09-15: This isn't used. ??? */
240 static Irq *irq_list_lookup_addr (DList *head, IntVect *vector);
241 #endif
242 static int irq_cmp_addr (AvrClass *d1, AvrClass *d2);
243 static int irq_cmp_pending (AvrClass *d1, AvrClass *d2);
244
245 /* Compare function for break points. */
246
247 static int
248 irq_cmp_addr (AvrClass *d1, AvrClass *d2)
249 {
250 return ((Irq *)d1)->vector->addr - ((Irq *)d2)->vector->addr;
251 }
252
253 static DList *
254 irq_list_add (DList *head, IntVect *vector)
255 {
256 Irq *irq = irq_new (vector, 0, 0);
257
258 return dlist_add (head, (AvrClass *)irq, irq_cmp_addr);
259 }
260
261 static DList *
262 irq_list_delete (DList *head, IntVect *vector)
263 {
264 Irq *irq = irq_new (vector, 0, 0);
265
266 head = dlist_delete (head, (AvrClass *)irq, irq_cmp_addr);
267 class_unref ((AvrClass *)irq);
268
269 return head;
270 }
271
272 #if 0 /* TRoth/2002-09-15: This isn't used. ??? */
273 static Irq *
274 irq_list_lookup_addr (DList *head, IntVect *vector)
275 {
276 Irq *found;
277 Irq *irq = irq_new (vector, 0, 0);
278
279 found = (Irq *)dlist_lookup (head, (AvrClass *)irq, irq_cmp_addr);
280 class_unref ((AvrClass *)irq);
281
282 return found;
283 }
284 #endif
285
286 static int
287 irq_cmp_pending (AvrClass *d1, AvrClass *d2)
288 {
289 Irq *i1 = (Irq *)d1; /* This is the irq which might be ready to be
290 vectored into. */
291 int state = ((Irq *)d2)->state; /* The state the device is currently
292 in. */
293 unsigned int sleep_mode = ((Irq *)d2)->sleep_mode; /* This is the sleep
294 mode the device in
295 currently in. Only
296 one bit should be
297 set. */
298
299 if (state == STATE_SLEEP)
300 {
301 /* If device is in the sleep state, the irq will only pending if it
302 can wake up the device. */
303
304 if (sleep_mode & i1->vector->can_wake)
305 return 0; /* vector into the irq */
306 else
307 return -1; /* try the next irq */
308 }
309
310 /* If the state is not STATE_SLEEP, any irq we see is automatically
311 pending, so vector it. */
312
313 return 0;
314 }
315
316 /* Walk the list looking for a pending irq which can be handled. If the device
317 is in a sleep state, the can_wake mask could force the head of the list to
318 not be the irq which gets vectored. */
319
320 static IntVect *
321 irq_get_pending_vector (DList *head, int state, unsigned int sleep_mode)
322 {
323 Irq *found;
324 Irq *irq = irq_new (NULL, state, sleep_mode);
325
326 found = (Irq *)dlist_lookup (head, (AvrClass *)irq, irq_cmp_pending);
327 class_unref ((AvrClass *)irq);
328
329 return found->vector;
330 }
331
332 #if 0 /* TRoth/2002-09-15: This isn't used. ??? */
333 static IntVect *
334 irq_get_head_vector (DList *head)
335 {
336 return ((Irq *)dlist_get_head_data (head))->vector;
337 }
338 #endif
339
340 /***************************************************************************\
341 *
342 * AvrCore(AvrClass) Methods
343 *
344 \***************************************************************************/
345
346 static void avr_core_construct (AvrCore *core, DevSuppDefn *dev);
347
348 /** \name AvrCore handling methods */
349
350 /*@{*/
351
352 /** \brief Allocate a new AvrCore object. */
353
354 AvrCore *
355 avr_core_new (char *dev_name)
356 {
357 AvrCore *core = NULL;
358 DevSuppDefn *dev = dev_supp_lookup_device (dev_name);
359
360 if (dev)
361 {
362 fprintf (stderr, "\nSimulating a %s device.\n\n", dev_name);
363
364 core = avr_new (AvrCore, 1);
365 avr_core_construct (core, dev);
366 class_overload_destroy ((AvrClass *)core, avr_core_destroy);
367 }
368
369 return core;
370 }
371
372 /** \brief Constructor for the AvrCore class. */
373
374 static void
375 avr_core_construct (AvrCore *core, DevSuppDefn *dev)
376 {
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;
385 int addr;
386
387 if (core == NULL)
388 avr_error ("passed null ptr");
389
390 class_construct ((AvrClass *)core);
391
392 core->state = STATE_STOPPED;
393 core->sleep_mode = 0; /* each bit represents a sleep mode */
394 core->PC = 0;
395 core->PC_size = PC_sz;
396 core->PC_max = flash_sz / 2; /* flash_sz is in bytes, need number of
397 words here */
398
399 core->flash = flash_new (flash_sz);
400
401 core->breakpoints = NULL;
402
403 core->irq_pending = NULL;
404 core->irq_vtable = (IntVect *)(global_vtable_list[vtab_idx]);
405 core->irq_offset = 0;
406
407 core->CK = 0;
408 core->inst_CKS = 0;
409
410 core->clk_cb = NULL;
411 core->async_cb = NULL;
412
413 /* FIXME: hack to get it to compile. */
414 if (dev_supp_has_ext_io_reg (dev))
415 sram_end = 0xff + sram_sz;
416 else
417 sram_end = 0x5f + sram_sz;
418 if (xram_sz)
419 xram_end = 0xffff;
420 else
421 xram_end = sram_end; /* i.e., no XRAM at all */
422 if (dev_supp_has_ext_io_reg (dev))
423 core->mem = mem_new (0x1f, 0xff, sram_end, xram_end);
424 else
425 core->mem = mem_new (0x1f, 0x5f, sram_end, xram_end);
426
427 /* Attach the gpwr's to the memory bus. */
428
429 core->gpwr = gpwr_new ();
430 for (addr = 0; addr < 0x20; addr++)
431 {
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",
437 "r30", "r31" };
438
439 avr_core_attach_vdev (core, addr, reg_name[addr],
440 (VDevice *)core->gpwr, 0, 0, 0xff, 0xff);
441 }
442
443 /* Setup EEPROM before IO regs since its object is re-used in the EEPROM
444 control registers. */
445 if (eeprom_sz)
446 {
447 core->eeprom = eeprom_new (eeprom_sz, mask_EERE | mask_EEWE | mask_EEMWE);
448 }
449 else
450 {
451 core->eeprom = NULL;
452 }
453
454 dev_supp_attach_io_regs (core, dev);
455
456 /* Set up the stack. */
457
458 if (stack_sz)
459 {
460 core->stack = (Stack *)hwstack_new (stack_sz);
461 }
462 else
463 {
464 /* Assuming that SPL is always at 0x5d. */
465
466 core->stack = (Stack *)memstack_new (core->mem, 0x5d);
467 }
468
469 /* Assuming the SREG is always at 0x5f. */
470
471 core->sreg = (SREG *)avr_core_get_vdev_by_addr (core, 0x5f);
472 class_ref ((AvrClass *)core->sreg);
473
474 /* Assuming that RAMPZ is always at 0x5b. If the device doesn't support
475 RAMPZ, install a NULL pointer. */
476
477 core->rampz = (RAMPZ *)avr_core_get_vdev_by_addr (core, 0x5b);
478 if (core->rampz)
479 class_ref ((AvrClass *)core->rampz);
480
481 /* Attach the internal sram to the memory bus if needed. */
482
483 if (sram_sz)
484 {
485 int base;
486 VDevice *sram;
487
488 if (dev_supp_has_ext_io_reg (dev))
489 base = SRAM_EXTENDED_IO_BASE;
490 else
491 base = SRAM_BASE;
492
493 core->sram = sram_new (base, sram_sz);
494 sram = (VDevice *)core->sram;
495
496 avr_message ("attach: Internal SRAM from 0x%04x to 0x%04x\n", base,
497 (base + sram_sz - 1));
498
499 for (addr = base; addr < (base + sram_sz); addr++)
500 {
501 avr_core_attach_vdev (core, addr, "Internal SRAM", sram, 0, 0,
502 0xff, 0xff);
503 }
504 }
505 else
506 {
507 core->sram = NULL;
508 }
509
510 if (xram_sz)
511 {
512 int base;
513 VDevice *xram;
514
515 if (dev_supp_has_ext_io_reg (dev))
516 base = SRAM_EXTENDED_IO_BASE + sram_sz;
517 else
518 base = SRAM_BASE + sram_sz;
519
520 core->xram = sram_new (base, xram_sz);
521 xram = (VDevice *)core->xram;
522
523 avr_message ("attach: External SRAM from 0x%04x to 0x%04x\n", base,
524 (base + xram_sz - 1));
525
526 for (addr = base; addr < (base + xram_sz); addr++)
527 {
528 avr_core_attach_vdev (core, addr, "External SRAM", xram, 0, 0,
529 0xff, 0xff);
530 }
531 }
532 else
533 {
534 core->xram = NULL;
535 }
536
537 /* Initialize the decoder lookup table */
538
539 decode_init_lookup_table ();
540 }
541
542 /**
543 * \brief Destructor for the AvrCore class.
544 *
545 * Not to be called directly, except by a derived class.
546 * Called via class_unref.
547 */
548 void
549 avr_core_destroy (void *core)
550 {
551 AvrCore *_core = (AvrCore *)core;
552
553 if (_core == NULL)
554 return;
555
556 class_unref ((AvrClass *)_core->sreg);
557 class_unref ((AvrClass *)_core->flash);
558 class_unref ((AvrClass *)_core->gpwr);
559 class_unref ((AvrClass *)_core->mem);
560 class_unref ((AvrClass *)_core->stack);
561
562 dlist_delete_all (_core->breakpoints);
563 dlist_delete_all (_core->clk_cb);
564 dlist_delete_all (_core->async_cb);
565 dlist_delete_all (_core->irq_pending);
566
567 class_destroy (core);
568 }
569
570 /** \brief Query the sizes of the 3 memory spaces: flash, sram, and eeprom. */
571 void
572 avr_core_get_sizes (AvrCore *core, int *flash, int *sram, int *sram_start,
573 int *eeprom)
574 {
575 *flash = flash_get_size (core->flash);
576
577 if (core->sram)
578 {
579 *sram = sram_get_size (core->sram);
580 *sram_start = sram_get_base (core->sram);
581 }
582 else
583 {
584 *sram = 0;
585 *sram_start = 0;
586 }
587
588 if (core->eeprom)
589 *eeprom = eeprom_get_size (core->eeprom);
590 else
591 *eeprom = 0;
592 }
593
594 /** \brief Attach a virtual device into the Memory. */
595 extern inline void avr_core_attach_vdev (AvrCore *core, uint16_t addr,
596 char *name, VDevice *vdev,
597 int flags, uint8_t reset_value,
598 uint8_t rd_mask, uint8_t wr_mask);
599
600 /** \brief Returns the \c VDevice with the name \a name. */
601 extern inline VDevice *avr_core_get_vdev_by_name (AvrCore *core, char *name);
602
603 /** \brief Returns the \c VDevice which handles the address \a addr. */
604 extern inline VDevice *avr_core_get_vdev_by_addr (AvrCore *core, int addr);
605
606 /** \brief Sets the device's state (running, stopped, breakpoint, sleep). */
607 extern inline void avr_core_set_state (AvrCore *core, StateType state);
608
609 /** \brief Returns the device's state (running, stopped, breakpoint, sleep). */
610 extern inline int avr_core_get_state (AvrCore *core);
611
612 /** \brief Sets the device to a sleep state.
613 * \param core Pointer to the core.
614 * \param sleep_mode The BITNUMBER of the sleepstate.
615 */
616 extern inline void avr_core_set_sleep_mode (AvrCore *core, int sleep_mode);
617
618 /** \brief Return the device's sleepmode. */
619 extern inline int avr_core_get_sleep_mode (AvrCore *core);
620
621 /*@}*/
622
623 /** \name Program Memory Space Access Methods */
624
625 /*@{*/
626
627 /** \brief Reads a word from flash memory. */
628 static uint16_t avr_core_flash_read (AvrCore *core, int addr);
629
630 /** \brief Writes a word to flash memory. */
631 static void avr_core_flash_write (AvrCore *core, int addr,
632 uint16_t val);
633
634 /** \brief Writes a byte to flash memory.
635 *
636 * This function writes the lower 8 bit of a flash word.
637 * Use avr_core_flash_write() write to write a full word,
638 * or avr_core_flash_write_hi8() to write the upper 8 bits.
639 */
640 static void avr_core_flash_write_lo8 (AvrCore *core, int addr,
641 uint8_t val);
642
643 /** \brief Writes a byte to flash memory.
644 *
645 * This function writes the upper 8 bit of a flash word.
646 * Use avr_core_flash_write() write to write a full word,
647 * or avr_core_flash_write_lo8() to write the lower 8 bits.
648 */
649 static void avr_core_flash_write_hi8 (AvrCore *core, int addr,
650 uint8_t val);
651
652 /*@}*/
653
654 /** \name Data Memory Space Access Methods */
655
656 /*@{*/
657
658 /** \brief Reads a byte from memory.
659 *
660 * This accesses the \a register \a file and the \a SRAM.
661 */
662 static uint8_t avr_core_mem_read (AvrCore *core, int addr);
663
664 /** \brief Writes a byte to memory.
665 *
666 * This accesses the \a register \a file and the \a SRAM.
667 */
668 static void avr_core_mem_write (AvrCore *core, int addr, uint8_t val);
669
670 /*@}*/
671
672 /** \name Status Register Access Methods */
673
674 /*@{*/
675
676 /** \brief Get the value of the status register. */
677
678 static uint8_t avr_core_sreg_get (AvrCore *core);
679
680 /** \brief Set the value of the status register. */
681
682 static void avr_core_sreg_set (AvrCore *core, uint8_t v);
683
684 /** \brief Get the value of bit \c b of the status register. */
685
686 extern inline int avr_core_sreg_get_bit (AvrCore *core, int b);
687
688 /** \brief Set the value of bit \c b of the status register. */
689
690 extern inline void avr_core_sreg_set_bit (AvrCore *core, int b, int v);
691
692 /*@}*/
693
694 /** \name RAMPZ access methods */
695
696 /*@{*/
697
698 /** \brief Get the value of the rampz register. */
699
700 extern inline uint8_t avr_core_rampz_get (AvrCore *core);
701
702 /** \brief Set the value of the rampz register. */
703
704 extern inline void avr_core_rampz_set (AvrCore *core, uint8_t v);
705
706 /*@}*/
707
708 /**
709 * \Name General Purpose Working Register Access Methods
710 */
711
712 /*@{*/
713
714 /** \brief Returns a GPWR's(\a r0-r31) value. */
715 static uint8_t avr_core_gpwr_get (AvrCore *core, int reg);
716
717 /** \brief Writes a GPWR's (\a r0-r31) value. */
718 static void avr_core_gpwr_set (AvrCore *core, int reg, uint8_t val);
719
720 /*@}*/
721
722 /**
723 * \name Direct I/O Register Access Methods
724 *
725 * IO Registers are mapped in memory directly after the 32 (0x20)
726 * general registers.
727 */
728
729 /*@{*/
730
731 /** \brief Displays all registers. */
732 void
733 avr_core_io_display_names (AvrCore *core)
734 {
735 int i;
736 uint8_t val;
737 char name[80];
738
739 for (i = IO_REG_ADDR_BEGIN; i < IO_REG_ADDR_END; i++)
740 {
741 mem_io_fetch (core->mem, i, &val, name, sizeof (name) - 1);
742 display_io_reg_name (i - IO_REG_ADDR_BEGIN, name);
743 }
744 }
745
746 /** \brief Reads the value of a register.
747 * \param core Pointer to the core.
748 * \param reg The registers address. This address is counted above the
749 * beginning of the registers memory block (0x20).
750 */
751 extern inline uint8_t avr_core_io_read (AvrCore *core, int reg);
752
753 /** \brief Writes the value of a register.
754 * See avr_core_io_read() for a discussion of \a reg. */
755 extern inline void avr_core_io_write (AvrCore *core, int reg, uint8_t val);
756
757 /** \brief Read an io register into val and put the name of the register into
758 * buf. */
759 static void avr_core_io_fetch (AvrCore *core, int reg, uint8_t * val,
760 char *buf, int bufsiz);
761
762 /*@}*/
763
764 /** \name Stack Methods */
765
766 /*@{*/
767
768 /** \brief Pop 1-4 bytes off of the stack.
769 *
770 * See stack_pop() for more details.
771 */
772 extern inline uint32_t avr_core_stack_pop (AvrCore *core, int bytes);
773
774 /** \brief Push 1-4 bytes onto the stack.
775 *
776 * See stack_push() for more details.
777 */
778 extern inline void avr_core_stack_push (AvrCore *core, int bytes,
779 uint32_t val);
780
781 /*@}*/
782
783 /** \name Program Counter Methods */
784
785 /*@{*/
786
787 /** \brief Returns the size of the Program Counter in bytes.
788 *
789 * Most devices have a 16-bit PC (2 bytes), but some larger ones
790 * (e.g. mega256), have a 22-bit PC (3 bytes).
791 */
792 extern inline int32_t avr_core_PC_size (AvrCore *core);
793
794 /** \brief Returns the maximum value of the Program Counter.
795 *
796 * This is flash_size / 2.
797 */
798 static int32_t avr_core_PC_max (AvrCore *core);
799
800 /** \brief Return the current of the Program Counter. */
801 static int32_t avr_core_PC_get (AvrCore *core);
802
803 /** \brief Set the Program Counter to val.
804 *
805 * If val is not in the valid range of PC values, it is adjusted to fall in
806 * the valid range.
807 */
808 static void avr_core_PC_set (AvrCore *core, int32_t val);
809
810 /** \brief Increment the Program Counter by val.
811 *
812 * val can be either positive or negative.
813 *
814 * If the result of the incrememt is outside the valid range for PC, it is
815 * adjusted to fall in the valid range. This allows addresses to wrap around
816 * the end of the insn space.
817 */
818 extern inline void avr_core_PC_incr (AvrCore *core, int val);
819
820 /*@}*/
821
822 /** \name Methods for accessing CK and instruction Clocks */
823
824 /*@{*/
825
826 /** \brief Get the current clock counter. */
827 extern inline uint64_t avr_core_CK_get (AvrCore *core);
828
829 /** \brief Increment the clock counter. */
830 extern inline void avr_core_CK_incr (AvrCore *core);
831
832 /** \brief Get the number of clock cycles remaining for the currently
833 * executing instruction. */
834 extern inline int avr_core_inst_CKS_get (AvrCore *core);
835
836 /** \brief Set the number of clock cycles for the instruction being
837 * executed. */
838 extern inline void avr_core_inst_CKS_set (AvrCore *core, int val);
839
840 /** \name Interrupt Access Methods. */
841
842 /*@{*/
843
844 /** \brief Gets the first pending irq. */
845 IntVect *
846 avr_core_irq_get_pending (AvrCore *core)
847 {
848 return irq_get_pending_vector (core->irq_pending, core->state,
849 core->sleep_mode);
850 }
851
852 /** \brief Raises an irq by adding it's data to the irq_pending list. */
853 void
854 avr_core_irq_raise (AvrCore *core, unsigned int irq)
855 {
856 IntVect *irq_ptr = &core->irq_vtable[irq];
857
858 #if !defined(DISABLE_IRQ_MESSAGES)
859 avr_message ("Raising irq # %u [%s at 0x%x]\n", irq, irq_ptr->name,
860 irq_ptr->addr * 2);
861 #endif
862 core->irq_pending = irq_list_add (core->irq_pending, irq_ptr);
863 }
864
865 /** \brief Calls the interrupt's callback to clear the flag. */
866 void
867 avr_core_irq_clear (AvrCore *core, IntVect *irq)
868 {
869 core->irq_pending = irq_list_delete (core->irq_pending, irq);
870 }
871
872 /** \brief Removes all irqs from the irq_pending list. */
873 extern inline void avr_core_irq_clear_all (AvrCore *core);
874
875 /*@}*/
876
877 /** \name Break point access methods. */
878
879 /*@{*/
880
881 /** \brief Inserts a break point. */
882
883 void
884 avr_core_insert_breakpoint (AvrCore *core, int pc)
885 {
886 #define BREAK_OPCODE 0x9598
887
888 uint16_t insn = flash_read (core->flash, pc);
889
890 core->breakpoints = brk_pt_list_add (core->breakpoints, pc, insn);
891
892 flash_write (core->flash, pc, BREAK_OPCODE);
893 }
894
895 /** \brief Removes a break point. */
896
897 void
898 avr_core_remove_breakpoint (AvrCore *core, int pc)
899 {
900 BreakPt *bp;
901
902 bp = brk_pt_list_lookup (core->breakpoints, pc);
903 if (bp)
904 {
905 uint16_t insn = bp->opcode;
906
907 core->breakpoints = brk_pt_list_delete (core->breakpoints, pc);
908
909 flash_write (core->flash, pc, insn);
910 }
911 }
912
913 #ifndef DOXYGEN /* don't expose to doxygen */
914
915 struct bp_enable_data
916 {
917 AvrCore *core;
918 int enable;
919 };
920
921 #endif /* DOXYGEN */
922
923 static int
924 iter_enable_breakpoint (AvrClass *data, void *user_data)
925 {
926 BreakPt *bp = (BreakPt *)data;
927 struct bp_enable_data *bed = (struct bp_enable_data *)user_data;
928
929 if (bed->enable)
930 {
931 uint16_t insn = flash_read (bed->core->flash, bp->pc);
932
933 if (insn != BREAK_OPCODE)
934 {
935 /* Enable the breakpoint */
936 bp->opcode = insn;
937 flash_write (bed->core->flash, bp->pc, BREAK_OPCODE);
938 }
939 }
940 else
941 {
942 /* Disable the breakpoint */
943 flash_write (bed->core->flash, bp->pc, bp->opcode);
944 }
945
946 return 0; /* Don't delete any item from the list. */
947 }
948
949 /** \brief Disable breakpoints.
950
951 Disables all breakpoints that where set using avr_core_insert_breakpoint().
952 The breakpoints are not removed from the breakpoint list. */
953
954 void
955 avr_core_disable_breakpoints (AvrCore *core)
956 {
957 struct bp_enable_data bed = { core, 0 };
958
959 core->breakpoints =
960 brk_pt_iterator (core->breakpoints, iter_enable_breakpoint, &bed);
961 }
962
963 /** \brief Enable breakpoints.
964
965 Enables all breakpoints that where previous disabled. */
966
967 void
968 avr_core_enable_breakpoints (AvrCore *core)
969 {
970 struct bp_enable_data bed = { core, 1 };
971
972 core->breakpoints =
973 brk_pt_iterator (core->breakpoints, iter_enable_breakpoint, &bed);
974 }
975
976 /*@}*/
977
978 /* Private
979
980 Execute an instruction.
981 Presets the number of instruction clocks to zero so that break points and
982 invalid opcodes don't add extraneous clock counts.
983
984 Also checks for software breakpoints.
985 Any opcode except 0xffff can be a breakpoint.
986
987 Returns BREAK_POINT, or >= 0. */
988
989 static int
990 exec_next_instruction (AvrCore *core)
991 {
992 int result, pc;
993 uint16_t opcode;
994 struct opcode_info *opi;
995
996 pc = avr_core_PC_get (core);
997 opcode = flash_read (core->flash, pc);
998
999 /* Preset the number of instruction clocks to zero so that break points
1000 and invalid opcodes don't add extraneous clock counts. */
1001 avr_core_inst_CKS_set (core, 0);
1002
1003 opi = decode_opcode (opcode);
1004
1005 result = opi->func (core, opcode, opi->arg1, opi->arg2);
1006
1007 if (global_debug_inst_output)
1008 fprintf (stderr, "0x%06x (0x%06x) : 0x%04x : %s\n", pc, pc * 2,
1009 opcode, global_opcode_name[result]);
1010
1011 return result;
1012 }
1013
1014 /** \name Program control methods */
1015
1016 /*@{*/
1017
1018 /*
1019 * Private
1020 *
1021 * Checks to see if an interrupt is pending. If any are pending, and
1022 * if SREG(I) is set, the following will occur:
1023 * - push current PC onto stack
1024 * - PC <- interrupt vector
1025 * - I flag of SREG is cleared
1026 *
1027 * Reset vector is not controlled by the SREG(I) flag, thus if reset
1028 * interrupt has occurred, the device will be reset irregardless of state
1029 * of SREG(I).
1030 *
1031 * \note There are different ways of doing this:
1032 * - In register.c wdtcr_intr_cb() we can directly reset the MCU without
1033 * the use of irqs. This would require to make the callback an async
1034 * callback and it would allow the speed improvments commented out below
1035 * to be activated.
1036 * - Keep it as an interrupt an waste CPU time.
1037 *
1038 * Ted, what do you think we should do?
1039 */
1040
1041 static void
1042 avr_core_check_interrupts (AvrCore *core)
1043 {
1044 IntVect *irq;
1045
1046 if (core->irq_pending)
1047 {
1048 irq = avr_core_irq_get_pending (core);
1049
1050 if (irq)
1051 {
1052 if (irq->name == NULL)
1053 {
1054 avr_error ("Raised an invalid irq for device");
1055 }
1056
1057 if (irq->addr == IRQ_RESET_ADDR)
1058 {
1059 /* The global interrupt (SREG.I) never blocks a reset. We
1060 don't need to clear the irq since a reset clears all
1061 pending irq's. */
1062 avr_core_reset (core);
1063 }
1064
1065 if (avr_core_sreg_get_bit (core, SREG_I))
1066 {
1067 int pc = avr_core_PC_get (core);
1068 int pc_bytes = avr_core_PC_size (core);
1069
1070 avr_core_stack_push (core, pc_bytes, pc);
1071 avr_core_sreg_set_bit (core, SREG_I, 0);
1072
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);
1076 #endif
1077
1078 avr_core_PC_set (core, irq->addr + core->irq_offset);
1079
1080 avr_core_irq_clear (core, irq);
1081 }
1082 }
1083 }
1084 }
1085
1086 /**
1087 * \brief Process a single program instruction, all side effects and
1088 * peripheral stimulii.
1089 *
1090 * Executes instructions, calls callbacks, and checks for interrupts. */
1091
1092 int
1093 avr_core_step (AvrCore *core)
1094 {
1095 int res = 0;
1096 int state;
1097
1098 /* The MCU is stopped when in one of the many sleep modes */
1099 state = avr_core_get_state (core);
1100 if (state != STATE_SLEEP)
1101 {
1102 /* execute an instruction; may change state */
1103 res = exec_next_instruction (core);
1104 }
1105
1106 /* Execute the clock callbacks */
1107 while (core->inst_CKS > 0)
1108 {
1109 /* propagate clocks here */
1110 avr_core_clk_cb_exec (core);
1111
1112 avr_core_CK_incr (core);
1113
1114 core->inst_CKS--;
1115 }
1116
1117 /* FIXME: async cb's and interrupt checking might need to be put
1118 somewhere else. */
1119
1120 /* Execute the asynchronous callbacks */
1121 avr_core_async_cb_exec (core);
1122
1123 /* Check interrupts here. If the previous instruction was a reti, then we
1124 need to delay handling of any pending IRQs until after the next
1125 instruction is executed. */
1126 if (res != opcode_RETI)
1127 avr_core_check_interrupts (core);
1128
1129 return res;
1130 }
1131
1132 /** \brief Start the processing of instructions by the simulator.
1133 *
1134 * The simulated device will run until one of the following occurs:
1135 * - The state of the core is no longer STATE_RUNNING.
1136 * - The simulator receives a SIGINT signal.
1137 * - A breakpoint is reached (currently causes core to stop running).
1138 * - A fatal internal error occurs.
1139 *
1140 * \note When running simulavr in gdb server mode, this function is not
1141 * used. The avr_core_step() function is called repeatedly in a loop when the
1142 * continue command is issued from gdb. As such, the functionality in this
1143 * loop should be kept to a minimum.
1144 *
1145 * \todo Should add some basic breakpoint handling here. Maybe allow
1146 * continuing, and simple breakpoint management (disable, delete, set)
1147 */
1148
1149 void
1150 avr_core_run (AvrCore *core)
1151 {
1152 uint64_t cnt = 0;
1153 int res;
1154 uint64_t start_time, run_time;
1155
1156 avr_core_reset (core); /* make sure the device is in a sane state. */
1157
1158 core->state = STATE_RUNNING;
1159
1160 signal_watch_start (SIGINT);
1161
1162 /* FIXME: [TRoth 2002/03/19] This loop isn't going to handle sleep or idle
1163 modes properly. */
1164
1165 start_time = get_program_time ();
1166 while (core->state == STATE_RUNNING)
1167 {
1168 if (signal_has_occurred (SIGINT))
1169 break;
1170
1171 res = avr_core_step (core);
1172
1173 if (res == BREAK_POINT)
1174 break;
1175
1176 cnt++;
1177 }
1178 run_time = get_program_time () - start_time;
1179
1180 signal_watch_stop (SIGINT);
1181
1182 /* avoid division by zero below */
1183 if (run_time == 0) run_time = 1;
1184
1185 avr_message ("Run time was %lld.%03lld seconds.\n", run_time / 1000,
1186 run_time % 1000);
1187
1188 if (run_time == 0)
1189 run_time = 1; /* Avoid division by zero. */
1190
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));
1194 avr_message (" %lld clks/sec\n",
1195 (avr_core_CK_get (core) * 1000) / run_time);
1196 }
1197
1198 /** \brief Sets the simulated CPU back to its initial state.
1199 *
1200 * Zeroes out PC, IRQ's, clock, and memory.
1201 */
1202
1203 void
1204 avr_core_reset (AvrCore *core)
1205 {
1206 avr_core_PC_set (core, 0);
1207 avr_core_irq_clear_all (core);
1208
1209 avr_core_inst_CKS_set (core, 0);
1210
1211 /* Send clock cycles to display.
1212 Normaly the clockcycles must not be reset here!
1213 This leads to an error in the vcd file. */
1214
1215 display_clock (core->CK);
1216
1217 mem_reset (core->mem);
1218 }
1219
1220 /*@}*/
1221
1222 /** \name Callback Handling Methods */
1223
1224 /*@{*/
1225
1226 /**
1227 * \brief For adding external read and write callback functions.
1228 *
1229 * rd and wr should come in pairs, but it is safe to add
1230 * empty function via passing a NULL pointer for either function.
1231 *
1232 * \param core A pointer to an AvrCore object.
1233 *
1234 * \param port_id The ID for handling the simulavr inheritance model.
1235 *
1236 * \param ext_rd Function for the device core to call when it needs to
1237 * communicate with the external world via I/O Ports.
1238 *
1239 * \param ext_wr Function for the device core to call when it needs to
1240 * communicate with the external world via I/O Ports.
1241 *
1242 */
1243 void
1244 avr_core_add_ext_rd_wr (AvrCore *core, int addr, PortFP_ExtRd ext_rd,
1245 PortFP_ExtWr ext_wr)
1246 {
1247 Port *p = (Port *)mem_get_vdevice_by_addr (core->mem, addr);
1248
1249 if (p == NULL)
1250 {
1251 avr_warning ("Device does not have vdevice at 0x%04x.\n", addr);
1252 return;
1253 }
1254
1255 port_add_ext_rd_wr (p, ext_rd, ext_wr);
1256 }
1257
1258 /**
1259 * \brief Add a new clock callback to list.
1260 */
1261 extern inline void avr_core_clk_cb_add (AvrCore *core, CallBack *cb);
1262
1263 /**
1264 * \brief Add a new asynchronous callback to list.
1265 */
1266 extern inline void avr_core_async_cb_add (AvrCore *core, CallBack *cb);
1267
1268 /** \brief Run all the callbacks in the list.
1269
1270 If a callback returns non-zero (true), then it is done with it's job and
1271 wishes to be removed from the list.
1272
1273 The time argument has dual meaning. If the callback list is for the clock
1274 callbacks, time is the value of the CK clock counter. If the callback list
1275 is for the asynchronous callback, time is the number of milliseconds from
1276 some unknown, arbitrary time on the host system. */
1277
1278 extern inline void avr_core_clk_cb_exec (AvrCore *core);
1279
1280 /**
1281 * \brief Run all the asynchronous callbacks.
1282 */
1283 extern inline void avr_core_async_cb_exec (AvrCore *core);
1284
1285 /*@}*/
1286
1287 /**
1288 * \brief Dump the contents of the entire CPU core.
1289 *
1290 * \param core A pointer to an AvrCore object.
1291 * \param f_core An open file descriptor.
1292 */
1293 void
1294 avr_core_dump_core (AvrCore *core, FILE * f_core)
1295 {
1296 unsigned int pc = avr_core_PC_get (core);
1297
1298 fprintf (f_core, "PC = 0x%06x (PC*2 = 0x%06x)\n\n", pc, pc * 2);
1299 mem_dump_core (core->mem, f_core);
1300 flash_dump_core (core->flash, f_core);
1301 }
1302
1303 /**
1304 * \brief Load a program from an input file.
1305 */
1306 int
1307 avr_core_load_program (AvrCore *core, char *file, int format)
1308 {
1309 return flash_load_from_file (core->flash, file, format);
1310 }
1311
1312 /** \brief Load a program from an input file. */
1313 int
1314 avr_core_load_eeprom (AvrCore *core, char *file, int format)
1315 {
1316 EEProm *ee = (EEProm *)mem_get_vdevice_by_name (core->mem, "EEProm");
1317
1318 return eeprom_load_from_file (ee, file, format);
1319 }

Automatically generated by Doxygen 1.8.2 on Mon Aug 18 2014.