Statistics
| Branch: | Revision:

root / hw / pci.c @ abcebc7e

History | View | Annotate | Download (17.6 kB)

1 69b91039 bellard
/*
2 69b91039 bellard
 * QEMU PCI bus manager
3 69b91039 bellard
 *
4 69b91039 bellard
 * Copyright (c) 2004 Fabrice Bellard
5 69b91039 bellard
 * 
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 69b91039 bellard
#include "vl.h"
25 69b91039 bellard
26 69b91039 bellard
//#define DEBUG_PCI
27 69b91039 bellard
28 30468f78 bellard
struct PCIBus {
29 30468f78 bellard
    int bus_num;
30 30468f78 bellard
    int devfn_min;
31 502a5395 pbrook
    pci_set_irq_fn set_irq;
32 d2b59317 pbrook
    pci_map_irq_fn map_irq;
33 30468f78 bellard
    uint32_t config_reg; /* XXX: suppress */
34 384d8876 bellard
    /* low level pic */
35 384d8876 bellard
    SetIRQFunc *low_set_irq;
36 384d8876 bellard
    void *irq_opaque;
37 30468f78 bellard
    PCIDevice *devices[256];
38 80b3ada7 pbrook
    PCIDevice *parent_dev;
39 80b3ada7 pbrook
    PCIBus *next;
40 d2b59317 pbrook
    /* The bus IRQ state is the logical OR of the connected devices.
41 d2b59317 pbrook
       Keep a count of the number of devices with raised IRQs.  */
42 80b3ada7 pbrook
    int irq_count[];
43 30468f78 bellard
};
44 69b91039 bellard
45 1941d19c bellard
static void pci_update_mappings(PCIDevice *d);
46 1941d19c bellard
47 69b91039 bellard
target_phys_addr_t pci_mem_base;
48 0ac32c83 bellard
static int pci_irq_index;
49 30468f78 bellard
static PCIBus *first_bus;
50 30468f78 bellard
51 d2b59317 pbrook
PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
52 80b3ada7 pbrook
                         void *pic, int devfn_min, int nirq)
53 30468f78 bellard
{
54 30468f78 bellard
    PCIBus *bus;
55 80b3ada7 pbrook
    bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
56 502a5395 pbrook
    bus->set_irq = set_irq;
57 d2b59317 pbrook
    bus->map_irq = map_irq;
58 502a5395 pbrook
    bus->irq_opaque = pic;
59 502a5395 pbrook
    bus->devfn_min = devfn_min;
60 30468f78 bellard
    first_bus = bus;
61 30468f78 bellard
    return bus;
62 30468f78 bellard
}
63 69b91039 bellard
64 80b3ada7 pbrook
PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
65 80b3ada7 pbrook
{
66 80b3ada7 pbrook
    PCIBus *bus;
67 80b3ada7 pbrook
    bus = qemu_mallocz(sizeof(PCIBus));
68 80b3ada7 pbrook
    bus->map_irq = map_irq;
69 80b3ada7 pbrook
    bus->parent_dev = dev;
70 80b3ada7 pbrook
    bus->next = dev->bus->next;
71 80b3ada7 pbrook
    dev->bus->next = bus;
72 80b3ada7 pbrook
    return bus;
73 80b3ada7 pbrook
}
74 80b3ada7 pbrook
75 502a5395 pbrook
int pci_bus_num(PCIBus *s)
76 502a5395 pbrook
{
77 502a5395 pbrook
    return s->bus_num;
78 502a5395 pbrook
}
79 502a5395 pbrook
80 1941d19c bellard
void pci_device_save(PCIDevice *s, QEMUFile *f)
81 30ca2aab bellard
{
82 1941d19c bellard
    qemu_put_be32(f, 1); /* PCI device version */
83 30ca2aab bellard
    qemu_put_buffer(f, s->config, 256);
84 30ca2aab bellard
}
85 30ca2aab bellard
86 1941d19c bellard
int pci_device_load(PCIDevice *s, QEMUFile *f)
87 30ca2aab bellard
{
88 1941d19c bellard
    uint32_t version_id;
89 1941d19c bellard
    version_id = qemu_get_be32(f);
90 30ca2aab bellard
    if (version_id != 1)
91 30ca2aab bellard
        return -EINVAL;
92 30ca2aab bellard
    qemu_get_buffer(f, s->config, 256);
93 1941d19c bellard
    pci_update_mappings(s);
94 30ca2aab bellard
    return 0;
95 30ca2aab bellard
}
96 30ca2aab bellard
97 69b91039 bellard
/* -1 for devfn means auto assign */
98 30468f78 bellard
PCIDevice *pci_register_device(PCIBus *bus, const char *name, 
99 30468f78 bellard
                               int instance_size, int devfn,
100 69b91039 bellard
                               PCIConfigReadFunc *config_read, 
101 69b91039 bellard
                               PCIConfigWriteFunc *config_write)
