X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fdev%2Fpcidev.hh;h=5da8b2dfcdbfa4c51a4692401ef87cbf76476e32;hb=da3c3bfa98e7cf81010a476b0b6ceba4c936f417;hp=20ab9364a8879cd31c213a2b55e61cc5952a9602;hpb=93839380e7dc4799d234843d10329c03d38487fa;p=gem5.git diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh index 20ab9364a..5da8b2dfc 100644 --- a/src/dev/pcidev.hh +++ b/src/dev/pcidev.hh @@ -37,9 +37,13 @@ #ifndef __DEV_PCIDEV_HH__ #define __DEV_PCIDEV_HH__ +#include + #include "dev/io_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 @@ -48,52 +52,23 @@ #define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2); -/** - * 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. + * PCI device, base implementation is only config space. */ class PciDev : public DmaDevice { - class PciConfigPort : public PioPort + class PciConfigPort : public SimpleTimingPort { protected: PciDev *device; - virtual bool recvTiming(Packet *pkt); + virtual Tick recvAtomic(PacketPtr pkt); - virtual Tick recvAtomic(Packet *pkt); + virtual void getDeviceAddressRanges(AddrRangeList &resp, + bool &snoop); - virtual void recvFunctional(Packet *pkt) ; - - virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop); + Platform *platform; int busId; int deviceId; @@ -103,44 +78,19 @@ class PciDev : public DmaDevice public: PciConfigPort(PciDev *dev, int busid, int devid, int funcid, - Platform *p); - - friend class PioPort::SendEvent; + Platform *p); }; public: - struct Params : public PioDevice::Params + typedef PciDeviceParams Params; + const Params * + params() const { - /** - * A pointer to the object that contains the first 64 bytes of - * config space - */ - PciConfigData *configData; - - /** The bus number we are on */ - uint32_t busNum; - - /** The device number we have */ - uint32_t deviceNum; - - /** The function number */ - uint32_t functionNum; - - /** The latency for pio accesses. */ - Tick pio_delay; - - /** The latency for a config access. */ - Tick config_delay; - }; - - public: - const Params *params() const { return (const Params *)_params; } + 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 */ @@ -149,6 +99,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 { @@ -156,6 +113,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) { @@ -166,21 +127,29 @@ 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; Tick pioDelay; Tick configDelay; PciConfigPort *configPort; @@ -191,7 +160,7 @@ class PciDev : public DmaDevice * for normal operations that it does not need to override. * @param pkt packet containing the write the offset into config space */ - virtual Tick writeConfig(Packet *pkt); + virtual Tick writeConfig(PacketPtr pkt); /** @@ -200,7 +169,7 @@ class PciDev : public DmaDevice * for normal operations that it does not need to override. * @param pkt packet containing the write the offset into config space */ - virtual Tick readConfig(Packet *pkt); + virtual Tick readConfig(PacketPtr pkt); public: Addr pciToDma(Addr pciAddr) const @@ -208,31 +177,27 @@ class PciDev : public DmaDevice void intrPost() - { plat->postPciInt(letoh(configData->config.interruptLine)); } + { plat->postPciInt(letoh(config.interruptLine)); } void intrClear() - { plat->clearPciInt(letoh(configData->config.interruptLine)); } + { plat->clearPciInt(letoh(config.interruptLine)); } uint8_t interruptLine() - { return letoh(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 */ void addressRanges(AddrRangeList &range_list); - /** Do a PCI Configspace memory access. */ - Tick recvConfig(Packet *pkt) - { return pkt->isRead() ? readConfig(pkt) : writeConfig(pkt); } - /** * 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); + PciDev(const Params *params); virtual void init(); @@ -249,13 +214,16 @@ class PciDev : public DmaDevice */ virtual void unserialize(Checkpoint *cp, const std::string §ion); + + virtual unsigned int drain(Event *de); + virtual Port *getPort(const std::string &if_name, int idx = -1) { if (if_name == "config") { if (configPort != NULL) panic("pciconfig port already connected to."); - configPort = new PciConfigPort(this, params()->busNum, - params()->deviceNum, params()->functionNum, + configPort = new PciConfigPort(this, params()->pci_bus, + params()->pci_dev, params()->pci_func, params()->platform); return configPort; }