diff options
Diffstat (limited to 'dev')
-rw-r--r-- | dev/pciconfigall.cc | 29 | ||||
-rw-r--r-- | dev/pciconfigall.hh | 7 | ||||
-rw-r--r-- | dev/pcidev.hh | 4 |
3 files changed, 40 insertions, 0 deletions
diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index d5302d9ad..609763e92 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -33,10 +33,12 @@ #include <deque> #include <string> #include <vector> +#include <bitset> #include "base/trace.hh" #include "dev/pciconfigall.hh" #include "dev/pcidev.hh" +#include "dev/pcireg.h" #include "mem/bus/bus.hh" #include "mem/bus/pio_interface.hh" #include "mem/bus/pio_interface_impl.hh" @@ -65,6 +67,33 @@ PciConfigAll::PciConfigAll(const string &name, Addr a, MemoryController *mmu, devices[x][y] = NULL; } +// If two interrupts share the same line largely bad things will happen. +// Since we don't track how many times an interrupt was set and correspondingly +// cleared two devices on the same interrupt line and assert and deassert each +// others interrupt "line". Interrupts will not work correctly. +void +PciConfigAll::startup() +{ + bitset<256> intLines; + PciDev *tempDev; + uint8_t intline; + + for (int x = 0; x < MAX_PCI_DEV; x++) { + for (int y = 0; y < MAX_PCI_FUNC; y++) { + if (devices[x][y] != NULL) { + tempDev = devices[x][y]; + intline = tempDev->interruptLine(); + if (intLines.test(intline)) + warn("Interrupt line %#X is used multiple times" + "(You probably want to fix this).\n", (uint32_t)intline); + else + intLines.set(intline); + } // devices != NULL + } // PCI_FUNC + } // PCI_DEV + +} + Fault PciConfigAll::read(MemReqPtr &req, uint8_t *data) { diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh index d6b37b9b1..9cf2cf972 100644 --- a/dev/pciconfigall.hh +++ b/dev/pciconfigall.hh @@ -116,6 +116,12 @@ class PciConfigAll : public PioDevice virtual Fault write(MemReqPtr &req, const uint8_t *data); /** + * Start up function to check if more than one person is using an interrupt line + * and print a warning if such a case exists + */ + virtual void startup(); + + /** * Serialize this object to the given output stream. * @param os The stream to serialize to. */ @@ -134,6 +140,7 @@ class PciConfigAll : public PioDevice * @return Tick when the request is done */ Tick cacheAccess(MemReqPtr &req); + }; #endif // __PCICONFIGALL_HH__ diff --git a/dev/pcidev.hh b/dev/pcidev.hh index 73d2e3c44..4b947b560 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -141,6 +141,10 @@ class PciDev : public DmaDevice intrClear() { plat->clearPciInt(configData->config.hdr.pci0.interruptLine); } + uint8_t + interruptLine() + { return configData->config.hdr.pci0.interruptLine; } + public: /** * Constructor for PCI Dev. This function copies data from the |