summaryrefslogtreecommitdiff
path: root/src/mem/ruby/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/ruby/common')
-rw-r--r--src/mem/ruby/common/Address.cc68
-rw-r--r--src/mem/ruby/common/Address.hh255
-rw-r--r--src/mem/ruby/common/Consumer.hh89
-rw-r--r--src/mem/ruby/common/DataBlock.cc91
-rw-r--r--src/mem/ruby/common/DataBlock.hh82
-rw-r--r--src/mem/ruby/common/Debug.cc380
-rw-r--r--src/mem/ruby/common/Debug.hh306
-rw-r--r--src/mem/ruby/common/Driver.cc39
-rw-r--r--src/mem/ruby/common/Driver.hh80
-rw-r--r--src/mem/ruby/common/Global.cc35
-rw-r--r--src/mem/ruby/common/Global.hh110
-rw-r--r--src/mem/ruby/common/Histogram.cc185
-rw-r--r--src/mem/ruby/common/Histogram.hh104
-rw-r--r--src/mem/ruby/common/Message.cc34
-rw-r--r--src/mem/ruby/common/NetDest.cc259
-rw-r--r--src/mem/ruby/common/NetDest.hh145
-rw-r--r--src/mem/ruby/common/SConscript45
-rw-r--r--src/mem/ruby/common/Set.cc576
-rw-r--r--src/mem/ruby/common/Set.hh202
-rw-r--r--src/mem/ruby/common/SubBlock.cc81
-rw-r--r--src/mem/ruby/common/SubBlock.hh105
21 files changed, 3271 insertions, 0 deletions
diff --git a/src/mem/ruby/common/Address.cc b/src/mem/ruby/common/Address.cc
new file mode 100644
index 000000000..b4ad39294
--- /dev/null
+++ b/src/mem/ruby/common/Address.cc
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "mem/ruby/common/Address.hh"
+
+void Address::output(ostream& out) const
+{
+ // Note: this outputs addresses in the form "ffff", not "0xffff".
+ // This code should always be able to write out addresses in a
+ // format that can be read in by the below input() method. Please
+ // don't change this without talking to Milo first.
+ out << hex << m_address << dec;
+}
+
+void Address::input(istream& in)
+{
+ // Note: this only works with addresses in the form "ffff", not
+ // "0xffff". This code should always be able to read in addresses
+ // written out by the above output() method. Please don't change
+ // this without talking to Milo first.
+ in >> hex >> m_address >> dec;
+}
+
+Address::Address(const Address& obj)
+{
+ m_address = obj.m_address;
+}
+
+Address& Address::operator=(const Address& obj)
+{
+ if (this == &obj) {
+ // assert(false);
+ } else {
+ m_address = obj.m_address;
+ }
+ return *this;
+}
+
diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh
new file mode 100644
index 000000000..da218f177
--- /dev/null
+++ b/src/mem/ruby/common/Address.hh
@@ -0,0 +1,255 @@
+
+/*
+ * Copyright (c) 1999 by Mark Hill and David Wood for the Wisconsin
+ * Multifacet Project. ALL RIGHTS RESERVED.
+ *
+ * ##HEADER##
+ *
+ * This software is furnished under a license and may be used and
+ * copied only in accordance with the terms of such license and the
+ * inclusion of the above copyright notice. This software or any
+ * other copies thereof or any derivative works may not be provided or
+ * otherwise made available to any other persons. Title to and
+ * ownership of the software is retained by Mark Hill and David Wood.
+ * Any use of this software must include the above copyright notice.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". THE LICENSOR MAKES NO
+ * WARRANTIES ABOUT ITS CORRECTNESS OR PERFORMANCE.
+ * */
+
+/*
+ * $Id$
+ */
+
+#ifndef ADDRESS_H
+#define ADDRESS_H
+
+#include <iomanip>
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/config/RubyConfig.hh"
+#include "mem/ruby/system/NodeID.hh"
+#include "mem/ruby/system/MachineID.hh"
+
+const int ADDRESS_WIDTH = 64; // address width in bytes
+
+class Address;
+typedef Address PhysAddress;
+typedef Address VirtAddress;
+
+class Address {
+public:
+ // Constructors
+ Address() { m_address = 0; }
+ explicit Address(physical_address_t address) { m_address = address; }
+
+ Address(const Address& obj);
+ Address& operator=(const Address& obj);
+
+ // Destructor
+ // ~Address();
+
+ // Public Methods
+
+ void setAddress(physical_address_t address) { m_address = address; }
+ physical_address_t getAddress() const {return m_address;}
+ // selects bits inclusive
+ physical_address_t bitSelect(int small, int big) const;
+ physical_address_t maskLowOrderBits(int number) const;
+ physical_address_t maskHighOrderBits(int number) const;
+ physical_address_t shiftLowOrderBits(int number) const;
+ physical_address_t getLineAddress() const
+ { return bitSelect(RubyConfig::dataBlockBits(), ADDRESS_WIDTH); }
+ physical_address_t getOffset() const
+ { return bitSelect(0, RubyConfig::dataBlockBits()-1); }
+
+ void makeLineAddress() { m_address = maskLowOrderBits(RubyConfig::dataBlockBits()); }
+ // returns the next stride address based on line address
+ void makeNextStrideAddress( int stride) {
+ m_address = maskLowOrderBits(RubyConfig::dataBlockBits())
+ + RubyConfig::dataBlockBytes()*stride;
+ }
+ void makePageAddress() { m_address = maskLowOrderBits(RubyConfig::pageSizeBits()); }
+ int getBankSetNum() const;
+ int getBankSetDist() const;
+
+ Index memoryModuleIndex() const;
+
+ void print(ostream& out) const;
+ void output(ostream& out) const;
+ void input(istream& in);
+
+ void setOffset( int offset ){
+ // first, zero out the offset bits
+ makeLineAddress();
+ m_address |= (physical_address_t) offset;
+ }
+
+private:
+ // Private Methods
+
+ // Private copy constructor and assignment operator
+ // Address(const Address& obj);
+ // Address& operator=(const Address& obj);
+
+ // Data Members (m_ prefix)
+ physical_address_t m_address;
+};
+
+inline
+Address line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; }
+
+inline
+Address next_stride_address(const Address& addr, int stride) {
+ Address temp = addr;
+ temp.makeNextStrideAddress(stride);
+ temp.setAddress(temp.maskHighOrderBits(ADDRESS_WIDTH-RubyConfig::memorySizeBits())); // surpress wrap-around problem
+ return temp;
+}
+
+inline
+Address page_address(const Address& addr) { Address temp(addr); temp.makePageAddress(); return temp; }
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Address& obj);
+// comparison operator declaration
+bool operator==(const Address& obj1, const Address& obj2);
+bool operator!=(const Address& obj1, const Address& obj2);
+bool operator<(const Address& obj1, const Address& obj2);
+/* Address& operator=(const physical_address_t address); */
+
+inline
+bool operator<(const Address& obj1, const Address& obj2)
+{
+ return obj1.getAddress() < obj2.getAddress();
+}
+
+// ******************* Definitions *******************
+
+// Output operator definition
+inline
+ostream& operator<<(ostream& out, const Address& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+inline
+bool operator==(const Address& obj1, const Address& obj2)
+{
+ return (obj1.getAddress() == obj2.getAddress());
+}
+
+inline
+bool operator!=(const Address& obj1, const Address& obj2)
+{
+ return (obj1.getAddress() != obj2.getAddress());
+}
+
+inline
+physical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive
+{
+ physical_address_t mask;
+ assert(big >= small);
+
+ if (big >= ADDRESS_WIDTH - 1) {
+ return (m_address >> small);
+ } else {
+ mask = ~((physical_address_t)~0 << (big + 1));
+ // FIXME - this is slow to manipulate a 64-bit number using 32-bits
+ physical_address_t partial = (m_address & mask);
+ return (partial >> small);
+ }
+}
+
+inline
+physical_address_t Address::maskLowOrderBits(int number) const
+{
+ physical_address_t mask;
+
+ if (number >= ADDRESS_WIDTH - 1) {
+ mask = ~0;
+ } else {
+ mask = (physical_address_t)~0 << number;
+ }
+ return (m_address & mask);
+}
+
+inline
+physical_address_t Address::maskHighOrderBits(int number) const
+{
+ physical_address_t mask;
+
+ if (number >= ADDRESS_WIDTH - 1) {
+ mask = ~0;
+ } else {
+ mask = (physical_address_t)~0 >> number;
+ }
+ return (m_address & mask);
+}
+
+inline
+physical_address_t Address::shiftLowOrderBits(int number) const
+{
+ return (m_address >> number);
+}
+
+inline
+integer_t Address::memoryModuleIndex() const
+{
+ integer_t index = bitSelect(RubyConfig::dataBlockBits()+RubyConfig::memoryBits(), ADDRESS_WIDTH);
+ assert (index >= 0);
+ if (index >= RubyConfig::memoryModuleBlocks()) {
+ cerr << " memoryBits: " << RubyConfig::memoryBits() << " memorySizeBits: " << RubyConfig::memorySizeBits()
+ << " Address: " << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush
+ << "error: limit exceeded. " <<
+ " dataBlockBits: " << RubyConfig::dataBlockBits() <<
+ " memoryModuleBlocks: " << RubyConfig::memoryModuleBlocks() <<
+ " index: " << index << endl;
+ }
+ assert (index < RubyConfig::memoryModuleBlocks());
+ return index;
+
+ // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS);
+ // Index indexLowPortion = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1);
+
+ //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS));
+
+ /*
+ Round-robin mapping of addresses, at page size granularity
+
+ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS
+ | | | |
+ \ / \ / \ / \ / 0
+ -----------------------------------------------------------------------
+ | unused |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| |
+ | |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| |
+ -----------------------------------------------------------------------
+ indexHighPortion indexLowPortion
+ <------->
+ NUMBER_OF_MEMORY_MODULE_BITS
+ */
+}
+
+inline
+void Address::print(ostream& out) const
+{
+ out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush;
+}
+
+class Address;
+namespace __gnu_cxx {
+ template <> struct hash<Address>
+ {
+ size_t operator()(const Address &s) const { return (size_t) s.getAddress(); }
+ };
+}
+namespace std {
+ template <> struct equal_to<Address>
+ {
+ bool operator()(const Address& s1, const Address& s2) const { return s1 == s2; }
+ };
+}
+
+#endif //ADDRESS_H
+
diff --git a/src/mem/ruby/common/Consumer.hh b/src/mem/ruby/common/Consumer.hh
new file mode 100644
index 000000000..34cd7864c
--- /dev/null
+++ b/src/mem/ruby/common/Consumer.hh
@@ -0,0 +1,89 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: This is the virtual base class of all classes that can
+ * be the targets of wakeup events. There is only two methods,
+ * wakeup() and print() and no data members.
+ *
+ */
+
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/eventqueue/RubyEventQueue.hh"
+
+class MessageBuffer;
+
+class Consumer {
+public:
+ // Constructors
+ Consumer() { m_last_scheduled_wakeup = 0; m_last_wakeup = 0; m_out_link_vec.setSize(0); }
+
+ // Destructor
+ virtual ~Consumer() { }
+
+ // Public Methods - pure virtual methods
+ void triggerWakeup() { Time time = g_eventQueue_ptr->getTime(); if (m_last_wakeup != time) { wakeup(); m_last_wakeup = time; }}
+ virtual void wakeup() = 0;
+ virtual void print(ostream& out) const = 0;
+ const Time& getLastScheduledWakeup() const { return m_last_scheduled_wakeup; }
+ void setLastScheduledWakeup(const Time& time) { m_last_scheduled_wakeup = time; }
+ Vector< Vector<MessageBuffer*> > getOutBuffers() { return m_out_link_vec; }
+
+protected:
+ Vector< Vector<MessageBuffer*> > m_out_link_vec;
+
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ Time m_last_scheduled_wakeup;
+ Time m_last_wakeup;
+};
+
+// Output operator declaration
+inline extern
+ostream& operator<<(ostream& out, const Consumer& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+inline extern
+ostream& operator<<(ostream& out, const Consumer& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //CONSUMER_H
diff --git a/src/mem/ruby/common/DataBlock.cc b/src/mem/ruby/common/DataBlock.cc
new file mode 100644
index 000000000..ce72bc7f4
--- /dev/null
+++ b/src/mem/ruby/common/DataBlock.cc
@@ -0,0 +1,91 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "mem/ruby/common/DataBlock.hh"
+
+DataBlock::DataBlock()
+{
+ if (DATA_BLOCK || XACT_MEMORY) {
+ m_data.setSize(RubyConfig::dataBlockBytes());
+ }
+ clear();
+}
+
+DataBlock::~DataBlock()
+{
+
+}
+
+void DataBlock::clear()
+{
+ int size = m_data.size();
+ for (int i = 0; i < size; i++) {
+ m_data[i] = 0;
+ }
+}
+
+bool DataBlock::equal(const DataBlock& obj) const
+{
+ bool value = true;
+ int size = m_data.size();
+ for (int i = 0; i < size; i++) {
+ value = value && (m_data[i] == obj.m_data[i]);
+ }
+ return value;
+}
+
+void DataBlock::print(ostream& out) const
+{
+ int size = m_data.size();
+ for (int i = 0; i < size; i+=4) {
+ out << hex << *((uint32*)(&(m_data[i]))) << " ";
+ }
+ out << dec << "]" << flush;
+}
+
+uint8 DataBlock::getByte(int whichByte) const
+{
+ if (DATA_BLOCK || XACT_MEMORY) {
+ return m_data[whichByte];
+ } else {
+ return 0;
+ }
+}
+
+void DataBlock::setByte(int whichByte, uint8 data)
+{
+ if (DATA_BLOCK || XACT_MEMORY) {
+ m_data[whichByte] = data;
+ }
+}
+
diff --git a/src/mem/ruby/common/DataBlock.hh b/src/mem/ruby/common/DataBlock.hh
new file mode 100644
index 000000000..8711cb740
--- /dev/null
+++ b/src/mem/ruby/common/DataBlock.hh
@@ -0,0 +1,82 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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 DATABLOCK_H
+#define DATABLOCK_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/config/RubyConfig.hh"
+#include "mem/gems_common/Vector.hh"
+
+class DataBlock {
+public:
+ // Constructors
+ DataBlock();
+
+ // Destructor
+ ~DataBlock();
+
+ // Public Methods
+ void clear();
+ uint8 getByte(int whichByte) const;
+ void setByte(int whichByte, uint8 data);
+ bool equal(const DataBlock& obj) const;
+ void print(ostream& out) const;
+
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ Vector<uint8> m_data;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const DataBlock& obj);
+
+bool operator==(const DataBlock& obj1, const DataBlock& obj2);
+
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const DataBlock& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+extern inline
+bool operator==(const DataBlock& obj1,const DataBlock& obj2)
+{
+ return (obj1.equal(obj2));
+}
+
+#endif //DATABLOCK_H
diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc
new file mode 100644
index 000000000..02f4069ee
--- /dev/null
+++ b/src/mem/ruby/common/Debug.cc
@@ -0,0 +1,380 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ */
+
+#include <fstream>
+#include <stdarg.h>
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/Debug.hh"
+#include "mem/ruby/eventqueue/RubyEventQueue.hh"
+
+class Debug;
+extern Debug* g_debug_ptr;
+std::ostream * debug_cout_ptr;
+
+struct DebugComponentData
+{
+ const char *desc;
+ const char ch;
+};
+
+// component character list
+DebugComponentData debugComponents[] =
+{
+ {"System", 's' },
+ {"Node", 'N' },
+ {"Queue", 'q' },
+ {"Event Queue", 'e' },
+ {"Network", 'n' },
+ {"Sequencer", 'S' },
+ {"Tester", 't' },
+ {"Generated", 'g' },
+ {"SLICC", 'l' },
+ {"Network Queues", 'Q' },
+ {"Time", 'T' },
+ {"Network Internals", 'i' },
+ {"Store Buffer", 'b' },
+ {"Cache", 'c' },
+ {"Predictor", 'p' },
+ {"Allocator", 'a' },
+};
+
+extern "C" void changeDebugVerbosity(VerbosityLevel vb);
+extern "C" void changeDebugFilter(int filter);
+
+void changeDebugVerbosity(VerbosityLevel vb)
+{
+ g_debug_ptr->setVerbosity(vb);
+}
+
+void changeDebugFilter(int filter)
+{
+ g_debug_ptr->setFilter(filter);
+}
+
+Debug::Debug( const char *filterString, const char *verboseString,
+ Time filterStartTime, const char *filename )
+{
+ m_verbosityLevel = No_Verb;
+ clearFilter();
+ debug_cout_ptr = &cout;
+
+ m_starting_cycle = filterStartTime;
+ setFilterString( filterString );
+ setVerbosityString( verboseString );
+ setDebugOutputFile( filename );
+}
+
+Debug::~Debug()
+{
+}
+
+void Debug::printVerbosity(ostream& out) const
+{
+ switch (getVerbosity()) {
+ case No_Verb:
+ out << "verbosity = No_Verb" << endl;
+ break;
+ case Low_Verb:
+ out << "verbosity = Low_Verb" << endl;
+ break;
+ case Med_Verb:
+ out << "verbosity = Med_Verb" << endl;
+ break;
+ case High_Verb:
+ out << "verbosity = High_Verb" << endl;
+ break;
+ default:
+ out << "verbosity = unknown" << endl;
+ }
+}
+
+bool Debug::validDebug(int module, PriorityLevel priority)
+{
+ int local_module = (1 << module);
+ if(m_filter & local_module) {
+ if (g_eventQueue_ptr == NULL ||
+ g_eventQueue_ptr->getTime() >= m_starting_cycle) {
+ switch(m_verbosityLevel) {
+ case No_Verb:
+ return false;
+ break;
+ case Low_Verb:
+ if(priority == HighPrio) {
+ return true;
+ }else{
+ return false;
+ }
+ break;
+ case Med_Verb:
+ if(priority == HighPrio || priority == MedPrio ) {
+ return true;
+ }else{
+ return false;
+ }
+ break;
+ case High_Verb:
+ return true;
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+void Debug::setDebugTime(Time t)
+{
+ m_starting_cycle = t;
+}
+
+void Debug::setVerbosity(VerbosityLevel vb)
+{
+ m_verbosityLevel = vb;
+}
+
+void Debug::setFilter(int filter)
+{
+ m_filter = filter;
+}
+
+bool Debug::checkVerbosityString(const char *verb_str)
+{
+ if (verb_str == NULL) {
+ cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl;
+ return true; // error
+ } else if ( (string(verb_str) == "none") ||
+ (string(verb_str) == "low") ||
+ (string(verb_str) == "med") ||
+ (string(verb_str) == "high") ) {
+ return false;
+ }
+ cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl;
+ return true; // error
+}
+
+bool Debug::setVerbosityString(const char *verb_str)
+{
+ bool check_fails = checkVerbosityString(verb_str);
+ if (check_fails) {
+ return true; // error
+ }
+ if (string(verb_str) == "none") {
+ setVerbosity(No_Verb);
+ } else if (string(verb_str) == "low") {
+ setVerbosity(Low_Verb);
+ } else if (string(verb_str) == "med") {
+ setVerbosity(Med_Verb);
+ } else if (string(verb_str) == "high") {
+ setVerbosity(High_Verb);
+ } else {
+ cerr << "Error: unrecognized verbosity (use none, low, med, high): " << verb_str << endl;
+ return true; // error
+ }
+ return false; // no error
+}
+
+bool Debug::checkFilter(char ch)
+{
+ for (int i=0; i<NUMBER_OF_COMPS; i++) {
+ // Look at all components to find a character match
+ if (debugComponents[i].ch == ch) {
+ // We found a match - return no error
+ return false; // no error
+ }
+ }
+ return true; // error
+}
+
+bool Debug::checkFilterString(const char *filter_str)
+{
+ if (filter_str == NULL) {
+ cerr << "Error: unrecognized component filter: NULL" << endl;
+ return true; // error
+ }
+
+ // check for default filter ("none") before reporting RUBY_DEBUG error
+ if ( (string(filter_str) == "none") ) {
+ return false; // no error
+ }
+
+ if (RUBY_DEBUG == false) {
+ cerr << "Error: User specified set of debug components, but the RUBY_DEBUG compile-time flag is false." << endl;
+ cerr << "Solution: Re-compile with RUBY_DEBUG set to true." << endl;
+ return true; // error
+ }
+
+ if ( (string(filter_str) == "all") ) {
+ return false; // no error
+ }
+
+ // scan string checking each character
+ for (unsigned int i = 0; i < strlen(filter_str); i++) {
+ bool unrecognized = checkFilter( filter_str[i] );
+ if (unrecognized == true) {
+ return true; // error
+ }
+ }
+ return false; // no error
+}
+
+bool Debug::setFilterString(const char *filter_str)
+{
+ if (checkFilterString(filter_str)) {
+ return true; // error
+ }
+
+ if (string(filter_str) == "all" ) {
+ allFilter();
+ } else if (string(filter_str) == "none") {
+ clearFilter();
+ } else {
+ // scan string adding to bit mask for each component which is present
+ for (unsigned int i = 0; i < strlen(filter_str); i++) {
+ bool error = addFilter( filter_str[i] );
+ if (error) {
+ return true; // error
+ }
+ }
+ }
+ return false; // no error
+}
+
+bool Debug::addFilter(char ch)
+{
+ for (int i=0; i<NUMBER_OF_COMPS; i++) {
+ // Look at all components to find a character match
+ if (debugComponents[i].ch == ch) {
+ // We found a match - update the filter bit mask
+ cout << " Debug: Adding to filter: '" << ch << "' (" << debugComponents[i].desc << ")" << endl;
+ m_filter |= (1 << i);
+ return false; // no error
+ }
+ }
+
+ // We didn't find the character
+ cerr << "Error: unrecognized component filter: " << ch << endl;
+ usageInstructions();
+ return true; // error
+}
+
+void Debug::clearFilter()
+{
+ m_filter = 0;
+}
+
+void Debug::allFilter()
+{
+ m_filter = ~0;
+}
+
+void Debug::usageInstructions(void)
+{
+ cerr << "Debug components: " << endl;
+ for (int i=0; i<NUMBER_OF_COMPS; i++) {
+ cerr << " " << debugComponents[i].ch << ": " << debugComponents[i].desc << endl;
+ }
+}
+
+void Debug::print(ostream& out) const
+{
+ out << "[Debug]" << endl;
+}
+
+void Debug::setDebugOutputFile (const char * filename)
+{
+ if ( (filename == NULL) ||
+ (!strcmp(filename, "none")) ) {
+ debug_cout_ptr = &cout;
+ return;
+ }
+
+ if (m_fout.is_open() ) {
+ m_fout.close ();
+ }
+ m_fout.open (filename, std::ios::out);
+ if (! m_fout.is_open() ) {
+ cerr << "setDebugOutputFile: can't open file " << filename << endl;
+ }
+ else {
+ debug_cout_ptr = &m_fout;
+ }
+}
+
+void Debug::closeDebugOutputFile ()
+{
+ if (m_fout.is_open() ) {
+ m_fout.close ();
+ debug_cout_ptr = &cout;
+ }
+}
+
+void Debug::debugMsg( const char *fmt, ... )
+{
+ va_list args;
+
+ // you could check validDebug() here before printing the message
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+}
+
+/*
+void DEBUG_OUT( const char* fmt, ...) {
+ if (RUBY_DEBUG) {
+ cout << "Debug: in fn "
+ << __PRETTY_FUNCTION__
+ << " in " << __FILE__ << ":"
+ << __LINE__ << ": ";
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+ }
+}
+
+void ERROR_OUT( const char* fmt, ... ) {
+ if (ERROR_MESSAGE_FLAG) {
+ cout << "error: in fn "
+ << __PRETTY_FUNCTION__ << " in "
+ << __FILE__ << ":"
+ << __LINE__ << ": ";
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+ }
+ assert(0);
+}
+*/
+
diff --git a/src/mem/ruby/common/Debug.hh b/src/mem/ruby/common/Debug.hh
new file mode 100644
index 000000000..8548e9772
--- /dev/null
+++ b/src/mem/ruby/common/Debug.hh
@@ -0,0 +1,306 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <unistd.h>
+#include <iostream>
+
+#include "config/ruby_debug.hh"
+
+extern std::ostream * debug_cout_ptr;
+
+// component enumeration
+enum DebugComponents
+{
+ SYSTEM_COMP,
+ NODE_COMP,
+ QUEUE_COMP,
+ EVENTQUEUE_COMP,
+ NETWORK_COMP,
+ SEQUENCER_COMP,
+ TESTER_COMP,
+ GENERATED_COMP,
+ SLICC_COMP,
+ NETWORKQUEUE_COMP,
+ TIME_COMP,
+ NETWORK_INTERNALS_COMP,
+ STOREBUFFER_COMP,
+ CACHE_COMP,
+ PREDICTOR_COMP,
+ ALLOCATOR_COMP,
+ NUMBER_OF_COMPS
+};
+
+enum PriorityLevel {HighPrio, MedPrio, LowPrio};
+enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb};
+
+class Debug {
+public:
+ // Constructors
+ Debug( const char *filterString, const char *verboseString,
+ Time filterStartTime, const char *filename );
+
+ // Destructor
+ ~Debug();
+
+ // Public Methods
+ bool validDebug(int module, PriorityLevel priority);
+ void printVerbosity(ostream& out) const;
+ void setVerbosity(VerbosityLevel vb);
+ static bool checkVerbosityString(const char *verb_str);
+ bool setVerbosityString(const char *);
+ VerbosityLevel getVerbosity() const { return m_verbosityLevel; }
+ void setFilter(int);
+ static bool checkFilter( char);
+ static bool checkFilterString(const char *);
+ bool setFilterString(const char *);
+ void setDebugTime(Time);
+ Time getDebugTime() const { return m_starting_cycle; }
+ bool addFilter(char);
+ void clearFilter();
+ void allFilter();
+ void print(ostream& out) const;
+ /* old school debugging "vararg": sends messages to screen and log */
+ void debugMsg( const char *fmt, ... );
+
+ void setDebugOutputFile (const char * filename);
+ void closeDebugOutputFile ();
+ static void usageInstructions(void);
+
+private:
+ // Private Methods
+
+ // Private copy constructor and assignment operator
+ Debug(const Debug& obj);
+ Debug& operator=(const Debug& obj);
+
+ // Data Members (m_ prefix)
+ VerbosityLevel m_verbosityLevel;
+ int m_filter;
+ Time m_starting_cycle;
+
+ std::fstream m_fout;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Debug& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Debug& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+const bool ERROR_MESSAGE_FLAG = true;
+const bool WARNING_MESSAGE_FLAG = true;
+
+#ifdef RUBY_NO_ASSERT
+const bool ASSERT_FLAG = false;
+#else
+const bool ASSERT_FLAG = true;
+#endif
+
+#undef assert
+#define assert(EXPR) ASSERT(EXPR)
+#undef ASSERT
+#define ASSERT(EXPR)\
+{\
+ if (ASSERT_FLAG) {\
+ if (!(EXPR)) {\
+ cerr << "failed assertion '"\
+ << #EXPR << "' at fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << endl << flush;\
+ (* debug_cout_ptr) << "failed assertion '"\
+ << #EXPR << "' at fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << endl << flush;\
+ if(isatty(STDERR_FILENO)) {\
+ cerr << "At this point you might want to attach a debug to ";\
+ cerr << "the running and get to the" << endl;\
+ cerr << "crash site; otherwise press enter to continue" << endl;\
+ cerr << "PID: " << getpid();\
+ cerr << endl << flush; \
+ char c; \
+ cin.get(c); \
+ }\
+ abort();\
+ }\
+ }\
+}
+
+#define BREAK(X)\
+{\
+ cerr << "breakpoint '"\
+ << #X << "' reached at fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << endl << flush;\
+ if(isatty(STDERR_FILENO)) {\
+ cerr << "press enter to continue" << endl;\
+ cerr << "PID: " << getpid();\
+ cerr << endl << flush; \
+ char c; \
+ cin.get(c); \
+ }\
+}
+
+#define ERROR_MSG(MESSAGE)\
+{\
+ if (ERROR_MESSAGE_FLAG) {\
+ cerr << "Fatal Error: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ (* debug_cout_ptr) << "Fatal Error: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ abort();\
+ }\
+}
+
+#define WARN_MSG(MESSAGE)\
+{\
+ if (WARNING_MESSAGE_FLAG) {\
+ cerr << "Warning: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ (* debug_cout_ptr) << "Warning: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ }\
+}
+
+#define WARN_EXPR(EXPR)\
+{\
+ if (WARNING_MESSAGE_FLAG) {\
+ cerr << "Warning: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << #EXPR << " is "\
+ << (EXPR) << endl << flush;\
+ (* debug_cout_ptr) << "Warning: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << #EXPR << " is "\
+ << (EXPR) << endl << flush;\
+ }\
+}
+
+#define DEBUG_MSG(module, priority, MESSAGE)\
+{\
+ if (RUBY_DEBUG) {\
+ if (g_debug_ptr->validDebug(module, priority)) {\
+ (* debug_cout_ptr) << "Debug: in fn "\
+ << __PRETTY_FUNCTION__\
+ << " in " << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ }\
+ }\
+}
+
+#define DEBUG_EXPR(module, priority, EXPR)\
+{\
+ if (RUBY_DEBUG) {\
+ if (g_debug_ptr->validDebug(module, priority)) {\
+ (* debug_cout_ptr) << "Debug: in fn "\
+ << __PRETTY_FUNCTION__\
+ << " in " << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << #EXPR << " is "\
+ << (EXPR) << endl << flush;\
+ }\
+ }\
+}
+
+#define DEBUG_NEWLINE(module, priority)\
+{\
+ if (RUBY_DEBUG) {\
+ if (g_debug_ptr->validDebug(module, priority)) {\
+ (* debug_cout_ptr) << endl << flush;\
+ }\
+ }\
+}
+
+#define DEBUG_SLICC(priority, LINE, MESSAGE)\
+{\
+ if (RUBY_DEBUG) {\
+ if (g_debug_ptr->validDebug(SLICC_COMP, priority)) {\
+ (* debug_cout_ptr) << (LINE) << (MESSAGE) << endl << flush;\
+ }\
+ }\
+}
+
+#define DEBUG_OUT( rest... ) \
+{\
+ if (RUBY_DEBUG) {\
+ cout << "Debug: in fn "\
+ << __PRETTY_FUNCTION__\
+ << " in " << __FILE__ << ":"\
+ << __LINE__ << ": "; \
+ g_debug_ptr->debugMsg(rest); \
+ }\
+}
+
+#define ERROR_OUT( rest... ) \
+{\
+ if (ERROR_MESSAGE_FLAG) {\
+ cout << "error: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": ";\
+ g_debug_ptr->debugMsg(rest); \
+ }\
+}
+
+#endif //DEBUG_H
+
diff --git a/src/mem/ruby/common/Driver.cc b/src/mem/ruby/common/Driver.cc
new file mode 100644
index 000000000..2d6034b02
--- /dev/null
+++ b/src/mem/ruby/common/Driver.cc
@@ -0,0 +1,39 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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/ruby/common/Driver.hh"
+
+Driver::Driver()
+{
+}
+
+// still need to be defined for subclasses
+Driver::~Driver()
+{
+}
diff --git a/src/mem/ruby/common/Driver.hh b/src/mem/ruby/common/Driver.hh
new file mode 100644
index 000000000..38bdbbf91
--- /dev/null
+++ b/src/mem/ruby/common/Driver.hh
@@ -0,0 +1,80 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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 DRIVER_H
+#define DRIVER_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/Consumer.hh"
+#include "mem/ruby/system/NodeID.hh"
+#include "mem/protocol/CacheRequestType.hh"
+#include "mem/packet.hh"
+
+class RubySystem;
+class SubBlock;
+class Address;
+class MachineID;
+class SimicsHypervisor;
+
+class Driver {
+public:
+ // Constructors
+ Driver();
+
+ // Destructor
+ virtual ~Driver() = 0;
+
+ // Public Methods
+ virtual void get_network_config() {}
+ virtual void hitCallback(Packet* pkt) = 0;
+ virtual integer_t getInstructionCount(int procID) const { return 1; }
+ virtual integer_t getCycleCount(int procID) const { return 1; }
+
+ virtual void printDebug(){} //called by Sequencer
+
+ virtual void printStats(ostream& out) const = 0;
+ virtual void clearStats() = 0;
+
+ virtual void printConfig(ostream& out) const = 0;
+
+ virtual integer_t readPhysicalMemory(int procID, physical_address_t address,
+ int len ){ ASSERT(0); return 0; }
+
+ virtual void writePhysicalMemory( int procID, physical_address_t address,
+ integer_t value, int len ){ ASSERT(0); }
+
+protected:
+ // accessible by subclasses
+
+private:
+ // inaccessible by subclasses
+
+};
+
+#endif //DRIVER_H
diff --git a/src/mem/ruby/common/Global.cc b/src/mem/ruby/common/Global.cc
new file mode 100644
index 000000000..7c7cab1e8
--- /dev/null
+++ b/src/mem/ruby/common/Global.cc
@@ -0,0 +1,35 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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/ruby/common/Global.hh"
+
+RubyEventQueue* g_eventQueue_ptr = NULL;
+RubySystem* g_system_ptr = NULL;
+Debug* g_debug_ptr = NULL;
+
diff --git a/src/mem/ruby/common/Global.hh b/src/mem/ruby/common/Global.hh
new file mode 100644
index 000000000..6b524bb70
--- /dev/null
+++ b/src/mem/ruby/common/Global.hh
@@ -0,0 +1,110 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * */
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#ifdef SINGLE_LEVEL_CACHE
+const bool TWO_LEVEL_CACHE = false;
+#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // currently all protocols require L1s == nodes
+#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // "
+#define L2_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // "
+#define L2_CACHE_VARIABLE m_L1Cache_cacheMemory_vec
+#else
+const bool TWO_LEVEL_CACHE = true;
+#ifdef IS_CMP
+#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_L1IcacheMemory_vec[m_version]
+#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_L1DcacheMemory_vec[m_version]
+#define L2_CACHE_MEMBER_VARIABLE m_L2Cache_L2cacheMemory_vec[m_version]
+#define L2_CACHE_VARIABLE m_L2Cache_L2cacheMemory_vec
+#else // not IS_CMP
+#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_L1IcacheMemory_vec[m_version] // currently all protocols require L1s == nodes
+#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_L1DcacheMemory_vec[m_version] // "
+// #define L2_CACHE_MEMBER_VARIABLE m_L1Cache_L2cacheMemory_vec[m_version] // old exclusive caches don't support L2s != nodes
+#define L2_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // old exclusive caches don't support L2s != nodes
+#define L2_CACHE_VARIABLE m_L1Cache_L2cacheMemory_vec
+#endif // IS_CMP
+#endif //SINGLE_LEVEL_CACHE
+
+#define DIRECTORY_MEMBER_VARIABLE m_Directory_directory_vec[m_version]
+#define TBE_TABLE_MEMBER_VARIABLE m_L1Cache_TBEs_vec[m_version]
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+
+typedef signed char int8;
+typedef int int32;
+typedef long long int64;
+
+typedef long long integer_t;
+typedef unsigned long long uinteger_t;
+
+typedef int64 Time;
+typedef uint64 physical_address_t;
+typedef uint64 la_t;
+typedef uint64 pa_t;
+typedef integer_t simtime_t;
+
+// external includes for all classes
+#include "mem/gems_common/std-includes.hh"
+#include "mem/ruby/common/Debug.hh"
+
+// simple type declarations
+typedef Time LogicalTime;
+typedef int64 Index; // what the address bit ripper returns
+typedef int word; // one word of a cache line
+typedef unsigned int uint;
+typedef int SwitchID;
+typedef int LinkID;
+
+class RubyEventQueue;
+extern RubyEventQueue* g_eventQueue_ptr;
+
+class RubySystem;
+extern RubySystem* g_system_ptr;
+
+class Debug;
+extern Debug* g_debug_ptr;
+
+// FIXME: this is required by the contructor of Directory_Entry.h. It can't go
+// into slicc_util.h because it opens a can of ugly worms
+extern inline int max_tokens()
+{
+ return 1024;
+}
+
+
+#endif //GLOBAL_H
+
diff --git a/src/mem/ruby/common/Histogram.cc b/src/mem/ruby/common/Histogram.cc
new file mode 100644
index 000000000..7f9a7027e
--- /dev/null
+++ b/src/mem/ruby/common/Histogram.cc
@@ -0,0 +1,185 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ */
+
+#include "mem/ruby/common/Histogram.hh"
+
+Histogram::Histogram(int binsize, int bins)
+{
+ m_binsize = binsize;
+ m_bins = bins;
+ clear();
+}
+
+Histogram::~Histogram()
+{
+}
+
+void Histogram::clear(int binsize, int bins)
+{
+ m_binsize = binsize;
+ clear(bins);
+}
+
+void Histogram::clear(int bins)
+{
+ m_bins = bins;
+ m_largest_bin = 0;
+ m_max = 0;
+ m_data.setSize(m_bins);
+ for (int i = 0; i < m_bins; i++) {
+ m_data[i] = 0;
+ }
+ m_count = 0;
+ m_max = 0;
+
+ m_sumSamples = 0;
+ m_sumSquaredSamples = 0;
+}
+
+
+void Histogram::add(int64 value)
+{
+ assert(value >= 0);
+ m_max = max(m_max, value);
+ m_count++;
+
+ m_sumSamples += value;
+ m_sumSquaredSamples += (value*value);
+
+ int index;
+ if (m_binsize == -1) {
+ // This is a log base 2 histogram
+ if (value == 0) {
+ index = 0;
+ } else {
+ index = int(log(double(value))/log(2.0))+1;
+ if (index >= m_data.size()) {
+ index = m_data.size()-1;
+ }
+ }
+ } else {
+ // This is a linear histogram
+ while (m_max >= (m_bins * m_binsize)) {
+ for (int i = 0; i < m_bins/2; i++) {
+ m_data[i] = m_data[i*2] + m_data[i*2 + 1];
+ }
+ for (int i = m_bins/2; i < m_bins; i++) {
+ m_data[i] = 0;
+ }
+ m_binsize *= 2;
+ }
+ index = value/m_binsize;
+ }
+ assert(index >= 0);
+ m_data[index]++;
+ m_largest_bin = max(m_largest_bin, index);
+}
+
+void Histogram::add(const Histogram& hist)
+{
+ assert(hist.getBins() == m_bins);
+ assert(hist.getBinSize() == -1); // assume log histogram
+ assert(m_binsize == -1);
+
+ for (int j = 0; j < hist.getData(0); j++) {
+ add(0);
+ }
+
+ for (int i = 1; i < m_bins; i++) {
+ for (int j = 0; j < hist.getData(i); j++) {
+ add(1<<(i-1)); // account for the + 1 index
+ }
+ }
+
+}
+
+// Computation of standard deviation of samples a1, a2, ... aN
+// variance = [SUM {ai^2} - (SUM {ai})^2/N]/(N-1)
+// std deviation equals square root of variance
+double Histogram::getStandardDeviation() const
+{
+ double variance;
+ if(m_count > 1){
+ variance = (double)(m_sumSquaredSamples - m_sumSamples*m_sumSamples/m_count)/(m_count - 1);
+ } else {
+ return 0;
+ }
+ return sqrt(variance);
+}
+
+void Histogram::print(ostream& out) const
+{
+ printWithMultiplier(out, 1.0);
+}
+
+void Histogram::printPercent(ostream& out) const
+{
+ if (m_count == 0) {
+ printWithMultiplier(out, 0.0);
+ } else {
+ printWithMultiplier(out, 100.0/double(m_count));
+ }
+}
+
+void Histogram::printWithMultiplier(ostream& out, double multiplier) const
+{
+ if (m_binsize == -1) {
+ out << "[binsize: log2 ";
+ } else {
+ out << "[binsize: " << m_binsize << " ";
+ }
+ out << "max: " << m_max << " ";
+ out << "count: " << m_count << " ";
+ // out << "total: " << m_sumSamples << " ";
+ if (m_count == 0) {
+ out << "average: NaN |";
+ out << "standard deviation: NaN |";
+ } else {
+ out << "average: " << setw(5) << ((double) m_sumSamples)/m_count << " | ";
+ out << "standard deviation: " << getStandardDeviation() << " |";
+ }
+ for (int i = 0; i < m_bins && i <= m_largest_bin; i++) {
+ if (multiplier == 1.0) {
+ out << " " << m_data[i];
+ } else {
+ out << " " << double(m_data[i]) * multiplier;
+ }
+ }
+ out << " ]";
+}
+
+bool node_less_then_eq(const Histogram* n1, const Histogram* n2)
+{
+ return (n1->size() > n2->size());
+}
diff --git a/src/mem/ruby/common/Histogram.hh b/src/mem/ruby/common/Histogram.hh
new file mode 100644
index 000000000..59afde867
--- /dev/null
+++ b/src/mem/ruby/common/Histogram.hh
@@ -0,0 +1,104 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: The histogram class implements a simple histogram
+ *
+ */
+
+#ifndef HISTOGRAM_H
+#define HISTOGRAM_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/gems_common/Vector.hh"
+
+class Histogram {
+public:
+ // Constructors
+ Histogram(int binsize = 1, int bins = 50);
+
+ // Destructor
+ ~Histogram();
+
+ // Public Methods
+
+ void add(int64 value);
+ void add(const Histogram& hist);
+ void clear() { clear(m_bins); }
+ void clear(int bins);
+ void clear(int binsize, int bins);
+ int64 size() const { return m_count; }
+ int getBins() const { return m_bins; }
+ int getBinSize() const { return m_binsize; }
+ int64 getTotal() const { return m_sumSamples; }
+ int64 getData(int index) const { return m_data[index]; }
+
+ void printWithMultiplier(ostream& out, double multiplier) const;
+ void printPercent(ostream& out) const;
+ void print(ostream& out) const;
+private:
+ // Private Methods
+
+ // Private copy constructor and assignment operator
+ // Histogram(const Histogram& obj);
+ // Histogram& operator=(const Histogram& obj);
+
+ // Data Members (m_ prefix)
+ Vector<int64> m_data;
+ int64 m_max; // the maximum value seen so far
+ int64 m_count; // the number of elements added
+ int m_binsize; // the size of each bucket
+ int m_bins; // the number of buckets
+ int m_largest_bin; // the largest bin used
+
+ int64 m_sumSamples; // the sum of all samples
+ int64 m_sumSquaredSamples; // the sum of the square of all samples
+
+ double getStandardDeviation() const;
+};
+
+bool node_less_then_eq(const Histogram* n1, const Histogram* n2);
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Histogram& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Histogram& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //HISTOGRAM_H
diff --git a/src/mem/ruby/common/Message.cc b/src/mem/ruby/common/Message.cc
new file mode 100644
index 000000000..bf3307687
--- /dev/null
+++ b/src/mem/ruby/common/Message.cc
@@ -0,0 +1,34 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "mem/ruby/slicc_interface/Message.hh"
diff --git a/src/mem/ruby/common/NetDest.cc b/src/mem/ruby/common/NetDest.cc
new file mode 100644
index 000000000..951307395
--- /dev/null
+++ b/src/mem/ruby/common/NetDest.cc
@@ -0,0 +1,259 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetDest.C
+ *
+ * Description: See NetDest.h
+ *
+ * $Id$
+ *
+ */
+
+#include "mem/ruby/common/NetDest.hh"
+#include "mem/ruby/config/RubyConfig.hh"
+#include "mem/protocol/Protocol.hh"
+
+NetDest::NetDest()
+{
+ setSize();
+}
+
+void NetDest::add(MachineID newElement)
+{
+ m_bits[vecIndex(newElement)].add(bitIndex(newElement.num));
+}
+
+void NetDest::addNetDest(const NetDest& netDest)
+{
+ assert(m_bits.size() == netDest.getSize());
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].addSet(netDest.m_bits[i]);
+ }
+}
+
+void NetDest::addRandom()
+{
+ int i = random()%m_bits.size();
+ m_bits[i].addRandom();
+}
+
+void NetDest::setNetDest(MachineType machine, const Set& set)
+{
+ // assure that there is only one set of destinations for this machine
+ assert(MachineType_base_level((MachineType)(machine+1)) - MachineType_base_level(machine) == 1);
+ m_bits[MachineType_base_level(machine)] = set;
+}
+
+void NetDest::remove(MachineID oldElement)
+{
+ m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num));
+}
+
+void NetDest::removeNetDest(const NetDest& netDest)
+{
+ assert(m_bits.size() == netDest.getSize());
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].removeSet(netDest.m_bits[i]);
+
+ }
+}
+
+void NetDest::clear()
+{
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].clear();
+ }
+}
+
+void NetDest::broadcast()
+{
+ for (MachineType machine = MachineType_FIRST; machine < MachineType_NUM; ++machine) {
+ broadcast(machine);
+ }
+}
+
+void NetDest::broadcast(MachineType machineType) {
+
+ for (int i = 0; i < MachineType_base_count(machineType); i++) {
+ MachineID mach = {machineType, i};
+ add(mach);
+ }
+}
+
+//For Princeton Network
+Vector<NodeID> NetDest::getAllDest() {
+ Vector<NodeID> dest;
+ dest.clear();
+ for (int i=0; i<m_bits.size(); i++) {
+ for (int j=0; j<m_bits[i].getSize(); j++) {
+ if (m_bits[i].isElement(j)) {
+ dest.insertAtBottom((NodeID) (MachineType_base_number((MachineType) i) + j));
+ }
+ }
+ }
+ return dest;
+}
+
+int NetDest::count() const
+{
+ int counter = 0;
+ for (int i=0; i<m_bits.size(); i++) {
+ counter += m_bits[i].count();
+ }
+ return counter;
+}
+
+NodeID NetDest::elementAt(MachineID index) {
+ return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
+}
+
+NodeID NetDest::smallestElement() const
+{
+ assert(count() > 0);
+ for (int i=0; i<m_bits.size(); i++) {
+ for (int j=0; j<m_bits[i].getSize(); j++) {
+ if (m_bits[i].isElement(j)) {
+ return j;
+ }
+ }
+ }
+ ERROR_MSG("No smallest element of an empty set.");
+}
+
+MachineID NetDest::smallestElement(MachineType machine) const
+{
+ for (int j = 0; j < m_bits[MachineType_base_level(machine)].getSize(); j++) {
+ if (m_bits[MachineType_base_level(machine)].isElement(j)) {
+ MachineID mach = {machine, j};
+ return mach;
+ }
+ }
+
+ ERROR_MSG("No smallest element of given MachineType.");
+}
+
+
+// Returns true iff all bits are set
+bool NetDest::isBroadcast() const
+{
+ for (int i=0; i<m_bits.size(); i++) {
+ if (!m_bits[i].isBroadcast()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// Returns true iff no bits are set
+bool NetDest::isEmpty() const
+{
+ for (int i=0; i<m_bits.size(); i++) {
+ if (!m_bits[i].isEmpty()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// returns the logical OR of "this" set and orNetDest
+NetDest NetDest::OR(const NetDest& orNetDest) const
+{
+ assert(m_bits.size() == orNetDest.getSize());
+ NetDest result;
+ for (int i=0; i<m_bits.size(); i++) {
+ result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]);
+ }
+ return result;
+}
+
+
+// returns the logical AND of "this" set and andNetDest
+NetDest NetDest::AND(const NetDest& andNetDest) const
+{
+ assert(m_bits.size() == andNetDest.getSize());
+ NetDest result;
+ for (int i=0; i<m_bits.size(); i++) {
+ result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]);
+ }
+ return result;
+}
+
+// Returns true if the intersection of the two sets is non-empty
+bool NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const
+{
+ assert(m_bits.size() == other_netDest.getSize());
+ for (int i=0; i<m_bits.size(); i++) {
+ if (m_bits[i].intersectionIsNotEmpty(other_netDest.m_bits[i])) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool NetDest::isSuperset(const NetDest& test) const
+{
+ assert(m_bits.size() == test.getSize());
+
+ for (int i=0; i<m_bits.size(); i++) {
+ if (!m_bits[i].isSuperset(test.m_bits[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool NetDest::isElement(MachineID element) const
+{
+ return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num));
+}
+
+void NetDest::setSize()
+{
+ m_bits.setSize(MachineType_base_level(MachineType_NUM));
+ assert(m_bits.size() == MachineType_NUM);
+
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].setSize(MachineType_base_count((MachineType)i));
+ }
+}
+
+void NetDest::print(ostream& out) const
+{
+ out << "[NetDest (" << m_bits.size() << ") ";
+
+ for (int i=0; i<m_bits.size(); i++) {
+ for (int j=0; j<m_bits[i].getSize(); j++) {
+ out << (bool) m_bits[i].isElement(j) << " ";
+ }
+ out << " - ";
+ }
+ out << "]";
+}
+
diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh
new file mode 100644
index 000000000..17ede03e9
--- /dev/null
+++ b/src/mem/ruby/common/NetDest.hh
@@ -0,0 +1,145 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Set.h
+ *
+ * Description:
+ *
+ * $Id$
+ *
+ */
+
+// NetDest specifies the network destination of a NetworkMessage
+// This is backward compatible with the Set class that was previously
+// used to specify network destinations.
+// NetDest supports both node networks and component networks
+
+#ifndef NETDEST_H
+#define NETDEST_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/gems_common/Vector.hh"
+#include "mem/ruby/system/NodeID.hh"
+#include "mem/ruby/system/MachineID.hh"
+#include "mem/ruby/config/RubyConfig.hh"
+#include "mem/ruby/common/Set.hh"
+#include "mem/protocol/MachineType.hh"
+
+class Set;
+
+class NetDest {
+public:
+ // Constructors
+ // creates and empty set
+ NetDest();
+ explicit NetDest(int bit_size);
+
+ NetDest& operator=(const Set& obj);
+
+ // Destructor
+ // ~NetDest();
+
+ // Public Methods
+ void add(MachineID newElement);
+ void addNetDest(const NetDest& netDest);
+ void addRandom();
+ void setNetDest(MachineType machine, const Set& set);
+ void remove(MachineID oldElement);
+ void removeNetDest(const NetDest& netDest);
+ void clear();
+ void broadcast();
+ void broadcast(MachineType machine);
+ int count() const;
+ bool isEqual(const NetDest& netDest);
+
+ NetDest OR(const NetDest& orNetDest) const; // return the logical OR of this netDest and orNetDest
+ NetDest AND(const NetDest& andNetDest) const; // return the logical AND of this netDest and andNetDest
+
+ // Returns true if the intersection of the two netDests is non-empty
+ bool intersectionIsNotEmpty(const NetDest& other_netDest) const;
+
+ // Returns true if the intersection of the two netDests is empty
+ bool intersectionIsEmpty(const NetDest& other_netDest) const;
+
+ bool isSuperset(const NetDest& test) const;
+ bool isSubset(const NetDest& test) const { return test.isSuperset(*this); }
+ bool isElement(MachineID element) const;
+ bool isBroadcast() const;
+ bool isEmpty() const;
+
+ //For Princeton Network
+ Vector<NodeID> getAllDest();
+
+ NodeID smallestElement() const;
+ MachineID smallestElement(MachineType machine) const;
+
+ void setSize();
+ int getSize() const { return m_bits.size(); }
+
+ // get element for a index
+ NodeID elementAt(MachineID index);
+
+ void print(ostream& out) const;
+
+private:
+
+ // Private Methods
+ // returns a value >= MachineType_base_level("this machine") and < MachineType_base_level("next highest machine")
+ int vecIndex(MachineID m) const {
+ int vec_index = MachineType_base_level(m.type);
+ assert(vec_index < m_bits.size());
+ return vec_index;
+ }
+
+ NodeID bitIndex(NodeID index) const {
+ return index;
+ }
+
+ // Data Members (m_ prefix)
+ Vector < Set > m_bits; // a Vector of bit vectors - i.e. Sets
+
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const NetDest& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const NetDest& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //NETDEST_H
+
diff --git a/src/mem/ruby/common/SConscript b/src/mem/ruby/common/SConscript
new file mode 100644
index 000000000..15df8312e
--- /dev/null
+++ b/src/mem/ruby/common/SConscript
@@ -0,0 +1,45 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+Import('*')
+
+if not env['RUBY']:
+ Return()
+
+Source('Address.cc')
+Source('DataBlock.cc')
+Source('Debug.cc')
+Source('Driver.cc')
+Source('Global.cc')
+Source('Histogram.cc')
+Source('Message.cc')
+Source('NetDest.cc')
+Source('Set.cc', Werror=False)
+Source('SubBlock.cc')
diff --git a/src/mem/ruby/common/Set.cc b/src/mem/ruby/common/Set.cc
new file mode 100644
index 000000000..b4c4e4789
--- /dev/null
+++ b/src/mem/ruby/common/Set.cc
@@ -0,0 +1,576 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Set.C
+ *
+ * Description: See Set.h
+ *
+ * $Id: BigSet.C 1.9 05/01/19 13:12:25-06:00 mikem@maya.cs.wisc.edu $
+ *
+ */
+
+// modified (rewritten) 05/20/05 by Dan Gibson to accomimdate FASTER >32 bit
+// set sizes
+
+#include "mem/ruby/common/Set.hh"
+#include "mem/ruby/config/RubyConfig.hh"
+
+#if __amd64__ || __LP64__
+#define __64BITS__
+#else
+#define __32BITS__
+#endif
+
+Set::Set()
+{
+ m_p_nArray = NULL;
+ setSize(RubyConfig::numberOfProcessors());
+}
+
+// copy constructor
+Set::Set(const Set& obj) {
+ m_p_nArray = NULL;
+ setSize(obj.m_nSize);
+
+ // copy from the host to this array
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] = obj.m_p_nArray[i];
+ }
+
+}
+
+Set::Set(int size)
+{
+ m_p_nArray = NULL;
+ assert(size>0);
+ setSize(size);
+}
+
+Set::~Set() {
+ if( (m_p_nArray != (&m_p_nArray_Static[0])) && (m_p_nArray != NULL))
+ delete [] m_p_nArray;
+ m_p_nArray = NULL;
+}
+
+
+// /*
+// * This function should set the bit corresponding to index
+// * to 1.
+// */
+
+// void Set::add(NodeID index)
+// {
+// assert(index<m_nSize && index >= 0);
+
+// #ifdef __32BITS__
+// m_p_nArray[index>>5] |= (1 << (index & 0x01F));
+// #else
+// m_p_nArray[index>>6] |= (((unsigned long) 1) << (index & 0x03F));
+// #endif // __32BITS__
+
+// }
+
+/*
+ * This function should set all the bits in the current set
+ * that are already set in the parameter set
+ */
+void Set::addSet(const Set& set)
+{
+ assert(getSize()==set.getSize());
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] |= set.m_p_nArray[i];
+ }
+
+}
+
+/*
+ * This function should randomly assign 1 to the bits in the set--
+ * it should not clear the bits bits first, though?
+ */
+void Set::addRandom()
+{
+
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] |= random() ^ (random() << 4); // this ensures that all 32 bits are subject to random effects,
+ // as RAND_MAX typically = 0x7FFFFFFF
+ }
+
+ // now just ensure that no bits over the maximum size were set
+#ifdef __32BITS__
+ long mask = 0x7FFFFFFF;
+
+ // the number of populated spaces in the higest-order array slot is:
+ // m_nSize % 32, so the uppermost 32 - m_nSize%32 bits should be
+ // cleared
+
+ if((m_nSize % 32) != 0) {
+ for(int j=0; j<32-(m_nSize&0x01F); j++) {
+ m_p_nArray[m_nArrayLen-1] &= mask;
+ mask = mask >> 1;
+ }
+ }
+#else
+ long mask = 0x7FFFFFFFFFFFFFFF;
+
+ // the number of populated spaces in the higest-order array slot is:
+ // m_nSize % 64, so the uppermost 64 - m_nSize%64 bits should be
+ // cleared
+
+ if((m_nSize % 64) != 0) {
+ for(int j=0; j<64-(m_nSize&0x03F); j++) {
+ m_p_nArray[m_nArrayLen-1] &= mask;
+ mask = mask >> 1;
+ }
+ }
+#endif // __32BITS__
+
+}
+
+// /*
+// * This function unsets the bit associated with index
+// */
+// void Set::remove(NodeID index)
+// {
+// assert(index<m_nSize && index>=0);
+
+// #ifdef __32BITS__
+// m_p_nArray[index>>5] &= ~(0x00000001 << (index & 0x01F));
+// #else
+// m_p_nArray[index>>6] &= ~(((unsigned long) 0x0000000000000001) << (index & 0x03F));
+// #endif // __32BITS__
+
+// }
+
+
+/*
+ * This function clears bits that are =1 in the parameter set
+ */
+void Set::removeSet(const Set& set)
+{
+
+ assert(m_nSize==set.m_nSize);
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] &= ~(set.m_p_nArray[i]);
+ }
+
+}
+
+// /*
+// * This function clears all bits in the set
+// */
+// void Set::clear()
+// {
+// for(int i=0; i<m_nArrayLen; i++) {
+// m_p_nArray[i] = 0;
+// }
+// }
+
+/*
+ * this function sets all bits in the set
+ */
+void Set::broadcast()
+{
+
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] = -1; // note that -1 corresponds to all 1's in 2's comp.
+ }
+
+ // now just ensure that no bits over the maximum size were set
+#ifdef __32BITS__
+ long mask = 0x7FFFFFFF;
+
+ // the number of populated spaces in the higest-order array slot is:
+ // m_nSize % 32, so the uppermost 32 - m_nSize%32 bits should be
+ // cleared
+
+ if((m_nSize % 32) != 0) {
+ for(int j=0; j<32-(m_nSize&0x01F); j++) {
+ m_p_nArray[m_nArrayLen-1] &= mask;
+ mask = mask >> 1;
+ }
+ }
+#else
+ long mask = 0x7FFFFFFFFFFFFFFF;
+
+ // the number of populated spaces in the higest-order array slot is:
+ // m_nSize % 64, so the uppermost 64 - m_nSize%64 bits should be
+ // cleared
+
+ if((m_nSize % 64) != 0) {
+ for(int j=0; j<64-(m_nSize&0x03F); j++) {
+ m_p_nArray[m_nArrayLen-1] &= mask;
+ mask = mask >> 1;
+ }
+ }
+#endif // __32BITS__
+
+}
+
+/*
+ * This function returns the population count of 1's in the set
+ */
+int Set::count() const
+{
+ int counter = 0;
+ long mask;
+ for( int i=0; i<m_nArrayLen; i++) {
+ mask = (long) 0x01;
+
+#ifdef __32BITS__
+ for( int j=0; j<32; j++) {
+ if(m_p_nArray[i] & mask) counter++;
+ mask = mask << 1;
+ }
+
+#else
+
+ for( int j=0; j<64; j++) { // FIXME - significant performance loss when array population << 64
+ if((m_p_nArray[i] & mask) != 0) {
+ counter++;
+ }
+ mask = mask << 1;
+ }
+
+#endif // __32BITS__
+
+ }
+
+ return counter;
+}
+
+/*
+ * This function checks for set equality
+ */
+
+bool Set::isEqual(const Set& set) const
+{
+ assert(m_nSize==set.m_nSize);
+
+ for(int i=0;i<m_nArrayLen;i++) {
+ if(m_p_nArray[i] != set.m_p_nArray[i]) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*
+ * This function returns the NodeID (int) of the
+ * least set bit
+ */
+NodeID Set::smallestElement() const
+{
+ assert(count() > 0);
+ long x;
+ for( int i=0; i<m_nArrayLen; i++) {
+ if(m_p_nArray[i]!=0) {
+ // the least-set bit must be in here
+ x = m_p_nArray[i];
+
+#ifdef __32BITS__
+ for( int j=0; j<32; j++) {
+ if(x & 0x00000001) {
+ return 32*i+j;
+ }
+
+ x = x >> 1;
+ }
+#else
+ for( int j=0; j<64; j++) {
+ if(x & 0x0000000000000001) {
+ return 64*i+j;
+ }
+
+ x = x >> 1;
+ }
+#endif // __32BITS__
+
+ ERROR_MSG("No smallest element of an empty set.");
+ }
+ }
+
+ ERROR_MSG("No smallest element of an empty set.");
+
+ return 0;
+}
+
+/*
+ * this function returns true iff all bits are set
+ */
+bool Set::isBroadcast() const
+{
+ // check the fully-loaded words by equal to 0xffffffff
+ // only the last word may not be fully loaded, it is not
+ // fully loaded iff m_nSize % 32 or 64 !=0 => fully loaded iff
+ // m_nSize % 32 or 64 == 0
+
+#ifdef __32BITS__
+ for(int i=0; i< (((m_nSize % 32)==0) ? m_nArrayLen : m_nArrayLen-1); i++) {
+ if(m_p_nArray[i]!=-1) {
+ return false;
+ }
+ }
+
+ // now check the last word, which may not be fully loaded
+ long mask = 1;
+ for(int j=0; j< (m_nSize % 32); j++) {
+ if((mask & m_p_nArray[m_nArrayLen-1])==0) {
+ return false;
+ }
+ mask = mask << 1;
+ }
+#else
+ for(int i=0; i< (((m_nSize % 64)==0) ? m_nArrayLen : m_nArrayLen-1); i++) {
+ if(m_p_nArray[i]!=-1) {
+ return false;
+ }
+ }
+
+ // now check the last word, which may not be fully loaded
+ long mask = 1;
+ for(int j=0; j< (m_nSize % 64); j++) {
+ if((mask & m_p_nArray[m_nArrayLen-1])==0) {
+ return false;
+ }
+ mask = mask << 1;
+ }
+
+#endif // __32BITS__
+
+ return true;
+}
+
+/*
+ * this function returns true iff no bits are set
+ */
+bool Set::isEmpty() const
+{
+
+ // here we can simply check if all = 0, since we ensure
+ // that "extra slots" are all zero
+ for(int i=0; i< m_nArrayLen ; i++) {
+ if(m_p_nArray[i]!=0) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// returns the logical OR of "this" set and orSet
+Set Set::OR(const Set& orSet) const
+{
+ Set result(m_nSize);
+ assert(m_nSize == orSet.m_nSize);
+ for(int i=0; i< m_nArrayLen; i++) {
+ result.m_p_nArray[i] = m_p_nArray[i] | orSet.m_p_nArray[i];
+ }
+
+ return result;
+
+}
+
+// returns the logical AND of "this" set and andSet
+Set Set::AND(const Set& andSet) const
+{
+ Set result(m_nSize);
+ assert(m_nSize == andSet.m_nSize);
+
+ for(int i=0; i< m_nArrayLen; i++) {
+ result.m_p_nArray[i] = m_p_nArray[i] & andSet.m_p_nArray[i];
+ }
+
+ return result;
+}
+
+// // Returns true if the intersection of the two sets is non-empty
+// bool Set::intersectionIsNotEmpty(const Set& other_set) const
+// {
+// assert(m_nSize == other_set.m_nSize);
+// for(int i=0; i< m_nArrayLen; i++) {
+// if(m_p_nArray[i] & other_set.m_p_nArray[i]) {
+// return true;
+// }
+// }
+
+// return false;
+
+// }
+
+// // Returns true if the intersection of the two sets is empty
+// bool Set::intersectionIsEmpty(const Set& other_set) const
+// {
+// assert(m_nSize == other_set.m_nSize);
+// for(int i=0; i< m_nArrayLen; i++) {
+// if(m_p_nArray[i] & other_set.m_p_nArray[i]) {
+// return false;
+// }
+// }
+
+// return true;
+
+// }
+
+/*
+ * Returns false if a bit is set in the parameter set that is
+ * NOT set in this set
+ */
+bool Set::isSuperset(const Set& test) const
+{
+ assert(m_nSize == test.m_nSize);
+
+ for(int i=0;i<m_nArrayLen;i++) {
+ if(((test.m_p_nArray[i] & m_p_nArray[i]) | ~test.m_p_nArray[i]) != -1) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// /*
+// * Returns true iff this bit is set
+// */
+// bool Set::isElement(NodeID element) const
+// {
+// bool result;
+
+// #ifdef __32BITS__
+// result = ((m_p_nArray[element>>5] & (0x00000001 << (element & 0x01F)))!=0);
+// #else
+// result = ((m_p_nArray[element>>6] & (((unsigned long) 0x0000000000000001) << (element & 0x03F)))!=0);
+// #endif // __32BITS__
+
+// return result;
+// }
+
+/*
+ * "Supposed" to return the node id of the (n+1)th set
+ * bit, IE n=0 => returns nodeid of first set bit, BUT
+ * since BigSet.C behaves strangely, this implementation
+ * will behave strangely just for reverse compatability.
+ *
+ * Was originally implemented for the flight data recorder
+ * FDR
+ */
+
+// NodeID Set::elementAt(int n) const
+// {
+// if(isElement(n)) return (NodeID) true;
+// else return 0;
+
+// /*
+// int match = -1;
+// for(int i=0;i<m_nSize;i++) {
+// if(isElement(i)) match++;
+// if(match==n) {
+// return i;
+// }
+// }
+
+// return -1;
+// */
+// }
+
+void Set::setSize(int size)
+{
+ m_nSize = size;
+
+#ifdef __32BITS__
+ m_nArrayLen = m_nSize/32 + ((m_nSize%32==0) ? 0 : 1 );
+#else
+ m_nArrayLen = m_nSize/64 + ((m_nSize%64==0) ? 0 : 1 );
+#endif // __32BITS__
+
+ // decide whether to use dynamic or static alloction
+ if(m_nArrayLen<=NUMBER_WORDS_PER_SET) { // constant defined in RubyConfig.h
+ // its OK to use the static allocation, and it will
+ // probably be faster (as m_nArrayLen is already in the
+ // cache and they will probably share the same cache line)
+
+ // if switching from dyanamic to static allocation (which
+ // is probably rare, but why not be complete?), must delete
+ // the dynamically allocated space
+ if((m_p_nArray != NULL) && (m_p_nArray != &m_p_nArray_Static[0]))
+ delete [] m_p_nArray;
+
+ m_p_nArray = & m_p_nArray_Static[0];
+ } else {
+
+ // can't use static allocation...simply not enough room
+ // so dynamically allocate some space
+ if((m_p_nArray != NULL) && (m_p_nArray != &m_p_nArray_Static[0]))
+ delete [] m_p_nArray;
+
+ m_p_nArray = new long[m_nArrayLen];
+ }
+
+ clear();
+}
+
+Set& Set::operator=(const Set& obj) {
+ if(this == &obj) {
+ // do nothing
+ } else {
+
+ // resize this item
+ setSize(obj.getSize());
+
+ // copy the elements from obj to this
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] = obj.m_p_nArray[i];
+ }
+ }
+
+ return *this;
+}
+
+void Set::print(ostream& out) const
+{
+ if(m_p_nArray==NULL) {
+ out << "[Set {Empty}]";
+ return;
+ }
+ char buff[24];
+ out << "[Set 0x ";
+ for (int i=m_nArrayLen-1; i>=0; i--) {
+#ifdef __32BITS__
+ sprintf(buff,"%08X ",m_p_nArray[i]);
+#else
+ sprintf(buff,"0x %016llX ",m_p_nArray[i]);
+#endif // __32BITS__
+ out << buff;
+ }
+ out << " ]";
+
+}
+
+
diff --git a/src/mem/ruby/common/Set.hh b/src/mem/ruby/common/Set.hh
new file mode 100644
index 000000000..45f06e6aa
--- /dev/null
+++ b/src/mem/ruby/common/Set.hh
@@ -0,0 +1,202 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Set.h
+ *
+ * Description:
+ *
+ * $Id: BigSet.h 1.6 05/01/19 13:12:25-06:00 mikem@maya.cs.wisc.edu $
+ *
+ */
+
+// modified by Dan Gibson on 05/20/05 to accomidate FASTER
+// >32 set lengths, using an array of ints w/ 32 bits/int
+
+// NOTE: Never include this file directly, this should only be
+// included from Set.h
+
+#ifndef SET_H
+#define SET_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/gems_common/Vector.hh"
+#include "mem/ruby/system/NodeID.hh"
+#include "mem/ruby/config/RubyConfig.hh"
+
+// gibson 05/20/05
+// enum PresenceBit {NotPresent, Present};
+
+class Set {
+public:
+ // Constructors
+ // creates and empty set
+ Set();
+ Set (int size);
+
+ // used during the replay mechanism
+ // Set(const char *str);
+
+ Set(const Set& obj);
+ Set& operator=(const Set& obj);
+
+ // Destructor
+ ~Set();
+
+ // Public Methods
+
+ inline void add(NodeID index)
+ {
+#ifdef __32BITS__
+ m_p_nArray[index>>5] |= (1 << (index & 0x01F));
+#else
+ m_p_nArray[index>>6] |= (((unsigned long) 1) << (index & 0x03F));
+#endif // __32BITS__
+ }
+
+ void addSet(const Set& set);
+ void addRandom();
+
+ inline void remove(NodeID index)
+ {
+#ifdef __32BITS__
+ m_p_nArray[index>>5] &= ~(0x00000001 << (index & 0x01F));
+#else
+ m_p_nArray[index>>6] &= ~(((unsigned long) 0x0000000000000001) << (index & 0x03F));
+#endif // __32BITS__
+ }
+
+
+ void removeSet(const Set& set);
+
+ inline void clear() { for(int i=0; i<m_nArrayLen; i++) m_p_nArray[i] = 0; }
+
+ void broadcast();
+ int count() const;
+ bool isEqual(const Set& set) const;
+
+ Set OR(const Set& orSet) const; // return the logical OR of this set and orSet
+ Set AND(const Set& andSet) const; // return the logical AND of this set and andSet
+
+ // Returns true if the intersection of the two sets is non-empty
+ inline bool intersectionIsNotEmpty(const Set& other_set) const
+ {
+ for(int i=0; i< m_nArrayLen; i++) {
+ if(m_p_nArray[i] & other_set.m_p_nArray[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Returns true if the intersection of the two sets is empty
+ inline bool intersectionIsEmpty(const Set& other_set) const
+ {
+ for(int i=0; i< m_nArrayLen; i++) {
+ if(m_p_nArray[i] & other_set.m_p_nArray[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool isSuperset(const Set& test) const;
+ bool isSubset(const Set& test) const { return test.isSuperset(*this); }
+
+ inline bool isElement(NodeID element) const
+ {
+#ifdef __32BITS__
+ return ((m_p_nArray[element>>5] & (0x00000001 << (element & 0x01F)))!=0);
+#else
+ return ((m_p_nArray[element>>6] & (((unsigned long) 0x0000000000000001) << (element & 0x03F)))!=0);
+#endif // __32BITS__
+
+ }
+
+ bool isBroadcast() const;
+ bool isEmpty() const;
+
+ NodeID smallestElement() const;
+
+ // int size() const;
+ void setSize (int size);
+
+ // get element for a index
+ inline NodeID elementAt(int index) const
+ {
+ if(isElement(index)) return (NodeID) true;
+ else return 0;
+ }
+
+ // gibson 05/20/05
+ int getSize() const { return m_nSize; }
+
+ // DEPRECATED METHODS
+ void addToSet(NodeID newElement) { add(newElement); } // Deprecated
+ void removeFromSet(NodeID newElement) { remove(newElement); } // Deprecated
+ void clearSet() { clear(); } // Deprecated
+ void setBroadcast() { broadcast(); } // Deprecated
+ bool presentInSet(NodeID element) const { return isElement(element); } // Deprecated
+
+ void print(ostream& out) const;
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ // gibson 05/20/05
+ // Vector<uint8> m_bits; // This is an vector of uint8 to reduce the size of the set
+
+ int m_nSize; // the number of bits in this set
+ int m_nArrayLen; // the number of 32-bit words that are held in the array
+
+ // Changed 5/24/05 for static allocation of array
+ // note that "long" corresponds to 32 bits on a 32-bit machine,
+ // 64 bits if the -m64 parameter is passed to g++, which it is
+ // for an AMD opteron under our configuration
+
+ long * m_p_nArray; // an word array to hold the bits in the set
+ long m_p_nArray_Static[NUMBER_WORDS_PER_SET];
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Set& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Set& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //SET_H
+
diff --git a/src/mem/ruby/common/SubBlock.cc b/src/mem/ruby/common/SubBlock.cc
new file mode 100644
index 000000000..568d3106a
--- /dev/null
+++ b/src/mem/ruby/common/SubBlock.cc
@@ -0,0 +1,81 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "mem/ruby/common/SubBlock.hh"
+
+SubBlock::SubBlock(const Address& addr, int size)
+{
+ m_address = addr;
+ setSize(size);
+ for(int i=0; i<size; i++) {
+ setByte(i, 0);
+ }
+}
+
+SubBlock::SubBlock(const Address& addr, const Address& logicalAddress, int size)
+{
+ m_address = addr;
+ m_logicalAddress = logicalAddress;
+ setSize(size);
+ for(int i=0; i<size; i++) {
+ setByte(i, 0);
+ }
+}
+
+void SubBlock::internalMergeFrom(const DataBlock& data)
+{
+ int size = getSize();
+ assert(size > 0);
+ int offset = m_address.getOffset();
+ for(int i=0; i<size; i++) {
+ this->setByte(i, data.getByte(offset+i));
+ }
+}
+
+void SubBlock::internalMergeTo(DataBlock& data) const
+{
+ int size = getSize();
+ assert(size > 0);
+ int offset = m_address.getOffset();
+ for(int i=0; i<size; i++) {
+ data.setByte(offset+i, this->getByte(i)); // This will detect crossing a cache line boundary
+ }
+}
+
+void SubBlock::print(ostream& out) const
+{
+ out << "[" << m_address << ", " << getSize() << ", " << m_data << "]";
+}
+
+
+
diff --git a/src/mem/ruby/common/SubBlock.hh b/src/mem/ruby/common/SubBlock.hh
new file mode 100644
index 000000000..5831be35a
--- /dev/null
+++ b/src/mem/ruby/common/SubBlock.hh
@@ -0,0 +1,105 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SubBlock_H
+#define SubBlock_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/config/RubyConfig.hh"
+#include "mem/ruby/common/DataBlock.hh"
+#include "mem/gems_common/Vector.hh"
+
+class SubBlock {
+public:
+ // Constructors
+ SubBlock() { }
+ SubBlock(const Address& addr, int size);
+ SubBlock(const Address& addr, const Address& logicalAddress, int size);
+
+ // Destructor
+ ~SubBlock() { }
+
+ // Public Methods
+ const Address& getAddress() const { return m_address; }
+ const Address& getLogicalAddress() const { return m_logicalAddress; }
+ void setAddress(const Address& addr) { m_address = addr; }
+ void setLogicalAddress(const Address& addr) { m_logicalAddress = addr; }
+
+ int getSize() const { return m_data.size(); }
+ void setSize(int size) { m_data.setSize(size); }
+ uint8 getByte(int offset) const { return m_data[offset]; }
+ void setByte(int offset, uint8 data) { m_data[offset] = data; }
+
+ // Shorthands
+ uint8 readByte() const { return getByte(0); }
+ void writeByte(uint8 data) { setByte(0, data); }
+
+ // Merging to and from DataBlocks - We only need to worry about
+ // updates when we are using DataBlocks
+ void mergeTo(DataBlock& data) const { if (DATA_BLOCK) { internalMergeTo(data); } }
+ void mergeFrom(const DataBlock& data) { if (DATA_BLOCK) { internalMergeFrom(data); } }
+
+ void print(ostream& out) const;
+private:
+ // Private Methods
+ // SubBlock(const SubBlock& obj);
+ // SubBlock& operator=(const SubBlock& obj);
+ // bool bytePresent(const Address& addr) { return ((addr.getAddress() >= m_address.getAddress()) && (addr.getAddress() < (m_address.getAddress()+getSize()))); }
+ // uint8 getByte(const Address& addr) { return m_data[addr.getAddress() - m_address.getAddress()]; }
+
+ void internalMergeTo(DataBlock& data) const;
+ void internalMergeFrom(const DataBlock& data);
+
+ // Data Members (m_ prefix)
+ Address m_address;
+ Address m_logicalAddress;
+ Vector<uint> m_data;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const SubBlock& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const SubBlock& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //SubBlock_H