pci.c 25.6 KB
Newer Older
B
bellard 已提交
1 2 3 4
/*
 * QEMU PCI bus manager
 *
 * Copyright (c) 2004 Fabrice Bellard
5
 *
B
bellard 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
P
pbrook 已提交
24 25
#include "hw.h"
#include "pci.h"
A
aliguori 已提交
26
#include "monitor.h"
P
pbrook 已提交
27
#include "net.h"
28
#include "sysemu.h"
B
bellard 已提交
29 30 31

//#define DEBUG_PCI

32 33 34
struct PCIBus {
    int bus_num;
    int devfn_min;
P
pbrook 已提交
35
    pci_set_irq_fn set_irq;
36
    pci_map_irq_fn map_irq;
37
    uint32_t config_reg; /* XXX: suppress */
38 39
    /* low level pic */
    SetIRQFunc *low_set_irq;
P
pbrook 已提交
40
    qemu_irq *irq_opaque;
41
    PCIDevice *devices[256];
P
pbrook 已提交
42 43
    PCIDevice *parent_dev;
    PCIBus *next;
44 45
    /* The bus IRQ state is the logical OR of the connected devices.
       Keep a count of the number of devices with raised IRQs.  */
46
    int nirq;
P
pbrook 已提交
47
    int irq_count[];
48
};
B
bellard 已提交
49

B
bellard 已提交
50
static void pci_update_mappings(PCIDevice *d);
P
pbrook 已提交
51
static void pci_set_irq(void *opaque, int irq_num, int level);
B
bellard 已提交
52

B
bellard 已提交
53
target_phys_addr_t pci_mem_base;
54 55
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
56
static int pci_irq_index;
57 58
static PCIBus *first_bus;

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
static void pcibus_save(QEMUFile *f, void *opaque)
{
    PCIBus *bus = (PCIBus *)opaque;
    int i;

    qemu_put_be32(f, bus->nirq);
    for (i = 0; i < bus->nirq; i++)
        qemu_put_be32(f, bus->irq_count[i]);
}

static int  pcibus_load(QEMUFile *f, void *opaque, int version_id)
{
    PCIBus *bus = (PCIBus *)opaque;
    int i, nirq;

    if (version_id != 1)
        return -EINVAL;

    nirq = qemu_get_be32(f);
    if (bus->nirq != nirq) {
        fprintf(stderr, "pcibus_load: nirq mismatch: src=%d dst=%d\n",
                nirq, bus->nirq);
        return -EINVAL;
    }

    for (i = 0; i < nirq; i++)
        bus->irq_count[i] = qemu_get_be32(f);

    return 0;
}

90
PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
P
pbrook 已提交
91
                         qemu_irq *pic, int devfn_min, int nirq)
92 93
{
    PCIBus *bus;
94 95
    static int nbus = 0;

P
pbrook 已提交
96
    bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
P
pbrook 已提交
97
    bus->set_irq = set_irq;
98
    bus->map_irq = map_irq;
P
pbrook 已提交
99 100
    bus->irq_opaque = pic;
    bus->devfn_min = devfn_min;
101
    bus->nirq = nirq;
I
Isaku Yamahata 已提交
102
    bus->next = first_bus;
103
    first_bus = bus;
104
    register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
105 106
    return bus;
}
B
bellard 已提交
107

108
static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
P
pbrook 已提交
109 110 111 112 113 114 115 116 117 118
{
    PCIBus *bus;
    bus = qemu_mallocz(sizeof(PCIBus));
    bus->map_irq = map_irq;
    bus->parent_dev = dev;
    bus->next = dev->bus->next;
    dev->bus->next = bus;
    return bus;
}

P
pbrook 已提交
119 120 121 122 123
int pci_bus_num(PCIBus *s)
{
    return s->bus_num;
}

B
bellard 已提交
124
void pci_device_save(PCIDevice *s, QEMUFile *f)
125
{
126 127 128
    int i;

    qemu_put_be32(f, 2); /* PCI device version */
129
    qemu_put_buffer(f, s->config, 256);
130 131
    for (i = 0; i < 4; i++)
        qemu_put_be32(f, s->irq_state[i]);
132 133
}

