summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorWilliam Wang <william.wang@arm.com>2012-03-30 09:40:11 -0400
committerWilliam Wang <william.wang@arm.com>2012-03-30 09:40:11 -0400
commitf9d403a7b95c50a8b75f8442101eb87ca465f967 (patch)
treea8302eb02dd5947d53b9437cc19d552145267189 /src/arch
parenta14013af3a9e04d68985aea7bcff6c1e70bdbb82 (diff)
downloadgem5-f9d403a7b95c50a8b75f8442101eb87ca465f967.tar.xz
MEM: Introduce the master/slave port sub-classes in C++
This patch introduces the notion of a master and slave port in the C++ code, thus bringing the previous classification from the Python classes into the corresponding simulation objects and memory objects. The patch enables us to classify behaviours into the two bins and add assumptions and enfore compliance, also simplifying the two interfaces. As a starting point, isSnooping is confined to a master port, and getAddrRanges to slave ports. More of these specilisations are to come in later patches. The getPort function is not getMasterPort and getSlavePort, and returns a port reference rather than a pointer as NULL would never be a valid return value. The default implementation of these two functions is placed in MemObject, and calls fatal. The one drawback with this specific patch is that it requires some code duplication, e.g. QueuedPort becomes QueuedMasterPort and QueuedSlavePort, and BusPort becomes BusMasterPort and BusSlavePort (avoiding multiple inheritance). With the later introduction of the port interfaces, moving the functionality outside the port itself, a lot of the duplicated code will disappear again.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/arm/table_walker.cc8
-rw-r--r--src/arch/arm/table_walker.hh3
-rw-r--r--src/arch/arm/tlb.cc6
-rw-r--r--src/arch/arm/tlb.hh13
-rw-r--r--src/arch/x86/interrupts.cc17
-rw-r--r--src/arch/x86/interrupts.hh21
-rw-r--r--src/arch/x86/pagetable_walker.cc13
-rw-r--r--src/arch/x86/pagetable_walker.hh9
-rw-r--r--src/arch/x86/tlb.cc6
-rw-r--r--src/arch/x86/tlb.hh12
10 files changed, 70 insertions, 38 deletions
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 8bffe68f8..73a691cff 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -91,13 +91,13 @@ TableWalker::resume()
}
}
-Port*
-TableWalker::getPort(const std::string &if_name, int idx)
+MasterPort&
+TableWalker::getMasterPort(const std::string &if_name, int idx)
{
if (if_name == "port") {
- return &port;
+ return port;
}
- return NULL;
+ return MemObject::getMasterPort(if_name, idx);
}
Fault
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index b5099bb27..a6ff2585b 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -358,7 +358,8 @@ class TableWalker : public MemObject
virtual unsigned int drain(Event *de);
virtual void resume();
- virtual Port *getPort(const std::string &if_name, int idx = -1);
+ virtual MasterPort& getMasterPort(const std::string &if_name,
+ int idx = -1);
Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
TLB::Translation *_trans, bool timing, bool functional = false);
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 0b003e9fb..f9b2e6fe7 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -722,10 +722,10 @@ TLB::translateTiming(RequestPtr req, ThreadContext *tc,
return fault;
}
-Port*
-TLB::getPort()
+MasterPort*
+TLB::getMasterPort()
{
- return tableWalker->getPort("port");
+ return &tableWalker->getMasterPort("port");
}
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index daf59f01d..a20957f6a 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -214,8 +214,17 @@ class TLB : public BaseTLB
void regStats();
- // Get the port from the table walker and return it
- virtual Port *getPort();
+ /**
+ * Get the table walker master port. This is used for migrating
+ * port connections during a CPU takeOverFrom() call. For
+ * architectures that do not have a table walker, NULL is
+ * returned, hence the use of a pointer rather than a
+ * reference. For ARM this method will always return a valid port
+ * pointer.
+ *
+ * @return A pointer to the walker master port
+ */
+ virtual MasterPort* getMasterPort();
// Caching misc register values here.
// Writing to misc registers needs to invalidate them.
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
index 6a9f07af2..a422a4758 100644
--- a/src/arch/x86/interrupts.cc
+++ b/src/arch/x86/interrupts.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2008 The Hewlett-Packard Development Company
* All rights reserved.
*
@@ -304,6 +316,9 @@ X86ISA::Interrupts::init()
//
BasicPioDevice::init();
IntDev::init();
+
+ // the slave port has a range so inform the connected master
+ intSlavePort.sendRangeChange();
}
@@ -554,7 +569,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
break;
}
pendingIPIs += apics.size();
- intPort.sendMessage(apics, message, timing);
+ intMasterPort.sendMessage(apics, message, timing);
newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
}
break;
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
index abf3040bd..328e7159d 100644
--- a/src/arch/x86/interrupts.hh
+++ b/src/arch/x86/interrupts.hh
@@ -189,7 +189,7 @@ class Interrupts : public BasicPioDevice, IntDev
int initialApicId;
// Port for receiving interrupts
- IntPort intSlavePort;
+ IntSlavePort intSlavePort;
public:
@@ -239,17 +239,20 @@ class Interrupts : public BasicPioDevice, IntDev
AddrRangeList getAddrRanges();
AddrRangeList getIntAddrRange();
- Port *getPort(const std::string &if_name, int idx = -1)
+ MasterPort &getMasterPort(const std::string &if_name, int idx = -1)
{
- // a bit of an odd one since there is now two ports in the
- // Python class we also need two ports even if they are
- // identical
if (if_name == "int_master") {
- return &intPort;
- } else if (if_name == "int_slave") {
- return &intSlavePort;
+ return intMasterPort;
}
- return BasicPioDevice::getPort(if_name, idx);
+ return BasicPioDevice::getMasterPort(if_name, idx);
+ }
+
+ SlavePort &getSlavePort(const std::string &if_name, int idx = -1)
+ {
+ if (if_name == "int_slave") {
+ return intSlavePort;
+ }
+ return BasicPioDevice::getSlavePort(if_name, idx);
}
/*
diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc
index f29531cd5..87505f4df 100644
--- a/src/arch/x86/pagetable_walker.cc
+++ b/src/arch/x86/pagetable_walker.cc
@@ -154,11 +154,6 @@ Walker::WalkerPort::recvFunctional(PacketPtr pkt)
}
void
-Walker::WalkerPort::recvRangeChange()
-{
-}
-
-void
Walker::WalkerPort::recvRetry()
{
walker->recvRetry();
@@ -182,13 +177,13 @@ bool Walker::sendTiming(WalkerState* sendingState, PacketPtr pkt)
return port.sendTiming(pkt);
}
-Port *
-Walker::getPort(const std::string &if_name, int idx)
+MasterPort &
+Walker::getMasterPort(const std::string &if_name, int idx)
{
if (if_name == "port")
- return &port;
+ return port;
else
- panic("No page table walker port named %s!\n", if_name);
+ return MemObject::getMasterPort(if_name, idx);
}
void
diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh
index 90f075280..bf7a9e615 100644
--- a/src/arch/x86/pagetable_walker.hh
+++ b/src/arch/x86/pagetable_walker.hh
@@ -60,11 +60,11 @@ namespace X86ISA
{
protected:
// Port for accessing memory
- class WalkerPort : public Port
+ class WalkerPort : public MasterPort
{
public:
WalkerPort(const std::string &_name, Walker * _walker) :
- Port(_name, _walker), walker(_walker)
+ MasterPort(_name, _walker), walker(_walker)
{}
protected:
@@ -73,9 +73,8 @@ namespace X86ISA
bool recvTiming(PacketPtr pkt);
Tick recvAtomic(PacketPtr pkt);
void recvFunctional(PacketPtr pkt);
- void recvRangeChange();
void recvRetry();
- bool isSnooping() { return true; }
+ bool isSnooping() const { return true; }
};
friend class WalkerPort;
@@ -166,7 +165,7 @@ namespace X86ISA
RequestPtr req, BaseTLB::Mode mode);
Fault startFunctional(ThreadContext * _tc, Addr &addr,
Addr &pageSize, BaseTLB::Mode mode);
- Port *getPort(const std::string &if_name, int idx = -1);
+ MasterPort &getMasterPort(const std::string &if_name, int idx = -1);
protected:
// The TLB we're supposed to load.
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index 10ef217e1..89561f851 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -428,10 +428,10 @@ TLB::unserialize(Checkpoint *cp, const std::string &section)
{
}
-Port *
-TLB::getPort()
+MasterPort *
+TLB::getMasterPort()
{
- return walker->getPort("port");
+ return &walker->getMasterPort("port");
}
} // namespace X86ISA
diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh
index 078b8b8d6..bcadda762 100644
--- a/src/arch/x86/tlb.hh
+++ b/src/arch/x86/tlb.hh
@@ -125,7 +125,17 @@ namespace X86ISA
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
- virtual Port * getPort();
+ /**
+ * Get the table walker master port. This is used for
+ * migrating port connections during a CPU takeOverFrom()
+ * call. For architectures that do not have a table walker,
+ * NULL is returned, hence the use of a pointer rather than a
+ * reference. For X86 this method will always return a valid
+ * port pointer.
+ *
+ * @return A pointer to the walker master port
+ */
+ virtual MasterPort *getMasterPort();
};
}