Statistics
| Branch: | Revision:

root / hw / pci.c @ d78f3995

History | View | Annotate | Download (24.2 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 1f62d938 bellard
            case 0x08:
498 1f62d938 bellard
            case 0x09:
499 1f62d938 bellard
            case 0x0a:
500 1f62d938 bellard
            case 0x0b:
501 1f62d938 bellard
            case 0x0e:
502 1f62d938 bellard
            case 0x10 ... 0x27: /* base */
503 8098ed41 aurel32
            case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */
504 1f62d938 bellard
            case 0x30 ... 0x33: /* rom */
505 1f62d938 bellard
            case 0x3d:
506 1f62d938 bellard
                can_write = 0;
507 1f62d938 bellard
                break;
508 1f62d938 bellard
            default:
509 1f62d938 bellard
                can_write = 1;
510 1f62d938 bellard
                break;
511 1f62d938 bellard
            }
512 0ac32c83 bellard
            break;
513 0ac32c83 bellard
        default:
514 1f62d938 bellard
        case 0x01:
515 1f62d938 bellard
            switch(addr) {
516 1f62d938 bellard
            case 0x00:
517 1f62d938 bellard
            case 0x01:
518 1f62d938 bellard
            case 0x02:
519 1f62d938 bellard
            case 0x03:
520 1f62d938 bellard
            case 0x08:
521 1f62d938 bellard
            case 0x09:
522 1f62d938 bellard
            case 0x0a:
523 1f62d938 bellard
            case 0x0b:
524 1f62d938 bellard
            case 0x0e:
525 8098ed41 aurel32
            case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */
526 1f62d938 bellard
            case 0x38 ... 0x3b: /* rom */
527 1f62d938 bellard
            case 0x3d:
528 1f62d938 bellard
                can_write = 0;
529 1f62d938 bellard
                break;
530 1f62d938 bellard
            default:
531 1f62d938 bellard
                can_write = 1;
532 1f62d938 bellard
                break;
533 1f62d938 bellard
            }
534 0ac32c83 bellard
            break;
535 0ac32c83 bellard
        }
536 0ac32c83 bellard
        if (can_write) {
537 8098ed41 aurel32
            /* Mask out writes to reserved bits in registers */
538 8098ed41 aurel32
            switch (addr) {
539 475dc65f aurel32
            case 0x05:
540 475dc65f aurel32
                val &= ~PCI_COMMAND_RESERVED_MASK_HI;
541 475dc65f aurel32
                break;
542 8098ed41 aurel32
            case 0x06:
543 8098ed41 aurel32
                val &= ~PCI_STATUS_RESERVED_MASK_LO;
544 8098ed41 aurel32
                break;
545 8098ed41 aurel32
            case 0x07:
546 8098ed41 aurel32
                val &= ~PCI_STATUS_RESERVED_MASK_HI;
547 8098ed41 aurel32
                break;
548 8098ed41 aurel32
            }
549 7bf5be70 bellard
            d->config[addr] = val;
550 0ac32c83 bellard
        }
551 a2d4e44b ths
        if (++addr > 0xff)
552 a2d4e44b ths
                break;
553 0ac32c83 bellard
        val >>= 8;
554 0ac32c83 bellard
    }
555 0ac32c83 bellard
556 0ac32c83 bellard
    end = address + len;
557 0ac32c83 bellard
    if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
558 0ac32c83 bellard
        /* if the command register is modified, we must modify the mappings */
559 0ac32c83 bellard
        pci_update_mappings(d);
560 69b91039 bellard
    }
561 69b91039 bellard
}
562 69b91039 bellard
563 502a5395 pbrook
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
564 69b91039 bellard
{
565 30468f78 bellard
    PCIBus *s = opaque;
566 30468f78 bellard
    PCIDevice *pci_dev;
567 30468f78 bellard
    int config_addr, bus_num;
568 3b46e624 ths
569 69b91039 bellard
#if defined(DEBUG_PCI) && 0
570 69b91039 bellard
    printf("pci_data_write: addr=%08x val=%08x len=%d\n",
571 502a5395 pbrook
           addr, val, len);
572 69b91039 bellard
#endif
573 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
574 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
575 80b3ada7 pbrook
        s = s->next;
576 80b3ada7 pbrook
    if (!s)
577 69b91039 bellard
        return;
578 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
579 69b91039 bellard
    if (!pci_dev)
580 69b91039 bellard
        return;
581 502a5395 pbrook
    config_addr = addr & 0xff;
582 69b91039 bellard
#if defined(DEBUG_PCI)
583 69b91039 bellard
    printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
584 69b91039 bellard
           pci_dev->name, config_addr, val, len);
