Devices: Add support for legacy fixed IO locations in BARs.
This commit is contained in:
parent
bb7ad80bbe
commit
3ecc38cb8b
13 changed files with 139 additions and 35 deletions
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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>());
|
||||
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;
|
||||
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);
|
||||
// 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;
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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__
|
||||
|
|
Loading…
Reference in a new issue