102 69b91039 bellard
{
103 30468f78 bellard
    PCIDevice *pci_dev;
104 69b91039 bellard
105 0ac32c83 bellard
    if (pci_irq_index >= PCI_DEVICES_MAX)
106 0ac32c83 bellard
        return NULL;
107 0ac32c83 bellard
    
108 69b91039 bellard
    if (devfn < 0) {
109 30468f78 bellard
        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
110 30468f78 bellard
            if (!bus->devices[devfn])
111 69b91039 bellard
                goto found;
112 69b91039 bellard
        }
113 69b91039 bellard
        return NULL;
114 69b91039 bellard
    found: ;
115 69b91039 bellard
    }
116 69b91039 bellard
    pci_dev = qemu_mallocz(instance_size);
117 69b91039 bellard
    if (!pci_dev)
118 69b91039 bellard
        return NULL;
119 30468f78 bellard
    pci_dev->bus = bus;
120 69b91039 bellard
    pci_dev->devfn = devfn;
121 69b91039 bellard
    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
122 d2b59317 pbrook
    memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
123 0ac32c83 bellard
124 0ac32c83 bellard
    if (!config_read)
125 0ac32c83 bellard
        config_read = pci_default_read_config;
126 0ac32c83 bellard
    if (!config_write)
127 0ac32c83 bellard
        config_write = pci_default_write_config;
128 69b91039 bellard
    pci_dev->config_read = config_read;
129 69b91039 bellard
    pci_dev->config_write = config_write;
130 0ac32c83 bellard
    pci_dev->irq_index = pci_irq_index++;
131 30468f78 bellard
    bus->devices[devfn] = pci_dev;
132 69b91039 bellard
    return pci_dev;
133 69b91039 bellard
}
134 69b91039 bellard
135 69b91039 bellard
void pci_register_io_region(PCIDevice *pci_dev, int region_num, 
136 69b91039 bellard
                            uint32_t size, int type, 
137 69b91039 bellard
                            PCIMapIORegionFunc *map_func)
138 69b91039 bellard
{
139 69b91039 bellard
    PCIIORegion *r;
140 d7ce493a pbrook
    uint32_t addr;
141 69b91039 bellard
142 8a8696a3 bellard
    if ((unsigned int)region_num >= PCI_NUM_REGIONS)
143 69b91039 bellard
        return;
144 69b91039 bellard
    r = &pci_dev->io_regions[region_num];
145 69b91039 bellard
    r->addr = -1;
146 69b91039 bellard
    r->size = size;
147 69b91039 bellard
    r->type = type;
148 69b91039 bellard
    r->map_func = map_func;
149 d7ce493a pbrook
    if (region_num == PCI_ROM_SLOT) {
150 d7ce493a pbrook
        addr = 0x30;
151 d7ce493a pbrook
    } else {
152 d7ce493a pbrook
        addr = 0x10 + region_num * 4;
153 d7ce493a pbrook
    }
154 d7ce493a pbrook
    *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
155 69b91039 bellard
}
156 69b91039 bellard
157 502a5395 pbrook
target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
158 69b91039 bellard
{
159 502a5395 pbrook
    return addr + pci_mem_base;
160 69b91039 bellard
}
161 69b91039 bellard
162 0ac32c83 bellard
static void pci_update_mappings(PCIDevice *d)
163 0ac32c83 bellard
{
164 0ac32c83 bellard
    PCIIORegion *r;
165 0ac32c83 bellard
    int cmd, i;
166 8a8696a3 bellard
    uint32_t last_addr, new_addr, config_ofs;
167 0ac32c83 bellard
    
168 0ac32c83 bellard
    cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
169 8a8696a3 bellard
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
170 0ac32c83 bellard
        r = &d->io_regions[i];
171 8a8696a3 bellard
        if (i == PCI_ROM_SLOT) {
172 8a8696a3 bellard
            config_ofs = 0x30;
173 8a8696a3 bellard
        } else {
174 8a8696a3 bellard
            config_ofs = 0x10 + i * 4;
175 8a8696a3 bellard
        }
176 0ac32c83 bellard
        if (r->size != 0) {
177 0ac32c83 bellard
            if (r->type & PCI_ADDRESS_SPACE_IO) {
178 0ac32c83 bellard
                if (cmd & PCI_COMMAND_IO) {
179 0ac32c83 bellard
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config + 
180 8a8696a3 bellard
                                                         config_ofs));
181 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
182 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
183 0ac32c83 bellard
                    /* NOTE: we have only 64K ioports on PC */
184 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
185 0ac32c83 bellard
                        last_addr >= 0x10000) {
186 0ac32c83 bellard
                        new_addr = -1;
187 0ac32c83 bellard
                    }
188 0ac32c83 bellard
                } else {
189 0ac32c83 bellard
                    new_addr = -1;
190 0ac32c83 bellard
                }
