Statistics
| Branch: | Revision:

root / hw / pci.c @ a6307b08

History | View | Annotate | Download (30 kB)

1 69b91039 bellard
/*
2 69b91039 bellard
 * QEMU PCI bus manager
3 69b91039 bellard
 *
4 69b91039 bellard
 * Copyright (c) 2004 Fabrice Bellard
5 5fafdf24 ths
 *
6 69b91039 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 69b91039 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 69b91039 bellard
 * in the Software without restriction, including without limitation the rights
9 69b91039 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 69b91039 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 69b91039 bellard
 * furnished to do so, subject to the following conditions:
12 69b91039 bellard
 *
13 69b91039 bellard
 * The above copyright notice and this permission notice shall be included in
14 69b91039 bellard
 * all copies or substantial portions of the Software.
15 69b91039 bellard
 *
16 69b91039 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 69b91039 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 69b91039 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 69b91039 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 69b91039 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 69b91039 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 69b91039 bellard
 * THE SOFTWARE.
23 69b91039 bellard
 */
24 87ecb68b pbrook
#include "hw.h"
25 87ecb68b pbrook
#include "pci.h"
26 376253ec aliguori
#include "monitor.h"
27 87ecb68b pbrook
#include "net.h"
28 880345c4 aliguori
#include "sysemu.h"
29 69b91039 bellard
30 69b91039 bellard
//#define DEBUG_PCI
31 d8d2e079 Isaku Yamahata
#ifdef DEBUG_PCI
32 d8d2e079 Isaku Yamahata
# define PCI_DPRINTF(format, ...)       printf(format, __VA_ARGS__)
33 d8d2e079 Isaku Yamahata
#else
34 d8d2e079 Isaku Yamahata
# define PCI_DPRINTF(format, ...)       do { } while (0)
35 d8d2e079 Isaku Yamahata
#endif
36 69b91039 bellard
37 30468f78 bellard
struct PCIBus {
38 02e2da45 Paul Brook
    BusState qbus;
39 30468f78 bellard
    int bus_num;
40 30468f78 bellard
    int devfn_min;
41 502a5395 pbrook
    pci_set_irq_fn set_irq;
42 d2b59317 pbrook
    pci_map_irq_fn map_irq;
43 30468f78 bellard
    uint32_t config_reg; /* XXX: suppress */
44 384d8876 bellard
    /* low level pic */
45 384d8876 bellard
    SetIRQFunc *low_set_irq;
46 d537cf6c pbrook
    qemu_irq *irq_opaque;
47 30468f78 bellard
    PCIDevice *devices[256];
48 80b3ada7 pbrook
    PCIDevice *parent_dev;
49 80b3ada7 pbrook
    PCIBus *next;
50 d2b59317 pbrook
    /* The bus IRQ state is the logical OR of the connected devices.
51 d2b59317 pbrook
       Keep a count of the number of devices with raised IRQs.  */
52 52fc1d83 balrog
    int nirq;
53 10c4c98a Gerd Hoffmann
    int *irq_count;
54 10c4c98a Gerd Hoffmann
};
55 10c4c98a Gerd Hoffmann
56 10c4c98a Gerd Hoffmann
static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
57 10c4c98a Gerd Hoffmann
58 10c4c98a Gerd Hoffmann
static struct BusInfo pci_bus_info = {
59 10c4c98a Gerd Hoffmann
    .name       = "PCI",
60 10c4c98a Gerd Hoffmann
    .size       = sizeof(PCIBus),
61 10c4c98a Gerd Hoffmann
    .print_dev  = pcibus_dev_print,
62 ee6847d1 Gerd Hoffmann
    .props      = (Property[]) {
63 ee6847d1 Gerd Hoffmann
        {
64 a6307b08 Gerd Hoffmann
            .name   = "addr",
65 a6307b08 Gerd Hoffmann
            .info   = &qdev_prop_pci_devfn,
66 ee6847d1 Gerd Hoffmann
            .offset = offsetof(PCIDevice, devfn),
67 ee6847d1 Gerd Hoffmann
            .defval = (uint32_t[]) { -1 },
68 ee6847d1 Gerd Hoffmann
        },
69 ee6847d1 Gerd Hoffmann
        {/* end of list */}
70 ee6847d1 Gerd Hoffmann
    }
71 30468f78 bellard
};
72 69b91039 bellard
73 1941d19c bellard
static void pci_update_mappings(PCIDevice *d);
74 d537cf6c pbrook
static void pci_set_irq(void *opaque, int irq_num, int level);
75 1941d19c bellard
76 69b91039 bellard
target_phys_addr_t pci_mem_base;
77 d350d97d aliguori
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
78 d350d97d aliguori
static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
79 30468f78 bellard
static PCIBus *first_bus;
80 30468f78 bellard
81 52fc1d83 balrog
static void pcibus_save(QEMUFile *f, void *opaque)
82 52fc1d83 balrog
{
83 52fc1d83 balrog
    PCIBus *bus = (PCIBus *)opaque;
84 52fc1d83 balrog
    int i;
85 52fc1d83 balrog
86 52fc1d83 balrog
    qemu_put_be32(f, bus->nirq);
87 52fc1d83 balrog
    for (i = 0; i < bus->nirq; i++)
88 52fc1d83 balrog
        qemu_put_be32(f, bus->irq_count[i]);
89 52fc1d83 balrog
}
90 52fc1d83 balrog
91 52fc1d83 balrog
static int  pcibus_load(QEMUFile *f, void *opaque, int version_id)
92 52fc1d83 balrog
{
93 52fc1d83 balrog
    PCIBus *bus = (PCIBus *)opaque;
94 52fc1d83 balrog
    int i, nirq;
95 52fc1d83 balrog
96 52fc1d83 balrog
    if (version_id != 1)
97 52fc1d83 balrog
        return -EINVAL;
98 52fc1d83 balrog
99 52fc1d83 balrog
    nirq = qemu_get_be32(f);
100 52fc1d83 balrog
    if (bus->nirq != nirq) {
101 52fc1d83 balrog
        fprintf(stderr, "pcibus_load: nirq mismatch: src=%d dst=%d\n",
102 52fc1d83 balrog
                nirq, bus->nirq);
103 52fc1d83 balrog
        return -EINVAL;
104 52fc1d83 balrog
    }
105 52fc1d83 balrog
106 52fc1d83 balrog
    for (i = 0; i < nirq; i++)
107 52fc1d83 balrog
        bus->irq_count[i] = qemu_get_be32(f);
108 52fc1d83 balrog
109 52fc1d83 balrog
    return 0;
110 52fc1d83 balrog
}
111 52fc1d83 balrog
112 6eaa6847 Gleb Natapov
static void pci_bus_reset(void *opaque)
113 6eaa6847 Gleb Natapov
{
114 6eaa6847 Gleb Natapov
    PCIBus *bus = (PCIBus *)opaque;
115 6eaa6847 Gleb Natapov
    int i;
116 6eaa6847 Gleb Natapov
117 6eaa6847 Gleb Natapov
    for (i = 0; i < bus->nirq; i++) {
118 6eaa6847 Gleb Natapov
        bus->irq_count[i] = 0;
119 6eaa6847 Gleb Natapov
    }
120 6eaa6847 Gleb Natapov
    for (i = 0; i < 256; i++) {
121 6eaa6847 Gleb Natapov
        if (bus->devices[i])
122 6eaa6847 Gleb Natapov
            memset(bus->devices[i]->irq_state, 0,
123 6eaa6847 Gleb Natapov
                   sizeof(bus->devices[i]->irq_state));
124 6eaa6847 Gleb Natapov
    }
125 6eaa6847 Gleb Natapov
}
126 6eaa6847 Gleb Natapov
127 02e2da45 Paul Brook
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
128 02e2da45 Paul Brook
                         pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
129 d537cf6c pbrook
                         qemu_irq *pic, int devfn_min, int nirq)
130 30468f78 bellard
{
131 30468f78 bellard
    PCIBus *bus;
132 52fc1d83 balrog
    static int nbus = 0;
133 52fc1d83 balrog
134 10c4c98a Gerd Hoffmann
    bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, parent, name));
135 502a5395 pbrook
    bus->set_irq = set_irq;
136 d2b59317 pbrook
    bus->map_irq = map_irq;
