From 0a18bc0d6cdcbf68f9bf01ae98ce0f678c62f16f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 27 Jul 2009 00:50:55 -0700 Subject: ARM: Detect OABI binaries and complain that they're no-longer supported. --- src/base/loader/elf_object.cc | 4 +++- src/base/loader/object_file.hh | 3 ++- src/sim/process.cc | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 16fc698dd..15ad88f76 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -107,7 +107,6 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) { case ELFOSABI_LINUX: - case ELFOSABI_ARM: opSys = ObjectFile::Linux; break; case ELFOSABI_SOLARIS: @@ -116,6 +115,9 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) case ELFOSABI_TRU64: opSys = ObjectFile::Tru64; break; + case ELFOSABI_ARM: + opSys = ObjectFile::LinuxArmOABI; + break; default: opSys = ObjectFile::UnknownOpSys; } diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh index 73df5caf6..e511451b7 100644 --- a/src/base/loader/object_file.hh +++ b/src/base/loader/object_file.hh @@ -59,7 +59,8 @@ class ObjectFile UnknownOpSys, Tru64, Linux, - Solaris + Solaris, + LinuxArmOABI }; protected: diff --git a/src/sim/process.cc b/src/sim/process.cc index c12101069..55bd2f209 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -748,7 +748,9 @@ LiveProcess::create(LiveProcessParams * params) case ObjectFile::Linux: process = new ArmLinuxProcess(params, objFile); break; - + case ObjectFile::LinuxArmOABI: + fatal("M5 does not support ARM OABI binaries. Please recompile with an" + " EABI compiler."); default: fatal("Unknown/unsupported operating system."); } -- cgit v1.2.3 From 99831ed93821ee8efc3e7a4b6671c5b226d245e2 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 27 Jul 2009 00:51:01 -0700 Subject: ARM: Handle register indexed system calls. --- src/arch/arm/isa/decoder.isa | 5 ++++- src/arch/arm/isa/operands.isa | 1 + src/arch/arm/linux/process.cc | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 76d584858..f43395c19 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -422,7 +422,10 @@ format DataOp { // 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/operands.isa b/src/arch/arm/isa/operands.isa index fa41918c1..6e6eea5a8 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), diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index 7158acfff..c5320c1ab 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -448,7 +448,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; -- cgit v1.2.3 From e7640227cac9432c689491f29c996d9168bfb330 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 27 Jul 2009 00:51:20 -0700 Subject: ARM: Fix fstat/fstat64 structs to match EABI definitions. --- src/arch/arm/linux/linux.hh | 42 ++++++++++++++++++++++++++++++++++++++++++ src/arch/arm/linux/process.cc | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index 16bcee47a..cc3b620ee 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -123,6 +123,48 @@ class ArmLinux : public Linux 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 c5320c1ab..e72c3fb3c 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -260,7 +260,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = { /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc), /* 195 */ SyscallDesc("stat64", unimplementedFunc), /* 196 */ SyscallDesc("lstat64", lstat64Func), - /* 197 */ SyscallDesc("fstat64", fstatFunc), + /* 197 */ SyscallDesc("fstat64", fstat64Func), /* 198 */ SyscallDesc("lchown", unimplementedFunc), /* 199 */ SyscallDesc("getuid", getuidFunc), /* 200 */ SyscallDesc("getgid", getgidFunc), -- cgit v1.2.3 From 519ace4dfdb5150915336735a34e21fb6c70b1dd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:51:35 -0700 Subject: ARM: Add a native tracer. --HG-- rename : src/arch/sparc/SparcNativeTrace.py => src/arch/arm/ArmNativeTrace.py rename : src/arch/sparc/nativetrace.cc => src/arch/arm/nativetrace.cc rename : src/arch/sparc/nativetrace.hh => src/arch/arm/nativetrace.hh --- src/arch/arm/ArmNativeTrace.py | 35 ++++++++++++++++++ src/arch/arm/SConscript | 3 ++ src/arch/arm/nativetrace.cc | 84 ++++++++++++++++++++++++++++++++++++++++++ src/arch/arm/nativetrace.hh | 50 +++++++++++++++++++++++++ 4 files changed, 172 insertions(+) create mode 100644 src/arch/arm/ArmNativeTrace.py create mode 100644 src/arch/arm/nativetrace.cc create mode 100644 src/arch/arm/nativetrace.hh (limited to 'src') diff --git a/src/arch/arm/ArmNativeTrace.py b/src/arch/arm/ArmNativeTrace.py new file mode 100644 index 000000000..fb3d4a4ff --- /dev/null +++ b/src/arch/arm/ArmNativeTrace.py @@ -0,0 +1,35 @@ +# 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' 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/nativetrace.cc b/src/arch/arm/nativetrace.cc new file mode 100644 index 000000000..78e0447f9 --- /dev/null +++ b/src/arch/arm/nativetrace.cc @@ -0,0 +1,84 @@ +/* + * 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 { + +static const char *regNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc", + "cpsr" +}; + +void +Trace::ArmNativeTrace::check(NativeTraceRecord *record) +{ + ThreadContext *tc = record->getThread(); + + uint32_t regVal, realRegVal; + + const char **regName = regNames; + // Regular int regs + for (int i = 0; i < 15; i++) { + regVal = tc->readIntReg(i); + read(&realRegVal, sizeof(realRegVal)); + realRegVal = ArmISA::gtoh(realRegVal); + checkReg(*(regName++), regVal, realRegVal); + } + + //R15, aliased with the PC + regVal = tc->readNextPC(); + read(&realRegVal, sizeof(realRegVal)); + realRegVal = ArmISA::gtoh(realRegVal); + checkReg(*(regName++), regVal, realRegVal); + + //CPSR + regVal = tc->readMiscReg(MISCREG_CPSR); + read(&realRegVal, sizeof(realRegVal)); + realRegVal = ArmISA::gtoh(realRegVal); + checkReg(*(regName++), regVal, realRegVal); +} + +} /* 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..a347040fb --- /dev/null +++ b/src/arch/arm/nativetrace.hh @@ -0,0 +1,50 @@ +/* + * 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" + +namespace Trace { + +class ArmNativeTrace : public NativeTrace +{ + public: + ArmNativeTrace(const Params *p) : NativeTrace(p) + {} + + void check(NativeTraceRecord *record); +}; + +} /* namespace Trace */ + +#endif // __ARCH_ARM_NATIVETRACE_HH__ -- cgit v1.2.3 From a41e1320077fc12869827899d034d5e3de155ffd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:52:01 -0700 Subject: ARM: Make native trace only print when registers are changing value. When registers have incorrect values but aren't actively changing, it's likely they're not being modified at all. The fact that they're still wrong isn't very important. --- src/arch/arm/nativetrace.cc | 85 ++++++++++++++++++++++++++++++++++++--------- src/arch/arm/nativetrace.hh | 50 ++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 78e0447f9..2dd0b8575 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -36,39 +36,92 @@ 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::check(NativeTraceRecord *record) +Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent) { - ThreadContext *tc = record->getThread(); + oldState = state[current]; + current = (current + 1) % 2; + newState = state[current]; - uint32_t regVal, realRegVal; + parent->read(newState, sizeof(newState[0]) * STATE_NUMVALS); + for (int i = 0; i < STATE_NUMVALS; i++) { + newState[i] = ArmISA::gtoh(newState[i]); + changed[i] = (oldState[i] != newState[i]); + } +} + +void +Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc) +{ + oldState = state[current]; + current = (current + 1) % 2; + newState = state[current]; - const char **regName = regNames; // Regular int regs for (int i = 0; i < 15; i++) { - regVal = tc->readIntReg(i); - read(&realRegVal, sizeof(realRegVal)); - realRegVal = ArmISA::gtoh(realRegVal); - checkReg(*(regName++), regVal, realRegVal); + newState[i] = tc->readIntReg(i); + changed[i] = (oldState[i] != newState[i]); } //R15, aliased with the PC - regVal = tc->readNextPC(); - read(&realRegVal, sizeof(realRegVal)); - realRegVal = ArmISA::gtoh(realRegVal); - checkReg(*(regName++), regVal, realRegVal); + newState[STATE_PC] = tc->readNextPC(); + changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]); //CPSR - regVal = tc->readMiscReg(MISCREG_CPSR); - read(&realRegVal, sizeof(realRegVal)); - realRegVal = ArmISA::gtoh(realRegVal); - checkReg(*(regName++), regVal, realRegVal); + newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR); + changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]); +} + +void +Trace::ArmNativeTrace::check(NativeTraceRecord *record) +{ + nState.update(this); + mState.update(record->getThread()); + + // Regular int regs + for (int i = 0; i < STATE_NUMVALS; i++) { + if (nState.changed[i] || mState.changed[i]) { + const char *vergence = " "; + if (mState.oldState[i] == nState.oldState[i] && + mState.newState[i] != nState.newState[i]) { + vergence = "<>"; + } else if (mState.oldState[i] != nState.oldState[i] && + mState.newState[i] == nState.newState[i]) { + vergence = "><"; + } + 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 if (mState.oldState[i] != nState.oldState[i] || + mState.newState[i] != nState.newState[i]) { + 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]); + } + } + } } } /* namespace Trace */ diff --git a/src/arch/arm/nativetrace.hh b/src/arch/arm/nativetrace.hh index a347040fb..d39bdcfa8 100644 --- a/src/arch/arm/nativetrace.hh +++ b/src/arch/arm/nativetrace.hh @@ -38,6 +38,56 @@ 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; + public: ArmNativeTrace(const Params *p) : NativeTrace(p) {} -- cgit v1.2.3 From ebc28976739a4618c40d527a94a013eb35471089 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:52:19 -0700 Subject: Elf: Add in some new aux vector type constants. --- src/sim/process.hh | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/sim/process.hh b/src/sim/process.hh index 0d5421dcd..05a48071a 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -295,6 +295,10 @@ class LiveProcess : public Process M5_AT_CLKTCK = 17, M5_AT_SECURE = 23, + M5_BASE_PLATFORM = 24, + M5_AT_RANDOM = 25, + + M5_AT_EXECFN = 31, M5_AT_VECTOR_SIZE = 44 }; -- cgit v1.2.3 From b8bf34be05648d73d1ff6cdb9b831145544a38df Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:52:31 -0700 Subject: ARM: Set up the initial stack frame to match a recent Linux. --- src/arch/arm/process.cc | 240 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 203 insertions(+), 37 deletions(-) (limited to 'src') 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 &strings, void ArmLiveProcess::argsInit(int intSize, int pageSize) { + typedef AuxVector auxv_t; + std::vector 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(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 -- cgit v1.2.3 From dc0df3f3966b3d4a5ff313007b44fb4b428a70d9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:52:48 -0700 Subject: ARM: Initialize the CPSR so that we're in user mode. --- src/arch/arm/isa.hh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') 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 -- cgit v1.2.3 From b560acfe17b5898d0c68715f9d1cb7e1dd1f006f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:52:59 -0700 Subject: ARM: Fix the CLZ instruction. --- src/arch/arm/isa/decoder.isa | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index f43395c19..046e52950 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 { -- cgit v1.2.3 From 4079792f2b61bd1e7c46a5aa8ddb06974982d1db Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:53:10 -0700 Subject: ARM: Add in spots for the VFP control registers. --- src/arch/arm/isa/operands.isa | 7 +++++-- src/arch/arm/miscregs.hh | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 6e6eea5a8..ac7427dad 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -82,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/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 }; -- cgit v1.2.3 From 2828fa459db0acbd92d569a3a1821b03d079604f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:53:24 -0700 Subject: ARM: Implement a basic version of the fmrx instruction. --- src/arch/arm/isa/decoder.isa | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 046e52950..36c229695 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -416,6 +416,15 @@ 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; }}); + } + } + } } format PredOp { // ARM System Call (SoftWare Interrupt) -- cgit v1.2.3 From c18d6cb1a72418b3ebf9c2df7ee339c43ee20484 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:53:29 -0700 Subject: ARM: Implement a basic version of the fmxr instruction. --- src/arch/arm/isa/decoder.isa | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 36c229695..4e6d925ac 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -423,6 +423,11 @@ format DataOp { 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; }}); + } } } } -- cgit v1.2.3 From 8ec235c7b189c3ae1bf13358774add595710cfd6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:54:09 -0700 Subject: ARM: Make native trace print out what instruction caused an error. --- src/arch/arm/nativetrace.cc | 15 +++++++++++++++ src/cpu/NativeTrace.py | 4 ++-- src/cpu/nativetrace.cc | 2 +- src/cpu/nativetrace.hh | 8 ++++---- 4 files changed, 22 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 2dd0b8575..7301653f4 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -86,6 +86,7 @@ Trace::ArmNativeTrace::check(NativeTraceRecord *record) nState.update(this); mState.update(record->getThread()); + bool errorFound = false; // Regular int regs for (int i = 0; i < STATE_NUMVALS; i++) { if (nState.changed[i] || mState.changed[i]) { @@ -104,6 +105,7 @@ Trace::ArmNativeTrace::check(NativeTraceRecord *record) vergence, regNames[i], nState.newState[i], mState.oldState[i], mState.newState[i]); + errorFound = true; } else if (!mState.changed[i]) { DPRINTF(ExecRegDelta, "%s [%5s] "\ "Native: %#010x => %#010x "\ @@ -111,6 +113,7 @@ Trace::ArmNativeTrace::check(NativeTraceRecord *record) vergence, regNames[i], nState.oldState[i], nState.newState[i], mState.newState[i]); + errorFound = true; } else if (mState.oldState[i] != nState.oldState[i] || mState.newState[i] != nState.newState[i]) { DPRINTF(ExecRegDelta, "%s [%5s] "\ @@ -119,9 +122,21 @@ Trace::ArmNativeTrace::check(NativeTraceRecord *record) vergence, regNames[i], nState.oldState[i], nState.newState[i], mState.oldState[i], mState.newState[i]); + errorFound = true; } } } + 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); + } } } /* namespace Trace */ diff --git a/src/cpu/NativeTrace.py b/src/cpu/NativeTrace.py index 7fd240543..dba6de067 100644 --- a/src/cpu/NativeTrace.py +++ b/src/cpu/NativeTrace.py @@ -28,9 +28,9 @@ from m5.SimObject import SimObject from m5.params import * -from InstTracer import InstTracer +from ExeTracer import ExeTracer -class NativeTrace(InstTracer): +class NativeTrace(ExeTracer): abstract = True type = 'NativeTrace' cxx_class = 'Trace::NativeTrace' diff --git a/src/cpu/nativetrace.cc b/src/cpu/nativetrace.cc index 47c58434f..8c17eb825 100644 --- a/src/cpu/nativetrace.cc +++ b/src/cpu/nativetrace.cc @@ -38,7 +38,7 @@ using namespace std; namespace Trace { NativeTrace::NativeTrace(const Params *p) - : InstTracer(p) + : ExeTracer(p) { if (ListenSocket::allDisabled()) fatal("All listeners are disabled!"); diff --git a/src/cpu/nativetrace.hh b/src/cpu/nativetrace.hh index 34869f263..6ad6b0242 100644 --- a/src/cpu/nativetrace.hh +++ b/src/cpu/nativetrace.hh @@ -37,8 +37,8 @@ #include "base/socket.hh" #include "base/trace.hh" #include "base/types.hh" +#include "cpu/exetrace.hh" #include "cpu/static_inst.hh" -#include "sim/insttracer.hh" class ThreadContext; @@ -46,7 +46,7 @@ namespace Trace { class NativeTrace; -class NativeTraceRecord : public InstRecord +class NativeTraceRecord : public ExeTracerRecord { protected: NativeTrace * parent; @@ -56,7 +56,7 @@ class NativeTraceRecord : public InstRecord Tick _when, ThreadContext *_thread, const StaticInstPtr _staticInst, Addr _pc, bool spec, const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0) - : InstRecord(_when, _thread, _staticInst, _pc, spec, + : ExeTracerRecord(_when, _thread, _staticInst, _pc, spec, _macroStaticInst, _upc), parent(_parent) { @@ -65,7 +65,7 @@ class NativeTraceRecord : public InstRecord void dump(); }; -class NativeTrace : public InstTracer +class NativeTrace : public ExeTracer { protected: int fd; -- cgit v1.2.3 From 90d3d3535b206fa011ab86ffc278c8851fe997a6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:54:24 -0700 Subject: imported patch nativetracestreamline.patch --- src/arch/arm/nativetrace.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 7301653f4..469869e56 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -91,13 +91,17 @@ Trace::ArmNativeTrace::check(NativeTraceRecord *record) for (int i = 0; i < STATE_NUMVALS; i++) { if (nState.changed[i] || mState.changed[i]) { const char *vergence = " "; - if (mState.oldState[i] == nState.oldState[i] && - mState.newState[i] != nState.newState[i]) { + 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 (mState.oldState[i] != nState.oldState[i] && - mState.newState[i] == nState.newState[i]) { + } else if (!oldMatch && newMatch) { vergence = "><"; } + errorFound = true; if (!nState.changed[i]) { DPRINTF(ExecRegDelta, "%s [%5s] "\ "Native: %#010x "\ @@ -105,7 +109,6 @@ Trace::ArmNativeTrace::check(NativeTraceRecord *record) vergence, regNames[i], nState.newState[i], mState.oldState[i], mState.newState[i]); - errorFound = true; } else if (!mState.changed[i]) { DPRINTF(ExecRegDelta, "%s [%5s] "\ "Native: %#010x => %#010x "\ @@ -113,16 +116,13 @@ Trace::ArmNativeTrace::check(NativeTraceRecord *record) vergence, regNames[i], nState.oldState[i], nState.newState[i], mState.newState[i]); - errorFound = true; - } else if (mState.oldState[i] != nState.oldState[i] || - mState.newState[i] != nState.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]); - errorFound = true; } } } -- cgit v1.2.3 From 52b4a7c36ffbfcf48f6360ace5b69c18adddfa7a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:54:30 -0700 Subject: ARM: Only send information that changed between statetrace and M5. --- src/arch/arm/nativetrace.cc | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 469869e56..7c9c70e0c 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -51,10 +51,31 @@ Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent) current = (current + 1) % 2; newState = state[current]; - parent->read(newState, sizeof(newState[0]) * STATE_NUMVALS); + 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++) { - newState[i] = ArmISA::gtoh(newState[i]); - changed[i] = (oldState[i] != newState[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]); + } } } -- cgit v1.2.3 From d3f2992e39183ff4e841d9fd3b9fac255446572f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:54:50 -0700 Subject: ARM: Decode fstmx and fldmx instructions. We can ignore them for now. --- src/arch/arm/isa/decoder.isa | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 4e6d925ac..a999b52e9 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -318,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 { -- cgit v1.2.3 From daf8718da9d84740db559ee123ab6994673ba5da Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 27 Jul 2009 00:54:55 -0700 Subject: ARM: Update some syscall constants and delete others that are Alpha only. --- src/arch/arm/linux/linux.hh | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index cc3b620ee..982652ddc 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(). @@ -86,11 +75,6 @@ class ArmLinux : public Linux static const int TGT_RUSAGE_BOTH = -2; //@} - //@{ - /// For setsysinfo(). - static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control() - //@} - //@{ /// ioctl() command codes. static const unsigned TIOCGETP_ = 0x40067408; @@ -114,12 +98,11 @@ 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 }; -- cgit v1.2.3 From 19a4fb0ff3fd8a28f77552912b04f165ca97889a Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 29 Jul 2009 00:09:44 -0700 Subject: ARM: Fix an ioctl constant. --- src/arch/arm/linux/linux.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index 982652ddc..d99fa8e49 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -77,7 +77,7 @@ class ArmLinux : public Linux //@{ /// 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; -- cgit v1.2.3 From 0a9eb59e6f8be32939c6a267e67943ef50b8ba83 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 29 Jul 2009 00:09:46 -0700 Subject: ARM: Ignore the "times" system call. --- src/arch/arm/linux/process.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index e72c3fb3c..75e3a67ca 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), -- cgit v1.2.3 From 873112ea9924074212f1dd667d345850c6dce789 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 29 Jul 2009 00:14:43 -0700 Subject: ARM: Make sure the target process doesn't run away from statetrace. --- src/arch/arm/nativetrace.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 7c9c70e0c..90c5e5c25 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -104,8 +104,13 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc) 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(record->getThread()); + mState.update(tc); bool errorFound = false; // Regular int regs -- cgit v1.2.3 From 2871a13ab31aaabea93f1d55595e199ea76e9dcf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 29 Jul 2009 00:15:26 -0700 Subject: Simple CPU: Make the simple CPU handle the IntRegs trace flag. --- src/cpu/simple_thread.hh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index d9d624e77..8a44eba37 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -262,7 +262,9 @@ class SimpleThread : public ThreadState { int flatIndex = isa.flattenIntIndex(reg_idx); assert(flatIndex < TheISA::NumIntRegs); - return intRegs[flatIndex]; + uint64_t regVal = intRegs[flatIndex]; + DPRINTF(IntRegs, "Reading int reg %d as %#x.\n", reg_idx, regVal); + return regVal; } FloatReg readFloatReg(int reg_idx) @@ -283,6 +285,7 @@ class SimpleThread : public ThreadState { int flatIndex = isa.flattenIntIndex(reg_idx); assert(flatIndex < TheISA::NumIntRegs); + DPRINTF(IntRegs, "Setting int reg %d to %#x.\n", reg_idx, val); intRegs[flatIndex] = val; } -- cgit v1.2.3 From 1e04b6281d864c1b1cbf819cb17595d90d20adbe Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 29 Jul 2009 00:17:11 -0700 Subject: ARM: Make the ARM native tracer stop M5 if control diverges. If the control flow of M5's executable and statetrace's target process get out of sync even a little, there will be a LOT of output, very little of which will be useful. There's also almost no hope for recovery. In those cases, we might as well give up and not generate a huge, mostly worthless trace file. --- src/arch/arm/ArmNativeTrace.py | 2 ++ src/arch/arm/nativetrace.cc | 5 +++++ src/arch/arm/nativetrace.hh | 14 +++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/arm/ArmNativeTrace.py b/src/arch/arm/ArmNativeTrace.py index fb3d4a4ff..0a76913e3 100644 --- a/src/arch/arm/ArmNativeTrace.py +++ b/src/arch/arm/ArmNativeTrace.py @@ -33,3 +33,5 @@ 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/nativetrace.cc b/src/arch/arm/nativetrace.cc index 90c5e5c25..1ad9e1a19 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -162,6 +162,11 @@ Trace::ArmNativeTrace::check(NativeTraceRecord *record) } 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!"); } } diff --git a/src/arch/arm/nativetrace.hh b/src/arch/arm/nativetrace.hh index d39bdcfa8..7467e3378 100644 --- a/src/arch/arm/nativetrace.hh +++ b/src/arch/arm/nativetrace.hh @@ -33,6 +33,7 @@ #include "base/types.hh" #include "cpu/nativetrace.hh" +#include "params/ArmNativeTrace.hh" namespace Trace { @@ -88,8 +89,19 @@ class ArmNativeTrace : public NativeTrace ThreadState nState, mState; + bool stopOnPCError; + public: - ArmNativeTrace(const Params *p) : NativeTrace(p) + typedef ArmNativeTraceParams Params; + + const Params * + params() const + { + return dynamic_cast(_params); + } + + ArmNativeTrace(const Params *p) : + NativeTrace(p), stopOnPCError(p->stop_on_pc_error) {} void check(NativeTraceRecord *record); -- cgit v1.2.3 From c2da5bae17436b87a9aa960eab2f77383f4e5a4c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 29 Jul 2009 00:17:20 -0700 Subject: ARM: Get rid of a stray line in the set_tls handler. --- src/arch/arm/linux/process.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index 75e3a67ca..6736a649d 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -418,7 +418,6 @@ setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { uint32_t tlsPtr = process->getSyscallArg(tc, 0); - TypedBufferArg name(process->getSyscallArg(tc, 0)); tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0, (uint8_t *)&tlsPtr, sizeof(tlsPtr)); -- cgit v1.2.3 From b066e717f4301bd5b882319d7d52e8bbd9c0b6c2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 29 Jul 2009 00:18:26 -0700 Subject: ARM: Fix an instruction in the cmpxchg kernel provided routine. The instruction was encoded as a load instead of the intended store. --- src/arch/arm/linux/process.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index 6736a649d..56e3588a7 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -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 }; -- cgit v1.2.3 From 4971331b4f8f9e79cf6dcc564a85fb432bef8b9c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 29 Jul 2009 22:24:00 -0700 Subject: ARM: Mul and mla ignore the c and v flags, but we were setting them to 1. --- src/arch/arm/isa/formats/pred.isa | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') 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)' -- cgit v1.2.3 From 3dd3de5feb31055a48acb39575da25a9cea2626d Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 30 Jul 2009 17:42:57 -0700 Subject: compile: fix accidental conversion of == into = --- src/arch/mips/mt.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') 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 + -- cgit v1.2.3