Add support for v4 SystemMode.
authorNick Clifton <nickc@redhat.com>
Tue, 30 May 2000 17:13:37 +0000 (17:13 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 30 May 2000 17:13:37 +0000 (17:13 +0000)
sim/arm/ChangeLog
sim/arm/Makefile.in
sim/arm/armcopro.c
sim/arm/armdefs.h
sim/arm/armemu.c
sim/arm/arminit.c
sim/arm/armos.c
sim/arm/armsupp.c
sim/arm/configure
sim/arm/configure.in
sim/arm/wrapper.c

index b58b9ad..f7b7895 100644 (file)
@@ -1,4 +1,30 @@
-Tue May 23 21:39:23 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+2000-05-25  Nick Clifton  <nickc@cygnus.com>
+
+       * armcopro.c (MMUMCR): Only indicate mode change if a singal has
+       really changed.
+       (MMUWrite): Only indicate mode change if a singal has really
+       changed.
+
+       * armdefs.h (SYSTEMMODE): Define.
+       (BANK_CAN_ACEESS_SPSR): Define.
+
+       * armemu.c (ARM_Emulate26): If the mode has changed allow the PC
+       to advance before stopping the emulation.
+
+       * arminit.c (ARMul_Reset): Ensure Mode field of State is set
+       correctly.
+
+       * armos.c (ARMul_OSInit): Create a initial stack pointer for
+       System mode.
+
+       * armsupp.c (ModeToBank): Remove unused first parameter.
+       Add support for System Mode.
+       (ARMul_GetSPSR): Use BANK_CAN_ACCESS_SPSR macro.
+       (ARMul_SetSPSR): Use BANK_CAN_ACCESS_SPSR macro.
+       (ARMul_FixSPSR): Use BANK_CAN_ACCESS_SPSR macro.
+       (ARMulSwitchMode): Add support for System Mode.
+
+Wed May 24 14:40:34 2000  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * configure: Regenerated to track ../common/aclocal.m4 changes.
 
index e2f2b3c..19a9bca 100644 (file)
 
 SIM_EXTRA_CFLAGS = -DMODET -DNEED_UI_LOOP_HOOK
 
-SIM_OBJS = armcopro.o armemu26.o armemu32.o arminit.o armos.o armsupp.o \
-       armvirt.o bag.o thumbemu.o wrapper.o sim-load.o
+COPRO=@COPRO@
+
+SIM_OBJS = armemu26.o armemu32.o arminit.o armos.o armsupp.o \
+       armvirt.o bag.o thumbemu.o wrapper.o sim-load.o $(COPRO) 
 
 ## COMMON_POST_CONFIG_FRAG
 
 
 armos.o: armos.c armdefs.h armos.h armfpe.h
 
-armcopro.o: armcopro.c armdefs.h 
+armcopro.o: armcopro.c armdefs.h
 
 armemu26.o: armemu.c armdefs.h armemu.h 
        $(CC) -c $< -o armemu26.o $(ALL_CFLAGS)
index 579446c..48be680 100644 (file)
@@ -16,6 +16,7 @@
     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 
 #include "armdefs.h"
+#include "armemu.h"
 #include "ansidecl.h"
 
 extern unsigned ARMul_CoProInit (ARMul_State * state);
@@ -79,15 +80,29 @@ MMUMCR (ARMul_State * state, unsigned type ATTRIBUTE_UNUSED, ARMword instr, ARMw
   int reg = BITS (16, 19) & 7;
 
   MMUReg[reg] = value;
+  
   if (reg == 1)
     {
+      ARMword p,d,l,b;
+
+      p = state->prog32Sig;
+      d = state->data32Sig;
+      l = state->lateabtSig;
+      b = state->bigendSig;
+      
       state->prog32Sig = value >> 4 & 1;
       state->data32Sig = value >> 5 & 1;
       state->lateabtSig = value >> 6 & 1;
       state->bigendSig = value >> 7 & 1;
-      state->Emulate = TRUE;   /* force ARMulator to notice these now ! */
+
+      if (p != state->prog32Sig
+         || d != state->data32Sig
+         || l != state->lateabtSig
+         || b != state->bigendSig)
+       state->Emulate = CHANGEMODE;    /* Force ARMulator to notice these now.  */
     }
-  return (ARMul_DONE);
+  
+  return ARMul_DONE;
 }
 
 
@@ -106,15 +121,30 @@ MMUWrite (ARMul_State * state, unsigned reg, ARMword value)
 {
   if (reg < 8)
     MMUReg[reg] = value;
+  
   if (reg == 1)
     {
+      ARMword p,d,l,b;
+
+      p = state->prog32Sig;
+      d = state->data32Sig;
+      l = state->lateabtSig;
+      b = state->bigendSig;
+      
       state->prog32Sig = value >> 4 & 1;
       state->data32Sig = value >> 5 & 1;
       state->lateabtSig = value >> 6 & 1;
       state->bigendSig = value >> 7 & 1;
-      state->Emulate = TRUE;   /* force ARMulator to notice these now ! */
+
+      
+      if (p != state->prog32Sig
+         || d != state->data32Sig
+         || l != state->lateabtSig
+         || b != state->bigendSig)
+       state->Emulate = CHANGEMODE;    /* Force ARMulator to notice these now.  */
     }
-  return (TRUE);
+  
+  return TRUE;
 }
 
 
index bce638d..b23f26f 100644 (file)
@@ -200,16 +200,17 @@ struct ARMul_State
 *                          Mode and Bank Constants                          *
 \***************************************************************************/
 
-#define USER26MODE 0L
-#define FIQ26MODE 1L
-#define IRQ26MODE 2L
-#define SVC26MODE 3L
-#define USER32MODE 16L
-#define FIQ32MODE 17L
-#define IRQ32MODE 18L
-#define SVC32MODE 19L
+#define USER26MODE   0L
+#define FIQ26MODE    1L
+#define IRQ26MODE    2L
+#define SVC26MODE    3L
+#define USER32MODE  16L
+#define FIQ32MODE   17L
+#define IRQ32MODE   18L
+#define SVC32MODE   19L
 #define ABORT32MODE 23L
 #define UNDEF32MODE 27L
+#define SYSTEMMODE  31L
 
 #define ARM32BITMODE (state->Mode > 3)
 #define ARM26BITMODE (state->Mode <= 3)
@@ -225,6 +226,10 @@ struct ARMul_State
 #define ABORTBANK 4
 #define UNDEFBANK 5
 #define DUMMYBANK 6
+#define SYSTEMBANK 7
+
+#define BANK_CAN_ACCESS_SPSR(bank)  \
+  ((bank) != USERBANK && (bank) != SYSTEMBANK && (bank) != DUMMYBANK)
 
 /***************************************************************************\
 *                  Definitons of things in the emulator                     *
index d890cda..acbcb75 100644 (file)
@@ -2864,6 +2864,9 @@ ARMul_Emulate26 (register ARMul_State * state)
 
       if (state->Emulate == ONCE)
        state->Emulate = STOP;
+      /* If we have changed mode, allow the PC to advance before stopping.  */
+      else if (state->Emulate == CHANGEMODE)
+       continue;
       else if (state->Emulate != RUN)
        break;
     }
