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