summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2009-07-31 10:40:42 -0400
committerKorey Sewell <ksewell@umich.edu>2009-07-31 10:40:42 -0400
commitaa75b9a7a7489bf86c4e6d406ff612e596ddff96 (patch)
tree58a6816583a21c19c181e32bff10bf74aa9ad15f /src/arch
parent60063cc700912666fa8b7968d692d00a1e82cb67 (diff)
parent3dd3de5feb31055a48acb39575da25a9cea2626d (diff)
downloadgem5-aa75b9a7a7489bf86c4e6d406ff612e596ddff96.tar.xz
merge mips fix and statetrace changes
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/arm/ArmNativeTrace.py37
-rw-r--r--src/arch/arm/SConscript3
-rw-r--r--src/arch/arm/isa.hh6
-rw-r--r--src/arch/arm/isa/decoder.isa26
-rw-r--r--src/arch/arm/isa/formats/pred.isa6
-rw-r--r--src/arch/arm/isa/operands.isa8
-rw-r--r--src/arch/arm/linux/linux.hh73
-rw-r--r--src/arch/arm/linux/process.cc10
-rw-r--r--src/arch/arm/miscregs.hh3
-rw-r--r--src/arch/arm/nativetrace.cc183
-rw-r--r--src/arch/arm/nativetrace.hh112
-rw-r--r--src/arch/arm/process.cc240
-rwxr-xr-xsrc/arch/mips/mt.hh2
13 files changed, 634 insertions, 75 deletions
diff --git a/src/arch/arm/ArmNativeTrace.py b/src/arch/arm/ArmNativeTrace.py
new file mode 100644
index 000000000..0a76913e3
--- /dev/null
+++ b/src/arch/arm/ArmNativeTrace.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2009 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.SimObject import SimObject
+from m5.params import *
+from NativeTrace import NativeTrace
+
+class ArmNativeTrace(NativeTrace):
+ type = 'ArmNativeTrace'
+ cxx_class = 'Trace::ArmNativeTrace'
+ stop_on_pc_error = Param.Bool(True,
+ "Stop M5 if it and statetrace's pcs are different")
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
index 519435489..55ecabdc3 100644
--- a/src/arch/arm/SConscript
+++ b/src/arch/arm/SConscript
@@ -39,11 +39,14 @@ if env['TARGET_ISA'] == 'arm':
Source('insts/mem.cc')
Source('insts/pred_inst.cc')
Source('insts/static_inst.cc')
+ Source('nativetrace.cc')
Source('pagetable.cc')
Source('tlb.cc')
Source('vtophys.cc')
+ SimObject('ArmNativeTrace.py')
SimObject('ArmTLB.py')
+
TraceFlag('Arm')
if env['FULL_SYSTEM']:
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 39acc9c08..2315afa9e 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -48,7 +48,11 @@ namespace ArmISA
public:
void clear()
{
- // Unknown startup state currently
+ memset(miscRegs, 0, sizeof(miscRegs));
+ CPSR cpsr = 0;
+ cpsr.mode = MODE_USER;
+ miscRegs[MISCREG_CPSR] = cpsr;
+ //XXX We need to initialize the rest of the state.
}
MiscReg
diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa
index 76d584858..a999b52e9 100644
--- a/src/arch/arm/isa/decoder.isa
+++ b/src/arch/arm/isa/decoder.isa
@@ -113,8 +113,7 @@ format DataOp {
0x1: decode OPCODE {
0x9: BranchExchange::bx({{ }});
0xb: PredOp::clz({{
- unsigned lsb = findLsbSet(Rm);
- Rd = (lsb > 31) ? 32 : lsb;
+ Rd = ((Rm == 0) ? 32 : (31 - findMsbSet(Rm)));
}});
}
0x2: decode OPCODE {
@@ -319,6 +318,10 @@ format DataOp {
0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }});
0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }});
}
+ 0xb: decode LOADOP {
+ 0x0: WarnUnimpl::fstmx();
+ 0x1: WarnUnimpl::fldmx();
+ }
}
0x7: decode OPCODE_24 {
0: decode CPNUM {
@@ -417,12 +420,29 @@ format DataOp {
}
}
}
+ 0xa: decode MISC_OPCODE {
+ 0x1: decode MEDIA_OPCODE {
+ 0xf: decode RN {
+ 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
+ 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
+ 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
+ }
+ 0xe: decode RN {
+ 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
+ 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
+ 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
+ }
+ }
+ }
}
format PredOp {
// ARM System Call (SoftWare Interrupt)
1: swi({{ if (testPredicate(Cpsr, condCode))
{
- xc->syscall(IMMED_23_0);
+ if (IMMED_23_0)
+ xc->syscall(IMMED_23_0);
+ else
+ xc->syscall(R7);
}
}});
}
diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa
index 50e162f3d..e90788c91 100644
--- a/src/arch/arm/isa/formats/pred.isa
+++ b/src/arch/arm/isa/formats/pred.isa
@@ -105,7 +105,8 @@ let {{
def getCcCode(flagtype):
icReg = icImm = iv = ''
if flagtype == "none":
- icReg = icImm = iv = '1'
+ icReg = icImm = 'Cpsr<29:>'
+ iv = 'Cpsr<28:>'
elif flagtype == "add":
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
iv = 'findOverflow(32, resTemp, Rn, op2)'
@@ -125,7 +126,8 @@ let {{
def getImmCcCode(flagtype):
ivValue = icValue = ''
if flagtype == "none":
- icValue = ivValue = '1'
+ icValue = 'Cpsr<29:>'
+ ivValue = 'Cpsr<28:>'
elif flagtype == "add":
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index fa41918c1..ac7427dad 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -57,6 +57,7 @@ def operands {{
'Rm': ('IntReg', 'uw', 'RM', 'IsInteger', 2, maybePCRead, maybePCWrite),
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite),
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite),
+ 'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
#Destination register for load/store double instructions
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
@@ -81,7 +82,10 @@ def operands {{
'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40),
'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41),
- 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 42),
- 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 43),
+ 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42),
+ 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43),
+ 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44),
+ 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45),
+ 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46)
}};
diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh
index 16bcee47a..d99fa8e49 100644
--- a/src/arch/arm/linux/linux.hh
+++ b/src/arch/arm/linux/linux.hh
@@ -66,18 +66,7 @@ class ArmLinux : public Linux
//@}
/// For mmap().
- static const unsigned TGT_MAP_ANONYMOUS = 0x800;
-
- //@{
- /// For getsysinfo().
- static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
- static const unsigned GSI_CPU_INFO = 59; //!< CPU information
- static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
- static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
- static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
- static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
- static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
- //@}
+ static const unsigned TGT_MAP_ANONYMOUS = 0x20;
//@{
/// For getrusage().
@@ -87,13 +76,8 @@ class ArmLinux : public Linux
//@}
//@{
- /// For setsysinfo().
- static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
- //@}
-
- //@{
/// ioctl() command codes.
- static const unsigned TIOCGETP_ = 0x40067408;
+ static const unsigned TIOCGETP_ = 0x5401;
static const unsigned TIOCSETP_ = 0x80067409;
static const unsigned TIOCSETN_ = 0x8006740a;
static const unsigned TIOCSETC_ = 0x80067411;
@@ -114,15 +98,56 @@ class ArmLinux : public Linux
TGT_RLIMIT_DATA = 2,
TGT_RLIMIT_STACK = 3,
TGT_RLIMIT_CORE = 4,
- TGT_RLIMIT_NOFILE = 5,
- TGT_RLIMIT_AS = 6,
- TGT_RLIMIT_RSS = 7,
- TGT_RLIMIT_VMEM = 7,
- TGT_RLIMIT_NPROC = 8,
- TGT_RLIMIT_MEMLOCK = 9,
+ TGT_RLIMIT_RSS = 5,
+ TGT_RLIMIT_NPROC = 6,
+ TGT_RLIMIT_NOFILE = 7,
+ TGT_RLIMIT_MEMLOCK = 8,
+ TGT_RLIMIT_AS = 9,
TGT_RLIMIT_LOCKS = 10
};
+ typedef struct {
+ uint32_t st_dev;
+ uint32_t st_ino;
+ uint16_t st_mode;
+ uint16_t st_nlink;
+ uint16_t st_uid;
+ uint16_t st_gid;
+ uint32_t st_rdev;
+ uint32_t st_size;
+ uint32_t st_blksize;
+ uint32_t st_blocks;
+ uint32_t st_atimeX;
+ uint32_t st_atime_nsec;
+ uint32_t st_mtimeX;
+ uint32_t st_mtime_nsec;
+ uint32_t st_ctimeX;
+ uint32_t st_ctime_nsec;
+ } tgt_stat;
+
+ typedef struct {
+ uint64_t st_dev;
+ uint8_t __pad0[4];
+ uint32_t __st_ino;
+ uint32_t st_mode;
+ uint32_t st_nlink;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint64_t st_rdev;
+ uint8_t __pad3[4];
+ int64_t __attribute__ ((aligned (8))) st_size;
+ uint32_t st_blksize;
+ uint64_t __attribute__ ((aligned (8))) st_blocks;
+ uint32_t st_atimeX;
+ uint32_t st_atime_nsec;
+ uint32_t st_mtimeX;
+ uint32_t st_mtime_nsec;
+ uint32_t st_ctimeX;
+ uint32_t st_ctime_nsec;
+ uint64_t st_ino;
+ } tgt_stat64;
+
+
};
#endif
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc
index 7158acfff..56e3588a7 100644
--- a/src/arch/arm/linux/process.cc
+++ b/src/arch/arm/linux/process.cc
@@ -106,7 +106,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
/* 40 */ SyscallDesc("rmdir", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
- /* 43 */ SyscallDesc("times", unimplementedFunc),
+ /* 43 */ SyscallDesc("times", ignoreFunc),
/* 44 */ SyscallDesc("prof", unimplementedFunc),
/* 45 */ SyscallDesc("brk", brkFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
@@ -260,7 +260,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
/* 194 */ SyscallDesc("ftruncate64", unimplementedFunc),
/* 195 */ SyscallDesc("stat64", unimplementedFunc),
/* 196 */ SyscallDesc("lstat64", lstat64Func<ArmLinux>),
- /* 197 */ SyscallDesc("fstat64", fstatFunc<ArmLinux>),
+ /* 197 */ SyscallDesc("fstat64", fstat64Func<ArmLinux>),
/* 198 */ SyscallDesc("lchown", unimplementedFunc),
/* 199 */ SyscallDesc("getuid", getuidFunc),
/* 200 */ SyscallDesc("getgid", getgidFunc),
@@ -418,7 +418,6 @@ setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
uint32_t tlsPtr = process->getSyscallArg(tc, 0);
- TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
@@ -448,7 +447,8 @@ ArmLinuxProcess::getDesc(int callnum)
// Angel SWI syscalls are unsupported in this release
if (callnum == 0x123456) {
panic("Attempt to execute an ANGEL_SWI system call (newlib-related)");
- } else if ((callnum & 0x00f00000) == 0x00900000) {
+ } else if ((callnum & 0x00f00000) == 0x00900000 ||
+ (callnum & 0xf0000) == 0xf0000) {
callnum &= 0x000fffff;
if ((callnum & 0x0f0000) == 0xf0000) {
callnum -= 0x0f0001;
@@ -496,7 +496,7 @@ ArmLinuxProcess::startup()
{
0x00, 0x30, 0x92, 0xe5, //ldr r3, [r2]
0x00, 0x30, 0x53, 0xe0, //subs r3, r3, r0
- 0x00, 0x10, 0x92, 0x05, //streq r1, [r2]
+ 0x00, 0x10, 0x82, 0x05, //streq r1, [r2]
0x03, 0x00, 0xa0, 0xe1, //mov r0, r3
0x0e, 0xf0, 0xa0, 0xe1 //usr_ret lr
};
diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh
index 42065b0fd..3180669de 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -62,6 +62,9 @@ namespace ArmISA
MISCREG_SPSR_UND,
MISCREG_SPSR_ABT,
MISCREG_FPSR,
+ MISCREG_FPSID,
+ MISCREG_FPSCR,
+ MISCREG_FPEXC,
NUM_MISCREGS
};
diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc
new file mode 100644
index 000000000..1ad9e1a19
--- /dev/null
+++ b/src/arch/arm/nativetrace.cc
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/miscregs.hh"
+#include "arch/arm/nativetrace.hh"
+#include "cpu/thread_context.hh"
+#include "params/ArmNativeTrace.hh"
+
+namespace Trace {
+
+#if TRACING_ON
+static const char *regNames[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc",
+ "cpsr"
+};
+#endif
+
+void
+Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent)
+{
+ oldState = state[current];
+ current = (current + 1) % 2;
+ newState = state[current];
+
+ memcpy(newState, oldState, sizeof(state[0]));
+
+ uint32_t diffVector;
+ parent->read(&diffVector, sizeof(diffVector));
+ diffVector = ArmISA::gtoh(diffVector);
+
+ int changes = 0;
+ for (int i = 0; i < STATE_NUMVALS; i++) {
+ if (diffVector & 0x1) {
+ changed[i] = true;
+ changes++;
+ } else {
+ changed[i] = false;
+ }
+ diffVector >>= 1;
+ }
+
+ uint32_t values[changes];
+ parent->read(values, sizeof(values));
+ int pos = 0;
+ for (int i = 0; i < STATE_NUMVALS; i++) {
+ if (changed[i]) {
+ newState[i] = ArmISA::gtoh(values[pos++]);
+ changed[i] = (newState[i] != oldState[i]);
+ }
+ }
+}
+
+void
+Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
+{
+ oldState = state[current];
+ current = (current + 1) % 2;
+ newState = state[current];
+
+ // Regular int regs
+ for (int i = 0; i < 15; i++) {
+ newState[i] = tc->readIntReg(i);
+ changed[i] = (oldState[i] != newState[i]);
+ }
+
+ //R15, aliased with the PC
+ newState[STATE_PC] = tc->readNextPC();
+ changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
+
+ //CPSR
+ newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR);
+ changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
+}
+
+void
+Trace::ArmNativeTrace::check(NativeTraceRecord *record)
+{
+ ThreadContext *tc = record->getThread();
+ // This area is read only on the target. It can't stop there to tell us
+ // what's going on, so we should skip over anything there also.
+ if (tc->readNextPC() > 0xffff0000)
+ return;
+ nState.update(this);
+ mState.update(tc);
+
+ bool errorFound = false;
+ // Regular int regs
+ for (int i = 0; i < STATE_NUMVALS; i++) {
+ if (nState.changed[i] || mState.changed[i]) {
+ const char *vergence = " ";
+ bool oldMatch = (mState.oldState[i] == nState.oldState[i]);
+ bool newMatch = (mState.newState[i] == nState.newState[i]);
+ if (oldMatch && newMatch) {
+ // The more things change, the more they stay the same.
+ continue;
+ } else if (oldMatch && !newMatch) {
+ vergence = "<>";
+ } else if (!oldMatch && newMatch) {
+ vergence = "><";
+ }
+ errorFound = true;
+ if (!nState.changed[i]) {
+ DPRINTF(ExecRegDelta, "%s [%5s] "\
+ "Native: %#010x "\
+ "M5: %#010x => %#010x\n",
+ vergence, regNames[i],
+ nState.newState[i],
+ mState.oldState[i], mState.newState[i]);
+ } else if (!mState.changed[i]) {
+ DPRINTF(ExecRegDelta, "%s [%5s] "\
+ "Native: %#010x => %#010x "\
+ "M5: %#010x \n",
+ vergence, regNames[i],
+ nState.oldState[i], nState.newState[i],
+ mState.newState[i]);
+ } else {
+ DPRINTF(ExecRegDelta, "%s [%5s] "\
+ "Native: %#010x => %#010x "\
+ "M5: %#010x => %#010x\n",
+ vergence, regNames[i],
+ nState.oldState[i], nState.newState[i],
+ mState.oldState[i], mState.newState[i]);
+ }
+ }
+ }
+ if (errorFound) {
+ StaticInstPtr inst = record->getStaticInst();
+ assert(inst);
+ bool ran = true;
+ if (inst->isMicroop()) {
+ ran = false;
+ inst = record->getMacroStaticInst();
+ }
+ assert(inst);
+ record->traceInst(inst, ran);
+
+ bool pcError = (mState.newState[STATE_PC] !=
+ nState.newState[STATE_PC]);
+ if (stopOnPCError && pcError)
+ panic("Native trace detected an error in control flow!");
+ }
+}
+
+} /* namespace Trace */
+
+////////////////////////////////////////////////////////////////////////
+//
+// ExeTracer Simulation Object
+//
+Trace::ArmNativeTrace *
+ArmNativeTraceParams::create()
+{
+ return new Trace::ArmNativeTrace(this);
+};
diff --git a/src/arch/arm/nativetrace.hh b/src/arch/arm/nativetrace.hh
new file mode 100644
index 000000000..7467e3378
--- /dev/null
+++ b/src/arch/arm/nativetrace.hh
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_ARM_NATIVETRACE_HH__
+#define __ARCH_ARM_NATIVETRACE_HH__
+
+#include "base/types.hh"
+#include "cpu/nativetrace.hh"
+#include "params/ArmNativeTrace.hh"
+
+namespace Trace {
+
+class ArmNativeTrace : public NativeTrace
+{
+ public:
+ enum StateID {
+ STATE_R0,
+ STATE_R1,
+ STATE_R2,
+ STATE_R3,
+ STATE_R4,
+ STATE_R5,
+ STATE_R6,
+ STATE_R7,
+ STATE_R8,
+ STATE_R9,
+ STATE_R10,
+ STATE_R11,
+ STATE_FP = STATE_R11,
+ STATE_R12,
+ STATE_R13,
+ STATE_SP = STATE_R13,
+ STATE_R14,
+ STATE_LR = STATE_R14,
+ STATE_R15,
+ STATE_PC = STATE_R15,
+ STATE_CPSR,
+ STATE_NUMVALS
+ };
+
+ protected:
+ struct ThreadState {
+ bool changed[STATE_NUMVALS];
+ uint32_t state[2][STATE_NUMVALS];
+ uint32_t *newState;
+ uint32_t *oldState;
+ int current;
+ void update(NativeTrace *parent);
+ void update(ThreadContext *tc);
+
+ ThreadState()
+ {
+ for (int i = 0; i < STATE_NUMVALS; i++) {
+ changed[i] = false;
+ state[0][i] = state[1][i] = 0;
+ current = 0;
+ newState = state[0];
+ oldState = state[1];
+ }
+ }
+ };
+
+ ThreadState nState, mState;
+
+ bool stopOnPCError;
+
+ public:
+ typedef ArmNativeTraceParams Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ ArmNativeTrace(const Params *p) :
+ NativeTrace(p), stopOnPCError(p->stop_on_pc_error)
+ {}
+
+ void check(NativeTraceRecord *record);
+};
+
+} /* namespace Trace */
+
+#endif // __ARCH_ARM_NATIVETRACE_HH__
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index 365d5b22c..cd7cc9736 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -46,7 +46,7 @@ using namespace ArmISA;
ArmLiveProcess::ArmLiveProcess(LiveProcessParams *params, ObjectFile *objFile)
: LiveProcess(params, objFile)
{
- stack_base = 0xc0000000L;
+ stack_base = 0xbf000000L;
// Set pointer for next thread stack. Reserve 8M for main stack.
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
@@ -88,73 +88,239 @@ ArmLiveProcess::copyStringArray32(std::vector<std::string> &strings,
void
ArmLiveProcess::argsInit(int intSize, int pageSize)
{
+ typedef AuxVector<uint32_t> auxv_t;
+ std::vector<auxv_t> auxv;
+
+ string filename;
+ if (argv.size() < 1)
+ filename = "";
+ else
+ filename = argv[0];
+
+ //We want 16 byte alignment
+ uint64_t align = 16;
+
// Overloaded argsInit so that we can fine-tune for ARM architecture
Process::startup();
// load object file into target memory
objFile->loadSections(initVirtMem);
- // Calculate how much space we need for arg & env arrays.
- int argv_array_size = intSize * (argv.size() + 1);
- int envp_array_size = intSize * (envp.size() + 1);
- int arg_data_size = 0;
- for (int i = 0; i < argv.size(); ++i) {
- arg_data_size += argv[i].size() + 1;
+ enum ArmCpuFeature {
+ Arm_Swp = 1 << 0,
+ Arm_Half = 1 << 1,
+ Arm_Thumb = 1 << 2,
+ Arm_26Bit = 1 << 3,
+ Arm_FastMult = 1 << 4,
+ Arm_Fpa = 1 << 5,
+ Arm_Vfp = 1 << 6,
+ Arm_Edsp = 1 << 7,
+ Arm_Java = 1 << 8,
+ Arm_Iwmmxt = 1 << 9,
+ Arm_Crunch = 1 << 10
+ };
+
+ //Setup the auxilliary vectors. These will already have endian conversion.
+ //Auxilliary vectors are loaded only for elf formatted executables.
+ ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+ if (elfObject) {
+ uint32_t features =
+ Arm_Swp |
+ Arm_Half |
+ Arm_Thumb |
+// Arm_26Bit |
+ Arm_FastMult |
+// Arm_Fpa |
+ Arm_Vfp |
+ Arm_Edsp |
+ Arm_Java |
+// Arm_Iwmmxt |
+// Arm_Crunch |
+ 0;
+
+ //Bits which describe the system hardware capabilities
+ //XXX Figure out what these should be
+ auxv.push_back(auxv_t(M5_AT_HWCAP, features));
+ //The system page size
+ auxv.push_back(auxv_t(M5_AT_PAGESZ, ArmISA::VMPageSize));
+ //Frequency at which times() increments
+ auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64));
+ // For statically linked executables, this is the virtual address of the
+ // program header tables if they appear in the executable image
+ auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
+ // This is the size of a program header entry from the elf file.
+ auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
+ // This is the number of program headers from the original elf file.
+ auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+ //This is the address of the elf "interpreter", It should be set
+ //to 0 for regular executables. It should be something else
+ //(not sure what) for dynamic libraries.
+ auxv.push_back(auxv_t(M5_AT_BASE, 0));
+
+ //XXX Figure out what this should be.
+ auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
+ //The entry point to the program
+ auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
+ //Different user and group IDs
+ auxv.push_back(auxv_t(M5_AT_UID, uid()));
+ auxv.push_back(auxv_t(M5_AT_EUID, euid()));
+ auxv.push_back(auxv_t(M5_AT_GID, gid()));
+ auxv.push_back(auxv_t(M5_AT_EGID, egid()));
+ //Whether to enable "secure mode" in the executable
+ auxv.push_back(auxv_t(M5_AT_SECURE, 0));
+ //The filename of the program
+ auxv.push_back(auxv_t(M5_AT_EXECFN, 0));
+ //The string "v51" with unknown meaning
+ auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
}
+
+ //Figure out how big the initial stack nedes to be
+
+ // A sentry NULL void pointer at the top of the stack.
+ int sentry_size = intSize;
+
+ string platform = "v51";
+ int platform_size = platform.size() + 1;
+
+ // The aux vectors are put on the stack in two groups. The first group are
+ // the vectors that are generated as the elf is loaded. The second group
+ // are the ones that were computed ahead of time and include the platform
+ // string.
+ int aux_data_size = filename.size() + 1;
+
int env_data_size = 0;
for (int i = 0; i < envp.size(); ++i) {
env_data_size += envp[i].size() + 1;
}
+ int arg_data_size = 0;
+ for (int i = 0; i < argv.size(); ++i) {
+ arg_data_size += argv[i].size() + 1;
+ }
- int space_needed =
- argv_array_size + envp_array_size + arg_data_size + env_data_size;
- if (space_needed < 16*1024)
- space_needed = 16*1024;
+ int info_block_size =
+ sentry_size + env_data_size + arg_data_size +
+ aux_data_size + platform_size;
+
+ //Each auxilliary vector is two 4 byte words
+ int aux_array_size = intSize * 2 * (auxv.size() + 1);
+
+ int envp_array_size = intSize * (envp.size() + 1);
+ int argv_array_size = intSize * (argv.size() + 1);
+
+ int argc_size = intSize;
+
+ //Figure out the size of the contents of the actual initial frame
+ int frame_size =
+ info_block_size +
+ aux_array_size +
+ envp_array_size +
+ argv_array_size +
+ argc_size;
+
+ //There needs to be padding after the auxiliary vector data so that the
+ //very bottom of the stack is aligned properly.
+ int partial_size = frame_size;
+ int aligned_partial_size = roundUp(partial_size, align);
+ int aux_padding = aligned_partial_size - partial_size;
+
+ int space_needed = frame_size + aux_padding;
- // set bottom of stack
stack_min = stack_base - space_needed;
- // align it
- stack_min = roundDown(stack_min, pageSize);
+ stack_min = roundDown(stack_min, align);
stack_size = stack_base - stack_min;
+
// map memory
- pTable->allocate(stack_min, roundUp(stack_size, pageSize));
+ pTable->allocate(roundDown(stack_min, pageSize),
+ roundUp(stack_size, pageSize));
// map out initial stack contents
- Addr argv_array_base = stack_min + intSize; // room for argc
- Addr envp_array_base = argv_array_base + argv_array_size;
- Addr arg_data_base = envp_array_base + envp_array_size;
- Addr env_data_base = arg_data_base + arg_data_size;
+ uint32_t sentry_base = stack_base - sentry_size;
+ uint32_t aux_data_base = sentry_base - aux_data_size;
+ uint32_t env_data_base = aux_data_base - env_data_size;
+ uint32_t arg_data_base = env_data_base - arg_data_size;
+ uint32_t platform_base = arg_data_base - platform_size;
+ uint32_t auxv_array_base = platform_base - aux_array_size - aux_padding;
+ uint32_t envp_array_base = auxv_array_base - envp_array_size;
+ uint32_t argv_array_base = envp_array_base - argv_array_size;
+ uint32_t argc_base = argv_array_base - argc_size;
+
+ DPRINTF(Stack, "The addresses of items on the initial stack:\n");
+ DPRINTF(Stack, "0x%x - aux data\n", aux_data_base);
+ DPRINTF(Stack, "0x%x - env data\n", env_data_base);
+ DPRINTF(Stack, "0x%x - arg data\n", arg_data_base);
+ DPRINTF(Stack, "0x%x - platform base\n", platform_base);
+ DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base);
+ DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
+ DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
+ DPRINTF(Stack, "0x%x - argc \n", argc_base);
+ DPRINTF(Stack, "0x%x - stack min\n", stack_min);
// write contents to stack
- uint64_t argc = argv.size();
- if (intSize == 8)
- argc = htog((uint64_t)argc);
- else if (intSize == 4)
- argc = htog((uint32_t)argc);
- else
- panic("Unknown int size");
- initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
+ // figure out argc
+ uint32_t argc = argv.size();
+ uint32_t guestArgc = ArmISA::htog(argc);
- copyStringArray32(argv, argv_array_base, arg_data_base, initVirtMem);
- copyStringArray32(envp, envp_array_base, env_data_base, initVirtMem);
+ //Write out the sentry void *
+ uint32_t sentry_NULL = 0;
+ initVirtMem->writeBlob(sentry_base,
+ (uint8_t*)&sentry_NULL, sentry_size);
- /*
- //uint8_t insns[] = {0xe5, 0x9f, 0x00, 0x08, 0xe1, 0xa0, 0xf0, 0x0e};
- uint8_t insns[] = {0x08, 0x00, 0x9f, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1};
+ //Fix up the aux vectors which point to other data
+ for (int i = auxv.size() - 1; i >= 0; i--) {
+ if (auxv[i].a_type == M5_AT_PLATFORM) {
+ auxv[i].a_val = platform_base;
+ initVirtMem->writeString(platform_base, platform.c_str());
+ } else if (auxv[i].a_type == M5_AT_EXECFN) {
+ auxv[i].a_val = aux_data_base;
+ initVirtMem->writeString(aux_data_base, filename.c_str());
+ }
+ }
- initVirtMem->writeBlob(0xffff0fe0, insns, 8);
- */
+ //Copy the aux stuff
+ for(int x = 0; x < auxv.size(); x++)
+ {
+ initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+ (uint8_t*)&(auxv[x].a_type), intSize);
+ initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+ (uint8_t*)&(auxv[x].a_val), intSize);
+ }
+ //Write out the terminating zeroed auxilliary vector
+ const uint64_t zero = 0;
+ initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
+ (uint8_t*)&zero, 2 * intSize);
- ThreadContext *tc = system->getThreadContext(contextIds[0]);
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+
+ initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
- tc->setIntReg(ArgumentReg1, argc);
- tc->setIntReg(ArgumentReg2, argv_array_base);
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+ //Set the stack pointer register
tc->setIntReg(StackPointerReg, stack_min);
+ //A pointer to a function to run when the program exits. We'll set this
+ //to zero explicitly to make sure this isn't used.
+ tc->setIntReg(ArgumentReg0, 0);
+ //Set argument regs 1 and 2 to argv[0] and envp[0] respectively
+ if (argv.size() > 0) {
+ tc->setIntReg(ArgumentReg1, arg_data_base + arg_data_size -
+ argv[argv.size() - 1].size() - 1);
+ } else {
+ tc->setIntReg(ArgumentReg1, 0);
+ }
+ if (envp.size() > 0) {
+ tc->setIntReg(ArgumentReg2, env_data_base + env_data_size -
+ envp[envp.size() - 1].size() - 1);
+ } else {
+ tc->setIntReg(ArgumentReg2, 0);
+ }
Addr prog_entry = objFile->entryPoint();
tc->setPC(prog_entry);
tc->setNextPC(prog_entry + sizeof(MachInst));
+
+ //Align the "stack_min" to a page boundary.
+ stack_min = roundDown(stack_min, pageSize);
}
ArmISA::IntReg
diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh
index 3cb81c201..7217c335e 100755
--- a/src/arch/mips/mt.hh
+++ b/src/arch/mips/mt.hh
@@ -118,7 +118,7 @@ forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
tc->readRegOtherThread(MISCREG_TC_BIND + Ctrl_Base_DepTag, tid);
TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
- if (tidTCBind.curVPE = tcBind.curVPE) {
+ if (tidTCBind.curVPE == tcBind.curVPE) {
TCStatusReg tidTCStatus =
tc->readRegOtherThread(MISCREG_TC_STATUS +