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