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