Add support for v4 SystemMode.
This commit is contained in:
parent
ac73857d80
commit
c1a72ffdd6
@ -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.
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 *
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
2
sim/arm/configure
vendored
2
sim/arm/configure
vendored
@ -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
|
||||
|
@ -7,4 +7,7 @@ SIM_AC_COMMON
|
||||
|
||||
AC_CHECK_HEADERS(unistd.h)
|
||||
|
||||
COPRO=armcopro.o
|
||||
AC_SUBST(COPRO)
|
||||
|
||||
SIM_AC_OUTPUT
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user