585 69b91039 bellard
#endif
586 0ac32c83 bellard
    pci_dev->config_write(pci_dev, config_addr, val, len);
587 69b91039 bellard
}
588 69b91039 bellard
589 502a5395 pbrook
uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
590 69b91039 bellard
{
591 30468f78 bellard
    PCIBus *s = opaque;
592 30468f78 bellard
    PCIDevice *pci_dev;
593 30468f78 bellard
    int config_addr, bus_num;
594 69b91039 bellard
    uint32_t val;
595 69b91039 bellard
596 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
597 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
598 80b3ada7 pbrook
        s= s->next;
599 80b3ada7 pbrook
    if (!s)
600 69b91039 bellard
        goto fail;
601 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
602 69b91039 bellard
    if (!pci_dev) {
603 69b91039 bellard
    fail:
604 63ce9e0a bellard
        switch(len) {
605 63ce9e0a bellard
        case 1:
606 63ce9e0a bellard
            val = 0xff;
607 63ce9e0a bellard
            break;
608 63ce9e0a bellard
        case 2:
609 63ce9e0a bellard
            val = 0xffff;
610 63ce9e0a bellard
            break;
611 63ce9e0a bellard
        default:
612 63ce9e0a bellard
        case 4:
613 63ce9e0a bellard
            val = 0xffffffff;
614 63ce9e0a bellard
            break;
615 63ce9e0a bellard
        }
616 69b91039 bellard
        goto the_end;
617 69b91039 bellard
    }
618 502a5395 pbrook
    config_addr = addr & 0xff;
619 69b91039 bellard
    val = pci_dev->config_read(pci_dev, config_addr, len);
620 69b91039 bellard
#if defined(DEBUG_PCI)
621 69b91039 bellard
    printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
622 69b91039 bellard
           pci_dev->name, config_addr, val, len);
623 69b91039 bellard
#endif
624 69b91039 bellard
 the_end:
625 69b91039 bellard
#if defined(DEBUG_PCI) && 0
626 69b91039 bellard
    printf("pci_data_read: addr=%08x val=%08x len=%d\n",
627 502a5395 pbrook
           addr, val, len);
628 69b91039 bellard
#endif
629 69b91039 bellard
    return val;
