Statistics
| Branch: | Revision:

root / hw / pci.c @ 4870852c

History | View | Annotate | Download (24.3 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 fbe78f4f aliguori
#include "virtio-net.h"
29 880345c4 aliguori
#include "sysemu.h"
30 69b91039 bellard
31 69b91039 bellard
//#define DEBUG_PCI
32 69b91039 bellard
33 30468f78 bellard
struct PCIBus {
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 0ac32c83 bellard
static int pci_irq_index;
58 30468f78 bellard
static PCIBus *first_bus;
59 30468f78 bellard
60 52fc1d83 balrog
static void pcibus_save(QEMUFile *f, void *opaque)
61 52fc1d83 balrog
{
62 52fc1d83 balrog
    PCIBus *bus = (PCIBus *)opaque;
63 52fc1d83 balrog
    int i;
64 52fc1d83 balrog
65 52fc1d83 balrog
    qemu_put_be32(f, bus->nirq);
66 52fc1d83 balrog
    for (i = 0; i < bus->nirq; i++)
67 52fc1d83 balrog
        qemu_put_be32(f, bus->irq_count[i]);
68 52fc1d83 balrog
}
69 52fc1d83 balrog
70 52fc1d83 balrog
static int  pcibus_load(QEMUFile *f, void *opaque, int version_id)
71 52fc1d83 balrog
{
72 52fc1d83 balrog
    PCIBus *bus = (PCIBus *)opaque;
73 52fc1d83 balrog
    int i, nirq;
74 52fc1d83 balrog
75 52fc1d83 balrog
    if (version_id != 1)
76 52fc1d83 balrog
        return -EINVAL;
77 52fc1d83 balrog
78 52fc1d83 balrog
    nirq = qemu_get_be32(f);
79 52fc1d83 balrog
    if (bus->nirq != nirq) {
80 52fc1d83 balrog
        fprintf(stderr, "pcibus_load: nirq mismatch: src=%d dst=%d\n",
81 52fc1d83 balrog
                nirq, bus->nirq);
82 52fc1d83 balrog
        return -EINVAL;
83 52fc1d83 balrog
    }
84 52fc1d83 balrog
85 52fc1d83 balrog
    for (i = 0; i < nirq; i++)
86 52fc1d83 balrog
        bus->irq_count[i] = qemu_get_be32(f);
87 52fc1d83 balrog
88 52fc1d83 balrog
    return 0;
89 52fc1d83 balrog
}
90 52fc1d83 balrog
91 d2b59317 pbrook
PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
92 d537cf6c pbrook
                         qemu_irq *pic, int devfn_min, int nirq)
93 30468f78 bellard
{
94 30468f78 bellard
    PCIBus *bus;
95 52fc1d83 balrog
    static int nbus = 0;
96 52fc1d83 balrog
97 80b3ada7 pbrook
    bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
98 502a5395 pbrook
    bus->set_irq = set_irq;
99 d2b59317 pbrook
    bus->map_irq = map_irq;
100 502a5395 pbrook
    bus->irq_opaque = pic;
101 502a5395 pbrook
    bus->devfn_min = devfn_min;
102 52fc1d83 balrog
    bus->nirq = nirq;
103 30468f78 bellard
    first_bus = bus;
104 52fc1d83 balrog
    register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
105 30468f78 bellard
    return bus;
106 30468f78 bellard
}
107 69b91039 bellard
108 9596ebb7 pbrook
static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
109 80b3ada7 pbrook
{
110 80b3ada7 pbrook
    PCIBus *bus;
111 80b3ada7 pbrook
    bus = qemu_mallocz(sizeof(PCIBus));
112 80b3ada7 pbrook
    bus->map_irq = map_irq;
113 80b3ada7 pbrook
    bus->parent_dev = dev;
114 80b3ada7 pbrook
    bus->next = dev->bus->next;
115 80b3ada7 pbrook
    dev->bus->next = bus;
116 80b3ada7 pbrook
    return bus;
117 80b3ada7 pbrook
}
118 80b3ada7 pbrook
119 502a5395 pbrook
int pci_bus_num(PCIBus *s)
120 502a5395 pbrook
{
121 502a5395 pbrook
    return s->bus_num;
122 502a5395 pbrook
}
123 502a5395 pbrook
124 1941d19c bellard
void pci_device_save(PCIDevice *s, QEMUFile *f)
125 30ca2aab bellard
{
126 52fc1d83 balrog
    int i;
127 52fc1d83 balrog
128 52fc1d83 balrog
    qemu_put_be32(f, 2); /* PCI device version */
129 30ca2aab bellard
    qemu_put_buffer(f, s->config, 256);
130 52fc1d83 balrog
    for (i = 0; i < 4; i++)
131 52fc1d83 balrog
        qemu_put_be32(f, s->irq_state[i]);
132 30ca2aab bellard
}
133 30ca2aab bellard
134 1941d19c bellard
int pci_device_load(PCIDevice *s, QEMUFile *f)
135 30ca2aab bellard
{
136 1941d19c bellard
    uint32_t version_id;
137 52fc1d83 balrog
    int i;
138 52fc1d83 balrog
139 1941d19c bellard
    version_id = qemu_get_be32(f);
140 52fc1d83 balrog
    if (version_id > 2)
141 30ca2aab bellard
        return -EINVAL;
142 30ca2aab bellard
    qemu_get_buffer(f, s->config, 256);
143 1941d19c bellard
    pci_update_mappings(s);
144 52fc1d83 balrog
145 52fc1d83 balrog
    if (version_id >= 2)
146 52fc1d83 balrog
        for (i = 0; i < 4; i ++)
147 52fc1d83 balrog
            s->irq_state[i] = qemu_get_be32(f);
148 52fc1d83 balrog
149 30ca2aab bellard
    return 0;
150 30ca2aab bellard
}
151 30ca2aab bellard
152 d350d97d aliguori
static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
153 d350d97d aliguori
{
154 d350d97d aliguori
    uint16_t *id;
155 d350d97d aliguori
156 d350d97d aliguori
    id = (void*)(&pci_dev->config[PCI_SUBVENDOR_ID]);
157 d350d97d aliguori
    id[0] = cpu_to_le16(pci_default_sub_vendor_id);
158 d350d97d aliguori
    id[1] = cpu_to_le16(pci_default_sub_device_id);
159 d350d97d aliguori
    return 0;
160 d350d97d aliguori
}
161 d350d97d aliguori
162 880345c4 aliguori
/*
163 880345c4 aliguori
 * Parse [[<domain>:]<bus>:]<slot>, return -1 on error
164 880345c4 aliguori
 */
165 880345c4 aliguori
static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
166 880345c4 aliguori
{
167 880345c4 aliguori
    const char *p;
168 880345c4 aliguori
    char *e;
169 880345c4 aliguori
    unsigned long val;
170 880345c4 aliguori
    unsigned long dom = 0, bus = 0;
171 880345c4 aliguori
    unsigned slot = 0;
172 880345c4 aliguori
173 880345c4 aliguori
    p = addr;
174 880345c4 aliguori
    val = strtoul(p, &e, 16);
175 880345c4 aliguori
    if (e == p)
176 880345c4 aliguori
        return -1;
177 880345c4 aliguori
    if (*e == ':') {
178 880345c4 aliguori
        bus = val;
179 880345c4 aliguori
        p = e + 1;
180 880345c4 aliguori
        val = strtoul(p, &e, 16);
181 880345c4 aliguori
        if (e == p)
182 880345c4 aliguori
            return -1;
183 880345c4 aliguori
        if (*e == ':') {
184 880345c4 aliguori
            dom = bus;
185 880345c4 aliguori
            bus = val;
186 880345c4 aliguori
            p = e + 1;
187 880345c4 aliguori
            val = strtoul(p, &e, 16);
188 880345c4 aliguori
            if (e == p)
189 880345c4 aliguori
                return -1;
190 880345c4 aliguori
        }
191 880345c4 aliguori
    }
192 880345c4 aliguori
193 880345c4 aliguori
    if (dom > 0xffff || bus > 0xff || val > 0x1f)
194 880345c4 aliguori
        return -1;
195 880345c4 aliguori
196 880345c4 aliguori
    slot = val;
197 880345c4 aliguori
198 880345c4 aliguori
    if (*e)
199 880345c4 aliguori
        return -1;
200 880345c4 aliguori
201 880345c4 aliguori
    /* Note: QEMU doesn't implement domains other than 0 */
202 880345c4 aliguori
    if (dom != 0 || pci_find_bus(bus) == NULL)
203 880345c4 aliguori
        return -1;
204 880345c4 aliguori
205 880345c4 aliguori
    *domp = dom;
206 880345c4 aliguori
    *busp = bus;
207 880345c4 aliguori
    *slotp = slot;
208 880345c4 aliguori
    return 0;
209 880345c4 aliguori
}
210 880345c4 aliguori
211 880345c4 aliguori
int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
212 880345c4 aliguori
{
213 880345c4 aliguori
    char devaddr[32];
214 880345c4 aliguori
215 880345c4 aliguori
    if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
216 880345c4 aliguori
        return -1;
217 880345c4 aliguori
218 880345c4 aliguori
    return pci_parse_devaddr(devaddr, domp, busp, slotp);
219 880345c4 aliguori
}
220 880345c4 aliguori
221 880345c4 aliguori
int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
222 880345c4 aliguori
{
223 880345c4 aliguori
    char devaddr[32];
224 880345c4 aliguori
225 880345c4 aliguori
    if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
226 880345c4 aliguori
        return -1;
227 880345c4 aliguori
228 880345c4 aliguori
    if (!strcmp(devaddr, "auto")) {
229 880345c4 aliguori
        *domp = *busp = 0;
230 880345c4 aliguori
        *slotp = -1;
231 880345c4 aliguori
        /* want to support dom/bus auto-assign at some point */
232 880345c4 aliguori
        return 0;
233 880345c4 aliguori
    }
234 880345c4 aliguori
235 880345c4 aliguori
    return pci_parse_devaddr(devaddr, domp, busp, slotp);
236 880345c4 aliguori
}
237 880345c4 aliguori
238 69b91039 bellard
/* -1 for devfn means auto assign */
239 5fafdf24 ths
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
240 30468f78 bellard
                               int instance_size, int devfn,
241 5fafdf24 ths
                               PCIConfigReadFunc *config_read,
242 69b91039 bellard
                               PCIConfigWriteFunc *config_write)