@@ -2872,7 +2875,8 @@ ARMul_Emulate26 (register ARMul_State * state)
   state->decoded = decoded;
   state->loaded = loaded;
   state->pc = pc;
-  return (pc);
+
+  return pc;
 }                              /* Emulate 26/32 in instruction based mode */
 
 
index 3e75b47..0105c17 100644 (file)
@@ -85,7 +85,8 @@ ARMul_NewState (void)
     }
   for (i = 0; i < 7; i++)
     state->Spsr[i] = 0;
-  state->Mode = 0;
+  
+  state->Mode = USER26MODE;
 
   state->CallDebug = FALSE;
   state->Debug = FALSE;
@@ -156,18 +157,23 @@ void
 ARMul_Reset (ARMul_State * state)
 {
   state->NextInstr = 0;
+
   if (state->prog32Sig)
     {
       state->Reg[15] = 0;
       state->Cpsr = INTBITS | SVC32MODE;
+      state->Mode = SVC32MODE;
     }
   else
     {
       state->Reg[15] = R15INTBITS | SVC26MODE;
       state->Cpsr = INTBITS | SVC26MODE;
+      state->Mode = SVC26MODE;
     }
+
   ARMul_CPSRAltered (state);
   state->Bank = SVCBANK;
+
   FLUSHPIPE;
 
   state->EndCondition = 0;
index 67dd51c..958d4cd 100644 (file)
@@ -165,6 +165,7 @@ ARMul_OSInit (ARMul_State * state)
   ARMul_SetReg (state, SVC32MODE, 13, ADDRSUPERSTACK); /* and for supervisor mode */
   ARMul_SetReg (state, ABORT32MODE, 13, ADDRSUPERSTACK);       /* and for abort 32 mode */
   ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK);       /* and for undef 32 mode */
