Revision 69b91039
b/Changelog | ||
---|---|---|
8 | 8 |
- int13 CDROM BIOS fix (aka Solaris x86 install CD fix) |
9 | 9 |
- int15, ah=86 BIOS fix (aka Solaris x86 hardware probe hang up fix) |
10 | 10 |
- BSR/BSF "undefined behaviour" fix |
11 |
- vmdk2raw: convert VMware disk images to raw images |
|
12 |
- PCI support |
|
13 |
- NE2K PCI support |
|
11 | 14 |
|
12 | 15 |
version 0.5.5: |
13 | 16 |
|
b/Makefile.target | ||
---|---|---|
232 | 232 |
endif |
233 | 233 |
|
234 | 234 |
# must use static linking to avoid leaving stuff in virtual address space |
235 |
VL_OBJS=vl.o osdep.o block.o monitor.o |
|
235 |
VL_OBJS=vl.o osdep.o block.o monitor.o pci.o pci2isa.o
|
|
236 | 236 |
|
237 | 237 |
ifeq ($(TARGET_ARCH), i386) |
238 | 238 |
# Hardware support |
b/hw/ide.c | ||
---|---|---|
1433 | 1433 |
} |
1434 | 1434 |
} |
1435 | 1435 |
|
1436 |
void ide_init(int iobase, int iobase2, int irq,
|
|
1437 |
BlockDriverState *hd0, BlockDriverState *hd1) |
|
1436 |
static void ide_init2(IDEState *ide_state, int irq,
|
|
1437 |
BlockDriverState *hd0, BlockDriverState *hd1)
|
|
1438 | 1438 |
{ |
1439 |
IDEState *s, *ide_state;
|
|
1439 |
IDEState *s; |
|
1440 | 1440 |
static int drive_serial = 1; |
1441 | 1441 |
int i, cylinders, heads, secs; |
1442 | 1442 |
int64_t nb_sectors; |
1443 | 1443 |
|
1444 |
ide_state = qemu_mallocz(sizeof(IDEState) * 2); |
|
1445 |
if (!ide_state) |
|
1446 |
return; |
|
1447 |
|
|
1448 | 1444 |
for(i = 0; i < 2; i++) { |
1449 | 1445 |
s = ide_state + i; |
1450 | 1446 |
if (i == 0) |
... | ... | |
1483 | 1479 |
s->irq = irq; |
1484 | 1480 |
ide_reset(s); |
1485 | 1481 |
} |
1482 |
} |
|
1483 |
|
|
1484 |
/***********************************************************/ |
|
1485 |
/* ISA IDE definitions */ |
|
1486 |
|
|
1487 |
void isa_ide_init(int iobase, int iobase2, int irq, |
|
1488 |
BlockDriverState *hd0, BlockDriverState *hd1) |
|
1489 |
{ |
|
1490 |
IDEState *ide_state; |
|
1491 |
|
|
1492 |
ide_state = qemu_mallocz(sizeof(IDEState) * 2); |
|
1493 |
if (!ide_state) |
|
1494 |
return; |
|
1495 |
|
|
1496 |
ide_init2(ide_state, irq, hd0, hd1); |
|
1497 |
|
|
1486 | 1498 |
register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state); |
1487 | 1499 |
register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state); |
1488 | 1500 |
if (iobase2) { |
... | ... | |
1496 | 1508 |
register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state); |
1497 | 1509 |
register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state); |
1498 | 1510 |
} |
1511 |
|
|
1512 |
/***********************************************************/ |
|
1513 |
/* PCI IDE definitions */ |
|
1514 |
|
|
1515 |
typedef struct PCIIDEState { |
|
1516 |
PCIDevice dev; |
|
1517 |
IDEState ide_if[4]; |
|
1518 |
} PCIIDEState; |
|
1519 |
|
|
1520 |
static uint32_t ide_read_config(PCIDevice *d, |
|
1521 |
uint32_t address, int len) |
|
1522 |
{ |
|
1523 |
uint32_t val; |
|
1524 |
val = 0; |
|
1525 |
memcpy(&val, d->config + address, len); |
|
1526 |
return val; |
|
1527 |
} |
|
1528 |
|
|
1529 |
static void ide_write_config(PCIDevice *d, |
|
1530 |
uint32_t address, uint32_t val, int len) |
|
1531 |
{ |
|
1532 |
memcpy(d->config + address, &val, len); |
|
1533 |
} |
|
1534 |
|
|
1535 |
static void ide_map(PCIDevice *pci_dev, int region_num, |
|
1536 |
uint32_t addr, uint32_t size, int type) |
|
1537 |
{ |
|
1538 |
PCIIDEState *d = (PCIIDEState *)pci_dev; |
|
1539 |
IDEState *ide_state; |
|
1540 |
|
|
1541 |
if (region_num <= 3) { |
|
1542 |
ide_state = &d->ide_if[(region_num >> 1) * 2]; |
|
1543 |
if (region_num & 1) { |
|
1544 |
register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state); |
|
1545 |
register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state); |
|
1546 |
} else { |
|
1547 |
register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state); |
|
1548 |
register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state); |
|
1549 |
|
|
1550 |
/* data ports */ |
|
1551 |
register_ioport_write(addr, 2, 2, ide_data_writew, ide_state); |
|
1552 |
register_ioport_read(addr, 2, 2, ide_data_readw, ide_state); |
|
1553 |
register_ioport_write(addr, 4, 4, ide_data_writel, ide_state); |
|
1554 |
register_ioport_read(addr, 4, 4, ide_data_readl, ide_state); |
|
1555 |
} |
|
1556 |
} |
|
1557 |
} |
|
1558 |
|
|
1559 |
/* hd_table must contain 4 block drivers */ |
|
1560 |
void pci_ide_init(BlockDriverState **hd_table) |
|
1561 |
{ |
|
1562 |
PCIIDEState *d; |
|
1563 |
uint8_t *pci_conf; |
|
1564 |
|
|
1565 |
d = (PCIIDEState *)pci_register_device("IDE", sizeof(PCIIDEState), |
|
1566 |
0, -1, |
|
1567 |
ide_read_config, |
|
1568 |
ide_write_config); |
|
1569 |
pci_conf = d->dev.config; |
|
1570 |
pci_conf[0x00] = 0x86; // Intel |
|
1571 |
pci_conf[0x01] = 0x80; |
|
1572 |
pci_conf[0x02] = 0x00; // fake |
|
1573 |
pci_conf[0x03] = 0x01; // fake |
|
1574 |
pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE |
|
1575 |
pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage |
|
1576 |
pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic |
|
1577 |
|
|
1578 |
pci_conf[0x2c] = 0x86; // subsys vendor |
|
1579 |
pci_conf[0x2d] = 0x80; // subsys vendor |
|
1580 |
pci_conf[0x2e] = 0x00; // fake |
|
1581 |
pci_conf[0x2f] = 0x01; // fake |
|
1582 |
|
|
1583 |
pci_register_io_region((PCIDevice *)d, 0, 0x8, |
|
1584 |
PCI_ADDRESS_SPACE_IO, ide_map); |
|
1585 |
pci_register_io_region((PCIDevice *)d, 1, 0x4, |
|
1586 |
PCI_ADDRESS_SPACE_IO, ide_map); |
|
1587 |
pci_register_io_region((PCIDevice *)d, 2, 0x8, |
|
1588 |
PCI_ADDRESS_SPACE_IO, ide_map); |
|
1589 |
pci_register_io_region((PCIDevice *)d, 3, 0x4, |
|
1590 |
PCI_ADDRESS_SPACE_IO, ide_map); |
|
1591 |
|
|
1592 |
ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]); |
|
1593 |
ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); |
|
1594 |
} |
b/hw/ne2000.c | ||
---|---|---|
368 | 368 |
} |
369 | 369 |
|
370 | 370 |
static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr, |
371 |
uint32_t val) |
|
371 |
uint32_t val)
|
|
372 | 372 |
{ |
373 | 373 |
if (addr < 32 || |
374 | 374 |
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { |
... | ... | |
382 | 382 |
addr &= ~1; /* XXX: check exact behaviour if not even */ |
383 | 383 |
if (addr < 32 || |
384 | 384 |
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { |
385 |
s->mem[addr] = val; |
|
386 |
s->mem[addr + 1] = val >> 8; |
|
385 |
*(uint16_t *)(s->mem + addr) = cpu_to_le16(val); |
|
386 |
} |
|
387 |
} |
|
388 |
|
|
389 |
static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr, |
|
390 |
uint32_t val) |
|
391 |
{ |
|
392 |
addr &= ~3; /* XXX: check exact behaviour if not even */ |
|
393 |
if (addr < 32 || |
|
394 |
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { |
|
395 |
*(uint32_t *)(s->mem + addr) = cpu_to_le32(val); |
|
387 | 396 |
} |
388 | 397 |
} |
389 | 398 |
|
... | ... | |
402 | 411 |
addr &= ~1; /* XXX: check exact behaviour if not even */ |
403 | 412 |
if (addr < 32 || |
404 | 413 |
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { |
405 |
return s->mem[addr] | (s->mem[addr + 1] << 8);
|
|
414 |
return le16_to_cpu(*(uint16_t *)(s->mem + addr));
|
|
406 | 415 |
} else { |
407 | 416 |
return 0xffff; |
408 | 417 |
} |
409 | 418 |
} |
410 | 419 |
|
420 |
static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr) |
|
421 |
{ |
|
422 |
addr &= ~3; /* XXX: check exact behaviour if not even */ |
|
423 |
if (addr < 32 || |
|
424 |
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { |
|
425 |
return le32_to_cpu(*(uint32_t *)(s->mem + addr)); |
|
426 |
} else { |
|
427 |
return 0xffffffff; |
|
428 |
} |
|
429 |
} |
|
430 |
|
|
411 | 431 |
static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
412 | 432 |
{ |
413 | 433 |
NE2000State *s = opaque; |
... | ... | |
468 | 488 |
return ret; |
469 | 489 |
} |
470 | 490 |
|
491 |
static void ne2000_asic_ioport_writel(void *opaque, uint32_t addr, uint32_t val) |
|
492 |
{ |
|
493 |
NE2000State *s = opaque; |
|
494 |
|
|
495 |
#ifdef DEBUG_NE2000 |
|
496 |
printf("NE2000: asic writel val=0x%04x\n", val); |
|
497 |
#endif |
|
498 |
if (s->rcnt == 0) |
|
499 |
return; |
|
500 |
/* 32 bit access */ |
|
501 |
ne2000_mem_writel(s, s->rsar, val); |
|
502 |
s->rsar += 4; |
|
503 |
s->rcnt -= 4; |
|
504 |
/* wrap */ |
|
505 |
if (s->rsar == s->stop) |
|
506 |
s->rsar = s->start; |
|
507 |
if (s->rcnt == 0) { |
|
508 |
/* signal end of transfert */ |
|
509 |
s->isr |= ENISR_RDC; |
|
510 |
ne2000_update_irq(s); |
|
511 |
} |
|
512 |
} |
|
513 |
|
|
514 |
static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr) |
|
515 |
{ |
|
516 |
NE2000State *s = opaque; |
|
517 |
int ret; |
|
518 |
|
|
519 |
/* 32 bit access */ |
|
520 |
ret = ne2000_mem_readl(s, s->rsar); |
|
521 |
s->rsar += 4; |
|
522 |
s->rcnt -= 4; |
|
523 |
|
|
524 |
/* wrap */ |
|
525 |
if (s->rsar == s->stop) |
|
526 |
s->rsar = s->start; |
|
527 |
if (s->rcnt == 0) { |
|
528 |
/* signal end of transfert */ |
|
529 |
s->isr |= ENISR_RDC; |
|
530 |
ne2000_update_irq(s); |
|
531 |
} |
|
532 |
#ifdef DEBUG_NE2000 |
|
533 |
printf("NE2000: asic readl val=0x%04x\n", ret); |
|
534 |
#endif |
|
535 |
return ret; |
|
536 |
} |
|
537 |
|
|
471 | 538 |
static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
472 | 539 |
{ |
473 | 540 |
/* nothing to do (end of reset pulse) */ |
... | ... | |
480 | 547 |
return 0; |
481 | 548 |
} |
482 | 549 |
|
483 |
void ne2000_init(int base, int irq, NetDriverState *nd) |
|
550 |
void isa_ne2000_init(int base, int irq, NetDriverState *nd)
|
|
484 | 551 |
{ |
485 | 552 |
NE2000State *s; |
486 | 553 |
|
... | ... | |
505 | 572 |
|
506 | 573 |
qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s); |
507 | 574 |
} |
575 |
|
|
576 |
/***********************************************************/ |
|
577 |
/* PCI NE2000 definitions */ |
|
578 |
|
|
579 |
typedef struct PCINE2000State { |
|
580 |
PCIDevice dev; |
|
581 |
NE2000State ne2000; |
|
582 |
} PCINE2000State; |
|
583 |
|
|
584 |
static uint32_t ne2000_read_config(PCIDevice *d, |
|
585 |
uint32_t address, int len) |
|
586 |
{ |
|
587 |
uint32_t val; |
|
588 |
val = 0; |
|
589 |
memcpy(&val, d->config + address, len); |
|
590 |
return val; |
|
591 |
} |
|
592 |
|
|
593 |
static void ne2000_write_config(PCIDevice *d, |
|
594 |
uint32_t address, uint32_t val, int len) |
|
595 |
{ |
|
596 |
memcpy(d->config + address, &val, len); |
|
597 |
} |
|
598 |
|
|
599 |
static void ne2000_map(PCIDevice *pci_dev, int region_num, |
|
600 |
uint32_t addr, uint32_t size, int type) |
|
601 |
{ |
|
602 |
PCINE2000State *d = (PCINE2000State *)pci_dev; |
|
603 |
NE2000State *s = &d->ne2000; |
|
604 |
|
|
605 |
register_ioport_write(addr, 16, 1, ne2000_ioport_write, s); |
|
606 |
register_ioport_read(addr, 16, 1, ne2000_ioport_read, s); |
|
607 |
|
|
608 |
register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s); |
|
609 |
register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s); |
|
610 |
register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s); |
|
611 |
register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s); |
|
612 |
register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s); |
|
613 |
register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s); |
|
614 |
|
|
615 |
register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s); |
|
616 |
register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s); |
|
617 |
} |
|
618 |
|
|
619 |
void pci_ne2000_init(NetDriverState *nd) |
|
620 |
{ |
|
621 |
PCINE2000State *d; |
|
622 |
NE2000State *s; |
|
623 |
uint8_t *pci_conf; |
|
624 |
|
|
625 |
d = (PCINE2000State *)pci_register_device("NE2000", sizeof(PCINE2000State), |
|
626 |
0, -1, |
|
627 |
ne2000_read_config, |
|
628 |
ne2000_write_config); |
|
629 |
pci_conf = d->dev.config; |
|
630 |
pci_conf[0x00] = 0xec; // Realtek 8029 |
|
631 |
pci_conf[0x01] = 0x10; |
|
632 |
pci_conf[0x02] = 0x29; |
|
633 |
pci_conf[0x03] = 0x80; |
|
634 |
pci_conf[0x0a] = 0x00; // ethernet network controller |
|
635 |
pci_conf[0x0b] = 0x02; |
|
636 |
pci_conf[0x0e] = 0x00; // header_type |
|
637 |
|
|
638 |
/* XXX: do that in the BIOS */ |
|
639 |
pci_conf[0x3c] = 11; // interrupt line |
|
640 |
pci_conf[0x3d] = 1; // interrupt pin |
|
641 |
|
|
642 |
pci_register_io_region((PCIDevice *)d, 0, 0x100, |
|
643 |
PCI_ADDRESS_SPACE_IO, ne2000_map); |
|
644 |
s = &d->ne2000; |
|
645 |
s->irq = 11; |
|
646 |
s->nd = nd; |
|
647 |
ne2000_reset(s); |
|
648 |
qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s); |
|
649 |
} |
b/hw/pc.c | ||
---|---|---|
380 | 380 |
stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01); |
381 | 381 |
} |
382 | 382 |
|
383 |
if (pci_enabled) { |
|
384 |
i440fx_init(); |
|
385 |
piix3_init(); |
|
386 |
} |
|
387 |
|
|
383 | 388 |
/* init basic PC hardware */ |
384 | 389 |
register_ioport_write(0x80, 1, 1, ioport80_write, NULL); |
385 | 390 |
|
... | ... | |
401 | 406 |
fd = serial_open_device(); |
402 | 407 |
serial_init(0x3f8, 4, fd); |
403 | 408 |
|
404 |
nb_nics1 = nb_nics; |
|
405 |
if (nb_nics1 > NE2000_NB_MAX) |
|
406 |
nb_nics1 = NE2000_NB_MAX; |
|
407 |
for(i = 0; i < nb_nics1; i++) { |
|
408 |
ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]); |
|
409 |
} |
|
409 |
if (pci_enabled) { |
|
410 |
for(i = 0; i < nb_nics; i++) { |
|
411 |
pci_ne2000_init(&nd_table[i]); |
|
412 |
} |
|
413 |
pci_ide_init(bs_table); |
|
414 |
} else { |
|
415 |
nb_nics1 = nb_nics; |
|
416 |
if (nb_nics1 > NE2000_NB_MAX) |
|
417 |
nb_nics1 = NE2000_NB_MAX; |
|
418 |
for(i = 0; i < nb_nics1; i++) { |
|
419 |
isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]); |
|
420 |
} |
|
410 | 421 |
|
411 |
for(i = 0; i < 2; i++) { |
|
412 |
ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], |
|
413 |
bs_table[2 * i], bs_table[2 * i + 1]); |
|
422 |
for(i = 0; i < 2; i++) { |
|
423 |
isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], |
|
424 |
bs_table[2 * i], bs_table[2 * i + 1]); |
|
425 |
} |
|
414 | 426 |
} |
427 |
|
|
415 | 428 |
kbd_init(); |
416 | 429 |
DMA_init(); |
417 | 430 |
|
... | ... | |
426 | 439 |
floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); |
427 | 440 |
|
428 | 441 |
cmos_init(ram_size, boot_device); |
442 |
|
|
443 |
/* must be done after all PCI devices are instanciated */ |
|
444 |
/* XXX: should be done in the Bochs BIOS */ |
|
445 |
if (pci_enabled) { |
|
446 |
pci_bios_init(); |
|
447 |
} |
|
429 | 448 |
} |
b/hw/pci.c | ||
---|---|---|
1 |
/* |
|
2 |
* QEMU PCI bus manager |
|
3 |
* |
|
4 |
* Copyright (c) 2004 Fabrice Bellard |
|
5 |
* |
|
6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
7 |
* of this software and associated documentation files (the "Software"), to deal |
|
8 |
* in the Software without restriction, including without limitation the rights |
|
9 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
10 |
* copies of the Software, and to permit persons to whom the Software is |
|
11 |
* furnished to do so, subject to the following conditions: |
|
12 |
* |
|
13 |
* The above copyright notice and this permission notice shall be included in |
|
14 |
* all copies or substantial portions of the Software. |
|
15 |
* |
|
16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
17 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
18 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
19 |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
20 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
21 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
22 |
* THE SOFTWARE. |
|
23 |
*/ |
|
24 |
#include "vl.h" |
|
25 |
|
|
26 |
//#define DEBUG_PCI |
|
27 |
|
|
28 |
typedef struct PCIBridge { |
|
29 |
uint32_t config_reg; |
|
30 |
PCIDevice **pci_bus[256]; |
|
31 |
} PCIBridge; |
|
32 |
|
|
33 |
static PCIBridge pci_bridge; |
|
34 |
target_phys_addr_t pci_mem_base; |
|
35 |
|
|
36 |
/* -1 for devfn means auto assign */ |
|
37 |
PCIDevice *pci_register_device(const char *name, int instance_size, |
|
38 |
int bus_num, int devfn, |
|
39 |
PCIConfigReadFunc *config_read, |
|
40 |
PCIConfigWriteFunc *config_write) |
|
41 |
{ |
|
42 |
PCIBridge *s = &pci_bridge; |
|
43 |
PCIDevice *pci_dev, **bus; |
|
44 |
|
|
45 |
if (!s->pci_bus[bus_num]) { |
|
46 |
s->pci_bus[bus_num] = qemu_mallocz(256 * sizeof(PCIDevice *)); |
|
47 |
if (!s->pci_bus[bus_num]) |
|
48 |
return NULL; |
|
49 |
} |
|
50 |
bus = s->pci_bus[bus_num]; |
|
51 |
if (devfn < 0) { |
|
52 |
for(devfn = 0 ; devfn < 256; devfn += 8) { |
|
53 |
if (!bus[devfn]) |
|
54 |
goto found; |
|
55 |
} |
|
56 |
return NULL; |
|
57 |
found: ; |
|
58 |
} |
|
59 |
pci_dev = qemu_mallocz(instance_size); |
|
60 |
if (!pci_dev) |
|
61 |
return NULL; |
|
62 |
pci_dev->bus_num = bus_num; |
|
63 |
pci_dev->devfn = devfn; |
|
64 |
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); |
|
65 |
pci_dev->config_read = config_read; |
|
66 |
pci_dev->config_write = config_write; |
|
67 |
bus[devfn] = pci_dev; |
|
68 |
return pci_dev; |
|
69 |
} |
|
70 |
|
|
71 |
void pci_register_io_region(PCIDevice *pci_dev, int region_num, |
|
72 |
uint32_t size, int type, |
|
73 |
PCIMapIORegionFunc *map_func) |
|
74 |
{ |
|
75 |
PCIIORegion *r; |
|
76 |
|
|
77 |
if ((unsigned int)region_num >= 6) |
|
78 |
return; |
|
79 |
r = &pci_dev->io_regions[region_num]; |
|
80 |
r->addr = -1; |
|
81 |
r->size = size; |
|
82 |
r->type = type; |
|
83 |
r->map_func = map_func; |
|
84 |
} |
|
85 |
|
|
86 |
static void pci_config_writel(void* opaque, uint32_t addr, uint32_t val) |
|
87 |
{ |
|
88 |
PCIBridge *s = opaque; |
|
89 |
s->config_reg = val; |
|
90 |
} |
|
91 |
|
|
92 |
static uint32_t pci_config_readl(void* opaque, uint32_t addr) |
|
93 |
{ |
|
94 |
PCIBridge *s = opaque; |
|
95 |
return s->config_reg; |
|
96 |
} |
|
97 |
|
|
98 |
static void unmap_region(PCIIORegion *r) |
|
99 |
{ |
|
100 |
if (r->addr == -1) |
|
101 |
return; |
|
102 |
#ifdef DEBUG_PCI |
|
103 |
printf("unmap addr=%08x size=%08x\n", r->addr, r->size); |
|
104 |
#endif |
|
105 |
if (r->type & PCI_ADDRESS_SPACE_IO) { |
|
106 |
isa_unassign_ioport(r->addr, r->size); |
|
107 |
} else { |
|
108 |
cpu_register_physical_memory(r->addr + pci_mem_base, r->size, |
|
109 |
IO_MEM_UNASSIGNED); |
|
110 |
} |
|
111 |
} |
|
112 |
|
|
113 |
static void pci_data_write(void *opaque, uint32_t addr, |
|
114 |
uint32_t val, int len) |
|
115 |
{ |
|
116 |
PCIBridge *s = opaque; |
|
117 |
PCIDevice **bus, *pci_dev; |
|
118 |
int config_addr, reg; |
|
119 |
|
|
120 |
#if defined(DEBUG_PCI) && 0 |
|
121 |
printf("pci_data_write: addr=%08x val=%08x len=%d\n", |
|
122 |
s->config_reg, val, len); |
|
123 |
#endif |
|
124 |
if (!(s->config_reg & (1 << 31))) { |
|
125 |
return; |
|
126 |
} |
|
127 |
if ((s->config_reg & 0x3) != 0) { |
|
128 |
return; |
|
129 |
} |
|
130 |
bus = s->pci_bus[(s->config_reg >> 16) & 0xff]; |
|
131 |
if (!bus) |
|
132 |
return; |
|
133 |
pci_dev = bus[(s->config_reg >> 8) & 0xff]; |
|
134 |
if (!pci_dev) |
|
135 |
return; |
|
136 |
config_addr = (s->config_reg & 0xfc) | (addr & 3); |
|
137 |
|
|
138 |
#if defined(DEBUG_PCI) |
|
139 |
printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n", |
|
140 |
pci_dev->name, config_addr, val, len); |
|
141 |
#endif |
|
142 |
if (len == 4 && (config_addr >= 0x10 && config_addr < 0x10 + 4 * 6)) { |
|
143 |
PCIIORegion *r; |
|
144 |
reg = (config_addr - 0x10) >> 2; |
|
145 |
r = &pci_dev->io_regions[reg]; |
|
146 |
if (r->size == 0) |
|
147 |
goto default_config; |
|
148 |
if (val != 0xffffffff && val != 0) { |
|
149 |
/* XXX: the memory assignment should be global to handle |
|
150 |
overlaps, but it is not needed at this stage */ |
|
151 |
/* first unmap the old region */ |
|
152 |
unmap_region(r); |
|
153 |
/* change the address */ |
|
154 |
if (r->type & PCI_ADDRESS_SPACE_IO) |
|
155 |
r->addr = val & ~0x3; |
|
156 |
else |
|
157 |
r->addr = val & ~0xf; |
|
158 |
#ifdef DEBUG_PCI |
|
159 |
printf("map addr=%08x size=%08x type=%d\n", |
|
160 |
r->addr, r->size, r->type); |
|
161 |
#endif |
|
162 |
r->map_func(pci_dev, reg, r->addr, r->size, r->type); |
|
163 |
} |
|
164 |
/* now compute the stored value */ |
|
165 |
val &= ~(r->size - 1); |
|
166 |
val |= r->type; |
|
167 |
*(uint32_t *)(pci_dev->config + 0x10 + reg * 4) = cpu_to_le32(val); |
|
168 |
} else { |
|
169 |
default_config: |
|
170 |
pci_dev->config_write(pci_dev, config_addr, val, len); |
|
171 |
} |
|
172 |
} |
|
173 |
|
|
174 |
static uint32_t pci_data_read(void *opaque, uint32_t addr, |
|
175 |
int len) |
|
176 |
{ |
|
177 |
PCIBridge *s = opaque; |
|
178 |
PCIDevice **bus, *pci_dev; |
|
179 |
int config_addr; |
|
180 |
uint32_t val; |
|
181 |
|
|
182 |
if (!(s->config_reg & (1 << 31))) |
|
183 |
goto fail; |
|
184 |
if ((s->config_reg & 0x3) != 0) |
|
185 |
goto fail; |
|
186 |
bus = s->pci_bus[(s->config_reg >> 16) & 0xff]; |
|
187 |
if (!bus) |
|
188 |
goto fail; |
|
189 |
pci_dev = bus[(s->config_reg >> 8) & 0xff]; |
|
190 |
if (!pci_dev) { |
|
191 |
fail: |
|
192 |
val = 0; |
|
193 |
goto the_end; |
|
194 |
} |
|
195 |
config_addr = (s->config_reg & 0xfc) | (addr & 3); |
|
196 |
val = pci_dev->config_read(pci_dev, config_addr, len); |
|
197 |
#if defined(DEBUG_PCI) |
|
198 |
printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n", |
|
199 |
pci_dev->name, config_addr, val, len); |
|
200 |
#endif |
|
201 |
the_end: |
|
202 |
#if defined(DEBUG_PCI) && 0 |
|
203 |
printf("pci_data_read: addr=%08x val=%08x len=%d\n", |
|
204 |
s->config_reg, val, len); |
|
205 |
#endif |
|
206 |
return val; |
|
207 |
} |
|
208 |
|
|
209 |
static void pci_data_writeb(void* opaque, uint32_t addr, uint32_t val) |
|
210 |
{ |
|
211 |
pci_data_write(opaque, addr, val, 1); |
|
212 |
} |
|
213 |
|
|
214 |
static void pci_data_writew(void* opaque, uint32_t addr, uint32_t val) |
|
215 |
{ |
|
216 |
pci_data_write(opaque, addr, val, 2); |
|
217 |
} |
|
218 |
|
|
219 |
static void pci_data_writel(void* opaque, uint32_t addr, uint32_t val) |
|
220 |
{ |
|
221 |
pci_data_write(opaque, addr, val, 4); |
|
222 |
} |
|
223 |
|
|
224 |
static uint32_t pci_data_readb(void* opaque, uint32_t addr) |
|
225 |
{ |
|
226 |
return pci_data_read(opaque, addr, 1); |
|
227 |
} |
|
228 |
|
|
229 |
static uint32_t pci_data_readw(void* opaque, uint32_t addr) |
|
230 |
{ |
|
231 |
return pci_data_read(opaque, addr, 2); |
|
232 |
} |
|
233 |
|
|
234 |
static uint32_t pci_data_readl(void* opaque, uint32_t addr) |
|
235 |
{ |
|
236 |
return pci_data_read(opaque, addr, 4); |
|
237 |
} |
|
238 |
|
|
239 |
/* i440FX PCI bridge */ |
|
240 |
|
|
241 |
static uint32_t i440_read_config(PCIDevice *d, |
|
242 |
uint32_t address, int len) |
|
243 |
{ |
|
244 |
uint32_t val; |
|
245 |
val = 0; |
|
246 |
memcpy(&val, d->config + address, len); |
|
247 |
return val; |
|
248 |
} |
|
249 |
|
|
250 |
static void i440_write_config(PCIDevice *d, |
|
251 |
uint32_t address, uint32_t val, int len) |
|
252 |
{ |
|
253 |
memcpy(d->config + address, &val, len); |
|
254 |
} |
|
255 |
|
|
256 |
void i440fx_init(void) |
|
257 |
{ |
|
258 |
PCIBridge *s = &pci_bridge; |
|
259 |
PCIDevice *d; |
|
260 |
|
|
261 |
register_ioport_write(0xcf8, 4, 4, pci_config_writel, s); |
|
262 |
register_ioport_read(0xcf8, 4, 4, pci_config_readl, s); |
|
263 |
|
|
264 |
register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s); |
|
265 |
register_ioport_write(0xcfc, 4, 2, pci_data_writew, s); |
|
266 |
register_ioport_write(0xcfc, 4, 4, pci_data_writel, s); |
|
267 |
register_ioport_read(0xcfc, 4, 1, pci_data_readb, s); |
|
268 |
register_ioport_read(0xcfc, 4, 2, pci_data_readw, s); |
|
269 |
register_ioport_read(0xcfc, 4, 4, pci_data_readl, s); |
|
270 |
|
|
271 |
d = pci_register_device("i440FX", sizeof(PCIDevice), 0, 0, |
|
272 |
i440_read_config, i440_write_config); |
|
273 |
|
|
274 |
d->config[0x00] = 0x86; // vendor_id |
|
275 |
d->config[0x01] = 0x80; |
|
276 |
d->config[0x02] = 0x37; // device_id |
|
277 |
d->config[0x03] = 0x12; |
|
278 |
d->config[0x08] = 0x02; // revision |
|
279 |
d->config[0x0a] = 0x04; // class_sub = pci2pci |
|
280 |
d->config[0x0b] = 0x06; // class_base = PCI_bridge |
|
281 |
d->config[0x0c] = 0x01; // line_size in 32 bit words |
|
282 |
d->config[0x0e] = 0x01; // header_type |
|
283 |
} |
|
284 |
|
|
285 |
/* NOTE: the following should be done by the BIOS */ |
|
286 |
|
|
287 |
static uint32_t pci_bios_io_addr; |
|
288 |
static uint32_t pci_bios_mem_addr; |
|
289 |
|
|
290 |
static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr) |
|
291 |
{ |
|
292 |
PCIBridge *s = &pci_bridge; |
|
293 |
PCIIORegion *r; |
|
294 |
|
|
295 |
s->config_reg = 0x80000000 | (d->bus_num << 16) | |
|
296 |
(d->devfn << 8) | (0x10 + region_num * 4); |
|
297 |
pci_data_write(s, 0, addr, 4); |
|
298 |
r = &d->io_regions[region_num]; |
|
299 |
|
|
300 |
/* enable memory mappings */ |
|
301 |
if (r->type & PCI_ADDRESS_SPACE_IO) |
|
302 |
d->config[0x04] |= 1; |
|
303 |
else |
|
304 |
d->config[0x04] |= 2; |
|
305 |
} |
|
306 |
|
|
307 |
|
|
308 |
static void pci_bios_init_device(PCIDevice *d) |
|
309 |
{ |
|
310 |
int class; |
|
311 |
PCIIORegion *r; |
|
312 |
uint32_t *paddr; |
|
313 |
int i; |
|
314 |
|
|
315 |
class = d->config[0x0a] | (d->config[0x0b] << 8); |
|
316 |
switch(class) { |
|
317 |
case 0x0101: |
|
318 |
/* IDE: we map it as in ISA mode */ |
|
319 |
pci_set_io_region_addr(d, 0, 0x1f0); |
|
320 |
pci_set_io_region_addr(d, 1, 0x3f4); |
|
321 |
pci_set_io_region_addr(d, 2, 0x170); |
|
322 |
pci_set_io_region_addr(d, 3, 0x374); |
|
323 |
break; |
|
324 |
default: |
|
325 |
/* default memory mappings */ |
|
326 |
for(i = 0; i < 6; i++) { |
|
327 |
r = &d->io_regions[i]; |
|
328 |
if (r->size) { |
|
329 |
if (r->type & PCI_ADDRESS_SPACE_IO) |
|
330 |
paddr = &pci_bios_io_addr; |
|
331 |
else |
|
332 |
paddr = &pci_bios_mem_addr; |
|
333 |
*paddr = (*paddr + r->size - 1) & ~(r->size - 1); |
|
334 |
pci_set_io_region_addr(d, i, *paddr); |
|
335 |
*paddr += r->size; |
|
336 |
} |
|
337 |
} |
|
338 |
break; |
|
339 |
} |
|
340 |
} |
|
341 |
|
|
342 |
/* |
|
343 |
* This function initializes the PCI devices as a normal PCI BIOS |
|
344 |
* would do. It is provided just in case the BIOS has no support for |
|
345 |
* PCI. |
|
346 |
*/ |
|
347 |
void pci_bios_init(void) |
|
348 |
{ |
|
349 |
PCIBridge *s = &pci_bridge; |
|
350 |
PCIDevice **bus; |
|
351 |
int bus_num, devfn; |
|
352 |
|
|
353 |
pci_bios_io_addr = 0xc000; |
|
354 |
pci_bios_mem_addr = 0xf0000000; |
|
355 |
|
|
356 |
for(bus_num = 0; bus_num < 256; bus_num++) { |
|
357 |
bus = s->pci_bus[bus_num]; |
|
358 |
if (bus) { |
|
359 |
for(devfn = 0; devfn < 256; devfn++) { |
|
360 |
if (bus[devfn]) |
|
361 |
pci_bios_init_device(bus[devfn]); |
|
362 |
} |
|
363 |
} |
|
364 |
} |
|
365 |
} |
|
366 |
|
|
367 |
|
b/hw/pci2isa.c | ||
---|---|---|
1 |
/* |
|
2 |
* QEMU PCI to ISA bridge |
|
3 |
* |
|
4 |
* Copyright (c) 2004 Fabrice Bellard |
|
5 |
* |
|
6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
7 |
* of this software and associated documentation files (the "Software"), to deal |
|
8 |
* in the Software without restriction, including without limitation the rights |
|
9 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
10 |
* copies of the Software, and to permit persons to whom the Software is |
|
11 |
* furnished to do so, subject to the following conditions: |
|
12 |
* |
|
13 |
* The above copyright notice and this permission notice shall be included in |
|
14 |
* all copies or substantial portions of the Software. |
|
15 |
* |
|
16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
17 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
18 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
19 |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
20 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
21 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
22 |
* THE SOFTWARE. |
|
23 |
*/ |
|
24 |
#include "vl.h" |
|
25 |
|
|
26 |
//#define DEBUG_PCI |
|
27 |
|
|
28 |
typedef struct PIIX3State { |
|
29 |
PCIDevice dev; |
|
30 |
uint8_t elcr1; |
|
31 |
uint8_t elcr2; |
|
32 |
} PIIX3State; |
|
33 |
|
|
34 |
static void piix3_reset(PIIX3State *d) |
|
35 |
{ |
|
36 |
uint8_t *pci_conf = d->dev.config; |
|
37 |
|
|
38 |
pci_conf[0x04] = 0x07; // master, memory and I/O |
|
39 |
pci_conf[0x05] = 0x00; |
|
40 |
pci_conf[0x06] = 0x00; |
|
41 |
pci_conf[0x07] = 0x02; // PCI_status_devsel_medium |
|
42 |
pci_conf[0x4c] = 0x4d; |
|
43 |
pci_conf[0x4e] = 0x03; |
|
44 |
pci_conf[0x4f] = 0x00; |
|
45 |
pci_conf[0x60] = 0x80; |
|
46 |
pci_conf[0x69] = 0x02; |
|
47 |
pci_conf[0x70] = 0x80; |
|
48 |
pci_conf[0x76] = 0x0c; |
|
49 |
pci_conf[0x77] = 0x0c; |
|
50 |
pci_conf[0x78] = 0x02; |
|
51 |
pci_conf[0x79] = 0x00; |
|
52 |
pci_conf[0x80] = 0x00; |
|
53 |
pci_conf[0x82] = 0x00; |
|
54 |
pci_conf[0xa0] = 0x08; |
|
55 |
pci_conf[0xa0] = 0x08; |
|
56 |
pci_conf[0xa2] = 0x00; |
|
57 |
pci_conf[0xa3] = 0x00; |
|
58 |
pci_conf[0xa4] = 0x00; |
|
59 |
pci_conf[0xa5] = 0x00; |
|
60 |
pci_conf[0xa6] = 0x00; |
|
61 |
pci_conf[0xa7] = 0x00; |
|
62 |
pci_conf[0xa8] = 0x0f; |
|
63 |
pci_conf[0xaa] = 0x00; |
|
64 |
pci_conf[0xab] = 0x00; |
|
65 |
pci_conf[0xac] = 0x00; |
|
66 |
pci_conf[0xae] = 0x00; |
|
67 |
|
|
68 |
d->elcr1 = 0x00; |
|
69 |
d->elcr2 = 0x00; |
|
70 |
} |
|
71 |
|
|
72 |
static uint32_t piix3_read_config(PCIDevice *d, |
|
73 |
uint32_t address, int len) |
|
74 |
{ |
|
75 |
uint32_t val; |
|
76 |
val = 0; |
|
77 |
memcpy(&val, d->config + address, len); |
|
78 |
return val; |
|
79 |
} |
|
80 |
|
|
81 |
static void piix3_write_config(PCIDevice *d, |
|
82 |
uint32_t address, uint32_t val, int len) |
|
83 |
{ |
|
84 |
memcpy(d->config + address, &val, len); |
|
85 |
} |
|
86 |
|
|
87 |
void piix3_init(void) |
|
88 |
{ |
|
89 |
PIIX3State *d; |
|
90 |
uint8_t *pci_conf; |
|
91 |
|
|
92 |
d = (PIIX3State *)pci_register_device("PIIX3", sizeof(PIIX3State), |
|
93 |
0, -1, |
|
94 |
piix3_read_config, |
|
95 |
piix3_write_config); |
|
96 |
pci_conf = d->dev.config; |
|
97 |
|
|
98 |
pci_conf[0x00] = 0x86; // Intel |
|
99 |
pci_conf[0x01] = 0x80; |
|
100 |
pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1) |
|
101 |
pci_conf[0x03] = 0x70; |
|
102 |
pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA |
|
103 |
pci_conf[0x0b] = 0x06; // class_base = PCI_bridge |
|
104 |
pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic |
|
105 |
|
|
106 |
piix3_reset(d); |
|
107 |
} |
b/hw/ppc_prep.c | ||
---|---|---|
962 | 962 |
if (nb_nics1 > NE2000_NB_MAX) |
963 | 963 |
nb_nics1 = NE2000_NB_MAX; |
964 | 964 |
for(i = 0; i < nb_nics1; i++) { |
965 |
ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]); |
|
965 |
isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
|
|
966 | 966 |
} |
967 | 967 |
#endif |
968 | 968 |
|
969 | 969 |
for(i = 0; i < 2; i++) { |
970 |
ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], |
|
971 |
bs_table[2 * i], bs_table[2 * i + 1]); |
|
970 |
isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
|
|
971 |
bs_table[2 * i], bs_table[2 * i + 1]);
|
|
972 | 972 |
} |
973 | 973 |
kbd_init(); |
974 | 974 |
AUD_init(); |
b/vl.c | ||
---|---|---|
121 | 121 |
QEMUTimer *gui_timer; |
122 | 122 |
int vm_running; |
123 | 123 |
int audio_enabled = 0; |
124 |
int pci_enabled = 0; |
|
124 | 125 |
|
125 | 126 |
/***********************************************************/ |
126 | 127 |
/* x86 ISA bus support */ |
... | ... | |
238 | 239 |
return 0; |
239 | 240 |
} |
240 | 241 |
|
242 |
void isa_unassign_ioport(int start, int length) |
|
243 |
{ |
|
244 |
int i; |
|
245 |
|
|
246 |
for(i = start; i < start + length; i++) { |
|
247 |
ioport_read_table[0][i] = default_ioport_readb; |
|
248 |
ioport_read_table[1][i] = default_ioport_readw; |
|
249 |
ioport_read_table[2][i] = default_ioport_readl; |
|
250 |
|
|
251 |
ioport_write_table[0][i] = default_ioport_writeb; |
|
252 |
ioport_write_table[1][i] = default_ioport_writew; |
|
253 |
ioport_write_table[2][i] = default_ioport_writel; |
|
254 |
} |
|
255 |
} |
|
256 |
|
|
241 | 257 |
void pstrcpy(char *buf, int buf_size, const char *str) |
242 | 258 |
{ |
243 | 259 |
int c; |
... | ... | |
1973 | 1989 |
QEMU_OPTION_hdachs, |
1974 | 1990 |
QEMU_OPTION_L, |
1975 | 1991 |
QEMU_OPTION_no_code_copy, |
1992 |
QEMU_OPTION_pci, |
|
1976 | 1993 |
}; |
1977 | 1994 |
|
1978 | 1995 |
typedef struct QEMUOption { |
... | ... | |
1999 | 2016 |
|
2000 | 2017 |
{ "nics", HAS_ARG, QEMU_OPTION_nics}, |
2001 | 2018 |
{ "macaddr", HAS_ARG, QEMU_OPTION_macaddr}, |
2002 |
{ "n", HAS_ARG, QEMU_OPTION_d },
|
|
2019 |
{ "n", HAS_ARG, QEMU_OPTION_n },
|
|
2003 | 2020 |
{ "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd }, |
2004 | 2021 |
#ifdef CONFIG_SLIRP |
2005 | 2022 |
{ "user-net", 0, QEMU_OPTION_user_net }, |
... | ... | |
2017 | 2034 |
{ "hdachs", HAS_ARG, QEMU_OPTION_hdachs }, |
2018 | 2035 |
{ "L", HAS_ARG, QEMU_OPTION_L }, |
2019 | 2036 |
{ "no-code-copy", 0, QEMU_OPTION_no_code_copy }, |
2037 |
{ "pci", 0, QEMU_OPTION_pci }, |
|
2020 | 2038 |
{ NULL }, |
2021 | 2039 |
}; |
2022 | 2040 |
|
... | ... | |
2286 | 2304 |
case QEMU_OPTION_S: |
2287 | 2305 |
start_emulation = 0; |
2288 | 2306 |
break; |
2307 |
case QEMU_OPTION_pci: |
|
2308 |
pci_enabled = 1; |
|
2309 |
break; |
|
2289 | 2310 |
} |
2290 | 2311 |
} |
2291 | 2312 |
} |
b/vl.h | ||
---|---|---|
218 | 218 |
|
219 | 219 |
/* The real time clock should be used only for stuff which does not |
220 | 220 |
change the virtual machine state, as it is run even if the virtual |
221 |
machine is stopped. The real time clock has a frequency or 1000
|
|
221 |
machine is stopped. The real time clock has a frequency of 1000
|
|
222 | 222 |
Hz. */ |
223 | 223 |
extern QEMUClock *rt_clock; |
224 | 224 |
|
... | ... | |
360 | 360 |
IOPortReadFunc *func, void *opaque); |
361 | 361 |
int register_ioport_write(int start, int length, int size, |
362 | 362 |
IOPortWriteFunc *func, void *opaque); |
363 |
void isa_unassign_ioport(int start, int length); |
|
364 |
|
|
365 |
/* PCI bus */ |
|
366 |
|
|
367 |
extern int pci_enabled; |
|
368 |
|
|
369 |
extern target_phys_addr_t pci_mem_base; |
|
370 |
|
|
371 |
typedef struct PCIDevice PCIDevice; |
|
372 |
|
|
373 |
typedef void PCIConfigWriteFunc(PCIDevice *pci_dev, |
|
374 |
uint32_t address, uint32_t data, int len); |
|
375 |
typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev, |
|
376 |
uint32_t address, int len); |
|
377 |
typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num, |
|
378 |
uint32_t addr, uint32_t size, int type); |
|
379 |
|
|
380 |
#define PCI_ADDRESS_SPACE_MEM 0x00 |
|
381 |
#define PCI_ADDRESS_SPACE_IO 0x01 |
|
382 |
#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08 |
|
383 |
|
|
384 |
typedef struct PCIIORegion { |
|
385 |
uint32_t addr; |
|
386 |
uint32_t size; |
|
387 |
uint8_t type; |
|
388 |
PCIMapIORegionFunc *map_func; |
|
389 |
} PCIIORegion; |
|
390 |
|
|
391 |
struct PCIDevice { |
|
392 |
/* PCI config space */ |
|
393 |
uint8_t config[256]; |
|
394 |
|
|
395 |
/* the following fields are read only */ |
|
396 |
int bus_num; |
|
397 |
int devfn; |
|
398 |
char name[64]; |
|
399 |
PCIIORegion io_regions[6]; |
|
400 |
|
|
401 |
/* do not access the following fields */ |
|
402 |
PCIConfigReadFunc *config_read; |
|
403 |
PCIConfigWriteFunc *config_write; |
|
404 |
}; |
|
405 |
|
|
406 |
PCIDevice *pci_register_device(const char *name, int instance_size, |
|
407 |
int bus_num, int devfn, |
|
408 |
PCIConfigReadFunc *config_read, |
|
409 |
PCIConfigWriteFunc *config_write); |
|
410 |
|
|
411 |
void pci_register_io_region(PCIDevice *pci_dev, int region_num, |
|
412 |
uint32_t size, int type, |
|
413 |
PCIMapIORegionFunc *map_func); |
|
414 |
|
|
415 |
void i440fx_init(void); |
|
416 |
void piix3_init(void); |
|
417 |
void pci_bios_init(void); |
|
363 | 418 |
|
364 | 419 |
/* vga.c */ |
365 | 420 |
|
... | ... | |
397 | 452 |
|
398 | 453 |
extern BlockDriverState *bs_table[MAX_DISKS]; |
399 | 454 |
|
400 |
void ide_init(int iobase, int iobase2, int irq, |
|
401 |
BlockDriverState *hd0, BlockDriverState *hd1); |
|
455 |
void isa_ide_init(int iobase, int iobase2, int irq, |
|
456 |
BlockDriverState *hd0, BlockDriverState *hd1); |
|
457 |
void pci_ide_init(BlockDriverState **hd_table); |
|
402 | 458 |
|
403 | 459 |
/* oss.c */ |
404 | 460 |
typedef enum { |
... | ... | |
446 | 502 |
|
447 | 503 |
/* ne2000.c */ |
448 | 504 |
|
449 |
void ne2000_init(int base, int irq, NetDriverState *nd); |
|
505 |
void isa_ne2000_init(int base, int irq, NetDriverState *nd); |
|
506 |
void pci_ne2000_init(NetDriverState *nd); |
|
450 | 507 |
|
451 | 508 |
/* pckbd.c */ |
452 | 509 |
|
Also available in: Unified diff