aboutsummaryrefslogtreecommitdiff
path: root/sim/arm
diff options
context:
space:
mode:
Diffstat (limited to 'sim/arm')
-rw-r--r--sim/arm/ChangeLog28
-rw-r--r--sim/arm/Makefile.in8
-rw-r--r--sim/arm/armcopro.c38
-rw-r--r--sim/arm/armdefs.h21
-rw-r--r--sim/arm/armemu.c6
-rw-r--r--sim/arm/arminit.c8
-rw-r--r--sim/arm/armos.c1
-rw-r--r--sim/arm/armsupp.c93
-rwxr-xr-xsim/arm/configure2
-rw-r--r--sim/arm/configure.in3
-rw-r--r--sim/arm/wrapper.c8
11 files changed, 159 insertions, 57 deletions
diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog
index b58b9ad..f7b7895 100644
--- a/sim/arm/ChangeLog
+++ b/sim/arm/ChangeLog
@@ -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.
diff --git a/sim/arm/Makefile.in b/sim/arm/Makefile.in
index e2f2b3c..19a9bca 100644
--- a/sim/arm/Makefile.in
+++ b/sim/arm/Makefile.in
@@ -20,15 +20,17 @@
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)
diff --git a/sim/arm/armcopro.c b/sim/arm/armcopro.c
index 579446c..48be680 100644
--- a/sim/arm/armcopro.c
+++ b/sim/arm/armcopro.c
@@ -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;
}
diff --git a/sim/arm/armdefs.h b/sim/arm/armdefs.h
index bce638d..b23f26f 100644
--- a/sim/arm/armdefs.h
+++ b/sim/arm/armdefs.h
@@ -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 *
diff --git a/sim/arm/armemu.c b/sim/arm/armemu.c
index d890cda..acbcb75 100644
--- a/sim/arm/armemu.c
+++ b/sim/arm/armemu.c
@@ -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 */
diff --git a/sim/arm/arminit.c b/sim/arm/arminit.c
index 3e75b47..0105c17 100644
--- a/sim/arm/arminit.c
+++ b/sim/arm/arminit.c
@@ -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;
diff --git a/sim/arm/armos.c b/sim/arm/armos.c
index 67dd51c..958d4cd 100644
--- a/sim/arm/armos.c
+++ b/sim/arm/armos.c
@@ -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 */
diff --git a/sim/arm/armsupp.c b/sim/arm/armsupp.c
index 154d520..5c18ddd 100644
--- a/sim/arm/armsupp.c
+++ b/sim/arm/armsupp.c
@@ -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
diff --git a/sim/arm/configure b/sim/arm/configure
index 2720d6b..2c574e4 100755
--- a/sim/arm/configure
+++ b/sim/arm/configure
@@ -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
diff --git a/sim/arm/configure.in b/sim/arm/configure.in
index 033b0bc..cbfac44 100644
--- a/sim/arm/configure.in
+++ b/sim/arm/configure.in
@@ -7,4 +7,7 @@ SIM_AC_COMMON
AC_CHECK_HEADERS(unistd.h)
+COPRO=armcopro.o
+AC_SUBST(COPRO)
+
SIM_AC_OUTPUT
diff --git a/sim/arm/wrapper.c b/sim/arm/wrapper.c
index 003dec6..8fca85d 100644
--- a/sim/arm/wrapper.c
+++ b/sim/arm/wrapper.c
@@ -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.