243 69b91039 bellard
{
244 30468f78 bellard
    PCIDevice *pci_dev;
245 69b91039 bellard
246 0ac32c83 bellard
    if (pci_irq_index >= PCI_DEVICES_MAX)
247 0ac32c83 bellard
        return NULL;
248 3b46e624 ths
249 69b91039 bellard
    if (devfn < 0) {
250 30468f78 bellard
        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
251 30468f78 bellard
            if (!bus->devices[devfn])
252 69b91039 bellard
                goto found;
253 69b91039 bellard
        }
254 69b91039 bellard
        return NULL;
255 69b91039 bellard
    found: ;
256 69b91039 bellard
    }
257 69b91039 bellard
    pci_dev = qemu_mallocz(instance_size);
258 30468f78 bellard
    pci_dev->bus = bus;
259 69b91039 bellard
    pci_dev->devfn = devfn;
260 69b91039 bellard
    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
261 d2b59317 pbrook
    memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
262 d350d97d aliguori
    pci_set_default_subsystem_id(pci_dev);
263 0ac32c83 bellard
264 0ac32c83 bellard
    if (!config_read)
265 0ac32c83 bellard
        config_read = pci_default_read_config;
266 0ac32c83 bellard
    if (!config_write)
267 0ac32c83 bellard
        config_write = pci_default_write_config;
268 69b91039 bellard
    pci_dev->config_read = config_read;
269 69b91039 bellard
    pci_dev->config_write = config_write;