137 502a5395 pbrook
    bus->irq_opaque = pic;
138 502a5395 pbrook
    bus->devfn_min = devfn_min;
139 52fc1d83 balrog
    bus->nirq = nirq;
140 616cbc78 Paul Brook
    bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
141 425c608c Isaku Yamahata
    bus->next = first_bus;
142 30468f78 bellard
    first_bus = bus;
143 52fc1d83 balrog
    register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
144 a08d4367 Jan Kiszka
    qemu_register_reset(pci_bus_reset, bus);
145 30468f78 bellard
    return bus;
146 30468f78 bellard
}
147 69b91039 bellard
148 72f44c8c Blue Swirl
static PCIBus *pci_register_secondary_bus(PCIDevice *dev,
149 72f44c8c Blue Swirl
                                          pci_map_irq_fn map_irq,
150 72f44c8c Blue Swirl
                                          const char *name)
151 80b3ada7 pbrook
{
152 80b3ada7 pbrook
    PCIBus *bus;
153 16eaedf2 Gerd Hoffmann
154 72f44c8c Blue Swirl
    bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, &dev->qdev, name));
155 80b3ada7 pbrook
    bus->map_irq = map_irq;
156 80b3ada7 pbrook
    bus->parent_dev = dev;
157 80b3ada7 pbrook
    bus->next = dev->bus->next;
158 80b3ada7 pbrook
    dev->bus->next = bus;
159 80b3ada7 pbrook
    return bus;
160 80b3ada7 pbrook
}
161 80b3ada7 pbrook
162 502a5395 pbrook
int pci_bus_num(PCIBus *s)
163 502a5395 pbrook
{
164 502a5395 pbrook
    return s->bus_num;
165 502a5395 pbrook
}
166 502a5395 pbrook
167 1941d19c bellard
void pci_device_save(PCIDevice *s, QEMUFile *f)
168 30ca2aab bellard
{
169 52fc1d83 balrog
    int i;
170 52fc1d83 balrog
171 52fc1d83 balrog
    qemu_put_be32(f, 2); /* PCI device version */
172 30ca2aab bellard
    qemu_put_buffer(f, s->config, 256);
173 52fc1d83 balrog
    for (i = 0; i < 4; i++)
174 52fc1d83 balrog
        qemu_put_be32(f, s->irq_state[i]);
175 30ca2aab bellard
}
176 30ca2aab bellard
177 1941d19c bellard
int pci_device_load(PCIDevice *s, QEMUFile *f)
178 30ca2aab bellard
{
179 bd4b65ee Michael S. Tsirkin
    uint8_t config[PCI_CONFIG_SPACE_SIZE];
180 1941d19c bellard
    uint32_t version_id;
181 52fc1d83 balrog
    int i;
182 52fc1d83 balrog
183 1941d19c bellard
    version_id = qemu_get_be32(f);
184 52fc1d83 balrog
    if (version_id > 2)
185 30ca2aab bellard
        return -EINVAL;
186 bd4b65ee Michael S. Tsirkin
    qemu_get_buffer(f, config, sizeof config);
187 bd4b65ee Michael S. Tsirkin
    for (i = 0; i < sizeof config; ++i)
188 bd4b65ee Michael S. Tsirkin
        if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i])
189 bd4b65ee Michael S. Tsirkin
            return -EINVAL;
190 bd4b65ee Michael S. Tsirkin
    memcpy(s->config, config, sizeof config);
191 bd4b65ee Michael S. Tsirkin
192 1941d19c bellard
    pci_update_mappings(s);
193 52fc1d83 balrog
194 52fc1d83 balrog
    if (version_id >= 2)
195 52fc1d83 balrog
        for (i = 0; i < 4; i ++)
196 52fc1d83 balrog
            s->irq_state[i] = qemu_get_be32(f);
197 30ca2aab bellard
    return 0;
198 30ca2aab bellard
}
199 30ca2aab bellard
200 d350d97d aliguori
static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
201 d350d97d aliguori
{
202 d350d97d aliguori
    uint16_t *id;
203 d350d97d aliguori
204 d350d97d aliguori
    id = (void*)(&pci_dev->config[PCI_SUBVENDOR_ID]);
205 d350d97d aliguori
    id[0] = cpu_to_le16(pci_default_sub_vendor_id);
206 d350d97d aliguori
    id[1] = cpu_to_le16(pci_default_sub_device_id);
207 d350d97d aliguori
    return 0;
208 d350d97d aliguori
}
209 d350d97d aliguori
210 880345c4 aliguori
/*
211 880345c4 aliguori
 * Parse [[<domain>:]<bus>:]<slot>, return -1 on error
212 880345c4 aliguori
 */
213 880345c4 aliguori
static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
214 880345c4 aliguori
{
215 880345c4 aliguori
    const char *p;
216 880345c4 aliguori
    char *e;
217 880345c4 aliguori
    unsigned long val;
218 880345c4 aliguori
    unsigned long dom = 0, bus = 0;
219 880345c4 aliguori
    unsigned slot = 0;
220 880345c4 aliguori
221 880345c4 aliguori
    p = addr;
222 880345c4 aliguori
    val = strtoul(p, &e, 16);
223 880345c4 aliguori
    if (e == p)
224 880345c4 aliguori
        return -1;
225 880345c4 aliguori
    if (*e == ':') {
226 880345c4 aliguori
        bus = val;
227 880345c4 aliguori
        p = e + 1;
228 880345c4 aliguori
        val = strtoul(p, &e, 16);
229 880345c4 aliguori
        if (e == p)
230 880345c4 aliguori
            return -1;
231 880345c4 aliguori
        if (*e == ':') {
232 880345c4 aliguori
            dom = bus;
233 880345c4 aliguori
            bus = val;
234 880345c4 aliguori
            p = e + 1;
235 880345c4 aliguori
            val = strtoul(p, &e, 16);
236 880345c4 aliguori
            if (e == p)
237 880345c4 aliguori
                return -1;
238 880345c4 aliguori
        }
239 880345c4 aliguori
    }
240 880345c4 aliguori
241 880345c4 aliguori
    if (dom > 0xffff || bus > 0xff || val > 0x1f)
242 880345c4 aliguori
        return -1;
243 880345c4 aliguori
244 880345c4 aliguori
    slot = val;
245 880345c4 aliguori
246 880345c4 aliguori
    if (*e)
247 880345c4 aliguori
        return -1;
248 880345c4 aliguori
249 880345c4 aliguori
    /* Note: QEMU doesn't implement domains other than 0 */
250 880345c4 aliguori
    if (dom != 0 || pci_find_bus(bus) == NULL)
251 880345c4 aliguori
        return -1;
252 880345c4 aliguori
253 880345c4 aliguori
    *domp = dom;
254 880345c4 aliguori
    *busp = bus;
255 880345c4 aliguori
    *slotp = slot;
256 880345c4 aliguori
    return 0;
257 880345c4 aliguori
}
258 880345c4 aliguori
259 e9283f8b Jan Kiszka
int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
260 e9283f8b Jan Kiszka
                     unsigned *slotp)
261 880345c4 aliguori
{
262 e9283f8b Jan Kiszka
    /* strip legacy tag */
263 e9283f8b Jan Kiszka
    if (!strncmp(addr, "pci_addr=", 9)) {
264 e9283f8b Jan Kiszka
        addr += 9;
265 e9283f8b Jan Kiszka
    }
266 e9283f8b Jan Kiszka
    if (pci_parse_devaddr(addr, domp, busp, slotp)) {
267 e9283f8b Jan Kiszka
        monitor_printf(mon, "Invalid pci address\n");
268 880345c4 aliguori
        return -1;
269 e9283f8b Jan Kiszka
    }
270 e9283f8b Jan Kiszka
    return 0;
271 880345c4 aliguori
}
272 880345c4 aliguori
273 5607c388 Markus Armbruster
static PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
274 5607c388 Markus Armbruster
{
275 5607c388 Markus Armbruster
    int dom, bus;
276 5607c388 Markus Armbruster
    unsigned slot;
277 5607c388 Markus Armbruster
278 5607c388 Markus Armbruster
    if (!devaddr) {
279 5607c388 Markus Armbruster
        *devfnp = -1;
280 5607c388 Markus Armbruster
        return pci_find_bus(0);
281 5607c388 Markus Armbruster
    }
282 5607c388 Markus Armbruster
283 5607c388 Markus Armbruster
    if (pci_parse_devaddr(devaddr, &dom, &bus, &slot) < 0) {
284 5607c388 Markus Armbruster
        return NULL;
285 5607c388 Markus Armbruster
    }
286 5607c388 Markus Armbruster
287 5607c388 Markus Armbruster
    *devfnp = slot << 3;
288 5607c388 Markus Armbruster
    return pci_find_bus(bus);
289 5607c388 Markus Armbruster
}
290 5607c388 Markus Armbruster
291 bd4b65ee Michael S. Tsirkin
static void pci_init_cmask(PCIDevice *dev)
292 bd4b65ee Michael S. Tsirkin
{
293 bd4b65ee Michael S. Tsirkin
    pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff);
