Fix pci hotplug to generate level triggered interrupt.
SCI is level triggered. pci hotplug should behave appropriately. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
4441a2870a
commit
633aa0acfe
@ -107,7 +107,9 @@ static void pm_update_sci(PIIX4PMState *s)
|
|||||||
(ACPI_BITMASK_RT_CLOCK_ENABLE |
|
(ACPI_BITMASK_RT_CLOCK_ENABLE |
|
||||||
ACPI_BITMASK_POWER_BUTTON_ENABLE |
|
ACPI_BITMASK_POWER_BUTTON_ENABLE |
|
||||||
ACPI_BITMASK_GLOBAL_LOCK_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);
|
qemu_set_irq(s->irq, sci_level);
|
||||||
/* schedule a timer interruption if needed */
|
/* schedule a timer interruption if needed */
|
||||||
if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
|
if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
|
||||||
@ -462,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)
|
static uint32_t gpe_readb(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
struct gpe_regs *g = opaque;
|
PIIX4PMState *s = opaque;
|
||||||
|
struct gpe_regs *g = &s->gpe;
|
||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case GPE_BASE:
|
case GPE_BASE:
|
||||||
case GPE_BASE + 1:
|
case GPE_BASE + 1:
|
||||||
@ -502,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)
|
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) {
|
switch (addr) {
|
||||||
case GPE_BASE:
|
case GPE_BASE:
|
||||||
case GPE_BASE + 1:
|
case GPE_BASE + 1:
|
||||||
@ -516,6 +522,8 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_update_sci(s);
|
||||||
|
|
||||||
PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
|
PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,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)
|
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;
|
struct pci_status *pci0_status = &s->pci0_status;
|
||||||
|
|
||||||
register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, gpe);
|
register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, s);
|
||||||
register_ioport_read(GPE_BASE, 4, 1, gpe_readb, gpe);
|
register_ioport_read(GPE_BASE, 4, 1, gpe_readb, s);
|
||||||
|
|
||||||
register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
|
register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
|
||||||
register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status);
|
register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status);
|
||||||
@ -621,9 +628,8 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state)
|
|||||||
} else {
|
} else {
|
||||||
disable_device(s, slot);
|
disable_device(s, slot);
|
||||||
}
|
}
|
||||||
if (s->gpe.en & 2) {
|
|
||||||
qemu_set_irq(s->irq, 1);
|
pm_update_sci(s);
|
||||||
qemu_set_irq(s->irq, 0);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user