1 /*
2  * Copyright (c) 2019 LK Trusty Authors. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #pragma once
25 
26 #include <stdint.h>
27 
28 /* Virtio devices must have the PIC Vendor ID 0x1AF4 */
29 #define VIRTIO_DEVICE_VENDOR_ID 0x1AF4
30 /* Transitional PCI console device has Device ID 0x1003 */
31 #define VIRTIO_PCI_DEVICE_CONSOLE_ID 0x1003
32 
33 /* Virtio structure PCI capabilities: Common configuration */
34 #define VIRTIO_PCI_CAP_COMMON_CFG 0x1
35 /* Virtio structure PCI capabilities: Notifications */
36 #define VIRTIO_PCI_CAP_NOTIFY_CFG 0x2
37 
38 /**
39  * struct virtio_pci_cap - Virtio PCI capability structure
40  * @cap_vndr:   Generic PCI field: PCI_CAP_ID_VNDR
41  * @cap_next:   Generic PCI field: next ptr.
42  * @cap_len:    Generic PCI field: capability length.
43  * @cfg_type:   Identifies the structure.
44  * @bar:        Where to find it.
45  * @padding:    Pad to full dword.
46  * @offset:     Offset within bar.
47  * @length:     Length of the structure, in bytes.
48  */
49 struct virtio_pci_cap {
50     uint8_t cap_vndr;
51     uint8_t cap_next;
52     uint8_t cap_len;
53     uint8_t cfg_type;
54     uint8_t bar;
55     uint8_t padding[3];
56     uint32_t offset;
57     uint32_t length;
58 };
59 
60 /**
61  * struct virtio_pci_common_cfg - Virtio PCI common configuration structure
62  * @host_features_sel:  Selects which half of the feature vector @host_features
63  *                      exposes - 0 for low, 1 for high.
64  * @host_features:      32-bits of which features the host supports.
65  * @guest_features_sel: Selects which half of the feature vector
66  *                      @guest_features is writing to.
67  * @guest_features:     32-bits of which features the guest wants.
68  * @msix_config:        Guest sets the Configuration Vector for MSI-X.
69  * @num_queues:         Host specifies the maximum number of virtqueues
70  *                      supported.
71  * @device_status:      Used to negotiate startup. Write 0 to reset.
72  * @config_generation:  Guest changes this every time the configuration
73  *                      noticeably changes.
74  * @queue_sel:          Which device queue the guest is configuring
75  * @queue_size:         Queue size used by the guest for the selected queue.
76  * @queue_msix_vector:  Guest uses this to specify the queue vector for MSI-X.
77  * @queue_enable:       Guest uses this to selectively prevent the host from
78  *                      executing requests from this virtqueue.
79  *                      1- enabled; 0 - disabled.
80  * @queue_notify_off:   Guest reads this to calculate the offset from start of
81  *                      Notification structure at which this queue is located.
82  * @queue_desc:         Physical address of the Descriptor Table.
83  * @queue_avail:        Physical address of the Available Ring.
84  * @queue_used:         Physical address of the Used Ring.
85  */
86 struct virtio_pci_common_cfg {
87     /* About the whole device. */
88     uint32_t host_features_sel;
89     uint32_t host_features;
90     uint32_t guest_features_sel;
91     uint32_t guest_features;
92     uint16_t msix_config;
93     uint16_t num_queues;
94     uint8_t device_status;
95     uint8_t config_generation;
96 
97     /* About a specific virtqueue. */
98     uint16_t queue_sel;
99     uint16_t queue_size;
100     uint16_t queue_msix_vector;
101     uint16_t queue_enable;
102     uint16_t queue_notify_off;
103     uint64_t queue_desc;
104     uint64_t queue_avail;
105     uint64_t queue_used;
106 };
107 
108 /**
109  *struct virtio_pci_notify_cap - Virtio PCI notification capability structure
110  * @cap:                   Virtio PCI capability.
111  * @notify_off_multiplier: Multiplier for queue_notify_off.
112  *                         notify_off_multiplier is combined with the
113  *                         queue_notify_off to derive the Queue Notify address
114  *                         within a BAR for a virtqueue:
115  *                         cap.offset + queue_notify_off * notify_off_multiplier
116  */
117 struct virtio_pci_notify_cap {
118     struct virtio_pci_cap cap;
119     uint32_t notify_off_multiplier;
120 };
121