/*
+ * 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) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
#include "debug/SimpleCPU.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
+#include "mem/physical.hh"
#include "params/AtomicSimpleCPU.hh"
#include "sim/faults.hh"
#include "sim/system.hh"
+#include "sim/full_system.hh"
using namespace std;
using namespace TheISA;
return "AtomicSimpleCPU tick";
}
-Port *
-AtomicSimpleCPU::getPort(const string &if_name, int idx)
-{
- if (if_name == "dcache_port")
- return &dcachePort;
- else if (if_name == "icache_port")
- return &icachePort;
- else if (if_name == "physmem_port") {
- hasPhysMemPort = true;
- return &physmemPort;
- }
- else
- panic("No Such Port\n");
-}
-
void
AtomicSimpleCPU::init()
{
BaseCPU::init();
-#if FULL_SYSTEM
- ThreadID size = threadContexts.size();
- for (ThreadID i = 0; i < size; ++i) {
- ThreadContext *tc = threadContexts[i];
-
- // initialize CPU, including PC
- TheISA::initCPU(tc, tc->contextId());
- }
// Initialise the ThreadContext's memory proxies
tcBase()->initMemProxies(tcBase());
-#endif
- if (hasPhysMemPort) {
- AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges();
- physMemAddr = *pmAddrList.begin();
+
+ if (FullSystem && !params()->defer_registration) {
+ ThreadID size = threadContexts.size();
+ for (ThreadID i = 0; i < size; ++i) {
+ ThreadContext *tc = threadContexts[i];
+ // initialize CPU, including PC
+ TheISA::initCPU(tc, tc->contextId());
+ }
}
+
// Atomic doesn't do MT right now, so contextId == threadId
ifetch_req.setThreadContext(_cpuId, 0); // Add thread ID if we add MT
data_read_req.setThreadContext(_cpuId, 0); // Add thread ID here too
simulate_data_stalls(p->simulate_data_stalls),
simulate_inst_stalls(p->simulate_inst_stalls),
icachePort(name() + "-iport", this), dcachePort(name() + "-iport", this),
- physmemPort(name() + "-iport", this), hasPhysMemPort(false)
+ fastmem(p->fastmem)
{
_status = Idle;
}
void
AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
{
- BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
+ BaseCPU::takeOverFrom(oldCPU);
assert(!tickEvent.scheduled());
void
-AtomicSimpleCPU::activateContext(int thread_num, int delay)
+AtomicSimpleCPU::activateContext(ThreadID thread_num, int delay)
{
DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay);
void
-AtomicSimpleCPU::suspendContext(int thread_num)
+AtomicSimpleCPU::suspendContext(ThreadID thread_num)
{
DPRINTF(SimpleCPU, "SuspendContext %d\n", thread_num);
dcache_latency = 0;
while (1) {
- req->setVirt(0, addr, size, flags, thread->pcState().instAddr());
+ req->setVirt(0, addr, size, flags, dataMasterId(), thread->pcState().instAddr());
// translate to physical address
Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Read);
// Now do the access.
if (fault == NoFault && !req->getFlags().isSet(Request::NO_ACCESS)) {
Packet pkt = Packet(req,
- req->isLLSC() ? MemCmd::LoadLockedReq : MemCmd::ReadReq,
- Packet::Broadcast);
+ req->isLLSC() ? MemCmd::LoadLockedReq :
+ MemCmd::ReadReq);
pkt.dataStatic(data);
if (req->isMmappedIpr())
dcache_latency += TheISA::handleIprRead(thread->getTC(), &pkt);
else {
- if (hasPhysMemPort && pkt.getAddr() == physMemAddr)
- dcache_latency += physmemPort.sendAtomic(&pkt);
+ if (fastmem && system->isMemAddr(pkt.getAddr()))
+ system->getPhysMem().access(&pkt);
else
dcache_latency += dcachePort.sendAtomic(&pkt);
}
dcache_latency = 0;
while(1) {
- req->setVirt(0, addr, size, flags, thread->pcState().instAddr());
+ req->setVirt(0, addr, size, flags, dataMasterId(), thread->pcState().instAddr());
// translate to physical address
Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Write);
}
if (do_access && !req->getFlags().isSet(Request::NO_ACCESS)) {
- Packet pkt = Packet(req, cmd, Packet::Broadcast);
+ Packet pkt = Packet(req, cmd);
pkt.dataStatic(data);
if (req->isMmappedIpr()) {
dcache_latency +=
TheISA::handleIprWrite(thread->getTC(), &pkt);
} else {
- if (hasPhysMemPort && pkt.getAddr() == physMemAddr)
- dcache_latency += physmemPort.sendAtomic(&pkt);
+ if (fastmem && system->isMemAddr(pkt.getAddr()))
+ system->getPhysMem().access(&pkt);
else
dcache_latency += dcachePort.sendAtomic(&pkt);
}
dcache_access = false; // assume no dcache access
if (needToFetch) {
- // This is commented out because the predecoder would act like
+ // This is commented out because the decoder would act like
// a tiny cache otherwise. It wouldn't be flushed when needed
// like the I cache. It should be flushed, and when that works
// this code should be uncommented.
//Fetch more instruction memory if necessary
- //if(predecoder.needMoreBytes())
+ //if(decoder.needMoreBytes())
//{
icache_access = true;
- Packet ifetch_pkt = Packet(&ifetch_req, MemCmd::ReadReq,
- Packet::Broadcast);
+ Packet ifetch_pkt = Packet(&ifetch_req, MemCmd::ReadReq);
ifetch_pkt.dataStatic(&inst);
- if (hasPhysMemPort && ifetch_pkt.getAddr() == physMemAddr)
- icache_latency = physmemPort.sendAtomic(&ifetch_pkt);
+ if (fastmem && system->isMemAddr(ifetch_pkt.getAddr()))
+ system->getPhysMem().access(&ifetch_pkt);
else
icache_latency = icachePort.sendAtomic(&ifetch_pkt);
AtomicSimpleCPUParams::create()
{
numThreads = 1;
-#if !FULL_SYSTEM
- if (workload.size() != 1)
+ if (!FullSystem && workload.size() != 1)
panic("only one workload allowed");
-#endif
return new AtomicSimpleCPU(this);
}