From db8b1e4b78b7f51b673f80d4f2a1e5f5c86d4446 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 19 Jun 2011 21:43:38 -0400 Subject: [PATCH] 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 --- src/cpu/inorder/cpu.cc | 21 ++++++++++++--------- src/cpu/inorder/cpu.hh | 14 ++++++++++---- src/cpu/inorder/inorder_dyn_inst.cc | 3 ++- src/cpu/inorder/inorder_dyn_inst.hh | 5 +++++ src/cpu/inorder/resources/execution_unit.cc | 14 +++++++++++--- 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); } @@ -1600,6 +1597,12 @@ InOrderCPU::wakeup() #endif #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) { 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 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());