GNU Linux-libre 5.10.219-gnu1
[releases.git] / drivers / xen / xen-pciback / conf_space_header.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * PCI Backend - Handles the virtual fields in the configuration space headers.
4  *
5  * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
6  */
7
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9 #define dev_fmt pr_fmt
10
11 #include <linux/kernel.h>
12 #include <linux/pci.h>
13 #include "pciback.h"
14 #include "conf_space.h"
15
16 struct pci_cmd_info {
17         u16 val;
18 };
19
20 struct pci_bar_info {
21         u32 val;
22         u32 len_val;
23         int which;
24 };
25
26 #define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
27 #define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
28
29 /* Bits guests are allowed to control in permissive mode. */
30 #define PCI_COMMAND_GUEST (PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL| \
31                            PCI_COMMAND_INVALIDATE|PCI_COMMAND_VGA_PALETTE| \
32                            PCI_COMMAND_WAIT|PCI_COMMAND_FAST_BACK)
33
34 static void *command_init(struct pci_dev *dev, int offset)
35 {
36         struct pci_cmd_info *cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
37         int err;
38
39         if (!cmd)
40                 return ERR_PTR(-ENOMEM);
41
42         err = pci_read_config_word(dev, PCI_COMMAND, &cmd->val);
43         if (err) {
44                 kfree(cmd);
45                 return ERR_PTR(err);
46         }
47
48         return cmd;
49 }
50
51 static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
52 {
53         int ret = pci_read_config_word(dev, offset, value);
54         const struct pci_cmd_info *cmd = data;
55
56         *value &= PCI_COMMAND_GUEST;
57         *value |= cmd->val & ~PCI_COMMAND_GUEST;
58
59         return ret;
60 }
61
62 static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
63 {
64         struct xen_pcibk_dev_data *dev_data;
65         int err;
66         u16 val;
67         struct pci_cmd_info *cmd = data;
68
69         dev_data = pci_get_drvdata(dev);
70         if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
71                 dev_dbg(&dev->dev, "enable\n");
72                 err = pci_enable_device(dev);
73                 if (err)
74                         return err;
75                 if (dev_data)
76                         dev_data->enable_intx = 1;
77         } else if (pci_is_enabled(dev) && !is_enable_cmd(value)) {
78                 dev_dbg(&dev->dev, "disable\n");
79                 pci_disable_device(dev);
80                 if (dev_data)
81                         dev_data->enable_intx = 0;
82         }
83
84         if (!dev->is_busmaster && is_master_cmd(value)) {
85                 dev_dbg(&dev->dev, "set bus master\n");
86                 pci_set_master(dev);
87         } else if (dev->is_busmaster && !is_master_cmd(value)) {
88                 dev_dbg(&dev->dev, "clear bus master\n");
89                 pci_clear_master(dev);
90         }
91
92         if (!(cmd->val & PCI_COMMAND_INVALIDATE) &&
93             (value & PCI_COMMAND_INVALIDATE)) {
94                 dev_dbg(&dev->dev, "enable memory-write-invalidate\n");
95                 err = pci_set_mwi(dev);
96                 if (err) {
97                         dev_warn(&dev->dev, "cannot enable memory-write-invalidate (%d)\n",
98                                 err);
99                         value &= ~PCI_COMMAND_INVALIDATE;
100                 }
101         } else if ((cmd->val & PCI_COMMAND_INVALIDATE) &&
102                    !(value & PCI_COMMAND_INVALIDATE)) {
103                 dev_dbg(&dev->dev, "disable memory-write-invalidate\n");
104                 pci_clear_mwi(dev);
105         }
106
107         if (dev_data && dev_data->allow_interrupt_control &&
108             ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE))
109                 pci_intx(dev, !(value & PCI_COMMAND_INTX_DISABLE));
110
111         cmd->val = value;
112
113         if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive))
114                 return 0;
115
116         /* Only allow the guest to control certain bits. */
117         err = pci_read_config_word(dev, offset, &val);
118         if (err || val == value)
119                 return err;
120
121         value &= PCI_COMMAND_GUEST;
122         value |= val & ~PCI_COMMAND_GUEST;
123
124         return pci_write_config_word(dev, offset, value);
125 }
126
127 static int rom_write(struct pci_dev *dev, int offset, u32 value, void *data)
128 {
129         struct pci_bar_info *bar = data;
130
131         if (unlikely(!bar)) {
132                 dev_warn(&dev->dev, "driver data not found\n");
133                 return XEN_PCI_ERR_op_failed;
134         }
135
136         /* A write to obtain the length must happen as a 32-bit write.
137          * This does not (yet) support writing individual bytes
138          */
139         if ((value | ~PCI_ROM_ADDRESS_MASK) == ~0U)
140                 bar->which = 1;
141         else {
142                 u32 tmpval;
143                 pci_read_config_dword(dev, offset, &tmpval);
144                 if (tmpval != bar->val && value == bar->val) {
145                         /* Allow restoration of bar value. */
146                         pci_write_config_dword(dev, offset, bar->val);
147                 }
148                 bar->which = 0;
149         }
150
151         /* Do we need to support enabling/disabling the rom address here? */
152
153         return 0;
154 }
155
156 /* For the BARs, only allow writes which write ~0 or
157  * the correct resource information
158  * (Needed for when the driver probes the resource usage)
159  */
160 static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data)
161 {
162         struct pci_bar_info *bar = data;
163         unsigned int pos = (offset - PCI_BASE_ADDRESS_0) / 4;
164         const struct resource *res = dev->resource;
165         u32 mask;
166
167         if (unlikely(!bar)) {
168                 dev_warn(&dev->dev, "driver data not found\n");
169                 return XEN_PCI_ERR_op_failed;
170         }
171
172         /* A write to obtain the length must happen as a 32-bit write.
173          * This does not (yet) support writing individual bytes
174          */
175         if (res[pos].flags & IORESOURCE_IO)
176                 mask = ~PCI_BASE_ADDRESS_IO_MASK;
177         else if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64))
178                 mask = 0;
179         else
180                 mask = ~PCI_BASE_ADDRESS_MEM_MASK;
181         if ((value | mask) == ~0U)
182                 bar->which = 1;
183         else {
184                 u32 tmpval;
185                 pci_read_config_dword(dev, offset, &tmpval);
186                 if (tmpval != bar->val && value == bar->val) {
187                         /* Allow restoration of bar value. */
188                         pci_write_config_dword(dev, offset, bar->val);
189                 }
190                 bar->which = 0;
191         }
192
193         return 0;
194 }
195
196 static int bar_read(struct pci_dev *dev, int offset, u32 * value, void *data)
197 {
198         struct pci_bar_info *bar = data;
199
200         if (unlikely(!bar)) {
201                 dev_warn(&dev->dev, "driver data not found\n");
202                 return XEN_PCI_ERR_op_failed;
203         }
204
205         *value = bar->which ? bar->len_val : bar->val;
206
207         return 0;
208 }
209
210 static void *bar_init(struct pci_dev *dev, int offset)
211 {
212         unsigned int pos;
213         const struct resource *res = dev->resource;
214         struct pci_bar_info *bar = kzalloc(sizeof(*bar), GFP_KERNEL);
215
216         if (!bar)
217                 return ERR_PTR(-ENOMEM);
218
219         if (offset == PCI_ROM_ADDRESS || offset == PCI_ROM_ADDRESS1)
220                 pos = PCI_ROM_RESOURCE;
221         else {
222                 pos = (offset - PCI_BASE_ADDRESS_0) / 4;
223                 if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64)) {
224                         bar->val = res[pos - 1].start >> 32;
225                         bar->len_val = -resource_size(&res[pos - 1]) >> 32;
226                         return bar;
227                 }
228         }
229
230         if (!res[pos].flags ||
231             (res[pos].flags & (IORESOURCE_DISABLED | IORESOURCE_UNSET |
232                                IORESOURCE_BUSY)))
233                 return bar;
234
235         bar->val = res[pos].start |
236                    (res[pos].flags & PCI_REGION_FLAG_MASK);
237         bar->len_val = -resource_size(&res[pos]) |
238                        (res[pos].flags & PCI_REGION_FLAG_MASK);
239
240         return bar;
241 }
242
243 static void bar_reset(struct pci_dev *dev, int offset, void *data)
244 {
245         struct pci_bar_info *bar = data;
246
247         bar->which = 0;
248 }
249
250 static void bar_release(struct pci_dev *dev, int offset, void *data)
251 {
252         kfree(data);
253 }
254
255 static int xen_pcibk_read_vendor(struct pci_dev *dev, int offset,
256                                u16 *value, void *data)
257 {
258         *value = dev->vendor;
259
260         return 0;
261 }
262
263 static int xen_pcibk_read_device(struct pci_dev *dev, int offset,
264                                u16 *value, void *data)
265 {
266         *value = dev->device;
267
268         return 0;
269 }
270
271 static int interrupt_read(struct pci_dev *dev, int offset, u8 * value,
272                           void *data)
273 {
274         *value = (u8) dev->irq;
275
276         return 0;
277 }
278
279 static int bist_write(struct pci_dev *dev, int offset, u8 value, void *data)
280 {
281         u8 cur_value;
282         int err;
283
284         err = pci_read_config_byte(dev, offset, &cur_value);
285         if (err)
286                 goto out;
287
288         if ((cur_value & ~PCI_BIST_START) == (value & ~PCI_BIST_START)
289             || value == PCI_BIST_START)
290                 err = pci_write_config_byte(dev, offset, value);
291
292 out:
293         return err;
294 }
295
296 static const struct config_field header_common[] = {
297         {
298          .offset    = PCI_VENDOR_ID,
299          .size      = 2,
300          .u.w.read  = xen_pcibk_read_vendor,
301         },
302         {
303          .offset    = PCI_DEVICE_ID,
304          .size      = 2,
305          .u.w.read  = xen_pcibk_read_device,
306         },
307         {
308          .offset    = PCI_COMMAND,
309          .size      = 2,
310          .init      = command_init,
311          .release   = bar_release,
312          .u.w.read  = command_read,
313          .u.w.write = command_write,
314         },
315         {
316          .offset    = PCI_INTERRUPT_LINE,
317          .size      = 1,
318          .u.b.read  = interrupt_read,
319         },
320         {
321          .offset    = PCI_INTERRUPT_PIN,
322          .size      = 1,
323          .u.b.read  = xen_pcibk_read_config_byte,
324         },
325         {
326          /* Any side effects of letting driver domain control cache line? */
327          .offset    = PCI_CACHE_LINE_SIZE,
328          .size      = 1,
329          .u.b.read  = xen_pcibk_read_config_byte,
330          .u.b.write = xen_pcibk_write_config_byte,
331         },
332         {
333          .offset    = PCI_LATENCY_TIMER,
334          .size      = 1,
335          .u.b.read  = xen_pcibk_read_config_byte,
336         },
337         {
338          .offset    = PCI_BIST,
339          .size      = 1,
340          .u.b.read  = xen_pcibk_read_config_byte,
341          .u.b.write = bist_write,
342         },
343         {}
344 };
345
346 #define CFG_FIELD_BAR(reg_offset)                       \
347         {                                               \
348         .offset     = reg_offset,                       \
349         .size       = 4,                                \
350         .init       = bar_init,                         \
351         .reset      = bar_reset,                        \
352         .release    = bar_release,                      \
353         .u.dw.read  = bar_read,                         \
354         .u.dw.write = bar_write,                        \
355         }
356
357 #define CFG_FIELD_ROM(reg_offset)                       \
358         {                                               \
359         .offset     = reg_offset,                       \
360         .size       = 4,                                \
361         .init       = bar_init,                         \
362         .reset      = bar_reset,                        \
363         .release    = bar_release,                      \
364         .u.dw.read  = bar_read,                         \
365         .u.dw.write = rom_write,                        \
366         }
367
368 static const struct config_field header_0[] = {
369         CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
370         CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
371         CFG_FIELD_BAR(PCI_BASE_ADDRESS_2),
372         CFG_FIELD_BAR(PCI_BASE_ADDRESS_3),
373         CFG_FIELD_BAR(PCI_BASE_ADDRESS_4),
374         CFG_FIELD_BAR(PCI_BASE_ADDRESS_5),
375         CFG_FIELD_ROM(PCI_ROM_ADDRESS),
376         {}
377 };
378
379 static const struct config_field header_1[] = {
380         CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
381         CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
382         CFG_FIELD_ROM(PCI_ROM_ADDRESS1),
383         {}
384 };
385
386 int xen_pcibk_config_header_add_fields(struct pci_dev *dev)
387 {
388         int err;
389
390         err = xen_pcibk_config_add_fields(dev, header_common);
391         if (err)
392                 goto out;
393
394         switch (dev->hdr_type) {
395         case PCI_HEADER_TYPE_NORMAL:
396                 err = xen_pcibk_config_add_fields(dev, header_0);
397                 break;
398
399         case PCI_HEADER_TYPE_BRIDGE:
400                 err = xen_pcibk_config_add_fields(dev, header_1);
401                 break;
402
403         default:
404                 err = -EINVAL;
405                 dev_err(&dev->dev, "Unsupported header type %d!\n",
406                         dev->hdr_type);
407                 break;
408         }
409
410 out:
411         return err;
412 }