xref: /OK3568_Linux_fs/external/rkwifibt/drivers/infineon/include/event_log.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * EVENT_LOG system definitions
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 1999-2017, Broadcom Corporation
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *      Unless you and Broadcom execute a separate written software license
9*4882a593Smuzhiyun  * agreement governing use of this software, this software is licensed to you
10*4882a593Smuzhiyun  * under the terms of the GNU General Public License version 2 (the "GPL"),
11*4882a593Smuzhiyun  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
12*4882a593Smuzhiyun  * following added to such license:
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *      As a special exception, the copyright holders of this software give you
15*4882a593Smuzhiyun  * permission to link this software with independent modules, and to copy and
16*4882a593Smuzhiyun  * distribute the resulting executable under terms of your choice, provided that
17*4882a593Smuzhiyun  * you also meet, for each linked independent module, the terms and conditions of
18*4882a593Smuzhiyun  * the license of that module.  An independent module is a module which is not
19*4882a593Smuzhiyun  * derived from this software.  The special exception does not apply to any
20*4882a593Smuzhiyun  * modifications of the software.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  *      Notwithstanding the above, under no circumstances may you combine this
23*4882a593Smuzhiyun  * software in any way with any other Broadcom software provided under a license
24*4882a593Smuzhiyun  * other than the GPL, without Broadcom's express prior written consent.
25*4882a593Smuzhiyun  *
26*4882a593Smuzhiyun  *
27*4882a593Smuzhiyun  * <<Broadcom-WL-IPTag/Open:>>
28*4882a593Smuzhiyun  *
29*4882a593Smuzhiyun  * $Id: event_log.h 692339 2017-03-27 17:04:27Z $
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #ifndef _EVENT_LOG_H_
33*4882a593Smuzhiyun #define _EVENT_LOG_H_
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #include <typedefs.h>
36*4882a593Smuzhiyun #include <event_log_set.h>
37*4882a593Smuzhiyun #include <event_log_tag.h>
38*4882a593Smuzhiyun #include <event_log_payload.h>
39*4882a593Smuzhiyun #include <osl_decl.h>
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /* logstrs header */
42*4882a593Smuzhiyun #define LOGSTRS_MAGIC   0x4C4F4753
43*4882a593Smuzhiyun #define LOGSTRS_VERSION 0x1
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /* We make sure that the block size will fit in a single packet
46*4882a593Smuzhiyun  *  (allowing for a bit of overhead on each packet
47*4882a593Smuzhiyun  */
48*4882a593Smuzhiyun #if defined(BCMPCIEDEV)
49*4882a593Smuzhiyun #define EVENT_LOG_MAX_BLOCK_SIZE	1648
50*4882a593Smuzhiyun #else
51*4882a593Smuzhiyun #define EVENT_LOG_MAX_BLOCK_SIZE	1400
52*4882a593Smuzhiyun #endif // endif
53*4882a593Smuzhiyun #define EVENT_LOG_WL_BLOCK_SIZE		0x200
54*4882a593Smuzhiyun #define EVENT_LOG_PSM_BLOCK_SIZE	0x200
55*4882a593Smuzhiyun #define EVENT_LOG_BUS_BLOCK_SIZE	0x200
56*4882a593Smuzhiyun #define EVENT_LOG_ERROR_BLOCK_SIZE	0x200
57*4882a593Smuzhiyun /* Maximum event log record payload size = 1016 bytes or 254 words. */
58*4882a593Smuzhiyun #define EVENT_LOG_MAX_RECORD_PAYLOAD_SIZE	254
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /*
61*4882a593Smuzhiyun  * There are multiple levels of objects define here:
62*4882a593Smuzhiyun  *   event_log_set - a set of buffers
63*4882a593Smuzhiyun  *   event log groups - every event log call is part of just one.  All
64*4882a593Smuzhiyun  *                      event log calls in a group are handled the
65*4882a593Smuzhiyun  *                      same way.  Each event log group is associated
66*4882a593Smuzhiyun  *                      with an event log set or is off.
67*4882a593Smuzhiyun  */
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun #ifndef __ASSEMBLER__
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /* On the external system where the dumper is we need to make sure
72*4882a593Smuzhiyun  * that these types are the same size as they are on the ARM the
73*4882a593Smuzhiyun  * produced them
74*4882a593Smuzhiyun  */
75*4882a593Smuzhiyun #ifdef EVENT_LOG_DUMPER
76*4882a593Smuzhiyun #define _EL_BLOCK_PTR uint32
77*4882a593Smuzhiyun #define _EL_TYPE_PTR uint32
78*4882a593Smuzhiyun #define _EL_SET_PTR uint32
79*4882a593Smuzhiyun #define _EL_TOP_PTR uint32
80*4882a593Smuzhiyun #else
81*4882a593Smuzhiyun #define _EL_BLOCK_PTR struct event_log_block *
82*4882a593Smuzhiyun #define _EL_TYPE_PTR uint32 *
83*4882a593Smuzhiyun #define _EL_SET_PTR struct event_log_set **
84*4882a593Smuzhiyun #define _EL_TOP_PTR struct event_log_top *
85*4882a593Smuzhiyun #endif /* EVENT_LOG_DUMPER */
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun /* Event log sets (a logical circurlar buffer) consist of one or more
88*4882a593Smuzhiyun  * event_log_blocks.  The blocks themselves form a logical circular
89*4882a593Smuzhiyun  * list.  The log entries are placed in each event_log_block until it
90*4882a593Smuzhiyun  * is full.  Logging continues with the next event_log_block in the
91*4882a593Smuzhiyun  * event_set until the last event_log_block is reached and then
92*4882a593Smuzhiyun  * logging starts over with the first event_log_block in the
93*4882a593Smuzhiyun  * event_set.
94*4882a593Smuzhiyun  */
95*4882a593Smuzhiyun typedef struct event_log_block {
96*4882a593Smuzhiyun 	_EL_BLOCK_PTR next_block;
97*4882a593Smuzhiyun 	_EL_BLOCK_PTR prev_block;
98*4882a593Smuzhiyun 	_EL_TYPE_PTR end_ptr;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	/* Start of packet sent for log tracing */
101*4882a593Smuzhiyun 	uint16 pktlen;			/* Size of rest of block */
102*4882a593Smuzhiyun 	uint16 count;			/* Logtrace counter */
103*4882a593Smuzhiyun 	uint32 extra_hdr_info;		/* LSB: 6 bits set id. MSB 24 bits reserved */
104*4882a593Smuzhiyun 	uint32 event_logs;
105*4882a593Smuzhiyun } event_log_block_t;
106*4882a593Smuzhiyun #define EVENT_LOG_BLOCK_HDRLEN		8 /* pktlen 2 + count 2 + extra_hdr_info 4 */
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun #define EVENT_LOG_BLOCK_LEN 12
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun typedef enum {
111*4882a593Smuzhiyun 	SET_DESTINATION_INVALID = -1,
112*4882a593Smuzhiyun 	SET_DESTINATION_HOST = 0,
113*4882a593Smuzhiyun 	SET_DESTINATION_NONE = 1,
114*4882a593Smuzhiyun 	SET_DESTINATION_MAX
115*4882a593Smuzhiyun } event_log_set_destination_t;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun /* There can be multiple event_sets with each logging a set of
118*4882a593Smuzhiyun  * associated events (i.e, "fast" and "slow" events).
119*4882a593Smuzhiyun  */
120*4882a593Smuzhiyun typedef struct event_log_set {
121*4882a593Smuzhiyun 	_EL_BLOCK_PTR first_block; 	/* Pointer to first event_log block */
122*4882a593Smuzhiyun 	_EL_BLOCK_PTR last_block; 	/* Pointer to last event_log block */
123*4882a593Smuzhiyun 	_EL_BLOCK_PTR logtrace_block;	/* next block traced */
124*4882a593Smuzhiyun 	_EL_BLOCK_PTR cur_block;   	/* Pointer to current event_log block */
125*4882a593Smuzhiyun 	_EL_TYPE_PTR cur_ptr;      	/* Current event_log pointer */
126*4882a593Smuzhiyun 	uint32 blockcount;		/* Number of blocks */
127*4882a593Smuzhiyun 	uint16 logtrace_count;		/* Last count for logtrace */
128*4882a593Smuzhiyun 	uint16 blockfill_count;		/* Fill count for logtrace */
129*4882a593Smuzhiyun 	uint32 timestamp;		/* Last timestamp event */
130*4882a593Smuzhiyun 	uint32 cyclecount;		/* Cycles at last timestamp event */
131*4882a593Smuzhiyun 	event_log_set_destination_t destination;
132*4882a593Smuzhiyun 	uint16 size;			/* same size for all buffers in one  set */
133*4882a593Smuzhiyun } event_log_set_t;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun /* logstr_hdr_flags */
136*4882a593Smuzhiyun #define LOGSTRS_ENCRYPTED 0x1
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun /* Top data structure for access to everything else */
139*4882a593Smuzhiyun typedef struct event_log_top {
140*4882a593Smuzhiyun 	uint32 magic;
141*4882a593Smuzhiyun #define EVENT_LOG_TOP_MAGIC 0x474C8669 /* 'EVLG' */
142*4882a593Smuzhiyun 	uint32 version;
143*4882a593Smuzhiyun #define EVENT_LOG_VERSION 1
144*4882a593Smuzhiyun 	uint32 num_sets;
145*4882a593Smuzhiyun 	uint32 logstrs_size;		/* Size of lognums + logstrs area */
146*4882a593Smuzhiyun 	uint32 timestamp;		/* Last timestamp event */
147*4882a593Smuzhiyun 	uint32 cyclecount;		/* Cycles at last timestamp event */
148*4882a593Smuzhiyun 	_EL_SET_PTR sets;		/* Ptr to array of <num_sets> set ptrs */
149*4882a593Smuzhiyun } event_log_top_t;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun /* structure of the trailing 3 words in logstrs.bin */
152*4882a593Smuzhiyun typedef struct {
153*4882a593Smuzhiyun 	uint32 fw_id;		/* FWID will be written by tool later */
154*4882a593Smuzhiyun 	uint32 flags;		/* 0th bit indicates whether encrypted or not */
155*4882a593Smuzhiyun 	/* Keep version and magic last since "header" is appended to the end of logstrs file. */
156*4882a593Smuzhiyun 	uint32 version;		/* Header version */
157*4882a593Smuzhiyun 	uint32 log_magic;	/* MAGIC number for verification 'LOGS' */
158*4882a593Smuzhiyun } logstr_trailer_t;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /* Data structure of Keeping the Header from logstrs.bin */
161*4882a593Smuzhiyun typedef struct {
162*4882a593Smuzhiyun 	uint32 logstrs_size;    /* Size of the file */
163*4882a593Smuzhiyun 	uint32 rom_lognums_offset; /* Offset to the ROM lognum */
164*4882a593Smuzhiyun 	uint32 ram_lognums_offset; /* Offset to the RAM lognum */
165*4882a593Smuzhiyun 	uint32 rom_logstrs_offset; /* Offset to the ROM logstr */
166*4882a593Smuzhiyun 	uint32 ram_logstrs_offset; /* Offset to the RAM logstr */
167*4882a593Smuzhiyun 	logstr_trailer_t trailer;
168*4882a593Smuzhiyun } logstr_header_t;
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun /* Ver 1 Header from logstrs.bin */
171*4882a593Smuzhiyun typedef struct {
172*4882a593Smuzhiyun 	uint32 logstrs_size;    /* Size of the file */
173*4882a593Smuzhiyun 	uint32 rom_lognums_offset; /* Offset to the ROM lognum */
174*4882a593Smuzhiyun 	uint32 ram_lognums_offset; /* Offset to the RAM lognum */
175*4882a593Smuzhiyun 	uint32 rom_logstrs_offset; /* Offset to the ROM logstr */
176*4882a593Smuzhiyun 	uint32 ram_logstrs_offset; /* Offset to the RAM logstr */
177*4882a593Smuzhiyun 	/* Keep version and magic last since "header" is appended to the end of logstrs file. */
178*4882a593Smuzhiyun 	uint32 version;            /* Header version */
179*4882a593Smuzhiyun 	uint32 log_magic;       /* MAGIC number for verification 'LOGS' */
180*4882a593Smuzhiyun } logstr_header_v1_t;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun /*
183*4882a593Smuzhiyun  * Use the following macros for generating log events.
184*4882a593Smuzhiyun  *
185*4882a593Smuzhiyun  * The FAST versions check the enable of the tag before evaluating the arguments and calling the
186*4882a593Smuzhiyun  * event_log function.  This adds 5 instructions.  The COMPACT versions evaluate the arguments
187*4882a593Smuzhiyun  * and call the event_log function unconditionally.  The event_log function will then skip logging
188*4882a593Smuzhiyun  * if this tag is disabled.
189*4882a593Smuzhiyun  *
190*4882a593Smuzhiyun  * To support easy usage of existing debugging (e.g. msglevel) via macro re-definition there are
191*4882a593Smuzhiyun  * two variants of these macros to help.
192*4882a593Smuzhiyun  *
193*4882a593Smuzhiyun  * First there are the CAST versions.  The event_log function normally logs uint32 values or else
194*4882a593Smuzhiyun  * they have to be cast to uint32.  The CAST versions blindly cast for you so you don't have to edit
195*4882a593Smuzhiyun  * any existing code.
196*4882a593Smuzhiyun  *
197*4882a593Smuzhiyun  * Second there are the PAREN_ARGS versions.  These expect the logging format string and arguments
198*4882a593Smuzhiyun  * to be enclosed in parentheses.  This allows us to make the following mapping of an existing
199*4882a593Smuzhiyun  * msglevel macro:
200*4882a593Smuzhiyun  *  #define WL_ERROR(args)   EVENT_LOG_CAST_PAREN_ARGS(EVENT_LOG_TAG_WL_ERROR, args)
201*4882a593Smuzhiyun  *
202*4882a593Smuzhiyun  * The versions of the macros without FAST or COMPACT in their name are just synonyms for the
203*4882a593Smuzhiyun  * COMPACT versions.
204*4882a593Smuzhiyun  *
205*4882a593Smuzhiyun  * You should use the COMPACT macro (or its synonym) in cases where there is some preceding logic
206*4882a593Smuzhiyun  * that prevents the execution of the macro, e.g. WL_ERROR by definition rarely gets executed.
207*4882a593Smuzhiyun  * Use the FAST macro in performance sensitive paths. The key concept here is that you should be
208*4882a593Smuzhiyun  * assuming that your macro usage is compiled into ROM and can't be changed ... so choose wisely.
209*4882a593Smuzhiyun  *
210*4882a593Smuzhiyun  */
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun #if !defined(EVENT_LOG_DUMPER)
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun #ifndef EVENT_LOG_COMPILE
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun /* Null define if no tracing */
217*4882a593Smuzhiyun #define EVENT_LOG(format, ...)
218*4882a593Smuzhiyun #define EVENT_LOG_FAST(tag, fmt, ...)
219*4882a593Smuzhiyun #define EVENT_LOG_COMPACT(tag, fmt, ...)
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun #define EVENT_LOG_CAST(tag, fmt, ...)
222*4882a593Smuzhiyun #define EVENT_LOG_FAST_CAST(tag, fmt, ...)
223*4882a593Smuzhiyun #define EVENT_LOG_COMPACT_CAST(tag, fmt, ...)
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun #define EVENT_LOG_CAST_PAREN_ARGS(tag, pargs)
226*4882a593Smuzhiyun #define EVENT_LOG_FAST_CAST_PAREN_ARGS(tag, pargs)
227*4882a593Smuzhiyun #define EVENT_LOG_COMPACT_CAST_PAREN_ARGS(tag, pargs)
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun #define EVENT_LOG_IS_ON(tag)		0
230*4882a593Smuzhiyun #define EVENT_LOG_IS_LOG_ON(tag)	0
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun #define EVENT_LOG_BUFFER(tag, buf, size)
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun #else  /* EVENT_LOG_COMPILE */
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun /* The first few are special because they can be done more efficiently
237*4882a593Smuzhiyun  * this way and they are the common case.  Once there are too many
238*4882a593Smuzhiyun  * parameters the code size starts to be an issue and a loop is better
239*4882a593Smuzhiyun  */
240*4882a593Smuzhiyun #define _EVENT_LOG0(tag, fmt_num) 			\
241*4882a593Smuzhiyun 	event_log0(tag, fmt_num)
242*4882a593Smuzhiyun #define _EVENT_LOG1(tag, fmt_num, t1) 			\
243*4882a593Smuzhiyun 	event_log1(tag, fmt_num, t1)
244*4882a593Smuzhiyun #define _EVENT_LOG2(tag, fmt_num, t1, t2) 		\
245*4882a593Smuzhiyun 	event_log2(tag, fmt_num, t1, t2)
246*4882a593Smuzhiyun #define _EVENT_LOG3(tag, fmt_num, t1, t2, t3) 		\
247*4882a593Smuzhiyun 	event_log3(tag, fmt_num, t1, t2, t3)
248*4882a593Smuzhiyun #define _EVENT_LOG4(tag, fmt_num, t1, t2, t3, t4) 	\
249*4882a593Smuzhiyun 	event_log4(tag, fmt_num, t1, t2, t3, t4)
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun /* The rest call the generic routine that takes a count */
252*4882a593Smuzhiyun #define _EVENT_LOG5(tag, fmt_num, ...) event_logn(5, tag, fmt_num, __VA_ARGS__)
253*4882a593Smuzhiyun #define _EVENT_LOG6(tag, fmt_num, ...) event_logn(6, tag, fmt_num, __VA_ARGS__)
254*4882a593Smuzhiyun #define _EVENT_LOG7(tag, fmt_num, ...) event_logn(7, tag, fmt_num, __VA_ARGS__)
255*4882a593Smuzhiyun #define _EVENT_LOG8(tag, fmt_num, ...) event_logn(8, tag, fmt_num, __VA_ARGS__)
256*4882a593Smuzhiyun #define _EVENT_LOG9(tag, fmt_num, ...) event_logn(9, tag, fmt_num, __VA_ARGS__)
257*4882a593Smuzhiyun #define _EVENT_LOGA(tag, fmt_num, ...) event_logn(10, tag, fmt_num, __VA_ARGS__)
258*4882a593Smuzhiyun #define _EVENT_LOGB(tag, fmt_num, ...) event_logn(11, tag, fmt_num, __VA_ARGS__)
259*4882a593Smuzhiyun #define _EVENT_LOGC(tag, fmt_num, ...) event_logn(12, tag, fmt_num, __VA_ARGS__)
260*4882a593Smuzhiyun #define _EVENT_LOGD(tag, fmt_num, ...) event_logn(13, tag, fmt_num, __VA_ARGS__)
261*4882a593Smuzhiyun #define _EVENT_LOGE(tag, fmt_num, ...) event_logn(14, tag, fmt_num, __VA_ARGS__)
262*4882a593Smuzhiyun #define _EVENT_LOGF(tag, fmt_num, ...) event_logn(15, tag, fmt_num, __VA_ARGS__)
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun /* Casting  low level macros */
265*4882a593Smuzhiyun #define _EVENT_LOG_CAST0(tag, fmt_num)			\
266*4882a593Smuzhiyun 	event_log0(tag, fmt_num)
267*4882a593Smuzhiyun #define _EVENT_LOG_CAST1(tag, fmt_num, t1)		\
268*4882a593Smuzhiyun 	event_log1(tag, fmt_num, (uint32)(t1))
269*4882a593Smuzhiyun #define _EVENT_LOG_CAST2(tag, fmt_num, t1, t2)		\
270*4882a593Smuzhiyun 	event_log2(tag, fmt_num, (uint32)(t1), (uint32)(t2))
271*4882a593Smuzhiyun #define _EVENT_LOG_CAST3(tag, fmt_num, t1, t2, t3)	\
272*4882a593Smuzhiyun 	event_log3(tag, fmt_num, (uint32)(t1), (uint32)(t2), (uint32)(t3))
273*4882a593Smuzhiyun #define _EVENT_LOG_CAST4(tag, fmt_num, t1, t2, t3, t4)	\
274*4882a593Smuzhiyun 	event_log4(tag, fmt_num, (uint32)(t1), (uint32)(t2), (uint32)(t3), (uint32)(t4))
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun /* The rest call the generic routine that takes a count */
277*4882a593Smuzhiyun #define _EVENT_LOG_CAST5(tag, fmt_num, ...) _EVENT_LOG5(tag, fmt_num, __VA_ARGS__)
278*4882a593Smuzhiyun #define _EVENT_LOG_CAST6(tag, fmt_num, ...) _EVENT_LOG6(tag, fmt_num, __VA_ARGS__)
279*4882a593Smuzhiyun #define _EVENT_LOG_CAST7(tag, fmt_num, ...) _EVENT_LOG7(tag, fmt_num, __VA_ARGS__)
280*4882a593Smuzhiyun #define _EVENT_LOG_CAST8(tag, fmt_num, ...) _EVENT_LOG8(tag, fmt_num, __VA_ARGS__)
281*4882a593Smuzhiyun #define _EVENT_LOG_CAST9(tag, fmt_num, ...) _EVENT_LOG9(tag, fmt_num, __VA_ARGS__)
282*4882a593Smuzhiyun #define _EVENT_LOG_CASTA(tag, fmt_num, ...) _EVENT_LOGA(tag, fmt_num, __VA_ARGS__)
283*4882a593Smuzhiyun #define _EVENT_LOG_CASTB(tag, fmt_num, ...) _EVENT_LOGB(tag, fmt_num, __VA_ARGS__)
284*4882a593Smuzhiyun #define _EVENT_LOG_CASTC(tag, fmt_num, ...) _EVENT_LOGC(tag, fmt_num, __VA_ARGS__)
285*4882a593Smuzhiyun #define _EVENT_LOG_CASTD(tag, fmt_num, ...) _EVENT_LOGD(tag, fmt_num, __VA_ARGS__)
286*4882a593Smuzhiyun #define _EVENT_LOG_CASTE(tag, fmt_num, ...) _EVENT_LOGE(tag, fmt_num, __VA_ARGS__)
287*4882a593Smuzhiyun #define _EVENT_LOG_CASTF(tag, fmt_num, ...) _EVENT_LOGF(tag, fmt_num, __VA_ARGS__)
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun /* Hack to make the proper routine call when variadic macros get
290*4882a593Smuzhiyun  * passed.  Note the max of 15 arguments.  More than that can't be
291*4882a593Smuzhiyun  * handled by the event_log entries anyways so best to catch it at compile
292*4882a593Smuzhiyun  * time
293*4882a593Smuzhiyun  */
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun #define _EVENT_LOG_VA_NUM_ARGS(F, _1, _2, _3, _4, _5, _6, _7, _8, _9,	\
296*4882a593Smuzhiyun 			       _A, _B, _C, _D, _E, _F, N, ...) F ## N
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun /* cast = _EVENT_LOG for no casting
299*4882a593Smuzhiyun  * cast = _EVENT_LOG_CAST for casting of fmt arguments to uint32.
300*4882a593Smuzhiyun  *        Only first 4 arguments are casted to uint32. event_logn() is called
301*4882a593Smuzhiyun  *        if more than 4 arguments are present. This function internally assumes
302*4882a593Smuzhiyun  *        all arguments are uint32
303*4882a593Smuzhiyun  */
304*4882a593Smuzhiyun #define _EVENT_LOG(cast, tag, fmt, ...)					\
305*4882a593Smuzhiyun 	static char logstr[] __attribute__ ((section(".logstrs"))) = fmt; \
306*4882a593Smuzhiyun 	static uint32 fmtnum __attribute__ ((section(".lognums"))) = (uint32) &logstr; \
307*4882a593Smuzhiyun 	_EVENT_LOG_VA_NUM_ARGS(cast, ##__VA_ARGS__,			\
308*4882a593Smuzhiyun 			       F, E, D, C, B, A, 9, 8,			\
309*4882a593Smuzhiyun 			       7, 6, 5, 4, 3, 2, 1, 0)			\
310*4882a593Smuzhiyun 	(tag, (int) &fmtnum , ## __VA_ARGS__)
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun #define EVENT_LOG_FAST(tag, fmt, ...)					\
313*4882a593Smuzhiyun 	do {								\
314*4882a593Smuzhiyun 		if (event_log_tag_sets != NULL) {			\
315*4882a593Smuzhiyun 			uint8 tag_flag = *(event_log_tag_sets + tag);	\
316*4882a593Smuzhiyun 			if ((tag_flag & ~EVENT_LOG_TAG_FLAG_SET_MASK) != 0) {		\
317*4882a593Smuzhiyun 				_EVENT_LOG(_EVENT_LOG, tag, fmt , ## __VA_ARGS__);	\
318*4882a593Smuzhiyun 			}						\
319*4882a593Smuzhiyun 		}							\
320*4882a593Smuzhiyun 	} while (0)
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun #define EVENT_LOG_COMPACT(tag, fmt, ...)				\
323*4882a593Smuzhiyun 	do {								\
324*4882a593Smuzhiyun 		_EVENT_LOG(_EVENT_LOG, tag, fmt , ## __VA_ARGS__);	\
325*4882a593Smuzhiyun 	} while (0)
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun /* Event log macro with casting to uint32 of arguments */
328*4882a593Smuzhiyun #define EVENT_LOG_FAST_CAST(tag, fmt, ...)				\
329*4882a593Smuzhiyun 	do {								\
330*4882a593Smuzhiyun 		if (event_log_tag_sets != NULL) {			\
331*4882a593Smuzhiyun 			uint8 tag_flag = *(event_log_tag_sets + tag);	\
332*4882a593Smuzhiyun 			if ((tag_flag & ~EVENT_LOG_TAG_FLAG_SET_MASK) != 0) {		\
333*4882a593Smuzhiyun 				_EVENT_LOG(_EVENT_LOG_CAST, tag, fmt , ## __VA_ARGS__);	\
334*4882a593Smuzhiyun 			}						\
335*4882a593Smuzhiyun 		}							\
336*4882a593Smuzhiyun 	} while (0)
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun #define EVENT_LOG_COMPACT_CAST(tag, fmt, ...)				\
339*4882a593Smuzhiyun 	do {								\
340*4882a593Smuzhiyun 		_EVENT_LOG(_EVENT_LOG_CAST, tag, fmt , ## __VA_ARGS__);	\
341*4882a593Smuzhiyun 	} while (0)
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun #define EVENT_LOG(tag, fmt, ...) EVENT_LOG_COMPACT(tag, fmt , ## __VA_ARGS__)
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun #define EVENT_LOG_CAST(tag, fmt, ...) EVENT_LOG_COMPACT_CAST(tag, fmt , ## __VA_ARGS__)
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun #define _EVENT_LOG_REMOVE_PAREN(...) __VA_ARGS__
348*4882a593Smuzhiyun #define EVENT_LOG_REMOVE_PAREN(args) _EVENT_LOG_REMOVE_PAREN args
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun #define EVENT_LOG_CAST_PAREN_ARGS(tag, pargs)				\
351*4882a593Smuzhiyun 		EVENT_LOG_CAST(tag, EVENT_LOG_REMOVE_PAREN(pargs))
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun #define EVENT_LOG_FAST_CAST_PAREN_ARGS(tag, pargs)			\
354*4882a593Smuzhiyun 		EVENT_LOG_FAST_CAST(tag, EVENT_LOG_REMOVE_PAREN(pargs))
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun #define EVENT_LOG_COMPACT_CAST_PAREN_ARGS(tag, pargs)			\
357*4882a593Smuzhiyun 		EVENT_LOG_COMPACT_CAST(tag, EVENT_LOG_REMOVE_PAREN(pargs))
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun /* Minimal event logging. Event log internally calls event_logx()
360*4882a593Smuzhiyun  * log return address in caller.
361*4882a593Smuzhiyun  * Note that the if(0){..} below is to avoid compiler warnings
362*4882a593Smuzhiyun  * due to unused variables caused by this macro
363*4882a593Smuzhiyun  */
364*4882a593Smuzhiyun #define EVENT_LOG_RA(tag, args)						\
365*4882a593Smuzhiyun 	do {								\
366*4882a593Smuzhiyun 		if (0) {						\
367*4882a593Smuzhiyun 			EVENT_LOG_COMPACT_CAST_PAREN_ARGS(tag, args);	\
368*4882a593Smuzhiyun 		}							\
369*4882a593Smuzhiyun 		event_log_caller_return_address(tag);			\
370*4882a593Smuzhiyun 	} while (0)
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun #define EVENT_LOG_IS_ON(tag) (*(event_log_tag_sets + (tag)) & ~EVENT_LOG_TAG_FLAG_SET_MASK)
373*4882a593Smuzhiyun #define EVENT_LOG_IS_LOG_ON(tag) (*(event_log_tag_sets + (tag)) & EVENT_LOG_TAG_FLAG_LOG)
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun #define EVENT_LOG_BUFFER(tag, buf, size)	event_log_buffer(tag, buf, size)
376*4882a593Smuzhiyun #define EVENT_DUMP	event_log_buffer
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun extern uint8 *event_log_tag_sets;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun extern int event_log_init(osl_t *osh);
381*4882a593Smuzhiyun extern int event_log_set_init(osl_t *osh, int set_num, int size);
382*4882a593Smuzhiyun extern int event_log_set_expand(osl_t *osh, int set_num, int size);
383*4882a593Smuzhiyun extern int event_log_set_shrink(osl_t *osh, int set_num, int size);
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun extern int event_log_tag_start(int tag, int set_num, int flags);
386*4882a593Smuzhiyun extern int event_log_tag_set_retrieve(int tag);
387*4882a593Smuzhiyun extern int event_log_tag_stop(int tag);
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun typedef void (*event_log_logtrace_trigger_fn_t)(void *ctx);
390*4882a593Smuzhiyun void event_log_set_logtrace_trigger_fn(event_log_logtrace_trigger_fn_t fn, void *ctx);
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun event_log_top_t *event_log_get_top(void);
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun extern int event_log_get(int set_num, int buflen, void *buf);
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun extern uint8 *event_log_next_logtrace(int set_num);
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun extern void event_log0(int tag, int fmtNum);
399*4882a593Smuzhiyun extern void event_log1(int tag, int fmtNum, uint32 t1);
400*4882a593Smuzhiyun extern void event_log2(int tag, int fmtNum, uint32 t1, uint32 t2);
401*4882a593Smuzhiyun extern void event_log3(int tag, int fmtNum, uint32 t1, uint32 t2, uint32 t3);
402*4882a593Smuzhiyun extern void event_log4(int tag, int fmtNum, uint32 t1, uint32 t2, uint32 t3, uint32 t4);
403*4882a593Smuzhiyun extern void event_logn(int num_args, int tag, int fmtNum, ...);
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun extern void event_log_time_sync(uint32 ms);
406*4882a593Smuzhiyun extern void event_log_buffer(int tag, uint8 *buf, int size);
407*4882a593Smuzhiyun extern void event_log_caller_return_address(int tag);
408*4882a593Smuzhiyun extern int event_log_set_destination_set(int set, event_log_set_destination_t dest);
409*4882a593Smuzhiyun extern event_log_set_destination_t event_log_set_destination_get(int set);
410*4882a593Smuzhiyun extern int event_log_flush_log_buffer(int set);
411*4882a593Smuzhiyun extern uint16 event_log_get_available_space(int set);
412*4882a593Smuzhiyun extern bool event_log_is_set_configured(int set_num);
413*4882a593Smuzhiyun extern bool event_log_is_tag_valid(int tag);
414*4882a593Smuzhiyun /* returns number of blocks available for writing */
415*4882a593Smuzhiyun extern int event_log_free_blocks_get(int set);
416*4882a593Smuzhiyun extern bool event_log_is_ready(void);
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun #endif /* EVENT_LOG_DUMPER */
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun #endif /* EVENT_LOG_COMPILE */
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun #endif /* __ASSEMBLER__ */
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun #endif /* _EVENT_LOG_H_ */
425