diff options
-rw-r--r-- | AUTHORS | 42 | ||||
-rw-r--r-- | README | 88 | ||||
-rw-r--r-- | RELEASE_NOTES | 8 | ||||
-rw-r--r-- | configs/test/test.py | 25 | ||||
-rw-r--r-- | src/arch/alpha/faults.cc | 33 | ||||
-rw-r--r-- | src/arch/alpha/faults.hh | 23 | ||||
-rw-r--r-- | src/arch/mips/faults.cc | 33 | ||||
-rw-r--r-- | src/arch/mips/faults.hh | 24 | ||||
-rw-r--r-- | src/arch/sparc/faults.cc | 30 | ||||
-rw-r--r-- | src/arch/sparc/faults.hh | 26 | ||||
-rw-r--r-- | src/base/fast_alloc.cc | 2 | ||||
-rw-r--r-- | src/base/trace.cc | 5 | ||||
-rw-r--r-- | src/cpu/o3/alpha_cpu.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/alpha_cpu_impl.hh | 16 | ||||
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 5 | ||||
-rw-r--r-- | src/cpu/o3/fetch.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit.hh | 2 | ||||
-rw-r--r-- | src/cpu/simple/atomic.cc | 11 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 4 | ||||
-rw-r--r-- | src/mem/page_table.cc | 30 | ||||
-rw-r--r-- | src/mem/page_table.hh | 11 | ||||
-rw-r--r-- | src/sim/debug.cc | 4 | ||||
-rw-r--r-- | src/sim/faults.hh | 4 | ||||
-rw-r--r-- | src/sim/process.cc | 5 | ||||
-rw-r--r-- | src/sim/sim_object.cc | 1 | ||||
-rw-r--r-- | src/sim/stat_control.cc | 3 | ||||
-rw-r--r-- | src/sim/system.cc | 1 |
27 files changed, 314 insertions, 128 deletions
diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..8904070d8 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,42 @@ +Steven K. Reinhardt +----------------------- + +Nathan L. Binkert +----------------------- + +Erik G. Hallnor +----------------------- + +Steve E. Raasch +----------------------- + +Lisa R. Hsu +----------------------- + +Ali G. Saidi +----------------------- + +Andrew L. Schultz +----------------------- + +Kevin T. Lim +----------------------- + +Ronald G. Dreslinski Jr +----------------------- + +Gabriel Black +----------------------- + +Korey Sewell +----------------------- + +David Green +----------------------- + +Benjamin S. Nash +----------------------- + +Miguel J. Serrano +----------------------- + @@ -1,21 +1,27 @@ -This is release m5_1.1 of the M5 simulator. +This is release 2.0 of the M5 simulator. -This file contains brief "getting started" instructions. For more -information, see http://m5.eecs.umich.edu. If you have questions, -please send mail to m5sim-users@lists.sourceforge.net. +For information about building the simulator and getting started please refer +to: http://m5.eecs.umich.edu/ + +Specific Pages of Interest are: +http://m5.eecs.umich.edu/wiki/index.php/Compiling_M5 +http://m5.eecs.umich.edu/wiki/index.php/Running_M5 + +If you have questions, please send mail to m5sim-users@lists.sourceforge.net. WHAT'S INCLUDED (AND NOT) ------------------------- The basic source release includes these subdirectories: - - m5: the simulator itself - - m5-test: regression tests - - ext: less-common external packages needed to build m5 - - alpha-system: source for Alpha console and PALcode + - m5: + - src: source code of the m5 simulator + - test: regression tests + - ext: less-common external packages needed to build m5 + - system/alpha: source for Alpha console and PALcode To run full-system simulations, you will need compiled console, PALcode, and kernel binaries and one or more disk images. These files -are collected in a separate archive, m5_system_1.1.tar.bz2. This file +are collected in a separate archive, m5_system_2.0.tar.bz2. This file is included on the CD release, or you can download it separately from Sourceforge. @@ -31,66 +37,8 @@ set of Linux source patches (linux_m5-2.6.8.1.diff), and the scons program needed to build M5. If you do not have the CD, the same HTML documentation is available online at http://m5.eecs.umich.edu/docs, the Linux source patches are available at -http://m5.eecs.umich.edu/dist/linux_m5-2.6.8.1.diff, and the scons -program is available from http://www.scons.org. - -WHAT'S NEEDED -------------- -- GCC version 3.3 or newer -- Python 2.3 or newer -- SCons 0.96.1 or newer (see http://www.scons.org) - -WHAT'S RECOMMENDED ------------------- -- MySQL (for statistics complex statistics storage/retrieval) -- Python-MysqlDB (for statistics analysis) - -GETTING STARTED ---------------- - -There are two different build targets and three optimizations levels: - -Target: -------- -ALPHA_SE - Syscall emulation simulation -ALPHA_FS - Full system simulation - -Optimization: -------------- -m5.debug - debug version of the code with tracing and without optimization -m5.opt - optimized version of code with tracing -m5.fast - optimized version of the code without tracing and asserts - -Different targets are built in different subdirectories of m5/build. -Binaries with the same target but different optimization levels share -the same directory. Note that you can build m5 in any directory you -choose;p just configure the target directory using the 'mkbuilddir' -script in m5/build. - -The following steps will build and test the simulator. The variable -"$top" refers to the top directory where you've unpacked the files, -i.e., the one containing the m5, m5-test, and ext directories. If you -have a multiprocessor system, you should give scons a "-j N" argument (like -make) to run N jobs in parallel. - -To build and test the syscall-emulation simulator: - - cd $top/m5/build - scons ALPHA_SE/test/opt/quick - -This process takes under 10 minutes on a dual 3GHz Xeon system (using -the '-j 4' option). - -To build and test the full-system simulator: - -1. Unpack the full-system binaries from m5_system_1.1.tar.bz2. (See - above for directions on obtaining this file if you don't have it.) - This package includes disk images and kernel, palcode, and console - binaries for Linux and FreeBSD. -2. Edit the SYSTEMDIR search path in $top/m5-test/SysPaths.py to - include the path to your local copy of the binaries. -3. In $top/m5/build, run "scons ALPHA_FS/test/opt/quick". +http://m5.eecs.umich.edu/dist/linux_m5-2.6.8.1.diff, the scons +program is available from http://www.scons.org, and swig is available from +http://www.swig.org. -This process also takes under 10 minutes on a dual 3GHz Xeon system -(again using the '-j 4' option). diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 983c9b2e9..6eb9b1844 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,3 +1,11 @@ +XXX. X, 2006: m5_2.0 +-------------------- +Major update to M5 including: +- New CPU model +- Sew memory system +- More extensive python integration +- Preliminary syscall emulation support for MIPS and SPARC + Oct. 8, 2005: m5_1.1 -------------------- Update release for IOSCA workshop mini-tutorial. New features include: diff --git a/configs/test/test.py b/configs/test/test.py index 48d43cee9..3095cd1d1 100644 --- a/configs/test/test.py +++ b/configs/test/test.py @@ -11,10 +11,19 @@ from FullO3Config import * # parse command-line arguments parser = optparse.OptionParser(option_list=m5.standardOptions) -parser.add_option("-c", "--cmd", default="hello") -parser.add_option("-t", "--timing", action="store_true") -parser.add_option("-d", "--detailed", action="store_true") -parser.add_option("-m", "--maxtick", type="int") +parser.add_option("-c", "--cmd", default="hello", + help="The binary to run in syscall emulation mode.") +parser.add_option("-o", "--options", default="", + help="The options to pass to the binary, use \" \" around the entire\ + string.") +parser.add_option("-i", "--input", default="", + help="A file of input to give to the binary.") +parser.add_option("-t", "--timing", action="store_true", + help="Use simple timing CPU.") +parser.add_option("-d", "--detailed", action="store_true", + help="Use detailed CPU.") +parser.add_option("-m", "--maxtick", type="int", + help="Set the maximum number of ticks to run for") (options, args) = parser.parse_args() m5.setStandardOptions(options) @@ -28,11 +37,17 @@ this_dir = os.path.dirname(__file__) process = LiveProcess() process.executable = os.path.join(this_dir, options.cmd) -process.cmd = options.cmd +process.cmd = options.cmd + " " + options.options +if options.input != "": + process.input = options.input magicbus = Bus() mem = PhysicalMemory() +if options.timing and options.detailed: + print "Error: you may only specify one cpu model"; + sys.exit(1) + if options.timing: cpu = TimingSimpleCPU() elif options.detailed: diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 8493223ff..eef4361fd 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -35,6 +35,9 @@ #include "base/trace.hh" #if FULL_SYSTEM #include "arch/alpha/ev5.hh" +#else +#include "sim/process.hh" +#include "mem/page_table.hh" #endif namespace AlphaISA @@ -56,6 +59,12 @@ FaultName ArithmeticFault::_name = "arith"; FaultVect ArithmeticFault::_vect = 0x0501; FaultStat ArithmeticFault::_count; +#if !FULL_SYSTEM +FaultName PageTableFault::_name = "page_table_fault"; +FaultVect PageTableFault::_vect = 0x0000; +FaultStat PageTableFault::_count; +#endif + FaultName InterruptFault::_name = "interrupt"; FaultVect InterruptFault::_vect = 0x0101; FaultStat InterruptFault::_count; @@ -173,6 +182,30 @@ void ItbFault::invoke(ThreadContext * tc) AlphaFault::invoke(tc); } +#else //!FULL_SYSTEM + +void PageTableFault::invoke(ThreadContext *tc) +{ + Process *p = tc->getProcessPtr(); + + // address is higher than the stack region or in the current stack region + if (vaddr > p->stack_base || vaddr > p->stack_min) + FaultBase::invoke(tc); + + // We've accessed the next page + if (vaddr > p->stack_min - PageBytes) { + warn("Increasing stack %#x:%#x to %#x:%#x because of access to %#x", + p->stack_min, p->stack_base, p->stack_min - PageBytes, + p->stack_base, vaddr); + p->stack_min -= PageBytes; + if (p->stack_base - p->stack_min > 8*1024*1024) + fatal("Over max stack size for one thread\n"); + p->pTable->allocate(p->stack_min, PageBytes); + } else { + FaultBase::invoke(tc); + } +} + #endif } // namespace AlphaISA diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh index f952cf9d6..11a568174 100644 --- a/src/arch/alpha/faults.hh +++ b/src/arch/alpha/faults.hh @@ -81,6 +81,29 @@ class AlignmentFault : public AlphaFault bool isAlignmentFault() {return true;} }; +#if !FULL_SYSTEM +class PageTableFault : public AlphaFault +{ + private: + Addr vaddr; + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + PageTableFault(Addr va) + : vaddr(va) {} + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} + void invoke(ThreadContext * tc); +}; + +static inline Fault genPageTableFault(Addr va) +{ + return new PageTableFault(va); +} +#endif + static inline Fault genMachineCheckFault() { return new MachineCheckFault; diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc index 810c3fed4..cfeb045eb 100644 --- a/src/arch/mips/faults.cc +++ b/src/arch/mips/faults.cc @@ -32,6 +32,10 @@ #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "base/trace.hh" +#if !FULL_SYSTEM +#include "sim/process.hh" +#include "mem/page_table.hh" +#endif namespace MipsISA { @@ -52,6 +56,12 @@ FaultName ArithmeticFault::_name = "arith"; FaultVect ArithmeticFault::_vect = 0x0501; FaultStat ArithmeticFault::_count; +#if !FULL_SYSTEM +FaultName PageTableFault::_name = "page_table_fault"; +FaultVect PageTableFault::_vect = 0x0000; +FaultStat PageTableFault::_count; +#endif + FaultName InterruptFault::_name = "interrupt"; FaultVect InterruptFault::_vect = 0x0101; FaultStat InterruptFault::_count; @@ -127,7 +137,28 @@ void ArithmeticFault::invoke(ThreadContext * tc) panic("Arithmetic traps are unimplemented!"); } -#endif +#else //!FULL_SYSTEM +void PageTableFault::invoke(ThreadContext *tc) +{ + Process *p = tc->getProcessPtr(); + + // address is higher than the stack region or in the current stack region + if (vaddr > p->stack_base || vaddr > p->stack_min) + FaultBase::invoke(tc); + + // We've accessed the next page + if (vaddr > p->stack_min - PageBytes) { + p->stack_min -= PageBytes; + if (p->stack_base - p->stack_min > 8*1024*1024) + fatal("Over max stack size for one thread\n"); + p->pTable->allocate(p->stack_min, PageBytes); + warn("Increasing stack size by one page."); + } else { + FaultBase::invoke(tc); + } +} + +#endif } // namespace MipsISA diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh index d8bf59cc1..95c61cfbc 100644 --- a/src/arch/mips/faults.hh +++ b/src/arch/mips/faults.hh @@ -79,6 +79,30 @@ class AlignmentFault : public MipsFault bool isAlignmentFault() {return true;} }; +#if !FULL_SYSTEM +class PageTableFault : public MipsFault +{ + private: + Addr vaddr; + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + PageTableFault(Addr va) + : vaddr(va) {} + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} + void invoke(ThreadContext * tc); +}; + +static inline Fault genPageTableFault(Addr va) +{ + return new PageTableFault(va); +} +#endif + + static inline Fault genMachineCheckFault() { return new MachineCheckFault; diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 2af242bd8..7b7765935 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -33,6 +33,10 @@ #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "base/trace.hh" +#if !FULL_SYSTEM +#include "sim/process.hh" +#include "mem/page_table.hh" +#endif namespace SparcISA { @@ -218,6 +222,13 @@ TrapType TrapInstruction::_baseTrapType = 0x100; FaultPriority TrapInstruction::_priority = 16; FaultStat TrapInstruction::_count; +#if !FULL_SYSTEM +FaultName PageTableFault::_name = "page_table_fault"; +TrapType PageTableFault::_trapType = 0x0000; +FaultPriority PageTableFault::_priority = 0; +FaultStat PageTableFault::_count; +#endif + #if FULL_SYSTEM void SparcFault::invoke(ThreadContext * tc) @@ -252,6 +263,25 @@ void TrapInstruction::invoke(ThreadContext * tc) // Should be handled in ISA. } +void PageTableFault::invoke(ThreadContext *tc) +{ + Process *p = tc->getProcessPtr(); + + // address is higher than the stack region or in the current stack region + if (vaddr > p->stack_base || vaddr > p->stack_min) + FaultBase::invoke(tc); + + // We've accessed the next page + if (vaddr > p->stack_min - PageBytes) { + p->stack_min -= PageBytes; + if (p->stack_base - p->stack_min > 8*1024*1024) + fatal("Over max stack size for one thread\n"); + p->pTable->allocate(p->stack_min, PageBytes); + warn("Increasing stack size by one page."); + } else { + FaultBase::invoke(tc); + } +} #endif } // namespace SparcISA diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 9f595a28b..b279f4911 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -83,6 +83,31 @@ class MemAddressNotAligned : public SparcFault bool isAlignmentFault() {return true;} }; +#if !FULL_SYSTEM +class PageTableFault : public SparcFault +{ + private: + Addr vaddr; + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + PageTableFault(Addr va) + : vaddr(va) {} + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} + void invoke(ThreadContext * tc); +}; + +static inline Fault genPageTableFault(Addr va) +{ + return new PageTableFault(va); +} +#endif + static inline Fault genMachineCheckFault() { return new InternalProcessorError; @@ -589,6 +614,7 @@ class TrapInstruction : public EnumeratedFault #endif }; + } // SparcISA namespace #endif // __FAULTS_HH__ diff --git a/src/base/fast_alloc.cc b/src/base/fast_alloc.cc index 455fb8ed7..610dff66c 100644 --- a/src/base/fast_alloc.cc +++ b/src/base/fast_alloc.cc @@ -180,13 +180,11 @@ FastAlloc::dump_oldest(int n) // C interfaces to FastAlloc::dump_summary() and FastAlloc::dump_oldest(). // gdb seems to have trouble with calling C++ functions directly. // -extern "C" void fast_alloc_summary() { FastAlloc::dump_summary(); } -extern "C" void fast_alloc_oldest(int n) { FastAlloc::dump_oldest(n); diff --git a/src/base/trace.cc b/src/base/trace.cc index 50426b992..9fa615f4d 100644 --- a/src/base/trace.cc +++ b/src/base/trace.cc @@ -247,7 +247,6 @@ DebugOut() // // Dump trace buffer to specified file (cout if NULL) // -extern "C" void dumpTrace(const char *filename) { @@ -269,7 +268,6 @@ dumpTrace(const char *filename) // same facility as the "trace to file" feature, and will print error // messages rather than clobbering an existing ostream pointer. // -extern "C" void echoTrace(bool on) { @@ -289,7 +287,6 @@ echoTrace(bool on) } } -extern "C" void printTraceFlags() { @@ -338,14 +335,12 @@ tweakTraceFlag(const char *string, bool value) cprintf("could not find flag %s\n", string); } -extern "C" void setTraceFlag(const char *string) { tweakTraceFlag(string, true); } -extern "C" void clearTraceFlag(const char *string) { diff --git a/src/cpu/o3/alpha_cpu.hh b/src/cpu/o3/alpha_cpu.hh index 55b975142..d7f3d5801 100644 --- a/src/cpu/o3/alpha_cpu.hh +++ b/src/cpu/o3/alpha_cpu.hh @@ -384,8 +384,6 @@ class AlphaO3CPU : public FullO3CPU<Impl> bool inPalMode(uint64_t PC) { return AlphaISA::PcPAL(PC); } - /** Traps to handle given fault. */ - void trap(Fault fault, unsigned tid); bool simPalCheck(int palFunc, unsigned tid); /** Processes any interrupts. */ @@ -395,6 +393,8 @@ class AlphaO3CPU : public FullO3CPU<Impl> void halt() { panic("Halt not implemented!\n"); } #endif + /** Traps to handle given fault. */ + void trap(Fault fault, unsigned tid); #if !FULL_SYSTEM /** Executes a syscall. diff --git a/src/cpu/o3/alpha_cpu_impl.hh b/src/cpu/o3/alpha_cpu_impl.hh index 532611fb6..eca6fbbcb 100644 --- a/src/cpu/o3/alpha_cpu_impl.hh +++ b/src/cpu/o3/alpha_cpu_impl.hh @@ -755,14 +755,6 @@ AlphaO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid) template <class Impl> void -AlphaO3CPU<Impl>::trap(Fault fault, unsigned tid) -{ - // Pass the thread's TC into the invoke method. - fault->invoke(this->threadContexts[tid]); -} - -template <class Impl> -void AlphaO3CPU<Impl>::processInterrupts() { // Check for interrupts here. For now can copy the code that @@ -823,6 +815,14 @@ AlphaO3CPU<Impl>::processInterrupts() #endif // FULL_SYSTEM +template <class Impl> +void +AlphaO3CPU<Impl>::trap(Fault fault, unsigned tid) +{ + // Pass the thread's TC into the invoke method. + fault->invoke(this->threadContexts[tid]); +} + #if !FULL_SYSTEM template <class Impl> diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 176f83246..cd7dd47d4 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -991,7 +991,6 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num) if (inst_fault != NoFault) { head_inst->setCompleted(); -#if FULL_SYSTEM DPRINTF(Commit, "Inst [sn:%lli] PC %#x has a fault\n", head_inst->seqNum, head_inst->readPC()); @@ -1035,10 +1034,6 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num) generateTrapEvent(tid); return false; -#else // !FULL_SYSTEM - panic("fault (%d) detected @ PC %08p", inst_fault, - head_inst->PC); -#endif // FULL_SYSTEM } updateComInstStats(head_inst); diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 790c28f09..7fcd21b7d 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -36,7 +36,7 @@ #include "base/statistics.hh" #include "base/timebuf.hh" #include "cpu/pc_event.hh" -#include "mem/packet.hh" +#include "mem/packet_impl.hh" #include "mem/port.hh" #include "sim/eventq.hh" diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index 9b67e61f2..74b8fe5bb 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -40,7 +40,7 @@ #include "config/full_system.hh" #include "base/hashmap.hh" #include "cpu/inst_seq.hh" -#include "mem/packet.hh" +#include "mem/packet_impl.hh" #include "mem/port.hh" /** diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 7be74e97e..be6f421b3 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -407,15 +407,14 @@ AtomicSimpleCPU::tick() postExecute(); if (simulate_stalls) { - // This calculation assumes that the icache and dcache - // access latencies are always a multiple of the CPU's - // cycle time. If not, the next tick event may get - // scheduled at a non-integer multiple of the CPU - // cycle time. Tick icache_stall = icache_latency - cycles(1); Tick dcache_stall = dcache_access ? dcache_latency - cycles(1) : 0; - latency += icache_stall + dcache_stall; + Tick stall_cycles = (icache_stall + dcache_stall) / cycles(1); + if (cycles(stall_cycles) < (icache_stall + dcache_stall)) + latency += cycles(stall_cycles+1); + else + latency += cycles(stall_cycles); } } diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index b4258fce6..db5dd2acf 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -446,11 +446,7 @@ void BaseSimpleCPU::advancePC(Fault fault) { if (fault != NoFault) { -#if FULL_SYSTEM fault->invoke(tc); -#else // !FULL_SYSTEM - fatal("fault (%s) detected @ PC %08p", fault->name(), thread->readPC()); -#endif // FULL_SYSTEM } else { // go to the next instruction diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index b5cecc7da..a34a0393a 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -54,6 +54,9 @@ PageTable::PageTable(System *_system, Addr _pageSize) system(_system) { assert(isPowerOf2(pageSize)); + pTableCache[0].vaddr = 0; + pTableCache[1].vaddr = 0; + pTableCache[2].vaddr = 0; } PageTable::~PageTable() @@ -95,7 +98,7 @@ PageTable::allocate(Addr vaddr, int size) assert(pageOffset(vaddr) == 0); for (; size > 0; size -= pageSize, vaddr += pageSize) { - std::map<Addr,Addr>::iterator iter = pTable.find(vaddr); + m5::hash_map<Addr,Addr>::iterator iter = pTable.find(vaddr); if (iter != pTable.end()) { // already mapped @@ -103,6 +106,12 @@ PageTable::allocate(Addr vaddr, int size) } pTable[vaddr] = system->new_page(); + pTableCache[2].paddr = pTableCache[1].paddr; + pTableCache[2].vaddr = pTableCache[1].vaddr; + pTableCache[1].paddr = pTableCache[0].paddr; + pTableCache[1].vaddr = pTableCache[0].vaddr; + pTableCache[0].paddr = pTable[vaddr]; + pTableCache[0].vaddr = vaddr; } } @@ -112,7 +121,22 @@ bool PageTable::translate(Addr vaddr, Addr &paddr) { Addr page_addr = pageAlign(vaddr); - std::map<Addr,Addr>::iterator iter = pTable.find(page_addr); + paddr = 0; + + if (pTableCache[0].vaddr == vaddr) { + paddr = pTableCache[0].paddr; + return true; + } + if (pTableCache[1].vaddr == vaddr) { + paddr = pTableCache[1].paddr; + return true; + } + if (pTableCache[2].vaddr == vaddr) { + paddr = pTableCache[2].paddr; + return true; + } + + m5::hash_map<Addr,Addr>::iterator iter = pTable.find(page_addr); if (iter == pTable.end()) { return false; @@ -130,7 +154,7 @@ PageTable::translate(RequestPtr &req) assert(pageAlign(req->getVaddr() + req->getSize() - 1) == pageAlign(req->getVaddr())); if (!translate(req->getVaddr(), paddr)) { - return genMachineCheckFault(); + return genPageTableFault(req->getVaddr()); } req->setPaddr(paddr); return page_check(req->getPaddr(), req->getSize()); diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index f7212d423..494c0ce9a 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -37,9 +37,9 @@ #define __PAGE_TABLE__ #include <string> -#include <map> #include "arch/isa_traits.hh" +#include "base/hashmap.hh" #include "base/trace.hh" #include "mem/request.hh" #include "mem/packet.hh" @@ -53,7 +53,14 @@ class System; class PageTable { protected: - std::map<Addr,Addr> pTable; + m5::hash_map<Addr,Addr> pTable; + + struct cacheElement { + Addr paddr; + Addr vaddr; + } ; + + struct cacheElement pTableCache[3]; const Addr pageSize; const Addr offsetMask; diff --git a/src/sim/debug.cc b/src/sim/debug.cc index b82219f7d..be9566836 100644 --- a/src/sim/debug.cc +++ b/src/sim/debug.cc @@ -127,12 +127,12 @@ DebugContext::checkParams() // handy function to schedule DebugBreakEvent on main event queue // (callable from debugger) // -extern "C" void sched_break_cycle(Tick when) +void sched_break_cycle(Tick when) { new DebugBreakEvent(&mainEventQueue, when); } -extern "C" void eventq_dump() +void eventq_dump() { mainEventQueue.dump(); } diff --git a/src/sim/faults.hh b/src/sim/faults.hh index 23385c649..00264d8fc 100644 --- a/src/sim/faults.hh +++ b/src/sim/faults.hh @@ -54,11 +54,7 @@ class FaultBase : public RefCounted { public: virtual FaultName name() = 0; -#if FULL_SYSTEM virtual void invoke(ThreadContext * tc); -#else - virtual void invoke(ThreadContext * tc); -#endif // template<typename T> // bool isA() {return dynamic_cast<T *>(this);} virtual bool isMachineCheckFault() {return false;} diff --git a/src/sim/process.cc b/src/sim/process.cc index 5080c3ac1..9cdc5b9f5 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -326,11 +326,10 @@ LiveProcess::argsInit(int intSize, int pageSize) // set bottom of stack stack_min = stack_base - space_needed; // align it - stack_min &= ~(intSize-1); + stack_min = roundDown(stack_min, pageSize); stack_size = stack_base - stack_min; // map memory - pTable->allocate(roundDown(stack_min, pageSize), - roundUp(stack_size, pageSize)); + pTable->allocate(stack_min, roundUp(stack_size, pageSize)); // map out initial stack contents Addr argv_array_base = stack_min + intSize; // room for argc diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc index 5752e4ef1..551555b25 100644 --- a/src/sim/sim_object.cc +++ b/src/sim/sim_object.cc @@ -256,7 +256,6 @@ SimObject::debugObjectBreak(const string &objs) } } -extern "C" void debugObjectBreak(const char *objs) { diff --git a/src/sim/stat_control.cc b/src/sim/stat_control.cc index f7fc03d74..041830ab7 100644 --- a/src/sim/stat_control.cc +++ b/src/sim/stat_control.cc @@ -221,8 +221,7 @@ SetupEvent(int flags, Tick when, Tick repeat) /* namespace Stats */ } -extern "C" void -debugDumpStats() +void debugDumpStats() { Stats::DumpNow(); } diff --git a/src/sim/system.cc b/src/sim/system.cc index 91bba85fe..89e7b8542 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -243,7 +243,6 @@ System::printSystems() } } -extern "C" void printSystems() { |