util/sconfig: Enable parsing of override device tree

This change allows sconfig utility to accept an extra optional
parameter to specify override device tree that can be used to override
the properties or add new devices in addition to that provided by base
device tree. This is helpful for variants that share most of the
devicetree but have to override certain registers or add some devices
which might not be applicable to base devicetree.

In order to support the override devicetree, following changes are
made in this CL:
1. override_root_dev and override_root_bus are provided.
2. main() function is updated to accept an optional argument.
3. If override device file is provided, then parse_devicetree is
called for override_devtree as well.

This change in itself does not provide the override feature. It is
only a small step towards the final goal. The override devicetree
parsed by sconfig is currently unused.

BUG=b:80081934

Change-Id: I477e038c8922ae1a9ed5d8bf22a5f927a19a69c7
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/26689
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
diff --git a/util/sconfig/main.c b/util/sconfig/main.c
index b293c5d..06e991e 100644
--- a/util/sconfig/main.c
+++ b/util/sconfig/main.c
@@ -75,7 +75,13 @@
  *
  *
  */
+
+/* Root device of primary tree. */
 static struct device base_root_dev;
+
+/* Root device of override tree (if applicable). */
+static struct device override_root_dev;
+
 static struct chip_instance mainboard_instance;
 
 static struct bus base_root_bus = {
@@ -94,6 +100,28 @@
 	.bus = &base_root_bus,
 };
 
+static struct bus override_root_bus = {
+	.id = 0,
+	.dev = &override_root_dev,
+};
+
+static struct device override_root_dev = {
+	.name = "override_root",
+	.id = 0,
+	/*
+	 * Override tree root device points to the same mainboard chip instance
+	 * as the base tree root device. It should not cause any side-effects
+	 * since the mainboard chip instance pointer in override tree will just
+	 * be ignored.
+	 */
+	.chip_instance = &mainboard_instance,
+	.path = " .type = DEVICE_PATH_ROOT ",
+	.ops = "&default_dev_ops_root",
+	.parent = &override_root_bus,
+	.enabled = 1,
+	.bus = &override_root_bus,
+};
+
 static struct chip mainboard_chip = {
 	.name = "mainboard",
 	.name_underscore = "mainboard",
@@ -857,16 +885,19 @@
 
 static void usage(void)
 {
-	printf("usage: sconfig devicetree_file output_file\n");
+	printf("usage: sconfig devicetree_file output_file [override_devicetree_file]\n");
 	exit(1);
 }
 
 enum {
 	DEVICEFILE_ARG = 1,
-	OUTPUTFILE_ARG
+	OUTPUTFILE_ARG,
+	OVERRIDE_DEVICEFILE_ARG,
 };
 
-#define ARG_COUNT		3
+#define MANDATORY_ARG_COUNT		3
+#define OPTIONAL_ARG_COUNT		1
+#define TOTAL_ARG_COUNT		(MANDATORY_ARG_COUNT + OPTIONAL_ARG_COUNT)
 
 static void parse_devicetree(const char *file, struct bus *parent)
 {
@@ -888,14 +919,20 @@
 
 int main(int argc, char **argv)
 {
-	if (argc != ARG_COUNT)
+	if ((argc < MANDATORY_ARG_COUNT) || (argc > TOTAL_ARG_COUNT))
 		usage();
 
-	char *base_devtree = argv[DEVICEFILE_ARG];
-	char *outputc = argv[OUTPUTFILE_ARG];
+	const char *base_devtree = argv[DEVICEFILE_ARG];
+	const char *outputc = argv[OUTPUTFILE_ARG];
+	const char *override_devtree;
 
 	parse_devicetree(base_devtree, &base_root_bus);
 
+	if (argc == TOTAL_ARG_COUNT) {
+		override_devtree = argv[OVERRIDE_DEVICEFILE_ARG];
+		parse_devicetree(override_devtree, &override_root_bus);
+	}
+
 	FILE *autogen = fopen(outputc, "w");
 	if (!autogen) {
 		fprintf(stderr, "Could not open file '%s' for writing: ",