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