diff options
Diffstat (limited to 'src/vnet/devices/virtio')
-rw-r--r-- | src/vnet/devices/virtio/cli.c | 2 | ||||
-rw-r--r-- | src/vnet/devices/virtio/pci.c | 367 | ||||
-rw-r--r-- | src/vnet/devices/virtio/pci.h | 66 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio.h | 19 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio_pci_legacy.c | 383 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio_pci_legacy.h | 44 |
6 files changed, 531 insertions, 350 deletions
diff --git a/src/vnet/devices/virtio/cli.c b/src/vnet/devices/virtio/cli.c index 1b37338af1f..6d47bad7e39 100644 --- a/src/vnet/devices/virtio/cli.c +++ b/src/vnet/devices/virtio/cli.c @@ -229,7 +229,7 @@ show_virtio_pci_fn (vlib_main_t * vm, unformat_input_t * input, { vif = pool_elt_at_index (vim->interfaces, hi->dev_instance); if (vif->type == VIRTIO_IF_TYPE_PCI) - debug_device_config_space (vm, vif); + vif->virtio_pci_func->device_debug_config_space (vm, vif); } virtio_show (vm, hw_if_indices, show_descr, VIRTIO_IF_TYPE_PCI); diff --git a/src/vnet/devices/virtio/pci.c b/src/vnet/devices/virtio/pci.c index d28c7464e5a..16c7f6d5ed5 100644 --- a/src/vnet/devices/virtio/pci.c +++ b/src/vnet/devices/virtio/pci.c @@ -36,9 +36,6 @@ #define PCI_MSIX_ENABLE 0x8000 -#define PCI_CONFIG_SIZE(vif) ((vif->msix_enabled == VIRTIO_MSIX_ENABLED) ? \ - 24 : 20) - static pci_device_id_t virtio_pci_device_ids[] = { { .vendor_id = PCI_VENDOR_ID_VIRTIO, @@ -49,204 +46,6 @@ static pci_device_id_t virtio_pci_device_ids[] = { {0}, }; -static void -virtio_pci_legacy_read_config (vlib_main_t * vm, virtio_if_t * vif, void *dst, - int len, u32 addr) -{ - u32 size = 0; - vlib_pci_dev_handle_t h = vif->pci_dev_handle; - - while (len > 0) - { - if (len >= 4) - { - size = 4; - vlib_pci_read_io_u32 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst); - } - else if (len >= 2) - { - size = 2; - vlib_pci_read_io_u16 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst); - } - else - { - size = 1; - vlib_pci_read_io_u8 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst); - } - dst = (u8 *) dst + size; - addr += size; - len -= size; - } -} - -static void -virtio_pci_legacy_write_config (vlib_main_t * vm, virtio_if_t * vif, - void *src, int len, u32 addr) -{ - u32 size = 0; - vlib_pci_dev_handle_t h = vif->pci_dev_handle; - - while (len > 0) - { - if (len >= 4) - { - size = 4; - vlib_pci_write_io_u32 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src); - } - else if (len >= 2) - { - size = 2; - vlib_pci_write_io_u16 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src); - } - else - { - size = 1; - vlib_pci_write_io_u8 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src); - } - src = (u8 *) src + size; - addr += size; - len -= size; - } -} - -static u64 -virtio_pci_legacy_get_host_features (vlib_main_t * vm, virtio_if_t * vif) -{ - u32 features; - vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_HOST_FEATURES, - &features); - return features; -} - -static u32 -virtio_pci_legacy_get_guest_features (vlib_main_t * vm, virtio_if_t * vif) -{ - u32 feature = 0; - vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES, - &feature); - vif->features = feature; - return feature; -} - -static u32 -virtio_pci_legacy_set_guest_features (vlib_main_t * vm, virtio_if_t * vif, - u64 features) -{ - if ((features >> 32) != 0) - { - clib_warning ("only 32 bit features are allowed for legacy virtio!"); - } - u32 feature = 0, guest_features = (u32) features; - vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES, - &guest_features); - vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES, - &feature); - return feature; -} - -static u8 -virtio_pci_legacy_get_status (vlib_main_t * vm, virtio_if_t * vif) -{ - u8 status = 0; - vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &status); - return status; -} - -static void -virtio_pci_legacy_set_status (vlib_main_t * vm, virtio_if_t * vif, u8 status) -{ - if (status != VIRTIO_CONFIG_STATUS_RESET) - status |= virtio_pci_legacy_get_status (vm, vif); - vlib_pci_write_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &status); -} - -static u8 -virtio_pci_legacy_reset (vlib_main_t * vm, virtio_if_t * vif) -{ - virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_RESET); - return virtio_pci_legacy_get_status (vm, vif); -} - -static u8 -virtio_pci_legacy_get_isr (vlib_main_t * vm, virtio_if_t * vif) -{ - u8 isr = 0; - vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_ISR, &isr); - return isr; -} - -static u16 -virtio_pci_legacy_get_queue_num (vlib_main_t * vm, virtio_if_t * vif, - u16 queue_id) -{ - u16 queue_num = 0; - vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, - &queue_id); - vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NUM, - &queue_num); - return queue_num; -} - -static int -virtio_pci_legacy_setup_queue (vlib_main_t * vm, virtio_if_t * vif, - u16 queue_id, void *p) -{ - u64 addr = vlib_physmem_get_pa (vm, p) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT; - u32 addr2 = 0; - vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, - &queue_id); - vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, - (u32 *) & addr); - vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, - &addr2); - if ((u32) addr == addr2) - return 0; - return 1; -} - -static void -virtio_pci_legacy_del_queue (vlib_main_t * vm, virtio_if_t * vif, - u16 queue_id) -{ - u32 src = 0; - vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, - &queue_id); - vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, &src); -} - -inline void -virtio_pci_legacy_notify_queue (vlib_main_t * vm, virtio_if_t * vif, - u16 queue_id) -{ - vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY, - &queue_id); -} - -/* Enable one vector (0) for Link State Intrerrupt */ -static u16 -virtio_pci_legacy_set_config_irq (vlib_main_t * vm, virtio_if_t * vif, - u16 vec) -{ - vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR, - &vec); - vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR, - &vec); - return vec; -} - -static u16 -virtio_pci_legacy_set_queue_irq (vlib_main_t * vm, virtio_if_t * vif, u16 vec, - u16 queue_id) -{ - vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, - &queue_id); - vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR, - &vec); - vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR, - &vec); - return vec; -} - static u32 virtio_pci_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hw, u32 flags) @@ -257,17 +56,12 @@ virtio_pci_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hw, static clib_error_t * virtio_pci_get_max_virtqueue_pairs (vlib_main_t * vm, virtio_if_t * vif) { - virtio_net_config_t config; clib_error_t *error = 0; u16 max_queue_pairs = 1; if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ)) { - virtio_pci_legacy_read_config (vm, vif, &config.max_virtqueue_pairs, - sizeof (config.max_virtqueue_pairs), - STRUCT_OFFSET_OF (virtio_net_config_t, - max_virtqueue_pairs)); - max_queue_pairs = config.max_virtqueue_pairs; + max_queue_pairs = vif->virtio_pci_func->get_max_queue_pairs (vm, vif); } virtio_log_debug (vif, "max queue pair is %x", max_queue_pairs); @@ -283,8 +77,8 @@ virtio_pci_get_max_virtqueue_pairs (vlib_main_t * vm, virtio_if_t * vif) static void virtio_pci_set_mac (vlib_main_t * vm, virtio_if_t * vif) { - virtio_pci_legacy_write_config (vm, vif, vif->mac_addr, - sizeof (vif->mac_addr), 0); + if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MAC)) + vif->virtio_pci_func->set_mac (vm, vif); } static u32 @@ -292,8 +86,7 @@ virtio_pci_get_mac (vlib_main_t * vm, virtio_if_t * vif) { if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MAC)) { - virtio_pci_legacy_read_config (vm, vif, vif->mac_addr, - sizeof (vif->mac_addr), 0); + vif->virtio_pci_func->get_mac (vm, vif); return 0; } return 1; @@ -307,9 +100,7 @@ virtio_pci_is_link_up (vlib_main_t * vm, virtio_if_t * vif) */ u16 status = 1; if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_STATUS)) - virtio_pci_legacy_read_config (vm, vif, &status, sizeof (status), /* mac */ - STRUCT_OFFSET_OF (virtio_net_config_t, - status)); + status = vif->virtio_pci_func->get_device_status (vm, vif); return status; } @@ -358,7 +149,7 @@ virtio_pci_irq_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h) u8 isr = 0; u16 line = 0; - isr = virtio_pci_legacy_get_isr (vm, vif); + isr = vif->virtio_pci_func->get_isr (vm, vif); /* * If the lower bit is set: look through the used rings of @@ -403,72 +194,6 @@ device_status (vlib_main_t * vm, virtio_if_t * vif) } } -inline void -debug_device_config_space (vlib_main_t * vm, virtio_if_t * vif) -{ - u32 data_u32; - u16 data_u16; - u8 data_u8; - vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_HOST_FEATURES, - &data_u32); - vlib_cli_output (vm, "remote features 0x%lx", data_u32); - vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES, - &data_u32); - vlib_cli_output (vm, "guest features 0x%lx", data_u32); - vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, - &data_u32); - vlib_cli_output (vm, "queue address 0x%lx", data_u32); - vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NUM, - &data_u16); - vlib_cli_output (vm, "queue size 0x%x", data_u16); - vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, - &data_u16); - vlib_cli_output (vm, "queue select 0x%x", data_u16); - vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY, - &data_u16); - vlib_cli_output (vm, "queue notify 0x%x", data_u16); - vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &data_u8); - vlib_cli_output (vm, "status 0x%x", data_u8); - vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_ISR, &data_u8); - vlib_cli_output (vm, "isr 0x%x", data_u8); - - if (vif->msix_enabled == VIRTIO_MSIX_ENABLED) - { - vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR, - &data_u16); - vlib_cli_output (vm, "config vector 0x%x", data_u16); - u16 queue_id = 0; - vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, - &queue_id); - vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR, - &data_u16); - vlib_cli_output (vm, "queue vector for queue (0) 0x%x", data_u16); - } - - u8 mac[6]; - virtio_pci_legacy_read_config (vm, vif, mac, sizeof (mac), 0); - vlib_cli_output (vm, "mac %U", format_ethernet_address, mac); - virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16), /* offset to status */ - 6); - vlib_cli_output (vm, "link up/down status 0x%x", data_u16); - virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16), - /* offset to max_virtqueue */ 8); - vlib_cli_output (vm, "num of virtqueue 0x%x", data_u16); - virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16), /* offset to mtu */ - 10); - vlib_cli_output (vm, "mtu 0x%x", data_u16); - - u32 i = PCI_CONFIG_SIZE (vif) + 12, a = 4; - i += a; - i &= ~a; - for (; i < 64; i += 4) - { - u32 data = 0; - vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, i, &data); - vlib_cli_output (vm, "0x%lx", data); - } -} - struct virtio_ctrl_msg { struct virtio_net_ctrl_hdr ctrl; @@ -587,8 +312,8 @@ virtio_pci_disable_offload (vlib_main_t * vm, virtio_if_t * vif) status = virtio_pci_send_ctrl_msg (vm, vif, &offload_hdr, sizeof (offloads)); virtio_log_debug (vif, "disable offloads"); - vif->remote_features = virtio_pci_legacy_get_host_features (vm, vif); - virtio_pci_legacy_get_guest_features (vm, vif); + vif->remote_features = vif->virtio_pci_func->get_device_features (vm, vif); + vif->virtio_pci_func->get_driver_features (vm, vif); return status; } @@ -608,8 +333,8 @@ virtio_pci_enable_checksum_offload (vlib_main_t * vm, virtio_if_t * vif) status = virtio_pci_send_ctrl_msg (vm, vif, &csum_offload_hdr, sizeof (offloads)); virtio_log_debug (vif, "enable checksum offload"); - vif->remote_features = virtio_pci_legacy_get_host_features (vm, vif); - virtio_pci_legacy_get_guest_features (vm, vif); + vif->remote_features = vif->virtio_pci_func->get_device_features (vm, vif); + vif->features = vif->virtio_pci_func->get_driver_features (vm, vif); return status; } @@ -629,8 +354,8 @@ virtio_pci_enable_gso (vlib_main_t * vm, virtio_if_t * vif) status = virtio_pci_send_ctrl_msg (vm, vif, &gso_hdr, sizeof (offloads)); virtio_log_debug (vif, "enable gso"); - vif->remote_features = virtio_pci_legacy_get_host_features (vm, vif); - virtio_pci_legacy_get_guest_features (vm, vif); + vif->remote_features = vif->virtio_pci_func->get_device_features (vm, vif); + vif->virtio_pci_func->get_driver_features (vm, vif); return status; } @@ -733,7 +458,7 @@ virtio_pci_control_vring_init (vlib_main_t * vm, virtio_if_t * vif, u32 i = 0; void *ptr = NULL; - queue_size = virtio_pci_legacy_get_queue_num (vm, vif, queue_num); + queue_size = vif->virtio_pci_func->get_queue_size (vm, vif, queue_num); if (!virtio_pci_queue_size_valid (queue_size)) clib_warning ("queue size is not valid"); @@ -768,7 +493,7 @@ virtio_pci_control_vring_init (vlib_main_t * vm, virtio_if_t * vif, vring->size = queue_size; virtio_log_debug (vif, "control-queue: number %u, size %u", queue_num, queue_size); - virtio_pci_legacy_setup_queue (vm, vif, queue_num, ptr); + vif->virtio_pci_func->setup_queue (vm, vif, queue_num, ptr); vring->kick_fd = -1; return error; @@ -784,7 +509,7 @@ virtio_pci_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 queue_num) u32 i = 0; void *ptr = NULL; - queue_size = virtio_pci_legacy_get_queue_num (vm, vif, queue_num); + queue_size = vif->virtio_pci_func->get_queue_size (vm, vif, queue_num); if (!virtio_pci_queue_size_valid (queue_size)) clib_warning ("queue size is not valid"); @@ -840,7 +565,7 @@ virtio_pci_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 queue_num) queue_size); } vring->size = queue_size; - if (virtio_pci_legacy_setup_queue (vm, vif, queue_num, ptr)) + if (vif->virtio_pci_func->setup_queue (vm, vif, queue_num, ptr)) return clib_error_return (0, "error in queue address setup"); vring->kick_fd = -1; @@ -884,23 +609,21 @@ virtio_negotiate_features (vlib_main_t * vm, virtio_if_t * vif, if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MTU)) { - virtio_net_config_t config; - virtio_pci_legacy_read_config (vm, vif, &config.mtu, - sizeof (config.mtu), - STRUCT_OFFSET_OF (virtio_net_config_t, - mtu)); - if (config.mtu < 64) + u16 mtu = 0; + mtu = vif->virtio_pci_func->get_mtu (vm, vif); + + if (mtu < 64) vif->features &= ~VIRTIO_FEATURE (VIRTIO_NET_F_MTU); } - vif->features = - virtio_pci_legacy_set_guest_features (vm, vif, vif->features); + vif->virtio_pci_func->set_driver_features (vm, vif, vif->features); + vif->features = vif->virtio_pci_func->get_driver_features (vm, vif); } void virtio_pci_read_device_feature (vlib_main_t * vm, virtio_if_t * vif) { - vif->remote_features = virtio_pci_legacy_get_host_features (vm, vif); + vif->remote_features = vif->virtio_pci_func->get_device_features (vm, vif); } int @@ -911,22 +634,22 @@ virtio_pci_reset_device (vlib_main_t * vm, virtio_if_t * vif) /* * Reset the device */ - status = virtio_pci_legacy_reset (vm, vif); + status = vif->virtio_pci_func->device_reset (vm, vif); /* * Set the Acknowledge status bit */ - virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_ACK); + vif->virtio_pci_func->set_status (vm, vif, VIRTIO_CONFIG_STATUS_ACK); /* * Set the Driver status bit */ - virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_DRIVER); + vif->virtio_pci_func->set_status (vm, vif, VIRTIO_CONFIG_STATUS_DRIVER); /* * Read the status and verify it */ - status = virtio_pci_legacy_get_status (vm, vif); + status = vif->virtio_pci_func->get_status (vm, vif); if (! ((status & VIRTIO_CONFIG_STATUS_ACK) && (status & VIRTIO_CONFIG_STATUS_DRIVER))) @@ -1023,6 +746,8 @@ virtio_pci_read_caps (vlib_main_t * vm, virtio_if_t * vif) pos = cap.cap_next; } + vif->virtio_pci_func = &virtio_pci_legacy_func; + if (common_cfg == 0 || notify_base == 0 || dev_cfg == 0 || isr == 0) { virtio_log_debug (vif, "legacy virtio pci device found"); @@ -1077,8 +802,9 @@ virtio_pci_device_init (vlib_main_t * vm, virtio_if_t * vif, /* * After FEATURE_OK, driver should not accept new feature bits */ - virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_FEATURES_OK); - status = virtio_pci_legacy_get_status (vm, vif); + vif->virtio_pci_func->set_status (vm, vif, + VIRTIO_CONFIG_STATUS_FEATURES_OK); + status = vif->virtio_pci_func->get_status (vm, vif); if (!(status & VIRTIO_CONFIG_STATUS_FEATURES_OK)) { args->rv = VNET_API_ERROR_UNSUPPORTED; @@ -1136,8 +862,10 @@ virtio_pci_device_init (vlib_main_t * vm, virtio_if_t * vif, args->rv = VNET_API_ERROR_INIT_FAILED; virtio_log_error (vif, "%s (%u) %s", "error in rxq-queue", RX_QUEUE (i), "initialization"); - clib_error_return (error, "%s (%u) %s", "error in rxq-queue", - RX_QUEUE (i), "initialization"); + error = + clib_error_return (error, "%s (%u) %s", "error in rxq-queue", + RX_QUEUE (i), "initialization"); + goto err; } else { @@ -1165,8 +893,10 @@ virtio_pci_device_init (vlib_main_t * vm, virtio_if_t * vif, args->rv = VNET_API_ERROR_INIT_FAILED; virtio_log_error (vif, "%s (%u) %s", "error in txq-queue", TX_QUEUE (i), "initialization"); - clib_error_return (error, "%s (%u) %s", "error in txq-queue", - TX_QUEUE (i), "initialization"); + error = + clib_error_return (error, "%s (%u) %s", "error in txq-queue", + TX_QUEUE (i), "initialization"); + goto err; } else { @@ -1197,7 +927,7 @@ virtio_pci_device_init (vlib_main_t * vm, virtio_if_t * vif, if (vif->msix_enabled == VIRTIO_MSIX_ENABLED) { int i, j; - if (virtio_pci_legacy_set_config_irq (vm, vif, 0) == + if (vif->virtio_pci_func->set_config_irq (vm, vif, 0) == VIRTIO_MSI_NO_VECTOR) { virtio_log_warning (vif, "config vector 0 is not set"); @@ -1208,7 +938,8 @@ virtio_pci_device_init (vlib_main_t * vm, virtio_if_t * vif, } for (i = 0, j = 1; i < vif->max_queue_pairs; i++, j++) { - if (virtio_pci_legacy_set_queue_irq (vm, vif, j, RX_QUEUE (i)) == + if (vif->virtio_pci_func->set_queue_irq (vm, vif, j, + RX_QUEUE (i)) == VIRTIO_MSI_NO_VECTOR) { virtio_log_warning (vif, "queue (%u) vector is not set at %u", @@ -1225,8 +956,8 @@ virtio_pci_device_init (vlib_main_t * vm, virtio_if_t * vif, /* * set the driver status OK */ - virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_DRIVER_OK); - vif->status = virtio_pci_legacy_get_status (vm, vif); + vif->virtio_pci_func->set_status (vm, vif, VIRTIO_CONFIG_STATUS_DRIVER_OK); + vif->status = vif->virtio_pci_func->get_status (vm, vif); err: return error; } @@ -1431,14 +1162,14 @@ virtio_pci_delete_if (vlib_main_t * vm, virtio_if_t * vif) for (i = 0; i < vif->max_queue_pairs; i++) { - virtio_pci_legacy_del_queue (vm, vif, RX_QUEUE (i)); - virtio_pci_legacy_del_queue (vm, vif, TX_QUEUE (i)); + vif->virtio_pci_func->del_queue (vm, vif, RX_QUEUE (i)); + vif->virtio_pci_func->del_queue (vm, vif, TX_QUEUE (i)); } if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) - virtio_pci_legacy_del_queue (vm, vif, vif->max_queue_pairs * 2); + vif->virtio_pci_func->del_queue (vm, vif, vif->max_queue_pairs * 2); - virtio_pci_legacy_reset (vm, vif); + vif->virtio_pci_func->device_reset (vm, vif); if (vif->hw_if_index) { diff --git a/src/vnet/devices/virtio/pci.h b/src/vnet/devices/virtio/pci.h index 8ec1360bc59..dfc0711305a 100644 --- a/src/vnet/devices/virtio/pci.h +++ b/src/vnet/devices/virtio/pci.h @@ -20,23 +20,6 @@ #define VIRTIO_PCI_ABI_VERSION 0 /* - * VirtIO Header, located in BAR 0. - */ -#define VIRTIO_PCI_HOST_FEATURES 0 /* host's supported features (32bit, RO) */ -#define VIRTIO_PCI_GUEST_FEATURES 4 /* guest's supported features (32, RW) */ -#define VIRTIO_PCI_QUEUE_PFN 8 /* physical address of VQ (32, RW) */ -#define VIRTIO_PCI_QUEUE_NUM 12 /* number of ring entries (16, RO) */ -#define VIRTIO_PCI_QUEUE_SEL 14 /* current VQ selection (16, RW) */ -#define VIRTIO_PCI_QUEUE_NOTIFY 16 /* notify host regarding VQ (16, RW) */ -#define VIRTIO_PCI_STATUS 18 /* device status register (8, RW) */ -#define VIRTIO_PCI_ISR 19 /* interrupt status register, reading - * also clears the register (8, RO) */ -/* Only if MSIX is enabled: */ -#define VIRTIO_MSI_CONFIG_VECTOR 20 /* configuration change vector (16, RW) */ -#define VIRTIO_MSI_QUEUE_VECTOR 22 /* vector for selected VQ notifications - (16, RW) */ - -/* * Vector value used to disable MSI for queue. * define in include/linux/virtio_pci.h * #define VIRTIO_MSI_NO_VECTOR 0xFFFF @@ -187,6 +170,14 @@ typedef struct typedef struct { + u8 mac[6]; + u16 status; + u16 max_virtqueue_pairs; + u16 mtu; +} virtio_net_config_t; + +typedef struct +{ u64 addr; u32 len; u16 flags; @@ -215,6 +206,44 @@ typedef struct /* u16 avail_event; */ } vring_used_t; +typedef struct _virtio_pci_func +{ + void (*read_config) (vlib_main_t * vm, virtio_if_t * vif, void *dst, + int len, u32 addr); + void (*write_config) (vlib_main_t * vm, virtio_if_t * vif, void *src, + int len, u32 addr); + + u64 (*get_device_features) (vlib_main_t * vm, virtio_if_t * vif); + u64 (*get_driver_features) (vlib_main_t * vm, virtio_if_t * vif); + void (*set_driver_features) (vlib_main_t * vm, virtio_if_t * vif, + u64 features); + + u8 (*get_status) (vlib_main_t * vm, virtio_if_t * vif); + void (*set_status) (vlib_main_t * vm, virtio_if_t * vif, u8 status); + u8 (*device_reset) (vlib_main_t * vm, virtio_if_t * vif); + + u8 (*get_isr) (vlib_main_t * vm, virtio_if_t * vif); + + u16 (*get_queue_size) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id); + void (*set_queue_size) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id, + u16 queue_size); + u8 (*setup_queue) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id, + void *p); + void (*del_queue) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id); + void (*notify_queue) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id); + + u16 (*set_config_irq) (vlib_main_t * vm, virtio_if_t * vif, u16 vec); + u16 (*set_queue_irq) (vlib_main_t * vm, virtio_if_t * vif, u16 vec, + u16 queue_id); + + void (*get_mac) (vlib_main_t * vm, virtio_if_t * vif); + void (*set_mac) (vlib_main_t * vm, virtio_if_t * vif); + u16 (*get_device_status) (vlib_main_t * vm, virtio_if_t * vif); + u16 (*get_max_queue_pairs) (vlib_main_t * vm, virtio_if_t * vif); + u16 (*get_mtu) (vlib_main_t * vm, virtio_if_t * vif); + void (*device_debug_config_space) (vlib_main_t * vm, virtio_if_t * vif); +} virtio_pci_func_t; + typedef struct { u32 addr; @@ -229,7 +258,8 @@ typedef struct clib_error_t *error; } virtio_pci_create_if_args_t; -extern void debug_device_config_space (vlib_main_t * vm, virtio_if_t * vif); +extern const virtio_pci_func_t virtio_pci_legacy_func; + extern void device_status (vlib_main_t * vm, virtio_if_t * vif); void virtio_pci_create_if (vlib_main_t * vm, virtio_pci_create_if_args_t * args); diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h index b57c6ebd77d..e1ba71dae2e 100644 --- a/src/vnet/devices/virtio/virtio.h +++ b/src/vnet/devices/virtio/virtio.h @@ -70,9 +70,6 @@ typedef enum #undef _ } virtio_if_flag_t; -#define VIRTIO_NUM_RX_DESC 256 -#define VIRTIO_NUM_TX_DESC 256 - #define VIRTIO_FEATURE(X) (1ULL << X) #define TX_QUEUE(X) ((X*2) + 1) @@ -80,6 +77,9 @@ typedef enum #define TX_QUEUE_ACCESS(X) (X/2) #define RX_QUEUE_ACCESS(X) (X/2) +#define VIRTIO_NUM_RX_DESC 256 +#define VIRTIO_NUM_TX_DESC 256 + #define foreach_virtio_if_types \ _ (TAP, 0) \ _ (TUN, 1) \ @@ -93,15 +93,6 @@ typedef enum VIRTIO_IF_N_TYPES = (1 << 3), } virtio_if_type_t; - -typedef struct -{ - u8 mac[6]; - u16 status; - u16 max_virtqueue_pairs; - u16 mtu; -} virtio_net_config_t; - #define VIRTIO_RING_FLAG_MASK_INT 1 typedef struct @@ -139,6 +130,8 @@ typedef union u32 as_u32; } pci_addr_t; +typedef struct _virtio_pci_func virtio_pci_func_t; + typedef struct { CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); @@ -197,6 +190,7 @@ typedef struct u32 tap_flags; int ifindex; virtio_vring_t *cxq_vring; + const virtio_pci_func_t *virtio_pci_func; } virtio_if_t; typedef struct @@ -245,7 +239,6 @@ virtio_kick (vlib_main_t * vm, virtio_vring_t * vring, virtio_if_t * vif) } } - #define virtio_log_debug(vif, f, ...) \ { \ vlib_log(VLIB_LOG_LEVEL_DEBUG, virtio_main.log_default, \ diff --git a/src/vnet/devices/virtio/virtio_pci_legacy.c b/src/vnet/devices/virtio/virtio_pci_legacy.c new file mode 100644 index 00000000000..f70776db5ac --- /dev/null +++ b/src/vnet/devices/virtio/virtio_pci_legacy.c @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2018 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <vlib/vlib.h> +#include <vlib/pci/pci.h> +#include <vnet/ethernet/ethernet.h> +#include <vnet/ip/ip4_packet.h> +#include <vnet/ip/ip6_packet.h> +#include <vnet/devices/virtio/virtio.h> +#include <vnet/devices/virtio/virtio_pci_legacy.h> +#include <vnet/devices/virtio/pci.h> + +#define PCI_CONFIG_SIZE(vif) ((vif->msix_enabled == VIRTIO_MSIX_ENABLED) ? \ + 24 : 20) + +static void +virtio_pci_legacy_read_config (vlib_main_t * vm, virtio_if_t * vif, void *dst, + int len, u32 addr) +{ + u32 size = 0; + vlib_pci_dev_handle_t h = vif->pci_dev_handle; + + while (len > 0) + { + if (len >= 4) + { + size = 4; + vlib_pci_read_io_u32 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst); + } + else if (len >= 2) + { + size = 2; + vlib_pci_read_io_u16 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst); + } + else + { + size = 1; + vlib_pci_read_io_u8 (vm, h, PCI_CONFIG_SIZE (vif) + addr, dst); + } + dst = (u8 *) dst + size; + addr += size; + len -= size; + } +} + +static void +virtio_pci_legacy_write_config (vlib_main_t * vm, virtio_if_t * vif, + void *src, int len, u32 addr) +{ + u32 size = 0; + vlib_pci_dev_handle_t h = vif->pci_dev_handle; + + while (len > 0) + { + if (len >= 4) + { + size = 4; + vlib_pci_write_io_u32 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src); + } + else if (len >= 2) + { + size = 2; + vlib_pci_write_io_u16 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src); + } + else + { + size = 1; + vlib_pci_write_io_u8 (vm, h, PCI_CONFIG_SIZE (vif) + addr, src); + } + src = (u8 *) src + size; + addr += size; + len -= size; + } +} + +static u64 +virtio_pci_legacy_get_host_features (vlib_main_t * vm, virtio_if_t * vif) +{ + u32 host_features; + vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_HOST_FEATURES, + &host_features); + return host_features; +} + +static u64 +virtio_pci_legacy_get_guest_features (vlib_main_t * vm, virtio_if_t * vif) +{ + u32 guest_features = 0; + vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES, + &guest_features); + vif->features = guest_features; + return guest_features; +} + +static void +virtio_pci_legacy_set_guest_features (vlib_main_t * vm, virtio_if_t * vif, + u64 guest_features) +{ + if ((guest_features >> 32) != 0) + { + clib_warning ("only 32 bit features are allowed for legacy virtio!"); + } + u32 features = 0; + vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES, + (u32 *) & guest_features); + vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES, + &features); + if (features != (u32) guest_features) + { + clib_warning ("legacy set guest features failed!"); + } +} + +static u8 +virtio_pci_legacy_get_status (vlib_main_t * vm, virtio_if_t * vif) +{ + u8 status = 0; + vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &status); + return status; +} + +static void +virtio_pci_legacy_set_status (vlib_main_t * vm, virtio_if_t * vif, u8 status) +{ + if (status != VIRTIO_CONFIG_STATUS_RESET) + status |= virtio_pci_legacy_get_status (vm, vif); + vlib_pci_write_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &status); +} + +static u8 +virtio_pci_legacy_reset (vlib_main_t * vm, virtio_if_t * vif) +{ + virtio_pci_legacy_set_status (vm, vif, VIRTIO_CONFIG_STATUS_RESET); + return virtio_pci_legacy_get_status (vm, vif); +} + +static u8 +virtio_pci_legacy_get_isr (vlib_main_t * vm, virtio_if_t * vif) +{ + u8 isr = 0; + vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_ISR, &isr); + return isr; +} + +static u16 +virtio_pci_legacy_get_queue_num (vlib_main_t * vm, virtio_if_t * vif, + u16 queue_id) +{ + u16 queue_num = 0; + vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, + &queue_id); + vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NUM, + &queue_num); + return queue_num; +} + +static void +virtio_pci_legacy_set_queue_num (vlib_main_t * vm, virtio_if_t * vif, + u16 queue_id, u16 queue_size) +{ + /* do nothing */ +} + +static u8 +virtio_pci_legacy_setup_queue (vlib_main_t * vm, virtio_if_t * vif, + u16 queue_id, void *p) +{ + u64 addr = vlib_physmem_get_pa (vm, p) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT; + u32 addr2 = 0; + vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, + &queue_id); + vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, + (u32 *) & addr); + vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, + &addr2); + if ((u32) addr == addr2) + return 0; + + clib_warning ("legacy queue setup failed!"); + return 1; +} + +static void +virtio_pci_legacy_del_queue (vlib_main_t * vm, virtio_if_t * vif, + u16 queue_id) +{ + u32 src = 0; + vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, + &queue_id); + vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, &src); +} + +inline void +virtio_pci_legacy_notify_queue (vlib_main_t * vm, virtio_if_t * vif, + u16 queue_id) +{ + vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY, + &queue_id); +} + +/* Enable one vector (0) for Link State Intrerrupt */ +static u16 +virtio_pci_legacy_set_config_irq (vlib_main_t * vm, virtio_if_t * vif, + u16 vec) +{ + vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR, + &vec); + vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR, + &vec); + return vec; +} + +static u16 +virtio_pci_legacy_set_queue_irq (vlib_main_t * vm, virtio_if_t * vif, u16 vec, + u16 queue_id) +{ + vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, + &queue_id); + vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR, + &vec); + vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR, + &vec); + return vec; +} + +static void +virtio_pci_legacy_get_mac (vlib_main_t * vm, virtio_if_t * vif) +{ + virtio_pci_legacy_read_config (vm, vif, vif->mac_addr, + sizeof (vif->mac_addr), 0); +} + +static void +virtio_pci_legacy_set_mac (vlib_main_t * vm, virtio_if_t * vif) +{ + virtio_pci_legacy_write_config (vm, vif, vif->mac_addr, + sizeof (vif->mac_addr), 0); +} + +static u16 +virtio_pci_legacy_get_device_status (vlib_main_t * vm, virtio_if_t * vif) +{ + u16 status = 0; + virtio_pci_legacy_read_config (vm, vif, &status, + sizeof (status), + STRUCT_OFFSET_OF + (virtio_net_config_t, status)); + return status; +} + +static u16 +virtio_pci_legacy_get_max_queue_pairs (vlib_main_t * vm, virtio_if_t * vif) +{ + virtio_net_config_t config; + virtio_pci_legacy_read_config (vm, vif, &config.max_virtqueue_pairs, + sizeof (config.max_virtqueue_pairs), + STRUCT_OFFSET_OF + (virtio_net_config_t, max_virtqueue_pairs)); + return config.max_virtqueue_pairs; +} + +static u16 +virtio_pci_legacy_get_mtu (vlib_main_t * vm, virtio_if_t * vif) +{ + virtio_net_config_t config; + virtio_pci_legacy_read_config (vm, vif, &config.mtu, + sizeof (config.mtu), + STRUCT_OFFSET_OF (virtio_net_config_t, mtu)); + return config.mtu; +} + + +static void +virtio_pci_legacy_device_debug_config_space (vlib_main_t * vm, + virtio_if_t * vif) +{ + u32 data_u32; + u16 data_u16; + u8 data_u8; + vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_HOST_FEATURES, + &data_u32); + vlib_cli_output (vm, "remote features 0x%lx", data_u32); + vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_GUEST_FEATURES, + &data_u32); + vlib_cli_output (vm, "guest features 0x%lx", data_u32); + vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, + &data_u32); + vlib_cli_output (vm, "queue address 0x%lx", data_u32); + vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NUM, + &data_u16); + vlib_cli_output (vm, "queue size 0x%x", data_u16); + vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, + &data_u16); + vlib_cli_output (vm, "queue select 0x%x", data_u16); + vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY, + &data_u16); + vlib_cli_output (vm, "queue notify 0x%x", data_u16); + vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_STATUS, &data_u8); + vlib_cli_output (vm, "status 0x%x", data_u8); + vlib_pci_read_io_u8 (vm, vif->pci_dev_handle, VIRTIO_PCI_ISR, &data_u8); + vlib_cli_output (vm, "isr 0x%x", data_u8); + + if (vif->msix_enabled == VIRTIO_MSIX_ENABLED) + { + vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_CONFIG_VECTOR, + &data_u16); + vlib_cli_output (vm, "config vector 0x%x", data_u16); + u16 queue_id = 0; + vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_SEL, + &queue_id); + vlib_pci_read_io_u16 (vm, vif->pci_dev_handle, VIRTIO_MSI_QUEUE_VECTOR, + &data_u16); + vlib_cli_output (vm, "queue vector for queue (0) 0x%x", data_u16); + } + + u8 mac[6]; + virtio_pci_legacy_read_config (vm, vif, mac, sizeof (mac), 0); + vlib_cli_output (vm, "mac %U", format_ethernet_address, mac); + virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16), /* offset to status */ + 6); + vlib_cli_output (vm, "link up/down status 0x%x", data_u16); + virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16), + /* offset to max_virtqueue */ 8); + vlib_cli_output (vm, "num of virtqueue 0x%x", data_u16); + virtio_pci_legacy_read_config (vm, vif, &data_u16, sizeof (u16), /* offset to mtu */ + 10); + vlib_cli_output (vm, "mtu 0x%x", data_u16); + + u32 i = PCI_CONFIG_SIZE (vif) + 12, a = 4; + i += a; + i &= ~a; + for (; i < 64; i += 4) + { + u32 data = 0; + vlib_pci_read_io_u32 (vm, vif->pci_dev_handle, i, &data); + vlib_cli_output (vm, "0x%lx", data); + } +} + +const virtio_pci_func_t virtio_pci_legacy_func = { + .read_config = virtio_pci_legacy_read_config, + .write_config = virtio_pci_legacy_write_config, + .get_device_features = virtio_pci_legacy_get_host_features, + .get_driver_features = virtio_pci_legacy_get_guest_features, + .set_driver_features = virtio_pci_legacy_set_guest_features, + .get_status = virtio_pci_legacy_get_status, + .set_status = virtio_pci_legacy_set_status, + .device_reset = virtio_pci_legacy_reset, + .get_isr = virtio_pci_legacy_get_isr, + .get_queue_size = virtio_pci_legacy_get_queue_num, + .set_queue_size = virtio_pci_legacy_set_queue_num, + .setup_queue = virtio_pci_legacy_setup_queue, + .del_queue = virtio_pci_legacy_del_queue, + .notify_queue = virtio_pci_legacy_notify_queue, + .set_config_irq = virtio_pci_legacy_set_config_irq, + .set_queue_irq = virtio_pci_legacy_set_queue_irq, + .get_mac = virtio_pci_legacy_get_mac, + .set_mac = virtio_pci_legacy_set_mac, + .get_device_status = virtio_pci_legacy_get_device_status, + .get_max_queue_pairs = virtio_pci_legacy_get_max_queue_pairs, + .get_mtu = virtio_pci_legacy_get_mtu, + .device_debug_config_space = virtio_pci_legacy_device_debug_config_space, +}; + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/devices/virtio/virtio_pci_legacy.h b/src/vnet/devices/virtio/virtio_pci_legacy.h new file mode 100644 index 00000000000..0db04c1966a --- /dev/null +++ b/src/vnet/devices/virtio/virtio_pci_legacy.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __included_virtio_pci_legacy_h__ +#define __included_virtio_pci_legacy_h__ + +/* + * VirtIO Header, located in BAR 0. + */ +#define VIRTIO_PCI_HOST_FEATURES 0 /* host's supported features (32bit, RO) */ +#define VIRTIO_PCI_GUEST_FEATURES 4 /* guest's supported features (32, RW) */ +#define VIRTIO_PCI_QUEUE_PFN 8 /* physical address of VQ (32, RW) */ +#define VIRTIO_PCI_QUEUE_NUM 12 /* number of ring entries (16, RO) */ +#define VIRTIO_PCI_QUEUE_SEL 14 /* current VQ selection (16, RW) */ +#define VIRTIO_PCI_QUEUE_NOTIFY 16 /* notify host regarding VQ (16, RW) */ +#define VIRTIO_PCI_STATUS 18 /* device status register (8, RW) */ +#define VIRTIO_PCI_ISR 19 /* interrupt status register, reading + * also clears the register (8, RO) */ +/* Only if MSIX is enabled: */ +#define VIRTIO_MSI_CONFIG_VECTOR 20 /* configuration change vector (16, RW) */ +#define VIRTIO_MSI_QUEUE_VECTOR 22 /* vector for selected VQ notifications + (16, RW) */ +#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12 + +#endif /* __included_virtio_pci_legacy_h__ */ +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |