device.hh revision 2846
16019SN/A/* 26019SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 310346Smitch.hayenga@arm.com * All rights reserved. 47134Sgblack@eecs.umich.edu * 57134Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67134Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77134Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87134Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97134Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107134Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117134Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127134Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137134Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147134Sgblack@eecs.umich.edu * this software without specific prior written permission. 156019SN/A * 166019SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176019SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186019SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196019SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206019SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216019SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226019SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236019SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246019SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256019SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266019SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276019SN/A * 286019SN/A * Authors: Ali Saidi 296019SN/A * Andrew Schultz 306019SN/A * Nathan Binkert 316019SN/A */ 326019SN/A 336019SN/A/* @file 346019SN/A * Interface for devices using PCI configuration 356019SN/A */ 366019SN/A 376019SN/A#ifndef __DEV_PCIDEV_HH__ 386019SN/A#define __DEV_PCIDEV_HH__ 396019SN/A 406019SN/A#include "dev/io_device.hh" 416019SN/A#include "dev/pcireg.h" 426308SN/A#include "dev/platform.hh" 436308SN/A 446309SN/A#define BAR_IO_MASK 0x3 456309SN/A#define BAR_MEM_MASK 0xF 466309SN/A#define BAR_IO_SPACE_BIT 0x1 476309SN/A#define BAR_IO_SPACE(x) ((x) & BAR_IO_SPACE_BIT) 486309SN/A#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2); 497134Sgblack@eecs.umich.edu 508588Sgblack@eecs.umich.edu 516309SN/A/** 526309SN/A * This class encapulates the first 64 bytes of a singles PCI 537296Sgblack@eecs.umich.edu * devices config space that in configured by the configuration file. 548139SMatt.Horsnell@arm.com */ 556309SN/Aclass PciConfigData : public SimObject 566309SN/A{ 576309SN/A public: 5810346Smitch.hayenga@arm.com /** 5910346Smitch.hayenga@arm.com * Constructor to initialize the devices config space to 0. 6010346Smitch.hayenga@arm.com */ 6110346Smitch.hayenga@arm.com PciConfigData(const std::string &name) 6210346Smitch.hayenga@arm.com : SimObject(name) 6310346Smitch.hayenga@arm.com { 6410346Smitch.hayenga@arm.com memset(config.data, 0, sizeof(config.data)); 6510346Smitch.hayenga@arm.com memset(BARAddrs, 0, sizeof(BARAddrs)); 6610346Smitch.hayenga@arm.com memset(BARSize, 0, sizeof(BARSize)); 6710346Smitch.hayenga@arm.com } 6810346Smitch.hayenga@arm.com 6910346Smitch.hayenga@arm.com /** The first 64 bytes */ 708588Sgblack@eecs.umich.edu PCIConfig config; 717174Sgblack@eecs.umich.edu 727639Sgblack@eecs.umich.edu /** The size of the BARs */ 737639Sgblack@eecs.umich.edu uint32_t BARSize[6]; 747644Sali.saidi@arm.com 758139SMatt.Horsnell@arm.com /** The addresses of the BARs */ 767639Sgblack@eecs.umich.edu Addr BARAddrs[6]; 777639Sgblack@eecs.umich.edu}; 787639Sgblack@eecs.umich.edu 798588Sgblack@eecs.umich.edu 807639Sgblack@eecs.umich.edu/** 817639Sgblack@eecs.umich.edu * PCI device, base implemnation is only config space. 827639Sgblack@eecs.umich.edu */ 837644Sali.saidi@arm.comclass PciDev : public DmaDevice 848139SMatt.Horsnell@arm.com{ 857639Sgblack@eecs.umich.edu class PciConfigPort : public PioPort 867639Sgblack@eecs.umich.edu { 877639Sgblack@eecs.umich.edu protected: 887639Sgblack@eecs.umich.edu PciDev *device; 897639Sgblack@eecs.umich.edu 908588Sgblack@eecs.umich.edu virtual bool recvTiming(Packet *pkt); 917639Sgblack@eecs.umich.edu 927639Sgblack@eecs.umich.edu virtual Tick recvAtomic(Packet *pkt); 937639Sgblack@eecs.umich.edu 947644Sali.saidi@arm.com virtual void recvFunctional(Packet *pkt) ; 958139SMatt.Horsnell@arm.com 967639Sgblack@eecs.umich.edu virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop); 977639Sgblack@eecs.umich.edu 987639Sgblack@eecs.umich.edu int busId; 997639Sgblack@eecs.umich.edu int deviceId; 1007174Sgblack@eecs.umich.edu int functionId; 1018148SAli.Saidi@ARM.com 1028303SAli.Saidi@ARM.com Addr configAddr; 1037400SAli.Saidi@ARM.com 1048303SAli.Saidi@ARM.com public: 1058303SAli.Saidi@ARM.com PciConfigPort(PciDev *dev, int busid, int devid, int funcid, 10610037SARM gem5 Developers Platform *p); 10710037SARM gem5 Developers 1088303SAli.Saidi@ARM.com friend class PioPort::SendEvent; 1098303SAli.Saidi@ARM.com }; 1108303SAli.Saidi@ARM.com 1118303SAli.Saidi@ARM.com public: 1128303SAli.Saidi@ARM.com struct Params : public PioDevice::Params 1138303SAli.Saidi@ARM.com { 1148205SAli.Saidi@ARM.com /** 1157858SMatt.Horsnell@arm.com * A pointer to the object that contains the first 64 bytes of 1168285SPrakash.Ramrakhyani@arm.com * config space 1176754SN/A */ 1188148SAli.Saidi@ARM.com PciConfigData *configData; 1196754SN/A 1206754SN/A /** The bus number we are on */ 1218148SAli.Saidi@ARM.com uint32_t busNum; 1228588Sgblack@eecs.umich.edu 1236754SN/A /** The device number we have */ 1248139SMatt.Horsnell@arm.com uint32_t deviceNum; 1257422Sgblack@eecs.umich.edu 1268148SAli.Saidi@ARM.com /** The function number */ 1278148SAli.Saidi@ARM.com uint32_t functionNum; 1286754SN/A 1298588Sgblack@eecs.umich.edu /** The latency for pio accesses. */ 1306309SN/A Tick pio_delay; 1316309SN/A 1327296Sgblack@eecs.umich.edu /** The latency for a config access. */ 1337303Sgblack@eecs.umich.edu Tick config_delay; 1348139SMatt.Horsnell@arm.com }; 1356309SN/A 1366309SN/A public: 1376309SN/A const Params *params() const { return (const Params *)_params; } 1388588Sgblack@eecs.umich.edu 1397174Sgblack@eecs.umich.edu protected: 1407174Sgblack@eecs.umich.edu /** The current config space. Unlike the PciConfigData this is 1417296Sgblack@eecs.umich.edu * updated during simulation while continues to reflect what was 1427303Sgblack@eecs.umich.edu * in the config file. 1437644Sali.saidi@arm.com */ 1448139SMatt.Horsnell@arm.com PCIConfig config; 1457174Sgblack@eecs.umich.edu 1467174Sgblack@eecs.umich.edu /** The size of the BARs */ 1477174Sgblack@eecs.umich.edu uint32_t BARSize[6]; 1488588Sgblack@eecs.umich.edu 1497639Sgblack@eecs.umich.edu /** The current address mapping of the BARs */ 1507639Sgblack@eecs.umich.edu Addr BARAddrs[6]; 1517639Sgblack@eecs.umich.edu 1527639Sgblack@eecs.umich.edu bool 1537644Sali.saidi@arm.com isBAR(Addr addr, int bar) const 1548139SMatt.Horsnell@arm.com { 1557639Sgblack@eecs.umich.edu assert(bar >= 0 && bar < 6); 1567639Sgblack@eecs.umich.edu return BARAddrs[bar] <= addr && addr < BARAddrs[bar] + BARSize[bar]; 1577639Sgblack@eecs.umich.edu } 1587639Sgblack@eecs.umich.edu 1597639Sgblack@eecs.umich.edu int 1608588Sgblack@eecs.umich.edu getBAR(Addr addr) 1617639Sgblack@eecs.umich.edu { 1627639Sgblack@eecs.umich.edu for (int i = 0; i <= 5; ++i) 1637639Sgblack@eecs.umich.edu if (isBAR(addr, i)) 1647639Sgblack@eecs.umich.edu return i; 1657644Sali.saidi@arm.com 1668139SMatt.Horsnell@arm.com return -1; 1677639Sgblack@eecs.umich.edu } 1687639Sgblack@eecs.umich.edu 1697639Sgblack@eecs.umich.edu bool 1707639Sgblack@eecs.umich.edu getBAR(Addr paddr, Addr &daddr, int &bar) 1717639Sgblack@eecs.umich.edu { 1727174Sgblack@eecs.umich.edu int b = getBAR(paddr); 1737174Sgblack@eecs.umich.edu if (b < 0) 17410346Smitch.hayenga@arm.com return false; 17510346Smitch.hayenga@arm.com 1767639Sgblack@eecs.umich.edu daddr = paddr - BARAddrs[b]; 1777639Sgblack@eecs.umich.edu bar = b; 1787174Sgblack@eecs.umich.edu return true; 1797174Sgblack@eecs.umich.edu } 1807174Sgblack@eecs.umich.edu 1817174Sgblack@eecs.umich.edu protected: 1827174Sgblack@eecs.umich.edu Platform *plat; 1837174Sgblack@eecs.umich.edu PciConfigData *configData; 1847174Sgblack@eecs.umich.edu Tick pioDelay; 1857174Sgblack@eecs.umich.edu Tick configDelay; 1867174Sgblack@eecs.umich.edu PciConfigPort *configPort; 1877174Sgblack@eecs.umich.edu 1887174Sgblack@eecs.umich.edu /** 18910346Smitch.hayenga@arm.com * Write to the PCI config space data that is stored locally. This may be 19010346Smitch.hayenga@arm.com * overridden by the device but at some point it will eventually call this 19110346Smitch.hayenga@arm.com * for normal operations that it does not need to override. 19210346Smitch.hayenga@arm.com * @param pkt packet containing the write the offset into config space 19310346Smitch.hayenga@arm.com */ 19410346Smitch.hayenga@arm.com virtual Tick writeConfig(Packet *pkt); 1956309SN/A 1966308SN/A 1977639Sgblack@eecs.umich.edu /** 1987639Sgblack@eecs.umich.edu * Read from the PCI config space data that is stored locally. This may be 1997639Sgblack@eecs.umich.edu * overridden by the device but at some point it will eventually call this 20010037SARM gem5 Developers * for normal operations that it does not need to override. 2017639Sgblack@eecs.umich.edu * @param pkt packet containing the write the offset into config space 2027639Sgblack@eecs.umich.edu */ 2037639Sgblack@eecs.umich.edu virtual Tick readConfig(Packet *pkt); 2047639Sgblack@eecs.umich.edu 2057639Sgblack@eecs.umich.edu public: 2067639Sgblack@eecs.umich.edu Addr pciToDma(Addr pciAddr) const 2077639Sgblack@eecs.umich.edu { return plat->pciToDma(pciAddr); } 2087639Sgblack@eecs.umich.edu 2097639Sgblack@eecs.umich.edu void 2107639Sgblack@eecs.umich.edu intrPost() 2117639Sgblack@eecs.umich.edu { plat->postPciInt(letoh(configData->config.interruptLine)); } 2127639Sgblack@eecs.umich.edu 2137639Sgblack@eecs.umich.edu void 2147639Sgblack@eecs.umich.edu intrClear() 2157639Sgblack@eecs.umich.edu { plat->clearPciInt(letoh(configData->config.interruptLine)); } 2167639Sgblack@eecs.umich.edu 2177639Sgblack@eecs.umich.edu uint8_t 2187639Sgblack@eecs.umich.edu interruptLine() 2197639Sgblack@eecs.umich.edu { return letoh(configData->config.interruptLine); } 2207639Sgblack@eecs.umich.edu 2217639Sgblack@eecs.umich.edu /** return the address ranges that this device responds to. 2227639Sgblack@eecs.umich.edu * @params range_list range list to populate with ranges 2237639Sgblack@eecs.umich.edu */ 2247639Sgblack@eecs.umich.edu void addressRanges(AddrRangeList &range_list); 2257639Sgblack@eecs.umich.edu 2267639Sgblack@eecs.umich.edu /** Do a PCI Configspace memory access. */ 2277639Sgblack@eecs.umich.edu Tick recvConfig(Packet *pkt) 2287639Sgblack@eecs.umich.edu { return pkt->isRead() ? readConfig(pkt) : writeConfig(pkt); } 2297639Sgblack@eecs.umich.edu 2307639Sgblack@eecs.umich.edu /** 2317639Sgblack@eecs.umich.edu * Constructor for PCI Dev. This function copies data from the 2327639Sgblack@eecs.umich.edu * config file object PCIConfigData and registers the device with 2337639Sgblack@eecs.umich.edu * a PciConfigAll object. 2347639Sgblack@eecs.umich.edu */ 2357639Sgblack@eecs.umich.edu PciDev(Params *params); 2368588Sgblack@eecs.umich.edu 2377639Sgblack@eecs.umich.edu virtual void init(); 2387639Sgblack@eecs.umich.edu 2397639Sgblack@eecs.umich.edu /** 2407639Sgblack@eecs.umich.edu * Serialize this object to the given output stream. 2417639Sgblack@eecs.umich.edu * @param os The stream to serialize to. 2427639Sgblack@eecs.umich.edu */ 2438588Sgblack@eecs.umich.edu virtual void serialize(std::ostream &os); 2447639Sgblack@eecs.umich.edu 2457639Sgblack@eecs.umich.edu /** 2467639Sgblack@eecs.umich.edu * Reconstruct the state of this object from a checkpoint. 2477639Sgblack@eecs.umich.edu * @param cp The checkpoint use. 2487639Sgblack@eecs.umich.edu * @param section The section name of this object 2497639Sgblack@eecs.umich.edu */ 2507639Sgblack@eecs.umich.edu virtual void unserialize(Checkpoint *cp, const std::string §ion); 2517639Sgblack@eecs.umich.edu 2527639Sgblack@eecs.umich.edu virtual Port *getPort(const std::string &if_name, int idx = -1) 2537639Sgblack@eecs.umich.edu { 2547639Sgblack@eecs.umich.edu if (if_name == "config") { 2557644Sali.saidi@arm.com if (configPort != NULL) 2567639Sgblack@eecs.umich.edu panic("pciconfig port already connected to."); 2577639Sgblack@eecs.umich.edu configPort = new PciConfigPort(this, params()->busNum, 2587639Sgblack@eecs.umich.edu params()->deviceNum, params()->functionNum, 2597639Sgblack@eecs.umich.edu params()->platform); 2607639Sgblack@eecs.umich.edu return configPort; 2617639Sgblack@eecs.umich.edu } 2627639Sgblack@eecs.umich.edu return DmaDevice::getPort(if_name, idx); 2637639Sgblack@eecs.umich.edu } 2647644Sali.saidi@arm.com 2657639Sgblack@eecs.umich.edu}; 2667639Sgblack@eecs.umich.edu#endif // __DEV_PCIDEV_HH__ 2677639Sgblack@eecs.umich.edu