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