294 bd4b65ee Michael S. Tsirkin
    pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff);
295 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_STATUS] = PCI_STATUS_CAP_LIST;
296 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_REVISION_ID] = 0xff;
297 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_CLASS_PROG] = 0xff;
298 bd4b65ee Michael S. Tsirkin
    pci_set_word(dev->cmask + PCI_CLASS_DEVICE, 0xffff);
299 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_HEADER_TYPE] = 0xff;
300 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_CAPABILITY_LIST] = 0xff;
301 bd4b65ee Michael S. Tsirkin
}
302 bd4b65ee Michael S. Tsirkin
303 b7ee1603 Michael S. Tsirkin
static void pci_init_wmask(PCIDevice *dev)
304 b7ee1603 Michael S. Tsirkin
{
305 b7ee1603 Michael S. Tsirkin
    int i;
306 b7ee1603 Michael S. Tsirkin
    dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
307 b7ee1603 Michael S. Tsirkin
    dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
308 b7ee1603 Michael S. Tsirkin
    dev->wmask[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY
309 b7ee1603 Michael S. Tsirkin
                              | PCI_COMMAND_MASTER;
310 b7ee1603 Michael S. Tsirkin
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
311 b7ee1603 Michael S. Tsirkin
        dev->wmask[i] = 0xff;
312 b7ee1603 Michael S. Tsirkin
}
313 b7ee1603 Michael S. Tsirkin
314 69b91039 bellard
/* -1 for devfn means auto assign */
315 6b1b92d3 Paul Brook
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
316 6b1b92d3 Paul Brook
                                         const char *name, int devfn,
317 6b1b92d3 Paul Brook
                                         PCIConfigReadFunc *config_read,
318 6b1b92d3 Paul Brook
                                         PCIConfigWriteFunc *config_write)
319 69b91039 bellard
{
320 69b91039 bellard
    if (devfn < 0) {
321 30468f78 bellard
        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
322 30468f78 bellard
            if (!bus->devices[devfn])
323 69b91039 bellard
                goto found;
324 69b91039 bellard
        }
325 69b91039 bellard
        return NULL;
326 69b91039 bellard
    found: ;
327 07b7d053 Markus Armbruster
    } else if (bus->devices[devfn]) {
328 07b7d053 Markus Armbruster
        return NULL;
329 69b91039 bellard
    }
330 30468f78 bellard
    pci_dev->bus = bus;
331 69b91039 bellard
    pci_dev->devfn = devfn;
332 69b91039 bellard
    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
333 d2b59317 pbrook
    memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
334 d350d97d aliguori
    pci_set_default_subsystem_id(pci_dev);
335 bd4b65ee Michael S. Tsirkin
    pci_init_cmask(pci_dev);
336 b7ee1603 Michael S. Tsirkin
    pci_init_wmask(pci_dev);
337 0ac32c83 bellard
338 0ac32c83 bellard
    if (!config_read)
339 0ac32c83 bellard
        config_read = pci_default_read_config;
340 0ac32c83 bellard
    if (!config_write)
341 0ac32c83 bellard
        config_write = pci_default_write_config;
342 69b91039 bellard
    pci_dev->config_read = config_read;
343 69b91039 bellard
    pci_dev->config_write = config_write;
344 30468f78 bellard
    bus->devices[devfn] = pci_dev;
345 d537cf6c pbrook
    pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
346 69b91039 bellard
    return pci_dev;
347 69b91039 bellard
}
348 69b91039 bellard
349 6b1b92d3 Paul Brook
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
350 6b1b92d3 Paul Brook
                               int instance_size, int devfn,
351 6b1b92d3 Paul Brook
                               PCIConfigReadFunc *config_read,
352 6b1b92d3 Paul Brook
                               PCIConfigWriteFunc *config_write)
353 6b1b92d3 Paul Brook
{
354 6b1b92d3 Paul Brook
    PCIDevice *pci_dev;
355 6b1b92d3 Paul Brook
356 6b1b92d3 Paul Brook
    pci_dev = qemu_mallocz(instance_size);
357 6b1b92d3 Paul Brook
    pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,
358 6b1b92d3 Paul Brook
                                     config_read, config_write);
359 6b1b92d3 Paul Brook
    return pci_dev;
360 6b1b92d3 Paul Brook
}
361 5851e08c aliguori
static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
362 5851e08c aliguori
{
363 5851e08c aliguori
    return addr + pci_mem_base;
364 5851e08c aliguori
}
365 5851e08c aliguori
366 5851e08c aliguori
static void pci_unregister_io_regions(PCIDevice *pci_dev)
367 5851e08c aliguori
{
368 5851e08c aliguori
    PCIIORegion *r;
369 5851e08c aliguori
    int i;
370 5851e08c aliguori
371 5851e08c aliguori
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
372 5851e08c aliguori
        r = &pci_dev->io_regions[i];
373 5851e08c aliguori
        if (!r->size || r->addr == -1)
374 5851e08c aliguori
            continue;
375 5851e08c aliguori
        if (r->type == PCI_ADDRESS_SPACE_IO) {
376 5851e08c aliguori
            isa_unassign_ioport(r->addr, r->size);
377 5851e08c aliguori
        } else {
378 5851e08c aliguori
            cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
379 5851e08c aliguori
                                                     r->size,
380 5851e08c aliguori
                                                     IO_MEM_UNASSIGNED);
381 5851e08c aliguori
        }
382 5851e08c aliguori
    }
383 5851e08c aliguori
}
384 5851e08c aliguori
385 5851e08c aliguori
int pci_unregister_device(PCIDevice *pci_dev)
386 5851e08c aliguori
{
387 5851e08c aliguori
    int ret = 0;
388 5851e08c aliguori
389 5851e08c aliguori
    if (pci_dev->unregister)
390 5851e08c aliguori
        ret = pci_dev->unregister(pci_dev);
391 5851e08c aliguori
    if (ret)
392 5851e08c aliguori
        return ret;
393 5851e08c aliguori
394 5851e08c aliguori
    pci_unregister_io_regions(pci_dev);
395 5851e08c aliguori
396 5851e08c aliguori
    qemu_free_irqs(pci_dev->irq);
397 5851e08c aliguori
    pci_dev->bus->devices[pci_dev->devfn] = NULL;
398 02e2da45 Paul Brook
    qdev_free(&pci_dev->qdev);
399 5851e08c aliguori
    return 0;
400 5851e08c aliguori
}
401 5851e08c aliguori
402 28c2c264 Avi Kivity
void pci_register_bar(PCIDevice *pci_dev, int region_num,
403 5fafdf24 ths
                            uint32_t size, int type,
404 69b91039 bellard
                            PCIMapIORegionFunc *map_func)