B
bellard 已提交
134
int pci_device_load(PCIDevice *s, QEMUFile *f)
135
{
B
bellard 已提交
136
    uint32_t version_id;
137 138
    int i;

B
bellard 已提交
139
    version_id = qemu_get_be32(f);
140
    if (version_id > 2)
141 142
        return -EINVAL;
    qemu_get_buffer(f, s->config, 256);
B
bellard 已提交
143
    pci_update_mappings(s);
144 145 146 147 148

    if (version_id >= 2)
        for (i = 0; i < 4; i ++)
            s->irq_state[i] = qemu_get_be32(f);

149 150 151
    return 0;
}

152 153 154 155 156 157 158 159 160 161
static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
{
    uint16_t *id;

    id = (void*)(&pci_dev->config[PCI_SUBVENDOR_ID]);
    id[0] = cpu_to_le16(pci_default_sub_vendor_id);
    id[1] = cpu_to_le16(pci_default_sub_device_id);
    return 0;
}

162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
/*
 * Parse [[<domain>:]<bus>:]<slot>, return -1 on error
 */
static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
{
    const char *p;
    char *e;
    unsigned long val;
    unsigned long dom = 0, bus = 0;
    unsigned slot = 0;

    p = addr;
    val = strtoul(p, &e, 16);
    if (e == p)
	return -1;
    if (*e == ':') {
	bus = val;
	p = e + 1;
	val = strtoul(p, &e, 16);
	if (e == p)
	    return -1;
	if (*e == ':') {
	    dom = bus;
	    bus = val;
	    p = e + 1;
	    val = strtoul(p, &e, 16);
	    if (e == p)
		return -1;
	}
    }

    if (dom > 0xffff || bus > 0xff || val > 0x1f)
	return -1;

    slot = val;

    if (*e)
	return -1;

    /* Note: QEMU doesn't implement domains other than 0 */
    if (dom != 0 || pci_find_bus(bus) == NULL)
	return -1;

    *domp = dom;
    *busp = bus;
    *slotp = slot;
    return 0;
}

int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
{
    char devaddr[32];

    if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
        return -1;

    return pci_parse_devaddr(devaddr, domp, busp, slotp);
}

int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
{
    char devaddr[32];

    if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
	return -1;

    if (!strcmp(devaddr, "auto")) {
        *domp = *busp = 0;
        *slotp = -1;
        /* want to support dom/bus auto-assign at some point */
        return 0;
    }

    return pci_parse_devaddr(devaddr, domp, busp, slotp);
}

B
bellard 已提交
238
/* -1 for devfn means auto assign */
P
Paul Brook 已提交
239 240 241 242
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
                                         const char *name, int devfn,
                                         PCIConfigReadFunc *config_read,
                                         PCIConfigWriteFunc *config_write)
B
bellard 已提交
243
{
244 245
    if (pci_irq_index >= PCI_DEVICES_MAX)
        return NULL;
246

B
bellard 已提交
247
    if (devfn < 0) {
248 249
        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
            if (!bus->devices[devfn])
B
bellard 已提交
250 251 252 253 254
                goto found;
        }
        return NULL;
    found: ;
    }
255
    pci_dev->bus = bus;
B
bellard 已提交
256 257
    pci_dev->devfn = devfn;
    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
258
    memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
259
    pci_set_default_subsystem_id(pci_dev);
260 261 262 263 264

    if (!config_read)
        config_read = pci_default_read_config;
    if (!config_write)
        config_write = pci_default_write_config;
B
bellard 已提交
265 266
    pci_dev->config_read = config_read;
    pci_dev->config_write = config_write;
267
    pci_dev->irq_index = pci_irq_index++;
268
    bus->devices[devfn] = pci_dev;
P
pbrook 已提交
269
    pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
B
bellard 已提交
270 271 272
    return pci_dev;
}

