1 
2 /*
3  * Copyright (C) Texas Instruments - http://www.ti.com/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 /* NOTE: This header should be only included from perf.h */
22 
23 /* this union is used to convert a float to a long representation without
24    breaking strict aliasing rules */
25 union __PERF_float_long
26 {
27     float f;
28     unsigned long l;
29 };
30 
31 /* combine 2 values in a unsigned long */
32 #define PERF_mask(field, len) \
33     ( ((unsigned long) (field)) & ((1 << (len)) - 1) )
34 
35 #define PERF_bits(field, start, len) \
36     ( (((unsigned long) (field)) >> start) & ((1 << (len)) - 1) )
37 
38 #define PERF_log_combine(flag, field, len) \
39     ( ((unsigned long) (flag)) | (PERF_mask(field, len) & PERF_LOG_NotMask) )
40 
41 #define PERF_COMBINE2(field1, len1, field2, len2) \
42     ( ( PERF_mask(field1, len1) << (len2) ) |     \
43         PERF_mask(field2, len2) )
44 
45 #define PERF_LOGCOMBINE2(flag, field1, len1, field2, len2)            \
46     PERF_log_combine(flag, PERF_COMBINE2(field1, len1, field2, len2), \
47     (len1) + (len2))
48 
49 #define PERF_COMBINE3(field1, len1, field2, len2, field3, len3) \
50     ((( ( PERF_mask(field1, len1)   << (len2) ) |               \
51           PERF_mask(field2, len2) ) << (len3) ) |               \
52           PERF_mask(field3, len3) )
53 
54 #define PERF_LOGCOMBINE3(flag, field1, len1, field2, len2, field3, len3)     \
55     PERF_log_combine(flag,                                                   \
56                     PERF_COMBINE3(field1, len1, field2, len2, field3, len3), \
57                     (len1) + (len2) + (len3))
58 
59 /*=============================================================================
60     HARD CODED (default) INTERFACE
61 
62     This translates each instrumentation directly into a logging call.  It is
63     always defined, so that the logs can be done by the custom interface.
64 =============================================================================*/
65 
66 #define __PERF_LOG_Boundary(           \
67         hObject,                       \
68         eBoundary)                     \
69     PERF_check((hObject),              \
70      __PERF_log1(get_Private(hObject), \
71                  PERF_log_combine(PERF_LOG_Boundary, eBoundary, 26)) ) /* Macro End */
72 
73 /* we squeeze PERF_LOG flag into 2 or 4 bits */
74 #define __PERF_LOG_Buffer(                                                  \
75         hObject,                                                            \
76         flSending,                                                          \
77         flMultiple,                                                         \
78         flFrame,                                                            \
79         ulAddress1,                                                         \
80         ulAddress2,                                                         \
81         ulSize,                                                             \
82         eModule1,                                                           \
83         eModule2)                                                           \
84     PERF_check((hObject),                                                   \
85      PERF_IsMultiple(flMultiple) ?                                          \
86       __PERF_log3(get_Private(hObject),                                     \
87                   PERF_IsXfering(flSending) ?                               \
88                   (PERF_LOG_Buffer | PERF_LOG_Xfering |  /* 2 bits */       \
89                    PERF_COMBINE3((ulSize) >> 3, 30 - 2 * PERF_ModuleBits,   \
90                                  eModule2, PERF_ModuleBits,                 \
91                                  eModule1, PERF_ModuleBits) ) :             \
92                   (PERF_LOG_Buffer | flSending |  /* 4 bits */              \
93                    PERF_COMBINE2(ulSize, 28 - PERF_ModuleBits,              \
94                                  eModule1, PERF_ModuleBits) ),              \
95                   ( ((unsigned long) (ulAddress1)) & ~3 ) |                 \
96                   ( PERF_IsFrame   (flFrame)    ? PERF_LOG_Frame    : 0 ) | \
97                   ( PERF_IsMultiple(flMultiple) ? PERF_LOG_Multiple : 0 ),  \
98                   (unsigned long) (ulAddress2) ) :                          \
99       __PERF_log2(get_Private(hObject),                                     \
100                   PERF_IsXfering(flSending) ?                               \
101                   (PERF_LOG_Buffer | PERF_LOG_Xfering |  /* 2 bits */       \
102                    PERF_COMBINE3((ulSize) >> 3, 30 - 2 * PERF_ModuleBits,   \
103                                  eModule2, PERF_ModuleBits,                 \
104                                  eModule1, PERF_ModuleBits) ) :             \
105                   (PERF_LOG_Buffer | flSending | /* 4 bits */               \
106                    PERF_COMBINE2(ulSize, 28 - PERF_ModuleBits,              \
107                                  eModule1, PERF_ModuleBits) ),              \
108                   ( ((unsigned long) (ulAddress1)) & ~3 ) |                 \
109                   ( PERF_IsFrame   (flFrame)    ? PERF_LOG_Frame    : 0 ) | \
110                   ( PERF_IsMultiple(flMultiple) ? PERF_LOG_Multiple : 0 ) ))
111 
112 #define __PERF_LOG_Command(                                               \
113         hObject,                                                          \
114         ulSending,                                                        \
115         ulArgument,                                                       \
116         ulCommand,                                                        \
117         eModule)                                                          \
118     PERF_check((hObject),                                                 \
119      __PERF_log3(get_Private(hObject),                                    \
120                  PERF_log_combine(PERF_LOG_Command | ulSending, eModule, 28), \
121                  ((unsigned long) (ulCommand)),                           \
122                  ((unsigned long) (ulArgument)) ) ) /* Macro End */
123 
124 #define __PERF_LOG_Log(                              \
125         hObject,                                     \
126         ulData1,                                     \
127         ulData2,                                     \
128         ulData3)                                     \
129     PERF_check((hObject),                            \
130     __PERF_log3(get_Private(hObject),                \
131         PERF_log_combine(PERF_LOG_Log, ulData1, 28), \
132         ((unsigned long) (ulData2)),                 \
133         ((unsigned long) (ulData3)) ) ) /* Macro End */
134 
135 #define __PERF_LOG_SyncAV(                                                \
136         hObject,                                                          \
137         fTimeAudio,                                                       \
138         fTimeVideo,                                                       \
139         eSyncOperation)                                                   \
140     do                                                                    \
141     {                                                                     \
142         union __PERF_float_long uA,uV;                                    \
143         uA.f = fTimeAudio;  uV.f = fTimeVideo;                            \
144         PERF_check((hObject),                                             \
145          __PERF_log3(get_Private(hObject),                                \
146                      PERF_log_combine(PERF_LOG_Sync, eSyncOperation, 28), \
147                      uA.l, uV.l));                                        \
148     }\
149     while(0) /* Macro End */
150 
151 #define __PERF_LOG_ThreadCreated(                          \
152         hObject,                                           \
153         ulThreadID,                                        \
154         ulThreadName)                                      \
155     PERF_check((hObject),                                  \
156     __PERF_log2(get_Private(hObject),                      \
157         PERF_log_combine(PERF_LOG_Thread, ulThreadID, 26), \
158         ((unsigned long) (ulThreadName)) ) ) /* Macro End */
159 
160 
161 /* ============================================================================
162    PERF LOG Data Structures
163 ============================================================================ */
164 
165 /* private PERF structure for logging */
166 typedef struct PERF_LOG_Private
167 {
168     unsigned long   uBufferCount; /* number of buffers filled */
169     unsigned long   uBufSize;     /* size of buffer */
170     unsigned long  *puBuffer;     /* start of current buffer */
171     unsigned long  *puEnd;        /* 'end' of current buffer */
172     unsigned long  *puPtr;        /* current buffer pointer */
173     FILE *fOut;                   /* output file */
174     char *fOutFile;               /* output file name */
175 } PERF_LOG_Private;
176 
177 /* log flags used */
178 enum PERF_LogStamps
179 {
180     /* 1 arguments */
181     PERF_LOG_Done     = 0x00000000,
182     PERF_LOG_Boundary = 0x08000000,
183     /* 2 arguments */
184     PERF_LOG_Thread   = 0x0C000000,
185     /* 3 arguments */
186     PERF_LOG_Log      = 0x10000000,
187     PERF_LOG_Sync     = 0x20000000,
188 #ifdef __PERF_LOG_LOCATION__
189     /* many arguments */
190     PERF_LOG_Location = 0x30000000,
191 #endif
192     PERF_LOG_Command  = 0x40000000,  /* - 0x70000000 */
193     /* 2 or 3 arguments */
194     PERF_LOG_Buffer   = 0x80000000,  /* - 0xF0000000 */
195 
196     /* flags and masks */
197     PERF_LOG_Mask     = 0xF0000000,
198     PERF_LOG_NotMask  = ~PERF_LOG_Mask,
199     PERF_LOG_Mask2    = 0xFC000000,
200     PERF_LOG_NotMask2 = ~PERF_LOG_Mask2,
201     PERF_LOG_Frame    = 0x00000002,
202     PERF_LOG_Multiple = 0x00000001,
203 
204     /* NOTE: we identify xfer buffer from upper 2 bits (11) */
205     PERF_LOG_Xfering  = 0x40000000,
206     /* NOTE: we identify other buffer logs from upper 4 bits (1000 or 1011) */
207     PERF_LOG_Sending  = 0x30000000,
208 };
209 
210 
211 #ifdef __PERF_LOG_LOCATION__
212 
213 /* PERF log locations are encoded in 6-bits/char.  The last 20 characters of
214    the filename and functionname are saved (20*6*2 bits), along with the last
215    12 bits of the line.  4-bit log stamp makes this 240+12+4=256 bits.  */
216 
217 /* __PERF_ENCODE_CHAR converts a character to a 6-bit value:
218     a-z => 0-25
219     A-Z => 26-51
220     1-9 => 52-60
221       0 => 'O' (41)
222       . => 61
223     /,\ => 62
224  else,_ => 63         */
225 #define __PERF_ENCODE_CHAR(c) \
226    ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 'a')      : \
227      ((c) >= 'A' && (c) <= 'Z') ? ((c) - 'A' + 26) : \
228      ((c) >= '1' && (c) <= '9') ? ((c) - '1' + 52) : \
229                      (c) == '.' ? 61 :               \
230                      (c) == '0' ? ('O' - 'A' + 26) : \
231     ((c) == '/' || (c) == '\\') ? 62 : 63 )
232 
233 /* Get the i-th character from the end of a string, or '/' if i is too big */
234 #define __PERF_GET_INDEXED_CHAR(sz, i) (strlen(sz) <= i ? '/' : sz[strlen(sz) - i - 1])
235 
236 /* Encode i-th character of a string (from the end) */
237 #define __PERF_ENCODE_INDEXED(sz, i) \
238     __PERF_ENCODE_CHAR(__PERF_GET_INDEXED_CHAR(sz, i))
239 
240 /* Encode and pack 6 characters into 32 bits.  Only the left 2 bits of the
241    6th character will fit */
242 #define __PERF_PACK6(a1,a2,a3,a4,a5,a6) \
243     (((unsigned long) (a1))        | \
244     (((unsigned long) (a2)) << 6)  | \
245     (((unsigned long) (a3)) << 12) | \
246     (((unsigned long) (a4)) << 18) | \
247     (((unsigned long) (a5)) << 24) | \
248    ((((unsigned long) (a6)) & 0x30) << 26))
249 
250 #endif
251 
252 /* ============================================================================
253    PERF LOG External methods
254 ============================================================================ */
255 
256 extern void __PERF_LOG_log_common(PERF_Private *perf, unsigned long *time_loc);
257 
258 /* ============================================================================
259    PERF LOG Inline methods
260 ============================================================================ */
261 #if defined(__PERF_C__) || defined(INLINE_SUPPORTED)
262 
263 /* Effects: logs 1 data */
__PERF_log1(PERF_Private * priv,unsigned long ulData1)264 INLINE void __PERF_log1(PERF_Private *priv,
265                         unsigned long ulData1)
266 {
267     /* get log private structures */
268     PERF_LOG_Private *me   = priv->pLog;
269     unsigned long *time_loc = me->puPtr++;
270 
271     *me->puPtr++ = ulData1;
272     __PERF_LOG_log_common(priv, time_loc);
273 }
274 
275 /* Effects: logs 2 data */
__PERF_log2(PERF_Private * priv,unsigned long ulData1,unsigned long ulData2)276 INLINE void __PERF_log2(PERF_Private *priv,
277                         unsigned long ulData1,
278                         unsigned long ulData2)
279 {
280     /* get log private structures */
281     PERF_LOG_Private *me   = priv->pLog;
282     unsigned long *time_loc = me->puPtr++;
283 
284     *me->puPtr++ = ulData1;
285     *me->puPtr++ = ulData2;
286     __PERF_LOG_log_common(priv, time_loc);
287 }
288 
289 /* Effects: logs 3 data */
__PERF_log3(PERF_Private * priv,unsigned long ulData1,unsigned long ulData2,unsigned long ulData3)290 INLINE void __PERF_log3(PERF_Private *priv,
291                         unsigned long ulData1,
292                         unsigned long ulData2,
293                         unsigned long ulData3)
294 {
295     /* get log private structures */
296     PERF_LOG_Private *me   = priv->pLog;
297     unsigned long *time_loc = me->puPtr++;
298 
299     *me->puPtr++ = ulData1;
300     *me->puPtr++ = ulData2;
301     *me->puPtr++ = ulData3;
302     __PERF_LOG_log_common(priv, time_loc);
303 }
304 
305 #ifdef __PERF_LOG_LOCATION__
306 
307 void __PERF_LOG_flush(PERF_LOG_Private *me);
308 
309 /* Effects: logs 3 data */
310 INLINE void
__PERF_log8(PERF_Private * priv,unsigned long ulData1,unsigned long ulData2,unsigned long ulData3,unsigned long ulData4,unsigned long ulData5,unsigned long ulData6,unsigned long ulData7,unsigned long ulData8)311 __PERF_log8(PERF_Private *priv,
312             unsigned long ulData1,
313             unsigned long ulData2,
314             unsigned long ulData3,
315             unsigned long ulData4,
316             unsigned long ulData5,
317             unsigned long ulData6,
318             unsigned long ulData7,
319             unsigned long ulData8)
320 {
321     /* get log private structures */
322     PERF_LOG_Private *me   = priv->pLog;
323 
324     *me->puPtr++ = ulData8;
325     *me->puPtr++ = (ulData1 & PERF_LOG_NotMask) | PERF_LOG_Location;
326     *me->puPtr++ = ulData2;
327     *me->puPtr++ = ulData3;
328     *me->puPtr++ = ulData4;
329     *me->puPtr++ = ulData5;
330     *me->puPtr++ = ulData6;
331     *me->puPtr++ = ulData7;
332 
333     /* flush if we reached end of the buffer */
334     if (me->puPtr > me->puEnd) __PERF_LOG_flush(me);
335 }
336 
337 INLINE void
__PERF_LOG_Location(PERF_OBJHANDLE hObject,const char * szFile,unsigned long ulLine,const char * szFunc)338 __PERF_LOG_Location(PERF_OBJHANDLE hObject,
339                     const char *szFile,
340                     unsigned long ulLine,
341                     const char *szFunc)
342 {
343     if (hObject)
344     {
345         unsigned long a6  = __PERF_ENCODE_INDEXED(szFile, 5);
346         unsigned long a12 = __PERF_ENCODE_INDEXED(szFile, 11);
347         unsigned long a18 = __PERF_ENCODE_INDEXED(szFile, 17);
348         unsigned long b6  = __PERF_ENCODE_INDEXED(szFunc, 5);
349         unsigned long b12 = __PERF_ENCODE_INDEXED(szFunc, 11);
350         unsigned long b18 = __PERF_ENCODE_INDEXED(szFunc, 17);
351 
352         /* get log private structures */
353         __PERF_log8(get_Private(hObject),
354                     (a18 & 0xf) | ((b6 & 0xf) << 4) | ((b12 & 0xf) << 8) |
355                     ((b18 & 0xf) << 12) | ((ulLine & 0xfff) << 16),
356                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 0),
357                                  __PERF_ENCODE_INDEXED(szFile, 1),
358                                  __PERF_ENCODE_INDEXED(szFile, 2),
359                                  __PERF_ENCODE_INDEXED(szFile, 3),
360                                  __PERF_ENCODE_INDEXED(szFile, 4), a6),
361                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 6),
362                                  __PERF_ENCODE_INDEXED(szFile, 7),
363                                  __PERF_ENCODE_INDEXED(szFile, 8),
364                                  __PERF_ENCODE_INDEXED(szFile, 9),
365                                  __PERF_ENCODE_INDEXED(szFile, 10), a12),
366                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 12),
367                                  __PERF_ENCODE_INDEXED(szFile, 13),
368                                  __PERF_ENCODE_INDEXED(szFile, 14),
369                                  __PERF_ENCODE_INDEXED(szFile, 15),
370                                  __PERF_ENCODE_INDEXED(szFile, 16), a18),
371                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 0),
372                                  __PERF_ENCODE_INDEXED(szFunc, 1),
373                                  __PERF_ENCODE_INDEXED(szFunc, 2),
374                                  __PERF_ENCODE_INDEXED(szFunc, 3),
375                                  __PERF_ENCODE_INDEXED(szFunc, 4), b6),
376                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 6),
377                                  __PERF_ENCODE_INDEXED(szFunc, 7),
378                                  __PERF_ENCODE_INDEXED(szFunc, 8),
379                                  __PERF_ENCODE_INDEXED(szFunc, 9),
380                                  __PERF_ENCODE_INDEXED(szFunc, 10), b12),
381                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 12),
382                                  __PERF_ENCODE_INDEXED(szFunc, 13),
383                                  __PERF_ENCODE_INDEXED(szFunc, 14),
384                                  __PERF_ENCODE_INDEXED(szFunc, 15),
385                                  __PERF_ENCODE_INDEXED(szFunc, 16), b18),
386                     __PERF_ENCODE_INDEXED(szFile, 18) |
387                     (__PERF_ENCODE_INDEXED(szFile, 19) << 6)  |
388                     (__PERF_ENCODE_INDEXED(szFunc, 18) << 12) |
389                     (__PERF_ENCODE_INDEXED(szFunc, 19) << 18) |
390                     ((a6 & 0xf) << 24) | ((a12 & 0xf) << 28) );
391     }
392 }
393 
394 #endif
395 
396 #else
397 
398 extern void __PERF_log1(PERF_Private *priv,
399                         unsigned long ulData1);
400 extern void __PERF_log2(PERF_Private *priv,
401                         unsigned long ulData1,
402                         unsigned long ulData2);
403 extern void __PERF_log3(PERF_Private *priv,
404                         unsigned long ulData1,
405                         unsigned long ulData2,
406                         unsigned long ulData3);
407 
408 #ifdef __PERF_LOG_LOCATION__
409 
410 extern void __PERF_log8(PERF_Private *priv,
411                         unsigned long ulData1,
412                         unsigned long ulData2,
413                         unsigned long ulData3,
414                         unsigned long ulData4,
415                         unsigned long ulData5,
416                         unsigned long ulData6,
417                         unsigned long ulData7,
418                         unsigned long ulData8);
419 
420 
421 #define __PERF_LOG_Location(hObject, szFile, ulLine, szFunc)           \
422 do                                                                     \
423 {                                                                      \
424     if (hObject)                                                       \
425     {                                                                  \
426         unsigned long a6  = __PERF_ENCODE_INDEXED(szFile, 5);          \
427         unsigned long a12 = __PERF_ENCODE_INDEXED(szFile, 11);         \
428         unsigned long a18 = __PERF_ENCODE_INDEXED(szFile, 17);         \
429         unsigned long b6  = __PERF_ENCODE_INDEXED(szFunc, 5);          \
430         unsigned long b12 = __PERF_ENCODE_INDEXED(szFunc, 11);         \
431         unsigned long b18 = __PERF_ENCODE_INDEXED(szFunc, 17);         \
432                                                                        \
433         __PERF_log8(get_Private(hObject),                              \
434                     (a18 & 0xf)        | ((b6 & 0xf) << 4)   |         \
435                     ((b12 & 0xf) << 8) | ((b18 & 0xf) << 12) |         \
436                     ((ulLine & 0xfff) << 16),                          \
437                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 0),     \
438                               __PERF_ENCODE_INDEXED(szFile, 1),        \
439                               __PERF_ENCODE_INDEXED(szFile, 2),        \
440                               __PERF_ENCODE_INDEXED(szFile, 3),        \
441                               __PERF_ENCODE_INDEXED(szFile, 4), a6),   \
442                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 6),     \
443                               __PERF_ENCODE_INDEXED(szFile, 7),        \
444                               __PERF_ENCODE_INDEXED(szFile, 8),        \
445                               __PERF_ENCODE_INDEXED(szFile, 9),        \
446                               __PERF_ENCODE_INDEXED(szFile, 10), a12), \
447                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 12),    \
448                               __PERF_ENCODE_INDEXED(szFile, 13),       \
449                               __PERF_ENCODE_INDEXED(szFile, 14),       \
450                               __PERF_ENCODE_INDEXED(szFile, 15),       \
451                               __PERF_ENCODE_INDEXED(szFile, 16), a18), \
452                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 0),     \
453                               __PERF_ENCODE_INDEXED(szFunc, 1),        \
454                               __PERF_ENCODE_INDEXED(szFunc, 2),        \
455                               __PERF_ENCODE_INDEXED(szFunc, 3),        \
456                               __PERF_ENCODE_INDEXED(szFunc, 4), b6),   \
457                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 6),     \
458                               __PERF_ENCODE_INDEXED(szFunc, 7),        \
459                               __PERF_ENCODE_INDEXED(szFunc, 8),        \
460                               __PERF_ENCODE_INDEXED(szFunc, 9),        \
461                               __PERF_ENCODE_INDEXED(szFunc, 10), b12), \
462                     __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 12),    \
463                               __PERF_ENCODE_INDEXED(szFunc, 13),       \
464                               __PERF_ENCODE_INDEXED(szFunc, 14),       \
465                               __PERF_ENCODE_INDEXED(szFunc, 15),       \
466                               __PERF_ENCODE_INDEXED(szFunc, 16), b18), \
467                     __PERF_ENCODE_INDEXED(szFile, 18) |                \
468                     (__PERF_ENCODE_INDEXED(szFile, 19) << 6)  |        \
469                     (__PERF_ENCODE_INDEXED(szFunc, 18) << 12) |        \
470                     (__PERF_ENCODE_INDEXED(szFunc, 19) << 18) |        \
471                     ((a6 & 0xf) << 24) |  ((a12 & 0xf) << 28));        \
472     }                                                                  \
473 }                                                                      \
474 while (0);
475 
476 #endif
477 
478 #endif
479 
480