summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2012-01-07 02:15:35 -0800
committerGabe Black <gblack@eecs.umich.edu>2012-01-07 02:15:35 -0800
commitec936364b7238cddea7734ea79c6e04b52a683c6 (patch)
tree788fc19c3ba599d6f39d3990769888a0650be5ff /src
parent36a822f08e88483b41af214ace4fd3dccf3aa8cb (diff)
parent9b52717a92ed9592bd98a41683509f538262a5c7 (diff)
downloadgem5-ec936364b7238cddea7734ea79c6e04b52a683c6.tar.xz
Merge with the main repository again.
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/isa/insts/misc.isa3
-rw-r--r--src/arch/arm/table_walker.cc2
-rw-r--r--src/arch/sparc/isa/formats/basic.isa68
-rw-r--r--src/arch/x86/isa/microops/regop.isa11
-rw-r--r--src/arch/x86/predecoder.cc2
-rw-r--r--src/base/bitmap.cc44
-rw-r--r--src/base/bitmap.hh15
-rw-r--r--src/base/compiler.hh2
-rw-r--r--src/base/output.cc140
-rw-r--r--src/base/output.hh121
-rw-r--r--src/base/stats/text.cc6
-rw-r--r--src/base/trace.cc2
-rw-r--r--src/base/vnc/VncServer.py1
-rw-r--r--src/base/vnc/convert.cc23
-rw-r--r--src/base/vnc/convert.hh18
-rw-r--r--src/base/vnc/vncserver.cc54
-rw-r--r--src/base/vnc/vncserver.hh22
-rw-r--r--src/cpu/BaseCPU.py19
-rw-r--r--src/cpu/base.cc6
-rw-r--r--src/cpu/o3/O3CPU.py4
-rw-r--r--src/cpu/o3/cpu.cc13
-rw-r--r--src/cpu/o3/cpu.hh3
-rw-r--r--src/dev/io_device.cc12
-rw-r--r--src/dev/io_device.hh36
-rw-r--r--src/dev/sparc/mm_disk.cc2
-rw-r--r--src/dev/terminal.cc3
-rw-r--r--src/mem/physical.cc3
-rw-r--r--src/mem/protocol/MOESI_hammer-cache.sm66
-rw-r--r--src/mem/protocol/Network_test.slicc1
-rw-r--r--src/mem/ruby/network/topologies/MeshDirCorners.py2
-rw-r--r--src/sim/process.cc2
31 files changed, 593 insertions, 113 deletions
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa
index 495cb722c..b671843cf 100644
--- a/src/arch/arm/isa/insts/misc.isa
+++ b/src/arch/arm/isa/insts/misc.isa
@@ -49,7 +49,8 @@ let {{
svcIop = InstObjParams("svc", "Svc", "PredOp",
{ "code": svcCode,
- "predicate_test": predicateTest }, ["IsSyscall"])
+ "predicate_test": predicateTest },
+ ["IsSyscall", "IsNonSpeculative", "IsSerializeAfter"])
header_output = BasicDeclare.subst(svcIop)
decoder_output = BasicConstructor.subst(svcIop)
exec_output = PredOpExecute.subst(svcIop)
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 62b22472b..b2ab010c0 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -99,7 +99,7 @@ TableWalker::getPort(const std::string &if_name, int idx)
System *sys = params()->sys;
Tick minb = params()->min_backoff;
Tick maxb = params()->max_backoff;
- port = new DmaPort(this, sys, minb, maxb);
+ port = new DmaPort(this, sys, minb, maxb, true);
return port;
}
return NULL;
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index bef8af2cd..915e34564 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -33,6 +33,11 @@ def template BasicExecDeclare {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
+def template DoFpOpDeclare {{
+ Fault doFpOp(%(CPU_exec_context)s *, Trace::InstRecord *)
+ const M5_NO_INLINE;
+}};
+
// Definitions of execute methods that panic.
def template BasicExecPanic {{
Fault
@@ -58,6 +63,21 @@ def template BasicDeclare {{
}};
// Basic instruction class declaration template.
+def template FpBasicDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ // Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(DoFpOpDeclare)s
+ };
+}};
+
+// Basic instruction class declaration template.
def template BasicDeclareWithMnemonic {{
/**
* Static instruction class for "%(mnemonic)s".
@@ -110,6 +130,22 @@ def template BasicExecute {{
}
}};
+def template DoFpOpExecute {{
+ Fault
+ %(class_name)s::doFpOp(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(fp_code)s;
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+ return fault;
+ }
+}};
+
// Basic decode template.
def template BasicDecode {{
return new %(class_name)s(machInst);
@@ -131,9 +167,9 @@ def format BasicOperate(code, *flags) {{
}};
def format FpBasic(code, *flags) {{
- fp_code = """
- Fsr |= bits(Fsr,4,0) << 5;
- Fsr = insertBits(Fsr,4,0,0);
+ exec_code = """
+ Fsr |= bits(Fsr, 4, 0) << 5;
+ Fsr = insertBits(Fsr, 4, 0, 0);
int newrnd = M5_FE_TONEAREST;
switch (Fsr<31:30>) {
case 0: newrnd = M5_FE_TONEAREST; break;
@@ -143,18 +179,18 @@ def format FpBasic(code, *flags) {{
}
int oldrnd = m5_fegetround();
m5_fesetround(newrnd);
+ __asm__ __volatile__("" ::: "memory");
+ fault = doFpOp(xc, traceData);
+ __asm__ __volatile__("" ::: "memory");
+ m5_fesetround(oldrnd);
+ return fault;
"""
-
- fp_code += code
-
-
- fp_code += """
- m5_fesetround(oldrnd);
-"""
- fp_code = filterDoubles(fp_code)
- iop = InstObjParams(name, Name, 'SparcStaticInst', fp_code, flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
+ fp_code = filterDoubles(code)
+ iop = InstObjParams(name, Name, 'SparcStaticInst',
+ { "code" : exec_code, "fp_code" : fp_code }, flags)
+ header_output = FpBasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+ exec_output += DoFpOpExecute.subst(iop)
}};
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index a6e0564ba..bc139a609 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -1335,16 +1335,15 @@ let {{
if (selector.si || selector.ti) {
if (!desc.p) {
fault = new StackFault(selector);
- }
- } else {
- if ((m5reg.submode != SixtyFourBitMode ||
- m5reg.cpl == 3) ||
- !(desc.s == 1 &&
- desc.type.codeOrData == 0 && desc.type.w) ||
+ } else if (!(desc.s == 1 && desc.type.codeOrData == 0 &&
+ desc.type.w) ||
(desc.dpl != m5reg.cpl) ||
(selector.rpl != m5reg.cpl)) {
fault = new GeneralProtection(selector);
}
+ } else if (m5reg.submode != SixtyFourBitMode ||
+ m5reg.cpl == 3) {
+ fault = new GeneralProtection(selector);
}
break;
case SegIretCheck:
diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc
index 429b91687..a4aa93b48 100644
--- a/src/arch/x86/predecoder.cc
+++ b/src/arch/x86/predecoder.cc
@@ -186,7 +186,7 @@ namespace X86ISA
DPRINTF(Predecoder, "Found two byte opcode.\n");
emi.opcode.prefixA = nextByte;
}
- else if(emi.opcode.num == 2 && (nextByte == 0x38 || nextByte == 0x3F))
+ else if(emi.opcode.num == 2 && (nextByte == 0x38 || nextByte == 0x3A))
{
nextState = OpcodeState;
DPRINTF(Predecoder, "Found three byte opcode.\n");
diff --git a/src/base/bitmap.cc b/src/base/bitmap.cc
index 0d2a9302b..08425d74f 100644
--- a/src/base/bitmap.cc
+++ b/src/base/bitmap.cc
@@ -36,6 +36,7 @@
*
* Authors: William Wang
* Ali Saidi
+ * Chris Emmons
*/
#include <cassert>
@@ -43,29 +44,50 @@
#include "base/bitmap.hh"
#include "base/misc.hh"
+const size_t Bitmap::sizeofHeaderBuffer = sizeof(Magic) + sizeof(Header) +
+ sizeof(Info);
+
// bitmap class ctor
Bitmap::Bitmap(VideoConvert::Mode _mode, uint16_t w, uint16_t h, uint8_t *d)
: mode(_mode), height(h), width(w), data(d),
- vc(mode, VideoConvert::rgb8888, width, height)
+ vc(mode, VideoConvert::rgb8888, width, height), headerBuffer(0)
{
}
+Bitmap::~Bitmap() {
+ if (headerBuffer)
+ delete [] headerBuffer;
+}
+
void
-Bitmap::write(std::ostream *bmp)
+Bitmap::write(std::ostream *bmp) const
{
assert(data);
- // For further information see: http://en.wikipedia.org/wiki/BMP_file_format
- Magic magic = {{'B','M'}};
- Header header = {sizeof(VideoConvert::Rgb8888) * width * height , 0, 0, 54};
- Info info = {sizeof(Info), width, height, 1,
- sizeof(VideoConvert::Rgb8888) * 8, 0,
- sizeof(VideoConvert::Rgb8888) * width * height, 1, 1, 0, 0};
+ // header is always the same for a bitmap object; compute the info once per
+ // bitmap object
+ if (!headerBuffer) {
+ // For further information see:
+ // http://en.wikipedia.org/wiki/BMP_file_format
+ Magic magic = {{'B','M'}};
+ Header header = {sizeof(VideoConvert::Rgb8888) * width * height,
+ 0, 0, 54};
+ Info info = {sizeof(Info), width, height, 1,
+ sizeof(VideoConvert::Rgb8888) * 8, 0,
+ sizeof(VideoConvert::Rgb8888) * width * height, 1, 1, 0, 0};
+
+ char *p = headerBuffer = new char[sizeofHeaderBuffer];
+ memcpy(p, &magic, sizeof(Magic));
+ p += sizeof(Magic);
+ memcpy(p, &header, sizeof(Header));
+ p += sizeof(Header);
+ memcpy(p, &info, sizeof(Info));
+ }
- bmp->write(reinterpret_cast<char*>(&magic), sizeof(magic));
- bmp->write(reinterpret_cast<char*>(&header), sizeof(header));
- bmp->write(reinterpret_cast<char*>(&info), sizeof(info));
+ // 1. write the header
+ bmp->write(headerBuffer, sizeofHeaderBuffer);
+ // 2. write the bitmap data
uint8_t *tmp = vc.convert(data);
uint32_t *tmp32 = (uint32_t*)tmp;
diff --git a/src/base/bitmap.hh b/src/base/bitmap.hh
index 9dfaa87a1..e9ad15473 100644
--- a/src/base/bitmap.hh
+++ b/src/base/bitmap.hh
@@ -36,6 +36,7 @@
*
* Authors: William Wang
* Ali Saidi
+ * Chris Emmons
*/
#ifndef __BASE_BITMAP_HH__
#define __BASE_BITMAP_HH__
@@ -62,6 +63,9 @@ class Bitmap
*/
Bitmap(VideoConvert::Mode mode, uint16_t w, uint16_t h, uint8_t *d);
+ /** Destructor */
+ ~Bitmap();
+
/** Provide the converter with the data that should be output. It will be
* converted into rgb8888 and write out when write() is called.
* @param d the data
@@ -71,7 +75,13 @@ class Bitmap
/** Write the provided data into the fstream provided
* @param bmp stream to write to
*/
- void write(std::ostream *bmp);
+ void write(std::ostream *bmp) const;
+
+ /** Gets a hash over the bitmap for quick comparisons to other bitmaps.
+ * @return hash of the bitmap
+ */
+ uint64_t getHash() const { return vc.getHash(data); }
+
private:
VideoConvert::Mode mode;
@@ -81,6 +91,9 @@ class Bitmap
VideoConvert vc;
+ mutable char *headerBuffer;
+ static const size_t sizeofHeaderBuffer;
+
struct Magic
{
unsigned char magic_number[2];
diff --git a/src/base/compiler.hh b/src/base/compiler.hh
index 3315fb2f7..a95cb791c 100644
--- a/src/base/compiler.hh
+++ b/src/base/compiler.hh
@@ -42,6 +42,7 @@
#define M5_DUMMY_RETURN
#define M5_VAR_USED __attribute__((unused))
#define M5_ATTR_PACKED __attribute__ ((__packed__))
+#define M5_NO_INLINE __attribute__ ((__noinline__))
#elif defined(__SUNPRO_CC)
// this doesn't do anything with sun cc, but why not
#define M5_ATTR_NORETURN __sun_attr__((__noreturn__))
@@ -50,6 +51,7 @@
#define M5_VAR_USED
#define M5_PRAGMA_NORETURN(x) DO_PRAGMA(does_not_return(x))
#define M5_ATTR_PACKED __attribute__ ((__packed__))
+#define M5_NO_INLINE __attribute__ ((__noinline__))
#else
#error "Need to define compiler options in base/compiler.hh"
#endif
diff --git a/src/base/output.cc b/src/base/output.cc
index 020247152..1c749e5bf 100644
--- a/src/base/output.cc
+++ b/src/base/output.cc
@@ -26,11 +26,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Nathan Binkert
+ * Chris Emmons
*/
#include <sys/stat.h>
#include <sys/types.h>
+#include <dirent.h>
+#include <cassert>
#include <cerrno>
#include <climits>
#include <cstdlib>
@@ -46,7 +49,7 @@ using namespace std;
OutputDirectory simout;
/**
- *
+ * @file This file manages creating / deleting output files for the simulator.
*/
OutputDirectory::OutputDirectory()
{}
@@ -73,26 +76,54 @@ OutputDirectory::checkForStdio(const string &name) const
ostream *
OutputDirectory::openFile(const string &filename,
- ios_base::openmode mode) const
+ ios_base::openmode mode)
{
if (filename.find(".gz", filename.length()-3) < filename.length()) {
ogzstream *file = new ogzstream(filename.c_str(), mode);
-
if (!file->is_open())
fatal("Cannot open file %s", filename);
-
+ assert(files.find(filename) == files.end());
+ files[filename] = file;
return file;
} else {
ofstream *file = new ofstream(filename.c_str(), mode);
-
if (!file->is_open())
fatal("Cannot open file %s", filename);
-
+ assert(files.find(filename) == files.end());
+ files[filename] = file;
return file;
}
}
void
+OutputDirectory::close(ostream *openStream) {
+ map_t::iterator i;
+ for (i = files.begin(); i != files.end(); i++) {
+ if (i->second != openStream)
+ continue;
+
+ ofstream *fs = dynamic_cast<ofstream*>(i->second);
+ if (fs) {
+ fs->close();
+ delete i->second;
+ break;
+ } else {
+ ogzstream *gfs = dynamic_cast<ogzstream*>(i->second);
+ if (gfs) {
+ gfs->close();
+ delete i->second;
+ break;
+ }
+ }
+ }
+
+ if (i == files.end())
+ fatal("Attempted to close an unregistred file stream");
+
+ files.erase(i);
+}
+
+void
OutputDirectory::setDirectory(const string &d)
{
if (!dir.empty())
@@ -100,9 +131,9 @@ OutputDirectory::setDirectory(const string &d)
dir = d;
- // guarantee that directory ends with a '/'
- if (dir[dir.size() - 1] != '/')
- dir += "/";
+ // guarantee that directory ends with a path separator
+ if (dir[dir.size() - 1] != PATH_SEPARATOR)
+ dir += PATH_SEPARATOR;
}
const string &
@@ -117,7 +148,7 @@ OutputDirectory::directory() const
inline string
OutputDirectory::resolve(const string &name) const
{
- return (name[0] != '/') ? dir + name : name;
+ return (name[0] != PATH_SEPARATOR) ? dir + name : name;
}
ostream *
@@ -136,20 +167,18 @@ OutputDirectory::create(const string &name, bool binary)
}
ostream *
-OutputDirectory::find(const string &name)
+OutputDirectory::find(const string &name) const
{
ostream *file = checkForStdio(name);
if (file)
return file;
- string filename = resolve(name);
- map_t::iterator i = files.find(filename);
+ const string filename = resolve(name);
+ map_t::const_iterator i = files.find(filename);
if (i != files.end())
return (*i).second;
- file = openFile(filename);
- files[filename] = file;
- return file;
+ return NULL;
}
bool
@@ -157,3 +186,82 @@ OutputDirectory::isFile(const std::ostream *os)
{
return os && os != &cerr && os != &cout;
}
+
+bool
+OutputDirectory::isFile(const string &name) const
+{
+ // definitely a file if in our data structure
+ if (find(name) != NULL) return true;
+
+ struct stat st_buf;
+ int st = stat(name.c_str(), &st_buf);
+ return (st == 0) && S_ISREG(st_buf.st_mode);
+}
+
+string
+OutputDirectory::createSubdirectory(const string &name) const
+{
+ const string new_dir = resolve(name);
+ if (new_dir.find(directory()) == string::npos)
+ fatal("Attempting to create subdirectory not in m5 output dir\n");
+
+ // if it already exists, that's ok; otherwise, fail if we couldn't create
+ if ((mkdir(new_dir.c_str(), 0755) != 0) && (errno != EEXIST))
+ fatal("Failed to create new output subdirectory '%s'\n", new_dir);
+
+ return name + PATH_SEPARATOR;
+}
+
+void
+OutputDirectory::remove(const string &name, bool recursive)
+{
+ const string fname = resolve(name);
+
+ if (fname.find(directory()) == string::npos)
+ fatal("Attempting to remove file/dir not in output dir\n");
+
+ if (isFile(fname)) {
+ // close and release file if we have it open
+ map_t::iterator itr = files.find(fname);
+ if (itr != files.end()) {
+ delete itr->second;
+ files.erase(itr);
+ }
+
+ if (::remove(fname.c_str()) != 0)
+ fatal("Could not erase file '%s'\n", fname);
+ } else {
+ // assume 'name' is a directory
+ if (recursive) {
+ DIR *dir = opendir(fname.c_str());
+
+ // silently ignore removal request for non-existent directory
+ if ((!dir) && (errno == ENOENT))
+ return;
+
+ // fail on other errors
+ if (!dir) {
+ perror("opendir");
+ fatal("Error opening directory for recursive removal '%s'\n",
+ fname);
+ }
+
+ struct dirent *de = readdir(dir);
+ while (de != NULL) {
+ // ignore files starting with a '.'; user must delete those
+ // manually if they really want to
+ if (de->d_name[0] != '.')
+ remove(name + PATH_SEPARATOR + de->d_name, recursive);
+
+ de = readdir(dir);
+ }
+ }
+
+ // try to force recognition that we deleted the files in the directory
+ sync();
+
+ if (::remove(fname.c_str()) != 0) {
+ perror("Warning! 'remove' failed. Could not erase directory.");
+ }
+ }
+}
diff --git a/src/base/output.hh b/src/base/output.hh
index 38c63714c..b86e68856 100644
--- a/src/base/output.hh
+++ b/src/base/output.hh
@@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Nathan Binkert
+ * Chris Emmons
*/
#ifndef __BASE_OUTPUT_HH__
@@ -35,33 +36,147 @@
#include <map>
#include <string>
+/** Interface for creating files in a gem5 output directory. */
class OutputDirectory
{
private:
+ /** File names and associated stream handles */
typedef std::map<std::string, std::ostream *> map_t;
+ /** Open file streams within this directory */
map_t files;
+
+ /** Name of this directory */
std::string dir;
+ /** System-specific path separator character */
+ static const char PATH_SEPARATOR = '/';
+
+ /**
+ * Returns relative file names prepended with name of this directory.
+ * Returns absolute file names unaltered.
+ *
+ * @param name file name to prepend with directory name
+ * @return file name prepended with base directory name or unaltered
+ * absolute file name
+ */
std::string resolve(const std::string &name) const;
protected:
+ /**
+ * Determines whether given file name corresponds to standard output
+ * streams.
+ *
+ * @param name name of file to check
+ * @return output stream for standard output or error stream if name
+ * corresponds to one or the other; NULL otherwise
+ */
std::ostream *checkForStdio(const std::string &name) const;
+
+ /** Opens a file (optionally compressed).
+ *
+ * Will open a file as a compressed stream if filename ends in .gz.
+ *
+ * @param filename file to open
+ * @param mode attributes to open file with
+ * @return stream pointer to opened file; will cause sim fail on error
+ */
std::ostream *openFile(const std::string &filename,
- std::ios_base::openmode mode = std::ios::trunc) const;
+ std::ios_base::openmode mode = std::ios::trunc);
public:
+ /** Constructor. */
OutputDirectory();
+
+ /** Destructor. */
~OutputDirectory();
+ /**
+ * Sets name of this directory.
+ * @param dir name of this directory
+ */
void setDirectory(const std::string &dir);
+
+ /**
+ * Gets name of this directory.
+ * @return name of this directory
+ */
const std::string &directory() const;
+ /**
+ * Creates a file in this directory (optionally compressed).
+ *
+ * Will open a file as a compressed stream if filename ends in .gz.
+ *
+ * @param name name of file to create (without this directory's name
+ * leading it)
+ * @param binary true to create a binary file; false otherwise
+ * @return stream to the opened file
+ */
std::ostream *create(const std::string &name, bool binary = false);
- std::ostream *find(const std::string &name);
+ /**
+ * Closes a file stream.
+ *
+ * Stream must have been opened through this interface, or sim will fail.
+ *
+ * @param openStream open stream to close
+ */
+ void close(std::ostream *openStream);
+
+ /**
+ * Finds stream associated with a file.
+ * @param name of file
+ * @return stream to specified file or NULL if file does not exist
+ */
+ std::ostream *find(const std::string &name) const;
+
+ /**
+ * Returns true if stream is open and not standard output or error.
+ * @param os output stream to evaluate
+ * @return true if os is non-NULL and not cout or cerr
+ */
static bool isFile(const std::ostream *os);
- static inline bool isFile(const std::ostream &os) { return isFile(&os); }
+
+ /**
+ * Determines whether a file name corresponds to a file in this directory.
+ * @param name name of file to evaluate
+ * @return true iff file has been opened in this directory or exists on the
+ * file system within this directory
+ */
+ bool isFile(const std::string &name) const;
+
+ /**
+ * Returns true if stream is open and not standard output or error.
+ * @param os output stream to evaluate
+ * @return true if os is non-NULL and not cout or cerr
+ */
+ static inline bool isFile(const std::ostream &os) {
+ return isFile(&os);
+ }
+
+ /**
+ * Creates a subdirectory within this directory.
+ * @param name name of subdirectory
+ * @return the new subdirectory's name suffixed with a path separator
+ */
+ std::string createSubdirectory(const std::string &name) const;
+
+ /**
+ * Removes a specified file or subdirectory.
+ *
+ * Will cause sim to fail for most errors. However, it will only warn the
+ * user if a directory could not be removed. This is in place to
+ * accommodate slow file systems where file deletions within a subdirectory
+ * may not be recognized quickly enough thereby causing the subsequent call
+ * to remove the directory to fail (seemingly unempty directory).
+ *
+ * @param name name of file or subdirectory to remove; name should not
+ * be prepended with the name of this directory object
+ * @param recursive set to true to attempt to recursively delete a
+ * subdirectory and its contents
+ */
+ void remove(const std::string &name, bool recursive=false);
};
extern OutputDirectory simout;
diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc
index f8471f1a1..683ba7fe4 100644
--- a/src/base/stats/text.cc
+++ b/src/base/stats/text.cc
@@ -674,7 +674,11 @@ initText(const string &filename, bool desc)
static bool connected = false;
if (!connected) {
- text.open(*simout.find(filename));
+ ostream *os = simout.find(filename);
+ if (!os)
+ os = simout.create(filename);
+
+ text.open(*os);
text.descriptions = desc;
connected = true;
}
diff --git a/src/base/trace.cc b/src/base/trace.cc
index 1a035d400..fa55e42a9 100644
--- a/src/base/trace.cc
+++ b/src/base/trace.cc
@@ -64,6 +64,8 @@ void
setOutput(const string &filename)
{
dprintf_stream = simout.find(filename);
+ if (!dprintf_stream)
+ dprintf_stream = simout.create(filename);
}
ObjectMatch ignore;
diff --git a/src/base/vnc/VncServer.py b/src/base/vnc/VncServer.py
index 21eb3ed28..6b746f2e2 100644
--- a/src/base/vnc/VncServer.py
+++ b/src/base/vnc/VncServer.py
@@ -43,3 +43,4 @@ class VncServer(SimObject):
type = 'VncServer'
port = Param.TcpPort(5900, "listen port")
number = Param.Int(0, "vnc client number")
+ frame_capture = Param.Bool(False, "capture changed frames to files")
diff --git a/src/base/vnc/convert.cc b/src/base/vnc/convert.cc
index cd1502ce6..915a99407 100644
--- a/src/base/vnc/convert.cc
+++ b/src/base/vnc/convert.cc
@@ -67,7 +67,7 @@ VideoConvert::~VideoConvert()
}
uint8_t*
-VideoConvert::convert(uint8_t *fb)
+VideoConvert::convert(const uint8_t *fb) const
{
switch (inputMode) {
case bgr565:
@@ -82,7 +82,7 @@ VideoConvert::convert(uint8_t *fb)
}
uint8_t*
-VideoConvert::m565rgb8888(uint8_t *fb, bool bgr)
+VideoConvert::m565rgb8888(const uint8_t *fb, bool bgr) const
{
uint8_t *out = new uint8_t[area() * sizeof(uint32_t)];
uint32_t *out32 = (uint32_t*)out;
@@ -113,7 +113,7 @@ VideoConvert::m565rgb8888(uint8_t *fb, bool bgr)
uint8_t*
-VideoConvert::bgr8888rgb8888(uint8_t *fb)
+VideoConvert::bgr8888rgb8888(const uint8_t *fb) const
{
uint8_t *out = new uint8_t[area() * sizeof(uint32_t)];
uint32_t *out32 = (uint32_t*)out;
@@ -136,4 +136,21 @@ VideoConvert::bgr8888rgb8888(uint8_t *fb)
return out;
}
+/*
+uint64_t
+VideoConvert::getHash(const uint8_t *fb) const
+{
+ const uint8_t *fb_e = fb + area();
+
+ uint64_t hash = 1;
+ while (fb < fb_e - 8) {
+ hash += *((const uint64_t*)fb);
+ fb += 8;
+ }
+
+ while (fb < fb_e) {
+ hash += *(fb++);
+ }
+ return hash;
+}*/
diff --git a/src/base/vnc/convert.hh b/src/base/vnc/convert.hh
index 68a21d677..17df0747b 100644
--- a/src/base/vnc/convert.hh
+++ b/src/base/vnc/convert.hh
@@ -44,6 +44,7 @@
#ifndef __BASE_VNC_CONVERT_HH__
#define __BASE_VNC_CONVERT_HH__
+#include <zlib.h>
#include "base/bitunion.hh"
class VideoConvert
@@ -107,12 +108,21 @@ class VideoConvert
* @param fb the frame buffer to convert
* @return the converted data (user must free)
*/
- uint8_t* convert(uint8_t *fb);
+ uint8_t* convert(const uint8_t *fb) const;
/** Return the number of pixels that this buffer specifies
* @return number of pixels
*/
- int area() { return width * height; }
+ int area() const { return width * height; }
+
+ /**
+ * Returns a hash on the raw data.
+ *
+ * @return hash of the buffer
+ */
+ inline uint64_t getHash(const uint8_t *fb) const {
+ return adler32(0UL, fb, width * height);
+ }
private:
@@ -121,7 +131,7 @@ class VideoConvert
* @param fb the data to convert
* @return converted data
*/
- uint8_t* bgr8888rgb8888(uint8_t *fb);
+ uint8_t* bgr8888rgb8888(const uint8_t *fb) const;
/**
* Convert a bgr565 or rgb565 input to rgb8888.
@@ -129,7 +139,7 @@ class VideoConvert
* @param bgr true if the input data is bgr565
* @return converted data
*/
- uint8_t* m565rgb8888(uint8_t *fb, bool bgr);
+ uint8_t* m565rgb8888(const uint8_t *fb, bool bgr) const;
Mode inputMode;
Mode outputMode;
diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc
index 18e581bfe..b4a783219 100644
--- a/src/base/vnc/vncserver.cc
+++ b/src/base/vnc/vncserver.cc
@@ -43,7 +43,10 @@
*/
#include <sys/ioctl.h>
+#include <sys/stat.h>
#include <sys/termios.h>
+#include <sys/types.h>
+#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
@@ -52,11 +55,14 @@
#include "base/vnc/vncserver.hh"
#include "base/atomicio.hh"
+#include "base/bitmap.hh"
#include "base/misc.hh"
+#include "base/output.hh"
#include "base/socket.hh"
#include "base/trace.hh"
#include "debug/VNC.hh"
#include "sim/byteswap.hh"
+#include "sim/core.hh"
using namespace std;
@@ -98,14 +104,14 @@ VncServer::VncServer(const Params *p)
: SimObject(p), listenEvent(NULL), dataEvent(NULL), number(p->number),
dataFd(-1), _videoWidth(1), _videoHeight(1), clientRfb(0), keyboard(NULL),
mouse(NULL), sendUpdate(false), videoMode(VideoConvert::UnknownMode),
- vc(NULL)
+ vc(NULL), captureEnabled(p->frame_capture), captureCurrentFrame(0),
+ captureLastHash(0), captureBitmap(0)
{
if (p->port)
listen(p->port);
curState = WaitForProtocolVersion;
-
// currently we only support this one pixel format
// unpacked 32bit rgb (rgb888 + 8 bits of nothing/alpha)
// keep it around for telling the client and making
@@ -121,6 +127,14 @@ VncServer::VncServer(const Params *p)
pixelFormat.greenshift = 8;
pixelFormat.blueshift = 0;
+ if (captureEnabled) {
+ // remove existing frame output directory if it exists, then create a
+ // clean empty directory
+ const string FRAME_OUTPUT_SUBDIR = "frames_" + name();
+ simout.remove(FRAME_OUTPUT_SUBDIR, true);
+ captureOutputDirectory = simout.createSubdirectory(
+ FRAME_OUTPUT_SUBDIR);
+ }
DPRINTF(VNC, "Vnc server created at port %d\n", p->port);
}
@@ -686,6 +700,16 @@ VncServer::setFrameBufferParams(VideoConvert::Mode mode, int width, int height)
vc = new VideoConvert(mode, VideoConvert::rgb8888, videoWidth(),
videoHeight());
+ if (captureEnabled) {
+ // create bitmap of the frame with new attributes
+ if (captureBitmap)
+ delete captureBitmap;
+
+ assert(clientRfb);
+ captureBitmap = new Bitmap(videoMode, width, height, clientRfb);
+ assert(captureBitmap);
+ }
+
if (dataFd > 0 && clientRfb && curState == NormalPhase) {
if (supportsResizeEnc)
sendFrameBufferResized();
@@ -702,3 +726,29 @@ VncServerParams::create()
{
return new VncServer(this);
}
+
+void
+VncServer::captureFrameBuffer()
+{
+ assert(captureBitmap);
+
+ // skip identical frames
+ uint64_t new_hash = captureBitmap->getHash();
+ if (captureLastHash == new_hash)
+ return;
+ captureLastHash = new_hash;
+
+ // get the filename for the current frame
+ char frameFilenameBuffer[64];
+ snprintf(frameFilenameBuffer, 64, "fb.%06d.%lld.bmp.gz",
+ captureCurrentFrame, static_cast<long long int>(curTick()));
+ const string frameFilename(frameFilenameBuffer);
+
+ // create the compressed framebuffer file
+ ostream *fb_out = simout.create(captureOutputDirectory + frameFilename,
+ true);
+ captureBitmap->write(fb_out);
+ simout.close(fb_out);
+
+ ++captureCurrentFrame;
+}
diff --git a/src/base/vnc/vncserver.hh b/src/base/vnc/vncserver.hh
index 96dbdedda..33d833f26 100644
--- a/src/base/vnc/vncserver.hh
+++ b/src/base/vnc/vncserver.hh
@@ -48,6 +48,7 @@
#include <iostream>
#include "base/vnc/convert.hh"
+#include "base/bitmap.hh"
#include "base/circlebuf.hh"
#include "base/pollevent.hh"
#include "base/socket.hh"
@@ -55,6 +56,7 @@
#include "params/VncServer.hh"
#include "sim/sim_object.hh"
+
/**
* A device that expects to receive input from the vnc server should derrive
* (through mulitple inheritence if necessary from VncKeyboard or VncMouse
@@ -316,7 +318,25 @@ class VncServer : public SimObject
/** The video converter that transforms data for us */
VideoConvert *vc;
+ /** Flag indicating whether to capture snapshots of frame buffer or not */
+ bool captureEnabled;
+
+ /** Current frame number being captured to a file */
+ int captureCurrentFrame;
+
+ /** Directory to store captured frames to */
+ std::string captureOutputDirectory;
+
+ /** Computed hash of the last captured frame */
+ uint64_t captureLastHash;
+
+ /** Cached bitmap object for writing out frame buffers to file */
+ Bitmap *captureBitmap;
+
protected:
+ /** Captures the current frame buffer to a file */
+ void captureFrameBuffer();
+
/**
* vnc client Interface
*/
@@ -449,6 +469,8 @@ class VncServer : public SimObject
setDirty()
{
sendUpdate = true;
+ if (captureEnabled)
+ captureFrameBuffer();
sendFrameBufferUpdate();
}
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
index b5c203742..50a8501e2 100644
--- a/src/cpu/BaseCPU.py
+++ b/src/cpu/BaseCPU.py
@@ -167,15 +167,16 @@ class BaseCPU(MemObject):
self.icache_port = ic.cpu_side
self.dcache_port = dc.cpu_side
self._cached_ports = ['icache.mem_side', 'dcache.mem_side']
- if buildEnv['TARGET_ISA'] == 'x86' and iwc and dwc:
- self.itb_walker_cache = iwc
- self.dtb_walker_cache = dwc
- self.itb.walker.port = iwc.cpu_side
- self.dtb.walker.port = dwc.cpu_side
- self._cached_ports += ["itb_walker_cache.mem_side", \
- "dtb_walker_cache.mem_side"]
- elif buildEnv['TARGET_ISA'] == 'arm':
- self._cached_ports += ["itb.walker.port", "dtb.walker.port"]
+ if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
+ if iwc and dwc:
+ self.itb_walker_cache = iwc
+ self.dtb_walker_cache = dwc
+ self.itb.walker.port = iwc.cpu_side
+ self.dtb.walker.port = dwc.cpu_side
+ self._cached_ports += ["itb_walker_cache.mem_side", \
+ "dtb_walker_cache.mem_side"]
+ else:
+ self._cached_ports += ["itb.walker.port", "dtb.walker.port"]
def addTwoLevelCacheHierarchy(self, ic, dc, l2c, iwc = None, dwc = None):
self.addPrivateSplitL1Caches(ic, dc, iwc, dwc)
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 6e2de0baf..a0785ac10 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -184,7 +184,11 @@ BaseCPU::BaseCPU(Params *p)
functionTracingEnabled = false;
if (p->function_trace) {
- functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
+ const string fname = csprintf("ftrace.%s", name());
+ functionTraceStream = simout.find(fname);
+ if (!functionTraceStream)
+ functionTraceStream = simout.create(fname);
+
currentFunctionStart = currentFunctionEnd = 0;
functionEntryTick = p->function_trace_start;
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index 51643c169..1d8950a73 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -142,7 +142,3 @@ class DerivO3CPU(BaseCPU):
smtROBThreshold = Param.Int(100, "SMT ROB Threshold Sharing Parameter")
smtCommitPolicy = Param.String('RoundRobin', "SMT Commit Policy")
- def addPrivateSplitL1Caches(self, ic, dc, iwc = None, dwc = None):
- BaseCPU.addPrivateSplitL1Caches(self, ic, dc, iwc, dwc)
- self.icache.tgts_per_mshr = 20
- self.dcache.tgts_per_mshr = 20
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index bb5ccc17e..5d3af6c70 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -438,6 +438,12 @@ FullO3CPU<Impl>::regStats()
"to idling")
.prereq(idleCycles);
+ quiesceCycles
+ .name(name() + ".quiesceCycles")
+ .desc("Total number of cycles that CPU has spent quiesced or waiting "
+ "for an interrupt")
+ .prereq(quiesceCycles);
+
// Number of Instructions simulated
// --------------------------------
// Should probably be in Base CPU but need templated
@@ -682,6 +688,8 @@ FullO3CPU<Impl>::activateContext(ThreadID tid, int delay)
activityRec.activity();
fetch.wakeFromQuiesce();
+ quiesceCycles += tickToCycles((curTick() - 1) - lastRunningCycle);
+
lastActivatedCycle = curTick();
_status = Running;
@@ -716,6 +724,9 @@ FullO3CPU<Impl>::suspendContext(ThreadID tid)
if ((activeThreads.size() == 1 && !deallocated) ||
activeThreads.size() == 0)
unscheduleTickEvent();
+
+ DPRINTF(Quiesce, "Suspending Context\n");
+ lastRunningCycle = curTick();
_status = Idle;
}
@@ -1193,6 +1204,8 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
}
if (!tickEvent.scheduled())
schedule(tickEvent, nextCycle());
+
+ lastRunningCycle = curTick();
}
template <class Impl>
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index b5654dee1..7580106ad 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -713,6 +713,9 @@ class FullO3CPU : public BaseO3CPU
Stats::Scalar timesIdled;
/** Stat for total number of cycles the CPU spends descheduled. */
Stats::Scalar idleCycles;
+ /** Stat for total number of cycles the CPU spends descheduled due to a
+ * quiesce operation or waiting for an interrupt. */
+ Stats::Scalar quiesceCycles;
/** Stat for the number of committed instructions per thread. */
Stats::Vector committedInsts;
/** Stat for the total number of committed instructions. */
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index 62e4a9c37..942b835f0 100644
--- a/src/dev/io_device.cc
+++ b/src/dev/io_device.cc
@@ -115,11 +115,13 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list)
}
-DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff)
+DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff,
+ bool recv_snoops)
: Port(dev->name() + "-dmaport", dev), device(dev), sys(s),
pendingCount(0), actionInProgress(0), drainEvent(NULL),
backoffTime(0), minBackoffDelay(min_backoff),
- maxBackoffDelay(max_backoff), inRetry(false), backoffEvent(this)
+ maxBackoffDelay(max_backoff), inRetry(false), recvSnoops(recv_snoops),
+ snoopRangeSent(false), backoffEvent(this)
{ }
bool
@@ -141,6 +143,12 @@ DmaPort::recvTiming(PacketPtr pkt)
pkt->reinitNacked();
queueDma(pkt, true);
} else if (pkt->senderState) {
+ if (recvSnoops) {
+ if (pkt->isRequest()) {
+ return true;
+ }
+ }
+
DmaReqState *state;
backoffTime >>= 2;
diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh
index a92402bfe..083ab43cb 100644
--- a/src/dev/io_device.hh
+++ b/src/dev/io_device.hh
@@ -129,20 +129,45 @@ class DmaPort : public Port
* it is that it's sending. */
bool inRetry;
+ /** Port accesses a cache which requires snooping */
+ bool recvSnoops;
+
+ /** Records snoop response so we only reply once to a status change */
+ bool snoopRangeSent;
+
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt)
- { panic("dma port shouldn't be used for pio access."); M5_DUMMY_RETURN }
+ {
+ if (recvSnoops) return 0;
+
+ panic("dma port shouldn't be used for pio access."); M5_DUMMY_RETURN
+ }
virtual void recvFunctional(PacketPtr pkt)
- { panic("dma port shouldn't be used for pio access."); }
+ {
+ if (recvSnoops) return;
+
+ panic("dma port shouldn't be used for pio access.");
+ }
virtual void recvStatusChange(Status status)
- { ; }
+ {
+ if (recvSnoops) {
+ if (status == RangeChange) {
+ if (!snoopRangeSent) {
+ snoopRangeSent = true;
+ sendStatusChange(Port::RangeChange);
+ }
+ return;
+ }
+ panic("Unexpected recvStatusChange\n");
+ }
+ }
virtual void recvRetry() ;
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
- { resp.clear(); snoop = false; }
+ { resp.clear(); snoop = recvSnoops; }
void queueDma(PacketPtr pkt, bool front = false);
void sendDma();
@@ -151,7 +176,8 @@ class DmaPort : public Port
EventWrapper<DmaPort, &DmaPort::sendDma> backoffEvent;
public:
- DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff);
+ DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff,
+ bool recv_snoops = false);
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
uint8_t *data, Tick delay, Request::Flags flag = 0);
diff --git a/src/dev/sparc/mm_disk.cc b/src/dev/sparc/mm_disk.cc
index b86905387..1921f6d96 100644
--- a/src/dev/sparc/mm_disk.cc
+++ b/src/dev/sparc/mm_disk.cc
@@ -83,7 +83,7 @@ MmDisk::read(PacketPtr pkt)
break;
case sizeof(uint16_t):
memcpy(&d16, diskData + (accessAddr % SectorSize), 2);
- pkt->set(htobe(d32));
+ pkt->set(htobe(d16));
DPRINTF(IdeDisk, "reading word %#x value= %#x\n", accessAddr, d16);
break;
case sizeof(uint32_t):
diff --git a/src/dev/terminal.cc b/src/dev/terminal.cc
index bae4c9194..74d5ddde7 100644
--- a/src/dev/terminal.cc
+++ b/src/dev/terminal.cc
@@ -102,6 +102,9 @@ Terminal::Terminal(const Params *p)
{
if (p->output) {
outfile = simout.find(p->name);
+ if (!outfile)
+ outfile = simout.create(p->name);
+
outfile->setf(ios::unitbuf);
}
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index e8b978ec8..d5c4e892f 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -556,7 +556,8 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
UNSERIALIZE_SCALAR(_size);
if (size() > params()->range.size())
- fatal("Memory size has changed!\n");
+ fatal("Memory size has changed! size %lld, param size %lld\n",
+ size(), params()->range.size());
pmemAddr = (uint8_t *)mmap(NULL, size(),
PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm
index 9576ba1af..b9d355736 100644
--- a/src/mem/protocol/MOESI_hammer-cache.sm
+++ b/src/mem/protocol/MOESI_hammer-cache.sm
@@ -62,6 +62,13 @@ machine(L1Cache, "AMD Hammer-like protocol")
M, AccessPermission:Read_Only, desc="Modified (dirty)";
MM, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)";
+ // Base states, locked and ready to service the mandatory queue
+ IR, AccessPermission:Invalid, desc="Idle";
+ SR, AccessPermission:Read_Only, desc="Shared";
+ OR, AccessPermission:Read_Only, desc="Owned";
+ MR, AccessPermission:Read_Only, desc="Modified (dirty)";
+ MMR, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)";
+
// Transient States
IM, AccessPermission:Busy, "IM", desc="Issued GetX";
SM, AccessPermission:Read_Only, "SM", desc="Issued GetX, we still have a valid copy of the line";
@@ -1217,6 +1224,11 @@ machine(L1Cache, "AMD Hammer-like protocol")
stall_and_wait(mandatoryQueue_in, address);
}
+ action(z_stall, "z", desc="stall") {
+ // do nothing and the special z_stall action will return a protocol stall
+ // so that the next port is checked
+ }
+
action(kd_wakeUpDependents, "kd", desc="wake-up dependents") {
wakeUpBuffers(address);
}
@@ -1246,7 +1258,7 @@ machine(L1Cache, "AMD Hammer-like protocol")
zz_stallAndWaitMandatoryQueue;
}
- transition({IM, SM, ISM, OM, IS, SS, MM_W, M_W, OI, MI, II, IT, ST, OT, MT, MMT, IM_F, SM_F, ISM_F, OM_F, MM_WF, MI_F, MM_F}, L1_to_L2) {
+ transition({IM, SM, ISM, OM, IS, SS, MM_W, M_W, OI, MI, II, IT, ST, OT, MT, MMT, IM_F, SM_F, ISM_F, OM_F, MM_WF, MI_F, MM_F, IR, SR, OR, MR, MMR}, L1_to_L2) {
zz_stallAndWaitMandatoryQueue;
}
@@ -1259,7 +1271,11 @@ machine(L1Cache, "AMD Hammer-like protocol")
}
transition({IT, ST, OT, MT, MMT}, {Other_GETX, NC_DMA_GETS, Other_GETS, Merged_GETS, Other_GETS_No_Mig, Invalidate, Flush_line}) {
- // stall
+ z_stall;
+ }
+
+ transition({IR, SR, OR, MR, MMR}, {Other_GETX, NC_DMA_GETS, Other_GETS, Merged_GETS, Other_GETS_No_Mig, Invalidate}) {
+ z_stall;
}
// Transitions moving data between the L1 and L2 caches
@@ -1382,33 +1398,33 @@ machine(L1Cache, "AMD Hammer-like protocol")
ll_L2toL1Transfer;
}
- transition(IT, Complete_L2_to_L1, I) {
+ transition(IT, Complete_L2_to_L1, IR) {
j_popTriggerQueue;
kd_wakeUpDependents;
}
- transition(ST, Complete_L2_to_L1, S) {
+ transition(ST, Complete_L2_to_L1, SR) {
j_popTriggerQueue;
kd_wakeUpDependents;
}
- transition(OT, Complete_L2_to_L1, O) {
+ transition(OT, Complete_L2_to_L1, OR) {
j_popTriggerQueue;
kd_wakeUpDependents;
}
- transition(MT, Complete_L2_to_L1, M) {
+ transition(MT, Complete_L2_to_L1, MR) {
j_popTriggerQueue;
kd_wakeUpDependents;
}
- transition(MMT, Complete_L2_to_L1, MM) {
+ transition(MMT, Complete_L2_to_L1, MMR) {
j_popTriggerQueue;
kd_wakeUpDependents;
}
// Transitions from Idle
- transition(I, Load, IS) {
+ transition({I, IR}, Load, IS) {
ii_allocateL1DCacheBlock;
i_allocateTBE;
a_issueGETS;
@@ -1416,7 +1432,7 @@ machine(L1Cache, "AMD Hammer-like protocol")
k_popMandatoryQueue;
}
- transition(I, Ifetch, IS) {
+ transition({I, IR}, Ifetch, IS) {
jj_allocateL1ICacheBlock;
i_allocateTBE;
a_issueGETS;
@@ -1424,7 +1440,7 @@ machine(L1Cache, "AMD Hammer-like protocol")
k_popMandatoryQueue;
}
- transition(I, Store, IM) {
+ transition({I, IR}, Store, IM) {
ii_allocateL1DCacheBlock;
i_allocateTBE;
b_issueGETX;
@@ -1432,7 +1448,7 @@ machine(L1Cache, "AMD Hammer-like protocol")
k_popMandatoryQueue;
}
- transition(I, Flush_line, IM_F) {
+ transition({I, IR}, Flush_line, IM_F) {
it_allocateTBE;
bf_issueGETF;
uu_profileMiss;
@@ -1455,14 +1471,19 @@ machine(L1Cache, "AMD Hammer-like protocol")
k_popMandatoryQueue;
}
- transition(S, Store, SM) {
+ transition(SR, {Load, Ifetch}, S) {
+ h_load_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition({S, SR}, Store, SM) {
i_allocateTBE;
b_issueGETX;
uu_profileMiss;
k_popMandatoryQueue;
}
- transition(S, Flush_line, SM_F) {
+ transition({S, SR}, Flush_line, SM_F) {
i_allocateTBE;
bf_issueGETF;
uu_profileMiss;
@@ -1491,14 +1512,19 @@ machine(L1Cache, "AMD Hammer-like protocol")
k_popMandatoryQueue;
}
- transition(O, Store, OM) {
+ transition(OR, {Load, Ifetch}, O) {
+ h_load_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition({O, OR}, Store, OM) {
i_allocateTBE;
b_issueGETX;
p_decrementNumberOfMessagesByOne;
uu_profileMiss;
k_popMandatoryQueue;
}
- transition(O, Flush_line, OM_F) {
+ transition({O, OR}, Flush_line, OM_F) {
i_allocateTBE;
bf_issueGETF;
p_decrementNumberOfMessagesByOne;
@@ -1530,17 +1556,17 @@ machine(L1Cache, "AMD Hammer-like protocol")
}
// Transitions from Modified
- transition(MM, {Load, Ifetch}) {
+ transition({MM, MMR}, {Load, Ifetch}, MM) {
h_load_hit;
k_popMandatoryQueue;
}
- transition(MM, Store) {
+ transition({MM, MMR}, Store, MM) {
hh_store_hit;
k_popMandatoryQueue;
}
- transition({MM, M}, Flush_line, MM_F) {
+ transition({MM, M, MMR}, Flush_line, MM_F) {
i_allocateTBE;
bf_issueGETF;
p_decrementNumberOfMessagesByOne;
@@ -1587,12 +1613,12 @@ machine(L1Cache, "AMD Hammer-like protocol")
}
// Transitions from Dirty Exclusive
- transition(M, {Load, Ifetch}) {
+ transition({M, MR}, {Load, Ifetch}, M) {
h_load_hit;
k_popMandatoryQueue;
}
- transition(M, Store, MM) {
+ transition({M, MR}, Store, MM) {
hh_store_hit;
k_popMandatoryQueue;
}
diff --git a/src/mem/protocol/Network_test.slicc b/src/mem/protocol/Network_test.slicc
index b122b149c..a065a8535 100644
--- a/src/mem/protocol/Network_test.slicc
+++ b/src/mem/protocol/Network_test.slicc
@@ -3,4 +3,3 @@ include "RubySlicc_interfaces.slicc";
include "Network_test-msg.sm";
include "Network_test-cache.sm";
include "Network_test-dir.sm";
-include "standard_1level_CMP-protocol.sm";
diff --git a/src/mem/ruby/network/topologies/MeshDirCorners.py b/src/mem/ruby/network/topologies/MeshDirCorners.py
index f9d302d19..7be8b9101 100644
--- a/src/mem/ruby/network/topologies/MeshDirCorners.py
+++ b/src/mem/ruby/network/topologies/MeshDirCorners.py
@@ -99,7 +99,7 @@ def makeTopology(nodes, options, IntLink, ExtLink, Router):
# Connect the dma nodes to router 0. These should only be DMA nodes.
for (i, node) in enumerate(dma_nodes):
assert(node.type == 'DMA_Controller')
- ext_links.append(ExtLink(ext_node=node, int_node=mesh.routers[0]))
+ ext_links.append(ExtLink(link_id=link_count, ext_node=node, int_node=mesh.routers[0]))
# Create the mesh links. First row (east-west) links then column
# (north-south) links
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 468f42955..c400b72ee 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -350,8 +350,6 @@ Process::fixupStackFault(Addr vaddr)
};
return true;
}
- warn("Not extending stack: address %#x isn't at the end of the stack.",
- vaddr);
return false;
}