191 0ac32c83 bellard
            } else {
192 0ac32c83 bellard
                if (cmd & PCI_COMMAND_MEMORY) {
193 0ac32c83 bellard
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config + 
194 8a8696a3 bellard
                                                         config_ofs));
195 8a8696a3 bellard
                    /* the ROM slot has a specific enable bit */
196 8a8696a3 bellard
                    if (i == PCI_ROM_SLOT && !(new_addr & 1))
197 8a8696a3 bellard
                        goto no_mem_map;
198 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
199 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
200 0ac32c83 bellard
                    /* NOTE: we do not support wrapping */
201 0ac32c83 bellard
                    /* XXX: as we cannot support really dynamic
202 0ac32c83 bellard
                       mappings, we handle specific values as invalid
203 0ac32c83 bellard
                       mappings. */
204 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
205 0ac32c83 bellard
                        last_addr == -1) {
206 0ac32c83 bellard
                        new_addr = -1;
207 0ac32c83 bellard
                    }
208 0ac32c83 bellard
                } else {
209 8a8696a3 bellard
                no_mem_map:
210 0ac32c83 bellard
                    new_addr = -1;
211 0ac32c83 bellard
                }
212 0ac32c83 bellard
            }
213 0ac32c83 bellard
            /* now do the real mapping */
214 0ac32c83 bellard
            if (new_addr != r->addr) {
215 0ac32c83 bellard
                if (r->addr != -1) {
216 0ac32c83 bellard
                    if (r->type & PCI_ADDRESS_SPACE_IO) {
217 0ac32c83 bellard
                        int class;
218 0ac32c83 bellard
                        /* NOTE: specific hack for IDE in PC case:
219 0ac32c83 bellard
                           only one byte must be mapped. */
220 0ac32c83 bellard
                        class = d->config[0x0a] | (d->config[0x0b] << 8);
221 0ac32c83 bellard
                        if (class == 0x0101 && r->size == 4) {
222 0ac32c83 bellard
                            isa_unassign_ioport(r->addr + 2, 1);
223 0ac32c83 bellard
                        } else {
224 0ac32c83 bellard
                            isa_unassign_ioport(r->addr, r->size);
225 0ac32c83 bellard
                        }
226 0ac32c83 bellard
                    } else {
227 502a5395 pbrook
                        cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
228 0ac32c83 bellard
                                                     r->size, 
229 0ac32c83 bellard
                                                     IO_MEM_UNASSIGNED);
230 0ac32c83 bellard
                    }
231 0ac32c83 bellard
                }
232 0ac32c83 bellard
                r->addr = new_addr;
233 0ac32c83 bellard
                if (r->addr != -1) {
234 0ac32c83 bellard
                    r->map_func(d, i, r->addr, r->size, r->type);
235 0ac32c83 bellard
                }
236 0ac32c83 bellard
            }
237 0ac32c83 bellard
        }
238 0ac32c83 bellard
    }
