Commit d4032ea9fae0c8a6fdd020f4f8fd448a044757a3
authorMichel Pollet <buserror@gmail.com>
Sat, 25 Feb 2012 17:57:59 +0000 (17:57 +0000)
committerMichel Pollet <buserror@gmail.com>
Sat, 25 Feb 2012 17:57:59 +0000 (17:57 +0000)
Split the runtime data related to interrupts into it's own
struct, and updated anyone using it directly.
Ultimately it would be the goal not to have to pass an avr_t
around to all the functions.

Signed-off-by: Michel Pollet <buserror@gmail.com>
8 files changed:
simavr/sim/run_avr.c
simavr/sim/sim_avr.c
simavr/sim/sim_avr.h
simavr/sim/sim_cycle_timers.c
simavr/sim/sim_cycle_timers.h
simavr/sim/sim_interrupts.c
simavr/sim/sim_interrupts.h
tests/tests.c

index e43424fae5fa813af0e3cd00357edef7bb8a942a..0c1fddd74bc098f493ed9415e05dc1f26536092a 100644 (file)
@@ -153,8 +153,8 @@ int main(int argc, char *argv[])
        }
        avr->trace = trace;
        for (int ti = 0; ti < trace_vectors_count; ti++)
-               if (avr->vector[trace_vectors[ti]])
-                       avr->vector[trace_vectors[ti]]->trace++;
+               if (avr->interrupts.vector[trace_vectors[ti]])
+                       avr->interrupts.vector[trace_vectors[ti]]->trace = 1;
 
        // even if not setup at startup, activate gdb if crashing
        avr->gdb_port = 1234;
index 657131b3b490da84e521210a70f386154813eb01..6cda116dcb5b54ce28509c66b51f1267a01e87d4 100644 (file)
@@ -82,7 +82,8 @@ void avr_reset(avr_t * avr)
                avr->sreg[i] = 0;
        if (avr->reset)
                avr->reset(avr);