405 69b91039 bellard
{
406 69b91039 bellard
    PCIIORegion *r;
407 d7ce493a pbrook
    uint32_t addr;
408 b7ee1603 Michael S. Tsirkin
    uint32_t wmask;
409 69b91039 bellard
410 8a8696a3 bellard
    if ((unsigned int)region_num >= PCI_NUM_REGIONS)
411 69b91039 bellard
        return;
412 a4c20c6a aliguori
413 a4c20c6a aliguori
    if (size & (size-1)) {
414 a4c20c6a aliguori
        fprintf(stderr, "ERROR: PCI region size must be pow2 "
415 a4c20c6a aliguori
                    "type=0x%x, size=0x%x\n", type, size);
416 a4c20c6a aliguori
        exit(1);
417 a4c20c6a aliguori
    }
418 a4c20c6a aliguori
419 69b91039 bellard
    r = &pci_dev->io_regions[region_num];
420 69b91039 bellard
    r->addr = -1;
421 69b91039 bellard
    r->size = size;
422 69b91039 bellard
    r->type = type;
423 69b91039 bellard
    r->map_func = map_func;
424 b7ee1603 Michael S. Tsirkin
425 b7ee1603 Michael S. Tsirkin
    wmask = ~(size - 1);
426 d7ce493a pbrook
    if (region_num == PCI_ROM_SLOT) {
427 d7ce493a pbrook
        addr = 0x30;
428 b7ee1603 Michael S. Tsirkin
        /* ROM enable bit is writeable */
429 b7ee1603 Michael S. Tsirkin
        wmask |= 1;
430 d7ce493a pbrook
    } else {
431 d7ce493a pbrook
        addr = 0x10 + region_num * 4;
432 d7ce493a pbrook
    }
433 d7ce493a pbrook
    *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
434 b7ee1603 Michael S. Tsirkin
    *(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask);
435 bd4b65ee Michael S. Tsirkin
    *(uint32_t *)(pci_dev->cmask + addr) = 0xffffffff;
436 69b91039 bellard
}
437 69b91039 bellard
438 0ac32c83 bellard
static void pci_update_mappings(PCIDevice *d)
439 0ac32c83 bellard
{
440 0ac32c83 bellard
    PCIIORegion *r;
441 0ac32c83 bellard
    int cmd, i;
442 8a8696a3 bellard
    uint32_t last_addr, new_addr, config_ofs;
443 3b46e624 ths
444 0ac32c83 bellard
    cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
445 8a8696a3 bellard
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
446 0ac32c83 bellard
        r = &d->io_regions[i];
447 8a8696a3 bellard
        if (i == PCI_ROM_SLOT) {
448 8a8696a3 bellard
            config_ofs = 0x30;
449 8a8696a3 bellard
        } else {
450 8a8696a3 bellard
            config_ofs = 0x10 + i * 4;
451 8a8696a3 bellard
        }
452 0ac32c83 bellard
        if (r->size != 0) {
453 0ac32c83 bellard
            if (r->type & PCI_ADDRESS_SPACE_IO) {
454 0ac32c83 bellard
                if (cmd & PCI_COMMAND_IO) {
455 5fafdf24 ths
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
456 8a8696a3 bellard
                                                         config_ofs));
457 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
458 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
459 0ac32c83 bellard
                    /* NOTE: we have only 64K ioports on PC */
460 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
461 0ac32c83 bellard
                        last_addr >= 0x10000) {
462 0ac32c83 bellard
                        new_addr = -1;
463 0ac32c83 bellard
                    }
464 0ac32c83 bellard
                } else {
465 0ac32c83 bellard
                    new_addr = -1;
466 0ac32c83 bellard
                }
467 0ac32c83 bellard
            } else {
468 0ac32c83 bellard
                if (cmd & PCI_COMMAND_MEMORY) {
469 5fafdf24 ths
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
470 8a8696a3 bellard
                                                         config_ofs));
471 8a8696a3 bellard
                    /* the ROM slot has a specific enable bit */
472 8a8696a3 bellard
                    if (i == PCI_ROM_SLOT && !(new_addr & 1))
473 8a8696a3 bellard
                        goto no_mem_map;
474 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
475 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
476 0ac32c83 bellard
                    /* NOTE: we do not support wrapping */
477 0ac32c83 bellard
                    /* XXX: as we cannot support really dynamic
478 0ac32c83 bellard
                       mappings, we handle specific values as invalid
479 0ac32c83 bellard
                       mappings. */
480 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
481 0ac32c83 bellard
                        last_addr == -1) {
482 0ac32c83 bellard
                        new_addr = -1;
483 0ac32c83 bellard
                    }
484 0ac32c83 bellard
                } else {
485 8a8696a3 bellard
                no_mem_map:
486 0ac32c83 bellard
                    new_addr = -1;
487 0ac32c83 bellard
                }
488 0ac32c83 bellard
            }
489 0ac32c83 bellard
            /* now do the real mapping */
490 0ac32c83 bellard
            if (new_addr != r->addr) {
491 0ac32c83 bellard
                if (r->addr != -1) {
492 0ac32c83 bellard
                    if (r->type & PCI_ADDRESS_SPACE_IO) {
493 0ac32c83 bellard
                        int class;
494 0ac32c83 bellard
                        /* NOTE: specific hack for IDE in PC case:
495 0ac32c83 bellard
                           only one byte must be mapped. */
496 0ac32c83 bellard
                        class = d->config[0x0a] | (d->config[0x0b] << 8);
497 0ac32c83 bellard
                        if (class == 0x0101 && r->size == 4) {
498 0ac32c83 bellard
                            isa_unassign_ioport(r->addr + 2, 1);
499 0ac32c83 bellard
                        } else {
500 0ac32c83 bellard
                            isa_unassign_ioport(r->addr, r->size);
501 0ac32c83 bellard
                        }
502 0ac32c83 bellard
                    } else {
503 502a5395 pbrook
                        cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
504 5fafdf24 ths
                                                     r->size,
505 0ac32c83 bellard
                                                     IO_MEM_UNASSIGNED);
506 f65ed4c1 aliguori
                        qemu_unregister_coalesced_mmio(r->addr, r->size);
507 0ac32c83 bellard
                    }
508 0ac32c83 bellard
                }
509 0ac32c83 bellard
                r->addr = new_addr;
510 0ac32c83 bellard
                if (r->addr != -1) {
511 0ac32c83 bellard
                    r->map_func(d, i, r->addr, r->size, r->type);
512 0ac32c83 bellard
                }
513 0ac32c83 bellard
            }
514 0ac32c83 bellard
        }
515 0ac32c83 bellard
    }
516 0ac32c83 bellard
}
517 0ac32c83 bellard
518 5fafdf24 ths
uint32_t pci_default_read_config(PCIDevice *d,
519 0ac32c83 bellard
                                 uint32_t address, int len)
520 69b91039 bellard
{
521 0ac32c83 bellard
    uint32_t val;
522 a2d4e44b ths
523 0ac32c83 bellard
    switch(len) {
524 0ac32c83 bellard
    default:
525 0ac32c83 bellard
    case 4:
526 a2d4e44b ths
        if (address <= 0xfc) {
527 a2d4e44b ths
            val = le32_to_cpu(*(uint32_t *)(d->config + address));
528 a2d4e44b ths
            break;
529 a2d4e44b ths
        }
530 a2d4e44b ths
        /* fall through */
531 a2d4e44b ths
    case 2:
532 a2d4e44b ths
        if (address <= 0xfe) {
533 a2d4e44b ths
            val = le16_to_cpu(*(uint16_t *)(d->config + address));
534 a2d4e44b ths
            break;
535 a2d4e44b ths
        }
536 a2d4e44b ths
        /* fall through */
537 a2d4e44b ths
    case 1:
538 a2d4e44b ths
        val = d->config[address];
539 0ac32c83 bellard
        break;
540 0ac32c83 bellard
    }
541 0ac32c83 bellard
    return val;
542 0ac32c83 bellard
}
543 0ac32c83 bellard
544 b7ee1603 Michael S. Tsirkin
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
545 0ac32c83 bellard
{
546 b7ee1603 Michael S. Tsirkin
    uint8_t orig[PCI_CONFIG_SPACE_SIZE];
547 b7ee1603 Michael S. Tsirkin
    int i;
548 0ac32c83 bellard
549 0ac32c83 bellard
    /* not efficient, but simple */
550 b7ee1603 Michael S. Tsirkin
    memcpy(orig, d->config, PCI_CONFIG_SPACE_SIZE);
551 b7ee1603 Michael S. Tsirkin
    for(i = 0; i < l && addr < PCI_CONFIG_SPACE_SIZE; val >>= 8, ++i, ++addr) {
552 b7ee1603 Michael S. Tsirkin
        uint8_t wmask = d->wmask[addr];
553 b7ee1603 Michael S. Tsirkin
        d->config[addr] = (d->config[addr] & ~wmask) | (val & wmask);
554 0ac32c83 bellard
    }
555 b7ee1603 Michael S. Tsirkin
    if (memcmp(orig + PCI_BASE_ADDRESS_0, d->config + PCI_BASE_ADDRESS_0, 24)
556 b7ee1603 Michael S. Tsirkin
        || ((orig[PCI_COMMAND] ^ d->config[PCI_COMMAND])
557 b7ee1603 Michael S. Tsirkin
            & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)))
