1793SN/A/*
29957SN/A * Copyright (c) 2013 ARM Limited
39957SN/A * All rights reserved
49957SN/A *
59957SN/A * The license below extends only to copyright in the software and shall
69957SN/A * not be construed as granting a license to any other intellectual
79957SN/A * property including but not limited to intellectual property relating
89957SN/A * to a hardware implementation of the functionality of the software
99957SN/A * licensed hereunder.  You may use the software subject to the license
109957SN/A * terms below provided that you ensure that this notice is replicated
119957SN/A * unmodified and in its entirety in all distributions of the software,
129957SN/A * modified or unmodified, in source code or in binary form.
139957SN/A *
141762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
15793SN/A * All rights reserved.
16793SN/A *
17793SN/A * Redistribution and use in source and binary forms, with or without
18793SN/A * modification, are permitted provided that the following conditions are
19793SN/A * met: redistributions of source code must retain the above copyright
20793SN/A * notice, this list of conditions and the following disclaimer;
21793SN/A * redistributions in binary form must reproduce the above copyright
22793SN/A * notice, this list of conditions and the following disclaimer in the
23793SN/A * documentation and/or other materials provided with the distribution;
24793SN/A * neither the name of the copyright holders nor the names of its
25793SN/A * contributors may be used to endorse or promote products derived from
26793SN/A * this software without specific prior written permission.
27793SN/A *
28793SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29793SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30793SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31793SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32793SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33793SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34793SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35793SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36793SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37793SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38793SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665SN/A *
402665SN/A * Authors: Ali Saidi
412665SN/A *          Andrew Schultz
422665SN/A *          Nathan Binkert
43793SN/A */
44793SN/A
45793SN/A/* @file
46845SN/A * Interface for devices using PCI configuration
47793SN/A */
48793SN/A
4911260Sandreas.sandberg@arm.com#ifndef __DEV_PCI_DEVICE_HH__
5011260Sandreas.sandberg@arm.com#define __DEV_PCI_DEVICE_HH__
51793SN/A
523918SN/A#include <cstring>
539957SN/A#include <vector>
543918SN/A
559016SN/A#include "dev/dma_device.hh"
5611244SN/A#include "dev/pci/host.hh"
5711260Sandreas.sandberg@arm.com#include "dev/pci/pcireg.h"
584762SN/A#include "params/PciDevice.hh"
593348SN/A#include "sim/byteswap.hh"
60795SN/A
611817SN/A#define BAR_IO_MASK 0x3
621817SN/A#define BAR_MEM_MASK 0xF
631817SN/A#define BAR_IO_SPACE_BIT 0x1
641817SN/A#define BAR_IO_SPACE(x) ((x) & BAR_IO_SPACE_BIT)
651817SN/A#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
661817SN/A
67795SN/A/**
683083SN/A * PCI device, base implementation is only config space.
69793SN/A */
709807SN/Aclass PciDevice : public DmaDevice
71793SN/A{
7211244SN/A  protected:
7311244SN/A    const PciBusAddr _busAddr;
742846SN/A
754982SN/A    /** The current config space.  */
76793SN/A    PCIConfig config;
7711244SN/A
789957SN/A    /** The capability list structures and base addresses
799957SN/A     * @{
809957SN/A     */
819957SN/A    const int PMCAP_BASE;
8210479SN/A    const int PMCAP_ID_OFFSET;
8310479SN/A    const int PMCAP_PC_OFFSET;
8410479SN/A    const int PMCAP_PMCS_OFFSET;
859957SN/A    PMCAP pmcap;
869957SN/A
879957SN/A    const int MSICAP_BASE;
889957SN/A    MSICAP msicap;
899957SN/A
909957SN/A    const int MSIXCAP_BASE;
9110479SN/A    const int MSIXCAP_ID_OFFSET;
9210479SN/A    const int MSIXCAP_MXC_OFFSET;
9310479SN/A    const int MSIXCAP_MTAB_OFFSET;
9410479SN/A    const int MSIXCAP_MPBA_OFFSET;
9510479SN/A    int MSIX_TABLE_OFFSET;
9610479SN/A    int MSIX_TABLE_END;
9710479SN/A    int MSIX_PBA_OFFSET;
9810479SN/A    int MSIX_PBA_END;
999957SN/A    MSIXCAP msixcap;
1009957SN/A
1019957SN/A    const int PXCAP_BASE;
1029957SN/A    PXCAP pxcap;
1039957SN/A    /** @} */
1049957SN/A
1059957SN/A    /** MSIX Table and PBA Structures */
1069957SN/A    std::vector<MSIXTable> msix_table;
1079957SN/A    std::vector<MSIXPbaEntry> msix_pba;
108885SN/A
109885SN/A    /** The size of the BARs */
110793SN/A    uint32_t BARSize[6];
111885SN/A
112885SN/A    /** The current address mapping of the BARs */
113795SN/A    Addr BARAddrs[6];
114793SN/A
1155834SN/A    /** Whether the BARs are really hardwired legacy IO locations. */
1165834SN/A    bool legacyIO[6];
1175834SN/A
1183083SN/A    /**
1193083SN/A     * Does the given address lie within the space mapped by the given
1203083SN/A     * base address register?
1213083SN/A     */
1221992SN/A    bool
1231992SN/A    isBAR(Addr addr, int bar) const
1241992SN/A    {
1251992SN/A        assert(bar >= 0 && bar < 6);
1261992SN/A        return BARAddrs[bar] <= addr && addr < BARAddrs[bar] + BARSize[bar];
1271992SN/A    }
1281992SN/A
1293083SN/A    /**
1303083SN/A     * Which base address register (if any) maps the given address?
1313083SN/A     * @return The BAR number (0-5 inclusive), or -1 if none.
1323083SN/A     */
1331992SN/A    int
1341992SN/A    getBAR(Addr addr)
1351992SN/A    {
1361992SN/A        for (int i = 0; i <= 5; ++i)
1371992SN/A            if (isBAR(addr, i))
1381992SN/A                return i;
1391992SN/A
1401992SN/A        return -1;
1411992SN/A    }
1421992SN/A
1433083SN/A    /**
1443083SN/A     * Which base address register (if any) maps the given address?
1453083SN/A     * @param addr The address to check.
1463083SN/A     * @retval bar The BAR number (0-5 inclusive),
1473083SN/A     *             only valid if return value is true.
1483083SN/A     * @retval offs The offset from the base address,
1493083SN/A     *              only valid if return value is true.
1503083SN/A     * @return True iff address maps to a base address register's region.
1513083SN/A     */
1521992SN/A    bool
1533083SN/A    getBAR(Addr addr, int &bar, Addr &offs)
1541992SN/A    {
1553083SN/A        int b = getBAR(addr);
1561992SN/A        if (b < 0)
1571992SN/A            return false;
1581992SN/A
1593083SN/A        offs = addr - BARAddrs[b];
1601992SN/A        bar = b;
1611992SN/A        return true;
1621992SN/A    }
1631992SN/A
16411244SN/A  public: // Host configuration interface
1652846SN/A    /**
1662846SN/A     * Write to the PCI config space data that is stored locally. This may be
1672846SN/A     * overridden by the device but at some point it will eventually call this
1682846SN/A     * for normal operations that it does not need to override.
1692846SN/A     * @param pkt packet containing the write the offset into config space
1702846SN/A     */
1713349SN/A    virtual Tick writeConfig(PacketPtr pkt);
1722846SN/A
1732846SN/A
1742846SN/A    /**
1752846SN/A     * Read from the PCI config space data that is stored locally. This may be
1762846SN/A     * overridden by the device but at some point it will eventually call this
1772846SN/A     * for normal operations that it does not need to override.
1782846SN/A     * @param pkt packet containing the write the offset into config space
1792846SN/A     */
1803349SN/A    virtual Tick readConfig(PacketPtr pkt);
1811149SN/A
18211244SN/A  protected:
18311244SN/A    PciHost::DeviceInterface hostInterface;
18411244SN/A
18511244SN/A    Tick pioDelay;
18611244SN/A    Tick configDelay;
18711244SN/A
1881149SN/A  public:
18911244SN/A    Addr pciToDma(Addr pci_addr) const {
19011244SN/A        return hostInterface.dmaAddr(pci_addr);
19111244SN/A    }
1921149SN/A
19311244SN/A    void intrPost() { hostInterface.postInt(); }
19411244SN/A    void intrClear() { hostInterface.clearInt(); }
1951149SN/A
19611244SN/A    uint8_t interruptLine() const { return letoh(config.interruptLine); }
1971278SN/A
1988711SN/A    /**
1998711SN/A     * Determine the address ranges that this device responds to.
2008711SN/A     *
2018711SN/A     * @return a list of non-overlapping address ranges
2022565SN/A     */
20311169SN/A    AddrRangeList getAddrRanges() const override;
2042565SN/A
205885SN/A    /**
2061149SN/A     * Constructor for PCI Dev. This function copies data from the
2071149SN/A     * config file object PCIConfigData and registers the device with
20811244SN/A     * a PciHost object.
209885SN/A     */
21011244SN/A    PciDevice(const PciDeviceParams *params);
211793SN/A
212885SN/A    /**
213885SN/A     * Serialize this object to the given output stream.
214885SN/A     * @param os The stream to serialize to.
215885SN/A     */
21611168SN/A    void serialize(CheckpointOut &cp) const override;
217885SN/A
218885SN/A    /**
219885SN/A     * Reconstruct the state of this object from a checkpoint.
220885SN/A     * @param cp The checkpoint use.
221885SN/A     * @param section The section name of this object
222885SN/A     */
22311168SN/A    void unserialize(CheckpointIn &cp) override;
2242846SN/A
22511244SN/A    const PciBusAddr &busAddr() const { return _busAddr; }
226793SN/A};
22711260Sandreas.sandberg@arm.com#endif // __DEV_PCI_DEVICE_HH__
228