summaryrefslogtreecommitdiffstats
path: root/arch/kvx
diff options
context:
space:
mode:
authorClement Leger <clement.leger@kalray.eu>2020-06-30 22:44:02 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-07-01 07:23:14 +0200
commitc10551150b2e4e7a746b24f43cd9d7a9b440d14a (patch)
treed677dd5097f885ca913ce34cfcf79a8a443c594b /arch/kvx
parentb6bc2e84031e2d8859277982c18f8fdc75a81035 (diff)
downloadbarebox-c10551150b2e4e7a746b24f43cd9d7a9b440d14a.tar.gz
barebox-c10551150b2e4e7a746b24f43cd9d7a9b440d14a.tar.xz
kvx: add support for elf loading using bootm
In order to boot elfs files, add bootm command support for kvx. This support can boot elf files using bootm elf support. initrd and device-tree handling is also included and loads them after the elf file load address. Signed-off-by: Clement Leger <cleger@kalray.eu> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/kvx')
-rw-r--r--arch/kvx/Kconfig5
-rw-r--r--arch/kvx/configs/generic_defconfig3
-rw-r--r--arch/kvx/include/asm/bootm.h11
-rw-r--r--arch/kvx/include/asm/elf.h3
-rw-r--r--arch/kvx/lib/Makefile2
-rw-r--r--arch/kvx/lib/bootm.c133
6 files changed, 155 insertions, 2 deletions
diff --git a/arch/kvx/Kconfig b/arch/kvx/Kconfig
index 5463bb4f14..3327021e1a 100644
--- a/arch/kvx/Kconfig
+++ b/arch/kvx/Kconfig
@@ -1,9 +1,14 @@
config KVX
bool
select 64BIT
+ select BOOTM
+ select BOOTM_ELF
+ select BOOTM_OFTREE
+ select BOOTM_INITRD
select CLKDEV_LOOKUP
select COMMON_CLK
select COMMON_CLK_OF_PROVIDER
+ select ELF
select FLEXIBLE_BOOTARGS
select GENERIC_FIND_NEXT_BIT
select LIBFDT
diff --git a/arch/kvx/configs/generic_defconfig b/arch/kvx/configs/generic_defconfig
index f9ff773a0e..8162171741 100644
--- a/arch/kvx/configs/generic_defconfig
+++ b/arch/kvx/configs/generic_defconfig
@@ -1,7 +1,8 @@
CONFIG_AUTO_COMPLETE=y
CONFIG_BAUDRATE=115200
-# CONFIG_BOOTM is not set
CONFIG_CLOCKSOURCE_KVX=y
+CONFIG_CMD_BOOT=y
+CONFIG_CMD_BOOTM=y
CONFIG_CMD_CMP=y
CONFIG_CMD_OF_DUMP=y
CONFIG_CMD_POWEROFF=y
diff --git a/arch/kvx/include/asm/bootm.h b/arch/kvx/include/asm/bootm.h
new file mode 100644
index 0000000000..7ad7e2e878
--- /dev/null
+++ b/arch/kvx/include/asm/bootm.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2019 Kalray Inc.
+ */
+
+#ifndef _ASM_KVX_BOOTM_H
+#define _ASM_KVX_BOOTM_H
+
+#define LINUX_BOOT_PARAM_MAGIC 0x31564752414E494CULL
+
+#endif /* _ASM_KVX_BOOTM_H */
diff --git a/arch/kvx/include/asm/elf.h b/arch/kvx/include/asm/elf.h
index 7cc09d7bac..2975ad1b90 100644
--- a/arch/kvx/include/asm/elf.h
+++ b/arch/kvx/include/asm/elf.h
@@ -11,6 +11,9 @@
*/
#include <linux/types.h>
+#define EM_KVX 256
+
+#define ELF_ARCH EM_KVX
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
diff --git a/arch/kvx/lib/Makefile b/arch/kvx/lib/Makefile
index 352e7034a6..6e56462daa 100644
--- a/arch/kvx/lib/Makefile
+++ b/arch/kvx/lib/Makefile
@@ -3,4 +3,4 @@
# Copyright (C) 2019 Kalray Inc.
#
-obj-y += cpuinfo.o board.o dtb.o poweroff.o
+obj-y += cpuinfo.o board.o dtb.o poweroff.o bootm.o
diff --git a/arch/kvx/lib/bootm.c b/arch/kvx/lib/bootm.c
new file mode 100644
index 0000000000..198eef7980
--- /dev/null
+++ b/arch/kvx/lib/bootm.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2019 Kalray Inc.
+ */
+
+#include <elf.h>
+#include <boot.h>
+#include <init.h>
+#include <bootm.h>
+#include <binfmt.h>
+#include <common.h>
+#include <libfile.h>
+#include <linux/kernel.h>
+
+#include <asm/cache.h>
+#include <asm/bootm.h>
+
+typedef void __noreturn (*boot_func_entry)(unsigned long, void *);
+
+static int do_boot_entry(struct image_data *data, boot_func_entry entry,
+ void *fdt_load_addr)
+{
+ printf("starting elf (entry at %p)\n", entry);
+
+ if (data->dryrun)
+ return 0;
+
+ shutdown_barebox();
+
+ /* Synchronize I-cache with D-cache */
+ sync_caches_for_execution();
+
+ /**
+ * Parameters passing
+ * r0: boot magic
+ * r1: device tree pointer
+ */
+ entry(LINUX_BOOT_PARAM_MAGIC, (void *) fdt_load_addr);
+
+ /* should never return ! */
+ panic("Returned from boot program !\n");
+
+ return -EINVAL;
+}
+
+static int do_boot_elf(struct image_data *data, struct elf_image *elf)
+{
+ int ret;
+ void *fdt;
+ boot_func_entry entry;
+ unsigned long load_addr, initrd_address;
+
+ /* load initrd after the elf */
+ load_addr = PAGE_ALIGN((unsigned long) elf->high_addr);
+ if (bootm_has_initrd(data)) {
+ if (data->initrd_address != UIMAGE_INVALID_ADDRESS)
+ initrd_address = data->initrd_address;
+ else
+ initrd_address = load_addr;
+
+ printf("Loading initrd at 0x%lx\n", initrd_address);
+ ret = bootm_load_initrd(data, initrd_address);
+ if (ret) {
+ printf("Failed to load initrd\n");
+ return ret;
+ }
+
+ if (data->initrd_address == UIMAGE_INVALID_ADDRESS) {
+ load_addr += resource_size(data->initrd_res);
+ load_addr = PAGE_ALIGN(load_addr);
+ }
+ }
+
+ fdt = bootm_get_devicetree(data);
+ if (IS_ERR(fdt)) {
+ printf("Failed to load dtb\n");
+ return PTR_ERR(fdt);
+ }
+
+ printf("Loading device tree at %lx\n", load_addr);
+ /* load device tree after the initrd if any */
+ ret = bootm_load_devicetree(data, fdt, load_addr);
+ if (ret) {
+ printf("Failed to load device tree: %d\n", ret);
+ goto err_free_fdt;
+ }
+
+ entry = (boot_func_entry) data->os_address;
+
+ ret = do_boot_entry(data, entry, fdt);
+
+err_free_fdt:
+ free(fdt);
+
+ return ret;
+}
+
+static int do_bootm_elf(struct image_data *data)
+{
+ int ret;
+
+ ret = bootm_load_os(data, data->os_address);
+ if (ret)
+ return ret;
+
+ return do_boot_elf(data, data->elf);
+}
+
+static struct image_handler elf_handler = {
+ .name = "ELF",
+ .bootm = do_bootm_elf,
+ .filetype = filetype_elf,
+};
+
+static struct binfmt_hook binfmt_elf_hook = {
+ .type = filetype_elf,
+ .exec = "bootm",
+};
+
+static int kvx_register_image_handler(void)
+{
+ register_image_handler(&elf_handler);
+
+ binfmt_register(&binfmt_elf_hook);
+
+ return 0;
+}
+
+late_initcall(kvx_register_image_handler);