From patchwork Fri Aug 14 19:16:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chenbo Xia X-Patchwork-Id: 75551 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E670CA04B0; Fri, 14 Aug 2020 12:27:10 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id BF90C1C10E; Fri, 14 Aug 2020 12:27:03 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 03AA41C0DC for ; Fri, 14 Aug 2020 12:27:01 +0200 (CEST) IronPort-SDR: wJcpB1/FhTI1dhxoh3lcUS7MHoKE6KiBixxB+KDpnBun0mx1kVSdBftz+4KDwdAZ09xUnx/0tN 1WWX/mQk3vRQ== X-IronPort-AV: E=McAfee;i="6000,8403,9712"; a="153616454" X-IronPort-AV: E=Sophos;i="5.76,312,1592895600"; d="scan'208";a="153616454" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Aug 2020 03:27:01 -0700 IronPort-SDR: 13312pMLVMfArqpfMYLhGiBLxvrPNKiraV9AI+myI/pjt7T+UsCbbM9tNC775ggIJtcneQbSvB X6bvR6Aui5tg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,312,1592895600"; d="scan'208";a="295717612" Received: from npg-dpdk-virtio-xiachenbo-nw.sh.intel.com ([10.67.119.123]) by orsmga006.jf.intel.com with ESMTP; 14 Aug 2020 03:26:59 -0700 From: Chenbo Xia To: dev@dpdk.org, thomas@monjalon.net, xuan.ding@intel.com, xiuchun.lu@intel.com, cunming.liang@intel.com, changpeng.liu@intel.com Cc: zhihong.wang@intel.com Date: Fri, 14 Aug 2020 19:16:06 +0000 Message-Id: <20200814191606.26312-3-chenbo.xia@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200814191606.26312-1-chenbo.xia@intel.com> References: <20200814191606.26312-1-chenbo.xia@intel.com> Subject: [dpdk-dev] [RFC v1 2/2] emudev: Add library for emulated device X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" To enable DPDK to be an alternative I/O device emulation library of building virtualized devices in separate processes outside QEMU, a new device class named emudev is introduced in this patch. Emudev is a device type for emulated devices. Providers, which are specific emudev drivers, could choose the transport to QEMU. An option of tranport could be vfio-over-socket (also called vfio-user), which is defined by a standard protocol in QEMU. Signed-off-by: Chenbo Xia Signed-off-by: Xiuchun Lu --- lib/librte_emudev/rte_emudev.h | 315 +++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 lib/librte_emudev/rte_emudev.h diff --git a/lib/librte_emudev/rte_emudev.h b/lib/librte_emudev/rte_emudev.h new file mode 100644 index 000000000..2ffc4dbe0 --- /dev/null +++ b/lib/librte_emudev/rte_emudev.h @@ -0,0 +1,315 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Intel Corporation + */ + +#ifndef _RTE_EMUDEV_H_ +#define _RTE_EMUDEV_H_ + +#include +#include +#include + +typedef void *rte_emudev_conf_t; +typedef void *rte_emudev_attr_t; +typedef void *rte_emudev_mem_table_t; +typedef char *emu_dev_type_t; + +struct rte_emu_dev; + +struct emu_dev_info { + emu_dev_type_t dev_type; + uint32_t max_qp_num; + uint32_t max_event_num; +}; + +struct emu_dev_q_info { + uint64_t base; + uint64_t size; + uint32_t doorbell_id; + uint32_t irq_vector; + void *priv; +}; + +struct emu_dev_irq_info { + uint32_t vector; + int fd; + void *priv; +}; + +struct emu_dev_db_info { + uint32_t id; + uint32_t flag; +#define EMU_DEV_DB_FD (0x1 << 0) +#define EMU_DEV_DB_MEM (0x1 << 1) + union { + int fd; + struct { + uint64_t base; + uint64_t size; + } mem; + } data; + void *priv; +}; + +/** + * Back-end driver and emualated device provider should have + * the same definiton of events and events message. + */ +struct emu_dev_event_channel { + int fd; + struct rte_ring *queue; +}; + +struct emu_dev_attr_info { + const char *attr_name; + rte_emudev_attr_t attr; +}; + +struct emu_dev_ops { + int (*dev_start)(struct rte_emu_dev *dev); + void (*dev_stop)(struct rte_emu_dev *dev); + int (*dev_configure)(struct rte_emu_dev *dev, + rte_emudev_conf_t dev_conf); + int (*dev_close)(struct rte_emu_dev *dev); + struct emu_dev_info *(*get_dev_info)(struct rte_emu_dev *dev); + int (*subscribe_event)(struct rte_emu_dev *dev, + const struct emu_dev_event_channel *ev_chnl); + int (*unsubscribe_event)(struct rte_emu_dev *dev, + const struct emu_dev_event_channel *ev_chnl); + rte_emudev_mem_table_t (*get_mem_table)(struct rte_emu_dev *dev); + struct emu_dev_q_info *(*get_queue_info)(struct rte_emu_dev *dev, + uint32_t queue); + struct emu_dev_irq_info *(*get_irq_info)(struct rte_emu_dev *dev, + uint32_t vector); + struct emu_dev_db_info *(*get_db_info)(struct rte_emu_dev *dev, + uint32_t doorbell); + rte_emudev_attr_t (*get_attr)(struct rte_emu_dev *dev, + const char *attr_name); + int (*set_attr)(struct rte_emu_dev *dev, const char *attr_name, + rte_emudev_attr_t attr); + int (*region_map)(struct rte_emu_dev *dev, const char *region_name, + uint16_t region_size, uint64_t *base_addr); +}; + +struct rte_emu_dev { + struct rte_device *device; + const struct emu_dev_ops *dev_ops; + const struct emu_dev_event_channel *ev_chnl; + struct emu_dev_info *dev_info; + uint16_t num_attr; + struct emu_dev_attr_info **attr; + void *priv_data; +} __rte_cache_aligned; + +/** + * Note that 'rte_emu_dev_allocate','rte_emu_dev_release' and + * 'rte_emu_dev_allocated' should be called by emulated device + * provider. + * / + +/** + * Allocate a new emudev for an emulation device and retures the pointer + * to the emudev. + * + * @param name + * Name of the emudev + * @return + * Pointer to rte_emu_dev on success, NULL on failure + */ +struct rte_emu_dev * +rte_emu_dev_allocate(const char *name); + +/** + * Release the emudev. + * + * @param dev + * The emulated device + * @return + * 0 on success, -1 on failure + */ +int +rte_emu_dev_release(struct rte_emu_dev *dev); + +/** + * Find an emudev using name. + * + * @param name + * Name of the emudev + * @return + * Pointer to rte_emu_dev on success, NULL on failure + */ +struct rte_emu_dev * +rte_emu_dev_allocated(const char *name); + +/** + * Start an emulation device. + * + * @param dev_id + * Device ID of emudev + * @return + * 0 on success, -1 on failure + */ +int rte_emu_dev_start(uint16_t dev_id); + +/** + * Stop an emulation device. + * + * @param dev_id + * Device ID of emudev + */ +void rte_emu_dev_stop(uint16_t dev_id); + +/** + * Configure an emulation device. + * + * @param dev_id + * Device ID of emudev + * @param dev_conf + * Device configure info + * @return + * 0 on success, -1 on failure + */ +int rte_emu_dev_configure(uint16_t dev_id, rte_emudev_conf_t dev_conf); + +/** + * Close an emulation device. + * + * @param dev_id + * Device ID of emudev + */ +void rte_emu_dev_close(uint16_t dev_id); + +/* Note that below APIs should only be called by back-end driver */ + +/** + * Back-end driver subscribes events of the emulated device. + * + * @param dev_id + * Device ID of emudev + * @param ev_chnl + * Event channel that events should be passed to + * @return + * 0 on success, -1 on failure + */ +int rte_emu_subscribe_event(uint16_t dev_id, + const struct emu_dev_event_channel *ev_chnl); + +/** + * Back-end driver unsubscribes events of the emulated device. + * + * @param dev_id + * Device ID of emudev + * @param set + * Event channel that events should be passed to + * @return + * 0 on success, -1 on failure + */ +int rte_emu_unsubscribe_event(uint16_t dev_id, + const struct emu_dev_event_channel *ev_chnl); + +/** + * Back-end driver gets the device info of the emulated device. + * + * @param dev_id + * Device ID of emudev + * @return + * Pointer to dev info on success, NULL on failure + */ +struct emu_dev_info *rte_emu_get_dev_info(uint16_t dev_id); + +/** + * Get the memory table content and operations of the emulated device. + * + * @param dev_id + * Device ID of emudev + * @return + * Pointer to memory table on success, NULL on failure + */ +rte_emudev_mem_table_t rte_emu_get_mem_table(uint16_t dev_id); + +/** + * Get queue info of the emudev. + * + * @param dev_id + * Device ID of emudev + * @param queue + * Queue ID of emudev + * @return + * Pointer to queue info on success, NULL on failure + */ +struct emu_dev_q_info *rte_emu_get_queue_info(uint16_t dev_id, + uint32_t queue); + +/** + * Get irq info of the emudev. + * + * @param dev_id + * Device ID of emudev + * @param vector + * Interrupt vector + * @return + * Pointer to irq info on success, NULL on failure + */ +struct emu_dev_irq_info *rte_emu_get_irq_info(uint16_t dev_id, + uint32_t vector); + +/** + * Get doorbell info of the emudev. + * + * @param dev_id + * Device ID of emudev + * @param doorbell + * Doorbell ID + * @return + * Pointer to doorbell info on success, NULL on failure + */ +struct emu_dev_db_info *rte_emu_get_db_info(uint16_t dev_id, + uint32_t doorbell); + +/** + * Set attribute of the emudev. + * + * @param dev_id + * Device ID of emudev + * @param attr_name + * Opaque object representing an attribute in implementation. + * @param attr + * Pointer to attribute + * @return + * 0 on success, -1 on failure + */ +int rte_emu_set_attr(uint16_t dev_id, const char *attr_name, + rte_emudev_attr_t attr); + +/** + * Get attribute of the emudev. + * + * @param dev_id + * Device ID of emudev + * @param attr_name + * Opaque object representing an attribute in implementation. + * @return + * Corresponding attr on success, NULL on failure + */ +rte_emudev_attr_t rte_emu_get_attr(uint16_t dev_id, const char *attr_name); + +/** + * Back-end driver maps a region to the emulated device. + * Region name identifies the meaning of the region and the emulated + * device and the back-end driver should have the same definition of + * region name and its meaning. + * + * @param dev_id + * Device ID of emudev + * @param region_name + * . + * @param attr + * Pointer to attribute + * @return + * 0 on success, -1 on failure + */ +int rte_emu_region_map(uint16_t dev_id, const char *region_name, + uint16_t region_size, uint64_t *base_addr); + +extern struct rte_emu_dev rte_emu_devices[]; +#endif /* _RTE_EMUDEV_H_ */