54 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
59 mConfigurationSpace(),
63 mLastPacketHeader ( 0x200000f0 ),
64 mTrafficHistory ( 16, 0x00 ),
65 mReceivedControlPacketHeaderHistory ( 4 , 0x00000000 ),
66 mSentControlPacketHeaderHistory ( 4 , 0x00000000 ),
67 mBigEndianHack ( aBigEndianHack )
69 for (
size_t i = 0; i < 10; i++)
73 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
79 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
83 if ( IPbus_major == 2 )
85 bool is_status_request = ( *mReceive.begin() == 0xF1000020 );
86 bool is_resend_request = ( ( *mReceive.begin() & 0xFF0000FF ) == 0xF2000020 );
88 if ( mBigEndianHack || is_status_request || is_resend_request )
90 for ( std::vector<uint32_t>::iterator lIt ( mReceive.begin() ) ; lIt != mReceive.begin() + ( aByteCount>>2 ) ; ++lIt )
92 *lIt = ntohl ( *lIt );
97 std::vector<uint32_t>::const_iterator lBegin, lEnd;
103 log (
Debug() ,
"\n=============================================== RECEIVED ===============================================" );
105 lBegin = mReceive.begin();
106 lEnd = mReceive.begin() + ( aByteCount>>2 );
107 lHostToTargetDebugger.
analyze ( lBegin , lEnd );
112 lBegin = mReceive.begin();
113 lEnd = mReceive.begin() + ( aByteCount>>2 );
115 if ( ! base_type::analyze ( lBegin , lEnd ) )
117 log (
Error() ,
"Found a bad header" );
121 if ( ( base_type::mPacketType == 0 ) && ( mReply.size() != 0 ) )
123 mReplyHistory.push_back ( std::make_pair ( base_type::mPacketCounter , mReply ) );
124 mReplyHistory.pop_front();
127 if ( mReplyDelay > std::chrono::microseconds(0) )
129 log (
Info() ,
"Sleeping for " , mReplyDelay.count(),
"ms" );
130 std::this_thread::sleep_for( mReplyDelay );
131 mReplyDelay = std::chrono::microseconds(0);
132 log (
Info() ,
"Now replying " );
139 log (
Debug() ,
"\n=============================================== SENDING ===============================================" );
141 lBegin = mReply.begin();
143 lTargetToHostDebugger.
analyze ( lBegin , lEnd );
149 if ( IPbus_major == 2 )
151 if ( mBigEndianHack || base_type::mPacketType == 1 )
153 for (
auto&
x: mReply )
160 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
163 if( ! mMemory.size() )
169 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
172 if( ! mMemory.size() )
178 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
181 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
182 mReceivedControlPacketHeaderHistory.pop_front();
184 mReply.push_back ( lExpected );
185 mSentControlPacketHeaderHistory.push_back ( lExpected );
186 mSentControlPacketHeaderHistory.pop_front();
190 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
193 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
194 mReceivedControlPacketHeaderHistory.pop_front();
195 uint32_t lAddress ( aAddress );
197 mReply.push_back ( lExpected );
198 mSentControlPacketHeaderHistory.push_back ( lExpected );
199 mSentControlPacketHeaderHistory.pop_front();
201 for ( ; base_type::mWordCounter!=0 ; --base_type::mWordCounter )
203 mReply.push_back ( GetEndpoint( lAddress ) );
208 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
211 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
212 mReceivedControlPacketHeaderHistory.pop_front();
213 uint32_t lAddress ( aAddress );
215 mReply.push_back ( lExpected );
216 mSentControlPacketHeaderHistory.push_back ( lExpected );
217 mSentControlPacketHeaderHistory.pop_front();
219 for ( ; base_type::mWordCounter!=0 ; --base_type::mWordCounter )
221 mReply.push_back ( GetEndpoint( lAddress++ ) );
226 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
229 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
230 mReceivedControlPacketHeaderHistory.pop_front();
231 uint32_t lAddress ( aAddress );
233 mReply.push_back ( lExpected );
234 mSentControlPacketHeaderHistory.push_back ( lExpected );
235 mSentControlPacketHeaderHistory.pop_front();
237 for ( ; base_type::mWordCounter!=0 ; --base_type::mWordCounter )
239 mReply.push_back ( mConfigurationSpace.at( lAddress++ ) );
244 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
247 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
248 mReceivedControlPacketHeaderHistory.pop_front();
249 uint32_t lAddress ( aAddress );
251 while ( aIt != aEnd )
253 SetEndpoint ( lAddress , *aIt++ );
258 if ( IPbus_major == 1 )
267 mReply.push_back ( lExpected );
268 mSentControlPacketHeaderHistory.push_back ( lExpected );
269 mSentControlPacketHeaderHistory.pop_front();
273 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
276 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
277 mReceivedControlPacketHeaderHistory.pop_front();
278 uint32_t lAddress ( aAddress );
280 while ( aIt != aEnd )
282 SetEndpoint ( lAddress++ , *aIt++ );
287 if ( IPbus_major == 1 )
296 mReply.push_back ( lExpected );
297 mSentControlPacketHeaderHistory.push_back ( lExpected );
298 mSentControlPacketHeaderHistory.pop_front();
302 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
305 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
306 mReceivedControlPacketHeaderHistory.pop_front();
307 uint32_t lAddress ( aAddress );
309 mReply.push_back ( lExpected );
310 mSentControlPacketHeaderHistory.push_back ( lExpected );
311 mSentControlPacketHeaderHistory.pop_front();
313 if ( IPbus_major == 1 )
316 uint32_t lValue( GetEndpoint( lAddress ) );
318 SetEndpoint( lAddress , lValue );
319 mReply.push_back ( lValue );
324 uint32_t lValue( GetEndpoint( lAddress ) );
325 mReply.push_back ( lValue );
327 SetEndpoint( lAddress , lValue );
332 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
335 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
336 mReceivedControlPacketHeaderHistory.pop_front();
337 uint32_t lAddress ( aAddress );
339 mReply.push_back ( lExpected );
340 mSentControlPacketHeaderHistory.push_back ( lExpected );
341 mSentControlPacketHeaderHistory.pop_front();
343 if ( IPbus_major == 1 )
346 uint32_t lValue( GetEndpoint( lAddress ) );
349 SetEndpoint( lAddress , lValue );
350 mReply.push_back ( lValue );
355 uint32_t lValue( GetEndpoint( lAddress ) );
356 mReply.push_back ( lValue );
359 SetEndpoint( lAddress , lValue );
364 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
368 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
369 mReceivedControlPacketHeaderHistory.pop_front();
371 mReply.push_back ( lExpected );
372 mSentControlPacketHeaderHistory.push_back ( lExpected );
373 mSentControlPacketHeaderHistory.pop_front();
377 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
380 if ( base_type::mPacketCounter != 0 )
382 uint16_t lTemp ( ( ( mLastPacketHeader>>8 ) &0x0000FFFF ) + 1 );
389 if ( base_type::mPacketCounter != lTemp )
391 mTrafficHistory.push_back ( 5 );
392 mTrafficHistory.pop_front();
393 log(
Notice(),
"Dummy hardware received control packet with ID ",
Integer(base_type::mPacketCounter),
", but expected ID ",
Integer(lTemp));
397 mLastPacketHeader = base_type::mPacketHeader;
400 mReply.push_back ( base_type::mPacketHeader );
401 mTrafficHistory.push_back ( 2 );
402 mTrafficHistory.pop_front();
407 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
410 mReply.push_back ( base_type::mPacketHeader );
411 mReply.push_back (
BUFFER_SIZE *
sizeof ( uint32_t ) );
413 uint16_t lTemp ( ( ( mLastPacketHeader>>8 ) &0x0000FFFF ) + 1 );
420 mReply.push_back ( ( mLastPacketHeader & 0xFF0000FF ) | ( ( lTemp <<8 ) & 0x00FFFF00 ) );
421 std::deque< uint8_t >::const_iterator lIt ( mTrafficHistory.begin() );
423 for ( uint32_t i = 0; i != 4 ; ++i )
425 uint32_t lTemp ( 0x00000000 );
427 for ( uint32_t
j = 0;
j != 4 ; ++
j )
430 lTemp |= ( uint32_t ) ( *lIt );
434 mReply.push_back ( lTemp );;
437 for (
const auto&
x: mReceivedControlPacketHeaderHistory )
439 mReply.push_back (
x );
442 for (
const auto&
x: mSentControlPacketHeaderHistory )
444 mReply.push_back (
x );
447 mTrafficHistory.push_back ( 3 );
448 mTrafficHistory.pop_front();
452 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
455 std::deque< std::pair< uint32_t , std::vector< uint32_t > > >::reverse_iterator lIt = mReplyHistory.rbegin();
457 for ( ; lIt!=mReplyHistory.rend() ; ++lIt )
459 if ( lIt->first == base_type::mPacketCounter )
461 mReply = lIt->second;
466 mTrafficHistory.push_back ( 4 );
467 mTrafficHistory.pop_front();
471 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
474 mTrafficHistory.push_back ( 5 );
475 mTrafficHistory.pop_front();
Helper class to decode IPbus packets as passed from the Client to the Target.
bool analyze(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd, const bool &aContinueOnError=true)
Analyse an IPbus packet held as a vector of uint32_t's.
A class which provides the version-specific functionality for IPbus.
Helper class to decode IPbus packets as passed from the Target to the Client.
bool analyze(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd, const bool &aContinueOnError=true)
Analyse an IPbus packet held as a vector of uint32_t's.
Abstract base class to emulate IPbus hardware.
void unknown_type()
Analyse request and create reply when the header is unknown.
void rmw_sum(const uint32_t &aAddress, const uint32_t &aAddend)
Analyse request and create reply when a read-modify-write sum is observed.
void read(const uint32_t &aAddress)
Analyse request and create reply when an incrementing read is observed.
void SetEndpoint(const uint32_t &aAddress, const uint32_t &aValue)
void ni_write(const uint32_t &aAddress, std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Analyse request and create reply when a non-incrementing write is observed.
void ni_read(const uint32_t &aAddress)
Analyse request and create reply when a non-incrementing read is observed.
uint32_t GetEndpoint(const uint32_t &aAddress)
void write(const uint32_t &aAddress, std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Analyse request and create reply when an incrementing write is observed.
DummyHardware(const uint32_t &aReplyDelay, const bool &aBigEndianHack)
Constructor.
void rmw_bits(const uint32_t &aAddress, const uint32_t &aAndTerm, const uint32_t &aOrTerm)
Analyse request and create reply when a read-modify-write bits is observed.
void status_packet_header()
Analyse request and create reply when an IPbus 2.0 status packet header is observed.
std::vector< uint32_t > mConfigurationSpace
The configuration space within the virtual hardware.
bool control_packet_header()
Analyse request and create reply when an IPbus 2.0 control packet header is observed.
void resend_packet_header()
Analyse request and create reply when an IPbus 2.0 resend packet header is observed.
void readConfigurationSpace(const uint32_t &aAddress)
Analyse request and create reply when an incrementing "configuration space" read is observed.
void unknown_packet_header()
Analyse request and create reply when an unknown IPbus 2.0 packet header is observed.
void bot()
Analyse request and create reply when a Byte-OrderTransaction is observed.
void AnalyzeReceivedAndCreateReply(const uint32_t &aByteCount)
Function which analyses the received IPbus packet and creates the suitable response.
Common abstract base class for IPbus 1.3 and 2.0 dummy hardware.
None tests(nox.Session session)
std::vector< uint32_t >::const_iterator j
static const uint32_t BUFFER_SIZE
Size of the receive and reply buffers.
static const uint32_t REPLY_HISTORY_DEPTH
The size of the reply history for IPbus 2.0.
static const uint32_t ADDRESSMASK
The mask for the address space (size of the address space in one larger than this)
_Integer< T, IntFmt<> > Integer(const T &aT)
Forward declare a function which creates an instance of the ultra-lightweight wrapper from an integer...
const bool & LoggingIncludes(const FatalLevel &)
Function to check at runtime whether the level Fatal is to be included in the log output.
void log(FatalLevel &aFatal, const T0 &aArg0)
Function to add a log entry at Fatal level.
Empty struct which acts as a dummy variable for passing the formatting information around.