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 */
25union __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 */
166typedef 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 */
178enum 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
256extern 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 */
264INLINE 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 */
276INLINE 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 */
290INLINE 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
307void __PERF_LOG_flush(PERF_LOG_Private *me);
308
309/* Effects: logs 3 data */
310INLINE void
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
337INLINE void
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
398extern void __PERF_log1(PERF_Private *priv,
399                        unsigned long ulData1);
400extern void __PERF_log2(PERF_Private *priv,
401                        unsigned long ulData1,
402                        unsigned long ulData2);
403extern 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
410extern 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)           \
422do                                                                     \
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}                                                                      \
474while (0);
475
476#endif
477
478#endif
479
480