* common/aclocal.m4: Pass ../../intl to ZW_GNU_GETTEXT_SISTER_DIR.
[deliverable/binutils-gdb.git] / sim / mips / dv-tx3904irc.c
index f11f4c0ae9659eb5560fed766dc0f33b6c9a3457..8b84e5c7d28b0000f1a1aefd29716693bd388a11 100644 (file)
@@ -21,7 +21,7 @@
 
 
 #include "sim-main.h"
-#include "hw-base.h"
+#include "hw-main.h"
 
 
 /* DEVICE
    
    Implements the tx3904 interrupt controller described in the tx3904
    user guide.  It does not include the interrupt detection circuit
-   that preprocesses the eight external interrupts.
+   that preprocesses the eight external interrupts, so assumes that
+   each event on an input interrupt port signals a new interrupt.
+   That is, it implements edge- rather than level-triggered
+   interrupts.
+
+   This implementation does not support multiple concurrent
+   interrupts.
 
 
    PROPERTIES
    that even though INT[0] is tied externally to IP[5], we simulate
    it as passing through the controller.
 
+   An output level of zero signals the clearing of a level interrupt.
+
 
    int0-7 (input)
 
-   External interrupts.
+   External interrupts.  Level = 0 -> level interrupt cleared.
 
    
    dmac0-3 (input)
 
-   DMA internal interrupts, correspond to DMA channels 0-3.
+   DMA internal interrupts, correspond to DMA channels 0-3.  Level = 0 -> level interrupt cleared.
 
 
    sio0-1 (input)
 
-   SIO internal interrupts.
+   SIO internal interrupts.  Level = 0 -> level interrupt cleared.
 
 
    tmr0-2 (input)
 
-   Timer internal interrupts.
+   Timer internal interrupts.  Level = 0 -> level interrupt cleared.
 
    */
 
 
 
+
+
+/* register numbers; each is one word long */
+enum
+{
+  ISR_REG = 0,
+  IMR_REG = 1,
+  ILR0_REG = 4,
+  ILR1_REG = 5,
+  ILR2_REG = 6,
+  ILR3_REG = 7,
+};
+
+
 /* port ID's */
 
-enum {
+enum
+{
   /* inputs, ordered to correspond to interrupt sources 0..15 */
   INT1_PORT = 0, INT2_PORT, INT3_PORT, INT4_PORT, INT5_PORT, INT6_PORT, INT7_PORT,
   DMAC3_PORT, DMAC2_PORT, DMAC1_PORT, DMAC0_PORT, SIO0_PORT, SIO1_PORT,
@@ -108,18 +131,6 @@ enum {
 };
 
 
-/* register numbers; each is one word long */
-enum {
-  ISR_REG = 0,
-  IMR_REG = 1,
-  ILR0_REG = 4,
-  ILR1_REG = 5,
-  ILR2_REG = 6,
-  ILR3_REG = 7,
-};
-
-
-
 static const struct hw_port_descriptor tx3904irc_ports[] = {
 
   /* interrupt output */
@@ -178,9 +189,9 @@ struct tx3904irc {
 /* Finish off the partially created hw device.  Attach our local
    callbacks.  Wire up our port names etc */
 
-static hw_io_read_buffer_callback tx3904irc_io_read_buffer;
-static hw_io_write_buffer_callback tx3904irc_io_write_buffer;
-static hw_port_event_callback tx3904irc_port_event;
+static hw_io_read_buffer_method tx3904irc_io_read_buffer;
+static hw_io_write_buffer_method tx3904irc_io_write_buffer;
+static hw_port_event_method tx3904irc_port_event;
 
 static void
 attach_tx3904irc_regs (struct hw *me,
@@ -217,7 +228,6 @@ attach_tx3904irc_regs (struct hw *me,
 static void
 tx3904irc_finish (struct hw *me)
 {
-  int i;
   struct tx3904irc *controller;
 
   controller = HW_ZALLOC (me, struct tx3904irc);
@@ -246,12 +256,20 @@ tx3904irc_finish (struct hw *me)
 static void
 tx3904irc_port_event (struct hw *me,
                     int my_port,
-                    struct hw *source,
+                    struct hw *source_dev,
                     int source_port,
                     int level)
 {
   struct tx3904irc *controller = hw_data (me);
 
+  /* handle deactivated interrupt */
+  if(level == 0)
+    {
+      HW_TRACE ((me, "interrupt cleared on port %d", my_port));
+      hw_port_event(me, IP_PORT, 0);
+      return;
+    }
+
   switch (my_port)
     {
     case INT0_PORT: 
@@ -269,7 +287,7 @@ tx3904irc_port_event (struct hw *me,
       {
        int source = my_port - INT1_PORT;
 
-       HW_TRACE ((me, "port-event interrupt source %d", source));
+       HW_TRACE ((me, "interrupt asserted on port %d", source));
        ISR_SET(controller, source);
        if(ILR_GET(controller, source) > IMR_GET(controller))
          {
@@ -336,7 +354,8 @@ tx3904irc_io_read_buffer (struct hw *me,
        }
 
       /* write requested byte out */
-      memcpy(dest+byte, ((char*)& register_value)+reg_offset, 1);
+      register_value = H2T_4(register_value);
+      memcpy ((char*) dest + byte, ((char*)& register_value)+reg_offset, 1);
     }
 
   return nr_bytes;
@@ -375,18 +394,20 @@ tx3904irc_io_write_buffer (struct hw *me,
        default: register_ptr = & register_value; /* used as a dummy */
        }
 
-      HW_TRACE ((me, "reg %d pre: %08lx", reg_number, (long) *register_ptr));
+      /* HW_TRACE ((me, "reg %d pre: %08lx", reg_number, (long) *register_ptr)); */
 
       /* overwrite requested byte */
-      memcpy(((char*)register_ptr)+reg_offset, source+byte, 1);
+      register_value = H2T_4(* register_ptr);
+      memcpy (((char*)&register_value)+reg_offset, (const char*)source + byte, 1);
+      * register_ptr = T2H_4(register_value);
 
-      HW_TRACE ((me, "post: %08lx", (long) *register_ptr));
+      /* HW_TRACE ((me, "post: %08lx", (long) *register_ptr)); */
     }
   return nr_bytes;
 }     
 
 
-const struct hw_device_descriptor dv_tx3904irc_descriptor[] = {
+const struct hw_descriptor dv_tx3904irc_descriptor[] = {
   { "tx3904irc", tx3904irc_finish, },
   { NULL },
 };
This page took 0.024682 seconds and 4 git commands to generate.