#!/usr/bin/env python3 import os,sys import optparse import subprocess import re import operator # map of Workaround names -> (list of platforms) workarounds = {} verbose = False def find_nth(haystack, needle, n): start = haystack.find(needle) while start >= 0 and n > 1: start = haystack.find(needle, start + len(needle)) n -= 1 return start valid_platforms = ('ctg', 'elk', 'ilk', 'snb', 'ivb', 'vlv', 'hsw', 'bdw', 'chv', 'skl', 'bxt', 'kbl') def parse_platforms(line, p): l = p.split(',') for p in l: if p not in valid_platforms: sys.stdout.write("warning: %s\n" % line) sys.stdout.write("unknown platform %s\n" % p) return l wa_re = re.compile('(?PW[aA][A-Z0-9][a-zA-Z0-9_]+):(?P[a-z,]+)') waname_re = re.compile('(?PW[aA][A-Z0-9][a-zA-Z0-9_]+)') def parse(me): for line in me.splitlines(): match = wa_re.search(str(line)) if not match: if not verbose: continue # Those lines come from a git grep that looks for Wa # names, so if we don't match wa_re here it's because # no platform has been specified name = waname_re.search(line).group('name') path = line[:find_nth(line, ':', 2)] sys.stdout.write("warning: %s\n" % line) sys.stdout.write("%s: no platform for %s\n" % (path, name)) continue wa_name = match.group('name') platforms = match.group('platforms') if wa_name in workarounds: platforms = parse_platforms(line, platforms) for p in platforms: if not p in workarounds[wa_name]: workarounds[wa_name].append(p) else: workarounds[wa_name] = parse_platforms(line, platforms) def execute(cmd): p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() return out, err def parse_options(args): usage = "Usage: list-workarounds [options] path-to-kernel -k path-to-kernel -m path-to-mesa" parser = optparse.OptionParser(usage, version=1.0) parser.add_option("-k", "--kernel-path", dest="kernel_path", default=None, help="path to kernel") parser.add_option("-m", "--mesa-path", dest="mesa_path", default=None, help="path to mesa") parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="be more verbose") parser.add_option("-p", "--platform", dest="platform", default=None, help="List workarounds for the specified platform") (options, args) = parser.parse_args() return (options, args) def print_workarounds(project_root, driver_dir, project): olddir = os.getcwd() os.chdir(project_root) work_arounds, err = execute(['git', 'grep', '-n', '-e', 'W[aA][A-Z0-9][a-zA-Z0-9_]\+', driver_dir]) os.chdir(olddir) if err: print(err) sys.exit(1) parse(work_arounds) print("\nList of workarounds found in %s:" % project) for wa in sorted(workarounds.keys()): if not options.platform: print("%s: %s" % (wa, ', '.join(workarounds[wa]))) elif options.platform in workarounds[wa]: print(wa) if __name__ == '__main__': (options, args) = parse_options(sys.argv) verbose = options.verbose kernel_path = None if not len(args) and options.kernel_path == None and options.mesa_path == None: sys.stderr.write("error: A path to either a kernel tree or Mesa is required\n") sys.exit(1) if len(args): kernel_path = args[0] elif options.kernel_path != None: kernel_path = options.kernel_path if kernel_path != None: # --- list Kernel workarounds if path is provided --- kconfig = os.path.join(kernel_path, 'Kconfig') if not os.path.isfile(kconfig): sys.stderr.write("error: %s does not point to a kernel tree \n" % kernel_path) sys.exit(1) i915_dir = os.path.join('drivers', 'gpu', 'drm', 'i915') print_workarounds(kernel_path, i915_dir, "kernel") # --- list mesa workarounds if path is provided --- if options.mesa_path != None: # reset workarounds array workarounds = {} mesa_path = options.mesa_path i965_dir = os.path.join('src', 'mesa', 'drivers', 'dri', 'i965') mesa_dir = os.path.join(mesa_path, i965_dir) if not os.path.exists(mesa_dir): sys.stderr.write("error: %s does not point to a valid mesa path \n" % mesa_path) sys.exit(1) print_workarounds(mesa_path, i965_dir, "Mesa")