Revision ac404095 hw/acpi_piix4.c
b/hw/acpi_piix4.c | ||
---|---|---|
29 | 29 |
|
30 | 30 |
#define ACPI_DBG_IO_ADDR 0xb044 |
31 | 31 |
|
32 |
#define GPE_BASE 0xafe0 |
|
33 |
#define PCI_BASE 0xae00 |
|
34 |
#define PCI_EJ_BASE 0xae08 |
|
35 |
|
|
36 |
struct gpe_regs { |
|
37 |
uint16_t sts; /* status */ |
|
38 |
uint16_t en; /* enabled */ |
|
39 |
}; |
|
40 |
|
|
41 |
struct pci_status { |
|
42 |
uint32_t up; |
|
43 |
uint32_t down; |
|
44 |
}; |
|
45 |
|
|
32 | 46 |
typedef struct PIIX4PMState { |
33 | 47 |
PCIDevice dev; |
34 | 48 |
uint16_t pmsts; |
... | ... | |
47 | 61 |
qemu_irq cmos_s3; |
48 | 62 |
qemu_irq smi_irq; |
49 | 63 |
int kvm_enabled; |
64 |
|
|
65 |
/* for pci hotplug */ |
|
66 |
struct gpe_regs gpe; |
|
67 |
struct pci_status pci0_status; |
|
50 | 68 |
} PIIX4PMState; |
51 | 69 |
|
70 |
static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s); |
|
71 |
|
|
52 | 72 |
#define ACPI_ENABLE 0xf1 |
53 | 73 |
#define ACPI_DISABLE 0xf0 |
54 | 74 |
|
55 |
static PIIX4PMState *pm_state; |
|
56 |
|
|
57 | 75 |
static uint32_t get_pmtmr(PIIX4PMState *s) |
58 | 76 |
{ |
59 | 77 |
uint32_t d; |
... | ... | |
325 | 343 |
PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev); |
326 | 344 |
uint8_t *pci_conf; |
327 | 345 |
|
328 |
pm_state = s; |
|
329 | 346 |
pci_conf = s->dev.config; |
330 | 347 |
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); |
331 | 348 |
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_3); |
... | ... | |
369 | 386 |
|
370 | 387 |
pm_smbus_init(&s->dev.qdev, &s->smb); |
371 | 388 |
qemu_register_reset(piix4_reset, s); |
389 |
piix4_acpi_system_hot_add_init(dev->bus, s); |
|
372 | 390 |
|
373 | 391 |
return 0; |
374 | 392 |
} |
... | ... | |
414 | 432 |
|
415 | 433 |
device_init(piix4_pm_register); |
416 | 434 |
|
417 |
#define GPE_BASE 0xafe0 |
|
418 |
#define PCI_BASE 0xae00 |
|
419 |
#define PCI_EJ_BASE 0xae08 |
|
420 |
|
|
421 |
struct gpe_regs { |
|
422 |
uint16_t sts; /* status */ |
|
423 |
uint16_t en; /* enabled */ |
|
424 |
}; |
|
425 |
|
|
426 |
struct pci_status { |
|
427 |
uint32_t up; |
|
428 |
uint32_t down; |
|
429 |
}; |
|
430 |
|
|
431 |
static struct gpe_regs gpe; |
|
432 |
static struct pci_status pci0_status; |
|
433 |
|
|
434 | 435 |
static uint32_t gpe_read_val(uint16_t val, uint32_t addr) |
435 | 436 |
{ |
436 | 437 |
if (addr & 1) |
... | ... | |
570 | 571 |
|
571 | 572 |
static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state); |
572 | 573 |
|
573 |
void piix4_acpi_system_hot_add_init(PCIBus *bus)
|
|
574 |
static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
|
|
574 | 575 |
{ |
575 |
register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
|
|
576 |
register_ioport_read(GPE_BASE, 4, 1, gpe_readb, &gpe);
|
|
576 |
struct gpe_regs *gpe = &s->gpe;
|
|
577 |
struct pci_status *pci0_status = &s->pci0_status;
|
|
577 | 578 |
|
578 |
register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status); |
|
579 |
register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, &pci0_status); |
|
579 |
register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, gpe); |
|
580 |
register_ioport_read(GPE_BASE, 4, 1, gpe_readb, gpe); |
|
581 |
|
|
582 |
register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status); |
|
583 |
register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status); |
|
580 | 584 |
|
581 | 585 |
register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, bus); |
582 | 586 |
register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, bus); |
583 | 587 |
|
584 |
pci_bus_hotplug(bus, piix4_device_hotplug, NULL);
|
|
588 |
pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
|
|
585 | 589 |
} |
586 | 590 |
|
587 |
static void enable_device(struct pci_status *p, struct gpe_regs *g, int slot)
|
|
591 |
static void enable_device(PIIX4PMState *s, int slot)
|
|
588 | 592 |
{ |
589 |
g->sts |= 2;
|
|
590 |
p->up |= (1 << slot);
|
|
593 |
s->gpe.sts |= 2;
|
|
594 |
s->pci0_status.up |= (1 << slot);
|
|
591 | 595 |
} |
592 | 596 |
|
593 |
static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot)
|
|
597 |
static void disable_device(PIIX4PMState *s, int slot)
|
|
594 | 598 |
{ |
595 |
g->sts |= 2;
|
|
596 |
p->down |= (1 << slot);
|
|
599 |
s->gpe.sts |= 2;
|
|
600 |
s->pci0_status.down |= (1 << slot);
|
|
597 | 601 |
} |
598 | 602 |
|
599 | 603 |
static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state) |
600 | 604 |
{ |
601 | 605 |
int slot = PCI_SLOT(dev->devfn); |
606 |
PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, |
|
607 |
DO_UPCAST(PCIDevice, qdev, qdev)); |
|
602 | 608 |
|
603 |
pci0_status.up = 0; |
|
604 |
pci0_status.down = 0; |
|
605 |
if (state) |
|
606 |
enable_device(&pci0_status, &gpe, slot); |
|
607 |
else |
|
608 |
disable_device(&pci0_status, &gpe, slot); |
|
609 |
if (gpe.en & 2) { |
|
610 |
qemu_set_irq(pm_state->irq, 1); |
|
611 |
qemu_set_irq(pm_state->irq, 0); |
|
609 |
s->pci0_status.up = 0; |
|
610 |
s->pci0_status.down = 0; |
|
611 |
if (state) { |
|
612 |
enable_device(s, slot); |
|
613 |
} else { |
|
614 |
disable_device(s, slot); |
|
615 |
} |
|
616 |
if (s->gpe.en & 2) { |
|
617 |
qemu_set_irq(s->irq, 1); |
|
618 |
qemu_set_irq(s->irq, 0); |
|
612 | 619 |
} |
613 | 620 |
return 0; |
614 | 621 |
} |
Also available in: Unified diff