X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fdev%2Fpcidev.hh;h=9994d2a2de645bdbf54f368bd82ec8891af4268a;hb=2a740aa09682c32eb8f1f8880f279c943d8c6ee1;hp=92786427b363d67f0192230be3ada16fdc61dd39;hpb=b36796914af8bfc6729cc8a519e57572460e43e8;p=gem5.git diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh index 92786427b..9994d2a2d 100644 --- a/src/dev/pcidev.hh +++ b/src/dev/pcidev.hh @@ -37,9 +37,13 @@ #ifndef __DEV_PCIDEV_HH__ #define __DEV_PCIDEV_HH__ -#include "dev/io_device.hh" +#include + +#include "dev/dma_device.hh" #include "dev/pcireg.h" #include "dev/platform.hh" +#include "params/PciDevice.hh" +#include "sim/byteswap.hh" #define BAR_IO_MASK 0x3 #define BAR_MEM_MASK 0xF @@ -47,82 +51,45 @@ #define BAR_IO_SPACE(x) ((x) & BAR_IO_SPACE_BIT) #define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2); -class PciConfigAll; /** - * This class encapulates the first 64 bytes of a singles PCI - * devices config space that in configured by the configuration file. - */ -class PciConfigData : public SimObject -{ - public: - /** - * Constructor to initialize the devices config space to 0. - */ - PciConfigData(const std::string &name) - : SimObject(name) - { - memset(config.data, 0, sizeof(config.data)); - memset(BARAddrs, 0, sizeof(BARAddrs)); - memset(BARSize, 0, sizeof(BARSize)); - } - - /** The first 64 bytes */ - PCIConfig config; - - /** The size of the BARs */ - uint32_t BARSize[6]; - - /** The addresses of the BARs */ - Addr BARAddrs[6]; -}; - -/** - * PCI device, base implemnation is only config space. - * Each device is connected to a PCIConfigSpace device - * which returns -1 for everything but the pcidevs that - * register with it. This object registers with the PCIConfig space - * object. + * PCI device, base implementation is only config space. */ class PciDev : public DmaDevice { - public: - struct Params : public ::PioDevice::Params + class PciConfigPort : public SimpleTimingPort { - /** - * A pointer to the configspace all object that calls us when - * a read comes to this particular device/function. - */ - PciConfigAll *configSpace; + protected: + PciDev *device; + + virtual Tick recvAtomic(PacketPtr pkt); - /** - * A pointer to the object that contains the first 64 bytes of - * config space - */ - PciConfigData *configData; + virtual AddrRangeList getAddrRanges() const; - /** The bus number we are on */ - uint32_t busNum; + Platform *platform; - /** The device number we have */ - uint32_t deviceNum; + int busId; + int deviceId; + int functionId; - /** The function number */ - uint32_t functionNum; + Addr configAddr; - /** The latency for pio accesses. */ - Tick pio_delay; + public: + PciConfigPort(PciDev *dev, int busid, int devid, int funcid, + Platform *p); }; public: - const Params *params() const { return (const Params *)_params; } + typedef PciDeviceParams Params; + const Params * + params() const + { + return dynamic_cast(_params); + } protected: - /** The current config space. Unlike the PciConfigData this is - * updated during simulation while continues to reflect what was - * in the config file. - */ + /** The current config space. */ PCIConfig config; /** The size of the BARs */ @@ -131,6 +98,13 @@ 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? + */ bool isBAR(Addr addr, int bar) const { @@ -138,6 +112,10 @@ class PciDev : public DmaDevice return BARAddrs[bar] <= addr && addr < BARAddrs[bar] + BARSize[bar]; } + /** + * Which base address register (if any) maps the given address? + * @return The BAR number (0-5 inclusive), or -1 if none. + */ int getBAR(Addr addr) { @@ -148,75 +126,81 @@ class PciDev : public DmaDevice return -1; } + /** + * Which base address register (if any) maps the given address? + * @param addr The address to check. + * @retval bar The BAR number (0-5 inclusive), + * only valid if return value is true. + * @retval offs The offset from the base address, + * only valid if return value is true. + * @return True iff address maps to a base address register's region. + */ bool - getBAR(Addr paddr, Addr &daddr, int &bar) + getBAR(Addr addr, int &bar, Addr &offs) { - int b = getBAR(paddr); + int b = getBAR(addr); if (b < 0) return false; - daddr = paddr - BARAddrs[b]; + offs = addr - BARAddrs[b]; bar = b; return true; } protected: - Platform *plat; - PciConfigData *configData; + Platform *platform; Tick pioDelay; + Tick configDelay; + PciConfigPort configPort; + + /** + * Write to the PCI config space data that is stored locally. This may be + * overridden by the device but at some point it will eventually call this + * for normal operations that it does not need to override. + * @param pkt packet containing the write the offset into config space + */ + virtual Tick writeConfig(PacketPtr pkt); + + + /** + * Read from the PCI config space data that is stored locally. This may be + * overridden by the device but at some point it will eventually call this + * for normal operations that it does not need to override. + * @param pkt packet containing the write the offset into config space + */ + virtual Tick readConfig(PacketPtr pkt); public: Addr pciToDma(Addr pciAddr) const - { return plat->pciToDma(pciAddr); } + { return platform->pciToDma(pciAddr); } void intrPost() - { plat->postPciInt(configData->config.interruptLine); } + { platform->postPciInt(letoh(config.interruptLine)); } void intrClear() - { plat->clearPciInt(configData->config.interruptLine); } + { platform->clearPciInt(letoh(config.interruptLine)); } uint8_t interruptLine() - { return configData->config.interruptLine; } + { return letoh(config.interruptLine); } - /** return the address ranges that this device responds to. - * @params range_list range list to populate with ranges + /** + * Determine the address ranges that this device responds to. + * + * @return a list of non-overlapping address ranges */ - void addressRanges(AddrRangeList &range_list); + AddrRangeList getAddrRanges() const; /** * Constructor for PCI Dev. This function copies data from the * config file object PCIConfigData and registers the device with * a PciConfigAll object. */ - PciDev(Params *params); - - /** - * Write to the PCI config space data that is stored locally. This may be - * overridden by the device but at some point it will eventually call this - * for normal operations that it does not need to override. - * @param offset the offset into config space - * @param size the size of the write - * @param data the data to write - */ - virtual void writeConfig(int offset, const uint8_t data); - virtual void writeConfig(int offset, const uint16_t data); - virtual void writeConfig(int offset, const uint32_t data); + PciDev(const Params *params); - - /** - * Read from the PCI config space data that is stored locally. This may be - * overridden by the device but at some point it will eventually call this - * for normal operations that it does not need to override. - * @param offset the offset into config space - * @param size the size of the read - * @param data pointer to the location where the read value should be stored - */ - virtual void readConfig(int offset, uint8_t *data); - virtual void readConfig(int offset, uint16_t *data); - virtual void readConfig(int offset, uint32_t *data); + virtual void init(); /** * Serialize this object to the given output stream. @@ -230,5 +214,18 @@ class PciDev : public DmaDevice * @param section The section name of this object */ virtual void unserialize(Checkpoint *cp, const std::string §ion); + + + virtual unsigned int drain(Event *de); + + virtual BaseSlavePort &getSlavePort(const std::string &if_name, + PortID idx = InvalidPortID) + { + if (if_name == "config") { + return configPort; + } + return DmaDevice::getSlavePort(if_name, idx); + } + }; #endif // __DEV_PCIDEV_HH__