]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
board: Introduce xenguest_arm64 board
authorAndrii Anisov <andrii_anisov@epam.com>
Thu, 6 Aug 2020 09:42:47 +0000 (12:42 +0300)
committerTom Rini <trini@konsulko.com>
Fri, 14 Aug 2020 19:18:27 +0000 (15:18 -0400)
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 <andrii_anisov@epam.com>
Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Signed-off-by: Anastasiia Lukianenko <anastasiia_lukianenko@epam.com>
13 files changed:
arch/arm/Kconfig
arch/arm/cpu/armv8/Makefile
arch/arm/cpu/armv8/xen/Makefile [new file with mode: 0644]
arch/arm/cpu/armv8/xen/hypercall.S [new file with mode: 0644]
arch/arm/cpu/armv8/xen/lowlevel_init.S [new file with mode: 0644]
arch/arm/include/asm/xen.h [new file with mode: 0644]
arch/arm/include/asm/xen/hypercall.h [new file with mode: 0644]
board/xen/xenguest_arm64/Kconfig [new file with mode: 0644]
board/xen/xenguest_arm64/MAINTAINERS [new file with mode: 0644]
board/xen/xenguest_arm64/Makefile [new file with mode: 0644]
board/xen/xenguest_arm64/xenguest_arm64.c [new file with mode: 0644]
configs/xenguest_arm64_defconfig [new file with mode: 0644]
include/configs/xenguest_arm64.h [new file with mode: 0644]

index 6b8a32c38d951772780cba71faf83a07973ce573..bee626f05c5a32c52a37b379433da471fee71b1d 100644 (file)
@@ -1749,6 +1749,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
@@ -1955,6 +1961,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"
 
index 7e33a183d54b84f85f23a55037a178d36b464c20..93d26f9856891eb4809a14e11c77f275b202af8d 100644 (file)
@@ -40,3 +40,4 @@ obj-$(CONFIG_TARGET_HIKEY) += hisilicon/
 obj-$(CONFIG_ARMV8_PSCI) += psci.o
 obj-$(CONFIG_ARCH_SUNXI) += lowlevel_init.o
 obj-$(CONFIG_TARGET_BCMNS3) += bcmns3/
+obj-$(CONFIG_XEN) += xen/
diff --git a/arch/arm/cpu/armv8/xen/Makefile b/arch/arm/cpu/armv8/xen/Makefile
new file mode 100644 (file)
index 0000000..e3b4ae2
--- /dev/null
@@ -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 (file)
index 0000000..731256b
--- /dev/null
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * hypercall.S
+ *
+ * Xen hypercall wrappers
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, 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 <xen/interface/xen.h>
+
+#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 (file)
index 0000000..760e32e
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ *
+ * (C) 2017 NXP
+ * (C) 2020 EPAM Systems Inc.
+ */
+
+#include <config.h>
+
+.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 (file)
index 0000000..8e2ee3d
--- /dev/null
@@ -0,0 +1,7 @@
+/* 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 (file)
index 0000000..a4fd077
--- /dev/null
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * hypercall.h
+ *
+ * Linux-specific hypervisor handling.
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ */
+
+#ifndef _ASM_ARM_XEN_HYPERCALL_H
+#define _ASM_ARM_XEN_HYPERCALL_H
+
+#include <xen/interface/xen.h>
+
+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 (file)
index 0000000..cc131ed
--- /dev/null
@@ -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/MAINTAINERS b/board/xen/xenguest_arm64/MAINTAINERS
new file mode 100644 (file)
index 0000000..787e9e0
--- /dev/null
@@ -0,0 +1,7 @@
+XEN GUEST FOR ARM64
+M:     Andrii Anisov <andrii_anisov@epam.com>
+S:     Maintained
+F:     board/xen/xenguest_arm64/
+F:     doc/board/xen/
+F:     include/configs/xenguest_arm64.h
+F:     configs/xenguest_arm64_defconfig
diff --git a/board/xen/xenguest_arm64/Makefile b/board/xen/xenguest_arm64/Makefile
new file mode 100644 (file)
index 0000000..1cf87a7
--- /dev/null
@@ -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 (file)
index 0000000..1d1e229
--- /dev/null
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) 2013
+ * David Feng <fenghua@phytium.com.cn>
+ * Sharma Bhupesh <bhupesh.sharma@freescale.com>
+ *
+ * (C) 2020 EPAM Systems Inc
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+
+#include <asm/io.h>
+#include <asm/armv8/mmu.h>
+#include <asm/xen.h>
+#include <asm/xen/hypercall.h>
+
+#include <linux/compiler.h>
+
+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, struct bd_info *bd)
+{
+       return 0;
+}
+
+int ft_board_setup(void *blob, struct bd_info *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 (file)
index 0000000..f730799
--- /dev/null
@@ -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=y
+# 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 (file)
index 0000000..d8958cf
--- /dev/null
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ *
+ * (C) Copyright 2020 EPAM Systemc Inc.
+ */
+#ifndef __XENGUEST_ARM64_H
+#define __XENGUEST_ARM64_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#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 */