From patchwork Wed Jul 1 16:29:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nastya Vicodin X-Patchwork-Id: 240621 List-Id: U-Boot discussion From: vicooodin at gmail.com (Anastasiia Lukianenko) Date: Wed, 1 Jul 2020 19:29:45 +0300 Subject: [PATCH 03/17] board: Introduce xenguest_arm64 board In-Reply-To: <20200701162959.9814-1-vicooodin@gmail.com> References: <20200701162959.9814-1-vicooodin@gmail.com> Message-ID: <20200701162959.9814-4-vicooodin@gmail.com> From: Andrii Anisov Introduce a minimal Xen guest board running as a virtual machine under Xen Project's hypervisor [1], [2]. Part of the code is ported from Xen mini-os and also uses work initially done by different authors from NXP: please see relevant files for their copyrights. [1] https://xenbits.xen.org [2] https://wiki.xenproject.org/ Signed-off-by: Andrii Anisov Signed-off-by: Oleksandr Andrushchenko Signed-off-by: Anastasiia Lukianenko --- arch/arm/Kconfig | 7 + arch/arm/cpu/armv8/Makefile | 1 + arch/arm/cpu/armv8/xen/Makefile | 6 + arch/arm/cpu/armv8/xen/hypercall.S | 78 +++++++++++ arch/arm/cpu/armv8/xen/lowlevel_init.S | 34 +++++ arch/arm/include/asm/xen.h | 8 ++ arch/arm/include/asm/xen/hypercall.h | 45 +++++++ board/xen/xenguest_arm64/Kconfig | 12 ++ board/xen/xenguest_arm64/Makefile | 5 + board/xen/xenguest_arm64/xenguest_arm64.c | 153 ++++++++++++++++++++++ configs/xenguest_arm64_defconfig | 56 ++++++++ include/configs/xenguest_arm64.h | 45 +++++++ 12 files changed, 450 insertions(+) create mode 100644 arch/arm/cpu/armv8/xen/Makefile create mode 100644 arch/arm/cpu/armv8/xen/hypercall.S create mode 100644 arch/arm/cpu/armv8/xen/lowlevel_init.S create mode 100644 arch/arm/include/asm/xen.h create mode 100644 arch/arm/include/asm/xen/hypercall.h create mode 100644 board/xen/xenguest_arm64/Kconfig create mode 100644 board/xen/xenguest_arm64/Makefile create mode 100644 board/xen/xenguest_arm64/xenguest_arm64.c create mode 100644 configs/xenguest_arm64_defconfig create mode 100644 include/configs/xenguest_arm64.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e9ad716aaa..c469863967 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1717,6 +1717,12 @@ config TARGET_PRESIDIO_ASIC bool "Support Cortina Presidio ASIC Platform" select ARM64 +config TARGET_XENGUEST_ARM64 + bool "Xen guest ARM64" + select ARM64 + select XEN + select OF_CONTROL + select LINUX_KERNEL_IMAGE_HEADER endchoice config ARCH_SUPPORT_TFABOOT @@ -1920,6 +1926,7 @@ source "board/xilinx/Kconfig" source "board/xilinx/zynq/Kconfig" source "board/xilinx/zynqmp/Kconfig" source "board/phytium/durian/Kconfig" +source "board/xen/xenguest_arm64/Kconfig" source "arch/arm/Kconfig.debug" diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index 2e48df0eb9..dd6c354d19 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -39,3 +39,4 @@ obj-$(CONFIG_S32V234) += s32v234/ obj-$(CONFIG_TARGET_HIKEY) += hisilicon/ obj-$(CONFIG_ARMV8_PSCI) += psci.o obj-$(CONFIG_ARCH_SUNXI) += lowlevel_init.o +obj-$(CONFIG_XEN) += xen/ diff --git a/arch/arm/cpu/armv8/xen/Makefile b/arch/arm/cpu/armv8/xen/Makefile new file mode 100644 index 0000000000..e3b4ae2bd4 --- /dev/null +++ b/arch/arm/cpu/armv8/xen/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) 2018 NXP +# (C) 2020 EPAM Systems Inc. + +obj-y += lowlevel_init.o hypercall.o diff --git a/arch/arm/cpu/armv8/xen/hypercall.S b/arch/arm/cpu/armv8/xen/hypercall.S new file mode 100644 index 0000000000..9596e336b5 --- /dev/null +++ b/arch/arm/cpu/armv8/xen/hypercall.S @@ -0,0 +1,78 @@ +/****************************************************************************** + * hypercall.S + * + * Xen hypercall wrappers + * + * Stefano Stabellini , Citrix, 2012 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* + * The Xen hypercall calling convention is very similar to the procedure + * call standard for the ARM 64-bit architecture: the first parameter is + * passed in x0, the second in x1, the third in x2, the fourth in x3 and + * the fifth in x4. + * + * The hypercall number is passed in x16. + * + * The return value is in x0. + * + * The hvc ISS is required to be 0xEA1, that is the Xen specific ARM + * hypercall tag. + * + * Parameter structs passed to hypercalls are laid out according to + * the ARM 64-bit EABI standard. + */ + +#include + +#define XEN_HYPERCALL_TAG 0xEA1 + +#define HYPERCALL_SIMPLE(hypercall) \ +.globl HYPERVISOR_##hypercall; \ +.align 4,0x90; \ +HYPERVISOR_##hypercall: \ + mov x16, #__HYPERVISOR_##hypercall; \ + hvc XEN_HYPERCALL_TAG; \ + ret; \ + +#define HYPERCALL0 HYPERCALL_SIMPLE +#define HYPERCALL1 HYPERCALL_SIMPLE +#define HYPERCALL2 HYPERCALL_SIMPLE +#define HYPERCALL3 HYPERCALL_SIMPLE +#define HYPERCALL4 HYPERCALL_SIMPLE +#define HYPERCALL5 HYPERCALL_SIMPLE + + .text + +HYPERCALL2(xen_version); +HYPERCALL3(console_io); +HYPERCALL3(grant_table_op); +HYPERCALL2(sched_op); +HYPERCALL2(event_channel_op); +HYPERCALL2(hvm_op); +HYPERCALL2(memory_op); + diff --git a/arch/arm/cpu/armv8/xen/lowlevel_init.S b/arch/arm/cpu/armv8/xen/lowlevel_init.S new file mode 100644 index 0000000000..25ed438e20 --- /dev/null +++ b/arch/arm/cpu/armv8/xen/lowlevel_init.S @@ -0,0 +1,34 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + * + * (C) 2017 NXP + * (C) 2020 EPAM Systems Inc. + */ + +#include + +.align 8 +.global rom_pointer +rom_pointer: + .space 32 + +/* + * Routine: save_boot_params (called after reset from start.S) + */ + +.global save_boot_params +save_boot_params: + /* The firmware provided ATAG/FDT address can be found in r2/x0 */ + adr x1, rom_pointer + stp x0, x2, [x1], #16 + stp x3, x4, [x1], #16 + + /* Returns */ + b save_boot_params_ret + +.global restore_boot_params +restore_boot_params: + adr x1, rom_pointer + ldp x0, x2, [x1], #16 + ldp x3, x4, [x1], #16 + ret diff --git a/arch/arm/include/asm/xen.h b/arch/arm/include/asm/xen.h new file mode 100644 index 0000000000..fb7f03e19c --- /dev/null +++ b/arch/arm/include/asm/xen.h @@ -0,0 +1,8 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + * + * (C) 2020 EPAM Systems Inc. + */ + +extern unsigned long rom_pointer[]; + diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h new file mode 100644 index 0000000000..26644ce886 --- /dev/null +++ b/arch/arm/include/asm/xen/hypercall.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * hypercall.h + * + * Linux-specific hypervisor handling. + * + * Stefano Stabellini , Citrix, 2012 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _ASM_ARM_XEN_HYPERCALL_H +#define _ASM_ARM_XEN_HYPERCALL_H + +#include + +int HYPERVISOR_xen_version(int cmd, void *arg); +int HYPERVISOR_console_io(int cmd, int count, char *str); +int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count); +int HYPERVISOR_sched_op(int cmd, void *arg); +int HYPERVISOR_event_channel_op(int cmd, void *arg); +unsigned long HYPERVISOR_hvm_op(int op, void *arg); +int HYPERVISOR_memory_op(unsigned int cmd, void *arg); +#endif /* _ASM_ARM_XEN_HYPERCALL_H */ diff --git a/board/xen/xenguest_arm64/Kconfig b/board/xen/xenguest_arm64/Kconfig new file mode 100644 index 0000000000..cc131ed5b9 --- /dev/null +++ b/board/xen/xenguest_arm64/Kconfig @@ -0,0 +1,12 @@ +if TARGET_XENGUEST_ARM64 + +config SYS_BOARD + default "xenguest_arm64" + +config SYS_VENDOR + default "xen" + +config SYS_CONFIG_NAME + default "xenguest_arm64" + +endif diff --git a/board/xen/xenguest_arm64/Makefile b/board/xen/xenguest_arm64/Makefile new file mode 100644 index 0000000000..1cf87a728f --- /dev/null +++ b/board/xen/xenguest_arm64/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2020 EPAM Systems Inc. + +obj-y := xenguest_arm64.o diff --git a/board/xen/xenguest_arm64/xenguest_arm64.c b/board/xen/xenguest_arm64/xenguest_arm64.c new file mode 100644 index 0000000000..9e099f388f --- /dev/null +++ b/board/xen/xenguest_arm64/xenguest_arm64.c @@ -0,0 +1,153 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + * + * (C) 2013 + * David Feng + * Sharma Bhupesh + * + * (C) 2020 EPAM Systems Inc + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + return 0; +} + +/* + * Use fdt provided by Xen: according to + * https://www.kernel.org/doc/Documentation/arm64/booting.txt + * x0 is the physical address of the device tree blob (dtb) in system RAM. + * This is stored in rom_pointer during low level init. + */ +void *board_fdt_blob_setup(void) +{ + if (fdt_magic(rom_pointer[0]) != FDT_MAGIC) + return NULL; + return (void *)rom_pointer[0]; +} + +#define MAX_MEM_MAP_REGIONS 5 +static struct mm_region xen_mem_map[MAX_MEM_MAP_REGIONS]; +struct mm_region *mem_map = xen_mem_map; + +static int get_next_memory_node(const void *blob, int mem) +{ + do { + mem = fdt_node_offset_by_prop_value(blob, mem, + "device_type", "memory", 7); + } while (!fdtdec_get_is_enabled(blob, mem)); + + return mem; +} + +static int setup_mem_map(void) +{ + int i, ret, mem, reg = 0; + struct fdt_resource res; + const void *blob = gd->fdt_blob; + + mem = get_next_memory_node(blob, -1); + if (mem < 0) { + printf("%s: Missing /memory node\n", __func__); + return -EINVAL; + } + + for (i = 0; i < MAX_MEM_MAP_REGIONS; i++) { + ret = fdt_get_resource(blob, mem, "reg", reg++, &res); + if (ret == -FDT_ERR_NOTFOUND) { + reg = 0; + mem = get_next_memory_node(blob, mem); + if (mem == -FDT_ERR_NOTFOUND) + break; + + ret = fdt_get_resource(blob, mem, "reg", reg++, &res); + if (ret == -FDT_ERR_NOTFOUND) + break; + } + if (ret != 0) { + printf("No reg property for memory node\n"); + return -EINVAL; + } + + xen_mem_map[i].virt = (phys_addr_t)res.start; + xen_mem_map[i].phys = (phys_addr_t)res.start; + xen_mem_map[i].size = (phys_size_t)(res.end - res.start + 1); + xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE); + } + return 0; +} + +void enable_caches(void) +{ + /* Re-setup the memory map as BSS gets cleared after relocation. */ + setup_mem_map(); + icache_enable(); + dcache_enable(); +} + +/* Read memory settings from the Xen provided device tree. */ +int dram_init(void) +{ + int ret; + + ret = fdtdec_setup_mem_size_base(); + if (ret < 0) + return ret; + /* Setup memory map, so MMU page table size can be estimated. */ + return setup_mem_map(); +} + +int dram_init_banksize(void) +{ + return fdtdec_setup_memory_banksize(); +} + +/* + * Board specific reset that is system reset. + */ +void reset_cpu(ulong addr) +{ +} + +int ft_system_setup(void *blob, bd_t *bd) +{ + return 0; +} + +int ft_board_setup(void *blob, bd_t *bd) +{ + return 0; +} + +int board_early_init_f(void) +{ + return 0; +} + +int print_cpuinfo(void) +{ + printf("Xen virtual CPU\n"); + return 0; +} + +__weak struct serial_device *default_serial_console(void) +{ + return NULL; +} + diff --git a/configs/xenguest_arm64_defconfig b/configs/xenguest_arm64_defconfig new file mode 100644 index 0000000000..2a8caf8647 --- /dev/null +++ b/configs/xenguest_arm64_defconfig @@ -0,0 +1,56 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_SYS_TEXT_BASE=0x40080000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_IDENT_STRING=" xenguest" +CONFIG_TARGET_XENGUEST_ARM64=y +CONFIG_BOOTDELAY=10 + +CONFIG_SYS_PROMPT="xenguest# " + +CONFIG_CMD_NET=n +CONFIG_CMD_BDI=n +CONFIG_CMD_BOOTD=n +CONFIG_CMD_BOOTEFI=n +CONFIG_CMD_BOOTEFI_HELLO_COMPILE=n +CONFIG_CMD_ELF=n +CONFIG_CMD_GO=n +CONFIG_CMD_RUN=n +CONFIG_CMD_IMI=n +CONFIG_CMD_IMLS=n +CONFIG_CMD_XIMG=n +CONFIG_CMD_EXPORTENV=n +CONFIG_CMD_IMPORTENV=n +CONFIG_CMD_EDITENV=n +CONFIG_CMD_ENV_EXISTS=n +CONFIG_CMD_MEMORY=y +CONFIG_CMD_CRC32=n +CONFIG_CMD_DM=n +CONFIG_CMD_LOADB=n +CONFIG_CMD_LOADS=n +CONFIG_CMD_FLASH=n +CONFIG_CMD_GPT=n +CONFIG_CMD_FPGA=n +CONFIG_CMD_ECHO=n +CONFIG_CMD_ITEST=n +CONFIG_CMD_SOURCE=n +CONFIG_CMD_SETEXPR=n +CONFIG_CMD_MISC=n +CONFIG_CMD_UNZIP=n +CONFIG_CMD_LZMADEC=n +CONFIG_CMD_SAVEENV=n +CONFIG_CMD_UMS=n + +#CONFIG_USB=n +# CONFIG_ISO_PARTITION is not set + +#CONFIG_EFI_PARTITION=y +# CONFIG_EFI_LOADER is not set + +# CONFIG_DM is not set +# CONFIG_MMC is not set +# CONFIG_DM_SERIAL is not set +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set + +CONFIG_OF_BOARD=y +CONFIG_OF_LIBFDT=y diff --git a/include/configs/xenguest_arm64.h b/include/configs/xenguest_arm64.h new file mode 100644 index 0000000000..467dabf1e5 --- /dev/null +++ b/include/configs/xenguest_arm64.h @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + * + * (C) Copyright 2020 EPAM Systemc Inc. + */ +#ifndef __XENGUEST_ARM64_H +#define __XENGUEST_ARM64_H + +#ifndef __ASSEMBLY__ +#include +#endif + +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_EXTRA_ENV_SETTINGS + +#undef CONFIG_NR_DRAM_BANKS +#undef CONFIG_SYS_SDRAM_BASE + +#define CONFIG_NR_DRAM_BANKS 1 + +/* + * This can be any arbitrary address as we are using PIE, but + * please note, that CONFIG_SYS_TEXT_BASE must match the below. + */ +#define CONFIG_SYS_LOAD_ADDR 0x40000000 +#define CONFIG_LNX_KRNL_IMG_TEXT_OFFSET_BASE CONFIG_SYS_LOAD_ADDR + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (32 * 1024 * 1024) + +/* Monitor Command Prompt */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_CBSIZE 1024 +#define CONFIG_SYS_MAXARGS 64 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) + +#define CONFIG_OF_SYSTEM_SETUP + +#define CONFIG_CMDLINE_TAG 1 +#define CONFIG_INITRD_TAG 1 + +#endif /* __XENGUEST_ARM64_H */