diff options
Diffstat (limited to 'src/dev/pcidev.cc')
-rw-r--r-- | src/dev/pcidev.cc | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc index 56b8cd3c8..b311ed8cf 100644 --- a/src/dev/pcidev.cc +++ b/src/dev/pcidev.cc @@ -59,7 +59,7 @@ PciDev::PciConfigPort::PciConfigPort(PciDev *dev, int busid, int devid, : SimpleTimingPort(dev->name() + "-pciconf", dev), device(dev), platform(p), busId(busid), deviceId(devid), functionId(funcid) { - configAddr = platform->calcConfigAddr(busId, deviceId, functionId); + configAddr = platform->calcPciConfigAddr(busId, deviceId, functionId); } @@ -121,15 +121,26 @@ PciDev::PciDev(const Params *p) BARSize[4] = p->BAR4Size; BARSize[5] = p->BAR5Size; + legacyIO[0] = p->BAR0LegacyIO; + legacyIO[1] = p->BAR1LegacyIO; + legacyIO[2] = p->BAR2LegacyIO; + legacyIO[3] = p->BAR3LegacyIO; + legacyIO[4] = p->BAR4LegacyIO; + legacyIO[5] = p->BAR5LegacyIO; + for (int i = 0; i < 6; ++i) { - uint32_t barsize = BARSize[i]; - if (barsize != 0 && !isPowerOf2(barsize)) { - fatal("BAR %d size %d is not a power of 2\n", i, BARSize[i]); + if (legacyIO[i]) { + BARAddrs[i] = platform->calcPciIOAddr(letoh(config.baseAddr[i])); + config.baseAddr[i] = 0; + } else { + BARAddrs[i] = 0; + uint32_t barsize = BARSize[i]; + if (barsize != 0 && !isPowerOf2(barsize)) { + fatal("BAR %d size %d is not a power of 2\n", i, BARSize[i]); + } } } - memset(BARAddrs, 0, sizeof(BARAddrs)); - plat->registerPciDevice(0, p->pci_dev, p->pci_func, letoh(config.interruptLine)); } @@ -268,30 +279,32 @@ PciDev::writeConfig(PacketPtr pkt) { int barnum = BAR_NUMBER(offset); - // convert BAR values to host endianness - uint32_t he_old_bar = letoh(config.baseAddr[barnum]); - uint32_t he_new_bar = letoh(pkt->get<uint32_t>()); - - uint32_t bar_mask = - BAR_IO_SPACE(he_old_bar) ? BAR_IO_MASK : BAR_MEM_MASK; - - // Writing 0xffffffff to a BAR tells the card to set the - // value of the bar to a bitmask indicating the size of - // memory it needs - if (he_new_bar == 0xffffffff) { - he_new_bar = ~(BARSize[barnum] - 1); - } else { - // does it mean something special to write 0 to a BAR? - he_new_bar &= ~bar_mask; - if (he_new_bar) { - Addr space_base = BAR_IO_SPACE(he_old_bar) ? - TSUNAMI_PCI0_IO : TSUNAMI_PCI0_MEMORY; - BARAddrs[barnum] = he_new_bar + space_base; - pioPort->sendStatusChange(Port::RangeChange); + if (!legacyIO[barnum]) { + // convert BAR values to host endianness + uint32_t he_old_bar = letoh(config.baseAddr[barnum]); + uint32_t he_new_bar = letoh(pkt->get<uint32_t>()); + + uint32_t bar_mask = + BAR_IO_SPACE(he_old_bar) ? BAR_IO_MASK : BAR_MEM_MASK; + + // Writing 0xffffffff to a BAR tells the card to set the + // value of the bar to a bitmask indicating the size of + // memory it needs + if (he_new_bar == 0xffffffff) { + he_new_bar = ~(BARSize[barnum] - 1); + } else { + // does it mean something special to write 0 to a BAR? + he_new_bar &= ~bar_mask; + if (he_new_bar) { + BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ? + platform->calcPciIOAddr(he_new_bar) : + platform->calcPciMemAddr(he_new_bar); + pioPort->sendStatusChange(Port::RangeChange); + } } + config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) | + (he_old_bar & bar_mask)); } - config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) | - (he_old_bar & bar_mask)); } break; |