Statistics
| Branch: | Revision:

root / hw / pci.c @ 02eb84d0

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