summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/bridge.cc96
-rw-r--r--src/mem/bridge.hh9
-rw-r--r--src/mem/bus.cc30
-rw-r--r--src/mem/bus.hh15
-rw-r--r--src/mem/cache/prefetch/tagged_prefetcher_impl.hh2
-rw-r--r--src/mem/config/prefetch.hh2
-rw-r--r--src/mem/mem_object.cc2
-rw-r--r--src/mem/mem_object.hh2
-rw-r--r--src/mem/packet.cc17
-rw-r--r--src/mem/packet.hh180
-rw-r--r--src/mem/page_table.cc3
-rw-r--r--src/mem/page_table.hh2
-rw-r--r--src/mem/physical.cc5
-rw-r--r--src/mem/physical.hh2
-rw-r--r--src/mem/port.cc7
-rw-r--r--src/mem/port.hh47
-rw-r--r--src/mem/port_impl.hh53
-rw-r--r--src/mem/request.hh249
-rw-r--r--src/mem/translating_port.cc3
-rw-r--r--src/mem/translating_port.hh3
-rw-r--r--src/mem/vport.cc10
-rw-r--r--src/mem/vport.hh21
22 files changed, 476 insertions, 284 deletions
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index 736e8dc81..3718cbaaf 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -25,6 +25,9 @@
* 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: Ali Saidi
+ * Steve Reinhardt
*/
/**
@@ -90,7 +93,17 @@ Bridge::BridgePort::recvTiming(Packet *pkt)
DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr());
- if (pkt->isResponse()) {
+ return otherPort->queueForSendTiming(pkt);
+}
+
+
+bool
+Bridge::BridgePort::queueForSendTiming(Packet *pkt)
+{
+ if (queueFull())
+ return false;
+
+ if (pkt->isResponse()) {
// This is a response for a request we forwarded earlier. The
// corresponding PacketBuffer should be stored in the packet's
// senderState field.
@@ -99,22 +112,16 @@ Bridge::BridgePort::recvTiming(Packet *pkt)
// set up new packet dest & senderState based on values saved
// from original request
buf->fixResponse(pkt);
+ DPRINTF(BusBridge, "restoring sender state: %#X, from packet buffer: %#X\n",
+ pkt->senderState, buf);
DPRINTF(BusBridge, " is response, new dest %d\n", pkt->getDest());
delete buf;
}
- return otherPort->queueForSendTiming(pkt);
-}
-
-
-bool
-Bridge::BridgePort::queueForSendTiming(Packet *pkt)
-{
- if (queueFull())
- return false;
-
Tick readyTime = curTick + delay;
PacketBuffer *buf = new PacketBuffer(pkt, readyTime);
+ DPRINTF(BusBridge, "old sender state: %#X, new sender state: %#X\n",
+ buf->origSenderState, buf);
// If we're about to put this packet at the head of the queue, we
// need to schedule an event to do the transmit. Otherwise there
@@ -126,43 +133,16 @@ Bridge::BridgePort::queueForSendTiming(Packet *pkt)
sendQueue.push_back(buf);
- // Did we just become blocked? If yes, let other side know.
- if (queueFull())
- otherPort->sendStatusChange(Port::Blocked);
-
return true;
}
-
-void
-Bridge::BridgePort::finishSend(PacketBuffer *buf)
-{
- if (buf->expectResponse) {
- // Must wait for response. We just need to count outstanding
- // responses (in case we want to cap them); PacketBuffer
- // pointer will be recovered on response.
- ++outstandingResponses;
- DPRINTF(BusBridge, " successful: awaiting response (%d)\n",
- outstandingResponses);
- } else {
- // no response expected... deallocate packet buffer now.
- DPRINTF(BusBridge, " successful: no response expected\n");
- delete buf;
- }
-
- // If there are more packets to send, schedule event to try again.
- if (!sendQueue.empty()) {
- buf = sendQueue.front();
- sendEvent.schedule(std::max(buf->ready, curTick + 1));
- }
-}
-
-
void
Bridge::BridgePort::trySend()
{
assert(!sendQueue.empty());
+ bool was_full = queueFull();
+
PacketBuffer *buf = sendQueue.front();
assert(buf->ready <= curTick);
@@ -176,20 +156,41 @@ Bridge::BridgePort::trySend()
// send successful
sendQueue.pop_front();
buf->pkt = NULL; // we no longer own packet, so it's not safe to look at it
- finishSend(buf);
+
+ if (buf->expectResponse) {
+ // Must wait for response. We just need to count outstanding
+ // responses (in case we want to cap them); PacketBuffer
+ // pointer will be recovered on response.
+ ++outstandingResponses;
+ DPRINTF(BusBridge, " successful: awaiting response (%d)\n",
+ outstandingResponses);
+ } else {
+ // no response expected... deallocate packet buffer now.
+ DPRINTF(BusBridge, " successful: no response expected\n");
+ delete buf;
+ }
+
+ // If there are more packets to send, schedule event to try again.
+ if (!sendQueue.empty()) {
+ buf = sendQueue.front();
+ sendEvent.schedule(std::max(buf->ready, curTick + 1));
+ }
+ // Let things start sending again
+ if (was_full) {
+ DPRINTF(BusBridge, "Queue was full, sending retry\n");
+ otherPort->sendRetry();
+ }
+
} else {
DPRINTF(BusBridge, " unsuccessful\n");
}
}
-Packet *
+void
Bridge::BridgePort::recvRetry()
{
- PacketBuffer *buf = sendQueue.front();
- Packet *pkt = buf->pkt;
- finishSend(buf);
- return pkt;
+ trySend();
}
/** Function called by the port when the bus is receiving a Atomic
@@ -223,9 +224,6 @@ Bridge::BridgePort::recvFunctional(Packet *pkt)
void
Bridge::BridgePort::recvStatusChange(Port::Status status)
{
- if (status == Port::Blocked || status == Port::Unblocked)
- return;
-
otherPort->sendStatusChange(status);
}
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index 8a5cbf92a..37fb92662 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -24,6 +24,9 @@
* 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: Ali Saidi
+ * Steve Reinhardt
*/
/**
@@ -38,7 +41,6 @@
#include <inttypes.h>
#include <queue>
-
#include "mem/mem_object.hh"
#include "mem/packet.hh"
#include "mem/port.hh"
@@ -77,7 +79,8 @@ class Bridge : public MemObject
origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
expectResponse(_pkt->needsResponse())
{
- pkt->senderState = this;
+ if (!pkt->isResponse())
+ pkt->senderState = this;
}
void fixResponse(Packet *pkt)
@@ -146,7 +149,7 @@ class Bridge : public MemObject
/** When receiving a retry request from the peer port,
pass it to the bridge. */
- virtual Packet* recvRetry();
+ virtual void recvRetry();
/** When receiving a Atomic requestfrom the peer port,
pass it to the bridge. */
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index cfc99a64f..919acd23c 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -24,6 +24,8 @@
* 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: Ali Saidi
*/
/**
@@ -72,9 +74,35 @@ Bus::recvTiming(Packet *pkt)
assert(dest != pkt->getSrc()); // catch infinite loops
port = interfaces[dest];
}
- return port->sendTiming(pkt);
+ if (port->sendTiming(pkt)) {
+ // packet was successfully sent, just return true.
+ return true;
+ }
+
+ // packet not successfully sent
+ retryList.push_back(interfaces[pkt->getSrc()]);
+ return false;
}
+void
+Bus::recvRetry(int id)
+{
+ // Go through all the elements on the list calling sendRetry on each
+ // This is not very efficient at all but it works. Ultimately we should end
+ // up with something that is more intelligent.
+ int initialSize = retryList.size();
+ int i;
+ Port *p;
+
+ for (i = 0; i < initialSize; i++) {
+ assert(retryList.size() > 0);
+ p = retryList.front();
+ retryList.pop_front();
+ p->sendRetry();
+ }
+}
+
+
Port *
Bus::findPort(Addr addr, int id)
{
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 5eeb07904..50bfba6e4 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -24,6 +24,8 @@
* 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: Ron Dreslinski
*/
/**
@@ -67,6 +69,10 @@ class Bus : public MemObject
transaction.*/
void recvFunctional(Packet *pkt);
+ /** Timing function called by port when it is once again able to process
+ * requests. */
+ void recvRetry(int id);
+
/** Function called by the port when the bus is recieving a status change.*/
void recvStatusChange(Port::Status status, int id);
@@ -126,6 +132,11 @@ class Bus : public MemObject
virtual void recvStatusChange(Status status)
{ bus->recvStatusChange(status, id); }
+ /** When reciving a retry from the peer port (at id),
+ pass it to the bus. */
+ virtual void recvRetry()
+ { bus->recvRetry(id); }
+
// This should return all the 'owned' addresses that are
// downstream from this bus, yes? That is, the union of all
// the 'owned' address ranges of all the other interfaces on
@@ -143,6 +154,10 @@ class Bus : public MemObject
connected to this bus.*/
std::vector<Port*> interfaces;
+ /** An array of pointers to ports that retry should be called on because the
+ * original send failed for whatever reason.*/
+ std::list<Port*> retryList;
+
public:
/** A function used to return the port associated with this bus object. */
diff --git a/src/mem/cache/prefetch/tagged_prefetcher_impl.hh b/src/mem/cache/prefetch/tagged_prefetcher_impl.hh
index 6c27256a9..7bdabbe14 100644
--- a/src/mem/cache/prefetch/tagged_prefetcher_impl.hh
+++ b/src/mem/cache/prefetch/tagged_prefetcher_impl.hh
@@ -24,6 +24,8 @@
* 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: Ron Dreslinski
*/
/**
diff --git a/src/mem/config/prefetch.hh b/src/mem/config/prefetch.hh
index 03eb570f0..d24db79da 100644
--- a/src/mem/config/prefetch.hh
+++ b/src/mem/config/prefetch.hh
@@ -24,6 +24,8 @@
* 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: Ron Dreslinski
*/
/**
diff --git a/src/mem/mem_object.cc b/src/mem/mem_object.cc
index f579a0727..d4d3fd283 100644
--- a/src/mem/mem_object.cc
+++ b/src/mem/mem_object.cc
@@ -24,6 +24,8 @@
* 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: Steve Reinhardt
*/
#include "mem/mem_object.hh"
diff --git a/src/mem/mem_object.hh b/src/mem/mem_object.hh
index 58930eccc..ac547619d 100644
--- a/src/mem/mem_object.hh
+++ b/src/mem/mem_object.hh
@@ -24,6 +24,8 @@
* 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: Ron Dreslinski
*/
/**
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index 3b415d77f..56dd2bdfa 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -24,6 +24,9 @@
* 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: Ali Saidi
+ * Steve Reinhardt
*/
/**
@@ -97,20 +100,6 @@ Packet::intersect(Packet *p)
return false;
}
-/** Minimally reset a packet so something like simple cpu can reuse it. */
-void
-Packet::reset()
-{
- result = Unknown;
- if (dynamicData) {
- deleteData();
- dynamicData = false;
- arrayData = false;
- time = curTick;
- }
-}
-
-
bool
fixPacket(Packet *func, Packet *timing)
{
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 83f52ede5..403039d96 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -24,12 +24,15 @@
* 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: Ron Dreslinski
+ * Steve Reinhardt
+ * Ali Saidi
*/
/**
* @file
- * Declaration of the Packet Class, a packet is a transaction occuring
- * between a single level of the memory heirarchy (ie L1->L2).
+ * Declaration of the Packet class.
*/
#ifndef __MEM_PACKET_HH__
@@ -44,81 +47,96 @@ typedef Packet* PacketPtr;
typedef uint8_t* PacketDataPtr;
/**
- * A Packet is the structure to handle requests between two levels
- * of the memory system. The Request is a global object that trancends
- * all of the memory heirarchy, but at each levels interface a packet
- * is created to transfer data/requests. For example, a request would
- * be used to initiate a request to go to memory/IOdevices, as the request
- * passes through the memory system several packets will be created. One
- * will be created to go between the L1 and L2 caches and another to go to
- * the next level and so forth.
- *
- * Packets are assumed to be returned in the case of a single response. If
- * the transaction has no response, then the consumer will delete the packet.
+ * A Packet is used to encapsulate a transfer between two objects in
+ * the memory system (e.g., the L1 and L2 cache). (In contrast, a
+ * single Request travels all the way from the requester to the
+ * ultimate destination and back, possibly being conveyed by several
+ * different Packets along the way.)
*/
class Packet
{
private:
- /** A pointer to the data being transfered. It can be differnt sizes
- at each level of the heirarchy so it belongs in the packet,
- not request. This may or may not be populated when a responder recieves
- the packet. If not populated it memory should be allocated.
+ /** A pointer to the data being transfered. It can be differnt
+ * sizes at each level of the heirarchy so it belongs in the
+ * packet, not request. This may or may not be populated when a
+ * responder recieves the packet. If not populated it memory
+ * should be allocated.
*/
PacketDataPtr data;
- /** Is the data pointer set to a value that shouldn't be freed when the
- * packet is destroyed? */
+ /** Is the data pointer set to a value that shouldn't be freed
+ * when the packet is destroyed? */
bool staticData;
- /** The data pointer points to a value that should be freed when the packet
- * is destroyed. */
+ /** The data pointer points to a value that should be freed when
+ * the packet is destroyed. */
bool dynamicData;
- /** the data pointer points to an array (thus delete [] ) needs to be called
- * on it rather than simply delete.*/
+ /** the data pointer points to an array (thus delete [] ) needs to
+ * be called on it rather than simply delete.*/
bool arrayData;
- /** The address of the request, could be virtual or physical (depending on
- cache configurations). */
+ /** The address of the request. This address could be virtual or
+ * physical, depending on the system configuration. */
Addr addr;
- /** Indicates the size of the request. */
+ /** The size of the request or transfer. */
int size;
- /** A index of the source of the transaction. */
+ /** Device address (e.g., bus ID) of the source of the
+ * transaction. The source is not responsible for setting this
+ * field; it is set implicitly by the interconnect when the
+ * packet * is first sent. */
short src;
- /** A index to the destination of the transaction. */
+ /** Device address (e.g., bus ID) of the destination of the
+ * transaction. The special value Broadcast indicates that the
+ * packet should be routed based on its address. This field is
+ * initialized in the constructor and is thus always valid
+ * (unlike * addr, size, and src). */
short dest;
- bool addrValid;
- bool sizeValid;
+ /** Are the 'addr' and 'size' fields valid? */
+ bool addrSizeValid;
+ /** Is the 'src' field valid? */
bool srcValid;
public:
+ /** The special destination address indicating that the packet
+ * should be routed based on its address. */
static const short Broadcast = -1;
- /** A pointer to the overall request. */
+ /** A pointer to the original request. */
RequestPtr req;
+ /** A virtual base opaque structure used to hold coherence-related
+ * state. A specific subclass would be derived from this to
+ * carry state specific to a particular coherence protocol. */
class CoherenceState {
public:
virtual ~CoherenceState() {}
};
- /** A virtual base opaque structure used to hold
- coherence status messages. */
- CoherenceState *coherence; // virtual base opaque,
- // assert(dynamic_cast<Foo>) etc.
-
+ /** This packet's coherence state. Caches should use
+ * dynamic_cast<> to cast to the state appropriate for the
+ * system's coherence protocol. */
+ CoherenceState *coherence;
+
+ /** A virtual base opaque structure used to hold state associated
+ * with the packet but specific to the sending device (e.g., an
+ * MSHR). A pointer to this state is returned in the packet's
+ * response so that the sender can quickly look up the state
+ * needed to process it. A specific subclass would be derived
+ * from this to carry state specific to a particular sending
+ * device. */
class SenderState {
public:
virtual ~SenderState() {}
};
- /** A virtual base opaque structure used to hold the senders state. */
- SenderState *senderState; // virtual base opaque,
- // assert(dynamic_cast<Foo>) etc.
+ /** This packet's sender state. Devices should use dynamic_cast<>
+ * to cast to the state appropriate to the sender. */
+ SenderState *senderState;
private:
/** List of command attributes. */
@@ -144,9 +162,11 @@ class Packet
WriteResp = IsWrite | IsResponse
};
+ /** Return the string name of the cmd field (for debugging and
+ * tracing). */
const std::string &cmdString() const;
- /** The command of the transaction. */
+ /** The command field of the packet. */
Command cmd;
bool isRead() { return (cmd & IsRead) != 0; }
@@ -154,28 +174,16 @@ class Packet
bool isResponse() { return (cmd & IsResponse) != 0; }
bool needsResponse() { return (cmd & NeedsResponse) != 0; }
- void makeTimingResponse() {
- assert(needsResponse());
- int icmd = (int)cmd;
- icmd &= ~(IsRequest | NeedsResponse);
- icmd |= IsResponse;
- cmd = (Command)icmd;
- dest = src;
- srcValid = false;
- }
-
- /** The time this request was responded to. Used to calculate latencies. */
- Tick time;
-
- /** The result of a particular packets request. */
+ /** Possible results of a packet's request. */
enum Result
{
Success,
BadAddress,
+ Nacked,
Unknown
};
- /** The result of the packet transaction. */
+ /** The result of this packet's request. */
Result result;
/** Accessor function that returns the source index of the packet. */
@@ -187,35 +195,71 @@ class Packet
short getDest() const { return dest; }
void setDest(short _dest) { dest = _dest; }
- Addr getAddr() const { assert(addrValid); return addr; }
- void setAddr(Addr _addr) { addr = _addr; addrValid = true; }
-
- int getSize() const { assert(sizeValid); return size; }
- void setSize(int _size) { size = _size; sizeValid = true; }
-
+ Addr getAddr() const { assert(addrSizeValid); return addr; }
+ int getSize() const { assert(addrSizeValid); return size; }
+ /** Constructor. Note that a Request object must be constructed
+ * first, but the Requests's physical address and size fields
+ * need not be valid. The command and destination addresses
+ * must be supplied. */
Packet(Request *_req, Command _cmd, short _dest)
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
addr(_req->paddr), size(_req->size), dest(_dest),
- addrValid(_req->validPaddr), sizeValid(_req->validSize),
+ addrSizeValid(_req->validPaddr),
srcValid(false),
req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
- time(curTick), result(Unknown)
+ result(Unknown)
{
}
+ /** Destructor. */
~Packet()
{ deleteData(); }
+ /** Reinitialize packet address and size from the associated
+ * Request object, and reset other fields that may have been
+ * modified by a previous transaction. Typically called when a
+ * statically allocated Request/Packet pair is reused for
+ * multiple transactions. */
+ void reinitFromRequest() {
+ assert(req->validPaddr);
+ addr = req->paddr;
+ size = req->size;
+ addrSizeValid = true;
+ result = Unknown;
+ if (dynamicData) {
+ deleteData();
+ dynamicData = false;
+ arrayData = false;
+ }
+ }
- /** Minimally reset a packet so something like simple cpu can reuse it. */
- void reset();
+ /** Take a request packet and modify it in place to be suitable
+ * for returning as a response to that request. Used for timing
+ * accesses only. For atomic and functional accesses, the
+ * request packet is always implicitly passed back *without*
+ * modifying the command or destination fields, so this function
+ * should not be called. */
+ void makeTimingResponse() {
+ assert(needsResponse());
+ int icmd = (int)cmd;
+ icmd &= ~(IsRequest | NeedsResponse);
+ icmd |= IsResponse;
+ cmd = (Command)icmd;
+ dest = src;
+ srcValid = false;
+ }
- void reinitFromRequest() {
- if (req->validPaddr) setAddr(req->paddr);
- if (req->validSize) setSize(req->size);
+ /** Take a request packet that has been returned as NACKED and modify it so
+ * that it can be sent out again. Only packets that need a response can be
+ * NACKED, so verify that that is true. */
+ void reinitNacked() {
+ assert(needsResponse() && result == Nacked);
+ dest = Broadcast;
+ result = Unknown;
}
+
/** Set the data pointer to the following value that should not be freed. */
template <typename T>
void dataStatic(T *p);
diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc
index c4e1ea193..b5cecc7da 100644
--- a/src/mem/page_table.cc
+++ b/src/mem/page_table.cc
@@ -24,6 +24,9 @@
* 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: Steve Reinhardt
+ * Ron Dreslinski
*/
/**
diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh
index 26248261a..f7212d423 100644
--- a/src/mem/page_table.hh
+++ b/src/mem/page_table.hh
@@ -24,6 +24,8 @@
* 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: Steve Reinhardt
*/
/**
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index 26dbef0cd..fb31fb4a3 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -24,6 +24,8 @@
* 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: Ron Dreslinski
*/
#include <sys/types.h>
@@ -139,8 +141,7 @@ Tick
PhysicalMemory::doAtomicAccess(Packet *pkt)
{
doFunctionalAccess(pkt);
- pkt->time = curTick + lat;
- return curTick + lat;
+ return lat;
}
void
diff --git a/src/mem/physical.hh b/src/mem/physical.hh
index 2ced79045..88ea543da 100644
--- a/src/mem/physical.hh
+++ b/src/mem/physical.hh
@@ -24,6 +24,8 @@
* 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: Ron Dreslinski
*/
/* @file
diff --git a/src/mem/port.cc b/src/mem/port.cc
index 651cb739a..bec9d2274 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -24,6 +24,8 @@
* 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: Steve Reinhardt
*/
/**
@@ -45,13 +47,12 @@ Port::setPeer(Port *port)
void
Port::blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd)
{
- Request req(false);
+ Request req;
Packet pkt(&req, cmd, Packet::Broadcast);
for (ChunkGenerator gen(addr, size, peerBlockSize());
!gen.done(); gen.next()) {
- req.setPaddr(gen.addr());
- req.setSize(gen.size());
+ req.setPhys(gen.addr(), gen.size(), 0);
pkt.reinitFromRequest();
pkt.dataStatic(p);
sendFunctional(&pkt);
diff --git a/src/mem/port.hh b/src/mem/port.hh
index f9103865e..2edad095e 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -24,6 +24,8 @@
* 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: Ron Dreslinski
*/
/**
@@ -74,6 +76,11 @@ class Port
/** Descriptive name (for DPRINTF output) */
const std::string portName;
+ /** A pointer to the peer port. Ports always come in pairs, that way they
+ can use a standardized interface to communicate between different
+ memory objects. */
+ Port *peer;
+
public:
/**
@@ -83,7 +90,7 @@ class Port
* of memory system object to which the port belongs.
*/
Port(const std::string &_name)
- : portName(_name)
+ : portName(_name), peer(NULL)
{ }
/** Return port name (for DPRINTF). */
@@ -92,23 +99,12 @@ class Port
virtual ~Port() {};
// mey be better to use subclasses & RTTI?
- /** Holds the ports status. Keeps track if it is blocked, or has
- calculated a range change. */
+ /** Holds the ports status. Currently just that a range recomputation needs
+ * to be done. */
enum Status {
- Blocked,
- Unblocked,
RangeChange
};
- private:
-
- /** A pointer to the peer port. Ports always come in pairs, that way they
- can use a standardized interface to communicate between different
- memory objects. */
- Port *peer;
-
- public:
-
/** Function to set the pointer for the peer port.
@todo should be called by the configuration stuff (python).
*/
@@ -140,7 +136,7 @@ class Port
wait. This shouldn't be valid for response paths (IO Devices).
so it is set to panic if it isn't already defined.
*/
- virtual Packet *recvRetry() { panic("??"); }
+ virtual void recvRetry() { panic("??"); }
/** Called by a peer port in order to determine the block size of the
device connected to this port. It sometimes doesn't make sense for
@@ -165,16 +161,17 @@ class Port
port receive function.
@return This function returns if the send was succesful in it's
recieve. If it was a failure, then the port will wait for a recvRetry
- at which point it can issue a successful sendTiming. This is used in
+ at which point it can possibly issue a successful sendTiming. This is used in
case a cache has a higher priority request come in while waiting for
the bus to arbitrate.
*/
bool sendTiming(Packet *pkt) { return peer->recvTiming(pkt); }
- /** Function called by the associated device to send an atomic access,
- an access in which the data is moved and the state is updated in one
- cycle, without interleaving with other memory accesses.
- */
+ /** Function called by the associated device to send an atomic
+ * access, an access in which the data is moved and the state is
+ * updated in one cycle, without interleaving with other memory
+ * accesses. Returns estimated latency of access.
+ */
Tick sendAtomic(Packet *pkt)
{ return peer->recvAtomic(pkt); }
@@ -194,7 +191,7 @@ class Port
/** When a timing access doesn't return a success, some time later the
Retry will be sent.
*/
- Packet *sendRetry() { return peer->recvRetry(); }
+ void sendRetry() { return peer->recvRetry(); }
/** Called by the associated device if it wishes to find out the blocksize
of the device on attached to the peer port.
@@ -252,6 +249,14 @@ class FunctionalPort : public Port
virtual void recvFunctional(Packet *pkt) { panic("FuncPort is UniDir"); }
virtual void recvStatusChange(Status status) {}
+ /** a write function that also does an endian conversion. */
+ template <typename T>
+ inline void writeHtoG(Addr addr, T d);
+
+ /** a read function that also does an endian conversion. */
+ template <typename T>
+ inline T readGtoH(Addr addr);
+
template <typename T>
inline void write(Addr addr, T d)
{
diff --git a/src/mem/port_impl.hh b/src/mem/port_impl.hh
new file mode 100644
index 000000000..e9a159293
--- /dev/null
+++ b/src/mem/port_impl.hh
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+#include "arch/isa_specific.hh"
+#include "arch/isa_traits.hh"
+#include "mem/port.hh"
+#include "sim/byteswap.hh"
+
+template <typename T>
+void
+FunctionalPort::writeHtoG(Addr addr, T d)
+{
+ d = TheISA::htog(d);
+ writeBlob(addr, (uint8_t*)&d, sizeof(T));
+}
+
+
+template <typename T>
+T
+FunctionalPort::readGtoH(Addr addr)
+{
+ T d;
+ readBlob(addr, (uint8_t*)&d, sizeof(T));
+ return TheISA::gtoh(d);
+}
+
diff --git a/src/mem/request.hh b/src/mem/request.hh
index 10550e859..af1d6d8a8 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -24,6 +24,10 @@
* 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: Ron Dreslinski
+ * Steve Reinhardt
+ * Ali Saidi
*/
/**
@@ -61,139 +65,164 @@ const unsigned NO_ALIGN_FAULT = 0x400;
class Request
{
- //@todo Make Accesor functions, make these private.
- public:
- /** Constructor, needs a bool to signify if it is/isn't Cpu Request. */
- Request(bool isCpu);
-
- /** reset the request to it's initial state so it can be reused.*/
- void resetAll(bool isCpu);
-
- /** reset the request's addrs times, etc, so but not everything to same
- * time. */
- void resetMin();
-
-//First non-cpu request fields
private:
- /** The physical address of the request. */
+ /**
+ * The physical address of the request. Valid only if validPaddr
+ * is set. */
Addr paddr;
- /** Wether or not paddr is valid (has been written yet). */
- bool validPaddr;
- /** The size of the request. */
+ /**
+ * The size of the request. This field must be set when vaddr or
+ * paddr is written via setVirt() or setPhys(), so it is always
+ * valid as long as one of the address fields is valid. */
int size;
- /** Wether or not size is valid (has been written yet). */
- bool validSize;
-
- /** The time this request was started. Used to calculate latencies. */
- Tick time;
- /** Wether or not time is valid (has been written yet). */
- bool validTime;
-
- /** Destination address if this is a block copy. */
- Addr copyDest;
- /** Wether or not copyDest is valid (has been written yet). */
- bool validCopyDest;
/** Flag structure for the request. */
uint32_t flags;
-//Accsesors for non-cpu request fields
- public:
- /** Accesor for paddr. */
- Addr getPaddr();
- /** Accesor for paddr. */
- void setPaddr(Addr _paddr);
-
- /** Accesor for size. */
- int getSize();
- /** Accesor for size. */
- void setSize(int _size);
-
- /** Accesor for time. */
- Tick getTime();
- /** Accesor for time. */
- void setTime(Tick _time);
-
- /** Accesor for copy dest. */
- Addr getCopyDest();
- /** Accesor for copy dest. */
- void setCopyDest(Addr _copyDest);
-
- /** Accesor for flags. */
- uint32_t getFlags();
- /** Accesor for paddr. */
- void setFlags(uint32_t _flags);
-
-//Now cpu-request fields
- private:
- /** Bool to signify if this is a cpuRequest. */
- bool cpuReq;
-
- /** The virtual address of the request. */
- Addr vaddr;
- /** Wether or not the vaddr is valid. */
- bool validVaddr;
+ /**
+ * The time this request was started. Used to calculate
+ * latencies. This field is set to curTick any time paddr or vaddr
+ * is written. */
+ Tick time;
/** The address space ID. */
int asid;
- /** Wether or not the asid is valid. */
- bool validAsid;
+ /** The virtual address of the request. */
+ Addr vaddr;
/** The return value of store conditional. */
uint64_t scResult;
- /** Wether or not the sc result is valid. */
- bool validScResult;
- /** The cpu number for statistics. */
+ /** The cpu number (for statistics, typically). */
int cpuNum;
- /** Wether or not the cpu number is valid. */
- bool validCpuNum;
-
- /** The requesting thread id. */
+ /** The requesting thread id (for statistics, typically). */
int threadNum;
- /** Wether or not the thread id is valid. */
- bool validThreadNum;
/** program counter of initiating access; for tracing/debugging */
Addr pc;
- /** Wether or not the pc is valid. */
+
+ /** Whether or not paddr is valid (has been written yet). */
+ bool validPaddr;
+ /** Whether or not the asid & vaddr are valid. */
+ bool validAsidVaddr;
+ /** Whether or not the sc result is valid. */
+ bool validScResult;
+ /** Whether or not the cpu number & thread ID are valid. */
+ bool validCpuAndThreadNums;
+ /** Whether or not the pc is valid. */
bool validPC;
-//Accessor Functions for cpu request fields
public:
- /** Accesor function to determine if this is a cpu request or not.*/
- bool isCpuRequest();
-
- /** Accesor function for vaddr.*/
- Addr getVaddr();
- /** Accesor function for vaddr.*/
- void setVaddr(Addr _vaddr);
-
- /** Accesor function for asid.*/
- int getAsid();
- /** Accesor function for asid.*/
- void setAsid(int _asid);
-
- /** Accesor function for store conditional return value.*/
- uint64_t getScResult();
- /** Accesor function for store conditional return value.*/
- void setScResult(uint64_t _scResult);
-
- /** Accesor function for cpu number.*/
- int getCpuNum();
- /** Accesor function for cpu number.*/
- void setCpuNum(int _cpuNum);
-
- /** Accesor function for thread number.*/
- int getThreadNum();
- /** Accesor function for thread number.*/
- void setThreadNum(int _threadNum);
-
- /** Accesor function for pc.*/
- Addr getPC();
- /** Accesor function for pc.*/
- void setPC(Addr _pc);
+ /** Minimal constructor. No fields are initialized. */
+ Request()
+ : validPaddr(false), validAsidVaddr(false),
+ validScResult(false), validCpuAndThreadNums(false), validPC(false)
+ {}
+
+ /**
+ * Constructor for physical (e.g. device) requests. Initializes
+ * just physical address, size, flags, and timestamp (to curTick).
+ * These fields are adequate to perform a request. */
+ Request(Addr _paddr, int _size, int _flags)
+ : validCpuAndThreadNums(false)
+ { setPhys(_paddr, _size, _flags); }
+
+ Request(int _asid, Addr _vaddr, int _size, int _flags, Addr _pc,
+ int _cpuNum, int _threadNum)
+ {
+ setThreadContext(_cpuNum, _threadNum);
+ setVirt(_asid, _vaddr, _size, _flags, _pc);
+ }
+
+ /**
+ * Set up CPU and thread numbers. */
+ void setThreadContext(int _cpuNum, int _threadNum)
+ {
+ cpuNum = _cpuNum;
+ threadNum = _threadNum;
+ validCpuAndThreadNums = true;
+ }
+
+ /**
+ * Set up a physical (e.g. device) request in a previously
+ * allocated Request object. */
+ void setPhys(Addr _paddr, int _size, int _flags)
+ {
+ paddr = _paddr;
+ size = _size;
+ flags = _flags;
+ time = curTick;
+ validPaddr = true;
+ validAsidVaddr = false;
+ validPC = false;
+ validScResult = false;
+ }
+
+ /**
+ * Set up a virtual (e.g., CPU) request in a previously
+ * allocated Request object. */
+ void setVirt(int _asid, Addr _vaddr, int _size, int _flags, Addr _pc)
+ {
+ asid = _asid;
+ vaddr = _vaddr;
+ size = _size;
+ flags = _flags;
+ pc = _pc;
+ time = curTick;
+ validPaddr = false;
+ validAsidVaddr = true;
+ validPC = true;
+ validScResult = false;
+ }
+
+ /** Set just the physical address. This should only be used to
+ * record the result of a translation, and thus the vaddr must be
+ * valid before this method is called. Otherwise, use setPhys()
+ * to guarantee that the size and flags are also set.
+ */
+ void setPaddr(Addr _paddr)
+ {
+ assert(validAsidVaddr);
+ paddr = _paddr;
+ validPaddr = true;
+ }
+
+ /** Accessor for paddr. */
+ Addr getPaddr() { assert(validPaddr); return paddr; }
+
+ /** Accessor for size. */
+ int getSize() { assert(validPaddr || validAsidVaddr); return size; }
+ /** Accessor for time. */
+ Tick getTime() { assert(validPaddr || validAsidVaddr); return time; }
+
+ /** Accessor for flags. */
+ uint32_t getFlags() { assert(validPaddr || validAsidVaddr); return flags; }
+ /** Accessor for paddr. */
+ void setFlags(uint32_t _flags)
+ { assert(validPaddr || validAsidVaddr); flags = _flags; }
+
+ /** Accessor function for vaddr.*/
+ Addr getVaddr() { assert(validAsidVaddr); return vaddr; }
+
+ /** Accessor function for asid.*/
+ int getAsid() { assert(validAsidVaddr); return asid; }
+
+ /** Accessor function to check if sc result is valid. */
+ bool scResultValid() { return validScResult; }
+ /** Accessor function for store conditional return value.*/
+ uint64_t getScResult() { assert(validScResult); return scResult; }
+ /** Accessor function for store conditional return value.*/
+ void setScResult(uint64_t _scResult)
+ { scResult = _scResult; validScResult = true; }
+
+ /** Accessor function for cpu number.*/
+ int getCpuNum() { assert(validCpuAndThreadNums); return cpuNum; }
+ /** Accessor function for thread number.*/
+ int getThreadNum() { assert(validCpuAndThreadNums); return threadNum; }
+
+ /** Accessor function for pc.*/
+ Addr getPC() { assert(validPC); return pc; }
friend class Packet;
};
diff --git a/src/mem/translating_port.cc b/src/mem/translating_port.cc
index ee4d277b6..d2c854086 100644
--- a/src/mem/translating_port.cc
+++ b/src/mem/translating_port.cc
@@ -24,6 +24,9 @@
* 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: Ron Dreslinski
+ * Steve Reinhardt
*/
#include <string>
diff --git a/src/mem/translating_port.hh b/src/mem/translating_port.hh
index d078158a3..7354278ba 100644
--- a/src/mem/translating_port.hh
+++ b/src/mem/translating_port.hh
@@ -24,6 +24,9 @@
* 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: Ron Dreslinski
+ * Ali Saidi
*/
#ifndef __MEM_TRANSLATING_PROT_HH__
diff --git a/src/mem/vport.cc b/src/mem/vport.cc
index cc569acf3..cd297bb8e 100644
--- a/src/mem/vport.cc
+++ b/src/mem/vport.cc
@@ -24,6 +24,8 @@
* 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: Ali Saidi
*/
/**
@@ -40,8 +42,8 @@ VirtualPort::readBlob(Addr addr, uint8_t *p, int size)
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
gen.next())
{
- if (xc)
- paddr = TheISA::vtophys(xc,gen.addr());
+ if (tc)
+ paddr = TheISA::vtophys(tc,gen.addr());
else
paddr = TheISA::vtophys(gen.addr());
@@ -57,8 +59,8 @@ VirtualPort::writeBlob(Addr addr, uint8_t *p, int size)
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
gen.next())
{
- if (xc)
- paddr = TheISA::vtophys(xc,gen.addr());
+ if (tc)
+ paddr = TheISA::vtophys(tc,gen.addr());
else
paddr = TheISA::vtophys(gen.addr());
diff --git a/src/mem/vport.hh b/src/mem/vport.hh
index 0f3b1f09e..697c8e5f3 100644
--- a/src/mem/vport.hh
+++ b/src/mem/vport.hh
@@ -24,6 +24,8 @@
* 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: Ali Saidi
*/
/**
@@ -36,13 +38,13 @@
#ifndef __MEM_VPORT_HH__
#define __MEM_VPORT_HH__
-#include "mem/port.hh"
+#include "mem/port_impl.hh"
#include "config/full_system.hh"
#include "arch/vtophys.hh"
/** A class that translates a virtual address to a physical address and then
- * calls the above read/write functions. If an execution context is provided the
+ * calls the above read/write functions. If a thread context is provided the
* address can alway be translated, If not it can only be translated if it is a
* simple address masking operation (such as alpha super page accesses).
*/
@@ -50,18 +52,19 @@
class VirtualPort : public FunctionalPort
{
private:
- ExecContext *xc;
+ ThreadContext *tc;
public:
- VirtualPort(const std::string &_name, ExecContext *_xc = NULL)
- : FunctionalPort(_name), xc(_xc)
+ VirtualPort(const std::string &_name, ThreadContext *_tc = NULL)
+ : FunctionalPort(_name), tc(_tc)
{}
- /** Return true if we have an exec context. This is used to prevent someone
- * from accidently deleting the cpus statically allocated vport.
- * @return true if an execution context isn't valid
+ /** Return true if we have an thread context. This is used to
+ * prevent someone from accidently deleting the cpus statically
+ * allocated vport.
+ * @return true if a thread context isn't valid
*/
- bool nullExecContext() { return xc != NULL; }
+ bool nullThreadContext() { return tc != NULL; }
/** Version of readblob that translates virt->phys and deals
* with page boundries. */