1bf215546Sopenharmony_ci# Copyright © 2021 Collabora, Ltd. 2bf215546Sopenharmony_ci# Author: Antonio Caggiano <antonio.caggiano@collabora.com> 3bf215546Sopenharmony_ci 4bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a copy 5bf215546Sopenharmony_ci# of this software and associated documentation files (the "Software"), to deal 6bf215546Sopenharmony_ci# in the Software without restriction, including without limitation the rights 7bf215546Sopenharmony_ci# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8bf215546Sopenharmony_ci# copies of the Software, and to permit persons to whom the Software is 9bf215546Sopenharmony_ci# furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_ci# The above copyright notice and this permission notice shall be included in 12bf215546Sopenharmony_ci# all copies or substantial portions of the 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 THE 17bf215546Sopenharmony_ci# 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 FROM, 19bf215546Sopenharmony_ci# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20bf215546Sopenharmony_ci# THE SOFTWARE. 21bf215546Sopenharmony_ci 22bf215546Sopenharmony_ciimport argparse 23bf215546Sopenharmony_ciimport textwrap 24bf215546Sopenharmony_ciimport os 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ciimport xml.etree.ElementTree as et 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ciclass SourceFile: 30bf215546Sopenharmony_ci def __init__(self, filename): 31bf215546Sopenharmony_ci self.file = open(filename, 'w') 32bf215546Sopenharmony_ci self._indent = 0 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci def write(self, *args): 35bf215546Sopenharmony_ci code = ' '.join(map(str,args)) 36bf215546Sopenharmony_ci for line in code.splitlines(): 37bf215546Sopenharmony_ci text = ''.rjust(self._indent) + line 38bf215546Sopenharmony_ci self.file.write(text.rstrip() + "\n") 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci def indent(self, n): 41bf215546Sopenharmony_ci self._indent += n 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci def outdent(self, n): 44bf215546Sopenharmony_ci self._indent -= n 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ciclass Counter: 48bf215546Sopenharmony_ci # category Category owning the counter 49bf215546Sopenharmony_ci # xml XML representation of itself 50bf215546Sopenharmony_ci def __init__(self, category, xml): 51bf215546Sopenharmony_ci self.category = category 52bf215546Sopenharmony_ci self.xml = xml 53bf215546Sopenharmony_ci self.name = self.xml.get("name") 54bf215546Sopenharmony_ci self.desc = self.xml.get("description") 55bf215546Sopenharmony_ci self.units = self.xml.get("units") 56bf215546Sopenharmony_ci self.offset = int(self.xml.get("offset")) 57bf215546Sopenharmony_ci self.underscore_name = self.xml.get("counter").lower() 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ciclass Category: 61bf215546Sopenharmony_ci # product Product owning the gategory 62bf215546Sopenharmony_ci # xml XML representation of itself 63bf215546Sopenharmony_ci def __init__(self, product, xml): 64bf215546Sopenharmony_ci self.product = product 65bf215546Sopenharmony_ci self.xml = xml 66bf215546Sopenharmony_ci self.name = self.xml.get("name") 67bf215546Sopenharmony_ci self.underscore_name = self.name.lower().replace(' ', '_') 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci xml_counters = self.xml.findall("event") 70bf215546Sopenharmony_ci self.counters = [] 71bf215546Sopenharmony_ci for xml_counter in xml_counters: 72bf215546Sopenharmony_ci self.counters.append(Counter(self, xml_counter)) 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci# Wraps an entire *.xml file. 76bf215546Sopenharmony_ciclass Product: 77bf215546Sopenharmony_ci def __init__(self, filename): 78bf215546Sopenharmony_ci self.filename = filename 79bf215546Sopenharmony_ci self.xml = et.parse(self.filename) 80bf215546Sopenharmony_ci self.name = self.xml.getroot().get('id') 81bf215546Sopenharmony_ci self.id = self.name.lower() 82bf215546Sopenharmony_ci self.categories = [] 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci for xml_cat in self.xml.findall(".//category"): 85bf215546Sopenharmony_ci self.categories.append(Category(self, xml_cat)) 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_cidef main(): 89bf215546Sopenharmony_ci parser = argparse.ArgumentParser() 90bf215546Sopenharmony_ci parser.add_argument("--header", help="Header file to write", required=True) 91bf215546Sopenharmony_ci parser.add_argument("--code", help="C file to write", required=True) 92bf215546Sopenharmony_ci parser.add_argument("xml_files", nargs='+', help="List of xml metrics files to process") 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci args = parser.parse_args() 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci c = SourceFile(args.code) 97bf215546Sopenharmony_ci h = SourceFile(args.header) 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci prods = [] 100bf215546Sopenharmony_ci for xml_file in args.xml_files: 101bf215546Sopenharmony_ci prods.append(Product(xml_file)) 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci tab_size = 3 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci copyright = textwrap.dedent("""\ 106bf215546Sopenharmony_ci /* Autogenerated file, DO NOT EDIT manually! generated by {} 107bf215546Sopenharmony_ci * 108bf215546Sopenharmony_ci * Copyright © 2021 Arm Limited 109bf215546Sopenharmony_ci * Copyright © 2021 Collabora Ltd. 110bf215546Sopenharmony_ci * 111bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 112bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 113bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 114bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 115bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 116bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 117bf215546Sopenharmony_ci * 118bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 119bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 120bf215546Sopenharmony_ci * Software. 121bf215546Sopenharmony_ci * 122bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 123bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 124bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 125bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 126bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 127bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 128bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 129bf215546Sopenharmony_ci */ 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci """).format(os.path.basename(__file__)) 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci h.write(copyright) 134bf215546Sopenharmony_ci h.write(textwrap.dedent("""\ 135bf215546Sopenharmony_ci #ifndef PAN_PERF_METRICS_H 136bf215546Sopenharmony_ci #define PAN_PERF_METRICS_H 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci #include "perf/pan_perf.h" 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci """)) 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci c.write(copyright) 143bf215546Sopenharmony_ci c.write("#include \"" + os.path.basename(args.header) + "\"") 144bf215546Sopenharmony_ci c.write(textwrap.dedent("""\ 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci #include <util/macros.h> 147bf215546Sopenharmony_ci """)) 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci for prod in prods: 150bf215546Sopenharmony_ci c.write(textwrap.dedent(""" 151bf215546Sopenharmony_ci static void UNUSED 152bf215546Sopenharmony_ci static_asserts_%s(void) 153bf215546Sopenharmony_ci { 154bf215546Sopenharmony_ci """ % prod.id)) 155bf215546Sopenharmony_ci c.indent(tab_size) 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci n_categories = len(prod.categories) 158bf215546Sopenharmony_ci c.write("STATIC_ASSERT(%u <= PAN_PERF_MAX_CATEGORIES);" % n_categories) 159bf215546Sopenharmony_ci n_counters = 0 160bf215546Sopenharmony_ci for category in prod.categories: 161bf215546Sopenharmony_ci category_counters_count = len(category.counters) 162bf215546Sopenharmony_ci c.write("STATIC_ASSERT(%u <= PAN_PERF_MAX_COUNTERS);" % category_counters_count) 163bf215546Sopenharmony_ci n_counters += category_counters_count 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci c.outdent(tab_size) 166bf215546Sopenharmony_ci c.write("}\n") 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci current_struct_name = "panfrost_perf_config_%s" % prod.id 170bf215546Sopenharmony_ci c.write("\nconst struct panfrost_perf_config %s = {" % current_struct_name) 171bf215546Sopenharmony_ci c.indent(tab_size) 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci c.write(".name = \"%s\"," % prod.name) 174bf215546Sopenharmony_ci c.write(".n_categories = %u," % len(prod.categories)) 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci c.write(".categories = {") 177bf215546Sopenharmony_ci c.indent(tab_size) 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci counter_id = 0 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci for i in range(0, len(prod.categories)): 182bf215546Sopenharmony_ci category = prod.categories[i] 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci c.write("{") 185bf215546Sopenharmony_ci c.indent(tab_size) 186bf215546Sopenharmony_ci c.write(".name = \"%s\"," % (category.name)) 187bf215546Sopenharmony_ci c.write(".n_counters = %u," % (len(category.counters))) 188bf215546Sopenharmony_ci c.write(".counters = {") 189bf215546Sopenharmony_ci c.indent(tab_size) 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci for j in range(0, len(category.counters)): 192bf215546Sopenharmony_ci counter = category.counters[j] 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci assert counter_id < n_counters 195bf215546Sopenharmony_ci c.write("{") 196bf215546Sopenharmony_ci c.indent(tab_size) 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci c.write(".name = \"%s\"," % (counter.name)) 199bf215546Sopenharmony_ci c.write(".desc = \"%s\"," % (counter.desc.replace("\\", "\\\\"))) 200bf215546Sopenharmony_ci c.write(".symbol_name = \"%s\"," % (counter.underscore_name)) 201bf215546Sopenharmony_ci c.write(".units = PAN_PERF_COUNTER_UNITS_%s," % (counter.units.upper())) 202bf215546Sopenharmony_ci c.write(".offset = %u," % (counter.offset)) 203bf215546Sopenharmony_ci c.write(".category_index = %u," % i) 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci c.outdent(tab_size) 206bf215546Sopenharmony_ci c.write("}, // counter") 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci counter_id += 1 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci c.outdent(tab_size) 211bf215546Sopenharmony_ci c.write("}, // counters") 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci c.outdent(tab_size) 214bf215546Sopenharmony_ci c.write("}, // category") 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci c.outdent(tab_size) 217bf215546Sopenharmony_ci c.write("}, // categories") 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci c.outdent(tab_size) 220bf215546Sopenharmony_ci c.write("}; // %s\n" % current_struct_name) 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci h.write("extern const struct panfrost_perf_config * panfrost_perf_configs[%u];\n" % len(prods)) 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci c.write("\nconst struct panfrost_perf_config * panfrost_perf_configs[] = {") 225bf215546Sopenharmony_ci c.indent(tab_size) 226bf215546Sopenharmony_ci for prod in prods: 227bf215546Sopenharmony_ci c.write("&panfrost_perf_config_%s," % prod.id) 228bf215546Sopenharmony_ci c.outdent(tab_size) 229bf215546Sopenharmony_ci c.write("};") 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci h.write("\n#endif // PAN_PERF_METRICS_H") 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ciif __name__ == '__main__': 235bf215546Sopenharmony_ci main() 236