558 0ac32c83 bellard
        pci_update_mappings(d);
559 69b91039 bellard
}
560 69b91039 bellard
561 502a5395 pbrook
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
562 69b91039 bellard
{
563 30468f78 bellard
    PCIBus *s = opaque;
564 30468f78 bellard
    PCIDevice *pci_dev;
565 30468f78 bellard
    int config_addr, bus_num;
566 3b46e624 ths
567 d8d2e079 Isaku Yamahata
#if 0
568 d8d2e079 Isaku Yamahata
    PCI_DPRINTF("pci_data_write: addr=%08x val=%08x len=%d\n",
569 d8d2e079 Isaku Yamahata
                addr, val, len);
570 69b91039 bellard
#endif
571 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
572 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
573 80b3ada7 pbrook
        s = s->next;
574 80b3ada7 pbrook
    if (!s)
575 69b91039 bellard
        return;
576 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
577 69b91039 bellard
    if (!pci_dev)
578 69b91039 bellard
        return;
579 502a5395 pbrook
    config_addr = addr & 0xff;
580 d8d2e079 Isaku Yamahata
    PCI_DPRINTF("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
581 d8d2e079 Isaku Yamahata
                pci_dev->name, config_addr, val, len);
582 0ac32c83 bellard
    pci_dev->config_write(pci_dev, config_addr, val, len);
583 69b91039 bellard
}
584 69b91039 bellard
585 502a5395 pbrook
uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
586 69b91039 bellard
{
587 30468f78 bellard
    PCIBus *s = opaque;
588 30468f78 bellard
    PCIDevice *pci_dev;
589 30468f78 bellard
    int config_addr, bus_num;
590 69b91039 bellard
    uint32_t val;
591 69b91039 bellard
592 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
593 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
594 80b3ada7 pbrook
        s= s->next;
595 80b3ada7 pbrook
    if (!s)
596 69b91039 bellard
        goto fail;
597 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
598 69b91039 bellard
    if (!pci_dev) {
599 69b91039 bellard
    fail:
600 63ce9e0a bellard
        switch(len) {
601 63ce9e0a bellard
        case 1:
602 63ce9e0a bellard
            val = 0xff;
603 63ce9e0a bellard
            break;
604 63ce9e0a bellard
        case 2:
605 63ce9e0a bellard
            val = 0xffff;
606 63ce9e0a bellard
            break;
607 63ce9e0a bellard
        default:
608 63ce9e0a bellard
        case 4:
609 63ce9e0a bellard
            val = 0xffffffff;
610 63ce9e0a bellard
            break;
611 63ce9e0a bellard
        }
612 69b91039 bellard
        goto the_end;
613 69b91039 bellard
    }
614 502a5395 pbrook
    config_addr = addr & 0xff;
615 69b91039 bellard
    val = pci_dev->config_read(pci_dev, config_addr, len);
616 d8d2e079 Isaku Yamahata
    PCI_DPRINTF("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
617 d8d2e079 Isaku Yamahata
                pci_dev->name, config_addr, val, len);
618 69b91039 bellard
 the_end:
619 d8d2e079 Isaku Yamahata
#if 0
620 d8d2e079 Isaku Yamahata
    PCI_DPRINTF("pci_data_read: addr=%08x val=%08x len=%d\n",
621 d8d2e079 Isaku Yamahata
                addr, val, len);
622 69b91039 bellard
#endif
623 69b91039 bellard
    return val;
624 69b91039 bellard
}
625 69b91039 bellard
626 502a5395 pbrook
/***********************************************************/
627 502a5395 pbrook
/* generic PCI irq support */
628 30468f78 bellard
629 502a5395 pbrook
/* 0 <= irq_num <= 3. level must be 0 or 1 */
630 d537cf6c pbrook
static void pci_set_irq(void *opaque, int irq_num, int level)
631 69b91039 bellard
{
632 d537cf6c pbrook
    PCIDevice *pci_dev = (PCIDevice *)opaque;
633 80b3ada7 pbrook
    PCIBus *bus;
634 80b3ada7 pbrook
    int change;
635 3b46e624 ths
636 80b3ada7 pbrook
    change = level - pci_dev->irq_state[irq_num];
637 80b3ada7 pbrook
    if (!change)
638 80b3ada7 pbrook
        return;
639 d2b59317 pbrook
640 d2b59317 pbrook
    pci_dev->irq_state[irq_num] = level;
641 5e966ce6 pbrook
    for (;;) {
642 5e966ce6 pbrook
        bus = pci_dev->bus;
643 80b3ada7 pbrook
        irq_num = bus->map_irq(pci_dev, irq_num);
644 5e966ce6 pbrook
        if (bus->set_irq)
645 5e966ce6 pbrook
            break;
646 80b3ada7 pbrook
        pci_dev = bus->parent_dev;
647 80b3ada7 pbrook
    }
648 80b3ada7 pbrook
    bus->irq_count[irq_num] += change;
649 d2b59317 pbrook
    bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
650 69b91039 bellard
}
651 69b91039 bellard
652 502a5395 pbrook
/***********************************************************/
653 502a5395 pbrook
/* monitor info on PCI */
654 0ac32c83 bellard
655 6650ee6d pbrook
typedef struct {
656 6650ee6d pbrook
    uint16_t class;
657 6650ee6d pbrook
    const char *desc;
658 6650ee6d pbrook
} pci_class_desc;
659 6650ee6d pbrook
660 09bc878a blueswir1
static const pci_class_desc pci_class_descriptions[] =
661 6650ee6d pbrook
{
662 4ca9c76f pbrook
    { 0x0100, "SCSI controller"},
663 6650ee6d pbrook
    { 0x0101, "IDE controller"},
664 dcb5b19a ths
    { 0x0102, "Floppy controller"},
665 dcb5b19a ths
    { 0x0103, "IPI controller"},
666 dcb5b19a ths
    { 0x0104, "RAID controller"},
667 dcb5b19a ths
    { 0x0106, "SATA controller"},
668 dcb5b19a ths
    { 0x0107, "SAS controller"},
669 dcb5b19a ths
    { 0x0180, "Storage controller"},
670 6650ee6d pbrook
    { 0x0200, "Ethernet controller"},
671 dcb5b19a ths
    { 0x0201, "Token Ring controller"},
672 dcb5b19a ths
    { 0x0202, "FDDI controller"},
673 dcb5b19a ths
    { 0x0203, "ATM controller"},
674 dcb5b19a ths
    { 0x0280, "Network controller"},
675 6650ee6d pbrook
    { 0x0300, "VGA controller"},
676 dcb5b19a ths
    { 0x0301, "XGA controller"},
677 dcb5b19a ths
    { 0x0302, "3D controller"},
678 dcb5b19a ths
    { 0x0380, "Display controller"},
679 dcb5b19a ths
    { 0x0400, "Video controller"},
680 dcb5b19a ths
    { 0x0401, "Audio controller"},
681 dcb5b19a ths
    { 0x0402, "Phone"},
682 dcb5b19a ths
    { 0x0480, "Multimedia controller"},
683 dcb5b19a ths
    { 0x0500, "RAM controller"},
684 dcb5b19a ths
    { 0x0501, "Flash controller"},
685 dcb5b19a ths
    { 0x0580, "Memory controller"},
686 6650ee6d pbrook
    { 0x0600, "Host bridge"},
687 6650ee6d pbrook
    { 0x0601, "ISA bridge"},
688 dcb5b19a ths
    { 0x0602, "EISA bridge"},
689 dcb5b19a ths
    { 0x0603, "MC bridge"},
690 6650ee6d pbrook
    { 0x0604, "PCI bridge"},
691 dcb5b19a ths
    { 0x0605, "PCMCIA bridge"},
692 dcb5b19a ths
    { 0x0606, "NUBUS bridge"},
693 dcb5b19a ths
    { 0x0607, "CARDBUS bridge"},
694 dcb5b19a ths
    { 0x0608, "RACEWAY bridge"},
695 dcb5b19a ths
    { 0x0680, "Bridge"},
696 6650ee6d pbrook
    { 0x0c03, "USB controller"},
697 6650ee6d pbrook
    { 0, NULL}
698 6650ee6d pbrook
};
699 6650ee6d pbrook
700 502a5395 pbrook
static void pci_info_device(PCIDevice *d)
701 30468f78 bellard
{
702 376253ec aliguori
    Monitor *mon = cur_mon;
703 502a5395 pbrook
    int i, class;
704 502a5395 pbrook
    PCIIORegion *r;
705 09bc878a blueswir1
    const pci_class_desc *desc;
706 30468f78 bellard
707 376253ec aliguori
    monitor_printf(mon, "  Bus %2d, device %3d, function %d:\n",
708 376253ec aliguori
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
709 502a5395 pbrook
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
710 376253ec aliguori
    monitor_printf(mon, "    ");
711 6650ee6d pbrook
    desc = pci_class_descriptions;
712 6650ee6d pbrook
    while (desc->desc && class != desc->class)
713 6650ee6d pbrook
        desc++;
714 6650ee6d pbrook
    if (desc->desc) {
715 376253ec aliguori
        monitor_printf(mon, "%s", desc->desc);
716 6650ee6d pbrook
    } else {
717 376253ec aliguori
        monitor_printf(mon, "Class %04x", class);
718 72cc6cfe bellard
    }
719 376253ec aliguori
    monitor_printf(mon, ": PCI device %04x:%04x\n",
720 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
721 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
722 30468f78 bellard
723 502a5395 pbrook
    if (d->config[PCI_INTERRUPT_PIN] != 0) {
724 376253ec aliguori
        monitor_printf(mon, "      IRQ %d.\n",
725 376253ec aliguori
                       d->config[PCI_INTERRUPT_LINE]);
726 30468f78 bellard
    }
727 80b3ada7 pbrook
    if (class == 0x0604) {
728 376253ec aliguori
        monitor_printf(mon, "      BUS %d.\n", d->config[0x19]);
729 80b3ada7 pbrook
    }
730 502a5395 pbrook
    for(i = 0;i < PCI_NUM_REGIONS; i++) {
731 502a5395 pbrook
        r = &d->io_regions[i];
732 502a5395 pbrook
        if (r->size != 0) {
733 376253ec aliguori
            monitor_printf(mon, "      BAR%d: ", i);
734 502a5395 pbrook
            if (r->type & PCI_ADDRESS_SPACE_IO) {
735 376253ec aliguori
                monitor_printf(mon, "I/O at 0x%04x [0x%04x].\n",
736 376253ec aliguori
                               r->addr, r->addr + r->size - 1);
737 502a5395 pbrook
            } else {
738 376253ec aliguori
                monitor_printf(mon, "32 bit memory at 0x%08x [0x%08x].\n",
739 376253ec aliguori
                               r->addr, r->addr + r->size - 1);
740 502a5395 pbrook
            }
741 502a5395 pbrook
        }
742 77d4bc34 bellard
    }
743 8ad12514 Gerd Hoffmann
    monitor_printf(mon, "      id \"%s\"\n", d->qdev.id ? d->qdev.id : "");
744 80b3ada7 pbrook
    if (class == 0x0604 && d->config[0x19] != 0) {
745 80b3ada7 pbrook
        pci_for_each_device(d->config[0x19], pci_info_device);
746 80b3ada7 pbrook
    }
747 384d8876 bellard
}
748 384d8876 bellard
749 80b3ada7 pbrook
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
750 384d8876 bellard
{
751 502a5395 pbrook
    PCIBus *bus = first_bus;
752 384d8876 bellard
    PCIDevice *d;
753 502a5395 pbrook
    int devfn;
754 3b46e624 ths
755 80b3ada7 pbrook
    while (bus && bus->bus_num != bus_num)
756 80b3ada7 pbrook
        bus = bus->next;
757 502a5395 pbrook
    if (bus) {
758 502a5395 pbrook
        for(devfn = 0; devfn < 256; devfn++) {
759 502a5395 pbrook
            d = bus->devices[devfn];
760 502a5395 pbrook
            if (d)
761 502a5395 pbrook
                fn(d);
762 502a5395 pbrook
        }
763 f2aa58c6 bellard
    }
764 f2aa58c6 bellard
}
765 f2aa58c6 bellard
766 376253ec aliguori
void pci_info(Monitor *mon)
767 f2aa58c6 bellard
{
768 80b3ada7 pbrook
    pci_for_each_device(0, pci_info_device);
769 77d4bc34 bellard
}
770 a41b2ff2 pbrook
771 1f5f6638 Markus Armbruster
PCIDevice *pci_create(const char *name, const char *devaddr)
772 5607c388 Markus Armbruster
{
773 5607c388 Markus Armbruster
    PCIBus *bus;
774 5607c388 Markus Armbruster
    int devfn;
775 5607c388 Markus Armbruster
    DeviceState *dev;
776 5607c388 Markus Armbruster
777 5607c388 Markus Armbruster
    bus = pci_get_bus_devfn(&devfn, devaddr);
778 5607c388 Markus Armbruster
    if (!bus) {
779 5607c388 Markus Armbruster
        fprintf(stderr, "Invalid PCI device address %s for device %s\n",
780 5607c388 Markus Armbruster
                devaddr, name);
781 5607c388 Markus Armbruster
        exit(1);
782 5607c388 Markus Armbruster
    }
783 5607c388 Markus Armbruster
784 5607c388 Markus Armbruster
    dev = qdev_create(&bus->qbus, name);
785 a6307b08 Gerd Hoffmann
    qdev_prop_set_uint32(dev, "addr", devfn);
786 5607c388 Markus Armbruster
    return (PCIDevice *)dev;
787 5607c388 Markus Armbruster
}
788 5607c388 Markus Armbruster
789 cb457d76 aliguori
static const char * const pci_nic_models[] = {
790 cb457d76 aliguori
    "ne2k_pci",
791 cb457d76 aliguori
    "i82551",
792 cb457d76 aliguori
    "i82557b",
793 cb457d76 aliguori
    "i82559er",
794 cb457d76 aliguori
    "rtl8139",
795 cb457d76 aliguori
    "e1000",
796 cb457d76 aliguori
    "pcnet",
797 cb457d76 aliguori
    "virtio",
798 cb457d76 aliguori
    NULL
799 cb457d76 aliguori
};
800 cb457d76 aliguori
801 9d07d757 Paul Brook
static const char * const pci_nic_names[] = {
802 9d07d757 Paul Brook
    "ne2k_pci",
803 9d07d757 Paul Brook
    "i82551",
804 9d07d757 Paul Brook
    "i82557b",
805 9d07d757 Paul Brook
    "i82559er",
806 9d07d757 Paul Brook
    "rtl8139",
807 9d07d757 Paul Brook
    "e1000",
808 9d07d757 Paul Brook
    "pcnet",
809 53c25cea Paul Brook
    "virtio-net-pci",
810 cb457d76 aliguori
    NULL
811 cb457d76 aliguori
};
812 cb457d76 aliguori
813 a41b2ff2 pbrook
/* Initialize a PCI NIC.  */
814 5607c388 Markus Armbruster
PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
815 5607c388 Markus Armbruster
                        const char *default_devaddr)
816 a41b2ff2 pbrook
{
817 5607c388 Markus Armbruster
    const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
818 5607c388 Markus Armbruster
    PCIDevice *pci_dev;
819 9d07d757 Paul Brook
    DeviceState *dev;
820 cb457d76 aliguori
    int i;
821 cb457d76 aliguori
822 cb457d76 aliguori
    qemu_check_nic_model_list(nd, pci_nic_models, default_model);
823 cb457d76 aliguori
824 9d07d757 Paul Brook
    for (i = 0; pci_nic_models[i]; i++) {
825 72da4208 aliguori
        if (strcmp(nd->model, pci_nic_models[i]) == 0) {
826 5607c388 Markus Armbruster
            pci_dev = pci_create(pci_nic_names[i], devaddr);
827 5607c388 Markus Armbruster
            dev = &pci_dev->qdev;
828 eb54b6dc Gerd Hoffmann
            if (nd->id)
829 eb54b6dc Gerd Hoffmann
                dev->id = qemu_strdup(nd->id);
830 ee6847d1 Gerd Hoffmann
            dev->nd = nd;
831 9d07d757 Paul Brook
            qdev_init(dev);
832 9d07d757 Paul Brook
            nd->private = dev;
833 5607c388 Markus Armbruster
            return pci_dev;
834 72da4208 aliguori
        }
835 9d07d757 Paul Brook
    }
836 72da4208 aliguori
837 72da4208 aliguori
    return NULL;
838 a41b2ff2 pbrook
}
839 a41b2ff2 pbrook
840 80b3ada7 pbrook
typedef struct {
841 80b3ada7 pbrook
    PCIDevice dev;
842 80b3ada7 pbrook
    PCIBus *bus;
843 80b3ada7 pbrook
} PCIBridge;
844 80b3ada7 pbrook
845 9596ebb7 pbrook
static void pci_bridge_write_config(PCIDevice *d,
846 80b3ada7 pbrook
                             uint32_t address, uint32_t val, int len)
847 80b3ada7 pbrook
{
848 80b3ada7 pbrook
    PCIBridge *s = (PCIBridge *)d;
849 80b3ada7 pbrook
850 80b3ada7 pbrook
    pci_default_write_config(d, address, val, len);
851 b7ee1603 Michael S. Tsirkin
    s->bus->bus_num = d->config[PCI_SECONDARY_BUS];
852 80b3ada7 pbrook
}
853 80b3ada7 pbrook
854 3ae80618 aliguori
PCIBus *pci_find_bus(int bus_num)
855 3ae80618 aliguori
{
856 3ae80618 aliguori
    PCIBus *bus = first_bus;
857 3ae80618 aliguori
858 3ae80618 aliguori
    while (bus && bus->bus_num != bus_num)
859 3ae80618 aliguori
        bus = bus->next;
860 3ae80618 aliguori
861 3ae80618 aliguori
    return bus;
862 3ae80618 aliguori
}
863 3ae80618 aliguori
864 3ae80618 aliguori
PCIDevice *pci_find_device(int bus_num, int slot, int function)
865 3ae80618 aliguori
{
866 3ae80618 aliguori
    PCIBus *bus = pci_find_bus(bus_num);
867 3ae80618 aliguori
868 3ae80618 aliguori
    if (!bus)
869 3ae80618 aliguori
        return NULL;
870 3ae80618 aliguori
871 3ae80618 aliguori
    return bus->devices[PCI_DEVFN(slot, function)];
872 3ae80618 aliguori
}
873 3ae80618 aliguori
874 480b9f24 blueswir1
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
875 80b3ada7 pbrook
                        pci_map_irq_fn map_irq, const char *name)
