Changeset 6ccc424 in mainline
- Timestamp:
- 2018-05-22T19:06:50Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a86174ec
- Parents:
- 00192cde
- git-author:
- Jakub Jermar <jakub@…> (2018-04-21 22:14:00)
- git-committer:
- Jakub Jermar <jakub@…> (2018-05-22 19:06:50)
- Location:
- uspace/lib
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/include/pci_dev_iface.h
r00192cde r6ccc424 45 45 #define PCI_SUB_CLASS 0x0A 46 46 #define PCI_BASE_CLASS 0x0B 47 #define PCI_BAR0 0x10 47 48 #define PCI_CAP_PTR 0x34 49 50 #define PCI_BAR_COUNT 6 48 51 49 52 #define PCI_STATUS_CAP_LIST (1 << 4) -
uspace/lib/virtio/virtio-pci.c
r00192cde r6ccc424 33 33 34 34 #include <ddf/driver.h> 35 #include <ddf/log.h> 35 36 #include <pci_dev_iface.h> 36 37 37 static void virtio_pci_common_cfg(virtio_dev_t *vdev, hw_resource_list_t *res, 38 uint8_t bar, uint32_t offset, uint32_t length) 39 { 40 /* Proceed only if we don't have common config structure yet */ 38 static bool check_bar(virtio_dev_t *vdev, uint8_t bar) 39 { 40 /* We must ignore the capability if bar is greater than 5 */ 41 if (bar >= PCI_BAR_COUNT) 42 return false; 43 44 /* This is not a mapped BAR */ 45 if (!vdev->bar[bar].mapped) 46 return false; 47 48 return true; 49 } 50 51 static void virtio_pci_common_cfg(virtio_dev_t *vdev, uint8_t bar, 52 uint32_t offset, uint32_t length) 53 { 41 54 if (vdev->common_cfg) 42 55 return; 43 56 44 /* We must ignore the capability if bar is greater than 5 */ 45 if (bar > 5) 46 return; 57 if (!check_bar(vdev, bar)) 58 return; 59 60 vdev->common_cfg = vdev->bar[bar].mapped_base + offset; 61 62 ddf_msg(LVL_NOTE, "common_cfg=%p", vdev->common_cfg); 63 } 64 65 static void virtio_pci_notify_cfg(virtio_dev_t *vdev, uint8_t bar, 66 uint32_t offset, uint32_t length, uint32_t multiplier) 67 { 68 if (vdev->notify_base) 69 return; 70 71 if (!check_bar(vdev, bar)) 72 return; 73 74 vdev->notify_base = vdev->bar[bar].mapped_base + offset; 75 vdev->notify_off_multiplier = multiplier; 76 77 ddf_msg(LVL_NOTE, "notify_base=%p, off_multiplier=%u", 78 vdev->notify_base, vdev->notify_off_multiplier); 79 } 80 81 static void virtio_pci_isr_cfg(virtio_dev_t *vdev, uint8_t bar, uint32_t offset, 82 uint32_t length) 83 { 84 if (vdev->isr) 85 return; 86 87 if (!check_bar(vdev, bar)) 88 return; 89 90 vdev->isr = vdev->bar[bar].mapped_base + offset; 91 92 ddf_msg(LVL_NOTE, "isr=%p", vdev->isr); 93 } 94 95 static void virtio_pci_device_cfg(virtio_dev_t *vdev, uint8_t bar, 96 uint32_t offset, uint32_t length) 97 { 98 if (vdev->device_cfg) 99 return; 100 101 if (!check_bar(vdev, bar)) 102 return; 103 104 vdev->device_cfg = vdev->bar[bar].mapped_base + offset; 105 106 ddf_msg(LVL_NOTE, "device_cfg=%p", vdev->device_cfg); 47 107 } 48 108 49 109 errno_t virtio_pci_dev_init(ddf_dev_t *dev, virtio_dev_t *vdev) 50 110 { 111 memset(vdev, 0, sizeof(virtio_dev_t)); 112 51 113 async_sess_t *pci_sess = ddf_dev_parent_sess_get(dev); 52 114 if (!pci_sess) 53 115 return ENOENT; 54 116 55 errno_t rc; 117 pio_window_t pio_window; 118 errno_t rc = pio_window_get(pci_sess, &pio_window); 119 if (rc != EOK) 120 return rc; 121 56 122 hw_resource_list_t hw_res; 57 123 rc = hw_res_get_resource_list(pci_sess, &hw_res); 58 124 if (rc != EOK) 59 125 return rc; 126 127 /* 128 * Enable resources and reconstruct the mapping between BAR and resource 129 * indices. We are going to need this later when the VIRTIO PCI 130 * capabilities refer to specific BARs. 131 * 132 * XXX: The mapping should probably be provided by the PCI driver 133 * itself. 134 */ 135 for (unsigned i = 0, j = 0; i < PCI_BAR_COUNT && j < hw_res.count; 136 i++) { 137 /* Detect and skip unused BARs */ 138 uint32_t bar; 139 rc = pci_config_space_read_32(pci_sess, 140 PCI_BAR0 + i * sizeof(uint32_t), &bar); 141 if (!bar) 142 continue; 143 144 rc = pio_enable_resource(&pio_window, &hw_res.resources[j], 145 &vdev->bar[i].mapped_base); 146 if (rc == EOK) 147 vdev->bar[i].mapped = true; 148 j++; 149 } 60 150 61 151 /* … … 92 182 return rc; 93 183 184 uint32_t multiplier; 94 185 switch (type) { 95 186 case VIRTIO_PCI_CAP_COMMON_CFG: 96 virtio_pci_common_cfg(vdev, &hw_res, bar,97 offset,length);187 virtio_pci_common_cfg(vdev, bar, offset, 188 length); 98 189 break; 99 190 case VIRTIO_PCI_CAP_NOTIFY_CFG: 191 rc = pci_config_space_read_32(pci_sess, 192 VIRTIO_PCI_CAP_END(c), &multiplier); 193 if (rc != EOK) 194 return rc; 195 virtio_pci_notify_cfg(vdev, bar, offset, length, 196 multiplier); 100 197 break; 101 198 case VIRTIO_PCI_CAP_ISR_CFG: 199 virtio_pci_isr_cfg(vdev, bar, offset, length); 102 200 break; 103 201 case VIRTIO_PCI_CAP_DEVICE_CFG: 202 virtio_pci_device_cfg(vdev, bar, offset, 203 length); 104 204 break; 105 205 case VIRTIO_PCI_CAP_PCI_CFG: -
uspace/lib/virtio/virtio-pci.h
r00192cde r6ccc424 34 34 35 35 #include <ddf/driver.h> 36 #include <pci_dev_iface.h> 36 37 #include <ddi.h> 37 38 … … 40 41 #define VIRTIO_PCI_CAP_OFFSET(c) ((c) + 8) 41 42 #define VIRTIO_PCI_CAP_LENGTH(c) ((c) + 12) 43 #define VIRTIO_PCI_CAP_END(c) ((c) + 16) 42 44 43 45 #define VIRTIO_PCI_CAP_COMMON_CFG 1 … … 68 70 69 71 typedef struct { 72 struct { 73 bool mapped; 74 void *mapped_base; 75 } bar[PCI_BAR_COUNT]; 76 77 /** Commong configuration structure */ 70 78 virtio_pci_common_cfg_t *common_cfg; 79 80 /** Notification base address */ 81 ioport8_t *notify_base; 82 /** Notification offset multiplier */ 83 uint32_t notify_off_multiplier; 84 85 /** INT#x interrupt ISR register */ 86 ioport8_t *isr; 87 88 /** Device-specific configuration */ 89 void *device_cfg; 71 90 } virtio_dev_t; 72 91
Note:
See TracChangeset
for help on using the changeset viewer.