diff options
Diffstat (limited to 'hw/isa/piix4.c')
-rw-r--r-- | hw/isa/piix4.c | 116 |
1 files changed, 60 insertions, 56 deletions
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 8607e0a..15f344d 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -34,6 +34,8 @@ #include "hw/timer/i8254.h" #include "hw/rtc/mc146818rtc.h" #include "hw/ide/pci.h" +#include "hw/acpi/piix4.h" +#include "hw/usb/hcd-uhci.h" #include "migration/vmstate.h" #include "sysemu/reset.h" #include "sysemu/runstate.h" @@ -45,6 +47,9 @@ struct PIIX4State { qemu_irq *isa; RTCState rtc; + PCIIDEState ide; + UHCIState uhci; + PIIX4PMState pm; /* Reset Control Register */ MemoryRegion rcr_mem; uint8_t rcr; @@ -73,6 +78,31 @@ static void piix4_set_irq(void *opaque, int irq_num, int level) } } +static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) +{ + int slot; + + slot = PCI_SLOT(pci_dev->devfn); + + switch (slot) { + /* PIIX4 USB */ + case 10: + return 3; + /* AMD 79C973 Ethernet */ + case 11: + return 1; + /* Crystal 4281 Sound */ + case 12: + return 2; + /* PCI slot 1 to 4 */ + case 18 ... 21: + return ((slot - 18) + irq_num) & 0x03; + /* Unknown device, don't do any translation */ + default: + return irq_num; + } +} + static void piix4_isa_reset(DeviceState *dev) { PIIX4State *d = PIIX4_PCI_DEVICE(dev); @@ -179,6 +209,7 @@ static const MemoryRegionOps piix4_rcr_ops = { static void piix4_realize(PCIDevice *dev, Error **errp) { PIIX4State *s = PIIX4_PCI_DEVICE(dev); + PCIBus *pci_bus = pci_get_bus(dev); ISABus *isa_bus; qemu_irq *i8259_out_irq; @@ -217,13 +248,41 @@ static void piix4_realize(PCIDevice *dev, Error **errp) return; } s->rtc.irq = isa_get_irq(ISA_DEVICE(&s->rtc), s->rtc.isairq); + + /* IDE */ + qdev_prop_set_int32(DEVICE(&s->ide), "addr", dev->devfn + 1); + if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) { + return; + } + pci_ide_create_devs(PCI_DEVICE(&s->ide)); + + /* USB */ + qdev_prop_set_int32(DEVICE(&s->uhci), "addr", dev->devfn + 2); + if (!qdev_realize(DEVICE(&s->uhci), BUS(pci_bus), errp)) { + return; + } + + /* ACPI controller */ + qdev_prop_set_int32(DEVICE(&s->pm), "addr", dev->devfn + 3); + if (!qdev_realize(DEVICE(&s->pm), BUS(pci_bus), errp)) { + return; + } + qdev_connect_gpio_out(DEVICE(&s->pm), 0, s->isa[9]); + + pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS); } static void piix4_init(Object *obj) { PIIX4State *s = PIIX4_PCI_DEVICE(obj); - object_initialize(&s->rtc, sizeof(s->rtc), TYPE_MC146818_RTC); + object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC); + object_initialize_child(obj, "ide", &s->ide, "piix4-ide"); + object_initialize_child(obj, "uhci", &s->uhci, "piix4-usb-uhci"); + + object_initialize_child(obj, "pm", &s->pm, TYPE_PIIX4_PM); + qdev_prop_set_uint32(DEVICE(&s->pm), "smb_io_base", 0x1100); + qdev_prop_set_bit(DEVICE(&s->pm), "smm-enabled", 0); } static void piix4_class_init(ObjectClass *klass, void *data) @@ -264,58 +323,3 @@ static void piix4_register_types(void) } type_init(piix4_register_types) - -static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) -{ - int slot; - - slot = PCI_SLOT(pci_dev->devfn); - - switch (slot) { - /* PIIX4 USB */ - case 10: - return 3; - /* AMD 79C973 Ethernet */ - case 11: - return 1; - /* Crystal 4281 Sound */ - case 12: - return 2; - /* PCI slot 1 to 4 */ - case 18 ... 21: - return ((slot - 18) + irq_num) & 0x03; - /* Unknown device, don't do any translation */ - default: - return irq_num; - } -} - -DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus) -{ - PIIX4State *s; - PCIDevice *pci; - DeviceState *dev; - int devfn = PCI_DEVFN(10, 0); - - pci = pci_create_simple_multifunction(pci_bus, devfn, true, - TYPE_PIIX4_PCI_DEVICE); - dev = DEVICE(pci); - s = PIIX4_PCI_DEVICE(pci); - if (isa_bus) { - *isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0")); - } - - pci = pci_create_simple(pci_bus, devfn + 1, "piix4-ide"); - pci_ide_create_devs(pci); - - pci_create_simple(pci_bus, devfn + 2, "piix4-usb-uhci"); - if (smbus) { - *smbus = piix4_pm_init(pci_bus, devfn + 3, 0x1100, - qdev_get_gpio_in_named(dev, "isa", 9), - NULL, 0, NULL); - } - - pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS); - - return dev; -} |