μHAL (v2.8.17)
Part of the IPbus software repository
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
IPbusInspector.cpp
Go to the documentation of this file.
1/*
2---------------------------------------------------------------------------
3
4 This file is part of uHAL.
5
6 uHAL is a hardware access library and programming framework
7 originally developed for upgrades of the Level-1 trigger of the CMS
8 experiment at CERN.
9
10 uHAL is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 uHAL is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with uHAL. If not, see <http://www.gnu.org/licenses/>.
22
23
24 Andrew Rose, Imperial College, London
25 email: awr01 <AT> imperial.ac.uk
26
27 Marc Magrans de Abril, CERN
28 email: marc.magrans.de.abril <AT> cern.ch
29
30---------------------------------------------------------------------------
31*/
32
34
35
39#include "uhal/log/log.hpp"
40
41
42namespace uhal
43{
44
45 template< uint8_t IPbus_major , uint8_t IPbus_minor >
47 mHeader ( 0 ),
48 mWordCounter ( 0 ),
49 mTransactionId ( 0 ),
50 mResponseGood ( 0 ),
51 mPacketHeader ( 0 ),
52 mPacketCounter ( 0 ),
53 mPacketType ( 0 )
54 {}
55
56
57 template< uint8_t IPbus_major , uint8_t IPbus_minor >
59
60
61 template< uint8_t IPbus_major , uint8_t IPbus_minor >
62 bool HostToTargetInspector<IPbus_major , IPbus_minor>::analyze ( std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd , const bool& aContinueOnError )
63 {
64 for ( std::vector<uint32_t>::const_iterator lIt ( aIt ); lIt != aEnd; ++lIt )
65 {
66 log ( Debug , Integer ( *lIt, IntFmt<hex,fixed>() ) );
67 }
68
69 // log ( Notice() , Pointer(&(*aIt)) , " : " , Pointer(&(*aEnd)) , "(", Integer((&(*aEnd)-&(*aIt))*4) ,")" );
70 uint32_t lAddress , lAddend , lAndTerm , lOrTerm ;
71 std::vector<uint32_t>::const_iterator lPayloadBegin, lPayloadEnd;
72
73 if ( IPbus_major != 1 )
74 {
75 mPacketHeader = *aIt++;
76 mPacketCounter = ( mPacketHeader>>8 ) &0xFFFF ;
77 mPacketType = mPacketHeader&0x0F ;
78 }
79
80 switch ( mPacketType )
81 {
82 case 0:
83
84 if ( IPbus_major != 1 )
85 {
86 if ( !control_packet_header ( ) )
87 {
88 return true;
89 }
90 }
91
92 do
93 {
94 mHeader = *aIt++;
95
97 mHeader ,
98 mType ,
99 mWordCounter ,
100 mTransactionId ,
101 mResponseGood )
102 )
103 {
104 log ( Error() , "Unable to parse send header " , Integer ( mHeader, IntFmt<hex,fixed>() ) );
105
106 if ( IPbus_major != 1 )
107 {
108 if ( ! aContinueOnError )
109 {
110 aIt--;
111 return true;
112 }
113
114 log ( Warning() , "Attempting to see if it is because the bad header was, in fact, a packet header" );
115 aIt--;
116 return this->analyze ( aIt , aEnd );
117 }
118 else
119 {
120 return false;
121 }
122 }
123
124 if ( ( IPbus_major==1 && mResponseGood != 0 ) || ( IPbus_major==2 && mResponseGood != 0xf ) )
125 {
126 log ( Error(), "Bad InfoCode value of ", Integer ( mResponseGood ), " detected in IPbus transaction request header ", Integer ( mHeader, IntFmt<hex,fixed>() ) );
127 return false;
128 }
129
130 switch ( mType )
131 {
132 case B_O_T:
133 bot();
134 break;
135 case NI_READ:
136 lAddress = *aIt++;
137 ni_read ( lAddress );
138 break;
139 case READ:
140 lAddress = *aIt++;
141 read ( lAddress );
142 break;
144 lAddress = *aIt++;
145 readConfigurationSpace( lAddress );
146 break;
147 case NI_WRITE:
148 lAddress = *aIt++;
149 lPayloadBegin = aIt;
150 lPayloadEnd = aIt + mWordCounter;
151 ni_write ( lAddress , lPayloadBegin , lPayloadEnd );
152 aIt += mWordCounter;
153 break;
154 case WRITE:
155 lAddress = *aIt++;
156 lPayloadBegin = aIt;
157 lPayloadEnd = aIt + mWordCounter;
158 write ( lAddress , lPayloadBegin , lPayloadEnd );
159 aIt += mWordCounter;
160 break;
161 case RMW_SUM:
162 lAddress = *aIt++;
163 lAddend = *aIt++;
164 rmw_sum ( lAddress , lAddend );
165 break;
166 case RMW_BITS:
167 lAddress = *aIt++;
168 lAndTerm = *aIt++;
169 lOrTerm = *aIt++;
170 rmw_bits ( lAddress , lAndTerm , lOrTerm );
171 break;
172 default:
173 unknown_type();
174 return false;
175 }
176 }
177 while ( aIt!=aEnd );
178
179 break;
180 case 1:
181 aIt=aEnd;
182 status_packet_header();
183 break;
184 case 2:
185 aIt=aEnd;
186 resend_packet_header();
187 break;
188 default:
189 unknown_packet_header( );
190 return false;
191 }
192
193 return true;
194 }
195
196
197 template< uint8_t IPbus_major , uint8_t IPbus_minor >
199 {
200 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | BOT, transaction ID " , Integer ( mTransactionId ) );
201 }
202
203
204 template< uint8_t IPbus_major , uint8_t IPbus_minor >
206 {
207 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Non-incrementing read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
208 log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
209 }
210
211
212 template< uint8_t IPbus_major , uint8_t IPbus_minor >
214 {
215 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
216 log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
217 }
218
219
220 template< uint8_t IPbus_major , uint8_t IPbus_minor >
222 {
223 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing 'configuration space' read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
224 log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
225 }
226
227
228 template< uint8_t IPbus_major , uint8_t IPbus_minor >
229 void HostToTargetInspector<IPbus_major , IPbus_minor>::ni_write ( const uint32_t& aAddress , std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd )
230 {
231 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Non-incrementing write, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
232 log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
233 uint32_t lCounter ( 0 );
234
235 while ( aIt != aEnd )
236 {
237 log ( Notice() , Integer ( *aIt++, IntFmt<hex,fixed>() ) , " | > Data [" , Integer ( lCounter++ ) , "]" );
238 }
239 }
240
241
242 template< uint8_t IPbus_major , uint8_t IPbus_minor >
243 void HostToTargetInspector<IPbus_major , IPbus_minor>::write ( const uint32_t& aAddress , std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd )
244 {
245 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing write, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
246 log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
247 uint32_t lCounter ( 0 );
248
249 while ( aIt != aEnd )
250 {
251 log ( Notice() , Integer ( *aIt++, IntFmt<hex,fixed>() ) , " | > Data [" , Integer ( lCounter++ ) , "]" );
252 }
253 }
254
255
256 template< uint8_t IPbus_major , uint8_t IPbus_minor >
257 void HostToTargetInspector<IPbus_major , IPbus_minor>::rmw_sum ( const uint32_t& aAddress , const uint32_t& aAddend )
258 {
259 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Read-modify-write sum, transaction ID " , Integer ( mTransactionId ) );
260 log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
261 log ( Notice() , Integer ( aAddend, IntFmt<hex,fixed>() ) , " | > Addend" );
262 }
263
264
265 template< uint8_t IPbus_major , uint8_t IPbus_minor >
266 void HostToTargetInspector<IPbus_major , IPbus_minor>::rmw_bits ( const uint32_t& aAddress , const uint32_t& aAndTerm , const uint32_t& aOrTerm )
267 {
268 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Read-modify-write bits, transaction ID " , Integer ( mTransactionId ) );
269 log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
270 log ( Notice() , Integer ( aAndTerm, IntFmt<hex,fixed>() ) , " | > And-term" );
271 log ( Notice() , Integer ( aOrTerm, IntFmt<hex,fixed>() ) , " | > Or-term" );
272 }
273
274
275 template< uint8_t IPbus_major , uint8_t IPbus_minor >
277 {
278 log ( Error() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Unknown Transaction Header" );
279 }
280
281
282 template< uint8_t IPbus_major , uint8_t IPbus_minor >
284 {
285 log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Control (Instruction) Packet Header , Packet Counter " , Integer ( mPacketCounter ) );
286 return true;
287 }
288
289
290 template< uint8_t IPbus_major , uint8_t IPbus_minor >
292 {
293 log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Status Packet Header" );
294 }
295
296
297 template< uint8_t IPbus_major , uint8_t IPbus_minor >
299 {
300 log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Resend Request Packet Header" );
301 }
302
303
304 template< uint8_t IPbus_major , uint8_t IPbus_minor >
306 {
307 log ( Error() , Integer ( mPacketHeader, IntFmt<hex,fixed>() ) , " | Unknown Packet Header" );
308 }
309
310
311
312 template< uint8_t IPbus_major , uint8_t IPbus_minor >
315 mHeader ( 0 ),
316 mWordCounter ( 0 ),
317 mTransactionId ( 0 ),
318 mResponseGood ( 0 ),
319 mPacketHeader ( 0 ),
320 mPacketCounter ( 0 ),
321 mPacketType ( 0 )
322 {}
323
324
325 template< uint8_t IPbus_major , uint8_t IPbus_minor >
327
328
329 template< uint8_t IPbus_major , uint8_t IPbus_minor >
330 bool TargetToHostInspector<IPbus_major , IPbus_minor>::analyze ( std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd , const bool& aContinueOnError )
331 {
332 uint32_t lNewValue;
333 std::vector<uint32_t>::const_iterator lPayloadBegin, lPayloadEnd;
334
335 if ( IPbus_major != 1 )
336 {
337 mPacketHeader = *aIt++;
338 mPacketCounter = ( mPacketHeader>>8 ) &0xFFFF ;
339 mPacketType = mPacketHeader&0x0F ;
340 }
341
342 switch ( mPacketType )
343 {
344 case 0:
345
346 if ( IPbus_major != 1 )
347 {
348 if ( !control_packet_header ( ) )
349 {
350 return false;
351 }
352 }
353
354 do
355 {
356 mHeader = *aIt++;
357
359 mHeader ,
360 mType ,
361 mWordCounter ,
362 mTransactionId ,
363 mResponseGood )
364 )
365 {
366 log ( Error() , "Unable to parse reply header " , Integer ( mHeader, IntFmt<hex,fixed>() ) );
367
368 if ( IPbus_major != 1 )
369 {
370 if ( ! aContinueOnError )
371 {
372 aIt--;
373 return true;
374 }
375
376 log ( Warning() , "Attempting to see if it is because the bad header was, in fact, a packet header" );
377 aIt--;
378 return this->analyze ( aIt , aEnd );
379 }
380 else
381 {
382 return false;
383 }
384 }
385
386 switch ( mType )
387 {
388 case B_O_T:
389 bot();
390 break;
391 case NI_READ:
392 lPayloadBegin = aIt;
393 lPayloadEnd = aIt + mWordCounter;
394 ni_read ( lPayloadBegin , lPayloadEnd );
395 aIt += mWordCounter;
396 break;
397 case READ:
398 lPayloadBegin = aIt;
399 lPayloadEnd = aIt + mWordCounter;
400 read ( lPayloadBegin , lPayloadEnd );
401 aIt += mWordCounter;
402 break;
403 case NI_WRITE:
404 ni_write ();
405 break;
406 case WRITE:
407 write ();
408 break;
409 case RMW_SUM:
410 lNewValue = *aIt++;
411 rmw_sum ( lNewValue );
412 break;
413 case RMW_BITS:
414 lNewValue = *aIt++;
415 rmw_bits ( lNewValue );
416 break;
417 default:
418 unknown_type();
419 return false;
420 }
421 }
422 while ( aIt!=aEnd );
423
424 break;
425 case 1:
426 aIt=aEnd;
427 status_packet_header( );
428 break;
429 default:
430 unknown_packet_header( );
431 return false;
432 }
433
434 return true;
435 }
436
437
438 template< uint8_t IPbus_major , uint8_t IPbus_minor >
440 {
441 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | BOT, transaction ID " , Integer ( mTransactionId ) );
442 }
443
444
445 template< uint8_t IPbus_major , uint8_t IPbus_minor >
446 void TargetToHostInspector<IPbus_major , IPbus_minor>::ni_read ( std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd )
447 {
448 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Non-incrementing read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
449 uint32_t lCounter ( 0 );
450
451 while ( aIt != aEnd )
452 {
453 log ( Notice() , Integer ( *aIt++, IntFmt<hex,fixed>() ) , " | > Data [" , Integer ( lCounter++ ) , "]" );
454 }
455 }
456
457
458 template< uint8_t IPbus_major , uint8_t IPbus_minor >
459 void TargetToHostInspector<IPbus_major , IPbus_minor>::read ( std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd )
460 {
461 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
462 uint32_t lCounter ( 0 );
463
464 while ( aIt != aEnd )
465 {
466 log ( Notice() , Integer ( *aIt++, IntFmt<hex,fixed>() ) , " | > Data [" , Integer ( lCounter++ ) , "]" );
467 }
468 }
469
470
471 template< uint8_t IPbus_major , uint8_t IPbus_minor >
473 {
474 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Non-incrementing write, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
475 }
476
477
478 template< uint8_t IPbus_major , uint8_t IPbus_minor >
480 {
481 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing write, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
482 }
483
484
485 template< uint8_t IPbus_major , uint8_t IPbus_minor >
487 {
488 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Read-modify-write sum, transaction ID " , Integer ( mTransactionId ) );
489 log ( Notice() , Integer ( aNewValue, IntFmt<hex,fixed>() ) , " | > Data" );
490 }
491
492
493 template< uint8_t IPbus_major , uint8_t IPbus_minor >
495 {
496 log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Read-modify-write bits, transaction ID " , Integer ( mTransactionId ) );
497 log ( Notice() , Integer ( aNewValue, IntFmt<hex,fixed>() ) , " | > Data" );
498 }
499
500
501 template< uint8_t IPbus_major , uint8_t IPbus_minor >
503 {
504 log ( Error() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Unknown Transaction Header" );
505 }
506
507
508 template< uint8_t IPbus_major , uint8_t IPbus_minor >
510 {
511 log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Control (Instruction) Packet Header , Packet Counter " , Integer ( mPacketCounter ) );
512 return true;
513 }
514
515
516 template< uint8_t IPbus_major , uint8_t IPbus_minor >
518 {
519 log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Status Packet Header" );
520 }
521
522
523 template< uint8_t IPbus_major , uint8_t IPbus_minor >
525 {
526 log ( Error() , Integer ( mPacketHeader, IntFmt<hex,fixed>() ) , " | Unknown Packet Header" );
527 }
528
529
530 template class HostToTargetInspector<1, 3>;
531 template class HostToTargetInspector<2, 0>;
532 template class TargetToHostInspector<1, 3>;
533 template class TargetToHostInspector<2, 0>;
534}
Helper class to decode IPbus packets as passed from the Client to the Target.
virtual bool control_packet_header()
Virtual callback function called when an IPbus 2.0 control packet header is observed.
virtual void resend_packet_header()
Virtual callback function called when an IPbus 2.0 resend packet header is observed.
virtual ~HostToTargetInspector()
Destructor.
virtual void unknown_type()
Virtual callback function for the case where the header is unknown.
virtual void status_packet_header()
Virtual callback function called when an IPbus 2.0 status packet header is observed.
virtual void ni_read(const uint32_t &aAddress)
Virtual callback function called when a non-incrementing read is observed.
virtual void read(const uint32_t &aAddress)
Virtual callback function called when an incrementing read is observed.
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.
virtual void ni_write(const uint32_t &aAddress, std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Virtual callback function called when a non-incrementing write is observed.
virtual void bot()
Virtual callback function called when a Byte-OrderTransaction is observed.
virtual void rmw_bits(const uint32_t &aAddress, const uint32_t &aAndTerm, const uint32_t &aOrTerm)
Virtual callback function called when a read-modify-write bits is observed.
virtual void unknown_packet_header()
Virtual callback function called when an unknown IPbus 2.0 packet header is observed.
virtual void rmw_sum(const uint32_t &aAddress, const uint32_t &aAddend)
Virtual callback function called when a read-modify-write sum is observed.
HostToTargetInspector()
Default constructor.
virtual void readConfigurationSpace(const uint32_t &aAddress)
Virtual callback function called when an incrementing "configuration space" read is observed.
virtual void write(const uint32_t &aAddress, std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Virtual callback function called when an incrementing write is observed.
A class which provides the version-specific functionality for IPbus.
Helper class to decode IPbus packets as passed from the Target to the Client.
virtual void ni_write()
Virtual callback function called when a non-incrementing write is observed.
virtual void rmw_bits(const uint32_t &aNewValue)
Virtual callback function called when a read-modify-write bits is observed.
virtual void write()
Virtual callback function called when an incrementing write is observed.
virtual void unknown_packet_header()
Virtual callback function called when an unknown IPbus 2.0 packet header is observed.
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.
virtual void status_packet_header()
Virtual callback function called when an IPbus 2.0 status packet header is observed.
virtual ~TargetToHostInspector()
Destructor.
virtual void unknown_type()
Virtual callback function for the case where the header is unknown.
virtual void bot()
Virtual callback function called when a Byte-OrderTransaction is observed.
virtual void read(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Virtual callback function called when an incrementing read is observed.
TargetToHostInspector()
Default constructor.
virtual void ni_read(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Virtual callback function called when a non-incrementing read is observed.
virtual bool control_packet_header()
Virtual callback function called when an IPbus 2.0 control packet header is observed.
virtual void rmw_sum(const uint32_t &aNewValue)
Virtual callback function called when a read-modify-write sum is observed.
DebugLevel Debug
Definition: LogLevels.cpp:133
_Integer< T, IntFmt<> > Integer(const T &aT)
Forward declare a function which creates an instance of the ultra-lightweight wrapper from an integer...
ErrorLevel Error
Definition: LogLevels.cpp:61
void log(FatalLevel &aFatal, const T0 &aArg0)
Function to add a log entry at Fatal level.
Definition: log.hxx:18
WarningLevel Warning
Definition: LogLevels.cpp:79
NoticeLevel Notice
Definition: LogLevels.cpp:97
Empty struct which acts as a dummy variable for passing the formatting information around.