mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 13:43:28 +00:00
board: xen: introduce virtio-blk support
Added new xenguest_arm64_virtio_defconfig which enables support for virtio-blk using various types of transport like virtio-pci, vrtio-mmio. Currently supported: up to 2 PCI host bridges and 10 MMIO devices. Note: DT parsing code was partly taken from pci-uclass.c Limitation: All memory regions should be below 4GB address space. Signed-off-by: Andrii Chepurnyi <andrii_chepurnyi@epam.com>
This commit is contained in:
parent
357f4fb0bd
commit
0501c997a0
5 changed files with 181 additions and 3 deletions
|
@ -6,3 +6,4 @@ F: board/xen/xenguest_arm64/
|
||||||
F: doc/board/xen/
|
F: doc/board/xen/
|
||||||
F: include/configs/xenguest_arm64.h
|
F: include/configs/xenguest_arm64.h
|
||||||
F: configs/xenguest_arm64_defconfig
|
F: configs/xenguest_arm64_defconfig
|
||||||
|
F: configs/xenguest_arm64_virtio_defconfig
|
||||||
|
|
|
@ -8,12 +8,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <log.h>
|
||||||
#include <cpu_func.h>
|
#include <cpu_func.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <xen.h>
|
#include <xen.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
|
#include <virtio_types.h>
|
||||||
|
#include <virtio.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/armv8/mmu.h>
|
#include <asm/armv8/mmu.h>
|
||||||
|
@ -49,7 +52,14 @@ void *board_fdt_blob_setup(int *err)
|
||||||
return (void *)rom_pointer[0];
|
return (void *)rom_pointer[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_MEM_MAP_REGIONS 5
|
/*
|
||||||
|
* MAX_MEM_MAP_REGIONS should respect to:
|
||||||
|
* 3 Xen related regions
|
||||||
|
* 6 regions for 2 PCI Host bridges
|
||||||
|
* 10 regions for MMIO devices
|
||||||
|
* 2 memory regions
|
||||||
|
*/
|
||||||
|
#define MAX_MEM_MAP_REGIONS 22
|
||||||
static struct mm_region xen_mem_map[MAX_MEM_MAP_REGIONS];
|
static struct mm_region xen_mem_map[MAX_MEM_MAP_REGIONS];
|
||||||
struct mm_region *mem_map = xen_mem_map;
|
struct mm_region *mem_map = xen_mem_map;
|
||||||
|
|
||||||
|
@ -63,6 +73,93 @@ static int get_next_memory_node(const void *blob, int mem)
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_VIRTIO_BLK
|
||||||
|
#ifdef CONFIG_VIRTIO_PCI
|
||||||
|
static void add_pci_mem_map(const void *blob, int *cnt)
|
||||||
|
{
|
||||||
|
struct fdt_resource reg_res;
|
||||||
|
int node = -1, len = 0, cells_per_record = 0, max_regions = 0;
|
||||||
|
int pci_addr_cells = 0, addr_cells = 0, size_cells = 0;
|
||||||
|
|
||||||
|
while ((node = fdt_node_offset_by_prop_value(blob, node, "compatible",
|
||||||
|
"pci-host-ecam-generic",
|
||||||
|
sizeof("pci-host-ecam-generic"))) >= 0) {
|
||||||
|
if ((*cnt) >= MAX_MEM_MAP_REGIONS ||
|
||||||
|
fdt_get_resource(blob, node, "reg", 0, ®_res) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xen_mem_map[*cnt].virt = reg_res.start;
|
||||||
|
xen_mem_map[*cnt].phys = reg_res.start;
|
||||||
|
xen_mem_map[*cnt].size = fdt_resource_size(®_res);
|
||||||
|
xen_mem_map[*cnt].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||||
|
PTE_BLOCK_INNER_SHARE);
|
||||||
|
(*cnt)++;
|
||||||
|
|
||||||
|
const u32 *prop = fdt_getprop(blob, node, "ranges", &len);
|
||||||
|
|
||||||
|
if (!prop)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pci_addr_cells = fdt_address_cells(blob, node);
|
||||||
|
addr_cells = fdt_address_cells(blob, 0);
|
||||||
|
size_cells = fdt_size_cells(blob, node);
|
||||||
|
|
||||||
|
/* PCI addresses are always 3-cells */
|
||||||
|
len /= sizeof(u32);
|
||||||
|
cells_per_record = pci_addr_cells + addr_cells + size_cells;
|
||||||
|
max_regions = len / cells_per_record + CONFIG_NR_DRAM_BANKS;
|
||||||
|
|
||||||
|
for (int i = 0; i < max_regions; i++, len -= cells_per_record) {
|
||||||
|
u64 pci_addr, addr, size;
|
||||||
|
int space_code;
|
||||||
|
u32 flags;
|
||||||
|
|
||||||
|
if (((*cnt) >= MAX_MEM_MAP_REGIONS) || len < cells_per_record)
|
||||||
|
return;
|
||||||
|
|
||||||
|
flags = fdt32_to_cpu(prop[0]);
|
||||||
|
space_code = (flags >> 24) & 3;
|
||||||
|
pci_addr = fdtdec_get_number(prop + 1, 2);
|
||||||
|
prop += pci_addr_cells;
|
||||||
|
addr = fdtdec_get_number(prop, addr_cells);
|
||||||
|
prop += addr_cells;
|
||||||
|
size = fdtdec_get_number(prop, size_cells);
|
||||||
|
prop += size_cells;
|
||||||
|
|
||||||
|
xen_mem_map[*cnt].virt = addr;
|
||||||
|
xen_mem_map[*cnt].phys = addr;
|
||||||
|
xen_mem_map[*cnt].size = size;
|
||||||
|
xen_mem_map[*cnt].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||||
|
PTE_BLOCK_INNER_SHARE);
|
||||||
|
(*cnt)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_VIRTIO_MMIO
|
||||||
|
static void add_mmio_mem_map(const void *blob, int *cnt)
|
||||||
|
{
|
||||||
|
int node = -1;
|
||||||
|
struct fdt_resource reg_res;
|
||||||
|
|
||||||
|
if ((*cnt) >= MAX_MEM_MAP_REGIONS)
|
||||||
|
return;
|
||||||
|
while ((node = fdt_node_offset_by_prop_value(blob, node, "compatible", "virtio,mmio",
|
||||||
|
sizeof("virtio,mmio"))) >= 0) {
|
||||||
|
if (fdt_get_resource(blob, node, "reg", 0, ®_res) < 0)
|
||||||
|
return;
|
||||||
|
xen_mem_map[*cnt].virt = reg_res.start;
|
||||||
|
xen_mem_map[*cnt].phys = reg_res.start;
|
||||||
|
xen_mem_map[*cnt].size = roundup(fdt_resource_size(®_res), PAGE_SIZE);
|
||||||
|
xen_mem_map[*cnt].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||||
|
PTE_BLOCK_INNER_SHARE);
|
||||||
|
(*cnt)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static int setup_mem_map(void)
|
static int setup_mem_map(void)
|
||||||
{
|
{
|
||||||
int i = 0, ret, mem, reg = 0;
|
int i = 0, ret, mem, reg = 0;
|
||||||
|
@ -72,6 +169,7 @@ static int setup_mem_map(void)
|
||||||
phys_addr_t gnttab_base;
|
phys_addr_t gnttab_base;
|
||||||
phys_size_t gnttab_sz;
|
phys_size_t gnttab_sz;
|
||||||
|
|
||||||
|
memset(xen_mem_map, 0, sizeof(xen_mem_map));
|
||||||
/*
|
/*
|
||||||
* Add "magic" region which is used by Xen to provide some essentials
|
* Add "magic" region which is used by Xen to provide some essentials
|
||||||
* for the guest: we need console and xenstore.
|
* for the guest: we need console and xenstore.
|
||||||
|
@ -143,6 +241,14 @@ static int setup_mem_map(void)
|
||||||
xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||||
PTE_BLOCK_INNER_SHARE);
|
PTE_BLOCK_INNER_SHARE);
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_VIRTIO_BLK
|
||||||
|
#ifdef CONFIG_VIRTIO_PCI
|
||||||
|
add_pci_mem_map(blob, &i);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_VIRTIO_MMIO
|
||||||
|
add_mmio_mem_map(blob, &i);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
63
configs/xenguest_arm64_virtio_defconfig
Normal file
63
configs/xenguest_arm64_virtio_defconfig
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
CONFIG_ARM=y
|
||||||
|
CONFIG_POSITION_INDEPENDENT=y
|
||||||
|
CONFIG_TARGET_XENGUEST_ARM64=y
|
||||||
|
CONFIG_TEXT_BASE=0x40080000
|
||||||
|
CONFIG_SYS_MALLOC_LEN=0x2000000
|
||||||
|
CONFIG_SYS_MALLOC_F_LEN=0x400
|
||||||
|
CONFIG_NR_DRAM_BANKS=1
|
||||||
|
CONFIG_DEFAULT_DEVICE_TREE="xenguest-arm64"
|
||||||
|
CONFIG_SYS_PROMPT="xenguest# "
|
||||||
|
CONFIG_IDENT_STRING=" xenguest"
|
||||||
|
CONFIG_SYS_LOAD_ADDR=0x40000000
|
||||||
|
CONFIG_OF_SYSTEM_SETUP=y
|
||||||
|
CONFIG_BOOTDELAY=10
|
||||||
|
CONFIG_SYS_MAXARGS=64
|
||||||
|
CONFIG_SYS_PBSIZE=1051
|
||||||
|
#CONFIG_SYS_CBSIZE=512
|
||||||
|
# CONFIG_CMD_BDI is not set
|
||||||
|
# CONFIG_CMD_BOOTD is not set
|
||||||
|
CONFIG_SYS_BOOTM_LEN=0x800000
|
||||||
|
# CONFIG_CMD_ELF is not set
|
||||||
|
# CONFIG_CMD_GO is not set
|
||||||
|
# CONFIG_CMD_IMI is not set
|
||||||
|
# CONFIG_CMD_XIMG is not set
|
||||||
|
# CONFIG_CMD_EXPORTENV is not set
|
||||||
|
# CONFIG_CMD_IMPORTENV is not set
|
||||||
|
# CONFIG_CMD_EDITENV is not set
|
||||||
|
# CONFIG_CMD_SAVEENV is not set
|
||||||
|
# CONFIG_CMD_ENV_EXISTS is not set
|
||||||
|
# CONFIG_CMD_CRC32 is not set
|
||||||
|
# CONFIG_CMD_LZMADEC is not set
|
||||||
|
# CONFIG_CMD_UNZIP is not set
|
||||||
|
# CONFIG_CMD_LOADB is not set
|
||||||
|
# CONFIG_CMD_LOADS is not set
|
||||||
|
# CONFIG_CMD_ECHO is not set
|
||||||
|
# CONFIG_CMD_ITEST is not set
|
||||||
|
# CONFIG_CMD_SOURCE is not set
|
||||||
|
# CONFIG_CMD_SETEXPR is not set
|
||||||
|
# CONFIG_CMD_SLEEP is not set
|
||||||
|
CONFIG_CMD_EXT4=y
|
||||||
|
CONFIG_CMD_FAT=y
|
||||||
|
# CONFIG_NET is not set
|
||||||
|
# CONFIG_MMC is not set
|
||||||
|
# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
|
||||||
|
CONFIG_DM_SERIAL=y
|
||||||
|
CONFIG_PHYS_64BIT=y
|
||||||
|
CONFIG_PCI=y
|
||||||
|
CONFIG_CMD_PCI=y
|
||||||
|
CONFIG_PCIE_ECAM_GENERIC=y
|
||||||
|
CONFIG_PCI_REGION_MULTI_ENTRY=y
|
||||||
|
CONFIG_PCI_INIT_R=y
|
||||||
|
CONFIG_PCI_PNP=y
|
||||||
|
CONFIG_DM_PCI_COMPAT=y
|
||||||
|
CONFIG_SYS_PCI_64BIT=y
|
||||||
|
CONFIG_VIRTIO=y
|
||||||
|
CONFIG_VIRTIO_MMIO=y
|
||||||
|
CONFIG_VIRTIO_PCI=y
|
||||||
|
CONFIG_VIRTIO_BLK=y
|
||||||
|
CONFIG_CMD_VIRTIO=y
|
||||||
|
# CONFIG_VIRTIO_PCI_LEGACY is not set
|
||||||
|
# CONFIG_VIRTIO_NET is not set
|
||||||
|
# CONFIG_VIRTIO_RNG is not set
|
||||||
|
CONFIG_CMD_GPT=y
|
||||||
|
CONFIG_PARTITION_TYPE_GUID=y
|
|
@ -23,6 +23,7 @@ previously done by NXP [4]:
|
||||||
- PV block device frontend driver with XenStore based device enumeration and
|
- PV block device frontend driver with XenStore based device enumeration and
|
||||||
UCLASS_PVBLOCK class;
|
UCLASS_PVBLOCK class;
|
||||||
- PV serial console device frontend driver;
|
- PV serial console device frontend driver;
|
||||||
|
- Virtio block device support;
|
||||||
- Xen hypervisor support with minimal set of the essential headers adapted from
|
- Xen hypervisor support with minimal set of the essential headers adapted from
|
||||||
the Linux kernel;
|
the Linux kernel;
|
||||||
- Xen grant table support;
|
- Xen grant table support;
|
||||||
|
@ -34,6 +35,7 @@ previously done by NXP [4]:
|
||||||
define any start addresses at compile time which is up to Xen to choose at
|
define any start addresses at compile time which is up to Xen to choose at
|
||||||
run-time;
|
run-time;
|
||||||
- new defconfig introduced: xenguest_arm64_defconfig.
|
- new defconfig introduced: xenguest_arm64_defconfig.
|
||||||
|
- new defconfig introduced: xenguest_arm64_virtio_defconfig.
|
||||||
|
|
||||||
|
|
||||||
Board limitations
|
Board limitations
|
||||||
|
|
|
@ -14,9 +14,15 @@
|
||||||
#undef CFG_SYS_SDRAM_BASE
|
#undef CFG_SYS_SDRAM_BASE
|
||||||
|
|
||||||
#undef CFG_EXTRA_ENV_SETTINGS
|
#undef CFG_EXTRA_ENV_SETTINGS
|
||||||
|
|
||||||
|
#ifdef CONFIG_VIRTIO_BLK
|
||||||
#define CFG_EXTRA_ENV_SETTINGS \
|
#define CFG_EXTRA_ENV_SETTINGS \
|
||||||
"loadimage=ext4load pvblock 0 0x90000000 /boot/Image;\0" \
|
"virtioboot=virtio scan; ext4load virtio 0 0x90000000 /boot/Image;" \
|
||||||
"pvblockboot=run loadimage;" \
|
"booti 0x90000000 - ${fdtcontroladdr};\0"
|
||||||
|
#else
|
||||||
|
#define CFG_EXTRA_ENV_SETTINGS \
|
||||||
|
"pvblockboot=ext4load pvblock 0 0x90000000 /boot/Image;" \
|
||||||
"booti 0x90000000 - 0x88000000;\0"
|
"booti 0x90000000 - 0x88000000;\0"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __XENGUEST_ARM64_H */
|
#endif /* __XENGUEST_ARM64_H */
|
||||||
|
|
Loading…
Reference in a new issue