00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef MEMORY_H
00016 #define MEMORY_H
00017
00018 #include "global.h"
00019
00020 #include <queue>
00021 #include "specMem.h"
00022 #include "fe_debug.h"
00023
00024
00025
00026
00027
00028 class memory_interface {
00029 #if 0 // WANT_CHECKPOINT_SUPPORT
00030 BOOST_SERIALIZE {
00031 }
00032 #endif
00033 public:
00034 typedef enum {FULL=1, EMPTY=0} mState;
00035 virtual ~memory_interface() {;}
00036
00037 virtual uint8_t ReadMemory8(const simAddress, const bool)=0;
00038
00039 virtual uint16_t ReadMemory16(const simAddress, const bool)=0;
00040
00041 virtual uint32_t ReadMemory32(const simAddress, const bool)=0;
00042
00043 virtual uint64_t ReadMemory64(const simAddress, const bool)=0;
00044
00045 virtual bool WriteMemory8(const simAddress, const uint8_t, const bool)=0;
00046
00047 virtual bool WriteMemory16(const simAddress, const uint16_t, const bool)=0;
00048
00049 virtual bool WriteMemory32(const simAddress, const uint32_t, const bool)=0;
00050
00051 virtual bool WriteMemory64(const simAddress, const uint64_t, const bool)=0;
00052
00053 virtual mState getFE(const simAddress)=0;
00054
00055 virtual void setFE(const simAddress, const mState FEValue)=0;
00056
00057 virtual void squashSpec()=0;
00058 };
00059 class base_memory;
00060
00061 struct MemMapEntry {
00062 #if 0 // WANT_CHECKPOINT_SUPPORT
00063 BOOST_SERIALIZE {
00064 ar & BOOST_SERIALIZATION_NVP(mem);
00065 ar & BOOST_SERIALIZATION_NVP(addr);
00066 ar & BOOST_SERIALIZATION_NVP(len);
00067 ar & BOOST_SERIALIZATION_NVP(offset);
00068 ar & BOOST_SERIALIZATION_NVP(writeLat);
00069 }
00070 #endif
00071 memory_interface* mem;
00072 simAddress addr;
00073 int len;
00074 simAddress offset;
00075 int writeLat;
00076
00077 };
00078
00079 typedef std::map<simAddress,MemMapEntry> MemMapByAddr;
00080
00081 enum { ReadOp=1, WriteOp };
00082 enum { Size8, Size16, Size32, Size64 };
00083
00084 #define OpSize( op ) ( op >> 16 )
00085 #define OpType( op ) ( op & 0xffff )
00086
00087 class MemAccess {
00088 friend class MemAccess_compare;
00089
00090 public:
00091
00092 static unsigned long counter;
00093
00094 unsigned long long when;
00095 unsigned long number;
00096 simAddress addr;
00097 uint32_t value;
00098 bool spec;
00099 int size;
00100 MemMapEntry *foo;
00101
00102 MemAccess( unsigned long long _when,
00103 simAddress _addr,
00104 uint32_t _value,
00105 bool _spec,
00106 int _size,
00107 MemMapEntry *_foo ) {
00108 when = _when;
00109 addr = _addr;
00110 value = _value;
00111 spec = _spec;
00112 size = _size;
00113 foo = _foo;
00114 number = counter++;
00115 }
00116 };
00117
00118 class MemAccess_compare {
00119 public:
00120 bool operator()(const MemAccess* x, const MemAccess* y) const
00121 {
00122 if ( x->when > y->when ) return true;
00123
00124 if ( x->when == y->when && x->number > y->number ) return true;
00125
00126 return false;
00127 }
00128 };
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 class base_memory : public memory_interface
00139 {
00140 #if 0 //WANT_CHECKPOINT_SUPPORT
00141 BOOST_SERIALIZE {
00142 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( memory_interface );
00143 ar & BOOST_SERIALIZATION_NVP(defaultFEB);
00144 ar & BOOST_SERIALIZATION_NVP(PageArray);
00145 ar & BOOST_SERIALIZATION_NVP(FEArray);
00146 ar & BOOST_SERIALIZATION_NVP(PageSize);
00147 ar & BOOST_SERIALIZATION_NVP(PageShift);
00148 ar & BOOST_SERIALIZATION_NVP(PageMask);
00149 ar & BOOST_SERIALIZATION_NVP(sizeP);
00150 ar & BOOST_SERIALIZATION_NVP(numPagesP);
00151 ar & BOOST_SERIALIZATION_NVP(identP);
00152
00153
00154
00155
00156
00157
00158 ar & BOOST_SERIALIZATION_NVP(memMapByAddr);
00159 }
00160 #endif
00161 static mState defaultFEB;
00162
00163
00164
00165
00166
00167 vector<vector<uint8_t>* > PageArray;
00168
00169
00170
00171 vector<vector<uint8_t>* > FEArray;
00172
00173 uint32_t PageSize;
00174
00175 uint32_t PageShift;
00176
00177 uint32_t PageMask;
00178 inline uint8_t *GetPage (const simAddress sa);
00179 inline uint8_t *GetFEPage(const simAddress);
00180 specMemory specMem;
00181
00182 inline void readFileBackPage( const simAddress pageAddr, uint8_t *bufAddr, int size );
00183 inline void writeFileBackPage( const simAddress pageAddr, uint8_t *bufAddr, int size );
00184
00185 ulong sizeP;
00186 uint numPagesP;
00187 uint identP;
00188 int fdP;
00189 char backingFileNameP[FILENAME_MAX];
00190 uint32_t *backingBitsP;
00191 uint8_t *filePageBufP;
00192 simAddress filePageAddrP;
00193 bool gupsP;
00194
00195 MemMapByAddr memMapByAddr;
00196
00197 MemMapEntry* FindMemByAddr( simAddress addr);
00198 priority_queue<MemAccess*,vector<MemAccess*>,MemAccess_compare> memWrite;
00199
00200
00201
00202
00203
00204 public:
00205 base_memory(ulong size = 0x80000000 ,
00206 uint pageSize = 0x4000 , uint ident = 0);
00207 static uint8_t getDefaultFEB() { return defaultFEB; }
00208
00209
00210
00211
00212
00213
00214 virtual ~base_memory() {;}
00215 uint8_t _ReadMemory8(const simAddress, const bool);
00216 uint16_t _ReadMemory16(const simAddress, const bool);
00217 uint32_t _ReadMemory32(const simAddress, const bool);
00218 uint64_t _ReadMemory64(const simAddress, const bool);
00219 bool _WriteMemory8(const simAddress, const uint8_t, const bool);
00220 bool _WriteMemory16(const simAddress, const uint16_t, const bool);
00221 bool _WriteMemory32(const simAddress, const uint32_t, const bool);
00222 bool _WriteMemory64(const simAddress, const uint64_t, const bool);
00223 virtual mState getFE(const simAddress);
00224 virtual void setFE(const simAddress, const mState FEValue);
00225 virtual void squashSpec() {specMem.squashSpec();}
00226 void clearMemory();
00227 bool hasPage(const simAddress);
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 bool LoadMem( const simAddress dest, void* const source, int Bytes);
00239
00240
00241 #define REDIRECT_READ_FUNC_GET(S) \
00242 virtual uint##S ReadMemory##S(const simAddress sa, \
00243 const bool spec) \
00244 { \
00245 return _ReadMemory##S(sa,spec); \
00246 }
00247
00248 #define REDIRECT_WRITE_FUNC_GET(S) \
00249 virtual bool WriteMemory##S(const simAddress sa, \
00250 const uint##S Data, const bool spec) \
00251 { \
00252 return _WriteMemory##S(sa,Data,spec); \
00253 }
00254
00255 #define SST_DELAY(S) \
00256 bool delayWriteMemory##S( MemMapEntry *tmp, \
00257 const simAddress sa, const uint##S Data, const bool spec) \
00258 { \
00259 simAddress addr = tmp->offset + (sa - tmp->addr); \
00260 \
00261 DPRINT(V1,"sa=%#x new-addr=%#x value=%x\n",(uint)sa,(uint)addr,(int)Data); \
00262 \
00263 bool ret = tmp->mem->WriteMemory##S( addr, Data, spec ); \
00264 if ( tmp->comp ) { \
00265 WriteNotify( tmp->comp, addr, Size##S ); \
00266 } \
00267 return ret; \
00268 }
00269
00270 REDIRECT_READ_FUNC_GET(8)
00271 REDIRECT_READ_FUNC_GET(16)
00272 REDIRECT_READ_FUNC_GET(32)
00273 REDIRECT_READ_FUNC_GET(64)
00274
00275 REDIRECT_WRITE_FUNC_GET(8)
00276 REDIRECT_WRITE_FUNC_GET(16)
00277 REDIRECT_WRITE_FUNC_GET(32)
00278 REDIRECT_WRITE_FUNC_GET(64)
00279
00280
00281
00282
00283 #undef DELAY
00284
00285 void setup();
00286 void finish();
00287 void preTic();
00288
00289 };
00290
00291 typedef enum {
00292 GlobalTextMem = 1,
00293 GlobalDataMem = 2,
00294 LocalDynamic = 3,
00295 GlobalDynamic = 4,
00296 AddressError = 0,
00297 MemTypes = 5
00298 } memoryAccType;
00299
00300 #include "mallocSysCall.h"
00301
00302
00303
00304
00305
00306
00307
00308 class memory : public memory_interface {
00309 #if 0 // WANT_CHECKPOINT_SUPPORT
00310 BOOST_SERIALIZE {
00311 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( memory_interface );
00312 ar & BOOST_SERIALIZATION_NVP(myMem);
00313
00314
00315
00316
00317 ar & BOOST_SERIALIZATION_NVP(madeMemory);
00318 }
00319 #endif
00320 base_memory *myMem;
00321 static vmRegionAlloc globalDynamic;
00322 static localRegionAlloc localDynamic;
00323
00324 public:
00325 static simAddress segRange[MemTypes][2];
00326 static const char *segName[MemTypes];
00327
00328 bool madeMemory;
00329
00330 base_memory *getBaseMem() {return myMem;}
00331
00332
00333
00334
00335 memory() : myMem(new base_memory()), madeMemory(1) {}
00336 memory(base_memory *bm) : myMem(bm), madeMemory(0) {
00337 if (bm == NULL) {
00338 myMem = new base_memory();
00339 madeMemory = 1;
00340 }
00341 }
00342
00343 virtual ~memory() {
00344 if (myMem && madeMemory) {
00345 delete myMem;
00346 }
00347 }
00348 virtual int finish() {
00349 myMem->finish();
00350 return 0;
00351 }
00352
00353 static memoryAccType getAccType(simAddress sa);
00354
00355 virtual mState getFE(const simAddress sa) {return myMem->getFE(sa);}
00356 virtual void setFE(const simAddress sa, const mState FEValue) {
00357 myMem->setFE(sa, FEValue);
00358 }
00359 virtual void squashSpec() {myMem->squashSpec();}
00360
00361 virtual uint8_t ReadMemory8(const simAddress sa, const bool s);
00362 virtual bool WriteMemory8(const simAddress sa, const uint8_t d, const bool s);
00363 virtual uint16_t ReadMemory16(const simAddress sa, const bool s);
00364 virtual bool WriteMemory16(const simAddress sa, const uint16_t d, const bool s);
00365 virtual uint32_t ReadMemory32(const simAddress sa, const bool s);
00366 virtual bool WriteMemory32(const simAddress sa, const uint32_t d, const bool s);
00367 virtual uint64_t ReadMemory64(const simAddress sa, const bool s);
00368 virtual bool WriteMemory64(const simAddress sa, const uint64_t d, const bool s);
00369
00370 static simAddress globalAllocate (unsigned int size);
00371 static simAddress localAllocateNearAddr (unsigned int size, simAddress addr);
00372 static simAddress localAllocateAtID (unsigned int size, unsigned int ID);
00373 static unsigned int memFree(simAddress addr, unsigned int size);
00374
00375 static void setUpLocalDistribution ( uint hashShift, uint locCount) {
00376 localDynamic.setup(hashShift, locCount);
00377 }
00378 static void addLocalID (processor *p, uint locID) {
00379 localDynamic.addLoc(p, locID);
00380 }
00381 static int getLocalID (processor *p) {
00382 return localDynamic.getLoc(p);
00383 }
00384 static int whichLoc (simAddress sa) {
00385 return localDynamic.whichLoc(sa);
00386 }
00387 static uint maxLocalChunk() {
00388 return localDynamic.stride();
00389 }
00390 static uint numLocales() {
00391 return localDynamic.locs();
00392 }
00393 static simAddress addrOnLoc (uint i) {
00394 return localDynamic.addrOnLoc(i);
00395 }
00396 };
00397
00398 #endif