X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fdev%2Fpcidev.cc;h=a22612d185f780f79d885f2916aa47b019b03efd;hb=23755eb43428845737aa514314f1bd0ace5d5372;hp=c2a2bc02d841dead62fcb41e48083ddc3e66d0a6;hpb=a3ae9486d543f23cd4203381e7bcf2ce86c51389;p=gem5.git diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc index c2a2bc02d..a22612d18 100644 --- a/src/dev/pcidev.cc +++ b/src/dev/pcidev.cc @@ -39,18 +39,17 @@ #include #include "base/inifile.hh" -#include "base/intmath.hh" // for isPowerOf2( +#include "base/intmath.hh" #include "base/misc.hh" -#include "base/str.hh" // for to_number +#include "base/str.hh" #include "base/trace.hh" +#include "debug/PCIDEV.hh" +#include "dev/alpha/tsunamireg.h" #include "dev/pciconfigall.hh" #include "dev/pcidev.hh" -#include "dev/alpha/tsunamireg.h" #include "mem/packet.hh" #include "mem/packet_access.hh" -#include "sim/builder.hh" #include "sim/byteswap.hh" -#include "sim/param.hh" #include "sim/core.hh" using namespace std; @@ -58,17 +57,16 @@ using namespace std; PciDev::PciConfigPort::PciConfigPort(PciDev *dev, int busid, int devid, int funcid, Platform *p) - : SimpleTimingPort(dev->name() + "-pciconf"), device(dev), platform(p), - busId(busid), deviceId(devid), functionId(funcid) + : 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); } Tick PciDev::PciConfigPort::recvAtomic(PacketPtr pkt) { - assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= configAddr && pkt->getAddr() < configAddr + PCI_CONFIG_SIZE); return pkt->isRead() ? device->readConfig(pkt) : device->writeConfig(pkt); @@ -79,26 +77,74 @@ PciDev::PciConfigPort::getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) { snoop = false;; - resp.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1)); + if (configAddr != ULL(-1)) + resp.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1)); } -PciDev::PciDev(Params *p) - : DmaDevice(p), plat(p->platform), configData(p->configData), - pioDelay(p->pio_delay), configDelay(p->config_delay), - configPort(NULL) +PciDev::PciDev(const Params *p) + : DmaDevice(p), plat(p->platform), pioDelay(p->pio_latency), + configDelay(p->config_latency), configPort(NULL) { - // copy the config data from the PciConfigData object - if (configData) { - memcpy(config.data, configData->config.data, sizeof(config.data)); - memcpy(BARSize, configData->BARSize, sizeof(BARSize)); - } else - panic("NULL pointer to configuration data"); + config.vendor = htole(p->VendorID); + config.device = htole(p->DeviceID); + config.command = htole(p->Command); + config.status = htole(p->Status); + config.revision = htole(p->Revision); + config.progIF = htole(p->ProgIF); + config.subClassCode = htole(p->SubClassCode); + config.classCode = htole(p->ClassCode); + config.cacheLineSize = htole(p->CacheLineSize); + config.latencyTimer = htole(p->LatencyTimer); + config.headerType = htole(p->HeaderType); + config.bist = htole(p->BIST); + + config.baseAddr[0] = htole(p->BAR0); + config.baseAddr[1] = htole(p->BAR1); + config.baseAddr[2] = htole(p->BAR2); + config.baseAddr[3] = htole(p->BAR3); + config.baseAddr[4] = htole(p->BAR4); + config.baseAddr[5] = htole(p->BAR5); + config.cardbusCIS = htole(p->CardbusCIS); + config.subsystemVendorID = htole(p->SubsystemVendorID); + config.subsystemID = htole(p->SubsystemID); + config.expansionROM = htole(p->ExpansionROM); + config.reserved0 = 0; + config.reserved1 = 0; + config.interruptLine = htole(p->InterruptLine); + config.interruptPin = htole(p->InterruptPin); + config.minimumGrant = htole(p->MinimumGrant); + config.maximumLatency = htole(p->MaximumLatency); + + BARSize[0] = p->BAR0Size; + BARSize[1] = p->BAR1Size; + BARSize[2] = p->BAR2Size; + BARSize[3] = p->BAR3Size; + 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; - memset(BARAddrs, 0, sizeof(BARAddrs)); + for (int i = 0; i < 6; ++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]); + } + } + } - plat->registerPciDevice(0, p->deviceNum, p->functionNum, - letoh(configData->config.interruptLine)); + plat->registerPciDevice(0, p->pci_dev, p->pci_func, + letoh(config.interruptLine)); } void @@ -136,27 +182,27 @@ PciDev::readConfig(PacketPtr pkt) pkt->set(config.data[offset]); DPRINTF(PCIDEV, "readConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n", - params()->deviceNum, params()->functionNum, offset, + params()->pci_dev, params()->pci_func, offset, (uint32_t)pkt->get()); break; case sizeof(uint16_t): pkt->set(*(uint16_t*)&config.data[offset]); DPRINTF(PCIDEV, "readConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n", - params()->deviceNum, params()->functionNum, offset, + params()->pci_dev, params()->pci_func, offset, (uint32_t)pkt->get()); break; case sizeof(uint32_t): pkt->set(*(uint32_t*)&config.data[offset]); DPRINTF(PCIDEV, "readConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n", - params()->deviceNum, params()->functionNum, offset, + params()->pci_dev, params()->pci_func, offset, (uint32_t)pkt->get()); break; default: panic("invalid access size(?) for PCI configspace!\n"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return configDelay; } @@ -183,8 +229,10 @@ PciDev::writeConfig(PacketPtr pkt) switch (offset) { case PCI0_INTERRUPT_LINE: config.interruptLine = pkt->get(); + break; case PCI_CACHE_LINE_SIZE: config.cacheLineSize = pkt->get(); + break; case PCI_LATENCY_TIMER: config.latencyTimer = pkt->get(); break; @@ -200,15 +248,17 @@ PciDev::writeConfig(PacketPtr pkt) } DPRINTF(PCIDEV, "writeConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n", - params()->deviceNum, params()->functionNum, offset, + params()->pci_dev, params()->pci_func, offset, (uint32_t)pkt->get()); break; case sizeof(uint16_t): switch (offset) { case PCI_COMMAND: config.command = pkt->get(); + break; case PCI_STATUS: config.status = pkt->get(); + break; case PCI_CACHE_LINE_SIZE: config.cacheLineSize = pkt->get(); break; @@ -217,7 +267,7 @@ PciDev::writeConfig(PacketPtr pkt) } DPRINTF(PCIDEV, "writeConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n", - params()->deviceNum, params()->functionNum, offset, + params()->pci_dev, params()->pci_func, offset, (uint32_t)pkt->get()); break; case sizeof(uint32_t): @@ -231,30 +281,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; @@ -277,15 +329,14 @@ PciDev::writeConfig(PacketPtr pkt) } DPRINTF(PCIDEV, "writeConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n", - params()->deviceNum, params()->functionNum, offset, + params()->pci_dev, params()->pci_func, offset, (uint32_t)pkt->get()); break; default: panic("invalid access size(?) for PCI configspace!\n"); } - pkt->result = Packet::Success; + pkt->makeAtomicResponse(); return configDelay; - } void @@ -307,132 +358,3 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion) } -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigData) - - Param VendorID; - Param DeviceID; - Param Command; - Param Status; - Param Revision; - Param ProgIF; - Param SubClassCode; - Param ClassCode; - Param CacheLineSize; - Param LatencyTimer; - Param HeaderType; - Param BIST; - Param BAR0; - Param BAR1; - Param BAR2; - Param BAR3; - Param BAR4; - Param BAR5; - Param CardbusCIS; - Param SubsystemVendorID; - Param SubsystemID; - Param ExpansionROM; - Param InterruptLine; - Param InterruptPin; - Param MinimumGrant; - Param MaximumLatency; - Param BAR0Size; - Param BAR1Size; - Param BAR2Size; - Param BAR3Size; - Param BAR4Size; - Param BAR5Size; - -END_DECLARE_SIM_OBJECT_PARAMS(PciConfigData) - -BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigData) - - INIT_PARAM(VendorID, "Vendor ID"), - INIT_PARAM(DeviceID, "Device ID"), - INIT_PARAM_DFLT(Command, "Command Register", 0x00), - INIT_PARAM_DFLT(Status, "Status Register", 0x00), - INIT_PARAM_DFLT(Revision, "Device Revision", 0x00), - INIT_PARAM_DFLT(ProgIF, "Programming Interface", 0x00), - INIT_PARAM(SubClassCode, "Sub-Class Code"), - INIT_PARAM(ClassCode, "Class Code"), - INIT_PARAM_DFLT(CacheLineSize, "System Cacheline Size", 0x00), - INIT_PARAM_DFLT(LatencyTimer, "PCI Latency Timer", 0x00), - INIT_PARAM_DFLT(HeaderType, "PCI Header Type", 0x00), - INIT_PARAM_DFLT(BIST, "Built In Self Test", 0x00), - INIT_PARAM_DFLT(BAR0, "Base Address Register 0", 0x00), - INIT_PARAM_DFLT(BAR1, "Base Address Register 1", 0x00), - INIT_PARAM_DFLT(BAR2, "Base Address Register 2", 0x00), - INIT_PARAM_DFLT(BAR3, "Base Address Register 3", 0x00), - INIT_PARAM_DFLT(BAR4, "Base Address Register 4", 0x00), - INIT_PARAM_DFLT(BAR5, "Base Address Register 5", 0x00), - INIT_PARAM_DFLT(CardbusCIS, "Cardbus Card Information Structure", 0x00), - INIT_PARAM_DFLT(SubsystemVendorID, "Subsystem Vendor ID", 0x00), - INIT_PARAM_DFLT(SubsystemID, "Subsystem ID", 0x00), - INIT_PARAM_DFLT(ExpansionROM, "Expansion ROM Base Address Register", 0x00), - INIT_PARAM(InterruptLine, "Interrupt Line Register"), - INIT_PARAM(InterruptPin, "Interrupt Pin Register"), - INIT_PARAM_DFLT(MinimumGrant, "Minimum Grant", 0x00), - INIT_PARAM_DFLT(MaximumLatency, "Maximum Latency", 0x00), - INIT_PARAM_DFLT(BAR0Size, "Base Address Register 0 Size", 0x00), - INIT_PARAM_DFLT(BAR1Size, "Base Address Register 1 Size", 0x00), - INIT_PARAM_DFLT(BAR2Size, "Base Address Register 2 Size", 0x00), - INIT_PARAM_DFLT(BAR3Size, "Base Address Register 3 Size", 0x00), - INIT_PARAM_DFLT(BAR4Size, "Base Address Register 4 Size", 0x00), - INIT_PARAM_DFLT(BAR5Size, "Base Address Register 5 Size", 0x00) - -END_INIT_SIM_OBJECT_PARAMS(PciConfigData) - -CREATE_SIM_OBJECT(PciConfigData) -{ - PciConfigData *data = new PciConfigData(getInstanceName()); - - data->config.vendor = htole(VendorID.returnValue()); - data->config.device = htole(DeviceID.returnValue()); - data->config.command = htole(Command.returnValue()); - data->config.status = htole(Status.returnValue()); - data->config.revision = htole(Revision.returnValue()); - data->config.progIF = htole(ProgIF.returnValue()); - data->config.subClassCode = htole(SubClassCode.returnValue()); - data->config.classCode = htole(ClassCode.returnValue()); - data->config.cacheLineSize = htole(CacheLineSize.returnValue()); - data->config.latencyTimer = htole(LatencyTimer.returnValue()); - data->config.headerType = htole(HeaderType.returnValue()); - data->config.bist = htole(BIST.returnValue()); - - data->config.baseAddr[0] = htole(BAR0.returnValue()); - data->config.baseAddr[1] = htole(BAR1.returnValue()); - data->config.baseAddr[2] = htole(BAR2.returnValue()); - data->config.baseAddr[3] = htole(BAR3.returnValue()); - data->config.baseAddr[4] = htole(BAR4.returnValue()); - data->config.baseAddr[5] = htole(BAR5.returnValue()); - data->config.cardbusCIS = htole(CardbusCIS.returnValue()); - data->config.subsystemVendorID = htole(SubsystemVendorID.returnValue()); - data->config.subsystemID = htole(SubsystemID.returnValue()); - data->config.expansionROM = htole(ExpansionROM.returnValue()); - data->config.interruptLine = htole(InterruptLine.returnValue()); - data->config.interruptPin = htole(InterruptPin.returnValue()); - data->config.minimumGrant = htole(MinimumGrant.returnValue()); - data->config.maximumLatency = htole(MaximumLatency.returnValue()); - - data->BARSize[0] = BAR0Size; - data->BARSize[1] = BAR1Size; - data->BARSize[2] = BAR2Size; - data->BARSize[3] = BAR3Size; - data->BARSize[4] = BAR4Size; - data->BARSize[5] = BAR5Size; - - for (int i = 0; i < 6; ++i) { - uint32_t barsize = data->BARSize[i]; - if (barsize != 0 && !isPowerOf2(barsize)) { - fatal("%s: BAR %d size %d is not a power of 2\n", - getInstanceName(), i, data->BARSize[i]); - } - } - - return data; -} - -REGISTER_SIM_OBJECT("PciConfigData", PciConfigData) - -#endif // DOXYGEN_SHOULD_SKIP_THIS