* Updates to tx3904 peripheral simulations for ECC.
authorFrank Ch. Eigler <fche@redhat.com>
Tue, 9 Jun 1998 16:54:09 +0000 (16:54 +0000)
committerFrank Ch. Eigler <fche@redhat.com>
Tue, 9 Jun 1998 16:54:09 +0000 (16:54 +0000)
Tue Jun  9 12:29:50 1998  Frank Ch. Eigler  <fche@cygnus.com>
* dv-tx3904cpu.c (deliver_*_interrupt,*_port_event): Set the CAUSE
  register upon non-zero interrupt event level, clear upon zero
  event value.
* dv-tx3904irc.c (*_port_event): Handle deactivated interrupt signal
by passing zero event value.
(*_io_{read,write}_buffer): Endianness fixes.
* dv-tx3904tmr.c (*_io_{read,write}_buffer): Endianness fixes.
(deliver_*_tick): Reduce sim event interval to 75% of count interval.
* interp.c (sim_open): Added jmr3904pal board type that adds PAL-based
serial I/O and timer module at base address 0xFFFF0000.

sim/mips/ChangeLog
sim/mips/dv-tx3904cpu.c
sim/mips/dv-tx3904tmr.c
sim/mips/interp.c

index ce005707b3f8266cbd8a896338481f3638b2db97..65280f322ea56fd82d5003c98e88c7b73afebfa1 100644 (file)
@@ -1,3 +1,19 @@
+start-sanitize-tx3904
+Tue Jun  9 12:29:50 1998  Frank Ch. Eigler  <fche@cygnus.com>
+
+       * dv-tx3904cpu.c (deliver_*_interrupt,*_port_event): Set the CAUSE
+       register upon non-zero interrupt event level, clear upon zero
+       event value.
+       * dv-tx3904irc.c (*_port_event): Handle deactivated interrupt signal
+       by passing zero event value.
+       (*_io_{read,write}_buffer): Endianness fixes.
+       * dv-tx3904tmr.c (*_io_{read,write}_buffer): Endianness fixes.
+       (deliver_*_tick): Reduce sim event interval to 75% of count interval.
+
+       * interp.c (sim_open): Added jmr3904pal board type that adds PAL-based
+       serial I/O and timer module at base address 0xFFFF0000.
+       
+end-sanitize-tx3904
 Tue Jun  9 11:52:29 1998  Gavin Koch  <gavin@cygnus.com>
 
        * mips.igen (SWC1) : Correct the handling of ReverseEndian 
index d043253ac497504f3392fa2dd69d066a0e18cf60..a040d4c8163ce8c115f4e505135ebe83ce13791b 100644 (file)
@@ -1,4 +1,4 @@
-/*  This file is part of the program GDB, the GU debugger.
+/*  This file is part of the program GDB, the GNU debugger.
     
     Copyright (C) 1998 Free Software Foundation, Inc.
     Contributed by Cygnus Solutions.
@@ -163,24 +163,28 @@ deliver_tx3904cpu_interrupt (struct hw *me,
                 controller->pending_level,
                 (long) CIA_GET (cpu), (long) SR));
 
-      /* Don't overwrite the CAUSE field since we have no good place to clear
-        it again.  The specs allow it to be zero by the time the interrupt
-        handler is invoked. */
-      /* CAUSE &= ~ (cause_IP_mask << cause_IP_shift);
-        CAUSE |= (controller->pending_level & cause_IP_mask) << cause_IP_shift; */
+      /* Clear CAUSE register.  It may stay this way if the interrupt
+        was cleared with a negative pending_level. */
+      CAUSE &= ~ (cause_IP_mask << cause_IP_shift);
 