630 69b91039 bellard
}
631 69b91039 bellard
632 502a5395 pbrook
/***********************************************************/
633 502a5395 pbrook
/* generic PCI irq support */
634 30468f78 bellard
635 502a5395 pbrook
/* 0 <= irq_num <= 3. level must be 0 or 1 */
636 d537cf6c pbrook
static void pci_set_irq(void *opaque, int irq_num, int level)
637 69b91039 bellard
{
638 d537cf6c pbrook
    PCIDevice *pci_dev = (PCIDevice *)opaque;
639 80b3ada7 pbrook
    PCIBus *bus;
640 80b3ada7 pbrook
    int change;
641 3b46e624 ths
642 80b3ada7 pbrook
    change = level - pci_dev->irq_state[irq_num];
643 80b3ada7 pbrook
    if (!change)
644 80b3ada7 pbrook
        return;
645 d2b59317 pbrook
646 d2b59317 pbrook
    pci_dev->irq_state[irq_num] = level;
647 5e966ce6 pbrook
    for (;;) {
648 5e966ce6 pbrook
        bus = pci_dev->bus;
649 80b3ada7 pbrook
        irq_num = bus->map_irq(pci_dev, irq_num);
650 5e966ce6 pbrook
        if (bus->set_irq)
651 5e966ce6 pbrook
            break;
652 80b3ada7 pbrook
        pci_dev = bus->parent_dev;
653 80b3ada7 pbrook
    }
654 80b3ada7 pbrook
    bus->irq_count[irq_num] += change;
655 d2b59317 pbrook
    bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
656 69b91039 bellard
}
657 69b91039 bellard
658 502a5395 pbrook
/***********************************************************/
659 502a5395 pbrook
/* monitor info on PCI */
660 0ac32c83 bellard
661 6650ee6d pbrook
typedef struct {
662 6650ee6d pbrook
    uint16_t class;
663 6650ee6d pbrook
    const char *desc;
664 6650ee6d pbrook
} pci_class_desc;
665 6650ee6d pbrook
666 09bc878a blueswir1
static const pci_class_desc pci_class_descriptions[] =
667 6650ee6d pbrook
{
668 4ca9c76f pbrook
    { 0x0100, "SCSI controller"},
669 6650ee6d pbrook
    { 0x0101, "IDE controller"},
670 dcb5b19a ths
    { 0x0102, "Floppy controller"},
671 dcb5b19a ths
    { 0x0103, "IPI controller"},
672 dcb5b19a ths
    { 0x0104, "RAID controller"},
673 dcb5b19a ths
    { 0x0106, "SATA controller"},
674 dcb5b19a ths
    { 0x0107, "SAS controller"},
675 dcb5b19a ths
    { 0x0180, "Storage controller"},
676 6650ee6d pbrook
    { 0x0200, "Ethernet controller"},
677 dcb5b19a ths
    { 0x0201, "Token Ring controller"},
678 dcb5b19a ths
    { 0x0202, "FDDI controller"},
679 dcb5b19a ths
    { 0x0203, "ATM controller"},
680 dcb5b19a ths
    { 0x0280, "Network controller"},
681 6650ee6d pbrook
    { 0x0300, "VGA controller"},
682 dcb5b19a ths
    { 0x0301, "XGA controller"},
683 dcb5b19a ths
    { 0x0302, "3D controller"},
684 dcb5b19a ths
    { 0x0380, "Display controller"},
685 dcb5b19a ths
    { 0x0400, "Video controller"},
686 dcb5b19a ths
    { 0x0401, "Audio controller"},
687 dcb5b19a ths
    { 0x0402, "Phone"},
688 dcb5b19a ths
    { 0x0480, "Multimedia controller"},
689 dcb5b19a ths
    { 0x0500, "RAM controller"},
690 dcb5b19a ths
    { 0x0501, "Flash controller"},
691 dcb5b19a ths
    { 0x0580, "Memory controller"},
692 6650ee6d pbrook
    { 0x0600, "Host bridge"},
693 6650ee6d pbrook
    { 0x0601, "ISA bridge"},
694 dcb5b19a ths
    { 0x0602, "EISA bridge"},
695 dcb5b19a ths
    { 0x0603, "MC bridge"},
696 6650ee6d pbrook
    { 0x0604, "PCI bridge"},
697 dcb5b19a ths
    { 0x0605, "PCMCIA bridge"},
698 dcb5b19a ths
    { 0x0606, "NUBUS bridge"},
699 dcb5b19a ths
    { 0x0607, "CARDBUS bridge"},
700 dcb5b19a ths
    { 0x0608, "RACEWAY bridge"},
701 dcb5b19a ths
    { 0x0680, "Bridge"},
702 6650ee6d pbrook
    { 0x0c03, "USB controller"},
703 6650ee6d pbrook
    { 0, NULL}
704 6650ee6d pbrook
};
705 6650ee6d pbrook
706 502a5395 pbrook
static void pci_info_device(PCIDevice *d)
707 30468f78 bellard
{
708 376253ec aliguori
    Monitor *mon = cur_mon;
709 502a5395 pbrook
    int i, class;
710 502a5395 pbrook
    PCIIORegion *r;
711 09bc878a blueswir1
    const pci_class_desc *desc;
712 30468f78 bellard
713 376253ec aliguori
    monitor_printf(mon, "  Bus %2d, device %3d, function %d:\n",
714 376253ec aliguori
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
715 502a5395 pbrook
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
716 376253ec aliguori
    monitor_printf(mon, "    ");
717 6650ee6d pbrook
    desc = pci_class_descriptions;
718 6650ee6d pbrook
    while (desc->desc && class != desc->class)
719 6650ee6d pbrook
        desc++;
720 6650ee6d pbrook
    if (desc->desc) {
721 376253ec aliguori
        monitor_printf(mon, "%s", desc->desc);
722 6650ee6d pbrook
    } else {
723 376253ec aliguori
        monitor_printf(mon, "Class %04x", class);
724 72cc6cfe bellard
    }
725 376253ec aliguori
    monitor_printf(mon, ": PCI device %04x:%04x\n",
726 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
727 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
728 30468f78 bellard
729 502a5395 pbrook
    if (d->config[PCI_INTERRUPT_PIN] != 0) {
730 376253ec aliguori
        monitor_printf(mon, "      IRQ %d.\n",
731 376253ec aliguori
                       d->config[PCI_INTERRUPT_LINE]);
732 30468f78 bellard
    }
733 80b3ada7 pbrook
    if (class == 0x0604) {
734 376253ec aliguori
        monitor_printf(mon, "      BUS %d.\n", d->config[0x19]);
735 80b3ada7 pbrook
    }
736 502a5395 pbrook
    for(i = 0;i < PCI_NUM_REGIONS; i++) {
737 502a5395 pbrook
        r = &d->io_regions[i];
738 502a5395 pbrook
        if (r->size != 0) {
739 376253ec aliguori
            monitor_printf(mon, "      BAR%d: ", i);
740 502a5395 pbrook
            if (r->type & PCI_ADDRESS_SPACE_IO) {
741 376253ec aliguori
                monitor_printf(mon, "I/O at 0x%04x [0x%04x].\n",
742 376253ec aliguori
                               r->addr, r->addr + r->size - 1);
743 502a5395 pbrook
            } else {
744 376253ec aliguori
                monitor_printf(mon, "32 bit memory at 0x%08x [0x%08x].\n",
745 376253ec aliguori
                               r->addr, r->addr + r->size - 1);
746 502a5395 pbrook
            }
747 502a5395 pbrook
        }
748 77d4bc34 bellard
    }
749 80b3ada7 pbrook
    if (class == 0x0604 && d->config[0x19] != 0) {
750 80b3ada7 pbrook
        pci_for_each_device(d->config[0x19], pci_info_device);
751 80b3ada7 pbrook
    }
752 384d8876 bellard
}
753 384d8876 bellard
754 80b3ada7 pbrook
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
755 384d8876 bellard
{
756 502a5395 pbrook
    PCIBus *bus = first_bus;
757 384d8876 bellard
    PCIDevice *d;
758 502a5395 pbrook
    int devfn;
759 3b46e624 ths
760 80b3ada7 pbrook
    while (bus && bus->bus_num != bus_num)
761 80b3ada7 pbrook
        bus = bus->next;
762 502a5395 pbrook
    if (bus) {
763 502a5395 pbrook
        for(devfn = 0; devfn < 256; devfn++) {
764 502a5395 pbrook
            d = bus->devices[devfn];
765 502a5395 pbrook
            if (d)
766 502a5395 pbrook
                fn(d);
767 502a5395 pbrook
        }
768 f2aa58c6 bellard
    }
769 f2aa58c6 bellard
}
770 f2aa58c6 bellard
771 376253ec aliguori
void pci_info(Monitor *mon)
772 f2aa58c6 bellard
{
773 80b3ada7 pbrook
    pci_for_each_device(0, pci_info_device);
774 77d4bc34 bellard
}
775 a41b2ff2 pbrook
776 cb457d76 aliguori
static const char * const pci_nic_models[] = {
777 cb457d76 aliguori
    "ne2k_pci",
778 cb457d76 aliguori
    "i82551",
779 cb457d76 aliguori
    "i82557b",
780 cb457d76 aliguori
    "i82559er",
781 cb457d76 aliguori
    "rtl8139",
782 cb457d76 aliguori
    "e1000",
783 cb457d76 aliguori
    "pcnet",
784 cb457d76 aliguori
    "virtio",
785 cb457d76 aliguori
    NULL
786 cb457d76 aliguori
};
787 cb457d76 aliguori
788 72da4208 aliguori
typedef PCIDevice *(*PCINICInitFn)(PCIBus *, NICInfo *, int);
789 cb457d76 aliguori
790 cb457d76 aliguori
static PCINICInitFn pci_nic_init_fns[] = {
791 cb457d76 aliguori
    pci_ne2000_init,
792 cb457d76 aliguori
    pci_i82551_init,
793 cb457d76 aliguori
    pci_i82557b_init,
794 cb457d76 aliguori
    pci_i82559er_init,
795 cb457d76 aliguori
    pci_rtl8139_init,
796 cb457d76 aliguori
    pci_e1000_init,
797 cb457d76 aliguori
    pci_pcnet_init,
798 cb457d76 aliguori
    virtio_net_init,
799 cb457d76 aliguori
    NULL
800 cb457d76 aliguori
};
801 cb457d76 aliguori
802 a41b2ff2 pbrook
/* Initialize a PCI NIC.  */
803 72da4208 aliguori
PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
804 cb457d76 aliguori
                  const char *default_model)
805 a41b2ff2 pbrook
{
806 72da4208 aliguori
    PCIDevice *pci_dev;
807 cb457d76 aliguori
    int i;
808 cb457d76 aliguori
809 cb457d76 aliguori
    qemu_check_nic_model_list(nd, pci_nic_models, default_model);
810 cb457d76 aliguori
811 cb457d76 aliguori
    for (i = 0; pci_nic_models[i]; i++)
812 72da4208 aliguori
        if (strcmp(nd->model, pci_nic_models[i]) == 0) {
813 72da4208 aliguori
            pci_dev = pci_nic_init_fns[i](bus, nd, devfn);
814 72da4208 aliguori
            if (pci_dev)
815 72da4208 aliguori
                nd->private = pci_dev;
816 72da4208 aliguori
            return pci_dev;
817 72da4208 aliguori
        }
818 72da4208 aliguori
819 72da4208 aliguori
    return NULL;
820 a41b2ff2 pbrook
}
821 a41b2ff2 pbrook
822 80b3ada7 pbrook
typedef struct {
823 80b3ada7 pbrook
    PCIDevice dev;
824 80b3ada7 pbrook
    PCIBus *bus;
825 80b3ada7 pbrook
} PCIBridge;
826 80b3ada7 pbrook
827 9596ebb7 pbrook
static void pci_bridge_write_config(PCIDevice *d,
828 80b3ada7 pbrook
                             uint32_t address, uint32_t val, int len)
829 80b3ada7 pbrook
{
830 80b3ada7 pbrook
    PCIBridge *s = (PCIBridge *)d;
831 80b3ada7 pbrook
832 80b3ada7 pbrook
    if (address == 0x19 || (address == 0x18 && len > 1)) {
833 80b3ada7 pbrook
        if (address == 0x19)
834 80b3ada7 pbrook
            s->bus->bus_num = val & 0xff;
835 80b3ada7 pbrook
        else
836 80b3ada7 pbrook
            s->bus->bus_num = (val >> 8) & 0xff;
837 80b3ada7 pbrook
#if defined(DEBUG_PCI)
838 80b3ada7 pbrook
        printf ("pci-bridge: %s: Assigned bus %d\n", d->name, s->bus->bus_num);
839 80b3ada7 pbrook
#endif
840 80b3ada7 pbrook
    }
841 80b3ada7 pbrook
    pci_default_write_config(d, address, val, len);
842 80b3ada7 pbrook
}
843 80b3ada7 pbrook
844 3ae80618 aliguori
PCIBus *pci_find_bus(int bus_num)
845 3ae80618 aliguori
{
846 3ae80618 aliguori
    PCIBus *bus = first_bus;
847 3ae80618 aliguori
848 3ae80618 aliguori
    while (bus && bus->bus_num != bus_num)
849 3ae80618 aliguori
        bus = bus->next;
850 3ae80618 aliguori
851 3ae80618 aliguori
    return bus;
852 3ae80618 aliguori
}
853 3ae80618 aliguori
854 3ae80618 aliguori
PCIDevice *pci_find_device(int bus_num, int slot, int function)
855 3ae80618 aliguori
{
856 3ae80618 aliguori
    PCIBus *bus = pci_find_bus(bus_num);
857 3ae80618 aliguori
858 3ae80618 aliguori
    if (!bus)
859 3ae80618 aliguori
        return NULL;
860 3ae80618 aliguori
861 3ae80618 aliguori
    return bus->devices[PCI_DEVFN(slot, function)];
862 3ae80618 aliguori
}
863 3ae80618 aliguori
864 480b9f24 blueswir1
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
865 80b3ada7 pbrook
                        pci_map_irq_fn map_irq, const char *name)