239 0ac32c83 bellard
}
240 0ac32c83 bellard
241 0ac32c83 bellard
uint32_t pci_default_read_config(PCIDevice *d, 
242 0ac32c83 bellard
                                 uint32_t address, int len)
243 69b91039 bellard
{
244 0ac32c83 bellard
    uint32_t val;
245 a2d4e44b ths
246 0ac32c83 bellard
    switch(len) {
247 0ac32c83 bellard
    default:
248 0ac32c83 bellard
    case 4:
249 a2d4e44b ths
        if (address <= 0xfc) {
250 a2d4e44b ths
            val = le32_to_cpu(*(uint32_t *)(d->config + address));
251 a2d4e44b ths
            break;
252 a2d4e44b ths
        }
253 a2d4e44b ths
        /* fall through */
254 a2d4e44b ths
    case 2:
255 a2d4e44b ths
        if (address <= 0xfe) {
256 a2d4e44b ths
            val = le16_to_cpu(*(uint16_t *)(d->config + address));
257 a2d4e44b ths
            break;
258 a2d4e44b ths
        }
259 a2d4e44b ths
        /* fall through */
260 a2d4e44b ths
    case 1:
261 a2d4e44b ths
        val = d->config[address];
262 0ac32c83 bellard
        break;
263 0ac32c83 bellard
    }
264 0ac32c83 bellard
    return val;
265 0ac32c83 bellard
}
266 0ac32c83 bellard
267 0ac32c83 bellard
void pci_default_write_config(PCIDevice *d, 
268 0ac32c83 bellard
                              uint32_t address, uint32_t val, int len)
269 0ac32c83 bellard
{
270 0ac32c83 bellard
    int can_write, i;
271 7bf5be70 bellard
    uint32_t end, addr;
272 0ac32c83 bellard
273 8a8696a3 bellard
    if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) || 
274 8a8696a3 bellard
                     (address >= 0x30 && address < 0x34))) {
275 0ac32c83 bellard
        PCIIORegion *r;
276 0ac32c83 bellard
        int reg;
277 0ac32c83 bellard
278 8a8696a3 bellard
        if ( address >= 0x30 ) {
279 8a8696a3 bellard
            reg = PCI_ROM_SLOT;
280 8a8696a3 bellard
        }else{
281 8a8696a3 bellard
            reg = (address - 0x10) >> 2;
282 8a8696a3 bellard
        }
283 0ac32c83 bellard
        r = &d->io_regions[reg];
284 0ac32c83 bellard
        if (r->size == 0)
285 0ac32c83 bellard
            goto default_config;
286 0ac32c83 bellard
        /* compute the stored value */
287 8a8696a3 bellard
        if (reg == PCI_ROM_SLOT) {
288 8a8696a3 bellard
            /* keep ROM enable bit */
289 8a8696a3 bellard
            val &= (~(r->size - 1)) | 1;
290 8a8696a3 bellard
        } else {
291 8a8696a3 bellard
            val &= ~(r->size - 1);
292 8a8696a3 bellard
            val |= r->type;
293 8a8696a3 bellard
        }
294 8a8696a3 bellard
        *(uint32_t *)(d->config + address) = cpu_to_le32(val);
295 0ac32c83 bellard
        pci_update_mappings(d);
296 69b91039 bellard
        return;
297 0ac32c83 bellard
    }
298 0ac32c83 bellard
 default_config:
299 0ac32c83 bellard
    /* not efficient, but simple */
300 7bf5be70 bellard
    addr = address;
