O3: Generalize the O3 CPU object so it isn't split out by ISA.

This commit is contained in:
Gabe Black
2008-10-09 00:08:50 -07:00
parent 975c9e3af8
commit e09c403d32
26 changed files with 428 additions and 1535 deletions

View File

@@ -29,10 +29,9 @@
*/
#include "cpu/o3/alpha/impl.hh"
#include "cpu/o3/alpha/cpu_impl.hh"
#include "cpu/o3/alpha/dyn_inst.hh"
#include "cpu/o3/cpu.hh"
// Force instantiation of AlphaO3CPU for all the implemntations that are
// needed. Consider merging this and alpha_dyn_inst.cc, and maybe all
// classes that depend on a certain impl, into one file (alpha_impl.cc?).
template class AlphaO3CPU<AlphaSimpleImpl>;
template class FullO3CPU<AlphaSimpleImpl>;

View File

@@ -1,149 +0,0 @@
/*
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
*/
#ifndef __CPU_O3_ALPHA_CPU_HH__
#define __CPU_O3_ALPHA_CPU_HH__
#include "arch/regfile.hh"
#include "arch/types.hh"
#include "cpu/thread_context.hh"
#include "cpu/o3/cpu.hh"
#include "sim/byteswap.hh"
class DerivO3CPUParams;
class EndQuiesceEvent;
namespace Kernel {
class Statistics;
};
class TranslatingPort;
/**
* AlphaO3CPU class. Derives from the FullO3CPU class, and
* implements all ISA and implementation specific functions of the
* CPU. This is the CPU class that is used for the SimObjects, and is
* what is given to the DynInsts. Most of its state exists in the
* FullO3CPU; the state is has is mainly for ISA specific
* functionality.
*/
template <class Impl>
class AlphaO3CPU : public FullO3CPU<Impl>
{
public:
typedef O3ThreadState<Impl> ImplState;
typedef O3ThreadState<Impl> Thread;
/** Constructs an AlphaO3CPU with the given parameters. */
AlphaO3CPU(DerivO3CPUParams *params);
/** Registers statistics. */
void regStats();
/** Reads a miscellaneous register. */
TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val,
unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
* thread. The source of the squash is an external update of
* state through the TC.
*/
void squashFromTC(unsigned tid);
#if FULL_SYSTEM
/** Posts an interrupt. */
void post_interrupt(int int_num, int index);
/** HW return from error interrupt. */
Fault hwrei(unsigned tid);
bool simPalCheck(int palFunc, unsigned tid);
/** Returns the Fault for any valid interrupt. */
Fault getInterrupts();
/** Processes any an interrupt fault. */
void processInterrupts(Fault interrupt);
/** Halts the CPU. */
void halt() { panic("Halt not implemented!\n"); }
#endif
/** Traps to handle given fault. */
void trap(Fault fault, unsigned tid);
#if !FULL_SYSTEM
/** Executes a syscall.
* @todo: Determine if this needs to be virtual.
*/
void syscall(int64_t callnum, int tid);
/** Gets a syscall argument. */
TheISA::IntReg getSyscallArg(int i, int tid);
/** Used to shift args for indirect syscall. */
void setSyscallArg(int i, TheISA::IntReg val, int tid);
/** Sets the return value of a syscall. */
void setSyscallReturn(SyscallReturn return_value, int tid);
#endif
/** CPU read function, forwards read to LSQ. */
template <class T>
Fault read(RequestPtr &req, T &data, int load_idx)
{
return this->iew.ldstQueue.read(req, data, load_idx);
}
/** CPU write function, forwards write to LSQ. */
template <class T>
Fault write(RequestPtr &req, T &data, int store_idx)
{
return this->iew.ldstQueue.write(req, data, store_idx);
}
Addr lockAddr;
/** Temporary fix for the lock flag, works in the UP case. */
bool lockFlag;
};
#endif // __CPU_O3_ALPHA_CPU_HH__

View File

@@ -30,18 +30,17 @@
#include <string>
#include "config/full_system.hh"
#include "config/use_checker.hh"
#include "cpu/base.hh"
#include "cpu/o3/alpha/cpu.hh"
#include "cpu/o3/cpu.hh"
#include "cpu/o3/alpha/impl.hh"
#include "cpu/o3/fu_pool.hh"
#include "params/DerivO3CPU.hh"
class DerivO3CPU : public AlphaO3CPU<AlphaSimpleImpl>
class DerivO3CPU : public FullO3CPU<AlphaSimpleImpl>
{
public:
DerivO3CPU(DerivO3CPUParams *p)
: AlphaO3CPU<AlphaSimpleImpl>(p)
: FullO3CPU<AlphaSimpleImpl>(p)
{ }
};

View File