270 0ac32c83 bellard
    pci_dev->irq_index = pci_irq_index++;
271 30468f78 bellard
    bus->devices[devfn] = pci_dev;
272 d537cf6c pbrook
    pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
273 69b91039 bellard
    return pci_dev;
274 69b91039 bellard
}
275 69b91039 bellard
276 5851e08c aliguori
static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
277 5851e08c aliguori
{
278 5851e08c aliguori
    return addr + pci_mem_base;
279 5851e08c aliguori
}
280 5851e08c aliguori
281 5851e08c aliguori
static void pci_unregister_io_regions(PCIDevice *pci_dev)
282 5851e08c aliguori
{
283 5851e08c aliguori
    PCIIORegion *r;
284 5851e08c aliguori
    int i;
285 5851e08c aliguori
286 5851e08c aliguori
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
287 5851e08c aliguori
        r = &pci_dev->io_regions[i];
288 5851e08c aliguori
        if (!r->size || r->addr == -1)
289 5851e08c aliguori
            continue;
290 5851e08c aliguori
        if (r->type == PCI_ADDRESS_SPACE_IO) {
291 5851e08c aliguori
            isa_unassign_ioport(r->addr, r->size);
292 5851e08c aliguori
        } else {
293 5851e08c aliguori
            cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
294 5851e08c aliguori
                                                     r->size,
295 5851e08c aliguori
                                                     IO_MEM_UNASSIGNED);
296 5851e08c aliguori
        }
297 5851e08c aliguori
    }
298 5851e08c aliguori
}
299 5851e08c aliguori
300 5851e08c aliguori
int pci_unregister_device(PCIDevice *pci_dev)
301 5851e08c aliguori
{
302 5851e08c aliguori
    int ret = 0;
303 5851e08c aliguori
304 5851e08c aliguori
    if (pci_dev->unregister)
305 5851e08c aliguori
        ret = pci_dev->unregister(pci_dev);
306 5851e08c aliguori
    if (ret)
307 5851e08c aliguori
        return ret;
308 5851e08c aliguori
309 5851e08c aliguori
    pci_unregister_io_regions(pci_dev);
310 5851e08c aliguori
311 5851e08c aliguori
    qemu_free_irqs(pci_dev->irq);
312 5851e08c aliguori
    pci_irq_index--;
313 5851e08c aliguori
    pci_dev->bus->devices[pci_dev->devfn] = NULL;
314 5851e08c aliguori
    qemu_free(pci_dev);
315 5851e08c aliguori
    return 0;
316 5851e08c aliguori
}
317 5851e08c aliguori
318 5fafdf24 ths
void pci_register_io_region(PCIDevice *pci_dev, int region_num,
319 5fafdf24 ths
                            uint32_t size, int type,
320 69b91039 bellard
                            PCIMapIORegionFunc *map_func)
321 69b91039 bellard
{
322 69b91039 bellard
    PCIIORegion *r;
323 d7ce493a pbrook
    uint32_t addr;
324 69b91039 bellard
325 8a8696a3 bellard
    if ((unsigned int)region_num >= PCI_NUM_REGIONS)
326 69b91039 bellard
        return;
327 a4c20c6a aliguori
328 a4c20c6a aliguori
    if (size & (size-1)) {
329 a4c20c6a aliguori
        fprintf(stderr, "ERROR: PCI region size must be pow2 "
330 a4c20c6a aliguori
                    "type=0x%x, size=0x%x\n", type, size);
331 a4c20c6a aliguori
        exit(1);
332 a4c20c6a aliguori
    }
333 a4c20c6a aliguori
334 69b91039 bellard
    r = &pci_dev->io_regions[region_num];
335 69b91039 bellard
    r->addr = -1;
336 69b91039 bellard
    r->size = size;
337 69b91039 bellard
    r->type = type;
338 69b91039 bellard
    r->map_func = map_func;
339 d7ce493a pbrook
    if (region_num == PCI_ROM_SLOT) {
340 d7ce493a pbrook
        addr = 0x30;
341 d7ce493a pbrook
    } else {
342 d7ce493a pbrook
        addr = 0x10 + region_num * 4;
343 d7ce493a pbrook
    }
344 d7ce493a pbrook
    *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
345 69b91039 bellard
}
346 69b91039 bellard
347 0ac32c83 bellard
static void pci_update_mappings(PCIDevice *d)
348 0ac32c83 bellard
{
349 0ac32c83 bellard
    PCIIORegion *r;
350 0ac32c83 bellard
    int cmd, i;
351 8a8696a3 bellard
    uint32_t last_addr, new_addr, config_ofs;
352 3b46e624 ths
353 0ac32c83 bellard
    cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
354 8a8696a3 bellard
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
355 0ac32c83 bellard
        r = &d->io_regions[i];
356 8a8696a3 bellard
        if (i == PCI_ROM_SLOT) {
357 8a8696a3 bellard
            config_ofs = 0x30;
358 8a8696a3 bellard
        } else {
359 8a8696a3 bellard
            config_ofs = 0x10 + i * 4;
360 8a8696a3 bellard
        }
361 0ac32c83 bellard
        if (r->size != 0) {
362 0ac32c83 bellard
            if (r->type & PCI_ADDRESS_SPACE_IO) {
363 0ac32c83 bellard
                if (cmd & PCI_COMMAND_IO) {
364 5fafdf24 ths
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
365 8a8696a3 bellard
                                                         config_ofs));
366 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
367 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
368 0ac32c83 bellard
                    /* NOTE: we have only 64K ioports on PC */
369 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
370 0ac32c83 bellard
                        last_addr >= 0x10000) {
371 0ac32c83 bellard
                        new_addr = -1;
372 0ac32c83 bellard
                    }
373 0ac32c83 bellard
                } else {
374 0ac32c83 bellard
                    new_addr = -1;
375 0ac32c83 bellard
                }
