From 1b1495930c74bab639f0985c2d55f767336aa59b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 24 Oct 2006 15:50:41 -0400 Subject: [PATCH 01/40] Replace the Alpha No op with a SPARC one. --HG-- extra : convert_revision : bed03e63dc80bf24f21bad08e6553d7aab92c7b3 --- src/arch/sparc/isa_traits.hh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 6d5aa4251..de54e168b 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -57,12 +57,11 @@ namespace SparcISA //This makes sure the big endian versions of certain functions are used. using namespace BigEndianGuest; - // Alpha Does NOT have a delay slot + // SPARC have a delay slot #define ISA_HAS_DELAY_SLOT 1 - //TODO this needs to be a SPARC Noop - // Alpha UNOP (ldq_u r31,0(r0)) - const MachInst NoopMachInst = 0x2ffe0000; + // SPARC NOP (sethi %(hi(0), g0) + const MachInst NoopMachInst = 0x01000000; const int NumIntRegs = 32; const int NumFloatRegs = 64; From e2eef8859b44dbb9d307f6ff50047bdb6b730277 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Oct 2006 17:49:41 -0400 Subject: [PATCH 02/40] Implemented the SPARC fill and spill handlers. src/arch/sparc/faults.cc: src/arch/sparc/faults.hh: Added a function to do normal SPARC trap processing, and implemented the spill and fill faults for SE src/arch/sparc/process.cc: src/arch/sparc/process.hh: Added fill and spill handlers which are stuffed into the processes address space. The location of these handlers are stored in fillStart and spillStart. --HG-- extra : convert_revision : 59adb96570cce86f373fbc2c3e4c05abe1742d3b --- src/arch/sparc/faults.cc | 173 +++++++++++++++++++++++++++++++++++++- src/arch/sparc/faults.hh | 6 +- src/arch/sparc/process.cc | 106 +++++++++++++++++++++-- src/arch/sparc/process.hh | 9 ++ 4 files changed, 284 insertions(+), 10 deletions(-) diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 7b7765935..fd91ccf0f 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -29,15 +29,22 @@ * Kevin Lim */ +#include + #include "arch/sparc/faults.hh" -#include "cpu/thread_context.hh" -#include "cpu/base.hh" +#include "arch/sparc/isa_traits.hh" +#include "arch/sparc/process.hh" +#include "base/bitfield.hh" #include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" #if !FULL_SYSTEM -#include "sim/process.hh" #include "mem/page_table.hh" +#include "sim/process.hh" #endif +using namespace std; + namespace SparcISA { @@ -229,6 +236,129 @@ FaultPriority PageTableFault::_priority = 0; FaultStat PageTableFault::_count; #endif +/** + * This sets everything up for a normal trap except for actually jumping to + * the handler. It will need to be expanded to include the state machine in + * the manual. Right now it assumes that traps will always be to the + * privileged level. + */ + +void doNormalFault(ThreadContext *tc, TrapType tt) +{ + uint64_t TL = tc->readMiscReg(MISCREG_TL); + uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE); + uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE); + uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + uint64_t CCR = tc->readMiscReg(MISCREG_CCR); + uint64_t ASI = tc->readMiscReg(MISCREG_ASI); + uint64_t CWP = tc->readMiscReg(MISCREG_CWP); + uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + uint64_t GL = tc->readMiscReg(MISCREG_GL); + uint64_t PC = tc->readPC(); + uint64_t NPC = tc->readNextPC(); + + //Increment the trap level + TL++; + tc->setMiscReg(MISCREG_TL, TL); + + //Save off state + + //set TSTATE.gl to gl + replaceBits(TSTATE, 42, 40, GL); + //set TSTATE.ccr to ccr + replaceBits(TSTATE, 39, 32, CCR); + //set TSTATE.asi to asi + replaceBits(TSTATE, 31, 24, ASI); + //set TSTATE.pstate to pstate + replaceBits(TSTATE, 20, 8, PSTATE); + //set TSTATE.cwp to cwp + replaceBits(TSTATE, 4, 0, CWP); + + //Write back TSTATE + tc->setMiscReg(MISCREG_TSTATE, TSTATE); + + //set TPC to PC + tc->setMiscReg(MISCREG_TPC, PC); + //set TNPC to NPC + tc->setMiscReg(MISCREG_TNPC, NPC); + + //set HTSTATE.hpstate to hpstate + tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); + + //TT = trap type; + tc->setMiscReg(MISCREG_TT, tt); + + //Update the global register level + if(1/*We're delivering the trap in priveleged mode*/) + tc->setMiscReg(MISCREG_GL, max(GL+1, MaxGL)); + else + tc->setMiscReg(MISCREG_GL, max(GL+1, MaxPGL)); + + //PSTATE.mm is unchanged + //PSTATE.pef = whether or not an fpu is present + //XXX We'll say there's one present, even though there aren't + //implementations for a decent number of the instructions + PSTATE |= (1 << 4); + //PSTATE.am = 0 + PSTATE &= ~(1 << 3); + if(1/*We're delivering the trap in priveleged mode*/) + { + //PSTATE.priv = 1 + PSTATE |= (1 << 2); + //PSTATE.cle = PSTATE.tle + replaceBits(PSTATE, 9, 9, PSTATE >> 8); + } + else + { + //PSTATE.priv = 0 + PSTATE &= ~(1 << 2); + //PSTATE.cle = 0 + PSTATE &= ~(1 << 9); + } + //PSTATE.ie = 0 + PSTATE &= ~(1 << 1); + //PSTATE.tle is unchanged + //PSTATE.tct = 0 + //XXX Where exactly is this field? + tc->setMiscReg(MISCREG_PSTATE, PSTATE); + + if(0/*We're delivering the trap in hyperprivileged mode*/) + { + //HPSTATE.red = 0 + HPSTATE &= ~(1 << 5); + //HPSTATE.hpriv = 1 + HPSTATE |= (1 << 2); + //HPSTATE.ibe = 0 + HPSTATE &= ~(1 << 10); + //HPSTATE.tlz is unchanged + tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); + } + + bool changedCWP = true; + if(tt == 0x24) + { + warn("Incrementing the CWP by 1\n"); + CWP++; + } + else if(0x80 <= tt && tt <= 0xbf) + { + warn("Incrementing the CWP by %d\n", CANSAVE + 2); + CWP += (CANSAVE + 2); + } + else if(0xc0 <= tt && tt <= 0xff) + { + warn("Decrementing the CWP by 1\n"); + CWP--; + } + else + changedCWP = false; + if(changedCWP) + { + CWP = (CWP + NWindows) % NWindows; + tc->setMiscRegWithEffect(MISCREG_CWP, CWP); + } +} + #if FULL_SYSTEM void SparcFault::invoke(ThreadContext * tc) @@ -263,6 +393,42 @@ void TrapInstruction::invoke(ThreadContext * tc) // Should be handled in ISA. } +void SpillNNormal::invoke(ThreadContext *tc) +{ + warn("I'm in a spill trap\n"); + doNormalFault(tc, trapType()); + + Process *p = tc->getProcessPtr(); + + //This will only work in faults from a SparcLiveProcess + SparcLiveProcess *lp = dynamic_cast(p); + assert(lp); + + //Then adjust the PC and NPC + Addr spillStart = lp->readSpillStart(); + tc->setPC(spillStart); + tc->setNextPC(spillStart + sizeof(MachInst)); + tc->setNextNPC(spillStart + 2*sizeof(MachInst)); +} + +void FillNNormal::invoke(ThreadContext *tc) +{ + warn("I'm in a fill trap\n"); + doNormalFault(tc, trapType()); + + Process * p = tc->getProcessPtr(); + + //This will only work in faults from a SparcLiveProcess + SparcLiveProcess *lp = dynamic_cast(p); + assert(lp); + + //The adjust the PC and NPC + Addr fillStart = lp->readFillStart(); + tc->setPC(fillStart); + tc->setNextPC(fillStart + sizeof(MachInst)); + tc->setNextNPC(fillStart + 2*sizeof(MachInst)); +} + void PageTableFault::invoke(ThreadContext *tc) { Process *p = tc->getProcessPtr(); @@ -282,6 +448,7 @@ void PageTableFault::invoke(ThreadContext *tc) FaultBase::invoke(tc); } } + #endif } // namespace SparcISA diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index b279f4911..394a06294 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -39,8 +39,8 @@ namespace SparcISA { -typedef const uint32_t TrapType; -typedef const uint32_t FaultPriority; +typedef uint32_t TrapType; +typedef uint32_t FaultPriority; class SparcFault : public FaultBase { @@ -547,6 +547,7 @@ class SpillNNormal : public EnumeratedFault FaultName name() {return _name;} FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} + void invoke(ThreadContext * tc); }; class SpillNOther : public EnumeratedFault @@ -577,6 +578,7 @@ class FillNNormal : public EnumeratedFault FaultName name() {return _name;} FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} + void invoke(ThreadContext * tc); }; class FillNOther : public EnumeratedFault diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 3323ba7a0..a3b7dde7c 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -66,6 +66,10 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile, // Set pointer for next thread stack. Reserve 8M for main stack. next_thread_stack_base = stack_base - (8 * 1024 * 1024); + + //Initialize these to 0s + fillStart = 0; + spillStart = 0; } void @@ -88,15 +92,19 @@ SparcLiveProcess::startup() */ //No windows contain info from other programs - threadContexts[0]->setMiscRegWithEffect(MISCREG_OTHERWIN, 0); + threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0); //There are no windows to pop - threadContexts[0]->setMiscRegWithEffect(MISCREG_CANRESTORE, 0); + threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0); //All windows are available to save into - threadContexts[0]->setMiscRegWithEffect(MISCREG_CANSAVE, NWindows - 2); + threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2); //All windows are "clean" - threadContexts[0]->setMiscRegWithEffect(MISCREG_CLEANWIN, NWindows); + threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows); //Start with register window 0 - threadContexts[0]->setMiscRegWithEffect(MISCREG_CWP, 0); + threadContexts[0]->setMiscReg(MISCREG_CWP, 0); + //Always use spill and fill traps 0 + threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0); + //Set the trap level to 0 + threadContexts[0]->setMiscReg(MISCREG_TL, 0); } m5_auxv_t buildAuxVect(int64_t type, int64_t val) @@ -107,6 +115,83 @@ m5_auxv_t buildAuxVect(int64_t type, int64_t val) return result; } +//We only use 19 instructions for the trap handlers, but there would be +//space for 32 in a real SPARC trap table. +const int numFillInsts = 32; +const int numSpillInsts = 32; + +MachInst fillHandler[numFillInsts] = +{ + htog(0x87802018), //wr %g0, ASI_AIUP, %asi + htog(0xe0dba7ff), //ldxa [%sp + BIAS + (0*8)] %asi, %l0 + htog(0xe2dba807), //ldxa [%sp + BIAS + (1*8)] %asi, %l1 + htog(0xe4dba80f), //ldxa [%sp + BIAS + (2*8)] %asi, %l2 + htog(0xe6dba817), //ldxa [%sp + BIAS + (3*8)] %asi, %l3 + htog(0xe8dba81f), //ldxa [%sp + BIAS + (4*8)] %asi, %l4 + htog(0xeadba827), //ldxa [%sp + BIAS + (5*8)] %asi, %l5 + htog(0xecdba82f), //ldxa [%sp + BIAS + (6*8)] %asi, %l6 + htog(0xeedba837), //ldxa [%sp + BIAS + (7*8)] %asi, %l7 + htog(0xf0dba83f), //ldxa [%sp + BIAS + (8*8)] %asi, %i0 + htog(0xf2dba847), //ldxa [%sp + BIAS + (9*8)] %asi, %i1 + htog(0xf4dba84f), //ldxa [%sp + BIAS + (10*8)] %asi, %i2 + htog(0xf6dba857), //ldxa [%sp + BIAS + (11*8)] %asi, %i3 + htog(0xf8dba85f), //ldxa [%sp + BIAS + (12*8)] %asi, %i4 + htog(0xfadba867), //ldxa [%sp + BIAS + (13*8)] %asi, %i5 + htog(0xfcdba86f), //ldxa [%sp + BIAS + (14*8)] %asi, %i6 + htog(0xfedba877), //ldxa [%sp + BIAS + (15*8)] %asi, %i7 + htog(0x83880000), //restored + htog(0x83F00000), //retry + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000) //illtrap +}; + +MachInst spillHandler[numSpillInsts] = +{ + htog(0x87802018), //wr %g0, ASI_AIUP, %asi + htog(0xe0f3a7ff), //stxa %l0, [%sp + BIAS + (0*8)] %asi + htog(0xe2f3a807), //stxa %l1, [%sp + BIAS + (1*8)] %asi + htog(0xe4f3a80f), //stxa %l2, [%sp + BIAS + (2*8)] %asi + htog(0xe6f3a817), //stxa %l3, [%sp + BIAS + (3*8)] %asi + htog(0xe8f3a81f), //stxa %l4, [%sp + BIAS + (4*8)] %asi + htog(0xeaf3a827), //stxa %l5, [%sp + BIAS + (5*8)] %asi + htog(0xecf3a82f), //stxa %l6, [%sp + BIAS + (6*8)] %asi + htog(0xeef3a837), //stxa %l7, [%sp + BIAS + (7*8)] %asi + htog(0xf0f3a83f), //stxa %i0, [%sp + BIAS + (8*8)] %asi + htog(0xf2f3a847), //stxa %i1, [%sp + BIAS + (9*8)] %asi + htog(0xf4f3a84f), //stxa %i2, [%sp + BIAS + (10*8)] %asi + htog(0xf6f3a857), //stxa %i3, [%sp + BIAS + (11*8)] %asi + htog(0xf8f3a85f), //stxa %i4, [%sp + BIAS + (12*8)] %asi + htog(0xfaf3a867), //stxa %i5, [%sp + BIAS + (13*8)] %asi + htog(0xfcf3a86f), //stxa %i6, [%sp + BIAS + (14*8)] %asi + htog(0xfef3a877), //stxa %i7, [%sp + BIAS + (15*8)] %asi + htog(0x81880000), //saved + htog(0x83F00000), //retry + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000) //illtrap +}; + void SparcLiveProcess::argsInit(int intSize, int pageSize) { @@ -317,6 +402,17 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); + //Stuff the trap handlers into the processes address space. + //Since the stack grows down and is the highest area in the processes + //address space, we can put stuff above it and stay out of the way. + int fillSize = sizeof(MachInst) * numFillInsts; + int spillSize = sizeof(MachInst) * numSpillInsts; + fillStart = stack_base; + spillStart = fillStart + fillSize; + initVirtMem->writeBlob(fillStart, (uint8_t*)fillHandler, fillSize); + initVirtMem->writeBlob(spillStart, (uint8_t*)spillHandler, spillSize); + + //Set up the thread context to start running the process threadContexts[0]->setIntReg(ArgumentReg0, argc); threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base); threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias); diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index 7cc52e241..2320810c7 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -55,6 +55,9 @@ class SparcLiveProcess : public LiveProcess static const Addr StackBias = 2047; + //The locations of the fill and spill handlers + Addr fillStart, spillStart; + std::vector auxv; SparcLiveProcess(const std::string &nm, ObjectFile *objFile, @@ -71,6 +74,12 @@ class SparcLiveProcess : public LiveProcess void argsInit(int intSize, int pageSize); + Addr readFillStart() + { return fillStart; } + + Addr readSpillStart() + { return spillStart; } + }; #endif // __SPARC_PROCESS_HH__ From 047455625e333f10c73d16d5457d5b966ffae8e2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Oct 2006 17:50:39 -0400 Subject: [PATCH 03/40] Fixed the bitfield FCN to include the right bits. --HG-- extra : convert_revision : 040beb4dd982784773c3c3ad04cc48c2dc98b58c --- src/arch/sparc/isa/bitfields.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/sparc/isa/bitfields.isa b/src/arch/sparc/isa/bitfields.isa index 372f5c4ef..7e884866c 100644 --- a/src/arch/sparc/isa/bitfields.isa +++ b/src/arch/sparc/isa/bitfields.isa @@ -50,7 +50,7 @@ def bitfield D16LO <13:0>; def bitfield DISP19 <18:0>; def bitfield DISP22 <21:0>; def bitfield DISP30 <29:0>; -def bitfield FCN <29:26>; +def bitfield FCN <29:25>; def bitfield I <13>; def bitfield IMM_ASI <12:5>; def bitfield IMM22 <21:0>; From 99d9d40e6c3e4c6c4fbfa3f4475ac3907e6f9d15 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Oct 2006 17:54:14 -0400 Subject: [PATCH 04/40] Implemented the saved and restored instructions, fixed up register window instructions so that the cwp is modified at the correct time (when handling the fault), and fixed the "done" instruction. --HG-- extra : convert_revision : 3c9144422f087af1d375782cce1c9b77ca7936c9 --- src/arch/sparc/isa/decoder.isa | 68 +++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 45d3616d9..d5f0a0738 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -425,8 +425,24 @@ decode OP default Unknown::unknown() xc->setMiscRegWithEffect(RD + AsrStart, Rs1 ^ Rs2_or_imm13); }}); 0x31: decode FCN { - 0x0: BasicOperate::saved({{/*Boogy Boogy*/}}); - 0x1: BasicOperate::restored({{/*Boogy Boogy*/}}); + 0x0: Priv::saved({{ + assert(Cansave < NWindows - 2); + assert(Otherwin || Canrestore); + Cansave = Cansave + 1; + if(Otherwin == 0) + Canrestore = Canrestore - 1; + else + Otherwin = Otherwin - 1; + }}); + 0x1: BasicOperate::restored({{ + assert(Cansave || Otherwin); + assert(Canrestore < NWindows - 2); + Canrestore = Canrestore + 1; + if(Otherwin == 0) + Cansave = Cansave - 1; + else + Otherwin = Otherwin - 1; + }}); } 0x32: Priv::wrpr({{ // XXX Need to protect with format that traps non-priv @@ -684,10 +700,6 @@ decode OP default Unknown::unknown() NNPC = target; if(fault == NoFault) { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one - Cwp = (Cwp - 1 + NWindows) % NWindows; if(Canrestore == 0) { if(Otherwin) @@ -697,14 +709,18 @@ decode OP default Unknown::unknown() } else { - Rd = Rs1 + Rs2_or_imm13; + //CWP should be set directly so that it always happens + //Also, this will allow writing to the new window and + //reading from the old one + Cwp = (Cwp - 1 + NWindows) % NWindows; Cansave = Cansave + 1; Canrestore = Canrestore - 1; + //This is here to make sure the CWP is written + //no matter what. This ensures that the results + //are written in the new window as well. + xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); + warn("About to set the CWP to %d\n", Cwp); } - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3A: decode CC @@ -747,11 +763,11 @@ decode OP default Unknown::unknown() fault = new SpillNOther(Wstate<5:3>); else fault = new SpillNNormal(Wstate<2:0>); - Cwp = (Cwp + 2) % NWindows; + //Cwp = (Cwp + 2) % NWindows; } else if(Cleanwin - Canrestore == 0) { - Cwp = (Cwp + 1) % NWindows; + //Cwp = (Cwp + 1) % NWindows; fault = new CleanWindow; } else @@ -760,17 +776,13 @@ decode OP default Unknown::unknown() Rd = Rs1 + Rs2_or_imm13; Cansave = Cansave - 1; Canrestore = Canrestore + 1; + //This is here to make sure the CWP is written + //no matter what. This ensures that the results + //are written in the new window as well. + xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); }}); 0x3D: restore({{ - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one - Cwp = (Cwp - 1 + NWindows) % NWindows; if(Canrestore == 0) { if(Otherwin) @@ -780,14 +792,18 @@ decode OP default Unknown::unknown() } else { + //CWP should be set directly so that it always happens + //Also, this will allow writing to the new window and + //reading from the old one + Cwp = (Cwp - 1 + NWindows) % NWindows; Rd = Rs1 + Rs2_or_imm13; Cansave = Cansave + 1; Canrestore = Canrestore - 1; + //This is here to make sure the CWP is written + //no matter what. This ensures that the results + //are written in the new window as well. + xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); }}); 0x3E: decode FCN { 0x0: Priv::done({{ @@ -812,7 +828,7 @@ decode OP default Unknown::unknown() Ccr = Tstate<39:32>; Gl = Tstate<42:40>; NPC = Tpc; - NNPC = Tnpc + 4; + NNPC = Tnpc; Tl = Tl - 1; }}); } From 93b3176d4e72813bc64340eb534eb280f68764e1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Oct 2006 17:58:44 -0400 Subject: [PATCH 05/40] Fixed the priv instruction format. src/arch/sparc/isa/formats/priv.isa: Fix the priv format so that it uses isa_parser operands rather than accessing the registers directly in checkCode. Also, the expressions needed to be negated. src/arch/sparc/isa/operands.isa: Added an Hpstate operand, and adjusted the numbering. --HG-- extra : convert_revision : 4a70862df061aa9e1b9eab125c4c2fc839ac3b5a --- src/arch/sparc/isa/formats/priv.isa | 5 ++--- src/arch/sparc/isa/operands.isa | 21 +++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index 2a38422a7..04c67d332 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -121,15 +121,14 @@ let {{ // Primary format for integer operate instructions: def format Priv(code, *opt_flags) {{ - checkCode = '''((xc->readMiscReg(PrStart + MISCREG_PSTATE))<2:2>) || - ((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)''' + checkCode = "!(Pstate<2:2> || Hpstate<2:2>)" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, checkCode, name, Name, opt_flags + ('IprAccessOp',)) }}; def format HPriv(code, *opt_flags) {{ - checkCode = "((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)" + checkCode = "!Hpstate<2:2>" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, checkCode, name, Name, opt_flags + ('IprAccessOp',)) diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index b8b75170b..ba2c38e91 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -95,18 +95,19 @@ def operands {{ 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 44), 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 45), 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 46), - 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 47), + 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 47), + 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 48), - 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 48), - 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 49), - 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 50), - 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 51), - 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 52), - 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 53), - 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54), + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 49), + 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 50), + 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 51), + 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 52), + 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 53), + 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 54), + 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 55), - 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55), - 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56), + 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 56), + 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 57), # Mem gets a large number so it's always last 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) From f4be29804f96fc4abda6cde547add7285458815f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 25 Oct 2006 18:34:21 -0400 Subject: [PATCH 06/40] Fix simple timing port keep a list of all packets, have only one event, and scan all packets on a functional access. --HG-- extra : convert_revision : c735a6408443b5cc90d1c1841c7aeb61e02ec6ae --- src/mem/tport.cc | 64 ++++++++++++++++++++++++++---------------------- src/mem/tport.hh | 33 ++++++++++++------------- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/src/mem/tport.cc b/src/mem/tport.cc index 55a461a8b..b9d5cbe4a 100644 --- a/src/mem/tport.cc +++ b/src/mem/tport.cc @@ -33,15 +33,16 @@ void SimpleTimingPort::recvFunctional(PacketPtr pkt) { - std::list::iterator i = transmitList.begin(); - std::list::iterator end = transmitList.end(); + std::list >::iterator i = transmitList.begin(); + std::list >::iterator end = transmitList.end(); + bool done = false; - while (i != end) { - PacketPtr target = *i; + while (i != end && !done) { + PacketPtr target = i->second; // If the target contains data, and it overlaps the // probed request, need to update data if (target->intersect(pkt)) - fixPacket(pkt, target); + done = fixPacket(pkt, target); } @@ -63,7 +64,7 @@ SimpleTimingPort::recvTiming(PacketPtr pkt) // turn packet around to go back to requester if response expected if (pkt->needsResponse()) { pkt->makeTimingResponse(); - sendTimingLater(pkt, latency); + sendTiming(pkt, latency); } else { if (pkt->cmd != Packet::UpgradeReq) @@ -78,14 +79,14 @@ SimpleTimingPort::recvTiming(PacketPtr pkt) void SimpleTimingPort::recvRetry() { - assert(outTiming > 0); assert(!transmitList.empty()); - if (sendTiming(transmitList.front())) { + if (Port::sendTiming(transmitList.front().second)) { transmitList.pop_front(); - outTiming--; DPRINTF(Bus, "No Longer waiting on retry\n"); - if (!transmitList.empty()) - sendTimingLater(transmitList.front(), 1); + if (!transmitList.empty()) { + Tick time = transmitList.front().first; + sendEvent.schedule(time <= curTick ? curTick+1 : time); + } } if (transmitList.empty() && drainEvent) { @@ -94,39 +95,44 @@ SimpleTimingPort::recvRetry() } } +void +SimpleTimingPort::sendTiming(PacketPtr pkt, Tick time) +{ + if (transmitList.empty()) { + assert(!sendEvent.scheduled()); + sendEvent.schedule(curTick+time); + } + transmitList.push_back(std::pair(time+curTick,pkt)); +} + void SimpleTimingPort::SendEvent::process() { - assert(port->outTiming > 0); - if (!port->transmitList.empty() && port->transmitList.front() != packet) { - //We are not the head of the list - port->transmitList.push_back(packet); - } else if (port->sendTiming(packet)) { - // send successful - if (port->transmitList.size()) { - port->transmitList.pop_front(); - port->outTiming--; - if (!port->transmitList.empty()) - port->sendTimingLater(port->transmitList.front(), 1); + assert(port->transmitList.size()); + assert(port->transmitList.front().first <= curTick); + if (port->Port::sendTiming(port->transmitList.front().second)) { + //send successful, remove packet + port->transmitList.pop_front(); + if (!port->transmitList.empty()) { + Tick time = port->transmitList.front().first; + schedule(time <= curTick ? curTick+1 : time); } if (port->transmitList.empty() && port->drainEvent) { port->drainEvent->process(); port->drainEvent = NULL; } - } else { - // send unsuccessful (due to flow control). Will get retry - // callback later; save for then if not already - DPRINTF(Bus, "Waiting on retry\n"); - if (!(port->transmitList.front() == packet)) - port->transmitList.push_back(packet); + return; } + // send unsuccessful (due to flow control). Will get retry + // callback later; save for then if not already + DPRINTF(Bus, "Waiting on retry\n"); } unsigned int SimpleTimingPort::drain(Event *de) { - if (outTiming == 0 && transmitList.size() == 0) + if (transmitList.size() == 0) return 0; drainEvent = de; return 1; diff --git a/src/mem/tport.hh b/src/mem/tport.hh index fbe81c443..438ec56dc 100644 --- a/src/mem/tport.hh +++ b/src/mem/tport.hh @@ -60,23 +60,22 @@ class SimpleTimingPort : public Port protected: /** A list of outgoing timing response packets that haven't been * serviced yet. */ - std::list transmitList; + std::list > transmitList; /** * This class is used to implemented sendTiming() with a delay. When - * a delay is requested a new event is created. When the event time - * expires it attempts to send the packet. If it cannot, the packet - * is pushed onto the transmit list to be sent when recvRetry() is - * called. */ + * a delay is requested a the event is scheduled if it isn't already. + * When the event time expires it attempts to send the packet. + * If it cannot, the packet sent when recvRetry() is called. + **/ class SendEvent : public Event { SimpleTimingPort *port; - PacketPtr packet; public: - SendEvent(SimpleTimingPort *p, PacketPtr pkt, Tick t) - : Event(&mainEventQueue), port(p), packet(pkt) - { setFlags(AutoDelete); schedule(curTick + t); } + SendEvent(SimpleTimingPort *p) + : Event(&mainEventQueue), port(p) + { } virtual void process(); @@ -84,19 +83,17 @@ class SimpleTimingPort : public Port { return "Future scheduled sendTiming event"; } }; - - /** Number of timing requests that are emulating the device timing before - * attempting to end up on the bus. - */ - int outTiming; + SendEvent sendEvent; /** If we need to drain, keep the drain event around until we're done * here.*/ Event *drainEvent; - /** Schedule a sendTiming() event to be called in the future. */ - void sendTimingLater(PacketPtr pkt, Tick time) - { outTiming++; new SendEvent(this, pkt, time); } + /** Schedule a sendTiming() event to be called in the future. + * @param pkt packet to send + * @param time increment from now (in ticks) to send packet + */ + void sendTiming(PacketPtr pkt, Tick time); /** This function is notification that the device should attempt to send a * packet again. */ @@ -118,7 +115,7 @@ class SimpleTimingPort : public Port public: SimpleTimingPort(std::string pname) - : Port(pname), outTiming(0), drainEvent(NULL) + : Port(pname), sendEvent(this), drainEvent(NULL) {} /** Hook for draining timing accesses from the system. The From 260b3c0cf074bddb4dff8a126811ea9c4c2d6687 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Thu, 26 Oct 2006 16:04:09 -0400 Subject: [PATCH 07/40] se.py: make the same os.getcwd fix ali made in fs.py, make connectMemPorts occur after caches are created. configs/example/se.py: make the same os.getcwd fix ali made in fs.py, make connectMemPorts occur after caches are created. --HG-- extra : convert_revision : 9760ae073d97cd62d3e44f10199d31cce79d4a1d --- configs/example/se.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/configs/example/se.py b/configs/example/se.py index 2e63e27da..c4150eed7 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -129,14 +129,15 @@ cpu.cpu_id = 0 system = System(cpu = cpu, physmem = PhysicalMemory(range=AddrRange("512MB")), membus = Bus()) -system.physmem.port = system.membus.port -system.cpu.connectMemPorts(system.membus) -system.cpu.mem = system.physmem -system.cpu.clock = '2GHz' + if options.caches and not options.standard_switch: system.cpu.addPrivateSplitL1Caches(MyCache(size = '32kB'), MyCache(size = '64kB')) +system.physmem.port = system.membus.port +system.cpu.connectMemPorts(system.membus) +system.cpu.mem = system.physmem +system.cpu.clock = '2GHz' root = Root(system = system) if options.timing or options.detailed: @@ -169,7 +170,7 @@ m5.instantiate(root) if options.checkpoint_dir: cptdir = options.checkpoint_dir else: - cptdir = getcwd() + cptdir = os.getcwd() if options.checkpoint_restore: from os.path import isdir From e441be1b82171651308c22eac01c854e7813c2dd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 26 Oct 2006 20:22:23 -0400 Subject: [PATCH 08/40] Change the default function from setMiscRegWithEffect to setMiscReg --HG-- extra : convert_revision : bedf422d51a52b009390b1e94f5330f752be2b87 --- src/arch/isa_parser.py | 2 +- src/arch/sparc/miscregfile.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index b235398f1..6504c7b32 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -1316,7 +1316,7 @@ class ControlRegOperand(Operand): def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write control register as FP') - wb = 'xc->setMiscReg(%s, %s);\n' % (self.reg_spec, self.base_name) + wb = 'xc->setMiscRegWithEffect(%s, %s);\n' % (self.reg_spec, self.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ self.base_name return wb diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 8041e45c0..efaa22f67 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -470,7 +470,7 @@ Fault MiscRegFile::setRegWithEffect(int miscReg, /** Floating Point Status Register */ case MISCREG_FSR: - panic("Floating Point not implemented\n"); + setReg(miscReg, val); default: #if FULL_SYSTEM setFSRegWithEffect(miscReg, val, tc); From 5024b202785b066307b5bc697ee39bccf344a100 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 26 Oct 2006 20:23:00 -0400 Subject: [PATCH 09/40] Got rid of some debug output --HG-- extra : convert_revision : 6e98cf839dc92bde5f06f9b9bf11ca6ac661c907 --- src/arch/sparc/faults.cc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index fd91ccf0f..2c8da44c5 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -336,22 +336,14 @@ void doNormalFault(ThreadContext *tc, TrapType tt) bool changedCWP = true; if(tt == 0x24) - { - warn("Incrementing the CWP by 1\n"); CWP++; - } else if(0x80 <= tt && tt <= 0xbf) - { - warn("Incrementing the CWP by %d\n", CANSAVE + 2); CWP += (CANSAVE + 2); - } else if(0xc0 <= tt && tt <= 0xff) - { - warn("Decrementing the CWP by 1\n"); CWP--; - } else changedCWP = false; + if(changedCWP) { CWP = (CWP + NWindows) % NWindows; @@ -395,7 +387,6 @@ void TrapInstruction::invoke(ThreadContext * tc) void SpillNNormal::invoke(ThreadContext *tc) { - warn("I'm in a spill trap\n"); doNormalFault(tc, trapType()); Process *p = tc->getProcessPtr(); @@ -413,7 +404,6 @@ void SpillNNormal::invoke(ThreadContext *tc) void FillNNormal::invoke(ThreadContext *tc) { - warn("I'm in a fill trap\n"); doNormalFault(tc, trapType()); Process * p = tc->getProcessPtr(); From d1b30102fdaa79b9937e9405aeade54a72685746 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 26 Oct 2006 20:24:01 -0400 Subject: [PATCH 10/40] Changed the number of register windows to be more realistic. --HG-- extra : convert_revision : ae557307f377b19bae82226dafa8b4b2654cae52 --- src/arch/sparc/isa_traits.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index de54e168b..fb09121a3 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -86,7 +86,7 @@ namespace SparcISA const int MaxPGL = 2; // NWINDOWS - number of register windows, can be 3 to 32 - const int NWindows = 32; + const int NWindows = 8; // semantically meaningful register indices const int ZeroReg = 0; // architecturally meaningful From f88b90dd564f59ca0f045df6f12c87185cbef687 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 26 Oct 2006 20:25:22 -0400 Subject: [PATCH 11/40] Added a few functions to stuff values into bitfields in an instruction. --HG-- extra : convert_revision : 507d7e13fd6276acf36b75eba31dff5e8080113f --- src/base/bitfield.hh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh index 879780d56..177279678 100644 --- a/src/base/bitfield.hh +++ b/src/base/bitfield.hh @@ -69,4 +69,28 @@ sext(uint64_t val) return sign_bit ? (val | ~mask(N)) : val; } +/** + * Return val with bits first to last set to bit_val + */ +template +inline +T +insertBits(T val, int first, int last, B bit_val) +{ + T bmask = mask(first - last + 1) << last; + return ((bit_val << last) & bmask) | (val & ~bmask); +} + +/** + * A convenience function to replace bits first to last of val with bit_val + * in place. + */ +template +inline +void +replaceBits(T& val, int first, int last, B bit_val) +{ + val = insertBits(val, first, last, bit_val); +} + #endif // __BASE_BITFIELD_HH__ From f33bab2386ea1f3dbdcff547501af0e78d659101 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 26 Oct 2006 22:47:17 -0400 Subject: [PATCH 12/40] Cleaned up the decoder slightly. --HG-- extra : convert_revision : a7050aa8768c132f0161f00ba17ae02d71f0b829 --- src/arch/sparc/isa/decoder.isa | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index d5f0a0738..a2657b3cd 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -447,12 +447,12 @@ decode OP default Unknown::unknown() 0x32: Priv::wrpr({{ // XXX Need to protect with format that traps non-priv // access - fault = xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13); + xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13); }}); 0x33: HPriv::wrhpr({{ // XXX Need to protect with format that traps non-priv/priv // access - fault = xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13); + xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13); }}); 0x34: decode OPF{ format BasicOperate{ @@ -719,7 +719,6 @@ decode OP default Unknown::unknown() //no matter what. This ensures that the results //are written in the new window as well. xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); - warn("About to set the CWP to %d\n", Cwp); } } }}); From 2cb190d1e3854f3d82b88ccd9b6b6365b87c331d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 26 Oct 2006 22:48:02 -0400 Subject: [PATCH 13/40] Reorganized the MiscRegFile --HG-- extra : convert_revision : 088112c9b8a4ea09c8015da5a0b65ed2fc9398d2 --- src/arch/sparc/miscregfile.cc | 163 ++++++++++------------------------ src/arch/sparc/miscregfile.hh | 1 - 2 files changed, 49 insertions(+), 115 deletions(-) diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index efaa22f67..ada3c18e7 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -221,8 +221,6 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, } return tc->getCpuPtr()->curCycle() - tickFields.counter | tickFields.npt << 63; - case MISCREG_PC: - return tc->readPC(); case MISCREG_FPRS: fault = new UnimpFault("FPU not implemented\n"); return 0; @@ -280,112 +278,115 @@ Fault MiscRegFile::setReg(int miscReg, const MiscReg &val) switch (miscReg) { case MISCREG_Y: y = val; - return NoFault; + break; case MISCREG_CCR: ccr = val; - return NoFault; + break; case MISCREG_ASI: asi = val; - return NoFault; + break; case MISCREG_FPRS: fprs = val; - return NoFault; + break; case MISCREG_TICK: - tick = val; - return NoFault; + tick = val; + break; case MISCREG_PCR: case MISCREG_PIC: panic("ASR number %d not implemented\n", miscReg - AsrStart); case MISCREG_GSR: gsr = val; + break; case MISCREG_SOFTINT: - softint = val; - return NoFault; + softint = val; + break; case MISCREG_TICK_CMPR: - tick_cmpr = val; - return NoFault; + tick_cmpr = val; + break; case MISCREG_STICK: - stick = val; - return NoFault; + stick = val; + break; case MISCREG_STICK_CMPR: - stick_cmpr = val; - return NoFault; + stick_cmpr = val; + break; /** Privilged Registers */ case MISCREG_TPC: tpc[tl-1] = val; - return NoFault; + break; case MISCREG_TNPC: tnpc[tl-1] = val; - return NoFault; + break; case MISCREG_TSTATE: tstate[tl-1] = val; - return NoFault; + break; case MISCREG_TT: tt[tl-1] = val; - return NoFault; + break; case MISCREG_PRIVTICK: panic("Priviliged access to tick regesiters not implemented\n"); case MISCREG_TBA: - tba = val; - return NoFault; + // clear lower 7 bits on writes. + tba = val & ULL(~0x7FFF); + break; case MISCREG_PSTATE: pstate = val; - return NoFault; + break; case MISCREG_TL: tl = val; - return NoFault; + break; case MISCREG_PIL: pil = val; - return NoFault; + break; case MISCREG_CWP: cwp = val; - return NoFault; + break; case MISCREG_CANSAVE: cansave = val; - return NoFault; + break; case MISCREG_CANRESTORE: canrestore = val; - return NoFault; + break; case MISCREG_CLEANWIN: cleanwin = val; - return NoFault; + break; case MISCREG_OTHERWIN: otherwin = val; - return NoFault; + break; case MISCREG_WSTATE: wstate = val; - return NoFault; + break; case MISCREG_GL: gl = val; - return NoFault; + break; /** Hyper privileged registers */ case MISCREG_HPSTATE: hpstate = val; - return NoFault; + break; case MISCREG_HTSTATE: htstate[tl-1] = val; - return NoFault; + break; case MISCREG_HINTP: panic("HINTP not implemented\n"); case MISCREG_HTBA: htba = val; - return NoFault; + break; case MISCREG_STRAND_STS_REG: strandStatusReg = val; - return NoFault; + break; case MISCREG_HSTICK_CMPR: hstick_cmpr = val; - return NoFault; + break; /** Floating Point Status Register */ case MISCREG_FSR: fsr = val; - return NoFault; + break; default: panic("Miscellaneous register %d not implemented\n", miscReg); } + return NoFault; } Fault MiscRegFile::setRegWithEffect(int miscReg, @@ -393,91 +394,25 @@ Fault MiscRegFile::setRegWithEffect(int miscReg, { const uint64_t Bit64 = (1ULL << 63); switch (miscReg) { - case MISCREG_Y: - case MISCREG_CCR: - case MISCREG_ASI: - setReg(miscReg, val); - return NoFault; - case MISCREG_PRIVTICK: case MISCREG_TICK: - if (isNonPriv()) - return new PrivilegedOpcode; - if (isPriv()) - return new PrivilegedAction; tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64; tickFields.npt = val & Bit64 ? 1 : 0; - return NoFault; - case MISCREG_PC: - return new IllegalInstruction; + break; case MISCREG_FPRS: - return new UnimpFault("FPU not implemented\n"); + //Configure the fpu based on the fprs + break; case MISCREG_PCR: - return new UnimpFault("Performance Instrumentation not impl\n"); - case MISCREG_PIC: - return new UnimpFault("Performance Instrumentation not impl\n"); - case MISCREG_GSR: - return setReg(miscReg, val); - - /** Privilged Registers */ - case MISCREG_TPC: - case MISCREG_TNPC: - case MISCREG_TSTATE: - case MISCREG_TT: - if (tl == 0) - return new IllegalInstruction; - setReg(miscReg, val); - return NoFault; - - case MISCREG_TBA: - // clear lower 7 bits on writes. - setReg(miscReg, val & ULL(~0x7FFF)); - return NoFault; - - case MISCREG_PSTATE: - setReg(miscReg, val); - return NoFault; - - case MISCREG_TL: - if (isHyperPriv() && val > MaxTL) - setReg(miscReg, MaxTL); - else if (isPriv() && !isHyperPriv() && val > MaxPTL) - setReg(miscReg, MaxPTL); - else - setReg(miscReg, val); - return NoFault; - + //Set up performance counting based on pcr value + break; case MISCREG_CWP: tc->changeRegFileContext(CONTEXT_CWP, val); - case MISCREG_CANSAVE: - case MISCREG_CANRESTORE: - case MISCREG_CLEANWIN: - case MISCREG_OTHERWIN: - case MISCREG_WSTATE: - setReg(miscReg, val); - return NoFault; - + break; case MISCREG_GL: - int newval; - if (isHyperPriv() && val > MaxGL) - newval = MaxGL; - else if (isPriv() && !isHyperPriv() && val > MaxPGL) - newval = MaxPGL; - else - newval = val; - tc->changeRegFileContext(CONTEXT_GLOBALS, newval); - setReg(miscReg, newval); - return NoFault; - - /** Floating Point Status Register */ - case MISCREG_FSR: - setReg(miscReg, val); - default: -#if FULL_SYSTEM - setFSRegWithEffect(miscReg, val, tc); -#else - return new IllegalInstruction; -#endif + tc->changeRegFileContext(CONTEXT_GLOBALS, val); + break; } + setReg(miscReg, val); + return NoFault; } void MiscRegFile::serialize(std::ostream & os) diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index be143311f..0d81dae1e 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -56,7 +56,6 @@ namespace SparcISA MISCREG_CCR = AsrStart + 2, MISCREG_ASI = AsrStart + 3, MISCREG_TICK = AsrStart + 4, - MISCREG_PC = AsrStart + 5, MISCREG_FPRS = AsrStart + 6, MISCREG_PCR = AsrStart + 16, MISCREG_PIC = AsrStart + 17, From 944bfde6b34a27f2438e38f7d870532ed6c0447a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Oct 2006 01:36:42 -0400 Subject: [PATCH 14/40] Clean up MiscRegFile --HG-- extra : convert_revision : 3bc792596c99df3a5c2c82da58b801a63ccf6ddb --- src/arch/sparc/miscregfile.cc | 65 ++++------------------------------- src/arch/sparc/miscregfile.hh | 24 ++----------- 2 files changed, 9 insertions(+), 80 deletions(-) diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index ada3c18e7..bf4572878 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -202,78 +202,27 @@ MiscReg MiscRegFile::readReg(int miscReg) } } -MiscReg MiscRegFile::readRegWithEffect(int miscReg, - Fault &fault, ThreadContext * tc) +MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) { - fault = NoFault; switch (miscReg) { - case MISCREG_Y: - case MISCREG_CCR: - case MISCREG_ASI: - return readReg(miscReg); - case MISCREG_TICK: case MISCREG_PRIVTICK: - // Check for reading privilege - if (tickFields.npt && !isNonPriv()) { - fault = new PrivilegedAction; - return 0; - } return tc->getCpuPtr()->curCycle() - tickFields.counter | tickFields.npt << 63; case MISCREG_FPRS: - fault = new UnimpFault("FPU not implemented\n"); - return 0; + panic("FPU not implemented\n"); case MISCREG_PCR: - fault = new UnimpFault("Performance Instrumentation not impl\n"); - return 0; case MISCREG_PIC: - fault = new UnimpFault("Performance Instrumentation not impl\n"); - return 0; - case MISCREG_GSR: - return readReg(miscReg); - - /** Privilged Registers */ - case MISCREG_TPC: - case MISCREG_TNPC: - case MISCREG_TSTATE: - case MISCREG_TT: - if (tl == 0) { - fault = new IllegalInstruction; - return 0; - } // NOTE THE FALL THROUGH! - case MISCREG_PSTATE: - case MISCREG_TL: - return readReg(miscReg); - - case MISCREG_TBA: - return readReg(miscReg) & ULL(~0x7FFF); - - case MISCREG_PIL: - - case MISCREG_CWP: - case MISCREG_CANSAVE: - case MISCREG_CANRESTORE: - case MISCREG_CLEANWIN: - case MISCREG_OTHERWIN: - case MISCREG_WSTATE: - case MISCREG_GL: - return readReg(miscReg); + panic("Performance Instrumentation not impl\n"); /** Floating Point Status Register */ case MISCREG_FSR: panic("Floating Point not implemented\n"); - default: -#if FULL_SYSTEM - return readFSRegWithEffect(miscReg, fault, tc); -#else - fault = new IllegalInstruction; - return 0; -#endif } + return readReg(miscReg); } -Fault MiscRegFile::setReg(int miscReg, const MiscReg &val) +void MiscRegFile::setReg(int miscReg, const MiscReg &val) { switch (miscReg) { case MISCREG_Y: @@ -386,10 +335,9 @@ Fault MiscRegFile::setReg(int miscReg, const MiscReg &val) default: panic("Miscellaneous register %d not implemented\n", miscReg); } - return NoFault; } -Fault MiscRegFile::setRegWithEffect(int miscReg, +void MiscRegFile::setRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { const uint64_t Bit64 = (1ULL << 63); @@ -412,7 +360,6 @@ Fault MiscRegFile::setRegWithEffect(int miscReg, break; } setReg(miscReg, val); - return NoFault; } void MiscRegFile::serialize(std::ostream & os) diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 0d81dae1e..771cb1ed6 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -365,31 +365,13 @@ namespace SparcISA reset(); } - /** read a value out of an either an SE or FS IPR. No checking is done - * about SE vs. FS as this is mostly used to copy the regfile. Thus more - * register are copied that are necessary for FS. However this prevents - * a bunch of ifdefs and is rarely called so is not performance - * criticial. */ MiscReg readReg(int miscReg); - /** Read a value from an IPR. Only the SE iprs are here and the rest - * are are readFSRegWithEffect (which is called by readRegWithEffect()). - * Checking is done for permission based on state bits in the miscreg - * file. */ - MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); + MiscReg readRegWithEffect(int miscReg, ThreadContext *tc); - /** write a value into an either an SE or FS IPR. No checking is done - * about SE vs. FS as this is mostly used to copy the regfile. Thus more - * register are copied that are necessary for FS. However this prevents - * a bunch of ifdefs and is rarely called so is not performance - * criticial.*/ - Fault setReg(int miscReg, const MiscReg &val); + void setReg(int miscReg, const MiscReg &val); - /** Write a value into an IPR. Only the SE iprs are here and the rest - * are are setFSRegWithEffect (which is called by setRegWithEffect()). - * Checking is done for permission based on state bits in the miscreg - * file. */ - Fault setRegWithEffect(int miscReg, + void setRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc); void serialize(std::ostream & os); From b1cc98ed54b21e02c5ac52002497a5368452c529 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Oct 2006 01:43:26 -0400 Subject: [PATCH 15/40] Made the regfile compatible with the new definitions in MiscRegFile --HG-- extra : convert_revision : d63ea6fb1e549e737204ee6653c06f89ec5e43ef --- src/arch/sparc/regfile.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 747426781..5eb874d39 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -82,18 +82,21 @@ MiscReg RegFile::readMiscReg(int miscReg) MiscReg RegFile::readMiscRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc) { - return miscRegFile.readRegWithEffect(miscReg, fault, tc); + fault = NoFault; + return miscRegFile.readRegWithEffect(miscReg, tc); } Fault RegFile::setMiscReg(int miscReg, const MiscReg &val) { - return miscRegFile.setReg(miscReg, val); + miscRegFile.setReg(miscReg, val); + return NoFault; } Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { - return miscRegFile.setRegWithEffect(miscReg, val, tc); + miscRegFile.setRegWithEffect(miscReg, val, tc); + return NoFault; } FloatReg RegFile::readFloatReg(int floatReg, int width) From 709d50cd6bb4571b13385eed578f419bef3d579c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Oct 2006 01:43:51 -0400 Subject: [PATCH 16/40] Got rid of some outdated comments. --HG-- extra : convert_revision : 30fa768c4a934cf5f9dc0ad84e0e421327ccbed3 --- src/arch/sparc/isa/decoder.isa | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index a2657b3cd..dc7597e5e 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -357,13 +357,9 @@ decode OP default Unknown::unknown() }}); } 0x29: HPriv::rdhpr({{ - // XXX Need to protect with format that traps non-priv/priv - // access Rd = xc->readMiscRegWithEffect(RS1 + HprStart, fault); }}); 0x2A: Priv::rdpr({{ - // XXX Need to protect with format that traps non-priv - // access Rd = xc->readMiscRegWithEffect(RS1 + PrStart, fault); }}); 0x2B: BasicOperate::flushw({{ From ca34c62bf96b66fdb1aefc3b08cad8d969ee6bc9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Oct 2006 02:21:09 -0400 Subject: [PATCH 17/40] Update stats for fill/spill handlers --HG-- extra : convert_revision : 2ed2e868ccbb3316f84ea691497d2e0dd4ec2416 --- .../ref/sparc/linux/simple-atomic/config.ini | 2 + .../ref/sparc/linux/simple-atomic/config.out | 2 + .../ref/sparc/linux/simple-atomic/m5stats.txt | 18 +- .../ref/sparc/linux/simple-atomic/stdout | 8 +- .../ref/sparc/linux/simple-timing/config.ini | 1 - .../ref/sparc/linux/simple-timing/m5stats.txt | 232 +++++++++--------- .../ref/sparc/linux/simple-timing/stdout | 8 +- 7 files changed, 137 insertions(+), 134 deletions(-) diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.ini b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.ini index 21028fa63..9da46d74f 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.ini +++ b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.ini @@ -91,6 +91,8 @@ uid=100 [system.membus] type=Bus bus_id=0 +clock=1000 +width=64 port=system.physmem.port system.cpu.icache_port system.cpu.dcache_port [system.physmem] diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.out b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.out index f5be4e3bd..fc125a624 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.out +++ b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.out @@ -19,6 +19,8 @@ mem_mode=atomic [system.membus] type=Bus bus_id=0 +clock=1000 +width=64 [system.cpu.workload] type=LiveProcess diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/m5stats.txt b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/m5stats.txt index e87e77b8f..5c79f4d62 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/m5stats.txt +++ b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/m5stats.txt @@ -1,18 +1,18 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 2175 # Simulator instruction rate (inst/s) -host_mem_usage 147292 # Number of bytes of host memory used -host_seconds 2.06 # Real time elapsed on the host -host_tick_rate 2174 # Simulator tick rate (ticks/s) +host_inst_rate 58121 # Simulator instruction rate (inst/s) +host_mem_usage 148396 # Number of bytes of host memory used +host_seconds 0.08 # Real time elapsed on the host +host_tick_rate 57840 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 4483 # Number of instructions simulated +sim_insts 4863 # Number of instructions simulated sim_seconds 0.000000 # Number of seconds simulated -sim_ticks 4482 # Number of ticks simulated +sim_ticks 4862 # Number of ticks simulated system.cpu.idle_fraction 0 # Percentage of idle cycles system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 4483 # number of cpu cycles simulated -system.cpu.num_insts 4483 # Number of instructions executed -system.cpu.num_refs 965 # Number of memory references +system.cpu.numCycles 4863 # number of cpu cycles simulated +system.cpu.num_insts 4863 # Number of instructions executed +system.cpu.num_refs 1269 # Number of memory references system.cpu.workload.PROG:num_syscalls 11 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/stdout b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/stdout index c9df3a17c..1d76c6089 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/stdout +++ b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/stdout @@ -5,8 +5,8 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Oct 8 2006 14:19:59 -M5 started Sun Oct 8 14:20:03 2006 +M5 compiled Oct 27 2006 02:07:29 +M5 started Fri Oct 27 02:08:08 2006 M5 executing on zizzer.eecs.umich.edu -command line: build/SPARC_SE/m5.opt -d build/SPARC_SE/tests/opt/quick/00.hello/sparc/linux/simple-atomic tests/run.py quick/00.hello/sparc/linux/simple-atomic -Exiting @ tick 4482 because target called exit() +command line: build/SPARC_SE/m5.debug -d build/SPARC_SE/tests/debug/quick/00.hello/sparc/linux/simple-atomic tests/run.py quick/00.hello/sparc/linux/simple-atomic +Exiting @ tick 4862 because target called exit() diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini b/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini index 982973385..da87d03a1 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini +++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini @@ -20,7 +20,6 @@ print_effaddr=true print_fetchseq=false print_iregs=false print_opclass=true -print_reg_delta=false print_thread=true speculative=true trace_system=client diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt b/tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt index c4dc22855..3645207b1 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt +++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt @@ -1,67 +1,67 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 53689 # Simulator instruction rate (inst/s) -host_mem_usage 177104 # Number of bytes of host memory used -host_seconds 0.08 # Real time elapsed on the host -host_tick_rate 17808084 # Simulator tick rate (ticks/s) +host_inst_rate 48159 # Simulator instruction rate (inst/s) +host_mem_usage 179620 # Number of bytes of host memory used +host_seconds 0.10 # Real time elapsed on the host +host_tick_rate 15510230 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 4483 # Number of instructions simulated -sim_seconds 0.000001 # Number of seconds simulated -sim_ticks 1497001 # Number of ticks simulated -system.cpu.dcache.ReadReq_accesses 464 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 3972.166667 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 2972.166667 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 410 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 214497 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.116379 # miss rate for ReadReq accesses +sim_insts 4863 # Number of instructions simulated +sim_seconds 0.000002 # Number of seconds simulated +sim_ticks 1573001 # Number of ticks simulated +system.cpu.dcache.ReadReq_accesses 608 # number of ReadReq accesses(hits+misses) +system.cpu.dcache.ReadReq_avg_miss_latency 3971.370370 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 2971.370370 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 554 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 214454 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.088816 # miss rate for ReadReq accesses system.cpu.dcache.ReadReq_misses 54 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 160497 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.116379 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_miss_latency 160454 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.088816 # mshr miss rate for ReadReq accesses system.cpu.dcache.ReadReq_mshr_misses 54 # number of ReadReq MSHR misses -system.cpu.dcache.WriteReq_accesses 501 # number of WriteReq accesses(hits+misses) -system.cpu.dcache.WriteReq_avg_miss_latency 3980.840580 # average WriteReq miss latency -system.cpu.dcache.WriteReq_avg_mshr_miss_latency 2980.840580 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 432 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 274678 # number of WriteReq miss cycles -system.cpu.dcache.WriteReq_miss_rate 0.137725 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 69 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 205678 # number of WriteReq MSHR miss cycles -system.cpu.dcache.WriteReq_mshr_miss_rate 0.137725 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 69 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_accesses 661 # number of WriteReq accesses(hits+misses) +system.cpu.dcache.WriteReq_avg_miss_latency 3981.559524 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 2981.559524 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 577 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 334451 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.127080 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 84 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 250451 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.127080 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 84 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles_no_mshrs # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles_no_targets # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 6.845528 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 8.195652 # Average number of references to valid blocks. system.cpu.dcache.blocked_no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles_no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles_no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed -system.cpu.dcache.demand_accesses 965 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 3977.032520 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 2977.032520 # average overall mshr miss latency -system.cpu.dcache.demand_hits 842 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 489175 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.127461 # miss rate for demand accesses -system.cpu.dcache.demand_misses 123 # number of demand (read+write) misses +system.cpu.dcache.demand_accesses 1269 # number of demand (read+write) accesses +system.cpu.dcache.demand_avg_miss_latency 3977.572464 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 2977.572464 # average overall mshr miss latency +system.cpu.dcache.demand_hits 1131 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 548905 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.108747 # miss rate for demand accesses +system.cpu.dcache.demand_misses 138 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 366175 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.127461 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 123 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 410905 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.108747 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 138 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.dcache.overall_accesses 965 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 3977.032520 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 2977.032520 # average overall mshr miss latency +system.cpu.dcache.overall_accesses 1269 # number of overall (read+write) accesses +system.cpu.dcache.overall_avg_miss_latency 3977.572464 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 2977.572464 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 842 # number of overall hits -system.cpu.dcache.overall_miss_latency 489175 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.127461 # miss rate for overall accesses -system.cpu.dcache.overall_misses 123 # number of overall misses +system.cpu.dcache.overall_hits 1131 # number of overall hits +system.cpu.dcache.overall_miss_latency 548905 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.108747 # miss rate for overall accesses +system.cpu.dcache.overall_misses 138 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 366175 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.127461 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 123 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 410905 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.108747 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 138 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.dcache.prefetcher.num_hwpf_already_in_cache 0 # number of hwpf that were already in the cache @@ -74,56 +74,56 @@ system.cpu.dcache.prefetcher.num_hwpf_removed_MSHR_hit 0 system.cpu.dcache.prefetcher.num_hwpf_span_page 0 # number of hwpf spanning a virtual page system.cpu.dcache.prefetcher.num_hwpf_squashed_from_miss 0 # number of hwpf that got squashed due to a miss aborting calculation time system.cpu.dcache.replacements 0 # number of replacements -system.cpu.dcache.sampled_refs 123 # Sample count of references to valid blocks. +system.cpu.dcache.sampled_refs 138 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 71.370810 # Cycle average of tags in use -system.cpu.dcache.total_refs 842 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 81.997528 # Cycle average of tags in use +system.cpu.dcache.total_refs 1131 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.dcache.writebacks 0 # number of writebacks -system.cpu.icache.ReadReq_accesses 4484 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 3979.178571 # average ReadReq miss latency -system.cpu.icache.ReadReq_avg_mshr_miss_latency 2979.178571 # average ReadReq mshr miss latency -system.cpu.icache.ReadReq_hits 4232 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 1002753 # number of ReadReq miss cycles -system.cpu.icache.ReadReq_miss_rate 0.056200 # miss rate for ReadReq accesses -system.cpu.icache.ReadReq_misses 252 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_miss_latency 750753 # number of ReadReq MSHR miss cycles -system.cpu.icache.ReadReq_mshr_miss_rate 0.056200 # mshr miss rate for ReadReq accesses -system.cpu.icache.ReadReq_mshr_misses 252 # number of ReadReq MSHR misses +system.cpu.icache.ReadReq_accesses 4864 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 3977.960938 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 2977.960938 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_hits 4608 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 1018358 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.052632 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 256 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_miss_latency 762358 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_rate 0.052632 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_misses 256 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles_no_mshrs # average number of cycles each access was blocked system.cpu.icache.avg_blocked_cycles_no_targets # average number of cycles each access was blocked -system.cpu.icache.avg_refs 16.793651 # Average number of references to valid blocks. +system.cpu.icache.avg_refs 18 # Average number of references to valid blocks. system.cpu.icache.blocked_no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked_no_targets 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles_no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles_no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed -system.cpu.icache.demand_accesses 4484 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 3979.178571 # average overall miss latency -system.cpu.icache.demand_avg_mshr_miss_latency 2979.178571 # average overall mshr miss latency -system.cpu.icache.demand_hits 4232 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 1002753 # number of demand (read+write) miss cycles -system.cpu.icache.demand_miss_rate 0.056200 # miss rate for demand accesses -system.cpu.icache.demand_misses 252 # number of demand (read+write) misses +system.cpu.icache.demand_accesses 4864 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 3977.960938 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 2977.960938 # average overall mshr miss latency +system.cpu.icache.demand_hits 4608 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 1018358 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.052632 # miss rate for demand accesses +system.cpu.icache.demand_misses 256 # number of demand (read+write) misses system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.icache.demand_mshr_miss_latency 750753 # number of demand (read+write) MSHR miss cycles -system.cpu.icache.demand_mshr_miss_rate 0.056200 # mshr miss rate for demand accesses -system.cpu.icache.demand_mshr_misses 252 # number of demand (read+write) MSHR misses +system.cpu.icache.demand_mshr_miss_latency 762358 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_rate 0.052632 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_misses 256 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.icache.overall_accesses 4484 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 3979.178571 # average overall miss latency -system.cpu.icache.overall_avg_mshr_miss_latency 2979.178571 # average overall mshr miss latency +system.cpu.icache.overall_accesses 4864 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 3977.960938 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 2977.960938 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no value # average overall mshr uncacheable latency -system.cpu.icache.overall_hits 4232 # number of overall hits -system.cpu.icache.overall_miss_latency 1002753 # number of overall miss cycles -system.cpu.icache.overall_miss_rate 0.056200 # miss rate for overall accesses -system.cpu.icache.overall_misses 252 # number of overall misses +system.cpu.icache.overall_hits 4608 # number of overall hits +system.cpu.icache.overall_miss_latency 1018358 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.052632 # miss rate for overall accesses +system.cpu.icache.overall_misses 256 # number of overall misses system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.icache.overall_mshr_miss_latency 750753 # number of overall MSHR miss cycles -system.cpu.icache.overall_mshr_miss_rate 0.056200 # mshr miss rate for overall accesses -system.cpu.icache.overall_mshr_misses 252 # number of overall MSHR misses +system.cpu.icache.overall_mshr_miss_latency 762358 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_rate 0.052632 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_misses 256 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.icache.prefetcher.num_hwpf_already_in_cache 0 # number of hwpf that were already in the cache @@ -136,57 +136,57 @@ system.cpu.icache.prefetcher.num_hwpf_removed_MSHR_hit 0 system.cpu.icache.prefetcher.num_hwpf_span_page 0 # number of hwpf spanning a virtual page system.cpu.icache.prefetcher.num_hwpf_squashed_from_miss 0 # number of hwpf that got squashed due to a miss aborting calculation time system.cpu.icache.replacements 0 # number of replacements -system.cpu.icache.sampled_refs 252 # Sample count of references to valid blocks. +system.cpu.icache.sampled_refs 256 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 115.914677 # Cycle average of tags in use -system.cpu.icache.total_refs 4232 # Total number of references to valid blocks. +system.cpu.icache.tagsinuse 114.778311 # Cycle average of tags in use +system.cpu.icache.total_refs 4608 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadReq_accesses 375 # number of ReadReq accesses(hits+misses) -system.cpu.l2cache.ReadReq_avg_miss_latency 2986.473118 # average ReadReq miss latency -system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 1985.473118 # average ReadReq mshr miss latency +system.cpu.l2cache.ReadReq_accesses 394 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 2985.429668 # average ReadReq miss latency +system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 1984.429668 # average ReadReq mshr miss latency system.cpu.l2cache.ReadReq_hits 3 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 1110968 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.992000 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 372 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 738596 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.992000 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 372 # number of ReadReq MSHR misses +system.cpu.l2cache.ReadReq_miss_latency 1167303 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.992386 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 391 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 775912 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.992386 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 391 # number of ReadReq MSHR misses system.cpu.l2cache.avg_blocked_cycles_no_mshrs # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles_no_targets # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 0.008065 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 0.007673 # Average number of references to valid blocks. system.cpu.l2cache.blocked_no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles_no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles_no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 375 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 2986.473118 # average overall miss latency -system.cpu.l2cache.demand_avg_mshr_miss_latency 1985.473118 # average overall mshr miss latency +system.cpu.l2cache.demand_accesses 394 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 2985.429668 # average overall miss latency +system.cpu.l2cache.demand_avg_mshr_miss_latency 1984.429668 # average overall mshr miss latency system.cpu.l2cache.demand_hits 3 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 1110968 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.992000 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 372 # number of demand (read+write) misses +system.cpu.l2cache.demand_miss_latency 1167303 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.992386 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 391 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 738596 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.992000 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 372 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 775912 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.992386 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 391 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 375 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 2986.473118 # average overall miss latency -system.cpu.l2cache.overall_avg_mshr_miss_latency 1985.473118 # average overall mshr miss latency +system.cpu.l2cache.overall_accesses 394 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 2985.429668 # average overall miss latency +system.cpu.l2cache.overall_avg_mshr_miss_latency 1984.429668 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no value # average overall mshr uncacheable latency system.cpu.l2cache.overall_hits 3 # number of overall hits -system.cpu.l2cache.overall_miss_latency 1110968 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.992000 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 372 # number of overall misses +system.cpu.l2cache.overall_miss_latency 1167303 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.992386 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 391 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 738596 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.992000 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 372 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 775912 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.992386 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 391 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.l2cache.prefetcher.num_hwpf_already_in_cache 0 # number of hwpf that were already in the cache @@ -199,16 +199,16 @@ system.cpu.l2cache.prefetcher.num_hwpf_removed_MSHR_hit 0 system.cpu.l2cache.prefetcher.num_hwpf_span_page 0 # number of hwpf spanning a virtual page system.cpu.l2cache.prefetcher.num_hwpf_squashed_from_miss 0 # number of hwpf that got squashed due to a miss aborting calculation time system.cpu.l2cache.replacements 0 # number of replacements -system.cpu.l2cache.sampled_refs 372 # Sample count of references to valid blocks. +system.cpu.l2cache.sampled_refs 391 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 185.896040 # Cycle average of tags in use +system.cpu.l2cache.tagsinuse 195.424915 # Cycle average of tags in use system.cpu.l2cache.total_refs 3 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.l2cache.writebacks 0 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 1497001 # number of cpu cycles simulated -system.cpu.num_insts 4483 # Number of instructions executed -system.cpu.num_refs 965 # Number of memory references +system.cpu.numCycles 1573001 # number of cpu cycles simulated +system.cpu.num_insts 4863 # Number of instructions executed +system.cpu.num_refs 1269 # Number of memory references system.cpu.workload.PROG:num_syscalls 11 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout b/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout index 3c17ee40b..b1da2e4ab 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout +++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout @@ -5,8 +5,8 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Oct 23 2006 07:47:36 -M5 started Mon Oct 23 07:47:41 2006 -M5 executing on zeep +M5 compiled Oct 27 2006 02:07:29 +M5 started Fri Oct 27 02:08:11 2006 +M5 executing on zizzer.eecs.umich.edu command line: build/SPARC_SE/m5.debug -d build/SPARC_SE/tests/debug/quick/00.hello/sparc/linux/simple-timing tests/run.py quick/00.hello/sparc/linux/simple-timing -Exiting @ tick 1497001 because target called exit() +Exiting @ tick 1573001 because target called exit() From d5974eff73a3cb69e50754ba92f65a73c904c2e0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Oct 2006 06:51:28 -0400 Subject: [PATCH 18/40] Potential fix to clock skew problem. --HG-- extra : convert_revision : 51572523190a886fd0ff64817edc88e260c5fa9d --- src/cpu/simple/atomic.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index edba55b0d..b4ea4b216 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -234,6 +234,9 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay) assert(!tickEvent.scheduled()); notIdleFraction++; + //Make sure ticks are still on multiples of cycles + Tick nextTick = curTick + cycles(1) - 1; + nextTick -= (nextTick % (cycles(1))); tickEvent.schedule(curTick + cycles(delay)); _status = Running; } From a46e19f7384eb3e6a03136ddab5ba74716e43eb6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Oct 2006 07:09:14 -0400 Subject: [PATCH 19/40] A more complete attempt to fix the clock skew. --HG-- extra : convert_revision : b2d505de51fc5fcae5177b2a13140729474e249e --- src/cpu/simple/atomic.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index b4ea4b216..a72f6361a 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -188,8 +188,11 @@ AtomicSimpleCPU::resume() changeState(SimObject::Running); if (thread->status() == ThreadContext::Active) { - if (!tickEvent.scheduled()) - tickEvent.schedule(curTick); + if (!tickEvent.scheduled()) { + Tick nextTick = curTick + cycles(1) - 1; + nextTick -= (nextTick % (cycles(1))); + tickEvent.schedule(nextTick); + } } } } @@ -217,7 +220,9 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU) ThreadContext *tc = threadContexts[i]; if (tc->status() == ThreadContext::Active && _status != Running) { _status = Running; - tickEvent.schedule(curTick); + Tick nextTick = curTick + cycles(1) - 1; + nextTick -= (nextTick % (cycles(1))); + tickEvent.schedule(nextTick); break; } } @@ -237,7 +242,7 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay) //Make sure ticks are still on multiples of cycles Tick nextTick = curTick + cycles(1) - 1; nextTick -= (nextTick % (cycles(1))); - tickEvent.schedule(curTick + cycles(delay)); + tickEvent.schedule(nextTick); _status = Running; } From baaadb0d43f2570a8bd541b085ac0e8cff56e555 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 27 Oct 2006 09:10:50 -0400 Subject: [PATCH 20/40] add packet_access.hh --HG-- extra : convert_revision : 7fe4958549101fca9613baa4a317d96f4970d432 --- src/dev/i8254xGBe.cc | 53 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc index e52a3e73d..7fc68f4e7 100644 --- a/src/dev/i8254xGBe.cc +++ b/src/dev/i8254xGBe.cc @@ -38,6 +38,7 @@ #include "base/inet.hh" #include "dev/i8254xGBe.hh" #include "mem/packet.hh" +#include "mem/packet_access.hh" #include "sim/builder.hh" #include "sim/stats.hh" #include "sim/system.hh" @@ -66,12 +67,17 @@ IGbE::IGbE(Params *p) regs.tctl.reg = 0; regs.manc.reg = 0; + regs.pba.rxa = 0x30; + regs.pba.txa = 0x10; + eeOpBits = 0; eeAddrBits = 0; eeDataBits = 0; eeOpcode = 0; - memset(&flash, 0, EEPROM_SIZE); + // clear all 64 16 bit words of the eeprom + memset(&flash, 0, EEPROM_SIZE*2); + // Magic happy checksum value flash[0] = 0xBABA; } @@ -108,7 +114,7 @@ IGbE::read(PacketPtr pkt) // Only 32bit accesses allowed assert(pkt->getSize() == 4); - DPRINTF(Ethernet, "Read device register %#X\n", daddr); + //DPRINTF(Ethernet, "Read device register %#X\n", daddr); pkt->allocate(); @@ -116,6 +122,7 @@ IGbE::read(PacketPtr pkt) /// Handle read of register here /// + switch (daddr) { case CTRL: pkt->set(regs.ctrl.reg); @@ -141,11 +148,23 @@ IGbE::read(PacketPtr pkt) case TCTL: pkt->set(regs.tctl.reg); break; + case PBA: + pkt->set(regs.pba.reg); + break; + case WUC: + case LEDCTL: + pkt->set(0); // We don't care, so just return 0 + break; case MANC: pkt->set(regs.manc.reg); break; default: - panic("Read request to unknown register number: %#x\n", daddr); + if (!(daddr >= VFTA && daddr < (VFTA + VLAN_FILTER_TABLE_SIZE)*4) && + !(daddr >= RAL && daddr < (RAL + RCV_ADDRESS_TABLE_SIZE)*4) && + !(daddr >= MTA && daddr < (MTA + MULTICAST_TABLE_SIZE)*4)) + pkt->set(0); + else + panic("Read request to unknown register number: %#x\n", daddr); }; pkt->result = Packet::Success; @@ -168,7 +187,7 @@ IGbE::write(PacketPtr pkt) // Only 32bit accesses allowed assert(pkt->getSize() == sizeof(uint32_t)); - DPRINTF(Ethernet, "Wrote device register %#X value %#X\n", daddr, pkt->get()); + //DPRINTF(Ethernet, "Wrote device register %#X value %#X\n", daddr, pkt->get()); /// /// Handle write of register here @@ -195,10 +214,10 @@ IGbE::write(PacketPtr pkt) eeAddr = eeAddr << 1 | regs.eecd.din; eeAddrBits++; } else if (eeDataBits < 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) { - assert(eeAddr < EEPROM_SIZE); - DPRINTF(Ethernet, "EEPROM bit read: %d word: %#X\n", - flash[eeAddr] >> eeDataBits & 0x1, flash[eeAddr]); - regs.eecd.dout = (flash[eeAddr] >> eeDataBits) & 0x1; + assert(eeAddr>>1 < EEPROM_SIZE); + DPRINTF(EthernetEEPROM, "EEPROM bit read: %d word: %#X\n", + flash[eeAddr>>1] >> eeDataBits & 0x1, flash[eeAddr>>1]); + regs.eecd.dout = (flash[eeAddr>>1] >> (15-eeDataBits)) & 0x1; eeDataBits++; } else if (eeDataBits < 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI) { regs.eecd.dout = 0; @@ -219,8 +238,9 @@ IGbE::write(PacketPtr pkt) eeAddr = 0; } - DPRINTF(Ethernet, "EEPROM: opcode: %#X:%d\n", - (uint32_t)eeOpcode, (uint32_t) eeOpBits); + DPRINTF(EthernetEEPROM, "EEPROM: opcode: %#X:%d addr: %#X:%d\n", + (uint32_t)eeOpcode, (uint32_t) eeOpBits, + (uint32_t)eeAddr>>1, (uint32_t)eeAddrBits); if (eeOpBits == 8 && !(eeOpcode == EEPROM_READ_OPCODE_SPI || eeOpcode == EEPROM_RDSR_OPCODE_SPI )) panic("Unknown eeprom opcode: %#X:%d\n", (uint32_t)eeOpcode, @@ -246,11 +266,22 @@ IGbE::write(PacketPtr pkt) case TCTL: regs.tctl.reg = val; break; + case PBA: + regs.pba.rxa = val; + regs.pba.txa = 64 - regs.pba.rxa; + break; + case WUC: + case LEDCTL: + ; // We don't care, so don't store anything + break; case MANC: regs.manc.reg = val; break; default: - panic("Write request to unknown register number: %#x\n", daddr); + if (!(daddr >= VFTA && daddr < (VFTA + VLAN_FILTER_TABLE_SIZE)*4) && + !(daddr >= RAL && daddr < (RAL + RCV_ADDRESS_TABLE_SIZE)*4) && + !(daddr >= MTA && daddr < (MTA + MULTICAST_TABLE_SIZE)*4)) + panic("Write request to unknown register number: %#x\n", daddr); }; pkt->result = Packet::Success; From a6fd29ddf9b2b40d5b1beb425ab2f043cc97a911 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Fri, 27 Oct 2006 16:32:26 -0400 Subject: [PATCH 21/40] factor out common run code from se.py and fs.py. configs/example/fs.py: factor out common code. configs/example/se.py: factor out common code --HG-- extra : convert_revision : 72a1f653c84eae1b7d281e0a5e60ee116ad6b27d --- configs/common/Caches.py | 39 +++++++ configs/common/Options.py | 57 ++++++++++ configs/common/Simulation.py | 175 ++++++++++++++++++++++++++++++ configs/example/fs.py | 169 +---------------------------- configs/example/se.py | 205 ++++------------------------------- 5 files changed, 299 insertions(+), 346 deletions(-) create mode 100644 configs/common/Caches.py create mode 100644 configs/common/Options.py create mode 100644 configs/common/Simulation.py diff --git a/configs/common/Caches.py b/configs/common/Caches.py new file mode 100644 index 000000000..d86fba246 --- /dev/null +++ b/configs/common/Caches.py @@ -0,0 +1,39 @@ +# 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: Lisa Hsu + +import m5 +from m5.objects import * + +class L1Cache(BaseCache): + assoc = 2 + block_size = 64 + latency = 1 + mshrs = 10 + tgts_per_mshr = 5 + protocol = CoherenceProtocol(protocol='moesi') + diff --git a/configs/common/Options.py b/configs/common/Options.py new file mode 100644 index 000000000..d9c1cc64e --- /dev/null +++ b/configs/common/Options.py @@ -0,0 +1,57 @@ +# 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: Lisa Hsu + +# system options +parser.add_option("-d", "--detailed", action="store_true") +parser.add_option("-t", "--timing", action="store_true") +parser.add_option("-n", "--num_cpus", type="int", default=1) +parser.add_option("--caches", action="store_true") + +# Run duration options +parser.add_option("-m", "--maxtick", type="int") +parser.add_option("--maxtime", type="float") + +# Checkpointing options +###Note that performing checkpointing via python script files will override +###checkpoint instructions built into binaries. +parser.add_option("--take_checkpoints", action="store", type="string", + help=" will take checkpoint at cycle M and every N cycles \ + thereafter") +parser.add_option("--max_checkpoints", action="store", type="int", + help="the maximum number of checkpoints to drop", + default=5) +parser.add_option("--checkpoint_dir", action="store", type="string", + help="Place all checkpoints in this absolute directory") +parser.add_option("-r", "--checkpoint_restore", action="store", type="int", + help="restore from checkpoint ") + +# CPU Switching - default switch model goes from a checkpoint +# to a timing simple CPU with caches to warm up, then to detailed CPU for +# data measurement +parser.add_option("-s", "--standard_switch", action="store_true", + help="switch from one cpu mode to another") diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py new file mode 100644 index 000000000..b927315ba --- /dev/null +++ b/configs/common/Simulation.py @@ -0,0 +1,175 @@ +# 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: Lisa Hsu + +from os import getcwd +import m5 +from m5.objects import * +m5.AddToPath('../common') +from Caches import * + +def run(options, root, testsys): + if options.maxtick: + maxtick = options.maxtick + elif options.maxtime: + simtime = int(options.maxtime * root.clock.value) + print "simulating for: ", simtime + maxtick = simtime + else: + maxtick = -1 + + if options.checkpoint_dir: + cptdir = options.checkpoint_dir + else: + cptdir = getcwd() + + np = options.num_cpus + max_checkpoints = options.max_checkpoints + + if options.standard_switch: + switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i)) + for i in xrange(np)] + switch_cpus1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i)) + for i in xrange(np)] + for i in xrange(np): + switch_cpus[i].system = testsys + switch_cpus1[i].system = testsys + if not m5.build_env['FULL_SYSTEM']: + switch_cpus[i].workload = testsys.cpu[i].workload + switch_cpus1[i].workload = testsys.cpu[i].workload + switch_cpus[i].clock = testsys.cpu[0].clock + switch_cpus1[i].clock = testsys.cpu[0].clock + if options.caches: + switch_cpus[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), + L1Cache(size = '64kB')) + + switch_cpus[i].mem = testsys.physmem + switch_cpus1[i].mem = testsys.physmem + switch_cpus[i].connectMemPorts(testsys.membus) + root.switch_cpus = switch_cpus + root.switch_cpus1 = switch_cpus1 + switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] + switch_cpu_list1 = [(switch_cpus[i], switch_cpus1[i]) for i in xrange(np)] + + m5.instantiate(root) + + if options.checkpoint_restore: + from os.path import isdir + from os import listdir + import re + + if not isdir(cptdir): + m5.panic("checkpoint dir %s does not exist!" % cptdir) + + dirs = listdir(cptdir) + expr = re.compile('cpt.([0-9]*)') + cpts = [] + for dir in dirs: + match = expr.match(dir) + if match: + cpts.append(match.group(1)) + + cpts.sort(lambda a,b: cmp(long(a), long(b))) + + cpt_num = options.checkpoint_restore + + if cpt_num > len(cpts): + m5.panic('Checkpoint %d not found' % cpt_num) + + m5.restoreCheckpoint(root, + "/".join([cptdir, "cpt.%s" % cpts[cpt_num - 1]])) + + if options.standard_switch: + exit_event = m5.simulate(10000) + + ## when you change to Timing (or Atomic), you halt the system given + ## as argument. When you are finished with the system changes + ## (including switchCpus), you must resume the system manually. + ## You DON'T need to resume after just switching CPUs if you haven't + ## changed anything on the system level. + + m5.changeToTiming(testsys) + m5.switchCpus(switch_cpu_list) + m5.resume(testsys) + + exit_event = m5.simulate(3000000) + m5.switchCpus(switch_cpu_list1) + + num_checkpoints = 0 + exit_cause = '' + + if options.take_checkpoints: + [when, period] = options.take_checkpoints.split(",", 1) + when = int(when) + period = int(period) + + print "when is ", when, " period is ", period + exit_event = m5.simulate(when) + while exit_event.getCause() == "checkpoint": + exit_event = m5.simulate(when - m5.curTick()) + + if exit_event.getCause() == "simulate() limit reached": + m5.checkpoint(root, cptdir + "cpt.%d") + num_checkpoints += 1 + + sim_ticks = when + exit_cause = "maximum %d checkpoints dropped" % max_checkpoints + while num_checkpoints < max_checkpoints: + if (sim_ticks + period) > maxtick and maxtick != -1: + exit_event = m5.simulate(maxtick - sim_ticks) + exit_cause = exit_event.getCause() + break + else: + exit_event = m5.simulate(period) + sim_ticks += period + while exit_event.getCause() == "checkpoint": + exit_event = m5.simulate(sim_ticks - m5.curTick()) + if exit_event.getCause() == "simulate() limit reached": + m5.checkpoint(root, cptdir + "cpt.%d") + num_checkpoints += 1 + + else: #no checkpoints being taken via this script + exit_event = m5.simulate(maxtick) + + while exit_event.getCause() == "checkpoint": + m5.checkpoint(root, cptdir + "cpt.%d") + num_checkpoints += 1 + if num_checkpoints == max_checkpoints: + exit_cause = "maximum %d checkpoints dropped" % max_checkpoints + break + + if maxtick == -1: + exit_event = m5.simulate(maxtick) + else: + exit_event = m5.simulate(maxtick - m5.curTick()) + + exit_cause = exit_event.getCause() + + if exit_cause == '': + exit_cause = exit_event.getCause() + print 'Exiting @ cycle', m5.curTick(), 'because ', exit_cause + diff --git a/configs/example/fs.py b/configs/example/fs.py index a9daf63be..ec3be835a 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -34,6 +34,7 @@ m5.AddToPath('../common') from FSConfig import * from SysPaths import * from Benchmarks import * +import Simulation if not m5.build_env['FULL_SYSTEM']: m5.panic("This script requires full-system mode (ALPHA_FS).") @@ -48,40 +49,13 @@ parser.add_option("-b", "--benchmark", action="store", type="string", help="Specify the benchmark to run. Available benchmarks: %s"\ % DefinedBenchmarks) -# system options -parser.add_option("-d", "--detailed", action="store_true") -parser.add_option("-t", "--timing", action="store_true") -parser.add_option("-n", "--num_cpus", type="int", default=1) -parser.add_option("--caches", action="store_true") - -# Run duration options -parser.add_option("-m", "--maxtick", type="int") -parser.add_option("--maxtime", type="float") - # Metafile options parser.add_option("--etherdump", action="store", type="string", dest="etherdump", help="Specify the filename to dump a pcap capture of the" \ "ethernet traffic") -# Checkpointing options -###Note that performing checkpointing via python script files will override -###checkpoint instructions built into binaries. -parser.add_option("--take_checkpoints", action="store", type="string", - help=" will take checkpoint at cycle M and every N cycles \ - thereafter") -parser.add_option("--max_checkpoints", action="store", type="int", - help="the maximum number of checkpoints to drop", - default=5) -parser.add_option("--checkpoint_dir", action="store", type="string", - help="Place all checkpoints in this absolute directory") -parser.add_option("-r", "--checkpoint_restore", action="store", type="int", - help="restore from checkpoint ") -# CPU Switching - default switch model goes from a checkpoint -# to a timing simple CPU with caches to warm up, then to detailed CPU for -# data measurement -parser.add_option("-s", "--standard_switch", action="store_true", - help="switch from one cpu mode to another") +execfile("Options.py") (options, args) = parser.parse_args() @@ -89,14 +63,6 @@ if args: print "Error: script doesn't take any positional arguments" sys.exit(1) -class MyCache(BaseCache): - assoc = 2 - block_size = 64 - latency = 1 - mshrs = 10 - tgts_per_mshr = 5 - protocol = CoherenceProtocol(protocol='moesi') - # driver system CPU is always simple... note this is an assignment of # a class, not an instance. DriveCPUClass = AtomicSimpleCPU @@ -134,8 +100,8 @@ np = options.num_cpus test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)] for i in xrange(np): if options.caches and not options.standard_switch: - test_sys.cpu[i].addPrivateSplitL1Caches(MyCache(size = '32kB'), - MyCache(size = '64kB')) + test_sys.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), + L2Cache(size = '64kB')) test_sys.cpu[i].connectMemPorts(test_sys.membus) test_sys.cpu[i].mem = test_sys.physmem @@ -151,129 +117,4 @@ else: print "Error I don't know how to create more than 2 systems." sys.exit(1) -if options.standard_switch: - switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i) for i in xrange(np))] - switch_cpus1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i) for i in xrange(np))] - for i in xrange(np): - switch_cpus[i].system = test_sys - switch_cpus1[i].system = test_sys - switch_cpus[i].clock = TestCPUClass.clock - switch_cpus1[i].clock = TestCPUClass.clock - if options.caches: - switch_cpus[i].addPrivateSplitL1Caches(MyCache(size = '32kB'), - MyCache(size = '64kB')) - - switch_cpus[i].mem = test_sys.physmem - switch_cpus1[i].mem = test_sys.physmem - switch_cpus[i].connectMemPorts(test_sys.membus) - root.switch_cpus = switch_cpus - root.switch_cpus1 = switch_cpus1 - switch_cpu_list = [(test_sys.cpu[i], switch_cpus[i]) for i in xrange(np)] - switch_cpu_list1 = [(switch_cpus[i], switch_cpus1[i]) for i in xrange(np)] - -m5.instantiate(root) - -if options.checkpoint_dir: - cptdir = options.checkpoint_dir -else: - cptdir = getcwd() - -if options.checkpoint_restore: - from os.path import isdir - from os import listdir, getcwd - import re - - if not isdir(cptdir): - m5.panic("checkpoint dir %s does not exist!" % cptdir) - - dirs = listdir(cptdir) - expr = re.compile('cpt.([0-9]*)') - cpts = [] - for dir in dirs: - match = expr.match(dir) - if match: - cpts.append(match.group(1)) - - cpts.sort(lambda a,b: cmp(long(a), long(b))) - - if options.checkpoint_restore > len(cpts): - m5.panic('Checkpoint %d not found' % options.checkpoint_restore) - - m5.restoreCheckpoint(root, "/".join([cptdir, "cpt.%s" % cpts[options.checkpoint_restore - 1]])) - -if options.standard_switch: - exit_event = m5.simulate(1000) - ## when you change to Timing (or Atomic), you halt the system given - ## as argument. When you are finished with the system changes - ## (including switchCpus), you must resume the system manually. - ## You DON'T need to resume after just switching CPUs if you haven't - ## changed anything on the system level. - m5.changeToTiming(test_sys) - m5.switchCpus(switch_cpu_list) - m5.resume(test_sys) - - exit_event = m5.simulate(500000000000) - m5.switchCpus(switch_cpu_list1) - -if options.maxtick: - maxtick = options.maxtick -elif options.maxtime: - simtime = int(options.maxtime * root.clock.value) - print "simulating for: ", simtime - maxtick = simtime -else: - maxtick = -1 - -num_checkpoints = 0 - -exit_cause = '' - -if options.take_checkpoints: - [when, period] = options.take_checkpoints.split(",", 1) - when = int(when) - period = int(period) - - exit_event = m5.simulate(when) - while exit_event.getCause() == "checkpoint": - exit_event = m5.simulate(when - m5.curTick()) - - if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - - sim_ticks = when - exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints - while num_checkpoints < options.max_checkpoints: - if (sim_ticks + period) > maxtick and maxtick != -1: - exit_event = m5.simulate(maxtick - sim_ticks) - exit_cause = exit_event.getCause() - break - else: - exit_event = m5.simulate(period) - sim_ticks += period - while exit_event.getCause() == "checkpoint": - exit_event = m5.simulate(period - m5.curTick()) - if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - -else: #no checkpoints being taken via this script - exit_event = m5.simulate(maxtick) - - while exit_event.getCause() == "checkpoint": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - if num_checkpoints == options.max_checkpoints: - exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints - break - - if maxtick == -1: - exit_event = m5.simulate(maxtick) - else: - exit_event = m5.simulate(maxtick - m5.curTick()) - - exit_cause = exit_event.getCause() - -if exit_cause == '': - exit_cause = exit_event.getCause() -print 'Exiting @ cycle', m5.curTick(), 'because ', exit_cause +Simulation.run(options, root, test_sys) diff --git a/configs/example/se.py b/configs/example/se.py index 2e63e27da..e4fe93294 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -34,6 +34,7 @@ import m5 from m5.objects import * import os, optparse, sys m5.AddToPath('../common') +import Simulation parser = optparse.OptionParser() @@ -47,34 +48,7 @@ parser.add_option("-o", "--options", default="", parser.add_option("-i", "--input", default="", help="A file of input to give to the binary.") -# System options -parser.add_option("-d", "--detailed", action="store_true") -parser.add_option("-t", "--timing", action="store_true") -parser.add_option("--caches", action="store_true") - -# Run duration options -parser.add_option("-m", "--maxtick", type="int") -parser.add_option("--maxtime", type="float") - -#Checkpointing options -###Note that performing checkpointing via python script files will override -###checkpoint instructions built into binaries. -parser.add_option("--take_checkpoints", action="store", type="string", - help=" will take checkpoint at cycle M and every N cycles \ - thereafter") -parser.add_option("--max_checkpoints", action="store", type="int", - help="the maximum number of checkpoints to drop", - default=5) -parser.add_option("--checkpoint_dir", action="store", type="string", - help="Place all checkpoints in this absolute directory") -parser.add_option("-r", "--checkpoint_restore", action="store", type="int", - help="restore from checkpoint ") - -#CPU Switching - default switch model generally goes from a checkpoint -#to a timing simple CPU with caches to warm up, then to detailed CPU for -#data measurement -parser.add_option("-s", "--standard_switch", action="store_true", - help="switch from one cpu mode to another") +execfile("Options.py") (options, args) = parser.parse_args() @@ -82,13 +56,6 @@ if args: print "Error: script doesn't take any positional arguments" sys.exit(1) -class MyCache(BaseCache): - assoc = 2 - block_size = 64 - latency = 1 - mshrs = 10 - tgts_per_mshr = 5 - process = LiveProcess() process.executable = options.cmd process.cmd = options.cmd + " " + options.options @@ -117,159 +84,33 @@ if options.detailed: if options.timing: - cpu = TimingSimpleCPU() + CPUClass = TimingSimpleCPU + test_mem_mode = 'timing' elif options.detailed: - cpu = DerivO3CPU() + CPUClass = DerivO3CPU + test_mem_mode = 'timing' else: - cpu = AtomicSimpleCPU() + CPUClass = AtomicSimpleCPU + test_mem_mode = 'atomic' -cpu.workload = process -cpu.cpu_id = 0 +CPUClass.clock = '2GHz' -system = System(cpu = cpu, +np = options.num_cpus + +system = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)], physmem = PhysicalMemory(range=AddrRange("512MB")), - membus = Bus()) + membus = Bus(), mem_mode = test_mem_mode) + system.physmem.port = system.membus.port -system.cpu.connectMemPorts(system.membus) -system.cpu.mem = system.physmem -system.cpu.clock = '2GHz' -if options.caches and not options.standard_switch: - system.cpu.addPrivateSplitL1Caches(MyCache(size = '32kB'), - MyCache(size = '64kB')) + +for i in xrange(np): + if options.caches and not options.standard_switch: + system.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), + L2Cache(size = '64kB')) + system.cpu[i].connectMemPorts(system.membus) + system.cpu[i].mem = system.physmem + system.cpu[i].workload = process root = Root(system = system) -if options.timing or options.detailed: - root.system.mem_mode = 'timing' - -if options.standard_switch: - switch_cpu = TimingSimpleCPU(defer_registration=True, cpu_id=1) - switch_cpu1 = DerivO3CPU(defer_registration=True, cpu_id=2) - switch_cpu.system = system - switch_cpu1.system = system - switch_cpu.clock = cpu.clock - switch_cpu1.clock = cpu.clock - if options.caches: - switch_cpu.addPrivateSplitL1Caches(MyCache(size = '32kB'), - MyCache(size = '64kB')) - - switch_cpu.workload = process - switch_cpu1.workload = process - switch_cpu.mem = system.physmem - switch_cpu1.mem = system.physmem - switch_cpu.connectMemPorts(system.membus) - root.switch_cpu = switch_cpu - root.switch_cpu1 = switch_cpu1 - switch_cpu_list = [(system.cpu, switch_cpu)] - switch_cpu_list1 = [(switch_cpu, switch_cpu1)] - -# instantiate configuration -m5.instantiate(root) - -if options.checkpoint_dir: - cptdir = options.checkpoint_dir -else: - cptdir = getcwd() - -if options.checkpoint_restore: - from os.path import isdir - from os import listdir, getcwd - import re - - if not isdir(cptdir): - m5.panic("checkpoint dir %s does not exist!" % cptdir) - - dirs = listdir(cptdir) - expr = re.compile('cpt.([0-9]*)') - cpts = [] - for dir in dirs: - match = expr.match(dir) - if match: - cpts.append(match.group(1)) - - cpts.sort(lambda a,b: cmp(long(a), long(b))) - - if options.checkpoint_restore > len(cpts): - m5.panic('Checkpoint %d not found' % options.checkpoint_restore) - - print "restoring checkpoint from ","/".join([cptdir, "cpt.%s" % cpts[options.checkpoint_restore - 1]]) - m5.restoreCheckpoint(root, "/".join([cptdir, "cpt.%s" % cpts[options.checkpoint_restore - 1]])) - -if options.standard_switch: - exit_event = m5.simulate(10000) - ## when you change to Timing (or Atomic), you halt the system given - ## as argument. When you are finished with the system changes - ## (including switchCpus), you must resume the system manually. - ## You DON'T need to resume after just switching CPUs if you haven't - ## changed anything on the system level. - m5.changeToTiming(system) - m5.switchCpus(switch_cpu_list) - m5.resume(system) - - exit_event = m5.simulate(500000000000) - m5.switchCpus(switch_cpu_list1) - -if options.maxtick: - maxtick = options.maxtick -elif options.maxtime: - simtime = int(options.maxtime * root.clock.value) - print "simulating for: ", simtime - maxtick = simtime -else: - maxtick = -1 - -num_checkpoints = 0 - -exit_cause = '' - -if options.take_checkpoints: - [when, period] = options.take_checkpoints.split(",", 1) - when = int(when) - period = int(period) - - exit_event = m5.simulate(when) - while exit_event.getCause() == "checkpoint": - exit_event = m5.simulate(when - m5.curTick()) - - if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - - sim_ticks = when - exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints - while num_checkpoints < options.max_checkpoints: - if (sim_ticks + period) > maxtick and maxtick != -1: - exit_event = m5.simulate(maxtick - sim_ticks) - exit_cause = exit_event.getCause() - break - else: - exit_event = m5.simulate(period) - sim_ticks += period - while exit_event.getCause() == "checkpoint": - exit_event = m5.simulate(period - m5.curTick()) - if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - -else: #no checkpoints being taken via this script - exit_event = m5.simulate(maxtick) - - while exit_event.getCause() == "checkpoint": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - if num_checkpoints == options.max_checkpoints: - exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints - break - - if maxtick == -1: - exit_event = m5.simulate(maxtick) - else: - exit_event = m5.simulate(maxtick - m5.curTick()) - - exit_cause = exit_event.getCause() - -if exit_cause == '': - exit_cause = exit_event.getCause() -print 'Exiting @ cycle', m5.curTick(), 'because ', exit_cause - - +Simulation.run(options, root, system) From 27ef642a763bc6e0c79f0326b4c07018a42205f9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 28 Oct 2006 03:44:55 -0400 Subject: [PATCH 22/40] One last adjustment to get rid of skew in the simple atomic cpu. --HG-- extra : convert_revision : 8e46929ed7da5dae6888f773de4e1ecc9b249fe0 --- src/cpu/simple/atomic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index a72f6361a..11e4d2acb 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -240,7 +240,7 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay) notIdleFraction++; //Make sure ticks are still on multiples of cycles - Tick nextTick = curTick + cycles(1) - 1; + Tick nextTick = curTick + cycles(delay + 1) - 1; nextTick -= (nextTick % (cycles(1))); tickEvent.schedule(nextTick); _status = Running; From 7f1463f94a67e6005a99e315df653bab2f056fa5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 28 Oct 2006 04:00:24 -0400 Subject: [PATCH 23/40] Include the right version of faults.hh --HG-- extra : convert_revision : 4762b8ab46ac755726cc658a378c2cf5b2061dc3 --- src/cpu/ozone/back_end.hh | 2 +- src/cpu/ozone/dyn_inst_impl.hh | 2 +- src/cpu/ozone/front_end_impl.hh | 2 +- src/cpu/ozone/inorder_back_end.hh | 2 +- src/cpu/ozone/inorder_back_end_impl.hh | 2 +- src/cpu/ozone/lw_back_end.hh | 2 +- src/cpu/ozone/thread_state.hh | 2 +- src/cpu/simple/base.cc | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cpu/ozone/back_end.hh b/src/cpu/ozone/back_end.hh index 8debd277d..992f55c6e 100644 --- a/src/cpu/ozone/back_end.hh +++ b/src/cpu/ozone/back_end.hh @@ -35,7 +35,7 @@ #include #include -#include "arch/faults.hh" +#include "sim/faults.hh" #include "base/timebuf.hh" #include "cpu/inst_seq.hh" #include "cpu/ozone/rename_table.hh" diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh index 0a1e1c139..9d42ab05b 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -28,7 +28,7 @@ * Authors: Kevin Lim */ -#include "arch/faults.hh" +#include "sim/faults.hh" #include "config/full_system.hh" #include "cpu/ozone/dyn_inst.hh" #include "kern/kernel_stats.hh" diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 36e87ec9c..60c954517 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -30,7 +30,7 @@ #include "config/use_checker.hh" -#include "arch/faults.hh" +#include "sim/faults.hh" #include "arch/isa_traits.hh" #include "arch/utility.hh" #include "base/statistics.hh" diff --git a/src/cpu/ozone/inorder_back_end.hh b/src/cpu/ozone/inorder_back_end.hh index 76eef6fad..b2522bdc8 100644 --- a/src/cpu/ozone/inorder_back_end.hh +++ b/src/cpu/ozone/inorder_back_end.hh @@ -33,7 +33,7 @@ #include -#include "arch/faults.hh" +#include "sim/faults.hh" #include "base/timebuf.hh" #include "cpu/thread_context.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/ozone/inorder_back_end_impl.hh b/src/cpu/ozone/inorder_back_end_impl.hh index 16ebac163..8aef9c074 100644 --- a/src/cpu/ozone/inorder_back_end_impl.hh +++ b/src/cpu/ozone/inorder_back_end_impl.hh @@ -28,7 +28,7 @@ * Authors: Kevin Lim */ -#include "arch/faults.hh" +#include "sim/faults.hh" #include "arch/types.hh" #include "cpu/ozone/inorder_back_end.hh" #include "cpu/ozone/thread_state.hh" diff --git a/src/cpu/ozone/lw_back_end.hh b/src/cpu/ozone/lw_back_end.hh index 49c6a1ae2..08a6863d0 100644 --- a/src/cpu/ozone/lw_back_end.hh +++ b/src/cpu/ozone/lw_back_end.hh @@ -36,7 +36,7 @@ #include #include -#include "arch/faults.hh" +#include "sim/faults.hh" #include "base/timebuf.hh" #include "cpu/inst_seq.hh" #include "cpu/ozone/rename_table.hh" diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh index c86f3552e..985e09b52 100644 --- a/src/cpu/ozone/thread_state.hh +++ b/src/cpu/ozone/thread_state.hh @@ -31,7 +31,7 @@ #ifndef __CPU_OZONE_THREAD_STATE_HH__ #define __CPU_OZONE_THREAD_STATE_HH__ -#include "arch/faults.hh" +#include "sim/faults.hh" #include "arch/types.hh" #include "arch/regfile.hh" #include "base/callback.hh" diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index cbb3980cb..81e9e6720 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -29,7 +29,7 @@ */ #include "arch/utility.hh" -#include "arch/faults.hh" +#include "sim/faults.hh" #include "base/cprintf.hh" #include "base/inifile.hh" #include "base/loader/symtab.hh" From ab6b6a92022af26d8d26d16928e73d6211c7cd7b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 28 Oct 2006 04:44:05 -0400 Subject: [PATCH 24/40] This one really needs to be arch/faults.hh --HG-- extra : convert_revision : aad1ee04ade9f4394c9ef0386f23d6f2ca373412 --- src/cpu/simple/base.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 81e9e6720..cbb3980cb 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -29,7 +29,7 @@ */ #include "arch/utility.hh" -#include "sim/faults.hh" +#include "arch/faults.hh" #include "base/cprintf.hh" #include "base/inifile.hh" #include "base/loader/symtab.hh" From 14f53b9b6b3d1b417c2c14567e2eee48d7caba9d Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 28 Oct 2006 13:16:53 -0400 Subject: [PATCH 25/40] remove intel nic from SConscript --HG-- extra : convert_revision : b01bb258c97cf42d46a94faedab31726623fe437 --- src/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SConscript b/src/SConscript index 9f88bbeea..28f39bc29 100644 --- a/src/SConscript +++ b/src/SConscript @@ -220,7 +220,6 @@ full_system_sources = Split(''' dev/etherlink.cc dev/etherpkt.cc dev/ethertap.cc - dev/i8254xGBe.cc dev/ide_ctrl.cc dev/ide_disk.cc dev/io_device.cc @@ -253,6 +252,7 @@ full_system_sources = Split(''' sim/pseudo_inst.cc ''') #dev/sinic.cc + #dev/i8254xGBe.cc if env['TARGET_ISA'] == 'alpha': From 6dddca951151c953fdab6f3e57b9385150d8b90b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Oct 2006 01:58:37 -0500 Subject: [PATCH 26/40] Add an integer microcode register. --HG-- extra : convert_revision : f23dbfdfe44e8e6cdd6948000669ad4f743b9fb4 --- src/arch/sparc/intregfile.cc | 19 ++++++++++++++++--- src/arch/sparc/intregfile.hh | 1 + src/arch/sparc/isa/operands.isa | 1 + src/arch/sparc/isa_traits.hh | 8 ++++++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index bef62f6ae..164f194dd 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -75,8 +75,14 @@ IntRegFile::IntRegFile() IntReg IntRegFile::readReg(int intReg) { - IntReg val = - regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; + IntReg val; + if(intReg < NumRegularIntRegs) + val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; + else if((intReg -= NumRegularIntRegs) < NumMicroIntRegs) + val = microRegs[intReg]; + else + panic("Tried to read non-existant integer register\n"); + DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val); return val; } @@ -86,7 +92,12 @@ Fault IntRegFile::setReg(int intReg, const IntReg &val) if(intReg) { DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); - regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; + if(intReg < NumRegularIntRegs) + regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; + else if((intReg -= NumRegularIntRegs) < NumMicroIntRegs) + microRegs[intReg] = val; + else + panic("Tried to set non-existant integer register\n"); } return NoFault; } @@ -123,6 +134,7 @@ void IntRegFile::serialize(std::ostream &os) SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); for(x = 0; x < 2 * NWindows; x++) SERIALIZE_ARRAY(regSegments[x], RegsPerFrame); + SERIALIZE_ARRAY(microRegs, NumMicroIntRegs); } void IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) @@ -132,4 +144,5 @@ void IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); for(unsigned int x = 0; x < 2 * NWindows; x++) UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame); + UNSERIALIZE_ARRAY(microRegs, NumMicroIntRegs); } diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh index d305c753b..223e3b34c 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -65,6 +65,7 @@ namespace SparcISA IntReg regGlobals[MaxGL][RegsPerFrame]; IntReg regSegments[2 * NWindows][RegsPerFrame]; + IntReg microRegs[NumMicroIntRegs]; enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index ba2c38e91..80b499b91 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -61,6 +61,7 @@ def operands {{ 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3), 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4), 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5), + 'uReg0': ('IntReg', 'udw', 'NumRegularIntRegs+0', 'IsInteger', 6), 'Frds': ('FloatReg', 'sf', 'RD', 'IsFloating', 10), 'Frd': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10), # Each Frd_N refers to the Nth double precision register from Frd. diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index fb09121a3..46a0ebbfb 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -57,13 +57,17 @@ namespace SparcISA //This makes sure the big endian versions of certain functions are used. using namespace BigEndianGuest; - // SPARC have a delay slot + // SPARC has a delay slot #define ISA_HAS_DELAY_SLOT 1 // SPARC NOP (sethi %(hi(0), g0) const MachInst NoopMachInst = 0x01000000; - const int NumIntRegs = 32; + const int NumRegularIntRegs = 32; + const int NumMicroIntRegs = 1; + const int NumIntRegs = + NumRegularIntRegs + + NumMicroIntRegs; const int NumFloatRegs = 64; const int NumMiscRegs = 40; From ce313a15d5310aa8ee4412014e129ae26e7d18dc Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Oct 2006 01:59:30 -0500 Subject: [PATCH 27/40] Fixed ldstub to use the right format, and made the load/store operations use the integer microcode register. --HG-- extra : convert_revision : 7df5bd4bbe8a2607c7d2b4799826831d6a440926 --- src/arch/sparc/isa/decoder.isa | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index dc7597e5e..aa3b6de6f 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -851,16 +851,15 @@ decode OP default Unknown::unknown() 0x09: ldsb({{Rd = (int8_t)Mem.sb;}}); 0x0A: ldsh({{Rd = (int16_t)Mem.shw;}}); 0x0B: ldx({{Rd = (int64_t)Mem.sdw;}}); - 0x0D: ldstub({{ - Rd = Mem.ub; - Mem.ub = 0xFF; - }}); } + 0x0D: LoadStore::ldstub( + {{Rd = Mem.ub;}}, + {{Mem.ub = 0xFF;}}); 0x0E: Store::stx({{Mem.udw = Rd}}); 0x0F: LoadStore::swap( - {{*temp = Rd.uw; + {{uReg0 = Rd.uw; Rd.uw = Mem.uw;}}, - {{Mem.uw = *temp;}}); + {{Mem.uw = uReg0;}}); format Load { 0x10: lduwa({{Rd = Mem.uw;}}); 0x11: lduba({{Rd = Mem.ub;}}); @@ -888,9 +887,9 @@ decode OP default Unknown::unknown() {{Mem.ub = 0xFF}}); 0x1E: Store::stxa({{Mem.udw = Rd}}); 0x1F: LoadStore::swapa( - {{*temp = Rd.uw; + {{uReg0 = Rd.uw; Rd.uw = Mem.uw;}}, - {{Mem.uw = *temp;}}); + {{Mem.uw = uReg0;}}); format Trap { 0x20: Load::ldf({{Frd.uw = Mem.uw;}}); 0x21: decode X { From 9adba8d98e0d73a6dcf745258da3ac2272e93a6a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Oct 2006 02:57:32 -0500 Subject: [PATCH 28/40] Bring casa and casxa up to date src/arch/sparc/isa/decoder.isa: Fix up the casa and casxa instructions. src/arch/sparc/isa/formats/formats.isa: This is handled in loadstore.isa now src/arch/sparc/isa/formats/mem/basicmem.isa: src/arch/sparc/isa/formats/mem/blockmem.isa: Renamed doSplitExecute to doDualSplitExecute. This differentiates between the version that does both a register and immediate version, and one that just does a register version. src/arch/sparc/isa/formats/mem/mem.isa: The cas format is handled in loadstore.isa as well now. src/arch/sparc/isa/formats/mem/util.isa: Reorganized things a bit to better support cas --HG-- extra : convert_revision : 12411e89e763287e52f9825bf7a417b263c1037f --- src/arch/sparc/isa/decoder.isa | 22 ++++++------ src/arch/sparc/isa/formats/formats.isa | 3 -- src/arch/sparc/isa/formats/mem/basicmem.isa | 2 +- src/arch/sparc/isa/formats/mem/blockmem.isa | 2 +- src/arch/sparc/isa/formats/mem/mem.isa | 2 +- src/arch/sparc/isa/formats/mem/util.isa | 40 +++++++++++++-------- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index aa3b6de6f..a64ff09bb 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -1072,19 +1072,21 @@ decode OP default Unknown::unknown() {{fault = new DataAccessException;}}); } } - 0x3C: Cas::casa({{ - uint64_t val = Mem.uw; - if(Rs2.uw == val) + 0x3C: Cas::casa( + {{uReg0 = Mem.uw;}}, + {{if(Rs2.uw == uReg0) Mem.uw = Rd.uw; - Rd.uw = val; - }}); + else + storeCond = false; + Rd.uw = uReg0;}}); 0x3D: Nop::prefetcha({{ }}); - 0x3E: Cas::casxa({{ - uint64_t val = Mem.udw; - if(Rs2 == val) + 0x3E: Cas::casxa( + {{uReg0 = Mem.udw;}}, + {{if(Rs2 == uReg0) Mem.udw = Rd; - Rd = val; - }}); + else + storeCond = false; + Rd = uReg0;}}); } } } diff --git a/src/arch/sparc/isa/formats/formats.isa b/src/arch/sparc/isa/formats/formats.isa index 5b81a1ab1..8125e6349 100644 --- a/src/arch/sparc/isa/formats/formats.isa +++ b/src/arch/sparc/isa/formats/formats.isa @@ -42,9 +42,6 @@ //Include the memory formats ##include "mem/mem.isa" -//Include the compare and swap format -##include "cas.isa" - //Include the trap format ##include "trap.isa" diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index c13194d0f..147767bbc 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -156,7 +156,7 @@ let {{ header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm) decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm) decode_block = ROrImmDecode.subst(iop) - exec_output = doSplitExecute(code, addrCalcReg, addrCalcImm, execute, + exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm, execute, faultCode, name, name + "Imm", Name, Name + "Imm", opt_flags) return (header_output, decoder_output, exec_output, decode_block) }}; diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 93ad1b2b8..4f2f30236 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -301,7 +301,7 @@ let {{ "set_flags": flag_code}) decoder_output += BlockMemMicroConstructor.subst(iop) decoder_output += BlockMemMicroConstructor.subst(iop_imm) - exec_output += doSplitExecute( + exec_output += doDualSplitExecute( pcedCode, addrCalcReg, addrCalcImm, execute, faultCode, makeMicroName(name, microPc), makeMicroName(name + "Imm", microPc), diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa index 20a22c45d..fedece2b8 100644 --- a/src/arch/sparc/isa/formats/mem/mem.isa +++ b/src/arch/sparc/isa/formats/mem/mem.isa @@ -41,5 +41,5 @@ //Include the block memory format ##include "blockmem.isa" -//Include the load/store memory format +//Include the load/store and cas memory format ##include "loadstore.isa" diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index 241a25d17..673aee6be 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -102,6 +102,9 @@ def template StoreExecute {{ { Fault fault = NoFault; uint64_t write_result = 0; + //This is to support the conditional store in cas instructions. + //It should be optomized out in all the others + bool storeCond = true; Addr EA; %(op_decl)s; %(op_rd)s; @@ -112,7 +115,7 @@ def template StoreExecute {{ { %(code)s; } - if(fault == NoFault) + if(storeCond && fault == NoFault) { fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); } @@ -130,6 +133,7 @@ def template StoreExecute {{ { Fault fault = NoFault; uint64_t write_result = 0; + bool storeCond = true; Addr EA; %(op_decl)s; %(op_rd)s; @@ -140,7 +144,7 @@ def template StoreExecute {{ { %(code)s; } - if(fault == NoFault) + if(storeCond && fault == NoFault) { fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); } @@ -204,23 +208,29 @@ let {{ //and in the other they're distributed across two. Also note that for //execute functions, the name of the base class doesn't matter. let {{ - def doSplitExecute(code, eaRegCode, eaImmCode, execute, + def doSplitExecute(code, eaCode, execute, + faultCode, name, Name, opt_flags): + codeIop = InstObjParams(name, Name, '', code, opt_flags) + eaIop = InstObjParams(name, Name, '', eaCode, + opt_flags, {"fault_check": faultCode}) + iop = InstObjParams(name, Name, '', code, opt_flags, + {"fault_check": faultCode, "ea_code" : eaCode}) + (iop.ea_decl, + iop.ea_rd, + iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb) + (iop.code_decl, + iop.code_rd, + iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb) + return execute.subst(iop) + + + def doDualSplitExecute(code, eaRegCode, eaImmCode, execute, faultCode, nameReg, nameImm, NameReg, NameImm, opt_flags): - codeIop = InstObjParams(nameReg, NameReg, '', code, opt_flags) executeCode = '' for (eaCode, name, Name) in ( (eaRegCode, nameReg, NameReg), (eaImmCode, nameImm, NameImm)): - eaIop = InstObjParams(name, Name, '', eaCode, - opt_flags, {"fault_check": faultCode}) - iop = InstObjParams(name, Name, '', code, opt_flags, - {"fault_check": faultCode, "ea_code" : eaCode}) - (iop.ea_decl, - iop.ea_rd, - iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb) - (iop.code_decl, - iop.code_rd, - iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb) - executeCode += execute.subst(iop) + executeCode += doSplitExecute(code, eaCode, + execute, faultCode, name, Name, opt_flags) return executeCode }}; From 6e66de7c7563ef7e969a0df4a9a09d026231baa5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Oct 2006 03:26:41 -0500 Subject: [PATCH 29/40] Fix when the IsDelayedCommit flag is set. --HG-- extra : convert_revision : ab6cd69f82b2013d66a91beaa3e39d8f417a9251 --- src/arch/sparc/isa/formats/mem/blockmem.isa | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 4f2f30236..8b4aca473 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -56,14 +56,14 @@ output header {{ {} }; - class BlockMemMicro : public SparcDelayedMicroInst + class BlockMemMicro : public SparcMicroInst { protected: // Constructor BlockMemMicro(const char *mnem, ExtMachInst _machInst, OpClass __opClass, int8_t _offset) : - SparcDelayedMicroInst(mnem, _machInst, __opClass), + SparcMicroInst(mnem, _machInst, __opClass), offset(_offset) {} @@ -290,6 +290,8 @@ let {{ flag_code = '' if (microPc == 7): flag_code = "flags[IsLastMicroOp] = true;" + else: + flag_code = "flags[IsDelayedCommit] = true;" pcedCode = matcher.sub("Frd_%d" % microPc, code) iop = InstObjParams(name, Name, 'BlockMem', pcedCode, opt_flags, {"ea_code": addrCalcReg, From 349c7aff9b1a4643f8501d4b5cd7eff8753dfac9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Oct 2006 03:40:52 -0500 Subject: [PATCH 30/40] Move the mem classes into util.isa so that multiple inheritance can be used in the future for micro insts. --HG-- extra : convert_revision : c71faa5e43b56ed15d00ed5fd57c020d1c845445 --- src/arch/sparc/isa/formats/mem/basicmem.isa | 94 --------------------- src/arch/sparc/isa/formats/mem/util.isa | 94 +++++++++++++++++++++ 2 files changed, 94 insertions(+), 94 deletions(-) diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index 147767bbc..cb6c2f161 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -32,100 +32,6 @@ // Mem instructions // -output header {{ - /** - * Base class for memory operations. - */ - class Mem : public SparcStaticInst - { - protected: - - // Constructor - Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : - SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - }; - - /** - * Class for memory operations which use an immediate offset. - */ - class MemImm : public Mem - { - protected: - - // Constructor - MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : - Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) - {} - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - - const int32_t imm; - }; -}}; - -output decoder {{ - std::string Mem::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream response; - bool load = flags[IsLoad]; - bool save = flags[IsStore]; - - printMnemonic(response, mnemonic); - if(save) - { - printReg(response, _srcRegIdx[0]); - ccprintf(response, ", "); - } - ccprintf(response, "[ "); - printReg(response, _srcRegIdx[!save ? 0 : 1]); - ccprintf(response, " + "); - printReg(response, _srcRegIdx[!save ? 1 : 2]); - ccprintf(response, " ]"); - if(load) - { - ccprintf(response, ", "); - printReg(response, _destRegIdx[0]); - } - - return response.str(); - } - - std::string MemImm::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream response; - bool load = flags[IsLoad]; - bool save = flags[IsStore]; - - printMnemonic(response, mnemonic); - if(save) - { - printReg(response, _srcRegIdx[0]); - ccprintf(response, ", "); - } - ccprintf(response, "[ "); - printReg(response, _srcRegIdx[!save ? 0 : 1]); - if(imm >= 0) - ccprintf(response, " + 0x%x ]", imm); - else - ccprintf(response, " + -0x%x ]", -imm); - if(load) - { - ccprintf(response, ", "); - printReg(response, _destRegIdx[0]); - } - - return response.str(); - } -}}; - def template MemDeclare {{ /** * Static instruction class for "%(mnemonic)s". diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index 673aee6be..b9f7fde2d 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -33,6 +33,100 @@ // Mem utility templates and functions // +output header {{ + /** + * Base class for memory operations. + */ + class Mem : public SparcStaticInst + { + protected: + + // Constructor + Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; + + /** + * Class for memory operations which use an immediate offset. + */ + class MemImm : public Mem + { + protected: + + // Constructor + MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : + Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) + {} + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + const int32_t imm; + }; +}}; + +output decoder {{ + std::string Mem::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + bool load = flags[IsLoad]; + bool save = flags[IsStore]; + + printMnemonic(response, mnemonic); + if(save) + { + printReg(response, _srcRegIdx[0]); + ccprintf(response, ", "); + } + ccprintf(response, "[ "); + printReg(response, _srcRegIdx[!save ? 0 : 1]); + ccprintf(response, " + "); + printReg(response, _srcRegIdx[!save ? 1 : 2]); + ccprintf(response, " ]"); + if(load) + { + ccprintf(response, ", "); + printReg(response, _destRegIdx[0]); + } + + return response.str(); + } + + std::string MemImm::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + bool load = flags[IsLoad]; + bool save = flags[IsStore]; + + printMnemonic(response, mnemonic); + if(save) + { + printReg(response, _srcRegIdx[0]); + ccprintf(response, ", "); + } + ccprintf(response, "[ "); + printReg(response, _srcRegIdx[!save ? 0 : 1]); + if(imm >= 0) + ccprintf(response, " + 0x%x ]", imm); + else + ccprintf(response, " + -0x%x ]", -imm); + if(load) + { + ccprintf(response, ", "); + printReg(response, _destRegIdx[0]); + } + + return response.str(); + } +}}; + //This template provides the execute functions for a load def template LoadExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, From 628a3b1d01702d1e3888c40c4a02c38c636ae6d4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Oct 2006 04:04:50 -0500 Subject: [PATCH 31/40] An attempt to serialize the state of the micro code mechanism in the simple cpu. src/cpu/simple/base.cc: Make a microcoded op start at the current micropc, rather than starting at 0. src/cpu/thread_state.cc: Serialize the microPC and nextMicroPC --HG-- extra : convert_revision : 5302215f17312ecef3ff4c6548acb05297ee4ff6 --- src/cpu/simple/base.cc | 6 ++++-- src/cpu/thread_state.cc | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index cbb3980cb..253d33243 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -401,13 +401,15 @@ BaseSimpleCPU::preExecute() StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); if (instPtr->isMacroOp()) { curMacroStaticInst = instPtr; - curStaticInst = curMacroStaticInst->fetchMicroOp(0); + curStaticInst = curMacroStaticInst-> + fetchMicroOp(thread->readMicroPC()); } else { curStaticInst = instPtr; } } else { //Read the next micro op from the macro op - curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPC()); + curStaticInst = curMacroStaticInst-> + fetchMicroOp(thread->readMicroPC()); } diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index c644ae8d7..e6ebcc525 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -62,6 +62,8 @@ ThreadState::serialize(std::ostream &os) // thread_num and cpu_id are deterministic from the config SERIALIZE_SCALAR(funcExeInst); SERIALIZE_SCALAR(inst); + SERIALIZE_SCALAR(microPC); + SERIALIZE_SCALAR(nextMicroPC); #if FULL_SYSTEM Tick quiesceEndTick = 0; @@ -81,6 +83,8 @@ ThreadState::unserialize(Checkpoint *cp, const std::string §ion) // thread_num and cpu_id are deterministic from the config UNSERIALIZE_SCALAR(funcExeInst); UNSERIALIZE_SCALAR(inst); + UNSERIALIZE_SCALAR(microPC); + UNSERIALIZE_SCALAR(nextMicroPC); #if FULL_SYSTEM Tick quiesceEndTick; From b40af2328a254b109a08327475bb8f2aa906399b Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 30 Oct 2006 13:33:27 -0500 Subject: [PATCH 32/40] add some comments and make the warmup period in a switchover parameterizable. configs/common/Options.py: make the warmup period in a standard switch part of the option. configs/common/Simulation.py: add some comments and also make the warmup period an option. --HG-- extra : convert_revision : 0fa587291b97ff87c3b3a617e7359ac6d9bed7a5 --- configs/common/Options.py | 5 +++-- configs/common/Simulation.py | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/configs/common/Options.py b/configs/common/Options.py index d9c1cc64e..d89023082 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -53,5 +53,6 @@ parser.add_option("-r", "--checkpoint_restore", action="store", type="int", # CPU Switching - default switch model goes from a checkpoint # to a timing simple CPU with caches to warm up, then to detailed CPU for # data measurement -parser.add_option("-s", "--standard_switch", action="store_true", - help="switch from one cpu mode to another") +parser.add_option("-s", "--standard_switch", action="store", type="int", + help="switch from timing CPU to Detailed CPU after a period of \ + cycles warmup", default=5000000000) diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index b927315ba..59cf32303 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -116,12 +116,15 @@ def run(options, root, testsys): m5.switchCpus(switch_cpu_list) m5.resume(testsys) - exit_event = m5.simulate(3000000) + exit_event = m5.simulate(options.standard_switch) m5.switchCpus(switch_cpu_list1) num_checkpoints = 0 exit_cause = '' + ## Checkpoints being taken via the command line at and at subsequent + ## periods of . Checkpoint instructions received from the benchmark running + ## are ignored and skipped in favor of command line checkpoint instructions. if options.take_checkpoints: [when, period] = options.take_checkpoints.split(",", 1) when = int(when) From bc93802fb8f65656c09cfb96f2e4c2febe0e569f Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Mon, 30 Oct 2006 14:01:34 -0500 Subject: [PATCH 33/40] Use some python os.path stuff to make it more flexible where we can execute this script from. --HG-- extra : convert_revision : a76861a0f2669a7cd3bf3a34177739c69a913545 --- configs/example/fs.py | 7 +++++-- configs/example/se.py | 9 +++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/configs/example/fs.py b/configs/example/fs.py index ec3be835a..aefa26169 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -39,6 +39,10 @@ import Simulation if not m5.build_env['FULL_SYSTEM']: m5.panic("This script requires full-system mode (ALPHA_FS).") +# Get paths we might need. It's expected this file is in m5/configs/example. +config_path = os.path.dirname(os.path.abspath(__file__)) +config_root = os.path.dirname(config_path) + parser = optparse.OptionParser() # Benchmark options @@ -54,8 +58,7 @@ parser.add_option("--etherdump", action="store", type="string", dest="etherdump" help="Specify the filename to dump a pcap capture of the" \ "ethernet traffic") - -execfile("Options.py") +execfile(os.path.join(config_root, "common", "Options.py")) (options, args) = parser.parse_args() diff --git a/configs/example/se.py b/configs/example/se.py index e4fe93294..1afeaf391 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -36,11 +36,16 @@ import os, optparse, sys m5.AddToPath('../common') import Simulation +# Get paths we might need. It's expected this file is in m5/configs/example. +config_path = os.path.dirname(os.path.abspath(__file__)) +config_root = os.path.dirname(config_path) +m5_root = os.path.dirname(config_root) + parser = optparse.OptionParser() # Benchmark options parser.add_option("-c", "--cmd", - default="../../tests/test-progs/hello/bin/alpha/linux/hello", + default=os.path.join(m5_root, "tests/test-progs/hello/bin/alpha/linux/hello"), help="The binary to run in syscall emulation mode.") parser.add_option("-o", "--options", default="", help="The options to pass to the binary, use \" \" around the entire\ @@ -48,7 +53,7 @@ parser.add_option("-o", "--options", default="", parser.add_option("-i", "--input", default="", help="A file of input to give to the binary.") -execfile("Options.py") +execfile(os.path.join(config_root, "common", "Options.py")) (options, args) = parser.parse_args() From 883f0394f5eefea6fb541229564dcb8543d020fd Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 30 Oct 2006 14:12:15 -0500 Subject: [PATCH 34/40] decouple the switch option from the warmup period option - parsing was confused otherwise, oops. --HG-- extra : convert_revision : 951fc664c59363df5f5e026aa791d83c26f050ec --- configs/common/Options.py | 8 +++++--- configs/common/Simulation.py | 3 +-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/configs/common/Options.py b/configs/common/Options.py index d89023082..69f48dc3b 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -53,6 +53,8 @@ parser.add_option("-r", "--checkpoint_restore", action="store", type="int", # CPU Switching - default switch model goes from a checkpoint # to a timing simple CPU with caches to warm up, then to detailed CPU for # data measurement -parser.add_option("-s", "--standard_switch", action="store", type="int", - help="switch from timing CPU to Detailed CPU after a period of \ - cycles warmup", default=5000000000) +parser.add_option("-s", "--standard_switch", action="store_true", + help="switch from timing CPU to Detailed CPU") +parser.add_option("-w", "--warmup", action="store", type="int", + help="if -s, then this is the warmup period. else, this is ignored", + default=5000000000) diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index 59cf32303..899a291fc 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -116,7 +116,7 @@ def run(options, root, testsys): m5.switchCpus(switch_cpu_list) m5.resume(testsys) - exit_event = m5.simulate(options.standard_switch) + exit_event = m5.simulate(options.warmup) m5.switchCpus(switch_cpu_list1) num_checkpoints = 0 @@ -130,7 +130,6 @@ def run(options, root, testsys): when = int(when) period = int(period) - print "when is ", when, " period is ", period exit_event = m5.simulate(when) while exit_event.getCause() == "checkpoint": exit_event = m5.simulate(when - m5.curTick()) From fe2698c435ef8f37273e60f1cc7d70b95b4aa3d5 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 30 Oct 2006 14:19:16 -0500 Subject: [PATCH 35/40] ensure that there is a "/" between the cptdir and the cpt.%d. --HG-- extra : convert_revision : 9aed7c3aecad10b039f3cfb26e04a7950be6bed1 --- configs/common/Simulation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index 899a291fc..a2d045a5e 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -135,7 +135,7 @@ def run(options, root, testsys): exit_event = m5.simulate(when - m5.curTick()) if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") + m5.checkpoint(root, "/".join([cptdir,"cpt.%d"])) num_checkpoints += 1 sim_ticks = when @@ -151,14 +151,14 @@ def run(options, root, testsys): while exit_event.getCause() == "checkpoint": exit_event = m5.simulate(sim_ticks - m5.curTick()) if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") + m5.checkpoint(root, "/".join([cptdir,"cpt.%d"])) num_checkpoints += 1 else: #no checkpoints being taken via this script exit_event = m5.simulate(maxtick) while exit_event.getCause() == "checkpoint": - m5.checkpoint(root, cptdir + "cpt.%d") + m5.checkpoint(root, "/".join([cptdir,"cpt.%d"])) num_checkpoints += 1 if num_checkpoints == max_checkpoints: exit_cause = "maximum %d checkpoints dropped" % max_checkpoints From 580c8421ab5d438ea4264a3a44495568a38bc59b Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 30 Oct 2006 16:51:46 -0500 Subject: [PATCH 36/40] se.py, fs.py: import Caches Simulation.py: Fix typo - L2Cache --> L1Cache configs/common/Simulation.py: Fix typo - L2Cache --> L1Cache configs/example/fs.py: configs/example/se.py: import Caches --HG-- extra : convert_revision : 4292225b322c069665262eab7c83b5341844fba0 --- configs/common/FSConfig.py | 3 ++- configs/common/Simulation.py | 2 +- configs/example/fs.py | 3 ++- configs/example/se.py | 7 ++++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index 05888b10b..7ba1b001c 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -72,7 +72,8 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None): self.mem_mode = mem_mode self.sim_console = SimConsole(listener=ConsoleListener(port=3456)) self.kernel = binary('vmlinux') - self.pal = binary('ts_osfpal') +## self.pal = binary('ts_osfpal') + self.pal = '/z/hsul/work/m5/alpha-system/palcode/ts_osfpal' self.console = binary('console') self.boot_osflags = 'root=/dev/hda1 console=ttyS0' diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index a2d045a5e..5e9c1d339 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -30,7 +30,7 @@ from os import getcwd import m5 from m5.objects import * m5.AddToPath('../common') -from Caches import * +from Caches import L1Cache def run(options, root, testsys): if options.maxtick: diff --git a/configs/example/fs.py b/configs/example/fs.py index aefa26169..3ce463879 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -35,6 +35,7 @@ from FSConfig import * from SysPaths import * from Benchmarks import * import Simulation +from Caches import * if not m5.build_env['FULL_SYSTEM']: m5.panic("This script requires full-system mode (ALPHA_FS).") @@ -104,7 +105,7 @@ test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)] for i in xrange(np): if options.caches and not options.standard_switch: test_sys.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), - L2Cache(size = '64kB')) + L1Cache(size = '64kB')) test_sys.cpu[i].connectMemPorts(test_sys.membus) test_sys.cpu[i].mem = test_sys.physmem diff --git a/configs/example/se.py b/configs/example/se.py index 1afeaf391..83c2b1f8d 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -35,11 +35,16 @@ from m5.objects import * import os, optparse, sys m5.AddToPath('../common') import Simulation +from Caches import * # Get paths we might need. It's expected this file is in m5/configs/example. config_path = os.path.dirname(os.path.abspath(__file__)) config_root = os.path.dirname(config_path) m5_root = os.path.dirname(config_root) +print m5_root +print config_path +print config_root + parser = optparse.OptionParser() @@ -111,7 +116,7 @@ system.physmem.port = system.membus.port for i in xrange(np): if options.caches and not options.standard_switch: system.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), - L2Cache(size = '64kB')) + L1Cache(size = '64kB')) system.cpu[i].connectMemPorts(system.membus) system.cpu[i].mem = system.physmem system.cpu[i].workload = process From 697b432ba8103d4e05368194989636406d5b85d9 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 30 Oct 2006 16:55:52 -0500 Subject: [PATCH 37/40] FSConfig.py: Accidentally committed this last time configs/common/FSConfig.py: Accidentally committed this last time --HG-- extra : convert_revision : 32d49c17c661b57a9aa9c3b057258f6e037ba745 --- configs/common/FSConfig.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index 7ba1b001c..05888b10b 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -72,8 +72,7 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None): self.mem_mode = mem_mode self.sim_console = SimConsole(listener=ConsoleListener(port=3456)) self.kernel = binary('vmlinux') -## self.pal = binary('ts_osfpal') - self.pal = '/z/hsul/work/m5/alpha-system/palcode/ts_osfpal' + self.pal = binary('ts_osfpal') self.console = binary('console') self.boot_osflags = 'root=/dev/hda1 console=ttyS0' From c68f7feaa8bcecaf28f4110fc98b5d57bc755061 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 31 Oct 2006 13:23:17 -0500 Subject: [PATCH 39/40] add the ability to insert into the middle of the timing port send list --HG-- extra : convert_revision : 5422025f74ba7013f98d1d1dcbd1070f580aae61 --- src/mem/tport.cc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/mem/tport.cc b/src/mem/tport.cc index b9d5cbe4a..086d91279 100644 --- a/src/mem/tport.cc +++ b/src/mem/tport.cc @@ -44,6 +44,7 @@ SimpleTimingPort::recvFunctional(PacketPtr pkt) if (target->intersect(pkt)) done = fixPacket(pkt, target); + i++; } //Then just do an atomic access and throw away the returned latency @@ -98,11 +99,29 @@ SimpleTimingPort::recvRetry() void SimpleTimingPort::sendTiming(PacketPtr pkt, Tick time) { + // Nothing is on the list: add it and schedule an event if (transmitList.empty()) { assert(!sendEvent.scheduled()); sendEvent.schedule(curTick+time); + transmitList.push_back(std::pair(time+curTick,pkt)); + return; + } + + // something is on the list and this belongs at the end + if (time+curTick >= transmitList.back().first) { + transmitList.push_back(std::pair(time+curTick,pkt)); + return; + } + // Something is on the list and this belongs somewhere else + std::list >::iterator i = transmitList.begin(); + std::list >::iterator end = transmitList.end(); + bool done = false; + + while (i != end && !done) { + if (time+curTick < i->first) + transmitList.insert(i,std::pair(time+curTick,pkt)); + i++; } - transmitList.push_back(std::pair(time+curTick,pkt)); } void From 17141a1be9c656d2bba77e8853dd3d4cbce01beb Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 31 Oct 2006 13:23:49 -0500 Subject: [PATCH 40/40] remove connectAll() and connect() code since it isn't used anymore. (The python does it all) --HG-- extra : convert_revision : e16a1ff59d4522703b155c2e68379a3072e8f47f --- src/sim/sim_object.cc | 20 -------------------- src/sim/sim_object.hh | 2 -- 2 files changed, 22 deletions(-) diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc index d12b06b7a..8fc8fe58f 100644 --- a/src/sim/sim_object.cc +++ b/src/sim/sim_object.cc @@ -91,11 +91,6 @@ SimObject::SimObject(const string &_name) state = Running; } -void -SimObject::connect() -{ -} - void SimObject::init() { @@ -159,21 +154,6 @@ SimObject::regAllStats() Stats::registerResetCallback(&StatResetCB); } -// -// static function: call connect() on all SimObjects. -// -void -SimObject::connectAll() -{ - SimObjectList::iterator i = simObjectList.begin(); - SimObjectList::iterator end = simObjectList.end(); - - for (; i != end; ++i) { - SimObject *obj = *i; - obj->connect(); - } -} - // // static function: call init() on all SimObjects. // diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index 32807b69d..93802e247 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -101,9 +101,7 @@ class SimObject : public Serializable, protected StartupCallback // initialization pass of all objects. // Gets invoked after construction, before unserialize. virtual void init(); - virtual void connect(); static void initAll(); - static void connectAll(); // register statistics for this object virtual void regStats();