301 0ac32c83 bellard
    for(i = 0; i < len; i++) {
302 0ac32c83 bellard
        /* default read/write accesses */
303 1f62d938 bellard
        switch(d->config[0x0e]) {
304 0ac32c83 bellard
        case 0x00:
305 1f62d938 bellard
        case 0x80:
306 1f62d938 bellard
            switch(addr) {
307 1f62d938 bellard
            case 0x00:
308 1f62d938 bellard
            case 0x01:
309 1f62d938 bellard
            case 0x02:
310 1f62d938 bellard
            case 0x03:
311 1f62d938 bellard
            case 0x08:
312 1f62d938 bellard
            case 0x09:
313 1f62d938 bellard
            case 0x0a:
314 1f62d938 bellard
            case 0x0b:
315 1f62d938 bellard
            case 0x0e:
316 1f62d938 bellard
            case 0x10 ... 0x27: /* base */
317 1f62d938 bellard
            case 0x30 ... 0x33: /* rom */
318 1f62d938 bellard
            case 0x3d:
319 1f62d938 bellard
                can_write = 0;
320 1f62d938 bellard
                break;
321 1f62d938 bellard
            default:
322 1f62d938 bellard
                can_write = 1;
323 1f62d938 bellard
                break;
324 1f62d938 bellard
            }
325 0ac32c83 bellard
            break;
326 0ac32c83 bellard
        default:
327 1f62d938 bellard
        case 0x01:
328 1f62d938 bellard
            switch(addr) {
329 1f62d938 bellard
            case 0x00:
330 1f62d938 bellard
            case 0x01:
331 1f62d938 bellard
            case 0x02:
332 1f62d938 bellard
            case 0x03:
333 1f62d938 bellard
            case 0x08:
334 1f62d938 bellard
            case 0x09:
335 1f62d938 bellard
            case 0x0a:
336 1f62d938 bellard
            case 0x0b:
337 1f62d938 bellard
            case 0x0e:
338 1f62d938 bellard
            case 0x38 ... 0x3b: /* rom */
339 1f62d938 bellard
            case 0x3d:
340 1f62d938 bellard
                can_write = 0;
341 1f62d938 bellard
                break;
342 1f62d938 bellard
            default:
343 1f62d938 bellard
                can_write = 1;
344 1f62d938 bellard
                break;
345 1f62d938 bellard
            }
346 0ac32c83 bellard
            break;
347 0ac32c83 bellard
        }
348 0ac32c83 bellard
        if (can_write) {
349 7bf5be70 bellard
            d->config[addr] = val;
350 0ac32c83 bellard
        }
351 a2d4e44b ths
        if (++addr > 0xff)
352 a2d4e44b ths
                break;
353 0ac32c83 bellard
        val >>= 8;
354 0ac32c83 bellard
    }
355 0ac32c83 bellard
356 0ac32c83 bellard
    end = address + len;
357 0ac32c83 bellard
    if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
358 0ac32c83 bellard
        /* if the command register is modified, we must modify the mappings */
359 0ac32c83 bellard
        pci_update_mappings(d);
360 69b91039 bellard
    }
361 69b91039 bellard
}
362 69b91039 bellard
363 502a5395 pbrook
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
364 69b91039 bellard
{
365 30468f78 bellard
    PCIBus *s = opaque;
366 30468f78 bellard
    PCIDevice *pci_dev;
367 30468f78 bellard
    int config_addr, bus_num;
368 69b91039 bellard
    
369 69b91039 bellard
#if defined(DEBUG_PCI) && 0
370 69b91039 bellard
    printf("pci_data_write: addr=%08x val=%08x len=%d\n",
371 502a5395 pbrook
           addr, val, len);
372 69b91039 bellard
#endif
373 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
374 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
375 80b3ada7 pbrook
        s = s->next;
376 80b3ada7 pbrook
    if (!s)
377 69b91039 bellard
        return;
378 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
379 69b91039 bellard
    if (!pci_dev)
380 69b91039 bellard
        return;
381 502a5395 pbrook
    config_addr = addr & 0xff;
382 69b91039 bellard
#if defined(DEBUG_PCI)
383 69b91039 bellard
    printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
384 69b91039 bellard
           pci_dev->name, config_addr, val, len);
385 69b91039 bellard
#endif
386 0ac32c83 bellard
    pci_dev->config_write(pci_dev, config_addr, val, len);