866 80b3ada7 pbrook
{
867 80b3ada7 pbrook
    PCIBridge *s;
868 5fafdf24 ths
    s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
869 80b3ada7 pbrook
                                         devfn, NULL, pci_bridge_write_config);
870 480b9f24 blueswir1
871 480b9f24 blueswir1
    pci_config_set_vendor_id(s->dev.config, vid);
872 480b9f24 blueswir1
    pci_config_set_device_id(s->dev.config, did);
873 480b9f24 blueswir1
874 80b3ada7 pbrook
    s->dev.config[0x04] = 0x06; // command = bus master, pci mem
875 80b3ada7 pbrook
    s->dev.config[0x05] = 0x00;
876 80b3ada7 pbrook
    s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
877 80b3ada7 pbrook
    s->dev.config[0x07] = 0x00; // status = fast devsel
878 80b3ada7 pbrook
    s->dev.config[0x08] = 0x00; // revision
879 80b3ada7 pbrook
    s->dev.config[0x09] = 0x00; // programming i/f
880 173a543b blueswir1
    pci_config_set_class(s->dev.config, PCI_CLASS_BRIDGE_PCI);
881 80b3ada7 pbrook
    s->dev.config[0x0D] = 0x10; // latency_timer
882 80b3ada7 pbrook
    s->dev.config[0x0E] = 0x81; // header_type
883 80b3ada7 pbrook
    s->dev.config[0x1E] = 0xa0; // secondary status
884 80b3ada7 pbrook
885 80b3ada7 pbrook
    s->bus = pci_register_secondary_bus(&s->dev, map_irq);
886 80b3ada7 pbrook
    return s->bus;
887 80b3ada7 pbrook
}