376 0ac32c83 bellard
            } else {
377 0ac32c83 bellard
                if (cmd & PCI_COMMAND_MEMORY) {
378 5fafdf24 ths
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
379 8a8696a3 bellard
                                                         config_ofs));
380 8a8696a3 bellard
                    /* the ROM slot has a specific enable bit */
381 8a8696a3 bellard
                    if (i == PCI_ROM_SLOT && !(new_addr & 1))
382 8a8696a3 bellard
                        goto no_mem_map;
383 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
384 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
385 0ac32c83 bellard
                    /* NOTE: we do not support wrapping */
386 0ac32c83 bellard
                    /* XXX: as we cannot support really dynamic
387 0ac32c83 bellard
                       mappings, we handle specific values as invalid
388 0ac32c83 bellard
                       mappings. */
389 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
390 0ac32c83 bellard
                        last_addr == -1) {
391 0ac32c83 bellard
                        new_addr = -1;
392 0ac32c83 bellard
                    }
393 0ac32c83 bellard
                } else {
394 8a8696a3 bellard
                no_mem_map:
395 0ac32c83 bellard
                    new_addr = -1;
396 0ac32c83 bellard
                }
397 0ac32c83 bellard
            }
398 0ac32c83 bellard
            /* now do the real mapping */
399 0ac32c83 bellard
            if (new_addr != r->addr) {
400 0ac32c83 bellard
                if (r->addr != -1) {
401 0ac32c83 bellard
                    if (r->type & PCI_ADDRESS_SPACE_IO) {
402 0ac32c83 bellard
                        int class;
403 0ac32c83 bellard
                        /* NOTE: specific hack for IDE in PC case:
404 0ac32c83 bellard
                           only one byte must be mapped. */
405 0ac32c83 bellard
                        class = d->config[0x0a] | (d->config[0x0b] << 8);
406 0ac32c83 bellard
                        if (class == 0x0101 && r->size == 4) {
407 0ac32c83 bellard
                            isa_unassign_ioport(r->addr + 2, 1);
408 0ac32c83 bellard
                        } else {
409 0ac32c83 bellard
                            isa_unassign_ioport(r->addr, r->size);
410 0ac32c83 bellard
                        }
411 0ac32c83 bellard
                    } else {
412 502a5395 pbrook
                        cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
413 5fafdf24 ths
                                                     r->size,
414 0ac32c83 bellard
                                                     IO_MEM_UNASSIGNED);
415 f65ed4c1 aliguori
                        qemu_unregister_coalesced_mmio(r->addr, r->size);
416 0ac32c83 bellard
                    }
417 0ac32c83 bellard
                }
418 0ac32c83 bellard
                r->addr = new_addr;
419 0ac32c83 bellard
                if (r->addr != -1) {
420 0ac32c83 bellard
                    r->map_func(d, i, r->addr, r->size, r->type);
421 0ac32c83 bellard
                }
422 0ac32c83 bellard
            }
423 0ac32c83 bellard
        }
424 0ac32c83 bellard
    }
425 0ac32c83 bellard
}
426 0ac32c83 bellard
427 5fafdf24 ths
uint32_t pci_default_read_config(PCIDevice *d,
428 0ac32c83 bellard
                                 uint32_t address, int len)
429 69b91039 bellard
{
430 0ac32c83 bellard
    uint32_t val;
431 a2d4e44b ths
432 0ac32c83 bellard
    switch(len) {
433 0ac32c83 bellard
    default:
434 0ac32c83 bellard
    case 4:
435 a2d4e44b ths
        if (address <= 0xfc) {
436 a2d4e44b ths
            val = le32_to_cpu(*(uint32_t *)(d->config + address));
437 a2d4e44b ths
            break;
438 a2d4e44b ths
        }
439 a2d4e44b ths
        /* fall through */
440 a2d4e44b ths
    case 2:
441 a2d4e44b ths
        if (address <= 0xfe) {
442 a2d4e44b ths
            val = le16_to_cpu(*(uint16_t *)(d->config + address));
443 a2d4e44b ths
            break;
444 a2d4e44b ths
        }
445 a2d4e44b ths
        /* fall through */
446 a2d4e44b ths
    case 1:
447 a2d4e44b ths
        val = d->config[address];
448 0ac32c83 bellard
        break;
449 0ac32c83 bellard
    }
450 0ac32c83 bellard
    return val;
451 0ac32c83 bellard
}
452 0ac32c83 bellard
453 5fafdf24 ths
void pci_default_write_config(PCIDevice *d,
454 0ac32c83 bellard
                              uint32_t address, uint32_t val, int len)
455 0ac32c83 bellard
{
456 0ac32c83 bellard
    int can_write, i;
457 7bf5be70 bellard
    uint32_t end, addr;
458 0ac32c83 bellard
459 5fafdf24 ths
    if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) ||
460 8a8696a3 bellard
                     (address >= 0x30 && address < 0x34))) {
461 0ac32c83 bellard
        PCIIORegion *r;
462 0ac32c83 bellard
        int reg;
463 0ac32c83 bellard
464 8a8696a3 bellard
        if ( address >= 0x30 ) {
465 8a8696a3 bellard
            reg = PCI_ROM_SLOT;
466 8a8696a3 bellard
        }else{
467 8a8696a3 bellard
            reg = (address - 0x10) >> 2;
468 8a8696a3 bellard
        }
469 0ac32c83 bellard
        r = &d->io_regions[reg];
470 0ac32c83 bellard
        if (r->size == 0)
471 0ac32c83 bellard
            goto default_config;
472 0ac32c83 bellard
        /* compute the stored value */
473 8a8696a3 bellard
        if (reg == PCI_ROM_SLOT) {
474 8a8696a3 bellard
            /* keep ROM enable bit */
475 8a8696a3 bellard
            val &= (~(r->size - 1)) | 1;
476 8a8696a3 bellard
        } else {
477 8a8696a3 bellard
            val &= ~(r->size - 1);
478 8a8696a3 bellard
            val |= r->type;
479 8a8696a3 bellard
        }
480 8a8696a3 bellard
        *(uint32_t *)(d->config + address) = cpu_to_le32(val);
481 0ac32c83 bellard
        pci_update_mappings(d);
482 69b91039 bellard
        return;
483 0ac32c83 bellard
    }
