/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2011 Regents of the University of California
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* Authors: Steve Reinhardt
* Lisa Hsu
* Nathan Binkert
+ * Rick Strong
*/
#ifndef __SYSTEM_HH__
#include "base/loader/symtab.hh"
#include "base/misc.hh"
#include "base/statistics.hh"
+#include "config/full_system.hh"
#include "cpu/pc_event.hh"
+#include "enums/MemoryMode.hh"
#include "mem/port.hh"
+#include "params/System.hh"
#include "sim/sim_object.hh"
+
#if FULL_SYSTEM
#include "kern/system_events.hh"
-#include "mem/vport.hh"
#endif
class BaseCPU;
#if FULL_SYSTEM
class Platform;
-class GDBListener;
-class RemoteGDB;
+class FunctionalPort;
+class VirtualPort;
#endif
+class GDBListener;
+class BaseRemoteGDB;
class System : public SimObject
{
public:
- enum MemoryMode {
- Invalid=0,
- Atomic,
- Timing
- };
+ static const char *MemoryModeStrings[3];
- MemoryMode getMemoryMode() { assert(memoryMode); return memoryMode; }
+ Enums::MemoryMode
+ getMemoryMode()
+ {
+ assert(memoryMode);
+ return memoryMode;
+ }
/** Change the memory mode of the system. This should only be called by the
* python!!
* @param mode Mode to change to (atomic/timing)
*/
- void setMemoryMode(MemoryMode mode);
+ void setMemoryMode(Enums::MemoryMode mode);
PhysicalMemory *physmem;
PCEventQueue pcEventQueue;
std::vector<ThreadContext *> threadContexts;
- int numcpus;
+ int _numContexts;
- int getNumCPUs()
+ ThreadContext *getThreadContext(ThreadID tid)
{
- if (numcpus != threadContexts.size())
- panic("cpu array not fully populated!");
+ return threadContexts[tid];
+ }
- return numcpus;
+ int numContexts()
+ {
+ assert(_numContexts == (int)threadContexts.size());
+ return _numContexts;
}
+ /** Return number of running (non-halted) thread contexts in
+ * system. These threads could be Active or Suspended. */
+ int numRunningContexts();
+
+ /** List to store ranges of memories in this system */
+ AddrRangeList memRanges;
+
+ /** check if an address points to valid system memory
+ * and thus we can fetch instructions out of it
+ */
+ bool isMemory(const Addr addr) const;
+
#if FULL_SYSTEM
Platform *platform;
uint64_t init_param;
/** Port to physical memory used for writing object files into ram at
* boot.*/
- FunctionalPort functionalPort;
- VirtualPort virtPort;
+ FunctionalPort *functionalPort;
+ VirtualPort *virtPort;
/** kernel symbol table */
SymbolTable *kernelSymtab;
/** Entry point in the kernel to start at */
Addr kernelEntry;
+ /** Mask that should be anded for binary/symbol loading.
+ * This allows one two different OS requirements for the same ISA to be
+ * handled. Some OSes are compiled for a virtual address and need to be
+ * loaded into physical memory that starts at address 0, while other
+ * bare metal tools generate images that start at address 0.
+ */
+ Addr loadAddrMask;
+
#else
- int page_ptr;
+ Addr pagePtr;
+
+ protected:
+ uint64_t nextPID;
+
+ public:
+ uint64_t allocatePID()
+ {
+ return nextPID++;
+ }
+
+ /** Amount of physical memory that is still free */
+ Addr freeMemSize();
+
+ /** Amount of physical memory that exists */
+ Addr memSize();
#endif // FULL_SYSTEM
protected:
+ Enums::MemoryMode memoryMode;
+ uint64_t workItemsBegin;
+ uint64_t workItemsEnd;
+ uint32_t numWorkIds;
+ std::vector<bool> activeCpus;
- MemoryMode memoryMode;
+ public:
+ virtual void regStats();
+ /**
+ * Called by pseudo_inst to track the number of work items started by this
+ * system.
+ */
+ uint64_t
+ incWorkItemsBegin()
+ {
+ return ++workItemsBegin;
+ }
+
+ /**
+ * Called by pseudo_inst to track the number of work items completed by
+ * this system.
+ */
+ uint64_t
+ incWorkItemsEnd()
+ {
+ return ++workItemsEnd;
+ }
+
+ /**
+ * Called by pseudo_inst to mark the cpus actively executing work items.
+ * Returns the total number of cpus that have executed work item begin or
+ * ends.
+ */
+ int
+ markWorkItem(int index)
+ {
+ int count = 0;
+ assert(index < activeCpus.size());
+ activeCpus[index] = true;
+ for (std::vector<bool>::iterator i = activeCpus.begin();
+ i < activeCpus.end(); i++) {
+ if (*i) count++;
+ }
+ return count;
+ }
+
+ inline void workItemBegin(uint32_t tid, uint32_t workid)
+ {
+ std::pair<uint32_t,uint32_t> p(tid, workid);
+ lastWorkItemStarted[p] = curTick();
+ }
+
+ void workItemEnd(uint32_t tid, uint32_t workid);
#if FULL_SYSTEM
/**
* up in the specified symbol table.
*/
template <class T>
- T *System::addFuncEvent(SymbolTable *symtab, const char *lbl)
+ T *addFuncEvent(SymbolTable *symtab, const char *lbl)
{
Addr addr = 0; // initialize only to avoid compiler warning
/** Add a function-based event to kernel code. */
template <class T>
- T *System::addKernelFuncEvent(const char *lbl)
+ T *addKernelFuncEvent(const char *lbl)
{
return addFuncEvent<T>(kernelSymtab, lbl);
}
#endif
public:
-#if FULL_SYSTEM
- std::vector<RemoteGDB *> remoteGDB;
+ std::vector<BaseRemoteGDB *> remoteGDB;
std::vector<GDBListener *> gdbListen;
- virtual bool breakpoint() = 0;
-#endif // FULL_SYSTEM
+ bool breakpoint();
public:
- struct Params
- {
- std::string name;
- PhysicalMemory *physmem;
-
-#if FULL_SYSTEM
- Tick boot_cpu_frequency;
- std::string boot_osflags;
- uint64_t init_param;
-
- std::string kernel_path;
- std::string readfile;
-#endif
- };
+ typedef SystemParams Params;
protected:
Params *_params;
System(Params *p);
~System();
- void startup();
+ void initState();
const Params *params() const { return (const Params *)_params; }
#else
- Addr new_page();
+ /// Allocate npages contiguous unused physical pages
+ /// @return Starting address of first page
+ Addr allocPhysPages(int npages);
#endif // FULL_SYSTEM
- int registerThreadContext(ThreadContext *tc, int tcIndex);
- void replaceThreadContext(ThreadContext *tc, int tcIndex);
+ int registerThreadContext(ThreadContext *tc, int assigned=-1);
+ void replaceThreadContext(ThreadContext *tc, int context_id);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string §ion);
+ virtual void resume();
public:
+ Counter totalNumInsts;
+ EventQueue instEventQueue;
+ std::map<std::pair<uint32_t,uint32_t>, Tick> lastWorkItemStarted;
+ std::map<uint32_t, Stats::Histogram*> workItemStats;
+
////////////////////////////////////////////
//
// STATIC GLOBAL SYSTEM LIST