+  ARMul_SetReg (state, SYSTEMMODE, 13, ADDRSUPERSTACK);        /* and for system mode */
   instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8);  /* load pc from soft vector */
   for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
     ARMul_WriteWord (state, i, instr); /* write hardware vectors */
index 154d520..5c18ddd 100644 (file)
@@ -42,7 +42,7 @@ void ARMul_R15Altered (ARMul_State * state);
 
 ARMword ARMul_SwitchMode (ARMul_State * state, ARMword oldmode,
                          ARMword newmode);
-static ARMword ModeToBank (ARMul_State * state, ARMword mode);
+static ARMword ModeToBank (ARMword mode);
 
 unsigned ARMul_NthReg (ARMword instr, unsigned number);
 
@@ -87,7 +87,7 @@ ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
 {
   mode &= MODEBITS;
   if (mode != state->Mode)
-    return (state->RegBank[ModeToBank (state, (ARMword) mode)][reg]);
+    return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
   else
     return (state->Reg[reg]);
 }
@@ -101,7 +101,7 @@ ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
 {
   mode &= MODEBITS;
   if (mode != state->Mode)
-    state->RegBank[ModeToBank (state, (ARMword) mode)][reg] = value;
+    state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
   else
     state->Reg[reg] = value;
 }
@@ -233,11 +233,12 @@ ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
 ARMword
 ARMul_GetSPSR (ARMul_State * state, ARMword mode)
 {
-  ARMword bank = ModeToBank (state, mode & MODEBITS);
-  if (bank == USERBANK || bank == DUMMYBANK)
-    return (CPSR);
-  else
-    return (state->Spsr[bank]);
+  ARMword bank = ModeToBank (mode & MODEBITS);
+
+  if (! BANK_CAN_ACCESS_SPSR (bank))
+    return CPSR;
+
+  return state->Spsr[bank];
 }
 
 /***************************************************************************\
@@ -247,8 +248,9 @@ ARMul_GetSPSR (ARMul_State * state, ARMword mode)
 void
 ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
 {
-  ARMword bank = ModeToBank (state, mode & MODEBITS);
-  if (bank != USERBANK && bank != DUMMYBANK)
+  ARMword bank = ModeToBank (mode & MODEBITS);
+  
+  if (BANK_CAN_ACCESS_SPSR (bank))
     state->Spsr[bank] = value;
 }
 
@@ -259,7 +261,7 @@ ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
 void
 ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
 {
-  if (state->Bank != USERBANK && state->Bank != DUMMYBANK)
+  if (BANK_CAN_ACCESS_SPSR (state->Bank))
     {
       if (BITS (16, 19) == 9)
        SETPSR (state->Spsr[state->Bank], rhs);
@@ -282,11 +284,14 @@ ARMul_CPSRAltered (ARMul_State * state)
 
   if (state->prog32Sig == LOW)
     state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
+
   oldmode = state->Mode;
+  
   if (state->Mode != (state->Cpsr & MODEBITS))
     {
       state->Mode =
        ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS);
+      
       state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
     }
 
@@ -317,7 +322,6 @@ ARMul_CPSRAltered (ARMul_State * state)
       else
        state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
     }
-
 }
 
 /***************************************************************************\
@@ -355,23 +359,30 @@ ARMword
 ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
 {
   unsigned i;
-
-  oldmode = ModeToBank (state, oldmode);
-  state->Bank = ModeToBank (state, newmode);
-  if (oldmode != state->Bank)
+  ARMword  oldbank;
+  ARMword  newbank;
+  
+  oldbank = ModeToBank (oldmode);
+  newbank = state->Bank = ModeToBank (newmode);
+  
+  if (oldbank != newbank)
     {                          /* really need to do it */
-      switch (oldmode)
+      switch (oldbank)
        {                       /* save away the old registers */
+       case SYSTEMBANK:
+         /* The System mode uses the USER bank.  */
+         oldbank = USERBANK;
+         /* Fall through.  */
        case USERBANK:
        case IRQBANK:
        case SVCBANK:
        case ABORTBANK:
        case UNDEFBANK:
-         if (state->Bank == FIQBANK)
+         if (newbank == FIQBANK)
            for (i = 8; i < 13; i++)
              state->RegBank[USERBANK][i] = state->Reg[i];
-         state->RegBank[oldmode][13] = state->Reg[13];
-         state->RegBank[oldmode][14] = state->Reg[14];
+         state->RegBank[oldbank][13] = state->Reg[13];
+         state->RegBank[oldbank][14] = state->Reg[14];
          break;
        case FIQBANK:
          for (i = 8; i < 15; i++)
@@ -381,20 +392,25 @@ ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
          for (i = 8; i < 15; i++)
            state->RegBank[DUMMYBANK][i] = 0;
          break;
-
+       default:
+         abort ();
        }
