Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ea2a44f authored by Cosmin Tanislav's avatar Cosmin Tanislav
Browse files

merge_dtbs: Sort DTBOs based on needed symbols

Some DTBOs might use symbols from other DTBOs and require them to be
applied before them.

Sort them based on the __symbols__ and __fixups__ nodes, by creating a
dependency graph.

Change-Id: I40acf5da6b673b636a91f75ae3f3c634f2b5c505
parent 722d1ce1
Loading
Loading
Loading
Loading
+37 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import copy
import graphlib
import os
import sys
import subprocess
@@ -291,6 +292,14 @@ class DeviceTree(DeviceTreeInfo):
		if not self.has_any_properties():
			logging.warning('{} has no properties and may match with any other devicetree'.format(os.path.basename(self.filename)))

	def list_props(self, node):
		r = subprocess.run(["fdtget", "-p", self.filename, node],
			check=False, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
		if r.returncode != 0:
			return []
		out = r.stdout.decode("utf-8").strip()
		return out.splitlines()[:-1]

	def get_prop(self, node, property, prop_type='i', check_output=True):
		r = subprocess.run(["fdtget", "-t", prop_type, self.filename, node, property],
			check=check_output, stdout=subprocess.PIPE,
@@ -458,6 +467,25 @@ class MergedDeviceTree(object):
		for mdt in self.merged_devicetrees:
			yield mdt.save(name, out_dir)

def create_adjacency(devicetrees):
	graph = {}
	symbol_map = {}

	for dt in devicetrees:
		for symbol in dt.list_props('/__symbols__'):
			symbol_map.setdefault(symbol, []).append(dt.filename)

	for dt in devicetrees:
		graph[dt.filename] = set()

		for fixup in dt.list_props('/__fixups__'):
			if fixup not in symbol_map:
				continue

			graph[dt.filename].update(symbol_map[fixup])

	return graph

def parse_dt_files(dt_folder):
	devicetrees = []
	for root, dirs, files in os.walk(dt_folder):
@@ -468,6 +496,14 @@ def parse_dt_files(dt_folder):
			devicetrees.append(DeviceTree(filepath))
	return devicetrees

def parse_tech_dt_files(dt_folder):
	devicetrees = parse_dt_files(dt_folder)
	graph = create_adjacency(devicetrees)
	order = graphlib.TopologicalSorter(graph).static_order()
	order_index = {node: i for i, node in enumerate(order)}
	devicetrees.sort(key=lambda dt: order_index[dt.filename])
	return devicetrees

def main():

	parser = argparse.ArgumentParser(description='Merge devicetree blobs of techpacks with Kernel Platform SoCs')
@@ -487,7 +523,7 @@ def main():
	logging.info('Parsed bases: \n{}'.format(all_bases))

	logging.info('Parsing techpack dtb files from {}'.format(args.techpack))
	techpacks = parse_dt_files(args.techpack)
	techpacks = parse_tech_dt_files(args.techpack)
	all_techpacks = '\n'.join(list(map(lambda x: str(x), techpacks)))
	logging.info('Parsed techpacks: \n{}'.format(all_techpacks))