17ec681f3Smrg# Copyright © 2021 Collabora, Ltd. 27ec681f3Smrg# Author: Antonio Caggiano <antonio.caggiano@collabora.com> 37ec681f3Smrg 47ec681f3Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 57ec681f3Smrg# of this software and associated documentation files (the "Software"), to deal 67ec681f3Smrg# in the Software without restriction, including without limitation the rights 77ec681f3Smrg# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 87ec681f3Smrg# copies of the Software, and to permit persons to whom the Software is 97ec681f3Smrg# furnished to do so, subject to the following conditions: 107ec681f3Smrg 117ec681f3Smrg# The above copyright notice and this permission notice shall be included in 127ec681f3Smrg# all copies or substantial portions of the Software. 137ec681f3Smrg 147ec681f3Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 157ec681f3Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167ec681f3Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 177ec681f3Smrg# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 187ec681f3Smrg# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 197ec681f3Smrg# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 207ec681f3Smrg# THE SOFTWARE. 217ec681f3Smrg 227ec681f3Smrgimport argparse 237ec681f3Smrgimport textwrap 247ec681f3Smrgimport os 257ec681f3Smrg 267ec681f3Smrgimport xml.etree.ElementTree as et 277ec681f3Smrg 287ec681f3Smrg 297ec681f3Smrgclass SourceFile: 307ec681f3Smrg def __init__(self, filename): 317ec681f3Smrg self.file = open(filename, 'w') 327ec681f3Smrg self._indent = 0 337ec681f3Smrg 347ec681f3Smrg def write(self, *args): 357ec681f3Smrg code = ' '.join(map(str,args)) 367ec681f3Smrg for line in code.splitlines(): 377ec681f3Smrg text = ''.rjust(self._indent) + line 387ec681f3Smrg self.file.write(text.rstrip() + "\n") 397ec681f3Smrg 407ec681f3Smrg def indent(self, n): 417ec681f3Smrg self._indent += n 427ec681f3Smrg 437ec681f3Smrg def outdent(self, n): 447ec681f3Smrg self._indent -= n 457ec681f3Smrg 467ec681f3Smrg 477ec681f3Smrgclass Counter: 487ec681f3Smrg # category Category owning the counter 497ec681f3Smrg # xml XML representation of itself 507ec681f3Smrg def __init__(self, category, xml): 517ec681f3Smrg self.category = category 527ec681f3Smrg self.xml = xml 537ec681f3Smrg self.name = self.xml.get("name") 547ec681f3Smrg self.desc = self.xml.get("description") 557ec681f3Smrg self.units = self.xml.get("units") 567ec681f3Smrg self.offset = int(self.xml.get("offset")) 577ec681f3Smrg self.underscore_name = self.xml.get("counter").lower() 587ec681f3Smrg 597ec681f3Smrg 607ec681f3Smrgclass Category: 617ec681f3Smrg # product Product owning the gategory 627ec681f3Smrg # xml XML representation of itself 637ec681f3Smrg def __init__(self, product, xml): 647ec681f3Smrg self.product = product 657ec681f3Smrg self.xml = xml 667ec681f3Smrg self.name = self.xml.get("name") 677ec681f3Smrg self.underscore_name = self.name.lower().replace(' ', '_') 687ec681f3Smrg 697ec681f3Smrg xml_counters = self.xml.findall("event") 707ec681f3Smrg self.counters = [] 717ec681f3Smrg for xml_counter in xml_counters: 727ec681f3Smrg self.counters.append(Counter(self, xml_counter)) 737ec681f3Smrg 747ec681f3Smrg 757ec681f3Smrg# Wraps an entire *.xml file. 767ec681f3Smrgclass Product: 777ec681f3Smrg def __init__(self, filename): 787ec681f3Smrg self.filename = filename 797ec681f3Smrg self.xml = et.parse(self.filename) 807ec681f3Smrg self.id = self.xml.getroot().get('id').lower() 817ec681f3Smrg self.categories = [] 827ec681f3Smrg 837ec681f3Smrg for xml_cat in self.xml.findall(".//category"): 847ec681f3Smrg self.categories.append(Category(self, xml_cat)) 857ec681f3Smrg 867ec681f3Smrg 877ec681f3Smrgdef main(): 887ec681f3Smrg parser = argparse.ArgumentParser() 897ec681f3Smrg parser.add_argument("--header", help="Header file to write", required=True) 907ec681f3Smrg parser.add_argument("--code", help="C file to write", required=True) 917ec681f3Smrg parser.add_argument("xml_files", nargs='+', help="List of xml metrics files to process") 927ec681f3Smrg 937ec681f3Smrg args = parser.parse_args() 947ec681f3Smrg 957ec681f3Smrg c = SourceFile(args.code) 967ec681f3Smrg h = SourceFile(args.header) 977ec681f3Smrg 987ec681f3Smrg prods = [] 997ec681f3Smrg for xml_file in args.xml_files: 1007ec681f3Smrg prods.append(Product(xml_file)) 1017ec681f3Smrg 1027ec681f3Smrg tab_size = 3 1037ec681f3Smrg 1047ec681f3Smrg copyright = textwrap.dedent("""\ 1057ec681f3Smrg /* Autogenerated file, DO NOT EDIT manually! generated by {} 1067ec681f3Smrg * 1077ec681f3Smrg * Copyright © 2021 Arm Limited 1087ec681f3Smrg * Copyright © 2021 Collabora Ltd. 1097ec681f3Smrg * 1107ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 1117ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 1127ec681f3Smrg * to deal in the Software without restriction, including without limitation 1137ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1147ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 1157ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 1167ec681f3Smrg * 1177ec681f3Smrg * The above copyright notice and this permission notice (including the next 1187ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 1197ec681f3Smrg * Software. 1207ec681f3Smrg * 1217ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1227ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1237ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1247ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1257ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 1267ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 1277ec681f3Smrg * DEALINGS IN THE SOFTWARE. 1287ec681f3Smrg */ 1297ec681f3Smrg 1307ec681f3Smrg """).format(os.path.basename(__file__)) 1317ec681f3Smrg 1327ec681f3Smrg h.write(copyright) 1337ec681f3Smrg h.write(textwrap.dedent("""\ 1347ec681f3Smrg #ifndef PAN_PERF_METRICS_H 1357ec681f3Smrg #define PAN_PERF_METRICS_H 1367ec681f3Smrg 1377ec681f3Smrg #include "perf/pan_perf.h" 1387ec681f3Smrg 1397ec681f3Smrg """)) 1407ec681f3Smrg 1417ec681f3Smrg c.write(copyright) 1427ec681f3Smrg c.write("#include \"" + os.path.basename(args.header) + "\"") 1437ec681f3Smrg c.write(textwrap.dedent("""\ 1447ec681f3Smrg 1457ec681f3Smrg #include <util/macros.h> 1467ec681f3Smrg """)) 1477ec681f3Smrg 1487ec681f3Smrg for prod in prods: 1497ec681f3Smrg h.write("extern const struct panfrost_perf_config panfrost_perf_config_%s;\n" % prod.id) 1507ec681f3Smrg 1517ec681f3Smrg for prod in prods: 1527ec681f3Smrg c.write(textwrap.dedent(""" 1537ec681f3Smrg static void UNUSED 1547ec681f3Smrg static_asserts_%s(void) 1557ec681f3Smrg { 1567ec681f3Smrg """ % prod.id)) 1577ec681f3Smrg c.indent(tab_size) 1587ec681f3Smrg 1597ec681f3Smrg n_categories = len(prod.categories) 1607ec681f3Smrg c.write("STATIC_ASSERT(%u <= PAN_PERF_MAX_CATEGORIES);" % n_categories) 1617ec681f3Smrg n_counters = 0 1627ec681f3Smrg for category in prod.categories: 1637ec681f3Smrg category_counters_count = len(category.counters) 1647ec681f3Smrg c.write("STATIC_ASSERT(%u <= PAN_PERF_MAX_COUNTERS);" % category_counters_count) 1657ec681f3Smrg n_counters += category_counters_count 1667ec681f3Smrg 1677ec681f3Smrg c.outdent(tab_size) 1687ec681f3Smrg c.write("}\n") 1697ec681f3Smrg 1707ec681f3Smrg 1717ec681f3Smrg current_struct_name = "panfrost_perf_config_%s" % prod.id 1727ec681f3Smrg c.write("\nconst struct panfrost_perf_config %s = {" % current_struct_name) 1737ec681f3Smrg c.indent(tab_size) 1747ec681f3Smrg 1757ec681f3Smrg c.write(".n_categories = %u," % len(prod.categories)) 1767ec681f3Smrg 1777ec681f3Smrg c.write(".categories = {") 1787ec681f3Smrg c.indent(tab_size) 1797ec681f3Smrg 1807ec681f3Smrg counter_id = 0 1817ec681f3Smrg 1827ec681f3Smrg for i in range(0, len(prod.categories)): 1837ec681f3Smrg category = prod.categories[i] 1847ec681f3Smrg 1857ec681f3Smrg c.write("{") 1867ec681f3Smrg c.indent(tab_size) 1877ec681f3Smrg c.write(".name = \"%s\"," % (category.name)) 1887ec681f3Smrg c.write(".n_counters = %u," % (len(category.counters))) 1897ec681f3Smrg c.write(".counters = {") 1907ec681f3Smrg c.indent(tab_size) 1917ec681f3Smrg 1927ec681f3Smrg for j in range(0, len(category.counters)): 1937ec681f3Smrg counter = category.counters[j] 1947ec681f3Smrg 1957ec681f3Smrg assert counter_id < n_counters 1967ec681f3Smrg c.write("{") 1977ec681f3Smrg c.indent(tab_size) 1987ec681f3Smrg 1997ec681f3Smrg c.write(".name = \"%s\"," % (counter.name)) 2007ec681f3Smrg c.write(".desc = \"%s\"," % (counter.desc.replace("\\", "\\\\"))) 2017ec681f3Smrg c.write(".symbol_name = \"%s\"," % (counter.underscore_name)) 2027ec681f3Smrg c.write(".units = PAN_PERF_COUNTER_UNITS_%s," % (counter.units.upper())) 2037ec681f3Smrg c.write(".offset = %u," % (counter.offset)) 2047ec681f3Smrg c.write(".category = &%s.categories[%u]," % (current_struct_name, i)) 2057ec681f3Smrg 2067ec681f3Smrg c.outdent(tab_size) 2077ec681f3Smrg c.write("}, // counter") 2087ec681f3Smrg 2097ec681f3Smrg counter_id += 1 2107ec681f3Smrg 2117ec681f3Smrg c.outdent(tab_size) 2127ec681f3Smrg c.write("}, // counters") 2137ec681f3Smrg 2147ec681f3Smrg c.outdent(tab_size) 2157ec681f3Smrg c.write("}, // category") 2167ec681f3Smrg 2177ec681f3Smrg c.outdent(tab_size) 2187ec681f3Smrg c.write("}, // categories") 2197ec681f3Smrg 2207ec681f3Smrg c.outdent(tab_size) 2217ec681f3Smrg c.write("}; // %s\n" % current_struct_name) 2227ec681f3Smrg 2237ec681f3Smrg h.write("\n#endif // PAN_PERF_METRICS_H") 2247ec681f3Smrg 2257ec681f3Smrg 2267ec681f3Smrgif __name__ == '__main__': 2277ec681f3Smrg main() 228