484 0ac32c83 bellard
 default_config:
485 0ac32c83 bellard
    /* not efficient, but simple */
486 7bf5be70 bellard
    addr = address;
487 0ac32c83 bellard
    for(i = 0; i < len; i++) {
488 0ac32c83 bellard
        /* default read/write accesses */
489 1f62d938 bellard
        switch(d->config[0x0e]) {
490 0ac32c83 bellard
        case 0x00:
491 1f62d938 bellard
        case 0x80:
492 1f62d938 bellard
            switch(addr) {
493 1f62d938 bellard
            case 0x00:
494 1f62d938 bellard
            case 0x01:
495 1f62d938 bellard
            case 0x02:
496 1f62d938 bellard
            case 0x03:
497 c2c5104b aliguori
            case 0x06:
498 c2c5104b aliguori
            case 0x07:
499 1f62d938 bellard
            case 0x08:
500 1f62d938 bellard
            case 0x09:
501 1f62d938 bellard
            case 0x0a:
502 1f62d938 bellard
            case 0x0b:
503 1f62d938 bellard
            case 0x0e:
504 1f62d938 bellard
            case 0x10 ... 0x27: /* base */
505 8098ed41 aurel32
            case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */
506 1f62d938 bellard
            case 0x30 ... 0x33: /* rom */
507 1f62d938 bellard
            case 0x3d:
508 1f62d938 bellard
                can_write = 0;
509 1f62d938 bellard
                break;
510 1f62d938 bellard
            default:
511 1f62d938 bellard
                can_write = 1;
512 1f62d938 bellard
                break;
513 1f62d938 bellard
            }
514 0ac32c83 bellard
            break;
515 0ac32c83 bellard
        default:
516 1f62d938 bellard
        case 0x01:
517 1f62d938 bellard
            switch(addr) {
518 1f62d938 bellard
            case 0x00:
519 1f62d938 bellard
            case 0x01:
520 1f62d938 bellard
            case 0x02:
521 1f62d938 bellard
            case 0x03:
522 c2c5104b aliguori
            case 0x06:
523 c2c5104b aliguori
            case 0x07:
524 1f62d938 bellard
            case 0x08:
525 1f62d938 bellard
            case 0x09:
526 1f62d938 bellard
            case 0x0a:
527 1f62d938 bellard
            case 0x0b:
528 1f62d938 bellard
            case 0x0e:
529 8098ed41 aurel32
            case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */
530 1f62d938 bellard
            case 0x38 ... 0x3b: /* rom */
531 1f62d938 bellard
            case 0x3d:
532 1f62d938 bellard
                can_write = 0;
533 1f62d938 bellard
                break;
534 1f62d938 bellard
            default:
535 1f62d938 bellard
                can_write = 1;
536 1f62d938 bellard
                break;
537 1f62d938 bellard
            }
538 0ac32c83 bellard
            break;
539 0ac32c83 bellard
        }
540 0ac32c83 bellard
        if (can_write) {
541 8098ed41 aurel32
            /* Mask out writes to reserved bits in registers */
542 8098ed41 aurel32
            switch (addr) {
543 475dc65f aurel32
            case 0x05:
544 475dc65f aurel32
                val &= ~PCI_COMMAND_RESERVED_MASK_HI;
545 475dc65f aurel32
                break;
546 8098ed41 aurel32
            case 0x06:
547 8098ed41 aurel32
                val &= ~PCI_STATUS_RESERVED_MASK_LO;
548 8098ed41 aurel32
                break;
549 8098ed41 aurel32
            case 0x07:
550 8098ed41 aurel32
                val &= ~PCI_STATUS_RESERVED_MASK_HI;
551 8098ed41 aurel32
                break;
552 8098ed41 aurel32
            }
553 7bf5be70 bellard
            d->config[addr] = val;
554 0ac32c83 bellard
        }
555 a2d4e44b ths
        if (++addr > 0xff)
556 a2d4e44b ths
                break;
557 0ac32c83 bellard
        val >>= 8;
558 0ac32c83 bellard
    }
559 0ac32c83 bellard
560 0ac32c83 bellard
    end = address + len;
561 0ac32c83 bellard
    if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
562 0ac32c83 bellard
        /* if the command register is modified, we must modify the mappings */
563 0ac32c83 bellard
        pci_update_mappings(d);
564 69b91039 bellard
    }
565 69b91039 bellard
}
566 69b91039 bellard
567 502a5395 pbrook
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
568 69b91039 bellard
{
569 30468f78 bellard
    PCIBus *s = opaque;
570 30468f78 bellard
    PCIDevice *pci_dev;
571 30468f78 bellard
    int config_addr, bus_num;
572 3b46e624 ths
573 69b91039 bellard
#if defined(DEBUG_PCI) && 0
574 69b91039 bellard
    printf("pci_data_write: addr=%08x val=%08x len=%d\n",
575 502a5395 pbrook
           addr, val, len);
576 69b91039 bellard
#endif
577 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
578 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
579 80b3ada7 pbrook
        s = s->next;
580 80b3ada7 pbrook
    if (!s)
581 69b91039 bellard
        return;
582 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
583 69b91039 bellard
    if (!pci_dev)
584 69b91039 bellard
        return;
585 502a5395 pbrook
    config_addr = addr & 0xff;
586 69b91039 bellard
#if defined(DEBUG_PCI)
587 69b91039 bellard
    printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
588 69b91039 bellard
           pci_dev->name, config_addr, val, len);
589 69b91039 bellard
#endif
590 0ac32c83 bellard
    pci_dev->config_write(pci_dev, config_addr, val, len);