P
Paul Brook 已提交
273 274 275 276 277 278 279 280 281 282 283 284
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                               int instance_size, int devfn,
                               PCIConfigReadFunc *config_read,
                               PCIConfigWriteFunc *config_write)
{
    PCIDevice *pci_dev;

    pci_dev = qemu_mallocz(instance_size);
    pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,
                                     config_read, config_write);
    return pci_dev;
}
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
{
    return addr + pci_mem_base;
}

static void pci_unregister_io_regions(PCIDevice *pci_dev)
{
    PCIIORegion *r;
    int i;

    for(i = 0; i < PCI_NUM_REGIONS; i++) {
        r = &pci_dev->io_regions[i];
        if (!r->size || r->addr == -1)
            continue;
        if (r->type == PCI_ADDRESS_SPACE_IO) {
            isa_unassign_ioport(r->addr, r->size);
        } else {
            cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
                                                     r->size,
                                                     IO_MEM_UNASSIGNED);
        }
    }
}

int pci_unregister_device(PCIDevice *pci_dev)
{
    int ret = 0;

    if (pci_dev->unregister)
        ret = pci_dev->unregister(pci_dev);
    if (ret)
        return ret;

    pci_unregister_io_regions(pci_dev);

    qemu_free_irqs(pci_dev->irq);
    pci_irq_index--;
    pci_dev->bus->devices[pci_dev->devfn] = NULL;
    qemu_free(pci_dev);
    return 0;
}

327 328
void pci_register_io_region(PCIDevice *pci_dev, int region_num,
                            uint32_t size, int type,
B
bellard 已提交
329 330 331
                            PCIMapIORegionFunc *map_func)
{
    PCIIORegion *r;
P
pbrook 已提交
332
    uint32_t addr;
B
bellard 已提交
333

334
    if ((unsigned int)region_num >= PCI_NUM_REGIONS)
B
bellard 已提交
335
        return;
336 337 338 339 340 341 342

    if (size & (size-1)) {
        fprintf(stderr, "ERROR: PCI region size must be pow2 "
                    "type=0x%x, size=0x%x\n", type, size);
        exit(1);
    }

B
bellard 已提交
343 344 345 346 347
    r = &pci_dev->io_regions[region_num];
    r->addr = -1;
    r->size = size;
    r->type = type;
    r->map_func = map_func;
P
pbrook 已提交
348 349 350 351 352 353
    if (region_num == PCI_ROM_SLOT) {
        addr = 0x30;
    } else {
        addr = 0x10 + region_num * 4;
    }
    *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
B
bellard 已提交
354 355
}

356 357 358 359
static void pci_update_mappings(PCIDevice *d)
{
    PCIIORegion *r;
    int cmd, i;
360
    uint32_t last_addr, new_addr, config_ofs;
361

362
    cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
363
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
364
        r = &d->io_regions[i];
365 366 367 368 369
        if (i == PCI_ROM_SLOT) {
            config_ofs = 0x30;
        } else {
            config_ofs = 0x10 + i * 4;
        }
370 371 372
        if (r->size != 0) {
            if (r->type & PCI_ADDRESS_SPACE_IO) {
                if (cmd & PCI_COMMAND_IO) {
373
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
374
                                                         config_ofs));
375 376 377 378 379 380 381 382 383 384 385 386
                    new_addr = new_addr & ~(r->size - 1);
                    last_addr = new_addr + r->size - 1;
                    /* NOTE: we have only 64K ioports on PC */
                    if (last_addr <= new_addr || new_addr == 0 ||
                        last_addr >= 0x10000) {
                        new_addr = -1;
                    }
                } else {
                    new_addr = -1;
                }
            } else {
                if (cmd & PCI_COMMAND_MEMORY) {
387
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
388 389 390 391
                                                         config_ofs));
                    /* the ROM slot has a specific enable bit */
                    if (i == PCI_ROM_SLOT && !(new_addr & 1))
                        goto no_mem_map;
