Merge ktlim@zizzer:/bk/newmem

into  zamp.eecs.umich.edu:/z/ktlim2/clean/newmem-merge

--HG--
extra : convert_revision : 0756f7f1f63fae472e0ef1d20e9eb38e56de78c8
This commit is contained in:
Kevin Lim 2006-06-29 21:38:16 -04:00
commit 0fbecab797
27 changed files with 314 additions and 128 deletions

42
AUTHORS Normal file
View file

@ -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
-----------------------

86
README
View file

@ -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
- m5:
- src: source code of the m5 simulator
- test: regression tests
- ext: less-common external packages needed to build m5
- alpha-system: source for Alpha console and PALcode
- 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.
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.
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".
This process also takes under 10 minutes on a dual 3GHz Xeon system
(again using the '-j 4' option).

View file

@ -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:

View file

@ -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:

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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__

View file

@ -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);

View file

@ -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)
{

View file

@ -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.

View file

@ -753,14 +753,6 @@ AlphaO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
return true;
}
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()
@ -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>

View file

@ -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);

View file

@ -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"

View file

@ -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"
/**

View file

@ -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);
}
}

View file

@ -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

View file

@ -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());

View file

@ -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;

View file

@ -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();
}

View file

@ -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;}

View file

@ -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

View file

@ -256,7 +256,6 @@ SimObject::debugObjectBreak(const string &objs)
}
}
extern "C"
void
debugObjectBreak(const char *objs)
{

View file

@ -221,8 +221,7 @@ SetupEvent(int flags, Tick when, Tick repeat)
/* namespace Stats */ }
extern "C" void
debugDumpStats()
void debugDumpStats()
{
Stats::DumpNow();
}

View file

@ -243,7 +243,6 @@ System::printSystems()
}
}
extern "C"
void
printSystems()
{