92c5a5c8cb
configs/common/FSConfig.py: seperate the hypervisor memory and the guest0 memory. In reality we're going to need a better way to do this at some point. Perhaps auto generating the hv-desc image based on the specified config. src/arch/sparc/isa/decoder.isa: change reads/writes to the [hs]tick(cmpr) registers to use readmiscregwitheffect src/arch/sparc/miscregfile.cc: For niagra stick and tick are aliased to one value (if we end up doing mps we might not want this). Use instruction count from cpu rather than cycles because that is what legion does we can change it back after were done with legion src/base/bitfield.hh: add a new function mbits() that just masks off bits of interest but doesn't shift src/cpu/base.cc: src/cpu/base.hh: add instruction count to cpu src/cpu/exetrace.cc: src/cpu/m5legion_interface.h: compare instruction count between legion and m5 too src/cpu/simple/atomic.cc: change asserts of packet success to if panics wrapped with NDEBUG defines so we can get some more useful information when we have a bad address src/dev/isa_fake.cc: src/dev/isa_fake.hh: src/python/m5/objects/Device.py: expand isa fake a bit more having data for each size request, the ability to have writes update the data and to warn on accesses src/python/m5/objects/System.py: convert some tabs to spaces src/python/m5/objects/T1000.py: add more fake devices for each l1 bank and each memory controller --HG-- extra : convert_revision : 8024ae07b765a04ff6f600e5875b55d8a7d3d276
281 lines
7.9 KiB
C++
281 lines
7.9 KiB
C++
/*
|
|
* Copyright (c) 2002-2005 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
|
|
* Nathan Binkert
|
|
*/
|
|
|
|
#ifndef __CPU_BASE_HH__
|
|
#define __CPU_BASE_HH__
|
|
|
|
#include <vector>
|
|
|
|
#include "base/statistics.hh"
|
|
#include "config/full_system.hh"
|
|
#include "sim/eventq.hh"
|
|
#include "mem/mem_object.hh"
|
|
#include "arch/isa_traits.hh"
|
|
|
|
#if FULL_SYSTEM
|
|
#include "arch/interrupts.hh"
|
|
#endif
|
|
|
|
class BranchPred;
|
|
class CheckerCPU;
|
|
class ThreadContext;
|
|
class System;
|
|
class Port;
|
|
|
|
class CPUProgressEvent : public Event
|
|
{
|
|
protected:
|
|
Tick interval;
|
|
Counter lastNumInst;
|
|
BaseCPU *cpu;
|
|
|
|
public:
|
|
CPUProgressEvent(EventQueue *q, Tick ival, BaseCPU *_cpu);
|
|
|
|
void process();
|
|
|
|
virtual const char *description();
|
|
};
|
|
|
|
class BaseCPU : public MemObject
|
|
{
|
|
protected:
|
|
// CPU's clock period in terms of the number of ticks of curTime.
|
|
Tick clock;
|
|
// @todo remove me after debugging with legion done
|
|
Tick instCnt;
|
|
|
|
public:
|
|
// Tick currentTick;
|
|
inline Tick frequency() const { return Clock::Frequency / clock; }
|
|
inline Tick cycles(int numCycles) const { return clock * numCycles; }
|
|
inline Tick curCycle() const { return curTick / clock; }
|
|
// @todo remove me after debugging with legion done
|
|
Tick instCount() { return instCnt; }
|
|
|
|
/** The next cycle the CPU should be scheduled, given a cache
|
|
* access or quiesce event returning on this cycle. This function
|
|
* may return curTick if the CPU should run on the current cycle.
|
|
*/
|
|
Tick nextCycle();
|
|
|
|
/** The next cycle the CPU should be scheduled, given a cache
|
|
* access or quiesce event returning on the given Tick. This
|
|
* function may return curTick if the CPU should run on the
|
|
* current cycle.
|
|
* @param begin_tick The tick that the event is completing on.
|
|
*/
|
|
Tick nextCycle(Tick begin_tick);
|
|
|
|
#if FULL_SYSTEM
|
|
protected:
|
|
// uint64_t interrupts[TheISA::NumInterruptLevels];
|
|
// uint64_t intstatus;
|
|
TheISA::Interrupts interrupts;
|
|
|
|
public:
|
|
virtual void post_interrupt(int int_num, int index);
|
|
virtual void clear_interrupt(int int_num, int index);
|
|
virtual void clear_interrupts();
|
|
bool checkInterrupts;
|
|
|
|
bool check_interrupts(ThreadContext * tc) const
|
|
{ return interrupts.check_interrupts(tc); }
|
|
|
|
class ProfileEvent : public Event
|
|
{
|
|
private:
|
|
BaseCPU *cpu;
|
|
int interval;
|
|
|
|
public:
|
|
ProfileEvent(BaseCPU *cpu, int interval);
|
|
void process();
|
|
};
|
|
ProfileEvent *profileEvent;
|
|
#endif
|
|
|
|
protected:
|
|
std::vector<ThreadContext *> threadContexts;
|
|
|
|
public:
|
|
|
|
/// Notify the CPU that the indicated context is now active. The
|
|
/// delay parameter indicates the number of ticks to wait before
|
|
/// executing (typically 0 or 1).
|
|
virtual void activateContext(int thread_num, int delay) {}
|
|
|
|
/// Notify the CPU that the indicated context is now suspended.
|
|
virtual void suspendContext(int thread_num) {}
|
|
|
|
/// Notify the CPU that the indicated context is now deallocated.
|
|
virtual void deallocateContext(int thread_num) {}
|
|
|
|
/// Notify the CPU that the indicated context is now halted.
|
|
virtual void haltContext(int thread_num) {}
|
|
|
|
public:
|
|
struct Params
|
|
{
|
|
std::string name;
|
|
int numberOfThreads;
|
|
bool deferRegistration;
|
|
Counter max_insts_any_thread;
|
|
Counter max_insts_all_threads;
|
|
Counter max_loads_any_thread;
|
|
Counter max_loads_all_threads;
|
|
Tick clock;
|
|
bool functionTrace;
|
|
Tick functionTraceStart;
|
|
System *system;
|
|
int cpu_id;
|
|
Tick phase;
|
|
#if FULL_SYSTEM
|
|
Tick profile;
|
|
|
|
bool do_statistics_insts;
|
|
bool do_checkpoint_insts;
|
|
bool do_quiesce;
|
|
#endif
|
|
Tick progress_interval;
|
|
BaseCPU *checker;
|
|
|
|
Params();
|
|
};
|
|
|
|
const Params *params;
|
|
|
|
BaseCPU(Params *params);
|
|
virtual ~BaseCPU();
|
|
|
|
virtual void init();
|
|
virtual void startup();
|
|
virtual void regStats();
|
|
|
|
virtual void activateWhenReady(int tid) {};
|
|
|
|
void registerThreadContexts();
|
|
|
|
/// Prepare for another CPU to take over execution. When it is
|
|
/// is ready (drained pipe) it signals the sampler.
|
|
virtual void switchOut();
|
|
|
|
/// Take over execution from the given CPU. Used for warm-up and
|
|
/// sampling.
|
|
virtual void takeOverFrom(BaseCPU *);
|
|
|
|
/**
|
|
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
|
|
* This is a constant for the duration of the simulation.
|
|
*/
|
|
int number_of_threads;
|
|
|
|
/**
|
|
* Vector of per-thread instruction-based event queues. Used for
|
|
* scheduling events based on number of instructions committed by
|
|
* a particular thread.
|
|
*/
|
|
EventQueue **comInstEventQueue;
|
|
|
|
/**
|
|
* Vector of per-thread load-based event queues. Used for
|
|
* scheduling events based on number of loads committed by
|
|
*a particular thread.
|
|
*/
|
|
EventQueue **comLoadEventQueue;
|
|
|
|
System *system;
|
|
|
|
Tick phase;
|
|
|
|
#if FULL_SYSTEM
|
|
/**
|
|
* Serialize this object to the given output stream.
|
|
* @param os The stream to serialize to.
|
|
*/
|
|
virtual void serialize(std::ostream &os);
|
|
|
|
/**
|
|
* Reconstruct the state of this object from a checkpoint.
|
|
* @param cp The checkpoint use.
|
|
* @param section The section name of this object
|
|
*/
|
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
|
|
|
#endif
|
|
|
|
/**
|
|
* Return pointer to CPU's branch predictor (NULL if none).
|
|
* @return Branch predictor pointer.
|
|
*/
|
|
virtual BranchPred *getBranchPred() { return NULL; };
|
|
|
|
virtual Counter totalInstructions() const { return 0; }
|
|
|
|
// Function tracing
|
|
private:
|
|
bool functionTracingEnabled;
|
|
std::ostream *functionTraceStream;
|
|
Addr currentFunctionStart;
|
|
Addr currentFunctionEnd;
|
|
Tick functionEntryTick;
|
|
void enableFunctionTrace();
|
|
void traceFunctionsInternal(Addr pc);
|
|
|
|
protected:
|
|
void traceFunctions(Addr pc)
|
|
{
|
|
if (functionTracingEnabled)
|
|
traceFunctionsInternal(pc);
|
|
}
|
|
|
|
private:
|
|
static std::vector<BaseCPU *> cpuList; //!< Static global cpu list
|
|
|
|
public:
|
|
static int numSimulatedCPUs() { return cpuList.size(); }
|
|
static Counter numSimulatedInstructions()
|
|
{
|
|
Counter total = 0;
|
|
|
|
int size = cpuList.size();
|
|
for (int i = 0; i < size; ++i)
|
|
total += cpuList[i]->totalInstructions();
|
|
|
|
return total;
|
|
}
|
|
|
|
public:
|
|
// Number of CPU cycles simulated
|
|
Stats::Scalar<> numCycles;
|
|
};
|
|
|
|
#endif // __CPU_BASE_HH__
|