-      /* check for enabled / unmasked interrupts */
-      if((SR & status_IEc) &&
-        (controller->pending_level & ((SR >> status_IM_shift) & status_IM_mask)))
+      if(controller->pending_level > 0) /* interrupt set */
        {
-         controller->pending_level = 0;
-         SignalExceptionInterrupt();
-       }
-      else
-       {
-         /* reschedule soon */
-         hw_event_queue_schedule (me, 1, deliver_tx3904cpu_interrupt, NULL);
-       }
+         /* set hardware-interrupt subfields of CAUSE register */
+         CAUSE |= (controller->pending_level & cause_IP_mask) << cause_IP_shift;
+
+         /* check for enabled / unmasked interrupts */
+         if((SR & status_IEc) &&
+            (controller->pending_level & ((SR >> status_IM_shift) & status_IM_mask)))
+           {
+             controller->pending_level = 0;
+             SignalExceptionInterrupt();
+           }
+         else
+           {
+             /* reschedule soon */
+             hw_event_queue_schedule (me, 1, deliver_tx3904cpu_interrupt, NULL);
+           }
+       } /* interrupt set */
     }
 #undef CPU cpu
 #undef SD current_state
@@ -209,7 +213,11 @@ tx3904cpu_port_event (struct hw *me,
       break;
       
     case LEVEL_PORT:
-      controller->pending_level |= level; /* accumulate bits until they are cleared */
+      /* level == 0 means that the interrupt was cleared */
+      if(level == 0)
+       controller->pending_level = -1; /* signal end of interrupt */
+      else
+       controller->pending_level = level;
       HW_TRACE ((me, "port-in level=%d", level));
       break;
       
index b1014218a5e131ffb361d19771ddfdaac8d4bcaa..b27e9b0bfbf654d27103d950df32cb82f625c1af 100644 (file)
@@ -324,7 +324,7 @@ tx3904tmr_io_read_buffer (struct hw *me,
     {
       address_word address = base + byte;
       int reg_number = (address - controller->base_address) / 4;
-      int reg_offset = (address - controller->base_address) % 4;
+      int reg_offset = 3 - (address - controller->base_address) % 4;
       unsigned_4 register_value; /* in target byte order */
 
       /* fill in entire register_value word */
@@ -367,7 +367,7 @@ tx3904tmr_io_write_buffer (struct hw *me,
       address_word address = base + byte;
       unsigned_1 write_byte = ((char*) source)[byte];
       int reg_number = (address - controller->base_address) / 4;
-      int reg_offset = (address - controller->base_address) % 4;
+      int reg_offset = 3 - (address - controller->base_address) % 4;
       unsigned_4* register_ptr;
       unsigned_4 register_value;
 
@@ -384,9 +384,8 @@ tx3904tmr_io_write_buffer (struct hw *me,
              if(GET_TCR_TCE(controller) == 0 &&
                 GET_TCR_CRE(controller) == 1)
                controller->trr = 0;
-
            }
-         HW_TRACE ((me, "tcr: %08lx", (long) controller->tcr));
+         /* HW_TRACE ((me, "tcr: %08lx", (long) controller->tcr)); */
          break;
 
        case ITMR_REG:
@@ -398,7 +397,7 @@ tx3904tmr_io_write_buffer (struct hw *me,
            {
              SET_ITMR_TZCE(controller, write_byte & 0x01);
            }
-         HW_TRACE ((me, "itmr: %08lx", (long) controller->itmr));
+         /* HW_TRACE ((me, "itmr: %08lx", (long) controller->itmr)); */
          break;
 
        case CCDR_REG:
@@ -406,7 +405,7 @@ tx3904tmr_io_write_buffer (struct hw *me,
            {
              controller->ccdr = write_byte & 0x07;
            }
-         HW_TRACE ((me, "ccdr: %08lx", (long) controller->ccdr));
+         /* HW_TRACE ((me, "ccdr: %08lx", (long) controller->ccdr)); */
          break;
 
        case PMGR_REG:
@@ -419,7 +418,7 @@ tx3904tmr_io_write_buffer (struct hw *me,
            {
              SET_PMGR_FFI(controller, write_byte & 0x01);
            }
-         HW_TRACE ((me, "pmgr: %08lx", (long) controller->pmgr));
+         /* HW_TRACE ((me, "pmgr: %08lx", (long) controller->pmgr)); */
          break;
 
        case WTMR_REG:
@@ -432,7 +431,7 @@ tx3904tmr_io_write_buffer (struct hw *me,
              SET_WTMR_WDIS(controller, write_byte & 0x80);
              SET_WTMR_TWC(controller, write_byte & 0x01);
            }
-         HW_TRACE ((me, "wtmr: %08lx", (long) controller->wtmr));
+         /* HW_TRACE ((me, "wtmr: %08lx", (long) controller->wtmr)); */
          break;
 
        case TISR_REG:
@@ -450,23 +449,23 @@ tx3904tmr_io_write_buffer (struct hw *me,
              /* clear interrupt status register */
              controller->tisr = 0;
            }
-         HW_TRACE ((me, "tisr: %08lx", (long) controller->tisr));
+         /* HW_TRACE ((me, "tisr: %08lx", (long) controller->tisr)); */
          break;
 
        case CPRA_REG:
          if(reg_offset < 3) /* first, second, or third byte */
            {
-             MBLIT32(controller->cpra, (reg_offset*8), (reg_offset*8+7), write_byte);
+             MBLIT32(controller->cpra, (reg_offset*8)+7, (reg_offset*8), write_byte);
            }
-         HW_TRACE ((me, "cpra: %08lx", (long) controller->cpra));
+         /* HW_TRACE ((me, "cpra: %08lx", (long) controller->cpra)); */
          break;
 
        case CPRB_REG:
          if(reg_offset < 3) /* first, second, or third byte */
            {
-             MBLIT32(controller->cprb, (reg_offset*8), (reg_offset*8+7), write_byte);
+             MBLIT32(controller->cprb, (reg_offset*8)+7, (reg_offset*8), write_byte);
            }
-         HW_TRACE ((me, "cprb: %08lx", (long) controller->cprb));
+         /* HW_TRACE ((me, "cprb: %08lx", (long) controller->cprb)); */
          break;
 
        default: 
@@ -667,9 +666,9 @@ deliver_tx3904tmr_tick (struct hw *me,
     } /* end quotient loop */
 
   /* Reschedule a timer event in near future, so we can increment the
-     counter again.  Set the event about 50% of divisor time away, so
-     we will experience roughly two events per counter increment. */
-  hw_event_queue_schedule(me, divisor/2, deliver_tx3904tmr_tick, NULL);
+     counter again.  Set the event about 75% of divisor time away, so
+     we will experience roughly 1.3 events per counter increment. */
+  hw_event_queue_schedule(me, divisor*3/4, deliver_tx3904tmr_tick, NULL);
 }
 
 
index f35674a2d8b04e473a4562241b1a3e61b6b9a4c6..104e0d88fc677c1b5be3723d44a2fbad1b306050 100644 (file)
@@ -363,6 +363,8 @@ static const OPTION mips_options[] =
 /* start-sanitize-tx3904 */
 #define BOARD_JMR3904 "jmr3904"
            "|" BOARD_JMR3904
+#define BOARD_JMR3904_PAL "jmr3904pal"
+           "|" BOARD_JMR3904_PAL
 #define BOARD_JMR3904_DEBUG "jmr3904debug"
            "|" BOARD_JMR3904_DEBUG
 /* end-sanitize-tx3904 */
@@ -481,6 +483,7 @@ sim_open (kind, cb, abfd, argv)
 #if (WITH_HW)
   if (board != NULL
       && (strcmp(board, BOARD_JMR3904) == 0 ||
+         strcmp(board, BOARD_JMR3904_PAL) == 0 ||
          strcmp(board, BOARD_JMR3904_DEBUG) == 0))
     {
       /* match VIRTUAL memory layout of JMR-TX3904 board */
@@ -518,6 +521,19 @@ sim_open (kind, cb, abfd, argv)
       sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
       sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
 
+      /* add PAL timer & I/O module */
+      if(! strcmp(board, BOARD_JMR3904_PAL))
+       {
+        /* the device */
+        sim_hw_parse (sd, "/pal@0xffff0000");
+        sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
+
+        /* wire up interrupt ports to irc */
+        sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
+        sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
+        sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
+       }
+
       if(! strcmp(board, BOARD_JMR3904_DEBUG))
        {
          /* -- DEBUG: glue interrupt generators --- */