/*
sim_avr.h
- Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
+ Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
This file is part of simavr.
#ifndef __SIM_AVR_H__
#define __SIM_AVR_H__
-#include <stdint.h>
-
#ifdef __cplusplus
extern "C" {
#endif
#include "sim_irq.h"
-
-typedef uint64_t avr_cycle_count_t;
-typedef uint16_t avr_io_addr_t;
+#include "sim_interrupts.h"
+#include "sim_cycle_timers.h"
struct avr_t;
-typedef uint8_t (*avr_io_read_t)(struct avr_t * avr, avr_io_addr_t addr, void * param);
-typedef void (*avr_io_write_t)(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param);
-typedef avr_cycle_count_t (*avr_cycle_timer_t)(struct avr_t * avr, avr_cycle_count_t when, void * param);
+typedef uint8_t (*avr_io_read_t)(
+ struct avr_t * avr,
+ avr_io_addr_t addr,
+ void * param);
+typedef void (*avr_io_write_t)(
+ struct avr_t * avr,
+ avr_io_addr_t addr,
+ uint8_t v,
+ void * param);
enum {
// SREG bit indexes
R_SREG = 32+0x3f,
// maximum number of IO registers, on normal AVRs
- MAX_IOs = 256 - 32, // minus 32 GP registers
+ MAX_IOs = 256, // Bigger AVRs need more than 256-32 (mega1280)
};
#define AVR_DATA_TO_IO(v) ((v) - 32)
cpu_Step, // run ONE instruction, then...
cpu_StepDone, // tell gdb it's all OK, and give it registers
+ cpu_Done, // avr software stopped gracefully
+ cpu_Crashed, // avr software crashed (watchdog fired)
+};
+
+// this is only ever used if CONFIG_SIMAVR_TRACE is defined
+struct avr_trace_data_t {
+ struct avr_symbol_t ** codeline;
+
+ /* DEBUG ONLY
+ * this keeps track of "jumps" ie, call,jmp,ret,reti and so on
+ * allows dumping of a meaningful data even if the stack is
+ * munched and so on
+ */
+ #define OLD_PC_SIZE 32
+ struct {
+ uint32_t pc;
+ uint16_t sp;
+ } old[OLD_PC_SIZE]; // catches reset..
+ int old_pci;
+
+#if AVR_STACK_WATCH
+ #define STACK_FRAME_SIZE 32
+ // this records the call/ret pairs, to try to catch
+ // code that munches the stack -under- their own frame
+ struct {
+ uint32_t pc;
+ uint16_t sp;
+ } stack_frame[STACK_FRAME_SIZE];
+ int stack_frame_index;
+#endif
+
+ // DEBUG ONLY
+ // keeps track of which registers gets touched by instructions
+ // reset before each new instructions. Allows meaningful traces
+ uint32_t touched[256 / 32]; // debug
};
/*
// queue of io modules
struct avr_io_t *io_port;
- // cycle timers are callbacks that will be called when "when" cycle is reached
- // the bitmap allows quick knowledge of whether there is anything to call
- // these timers are one shots, then get cleared if the timer function returns zero,
- // they get reset if the callback function returns a new cycle number
- uint32_t cycle_timer_map;
- avr_cycle_count_t next_cycle_timer;
- struct {
- avr_cycle_count_t when;
- avr_cycle_timer_t timer;
- void * param;
- } cycle_timer[32];
-
- // interrupt vectors, and their enable/clear registers
- struct avr_int_vector_t * vector[64];
- uint8_t pending_wait; // number of cycles to wait for pending
- uint32_t pending[2]; // pending interrupts
+ // cycle timers tracking & delivery
+ avr_cycle_timer_pool_t cycle_timers;
+ // interrupt vectors and delivery fifo
+ avr_int_table_t interrupts;
// DEBUG ONLY -- value ignored if CONFIG_SIMAVR_TRACE = 0
- int trace;
+ int trace : 1,
+ log : 2; // log level, default to 1
-#if CONFIG_SIMAVR_TRACE
- struct avr_symbol_t ** codeline;
-
- /* DEBUG ONLY
- * this keeps track of "jumps" ie, call,jmp,ret,reti and so on
- * allows dumping of a meaningful data even if the stack is
- * munched and so on
- */
- #define OLD_PC_SIZE 32
- struct {
- uint32_t pc;
- uint16_t sp;
- } old[OLD_PC_SIZE]; // catches reset..
- int old_pci;
-
-#if AVR_STACK_WATCH
- #define STACK_FRAME_SIZE 32
- // this records the call/ret pairs, to try to catch
- // code that munches the stack -under- their own frame
- struct {
- uint32_t pc;
- uint16_t sp;
- } stack_frame[STACK_FRAME_SIZE];
- int stack_frame_index;
-#endif
-
- // DEBUG ONLY
- // keeps track of which registers gets touched by instructions
- // reset before each new instructions. Allows meaningful traces
- uint32_t touched[256 / 32]; // debug
-#endif
+ // Only used if CONFIG_SIMAVR_TRACE is defined
+ struct avr_trace_data_t *trace_data;
// VALUE CHANGE DUMP file (waveforms)
// this is the VCD file that gets allocated if the
} avr_symbol_t;
// locate the maker for mcu "name" and allocates a new avr instance
-avr_t * avr_make_mcu_by_name(const char *name);
+avr_t *
+avr_make_mcu_by_name(
+ const char *name);
// initializes a new AVR instance. Will call the IO registers init(), and then reset()
-int avr_init(avr_t * avr);
+int
+avr_init(
+ avr_t * avr);
// resets the AVR, and the IO modules
-void avr_reset(avr_t * avr);
+void
+avr_reset(
+ avr_t * avr);
// run one cycle of the AVR, sleep if necessary
-int avr_run(avr_t * avr);
+int
+avr_run(
+ avr_t * avr);
// finish any pending operations
-void avr_terminate(avr_t * avr);
+void
+avr_terminate(
+ avr_t * avr);
// set an IO register to receive commands from the AVR firmware
// it's optional, and uses the ELF tags
-void avr_set_command_register(avr_t * avr, avr_io_addr_t addr);
+void
+avr_set_command_register(
+ avr_t * avr,
+ avr_io_addr_t addr);
// specify the "console register" -- output sent to this register
// is printed on the simulator console, without using a UART
-void avr_set_console_register(avr_t * avr, avr_io_addr_t addr);
+void
+avr_set_console_register(
+ avr_t * avr,
+ avr_io_addr_t addr);
// load code in the "flash"
-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,
+ uint32_t address);
/*
* these are accessors for avr->data but allows watchpoints to be set for gdb
* IO modules use that to set values to registers, and the AVR core decoder uses
* that to register "public" read by instructions.
*/
-void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v);
-uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr);
+void
+avr_core_watch_write(
+ avr_t *avr,
+ uint16_t addr,
+ uint8_t v);
+uint8_t
+avr_core_watch_read(
+ avr_t *avr,
+ uint16_t addr);
// called when the core has detected a crash somehow.
// this might activate gdb server
-void avr_sadly_crashed(avr_t *avr, uint8_t signal);
+void
+avr_sadly_crashed(
+ avr_t *avr,
+ uint8_t signal);
/*
#include "sim_io.h"
#include "sim_regbit.h"
-#include "sim_interrupts.h"
-#include "sim_cycle_timers.h"
#endif /*__SIM_AVR_H__*/