387 69b91039 bellard
}
388 69b91039 bellard
389 502a5395 pbrook
uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
390 69b91039 bellard
{
391 30468f78 bellard
    PCIBus *s = opaque;
392 30468f78 bellard
    PCIDevice *pci_dev;
393 30468f78 bellard
    int config_addr, bus_num;
394 69b91039 bellard
    uint32_t val;
395 69b91039 bellard
396 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
397 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
398 80b3ada7 pbrook
        s= s->next;
399 80b3ada7 pbrook
    if (!s)
400 69b91039 bellard
        goto fail;
401 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
402 69b91039 bellard
    if (!pci_dev) {
403 69b91039 bellard
    fail:
404 63ce9e0a bellard
        switch(len) {
405 63ce9e0a bellard
        case 1:
406 63ce9e0a bellard
            val = 0xff;
407 63ce9e0a bellard
            break;
408 63ce9e0a bellard
        case 2:
409 63ce9e0a bellard
            val = 0xffff;
410 63ce9e0a bellard
            break;
411 63ce9e0a bellard
        default:
412 63ce9e0a bellard
        case 4:
413 63ce9e0a bellard
            val = 0xffffffff;
414 63ce9e0a bellard
            break;
415 63ce9e0a bellard
        }
416 69b91039 bellard
        goto the_end;
417 69b91039 bellard
    }
418 502a5395 pbrook
    config_addr = addr & 0xff;
419 69b91039 bellard
    val = pci_dev->config_read(pci_dev, config_addr, len);
420 69b91039 bellard
#if defined(DEBUG_PCI)
421 69b91039 bellard
    printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
422 69b91039 bellard
           pci_dev->name, config_addr, val, len);
423 69b91039 bellard
#endif
424 69b91039 bellard
 the_end:
425 69b91039 bellard
#if defined(DEBUG_PCI) && 0
426 69b91039 bellard
    printf("pci_data_read: addr=%08x val=%08x len=%d\n",
427 502a5395 pbrook
           addr, val, len);
428 69b91039 bellard
#endif
429 69b91039 bellard
    return val;
