samples: drivers: ethernet: Add Jailhouse IVSHMEM Ethernet sample

Add an IVSHMEM Ethernet sample to communicate between Zephyr
and Linux root cell within the Jailhouse hypervisor.

The supported configuration runs the Jailhouse hypervisor
within QEMU Cortex-A53.

Signed-off-by: Grant Ramsay <gramsay@enphaseenergy.com>
This commit is contained in:
Grant Ramsay 2023-04-30 14:40:29 +12:00 committed by Christopher Friedt
parent 82dd4efc66
commit 83928aaab7
7 changed files with 307 additions and 0 deletions

View file

@ -0,0 +1,9 @@
# Copyright (c) 2023 Enphase Energy
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(eth_ivshmem)
target_sources(app PRIVATE src/main.c)

View file

@ -0,0 +1,164 @@
.. _eth_ivshmem_sample:
Inter-VM Shared Memory (ivshmem) Ethernet Sample Application
############################################################
Overview
********
This application demonstrates how to use IVSHMEM Ethernet to communicate with
another "cell" in the Jailhouse hypervisor. Currently only the qemu_cortex_a53
board is supported.
Building Jailhouse Linux for QEMU
*********************************
Clone Jailhouse yocto project. At the time of writing, the "next" branch has
some fixes that are not yet on the "master" branch:
.. code-block:: console
git clone https://github.com/siemens/jailhouse-images.git
cd jailhouse-images
git checkout origin/next
Open the menu, select "QEMU ARM64 virtual target" then "Save & Build"
(this will take a while):
.. code-block:: console
./kas-container menu
Edit "start-qemu.sh":
* change ``-cpu cortex-a57`` -> ``-cpu cortex-a53``
under the ``arm64|aarch64`` case
* Enable SSH access by appending ``,hostfwd=tcp::2222-:22`` to
``-netdev user,id=net`` in the QEMU process arguments
(2222 can be replaced with any unused port)
Start QEMU:
.. code-block:: console
./start-qemu.sh arm64
This should boot Linux and drop into a shell.
Build the Zephyr sample
***********************
.. zephyr-app-commands::
:zephyr-app: samples/drivers/ethernet/eth_ivshmem
:board: qemu_cortex_a53
:goals: build
Running the sample
******************
Copy the generated zephyr.bin to the Jailhouse Linux root cell:
.. code-block:: console
scp -P 2222 path/to/zephyr.bin root@localhost:/root
Jailhouse has a prebuilt Zephyr cell configuration that works for
this sample "qemu-arm64-zephyr-demo".
Back in Jailhouse Linux shell, create the Zephyr cell:
.. code-block:: console
jailhouse enable /etc/jailhouse/qemu-arm64.cell
jailhouse console
jailhouse cell create /etc/jailhouse/qemu-arm64-zephyr-demo.cell
You may see a quirk here where the Linux shell stops taking input...
If you get this, open a second shell via SSH:
.. code-block:: console
ssh -p 2222 root@localhost
Load and start the Zephyr cell:
.. code-block:: console
jailhouse cell load qemu-arm64-zephyr-demo zephyr.bin --address 0x70000000
jailhouse cell start qemu-arm64-zephyr-demo
Now you can run Zephyr and Linux shell commands to communicate between
the cells.
Ping Linux from Zephyr
**********************
.. code-block:: console
*** Booting Zephyr OS build v3.3.0-475-g45b9e84c6013 ***
uart:~$ net ping 192.168.19.1
PING 192.168.19.1
28 bytes from 192.168.19.1 to 192.168.19.2: icmp_seq=1 ttl=64 time=5.06 ms
28 bytes from 192.168.19.1 to 192.168.19.2: icmp_seq=2 ttl=64 time=7.99 ms
28 bytes from 192.168.19.1 to 192.168.19.2: icmp_seq=3 ttl=64 time=1.77 ms
Ping Zephyr from Linux
**********************
.. code-block:: console
root@demo:~# ping -c 3 192.168.19.2
PING 192.168.19.2 (192.168.19.2) 56(84) bytes of data.
64 bytes from 192.168.19.2: icmp_seq=1 ttl=64 time=0.646 ms
64 bytes from 192.168.19.2: icmp_seq=2 ttl=64 time=1.45 ms
64 bytes from 192.168.19.2: icmp_seq=3 ttl=64 time=1.28 ms
--- 192.168.19.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 0.646/1.124/1.450/0.345 ms
Run zperf / iPerf
*****************
:ref:`zperf` / iPerf can be used to perform network throughput measurements.
In Zephyr:
.. code-block:: console
# Start zperf TCP server
zperf tcp download 5001
In Linux:
.. code-block:: console
# Install iPerf 2.0.5
apt install wget
wget https://iperf.fr/download/ubuntu/iperf_2.0.5+dfsg1-2_arm64.deb
apt install ./iperf_2.0.5+dfsg1-2_arm64.deb
rm iperf_2.0.5+dfsg1-2_arm64.deb
# Connect iPerf TCP client
iperf -l 1K -V -c 192.168.19.2 -p 5001
Zephyr output:
.. code-block:: console
TCP server started on port 5001
New TCP session started.
TCP session ended
Duration: 10.01 s
rate: 57.72 Mbps
Linux output:
.. code-block:: console
------------------------------------------------------------
Client connecting to 192.168.19.2, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.19.1 port 58430 connected with 192.168.19.2 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 72.2 MBytes 60.6 Mbits/sec