-
+       avr_interrupt_reset(avr);
+       avr_cycle_timer_reset(avr);
        avr_io_t * port = avr->io_port;
        while (port) {
                if (port->reset)
@@ -201,7 +202,7 @@ void avr_callback_run_gdb(avr_t * avr)
        // if we just re-enabled the interrupts...
        // double buffer the I flag, to detect that edge
        if (avr->sreg[S_I] && !avr->i_shadow)
-               avr->pending_wait++;
+               avr->interrupts.pending_wait++;
        avr->i_shadow = avr->sreg[S_I];
 
        // run the cycle timers, get the suggested sleep time
@@ -255,7 +256,7 @@ void avr_callback_run_raw(avr_t * avr)
        // if we just re-enabled the interrupts...
        // double buffer the I flag, to detect that edge
        if (avr->sreg[S_I] && !avr->i_shadow)
-               avr->pending_wait++;
+               avr->interrupts.pending_wait++;
        avr->i_shadow = avr->sreg[S_I];
 
        // run the cycle timers, get the suggested sleeo time
index a91c2b98b35ec1cfcc1471fb288d1ae7b584a1f4..6c0fc0388f7abaecd0a690d5ab0252eb254d39c3 100644 (file)
@@ -27,6 +27,7 @@ extern "C" {
 #endif
 
 #include "sim_irq.h"
+#include "sim_interrupts.h"
 #include "sim_cycle_timers.h"
 
 struct avr_t;
@@ -229,14 +230,10 @@ typedef struct avr_t {
        // queue of io modules
        struct avr_io_t *io_port;
 
+       // cycle timers tracking & delivery
        avr_cycle_timer_pool_t  cycle_timers;
-
-       // interrupt vectors, and their enable/clear registers
-       struct avr_int_vector_t * vector[64];
-       uint8_t         vector_count;
-       uint8_t         pending_wait;   // number of cycles to wait for pending
-       struct avr_int_vector_t * pending[64]; // needs to be >= vectors and a power of two
-       uint8_t         pending_w, pending_r;   // fifo cursors
+       // interrupt vectors and delivery fifo
+       avr_int_table_t interrupts;
 
        // DEBUG ONLY -- value ignored if CONFIG_SIMAVR_TRACE = 0
        int             trace : 1,
@@ -354,8 +351,6 @@ void avr_callback_run_raw(avr_t * avr);
 
 #include "sim_io.h"
 #include "sim_regbit.h"
-#include "sim_interrupts.h"
-#include "sim_cycle_timers.h"
 
 #endif /*__SIM_AVR_H__*/
 
index bca155cdd05a67b72dc9c8f1956cd88c62cf85e3..d11639c28beb9f545ae55ca81c8326c822aa6dec 100644 (file)
 #include "sim_time.h"
 #include "sim_cycle_timers.h"
 
+void
+avr_cycle_timer_reset(
+               struct avr_t * avr)
+{
+       avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
+       memset(pool, 0, sizeof(*pool));
+}
 
 // no sanity checks checking here, on purpose
 static void
index 7ec3f9e5677e353fc8cc91c6e39e7ad819bc91c5..9de7f40502beeb541327b564c9b75a10d9c61578 100644 (file)
@@ -92,6 +92,9 @@ avr_cycle_timer_status(
 avr_cycle_count_t
 avr_cycle_timer_process(
                struct avr_t * avr);
+void
+avr_cycle_timer_reset(
+               struct avr_t * avr);
 
 #ifdef __cplusplus
 };
index 689c90412130f6bebea165b5c752f75f279425d8..3e094e51f14f466a55b24d0071aebe7b06105b48 100644 (file)
 #include <string.h>
 #include <strings.h>
 #include "sim_interrupts.h"
+#include "sim_avr.h"
 #include "sim_core.h"
 
 // modulo a cursor value on the pending interrupt fifo
-#define INT_FIFO_SIZE (sizeof(avr->pending) / sizeof(avr_int_vector_t *))
+#define INT_FIFO_SIZE (sizeof(table->pending) / sizeof(avr_int_vector_t *))
 #define INT_FIFO_MOD(_v) ((_v) &  (INT_FIFO_SIZE - 1))
 
+void
+avr_interrupt_reset(
+               avr_t * avr )
+{
+       avr_int_table_p table = &avr->interrupts;
+       memset(table, 0, sizeof(*table));
+}
+
 void
 avr_register_vector(
                avr_t *avr,
                avr_int_vector_t * vector)
 {
-       if (vector->vector) {
-               vector->irq.irq = vector->vector;
-               avr->vector[avr->vector_count++] = vector;
-               if (vector->trace)
-                       printf("%s register vector %d (enabled %04x:%d)\n", __FUNCTION__, vector->vector, vector->enable.reg, vector->enable.bit);
+       if (!vector->vector)
+               return;
 
-               if (!vector->enable.reg)
-                       printf("avr_register_vector: No 'enable' bit on vector %d !\n", vector->vector);
-       }
+       avr_int_table_p table = &avr->interrupts;
+
+       vector->irq.irq = vector->vector;
+       table->vector[table->vector_count++] = vector;
+       if (vector->trace)
+               printf("%s register vector %d (enabled %04x:%d)\n", __FUNCTION__, vector->vector, vector->enable.reg, vector->enable.bit);
+
+       if (!vector->enable.reg)
+               printf("avr_register_vector: No 'enable' bit on vector %d !\n", vector->vector);
 }
 
 int
 avr_has_pending_interrupts(
                avr_t * avr)
 {
-       return avr->pending_r != avr->pending_w;
+       avr_int_table_p table = &avr->interrupts;
+       return table->pending_r != table->pending_w;
 }
 
 int
@@ -92,15 +105,18 @@ avr_raise_interrupt(
 
        // Mark the interrupt as pending
        vector->pending = 1;
-       avr->pending[avr->pending_w++] = vector;
-       avr->pending_w = INT_FIFO_MOD(avr->pending_w);
+
+       avr_int_table_p table = &avr->interrupts;
+
+       table->pending[table->pending_w++] = vector;
+       table->pending_w = INT_FIFO_MOD(table->pending_w);
 
        avr_raise_irq(&vector->irq, 1);
 
        // If the interrupt is enabled, attempt to wake the core
        if (avr_regbit_get(avr, vector->enable)) {
-               if (!avr->pending_wait)
-                       avr->pending_wait = 1;          // latency on interrupts ??
+               if (!table->pending_wait)
+                       table->pending_wait = 1;                // latency on interrupts ??
                if (avr->state != cpu_Running) {
                        if (vector->trace)
                                printf("Waking CPU due to interrupt\n");
@@ -146,9 +162,10 @@ avr_get_interrupt_irq(
                avr_t * avr,
                uint8_t v)
 {
-       for (int i = 0; i < avr->vector_count; i++)
-               if (avr->vector[i]->vector == v)
-                       return &avr->vector[i]->irq;
+       avr_int_table_p table = &avr->interrupts;
+       for (int i = 0; i < table->vector_count; i++)
+               if (table->vector[i]->vector == v)
+                       return &table->vector[i]->irq;
        return NULL;
 }
 
@@ -166,35 +183,37 @@ avr_service_interrupts(
        if (!avr_has_pending_interrupts(avr))
                return;
 
-       if (!avr->pending_wait) {
-               avr->pending_wait = 2;  // for next one...
+       avr_int_table_p table = &avr->interrupts;
+
+       if (!table->pending_wait) {
+               table->pending_wait = 2;        // for next one...
                return;
        }
-       avr->pending_wait--;
-       if (avr->pending_wait)
+       table->pending_wait--;
+       if (table->pending_wait)
                return;
 
        // how many are pending...
-       int cnt = avr->pending_w > avr->pending_r ?
-                       avr->pending_w - avr->pending_r :
-                       (avr->pending_w+INT_FIFO_SIZE) - avr->pending_r;
+       int cnt = table->pending_w > table->pending_r ?
+                       table->pending_w - table->pending_r :
+                       (table->pending_w + INT_FIFO_SIZE) - table->pending_r;
        // locate the highest priority one
        int min = 0xff;
        int mini = 0;
        for (int ii = 0; ii < cnt; ii++) {
-               int vi = INT_FIFO_MOD(avr->pending_r + ii);
-               avr_int_vector_t * v = avr->pending[vi];
+               int vi = INT_FIFO_MOD(table->pending_r + ii);
+               avr_int_vector_t * v = table->pending[vi];
                if (v->vector < min) {
                        min = v->vector;
                        mini = vi;
                }
        }
-       avr_int_vector_t * vector = avr->pending[mini];
+       avr_int_vector_t * vector = table->pending[mini];
 
        // now move the one at the front of the fifo in the slot of
        // the one we service
-       avr->pending[mini] = avr->pending[avr->pending_r++];
-       avr->pending_r = INT_FIFO_MOD(avr->pending_r);
+       table->pending[mini] = table->pending[table->pending_r++];
+       table->pending_r = INT_FIFO_MOD(table->pending_r);
 
        // if that single interrupt is masked, ignore it and continue
        // could also have been disabled, or cleared
index e98659e2046f2104be6dfd465ce942aaaf33bbf2..148b28c6c0334a3128818d5e1bec1d62f59f2d0a 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef __SIM_INTERRUPTS_H__
 #define __SIM_INTERRUPTS_H__
 
-#include "sim_avr.h"
+#include "sim_avr_types.h"
 #include "sim_irq.h"
 
 #ifdef __cplusplus
@@ -31,51 +31,62 @@ extern "C" {
 
 // interrupt vector for the IO modules
 typedef struct avr_int_vector_t {
-       uint8_t pending : 1, vector;    // vector number, zero (reset) is reserved
-       avr_regbit_t enable;    // IO register index for the "interrupt enable" flag for this vector
-       avr_regbit_t raised;    // IO register index for the register where the "raised" flag is (optional)
+       uint8_t                 vector;                 // vector number, zero (reset) is reserved
+       avr_regbit_t    enable;                 // IO register index for the "interrupt enable" flag for this vector
+       avr_regbit_t    raised;                 // IO register index for the register where the "raised" flag is (optional)
 
-       avr_irq_t               irq;            // raised to 1 when queued, to zero when called
-       uint8_t                 trace;          // only for debug of a vector
+       avr_irq_t               irq;                    // raised to 1 when queued, to zero when called
+       uint8_t                 pending : 1,    // 1 while scheduled in the fifo
+                                       trace : 1;              // only for debug of a vector
 } avr_int_vector_t;
 
+// interrupt vectors, and their enable/clear registers
+typedef struct  avr_int_table_t {
+       avr_int_vector_t * vector[64];
+       uint8_t                 vector_count;
+       uint8_t                 pending_wait;   // number of cycles to wait for pending
+       avr_int_vector_t * pending[64]; // needs to be >= vectors and a power of two
+       uint8_t                 pending_w,
+                                       pending_r;      // fifo cursors
+} avr_int_table_t, *avr_int_table_p;
+
 /*
  * Interrupt Helper Functions
  */
 // register an interrupt vector. It's only needed if you want to use the "r_raised" flags
 void
 avr_register_vector(
-               avr_t *avr,
+               struct avr_t *avr,
                avr_int_vector_t * vector);
 // raise an interrupt (if enabled). The interrupt is latched and will be called later
 // return non-zero if the interrupt was raised and is now pending
 int
 avr_raise_interrupt(
-               avr_t * avr,
+               struct avr_t * avr,
                avr_int_vector_t * vector);
 // return non-zero if the AVR core has any pending interrupts
 int
 avr_has_pending_interrupts(
-               avr_t * avr);
+               struct avr_t * avr);
 // return nonzero if a specific interrupt vector is pending
 int
 avr_is_interrupt_pending(
-               avr_t * avr,
+               struct avr_t * avr,
                avr_int_vector_t * vector);
 // clear the "pending" status of an interrupt
 void
 avr_clear_interrupt(
-               avr_t * avr,
+               struct avr_t * avr,
                avr_int_vector_t * vector);
 // called by the core at each cycle to check whether an interrupt is pending
 void
 avr_service_interrupts(
-               avr_t * avr);
+               struct avr_t * avr);
 
 // clear the interrupt (inc pending) if "raised" flag is 1
 int
 avr_clear_interrupt_if(
-               avr_t * avr,
+               struct avr_t * avr,
                avr_int_vector_t * vector,
                uint8_t old);
 
@@ -83,9 +94,14 @@ avr_clear_interrupt_if(
 // this allows tracing of pending interrupts
 avr_irq_t *
 avr_get_interrupt_irq(
-               avr_t * avr,
+               struct avr_t * avr,
                uint8_t v);
 
+// reset the interrupt table and the fifo
+void
+avr_interrupt_reset(
+               struct avr_t * avr );
+
 #ifdef __cplusplus
 };
 #endif
index c21b1ac46bf6a8ac4610f2ef1a35df6e70ef841c..f389f4dbb8f79ee17f4230787fa1727b014a49c3 100644 (file)
@@ -60,7 +60,7 @@ static int my_avr_run(avr_t * avr)
        // if we just re-enabled the interrupts...
        // double buffer the I flag, to detect that edge
        if (avr->sreg[S_I] && !avr->i_shadow)
-               avr->pending_wait++;
+               avr->interrupts.pending_wait++;
        avr->i_shadow = avr->sreg[S_I];
 
        // run the cycle timers, get the suggested sleep time