From e72a682cfb7d353ebb10b4afa365809b5bd2dd05 Mon Sep 17 00:00:00 2001 From: Mark Hatle Date: Mon, 9 Mar 2020 18:39:50 +0000 Subject: microblaze_dtb.py: Convert a dtb to one or more microblaze TUNE_FEATURES Because the microblaze is adjustable on the FPGA, we need a way for the system to adjust the TUNE_FEATURES for a given build. The device tree can specify the capabilities of the microblaze implementations defined in a specific design. If present, these can then be processed to provide a set of TUNE_FEATURES for each declared microblaze CPU. The output of the tool is formated in a way that it can be directly included in the user's local.conf, or placed in a file that is included by a machine or other file. The user will only have to declare the DEFAULTTUNE value that matches one of the generated tunes. General rules that are implemented: TUNE_FEATURE CONDITION ------------ ------------------------------- microblaze (all microblaze cpus) bigendian xlnx,endianness is not 1 64-bit xlnx,data-size is 64 barrel-shift xlnx,use-barrel is 1 pattern-compare xlnx,use-pcmp-instr is 1 reorder xlnx,use-reorder-instr is not 0 frequency-optimized xlnx,area-optimized is 2 multiply-low xlnx,use-hw-mul is 1 multiple-high xlnx,use-hw-mul is 2 divide-hard xlnx,use-div is 1 fpu-soft xlnx,use-fpu is not 1 or 2 fpu-hard xlnx,use-fpu is 1 fpu-hard-extended xlnx,use-fpu is 2 vX.YY model value of X.YY[.Z] Signed-off-by: Mark Hatle --- meta-xilinx-standalone/microblaze_dtb.py | 174 +++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 meta-xilinx-standalone/microblaze_dtb.py diff --git a/meta-xilinx-standalone/microblaze_dtb.py b/meta-xilinx-standalone/microblaze_dtb.py new file mode 100644 index 00000000..aba72497 --- /dev/null +++ b/meta-xilinx-standalone/microblaze_dtb.py @@ -0,0 +1,174 @@ +import argparse +import libfdt +import os +import sys + +# Format: FEATURE : (dtb property, condition_operator, condition_value) +# If dtb property is None, then the item is always on +# +# If the condition_operator is None, then enable if it exists for existance +# +# If the condition_operator is '!', and condition_value is None then enable if +# if is not defined +# +# Otherwise 'condition' and value are evaluated by type. + +microblaze_tune_features = { + 'microblaze' : (None, None, None), + 'bigendian': ('xlnx,endianness', '!', 1), + '64-bit' : ('xlnx,data-size', '=', 64), + 'barrel-shift': ('xlnx,use-barrel', '=', 1), + 'pattern-compare': ('xlnx,use-pcmp-instr', '=', 1), + 'reorder' : ('xlnx,use-reorder-instr', '!', 0), + 'frequency-optimized': ('xlnx,area-optimized', '=', 2), + 'multiply-low': ('xlnx,use-hw-mul', '=', 1), + 'multiply-high': ('xlnx,use-hw-mul', '=', 2), + 'divide-high': ('xlnx,use-div', '=', 1), + 'fpu-soft': ('xlnx,use-fpu', '!', [1,2]), + 'fpu-hard': ('xlnx,use-fpu', '=', 1), + 'fpu-hard-extended':('xlnx,use-fpu', '=', 2), +} + +def processProperties(fdt, node): + TUNE_FEATURES = [] + + for feature in microblaze_tune_features: + (property, cop, cvalue) = microblaze_tune_features[feature] + + if not property: + TUNE_FEATURES.append(feature) + + # Special processing to get the version + if feature == "microblaze": + ver = microblazeVersion(fdt, node) + if ver: + TUNE_FEATURES.append(ver) + continue + + prop_value = fdt.getprop( node, property, libfdt.QUIET_NOTFOUND) + + if not prop_value or prop_value == -1: + if cop == '!': + if not cvalue: + TUNE_FEATURES.append(ver) + continue + continue + + # If no operator + if not cop or (cop == '=' and not cvalue): + TUNE_FEATURES.append(feature) + continue + + ctype = type(cvalue) + if ctype == type(list()): + val_list = cvalue + else: + val_list = [ cvalue ] + + result = False + for value in val_list: + ctype = type(value) + if ctype == type(int()): + val = prop_value.as_uint32() + else: + raise TypeError('Unknown type %s' % ctype) + + if cop == '!': + if value != val: + result = True + else: + result = False + continue + + if cop == '=': + if value == val: + result = True + else: + result = False + continue + + if result == True: + TUNE_FEATURES.append(feature) + + return TUNE_FEATURES + +def microblazeVersion(fdt, node): + version = None + + val = fdt.getprop( node, 'model', libfdt.QUIET_NOTFOUND) + + if val and val != -1: + val = fdt.getprop( node, 'model' ).as_str() + version = val[val.find('microblaze,') + 11:] + + if version.startswith('8'): + # Strip 8.xx.y, to just 8.xx + v = version.split('.') + version = '.'.join(v[0:2]) + + version = 'v' + version + + return version + +def MicroblazeConfig(dtbfile, out): + fdt = libfdt.Fdt(open(dtbfile, mode='rb').read()) + + cpu = -1 + while (True): + cpu = cpu + 1 + try: + node = fdt.path_offset('/cpus/cpu@%d' % cpu) + + try: + prop = fdt.getprop( node, 'compatible' ) + + prop_val = prop[:-1].decode('utf-8').split('\x00') + + microblaze = False + for val in prop_val: + if "microblaze" in val: + microblaze = True + break + + if not microblaze: + continue + + # Construct TUNE_FEATURE here + TUNE_FEATURES = processProperties(fdt, node) + + out.write('AVAILTUNES += "microblaze-cpu%s"\n' % (cpu)) + out.write('TUNE_FEATURES_tune-microblaze-cpu%s = "%s"\n' % (cpu, ' '.join(TUNE_FEATURES))) + out.write('PACKAGE_EXTRA_ARCHS_tune-microblaze-cpu%s = "${TUNE_PKGARCH}"\n' % (cpu)) + + except Exception as e: + sys.stderr.write("Exception looking at properties: %s\n" % e) + + continue + + except Exception as e: + # CPUs SHOULD be consecutive w/o gaps, so no more to search + break + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Generate MicroBlaze TUNE_FEATURES') + + parser.add_argument('-d', '--dtb-file', action='store', + help='DTB file to process') + + parser.add_argument('-o', '--output', action='store', + help='Output file to store TUNE_FEATURE settings') + + args = parser.parse_args() + + if not args.dtb_file: + sys.stderr.write('ERROR: You must specify a DTB_FILE to process.\n') + sys.exit(1) + + outputf = sys.stdout + if args.output: + if os.path.exists(args.output): + sys.stderr.write('ERROR: The output file "%s" exists!\n' % args.output) + sys.exit(1) + outputf = open(args.output, 'w') + + MicroblazeConfig(args.dtb_file, outputf) -- cgit v1.2.3-54-g00ecf