summaryrefslogtreecommitdiff
path: root/src/dev/pcidev.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-02-01 00:02:21 -0800
committerGabe Black <gblack@eecs.umich.edu>2009-02-01 00:02:21 -0800
commit3ecc38cb8b882169fb64bf939f709326915f375e (patch)
tree08f8a5952311d17f15445f9e24b9f9c57fb054a3 /src/dev/pcidev.cc
parentbb7ad80bbe565800b09c38bdc02c12f827ec9240 (diff)
downloadgem5-3ecc38cb8b882169fb64bf939f709326915f375e.tar.xz
Devices: Add support for legacy fixed IO locations in BARs.
Diffstat (limited to 'src/dev/pcidev.cc')
-rw-r--r--src/dev/pcidev.cc69
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;