summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:38 -0400
committerKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:38 -0400
commitdb8b1e4b78b7f51b673f80d4f2a1e5f5c86d4446 (patch)
treeca55fe420ad974c39432eab352147f52c23e7f48 /src
parentc95fe261abab85bee247737a3d171378689891e0 (diff)
downloadgem5-db8b1e4b78b7f51b673f80d4f2a1e5f5c86d4446.tar.xz
inorder: treat SE mode syscalls as a trapping instruction
define a syscallContext to schedule the syscall and then use syscall() to actually perform the action
Diffstat (limited to 'src')
-rw-r--r--src/cpu/inorder/cpu.cc21
-rw-r--r--src/cpu/inorder/cpu.hh14
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc3
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh5
-rw-r--r--src/cpu/inorder/resources/execution_unit.cc14
5 files changed, 40 insertions, 17 deletions
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index 7ef48608a..a634535bc 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -105,7 +105,7 @@ std::string InOrderCPU::eventNames[NumCPUEvents] =
"HaltThread",
"SuspendThread",
"Trap",
- "InstGraduated",
+ "Syscall",
"SquashFromMemStall",
"UpdatePCs"
};
@@ -151,6 +151,11 @@ InOrderCPU::CPUEvent::process()
cpu->resPool->trap(fault, tid, inst);
break;
+ case Syscall:
+ cpu->syscall(inst->syscallNum, tid);
+ cpu->resPool->trap(fault, tid, inst);
+ break;
+
default:
fatal("Unrecognized Event Type %s", eventNames[cpuEventType]);
}
@@ -1068,9 +1073,6 @@ InOrderCPU::activateNextReadyContext(int delay)
{
DPRINTF(InOrderCPU,"Activating next ready thread\n");
- // NOTE: Add 5 to the event priority so that we always activate
- // threads after we've finished deactivating, squashing,etc.
- // other threads
scheduleCpuEvent(ActivateNextReadyThread, NoFault, 0/*tid*/, dummyInst[0],
delay, ActivateNextReadyThread_Pri);
@@ -1382,11 +1384,6 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
// Check for instruction-count-based events.
comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
- // Broadcast to other resources an instruction
- // has been completed
- resPool->scheduleEvent((CPUEventType)ResourcePool::InstGraduated, inst,
- 0, 0, tid);
-
// Finally, remove instruction from CPU
removeInst(inst);
}
@@ -1601,6 +1598,12 @@ InOrderCPU::wakeup()
#if !FULL_SYSTEM
void
+InOrderCPU::syscallContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
+{
+ scheduleCpuEvent(Syscall, fault, tid, inst, delay, Syscall_Pri);
+}
+
+void
InOrderCPU::syscall(int64_t callnum, ThreadID tid)
{
DPRINTF(InOrderCPU, "[tid:%i] Executing syscall().\n\n", tid);
diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index c8ac33a89..a87030828 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -182,7 +182,7 @@ class InOrderCPU : public BaseCPU
HaltThread,
SuspendThread,
Trap,
- InstGraduated,
+ Syscall,
SquashFromMemStall,
UpdatePCs,
NumCPUEvents
@@ -192,6 +192,7 @@ class InOrderCPU : public BaseCPU
enum CPUEventPri {
InOrderCPU_Pri = Event::CPU_Tick_Pri,
+ Syscall_Pri = Event::CPU_Tick_Pri + 9,
ActivateNextReadyThread_Pri = Event::CPU_Tick_Pri + 10
};
@@ -207,6 +208,7 @@ class InOrderCPU : public BaseCPU
DynInstPtr inst;
Fault fault;
unsigned vpe;
+ short syscall_num;
public:
/** Constructs a CPU event. */
@@ -436,6 +438,13 @@ class InOrderCPU : public BaseCPU
/** Check if this address is a valid data address. */
bool validDataAddr(Addr addr) { return true; }
+#else
+ /** Schedule a syscall on the CPU */
+ void syscallContext(Fault fault, ThreadID tid, DynInstPtr inst,
+ int delay = 0);
+
+ /** Executes a syscall.*/
+ void syscall(int64_t callnum, ThreadID tid);
#endif
/** Schedule a trap on the CPU */
@@ -650,9 +659,6 @@ class InOrderCPU : public BaseCPU
Fault write(DynInstPtr inst, uint8_t *data, unsigned size,
Addr addr, unsigned flags, uint64_t *write_res = NULL);
- /** Executes a syscall.*/
- void syscall(int64_t callnum, ThreadID tid);
-
public:
/** Per-Thread List of all the instructions in flight. */
std::list<DynInstPtr> instList[ThePipeline::MaxThreads];
diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc
index 1252ed6d1..ccde20da4 100644
--- a/src/cpu/inorder/inorder_dyn_inst.cc
+++ b/src/cpu/inorder/inorder_dyn_inst.cc
@@ -296,7 +296,8 @@ InOrderDynInst::simPalCheck(int palFunc)
void
InOrderDynInst::syscall(int64_t callnum)
{
- cpu->syscall(callnum, this->threadNumber);
+ syscallNum = callnum;
+ cpu->syscallContext(NoFault, this->threadNumber, this);
}
#endif
diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh
index b374e24a6..d14a7edfd 100644
--- a/src/cpu/inorder/inorder_dyn_inst.hh
+++ b/src/cpu/inorder/inorder_dyn_inst.hh
@@ -385,6 +385,9 @@ class InOrderDynInst : public FastAlloc, public RefCounted
bool isQuiesce() const { return staticInst->isQuiesce(); }
bool isIprAccess() const { return staticInst->isIprAccess(); }
bool isUnverifiable() const { return staticInst->isUnverifiable(); }
+ bool isSyscall() const
+ { return staticInst->isSyscall(); }
+
/////////////////////////////////////////////
//
@@ -509,6 +512,8 @@ class InOrderDynInst : public FastAlloc, public RefCounted
void trap(Fault fault);
bool simPalCheck(int palFunc);
#else
+ short syscallNum;
+
/** Calls a syscall. */
void syscall(int64_t callnum);
#endif
diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc
index 6b89c8230..77ab21b21 100644
--- a/src/cpu/inorder/resources/execution_unit.cc
+++ b/src/cpu/inorder/resources/execution_unit.cc
@@ -89,6 +89,8 @@ ExecutionUnit::execute(int slot_num)
DynInstPtr inst = reqs[slot_num]->inst;
Fault fault = NoFault;
Tick cur_tick = curTick();
+ unsigned stage_num = exec_req->getStageNum();
+ ThreadID tid = inst->readTid();
#if TRACING_ON
InstSeqNum seq_num = inst->seqNum;
#endif
@@ -149,13 +151,10 @@ ExecutionUnit::execute(int slot_num)
assert(inst->isControl());
// Set up Squash Generated By this Misprediction
- unsigned stage_num = exec_req->getStageNum();
- ThreadID tid = inst->readTid();
TheISA::PCState pc = inst->pcState();
TheISA::advancePC(pc, inst->staticInst);
inst->setPredTarg(pc);
inst->setSquashInfo(stage_num);
-
setupSquash(inst, stage_num, tid);
DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i] Squashing from "
@@ -210,6 +209,15 @@ ExecutionUnit::execute(int slot_num)
seq_num,
(inst->resultType(0) == InOrderDynInst::Float) ?
inst->readFloatResult(0) : inst->readIntResult(0));
+
+#if !FULL_SYSTEM
+ // The Syscall might change the PC, so conservatively
+ // squash everything behing it
+ if (inst->isSyscall()) {
+ inst->setSquashInfo(stage_num);
+ setupSquash(inst, stage_num, tid);
+ }
+#endif
} else {
DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: had a %s "
"fault.\n", inst->readTid(), seq_num, fault->name());