591 69b91039 bellard
}
592 69b91039 bellard
593 502a5395 pbrook
uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
594 69b91039 bellard
{
595 30468f78 bellard
    PCIBus *s = opaque;
596 30468f78 bellard
    PCIDevice *pci_dev;
597 30468f78 bellard
    int config_addr, bus_num;
598 69b91039 bellard
    uint32_t val;
599 69b91039 bellard
600 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
601 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
602 80b3ada7 pbrook
        s= s->next;
603 80b3ada7 pbrook
    if (!s)
604 69b91039 bellard
        goto fail;
605 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
606 69b91039 bellard
    if (!pci_dev) {
607 69b91039 bellard
    fail:
608 63ce9e0a bellard
        switch(len) {
609 63ce9e0a bellard
        case 1:
610 63ce9e0a bellard
            val = 0xff;
611 63ce9e0a bellard
            break;
612 63ce9e0a bellard
        case 2:
613 63ce9e0a bellard
            val = 0xffff;
614 63ce9e0a bellard
            break;
615 63ce9e0a bellard
        default:
616 63ce9e0a bellard
        case 4:
617 63ce9e0a bellard
            val = 0xffffffff;
618 63ce9e0a bellard
            break;
619 63ce9e0a bellard
        }
620 69b91039 bellard
        goto the_end;
621 69b91039 bellard
    }
622 502a5395 pbrook
    config_addr = addr & 0xff;
623 69b91039 bellard
    val = pci_dev->config_read(pci_dev, config_addr, len);
624 69b91039 bellard
#if defined(DEBUG_PCI)
625 69b91039 bellard
    printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
626 69b91039 bellard
           pci_dev->name, config_addr, val, len);
627 69b91039 bellard
#endif
628 69b91039 bellard
 the_end:
629 69b91039 bellard
#if defined(DEBUG_PCI) && 0
630 69b91039 bellard
    printf("pci_data_read: addr=%08x val=%08x len=%d\n",
631 502a5395 pbrook
           addr, val, len);
632 69b91039 bellard
#endif
633 69b91039 bellard
    return val;