-      switch (state->Bank)
+      
+      switch (newbank)
        {                       /* restore the new registers */
+       case SYSTEMBANK:
+         newbank = USERBANK;
+         /* Fall through.  */
        case USERBANK:
        case IRQBANK:
        case SVCBANK:
        case ABORTBANK:
        case UNDEFBANK:
-         if (oldmode == FIQBANK)
+         if (oldbank == FIQBANK)
            for (i = 8; i < 13; i++)
              state->Reg[i] = state->RegBank[USERBANK][i];
-         state->Reg[13] = state->RegBank[state->Bank][13];
-         state->Reg[14] = state->RegBank[state->Bank][14];
+         state->Reg[13] = state->RegBank[newbank][13];
+         state->Reg[14] = state->RegBank[newbank][14];
          break;
        case FIQBANK:
          for (i = 8; i < 15; i++)
@@ -404,9 +420,12 @@ ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
          for (i = 8; i < 15; i++)
            state->Reg[i] = 0;
          break;
+       default:
+         abort ();
        }                       /* switch */
     }                          /* if */
-  return (newmode);
+  
+  return newmode;
 }
 
 /***************************************************************************\
@@ -415,21 +434,24 @@ ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
 \***************************************************************************/
 
 static ARMword
-ModeToBank (ARMul_State * state ATTRIBUTE_UNUSED, ARMword mode)
+ModeToBank (ARMword mode)
 {
-  static ARMword bankofmode[] = { USERBANK, FIQBANK, IRQBANK, SVCBANK,
+  static ARMword bankofmode[] =
+  {
+    USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
     DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
     DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
     DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
-    USERBANK, FIQBANK, IRQBANK, SVCBANK,
+    USERBANK,  FIQBANK,   IRQBANK,   SVCBANK,
     DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
-    DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
+    DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
   };
 
-  if (mode > UNDEF32MODE)
-    return (DUMMYBANK);
-  else
-    return (bankofmode[mode]);
+  if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
+    return DUMMYBANK;
+
+  return bankofmode[mode];
 }
 
 /***************************************************************************\
@@ -650,9 +672,11 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
   unsigned cpab;
 
   cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
+
   while (cpab == ARMul_BUSY)
     {
       ARMul_Icycles (state, 1, 0);
+
       if (IntPending (state))
        {
          cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
@@ -661,6 +685,7 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
       else
        cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source);
     }
+
   if (cpab == ARMul_CANT)
     ARMul_Abort (state, ARMul_UndefinedInstrV);
   else
index 2720d6b..2c574e4 100755 (executable)
@@ -3534,6 +3534,7 @@ fi
 done
 
 
+COPRO=armcopro.o
 
 
 trap '' 1 2 15
@@ -3744,6 +3745,7 @@ s%@sim_stdio@%$sim_stdio%g
 s%@sim_trace@%$sim_trace%g
 s%@sim_profile@%$sim_profile%g
 s%@EXEEXT@%$EXEEXT%g
+s%@COPRO@%$COPRO%g
 
 CEOF
 EOF
index 033b0bc..cbfac44 100644 (file)
@@ -7,4 +7,7 @@ SIM_AC_COMMON
 
 AC_CHECK_HEADERS(unistd.h)
 
+COPRO=armcopro.o
+AC_SUBST(COPRO)
+
 SIM_AC_OUTPUT
index 003dec6..8fca85d 100644 (file)
@@ -205,13 +205,11 @@ sim_create_inferior (sd, abfd, argv, env)
   else
     ARMul_SetPC (state, 0);    /* ??? */
 
-#if 1                          /* JGS */
   /* We explicitly select a processor capable of supporting the ARM
-     32bit mode, and then we force the simulated CPU into the 32bit
-     User mode: */
+     32bit mode.  JGS  */
   ARMul_SelectProcessor (state, ARM600);
+  /* And then we force the simulated CPU into the 32bit User mode.  */
   ARMul_SetCPSR (state, USER32MODE);
-#endif
 
   if (argv != NULL)
     {
@@ -359,7 +357,7 @@ sim_open (kind, ptr, abfd, argv)
 {
   sim_kind = kind;
   if (myname) free (myname);
-  myname = xstrdup (argv[0]);
+  myname = (char *) xstrdup (argv[0]);
   sim_callback = ptr;
 
   /* Decide upon the endian-ness of the processor.