430 69b91039 bellard
}
431 69b91039 bellard
432 502a5395 pbrook
/***********************************************************/
433 502a5395 pbrook
/* generic PCI irq support */
434 30468f78 bellard
435 502a5395 pbrook
/* 0 <= irq_num <= 3. level must be 0 or 1 */
436 502a5395 pbrook
void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
437 69b91039 bellard
{
438 80b3ada7 pbrook
    PCIBus *bus;
439 80b3ada7 pbrook
    int change;
440 80b3ada7 pbrook
    
441 80b3ada7 pbrook
    change = level - pci_dev->irq_state[irq_num];
442 80b3ada7 pbrook
    if (!change)
443 80b3ada7 pbrook
        return;
444 d2b59317 pbrook
445 d2b59317 pbrook
    pci_dev->irq_state[irq_num] = level;
446 5e966ce6 pbrook
    for (;;) {
447 5e966ce6 pbrook
        bus = pci_dev->bus;
448 80b3ada7 pbrook
        irq_num = bus->map_irq(pci_dev, irq_num);
449 5e966ce6 pbrook
        if (bus->set_irq)
450 5e966ce6 pbrook
            break;
451 80b3ada7 pbrook
        pci_dev = bus->parent_dev;
452 80b3ada7 pbrook
    }
453 80b3ada7 pbrook
    bus->irq_count[irq_num] += change;
454 d2b59317 pbrook
    bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
455 69b91039 bellard
}
456 69b91039 bellard
457 502a5395 pbrook
/***********************************************************/
458 502a5395 pbrook
/* monitor info on PCI */
459 0ac32c83 bellard
460 6650ee6d pbrook
typedef struct {
461 6650ee6d pbrook
    uint16_t class;
462 6650ee6d pbrook
    const char *desc;
463 6650ee6d pbrook
} pci_class_desc;
464 6650ee6d pbrook
465 6650ee6d pbrook
static pci_class_desc pci_class_descriptions[] = 
466 6650ee6d pbrook
{
467 4ca9c76f pbrook
    { 0x0100, "SCSI controller"},
468 6650ee6d pbrook
    { 0x0101, "IDE controller"},
469 6650ee6d pbrook
    { 0x0200, "Ethernet controller"},
470 6650ee6d pbrook
    { 0x0300, "VGA controller"},
471 6650ee6d pbrook
    { 0x0600, "Host bridge"},
472 6650ee6d pbrook
    { 0x0601, "ISA bridge"},
473 6650ee6d pbrook
    { 0x0604, "PCI bridge"},
474 6650ee6d pbrook
    { 0x0c03, "USB controller"},
475 6650ee6d pbrook
    { 0, NULL}
476 6650ee6d pbrook
};
477 6650ee6d pbrook
478 502a5395 pbrook
static void pci_info_device(PCIDevice *d)
479 30468f78 bellard
{
480 502a5395 pbrook
    int i, class;
481 502a5395 pbrook
    PCIIORegion *r;
482 6650ee6d pbrook
    pci_class_desc *desc;
483 30468f78 bellard
484 502a5395 pbrook
    term_printf("  Bus %2d, device %3d, function %d:\n",
485 502a5395 pbrook
           d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
486 502a5395 pbrook
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
487 502a5395 pbrook
    term_printf("    ");
488 6650ee6d pbrook
    desc = pci_class_descriptions;
489 6650ee6d pbrook
    while (desc->desc && class != desc->class)
490 6650ee6d pbrook
        desc++;
491 6650ee6d pbrook
    if (desc->desc) {
492 6650ee6d pbrook
        term_printf("%s", desc->desc);
493 6650ee6d pbrook
    } else {
494 502a5395 pbrook
        term_printf("Class %04x", class);
495 72cc6cfe bellard
    }
496 502a5395 pbrook
    term_printf(": PCI device %04x:%04x\n",
497 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
498 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
499 30468f78 bellard
500 502a5395 pbrook
    if (d->config[PCI_INTERRUPT_PIN] != 0) {
501 502a5395 pbrook
        term_printf("      IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
502 30468f78 bellard
    }
503 80b3ada7 pbrook
    if (class == 0x0604) {
504 80b3ada7 pbrook
        term_printf("      BUS %d.\n", d->config[0x19]);
505 80b3ada7 pbrook
    }
506 502a5395 pbrook
    for(i = 0;i < PCI_NUM_REGIONS; i++) {
507 502a5395 pbrook
        r = &d->io_regions[i];
508 502a5395 pbrook
        if (r->size != 0) {
509 502a5395 pbrook
            term_printf("      BAR%d: ", i);
510 502a5395 pbrook
            if (r->type & PCI_ADDRESS_SPACE_IO) {
511 502a5395 pbrook
                term_printf("I/O at 0x%04x [0x%04x].\n", 
512 502a5395 pbrook
                       r->addr, r->addr + r->size - 1);
513 502a5395 pbrook
            } else {
514 502a5395 pbrook
                term_printf("32 bit memory at 0x%08x [0x%08x].\n", 
515 502a5395 pbrook
                       r->addr, r->addr + r->size - 1);
516 502a5395 pbrook
            }
517 502a5395 pbrook
        }
518 77d4bc34 bellard
    }
519 80b3ada7 pbrook
    if (class == 0x0604 && d->config[0x19] != 0) {
520 80b3ada7 pbrook
        pci_for_each_device(d->config[0x19], pci_info_device);
521 80b3ada7 pbrook
    }
522 384d8876 bellard
}
523 384d8876 bellard
524 80b3ada7 pbrook
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
525 384d8876 bellard
{
526 502a5395 pbrook
    PCIBus *bus = first_bus;
527 384d8876 bellard
    PCIDevice *d;
528 502a5395 pbrook
    int devfn;
529 384d8876 bellard
    
530 80b3ada7 pbrook
    while (bus && bus->bus_num != bus_num)
531 80b3ada7 pbrook
        bus = bus->next;
532 502a5395 pbrook
    if (bus) {
533 502a5395 pbrook
        for(devfn = 0; devfn < 256; devfn++) {
534 502a5395 pbrook
            d = bus->devices[devfn];
535 502a5395 pbrook
            if (d)
536 502a5395 pbrook
                fn(d);
537 502a5395 pbrook
        }
538 f2aa58c6 bellard
    }
539 f2aa58c6 bellard
}
540 f2aa58c6 bellard
541 502a5395 pbrook
void pci_info(void)
542 f2aa58c6 bellard
{
543 80b3ada7 pbrook
    pci_for_each_device(0, pci_info_device);
544 77d4bc34 bellard
}
545 a41b2ff2 pbrook
546 a41b2ff2 pbrook
/* Initialize a PCI NIC.  */
547 abcebc7e ths
void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn)
548 a41b2ff2 pbrook
{
549 a41b2ff2 pbrook
    if (strcmp(nd->model, "ne2k_pci") == 0) {
550 abcebc7e ths
        pci_ne2000_init(bus, nd, devfn);
551 a41b2ff2 pbrook
    } else if (strcmp(nd->model, "rtl8139") == 0) {
552 abcebc7e ths
        pci_rtl8139_init(bus, nd, devfn);
553 e3c2613f bellard
    } else if (strcmp(nd->model, "pcnet") == 0) {
554 abcebc7e ths
        pci_pcnet_init(bus, nd, devfn);
555 a41b2ff2 pbrook
    } else {
556 a41b2ff2 pbrook
        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
557 a41b2ff2 pbrook
        exit (1);
558 a41b2ff2 pbrook
    }
559 a41b2ff2 pbrook
}
560 a41b2ff2 pbrook
561 80b3ada7 pbrook
typedef struct {
562 80b3ada7 pbrook
    PCIDevice dev;
563 80b3ada7 pbrook
    PCIBus *bus;
564 80b3ada7 pbrook
} PCIBridge;
565 80b3ada7 pbrook
566 80b3ada7 pbrook
void pci_bridge_write_config(PCIDevice *d, 
567 80b3ada7 pbrook
                             uint32_t address, uint32_t val, int len)
568 80b3ada7 pbrook
{
569 80b3ada7 pbrook
    PCIBridge *s = (PCIBridge *)d;
570 80b3ada7 pbrook
571 80b3ada7 pbrook
    if (address == 0x19 || (address == 0x18 && len > 1)) {
572 80b3ada7 pbrook
        if (address == 0x19)
573 80b3ada7 pbrook
            s->bus->bus_num = val & 0xff;
574 80b3ada7 pbrook
        else
575 80b3ada7 pbrook
            s->bus->bus_num = (val >> 8) & 0xff;
576 80b3ada7 pbrook
#if defined(DEBUG_PCI)
577 80b3ada7 pbrook
        printf ("pci-bridge: %s: Assigned bus %d\n", d->name, s->bus->bus_num);
578 80b3ada7 pbrook
#endif
579 80b3ada7 pbrook
    }
580 80b3ada7 pbrook
    pci_default_write_config(d, address, val, len);
581 80b3ada7 pbrook
}
582 80b3ada7 pbrook
583 80b3ada7 pbrook
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
584 80b3ada7 pbrook
                        pci_map_irq_fn map_irq, const char *name)
585 80b3ada7 pbrook
{
586 80b3ada7 pbrook
    PCIBridge *s;
587 80b3ada7 pbrook
    s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge), 
588 80b3ada7 pbrook
                                         devfn, NULL, pci_bridge_write_config);
