1bf215546Sopenharmony_ci# Copyright (c) 2015-2017 Intel Corporation 2bf215546Sopenharmony_ci# 3bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 4bf215546Sopenharmony_ci# copy of this software and associated documentation files (the "Software"), 5bf215546Sopenharmony_ci# to deal in the Software without restriction, including without limitation 6bf215546Sopenharmony_ci# the rights to use, copy, modify, merge, publish, distribute, sublicense, 7bf215546Sopenharmony_ci# and/or sell copies of the Software, and to permit persons to whom the 8bf215546Sopenharmony_ci# Software is furnished to do so, subject to the following conditions: 9bf215546Sopenharmony_ci# 10bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the next 11bf215546Sopenharmony_ci# paragraph) shall be included in all copies or substantial portions of the 12bf215546Sopenharmony_ci# Software. 13bf215546Sopenharmony_ci# 14bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15bf215546Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18bf215546Sopenharmony_ci# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19bf215546Sopenharmony_ci# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20bf215546Sopenharmony_ci# IN THE SOFTWARE. 21bf215546Sopenharmony_ci 22bf215546Sopenharmony_ciimport argparse 23bf215546Sopenharmony_ciimport builtins 24bf215546Sopenharmony_ciimport collections 25bf215546Sopenharmony_ciimport os 26bf215546Sopenharmony_ciimport re 27bf215546Sopenharmony_ciimport sys 28bf215546Sopenharmony_ciimport textwrap 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ciimport xml.etree.ElementTree as et 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_cihashed_funcs = {} 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_cic_file = None 35bf215546Sopenharmony_ci_c_indent = 0 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cidef c(*args): 38bf215546Sopenharmony_ci code = ' '.join(map(str,args)) 39bf215546Sopenharmony_ci for line in code.splitlines(): 40bf215546Sopenharmony_ci text = ''.rjust(_c_indent) + line 41bf215546Sopenharmony_ci c_file.write(text.rstrip() + "\n") 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci# indented, but no trailing newline... 44bf215546Sopenharmony_cidef c_line_start(code): 45bf215546Sopenharmony_ci c_file.write(''.rjust(_c_indent) + code) 46bf215546Sopenharmony_cidef c_raw(code): 47bf215546Sopenharmony_ci c_file.write(code) 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_cidef c_indent(n): 50bf215546Sopenharmony_ci global _c_indent 51bf215546Sopenharmony_ci _c_indent = _c_indent + n 52bf215546Sopenharmony_cidef c_outdent(n): 53bf215546Sopenharmony_ci global _c_indent 54bf215546Sopenharmony_ci _c_indent = _c_indent - n 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ciheader_file = None 57bf215546Sopenharmony_ci_h_indent = 0 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_cidef h(*args): 60bf215546Sopenharmony_ci code = ' '.join(map(str,args)) 61bf215546Sopenharmony_ci for line in code.splitlines(): 62bf215546Sopenharmony_ci text = ''.rjust(_h_indent) + line 63bf215546Sopenharmony_ci header_file.write(text.rstrip() + "\n") 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_cidef h_indent(n): 66bf215546Sopenharmony_ci global _c_indent 67bf215546Sopenharmony_ci _h_indent = _h_indent + n 68bf215546Sopenharmony_cidef h_outdent(n): 69bf215546Sopenharmony_ci global _c_indent 70bf215546Sopenharmony_ci _h_indent = _h_indent - n 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_cidef emit_fadd(tmp_id, args): 74bf215546Sopenharmony_ci c("double tmp{0} = {1} + {2};".format(tmp_id, args[1], args[0])) 75bf215546Sopenharmony_ci return tmp_id + 1 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci# Be careful to check for divide by zero... 78bf215546Sopenharmony_cidef emit_fdiv(tmp_id, args): 79bf215546Sopenharmony_ci c("double tmp{0} = {1};".format(tmp_id, args[1])) 80bf215546Sopenharmony_ci c("double tmp{0} = {1};".format(tmp_id + 1, args[0])) 81bf215546Sopenharmony_ci c("double tmp{0} = tmp{1} ? tmp{2} / tmp{1} : 0;".format(tmp_id + 2, tmp_id + 1, tmp_id)) 82bf215546Sopenharmony_ci return tmp_id + 3 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_cidef emit_fmax(tmp_id, args): 85bf215546Sopenharmony_ci c("double tmp{0} = {1};".format(tmp_id, args[1])) 86bf215546Sopenharmony_ci c("double tmp{0} = {1};".format(tmp_id + 1, args[0])) 87bf215546Sopenharmony_ci c("double tmp{0} = MAX(tmp{1}, tmp{2});".format(tmp_id + 2, tmp_id, tmp_id + 1)) 88bf215546Sopenharmony_ci return tmp_id + 3 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_cidef emit_fmul(tmp_id, args): 91bf215546Sopenharmony_ci c("double tmp{0} = {1} * {2};".format(tmp_id, args[1], args[0])) 92bf215546Sopenharmony_ci return tmp_id + 1 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_cidef emit_fsub(tmp_id, args): 95bf215546Sopenharmony_ci c("double tmp{0} = {1} - {2};".format(tmp_id, args[1], args[0])) 96bf215546Sopenharmony_ci return tmp_id + 1 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_cidef emit_read(tmp_id, args): 99bf215546Sopenharmony_ci type = args[1].lower() 100bf215546Sopenharmony_ci c("uint64_t tmp{0} = results->accumulator[query->{1}_offset + {2}];".format(tmp_id, type, args[0])) 101bf215546Sopenharmony_ci return tmp_id + 1 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_cidef emit_uadd(tmp_id, args): 104bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} + {2};".format(tmp_id, args[1], args[0])) 105bf215546Sopenharmony_ci return tmp_id + 1 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci# Be careful to check for divide by zero... 108bf215546Sopenharmony_cidef emit_udiv(tmp_id, args): 109bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1};".format(tmp_id, args[1])) 110bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1};".format(tmp_id + 1, args[0])) 111bf215546Sopenharmony_ci if args[0].isdigit(): 112bf215546Sopenharmony_ci assert int(args[0]) > 0 113bf215546Sopenharmony_ci c("uint64_t tmp{0} = tmp{2} / tmp{1};".format(tmp_id + 2, tmp_id + 1, tmp_id)) 114bf215546Sopenharmony_ci else: 115bf215546Sopenharmony_ci c("uint64_t tmp{0} = tmp{1} ? tmp{2} / tmp{1} : 0;".format(tmp_id + 2, tmp_id + 1, tmp_id)) 116bf215546Sopenharmony_ci return tmp_id + 3 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_cidef emit_umul(tmp_id, args): 119bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} * {2};".format(tmp_id, args[1], args[0])) 120bf215546Sopenharmony_ci return tmp_id + 1 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_cidef emit_usub(tmp_id, args): 123bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} - {2};".format(tmp_id, args[1], args[0])) 124bf215546Sopenharmony_ci return tmp_id + 1 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_cidef emit_umin(tmp_id, args): 127bf215546Sopenharmony_ci c("uint64_t tmp{0} = MIN({1}, {2});".format(tmp_id, args[1], args[0])) 128bf215546Sopenharmony_ci return tmp_id + 1 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_cidef emit_lshft(tmp_id, args): 131bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} << {2};".format(tmp_id, args[1], args[0])) 132bf215546Sopenharmony_ci return tmp_id + 1 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_cidef emit_rshft(tmp_id, args): 135bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} >> {2};".format(tmp_id, args[1], args[0])) 136bf215546Sopenharmony_ci return tmp_id + 1 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_cidef emit_and(tmp_id, args): 139bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} & {2};".format(tmp_id, args[1], args[0])) 140bf215546Sopenharmony_ci return tmp_id + 1 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_cidef emit_ulte(tmp_id, args): 143bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} <= {2};".format(tmp_id, args[1], args[0])) 144bf215546Sopenharmony_ci return tmp_id + 1 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_cidef emit_ult(tmp_id, args): 147bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} < {2};".format(tmp_id, args[1], args[0])) 148bf215546Sopenharmony_ci return tmp_id + 1 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_cidef emit_ugte(tmp_id, args): 151bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} >= {2};".format(tmp_id, args[1], args[0])) 152bf215546Sopenharmony_ci return tmp_id + 1 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_cidef emit_ugt(tmp_id, args): 155bf215546Sopenharmony_ci c("uint64_t tmp{0} = {1} > {2};".format(tmp_id, args[1], args[0])) 156bf215546Sopenharmony_ci return tmp_id + 1 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ciops = {} 159bf215546Sopenharmony_ci# (n operands, emitter) 160bf215546Sopenharmony_ciops["FADD"] = (2, emit_fadd) 161bf215546Sopenharmony_ciops["FDIV"] = (2, emit_fdiv) 162bf215546Sopenharmony_ciops["FMAX"] = (2, emit_fmax) 163bf215546Sopenharmony_ciops["FMUL"] = (2, emit_fmul) 164bf215546Sopenharmony_ciops["FSUB"] = (2, emit_fsub) 165bf215546Sopenharmony_ciops["READ"] = (2, emit_read) 166bf215546Sopenharmony_ciops["UADD"] = (2, emit_uadd) 167bf215546Sopenharmony_ciops["UDIV"] = (2, emit_udiv) 168bf215546Sopenharmony_ciops["UMUL"] = (2, emit_umul) 169bf215546Sopenharmony_ciops["USUB"] = (2, emit_usub) 170bf215546Sopenharmony_ciops["UMIN"] = (2, emit_umin) 171bf215546Sopenharmony_ciops["<<"] = (2, emit_lshft) 172bf215546Sopenharmony_ciops[">>"] = (2, emit_rshft) 173bf215546Sopenharmony_ciops["AND"] = (2, emit_and) 174bf215546Sopenharmony_ciops["UGTE"] = (2, emit_ugte) 175bf215546Sopenharmony_ciops["UGT"] = (2, emit_ugt) 176bf215546Sopenharmony_ciops["ULTE"] = (2, emit_ulte) 177bf215546Sopenharmony_ciops["ULT"] = (2, emit_ult) 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_cidef brkt(subexp): 181bf215546Sopenharmony_ci if " " in subexp: 182bf215546Sopenharmony_ci return "(" + subexp + ")" 183bf215546Sopenharmony_ci else: 184bf215546Sopenharmony_ci return subexp 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_cidef splice_bitwise_and(args): 187bf215546Sopenharmony_ci return brkt(args[1]) + " & " + brkt(args[0]) 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_cidef splice_logical_and(args): 190bf215546Sopenharmony_ci return brkt(args[1]) + " && " + brkt(args[0]) 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_cidef splice_ult(args): 193bf215546Sopenharmony_ci return brkt(args[1]) + " < " + brkt(args[0]) 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_cidef splice_ugte(args): 196bf215546Sopenharmony_ci return brkt(args[1]) + " >= " + brkt(args[0]) 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_cidef splice_ulte(args): 199bf215546Sopenharmony_ci return brkt(args[1]) + " <= " + brkt(args[0]) 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_cidef splice_ugt(args): 202bf215546Sopenharmony_ci return brkt(args[1]) + " > " + brkt(args[0]) 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ciexp_ops = {} 205bf215546Sopenharmony_ci# (n operands, splicer) 206bf215546Sopenharmony_ciexp_ops["AND"] = (2, splice_bitwise_and) 207bf215546Sopenharmony_ciexp_ops["UGTE"] = (2, splice_ugte) 208bf215546Sopenharmony_ciexp_ops["ULT"] = (2, splice_ult) 209bf215546Sopenharmony_ciexp_ops["&&"] = (2, splice_logical_and) 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_cihw_vars = {} 213bf215546Sopenharmony_cihw_vars["$EuCoresTotalCount"] = "perf->sys_vars.n_eus" 214bf215546Sopenharmony_cihw_vars["$EuSlicesTotalCount"] = "perf->sys_vars.n_eu_slices" 215bf215546Sopenharmony_cihw_vars["$EuSubslicesTotalCount"] = "perf->sys_vars.n_eu_sub_slices" 216bf215546Sopenharmony_cihw_vars["$EuDualSubslicesTotalCount"] = "perf->sys_vars.n_eu_sub_slices" 217bf215546Sopenharmony_cihw_vars["$EuDualSubslicesSlice0123Count"] = "perf->sys_vars.n_eu_slice0123" 218bf215546Sopenharmony_cihw_vars["$EuThreadsCount"] = "perf->devinfo.num_thread_per_eu" 219bf215546Sopenharmony_cihw_vars["$SliceMask"] = "perf->sys_vars.slice_mask" 220bf215546Sopenharmony_ci# subslice_mask is interchangeable with subslice/dual-subslice since Gfx12+ 221bf215546Sopenharmony_ci# only has dual subslices which can be assimilated with 16EUs subslices. 222bf215546Sopenharmony_cihw_vars["$SubsliceMask"] = "perf->sys_vars.subslice_mask" 223bf215546Sopenharmony_cihw_vars["$DualSubsliceMask"] = "perf->sys_vars.subslice_mask" 224bf215546Sopenharmony_cihw_vars["$GpuTimestampFrequency"] = "perf->devinfo.timestamp_frequency" 225bf215546Sopenharmony_cihw_vars["$GpuMinFrequency"] = "perf->sys_vars.gt_min_freq" 226bf215546Sopenharmony_cihw_vars["$GpuMaxFrequency"] = "perf->sys_vars.gt_max_freq" 227bf215546Sopenharmony_cihw_vars["$SkuRevisionId"] = "perf->devinfo.revision" 228bf215546Sopenharmony_cihw_vars["$QueryMode"] = "perf->sys_vars.query_mode" 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_cidef resolve_variable(name, set, allow_counters): 231bf215546Sopenharmony_ci if name in hw_vars: 232bf215546Sopenharmony_ci return hw_vars[name] 233bf215546Sopenharmony_ci m = re.search('\$GtSlice([0-9]+)$', name) 234bf215546Sopenharmony_ci if m: 235bf215546Sopenharmony_ci return 'intel_device_info_slice_available(&perf->devinfo, {0})'.format(m.group(1)) 236bf215546Sopenharmony_ci m = re.search('\$GtSlice([0-9]+)DualSubslice([0-9]+)$', name) 237bf215546Sopenharmony_ci if m: 238bf215546Sopenharmony_ci return 'intel_device_info_subslice_available(&perf->devinfo, {0}, {1})'.format(m.group(1), m.group(2)) 239bf215546Sopenharmony_ci if allow_counters and name in set.counter_vars: 240bf215546Sopenharmony_ci return set.read_funcs[name[1:]] + "(perf, query, results)" 241bf215546Sopenharmony_ci return None 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_cidef output_rpn_equation_code(set, counter, equation): 244bf215546Sopenharmony_ci c("/* RPN equation: " + equation + " */") 245bf215546Sopenharmony_ci tokens = equation.split() 246bf215546Sopenharmony_ci stack = [] 247bf215546Sopenharmony_ci tmp_id = 0 248bf215546Sopenharmony_ci tmp = None 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci for token in tokens: 251bf215546Sopenharmony_ci stack.append(token) 252bf215546Sopenharmony_ci while stack and stack[-1] in ops: 253bf215546Sopenharmony_ci op = stack.pop() 254bf215546Sopenharmony_ci argc, callback = ops[op] 255bf215546Sopenharmony_ci args = [] 256bf215546Sopenharmony_ci for i in range(0, argc): 257bf215546Sopenharmony_ci operand = stack.pop() 258bf215546Sopenharmony_ci if operand[0] == "$": 259bf215546Sopenharmony_ci resolved_variable = resolve_variable(operand, set, True) 260bf215546Sopenharmony_ci if resolved_variable == None: 261bf215546Sopenharmony_ci raise Exception("Failed to resolve variable " + operand + " in equation " + equation + " for " + set.name + " :: " + counter.get('name')); 262bf215546Sopenharmony_ci operand = resolved_variable 263bf215546Sopenharmony_ci args.append(operand) 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci tmp_id = callback(tmp_id, args) 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci tmp = "tmp{0}".format(tmp_id - 1) 268bf215546Sopenharmony_ci stack.append(tmp) 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci if len(stack) != 1: 271bf215546Sopenharmony_ci raise Exception("Spurious empty rpn code for " + set.name + " :: " + 272bf215546Sopenharmony_ci counter.get('name') + ".\nThis is probably due to some unhandled RPN function, in the equation \"" + 273bf215546Sopenharmony_ci equation + "\"") 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci value = stack[-1] 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci if value[0] == "$": 278bf215546Sopenharmony_ci resolved_variable = resolve_variable(value, set, True) 279bf215546Sopenharmony_ci if resolved_variable == None: 280bf215546Sopenharmony_ci raise Exception("Failed to resolve variable " + operand + " in equation " + equation + " for " + set.name + " :: " + counter.get('name')); 281bf215546Sopenharmony_ci value = resolved_variable 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci c("\nreturn " + value + ";") 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_cidef splice_rpn_expression(set, counter, expression): 286bf215546Sopenharmony_ci tokens = expression.split() 287bf215546Sopenharmony_ci stack = [] 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci for token in tokens: 290bf215546Sopenharmony_ci stack.append(token) 291bf215546Sopenharmony_ci while stack and stack[-1] in exp_ops: 292bf215546Sopenharmony_ci op = stack.pop() 293bf215546Sopenharmony_ci argc, callback = exp_ops[op] 294bf215546Sopenharmony_ci args = [] 295bf215546Sopenharmony_ci for i in range(0, argc): 296bf215546Sopenharmony_ci operand = stack.pop() 297bf215546Sopenharmony_ci if operand[0] == "$": 298bf215546Sopenharmony_ci resolved_variable = resolve_variable(operand, set, False) 299bf215546Sopenharmony_ci if resolved_variable == None: 300bf215546Sopenharmony_ci raise Exception("Failed to resolve variable " + operand + " in expression " + expression + " for " + set.name + " :: " + counter.get('name')) 301bf215546Sopenharmony_ci operand = resolved_variable 302bf215546Sopenharmony_ci args.append(operand) 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci subexp = callback(args) 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci stack.append(subexp) 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci if len(stack) != 1: 309bf215546Sopenharmony_ci raise Exception("Spurious empty rpn expression for " + set.name + " :: " + 310bf215546Sopenharmony_ci counter.get('name') + ".\nThis is probably due to some unhandled RPN operation, in the expression \"" + 311bf215546Sopenharmony_ci expression + "\"") 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci value = stack[-1] 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci if value[0] == "$": 316bf215546Sopenharmony_ci resolved_variable = resolve_variable(value, set, False) 317bf215546Sopenharmony_ci if resolved_variable == None: 318bf215546Sopenharmony_ci raise Exception("Failed to resolve variable " + operand + " in expression " + expression + " for " + set.name + " :: " + counter.get('name')) 319bf215546Sopenharmony_ci value = resolved_variable 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci return value 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_cidef output_counter_read(gen, set, counter): 324bf215546Sopenharmony_ci c("\n") 325bf215546Sopenharmony_ci c("/* {0} :: {1} */".format(set.name, counter.get('name'))) 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci if counter.read_hash in hashed_funcs: 328bf215546Sopenharmony_ci c("#define %s \\" % counter.read_sym) 329bf215546Sopenharmony_ci c_indent(3) 330bf215546Sopenharmony_ci c("%s" % hashed_funcs[counter.read_hash]) 331bf215546Sopenharmony_ci c_outdent(3) 332bf215546Sopenharmony_ci else: 333bf215546Sopenharmony_ci ret_type = counter.get('data_type') 334bf215546Sopenharmony_ci if ret_type == "uint64": 335bf215546Sopenharmony_ci ret_type = "uint64_t" 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci read_eq = counter.get('equation') 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci c("static " + ret_type) 340bf215546Sopenharmony_ci c(counter.read_sym + "(UNUSED struct intel_perf_config *perf,\n") 341bf215546Sopenharmony_ci c_indent(len(counter.read_sym) + 1) 342bf215546Sopenharmony_ci c("const struct intel_perf_query_info *query,\n") 343bf215546Sopenharmony_ci c("const struct intel_perf_query_result *results)\n") 344bf215546Sopenharmony_ci c_outdent(len(counter.read_sym) + 1) 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci c("{") 347bf215546Sopenharmony_ci c_indent(3) 348bf215546Sopenharmony_ci output_rpn_equation_code(set, counter, read_eq) 349bf215546Sopenharmony_ci c_outdent(3) 350bf215546Sopenharmony_ci c("}") 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci hashed_funcs[counter.read_hash] = counter.read_sym 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_cidef output_counter_max(gen, set, counter): 356bf215546Sopenharmony_ci max_eq = counter.get('max_equation') 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci if not counter.has_custom_max_func(): 359bf215546Sopenharmony_ci return 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci c("\n") 362bf215546Sopenharmony_ci c("/* {0} :: {1} */".format(set.name, counter.get('name'))) 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci if counter.max_hash in hashed_funcs: 365bf215546Sopenharmony_ci c("#define %s \\" % counter.max_sym) 366bf215546Sopenharmony_ci c_indent(3) 367bf215546Sopenharmony_ci c("%s" % hashed_funcs[counter.max_hash]) 368bf215546Sopenharmony_ci c_outdent(3) 369bf215546Sopenharmony_ci else: 370bf215546Sopenharmony_ci ret_type = counter.get('data_type') 371bf215546Sopenharmony_ci if ret_type == "uint64": 372bf215546Sopenharmony_ci ret_type = "uint64_t" 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci c("static " + ret_type) 375bf215546Sopenharmony_ci c(counter.max_sym + "(struct intel_perf_config *perf,\n") 376bf215546Sopenharmony_ci c_indent(len(counter.read_sym) + 1) 377bf215546Sopenharmony_ci c("const struct intel_perf_query_info *query,\n") 378bf215546Sopenharmony_ci c("const struct intel_perf_query_result *results)\n") 379bf215546Sopenharmony_ci c_outdent(len(counter.read_sym) + 1) 380bf215546Sopenharmony_ci c("{") 381bf215546Sopenharmony_ci c_indent(3) 382bf215546Sopenharmony_ci output_rpn_equation_code(set, counter, max_eq) 383bf215546Sopenharmony_ci c_outdent(3) 384bf215546Sopenharmony_ci c("}") 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci hashed_funcs[counter.max_hash] = counter.max_sym 387bf215546Sopenharmony_ci 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_cic_type_sizes = { "uint32_t": 4, "uint64_t": 8, "float": 4, "double": 8, "bool": 4 } 390bf215546Sopenharmony_cidef sizeof(c_type): 391bf215546Sopenharmony_ci return c_type_sizes[c_type] 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_cidef pot_align(base, pot_alignment): 394bf215546Sopenharmony_ci return (base + pot_alignment - 1) & ~(pot_alignment - 1); 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_cisemantic_type_map = { 397bf215546Sopenharmony_ci "duration": "raw", 398bf215546Sopenharmony_ci "ratio": "event" 399bf215546Sopenharmony_ci } 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_cidef output_availability(set, availability, counter_name): 402bf215546Sopenharmony_ci expression = splice_rpn_expression(set, counter_name, availability) 403bf215546Sopenharmony_ci lines = expression.split(' && ') 404bf215546Sopenharmony_ci n_lines = len(lines) 405bf215546Sopenharmony_ci if n_lines == 1: 406bf215546Sopenharmony_ci c("if (" + lines[0] + ") {") 407bf215546Sopenharmony_ci else: 408bf215546Sopenharmony_ci c("if (" + lines[0] + " &&") 409bf215546Sopenharmony_ci c_indent(4) 410bf215546Sopenharmony_ci for i in range(1, (n_lines - 1)): 411bf215546Sopenharmony_ci c(lines[i] + " &&") 412bf215546Sopenharmony_ci c(lines[(n_lines - 1)] + ") {") 413bf215546Sopenharmony_ci c_outdent(4) 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_cidef output_units(unit): 417bf215546Sopenharmony_ci return unit.replace(' ', '_').upper() 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci# should a unit be visible in description? 421bf215546Sopenharmony_ciunits_map = { 422bf215546Sopenharmony_ci "bytes" : True, 423bf215546Sopenharmony_ci "cycles" : True, 424bf215546Sopenharmony_ci "eu atomic requests to l3 cache lines" : False, 425bf215546Sopenharmony_ci "eu bytes per l3 cache line" : False, 426bf215546Sopenharmony_ci "eu requests to l3 cache lines" : False, 427bf215546Sopenharmony_ci "eu sends to l3 cache lines" : False, 428bf215546Sopenharmony_ci "events" : True, 429bf215546Sopenharmony_ci "hz" : True, 430bf215546Sopenharmony_ci "messages" : True, 431bf215546Sopenharmony_ci "ns" : True, 432bf215546Sopenharmony_ci "number" : False, 433bf215546Sopenharmony_ci "percent" : True, 434bf215546Sopenharmony_ci "pixels" : True, 435bf215546Sopenharmony_ci "texels" : True, 436bf215546Sopenharmony_ci "threads" : True, 437bf215546Sopenharmony_ci "us" : True, 438bf215546Sopenharmony_ci "utilization" : False, 439bf215546Sopenharmony_ci } 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_cidef desc_units(unit): 443bf215546Sopenharmony_ci val = units_map.get(unit) 444bf215546Sopenharmony_ci if val is None: 445bf215546Sopenharmony_ci raise Exception("Unknown unit: " + unit) 446bf215546Sopenharmony_ci if val == False: 447bf215546Sopenharmony_ci return "" 448bf215546Sopenharmony_ci if unit == 'hz': 449bf215546Sopenharmony_ci unit = 'Hz' 450bf215546Sopenharmony_ci return "Unit: " + unit + "." 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_cicounter_key_tuple = collections.namedtuple( 454bf215546Sopenharmony_ci 'counter_key', 455bf215546Sopenharmony_ci [ 456bf215546Sopenharmony_ci 'name', 457bf215546Sopenharmony_ci 'description', 458bf215546Sopenharmony_ci 'symbol_name', 459bf215546Sopenharmony_ci 'mdapi_group', 460bf215546Sopenharmony_ci 'semantic_type', 461bf215546Sopenharmony_ci 'data_type', 462bf215546Sopenharmony_ci 'units', 463bf215546Sopenharmony_ci ] 464bf215546Sopenharmony_ci) 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_cidef counter_key(counter): 468bf215546Sopenharmony_ci return counter_key_tuple._make([counter.get(field) for field in counter_key_tuple._fields]) 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_cidef output_counter_struct(set, counter, idx, 472bf215546Sopenharmony_ci name_to_idx, desc_to_idx, 473bf215546Sopenharmony_ci symbol_name_to_idx, category_to_idx): 474bf215546Sopenharmony_ci data_type = counter.data_type 475bf215546Sopenharmony_ci data_type_uc = data_type.upper() 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci semantic_type = counter.semantic_type 478bf215546Sopenharmony_ci if semantic_type in semantic_type_map: 479bf215546Sopenharmony_ci semantic_type = semantic_type_map[semantic_type] 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_ci semantic_type_uc = semantic_type.upper() 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci c("[" + str(idx) + "] = {\n") 484bf215546Sopenharmony_ci c_indent(3) 485bf215546Sopenharmony_ci c(".name_idx = " + str(name_to_idx[counter.name]) + ",\n") 486bf215546Sopenharmony_ci c(".desc_idx = " + str(desc_to_idx[counter.description + " " + desc_units(counter.units)]) + ",\n") 487bf215546Sopenharmony_ci c(".symbol_name_idx = " + str(symbol_name_to_idx[counter.symbol_name]) + ",\n") 488bf215546Sopenharmony_ci c(".category_idx = " + str(category_to_idx[counter.mdapi_group]) + ",\n") 489bf215546Sopenharmony_ci c(".type = INTEL_PERF_COUNTER_TYPE_" + semantic_type_uc + ",\n") 490bf215546Sopenharmony_ci c(".data_type = INTEL_PERF_COUNTER_DATA_TYPE_" + data_type_uc + ",\n") 491bf215546Sopenharmony_ci c(".units = INTEL_PERF_COUNTER_UNITS_" + output_units(counter.units) + ",\n") 492bf215546Sopenharmony_ci c_outdent(3) 493bf215546Sopenharmony_ci c("},\n") 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_cidef output_counter_report(set, counter, counter_to_idx, current_offset): 497bf215546Sopenharmony_ci data_type = counter.get('data_type') 498bf215546Sopenharmony_ci data_type_uc = data_type.upper() 499bf215546Sopenharmony_ci c_type = data_type 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci if "uint" in c_type: 502bf215546Sopenharmony_ci c_type = c_type + "_t" 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci semantic_type = counter.get('semantic_type') 505bf215546Sopenharmony_ci if semantic_type in semantic_type_map: 506bf215546Sopenharmony_ci semantic_type = semantic_type_map[semantic_type] 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci semantic_type_uc = semantic_type.upper() 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci c("\n") 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci availability = counter.get('availability') 513bf215546Sopenharmony_ci if availability: 514bf215546Sopenharmony_ci output_availability(set, availability, counter.get('name')) 515bf215546Sopenharmony_ci c_indent(3) 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci key = counter_key(counter) 518bf215546Sopenharmony_ci idx = str(counter_to_idx[key]) 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci current_offset = pot_align(current_offset, sizeof(c_type)) 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ci if data_type == 'uint64': 523bf215546Sopenharmony_ci c("intel_perf_query_add_counter_uint64(query, " + idx + ", " + 524bf215546Sopenharmony_ci str(current_offset) + ", " + 525bf215546Sopenharmony_ci set.max_funcs[counter.get('symbol_name')] + "," + 526bf215546Sopenharmony_ci set.read_funcs[counter.get('symbol_name')] + ");\n") 527bf215546Sopenharmony_ci else: 528bf215546Sopenharmony_ci c("intel_perf_query_add_counter_float(query, " + idx + ", " + 529bf215546Sopenharmony_ci str(current_offset) + ", " + 530bf215546Sopenharmony_ci set.max_funcs[counter.get('symbol_name')] + "," + 531bf215546Sopenharmony_ci set.read_funcs[counter.get('symbol_name')] + ");\n") 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci if availability: 535bf215546Sopenharmony_ci c_outdent(3); 536bf215546Sopenharmony_ci c("}") 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci return current_offset + sizeof(c_type) 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_cidef str_to_idx_table(strs): 542bf215546Sopenharmony_ci sorted_strs = sorted(strs) 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci str_to_idx = collections.OrderedDict() 545bf215546Sopenharmony_ci str_to_idx[sorted_strs[0]] = 0 546bf215546Sopenharmony_ci previous = sorted_strs[0] 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci for i in range(1, len(sorted_strs)): 549bf215546Sopenharmony_ci str_to_idx[sorted_strs[i]] = str_to_idx[previous] + len(previous) + 1 550bf215546Sopenharmony_ci previous = sorted_strs[i] 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_ci return str_to_idx 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_cidef output_str_table(name: str, str_to_idx): 556bf215546Sopenharmony_ci c("\n") 557bf215546Sopenharmony_ci c("static const char " + name + "[] = {\n") 558bf215546Sopenharmony_ci c_indent(3) 559bf215546Sopenharmony_ci c("\n".join(f"/* {idx} */ \"{val}\\0\"" for val, idx in str_to_idx.items())) 560bf215546Sopenharmony_ci c_outdent(3) 561bf215546Sopenharmony_ci c("};\n") 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ciregister_types = { 565bf215546Sopenharmony_ci 'FLEX': 'flex_regs', 566bf215546Sopenharmony_ci 'NOA': 'mux_regs', 567bf215546Sopenharmony_ci 'OA': 'b_counter_regs', 568bf215546Sopenharmony_ci} 569bf215546Sopenharmony_ci 570bf215546Sopenharmony_cidef compute_register_lengths(set): 571bf215546Sopenharmony_ci register_lengths = {} 572bf215546Sopenharmony_ci register_configs = set.findall('register_config') 573bf215546Sopenharmony_ci for register_config in register_configs: 574bf215546Sopenharmony_ci t = register_types[register_config.get('type')] 575bf215546Sopenharmony_ci if t not in register_lengths: 576bf215546Sopenharmony_ci register_lengths[t] = len(register_config.findall('register')) 577bf215546Sopenharmony_ci else: 578bf215546Sopenharmony_ci register_lengths[t] += len(register_config.findall('register')) 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci return register_lengths 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_cidef generate_register_configs(set): 584bf215546Sopenharmony_ci register_configs = set.findall('register_config') 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci for register_config in register_configs: 587bf215546Sopenharmony_ci t = register_types[register_config.get('type')] 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci availability = register_config.get('availability') 590bf215546Sopenharmony_ci if availability: 591bf215546Sopenharmony_ci output_availability(set, availability, register_config.get('type') + ' register config') 592bf215546Sopenharmony_ci c_indent(3) 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ci registers = register_config.findall('register') 595bf215546Sopenharmony_ci c("static const struct intel_perf_query_register_prog %s[] = {" % t) 596bf215546Sopenharmony_ci c_indent(3) 597bf215546Sopenharmony_ci for register in registers: 598bf215546Sopenharmony_ci c("{ .reg = %s, .val = %s }," % (register.get('address'), register.get('value'))) 599bf215546Sopenharmony_ci c_outdent(3) 600bf215546Sopenharmony_ci c("};") 601bf215546Sopenharmony_ci c("query->config.%s = %s;" % (t, t)) 602bf215546Sopenharmony_ci c("query->config.n_%s = ARRAY_SIZE(%s);" % (t, t)) 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci if availability: 605bf215546Sopenharmony_ci c_outdent(3) 606bf215546Sopenharmony_ci c("}") 607bf215546Sopenharmony_ci c("\n") 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci# Wraps a <counter> element from the oa-*.xml files. 611bf215546Sopenharmony_ciclass Counter: 612bf215546Sopenharmony_ci def __init__(self, set, xml): 613bf215546Sopenharmony_ci self.xml = xml 614bf215546Sopenharmony_ci self.set = set 615bf215546Sopenharmony_ci self.read_hash = None 616bf215546Sopenharmony_ci self.max_hash = None 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_ci self.read_sym = "{0}__{1}__{2}__read".format(self.set.gen.chipset, 619bf215546Sopenharmony_ci self.set.underscore_name, 620bf215546Sopenharmony_ci self.xml.get('underscore_name')) 621bf215546Sopenharmony_ci self.max_sym = self.build_max_sym() 622bf215546Sopenharmony_ci 623bf215546Sopenharmony_ci def get(self, prop): 624bf215546Sopenharmony_ci return self.xml.get(prop) 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci # Compute the hash of a counter's equation by expanding (including all the 627bf215546Sopenharmony_ci # sub-equations it depends on) 628bf215546Sopenharmony_ci def compute_hashes(self): 629bf215546Sopenharmony_ci if self.read_hash is not None: 630bf215546Sopenharmony_ci return 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_ci def replace_token(token): 633bf215546Sopenharmony_ci if token[0] != "$": 634bf215546Sopenharmony_ci return token 635bf215546Sopenharmony_ci if token not in self.set.counter_vars: 636bf215546Sopenharmony_ci return token 637bf215546Sopenharmony_ci self.set.counter_vars[token].compute_hashes() 638bf215546Sopenharmony_ci return self.set.counter_vars[token].read_hash 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_ci read_eq = self.xml.get('equation') 641bf215546Sopenharmony_ci self.read_hash = ' '.join(map(replace_token, read_eq.split())) 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci max_eq = self.xml.get('max_equation') 644bf215546Sopenharmony_ci if max_eq: 645bf215546Sopenharmony_ci self.max_hash = ' '.join(map(replace_token, max_eq.split())) 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_ci def has_custom_max_func(self): 648bf215546Sopenharmony_ci max_eq = self.xml.get('max_equation') 649bf215546Sopenharmony_ci if not max_eq: 650bf215546Sopenharmony_ci return False 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci try: 653bf215546Sopenharmony_ci val = float(max_eq) 654bf215546Sopenharmony_ci if val == 100: 655bf215546Sopenharmony_ci return False 656bf215546Sopenharmony_ci except ValueError: 657bf215546Sopenharmony_ci pass 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci for token in max_eq.split(): 660bf215546Sopenharmony_ci if token[0] == '$' and resolve_variable(token, self.set, True) == None: 661bf215546Sopenharmony_ci print("unresolved token " + token) 662bf215546Sopenharmony_ci return False 663bf215546Sopenharmony_ci return True 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci def build_max_sym(self): 666bf215546Sopenharmony_ci max_eq = self.xml.get('max_equation') 667bf215546Sopenharmony_ci if not max_eq: 668bf215546Sopenharmony_ci return "NULL" 669bf215546Sopenharmony_ci 670bf215546Sopenharmony_ci try: 671bf215546Sopenharmony_ci val = float(max_eq) 672bf215546Sopenharmony_ci if val == 100: 673bf215546Sopenharmony_ci if self.xml.get('data_type') == 'uint64': 674bf215546Sopenharmony_ci return "percentage_max_uint64" 675bf215546Sopenharmony_ci else: 676bf215546Sopenharmony_ci return "percentage_max_float" 677bf215546Sopenharmony_ci except ValueError: 678bf215546Sopenharmony_ci pass 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci assert self.has_custom_max_func() 681bf215546Sopenharmony_ci return "{0}__{1}__{2}__max".format(self.set.gen.chipset, 682bf215546Sopenharmony_ci self.set.underscore_name, 683bf215546Sopenharmony_ci self.xml.get('underscore_name')) 684bf215546Sopenharmony_ci 685bf215546Sopenharmony_ci 686bf215546Sopenharmony_ci# Wraps a <set> element from the oa-*.xml files. 687bf215546Sopenharmony_ciclass Set: 688bf215546Sopenharmony_ci def __init__(self, gen, xml): 689bf215546Sopenharmony_ci self.gen = gen 690bf215546Sopenharmony_ci self.xml = xml 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci self.counter_vars = {} 693bf215546Sopenharmony_ci self.max_funcs = {} 694bf215546Sopenharmony_ci self.read_funcs = {} 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci xml_counters = self.xml.findall("counter") 697bf215546Sopenharmony_ci self.counters = [] 698bf215546Sopenharmony_ci for xml_counter in xml_counters: 699bf215546Sopenharmony_ci counter = Counter(self, xml_counter) 700bf215546Sopenharmony_ci self.counters.append(counter) 701bf215546Sopenharmony_ci self.counter_vars['$' + counter.get('symbol_name')] = counter 702bf215546Sopenharmony_ci self.read_funcs[counter.get('symbol_name')] = counter.read_sym 703bf215546Sopenharmony_ci self.max_funcs[counter.get('symbol_name')] = counter.max_sym 704bf215546Sopenharmony_ci 705bf215546Sopenharmony_ci for counter in self.counters: 706bf215546Sopenharmony_ci counter.compute_hashes() 707bf215546Sopenharmony_ci 708bf215546Sopenharmony_ci @property 709bf215546Sopenharmony_ci def hw_config_guid(self): 710bf215546Sopenharmony_ci return self.xml.get('hw_config_guid') 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_ci @property 713bf215546Sopenharmony_ci def name(self): 714bf215546Sopenharmony_ci return self.xml.get('name') 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci @property 717bf215546Sopenharmony_ci def symbol_name(self): 718bf215546Sopenharmony_ci return self.xml.get('symbol_name') 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci @property 721bf215546Sopenharmony_ci def underscore_name(self): 722bf215546Sopenharmony_ci return self.xml.get('underscore_name') 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci def findall(self, path): 725bf215546Sopenharmony_ci return self.xml.findall(path) 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_ci def find(self, path): 728bf215546Sopenharmony_ci return self.xml.find(path) 729bf215546Sopenharmony_ci 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_ci# Wraps an entire oa-*.xml file. 732bf215546Sopenharmony_ciclass Gen: 733bf215546Sopenharmony_ci def __init__(self, filename): 734bf215546Sopenharmony_ci self.filename = filename 735bf215546Sopenharmony_ci self.xml = et.parse(self.filename) 736bf215546Sopenharmony_ci self.chipset = self.xml.find('.//set').get('chipset').lower() 737bf215546Sopenharmony_ci self.sets = [] 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci for xml_set in self.xml.findall(".//set"): 740bf215546Sopenharmony_ci self.sets.append(Set(self, xml_set)) 741bf215546Sopenharmony_ci 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_cidef main(): 744bf215546Sopenharmony_ci global c_file 745bf215546Sopenharmony_ci global header_file 746bf215546Sopenharmony_ci 747bf215546Sopenharmony_ci parser = argparse.ArgumentParser() 748bf215546Sopenharmony_ci parser.add_argument("--header", help="Header file to write", required=True) 749bf215546Sopenharmony_ci parser.add_argument("--code", help="C file to write", required=True) 750bf215546Sopenharmony_ci parser.add_argument("xml_files", nargs='+', help="List of xml metrics files to process") 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci args = parser.parse_args() 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_ci c_file = open(args.code, 'w') 755bf215546Sopenharmony_ci header_file = open(args.header, 'w') 756bf215546Sopenharmony_ci 757bf215546Sopenharmony_ci gens = [] 758bf215546Sopenharmony_ci for xml_file in args.xml_files: 759bf215546Sopenharmony_ci gens.append(Gen(xml_file)) 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci 762bf215546Sopenharmony_ci copyright = textwrap.dedent("""\ 763bf215546Sopenharmony_ci /* Autogenerated file, DO NOT EDIT manually! generated by {} 764bf215546Sopenharmony_ci * 765bf215546Sopenharmony_ci * Copyright (c) 2015 Intel Corporation 766bf215546Sopenharmony_ci * 767bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 768bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 769bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 770bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 771bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 772bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 773bf215546Sopenharmony_ci * 774bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 775bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 776bf215546Sopenharmony_ci * Software. 777bf215546Sopenharmony_ci * 778bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 779bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 780bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 781bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 782bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 783bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 784bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 785bf215546Sopenharmony_ci */ 786bf215546Sopenharmony_ci 787bf215546Sopenharmony_ci """).format(os.path.basename(__file__)) 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci h(copyright) 790bf215546Sopenharmony_ci h(textwrap.dedent("""\ 791bf215546Sopenharmony_ci #pragma once 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_ci struct intel_perf_config; 794bf215546Sopenharmony_ci 795bf215546Sopenharmony_ci """)) 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci c(copyright) 798bf215546Sopenharmony_ci c(textwrap.dedent("""\ 799bf215546Sopenharmony_ci #include <stdint.h> 800bf215546Sopenharmony_ci #include <stdbool.h> 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci #include <drm-uapi/i915_drm.h> 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_ci #include "util/hash_table.h" 805bf215546Sopenharmony_ci #include "util/ralloc.h" 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci """)) 808bf215546Sopenharmony_ci 809bf215546Sopenharmony_ci c("#include \"" + os.path.basename(args.header) + "\"") 810bf215546Sopenharmony_ci 811bf215546Sopenharmony_ci c(textwrap.dedent("""\ 812bf215546Sopenharmony_ci #include "perf/intel_perf.h" 813bf215546Sopenharmony_ci #include "perf/intel_perf_setup.h" 814bf215546Sopenharmony_ci """)) 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci names = builtins.set() 817bf215546Sopenharmony_ci descs = builtins.set() 818bf215546Sopenharmony_ci symbol_names = builtins.set() 819bf215546Sopenharmony_ci categories = builtins.set() 820bf215546Sopenharmony_ci for gen in gens: 821bf215546Sopenharmony_ci for set in gen.sets: 822bf215546Sopenharmony_ci for counter in set.counters: 823bf215546Sopenharmony_ci names.add(counter.get('name')) 824bf215546Sopenharmony_ci symbol_names.add(counter.get('symbol_name')) 825bf215546Sopenharmony_ci descs.add(counter.get('description') + " " + desc_units(counter.get('units'))) 826bf215546Sopenharmony_ci categories.add(counter.get('mdapi_group')) 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci name_to_idx = str_to_idx_table(names) 829bf215546Sopenharmony_ci output_str_table("name", name_to_idx) 830bf215546Sopenharmony_ci 831bf215546Sopenharmony_ci desc_to_idx = str_to_idx_table(descs) 832bf215546Sopenharmony_ci output_str_table("desc", desc_to_idx) 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci symbol_name_to_idx = str_to_idx_table(symbol_names) 835bf215546Sopenharmony_ci output_str_table("symbol_name", symbol_name_to_idx) 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ci category_to_idx = str_to_idx_table(categories) 838bf215546Sopenharmony_ci output_str_table("category", category_to_idx) 839bf215546Sopenharmony_ci 840bf215546Sopenharmony_ci # Print out all equation functions. 841bf215546Sopenharmony_ci for gen in gens: 842bf215546Sopenharmony_ci for set in gen.sets: 843bf215546Sopenharmony_ci for counter in set.counters: 844bf215546Sopenharmony_ci output_counter_read(gen, set, counter) 845bf215546Sopenharmony_ci output_counter_max(gen, set, counter) 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_ci c("\n") 848bf215546Sopenharmony_ci c("static const struct intel_perf_query_counter_data counters[] = {\n") 849bf215546Sopenharmony_ci c_indent(3) 850bf215546Sopenharmony_ci 851bf215546Sopenharmony_ci counter_to_idx = collections.OrderedDict() 852bf215546Sopenharmony_ci idx = 0 853bf215546Sopenharmony_ci for gen in gens: 854bf215546Sopenharmony_ci for set in gen.sets: 855bf215546Sopenharmony_ci for counter in set.counters: 856bf215546Sopenharmony_ci key = counter_key(counter) 857bf215546Sopenharmony_ci if key not in counter_to_idx: 858bf215546Sopenharmony_ci counter_to_idx[key] = idx 859bf215546Sopenharmony_ci output_counter_struct(set, key, idx, 860bf215546Sopenharmony_ci name_to_idx, 861bf215546Sopenharmony_ci desc_to_idx, 862bf215546Sopenharmony_ci symbol_name_to_idx, 863bf215546Sopenharmony_ci category_to_idx) 864bf215546Sopenharmony_ci idx += 1 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_ci c_outdent(3) 867bf215546Sopenharmony_ci c("};\n\n") 868bf215546Sopenharmony_ci 869bf215546Sopenharmony_ci c(textwrap.dedent("""\ 870bf215546Sopenharmony_ci static void ATTRIBUTE_NOINLINE 871bf215546Sopenharmony_ci intel_perf_query_add_counter_uint64(struct intel_perf_query_info *query, 872bf215546Sopenharmony_ci int counter_idx, size_t offset, 873bf215546Sopenharmony_ci intel_counter_read_uint64_t oa_counter_max, 874bf215546Sopenharmony_ci intel_counter_read_uint64_t oa_counter_read) 875bf215546Sopenharmony_ci { 876bf215546Sopenharmony_ci struct intel_perf_query_counter *dest = &query->counters[query->n_counters++]; 877bf215546Sopenharmony_ci const struct intel_perf_query_counter_data *counter = &counters[counter_idx]; 878bf215546Sopenharmony_ci 879bf215546Sopenharmony_ci dest->name = &name[counter->name_idx]; 880bf215546Sopenharmony_ci dest->desc = &desc[counter->desc_idx]; 881bf215546Sopenharmony_ci dest->symbol_name = &symbol_name[counter->symbol_name_idx]; 882bf215546Sopenharmony_ci dest->category = &category[counter->category_idx]; 883bf215546Sopenharmony_ci 884bf215546Sopenharmony_ci dest->offset = offset; 885bf215546Sopenharmony_ci dest->type = counter->type; 886bf215546Sopenharmony_ci dest->data_type = counter->data_type; 887bf215546Sopenharmony_ci dest->units = counter->units; 888bf215546Sopenharmony_ci dest->oa_counter_max_uint64 = oa_counter_max; 889bf215546Sopenharmony_ci dest->oa_counter_read_uint64 = oa_counter_read; 890bf215546Sopenharmony_ci } 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci static void ATTRIBUTE_NOINLINE 893bf215546Sopenharmony_ci intel_perf_query_add_counter_float(struct intel_perf_query_info *query, 894bf215546Sopenharmony_ci int counter_idx, size_t offset, 895bf215546Sopenharmony_ci intel_counter_read_float_t oa_counter_max, 896bf215546Sopenharmony_ci intel_counter_read_float_t oa_counter_read) 897bf215546Sopenharmony_ci { 898bf215546Sopenharmony_ci struct intel_perf_query_counter *dest = &query->counters[query->n_counters++]; 899bf215546Sopenharmony_ci const struct intel_perf_query_counter_data *counter = &counters[counter_idx]; 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci dest->name = &name[counter->name_idx]; 902bf215546Sopenharmony_ci dest->desc = &desc[counter->desc_idx]; 903bf215546Sopenharmony_ci dest->symbol_name = &symbol_name[counter->symbol_name_idx]; 904bf215546Sopenharmony_ci dest->category = &category[counter->category_idx]; 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_ci dest->offset = offset; 907bf215546Sopenharmony_ci dest->type = counter->type; 908bf215546Sopenharmony_ci dest->data_type = counter->data_type; 909bf215546Sopenharmony_ci dest->units = counter->units; 910bf215546Sopenharmony_ci dest->oa_counter_max_float = oa_counter_max; 911bf215546Sopenharmony_ci dest->oa_counter_read_float = oa_counter_read; 912bf215546Sopenharmony_ci } 913bf215546Sopenharmony_ci 914bf215546Sopenharmony_ci static float ATTRIBUTE_NOINLINE 915bf215546Sopenharmony_ci percentage_max_float(struct intel_perf_config *perf, 916bf215546Sopenharmony_ci const struct intel_perf_query_info *query, 917bf215546Sopenharmony_ci const struct intel_perf_query_result *results) 918bf215546Sopenharmony_ci { 919bf215546Sopenharmony_ci return 100; 920bf215546Sopenharmony_ci } 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci static uint64_t ATTRIBUTE_NOINLINE 923bf215546Sopenharmony_ci percentage_max_uint64(struct intel_perf_config *perf, 924bf215546Sopenharmony_ci const struct intel_perf_query_info *query, 925bf215546Sopenharmony_ci const struct intel_perf_query_result *results) 926bf215546Sopenharmony_ci { 927bf215546Sopenharmony_ci return 100; 928bf215546Sopenharmony_ci } 929bf215546Sopenharmony_ci """)) 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci # Print out all metric sets registration functions for each set in each 932bf215546Sopenharmony_ci # generation. 933bf215546Sopenharmony_ci for gen in gens: 934bf215546Sopenharmony_ci for set in gen.sets: 935bf215546Sopenharmony_ci counters = set.counters 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci c("\n") 938bf215546Sopenharmony_ci c("\nstatic void\n") 939bf215546Sopenharmony_ci c("{0}_register_{1}_counter_query(struct intel_perf_config *perf)\n".format(gen.chipset, set.underscore_name)) 940bf215546Sopenharmony_ci c("{\n") 941bf215546Sopenharmony_ci c_indent(3) 942bf215546Sopenharmony_ci 943bf215546Sopenharmony_ci if gen.chipset == "hsw": 944bf215546Sopenharmony_ci c("struct intel_perf_query_info *query = hsw_query_alloc(perf, %u);\n" % len(counters)) 945bf215546Sopenharmony_ci else: 946bf215546Sopenharmony_ci c("struct intel_perf_query_info *query = bdw_query_alloc(perf, %u);\n" % len(counters)) 947bf215546Sopenharmony_ci c("\n") 948bf215546Sopenharmony_ci c("query->name = \"" + set.name + "\";\n") 949bf215546Sopenharmony_ci c("query->symbol_name = \"" + set.symbol_name + "\";\n") 950bf215546Sopenharmony_ci c("query->guid = \"" + set.hw_config_guid + "\";\n") 951bf215546Sopenharmony_ci 952bf215546Sopenharmony_ci c("\n") 953bf215546Sopenharmony_ci c("struct intel_perf_query_counter *counter = query->counters;\n") 954bf215546Sopenharmony_ci 955bf215546Sopenharmony_ci c("\n") 956bf215546Sopenharmony_ci c("/* Note: we're assuming there can't be any variation in the definition ") 957bf215546Sopenharmony_ci c(" * of a query between contexts so it's ok to describe a query within a ") 958bf215546Sopenharmony_ci c(" * global variable which only needs to be initialized once... */") 959bf215546Sopenharmony_ci c("\nif (!query->data_size) {") 960bf215546Sopenharmony_ci c_indent(3) 961bf215546Sopenharmony_ci 962bf215546Sopenharmony_ci generate_register_configs(set) 963bf215546Sopenharmony_ci 964bf215546Sopenharmony_ci offset = 0 965bf215546Sopenharmony_ci for counter in counters: 966bf215546Sopenharmony_ci offset = output_counter_report(set, counter, counter_to_idx, offset) 967bf215546Sopenharmony_ci 968bf215546Sopenharmony_ci 969bf215546Sopenharmony_ci c("\ncounter = &query->counters[query->n_counters - 1];\n") 970bf215546Sopenharmony_ci c("query->data_size = counter->offset + intel_perf_query_counter_get_size(counter);\n") 971bf215546Sopenharmony_ci 972bf215546Sopenharmony_ci c_outdent(3) 973bf215546Sopenharmony_ci c("}"); 974bf215546Sopenharmony_ci 975bf215546Sopenharmony_ci c("\n_mesa_hash_table_insert(perf->oa_metrics_table, query->guid, query);") 976bf215546Sopenharmony_ci 977bf215546Sopenharmony_ci c_outdent(3) 978bf215546Sopenharmony_ci c("}\n") 979bf215546Sopenharmony_ci 980bf215546Sopenharmony_ci h("void intel_oa_register_queries_" + gen.chipset + "(struct intel_perf_config *perf);\n") 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci c("\nvoid") 983bf215546Sopenharmony_ci c("intel_oa_register_queries_" + gen.chipset + "(struct intel_perf_config *perf)") 984bf215546Sopenharmony_ci c("{") 985bf215546Sopenharmony_ci c_indent(3) 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci for set in gen.sets: 988bf215546Sopenharmony_ci c("{0}_register_{1}_counter_query(perf);".format(gen.chipset, set.underscore_name)) 989bf215546Sopenharmony_ci 990bf215546Sopenharmony_ci c_outdent(3) 991bf215546Sopenharmony_ci c("}") 992bf215546Sopenharmony_ci 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_ciif __name__ == '__main__': 995bf215546Sopenharmony_ci main() 996