• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/genericProc/FE/processor.h

00001 // Copyright 2010 Sandia Corporation. Under the terms
00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
00003 // Government retains certain rights in this software.
00004 // 
00005 // Copyright (c) 2005-2010, Sandia Corporation
00006 // All rights reserved.
00007 // Copyright (c) 2003-2005, University of Notre Dame
00008 // All rights reserved.
00009 // 
00010 // This file is part of the SST software package. For license
00011 // information, see the LICENSE file in the top level directory of the
00012 // distribution.
00013 
00014 
00015 #ifndef PROCESSOR_H
00016 #define PROCESSOR_H
00017 
00018 #include "sst_stdint.h" // for uint*_t
00019 #include "sst/core/component.h"
00020 #include <sst/core/cpunicEvent.h>
00021 #include "thread.h"
00022 #include "memory.h"
00023 #include "ptoVMapper.h"
00024 #include "pimSysCallTypes.h"
00025 #include <vector>
00026 #include <utility>
00027 #include <sst_config.h>
00028 #include <boost/serialization/list.hpp>
00029 
00030 
00031 #if HAVE_PHXSIM_H
00032 #include <../PHXSimC/PHXEvent.h>
00033 #endif
00034 
00035 using namespace std;
00036 using namespace SST;
00037 
00038 typedef SST::Component* (*ownerCheckFunc)(const simAddress, const simPID);
00039 
00040 //: An inapropriately named structure with home site startup info
00041 struct procPIDPair {
00042   //: The processor
00043   processor *first;
00044   //: Its PID
00045   simPID second;
00046   //: binary to load
00047   //
00048   // empty string is for the main binary. Otherwise, the binary name
00049   // will be the config string ":frontEnd:<binaryName>".
00050   string binaryName;
00051   //: constructor
00052   procPIDPair(processor *p, simPID pid) : first(p), second(pid), 
00053                                           binaryName("") {;}
00054   procPIDPair(processor *p, simPID pid, const string b) : first(p), second(pid),
00055                                                  binaryName(b) {;}
00056 };
00057 typedef vector<procPIDPair> procStartVec;
00058 typedef procStartVec (*getFirstThreadsHomeFunc)(string cfgstr);
00059 
00060 //: Generic processing component
00061 //!SEC:Framework
00062 class processor : public SST::Component, public memory,  public ptoVmapper
00063 {
00064 #if 0 // WANT_CHECKPOINT_SUPPORT
00065   BOOST_SERIALIZE {
00066     BOOST_VOID_CAST_REGISTER(processor*,Component*);
00067     ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( Component );
00068     ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( memory );
00069     ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( ptoVmapper );
00070     ar & BOOST_SERIALIZATION_NVP(myProcNum);
00071     ar & BOOST_SERIALIZATION_NVP(myCoreNum);
00072     ar & BOOST_SERIALIZATION_NVP(numCores);
00073   }
00074 #endif
00075   //static vector<memory_interface*> fullCopies;
00076   //static vector<processor*> procs;
00077 protected:
00078   int currentRunningCore;
00079 private:
00080 
00081   volatile bool nic_response;
00082 
00083 
00084   //WCUnit *_wcUnit;
00085 public:
00086    virtual int Setup( ) { return 0; }
00087    virtual int finish( ) { return memory::finish(); }
00088 
00089   //: request a memory be fully loaded
00090   //
00091   // This requests that a memory object recieve a full copy of memory
00092   // when it is loaded. Useful for ensuring that processors have
00093   // copies of globals for printing and such.
00094   //static void requestFullMemCopy(memory_interface *m) {fullCopies.push_back(m);}
00095 public:
00096   void procExit() {
00097     unregisterExit();
00098   }
00099 
00100   //:Initilize a processor.
00101   // Assigns the processor a unique ID.
00102   //processor(int name, base_memory *baseM, int coreNum = 0) : 
00103   processor(ComponentId_t id, Params_t& params) : 
00104     Component( id  ), memory(0),
00105     currentRunningCore(-1)
00106   {
00107     setUpLocalDistribution(12, 1); // kbw: this is a total hack, but then, so's the previous line
00108     nic_response= false;
00109     INFO("Processor at %p initialized\n", this);
00110   }
00111 
00112   //WCUnit* wcUnit() {return _wcUnit;}
00113 
00114   //static ownerCheckFunc whereIs;
00115   //static getFirstThreadsHomeFunc FirstThreadsHome;
00116   //static void init(string cfgstr);
00117   procStartVec getFirstThreadsHomes();
00118   bool CopyToSIM(simAddress dest, const simPID, void* source, const unsigned int Bytes);
00119   bool LoadToSIM(simAddress dest, const simPID, void* source, const unsigned int Bytes);
00120   bool CopyFromSIM(void* dest, const simAddress source, const simPID, const unsigned int Bytes);
00121   //: Return processor's unique id - hardcoded since we can't do multi-processor yet
00122   int getProcNum() const {return 1;}
00123   //: Return processor's core num
00124   int getCoreNum() const {return getCurrentRunningCore();}
00125   //: Return num of cores
00126   virtual int getNumCores() const = 0;
00127   int getCurrentRunningCore() const {return currentRunningCore;}
00128   //: Request a frame for a thread
00129   //
00130   // A thread can request a frame from a processor of words
00131   // words. This frame is private to the thread and is generally used
00132   // to contain registers. The thread is responsible for returning the
00133   // thread when it is done with it.
00134   //
00135   // The frame is identified by a frameID which can be used to
00136   // retrieve and access the frame.
00137   //virtual frameID requestFrame(int words)=0;
00138   //: Return a frame for reuse
00139   //
00140   // Deallocate a frame.
00141   //virtual void returnFrame(frameID)=0;
00142   //: Access a frame
00143   //
00144   // Takes a frame ID and returns a pointer to that frame. 
00145   //virtual simRegister* getFrame(frameID)=0;
00146   //: Insert a new thread into the processor
00147   //
00148   // When a new thread is created, it must be inserted into a
00149   // processor.
00150   virtual bool insertThread(thread*)=0;
00151   //: Check the locality of an address
00152   //
00153   // Checks if a given address is local to the processor.
00154   virtual bool isLocal(const simAddress, const simPID)=0;
00155   //: Spawn a thread to a Coprocessor
00156   //
00157   // Take the thread t, and send it to a coProcessor. 
00158   virtual bool spawnToCoProc(const PIM_coProc, thread* t, simRegister hint)=0;
00159   //: Switch Addressing mode
00160   //
00161   // A processor may have multiple addressing modes. If so, this is
00162   // used to switch between them.
00163   virtual bool switchAddrMode(PIM_addrMode) = 0;
00164   //: Write special registers
00165   //
00166   // A number of special commands or functions are accessible by
00167   // "writing" special registers. 
00168   virtual exceptType writeSpecial(const PIM_cmd, const int nargs, 
00169                                   const uint *args)=0;
00170   //: Read special registers
00171   //
00172   // A number of special commands or functions are accessible by
00173   // "reading" special registers. Reading may return sereral results.
00174   virtual exceptType readSpecial(const PIM_cmd cmd, const int nInArgs, 
00175                                  const int nOutArgs, const simRegister *args,
00176                                  simRegister *rets) {
00177     exceptType retval = PROC_EXCEPTION;
00178     switch( cmd ) {
00179       case PIM_CMD_GET_NUM_CORE:
00180         rets[0] = ntohl(getNumCores());
00181         retval = NO_EXCEPTION;
00182         break;
00183       case PIM_CMD_GET_CORE_NUM:
00184         rets[0] = ntohl(getCoreNum());
00185         retval = NO_EXCEPTION;
00186         break;
00187       case PIM_CMD_GET_MHZ:
00188         //rets[0] = ClockMhz();
00189         retval = NO_EXCEPTION;
00190         break;
00191     default:
00192       ;
00193     }
00194     return retval;
00195   };
00196 
00197   //: Reset internal counters
00198   //
00199   // reset internal accounting meters (IPC, inst committed, etc...)
00200   virtual void resetCounters() {
00201     printf("Reset Counters Not Supported on this Processor.\n");
00202   }
00203 
00204   //: Arg Checking Utility function
00205   //
00206   //Checks num of args to specials
00207   static inline void checkNumArgs(const PIM_cmd cmd, const int givenInArgs, 
00208                                   const int givenOutArgs, 
00209                                   const int reqInArgs, const int reqOutArgs) {
00210     if (givenInArgs != reqInArgs) {
00211       printf("Syscall %d does not have %d Input arguments. (%d given)\n", cmd, 
00212              reqInArgs, givenInArgs);
00213     }
00214     if (givenOutArgs != reqOutArgs) {
00215       printf("Syscall %d does not have %d Output arguments. (%d given)\n", cmd, 
00216              reqOutArgs, givenOutArgs);
00217     }
00218   }
00219 
00220   // We use this function to forward netsim calls to the netsim NIC
00221   virtual bool forwardToNetsimNIC(int call_num, char *params,
00222                                     const size_t params_length,
00223                                     char *buf, const size_t buf_len) = 0;
00224 
00225   // This function returns data the NIC may have sent back to the CPU
00226   virtual bool pickupNetsimNIC(CPUNicEvent **event) = 0;
00227 
00228   // These functions are used to manage the queue of NIC replies
00229   std::list<CPUNicEvent *> staging_area;
00230 
00231   int getNICresponse(void) {return !staging_area.empty();}
00232 
00233   virtual bool externalMemoryModel() = 0;
00234   //:send a (load/store) request to memory
00235   virtual bool sendMemoryReq( instType, uint64_t address,
00236                                instruction *inst, int mProcID) = 0;
00237   virtual int getOutstandingAdvancedMemReqs(int mProcID, int *max) = 0;
00238 #if HAVE_PHXSIM_H
00239   //: send a non-load/store request to memory (e.g. AMO)
00240   //
00241   // Note: this function will have to change format at some point to
00242   // accomodate other L2 in-mem ops
00243   virtual bool sendMemoryParcel(uint64_t address, instruction *inst, 
00244                                 PHXEvent *pe,
00245                                 int mProcID) = 0;
00246 #endif
00247     
00248   void addNICevent(CPUNicEvent *e) {
00249     staging_area.push_back(e);
00250   }
00251 
00252   CPUNicEvent *getNICevent(void) {
00253     CPUNicEvent *rc;
00254 
00255     rc= staging_area.front();
00256     staging_area.pop_front();
00257     return rc;
00258   }
00259 
00260 
00261 
00262   virtual void dataCacheInvalidate( simAddress addr ) {WARN("not implemented\n");};
00263 
00264 #define CPU_MEM_FUNC_GEN(S)                                             \
00265   virtual uint##S##_t ReadMemory##S(const simAddress sa, const bool s) {        \
00266     return memory::ReadMemory##S( getPhysAddr(sa), s);                  \
00267   }                                                                     \
00268     virtual bool WriteMemory##S(const simAddress sa, const uint##S##_t d,       \
00269                                 const bool s) {                         \
00270       return memory::WriteMemory##S( getPhysAddr(sa), d, s);            \
00271     } 
00272   
00273   CPU_MEM_FUNC_GEN(8)
00274   CPU_MEM_FUNC_GEN(16)
00275   CPU_MEM_FUNC_GEN(32)
00276   CPU_MEM_FUNC_GEN(64)
00277 
00278 };
00279 
00280 #endif

Generated on Fri Oct 22 2010 11:02:16 for SST by  doxygen 1.7.1