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 WANT_CHECKPOINT_SUPPORT
00030 BOOST_SERIALIZE {
00031 ;
00032 }
00033 #endif
00034 public:
00035 virtual ~memory_interface() {;}
00036
00037 virtual uint8 ReadMemory8(const simAddress, const bool)=0;
00038
00039 virtual uint16 ReadMemory16(const simAddress, const bool)=0;
00040
00041 virtual uint32 ReadMemory32(const simAddress, const bool)=0;
00042
00043 virtual uint64 ReadMemory64(const simAddress, const bool)=0;
00044
00045 virtual bool WriteMemory8(const simAddress, const uint8, const bool)=0;
00046
00047 virtual bool WriteMemory16(const simAddress, const uint16, const bool)=0;
00048
00049 virtual bool WriteMemory32(const simAddress, const uint32, const bool)=0;
00050
00051 virtual bool WriteMemory64(const simAddress, const uint64, const bool)=0;
00052
00053 virtual uint8 getFE(const simAddress)=0;
00054
00055 virtual void setFE(const simAddress, const uint8 FEValue)=0;
00056
00057 virtual void squashSpec()=0;
00058 };
00059 class base_memory;
00060
00061 struct MemMapEntry {
00062 #if 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 value;
00098 bool spec;
00099 int size;
00100 MemMapEntry *foo;
00101
00102 MemAccess( unsigned long long _when,
00103 simAddress _addr,
00104 uint32 _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 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 uint8 defaultFEB;
00162
00163
00164
00165
00166
00167 vector<vector<uint8>* > PageArray;
00168
00169
00170
00171 vector<vector<uint8>* > FEArray;
00172
00173 uint32 PageSize;
00174
00175 uint32 PageShift;
00176
00177 uint32 PageMask;
00178 inline uint8 *GetPage (const simAddress sa);
00179 inline uint8 *GetFEPage(const simAddress);
00180 specMemory specMem;
00181
00182 inline void readFileBackPage( const simAddress pageAddr, uint8 *bufAddr, int size );
00183 inline void writeFileBackPage( const simAddress pageAddr, uint8 *bufAddr, int size );
00184
00185 ulong sizeP;
00186 uint numPagesP;
00187 uint identP;
00188 int fdP;
00189 char backingFileNameP[FILENAME_MAX];
00190 uint32 *backingBitsP;
00191 uint8 *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 getDefaultFEB() { return defaultFEB; }
00208
00209
00210
00211 virtual ~base_memory() {;}
00212 uint8 _ReadMemory8(const simAddress, const bool);
00213 uint16 _ReadMemory16(const simAddress, const bool);
00214 uint32 _ReadMemory32(const simAddress, const bool);
00215 uint64 _ReadMemory64(const simAddress, const bool);
00216 bool _WriteMemory8(const simAddress, const uint8, const bool);
00217 bool _WriteMemory16(const simAddress, const uint16, const bool);
00218 bool _WriteMemory32(const simAddress, const uint32, const bool);
00219 bool _WriteMemory64(const simAddress, const uint64, const bool);
00220 virtual uint8 getFE(const simAddress);
00221 virtual void setFE(const simAddress, const uint8 FEValue);
00222 virtual void squashSpec() {specMem.squashSpec();}
00223 void clearMemory();
00224 bool hasPage(const simAddress);
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 bool LoadMem( const simAddress dest, void* const source, int Bytes);
00236
00237
00238 #define REDIRECT_READ_FUNC_GET(S) \
00239 virtual uint##S ReadMemory##S(const simAddress sa, \
00240 const bool spec) \
00241 { \
00242 return _ReadMemory##S(sa,spec); \
00243 }
00244
00245 #define REDIRECT_WRITE_FUNC_GET(S) \
00246 virtual bool WriteMemory##S(const simAddress sa, \
00247 const uint##S Data, const bool spec) \
00248 { \
00249 return _WriteMemory##S(sa,Data,spec); \
00250 }
00251
00252 #define SST_DELAY(S) \
00253 bool delayWriteMemory##S( MemMapEntry *tmp, \
00254 const simAddress sa, const uint##S Data, const bool spec) \
00255 { \
00256 simAddress addr = tmp->offset + (sa - tmp->addr); \
00257 \
00258 DPRINT(V1,"sa=%#x new-addr=%#x value=%x\n",(uint)sa,(uint)addr,(int)Data); \
00259 \
00260 bool ret = tmp->mem->WriteMemory##S( addr, Data, spec ); \
00261 if ( tmp->comp ) { \
00262 WriteNotify( tmp->comp, addr, Size##S ); \
00263 } \
00264 return ret; \
00265 }
00266
00267 REDIRECT_READ_FUNC_GET(8)
00268 REDIRECT_READ_FUNC_GET(16)
00269 REDIRECT_READ_FUNC_GET(32)
00270 REDIRECT_READ_FUNC_GET(64)
00271
00272 REDIRECT_WRITE_FUNC_GET(8)
00273 REDIRECT_WRITE_FUNC_GET(16)
00274 REDIRECT_WRITE_FUNC_GET(32)
00275 REDIRECT_WRITE_FUNC_GET(64)
00276
00277
00278
00279
00280 #undef DELAY
00281
00282 void setup();
00283 void finish();
00284 void preTic();
00285
00286 };
00287
00288 typedef enum {
00289 GlobalTextMem = 1,
00290 GlobalDataMem = 2,
00291 LocalDynamic = 3,
00292 GlobalDynamic = 4,
00293 AddressError = 0,
00294 MemTypes = 5
00295 } memoryAccType;
00296
00297 #include "mallocSysCall.h"
00298
00299
00300
00301
00302
00303
00304
00305 class memory : public memory_interface {
00306 #if WANT_CHECKPOINT_SUPPORT
00307 BOOST_SERIALIZE {
00308 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( memory_interface );
00309 ar & BOOST_SERIALIZATION_NVP(myMem);
00310
00311
00312
00313
00314 ar & BOOST_SERIALIZATION_NVP(madeMemory);
00315 }
00316 #endif
00317 base_memory *myMem;
00318 static vmRegionAlloc globalDynamic;
00319 static localRegionAlloc localDynamic;
00320
00321 public:
00322 static simAddress segRange[MemTypes][2];
00323 static const char *segName[MemTypes];
00324
00325 bool madeMemory;
00326
00327 base_memory *getBaseMem() {return myMem;}
00328
00329
00330
00331
00332 memory() : myMem(new base_memory()), madeMemory(1) {}
00333 memory(base_memory *bm) : myMem(bm), madeMemory(0) {
00334 if (bm == NULL) {
00335 myMem = new base_memory();
00336 madeMemory = 1;
00337 }
00338 }
00339
00340 virtual ~memory() {
00341 if (myMem && madeMemory) {
00342 delete myMem;
00343 }
00344 }
00345
00346 static memoryAccType getAccType(simAddress sa);
00347
00348 virtual uint8 getFE(const simAddress sa) {return myMem->getFE(sa);}
00349 virtual void setFE(const simAddress sa, const uint8 FEValue) {
00350 myMem->setFE(sa, FEValue);
00351 }
00352 virtual void squashSpec() {myMem->squashSpec();}
00353
00354 virtual uint8 ReadMemory8(const simAddress sa, const bool s);
00355 virtual bool WriteMemory8(const simAddress sa, const uint8 d, const bool s);
00356 virtual uint16 ReadMemory16(const simAddress sa, const bool s);
00357 virtual bool WriteMemory16(const simAddress sa, const uint16 d, const bool s);
00358 virtual uint32 ReadMemory32(const simAddress sa, const bool s);
00359 virtual bool WriteMemory32(const simAddress sa, const uint32 d, const bool s);
00360 virtual uint64 ReadMemory64(const simAddress sa, const bool s);
00361 virtual bool WriteMemory64(const simAddress sa, const uint64 d, const bool s);
00362
00363 static simAddress globalAllocate (unsigned int size);
00364 static simAddress localAllocateNearAddr (unsigned int size, simAddress addr);
00365 static simAddress localAllocateAtID (unsigned int size, unsigned int ID);
00366 static unsigned int memFree(simAddress addr, unsigned int size);
00367
00368 static void setUpLocalDistribution ( uint hashShift, uint locCount) {
00369 localDynamic.setup(hashShift, locCount);
00370 }
00371 static void addLocalID (processor *p, uint locID) {
00372 localDynamic.addLoc(p, locID);
00373 }
00374 static int getLocalID (processor *p) {
00375 return localDynamic.getLoc(p);
00376 }
00377 static int whichLoc (simAddress sa) {
00378 return localDynamic.whichLoc(sa);
00379 }
00380 static uint maxLocalChunk() {
00381 return localDynamic.stride();
00382 }
00383 static uint numLocales() {
00384 return localDynamic.locs();
00385 }
00386 static simAddress addrOnLoc (uint i) {
00387 return localDynamic.addrOnLoc(i);
00388 }
00389 };
00390
00391 #endif