876 80b3ada7 pbrook
{
877 80b3ada7 pbrook
    PCIBridge *s;
878 5fafdf24 ths
    s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
879 80b3ada7 pbrook
                                         devfn, NULL, pci_bridge_write_config);
880 480b9f24 blueswir1
881 480b9f24 blueswir1
    pci_config_set_vendor_id(s->dev.config, vid);
882 480b9f24 blueswir1
    pci_config_set_device_id(s->dev.config, did);
883 480b9f24 blueswir1
884 80b3ada7 pbrook
    s->dev.config[0x04] = 0x06; // command = bus master, pci mem
885 80b3ada7 pbrook
    s->dev.config[0x05] = 0x00;
886 80b3ada7 pbrook
    s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
887 80b3ada7 pbrook
    s->dev.config[0x07] = 0x00; // status = fast devsel
888 80b3ada7 pbrook
    s->dev.config[0x08] = 0x00; // revision
889 80b3ada7 pbrook
    s->dev.config[0x09] = 0x00; // programming i/f
890 173a543b blueswir1
    pci_config_set_class(s->dev.config, PCI_CLASS_BRIDGE_PCI);
891 80b3ada7 pbrook
    s->dev.config[0x0D] = 0x10; // latency_timer
892 6407f373 Isaku Yamahata
    s->dev.config[PCI_HEADER_TYPE] =
