ia64/linux-2.6.18-xen.hg

view drivers/pci/rom.c @ 882:8dec4aa9b8b9

PCI pass through: PCIe IO space multiplexing

This is required for more than 16 HVM domain to boot from
PCIe pass through device.

Linux as dom0 exclusively assigns IO space to downstream PCI bridges
and the assignment unit of PCI bridge IO space is 4K. So the only up
to 16 PCIe device can be accessed via IO space within 64K IO ports.
PCI expansion ROM BIOS often uses IO port access to boot from the
device, so on virtualized environment, it means only up to 16 guest
domain can boot from pass-through device.

This patch allows PCIe IO space sharing of pass-through device.
- reassign IO space of PCIe devices specified by
"guestiomuldev=[<segment>:]<bus>:<dev>[,[<segment:><bus>:dev]][,...]"
to be shared.
This is implemented as Linux PCI quirk fixup.

The sharing unit is PCIe switch. Ie IO space of the end point
devices under the same switch will be shared. If there are more than
one switches, two areas of IO space will be used.

- And the driver which arbitrates the accesses to the multiplexed PCIe
IO space. Later qemu-dm will use this.

Limitation:
IO port of IO shared devices can't be accessed from dom0 Linux device
driver. But this wouldn't be a big issue because PCIe specification
discourages the use of IO space and recommends that IO space should be
used only for bootable device with ROM code. OS device driver should
work without IO space access.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 28 09:57:49 2009 +0100 (2009-05-28)
parents 831230e53067
children
line source
1 /*
2 * drivers/pci/rom.c
3 *
4 * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
5 * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
6 *
7 * PCI ROM access routines
8 */
9 #include <linux/kernel.h>
10 #include <linux/pci.h>
11 #include <linux/slab.h>
13 #include "pci.h"
15 /**
16 * pci_enable_rom - enable ROM decoding for a PCI device
17 * @pdev: PCI device to enable
18 *
19 * Enable ROM decoding on @dev. This involves simply turning on the last
20 * bit of the PCI ROM BAR. Note that some cards may share address decoders
21 * between the ROM and other resources, so enabling it may disable access
22 * to MMIO registers or other card memory.
23 */
24 static int pci_enable_rom(struct pci_dev *pdev)
25 {
26 struct resource *res = pdev->resource + PCI_ROM_RESOURCE;
27 struct pci_bus_region region;
28 u32 rom_addr;
30 if (!res->flags)
31 return -1;
33 pcibios_resource_to_bus(pdev, &region, res);
34 pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
35 rom_addr &= ~PCI_ROM_ADDRESS_MASK;
36 rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE;
37 pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
38 return 0;
39 }
41 /**
42 * pci_disable_rom - disable ROM decoding for a PCI device
43 * @pdev: PCI device to disable
44 *
45 * Disable ROM decoding on a PCI device by turning off the last bit in the
46 * ROM BAR.
47 */
48 static void pci_disable_rom(struct pci_dev *pdev)
49 {
50 u32 rom_addr;
51 pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
52 rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
53 pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
54 }
56 /**
57 * pci_map_rom - map a PCI ROM to kernel space
58 * @pdev: pointer to pci device struct
59 * @size: pointer to receive size of pci window over ROM
60 * @return: kernel virtual pointer to image of ROM
61 *
62 * Map a PCI ROM into kernel space. If ROM is boot video ROM,
63 * the shadow BIOS copy will be returned instead of the
64 * actual ROM.
65 */
66 void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
67 {
68 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
69 loff_t start;
70 void __iomem *rom;
71 void __iomem *image;
72 int last_image;
74 /* IORESOURCE_ROM_SHADOW only set on x86 */
75 if (res->flags & IORESOURCE_ROM_SHADOW) {
76 /* primary video rom always starts here */
77 start = (loff_t)0xC0000;
78 *size = 0x20000; /* cover C000:0 through E000:0 */
79 } else {
80 if (res->flags & IORESOURCE_ROM_COPY) {
81 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
82 return (void __iomem *)(unsigned long)
83 pci_resource_start(pdev, PCI_ROM_RESOURCE);
84 } else {
85 /* assign the ROM an address if it doesn't have one */
86 if (res->parent == NULL &&
87 pci_assign_resource(pdev,PCI_ROM_RESOURCE))
88 return NULL;
89 start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
90 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
91 if (*size == 0)
92 return NULL;
94 /* Enable ROM space decodes */
95 if (pci_enable_rom(pdev))
96 return NULL;
97 }
98 }
100 rom = ioremap(start, *size);
101 if (!rom) {
102 /* restore enable if ioremap fails */
103 if (!(res->flags & (IORESOURCE_ROM_ENABLE |
104 IORESOURCE_ROM_SHADOW |
105 IORESOURCE_ROM_COPY)))
106 pci_disable_rom(pdev);
107 return NULL;
108 }
110 /*
111 * Try to find the true size of the ROM since sometimes the PCI window
112 * size is much larger than the actual size of the ROM.
113 * True size is important if the ROM is going to be copied.
114 */
115 image = rom;
116 do {
117 void __iomem *pds;
118 /* Standard PCI ROMs start out with these bytes 55 AA */
119 if (readb(image) != 0x55)
120 break;
121 if (readb(image + 1) != 0xAA)
122 break;
123 /* get the PCI data structure and check its signature */
124 pds = image + readw(image + 24);
125 if (readb(pds) != 'P')
126 break;
127 if (readb(pds + 1) != 'C')
128 break;
129 if (readb(pds + 2) != 'I')
130 break;
131 if (readb(pds + 3) != 'R')
132 break;
133 last_image = readb(pds + 21) & 0x80;
134 /* this length is reliable */
135 image += readw(pds + 16) * 512;
136 } while (!last_image);
138 /* never return a size larger than the PCI resource window */
139 /* there are known ROMs that get the size wrong */
140 *size = min((size_t)(image - rom), *size);
142 return rom;
143 }
145 /**
146 * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
147 * @pdev: pointer to pci device struct
148 * @size: pointer to receive size of pci window over ROM
149 * @return: kernel virtual pointer to image of ROM
150 *
151 * Map a PCI ROM into kernel space. If ROM is boot video ROM,
152 * the shadow BIOS copy will be returned instead of the
153 * actual ROM.
154 */
155 void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
156 {
157 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
158 void __iomem *rom;
160 rom = pci_map_rom(pdev, size);
161 if (!rom)
162 return NULL;
164 if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW))
165 return rom;
167 res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
168 if (!res->start)
169 return rom;
171 res->end = res->start + *size;
172 memcpy_fromio((void*)(unsigned long)res->start, rom, *size);
173 pci_unmap_rom(pdev, rom);
174 res->flags |= IORESOURCE_ROM_COPY;
176 return (void __iomem *)(unsigned long)res->start;
177 }
179 /**
180 * pci_unmap_rom - unmap the ROM from kernel space
181 * @pdev: pointer to pci device struct
182 * @rom: virtual address of the previous mapping
183 *
184 * Remove a mapping of a previously mapped ROM
185 */
186 void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
187 {
188 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
190 if (res->flags & IORESOURCE_ROM_COPY)
191 return;
193 iounmap(rom);
195 /* Disable again before continuing, leave enabled if pci=rom */
196 if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
197 pci_disable_rom(pdev);
198 }
200 /**
201 * pci_remove_rom - disable the ROM and remove its sysfs attribute
202 * @pdev: pointer to pci device struct
203 *
204 * Remove the rom file in sysfs and disable ROM decoding.
205 */
206 void pci_remove_rom(struct pci_dev *pdev)
207 {
208 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
210 if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
211 sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
212 if (!(res->flags & (IORESOURCE_ROM_ENABLE |
213 IORESOURCE_ROM_SHADOW |
214 IORESOURCE_ROM_COPY)))
215 pci_disable_rom(pdev);
216 }
218 /**
219 * pci_cleanup_rom - internal routine for freeing the ROM copy created
220 * by pci_map_rom_copy called from remove.c
221 * @pdev: pointer to pci device struct
222 *
223 * Free the copied ROM if we allocated one.
224 */
225 void pci_cleanup_rom(struct pci_dev *pdev)
226 {
227 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
228 if (res->flags & IORESOURCE_ROM_COPY) {
229 kfree((void*)(unsigned long)res->start);
230 res->flags &= ~IORESOURCE_ROM_COPY;
231 res->start = 0;
232 res->end = 0;
233 }
234 }
236 EXPORT_SYMBOL(pci_map_rom);
237 EXPORT_SYMBOL(pci_map_rom_copy);
238 EXPORT_SYMBOL(pci_unmap_rom);
239 EXPORT_SYMBOL(pci_remove_rom);