summaryrefslogtreecommitdiff
path: root/src/cpu/simple/timing.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/simple/timing.cc')
-rw-r--r--src/cpu/simple/timing.cc87
1 files changed, 53 insertions, 34 deletions
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index dfffb0b1f..45da7c3eb 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -30,6 +30,7 @@
#include "arch/locked_mem.hh"
#include "arch/utility.hh"
+#include "base/bigint.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/timing.hh"
#include "mem/packet.hh"
@@ -193,7 +194,7 @@ TimingSimpleCPU::switchOut()
void
TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
{
- BaseCPU::takeOverFrom(oldCPU);
+ BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
// if any of this CPU's ThreadContexts are active, mark the CPU as
// running and schedule its tick event.
@@ -208,23 +209,6 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
if (_status != Running) {
_status = Idle;
}
-
- Port *peer;
- if (icachePort.getPeer() == NULL) {
- peer = oldCPU->getPort("icache_port")->getPeer();
- icachePort.setPeer(peer);
- } else {
- peer = icachePort.getPeer();
- }
- peer->setPeer(&icachePort);
-
- if (dcachePort.getPeer() == NULL) {
- peer = oldCPU->getPort("dcache_port")->getPeer();
- dcachePort.setPeer(peer);
- } else {
- peer = dcachePort.getPeer();
- }
- peer->setPeer(&dcachePort);
}
@@ -239,12 +223,6 @@ TimingSimpleCPU::activateContext(int thread_num, int delay)
notIdleFraction++;
_status = Running;
-#if FULL_SYSTEM
- // Connect the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- tc->connectMemPorts();
-#endif
-
// kick things off by initiating the fetch of the next instruction
fetchEvent =
new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false);
@@ -286,7 +264,7 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// Now do the access.
if (fault == NoFault) {
PacketPtr pkt =
- new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
pkt->dataDynamic<T>(new T);
if (!dcachePort.sendTiming(pkt)) {
@@ -297,14 +275,14 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// memory system takes ownership of packet
dcache_pkt = NULL;
}
+
+ // This will need a new way to tell if it has a dcache attached.
+ if (req->isUncacheable())
+ recordEvent("Uncached Read");
} else {
delete req;
}
- // This will need a new way to tell if it has a dcache attached.
- if (req->isUncacheable())
- recordEvent("Uncached Read");
-
return fault;
}
@@ -312,6 +290,14 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
template
Fault
+TimingSimpleCPU::read(Addr addr, Twin64_t &data, unsigned flags);
+
+template
+Fault
+TimingSimpleCPU::read(Addr addr, Twin32_t &data, unsigned flags);
+
+template
+Fault
TimingSimpleCPU::read(Addr addr, uint64_t &data, unsigned flags);
template
@@ -359,13 +345,20 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(),
cpu_id, /* thread ID */ 0);
+ if (traceData) {
+ traceData->setAddr(req->getVaddr());
+ }
+
// translate to physical address
Fault fault = thread->translateDataWriteReq(req);
// Now do the access.
if (fault == NoFault) {
assert(dcache_pkt == NULL);
- dcache_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ if (req->isSwap())
+ dcache_pkt = new Packet(req, MemCmd::SwapReq, Packet::Broadcast);
+ else
+ dcache_pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
dcache_pkt->allocate();
dcache_pkt->set(data);
@@ -374,6 +367,10 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
if (req->isLocked()) {
do_access = TheISA::handleLockedWrite(thread, req);
}
+ if (req->isCondSwap()) {
+ assert(res);
+ req->setExtraData(*res);
+ }
if (do_access) {
if (!dcachePort.sendTiming(dcache_pkt)) {
@@ -384,13 +381,13 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
dcache_pkt = NULL;
}
}
+ // This will need a new way to tell if it's hooked up to a cache or not.
+ if (req->isUncacheable())
+ recordEvent("Uncached Write");
} else {
delete req;
}
- // This will need a new way to tell if it's hooked up to a cache or not.
- if (req->isUncacheable())
- recordEvent("Uncached Write");
// If the write needs to have a fault on the access, consider calling
// changeStatus() and changing it to "bad addr write" or something.
@@ -401,6 +398,16 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template
Fault
+TimingSimpleCPU::write(Twin32_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
+template
+Fault
+TimingSimpleCPU::write(Twin64_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
+template
+Fault
TimingSimpleCPU::write(uint64_t data, Addr addr,
unsigned flags, uint64_t *res);
@@ -454,7 +461,7 @@ TimingSimpleCPU::fetch()
ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0);
Fault fault = setupFetchRequest(ifetch_req);
- ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
+ ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
ifetch_pkt->dataStatic(&inst);
if (fault == NoFault) {
@@ -629,6 +636,18 @@ TimingSimpleCPU::completeDrain()
drainEvent->process();
}
+void
+TimingSimpleCPU::DcachePort::setPeer(Port *port)
+{
+ Port::setPeer(port);
+
+#if FULL_SYSTEM
+ // Update the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ cpu->tcBase()->connectMemPorts();
+#endif
+}
+
bool
TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
{