392 393 394 395 396 397 398 399 400 401 402
                    new_addr = new_addr & ~(r->size - 1);
                    last_addr = new_addr + r->size - 1;
                    /* NOTE: we do not support wrapping */
                    /* XXX: as we cannot support really dynamic
                       mappings, we handle specific values as invalid
                       mappings. */
                    if (last_addr <= new_addr || new_addr == 0 ||
                        last_addr == -1) {
                        new_addr = -1;
                    }
                } else {
403
                no_mem_map:
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
                    new_addr = -1;
                }
            }
            /* now do the real mapping */
            if (new_addr != r->addr) {
                if (r->addr != -1) {
                    if (r->type & PCI_ADDRESS_SPACE_IO) {
                        int class;
                        /* NOTE: specific hack for IDE in PC case:
                           only one byte must be mapped. */
                        class = d->config[0x0a] | (d->config[0x0b] << 8);
                        if (class == 0x0101 && r->size == 4) {
                            isa_unassign_ioport(r->addr + 2, 1);
                        } else {
                            isa_unassign_ioport(r->addr, r->size);
                        }
                    } else {
P
pbrook 已提交
421
                        cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
422
                                                     r->size,
423
                                                     IO_MEM_UNASSIGNED);
A
aliguori 已提交
424
                        qemu_unregister_coalesced_mmio(r->addr, r->size);
425 426 427 428 429 430 431 432 433 434 435
                    }
                }
                r->addr = new_addr;
                if (r->addr != -1) {
                    r->map_func(d, i, r->addr, r->size, r->type);
                }
            }
        }
    }
}

436
uint32_t pci_default_read_config(PCIDevice *d,
437
                                 uint32_t address, int len)
B
bellard 已提交
438
{
439
    uint32_t val;
440

441 442 443
    switch(len) {
    default:
    case 4:
444 445 446 447 448 449 450 451 452 453 454 455 456
	if (address <= 0xfc) {
	    val = le32_to_cpu(*(uint32_t *)(d->config + address));
	    break;
	}
	/* fall through */
    case 2:
        if (address <= 0xfe) {
	    val = le16_to_cpu(*(uint16_t *)(d->config + address));
	    break;
	}
	/* fall through */
    case 1:
        val = d->config[address];
457 458 459 460 461
        break;
    }
    return val;
}

462
void pci_default_write_config(PCIDevice *d,
463 464 465
                              uint32_t address, uint32_t val, int len)
{
    int can_write, i;
B
bellard 已提交
466
    uint32_t end, addr;
467

468
    if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) ||
469
                     (address >= 0x30 && address < 0x34))) {
470 471 472
        PCIIORegion *r;
        int reg;

473 474 475 476 477
        if ( address >= 0x30 ) {
            reg = PCI_ROM_SLOT;
        }else{
            reg = (address - 0x10) >> 2;
        }
478 479 480 481
        r = &d->io_regions[reg];
        if (r->size == 0)
            goto default_config;
        /* compute the stored value */
482 483 484 485 486 487 488 489
        if (reg == PCI_ROM_SLOT) {
            /* keep ROM enable bit */
            val &= (~(r->size - 1)) | 1;
        } else {
            val &= ~(r->size - 1);
            val |= r->type;
        }
        *(uint32_t *)(d->config + address) = cpu_to_le32(val);
490
        pci_update_mappings(d);
B
bellard 已提交
491
        return;
492 493 494
    }
 default_config:
    /* not efficient, but simple */
B
bellard 已提交
495
    addr = address;
