aboutsummaryrefslogtreecommitdiff
path: root/hw/isa/piix4.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/isa/piix4.c')
-rw-r--r--hw/isa/piix4.c116
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;
-}