summaryrefslogtreecommitdiff
path: root/board/emulation/qemu-riscv
diff options
context:
space:
mode:
Diffstat (limited to 'board/emulation/qemu-riscv')
-rw-r--r--board/emulation/qemu-riscv/Kconfig5
-rw-r--r--board/emulation/qemu-riscv/MAINTAINERS2
-rw-r--r--board/emulation/qemu-riscv/qemu-riscv.c73
3 files changed, 71 insertions, 9 deletions
diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
index 37a80db6a94..56bb5337d4c 100644
--- a/board/emulation/qemu-riscv/Kconfig
+++ b/board/emulation/qemu-riscv/Kconfig
@@ -13,7 +13,8 @@ config SYS_CONFIG_NAME
default "qemu-riscv"
config SYS_TEXT_BASE
- default 0x80000000
+ default 0x80000000 if !RISCV_SMODE
+ default 0x80200000 if RISCV_SMODE
config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
@@ -29,5 +30,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
imply CMD_EXT2
imply CMD_EXT4
imply CMD_FAT
+ imply BOARD_LATE_INIT
+ imply OF_BOARD_SETUP
endif
diff --git a/board/emulation/qemu-riscv/MAINTAINERS b/board/emulation/qemu-riscv/MAINTAINERS
index 3c6eb4f844a..c701c83d77a 100644
--- a/board/emulation/qemu-riscv/MAINTAINERS
+++ b/board/emulation/qemu-riscv/MAINTAINERS
@@ -4,4 +4,6 @@ S: Maintained
F: board/emulation/qemu-riscv/
F: include/configs/qemu-riscv.h
F: configs/qemu-riscv32_defconfig
+F: configs/qemu-riscv32_smode_defconfig
F: configs/qemu-riscv64_defconfig
+F: configs/qemu-riscv64_smode_defconfig
diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
index 2730a288fb1..d6167aaef15 100644
--- a/board/emulation/qemu-riscv/qemu-riscv.c
+++ b/board/emulation/qemu-riscv/qemu-riscv.c
@@ -9,8 +9,6 @@
#include <virtio_types.h>
#include <virtio.h>
-#define MROM_FDT_ADDR 0x1020
-
int board_init(void)
{
/*
@@ -22,11 +20,70 @@ int board_init(void)
return 0;
}
-void *board_fdt_blob_setup(void)
+int board_late_init(void)
{
- /*
- * QEMU loads a generated DTB for us immediately
- * after the reset vectors in the MROM
- */
- return (void *)MROM_FDT_ADDR;
+ ulong kernel_start;
+ ofnode chosen_node;
+ int ret;
+
+ chosen_node = ofnode_path("/chosen");
+ if (!ofnode_valid(chosen_node)) {
+ debug("No chosen node found, can't get kernel start address\n");
+ return 0;
+ }
+
+#ifdef CONFIG_ARCH_RV64I
+ ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
+ (u64 *)&kernel_start);
+#else
+ ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
+ (u32 *)&kernel_start);
+#endif
+ if (ret) {
+ debug("Can't find kernel start address in device tree\n");
+ return 0;
+ }
+
+ env_set_hex("kernel_start", kernel_start);
+
+ return 0;
+}
+
+/*
+ * QEMU specifies the location of Linux (supplied with the -kernel argument)
+ * in the device tree using the riscv,kernel-start and riscv,kernel-end
+ * properties. We currently rely on the SBI implementation of BBL to run
+ * Linux and therefore embed Linux as payload in BBL. This causes an issue,
+ * because BBL detects the kernel properties in the device tree and ignores
+ * the Linux payload as a result. To work around this issue, we clear the
+ * kernel properties before booting Linux.
+ *
+ * This workaround can be removed, once we do not require BBL for its SBI
+ * implementation anymore.
+ */
+int ft_board_setup(void *blob, bd_t *bd)
+{
+ int chosen_offset, ret;
+
+ chosen_offset = fdt_path_offset(blob, "/chosen");
+ if (chosen_offset < 0)
+ return 0;
+
+#ifdef CONFIG_ARCH_RV64I
+ ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-start", 0);
+#else
+ ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-start", 0);
+#endif
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_ARCH_RV64I
+ ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-end", 0);
+#else
+ ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-end", 0);
+#endif
+ if (ret)
+ return ret;
+
+ return 0;
}