496 497
    for(i = 0; i < len; i++) {
        /* default read/write accesses */
498
        switch(d->config[0x0e]) {
499
        case 0x00:
500 501 502 503 504 505
        case 0x80:
            switch(addr) {
            case 0x00:
            case 0x01:
            case 0x02:
            case 0x03:
506 507
            case 0x06:
            case 0x07:
508 509 510 511 512 513
            case 0x08:
            case 0x09:
            case 0x0a:
            case 0x0b:
            case 0x0e:
            case 0x10 ... 0x27: /* base */
514
            case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */
515 516 517 518 519 520 521 522
            case 0x30 ... 0x33: /* rom */
            case 0x3d:
                can_write = 0;
                break;
            default:
                can_write = 1;
                break;
            }
523 524
            break;
        default:
525 526 527 528 529 530
        case 0x01:
            switch(addr) {
            case 0x00:
            case 0x01:
            case 0x02:
            case 0x03:
531 532
            case 0x06:
            case 0x07:
533 534 535 536 537
            case 0x08:
            case 0x09:
            case 0x0a:
            case 0x0b:
            case 0x0e:
538
            case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */
539 540 541 542 543 544 545 546
            case 0x38 ... 0x3b: /* rom */
            case 0x3d:
                can_write = 0;
                break;
            default:
                can_write = 1;
                break;
            }
547 548 549
            break;
        }
        if (can_write) {
550 551
            /* Mask out writes to reserved bits in registers */
            switch (addr) {
552 553 554
	    case 0x05:
                val &= ~PCI_COMMAND_RESERVED_MASK_HI;
                break;
555 556 557 558 559 560 561
            case 0x06:
                val &= ~PCI_STATUS_RESERVED_MASK_LO;
                break;
            case 0x07:
                val &= ~PCI_STATUS_RESERVED_MASK_HI;
                break;
            }
B
bellard 已提交
562
            d->config[addr] = val;
563
        }
564 565
        if (++addr > 0xff)
        	break;
566 567 568 569 570 571 572
        val >>= 8;
    }

    end = address + len;
    if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
        /* if the command register is modified, we must modify the mappings */
        pci_update_mappings(d);
B
bellard 已提交
573 574 575
    }
}

P
pbrook 已提交
576
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
B
bellard 已提交
577
{
578 579 580
    PCIBus *s = opaque;
    PCIDevice *pci_dev;
    int config_addr, bus_num;
581

B
bellard 已提交
582 583
#if defined(DEBUG_PCI) && 0
    printf("pci_data_write: addr=%08x val=%08x len=%d\n",
P
pbrook 已提交
584
           addr, val, len);
B
bellard 已提交
585
#endif
P
pbrook 已提交
586
    bus_num = (addr >> 16) & 0xff;
P
pbrook 已提交
587 588 589
    while (s && s->bus_num != bus_num)
        s = s->next;
    if (!s)
B
bellard 已提交
590
        return;
P
pbrook 已提交
591
    pci_dev = s->devices[(addr >> 8) & 0xff];
B
bellard 已提交
592 593
    if (!pci_dev)
        return;
P
pbrook 已提交
594
    config_addr = addr & 0xff;
B
bellard 已提交
595 596 597 598
#if defined(DEBUG_PCI)
    printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
           pci_dev->name, config_addr, val, len);
#endif
599
    pci_dev->config_write(pci_dev, config_addr, val, len);
B
bellard 已提交
600 601
}

P
pbrook 已提交
602
uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
B
bellard 已提交
603
{
604 605 606
    PCIBus *s = opaque;
    PCIDevice *pci_dev;
    int config_addr, bus_num;
B
bellard 已提交
607 608
    uint32_t val;

P
pbrook 已提交
609
    bus_num = (addr >> 16) & 0xff;
P
pbrook 已提交
610 611 612
    while (s && s->bus_num != bus_num)
        s= s->next;
    if (!s)
B
bellard 已提交
613
        goto fail;
P
pbrook 已提交
614
    pci_dev = s->devices[(addr >> 8) & 0xff];
B
bellard 已提交
615 616
    if (!pci_dev) {
    fail:
617 618 619 620 621 622 623 624 625 626 627 628
        switch(len) {
        case 1:
            val = 0xff;
            break;
        case 2:
            val = 0xffff;
            break;
        default:
        case 4:
            val = 0xffffffff;
            break;
        }
B
bellard 已提交
629 630
        goto the_end;
    }
P
pbrook 已提交
631
    config_addr = addr & 0xff;
B
bellard 已提交
632 633 634 635 636 637 638 639
    val = pci_dev->config_read(pci_dev, config_addr, len);
#if defined(DEBUG_PCI)
    printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
           pci_dev->name, config_addr, val, len);
