From 3ecc38cb8b882169fb64bf939f709326915f375e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 00:02:21 -0800 Subject: Devices: Add support for legacy fixed IO locations in BARs. --- src/dev/Pci.py | 6 ++++ src/dev/alpha/tsunami.cc | 14 ++++++++- src/dev/alpha/tsunami.hh | 12 +++++++- src/dev/alpha/tsunami_pchip.cc | 11 +++++++ src/dev/alpha/tsunami_pchip.hh | 2 ++ src/dev/pciconfigall.cc | 2 +- src/dev/pcidev.cc | 69 +++++++++++++++++++++++++----------------- src/dev/pcidev.hh | 3 ++ src/dev/platform.hh | 4 ++- src/dev/sparc/t1000.cc | 16 +++++++++- src/dev/sparc/t1000.hh | 12 +++++++- src/dev/x86/pc.cc | 15 +++++++-- src/dev/x86/pc.hh | 12 +++++++- 13 files changed, 141 insertions(+), 37 deletions(-) diff --git a/src/dev/Pci.py b/src/dev/Pci.py index b50e1b15c..bd67d82fb 100644 --- a/src/dev/Pci.py +++ b/src/dev/Pci.py @@ -73,6 +73,12 @@ class PciDevice(DmaDevice): BAR3Size = Param.MemorySize32('0B', "Base Address Register 3 Size") BAR4Size = Param.MemorySize32('0B', "Base Address Register 4 Size") BAR5Size = Param.MemorySize32('0B', "Base Address Register 5 Size") + BAR0LegacyIO = Param.Bool(False, "Whether BAR0 is hardwired legacy IO") + BAR1LegacyIO = Param.Bool(False, "Whether BAR1 is hardwired legacy IO") + BAR2LegacyIO = Param.Bool(False, "Whether BAR2 is hardwired legacy IO") + BAR3LegacyIO = Param.Bool(False, "Whether BAR3 is hardwired legacy IO") + BAR4LegacyIO = Param.Bool(False, "Whether BAR4 is hardwired legacy IO") + BAR5LegacyIO = Param.Bool(False, "Whether BAR5 is hardwired legacy IO") CardbusCIS = Param.UInt32(0x00, "Cardbus Card Information Structure") SubsystemID = Param.UInt16(0x00, "Subsystem ID") diff --git a/src/dev/alpha/tsunami.cc b/src/dev/alpha/tsunami.cc index 7923fc3f1..b6478fe22 100644 --- a/src/dev/alpha/tsunami.cc +++ b/src/dev/alpha/tsunami.cc @@ -96,11 +96,23 @@ Tsunami::pciToDma(Addr pciAddr) const Addr -Tsunami::calcConfigAddr(int bus, int dev, int func) +Tsunami::calcPciConfigAddr(int bus, int dev, int func) { return pchip->calcConfigAddr(bus, dev, func); } +Addr +Tsunami::calcPciIOAddr(Addr addr) +{ + return pchip->calcIOAddr(addr); +} + +Addr +Tsunami::calcPciMemAddr(Addr addr) +{ + return pchip->calcMemAddr(addr); +} + void Tsunami::serialize(std::ostream &os) { diff --git a/src/dev/alpha/tsunami.hh b/src/dev/alpha/tsunami.hh index 44c5d41a4..64aafe533 100644 --- a/src/dev/alpha/tsunami.hh +++ b/src/dev/alpha/tsunami.hh @@ -116,7 +116,17 @@ class Tsunami : public Platform /** * Calculate the configuration address given a bus/dev/func. */ - virtual Addr calcConfigAddr(int bus, int dev, int func); + virtual Addr calcPciConfigAddr(int bus, int dev, int func); + + /** + * Calculate the address for an IO location on the PCI bus. + */ + virtual Addr calcPciIOAddr(Addr addr); + + /** + * Calculate the address for a memory location on the PCI bus. + */ + virtual Addr calcPciMemAddr(Addr addr); /** * Serialize this object to the given output stream. diff --git a/src/dev/alpha/tsunami_pchip.cc b/src/dev/alpha/tsunami_pchip.cc index 83bcf8e65..4df7d1150 100644 --- a/src/dev/alpha/tsunami_pchip.cc +++ b/src/dev/alpha/tsunami_pchip.cc @@ -300,6 +300,7 @@ TsunamiPChip::translatePciToDma(Addr busAddr) // if no match was found, then return the original address return busAddr; } + Addr TsunamiPChip::calcConfigAddr(int bus, int dev, int func) { @@ -310,7 +311,17 @@ TsunamiPChip::calcConfigAddr(int bus, int dev, int func) return TsunamiPciBus0Config | (func << 8) | (dev << 11); } +Addr +TsunamiPChip::calcIOAddr(Addr addr) +{ + return TSUNAMI_PCI0_IO + addr; +} +Addr +TsunamiPChip::calcMemAddr(Addr addr) +{ + return TSUNAMI_PCI0_MEMORY + addr; +} void TsunamiPChip::serialize(std::ostream &os) diff --git a/src/dev/alpha/tsunami_pchip.hh b/src/dev/alpha/tsunami_pchip.hh index 53050565f..d31a28dbe 100644 --- a/src/dev/alpha/tsunami_pchip.hh +++ b/src/dev/alpha/tsunami_pchip.hh @@ -84,6 +84,8 @@ class TsunamiPChip : public BasicPioDevice Addr translatePciToDma(Addr busAddr); Addr calcConfigAddr(int bus, int dev, int func); + Addr calcIOAddr(Addr addr); + Addr calcMemAddr(Addr addr); virtual Tick read(PacketPtr pkt); virtual Tick write(PacketPtr pkt); diff --git a/src/dev/pciconfigall.cc b/src/dev/pciconfigall.cc index faf033705..74396be5d 100644 --- a/src/dev/pciconfigall.cc +++ b/src/dev/pciconfigall.cc @@ -47,7 +47,7 @@ using namespace std; PciConfigAll::PciConfigAll(const Params *p) : PioDevice(p) { - pioAddr = p->platform->calcConfigAddr(params()->bus,0,0); + pioAddr = p->platform->calcPciConfigAddr(params()->bus,0,0); } 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 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 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; diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh index a584a957d..5da8b2dfc 100644 --- a/src/dev/pcidev.hh +++ b/src/dev/pcidev.hh @@ -99,6 +99,9 @@ class PciDev : public DmaDevice /** The current address mapping of the BARs */ Addr BARAddrs[6]; + /** Whether the BARs are really hardwired legacy IO locations. */ + bool legacyIO[6]; + /** * Does the given address lie within the space mapped by the given * base address register? diff --git a/src/dev/platform.hh b/src/dev/platform.hh index fc556787d..5f6f1df81 100644 --- a/src/dev/platform.hh +++ b/src/dev/platform.hh @@ -69,7 +69,9 @@ class Platform : public SimObject virtual void postPciInt(int line); virtual void clearPciInt(int line); virtual Addr pciToDma(Addr pciAddr) const; - virtual Addr calcConfigAddr(int bus, int dev, int func) = 0; + virtual Addr calcPciConfigAddr(int bus, int dev, int func) = 0; + virtual Addr calcPciIOAddr(Addr addr) = 0; + virtual Addr calcPciMemAddr(Addr addr) = 0; virtual void registerPciDevice(uint8_t bus, uint8_t dev, uint8_t func, uint8_t intr); diff --git a/src/dev/sparc/t1000.cc b/src/dev/sparc/t1000.cc index d42b442a1..88fb358ef 100644 --- a/src/dev/sparc/t1000.cc +++ b/src/dev/sparc/t1000.cc @@ -94,7 +94,21 @@ T1000::pciToDma(Addr pciAddr) const Addr -T1000::calcConfigAddr(int bus, int dev, int func) +T1000::calcPciConfigAddr(int bus, int dev, int func) +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +Addr +T1000::calcPciIOAddr(Addr addr) +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +Addr +T1000::calcPciMemAddr(Addr addr) { panic("Need implementation\n"); M5_DUMMY_RETURN diff --git a/src/dev/sparc/t1000.hh b/src/dev/sparc/t1000.hh index 76de0a550..01ff3d319 100644 --- a/src/dev/sparc/t1000.hh +++ b/src/dev/sparc/t1000.hh @@ -91,7 +91,17 @@ class T1000 : public Platform /** * Calculate the configuration address given a bus/dev/func. */ - virtual Addr calcConfigAddr(int bus, int dev, int func); + virtual Addr calcPciConfigAddr(int bus, int dev, int func); + + /** + * Calculate the address for an IO location on the PCI bus. + */ + virtual Addr calcPciIOAddr(Addr addr); + + /** + * Calculate the address for a memory location on the PCI bus. + */ + virtual Addr calcPciMemAddr(Addr addr); }; #endif // __DEV_T1000_HH__ diff --git a/src/dev/x86/pc.cc b/src/dev/x86/pc.cc index 2deed95d3..3dfa50d7f 100644 --- a/src/dev/x86/pc.cc +++ b/src/dev/x86/pc.cc @@ -143,9 +143,8 @@ Pc::pciToDma(Addr pciAddr) const M5_DUMMY_RETURN } - Addr -Pc::calcConfigAddr(int bus, int dev, int func) +Pc::calcPciConfigAddr(int bus, int dev, int func) { assert(func < 8); assert(dev < 32); @@ -153,6 +152,18 @@ Pc::calcConfigAddr(int bus, int dev, int func) return (PhysAddrPrefixPciConfig | (func << 8) | (dev << 11)); } +Addr +Pc::calcPciIOAddr(Addr addr) +{ + return PhysAddrPrefixIO + addr; +} + +Addr +Pc::calcPciMemAddr(Addr addr) +{ + return addr; +} + Pc * PcParams::create() { diff --git a/src/dev/x86/pc.hh b/src/dev/x86/pc.hh index 21055a566..427cc4165 100644 --- a/src/dev/x86/pc.hh +++ b/src/dev/x86/pc.hh @@ -93,7 +93,17 @@ class Pc : public Platform /** * Calculate the configuration address given a bus/dev/func. */ - virtual Addr calcConfigAddr(int bus, int dev, int func); + virtual Addr calcPciConfigAddr(int bus, int dev, int func); + + /** + * Calculate the address for an IO location on the PCI bus. + */ + virtual Addr calcPciIOAddr(Addr addr); + + /** + * Calculate the address for a memory location on the PCI bus. + */ + virtual Addr calcPciMemAddr(Addr addr); }; #endif // __DEV_PC_HH__ -- cgit v1.2.3