1/*
2Copyright (c) 2013, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/** \file
29 * Multi-Media Abstraction Layer API
30 */
31#ifndef MMAL_VC_DBGLOG_H
32#define MMAL_VC_DBGLOG_H
33
34#include "interface/mmal/mmal.h"
35#include "mmal_vc_msgs.h"
36
37/* Debug log for MMAL messages going past */
38
39typedef enum {
40 MMAL_DBG_MSG,
41 MMAL_DBG_BULK,
42 MMAL_DBG_OPENED,
43 MMAL_DBG_CLOSED,
44 MMAL_DBG_BULK_ACK,
45 MMAL_DBG_BULK_TX,
46 MMAL_DBG_BULK_RX,
47} MMAL_DBG_EVENT_TYPE_T;
48
49
50/** Debug log data. */
51typedef union
52{
53 struct {
54 mmal_worker_msg_header header;
55 uint32_t msg[4]; /**< Snarf this much message data */
56 } msg;
57
58 struct {
59 uint32_t len; /**< Length of transfer */
60 uint32_t data[4]; /**< Snarf this much payload data */
61 } bulk;
62
63 uint32_t uint;
64
65 uint32_t arr[15]; /** Pad complete DBG_ENTRY_T to 64 bytes per line */
66
67} MMAL_DBG_DATA_T;
68
69/** One entry in the debug log */
70typedef struct
71{
72 uint32_t time;
73 uint32_t event_type;
74 MMAL_DBG_DATA_T u;
75} MMAL_DBG_ENTRY_T;
76
77#define MMAL_DBG_ENTRIES_MAX 64
78#define MMAL_DBG_ENTRIES_MASK (MMAL_DBG_ENTRIES_MAX-1)
79#define MMAL_DBG_VERSION 1
80
81/** The debug log itself. This is currently allocated in uncached
82 * memory so that the ARM can easily access it.
83 */
84typedef struct
85{
86 uint32_t version;
87 uint32_t magic;
88 uint32_t num_entries;
89 uint32_t index;
90 uint32_t size;
91 uint32_t elemsize;
92 uint32_t pad[2];
93 MMAL_DBG_ENTRY_T entries[MMAL_DBG_ENTRIES_MAX];
94
95} MMAL_DBG_LOG_T;
96
97extern VCOS_MUTEX_T mmal_dbg_lock;
98extern MMAL_DBG_LOG_T *mmal_dbg_log;
99
100/** Get the next event and hold the lock. Should only be
101 * accessed by the macros below.
102 */
103static inline MMAL_DBG_ENTRY_T *mmal_log_lock_event(MMAL_DBG_EVENT_TYPE_T event_type ) {
104 uint32_t index;
105 MMAL_DBG_ENTRY_T *entry;
106 vcos_mutex_lock(&mmal_dbg_lock);
107 index = mmal_dbg_log->index++;
108 entry = mmal_dbg_log->entries + (index & MMAL_DBG_ENTRIES_MASK);
109 entry->time = vcos_getmicrosecs();
110 entry->event_type = event_type;
111 return entry;
112}
113
114/** Release the lock. Should only be accessed by the macros below. */
115static inline void mmal_log_unlock_event(void) {
116 vcos_mutex_unlock(&mmal_dbg_lock);
117}
118
119/** Initialise the logging module. */
120MMAL_STATUS_T mmal_vc_dbglog_init(void);
121
122/** Deinitialise the logging module. */
123void mmal_vc_dbglog_deinit(void);
124
125/** Put an entry into the log.
126 *
127 * @param short_type type of event, e.g. OPENED
128 * @param name union entry name, e.g. uint.
129 * @param event event data
130 */
131#define MMAL_LOG_EVENT(short_type, name, value) {\
132 MMAL_DBG_ENTRY_T *entry = mmal_log_lock_event(MMAL_DBG_##short_type); \
133 entry->u.name = value;\
134 mmal_log_unlock_event(); \
135}
136
137/** Log an uint event (i.e. all just the fact that it occurred */
138#define LOG_EVENT_UINT(short_type,u) MMAL_LOG_EVENT(short_type, uint, u)
139
140#define LOG_EVENT_OPENED() LOG_EVENT_UINT(OPENED,0)
141#define LOG_EVENT_CLOSED() LOG_EVENT_UINT(CLOSED,0)
142#define LOG_EVENT_BULK_ACK(reason) LOG_EVENT_UINT(BULK_ACK,reason)
143
144/** Log a message. Grabs part of the message data.
145 */
146#define LOG_EVENT_MSG(header) {\
147 MMAL_DBG_ENTRY_T *entry = mmal_log_lock_event(MMAL_DBG_MSG); \
148 memcpy(&entry->u.msg, header, sizeof(entry->u.msg)); \
149 mmal_log_unlock_event(); \
150}
151
152/** Log bulk data. For now, do not grab the actual data itself */
153#define LOG_EVENT_BULK(type, len, data) {\
154 MMAL_DBG_ENTRY_T *entry = mmal_log_lock_event(MMAL_DBG_BULK_##type); \
155 entry->u.bulk.len = len; \
156 mmal_log_unlock_event(); \
157}
158
159
160#endif
161