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