summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/alpha/process.cc11
-rw-r--r--src/arch/sparc/process.cc54
-rw-r--r--src/arch/x86/process.cc11
-rw-r--r--src/cpu/base.cc10
-rw-r--r--src/kern/tru64/tru64.hh27
-rw-r--r--src/sim/process.cc60
-rw-r--r--src/sim/process.hh17
-rw-r--r--src/sim/system.cc14
-rw-r--r--src/sim/system.hh7
9 files changed, 102 insertions, 109 deletions
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index 380e0e18e..28e8df308 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -67,12 +67,13 @@ AlphaLiveProcess::startup()
argsInit(MachineBytes, VMPageSize);
- threadContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer());
- //Opperate in user mode
- threadContexts[0]->setMiscRegNoEffect(IPR_ICM, 0x18);
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+ tc->setIntReg(GlobalPointerReg, objFile->globalPointer());
+ //Operate in user mode
+ tc->setMiscRegNoEffect(IPR_ICM, 0x18);
//No super page mapping
- threadContexts[0]->setMiscRegNoEffect(IPR_MCSR, 0);
+ tc->setMiscRegNoEffect(IPR_MCSR, 0);
//Set this to 0 for now, but it should be unique for each process
- threadContexts[0]->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
+ tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
}
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index a8fda04eb..987e0465e 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -112,44 +112,45 @@ SparcLiveProcess::startup()
{
Process::startup();
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//From the SPARC ABI
//Setup default FP state
- threadContexts[0]->setMiscRegNoEffect(MISCREG_FSR, 0);
+ tc->setMiscRegNoEffect(MISCREG_FSR, 0);
- threadContexts[0]->setMiscRegNoEffect(MISCREG_TICK, 0);
+ tc->setMiscRegNoEffect(MISCREG_TICK, 0);
/*
* Register window management registers
*/
//No windows contain info from other programs
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
- threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0);
+ //tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
+ tc->setIntReg(NumIntArchRegs + 6, 0);
//There are no windows to pop
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
- threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0);
+ //tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
+ tc->setIntReg(NumIntArchRegs + 4, 0);
//All windows are available to save into
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
- threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2);
+ //tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
+ tc->setIntReg(NumIntArchRegs + 3, NWindows - 2);
//All windows are "clean"
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
- threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows);
+ //tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
+ tc->setIntReg(NumIntArchRegs + 5, NWindows);
//Start with register window 0
- threadContexts[0]->setMiscRegNoEffect(MISCREG_CWP, 0);
+ tc->setMiscRegNoEffect(MISCREG_CWP, 0);
//Always use spill and fill traps 0
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_WSTATE, 0);
- threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0);
+ //tc->setMiscRegNoEffect(MISCREG_WSTATE, 0);
+ tc->setIntReg(NumIntArchRegs + 7, 0);
//Set the trap level to 0
- threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0);
+ tc->setMiscRegNoEffect(MISCREG_TL, 0);
//Set the ASI register to something fixed
- threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
+ tc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
/*
* T1 specific registers
*/
//Turn on the icache, dcache, dtb translation, and itb translation.
- threadContexts[0]->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);
+ tc->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);
}
void
@@ -160,8 +161,9 @@ Sparc32LiveProcess::startup()
SparcLiveProcess::startup();
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//The process runs in user mode with 32 bit addresses
- threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x0a);
+ tc->setMiscReg(MISCREG_PSTATE, 0x0a);
argsInit(32 / 8, VMPageSize);
}
@@ -174,8 +176,9 @@ Sparc64LiveProcess::startup()
SparcLiveProcess::startup();
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//The process runs in user mode
- threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x02);
+ tc->setMiscReg(MISCREG_PSTATE, 0x02);
argsInit(sizeof(IntReg), VMPageSize);
}
@@ -391,20 +394,21 @@ SparcLiveProcess::argsInit(int pageSize)
fillStart = stack_base;
spillStart = fillStart + sizeof(MachInst) * numFillInsts;
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set up the thread context to start running the process
//assert(NumArgumentRegs >= 2);
- //threadContexts[0]->setIntReg(ArgumentReg[0], argc);
- //threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
- threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias);
+ //tc->setIntReg(ArgumentReg[0], argc);
+ //tc->setIntReg(ArgumentReg[1], argv_array_base);
+ tc->setIntReg(StackPointerReg, stack_min - StackBias);
// %g1 is a pointer to a function that should be run at exit. Since we
// don't have anything like that, it should be set to 0.
- threadContexts[0]->setIntReg(1, 0);
+ tc->setIntReg(1, 0);
Addr prog_entry = objFile->entryPoint();
- threadContexts[0]->setPC(prog_entry);
- threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
- threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
+ tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
//Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index b62efd3cd..52933b7f4 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -146,8 +146,8 @@ X86LiveProcess::startup()
argsInit(sizeof(IntReg), VMPageSize);
- for (int i = 0; i < threadContexts.size(); i++) {
- ThreadContext * tc = threadContexts[i];
+ for (int i = 0; i < contextIds.size(); i++) {
+ ThreadContext * tc = system->getThreadContext(contextIds[i]);
SegAttr dataAttr = 0;
dataAttr.writable = 1;
@@ -458,14 +458,15 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set the stack pointer register
- threadContexts[0]->setIntReg(StackPointerReg, stack_min);
+ tc->setIntReg(StackPointerReg, stack_min);
Addr prog_entry = objFile->entryPoint();
// There doesn't need to be any segment base added in since we're dealing
// with the flat segmentation model.
- threadContexts[0]->setPC(prog_entry);
- threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
//Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 3e899d993..4845cbfaf 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -285,10 +285,9 @@ BaseCPU::registerThreadContexts()
for (int i = 0; i < threadContexts.size(); ++i) {
ThreadContext *tc = threadContexts[i];
-#if FULL_SYSTEM
system->registerThreadContext(tc);
-#else
- tc->getProcessPtr()->registerThreadContext(tc);
+#if !FULL_SYSTEM
+ tc->getProcessPtr()->assignThreadContext(tc->cpuId());
#endif
}
}
@@ -330,12 +329,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc)
CpuEvent::replaceThreadContext(oldTC, newTC);
assert(newTC->cpuId() == oldTC->cpuId());
-#if FULL_SYSTEM
system->replaceThreadContext(newTC, newTC->cpuId());
-#else
- assert(newTC->getProcessPtr() == oldTC->getProcessPtr());
- newTC->getProcessPtr()->replaceThreadContext(newTC, newTC->cpuId());
-#endif
if (DTRACE(Context))
ThreadContext::compare(oldTC, newTC);
diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh
index dfdb8524d..5f8307cd2 100644
--- a/src/kern/tru64/tru64.hh
+++ b/src/kern/tru64/tru64.hh
@@ -789,21 +789,18 @@ class Tru64 : public OperatingSystem
slot_state.copyOut(tc->getMemPort());
// Find a free simulator thread context.
- for (int i = 0; i < process->numCpus(); ++i) {
- ThreadContext *tc = process->threadContexts[i];
-
- if (tc->status() == ThreadContext::Unallocated) {
- // inactive context... grab it
- init_thread_context(tc, attrp, uniq_val);
-
- // This is supposed to be a port number, but we'll try
- // and get away with just sticking the thread index
- // here.
- *kidp = htog(thread_index);
- kidp.copyOut(tc->getMemPort());
-
- return 0;
- }
+ ThreadContext *tc = process->findFreeContext();
+ if (tc) {
+ // inactive context... grab it
+ init_thread_context(tc, attrp, uniq_val);
+
+ // This is supposed to be a port number, but we'll try
+ // and get away with just sticking the thread index
+ // here.
+ *kidp = htog(thread_index);
+ kidp.copyOut(tc->getMemPort());
+
+ return 0;
}
// fell out of loop... no available inactive context
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 23e890b06..50bc5e034 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -204,35 +204,29 @@ Process::openOutputFile(const string &filename)
return fd;
}
-
-int
-Process::registerThreadContext(ThreadContext *tc)
+ThreadContext *
+Process::findFreeContext()
{
- // add to list
- int myIndex = threadContexts.size();
- threadContexts.push_back(tc);
-
- int port = getRemoteGDBPort();
- if (port) {
- RemoteGDB *rgdb = new RemoteGDB(system, tc);
- GDBListener *gdbl = new GDBListener(rgdb, port + myIndex);
- gdbl->listen();
-
- remoteGDB.push_back(rgdb);
+ int size = contextIds.size();
+ ThreadContext *tc;
+ for (int i = 0; i < size; ++i) {
+ tc = system->getThreadContext(contextIds[i]);
+ if (tc->status() == ThreadContext::Unallocated) {
+ // inactive context, free to use
+ return tc;
+ }
}
-
- // return CPU number to caller
- return myIndex;
+ return NULL;
}
void
Process::startup()
{
- if (threadContexts.empty())
- fatal("Process %s is not associated with any CPUs!\n", name());
+ if (contextIds.empty())
+ fatal("Process %s is not associated with any HW contexts!\n", name());
// first thread context for this process... initialize & enable
- ThreadContext *tc = threadContexts[0];
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
// mark this context as active so it will start ticking.
tc->activate(0);
@@ -245,17 +239,6 @@ Process::startup()
initVirtMem->setPeer(mem_port);
}
-void
-Process::replaceThreadContext(ThreadContext *tc, int tcIndex)
-{
- if (tcIndex >= threadContexts.size()) {
- panic("replaceThreadContext: bad tcIndex, %d >= %d\n",
- tcIndex, threadContexts.size());
- }
-
- threadContexts[tcIndex] = tc;
-}
-
// map simulator fd sim_fd to target fd tgt_fd
void
Process::dup_fd(int sim_fd, int tgt_fd)
@@ -624,16 +607,19 @@ LiveProcess::argsInit(int intSize, int pageSize)
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
assert(NumArgumentRegs >= 2);
- threadContexts[0]->setIntReg(ArgumentReg[0], argc);
- threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
- threadContexts[0]->setIntReg(StackPointerReg, stack_min);
+
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+ tc->setIntReg(ArgumentReg[0], argc);
+ tc->setIntReg(ArgumentReg[1], argv_array_base);
+ tc->setIntReg(StackPointerReg, stack_min);
Addr prog_entry = objFile->entryPoint();
- threadContexts[0]->setPC(prog_entry);
- threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc
- threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+ tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
#endif
num_processes++;
diff --git a/src/sim/process.hh b/src/sim/process.hh
index cb59fed64..d6ed59ced 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -77,7 +77,7 @@ class Process : public SimObject
bool checkpointRestored;
// thread contexts associated with this process
- std::vector<ThreadContext *> threadContexts;
+ std::vector<int> contextIds;
// remote gdb objects
std::vector<TheISA::RemoteGDB *> remoteGDB;
@@ -85,7 +85,7 @@ class Process : public SimObject
bool breakpoint();
// number of CPUs (esxec contexts, really) assigned to this process.
- unsigned int numCpus() { return threadContexts.size(); }
+ unsigned int numCpus() { return contextIds.size(); }
// record of blocked context
struct WaitRec
@@ -187,12 +187,15 @@ class Process : public SimObject
// override of virtual SimObject method: register statistics
virtual void regStats();
- // register a thread context for this process.
- // returns tc's cpu number (index into threadContexts[])
- int registerThreadContext(ThreadContext *tc);
-
+ // After getting registered with system object, tell process which
+ // system-wide context id it is assigned.
+ void assignThreadContext(int context_id)
+ {
+ contextIds.push_back(context_id);
+ }
- void replaceThreadContext(ThreadContext *tc, int tcIndex);
+ // Find a free context to use
+ ThreadContext * findFreeContext();
// map simulator fd sim_fd to target fd tgt_fd
void dup_fd(int sim_fd, int tgt_fd);
diff --git a/src/sim/system.cc b/src/sim/system.cc
index 41075e9d0..8f25b4bb8 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -208,22 +208,24 @@ System::registerThreadContext(ThreadContext *tc)
void
System::startup()
{
+#if FULL_SYSTEM
int i;
for (i = 0; i < threadContexts.size(); i++)
TheISA::startupCPU(threadContexts[i], i);
+#endif
}
void
-System::replaceThreadContext(ThreadContext *tc, int id)
+System::replaceThreadContext(ThreadContext *tc, int context_id)
{
- if (id >= threadContexts.size()) {
+ if (context_id >= threadContexts.size()) {
panic("replaceThreadContext: bad id, %d >= %d\n",
- id, threadContexts.size());
+ context_id, threadContexts.size());
}
- threadContexts[id] = tc;
- if (id < remoteGDB.size())
- remoteGDB[id]->replaceThreadContext(tc);
+ threadContexts[context_id] = tc;
+ if (context_id < remoteGDB.size())
+ remoteGDB[context_id]->replaceThreadContext(tc);
}
#if !FULL_SYSTEM
diff --git a/src/sim/system.hh b/src/sim/system.hh
index f67d39c67..26cac714b 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -89,6 +89,11 @@ class System : public SimObject
std::vector<ThreadContext *> threadContexts;
int numcpus;
+ ThreadContext * getThreadContext(int tid)
+ {
+ return threadContexts[tid];
+ }
+
int getNumCPUs()
{
if (numcpus != threadContexts.size())
@@ -220,7 +225,7 @@ class System : public SimObject
#endif // FULL_SYSTEM
int registerThreadContext(ThreadContext *tc);
- void replaceThreadContext(ThreadContext *tc, int tcIndex);
+ void replaceThreadContext(ThreadContext *tc, int context_id);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);