arm: aarch64: add Xen virtual machine support
This commit adds minimal support for running zephyr as Xen guest. It does not use xen PV console, which is somewhat hard to implement, as it depends on xenbus infrastructure. Instead SBSA-compatible PL011 uart is used. Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
This commit is contained in:
parent
4fb1ee771a
commit
b07065d3f3
7
boards/arm/xenvm/Kconfig.board
Normal file
7
boards/arm/xenvm/Kconfig.board
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Copyright (c) 2020 EPAM Systems
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_XENVM
|
||||
bool "Xen Virtual Machine"
|
||||
depends on SOC_XENVM
|
||||
select ARM64
|
12
boards/arm/xenvm/Kconfig.defconfig
Normal file
12
boards/arm/xenvm/Kconfig.defconfig
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Copyright (c) 2020 EPAM Systems
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if BOARD_XENVM
|
||||
|
||||
config BUILD_OUTPUT_BIN
|
||||
default y
|
||||
|
||||
config BOARD
|
||||
default "xenvm"
|
||||
|
||||
endif # BOARD_XENVM
|
179
boards/arm/xenvm/doc/index.rst
Normal file
179
boards/arm/xenvm/doc/index.rst
Normal file
|
@ -0,0 +1,179 @@
|
|||
.. xenvm:
|
||||
|
||||
ARMv8 Xen Virtual Machine Example
|
||||
#################################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This board allows to run Zephyr as Xen guest on any ARMv8 board that supports
|
||||
ARM Virtualization Extensions. This is example configuration, as almost any VM
|
||||
configuration is unique in many aspects.
|
||||
|
||||
.. figure:: xen_project_logo.png
|
||||
:align: center
|
||||
:alt: XenVM
|
||||
|
||||
Xen virtual Guest (Credit: Xen Project)
|
||||
|
||||
It provides minimal set of devices:
|
||||
|
||||
* ARM Generic timer
|
||||
* GICv2
|
||||
* SBSA (subset of PL011) UART controller
|
||||
|
||||
|
||||
Hardware
|
||||
********
|
||||
Supported Features
|
||||
==================
|
||||
|
||||
The following hardware features are supported:
|
||||
|
||||
+--------------+-------------+----------------------+
|
||||
| Interface | Controller | Driver/Component |
|
||||
+==============+=============+======================+
|
||||
| GIC | virtualized | interrupt controller |
|
||||
+--------------+-------------+----------------------+
|
||||
| SBSA UART | emulated | serial port |
|
||||
+--------------+-------------+----------------------+
|
||||
| ARM TIMER | virtualized | system clock |
|
||||
+--------------+-------------+----------------------+
|
||||
|
||||
The kernel currently does not support other hardware features on this platform.
|
||||
|
||||
Devices
|
||||
========
|
||||
System Clock
|
||||
------------
|
||||
|
||||
This board configuration uses a system clock frequency of 8.32 MHz. This is the
|
||||
default value, which should be corrected for user's actual hardware.
|
||||
|
||||
You can determine clock frequency of your ARM Generic Timer by inspecting Xen
|
||||
boot log:
|
||||
|
||||
::
|
||||
|
||||
(XEN) [ 0.147541] Generic Timer IRQ: phys=30 hyp=26 virt=27 Freq: 8320 KHz
|
||||
|
||||
Serial Port
|
||||
-----------
|
||||
|
||||
This board configuration uses a single serial communication channel using SBSA
|
||||
UART. This is a minimal UART implementation provided by Xen. Xen PV Console is
|
||||
not supported at this moment.
|
||||
|
||||
Interrupt Controller
|
||||
--------------------
|
||||
|
||||
By default, GICv2 is selected. If your hardware is based on GICv3, you can
|
||||
configure Zephyr to use it, by amending device tree and Kconfig
|
||||
option in "xenvm" SoC as well as guest configuration file.
|
||||
|
||||
CPU Core type
|
||||
-------------
|
||||
|
||||
Default core in this configuration is Cortex A72. Depending on yours actual
|
||||
hardware you might want to change this option in the same way as Interrupt
|
||||
Controller configuration.
|
||||
|
||||
Known Problems or Limitations
|
||||
==============================
|
||||
|
||||
Xen configures guests in runtime by providing device tree that describes guest
|
||||
environment. On other hand, Zephyr uses static configuration that should be know
|
||||
at build time. So there are chances, that Zephyr image created with default
|
||||
configuration would not boot on your hardware. In this case you need to update
|
||||
configuration by altering device tree and Kconfig options. This will be covered
|
||||
in detail in next section.
|
||||
|
||||
No Xen-specific features are supported at the moment. This includes:
|
||||
|
||||
* Xen Enlighten memory page
|
||||
* XenBus
|
||||
* Xen event channels
|
||||
* Xen grant tables
|
||||
* Xen PV drivers (including PV console)
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
Use this configuration to run basic Zephyr applications and kernel tests as Xen
|
||||
guest, for example, with the :ref:`synchronization_sample`:
|
||||
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ west build -b xenvm samples/synchronization
|
||||
|
||||
This will build an image with the synchronization sample app. Next, you need to
|
||||
create guest configuration file :code:`zephyr.conf`. There is example:
|
||||
|
||||
.. code-block::
|
||||
|
||||
kernel="zephyr.bin"
|
||||
name="zephyr"
|
||||
vcpus=1
|
||||
memory=16
|
||||
gic_version="v2"
|
||||
on_crash="preserve"
|
||||
vuart="sbsa_uart"
|
||||
|
||||
You need to upload both :code:`zephyr.bin` and :code:`zephyr.conf` to your Dom0
|
||||
and then you can run Zephyr by issuing
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ xl create zephyr.conf
|
||||
|
||||
Next you need to attach to SBSA virtual console:
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ xl console -t vuart zephyr
|
||||
|
||||
You will see Zephyr output:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
*** Booting Zephyr OS build zephyr-v2.4.0-1137-g5803ee1e8183 ***
|
||||
thread_a: Hello World from cpu 0 on xenvm!
|
||||
thread_b: Hello World from cpu 0 on xenvm!
|
||||
thread_a: Hello World from cpu 0 on xenvm!
|
||||
thread_b: Hello World from cpu 0 on xenvm!
|
||||
thread_a: Hello World from cpu 0 on xenvm!
|
||||
|
||||
Exit xen virtual console by pressing :kbd:`CTRL+[`
|
||||
|
||||
Updating configuration
|
||||
**********************
|
||||
|
||||
As was said earlier, Xen describes hardware using device tree and expects that
|
||||
guest will parse device tree in runtime. On other hand, Zephyr supports only
|
||||
static, build time configuration. While provided configuration should work on
|
||||
almost any ARMv8 host running in aarch64 mode, there is no guarantee, that Xen
|
||||
will not change some values (like RAM base address) in the future.
|
||||
|
||||
Also, frequency of system timer is board specific and should be updated when running
|
||||
Zephyr xenvm image on new hardware.
|
||||
|
||||
One can make Xen to dump generated DTB by using :code:`LIBXL_DEBUG_DUMP_DTB`
|
||||
environment variable, like so:
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ LIBXL_DEBUG_DUMP_DTB=domu-libxl.dtb xl create zephyr.conf
|
||||
|
||||
Then, generated "domu-libxl.dtb" file can be de-compiled using "dtc" tool.
|
||||
|
||||
Use information from de-compiled DTB file to update all related entries in
|
||||
provided "xenvm.dts" file. If memory layout is also changed, you may need to
|
||||
update :code:`CONFIG_SRAM_BASE_ADDRESS` as well.
|
||||
|
||||
References
|
||||
**********
|
||||
|
||||
`Xen ARM with Virtualization Extensions <https://wiki.xenproject.org/wiki/Xen_ARM_with_Virtualization_Extensions>`_
|
||||
|
||||
`xl.conf (guest configuration file) manual <https://xenbits.xen.org/docs/unstable/man/xl.cfg.5.html>`_
|
BIN
boards/arm/xenvm/doc/xen_project_logo.png
Normal file
BIN
boards/arm/xenvm/doc/xen_project_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
89
boards/arm/xenvm/xenvm.dts
Normal file
89
boards/arm/xenvm/xenvm.dts
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2020 EPAM Systems
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* This file was created by running
|
||||
*
|
||||
* # LIBXL_DEBUG_DUMP_DTB=domu-libxl.dtb xl create zephyr.conf
|
||||
*
|
||||
* decompilling resulting domu-libxl.dtb and then manually aligning it
|
||||
* with zephyr requirements.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <mem.h>
|
||||
#include <arm/armv8-a.dtsi>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/ {
|
||||
model = "XENVM-4.15";
|
||||
compatible = "xen,xenvm-4.15", "xen,xenvm";
|
||||
interrupt-parent = <&gic>;
|
||||
#address-cells = <0x02>;
|
||||
#size-cells = <0x02>;
|
||||
|
||||
chosen {
|
||||
zephyr,console = &sbsa;
|
||||
zephyr,shell-uart = &sbsa;
|
||||
zephyr,sram = &ram;
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x00>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,armv8";
|
||||
enable-method = "psci";
|
||||
reg = <0x00>;
|
||||
};
|
||||
};
|
||||
|
||||
psci {
|
||||
compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
|
||||
method = "hvc";
|
||||
label = "PSCI";
|
||||
};
|
||||
|
||||
ram: memory@40000000 {
|
||||
device_type = "mmio-sram";
|
||||
reg = <0x00 0x40000000 0x00 DT_SIZE_M(16)>;
|
||||
};
|
||||
|
||||
gic: interrupt-controller@3001000 {
|
||||
compatible = "arm,gic";
|
||||
label = "GIC";
|
||||
#interrupt-cells = <0x04>;
|
||||
#address-cells = <0x00>;
|
||||
interrupt-controller;
|
||||
reg = <0x00 0x3001000 0x00 0x1000 0x00 0x3002000 0x00 0x2000>;
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,arm-timer";
|
||||
interrupts = <GIC_PPI 0x0d IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY
|
||||
GIC_PPI 0x0e IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY
|
||||
GIC_PPI 0x0b IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>;
|
||||
interrupt-parent = <&gic>;
|
||||
label = "arch_timer";
|
||||
};
|
||||
|
||||
hypervisor: hypervisor@38000000 {
|
||||
compatible = "xen,xen-4.15", "xen,xen";
|
||||
reg = <0x00 0x38000000 0x00 0x1000000>;
|
||||
interrupts = <GIC_PPI 0x0f IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
|
||||
interrupt-parent = <&gic>;
|
||||
};
|
||||
|
||||
sbsa: sbsa-pl011@22000000 {
|
||||
compatible = "arm,sbsa-uart";
|
||||
reg = <0x00 0x22000000 0x00 0x1000>;
|
||||
interrupts = <GIC_SPI 0x00 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>;
|
||||
interrupt-parent = <&gic>;
|
||||
current-speed = <0x1c200>;
|
||||
label = "UART";
|
||||
};
|
||||
};
|
20
boards/arm/xenvm/xenvm_defconfig
Normal file
20
boards/arm/xenvm/xenvm_defconfig
Normal file
|
@ -0,0 +1,20 @@
|
|||
CONFIG_SOC_XENVM=y
|
||||
CONFIG_BOARD_XENVM=y
|
||||
|
||||
# Enable UART driver
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
CONFIG_XIP=n
|
||||
CONFIG_FLASH_BASE_ADDRESS=0x0
|
||||
CONFIG_FLASH_SIZE=0
|
||||
CONFIG_AARCH64_IMAGE_HEADER=y
|
||||
CONFIG_MAX_XLAT_TABLES=10
|
||||
|
||||
# Enable console
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_UART_CONSOLE=y
|
||||
|
||||
# Enable serial port
|
||||
CONFIG_UART_PL011=y
|
||||
CONFIG_UART_PL011_SBSA=y
|
||||
CONFIG_UART_INTERRUPT_DRIVEN=n
|
3
soc/arm/xenvm/CMakeLists.txt
Normal file
3
soc/arm/xenvm/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c)
|
17
soc/arm/xenvm/Kconfig.defconfig
Normal file
17
soc/arm/xenvm/Kconfig.defconfig
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Copyright 2020 EPAM Systems
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if SOC_XENVM
|
||||
|
||||
config SOC
|
||||
default "xenvm"
|
||||
|
||||
config NUM_IRQS
|
||||
int
|
||||
default 500
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
int
|
||||
default 8320000
|
||||
|
||||
endif
|
10
soc/arm/xenvm/Kconfig.soc
Normal file
10
soc/arm/xenvm/Kconfig.soc
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright 2020 EPAM Systems
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SOC_XENVM
|
||||
bool "Xen virtual machine on aarch64"
|
||||
select ARM
|
||||
select ARM64
|
||||
select ARM_ARCH_TIMER
|
||||
select GIC_V2
|
||||
select CPU_CORTEX_A72
|
8
soc/arm/xenvm/linker.ld
Normal file
8
soc/arm/xenvm/linker.ld
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright 2020 EPAM Systems
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <autoconf.h>
|
||||
#include <arch/arm/aarch64/scripts/linker.ld>
|
31
soc/arm/xenvm/mmu_regions.c
Normal file
31
soc/arm/xenvm/mmu_regions.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2020 EPAM Systems
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <devicetree.h>
|
||||
#include <sys/util.h>
|
||||
#include <arch/arm/aarch64/arm_mmu.h>
|
||||
|
||||
static const struct arm_mmu_region mmu_regions[] = {
|
||||
|
||||
MMU_REGION_FLAT_ENTRY("GIC",
|
||||
DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 0),
|
||||
DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 0),
|
||||
MT_DEVICE_nGnRnE | MT_P_RW_U_RW | MT_NS),
|
||||
|
||||
MMU_REGION_FLAT_ENTRY("GIC",
|
||||
DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1),
|
||||
DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1),
|
||||
MT_DEVICE_nGnRnE | MT_P_RW_U_RW | MT_NS),
|
||||
|
||||
MMU_REGION_FLAT_ENTRY("UART",
|
||||
DT_REG_ADDR(DT_INST(0, arm_sbsa_uart)),
|
||||
DT_REG_SIZE(DT_INST(0, arm_sbsa_uart)),
|
||||
MT_DEVICE_nGnRnE | MT_P_RW_U_RW | MT_NS),
|
||||
};
|
||||
|
||||
const struct arm_mmu_config mmu_config = {
|
||||
.num_regions = ARRAY_SIZE(mmu_regions),
|
||||
.mmu_regions = mmu_regions,
|
||||
};
|
19
soc/arm/xenvm/soc.h
Normal file
19
soc/arm/xenvm/soc.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2020 EPAM Systems
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SOC_H_
|
||||
#define _SOC_H_
|
||||
|
||||
#include <sys/util.h>
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <device.h>
|
||||
|
||||
#endif /* !_ASMLANGUAGE */
|
||||
|
||||
#endif /* _SOC_H_ */
|
Loading…
Reference in a new issue