#endif
 the_end:
#if defined(DEBUG_PCI) && 0
    printf("pci_data_read: addr=%08x val=%08x len=%d\n",
P
pbrook 已提交
640
           addr, val, len);
B
bellard 已提交
641 642 643 644
#endif
    return val;
}

P
pbrook 已提交
645 646
/***********************************************************/
/* generic PCI irq support */
647

P
pbrook 已提交
648
/* 0 <= irq_num <= 3. level must be 0 or 1 */
P
pbrook 已提交
649
static void pci_set_irq(void *opaque, int irq_num, int level)
B
bellard 已提交
650
{
P
pbrook 已提交
651
    PCIDevice *pci_dev = (PCIDevice *)opaque;
P
pbrook 已提交
652 653
    PCIBus *bus;
    int change;
654

P
pbrook 已提交
655 656 657
    change = level - pci_dev->irq_state[irq_num];
    if (!change)
        return;
658 659

    pci_dev->irq_state[irq_num] = level;
P
pbrook 已提交
660 661
    for (;;) {
        bus = pci_dev->bus;
P
pbrook 已提交
662
        irq_num = bus->map_irq(pci_dev, irq_num);
P
pbrook 已提交
663 664
        if (bus->set_irq)
            break;
P
pbrook 已提交
665 666 667
        pci_dev = bus->parent_dev;
    }
    bus->irq_count[irq_num] += change;
668
    bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
B
bellard 已提交
669 670
}

P
pbrook 已提交
671 672
/***********************************************************/
/* monitor info on PCI */
673

674 675 676 677 678
typedef struct {
    uint16_t class;
    const char *desc;
} pci_class_desc;

679
static const pci_class_desc pci_class_descriptions[] =
680
{
P
pbrook 已提交
681
    { 0x0100, "SCSI controller"},
682
    { 0x0101, "IDE controller"},
T
ths 已提交
683 684 685 686 687 688
    { 0x0102, "Floppy controller"},
    { 0x0103, "IPI controller"},
    { 0x0104, "RAID controller"},
    { 0x0106, "SATA controller"},
    { 0x0107, "SAS controller"},
    { 0x0180, "Storage controller"},
689
    { 0x0200, "Ethernet controller"},
T
ths 已提交
690 691 692 693
    { 0x0201, "Token Ring controller"},
    { 0x0202, "FDDI controller"},
    { 0x0203, "ATM controller"},
    { 0x0280, "Network controller"},
694
    { 0x0300, "VGA controller"},
T
ths 已提交
695 696 697 698 699 700 701 702 703 704
    { 0x0301, "XGA controller"},
    { 0x0302, "3D controller"},
    { 0x0380, "Display controller"},
    { 0x0400, "Video controller"},
    { 0x0401, "Audio controller"},
    { 0x0402, "Phone"},
    { 0x0480, "Multimedia controller"},
    { 0x0500, "RAM controller"},
    { 0x0501, "Flash controller"},
    { 0x0580, "Memory controller"},
705 706
    { 0x0600, "Host bridge"},
    { 0x0601, "ISA bridge"},
T
ths 已提交
707 708
    { 0x0602, "EISA bridge"},
    { 0x0603, "MC bridge"},
709
    { 0x0604, "PCI bridge"},
T
ths 已提交
710 711 712 713 714
    { 0x0605, "PCMCIA bridge"},
    { 0x0606, "NUBUS bridge"},
    { 0x0607, "CARDBUS bridge"},
    { 0x0608, "RACEWAY bridge"},
    { 0x0680, "Bridge"},
715 716 717 718
    { 0x0c03, "USB controller"},
    { 0, NULL}
};

