Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/o3-merge/newmem --HG-- extra : convert_revision : 0c2db1e1b5fdb91c1ac5705ab872a6bfb575a67a
This commit is contained in:
@@ -168,11 +168,6 @@ BaseCPU::BaseCPU(Params *p)
|
||||
p->max_loads_all_threads, *counter);
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
memset(interrupts, 0, sizeof(interrupts));
|
||||
intstatus = 0;
|
||||
#endif
|
||||
|
||||
functionTracingEnabled = false;
|
||||
if (p->functionTrace) {
|
||||
functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
|
||||
@@ -259,6 +254,26 @@ BaseCPU::regStats()
|
||||
#endif
|
||||
}
|
||||
|
||||
Tick
|
||||
BaseCPU::nextCycle()
|
||||
{
|
||||
Tick next_tick = curTick + clock - 1;
|
||||
next_tick -= (next_tick % clock);
|
||||
return next_tick;
|
||||
}
|
||||
|
||||
Tick
|
||||
BaseCPU::nextCycle(Tick begin_tick)
|
||||
{
|
||||
Tick next_tick = begin_tick;
|
||||
|
||||
while (next_tick < curTick)
|
||||
next_tick += clock;
|
||||
|
||||
next_tick -= (next_tick % clock);
|
||||
assert(next_tick >= curTick);
|
||||
return next_tick;
|
||||
}
|
||||
|
||||
void
|
||||
BaseCPU::registerThreadContexts()
|
||||
@@ -314,9 +329,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
|
||||
interrupts[i] = oldCPU->interrupts[i];
|
||||
intstatus = oldCPU->intstatus;
|
||||
interrupts = oldCPU->interrupts;
|
||||
checkInterrupts = oldCPU->checkInterrupts;
|
||||
|
||||
for (int i = 0; i < threadContexts.size(); ++i)
|
||||
@@ -348,57 +361,33 @@ BaseCPU::ProfileEvent::process()
|
||||
void
|
||||
BaseCPU::post_interrupt(int int_num, int index)
|
||||
{
|
||||
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
|
||||
|
||||
if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
|
||||
panic("int_num out of bounds\n");
|
||||
|
||||
if (index < 0 || index >= sizeof(uint64_t) * 8)
|
||||
panic("int_num out of bounds\n");
|
||||
|
||||
checkInterrupts = true;
|
||||
interrupts[int_num] |= 1 << index;
|
||||
intstatus |= (ULL(1) << int_num);
|
||||
interrupts.post(int_num, index);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCPU::clear_interrupt(int int_num, int index)
|
||||
{
|
||||
DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
|
||||
|
||||
if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
|
||||
panic("int_num out of bounds\n");
|
||||
|
||||
if (index < 0 || index >= sizeof(uint64_t) * 8)
|
||||
panic("int_num out of bounds\n");
|
||||
|
||||
interrupts[int_num] &= ~(1 << index);
|
||||
if (interrupts[int_num] == 0)
|
||||
intstatus &= ~(ULL(1) << int_num);
|
||||
interrupts.clear(int_num, index);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCPU::clear_interrupts()
|
||||
{
|
||||
DPRINTF(Interrupt, "Interrupts all cleared\n");
|
||||
|
||||
memset(interrupts, 0, sizeof(interrupts));
|
||||
intstatus = 0;
|
||||
interrupts.clear_all();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BaseCPU::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
|
||||
SERIALIZE_SCALAR(intstatus);
|
||||
interrupts.serialize(os);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCPU::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
|
||||
UNSERIALIZE_SCALAR(intstatus);
|
||||
interrupts.unserialize(cp, section);
|
||||
}
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
#include "mem/mem_object.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/interrupts.hh"
|
||||
#endif
|
||||
|
||||
class BranchPred;
|
||||
class CheckerCPU;
|
||||
class ThreadContext;
|
||||
@@ -73,10 +77,25 @@ class BaseCPU : public MemObject
|
||||
inline Tick cycles(int numCycles) const { return clock * numCycles; }
|
||||
inline Tick curCycle() const { return curTick / clock; }
|
||||
|
||||
/** The next cycle the CPU should be scheduled, given a cache
|
||||
* access or quiesce event returning on this cycle. This function
|
||||
* may return curTick if the CPU should run on the current cycle.
|
||||
*/
|
||||
Tick nextCycle();
|
||||
|
||||
/** The next cycle the CPU should be scheduled, given a cache
|
||||
* access or quiesce event returning on the given Tick. This
|
||||
* function may return curTick if the CPU should run on the
|
||||
* current cycle.
|
||||
* @param begin_tick The tick that the event is completing on.
|
||||
*/
|
||||
Tick nextCycle(Tick begin_tick);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
protected:
|
||||
uint64_t interrupts[TheISA::NumInterruptLevels];
|
||||
uint64_t intstatus;
|
||||
// uint64_t interrupts[TheISA::NumInterruptLevels];
|
||||
// uint64_t intstatus;
|
||||
TheISA::Interrupts interrupts;
|
||||
|
||||
public:
|
||||
virtual void post_interrupt(int int_num, int index);
|
||||
@@ -84,15 +103,8 @@ class BaseCPU : public MemObject
|
||||
virtual void clear_interrupts();
|
||||
bool checkInterrupts;
|
||||
|
||||
bool check_interrupt(int int_num) const {
|
||||
if (int_num > TheISA::NumInterruptLevels)
|
||||
panic("int_num out of bounds\n");
|
||||
|
||||
return interrupts[int_num] != 0;
|
||||
}
|
||||
|
||||
bool check_interrupts() const { return intstatus != 0; }
|
||||
uint64_t intr_status() const { return intstatus; }
|
||||
bool check_interrupts(ThreadContext * tc) const
|
||||
{ return interrupts.check_interrupts(tc); }
|
||||
|
||||
class ProfileEvent : public Event
|
||||
{
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/kernel_stats.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
using namespace std;
|
||||
@@ -72,6 +72,12 @@ CheckerCPU::CheckerCPU(Params *p)
|
||||
systemPtr = NULL;
|
||||
#else
|
||||
process = p->process;
|
||||
thread = new SimpleThread(this, /* thread_num */ 0, process,
|
||||
/* asid */ 0);
|
||||
|
||||
thread->setStatus(ThreadContext::Suspended);
|
||||
tc = thread->getTC();
|
||||
threadContexts.push_back(tc);
|
||||
#endif
|
||||
|
||||
result.integer = 0;
|
||||
@@ -81,20 +87,6 @@ CheckerCPU::~CheckerCPU()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CheckerCPU::setMemory(MemObject *mem)
|
||||
{
|
||||
#if !FULL_SYSTEM
|
||||
memPtr = mem;
|
||||
thread = new SimpleThread(this, /* thread_num */ 0, process,
|
||||
/* asid */ 0, mem);
|
||||
|
||||
thread->setStatus(ThreadContext::Suspended);
|
||||
tc = thread->getTC();
|
||||
threadContexts.push_back(tc);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CheckerCPU::setSystem(System *system)
|
||||
{
|
||||
|
||||
@@ -47,9 +47,12 @@
|
||||
|
||||
// forward declarations
|
||||
#if FULL_SYSTEM
|
||||
namespace TheISA
|
||||
{
|
||||
class ITB;
|
||||
class DTB;
|
||||
}
|
||||
class Processor;
|
||||
class AlphaITB;
|
||||
class AlphaDTB;
|
||||
class PhysicalMemory;
|
||||
|
||||
class RemoteGDB;
|
||||
@@ -96,8 +99,8 @@ class CheckerCPU : public BaseCPU
|
||||
struct Params : public BaseCPU::Params
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
AlphaITB *itb;
|
||||
AlphaDTB *dtb;
|
||||
TheISA::ITB *itb;
|
||||
TheISA::DTB *dtb;
|
||||
#else
|
||||
Process *process;
|
||||
#endif
|
||||
@@ -112,10 +115,6 @@ class CheckerCPU : public BaseCPU
|
||||
|
||||
Process *process;
|
||||
|
||||
void setMemory(MemObject *mem);
|
||||
|
||||
MemObject *memPtr;
|
||||
|
||||
void setSystem(System *system);
|
||||
|
||||
System *systemPtr;
|
||||
@@ -140,8 +139,8 @@ class CheckerCPU : public BaseCPU
|
||||
|
||||
ThreadContext *tc;
|
||||
|
||||
AlphaITB *itb;
|
||||
AlphaDTB *dtb;
|
||||
TheISA::ITB *itb;
|
||||
TheISA::DTB *dtb;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
Addr dbg_vtophys(Addr addr);
|
||||
@@ -301,19 +300,19 @@ class CheckerCPU : public BaseCPU
|
||||
return thread->readMiscReg(misc_reg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
MiscReg readMiscRegWithEffect(int misc_reg)
|
||||
{
|
||||
return thread->readMiscRegWithEffect(misc_reg, fault);
|
||||
return thread->readMiscRegWithEffect(misc_reg);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val)
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
result.integer = val;
|
||||
miscRegIdxs.push(misc_reg);
|
||||
return thread->setMiscReg(misc_reg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
miscRegIdxs.push(misc_reg);
|
||||
return thread->setMiscRegWithEffect(misc_reg, val);
|
||||
@@ -328,9 +327,6 @@ class CheckerCPU : public BaseCPU
|
||||
|
||||
#if FULL_SYSTEM
|
||||
Fault hwrei() { return thread->hwrei(); }
|
||||
int readIntrFlag() { return thread->readIntrFlag(); }
|
||||
void setIntrFlag(int val) { thread->setIntrFlag(val); }
|
||||
bool inPalMode() { return thread->inPalMode(); }
|
||||
void ev5_trap(Fault fault) { fault->invoke(tc); }
|
||||
bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
|
||||
#else
|
||||
|
||||
@@ -199,8 +199,13 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
|
||||
// Checks both the machine instruction and the PC.
|
||||
validateInst(inst);
|
||||
|
||||
#if THE_ISA == ALPHA_ISA
|
||||
curStaticInst = StaticInst::decode(makeExtMI(machInst,
|
||||
thread->readPC()));
|
||||
#elif THE_ISA == SPARC_ISA
|
||||
curStaticInst = StaticInst::decode(makeExtMI(machInst,
|
||||
thread->getTC()));
|
||||
#endif
|
||||
|
||||
#if FULL_SYSTEM
|
||||
thread->setInst(machInst);
|
||||
|
||||
@@ -37,8 +37,10 @@
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
class EndQuiesceEvent;
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
namespace TheISA {
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -87,11 +89,12 @@ class CheckerThreadContext : public ThreadContext
|
||||
|
||||
PhysicalMemory *getPhysMemPtr() { return actualTC->getPhysMemPtr(); }
|
||||
|
||||
AlphaITB *getITBPtr() { return actualTC->getITBPtr(); }
|
||||
TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); }
|
||||
|
||||
AlphaDTB *getDTBPtr() { return actualTC->getDTBPtr(); }
|
||||
TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); }
|
||||
|
||||
Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); }
|
||||
TheISA::Kernel::Statistics *getKernelStats()
|
||||
{ return actualTC->getKernelStats(); }
|
||||
|
||||
FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
|
||||
|
||||
@@ -248,19 +251,19 @@ class CheckerThreadContext : public ThreadContext
|
||||
MiscReg readMiscReg(int misc_reg)
|
||||
{ return actualTC->readMiscReg(misc_reg); }
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
{ return actualTC->readMiscRegWithEffect(misc_reg, fault); }
|
||||
MiscReg readMiscRegWithEffect(int misc_reg)
|
||||
{ return actualTC->readMiscRegWithEffect(misc_reg); }
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val)
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
checkerTC->setMiscReg(misc_reg, val);
|
||||
return actualTC->setMiscReg(misc_reg, val);
|
||||
actualTC->setMiscReg(misc_reg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
checkerTC->setMiscRegWithEffect(misc_reg, val);
|
||||
return actualTC->setMiscRegWithEffect(misc_reg, val);
|
||||
actualTC->setMiscRegWithEffect(misc_reg, val);
|
||||
}
|
||||
|
||||
unsigned readStCondFailures()
|
||||
@@ -271,9 +274,6 @@ class CheckerThreadContext : public ThreadContext
|
||||
checkerTC->setStCondFailures(sc_failures);
|
||||
actualTC->setStCondFailures(sc_failures);
|
||||
}
|
||||
#if FULL_SYSTEM
|
||||
bool inPalMode() { return actualTC->inPalMode(); }
|
||||
#endif
|
||||
|
||||
// @todo: Fix this!
|
||||
bool misspeculating() { return actualTC->misspeculating(); }
|
||||
|
||||
@@ -44,7 +44,7 @@ class ThreadContext;
|
||||
* */
|
||||
class CpuEvent : public Event
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
/** type of global list of cpu events. */
|
||||
typedef std::vector<CpuEvent *> CpuEventList;
|
||||
|
||||
|
||||
@@ -101,14 +101,14 @@ class ExecContext {
|
||||
|
||||
/** Reads a miscellaneous register, handling any architectural
|
||||
* side effects due to reading that register. */
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault);
|
||||
MiscReg readMiscRegWithEffect(int misc_reg);
|
||||
|
||||
/** Sets a miscellaneous register. */
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val);
|
||||
void setMiscReg(int misc_reg, const MiscReg &val);
|
||||
|
||||
/** Sets a miscellaneous register, handling any architectural
|
||||
* side effects due to writing that register. */
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
|
||||
|
||||
/** Records the effective address of the instruction. Only valid
|
||||
* for memory ops. */
|
||||
@@ -144,10 +144,6 @@ class ExecContext {
|
||||
/** Somewhat Alpha-specific function that handles returning from
|
||||
* an error or interrupt. */
|
||||
Fault hwrei();
|
||||
/** Reads the interrupt flags. */
|
||||
int readIntrFlag();
|
||||
/** Sets the interrupt flags to a value. */
|
||||
void setIntrFlag(int val);
|
||||
|
||||
/**
|
||||
* Check for special simulator handling of specific PAL calls. If
|
||||
|
||||
@@ -33,8 +33,11 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include "arch/regfile.hh"
|
||||
#include "arch/utility.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/exetrace.hh"
|
||||
@@ -44,10 +47,15 @@
|
||||
|
||||
//XXX This is temporary
|
||||
#include "arch/isa_specific.hh"
|
||||
#include "cpu/m5legion_interface.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace TheISA;
|
||||
|
||||
namespace Trace {
|
||||
SharedData *shared_data = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Methods for the InstRecord object
|
||||
@@ -75,23 +83,19 @@ Trace::InstRecord::dump(ostream &outs)
|
||||
uint64_t newVal;
|
||||
static const char * prefixes[4] = {"G", "O", "L", "I"};
|
||||
|
||||
char buf[256];
|
||||
sprintf(buf, "PC = 0x%016llx", thread->readNextPC());
|
||||
outs << buf;
|
||||
sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC());
|
||||
outs << buf;
|
||||
outs << hex;
|
||||
outs << "PC = " << thread->readNextPC();
|
||||
outs << " NPC = " << thread->readNextNPC();
|
||||
newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
|
||||
if(newVal != ccr)
|
||||
{
|
||||
sprintf(buf, " CCR = 0x%016llx", newVal);
|
||||
outs << buf;
|
||||
outs << " CCR = " << newVal;
|
||||
ccr = newVal;
|
||||
}
|
||||
newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
|
||||
if(newVal != y)
|
||||
{
|
||||
sprintf(buf, " Y = 0x%016llx", newVal);
|
||||
outs << buf;
|
||||
outs << " Y = " << newVal;
|
||||
y = newVal;
|
||||
}
|
||||
for(int y = 0; y < 4; y++)
|
||||
@@ -102,8 +106,7 @@ Trace::InstRecord::dump(ostream &outs)
|
||||
newVal = thread->readIntReg(index);
|
||||
if(regs[index] != newVal)
|
||||
{
|
||||
sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal);
|
||||
outs << buf;
|
||||
outs << " " << prefixes[y] << dec << x << " = " << hex << newVal;
|
||||
regs[index] = newVal;
|
||||
}
|
||||
}
|
||||
@@ -113,12 +116,11 @@ Trace::InstRecord::dump(ostream &outs)
|
||||
newVal = thread->readFloatRegBits(2 * y, 64);
|
||||
if(floats[y] != newVal)
|
||||
{
|
||||
sprintf(buf, " F%d = 0x%016llx", 2 * y, newVal);
|
||||
outs << buf;
|
||||
outs << " F" << dec << (2 * y) << " = " << hex << newVal;
|
||||
floats[y] = newVal;
|
||||
}
|
||||
}
|
||||
outs << endl;
|
||||
outs << dec << endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -222,6 +224,85 @@ Trace::InstRecord::dump(ostream &outs)
|
||||
//
|
||||
outs << endl;
|
||||
}
|
||||
#if THE_ISA == SPARC_ISA
|
||||
// Compare
|
||||
if (flags[LEGION_LOCKSTEP])
|
||||
{
|
||||
bool compared = false;
|
||||
bool diffPC = false;
|
||||
bool diffInst = false;
|
||||
bool diffRegs = false;
|
||||
|
||||
if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
|
||||
while (!compared) {
|
||||
if (shared_data->flags == OWN_M5) {
|
||||
if (shared_data->pc != PC)
|
||||
diffPC = true;
|
||||
if (shared_data->instruction != staticInst->machInst)
|
||||
diffInst = true;
|
||||
for (int i = 0; i < TheISA::NumIntRegs; i++) {
|
||||
if (thread->readIntReg(i) != shared_data->intregs[i])
|
||||
diffRegs = true;
|
||||
}
|
||||
|
||||
if (diffPC || diffInst || diffRegs ) {
|
||||
outs << "Differences found between M5 and Legion:";
|
||||
if (diffPC)
|
||||
outs << " [PC]";
|
||||
if (diffInst)
|
||||
outs << " [Instruction]";
|
||||
if (diffRegs)
|
||||
outs << " [IntRegs]";
|
||||
outs << endl << endl;;
|
||||
|
||||
outs << setfill(' ') << setw(15)
|
||||
<< "M5 PC: " << "0x"<< setw(16) << setfill('0')
|
||||
<< hex << PC << endl;
|
||||
outs << setfill(' ') << setw(15)
|
||||
<< "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
|
||||
<< shared_data->pc << endl << endl;
|
||||
|
||||
outs << setfill(' ') << setw(15)
|
||||
<< "M5 Inst: " << "0x"<< setw(8)
|
||||
<< setfill('0') << hex << staticInst->machInst
|
||||
<< staticInst->disassemble(PC, debugSymbolTable)
|
||||
<< endl;
|
||||
|
||||
StaticInstPtr legionInst = StaticInst::decode(makeExtMI(shared_data->instruction, thread));
|
||||
outs << setfill(' ') << setw(15)
|
||||
<< " Legion Inst: "
|
||||
<< "0x" << setw(8) << setfill('0') << hex
|
||||
<< shared_data->instruction
|
||||
<< legionInst->disassemble(shared_data->pc, debugSymbolTable)
|
||||
<< endl;
|
||||
|
||||
outs << endl;
|
||||
|
||||
static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
|
||||
for(int y = 0; y < 4; y++)
|
||||
{
|
||||
for(int x = 0; x < 8; x++)
|
||||
{
|
||||
outs << regtypes[y] << x << " " ;
|
||||
outs << "0x" << hex << setw(16) << thread->readIntReg(y*8+x);
|
||||
if (thread->readIntReg(y*8 + x) != shared_data->intregs[y*8+x])
|
||||
outs << " X ";
|
||||
else
|
||||
outs << " | ";
|
||||
outs << "0x" << setw(16) << hex << shared_data->intregs[y*8+x]
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
fatal("Differences found between Legion and M5\n");
|
||||
}
|
||||
|
||||
compared = true;
|
||||
shared_data->flags = OWN_LEGION;
|
||||
}
|
||||
} // while
|
||||
} // if not microop
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -271,6 +352,9 @@ Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
|
||||
"Use symbols for the PC if available", true);
|
||||
Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
|
||||
"print trace in intel compatible format", false);
|
||||
Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
|
||||
"Compare sim state to legion state every cycle",
|
||||
false);
|
||||
Param<string> exe_trace_system(&exeTraceParams, "trace_system",
|
||||
"print trace of which system (client or server)",
|
||||
"client");
|
||||
@@ -296,7 +380,28 @@ Trace::InstRecord::setParams()
|
||||
flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta;
|
||||
flags[PC_SYMBOL] = exe_trace_pc_symbol;
|
||||
flags[INTEL_FORMAT] = exe_trace_intel_format;
|
||||
flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep;
|
||||
trace_system = exe_trace_system;
|
||||
|
||||
// If were going to be in lockstep with Legion
|
||||
// Setup shared memory, and get otherwise ready
|
||||
if (flags[LEGION_LOCKSTEP]) {
|
||||
int shmfd = shmget(getuid(), sizeof(SharedData), 0777);
|
||||
if (shmfd < 0)
|
||||
fatal("Couldn't get shared memory fd. Is Legion running?");
|
||||
|
||||
shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
|
||||
if (shared_data == (SharedData*)-1)
|
||||
fatal("Couldn't allocate shared memory");
|
||||
|
||||
if (shared_data->flags != OWN_M5)
|
||||
fatal("Shared memory has invalid owner");
|
||||
|
||||
if (shared_data->version != VERSION)
|
||||
fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
|
||||
shared_data->version);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -150,6 +150,7 @@ class InstRecord : public Record
|
||||
PRINT_REG_DELTA,
|
||||
PC_SYMBOL,
|
||||
INTEL_FORMAT,
|
||||
LEGION_LOCKSTEP,
|
||||
NUM_BITS
|
||||
};
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
#ifndef __STD_TYPES_HH__
|
||||
#define __STD_TYPES_HH__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// inst sequence type, used to order instructions in the ready list,
|
||||
// if this rolls over the ready list order temporarily will get messed
|
||||
// up, but execution will continue and complete correctly
|
||||
|
||||
50
src/cpu/m5legion_interface.h
Normal file
50
src/cpu/m5legion_interface.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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: Ali Saidi
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define VERSION 0xA1000002
|
||||
#define OWN_M5 0x000000AA
|
||||
#define OWN_LEGION 0x00000055
|
||||
|
||||
/** !!! VVV Increment VERSION on change VVV !!! **/
|
||||
|
||||
typedef struct {
|
||||
uint32_t flags;
|
||||
uint32_t version;
|
||||
|
||||
uint64_t pc;
|
||||
uint32_t instruction;
|
||||
uint64_t intregs[32];
|
||||
|
||||
} SharedData;
|
||||
|
||||
/** !!! ^^^ Increment VERSION on change ^^^ !!! **/
|
||||
|
||||
@@ -97,7 +97,7 @@ class MemTest : public MemObject
|
||||
public:
|
||||
|
||||
CpuPort(const std::string &_name, MemTest *_memtest)
|
||||
: Port(_name), memtest(_memtest)
|
||||
: Port(_name, _memtest), memtest(_memtest)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -37,6 +37,12 @@
|
||||
#include "cpu/o3/cpu.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
namespace TheISA
|
||||
{
|
||||
class ITB;
|
||||
class DTB;
|
||||
}
|
||||
|
||||
class EndQuiesceEvent;
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
@@ -73,9 +79,9 @@ class AlphaO3CPU : public FullO3CPU<Impl>
|
||||
|
||||
#if FULL_SYSTEM
|
||||
/** ITB pointer. */
|
||||
AlphaITB *itb;
|
||||
AlphaISA::ITB *itb;
|
||||
/** DTB pointer. */
|
||||
AlphaDTB *dtb;
|
||||
AlphaISA::DTB *dtb;
|
||||
#endif
|
||||
|
||||
/** Registers statistics. */
|
||||
@@ -126,15 +132,15 @@ class AlphaO3CPU : public FullO3CPU<Impl>
|
||||
/** Reads a misc. register, including any side effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault, unsigned tid);
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
|
||||
|
||||
/** Sets a miscellaneous register. */
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val, unsigned tid);
|
||||
void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid);
|
||||
|
||||
/** Sets a misc. register, including any side effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid);
|
||||
void setMiscRegWithEffect(int misc_reg, const 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
|
||||
@@ -145,15 +151,8 @@ class AlphaO3CPU : public FullO3CPU<Impl>
|
||||
#if FULL_SYSTEM
|
||||
/** Posts an interrupt. */
|
||||
void post_interrupt(int int_num, int index);
|
||||
/** Reads the interrupt flag. */
|
||||
int readIntrFlag();
|
||||
/** Sets the interrupt flags. */
|
||||
void setIntrFlag(int val);
|
||||
/** HW return from error interrupt. */
|
||||
Fault hwrei(unsigned tid);
|
||||
/** Returns if a specific PC is a PAL mode PC. */
|
||||
bool inPalMode(uint64_t PC)
|
||||
{ return AlphaISA::PcPAL(PC); }
|
||||
|
||||
bool simPalCheck(int palFunc, unsigned tid);
|
||||
|
||||
|
||||
@@ -54,15 +54,13 @@ Param<int> activity;
|
||||
#if FULL_SYSTEM
|
||||
SimObjectParam<System *> system;
|
||||
Param<int> cpu_id;
|
||||
SimObjectParam<AlphaITB *> itb;
|
||||
SimObjectParam<AlphaDTB *> dtb;
|
||||
SimObjectParam<AlphaISA::ITB *> itb;
|
||||
SimObjectParam<AlphaISA::DTB *> dtb;
|
||||
Param<Tick> profile;
|
||||
#else
|
||||
SimObjectVectorParam<Process *> workload;
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
SimObjectParam<MemObject *> mem;
|
||||
|
||||
SimObjectParam<BaseCPU *> checker;
|
||||
|
||||
Param<Counter> max_insts_any_thread;
|
||||
@@ -169,8 +167,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
|
||||
INIT_PARAM(workload, "Processes to run"),
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
INIT_PARAM(mem, "Memory"),
|
||||
|
||||
INIT_PARAM_DFLT(checker, "Checker CPU", NULL),
|
||||
|
||||
INIT_PARAM_DFLT(max_insts_any_thread,
|
||||
@@ -314,8 +310,6 @@ CREATE_SIM_OBJECT(DerivO3CPU)
|
||||
params->workload = workload;
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
params->mem = mem;
|
||||
|
||||
params->checker = checker;
|
||||
|
||||
params->max_insts_any_thread = max_insts_any_thread;
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/alpha/osfpal.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "arch/kernel_stats.hh"
|
||||
#include "cpu/quiesce_event.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
#include "sim/system.hh"
|
||||
#endif
|
||||
@@ -77,24 +77,10 @@ AlphaO3CPU<Impl>::AlphaO3CPU(Params *params)
|
||||
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, params->mem);
|
||||
this->thread[i] = new Thread(this, i, params->workload[i], i);
|
||||
|
||||
this->thread[i]->setStatus(ThreadContext::Suspended);
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
/* Use this port to for syscall emulation writes to memory. */
|
||||
Port *mem_port;
|
||||
TranslatingPort *trans_port;
|
||||
trans_port = new TranslatingPort(csprintf("%s-%d-funcport",
|
||||
name(), i),
|
||||
params->workload[i]->pTable,
|
||||
false);
|
||||
mem_port = params->mem->getPort("functional");
|
||||
mem_port->setPeer(trans_port);
|
||||
trans_port->setPeer(mem_port);
|
||||
this->thread[i]->setMemPort(trans_port);
|
||||
#endif
|
||||
//usedTids[i] = true;
|
||||
//threadMap[i] = i;
|
||||
} else {
|
||||
@@ -102,7 +88,7 @@ AlphaO3CPU<Impl>::AlphaO3CPU(Params *params)
|
||||
//when scheduling threads to CPU
|
||||
Process* dummy_proc = NULL;
|
||||
|
||||
this->thread[i] = new Thread(this, i, dummy_proc, i, params->mem);
|
||||
this->thread[i] = new Thread(this, i, dummy_proc, i);
|
||||
//usedTids[i] = false;
|
||||
}
|
||||
#endif // !FULL_SYSTEM
|
||||
@@ -198,25 +184,24 @@ AlphaO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
|
||||
|
||||
template <class Impl>
|
||||
TheISA::MiscReg
|
||||
AlphaO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, Fault &fault,
|
||||
unsigned tid)
|
||||
AlphaO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
|
||||
{
|
||||
return this->regFile.readMiscRegWithEffect(misc_reg, fault, tid);
|
||||
return this->regFile.readMiscRegWithEffect(misc_reg, tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
AlphaO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
|
||||
{
|
||||
return this->regFile.setMiscReg(misc_reg, val, tid);
|
||||
this->regFile.setMiscReg(misc_reg, val, tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
AlphaO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
|
||||
unsigned tid)
|
||||
{
|
||||
return this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
|
||||
this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
@@ -241,20 +226,6 @@ AlphaO3CPU<Impl>::post_interrupt(int int_num, int index)
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
int
|
||||
AlphaO3CPU<Impl>::readIntrFlag()
|
||||
{
|
||||
return this->regFile.readIntrFlag();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
AlphaO3CPU<Impl>::setIntrFlag(int val)
|
||||
{
|
||||
this->regFile.setIntrFlag(val);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
AlphaO3CPU<Impl>::hwrei(unsigned tid)
|
||||
@@ -299,7 +270,6 @@ template <class Impl>
|
||||
void
|
||||
AlphaO3CPU<Impl>::processInterrupts()
|
||||
{
|
||||
using namespace TheISA;
|
||||
// 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.
|
||||
@@ -308,51 +278,11 @@ AlphaO3CPU<Impl>::processInterrupts()
|
||||
|
||||
// Check if there are any outstanding interrupts
|
||||
//Handle the interrupts
|
||||
int ipl = 0;
|
||||
int summary = 0;
|
||||
Fault interrupt = this->interrupts.getInterrupt(this->tcBase(0));
|
||||
|
||||
this->checkInterrupts = false;
|
||||
|
||||
if (this->readMiscReg(IPR_ASTRR, 0))
|
||||
panic("asynchronous traps not implemented\n");
|
||||
|
||||
if (this->readMiscReg(IPR_SIRR, 0)) {
|
||||
for (int i = INTLEVEL_SOFTWARE_MIN;
|
||||
i < INTLEVEL_SOFTWARE_MAX; i++) {
|
||||
if (this->readMiscReg(IPR_SIRR, 0) & (ULL(1) << i)) {
|
||||
// See table 4-19 of the 21164 hardware reference
|
||||
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
|
||||
summary |= (ULL(1) << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t interrupts = this->intr_status();
|
||||
|
||||
if (interrupts) {
|
||||
for (int i = INTLEVEL_EXTERNAL_MIN;
|
||||
i < INTLEVEL_EXTERNAL_MAX; i++) {
|
||||
if (interrupts & (ULL(1) << i)) {
|
||||
// See table 4-19 of the 21164 hardware reference
|
||||
ipl = i;
|
||||
summary |= (ULL(1) << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ipl && ipl > this->readMiscReg(IPR_IPLR, 0)) {
|
||||
this->setMiscReg(IPR_ISR, summary, 0);
|
||||
this->setMiscReg(IPR_INTID, ipl, 0);
|
||||
// Checker needs to know these two registers were updated.
|
||||
#if USE_CHECKER
|
||||
if (this->checker) {
|
||||
this->checker->threadBase()->setMiscReg(IPR_ISR, summary);
|
||||
this->checker->threadBase()->setMiscReg(IPR_INTID, ipl);
|
||||
}
|
||||
#endif
|
||||
this->trap(Fault(new InterruptFault), 0);
|
||||
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
|
||||
this->readMiscReg(IPR_IPLR, 0), ipl, summary);
|
||||
if (interrupt != NoFault) {
|
||||
this->checkInterrupts = false;
|
||||
this->trap(interrupt, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,14 +102,13 @@ class AlphaDynInst : public BaseDynInst<Impl>
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
MiscReg readMiscRegWithEffect(int misc_reg)
|
||||
{
|
||||
return this->cpu->readMiscRegWithEffect(misc_reg, fault,
|
||||
this->threadNumber);
|
||||
return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val)
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
return this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
|
||||
@@ -118,7 +117,7 @@ class AlphaDynInst : public BaseDynInst<Impl>
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return this->cpu->setMiscRegWithEffect(misc_reg, val,
|
||||
this->threadNumber);
|
||||
@@ -127,12 +126,6 @@ class AlphaDynInst : public BaseDynInst<Impl>
|
||||
#if FULL_SYSTEM
|
||||
/** Calls hardware return from error interrupt. */
|
||||
Fault hwrei();
|
||||
/** Reads interrupt flag. */
|
||||
int readIntrFlag();
|
||||
/** Sets interrupt flag. */
|
||||
void setIntrFlag(int val);
|
||||
/** Checks if system is in PAL mode. */
|
||||
bool inPalMode();
|
||||
/** Traps to handle specified fault. */
|
||||
void trap(Fault fault);
|
||||
bool simPalCheck(int palFunc);
|
||||
|
||||
@@ -113,7 +113,7 @@ Fault
|
||||
AlphaDynInst<Impl>::hwrei()
|
||||
{
|
||||
// Can only do a hwrei when in pal mode.
|
||||
if (!this->cpu->inPalMode(this->readPC()))
|
||||
if (!(this->readPC() & 0x3))
|
||||
return new AlphaISA::UnimplementedOpcodeFault;
|
||||
|
||||
// Set the next PC based on the value of the EXC_ADDR IPR.
|
||||
@@ -127,27 +127,6 @@ AlphaDynInst<Impl>::hwrei()
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
int
|
||||
AlphaDynInst<Impl>::readIntrFlag()
|
||||
{
|
||||
return this->cpu->readIntrFlag();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
AlphaDynInst<Impl>::setIntrFlag(int val)
|
||||
{
|
||||
this->cpu->setIntrFlag(val);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
bool
|
||||
AlphaDynInst<Impl>::inPalMode()
|
||||
{
|
||||
return this->cpu->inPalMode(this->PC);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
AlphaDynInst<Impl>::trap(Fault fault)
|
||||
|
||||
@@ -35,8 +35,11 @@
|
||||
#include "cpu/o3/params.hh"
|
||||
|
||||
//Forward declarations
|
||||
class AlphaDTB;
|
||||
class AlphaITB;
|
||||
namespace AlphaISA
|
||||
{
|
||||
class DTB;
|
||||
class ITB;
|
||||
}
|
||||
class MemObject;
|
||||
class Process;
|
||||
class System;
|
||||
@@ -52,8 +55,8 @@ class AlphaSimpleParams : public O3Params
|
||||
public:
|
||||
|
||||
#if FULL_SYSTEM
|
||||
AlphaITB *itb;
|
||||
AlphaDTB *dtb;
|
||||
AlphaISA::ITB *itb;
|
||||
AlphaISA::DTB *dtb;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -37,21 +37,16 @@ class AlphaTC : public O3ThreadContext<Impl>
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
/** Returns a pointer to the ITB. */
|
||||
virtual AlphaITB *getITBPtr() { return this->cpu->itb; }
|
||||
virtual AlphaISA::ITB *getITBPtr() { return this->cpu->itb; }
|
||||
|
||||
/** Returns a pointer to the DTB. */
|
||||
virtual AlphaDTB *getDTBPtr() { return this->cpu->dtb; }
|
||||
virtual AlphaISA::DTB *getDTBPtr() { return this->cpu->dtb; }
|
||||
|
||||
/** Returns pointer to the quiesce event. */
|
||||
virtual EndQuiesceEvent *getQuiesceEvent()
|
||||
{
|
||||
return this->thread->quiesceEvent;
|
||||
}
|
||||
|
||||
/** Returns if the thread is currently in PAL mode, based on
|
||||
* the PC's value. */
|
||||
virtual bool inPalMode()
|
||||
{ return TheISA::PcPAL(this->cpu->readPC(this->thread->readTid())); }
|
||||
#endif
|
||||
|
||||
virtual uint64_t readNextNPC()
|
||||
|
||||
@@ -67,8 +67,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
|
||||
Param<Tick> progress_interval;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
SimObjectParam<AlphaITB *> itb;
|
||||
SimObjectParam<AlphaDTB *> dtb;
|
||||
SimObjectParam<TheISA::ITB *> itb;
|
||||
SimObjectParam<TheISA::DTB *> dtb;
|
||||
SimObjectParam<System *> system;
|
||||
Param<int> cpu_id;
|
||||
Param<Tick> profile;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "arch/utility.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/timebuf.hh"
|
||||
#include "cpu/exetrace.hh"
|
||||
@@ -638,8 +639,7 @@ DefaultCommit<Impl>::commit()
|
||||
// and no other traps or external squashes are currently pending.
|
||||
// @todo: Allow other threads to handle interrupts.
|
||||
if (cpu->checkInterrupts &&
|
||||
cpu->check_interrupts() &&
|
||||
!cpu->inPalMode(readPC()) &&
|
||||
cpu->check_interrupts(cpu->tcBase(0)) &&
|
||||
!trapSquash[0] &&
|
||||
!tcSquash[0]) {
|
||||
// Tell fetch that there is an interrupt pending. This will
|
||||
@@ -1085,8 +1085,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
|
||||
|
||||
#if FULL_SYSTEM
|
||||
if (thread[tid]->profile) {
|
||||
// bool usermode =
|
||||
// (cpu->readMiscReg(AlphaISA::IPR_DTB_CM, tid) & 0x18) != 0;
|
||||
// bool usermode = TheISA::inUserMode(thread[tid]->getTC());
|
||||
// thread[tid]->profilePC = usermode ? 1 : head_inst->readPC();
|
||||
thread[tid]->profilePC = head_inst->readPC();
|
||||
ProfileNode *node = thread[tid]->profile->consume(thread[tid]->getTC(),
|
||||
|
||||
@@ -187,7 +187,6 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
|
||||
system(params->system),
|
||||
physmem(system->physmem),
|
||||
#endif // FULL_SYSTEM
|
||||
mem(params->mem),
|
||||
drainCount(0),
|
||||
deferRegistration(params->deferRegistration),
|
||||
numThreads(number_of_threads)
|
||||
@@ -204,7 +203,6 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
|
||||
#if USE_CHECKER
|
||||
BaseCPU *temp_checker = params->checker;
|
||||
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
|
||||
checker->setMemory(mem);
|
||||
#if FULL_SYSTEM
|
||||
checker->setSystem(params->system);
|
||||
#endif
|
||||
|
||||
@@ -620,9 +620,6 @@ class FullO3CPU : public BaseO3CPU
|
||||
PhysicalMemory *physmem;
|
||||
#endif
|
||||
|
||||
/** Pointer to memory. */
|
||||
MemObject *mem;
|
||||
|
||||
/** Event to call process() on once draining has completed. */
|
||||
Event *drainEvent;
|
||||
|
||||
|
||||
@@ -329,8 +329,6 @@ class DefaultFetch
|
||||
/** Wire used to write any information heading to decode. */
|
||||
typename TimeBuffer<FetchStruct>::wire toDecode;
|
||||
|
||||
MemObject *mem;
|
||||
|
||||
/** Icache interface. */
|
||||
IcachePort *icachePort;
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/tlb.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "base/remote_gdb.hh"
|
||||
#include "sim/system.hh"
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
@@ -98,8 +97,7 @@ DefaultFetch<Impl>::IcachePort::recvRetry()
|
||||
|
||||
template<class Impl>
|
||||
DefaultFetch<Impl>::DefaultFetch(Params *params)
|
||||
: mem(params->mem),
|
||||
branchPred(params),
|
||||
: branchPred(params),
|
||||
decodeToFetchDelay(params->decodeToFetchDelay),
|
||||
renameToFetchDelay(params->renameToFetchDelay),
|
||||
iewToFetchDelay(params->iewToFetchDelay),
|
||||
@@ -562,14 +560,9 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
// Flag to say whether or not address is physical addr.
|
||||
unsigned flags = cpu->inPalMode(fetch_PC) ? PHYSICAL : 0;
|
||||
#else
|
||||
unsigned flags = 0;
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
if (cacheBlocked || isSwitchedOut() || (interruptPending && flags == 0)) {
|
||||
//AlphaDep
|
||||
if (cacheBlocked || isSwitchedOut() ||
|
||||
(interruptPending && (fetch_PC & 0x3))) {
|
||||
// Hold off fetch from getting new instructions when:
|
||||
// Cache is blocked, or
|
||||
// while an interrupt is pending and we're not in PAL mode, or
|
||||
@@ -588,7 +581,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
|
||||
// Setup the memReq to do a read of the first instruction's address.
|
||||
// Set the appropriate read size and flags as well.
|
||||
// Build request here.
|
||||
RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, flags,
|
||||
RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, 0,
|
||||
fetch_PC, cpu->readCpuId(), tid);
|
||||
|
||||
memReq[tid] = mem_req;
|
||||
@@ -1120,7 +1113,11 @@ DefaultFetch<Impl>::fetch(bool &status_change)
|
||||
inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
|
||||
(&cacheData[tid][offset]));
|
||||
|
||||
ext_inst = TheISA::makeExtMI(inst, cpu->tcBase(tid));
|
||||
#if THE_ISA == ALPHA_ISA
|
||||
ext_inst = TheISA::makeExtMI(inst, fetch_PC);
|
||||
#elif THE_ISA == SPARC_ISA
|
||||
ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC());
|
||||
#endif
|
||||
|
||||
// Create a new DynInst from the instruction fetched.
|
||||
DynInstPtr instruction = new DynInst(ext_inst, fetch_PC,
|
||||
|
||||
@@ -132,6 +132,7 @@ LSQUnit<Impl>::init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries,
|
||||
usedPorts = 0;
|
||||
cachePorts = params->cachePorts;
|
||||
|
||||
retryPkt = NULL;
|
||||
memDepViolator = NULL;
|
||||
|
||||
blockedLoadSeqNum = 0;
|
||||
|
||||
@@ -69,7 +69,7 @@ class MemDepUnit {
|
||||
typedef typename Impl::DynInstPtr DynInstPtr;
|
||||
|
||||
/** Empty constructor. Must call init() prior to using in this case. */
|
||||
MemDepUnit() {}
|
||||
MemDepUnit();
|
||||
|
||||
/** Constructs a MemDepUnit with given parameters. */
|
||||
MemDepUnit(Params *params);
|
||||
|
||||
@@ -33,6 +33,13 @@
|
||||
#include "cpu/o3/inst_queue.hh"
|
||||
#include "cpu/o3/mem_dep_unit.hh"
|
||||
|
||||
template <class MemDepPred, class Impl>
|
||||
MemDepUnit<MemDepPred, Impl>::MemDepUnit()
|
||||
: loadBarrier(false), loadBarrierSN(0), storeBarrier(false),
|
||||
storeBarrierSN(0), iqPtr(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
template <class MemDepPred, class Impl>
|
||||
MemDepUnit<MemDepPred, Impl>::MemDepUnit(Params *params)
|
||||
: depPred(params->SSITSize, params->LFSTSize), loadBarrier(false),
|
||||
@@ -160,8 +167,12 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
|
||||
// producing memrefs/stores.
|
||||
InstSeqNum producing_store;
|
||||
if (inst->isLoad() && loadBarrier) {
|
||||
DPRINTF(MemDepUnit, "Load barrier [sn:%lli] in flight\n",
|
||||
loadBarrierSN);
|
||||
producing_store = loadBarrierSN;
|
||||
} else if (inst->isStore() && storeBarrier) {
|
||||
DPRINTF(MemDepUnit, "Store barrier [sn:%lli] in flight\n",
|
||||
storeBarrierSN);
|
||||
producing_store = storeBarrierSN;
|
||||
} else {
|
||||
producing_store = depPred.checkInst(inst->readPC());
|
||||
@@ -171,10 +182,12 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
|
||||
|
||||
// If there is a producing store, try to find the entry.
|
||||
if (producing_store != 0) {
|
||||
DPRINTF(MemDepUnit, "Searching for producer\n");
|
||||
MemDepHashIt hash_it = memDepHash.find(producing_store);
|
||||
|
||||
if (hash_it != memDepHash.end()) {
|
||||
store_entry = (*hash_it).second;
|
||||
DPRINTF(MemDepUnit, "Proucer found\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,16 +92,15 @@ class MipsO3CPU : public FullO3CPU<Impl>
|
||||
/** Reads a misc. register, including any side effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
TheISA::MiscReg readMiscRegWithEffect(int misc_reg,
|
||||
Fault &fault, unsigned tid);
|
||||
TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
|
||||
|
||||
/** Sets a miscellaneous register. */
|
||||
Fault setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
|
||||
void setMiscReg(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.
|
||||
*/
|
||||
Fault setMiscRegWithEffect(int misc_reg,
|
||||
void setMiscRegWithEffect(int misc_reg,
|
||||
const TheISA::MiscReg &val, unsigned tid);
|
||||
|
||||
/** Initiates a squash of all in-flight instructions for a given
|
||||
|
||||
@@ -54,8 +54,6 @@ Param<int> activity;
|
||||
|
||||
SimObjectVectorParam<Process *> workload;
|
||||
|
||||
SimObjectParam<MemObject *> mem;
|
||||
|
||||
SimObjectParam<BaseCPU *> checker;
|
||||
|
||||
Param<Counter> max_insts_any_thread;
|
||||
@@ -153,8 +151,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
|
||||
|
||||
INIT_PARAM(workload, "Processes to run"),
|
||||
|
||||
INIT_PARAM(mem, "Memory"),
|
||||
|
||||
INIT_PARAM_DFLT(checker, "Checker CPU", NULL),
|
||||
|
||||
INIT_PARAM_DFLT(max_insts_any_thread,
|
||||
@@ -284,8 +280,6 @@ CREATE_SIM_OBJECT(DerivO3CPU)
|
||||
|
||||
params->workload = workload;
|
||||
|
||||
params->mem = mem;
|
||||
|
||||
params->checker = checker;
|
||||
|
||||
params->max_insts_any_thread = max_insts_any_thread;
|
||||
|
||||
@@ -58,24 +58,10 @@ MipsO3CPU<Impl>::MipsO3CPU(Params *params)
|
||||
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, params->mem);
|
||||
this->thread[i] = new Thread(this, i, params->workload[i], i);
|
||||
|
||||
this->thread[i]->setStatus(ThreadContext::Suspended);
|
||||
|
||||
|
||||
/* Use this port to for syscall emulation writes to memory. */
|
||||
Port *mem_port;
|
||||
TranslatingPort *trans_port;
|
||||
trans_port = new TranslatingPort(csprintf("%s-%d-funcport",
|
||||
name(), i),
|
||||
params->workload[i]->pTable,
|
||||
false);
|
||||
mem_port = params->mem->getPort("functional");
|
||||
mem_port->setPeer(trans_port);
|
||||
trans_port->setPeer(mem_port);
|
||||
this->thread[i]->setMemPort(trans_port);
|
||||
|
||||
//usedTids[i] = true;
|
||||
//threadMap[i] = i;
|
||||
} else {
|
||||
@@ -83,7 +69,7 @@ MipsO3CPU<Impl>::MipsO3CPU(Params *params)
|
||||
//when scheduling threads to CPU
|
||||
Process* dummy_proc = NULL;
|
||||
|
||||
this->thread[i] = new Thread(this, i, dummy_proc, i, params->mem);
|
||||
this->thread[i] = new Thread(this, i, dummy_proc, i);
|
||||
//usedTids[i] = false;
|
||||
}
|
||||
|
||||
@@ -156,25 +142,24 @@ MipsO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
|
||||
|
||||
template <class Impl>
|
||||
MiscReg
|
||||
MipsO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, Fault &fault,
|
||||
unsigned tid)
|
||||
MipsO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
|
||||
{
|
||||
return this->regFile.readMiscRegWithEffect(misc_reg, fault, tid);
|
||||
return this->regFile.readMiscRegWithEffect(misc_reg, tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
MipsO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
|
||||
{
|
||||
return this->regFile.setMiscReg(misc_reg, val, tid);
|
||||
this->regFile.setMiscReg(misc_reg, val, tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
MipsO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
|
||||
unsigned tid)
|
||||
{
|
||||
return this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
|
||||
this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
||||
@@ -103,23 +103,22 @@ class MipsDynInst : public BaseDynInst<Impl>
|
||||
/** Reads a misc. register, including any side-effects the read
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
MiscReg readMiscRegWithEffect(int misc_reg)
|
||||
{
|
||||
return this->cpu->readMiscRegWithEffect(misc_reg, fault,
|
||||
this->threadNumber);
|
||||
return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val)
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
this->instResult.integer = val;
|
||||
return this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
|
||||
this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
|
||||
}
|
||||
|
||||
/** Sets a misc. register, including any side-effects the write
|
||||
* might have as defined by the architecture.
|
||||
*/
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return this->cpu->setMiscRegWithEffect(misc_reg, val,
|
||||
this->threadNumber);
|
||||
|
||||
@@ -54,8 +54,6 @@ class O3Params : public BaseO3CPU::Params
|
||||
Process *process;
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
MemObject *mem;
|
||||
|
||||
BaseCPU *checker;
|
||||
|
||||
//
|
||||
|
||||
@@ -37,11 +37,9 @@
|
||||
#include "base/trace.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "cpu/o3/comm.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "kern/kernel_stats.hh"
|
||||
|
||||
#include "arch/kernel_stats.hh"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
@@ -232,31 +230,24 @@ class PhysRegFile
|
||||
return miscRegs[thread_id].readReg(misc_reg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault,
|
||||
unsigned thread_id)
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, unsigned thread_id)
|
||||
{
|
||||
return miscRegs[thread_id].readRegWithEffect(misc_reg, fault,
|
||||
return miscRegs[thread_id].readRegWithEffect(misc_reg,
|
||||
cpu->tcBase(thread_id));
|
||||
}
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id)
|
||||
void setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id)
|
||||
{
|
||||
return miscRegs[thread_id].setReg(misc_reg, val);
|
||||
miscRegs[thread_id].setReg(misc_reg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val,
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val,
|
||||
unsigned thread_id)
|
||||
{
|
||||
return miscRegs[thread_id].setRegWithEffect(misc_reg, val,
|
||||
miscRegs[thread_id].setRegWithEffect(misc_reg, val,
|
||||
cpu->tcBase(thread_id));
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
int readIntrFlag() { return intrflag; }
|
||||
/** Sets an interrupt flag. */
|
||||
void setIntrFlag(int val) { intrflag = val; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
/** (signed) integer register file. */
|
||||
IntReg *intRegFile;
|
||||
|
||||
@@ -83,7 +83,7 @@ class O3ThreadContext : public ThreadContext
|
||||
virtual PhysicalMemory *getPhysMemPtr() { return cpu->physmem; }
|
||||
|
||||
/** Returns a pointer to this thread's kernel statistics. */
|
||||
virtual Kernel::Statistics *getKernelStats()
|
||||
virtual TheISA::Kernel::Statistics *getKernelStats()
|
||||
{ return thread->kernelStats; }
|
||||
|
||||
virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
||||
@@ -201,15 +201,15 @@ class O3ThreadContext : public ThreadContext
|
||||
|
||||
/** Reads a misc. register, including any side-effects the
|
||||
* read might have as defined by the architecture. */
|
||||
virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
{ return cpu->readMiscRegWithEffect(misc_reg, fault, thread->readTid()); }
|
||||
virtual MiscReg readMiscRegWithEffect(int misc_reg)
|
||||
{ return cpu->readMiscRegWithEffect(misc_reg, thread->readTid()); }
|
||||
|
||||
/** Sets a misc. register. */
|
||||
virtual Fault setMiscReg(int misc_reg, const MiscReg &val);
|
||||
virtual void setMiscReg(int misc_reg, const MiscReg &val);
|
||||
|
||||
/** Sets a misc. register, including any side-effects the
|
||||
* write might have as defined by the architecture. */
|
||||
virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
|
||||
virtual void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
|
||||
|
||||
/** Returns the number of consecutive store conditional failures. */
|
||||
// @todo: Figure out where these store cond failures should go.
|
||||
|
||||
@@ -194,7 +194,7 @@ void
|
||||
O3ThreadContext<Impl>::regStats(const std::string &name)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
thread->kernelStats = new Kernel::Statistics(cpu->system);
|
||||
thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system);
|
||||
thread->kernelStats->regStats(name + ".kern");
|
||||
#endif
|
||||
}
|
||||
@@ -439,33 +439,28 @@ O3ThreadContext<Impl>::setNextPC(uint64_t val)
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
Fault ret_fault = cpu->setMiscReg(misc_reg, val, thread->readTid());
|
||||
cpu->setMiscReg(misc_reg, val, thread->readTid());
|
||||
|
||||
// Squash if we're not already in a state update mode.
|
||||
if (!thread->trapPending && !thread->inSyscall) {
|
||||
cpu->squashFromTC(thread->readTid());
|
||||
}
|
||||
|
||||
return ret_fault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
O3ThreadContext<Impl>::setMiscRegWithEffect(int misc_reg,
|
||||
const MiscReg &val)
|
||||
{
|
||||
Fault ret_fault = cpu->setMiscRegWithEffect(misc_reg, val,
|
||||
thread->readTid());
|
||||
cpu->setMiscRegWithEffect(misc_reg, val, thread->readTid());
|
||||
|
||||
// Squash if we're not already in a state update mode.
|
||||
if (!thread->trapPending && !thread->inSyscall) {
|
||||
cpu->squashFromTC(thread->readTid());
|
||||
}
|
||||
|
||||
return ret_fault;
|
||||
}
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
|
||||
@@ -77,7 +77,7 @@ struct O3ThreadState : public ThreadState {
|
||||
|
||||
#if FULL_SYSTEM
|
||||
O3ThreadState(O3CPU *_cpu, int _thread_num)
|
||||
: ThreadState(-1, _thread_num),
|
||||
: ThreadState(_cpu, -1, _thread_num),
|
||||
cpu(_cpu), inSyscall(0), trapPending(0)
|
||||
{
|
||||
if (cpu->params->profile) {
|
||||
@@ -95,9 +95,8 @@ struct O3ThreadState : public ThreadState {
|
||||
profilePC = 3;
|
||||
}
|
||||
#else
|
||||
O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid,
|
||||
MemObject *mem)
|
||||
: ThreadState(-1, _thread_num, _process, _asid, mem),
|
||||
O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid)
|
||||
: ThreadState(_cpu, -1, _thread_num, _process, _asid),
|
||||
cpu(_cpu), inSyscall(0), trapPending(0)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
@@ -68,8 +68,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
|
||||
Param<Tick> progress_interval;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
SimObjectParam<AlphaITB *> itb;
|
||||
SimObjectParam<AlphaDTB *> dtb;
|
||||
SimObjectParam<TheISA::ITB *> itb;
|
||||
SimObjectParam<TheISA::DTB *> dtb;
|
||||
SimObjectParam<System *> system;
|
||||
Param<int> cpu_id;
|
||||
Param<Tick> profile;
|
||||
|
||||
@@ -51,16 +51,21 @@
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/alpha/tlb.hh"
|
||||
|
||||
class AlphaITB;
|
||||
class AlphaDTB;
|
||||
namespace TheISA
|
||||
{
|
||||
class ITB;
|
||||
class DTB;
|
||||
}
|
||||
class PhysicalMemory;
|
||||
class MemoryController;
|
||||
|
||||
class RemoteGDB;
|
||||
class GDBListener;
|
||||
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
namespace TheISA {
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
};
|
||||
};
|
||||
|
||||
#else
|
||||
@@ -120,11 +125,11 @@ class OzoneCPU : public BaseCPU
|
||||
|
||||
PhysicalMemory *getPhysMemPtr() { return cpu->physmem; }
|
||||
|
||||
AlphaITB *getITBPtr() { return cpu->itb; }
|
||||
TheISA::ITB *getITBPtr() { return cpu->itb; }
|
||||
|
||||
AlphaDTB * getDTBPtr() { return cpu->dtb; }
|
||||
TheISA::DTB * getDTBPtr() { return cpu->dtb; }
|
||||
|
||||
Kernel::Statistics *getKernelStats()
|
||||
TheISA::Kernel::Statistics *getKernelStats()
|
||||
{ return thread->getKernelStats(); }
|
||||
|
||||
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
||||
@@ -224,11 +229,11 @@ class OzoneCPU : public BaseCPU
|
||||
// ISA stuff:
|
||||
MiscReg readMiscReg(int misc_reg);
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault);
|
||||
MiscReg readMiscRegWithEffect(int misc_reg);
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val);
|
||||
void setMiscReg(int misc_reg, const MiscReg &val);
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
|
||||
|
||||
unsigned readStCondFailures()
|
||||
{ return thread->storeCondFailures; }
|
||||
@@ -236,10 +241,6 @@ class OzoneCPU : public BaseCPU
|
||||
void setStCondFailures(unsigned sc_failures)
|
||||
{ thread->storeCondFailures = sc_failures; }
|
||||
|
||||
#if FULL_SYSTEM
|
||||
bool inPalMode() { return cpu->inPalMode(); }
|
||||
#endif
|
||||
|
||||
bool misspeculating() { return false; }
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
@@ -360,16 +361,14 @@ class OzoneCPU : public BaseCPU
|
||||
|
||||
bool interval_stats;
|
||||
|
||||
AlphaITB *itb;
|
||||
AlphaDTB *dtb;
|
||||
TheISA::ITB *itb;
|
||||
TheISA::DTB *dtb;
|
||||
System *system;
|
||||
PhysicalMemory *physmem;
|
||||
#endif
|
||||
|
||||
virtual Port *getPort(const std::string &name, int idx);
|
||||
|
||||
MemObject *mem;
|
||||
|
||||
FrontEnd *frontEnd;
|
||||
|
||||
BackEnd *backEnd;
|
||||
@@ -583,10 +582,6 @@ class OzoneCPU : public BaseCPU
|
||||
|
||||
#if FULL_SYSTEM
|
||||
Fault hwrei();
|
||||
int readIntrFlag() { return thread.intrflag; }
|
||||
void setIntrFlag(int val) { thread.intrflag = val; }
|
||||
bool inPalMode() { return AlphaISA::PcPAL(thread.PC); }
|
||||
bool inPalMode(Addr pc) { return AlphaISA::PcPAL(pc); }
|
||||
bool simPalCheck(int palFunc);
|
||||
void processInterrupts();
|
||||
#else
|
||||
|
||||
@@ -61,16 +61,14 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivOzoneCPU)
|
||||
#if FULL_SYSTEM
|
||||
SimObjectParam<System *> system;
|
||||
Param<int> cpu_id;
|
||||
SimObjectParam<AlphaITB *> itb;
|
||||
SimObjectParam<AlphaDTB *> dtb;
|
||||
SimObjectParam<TheISA::ITB *> itb;
|
||||
SimObjectParam<TheISA::DTB *> dtb;
|
||||
Param<Tick> profile;
|
||||
#else
|
||||
SimObjectVectorParam<Process *> workload;
|
||||
//SimObjectParam<PageTable *> page_table;
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
SimObjectParam<MemObject *> mem;
|
||||
|
||||
SimObjectParam<BaseCPU *> checker;
|
||||
|
||||
Param<Counter> max_insts_any_thread;
|
||||
@@ -191,8 +189,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
|
||||
// INIT_PARAM(page_table, "Page table"),
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
INIT_PARAM_DFLT(mem, "Memory", NULL),
|
||||
|
||||
INIT_PARAM_DFLT(checker, "Checker CPU", NULL),
|
||||
|
||||
INIT_PARAM_DFLT(max_insts_any_thread,
|
||||
@@ -350,7 +346,6 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
|
||||
// params->pTable = page_table;
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
params->mem = mem;
|
||||
params->checker = checker;
|
||||
params->max_insts_any_thread = max_insts_any_thread;
|
||||
params->max_insts_all_threads = max_insts_all_threads;
|
||||
|
||||
@@ -47,12 +47,12 @@
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/faults.hh"
|
||||
#include "arch/alpha/osfpal.hh"
|
||||
#include "arch/alpha/tlb.hh"
|
||||
#include "arch/alpha/types.hh"
|
||||
#include "arch/tlb.hh"
|
||||
#include "arch/types.hh"
|
||||
#include "arch/kernel_stats.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "base/callback.hh"
|
||||
#include "cpu/profile.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "sim/faults.hh"
|
||||
#include "sim/sim_events.hh"
|
||||
@@ -93,10 +93,10 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
|
||||
#if FULL_SYSTEM
|
||||
: BaseCPU(p), thread(this, 0), tickEvent(this, p->width),
|
||||
#else
|
||||
: BaseCPU(p), thread(this, 0, p->workload[0], 0, p->mem),
|
||||
: BaseCPU(p), thread(this, 0, p->workload[0], 0),
|
||||
tickEvent(this, p->width),
|
||||
#endif
|
||||
mem(p->mem), comm(5, 5)
|
||||
comm(5, 5)
|
||||
{
|
||||
frontEnd = new FrontEnd(p);
|
||||
backEnd = new BackEnd(p);
|
||||
@@ -107,7 +107,6 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
|
||||
#if USE_CHECKER
|
||||
BaseCPU *temp_checker = p->checker;
|
||||
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
|
||||
checker->setMemory(mem);
|
||||
#if FULL_SYSTEM
|
||||
checker->setSystem(p->system);
|
||||
#endif
|
||||
@@ -198,19 +197,7 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
|
||||
frontEnd->renameTable.copyFrom(thread.renameTable);
|
||||
backEnd->renameTable.copyFrom(thread.renameTable);
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
/* Use this port to for syscall emulation writes to memory. */
|
||||
Port *mem_port;
|
||||
TranslatingPort *trans_port;
|
||||
trans_port = new TranslatingPort(csprintf("%s-%d-funcport",
|
||||
name(), 0),
|
||||
p->workload[0]->pTable,
|
||||
false);
|
||||
mem_port = p->mem->getPort("functional");
|
||||
mem_port->setPeer(trans_port);
|
||||
trans_port->setPeer(mem_port);
|
||||
thread.setMemPort(trans_port);
|
||||
#else
|
||||
#if FULL_SYSTEM
|
||||
Port *mem_port;
|
||||
FunctionalPort *phys_port;
|
||||
VirtualPort *virt_port;
|
||||
@@ -904,7 +891,7 @@ void
|
||||
OzoneCPU<Impl>::OzoneTC::regStats(const std::string &name)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
thread->kernelStats = new Kernel::Statistics(cpu->system);
|
||||
thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system);
|
||||
thread->kernelStats->regStats(name + ".kern");
|
||||
#endif
|
||||
}
|
||||
@@ -1156,37 +1143,31 @@ OzoneCPU<Impl>::OzoneTC::readMiscReg(int misc_reg)
|
||||
|
||||
template <class Impl>
|
||||
TheISA::MiscReg
|
||||
OzoneCPU<Impl>::OzoneTC::readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
OzoneCPU<Impl>::OzoneTC::readMiscRegWithEffect(int misc_reg)
|
||||
{
|
||||
return thread->miscRegFile.readRegWithEffect(misc_reg,
|
||||
fault, this);
|
||||
return thread->miscRegFile.readRegWithEffect(misc_reg, this);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
// Needs to setup a squash event unless we're in syscall mode
|
||||
Fault ret_fault = thread->miscRegFile.setReg(misc_reg, val);
|
||||
thread->miscRegFile.setReg(misc_reg, val);
|
||||
|
||||
if (!thread->inSyscall) {
|
||||
cpu->squashFromTC();
|
||||
}
|
||||
|
||||
return ret_fault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
OzoneCPU<Impl>::OzoneTC::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
// Needs to setup a squash event unless we're in syscall mode
|
||||
Fault ret_fault = thread->miscRegFile.setRegWithEffect(misc_reg, val,
|
||||
this);
|
||||
thread->miscRegFile.setRegWithEffect(misc_reg, val, this);
|
||||
|
||||
if (!thread->inSyscall) {
|
||||
cpu->squashFromTC();
|
||||
}
|
||||
|
||||
return ret_fault;
|
||||
}
|
||||
|
||||
@@ -230,17 +230,14 @@ class OzoneDynInst : public BaseDynInst<Impl>
|
||||
// ISA stuff
|
||||
MiscReg readMiscReg(int misc_reg);
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault);
|
||||
MiscReg readMiscRegWithEffect(int misc_reg);
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val);
|
||||
void setMiscReg(int misc_reg, const MiscReg &val);
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
Fault hwrei();
|
||||
int readIntrFlag();
|
||||
void setIntrFlag(int val);
|
||||
bool inPalMode();
|
||||
void trap(Fault fault);
|
||||
bool simPalCheck(int palFunc);
|
||||
#else
|
||||
|
||||
@@ -31,7 +31,10 @@
|
||||
#include "sim/faults.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "cpu/ozone/dyn_inst.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "kern/kernel_stats.hh"
|
||||
#endif
|
||||
|
||||
template <class Impl>
|
||||
OzoneDynInst<Impl>::OzoneDynInst(OzoneCPU *cpu)
|
||||
@@ -223,24 +226,24 @@ OzoneDynInst<Impl>::readMiscReg(int misc_reg)
|
||||
|
||||
template <class Impl>
|
||||
TheISA::MiscReg
|
||||
OzoneDynInst<Impl>::readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
OzoneDynInst<Impl>::readMiscRegWithEffect(int misc_reg)
|
||||
{
|
||||
return this->thread->readMiscRegWithEffect(misc_reg, fault);
|
||||
return this->thread->readMiscRegWithEffect(misc_reg);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
OzoneDynInst<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
this->setIntResult(val);
|
||||
return this->thread->setMiscReg(misc_reg, val);
|
||||
this->thread->setMiscReg(misc_reg, val);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
void
|
||||
OzoneDynInst<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return this->thread->setMiscRegWithEffect(misc_reg, val);
|
||||
this->thread->setMiscRegWithEffect(misc_reg, val);
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
@@ -249,7 +252,7 @@ template <class Impl>
|
||||
Fault
|
||||
OzoneDynInst<Impl>::hwrei()
|
||||
{
|
||||
if (!this->cpu->inPalMode(this->readPC()))
|
||||
if (!(this->readPC() & 0x3))
|
||||
return new AlphaISA::UnimplementedOpcodeFault;
|
||||
|
||||
this->setNextPC(this->thread->readMiscReg(AlphaISA::IPR_EXC_ADDR));
|
||||
@@ -260,27 +263,6 @@ OzoneDynInst<Impl>::hwrei()
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
int
|
||||
OzoneDynInst<Impl>::readIntrFlag()
|
||||
{
|
||||
return this->cpu->readIntrFlag();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
OzoneDynInst<Impl>::setIntrFlag(int val)
|
||||
{
|
||||
this->cpu->setIntrFlag(val);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
bool
|
||||
OzoneDynInst<Impl>::inPalMode()
|
||||
{
|
||||
return this->cpu->inPalMode();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
OzoneDynInst<Impl>::trap(Fault fault)
|
||||
|
||||
@@ -208,8 +208,6 @@ class FrontEnd
|
||||
|
||||
IcachePort icachePort;
|
||||
|
||||
MemObject *mem;
|
||||
|
||||
RequestPtr memReq;
|
||||
|
||||
/** Mask to get a cache block's address. */
|
||||
|
||||
@@ -91,7 +91,6 @@ template <class Impl>
|
||||
FrontEnd<Impl>::FrontEnd(Params *params)
|
||||
: branchPred(params),
|
||||
icachePort(this),
|
||||
mem(params->mem),
|
||||
numInstsReady(params->frontEndLatency, 0),
|
||||
instBufferSize(0),
|
||||
maxInstBufferSize(params->maxInstBufferSize),
|
||||
@@ -463,15 +462,10 @@ Fault
|
||||
FrontEnd<Impl>::fetchCacheLine()
|
||||
{
|
||||
// Read a cache line, based on the current PC.
|
||||
#if FULL_SYSTEM
|
||||
// Flag to say whether or not address is physical addr.
|
||||
unsigned flags = cpu->inPalMode(PC) ? PHYSICAL : 0;
|
||||
#else
|
||||
unsigned flags = 0;
|
||||
#endif // FULL_SYSTEM
|
||||
Fault fault = NoFault;
|
||||
|
||||
if (interruptPending && flags == 0) {
|
||||
//AlphaDep
|
||||
if (interruptPending && (PC & 0x3)) {
|
||||
return fault;
|
||||
}
|
||||
|
||||
@@ -883,7 +877,11 @@ FrontEnd<Impl>::getInstFromCacheline()
|
||||
// Get the instruction from the array of the cache line.
|
||||
inst = htog(*reinterpret_cast<MachInst *>(&cacheData[offset]));
|
||||
|
||||
#if THE_ISA == ALPHA_ISA
|
||||
ExtMachInst decode_inst = TheISA::makeExtMI(inst, PC);
|
||||
#elif THE_ISA == SPARC_ISA
|
||||
ExtMachInst decode_inst = TheISA::makeExtMI(inst, tc);
|
||||
#endif
|
||||
|
||||
// Create a new DynInst from the instruction fetched.
|
||||
DynInstPtr instruction = new DynInst(decode_inst, PC, PC+sizeof(MachInst),
|
||||
|
||||
@@ -152,11 +152,11 @@ InorderBackEnd<Impl>::tick()
|
||||
#if FULL_SYSTEM
|
||||
if (interruptBlocked ||
|
||||
(cpu->checkInterrupts &&
|
||||
cpu->check_interrupts() &&
|
||||
!cpu->inPalMode())) {
|
||||
cpu->check_interrupts(tc))) {
|
||||
if (!robEmpty()) {
|
||||
interruptBlocked = true;
|
||||
} else if (robEmpty() && cpu->inPalMode()) {
|
||||
//AlphaDep
|
||||
} else if (robEmpty() && (PC & 0x3)) {
|
||||
// Will need to let the front end continue a bit until
|
||||
// we're out of pal mode. Hopefully we never get into an
|
||||
// infinite loop...
|
||||
|
||||
@@ -526,8 +526,7 @@ void
|
||||
LWBackEnd<Impl>::checkInterrupts()
|
||||
{
|
||||
if (cpu->checkInterrupts &&
|
||||
cpu->check_interrupts() &&
|
||||
!cpu->inPalMode(thread->readPC()) &&
|
||||
cpu->check_interrupts(tc) &&
|
||||
!trapSquash &&
|
||||
!tcSquash) {
|
||||
frontEnd->interruptPending = true;
|
||||
|
||||
@@ -239,8 +239,6 @@ class OzoneLWLSQ {
|
||||
/** Pointer to the back-end stage. */
|
||||
BackEnd *be;
|
||||
|
||||
MemObject *mem;
|
||||
|
||||
class DcachePort : public Port
|
||||
{
|
||||
protected:
|
||||
|
||||
@@ -154,8 +154,6 @@ OzoneLWLSQ<Impl>::init(Params *params, unsigned maxLQEntries,
|
||||
SQIndices.push(i);
|
||||
}
|
||||
|
||||
mem = params->mem;
|
||||
|
||||
usedPorts = 0;
|
||||
cachePorts = params->cachePorts;
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
|
||||
#if FULL_SYSTEM
|
||||
SimObjectParam<System *> system;
|
||||
Param<int> cpu_id;
|
||||
SimObjectParam<AlphaITB *> itb;
|
||||
SimObjectParam<AlphaDTB *> dtb;
|
||||
SimObjectParam<TheISA::ITB *> itb;
|
||||
SimObjectParam<TheISA::DTB *> dtb;
|
||||
#else
|
||||
SimObjectVectorParam<Process *> workload;
|
||||
//SimObjectParam<PageTable *> page_table;
|
||||
|
||||
@@ -34,8 +34,11 @@
|
||||
#include "cpu/ozone/cpu.hh"
|
||||
|
||||
//Forward declarations
|
||||
class AlphaDTB;
|
||||
class AlphaITB;
|
||||
namespace TheISA
|
||||
{
|
||||
class DTB;
|
||||
class ITB;
|
||||
}
|
||||
class FUPool;
|
||||
class MemObject;
|
||||
class PageTable;
|
||||
@@ -53,7 +56,7 @@ class SimpleParams : public BaseCPU::Params
|
||||
public:
|
||||
|
||||
#if FULL_SYSTEM
|
||||
AlphaITB *itb; AlphaDTB *dtb;
|
||||
TheISA::ITB *itb; TheISA::DTB *dtb;
|
||||
#else
|
||||
std::vector<Process *> workload;
|
||||
#endif // FULL_SYSTEM
|
||||
@@ -61,8 +64,6 @@ class SimpleParams : public BaseCPU::Params
|
||||
//Page Table
|
||||
PageTable *pTable;
|
||||
|
||||
MemObject *mem;
|
||||
|
||||
//
|
||||
// Caches
|
||||
//
|
||||
|
||||
@@ -67,7 +67,7 @@ struct OzoneThreadState : public ThreadState {
|
||||
|
||||
#if FULL_SYSTEM
|
||||
OzoneThreadState(CPUType *_cpu, int _thread_num)
|
||||
: ThreadState(-1, _thread_num),
|
||||
: ThreadState(_cpu, -1, _thread_num),
|
||||
intrflag(0), cpu(_cpu), inSyscall(0), trapPending(0)
|
||||
{
|
||||
if (cpu->params->profile) {
|
||||
@@ -87,8 +87,8 @@ struct OzoneThreadState : public ThreadState {
|
||||
}
|
||||
#else
|
||||
OzoneThreadState(CPUType *_cpu, int _thread_num, Process *_process,
|
||||
int _asid, MemObject *mem)
|
||||
: ThreadState(-1, _thread_num, _process, _asid, mem),
|
||||
int _asid)
|
||||
: ThreadState(_cpu, -1, _thread_num, _process, _asid),
|
||||
cpu(_cpu), inSyscall(0), trapPending(0)
|
||||
{
|
||||
miscRegFile.clear();
|
||||
@@ -120,19 +120,19 @@ struct OzoneThreadState : public ThreadState {
|
||||
return miscRegFile.readReg(misc_reg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
MiscReg readMiscRegWithEffect(int misc_reg)
|
||||
{
|
||||
return miscRegFile.readRegWithEffect(misc_reg, fault, tc);
|
||||
return miscRegFile.readRegWithEffect(misc_reg, tc);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val)
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return miscRegFile.setReg(misc_reg, val);
|
||||
miscRegFile.setReg(misc_reg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return miscRegFile.setRegWithEffect(misc_reg, val, tc);
|
||||
miscRegFile.setRegWithEffect(misc_reg, val, tc);
|
||||
}
|
||||
|
||||
uint64_t readPC()
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "sim/host.hh"
|
||||
|
||||
class ThreadContext;
|
||||
class PCEventQueue;
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "arch/stacktrace.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "arch/stacktrace.hh"
|
||||
|
||||
class ThreadContext;
|
||||
|
||||
@@ -66,7 +66,7 @@ class FunctionProfile
|
||||
const SymbolTable *symtab;
|
||||
ProfileNode top;
|
||||
std::map<Addr, Counter> pc_count;
|
||||
StackTrace trace;
|
||||
TheISA::StackTrace trace;
|
||||
|
||||
public:
|
||||
FunctionProfile(const SymbolTable *symtab);
|
||||
|
||||
@@ -72,15 +72,6 @@ AtomicSimpleCPU::getPort(const std::string &if_name, int idx)
|
||||
void
|
||||
AtomicSimpleCPU::init()
|
||||
{
|
||||
//Create Memory Ports (conect them up)
|
||||
// Port *mem_dport = mem->getPort("");
|
||||
// dcachePort.setPeer(mem_dport);
|
||||
// mem_dport->setPeer(&dcachePort);
|
||||
|
||||
// Port *mem_iport = mem->getPort("");
|
||||
// icachePort.setPeer(mem_iport);
|
||||
// mem_iport->setPeer(&icachePort);
|
||||
|
||||
BaseCPU::init();
|
||||
#if FULL_SYSTEM
|
||||
for (int i = 0; i < threadContexts.size(); ++i) {
|
||||
@@ -189,9 +180,7 @@ AtomicSimpleCPU::resume()
|
||||
changeState(SimObject::Running);
|
||||
if (thread->status() == ThreadContext::Active) {
|
||||
if (!tickEvent.scheduled()) {
|
||||
Tick nextTick = curTick + cycles(1) - 1;
|
||||
nextTick -= (nextTick % (cycles(1)));
|
||||
tickEvent.schedule(nextTick);
|
||||
tickEvent.schedule(nextCycle());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,9 +209,7 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||
ThreadContext *tc = threadContexts[i];
|
||||
if (tc->status() == ThreadContext::Active && _status != Running) {
|
||||
_status = Running;
|
||||
Tick nextTick = curTick + cycles(1) - 1;
|
||||
nextTick -= (nextTick % (cycles(1)));
|
||||
tickEvent.schedule(nextTick);
|
||||
tickEvent.schedule(nextCycle());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -240,9 +227,7 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay)
|
||||
|
||||
notIdleFraction++;
|
||||
//Make sure ticks are still on multiples of cycles
|
||||
Tick nextTick = curTick + cycles(delay + 1) - 1;
|
||||
nextTick -= (nextTick % (cycles(1)));
|
||||
tickEvent.schedule(nextTick);
|
||||
tickEvent.schedule(nextCycle(curTick + cycles(delay)));
|
||||
_status = Running;
|
||||
}
|
||||
|
||||
@@ -508,13 +493,12 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU)
|
||||
Param<Counter> max_loads_any_thread;
|
||||
Param<Counter> max_loads_all_threads;
|
||||
Param<Tick> progress_interval;
|
||||
SimObjectParam<MemObject *> mem;
|
||||
SimObjectParam<System *> system;
|
||||
Param<int> cpu_id;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
SimObjectParam<AlphaITB *> itb;
|
||||
SimObjectParam<AlphaDTB *> dtb;
|
||||
SimObjectParam<TheISA::ITB *> itb;
|
||||
SimObjectParam<TheISA::DTB *> dtb;
|
||||
Param<Tick> profile;
|
||||
#else
|
||||
SimObjectParam<Process *> workload;
|
||||
@@ -541,7 +525,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU)
|
||||
INIT_PARAM(max_loads_all_threads,
|
||||
"terminate when all threads have reached this load count"),
|
||||
INIT_PARAM(progress_interval, "Progress interval"),
|
||||
INIT_PARAM(mem, "memory"),
|
||||
INIT_PARAM(system, "system object"),
|
||||
INIT_PARAM(cpu_id, "processor ID"),
|
||||
|
||||
@@ -579,7 +562,6 @@ CREATE_SIM_OBJECT(AtomicSimpleCPU)
|
||||
params->functionTraceStart = function_trace_start;
|
||||
params->width = width;
|
||||
params->simulate_stalls = simulate_stalls;
|
||||
params->mem = mem;
|
||||
params->system = system;
|
||||
params->cpu_id = cpu_id;
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
||||
public:
|
||||
|
||||
CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu)
|
||||
: Port(_name), cpu(_cpu)
|
||||
: Port(_name, _cpu), cpu(_cpu)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#include "cpu/smt.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#include "mem/packet.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
@@ -58,10 +57,11 @@
|
||||
#include "sim/system.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "base/remote_gdb.hh"
|
||||
#include "arch/tlb.hh"
|
||||
#include "arch/kernel_stats.hh"
|
||||
#include "arch/stacktrace.hh"
|
||||
#include "arch/tlb.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "base/remote_gdb.hh"
|
||||
#else // !FULL_SYSTEM
|
||||
#include "mem/mem_object.hh"
|
||||
#endif // FULL_SYSTEM
|
||||
@@ -70,13 +70,13 @@ using namespace std;
|
||||
using namespace TheISA;
|
||||
|
||||
BaseSimpleCPU::BaseSimpleCPU(Params *p)
|
||||
: BaseCPU(p), mem(p->mem), thread(NULL)
|
||||
: BaseCPU(p), thread(NULL)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
|
||||
#else
|
||||
thread = new SimpleThread(this, /* thread_num */ 0, p->process,
|
||||
/* asid */ 0, mem);
|
||||
/* asid */ 0);
|
||||
#endif // !FULL_SYSTEM
|
||||
|
||||
thread->setStatus(ThreadContext::Suspended);
|
||||
@@ -311,43 +311,12 @@ void
|
||||
BaseSimpleCPU::checkForInterrupts()
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if (checkInterrupts && check_interrupts() && !thread->inPalMode()) {
|
||||
int ipl = 0;
|
||||
int summary = 0;
|
||||
checkInterrupts = false;
|
||||
if (checkInterrupts && check_interrupts(tc)) {
|
||||
Fault interrupt = interrupts.getInterrupt(tc);
|
||||
|
||||
if (thread->readMiscReg(IPR_SIRR)) {
|
||||
for (int i = INTLEVEL_SOFTWARE_MIN;
|
||||
i < INTLEVEL_SOFTWARE_MAX; i++) {
|
||||
if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
|
||||
// See table 4-19 of 21164 hardware reference
|
||||
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
|
||||
summary |= (ULL(1) << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t interrupts = thread->cpu->intr_status();
|
||||
for (int i = INTLEVEL_EXTERNAL_MIN;
|
||||
i < INTLEVEL_EXTERNAL_MAX; i++) {
|
||||
if (interrupts & (ULL(1) << i)) {
|
||||
// See table 4-19 of 21164 hardware reference
|
||||
ipl = i;
|
||||
summary |= (ULL(1) << i);
|
||||
}
|
||||
}
|
||||
|
||||
if (thread->readMiscReg(IPR_ASTRR))
|
||||
panic("asynchronous traps not implemented\n");
|
||||
|
||||
if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) {
|
||||
thread->setMiscReg(IPR_ISR, summary);
|
||||
thread->setMiscReg(IPR_INTID, ipl);
|
||||
|
||||
Fault(new InterruptFault)->invoke(tc);
|
||||
|
||||
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
|
||||
thread->readMiscReg(IPR_IPLR), ipl, summary);
|
||||
if (interrupt != NoFault) {
|
||||
checkInterrupts = false;
|
||||
interrupt->invoke(tc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -398,7 +367,15 @@ BaseSimpleCPU::preExecute()
|
||||
inst = gtoh(inst);
|
||||
//If we're not in the middle of a macro instruction
|
||||
if (!curMacroStaticInst) {
|
||||
#if THE_ISA == ALPHA_ISA
|
||||
StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC()));
|
||||
#elif THE_ISA == SPARC_ISA
|
||||
StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC()));
|
||||
#elif THE_ISA == MIPS_ISA
|
||||
//Mips doesn't do anything in it's MakeExtMI function right now,
|
||||
//so it won't be called.
|
||||
StaticInstPtr instPtr = StaticInst::decode(inst);
|
||||
#endif
|
||||
if (instPtr->isMacroOp()) {
|
||||
curMacroStaticInst = instPtr;
|
||||
curStaticInst = curMacroStaticInst->
|
||||
@@ -430,8 +407,7 @@ BaseSimpleCPU::postExecute()
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if (thread->profile) {
|
||||
bool usermode =
|
||||
(thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
|
||||
bool usermode = TheISA::inUserMode(tc);
|
||||
thread->profilePC = usermode ? 1 : thread->readPC();
|
||||
ProfileNode *node = thread->profile->consume(tc, inst);
|
||||
if (node)
|
||||
|
||||
@@ -47,8 +47,11 @@
|
||||
// forward declarations
|
||||
#if FULL_SYSTEM
|
||||
class Processor;
|
||||
class AlphaITB;
|
||||
class AlphaDTB;
|
||||
namespace TheISA
|
||||
{
|
||||
class ITB;
|
||||
class DTB;
|
||||
}
|
||||
class MemObject;
|
||||
|
||||
class RemoteGDB;
|
||||
@@ -76,8 +79,6 @@ class BaseSimpleCPU : public BaseCPU
|
||||
typedef TheISA::FloatReg FloatReg;
|
||||
typedef TheISA::FloatRegBits FloatRegBits;
|
||||
|
||||
MemObject *mem;
|
||||
|
||||
protected:
|
||||
Trace::InstRecord *traceData;
|
||||
|
||||
@@ -95,10 +96,9 @@ class BaseSimpleCPU : public BaseCPU
|
||||
public:
|
||||
struct Params : public BaseCPU::Params
|
||||
{
|
||||
MemObject *mem;
|
||||
#if FULL_SYSTEM
|
||||
AlphaITB *itb;
|
||||
AlphaDTB *dtb;
|
||||
TheISA::ITB *itb;
|
||||
TheISA::DTB *dtb;
|
||||
#else
|
||||
Process *process;
|
||||
#endif
|
||||
@@ -285,26 +285,23 @@ class BaseSimpleCPU : public BaseCPU
|
||||
return thread->readMiscReg(misc_reg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
MiscReg readMiscRegWithEffect(int misc_reg)
|
||||
{
|
||||
return thread->readMiscRegWithEffect(misc_reg, fault);
|
||||
return thread->readMiscRegWithEffect(misc_reg);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val)
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return thread->setMiscReg(misc_reg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return thread->setMiscRegWithEffect(misc_reg, val);
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
Fault hwrei() { return thread->hwrei(); }
|
||||
int readIntrFlag() { return thread->readIntrFlag(); }
|
||||
void setIntrFlag(int val) { thread->setIntrFlag(val); }
|
||||
bool inPalMode() { return thread->inPalMode(); }
|
||||
void ev5_trap(Fault fault) { fault->invoke(tc); }
|
||||
bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
|
||||
#else
|
||||
|
||||
@@ -532,14 +532,13 @@ TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt)
|
||||
{
|
||||
if (pkt->isResponse()) {
|
||||
// delay processing of returned data until next CPU clock edge
|
||||
Tick time = pkt->req->getTime();
|
||||
while (time < curTick)
|
||||
time += lat;
|
||||
Tick mem_time = pkt->req->getTime();
|
||||
Tick next_tick = cpu->nextCycle(mem_time);
|
||||
|
||||
if (time == curTick)
|
||||
if (next_tick == curTick)
|
||||
cpu->completeIfetch(pkt);
|
||||
else
|
||||
tickEvent.schedule(pkt, time);
|
||||
tickEvent.schedule(pkt, next_tick);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -610,14 +609,13 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
|
||||
{
|
||||
if (pkt->isResponse()) {
|
||||
// delay processing of returned data until next CPU clock edge
|
||||
Tick time = pkt->req->getTime();
|
||||
while (time < curTick)
|
||||
time += lat;
|
||||
Tick mem_time = pkt->req->getTime();
|
||||
Tick next_tick = cpu->nextCycle(mem_time);
|
||||
|
||||
if (time == curTick)
|
||||
if (next_tick == curTick)
|
||||
cpu->completeDataAccess(pkt);
|
||||
else
|
||||
tickEvent.schedule(pkt, time);
|
||||
tickEvent.schedule(pkt, next_tick);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -660,13 +658,12 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU)
|
||||
Param<Counter> max_loads_any_thread;
|
||||
Param<Counter> max_loads_all_threads;
|
||||
Param<Tick> progress_interval;
|
||||
SimObjectParam<MemObject *> mem;
|
||||
SimObjectParam<System *> system;
|
||||
Param<int> cpu_id;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
SimObjectParam<AlphaITB *> itb;
|
||||
SimObjectParam<AlphaDTB *> dtb;
|
||||
SimObjectParam<TheISA::ITB *> itb;
|
||||
SimObjectParam<TheISA::DTB *> dtb;
|
||||
Param<Tick> profile;
|
||||
#else
|
||||
SimObjectParam<Process *> workload;
|
||||
@@ -693,7 +690,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TimingSimpleCPU)
|
||||
INIT_PARAM(max_loads_all_threads,
|
||||
"terminate when all threads have reached this load count"),
|
||||
INIT_PARAM(progress_interval, "Progress interval"),
|
||||
INIT_PARAM(mem, "memory"),
|
||||
INIT_PARAM(system, "system object"),
|
||||
INIT_PARAM(cpu_id, "processor ID"),
|
||||
|
||||
@@ -729,7 +725,6 @@ CREATE_SIM_OBJECT(TimingSimpleCPU)
|
||||
params->clock = clock;
|
||||
params->functionTrace = function_trace;
|
||||
params->functionTraceStart = function_trace_start;
|
||||
params->mem = mem;
|
||||
params->system = system;
|
||||
params->cpu_id = cpu_id;
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||
public:
|
||||
|
||||
CpuPort(const std::string &_name, TimingSimpleCPU *_cpu, Tick _lat)
|
||||
: Port(_name), cpu(_cpu), lat(_lat)
|
||||
: Port(_name, _cpu), cpu(_cpu), lat(_lat)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
@@ -166,6 +166,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||
PacketPtr ifetch_pkt;
|
||||
PacketPtr dcache_pkt;
|
||||
|
||||
|
||||
|
||||
int cpu_id;
|
||||
Tick previousTick;
|
||||
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/kernel_stats.hh"
|
||||
#include "base/callback.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/output.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/profile.hh"
|
||||
#include "cpu/quiesce_event.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
#include "arch/stacktrace.hh"
|
||||
@@ -60,9 +60,9 @@ using namespace std;
|
||||
// constructor
|
||||
#if FULL_SYSTEM
|
||||
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
|
||||
AlphaITB *_itb, AlphaDTB *_dtb,
|
||||
TheISA::ITB *_itb, TheISA::DTB *_dtb,
|
||||
bool use_kernel_stats)
|
||||
: ThreadState(-1, _thread_num), cpu(_cpu), system(_sys), itb(_itb),
|
||||
: ThreadState(_cpu, -1, _thread_num), cpu(_cpu), system(_sys), itb(_itb),
|
||||
dtb(_dtb)
|
||||
|
||||
{
|
||||
@@ -87,7 +87,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
|
||||
profilePC = 3;
|
||||
|
||||
if (use_kernel_stats) {
|
||||
kernelStats = new Kernel::Statistics(system);
|
||||
kernelStats = new TheISA::Kernel::Statistics(system);
|
||||
} else {
|
||||
kernelStats = NULL;
|
||||
}
|
||||
@@ -106,19 +106,10 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
|
||||
}
|
||||
#else
|
||||
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
|
||||
Process *_process, int _asid, MemObject* memobj)
|
||||
: ThreadState(-1, _thread_num, _process, _asid, memobj),
|
||||
Process *_process, int _asid)
|
||||
: ThreadState(_cpu, -1, _thread_num, _process, _asid),
|
||||
cpu(_cpu)
|
||||
{
|
||||
/* Use this port to for syscall emulation writes to memory. */
|
||||
Port *mem_port;
|
||||
port = new TranslatingPort(csprintf("%s-%d-funcport",
|
||||
cpu->name(), tid),
|
||||
process->pTable, false);
|
||||
mem_port = memobj->getPort("functional");
|
||||
mem_port->setPeer(port);
|
||||
port->setPeer(mem_port);
|
||||
|
||||
regs.clear();
|
||||
tc = new ProxyThreadContext<SimpleThread>(this);
|
||||
}
|
||||
@@ -127,9 +118,9 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
|
||||
|
||||
SimpleThread::SimpleThread()
|
||||
#if FULL_SYSTEM
|
||||
: ThreadState(-1, -1)
|
||||
: ThreadState(NULL, -1, -1)
|
||||
#else
|
||||
: ThreadState(-1, -1, NULL, -1, NULL)
|
||||
: ThreadState(NULL, -1, -1, NULL, -1)
|
||||
#endif
|
||||
{
|
||||
tc = new ProxyThreadContext<SimpleThread>(this);
|
||||
@@ -138,6 +129,10 @@ SimpleThread::SimpleThread()
|
||||
|
||||
SimpleThread::~SimpleThread()
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
delete physPort;
|
||||
delete virtPort;
|
||||
#endif
|
||||
delete tc;
|
||||
}
|
||||
|
||||
@@ -163,7 +158,7 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
|
||||
quiesceEvent->tc = tc;
|
||||
}
|
||||
|
||||
Kernel::Statistics *stats = oldContext->getKernelStats();
|
||||
TheISA::Kernel::Statistics *stats = oldContext->getKernelStats();
|
||||
if (stats) {
|
||||
kernelStats = stats;
|
||||
}
|
||||
@@ -184,7 +179,7 @@ SimpleThread::copyTC(ThreadContext *context)
|
||||
if (quiesce) {
|
||||
quiesceEvent = quiesce;
|
||||
}
|
||||
Kernel::Statistics *stats = context->getKernelStats();
|
||||
TheISA::Kernel::Statistics *stats = context->getKernelStats();
|
||||
if (stats) {
|
||||
kernelStats = stats;
|
||||
}
|
||||
@@ -313,11 +308,9 @@ SimpleThread::getVirtPort(ThreadContext *src_tc)
|
||||
if (!src_tc)
|
||||
return virtPort;
|
||||
|
||||
VirtualPort *vp;
|
||||
Port *mem_port;
|
||||
VirtualPort *vp = new VirtualPort("tc-vport", src_tc);
|
||||
Port *mem_port = getMemFuncPort();
|
||||
|
||||
vp = new VirtualPort("tc-vport", src_tc);
|
||||
mem_port = system->physmem->getPort("functional");
|
||||
mem_port->setPeer(vp);
|
||||
vp->setPeer(mem_port);
|
||||
return vp;
|
||||
@@ -332,6 +325,5 @@ SimpleThread::delVirtPort(VirtualPort *vp)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -55,8 +55,10 @@ class ProfileNode;
|
||||
class FunctionalPort;
|
||||
class PhysicalPort;
|
||||
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
namespace TheISA {
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
};
|
||||
};
|
||||
|
||||
#else // !FULL_SYSTEM
|
||||
@@ -107,18 +109,17 @@ class SimpleThread : public ThreadState
|
||||
System *system;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
AlphaITB *itb;
|
||||
AlphaDTB *dtb;
|
||||
TheISA::ITB *itb;
|
||||
TheISA::DTB *dtb;
|
||||
#endif
|
||||
|
||||
// constructor: initialize SimpleThread from given process structure
|
||||
#if FULL_SYSTEM
|
||||
SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
|
||||
AlphaITB *_itb, AlphaDTB *_dtb,
|
||||
TheISA::ITB *_itb, TheISA::DTB *_dtb,
|
||||
bool use_kernel_stats = true);
|
||||
#else
|
||||
SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid,
|
||||
MemObject *memobj);
|
||||
SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
|
||||
#endif
|
||||
|
||||
SimpleThread();
|
||||
@@ -168,12 +169,11 @@ class SimpleThread : public ThreadState
|
||||
|
||||
void dumpFuncProfile();
|
||||
|
||||
int readIntrFlag() { return regs.intrflag; }
|
||||
void setIntrFlag(int val) { regs.intrflag = val; }
|
||||
Fault hwrei();
|
||||
|
||||
bool simPalCheck(int palFunc);
|
||||
#else
|
||||
|
||||
Fault translateInstReq(RequestPtr &req)
|
||||
{
|
||||
return process->pTable->translate(req);
|
||||
@@ -201,9 +201,9 @@ class SimpleThread : public ThreadState
|
||||
#if FULL_SYSTEM
|
||||
System *getSystemPtr() { return system; }
|
||||
|
||||
AlphaITB *getITBPtr() { return itb; }
|
||||
TheISA::ITB *getITBPtr() { return itb; }
|
||||
|
||||
AlphaDTB *getDTBPtr() { return dtb; }
|
||||
TheISA::DTB *getDTBPtr() { return dtb; }
|
||||
|
||||
FunctionalPort *getPhysPort() { return physPort; }
|
||||
|
||||
@@ -422,17 +422,17 @@ class SimpleThread : public ThreadState
|
||||
return regs.readMiscReg(misc_reg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
MiscReg readMiscRegWithEffect(int misc_reg)
|
||||
{
|
||||
return regs.readMiscRegWithEffect(misc_reg, fault, tc);
|
||||
return regs.readMiscRegWithEffect(misc_reg, tc);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val)
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return regs.setMiscReg(misc_reg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return regs.setMiscRegWithEffect(misc_reg, val, tc);
|
||||
}
|
||||
@@ -442,10 +442,6 @@ class SimpleThread : public ThreadState
|
||||
void setStCondFailures(unsigned sc_failures)
|
||||
{ storeCondFailures = sc_failures; }
|
||||
|
||||
#if FULL_SYSTEM
|
||||
bool inPalMode() { return AlphaISA::PcPAL(regs.readPC()); }
|
||||
#endif
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
TheISA::IntReg getSyscallArg(int i)
|
||||
{
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
#ifndef __CPU_THREAD_CONTEXT_HH__
|
||||
#define __CPU_THREAD_CONTEXT_HH__
|
||||
|
||||
#include "arch/types.hh"
|
||||
#include "arch/regfile.hh"
|
||||
#include "arch/syscallreturn.hh"
|
||||
#include "arch/types.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "mem/request.hh"
|
||||
#include "sim/faults.hh"
|
||||
@@ -43,8 +43,11 @@
|
||||
|
||||
// @todo: Figure out a more architecture independent way to obtain the ITB and
|
||||
// DTB pointers.
|
||||
class AlphaDTB;
|
||||
class AlphaITB;
|
||||
namespace TheISA
|
||||
{
|
||||
class DTB;
|
||||
class ITB;
|
||||
}
|
||||
class BaseCPU;
|
||||
class EndQuiesceEvent;
|
||||
class Event;
|
||||
@@ -53,8 +56,10 @@ class FunctionalPort;
|
||||
class VirtualPort;
|
||||
class Process;
|
||||
class System;
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
namespace TheISA {
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -117,11 +122,11 @@ class ThreadContext
|
||||
#if FULL_SYSTEM
|
||||
virtual System *getSystemPtr() = 0;
|
||||
|
||||
virtual AlphaITB *getITBPtr() = 0;
|
||||
virtual TheISA::ITB *getITBPtr() = 0;
|
||||
|
||||
virtual AlphaDTB * getDTBPtr() = 0;
|
||||
virtual TheISA::DTB *getDTBPtr() = 0;
|
||||
|
||||
virtual Kernel::Statistics *getKernelStats() = 0;
|
||||
virtual TheISA::Kernel::Statistics *getKernelStats() = 0;
|
||||
|
||||
virtual FunctionalPort *getPhysPort() = 0;
|
||||
|
||||
@@ -221,11 +226,11 @@ class ThreadContext
|
||||
|
||||
virtual MiscReg readMiscReg(int misc_reg) = 0;
|
||||
|
||||
virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0;
|
||||
virtual MiscReg readMiscRegWithEffect(int misc_reg) = 0;
|
||||
|
||||
virtual Fault setMiscReg(int misc_reg, const MiscReg &val) = 0;
|
||||
virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0;
|
||||
|
||||
virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0;
|
||||
virtual void setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0;
|
||||
|
||||
// Also not necessarily the best location for these two. Hopefully will go
|
||||
// away once we decide upon where st cond failures goes.
|
||||
@@ -233,10 +238,6 @@ class ThreadContext
|
||||
|
||||
virtual void setStCondFailures(unsigned sc_failures) = 0;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
virtual bool inPalMode() = 0;
|
||||
#endif
|
||||
|
||||
// Only really makes sense for old CPU model. Still could be useful though.
|
||||
virtual bool misspeculating() = 0;
|
||||
|
||||
@@ -292,11 +293,12 @@ class ProxyThreadContext : public ThreadContext
|
||||
#if FULL_SYSTEM
|
||||
System *getSystemPtr() { return actualTC->getSystemPtr(); }
|
||||
|
||||
AlphaITB *getITBPtr() { return actualTC->getITBPtr(); }
|
||||
TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); }
|
||||
|
||||
AlphaDTB *getDTBPtr() { return actualTC->getDTBPtr(); }
|
||||
TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); }
|
||||
|
||||
Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); }
|
||||
TheISA::Kernel::Statistics *getKernelStats()
|
||||
{ return actualTC->getKernelStats(); }
|
||||
|
||||
FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
|
||||
|
||||
@@ -407,13 +409,13 @@ class ProxyThreadContext : public ThreadContext
|
||||
MiscReg readMiscReg(int misc_reg)
|
||||
{ return actualTC->readMiscReg(misc_reg); }
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
{ return actualTC->readMiscRegWithEffect(misc_reg, fault); }
|
||||
MiscReg readMiscRegWithEffect(int misc_reg)
|
||||
{ return actualTC->readMiscRegWithEffect(misc_reg); }
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val)
|
||||
void setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{ return actualTC->setMiscReg(misc_reg, val); }
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{ return actualTC->setMiscRegWithEffect(misc_reg, val); }
|
||||
|
||||
unsigned readStCondFailures()
|
||||
@@ -421,9 +423,6 @@ class ProxyThreadContext : public ThreadContext
|
||||
|
||||
void setStCondFailures(unsigned sc_failures)
|
||||
{ actualTC->setStCondFailures(sc_failures); }
|
||||
#if FULL_SYSTEM
|
||||
bool inPalMode() { return actualTC->inPalMode(); }
|
||||
#endif
|
||||
|
||||
// @todo: Fix this!
|
||||
bool misspeculating() { return actualTC->misspeculating(); }
|
||||
|
||||
@@ -29,25 +29,29 @@
|
||||
*/
|
||||
|
||||
#include "base/output.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/profile.hh"
|
||||
#include "cpu/thread_state.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/kernel_stats.hh"
|
||||
#include "cpu/quiesce_event.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#endif
|
||||
|
||||
#if FULL_SYSTEM
|
||||
ThreadState::ThreadState(int _cpuId, int _tid)
|
||||
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
|
||||
ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid)
|
||||
: baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
|
||||
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
|
||||
physPort(NULL), virtPort(NULL),
|
||||
microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
|
||||
#else
|
||||
ThreadState::ThreadState(int _cpuId, int _tid, Process *_process,
|
||||
short _asid, MemObject *mem)
|
||||
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
|
||||
process(_process), asid(_asid),
|
||||
ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process,
|
||||
short _asid)
|
||||
: baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
|
||||
port(NULL), process(_process), asid(_asid),
|
||||
microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
|
||||
#endif
|
||||
{
|
||||
@@ -55,6 +59,16 @@ ThreadState::ThreadState(int _cpuId, int _tid, Process *_process,
|
||||
numLoad = 0;
|
||||
}
|
||||
|
||||
ThreadState::~ThreadState()
|
||||
{
|
||||
#if !FULL_SYSTEM
|
||||
if (port) {
|
||||
delete port->getPeer();
|
||||
delete port;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ThreadState::serialize(std::ostream &os)
|
||||
{
|
||||
@@ -112,4 +126,40 @@ ThreadState::profileSample()
|
||||
profile->sample(profileNode, profilePC);
|
||||
}
|
||||
|
||||
#else
|
||||
TranslatingPort *
|
||||
ThreadState::getMemPort()
|
||||
{
|
||||
if (port != NULL)
|
||||
return port;
|
||||
|
||||
/* Use this port to for syscall emulation writes to memory. */
|
||||
port = new TranslatingPort(csprintf("%s-%d-funcport",
|
||||
baseCpu->name(), tid),
|
||||
process->pTable, false);
|
||||
|
||||
Port *func_port = getMemFuncPort();
|
||||
|
||||
func_port->setPeer(port);
|
||||
port->setPeer(func_port);
|
||||
|
||||
return port;
|
||||
}
|
||||
#endif
|
||||
|
||||
Port *
|
||||
ThreadState::getMemFuncPort()
|
||||
{
|
||||
Port *dcache_port, *func_mem_port;
|
||||
|
||||
dcache_port = baseCpu->getPort("dcache_port");
|
||||
assert(dcache_port != NULL);
|
||||
|
||||
MemObject *mem_object = dcache_port->getPeer()->getOwner();
|
||||
assert(mem_object != NULL);
|
||||
|
||||
func_mem_port = mem_object->getPort("functional");
|
||||
assert(func_mem_port != NULL);
|
||||
|
||||
return func_mem_port;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
#include "mem/mem_object.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "sim/process.hh"
|
||||
#endif
|
||||
|
||||
@@ -45,12 +44,17 @@
|
||||
class EndQuiesceEvent;
|
||||
class FunctionProfile;
|
||||
class ProfileNode;
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
namespace TheISA {
|
||||
namespace Kernel {
|
||||
class Statistics;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
class BaseCPU;
|
||||
class Checkpoint;
|
||||
class Port;
|
||||
class TranslatingPort;
|
||||
|
||||
/**
|
||||
* Struct for holding general thread state that is needed across CPU
|
||||
@@ -62,12 +66,14 @@ struct ThreadState {
|
||||
typedef ThreadContext::Status Status;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
ThreadState(int _cpuId, int _tid);
|
||||
ThreadState(BaseCPU *cpu, int _cpuId, int _tid);
|
||||
#else
|
||||
ThreadState(int _cpuId, int _tid, Process *_process,
|
||||
short _asid, MemObject *mem);
|
||||
ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process,
|
||||
short _asid);
|
||||
#endif
|
||||
|
||||
~ThreadState();
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
@@ -93,7 +99,7 @@ struct ThreadState {
|
||||
|
||||
void profileSample();
|
||||
|
||||
Kernel::Statistics *getKernelStats() { return kernelStats; }
|
||||
TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
|
||||
|
||||
FunctionalPort *getPhysPort() { return physPort; }
|
||||
|
||||
@@ -105,7 +111,7 @@ struct ThreadState {
|
||||
#else
|
||||
Process *getProcessPtr() { return process; }
|
||||
|
||||
TranslatingPort *getMemPort() { return port; }
|
||||
TranslatingPort *getMemPort();
|
||||
|
||||
void setMemPort(TranslatingPort *_port) { port = _port; }
|
||||
|
||||
@@ -135,6 +141,12 @@ struct ThreadState {
|
||||
/** Sets the status of this thread. */
|
||||
void setStatus(Status new_status) { _status = new_status; }
|
||||
|
||||
protected:
|
||||
/** Gets a functional port from the memory object that's connected
|
||||
* to the CPU. */
|
||||
Port *getMemFuncPort();
|
||||
|
||||
public:
|
||||
/** Number of instructions committed. */
|
||||
Counter numInst;
|
||||
/** Stat for number instructions committed. */
|
||||
@@ -153,6 +165,9 @@ struct ThreadState {
|
||||
protected:
|
||||
ThreadContext::Status _status;
|
||||
|
||||
// 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;
|
||||
@@ -174,7 +189,7 @@ struct ThreadState {
|
||||
Addr profilePC;
|
||||
EndQuiesceEvent *quiesceEvent;
|
||||
|
||||
Kernel::Statistics *kernelStats;
|
||||
TheISA::Kernel::Statistics *kernelStats;
|
||||
protected:
|
||||
/** A functional port outgoing only for functional accesses to physical
|
||||
* addresses.*/
|
||||
|
||||
Reference in New Issue
Block a user