Revert "Revert "mb/sifive: Add Hifive Unmatched mainboard""

This reverts commit ec7b48076009cfe82e5ee91050f5fc66c4850193.

Reason for revert: <Reland>

I made the commit out of order with the fu740 commit; that's now
merged so there should be no problem.

Signed-off-by: ron minnich <rminnich@gmail.com>

Change-Id: I2fb8c2e0a7fcd5f26f4a004e0949332b108b6fcf
Reviewed-on: https://review.coreboot.org/c/coreboot/+/81052
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin L Roth <gaumless@gmail.com>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: ron minnich <rminnich@gmail.com>
diff --git a/src/mainboard/sifive/hifive-unmatched/fixup_fdt.c b/src/mainboard/sifive/hifive-unmatched/fixup_fdt.c
new file mode 100644
index 0000000..ed24ee3
--- /dev/null
+++ b/src/mainboard/sifive/hifive-unmatched/fixup_fdt.c
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console/console.h>
+#include <soc/otp.h>
+#include <soc/sdram.h>
+#include <cbfs.h>
+#include <device_tree.h>
+#include <bootstate.h>
+#include <mcall.h>
+
+static void do_fixup_mac(struct device_tree_node *node)
+{
+	uint32_t serial = otp_read_serial();
+	static unsigned char mac[6] = { 0x70, 0xb3, 0xd5, 0x92, 0xf0, 0x00 };
+	if (serial != ~0) {
+		mac[5] |= (serial >>  0) & 0xff;
+		mac[4] |= (serial >>  8) & 0xff;
+		mac[3] |= (serial >> 16) & 0xff;
+	}
+	dt_add_bin_prop(node, "local-mac-address", mac, 6);
+}
+
+static void fixup_mac(struct device_tree_node *parent)
+{
+	struct device_tree_property *prop;
+	const char *name = "local-mac-address";
+
+	list_for_each(prop, parent->properties, list_node) {
+		if (!strcmp(name, prop->prop.name))
+			do_fixup_mac(parent);
+	}
+
+	struct device_tree_node *child;
+	list_for_each(child, parent->children, list_node) {
+		fixup_mac(child);
+	}
+}
+
+static void do_fixup_memory(struct device_tree_node *node)
+{
+	u64 addrs[1], sizes[1];
+	addrs[0] = 0x80000000;
+	sizes[0] = sdram_size();
+	dt_add_reg_prop(node, addrs, sizes, 1, 2, 2);
+}
+
+static void fixup_memory(struct device_tree_node *parent)
+{
+	struct device_tree_property *prop;
+	const char *name = "device_type";
+	const char *value = "memory";
+
+	list_for_each(prop, parent->properties, list_node) {
+		if (!strcmp(name, prop->prop.name)) {
+			if (!strcmp(value, (char *)prop->prop.data))
+				do_fixup_memory(parent);
+		}
+	}
+
+	struct device_tree_node *child;
+	list_for_each(child, parent->children, list_node) {
+		fixup_memory(child);
+	}
+}
+
+static void fixup_fdt(void *unused)
+{
+	printk(BIOS_DEBUG, "fix up FDT\n");
+
+	void *fdt_rom;
+	struct device_tree *tree;
+
+	/* load flat dt from cbfs */
+	fdt_rom = cbfs_map("fallback/DTB", NULL);
+
+	if (fdt_rom == NULL) {
+		printk(BIOS_ERR, "Unable to load fallback/DTB from CBFS\n");
+		return;
+	}
+
+	/* Expand DT into a tree */
+	tree = fdt_unflatten(fdt_rom);
+
+	/* fixup tree */
+	fixup_mac(tree->root);
+	fixup_memory(tree->root);
+
+	/* convert the tree to a flat dt */
+	void *dt = malloc(dt_flat_size(tree));
+
+	if (dt == NULL) {
+		printk(BIOS_ERR, "Unable to allocate memory for flat device tree\n");
+		return;
+	}
+
+	dt_flatten(tree, dt);
+
+	/* update HLS */
+	for (int i = 0; i < CONFIG_MAX_CPUS; i++)
+		OTHER_HLS(i)->fdt = dt;
+}
+
+BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_EXIT, fixup_fdt, NULL);