@@ -98,7 +98,7 @@ public:
9898 ~virtio_legacy_pci_device () {}
9999
100100 virtual const char *get_version () { return " legacy" ; }
101- virtual u16 get_type_id () { return _dev->get_subsystem_id (); };
101+ virtual u16 get_type_id () { return _dev->get_subsystem_id (); }
102102
103103 virtual void select_queue (int queue);
104104 virtual u16 get_queue_size ();
@@ -115,7 +115,7 @@ public:
115115 virtual u8 read_config (u32 offset);
116116 virtual u8 read_and_ack_isr ();
117117
118- virtual bool is_modern () { return false ; };
118+ virtual bool is_modern () { return false ; }
119119protected:
120120 virtual bool parse_pci_config ();
121121
@@ -145,6 +145,8 @@ enum VIRTIO_MODERN_PCI_CONFIG {
145145 VIRTIO_PCI_CAP_DEVICE_CFG = 4 ,
146146 /* PCI configuration access */
147147 VIRTIO_PCI_CAP_PCI_CFG = 5 ,
148+ /* Shared memory region */
149+ VIRTIO_PCI_CAP_SHARED_MEMORY_CFG = 8 ,
148150};
149151
150152/* This is the PCI capability header: */
@@ -154,11 +156,20 @@ struct virtio_pci_cap {
154156 u8 cap_len; /* Generic PCI field: capability length */
155157 u8 cfg_type; /* Identifies the structure. */
156158 u8 bar; /* Where to find it. */
157- u8 padding[3 ]; /* Pad to full dword. */
159+ u8 id; /* Multiple capabilities of the same type */
160+ u8 padding[2 ]; /* Pad to full dword. */
158161 u32 offset; /* Offset within bar. */
159162 u32 length; /* Length of the structure, in bytes. */
160163};
161164
165+ /* A variant of virtio_pci_cap, for capabilities that require offsets or lengths
166+ * larger than 4GiB */
167+ struct virtio_pci_cap64 {
168+ struct virtio_pci_cap cap;
169+ u32 offset_hi;
170+ u32 length_hi;
171+ };
172+
162173/* The notification location is found using the VIRTIO_PCI_CAP_NOTIFY_CFG capability.
163174 * This capability is immediately followed by an additional field, like so:*/
164175struct virtio_pci_notify_cap {
@@ -198,7 +209,7 @@ struct virtio_pci_common_cfg {
198209class virtio_modern_pci_device : public virtio_pci_device {
199210public:
200211 struct virtio_capability {
201- virtio_capability (u32 cfg_offset, pci::bar* bar, u32 bar_no, u32 bar_offset, u32 length) :
212+ virtio_capability (u32 cfg_offset, pci::bar* bar, u32 bar_no, u64 bar_offset, u64 length) :
202213 _cfg_offset (cfg_offset),
203214 _bar (bar),
204215 _bar_no (bar_no),
@@ -207,27 +218,27 @@ public:
207218 assert (_length > 0 && _bar_offset >= 0 && _bar_offset + _length <= _bar->get_size ());
208219 }
209220
210- u8 virtio_conf_readb (u32 offset) {
221+ u8 virtio_conf_readb (u64 offset) {
211222 verify_offset (offset, sizeof (u8 ));
212223 return _bar->readb (_bar_offset + offset);
213224 };
214- u16 virtio_conf_readw (u32 offset) {
225+ u16 virtio_conf_readw (u64 offset) {
215226 verify_offset (offset, sizeof (u16 ));
216227 return _bar->readw (_bar_offset + offset);
217228 };
218- u32 virtio_conf_readl (u32 offset) {
229+ u32 virtio_conf_readl (u64 offset) {
219230 verify_offset (offset, sizeof (u32 ));
220231 return _bar->readl (_bar_offset + offset);
221232 };
222- void virtio_conf_writeb (u32 offset, u8 val) {
233+ void virtio_conf_writeb (u64 offset, u8 val) {
223234 verify_offset (offset, sizeof (u8 ));
224235 _bar->writeb (_bar_offset + offset, val);
225236 };
226- void virtio_conf_writew (u32 offset, u16 val) {
237+ void virtio_conf_writew (u64 offset, u16 val) {
227238 verify_offset (offset, sizeof (u16 ));
228239 _bar->writew (_bar_offset + offset, val);
229240 };
230- void virtio_conf_writel (u32 offset, u32 val) {
241+ void virtio_conf_writel (u64 offset, u32 val) {
231242 verify_offset (offset, sizeof (u32 ));
232243 _bar->writel (_bar_offset + offset, val);
233244 };
@@ -237,15 +248,15 @@ public:
237248 virtio_d (" %s bar=%d, offset=%x, size=%x" , prefix, _bar_no, _bar_offset, _length);
238249 }
239250 private:
240- inline void verify_offset (u32 offset, u32 size) {
251+ inline void verify_offset (u64 offset, u32 size) {
241252 assert (offset >= 0 && offset + size <= _length);
242253 }
243254
244255 u32 _cfg_offset;
245256 pci::bar* _bar;
246257 u32 _bar_no;
247- u32 _bar_offset;
248- u32 _length;
258+ u64 _bar_offset;
259+ u64 _length;
249260 };
250261
251262 explicit virtio_modern_pci_device (pci::device *dev);
@@ -277,11 +288,13 @@ protected:
277288 virtual bool parse_pci_config ();
278289private:
279290 void parse_virtio_capability (std::unique_ptr<virtio_capability> &ptr, u8 type);
291+ void parse_virtio_capabilities (std::vector<std::unique_ptr<virtio_capability>>& caps, u8 type);
280292
281293 std::unique_ptr<virtio_capability> _common_cfg;
282294 std::unique_ptr<virtio_capability> _isr_cfg;
283295 std::unique_ptr<virtio_capability> _notify_cfg;
284296 std::unique_ptr<virtio_capability> _device_cfg;
297+ std::vector<std::unique_ptr<virtio_capability>> _shm_cfgs;
285298
286299 u32 _notify_offset_multiplier;
287300 u32 _queues_notify_offsets[64 ];
@@ -293,4 +306,4 @@ virtio_device* create_virtio_pci_device(pci::device *dev);
293306
294307}
295308
296- #endif // VIRTIO_PCI_DEVICE_HH
309+ #endif // VIRTIO_PCI_DEVICE_HH
0 commit comments