Changes in uspace/drv/bus/pci/pciintel/pci.c [c90aed4:46eb2c4] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/pci/pciintel/pci.c
rc90aed4 r46eb2c4 57 57 #include <ops/hw_res.h> 58 58 #include <device/hw_res.h> 59 #include <ops/pio_window.h> 60 #include <device/pio_window.h> 59 61 #include <ddi.h> 60 62 #include <pci_dev_iface.h> … … 141 143 } 142 144 145 static pio_window_t *pciintel_get_pio_window(ddf_fun_t *fnode) 146 { 147 pci_fun_t *fun = pci_fun(fnode); 148 149 if (fun == NULL) 150 return NULL; 151 return &fun->pio_window; 152 } 153 154 143 155 static int pci_config_space_write_32(ddf_fun_t *fun, uint32_t address, 144 156 uint32_t data) … … 198 210 .get_resource_list = &pciintel_get_resources, 199 211 .enable_interrupt = &pciintel_enable_interrupt, 212 }; 213 214 static pio_window_ops_t pciintel_pio_window_ops = { 215 .get_pio_window = &pciintel_get_pio_window 200 216 }; 201 217 … … 211 227 static ddf_dev_ops_t pci_fun_ops = { 212 228 .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops, 229 .interfaces[PIO_WINDOW_DEV_IFACE] = &pciintel_pio_window_ops, 213 230 .interfaces[PCI_DEV_IFACE] = &pci_dev_ops 214 231 }; … … 233 250 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 234 251 { 252 const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 235 253 pci_bus_t *bus = pci_bus_from_fun(fun); 254 uint32_t val; 236 255 237 256 fibril_mutex_lock(&bus->conf_mutex); 238 239 const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 240 void *addr = bus->conf_data_port + (reg & 3); 241 242 pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr)); 243 257 258 pio_write_32(bus->conf_addr_reg, host2uint32_t_le(conf_addr)); 259 260 /* 261 * Always read full 32-bits from the PCI conf_data_port register and 262 * get the desired portion of it afterwards. Some architectures do not 263 * support shorter PIO reads offset from this register. 264 */ 265 val = uint32_t_le2host(pio_read_32(bus->conf_data_reg)); 266 244 267 switch (len) { 245 268 case 1: 246 /* No endianness change for 1 byte */ 247 buf[0] = pio_read_8(addr); 269 *buf = (uint8_t) (val >> ((reg & 3) * 8)); 248 270 break; 249 271 case 2: 250 ((uint16_t *) buf)[0] = uint16_t_le2host(pio_read_16(addr));272 *((uint16_t *) buf) = (uint16_t) (val >> ((reg & 3)) * 8); 251 273 break; 252 274 case 4: 253 ((uint32_t *) buf)[0] = uint32_t_le2host(pio_read_32(addr));275 *((uint32_t *) buf) = (uint32_t) val; 254 276 break; 255 277 } … … 260 282 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 261 283 { 284 const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 262 285 pci_bus_t *bus = pci_bus_from_fun(fun); 286 uint32_t val; 263 287 264 288 fibril_mutex_lock(&bus->conf_mutex); 265 266 const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 267 void *addr = bus->conf_data_port + (reg & 3); 268 269 pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr)); 289 290 /* 291 * Prepare to write full 32-bits to the PCI conf_data_port register. 292 * Some architectures do not support shorter PIO writes offset from this 293 * register. 294 */ 295 296 if (len < 4) { 297 /* 298 * We have fewer than full 32-bits, so we need to read the 299 * missing bits first. 300 */ 301 pio_write_32(bus->conf_addr_reg, host2uint32_t_le(conf_addr)); 302 val = uint32_t_le2host(pio_read_32(bus->conf_data_reg)); 303 } 270 304 271 305 switch (len) { 272 306 case 1: 273 /* No endianness change for 1 byte */274 pio_write_8(addr, buf[0]);307 val &= ~(0xffU << ((reg & 3) * 8)); 308 val |= *buf << ((reg & 3) * 8); 275 309 break; 276 310 case 2: 277 pio_write_16(addr, host2uint16_t_le(((uint16_t *) buf)[0])); 311 val &= ~(0xffffU << ((reg & 3) * 8)); 312 val |= *((uint16_t *) buf) << ((reg & 3) * 8); 278 313 break; 279 314 case 4: 280 pio_write_32(addr, host2uint32_t_le(((uint32_t *) buf)[0]));315 val = *((uint32_t *) buf); 281 316 break; 282 317 } 318 319 pio_write_32(bus->conf_addr_reg, host2uint32_t_le(conf_addr)); 320 pio_write_32(bus->conf_data_reg, host2uint32_t_le(val)); 283 321 284 322 fibril_mutex_unlock(&bus->conf_mutex); … … 411 449 hw_resources[count].res.io_range.address = range_addr; 412 450 hw_resources[count].res.io_range.size = range_size; 451 hw_resources[count].res.io_range.relative = true; 413 452 hw_resources[count].res.io_range.endianness = LITTLE_ENDIAN; 414 453 } else { … … 416 455 hw_resources[count].res.mem_range.address = range_addr; 417 456 hw_resources[count].res.mem_range.size = range_size; 457 hw_resources[count].res.mem_range.relative = false; 418 458 hw_resources[count].res.mem_range.endianness = LITTLE_ENDIAN; 419 459 } … … 433 473 { 434 474 /* Value of the BAR */ 435 uint32_t val, mask; 475 uint32_t val; 476 uint32_t bar; 477 uint32_t mask; 478 436 479 /* IO space address */ 437 480 bool io; … … 471 514 /* Get the address mask. */ 472 515 pci_conf_write_32(fun, addr, 0xffffffff); 473 mask &= pci_conf_read_32(fun, addr); 474 516 bar = pci_conf_read_32(fun, addr); 517 518 /* 519 * Unimplemented BARs read back as all 0's. 520 */ 521 if (!bar) 522 return addr + (addrw64 ? 8 : 4); 523 524 mask &= bar; 525 475 526 /* Restore the original value. */ 476 527 pci_conf_write_32(fun, addr, val); … … 520 571 { 521 572 uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE); 522 if (irq != 0xff) 573 uint8_t pin = pci_conf_read_8(fun, PCI_BRIDGE_INT_PIN); 574 575 if (pin != 0 && irq != 0xff) 523 576 pci_add_interrupt(fun, irq); 524 577 } … … 583 636 pci_read_bars(fun); 584 637 pci_read_interrupt(fun); 638 639 /* Propagate the PIO window to the function. */ 640 fun->pio_window = bus->pio_win; 585 641 586 642 ddf_fun_set_ops(fun->fnode, &pci_fun_ops); … … 613 669 static int pci_dev_add(ddf_dev_t *dnode) 614 670 { 671 hw_resource_list_t hw_resources; 615 672 pci_bus_t *bus = NULL; 616 673 ddf_fun_t *ctl = NULL; … … 638 695 goto fail; 639 696 } 640 641 hw_resource_list_t hw_resources; 697 698 rc = pio_window_get(sess, &bus->pio_win); 699 if (rc != EOK) { 700 ddf_msg(LVL_ERROR, "pci_dev_add failed to get PIO window " 701 "for the device."); 702 goto fail; 703 } 642 704 643 705 rc = hw_res_get_resource_list(sess, &hw_resources); … … 662 724 hw_resources.resources[1].res.io_range.address); 663 725 664 bus->conf_io_addr = 665 (uint32_t) hw_resources.resources[0].res.io_range.address; 666 bus->conf_io_data = 667 (uint32_t) hw_resources.resources[1].res.io_range.address; 668 669 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 4, 670 &bus->conf_addr_port)) { 726 if (pio_enable_resource(&bus->pio_win, &hw_resources.resources[0], 727 (void **) &bus->conf_addr_reg)) { 671 728 ddf_msg(LVL_ERROR, "Failed to enable configuration ports."); 672 729 rc = EADDRNOTAVAIL; 673 730 goto fail; 674 731 } 675 if (pio_enable ((void *)(uintptr_t)bus->conf_io_data, 4,676 &bus->conf_data_port)) {732 if (pio_enable_resource(&bus->pio_win, &hw_resources.resources[1], 733 (void **) &bus->conf_data_reg)) { 677 734 ddf_msg(LVL_ERROR, "Failed to enable configuration ports."); 678 735 rc = EADDRNOTAVAIL; … … 729 786 { 730 787 ddf_log_init(NAME); 731 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;732 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;733 788 } 734 789
Note:
See TracChangeset
for help on using the changeset viewer.