634 69b91039 bellard
}
635 69b91039 bellard
636 502a5395 pbrook
/***********************************************************/
637 502a5395 pbrook
/* generic PCI irq support */
638 30468f78 bellard
639 502a5395 pbrook
/* 0 <= irq_num <= 3. level must be 0 or 1 */
640 d537cf6c pbrook
static void pci_set_irq(void *opaque, int irq_num, int level)
641 69b91039 bellard
{
642 d537cf6c pbrook
    PCIDevice *pci_dev = (PCIDevice *)opaque;
643 80b3ada7 pbrook
    PCIBus *bus;
644 80b3ada7 pbrook
    int change;
645 3b46e624 ths
646 80b3ada7 pbrook
    change = level - pci_dev->irq_state[irq_num];
647 80b3ada7 pbrook
    if (!change)
648 80b3ada7 pbrook
        return;
649 d2b59317 pbrook
650 d2b59317 pbrook
    pci_dev->irq_state[irq_num] = level;
651 5e966ce6 pbrook
    for (;;) {
652 5e966ce6 pbrook
        bus = pci_dev->bus;
653 80b3ada7 pbrook
        irq_num = bus->map_irq(pci_dev, irq_num);
654 5e966ce6 pbrook
        if (bus->set_irq)
655 5e966ce6 pbrook
            break;
656 80b3ada7 pbrook
        pci_dev = bus->parent_dev;
657 80b3ada7 pbrook
    }
658 80b3ada7 pbrook
    bus->irq_count[irq_num] += change;
659 d2b59317 pbrook
    bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
660 69b91039 bellard
}
661 69b91039 bellard
662 502a5395 pbrook
/***********************************************************/
663 502a5395 pbrook
/* monitor info on PCI */
664 0ac32c83 bellard
665 6650ee6d pbrook
typedef struct {
666 6650ee6d pbrook
    uint16_t class;
667 6650ee6d pbrook
    const char *desc;
668 6650ee6d pbrook
} pci_class_desc;
669 6650ee6d pbrook
670 09bc878a blueswir1
static const pci_class_desc pci_class_descriptions[] =
671 6650ee6d pbrook
{
672 4ca9c76f pbrook
    { 0x0100, "SCSI controller"},
673 6650ee6d pbrook
    { 0x0101, "IDE controller"},
674 dcb5b19a ths
    { 0x0102, "Floppy controller"},
675 dcb5b19a ths
    { 0x0103, "IPI controller"},
676 dcb5b19a ths
    { 0x0104, "RAID controller"},
677 dcb5b19a ths
    { 0x0106, "SATA controller"},
678 dcb5b19a ths
    { 0x0107, "SAS controller"},
679 dcb5b19a ths
    { 0x0180, "Storage controller"},
680 6650ee6d pbrook
    { 0x0200, "Ethernet controller"},
681 dcb5b19a ths
    { 0x0201, "Token Ring controller"},
682 dcb5b19a ths
    { 0x0202, "FDDI controller"},
683 dcb5b19a ths
    { 0x0203, "ATM controller"},
684 dcb5b19a ths
    { 0x0280, "Network controller"},
685 6650ee6d pbrook
    { 0x0300, "VGA controller"},
686 dcb5b19a ths
    { 0x0301, "XGA controller"},
687 dcb5b19a ths
    { 0x0302, "3D controller"},
688 dcb5b19a ths
    { 0x0380, "Display controller"},
689 dcb5b19a ths
    { 0x0400, "Video controller"},
690 dcb5b19a ths
    { 0x0401, "Audio controller"},
691 dcb5b19a ths
    { 0x0402, "Phone"},
692 dcb5b19a ths
    { 0x0480, "Multimedia controller"},
693 dcb5b19a ths
    { 0x0500, "RAM controller"},
694 dcb5b19a ths
    { 0x0501, "Flash controller"},
695 dcb5b19a ths
    { 0x0580, "Memory controller"},
696 6650ee6d pbrook
    { 0x0600, "Host bridge"},
697 6650ee6d pbrook
    { 0x0601, "ISA bridge"},
698 dcb5b19a ths
    { 0x0602, "EISA bridge"},
699 dcb5b19a ths
    { 0x0603, "MC bridge"},
700 6650ee6d pbrook
    { 0x0604, "PCI bridge"},
701 dcb5b19a ths
    { 0x0605, "PCMCIA bridge"},
702 dcb5b19a ths
    { 0x0606, "NUBUS bridge"},
703 dcb5b19a ths
    { 0x0607, "CARDBUS bridge"},
704 dcb5b19a ths
    { 0x0608, "RACEWAY bridge"},
705 dcb5b19a ths
    { 0x0680, "Bridge"},
706 6650ee6d pbrook
    { 0x0c03, "USB controller"},
707 6650ee6d pbrook
    { 0, NULL}
708 6650ee6d pbrook
};
709 6650ee6d pbrook
710 502a5395 pbrook
static void pci_info_device(PCIDevice *d)
711 30468f78 bellard
{
712 376253ec aliguori
    Monitor *mon = cur_mon;
713 502a5395 pbrook
    int i, class;
714 502a5395 pbrook
    PCIIORegion *r;
715 09bc878a blueswir1
    const pci_class_desc *desc;
716 30468f78 bellard
717 376253ec aliguori
    monitor_printf(mon, "  Bus %2d, device %3d, function %d:\n",
718 376253ec aliguori
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
719 502a5395 pbrook
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
720 376253ec aliguori
    monitor_printf(mon, "    ");
721 6650ee6d pbrook
    desc = pci_class_descriptions;
722 6650ee6d pbrook
    while (desc->desc && class != desc->class)
723 6650ee6d pbrook
        desc++;
724 6650ee6d pbrook
    if (desc->desc) {
725 376253ec aliguori
        monitor_printf(mon, "%s", desc->desc);
726 6650ee6d pbrook
    } else {
727 376253ec aliguori
        monitor_printf(mon, "Class %04x", class);
728 72cc6cfe bellard
    }
729 376253ec aliguori
    monitor_printf(mon, ": PCI device %04x:%04x\n",
730 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
731 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
732 30468f78 bellard
733 502a5395 pbrook
    if (d->config[PCI_INTERRUPT_PIN] != 0) {
734 376253ec aliguori
        monitor_printf(mon, "      IRQ %d.\n",
735 376253ec aliguori
                       d->config[PCI_INTERRUPT_LINE]);
736 30468f78 bellard
    }
737 80b3ada7 pbrook
    if (class == 0x0604) {
738 376253ec aliguori
        monitor_printf(mon, "      BUS %d.\n", d->config[0x19]);
739 80b3ada7 pbrook
    }
740 502a5395 pbrook
    for(i = 0;i < PCI_NUM_REGIONS; i++) {
741 502a5395 pbrook
        r = &d->io_regions[i];
742 502a5395 pbrook
        if (r->size != 0) {
743 376253ec aliguori
            monitor_printf(mon, "      BAR%d: ", i);
744 502a5395 pbrook
            if (r->type & PCI_ADDRESS_SPACE_IO) {
745 376253ec aliguori
                monitor_printf(mon, "I/O at 0x%04x [0x%04x].\n",
746 376253ec aliguori
                               r->addr, r->addr + r->size - 1);
747 502a5395 pbrook
            } else {
748 376253ec aliguori
                monitor_printf(mon, "32 bit memory at 0x%08x [0x%08x].\n",
749 376253ec aliguori
                               r->addr, r->addr + r->size - 1);
750 502a5395 pbrook
            }
751 502a5395 pbrook
        }
752 77d4bc34 bellard
    }
753 80b3ada7 pbrook
    if (class == 0x0604 && d->config[0x19] != 0) {
754 80b3ada7 pbrook
        pci_for_each_device(d->config[0x19], pci_info_device);
755 80b3ada7 pbrook
    }
756 384d8876 bellard
}
757 384d8876 bellard
758 80b3ada7 pbrook
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
759 384d8876 bellard
{
760 502a5395 pbrook
    PCIBus *bus = first_bus;
761 384d8876 bellard
    PCIDevice *d;
762 502a5395 pbrook
    int devfn;
763 3b46e624 ths
764 80b3ada7 pbrook
    while (bus && bus->bus_num != bus_num)
765 80b3ada7 pbrook
        bus = bus->next;
766 502a5395 pbrook
    if (bus) {
767 502a5395 pbrook
        for(devfn = 0; devfn < 256; devfn++) {
768 502a5395 pbrook
            d = bus->devices[devfn];
769 502a5395 pbrook
            if (d)
770 502a5395 pbrook
                fn(d);
771 502a5395 pbrook
        }
772 f2aa58c6 bellard
    }
773 f2aa58c6 bellard
}
774 f2aa58c6 bellard
775 376253ec aliguori
void pci_info(Monitor *mon)
776 f2aa58c6 bellard
{
777 80b3ada7 pbrook
    pci_for_each_device(0, pci_info_device);
778 77d4bc34 bellard
}
779 a41b2ff2 pbrook
780 cb457d76 aliguori
static const char * const pci_nic_models[] = {
781 cb457d76 aliguori
    "ne2k_pci",
782 cb457d76 aliguori
    "i82551",
783 cb457d76 aliguori
    "i82557b",
784 cb457d76 aliguori
    "i82559er",
785 cb457d76 aliguori
    "rtl8139",
786 cb457d76 aliguori
    "e1000",
787 cb457d76 aliguori
    "pcnet",
788 cb457d76 aliguori
    "virtio",
789 cb457d76 aliguori
    NULL
790 cb457d76 aliguori
};
791 cb457d76 aliguori
792 72da4208 aliguori
typedef PCIDevice *(*PCINICInitFn)(PCIBus *, NICInfo *, int);
793 cb457d76 aliguori
794 cb457d76 aliguori
static PCINICInitFn pci_nic_init_fns[] = {
795 cb457d76 aliguori
    pci_ne2000_init,
796 cb457d76 aliguori
    pci_i82551_init,
797 cb457d76 aliguori
    pci_i82557b_init,
798 cb457d76 aliguori
    pci_i82559er_init,
799 cb457d76 aliguori
    pci_rtl8139_init,
800 cb457d76 aliguori
    pci_e1000_init,
801 cb457d76 aliguori
    pci_pcnet_init,
802 cb457d76 aliguori
    virtio_net_init,
803 cb457d76 aliguori
    NULL
804 cb457d76 aliguori
};
805 cb457d76 aliguori
806 a41b2ff2 pbrook
/* Initialize a PCI NIC.  */
807 72da4208 aliguori
PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
808 cb457d76 aliguori
                  const char *default_model)
809 a41b2ff2 pbrook
{
810 72da4208 aliguori
    PCIDevice *pci_dev;
811 cb457d76 aliguori
    int i;
812 cb457d76 aliguori
813 cb457d76 aliguori
    qemu_check_nic_model_list(nd, pci_nic_models, default_model);
814 cb457d76 aliguori
815 cb457d76 aliguori
    for (i = 0; pci_nic_models[i]; i++)
816 72da4208 aliguori
        if (strcmp(nd->model, pci_nic_models[i]) == 0) {
817 72da4208 aliguori
            pci_dev = pci_nic_init_fns[i](bus, nd, devfn);
818 72da4208 aliguori
            if (pci_dev)
819 72da4208 aliguori
                nd->private = pci_dev;
820 72da4208 aliguori
            return pci_dev;
821 72da4208 aliguori
        }
822 72da4208 aliguori
823 72da4208 aliguori
    return NULL;
824 a41b2ff2 pbrook
}
825 a41b2ff2 pbrook
826 80b3ada7 pbrook
typedef struct {
827 80b3ada7 pbrook
    PCIDevice dev;
828 80b3ada7 pbrook
    PCIBus *bus;
829 80b3ada7 pbrook
} PCIBridge;
830 80b3ada7 pbrook
831 9596ebb7 pbrook
static void pci_bridge_write_config(PCIDevice *d,
832 80b3ada7 pbrook
                             uint32_t address, uint32_t val, int len)
833 80b3ada7 pbrook
{
834 80b3ada7 pbrook
    PCIBridge *s = (PCIBridge *)d;
835 80b3ada7 pbrook
836 80b3ada7 pbrook
    if (address == 0x19 || (address == 0x18 && len > 1)) {
837 80b3ada7 pbrook
        if (address == 0x19)
838 80b3ada7 pbrook
            s->bus->bus_num = val & 0xff;
839 80b3ada7 pbrook
        else
840 80b3ada7 pbrook
            s->bus->bus_num = (val >> 8) & 0xff;
841 80b3ada7 pbrook
#if defined(DEBUG_PCI)
842 80b3ada7 pbrook
        printf ("pci-bridge: %s: Assigned bus %d\n", d->name, s->bus->bus_num);
843 80b3ada7 pbrook
#endif
844 80b3ada7 pbrook
    }
845 80b3ada7 pbrook
    pci_default_write_config(d, address, val, len);
846 80b3ada7 pbrook
}
847 80b3ada7 pbrook
848 3ae80618 aliguori
PCIBus *pci_find_bus(int bus_num)
849 3ae80618 aliguori
{
850 3ae80618 aliguori
    PCIBus *bus = first_bus;
851 3ae80618 aliguori
852 3ae80618 aliguori
    while (bus && bus->bus_num != bus_num)
853 3ae80618 aliguori
        bus = bus->next;
854 3ae80618 aliguori
855 3ae80618 aliguori
    return bus;
856 3ae80618 aliguori
}
857 3ae80618 aliguori
858 3ae80618 aliguori
PCIDevice *pci_find_device(int bus_num, int slot, int function)
859 3ae80618 aliguori
{
860 3ae80618 aliguori
    PCIBus *bus = pci_find_bus(bus_num);
861 3ae80618 aliguori
862 3ae80618 aliguori
    if (!bus)
863 3ae80618 aliguori
        return NULL;
864 3ae80618 aliguori
865 3ae80618 aliguori
    return bus->devices[PCI_DEVFN(slot, function)];
866 3ae80618 aliguori
}
867 3ae80618 aliguori
868 480b9f24 blueswir1
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
869 80b3ada7 pbrook
                        pci_map_irq_fn map_irq, const char *name)