P
pbrook 已提交
719
static void pci_info_device(PCIDevice *d)
720
{
A
aliguori 已提交
721
    Monitor *mon = cur_mon;
P
pbrook 已提交
722 723
    int i, class;
    PCIIORegion *r;
724
    const pci_class_desc *desc;
725

A
aliguori 已提交
726 727
    monitor_printf(mon, "  Bus %2d, device %3d, function %d:\n",
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
P
pbrook 已提交
728
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
A
aliguori 已提交
729
    monitor_printf(mon, "    ");
730 731 732 733
    desc = pci_class_descriptions;
    while (desc->desc && class != desc->class)
        desc++;
    if (desc->desc) {
A
aliguori 已提交
734
        monitor_printf(mon, "%s", desc->desc);
735
    } else {
A
aliguori 已提交
736
        monitor_printf(mon, "Class %04x", class);
737
    }
A
aliguori 已提交
738
    monitor_printf(mon, ": PCI device %04x:%04x\n",
P
pbrook 已提交
739 740
           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
741

P
pbrook 已提交
742
    if (d->config[PCI_INTERRUPT_PIN] != 0) {
A
aliguori 已提交
743 744
        monitor_printf(mon, "      IRQ %d.\n",
                       d->config[PCI_INTERRUPT_LINE]);
745
    }
P
pbrook 已提交
746
    if (class == 0x0604) {
A
aliguori 已提交
747
        monitor_printf(mon, "      BUS %d.\n", d->config[0x19]);
P
pbrook 已提交
748
    }
P
pbrook 已提交
749 750 751
    for(i = 0;i < PCI_NUM_REGIONS; i++) {
        r = &d->io_regions[i];
        if (r->size != 0) {
A
aliguori 已提交
752
            monitor_printf(mon, "      BAR%d: ", i);
P
pbrook 已提交
753
            if (r->type & PCI_ADDRESS_SPACE_IO) {
A
aliguori 已提交
754 755
                monitor_printf(mon, "I/O at 0x%04x [0x%04x].\n",
                               r->addr, r->addr + r->size - 1);
P
pbrook 已提交
756
            } else {
A
aliguori 已提交
757 758
                monitor_printf(mon, "32 bit memory at 0x%08x [0x%08x].\n",
                               r->addr, r->addr + r->size - 1);
P
pbrook 已提交
759 760
            }
        }
B
bellard 已提交
761
    }
P
pbrook 已提交
762 763 764
    if (class == 0x0604 && d->config[0x19] != 0) {
        pci_for_each_device(d->config[0x19], pci_info_device);
    }
765 766
}

P
pbrook 已提交
767
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
768
{
P
pbrook 已提交
769
    PCIBus *bus = first_bus;
770
    PCIDevice *d;
P
pbrook 已提交
771
    int devfn;
772

P
pbrook 已提交
773 774
    while (bus && bus->bus_num != bus_num)
        bus = bus->next;
P
pbrook 已提交
775 776 777 778 779 780
    if (bus) {
        for(devfn = 0; devfn < 256; devfn++) {
            d = bus->devices[devfn];
            if (d)
                fn(d);
        }
B
bellard 已提交
781 782 783
    }
}

A
aliguori 已提交
784
void pci_info(Monitor *mon)
B
bellard 已提交
785
{
P
pbrook 已提交
786
    pci_for_each_device(0, pci_info_device);
B
bellard 已提交
787
}
788

789 790 791 792 793 794 795 796 797 798 799 800
static const char * const pci_nic_models[] = {
    "ne2k_pci",
    "i82551",
    "i82557b",
    "i82559er",
    "rtl8139",
    "e1000",
    "pcnet",
    "virtio",
    NULL
};

P
Paul Brook 已提交
801 802 803 804 805 806 807 808 809
static const char * const pci_nic_names[] = {
    "ne2k_pci",
    "i82551",
    "i82557b",
    "i82559er",
    "rtl8139",
    "e1000",
    "pcnet",
    "virtio_net",
810 811 812
    NULL
};

813
/* Initialize a PCI NIC.  */
814
PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
815
                  const char *default_model)
816
{
P
Paul Brook 已提交
817
    DeviceState *dev;
818 819 820 821
    int i;

    qemu_check_nic_model_list(nd, pci_nic_models, default_model);

P
Paul Brook 已提交
822
    for (i = 0; pci_nic_models[i]; i++) {
823
        if (strcmp(nd->model, pci_nic_models[i]) == 0) {
P
Paul Brook 已提交
824 825 826 827 828 829
            dev = qdev_create(bus, pci_nic_names[i]);
            qdev_set_prop_int(dev, "devfn", devfn);
            qdev_set_netdev(dev, nd);
            qdev_init(dev);
            nd->private = dev;
            return (PCIDevice *)dev;
830
        }
P
Paul Brook 已提交
831
    }
832 833

    return NULL;
834 835
}

P
pbrook 已提交
836 837 838 839 840
typedef struct {
    PCIDevice dev;
    PCIBus *bus;
} PCIBridge;

841
static void pci_bridge_write_config(PCIDevice *d,
P
pbrook 已提交
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
                             uint32_t address, uint32_t val, int len)
{
    PCIBridge *s = (PCIBridge *)d;

    if (address == 0x19 || (address == 0x18 && len > 1)) {
        if (address == 0x19)
            s->bus->bus_num = val & 0xff;
        else
            s->bus->bus_num = (val >> 8) & 0xff;
#if defined(DEBUG_PCI)
        printf ("pci-bridge: %s: Assigned bus %d\n", d->name, s->bus->bus_num);
#endif
    }
    pci_default_write_config(d, address, val, len);
}

858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
PCIBus *pci_find_bus(int bus_num)
{
    PCIBus *bus = first_bus;

    while (bus && bus->bus_num != bus_num)
        bus = bus->next;

    return bus;
}

PCIDevice *pci_find_device(int bus_num, int slot, int function)
{
    PCIBus *bus = pci_find_bus(bus_num);

    if (!bus)
        return NULL;

    return bus->devices[PCI_DEVFN(slot, function)];
}

B
blueswir1 已提交
878
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
P
pbrook 已提交
879 880 881
                        pci_map_irq_fn map_irq, const char *name)
{
    PCIBridge *s;
882
    s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
P
pbrook 已提交
883
                                         devfn, NULL, pci_bridge_write_config);
