diff options
Diffstat (limited to 'hw/acpi_piix4.c')
-rw-r--r-- | hw/acpi_piix4.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 24dfcf2039..66c7885d62 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -22,6 +22,7 @@ #include "pci.h" #include "acpi.h" #include "sysemu.h" +#include "range.h" //#define DEBUG @@ -37,6 +38,8 @@ #define PCI_BASE 0xae00 #define PCI_EJ_BASE 0xae08 +#define PIIX4_PCI_HOTPLUG_STATUS 2 + struct gpe_regs { uint16_t sts; /* status */ uint16_t en; /* enabled */ @@ -104,7 +107,9 @@ static void pm_update_sci(PIIX4PMState *s) (ACPI_BITMASK_RT_CLOCK_ENABLE | ACPI_BITMASK_POWER_BUTTON_ENABLE | ACPI_BITMASK_GLOBAL_LOCK_ENABLE | - ACPI_BITMASK_TIMER_ENABLE)) != 0); + ACPI_BITMASK_TIMER_ENABLE)) != 0) || + (((s->gpe.sts & s->gpe.en) & PIIX4_PCI_HOTPLUG_STATUS) != 0); + qemu_set_irq(s->irq, sci_level); /* schedule a timer interruption if needed */ if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) && @@ -459,7 +464,9 @@ static uint32_t gpe_read_val(uint16_t val, uint32_t addr) static uint32_t gpe_readb(void *opaque, uint32_t addr) { uint32_t val = 0; - struct gpe_regs *g = opaque; + PIIX4PMState *s = opaque; + struct gpe_regs *g = &s->gpe; + switch (addr) { case GPE_BASE: case GPE_BASE + 1: @@ -499,7 +506,9 @@ static void gpe_reset_val(uint16_t *cur, int addr, uint32_t val) static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val) { - struct gpe_regs *g = opaque; + PIIX4PMState *s = opaque; + struct gpe_regs *g = &s->gpe; + switch (addr) { case GPE_BASE: case GPE_BASE + 1: @@ -511,7 +520,9 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val) break; default: break; - } + } + + pm_update_sci(s); PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val); } @@ -578,11 +589,10 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state); static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) { - struct gpe_regs *gpe = &s->gpe; struct pci_status *pci0_status = &s->pci0_status; - register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, gpe); - register_ioport_read(GPE_BASE, 4, 1, gpe_readb, gpe); + register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, s); + register_ioport_read(GPE_BASE, 4, 1, gpe_readb, s); register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status); register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status); @@ -595,13 +605,13 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) static void enable_device(PIIX4PMState *s, int slot) { - s->gpe.sts |= 2; + s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS; s->pci0_status.up |= (1 << slot); } static void disable_device(PIIX4PMState *s, int slot) { - s->gpe.sts |= 2; + s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS; s->pci0_status.down |= (1 << slot); } @@ -621,9 +631,8 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state) } else { disable_device(s, slot); } - if (s->gpe.en & 2) { - qemu_set_irq(s->irq, 1); - qemu_set_irq(s->irq, 0); - } + + pm_update_sci(s); + return 0; } |