893 6407f373 Isaku Yamahata
        PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
894 80b3ada7 pbrook
    s->dev.config[0x1E] = 0xa0; // secondary status
895 80b3ada7 pbrook
896 72f44c8c Blue Swirl
    s->bus = pci_register_secondary_bus(&s->dev, map_irq, name);
897 80b3ada7 pbrook
    return s->bus;
898 80b3ada7 pbrook
}
899 6b1b92d3 Paul Brook
900 02e2da45 Paul Brook
static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
901 6b1b92d3 Paul Brook
{
902 6b1b92d3 Paul Brook
    PCIDevice *pci_dev = (PCIDevice *)qdev;
903 02e2da45 Paul Brook
    PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
904 6b1b92d3 Paul Brook
    PCIBus *bus;
905 6b1b92d3 Paul Brook
    int devfn;
906 6b1b92d3 Paul Brook
907 02e2da45 Paul Brook
    bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
908 ee6847d1 Gerd Hoffmann
    devfn = pci_dev->devfn;
909 16eaedf2 Gerd Hoffmann
    pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
910 0aab0d3a Gerd Hoffmann
                                     info->config_read, info->config_write);
911 6b1b92d3 Paul Brook
    assert(pci_dev);
912 02e2da45 Paul Brook
    info->init(pci_dev);
913 6b1b92d3 Paul Brook
}
914 6b1b92d3 Paul Brook
915 0aab0d3a Gerd Hoffmann
void pci_qdev_register(PCIDeviceInfo *info)
916 6b1b92d3 Paul Brook
{
917 02e2da45 Paul Brook
    info->qdev.init = pci_qdev_init;
918 10c4c98a Gerd Hoffmann
    info->qdev.bus_info = &pci_bus_info;
919 074f2fff Gerd Hoffmann
    qdev_register(&info->qdev);
920 6b1b92d3 Paul Brook
}
921 6b1b92d3 Paul Brook
922 0aab0d3a Gerd Hoffmann
void pci_qdev_register_many(PCIDeviceInfo *info)
923 0aab0d3a Gerd Hoffmann
{
924 0aab0d3a Gerd Hoffmann
    while (info->qdev.name) {
925 0aab0d3a Gerd Hoffmann
        pci_qdev_register(info);
926 0aab0d3a Gerd Hoffmann
        info++;
927 0aab0d3a Gerd Hoffmann
    }
928 0aab0d3a Gerd Hoffmann
}
929 0aab0d3a Gerd Hoffmann
930 6b1b92d3 Paul Brook
PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
931 6b1b92d3 Paul Brook
{
932 6b1b92d3 Paul Brook
    DeviceState *dev;
933 6b1b92d3 Paul Brook
934 02e2da45 Paul Brook
    dev = qdev_create(&bus->qbus, name);
935 a6307b08 Gerd Hoffmann
    qdev_prop_set_uint32(dev, "addr", devfn);
936 6b1b92d3 Paul Brook
    qdev_init(dev);
937 6b1b92d3 Paul Brook
938 6b1b92d3 Paul Brook
    return (PCIDevice *)dev;
939 6b1b92d3 Paul Brook
}
940 6f4cbd39 Michael S. Tsirkin
941 6f4cbd39 Michael S. Tsirkin
static int pci_find_space(PCIDevice *pdev, uint8_t size)
942 6f4cbd39 Michael S. Tsirkin
{
943 6f4cbd39 Michael S. Tsirkin
    int offset = PCI_CONFIG_HEADER_SIZE;
944 6f4cbd39 Michael S. Tsirkin
    int i;
945 6f4cbd39 Michael S. Tsirkin
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
946 6f4cbd39 Michael S. Tsirkin
        if (pdev->used[i])
947 6f4cbd39 Michael S. Tsirkin
            offset = i + 1;
948 6f4cbd39 Michael S. Tsirkin
        else if (i - offset + 1 == size)
949 6f4cbd39 Michael S. Tsirkin
            return offset;
950 6f4cbd39 Michael S. Tsirkin
    return 0;
951 6f4cbd39 Michael S. Tsirkin
}
952 6f4cbd39 Michael S. Tsirkin
953 6f4cbd39 Michael S. Tsirkin
static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
954 6f4cbd39 Michael S. Tsirkin
                                        uint8_t *prev_p)