@@ -1,316 +0,0 @@
/*
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
*/
#include "config/use_checker.hh"
#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
#include "base/cprintf.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/checker/thread_context.hh"
#include "sim/sim_events.hh"
#include "sim/stats.hh"
#include "cpu/o3/alpha/cpu.hh"
#include "cpu/o3/alpha/thread_context.hh"
#include "cpu/o3/comm.hh"
#include "cpu/o3/thread_state.hh"
#if FULL_SYSTEM
#include "arch/alpha/osfpal.hh"
#include "arch/isa_traits.hh"
#include "arch/kernel_stats.hh"
#include "cpu/quiesce_event.hh"
#include "sim/sim_exit.hh"
#include "sim/system.hh"
#endif
#include "params/DerivO3CPU.hh"
template <class Impl>
AlphaO3CPU<Impl>::AlphaO3CPU(DerivO3CPUParams *params) :
FullO3CPU<Impl>(this, params)
{
DPRINTF(O3CPU, "Creating AlphaO3CPU object.\n");
// Setup any thread state.
this->thread.resize(this->numThreads);
for (int i = 0; i < this->numThreads; ++i) {
#if FULL_SYSTEM
// SMT is not supported in FS mode yet.
assert(this->numThreads == 1);
this->thread[i] = new Thread(this, 0);
this->thread[i]->setStatus(ThreadContext::Suspended);
#else
if (i < params->workload.size()) {
DPRINTF(O3CPU, "Workload[%i] process is %#x",
i, this->thread[i]);
this->thread[i] = new Thread(this, i, params->workload[i], i);
this->thread[i]->setStatus(ThreadContext::Suspended);
//usedTids[i] = true;
//threadMap[i] = i;
} else {
//Allocate Empty thread so M5 can use later
//when scheduling threads to CPU
Process* dummy_proc = NULL;
this->thread[i] = new Thread(this, i, dummy_proc, i);
//usedTids[i] = false;
}
#endif // !FULL_SYSTEM
ThreadContext *tc;
// Setup the TC that will serve as the interface to the threads/CPU.
AlphaTC<Impl> *alpha_tc =
new AlphaTC<Impl>;
tc = alpha_tc;
// If we're using a checker, then the TC should be the
// CheckerThreadContext.
#if USE_CHECKER
if (params->checker) {
tc = new CheckerThreadContext<AlphaTC<Impl> >(
alpha_tc, this->checker);
}
#endif
alpha_tc->cpu = this;
alpha_tc->thread = this->thread[i];
#if FULL_SYSTEM
// Setup quiesce event.
this->thread[i]->quiesceEvent = new EndQuiesceEvent(tc);
#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);
}
for (int i=0; i < this->numThreads; i++) {
this->thread[i]->setFuncExeInst(0);
}
lockAddr = 0;
lockFlag = false;
}
template <class Impl>
void
AlphaO3CPU<Impl>::regStats()
{
// Register stats for everything that has stats.
this->fullCPURegStats();
this->fetch.regStats();
this->decode.regStats();
this->rename.regStats();
this->iew.regStats();
this->commit.regStats();
}
template <class Impl>
TheISA::MiscReg
AlphaO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
TheISA::MiscReg
AlphaO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
AlphaO3CPU<Impl>::setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val,
unsigned tid)
{
this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
AlphaO3CPU<Impl>::setMiscReg(int misc_reg,
const TheISA::MiscReg &val, unsigned tid)
{
this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
void
AlphaO3CPU<Impl>::squashFromTC(unsigned tid)
{
this->thread[tid]->inSyscall = true;
this->commit.generateTCEvent(tid);
}
#if FULL_SYSTEM
template <class Impl>
void
AlphaO3CPU<Impl>::post_interrupt(int int_num, int index)
{
BaseCPU::post_interrupt(int_num, index);
if (this->thread[0]->status() == ThreadContext::Suspended) {
DPRINTF(IPI,"Suspended Processor awoke\n");
this->threadContexts[0]->activate();
}
}
template <class Impl>
Fault
AlphaO3CPU<Impl>::hwrei(unsigned tid)
{
// Need to clear the lock flag upon returning from an interrupt.
this->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, false, tid);
this->thread[tid]->kernelStats->hwrei();
// FIXME: XXX check for interrupts? XXX
return NoFault;
}
template <class Impl>
bool
AlphaO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
{
if (this->thread[tid]->kernelStats)
this->thread[tid]->kernelStats->callpal(palFunc,
this->threadContexts[tid]);
switch (palFunc) {
case PAL::halt:
halt();
if (--System::numSystemsRunning == 0)
exitSimLoop("all cpus halted");
break;
case PAL::bpt:
case PAL::bugchk:
if (this->system->breakpoint())
return false;
break;
}
return true;
}
template <class Impl>
Fault
AlphaO3CPU<Impl>::getInterrupts()
{
// Check if there are any outstanding interrupts
return this->interrupts.getInterrupt(this->threadContexts[0]);
}
template <class Impl>
void
AlphaO3CPU<Impl>::processInterrupts(Fault interrupt)
{
// Check for interrupts here. For now can copy the code that
// exists within isa_fullsys_traits.hh. Also assume that thread 0
// is the one that handles the interrupts.
// @todo: Possibly consolidate the interrupt checking code.
// @todo: Allow other threads to handle interrupts.
assert(interrupt != NoFault);
this->interrupts.updateIntrInfo(this->threadContexts[0]);
DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
this->trap(interrupt, 0);
}
#endif // FULL_SYSTEM
template <class Impl>
void
AlphaO3CPU<Impl>::trap(Fault fault, unsigned tid)
{
// Pass the thread's TC into the invoke method.
fault->invoke(this->threadContexts[tid]);
}
#if !FULL_SYSTEM
template <class Impl>
void
AlphaO3CPU<Impl>::syscall(int64_t callnum, int tid)
{
DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
DPRINTF(Activity,"Activity: syscall() called.\n");
// Temporarily increase this by one to account for the syscall
// instruction.
++(this->thread[tid]->funcExeInst);
// Execute the actual syscall.
this->thread[tid]->syscall(callnum);
// Decrease funcExeInst by one as the normal commit will handle
// incrementing it.
--(this->thread[tid]->funcExeInst);
}
template <class Impl>
TheISA::IntReg
AlphaO3CPU<Impl>::getSyscallArg(int i, int tid)
{
assert(i < TheISA::NumArgumentRegs);
return this->readArchIntReg(AlphaISA::ArgumentReg[i], tid);
}
template <class Impl>
void
AlphaO3CPU<Impl>::setSyscallArg(int i, TheISA::IntReg val, int tid)
{
assert(i < TheISA::NumArgumentRegs);
this->setArchIntReg(AlphaISA::ArgumentReg[i], val, tid);
}
template <class Impl>
void
AlphaO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
{
TheISA::setSyscallReturn(return_value, this->tcBase(tid));
}
#endif

View File

@@ -34,8 +34,8 @@
#include "arch/isa_traits.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/inst_seq.hh"
#include "cpu/o3/alpha/cpu.hh"
#include "cpu/o3/alpha/impl.hh"
#include "cpu/o3/cpu.hh"
class Packet;

View File

@@ -41,7 +41,7 @@ template <class Impl>
class AlphaDynInst;
template <class Impl>
class AlphaO3CPU;
class FullO3CPU;
/** Implementation specific struct that defines several key types to the
* CPU, the stages within the CPU, the time buffers, and the DynInst.
@@ -68,7 +68,7 @@ struct AlphaSimpleImpl
typedef RefCountingPtr<DynInst> DynInstPtr;
/** The O3CPU type to be used. */
typedef AlphaO3CPU<AlphaSimpleImpl> O3CPU;
typedef FullO3CPU<AlphaSimpleImpl> O3CPU;
/** Same typedef, but for CPUType. BaseDynInst may not always use
* an O3 CPU, so it's clearer to call it CPUType instead in that

View File

@@ -1,76 +0,0 @@
/*
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
*/
#include "arch/alpha/types.hh"
#include "cpu/o3/thread_context.hh"
template <class Impl>
class AlphaTC : public O3ThreadContext<Impl>
{
public:
#if FULL_SYSTEM
/** Returns pointer to the quiesce event. */
virtual EndQuiesceEvent *getQuiesceEvent()
{
return this->thread->quiesceEvent;
}
#endif
virtual uint64_t readNextNPC()
{
return this->readNextPC() + sizeof(TheISA::MachInst);
}
virtual void setNextNPC(uint64_t val)
{
panic("Alpha has no NextNPC!");
}
virtual void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{ panic("Not supported on Alpha!"); }
/** This function exits the thread context in the CPU and returns
* 1 if the CPU has no more active threads (meaning it's OK to exit);
* Used in syscall-emulation mode when a thread executes the 'exit'
* syscall.
*/
virtual int exit()
{
this->deallocate();
// If there are still threads executing in the system
if (this->cpu->numActiveThreads())
return 0; // don't exit simulation
else
return 1; // exit simulation
}
};

View File

@@ -29,6 +29,7 @@
*/
#include "cpu/base_dyn_inst_impl.hh"
#include "cpu/o3/cpu.hh"
#include "cpu/o3/isa_specific.hh"
// Explicit instantiation

View File

@@ -37,6 +37,7 @@
#include "cpu/thread_context.hh"
#include "cpu/o3/isa_specific.hh"
#include "cpu/o3/cpu.hh"
#include "cpu/o3/thread_context.hh"
#include "enums/MemoryMode.hh"
#include "sim/core.hh"
#include "sim/stat_control.hh"
@@ -52,6 +53,10 @@
#include "cpu/checker/cpu.hh"
#endif
#if THE_ISA == ALPHA_ISA
#include "arch/alpha/osfpal.hh"
#endif
class BaseCPUParams;
using namespace TheISA;
@@ -149,26 +154,26 @@ FullO3CPU<Impl>::DeallocateContextEvent::description() const
}
template <class Impl>
FullO3CPU<Impl>::FullO3CPU(O3CPU *o3_cpu, DerivO3CPUParams *params)
FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
: BaseO3CPU(params),
itb(params->itb),
dtb(params->dtb),
tickEvent(this),
removeInstsThisCycle(false),
fetch(o3_cpu, params),
decode(o3_cpu, params),
rename(o3_cpu, params),
iew(o3_cpu, params),
commit(o3_cpu, params),
fetch(this, params),
decode(this, params),
rename(this, params),
iew(this, params),
commit(this, params),
regFile(o3_cpu, params->numPhysIntRegs,
regFile(this, params->numPhysIntRegs,
params->numPhysFloatRegs),
freeList(params->numThreads,
TheISA::NumIntRegs, params->numPhysIntRegs,
TheISA::NumFloatRegs, params->numPhysFloatRegs),
rob(o3_cpu,
rob(this,
params->numROBEntries, params->squashWidth,
params->smtROBPolicy, params->smtROBThreshold,
params->numThreads),
@@ -338,8 +343,109 @@ FullO3CPU<Impl>::FullO3CPU(O3CPU *o3_cpu, DerivO3CPUParams *params)
//}
contextSwitch = false;
DPRINTF(O3CPU, "Creating O3CPU object.\n");
// Setup any thread state.
this->thread.resize(this->numThreads);
for (int i = 0; i < this->numThreads; ++i) {
#if FULL_SYSTEM
// SMT is not supported in FS mode yet.
assert(this->numThreads == 1);
this->thread[i] = new Thread(this, 0);
this->thread[i]->setStatus(ThreadContext::Suspended);
#else
if (i < params->workload.size()) {
DPRINTF(O3CPU, "Workload[%i] process is %#x",
i, this->thread[i]);
this->thread[i] = new typename FullO3CPU<Impl>::Thread(
(typename Impl::O3CPU *)(this),
i, params->workload[i], i);
this->thread[i]->setStatus(ThreadContext::Suspended);
//usedTids[i] = true;
//threadMap[i] = i;
} else {
//Allocate Empty thread so M5 can use later
//when scheduling threads to CPU
Process* dummy_proc = NULL;
this->thread[i] = new typename FullO3CPU<Impl>::Thread(
(typename Impl::O3CPU *)(this),
i, dummy_proc, i);
//usedTids[i] = false;
}
#endif // !FULL_SYSTEM
ThreadContext *tc;
// Setup the TC that will serve as the interface to the threads/CPU.
O3ThreadContext<Impl> *o3_tc = new O3ThreadContext<Impl>;
tc = o3_tc;
// If we're using a checker, then the TC should be the
// CheckerThreadContext.
#if USE_CHECKER
if (params->checker) {
tc = new CheckerThreadContext<O3ThreadContext<Impl> >(
o3_tc, this->checker);
}
#endif
o3_tc->cpu = (typename Impl::O3CPU *)(this);
assert(o3_tc->cpu);
o3_tc->thread = this->thread[i];
#if FULL_SYSTEM
// Setup quiesce event.
this->thread[i]->quiesceEvent = new EndQuiesceEvent(tc);
#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);
}
for (int i=0; i < this->numThreads; i++) {
this->thread[i]->setFuncExeInst(0);
}
lockAddr = 0;
lockFlag = false;
}
#if !FULL_SYSTEM
template <class Impl>
TheISA::IntReg
FullO3CPU<Impl>::getSyscallArg(int i, int tid)
{
assert(i < TheISA::NumArgumentRegs);
TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
TheISA::ArgumentReg[i]);
TheISA::IntReg val = this->readArchIntReg(idx, tid);
#if THE_ISA == SPARC_ISA
if (bits(this->readMiscRegNoEffect(SparcISA::MISCREG_PSTATE, tid), 3, 3))
val = bits(val, 31, 0);
#endif
return val;
}
template <class Impl>
void
FullO3CPU<Impl>::setSyscallArg(int i, TheISA::IntReg val, int tid)
{
assert(i < TheISA::NumArgumentRegs);
TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
TheISA::ArgumentReg[i]);
this->setArchIntReg(idx, val, tid);
}
#endif
template <class Impl>
FullO3CPU<Impl>::~FullO3CPU()
{
@@ -347,7 +453,7 @@ FullO3CPU<Impl>::~FullO3CPU()
template <class Impl>
void
FullO3CPU<Impl>::fullCPURegStats()
FullO3CPU<Impl>::regStats()
{
BaseO3CPU::regStats();
@@ -401,6 +507,11 @@ FullO3CPU<Impl>::fullCPURegStats()
.precision(6);
totalIpc = totalCommittedInsts / numCycles;
this->fetch.regStats();
this->decode.regStats();
this->rename.regStats();
this->iew.regStats();
this->commit.regStats();
}
template <class Impl>
@@ -783,6 +894,84 @@ FullO3CPU<Impl>::activateWhenReady(int tid)
}
#if FULL_SYSTEM
template <class Impl>
void
FullO3CPU<Impl>::post_interrupt(int int_num, int index)
{
BaseCPU::post_interrupt(int_num, index);
if (this->thread[0]->status() == ThreadContext::Suspended) {
DPRINTF(IPI,"Suspended Processor awoke\n");
this->threadContexts[0]->activate();
}
}
template <class Impl>
Fault
FullO3CPU<Impl>::hwrei(unsigned tid)
{
#if THE_ISA == ALPHA_ISA
// Need to clear the lock flag upon returning from an interrupt.
this->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, false, tid);
this->thread[tid]->kernelStats->hwrei();
// FIXME: XXX check for interrupts? XXX
#endif
return NoFault;
}
template <class Impl>
bool
FullO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
{
#if THE_ISA == ALPHA_ISA
if (this->thread[tid]->kernelStats)
this->thread[tid]->kernelStats->callpal(palFunc,
this->threadContexts[tid]);
switch (palFunc) {
case PAL::halt:
halt();
if (--System::numSystemsRunning == 0)
exitSimLoop("all cpus halted");
break;
case PAL::bpt:
case PAL::bugchk:
if (this->system->breakpoint())
return false;
break;
}
#endif
return true;
}
template <class Impl>
Fault
FullO3CPU<Impl>::getInterrupts()
{
// Check if there are any outstanding interrupts
return this->interrupts.getInterrupt(this->threadContexts[0]);
}
template <class Impl>
void
FullO3CPU<Impl>::processInterrupts(Fault interrupt)
{
// Check for interrupts here. For now can copy the code that
// exists within isa_fullsys_traits.hh. Also assume that thread 0
// is the one that handles the interrupts.
// @todo: Possibly consolidate the interrupt checking code.
// @todo: Allow other threads to handle interrupts.
assert(interrupt != NoFault);
this->interrupts.updateIntrInfo(this->threadContexts[0]);
DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
this->trap(interrupt, 0);
}
template <class Impl>
void
FullO3CPU<Impl>::updateMemPorts()
@@ -794,6 +983,45 @@ FullO3CPU<Impl>::updateMemPorts()
}
#endif
template <class Impl>
void
FullO3CPU<Impl>::trap(Fault fault, unsigned tid)
{
// Pass the thread's TC into the invoke method.
fault->invoke(this->threadContexts[tid]);
}
#if !FULL_SYSTEM
template <class Impl>
void
FullO3CPU<Impl>::syscall(int64_t callnum, int tid)
{
DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
DPRINTF(Activity,"Activity: syscall() called.\n");
// Temporarily increase this by one to account for the syscall
// instruction.
++(this->thread[tid]->funcExeInst);
// Execute the actual syscall.
this->thread[tid]->syscall(callnum);
// Decrease funcExeInst by one as the normal commit will handle
// incrementing it.
--(this->thread[tid]->funcExeInst);
}
template <class Impl>
void
FullO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
{
TheISA::setSyscallReturn(return_value, this->tcBase(tid));
}
#endif
template <class Impl>
void
FullO3CPU<Impl>::serialize(std::ostream &os)
@@ -993,6 +1221,36 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
tickEvent.schedule(nextCycle());
}
template <class Impl>
TheISA::MiscReg
FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
TheISA::MiscReg
FullO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
FullO3CPU<Impl>::setMiscRegNoEffect(int misc_reg,
const TheISA::MiscReg &val, unsigned tid)
{
this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
FullO3CPU<Impl>::setMiscReg(int misc_reg,
const TheISA::MiscReg &val, unsigned tid)
{
this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
uint64_t
FullO3CPU<Impl>::readIntReg(int reg_idx)
@@ -1211,6 +1469,14 @@ FullO3CPU<Impl>::setNextMicroPC(Addr new_PC,unsigned tid)
commit.setNextMicroPC(new_PC, tid);
}
template <class Impl>
void
FullO3CPU<Impl>::squashFromTC(unsigned tid)
{
this->thread[tid]->inSyscall = true;
this->commit.generateTCEvent(tid);
}
template <class Impl>
typename FullO3CPU<Impl>::ListIt
FullO3CPU<Impl>::addInst(DynInstPtr &inst)

View File

@@ -99,6 +99,7 @@ class FullO3CPU : public BaseO3CPU
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::O3CPU O3CPU;
typedef O3ThreadState<Impl> ImplState;
typedef O3ThreadState<Impl> Thread;
typedef typename std::list<DynInstPtr>::iterator ListIt;
@@ -201,6 +202,13 @@ class FullO3CPU : public BaseO3CPU
activateThreadEvent[tid].squash();
}
#if !FULL_SYSTEM
TheISA::IntReg getSyscallArg(int i, int tid);
/** Used to shift args for indirect syscall. */
void setSyscallArg(int i, TheISA::IntReg val, int tid);
#endif
/** The tick event used for scheduling CPU ticks. */
ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
@@ -257,12 +265,12 @@ class FullO3CPU : public BaseO3CPU
public:
/** Constructs a CPU with the given parameters. */
FullO3CPU(O3CPU *o3_cpu, DerivO3CPUParams *params);
FullO3CPU(DerivO3CPUParams *params);
/** Destructor. */
~FullO3CPU();
/** Registers statistics. */
void fullCPURegStats();
void regStats();
void demapPage(Addr vaddr, uint64_t asn)
{
@@ -368,12 +376,16 @@ class FullO3CPU : public BaseO3CPU
virtual void unserialize(Checkpoint *cp, const std::string &section);
public:
/** Executes a syscall on this cycle.
* ---------------------------------------
* Note: this is a virtual function. CPU-Specific
* functionality defined in derived classes
#if !FULL_SYSTEM
/** Executes a syscall.
* @todo: Determine if this needs to be virtual.
*/
virtual void syscall(int tid) { panic("Unimplemented!"); }
void syscall(int64_t callnum, int tid);
/** Sets the return value of a syscall. */
void setSyscallReturn(SyscallReturn return_value, int tid);
#endif
/** Starts draining the CPU's pipeline of all instructions in
* order to stop all memory accesses. */
@@ -395,7 +407,27 @@ class FullO3CPU : public BaseO3CPU
InstSeqNum getAndIncrementInstSeq()
{ return globalSeqNum++; }
/** Traps to handle given fault. */
void trap(Fault fault, unsigned tid);
#if FULL_SYSTEM
/** Posts an interrupt. */
void post_interrupt(int int_num, int index);
/** HW return from error interrupt. */
Fault hwrei(unsigned tid);
bool simPalCheck(int palFunc, unsigned tid);
/** Returns the Fault for any valid interrupt. */
Fault getInterrupts();
/** Processes any an interrupt fault. */
void processInterrupts(Fault interrupt);
/** Halts the CPU. */
void halt() { panic("Halt not implemented!\n"); }
/** Update the Virt and Phys ports of all ThreadContexts to
* reflect change in memory connections. */
void updateMemPorts();
@@ -425,6 +457,24 @@ class FullO3CPU : public BaseO3CPU
#endif
/** Register accessors. Index refers to the physical register index. */
/** Reads a miscellaneous register. */
TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
unsigned tid);
uint64_t readIntReg(int reg_idx);
TheISA::FloatReg readFloatReg(int reg_idx);
@@ -496,6 +546,12 @@ class FullO3CPU : public BaseO3CPU
/** Sets the commit next micro PC of a specific thread. */
void setNextMicroPC(Addr val, unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
* thread. The source of the squash is an external update of
* state through the TC.
*/
void squashFromTC(unsigned tid);
/** Function to add instruction onto the head of the list of the
* instructions. Used when new instructions are fetched.
*/
@@ -711,6 +767,25 @@ class FullO3CPU : public BaseO3CPU
/** Available thread ids in the cpu*/
std::vector<unsigned> tids;
/** CPU read function, forwards read to LSQ. */
template <class T>
Fault read(RequestPtr &req, T &data, int load_idx)
{
return this->iew.ldstQueue.read(req, data, load_idx);
}
/** CPU write function, forwards write to LSQ. */
template <class T>
Fault write(RequestPtr &req, T &data, int store_idx)
{
return this->iew.ldstQueue.write(req, data, store_idx);
}
Addr lockAddr;
/** Temporary fix for the lock flag, works in the UP case. */
bool lockFlag;
/** Stat for total number of times the CPU is descheduled. */
Stats::Scalar<> timesIdled;
/** Stat for total number of cycles the CPU spends descheduled. */

View File

@@ -31,15 +31,12 @@
#include "cpu/base.hh"
#if THE_ISA == ALPHA_ISA
#include "cpu/o3/alpha/cpu.hh"
#include "cpu/o3/alpha/impl.hh"
#include "cpu/o3/alpha/dyn_inst.hh"
#elif THE_ISA == MIPS_ISA
#include "cpu/o3/mips/cpu.hh"
#include "cpu/o3/mips/impl.hh"
#include "cpu/o3/mips/dyn_inst.hh"
#elif THE_ISA == SPARC_ISA
#include "cpu/o3/sparc/cpu.hh"
#include "cpu/o3/sparc/impl.hh"
#include "cpu/o3/sparc/dyn_inst.hh"
#else

View File

@@ -29,11 +29,10 @@
* Korey Sewell
*/
#include "cpu/o3/cpu.hh"
#include "cpu/o3/mips/impl.hh"
#include "cpu/o3/mips/cpu_impl.hh"
#include "cpu/o3/mips/dyn_inst.hh"
// Force instantiation of MipsO3CPU for all the implemntations that are
// needed. Consider merging this and mips_dyn_inst.cc, and maybe all
// classes that depend on a certain impl, into one file (mips_impl.cc?).
template class MipsO3CPU<MipsSimpleImpl>;
template class FullO3CPU<MipsSimpleImpl>;

View File

@@ -1,130 +0,0 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
* Korey Sewell
*/
#ifndef __CPU_O3_MIPS_CPU_HH__
#define __CPU_O3_MIPS_CPU_HH__
#include "arch/mips/regfile.hh"
#include "arch/mips/syscallreturn.hh"
#include "cpu/thread_context.hh"
#include "cpu/o3/cpu.hh"
#include "sim/byteswap.hh"
#include "sim/faults.hh"
class DerivO3CPUParams;
class EndQuiesceEvent;
namespace Kernel {
class Statistics;
};
class TranslatingPort;
/**
* MipsO3CPU class. Derives from the FullO3CPU class, and
* implements all ISA and implementation specific functions of the
* CPU. This is the CPU class that is used for the SimObjects, and is
* what is given to the DynInsts. Most of its state exists in the
* FullO3CPU; the state is has is mainly for ISA specific
* functionality.
*/
template <class Impl>
class MipsO3CPU : public FullO3CPU<Impl>
{
public:
typedef O3ThreadState<Impl> ImplState;
typedef O3ThreadState<Impl> Thread;
/** Constructs an MipsO3CPU with the given parameters. */
MipsO3CPU(DerivO3CPUParams *params);
/** Registers statistics. */
void regStats();
/** Reads a miscellaneous register. */
TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
void setMiscReg(int misc_reg,
const TheISA::MiscReg &val, unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
* thread. The source of the squash is an external update of
* state through the TC.
*/
void squashFromTC(unsigned tid);
/** Traps to handle given fault. */
void trap(Fault fault, unsigned tid);
/** Executes a syscall.
* @todo: Determine if this needs to be virtual.
*/
void syscall(int64_t callnum, int tid);
/** Gets a syscall argument. */
TheISA::IntReg getSyscallArg(int i, int tid);
/** Used to shift args for indirect syscall. */
void setSyscallArg(int i, TheISA::IntReg val, int tid);
/** Sets the return value of a syscall. */
void setSyscallReturn(SyscallReturn return_value, int tid);
/** CPU read function, forwards read to LSQ. */
template <class T>
Fault read(RequestPtr &req, T &data, int load_idx)
{
return this->iew.ldstQueue.read(req, data, load_idx);
}
/** CPU write function, forwards write to LSQ. */
template <class T>
Fault write(RequestPtr &req, T &data, int store_idx)
{
return this->iew.ldstQueue.write(req, data, store_idx);
}
Addr lockAddr;
/** Temporary fix for the lock flag, works in the UP case. */
bool lockFlag;
};
#endif // __CPU_O3_MIPS_CPU_HH__

View File

@@ -31,18 +31,17 @@
#include <string>
#include "config/full_system.hh"
#include "config/use_checker.hh"
#include "cpu/base.hh"
#include "cpu/o3/mips/cpu.hh"
#include "cpu/o3/cpu.hh"
#include "cpu/o3/mips/impl.hh"
#include "cpu/o3/fu_pool.hh"
#include "params/DerivO3CPU.hh"
class DerivO3CPU : public MipsO3CPU<MipsSimpleImpl>
class DerivO3CPU : public FullO3CPU<MipsSimpleImpl>
{
public:
DerivO3CPU(DerivO3CPUParams *p)
: MipsO3CPU<MipsSimpleImpl>(p)
: FullO3CPU<MipsSimpleImpl>(p)
{ }
};

View File

@@ -1,218 +0,0 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
* Korey Sewell
*/
#include "config/use_checker.hh"
#include "arch/mips/faults.hh"
#include "base/cprintf.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/checker/thread_context.hh"
#include "sim/sim_events.hh"
#include "sim/stats.hh"
#include "cpu/o3/mips/cpu.hh"
#include "cpu/o3/mips/thread_context.hh"
#include "cpu/o3/comm.hh"
#include "cpu/o3/thread_state.hh"
#include "params/DerivO3CPU.hh"
template <class Impl>
MipsO3CPU<Impl>::MipsO3CPU(DerivO3CPUParams *params)
: FullO3CPU<Impl>(this, params)
{
DPRINTF(O3CPU, "Creating MipsO3CPU object.\n");
// Setup any thread state.
this->thread.resize(this->numThreads);
for (int i = 0; i < this->numThreads; ++i) {
if (i < params->workload.size()) {
DPRINTF(O3CPU, "Workload[%i] process is %#x",
i, this->thread[i]);
this->thread[i] = new Thread(this, i, params->workload[i], i);
this->thread[i]->setStatus(ThreadContext::Suspended);
//usedTids[i] = true;
//threadMap[i] = i;
} else {
//Allocate Empty thread so M5 can use later
//when scheduling threads to CPU
Process* dummy_proc = NULL;
this->thread[i] = new Thread(this, i, dummy_proc, i);
//usedTids[i] = false;
}
ThreadContext *tc;
// Setup the TC that will serve as the interface to the threads/CPU.
MipsTC<Impl> *mips_tc =
new MipsTC<Impl>;
tc = mips_tc;
// If we're using a checker, then the TC should be the
// CheckerThreadContext.
#if USE_CHECKER
if (params->checker) {
tc = new CheckerThreadContext<MipsTC<Impl> >(
mips_tc, this->checker);
}
#endif
mips_tc->cpu = this;
mips_tc->thread = this->thread[i];
// 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);
}
for (int i=0; i < this->numThreads; i++) {
this->thread[i]->setFuncExeInst(0);
}
lockAddr = 0;
lockFlag = false;
}
template <class Impl>
void
MipsO3CPU<Impl>::regStats()
{
// Register stats for everything that has stats.
this->fullCPURegStats();
this->fetch.regStats();
this->decode.regStats();
this->rename.regStats();
this->iew.regStats();
this->commit.regStats();
}
template <class Impl>
MiscReg
MipsO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
MiscReg
MipsO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
MipsO3CPU<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
{
this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
MipsO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val,
unsigned tid)
{
this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
void
MipsO3CPU<Impl>::squashFromTC(unsigned tid)
{
this->thread[tid]->inSyscall = true;
this->commit.generateTCEvent(tid);
}
template <class Impl>
void
MipsO3CPU<Impl>::trap(Fault fault, unsigned tid)
{
// Pass the thread's TC into the invoke method.
fault->invoke(this->threadContexts[tid]);
}
#if !FULL_SYSTEM
template <class Impl>
void
MipsO3CPU<Impl>::syscall(int64_t callnum, int tid)
{
DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
DPRINTF(Activity,"Activity: syscall() called.\n");
// Temporarily increase this by one to account for the syscall
// instruction.
++(this->thread[tid]->funcExeInst);
// Execute the actual syscall.
this->thread[tid]->syscall(callnum);
// Decrease funcExeInst by one as the normal commit will handle
// incrementing it.
--(this->thread[tid]->funcExeInst);
DPRINTF(O3CPU, "[tid:%i] Register 2 is %i ", tid, this->readIntReg(2));
}
template <class Impl>
TheISA::IntReg
MipsO3CPU<Impl>::getSyscallArg(int i, int tid)
{
assert(i < TheISA::NumArgumentRegs);
return this->readArchIntReg(MipsISA::ArgumentReg[i], tid);
}
template <class Impl>
void
MipsO3CPU<Impl>::setSyscallArg(int i, IntReg val, int tid)
{
assert(i < TheISA::NumArgumentRegs);
this->setArchIntReg(MipsISA::ArgumentReg[i], val, tid);
}
template <class Impl>
void
MipsO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
{
TheISA::setSyscallReturn(return_value, this->tcBase(tid));
}
#endif

View File

@@ -35,7 +35,7 @@
#include "arch/isa_traits.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/inst_seq.hh"
#include "cpu/o3/mips/cpu.hh"
#include "cpu/o3/cpu.hh"
#include "cpu/o3/mips/impl.hh"
class Packet;

View File

@@ -42,7 +42,7 @@ template <class Impl>
class MipsDynInst;
template <class Impl>
class MipsO3CPU;
class FullO3CPU;
/** Implementation specific struct that defines several key types to the
* CPU, the stages within the CPU, the time buffers, and the DynInst.
@@ -69,7 +69,7 @@ struct MipsSimpleImpl
typedef RefCountingPtr<DynInst> DynInstPtr;
/** The O3CPU type to be used. */
typedef MipsO3CPU<MipsSimpleImpl> O3CPU;
typedef FullO3CPU<MipsSimpleImpl> O3CPU;
/** Same typedef, but for CPUType. BaseDynInst may not always use
* an O3 CPU, so it's clearer to call it CPUType instead in that

View File

@@ -1,68 +0,0 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
* Korey Sewell
*/
#include "arch/mips/types.hh"
#include "cpu/o3/thread_context.hh"
template <class Impl>
class MipsTC : public O3ThreadContext<Impl>
{
public:
virtual uint64_t readNextNPC()
{
return this->cpu->readNextNPC(this->thread->readTid());
}
virtual void setNextNPC(uint64_t val)
{
this->cpu->setNextNPC(val, this->thread->readTid());
}
virtual void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{ panic("Not supported on Mips!"); }
/** This function exits the thread context in the CPU and returns
* 1 if the CPU has no more active threads (meaning it's OK to exit);
* Used in syscall-emulation mode when a thread executes the 'exit'
* syscall.
*/
virtual int exit()
{
this->deallocate();
// If there are still threads executing in the system
if (this->cpu->numActiveThreads())
return 0; // don't exit simulation
else
return 1; // exit simulation
}
};

View File

@@ -28,11 +28,10 @@
* Authors: Gabe Black
*/
#include "cpu/o3/cpu.hh"
#include "cpu/o3/sparc/impl.hh"
#include "cpu/o3/sparc/cpu_impl.hh"
#include "cpu/o3/sparc/dyn_inst.hh"
// Force instantiation of SparcO3CPU for all the implementations that are
// needed. Consider merging this and sparc_dyn_inst.cc, and maybe all
// classes that depend on a certain impl, into one file (sparc_impl.cc?).
template class SparcO3CPU<SparcSimpleImpl>;
template class FullO3CPU<SparcSimpleImpl>;

View File

@@ -1,148 +0,0 @@
/*
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
*/
#ifndef __CPU_O3_SPARC_CPU_HH__
#define __CPU_O3_SPARC_CPU_HH__
#include "arch/sparc/regfile.hh"
#include "arch/sparc/types.hh"
#include "cpu/thread_context.hh"
#include "cpu/o3/cpu.hh"
#include "sim/byteswap.hh"
class DerivO3CPUParams;
class EndQuiesceEvent;
namespace Kernel {
class Statistics;
};
class TranslatingPort;
/**
* SparcO3CPU class. Derives from the FullO3CPU class, and
* implements all ISA and implementation specific functions of the
* CPU. This is the CPU class that is used for the SimObjects, and is
* what is given to the DynInsts. Most of its state exists in the
* FullO3CPU; the state is has is mainly for ISA specific
* functionality.
*/
template <class Impl>
class SparcO3CPU : public FullO3CPU<Impl>
{
public:
typedef O3ThreadState<Impl> ImplState;
typedef O3ThreadState<Impl> Thread;
/** Constructs an AlphaO3CPU with the given parameters. */
SparcO3CPU(DerivO3CPUParams *params);
/** Registers statistics. */
void regStats();
/** Reads a miscellaneous register. */
TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
* thread. The source of the squash is an external update of
* state through the TC.
*/
void squashFromTC(unsigned tid);
#if FULL_SYSTEM
/** Posts an interrupt. */
void post_interrupt(int int_num, int index);
/** HW return from error interrupt. */
Fault hwrei(unsigned tid);
bool simPalCheck(int palFunc, unsigned tid);
/** Returns the Fault for any valid interrupt. */
Fault getInterrupts();
/** Processes any an interrupt fault. */
void processInterrupts(Fault interrupt);
/** Halts the CPU. */
void halt() { panic("Halt not implemented!\n"); }
#endif
/** Traps to handle given fault. */
void trap(Fault fault, unsigned tid);
#if !FULL_SYSTEM
/** Executes a syscall.
* @todo: Determine if this needs to be virtual.
*/
void syscall(int64_t callnum, int tid);
/** Gets a syscall argument. */
TheISA::IntReg getSyscallArg(int i, int tid);
/** Used to shift args for indirect syscall. */
void setSyscallArg(int i, TheISA::IntReg val, int tid);
/** Sets the return value of a syscall. */
void setSyscallReturn(SyscallReturn return_value, int tid);
#endif
/** CPU read function, forwards read to LSQ. */
template <class T>
Fault read(RequestPtr &req, T &data, int load_idx)
{
return this->iew.ldstQueue.read(req, data, load_idx);
}
/** CPU write function, forwards write to LSQ. */
template <class T>
Fault write(RequestPtr &req, T &data, int store_idx)
{
return this->iew.ldstQueue.write(req, data, store_idx);
}
Addr lockAddr;
/** Temporary fix for the lock flag, works in the UP case. */
bool lockFlag;
};
#endif // __CPU_O3_SPARC_CPU_HH__

View File

@@ -32,17 +32,15 @@
#include "config/full_system.hh"
#include "config/use_checker.hh"
#include "cpu/base.hh"
#include "cpu/o3/sparc/cpu.hh"
#include "cpu/o3/cpu.hh"
#include "cpu/o3/sparc/impl.hh"
#include "cpu/o3/fu_pool.hh"
#include "params/DerivO3CPU.hh"
class DerivO3CPU : public SparcO3CPU<SparcSimpleImpl>
class DerivO3CPU : public FullO3CPU<SparcSimpleImpl>
{
public:
DerivO3CPU(DerivO3CPUParams *p)
: SparcO3CPU<SparcSimpleImpl>(p)
: FullO3CPU<SparcSimpleImpl>(p)
{ }
};

View File

@@ -1,300 +0,0 @@
/*
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#include "config/use_checker.hh"
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/miscregfile.hh"
#include "base/cprintf.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/checker/thread_context.hh"
#include "sim/sim_events.hh"
#include "sim/stats.hh"
#include "cpu/o3/sparc/cpu.hh"
#include "cpu/o3/sparc/thread_context.hh"
#include "cpu/o3/comm.hh"
#include "cpu/o3/thread_state.hh"
#if FULL_SYSTEM
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/kernel_stats.hh"
#include "cpu/quiesce_event.hh"
#include "sim/sim_exit.hh"
#include "sim/system.hh"
#endif
#include "params/DerivO3CPU.hh"
template <class Impl>
SparcO3CPU<Impl>::SparcO3CPU(DerivO3CPUParams *params) :
FullO3CPU<Impl>(this, params)
{
DPRINTF(O3CPU, "Creating SparcO3CPU object.\n");
// Setup any thread state.
this->thread.resize(this->numThreads);
for (int i = 0; i < this->numThreads; ++i) {
#if FULL_SYSTEM
// SMT is not supported in FS mode yet.
assert(this->numThreads == 1);
this->thread[i] = new Thread(this, 0);
this->thread[i]->setStatus(ThreadContext::Suspended);
#else
if (i < params->workload.size()) {
DPRINTF(O3CPU, "Workload[%i] process is %#x",
i, this->thread[i]);
this->thread[i] = new Thread(this, i, params->workload[i], i);
this->thread[i]->setStatus(ThreadContext::Suspended);
//usedTids[i] = true;
//threadMap[i] = i;
} else {
//Allocate Empty thread so M5 can use later
//when scheduling threads to CPU
Process* dummy_proc = NULL;
this->thread[i] = new Thread(this, i, dummy_proc, i);
//usedTids[i] = false;
}
#endif // !FULL_SYSTEM
ThreadContext *tc;
// Setup the TC that will serve as the interface to the threads/CPU.
SparcTC<Impl> *sparc_tc = new SparcTC<Impl>;
tc = sparc_tc;
// If we're using a checker, then the TC should be the
// CheckerThreadContext.
#if USE_CHECKER
if (params->checker) {
tc = new CheckerThreadContext<SparcTC<Impl> >(
sparc_tc, this->checker);
}
#endif
sparc_tc->cpu = this;
sparc_tc->thread = this->thread[i];
#if FULL_SYSTEM
// Setup quiesce event.
this->thread[i]->quiesceEvent = new EndQuiesceEvent(tc);
#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);
}
for (int i=0; i < this->numThreads; i++) {
this->thread[i]->setFuncExeInst(0);
}
lockAddr = 0;
lockFlag = false;
}
template <class Impl>
void
SparcO3CPU<Impl>::regStats()
{
// Register stats for everything that has stats.
this->fullCPURegStats();
this->fetch.regStats();
this->decode.regStats();
this->rename.regStats();
this->iew.regStats();
this->commit.regStats();
}
template <class Impl>
TheISA::MiscReg
SparcO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
TheISA::MiscReg
SparcO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
SparcO3CPU<Impl>::setMiscRegNoEffect(int misc_reg,
const SparcISA::MiscReg &val, unsigned tid)
{
this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
SparcO3CPU<Impl>::setMiscReg(int misc_reg,
const SparcISA::MiscReg &val, unsigned tid)
{
this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
void
SparcO3CPU<Impl>::squashFromTC(unsigned tid)
{
this->thread[tid]->inSyscall = true;
this->commit.generateTCEvent(tid);
}
#if FULL_SYSTEM
template <class Impl>
void
SparcO3CPU<Impl>::post_interrupt(int int_num, int index)
{
BaseCPU::post_interrupt(int_num, index);
if (this->thread[0]->status() == ThreadContext::Suspended) {
DPRINTF(IPI,"Suspended Processor awoke\n");
this->threadContexts[0]->activate();
}
}
template <class Impl>
Fault
SparcO3CPU<Impl>::hwrei(unsigned tid)
{
panic("This doesn't make sense for SPARC\n");
return NoFault;
}
template <class Impl>
bool
SparcO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
{
panic("This doesn't make sense for SPARC\n");
return true;
}
template <class Impl>
Fault
SparcO3CPU<Impl>::getInterrupts()
{
// Check if there are any outstanding interrupts
return this->interrupts.getInterrupt(this->threadContexts[0]);
}
template <class Impl>
void
SparcO3CPU<Impl>::processInterrupts(Fault interrupt)
{
// Check for interrupts here. For now can copy the code that
// exists within isa_fullsys_traits.hh. Also assume that thread 0
// is the one that handles the interrupts.
// @todo: Possibly consolidate the interrupt checking code.
// @todo: Allow other threads to handle interrupts.
assert(interrupt != NoFault);
this->interrupts.updateIntrInfo(this->threadContexts[0]);
DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
this->trap(interrupt, 0);
}
#endif // FULL_SYSTEM
template <class Impl>
void
SparcO3CPU<Impl>::trap(Fault fault, unsigned tid)
{
// Pass the thread's TC into the invoke method.
fault->invoke(this->threadContexts[tid]);
}
#if !FULL_SYSTEM
template <class Impl>
void
SparcO3CPU<Impl>::syscall(int64_t callnum, int tid)
{
DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
DPRINTF(Activity,"Activity: syscall() called.\n");
// Temporarily increase this by one to account for the syscall
// instruction.
++(this->thread[tid]->funcExeInst);
// Execute the actual syscall.
this->thread[tid]->syscall(callnum);
// Decrease funcExeInst by one as the normal commit will handle
// incrementing it.
--(this->thread[tid]->funcExeInst);
}
template <class Impl>
TheISA::IntReg
SparcO3CPU<Impl>::getSyscallArg(int i, int tid)
{
assert(i < TheISA::NumArgumentRegs);
TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
SparcISA::ArgumentReg[i]);
TheISA::IntReg val = this->readArchIntReg(idx, tid);
if (bits(this->readMiscRegNoEffect(SparcISA::MISCREG_PSTATE, tid), 3, 3))
val = bits(val, 31, 0);
return val;
}
template <class Impl>
void
SparcO3CPU<Impl>::setSyscallArg(int i, TheISA::IntReg val, int tid)
{
assert(i < TheISA::NumArgumentRegs);
TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
SparcISA::ArgumentReg[i]);
this->setArchIntReg(idx, val, tid);
}
template <class Impl>
void
SparcO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
{
TheISA::setSyscallReturn(return_value, this->tcBase(tid));
}
#endif

View File

@@ -35,7 +35,7 @@
#include "arch/sparc/types.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/inst_seq.hh"
#include "cpu/o3/sparc/cpu.hh"
#include "cpu/o3/cpu.hh"
#include "cpu/o3/sparc/impl.hh"
class Packet;

View File

@@ -41,7 +41,7 @@ template <class Impl>
class SparcDynInst;
template <class Impl>
class SparcO3CPU;
class FullO3CPU;
/** Implementation specific struct that defines several key types to the
* CPU, the stages within the CPU, the time buffers, and the DynInst.
@@ -68,7 +68,7 @@ struct SparcSimpleImpl
typedef RefCountingPtr<DynInst> DynInstPtr;
/** The O3CPU type to be used. */
typedef SparcO3CPU<SparcSimpleImpl> O3CPU;
typedef FullO3CPU<SparcSimpleImpl> O3CPU;
/** Same typedef, but for CPUType. BaseDynInst may not always use
* an O3 CPU, so it's clearer to call it CPUType instead in that

View File

@@ -1,78 +0,0 @@
/*
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#include "arch/sparc/types.hh"
#include "cpu/o3/thread_context.hh"
template <class Impl>
class SparcTC : public O3ThreadContext<Impl>
{
public:
#if FULL_SYSTEM
/** Returns pointer to the quiesce event. */
virtual EndQuiesceEvent *getQuiesceEvent()
{
return this->thread->quiesceEvent;
}
#endif
virtual uint64_t readNextNPC()
{
return this->cpu->readNextNPC(this->thread->readTid());
}
virtual void setNextNPC(uint64_t val)
{
this->cpu->setNextNPC(val, this->thread->readTid());
}
virtual void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{
//XXX Ignore this for now. This -really- needs to get fixed.
}
/** This function exits the thread context in the CPU and returns
* 1 if the CPU has no more active threads (meaning it's OK to exit);
* Used in syscall-emulation mode when a thread executes the 'exit'
* syscall.
*/
virtual int exit()
{
this->deallocate();
// If there are still threads executing in the system
if (this->cpu->numActiveThreads())
return 0; // don't exit simulation
else
return 1; // exit simulation
}
};

View File

@@ -260,7 +260,51 @@ class O3ThreadContext : public ThreadContext
/** Reads the funcExeInst counter. */
virtual Counter readFuncExeInst() { return thread->funcExeInst; }
#else
/** Returns pointer to the quiesce event. */
virtual EndQuiesceEvent *getQuiesceEvent()
{
return this->thread->quiesceEvent;
}
#endif
virtual uint64_t readNextNPC()
{
return this->cpu->readNextNPC(this->thread->readTid());
}
virtual void setNextNPC(uint64_t val)
{
#if THE_ISA == ALPHA_ISA
panic("Not supported on Alpha!");
#endif
this->cpu->setNextNPC(val, this->thread->readTid());
}
virtual void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{
#if THE_ISA != SPARC_ISA
panic("changeRegFileContext not implemented.");
#endif
}
/** This function exits the thread context in the CPU and returns
* 1 if the CPU has no more active threads (meaning it's OK to exit);
* Used in syscall-emulation mode when a thread executes the 'exit'
* syscall.
*/
virtual int exit()
{
this->deallocate();
// If there are still threads executing in the system
if (this->cpu->numActiveThreads())
return 0; // don't exit simulation
else
return 1; // exit simulation
}
};
#endif