1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 'use strict'; 6 7 /** 8 * @fileoverview Parses Mali DDK/kernel events in the Linux event trace format. 9 */ 10 base.require('tracing.importer.linux_perf.parser'); 11 base.exportTo('tracing.importer.linux_perf', function() { 12 13 var Parser = tracing.importer.linux_perf.Parser; 14 15 /** 16 * Parses Mali DDK/kernel trace events. 17 * @constructor 18 */ 19 function MaliParser(importer) { 20 Parser.call(this, importer); 21 22 // kernel DVFS events 23 importer.registerEventHandler('mali_dvfs_event', 24 MaliParser.prototype.dvfsEventEvent.bind(this)); 25 importer.registerEventHandler('mali_dvfs_set_clock', 26 MaliParser.prototype.dvfsSetClockEvent.bind(this)); 27 importer.registerEventHandler('mali_dvfs_set_voltage', 28 MaliParser.prototype.dvfsSetVoltageEvent.bind(this)); 29 30 // kernel Mali hw counter events 31 this.addJMCounter('mali_hwc_MESSAGES_SENT', 'Messages Sent'); 32 this.addJMCounter('mali_hwc_MESSAGES_RECEIVED', 'Messages Received'); 33 this.addJMCycles('mali_hwc_GPU_ACTIVE', 'GPU Active'); 34 this.addJMCycles('mali_hwc_IRQ_ACTIVE', 'IRQ Active'); 35 36 for (var i = 0; i < 7; i++) { 37 var jobStr = 'JS' + i; 38 var jobHWCStr = 'mali_hwc_' + jobStr; 39 this.addJMCounter(jobHWCStr + '_JOBS', jobStr + ' Jobs'); 40 this.addJMCounter(jobHWCStr + '_TASKS', jobStr + ' Tasks'); 41 this.addJMCycles(jobHWCStr + '_ACTIVE', jobStr + ' Active'); 42 this.addJMCycles(jobHWCStr + '_WAIT_READ', jobStr + ' Wait Read'); 43 this.addJMCycles(jobHWCStr + '_WAIT_ISSUE', jobStr + ' Wait Issue'); 44 this.addJMCycles(jobHWCStr + '_WAIT_DEPEND', jobStr + ' Wait Depend'); 45 this.addJMCycles(jobHWCStr + '_WAIT_FINISH', jobStr + ' Wait Finish'); 46 } 47 48 this.addTilerCounter('mali_hwc_TRIANGLES', 'Triangles'); 49 this.addTilerCounter('mali_hwc_QUADS', 'Quads'); 50 this.addTilerCounter('mali_hwc_POLYGONS', 'Polygons'); 51 this.addTilerCounter('mali_hwc_POINTS', 'Points'); 52 this.addTilerCounter('mali_hwc_LINES', 'Lines'); 53 this.addTilerCounter('mali_hwc_VCACHE_HIT', 'VCache Hit'); 54 this.addTilerCounter('mali_hwc_VCACHE_MISS', 'VCache Miss'); 55 this.addTilerCounter('mali_hwc_FRONT_FACING', 'Front Facing'); 56 this.addTilerCounter('mali_hwc_BACK_FACING', 'Back Facing'); 57 this.addTilerCounter('mali_hwc_PRIM_VISIBLE', 'Prim Visible'); 58 this.addTilerCounter('mali_hwc_PRIM_CULLED', 'Prim Culled'); 59 this.addTilerCounter('mali_hwc_PRIM_CLIPPED', 'Prim Clipped'); 60 61 this.addTilerCounter('mali_hwc_WRBUF_HIT', 'Wrbuf Hit'); 62 this.addTilerCounter('mali_hwc_WRBUF_MISS', 'Wrbuf Miss'); 63 this.addTilerCounter('mali_hwc_WRBUF_LINE', 'Wrbuf Line'); 64 this.addTilerCounter('mali_hwc_WRBUF_PARTIAL', 'Wrbuf Partial'); 65 this.addTilerCounter('mali_hwc_WRBUF_STALL', 'Wrbuf Stall'); 66 67 this.addTilerCycles('mali_hwc_ACTIVE', 'Tiler Active'); 68 this.addTilerCycles('mali_hwc_INDEX_WAIT', 'Index Wait'); 69 this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT', 'Index Range Wait'); 70 this.addTilerCycles('mali_hwc_VERTEX_WAIT', 'Vertex Wait'); 71 this.addTilerCycles('mali_hwc_PCACHE_WAIT', 'Pcache Wait'); 72 this.addTilerCycles('mali_hwc_WRBUF_WAIT', 'Wrbuf Wait'); 73 this.addTilerCycles('mali_hwc_BUS_READ', 'Bus Read'); 74 this.addTilerCycles('mali_hwc_BUS_WRITE', 'Bus Write'); 75 76 this.addTilerCycles('mali_hwc_TILER_UTLB_STALL', 'Tiler UTLB Stall'); 77 this.addTilerCycles('mali_hwc_TILER_UTLB_HIT', 'Tiler UTLB Hit'); 78 79 this.addFragCycles('mali_hwc_FRAG_ACTIVE', 'Active'); 80 /* NB: don't propagate spelling mistakes to labels */ 81 this.addFragCounter('mali_hwc_FRAG_PRIMATIVES', 'Primitives'); 82 this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED', 83 'Primitives Dropped'); 84 this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC', 'Descriptor Processing'); 85 this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR', 'PLR Processing??'); 86 this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT', 'Vertex Processing'); 87 this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP', 'Triangle Setup'); 88 this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST', 'Rasterization???'); 89 this.addFragCounter('mali_hwc_FRAG_THREADS', 'Threads'); 90 this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS', 'Dummy Threads'); 91 this.addFragCounter('mali_hwc_FRAG_QUADS_RAST', 'Quads Rast'); 92 this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST', 'Quads EZS Test'); 93 this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED', 'Quads EZS Killed'); 94 this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST', 'Quads LZS Test'); 95 this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED', 'Quads LZS Killed'); 96 this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE', 'No Tiles'); 97 this.addFragCounter('mali_hwc_FRAG_NUM_TILES', 'Tiles'); 98 this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM', 'Transactions Eliminated'); 99 100 this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE', 'Active'); 101 this.addComputeCounter('mali_hwc_COMPUTE_TASKS', 'Tasks'); 102 this.addComputeCounter('mali_hwc_COMPUTE_THREADS', 'Threads Started'); 103 this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC', 104 'Waiting for Descriptors'); 105 106 this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE', 'Active'); 107 108 this.addArithCounter('mali_hwc_ARITH_WORDS', 'Instructions (/Pipes)'); 109 this.addArithCycles('mali_hwc_ARITH_CYCLES_REG', 110 'Reg scheduling stalls (/Pipes)'); 111 this.addArithCycles('mali_hwc_ARITH_CYCLES_L0', 112 'L0 cache miss stalls (/Pipes)'); 113 this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND', 114 'Frag dep check failures (/Pipes)'); 115 116 this.addLSCounter('mali_hwc_LS_WORDS', 'Instruction Words Completed'); 117 this.addLSCounter('mali_hwc_LS_ISSUES', 'Full Pipeline Issues'); 118 this.addLSCounter('mali_hwc_LS_RESTARTS', 'Restarts (unpairable insts)'); 119 this.addLSCounter('mali_hwc_LS_REISSUES_MISS', 120 'Pipeline reissue (cache miss/uTLB)'); 121 this.addLSCounter('mali_hwc_LS_REISSUES_VD', 122 'Pipeline reissue (varying data)'); 123 /* TODO(sleffler) fix kernel event typo */ 124 this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS', 125 'Pipeline reissue (attribute cache miss)'); 126 this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB', 'Writeback not used'); 127 128 this.addTexCounter('mali_hwc_TEX_WORDS', 'Words'); 129 this.addTexCounter('mali_hwc_TEX_BUBBLES', 'Bubbles'); 130 this.addTexCounter('mali_hwc_TEX_WORDS_L0', 'Words L0'); 131 this.addTexCounter('mali_hwc_TEX_WORDS_DESC', 'Words Desc'); 132 this.addTexCounter('mali_hwc_TEX_THREADS', 'Threads'); 133 this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS', 'Recirc due to Full Miss'); 134 this.addTexCounter('mali_hwc_TEX_RECIRC_DESC', 'Recirc due to Desc Miss'); 135 this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI', 'Recirc due to Multipass'); 136 this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS', 137 'Recirc due to Partial Cache Miss'); 138 this.addTexCounter('mali_hwc_TEX_RECIRC_CONF', 139 'Recirc due to Cache Conflict'); 140 141 this.addLSCCounter('mali_hwc_LSC_READ_HITS', 'Read Hits'); 142 this.addLSCCounter('mali_hwc_LSC_READ_MISSES', 'Read Misses'); 143 this.addLSCCounter('mali_hwc_LSC_WRITE_HITS', 'Write Hits'); 144 this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES', 'Write Misses'); 145 this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS', 'Atomic Hits'); 146 this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES', 'Atomic Misses'); 147 this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES', 'Line Fetches'); 148 this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE', 'Dirty Lines'); 149 this.addLSCCounter('mali_hwc_LSC_SNOOPS', 'Snoops'); 150 151 this.addAXICounter('mali_hwc_AXI_TLB_STALL', 'Address channel stall'); 152 this.addAXICounter('mali_hwc_AXI_TLB_MISS', 'Cache Miss'); 153 this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION', 'Transactions'); 154 this.addAXICounter('mali_hwc_LS_TLB_MISS', 'LS Cache Miss'); 155 this.addAXICounter('mali_hwc_LS_TLB_HIT', 'LS Cache Hit'); 156 this.addAXICounter('mali_hwc_AXI_BEATS_READ', 'Read Beats'); 157 this.addAXICounter('mali_hwc_AXI_BEATS_WRITE', 'Write Beats'); 158 159 this.addMMUCounter('mali_hwc_MMU_TABLE_WALK', 'Page Table Walks'); 160 this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS', 161 'Cache Miss from Replay Buffer'); 162 this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL', 'Replay Buffer Full'); 163 this.addMMUCounter('mali_hwc_MMU_NEW_MISS', 'Cache Miss on New Request'); 164 this.addMMUCounter('mali_hwc_MMU_HIT', 'Cache Hit'); 165 166 this.addMMUCycles('mali_hwc_UTLB_STALL', 'UTLB Stalled'); 167 this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS', 'UTLB Replay Miss'); 168 this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL', 'UTLB Replay Full'); 169 this.addMMUCycles('mali_hwc_UTLB_NEW_MISS', 'UTLB New Miss'); 170 this.addMMUCycles('mali_hwc_UTLB_HIT', 'UTLB Hit'); 171 172 this.addL2Counter('mali_hwc_L2_READ_BEATS', 'Read Beats'); 173 this.addL2Counter('mali_hwc_L2_WRITE_BEATS', 'Write Beats'); 174 this.addL2Counter('mali_hwc_L2_ANY_LOOKUP', 'Any Lookup'); 175 this.addL2Counter('mali_hwc_L2_READ_LOOKUP', 'Read Lookup'); 176 this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP', 'Shareable Read Lookup'); 177 this.addL2Counter('mali_hwc_L2_READ_REPLAY', 'Read Replayed'); 178 this.addL2Counter('mali_hwc_L2_READ_SNOOP', 'Read Snoop'); 179 this.addL2Counter('mali_hwc_L2_READ_HIT', 'Read Cache Hit'); 180 this.addL2Counter('mali_hwc_L2_CLEAN_MISS', 'CleanUnique Miss'); 181 this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP', 'Write Lookup'); 182 this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP', 'Shareable Write Lookup'); 183 this.addL2Counter('mali_hwc_L2_WRITE_REPLAY', 'Write Replayed'); 184 this.addL2Counter('mali_hwc_L2_WRITE_SNOOP', 'Write Snoop'); 185 this.addL2Counter('mali_hwc_L2_WRITE_HIT', 'Write Cache Hit'); 186 this.addL2Counter('mali_hwc_L2_EXT_READ_FULL', 'ExtRD with BIU Full'); 187 this.addL2Counter('mali_hwc_L2_EXT_READ_HALF', 'ExtRD with BIU >1/2 Full'); 188 this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL', 'ExtWR with BIU Full'); 189 this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF', 'ExtWR with BIU >1/2 Full'); 190 191 this.addL2Counter('mali_hwc_L2_EXT_READ', 'External Read (ExtRD)'); 192 this.addL2Counter('mali_hwc_L2_EXT_READ_LINE', 'ExtRD (linefill)'); 193 this.addL2Counter('mali_hwc_L2_EXT_WRITE', 'External Write (ExtWR)'); 194 this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE', 'ExtWR (linefill)'); 195 this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL', 'ExtWR (burst size <64B)'); 196 this.addL2Counter('mali_hwc_L2_EXT_BARRIER', 'External Barrier'); 197 this.addL2Counter('mali_hwc_L2_EXT_AR_STALL', 'Address Read stalls'); 198 this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL', 199 'Response Buffer full stalls'); 200 this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL', 201 'Read Data Buffer full stalls'); 202 this.addL2Counter('mali_hwc_L2_EXT_R_RAW', 'RAW hazard stalls'); 203 this.addL2Counter('mali_hwc_L2_EXT_W_STALL', 'Write Data stalls'); 204 this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL', 'Write Data Buffer full'); 205 this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD', 'WAW or WAR hazard stalls'); 206 this.addL2Counter('mali_hwc_L2_TAG_HAZARD', 'Tag hazard replays'); 207 this.addL2Cycles('mali_hwc_L2_SNOOP_FULL', 'Snoop buffer full'); 208 this.addL2Cycles('mali_hwc_L2_REPLAY_FULL', 'Replay buffer full'); 209 210 // DDK events (from X server) 211 importer.registerEventHandler('tracing_mark_write:mali_driver', 212 MaliParser.prototype.maliDDKEvent.bind(this)); 213 214 this.model_ = importer.model_; 215 } 216 217 MaliParser.prototype = { 218 __proto__: Parser.prototype, 219 220 maliDDKOpenSlice: function(pid, tid, ts, func, blockinfo) { 221 var thread = this.importer.model_.getOrCreateProcess(pid) 222 .getOrCreateThread(tid); 223 var funcArgs = /^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func); 224 thread.sliceGroup.beginSlice('gpu-driver', funcArgs[1], ts, 225 { 'args': funcArgs[2], 226 'blockinfo': blockinfo }); 227 }, 228 229 maliDDKCloseSlice: function(pid, tid, ts, args, blockinfo) { 230 var thread = this.importer.model_.getOrCreateProcess(pid) 231 .getOrCreateThread(tid); 232 if (!thread.sliceGroup.openSliceCount) { 233 // Discard unmatched ends. 234 return; 235 } 236 thread.sliceGroup.endSlice(ts); 237 }, 238 239 /** 240 * Deduce the format of Mali perf events. 241 * 242 * @return {RegExp} the regular expression for parsing data when the format 243 * is recognized; otherwise null. 244 */ 245 autoDetectLineRE: function(line) { 246 // Matches Mali perf events with thread info 247 var lineREWithThread = 248 /^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/; 249 if (lineREWithThread.test(line)) 250 return lineREWithThread; 251 252 // Matches old-style Mali perf events 253 var lineRENoThread = /^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/; 254 if (lineRENoThread.test(line)) 255 return lineRENoThread; 256 return null; 257 }, 258 259 lineRE: null, 260 261 /** 262 * Parses maliDDK events and sets up state in the importer. 263 * events will come in pairs with a cros_trace_print_enter 264 * like this (line broken here for formatting): 265 * 266 * tracing_mark_write: mali_driver: (mali-012345) cros_trace_print_enter: \ 267 * gles/src/texture/mali_gles_texture_slave.c@1505: gles2_texturep_upload 268 * 269 * and a cros_trace_print_exit like this: 270 * 271 * tracing_mark_write: mali_driver: (mali-012345) cros_trace_print_exit: \ 272 * gles/src/texture/mali_gles_texture_slave.c@1505: 273 */ 274 maliDDKEvent: function(eventName, cpuNumber, pid, ts, eventBase) { 275 if (this.lineRE == null) { 276 this.lineRE = this.autoDetectLineRE(eventBase.details); 277 if (this.lineRE == null) 278 return false; 279 } 280 var maliEvent = this.lineRE.exec(eventBase.details); 281 // Old-style Mali perf events have no thread id, so make one. 282 var tid = (maliEvent[1] === '' ? 'mali' : maliEvent[1]); 283 switch (maliEvent[2]) { 284 case 'cros_trace_print_enter': 285 this.maliDDKOpenSlice(pid, tid, ts, maliEvent[4], 286 maliEvent[3]); 287 break; 288 case 'cros_trace_print_exit': 289 this.maliDDKCloseSlice(pid, tid, ts, [], maliEvent[3]); 290 } 291 return true; 292 }, 293 294 /* 295 * Kernel event support. 296 */ 297 298 dvfsSample: function(counterName, seriesName, ts, s) { 299 var value = parseInt(s); 300 var counter = this.model_.getOrCreateProcess(0). 301 getOrCreateCounter('DVFS', counterName); 302 if (counter.numSeries === 0) { 303 counter.addSeries(new tracing.trace_model.CounterSeries(seriesName, 304 tracing.getStringColorId(counter.name))); 305 } 306 counter.series.forEach(function(series) { 307 series.addSample(ts, value); 308 }); 309 }, 310 311 dvfsEventEvent: function(eventName, cpuNumber, pid, ts, eventBase) { 312 var event = /utilization=(\d+)/.exec(eventBase.details); 313 if (!event) 314 return false; 315 316 this.dvfsSample('DVFS Utilization', 'utilization', ts, event[1]); 317 return true; 318 }, 319 320 dvfsSetClockEvent: function(eventName, cpuNumber, pid, ts, eventBase) { 321 var event = /frequency=(\d+)/.exec(eventBase.details); 322 if (!event) 323 return false; 324 325 this.dvfsSample('DVFS Frequency', 'frequency', ts, event[1]); 326 return true; 327 }, 328 329 dvfsSetVoltageEvent: function(eventName, cpuNumber, pid, ts, eventBase) { 330 var event = /voltage=(\d+)/.exec(eventBase.details); 331 if (!event) 332 return false; 333 334 this.dvfsSample('DVFS Voltage', 'voltage', ts, event[1]); 335 return true; 336 }, 337 338 hwcSample: function(cat, counterName, seriesName, ts, eventBase) { 339 var event = /val=(\d+)/.exec(eventBase.details); 340 if (!event) 341 return false; 342 var value = parseInt(event[1]); 343 344 var counter = this.model_.getOrCreateProcess(0). 345 getOrCreateCounter(cat, counterName); 346 if (counter.numSeries === 0) { 347 counter.addSeries(new tracing.trace_model.CounterSeries(seriesName, 348 tracing.getStringColorId(counter.name))); 349 } 350 counter.series.forEach(function(series) { 351 series.addSample(ts, value); 352 }); 353 return true; 354 }, 355 356 /* 357 * Job Manager block counters. 358 */ 359 jmSample: function(ctrName, seriesName, ts, eventBase) { 360 return this.hwcSample('mali:jm', 'JM: ' + ctrName, seriesName, ts, 361 eventBase); 362 }, 363 addJMCounter: function(hwcEventName, hwcTitle) { 364 function handler(eventName, cpuNumber, pid, ts, eventBase) { 365 return this.jmSample(hwcTitle, 'count', ts, eventBase); 366 } 367 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 368 }, 369 addJMCycles: function(hwcEventName, hwcTitle) { 370 function handler(eventName, cpuNumber, pid, ts, eventBase) { 371 return this.jmSample(hwcTitle, 'cycles', ts, eventBase); 372 } 373 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 374 }, 375 376 /* 377 * Tiler block counters. 378 */ 379 tilerSample: function(ctrName, seriesName, ts, eventBase) { 380 return this.hwcSample('mali:tiler', 'Tiler: ' + ctrName, seriesName, 381 ts, eventBase); 382 }, 383 addTilerCounter: function(hwcEventName, hwcTitle) { 384 function handler(eventName, cpuNumber, pid, ts, eventBase) { 385 return this.tilerSample(hwcTitle, 'count', ts, eventBase); 386 } 387 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 388 }, 389 addTilerCycles: function(hwcEventName, hwcTitle) { 390 function handler(eventName, cpuNumber, pid, ts, eventBase) { 391 return this.tilerSample(hwcTitle, 'cycles', ts, eventBase); 392 } 393 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 394 }, 395 396 /* 397 * Fragment counters. 398 */ 399 fragSample: function(ctrName, seriesName, ts, eventBase) { 400 return this.hwcSample('mali:fragment', 'Fragment: ' + ctrName, 401 seriesName, ts, eventBase); 402 }, 403 addFragCounter: function(hwcEventName, hwcTitle) { 404 function handler(eventName, cpuNumber, pid, ts, eventBase) { 405 return this.fragSample(hwcTitle, 'count', ts, eventBase); 406 } 407 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 408 }, 409 addFragCycles: function(hwcEventName, hwcTitle) { 410 function handler(eventName, cpuNumber, pid, ts, eventBase) { 411 return this.fragSample(hwcTitle, 'cycles', ts, eventBase); 412 } 413 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 414 }, 415 416 /* 417 * Compute counters. 418 */ 419 computeSample: function(ctrName, seriesName, ts, eventBase) { 420 return this.hwcSample('mali:compute', 'Compute: ' + ctrName, 421 seriesName, ts, eventBase); 422 }, 423 addComputeCounter: function(hwcEventName, hwcTitle) { 424 function handler(eventName, cpuNumber, pid, ts, eventBase) { 425 return this.computeSample(hwcTitle, 'count', ts, eventBase); 426 } 427 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 428 }, 429 addComputeCycles: function(hwcEventName, hwcTitle) { 430 function handler(eventName, cpuNumber, pid, ts, eventBase) { 431 return this.computeSample(hwcTitle, 'cycles', ts, eventBase); 432 } 433 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 434 }, 435 436 /* 437 * Tripipe counters. 438 */ 439 addTripipeCycles: function(hwcEventName, hwcTitle) { 440 function handler(eventName, cpuNumber, pid, ts, eventBase) { 441 return this.hwcSample('mali:shader', 'Tripipe: ' + hwcTitle, 'cycles', 442 ts, eventBase); 443 } 444 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 445 }, 446 447 /* 448 * Arith counters. 449 */ 450 arithSample: function(ctrName, seriesName, ts, eventBase) { 451 return this.hwcSample('mali:arith', 'Arith: ' + ctrName, seriesName, ts, 452 eventBase); 453 }, 454 addArithCounter: function(hwcEventName, hwcTitle) { 455 function handler(eventName, cpuNumber, pid, ts, eventBase) { 456 return this.arithSample(hwcTitle, 'count', ts, eventBase); 457 } 458 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 459 }, 460 addArithCycles: function(hwcEventName, hwcTitle) { 461 function handler(eventName, cpuNumber, pid, ts, eventBase) { 462 return this.arithSample(hwcTitle, 'cycles', ts, eventBase); 463 } 464 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 465 }, 466 467 /* 468 * Load/Store counters. 469 */ 470 addLSCounter: function(hwcEventName, hwcTitle) { 471 function handler(eventName, cpuNumber, pid, ts, eventBase) { 472 return this.hwcSample('mali:ls', 'LS: ' + hwcTitle, 'count', ts, 473 eventBase); 474 } 475 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 476 }, 477 478 /* 479 * Texture counters. 480 */ 481 textureSample: function(ctrName, seriesName, ts, eventBase) { 482 return this.hwcSample('mali:texture', 'Texture: ' + ctrName, 483 seriesName, ts, eventBase); 484 }, 485 addTexCounter: function(hwcEventName, hwcTitle) { 486 function handler(eventName, cpuNumber, pid, ts, eventBase) { 487 return this.textureSample(hwcTitle, 'count', ts, eventBase); 488 } 489 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 490 }, 491 492 /* 493 * LSC counters. 494 */ 495 addLSCCounter: function(hwcEventName, hwcTitle) { 496 function handler(eventName, cpuNumber, pid, ts, eventBase) { 497 return this.hwcSample('mali:lsc', 'LSC: ' + hwcTitle, 'count', ts, 498 eventBase); 499 } 500 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 501 }, 502 503 /* 504 * TLB counters. 505 */ 506 addAXICounter: function(hwcEventName, hwcTitle) { 507 function handler(eventName, cpuNumber, pid, ts, eventBase) { 508 return this.hwcSample('mali:axi', 'AXI: ' + hwcTitle, 'count', ts, 509 eventBase); 510 } 511 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 512 }, 513 514 /* 515 * MMU counters. 516 */ 517 mmuSample: function(ctrName, seriesName, ts, eventBase) { 518 return this.hwcSample('mali:mmu', 'MMU: ' + ctrName, seriesName, ts, 519 eventBase); 520 }, 521 addMMUCounter: function(hwcEventName, hwcTitle) { 522 function handler(eventName, cpuNumber, pid, ts, eventBase) { 523 return this.mmuSample(hwcTitle, 'count', ts, eventBase); 524 } 525 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 526 }, 527 addMMUCycles: function(hwcEventName, hwcTitle) { 528 function handler(eventName, cpuNumber, pid, ts, eventBase) { 529 return this.mmuSample(hwcTitle, 'cycles', ts, eventBase); 530 } 531 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 532 }, 533 534 /* 535 * L2 counters. 536 */ 537 l2Sample: function(ctrName, seriesName, ts, eventBase) { 538 return this.hwcSample('mali:l2', 'L2: ' + ctrName, seriesName, ts, 539 eventBase); 540 }, 541 addL2Counter: function(hwcEventName, hwcTitle) { 542 function handler(eventName, cpuNumber, pid, ts, eventBase) { 543 return this.l2Sample(hwcTitle, 'count', ts, eventBase); 544 } 545 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 546 }, 547 addL2Cycles: function(hwcEventName, hwcTitle) { 548 function handler(eventName, cpuNumber, pid, ts, eventBase) { 549 return this.l2Sample(hwcTitle, 'cycles', ts, eventBase); 550 } 551 this.importer.registerEventHandler(hwcEventName, handler.bind(this)); 552 } 553 }; 554 555 Parser.registerSubtype(MaliParser); 556 557 return { 558 MaliParser: MaliParser 559 }; 560 }); 561