summaryrefslogtreecommitdiffstats
path: root/common/boards/qemu-virt/board.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/boards/qemu-virt/board.c')
-rw-r--r--common/boards/qemu-virt/board.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/common/boards/qemu-virt/board.c b/common/boards/qemu-virt/board.c
index 4064409c80..4f2f7374c5 100644
--- a/common/boards/qemu-virt/board.c
+++ b/common/boards/qemu-virt/board.c
@@ -7,6 +7,7 @@
#include <init.h>
#include <of.h>
#include <deep-probe.h>
+#include "qemu-virt-flash.h"
#ifdef CONFIG_64BIT
#define MACHINE "virt64"
@@ -34,35 +35,56 @@ static inline void arm_virt_init(void)
static inline void arm_virt_init(void) {}
#endif
-extern char __dtb_overlay_of_flash_start[];
+extern char __dtbo_qemu_virt_flash_start[];
+extern char __dtb_fitimage_pubkey_start[];
-static int virt_probe(struct device_d *dev)
+static const struct of_device_id virt_of_match[] = {
+ { .compatible = "linux,dummy-virt", .data = arm_virt_init },
+ { .compatible = "riscv-virtio" },
+ { /* Sentinel */},
+};
+BAREBOX_DEEP_PROBE_ENABLE(virt_of_match);
+
+/*
+ * We don't have a dedicated qemu-virt device tree and instead rely
+ * on what Qemu passes us. To be able to get fundamental changes
+ * in very early, we forego having a board driver here and do this
+ * directly in the initcall.
+ */
+static int virt_board_driver_init(void)
{
- struct device_node *overlay;
+ struct device_node *root = of_get_root_node();
+ struct device_node *flash, *overlay, *pubkey;
+ const struct of_device_id *id;
void (*init)(void);
- init = device_get_match_data(dev);
- if (init)
+ id = of_match_node(virt_of_match, root);
+ if (!id)
+ return 0;
+
+ if (id->data) {
+ init = id->data;
init();
+ }
- overlay = of_unflatten_dtb(__dtb_overlay_of_flash_start, INT_MAX);
- of_overlay_apply_tree(dev->device_node, overlay);
- /* of_probe() will happen later at of_populate_initcall */
+ /*
+ * Catch both old Qemu versions that place /flash in /soc and
+ * configurations, where the first flash bank is secure-world only
+ */
+ flash = of_find_node_by_path(PARTS_TARGET_PATH_STR);
+ if (flash && of_device_is_available(flash)) {
+ overlay = of_unflatten_dtb(__dtbo_qemu_virt_flash_start, INT_MAX);
+ of_overlay_apply_tree(root, overlay);
+ }
- return 0;
-}
+ pubkey = of_unflatten_dtb(__dtb_fitimage_pubkey_start, INT_MAX);
+ of_merge_nodes(root, pubkey);
-static const struct of_device_id virt_of_match[] = {
- { .compatible = "linux,dummy-virt", .data = arm_virt_init },
- { .compatible = "riscv-virtio" },
- { /* Sentinel */},
-};
-BAREBOX_DEEP_PROBE_ENABLE(virt_of_match);
+ /* fragment may have added aliases to the DT */
+ of_alias_scan();
-static struct driver_d virt_board_driver = {
- .name = "board-qemu-virt",
- .probe = virt_probe,
- .of_compatible = virt_of_match,
-};
+ /* of_probe() will happen later at of_populate_initcall */
-postcore_platform_driver(virt_board_driver);
+ return 0;
+}
+postcore_initcall(virt_board_driver_init);