1# Copyright © 2023 Intel Corporation 2 3# Permission is hereby granted, free of charge, to any person obtaining a 4# copy of this software and associated documentation files (the "Software"), 5# to deal in the Software without restriction, including without limitation 6# the rights to use, copy, modify, merge, publish, distribute, sublicense, 7# and/or sell copies of the Software, and to permit persons to whom the 8# Software is furnished to do so, subject to the following conditions: 9 10# The above copyright notice and this permission notice (including the next 11# paragraph) shall be included in all copies or substantial portions of the 12# Software. 13 14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20# IN THE SOFTWARE. 21 22import argparse 23import collections 24import json 25import os 26import sys 27from mako.template import Template 28 29HEADER_TEMPLATE = Template("""\ 30/* 31 * Copyright © 2023 Intel Corporation 32 * 33 * Permission is hereby granted, free of charge, to any person obtaining a 34 * copy of this software and associated documentation files (the "Software"), 35 * to deal in the Software without restriction, including without limitation 36 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 37 * and/or sell copies of the Software, and to permit persons to whom the 38 * Software is furnished to do so, subject to the following conditions: 39 * 40 * The above copyright notice and this permission notice (including the next 41 * paragraph) shall be included in all copies or substantial portions of the 42 * Software. 43 * 44 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 47 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 48 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 49 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 50 * IN THE SOFTWARE. 51 * 52 */ 53 54#ifndef INTEL_WA_H 55#define INTEL_WA_H 56 57#include "util/macros.h" 58 59#ifdef __cplusplus 60extern "C" { 61#endif 62 63struct intel_device_info; 64void intel_device_info_init_was(struct intel_device_info *devinfo); 65 66enum intel_wa_steppings { 67% for a in stepping_enum: 68 INTEL_STEPPING_${a}, 69% endfor 70 INTEL_STEPPING_RELEASE 71}; 72 73enum intel_workaround_id { 74% for a in wa_def: 75 INTEL_WA_${a}, 76% endfor 77 INTEL_WA_NUM 78}; 79 80/* These defines apply workarounds to a subset of platforms within a graphics 81 * generation. They must be used in conjunction with intel_needs_workaround() 82 * to check platform details. Use these macros to compile out genxml code on 83 * generations where it can never execute. Whenever possible, prefer use of 84 * INTEL_NEEDS_WA_{num} instead of INTEL_WA_{num}_GFX_VER 85 */ 86% for a in wa_def: 87#define INTEL_WA_${a}_GFX_VER ${wa_macro[a]} 88% endfor 89 90/* These defines may be used to compile out genxml workaround implementations 91 * using #if guards. If a definition has been 'poisoned' below, then it applies to a 92 * subset of a graphics generation. In that case, use INTEL_WA_{NUM}_GFX_VER macros 93 * in conjunction with calls to intel_needs_workaround(). 94 */ 95% for a in partial_gens: 96 % if partial_gens[a]: 97PRAGMA_POISON(INTEL_NEEDS_WA_${a}) 98 % else: 99#define INTEL_NEEDS_WA_${a} INTEL_WA_${a}_GFX_VER 100 % endif 101% endfor 102 103#define INTEL_ALL_WA ${"\\\\"} 104% for wa_id in wa_def: 105 INTEL_WA(${wa_id}), ${"\\\\"} 106% endfor 107 108#ifdef __cplusplus 109} 110#endif 111 112#endif /* INTEL_WA_H */ 113""") 114 115IMPL_TEMPLATE = Template("""\ 116/* 117 * Copyright © 2023 Intel Corporation 118 * 119 * Permission is hereby granted, free of charge, to any person obtaining a 120 * copy of this software and associated documentation files (the "Software"), 121 * to deal in the Software without restriction, including without limitation 122 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 123 * and/or sell copies of the Software, and to permit persons to whom the 124 * Software is furnished to do so, subject to the following conditions: 125 * 126 * The above copyright notice and this permission notice (including the next 127 * paragraph) shall be included in all copies or substantial portions of the 128 * Software. 129 * 130 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 131 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 132 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 133 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 134 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 135 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 136 * IN THE SOFTWARE. 137 * 138 */ 139 140#include "dev/intel_wa.h" 141#include "dev/intel_device_info.h" 142#include "util/bitset.h" 143 144void intel_device_info_init_was(struct intel_device_info *devinfo) 145{ 146 switch(devinfo->platform) { 147% for platform in platform_bugs: 148 case ${platform}: 149% if platform in stepping_bugs: 150 switch(intel_device_info_wa_stepping(devinfo)) { 151% for stepping, ids in stepping_bugs[platform].items(): 152 case INTEL_STEPPING_${stepping}: 153% for id in ids: 154 BITSET_SET(devinfo->workarounds, INTEL_WA_${id}); 155% endfor 156 break; 157% endfor 158 default: 159 break; 160 } 161% endif 162% for id in platform_bugs[platform]: 163 BITSET_SET(devinfo->workarounds, INTEL_WA_${id}); 164% endfor 165 break; 166% endfor 167 default: 168 /* unsupported platform */ 169 break; 170 }; 171} 172""") 173 174def stepping_enums(wa_def): 175 """provide a sorted list of all known steppings""" 176 stepping_enum = [] 177 for bug in wa_def.values(): 178 for platform_info in bug["mesa_platforms"].values(): 179 steppings = platform_info["steppings"] 180 if steppings == "all": 181 continue 182 steppings = steppings.split("..") 183 for stepping in steppings: 184 stepping = stepping.upper() 185 if stepping and stepping != "None" and stepping not in stepping_enum: 186 stepping_enum.append(stepping) 187 return sorted(stepping_enum) 188 189_PLATFORM_GFXVERS = {"INTEL_PLATFORM_BDW" : 80, 190 "INTEL_PLATFORM_CHV" : 80, 191 "INTEL_PLATFORM_SKL" : 90, 192 "INTEL_PLATFORM_BXT" : 90, 193 "INTEL_PLATFORM_KBL" : 90, 194 "INTEL_PLATFORM_GLK" : 90, 195 "INTEL_PLATFORM_CFL" : 90, 196 "INTEL_PLATFORM_ICL" : 110, 197 "INTEL_PLATFORM_EHL" : 110, 198 "INTEL_PLATFORM_TGL" : 120, 199 "INTEL_PLATFORM_RKL" : 120, 200 "INTEL_PLATFORM_DG1" : 120, 201 "INTEL_PLATFORM_ADL" : 120, 202 "INTEL_PLATFORM_RPL" : 120, 203 "INTEL_PLATFORM_DG2_G10" : 125, 204 "INTEL_PLATFORM_DG2_G11" : 125, 205 "INTEL_PLATFORM_DG2_G12" : 125, 206 "INTEL_PLATFORM_ATSM_G10" : 125, 207 "INTEL_PLATFORM_ATSM_G11" : 125, 208 "INTEL_PLATFORM_MTL_U" : 125, 209 "INTEL_PLATFORM_MTL_H" : 125, 210 "INTEL_PLATFORM_ARL_U" : 125, 211 "INTEL_PLATFORM_ARL_H" : 125, 212 "INTEL_PLATFORM_LNL" : 200, 213 "INTEL_PLATFORM_BMG" : 200, 214 } 215 216def macro_versions(wa_def): 217 """provide a map of workaround id -> GFX_VERx10 macro test""" 218 wa_macro = {} 219 for bug_id, bug in wa_def.items(): 220 platforms = set() 221 for platform in bug["mesa_platforms"]: 222 gfxver = _PLATFORM_GFXVERS[platform] 223 if gfxver not in platforms: 224 platforms.add(gfxver) 225 if not platforms: 226 continue 227 ver_cmps = [f"(GFX_VERx10 == {platform})" for platform in sorted(platforms)] 228 wa_macro[bug_id] = ver_cmps[0] 229 if len(ver_cmps) > 1: 230 wa_macro[bug_id] = f"({' || '.join(ver_cmps)})" 231 return wa_macro 232 233def partial_gens(wa_def): 234 """provide a map of workaround id -> true/false, indicating whether the wa 235 applies to a subset of platforms in a generation""" 236 wa_partial_gen = {} 237 238 # map of gfxver -> set(all platforms for gfxver) 239 generations = collections.defaultdict(set) 240 for platform, gfxver in _PLATFORM_GFXVERS.items(): 241 generations[gfxver].add(platform) 242 243 # map of platform -> set(all required platforms for gen completeness) 244 required_platforms = collections.defaultdict(set) 245 for gen_set in generations.values(): 246 for platform in gen_set: 247 required_platforms[platform] = gen_set 248 249 for bug_id, bug in wa_def.items(): 250 # for the given wa, create a set which includes all platforms that 251 # match any of the affected gfxver. 252 wa_required_for_completeness = set() 253 for platform in bug["mesa_platforms"]: 254 wa_required_for_completeness.update(required_platforms[platform]) 255 256 # eliminate each platform specifically indicated by the WA, to see if 257 # are left over. 258 for platform, desc in bug["mesa_platforms"].items(): 259 if desc["steppings"] == "all": 260 wa_required_for_completeness.remove(platform) 261 262 # if any platform remains in the required set, then this wa *partially* 263 # applies to one of the gfxvers. 264 wa_partial_gen[bug_id] = bool(wa_required_for_completeness) 265 return wa_partial_gen 266 267def platform_was(wa_def): 268 """provide a map of platform -> list of workarounds""" 269 platform_bugs = collections.defaultdict(list) 270 for workaround, bug in wa_def.items(): 271 for platform, desc in bug["mesa_platforms"].items(): 272 if desc["steppings"] != "all": 273 # stepping-specific workaround, not platform-wide 274 continue 275 platform_bugs[platform].append(workaround) 276 return platform_bugs 277 278def stepping_was(wa_def, all_steppings): 279 """provide a map of wa[platform][stepping] -> [ids]""" 280 stepping_bugs = collections.defaultdict(lambda: collections.defaultdict(list)) 281 for workaround, bug in wa_def.items(): 282 for platform, desc in bug["mesa_platforms"].items(): 283 if desc["steppings"] == "all": 284 continue 285 first_stepping, fixed_stepping = desc["steppings"].split("..") 286 first_stepping = first_stepping.upper() 287 fixed_stepping = fixed_stepping.upper() 288 steppings = [] 289 for step in all_steppings: 290 if step <first_stepping: 291 continue 292 if step >= fixed_stepping: 293 break 294 steppings.append(step) 295 for step in steppings: 296 u_step = step.upper() 297 stepping_bugs[platform][u_step].append(workaround) 298 stepping_bugs[platform][u_step].sort() 299 return stepping_bugs 300 301def main(): 302 """writes c/h generated files to outdir""" 303 parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) 304 parser.add_argument("wa_file", type=str, 305 help="json data file with workaround definitions") 306 parser.add_argument("header_file", help="include file to generate") 307 parser.add_argument("impl_file", help="implementation file to generate") 308 args = parser.parse_args() 309 if not os.path.exists(args.wa_file): 310 print(f"Error: workaround definition not found: {args.wa_file}") 311 sys.exit(-1) 312 313 # json dictionary of workaround definitions 314 wa_def = {} 315 with open(args.wa_file, encoding='utf8') as wa_fh: 316 wa_def = json.load(wa_fh) 317 318 # detect unknown platforms 319 unknown_platforms = set() 320 for wa in wa_def.values(): 321 for p in wa['mesa_platforms']: 322 if p not in _PLATFORM_GFXVERS: 323 unknown_platforms.add(p) 324 if unknown_platforms: 325 abbrev = map(lambda s: s.replace('INTEL_PLATFORM_', ''), 326 unknown_platforms) 327 raise Exception(f'warning: unknown platforms in {args.wa_file}: ' 328 f'{", ".join(abbrev)}') 329 330 steppings = stepping_enums(wa_def) 331 with open(args.header_file, 'w', encoding='utf8') as header: 332 header.write(HEADER_TEMPLATE.render(wa_def=wa_def, 333 stepping_enum=steppings, 334 wa_macro=macro_versions(wa_def), 335 partial_gens=partial_gens(wa_def))) 336 with open(args.impl_file, 'w', encoding='utf8') as impl: 337 impl.write(IMPL_TEMPLATE.render(platform_bugs=platform_was(wa_def), 338 stepping_bugs=stepping_was(wa_def, steppings))) 339 340main() 341