00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _MEMORY_H
00014 #define _MEMORY_H
00015
00016 #ifndef MEMORY_DBG
00017 #define MEMORY_DBG 0
00018 #endif
00019
00020 #define _MEMORY_DBG( fmt, args... ) \
00021 m_dbg.write( "%s():%d: "fmt, __FUNCTION__, __LINE__, ##args)
00022
00023 #include <queue>
00024 #include <memoryDev.h>
00025 #include <memMap.h>
00026
00027 template < typename addrT = uint64_t,
00028 typename cookieT = unsigned long,
00029 typename dataT = unsigned long >
00030 class Memory :
00031 public MemoryIF< addrT, cookieT >
00032 {
00033 public:
00034 typedef MemoryDev< addrT, cookieT > dev_t;
00035 typedef addrT addr_t;
00036 typedef addr_t length_t;
00037 typedef cookieT cookie_t;
00038 typedef dataT data_t;
00039
00040 public:
00041 Memory();
00042 bool devAdd( dev_t*, addr_t, addr_t );
00043
00044 virtual bool read( addr_t, cookie_t );
00045 virtual bool write( addr_t, cookie_t );
00046 virtual bool read( addr_t, data_t*, cookie_t );
00047 virtual bool write( addr_t, data_t*, cookie_t );
00048 virtual bool popCookie( cookie_t& );
00049 virtual bool map( addr_t, addr_t, length_t );
00050
00051
00052
00053 bool send(addr_t addr, cookie_t cookie, typename dev_t::event_t::reqType_t type);
00054
00055 private:
00056 typedef MemMap< addr_t, addr_t, dev_t* > devMap_t;
00057 typedef MemMap< addr_t, addr_t, std::pair< addr_t, addr_t > > memMap_t;
00058
00059 private:
00060 addr_t calcAddr( addr_t );
00061
00062 private:
00063 std::deque< cookie_t > m_cookieQ;
00064 devMap_t m_devMap;
00065 memMap_t m_memMap;
00066 Log< MEMORY_DBG >& m_dbg;
00067 };
00068
00069 template < typename addrT, typename cookieT, typename dataT >
00070 Memory< addrT, cookieT, dataT >::Memory() :
00071 m_dbg( *new Log< MEMORY_DBG >( "Memory::" ) )
00072 {
00073 }
00074
00075 template < typename addrT, typename cookieT, typename dataT >
00076 bool Memory< addrT, cookieT, dataT >::devAdd( dev_t* dev,
00077 addr_t addr, length_t length )
00078 {
00079 _MEMORY_DBG( "addr=%#lx length=%#lx\n", addr, length );
00080 return m_devMap.insert( addr, length, dev );
00081 }
00082
00083 template < typename addrT, typename cookieT, typename dataT >
00084 inline bool
00085 Memory< addrT, cookieT, dataT >::map( addr_t from,
00086 addr_t to, length_t length )
00087 {
00088 _MEMORY_DBG( "from=%#lx to=%#lx length=%#lx\n", from, to, length );
00089 return m_memMap.insert( from, length, std::make_pair( from, to ) );
00090 }
00091
00092 template < typename addrT, typename cookieT, typename dataT >
00093 inline bool
00094 Memory< addrT, cookieT, dataT >::read( addr_t addr, cookie_t cookie = NULL )
00095 {
00096 addr = calcAddr( addr );
00097 dev_t** dev = m_devMap.find( addr );
00098 if ( dev == NULL ) {
00099 _abort( Memory, "m_devMap.find( %#lx ) failed\n", (unsigned long)addr);
00100 }
00101 return (*dev)->read( addr, cookie );
00102 }
00103
00104 template < typename addrT, typename cookieT, typename dataT >
00105 inline bool
00106 Memory< addrT, cookieT, dataT >::write( addr_t addr, cookie_t cookie = NULL )
00107 {
00108 addr = calcAddr( addr );
00109 dev_t** dev = m_devMap.find( addr );
00110 if ( dev == NULL ) {
00111 _abort( Memory, "m_devMap.find( %#lx ) failed\n", (unsigned long)addr);
00112 }
00113 return (*dev)->write( addr, cookie );
00114 }
00115
00116 template < typename addrT, typename cookieT, typename dataT >
00117 inline bool
00118 Memory< addrT, cookieT, dataT >::read( addr_t addr, data_t* data,
00119 cookie_t cookie = NULL )
00120 {
00121 addr = calcAddr( addr );
00122 dev_t** dev = m_devMap.find( addr );
00123 if ( dev == NULL ) {
00124 _abort( Memory, "m_devMap.find( %#lx ) failed\n", (unsigned long)addr);
00125 }
00126 return (*dev)->read( addr, data, cookie );
00127 }
00128
00129 template < typename addrT, typename cookieT, typename dataT >
00130 inline bool
00131 Memory< addrT, cookieT, dataT >::write( addr_t addr, data_t* data,
00132 cookie_t cookie = NULL )
00133 {
00134 addr = calcAddr( addr );
00135 dev_t** dev = m_devMap.find( addr );
00136 if ( dev == NULL ) {
00137 _abort( Memory, "m_devMap.find( %#lx ) failed\n", (unsigned long)addr);
00138 }
00139 return (*dev)->write( addr, data, cookie );
00140 }
00141
00142 template < typename addrT, typename cookieT, typename dataT >
00143 inline bool
00144 Memory< addrT, cookieT, dataT >::send(addr_t addr, cookie_t cookie,
00145 typename dev_t::event_t::reqType_t type) {
00146 addr = calcAddr( addr );
00147 dev_t** dev = m_devMap.find( addr );
00148 if ( dev == NULL ) {
00149 _abort( Memory, "m_devMap.find( %#lx ) failed\n", (unsigned long)addr);
00150 }
00151 return (*dev)->send( addr, NULL, cookie, type );
00152 }
00153
00154 template < typename addrT, typename cookieT, typename dataT >
00155 inline bool
00156 Memory< addrT, cookieT, dataT >::popCookie( cookieT& cookie )
00157 {
00158 if ( ! m_cookieQ.empty() ) {
00159 cookie = m_cookieQ.front();
00160 m_cookieQ.pop_front();
00161 return true;
00162 }
00163
00164 bool ret = false;
00165 typename devMap_t::iterator iter = m_devMap.begin();
00166 for ( ; iter != m_devMap.end(); iter++ )
00167 {
00168 cookieT _cookie;
00169 if ( (*iter)->popCookie( _cookie ) ) {
00170 if ( ! ret ) {
00171 cookie = _cookie;
00172 ret = true;
00173 } else {
00174 m_cookieQ.push_back( _cookie );
00175 }
00176 }
00177 }
00178 return ret;
00179 }
00180
00181 template < typename addrT, typename cookieT, typename dataT >
00182 inline addrT
00183 Memory< addrT, cookieT, dataT >::calcAddr( addrT addr )
00184 {
00185 if ( m_memMap.empty() ) {
00186 _MEMORY_DBG( "addr=%#lx\n", addr );
00187 return addr;
00188 }
00189
00190 std::pair< addr_t, addr_t >* tmp;
00191 tmp = m_memMap.find( addr );
00192 if ( tmp == NULL ) {
00193 _abort( Memory, "m_memMap.find( %#lx ) failed\n", (unsigned long)addr);
00194 }
00195
00196 addr_t new_addr = ( addr - (*tmp).first ) + (*tmp).second;
00197 _MEMORY_DBG("%#lx -> %#lx\n", addr, new_addr );
00198
00199 return new_addr;
00200 }
00201
00202 #endif