TARGET_ISA = 'alpha'
FULL_SYSTEM = 1
-CPU_MODELS = 'AtomicSimpleCPU,TimingSimpleCPU,O3CPU'
+CPU_MODELS = 'AtomicSimpleCPU,TimingSimpleCPU,O3CPU,InOrderCPU'
PROTOCOL = 'MI_example'
cpu->resPool->trap(fault, tid, inst);
break;
+#if !FULL_SYSTEM
case Syscall:
cpu->syscall(inst->syscallNum, tid);
cpu->resPool->trap(fault, tid, inst);
break;
-
+#endif
default:
fatal("Unrecognized Event Type %s", eventNames[cpuEventType]);
}
stCondFails(0),
#if FULL_SYSTEM
system(params->system),
- physmem(system->physmem),
#endif // FULL_SYSTEM
#ifdef DEBUG
cpuEventNum(0),
resReqCount(0),
#endif // DEBUG
- switchCount(0),
+ drainCount(0),
deferRegistration(false/*params->deferRegistration*/),
stageTracing(params->stageTracing),
lastRunningCycle(0),
tc->cpu = this;
tc->thread = thread[tid];
+#if FULL_SYSTEM
+ // Setup quiesce event.
+ this->thread[tid]->quiesceEvent = new EndQuiesceEvent(tc);
+#endif
+
// Give the thread the TC.
thread[tid]->tc = tc;
thread[tid]->setFuncExeInst(0);
lastRunningCycle = curTick();
- // Reset CPU to reset state.
-#if FULL_SYSTEM
- Fault resetFault = new ResetFault();
- resetFault->invoke(tcBase());
-#endif
-
+ lockAddr = 0;
+ lockFlag = false;
// Schedule First Tick Event, CPU will reschedule itself from here on out.
scheduleTickEvent(0);
Fault
InOrderCPU::hwrei(ThreadID tid)
{
- panic("hwrei: Unimplemented");
+#if THE_ISA == ALPHA_ISA
+ // Need to clear the lock flag upon returning from an interrupt.
+ setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, false, tid);
+
+ thread[tid]->kernelStats->hwrei();
+ // FIXME: XXX check for interrupts? XXX
+#endif
return NoFault;
}
bool
InOrderCPU::simPalCheck(int palFunc, ThreadID tid)
{
- panic("simPalCheck: Unimplemented");
+#if THE_ISA == ALPHA_ISA
+ if (this->thread[tid]->kernelStats)
+ this->thread[tid]->kernelStats->callpal(palFunc,
+ this->threadContexts[tid]);
+
+ switch (palFunc) {
+ case PAL::halt:
+ halt();
+ if (--System::numSystemsRunning == 0)
+ exitSimLoop("all cpus halted");
+ break;
+ case PAL::bpt:
+ case PAL::bugchk:
+ if (this->system->breakpoint())
+ return false;
+ break;
+ }
+#endif
return true;
}
}
#if FULL_SYSTEM
-
+// Lots of copied full system code...place into BaseCPU class?
void
InOrderCPU::wakeup()
{
#if FULL_SYSTEM
/** Pointer to the system. */
System *system;
-
- /** Pointer to physical memory. */
- PhysicalMemory *physmem;
#endif
/** The global sequence number counter. */
unsigned resReqCount;
#endif
- /** Counter of how many stages have completed switching out. */
- int switchCount;
+ Addr lockAddr;
+
+ /** Temporary fix for the lock flag, works in the UP case. */
+ bool lockFlag;
+
+ /** Counter of how many stages have completed draining */
+ int drainCount;
/** Pointers to all of the threads in the CPU. */
std::vector<Thread *> thread;
#include "arch/faults.hh"
#include "base/bigint.hh"
+#include "base/cp_annotate.hh"
#include "base/cprintf.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
Fault
InOrderDynInst::hwrei()
{
- panic("InOrderDynInst: hwrei: unimplemented\n");
+#if THE_ISA == ALPHA_ISA
+ // Can only do a hwrei when in pal mode.
+ if (!(this->instAddr() & 0x3))
+ return new AlphaISA::UnimplementedOpcodeFault;
+
+ // Set the next PC based on the value of the EXC_ADDR IPR.
+ AlphaISA::PCState pc = this->pcState();
+ pc.npc(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
+ this->threadNumber));
+ this->pcState(pc);
+ if (CPA::available()) {
+ ThreadContext *tc = this->cpu->tcBase(this->threadNumber);
+ CPA::cpa()->swAutoBegin(tc, this->nextInstAddr());
+ }
+
+ // Tell CPU to clear any state it needs to if a hwrei is taken.
+ this->cpu->hwrei(this->threadNumber);
+#endif
return NoFault;
}
InOrderThreadContext::regStats(const std::string &name)
{
#if FULL_SYSTEM
- //thread->kernelStats = new Kernel::Statistics(cpu->system);
- //thread->kernelStats->regStats(name + ".kern");
+ thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system);
+ thread->kernelStats->regStats(name + ".kern");
#endif
;
}
#include "cpu/inorder/thread_state.hh"
#include "cpu/exetrace.hh"
#include "cpu/thread_context.hh"
+#include "arch/kernel_stats.hh"
+
+class EndQuiesceEvent;
+namespace Kernel {
+ class Statistics;
+};
class TranslatingPort;
'tsunami-simple-atomic-dual',
'tsunami-simple-timing-dual',
'twosys-tsunami-simple-atomic',
- 'tsunami-o3', 'tsunami-o3-dual']
+ 'tsunami-o3', 'tsunami-o3-dual',
+ 'tsunami-inorder']
if env['TARGET_ISA'] == 'sparc':
configs += ['t1000-simple-atomic',
't1000-simple-timing']
--- /dev/null
+# Copyright (c) 2006-2007 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: Steve Reinhardt
+
+import m5
+from m5.objects import *
+m5.util.addToPath('../configs/common')
+import FSConfig
+
+
+# --------------------
+# Base L1 Cache
+# ====================
+
+class L1(BaseCache):
+ latency = '1ns'
+ block_size = 64
+ mshrs = 4
+ tgts_per_mshr = 8
+ is_top_level = True
+
+# ----------------------
+# Base L2 Cache
+# ----------------------
+
+class L2(BaseCache):
+ block_size = 64
+ latency = '10ns'
+ mshrs = 92
+ tgts_per_mshr = 16
+ write_buffers = 8
+
+# ---------------------
+# I/O Cache
+# ---------------------
+class IOCache(BaseCache):
+ assoc = 8
+ block_size = 64
+ latency = '50ns'
+ mshrs = 20
+ size = '1kB'
+ tgts_per_mshr = 12
+ addr_range=AddrRange(0, size='8GB')
+ forward_snoops = False
+ is_top_level = True
+
+#cpu
+cpu = InOrderCPU(cpu_id=0)
+cpu.stageWidth = 4
+cpu.fetchBuffSize = 1
+
+#the system
+system = FSConfig.makeLinuxAlphaSystem('timing')
+
+system.cpu = cpu
+#create the l1/l2 bus
+system.toL2Bus = Bus()
+system.bridge.filter_ranges_a=[AddrRange(0, Addr.max)]
+system.bridge.filter_ranges_b=[AddrRange(0, size='8GB')]
+system.iocache = IOCache()
+system.iocache.cpu_side = system.iobus.port
+system.iocache.mem_side = system.membus.port
+
+
+#connect up the l2 cache
+system.l2c = L2(size='4MB', assoc=8)
+system.l2c.cpu_side = system.toL2Bus.port
+system.l2c.mem_side = system.membus.port
+
+#connect up the cpu and l1s
+cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1),
+ L1(size = '32kB', assoc = 4))
+# connect cpu level-1 caches to shared level-2 cache
+cpu.connectAllPorts(system.toL2Bus, system.membus)
+cpu.clock = '2GHz'
+
+root = Root(system=system)
+m5.ticks.setGlobalFrequency('1THz')
+