drivers: virt_ivshmem: Allow multiple instances of ivShMem devices.

- Supporting multiple instances of ivShMem virtual devices.
- Introduces DT based configuration for ivShMem devices.
- Add DTS overlay file to test new multiple ivshmem instance capability.
- Enable BDF unspecified device initialization.
  (limited to one instance. An improved version of pcie_bdf_lookup()
  will come soon that fixes this limitation)
- Make PCIE DTS file macros available for a proper ivshmem device
  properties parsing.

Sample for dts file:
pcie0 {
	label = "PCIE_0";
	#address-cells = <1>;
	#size-cells = <1>;
	compatible = "intel,pcie";
	ranges;
    ivshmem0: ivshmem@800 {
	    compatible = "qemu,ivshmem";
	    reg = <PCIE_BDF_NONE PCIE_ID(0x1af4,0x1110)>;
	    label = "IVSHMEM";
	    status = "okay";
    };
};

Signed-off-by: Michael Schmidt <michael1.schmidt@intel.com>
This commit is contained in:
Michael Schmidt 2021-09-21 14:28:26 +02:00 committed by Christopher Friedt
parent ad4e9934de
commit 2a09d5e53f
4 changed files with 62 additions and 10 deletions

View File

@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT qemu_ivshmem
#define LOG_LEVEL CONFIG_IVSHMEM_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(ivshmem);
@ -223,25 +225,42 @@ static const struct ivshmem_driver_api ivshmem_api = {
static int ivshmem_init(const struct device *dev)
{
struct ivshmem *data = dev->data;
static bool bdf_lookup_done;
data->bdf = pcie_bdf_lookup(PCIE_ID(IVSHMEM_VENDOR_ID,
IVSHMEM_DEVICE_ID));
if (data->bdf == PCIE_BDF_NONE) {
LOG_WRN("ivshmem device not found");
if ((data->bdf == PCIE_BDF_NONE) && bdf_lookup_done) {
LOG_ERR("One instance of ivshmem with pcie_bdf_lookup() already initialized.\n"
"Using more than one with PCIE_BDF_NONE parameter might conflict\n"
"with already initialized instances.");
return -ENOTSUP;
}
if ((data->bdf == PCIE_BDF_NONE) && !bdf_lookup_done) {
if (data->dev_ven_id) {
data->bdf = pcie_bdf_lookup(data->dev_ven_id);
} else {
data->bdf = pcie_bdf_lookup(PCIE_ID(IVSHMEM_VENDOR_ID, IVSHMEM_DEVICE_ID));
}
if (data->bdf == PCIE_BDF_NONE) {
LOG_WRN("ivshmem device not found");
return -ENOTSUP;
}
}
LOG_DBG("ivshmem found at bdf 0x%x", data->bdf);
bdf_lookup_done = true;
if (!ivshmem_configure(dev)) {
return -EIO;
}
return 0;
}
static struct ivshmem ivshmem_data;
#define IVSHMEM_DEVICE_INIT(n) \
static struct ivshmem ivshmem_data_##n = { \
.bdf = DT_INST_REG_ADDR_BY_IDX(n, 0), \
.dev_ven_id = DT_INST_REG_SIZE_BY_IDX(n, 0) \
}; \
DEVICE_DT_INST_DEFINE(n, &ivshmem_init, NULL, \
&ivshmem_data_##n, NULL, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
&ivshmem_api);
DEVICE_DEFINE(ivshmem, CONFIG_IVSHMEM_DEV_NAME,
ivshmem_init, NULL, &ivshmem_data, NULL,
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &ivshmem_api);
DT_INST_FOREACH_STATUS_OKAY(IVSHMEM_DEVICE_INIT)

View File

@ -25,6 +25,7 @@ struct ivshmem_param {
struct ivshmem {
DEVICE_MMIO_RAM;
pcie_bdf_t bdf;
uint32_t dev_ven_id;
uintptr_t shmem;
size_t size;
#ifdef CONFIG_IVSHMEM_DOORBELL

View File

@ -0,0 +1,8 @@
# Copyright (c) 2021 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
description: ivShMem device properties
compatible: "qemu,ivshmem"
include: base.yaml

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2021 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <dt-bindings/pcie/pcie.h>
/ {
pcie0 {
label = "PCIE_0";
#address-cells = <1>;
#size-cells = <1>;
compatible = "intel,pcie";
ranges;
ivshmem0: ivshmem@800 {
compatible = "qemu,ivshmem";
reg = <PCIE_BDF_NONE PCIE_ID(0x1af4,0x1110)>;
label = "IVSHMEM";
status = "okay";
};
};
};