diff --git a/arch/kvx/Kconfig b/arch/kvx/Kconfig index 5463bb4..3327021 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 f9ff773..8162171 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/cpu/barebox.lds.S b/arch/kvx/cpu/barebox.lds.S index bf92564..77ebaf0 100644 --- a/arch/kvx/cpu/barebox.lds.S +++ b/arch/kvx/cpu/barebox.lds.S @@ -10,8 +10,6 @@ OUTPUT_FORMAT("elf64-kvx") OUTPUT_ARCH("kvx:kv3-1:64") -#define DTB_DEFAULT_SIZE (24 * 1024) - SECTIONS { . = CONFIG_ARCH_TEXT_BASE; @@ -54,13 +52,6 @@ RO_DATA_SECTION } - .dtb ALIGN(16): - { - __dtb_start = .; - . += DTB_DEFAULT_SIZE; - __dtb_end = .; - } - _etext = .; /* End of text and rodata section */ .data ALIGN(4): { diff --git a/arch/kvx/include/asm/bootm.h b/arch/kvx/include/asm/bootm.h new file mode 100644 index 0000000..7ad7e2e --- /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/cache.h b/arch/kvx/include/asm/cache.h new file mode 100644 index 0000000..3be1767 --- /dev/null +++ b/arch/kvx/include/asm/cache.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2019 Kalray Inc. + */ + +#ifndef __KVX_CACHE_H +#define __KVX_CACHE_H + +#include + +static inline void sync_caches_for_execution(void) +{ + __builtin_kvx_fence(); + __builtin_kvx_iinval(); + __builtin_kvx_barrier(); +} + +#endif /* __KVX_CACHE_H */ diff --git a/arch/kvx/include/asm/elf.h b/arch/kvx/include/asm/elf.h index 7cc09d7..2975ad1 100644 --- a/arch/kvx/include/asm/elf.h +++ b/arch/kvx/include/asm/elf.h @@ -11,6 +11,9 @@ */ #include +#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 352e703..6e56462 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 0000000..198eef7 --- /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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +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); diff --git a/common/Kconfig b/common/Kconfig index f260291..b59dc39 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -39,7 +39,6 @@ config ELF bool "ELF Support" if COMPILE_TEST - depends on MIPS || COMPILE_TEST config FILETYPE bool diff --git a/common/bootm.c b/common/bootm.c index 4110d8d..bea73fa 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -510,7 +510,7 @@ uimage_print_contents(data->os); - if (data->os->header.ih_arch != IH_ARCH) { + if (IH_ARCH == IH_ARCH_INVALID || data->os->header.ih_arch != IH_ARCH) { printf("Unsupported Architecture 0x%x\n", data->os->header.ih_arch); return -EINVAL; diff --git a/include/image.h b/include/image.h index 88b628b..0a7832f 100644 --- a/include/image.h +++ b/include/image.h @@ -101,6 +101,8 @@ #define IH_ARCH IH_ARCH_AVR32 #elif defined(CONFIG_LINUX) #define IH_ARCH IH_ARCH_LINUX +#else +#define IH_ARCH IH_ARCH_INVALID #endif /*