blob: aba724974b7c5a3fe048c7052809ced78b49b873 [file] [log] [blame]
Andrew Geissler84ad7c52020-06-27 00:00:16 -05001import argparse
2import libfdt
3import os
4import sys
5
6# Format: FEATURE : (dtb property, condition_operator, condition_value)
7# If dtb property is None, then the item is always on
8#
9# If the condition_operator is None, then enable if it exists for existance
10#
11# If the condition_operator is '!', and condition_value is None then enable if
12# if is not defined
13#
14# Otherwise 'condition' and value are evaluated by type.
15
16microblaze_tune_features = {
17 'microblaze' : (None, None, None),
18 'bigendian': ('xlnx,endianness', '!', 1),
19 '64-bit' : ('xlnx,data-size', '=', 64),
20 'barrel-shift': ('xlnx,use-barrel', '=', 1),
21 'pattern-compare': ('xlnx,use-pcmp-instr', '=', 1),
22 'reorder' : ('xlnx,use-reorder-instr', '!', 0),
23 'frequency-optimized': ('xlnx,area-optimized', '=', 2),
24 'multiply-low': ('xlnx,use-hw-mul', '=', 1),
25 'multiply-high': ('xlnx,use-hw-mul', '=', 2),
26 'divide-high': ('xlnx,use-div', '=', 1),
27 'fpu-soft': ('xlnx,use-fpu', '!', [1,2]),
28 'fpu-hard': ('xlnx,use-fpu', '=', 1),
29 'fpu-hard-extended':('xlnx,use-fpu', '=', 2),
30}
31
32def processProperties(fdt, node):
33 TUNE_FEATURES = []
34
35 for feature in microblaze_tune_features:
36 (property, cop, cvalue) = microblaze_tune_features[feature]
37
38 if not property:
39 TUNE_FEATURES.append(feature)
40
41 # Special processing to get the version
42 if feature == "microblaze":
43 ver = microblazeVersion(fdt, node)
44 if ver:
45 TUNE_FEATURES.append(ver)
46 continue
47
48 prop_value = fdt.getprop( node, property, libfdt.QUIET_NOTFOUND)
49
50 if not prop_value or prop_value == -1:
51 if cop == '!':
52 if not cvalue:
53 TUNE_FEATURES.append(ver)
54 continue
55 continue
56
57 # If no operator
58 if not cop or (cop == '=' and not cvalue):
59 TUNE_FEATURES.append(feature)
60 continue
61
62 ctype = type(cvalue)
63 if ctype == type(list()):
64 val_list = cvalue
65 else:
66 val_list = [ cvalue ]
67
68 result = False
69 for value in val_list:
70 ctype = type(value)
71 if ctype == type(int()):
72 val = prop_value.as_uint32()
73 else:
74 raise TypeError('Unknown type %s' % ctype)
75
76 if cop == '!':
77 if value != val:
78 result = True
79 else:
80 result = False
81 continue
82
83 if cop == '=':
84 if value == val:
85 result = True
86 else:
87 result = False
88 continue
89
90 if result == True:
91 TUNE_FEATURES.append(feature)
92
93 return TUNE_FEATURES
94
95def microblazeVersion(fdt, node):
96 version = None
97
98 val = fdt.getprop( node, 'model', libfdt.QUIET_NOTFOUND)
99
100 if val and val != -1:
101 val = fdt.getprop( node, 'model' ).as_str()
102 version = val[val.find('microblaze,') + 11:]
103
104 if version.startswith('8'):
105 # Strip 8.xx.y, to just 8.xx
106 v = version.split('.')
107 version = '.'.join(v[0:2])
108
109 version = 'v' + version
110
111 return version
112
113def MicroblazeConfig(dtbfile, out):
114 fdt = libfdt.Fdt(open(dtbfile, mode='rb').read())
115
116 cpu = -1
117 while (True):
118 cpu = cpu + 1
119 try:
120 node = fdt.path_offset('/cpus/cpu@%d' % cpu)
121
122 try:
123 prop = fdt.getprop( node, 'compatible' )
124
125 prop_val = prop[:-1].decode('utf-8').split('\x00')
126
127 microblaze = False
128 for val in prop_val:
129 if "microblaze" in val:
130 microblaze = True
131 break
132
133 if not microblaze:
134 continue
135
136 # Construct TUNE_FEATURE here
137 TUNE_FEATURES = processProperties(fdt, node)
138
139 out.write('AVAILTUNES += "microblaze-cpu%s"\n' % (cpu))
140 out.write('TUNE_FEATURES_tune-microblaze-cpu%s = "%s"\n' % (cpu, ' '.join(TUNE_FEATURES)))
141 out.write('PACKAGE_EXTRA_ARCHS_tune-microblaze-cpu%s = "${TUNE_PKGARCH}"\n' % (cpu))
142
143 except Exception as e:
144 sys.stderr.write("Exception looking at properties: %s\n" % e)
145
146 continue
147
148 except Exception as e:
149 # CPUs SHOULD be consecutive w/o gaps, so no more to search
150 break
151
152if __name__ == "__main__":
153 parser = argparse.ArgumentParser(description='Generate MicroBlaze TUNE_FEATURES')
154
155 parser.add_argument('-d', '--dtb-file', action='store',
156 help='DTB file to process')
157
158 parser.add_argument('-o', '--output', action='store',
159 help='Output file to store TUNE_FEATURE settings')
160
161 args = parser.parse_args()
162
163 if not args.dtb_file:
164 sys.stderr.write('ERROR: You must specify a DTB_FILE to process.\n')
165 sys.exit(1)
166
167 outputf = sys.stdout
168 if args.output:
169 if os.path.exists(args.output):
170 sys.stderr.write('ERROR: The output file "%s" exists!\n' % args.output)
171 sys.exit(1)
172 outputf = open(args.output, 'w')
173
174 MicroblazeConfig(args.dtb_file, outputf)