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)
