summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript93
-rw-r--r--arch/SConscript10
-rw-r--r--arch/alpha/arguments.cc2
-rw-r--r--arch/alpha/ev5.cc6
-rw-r--r--arch/alpha/isa/main.isa2
-rw-r--r--arch/alpha/isa_traits.hh279
-rw-r--r--arch/alpha/linux/process.cc13
-rw-r--r--arch/alpha/linux/process.hh8
-rw-r--r--arch/alpha/process.cc124
-rw-r--r--arch/alpha/process.hh34
-rw-r--r--arch/alpha/regfile.hh168
-rw-r--r--arch/alpha/system.cc1
-rw-r--r--arch/alpha/tlb.hh1
-rw-r--r--arch/alpha/tru64/process.cc21
-rw-r--r--arch/alpha/tru64/process.hh7
-rw-r--r--arch/alpha/types.hh64
-rw-r--r--arch/alpha/utility.hh156
-rwxr-xr-xarch/isa_parser.py34
-rw-r--r--arch/isa_specific.hh2
-rw-r--r--arch/mips/SConscript3
-rw-r--r--arch/mips/faults.cc151
-rw-r--r--arch/mips/faults.hh263
-rw-r--r--arch/mips/isa/base.isa25
-rw-r--r--arch/mips/isa/decoder.isa89
-rw-r--r--arch/mips/isa/formats/branch.isa10
-rw-r--r--arch/mips/isa/formats/noop.isa4
-rw-r--r--arch/mips/isa/formats/unimp.isa2
-rw-r--r--arch/mips/isa/formats/unknown.isa2
-rw-r--r--arch/mips/isa/includes.isa8
-rw-r--r--arch/mips/isa_traits.cc120
-rw-r--r--arch/mips/isa_traits.hh278
-rw-r--r--arch/mips/linux_process.cc717
-rw-r--r--arch/mips/linux_process.hh5
-rw-r--r--arch/mips/process.cc125
-rw-r--r--arch/mips/process.hh35
-rw-r--r--arch/mips/utility.hh34
-rw-r--r--arch/sparc/SConscript3
-rw-r--r--arch/sparc/faults.cc16
-rw-r--r--arch/sparc/faults.hh4
-rw-r--r--arch/sparc/isa/base.isa90
-rw-r--r--arch/sparc/isa/bitfields.isa14
-rw-r--r--arch/sparc/isa/decoder.isa1126
-rw-r--r--arch/sparc/isa/formats.isa11
-rw-r--r--arch/sparc/isa/formats/branch.isa3
-rw-r--r--arch/sparc/isa/formats/integerop.isa203
-rw-r--r--arch/sparc/isa/formats/mem.isa15
-rw-r--r--arch/sparc/isa/formats/noop.isa4
-rw-r--r--arch/sparc/isa/formats/priv.isa165
-rw-r--r--arch/sparc/isa/formats/trap.isa13
-rw-r--r--arch/sparc/isa/formats/unknown.isa46
-rw-r--r--arch/sparc/isa/includes.isa6
-rw-r--r--arch/sparc/isa/operands.isa81
-rw-r--r--arch/sparc/isa_traits.hh500
-rw-r--r--arch/sparc/linux/process.cc580
-rw-r--r--arch/sparc/linux/process.hh7
-rw-r--r--arch/sparc/process.cc123
-rw-r--r--arch/sparc/process.hh33
-rw-r--r--arch/sparc/regfile.hh520
-rw-r--r--base/chunk_generator.hh137
-rw-r--r--base/intmath.hh4
-rw-r--r--base/loader/aout_object.cc26
-rw-r--r--base/loader/aout_object.hh2
-rw-r--r--base/loader/ecoff_object.cc26
-rw-r--r--base/loader/ecoff_object.hh2
-rw-r--r--base/loader/elf_object.cc48
-rw-r--r--base/loader/elf_object.hh5
-rw-r--r--base/loader/object_file.cc34
-rw-r--r--base/loader/object_file.hh16
-rw-r--r--base/remote_gdb.cc4
-rw-r--r--base/traceflags.py1
-rwxr-xr-xconfigs/test/hellobin0 -> 312176 bytes
-rwxr-xr-xconfigs/test/hello_mipsbin0 -> 623837 bytes
-rw-r--r--configs/test/test.py10
-rw-r--r--cpu/base.cc3
-rw-r--r--cpu/base.hh7
-rw-r--r--cpu/cpu_exec_context.cc39
-rw-r--r--cpu/cpu_exec_context.hh125
-rw-r--r--cpu/exec_context.hh84
-rw-r--r--cpu/exetrace.cc3
-rw-r--r--cpu/o3/alpha_cpu.hh4
-rw-r--r--cpu/o3/alpha_cpu_impl.hh12
-rw-r--r--cpu/o3/alpha_dyn_inst.hh36
-rw-r--r--cpu/o3/cpu.cc47
-rw-r--r--cpu/o3/cpu.hh16
-rw-r--r--cpu/o3/regfile.hh80
-rw-r--r--cpu/op_class.cc50
-rw-r--r--cpu/op_class.hh (renamed from encumbered/cpu/full/op_class.hh)38
-rw-r--r--cpu/ozone/cpu.hh36
-rw-r--r--cpu/pc_event.hh5
-rw-r--r--cpu/simple/cpu.cc420
-rw-r--r--cpu/simple/cpu.hh152
-rw-r--r--cpu/static_inst.hh14
-rw-r--r--dev/alpha_console.cc1
-rw-r--r--dev/ide_ctrl.cc1
-rw-r--r--dev/io_device.cc111
-rw-r--r--dev/io_device.hh147
-rw-r--r--dev/isa_fake.cc1
-rw-r--r--dev/ns_gige.cc1
-rw-r--r--dev/pciconfigall.cc1
-rw-r--r--dev/platform.hh4
-rw-r--r--dev/tsunami_cchip.cc1
-rw-r--r--dev/tsunami_io.cc1
-rw-r--r--dev/tsunami_pchip.cc1
-rw-r--r--dev/uart8250.cc1
-rw-r--r--kern/linux/linux.hh14
-rw-r--r--kern/tru64/tru64.hh96
-rw-r--r--kern/tru64/tru64_events.cc1
-rw-r--r--mem/bus.hh128
-rw-r--r--mem/mem_object.cc37
-rw-r--r--mem/mem_object.hh54
-rw-r--r--mem/packet.hh125
-rw-r--r--mem/page_table.cc131
-rw-r--r--mem/page_table.hh90
-rw-r--r--mem/physical.cc352
-rw-r--r--mem/physical.hh134
-rw-r--r--mem/port.cc76
-rw-r--r--mem/port.hh223
-rw-r--r--mem/request.hh107
-rw-r--r--mem/translating_port.cc186
-rw-r--r--mem/translating_port.hh62
-rw-r--r--python/m5/objects/BaseCPU.py4
-rw-r--r--python/m5/objects/Ethernet.py1
-rw-r--r--python/m5/objects/MemObject.py5
-rw-r--r--python/m5/objects/PhysicalMemory.py7
-rw-r--r--python/m5/objects/Process.py10
-rw-r--r--python/m5/objects/Root.py4
-rw-r--r--python/m5/objects/System.py17
-rw-r--r--sim/byteswap.hh4
-rw-r--r--sim/faults.cc1
-rw-r--r--sim/host.hh2
-rw-r--r--sim/process.cc216
-rw-r--r--sim/process.hh79
-rw-r--r--sim/syscall_emul.cc37
-rw-r--r--sim/syscall_emul.hh79
-rw-r--r--sim/system.cc86
-rw-r--r--sim/system.hh48
-rwxr-xr-xutil/qdo4
137 files changed, 7109 insertions, 3527 deletions
diff --git a/SConscript b/SConscript
index 8afac510b..ae77cbbc6 100644
--- a/SConscript
+++ b/SConscript
@@ -81,67 +81,18 @@ base_sources = Split('''
base/stats/text.cc
cpu/base.cc
- cpu/base_dyn_inst.cc
cpu/cpu_exec_context.cc
cpu/exetrace.cc
+ cpu/op_class.cc
cpu/pc_event.cc
cpu/static_inst.cc
cpu/sampler/sampler.cc
- cpu/trace/reader/mem_trace_reader.cc
- cpu/trace/reader/ibm_reader.cc
- cpu/trace/reader/itx_reader.cc
- cpu/trace/reader/m5_reader.cc
- cpu/trace/opt_cpu.cc
- cpu/trace/trace_cpu.cc
- encumbered/mem/functional/main.cc
-
- mem/base_hier.cc
- mem/base_mem.cc
- mem/hier_params.cc
- mem/mem_cmd.cc
- mem/mem_debug.cc
- mem/mem_req.cc
- mem/memory_interface.cc
- mem/bus/base_interface.cc
- mem/bus/bus.cc
- mem/bus/bus_bridge.cc
- mem/bus/bus_bridge_master.cc
- mem/bus/bus_bridge_slave.cc
- mem/bus/bus_interface.cc
- mem/bus/dma_bus_interface.cc
- mem/bus/dma_interface.cc
- mem/bus/master_interface.cc
- mem/bus/slave_interface.cc
- mem/cache/base_cache.cc
- mem/cache/cache.cc
- mem/cache/cache_builder.cc
- mem/cache/coherence/coherence_protocol.cc
- mem/cache/coherence/uni_coherence.cc
- mem/cache/miss/blocking_buffer.cc
- mem/cache/miss/miss_queue.cc
- mem/cache/miss/mshr.cc
- mem/cache/miss/mshr_queue.cc
- mem/cache/prefetch/base_prefetcher.cc
- mem/cache/prefetch/prefetcher.cc
- mem/cache/prefetch/tagged_prefetcher.cc
- mem/cache/tags/base_tags.cc
- mem/cache/tags/cache_tags.cc
- mem/cache/tags/fa_lru.cc
- mem/cache/tags/iic.cc
- mem/cache/tags/lru.cc
- mem/cache/tags/repl/gen.cc
- mem/cache/tags/repl/repl.cc
- mem/cache/tags/split.cc
- mem/cache/tags/split_lru.cc
- mem/cache/tags/split_lifo.cc
- mem/functional/functional.cc
- mem/timing/base_memory.cc
- mem/timing/memory_builder.cc
- mem/timing/simple_mem_bank.cc
- mem/trace/itx_writer.cc
- mem/trace/mem_trace_writer.cc
- mem/trace/m5_writer.cc
+ mem/mem_object.cc
+ mem/page_table.cc
+ mem/physical.cc
+ mem/port.cc
+ mem/translating_port.cc
python/pyconfig.cc
python/embedded_py.cc
@@ -162,6 +113,7 @@ base_sources = Split('''
sim/startup.cc
sim/stat_context.cc
sim/stat_control.cc
+ sim/system.cc
sim/trace_context.cc
''')
@@ -204,6 +156,17 @@ full_cpu_sources = Split('''
encumbered/cpu/full/iq/standard/iq_standard.cc
''')
+trace_reader_sources = Split('''
+ cpu/trace/reader/mem_trace_reader.cc
+ cpu/trace/reader/ibm_reader.cc
+ cpu/trace/reader/itx_reader.cc
+ cpu/trace/reader/m5_reader.cc
+ cpu/trace/opt_cpu.cc
+ cpu/trace/trace_cpu.cc
+ ''')
+
+
+
# MySql sources
mysql_sources = Split('''
base/mysql.cc
@@ -260,9 +223,6 @@ full_system_sources = Split('''
kern/tru64/tru64_syscalls.cc
mem/functional/memory_control.cc
- mem/functional/physical.cc
-
- sim/system.cc
sim/pseudo_inst.cc
''')
@@ -288,16 +248,25 @@ turbolaser_sources = Split('''
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
- cpu/memtest/memtest.cc
- encumbered/eio/eio.cc
- encumbered/eio/exolex.cc
- encumbered/eio/libexo.cc
kern/linux/linux.cc
kern/tru64/tru64.cc
sim/process.cc
sim/syscall_emul.cc
''')
+alpha_eio_sources = Split('''
+ encumbered/eio/exolex.cc
+ encumbered/eio/libexo.cc
+ encumbered/eio/eio.cc
+ ''')
+
+if env['TARGET_ISA'] == 'ALPHA_ISA':
+ syscall_emulation_sources += alpha_eio_sources
+
+memtest_sources = Split('''
+ cpu/memtest/memtest.cc
+ ''')
+
# Add a flag defining what THE_ISA should be for all compilation
env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
diff --git a/arch/SConscript b/arch/SConscript
index 0533261a2..d88d10368 100644
--- a/arch/SConscript
+++ b/arch/SConscript
@@ -45,13 +45,17 @@ sources = []
# List of headers to generate
isa_switch_hdrs = Split('''
+ arguments.hh
+ constants.hh
+ faults.hh
isa_traits.hh
- tlb.hh
process.hh
- arguments.hh
+ regfile.hh
stacktrace.hh
+ tlb.hh
+ types.hh
+ utility.hh
vtophys.hh
- faults.hh
''')
# Generate the header. target[0] is the full path of the output
diff --git a/arch/alpha/arguments.cc b/arch/alpha/arguments.cc
index 019390aeb..a782ea330 100644
--- a/arch/alpha/arguments.cc
+++ b/arch/alpha/arguments.cc
@@ -54,7 +54,7 @@ AlphaArguments::getArg(bool fp)
{
if (number < 6) {
if (fp)
- return xc->readFloatRegInt(16 + number);
+ return xc->readFloatRegBits(16 + number);
else
return xc->readIntReg(16 + number);
} else {
diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc
index 019e83dd4..a5a8851c2 100644
--- a/arch/alpha/ev5.cc
+++ b/arch/alpha/ev5.cc
@@ -134,7 +134,7 @@ AlphaISA::zeroRegisters(CPU *cpu)
// (no longer very clean due to the change in setIntReg() in the
// cpu model. Consider changing later.)
cpu->cpuXC->setIntReg(ZeroReg, 0);
- cpu->cpuXC->setFloatRegDouble(ZeroReg, 0.0);
+ cpu->cpuXC->setFloatReg(ZeroReg, 0.0);
}
Fault
@@ -542,10 +542,10 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
}
void
-AlphaISA::MiscRegFile::copyIprs(ExecContext *xc)
+AlphaISA::copyIprs(ExecContext *src, ExecContext *dest)
{
for (int i = IPR_Base_DepTag; i < NumInternalProcRegs; ++i) {
- ipr[i] = xc->readMiscReg(i);
+ dest->setMiscReg(i, src->readMiscReg(i));
}
}
diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa
index 17c9989ab..d4c744fbc 100644
--- a/arch/alpha/isa/main.isa
+++ b/arch/alpha/isa/main.isa
@@ -34,7 +34,7 @@ output header {{
#include "config/ss_compatible_fp.hh"
#include "cpu/static_inst.hh"
#include "arch/alpha/faults.hh"
-#include "mem/mem_req.hh" // some constructors use MemReq flags
+#include "mem/request.hh" // some constructors use MemReq flags
}};
output decoder {{
diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh
index 878193881..5f8b00c40 100644
--- a/arch/alpha/isa_traits.hh
+++ b/arch/alpha/isa_traits.hh
@@ -30,29 +30,15 @@
#define __ARCH_ALPHA_ISA_TRAITS_HH__
namespace LittleEndianGuest {}
-using namespace LittleEndianGuest;
-//#include "arch/alpha/faults.hh"
-#include "base/misc.hh"
+#include "arch/alpha/types.hh"
+#include "arch/alpha/constants.hh"
+#include "arch/alpha/regfile.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
-#include "sim/faults.hh"
-
-class ExecContext;
-class FastCPU;
-class FullCPU;
-class Checkpoint;
-
-#define TARGET_ALPHA
-class StaticInst;
class StaticInstPtr;
-namespace EV5 {
-int DTB_ASN_ASN(uint64_t reg);
-int ITB_ASN_ASN(uint64_t reg);
-}
-
#if !FULL_SYSTEM
class SyscallReturn {
public:
@@ -89,261 +75,22 @@ class SyscallReturn {
#endif
-
-
namespace AlphaISA
{
- typedef uint32_t MachInst;
- typedef uint64_t ExtMachInst;
- typedef uint8_t RegIndex;
-
- const int NumIntArchRegs = 32;
- const int NumPALShadowRegs = 8;
- const int NumFloatArchRegs = 32;
- // @todo: Figure out what this number really should be.
- const int NumMiscArchRegs = 32;
-
- // Static instruction parameters
- const int MaxInstSrcRegs = 3;
- const int MaxInstDestRegs = 2;
-
- // semantically meaningful register indices
- const int ZeroReg = 31; // architecturally meaningful
- // the rest of these depend on the ABI
- const int StackPointerReg = 30;
- const int GlobalPointerReg = 29;
- const int ProcedureValueReg = 27;
- const int ReturnAddressReg = 26;
- const int ReturnValueReg = 0;
- const int FramePointerReg = 15;
- const int ArgumentReg0 = 16;
- const int ArgumentReg1 = 17;
- const int ArgumentReg2 = 18;
- const int ArgumentReg3 = 19;
- const int ArgumentReg4 = 20;
- const int ArgumentReg5 = 21;
- const int SyscallNumReg = ReturnValueReg;
- const int SyscallPseudoReturnReg = ArgumentReg4;
- const int SyscallSuccessReg = 19;
-
-
-
- const int LogVMPageSize = 13; // 8K bytes
- const int VMPageSize = (1 << LogVMPageSize);
-
- const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
-
- const int WordBytes = 4;
- const int HalfwordBytes = 2;
- const int ByteBytes = 1;
-
-
- const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
- const int NumFloatRegs = NumFloatArchRegs;
- const int NumMiscRegs = NumMiscArchRegs;
-
- // These enumerate all the registers for dependence tracking.
- enum DependenceTags {
- // 0..31 are the integer regs 0..31
- // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
- FP_Base_DepTag = 40,
- Ctrl_Base_DepTag = 72,
- Fpcr_DepTag = 72, // floating point control register
- Uniq_DepTag = 73,
- Lock_Flag_DepTag = 74,
- Lock_Addr_DepTag = 75,
- IPR_Base_DepTag = 76
- };
-
- typedef uint64_t IntReg;
- typedef IntReg IntRegFile[NumIntRegs];
-
- // floating point register file entry type
- typedef union {
- uint64_t q;
- double d;
- } FloatReg;
-
- typedef union {
- uint64_t q[NumFloatRegs]; // integer qword view
- double d[NumFloatRegs]; // double-precision floating point view
- } FloatRegFile;
-
-extern const Addr PageShift;
-extern const Addr PageBytes;
-extern const Addr PageMask;
-extern const Addr PageOffset;
+using namespace LittleEndianGuest;
// redirected register map, really only used for the full system case.
extern const int reg_redir[NumIntRegs];
#if FULL_SYSTEM
- typedef uint64_t InternalProcReg;
-
#include "arch/alpha/isa_fullsys_traits.hh"
-#else
- const int NumInternalProcRegs = 0;
-#endif
-
- // control register file contents
- typedef uint64_t MiscReg;
- class MiscRegFile {
- protected:
- uint64_t fpcr; // floating point condition codes
- uint64_t uniq; // process-unique register
- bool lock_flag; // lock flag for LL/SC
- Addr lock_addr; // lock address for LL/SC
-
- public:
- MiscReg readReg(int misc_reg);
-
- //These functions should be removed once the simplescalar cpu model
- //has been replaced.
- int getInstAsid();
- int getDataAsid();
-
- MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
-
- Fault setReg(int misc_reg, const MiscReg &val);
-
- Fault setRegWithEffect(int misc_reg, const MiscReg &val,
- ExecContext *xc);
-
- void copyMiscRegs(ExecContext *xc);
-
-#if FULL_SYSTEM
- protected:
- InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
-
- private:
- MiscReg readIpr(int idx, Fault &fault, ExecContext *xc);
-
- Fault setIpr(int idx, uint64_t val, ExecContext *xc);
-
- void copyIprs(ExecContext *xc);
#endif
- friend class RegFile;
- };
-
- const int TotalNumRegs = NumIntRegs + NumFloatRegs +
- NumMiscRegs + NumInternalProcRegs;
-
- const int TotalDataRegs = NumIntRegs + NumFloatRegs;
-
- typedef union {
- IntReg intreg;
- FloatReg fpreg;
- MiscReg ctrlreg;
- } AnyReg;
-
- struct RegFile {
- IntRegFile intRegFile; // (signed) integer register file
- FloatRegFile floatRegFile; // floating point register file
- MiscRegFile miscRegs; // control register file
- Addr pc; // program counter
- Addr npc; // next-cycle program counter
- Addr nnpc;
-
-#if FULL_SYSTEM
- int intrflag; // interrupt flag
- inline int instAsid()
- { return EV5::ITB_ASN_ASN(miscRegs.ipr[IPR_ITB_ASN]); }
- inline int dataAsid()
- { return EV5::DTB_ASN_ASN(miscRegs.ipr[IPR_DTB_ASN]); }
-#endif // FULL_SYSTEM
-
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
- };
-
- static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc);
StaticInstPtr decodeInst(ExtMachInst);
- // return a no-op instruction... used for instruction fetch faults
- extern const ExtMachInst NoopMachInst;
-
- enum annotes {
- ANNOTE_NONE = 0,
- // An impossible number for instruction annotations
- ITOUCH_ANNOTE = 0xffffffff,
- };
-
- static inline bool isCallerSaveIntegerRegister(unsigned int reg) {
- panic("register classification not implemented");
- return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
- }
-
- static inline bool isCalleeSaveIntegerRegister(unsigned int reg) {
- panic("register classification not implemented");
- return (reg >= 9 && reg <= 15);
- }
-
- static inline bool isCallerSaveFloatRegister(unsigned int reg) {
- panic("register classification not implemented");
- return false;
- }
-
- static inline bool isCalleeSaveFloatRegister(unsigned int reg) {
- panic("register classification not implemented");
- return false;
- }
-
- static inline Addr alignAddress(const Addr &addr,
- unsigned int nbytes) {
- return (addr & ~(nbytes - 1));
- }
-
- // Instruction address compression hooks
- static inline Addr realPCToFetchPC(const Addr &addr) {
- return addr;
- }
-
- static inline Addr fetchPCToRealPC(const Addr &addr) {
- return addr;
- }
-
- // the size of "fetched" instructions (not necessarily the size
- // of real instructions for PISA)
- static inline size_t fetchInstSize() {
- return sizeof(MachInst);
- }
-
- static inline MachInst makeRegisterCopy(int dest, int src) {
- panic("makeRegisterCopy not implemented");
- return 0;
- }
-
- // Machine operations
-
- void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
- int regnum);
-
- void restoreMachineReg(RegFile &regs, const AnyReg &reg,
- int regnum);
-
-#if 0
- static void serializeSpecialRegs(const Serializable::Proxy &proxy,
- const RegFile &regs);
-
- static void unserializeSpecialRegs(const IniFile *db,
- const std::string &category,
- ConfigNode *node,
- RegFile &regs);
-#endif
-
- /**
- * Function to insure ISA semantics about 0 registers.
- * @param xc The execution context.
- */
- template <class XC>
- void zeroRegisters(XC *xc);
-
- const Addr MaxAddr = (Addr)-1;
-
#if !FULL_SYSTEM
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
{
@@ -363,22 +110,4 @@ extern const int reg_redir[NumIntRegs];
#endif
};
-static inline AlphaISA::ExtMachInst
-AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) {
-#if FULL_SYSTEM
- AlphaISA::ExtMachInst ext_inst = inst;
- if (pc && 0x1)
- return ext_inst|=(static_cast<AlphaISA::ExtMachInst>(pc & 0x1) << 32);
- else
- return ext_inst;
-#else
- return AlphaISA::ExtMachInst(inst);
-#endif
-}
-
-#if FULL_SYSTEM
-
-#include "arch/alpha/ev5.hh"
-#endif
-
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__
diff --git a/arch/alpha/linux/process.cc b/arch/alpha/linux/process.cc
index 1c911bc50..4bc283563 100644
--- a/arch/alpha/linux/process.cc
+++ b/arch/alpha/linux/process.cc
@@ -32,7 +32,6 @@
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "kern/linux/linux.hh"
-#include "mem/functional/functional.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
@@ -55,7 +54,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "alpha");
- name.copyOut(xc->getMemPtr());
+ name.copyOut(xc->getMemPort());
return 0;
}
@@ -75,7 +74,7 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
- fpcr.copyOut(xc->getMemPtr());
+ fpcr.copyOut(xc->getMemPort());
return 0;
}
@@ -101,7 +100,7 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
- fpcr.copyIn(xc->getMemPtr());
+ fpcr.copyIn(xc->getMemPort());
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0;
@@ -567,15 +566,17 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name,
ObjectFile *objFile,
+ System *system,
int stdin_fd,
int stdout_fd,
int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp)
- : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp),
+ : AlphaLiveProcess(name, objFile, system, stdin_fd, stdout_fd,
+ stderr_fd, argv, envp),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
- init_regs->intRegFile[0] = 0;
+ //init_regs->intRegFile[0] = 0;
}
diff --git a/arch/alpha/linux/process.hh b/arch/alpha/linux/process.hh
index 7de1b1ac1..2e0566665 100644
--- a/arch/alpha/linux/process.hh
+++ b/arch/alpha/linux/process.hh
@@ -29,16 +29,18 @@
#ifndef __ALPHA_LINUX_PROCESS_HH__
#define __ALPHA_LINUX_PROCESS_HH__
-#include "sim/process.hh"
+#include "arch/alpha/process.hh"
+namespace AlphaISA {
/// A process with emulated Alpha/Linux syscalls.
-class AlphaLinuxProcess : public LiveProcess
+class AlphaLinuxProcess : public AlphaLiveProcess
{
public:
/// Constructor.
AlphaLinuxProcess(const std::string &name,
ObjectFile *objFile,
+ System *system,
int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp);
@@ -54,5 +56,5 @@ class AlphaLinuxProcess : public LiveProcess
const int Num_Syscall_Descs;
};
-
+} // namespace AlphaISA
#endif // __ALPHA_LINUX_PROCESS_HH__
diff --git a/arch/alpha/process.cc b/arch/alpha/process.cc
index b2dbe7ad1..25ee79692 100644
--- a/arch/alpha/process.cc
+++ b/arch/alpha/process.cc
@@ -26,28 +26,44 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "arch/alpha/constants.hh"
#include "arch/alpha/process.hh"
+#include "arch/alpha/linux/process.hh"
+#include "arch/alpha/tru64/process.hh"
+#include "base/loader/object_file.hh"
+#include "base/misc.hh"
+#include "cpu/exec_context.hh"
+#include "sim/builder.hh"
+#include "sim/system.hh"
-namespace AlphaISA
-{
-LiveProcess *
-createProcess(const std::string &nm, ObjectFile * objFile,
- int stdin_fd, int stdout_fd, int stderr_fd,
+using namespace AlphaISA;
+using namespace std;
+
+AlphaLiveProcess *
+AlphaLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
+ int stdout_fd, int stderr_fd, std::string executable,
std::vector<std::string> &argv, std::vector<std::string> &envp)
{
- LiveProcess * process = NULL;
+ AlphaLiveProcess *process = NULL;
+
+ ObjectFile *objFile = createObjectFile(executable);
+ if (objFile == NULL) {
+ fatal("Can't load object file %s", executable);
+ }
+
+
if (objFile->getArch() != ObjectFile::Alpha)
fatal("Object file does not match architecture.");
switch (objFile->getOpSys()) {
case ObjectFile::Tru64:
- process = new AlphaTru64Process(nm, objFile,
+ process = new AlphaTru64Process(nm, objFile, system,
stdin_fd, stdout_fd, stderr_fd,
argv, envp);
break;
case ObjectFile::Linux:
- process = new AlphaLinuxProcess(nm, objFile,
+ process = new AlphaLinuxProcess(nm, objFile, system,
stdin_fd, stdout_fd, stderr_fd,
argv, envp);
break;
@@ -55,7 +71,97 @@ createProcess(const std::string &nm, ObjectFile * objFile,
default:
fatal("Unknown/unsupported operating system.");
}
+
+ if (process == NULL)
+ fatal("Unknown error creating process object.");
return process;
}
-} // namespace AlphaISA
+AlphaLiveProcess::AlphaLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv, std::vector<std::string> &envp)
+ : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp)
+{
+ brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
+ brk_point = roundUp(brk_point, VMPageSize);
+
+ // Set up stack. On Alpha, stack goes below text section. This
+ // code should get moved to some architecture-specific spot.
+ stack_base = objFile->textBase() - (409600+4096);
+
+ // Set up region for mmaps. Tru64 seems to start just above 0 and
+ // grow up from there.
+ mmap_start = mmap_end = 0x10000;
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+}
+
+void
+AlphaLiveProcess::startup()
+{
+ argsInit(MachineBytes, VMPageSize);
+
+ execContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer());
+}
+
+
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess)
+
+ VectorParam<string> cmd;
+ Param<string> executable;
+ Param<string> input;
+ Param<string> output;
+ VectorParam<string> env;
+ SimObjectParam<System *> system;
+
+END_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess)
+
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess)
+
+ INIT_PARAM(cmd, "command line (executable plus arguments)"),
+ INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
+ INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
+ INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
+ INIT_PARAM(env, "environment settings"),
+ INIT_PARAM(system, "system")
+
+END_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess)
+
+
+CREATE_SIM_OBJECT(AlphaLiveProcess)
+{
+ string in = input;
+ string out = output;
+
+ // initialize file descriptors to default: same as simulator
+ int stdin_fd, stdout_fd, stderr_fd;
+
+ if (in == "stdin" || in == "cin")
+ stdin_fd = STDIN_FILENO;
+ else
+ stdin_fd = Process::openInputFile(input);
+
+ if (out == "stdout" || out == "cout")
+ stdout_fd = STDOUT_FILENO;
+ else if (out == "stderr" || out == "cerr")
+ stdout_fd = STDERR_FILENO;
+ else
+ stdout_fd = Process::openOutputFile(out);
+
+ stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
+
+ return AlphaLiveProcess::create(getInstanceName(), system,
+ stdin_fd, stdout_fd, stderr_fd,
+ (string)executable == "" ? cmd[0] : executable,
+ cmd, env);
+}
+
+
+REGISTER_SIM_OBJECT("AlphaLiveProcess", AlphaLiveProcess)
+
diff --git a/arch/alpha/process.hh b/arch/alpha/process.hh
index 4a2a4212e..d97b36e2d 100644
--- a/arch/alpha/process.hh
+++ b/arch/alpha/process.hh
@@ -30,19 +30,35 @@
#define __ALPHA_PROCESS_HH__
#include <string>
+#include <vector>
+#include "sim/process.hh"
-#include "arch/alpha/linux/process.hh"
-#include "arch/alpha/tru64/process.hh"
-#include "base/loader/object_file.hh"
+class ObjectFile;
+class System;
-namespace AlphaISA
+
+class AlphaLiveProcess : public LiveProcess
{
+ protected:
+ AlphaLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
+
+ void startup();
+
+ public:
+ // this function is used to create the LiveProcess object, since
+ // we can't tell which subclass of LiveProcess to use until we
+ // open and look at the object file.
+ static AlphaLiveProcess *create(const std::string &nm,
+ System *_system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::string executable,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
-LiveProcess *
-createProcess(const std::string &nm, ObjectFile * objFile,
- int stdin_fd, int stdout_fd, int stderr_fd,
- std::vector<std::string> &argv, std::vector<std::string> &envp);
+};
-} // namespace AlphaISA
#endif // __ALPHA_PROCESS_HH__
diff --git a/arch/alpha/regfile.hh b/arch/alpha/regfile.hh
new file mode 100644
index 000000000..8a11a8eb6
--- /dev/null
+++ b/arch/alpha/regfile.hh
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ */
+
+#ifndef __ARCH_ALPHA_REGFILE_HH__
+#define __ARCH_ALPHA_REGFILE_HH__
+
+#include "arch/alpha/types.hh"
+#include "arch/alpha/constants.hh"
+#include "sim/faults.hh"
+
+class Checkpoint;
+class ExecContext;
+
+namespace AlphaISA
+{
+
+ typedef IntReg IntRegFile[NumIntRegs];
+
+ class FloatRegFile
+ {
+ protected:
+
+ union {
+ uint64_t q[NumFloatRegs]; // integer qword view
+ double d[NumFloatRegs]; // double-precision floating point view
+ };
+
+ public:
+
+ FloatReg readReg(int floatReg)
+ {
+ return d[floatReg];
+ }
+
+ FloatReg readReg(int floatReg, int width)
+ {
+ return readReg(floatReg);
+ }
+
+ FloatRegBits readRegBits(int floatReg)
+ {
+ return q[floatReg];
+ }
+
+ FloatRegBits readRegBits(int floatReg, int width)
+ {
+ return readRegBits(floatReg);
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val)
+ {
+ d[floatReg] = val;
+ return NoFault;
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val, int width)
+ {
+ return setReg(floatReg, val);
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val)
+ {
+ q[floatReg] = val;
+ return NoFault;
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+ return setRegBits(floatReg, val);
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ };
+
+ class MiscRegFile {
+ protected:
+ uint64_t fpcr; // floating point condition codes
+ uint64_t uniq; // process-unique register
+ bool lock_flag; // lock flag for LL/SC
+ Addr lock_addr; // lock address for LL/SC
+
+ public:
+ MiscReg readReg(int misc_reg);
+
+ //These functions should be removed once the simplescalar cpu model
+ //has been replaced.
+ int getInstAsid();
+ int getDataAsid();
+
+ MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
+
+ Fault setReg(int misc_reg, const MiscReg &val);
+
+ Fault setRegWithEffect(int misc_reg, const MiscReg &val,
+ ExecContext *xc);
+
+#if FULL_SYSTEM
+ protected:
+ typedef uint64_t InternalProcReg;
+
+ InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
+
+ private:
+ InternalProcReg readIpr(int idx, Fault &fault, ExecContext *xc);
+
+ Fault setIpr(int idx, InternalProcReg val, ExecContext *xc);
+#endif
+ friend class RegFile;
+ };
+
+ struct RegFile {
+ IntRegFile intRegFile; // (signed) integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegs; // control register file
+ Addr pc; // program counter
+ Addr npc; // next-cycle program counter
+ Addr nnpc;
+
+#if FULL_SYSTEM
+ int intrflag; // interrupt flag
+ inline int instAsid()
+ { return miscRegs.getInstAsid(); }
+ inline int dataAsid()
+ { return miscRegs.getDataAsid(); }
+#endif // FULL_SYSTEM
+
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+
+ void copyRegs(ExecContext *src, ExecContext *dest);
+
+ void copyMiscRegs(ExecContext *src, ExecContext *dest);
+
+#if FULL_SYSTEM
+ void copyIprs(ExecContext *src, ExecContext *dest);
+#endif
+} // namespace AlphaISA
+
+#endif
diff --git a/arch/alpha/system.cc b/arch/alpha/system.cc
index 25543da57..547e89cff 100644
--- a/arch/alpha/system.cc
+++ b/arch/alpha/system.cc
@@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "arch/alpha/ev5.hh"
#include "arch/alpha/system.hh"
#include "arch/vtophys.hh"
#include "base/remote_gdb.hh"
diff --git a/arch/alpha/tlb.hh b/arch/alpha/tlb.hh
index de955fa46..1c299e8b9 100644
--- a/arch/alpha/tlb.hh
+++ b/arch/alpha/tlb.hh
@@ -31,6 +31,7 @@
#include <map>
+#include "arch/alpha/ev5.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/faults.hh"
#include "base/statistics.hh"
diff --git a/arch/alpha/tru64/process.cc b/arch/alpha/tru64/process.cc
index ae83bb649..355d7f3e6 100644
--- a/arch/alpha/tru64/process.cc
+++ b/arch/alpha/tru64/process.cc
@@ -30,7 +30,6 @@
#include "arch/alpha/tru64/process.hh"
#include "cpu/exec_context.hh"
#include "kern/tru64/tru64.hh"
-#include "mem/functional/functional.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
@@ -50,7 +49,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "732");
strcpy(name->machine, "alpha");
- name.copyOut(xc->getMemPtr());
+ name.copyOut(xc->getMemPort());
return 0;
}
@@ -67,21 +66,21 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
case Tru64::GSI_MAX_CPU: {
TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1));
*max_cpu = htog((uint32_t)process->numCpus());
- max_cpu.copyOut(xc->getMemPtr());
+ max_cpu.copyOut(xc->getMemPort());
return 1;
}
case Tru64::GSI_CPUS_IN_BOX: {
TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1));
*cpus_in_box = htog((uint32_t)process->numCpus());
- cpus_in_box.copyOut(xc->getMemPtr());
+ cpus_in_box.copyOut(xc->getMemPort());
return 1;
}
case Tru64::GSI_PHYSMEM: {
TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1));
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
- physmem.copyOut(xc->getMemPtr());
+ physmem.copyOut(xc->getMemPort());
return 1;
}
@@ -98,14 +97,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
infop->cpu_ex_binding = htog(0);
infop->mhz = htog(667);
- infop.copyOut(xc->getMemPtr());
+ infop.copyOut(xc->getMemPort());
return 1;
}
case Tru64::GSI_PROC_TYPE: {
TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1));
*proc_type = htog((uint64_t)11);
- proc_type.copyOut(xc->getMemPtr());
+ proc_type.copyOut(xc->getMemPort());
return 1;
}
@@ -114,14 +113,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
strncpy((char *)bufArg.bufferPtr(),
"COMPAQ Professional Workstation XP1000",
nbytes);
- bufArg.copyOut(xc->getMemPtr());
+ bufArg.copyOut(xc->getMemPort());
return 1;
}
case Tru64::GSI_CLK_TCK: {
TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1));
*clk_hz = htog((uint64_t)1024);
- clk_hz.copyOut(xc->getMemPtr());
+ clk_hz.copyOut(xc->getMemPort());
return 1;
}
@@ -530,12 +529,14 @@ AlphaTru64Process::getDesc(int callnum)
AlphaTru64Process::AlphaTru64Process(const std::string &name,
ObjectFile *objFile,
+ System *system,
int stdin_fd,
int stdout_fd,
int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp)
- : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp),
+ : AlphaLiveProcess(name, objFile, system, stdin_fd, stdout_fd,
+ stderr_fd, argv, envp),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)),
Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc))
{
diff --git a/arch/alpha/tru64/process.hh b/arch/alpha/tru64/process.hh
index 051760702..1cde4cac0 100644
--- a/arch/alpha/tru64/process.hh
+++ b/arch/alpha/tru64/process.hh
@@ -29,15 +29,17 @@
#ifndef __ALPHA_TRU64_PROCESS_HH__
#define __ALPHA_TRU64_PROCESS_HH__
-#include "sim/process.hh"
+#include "arch/alpha/process.hh"
+namespace AlphaISA {
/// A process with emulated Alpha Tru64 syscalls.
-class AlphaTru64Process : public LiveProcess
+class AlphaTru64Process : public AlphaLiveProcess
{
public:
/// Constructor.
AlphaTru64Process(const std::string &name,
ObjectFile *objFile,
+ System *system,
int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp);
@@ -54,5 +56,6 @@ class AlphaTru64Process : public LiveProcess
virtual SyscallDesc* getDesc(int callnum);
};
+} // namespace AlphaISA
#endif // __ALPHA_TRU64_PROCESS_HH__
diff --git a/arch/alpha/types.hh b/arch/alpha/types.hh
new file mode 100644
index 000000000..d4cb482d8
--- /dev/null
+++ b/arch/alpha/types.hh
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ */
+
+#ifndef __ARCH_ALPHA_TYPES_HH__
+#define __ARCH_ALPHA_TYPES_HH__
+
+#include "sim/host.hh"
+
+namespace AlphaISA
+{
+
+ typedef uint32_t MachInst;
+ typedef uint64_t ExtMachInst;
+ typedef uint8_t RegIndex;
+
+ typedef uint64_t IntReg;
+
+ // floating point register file entry type
+ typedef double FloatReg;
+ typedef uint64_t FloatRegBits;
+
+ // control register file contents
+ typedef uint64_t MiscReg;
+
+ typedef union {
+ IntReg intreg;
+ FloatReg fpreg;
+ MiscReg ctrlreg;
+ } AnyReg;
+
+ enum annotes {
+ ANNOTE_NONE = 0,
+ // An impossible number for instruction annotations
+ ITOUCH_ANNOTE = 0xffffffff,
+ };
+
+} // namespace AlphaISA
+
+#endif
diff --git a/arch/alpha/utility.hh b/arch/alpha/utility.hh
new file mode 100644
index 000000000..6cc916307
--- /dev/null
+++ b/arch/alpha/utility.hh
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ */
+
+#ifndef __ARCH_ALPHA_UTILITY_HH__
+#define __ARCH_ALPHA_UTILITY_HH__
+
+#include "config/full_system.hh"
+#include "arch/alpha/types.hh"
+#include "arch/alpha/constants.hh"
+#include "arch/alpha/regfile.hh"
+#include "base/misc.hh"
+
+namespace AlphaISA
+{
+
+ static inline ExtMachInst
+ makeExtMI(MachInst inst, const uint64_t &pc) {
+#if FULL_SYSTEM
+ ExtMachInst ext_inst = inst;
+ if (pc && 0x1)
+ return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
+ else
+ return ext_inst;
+#else
+ return ExtMachInst(inst);
+#endif
+ }
+
+ inline bool isCallerSaveIntegerRegister(unsigned int reg) {
+ panic("register classification not implemented");
+ return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
+ }
+
+ inline bool isCalleeSaveIntegerRegister(unsigned int reg) {
+ panic("register classification not implemented");
+ return (reg >= 9 && reg <= 15);
+ }
+
+ inline bool isCallerSaveFloatRegister(unsigned int reg) {
+ panic("register classification not implemented");
+ return false;
+ }
+
+ inline bool isCalleeSaveFloatRegister(unsigned int reg) {
+ panic("register classification not implemented");
+ return false;
+ }
+
+ inline Addr alignAddress(const Addr &addr,
+ unsigned int nbytes) {
+ return (addr & ~(nbytes - 1));
+ }
+
+ // Instruction address compression hooks
+ inline Addr realPCToFetchPC(const Addr &addr) {
+ return addr;
+ }
+
+ inline Addr fetchPCToRealPC(const Addr &addr) {
+ return addr;
+ }
+
+ // the size of "fetched" instructions (not necessarily the size
+ // of real instructions for PISA)
+ inline size_t fetchInstSize() {
+ return sizeof(MachInst);
+ }
+
+ inline MachInst makeRegisterCopy(int dest, int src) {
+ panic("makeRegisterCopy not implemented");
+ return 0;
+ }
+
+ // Machine operations
+
+ void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
+ int regnum);
+
+ void restoreMachineReg(RegFile &regs, const AnyReg &reg,
+ int regnum);
+
+ /**
+ * Function to insure ISA semantics about 0 registers.
+ * @param xc The execution context.
+ */
+ template <class XC>
+ void zeroRegisters(XC *xc);
+
+#if FULL_SYSTEM
+ // Alpha IPR register accessors
+ inline bool PcPAL(Addr addr) { return addr & 0x1; }
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Translation stuff
+ //
+
+ inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
+
+ // User Virtual
+ inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
+
+ // Kernel Direct Mapped
+ inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; }
+ inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; }
+
+ // Kernel Virtual
+ inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; }
+
+ inline Addr
+ TruncPage(Addr addr)
+ { return addr & ~(PageBytes - 1); }
+
+ inline Addr
+ RoundPage(Addr addr)
+ { return (addr + PageBytes - 1) & ~(PageBytes - 1); }
+
+ void initCPU(ExecContext *xc, int cpuId);
+ void initIPRs(ExecContext *xc, int cpuId);
+
+ /**
+ * Function to check for and process any interrupts.
+ * @param xc The execution context.
+ */
+ template <class XC>
+ void processInterrupts(XC *xc);
+#endif
+
+} // namespace AlphaISA
+
+#endif
diff --git a/arch/isa_parser.py b/arch/isa_parser.py
index 570110d84..3f836ed7e 100755
--- a/arch/isa_parser.py
+++ b/arch/isa_parser.py
@@ -1217,16 +1217,23 @@ class FloatRegOperand(Operand):
def makeRead(self):
bit_select = 0
+ width = 0;
if (self.ctype == 'float'):
- func = 'readFloatRegSingle'
+ func = 'readFloatReg'
+ width = 32;
elif (self.ctype == 'double'):
- func = 'readFloatRegDouble'
+ func = 'readFloatReg'
+ width = 64;
else:
- func = 'readFloatRegInt'
+ func = 'readFloatRegBits'
if (self.size != self.dflt_size):
bit_select = 1
- base = 'xc->%s(this, %d)' % \
- (func, self.src_reg_idx)
+ if width:
+ base = 'xc->%s(this, %d, %d)' % \
+ (func, self.src_reg_idx, width)
+ else:
+ base = 'xc->%s(this, %d)' % \
+ (func, self.src_reg_idx)
if bit_select:
return '%s = bits(%s, %d, 0);\n' % \
(self.base_name, base, self.size-1)
@@ -1236,21 +1243,28 @@ class FloatRegOperand(Operand):
def makeWrite(self):
final_val = self.base_name
final_ctype = self.ctype
+ widthSpecifier = ''
+ width = 0
if (self.ctype == 'float'):
- func = 'setFloatRegSingle'
+ width = 32
+ func = 'setFloatReg'
elif (self.ctype == 'double'):
- func = 'setFloatRegDouble'
+ width = 64
+ func = 'setFloatReg'
else:
- func = 'setFloatRegInt'
+ func = 'setFloatRegBits'
final_ctype = 'uint%d_t' % self.dflt_size
if (self.size != self.dflt_size and self.is_signed):
final_val = 'sext<%d>(%s)' % (self.size, self.base_name)
+ if width:
+ widthSpecifier = ', %d' % width
wb = '''
{
%s final_val = %s;
- xc->%s(this, %d, final_val);\n
+ xc->%s(this, %d, final_val%s);\n
if (traceData) { traceData->setData(final_val); }
- }''' % (final_ctype, final_val, func, self.dest_reg_idx)
+ }''' % (final_ctype, final_val, func, self.dest_reg_idx,
+ widthSpecifier)
return wb
class ControlRegOperand(Operand):
diff --git a/arch/isa_specific.hh b/arch/isa_specific.hh
index 44f8e9d64..91c9ffb68 100644
--- a/arch/isa_specific.hh
+++ b/arch/isa_specific.hh
@@ -45,7 +45,7 @@
//would treat them as 0 in comparisons.
#define ALPHA_ISA 21064
#define SPARC_ISA 42
-#define MIPS_ISA 1337
+#define MIPS_ISA 34000
//These tell the preprocessor where to find the files of a particular
//ISA, and set the "TheISA" macro for use elsewhere.
diff --git a/arch/mips/SConscript b/arch/mips/SConscript
index b8efa7ef9..73d588f84 100644
--- a/arch/mips/SConscript
+++ b/arch/mips/SConscript
@@ -57,9 +57,8 @@ full_system_sources = Split('''
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
- common_syscall_emul.cc
linux_process.cc
- tru64_process.cc
+ process.cc
''')
# Set up complete list of sources based on configuration.
diff --git a/arch/mips/faults.cc b/arch/mips/faults.cc
index 142dfe0a4..1b31dfa69 100644
--- a/arch/mips/faults.cc
+++ b/arch/mips/faults.cc
@@ -27,54 +27,105 @@
*/
#include "arch/mips/faults.hh"
+#include "cpu/exec_context.hh"
+#include "cpu/base.hh"
+#include "base/trace.hh"
+
+namespace MipsISA
+{
+
+FaultName MachineCheckFault::_name = "Machine Check";
+FaultVect MachineCheckFault::_vect = 0x0401;
+FaultStat MachineCheckFault::_count;
+
+FaultName AlignmentFault::_name = "Alignment";
+FaultVect AlignmentFault::_vect = 0x0301;
+FaultStat AlignmentFault::_count;
+
+FaultName ResetFault::_name = "reset";
+FaultVect ResetFault::_vect = 0x0001;
+FaultStat ResetFault::_count;
+
+FaultName ArithmeticFault::_name = "arith";
+FaultVect ArithmeticFault::_vect = 0x0501;
+FaultStat ArithmeticFault::_count;
+
+FaultName InterruptFault::_name = "interrupt";
+FaultVect InterruptFault::_vect = 0x0101;
+FaultStat InterruptFault::_count;
+
+FaultName NDtbMissFault::_name = "dtb_miss_single";
+FaultVect NDtbMissFault::_vect = 0x0201;
+FaultStat NDtbMissFault::_count;
+
+FaultName PDtbMissFault::_name = "dtb_miss_double";
+FaultVect PDtbMissFault::_vect = 0x0281;
+FaultStat PDtbMissFault::_count;
+
+FaultName DtbPageFault::_name = "dfault";
+FaultVect DtbPageFault::_vect = 0x0381;
+FaultStat DtbPageFault::_count;
+
+FaultName DtbAcvFault::_name = "dfault";
+FaultVect DtbAcvFault::_vect = 0x0381;
+FaultStat DtbAcvFault::_count;
+
+FaultName ItbMissFault::_name = "itbmiss";
+FaultVect ItbMissFault::_vect = 0x0181;
+FaultStat ItbMissFault::_count;
+
+FaultName ItbPageFault::_name = "itbmiss";
+FaultVect ItbPageFault::_vect = 0x0181;
+FaultStat ItbPageFault::_count;
+
+FaultName ItbAcvFault::_name = "iaccvio";
+FaultVect ItbAcvFault::_vect = 0x0081;
+FaultStat ItbAcvFault::_count;
+
+FaultName UnimplementedOpcodeFault::_name = "opdec";
+FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
+FaultStat UnimplementedOpcodeFault::_count;
+
+FaultName FloatEnableFault::_name = "fen";
+FaultVect FloatEnableFault::_vect = 0x0581;
+FaultStat FloatEnableFault::_count;
+
+FaultName PalFault::_name = "pal";
+FaultVect PalFault::_vect = 0x2001;
+FaultStat PalFault::_count;
+
+FaultName IntegerOverflowFault::_name = "intover";
+FaultVect IntegerOverflowFault::_vect = 0x0501;
+FaultStat IntegerOverflowFault::_count;
+
+#if FULL_SYSTEM
+
+void MipsFault::invoke(ExecContext * xc)
+{
+ FaultBase::invoke(xc);
+ countStat()++;
+
+ // exception restart address
+ if (setRestartAddress() || !xc->inPalMode())
+ xc->setMiscReg(MipsISA::IPR_EXC_ADDR, xc->readPC());
+
+ if (skipFaultingInstruction()) {
+ // traps... skip faulting instruction.
+ xc->setMiscReg(MipsISA::IPR_EXC_ADDR,
+ xc->readMiscReg(MipsISA::IPR_EXC_ADDR) + 4);
+ }
+
+ xc->setPC(xc->readMiscReg(MipsISA::IPR_PAL_BASE) + vect());
+ xc->setNextPC(xc->readPC() + sizeof(MachInst));
+}
+
+void ArithmeticFault::invoke(ExecContext * xc)
+{
+ FaultBase::invoke(xc);
+ panic("Arithmetic traps are unimplemented!");
+}
+
+#endif
+
+} // namespace MipsISA
-ResetFaultType * const ResetFault =
- new ResetFaultType("reset", 1, 0x0001);
-ArithmeticFaultType * const ArithmeticFault =
- new ArithmeticFaultType("arith", 3, 0x0501);
-InterruptFaultType * const InterruptFault =
- new InterruptFaultType("interrupt", 4, 0x0101);
-NDtbMissFaultType * const NDtbMissFault =
- new NDtbMissFaultType("dtb_miss_single", 5, 0x0201);
-PDtbMissFaultType * const PDtbMissFault =
- new PDtbMissFaultType("dtb_miss_double", 6, 0x0281);
-DtbPageFaultType * const DtbPageFault =
- new DtbPageFaultType("dfault", 8, 0x0381);
-DtbAcvFaultType * const DtbAcvFault =
- new DtbAcvFaultType("dfault", 9, 0x0381);
-ItbMissFaultType * const ItbMissFault =
- new ItbMissFaultType("itbmiss", 10, 0x0181);
-ItbPageFaultType * const ItbPageFault =
- new ItbPageFaultType("itbmiss", 11, 0x0181);
-ItbAcvFaultType * const ItbAcvFault =
- new ItbAcvFaultType("iaccvio", 12, 0x0081);
-UnimplementedOpcodeFaultType * const UnimplementedOpcodeFault =
- new UnimplementedOpcodeFaultType("opdec", 13, 0x0481);
-FloatEnableFaultType * const FloatEnableFault =
- new FloatEnableFaultType("fen", 14, 0x0581);
-PalFaultType * const PalFault =
- new PalFaultType("pal", 15, 0x2001);
-IntegerOverflowFaultType * const IntegerOverflowFault =
- new IntegerOverflowFaultType("intover", 16, 0x0501);
-
-Fault ** ListOfFaults[] = {
- (Fault **)&NoFault,
- (Fault **)&ResetFault,
- (Fault **)&MachineCheckFault,
- (Fault **)&ArithmeticFault,
- (Fault **)&InterruptFault,
- (Fault **)&NDtbMissFault,
- (Fault **)&PDtbMissFault,
- (Fault **)&AlignmentFault,
- (Fault **)&DtbPageFault,
- (Fault **)&DtbAcvFault,
- (Fault **)&ItbMissFault,
- (Fault **)&ItbPageFault,
- (Fault **)&ItbAcvFault,
- (Fault **)&UnimplementedOpcodeFault,
- (Fault **)&FloatEnableFault,
- (Fault **)&PalFault,
- (Fault **)&IntegerOverflowFault,
- };
-
-int NumFaults = sizeof(ListOfFaults) / sizeof(Fault **);
diff --git a/arch/mips/faults.hh b/arch/mips/faults.hh
index c1cb956b0..0bdabe29e 100644
--- a/arch/mips/faults.hh
+++ b/arch/mips/faults.hh
@@ -30,131 +30,240 @@
#define __MIPS_FAULTS_HH__
#include "sim/faults.hh"
-#include "arch/isa_traits.hh" //For the Addr type
+
+// The design of the "name" and "vect" functions is in sim/faults.hh
+
+namespace MipsISA
+{
+
+typedef const Addr FaultVect;
class MipsFault : public FaultBase
{
+ protected:
+ virtual bool skipFaultingInstruction() {return false;}
+ virtual bool setRestartAddress() {return true;}
public:
- MipsFault(char * newName, int newId, Addr newVect)
- : FaultBase(newName, newId), vect(newVect)
- {;}
+#if FULL_SYSTEM
+ void invoke(ExecContext * xc);
+#endif
+ virtual FaultVect vect() = 0;
+ virtual FaultStat & countStat() = 0;
+};
- Addr vect;
+class MachineCheckFault : public MipsFault
+{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
+ public:
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+ bool isMachineCheckFault() {return true;}
};
-extern class ResetFaultType : public MipsFault
+class AlignmentFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- ResetFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const ResetFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+ bool isAlignmentFault() {return true;}
+};
-extern class ArithmeticFaultType : public MipsFault
+static inline Fault genMachineCheckFault()
{
+ return new MachineCheckFault;
+}
+
+static inline Fault genAlignmentFault()
+{
+ return new AlignmentFault;
+}
+
+class ResetFault : public MipsFault
+{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- ArithmeticFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const ArithmeticFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class InterruptFaultType : public MipsFault
+class ArithmeticFault : public MipsFault
{
+ protected:
+ bool skipFaultingInstruction() {return true;}
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- InterruptFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const InterruptFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+#if FULL_SYSTEM
+ void invoke(ExecContext * xc);
+#endif
+};
-extern class NDtbMissFaultType : public MipsFault
+class InterruptFault : public MipsFault
{
+ protected:
+ bool setRestartAddress() {return false;}
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- NDtbMissFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const NDtbMissFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class PDtbMissFaultType : public MipsFault
+class NDtbMissFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- PDtbMissFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const PDtbMissFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class DtbPageFaultType : public MipsFault
+class PDtbMissFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- DtbPageFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const DtbPageFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class DtbAcvFaultType : public MipsFault
+class DtbPageFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- DtbAcvFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const DtbAcvFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
+
+class DtbAcvFault : public MipsFault
+{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
+ public:
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class ItbMissFaultType : public MipsFault
+class ItbMissFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- ItbMissFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const ItbMissFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class ItbPageFaultType : public MipsFault
+class ItbPageFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- ItbPageFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const ItbPageFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class ItbAcvFaultType : public MipsFault
+class ItbAcvFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- ItbAcvFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const ItbAcvFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class UnimplementedOpcodeFaultType : public MipsFault
+class UnimplementedOpcodeFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const UnimplementedOpcodeFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class FloatEnableFaultType : public MipsFault
+class FloatEnableFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- FloatEnableFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const FloatEnableFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class PalFaultType : public MipsFault
+class PalFault : public MipsFault
{
+ protected:
+ bool skipFaultingInstruction() {return true;}
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- PalFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const PalFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern class IntegerOverflowFaultType : public MipsFault
+class IntegerOverflowFault : public MipsFault
{
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
public:
- IntegerOverflowFaultType(char * newName, int newId, Addr newVect)
- : MipsFault(newName, newId, newVect)
- {;}
-} * const IntegerOverflowFault;
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
-extern Fault ** ListOfFaults[];
-extern int NumFaults;
+} // MipsISA namespace
#endif // __FAULTS_HH__
diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa
index 4125b5101..89837c136 100644
--- a/arch/mips/isa/base.isa
+++ b/arch/mips/isa/base.isa
@@ -66,27 +66,24 @@ output decoder {{
ccprintf(ss, "%-10s ", mnemonic);
- // just print the first two source regs... if there's
- // a third one, it's a read-modify-write dest (Rc),
- // e.g. for CMOVxx
- if(_numSrcRegs > 0)
- {
+ if(_numDestRegs > 0){
+ if(_numSrcRegs > 0)
+ ss << ",";
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
}
- if(_numSrcRegs > 1)
- {
+ if(_numSrcRegs > 1) {
ss << ",";
printReg(ss, _srcRegIdx[1]);
}
- // just print the first dest... if there's a second one,
- // it's generally implicit
- if(_numDestRegs > 0)
- {
- if(_numSrcRegs > 0)
- ss << ",";
- printReg(ss, _destRegIdx[0]);
+
+ if(mnemonic == "sll"){
+ ccprintf(ss," %d",SA);
}
return ss.str();
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa
index 3f054f6a5..3a8a4dfd8 100644
--- a/arch/mips/isa/decoder.isa
+++ b/arch/mips/isa/decoder.isa
@@ -20,26 +20,27 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode FUNCTION_LO {
0x1: decode MOVCI {
format BasicOp {
- 0: movf({{ if (xc->readMiscReg(FPCR,0) != CC) Rd = Rs}});
- 1: movt({{ if (xc->readMiscReg(FPCR,0) == CC) Rd = Rs}});
+ 0: movf({{ if (xc->readMiscReg(FPCR) != CC) Rd = Rs}});
+ 1: movt({{ if (xc->readMiscReg(FPCR) == CC) Rd = Rs}});
}
}
format BasicOp {
//Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
- //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
-
- 0x0: decode RS {
- 0x0: decode RT default BasicOp::sll({{ Rd = Rt.uw << SA; }}) {
- 0x0: decode RD{
- 0x0: decode HINT {
- 0x0:nop({{}}); //really sll r0,r0,0
- 0x1:ssnop({{}});//really sll r0,r0,1
- 0x3:ehb({{}}); //really sll r0,r0,3
- }
- }
+ //are used to distinguish among the SLL, NOP, SSNOP and EHB functions.
+ 0x0: decode RS {
+ 0x0: decode RT { //fix Nop traditional vs. Nop converted disassembly later
+ 0x0: decode RD default Nop::nop(){
+ 0x0: decode SA {
+ 0x1: ssnop({{ ; }}); //really sll r0,r0,1
+ 0x3: ehb({{ ; }}); //really sll r0,r0,3
+ }
+ }
+
+ default: sll({{ Rd = Rt.uw << SA; }});
}
+
}
0x2: decode SRL {
@@ -76,9 +77,9 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x1: decode HINT {
- 0: jalr({{ NNPC = Rs; }},IsCall,IsReturn);
+ 0: jalr({{ Rd = NNPC; NNPC = Rs; }},IsCall,IsReturn);
- 1: jalr_hb({{ NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
+ 1: jalr_hb({{ Rd = NNPC; NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
}
}
@@ -87,10 +88,10 @@ decode OPCODE_HI default Unknown::unknown() {
0x3: movn({{ if (Rt != 0) Rd = Rs; }});
}
- format WarnUnimpl {
- 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative
- 0x5: break();
- 0x7: sync();
+ format BasicOp {
+ 0x4: syscall({{ xc->syscall(); }},IsNonSpeculative);
+ 0x5: break({{ panic("Not implemented break yet"); }},IsNonSpeculative);
+ 0x7: sync({{ panic("Not implemented sync yet"); }},IsNonSpeculative);
}
}
@@ -283,55 +284,37 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode SC {
0x0: dvpe({{
- int idx;
- int sel;
- getMiscRegIdx(MVPControl,idx,sel);
- Rt.sw = xc->readMiscReg(idx,sel);
- xc->setMiscReg(idx,sel);
+ Rt.sw = xc->readMiscReg(MVPControl);
+ xc->setMiscReg(MVPControl,0);
}});
0x1: evpe({{
- int idx;
- int sel;
- getMiscRegIdx(MVPControl,idx,sel);
- Rt.sw = xc->readMiscReg(idx,sel);
- xc->setMiscReg(idx,sel,1);
+ Rt.sw = xc->readMiscReg(MVPControl);
+ xc->setMiscReg(MVPControl,1);
}});
}
0x1: decode SC {
0x0: dmt({{
- int idx;
- int sel;
- getMiscRegIdx(VPEControl,idx,sel);
- Rt.sw = xc->readMiscReg(idx,sel);
- xc->setMiscReg(idx,sel);
+ Rt.sw = xc->readMiscReg(VPEControl);
+ xc->setMiscReg(VPEControl,0);
}});
0x1: emt({{
- int idx;
- int sel;
- getMiscRegIdx(VPEControl,idx,sel);
- Rt.sw = xc->readMiscReg(idx,sel);
- xc->setMiscReg(idx,sel,1);
+ Rt.sw = xc->readMiscReg(VPEControl);
+ xc->setMiscReg(VPEControl,1);
}});
}
0xC: decode SC {
0x0: di({{
- int idx;
- int sel;
- getMiscRegIdx(Status,idx,sel);
- Rt.sw = xc->readMiscReg(idx,sel);
- xc->setMiscReg(idx,sel);
+ Rt.sw = xc->readMiscReg(Status);
+ xc->setMiscReg(Status,0);
}});
0x1: ei({{
- int idx;
- int sel;
- getMiscRegIdx(Status,idx,sel);
- Rt.sw = xc->readMiscReg(idx,sel);
- xc->setMiscReg(idx,sel,1);
+ Rt.sw = xc->readMiscReg(Status);
+ xc->setMiscReg(Status,1);
}});
}
}
@@ -883,7 +866,7 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: lb({{ Rt.sw = Mem.sb; }});
0x1: lh({{ Rt.sw = Mem.sh; }});
0x2: lwl({{ Rt.sw = Mem.sw; }});//, WordAlign);
- 0x3: lw({{ Rt.sw = Mem.sb; }});
+ 0x3: lw({{ Rt.sw = Mem.sw; }});
0x4: lbu({{ Rt.uw = Mem.ub; }});
0x5: lhu({{ Rt.uw = Mem.uh; }});
0x6: lwr({{ Rt.uw = Mem.uw; }});//, WordAlign);
@@ -896,9 +879,9 @@ decode OPCODE_HI default Unknown::unknown() {
format StoreMemory {
0x0: sb({{ Mem.ub = Rt<7:0>; }});
0x1: sh({{ Mem.uh = Rt<15:0>; }});
- 0x2: swl({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
- 0x3: sw({{ Mem.ub = Rt<31:0>; }});
- 0x6: swr({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
+ 0x2: swl({{ Mem.uw = Rt<31:0>; }});//,WordAlign);
+ 0x3: sw({{ Mem.uw = Rt<31:0>; }});
+ 0x6: swr({{ Mem.uw = Rt<31:0>; }});//,WordAlign);
}
format WarnUnimpl {
diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa
index 0d2ad7855..cb0f4ac9c 100644
--- a/arch/mips/isa/formats/branch.isa
+++ b/arch/mips/isa/formats/branch.isa
@@ -187,6 +187,12 @@ output decoder {{
else
ccprintf(ss, "0x%x", target);
+ string inst_name = mnemonic;
+
+ if (inst_name.substr(inst_name.length()-2,inst_name.length()) == "al"){
+ ccprintf(ss, " (r31=0x%x)",pc+8);
+ }
+
return ss.str();
}
@@ -265,8 +271,6 @@ def format Branch(code,*flags) {{
code += ' NNPC = NNPC;\n'
code += '} \n'
- code += 'cout << hex << "NPC: " << NPC << " + " << disp << " = " << NNPC << endl;'
-
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
('IsDirectControl', 'IsCondControl'))
@@ -305,8 +309,6 @@ def format Jump(code,*flags) {{
if strlen > 1 and name[1:] == 'al':
code = 'r31 = NNPC;\n' + code
- #code += 'if(NNPC == 0x80000638) { NNPC = r31; cout << "SKIPPING JUMP TO SIM_GET_MEM_CONF" << endl;}'
- #code += 'target = NNPC;'
iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\
('IsIndirectControl', 'IsUncondControl'))
diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa
index d35179005..2aa4816e3 100644
--- a/arch/mips/isa/formats/noop.isa
+++ b/arch/mips/isa/formats/noop.isa
@@ -88,3 +88,7 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{
exec_output = BasicExecute.subst(iop)
}};
+def format Nop() {{
+ decode_block = 'return new Nop(\"sll r0,r0,0\",machInst);\n'
+}};
+
diff --git a/arch/mips/isa/formats/unimp.isa b/arch/mips/isa/formats/unimp.isa
index adbd5b5b1..890cf8d1a 100644
--- a/arch/mips/isa/formats/unimp.isa
+++ b/arch/mips/isa/formats/unimp.isa
@@ -111,7 +111,7 @@ output exec {{
{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE);
- return UnimplementedOpcodeFault;
+ return new UnimplementedOpcodeFault;
}
Fault
diff --git a/arch/mips/isa/formats/unknown.isa b/arch/mips/isa/formats/unknown.isa
index 4601b3684..47d166255 100644
--- a/arch/mips/isa/formats/unknown.isa
+++ b/arch/mips/isa/formats/unknown.isa
@@ -42,7 +42,7 @@ output exec {{
{
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x)", machInst, OPCODE);
- return UnimplementedOpcodeFault;
+ return new UnimplementedOpcodeFault;
}
}};
diff --git a/arch/mips/isa/includes.isa b/arch/mips/isa/includes.isa
index da919be00..b81c4eda2 100644
--- a/arch/mips/isa/includes.isa
+++ b/arch/mips/isa/includes.isa
@@ -9,10 +9,11 @@ output header {{
#include <iomanip>
#include "cpu/static_inst.hh"
-#include "mem/mem_req.hh" // some constructors use MemReq flags
+#include "arch/mips/isa_traits.hh"
}};
output decoder {{
+#include "arch/mips/isa_traits.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/exec_context.hh" // for Jump::branchTarget()
@@ -21,9 +22,12 @@ output decoder {{
#if defined(linux)
#include <fenv.h>
#endif
+
+using namespace MipsISA;
}};
output exec {{
+#include "arch/mips/isa_traits.hh"
#include <math.h>
#if defined(linux)
#include <fenv.h>
@@ -35,5 +39,7 @@ output exec {{
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
+
+using namespace MipsISA;
}};
diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc
index d01fa6bd4..849d3311d 100644
--- a/arch/mips/isa_traits.cc
+++ b/arch/mips/isa_traits.cc
@@ -34,97 +34,39 @@
using namespace MipsISA;
-//Function now Obsolete in current state.
-//If anyting this should return the correct miscreg index
-//but that is handled implicitly with enums anyway
+
+void
+MipsISA::copyRegs(ExecContext *src, ExecContext *dest)
+{
+ /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
+ uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
+ lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
+ lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag);
+
+#if FULL_SYSTEM
+ copyIprs(xc);
+ #endif*/
+}
+
void
-MipsISA::getMiscRegIdx(int reg_name,int &idx, int &sel)
+MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc)
{
- switch(reg_name)
- {
- case Index: idx = 0; sel = 0; break; //0-0 Index into the TLB array
- case MVPControl: idx = 0; sel = 1; break; //0-1 Per-processor register containing global
- case MVPConf0: idx = 0; sel = 2; break; //0-2 Per-processor register containing global
- case MVPConf1: idx = 0; sel = 3; break; //0-3 Per-processor register containing global
- case Random: idx = 1; sel = 3; break; //1-0 Randomly generated index into the TLB array
- case VPEControl: idx = 1; sel = 1; break; //1-1 Per-VPE register containing relatively volatile
- //thread configuration data
- case VPEConf0: idx = 1; sel = 2; break; //1-2 Per-VPE multi-thread configuration
- //information
- case VPEConf1: idx = 1; sel = 3; break; //1-3 Per-VPE multi-thread configuration
- //information
- case YQMask: idx = 1; sel = 4; break; //Per-VPE register defining which YIELD
- //qualifier bits may be used without generating
- //an exception
- case VPESchedule: idx = 1; sel = 5; break;
- case VPEScheFBack: idx = 1; sel = 6; break;
- case VPEOpt: idx = 1; sel = 7; break;
- case EntryLo0: idx = 1; sel = 5; break;
- case TCStatus: idx = 1; sel = 5; break;
- case TCBind: idx = 1; sel = 5; break;
- case TCRestart: idx = 1; sel = 5; break;
- case TCHalt: idx = 1; sel = 5; break;
- case TCContext: idx = 1; sel = 5; break;
- case TCSchedule: idx = 1; sel = 5; break;
- case TCScheFBack: panic("Accessing Unimplemented CP0 Register"); break;
- case EntryLo1: panic("Accessing Unimplemented CP0 Register"); break;
- case Context: panic("Accessing Unimplemented CP0 Register"); break;
- case ContextConfig: panic("Accessing Unimplemented CP0 Register"); break;
- //case PageMask: panic("Accessing Unimplemented CP0 Register"); break;
- case PageGrain: panic("Accessing Unimplemented CP0 Register"); break;
- case Wired: panic("Accessing Unimplemented CP0 Register"); break;
- case SRSConf0: panic("Accessing Unimplemented CP0 Register"); break;
- case SRSConf1: panic("Accessing Unimplemented CP0 Register"); break;
- case SRSConf2: panic("Accessing Unimplemented CP0 Register"); break;
- case SRSConf3: panic("Accessing Unimplemented CP0 Register"); break;
- case SRSConf4: panic("Accessing Unimplemented CP0 Register"); break;
- case BadVAddr: panic("Accessing Unimplemented CP0 Register"); break;
- case Count: panic("Accessing Unimplemented CP0 Register"); break;
- case EntryHi: panic("Accessing Unimplemented CP0 Register"); break;
- case Compare: panic("Accessing Unimplemented CP0 Register"); break;
- case Status: idx = 12; sel = 0; break; //12-0 Processor status and control
- case IntCtl: idx = 12; sel = 1; break; //12-1 Interrupt system status and control
- case SRSCtl: idx = 12; sel = 2; break; //12-2 Shadow register set status and control
- case SRSMap: idx = 12; sel = 3; break; //12-3 Shadow set IPL mapping
- case Cause: idx = 13; sel = 0; break; //13-0 Cause of last general exception
- case EPC: idx = 14; sel = 0; break; //14-0 Program counter at last exception
- case PrId: idx = 15; sel = 0; break; //15-0 Processor identification and revision
- case EBase: idx = 15; sel = 1; break; //15-1 Exception vector base register
- case Config: panic("Accessing Unimplemented CP0 Register"); break;
- case Config1: panic("Accessing Unimplemented CP0 Register"); break;
- case Config2: panic("Accessing Unimplemented CP0 Register"); break;
- case Config3: panic("Accessing Unimplemented CP0 Register"); break;
- case LLAddr: panic("Accessing Unimplemented CP0 Register"); break;
- case WatchLo: panic("Accessing Unimplemented CP0 Register"); break;
- case WatchHi: panic("Accessing Unimplemented CP0 Register"); break;
- case Debug: panic("Accessing Unimplemented CP0 Register"); break;
- case TraceControl1: panic("Accessing Unimplemented CP0 Register"); break;
- case TraceControl2: panic("Accessing Unimplemented CP0 Register"); break;
- case UserTraceData: panic("Accessing Unimplemented CP0 Register"); break;
- case TraceBPC: panic("Accessing Unimplemented CP0 Register"); break;
- case DEPC: panic("Accessing Unimplemented CP0 Register"); break;
- case PerfCnt: panic("Accessing Unimplemented CP0 Register"); break;
- case ErrCtl: panic("Accessing Unimplemented CP0 Register"); break;
- case CacheErr0: panic("Accessing Unimplemented CP0 Register"); break;
- case CacheErr1: panic("Accessing Unimplemented CP0 Register"); break;
- case CacheErr2: panic("Accessing Unimplemented CP0 Register"); break;
- case CacheErr3: panic("Accessing Unimplemented CP0 Register"); break;
- case TagLo: panic("Accessing Unimplemented CP0 Register"); break;
- case DataLo: panic("Accessing Unimplemented CP0 Register"); break;
- case TagHi: panic("Accessing Unimplemented CP0 Register"); break;
- case DataHi: panic("Accessing Unimplemented CP0 Register"); break;
- case ErrorEPC: panic("Accessing Unimplemented CP0 Register"); break;
-
- default:
- panic("Accessing Unimplemented Misc. Register");
- }
+ /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
+ uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
+ lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
+ lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag);
+
+#if FULL_SYSTEM
+ copyIprs(xc);
+ #endif*/
}
-void RegFile::coldReset()
+
+void MipsISA::RegFile::coldReset()
{
//CP0 Random Reg:
//Randomly generated index into the TLB array
- miscRegs[Random] = 0x0000003f;
+ /*miscRegs[Random] = 0x0000003f;
//CP0 Wired Reg.
miscRegs[Wired] = 0x0000000;
@@ -175,7 +117,7 @@ void RegFile::coldReset()
miscRegs[PerfCnt0] = 0x0000000;
//CP0 PERFCNTL2
- miscRegs[PerfCnt1] = 0x0000000;
+ miscRegs[PerfCnt1] = 0x0000000;*/
}
@@ -247,6 +189,10 @@ void RegFile::createCP0Regs()
//Cop-0 Regs. Bank 20:
miscRegs[20].resize(1);
+ case PerfCnt0: panic("Accessing Unimplemented CP0 Register"); break;
+ case PerfCnt1: panic("Accessing Unimplemented CP0 Register"); break;
+ case PerfCnt2: panic("Accessing Unimplemented CP0 Register"); break;
+ case PerfCnt3: panic("Accessing Unimplemented CP0 Register"); break;
//Cop-0 Regs. Bank 21:
//miscRegs[21].resize(1);
@@ -332,7 +278,7 @@ void
RegFile::serialize(std::ostream &os)
{
SERIALIZE_ARRAY(intRegFile, NumIntRegs);
- SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
+ //SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
//SERIALIZE_SCALAR(miscRegs.fpcr);
//SERIALIZE_SCALAR(miscRegs.uniq);
//SERIALIZE_SCALAR(miscRegs.lock_flag);
@@ -353,7 +299,7 @@ void
RegFile::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(intRegFile, NumIntRegs);
- UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
+ //UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
//UNSERIALIZE_SCALAR(miscRegs.fpcr);
//UNSERIALIZE_SCALAR(miscRegs.uniq);
//UNSERIALIZE_SCALAR(miscRegs.lock_flag);
diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh
index 1dfa0dc7a..8363f42f3 100644
--- a/arch/mips/isa_traits.hh
+++ b/arch/mips/isa_traits.hh
@@ -40,6 +40,7 @@
class FastCPU;
class FullCPU;
class Checkpoint;
+class ExecContext;
namespace LittleEndianGuest {};
using namespace LittleEndianGuest;
@@ -54,50 +55,100 @@ int DTB_ASN_ASN(uint64_t reg);
int ITB_ASN_ASN(uint64_t reg);
};
+#if !FULL_SYSTEM
+class SyscallReturn {
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint64_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint64_t)v;
+ }
+
+ ~SyscallReturn() {}
+
+ SyscallReturn& operator=(const SyscallReturn& s) {
+ retval = s.retval;
+ success = s.success;
+ return *this;
+ }
+
+ bool successful() { return success; }
+ uint64_t value() { return retval; }
+
+
+ private:
+ uint64_t retval;
+ bool success;
+};
+#endif
+
namespace MipsISA
{
typedef uint32_t MachInst;
-// typedef uint64_t Addr;
+ typedef uint32_t MachInst;
+ typedef uint64_t ExtMachInst;
typedef uint8_t RegIndex;
+// typedef uint64_t Addr;
+
+ // Constants Related to the number of registers
+
+ const int NumIntArchRegs = 32;
+ const int NumPALShadowRegs = 8;
+ const int NumFloatArchRegs = 32;
+ // @todo: Figure out what this number really should be.
+ const int NumMiscArchRegs = 32;
+
+ const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
+ const int NumFloatRegs = NumFloatArchRegs;
+ const int NumMiscRegs = NumMiscArchRegs;
+
+ const int TotalNumRegs = NumIntRegs + NumFloatRegs +
+ NumMiscRegs + 0/*NumInternalProcRegs*/;
+
+ const int TotalDataRegs = NumIntRegs + NumFloatRegs;
+
+ // Static instruction parameters
+ const int MaxInstSrcRegs = 3;
+ const int MaxInstDestRegs = 2;
+
+ // semantically meaningful register indices
+ const int ZeroReg = 0;
+ const int AssemblerReg = 1;
+ const int ReturnValueReg1 = 2;
+ const int ReturnValueReg2 = 3;
+ const int ArgumentReg0 = 4;
+ const int ArgumentReg1 = 5;
+ const int ArgumentReg2 = 6;
+ const int ArgumentReg3 = 7;
+ const int KernelReg0 = 26;
+ const int KernelReg1 = 27;
+ const int GlobalPointerReg = 28;
+ const int StackPointerReg = 29;
+ const int FramePointerReg = 30;
+ const int ReturnAddressReg = 31;
+
+ const int SyscallNumReg = ReturnValueReg1;
+ const int SyscallPseudoReturnReg = ArgumentReg3;
+ const int SyscallSuccessReg = 19;
+
+ const int LogVMPageSize = 13; // 8K bytes
+ const int VMPageSize = (1 << LogVMPageSize);
+
+ const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
+
+ const int MachineBytes = 4;
+ const int WordBytes = 4;
+ const int HalfwordBytes = 2;
+ const int ByteBytes = 1;
- enum {
- MemoryEnd = 0xffffffffffffffffULL,
-
- NumIntRegs = 32,
- NumFloatRegs = 32,
- NumMiscRegs = 258, //account for hi,lo regs
-
- MaxRegsOfAnyType = 32,
- // Static instruction parameters
- MaxInstSrcRegs = 3,
- MaxInstDestRegs = 2,
-
- // semantically meaningful register indices
- ZeroReg = 0, // architecturally meaningful
- // the rest of these depend on the ABI
- StackPointerReg = 30,
- GlobalPointerReg = 29,
- ProcedureValueReg = 27,
- ReturnAddressReg = 26,
- ReturnValueReg = 0,
- FramePointerReg = 15,
- ArgumentReg0 = 16,
- ArgumentReg1 = 17,
- ArgumentReg2 = 18,
- ArgumentReg3 = 19,
- ArgumentReg4 = 20,
- ArgumentReg5 = 21,
-
- LogVMPageSize = 13, // 8K bytes
- VMPageSize = (1 << LogVMPageSize),
-
- BranchPredAddrShiftAmt = 2, // instructions are 4-byte aligned
-
- WordBytes = 4,
- HalfwordBytes = 2,
- ByteBytes = 1,
- DepNA = 0,
- };
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
@@ -114,23 +165,84 @@ namespace MipsISA
typedef uint64_t IntReg;
typedef IntReg IntRegFile[NumIntRegs];
- // floating point register file entry type
+/* floating point register file entry type
typedef union {
uint64_t q;
double d;
- } FloatReg;
+ } FloatReg;*/
- typedef union {
+ typedef double FloatReg;
+ typedef uint64_t FloatRegBits;
+
+/*typedef union {
uint64_t q[NumFloatRegs]; // integer qword view
double d[NumFloatRegs]; // double-precision floating point view
- } FloatRegFile;
+ } FloatRegFile;*/
+
+ class FloatRegFile
+ {
+ protected:
+
+ FloatRegBits q[NumFloatRegs]; // integer qword view
+ double d[NumFloatRegs]; // double-precision floating point view
+
+ public:
+
+ FloatReg readReg(int floatReg)
+ {
+ return d[floatReg];
+ }
+
+ FloatReg readReg(int floatReg, int width)
+ {
+ return readReg(floatReg);
+ }
+
+ FloatRegBits readRegBits(int floatReg)
+ {
+ return q[floatReg];
+ }
+
+ FloatRegBits readRegBits(int floatReg, int width)
+ {
+ return readRegBits(floatReg);
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val)
+ {
+ d[floatReg] = val;
+ return NoFault;
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val, int width)
+ {
+ return setReg(floatReg, val);
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val)
+ {
+ q[floatReg] = val;
+ return NoFault;
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+ return setRegBits(floatReg, val);
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ };
+
+ void copyRegs(ExecContext *src, ExecContext *dest);
// cop-0/cop-1 system control register file
typedef uint64_t MiscReg;
//typedef MiscReg MiscRegFile[NumMiscRegs];
class MiscRegFile {
- public:
- MiscReg
+
protected:
uint64_t fpcr; // floating point condition codes
uint64_t uniq; // process-unique register
@@ -145,6 +257,8 @@ namespace MipsISA
int getInstAsid();
int getDataAsid();
+ void copyMiscRegs(ExecContext *xc);
+
MiscReg readReg(int misc_reg)
{ return miscRegFile[misc_reg]; }
@@ -159,7 +273,7 @@ namespace MipsISA
{ miscRegFile[misc_reg] = val; return NoFault; }
#if FULL_SYSTEM
- void clearIprs() { };
+ void clearIprs() { }
protected:
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
@@ -249,7 +363,7 @@ namespace MipsISA
EPC = 105,//105-112 //14-0 Program counter at last exception
- PRId = 113//113-120, //15-0 Processor identification and revision
+ PRId = 113,//113-120, //15-0 Processor identification and revision
EBase = 114, //15-1 Exception vector base register
Config = 121,//Bank 16: 121-128
@@ -363,15 +477,6 @@ extern const Addr PageOffset;
};
#endif
- enum {
- TotalNumRegs =
- NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs
- };
-
- enum {
- TotalDataRegs = NumIntRegs + NumFloatRegs
- };
-
typedef union {
IntReg intreg;
FloatReg fpreg;
@@ -411,7 +516,7 @@ extern const Addr PageOffset;
void coldReset();
};
- StaticInstPtr decodeInst(MachInst);
+ StaticInstPtr decodeInst(ExtMachInst);
// return a no-op instruction... used for instruction fetch faults
extern const MachInst NoopMachInst;
@@ -422,8 +527,20 @@ extern const Addr PageOffset;
ITOUCH_ANNOTE = 0xffffffff,
};
- void getMiscRegIdx(int reg_name,int &idx, int &sel);
+//void getMiscRegIdx(int reg_name,int &idx, int &sel);
+ static inline ExtMachInst
+ makeExtMI(MachInst inst, const uint64_t &pc) {
+#if FULL_SYSTEM
+ ExtMachInst ext_inst = inst;
+ if (pc && 0x1)
+ return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
+ else
+ return ext_inst;
+#else
+ return ExtMachInst(inst);
+#endif
+ }
static inline bool isCallerSaveIntegerRegister(unsigned int reg) {
panic("register classification not implemented");
@@ -470,6 +587,12 @@ extern const Addr PageOffset;
return 0;
}
+ static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+ {
+ regs->intRegFile[ReturnValueReg1] = 1;
+ //panic("Returning from syscall\n");
+ }
+
// Machine operations
void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
@@ -498,43 +621,6 @@ extern const Addr PageOffset;
const Addr MaxAddr = (Addr)-1;
};
-#if !FULL_SYSTEM
-class SyscallReturn {
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s) {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
-
- private:
- uint64_t retval;
- bool success;
-};
-
-#endif
-
-
#if FULL_SYSTEM
//typedef TheISA::InternalProcReg InternalProcReg;
//const int NumInternalProcRegs = TheISA::NumInternalProcRegs;
@@ -543,4 +629,6 @@ class SyscallReturn {
#include "arch/mips/mips34k.hh"
#endif
+using namespace MipsISA;
+
#endif // __ARCH_MIPS_ISA_TRAITS_HH__
diff --git a/arch/mips/linux_process.cc b/arch/mips/linux_process.cc
index 1d4f62350..91e9a56a1 100644
--- a/arch/mips/linux_process.cc
+++ b/arch/mips/linux_process.cc
@@ -33,7 +33,6 @@
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "kern/linux/linux.hh"
-#include "mem/functional/functional.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
@@ -54,15 +53,15 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "mips");
- name.copyOut(xc->mem);
+ name.copyOut(xc->getMemPort());
return 0;
}
-/// Target osf_getsysyinfo() handler. Even though this call is
+/// Target sys_getsysyinfo() handler. Even though this call is
/// borrowed from Tru64, the subcases that get used appear to be
/// different in practice from those used by Tru64 processes.
static SyscallReturn
-osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
+sys_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
unsigned op = xc->getSyscallArg(0);
@@ -74,12 +73,12 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
- fpcr.copyOut(xc->mem);
+ fpcr.copyOut(xc->getMemPort());
return 0;
}
default:
- cerr << "osf_getsysinfo: unknown op " << op << endl;
+ cerr << "sys_getsysinfo: unknown op " << op << endl;
abort();
break;
}
@@ -87,9 +86,9 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
return 1;
}
-/// Target osf_setsysinfo() handler.
+/// Target sys_setsysinfo() handler.
static SyscallReturn
-osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
+sys_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
unsigned op = xc->getSyscallArg(0);
@@ -100,14 +99,14 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
- fpcr.copyIn(xc->mem);
- DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
+ fpcr.copyIn(xc->getMemPort());
+ DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0;
}
default:
- cerr << "osf_setsysinfo: unknown op " << op << endl;
+ cerr << "sys_setsysinfo: unknown op " << op << endl;
abort();
break;
}
@@ -117,464 +116,304 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
SyscallDesc MipsLinuxProcess::syscallDescs[] = {
- /* 0 */ SyscallDesc("osf_syscall", unimplementedFunc),
+ /* 0 */ SyscallDesc("syscall", unimplementedFunc),
/* 1 */ SyscallDesc("exit", exitFunc),
/* 2 */ SyscallDesc("fork", unimplementedFunc),
/* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
- /* 5 */ SyscallDesc("osf_old_open", unimplementedFunc),
+ /* 5 */ SyscallDesc("open", openFunc<Linux>),
/* 6 */ SyscallDesc("close", closeFunc),
- /* 7 */ SyscallDesc("osf_wait4", unimplementedFunc),
- /* 8 */ SyscallDesc("osf_old_creat", unimplementedFunc),
+ /* 7 */ SyscallDesc("waitpid", unimplementedFunc),
+ /* 8 */ SyscallDesc("creat", unimplementedFunc),
/* 9 */ SyscallDesc("link", unimplementedFunc),
/* 10 */ SyscallDesc("unlink", unlinkFunc),
- /* 11 */ SyscallDesc("osf_execve", unimplementedFunc),
+ /* 11 */ SyscallDesc("execve", unimplementedFunc),
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
- /* 13 */ SyscallDesc("fchdir", unimplementedFunc),
+ /* 13 */ SyscallDesc("time", unimplementedFunc),
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
- /* 16 */ SyscallDesc("chown", chownFunc),
- /* 17 */ SyscallDesc("brk", obreakFunc),
- /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
+ /* 16 */ SyscallDesc("lchown", chownFunc),
+ /* 17 */ SyscallDesc("break", unimplementedFunc), /*obreak*/
+ /* 18 */ SyscallDesc("unused#18", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
- /* 20 */ SyscallDesc("getxpid", getpidFunc),
- /* 21 */ SyscallDesc("osf_mount", unimplementedFunc),
+ /* 20 */ SyscallDesc("getpid", getpidFunc),
+ /* 21 */ SyscallDesc("mount", unimplementedFunc),
/* 22 */ SyscallDesc("umount", unimplementedFunc),
/* 23 */ SyscallDesc("setuid", setuidFunc),
- /* 24 */ SyscallDesc("getxuid", getuidFunc),
- /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc),
- /* 26 */ SyscallDesc("osf_ptrace", unimplementedFunc),
- /* 27 */ SyscallDesc("osf_nrecvmsg", unimplementedFunc),
- /* 28 */ SyscallDesc("osf_nsendmsg", unimplementedFunc),
- /* 29 */ SyscallDesc("osf_nrecvfrom", unimplementedFunc),
- /* 30 */ SyscallDesc("osf_naccept", unimplementedFunc),
- /* 31 */ SyscallDesc("osf_ngetpeername", unimplementedFunc),
- /* 32 */ SyscallDesc("osf_ngetsockname", unimplementedFunc),
+ /* 24 */ SyscallDesc("getuid", getuidFunc),
+ /* 25 */ SyscallDesc("stime", unimplementedFunc),
+ /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
+ /* 27 */ SyscallDesc("alarm", unimplementedFunc),
+ /* 28 */ SyscallDesc("unused#28", unimplementedFunc),
+ /* 29 */ SyscallDesc("pause", unimplementedFunc),
+ /* 30 */ SyscallDesc("utime", unimplementedFunc),
+ /* 31 */ SyscallDesc("stty", unimplementedFunc),
+ /* 32 */ SyscallDesc("gtty", unimplementedFunc),
/* 33 */ SyscallDesc("access", unimplementedFunc),
- /* 34 */ SyscallDesc("osf_chflags", unimplementedFunc),
- /* 35 */ SyscallDesc("osf_fchflags", unimplementedFunc),
+ /* 34 */ SyscallDesc("nice", unimplementedFunc),
+ /* 35 */ SyscallDesc("ftime", unimplementedFunc),
/* 36 */ SyscallDesc("sync", unimplementedFunc),
- /* 37 */ SyscallDesc("kill", unimplementedFunc),
- /* 38 */ SyscallDesc("osf_old_stat", unimplementedFunc),
- /* 39 */ SyscallDesc("setpgid", unimplementedFunc),
- /* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc),
+ /* 37 */ SyscallDesc("kill", ignoreFunc),
+ /* 38 */ SyscallDesc("rename", unimplementedFunc),
+ /* 39 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 40 */ SyscallDesc("rmdir", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
- /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc),
- /* 44 */ SyscallDesc("osf_profil", unimplementedFunc),
- /* 45 */ SyscallDesc("open", openFunc<Linux>),
- /* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc),
- /* 47 */ SyscallDesc("getxgid", getgidFunc),
- /* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc),
- /* 49 */ SyscallDesc("osf_getlogin", unimplementedFunc),
- /* 50 */ SyscallDesc("osf_setlogin", unimplementedFunc),
+ /* 43 */ SyscallDesc("times", unimplementedFunc),
+ /* 44 */ SyscallDesc("prof", unimplementedFunc),
+ /* 45 */ SyscallDesc("brk", unimplementedFunc),/*openFunc<Linux>*/
+ /* 46 */ SyscallDesc("setgid", setgidFunc),
+ /* 47 */ SyscallDesc("getgid", getgidFunc),
+ /* 48 */ SyscallDesc("signal", ignoreFunc),
+ /* 49 */ SyscallDesc("geteuid", unimplementedFunc),
+ /* 50 */ SyscallDesc("getegid", unimplementedFunc),
/* 51 */ SyscallDesc("acct", unimplementedFunc),
- /* 52 */ SyscallDesc("sigpending", unimplementedFunc),
- /* 53 */ SyscallDesc("osf_classcntl", unimplementedFunc),
+ /* 52 */ SyscallDesc("umount2", unimplementedFunc),
+ /* 53 */ SyscallDesc("lock", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", ioctlFunc<Linux>),
- /* 55 */ SyscallDesc("osf_reboot", unimplementedFunc),
- /* 56 */ SyscallDesc("osf_revoke", unimplementedFunc),
- /* 57 */ SyscallDesc("symlink", unimplementedFunc),
- /* 58 */ SyscallDesc("readlink", unimplementedFunc),
- /* 59 */ SyscallDesc("execve", unimplementedFunc),
+ /* 55 */ SyscallDesc("fcntl", unimplementedFunc),
+ /* 56 */ SyscallDesc("mpx", unimplementedFunc),
+ /* 57 */ SyscallDesc("setpgid", unimplementedFunc),
+ /* 58 */ SyscallDesc("ulimit", unimplementedFunc),
+ /* 59 */ SyscallDesc("unused#59", unimplementedFunc),
/* 60 */ SyscallDesc("umask", unimplementedFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
- /* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc),
- /* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
- /* 64 */ SyscallDesc("getpagesize", getpagesizeFunc),
- /* 65 */ SyscallDesc("osf_mremap", unimplementedFunc),
- /* 66 */ SyscallDesc("vfork", unimplementedFunc),
- /* 67 */ SyscallDesc("stat", statFunc<Linux>),
- /* 68 */ SyscallDesc("lstat", lstatFunc<Linux>),
- /* 69 */ SyscallDesc("osf_sbrk", unimplementedFunc),
- /* 70 */ SyscallDesc("osf_sstk", unimplementedFunc),
- /* 71 */ SyscallDesc("mmap", mmapFunc<Linux>),
- /* 72 */ SyscallDesc("osf_old_vadvise", unimplementedFunc),
- /* 73 */ SyscallDesc("munmap", munmapFunc),
- /* 74 */ SyscallDesc("mprotect", ignoreFunc),
- /* 75 */ SyscallDesc("madvise", unimplementedFunc),
- /* 76 */ SyscallDesc("vhangup", unimplementedFunc),
- /* 77 */ SyscallDesc("osf_kmodcall", unimplementedFunc),
- /* 78 */ SyscallDesc("osf_mincore", unimplementedFunc),
- /* 79 */ SyscallDesc("getgroups", unimplementedFunc),
- /* 80 */ SyscallDesc("setgroups", unimplementedFunc),
- /* 81 */ SyscallDesc("osf_old_getpgrp", unimplementedFunc),
- /* 82 */ SyscallDesc("setpgrp", unimplementedFunc),
- /* 83 */ SyscallDesc("osf_setitimer", unimplementedFunc),
- /* 84 */ SyscallDesc("osf_old_wait", unimplementedFunc),
- /* 85 */ SyscallDesc("osf_table", unimplementedFunc),
- /* 86 */ SyscallDesc("osf_getitimer", unimplementedFunc),
- /* 87 */ SyscallDesc("gethostname", gethostnameFunc),
- /* 88 */ SyscallDesc("sethostname", unimplementedFunc),
- /* 89 */ SyscallDesc("getdtablesize", unimplementedFunc),
- /* 90 */ SyscallDesc("dup2", unimplementedFunc),
- /* 91 */ SyscallDesc("fstat", fstatFunc<Linux>),
- /* 92 */ SyscallDesc("fcntl", fcntlFunc),
- /* 93 */ SyscallDesc("osf_select", unimplementedFunc),
- /* 94 */ SyscallDesc("poll", unimplementedFunc),
- /* 95 */ SyscallDesc("fsync", unimplementedFunc),
- /* 96 */ SyscallDesc("setpriority", unimplementedFunc),
- /* 97 */ SyscallDesc("socket", unimplementedFunc),
- /* 98 */ SyscallDesc("connect", unimplementedFunc),
- /* 99 */ SyscallDesc("accept", unimplementedFunc),
- /* 100 */ SyscallDesc("getpriority", unimplementedFunc),
- /* 101 */ SyscallDesc("send", unimplementedFunc),
- /* 102 */ SyscallDesc("recv", unimplementedFunc),
- /* 103 */ SyscallDesc("sigreturn", unimplementedFunc),
- /* 104 */ SyscallDesc("bind", unimplementedFunc),
- /* 105 */ SyscallDesc("setsockopt", unimplementedFunc),
- /* 106 */ SyscallDesc("listen", unimplementedFunc),
- /* 107 */ SyscallDesc("osf_plock", unimplementedFunc),
- /* 108 */ SyscallDesc("osf_old_sigvec", unimplementedFunc),
- /* 109 */ SyscallDesc("osf_old_sigblock", unimplementedFunc),
- /* 110 */ SyscallDesc("osf_old_sigsetmask", unimplementedFunc),
- /* 111 */ SyscallDesc("sigsuspend", unimplementedFunc),
- /* 112 */ SyscallDesc("osf_sigstack", ignoreFunc),
- /* 113 */ SyscallDesc("recvmsg", unimplementedFunc),
- /* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
- /* 115 */ SyscallDesc("osf_old_vtrace", unimplementedFunc),
- /* 116 */ SyscallDesc("osf_gettimeofday", unimplementedFunc),
- /* 117 */ SyscallDesc("osf_getrusage", unimplementedFunc),
- /* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
- /* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc),
- /* 120 */ SyscallDesc("readv", unimplementedFunc),
- /* 121 */ SyscallDesc("writev", writevFunc<Linux>),
- /* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc),
- /* 123 */ SyscallDesc("fchown", fchownFunc),
- /* 124 */ SyscallDesc("fchmod", fchmodFunc<Linux>),
- /* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
- /* 126 */ SyscallDesc("setreuid", unimplementedFunc),
- /* 127 */ SyscallDesc("setregid", unimplementedFunc),
- /* 128 */ SyscallDesc("rename", renameFunc),
- /* 129 */ SyscallDesc("truncate", unimplementedFunc),
- /* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
- /* 131 */ SyscallDesc("flock", unimplementedFunc),
- /* 132 */ SyscallDesc("setgid", unimplementedFunc),
- /* 133 */ SyscallDesc("sendto", unimplementedFunc),
- /* 134 */ SyscallDesc("shutdown", unimplementedFunc),
- /* 135 */ SyscallDesc("socketpair", unimplementedFunc),
- /* 136 */ SyscallDesc("mkdir", unimplementedFunc),
- /* 137 */ SyscallDesc("rmdir", unimplementedFunc),
- /* 138 */ SyscallDesc("osf_utimes", unimplementedFunc),
- /* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc),
- /* 140 */ SyscallDesc("osf_adjtime", unimplementedFunc),
- /* 141 */ SyscallDesc("getpeername", unimplementedFunc),
- /* 142 */ SyscallDesc("osf_gethostid", unimplementedFunc),
- /* 143 */ SyscallDesc("osf_sethostid", unimplementedFunc),
- /* 144 */ SyscallDesc("getrlimit", getrlimitFunc<Linux>),
- /* 145 */ SyscallDesc("setrlimit", ignoreFunc),
- /* 146 */ SyscallDesc("osf_old_killpg", unimplementedFunc),
- /* 147 */ SyscallDesc("setsid", unimplementedFunc),
- /* 148 */ SyscallDesc("quotactl", unimplementedFunc),
- /* 149 */ SyscallDesc("osf_oldquota", unimplementedFunc),
- /* 150 */ SyscallDesc("getsockname", unimplementedFunc),
- /* 151 */ SyscallDesc("osf_pread", unimplementedFunc),
- /* 152 */ SyscallDesc("osf_pwrite", unimplementedFunc),
- /* 153 */ SyscallDesc("osf_pid_block", unimplementedFunc),
- /* 154 */ SyscallDesc("osf_pid_unblock", unimplementedFunc),
- /* 155 */ SyscallDesc("osf_signal_urti", unimplementedFunc),
- /* 156 */ SyscallDesc("sigaction", ignoreFunc),
- /* 157 */ SyscallDesc("osf_sigwaitprim", unimplementedFunc),
- /* 158 */ SyscallDesc("osf_nfssvc", unimplementedFunc),
- /* 159 */ SyscallDesc("osf_getdirentries", unimplementedFunc),
- /* 160 */ SyscallDesc("osf_statfs", unimplementedFunc),
- /* 161 */ SyscallDesc("osf_fstatfs", unimplementedFunc),
- /* 162 */ SyscallDesc("unknown #162", unimplementedFunc),
- /* 163 */ SyscallDesc("osf_async_daemon", unimplementedFunc),
- /* 164 */ SyscallDesc("osf_getfh", unimplementedFunc),
- /* 165 */ SyscallDesc("osf_getdomainname", unimplementedFunc),
- /* 166 */ SyscallDesc("setdomainname", unimplementedFunc),
- /* 167 */ SyscallDesc("unknown #167", unimplementedFunc),
- /* 168 */ SyscallDesc("unknown #168", unimplementedFunc),
- /* 169 */ SyscallDesc("osf_exportfs", unimplementedFunc),
- /* 170 */ SyscallDesc("unknown #170", unimplementedFunc),
- /* 171 */ SyscallDesc("unknown #171", unimplementedFunc),
- /* 172 */ SyscallDesc("unknown #172", unimplementedFunc),
- /* 173 */ SyscallDesc("unknown #173", unimplementedFunc),
- /* 174 */ SyscallDesc("unknown #174", unimplementedFunc),
- /* 175 */ SyscallDesc("unknown #175", unimplementedFunc),
- /* 176 */ SyscallDesc("unknown #176", unimplementedFunc),
- /* 177 */ SyscallDesc("unknown #177", unimplementedFunc),
- /* 178 */ SyscallDesc("unknown #178", unimplementedFunc),
- /* 179 */ SyscallDesc("unknown #179", unimplementedFunc),
- /* 180 */ SyscallDesc("unknown #180", unimplementedFunc),
- /* 181 */ SyscallDesc("osf_alt_plock", unimplementedFunc),
+ /* 62 */ SyscallDesc("ustat", unimplementedFunc),
+ /* 63 */ SyscallDesc("dup2", unimplementedFunc),
+ /* 64 */ SyscallDesc("getppid", getpagesizeFunc),
+ /* 65 */ SyscallDesc("getpgrp", unimplementedFunc),
+ /* 66 */ SyscallDesc("setsid", unimplementedFunc),
+ /* 67 */ SyscallDesc("sigaction", statFunc<Linux>),
+ /* 68 */ SyscallDesc("sgetmask", lstatFunc<Linux>),
+ /* 69 */ SyscallDesc("ssetmask", unimplementedFunc),
+ /* 70 */ SyscallDesc("setreuid", unimplementedFunc),
+ /* 71 */ SyscallDesc("setregid", mmapFunc<Linux>),
+ /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
+ /* 73 */ SyscallDesc("sigpending", munmapFunc),
+ /* 74 */ SyscallDesc("sethostname", ignoreFunc),
+ /* 75 */ SyscallDesc("setrlimit", unimplementedFunc),
+ /* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
+ /* 77 */ SyscallDesc("getrusage", unimplementedFunc),
+ /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
+ /* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
+ /* 80 */ SyscallDesc("getgroups", unimplementedFunc),
+ /* 81 */ SyscallDesc("setgroups", unimplementedFunc),
+ /* 82 */ SyscallDesc("reserved#82", unimplementedFunc),
+ /* 83 */ SyscallDesc("symlink", unimplementedFunc),
+ /* 84 */ SyscallDesc("unused#84", unimplementedFunc),
+ /* 85 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 86 */ SyscallDesc("uselib", unimplementedFunc),
+ /* 87 */ SyscallDesc("swapon", gethostnameFunc),
+ /* 88 */ SyscallDesc("reboot", unimplementedFunc),
+ /* 89 */ SyscallDesc("readdir", unimplementedFunc),
+ /* 90 */ SyscallDesc("mmap", mmapFunc<Linux>),
+ /* 91 */ SyscallDesc("munmap", ),/*fstatFunc<Linux>*/
+ /* 92 */ SyscallDesc("truncate", fcntlFunc),
+ /* 93 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 94 */ SyscallDesc("fchmod", unimplementedFunc),
+ /* 95 */ SyscallDesc("fchown", unimplementedFunc),
+ /* 96 */ SyscallDesc("getpriority", unimplementedFunc),
+ /* 97 */ SyscallDesc("setpriority", unimplementedFunc),
+ /* 98 */ SyscallDesc("profil", unimplementedFunc),
+ /* 99 */ SyscallDesc("statfs", unimplementedFunc),
+ /* 100 */ SyscallDesc("fstatfs", unimplementedFunc),
+ /* 101 */ SyscallDesc("ioperm", unimplementedFunc),
+ /* 102 */ SyscallDesc("socketcall", unimplementedFunc),
+ /* 103 */ SyscallDesc("syslog", unimplementedFunc),
+ /* 104 */ SyscallDesc("setitimer", unimplementedFunc),
+ /* 105 */ SyscallDesc("getitimer", unimplementedFunc),
+ /* 106 */ SyscallDesc("stat", unimplementedFunc),
+ /* 107 */ SyscallDesc("lstat", unimplementedFunc),
+ /* 108 */ SyscallDesc("fstat", unimplementedFunc),
+ /* 109 */ SyscallDesc("unused#109", unimplementedFunc),
+ /* 110 */ SyscallDesc("iopl", unimplementedFunc),
+ /* 111 */ SyscallDesc("vhangup", unimplementedFunc),
+ /* 112 */ SyscallDesc("idle", ignoreFunc),
+ /* 113 */ SyscallDesc("vm86", unimplementedFunc),
+ /* 114 */ SyscallDesc("wait4", unimplementedFunc),
+ /* 115 */ SyscallDesc("swapoff", unimplementedFunc),
+ /* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 117 */ SyscallDesc("ipc", unimplementedFunc),
+ /* 118 */ SyscallDesc("fsync", unimplementedFunc),
+ /* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
+ /* 120 */ SyscallDesc("clone", unimplementedFunc),
+ /* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
+ /* 122 */ SyscallDesc("uname", unameFunc)/*,writevFunc<Linux>*/
+ /* 123 */ SyscallDesc("modify_ldt", fchownFunc),
+ /* 124 */ SyscallDesc("adjtimex", fchmodFunc<Linux>),
+ /* 125 */ SyscallDesc("mprotect", unimplementedFunc),
+ /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc),
+ /* 127 */ SyscallDesc("create_module", unimplementedFunc),
+ /* 128 */ SyscallDesc("init_module", unimplementedFunc),
+ /* 129 */ SyscallDesc("delete_module", unimplementedFunc),
+ /* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
+ /* 131 */ SyscallDesc("quotactl", unimplementedFunc),
+ /* 132 */ SyscallDesc("getpgid", unimplementedFunc),
+ /* 133 */ SyscallDesc("fchdir", unimplementedFunc),
+ /* 134 */ SyscallDesc("bdflush", unimplementedFunc),
+ /* 135 */ SyscallDesc("sysfs", unimplementedFunc),
+ /* 136 */ SyscallDesc("personality", unimplementedFunc),
+ /* 137 */ SyscallDesc("afs_syscall", unimplementedFunc),
+ /* 138 */ SyscallDesc("setfsuid", unimplementedFunc),
+ /* 139 */ SyscallDesc("setfsgid", unimplementedFunc),
+ /* 140 */ SyscallDesc("llseek", unimplementedFunc),
+ /* 141 */ SyscallDesc("getdents", unimplementedFunc),
+ /* 142 */ SyscallDesc("newselect", unimplementedFunc),
+ /* 143 */ SyscallDesc("flock", unimplementedFunc),
+ /* 144 */ SyscallDesc("msync", unimplementedFunc),/*getrlimitFunc<Linux>*/
+ /* 145 */ SyscallDesc("readv", unimplementedFunc),
+ /* 146 */ SyscallDesc("writev", unimplementedFunc/*writeFunc*/),
+ /* 147 */ SyscallDesc("cacheflush", unimplementedFunc),
+ /* 148 */ SyscallDesc("cachectl", unimplementedFunc),
+ /* 149 */ SyscallDesc("sysmips", unimplementedFunc),
+ /* 150 */ SyscallDesc("unused#150", unimplementedFunc),
+ /* 151 */ SyscallDesc("getsid", unimplementedFunc),
+ /* 152 */ SyscallDesc("fdatasync", unimplementedFunc),
+ /* 153 */ SyscallDesc("sysctl", unimplementedFunc),
+ /* 154 */ SyscallDesc("mlock", unimplementedFunc),
+ /* 155 */ SyscallDesc("munlock", unimplementedFunc),
+ /* 156 */ SyscallDesc("mlockall", unimplementedFunc),
+ /* 157 */ SyscallDesc("munlockall", unimplementedFunc),
+ /* 158 */ SyscallDesc("sched_setparam", unimplementedFunc),
+ /* 159 */ SyscallDesc("sched_getparam", unimplementedFunc),
+ /* 160 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
+ /* 161 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
+ /* 162 */ SyscallDesc("sched_yield", unimplementedFunc),
+ /* 163 */ SyscallDesc("sched_get_prioritymax", unimplementedFunc),
+ /* 164 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
+ /* 165 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
+ /* 166 */ SyscallDesc("nanosleep", unimplementedFunc),
+ /* 167 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 168 */ SyscallDesc("accept", unimplementedFunc),
+ /* 169 */ SyscallDesc("bind", unimplementedFunc),
+ /* 170 */ SyscallDesc("connect", unimplementedFunc),
+ /* 171 */ SyscallDesc("getpeername", unimplementedFunc),
+ /* 172 */ SyscallDesc("getsockname", unimplementedFunc),
+ /* 173 */ SyscallDesc("getsockopt", unimplementedFunc),
+ /* 174 */ SyscallDesc("listen", unimplementedFunc),
+ /* 175 */ SyscallDesc("recv", unimplementedFunc),
+ /* 176 */ SyscallDesc("recvmsg", unimplementedFunc),
+ /* 177 */ SyscallDesc("send", unimplementedFunc),
+ /* 178 */ SyscallDesc("sendmsg", ignoreFunc),
+ /* 179 */ SyscallDesc("sendto", unimplementedFunc),
+ /* 180 */ SyscallDesc("setsockopt", unimplementedFunc),
+ /* 181 */ SyscallDesc("shutdown", unimplementedFunc),
/* 182 */ SyscallDesc("unknown #182", unimplementedFunc),
- /* 183 */ SyscallDesc("unknown #183", unimplementedFunc),
- /* 184 */ SyscallDesc("osf_getmnt", unimplementedFunc),
- /* 185 */ SyscallDesc("unknown #185", unimplementedFunc),
- /* 186 */ SyscallDesc("unknown #186", unimplementedFunc),
- /* 187 */ SyscallDesc("osf_alt_sigpending", unimplementedFunc),
- /* 188 */ SyscallDesc("osf_alt_setsid", unimplementedFunc),
- /* 189 */ SyscallDesc("unknown #189", unimplementedFunc),
- /* 190 */ SyscallDesc("unknown #190", unimplementedFunc),
- /* 191 */ SyscallDesc("unknown #191", unimplementedFunc),
- /* 192 */ SyscallDesc("unknown #192", unimplementedFunc),
- /* 193 */ SyscallDesc("unknown #193", unimplementedFunc),
- /* 194 */ SyscallDesc("unknown #194", unimplementedFunc),
- /* 195 */ SyscallDesc("unknown #195", unimplementedFunc),
- /* 196 */ SyscallDesc("unknown #196", unimplementedFunc),
- /* 197 */ SyscallDesc("unknown #197", unimplementedFunc),
- /* 198 */ SyscallDesc("unknown #198", unimplementedFunc),
- /* 199 */ SyscallDesc("osf_swapon", unimplementedFunc),
- /* 200 */ SyscallDesc("msgctl", unimplementedFunc),
- /* 201 */ SyscallDesc("msgget", unimplementedFunc),
- /* 202 */ SyscallDesc("msgrcv", unimplementedFunc),
- /* 203 */ SyscallDesc("msgsnd", unimplementedFunc),
- /* 204 */ SyscallDesc("semctl", unimplementedFunc),
- /* 205 */ SyscallDesc("semget", unimplementedFunc),
- /* 206 */ SyscallDesc("semop", unimplementedFunc),
- /* 207 */ SyscallDesc("osf_utsname", unimplementedFunc),
- /* 208 */ SyscallDesc("lchown", unimplementedFunc),
- /* 209 */ SyscallDesc("osf_shmat", unimplementedFunc),
- /* 210 */ SyscallDesc("shmctl", unimplementedFunc),
- /* 211 */ SyscallDesc("shmdt", unimplementedFunc),
- /* 212 */ SyscallDesc("shmget", unimplementedFunc),
- /* 213 */ SyscallDesc("osf_mvalid", unimplementedFunc),
- /* 214 */ SyscallDesc("osf_getaddressconf", unimplementedFunc),
- /* 215 */ SyscallDesc("osf_msleep", unimplementedFunc),
- /* 216 */ SyscallDesc("osf_mwakeup", unimplementedFunc),
- /* 217 */ SyscallDesc("msync", unimplementedFunc),
- /* 218 */ SyscallDesc("osf_signal", unimplementedFunc),
- /* 219 */ SyscallDesc("osf_utc_gettime", unimplementedFunc),
- /* 220 */ SyscallDesc("osf_utc_adjtime", unimplementedFunc),
- /* 221 */ SyscallDesc("unknown #221", unimplementedFunc),
- /* 222 */ SyscallDesc("osf_security", unimplementedFunc),
- /* 223 */ SyscallDesc("osf_kloadcall", unimplementedFunc),
- /* 224 */ SyscallDesc("unknown #224", unimplementedFunc),
- /* 225 */ SyscallDesc("unknown #225", unimplementedFunc),
- /* 226 */ SyscallDesc("unknown #226", unimplementedFunc),
- /* 227 */ SyscallDesc("unknown #227", unimplementedFunc),
- /* 228 */ SyscallDesc("unknown #228", unimplementedFunc),
- /* 229 */ SyscallDesc("unknown #229", unimplementedFunc),
- /* 230 */ SyscallDesc("unknown #230", unimplementedFunc),
- /* 231 */ SyscallDesc("unknown #231", unimplementedFunc),
- /* 232 */ SyscallDesc("unknown #232", unimplementedFunc),
- /* 233 */ SyscallDesc("getpgid", unimplementedFunc),
- /* 234 */ SyscallDesc("getsid", unimplementedFunc),
- /* 235 */ SyscallDesc("sigaltstack", ignoreFunc),
- /* 236 */ SyscallDesc("osf_waitid", unimplementedFunc),
- /* 237 */ SyscallDesc("osf_priocntlset", unimplementedFunc),
- /* 238 */ SyscallDesc("osf_sigsendset", unimplementedFunc),
- /* 239 */ SyscallDesc("osf_set_speculative", unimplementedFunc),
- /* 240 */ SyscallDesc("osf_msfs_syscall", unimplementedFunc),
- /* 241 */ SyscallDesc("osf_sysinfo", unimplementedFunc),
- /* 242 */ SyscallDesc("osf_uadmin", unimplementedFunc),
- /* 243 */ SyscallDesc("osf_fuser", unimplementedFunc),
- /* 244 */ SyscallDesc("osf_proplist_syscall", unimplementedFunc),
- /* 245 */ SyscallDesc("osf_ntp_adjtime", unimplementedFunc),
- /* 246 */ SyscallDesc("osf_ntp_gettime", unimplementedFunc),
- /* 247 */ SyscallDesc("osf_pathconf", unimplementedFunc),
- /* 248 */ SyscallDesc("osf_fpathconf", unimplementedFunc),
- /* 249 */ SyscallDesc("unknown #249", unimplementedFunc),
- /* 250 */ SyscallDesc("osf_uswitch", unimplementedFunc),
- /* 251 */ SyscallDesc("osf_usleep_thread", unimplementedFunc),
- /* 252 */ SyscallDesc("osf_audcntl", unimplementedFunc),
- /* 253 */ SyscallDesc("osf_audgen", unimplementedFunc),
- /* 254 */ SyscallDesc("sysfs", unimplementedFunc),
- /* 255 */ SyscallDesc("osf_subsys_info", unimplementedFunc),
- /* 256 */ SyscallDesc("osf_getsysinfo", osf_getsysinfoFunc),
- /* 257 */ SyscallDesc("osf_setsysinfo", osf_setsysinfoFunc),
- /* 258 */ SyscallDesc("osf_afs_syscall", unimplementedFunc),
- /* 259 */ SyscallDesc("osf_swapctl", unimplementedFunc),
- /* 260 */ SyscallDesc("osf_memcntl", unimplementedFunc),
- /* 261 */ SyscallDesc("osf_fdatasync", unimplementedFunc),
- /* 262 */ SyscallDesc("unknown #262", unimplementedFunc),
- /* 263 */ SyscallDesc("unknown #263", unimplementedFunc),
- /* 264 */ SyscallDesc("unknown #264", unimplementedFunc),
- /* 265 */ SyscallDesc("unknown #265", unimplementedFunc),
- /* 266 */ SyscallDesc("unknown #266", unimplementedFunc),
- /* 267 */ SyscallDesc("unknown #267", unimplementedFunc),
- /* 268 */ SyscallDesc("unknown #268", unimplementedFunc),
- /* 269 */ SyscallDesc("unknown #269", unimplementedFunc),
- /* 270 */ SyscallDesc("unknown #270", unimplementedFunc),
- /* 271 */ SyscallDesc("unknown #271", unimplementedFunc),
- /* 272 */ SyscallDesc("unknown #272", unimplementedFunc),
- /* 273 */ SyscallDesc("unknown #273", unimplementedFunc),
- /* 274 */ SyscallDesc("unknown #274", unimplementedFunc),
- /* 275 */ SyscallDesc("unknown #275", unimplementedFunc),
- /* 276 */ SyscallDesc("unknown #276", unimplementedFunc),
- /* 277 */ SyscallDesc("unknown #277", unimplementedFunc),
- /* 278 */ SyscallDesc("unknown #278", unimplementedFunc),
+ /* 183 */ SyscallDesc("socket", ignoreFunc),
+ /* 184 */ SyscallDesc("socketpair", unimplementedFunc),
+ /* 185 */ SyscallDesc("setresuid", unimplementedFunc),
+ /* 186 */ SyscallDesc("getresuid", unimplementedFunc),
+ /* 187 */ SyscallDesc("query_module", unimplementedFunc),
+ /* 188 */ SyscallDesc("poll", unimplementedFunc),
+ /* 189 */ SyscallDesc("nfsservctl", unimplementedFunc),
+ /* 190 */ SyscallDesc("setresgid", unimplementedFunc),
+ /* 191 */ SyscallDesc("getresgid", unimplementedFunc),
+ /* 192 */ SyscallDesc("prctl", unimplementedFunc),
+ /* 193 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
+ /* 194 */ SyscallDesc("rt_sigaction", ignoreFunc),
+ /* 195 */ SyscallDesc("rt_sigprocmask", ignoreFunc),
+ /* 196 */ SyscallDesc("rt_sigpending", unimplementedFunc),
+ /* 197 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+ /* 198 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
+ /* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+ /* 200 */ SyscallDesc("pread64", unimplementedFunc),
+ /* 201 */ SyscallDesc("pwrite64", unimplementedFunc),
+ /* 202 */ SyscallDesc("chown", unimplementedFunc),
+ /* 203 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 204 */ SyscallDesc("capget", unimplementedFunc),
+ /* 205 */ SyscallDesc("capset", unimplementedFunc),
+ /* 206 */ SyscallDesc("sigalstack", unimplementedFunc),
+ /* 207 */ SyscallDesc("sendfile", unimplementedFunc),
+ /* 208 */ SyscallDesc("getpmsg", unimplementedFunc),
+ /* 209 */ SyscallDesc("putpmsg", unimplementedFunc),
+ /* 210 */ SyscallDesc("mmap2", unimplementedFunc),
+ /* 211 */ SyscallDesc("truncate64", unimplementedFunc),
+ /* 212 */ SyscallDesc("ftruncate64", unimplementedFunc),
+ /* 213 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 214 */ SyscallDesc("lstat64", unimplementedFunc),
+ /* 215 */ SyscallDesc("fstat64", unimplementedFunc),
+ /* 216 */ SyscallDesc("pivot_root", unimplementedFunc),
+ /* 217 */ SyscallDesc("mincore", unimplementedFunc),
+ /* 218 */ SyscallDesc("madvise", unimplementedFunc),
+ /* 219 */ SyscallDesc("getdents64", unimplementedFunc),
+ /* 220 */ SyscallDesc("fcntl64", fcntlFunc),
+ /* 221 */ SyscallDesc("reserved#221", unimplementedFunc),
+ /* 222 */ SyscallDesc("gettid", unimplementedFunc),
+ /* 223 */ SyscallDesc("readahead", unimplementedFunc),
+ /* 224 */ SyscallDesc("setxattr", unimplementedFunc),
+ /* 225 */ SyscallDesc("lsetxattr", unimplementedFunc),
+ /* 226 */ SyscallDesc("fsetxattr", unimplementedFunc),
+ /* 227 */ SyscallDesc("getxattr", unimplementedFunc),
+ /* 228 */ SyscallDesc("lgetxattr", unimplementedFunc),
+ /* 229 */ SyscallDesc("fgetxattr", unimplementedFunc),
+ /* 230 */ SyscallDesc("listxattr", unimplementedFunc),
+ /* 231 */ SyscallDesc("llistxattr", unimplementedFunc),
+ /* 232 */ SyscallDesc("flistxattr", unimplementedFunc),
+ /* 233 */ SyscallDesc("removexattr", unimplementedFunc),
+ /* 234 */ SyscallDesc("lremovexattr", unimplementedFunc),
+ /* 235 */ SyscallDesc("fremovexattr", ignoreFunc),
+ /* 236 */ SyscallDesc("tkill", unimplementedFunc),
+ /* 237 */ SyscallDesc("sendfile64", unimplementedFunc),
+ /* 238 */ SyscallDesc("futex", unimplementedFunc),
+ /* 239 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 240 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 241 */ SyscallDesc("io_setup", unimplementedFunc),
+ /* 242 */ SyscallDesc("io_destroy", unimplementedFunc),
+ /* 243 */ SyscallDesc("io_getevents", unimplementedFunc),
+ /* 244 */ SyscallDesc("io_submit", unimplementedFunc),
+ /* 245 */ SyscallDesc("io_cancel", unimplementedFunc),
+ /* 246 */ SyscallDesc("exit_group", unimplementedFunc),
+ /* 247 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
+ /* 248 */ SyscallDesc("epoll_create", unimplementedFunc),
+ /* 249 */ SyscallDesc("epoll_ctl", unimplementedFunc),
+ /* 250 */ SyscallDesc("epoll_wait", unimplementedFunc),
+ /* 251 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+ /* 252 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 253 */ SyscallDesc("restart_syscall", unimplementedFunc),
+ /* 254 */ SyscallDesc("fadvise64", unimplementedFunc),
+ /* 255 */ SyscallDesc("statfs64", unimplementedFunc),
+ /* 256 */ SyscallDesc("fstafs64", unimplementedFunc),
+ /* 257 */ SyscallDesc("timer_create", sys_getsysinfoFunc),
+ /* 258 */ SyscallDesc("timer_settime", sys_setsysinfoFunc),
+ /* 259 */ SyscallDesc("timer_gettime", unimplementedFunc),
+ /* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+ /* 261 */ SyscallDesc("timer_delete", unimplementedFunc),
+ /* 262 */ SyscallDesc("clock_settime", unimplementedFunc),
+ /* 263 */ SyscallDesc("clock_gettime", unimplementedFunc),
+ /* 264 */ SyscallDesc("clock_getres", unimplementedFunc),
+ /* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
+ /* 266 */ SyscallDesc("tgkill", unimplementedFunc),
+ /* 267 */ SyscallDesc("utimes", unimplementedFunc),
+ /* 268 */ SyscallDesc("mbind", unimplementedFunc),
+ /* 269 */ SyscallDesc("get_mempolicy", unimplementedFunc),
+ /* 270 */ SyscallDesc("set_mempolicy", unimplementedFunc),
+ /* 271 */ SyscallDesc("mq_open", unimplementedFunc),
+ /* 272 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 273 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 274 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 275 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 276 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 277 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 278 */ SyscallDesc("waitid", unimplementedFunc),
/* 279 */ SyscallDesc("unknown #279", unimplementedFunc),
- /* 280 */ SyscallDesc("unknown #280", unimplementedFunc),
- /* 281 */ SyscallDesc("unknown #281", unimplementedFunc),
- /* 282 */ SyscallDesc("unknown #282", unimplementedFunc),
- /* 283 */ SyscallDesc("unknown #283", unimplementedFunc),
- /* 284 */ SyscallDesc("unknown #284", unimplementedFunc),
- /* 285 */ SyscallDesc("unknown #285", unimplementedFunc),
- /* 286 */ SyscallDesc("unknown #286", unimplementedFunc),
- /* 287 */ SyscallDesc("unknown #287", unimplementedFunc),
- /* 288 */ SyscallDesc("unknown #288", unimplementedFunc),
- /* 289 */ SyscallDesc("unknown #289", unimplementedFunc),
- /* 290 */ SyscallDesc("unknown #290", unimplementedFunc),
- /* 291 */ SyscallDesc("unknown #291", unimplementedFunc),
- /* 292 */ SyscallDesc("unknown #292", unimplementedFunc),
- /* 293 */ SyscallDesc("unknown #293", unimplementedFunc),
- /* 294 */ SyscallDesc("unknown #294", unimplementedFunc),
- /* 295 */ SyscallDesc("unknown #295", unimplementedFunc),
- /* 296 */ SyscallDesc("unknown #296", unimplementedFunc),
- /* 297 */ SyscallDesc("unknown #297", unimplementedFunc),
- /* 298 */ SyscallDesc("unknown #298", unimplementedFunc),
- /* 299 */ SyscallDesc("unknown #299", unimplementedFunc),
-/*
- * Linux-specific system calls begin at 300
- */
- /* 300 */ SyscallDesc("bdflush", unimplementedFunc),
- /* 301 */ SyscallDesc("sethae", unimplementedFunc),
- /* 302 */ SyscallDesc("mount", unimplementedFunc),
- /* 303 */ SyscallDesc("old_adjtimex", unimplementedFunc),
- /* 304 */ SyscallDesc("swapoff", unimplementedFunc),
- /* 305 */ SyscallDesc("getdents", unimplementedFunc),
- /* 306 */ SyscallDesc("create_module", unimplementedFunc),
- /* 307 */ SyscallDesc("init_module", unimplementedFunc),
- /* 308 */ SyscallDesc("delete_module", unimplementedFunc),
- /* 309 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
- /* 310 */ SyscallDesc("syslog", unimplementedFunc),
- /* 311 */ SyscallDesc("reboot", unimplementedFunc),
- /* 312 */ SyscallDesc("clone", unimplementedFunc),
- /* 313 */ SyscallDesc("uselib", unimplementedFunc),
- /* 314 */ SyscallDesc("mlock", unimplementedFunc),
- /* 315 */ SyscallDesc("munlock", unimplementedFunc),
- /* 316 */ SyscallDesc("mlockall", unimplementedFunc),
- /* 317 */ SyscallDesc("munlockall", unimplementedFunc),
- /* 318 */ SyscallDesc("sysinfo", unimplementedFunc),
- /* 319 */ SyscallDesc("_sysctl", unimplementedFunc),
- /* 320 */ SyscallDesc("was sys_idle", unimplementedFunc),
- /* 321 */ SyscallDesc("oldumount", unimplementedFunc),
- /* 322 */ SyscallDesc("swapon", unimplementedFunc),
- /* 323 */ SyscallDesc("times", ignoreFunc),
- /* 324 */ SyscallDesc("personality", unimplementedFunc),
- /* 325 */ SyscallDesc("setfsuid", unimplementedFunc),
- /* 326 */ SyscallDesc("setfsgid", unimplementedFunc),
- /* 327 */ SyscallDesc("ustat", unimplementedFunc),
- /* 328 */ SyscallDesc("statfs", unimplementedFunc),
- /* 329 */ SyscallDesc("fstatfs", unimplementedFunc),
- /* 330 */ SyscallDesc("sched_setparam", unimplementedFunc),
- /* 331 */ SyscallDesc("sched_getparam", unimplementedFunc),
- /* 332 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
- /* 333 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
- /* 334 */ SyscallDesc("sched_yield", unimplementedFunc),
- /* 335 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
- /* 336 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
- /* 337 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
- /* 338 */ SyscallDesc("afs_syscall", unimplementedFunc),
- /* 339 */ SyscallDesc("uname", unameFunc),
- /* 340 */ SyscallDesc("nanosleep", unimplementedFunc),
- /* 341 */ SyscallDesc("mremap", unimplementedFunc),
- /* 342 */ SyscallDesc("nfsservctl", unimplementedFunc),
- /* 343 */ SyscallDesc("setresuid", unimplementedFunc),
- /* 344 */ SyscallDesc("getresuid", unimplementedFunc),
- /* 345 */ SyscallDesc("pciconfig_read", unimplementedFunc),
- /* 346 */ SyscallDesc("pciconfig_write", unimplementedFunc),
- /* 347 */ SyscallDesc("query_module", unimplementedFunc),
- /* 348 */ SyscallDesc("prctl", unimplementedFunc),
- /* 349 */ SyscallDesc("pread", unimplementedFunc),
- /* 350 */ SyscallDesc("pwrite", unimplementedFunc),
- /* 351 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
- /* 352 */ SyscallDesc("rt_sigaction", ignoreFunc),
- /* 353 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
- /* 354 */ SyscallDesc("rt_sigpending", unimplementedFunc),
- /* 355 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
- /* 356 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
- /* 357 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
- /* 358 */ SyscallDesc("select", unimplementedFunc),
- /* 359 */ SyscallDesc("gettimeofday", gettimeofdayFunc<Linux>),
- /* 360 */ SyscallDesc("settimeofday", unimplementedFunc),
- /* 361 */ SyscallDesc("getitimer", unimplementedFunc),
- /* 362 */ SyscallDesc("setitimer", unimplementedFunc),
- /* 363 */ SyscallDesc("utimes", utimesFunc<Linux>),
- /* 364 */ SyscallDesc("getrusage", getrusageFunc<Linux>),
- /* 365 */ SyscallDesc("wait4", unimplementedFunc),
- /* 366 */ SyscallDesc("adjtimex", unimplementedFunc),
- /* 367 */ SyscallDesc("getcwd", unimplementedFunc),
- /* 368 */ SyscallDesc("capget", unimplementedFunc),
- /* 369 */ SyscallDesc("capset", unimplementedFunc),
- /* 370 */ SyscallDesc("sendfile", unimplementedFunc),
- /* 371 */ SyscallDesc("setresgid", unimplementedFunc),
- /* 372 */ SyscallDesc("getresgid", unimplementedFunc),
- /* 373 */ SyscallDesc("dipc", unimplementedFunc),
- /* 374 */ SyscallDesc("pivot_root", unimplementedFunc),
- /* 375 */ SyscallDesc("mincore", unimplementedFunc),
- /* 376 */ SyscallDesc("pciconfig_iobase", unimplementedFunc),
- /* 377 */ SyscallDesc("getdents64", unimplementedFunc),
- /* 378 */ SyscallDesc("gettid", unimplementedFunc),
- /* 379 */ SyscallDesc("readahead", unimplementedFunc),
- /* 380 */ SyscallDesc("security", unimplementedFunc),
- /* 381 */ SyscallDesc("tkill", unimplementedFunc),
- /* 382 */ SyscallDesc("setxattr", unimplementedFunc),
- /* 383 */ SyscallDesc("lsetxattr", unimplementedFunc),
- /* 384 */ SyscallDesc("fsetxattr", unimplementedFunc),
- /* 385 */ SyscallDesc("getxattr", unimplementedFunc),
- /* 386 */ SyscallDesc("lgetxattr", unimplementedFunc),
- /* 387 */ SyscallDesc("fgetxattr", unimplementedFunc),
- /* 388 */ SyscallDesc("listxattr", unimplementedFunc),
- /* 389 */ SyscallDesc("llistxattr", unimplementedFunc),
- /* 390 */ SyscallDesc("flistxattr", unimplementedFunc),
- /* 391 */ SyscallDesc("removexattr", unimplementedFunc),
- /* 392 */ SyscallDesc("lremovexattr", unimplementedFunc),
- /* 393 */ SyscallDesc("fremovexattr", unimplementedFunc),
- /* 394 */ SyscallDesc("futex", unimplementedFunc),
- /* 395 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
- /* 396 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
- /* 397 */ SyscallDesc("tuxcall", unimplementedFunc),
- /* 398 */ SyscallDesc("io_setup", unimplementedFunc),
- /* 399 */ SyscallDesc("io_destroy", unimplementedFunc),
- /* 400 */ SyscallDesc("io_getevents", unimplementedFunc),
- /* 401 */ SyscallDesc("io_submit", unimplementedFunc),
- /* 402 */ SyscallDesc("io_cancel", unimplementedFunc),
- /* 403 */ SyscallDesc("unknown #403", unimplementedFunc),
- /* 404 */ SyscallDesc("unknown #404", unimplementedFunc),
- /* 405 */ SyscallDesc("exit_group", exitFunc), // exit all threads...
- /* 406 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
- /* 407 */ SyscallDesc("sys_epoll_create", unimplementedFunc),
- /* 408 */ SyscallDesc("sys_epoll_ctl", unimplementedFunc),
- /* 409 */ SyscallDesc("sys_epoll_wait", unimplementedFunc),
- /* 410 */ SyscallDesc("remap_file_pages", unimplementedFunc),
- /* 411 */ SyscallDesc("set_tid_address", unimplementedFunc),
- /* 412 */ SyscallDesc("restart_syscall", unimplementedFunc),
- /* 413 */ SyscallDesc("fadvise64", unimplementedFunc),
- /* 414 */ SyscallDesc("timer_create", unimplementedFunc),
- /* 415 */ SyscallDesc("timer_settime", unimplementedFunc),
- /* 416 */ SyscallDesc("timer_gettime", unimplementedFunc),
- /* 417 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
- /* 418 */ SyscallDesc("timer_delete", unimplementedFunc),
- /* 419 */ SyscallDesc("clock_settime", unimplementedFunc),
- /* 420 */ SyscallDesc("clock_gettime", unimplementedFunc),
- /* 421 */ SyscallDesc("clock_getres", unimplementedFunc),
- /* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
- /* 423 */ SyscallDesc("semtimedop", unimplementedFunc),
- /* 424 */ SyscallDesc("tgkill", unimplementedFunc),
- /* 425 */ SyscallDesc("stat64", unimplementedFunc),
- /* 426 */ SyscallDesc("lstat64", lstat64Func<Linux>),
- /* 427 */ SyscallDesc("fstat64", fstat64Func<Linux>),
- /* 428 */ SyscallDesc("vserver", unimplementedFunc),
- /* 429 */ SyscallDesc("mbind", unimplementedFunc),
- /* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc),
- /* 431 */ SyscallDesc("set_mempolicy", unimplementedFunc),
- /* 432 */ SyscallDesc("mq_open", unimplementedFunc),
- /* 433 */ SyscallDesc("mq_unlink", unimplementedFunc),
- /* 434 */ SyscallDesc("mq_timedsend", unimplementedFunc),
- /* 435 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
- /* 436 */ SyscallDesc("mq_notify", unimplementedFunc),
- /* 437 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
- /* 438 */ SyscallDesc("waitid", unimplementedFunc),
- /* 439 */ SyscallDesc("add_key", unimplementedFunc),
- /* 440 */ SyscallDesc("request_key", unimplementedFunc),
- /* 441 */ SyscallDesc("keyctl", unimplementedFunc)
+ /* 280 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 281 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 282 */ SyscallDesc("keyctl", unimplementedFunc),
};
MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
ObjectFile *objFile,
+ System *system,
int stdin_fd,
int stdout_fd,
int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp)
- : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp),
+ : MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
- init_regs->intRegFile[0] = 0;
+ //init_regs->intRegFile[0] = 0;
}
@@ -582,7 +421,11 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
SyscallDesc*
MipsLinuxProcess::getDesc(int callnum)
{
- if (callnum < 0 || callnum > Num_Syscall_Descs)
+ //MIPS32 syscalls are in the range of 4000 - 4999
+ int m5_sys_idx = callnum - 4000;
+
+ if (m5_sys_idx < 0 || m5_sys_idx > Num_Syscall_Descs)
return NULL;
- return &syscallDescs[callnum];
+
+ return &syscallDescs[m5_sys_idx];
}
diff --git a/arch/mips/linux_process.hh b/arch/mips/linux_process.hh
index 5408a6c44..68da3227b 100644
--- a/arch/mips/linux_process.hh
+++ b/arch/mips/linux_process.hh
@@ -29,16 +29,17 @@
#ifndef __MIPS_LINUX_PROCESS_HH__
#define __MIPS_LINUX_PROCESS_HH__
-#include "sim/process.hh"
+#include "arch/mips/process.hh"
/// A process with emulated Mips/Linux syscalls.
-class MipsLinuxProcess : public LiveProcess
+class MipsLinuxProcess : public MipsLiveProcess
{
public:
/// Constructor.
MipsLinuxProcess(const std::string &name,
ObjectFile *objFile,
+ System *system,
int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp);
diff --git a/arch/mips/process.cc b/arch/mips/process.cc
index 6de44fe9f..3f24fc68f 100644
--- a/arch/mips/process.cc
+++ b/arch/mips/process.cc
@@ -26,22 +26,37 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "arch/mips/isa_traits.hh"
#include "arch/mips/process.hh"
+#include "arch/mips/linux_process.hh"
+#include "base/loader/object_file.hh"
+#include "base/misc.hh"
+#include "cpu/exec_context.hh"
+#include "sim/builder.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace MipsISA;
-namespace MipsISA
-{
-LiveProcess *
-createProcess(const string &nm, ObjectFile * objFile,
- int stdin_fd, int stdout_fd, int stderr_fd,
- vector<string> &argv, vector<string> &envp)
+MipsLiveProcess *
+MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
+ int stdout_fd, int stderr_fd, std::string executable,
+ std::vector<std::string> &argv, std::vector<std::string> &envp)
{
- LiveProcess * process = NULL;
- if (objFile->getArch() != ObjectFile::MIPS)
+ MipsLiveProcess *process = NULL;
+
+ ObjectFile *objFile = createObjectFile(executable);
+ if (objFile == NULL) {
+ fatal("Can't load object file %s", executable);
+ }
+
+
+ if (objFile->getArch() != ObjectFile::Mips)
fatal("Object file does not match architecture.");
switch (objFile->getOpSys()) {
case ObjectFile::Linux:
- process = new MipsLinuxProcess(nm, objFile,
+ process = new MipsLinuxProcess(nm, objFile, system,
stdin_fd, stdout_fd, stderr_fd,
argv, envp);
break;
@@ -49,8 +64,98 @@ createProcess(const string &nm, ObjectFile * objFile,
default:
fatal("Unknown/unsupported operating system.");
}
+
+ if (process == NULL)
+ fatal("Unknown error creating process object.");
return process;
}
-} // namespace MipsISA
+MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv, std::vector<std::string> &envp)
+ : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp)
+{
+
+ // XXX all the below need to be updated for SPARC - Ali
+ brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
+ brk_point = roundUp(brk_point, VMPageSize);
+
+ // Set up stack. On Alpha, stack goes below text section. This
+ // code should get moved to some architecture-specific spot.
+ stack_base = objFile->textBase() - (409600+4096);
+
+ // Set up region for mmaps. Tru64 seems to start just above 0 and
+ // grow up from there.
+ mmap_start = mmap_end = 0x10000;
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+}
+
+void
+MipsLiveProcess::startup()
+{
+ argsInit(MachineBytes, VMPageSize);
+}
+
+
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
+
+ VectorParam<string> cmd;
+ Param<string> executable;
+ Param<string> input;
+ Param<string> output;
+ VectorParam<string> env;
+ SimObjectParam<System *> system;
+
+END_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
+
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
+
+ INIT_PARAM(cmd, "command line (executable plus arguments)"),
+ INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
+ INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
+ INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
+ INIT_PARAM(env, "environment settings"),
+ INIT_PARAM(system, "system")
+
+END_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
+
+
+CREATE_SIM_OBJECT(MipsLiveProcess)
+{
+ string in = input;
+ string out = output;
+
+ // initialize file descriptors to default: same as simulator
+ int stdin_fd, stdout_fd, stderr_fd;
+
+ if (in == "stdin" || in == "cin")
+ stdin_fd = STDIN_FILENO;
+ else
+ stdin_fd = Process::openInputFile(input);
+
+ if (out == "stdout" || out == "cout")
+ stdout_fd = STDOUT_FILENO;
+ else if (out == "stderr" || out == "cerr")
+ stdout_fd = STDERR_FILENO;
+ else
+ stdout_fd = Process::openOutputFile(out);
+
+ stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
+
+ return MipsLiveProcess::create(getInstanceName(), system,
+ stdin_fd, stdout_fd, stderr_fd,
+ (string)executable == "" ? cmd[0] : executable,
+ cmd, env);
+}
+
+
+REGISTER_SIM_OBJECT("MipsLiveProcess", MipsLiveProcess)
+
diff --git a/arch/mips/process.hh b/arch/mips/process.hh
index ab4323107..2a13dc955 100644
--- a/arch/mips/process.hh
+++ b/arch/mips/process.hh
@@ -29,17 +29,36 @@
#ifndef __MIPS_PROCESS_HH__
#define __MIPS_PROCESS_HH__
-#include "arch/mips/linux_process.hh"
-#include "base/loader/object_file.hh"
+#include <string>
+#include <vector>
+#include "sim/process.hh"
-namespace MipsISA
+class LiveProcess;
+class ObjectFile;
+class System;
+
+class MipsLiveProcess : public LiveProcess
{
+ protected:
+ MipsLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
+
+ void startup();
+
+ public:
+ // this function is used to create the LiveProcess object, since
+ // we can't tell which subclass of LiveProcess to use until we
+ // open and look at the object file.
+ static MipsLiveProcess *create(const std::string &nm,
+ System *_system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::string executable,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
-LiveProcess *
-createProcess(const string &nm, ObjectFile * objFile,
- int stdin_fd, int stdout_fd, int stderr_fd,
- vector<string> &argv, vector<string> &envp);
+};
-} // namespace MipsISA
#endif // __MIPS_PROCESS_HH__
diff --git a/arch/mips/utility.hh b/arch/mips/utility.hh
new file mode 100644
index 000000000..d4ad6cbd8
--- /dev/null
+++ b/arch/mips/utility.hh
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ */
+
+#ifndef __ARCH_MIPS_UTILITY_HH__
+#define __ARCH_MIPS_UTILITY_HH__
+
+//Placeholder file for now
+
+#endif
diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript
index edff5821e..172e4390f 100644
--- a/arch/sparc/SConscript
+++ b/arch/sparc/SConscript
@@ -57,8 +57,7 @@ full_system_sources = Split('''
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
- common_syscall_emul.cc
- linux_process.cc
+ linux/process.cc
process.cc
''')
diff --git a/arch/sparc/faults.cc b/arch/sparc/faults.cc
index b48fc600b..9831a7679 100644
--- a/arch/sparc/faults.cc
+++ b/arch/sparc/faults.cc
@@ -89,10 +89,10 @@ TrapType IllegalInstruction::_trapType = 0x010;
FaultPriority IllegalInstruction::_priority = 7;
FaultStat IllegalInstruction::_count;
-FaultName PrivelegedOpcode::_name = "priv_opcode";
-TrapType PrivelegedOpcode::_trapType = 0x011;
-FaultPriority PrivelegedOpcode::_priority = 6;
-FaultStat PrivelegedOpcode::_count;
+FaultName PrivilegedOpcode::_name = "priv_opcode";
+TrapType PrivilegedOpcode::_trapType = 0x011;
+FaultPriority PrivilegedOpcode::_priority = 6;
+FaultStat PrivilegedOpcode::_count;
FaultName UnimplementedLDD::_name = "unimp_ldd";
TrapType UnimplementedLDD::_trapType = 0x012;
@@ -159,10 +159,10 @@ TrapType STDFMemAddressNotAligned::_trapType = 0x036;
FaultPriority STDFMemAddressNotAligned::_priority = 10;
FaultStat STDFMemAddressNotAligned::_count;
-FaultName PrivelegedAction::_name = "priv_action";
-TrapType PrivelegedAction::_trapType = 0x037;
-FaultPriority PrivelegedAction::_priority = 11;
-FaultStat PrivelegedAction::_count;
+FaultName PrivilegedAction::_name = "priv_action";
+TrapType PrivilegedAction::_trapType = 0x037;
+FaultPriority PrivilegedAction::_priority = 11;
+FaultStat PrivilegedAction::_count;
FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf";
TrapType LDQFMemAddressNotAligned::_trapType = 0x038;
diff --git a/arch/sparc/faults.hh b/arch/sparc/faults.hh
index 318b1ad5a..985407c26 100644
--- a/arch/sparc/faults.hh
+++ b/arch/sparc/faults.hh
@@ -216,7 +216,7 @@ class IllegalInstruction : public SparcFault
FaultStat & countStat() {return _count;}
};
-class PrivelegedOpcode : public SparcFault
+class PrivilegedOpcode : public SparcFault
{
private:
static FaultName _name;
@@ -412,7 +412,7 @@ class STDFMemAddressNotAligned : public SparcFault
FaultStat & countStat() {return _count;}
};
-class PrivelegedAction : public SparcFault
+class PrivilegedAction : public SparcFault
{
private:
static FaultName _name;
diff --git a/arch/sparc/isa/base.isa b/arch/sparc/isa/base.isa
index 992504369..4721f728b 100644
--- a/arch/sparc/isa/base.isa
+++ b/arch/sparc/isa/base.isa
@@ -5,15 +5,19 @@
output header {{
- struct condCodes
+ union CondCodes
{
- uint8_t c:1;
- uint8_t v:1;
- uint8_t z:1;
- uint8_t n:1;
- }
+ struct
+ {
+ uint8_t c:1;
+ uint8_t v:1;
+ uint8_t z:1;
+ uint8_t n:1;
+ };
+ uint32_t bits;
+ };
- enum condTest
+ enum CondTest
{
Always=0x8,
Never=0x0,
@@ -31,7 +35,7 @@ output header {{
Negative=0x6,
OverflowClear=0xF,
OverflowSet=0x7
- }
+ };
/**
* Base class for all SPARC static instructions.
@@ -48,13 +52,47 @@ output header {{
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
+
+ void printReg(std::ostream &os, int reg) const;
};
- bool passesCondition(condCodes codes, condTest condition);
+ bool passesCondition(uint32_t codes, uint32_t condition);
+}};
+
+def template ROrImmDecode {{
+ {
+ return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
+ : (SparcStaticInst *)(new %(class_name)s(machInst)));
+ }
+}};
+
+let {{
+ def splitOutImm(code):
+ matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>d{0,2})')
+ rOrImmMatch = matcher.search(code)
+ if (rOrImmMatch == None):
+ return (False, CodeBlock(code), None, '', '')
+ rString = matcher.sub(r'(?P=rNum)', rOrImmMatch.string)
+ iString = matcher.sub(r'(?P=iNum)', rOrImmMatch.string)
+ orig_code = code
+ code = matcher.sub(r'Rs(?P<rNum>)', orig_code)
+ imm_code = matcher.sub('imm', orig_code)
+ return (True, CodeBlock(code), CodeBlock(imm_code), rString, iString)
}};
output decoder {{
+ void
+ SparcStaticInst::printReg(std::ostream &os, int reg) const
+ {
+ if (reg < FP_Base_DepTag) {
+ ccprintf(os, "r%d", reg);
+ }
+ else {
+ ccprintf(os, "f%d", reg - FP_Base_DepTag);
+ }
+ }
+
std::string SparcStaticInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
@@ -87,8 +125,10 @@ output decoder {{
return ss.str();
}
- bool passesCondition(condCodes codes, condTest condition)
+ bool passesCondition(uint32_t codes, uint32_t condition)
{
+ CondCodes condCodes;
+ condCodes.bits = codes;
switch(condition)
{
case Always:
@@ -96,34 +136,36 @@ output decoder {{
case Never:
return false;
case NotEqual:
- return !codes.z;
+ return !condCodes.z;
case Equal:
- return codes.z;
+ return condCodes.z;
case Greater:
- return !(codes.z | (codes.n ^ codes.v));
+ return !(condCodes.z | (condCodes.n ^ condCodes.v));
case LessOrEqual:
- return codes.z | (codes.n ^ codes.v);
+ return condCodes.z | (condCodes.n ^ condCodes.v);
case GreaterOrEqual:
- return !(codes.n ^ codes.v);
+ return !(condCodes.n ^ condCodes.v);
case Less:
- return (codes.n ^ codes.v);
+ return (condCodes.n ^ condCodes.v);
case GreaterUnsigned:
- return !(codes.c | codes.z);
+ return !(condCodes.c | condCodes.z);
case LessOrEqualUnsigned:
- return (codes.c | codes.z);
+ return (condCodes.c | condCodes.z);
case CarryClear:
- return !codes.c;
+ return !condCodes.c;
case CarrySet:
- return codes.c;
+ return condCodes.c;
case Positive:
- return !codes.n;
+ return !condCodes.n;
case Negative:
- return codes.n;
+ return condCodes.n;
case OverflowClear:
- return !codes.v;
+ return !condCodes.v;
case OverflowSet:
- return codes.v;
+ return condCodes.v;
}
+ panic("Tried testing condition nonexistant "
+ "condition code %d", condition);
}
}};
diff --git a/arch/sparc/isa/bitfields.isa b/arch/sparc/isa/bitfields.isa
index b0ac57575..2e4478099 100644
--- a/arch/sparc/isa/bitfields.isa
+++ b/arch/sparc/isa/bitfields.isa
@@ -7,13 +7,11 @@
// simply defined alphabetically
def bitfield A <29>;
-def bitfield CC02 <20>;
-def bitfield CC03 <25>;
-def bitfield CC04 <11>;
-def bitfield CC12 <21>;
-def bitfield CC13 <26>;
-def bitfield CC14 <12>;
-def bitfield CC2 <18>;
+def bitfield BPCC <21:20>; // for BPcc & FBPcc
+def bitfield FCMPCC <26:56>; // for FCMP & FCMPEa
+def bitfield FMOVCC <13:11>; // for FMOVcc
+def bitfield CC <12:11>; // for MOVcc & Tcc
+def bitfield MOVCC3 <18>; // also for MOVcc
def bitfield CMASK <6:4>;
def bitfield COND2 <28:25>;
def bitfield COND4 <17:14>;
@@ -46,5 +44,5 @@ def bitfield SHCNT64 <5:0>;
def bitfield SIMM10 <9:0>;
def bitfield SIMM11 <10:0>;
def bitfield SIMM13 <12:0>;
-def bitfield SW_TRAP <6:0>;
+def bitfield SW_TRAP <7:0>;
def bitfield X <12>;
diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa
index eb458211b..a1bbf8984 100644
--- a/arch/sparc/isa/decoder.isa
+++ b/arch/sparc/isa/decoder.isa
@@ -3,660 +3,538 @@
// The actual decoder specification
//
-decode OP default Trap::unknown({{IllegalInstruction}}) {
-
- 0x0: decode OP2 {
- 0x0: Trap::illtrap({{illegal_instruction}}); //ILLTRAP
- 0x1: Branch::bpcc({{
- switch((CC12 << 1) | CC02)
- {
- case 1:
- case 3:
- fault = new IllegalInstruction;
- case 0:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2))
+decode OP default Unknown::unknown()
+{
+ 0x0: decode OP2
+ {
+ format Branch
+ {
+ //Throw an illegal instruction acception
+ 0x0: Trap::illtrap({{fault = new IllegalInstruction;}});
+ 0x1: decode BPCC
+ {
+ 0x0: bpcci({{
+ if(passesCondition(CcrIcc, COND2))
;//branchHere
- break;
- case 2:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2))
+ }});
+ 0x2: bpccx({{
+ if(passesCondition(CcrXcc, COND2))
;//branchHere
- break;
- }
- }});//BPcc
- 0x2: Branch::bicc({{
- if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2))
+ }});
+ }
+ 0x2: bicc({{
+ if(passesCondition(CcrIcc, COND2))
;//branchHere
- }});//Bicc
- 0x3: Branch::bpr({{
- switch(RCOND)
- {
- case 0:
- case 4:
- fault = new IllegalInstruction;
- case 1:
+ }});
+ 0x3: decode RCOND2
+ {
+ 0x1: bpreq({{
if(Rs1 == 0)
;//branchHere
- break;
- case 2:
+ }});
+ 0x2: bprle({{
if(Rs1 <= 0)
;//branchHere
- break;
- case 3:
+ }});
+ 0x3: bprl({{
if(Rs1 < 0)
;//branchHere
- break;
- case 5:
+ }});
+ 0x5: bprne({{
if(Rs1 != 0)
;//branchHere
- break;
- case 6:
+ }});
+ 0x6: bprg({{
if(Rs1 > 0)
;//branchHere
- break;
- case 7:
+ }});
+ 0x7: bprge({{
if(Rs1 >= 0)
;//branchHere
- break;
+ }});
+ }
+ //SETHI (or NOP if rd == 0 and imm == 0)
+ 0x4: IntOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}});
+ 0x5: Trap::fbpfcc({{fault = new FpDisabled;}});
+ 0x6: Trap::fbfcc({{fault = new FpDisabled;}});
+ }
+ }
+ 0x1: Branch::call({{
+ //branch here
+ Rd = xc->readPC();
+ }});
+ 0x2: decode OP3 {
+ format IntOp {
+ 0x00: add({{Rd = Rs1.sdw + Rs2_or_imm13;}});
+ 0x01: and({{Rd = Rs1.udw & Rs2_or_imm13;}});
+ 0x02: or({{Rd = Rs1.udw | Rs2_or_imm13;}});
+ 0x03: xor({{Rd = Rs1.udw ^ Rs2_or_imm13;}});
+ 0x04: sub({{Rd = Rs1.sdw + (~Rs2_or_imm)+1;}});
+ 0x05: andn({{Rd = Rs1.udw & ~Rs2_or_imm;}});
+ 0x06: orn({{Rd = Rs1.udw | ~Rs2_or_imm;}});
+ 0x07: xnor({{Rd = ~(Rs1.udw ^ Rs2_or_imm);}});
+ 0x08: addc({{Rd = Rs1.sdw + Rs2_or_imm + CcrIccC;}});
+ 0x09: mulx({{Rd = Rs1 * Rs2_or_imm;}});
+ 0x0A: umul({{
+ Rd = Rs1.udw<31:0> * Rs2_or_imm<31:0>;
+ YValue = Rd<63:32>;
+ }});
+ 0x0B: smul({{
+ Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm<31:0>;
+ YValue = Rd.sdw;
+ }});
+ 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm) + 1 + CcrIccC;}});
+ 0x0D: udivx({{
+ if(val2 == 0) fault = new DivisionByZero;
+ else Rd.udw = Rs1.udw / Rs2_or_imm;
+ }});
+ 0x0E: udiv({{
+ uint32_t resTemp, val2 = (I ? SIMM13 : Rs2.udw<31:0>);
+ if(Rs2_or_imm.udw == 0) fault = new DivisionByZero;
+ else
+ {
+ Rd.udw = ((YValue << 32) | Rs1.udw<31:0>) / Rs2_or_imm.udw;
+ if(Rd.udw >> 32 != 0)
+ Rd.udw = 0xFFFFFFFF;
+ }
+ }});
+ 0x0F: sdiv({{
+ if(val2 == 0)
+ fault = new DivisionByZero;
+ else
+ {
+ Rd.udw = ((YValue << 32) | Rs1.sdw<31:0>) / Rs2_or_imm;
+ if(Rd.udw<63:31> != 0)
+ Rd.udw = 0x7FFFFFFF;
+ else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF)
+ Rd.udw = 0xFFFFFFFF80000000;
}
- }}); //BPr
- //SETHI (or NOP if rd == 0 and imm == 0)
- 0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}});
- 0x5: Trap::fbpfcc({{throw fp_disabled;}}); //FBPfcc
- 0x6: Trap::fbfcc({{throw fp_disabled;}}); //FBfcc
+ }});//SDIV
}
- 0x1: Branch::call({{
- //branch here
- Rd = xc->pc;
- }});
- 0x2: decode OP3 {
- format IntegerOp {
- 0x00: add({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- Rd = Rs1.sdw + val2;
- }});//ADD
- 0x01: and({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw & val2;
- }});//AND
- 0x02: or({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw | val2;
- }});//OR
- 0x03: xor({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw ^ val2;
- }});//XOR
- 0x04: sub({{
- int64_t val2 = ~((uint64_t)(I ? SIMM13.sdw : Rs2.udw))+1;
- Rd = Rs1.sdw + val2;
- }});//SUB
- 0x05: andn({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw & ~val2;
- }});//ANDN
- 0x06: orn({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw | ~val2;
- }});//ORN
- 0x07: xnor({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = ~(Rs1.udw ^ val2);
- }});//XNOR
- 0x08: addc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
- Rd = Rs1.sdw + val2 + carryin;
- }});//ADDC
- 0x09: mulx({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 * val2;
- }});//MULX
- 0x0A: umul({{
- uint64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = resTemp = Rs1.udw<31:0> * val2<31:0>;
- xc->regs.MiscRegs.yFields.value = resTemp<63:32>;
- }});//UMUL
- 0x0B: smul({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw);
- rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>;
- xc->regs.MiscRegs.yFields.value = resTemp<63:32>;
- }});//SMUL
- 0x0C: subc({{
- int64_t val2 = ~((int64_t)(I ? SIMM13.sdw : Rs2.sdw))+1;
- int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
- Rd.sdw = Rs1.sdw + val2 + carryin;
- }});//SUBC
- 0x0D: udivx({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- if(val2 == 0) throw division_by_zero;
- Rd.udw = Rs1.udw / val2;
- }});//UDIVX
- 0x0E: udiv({{
- uint32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>);
- if(val2 == 0)
- fault = new DivisionByZero;
- resTemp = (uint64_t)((xc->regs.MiscRegs.yFields.value << 32)
- | Rs1.udw<31:0>) / val2;
+ format IntOpCc {
+ 0x10: addcc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//ADDcc
+ 0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}});
+ 0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}});
+ 0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}});
+ 0x14: subcc({{
+ int64_t resTemp, val2 = (int64_t)(I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 - val2;}},
+ {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}},
+ {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
+ {{((Rs1 >> 1) + (~val2) >> 1) +
+ ((Rs1 | ~val2) & 0x1))<63:>}},
+ {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
+ );//SUBcc
+ 0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}});
+ 0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}});
+ 0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}});
+ 0x18: addccc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ int64_t carryin = CcrIccC;
+ Rd = resTemp = Rs1 + val2 + carryin;}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31
+ + carryin)}},
+ {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
+ {{((Rs1 >> 1) + (val2 >> 1) +
+ ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//ADDCcc
+ 0x1A: umulcc({{
+ uint64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1.udw<31:0> * val2<31:0>;
+ YValue = resTemp<63:32>;}},
+ {{0}},{{0}},{{0}},{{0}});//UMULcc
+ 0x1B: smulcc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>;
+ YValue = resTemp<63:32>;}}
+ ,{{0}},{{0}},{{0}},{{0}});//SMULcc
+ 0x1C: subccc({{
+ int64_t resTemp, val2 = (int64_t)(I ? SIMM13 : Rs2);
+ int64_t carryin = CcrIccC;
+ Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
+ {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}},
+ {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
+ {{((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}},
+ {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
+ );//SUBCcc
+ 0x1D: udivxcc({{
+ uint64_t val2 = (I ? SIMM13 : Rs2.udw);
+ if(val2 == 0) fault = new DivisionByZero;
+ else Rd.udw = Rs1.udw / val2;}}
+ ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc
+ 0x1E: udivcc({{
+ uint32_t resTemp, val2 = (I ? SIMM13 : Rs2.udw<31:0>);
+ if(val2 == 0) fault = new DivisionByZero;
+ else
+ {
+ resTemp = (uint64_t)((YValue << 32) | Rs1.udw<31:0>) / val2;
int32_t overflow = (resTemp<63:32> != 0);
- if(overflow)
- rd.udw = resTemp = 0xFFFFFFFF;
- else
- rd.udw = resTemp;
- }}); //UDIV
- 0x0F: sdiv({{
- int32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>);
- if(val2 == 0)
- fault = new DivisionByZero;
-
- Rd.sdw = (int64_t)((xc->regs.MiscRegs.yFields.value << 32) |
- Rs1.sdw<31:0>) / val2;
- resTemp = Rd.sdw;
+ if(overflow) rd.udw = resTemp = 0xFFFFFFFF;
+ else rd.udw = resTemp;
+ } }},
+ {{0}},
+ {{overflow}},
+ {{0}},
+ {{0}}
+ );//UDIVcc
+ 0x1F: sdivcc({{
+ int32_t resTemp, val2 = (I ? SIMM13 : Rs2.sdw<31:0>);
+ if(val2 == 0) fault = new DivisionByZero;
+ else
+ {
+ Rd.sdw = resTemp = (int64_t)((YValue << 32) | Rs1.sdw<31:0>) / val2;
int32_t overflow = (resTemp<63:31> != 0);
- int32_t underflow =
- (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
- if(overflow)
- rd.udw = resTemp = 0x7FFFFFFF;
- else if(underflow)
- rd.udw = resTemp = 0xFFFFFFFF80000000;
- else
- rd.udw = resTemp;
- }});//SDIV
+ int32_t underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
+ if(overflow) rd.udw = resTemp = 0x7FFFFFFF;
+ else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000;
+ else rd.udw = resTemp;
+ } }},
+ {{0}},
+ {{overflow || underflow}},
+ {{0}},
+ {{0}}
+ );//SDIVcc
+ 0x20: taddcc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{overflow}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//TADDcc
+ 0x21: tsubcc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
+ {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{overflow}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//TSUBcc
+ 0x22: taddcctv({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
+ if(overflow) fault = new TagOverflow;}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{overflow}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//TADDccTV
+ 0x23: tsubcctv({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
+ if(overflow) fault = new TagOverflow;}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{overflow}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//TSUBccTV
+ 0x24: mulscc({{
+ int64_t resTemp, multiplicand = (I ? SIMM13 : Rs2);
+ int32_t multiplier = Rs1<31:0>;
+ int32_t savedLSB = Rs1<0:>;
+ multiplier = multipler<31:1> |
+ ((CcrIccN
+ ^ CcrIccV) << 32);
+ if(!YValue<0:>)
+ multiplicand = 0;
+ Rd = resTemp = multiplicand + multiplier;
+ YValue = YValue<31:1> | (savedLSB << 31);}},
+ {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}},
+ {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}},
+ {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}},
+ {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}}
+ );//MULScc
}
- format IntegerOpCc {
- 0x10: addcc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//ADDcc
- 0x11: andcc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 & val2;}},
- {{0}},{{0}},{{0}},{{0}});//ANDcc
- 0x12: orcc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 | val2;}},
- {{0}},{{0}},{{0}},{{0}});//ORcc
- 0x13: xorcc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 ^ val2;}},
- {{0}},{{0}},{{0}},{{0}});//XORcc
- 0x14: subcc({{
- int64_t resTemp, val2 = (int64_t)(I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 - val2;}},
- {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}},
- {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (~val2) >> 1) +
- ((Rs1 | ~val2) & 0x1))<63:>}},
- {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
- );//SUBcc
- 0x15: andncc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 & ~val2;}},
- {{0}},{{0}},{{0}},{{0}});//ANDNcc
- 0x16: orncc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 | ~val2;}},
- {{0}},{{0}},{{0}},{{0}});//ORNcc
- 0x17: xnorcc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = ~(Rs1 ^ val2);}},
- {{0}},{{0}},{{0}},{{0}});//XNORcc
- 0x18: addccc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
- Rd = resTemp = Rs1 + val2 + carryin;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31
- + carryin)}},
- {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (val2 >> 1) +
- ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//ADDCcc
- 0x1A: umulcc({{
- uint64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1.udw<31:0> * val2<31:0>;
- xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}},
- {{0}},{{0}},{{0}},{{0}});//UMULcc
- 0x1B: smulcc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>;
- xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}}
- ,{{0}},{{0}},{{0}},{{0}});//SMULcc
- 0x1C: subccc({{
- int64_t resTemp, val2 = (int64_t)(I ? SIMM13.sdw : Rs2);
- int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
- Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
- {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}},
- {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}},
- {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
- );//SUBCcc
- 0x1D: udivxcc({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- if(val2 == 0) throw division_by_zero;
- Rd.udw = Rs1.udw / val2;}}
- ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc
- 0x1E: udivcc({{
- uint32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>);
- if(val2 == 0) throw division_by_zero;
- resTemp = (uint64_t)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2;
- int32_t overflow = (resTemp<63:32> != 0);
- if(overflow) rd.udw = resTemp = 0xFFFFFFFF;
- else rd.udw = resTemp;}},
- {{0}},
- {{overflow}},
- {{0}},
- {{0}}
- );//UDIVcc
- 0x1F: sdivcc({{
- int32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>);
- if(val2 == 0) throw division_by_zero;
- Rd.sdw = resTemp = (int64_t)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2;
- int32_t overflow = (resTemp<63:31> != 0);
- int32_t underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
- if(overflow) rd.udw = resTemp = 0x7FFFFFFF;
- else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000;
- else rd.udw = resTemp;}},
- {{0}},
- {{overflow || underflow}},
- {{0}},
- {{0}}
- );//SDIVcc
- 0x20: taddcc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{overflow}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//TADDcc
- 0x21: tsubcc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
- {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{overflow}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//TSUBcc
- 0x22: taddcctv({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
- if(overflow) throw tag_overflow;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{overflow}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//TADDccTV
- 0x23: tsubcctv({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
- if(overflow) throw tag_overflow;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{overflow}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//TSUBccTV
- 0x24: mulscc({{
- int64_t resTemp, multiplicand = (I ? SIMM13.sdw : Rs2);
- int32_t multiplier = Rs1<31:0>;
- int32_t savedLSB = Rs1<0:>;
- multiplier = multipler<31:1> |
- ((xc->regs.MiscRegs.ccrFields.iccFields.n
- ^ xc->regs.MiscRegs.ccrFields.iccFields.v) << 32);
- if(!xc->regs.MiscRegs.yFields.value<0:>)
- multiplicand = 0;
- Rd = resTemp = multiplicand + multiplier;
- xc->regs.MiscRegs.yFields.value = xc->regs.MiscRegs.yFields.value<31:1> | (savedLSB << 31);}},
- {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}},
- {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}},
- {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}},
- {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}}
- );//MULScc
+ format IntOp
+ {
+ 0x25: decode X {
+ 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}});
+ 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}});
+ }
+ 0x26: decode X {
+ 0x0: srl({{Rd = Rs1.uw >> (I ? SHCNT32 : Rs2<4:0>);}});
+ 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}});
}
- format IntegerOp
+ 0x27: decode X {
+ 0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRA
+ 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRAX
+ }
+ 0x28: decode RS1 {
+ 0x0: rdy({{Rd = YValue;}}); //RDY
+ 0x2: rdccr({{Rd = Ccr;}}); //RDCCR
+ 0x3: rdasi({{Rd = Asi;}}); //RDASI
+ 0x4: PrivTick::rdtick({{Rd = Tick;}});
+ 0x5: rdpc({{Rd = xc->regs.pc;}}); //RDPC
+ 0x6: rdfprs({{Rd = Fprs;}}); //RDFPRS
+ 0xF: decode I {
+ 0x0: Noop::membar({{//Membar isn't needed yet}});
+ 0x1: Noop::stbar({{//Stbar isn't needed yet}});
+ }
+ }
+ 0x2A: decode RS1 {
+ format Priv
+ {
+ 0x0: rdprtpc({{
+ Rd = xc->readMiscReg(MISCREG_TPC_BASE + Tl);
+ }});
+ 0x1: rdprtnpc({{
+ Rd = xc->readMiscReg(MISCREG_TNPC_BASE + Tl);
+ }});
+ 0x2: rdprtstate({{
+ Rd = xc->readMiscReg(MISCREG_TSTATE_BASE + Tl);
+ }});
+ 0x3: rdprtt({{
+ Rd = xc->readMiscReg(MISCREG_TT_BASE + Tl);
+ }});
+ 0x4: rdprtick({{Rd = Tick;}});
+ 0x5: rdprtba({{Rd = Tba;}});
+ 0x6: rdprpstate({{Rd = Pstate;}});
+ 0x7: rdprtl({{Rd = Tl;}});
+ 0x8: rdprpil({{Rd = Pil;}});
+ 0x9: rdprcwp({{Rd = Cwp;}});
+ 0xA: rdprcansave({{Rd = Cansave;}});
+ 0xB: rdprcanrestore({{Rd = CanRestore;}});
+ 0xC: rdprcleanwin({{Rd = Cleanwin;}});
+ 0xD: rdprotherwin({{Rd = Otherwin;}});
+ 0xE: rdprwstate({{Rd = Wstate;}});
+ }
+ //The floating point queue isn't implemented right now.
+ 0xF: Trap::rdprfq({{fault = IllegalInstruction;}});
+ 0x1F: Priv::rdprver({{Rd = Ver;}});
+ }
+ 0x2B: BasicOperate::flushw({{//window toilet}}); //FLUSHW
+ 0x2C: decode MOVCC3
{
- 0x25: decode X {
- 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}}); //SLL
- 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}}); //SLLX
- }
- 0x26: decode X {
- 0x0: srl({{Rd = Rs1.udw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRL
- 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRLX
- }
- 0x27: decode X {
- 0x0: sra({{Rd = Rs1.sdw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRA
- 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRAX
- }
- 0x28: decode RS1 {
- 0x0: rdy({{Rd = xc->regs.MiscRegs.yFields.value;}}); //RDY
- 0x2: rdccr({{Rd = xc->regs.MiscRegs.ccr;}}); //RDCCR
- 0x3: rdasi({{Rd = xc->regs.MiscRegs.asi;}}); //RDASI
- 0x4: rdtick({{
- if(xc->regs.MiscRegs.pstateFields.priv == 0 &&
- xc->regs.MiscRegs.tickFields.npt == 1)
- throw privileged_action;
- Rd = xc->regs.MiscRegs.tick;
- }});//RDTICK
- 0x5: rdpc({{Rd = xc->regs.pc;}}); //RDPC
- 0x6: rdfprs({{Rd = xc->regs.MiscRegs.fprs;}}); //RDFPRS
- 0xF: decode I {
- 0x0: Noop::membar({{//Membar isn't needed yet}}); //MEMBAR
- 0x1: Noop::stbar({{//Stbar isn/'t needed yet}}); //STBAR
- }
- }
-
- 0x2A: decode RS1 {
- 0x0: rdprtpc({{checkPriv Rd = xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl];}});
- 0x1: rdprtnpc({{checkPriv Rd = xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl];}});
- 0x2: rdprtstate({{checkPriv Rd = xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl];}});
- 0x3: rdprtt({{checkPriv Rd = xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl];}});
- 0x4: rdprtick({{checkPriv Rd = xc->regs.MiscRegs.tick;}});
- 0x5: rdprtba({{checkPriv Rd = xc->regs.MiscRegs.tba;}});
- 0x6: rdprpstate({{checkPriv Rd = xc->regs.MiscRegs.pstate;}});
- 0x7: rdprtl({{checkPriv Rd = xc->regs.MiscRegs.tl;}});
- 0x8: rdprpil({{checkPriv Rd = xc->regs.MiscRegs.pil;}});
- 0x9: rdprcwp({{checkPriv Rd = xc->regs.MiscRegs.cwp;}});
- 0xA: rdprcansave({{checkPriv Rd = xc->regs.MiscRegs.cansave;}});
- 0xB: rdprcanrestore({{checkPriv Rd = xc->regs.MiscRegs.canrestore;}});
- 0xC: rdprcleanwin({{checkPriv Rd = xc->regs.MiscRegs.cleanwin;}});
- 0xD: rdprotherwin({{checkPriv Rd = xc->regs.MiscRegs.otherwin;}});
- 0xE: rdprwstate({{checkPriv Rd = xc->regs.MiscRegs.wstate;}});
- 0xF: rdprfq({{throw illegal_instruction;}}); //The floating point queue isn't implemented right now.
- }
- 0x2B: BasicOperate::flushw({{\\window toilet}}); //FLUSHW
- 0x2C: movcc({{
- ccBank = (CC24 << 2) | (CC14 << 1) | (CC04 << 0);
- switch(ccBank)
- {
- case 0: case 1: case 2: case 3:
- throw fp_disabled;
- break;
- case 5: case 7:
- throw illegal_instruction;
- break;
- case 4:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND4))
- Rd = (I ? SIMM11.sdw : RS2);
- break;
- case 6:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND4))
- Rd = (I ? SIMM11.sdw : RS2);
- break;
- }
- }});//MOVcc
- 0x2D: sdivx({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- if(val2 == 0) throw division_by_zero;
- Rd.sdw = Rs1.sdw / val2;
- }});//SDIVX
- 0x2E: decode RS1 {
- 0x0: IntegerOp::popc({{
- int64_t count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw);
- uint8_t oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}
- for(unsigned int x = 0; x < 16; x++)
- {
- count += oneBits[val2 & 0xF];
- val2 >> 4;
- }
- }});//POPC
- }
- 0x2F: movr({{
- uint64_t val2 = (I ? SIMM10.sdw : Rs2.sdw);
- switch(RCOND)
- {
- case 0: case 4:
- throw illegal_instruction;
- break;
- case 1:
- if(Rs1 == 0) Rd = val2;
- break;
- case 2:
- if(Rs1 <= 0) Rd = val2;
- break;
- case 3:
- if(Rs1 = 0) Rd = val2;
- break;
- case 5:
- if(Rs1 != 0) Rd = val2;
- break;
- case 6:
- if(Rs1 > 0) Rd = val2;
- break;
- case 7:
- if(Rs1 >= 0) Rd = val2;
- break;
- }
- }});//MOVR
- 0x30: decode RD {
- 0x0: wry({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.y = Rs1 ^ val2;
- }});//WRY
- 0x2: wrccr({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.ccr = Rs1 ^ val2;
- }});//WRCCR
- 0x3: wrasi({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.asi = Rs1 ^ val2;
- }});//WRASI
- 0x6: wrfprs({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.asi = Rs1 ^ val2;
- }});//WRFPRS
- 0xF: Trap::sir({{software_initiated_reset}}); //SIR
- }
- 0x31: decode FCN {
- 0x0: BasicOperate::saved({{\\Boogy Boogy}}); //SAVED
- 0x1: BasicOperate::restored({{\\Boogy Boogy}}); //RESTORED
- }
- 0x32: decode RD {
- 0x0: wrprtpc({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
- }});
- 0x1: wrprtnpc({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
- }});
- 0x2: wrprtstate({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
- }});
- 0x3: wrprtt({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
- }});
- 0x4: wrprtick({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tick = Rs1 ^ val2;
- }});
- 0x5: wrprtba({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tba = Rs1 ^ val2;
- }});
- 0x6: wrprpstate({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.pstate = Rs1 ^ val2;
- }});
- 0x7: wrprtl({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tl = Rs1 ^ val2;
- }});
- 0x8: wrprpil({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.pil = Rs1 ^ val2;
- }});
- 0x9: wrprcwp({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.cwp = Rs1 ^ val2;
- }});
- 0xA: wrprcansave({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.cansave = Rs1 ^ val2;
- }});
- 0xB: wrprcanrestore({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.canrestore = Rs1 ^ val2;
- }});
- 0xC: wrprcleanwin({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.cleanwin = Rs1 ^ val2;
- }});
- 0xD: wrprotherwin({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.otherwin = Rs1 ^ val2;
- }});
- 0xE: wrprwstate({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.wstate = Rs1 ^ val2;
- }});
- }
-
- 0x34: Trap::fpop1({{Throw fp_disabled;}}); //FPOP1
- 0x35: Trap::fpop2({{Throw fp_disabled;}}); //FPOP2
-
-
- 0x38: Branch::jmpl({{//Stuff}}); //JMPL
- 0x39: Branch::return({{//Other Stuff}}); //RETURN
- 0x3A: Trap::tcc({{
- switch((CC14 << 1) | (CC04 << 0))
- {
- case 1: case 3:
- throw illegal_instruction;
- case 0:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, machInst<25:28>))
- throw trap_instruction;
- break;
- case 2:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, machInst<25:28>))
- throw trap_instruction;
- break;
- }
- }}); //Tcc
- 0x3B: BasicOperate::flush({{//Lala}}); //FLUSH
- 0x3C: BasicOperate::save({{//leprechauns); //SAVE
- 0x3D: BasicOperate::restore({{//Eat my short int}}); //RESTORE
- 0x3E: decode FCN {
- 0x1: BasicOperate::done({{//Done thing}}); //DONE
- 0x2: BasicOperate::retry({{//Retry thing}}); //RETRY
- }
+ 0x0: Trap::movccfcc({{fault = new FpDisabled}});
+ 0x1: decode CC
+ {
+ 0x0: movcci({{
+ if(passesCondition(CcrIcc, COND4))
+ Rd = (I ? SIMM11 : RS2);
+ }});
+ 0x2: movccx({{
+ if(passesCondition(CcrXcc, COND4))
+ Rd = (I ? SIMM11 : RS2);
+ }});
+ }
}
- }
- 0x3: decode OP3 {
- format Mem {
- 0x00: lduw({{Rd.uw = Mem.uw;}}); //LDUW
- 0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB
- 0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH
- 0x03: ldd({{
- uint64_t val = Mem.udw;
- setIntReg(RD & (~1), val<31:0>);
- setIntReg(RD | 1, val<63:32>);
- }});//LDD
- 0x04: stw({{Mem.sw = Rd.sw;}}); //STW
- 0x05: stb({{Mem.sb = Rd.sb;}}); //STB
- 0x06: sth({{Mem.shw = Rd.shw;}}); //STH
- 0x07: std({{
- Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
- }});//STD
- 0x08: ldsw({{Rd.sw = Mem.sw;}}); //LDSW
- 0x09: ldsb({{Rd.sb = Mem.sb;}}); //LDSB
- 0x0A: ldsh({{Rd.shw = Mem.shw;}}); //LDSH
- 0x0B: ldx({{Rd.udw = Mem.udw;}}); //LDX
-
- 0x0D: ldstub({{
- Rd.ub = Mem.ub;
- Mem.ub = 0xFF;
- }}); //LDSTUB
- 0x0E: stx({{Rd.udw = Mem.udw;}}); //STX
- 0x0F: swap({{
- uint32_t temp = Rd.uw;
- Rd.uw = Mem.uw;
- Mem.uw = temp;
- }}); //SWAP
- 0x10: lduwa({{Rd.uw = Mem.uw;}}); //LDUWA
- 0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA
- 0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA
- 0x13: ldda({{
- uint64_t val = Mem.udw;
- setIntReg(RD & (~1), val<31:0>);
- setIntReg(RD | 1, val<63:32>);
- }}); //LDDA
- 0x14: stwa({{Mem.uw = Rd.uw;}}); //STWA
- 0x15: stba({{Mem.ub = Rd.ub;}}); //STBA
- 0x16: stha({{Mem.uhw = Rd.uhw;}}); //STHA
- 0x17: stda({{
- Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
- }}); //STDA
- 0x18: ldswa({{Rd.sw = Mem.sw;}}); //LDSWA
- 0x19: ldsba({{Rd.sb = Mem.sb;}}); //LDSBA
- 0x1A: ldsha({{Rd.shw = Mem.shw;}}); //LDSHA
- 0x1B: ldxa({{Rd.sdw = Mem.sdw;}}); //LDXA
-
- 0x1D: ldstuba({{
- Rd.ub = Mem.ub;
- Mem.ub = 0xFF;
- }}); //LDSTUBA
- 0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA
- 0x1F: swapa({{
- uint32_t temp = Rd.uw;
- Rd.uw = Mem.uw;
- Mem.uw = temp;
- }}); //SWAPA
- 0x20: Trap::ldf({{throw fp_disabled;}}); //LDF
- 0x21: decode X {
- 0x0: Trap::ldfsr({{throw fp_disabled;}}); //LDFSR
- 0x1: Trap::ldxfsr({{throw fp_disabled;}}); //LDXFSR
+ 0x2D: sdivx({{
+ if(Rs2_or_imm13 == 0) fault = new DivisionByZero;
+ else Rd.sdw = Rs1.sdw / Rs2_or_imm13;
+ }});//SDIVX
+ 0x2E: decode RS1 {
+ 0x0: IntOp::popc({{
+ int64_t count = 0, val2 = Rs2_or_imm;
+ uint8_t oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
+ for(unsigned int x = 0; x < 16; x++)
+ {
+ count += oneBits[Rs2_or_imm13 & 0xF];
+ val2 >> 4;
}
- 0x22: Trap::ldqf({{throw fp_disabled;}}); //LDQF
- 0x23: Trap::lddf({{throw fp_disabled;}}); //LDDF
- 0x24: Trap::stf({{throw fp_disabled;}}); //STF
- 0x25: decode X {
- 0x0: Trap::stfsr({{throw fp_disabled;}}); //STFSR
- 0x1: Trap::stxfsr({{throw fp_disabled;}}); //STXFSR
- }
- 0x26: Trap::stqf({{throw fp_disabled;}}); //STQF
- 0x27: Trap::stdf({{throw fp_disabled;}}); //STDF
-
-
-
-
-
- 0x2D: Noop::prefetch({{ }}); //PREFETCH
+ }});//POPC
+ }
+ 0x2F: decode RCOND3
+ {
+ 0x1: movreq({{if(Rs1 == 0) Rd = Rs2_or_imm10;}});
+ 0x2: movrle({{if(Rs1 <= 0) Rd = Rs2_or_imm10;}});
+ 0x3: movrl({{if(Rs1 < 0) Rd = Rs2_or_imm10;}});
+ 0x5: movrne({{if(Rs1 != 0) Rd = Rs2_or_imm10;}});
+ 0x6: movrg({{if(Rs1 > 0) Rd = Rs2_or_imm10;}});
+ 0x7: movrge({{if(Rs1 >= 0) Rd = Rs2_or_imm10;}});
+ }
+ 0x30: decode RD {
+ 0x0: wry({{Y = Rs1 ^ Rs2_or_imm13;}});
+ 0x2: wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}});
+ 0x3: wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}});
+ 0x6: wrfprs({{Asi = Rs1 ^ Rs2_or_imm13;}});
+ 0xF: Trap::sir({{fault = new SoftwareInitiatedReset;}});
+ }
+ 0x31: decode FCN {
+ 0x0: BasicOperate::saved({{//Boogy Boogy}}); //SAVED
+ 0x1: BasicOperate::restored({{//Boogy Boogy}}); //RESTORED
+ }
+ 0x32: decode RD {
+ format Priv
+ {
+ 0x0: wrprtpc({{
+ xc->setMiscReg(MISCREG_TPC_BASE + Tl,
+ Rs1 ^ Rs2_or_imm13);
+ }});
+ 0x1: wrprtnpc({{
+ xc->setMiscReg(MISCREG_TNPC_BASE + Tl,
+ Rs1 ^ Rs2_or_imm13);
+ }});
+ 0x2: wrprtstate({{
+ xc->setMiscReg(MISCREG_TSTATE_BASE + Tl,
+ Rs1 ^ Rs2_or_imm13);
+ }});
+ 0x3: wrprtt({{
+ xc->setMiscReg(MISCREG_TT_BASE + Tl,
+ Rs1 ^ Rs2_or_imm13);
+ }});
+ 0x4: wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}});
+ 0x5: wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}});
+ 0x6: wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}});
+ 0x7: wrprtl({{Tl = Rs1 ^ Rs2_or_imm13;}});
+ 0x8: wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}});
+ 0x9: wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}});
+ 0xA: wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}});
+ 0xB: wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}});
+ 0xC: wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}});
+ 0xD: wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}});
+ 0xE: wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}});
+ }
+ }
+ 0x34: Trap::fpop1({{fault = new FpDisabled;}});
+ 0x35: Trap::fpop2({{fault = new FpDisabled;}});
- 0x30: Trap::ldfa({{throw fp_disabled;}}); //LDFA
+ 0x38: Branch::jmpl({{//Stuff}}); //JMPL
+ 0x39: Branch::return({{//Other Stuff}}); //RETURN
+ 0x3A: decode CC
+ {
+ 0x0: Trap::tcci({{
+#if FULL_SYSTEM
+ fault = new TrapInstruction;
+#else
+ if(passesCondition(CcrIcc, machInst<25:28>))
+ // At least glibc only uses trap 0,
+ // solaris/sunos may use others
+ assert((I ? Rs1 + Rs2 : Rs1 + SW_TRAP) == 0);
+ xc->syscall();
+#endif
+ }});
+ 0x2: Trap::tccx({{
+#if FULL_SYSTEM
+ fault = new TrapInstruction;
+#else
+ if(passesCondition(CcrXcc, machInst<25:28>))
+ // At least glibc only uses trap 0,
+ // solaris/sunos may use others
+ assert((I ? Rs1 + Rs2 : Rs1 + SW_TRAP) == 0);
+ xc->syscall();
+#endif
+ }});
+ }
+ 0x3B: BasicOperate::flush({{//Lala}}); //FLUSH
+ 0x3C: BasicOperate::save({{//leprechauns); //SAVE
+ 0x3D: BasicOperate::restore({{//Eat my short int}}); //RESTORE
+ 0x3E: decode FCN {
+ 0x1: BasicOperate::done({{//Done thing}}); //DONE
+ 0x2: BasicOperate::retry({{//Retry thing}}); //RETRY
+ }
+ }
+ }
+ 0x3: decode OP3 {
+ format Mem {
+ 0x00: lduw({{Rd.uw = Mem.uw;}}); //LDUW
+ 0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB
+ 0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH
+ 0x03: ldd({{
+ uint64_t val = Mem.udw;
+ setIntReg(RD & (~1), val<31:0>);
+ setIntReg(RD | 1, val<63:32>);
+ }});//LDD
+ 0x04: stw({{Mem.sw = Rd.sw;}}); //STW
+ 0x05: stb({{Mem.sb = Rd.sb;}}); //STB
+ 0x06: sth({{Mem.shw = Rd.shw;}}); //STH
+ 0x07: std({{
+ Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
+ }});//STD
+ 0x08: ldsw({{Rd.sw = Mem.sw;}}); //LDSW
+ 0x09: ldsb({{Rd.sb = Mem.sb;}}); //LDSB
+ 0x0A: ldsh({{Rd.shw = Mem.shw;}}); //LDSH
+ 0x0B: ldx({{Rd.udw = Mem.udw;}}); //LDX
- 0x32: Trap::ldqfa({{throw fp_disabled;}}); //LDQFA
- 0x33: Trap::lddfa({{throw fp_disabled;}}); //LDDFA
- 0x34: Trap::stfa({{throw fp_disabled;}}); //STFA
- 0x35: Trap::stqfa({{throw fp_disabled;}}); //STQFA
- 0x36: Trap::stdfa({{throw fp_disabled;}}); //STDFA
+ 0x0D: ldstub({{
+ Rd.ub = Mem.ub;
+ Mem.ub = 0xFF;
+ }}); //LDSTUB
+ 0x0E: stx({{Rd.udw = Mem.udw;}}); //STX
+ 0x0F: swap({{
+ uint32_t temp = Rd.uw;
+ Rd.uw = Mem.uw;
+ Mem.uw = temp;
+ }}); //SWAP
+ 0x10: lduwa({{Rd.uw = Mem.uw;}}); //LDUWA
+ 0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA
+ 0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA
+ 0x13: ldda({{
+ uint64_t val = Mem.udw;
+ setIntReg(RD & (~1), val<31:0>);
+ setIntReg(RD | 1, val<63:32>);
+ }}); //LDDA
+ 0x14: stwa({{Mem.uw = Rd.uw;}}); //STWA
+ 0x15: stba({{Mem.ub = Rd.ub;}}); //STBA
+ 0x16: stha({{Mem.uhw = Rd.uhw;}}); //STHA
+ 0x17: stda({{
+ Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
+ }}); //STDA
+ 0x18: ldswa({{Rd.sw = Mem.sw;}}); //LDSWA
+ 0x19: ldsba({{Rd.sb = Mem.sb;}}); //LDSBA
+ 0x1A: ldsha({{Rd.shw = Mem.shw;}}); //LDSHA
+ 0x1B: ldxa({{Rd.sdw = Mem.sdw;}}); //LDXA
+ 0x1D: ldstuba({{
+ Rd.ub = Mem.ub;
+ Mem.ub = 0xFF;
+ }}); //LDSTUBA
+ 0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA
+ 0x1F: swapa({{
+ uint32_t temp = Rd.uw;
+ Rd.uw = Mem.uw;
+ Mem.uw = temp;
+ }}); //SWAPA
+ 0x20: Trap::ldf({{fault = new FpDisabled;}});
+ 0x21: decode X {
+ 0x0: Trap::ldfsr({{fault = new FpDisabled;}});
+ 0x1: Trap::ldxfsr({{fault = new FpDisabled;}});
+ }
+ 0x22: Trap::ldqf({{fault = new FpDisabled;}});
+ 0x23: Trap::lddf({{fault = new FpDisabled;}});
+ 0x24: Trap::stf({{fault = new FpDisabled;}});
+ 0x25: decode X {
+ 0x0: Trap::stfsr({{fault = new FpDisabled;}});
+ 0x1: Trap::stxfsr({{fault = new FpDisabled;}});
+ }
+ 0x26: Trap::stqf({{fault = new FpDisabled;}});
+ 0x27: Trap::stdf({{fault = new FpDisabled;}});
+ 0x2D: Noop::prefetch({{ }}); //PREFETCH
+ 0x30: Trap::ldfa({{return new FpDisabled;}});
+ 0x32: Trap::ldqfa({{fault = new FpDisabled;}});
+ 0x33: Trap::lddfa({{fault = new FpDisabled;}});
+ 0x34: Trap::stfa({{fault = new FpDisabled;}});
+ 0x35: Trap::stqfa({{fault = new FpDisabled;}});
+ 0x36: Trap::stdfa({{fault = new FpDisabled;}});
- 0x3C: Cas::casa(
- {{uint64_t val = Mem.uw;
- if(Rs2.uw == val)
- Mem.uw = Rd.uw;
- Rd.uw = val;
- }}); //CASA
- 0x3D: Noop::prefetcha({{ }}); //PREFETCHA
- 0x3E: Cas::casxa(
- {{uint64_t val = Mem.udw;
- if(Rs2 == val)
- Mem.udw = Rd;
- Rd = val;
- }}); //CASXA
- }
- }
+ 0x3C: Cas::casa(
+ {{uint64_t val = Mem.uw;
+ if(Rs2.uw == val)
+ Mem.uw = Rd.uw;
+ Rd.uw = val;
+ }}); //CASA
+ 0x3D: Noop::prefetcha({{ }}); //PREFETCHA
+ 0x3E: Cas::casxa({{
+ uint64_t val = Mem.udw;
+ if(Rs2 == val)
+ Mem.udw = Rd;
+ Rd = val;
+ }}); //CASXA
+ }
+ }
}
diff --git a/arch/sparc/isa/formats.isa b/arch/sparc/isa/formats.isa
index 547f8be48..9310ba3d3 100644
--- a/arch/sparc/isa/formats.isa
+++ b/arch/sparc/isa/formats.isa
@@ -5,12 +5,21 @@
//Include the integerOp and integerOpCc format
##include "m5/arch/sparc/isa/formats/integerop.isa"
-//Include the mem format
+//Include the memory format
##include "m5/arch/sparc/isa/formats/mem.isa"
+//Include the compare and swap format
+##include "m5/arch/sparc/isa/formats/cas.isa"
+
//Include the trap format
##include "m5/arch/sparc/isa/formats/trap.isa"
+//Include the "unknown" format
+##include "m5/arch/sparc/isa/formats/unknown.isa"
+
+//Include the priveleged mode format
+##include "m5/arch/sparc/isa/formats/priv.isa"
+
//Include the branch format
##include "m5/arch/sparc/isa/formats/branch.isa"
diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa
index 80101de1b..b9dc960de 100644
--- a/arch/sparc/isa/formats/branch.isa
+++ b/arch/sparc/isa/formats/branch.isa
@@ -34,7 +34,6 @@ def template BranchExecute {{
{
//Attempt to execute the instruction
Fault fault = NoFault;
- checkPriv;
%(op_decl)s;
%(op_rd)s;
@@ -57,6 +56,6 @@ def format Branch(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
+ decode_block = BasicDecode.subst(iop)
exec_output = BranchExecute.subst(iop)
}};
diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa
index 5a9e09896..e7bd4c2a4 100644
--- a/arch/sparc/isa/formats/integerop.isa
+++ b/arch/sparc/isa/formats/integerop.isa
@@ -7,106 +7,159 @@ output header {{
/**
* Base class for integer operations.
*/
- class IntegerOp : public SparcStaticInst
+ class IntOp : public SparcStaticInst
{
protected:
// Constructor
- IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
+ const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for 10 bit immediate integer operations.
+ */
+ class IntOpImm10 : public IntOp
+ {
+ protected:
+ // Constructor
+ IntOpImm10(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
+ IntOp(mnem, _machInst, __opClass), imm(SIMM10)
+ {
+ }
+
+ uint32_t imm;
+ };
+
+ /**
+ * Base class for 13 bit immediate integer operations.
+ */
+ class IntOpImm13 : public IntOp
+ {
+ protected:
+ // Constructor
+ IntOpImm13(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
+ IntOp(mnem, _machInst, __opClass), imm(SIMM13)
+ {
+ }
+
+ uint32_t imm;
};
}};
output decoder {{
- std::string IntegerOp::generateDisassembly(Addr pc,
+ std::string IntOp::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
- return "Integer instruction\n";
+ return "Integer instruction\n";
}
}};
-def template IntegerExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+def template IntOpExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
{
- //These are set to constants when the execute method
- //is generated
- bool useCc = ;
- bool checkPriv = ;
-
- //Attempt to execute the instruction
- try
- {
- checkPriv;
-
- %(op_decl)s;
- %(op_rd)s;
- %(code)s;
- }
- //If we have an exception for some reason,
- //deal with it
- catch(SparcException except)
- {
- //Deal with exception
- return No_Fault;
- }
-
- //Write the resulting state to the execution context
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ //Write the resulting state to the execution context
+ if(fault == NoFault)
%(op_wb)s;
- if(useCc)
- {
- xc->regs.miscRegFile.ccrFields.iccFields.n = Rd & (1 << 63);
- xc->regs.miscRegFile.ccrFields.iccFields.z = (Rd == 0);
- xc->regs.miscRegFile.ccrFields.iccFields.v = ivValue;
- xc->regs.miscRegFile.ccrFields.iccFields.c = icValue;
- xc->regs.miscRegFile.ccrFields.xccFields.n = Rd & (1 << 31);
- xc->regs.miscRegFile.ccrFields.xccFields.z = ((Rd & 0xFFFFFFFF) == 0);
- xc->regs.miscRegFile.ccrFields.xccFields.v = xvValue;
- xc->regs.miscRegFile.ccrFields.xccFields.c = xcValue;
- }
- return No_Fault;
+ return fault;
}
}};
-// Primary format for integer operate instructions:
-def format IntegerOp(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- checkPriv = (code.find('checkPriv') != -1)
- code.replace('checkPriv', '')
- if checkPriv:
- code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;')
- else:
- code.replace('checkPriv;', '')
- for (marker, value) in (('ivValue', '0'), ('icValue', '0'),
- ('xvValue', '0'), ('xcValue', '0')):
- code.replace(marker, value)
- iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
+def template IntOpCcExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ //Write the resulting state to the execution context
+ if(fault == NoFault)
+ {
+ %(op_wb)s;
+ CcrIccN = Rd & (1 << 63);
+ CcrIccZ = (Rd == 0);
+ CcrIccV = ivValue;
+ CcrIccC = icValue;
+ CcrXccN = Rd & (1 << 31);
+ CcrXccZ = ((Rd & 0xFFFFFFFF) == 0);
+ CcrXccV = xvValue;
+ CcrXccC = xcValue;
+ }
+ return fault;
+ }
+}};
+
+def template IntOpCcResExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ //Write the resulting state to the execution context
+ if(fault == NoFault)
+ {
+ %(op_wb)s;
+ CcrIccN = Rd & (1 << 63);
+ CcrIccZ = (Rd == 0);
+ CcrXccN = Rd & (1 << 31);
+ CcrXccZ = ((Rd & 0xFFFFFFFF) == 0);
+ CcrIccV = CcrIccC = CcrXccV = CcrXccC = 0;
+ }
+ return fault;
+ }
+}};
+
+let {{
+ def doIntFormat(code, execTemplate, name, Name, opt_flags):
+ (usesImm, cblk, immCblk, rString, iString) = splitOutImm(code)
+ iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = IntegerExecute.subst(iop)
+ exec_output = execTemplate.subst(iop)
+ if usesImm:
+ imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
+ immCblk, opt_flags)
+ header_output += BasicDeclare.subst(imm_iop)
+ decoder_output += BasicConstructor.subst(imm_iop)
+ exec_output += execTemplate.subst(imm_iop)
+ decode_block = ROrImmDecode.subst(iop)
+ else:
+ decode_block = BasicDecode.subst(iop)
}};
// Primary format for integer operate instructions:
-def format IntegerOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- checkPriv = (code.find('checkPriv') != -1)
- code.replace('checkPriv', '')
- if checkPriv:
- code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;')
- else:
- code.replace('checkPriv;', '')
- for (marker, value) in (('ivValue', ivValue), ('icValue', icValue),
- ('xvValue', xvValue), ('xcValue', xcValue)):
- code.replace(marker, value)
- iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = IntegerExecute.subst(iop)
+def format IntOp(code, *opt_flags) {{
+ doIntFormat(code, IntOpExecute, name, Name, opt_flags)
}};
+
+// Primary format for integer operate instructions:
+def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{
+ for (marker, value) in (('ivValue', ivValue), ('icValue', icValue),
+ ('xvValue', xvValue), ('xcValue', xcValue)):
+ code.replace(marker, value)
+ doIntFormat(code, IntOpCcExecute, name, Name, opt_flags)
+}};
+
+// Primary format for integer operate instructions:
+def format IntOpCcRes(code, *opt_flags) {{
+ doIntFormat(code, IntOpCcResExecute, name, Name, opt_flags)
+}};
+
diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa
index d72de47d0..06725eae8 100644
--- a/arch/sparc/isa/formats/mem.isa
+++ b/arch/sparc/isa/formats/mem.isa
@@ -12,7 +12,7 @@ output header {{
protected:
// Constructor
- Mem(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
@@ -56,18 +56,7 @@ def format Mem(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
+ decode_block = BasicDecode.subst(iop)
exec_output = MemExecute.subst(iop)
exec_output.replace('ea_code', 'EA = I ? (R1 + SIMM13) : R1 + R2;');
}};
-
-def format Cas(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = MemExecute.subst(iop)
- exec_output.replace('ea_code', 'EA = R1;');
-}};
diff --git a/arch/sparc/isa/formats/noop.isa b/arch/sparc/isa/formats/noop.isa
index fa4047f06..5007f5bcb 100644
--- a/arch/sparc/isa/formats/noop.isa
+++ b/arch/sparc/isa/formats/noop.isa
@@ -11,7 +11,7 @@ output header {{
{
protected:
// Constructor
- Noop(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Noop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
@@ -45,6 +45,6 @@ def format Noop(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
+ decode_block = BasicDecode.subst(iop)
exec_output = NoopExecute.subst(iop)
}};
diff --git a/arch/sparc/isa/formats/priv.isa b/arch/sparc/isa/formats/priv.isa
new file mode 100644
index 000000000..c89e769b4
--- /dev/null
+++ b/arch/sparc/isa/formats/priv.isa
@@ -0,0 +1,165 @@
+////////////////////////////////////////////////////////////////////
+//
+// Privilege mode instructions
+//
+
+output header {{
+ /**
+ * Base class for privelege mode operations.
+ */
+ class Priv : public SparcStaticInst
+ {
+ protected:
+ // Constructor
+ Priv(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
+ SparcStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for user mode "tick" access.
+ */
+ class PrivTick : public SparcStaticInst
+ {
+ protected:
+ // Constructor
+ PrivTick(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass) :
+ SparcStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for privelege mode operations with immediates.
+ */
+ class PrivImm : public Priv
+ {
+ protected:
+ // Constructor
+ PrivImm(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass) :
+ Priv(mnem, _machInst, __opClass), imm(SIMM13)
+ {
+ }
+
+ uint32_t imm;
+ };
+
+ /**
+ * Base class for user mode "tick" access with immediates.
+ */
+ class PrivTickImm : public PrivTick
+ {
+ protected:
+ // Constructor
+ PrivTickImm(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass) :
+ PrivTick(mnem, _machInst, __opClass), imm(SIMM13)
+ {
+ }
+
+ uint32_t imm;
+ };
+}};
+
+output decoder {{
+ std::string Priv::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return "Privileged Instruction";
+ }
+
+ std::string PrivTick::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return "Regular access to Tick";
+ }
+}};
+
+def template PrivExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ %(op_decl)s;
+ %(op_rd)s;
+
+ //If the processor isn't in privileged mode, fault out right away
+ if(!PstatePriv)
+ return new PrivilegedOpcode
+
+ %(code)s;
+ %(op_wb)s;
+ }
+}};
+
+def template PrivTickExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ %(op_decl)s;
+ %(op_rd)s;
+
+ //If the processor isn't in privileged mode, fault out right away
+ if(!PstatePriv && TickNpt)
+ return new PrivilegedAction
+
+ %(code)s;
+ %(op_wb)s;
+ }
+}};
+
+// Primary format for integer operate instructions:
+def format Priv(code, *opt_flags) {{
+ uses_imm = (code.find('Rs2_or_imm13') != -1)
+ if uses_imm:
+ orig_code = code
+ code = re.sub(r'Rs2_or_imm13', 'Rs2', orig_code)
+ imm_code = re.sub(r'Rs2_or_imm13(\.\w+)?', 'imm', orig_code)
+ cblk = CodeBlock(code)
+ iop = InstObjParams(name, Name, 'Priv', cblk, opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ exec_output = PrivExecute.subst(iop)
+ if uses_imm:
+ imm_cblk = CodeBlock(imm_code)
+ imm_iop = InstObjParams(name, Name + 'Imm', 'PrivImm', imm_cblk,
+ opt_flags)
+ header_output += BasicDeclare.subst(imm_iop)
+ decoder_output += BasicConstructor.subst(imm_iop)
+ exec_output += PrivExecute.subst(imm_iop)
+ decode_block = ROrImmDecode.subst(iop)
+ else:
+ decode_block = BasicDecode.subst(iop)
+}};
+
+// Primary format for integer operate instructions:
+def format PrivTick(code, *opt_flags) {{
+ uses_imm = (code.find('Rs2_or_imm13') != -1)
+ if uses_imm:
+ orig_code = code
+ code = re.sub(r'Rs2_or_imm13', 'Rs2', orig_code)
+ imm_code = re.sub(r'Rs2_or_imm13(\.\w+)?', 'imm', orig_code)
+ cblk = CodeBlock(code)
+ iop = InstObjParams(name, Name, 'PrivTick', cblk, opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ exec_output = PrivTickExecute.subst(iop)
+ if uses_imm:
+ imm_cblk = CodeBlock(imm_code)
+ imm_iop = InstObjParams(name, Name + 'Imm', 'PrivTickImm', imm_cblk,
+ opt_flags)
+ header_output += BasicDeclare.subst(imm_iop)
+ decoder_output += BasicConstructor.subst(imm_iop)
+ exec_output += PrivTickExecute.subst(imm_iop)
+ decode_block = Rb2OrImmDecode.subst(iop)
+ else:
+ decode_block = BasicDecode.subst(iop)
+}};
diff --git a/arch/sparc/isa/formats/trap.isa b/arch/sparc/isa/formats/trap.isa
index ff3aadf72..935fbfe6b 100644
--- a/arch/sparc/isa/formats/trap.isa
+++ b/arch/sparc/isa/formats/trap.isa
@@ -5,14 +5,15 @@
output header {{
/**
- * Base class for integer operations.
+ * Base class for trap instructions,
+ * or instructions that always fault.
*/
class Trap : public SparcStaticInst
{
protected:
// Constructor
- Trap(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Trap(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
@@ -34,18 +35,18 @@ def template TrapExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
- //TODO: set up a software fault and return it.
- return NoFault;
+ Fault fault = NoFault;
+ %(code)s
+ return fault;
}
}};
-// Primary format for integer operate instructions:
def format Trap(code, *opt_flags) {{
orig_code = code
cblk = CodeBlock(code)
iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
+ decode_block = BasicDecode.subst(iop)
exec_output = TrapExecute.subst(iop)
}};
diff --git a/arch/sparc/isa/formats/unknown.isa b/arch/sparc/isa/formats/unknown.isa
new file mode 100644
index 000000000..eeb2b9496
--- /dev/null
+++ b/arch/sparc/isa/formats/unknown.isa
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////
+//
+// Unknown instructions
+//
+
+output header {{
+ /**
+ * Class for Unknown/Illegal instructions
+ */
+ class Unknown : public SparcStaticInst
+ {
+ public:
+
+ // Constructor
+ Unknown(ExtMachInst _machInst) :
+ SparcStaticInst("unknown", _machInst, No_OpClass)
+ {
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ };
+}};
+
+output decoder {{
+ std::string Unknown::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return "Unknown instruction\n";
+ }
+}};
+
+output exec {{
+ Fault Unknown::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ return new IllegalInstruction;
+ }
+}};
+
+def format Unknown() {{
+ decode_block = 'return new Unknown(machInst);\n'
+}};
diff --git a/arch/sparc/isa/includes.isa b/arch/sparc/isa/includes.isa
index a99018b49..c39fc2ef9 100644
--- a/arch/sparc/isa/includes.isa
+++ b/arch/sparc/isa/includes.isa
@@ -10,7 +10,7 @@ output header {{
#include "cpu/static_inst.hh"
#include "arch/sparc/faults.hh"
-#include "mem/mem_req.hh" // some constructors use MemReq flags
+#include "mem/request.hh" // some constructors use MemReq flags
#include "arch/sparc/isa_traits.hh"
}};
@@ -34,10 +34,12 @@ output exec {{
#endif
#ifdef FULL_SYSTEM
-//#include "arch/alpha/pseudo_inst.hh"
+//#include "sim/pseudo_inst.hh"
#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
+
+using namespace SparcISA;
}};
diff --git a/arch/sparc/isa/operands.isa b/arch/sparc/isa/operands.isa
index 64f5abd08..abfdf7bcd 100644
--- a/arch/sparc/isa/operands.isa
+++ b/arch/sparc/isa/operands.isa
@@ -27,5 +27,84 @@ def operands {{
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
#'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
'R0': ('IntReg', 'udw', '0', None, 1),
- 'R16': ('IntReg', 'udw', '16', None, 1)
+ 'R16': ('IntReg', 'udw', '16', None, 1),
+ # Control registers
+ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 1),
+ 'PstateAg': ('ControlReg', 'udw', 'MISCREG_PSTATE_AG', None, 2),
+ 'PstateIe': ('ControlReg', 'udw', 'MISCREG_PSTATE_IE', None, 3),
+ 'PstatePriv': ('ControlReg', 'udw', 'MISCREG_PSTATE_PRIV', None, 4),
+ 'PstateAm': ('ControlReg', 'udw', 'MISCREG_PSTATE_AM', None, 5),
+ 'PstatePef': ('ControlReg', 'udw', 'MISCREG_PSTATE_PEF', None, 6),
+ 'PstateRed': ('ControlReg', 'udw', 'MISCREG_PSTATE_RED', None, 7),
+ 'PstateMm': ('ControlReg', 'udw', 'MISCREG_PSTATE_MM', None, 8),
+ 'PstateTle': ('ControlReg', 'udw', 'MISCREG_PSTATE_TLE', None, 9),
+ 'PstateCle': ('ControlReg', 'udw', 'MISCREG_PSTATE_CLE', None, 10),
+ 'Tba': ('ControlReg', 'udw', 'MISCREG_TBA', None, 11),
+ 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 12),
+ 'YValue': ('ControlReg', 'udw', 'MISCREG_Y_VALUE', None, 13),
+ 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 14),
+ 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 15),
+ #'Tt': ('ControlReg', 'udw', 'MISCREG_TT_BASE + tl', None, 16),
+ 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 17),
+ 'CcrIcc': ('ControlReg', 'udw', 'MISCREG_CCR_ICC', None, 18),
+ 'CcrIccC': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_C', None, 19),
+ 'CcrIccV': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_V', None, 20),
+ 'CcrIccZ': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_Z', None, 21),
+ 'CcrIccN': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_N', None, 22),
+ 'CcrXcc': ('ControlReg', 'udw', 'MISCREG_CCR_XCC', None, 23),
+ 'CcrXccC': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_C', None, 22),
+ 'CcrXccV': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_V', None, 23),
+ 'CcrXccZ': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_Z', None, 24),
+ 'CcrXccN': ('ControlReg', 'udw', 'MISCREG_XCC_N', None, 25),
+ 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 26),
+ 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 27),
+ #'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 28),
+ 'Tick': ('ControlReg', 'udw', 'MISCREG_TICK', None, 29),
+ 'TickCounter': ('ControlReg', 'udw', 'MISCREG_TICK_COUNTER', None, 32),
+ 'TickNpt': ('ControlReg', 'udw', 'MISCREG_TICK_NPT', None, 33),
+ 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 34),
+ 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 35),
+ 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 36),
+ 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 37),
+ 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 38),
+ 'WstateNormal': ('ControlReg', 'udw', 'MISCREG_WSTATE_NORMAL', None,39),
+ 'WstateOther': ('ControlReg', 'udw', 'MISCREG_WSTATE_OTHER', None, 40),
+ 'Ver': ('ControlReg', 'udw', 'MISCREG_VER', None, 41),
+ 'VerMaxwin': ('ControlReg', 'udw', 'MISCREG_VER_MAXWIN', None, 42),
+ 'VerMaxtl': ('ControlReg', 'udw', 'MISCREG_VER_MAXTL', None, 43),
+ 'VerMask': ('ControlReg', 'udw', 'MISCREG_VER_MASK', None, 44),
+ 'VerImpl': ('ControlReg', 'udw', 'MISCREG_VER_MASK', None, 45),
+ 'VerManuf': ('ControlReg', 'udw', 'MISCREG_VER_MANUF', None, 46),
+ 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 47),
+ 'FsrCexc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC', None, 48),
+ 'FsrCexcNxc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_NXC', None, 49),
+ 'FsrCexcDzc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_DZC', None, 50),
+ 'FsrCexcUfc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_UFC', None, 51),
+ 'FsrCexcOfc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_OFC', None, 52),
+ 'FsrCexcNvc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_NVC', None, 53),
+ 'FsrAexc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC', None, 54),
+ 'FsrAexcNxc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_NXC', None, 55),
+ 'FsrAexcDzc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_DZC', None, 56),
+ 'FsrAexcUfc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_UFC', None, 57),
+ 'FsrAexcOfc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_OFC', None, 58),
+ 'FsrAexcNvc': ('ControlReg', 'udw', 'MISCREC_FSR_AEXC_NVC', None, 59),
+ 'FsrFcc0': ('ControlReg', 'udw', 'MISCREG_FSR_FCC0', None, 60),
+ 'FsrQne': ('ControlReg', 'udw', 'MISCREG_FSR_QNE', None, 61),
+ 'FsrFtt': ('ControlReg', 'udw', 'MISCREG_FSR_FTT', None, 62),
+ 'FsrVer': ('ControlReg', 'udw', 'MISCREG_FSR_VER', None, 63),
+ 'FsrNs': ('ControlReg', 'udw', 'MISCREG_FSR_NS', None, 64),
+ 'FsrTem': ('ControlReg', 'udw', 'MISCREG_FSR_TEM', None, 65),
+ 'FsrTemNxm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_NXM', None, 66),
+ 'FsrTemDzm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_DZM', None, 67),
+ 'FsrTemUfm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_UFM', None, 68),
+ 'FsrTemOfm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_OFM', None, 69),
+ 'FsrTemNvm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_NVM', None, 70),
+ 'FsrRd': ('ControlReg', 'udw', 'MISCREG_FSR_RD', None, 71),
+ 'FsrFcc1': ('ControlReg', 'udw', 'MISCREG_FSR_FCC1', None, 72),
+ 'FsrFcc2': ('ControlReg', 'udw', 'MISCREG_FSR_FCC2', None, 73),
+ 'FsrFcc3': ('ControlReg', 'udw', 'MISCREG_FSR_FCC3', None, 74),
+ 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 75),
+ 'FprsDl': ('ControlReg', 'udw', 'MISCREG_FPRS_DL', None, 76),
+ 'FprsDu': ('ControlReg', 'udw', 'MISCREG_FPRS_DU', None, 77),
+ 'FprsFef': ('ControlReg', 'udw', 'MISCREG_FPRS_FEF', None, 78)
}};
diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh
index bd3c35beb..4886da7cf 100644
--- a/arch/sparc/isa_traits.hh
+++ b/arch/sparc/isa_traits.hh
@@ -29,46 +29,87 @@
#ifndef __ARCH_SPARC_ISA_TRAITS_HH__
#define __ARCH_SPARC_ISA_TRAITS_HH__
-#include "arch/sparc/faults.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
-//This makes sure the big endian versions of certain functions are used.
-namespace BigEndianGuest {}
-using namespace BigEndianGuest;
-
class ExecContext;
class FastCPU;
//class FullCPU;
class Checkpoint;
-#define TARGET_SPARC
-
class StaticInst;
class StaticInstPtr;
-//namespace EV5
-//{
-// int DTB_ASN_ASN(uint64_t reg);
-// int ITB_ASN_ASN(uint64_t reg);
-//}
+namespace BigEndianGuest {}
+
+#if !FULL_SYSTEM
+class SyscallReturn
+{
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint64_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint64_t)v;
+ }
+
+ ~SyscallReturn() {}
+
+ SyscallReturn& operator=(const SyscallReturn& s)
+ {
+ retval = s.retval;
+ success = s.success;
+ return *this;
+ }
+
+ bool successful() { return success; }
+ uint64_t value() { return retval; }
+
+ private:
+ uint64_t retval;
+ bool success;
+};
+
+#endif
+
namespace SparcISA
{
+
+ // These enumerate all the registers for dependence tracking.
+ enum DependenceTags {
+ // 0..31 are the integer regs 0..31
+ // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
+ FP_Base_DepTag = 32,
+ Ctrl_Base_DepTag = 96,
+ };
+
+ //This makes sure the big endian versions of certain functions are used.
+ using namespace BigEndianGuest;
+
typedef uint32_t MachInst;
typedef uint64_t ExtMachInst;
- typedef uint8_t RegIndex;
- const int NumFloatRegs = 32;
+ inline ExtMachInst
+ makeExtMI(MachInst inst, const Addr &pc) {
+ return ExtMachInst(inst);
+ }
+
+ const int NumIntRegs = 32;
+ const int NumFloatRegs = 64;
const int NumMiscRegs = 32;
- const int // Maximum trap level
- const int MaxTL = 4;
- const int
- const int // semantically meaningful register indices
+ // semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
- const int // the rest of these depend on the ABI
+ // the rest of these depend on the ABI
const int StackPointerReg = 14;
const int ReturnAddressReg = 31; // post call, precall is 15
const int ReturnValueReg = 8; // Post return, 24 is pre-return.
@@ -79,363 +120,43 @@ namespace SparcISA
const int ArgumentReg3 = 11;
const int ArgumentReg4 = 12;
const int ArgumentReg5 = 13;
+ const int SyscallNumReg = 1;
// Some OS syscall sue a second register (o1) to return a second value
const int SyscallPseudoReturnReg = ArgumentReg1;
+ //XXX These numbers are bogus
+ const int MaxInstSrcRegs = 3;
+ const int MaxInstDestRegs = 2;
+
+ typedef uint64_t IntReg;
+
+ // control register file contents
+ typedef uint64_t MiscReg;
+
+ typedef double FloatReg;
+ typedef uint64_t FloatRegBits;
//8K. This value is implmentation specific; and should probably
//be somewhere else.
const int LogVMPageSize = 13;
const int VMPageSize = (1 << LogVMPageSize);
+ //Why does both the previous set of constants and this one exist?
+ const int PageShift = 13;
+ const int PageBytes = ULL(1) << PageShift;
+ const int BranchPredAddrShiftAmt = 2;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- typedef uint64_t IntReg;
-
- class IntRegFile
- {
- private:
- //For right now, let's pretend the register file is static
- IntReg regs[32];
- public:
- IntReg & operator [] (RegIndex index)
- {
- //Don't allow indexes outside of the 32 registers
- index &= 0x1F;
- return regs[index];
- }
- };
+ const int MachineBytes = 8;
+ const int WordBytes = 4;
+ const int HalfwordBytes = 2;
+ const int ByteBytes = 1;
void serialize(std::ostream & os);
void unserialize(Checkpoint *cp, const std::string &section);
- typedef float float32_t;
- typedef double float64_t;
- //FIXME This actually usually refers to a 10 byte float, rather than a
- //16 byte float as required. This data type may have to be emulated.
- typedef long double float128_t;
-
- class FloatRegFile
- {
- private:
- //By using the largest data type, we ensure everything
- //is aligned correctly in memory
- union
- {
- float128_t rawRegs[16];
- uint64_t regDump[32];
- };
- class QuadRegs
- {
- private:
- FloatRegFile * parent;
- public:
- QuadRegs(FloatRegFile * p) : parent(p) {;}
- float128_t & operator [] (RegIndex index)
- {
- //Quad floats are index by the single
- //precision register the start on,
- //and only 16 should be accessed
- index = (index >> 2) & 0xF;
- return parent->rawRegs[index];
- }
- };
- class DoubleRegs
- {
- private:
- FloatRegFile * parent;
- public:
- DoubleRegs(FloatRegFile * p) : parent(p) {;}
- float64_t & operator [] (RegIndex index)
- {
- //Double floats are index by the single
- //precision register the start on,
- //and only 32 should be accessed
- index = (index >> 1) & 0x1F;
- return ((float64_t *)parent->rawRegs)[index];
- }
- };
- class SingleRegs
- {
- private:
- FloatRegFile * parent;
- public:
- SingleRegs(FloatRegFile * p) : parent(p) {;}
- float32_t & operator [] (RegIndex index)
- {
- //Only 32 single floats should be accessed
- index &= 0x1F;
- return ((float32_t *)parent->rawRegs)[index];
- }
- };
- public:
- void serialize(std::ostream & os);
-
- void unserialize(Checkpoint * cp, std::string & section);
-
- QuadRegs quadRegs;
- DoubleRegs doubleRegs;
- SingleRegs singleRegs;
- FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this)
- {;}
- };
-
- // control register file contents
- typedef uint64_t MiscReg;
- // The control registers, broken out into fields
- class MiscRegFile
- {
- private:
- union
- {
- uint16_t pstate; // Process State Register
- struct
- {
- uint16_t ag:1; // Alternate Globals
- uint16_t ie:1; // Interrupt enable
- uint16_t priv:1; // Privelege mode
- uint16_t am:1; // Address mask
- uint16_t pef:1; // PSTATE enable floating-point
- uint16_t red:1; // RED (reset, error, debug) state
- uint16_t mm:2; // Memory Model
- uint16_t tle:1; // Trap little-endian
- uint16_t cle:1; // Current little-endian
- } pstateFields;
- };
- uint64_t tba; // Trap Base Address
- union
- {
- uint64_t y; // Y (used in obsolete multiplication)
- struct
- {
- uint64_t value:32; // The actual value stored in y
- uint64_t :32; // reserved bits
- } yFields;
- };
- uint8_t pil; // Process Interrupt Register
- uint8_t cwp; // Current Window Pointer
- uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
- // on the previous level)
- union
- {
- uint8_t ccr; // Condition Code Register
- struct
- {
- union
- {
- uint8_t icc:4; // 32-bit condition codes
- struct
- {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } iccFields;
- };
- union
- {
- uint8_t xcc:4; // 64-bit condition codes
- struct
- {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } xccFields;
- };
- } ccrFields;
- };
- uint8_t asi; // Address Space Identifier
- uint8_t tl; // Trap Level
- uint64_t tpc[MaxTL]; // Trap Program Counter (value from
- // previous trap level)
- uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
- // previous trap level)
- union
- {
- uint64_t tstate[MaxTL]; // Trap State
- struct
- {
- //Values are from previous trap level
- uint64_t cwp:5; // Current Window Pointer
- uint64_t :2; // Reserved bits
- uint64_t pstate:10; // Process State
- uint64_t :6; // Reserved bits
- uint64_t asi:8; // Address Space Identifier
- uint64_t ccr:8; // Condition Code Register
- } tstateFields[MaxTL];
- };
- union
- {
- uint64_t tick; // Hardware clock-tick counter
- struct
- {
- uint64_t counter:63; // Clock-tick count
- uint64_t npt:1; // Non-priveleged trap
- } tickFields;
- };
- uint8_t cansave; // Savable windows
- uint8_t canrestore; // Restorable windows
- uint8_t otherwin; // Other windows
- uint8_t cleanwin; // Clean windows
- union
- {
- uint8_t wstate; // Window State
- struct
- {
- uint8_t normal:3; // Bits TT<4:2> are set to on a normal
- // register window trap
- uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
- // register window trap
- } wstateFields;
- };
- union
- {
- uint64_t ver; // Version
- struct
- {
- uint64_t maxwin:5; // Max CWP value
- uint64_t :2; // Reserved bits
- uint64_t maxtl:8; // Maximum trap level
- uint64_t :8; // Reserved bits
- uint64_t mask:8; // Processor mask set revision number
- uint64_t impl:16; // Implementation identification number
- uint64_t manuf:16; // Manufacturer code
- } verFields;
- };
- union
- {
- uint64_t fsr; // Floating-Point State Register
- struct
- {
- union
- {
- uint64_t cexc:5; // Current excpetion
- struct
- {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } cexecFields;
- };
- union
- {
- uint64_t aexc:5; // Accrued exception
- struct
- {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } aexecFields;
- };
- uint64_t fcc0:2; // Floating-Point condtion codes
- uint64_t :1; // Reserved bits
- uint64_t qne:1; // Deferred trap queue not empty
- // with no queue, it should read 0
- uint64_t ftt:3; // Floating-Point trap type
- uint64_t ver:3; // Version (of the FPU)
- uint64_t :2; // Reserved bits
- uint64_t ns:1; // Nonstandard floating point
- union
- {
- uint64_t tem:5; // Trap Enable Mask
- struct
- {
- uint64_t nxm:1; // Inexact
- uint64_t dzm:1; // Divide by zero
- uint64_t ufm:1; // Underflow
- uint64_t ofm:1; // Overflow
- uint64_t nvm:1; // Invalid operand
- } temFields;
- };
- uint64_t :2; // Reserved bits
- uint64_t rd:2; // Rounding direction
- uint64_t fcc1:2; // Floating-Point condition codes
- uint64_t fcc2:2; // Floating-Point condition codes
- uint64_t fcc3:2; // Floating-Point condition codes
- uint64_t :26; // Reserved bits
- } fsrFields;
- };
- union
- {
- uint8_t fprs; // Floating-Point Register State
- struct
- {
- uint8_t dl:1; // Dirty lower
- uint8_t du:1; // Dirty upper
- uint8_t fef:1; // FPRS enable floating-Point
- } fprsFields;
- };
-
- public:
- MiscReg readReg(int misc_reg);
-
- MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
-
- Fault setReg(int misc_reg, const MiscReg &val);
-
- Fault setRegWithEffect(int misc_reg, const MiscReg &val,
- ExecContext *xc);
-
- void serialize(std::ostream & os);
-
- void unserialize(Checkpoint * cp, std::string & section);
- };
-
- typedef union
- {
- float32_t singReg;
- float64_t doubReg;
- float128_t quadReg;
- } FloatReg;
-
- typedef union
- {
- IntReg intreg;
- FloatReg fpreg;
- MiscReg ctrlreg;
- } AnyReg;
-
- struct RegFile
- {
- IntRegFile intRegFile; // (signed) integer register file
- FloatRegFile floatRegFile; // floating point register file
- MiscRegFile miscRegFile; // control register file
-
- Addr pc; // Program Counter
- Addr npc; // Next Program Counter
- Addr nnpc;
-
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
- };
-
- StaticInstPtr decodeInst(MachInst);
+ StaticInstPtr decodeInst(ExtMachInst);
// return a no-op instruction... used for instruction fetch faults
extern const MachInst NoopMachInst;
@@ -463,65 +184,32 @@ namespace SparcISA
* @param xc The execution context.
*/
template <class XC>
+ void zeroRegisters(XC *xc);
+}
+
+#include "arch/sparc/regfile.hh"
+
+namespace SparcISA
+{
- static inline setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+#if !FULL_SYSTEM
+ static inline void setSyscallReturn(SyscallReturn return_value,
+ RegFile *regs)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
if (return_value.successful()) {
// no error
- regs->miscRegFile.ccrFields.iccFields.c = 0;
+ regs->miscRegs.setReg(MISCREG_CCR_ICC_C, 0);
regs->intRegFile[ReturnValueReg] = return_value.value();
} else {
// got an error, return details
- regs->miscRegFile.ccrFields.iccFields.c = 1;
+ regs->miscRegs.setReg(MISCREG_CCR_ICC_C, 1);
regs->intRegFile[ReturnValueReg] = -return_value.value();
}
}
-};
-
-#if !FULL_SYSTEM
-class SyscallReturn
-{
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s)
- {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
- private:
- uint64_t retval;
- bool success;
-};
-
-#endif
-
-
-#if FULL_SYSTEM
-
-#include "arch/alpha/ev5.hh"
#endif
+};
#endif // __ARCH_SPARC_ISA_TRAITS_HH__
diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc
index fa2a7b9f5..cb056eadc 100644
--- a/arch/sparc/linux/process.cc
+++ b/arch/sparc/linux/process.cc
@@ -26,14 +26,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "arch/sparc/common_syscall_emul.hh"
#include "arch/sparc/linux/process.hh"
#include "arch/sparc/isa_traits.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "kern/linux/linux.hh"
-#include "mem/functional/functional.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
@@ -55,318 +53,318 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "sparc");
- name.copyOut(xc->mem);
+ name.copyOut(xc->getMemPort());
return 0;
}
SyscallDesc SparcLinuxProcess::syscallDescs[] = {
- /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc);
- /* 1 */ SyscallDesc("exit", exitFunc);
- /* 2 */ SyscallDesc("fork", unimplementedFunc);
- /* 3 */ SyscallDesc("read", readFunc);
- /* 4 */ SyscallDesc("write", writeFunc);
- /* 5 */ SyscallDesc("open", openFunc<Linux>);
- /* 6 */ SyscallDesc("close", closeFinc);
- /* 7 */ SyscallDesc("wait4", unimplementedFunc);
- /* 8 */ SyscallDesc("creat", unimplementedFunc);
- /* 9 */ SyscallDesc("link", unimplementedFunc);
- /* 10 */ SyscallDesc("unlink", unlinkFunc);
- /* 11 */ SyscallDesc("execv", unimplementedFunc);
- /* 12 */ SyscallDesc("chdir", unimplementedFunc);
- /* 13 */ SyscallDesc("chown", chownFunc);
- /* 14 */ SyscallDesc("mknod", unimplementedFunc);
- /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>);
- /* 16 */ SyscallDesc("lchown", unimplementedFunc);
- /* 17 */ SyscallDesc("brk", obreakFunc);
- /* 18 */ SyscallDesc("perfctr", unimplementedFunc);
- /* 19 */ SyscallDesc("lseek", lseekFunc);
- /* 20 */ SyscallDesc("getpid", getpidFunc);
- /* 21 */ SyscallDesc("capget", unimplementedFunc);
- /* 22 */ SyscallDesc("capset", unimplementedFunc);
- /* 23 */ SyscallDesc("setuid", setuidFunc);
- /* 24 */ SyscallDesc("getuid", getuidFunc);
- /* 25 */ SyscallDesc("time", unimplementedFunc);
- /* 26 */ SyscallDesc("ptrace", unimplementedFunc);
- /* 27 */ SyscallDesc("alarm", unimplementedFunc);
- /* 28 */ SyscallDesc("sigaltstack", unimplementedFunc);
- /* 29 */ SyscallDesc("pause", unimplementedFunc);
- /* 30 */ SyscallDesc("utime", unimplementedFunc);
- /* 31 */ SyscallDesc("lchown32", unimplementedFunc);
- /* 32 */ SyscallDesc("fchown32", unimplementedFunc);
- /* 33 */ SyscallDesc("access", unimplementedFunc);
- /* 34 */ SyscallDesc("nice", unimplementedFunc);
- /* 35 */ SyscallDesc("chown32", unimplementedFunc);
- /* 36 */ SyscallDesc("sync", unimplementedFunc);
- /* 37 */ SyscallDesc("kill", unimplementedFunc);
- /* 38 */ SyscallDesc("stat", unimplementedFunc);
- /* 39 */ SyscallDesc("sendfile", unimplementedFunc);
- /* 40 */ SyscallDesc("lstat", unimplementedFunc);
- /* 41 */ SyscallDesc("dup", unimplementedFunc);
- /* 42 */ SyscallDesc("pipe", pipePseudoFunc);
- /* 43 */ SyscallDesc("times", unimplementedFunc);
- /* 44 */ SyscallDesc("getuid32", unimplementedFunc);
- /* 45 */ SyscallDesc("umount2", unimplementedFunc);
- /* 46 */ SyscallDesc("setgid", unimplementedFunc);
- /* 47 */ SyscallDesc("getgid", getgidFunc);
- /* 48 */ SyscallDesc("signal", unimplementedFunc);
- /* 49 */ SyscallDesc("geteuid", geteuidFunc);
- /* 50 */ SyscallDesc("getegid", getegidFunc);
- /* 51 */ SyscallDesc("acct", unimplementedFunc);
- /* 52 */ SyscallDesc("memory_ordering", unimplementedFunc);
- /* 53 */ SyscallDesc("getgid32", unimplementedFunc);
- /* 54 */ SyscallDesc("ioctl", unimplementedFunc);
- /* 55 */ SyscallDesc("reboot", unimplementedFunc);
- /* 56 */ SyscallDesc("mmap2", unimplementedFunc);
- /* 57 */ SyscallDesc("symlink", unimplementedFunc);
- /* 58 */ SyscallDesc("readlink", unimplementedFunc);
- /* 59 */ SyscallDesc("execve", unimplementedFunc);
- /* 60 */ SyscallDesc("umask", unimplementedFunc);
- /* 61 */ SyscallDesc("chroot", unimplementedFunc);
- /* 62 */ SyscallDesc("fstat", unimplementedFunc);
- /* 63 */ SyscallDesc("fstat64", unimplementedFunc);
- /* 64 */ SyscallDesc("getpagesize", unimplementedFunc);
- /* 65 */ SyscallDesc("msync", unimplementedFunc);
- /* 66 */ SyscallDesc("vfork", unimplementedFunc);
- /* 67 */ SyscallDesc("pread64", unimplementedFunc);
- /* 68 */ SyscallDesc("pwrite64", unimplementedFunc);
- /* 69 */ SyscallDesc("geteuid32", unimplementedFunc);
- /* 70 */ SyscallDesc("getdgid32", unimplementedFunc);
- /* 71 */ SyscallDesc("mmap", unimplementedFunc);
- /* 72 */ SyscallDesc("setreuid32", unimplementedFunc);
- /* 73 */ SyscallDesc("munmap", unimplementedFunc);
- /* 74 */ SyscallDesc("mprotect", unimplementedFunc);
- /* 75 */ SyscallDesc("madvise", unimplementedFunc);
- /* 76 */ SyscallDesc("vhangup", unimplementedFunc);
- /* 77 */ SyscallDesc("truncate64", unimplementedFunc);
- /* 78 */ SyscallDesc("mincore", unimplementedFunc);
- /* 79 */ SyscallDesc("getgroups", unimplementedFunc);
- /* 80 */ SyscallDesc("setgroups", unimplementedFunc);
- /* 81 */ SyscallDesc("getpgrp", unimplementedFunc);
- /* 82 */ SyscallDesc("setgroups32", unimplementedFunc);
- /* 83 */ SyscallDesc("setitimer", unimplementedFunc);
- /* 84 */ SyscallDesc("ftruncate64", unimplementedFunc);
- /* 85 */ SyscallDesc("swapon", unimplementedFunc);
- /* 86 */ SyscallDesc("getitimer", unimplementedFunc);
- /* 87 */ SyscallDesc("setuid32", unimplementedFunc);
- /* 88 */ SyscallDesc("sethostname", unimplementedFunc);
- /* 89 */ SyscallDesc("setgid32", unimplementedFunc);
- /* 90 */ SyscallDesc("dup2", unimplementedFunc);
- /* 91 */ SyscallDesc("setfsuid32", unimplementedFunc);
- /* 92 */ SyscallDesc("fcntl", unimplementedFunc);
- /* 93 */ SyscallDesc("select", unimplementedFunc);
- /* 94 */ SyscallDesc("setfsgid32", unimplementedFunc);
- /* 95 */ SyscallDesc("fsync", unimplementedFunc);
- /* 96 */ SyscallDesc("setpriority", unimplementedFunc);
- /* 97 */ SyscallDesc("socket", unimplementedFunc);
- /* 98 */ SyscallDesc("connect", unimplementedFunc);
- /* 99 */ SyscallDesc("accept", unimplementedFunc);
- /* 100 */ SyscallDesc("getpriority", unimplementedFunc);
- /* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc);
- /* 102 */ SyscallDesc("rt_sigaction", unimplementedFunc);
- /* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc);
- /* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc);
- /* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc);
- /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc);
- /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc);
- /* 108 */ SyscallDesc("setresuid", unimplementedFunc);
- /* 109 */ SyscallDesc("getresuid", unimplementedFunc);
- /* 110 */ SyscallDesc("setresgid", unimplementedFunc);
- /* 111 */ SyscallDesc("getresgid", unimplementedFunc);
- /* 112 */ SyscallDesc("setregid32", unimplementedFunc);
- /* 113 */ SyscallDesc("recvmsg", unimplementedFunc);
- /* 114 */ SyscallDesc("sendmsg", unimplementedFunc);
- /* 115 */ SyscallDesc("getgroups32", unimplementedFunc);
- /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc);
- /* 117 */ SyscallDesc("getrusage", unimplementedFunc);
- /* 118 */ SyscallDesc("getsockopt", unimplementedFunc);
- /* 119 */ SyscallDesc("getcwd", unimplementedFunc);
- /* 120 */ SyscallDesc("readv", unimplementedFunc);
- /* 121 */ SyscallDesc("writev", unimplementedFunc);
- /* 122 */ SyscallDesc("settimeofday", unimplementedFunc);
- /* 123 */ SyscallDesc("fchown", unimplementedFunc);
- /* 124 */ SyscallDesc("fchmod", unimplementedFunc);
- /* 125 */ SyscallDesc("recvfrom", unimplementedFunc);
- /* 126 */ SyscallDesc("setreuid", unimplementedFunc);
- /* 127 */ SyscallDesc("setregid", unimplementedFunc);
- /* 128 */ SyscallDesc("rename", unimplementedFunc);
- /* 129 */ SyscallDesc("truncate", unimplementedFunc);
- /* 130 */ SyscallDesc("ftruncate", unimplementedFunc);
- /* 131 */ SyscallDesc("flock", unimplementedFunc);
- /* 132 */ SyscallDesc("lstat64", unimplementedFunc);
- /* 133 */ SyscallDesc("sendto", unimplementedFunc);
- /* 134 */ SyscallDesc("shutdown", unimplementedFunc);
- /* 135 */ SyscallDesc("socketpair", unimplementedFunc);
- /* 136 */ SyscallDesc("mkdir", unimplementedFunc);
- /* 137 */ SyscallDesc("rmdir", unimplementedFunc);
- /* 138 */ SyscallDesc("utimes", unimplementedFunc);
- /* 139 */ SyscallDesc("stat64", unimplementedFunc);
- /* 140 */ SyscallDesc("sendfile64", unimplementedFunc);
- /* 141 */ SyscallDesc("getpeername", unimplementedFunc);
- /* 142 */ SyscallDesc("futex", unimplementedFunc);
- /* 143 */ SyscallDesc("gettid", unimplementedFunc);
- /* 144 */ SyscallDesc("getrlimit", unimplementedFunc);
- /* 145 */ SyscallDesc("setrlimit", unimplementedFunc);
- /* 146 */ SyscallDesc("pivot_root", unimplementedFunc);
- /* 147 */ SyscallDesc("prctl", unimplementedFunc);
- /* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc);
- /* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc);
- /* 150 */ SyscallDesc("getsockname", unimplementedFunc);
- /* 151 */ SyscallDesc("inotify_init", unimplementedFunc);
- /* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc);
- /* 153 */ SyscallDesc("poll", unimplementedFunc);
- /* 154 */ SyscallDesc("getdents64", unimplementedFunc);
- /* 155 */ SyscallDesc("fcntl64", unimplementedFunc);
- /* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc);
- /* 157 */ SyscallDesc("statfs", unimplementedFunc);
- /* 158 */ SyscallDesc("fstatfs", unimplementedFunc);
- /* 159 */ SyscallDesc("umount", unimplementedFunc);
- /* 160 */ SyscallDesc("sched_set_affinity", unimplementedFunc);
- /* 161 */ SyscallDesc("sched_get_affinity", unimplementedFunc);
- /* 162 */ SyscallDesc("getdomainname", unimplementedFunc);
- /* 163 */ SyscallDesc("setdomainname", unimplementedFunc);
- /* 164 */ SyscallDesc("utrap_install", unimplementedFunc);
- /* 165 */ SyscallDesc("quotactl", unimplementedFunc);
- /* 166 */ SyscallDesc("set_tid_address", unimplementedFunc);
- /* 167 */ SyscallDesc("mount", unimplementedFunc);
- /* 168 */ SyscallDesc("ustat", unimplementedFunc);
- /* 169 */ SyscallDesc("setxattr", unimplementedFunc);
- /* 170 */ SyscallDesc("lsetxattr", unimplementedFunc);
- /* 171 */ SyscallDesc("fsetxattr", unimplementedFunc);
- /* 172 */ SyscallDesc("getxattr", unimplementedFunc);
- /* 173 */ SyscallDesc("lgetxattr", unimplementedFunc);
- /* 174 */ SyscallDesc("getdents", unimplementedFunc);
- /* 175 */ SyscallDesc("setsid", unimplementedFunc);
- /* 176 */ SyscallDesc("fchdir", unimplementedFunc);
- /* 177 */ SyscallDesc("fgetxattr", unimplementedFunc);
- /* 178 */ SyscallDesc("listxattr", unimplementedFunc);
- /* 179 */ SyscallDesc("llistxattr", unimplementedFunc);
- /* 180 */ SyscallDesc("flistxattr", unimplementedFunc);
- /* 181 */ SyscallDesc("removexattr", unimplementedFunc);
- /* 182 */ SyscallDesc("lremovexattr", unimplementedFunc);
- /* 183 */ SyscallDesc("sigpending", unimplementedFunc);
- /* 184 */ SyscallDesc("query_module", unimplementedFunc);
- /* 185 */ SyscallDesc("setpgid", unimplementedFunc);
- /* 186 */ SyscallDesc("fremovexattr", unimplementedFunc);
- /* 187 */ SyscallDesc("tkill", unimplementedFunc);
- /* 188 */ SyscallDesc("exit_group", unimplementedFunc);
- /* 189 */ SyscallDesc("uname", unameFunc);
- /* 190 */ SyscallDesc("init_module", unimplementedFunc);
- /* 191 */ SyscallDesc("personality", unimplementedFunc);
- /* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc);
- /* 193 */ SyscallDesc("epoll_create", unimplementedFunc);
- /* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc);
- /* 195 */ SyscallDesc("epoll_wait", unimplementedFunc);
- /* 196 */ SyscallDesc("ioprio_set", unimplementedFunc);
- /* 197 */ SyscallDesc("getppid", getppidFunc);
- /* 198 */ SyscallDesc("sigaction", unimplementedFunc);
- /* 199 */ SyscallDesc("sgetmask", unimplementedFunc);
- /* 200 */ SyscallDesc("ssetmask", unimplementedFunc);
- /* 201 */ SyscallDesc("sigsuspend", unimplementedFunc);
- /* 202 */ SyscallDesc("oldlstat", unimplementedFunc);
- /* 203 */ SyscallDesc("uselib", unimplementedFunc);
- /* 204 */ SyscallDesc("readdir", unimplementedFunc);
- /* 205 */ SyscallDesc("readahead", unimplementedFunc);
- /* 206 */ SyscallDesc("socketcall", unimplementedFunc);
- /* 207 */ SyscallDesc("syslog", unimplementedFunc);
- /* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc);
- /* 209 */ SyscallDesc("fadvise64", unimplementedFunc);
- /* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc);
- /* 211 */ SyscallDesc("tgkill", unimplementedFunc);
- /* 212 */ SyscallDesc("waitpid", unimplementedFunc);
- /* 213 */ SyscallDesc("swapoff", unimplementedFunc);
- /* 214 */ SyscallDesc("sysinfo", unimplementedFunc);
- /* 215 */ SyscallDesc("ipc", unimplementedFunc);
- /* 216 */ SyscallDesc("sigreturn", unimplementedFunc);
- /* 217 */ SyscallDesc("clone", unimplementedFunc);
- /* 218 */ SyscallDesc("ioprio_get", unimplementedFunc);
- /* 219 */ SyscallDesc("adjtimex", unimplementedFunc);
- /* 220 */ SyscallDesc("sigprocmask", unimplementedFunc);
- /* 221 */ SyscallDesc("create_module", unimplementedFunc);
- /* 222 */ SyscallDesc("delete_module", unimplementedFunc);
- /* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc);
- /* 224 */ SyscallDesc("getpgid", unimplementedFunc);
- /* 225 */ SyscallDesc("bdflush", unimplementedFunc);
- /* 226 */ SyscallDesc("sysfs", unimplementedFunc);
- /* 227 */ SyscallDesc("afs_syscall", unimplementedFunc);
- /* 228 */ SyscallDesc("setfsuid", unimplementedFunc);
- /* 229 */ SyscallDesc("setfsgid", unimplementedFunc);
- /* 230 */ SyscallDesc("_newselect", unimplementedFunc);
- /* 231 */ SyscallDesc("time", unimplementedFunc);
- /* 232 */ SyscallDesc("oldstat", unimplementedFunc);
- /* 233 */ SyscallDesc("stime", unimplementedFunc);
- /* 234 */ SyscallDesc("statfs64", unimplementedFunc);
- /* 235 */ SyscallDesc("fstatfs64", unimplementedFunc);
- /* 236 */ SyscallDesc("_llseek", unimplementedFunc);
- /* 237 */ SyscallDesc("mlock", unimplementedFunc);
- /* 238 */ SyscallDesc("munlock", unimplementedFunc);
- /* 239 */ SyscallDesc("mlockall", unimplementedFunc);
- /* 240 */ SyscallDesc("munlockall", unimplementedFunc);
- /* 241 */ SyscallDesc("sched_setparam", unimplementedFunc);
- /* 242 */ SyscallDesc("sched_getparam", unimplementedFunc);
- /* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc);
- /* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc);
- /* 245 */ SyscallDesc("sched_yield", unimplementedFunc);
- /* 246 */ SyscallDesc("sched_get_priority_max", unimplimented);
- /* 247 */ SyscallDesc("sched_get_priority_min", unimplimented);
- /* 248 */ SyscallDesc("sched_rr_get_interval", unimplimented);
- /* 249 */ SyscallDesc("nanosleep", unimplementedFunc);
- /* 250 */ SyscallDesc("mremap", unimplementedFunc);
- /* 251 */ SyscallDesc("_sysctl", unimplementedFunc);
- /* 252 */ SyscallDesc("getsid", unimplementedFunc);
- /* 253 */ SyscallDesc("fdatasync", unimplementedFunc);
- /* 254 */ SyscallDesc("nfsservctl", unimplementedFunc);
- /* 255 */ SyscallDesc("aplib", unimplementedFunc);
- /* 256 */ SyscallDesc("clock_settime", unimplementedFunc);
- /* 257 */ SyscallDesc("clock_gettime", unimplementedFunc);
- /* 258 */ SyscallDesc("clock_getres", unimplementedFunc);
- /* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc);
- /* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc);
- /* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc);
- /* 262 */ SyscallDesc("timer_settime", unimplementedFunc);
- /* 263 */ SyscallDesc("timer_gettime", unimplementedFunc);
- /* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc);
- /* 265 */ SyscallDesc("timer_delete", unimplementedFunc);
- /* 266 */ SyscallDesc("timer_create", unimplementedFunc);
- /* 267 */ SyscallDesc("vserver", unimplementedFunc);
- /* 268 */ SyscallDesc("io_setup", unimplementedFunc);
- /* 269 */ SyscallDesc("io_destroy", unimplementedFunc);
- /* 270 */ SyscallDesc("io_submit", unimplementedFunc);
- /* 271 */ SyscallDesc("io_cancel", unimplementedFunc);
- /* 272 */ SyscallDesc("io_getevents", unimplementedFunc);
- /* 273 */ SyscallDesc("mq_open", unimplementedFunc);
- /* 274 */ SyscallDesc("mq_unlink", unimplementedFunc);
- /* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc);
- /* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc);
- /* 277 */ SyscallDesc("mq_notify", unimplementedFunc);
- /* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc);
- /* 279 */ SyscallDesc("waitid", unimplementedFunc);
- /* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc);
- /* 281 */ SyscallDesc("add_key", unimplementedFunc);
- /* 282 */ SyscallDesc("request_key", unimplementedFunc);
- /* 283 */ SyscallDesc("keyctl", unimplementedFunc);
+ /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
+ /* 1 */ SyscallDesc("exit", exitFunc),
+ /* 2 */ SyscallDesc("fork", unimplementedFunc),
+ /* 3 */ SyscallDesc("read", readFunc),
+ /* 4 */ SyscallDesc("write", writeFunc),
+ /* 5 */ SyscallDesc("open", openFunc<Linux>),
+ /* 6 */ SyscallDesc("close", closeFunc),
+ /* 7 */ SyscallDesc("wait4", unimplementedFunc),
+ /* 8 */ SyscallDesc("creat", unimplementedFunc),
+ /* 9 */ SyscallDesc("link", unimplementedFunc),
+ /* 10 */ SyscallDesc("unlink", unlinkFunc),
+ /* 11 */ SyscallDesc("execv", unimplementedFunc),
+ /* 12 */ SyscallDesc("chdir", unimplementedFunc),
+ /* 13 */ SyscallDesc("chown", chownFunc),
+ /* 14 */ SyscallDesc("mknod", unimplementedFunc),
+ /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
+ /* 16 */ SyscallDesc("lchown", unimplementedFunc),
+ /* 17 */ SyscallDesc("brk", obreakFunc),
+ /* 18 */ SyscallDesc("perfctr", unimplementedFunc),
+ /* 19 */ SyscallDesc("lseek", lseekFunc),
+ /* 20 */ SyscallDesc("getpid", getpidFunc),
+ /* 21 */ SyscallDesc("capget", unimplementedFunc),
+ /* 22 */ SyscallDesc("capset", unimplementedFunc),
+ /* 23 */ SyscallDesc("setuid", setuidFunc),
+ /* 24 */ SyscallDesc("getuid", getuidFunc),
+ /* 25 */ SyscallDesc("time", unimplementedFunc),
+ /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
+ /* 27 */ SyscallDesc("alarm", unimplementedFunc),
+ /* 28 */ SyscallDesc("sigaltstack", unimplementedFunc),
+ /* 29 */ SyscallDesc("pause", unimplementedFunc),
+ /* 30 */ SyscallDesc("utime", unimplementedFunc),
+ /* 31 */ SyscallDesc("lchown32", unimplementedFunc),
+ /* 32 */ SyscallDesc("fchown32", unimplementedFunc),
+ /* 33 */ SyscallDesc("access", unimplementedFunc),
+ /* 34 */ SyscallDesc("nice", unimplementedFunc),
+ /* 35 */ SyscallDesc("chown32", unimplementedFunc),
+ /* 36 */ SyscallDesc("sync", unimplementedFunc),
+ /* 37 */ SyscallDesc("kill", unimplementedFunc),
+ /* 38 */ SyscallDesc("stat", unimplementedFunc),
+ /* 39 */ SyscallDesc("sendfile", unimplementedFunc),
+ /* 40 */ SyscallDesc("lstat", unimplementedFunc),
+ /* 41 */ SyscallDesc("dup", unimplementedFunc),
+ /* 42 */ SyscallDesc("pipe", pipePseudoFunc),
+ /* 43 */ SyscallDesc("times", unimplementedFunc),
+ /* 44 */ SyscallDesc("getuid32", unimplementedFunc),
+ /* 45 */ SyscallDesc("umount2", unimplementedFunc),
+ /* 46 */ SyscallDesc("setgid", unimplementedFunc),
+ /* 47 */ SyscallDesc("getgid", getgidFunc),
+ /* 48 */ SyscallDesc("signal", unimplementedFunc),
+ /* 49 */ SyscallDesc("geteuid", geteuidFunc),
+ /* 50 */ SyscallDesc("getegid", getegidFunc),
+ /* 51 */ SyscallDesc("acct", unimplementedFunc),
+ /* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
+ /* 53 */ SyscallDesc("getgid32", unimplementedFunc),
+ /* 54 */ SyscallDesc("ioctl", unimplementedFunc),
+ /* 55 */ SyscallDesc("reboot", unimplementedFunc),
+ /* 56 */ SyscallDesc("mmap2", unimplementedFunc),
+ /* 57 */ SyscallDesc("symlink", unimplementedFunc),
+ /* 58 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 59 */ SyscallDesc("execve", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", unimplementedFunc),
+ /* 61 */ SyscallDesc("chroot", unimplementedFunc),
+ /* 62 */ SyscallDesc("fstat", unimplementedFunc),
+ /* 63 */ SyscallDesc("fstat64", unimplementedFunc),
+ /* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
+ /* 65 */ SyscallDesc("msync", unimplementedFunc),
+ /* 66 */ SyscallDesc("vfork", unimplementedFunc),
+ /* 67 */ SyscallDesc("pread64", unimplementedFunc),
+ /* 68 */ SyscallDesc("pwrite64", unimplementedFunc),
+ /* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
+ /* 70 */ SyscallDesc("getdgid32", unimplementedFunc),
+ /* 71 */ SyscallDesc("mmap", unimplementedFunc),
+ /* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
+ /* 73 */ SyscallDesc("munmap", unimplementedFunc),
+ /* 74 */ SyscallDesc("mprotect", unimplementedFunc),
+ /* 75 */ SyscallDesc("madvise", unimplementedFunc),
+ /* 76 */ SyscallDesc("vhangup", unimplementedFunc),
+ /* 77 */ SyscallDesc("truncate64", unimplementedFunc),
+ /* 78 */ SyscallDesc("mincore", unimplementedFunc),
+ /* 79 */ SyscallDesc("getgroups", unimplementedFunc),
+ /* 80 */ SyscallDesc("setgroups", unimplementedFunc),
+ /* 81 */ SyscallDesc("getpgrp", unimplementedFunc),
+ /* 82 */ SyscallDesc("setgroups32", unimplementedFunc),
+ /* 83 */ SyscallDesc("setitimer", unimplementedFunc),
+ /* 84 */ SyscallDesc("ftruncate64", unimplementedFunc),
+ /* 85 */ SyscallDesc("swapon", unimplementedFunc),
+ /* 86 */ SyscallDesc("getitimer", unimplementedFunc),
+ /* 87 */ SyscallDesc("setuid32", unimplementedFunc),
+ /* 88 */ SyscallDesc("sethostname", unimplementedFunc),
+ /* 89 */ SyscallDesc("setgid32", unimplementedFunc),
+ /* 90 */ SyscallDesc("dup2", unimplementedFunc),
+ /* 91 */ SyscallDesc("setfsuid32", unimplementedFunc),
+ /* 92 */ SyscallDesc("fcntl", unimplementedFunc),
+ /* 93 */ SyscallDesc("select", unimplementedFunc),
+ /* 94 */ SyscallDesc("setfsgid32", unimplementedFunc),
+ /* 95 */ SyscallDesc("fsync", unimplementedFunc),
+ /* 96 */ SyscallDesc("setpriority", unimplementedFunc),
+ /* 97 */ SyscallDesc("socket", unimplementedFunc),
+ /* 98 */ SyscallDesc("connect", unimplementedFunc),
+ /* 99 */ SyscallDesc("accept", unimplementedFunc),
+ /* 100 */ SyscallDesc("getpriority", unimplementedFunc),
+ /* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
+ /* 102 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+ /* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
+ /* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc),
+ /* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+ /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
+ /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+ /* 108 */ SyscallDesc("setresuid", unimplementedFunc),
+ /* 109 */ SyscallDesc("getresuid", unimplementedFunc),
+ /* 110 */ SyscallDesc("setresgid", unimplementedFunc),
+ /* 111 */ SyscallDesc("getresgid", unimplementedFunc),
+ /* 112 */ SyscallDesc("setregid32", unimplementedFunc),
+ /* 113 */ SyscallDesc("recvmsg", unimplementedFunc),
+ /* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
+ /* 115 */ SyscallDesc("getgroups32", unimplementedFunc),
+ /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc),
+ /* 117 */ SyscallDesc("getrusage", unimplementedFunc),
+ /* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
+ /* 119 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 120 */ SyscallDesc("readv", unimplementedFunc),
+ /* 121 */ SyscallDesc("writev", unimplementedFunc),
+ /* 122 */ SyscallDesc("settimeofday", unimplementedFunc),
+ /* 123 */ SyscallDesc("fchown", unimplementedFunc),
+ /* 124 */ SyscallDesc("fchmod", unimplementedFunc),
+ /* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
+ /* 126 */ SyscallDesc("setreuid", unimplementedFunc),
+ /* 127 */ SyscallDesc("setregid", unimplementedFunc),
+ /* 128 */ SyscallDesc("rename", unimplementedFunc),
+ /* 129 */ SyscallDesc("truncate", unimplementedFunc),
+ /* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 131 */ SyscallDesc("flock", unimplementedFunc),
+ /* 132 */ SyscallDesc("lstat64", unimplementedFunc),
+ /* 133 */ SyscallDesc("sendto", unimplementedFunc),
+ /* 134 */ SyscallDesc("shutdown", unimplementedFunc),
+ /* 135 */ SyscallDesc("socketpair", unimplementedFunc),
+ /* 136 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 137 */ SyscallDesc("rmdir", unimplementedFunc),
+ /* 138 */ SyscallDesc("utimes", unimplementedFunc),
+ /* 139 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 140 */ SyscallDesc("sendfile64", unimplementedFunc),
+ /* 141 */ SyscallDesc("getpeername", unimplementedFunc),
+ /* 142 */ SyscallDesc("futex", unimplementedFunc),
+ /* 143 */ SyscallDesc("gettid", unimplementedFunc),
+ /* 144 */ SyscallDesc("getrlimit", unimplementedFunc),
+ /* 145 */ SyscallDesc("setrlimit", unimplementedFunc),
+ /* 146 */ SyscallDesc("pivot_root", unimplementedFunc),
+ /* 147 */ SyscallDesc("prctl", unimplementedFunc),
+ /* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc),
+ /* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc),
+ /* 150 */ SyscallDesc("getsockname", unimplementedFunc),
+ /* 151 */ SyscallDesc("inotify_init", unimplementedFunc),
+ /* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
+ /* 153 */ SyscallDesc("poll", unimplementedFunc),
+ /* 154 */ SyscallDesc("getdents64", unimplementedFunc),
+ /* 155 */ SyscallDesc("fcntl64", unimplementedFunc),
+ /* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
+ /* 157 */ SyscallDesc("statfs", unimplementedFunc),
+ /* 158 */ SyscallDesc("fstatfs", unimplementedFunc),
+ /* 159 */ SyscallDesc("umount", unimplementedFunc),
+ /* 160 */ SyscallDesc("sched_set_affinity", unimplementedFunc),
+ /* 161 */ SyscallDesc("sched_get_affinity", unimplementedFunc),
+ /* 162 */ SyscallDesc("getdomainname", unimplementedFunc),
+ /* 163 */ SyscallDesc("setdomainname", unimplementedFunc),
+ /* 164 */ SyscallDesc("utrap_install", unimplementedFunc),
+ /* 165 */ SyscallDesc("quotactl", unimplementedFunc),
+ /* 166 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 167 */ SyscallDesc("mount", unimplementedFunc),
+ /* 168 */ SyscallDesc("ustat", unimplementedFunc),
+ /* 169 */ SyscallDesc("setxattr", unimplementedFunc),
+ /* 170 */ SyscallDesc("lsetxattr", unimplementedFunc),
+ /* 171 */ SyscallDesc("fsetxattr", unimplementedFunc),
+ /* 172 */ SyscallDesc("getxattr", unimplementedFunc),
+ /* 173 */ SyscallDesc("lgetxattr", unimplementedFunc),
+ /* 174 */ SyscallDesc("getdents", unimplementedFunc),
+ /* 175 */ SyscallDesc("setsid", unimplementedFunc),
+ /* 176 */ SyscallDesc("fchdir", unimplementedFunc),
+ /* 177 */ SyscallDesc("fgetxattr", unimplementedFunc),
+ /* 178 */ SyscallDesc("listxattr", unimplementedFunc),
+ /* 179 */ SyscallDesc("llistxattr", unimplementedFunc),
+ /* 180 */ SyscallDesc("flistxattr", unimplementedFunc),
+ /* 181 */ SyscallDesc("removexattr", unimplementedFunc),
+ /* 182 */ SyscallDesc("lremovexattr", unimplementedFunc),
+ /* 183 */ SyscallDesc("sigpending", unimplementedFunc),
+ /* 184 */ SyscallDesc("query_module", unimplementedFunc),
+ /* 185 */ SyscallDesc("setpgid", unimplementedFunc),
+ /* 186 */ SyscallDesc("fremovexattr", unimplementedFunc),
+ /* 187 */ SyscallDesc("tkill", unimplementedFunc),
+ /* 188 */ SyscallDesc("exit_group", unimplementedFunc),
+ /* 189 */ SyscallDesc("uname", unameFunc),
+ /* 190 */ SyscallDesc("init_module", unimplementedFunc),
+ /* 191 */ SyscallDesc("personality", unimplementedFunc),
+ /* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+ /* 193 */ SyscallDesc("epoll_create", unimplementedFunc),
+ /* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc),
+ /* 195 */ SyscallDesc("epoll_wait", unimplementedFunc),
+ /* 196 */ SyscallDesc("ioprio_set", unimplementedFunc),
+ /* 197 */ SyscallDesc("getppid", getppidFunc),
+ /* 198 */ SyscallDesc("sigaction", unimplementedFunc),
+ /* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
+ /* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
+ /* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
+ /* 202 */ SyscallDesc("oldlstat", unimplementedFunc),
+ /* 203 */ SyscallDesc("uselib", unimplementedFunc),
+ /* 204 */ SyscallDesc("readdir", unimplementedFunc),
+ /* 205 */ SyscallDesc("readahead", unimplementedFunc),
+ /* 206 */ SyscallDesc("socketcall", unimplementedFunc),
+ /* 207 */ SyscallDesc("syslog", unimplementedFunc),
+ /* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
+ /* 209 */ SyscallDesc("fadvise64", unimplementedFunc),
+ /* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc),
+ /* 211 */ SyscallDesc("tgkill", unimplementedFunc),
+ /* 212 */ SyscallDesc("waitpid", unimplementedFunc),
+ /* 213 */ SyscallDesc("swapoff", unimplementedFunc),
+ /* 214 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 215 */ SyscallDesc("ipc", unimplementedFunc),
+ /* 216 */ SyscallDesc("sigreturn", unimplementedFunc),
+ /* 217 */ SyscallDesc("clone", unimplementedFunc),
+ /* 218 */ SyscallDesc("ioprio_get", unimplementedFunc),
+ /* 219 */ SyscallDesc("adjtimex", unimplementedFunc),
+ /* 220 */ SyscallDesc("sigprocmask", unimplementedFunc),
+ /* 221 */ SyscallDesc("create_module", unimplementedFunc),
+ /* 222 */ SyscallDesc("delete_module", unimplementedFunc),
+ /* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
+ /* 224 */ SyscallDesc("getpgid", unimplementedFunc),
+ /* 225 */ SyscallDesc("bdflush", unimplementedFunc),
+ /* 226 */ SyscallDesc("sysfs", unimplementedFunc),
+ /* 227 */ SyscallDesc("afs_syscall", unimplementedFunc),
+ /* 228 */ SyscallDesc("setfsuid", unimplementedFunc),
+ /* 229 */ SyscallDesc("setfsgid", unimplementedFunc),
+ /* 230 */ SyscallDesc("_newselect", unimplementedFunc),
+ /* 231 */ SyscallDesc("time", unimplementedFunc),
+ /* 232 */ SyscallDesc("oldstat", unimplementedFunc),
+ /* 233 */ SyscallDesc("stime", unimplementedFunc),
+ /* 234 */ SyscallDesc("statfs64", unimplementedFunc),
+ /* 235 */ SyscallDesc("fstatfs64", unimplementedFunc),
+ /* 236 */ SyscallDesc("_llseek", unimplementedFunc),
+ /* 237 */ SyscallDesc("mlock", unimplementedFunc),
+ /* 238 */ SyscallDesc("munlock", unimplementedFunc),
+ /* 239 */ SyscallDesc("mlockall", unimplementedFunc),
+ /* 240 */ SyscallDesc("munlockall", unimplementedFunc),
+ /* 241 */ SyscallDesc("sched_setparam", unimplementedFunc),
+ /* 242 */ SyscallDesc("sched_getparam", unimplementedFunc),
+ /* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
+ /* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
+ /* 245 */ SyscallDesc("sched_yield", unimplementedFunc),
+ /* 246 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
+ /* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
+ /* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
+ /* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
+ /* 250 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 251 */ SyscallDesc("_sysctl", unimplementedFunc),
+ /* 252 */ SyscallDesc("getsid", unimplementedFunc),
+ /* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
+ /* 254 */ SyscallDesc("nfsservctl", unimplementedFunc),
+ /* 255 */ SyscallDesc("aplib", unimplementedFunc),
+ /* 256 */ SyscallDesc("clock_settime", unimplementedFunc),
+ /* 257 */ SyscallDesc("clock_gettime", unimplementedFunc),
+ /* 258 */ SyscallDesc("clock_getres", unimplementedFunc),
+ /* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
+ /* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 262 */ SyscallDesc("timer_settime", unimplementedFunc),
+ /* 263 */ SyscallDesc("timer_gettime", unimplementedFunc),
+ /* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+ /* 265 */ SyscallDesc("timer_delete", unimplementedFunc),
+ /* 266 */ SyscallDesc("timer_create", unimplementedFunc),
+ /* 267 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 268 */ SyscallDesc("io_setup", unimplementedFunc),
+ /* 269 */ SyscallDesc("io_destroy", unimplementedFunc),
+ /* 270 */ SyscallDesc("io_submit", unimplementedFunc),
+ /* 271 */ SyscallDesc("io_cancel", unimplementedFunc),
+ /* 272 */ SyscallDesc("io_getevents", unimplementedFunc),
+ /* 273 */ SyscallDesc("mq_open", unimplementedFunc),
+ /* 274 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 277 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 279 */ SyscallDesc("waitid", unimplementedFunc),
+ /* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc),
+ /* 281 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 282 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 283 */ SyscallDesc("keyctl", unimplementedFunc)
};
SparcLinuxProcess::SparcLinuxProcess(const std::string &name,
ObjectFile *objFile,
+ System * system,
int stdin_fd,
int stdout_fd,
int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp)
- : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp),
+ : SparcLiveProcess(name, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd, argv, envp),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
// The sparc syscall table must be <= 283 entries because that is all there
// is space for.
assert(Num_Syscall_Descs <= 283);
-
- init_regs->intRegFile[0] = 0;
}
SyscallDesc*
-AlphaLinuxProcess::getDesc(int callnum)
+SparcLinuxProcess::getDesc(int callnum)
{
if (callnum < 0 || callnum > Num_Syscall_Descs)
return NULL;
diff --git a/arch/sparc/linux/process.hh b/arch/sparc/linux/process.hh
index c41406b4b..1565ab549 100644
--- a/arch/sparc/linux/process.hh
+++ b/arch/sparc/linux/process.hh
@@ -29,16 +29,19 @@
#ifndef __SPARC_LINUX_PROCESS_HH__
#define __SPARC_LINUX_PROCESS_HH__
+#include "arch/sparc/process.hh"
#include "sim/process.hh"
+namespace SparcISA {
/// A process with emulated SPARC/Linux syscalls.
-class SparcLinuxProcess : public LiveProcess
+class SparcLinuxProcess : public SparcLiveProcess
{
public:
/// Constructor.
SparcLinuxProcess(const std::string &name,
ObjectFile *objFile,
+ System * system,
int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp);
@@ -54,5 +57,5 @@ class SparcLinuxProcess : public LiveProcess
const int Num_Syscall_Descs;
};
-
+} // namespace SparcISA
#endif // __ALPHA_LINUX_PROCESS_HH__
diff --git a/arch/sparc/process.cc b/arch/sparc/process.cc
index 53a215379..c7e08358d 100644
--- a/arch/sparc/process.cc
+++ b/arch/sparc/process.cc
@@ -26,22 +26,36 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
+#include "arch/sparc/linux/process.hh"
+#include "base/loader/object_file.hh"
+#include "base/misc.hh"
+#include "cpu/exec_context.hh"
+#include "sim/builder.hh"
+#include "sim/system.hh"
-namespace SparcISA
-{
+using namespace std;
+using namespace SparcISA;
-LiveProcess *
-createProcess(const string &nm, ObjectFile * objFile,
- int stdin_fd, int stdout_fd, int stderr_fd,
- vector<string> &argv, vector<string> &envp)
+SparcLiveProcess *
+SparcLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
+ int stdout_fd, int stderr_fd, std::string executable,
+ std::vector<std::string> &argv, std::vector<std::string> &envp)
{
- LiveProcess * process = NULL;
+ SparcLiveProcess *process = NULL;
+
+ ObjectFile *objFile = createObjectFile(executable);
+ if (objFile == NULL) {
+ fatal("Can't load object file %s", executable);
+ }
+
+
if (objFile->getArch() != ObjectFile::SPARC)
fatal("Object file does not match architecture.");
switch (objFile->getOpSys()) {
case ObjectFile::Linux:
- process = new SparcLinuxProcess(nm, objFile,
+ process = new SparcLinuxProcess(nm, objFile, system,
stdin_fd, stdout_fd, stderr_fd,
argv, envp);
break;
@@ -50,7 +64,98 @@ createProcess(const string &nm, ObjectFile * objFile,
default:
fatal("Unknown/unsupported operating system.");
}
+
+ if (process == NULL)
+ fatal("Unknown error creating process object.");
return process;
}
-} // namespace SparcISA
+SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv, std::vector<std::string> &envp)
+ : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp)
+{
+
+ // XXX all the below need to be updated for SPARC - Ali
+ brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
+ brk_point = roundUp(brk_point, VMPageSize);
+
+ // Set up stack. On Alpha, stack goes below text section. This
+ // code should get moved to some architecture-specific spot.
+ stack_base = objFile->textBase() - (409600+4096);
+
+ // Set up region for mmaps. Tru64 seems to start just above 0 and
+ // grow up from there.
+ mmap_start = mmap_end = 0x10000;
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+}
+
+void
+SparcLiveProcess::startup()
+{
+ argsInit(MachineBytes, VMPageSize);
+}
+
+
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcLiveProcess)
+
+ VectorParam<string> cmd;
+ Param<string> executable;
+ Param<string> input;
+ Param<string> output;
+ VectorParam<string> env;
+ SimObjectParam<System *> system;
+
+END_DECLARE_SIM_OBJECT_PARAMS(SparcLiveProcess)
+
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(SparcLiveProcess)
+
+ INIT_PARAM(cmd, "command line (executable plus arguments)"),
+ INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
+ INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
+ INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
+ INIT_PARAM(env, "environment settings"),
+ INIT_PARAM(system, "system")
+
+END_INIT_SIM_OBJECT_PARAMS(SparcLiveProcess)
+
+
+CREATE_SIM_OBJECT(SparcLiveProcess)
+{
+ string in = input;
+ string out = output;
+
+ // initialize file descriptors to default: same as simulator
+ int stdin_fd, stdout_fd, stderr_fd;
+
+ if (in == "stdin" || in == "cin")
+ stdin_fd = STDIN_FILENO;
+ else
+ stdin_fd = Process::openInputFile(input);
+
+ if (out == "stdout" || out == "cout")
+ stdout_fd = STDOUT_FILENO;
+ else if (out == "stderr" || out == "cerr")
+ stdout_fd = STDERR_FILENO;
+ else
+ stdout_fd = Process::openOutputFile(out);
+
+ stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
+
+ return SparcLiveProcess::create(getInstanceName(), system,
+ stdin_fd, stdout_fd, stderr_fd,
+ (string)executable == "" ? cmd[0] : executable,
+ cmd, env);
+}
+
+
+REGISTER_SIM_OBJECT("SparcLiveProcess", SparcLiveProcess)
+
+
diff --git a/arch/sparc/process.hh b/arch/sparc/process.hh
index 48041a316..cc4d0ae0a 100644
--- a/arch/sparc/process.hh
+++ b/arch/sparc/process.hh
@@ -29,17 +29,34 @@
#ifndef __SPARC_PROCESS_HH__
#define __SPARC_PROCESS_HH__
-#include "arch/sparc/linux/process.hh"
-#include "base/loader/object_file.hh"
+#include <string>
+#include <vector>
+#include "sim/process.hh"
-namespace SparcISA
+class ObjectFile;
+class System;
+
+class SparcLiveProcess : public LiveProcess
{
+ protected:
+ SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
+
+ void startup();
-LiveProcess *
-createProcess(const string &nm, ObjectFile * objFile,
- int stdin_fd, int stdout_fd, int stderr_fd,
- vector<string> &argv, vector<string> &envp);
+ public:
+ // this function is used to create the LiveProcess object, since
+ // we can't tell which subclass of LiveProcess to use until we
+ // open and look at the object file.
+ static SparcLiveProcess *create(const std::string &nm,
+ System *_system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::string executable,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
-} // namespace SparcISA
+};
#endif // __SPARC_PROCESS_HH__
diff --git a/arch/sparc/regfile.hh b/arch/sparc/regfile.hh
new file mode 100644
index 000000000..944fdfe80
--- /dev/null
+++ b/arch/sparc/regfile.hh
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ */
+
+#ifndef __ARCH_SPARC_REGFILE_HH__
+#define __ARCH_SPARC_REGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "sim/byteswap.hh"
+#include "sim/host.hh"
+
+class Checkpoint;
+
+namespace SparcISA
+{
+
+ typedef uint8_t RegIndex;
+
+ // Maximum trap level
+ const int MaxTL = 4;
+
+ //For right now, let's pretend the register file is flat
+ typedef IntReg IntRegFile[NumIntRegs];
+
+ typedef float float32_t;
+ typedef double float64_t;
+ //FIXME long double refers to a 10 byte float, rather than a
+ //16 byte float as required. This data type may have to be emulated.
+ typedef double float128_t;
+
+ class FloatRegFile
+ {
+ protected:
+ //Since the floating point registers overlap each other,
+ //A generic storage space is used. The float to be returned is
+ //pulled from the appropriate section of this region.
+ char regSpace[32 * 64];
+
+ static const int SingleWidth = 32;
+ static const int DoubleWidth = 64;
+ static const int QuadWidth = 128;
+
+ public:
+
+ FloatReg readReg(int floatReg, int width)
+ {
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ float32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, width);
+ return htog(result32);
+ case DoubleWidth:
+ float64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, width);
+ return htog(result64);
+ case QuadWidth:
+ float128_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, width);
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ }
+
+ FloatReg readReg(int floatReg)
+ {
+ //Use the "natural" width of a single float
+ return readReg(floatReg, SingleWidth);
+ }
+
+ FloatRegBits readRegBits(int floatReg, int width)
+ {
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ uint32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, width);
+ return htog(result32);
+ case DoubleWidth:
+ uint64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, width);
+ return htog(result64);
+ case QuadWidth:
+ uint64_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, width);
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ }
+
+ FloatRegBits readRegBits(int floatReg)
+ {
+ //Use the "natural" width of a single float
+ return readRegBits(floatReg, SingleWidth);
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val, int width)
+ {
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ uint32_t result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, width);
+ case DoubleWidth:
+ uint64_t result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, width);
+ case QuadWidth:
+ uint64_t result128 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result128, width);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val)
+ {
+ //Use the "natural" width of a single float
+ return setReg(floatReg, val, SingleWidth);
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ uint32_t result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, width);
+ case DoubleWidth:
+ uint64_t result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, width);
+ case QuadWidth:
+ uint64_t result128 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result128, width);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val)
+ {
+ //Use the "natural" width of a single float
+ return setReg(floatReg, val, SingleWidth);
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+
+ enum MiscRegIndex
+ {
+ MISCREG_PSTATE,
+ MISCREG_PSTATE_AG,
+ MISCREG_PSTATE_IE,
+ MISCREG_PSTATE_PRIV,
+ MISCREG_PSTATE_AM,
+ MISCREG_PSTATE_PEF,
+ MISCREG_PSTATE_RED,
+ MISCREG_PSTATE_MM,
+ MISCREG_PSTATE_TLE,
+ MISCREG_PSTATE_CLE,
+ MISCREG_TBA,
+ MISCREG_Y,
+ MISCREG_Y_VALUE,
+ MISCREG_PIL,
+ MISCREG_CWP,
+ MISCREG_TT_BASE,
+ MISCREG_TT_END = MISCREG_TT_BASE + MaxTL,
+ MISCREG_CCR,
+ MISCREG_CCR_ICC,
+ MISCREG_CCR_ICC_C,
+ MISCREG_CCR_ICC_V,
+ MISCREG_CCR_ICC_Z,
+ MISCREG_CCR_ICC_N,
+ MISCREG_CCR_XCC,
+ MISCREG_CCR_XCC_C,
+ MISCREG_CCR_XCC_V,
+ MISCREG_CCR_XCC_Z,
+ MISCREG_CCR_XCC_N,
+ MISCREG_ASI,
+ MISCREG_TL,
+ MISCREG_TPC_BASE,
+ MISCREG_TPC_END = MISCREG_TPC_BASE + MaxTL,
+ MISCREG_TNPC_BASE,
+ MISCREG_TNPC_END = MISCREG_TNPC_BASE + MaxTL,
+ MISCREG_TSTATE_BASE,
+ MISCREG_TSTATE_END = MISCREG_TSTATE_BASE + MaxTL,
+ MISCREG_TSTATE_CWP_BASE,
+ MISCREG_TSTATE_CWP_END = MISCREG_TSTATE_CWP_BASE + MaxTL,
+ MISCREG_TSTATE_PSTATE_BASE,
+ MISCREG_TSTATE_PSTATE_END = MISCREG_TSTATE_PSTATE_BASE + MaxTL,
+ MISCREG_TSTATE_ASI_BASE,
+ MISCREG_TSTATE_ASI_END = MISCREG_TSTATE_ASI_BASE + MaxTL,
+ MISCREG_TSTATE_CCR_BASE,
+ MISCREG_TSTATE_CCR_END = MISCREG_TSTATE_CCR_BASE + MaxTL,
+ MISCREG_TICK,
+ MISCREG_TICK_COUNTER,
+ MISCREG_TICK_NPT,
+ MISCREG_CANSAVE,
+ MISCREG_CANRESTORE,
+ MISCREG_OTHERWIN,
+ MISCREG_CLEANWIN,
+ MISCREG_WSTATE,
+ MISCREG_WSTATE_NORMAL,
+ MISCREG_WSTATE_OTHER,
+ MISCREG_VER,
+ MISCREG_VER_MAXWIN,
+ MISCREG_VER_MAXTL,
+ MISCREG_VER_MASK,
+ MISCREG_VER_IMPL,
+ MISCREG_VER_MANUF,
+ MISCREG_FSR,
+ MISCREG_FSR_CEXC,
+ MISCREG_FSR_CEXC_NXC,
+ MISCREG_FSR_CEXC_DZC,
+ MISCREG_FSR_CEXC_UFC,
+ MISCREG_FSR_CEXC_OFC,
+ MISCREG_FSR_CEXC_NVC,
+ MISCREG_FSR_AEXC,
+ MISCREG_FSR_AEXC_NXC,
+ MISCREG_FSR_AEXC_DZC,
+ MISCREG_FSR_AEXC_UFC,
+ MISCREG_FSR_AEXC_OFC,
+ MISCREG_FSR_AEXC_NVC,
+ MISCREG_FSR_FCC0,
+ MISCREG_FSR_QNE,
+ MISCREG_FSR_FTT,
+ MISCREG_FSR_VER,
+ MISCREG_FSR_NS,
+ MISCREG_FSR_TEM,
+ MISCREG_FSR_TEM_NXM,
+ MISCREG_FSR_TEM_DZM,
+ MISCREG_FSR_TEM_UFM,
+ MISCREG_FSR_TEM_OFM,
+ MISCREG_FSR_TEM_NVM,
+ MISCREG_FSR_RD,
+ MISCREG_FSR_FCC1,
+ MISCREG_FSR_FCC2,
+ MISCREG_FSR_FCC3,
+ MISCREG_FPRS,
+ MISCREG_FPRS_DL,
+ MISCREG_FPRS_DU,
+ MISCREG_FPRS_FEF,
+ numMiscRegs
+ };
+
+ // The control registers, broken out into fields
+ class MiscRegFile
+ {
+ private:
+ union
+ {
+ uint16_t pstate; // Process State Register
+ struct
+ {
+ uint16_t ag:1; // Alternate Globals
+ uint16_t ie:1; // Interrupt enable
+ uint16_t priv:1; // Privelege mode
+ uint16_t am:1; // Address mask
+ uint16_t pef:1; // PSTATE enable floating-point
+ uint16_t red:1; // RED (reset, error, debug) state
+ uint16_t mm:2; // Memory Model
+ uint16_t tle:1; // Trap little-endian
+ uint16_t cle:1; // Current little-endian
+ } pstateFields;
+ };
+ uint64_t tba; // Trap Base Address
+ union
+ {
+ uint64_t y; // Y (used in obsolete multiplication)
+ struct
+ {
+ uint64_t value:32; // The actual value stored in y
+ uint64_t :32; // reserved bits
+ } yFields;
+ };
+ uint8_t pil; // Process Interrupt Register
+ uint8_t cwp; // Current Window Pointer
+ uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
+ // on the previous level)
+ union
+ {
+ uint8_t ccr; // Condition Code Register
+ struct
+ {
+ union
+ {
+ uint8_t icc:4; // 32-bit condition codes
+ struct
+ {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } iccFields;
+ };
+ union
+ {
+ uint8_t xcc:4; // 64-bit condition codes
+ struct
+ {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } xccFields;
+ };
+ } ccrFields;
+ };
+ uint8_t asi; // Address Space Identifier
+ uint8_t tl; // Trap Level
+ uint64_t tpc[MaxTL]; // Trap Program Counter (value from
+ // previous trap level)
+ uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
+ // previous trap level)
+ union
+ {
+ uint64_t tstate[MaxTL]; // Trap State
+ struct
+ {
+ //Values are from previous trap level
+ uint64_t cwp:5; // Current Window Pointer
+ uint64_t :2; // Reserved bits
+ uint64_t pstate:10; // Process State
+ uint64_t :6; // Reserved bits
+ uint64_t asi:8; // Address Space Identifier
+ uint64_t ccr:8; // Condition Code Register
+ } tstateFields[MaxTL];
+ };
+ union
+ {
+ uint64_t tick; // Hardware clock-tick counter
+ struct
+ {
+ uint64_t counter:63; // Clock-tick count
+ uint64_t npt:1; // Non-priveleged trap
+ } tickFields;
+ };
+ uint8_t cansave; // Savable windows
+ uint8_t canrestore; // Restorable windows
+ uint8_t otherwin; // Other windows
+ uint8_t cleanwin; // Clean windows
+ union
+ {
+ uint8_t wstate; // Window State
+ struct
+ {
+ uint8_t normal:3; // Bits TT<4:2> are set to on a normal
+ // register window trap
+ uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
+ // register window trap
+ } wstateFields;
+ };
+ union
+ {
+ uint64_t ver; // Version
+ struct
+ {
+ uint64_t maxwin:5; // Max CWP value
+ uint64_t :2; // Reserved bits
+ uint64_t maxtl:8; // Maximum trap level
+ uint64_t :8; // Reserved bits
+ uint64_t mask:8; // Processor mask set revision number
+ uint64_t impl:16; // Implementation identification number
+ uint64_t manuf:16; // Manufacturer code
+ } verFields;
+ };
+ union
+ {
+ uint64_t fsr; // Floating-Point State Register
+ struct
+ {
+ union
+ {
+ uint64_t cexc:5; // Current excpetion
+ struct
+ {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } cexcFields;
+ };
+ union
+ {
+ uint64_t aexc:5; // Accrued exception
+ struct
+ {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } aexcFields;
+ };
+ uint64_t fcc0:2; // Floating-Point condtion codes
+ uint64_t :1; // Reserved bits
+ uint64_t qne:1; // Deferred trap queue not empty
+ // with no queue, it should read 0
+ uint64_t ftt:3; // Floating-Point trap type
+ uint64_t ver:3; // Version (of the FPU)
+ uint64_t :2; // Reserved bits
+ uint64_t ns:1; // Nonstandard floating point
+ union
+ {
+ uint64_t tem:5; // Trap Enable Mask
+ struct
+ {
+ uint64_t nxm:1; // Inexact
+ uint64_t dzm:1; // Divide by zero
+ uint64_t ufm:1; // Underflow
+ uint64_t ofm:1; // Overflow
+ uint64_t nvm:1; // Invalid operand
+ } temFields;
+ };
+ uint64_t :2; // Reserved bits
+ uint64_t rd:2; // Rounding direction
+ uint64_t fcc1:2; // Floating-Point condition codes
+ uint64_t fcc2:2; // Floating-Point condition codes
+ uint64_t fcc3:2; // Floating-Point condition codes
+ uint64_t :26; // Reserved bits
+ } fsrFields;
+ };
+ union
+ {
+ uint8_t fprs; // Floating-Point Register State
+ struct
+ {
+ uint8_t dl:1; // Dirty lower
+ uint8_t du:1; // Dirty upper
+ uint8_t fef:1; // FPRS enable floating-Point
+ } fprsFields;
+ };
+
+ public:
+ MiscReg readReg(int miscReg);
+
+ MiscReg readRegWithEffect(int miscReg, Fault &fault, ExecContext *xc);
+
+ Fault setReg(int miscReg, const MiscReg &val);
+
+ Fault setRegWithEffect(int miscReg, const MiscReg &val,
+ ExecContext *xc);
+
+ void serialize(std::ostream & os);
+
+ void unserialize(Checkpoint * cp, const std::string & section);
+
+ void copyMiscRegs(ExecContext * xc);
+ };
+
+ typedef union
+ {
+ IntReg intreg;
+ FloatReg fpreg;
+ MiscReg ctrlreg;
+ } AnyReg;
+
+ struct RegFile
+ {
+ IntRegFile intRegFile; // (signed) integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegs; // control register file
+
+ Addr pc; // Program Counter
+ Addr npc; // Next Program Counter
+ Addr nnpc;
+
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+
+ void copyRegs(ExecContext *src, ExecContext *dest);
+
+ void copyMiscRegs(ExecContext *src, ExecContext *dest);
+
+} // namespace SparcISA
+
+#endif
diff --git a/base/chunk_generator.hh b/base/chunk_generator.hh
new file mode 100644
index 000000000..1dca50db4
--- /dev/null
+++ b/base/chunk_generator.hh
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2001-2005 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.
+ */
+
+#ifndef __BASE__CHUNK_GENERATOR_HH__
+#define __BASE__CHUNK_GENERATOR_HH__
+
+/**
+ * @file
+ * Declaration and inline definition of ChunkGenerator object.
+ */
+
+#include <algorithm>
+#include "base/intmath.hh"
+#include "arch/isa_traits.hh" // for Addr
+
+/**
+ * This class takes an arbitrary memory region (address/length pair)
+ * and generates a series of appropriately (e.g. block- or page-)
+ * aligned chunks covering the same region.
+ *
+ * Example usage:
+
+\code
+ for (ChunkGenerator gen(addr, size, chunkSize); !gen.done(); gen.next()) {
+ doSomethingChunky(gen.addr(), gen.size());
+ }
+\endcode
+ */
+class ChunkGenerator
+{
+ private:
+ /** The starting address of the current chunk. */
+ Addr curAddr;
+ /** The starting address of the next chunk (after the current one). */
+ Addr nextAddr;
+ /** The size of the current chunk (in bytes). */
+ int curSize;
+ /** The number of bytes remaining in the region after the current chunk. */
+ int sizeLeft;
+ /** The maximum chunk size, e.g., the cache block size or page size. */
+ const int chunkSize;
+
+ public:
+ /**
+ * Constructor.
+ * @param startAddr The starting address of the region.
+ * @param totalSize The total size of the region.
+ * @param _chunkSize The size/alignment of chunks into which
+ * the region should be decomposed.
+ */
+ ChunkGenerator(Addr startAddr, int totalSize, int _chunkSize)
+ : chunkSize(_chunkSize)
+ {
+ // chunkSize must be a power of two
+ assert(chunkSize == 0 || isPowerOf2(chunkSize));
+
+ // set up initial chunk.
+ curAddr = startAddr;
+
+ if (chunkSize == 0) //Special Case, if we see 0, assume no chuncking
+ {
+ nextAddr = startAddr + totalSize;
+ }
+ else
+ {
+ // nextAddr should be *next* chunk start
+ nextAddr = roundUp(startAddr, chunkSize);
+ if (curAddr == nextAddr) {
+ // ... even if startAddr is already chunk-aligned
+ nextAddr += chunkSize;
+ }
+ }
+
+ // how many bytes are left between curAddr and the end of this chunk?
+ int left_in_chunk = nextAddr - curAddr;
+ curSize = std::min(totalSize, left_in_chunk);
+ sizeLeft = totalSize - curSize;
+ }
+
+ /** Return starting address of current chunk. */
+ Addr addr() { return curAddr; }
+ /** Return size in bytes of current chunk. */
+ int size() { return curSize; }
+
+ /**
+ * Are we done? That is, did the last call to next() advance
+ * past the end of the region?
+ * @return True if yes, false if more to go.
+ */
+ bool done() { return (curSize == 0); }
+
+ /**
+ * Advance generator to next chunk.
+ * @return True if successful, false if unsuccessful
+ * (because we were at the last chunk).
+ */
+ bool next()
+ {
+ if (sizeLeft == 0) {
+ curSize = 0;
+ return false;
+ }
+
+ curAddr = nextAddr;
+ curSize = std::min(sizeLeft, chunkSize);
+ sizeLeft -= curSize;
+ nextAddr += curSize;
+ return true;
+ }
+};
+
+#endif // __BASE__CHUNK_GENERATOR_HH__
diff --git a/base/intmath.hh b/base/intmath.hh
index df0687c62..51baddb91 100644
--- a/base/intmath.hh
+++ b/base/intmath.hh
@@ -186,9 +186,9 @@ roundUp(T val, int align)
template <class T>
inline T
-roundDown(T val, T align)
+roundDown(T val, int align)
{
- T mask = align - 1;
+ T mask = (T)align - 1;
return val & ~mask;
}
diff --git a/base/loader/aout_object.cc b/base/loader/aout_object.cc
index c81f7123f..564898ca3 100644
--- a/base/loader/aout_object.cc
+++ b/base/loader/aout_object.cc
@@ -30,7 +30,6 @@
#include "base/loader/aout_object.hh"
-#include "mem/functional/functional.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh" // for DPRINTF
@@ -64,12 +63,15 @@ AoutObject::AoutObject(const string &_filename, int _fd,
text.baseAddr = N_TXTADDR(*execHdr);
text.size = execHdr->tsize;
+ text.fileImage = fileData + N_TXTOFF(*execHdr);
data.baseAddr = N_DATADDR(*execHdr);
data.size = execHdr->dsize;
+ data.fileImage = fileData + N_DATOFF(*execHdr);
bss.baseAddr = N_BSSADDR(*execHdr);
bss.size = execHdr->bsize;
+ bss.fileImage = NULL;
DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
text.baseAddr, text.size, data.baseAddr, data.size,
@@ -78,28 +80,6 @@ AoutObject::AoutObject(const string &_filename, int _fd,
bool
-AoutObject::loadSections(FunctionalMemory *mem, bool loadPhys)
-{
- Addr textAddr = text.baseAddr;
- Addr dataAddr = data.baseAddr;
-
- if (loadPhys) {
- textAddr &= (ULL(1) << 40) - 1;
- dataAddr &= (ULL(1) << 40) - 1;
- }
-
- // Since we don't really have an MMU and all memory is
- // zero-filled, there's no need to set up the BSS segment.
- if (text.size != 0)
- mem->prot_write(textAddr, fileData + N_TXTOFF(*execHdr), text.size);
- if (data.size != 0)
- mem->prot_write(dataAddr, fileData + N_DATOFF(*execHdr), data.size);
-
- return true;
-}
-
-
-bool
AoutObject::loadGlobalSymbols(SymbolTable *symtab)
{
// a.out symbols not supported yet
diff --git a/base/loader/aout_object.hh b/base/loader/aout_object.hh
index 1868192b2..aeb710427 100644
--- a/base/loader/aout_object.hh
+++ b/base/loader/aout_object.hh
@@ -46,8 +46,6 @@ class AoutObject : public ObjectFile
public:
virtual ~AoutObject() {}
- virtual bool loadSections(FunctionalMemory *mem,
- bool loadPhys = false);
virtual bool loadGlobalSymbols(SymbolTable *symtab);
virtual bool loadLocalSymbols(SymbolTable *symtab);
diff --git a/base/loader/ecoff_object.cc b/base/loader/ecoff_object.cc
index 353a5f333..80917ee9c 100644
--- a/base/loader/ecoff_object.cc
+++ b/base/loader/ecoff_object.cc
@@ -29,8 +29,7 @@
#include <string>
#include "base/loader/ecoff_object.hh"
-
-#include "mem/functional/functional.hh"
+#include "base/misc.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh" // for DPRINTF
@@ -68,12 +67,15 @@ EcoffObject::EcoffObject(const string &_filename, int _fd,
text.baseAddr = aoutHdr->text_start;
text.size = aoutHdr->tsize;
+ text.fileImage = fileData + ECOFF_TXTOFF(execHdr);
data.baseAddr = aoutHdr->data_start;
data.size = aoutHdr->dsize;
+ data.fileImage = fileData + ECOFF_DATOFF(execHdr);
bss.baseAddr = aoutHdr->bss_start;
bss.size = aoutHdr->bsize;
+ bss.fileImage = NULL;
DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
text.baseAddr, text.size, data.baseAddr, data.size,
@@ -82,26 +84,6 @@ EcoffObject::EcoffObject(const string &_filename, int _fd,
bool
-EcoffObject::loadSections(FunctionalMemory *mem, bool loadPhys)
-{
- Addr textAddr = text.baseAddr;
- Addr dataAddr = data.baseAddr;
-
- if (loadPhys) {
- textAddr &= (ULL(1) << 40) - 1;
- dataAddr &= (ULL(1) << 40) - 1;
- }
-
- // Since we don't really have an MMU and all memory is
- // zero-filled, there's no need to set up the BSS segment.
- mem->prot_write(textAddr, fileData + ECOFF_TXTOFF(execHdr), text.size);
- mem->prot_write(dataAddr, fileData + ECOFF_DATOFF(execHdr), data.size);
-
- return true;
-}
-
-
-bool
EcoffObject::loadGlobalSymbols(SymbolTable *symtab)
{
if (!symtab)
diff --git a/base/loader/ecoff_object.hh b/base/loader/ecoff_object.hh
index 78aa7f3f7..603c70bec 100644
--- a/base/loader/ecoff_object.hh
+++ b/base/loader/ecoff_object.hh
@@ -50,8 +50,6 @@ class EcoffObject : public ObjectFile
public:
virtual ~EcoffObject() {}
- virtual bool loadSections(FunctionalMemory *mem,
- bool loadPhys = false);
virtual bool loadGlobalSymbols(SymbolTable *symtab);
virtual bool loadLocalSymbols(SymbolTable *symtab);
diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc
index 791c6f6de..58029bc3e 100644
--- a/base/loader/elf_object.cc
+++ b/base/loader/elf_object.cc
@@ -42,12 +42,14 @@
#include "libelf/gelf.h"
#include "base/loader/elf_object.hh"
+#include "base/misc.hh"
-#include "mem/functional/functional.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh" // for DPRINTF
+#include "sim/byteswap.hh"
+
using namespace std;
@@ -73,8 +75,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
DPRINTFR(Loader, "Not ELF\n");
elf_end(elf);
return NULL;
- }
- else {
+ } else {
//Detect the architecture
//Versioning issues in libelf need to be resolved to get the correct
//SPARC constants.
@@ -90,7 +91,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
arch = ObjectFile::SPARC;
} else if (ehdr.e_machine == EM_MIPS
&& ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
- arch = ObjectFile::MIPS;
+ arch = ObjectFile::Mips;
} else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
arch = ObjectFile::Alpha;
} else {
@@ -154,6 +155,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
section = elf_getscn(elf, ++secIdx);
} // while sections
}
+
elf_end(elf);
return new ElfObject(fname, fd, len, data, arch, opSys);
}
@@ -185,6 +187,7 @@ ElfObject::ElfObject(const string &_filename, int _fd,
entry = ehdr.e_entry;
+
// initialize segment sizes to 0 in case they're not present
text.size = data.size = bss.size = 0;
@@ -203,20 +206,18 @@ ElfObject::ElfObject(const string &_filename, int _fd,
if (text.size == 0) { // haven't seen text segment yet
text.baseAddr = phdr.p_vaddr;
text.size = phdr.p_filesz;
- // remember where the data is for loadSections()
- fileTextBits = fileData + phdr.p_offset;
+ text.fileImage = fileData + phdr.p_offset;
// if there's any padding at the end that's not in the
// file, call it the bss. This happens in the "text"
// segment if there's only one loadable segment (as for
// kernel images).
bss.size = phdr.p_memsz - phdr.p_filesz;
bss.baseAddr = phdr.p_vaddr + phdr.p_filesz;
- }
- else if (data.size == 0) { // have text, this must be data
+ bss.fileImage = NULL;
+ } else if (data.size == 0) { // have text, this must be data
data.baseAddr = phdr.p_vaddr;
data.size = phdr.p_filesz;
- // remember where the data is for loadSections()
- fileDataBits = fileData + phdr.p_offset;
+ data.fileImage = fileData + phdr.p_offset;
// if there's any padding at the end that's not in the
// file, call it the bss. Warn if this happens for both
// the text & data segments (should only have one bss).
@@ -225,6 +226,11 @@ ElfObject::ElfObject(const string &_filename, int _fd,
}
bss.size = phdr.p_memsz - phdr.p_filesz;
bss.baseAddr = phdr.p_vaddr + phdr.p_filesz;
+ bss.fileImage = NULL;
+ } else {
+ warn("More than two loadable segments in ELF object.");
+ warn("Ignoring segment @ 0x%x length 0x%x.",
+ phdr.p_vaddr, phdr.p_filesz);
}
}
@@ -242,28 +248,6 @@ ElfObject::ElfObject(const string &_filename, int _fd,
bool
-ElfObject::loadSections(FunctionalMemory *mem, bool loadPhys)
-{
- Addr textAddr = text.baseAddr;
- Addr dataAddr = data.baseAddr;
-
- if (loadPhys) {
- textAddr &= (ULL(1) << 40) - 1;
- dataAddr &= (ULL(1) << 40) - 1;
- }
-
- // Since we don't really have an MMU and all memory is
- // zero-filled, there's no need to set up the BSS segment.
- if (text.size != 0)
- mem->prot_write(textAddr, fileTextBits, text.size);
- if (data.size != 0)
- mem->prot_write(dataAddr, fileDataBits, data.size);
-
- return true;
-}
-
-
-bool
ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding)
{
Elf *elf;
diff --git a/base/loader/elf_object.hh b/base/loader/elf_object.hh
index 66d8b3e63..72c265edd 100644
--- a/base/loader/elf_object.hh
+++ b/base/loader/elf_object.hh
@@ -35,9 +35,6 @@ class ElfObject : public ObjectFile
{
protected:
- uint8_t *fileTextBits; //!< Pointer to file's text segment image
- uint8_t *fileDataBits; //!< Pointer to file's data segment image
-
/// Helper functions for loadGlobalSymbols() and loadLocalSymbols().
bool loadSomeSymbols(SymbolTable *symtab, int binding);
@@ -48,8 +45,6 @@ class ElfObject : public ObjectFile
public:
virtual ~ElfObject() {}
- virtual bool loadSections(FunctionalMemory *mem,
- bool loadPhys = false);
virtual bool loadGlobalSymbols(SymbolTable *symtab);
virtual bool loadLocalSymbols(SymbolTable *symtab);
diff --git a/base/loader/object_file.cc b/base/loader/object_file.cc
index 1410d05b8..7f46ae2fb 100644
--- a/base/loader/object_file.cc
+++ b/base/loader/object_file.cc
@@ -43,6 +43,8 @@
#include "base/loader/aout_object.hh"
#include "base/loader/elf_object.hh"
+#include "mem/translating_port.hh"
+
using namespace std;
ObjectFile::ObjectFile(const string &_filename, int _fd,
@@ -60,6 +62,38 @@ ObjectFile::~ObjectFile()
}
+bool
+ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys)
+{
+ if (sec->size != 0) {
+ Addr addr = sec->baseAddr;
+ if (loadPhys) {
+ // this is Alpha-specific... going to have to fix this
+ // for other architectures
+ addr &= (ULL(1) << 40) - 1;
+ }
+
+ if (sec->fileImage) {
+ memPort->writeBlob(addr, sec->fileImage, sec->size, true);
+ }
+ else {
+ // no image: must be bss
+ memPort->memsetBlob(addr, 0, sec->size, true);
+ }
+ }
+ return true;
+}
+
+
+bool
+ObjectFile::loadSections(TranslatingPort *memPort, bool loadPhys)
+{
+ return (loadSection(&text, memPort, loadPhys)
+ && loadSection(&data, memPort, loadPhys)
+ && loadSection(&bss, memPort, loadPhys));
+}
+
+
void
ObjectFile::close()
{
diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh
index 1b44ae14f..309089728 100644
--- a/base/loader/object_file.hh
+++ b/base/loader/object_file.hh
@@ -33,7 +33,7 @@
#include "sim/host.hh" // for Addr
-class FunctionalMemory;
+class TranslatingPort;
class SymbolTable;
class ObjectFile
@@ -44,7 +44,7 @@ class ObjectFile
UnknownArch,
Alpha,
SPARC,
- MIPS
+ Mips
};
enum OpSys {
@@ -72,8 +72,7 @@ class ObjectFile
void close();
- virtual bool loadSections(FunctionalMemory *mem,
- bool loadPhys = false) = 0;
+ virtual bool loadSections(TranslatingPort *memPort, bool loadPhys = false);
virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0;
virtual bool loadLocalSymbols(SymbolTable *symtab) = 0;
@@ -83,8 +82,9 @@ class ObjectFile
protected:
struct Section {
- Addr baseAddr;
- size_t size;
+ Addr baseAddr;
+ uint8_t *fileImage;
+ size_t size;
};
Addr entry;
@@ -94,8 +94,12 @@ class ObjectFile
Section data;
Section bss;
+ bool loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys);
+ void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
+
public:
Addr entryPoint() const { return entry; }
+
Addr globalPointer() const { return globalPtr; }
Addr textBase() const { return text.baseAddr; }
diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc
index 84093459c..8a6cbdc33 100644
--- a/base/remote_gdb.cc
+++ b/base/remote_gdb.cc
@@ -440,7 +440,7 @@ RemoteGDB::getregs()
#ifdef KGDB_FP_REGS
for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
- gdbregs[i + KGDB_REG_F0] = context->readFloatRegInt(i);
+ gdbregs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
}
#endif
}
@@ -467,7 +467,7 @@ RemoteGDB::setregs()
#ifdef KGDB_FP_REGS
for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
- context->setFloatRegInt(i, gdbregs[i + KGDB_REG_F0]);
+ context->setFloatRegBits(i, gdbregs[i + KGDB_REG_F0]);
}
#endif
context->setPC(gdbregs[KGDB_REG_PC]);
diff --git a/base/traceflags.py b/base/traceflags.py
index e814a00fb..c3b878027 100644
--- a/base/traceflags.py
+++ b/base/traceflags.py
@@ -142,6 +142,7 @@ baseFlags = [
'OoOCPU',
'HWPrefetch',
'Stack',
+ 'SimpleCPU',
]
#
diff --git a/configs/test/hello b/configs/test/hello
new file mode 100755
index 000000000..59c0d195c
--- /dev/null
+++ b/configs/test/hello
Binary files differ
diff --git a/configs/test/hello_mips b/configs/test/hello_mips
new file mode 100755
index 000000000..182182b4f
--- /dev/null
+++ b/configs/test/hello_mips
Binary files differ
diff --git a/configs/test/test.py b/configs/test/test.py
new file mode 100644
index 000000000..86a44313a
--- /dev/null
+++ b/configs/test/test.py
@@ -0,0 +1,10 @@
+from m5 import *
+
+class HelloWorld(AlphaLiveProcess):
+ executable = '../configs/test/hello'
+ cmd = 'hello'
+
+mem = PhysicalMemory()
+cpu = SimpleCPU(workload=HelloWorld(), mem=mem)
+system = System(physmem=mem, cpu=cpu)
+root = Root(system=system)
diff --git a/cpu/base.cc b/cpu/base.cc
index 2eb5f7fd3..9ce458c64 100644
--- a/cpu/base.cc
+++ b/cpu/base.cc
@@ -65,7 +65,7 @@ BaseCPU::BaseCPU(Params *p)
#else
BaseCPU::BaseCPU(Params *p)
: SimObject(p->name), clock(p->clock), params(p),
- number_of_threads(p->numberOfThreads)
+ number_of_threads(p->numberOfThreads), system(p->system)
#endif
{
DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this);
@@ -229,6 +229,7 @@ BaseCPU::registerExecContexts()
{
for (int i = 0; i < execContexts.size(); ++i) {
ExecContext *xc = execContexts[i];
+
#if FULL_SYSTEM
int id = params->cpu_id;
if (id != -1)
diff --git a/cpu/base.hh b/cpu/base.hh
index d9d5d2b88..79700c117 100644
--- a/cpu/base.hh
+++ b/cpu/base.hh
@@ -38,11 +38,8 @@
#include "sim/sim_object.hh"
#include "arch/isa_traits.hh"
-#if FULL_SYSTEM
class System;
namespace Kernel { class Statistics; }
-#endif
-
class BranchPred;
class ExecContext;
@@ -123,8 +120,8 @@ class BaseCPU : public SimObject
Tick clock;
bool functionTrace;
Tick functionTraceStart;
-#if FULL_SYSTEM
System *system;
+#if FULL_SYSTEM
int cpu_id;
Tick profile;
#endif
@@ -173,9 +170,9 @@ class BaseCPU : public SimObject
*/
EventQueue **comLoadEventQueue;
-#if FULL_SYSTEM
System *system;
+#if FULL_SYSTEM
/**
* Serialize this object to the given output stream.
* @param os The stream to serialize to.
diff --git a/cpu/cpu_exec_context.cc b/cpu/cpu_exec_context.cc
index b7238e73a..0a3dc5675 100644
--- a/cpu/cpu_exec_context.cc
+++ b/cpu/cpu_exec_context.cc
@@ -28,6 +28,7 @@
#include <string>
+#include "arch/isa_traits.hh"
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
@@ -45,6 +46,7 @@
#include "arch/stacktrace.hh"
#else
#include "sim/process.hh"
+#include "mem/translating_port.hh"
#endif
using namespace std;
@@ -53,7 +55,7 @@ using namespace std;
#if FULL_SYSTEM
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
AlphaITB *_itb, AlphaDTB *_dtb,
- FunctionalMemory *_mem)
+ Memory *_mem)
: _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), lastActivate(0), lastSuspend(0), mem(_mem), itb(_itb),
dtb(_dtb), system(_sys), memctrl(_sys->memctrl), physmem(_sys->physmem),
@@ -79,27 +81,19 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
}
#else
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
- Process *_process, int _asid)
+ Process *_process, int _asid, Port *mem_port)
: _status(ExecContext::Unallocated),
cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0),
- lastSuspend(0), process(_process), mem(process->getMemory()), asid(_asid),
- func_exe_inst(0), storeCondFailures(0)
-{
- memset(&regs, 0, sizeof(RegFile));
- proxy = new ProxyExecContext<CPUExecContext>(this);
-}
-
-CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
- FunctionalMemory *_mem, int _asid)
- : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid),
+ lastSuspend(0), process(_process), asid(_asid),
func_exe_inst(0), storeCondFailures(0)
{
+ port = new TranslatingPort(mem_port, process->pTable);
memset(&regs, 0, sizeof(RegFile));
proxy = new ProxyExecContext<CPUExecContext>(this);
}
CPUExecContext::CPUExecContext(RegFile *regFile)
- : cpu(NULL), thread_num(-1), process(NULL), mem(NULL), asid(-1),
+ : cpu(NULL), thread_num(-1), process(NULL), asid(-1),
func_exe_inst(0), storeCondFailures(0)
{
regs = *regFile;
@@ -158,7 +152,6 @@ void
CPUExecContext::takeOverFrom(ExecContext *oldContext)
{
// some things should already be set up
- assert(mem == oldContext->getMemPtr());
#if FULL_SYSTEM
assert(system == oldContext->getSystemPtr());
#else
@@ -277,22 +270,6 @@ CPUExecContext::regStats(const string &name)
void
CPUExecContext::copyArchRegs(ExecContext *xc)
{
- // First loop through the integer registers.
- for (int i = 0; i < AlphaISA::NumIntRegs; ++i) {
- setIntReg(i, xc->readIntReg(i));
- }
-
- // Then loop through the floating point registers.
- for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) {
- setFloatRegDouble(i, xc->readFloatRegDouble(i));
- setFloatRegInt(i, xc->readFloatRegInt(i));
- }
-
- // Copy misc. registers
- regs.miscRegs.copyMiscRegs(xc);
-
- // Lastly copy PC/NPC
- setPC(xc->readPC());
- setNextPC(xc->readNextPC());
+ TheISA::copyRegs(xc, proxy);
}
diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh
index beaf67352..236619752 100644
--- a/cpu/cpu_exec_context.hh
+++ b/cpu/cpu_exec_context.hh
@@ -32,16 +32,13 @@
#include "arch/isa_traits.hh"
#include "config/full_system.hh"
#include "cpu/exec_context.hh"
-#include "mem/functional/functional.hh"
-#include "mem/mem_req.hh"
+#include "mem/physical.hh"
+#include "mem/request.hh"
#include "sim/byteswap.hh"
#include "sim/eventq.hh"
#include "sim/host.hh"
#include "sim/serialize.hh"
-// forward declaration: see functional_memory.hh
-class FunctionalMemory;
-class PhysicalMemory;
class BaseCPU;
#if FULL_SYSTEM
@@ -56,6 +53,8 @@ class MemoryController;
#else // !FULL_SYSTEM
#include "sim/process.hh"
+#include "mem/page_table.hh"
+class TranslatingPort;
#endif // FULL_SYSTEM
@@ -72,6 +71,8 @@ class CPUExecContext
typedef TheISA::MachInst MachInst;
typedef TheISA::MiscRegFile MiscRegFile;
typedef TheISA::MiscReg MiscReg;
+ typedef TheISA::FloatReg FloatReg;
+ typedef TheISA::FloatRegBits FloatRegBits;
public:
typedef ExecContext::Status Status;
@@ -118,17 +119,21 @@ class CPUExecContext
Tick lastActivate;
Tick lastSuspend;
+ System *system;
+
+ /// Port that syscalls can use to access memory (provides translation step).
+ TranslatingPort *port;
+// Memory *mem;
+
#if FULL_SYSTEM
- FunctionalMemory *mem;
AlphaITB *itb;
AlphaDTB *dtb;
- System *system;
// the following two fields are redundant, since we can always
// look them up through the system pointer, but we'll leave them
// here for now for convenience
MemoryController *memctrl;
- PhysicalMemory *physmem;
+// PhysicalMemory *physmem;
FunctionProfile *profile;
ProfileNode *profileNode;
@@ -164,8 +169,6 @@ class CPUExecContext
#else
Process *process;
- FunctionalMemory *mem; // functional storage for process address space
-
// Address space ID. Note that this is used for TIMING cache
// simulation only; all functional memory accesses should use
// one of the FunctionalMemory pointers above.
@@ -202,9 +205,7 @@ class CPUExecContext
CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem);
#else
- CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
- CPUExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
- int _asid);
+ CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, Port *mem_port);
// Constructor to use XC to pass reg file around. Not used for anything
// else.
CPUExecContext(RegFile *regFile);
@@ -218,6 +219,8 @@ class CPUExecContext
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
+ TranslatingPort *getMemPort() { return port; }
+
BaseCPU *getCpuPtr() { return cpu; }
ExecContext *getProxy() { return proxy; }
@@ -233,22 +236,20 @@ class CPUExecContext
AlphaDTB *getDTBPtr() { return dtb; }
- bool validInstAddr(Addr addr) { return true; }
- bool validDataAddr(Addr addr) { return true; }
int getInstAsid() { return regs.instAsid(); }
int getDataAsid() { return regs.dataAsid(); }
- Fault translateInstReq(MemReqPtr &req)
+ Fault translateInstReq(CpuRequestPtr &req)
{
return itb->translate(req);
}
- Fault translateDataReadReq(MemReqPtr &req)
+ Fault translateDataReadReq(CpuRequestPtr &req)
{
return dtb->translate(req, false);
}
- Fault translateDataWriteReq(MemReqPtr &req)
+ Fault translateDataWriteReq(CpuRequestPtr &req)
{
return dtb->translate(req, true);
}
@@ -256,45 +257,31 @@ class CPUExecContext
#else
Process *getProcessPtr() { return process; }
- bool validInstAddr(Addr addr)
- { return process->validInstAddr(addr); }
-
- bool validDataAddr(Addr addr)
- { return process->validDataAddr(addr); }
-
int getInstAsid() { return asid; }
int getDataAsid() { return asid; }
- Fault dummyTranslation(MemReqPtr &req)
- {
-#if 0
- assert((req->vaddr >> 48 & 0xffff) == 0);
-#endif
-
- // put the asid in the upper 16 bits of the paddr
- req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
- req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
- return NoFault;
- }
- Fault translateInstReq(MemReqPtr &req)
+ Fault translateInstReq(CpuRequestPtr &req)
{
- return dummyTranslation(req);
+ return process->pTable->translate(req);
}
- Fault translateDataReadReq(MemReqPtr &req)
+
+ Fault translateDataReadReq(CpuRequestPtr &req)
{
- return dummyTranslation(req);
+ return process->pTable->translate(req);
}
- Fault translateDataWriteReq(MemReqPtr &req)
+
+ Fault translateDataWriteReq(CpuRequestPtr &req)
{
- return dummyTranslation(req);
+ return process->pTable->translate(req);
}
#endif
+/*
template <class T>
- Fault read(MemReqPtr &req, T &data)
+ Fault read(CpuRequestPtr &req, T &data)
{
-#if FULL_SYSTEM && defined(TARGET_ALPHA)
+#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
if (req->flags & LOCKED) {
req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
@@ -302,15 +289,15 @@ class CPUExecContext
#endif
Fault error;
- error = mem->read(req, data);
+ error = mem->prot_read(req->paddr, data, req->size);
data = LittleEndianGuest::gtoh(data);
return error;
}
template <class T>
- Fault write(MemReqPtr &req, T &data)
+ Fault write(CpuRequestPtr &req, T &data)
{
-#if FULL_SYSTEM && defined(TARGET_ALPHA)
+#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
ExecContext *xc;
// If this is a store conditional, act appropriately
@@ -356,9 +343,9 @@ class CPUExecContext
}
#endif
- return mem->write(req, (T)LittleEndianGuest::htog(data));
+ return mem->prot_write(req->paddr, (T)htog(data), req->size);
}
-
+*/
virtual bool misspeculating();
@@ -369,17 +356,17 @@ class CPUExecContext
inst = new_inst;
}
- Fault instRead(MemReqPtr &req)
+ Fault instRead(CpuRequestPtr &req)
{
- return mem->read(req, inst);
+ panic("instRead not implemented");
+ // return funcPhysMem->read(req, inst);
+ return NoFault;
}
void setCpuId(int id) { cpu_id = id; }
int readCpuId() { return cpu_id; }
- FunctionalMemory *getMemPtr() { return mem; }
-
void copyArchRegs(ExecContext *xc);
//
@@ -390,19 +377,24 @@ class CPUExecContext
return regs.intRegFile[reg_idx];
}
- float readFloatRegSingle(int reg_idx)
+ FloatReg readFloatReg(int reg_idx, int width)
{
- return (float)regs.floatRegFile.d[reg_idx];
+ return regs.floatRegFile.readReg(reg_idx, width);
}
- double readFloatRegDouble(int reg_idx)
+ FloatReg readFloatReg(int reg_idx)
{
- return regs.floatRegFile.d[reg_idx];
+ return regs.floatRegFile.readReg(reg_idx);
}
- uint64_t readFloatRegInt(int reg_idx)
+ FloatRegBits readFloatRegBits(int reg_idx, int width)
{
- return regs.floatRegFile.q[reg_idx];
+ return regs.floatRegFile.readRegBits(reg_idx, width);
+ }
+
+ FloatRegBits readFloatRegBits(int reg_idx)
+ {
+ return regs.floatRegFile.readRegBits(reg_idx);
}
void setIntReg(int reg_idx, uint64_t val)
@@ -410,19 +402,24 @@ class CPUExecContext
regs.intRegFile[reg_idx] = val;
}
- void setFloatRegSingle(int reg_idx, float val)
+ void setFloatReg(int reg_idx, FloatReg val, int width)
+ {
+ regs.floatRegFile.setReg(reg_idx, val, width);
+ }
+
+ void setFloatReg(int reg_idx, FloatReg val)
{
- regs.floatRegFile.d[reg_idx] = (double)val;
+ regs.floatRegFile.setReg(reg_idx, val);
}
- void setFloatRegDouble(int reg_idx, double val)
+ void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
{
- regs.floatRegFile.d[reg_idx] = val;
+ regs.floatRegFile.setRegBits(reg_idx, val, width);
}
- void setFloatRegInt(int reg_idx, uint64_t val)
+ void setFloatRegBits(int reg_idx, FloatRegBits val)
{
- regs.floatRegFile.q[reg_idx] = val;
+ regs.floatRegFile.setRegBits(reg_idx, val);
}
uint64_t readPC()
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index 2b6c41bd7..2fdb19c73 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -30,7 +30,7 @@
#define __CPU_EXEC_CONTEXT_HH__
#include "config/full_system.hh"
-#include "mem/mem_req.hh"
+#include "mem/request.hh"
#include "sim/faults.hh"
#include "sim/host.hh"
#include "sim/serialize.hh"
@@ -43,8 +43,8 @@ class AlphaDTB;
class AlphaITB;
class BaseCPU;
class Event;
-class FunctionalMemory;
class PhysicalMemory;
+class TranslatingPort;
class Process;
class System;
@@ -54,6 +54,8 @@ class ExecContext
typedef TheISA::RegFile RegFile;
typedef TheISA::MachInst MachInst;
typedef TheISA::IntReg IntReg;
+ typedef TheISA::FloatReg FloatReg;
+ typedef TheISA::FloatRegBits FloatRegBits;
typedef TheISA::MiscRegFile MiscRegFile;
typedef TheISA::MiscReg MiscReg;
public:
@@ -81,14 +83,14 @@ class ExecContext
virtual ~ExecContext() { };
+ virtual TranslatingPort *getMemPort() = 0;
+
virtual BaseCPU *getCpuPtr() = 0;
virtual void setCpuId(int id) = 0;
virtual int readCpuId() = 0;
- virtual FunctionalMemory *getMemPtr() = 0;
-
#if FULL_SYSTEM
virtual System *getSystemPtr() = 0;
@@ -143,16 +145,14 @@ class ExecContext
virtual int getThreadNum() = 0;
- virtual bool validInstAddr(Addr addr) = 0;
- virtual bool validDataAddr(Addr addr) = 0;
virtual int getInstAsid() = 0;
virtual int getDataAsid() = 0;
- virtual Fault translateInstReq(MemReqPtr &req) = 0;
+ virtual Fault translateInstReq(CpuRequestPtr &req) = 0;
- virtual Fault translateDataReadReq(MemReqPtr &req) = 0;
+ virtual Fault translateDataReadReq(CpuRequestPtr &req) = 0;
- virtual Fault translateDataWriteReq(MemReqPtr &req) = 0;
+ virtual Fault translateDataWriteReq(CpuRequestPtr &req) = 0;
// Also somewhat obnoxious. Really only used for the TLB fault.
// However, may be quite useful in SPARC.
@@ -167,19 +167,23 @@ class ExecContext
//
virtual uint64_t readIntReg(int reg_idx) = 0;
- virtual float readFloatRegSingle(int reg_idx) = 0;
+ virtual FloatReg readFloatReg(int reg_idx, int width) = 0;
+
+ virtual FloatReg readFloatReg(int reg_idx) = 0;
- virtual double readFloatRegDouble(int reg_idx) = 0;
+ virtual FloatRegBits readFloatRegBits(int reg_idx, int width) = 0;
- virtual uint64_t readFloatRegInt(int reg_idx) = 0;
+ virtual FloatRegBits readFloatRegBits(int reg_idx) = 0;
virtual void setIntReg(int reg_idx, uint64_t val) = 0;
- virtual void setFloatRegSingle(int reg_idx, float val) = 0;
+ virtual void setFloatReg(int reg_idx, FloatReg val, int width) = 0;
- virtual void setFloatRegDouble(int reg_idx, double val) = 0;
+ virtual void setFloatReg(int reg_idx, FloatReg val) = 0;
- virtual void setFloatRegInt(int reg_idx, uint64_t val) = 0;
+ virtual void setFloatRegBits(int reg_idx, FloatRegBits val) = 0;
+
+ virtual void setFloatRegBits(int reg_idx, FloatRegBits val, int width) = 0;
virtual uint64_t readPC() = 0;
@@ -189,6 +193,10 @@ class ExecContext
virtual void setNextPC(uint64_t val) = 0;
+ virtual uint64_t readNextNPC() = 0;
+
+ virtual void setNextNPC(uint64_t val) = 0;
+
virtual MiscReg readMiscReg(int misc_reg) = 0;
virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0;
@@ -243,14 +251,14 @@ class ProxyExecContext : public ExecContext
public:
+ TranslatingPort *getMemPort() { return actualXC->getMemPort(); }
+
BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); }
void setCpuId(int id) { actualXC->setCpuId(id); }
int readCpuId() { return actualXC->readCpuId(); }
- FunctionalMemory *getMemPtr() { return actualXC->getMemPtr(); }
-
#if FULL_SYSTEM
System *getSystemPtr() { return actualXC->getSystemPtr(); }
@@ -305,18 +313,16 @@ class ProxyExecContext : public ExecContext
int getThreadNum() { return actualXC->getThreadNum(); }
- bool validInstAddr(Addr addr) { return actualXC->validInstAddr(addr); }
- bool validDataAddr(Addr addr) { return actualXC->validDataAddr(addr); }
int getInstAsid() { return actualXC->getInstAsid(); }
int getDataAsid() { return actualXC->getDataAsid(); }
- Fault translateInstReq(MemReqPtr &req)
+ Fault translateInstReq(CpuRequestPtr &req)
{ return actualXC->translateInstReq(req); }
- Fault translateDataReadReq(MemReqPtr &req)
+ Fault translateDataReadReq(CpuRequestPtr &req)
{ return actualXC->translateDataReadReq(req); }
- Fault translateDataWriteReq(MemReqPtr &req)
+ Fault translateDataWriteReq(CpuRequestPtr &req)
{ return actualXC->translateDataWriteReq(req); }
// @todo: Do I need this?
@@ -333,26 +339,32 @@ class ProxyExecContext : public ExecContext
uint64_t readIntReg(int reg_idx)
{ return actualXC->readIntReg(reg_idx); }
- float readFloatRegSingle(int reg_idx)
- { return actualXC->readFloatRegSingle(reg_idx); }
+ FloatReg readFloatReg(int reg_idx, int width)
+ { return actualXC->readFloatReg(reg_idx, width); }
+
+ FloatReg readFloatReg(int reg_idx)
+ { return actualXC->readFloatReg(reg_idx); }
- double readFloatRegDouble(int reg_idx)
- { return actualXC->readFloatRegDouble(reg_idx); }
+ FloatRegBits readFloatRegBits(int reg_idx, int width)
+ { return actualXC->readFloatRegBits(reg_idx, width); }
- uint64_t readFloatRegInt(int reg_idx)
- { return actualXC->readFloatRegInt(reg_idx); }
+ FloatRegBits readFloatRegBits(int reg_idx)
+ { return actualXC->readFloatRegBits(reg_idx); }
void setIntReg(int reg_idx, uint64_t val)
{ actualXC->setIntReg(reg_idx, val); }
- void setFloatRegSingle(int reg_idx, float val)
- { actualXC->setFloatRegSingle(reg_idx, val); }
+ void setFloatReg(int reg_idx, FloatReg val, int width)
+ { actualXC->setFloatReg(reg_idx, val, width); }
- void setFloatRegDouble(int reg_idx, double val)
- { actualXC->setFloatRegDouble(reg_idx, val); }
+ void setFloatReg(int reg_idx, FloatReg val)
+ { actualXC->setFloatReg(reg_idx, val); }
- void setFloatRegInt(int reg_idx, uint64_t val)
- { actualXC->setFloatRegInt(reg_idx, val); }
+ void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
+ { actualXC->setFloatRegBits(reg_idx, val, width); }
+
+ void setFloatRegBits(int reg_idx, FloatRegBits val)
+ { actualXC->setFloatRegBits(reg_idx, val); }
uint64_t readPC() { return actualXC->readPC(); }
@@ -362,6 +374,10 @@ class ProxyExecContext : public ExecContext
void setNextPC(uint64_t val) { actualXC->setNextPC(val); }
+ uint64_t readNextNPC() { return actualXC->readNextNPC(); }
+
+ void setNextNPC(uint64_t val) { actualXC->setNextNPC(val); }
+
MiscReg readMiscReg(int misc_reg)
{ return actualXC->readMiscReg(misc_reg); }
diff --git a/cpu/exetrace.cc b/cpu/exetrace.cc
index 84b5eacf7..ebb719b2c 100644
--- a/cpu/exetrace.cc
+++ b/cpu/exetrace.cc
@@ -30,9 +30,6 @@
#include <iomanip>
#include "sim/param.hh"
-#include "encumbered/cpu/full/dyn_inst.hh"
-#include "encumbered/cpu/full/spec_state.hh"
-#include "encumbered/cpu/full/issue.hh"
#include "cpu/exetrace.hh"
#include "base/loader/symtab.hh"
#include "cpu/base.hh"
diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh
index 0352e9972..8e1e0f42a 100644
--- a/cpu/o3/alpha_cpu.hh
+++ b/cpu/o3/alpha_cpu.hh
@@ -208,7 +208,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
template <class T>
Fault read(MemReqPtr &req, T &data)
{
-#if FULL_SYSTEM && defined(TARGET_ALPHA)
+#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
if (req->flags & LOCKED) {
req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
@@ -230,7 +230,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
template <class T>
Fault write(MemReqPtr &req, T &data)
{
-#if FULL_SYSTEM && defined(TARGET_ALPHA)
+#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
ExecContext *xc;
// If this is a store conditional, act appropriately
diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh
index 9f1fa24f6..7c4c2b969 100644
--- a/cpu/o3/alpha_cpu_impl.hh
+++ b/cpu/o3/alpha_cpu_impl.hh
@@ -175,10 +175,8 @@ AlphaFullCPU<Impl>::copyToXC()
for (int i = 0; i < AlphaISA::NumFloatRegs; ++i)
{
renamed_reg = this->renameMap.lookup(i + AlphaISA::FP_Base_DepTag);
- this->cpuXC->setFloatRegDouble(i,
- this->regFile.readFloatRegDouble(renamed_reg));
- this->cpuXC->setFloatRegInt(i,
- this->regFile.readFloatRegInt(renamed_reg));
+ this->cpuXC->setFloatRegBits(i,
+ this->regFile.readFloatRegBits(renamed_reg));
}
this->cpuXC->setMiscReg(AlphaISA::Fpcr_DepTag,
@@ -223,10 +221,8 @@ AlphaFullCPU<Impl>::copyFromXC()
for (int i = 0; i < AlphaISA::NumFloatRegs; ++i)
{
renamed_reg = this->renameMap.lookup(i + AlphaISA::FP_Base_DepTag);
- this->regFile.setFloatRegDouble(renamed_reg,
- this->cpuXC->readFloatRegDouble(i));
- this->regFile.setFloatRegInt(renamed_reg,
- this->cpuXC->readFloatRegInt(i));
+ this->regFile.setFloatRegBits(renamed_reg,
+ this->cpuXC->readFloatRegBits(i));
}
// Then loop through the misc registers.
diff --git a/cpu/o3/alpha_dyn_inst.hh b/cpu/o3/alpha_dyn_inst.hh
index e7f7d3a57..5b8a05e5c 100644
--- a/cpu/o3/alpha_dyn_inst.hh
+++ b/cpu/o3/alpha_dyn_inst.hh
@@ -152,19 +152,24 @@ class AlphaDynInst : public BaseDynInst<Impl>
return this->cpu->readIntReg(_srcRegIdx[idx]);
}
- float readFloatRegSingle(const StaticInst *si, int idx)
+ FloatReg readFloatReg(const StaticInst *si, int idx, int width)
{
- return this->cpu->readFloatRegSingle(_srcRegIdx[idx]);
+ return this->cpu->readFloatReg(_srcRegIdx[idx], width);
}
- double readFloatRegDouble(const StaticInst *si, int idx)
+ FloatReg readFloatReg(const StaticInst *si, int idx)
{
- return this->cpu->readFloatRegDouble(_srcRegIdx[idx]);
+ return this->cpu->readFloatReg(_srcRegIdx[idx]);
}
- uint64_t readFloatRegInt(const StaticInst *si, int idx)
+ FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width)
{
- return this->cpu->readFloatRegInt(_srcRegIdx[idx]);
+ return this->cpu->readFloatRegBits(_srcRegIdx[idx], width);
+ }
+
+ FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
+ {
+ return this->cpu->readFloatRegBits(_srcRegIdx[idx]);
}
/** @todo: Make results into arrays so they can handle multiple dest
@@ -176,21 +181,28 @@ class AlphaDynInst : public BaseDynInst<Impl>
this->instResult.integer = val;
}
- void setFloatRegSingle(const StaticInst *si, int idx, float val)
+ void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
{
- this->cpu->setFloatRegSingle(_destRegIdx[idx], val);
+ this->cpu->setFloatReg(_destRegIdx[idx], val, width);
this->instResult.fp = val;
}
- void setFloatRegDouble(const StaticInst *si, int idx, double val)
+ void setFloatReg(const StaticInst *si, int idx, FloatReg val)
{
- this->cpu->setFloatRegDouble(_destRegIdx[idx], val);
+ this->cpu->setFloatReg(_destRegIdx[idx], val);
this->instResult.dbl = val;
}
- void setFloatRegInt(const StaticInst *si, int idx, uint64_t val)
+ void setFloatRegBits(const StaticInst *si, int idx,
+ FloatRegBits val, int width)
+ {
+ this->cpu->setFloatRegBits(_destRegIdx[idx], val, width);
+ this->instResult.integer = val;
+ }
+
+ void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val)
{
- this->cpu->setFloatRegInt(_destRegIdx[idx], val);
+ this->cpu->setFloatRegBits(_destRegIdx[idx], val);
this->instResult.integer = val;
}
diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc
index 62d68bb33..a268dbc23 100644
--- a/cpu/o3/cpu.cc
+++ b/cpu/o3/cpu.cc
@@ -258,8 +258,7 @@ FullO3CPU<Impl>::init()
// Then loop through the floating point registers.
for (int i = 0; i < TheISA::NumFloatRegs; ++i)
{
- regFile.floatRegFile[i].d = src_xc->readFloatRegDouble(i);
- regFile.floatRegFile[i].q = src_xc->readFloatRegInt(i);
+ regFile.floatRegFile.setRegBits(i, src_xc->readRegBits(i))
}
/*
// Then loop through the misc registers.
@@ -348,24 +347,31 @@ FullO3CPU<Impl>::readIntReg(int reg_idx)
}
template <class Impl>
-float
-FullO3CPU<Impl>::readFloatRegSingle(int reg_idx)
+FloatReg
+FullO3CPU<Impl>::readFloatReg(int reg_idx, int width)
{
- return regFile.readFloatRegSingle(reg_idx);
+ return regFile.readFloatReg(reg_idx, width);
}
template <class Impl>
-double
-FullO3CPU<Impl>::readFloatRegDouble(int reg_idx)
+FloatReg
+FullO3CPU<Impl>::readFloatReg(int reg_idx)
{
- return regFile.readFloatRegDouble(reg_idx);
+ return regFile.readFloatReg(reg_idx);
}
template <class Impl>
-uint64_t
-FullO3CPU<Impl>::readFloatRegInt(int reg_idx)
+FloatRegBits
+FullO3CPU<Impl>::readFloatRegBits(int reg_idx, int width)
+{
+ return regFile.readFloatRegBits(reg_idx, width);
+}
+
+template <class Impl>
+FloatRegBits
+FullO3CPU<Impl>::readFloatRegBits(int reg_idx)
{
- return regFile.readFloatRegInt(reg_idx);
+ return regFile.readFloatRegBits(reg_idx);
}
template <class Impl>
@@ -377,23 +383,30 @@ FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val)
template <class Impl>
void
-FullO3CPU<Impl>::setFloatRegSingle(int reg_idx, float val)
+FullO3CPU<Impl>::setFloatReg(int reg_idx, FloatReg val, int width)
+{
+ regFile.setFloatReg(reg_idx, val, width);
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::setFloatReg(int reg_idx, FloatReg val)
{
- regFile.setFloatRegSingle(reg_idx, val);
+ regFile.setFloatReg(reg_idx, val);
}
template <class Impl>
void
-FullO3CPU<Impl>::setFloatRegDouble(int reg_idx, double val)
+FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val, int width)
{
- regFile.setFloatRegDouble(reg_idx, val);
+ regFile.setFloatRegBits(reg_idx, val, width);
}
template <class Impl>
void
-FullO3CPU<Impl>::setFloatRegInt(int reg_idx, uint64_t val)
+FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
{
- regFile.setFloatRegInt(reg_idx, val);
+ regFile.setFloatRegBits(reg_idx, val);
}
template <class Impl>
diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh
index 6577e46e4..f7c80e8a1 100644
--- a/cpu/o3/cpu.hh
+++ b/cpu/o3/cpu.hh
@@ -170,19 +170,23 @@ class FullO3CPU : public BaseFullCPU
//
uint64_t readIntReg(int reg_idx);
- float readFloatRegSingle(int reg_idx);
+ FloatReg readFloatReg(int reg_idx);
- double readFloatRegDouble(int reg_idx);
+ FloatReg readFloatReg(int reg_idx, int width);
- uint64_t readFloatRegInt(int reg_idx);
+ FloatRegBits readFloatRegBits(int reg_idx);
+
+ FloatRegBits readFloatRegBits(int reg_idx, int width);
void setIntReg(int reg_idx, uint64_t val);
- void setFloatRegSingle(int reg_idx, float val);
+ void setFloatReg(int reg_idx, FloatReg val, int width);
+
+ void setFloatReg(int reg_idx, FloatReg val, int width);
- void setFloatRegDouble(int reg_idx, double val);
+ void setFloatRegBits(int reg_idx, FloatRegBits val);
- void setFloatRegInt(int reg_idx, uint64_t val);
+ void setFloatRegBits(int reg_idx, FloatRegBits val);
uint64_t readPC();
diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh
index 1e6e10f29..a5cfa8f3c 100644
--- a/cpu/o3/regfile.hh
+++ b/cpu/o3/regfile.hh
@@ -89,43 +89,64 @@ class PhysRegFile
return intRegFile[reg_idx];
}
- float readFloatRegSingle(PhysRegIndex reg_idx)
+ FloatReg readFloatReg(PhysRegIndex reg_idx, int width)
{
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Access to float register %i as single, has "
- "data %8.8f\n", int(reg_idx), (float)floatRegFile[reg_idx].d);
+ FloatReg floatReg = floatRegFile.readReg(reg_idx, width);
- return (float)floatRegFile[reg_idx].d;
+ DPRINTF(IEW, "RegFile: Access to %d byte float register %i, has "
+ "data %8.8d\n", int(reg_idx), (double)floatReg);
+
+ return floatReg;
}
- double readFloatRegDouble(PhysRegIndex reg_idx)
+ FloatReg readFloatReg(PhysRegIndex reg_idx)
{
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Access to float register %i as double, has "
- " data %8.8f\n", int(reg_idx), floatRegFile[reg_idx].d);
+ FloatReg floatReg = floatRegFile.readReg(reg_idx);
+
+ DPRINTF(IEW, "RegFile: Access to float register %i, has "
+ "data %8.8d\n", int(reg_idx), (double)floatReg);
- return floatRegFile[reg_idx].d;
+ return floatReg;
}
- uint64_t readFloatRegInt(PhysRegIndex reg_idx)
+ FloatRegBits readFloatRegBits(PhysRegIndex reg_idx, int width)
{
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Access to float register %i as int, has data "
- "%lli\n", int(reg_idx), floatRegFile[reg_idx].q);
+ FloatRegBits floatRegBits = floatRegFile.readRegBits(reg_idx, width);
+
+ DPRINTF(IEW, "RegFile: Access to %d byte float register %i as int, "
+ "has data %lli\n", int(reg_idx), (uint64_t)floatRegBits);
+
+ return floatRegBits;
+ }
+
+ FloatRegBits readFloatRegBits(PhysRegIndex reg_idx)
+ {
+ // Remove the base Float reg dependency.
+ reg_idx = reg_idx - numPhysicalIntRegs;
+
+ assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
+
+ FloatRegBits floatRegBits = floatRegFile.readRegBits(reg_idx);
+
+ DPRINTF(IEW, "RegFile: Access to float register %i as int, "
+ "has data %lli\n", int(reg_idx), (uint64_t)floatRegBits);
- return floatRegFile[reg_idx].q;
+ return floatRegBits;
}
void setIntReg(PhysRegIndex reg_idx, uint64_t val)
@@ -138,33 +159,33 @@ class PhysRegFile
intRegFile[reg_idx] = val;
}
- void setFloatRegSingle(PhysRegIndex reg_idx, float val)
+ void setFloatReg(PhysRegIndex reg_idx, FloatReg val, int width)
{
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Setting float register %i to %8.8f\n",
- int(reg_idx), val);
+ DPRINTF(IEW, "RegFile: Setting float register %i to %8.8d\n",
+ int(reg_idx), (double)val);
- floatRegFile[reg_idx].d = (double)val;
+ floatRegFile.setReg(reg_idx, val, width);
}
- void setFloatRegDouble(PhysRegIndex reg_idx, double val)
+ void setFloatReg(PhysRegIndex reg_idx, FloatReg val)
{
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Setting float register %i to %8.8f\n",
- int(reg_idx), val);
+ DPRINTF(IEW, "RegFile: Setting float register %i to %8.8d\n",
+ int(reg_idx), (double)val);
- floatRegFile[reg_idx].d = val;
+ floatRegFile.setReg(reg_idx, val);
}
- void setFloatRegInt(PhysRegIndex reg_idx, uint64_t val)
+ void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val, int width)
{
// Remove the base Float reg dependency.
reg_idx = reg_idx - numPhysicalIntRegs;
@@ -172,9 +193,22 @@ class PhysRegFile
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
DPRINTF(IEW, "RegFile: Setting float register %i to %lli\n",
- int(reg_idx), val);
+ int(reg_idx), (uint64_t)val);
+
+ floatRegFile.setRegBits(reg_idx, val, width);
+ }
+
+ void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val)
+ {
+ // Remove the base Float reg dependency.
+ reg_idx = reg_idx - numPhysicalIntRegs;
+
+ assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
+
+ DPRINTF(IEW, "RegFile: Setting float register %i to %lli\n",
+ int(reg_idx), (uint64_t)val);
- floatRegFile[reg_idx].q = val;
+ floatRegFile.setRegBits(reg_idx, val);
}
uint64_t readPC()
diff --git a/cpu/op_class.cc b/cpu/op_class.cc
new file mode 100644
index 000000000..00136ded5
--- /dev/null
+++ b/cpu/op_class.cc
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ */
+
+#include "cpu/op_class.hh"
+
+/** OpClass enum -> description string */
+const char *
+opClassStrings[Num_OpClasses] =
+{
+ "(null)",
+ "IntAlu",
+ "IntMult",
+ "IntDiv",
+ "FloatAdd",
+ "FloatCmp",
+ "FloatCvt",
+ "FloatMult",
+ "FloatDiv",
+ "FloatSqrt",
+ "MemRead",
+ "MemWrite",
+ "IprAccess",
+ "InstPrefetch"
+};
+
diff --git a/encumbered/cpu/full/op_class.hh b/cpu/op_class.hh
index ff53b58d2..cdb40a0fb 100644
--- a/encumbered/cpu/full/op_class.hh
+++ b/cpu/op_class.hh
@@ -26,8 +26,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __ENCUMBERED_CPU_FULL_OP_CLASS_HH__
-#define __ENCUMBERED_CPU_FULL_OP_CLASS_HH__
+#ifndef __CPU__OP_CLASS_HH__
+#define __CPU__OP_CLASS_HH__
/**
* @file
@@ -39,26 +39,26 @@
* assigning instructions to functional units.
*/
enum OpClass {
- No_OpClass = 0, /* inst does not use a functional unit */
- IntAluOp, /* integer ALU */
- IntMultOp, /* integer multiplier */
- IntDivOp, /* integer divider */
- FloatAddOp, /* floating point adder/subtractor */
- FloatCmpOp, /* floating point comparator */
- FloatCvtOp, /* floating point<->integer converter */
- FloatMultOp, /* floating point multiplier */
- FloatDivOp, /* floating point divider */
- FloatSqrtOp, /* floating point square root */
- MemReadOp, /* memory read port */
- MemWriteOp, /* memory write port */
- IprAccessOp, /* Internal Processor Register read/write port */
- InstPrefetchOp, /* instruction prefetch port (on I-cache) */
- Num_OpClasses /* total functional unit classes */
+ No_OpClass = 0, ///< Instruction does not use a functional unit
+ IntAluOp, ///< Integer ALU operaton (add/sub/logical)
+ IntMultOp, ///< Integer multiply
+ IntDivOp, ///< Integer divide
+ FloatAddOp, ///< Floating point add/subtract
+ FloatCmpOp, ///< Floating point comparison
+ FloatCvtOp, ///< Floating point<->integer conversion
+ FloatMultOp, ///< Floating point multiply
+ FloatDivOp, ///< Floating point divide
+ FloatSqrtOp, ///< Floating point square root
+ MemReadOp, ///< Memory read port
+ MemWriteOp, ///< Memory write port
+ IprAccessOp, ///< Internal Processor Register read/write port
+ InstPrefetchOp, ///< Instruction prefetch port (on I-cache)
+ Num_OpClasses ///< Total number of operation classes
};
/**
- * Array mapping OpClass enum values to strings. Defined in fu_pool.cc.
+ * Array mapping OpClass enum values to strings. Defined in op_class.cc.
*/
extern const char *opClassStrings[];
-#endif // __ENCUMBERED_CPU_FULL_OP_CLASS_HH__
+#endif // __CPU__OP_CLASS_HH__
diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh
index f5d84d656..fa849bb09 100644
--- a/cpu/ozone/cpu.hh
+++ b/cpu/ozone/cpu.hh
@@ -406,22 +406,28 @@ class OoOCPU : public BaseCPU
return xc->readIntReg(si->srcRegIdx(idx));
}
- float readFloatRegSingle(StaticInst *si, int idx)
+ FloatReg readFloatReg(StaticInst *si, int idx, width)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatRegSingle(reg_idx);
+ return xc->readFloatReg(reg_idx, width);
}
- double readFloatRegDouble(StaticInst *si, int idx)
+ FloatReg readFloatReg(StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatRegDouble(reg_idx);
+ return xc->readFloatReg(reg_idx);
}
- uint64_t readFloatRegInt(StaticInst *si, int idx)
+ FloatRegBits readFloatRegBits(StaticInst *si, int idx, int width)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatRegInt(reg_idx);
+ return xc->readFloatRegBits(reg_idx, width);
+ }
+
+ FloatRegBits readFloatRegBits(StaticInst *si, int idx)
+ {
+ int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
+ return xc->readFloatRegBits(reg_idx);
}
void setIntReg(StaticInst *si, int idx, uint64_t val)
@@ -429,22 +435,28 @@ class OoOCPU : public BaseCPU
xc->setIntReg(si->destRegIdx(idx), val);
}
- void setFloatRegSingle(StaticInst *si, int idx, float val)
+ void setFloatReg(StaticInst *si, int idx, FloatReg val, int width)
+ {
+ int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
+ xc->setFloatReg(reg_idx, val, width);
+ }
+
+ void setFloatReg(StaticInst *si, int idx, FloatReg val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatRegSingle(reg_idx, val);
+ xc->setFloatReg(reg_idx, val);
}
- void setFloatRegDouble(StaticInst *si, int idx, double val)
+ void setFloatRegBits(StaticInst *si, int idx, FloatRegBits val, int width)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatRegDouble(reg_idx, val);
+ xc->setFloatRegBits(reg_idx, val, width);
}
- void setFloatRegInt(StaticInst *si, int idx, uint64_t val)
+ void setFloatRegBits(StaticInst *si, int idx, FloatRegBits val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatRegInt(reg_idx, val);
+ xc->setFloatRegBits(reg_idx, val);
}
uint64_t readPC() { return PC; }
diff --git a/cpu/pc_event.hh b/cpu/pc_event.hh
index 7fa3902cc..32b7f3ef5 100644
--- a/cpu/pc_event.hh
+++ b/cpu/pc_event.hh
@@ -31,7 +31,7 @@
#include <vector>
-#include "mem/mem_req.hh"
+#include "base/misc.hh"
class ExecContext;
class PCEventQueue;
@@ -39,9 +39,6 @@ class PCEventQueue;
class PCEvent
{
protected:
- static const Addr badpc = MemReq::inval_addr;
-
- protected:
std::string description;
PCEventQueue *queue;
Addr evpc;
diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc
index 8db72b77e..d188074d4 100644
--- a/cpu/simple/cpu.cc
+++ b/cpu/simple/cpu.cc
@@ -35,6 +35,7 @@
#include <sstream>
#include <string>
+#include "arch/utility.hh"
#include "base/cprintf.hh"
#include "base/inifile.hh"
#include "base/loader/symtab.hh"
@@ -53,8 +54,6 @@
#include "cpu/smt.hh"
#include "cpu/static_inst.hh"
#include "kern/kernel_stats.hh"
-#include "mem/base_mem.hh"
-#include "mem/mem_interface.hh"
#include "sim/byteswap.hh"
#include "sim/builder.hh"
#include "sim/debug.hh"
@@ -72,13 +71,11 @@
#include "arch/stacktrace.hh"
#include "arch/vtophys.hh"
#else // !FULL_SYSTEM
-#include "mem/functional/functional.hh"
+#include "mem/mem_object.hh"
#endif // FULL_SYSTEM
using namespace std;
-//The SimpleCPU does alpha only
-using namespace AlphaISA;
-
+using namespace TheISA;
SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w)
: Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), width(w)
@@ -116,43 +113,85 @@ SimpleCPU::TickEvent::description()
}
-SimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu)
- : Event(&mainEventQueue), cpu(_cpu)
+bool
+SimpleCPU::CpuPort::recvTiming(Packet &pkt)
{
+ cpu->processResponse(pkt);
+ return true;
}
-void SimpleCPU::CacheCompletionEvent::process()
+Tick
+SimpleCPU::CpuPort::recvAtomic(Packet &pkt)
{
- cpu->processCacheCompletion();
+ panic("CPU doesn't expect callback!");
+ return curTick;
}
-const char *
-SimpleCPU::CacheCompletionEvent::description()
+void
+SimpleCPU::CpuPort::recvFunctional(Packet &pkt)
+{
+ panic("CPU doesn't expect callback!");
+}
+
+void
+SimpleCPU::CpuPort::recvStatusChange(Status status)
+{
+ cpu->recvStatusChange(status);
+}
+
+Packet *
+SimpleCPU::CpuPort::recvRetry()
{
- return "SimpleCPU cache completion event";
+ return cpu->processRetry();
}
SimpleCPU::SimpleCPU(Params *p)
- : BaseCPU(p), tickEvent(this, p->width), cpuXC(NULL),
- cacheCompletionEvent(this)
+ : BaseCPU(p), icachePort(this),
+ dcachePort(this), tickEvent(this, p->width), cpuXC(NULL)
{
_status = Idle;
+
+ //Create Memory Ports (conect them up)
+ Port *mem_dport = p->mem->getPort();
+ dcachePort.setPeer(mem_dport);
+ mem_dport->setPeer(&dcachePort);
+
+ Port *mem_iport = p->mem->getPort();
+ icachePort.setPeer(mem_iport);
+ mem_iport->setPeer(&icachePort);
+
#if FULL_SYSTEM
cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
-
#else
- cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process,
- /* asid */ 0);
+ cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0,
+ &dcachePort);
#endif // !FULL_SYSTEM
- xcProxy = cpuXC->getProxy();
- icacheInterface = p->icache_interface;
- dcacheInterface = p->dcache_interface;
+ xcProxy = cpuXC->getProxy();
- memReq = new MemReq();
- memReq->xc = xcProxy;
- memReq->asid = 0;
- memReq->data = new uint8_t[64];
+#if SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
+ ifetch_req = new CpuRequest;
+ ifetch_req->asid = 0;
+ ifetch_req->size = sizeof(MachInst);
+ ifetch_pkt = new Packet;
+ ifetch_pkt->cmd = Read;
+ ifetch_pkt->data = (uint8_t *)&inst;
+ ifetch_pkt->req = ifetch_req;
+ ifetch_pkt->size = sizeof(MachInst);
+
+ data_read_req = new CpuRequest;
+ data_read_req->asid = 0;
+ data_read_pkt = new Packet;
+ data_read_pkt->cmd = Read;
+ data_read_pkt->data = new uint8_t[8];
+ data_read_pkt->req = data_read_req;
+
+ data_write_req = new CpuRequest;
+ data_write_req->asid = 0;
+ data_write_pkt = new Packet;
+ data_write_pkt->cmd = Write;
+ data_write_pkt->req = data_write_req;
+#endif
numInst = 0;
startNumInst = 0;
@@ -172,9 +211,9 @@ void
SimpleCPU::switchOut(Sampler *s)
{
sampler = s;
- if (status() == DcacheMissStall) {
+ if (status() == DcacheWaitResponse) {
DPRINTF(Sampler,"Outstanding dcache access, waiting for completion\n");
- _status = DcacheMissSwitch;
+ _status = DcacheWaitSwitch;
}
else {
_status = SwitchedOut;
@@ -287,6 +326,18 @@ SimpleCPU::regStats()
.prereq(dcacheStallCycles)
;
+ icacheRetryCycles
+ .name(name() + ".icache_retry_cycles")
+ .desc("ICache total retry cycles")
+ .prereq(icacheRetryCycles)
+ ;
+
+ dcacheRetryCycles
+ .name(name() + ".dcache_retry_cycles")
+ .desc("DCache total retry cycles")
+ .prereq(dcacheRetryCycles)
+ ;
+
idleFraction = constant(1.0) - notIdleFraction;
}
@@ -308,7 +359,6 @@ SimpleCPU::serialize(ostream &os)
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
nameOut(os, csprintf("%s.cacheCompletionEvent", name()));
- cacheCompletionEvent.serialize(os);
}
void
@@ -319,8 +369,6 @@ SimpleCPU::unserialize(Checkpoint *cp, const string &section)
UNSERIALIZE_SCALAR(inst);
cpuXC->unserialize(cp, csprintf("%s.xc", section));
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
- cacheCompletionEvent
- .unserialize(cp, csprintf("%s.cacheCompletionEvent", section));
}
void
@@ -331,6 +379,7 @@ change_thread_state(int thread_number, int activate, int priority)
Fault
SimpleCPU::copySrcTranslate(Addr src)
{
+#if 0
static bool no_warn = true;
int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
// Only support block sizes of 64 atm.
@@ -347,8 +396,7 @@ SimpleCPU::copySrcTranslate(Addr src)
memReq->reset(src & ~(blk_size - 1), blk_size);
- // translate to physical address
- Fault fault = cpuXC->translateDataReadReq(memReq);
+ // translate to physical address Fault fault = cpuXC->translateDataReadReq(req);
if (fault == NoFault) {
cpuXC->copySrcAddr = src;
@@ -360,11 +408,15 @@ SimpleCPU::copySrcTranslate(Addr src)
cpuXC->copySrcPhysAddr = 0;
}
return fault;
+#else
+ return NoFault;
+#endif
}
Fault
SimpleCPU::copy(Addr dest)
{
+#if 0
static bool no_warn = true;
int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
// Only support block sizes of 64 atm.
@@ -383,7 +435,7 @@ SimpleCPU::copy(Addr dest)
memReq->reset(dest & ~(blk_size -1), blk_size);
// translate to physical address
- Fault fault = cpuXC->translateDataWriteReq(memReq);
+ Fault fault = cpuXC->translateDataWriteReq(req);
if (fault == NoFault) {
Addr dest_addr = memReq->paddr + offset;
@@ -407,6 +459,10 @@ SimpleCPU::copy(Addr dest)
assert(!fault->isAlignmentFault());
return fault;
+#else
+ panic("copy not implemented");
+ return NoFault;
+#endif
}
// precise architected memory state accessor macros
@@ -414,22 +470,64 @@ template <class T>
Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags)
{
- if (status() == DcacheMissStall || status() == DcacheMissSwitch) {
- Fault fault = cpuXC->read(memReq,data);
+ if (status() == DcacheWaitResponse || status() == DcacheWaitSwitch) {
+// Fault fault = xc->read(memReq,data);
+ // Not sure what to check for no fault...
+ if (data_read_pkt->result == Success) {
+ memcpy(&data, data_read_pkt->data, sizeof(T));
+ }
if (traceData) {
traceData->setAddr(addr);
}
- return fault;
+
+ // @todo: Figure out a way to create a Fault from the packet result.
+ return NoFault;
}
- memReq->reset(addr, sizeof(T), flags);
+// memReq->reset(addr, sizeof(T), flags);
+
+#if SIMPLE_CPU_MEM_TIMING
+ CpuRequest *data_read_req = new CpuRequest;
+#endif
+
+ data_read_req->vaddr = addr;
+ data_read_req->size = sizeof(T);
+ data_read_req->flags = flags;
+ data_read_req->time = curTick;
// translate to physical address
- Fault fault = cpuXC->translateDataReadReq(memReq);
+ Fault fault = cpuXC->translateDataReadReq(data_read_req);
- // if we have a cache, do cache access too
- if (fault == NoFault && dcacheInterface) {
+ // Now do the access.
+ if (fault == NoFault) {
+#if SIMPLE_CPU_MEM_TIMING
+ data_read_pkt = new Packet;
+ data_read_pkt->cmd = Read;
+ data_read_pkt->req = data_read_req;
+ data_read_pkt->data = new uint8_t[8];
+#endif
+ data_read_pkt->addr = data_read_req->paddr;
+ data_read_pkt->size = sizeof(T);
+
+ sendDcacheRequest(data_read_pkt);
+
+#if SIMPLE_CPU_MEM_IMMEDIATE
+ // Need to find a way to not duplicate code above.
+
+ if (data_read_pkt->result == Success) {
+ memcpy(&data, data_read_pkt->data, sizeof(T));
+ }
+
+ if (traceData) {
+ traceData->setAddr(addr);
+ }
+
+ // @todo: Figure out a way to create a Fault from the packet result.
+ return NoFault;
+#endif
+ }
+/*
memReq->cmd = Read;
memReq->completionEvent = NULL;
memReq->time = curTick;
@@ -454,8 +552,9 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
fault = cpuXC->read(memReq, data);
}
-
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
+*/
+ // This will need a new way to tell if it has a dcache attached.
+ if (data_read_req->flags & UNCACHEABLE)
recordEvent("Uncached Read");
return fault;
@@ -508,11 +607,31 @@ template <class T>
Fault
SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
- memReq->reset(addr, sizeof(T), flags);
+ data_write_req->vaddr = addr;
+ data_write_req->time = curTick;
+ data_write_req->size = sizeof(T);
+ data_write_req->flags = flags;
// translate to physical address
- Fault fault = cpuXC->translateDataWriteReq(memReq);
+ Fault fault = cpuXC->translateDataWriteReq(data_write_req);
+ // Now do the access.
+ if (fault == NoFault) {
+#if SIMPLE_CPU_MEM_TIMING
+ data_write_pkt = new Packet;
+ data_write_pkt->cmd = Write;
+ data_write_pkt->req = data_write_req;
+ data_write_pkt->data = new uint8_t[64];
+ memcpy(data_write_pkt->data, &data, sizeof(T));
+#else
+ data_write_pkt->data = (uint8_t *)&data;
+#endif
+ data_write_pkt->addr = data_write_req->paddr;
+ data_write_pkt->size = sizeof(T);
+
+ sendDcacheRequest(data_write_pkt);
+ }
+/*
// do functional access
if (fault == NoFault)
fault = cpuXC->write(memReq, data);
@@ -535,13 +654,16 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
_status = DcacheMissStall;
}
}
-
+*/
if (res && (fault == NoFault))
- *res = memReq->result;
+ *res = data_write_pkt->result;
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
+ // This will need a new way to tell if it's hooked up to a cache or not.
+ if (data_write_req->flags & UNCACHEABLE)
recordEvent("Uncached Write");
+ // If the write needs to have a fault on the access, consider calling
+ // changeStatus() and changing it to "bad addr write" or something.
return fault;
}
@@ -597,36 +719,130 @@ SimpleCPU::dbg_vtophys(Addr addr)
#endif // FULL_SYSTEM
void
-SimpleCPU::processCacheCompletion()
+SimpleCPU::sendIcacheRequest(Packet *pkt)
+{
+ assert(!tickEvent.scheduled());
+#if SIMPLE_CPU_MEM_TIMING
+ retry_pkt = pkt;
+ bool success = icachePort.sendTiming(*pkt);
+
+ unscheduleTickEvent();
+
+ lastIcacheStall = curTick;
+
+ if (!success) {
+ // Need to wait for retry
+ _status = IcacheRetry;
+ } else {
+ // Need to wait for cache to respond
+ _status = IcacheWaitResponse;
+ }
+#elif SIMPLE_CPU_MEM_ATOMIC
+ Tick latency = icachePort.sendAtomic(*pkt);
+
+ unscheduleTickEvent();
+ scheduleTickEvent(latency);
+
+ // Note that Icache miss cycles will be incorrect. Unless
+ // we check the status of the packet sent (is this valid?),
+ // we won't know if the latency is a hit or a miss.
+ icacheStallCycles += latency;
+
+ _status = IcacheAccessComplete;
+#elif SIMPLE_CPU_MEM_IMMEDIATE
+ icachePort.sendAtomic(*pkt);
+#else
+#error "SimpleCPU has no mem model set"
+#endif
+}
+
+void
+SimpleCPU::sendDcacheRequest(Packet *pkt)
+{
+ assert(!tickEvent.scheduled());
+#if SIMPLE_CPU_MEM_TIMING
+ unscheduleTickEvent();
+
+ retry_pkt = pkt;
+ bool success = dcachePort.sendTiming(*pkt);
+
+ lastDcacheStall = curTick;
+
+ if (!success) {
+ _status = DcacheRetry;
+ } else {
+ _status = DcacheWaitResponse;
+ }
+#elif SIMPLE_CPU_MEM_ATOMIC
+ unscheduleTickEvent();
+
+ Tick latency = dcachePort.sendAtomic(*pkt);
+
+ scheduleTickEvent(latency);
+
+ // Note that Dcache miss cycles will be incorrect. Unless
+ // we check the status of the packet sent (is this valid?),
+ // we won't know if the latency is a hit or a miss.
+ dcacheStallCycles += latency;
+#elif SIMPLE_CPU_MEM_IMMEDIATE
+ dcachePort.sendAtomic(*pkt);
+#else
+#error "SimpleCPU has no mem model set"
+#endif
+}
+
+void
+SimpleCPU::processResponse(Packet &response)
{
+ assert(SIMPLE_CPU_MEM_TIMING);
+
+ // For what things is the CPU the consumer of the packet it sent
+ // out? This may create a memory leak if that's the case and it's
+ // expected of the SimpleCPU to delete its own packet.
+ Packet *pkt = &response;
+
switch (status()) {
- case IcacheMissStall:
+ case IcacheWaitResponse:
icacheStallCycles += curTick - lastIcacheStall;
- _status = IcacheMissComplete;
+
+ _status = IcacheAccessComplete;
scheduleTickEvent(1);
+
+ // Copy the icache data into the instruction itself.
+ memcpy(&inst, pkt->data, sizeof(inst));
+
+ delete pkt;
break;
- case DcacheMissStall:
- if (memReq->cmd.isRead()) {
+ case DcacheWaitResponse:
+ if (pkt->cmd == Read) {
curStaticInst->execute(this,traceData);
if (traceData)
traceData->finalize();
}
+
+ delete pkt;
+
dcacheStallCycles += curTick - lastDcacheStall;
_status = Running;
scheduleTickEvent(1);
break;
- case DcacheMissSwitch:
- if (memReq->cmd.isRead()) {
+ case DcacheWaitSwitch:
+ if (pkt->cmd == Read) {
curStaticInst->execute(this,traceData);
if (traceData)
traceData->finalize();
}
+
+ delete pkt;
+
_status = SwitchedOut;
sampler->signalSwitched();
case SwitchedOut:
// If this CPU has been switched out due to sampling/warm-up,
// ignore any further status changes (e.g., due to cache
// misses outstanding at the time of the switch).
+ delete pkt;
+
return;
default:
panic("SimpleCPU::processCacheCompletion: bad state");
@@ -634,6 +850,28 @@ SimpleCPU::processCacheCompletion()
}
}
+Packet *
+SimpleCPU::processRetry()
+{
+#if SIMPLE_CPU_MEM_TIMING
+ switch(status()) {
+ case IcacheRetry:
+ icacheRetryCycles += curTick - lastIcacheStall;
+ return retry_pkt;
+ break;
+ case DcacheRetry:
+ dcacheRetryCycles += curTick - lastDcacheStall;
+ return retry_pkt;
+ break;
+ default:
+ panic("SimpleCPU::processRetry: bad state");
+ break;
+ }
+#else
+ panic("shouldn't be here");
+#endif
+}
+
#if FULL_SYSTEM
void
SimpleCPU::post_interrupt(int int_num, int index)
@@ -651,6 +889,8 @@ SimpleCPU::post_interrupt(int int_num, int index)
void
SimpleCPU::tick()
{
+ DPRINTF(SimpleCPU,"\n\n");
+
numCycles++;
traceData = NULL;
@@ -702,19 +942,18 @@ SimpleCPU::tick()
// maintain $r0 semantics
cpuXC->setIntReg(ZeroReg, 0);
-#ifdef TARGET_ALPHA
- cpuXC->setFloatRegDouble(ZeroReg, 0.0);
-#endif // TARGET_ALPHA
+#if THE_ISA == ALPHA_ISA
+ cpuXC->setFloatReg(ZeroReg, 0.0);
+#endif // ALPHA_ISA
- if (status() == IcacheMissComplete) {
+ if (status() == IcacheAccessComplete) {
// We've already fetched an instruction and were stalled on an
// I-cache miss. No need to fetch it again.
// Set status to running; tick event will get rescheduled if
// necessary at end of tick() function.
_status = Running;
- }
- else {
+ } else {
// Try to fetch an instruction
// set up memory request for instruction fetch
@@ -724,15 +963,38 @@ SimpleCPU::tick()
#define IFETCH_FLAGS(pc) 0
#endif
- memReq->cmd = Read;
- memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t),
- IFETCH_FLAGS(cpuXC->readPC()));
+ DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(),
+ cpuXC->readNextPC(),cpuXC->readNextNPC());
+
+#if SIMPLE_CPU_MEM_TIMING
+ CpuRequest *ifetch_req = new CpuRequest();
+ ifetch_req->size = sizeof(MachInst);
+#endif
- fault = cpuXC->translateInstReq(memReq);
+ ifetch_req->vaddr = cpuXC->readPC() & ~3;
+ ifetch_req->time = curTick;
- if (fault == NoFault)
- fault = cpuXC->mem->read(memReq, inst);
+/* memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t),
+ IFETCH_FLAGS(xc->regs.pc));
+*/
+ fault = cpuXC->translateInstReq(ifetch_req);
+
+ if (fault == NoFault) {
+#if SIMPLE_CPU_MEM_TIMING
+ Packet *ifetch_pkt = new Packet;
+ ifetch_pkt->cmd = Read;
+ ifetch_pkt->data = (uint8_t *)&inst;
+ ifetch_pkt->req = ifetch_req;
+ ifetch_pkt->size = sizeof(MachInst);
+#endif
+ ifetch_pkt->addr = ifetch_req->paddr;
+
+ sendIcacheRequest(ifetch_pkt);
+#if SIMPLE_CPU_MEM_TIMING || SIMPLE_CPU_MEM_ATOMIC
+ return;
+#endif
+/*
if (icacheInterface && fault == NoFault) {
memReq->completionEvent = NULL;
@@ -743,7 +1005,7 @@ SimpleCPU::tick()
// Ugly hack to get an event scheduled *only* if the access is
// a miss. We really should add first-class support for this
// at some point.
- if (result != MA_HIT && icacheInterface->doEvents()) {
+ if (result != MA_HIT && icacheInterface->doEvents()) {
memReq->completionEvent = &cacheCompletionEvent;
lastIcacheStall = curTick;
unscheduleTickEvent();
@@ -751,6 +1013,8 @@ SimpleCPU::tick()
return;
}
}
+*/
+ }
}
// If we've got a valid instruction (i.e., no fault on instruction
@@ -771,6 +1035,9 @@ SimpleCPU::tick()
traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst,
cpuXC->readPC());
+ DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
+ curStaticInst->getName(),curStaticInst->getOpcode(), curStaticInst->machInst);
+
#if FULL_SYSTEM
cpuXC->setInst(inst);
#endif // FULL_SYSTEM
@@ -806,8 +1073,7 @@ SimpleCPU::tick()
// If we have a dcache miss, then we can't finialize the instruction
// trace yet because we want to populate it with the data later
- if (traceData &&
- !(status() == DcacheMissStall && memReq->cmd.isRead())) {
+ if (traceData && (status() != DcacheWaitResponse)) {
traceData->finalize();
}
@@ -819,7 +1085,7 @@ SimpleCPU::tick()
#if FULL_SYSTEM
fault->invoke(xcProxy);
#else // !FULL_SYSTEM
- fatal("fault (%d) detected @ PC 0x%08p", fault, cpuXC->readPC());
+ fatal("fault (%s) detected @ PC %08p", fault->name(), cpuXC->readPC());
#endif // FULL_SYSTEM
}
else {
@@ -846,7 +1112,7 @@ SimpleCPU::tick()
assert(status() == Running ||
status() == Idle ||
- status() == DcacheMissStall);
+ status() == DcacheWaitResponse);
if (status() == Running && !tickEvent.scheduled())
tickEvent.schedule(curTick + cycles(1));
@@ -866,17 +1132,15 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
SimObjectParam<AlphaDTB *> dtb;
- SimObjectParam<FunctionalMemory *> mem;
SimObjectParam<System *> system;
Param<int> cpu_id;
Param<Tick> profile;
#else
+ SimObjectParam<MemObject *> mem;
SimObjectParam<Process *> workload;
#endif // FULL_SYSTEM
Param<int> clock;
- SimObjectParam<BaseMem *> icache;
- SimObjectParam<BaseMem *> dcache;
Param<bool> defer_registration;
Param<int> width;
@@ -899,17 +1163,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
INIT_PARAM(dtb, "Data TLB"),
- INIT_PARAM(mem, "memory"),
INIT_PARAM(system, "system object"),
INIT_PARAM(cpu_id, "processor ID"),
INIT_PARAM(profile, ""),
#else
+ INIT_PARAM(mem, "memory"),
INIT_PARAM(workload, "processes to run"),
#endif // FULL_SYSTEM
INIT_PARAM(clock, "clock speed"),
- INIT_PARAM(icache, "L1 instruction cache object"),
- INIT_PARAM(dcache, "L1 data cache object"),
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(width, "cpu width"),
INIT_PARAM(function_trace, "Enable function trace"),
@@ -931,18 +1193,16 @@ CREATE_SIM_OBJECT(SimpleCPU)
params->clock = clock;
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;
- params->icache_interface = (icache) ? icache->getInterface() : NULL;
- params->dcache_interface = (dcache) ? dcache->getInterface() : NULL;
params->width = width;
#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
- params->mem = mem;
params->system = system;
params->cpu_id = cpu_id;
params->profile = profile;
#else
+ params->mem = mem;
params->process = workload;
#endif
diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh
index 4ab9a1c3e..dc07027f9 100644
--- a/cpu/simple/cpu.hh
+++ b/cpu/simple/cpu.hh
@@ -36,6 +36,9 @@
#include "cpu/pc_event.hh"
#include "cpu/sampler/sampler.hh"
#include "cpu/static_inst.hh"
+#include "mem/packet.hh"
+#include "mem/port.hh"
+#include "mem/request.hh"
#include "sim/eventq.hh"
// forward declarations
@@ -43,7 +46,7 @@
class Processor;
class AlphaITB;
class AlphaDTB;
-class PhysicalMemory;
+class MemObject;
class RemoteGDB;
class GDBListener;
@@ -55,18 +58,56 @@ class Process;
#endif // FULL_SYSTEM
class ExecContext;
-class MemInterface;
class Checkpoint;
namespace Trace {
class InstRecord;
}
+
+// Set exactly one of these symbols to 1 to set the memory access
+// model. Probably should make these template parameters, or even
+// just fork the CPU models.
+//
+#define SIMPLE_CPU_MEM_TIMING 0
+#define SIMPLE_CPU_MEM_ATOMIC 0
+#define SIMPLE_CPU_MEM_IMMEDIATE 1
+
+
class SimpleCPU : public BaseCPU
{
protected:
typedef TheISA::MachInst MachInst;
typedef TheISA::MiscReg MiscReg;
+ typedef TheISA::FloatReg FloatReg;
+ typedef TheISA::FloatRegBits FloatRegBits;
+ class CpuPort : public Port
+ {
+
+ SimpleCPU *cpu;
+
+ public:
+
+ CpuPort(SimpleCPU *_cpu)
+ : cpu(_cpu)
+ { }
+
+ protected:
+
+ virtual bool recvTiming(Packet &pkt);
+
+ virtual Tick recvAtomic(Packet &pkt);
+
+ virtual void recvFunctional(Packet &pkt);
+
+ virtual void recvStatusChange(Status status);
+
+ virtual Packet *recvRetry();
+ };
+
+ CpuPort icachePort;
+ CpuPort dcachePort;
+
public:
// main simulation loop (one cycle)
void tick();
@@ -109,10 +150,12 @@ class SimpleCPU : public BaseCPU
enum Status {
Running,
Idle,
- IcacheMissStall,
- IcacheMissComplete,
- DcacheMissStall,
- DcacheMissSwitch,
+ IcacheRetry,
+ IcacheWaitResponse,
+ IcacheAccessComplete,
+ DcacheRetry,
+ DcacheWaitResponse,
+ DcacheWaitSwitch,
SwitchedOut
};
@@ -133,14 +176,12 @@ class SimpleCPU : public BaseCPU
public:
struct Params : public BaseCPU::Params
{
- MemInterface *icache_interface;
- MemInterface *dcache_interface;
int width;
#if FULL_SYSTEM
AlphaITB *itb;
AlphaDTB *dtb;
- FunctionalMemory *mem;
#else
+ MemObject *mem;
Process *process;
#endif
};
@@ -162,17 +203,19 @@ class SimpleCPU : public BaseCPU
bool interval_stats;
#endif
- // L1 instruction cache
- MemInterface *icacheInterface;
-
- // L1 data cache
- MemInterface *dcacheInterface;
-
// current instruction
MachInst inst;
- // Refcounted pointer to the one memory request.
- MemReqPtr memReq;
+#if SIMPLE_CPU_MEM_TIMING
+ Packet *retry_pkt;
+#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
+ CpuRequest *ifetch_req;
+ Packet *ifetch_pkt;
+ CpuRequest *data_read_req;
+ Packet *data_read_pkt;
+ CpuRequest *data_write_req;
+ Packet *data_write_pkt;
+#endif
// Pointer to the sampler that is telling us to switchover.
// Used to signal the completion of the pipe drain and schedule
@@ -181,20 +224,6 @@ class SimpleCPU : public BaseCPU
StaticInstPtr curStaticInst;
- class CacheCompletionEvent : public Event
- {
- private:
- SimpleCPU *cpu;
-
- public:
- CacheCompletionEvent(SimpleCPU *_cpu);
-
- virtual void process();
- virtual const char *description();
- };
-
- CacheCompletionEvent cacheCompletionEvent;
-
Status status() const { return _status; }
virtual void activateContext(int thread_num, int delay);
@@ -227,15 +256,28 @@ class SimpleCPU : public BaseCPU
Stats::Average<> notIdleFraction;
Stats::Formula idleFraction;
- // number of cycles stalled for I-cache misses
+ // number of cycles stalled for I-cache responses
Stats::Scalar<> icacheStallCycles;
Counter lastIcacheStall;
- // number of cycles stalled for D-cache misses
+ // number of cycles stalled for I-cache retries
+ Stats::Scalar<> icacheRetryCycles;
+ Counter lastIcacheRetry;
+
+ // number of cycles stalled for D-cache responses
Stats::Scalar<> dcacheStallCycles;
Counter lastDcacheStall;
- void processCacheCompletion();
+ // number of cycles stalled for D-cache retries
+ Stats::Scalar<> dcacheRetryCycles;
+ Counter lastDcacheRetry;
+
+ void sendIcacheRequest(Packet *pkt);
+ void sendDcacheRequest(Packet *pkt);
+ void processResponse(Packet &response);
+
+ Packet * processRetry();
+ void recvStatusChange(Port::Status status) {}
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
@@ -281,22 +323,28 @@ class SimpleCPU : public BaseCPU
return cpuXC->readIntReg(si->srcRegIdx(idx));
}
- float readFloatRegSingle(const StaticInst *si, int idx)
+ FloatReg readFloatReg(const StaticInst *si, int idx, int width)
+ {
+ int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
+ return cpuXC->readFloatReg(reg_idx, width);
+ }
+
+ FloatReg readFloatReg(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return cpuXC->readFloatRegSingle(reg_idx);
+ return cpuXC->readFloatReg(reg_idx);
}
- double readFloatRegDouble(const StaticInst *si, int idx)
+ FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return cpuXC->readFloatRegDouble(reg_idx);
+ return cpuXC->readFloatRegBits(reg_idx, width);
}
- uint64_t readFloatRegInt(const StaticInst *si, int idx)
+ FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return cpuXC->readFloatRegInt(reg_idx);
+ return cpuXC->readFloatRegBits(reg_idx);
}
void setIntReg(const StaticInst *si, int idx, uint64_t val)
@@ -304,26 +352,38 @@ class SimpleCPU : public BaseCPU
cpuXC->setIntReg(si->destRegIdx(idx), val);
}
- void setFloatRegSingle(const StaticInst *si, int idx, float val)
+ void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- cpuXC->setFloatRegSingle(reg_idx, val);
+ cpuXC->setFloatReg(reg_idx, val, width);
}
- void setFloatRegDouble(const StaticInst *si, int idx, double val)
+ void setFloatReg(const StaticInst *si, int idx, FloatReg val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- cpuXC->setFloatRegDouble(reg_idx, val);
+ cpuXC->setFloatReg(reg_idx, val);
}
- void setFloatRegInt(const StaticInst *si, int idx, uint64_t val)
+ void setFloatRegBits(const StaticInst *si, int idx,
+ FloatRegBits val, int width)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- cpuXC->setFloatRegInt(reg_idx, val);
+ cpuXC->setFloatRegBits(reg_idx, val, width);
+ }
+
+ void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val)
+ {
+ int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
+ cpuXC->setFloatRegBits(reg_idx, val);
}
uint64_t readPC() { return cpuXC->readPC(); }
+ uint64_t readNextPC() { return cpuXC->readNextPC(); }
+ uint64_t readNextNPC() { return cpuXC->readNextNPC(); }
+
+ void setPC(uint64_t val) { cpuXC->setPC(val); }
void setNextPC(uint64_t val) { cpuXC->setNextPC(val); }
+ void setNextNPC(uint64_t val) { cpuXC->setNextNPC(val); }
MiscReg readMiscReg(int misc_reg)
{
diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh
index 20116554e..a200e2849 100644
--- a/cpu/static_inst.hh
+++ b/cpu/static_inst.hh
@@ -33,8 +33,9 @@
#include <string>
#include "base/hashmap.hh"
+#include "base/misc.hh"
#include "base/refcnt.hh"
-#include "encumbered/cpu/full/op_class.hh"
+#include "cpu/op_class.hh"
#include "sim/host.hh"
#include "arch/isa_traits.hh"
@@ -390,6 +391,17 @@ class StaticInst : public StaticInstBase
/// @retval A pointer to the corresponding StaticInst object.
//This is defined as inline below.
static StaticInstPtr decode(ExtMachInst mach_inst);
+
+ //MIPS Decoder Debug Functions
+ int getOpcode() { return (machInst & 0xFC000000) >> 26 ; }//31..26
+ int getRs() { return (machInst & 0x03E00000) >> 21; } //25...21
+ int getRt() { return (machInst & 0x001F0000) >> 16; } //20...16
+ int getRd() { return (machInst & 0x0000F800) >> 11; } //15...11
+ int getOpname(){ return (machInst & 0x0000003F); }//5...0
+ int getBranch(){ return (machInst & 0x0000FFFF); }//5...0
+ int getJump(){ return (machInst & 0x03FFFFFF); }//5...0
+ int getHint(){ return (machInst & 0x000007C0) >> 6; } //10...6
+ std::string getName() { return mnemonic; }
};
typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc
index 6ca5e3a06..f40c5b7bf 100644
--- a/dev/alpha_console.cc
+++ b/dev/alpha_console.cc
@@ -34,6 +34,7 @@
#include <cstdio>
#include <string>
+#include "arch/alpha/ev5.hh"
#include "arch/alpha/system.hh"
#include "base/inifile.hh"
#include "base/str.hh"
diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc
index 56682a224..fed604867 100644
--- a/dev/ide_ctrl.cc
+++ b/dev/ide_ctrl.cc
@@ -31,6 +31,7 @@
#include <string>
#include <vector>
+#include "arch/alpha/ev5.hh"
#include "base/trace.hh"
#include "cpu/intr_control.hh"
#include "dev/ide_ctrl.hh"
diff --git a/dev/io_device.cc b/dev/io_device.cc
index 6ab876ab8..b580c2805 100644
--- a/dev/io_device.cc
+++ b/dev/io_device.cc
@@ -27,25 +27,119 @@
*/
#include "dev/io_device.hh"
-#include "mem/bus/base_interface.hh"
-#include "mem/bus/dma_interface.hh"
#include "sim/builder.hh"
+void
+PioPort::SendEvent::process()
+{
+ if (port->sendTiming(packet) == Success)
+ return;
+
+ port->transmitList.push_back(&packet);
+}
+
PioDevice::PioDevice(const std::string &name, Platform *p)
- : FunctionalMemory(name), platform(p), pioInterface(NULL), pioLatency(0)
-{}
+ : SimObject(name), platform(p)
+{
+ pioPort = new PioPort(this);
+}
+
+
+bool
+PioDevice::recvTiming(Packet &pkt)
+{
+ device->recvAtomic(pkt);
+ sendTiming(pkt, pkt.responseTime-pkt.requestTime);
+ return Success;
+}
PioDevice::~PioDevice()
{
- if (pioInterface)
+ if (pioPort)
delete pioInterface;
}
-DEFINE_SIM_OBJECT_CLASS_NAME("PioDevice", PioDevice)
+void
+DmaPort::sendDma(Packet &pkt)
+{
+ device->platform->system->memoryMode()
+ {
+ case MemAtomic:
+ }
+}
DmaDevice::DmaDevice(const std::string &name, Platform *p)
- : PioDevice(name, p), dmaInterface(NULL)
-{}
+ : PioDevice(name, p)
+{
+ dmaPort = new dmaPort(this);
+}
+
+void
+DmaPort::dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size,
+ Event *event, uint8_t *data = NULL)
+{
+
+ assert(event);
+
+ int prevSize = 0;
+ Packet basePkt;
+ Request baseReq;
+
+ basePkt.flags = 0;
+ basePkt.coherence = NULL;
+ basePkt.senderState = NULL;
+ basePkt.src = 0;
+ basePkt.dest = 0;
+ basePkt.cmd = cmd;
+ basePkt.result = Unknown;
+ basePkt.request = NULL;
+ baseReq.nicReq = true;
+ baseReq.time = curTick;
+
+ completionEvent = event;
+
+ for (ChunkGenerator gen(addr, size, peerBlockSize());
+ !gen.done(); gen.next()) {
+ Packet *pkt = new Packet(basePkt);
+ Request *req = new Request(baseReq);
+ pkt->addr = gen.addr();
+ pkt->size = gen.size();
+ pkt->req = req;
+ pkt->req->paddr = pkt->addr;
+ pkt->req->size = pkt->size;
+ // Increment the data pointer on a write
+ pkt->data = data ? data + prevSize : NULL ;
+ prevSize = pkt->size;
+
+ sendDma(*pkt);
+ }
+}
+
+
+void
+DmaPort::sendDma(Packet &pkt)
+{
+ // some kind of selction between access methods
+ // more work is going to have to be done to make
+ // switching actually work
+ MemState state = device->platform->system->memState;
+
+ if (state == Timing) {
+ if (sendTiming(pkt) == Failure)
+ transmitList.push_back(&packet);
+ } else if (state == Atomic) {
+ sendAtomic(pkt);
+ completionEvent->schedule(pkt.responseTime - pkt.requestTime);
+ completionEvent == NULL;
+ } else if (state == Functional) {
+ sendFunctional(pkt);
+ // Is this correct???
+ completionEvent->schedule(pkt.responseTime - pkt.requestTime);
+ completionEvent == NULL;
+ } else
+ panic("Unknown memory command state.");
+
+}
DmaDevice::~DmaDevice()
{
@@ -53,5 +147,4 @@ DmaDevice::~DmaDevice()
delete dmaInterface;
}
-DEFINE_SIM_OBJECT_CLASS_NAME("DmaDevice", DmaDevice)
diff --git a/dev/io_device.hh b/dev/io_device.hh
index bcfd062b9..a79c3f20a 100644
--- a/dev/io_device.hh
+++ b/dev/io_device.hh
@@ -29,34 +29,165 @@
#ifndef __DEV_IO_DEVICE_HH__
#define __DEV_IO_DEVICE_HH__
-#include "mem/functional/functional.hh"
+#include "base/chunk_generator.hh"
+#include "mem/port.hh"
+#include "sim/eventq.hh"
-class BaseInterface;
class Bus;
-class HierParams;
class Platform;
-template <class BusType> class DMAInterface;
+class PioDevice;
-class PioDevice : public FunctionalMemory
+class PioPort : public Port
{
protected:
+ PioDevice *device;
+
+ virtual bool recvTiming(Packet &pkt);
+
+ virtual Tick recvAtomic(Packet &pkt)
+ { return device->recvAtomic(pkt) };
+
+ virtual void recvFunctional(Packet &pkt)
+ { device->recvAtomic(pkt) };
+
+ virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner)
+ { device->addressRanges(range_list, owner); }
+
+ void sendTiming(Packet &pkt, Tick time)
+ { new SendEvent(this, pkt, time); }
+
+ class SendEvent : public Event
+ {
+ PioPort *port;
+ Packet packet;
+
+ SendEvent(PioPort *p, Packet &pkt, Tick t)
+ : Event(&mainEventQueue), packet(pkt)
+ { schedule(curTick + t); }
+
+ virtual void process();
+
+ virtual const char *description()
+ { return "Future scheduled sendTiming event"; }
+
+ friend class PioPort;
+ }
+
+ public:
+ PioPort(PioDevice *dev)
+ : device(dev)
+ { }
+
+};
+
+class DmaPort : public Port
+{
+ protected:
+ PioDevice *device;
+ std::list<Packet*> transmitList;
+
+
+ virtual bool recvTiming(Packet &pkt)
+ { completionEvent->schedule(curTick+1); completionEvent = NULL; }
+ virtual Tick recvAtomic(Packet &pkt)
+ { panic("dma port shouldn't be used for pio access."); }
+ virtual void recvFunctional(Packet &pkt)
+ { panic("dma port shouldn't be used for pio access."); }
+
+ virtual void recvStatusChange(Status status)
+ { ; }
+
+ virtual Packet *recvRetry()
+ { return transmitList.pop_front(); }
+
+ virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner)
+ { range_list.clear(); owner = true; }
+
+ void dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size,
+ Event *event, uint8_t *data = NULL);
+
+ void sendDma(Packet &pkt);
+
+ virtual Packet *recvRetry()
+ { return transmitList.pop_front(); }
+
+ class SendEvent : public Event
+ {
+ PioPort *port;
+ Packet packet;
+
+ SendEvent(PioPort *p, Packet &pkt, Tick t)
+ : Event(&mainEventQueue), packet(pkt)
+ { schedule(curTick + t); }
+
+ virtual void process();
+
+ virtual const char *description()
+ { return "Future scheduled sendTiming event"; }
+
+ friend class PioPort;
+ }
+ public:
+ DmaPort(DmaDevice *dev)
+ : device(dev)
+ { }
+
+
+};
+
+
+class PioDevice : public SimObject
+{
+ protected:
+
Platform *platform;
- BaseInterface *pioInterface;
- Tick pioLatency;
+
+ PioPort *pioPort;
+
+ virtual void addressRanges(AddrRangeList &range_list, bool &owner) = 0;
+
+ virtual read(Packet &pkt) = 0;
+
+ virtual write(Packet &pkt) = 0;
+
+ Tick recvAtomic(Packet &pkt)
+ { return pkt->cmd == Read ? this->read(pkt) : this->write(pkt); }
public:
PioDevice(const std::string &name, Platform *p);
+
virtual ~PioDevice();
+
+ virtual Port *getPort(std::string if_name)
+ {
+ if (if_name == "pio")
+ return pioPort;
+ else
+ return NULL;
+ }
};
class DmaDevice : public PioDevice
{
protected:
- DMAInterface<Bus> *dmaInterface;
+ DmaPort *dmaPort;
public:
DmaDevice(const std::string &name, Platform *p);
virtual ~DmaDevice();
+
+ virtual Port *getPort(std::string if_name)
+ {
+ if (if_name == "pio")
+ return pioPort;
+ else if (if_name = "dma")
+ return dmaPort;
+ else
+ return NULL;
+ }
};
+
+
+
#endif // __DEV_IO_DEVICE_HH__
diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc
index 2afebbded..7ce43b712 100644
--- a/dev/isa_fake.cc
+++ b/dev/isa_fake.cc
@@ -34,6 +34,7 @@
#include <string>
#include <vector>
+#include "arch/alpha/ev5.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "dev/isa_fake.hh"
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index ed8c794f9..f7e67811c 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -34,6 +34,7 @@
#include <deque>
#include <string>
+#include "arch/alpha/ev5.hh"
#include "base/inet.hh"
#include "cpu/exec_context.hh"
#include "dev/etherlink.hh"
diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc
index d55084fa5..1a138fb39 100644
--- a/dev/pciconfigall.cc
+++ b/dev/pciconfigall.cc
@@ -35,6 +35,7 @@
#include <vector>
#include <bitset>
+#include "arch/alpha/ev5.hh"
#include "base/trace.hh"
#include "dev/pciconfigall.hh"
#include "dev/pcidev.hh"
diff --git a/dev/platform.hh b/dev/platform.hh
index 1ee645454..2c37048d4 100644
--- a/dev/platform.hh
+++ b/dev/platform.hh
@@ -41,6 +41,7 @@ class PciConfigAll;
class IntrControl;
class SimConsole;
class Uart;
+class System;
class Platform : public SimObject
{
@@ -54,6 +55,9 @@ class Platform : public SimObject
/** Pointer to the UART, set by the uart */
Uart *uart;
+ /** Pointer to the system for info about the memory system. */
+ System *system;
+
public:
Platform(const std::string &name, IntrControl *intctrl, PciConfigAll *pci);
virtual ~Platform();
diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc
index 2649fe27a..8c6db8a43 100644
--- a/dev/tsunami_cchip.cc
+++ b/dev/tsunami_cchip.cc
@@ -34,6 +34,7 @@
#include <string>
#include <vector>
+#include "arch/alpha/ev5.hh"
#include "base/trace.hh"
#include "dev/tsunami_cchip.hh"
#include "dev/tsunamireg.h"
diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc
index e66d6653b..14fa97341 100644
--- a/dev/tsunami_io.cc
+++ b/dev/tsunami_io.cc
@@ -36,6 +36,7 @@
#include <string>
#include <vector>
+#include "arch/alpha/ev5.hh"
#include "base/trace.hh"
#include "dev/tsunami_io.hh"
#include "dev/tsunami.hh"
diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc
index 46efc3dfe..202076754 100644
--- a/dev/tsunami_pchip.cc
+++ b/dev/tsunami_pchip.cc
@@ -34,6 +34,7 @@
#include <string>
#include <vector>
+#include "arch/alpha/ev5.hh"
#include "base/trace.hh"
#include "dev/tsunami_pchip.hh"
#include "dev/tsunamireg.h"
diff --git a/dev/uart8250.cc b/dev/uart8250.cc
index 65bccee86..7b72b7ef4 100644
--- a/dev/uart8250.cc
+++ b/dev/uart8250.cc
@@ -33,6 +33,7 @@
#include <string>
#include <vector>
+#include "arch/alpha/ev5.hh"
#include "base/inifile.hh"
#include "base/str.hh" // for to_number
#include "base/trace.hh"
diff --git a/kern/linux/linux.hh b/kern/linux/linux.hh
index 0dbccf546..9237084fc 100644
--- a/kern/linux/linux.hh
+++ b/kern/linux/linux.hh
@@ -46,6 +46,8 @@ class Linux {};
#include "sim/syscall_emul.hh"
+class TranslatingPort;
+
///
/// This class encapsulates the types, structures, constants,
/// functions, and syscall-number mappings specific to the Alpha Linux
@@ -240,8 +242,10 @@ class Linux {
/// memory space. Used by stat(), fstat(), and lstat().
#if !BSD_HOST
static void
- copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat *host)
+ copyOutStatBuf(TranslatingPort *mem, Addr addr, hst_stat *host)
{
+ using namespace TheISA;
+
TypedBufferArg<Linux::tgt_stat> tgt(addr);
tgt->st_dev = htog(host->st_dev);
@@ -264,8 +268,10 @@ class Linux {
// Third version for bsd systems which no longer have any support for
// the old stat() call and stat() is actually a stat64()
static void
- copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat64 *host)
+ copyOutStatBuf(TranslatingPort *mem, Addr addr, hst_stat64 *host)
{
+ using namespace TheISA;
+
TypedBufferArg<Linux::tgt_stat> tgt(addr);
tgt->st_dev = htog(host->st_dev);
@@ -289,8 +295,10 @@ class Linux {
// Same for stat64
static void
- copyOutStat64Buf(FunctionalMemory *mem, int fd, Addr addr, hst_stat64 *host)
+ copyOutStat64Buf(TranslatingPort *mem, int fd, Addr addr, hst_stat64 *host)
{
+ using namespace TheISA;
+
TypedBufferArg<Linux::tgt_stat64> tgt(addr);
// fd == 1 checks are because libc does some checks
diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh
index 112f00f31..3f5ef3dea 100644
--- a/kern/tru64/tru64.hh
+++ b/kern/tru64/tru64.hh
@@ -61,6 +61,8 @@ typedef struct stat global_stat;
typedef struct statfs global_statfs;
typedef struct dirent global_dirent;
+class TranslatingPort;
+
///
/// This class encapsulates the types, structures, constants,
/// functions, and syscall-number mappings specific to the Alpha Tru64
@@ -540,8 +542,10 @@ class Tru64 {
/// memory space. Used by stat(), fstat(), and lstat().
template <class T>
static void
- copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host)
+ copyOutStatBuf(TranslatingPort *mem, Addr addr, global_stat *host)
{
+ using namespace TheISA;
+
TypedBufferArg<T> tgt(addr);
tgt->st_dev = htog(host->st_dev);
@@ -566,8 +570,10 @@ class Tru64 {
/// memory space. Used by statfs() and fstatfs().
template <class T>
static void
- copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host)
+ copyOutStatfsBuf(TranslatingPort *mem, Addr addr, global_statfs *host)
{
+ using namespace TheISA;
+
TypedBufferArg<T> tgt(addr);
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__)
@@ -590,13 +596,13 @@ class Tru64 {
class F64 {
public:
- static void copyOutStatBuf(FunctionalMemory *mem, Addr addr,
+ static void copyOutStatBuf(TranslatingPort *mem, Addr addr,
global_stat *host)
{
Tru64::copyOutStatBuf<Tru64::F64_stat>(mem, addr, host);
}
- static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr,
+ static void copyOutStatfsBuf(TranslatingPort *mem, Addr addr,
global_statfs *host)
{
Tru64::copyOutStatfsBuf<Tru64::F64_statfs>(mem, addr, host);
@@ -605,13 +611,13 @@ class Tru64 {
class PreF64 {
public:
- static void copyOutStatBuf(FunctionalMemory *mem, Addr addr,
+ static void copyOutStatBuf(TranslatingPort *mem, Addr addr,
global_stat *host)
{
Tru64::copyOutStatBuf<Tru64::pre_F64_stat>(mem, addr, host);
}
- static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr,
+ static void copyOutStatfsBuf(TranslatingPort *mem, Addr addr,
global_statfs *host)
{
Tru64::copyOutStatfsBuf<Tru64::pre_F64_statfs>(mem, addr, host);
@@ -623,8 +629,10 @@ class Tru64 {
/// the simulated memory space. Used by pre_F64_stat(),
/// pre_F64_fstat(), and pre_F64_lstat().
static void
- copyOutPreF64StatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
+ copyOutPreF64StatBuf(TranslatingPort *mem, Addr addr, struct stat *host)
{
+ using namespace TheISA;
+
TypedBufferArg<Tru64::pre_F64_stat> tgt(addr);
tgt->st_dev = htog(host->st_dev);
@@ -654,6 +662,8 @@ class Tru64 {
getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
+ using namespace TheISA;
+
#ifdef __CYGWIN__
panic("getdirent not implemented on cygwin!");
#else
@@ -666,7 +676,7 @@ class Tru64 {
// just pass basep through uninterpreted.
TypedBufferArg<int64_t> basep(tgt_basep);
- basep.copyIn(xc->getMemPtr());
+ basep.copyIn(xc->getMemPort());
long host_basep = (off_t)htog((int64_t)*basep);
int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
@@ -693,7 +703,7 @@ class Tru64 {
tgt_dp->d_reclen = tgt_bufsize;
tgt_dp->d_namlen = namelen;
strcpy(tgt_dp->d_name, host_dp->d_name);
- tgt_dp.copyOut(xc->getMemPtr());
+ tgt_dp.copyOut(xc->getMemPort());
tgt_buf_ptr += tgt_bufsize;
host_buf_ptr += host_dp->d_reclen;
@@ -702,7 +712,7 @@ class Tru64 {
delete [] host_buf;
*basep = htog((int64_t)host_basep);
- basep.copyOut(xc->getMemPtr());
+ basep.copyOut(xc->getMemPort());
return tgt_buf_ptr - tgt_buf;
#endif
@@ -713,10 +723,12 @@ class Tru64 {
sigreturnFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
+ using namespace TheISA;
+
using TheISA::RegFile;
TypedBufferArg<Tru64::sigcontext> sc(xc->getSyscallArg(0));
- sc.copyIn(xc->getMemPtr());
+ sc.copyIn(xc->getMemPort());
// Restore state from sigcontext structure.
// Note that we'll advance PC <- NPC before the end of the cycle,
@@ -726,7 +738,7 @@ class Tru64 {
for (int i = 0; i < 31; ++i) {
xc->setIntReg(i, htog(sc->sc_regs[i]));
- xc->setFloatRegInt(i, htog(sc->sc_fpregs[i]));
+ xc->setFloatRegBits(i, htog(sc->sc_fpregs[i]));
}
xc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr));
@@ -739,6 +751,8 @@ class Tru64 {
tableFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
+ using namespace TheISA;
+
int id = xc->getSyscallArg(0); // table ID
int index = xc->getSyscallArg(1); // index into table
// arg 2 is buffer pointer; type depends on table ID
@@ -761,7 +775,7 @@ class Tru64 {
elp->si_phz = htog(clk_hz);
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
elp->si_max_procs = htog(process->numCpus());
- elp.copyOut(xc->getMemPtr());
+ elp.copyOut(xc->getMemPort());
return 0;
}
@@ -780,9 +794,11 @@ class Tru64 {
stack_createFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
+ using namespace TheISA;
+
TypedBufferArg<Tru64::vm_stack> argp(xc->getSyscallArg(0));
- argp.copyIn(xc->getMemPtr());
+ argp.copyIn(xc->getMemPort());
// if the user chose an address, just let them have it. Otherwise
// pick one for them.
@@ -791,7 +807,7 @@ class Tru64 {
int stack_size = (htog(argp->rsize) + htog(argp->ysize) +
htog(argp->gsize));
process->next_thread_stack_base -= stack_size;
- argp.copyOut(xc->getMemPtr());
+ argp.copyOut(xc->getMemPort());
}
return 0;
@@ -808,10 +824,12 @@ class Tru64 {
nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
+ using namespace TheISA;
+
TypedBufferArg<Tru64::nxm_task_attr> attrp(xc->getSyscallArg(0));
TypedBufferArg<Addr> configptr_ptr(xc->getSyscallArg(1));
- attrp.copyIn(xc->getMemPtr());
+ attrp.copyIn(xc->getMemPort());
if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) {
cerr << "nxm_task_init: thread library version mismatch! "
@@ -852,7 +870,7 @@ class Tru64 {
config->nxm_slot_state = htog(slot_state_addr);
config->nxm_rad[0] = htog(rad_state_addr);
- config.copyOut(xc->getMemPtr());
+ config.copyOut(xc->getMemPort());
// initialize the slot_state array and copy it out
TypedBufferArg<Tru64::nxm_slot_state_t> slot_state(slot_state_addr,
@@ -865,7 +883,7 @@ class Tru64 {
(i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL;
}
- slot_state.copyOut(xc->getMemPtr());
+ slot_state.copyOut(xc->getMemPort());
// same for the per-RAD "shared" struct. Note that we need to
// allocate extra bytes for the per-VP array which is embedded at
@@ -899,13 +917,13 @@ class Tru64 {
}
}
- rad_state.copyOut(xc->getMemPtr());
+ rad_state.copyOut(xc->getMemPort());
//
// copy pointer to shared config area out to user
//
*configptr_ptr = htog(config_addr);
- configptr_ptr.copyOut(xc->getMemPtr());
+ configptr_ptr.copyOut(xc->getMemPort());
// Register this as a valid address range with the process
process->nxm_start = base_addr;
@@ -919,6 +937,8 @@ class Tru64 {
init_exec_context(ExecContext *ec,
Tru64::nxm_thread_attr *attrp, uint64_t uniq_val)
{
+ using namespace TheISA;
+
ec->clearArchRegs();
ec->setIntReg(TheISA::ArgumentReg0, gtoh(attrp->registers.a0));
@@ -937,12 +957,14 @@ class Tru64 {
nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
+ using namespace TheISA;
+
TypedBufferArg<Tru64::nxm_thread_attr> attrp(xc->getSyscallArg(0));
TypedBufferArg<uint64_t> kidp(xc->getSyscallArg(1));
int thread_index = xc->getSyscallArg(2);
// get attribute args
- attrp.copyIn(xc->getMemPtr());
+ attrp.copyIn(xc->getMemPort());
if (gtoh(attrp->version) != NXM_LIB_VERSION) {
cerr << "nxm_thread_create: thread library version mismatch! "
@@ -967,7 +989,7 @@ class Tru64 {
TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
rad_state_size);
- rad_state.copyIn(xc->getMemPtr());
+ rad_state.copyIn(xc->getMemPort());
uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset);
@@ -978,7 +1000,7 @@ class Tru64 {
// This is supposed to be a port number. Make something up.
*kidp = htog(99);
- kidp.copyOut(xc->getMemPtr());
+ kidp.copyOut(xc->getMemPort());
return 0;
} else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) {
@@ -992,7 +1014,7 @@ class Tru64 {
ssp->nxm_u.pth_id = attrp->pthid;
ssp->nxm_u.nxm_active = htog(uniq_val | 1);
- rad_state.copyOut(xc->getMemPtr());
+ rad_state.copyOut(xc->getMemPort());
Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info);
int slot_state_size =
@@ -1002,7 +1024,7 @@ class Tru64 {
slot_state(slot_state_addr,
slot_state_size);
- slot_state.copyIn(xc->getMemPtr());
+ slot_state.copyIn(xc->getMemPort());
if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
cerr << "nxm_thread_createFunc: requested VP slot "
@@ -1014,7 +1036,7 @@ class Tru64 {
// doesn't work anyway
slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
- slot_state.copyOut(xc->getMemPtr());
+ slot_state.copyOut(xc->getMemPort());
// Find a free simulator execution context.
for (int i = 0; i < process->numCpus(); ++i) {
@@ -1028,7 +1050,7 @@ class Tru64 {
// and get away with just sticking the thread index
// here.
*kidp = htog(thread_index);
- kidp.copyOut(xc->getMemPtr());
+ kidp.copyOut(xc->getMemPort());
return 0;
}
@@ -1155,14 +1177,16 @@ class Tru64 {
static void
m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc)
{
+ using namespace TheISA;
+
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(xc->getMemPtr());
+ lockp.copyIn(xc->getMemPort());
if (gtoh(*lockp) == 0) {
// lock is free: grab it
*lockp = htog(1);
- lockp.copyOut(xc->getMemPtr());
+ lockp.copyOut(xc->getMemPort());
} else {
// lock is busy: disable until free
process->waitList.push_back(Process::WaitRec(uaddr, xc));
@@ -1176,7 +1200,7 @@ class Tru64 {
{
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(xc->getMemPtr());
+ lockp.copyIn(xc->getMemPort());
assert(*lockp != 0);
// Check for a process waiting on the lock.
@@ -1185,7 +1209,7 @@ class Tru64 {
// clear lock field if no waiting context is taking over the lock
if (num_waiting == 0) {
*lockp = 0;
- lockp.copyOut(xc->getMemPtr());
+ lockp.copyOut(xc->getMemPort());
}
}
@@ -1209,15 +1233,17 @@ class Tru64 {
m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
+ using namespace TheISA;
+
Addr uaddr = xc->getSyscallArg(0);
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(xc->getMemPtr());
+ lockp.copyIn(xc->getMemPort());
if (gtoh(*lockp) == 0) {
// lock is free: grab it
*lockp = htog(1);
- lockp.copyOut(xc->getMemPtr());
+ lockp.copyOut(xc->getMemPort());
return 0;
} else {
return 1;
@@ -1266,13 +1292,15 @@ class Tru64 {
m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
+ using namespace TheISA;
+
Addr cond_addr = xc->getSyscallArg(0);
Addr lock_addr = xc->getSyscallArg(1);
TypedBufferArg<uint64_t> condp(cond_addr);
TypedBufferArg<uint64_t> lockp(lock_addr);
// user is supposed to acquire lock before entering
- lockp.copyIn(xc->getMemPtr());
+ lockp.copyIn(xc->getMemPort());
assert(gtoh(*lockp) != 0);
m5_unlock_mutex(lock_addr, process, xc);
diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc
index 8f2be6d9b..855c3cd36 100644
--- a/kern/tru64/tru64_events.cc
+++ b/kern/tru64/tru64_events.cc
@@ -33,6 +33,7 @@
#include "kern/tru64/dump_mbuf.hh"
#include "kern/tru64/printf.hh"
#include "mem/functional/memory_control.hh"
+#include "arch/alpha/ev5.hh"
#include "arch/arguments.hh"
#include "arch/isa_traits.hh"
#include "sim/system.hh"
diff --git a/mem/bus.hh b/mem/bus.hh
new file mode 100644
index 000000000..e26065295
--- /dev/null
+++ b/mem/bus.hh
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ */
+
+/**
+ * @file Decleration of a bus object.
+ */
+
+#ifndef __MEM_BUS_HH__
+#define __MEM_BUS_HH__
+
+#include <string>
+#include <list>
+#include <inttypes.h>
+
+#include "base/range.hh"
+#include "mem/mem_object.hh"
+#include "mem/packet.hh"
+#include "mem/port.hh"
+#include "mem/request.hh"
+
+class Bus : public MemObject
+{
+ /** Function called by the port when the bus is recieving a Timing
+ transaction.*/
+ bool recvTiming(Packet &pkt, int id);
+
+ /** Function called by the port when the bus is recieving a Atomic
+ transaction.*/
+ Tick recvAtomic(Packet &pkt, int id);
+
+ /** Function called by the port when the bus is recieving a Functional
+ transaction.*/
+ void recvFunctional(Packet &pkt, int id);
+
+ /** Function called by the port when the bus is recieving a status change.*/
+ void recvStatusChange(Port::Status status, int id);
+
+ /** Decleration of the buses port type, one will be instantiated for each
+ of the interfaces connecting to the bus. */
+ class BusPort : public Port
+ {
+ /** A pointer to the bus to which this port belongs. */
+ Bus *bus;
+
+ /** A id to keep track of the intercafe ID this port is connected to. */
+ int id;
+
+ public:
+
+ /** Constructor for the BusPort.*/
+ BusPort(Bus *_bus, int _id)
+ : bus(_bus), id(_id)
+ { }
+
+ protected:
+
+ /** When reciving a timing request from the peer port (at id),
+ pass it to the bus. */
+ virtual bool recvTiming(Packet &pkt)
+ { return bus->recvTiming(pkt, id); }
+
+ /** When reciving a Atomic requestfrom the peer port (at id),
+ pass it to the bus. */
+ virtual Tick recvAtomic(Packet &pkt)
+ { return bus->recvAtomic(pkt, id); }
+
+ /** When reciving a Functional requestfrom the peer port (at id),
+ pass it to the bus. */
+ virtual void recvFunctional(Packet &pkt)
+ { bus->recvFunctional(pkt, id); }
+
+ /** When reciving a status changefrom the peer port (at id),
+ pass it to the bus. */
+ virtual void recvStatusChange(Status status)
+ { bus->recvStatusChange(status, id); }
+
+ // This should return all the 'owned' addresses that are
+ // downstream from this bus, yes? That is, the union of all
+ // the 'owned' address ranges of all the other interfaces on
+ // this bus...
+ virtual void addressRanges(AddrRangeList &range_list, bool &owner);
+ };
+
+ /** A count of the number of interfaces connected to this bus. */
+ int num_interfaces;
+
+ /** An array of pointers to the peer port interfaces
+ connected to this bus.*/
+ Port *interfaces[];
+
+ public:
+
+ /** A function used to return the port associated with this bus object. */
+ virtual Port *getPort(const char *if_name)
+ {
+ // if_name ignored? forced to be empty?
+ int id = num_interfaces++;
+ interfaces[id] = new BusPort(this, id);
+ return interfaces[id];
+ }
+};
+
+#endif //__MEM_BUS_HH__
diff --git a/mem/mem_object.cc b/mem/mem_object.cc
new file mode 100644
index 000000000..f579a0727
--- /dev/null
+++ b/mem/mem_object.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ */
+
+#include "mem/mem_object.hh"
+#include "sim/param.hh"
+
+MemObject::MemObject(const std::string &name)
+ : SimObject(name)
+{
+}
+
+DEFINE_SIM_OBJECT_CLASS_NAME("MemObject", MemObject)
diff --git a/mem/mem_object.hh b/mem/mem_object.hh
new file mode 100644
index 000000000..7b3d942a4
--- /dev/null
+++ b/mem/mem_object.hh
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ */
+
+/**
+ * @file
+ * Base Memory Object decleration.
+ */
+
+#ifndef __MEM_MEM_OBJECT_HH__
+#define __MEM_MEM_OBJECT_HH__
+
+#include "sim/sim_object.hh"
+#include "mem/port.hh"
+
+/**
+ * The base MemoryObject class, allows for an accesor function to a
+ * simobj that returns the Port.
+ */
+class MemObject : public SimObject
+{
+ public:
+ MemObject(const std::string &name);
+
+ public:
+ /** Additional function to return the Port of a memory object. */
+ virtual Port *getPort(const char *if_name = NULL) = 0;
+};
+
+#endif //__MEM_MEM_OBJECT_HH__
diff --git a/mem/packet.hh b/mem/packet.hh
new file mode 100644
index 000000000..260fc60f7
--- /dev/null
+++ b/mem/packet.hh
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+/**
+ * @file
+ * Declaration of the Packet Class, a packet is a transaction occuring
+ * between a single level of the memory heirarchy (ie L1->L2).
+ */
+
+#ifndef __MEM_PACKET_HH__
+#define __MEM_PACKET_HH__
+
+#include "mem/request.hh"
+#include "arch/isa_traits.hh"
+#include "sim/root.hh"
+
+struct Packet;
+typedef Packet* PacketPtr;
+typedef uint8_t* PacketDataPtr;
+
+/** List of all commands associated with a packet. */
+enum Command
+{
+ Read,
+ Write
+};
+
+/** The result of a particular pakets request. */
+enum PacketResult
+{
+ Success,
+ BadAddress
+};
+
+class SenderState{};
+class Coherence{};
+
+/**
+ * A Packet is the structure to handle requests between two levels
+ * of the memory system. The Request is a global object that trancends
+ * all of the memory heirarchy, but at each levels interface a packet
+ * is created to transfer data/requests. For example, a request would
+ * be used to initiate a request to go to memory/IOdevices, as the request
+ * passes through the memory system several packets will be created. One
+ * will be created to go between the L1 and L2 caches and another to go to
+ * the next level and so forth.
+ *
+ * Packets are assumed to be returned in the case of a single response. If
+ * the transaction has no response, then the consumer will delete the packet.
+ */
+struct Packet
+{
+ /** The address of the request, could be virtual or physical (depending on
+ cache configurations). */
+ Addr addr;
+
+ /** Flag structure to hold flags for this particular packet */
+ uint64_t flags;
+
+ /** A pointer to the overall request. */
+ RequestPtr req;
+
+ /** A virtual base opaque structure used to hold
+ coherence status messages. */
+ Coherence *coherence; // virtual base opaque,
+ // assert(dynamic_cast<Foo>) etc.
+
+ /** A virtual base opaque structure used to hold the senders state. */
+ SenderState *senderState; // virtual base opaque,
+ // assert(dynamic_cast<Foo>) etc.
+
+ /** A pointer to the data being transfered. It can be differnt sizes
+ at each level of the heirarchy so it belongs in the packet,
+ not request*/
+ PacketDataPtr data;
+
+ /** Indicates the size of the request. */
+ int size;
+
+ /** A index of the source of the transaction. */
+ short src;
+
+ /** A index to the destination of the transaction. */
+ short dest;
+
+ /** The command of the transaction. */
+ Command cmd;
+
+ /** The result of the packet transaction. */
+ PacketResult result;
+
+ /** Accessor function that returns the source index of the packet. */
+ short getSrc() const { return src; }
+
+ /** Accessor function that returns the destination index of
+ the packet. */
+ short getDest() const { return dest; }
+};
+
+#endif //__MEM_PACKET_HH
diff --git a/mem/page_table.cc b/mem/page_table.cc
new file mode 100644
index 000000000..714ddde35
--- /dev/null
+++ b/mem/page_table.cc
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+/**
+ * @file
+ * Definitions of page table.
+ */
+#include <string>
+#include <map>
+#include <fstream>
+
+#include "arch/faults.hh"
+#include "base/bitfield.hh"
+#include "base/intmath.hh"
+#include "base/trace.hh"
+#include "mem/page_table.hh"
+#include "sim/builder.hh"
+#include "sim/sim_object.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace TheISA;
+
+PageTable::PageTable(System *_system, Addr _pageSize)
+ : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))),
+ system(_system)
+{
+ assert(isPowerOf2(pageSize));
+}
+
+PageTable::~PageTable()
+{
+}
+
+Fault
+PageTable::page_check(Addr addr, int size) const
+{
+ if (size < sizeof(uint64_t)) {
+ if (!isPowerOf2(size)) {
+ panic("Invalid request size!\n");
+ return genMachineCheckFault();
+ }
+
+ if ((size - 1) & addr)
+ return genAlignmentFault();
+ }
+ else {
+ if ((addr & (VMPageSize - 1)) + size > VMPageSize) {
+ panic("Invalid request size!\n");
+ return genMachineCheckFault();
+ }
+
+ if ((sizeof(uint64_t) - 1) & addr)
+ return genAlignmentFault();
+ }
+
+ return NoFault;
+}
+
+
+
+
+void
+PageTable::allocate(Addr vaddr, int size)
+{
+ // starting address must be page aligned
+ assert(pageOffset(vaddr) == 0);
+
+ for (; size > 0; size -= pageSize, vaddr += pageSize) {
+ std::map<Addr,Addr>::iterator iter = pTable.find(vaddr);
+
+ if (iter != pTable.end()) {
+ // already mapped
+ fatal("PageTable::allocate: address 0x%x already mapped", vaddr);
+ }
+
+ pTable[vaddr] = system->new_page();
+ }
+}
+
+
+
+bool
+PageTable::translate(Addr vaddr, Addr &paddr)
+{
+ Addr page_addr = pageAlign(vaddr);
+ std::map<Addr,Addr>::iterator iter = pTable.find(page_addr);
+
+ if (iter == pTable.end()) {
+ return false;
+ }
+
+ paddr = iter->second + pageOffset(vaddr);
+ return true;
+}
+
+
+Fault
+PageTable::translate(CpuRequestPtr &req)
+{
+ assert(pageAlign(req->vaddr + req->size - 1) == pageAlign(req->vaddr));
+ if (!translate(req->vaddr, req->paddr)) {
+ return genMachineCheckFault();
+ }
+ return page_check(req->paddr, req->size);
+}
diff --git a/mem/page_table.hh b/mem/page_table.hh
new file mode 100644
index 000000000..8f0842f58
--- /dev/null
+++ b/mem/page_table.hh
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+/**
+ * @file
+ * Declaration of a non-full system Page Table.
+ */
+
+#ifndef __PAGE_TABLE__
+#define __PAGE_TABLE__
+
+#include <string>
+#include <map>
+
+#include "arch/isa_traits.hh"
+#include "base/trace.hh"
+#include "mem/request.hh"
+#include "mem/packet.hh"
+#include "sim/sim_object.hh"
+
+class System;
+
+/**
+ * Page Table Decleration.
+ */
+class PageTable
+{
+ protected:
+ std::map<Addr,Addr> pTable;
+
+ const Addr pageSize;
+ const Addr offsetMask;
+
+ System *system;
+
+ public:
+
+ PageTable(System *_system, Addr _pageSize = TheISA::VMPageSize);
+
+ ~PageTable();
+
+ Addr pageAlign(Addr a) { return (a & ~offsetMask); }
+ Addr pageOffset(Addr a) { return (a & offsetMask); }
+
+ Fault page_check(Addr addr, int size) const;
+
+ void allocate(Addr vaddr, int size);
+
+ /**
+ * Translate function
+ * @param vaddr The virtual address.
+ * @return Physical address from translation.
+ */
+ bool translate(Addr vaddr, Addr &paddr);
+
+ /**
+ * Perform a translation on the memory request, fills in paddr
+ * field of mem_req.
+ * @param req The memory request.
+ */
+ Fault translate(CpuRequestPtr &req);
+
+};
+
+#endif
diff --git a/mem/physical.cc b/mem/physical.cc
new file mode 100644
index 000000000..c1e83fb9e
--- /dev/null
+++ b/mem/physical.cc
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2001-2005 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.
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <zlib.h>
+
+#include <cstdio>
+#include <iostream>
+#include <string>
+
+
+#include "base/misc.hh"
+#include "config/full_system.hh"
+#include "mem/physical.hh"
+#include "sim/host.hh"
+#include "sim/builder.hh"
+#include "sim/eventq.hh"
+#include "arch/isa_traits.hh"
+
+
+using namespace std;
+using namespace TheISA;
+
+PhysicalMemory::MemResponseEvent::MemResponseEvent(Packet &pkt, MemoryPort* _m)
+ : Event(&mainEventQueue, CPU_Tick_Pri), pkt(pkt), memoryPort(_m)
+{
+
+ this->setFlags(AutoDelete);
+}
+
+void
+PhysicalMemory::MemResponseEvent::process()
+{
+ memoryPort->sendTiming(pkt);
+}
+
+const char *
+PhysicalMemory::MemResponseEvent::description()
+{
+ return "Physical Memory Timing Access respnse event";
+}
+
+PhysicalMemory::PhysicalMemory(const string &n)
+ : MemObject(n), base_addr(0), pmem_addr(NULL)
+{
+ // Hardcoded to 128 MB for now.
+ pmem_size = 1 << 27;
+
+ if (pmem_size % TheISA::PageBytes != 0)
+ panic("Memory Size not divisible by page size\n");
+
+ int map_flags = MAP_ANON | MAP_PRIVATE;
+ pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE,
+ map_flags, -1, 0);
+
+ if (pmem_addr == (void *)MAP_FAILED) {
+ perror("mmap");
+ fatal("Could not mmap!\n");
+ }
+
+ page_ptr = 0;
+}
+
+PhysicalMemory::~PhysicalMemory()
+{
+ if (pmem_addr)
+ munmap(pmem_addr, pmem_size);
+ //Remove memPorts?
+}
+
+Addr
+PhysicalMemory::new_page()
+{
+ Addr return_addr = page_ptr << LogVMPageSize;
+ return_addr += base_addr;
+
+ ++page_ptr;
+ return return_addr;
+}
+
+int
+PhysicalMemory::deviceBlockSize()
+{
+ //Can accept anysize request
+ return 0;
+}
+
+bool
+PhysicalMemory::doTimingAccess (Packet &pkt, MemoryPort* memoryPort)
+{
+ doFunctionalAccess(pkt);
+
+ MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort);
+ response->schedule(curTick + lat);
+
+ return true;
+}
+
+Tick
+PhysicalMemory::doAtomicAccess(Packet &pkt)
+{
+ doFunctionalAccess(pkt);
+ return curTick + lat;
+}
+
+void
+PhysicalMemory::doFunctionalAccess(Packet &pkt)
+{
+ assert(pkt.addr + pkt.size < pmem_size);
+
+ switch (pkt.cmd) {
+ case Read:
+ memcpy(pkt.data, pmem_addr + pkt.addr - base_addr, pkt.size);
+ break;
+ case Write:
+ memcpy(pmem_addr + pkt.addr - base_addr, pkt.data, pkt.size);
+ break;
+ default:
+ panic("unimplemented");
+ }
+
+ pkt.result = Success;
+}
+
+Port *
+PhysicalMemory::getPort(const char *if_name)
+{
+ if (if_name == NULL) {
+ return new MemoryPort(this);
+ } else {
+ panic("PhysicalMemory::getPort: unknown port %s requested", if_name);
+ }
+}
+
+void
+PhysicalMemory::recvStatusChange(Port::Status status)
+{
+ panic("??");
+}
+
+PhysicalMemory::MemoryPort::MemoryPort(PhysicalMemory *_memory)
+ : memory(_memory)
+{ }
+
+void
+PhysicalMemory::MemoryPort::recvStatusChange(Port::Status status)
+{
+ memory->recvStatusChange(status);
+}
+
+void
+PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &range_list,
+ bool &owner)
+{
+ panic("??");
+}
+
+int
+PhysicalMemory::MemoryPort::deviceBlockSize()
+{
+ return memory->deviceBlockSize();
+}
+
+bool
+PhysicalMemory::MemoryPort::recvTiming(Packet &pkt)
+{
+ return memory->doTimingAccess(pkt, this);
+}
+
+Tick
+PhysicalMemory::MemoryPort::recvAtomic(Packet &pkt)
+{
+ return memory->doAtomicAccess(pkt);
+}
+
+void
+PhysicalMemory::MemoryPort::recvFunctional(Packet &pkt)
+{
+ memory->doFunctionalAccess(pkt);
+}
+
+
+
+void
+PhysicalMemory::serialize(ostream &os)
+{
+ gzFile compressedMem;
+ string filename = name() + ".physmem";
+
+ SERIALIZE_SCALAR(pmem_size);
+ SERIALIZE_SCALAR(filename);
+
+ // write memory file
+ string thefile = Checkpoint::dir() + "/" + filename.c_str();
+ int fd = creat(thefile.c_str(), 0664);
+ if (fd < 0) {
+ perror("creat");
+ fatal("Can't open physical memory checkpoint file '%s'\n", filename);
+ }
+
+ compressedMem = gzdopen(fd, "wb");
+ if (compressedMem == NULL)
+ fatal("Insufficient memory to allocate compression state for %s\n",
+ filename);
+
+ if (gzwrite(compressedMem, pmem_addr, pmem_size) != pmem_size) {
+ fatal("Write failed on physical memory checkpoint file '%s'\n",
+ filename);
+ }
+
+ if (gzclose(compressedMem))
+ fatal("Close failed on physical memory checkpoint file '%s'\n",
+ filename);
+}
+
+void
+PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
+{
+ gzFile compressedMem;
+ long *tempPage;
+ long *pmem_current;
+ uint64_t curSize;
+ uint32_t bytesRead;
+ const int chunkSize = 16384;
+
+
+ // unmap file that was mmaped in the constructor
+ munmap(pmem_addr, pmem_size);
+
+ string filename;
+
+ UNSERIALIZE_SCALAR(pmem_size);
+ UNSERIALIZE_SCALAR(filename);
+
+ filename = cp->cptDir + "/" + filename;
+
+ // mmap memoryfile
+ int fd = open(filename.c_str(), O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ fatal("Can't open physical memory checkpoint file '%s'", filename);
+ }
+
+ compressedMem = gzdopen(fd, "rb");
+ if (compressedMem == NULL)
+ fatal("Insufficient memory to allocate compression state for %s\n",
+ filename);
+
+
+ pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, 0);
+
+ if (pmem_addr == (void *)MAP_FAILED) {
+ perror("mmap");
+ fatal("Could not mmap physical memory!\n");
+ }
+
+ curSize = 0;
+ tempPage = (long*)malloc(chunkSize);
+ if (tempPage == NULL)
+ fatal("Unable to malloc memory to read file %s\n", filename);
+
+ /* Only copy bytes that are non-zero, so we don't give the VM system hell */
+ while (curSize < pmem_size) {
+ bytesRead = gzread(compressedMem, tempPage, chunkSize);
+ if (bytesRead != chunkSize && bytesRead != pmem_size - curSize)
+ fatal("Read failed on physical memory checkpoint file '%s'"
+ " got %d bytes, expected %d or %d bytes\n",
+ filename, bytesRead, chunkSize, pmem_size-curSize);
+
+ assert(bytesRead % sizeof(long) == 0);
+
+ for (int x = 0; x < bytesRead/sizeof(long); x++)
+ {
+ if (*(tempPage+x) != 0) {
+ pmem_current = (long*)(pmem_addr + curSize + x * sizeof(long));
+ *pmem_current = *(tempPage+x);
+ }
+ }
+ curSize += bytesRead;
+ }
+
+ free(tempPage);
+
+ if (gzclose(compressedMem))
+ fatal("Close failed on physical memory checkpoint file '%s'\n",
+ filename);
+
+}
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
+
+ Param<string> file;
+#if FULL_SYSTEM
+ SimObjectParam<MemoryController *> mmu;
+#endif
+ Param<Range<Addr> > range;
+
+END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
+
+ INIT_PARAM_DFLT(file, "memory mapped file", ""),
+#if FULL_SYSTEM
+ INIT_PARAM(mmu, "Memory Controller"),
+#endif
+ INIT_PARAM(range, "Device Address Range")
+
+END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
+
+CREATE_SIM_OBJECT(PhysicalMemory)
+{
+#if FULL_SYSTEM
+ if (mmu) {
+ return new PhysicalMemory(getInstanceName(), range, mmu, file);
+ }
+#endif
+
+ return new PhysicalMemory(getInstanceName());
+}
+
+REGISTER_SIM_OBJECT("PhysicalMemory", PhysicalMemory)
diff --git a/mem/physical.hh b/mem/physical.hh
new file mode 100644
index 000000000..b066d3dfc
--- /dev/null
+++ b/mem/physical.hh
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2001-2005 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.
+ */
+
+/* @file
+ */
+
+#ifndef __PHYSICAL_MEMORY_HH__
+#define __PHYSICAL_MEMORY_HH__
+
+#include "base/range.hh"
+#include "mem/mem_object.hh"
+#include "mem/packet.hh"
+#include "mem/port.hh"
+#include "sim/eventq.hh"
+#include <map>
+#include <string>
+
+//
+// Functional model for a contiguous block of physical memory. (i.e. RAM)
+//
+class PhysicalMemory : public MemObject
+{
+ class MemoryPort : public Port
+ {
+ PhysicalMemory *memory;
+
+ public:
+
+ MemoryPort(PhysicalMemory *_memory);
+
+ protected:
+
+ virtual bool recvTiming(Packet &pkt);
+
+ virtual Tick recvAtomic(Packet &pkt);
+
+ virtual void recvFunctional(Packet &pkt);
+
+ virtual void recvStatusChange(Status status);
+
+ virtual void getDeviceAddressRanges(AddrRangeList &range_list,
+ bool &owner);
+
+ virtual int deviceBlockSize();
+ };
+
+ virtual Port * getPort(const char *if_name);
+
+ int numPorts;
+
+ int lat;
+
+ struct MemResponseEvent : public Event
+ {
+ Packet &pkt;
+ MemoryPort *memoryPort;
+
+ MemResponseEvent(Packet &pkt, MemoryPort *memoryPort);
+ void process();
+ const char *description();
+ };
+
+ private:
+ // prevent copying of a MainMemory object
+ PhysicalMemory(const PhysicalMemory &specmem);
+ const PhysicalMemory &operator=(const PhysicalMemory &specmem);
+
+ protected:
+ Addr base_addr;
+ Addr pmem_size;
+ uint8_t *pmem_addr;
+ int page_ptr;
+
+ public:
+ Addr new_page();
+ uint64_t size() { return pmem_size; }
+
+ public:
+ PhysicalMemory(const std::string &n);
+ virtual ~PhysicalMemory();
+
+ public:
+ int deviceBlockSize();
+
+ // fast back-door memory access for vtophys(), remote gdb, etc.
+ // uint64_t phys_read_qword(Addr addr) const;
+ private:
+ bool doTimingAccess(Packet &pkt, MemoryPort *memoryPort);
+ Tick doAtomicAccess(Packet &pkt);
+ void doFunctionalAccess(Packet &pkt);
+
+ void recvStatusChange(Port::Status status);
+
+ public:
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+};
+
+/*uint64_t
+PhysicalMemory::phys_read_qword(Addr addr) const
+{
+ if (addr + sizeof(uint64_t) > pmem_size)
+ return 0;
+
+ return *(uint64_t *)(pmem_addr + addr);
+}*/
+
+
+#endif //__PHYSICAL_MEMORY_HH__
diff --git a/mem/port.cc b/mem/port.cc
new file mode 100644
index 000000000..fb4f3b4e0
--- /dev/null
+++ b/mem/port.cc
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ */
+
+/**
+ * @file Port object definitions.
+ */
+
+#include "base/chunk_generator.hh"
+#include "mem/port.hh"
+
+void
+Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd)
+{
+ Request req;
+ Packet pkt;
+ pkt.req = &req;
+ pkt.cmd = cmd;
+
+ for (ChunkGenerator gen(addr, size, peerBlockSize());
+ !gen.done(); gen.next()) {
+ pkt.addr = req.paddr = gen.addr();
+ pkt.size = req.size = gen.size();
+ pkt.data = p;
+ sendFunctional(pkt);
+ p += gen.size();
+ }
+}
+
+void
+Port::writeBlob(Addr addr, uint8_t *p, int size)
+{
+ blobHelper(addr, p, size, Write);
+}
+
+void
+Port::readBlob(Addr addr, uint8_t *p, int size)
+{
+ blobHelper(addr, p, size, Read);
+}
+
+void
+Port::memsetBlob(Addr addr, uint8_t val, int size)
+{
+ // quick and dirty...
+ uint8_t *buf = new uint8_t[size];
+
+ memset(buf, val, size);
+ blobHelper(addr, buf, size, Write);
+
+ delete buf;
+}
diff --git a/mem/port.hh b/mem/port.hh
new file mode 100644
index 000000000..947e7896a
--- /dev/null
+++ b/mem/port.hh
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ */
+
+/**
+ * @file
+ * Port Object Decleration. Ports are used to interface memory objects to
+ * each other. They will always come in pairs, and we refer to the other
+ * port object as the peer. These are used to make the design more
+ * modular so that a specific interface between every type of objcet doesn't
+ * have to be created.
+ */
+
+#ifndef __MEM_PORT_HH__
+#define __MEM_PORT_HH__
+
+#include <string>
+#include <list>
+#include <inttypes.h>
+
+#include "base/misc.hh"
+#include "base/range.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh"
+
+/** This typedef is used to clean up the parameter list of
+ * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared
+ * outside the Port object since it's also used by some mem objects.
+ * Eventually we should move this typedef to wherever Addr is
+ * defined.
+ */
+
+typedef std::list<Range<Addr> > AddrRangeList;
+
+/**
+ * Ports are used to interface memory objects to
+ * each other. They will always come in pairs, and we refer to the other
+ * port object as the peer. These are used to make the design more
+ * modular so that a specific interface between every type of objcet doesn't
+ * have to be created.
+ *
+ * Recv accesor functions are being called from the peer interface.
+ * Send accessor functions are being called from the device the port is
+ * associated with, and it will call the peer recv. accessor function.
+ */
+class Port
+{
+ public:
+
+ virtual ~Port() {};
+ // mey be better to use subclasses & RTTI?
+ /** Holds the ports status. Keeps track if it is blocked, or has
+ calculated a range change. */
+ enum Status {
+ Blocked,
+ Unblocked,
+ RangeChange
+ };
+
+ private:
+
+ /** A pointer to the peer port. Ports always come in pairs, that way they
+ can use a standardized interface to communicate between different
+ memory objects. */
+ Port *peer;
+
+ public:
+
+ /** Function to set the pointer for the peer port.
+ @todo should be called by the configuration stuff (python).
+ */
+ void setPeer(Port *port) { peer = port; }
+
+ /** Function to set the pointer for the peer port.
+ @todo should be called by the configuration stuff (python).
+ */
+ Port *getPeer() { return peer; }
+
+ protected:
+
+ /** These functions are protected because they should only be
+ * called by a peer port, never directly by any outside object. */
+
+ /** Called to recive a timing call from the peer port. */
+ virtual bool recvTiming(Packet &pkt) = 0;
+
+ /** Called to recive a atomic call from the peer port. */
+ virtual Tick recvAtomic(Packet &pkt) = 0;
+
+ /** Called to recive a functional call from the peer port. */
+ virtual void recvFunctional(Packet &pkt) = 0;
+
+ /** Called to recieve a status change from the peer port. */
+ virtual void recvStatusChange(Status status) = 0;
+
+ /** Called by a peer port if the send was unsuccesful, and had to
+ wait. This shouldn't be valid for response paths (IO Devices).
+ so it is set to panic if it isn't already defined.
+ */
+ virtual Packet *recvRetry() { panic("??"); }
+
+ /** Called by a peer port in order to determine the block size of the
+ device connected to this port. It sometimes doesn't make sense for
+ this function to be called, a DMA interface doesn't really have a
+ block size, so it is defaulted to a panic.
+ */
+ virtual int deviceBlockSize() { panic("??"); }
+
+ /** The peer port is requesting us to reply with a list of the ranges we
+ are responsible for.
+ @param owner is an output param that, if set, indicates that the
+ port is the owner of the specified ranges (i.e., slave, default
+ responder, etc.). If 'owner' is false, the interface is
+ interested in the specified ranges for snooping purposes. If
+ an object wants to own some ranges and snoop on others, it will
+ need to use two different ports.
+ */
+ virtual void getDeviceAddressRanges(AddrRangeList &range_list,
+ bool &owner)
+ { panic("??"); }
+
+ public:
+
+ /** Function called by associated memory device (cache, memory, iodevice)
+ in order to send a timing request to the port. Simply calls the peer
+ port receive function.
+ @return This function returns if the send was succesful in it's
+ recieve. If it was a failure, then the port will wait for a recvRetry
+ at which point it can issue a successful sendTiming. This is used in
+ case a cache has a higher priority request come in while waiting for
+ the bus to arbitrate.
+ */
+ bool sendTiming(Packet &pkt) { return peer->recvTiming(pkt); }
+
+ /** Function called by the associated device to send an atomic access,
+ an access in which the data is moved and the state is updated in one
+ cycle, without interleaving with other memory accesses.
+ */
+ Tick sendAtomic(Packet &pkt)
+ { return peer->recvAtomic(pkt); }
+
+ /** Function called by the associated device to send a functional access,
+ an access in which the data is instantly updated everywhere in the
+ memory system, without affecting the current state of any block
+ or moving the block.
+ */
+ void sendFunctional(Packet &pkt)
+ { return peer->recvFunctional(pkt); }
+
+ /** Called by the associated device to send a status change to the device
+ connected to the peer interface.
+ */
+ void sendStatusChange(Status status) {peer->recvStatusChange(status); }
+
+ /** When a timing access doesn't return a success, some time later the
+ Retry will be sent.
+ */
+ Packet *sendRetry() { return peer->recvRetry(); }
+
+ /** Called by the associated device if it wishes to find out the blocksize
+ of the device on attached to the peer port.
+ */
+ int peerBlockSize() { return peer->deviceBlockSize(); }
+
+ /** Called by the associated device if it wishes to find out the address
+ ranges connected to the peer ports devices.
+ */
+ void getPeerAddressRanges(AddrRangeList &range_list, bool &owner)
+ { peer->getDeviceAddressRanges(range_list, owner); }
+
+ /** This function is a wrapper around sendFunctional()
+ that breaks a larger, arbitrarily aligned access into
+ appropriate chunks. The default implementation can use
+ getBlockSize() to determine the block size and go from there.
+ */
+ void readBlob(Addr addr, uint8_t *p, int size);
+
+ /** This function is a wrapper around sendFunctional()
+ that breaks a larger, arbitrarily aligned access into
+ appropriate chunks. The default implementation can use
+ getBlockSize() to determine the block size and go from there.
+ */
+ void writeBlob(Addr addr, uint8_t *p, int size);
+
+ /** Fill size bytes starting at addr with byte value val. This
+ should not need to be virtual, since it can be implemented in
+ terms of writeBlob(). However, it shouldn't be
+ performance-critical either, so it could be if we wanted to.
+ */
+ void memsetBlob(Addr addr, uint8_t val, int size);
+
+ private:
+
+ /** Internal helper function for read/writeBlob().
+ */
+ void blobHelper(Addr addr, uint8_t *p, int size, Command cmd);
+};
+
+#endif //__MEM_PORT_HH__
diff --git a/mem/request.hh b/mem/request.hh
new file mode 100644
index 000000000..5e2275741
--- /dev/null
+++ b/mem/request.hh
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ */
+
+/**
+ * @file Decleration of a request, the overall memory request consisting of
+ the parts of the request that are persistent throughout the transaction.
+ */
+
+#ifndef __MEM_REQUEST_HH__
+#define __MEM_REQUEST_HH__
+
+#include "arch/isa_traits.hh"
+
+class Request;
+class CpuRequest;
+
+typedef Request* RequestPtr;
+typedef CpuRequest* CpuRequestPtr;
+
+/** The request is a Load locked/store conditional. */
+const unsigned LOCKED = 0x001;
+/** The virtual address is also the physical address. */
+const unsigned PHYSICAL = 0x002;
+/** The request is an ALPHA VPTE pal access (hw_ld). */
+const unsigned VPTE = 0x004;
+/** Use the alternate mode bits in ALPHA. */
+const unsigned ALTMODE = 0x008;
+/** The request is to an uncacheable address. */
+const unsigned UNCACHEABLE = 0x010;
+/** The request should not cause a page fault. */
+const unsigned NO_FAULT = 0x020;
+/** The request should be prefetched into the exclusive state. */
+const unsigned PF_EXCLUSIVE = 0x100;
+/** The request should be marked as LRU. */
+const unsigned EVICT_NEXT = 0x200;
+
+class Request
+{
+ //@todo Make Accesor functions, make these private.
+ public:
+ /** The physical address of the request. */
+ Addr paddr;
+
+ /** whether this req came from the CPU or not **DO we need this??***/
+ bool nicReq;
+
+ /** The size of the request. */
+ int size;
+
+ /** The time this request was started. Used to calculate latencies. */
+ Tick time;
+
+ /** Destination address if this is a block copy. */
+ Addr copyDest;
+
+ uint32_t flags;
+};
+
+class CpuRequest : public Request
+{
+ //@todo Make Accesor functions, make these private.
+ public:
+ /** The virtual address of the request. */
+ Addr vaddr;
+
+ /** The address space ID. */
+ int asid;
+
+ /** The return value of store conditional. */
+ uint64_t scResult;
+
+ /** The cpu number for statistics. */
+ int cpuNum;
+
+ /** The requesting thread id. */
+ int threadNum;
+
+ /** program counter of initiating access; for tracing/debugging */
+ Addr pc;
+};
+
+#endif // __MEM_REQUEST_HH__
diff --git a/mem/translating_port.cc b/mem/translating_port.cc
new file mode 100644
index 000000000..f0059fc08
--- /dev/null
+++ b/mem/translating_port.cc
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2001-2005 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.
+ */
+
+#include <string>
+#include "base/chunk_generator.hh"
+#include "mem/port.hh"
+#include "mem/translating_port.hh"
+#include "mem/page_table.hh"
+
+using namespace TheISA;
+
+TranslatingPort::TranslatingPort(Port *_port, PageTable *p_table)
+ : port(_port), pTable(p_table)
+{ }
+
+TranslatingPort::~TranslatingPort()
+{ }
+
+bool
+TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
+{
+ Addr paddr;
+ int prevSize = 0;
+
+ for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
+
+ if (!pTable->translate(gen.addr(),paddr))
+ return false;
+
+ port->readBlob(paddr, p + prevSize, gen.size());
+ prevSize += gen.size();
+ }
+
+ return true;
+}
+
+void
+TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
+{
+ if (!tryReadBlob(addr, p, size))
+ fatal("readBlob(0x%x, ...) failed", addr);
+}
+
+
+bool
+TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc)
+{
+
+ Addr paddr;
+ int prevSize = 0;
+
+ for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
+
+ if (!pTable->translate(gen.addr(), paddr)) {
+ if (alloc) {
+ pTable->allocate(roundDown(gen.addr(), VMPageSize),
+ VMPageSize);
+ pTable->translate(gen.addr(), paddr);
+ } else {
+ return false;
+ }
+ }
+
+ port->writeBlob(paddr, p + prevSize, gen.size());
+ prevSize += gen.size();
+ }
+
+ return true;
+}
+
+
+void
+TranslatingPort::writeBlob(Addr addr, uint8_t *p, int size, bool alloc)
+{
+ if (!tryWriteBlob(addr, p, size, alloc))
+ fatal("writeBlob(0x%x, ...) failed", addr);
+}
+
+bool
+TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size, bool alloc)
+{
+ Addr paddr;
+
+ for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
+
+ if (!pTable->translate(gen.addr(), paddr)) {
+ if (alloc) {
+ pTable->allocate(roundDown(gen.addr(), VMPageSize),
+ VMPageSize);
+ pTable->translate(gen.addr(), paddr);
+ } else {
+ return false;
+ }
+ }
+
+ port->memsetBlob(paddr, val, gen.size());
+ }
+
+ return true;
+}
+
+void
+TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size, bool alloc)
+{
+ if (!tryMemsetBlob(addr, val, size, alloc))
+ fatal("memsetBlob(0x%x, ...) failed", addr);
+}
+
+
+bool
+TranslatingPort::tryWriteString(Addr addr, const char *str)
+{
+ Addr paddr,vaddr;
+ uint8_t c;
+
+ vaddr = addr;
+
+ do {
+ c = *str++;
+ if (!pTable->translate(vaddr++,paddr))
+ return false;
+
+ port->writeBlob(paddr, &c, 1);
+ } while (c);
+
+ return true;
+}
+
+void
+TranslatingPort::writeString(Addr addr, const char *str)
+{
+ if (!tryWriteString(addr, str))
+ fatal("writeString(0x%x, ...) failed", addr);
+}
+
+bool
+TranslatingPort::tryReadString(std::string &str, Addr addr)
+{
+ Addr paddr,vaddr;
+ uint8_t c;
+
+ vaddr = addr;
+
+ do {
+ if (!pTable->translate(vaddr++,paddr))
+ return false;
+
+ port->readBlob(paddr, &c, 1);
+ str += c;
+ } while (c);
+
+ return true;
+}
+
+void
+TranslatingPort::readString(std::string &str, Addr addr)
+{
+ if (!tryReadString(str, addr))
+ fatal("readString(0x%x, ...) failed", addr);
+}
+
diff --git a/mem/translating_port.hh b/mem/translating_port.hh
new file mode 100644
index 000000000..2ba3d68e2
--- /dev/null
+++ b/mem/translating_port.hh
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2001-2005 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.
+ */
+
+#ifndef __MEM_TRANSLATING_PROT_HH__
+#define __MEM_TRANSLATING_PROT_HH__
+
+class Port;
+class PageTable;
+
+class TranslatingPort
+{
+ private:
+ Port *port;
+ PageTable *pTable;
+
+ TranslatingPort(const TranslatingPort &specmem);
+ const TranslatingPort &operator=(const TranslatingPort &specmem);
+
+ public:
+ TranslatingPort(Port *_port, PageTable *p_table);
+ virtual ~TranslatingPort();
+
+ public:
+ bool tryReadBlob(Addr addr, uint8_t *p, int size);
+ bool tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc = false);
+ bool tryMemsetBlob(Addr addr, uint8_t val, int size, bool alloc = false);
+ bool tryWriteString(Addr addr, const char *str);
+ bool tryReadString(std::string &str, Addr addr);
+
+ void readBlob(Addr addr, uint8_t *p, int size);
+ void writeBlob(Addr addr, uint8_t *p, int size, bool alloc = false);
+ void memsetBlob(Addr addr, uint8_t val, int size, bool alloc = false);
+ void writeString(Addr addr, const char *str);
+ void readString(std::string &str, Addr addr);
+};
+
+#endif
diff --git a/python/m5/objects/BaseCPU.py b/python/m5/objects/BaseCPU.py
index a90203729..07cb850f1 100644
--- a/python/m5/objects/BaseCPU.py
+++ b/python/m5/objects/BaseCPU.py
@@ -2,16 +2,14 @@ from m5 import *
class BaseCPU(SimObject):
type = 'BaseCPU'
abstract = True
- icache = Param.BaseMem(NULL, "L1 instruction cache object")
- dcache = Param.BaseMem(NULL, "L1 data cache object")
if build_env['FULL_SYSTEM']:
dtb = Param.AlphaDTB("Data TLB")
itb = Param.AlphaITB("Instruction TLB")
- mem = Param.FunctionalMemory("memory")
system = Param.System(Parent.any, "system object")
cpu_id = Param.Int(-1, "CPU identifier")
else:
+ mem = Param.Memory(Parent.any, "memory")
workload = VectorParam.Process("processes to run")
max_insts_all_threads = Param.Counter(0,
diff --git a/python/m5/objects/Ethernet.py b/python/m5/objects/Ethernet.py
index 6113e656f..22714e15c 100644
--- a/python/m5/objects/Ethernet.py
+++ b/python/m5/objects/Ethernet.py
@@ -69,7 +69,6 @@ class EtherDevBase(PciDevice):
physmem = Param.PhysicalMemory(Parent.any, "Physical Memory")
- hier = Param.HierParams(Parent.any, "Hierarchy global variables")
payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
dma_read_delay = Param.Latency('0us', "fixed delay for dma reads")
dma_read_factor = Param.Latency('0us', "multiplier for dma reads")
diff --git a/python/m5/objects/MemObject.py b/python/m5/objects/MemObject.py
new file mode 100644
index 000000000..4d68243e6
--- /dev/null
+++ b/python/m5/objects/MemObject.py
@@ -0,0 +1,5 @@
+from m5 import *
+
+class MemObject(SimObject):
+ type = 'MemObject'
+ abstract = True
diff --git a/python/m5/objects/PhysicalMemory.py b/python/m5/objects/PhysicalMemory.py
index f50937ee6..b0aba1a7d 100644
--- a/python/m5/objects/PhysicalMemory.py
+++ b/python/m5/objects/PhysicalMemory.py
@@ -1,8 +1,9 @@
from m5 import *
-from FunctionalMemory import FunctionalMemory
+from Memory import Memory
-class PhysicalMemory(FunctionalMemory):
+class PhysicalMemory(Memory):
type = 'PhysicalMemory'
range = Param.AddrRange("Device Address")
file = Param.String('', "memory mapped file")
- mmu = Param.MemoryController(Parent.any, "Memory Controller")
+ if build_env['FULL_SYSTEM']:
+ mmu = Param.MemoryController(Parent.any, "Memory Controller")
diff --git a/python/m5/objects/Process.py b/python/m5/objects/Process.py
index b4ccc1bec..60b00229e 100644
--- a/python/m5/objects/Process.py
+++ b/python/m5/objects/Process.py
@@ -3,6 +3,7 @@ class Process(SimObject):
type = 'Process'
abstract = True
output = Param.String('cout', 'filename for stdout/stderr')
+ system = Param.System(Parent.any, "system process will run on")
class LiveProcess(Process):
type = 'LiveProcess'
@@ -11,6 +12,15 @@ class LiveProcess(Process):
env = VectorParam.String('', "environment settings")
input = Param.String('cin', "filename for stdin")
+class AlphaLiveProcess(LiveProcess):
+ type = 'AlphaLiveProcess'
+
+class SparcLiveProcess(LiveProcess):
+ type = 'SparcLiveProcess'
+
+class MipsLiveProcess(LiveProcess):
+ type = 'MipsLiveProcess'
+
class EioProcess(Process):
type = 'EioProcess'
chkpt = Param.String('', "EIO checkpoint file name (optional)")
diff --git a/python/m5/objects/Root.py b/python/m5/objects/Root.py
index 23b13fc67..f51516098 100644
--- a/python/m5/objects/Root.py
+++ b/python/m5/objects/Root.py
@@ -1,5 +1,4 @@
from m5 import *
-from HierParams import HierParams
from Serialize import Serialize
from Statistics import Statistics
from Trace import Trace
@@ -13,12 +12,9 @@ class Root(SimObject):
"print a progress message every n ticks (0 = never)")
output_file = Param.String('cout', "file to dump simulator output to")
checkpoint = Param.String('', "checkpoint file to load")
-# hier = Param.HierParams(HierParams(do_data = False, do_events = True),
-# "shared memory hierarchy parameters")
# stats = Param.Statistics(Statistics(), "statistics object")
# trace = Param.Trace(Trace(), "trace object")
# serialize = Param.Serialize(Serialize(), "checkpoint generation options")
- hier = HierParams(do_data = False, do_events = True)
stats = Statistics()
trace = Trace()
exetrace = ExecutionTrace()
diff --git a/python/m5/objects/System.py b/python/m5/objects/System.py
index 5925cadf5..2959c1d1a 100644
--- a/python/m5/objects/System.py
+++ b/python/m5/objects/System.py
@@ -2,15 +2,16 @@ from m5 import *
class System(SimObject):
type = 'System'
- boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency,
- "boot processor frequency")
- memctrl = Param.MemoryController(Parent.any, "memory controller")
physmem = Param.PhysicalMemory(Parent.any, "phsyical memory")
- init_param = Param.UInt64(0, "numerical value to pass into simulator")
- bin = Param.Bool(False, "is this system binned")
- binned_fns = VectorParam.String([], "functions broken down and binned")
- kernel = Param.String("file that contains the kernel code")
- readfile = Param.String("", "file to read startup script from")
+ if build_env['FULL_SYSTEM']:
+ boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency,
+ "boot processor frequency")
+ memctrl = Param.MemoryController(Parent.any, "memory controller")
+ init_param = Param.UInt64(0, "numerical value to pass into simulator")
+ bin = Param.Bool(False, "is this system binned")
+ binned_fns = VectorParam.String([], "functions broken down and binned")
+ kernel = Param.String("file that contains the kernel code")
+ readfile = Param.String("", "file to read startup script from")
class AlphaSystem(System):
type = 'AlphaSystem'
diff --git a/sim/byteswap.hh b/sim/byteswap.hh
index c5d8801ab..0dd0ba827 100644
--- a/sim/byteswap.hh
+++ b/sim/byteswap.hh
@@ -79,7 +79,9 @@ static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);}
static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);}
static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);}
static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);}
-#if defined(__APPLE__)
+//This is to prevent the following two functions from compiling on
+//64bit machines. It won't detect everything, so it should be changed.
+#ifndef __x86_64__
static inline long swap_byte(long x) {return swap_byte32((long)x);}
static inline unsigned long swap_byte(unsigned long x)
{ return swap_byte32((unsigned long)x);}
diff --git a/sim/faults.cc b/sim/faults.cc
index 701384989..f7e9a0691 100644
--- a/sim/faults.cc
+++ b/sim/faults.cc
@@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "base/misc.hh"
#include "sim/faults.hh"
#include "cpu/exec_context.hh"
#include "cpu/base.hh"
diff --git a/sim/host.hh b/sim/host.hh
index f7e64f23c..48c977331 100644
--- a/sim/host.hh
+++ b/sim/host.hh
@@ -62,4 +62,6 @@ typedef int64_t Tick;
*/
typedef uint64_t Addr;
+const Addr MaxAddr = (Addr)-1;
+
#endif // __HOST_H__
diff --git a/sim/process.cc b/sim/process.cc
index a84a4f7ba..7b27c4274 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -37,18 +37,15 @@
#include "base/loader/symtab.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
-#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
-#include "cpu/smt.hh"
-#include "encumbered/cpu/full/thread.hh"
-#include "encumbered/eio/eio.hh"
-#include "encumbered/mem/functional/main.hh"
+#include "mem/page_table.hh"
+#include "mem/mem_object.hh"
+#include "mem/translating_port.hh"
#include "sim/builder.hh"
#include "sim/process.hh"
#include "sim/stats.hh"
#include "sim/syscall_emul.hh"
-
-#include "arch/process.hh"
+#include "sim/system.hh"
using namespace std;
using namespace TheISA;
@@ -66,20 +63,12 @@ using namespace TheISA;
int num_processes = 0;
Process::Process(const string &nm,
+ System *_system,
int stdin_fd, // initial I/O descriptors
int stdout_fd,
int stderr_fd)
- : SimObject(nm)
+ : SimObject(nm), system(_system)
{
- // allocate memory space
- memory = new MainMemory(nm + ".MainMem");
-
- // allocate initial register file
- init_regs = new RegFile;
- memset(init_regs, 0, sizeof(RegFile));
-
- cpuXC = new CPUExecContext(init_regs);
-
// initialize first 3 fds (stdin, stdout, stderr)
fd_map[STDIN_FILENO] = stdin_fd;
fd_map[STDOUT_FILENO] = stdout_fd;
@@ -92,9 +81,11 @@ Process::Process(const string &nm,
mmap_start = mmap_end = 0;
nxm_start = nxm_end = 0;
+ pTable = new PageTable(system);
// other parameters will be initialized when the program is loaded
}
+
void
Process::regStats()
{
@@ -146,13 +137,7 @@ Process::registerExecContext(ExecContext *xc)
int myIndex = execContexts.size();
execContexts.push_back(xc);
- if (myIndex == 0) {
- // copy process's initial regs struct
- // Hack for now to copy init regs
- xc->copyArchRegs(cpuXC->getProxy());
- }
-
- // return CPU number to caller and increment available CPU count
+ // return CPU number to caller
return myIndex;
}
@@ -160,13 +145,29 @@ void
Process::startup()
{
if (execContexts.empty())
- return;
+ fatal("Process %s is not associated with any CPUs!\n", name());
// first exec context for this process... initialize & enable
ExecContext *xc = execContexts[0];
// mark this context as active so it will start ticking.
xc->activate(0);
+
+ // Here we are grabbing the memory port of the CPU hosting the
+ // initial execution context for initialization. In the long run
+ // this is not what we want, since it means that all
+ // initialization accesses (e.g., loading object file sections)
+ // will be done a cache block at a time through the CPU's cache.
+ // We really want something more like:
+ //
+ // memport = system->physmem->getPort();
+ // myPort.setPeer(memport);
+ // memport->setPeer(&myPort);
+ // initVirtMem = new TranslatingPort(myPort, pTable);
+ //
+ // but we need our own dummy port "myPort" that doesn't exist.
+ // In the short term it works just fine though.
+ initVirtMem = xc->getMemPort();
}
void
@@ -251,38 +252,31 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process)
static void
copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr,
- FunctionalMemory *memory)
+ TranslatingPort* memPort)
{
Addr data_ptr_swap;
for (int i = 0; i < strings.size(); ++i) {
data_ptr_swap = htog(data_ptr);
- memory->access(Write, array_ptr, &data_ptr_swap, sizeof(Addr));
- memory->writeString(data_ptr, strings[i].c_str());
+ memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap, sizeof(Addr));
+ memPort->writeString(data_ptr, strings[i].c_str());
array_ptr += sizeof(Addr);
data_ptr += strings[i].size() + 1;
}
// add NULL terminator
data_ptr = 0;
- memory->access(Write, array_ptr, &data_ptr, sizeof(Addr));
+
+ memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(Addr));
}
-LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
+LiveProcess::LiveProcess(const string &nm, ObjectFile *_objFile,
+ System *_system,
int stdin_fd, int stdout_fd, int stderr_fd,
- vector<string> &argv, vector<string> &envp)
- : Process(nm, stdin_fd, stdout_fd, stderr_fd)
+ vector<string> &_argv, vector<string> &_envp)
+ : Process(nm, _system, stdin_fd, stdout_fd, stderr_fd),
+ objFile(_objFile), argv(_argv), envp(_envp)
{
prog_fname = argv[0];
- prog_entry = objFile->entryPoint();
- text_base = objFile->textBase();
- text_size = objFile->textSize();
- data_base = objFile->dataBase();
- data_size = objFile->dataSize() + objFile->bssSize();
- brk_point = roundUp(data_base + data_size, VMPageSize);
-
- // load object file into target memory
- objFile->loadSections(memory);
-
// load up symbols, if any... these may be used for debugging or
// profiling.
if (!debugSymbolTable) {
@@ -294,21 +288,19 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
debugSymbolTable = NULL;
}
}
+}
- // Set up stack. On Alpha, stack goes below text section. This
- // code should get moved to some architecture-specific spot.
- stack_base = text_base - (409600+4096);
-
- // Set up region for mmaps. Tru64 seems to start just above 0 and
- // grow up from there.
- mmap_start = mmap_end = 0x10000;
+void
+LiveProcess::argsInit(int intSize, int pageSize)
+{
+ Process::startup();
- // Set pointer for next thread stack. Reserve 8M for main stack.
- next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+ // load object file into target memory
+ objFile->loadSections(initVirtMem);
// Calculate how much space we need for arg & env arrays.
- int argv_array_size = sizeof(Addr) * (argv.size() + 1);
- int envp_array_size = sizeof(Addr) * (envp.size() + 1);
+ 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;
@@ -327,8 +319,11 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
// set bottom of stack
stack_min = stack_base - space_needed;
// align it
- stack_min &= ~7;
+ stack_min &= ~(intSize-1);
stack_size = stack_base - stack_min;
+ // map memory
+ pTable->allocate(roundDown(stack_min, pageSize),
+ roundUp(stack_size, pageSize));
// map out initial stack contents
Addr argv_array_base = stack_min + sizeof(uint64_t); // room for argc
@@ -338,18 +333,28 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
// write contents to stack
uint64_t argc = argv.size();
- argc = htog(argc);
- memory->access(Write, stack_min, &argc, sizeof(uint64_t));
-
- copyStringArray(argv, argv_array_base, arg_data_base, memory);
- copyStringArray(envp, envp_array_base, env_data_base, memory);
-
- cpuXC->setIntReg(ArgumentReg0, argc);
- cpuXC->setIntReg(ArgumentReg1, argv_array_base);
- cpuXC->setIntReg(StackPointerReg, stack_min);
- cpuXC->setIntReg(GlobalPointerReg, objFile->globalPointer());
- cpuXC->setPC(prog_entry);
- cpuXC->setNextPC(prog_entry + sizeof(MachInst));
+ 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);
+
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+
+ execContexts[0]->setIntReg(ArgumentReg0, argc);
+ execContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
+ execContexts[0]->setIntReg(StackPointerReg, stack_min);
+
+ Addr prog_entry = objFile->entryPoint();
+ execContexts[0]->setPC(prog_entry);
+ execContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+ execContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+
+ num_processes++;
}
void
@@ -366,81 +371,4 @@ LiveProcess::syscall(ExecContext *xc)
desc->doSyscall(callnum, this, xc);
}
-LiveProcess *
-LiveProcess::create(const string &nm,
- int stdin_fd, int stdout_fd, int stderr_fd,
- string executable,
- vector<string> &argv, vector<string> &envp)
-{
- LiveProcess *process = NULL;
- ObjectFile *objFile = createObjectFile(executable);
- if (objFile == NULL) {
- fatal("Can't load object file %s", executable);
- }
-
- // set up syscall emulation pointer for the current ISA
- process = createProcess(nm, objFile,
- stdin_fd, stdout_fd, stderr_fd,
- argv, envp);
-
- delete objFile;
-
- if (process == NULL)
- fatal("Unknown error creating process object.");
-
- return process;
-}
-
-
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
-
- VectorParam<string> cmd;
- Param<string> executable;
- Param<string> input;
- Param<string> output;
- VectorParam<string> env;
-
-END_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
-
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess)
-
- INIT_PARAM(cmd, "command line (executable plus arguments)"),
- INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
- INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
- INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
- INIT_PARAM(env, "environment settings")
-
-END_INIT_SIM_OBJECT_PARAMS(LiveProcess)
-
-
-CREATE_SIM_OBJECT(LiveProcess)
-{
- string in = input;
- string out = output;
-
- // initialize file descriptors to default: same as simulator
- int stdin_fd, stdout_fd, stderr_fd;
-
- if (in == "stdin" || in == "cin")
- stdin_fd = STDIN_FILENO;
- else
- stdin_fd = Process::openInputFile(input);
-
- if (out == "stdout" || out == "cout")
- stdout_fd = STDOUT_FILENO;
- else if (out == "stderr" || out == "cerr")
- stdout_fd = STDERR_FILENO;
- else
- stdout_fd = Process::openOutputFile(out);
-
- stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
-
- return LiveProcess::create(getInstanceName(),
- stdin_fd, stdout_fd, stderr_fd,
- (string)executable == "" ? cmd[0] : executable,
- cmd, env);
-}
-
-REGISTER_SIM_OBJECT("LiveProcess", LiveProcess)
+DEFINE_SIM_OBJECT_CLASS_NAME("LiveProcess", LiveProcess);
diff --git a/sim/process.hh b/sim/process.hh
index 3a48f128c..b5b9d18b3 100644
--- a/sim/process.hh
+++ b/sim/process.hh
@@ -40,23 +40,24 @@
#include <vector>
-#include "arch/isa_traits.hh"
-#include "sim/sim_object.hh"
-#include "sim/stats.hh"
#include "base/statistics.hh"
-#include "base/trace.hh"
+#include "sim/sim_object.hh"
class CPUExecContext;
class ExecContext;
-class FunctionalMemory;
class SyscallDesc;
+class PageTable;
+class TranslatingPort;
+class System;
+
class Process : public SimObject
{
- protected:
- typedef TheISA::RegFile RegFile;
- typedef TheISA::MachInst MachInst;
public:
+ /// Pointer to object representing the system this process is
+ /// running on.
+ System *system;
+
// have we initialized an execution context from this process? If
// yes, subsequent contexts are assumed to be for dynamically
// created threads and are not initialized.
@@ -76,22 +77,12 @@ class Process : public SimObject
WaitRec(Addr chan, ExecContext *ctx)
: waitChan(chan), waitingContext(ctx)
- {
- }
+ { }
};
// list of all blocked contexts
std::list<WaitRec> waitList;
- RegFile *init_regs; // initial register contents
- CPUExecContext *cpuXC; // XC to hold the init_regs
-
- Addr text_base; // text (code) segment base
- unsigned text_size; // text (code) size in bytes
-
- Addr data_base; // initialized data segment base
- unsigned data_size; // initialized data + bss size in bytes
-
Addr brk_point; // top of the data segment
Addr stack_base; // stack segment base (highest address)
@@ -110,7 +101,6 @@ class Process : public SimObject
Addr nxm_end;
std::string prog_fname; // file name
- Addr prog_entry; // entry point (initial PC)
Stats::Scalar<> num_syscalls; // number of syscalls executed
@@ -118,6 +108,7 @@ class Process : public SimObject
protected:
// constructor
Process(const std::string &nm,
+ System *_system,
int stdin_fd, // initial I/O descriptors
int stdout_fd,
int stderr_fd);
@@ -126,7 +117,11 @@ class Process : public SimObject
virtual void startup();
protected:
- FunctionalMemory *memory;
+ /// Memory object for initialization (image loading)
+ TranslatingPort *initVirtMem;
+
+ public:
+ PageTable *pTable;
private:
// file descriptor remapping support
@@ -160,29 +155,7 @@ class Process : public SimObject
// look up simulator fd for given target fd
int sim_fd(int tgt_fd);
- // is this a valid instruction fetch address?
- bool validInstAddr(Addr addr)
- {
- return (text_base <= addr &&
- addr < text_base + text_size &&
- !(addr & (sizeof(MachInst)-1)));
- }
-
- // is this a valid address? (used to filter data fetches)
- // note that we just assume stack size <= 16MB
- // this may be alpha-specific
- bool validDataAddr(Addr addr)
- {
- return ((data_base <= addr && addr < brk_point) ||
- (next_thread_stack_base <= addr && addr < stack_base) ||
- (text_base <= addr && addr < (text_base + text_size)) ||
- (mmap_start <= addr && addr < mmap_end) ||
- (nxm_start <= addr && addr < nxm_end));
- }
-
virtual void syscall(ExecContext *xc) = 0;
-
- virtual FunctionalMemory *getMemory() { return memory; }
};
//
@@ -192,25 +165,21 @@ class ObjectFile;
class LiveProcess : public Process
{
protected:
+ ObjectFile *objFile;
+ std::vector<std::string> argv;
+ std::vector<std::string> envp;
+
LiveProcess(const std::string &nm, ObjectFile *objFile,
- int stdin_fd, int stdout_fd, int stderr_fd,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp);
- public:
- // this function is used to create the LiveProcess object, since
- // we can't tell which subclass of LiveProcess to use until we
- // open and look at the object file.
- static LiveProcess *create(const std::string &nm,
- int stdin_fd, int stdout_fd, int stderr_fd,
- std::string executable,
- std::vector<std::string> &argv,
- std::vector<std::string> &envp);
+ void argsInit(int intSize, int pageSize);
+ public:
virtual void syscall(ExecContext *xc);
- virtual SyscallDesc* getDesc(int callnum) { panic("Must be implemented."); }
-
+ virtual SyscallDesc* getDesc(int callnum) = 0;
};
diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc
index 00168b025..9e49c6a5e 100644
--- a/sim/syscall_emul.cc
+++ b/sim/syscall_emul.cc
@@ -33,9 +33,11 @@
#include <iostream>
#include "sim/syscall_emul.hh"
+#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "cpu/base.hh"
+#include "mem/page_table.hh"
#include "sim/process.hh"
#include "sim/sim_events.hh"
@@ -63,7 +65,11 @@ SyscallReturn
unimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
+ //warn("ignoring syscall %s(%d, %d, ...)", desc->name,
+ // xc->getSyscallArg(0), xc->getSyscallArg(1));
fatal("syscall %s (#%d) unimplemented.", desc->name, callnum);
+
+ return 1;
}
@@ -82,7 +88,7 @@ SyscallReturn
exitFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
- new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff);
+ new SimExitEvent("target called exit()", xc->getSyscallArg(0) & 0xff);
return 1;
}
@@ -98,11 +104,18 @@ getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
SyscallReturn
obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
+ Addr junk;
+
// change brk addr to first arg
Addr new_brk = xc->getSyscallArg(0);
- if (new_brk != 0)
- {
- p->brk_point = xc->getSyscallArg(0);
+ if (new_brk != 0) {
+ for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point,
+ VMPageSize); !gen.done(); gen.next()) {
+ if (!p->pTable->translate(gen.addr(), junk))
+ p->pTable->allocate(roundDown(gen.addr(), VMPageSize),
+ VMPageSize);
+ }
+ p->brk_point = new_brk;
}
DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point);
return p->brk_point;
@@ -130,7 +143,7 @@ readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
if (bytes_read != -1)
- bufArg.copyOut(xc->getMemPtr());
+ bufArg.copyOut(xc->getMemPort());
return bytes_read;
}
@@ -142,7 +155,7 @@ writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
int nbytes = xc->getSyscallArg(2);
BufferArg bufArg(xc->getSyscallArg(1), nbytes);
- bufArg.copyIn(xc->getMemPtr());
+ bufArg.copyIn(xc->getMemPort());
int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
@@ -183,7 +196,7 @@ gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
strncpy((char *)name.bufferPtr(), hostname, name_len);
- name.copyOut(xc->getMemPtr());
+ name.copyOut(xc->getMemPort());
return 0;
}
@@ -193,7 +206,7 @@ unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
return (TheISA::IntReg)-EFAULT;
int result = unlink(path.c_str());
@@ -205,12 +218,12 @@ renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
string old_name;
- if (xc->getMemPtr()->readString(old_name, xc->getSyscallArg(0)) != NoFault)
+ if (!xc->getMemPort()->tryReadString(old_name, xc->getSyscallArg(0)))
return -EFAULT;
string new_name;
- if (xc->getMemPtr()->readString(new_name, xc->getSyscallArg(1)) != NoFault)
+ if (!xc->getMemPort()->tryReadString(new_name, xc->getSyscallArg(1)))
return -EFAULT;
int64_t result = rename(old_name.c_str(), new_name.c_str());
@@ -222,7 +235,7 @@ truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
return -EFAULT;
off_t length = xc->getSyscallArg(1);
@@ -250,7 +263,7 @@ chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
return -EFAULT;
/* XXX endianess */
diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh
index 35129bcb4..ae1196f03 100644
--- a/sim/syscall_emul.hh
+++ b/sim/syscall_emul.hh
@@ -45,12 +45,15 @@
#endif
#include <sys/uio.h>
-#include "base/intmath.hh" // for RoundUp
-#include "mem/functional/functional.hh"
#include "arch/isa_traits.hh" // for Addr
-
+#include "base/chunk_generator.hh"
+#include "base/intmath.hh" // for RoundUp
+#include "base/misc.hh"
#include "base/trace.hh"
+#include "cpu/base.hh"
#include "cpu/exec_context.hh"
+#include "mem/translating_port.hh"
+#include "mem/page_table.hh"
#include "sim/process.hh"
///
@@ -106,18 +109,18 @@ class BaseBufferArg {
//
// copy data into simulator space (read from target memory)
//
- virtual bool copyIn(FunctionalMemory *mem)
+ virtual bool copyIn(TranslatingPort *memport)
{
- mem->access(Read, addr, bufPtr, size);
+ memport->readBlob(addr, bufPtr, size);
return true; // no EFAULT detection for now
}
//
// copy data out of simulator space (write to target memory)
//
- virtual bool copyOut(FunctionalMemory *mem)
+ virtual bool copyOut(TranslatingPort *memport)
{
- mem->access(Write, addr, bufPtr, size);
+ memport->writeBlob(addr, bufPtr, size);
return true; // no EFAULT detection for now
}
@@ -369,7 +372,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
return -EFAULT;
if (path == "/dev/sysdev0") {
@@ -416,7 +419,7 @@ chmodFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
return -EFAULT;
uint32_t mode = xc->getSyscallArg(1);
@@ -469,8 +472,8 @@ statFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
- return -EFAULT;
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
+ return -EFAULT;
struct stat hostBuf;
int result = stat(path.c_str(), &hostBuf);
@@ -478,7 +481,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -507,7 +510,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStat64Buf(xc->getMemPtr(), fd, xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStat64Buf(xc->getMemPort(), fd, xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -521,8 +524,8 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
- return -EFAULT;
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
+ return -EFAULT;
struct stat hostBuf;
int result = lstat(path.c_str(), &hostBuf);
@@ -530,7 +533,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -543,8 +546,8 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
- return -EFAULT;
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
+ return -EFAULT;
#if BSD_HOST
struct stat hostBuf;
@@ -557,7 +560,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStat64Buf(xc->getMemPtr(), -1, xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStat64Buf(xc->getMemPort(), -1, xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -581,7 +584,8 @@ fstatFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf);
+
return 0;
}
@@ -594,8 +598,8 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
- return -EFAULT;
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
+ return -EFAULT;
struct statfs hostBuf;
int result = statfs(path.c_str(), &hostBuf);
@@ -603,7 +607,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -626,7 +630,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -644,18 +648,20 @@ writevFunc(SyscallDesc *desc, int callnum, Process *process,
return -EBADF;
}
+ TranslatingPort *p = xc->getMemPort();
uint64_t tiov_base = xc->getSyscallArg(1);
size_t count = xc->getSyscallArg(2);
struct iovec hiov[count];
for (int i = 0; i < count; ++i)
{
typename OS::tgt_iovec tiov;
- xc->getMemPtr()->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec),
- &tiov, sizeof(typename OS::tgt_iovec));
+
+ p->readBlob(tiov_base + i*sizeof(typename OS::tgt_iovec),
+ (uint8_t*)&tiov, sizeof(typename OS::tgt_iovec));
hiov[i].iov_len = gtoh(tiov.iov_len);
hiov[i].iov_base = new char [hiov[i].iov_len];
- xc->getMemPtr()->access(Read, gtoh(tiov.iov_base),
- hiov[i].iov_base, hiov[i].iov_len);
+ p->readBlob(gtoh(tiov.iov_base), (uint8_t *)hiov[i].iov_base,
+ hiov[i].iov_len);
}
int result = writev(process->sim_fd(fd), hiov, count);
@@ -694,10 +700,15 @@ mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
int flags = xc->getSyscallArg(3);
// int fd = p->sim_fd(xc->getSyscallArg(4));
// int offset = xc->getSyscallArg(5);
+ Addr junk;
if (start == 0) {
// user didn't give an address... pick one from our "mmap region"
start = p->mmap_end;
+ for (ChunkGenerator gen(start, roundUp(length, TheISA::VMPageSize), TheISA::VMPageSize); !gen.done(); gen.next()) {
+ if (!p->pTable->translate(gen.addr(), junk))
+ p->pTable->allocate(roundDown(gen.addr(), TheISA::VMPageSize), TheISA::VMPageSize);
+ }
p->mmap_end += roundUp(length, TheISA::VMPageSize);
if (p->nxm_start != 0) {
//If we have an nxm space, make sure we haven't colided
@@ -737,7 +748,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process,
break;
}
- rlp.copyOut(xc->getMemPtr());
+ rlp.copyOut(xc->getMemPort());
return 0;
}
@@ -754,7 +765,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process,
tp->tv_sec = htog(tp->tv_sec);
tp->tv_usec = htog(tp->tv_usec);
- tp.copyOut(xc->getMemPtr());
+ tp.copyOut(xc->getMemPort());
return 0;
}
@@ -768,11 +779,11 @@ utimesFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
- return -EFAULT;
+ if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
+ return -EFAULT;
TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1));
- tp.copyIn(xc->getMemPtr());
+ tp.copyIn(xc->getMemPort());
struct timeval hostTimeval[2];
for (int i = 0; i < 2; ++i)
@@ -824,7 +835,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process,
rup->ru_nvcsw = 0;
rup->ru_nivcsw = 0;
- rup.copyOut(xc->getMemPtr());
+ rup.copyOut(xc->getMemPort());
return 0;
}
diff --git a/sim/system.cc b/sim/system.cc
index 8820922c1..409e41ead 100644
--- a/sim/system.cc
+++ b/sim/system.cc
@@ -1,16 +1,18 @@
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
-#include "base/remote_gdb.hh"
#include "cpu/exec_context.hh"
-#include "kern/kernel_stats.hh"
-#include "mem/functional/memory_control.hh"
-#include "mem/functional/physical.hh"
-#include "arch/vtophys.hh"
#include "sim/builder.hh"
#include "arch/isa_traits.hh"
#include "sim/byteswap.hh"
#include "sim/system.hh"
#include "base/trace.hh"
+#include "mem/mem_object.hh"
+#if FULL_SYSTEM
+#include "base/remote_gdb.hh"
+#include "kern/kernel_stats.hh"
+#include "mem/functional/memory_control.hh"
+#include "arch/vtophys.hh"
+#endif
using namespace std;
using namespace TheISA;
@@ -20,12 +22,18 @@ vector<System *> System::systemList;
int System::numSystemsRunning = 0;
System::System(Params *p)
- : SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem),
- init_param(p->init_param), numcpus(0), _params(p)
+ : SimObject(p->name), physmem(p->physmem), numcpus(0),
+#if FULL_SYSTEM
+ memctrl(p->memctrl), init_param(p->init_param),
+#else
+ page_ptr(0),
+#endif
+ _params(p)
{
// add self to global system list
systemList.push_back(this);
+#if FULL_SYSTEM
kernelSymtab = new SymbolTable;
debugSymbolTable = new SymbolTable;
@@ -63,25 +71,33 @@ System::System(Params *p)
DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
DPRINTF(Loader, "Kernel loaded...\n");
+ kernelBinning = new Kernel::Binning(this);
+#endif // FULL_SYSTEM
+
// increment the number of running systms
numSystemsRunning++;
-
- kernelBinning = new Kernel::Binning(this);
}
System::~System()
{
+#if FULL_SYSTEM
delete kernelSymtab;
delete kernel;
delete kernelBinning;
+#else
+ panic("System::fixFuncEventAddr needs to be rewritten "
+ "to work with syscall emulation");
+#endif // FULL_SYSTEM}
}
-
+#if FULL_SYSTEM
int rgdb_wait = -1;
+#endif // FULL_SYSTEM
+
int
System::registerExecContext(ExecContext *xc, int id)
{
@@ -101,6 +117,7 @@ System::registerExecContext(ExecContext *xc, int id)
execContexts[id] = xc;
numcpus++;
+#if FULL_SYSTEM
RemoteGDB *rgdb = new RemoteGDB(this, xc);
GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
gdbl->listen();
@@ -116,6 +133,7 @@ System::registerExecContext(ExecContext *xc, int id)
}
remoteGDB[id] = rgdb;
+#endif // FULL_SYSTEM
return id;
}
@@ -137,30 +155,48 @@ System::replaceExecContext(ExecContext *xc, int id)
}
execContexts[id] = xc;
+#if FULL_SYSTEM
remoteGDB[id]->replaceExecContext(xc);
+#endif // FULL_SYSTEM
+}
+
+#if !FULL_SYSTEM
+Addr
+System::new_page()
+{
+ Addr return_addr = page_ptr << LogVMPageSize;
+ ++page_ptr;
+ return return_addr;
}
+#endif
void
System::regStats()
{
+#if FULL_SYSTEM
kernelBinning->regStats(name() + ".kern");
+#endif // FULL_SYSTEM
}
void
System::serialize(ostream &os)
{
+#if FULL_SYSTEM
kernelBinning->serialize(os);
kernelSymtab->serialize("kernel_symtab", os);
+#endif // FULL_SYSTEM
}
void
System::unserialize(Checkpoint *cp, const string &section)
{
+#if FULL_SYSTEM
kernelBinning->unserialize(cp, section);
kernelSymtab->unserialize("kernel_symtab", cp, section);
+#endif // FULL_SYSTEM
}
void
@@ -181,5 +217,35 @@ printSystems()
System::printSystems();
}
+#if FULL_SYSTEM
+
+// In full system mode, only derived classes (e.g. AlphaLinuxSystem)
+// can be created directly.
+
DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
+#else
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
+
+ SimObjectParam<MemObject *> physmem;
+
+END_DECLARE_SIM_OBJECT_PARAMS(System)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(System)
+
+ INIT_PARAM(physmem, "physical memory")
+
+END_INIT_SIM_OBJECT_PARAMS(System)
+
+CREATE_SIM_OBJECT(System)
+{
+ System::Params *p = new System::Params;
+ p->name = getInstanceName();
+ p->physmem = physmem;
+ return new System(p);
+}
+
+REGISTER_SIM_OBJECT("System", System)
+
+#endif
diff --git a/sim/system.hh b/sim/system.hh
index ea482a102..0f82f81f5 100644
--- a/sim/system.hh
+++ b/sim/system.hh
@@ -32,30 +32,33 @@
#include <string>
#include <vector>
-#include "base/statistics.hh"
#include "base/loader/symtab.hh"
+#include "base/misc.hh"
+#include "base/statistics.hh"
#include "cpu/pc_event.hh"
-#include "kern/system_events.hh"
#include "sim/sim_object.hh"
+#if FULL_SYSTEM
+#include "kern/system_events.hh"
+#endif
class BaseCPU;
class ExecContext;
-class GDBListener;
class MemoryController;
class ObjectFile;
-class PhysicalMemory;
+class MemObject;
+
+#if FULL_SYSTEM
class Platform;
+class GDBListener;
class RemoteGDB;
namespace Kernel { class Binning; }
+#endif
class System : public SimObject
{
public:
- MemoryController *memctrl;
- PhysicalMemory *physmem;
- Platform *platform;
+ MemObject *physmem;
PCEventQueue pcEventQueue;
- uint64_t init_param;
std::vector<ExecContext *> execContexts;
int numcpus;
@@ -68,6 +71,11 @@ class System : public SimObject
return numcpus;
}
+#if FULL_SYSTEM
+ MemoryController *memctrl;
+ Platform *platform;
+ uint64_t init_param;
+
/** kernel symbol table */
SymbolTable *kernelSymtab;
@@ -85,8 +93,16 @@ class System : public SimObject
Kernel::Binning *kernelBinning;
+#else
+
+ int page_ptr;
+
+
+#endif // FULL_SYSTEM
+
protected:
+#if FULL_SYSTEM
/**
* Fix up an address used to match PCs for hooking simulator
* events on to target function executions. See comment in
@@ -118,18 +134,23 @@ class System : public SimObject
return addFuncEvent<T>(kernelSymtab, lbl);
}
+#endif
public:
+#if FULL_SYSTEM
std::vector<RemoteGDB *> remoteGDB;
std::vector<GDBListener *> gdbListen;
virtual bool breakpoint() = 0;
+#endif // FULL_SYSTEM
public:
struct Params
{
std::string name;
+ MemObject *physmem;
+
+#if FULL_SYSTEM
Tick boot_cpu_frequency;
MemoryController *memctrl;
- PhysicalMemory *physmem;
uint64_t init_param;
bool bin;
std::vector<std::string> binned_fns;
@@ -137,6 +158,7 @@ class System : public SimObject
std::string kernel_path;
std::string readfile;
+#endif
};
protected:
@@ -151,6 +173,8 @@ class System : public SimObject
const Params *params() const { return (const Params *)_params; }
public:
+
+#if FULL_SYSTEM
/**
* Returns the addess the kernel starts at.
* @return address the kernel starts at
@@ -169,6 +193,12 @@ class System : public SimObject
*/
Addr getKernelEntry() const { return kernelEntry; }
+#else
+
+ Addr new_page();
+
+#endif // FULL_SYSTEM
+
int registerExecContext(ExecContext *xc, int xcIndex);
void replaceExecContext(ExecContext *xc, int xcIndex);
diff --git a/util/qdo b/util/qdo
index 135cce4ef..b3c025720 100755
--- a/util/qdo
+++ b/util/qdo
@@ -179,10 +179,10 @@ try:
if output_dir:
secs_waited = 0
- while not shell.dir_exists(output_dir) and secs_waited < 45:
+ while not shell.dir_exists(output_dir) and secs_waited < 90:
time.sleep(5)
secs_waited += 5
- if secs_waited > 10:
+ if secs_waited > 30:
print "waited", secs_waited, "seconds for", output_dir
# run command