View file

@ -0,0 +1,20 @@
# Jailhouse requires ARMv8-A non-secure mode
CONFIG_ARMV8_A_NS=y
# QEMU PCI requires at least 256M of virtual space
CONFIG_KERNEL_VM_SIZE=0x80000000
# QEMU PCI requires physical addresses with more than 32 bits
CONFIG_ARM64_VA_BITS_40=y
CONFIG_ARM64_PA_BITS_40=y
# PCIe config
CONFIG_PCIE_CONTROLLER=y
CONFIG_PCIE_ECAM=y
# Required for PCIe INTx interrupts
CONFIG_DYNAMIC_INTERRUPTS=y
# Disable unwanted default configs
CONFIG_NET_DRIVERS=n
CONFIG_NET_SLIP_TAP=n

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2023 Enphase Energy
*
* SPDX-License-Identifier: Apache-2.0
*/
/ {
soc {
/delete-node/ memory@40000000;
sram0: memory@70000000 {
compatible = "mmio-sram";
reg = <0x0 0x70000000 0x0 DT_SIZE_M(128)>;
};
/delete-node/ pcie@4010000000;
pcie: pcie@8e00000 {
compatible = "pci-host-ecam-generic";
device_type = "pci";
reg = <0x00 0x08e00000 0x00 0x100000>;
#size-cells = <0x02>;
#address-cells = <0x03>;
ranges = <0x02000000 0x00 0x10000000 0x0 0x10000000 0x00 0x10000>;
#interrupt-cells = <0x01>;
interrupt-map-mask = <0x00 0x00 0x00 0x07>;
interrupt-map = <
0x00 0x00 0x00 1 &gic 0 0 GIC_SPI 108 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY
0x00 0x00 0x00 2 &gic 0 0 GIC_SPI 109 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY
0x00 0x00 0x00 3 &gic 0 0 GIC_SPI 110 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY
0x00 0x00 0x00 4 &gic 0 0 GIC_SPI 111 IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
bus-range = <0x00 0x00>;
};
};
eth_ivshmem0: eth_ivshmem {
compatible = "siemens,ivshmem-eth";
ivshmem-v2 = <&ivshmem0>;
zephyr,random-mac-address;
status = "okay";
};
};
&pcie {
ivshmem0: ivshmem@0 {
compatible = "qemu,ivshmem";
ivshmem-v2;
vendor-id = <0x110A>; /* Siemens */
device-id = <0x4106>; /* IVSHMEM */
class-rev = <0xFF000100>; /* PCI_CLASS_OTHERS | IVSHMEM_PROTO_NET */
class-rev-mask = <0xFFFFFF00>; /* PCI_CLASS_MASK | IVSHMEM_PROTO_MASK */
interrupt-parent = <&pcie>;
interrupts = <1 2 3 4>;
reg = <0x00 0x00 0x00 0x00 0x01>;
status = "okay";
};
};

View file

@ -0,0 +1,37 @@
CONFIG_HEAP_MEM_POOL_SIZE=16777216
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_LOG_BACKEND_UART=y
CONFIG_ETHERNET_LOG_LEVEL_INF=y
CONFIG_IVSHMEM_LOG_LEVEL_INF=y
CONFIG_NETWORKING=y
CONFIG_NET_L2_ETHERNET=y
CONFIG_ETH_IVSHMEM=y
CONFIG_NET_STATISTICS=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_TCP=y
CONFIG_NET_IPV4=y
CONFIG_NET_TCP_ISN_RFC6528=n
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.19.2"
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
CONFIG_ENTROPY_GENERATOR=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_SHELL=y
CONFIG_NET_SHELL=y
CONFIG_NET_ZPERF=y
CONFIG_NET_TCP_WORKQ_STACK_SIZE=4096
CONFIG_NET_RX_STACK_SIZE=4096
CONFIG_SHELL_STACK_SIZE=4096
# Increase net buffer size/count for increased performace
CONFIG_NET_TCP_MAX_RECV_WINDOW_SIZE=5120
CONFIG_NET_PKT_TX_COUNT=6
CONFIG_NET_BUF_RX_COUNT=64

View file

@ -0,0 +1,7 @@
sample:
name: Inter-VM Shared Memory (ivshmem) Ethernet
tests:
sample.drivers.ethernet.eth_ivshmem:
platform_allow: qemu_cortex_a53
tags: drivers ethernet
build_only: true

View file

@ -0,0 +1,13 @@
/*
* Copyright (c) 2023 Enphase Energy
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
void main(void)
{
/* This sample uses the shell */
k_sleep(K_FOREVER);
}