955 6f4cbd39 Michael S. Tsirkin
{
956 6f4cbd39 Michael S. Tsirkin
    uint8_t next, prev;
957 6f4cbd39 Michael S. Tsirkin
958 6f4cbd39 Michael S. Tsirkin
    if (!(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST))
959 6f4cbd39 Michael S. Tsirkin
        return 0;
960 6f4cbd39 Michael S. Tsirkin
961 6f4cbd39 Michael S. Tsirkin
    for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
962 6f4cbd39 Michael S. Tsirkin
         prev = next + PCI_CAP_LIST_NEXT)
963 6f4cbd39 Michael S. Tsirkin
        if (pdev->config[next + PCI_CAP_LIST_ID] == cap_id)
964 6f4cbd39 Michael S. Tsirkin
            break;
965 6f4cbd39 Michael S. Tsirkin
966 6f4cbd39 Michael S. Tsirkin
    if (prev_p)
967 6f4cbd39 Michael S. Tsirkin
        *prev_p = prev;
968 6f4cbd39 Michael S. Tsirkin
    return next;
969 6f4cbd39 Michael S. Tsirkin
}
970 6f4cbd39 Michael S. Tsirkin
971 6f4cbd39 Michael S. Tsirkin
/* Reserve space and add capability to the linked list in pci config space */
972 6f4cbd39 Michael S. Tsirkin
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
973 6f4cbd39 Michael S. Tsirkin
{
974 6f4cbd39 Michael S. Tsirkin
    uint8_t offset = pci_find_space(pdev, size);
975 6f4cbd39 Michael S. Tsirkin
    uint8_t *config = pdev->config + offset;
976 6f4cbd39 Michael S. Tsirkin
    if (!offset)
977 6f4cbd39 Michael S. Tsirkin
        return -ENOSPC;
978 6f4cbd39 Michael S. Tsirkin
    config[PCI_CAP_LIST_ID] = cap_id;
979 6f4cbd39 Michael S. Tsirkin
    config[PCI_CAP_LIST_NEXT] = pdev->config[PCI_CAPABILITY_LIST];
980 6f4cbd39 Michael S. Tsirkin
    pdev->config[PCI_CAPABILITY_LIST] = offset;
981 6f4cbd39 Michael S. Tsirkin
    pdev->config[PCI_STATUS] |= PCI_STATUS_CAP_LIST;
982 6f4cbd39 Michael S. Tsirkin
    memset(pdev->used + offset, 0xFF, size);
983 6f4cbd39 Michael S. Tsirkin
    /* Make capability read-only by default */
984 6f4cbd39 Michael S. Tsirkin
    memset(pdev->wmask + offset, 0, size);
985 bd4b65ee Michael S. Tsirkin
    /* Check capability by default */
986 bd4b65ee Michael S. Tsirkin
    memset(pdev->cmask + offset, 0xFF, size);
987 6f4cbd39 Michael S. Tsirkin
    return offset;
988 6f4cbd39 Michael S. Tsirkin
}
989 6f4cbd39 Michael S. Tsirkin
990 6f4cbd39 Michael S. Tsirkin
/* Unlink capability from the pci config space. */
991 6f4cbd39 Michael S. Tsirkin
void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
992 6f4cbd39 Michael S. Tsirkin
{
993 6f4cbd39 Michael S. Tsirkin
    uint8_t prev, offset = pci_find_capability_list(pdev, cap_id, &prev);
994 6f4cbd39 Michael S. Tsirkin
    if (!offset)
995 6f4cbd39 Michael S. Tsirkin
        return;
996 6f4cbd39 Michael S. Tsirkin
    pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];
997 6f4cbd39 Michael S. Tsirkin
    /* Make capability writeable again */
998 6f4cbd39 Michael S. Tsirkin
    memset(pdev->wmask + offset, 0xff, size);
999 bd4b65ee Michael S. Tsirkin
    /* Clear cmask as device-specific registers can't be checked */
1000 bd4b65ee Michael S. Tsirkin
    memset(pdev->cmask + offset, 0, size);
1001 6f4cbd39 Michael S. Tsirkin
    memset(pdev->used + offset, 0, size);
1002 6f4cbd39 Michael S. Tsirkin
1003 6f4cbd39 Michael S. Tsirkin
    if (!pdev->config[PCI_CAPABILITY_LIST])
1004 6f4cbd39 Michael S. Tsirkin
        pdev->config[PCI_STATUS] &= ~PCI_STATUS_CAP_LIST;
1005 6f4cbd39 Michael S. Tsirkin
}
1006 6f4cbd39 Michael S. Tsirkin
1007 6f4cbd39 Michael S. Tsirkin
/* Reserve space for capability at a known offset (to call after load). */
1008 6f4cbd39 Michael S. Tsirkin
void pci_reserve_capability(PCIDevice *pdev, uint8_t offset, uint8_t size)
1009 6f4cbd39 Michael S. Tsirkin
{
1010 6f4cbd39 Michael S. Tsirkin
    memset(pdev->used + offset, 0xff, size);
1011 6f4cbd39 Michael S. Tsirkin
}
1012 6f4cbd39 Michael S. Tsirkin
1013 6f4cbd39 Michael S. Tsirkin
uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id)
1014 6f4cbd39 Michael S. Tsirkin
{
1015 6f4cbd39 Michael S. Tsirkin
    return pci_find_capability_list(pdev, cap_id, NULL);
1016 6f4cbd39 Michael S. Tsirkin
}
1017 10c4c98a Gerd Hoffmann
1018 10c4c98a Gerd Hoffmann
static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
1019 10c4c98a Gerd Hoffmann
{
1020 10c4c98a Gerd Hoffmann
    PCIDevice *d = (PCIDevice *)dev;
1021 10c4c98a Gerd Hoffmann
    const pci_class_desc *desc;
1022 10c4c98a Gerd Hoffmann
    char ctxt[64];
1023 10c4c98a Gerd Hoffmann
    PCIIORegion *r;
1024 10c4c98a Gerd Hoffmann
    int i, class;
1025 10c4c98a Gerd Hoffmann
1026 10c4c98a Gerd Hoffmann
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
1027 10c4c98a Gerd Hoffmann
    desc = pci_class_descriptions;
1028 10c4c98a Gerd Hoffmann
    while (desc->desc && class != desc->class)
1029 10c4c98a Gerd Hoffmann
        desc++;
1030 10c4c98a Gerd Hoffmann
    if (desc->desc) {
1031 10c4c98a Gerd Hoffmann
        snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
1032 10c4c98a Gerd Hoffmann
    } else {
1033 10c4c98a Gerd Hoffmann
        snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
1034 10c4c98a Gerd Hoffmann
    }
1035 10c4c98a Gerd Hoffmann
1036 10c4c98a Gerd Hoffmann
    monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
1037 10c4c98a Gerd Hoffmann
                   "pci id %04x:%04x (sub %04x:%04x)\n",
1038 10c4c98a Gerd Hoffmann
                   indent, "", ctxt,
1039 10c4c98a Gerd Hoffmann
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7,
1040 10c4c98a Gerd Hoffmann
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
1041 10c4c98a Gerd Hoffmann
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))),
1042 10c4c98a Gerd Hoffmann
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_VENDOR_ID))),
1043 10c4c98a Gerd Hoffmann
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_ID))));
1044 10c4c98a Gerd Hoffmann
    for (i = 0; i < PCI_NUM_REGIONS; i++) {
1045 10c4c98a Gerd Hoffmann
        r = &d->io_regions[i];
1046 10c4c98a Gerd Hoffmann
        if (!r->size)
1047 10c4c98a Gerd Hoffmann
            continue;
1048 10c4c98a Gerd Hoffmann
        monitor_printf(mon, "%*sbar %d: %s at 0x%x [0x%x]\n", indent, "",
1049 10c4c98a Gerd Hoffmann
                       i, r->type & PCI_ADDRESS_SPACE_IO ? "i/o" : "mem",
1050 10c4c98a Gerd Hoffmann
                       r->addr, r->addr + r->size - 1);
1051 10c4c98a Gerd Hoffmann
    }
1052 10c4c98a Gerd Hoffmann
}