589 80b3ada7 pbrook
    s->dev.config[0x00] = id >> 16;
590 80b3ada7 pbrook
    s->dev.config[0x01] = id > 24;
591 80b3ada7 pbrook
    s->dev.config[0x02] = id; // device_id
592 80b3ada7 pbrook
    s->dev.config[0x03] = id >> 8;
593 80b3ada7 pbrook
    s->dev.config[0x04] = 0x06; // command = bus master, pci mem
594 80b3ada7 pbrook
    s->dev.config[0x05] = 0x00;
595 80b3ada7 pbrook
    s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
596 80b3ada7 pbrook
    s->dev.config[0x07] = 0x00; // status = fast devsel
597 80b3ada7 pbrook
    s->dev.config[0x08] = 0x00; // revision
598 80b3ada7 pbrook
    s->dev.config[0x09] = 0x00; // programming i/f
599 80b3ada7 pbrook
    s->dev.config[0x0A] = 0x04; // class_sub = PCI to PCI bridge
600 80b3ada7 pbrook
    s->dev.config[0x0B] = 0x06; // class_base = PCI_bridge
601 80b3ada7 pbrook
    s->dev.config[0x0D] = 0x10; // latency_timer
602 80b3ada7 pbrook
    s->dev.config[0x0E] = 0x81; // header_type
603 80b3ada7 pbrook
    s->dev.config[0x1E] = 0xa0; // secondary status
604 80b3ada7 pbrook
605 80b3ada7 pbrook
    s->bus = pci_register_secondary_bus(&s->dev, map_irq);
606 80b3ada7 pbrook
    return s->bus;
607 80b3ada7 pbrook
}