1/*
2 * Copyright (c) 2013 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2004-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Ali Saidi
41 *          Andrew Schultz
42 *          Nathan Binkert
43 */
44
45/* @file
46 * Interface for devices using PCI configuration
47 */
48
49#ifndef __DEV_PCI_DEVICE_HH__
50#define __DEV_PCI_DEVICE_HH__
51
52#include <cstring>
53#include <vector>
54
55#include "dev/dma_device.hh"
56#include "dev/pci/host.hh"
57#include "dev/pci/pcireg.h"
58#include "params/PciDevice.hh"
59#include "sim/byteswap.hh"
60
61#define BAR_IO_MASK 0x3
62#define BAR_MEM_MASK 0xF
63#define BAR_IO_SPACE_BIT 0x1
64#define BAR_IO_SPACE(x) ((x) & BAR_IO_SPACE_BIT)
65#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
66
67/**
68 * PCI device, base implementation is only config space.
69 */
70class PciDevice : public DmaDevice
71{
72  protected:
73    const PciBusAddr _busAddr;
74
75    /** The current config space.  */
76    PCIConfig config;
77
78    /** The capability list structures and base addresses
79     * @{
80     */
81    const int PMCAP_BASE;
82    const int PMCAP_ID_OFFSET;
83    const int PMCAP_PC_OFFSET;
84    const int PMCAP_PMCS_OFFSET;
85    PMCAP pmcap;
86
87    const int MSICAP_BASE;
88    MSICAP msicap;
89
90    const int MSIXCAP_BASE;
91    const int MSIXCAP_ID_OFFSET;
92    const int MSIXCAP_MXC_OFFSET;
93    const int MSIXCAP_MTAB_OFFSET;
94    const int MSIXCAP_MPBA_OFFSET;
95    int MSIX_TABLE_OFFSET;
96    int MSIX_TABLE_END;
97    int MSIX_PBA_OFFSET;
98    int MSIX_PBA_END;
99    MSIXCAP msixcap;
100
101    const int PXCAP_BASE;
102    PXCAP pxcap;
103    /** @} */
104
105    /** MSIX Table and PBA Structures */
106    std::vector<MSIXTable> msix_table;
107    std::vector<MSIXPbaEntry> msix_pba;
108
109    /** The size of the BARs */
110    uint32_t BARSize[6];
111
112    /** The current address mapping of the BARs */
113    Addr BARAddrs[6];
114
115    /** Whether the BARs are really hardwired legacy IO locations. */
116    bool legacyIO[6];
117
118    /**
119     * Does the given address lie within the space mapped by the given
120     * base address register?
121     */
122    bool
123    isBAR(Addr addr, int bar) const
124    {
125        assert(bar >= 0 && bar < 6);
126        return BARAddrs[bar] <= addr && addr < BARAddrs[bar] + BARSize[bar];
127    }
128
129    /**
130     * Which base address register (if any) maps the given address?
131     * @return The BAR number (0-5 inclusive), or -1 if none.
132     */
133    int
134    getBAR(Addr addr)
135    {
136        for (int i = 0; i <= 5; ++i)
137            if (isBAR(addr, i))
138                return i;
139
140        return -1;
141    }
142
143    /**
144     * Which base address register (if any) maps the given address?
145     * @param addr The address to check.
146     * @retval bar The BAR number (0-5 inclusive),
147     *             only valid if return value is true.
148     * @retval offs The offset from the base address,
149     *              only valid if return value is true.
150     * @return True iff address maps to a base address register's region.
151     */
152    bool
153    getBAR(Addr addr, int &bar, Addr &offs)
154    {
155        int b = getBAR(addr);
156        if (b < 0)
157            return false;
158
159        offs = addr - BARAddrs[b];
160        bar = b;
161        return true;
162    }
163
164  public: // Host configuration interface
165    /**
166     * Write to the PCI config space data that is stored locally. This may be
167     * overridden by the device but at some point it will eventually call this
168     * for normal operations that it does not need to override.
169     * @param pkt packet containing the write the offset into config space
170     */
171    virtual Tick writeConfig(PacketPtr pkt);
172
173
174    /**
175     * Read from the PCI config space data that is stored locally. This may be
176     * overridden by the device but at some point it will eventually call this
177     * for normal operations that it does not need to override.
178     * @param pkt packet containing the write the offset into config space
179     */
180    virtual Tick readConfig(PacketPtr pkt);
181
182  protected:
183    PciHost::DeviceInterface hostInterface;
184
185    Tick pioDelay;
186    Tick configDelay;
187
188  public:
189    Addr pciToDma(Addr pci_addr) const {
190        return hostInterface.dmaAddr(pci_addr);
191    }
192
193    void intrPost() { hostInterface.postInt(); }
194    void intrClear() { hostInterface.clearInt(); }
195
196    uint8_t interruptLine() const { return letoh(config.interruptLine); }
197
198    /**
199     * Determine the address ranges that this device responds to.
200     *
201     * @return a list of non-overlapping address ranges
202     */
203    AddrRangeList getAddrRanges() const override;
204
205    /**
206     * Constructor for PCI Dev. This function copies data from the
207     * config file object PCIConfigData and registers the device with
208     * a PciHost object.
209     */
210    PciDevice(const PciDeviceParams *params);
211
212    /**
213     * Serialize this object to the given output stream.
214     * @param os The stream to serialize to.
215     */
216    void serialize(CheckpointOut &cp) const override;
217
218    /**
219     * Reconstruct the state of this object from a checkpoint.
220     * @param cp The checkpoint use.
221     * @param section The section name of this object
222     */
223    void unserialize(CheckpointIn &cp) override;
224
225    const PciBusAddr &busAddr() const { return _busAddr; }
226};
227#endif // __DEV_PCI_DEVICE_HH__
228