870 80b3ada7 pbrook
{
871 80b3ada7 pbrook
    PCIBridge *s;
872 5fafdf24 ths
    s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
873 80b3ada7 pbrook
                                         devfn, NULL, pci_bridge_write_config);
874 480b9f24 blueswir1
875 480b9f24 blueswir1
    pci_config_set_vendor_id(s->dev.config, vid);
876 480b9f24 blueswir1
    pci_config_set_device_id(s->dev.config, did);
877 480b9f24 blueswir1
878 80b3ada7 pbrook
    s->dev.config[0x04] = 0x06; // command = bus master, pci mem
879 80b3ada7 pbrook
    s->dev.config[0x05] = 0x00;
880 80b3ada7 pbrook
    s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
881 80b3ada7 pbrook
    s->dev.config[0x07] = 0x00; // status = fast devsel
882 80b3ada7 pbrook
    s->dev.config[0x08] = 0x00; // revision
883 80b3ada7 pbrook
    s->dev.config[0x09] = 0x00; // programming i/f
884 173a543b blueswir1
    pci_config_set_class(s->dev.config, PCI_CLASS_BRIDGE_PCI);
885 80b3ada7 pbrook
    s->dev.config[0x0D] = 0x10; // latency_timer
886 80b3ada7 pbrook
    s->dev.config[0x0E] = 0x81; // header_type
887 80b3ada7 pbrook
    s->dev.config[0x1E] = 0xa0; // secondary status
888 80b3ada7 pbrook
889 80b3ada7 pbrook
    s->bus = pci_register_secondary_bus(&s->dev, map_irq);
890 80b3ada7 pbrook
    return s->bus;
891 80b3ada7 pbrook
}