]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/include/jailhouse/pci.h
62fe8ef92cb800a0691ce9561a146ee1e9ed88fc
[jailhouse.git] / hypervisor / include / jailhouse / pci.h
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) Siemens AG, 2014
5  *
6  * Authors:
7  *  Ivan Kolchin <ivan.kolchin@siemens.com>
8  *  Jan Kiszka <jan.kiszka@siemens.com>
9  *
10  * This work is licensed under the terms of the GNU GPL, version 2.  See
11  * the COPYING file in the top-level directory.
12  */
13
14 #ifndef _JAILHOUSE_PCI_H
15 #define _JAILHOUSE_PCI_H
16
17 #include <asm/cell.h>
18
19 #define PCI_CFG_COMMAND         0x04
20 # define PCI_CMD_MEM            (1 << 1)
21 # define PCI_CMD_MASTER         (1 << 2)
22 # define PCI_CMD_INTX_OFF       (1 << 10)
23 #define PCI_CFG_STATUS          0x06
24 # define PCI_STS_CAPS           (1 << 4)
25 #define PCI_CFG_BAR             0x10
26 # define PCI_BAR_64BIT          0x4
27 #define PCI_CFG_BAR_END         0x27
28 #define PCI_CFG_ROMBAR          0x30
29 #define PCI_CFG_CAPS            0x34
30 #define PCI_CFG_INT             0x3c
31
32 #define PCI_CONFIG_HEADER_SIZE  0x40
33
34 #define PCI_NUM_BARS            6
35
36 #define PCI_DEV_CLASS_MEM       0x05
37
38 #define PCI_CAP_MSI             0x05
39 #define PCI_CAP_MSIX            0x11
40
41 /**
42  * @defgroup PCI PCI Subsystem
43  *
44  * The PCI subsystem provides access to PCI resources for the hypervisor and
45  * manages the cell's access to device configuration spaces and MSI-X tables.
46  * The subsystem depends on IOMMU services to configure DMA and interrupt
47  * mappings.
48  *
49  * @{
50  */
51
52 /** Extract PCI bus from BDF form. */
53 #define PCI_BUS(bdf)            ((bdf) >> 8)
54 /** Extract PCI device/function from BDF form. */
55 #define PCI_DEVFN(bdf)          ((bdf) & 0xff)
56 /** Extract PCI bus, device and function as parameter list from BDF form. */
57 #define PCI_BDF_PARAMS(bdf)     (bdf) >> 8, ((bdf) >> 3) & 0x1f, (bdf) & 7
58
59 /** MSI-X vectors supported per device without extra allocation. */
60 #define PCI_EMBEDDED_MSIX_VECTS 16
61
62 /**
63  * Access moderation return codes.
64  * See pci_cfg_read_moderate() and pci_cfg_write_moderate().
65  */
66 enum pci_access { PCI_ACCESS_REJECT, PCI_ACCESS_PERFORM, PCI_ACCESS_DONE };
67
68 /** MSI config space registers. See PCI specification. */
69 union pci_msi_registers {
70         /** @privatesection */
71         struct {
72                 u16 padding;
73                 u16 enable:1,
74                     ignore1:3,
75                     mme:3,
76                     ignore2:9;
77                 u32 address;
78                 u16 data;
79         } __attribute__((packed)) msg32;
80         struct {
81                 u32 padding; /* use msg32 */
82                 u64 address;
83                 u16 data;
84         } __attribute__((packed)) msg64;
85         u32 raw[4];
86         /** @publicsection */
87 } __attribute__((packed));
88
89 /** MSI-X config space registers. See PCI specification. */
90 union pci_msix_registers {
91         /** @privatesection */
92         struct {
93                 u16 padding;
94                 u16 ignore:14,
95                     fmask:1,
96                     enable:1;
97         } __attribute__((packed));
98         u32 raw;
99         /** @publicsection */
100 } __attribute__((packed));
101
102 /** MSI-X table entry. See PCI specification. */
103 union pci_msix_vector {
104         /** @privatesection */
105         struct {
106                 u64 address;
107                 u32 data;
108                 u32 masked:1;
109                 u32 reserved:31;
110         } __attribute__((packed));
111         u32 raw[4];
112         /** @publicsection */
113 } __attribute__((packed));
114
115 struct pci_ivshmem_endpoint;
116
117 /**
118  * PCI device state.
119  */
120 struct pci_device {
121         /** Reference to static device configuration. */
122         const struct jailhouse_pci_device *info;
123         /** Owning cell. */
124         struct cell *cell;
125         /** Shadow BAR */
126         u32 bar[PCI_NUM_BARS];
127
128         /** Shadow state of MSI config space registers. */
129         union pci_msi_registers msi_registers;
130
131         /** Shadow state of MSI-X config space registers. */
132         union pci_msix_registers msix_registers;
133         /** Next PCI device in this cell with MSI-X support. */
134         struct pci_device *next_msix_device;
135         /** Next virtual PCI device in this cell. */
136         struct pci_device *next_virtual_device;
137         /** ivshmem specific data. */
138         struct pci_ivshmem_endpoint *ivshmem_endpoint;
139         /** Real MSI-X table. */
140         union pci_msix_vector *msix_table;
141         /** Shadow state of MSI-X table. */
142         union pci_msix_vector *msix_vectors;
143         /** Buffer for shadow table of up to PCI_EMBEDDED_MSIX_VECTS vectors. */
144         union pci_msix_vector msix_vector_array[PCI_EMBEDDED_MSIX_VECTS];
145 };
146
147 int pci_init(void);
148
149 u32 pci_read_config(u16 bdf, u16 address, unsigned int size);
150 void pci_write_config(u16 bdf, u16 address, u32 value, unsigned int size);
151
152 struct pci_device *pci_get_assigned_device(const struct cell *cell, u16 bdf);
153
154 enum pci_access pci_cfg_read_moderate(struct pci_device *device, u16 address,
155                                       unsigned int size, u32 *value);
156 enum pci_access pci_cfg_write_moderate(struct pci_device *device, u16 address,
157                                        unsigned int size, u32 value);
158
159 int pci_mmio_access_handler(const struct cell *cell, bool is_write, u64 addr,
160                             u32 *value);
161
162 int pci_cell_init(struct cell *cell);
163 void pci_cell_exit(struct cell *cell);
164
165 void pci_config_commit(struct cell *cell_added_removed);
166
167 unsigned int pci_enabled_msi_vectors(struct pci_device *device);
168
169 void pci_prepare_handover(void);
170 void pci_shutdown(void);
171
172 /**
173  * Read from PCI config space via architecture-specific method.
174  * @param bdf           16-bit bus/device/function ID of target.
175  * @param address       Config space access address.
176  * @param size          Access size (1, 2 or 4 bytes).
177  *
178  * @return Read value.
179  *
180  * @see pci_read_config
181  * @see arch_pci_write_config
182  */
183 u32 arch_pci_read_config(u16 bdf, u16 address, unsigned int size);
184
185 /**
186  * Write to PCI config space via architecture-specific method.
187  * @param bdf           16-bit bus/device/function ID of target.
188  * @param address       Config space access address.
189  * @param value         Value to be written.
190  * @param size          Access size (1, 2 or 4 bytes).
191  *
192  * @see pci_write_config
193  * @see arch_pci_read_config
194  */
195 void arch_pci_write_config(u16 bdf, u16 address, u32 value, unsigned int size);
196
197 /**
198  * Perform architecture-specific steps on physical PCI device addition.
199  * @param cell          Cell to which the device is added.
200  * @param device        Device to be added.
201  *
202  * @return 0 on success, negative error code otherwise.
203  *
204  * @see arch_pci_remove_physical_device
205  */
206 int arch_pci_add_physical_device(struct cell *cell, struct pci_device *device);
207
208 /**
209  * Perform architecture-specific steps on physical PCI device removal.
210  * @param device        Device to be removed.
211  *
212  * @see arch_pci_add_physical_device
213  */
214 void arch_pci_remove_physical_device(struct pci_device *device);
215
216 /**
217  * Avoid MSI vector delivery of a given device.
218  * @param device        Device to be silenced.
219  * @param cap           MSI capability of the device.
220  */
221 void arch_pci_suppress_msi(struct pci_device *device,
222                            const struct jailhouse_pci_capability *cap);
223
224 /**
225  * Update MSI vector mapping for a given device.
226  * @param device        Device to be updated.
227  * @param cap           MSI capability of the device.
228  *
229  * @return 0 on success, negative error code otherwise.
230  *
231  * @see arch_pci_update_msix_vector
232  */
233 int arch_pci_update_msi(struct pci_device *device,
234                         const struct jailhouse_pci_capability *cap);
235
236 /**
237  * Update MSI-X vector mapping for a given device and vector.
238  * @param device        Device to be updated.
239  * @param index         MSI-X vector number.
240  *
241  * @return 0 on success, negative error code otherwise.
242  *
243  * @see arch_pci_update_msi
244  */
245 int arch_pci_update_msix_vector(struct pci_device *device, unsigned int index);
246
247 /**
248  * @defgroup PCI-IVSHMEM ivshmem
249  * @{
250  */
251 int pci_ivshmem_init(struct cell *cell, struct pci_device *device);
252 void pci_ivshmem_exit(struct pci_device *device);
253 int pci_ivshmem_update_msix(struct pci_device *device);
254 enum pci_access pci_ivshmem_cfg_write(struct pci_device *device,
255                                       unsigned int row, u32 mask, u32 value);
256 enum pci_access pci_ivshmem_cfg_read(struct pci_device *device, u16 address,
257                                      u32 *value);
258 int ivshmem_mmio_access_handler(const struct cell *cell, bool is_write,
259                                 u64 addr, u32 *value);
260 /** @} PCI-IVSHMEM */
261 /** @} PCI */
262 #endif /* !_JAILHOUSE_PCI_H */