if (stCondFailures % 100000 == 0) {
warn("cpu %d: %d consecutive "
"store conditional failures\n",
- xc->readCpuId(), stCondFailures);
+ xc->cpuId(), stCondFailures);
}
// store conditional failed already, so don't issue it to mem
if (stCondFailures % 10 == 0) {
warn("%i: cpu %d: %d consecutive "
"store conditional failures\n",
- curTick, xc->readCpuId(), stCondFailures);
+ curTick, xc->cpuId(), stCondFailures);
}
if (stCondFailures == 5000) {
temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative);
// Check that the CPU array is fully populated
// (by calling getNumCPus())
- assert(sys->getNumCPUs() > tc->readCpuId());
+ assert(sys->getNumCPUs() > tc->cpuId());
- temp |= tc->readCpuId() << STS::shft_id;
+ temp |= tc->cpuId() << STS::shft_id;
- for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) {
+ for (x = tc->cpuId() & ~3; x < sys->threadContexts.size(); x++) {
switch (sys->threadContexts[x]->status()) {
case ThreadContext::Active:
temp |= STS::st_run << (STS::shft_fsm0 -
*/
// Force the access to be uncacheable.
req->setFlags(req->getFlags() | UNCACHEABLE);
- req->setPaddr(x86LocalAPICAddress(tc->readCpuId(), paddr - baseAddr));
+ req->setPaddr(x86LocalAPICAddress(tc->cpuId(), paddr - baseAddr));
}
#endif
return NoFault;
abstract = True
system = Param.System(Parent.any, "system object")
- cpu_id = Param.Int("CPU identifier")
+ cpu_id = Param.Int(-1, "CPU identifier")
numThreads = Param.Unsigned(1, "number of HW thread contexts")
function_trace = Param.Bool(False, "Enable function trace")
#if FULL_SYSTEM
BaseCPU::BaseCPU(Params *p)
- : MemObject(p), clock(p->clock), instCnt(0), interrupts(p->interrupts),
+ : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id),
+ interrupts(p->interrupts),
number_of_threads(p->numThreads), system(p->system),
phase(p->phase)
#else
BaseCPU::BaseCPU(Params *p)
- : MemObject(p), clock(p->clock),
+ : MemObject(p), clock(p->clock), _cpuId(p->cpu_id),
number_of_threads(p->numThreads), system(p->system),
phase(p->phase)
#endif
{
// currentTick = curTick;
+ // if Python did not provide a valid ID, do it here
+ if (_cpuId == -1 ) {
+ _cpuId = cpuList.size();
+ }
+
// add self to global list of CPUs
cpuList.push_back(this);
+ DPRINTF(SyscallVerbose, "Constructing CPU with id %d\n", _cpuId);
+
if (number_of_threads > maxThreadsPerCPU)
maxThreadsPerCPU = number_of_threads;
ThreadContext *tc = threadContexts[i];
#if FULL_SYSTEM
- int id = params()->cpu_id;
- if (id != -1)
- id += i;
-
- tc->setCpuId(system->registerThreadContext(tc, id));
+ system->registerThreadContext(tc);
#else
- tc->setCpuId(tc->getProcessPtr()->registerThreadContext(tc));
+ tc->getProcessPtr()->registerThreadContext(tc);
#endif
}
}
{
assert(threadContexts.size() == oldCPU->threadContexts.size());
+ _cpuId = oldCPU->cpuId();
+
for (int i = 0; i < threadContexts.size(); ++i) {
ThreadContext *newTC = threadContexts[i];
ThreadContext *oldTC = oldCPU->threadContexts[i];
CpuEvent::replaceThreadContext(oldTC, newTC);
- assert(newTC->readCpuId() == oldTC->readCpuId());
+ assert(newTC->cpuId() == oldTC->cpuId());
#if FULL_SYSTEM
- system->replaceThreadContext(newTC, newTC->readCpuId());
+ system->replaceThreadContext(newTC, newTC->cpuId());
#else
assert(newTC->getProcessPtr() == oldTC->getProcessPtr());
- newTC->getProcessPtr()->replaceThreadContext(newTC, newTC->readCpuId());
+ newTC->getProcessPtr()->replaceThreadContext(newTC, newTC->cpuId());
#endif
if (DTRACE(Context))
Tick clock;
// @todo remove me after debugging with legion done
Tick instCnt;
+ // every cpu has an id, put it in the base cpu
+ // Set at initialization, only time a cpuId might change is during a
+ // takeover (which should be done from within the BaseCPU anyway,
+ // therefore no setCpuId() method is provided
+ int _cpuId;
public:
+ /** Reads this CPU's ID. */
+ int cpuId() { return _cpuId; }
+
// Tick currentTick;
inline Tick frequency() const { return Clock::Frequency / clock; }
inline Tick ticks(int numCycles) const { return clock * numCycles; }
void dump(std::string &outstring);
/** Read this CPU's ID. */
- int readCpuId() { return cpu->readCpuId(); }
+ int cpuId() { return cpu->cpuId(); }
/** Returns the fault type. */
Fault getFault() { return fault; }
reqMade = true;
Request *req = new Request();
req->setVirt(asid, vaddr, size, flags, PC);
- req->setThreadContext(thread->readCpuId(), threadNumber);
+ req->setThreadContext(thread->cpuId(), threadNumber);
fault = cpu->translateDataReadReq(req, thread);
reqMade = true;
Request *req = new Request();
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
- req->setThreadContext(thread->readCpuId(), threadNumber);
+ req->setThreadContext(thread->cpuId(), threadNumber);
fault = cpu->translateDataReadReq(req, thread);
reqMade = true;
Request *req = new Request();
req->setVirt(asid, vaddr, size, flags, PC);
- req->setThreadContext(thread->readCpuId(), threadNumber);
+ req->setThreadContext(thread->cpuId(), threadNumber);
fault = cpu->translateDataWriteReq(req, thread);
reqMade = true;
Request *req = new Request();
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
- req->setThreadContext(thread->readCpuId(), threadNumber);
+ req->setThreadContext(thread->cpuId(), threadNumber);
fault = cpu->translateDataWriteReq(req, thread);
memReq = new Request(inst->threadNumber, fetch_PC,
sizeof(uint32_t),
IFETCH_FLAGS(thread->readPC()),
- fetch_PC, thread->readCpuId(), inst->threadNumber);
+ fetch_PC, thread->cpuId(), inst->threadNumber);
bool succeeded = translateInstReq(memReq);
checkerTC->setCpuId(id);
}
- int readCpuId() { return actualTC->readCpuId(); }
+ int cpuId() { return actualTC->cpuId(); }
TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); }
using namespace TheISA;
BaseO3CPU::BaseO3CPU(BaseCPUParams *params)
- : BaseCPU(params), cpuId(0)
+ : BaseCPU(params)
{
}
#endif
// Give the thread the TC.
this->thread[i]->tc = tc;
- this->thread[i]->setCpuId(params->cpu_id);
// Add the TC to the CPU's list of TC's.
this->threadContexts.push_back(tc);
}
#if FULL_SYSTEM
- TheISA::initCPU(src_tc, src_tc->readCpuId());
+ TheISA::initCPU(src_tc, src_tc->cpuId());
#endif
}
BaseO3CPU(BaseCPUParams *params);
void regStats();
-
- /** Sets this CPU's ID. */
- void setCpuId(int id) { cpuId = id; }
-
- /** Reads this CPU's ID. */
- int readCpuId() { return cpuId; }
-
- protected:
- int cpuId;
};
/**
// Set the appropriate read size and flags as well.
// Build request here.
RequestPtr mem_req = new Request(tid, block_PC, cacheBlkSize, 0,
- fetch_PC, cpu->readCpuId(), tid);
+ fetch_PC, cpu->cpuId(), tid);
memReq[tid] = mem_req;
/** Returns a pointer to this CPU. */
virtual BaseCPU *getCpuPtr() { return cpu; }
- /** Sets this CPU's ID. */
- virtual void setCpuId(int id) { cpu->setCpuId(id); }
-
/** Reads this CPU's ID. */
- virtual int readCpuId() { return cpu->readCpuId(); }
+ virtual int cpuId() { return cpu->cpuId(); }
#if FULL_SYSTEM
/** Returns a pointer to the system. */
// copy over functional state
setStatus(old_context->status());
copyArchRegs(old_context);
- setCpuId(old_context->readCpuId());
#if !FULL_SYSTEM
thread->funcExeInst = old_context->readFuncExeInst();
#if FULL_SYSTEM
O3ThreadState(O3CPU *_cpu, int _thread_num)
- : ThreadState(_cpu, -1, _thread_num),
+ : ThreadState(_cpu, _thread_num),
cpu(_cpu), inSyscall(0), trapPending(0)
{
if (cpu->params()->profile) {
}
#else
O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid)
- : ThreadState(_cpu, -1, _thread_num, _process, _asid),
+ : ThreadState(_cpu, _thread_num, _process, _asid),
cpu(_cpu), inSyscall(0), trapPending(0)
{ }
#endif
BaseCPU *getCpuPtr();
- void setCpuId(int id);
-
- int readCpuId() { return thread->readCpuId(); }
-
TheISA::ITB *getITBPtr() { return cpu->itb; }
TheISA::DTB * getDTBPtr() { return cpu->dtb; }
public:
BaseCPU *getCpuPtr() { return this; }
- void setCpuId(int id) { cpuId = id; }
-
- int readCpuId() { return cpuId; }
-
- int cpuId;
-
void switchOut();
void signalSwitched();
void takeOverFrom(BaseCPU *oldCPU);
ThreadContext *tc = threadContexts[i];
// initialize CPU, including PC
- TheISA::initCPU(tc, tc->readCpuId());
+ TheISA::initCPU(tc, tc->cpuId());
}
#endif
frontEnd->renameTable.copyFrom(thread.renameTable);
// copy over functional state
setStatus(old_context->status());
copyArchRegs(old_context);
- setCpuId(old_context->readCpuId());
+ setCpuId(old_context->cpuId());
thread->setInst(old_context->getInst());
#if !FULL_SYSTEM
// Setup the memReq to do a read of the first isntruction's address.
// Set the appropriate read size and flags as well.
memReq = new Request(0, fetch_PC, cacheBlkSize, 0,
- PC, cpu->readCpuId(), 0);
+ PC, cpu->cpuId(), 0);
// Translate the instruction request.
fault = cpu->translateInstReq(memReq, thread);
AtomicSimpleCPU::init()
{
BaseCPU::init();
- cpuId = tc->readCpuId();
#if FULL_SYSTEM
for (int i = 0; i < threadContexts.size(); ++i) {
ThreadContext *tc = threadContexts[i];
// initialize CPU, including PC
- TheISA::initCPU(tc, cpuId);
+ TheISA::initCPU(tc, _cpuId);
}
#endif
if (hasPhysMemPort) {
physmemPort.getPeerAddressRanges(pmAddrList, snoop);
physMemAddr = *pmAddrList.begin();
}
- ifetch_req.setThreadContext(cpuId, 0); // Add thread ID if we add MT
- data_read_req.setThreadContext(cpuId, 0); // Add thread ID here too
- data_write_req.setThreadContext(cpuId, 0); // Add thread ID here too
+ ifetch_req.setThreadContext(_cpuId, 0); // Add thread ID if we add MT
+ data_read_req.setThreadContext(_cpuId, 0); // Add thread ID here too
+ data_write_req.setThreadContext(_cpuId, 0); // Add thread ID here too
}
bool
_status = Idle;
}
assert(threadContexts.size() == 1);
- cpuId = tc->readCpuId();
- ifetch_req.setThreadContext(cpuId, 0); // Add thread ID if we add MT
- data_read_req.setThreadContext(cpuId, 0); // Add thread ID here too
- data_write_req.setThreadContext(cpuId, 0); // Add thread ID here too
+ ifetch_req.setThreadContext(_cpuId, 0); // Add thread ID if we add MT
+ data_read_req.setThreadContext(_cpuId, 0); // Add thread ID here too
+ data_write_req.setThreadContext(_cpuId, 0); // Add thread ID here too
}
*/
ThreadContext *tc;
protected:
- int cpuId;
enum Status {
Idle,
TimingSimpleCPU::init()
{
BaseCPU::init();
- cpuId = tc->readCpuId();
#if FULL_SYSTEM
for (int i = 0; i < threadContexts.size(); ++i) {
ThreadContext *tc = threadContexts[i];
// initialize CPU, including PC
- TheISA::initCPU(tc, cpuId);
+ TheISA::initCPU(tc, _cpuId);
}
#endif
}
_status = Idle;
}
assert(threadContexts.size() == 1);
- cpuId = tc->readCpuId();
+ _cpuId = tc->cpuId();
previousTick = curTick;
}
{
Request *req =
new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(),
- cpuId, /* thread ID */ 0);
+ _cpuId, /* thread ID */ 0);
if (traceData) {
traceData->setAddr(req->getVaddr());
int size, unsigned flags)
{
Request *req =
- new Request(0, vaddr, size, flags, thread->readPC(), cpuId, 0);
+ new Request(0, vaddr, size, flags, thread->readPC(), _cpuId, 0);
if (traceData) {
traceData->setAddr(vaddr);
{
Request *req =
new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(),
- cpuId, /* thread ID */ 0);
+ _cpuId, /* thread ID */ 0);
if (traceData) {
traceData->setAddr(req->getVaddr());
int size, unsigned flags)
{
Request *req =
- new Request(0, vaddr, size, flags, thread->readPC(), cpuId, 0);
+ new Request(0, vaddr, size, flags, thread->readPC(), _cpuId, 0);
if (traceData) {
traceData->setAddr(vaddr);
if (!fromRom) {
Request *ifetch_req = new Request();
- ifetch_req->setThreadContext(cpuId, /* thread ID */ 0);
+ ifetch_req->setThreadContext(_cpuId, /* thread ID */ 0);
Fault fault = setupFetchRequest(ifetch_req);
ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
TheISA::ITB *_itb, TheISA::DTB *_dtb,
bool use_kernel_stats)
- : ThreadState(_cpu, -1, _thread_num), cpu(_cpu), system(_sys), itb(_itb),
+ : ThreadState(_cpu, _thread_num), cpu(_cpu), system(_sys), itb(_itb),
dtb(_dtb)
{
#else
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process,
TheISA::ITB *_itb, TheISA::DTB *_dtb, int _asid)
- : ThreadState(_cpu, -1, _thread_num, _process, _asid),
+ : ThreadState(_cpu, _thread_num, _process, _asid),
cpu(_cpu), itb(_itb), dtb(_dtb)
{
regs.clear();
SimpleThread::SimpleThread()
#if FULL_SYSTEM
- : ThreadState(NULL, -1, -1)
+ : ThreadState(NULL, -1)
#else
- : ThreadState(NULL, -1, -1, NULL, -1)
+ : ThreadState(NULL, -1, NULL, -1)
#endif
{
tc = new ProxyThreadContext<SimpleThread>(this);
// copy over functional state
_status = oldContext->status();
copyArchRegs(oldContext);
- cpuId = oldContext->readCpuId();
#if !FULL_SYSTEM
funcExeInst = oldContext->readFuncExeInst();
#endif
if (npc1 != npc2)
panic("NPCs doesn't match, one: %#x, two: %#x", npc1, npc2);
- int id1 = one->readCpuId();
- int id2 = two->readCpuId();
+ int id1 = one->cpuId();
+ int id2 = two->cpuId();
if (id1 != id2)
panic("CPU ids don't match, one: %d, two: %d", id1, id2);
}
virtual BaseCPU *getCpuPtr() = 0;
- virtual void setCpuId(int id) = 0;
-
- virtual int readCpuId() = 0;
+ virtual int cpuId() = 0;
virtual TheISA::ITB *getITBPtr() = 0;
BaseCPU *getCpuPtr() { return actualTC->getCpuPtr(); }
- void setCpuId(int id) { actualTC->setCpuId(id); }
-
- int readCpuId() { return actualTC->readCpuId(); }
+ int cpuId() { return actualTC->cpuId(); }
TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); }
#endif
#if FULL_SYSTEM
-ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid)
- : baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
+ThreadState::ThreadState(BaseCPU *cpu, int _tid)
+ : baseCpu(cpu), tid(_tid), lastActivate(0), lastSuspend(0),
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
kernelStats(NULL), physPort(NULL), virtPort(NULL),
microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
#else
-ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process,
+ThreadState::ThreadState(BaseCPU *cpu, int _tid, Process *_process,
short _asid)
- : baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
+ : baseCpu(cpu), tid(_tid), lastActivate(0), lastSuspend(0),
port(NULL), process(_process), asid(_asid),
microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
#endif
#include "arch/types.hh"
#include "cpu/profile.hh"
#include "cpu/thread_context.hh"
+#include "cpu/base.hh"
#if !FULL_SYSTEM
#include "mem/mem_object.hh"
};
#endif
-class BaseCPU;
class Checkpoint;
class Port;
class TranslatingPort;
typedef ThreadContext::Status Status;
#if FULL_SYSTEM
- ThreadState(BaseCPU *cpu, int _cpuId, int _tid);
+ ThreadState(BaseCPU *cpu, int _tid);
#else
- ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process,
+ ThreadState(BaseCPU *cpu, int _tid, Process *_process,
short _asid);
#endif
void unserialize(Checkpoint *cp, const std::string §ion);
- void setCpuId(int id) { cpuId = id; }
-
- int readCpuId() { return cpuId; }
+ int cpuId() { return baseCpu->cpuId(); }
void setTid(int id) { tid = id; }
// Pointer to the base CPU.
BaseCPU *baseCpu;
- // ID of this context w.r.t. the System or Process object to which
- // it belongs. For full-system mode, this is the system CPU ID.
- int cpuId;
-
// Index of hardware thread context on the CPU that this represents.
int tid;
}
int
-System::registerThreadContext(ThreadContext *tc, int id)
+System::registerThreadContext(ThreadContext *tc)
{
- if (id == -1) {
- for (id = 0; id < threadContexts.size(); id++) {
- if (!threadContexts[id])
- break;
- }
+ int id;
+ for (id = 0; id < threadContexts.size(); id++) {
+ if (!threadContexts[id])
+ break;
}
if (threadContexts.size() <= id)
#endif // FULL_SYSTEM
- int registerThreadContext(ThreadContext *tc, int tcIndex);
+ int registerThreadContext(ThreadContext *tc);
void replaceThreadContext(ThreadContext *tc, int tcIndex);
void serialize(std::ostream &os);