B
blueswir1 已提交
884 885 886 887

    pci_config_set_vendor_id(s->dev.config, vid);
    pci_config_set_device_id(s->dev.config, did);

P
pbrook 已提交
888 889 890 891 892 893
    s->dev.config[0x04] = 0x06; // command = bus master, pci mem
    s->dev.config[0x05] = 0x00;
    s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
    s->dev.config[0x07] = 0x00; // status = fast devsel
    s->dev.config[0x08] = 0x00; // revision
    s->dev.config[0x09] = 0x00; // programming i/f
894
    pci_config_set_class(s->dev.config, PCI_CLASS_BRIDGE_PCI);
P
pbrook 已提交
895
    s->dev.config[0x0D] = 0x10; // latency_timer
I
Isaku Yamahata 已提交
896 897
    s->dev.config[PCI_HEADER_TYPE] =
        PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
P
pbrook 已提交
898 899 900 901 902
    s->dev.config[0x1E] = 0xa0; // secondary status

    s->bus = pci_register_secondary_bus(&s->dev, map_irq);
    return s->bus;
}
P
Paul Brook 已提交
903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934

static void pci_qdev_init(DeviceState *qdev, void *opaque)
{
    PCIDevice *pci_dev = (PCIDevice *)qdev;
    pci_qdev_initfn init;
    PCIBus *bus;
    int devfn;

    init = opaque;
    bus = qdev_get_bus(qdev);
    devfn = qdev_get_prop_int(qdev, "devfn", -1);
    pci_dev = do_pci_register_device(pci_dev, bus, "FIXME", devfn,
                                     NULL, NULL);//FIXME:config_read, config_write);
    assert(pci_dev);
    init(pci_dev);
}

void pci_qdev_register(const char *name, int size, pci_qdev_initfn init)
{
    qdev_register(name, size, pci_qdev_init, init);
}

PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
{
    DeviceState *dev;

    dev = qdev_create(bus, name);
    qdev_set_prop_int(dev, "devfn", devfn);
    qdev_init(dev);

    return (PCIDevice *)dev;
}