acpi: add ACPIREGS

All those acpi structs are not independent from each other.
Various acpi functions expecting multiple acpi structs passed
in are a clean indicator for that ;)

So this patch bundles all acpi structs in the new ACPIREGS
struct, then use it everythere pass around acpi state.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Gerd Hoffmann 2012-02-23 13:45:16 +01:00 committed by Anthony Liguori
parent 067866d61c
commit 355bf2e5ba
4 changed files with 145 additions and 143 deletions

130
hw/acpi.c
View File

@ -249,63 +249,61 @@ int acpi_table_add(const char *t)
}
/* ACPI PM1a EVT */
uint16_t acpi_pm1_evt_get_sts(ACPIPM1EVT *pm1, int64_t overflow_time)
uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar, int64_t overflow_time)
{
int64_t d = acpi_pm_tmr_get_clock();
if (d >= overflow_time) {
pm1->sts |= ACPI_BITMASK_TIMER_STATUS;
ar->pm1.evt.sts |= ACPI_BITMASK_TIMER_STATUS;
}
return pm1->sts;
return ar->pm1.evt.sts;
}
void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val)
void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
{
uint16_t pm1_sts = acpi_pm1_evt_get_sts(pm1, tmr->overflow_time);
uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar, ar->tmr.overflow_time);
if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) {
/* if TMRSTS is reset, then compute the new overflow time */
acpi_pm_tmr_calc_overflow_time(tmr);
acpi_pm_tmr_calc_overflow_time(ar);
}
pm1->sts &= ~val;
ar->pm1.evt.sts &= ~val;
}
void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr)
void acpi_pm1_evt_power_down(ACPIREGS *ar)
{
if (!pm1) {
qemu_system_shutdown_request();
} else if (pm1->en & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
pm1->sts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
tmr->update_sci(tmr);
if (ar->pm1.evt.en & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
ar->pm1.evt.sts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
ar->tmr.update_sci(ar);
}
}
void acpi_pm1_evt_reset(ACPIPM1EVT *pm1)
void acpi_pm1_evt_reset(ACPIREGS *ar)
{
pm1->sts = 0;
pm1->en = 0;
ar->pm1.evt.sts = 0;
ar->pm1.evt.en = 0;
}
/* ACPI PM_TMR */
void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable)
void acpi_pm_tmr_update(ACPIREGS *ar, bool enable)
{
int64_t expire_time;
/* schedule a timer interruption if needed */
if (enable) {
expire_time = muldiv64(tmr->overflow_time, get_ticks_per_sec(),
expire_time = muldiv64(ar->tmr.overflow_time, get_ticks_per_sec(),
PM_TIMER_FREQUENCY);
qemu_mod_timer(tmr->timer, expire_time);
qemu_mod_timer(ar->tmr.timer, expire_time);
} else {
qemu_del_timer(tmr->timer);
qemu_del_timer(ar->tmr.timer);
}
}
void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr)
void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar)
{
int64_t d = acpi_pm_tmr_get_clock();
tmr->overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
ar->tmr.overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
}
uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr)
uint32_t acpi_pm_tmr_get(ACPIREGS *ar)
{
uint32_t d = acpi_pm_tmr_get_clock();
return d & 0xffffff;
@ -313,31 +311,31 @@ uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr)
static void acpi_pm_tmr_timer(void *opaque)
{
ACPIPMTimer *tmr = opaque;
tmr->update_sci(tmr);
ACPIREGS *ar = opaque;
ar->tmr.update_sci(ar);
}
void acpi_pm_tmr_init(ACPIPMTimer *tmr, acpi_update_sci_fn update_sci)
void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci)
{
tmr->update_sci = update_sci;
tmr->timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, tmr);
ar->tmr.update_sci = update_sci;
ar->tmr.timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, ar);
}
void acpi_pm_tmr_reset(ACPIPMTimer *tmr)
void acpi_pm_tmr_reset(ACPIREGS *ar)
{
tmr->overflow_time = 0;
qemu_del_timer(tmr->timer);
ar->tmr.overflow_time = 0;
qemu_del_timer(ar->tmr.timer);
}
/* ACPI PM1aCNT */
void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3)
void acpi_pm1_cnt_init(ACPIREGS *ar, qemu_irq cmos_s3)
{
pm1_cnt->cmos_s3 = cmos_s3;
ar->pm1.cnt.cmos_s3 = cmos_s3;
}
void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val)
void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
{
pm1_cnt->cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
if (val & ACPI_BITMASK_SLEEP_ENABLE) {
/* change suspend type */
@ -349,62 +347,62 @@ void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val)
case 1:
/* ACPI_BITMASK_WAKE_STATUS should be set on resume.
Pretend that resume was caused by power button */
pm1a->sts |=
ar->pm1.evt.sts |=
(ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
qemu_system_reset_request();
qemu_irq_raise(pm1_cnt->cmos_s3);
qemu_irq_raise(ar->pm1.cnt.cmos_s3);
default:
break;
}
}
}
void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable)
{
/* ACPI specs 3.0, 4.7.2.5 */
if (sci_enable) {
pm1_cnt->cnt |= ACPI_BITMASK_SCI_ENABLE;
ar->pm1.cnt.cnt |= ACPI_BITMASK_SCI_ENABLE;
} else if (sci_disable) {
pm1_cnt->cnt &= ~ACPI_BITMASK_SCI_ENABLE;
ar->pm1.cnt.cnt &= ~ACPI_BITMASK_SCI_ENABLE;
}
}
void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt)
void acpi_pm1_cnt_reset(ACPIREGS *ar)
{
pm1_cnt->cnt = 0;
if (pm1_cnt->cmos_s3) {
qemu_irq_lower(pm1_cnt->cmos_s3);
ar->pm1.cnt.cnt = 0;
if (ar->pm1.cnt.cmos_s3) {
qemu_irq_lower(ar->pm1.cnt.cmos_s3);
}
}
/* ACPI GPE */
void acpi_gpe_init(ACPIGPE *gpe, uint8_t len)
void acpi_gpe_init(ACPIREGS *ar, uint8_t len)
{
gpe->len = len;
gpe->sts = g_malloc0(len / 2);
gpe->en = g_malloc0(len / 2);
ar->gpe.len = len;
ar->gpe.sts = g_malloc0(len / 2);
ar->gpe.en = g_malloc0(len / 2);
}
void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk)
void acpi_gpe_blk(ACPIREGS *ar, uint32_t blk)
{
gpe->blk = blk;
ar->gpe.blk = blk;
}
void acpi_gpe_reset(ACPIGPE *gpe)
void acpi_gpe_reset(ACPIREGS *ar)
{
memset(gpe->sts, 0, gpe->len / 2);
memset(gpe->en, 0, gpe->len / 2);
memset(ar->gpe.sts, 0, ar->gpe.len / 2);
memset(ar->gpe.en, 0, ar->gpe.len / 2);
}
static uint8_t *acpi_gpe_ioport_get_ptr(ACPIGPE *gpe, uint32_t addr)
static uint8_t *acpi_gpe_ioport_get_ptr(ACPIREGS *ar, uint32_t addr)
{
uint8_t *cur = NULL;
if (addr < gpe->len / 2) {
cur = gpe->sts + addr;
} else if (addr < gpe->len) {
cur = gpe->en + addr - gpe->len / 2;
if (addr < ar->gpe.len / 2) {
cur = ar->gpe.sts + addr;
} else if (addr < ar->gpe.len) {
cur = ar->gpe.en + addr - ar->gpe.len / 2;
} else {
abort();
}
@ -412,16 +410,16 @@ static uint8_t *acpi_gpe_ioport_get_ptr(ACPIGPE *gpe, uint32_t addr)
return cur;
}
void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val)
void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val)
{
uint8_t *cur;
addr -= gpe->blk;
cur = acpi_gpe_ioport_get_ptr(gpe, addr);
if (addr < gpe->len / 2) {
addr -= ar->gpe.blk;
cur = acpi_gpe_ioport_get_ptr(ar, addr);
if (addr < ar->gpe.len / 2) {
/* GPE_STS */
*cur = (*cur) & ~val;
} else if (addr < gpe->len) {
} else if (addr < ar->gpe.len) {
/* GPE_EN */
*cur = val;
} else {
@ -429,13 +427,13 @@ void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val)
}
}
uint32_t acpi_gpe_ioport_readb(ACPIGPE *gpe, uint32_t addr)
uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
{
uint8_t *cur;
uint32_t val;
addr -= gpe->blk;
cur = acpi_gpe_ioport_get_ptr(gpe, addr);
addr -= ar->gpe.blk;
cur = acpi_gpe_ioport_get_ptr(ar, addr);
val = 0;
if (cur != NULL) {
val = *cur;

View File

@ -78,8 +78,9 @@ typedef struct ACPIPMTimer ACPIPMTimer;
typedef struct ACPIPM1EVT ACPIPM1EVT;
typedef struct ACPIPM1CNT ACPIPM1CNT;
typedef struct ACPIGPE ACPIGPE;
typedef struct ACPIREGS ACPIREGS;
typedef void (*acpi_update_sci_fn)(ACPIPMTimer *tmr);
typedef void (*acpi_update_sci_fn)(ACPIREGS *ar);
struct ACPIPMTimer {
QEMUTimer *timer;
@ -106,12 +107,21 @@ struct ACPIGPE {
uint8_t *en;
};
struct ACPIREGS {
ACPIPMTimer tmr;
ACPIGPE gpe;
struct {
ACPIPM1EVT evt;
ACPIPM1CNT cnt;
} pm1;
};
/* PM_TMR */
void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable);
void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr);
uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr);
void acpi_pm_tmr_init(ACPIPMTimer *tmr, acpi_update_sci_fn update_sci);
void acpi_pm_tmr_reset(ACPIPMTimer *tmr);
void acpi_pm_tmr_update(ACPIREGS *ar, bool enable);
void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar);
uint32_t acpi_pm_tmr_get(ACPIREGS *ar);
void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci);
void acpi_pm_tmr_reset(ACPIREGS *ar);
#include "qemu-timer.h"
static inline int64_t acpi_pm_tmr_get_clock(void)
@ -121,24 +131,24 @@ static inline int64_t acpi_pm_tmr_get_clock(void)
}
/* PM1a_EVT: piix and ich9 don't implement PM1b. */
uint16_t acpi_pm1_evt_get_sts(ACPIPM1EVT *pm1, int64_t overflow_time);
void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val);
void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr);
void acpi_pm1_evt_reset(ACPIPM1EVT *pm1);
uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar, int64_t overflow_time);
void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val);
void acpi_pm1_evt_power_down(ACPIREGS *ar);
void acpi_pm1_evt_reset(ACPIREGS *ar);
/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3);
void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val);
void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
void acpi_pm1_cnt_init(ACPIREGS *ar, qemu_irq cmos_s3);
void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val);
void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable);
void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt);
void acpi_pm1_cnt_reset(ACPIREGS *ar);
/* GPE0 */
void acpi_gpe_init(ACPIGPE *gpe, uint8_t len);
void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk);
void acpi_gpe_reset(ACPIGPE *gpe);
void acpi_gpe_init(ACPIREGS *ar, uint8_t len);
void acpi_gpe_blk(ACPIREGS *ar, uint32_t blk);
void acpi_gpe_reset(ACPIREGS *ar);
void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val);
uint32_t acpi_gpe_ioport_readb(ACPIGPE *gpe, uint32_t addr);
void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val);
uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
#endif /* !QEMU_HW_ACPI_H */

View File

@ -54,13 +54,10 @@ struct pci_status {
typedef struct PIIX4PMState {
PCIDevice dev;
IORange ioport;
ACPIPM1EVT pm1a;
ACPIPM1CNT pm1_cnt;
ACPIREGS ar;
APMState apm;
ACPIPMTimer tmr;
PMSMBus smb;
uint32_t smb_io_base;
@ -70,7 +67,6 @@ typedef struct PIIX4PMState {
Notifier machine_ready;
/* for pci hotplug */
ACPIGPE gpe;
struct pci_status pci0_status;
uint32_t pci0_hotplug_enable;
} PIIX4PMState;
@ -84,23 +80,24 @@ static void pm_update_sci(PIIX4PMState *s)
{
int sci_level, pmsts;
pmsts = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
sci_level = (((pmsts & s->pm1a.en) &
pmsts = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
sci_level = (((pmsts & s->ar.pm1.evt.en) &
(ACPI_BITMASK_RT_CLOCK_ENABLE |
ACPI_BITMASK_POWER_BUTTON_ENABLE |
ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
(((s->gpe.sts[0] & s->gpe.en[0]) & PIIX4_PCI_HOTPLUG_STATUS) != 0);
(((s->ar.gpe.sts[0] & s->ar.gpe.en[0])
& PIIX4_PCI_HOTPLUG_STATUS) != 0);
qemu_set_irq(s->irq, sci_level);
/* schedule a timer interruption if needed */
acpi_pm_tmr_update(&s->tmr, (s->pm1a.en & ACPI_BITMASK_TIMER_ENABLE) &&
acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
!(pmsts & ACPI_BITMASK_TIMER_STATUS));
}
static void pm_tmr_timer(ACPIPMTimer *tmr)
static void pm_tmr_timer(ACPIREGS *ar)
{
PIIX4PMState *s = container_of(tmr, PIIX4PMState, tmr);
PIIX4PMState *s = container_of(ar, PIIX4PMState, ar);
pm_update_sci(s);
}
@ -116,15 +113,15 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
switch(addr) {
case 0x00:
acpi_pm1_evt_write_sts(&s->pm1a, &s->tmr, val);
acpi_pm1_evt_write_sts(&s->ar, val);
pm_update_sci(s);
break;
case 0x02:
s->pm1a.en = val;
s->ar.pm1.evt.en = val;
pm_update_sci(s);
break;
case 0x04:
acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val);
acpi_pm1_cnt_write(&s->ar, val);
break;
default:
break;
@ -141,16 +138,16 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
switch(addr) {
case 0x00:
val = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
val = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
break;
case 0x02:
val = s->pm1a.en;
val = s->ar.pm1.evt.en;
break;
case 0x04:
val = s->pm1_cnt.cnt;
val = s->ar.pm1.cnt.cnt;
break;
case 0x08:
val = acpi_pm_tmr_get(&s->tmr);
val = acpi_pm_tmr_get(&s->ar);
break;
default:
val = 0;
@ -170,7 +167,7 @@ static void apm_ctrl_changed(uint32_t val, void *arg)
PIIX4PMState *s = arg;
/* ACPI specs 3.0, 4.7.2.5 */
acpi_pm1_cnt_update(&s->pm1_cnt, val == ACPI_ENABLE, val == ACPI_DISABLE);
acpi_pm1_cnt_update(&s->ar, val == ACPI_ENABLE, val == ACPI_DISABLE);
if (s->dev.config[0x5b] & (1 << 1)) {
if (s->smi_irq) {
@ -258,13 +255,13 @@ static const VMStateDescription vmstate_acpi = {
.post_load = vmstate_acpi_post_load,
.fields = (VMStateField []) {
VMSTATE_PCI_DEVICE(dev, PIIX4PMState),
VMSTATE_UINT16(pm1a.sts, PIIX4PMState),
VMSTATE_UINT16(pm1a.en, PIIX4PMState),
VMSTATE_UINT16(pm1_cnt.cnt, PIIX4PMState),
VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState),
VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState),
VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
VMSTATE_TIMER(tmr.timer, PIIX4PMState),
VMSTATE_INT64(tmr.overflow_time, PIIX4PMState),
VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState),
VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status,
struct pci_status),
VMSTATE_END_OF_LIST()
@ -310,10 +307,9 @@ static void piix4_reset(void *opaque)
static void piix4_powerdown(void *opaque, int irq, int power_failing)
{
PIIX4PMState *s = opaque;
ACPIPM1EVT *pm1a = s? &s->pm1a: NULL;
ACPIPMTimer *tmr = s? &s->tmr: NULL;
acpi_pm1_evt_power_down(pm1a, tmr);
assert(s != NULL);
acpi_pm1_evt_power_down(&s->ar);
}
static void piix4_pm_machine_ready(Notifier *n, void *opaque)
@ -361,8 +357,8 @@ static int piix4_pm_initfn(PCIDevice *dev)
register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb);
register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb);
acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
acpi_gpe_init(&s->gpe, GPE_LEN);
acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
acpi_gpe_init(&s->ar, GPE_LEN);
qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
@ -387,7 +383,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
s = DO_UPCAST(PIIX4PMState, dev, dev);
s->irq = sci_irq;
acpi_pm1_cnt_init(&s->pm1_cnt, cmos_s3);
acpi_pm1_cnt_init(&s->ar, cmos_s3);
s->smi_irq = smi_irq;
s->kvm_enabled = kvm_enabled;
@ -436,7 +432,7 @@ type_init(piix4_pm_register_types)
static uint32_t gpe_readb(void *opaque, uint32_t addr)
{
PIIX4PMState *s = opaque;
uint32_t val = acpi_gpe_ioport_readb(&s->gpe, addr);
uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr);
PIIX4_DPRINTF("gpe read %x == %x\n", addr, val);
return val;
@ -446,7 +442,7 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
{
PIIX4PMState *s = opaque;
acpi_gpe_ioport_writeb(&s->gpe, addr, val);
acpi_gpe_ioport_writeb(&s->ar, addr, val);
pm_update_sci(s);
PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
@ -531,7 +527,7 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
register_ioport_read(GPE_BASE, GPE_LEN, 1, gpe_readb, s);
acpi_gpe_blk(&s->gpe, GPE_BASE);
acpi_gpe_blk(&s->ar, GPE_BASE);
register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status);
@ -547,13 +543,13 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
static void enable_device(PIIX4PMState *s, int slot)
{
s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
s->pci0_status.up |= (1 << slot);
}
static void disable_device(PIIX4PMState *s, int slot)
{
s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
s->pci0_status.down |= (1 << slot);
}

View File

@ -159,10 +159,8 @@ static void vt82c686b_write_config(PCIDevice * d, uint32_t address,
typedef struct VT686PMState {
PCIDevice dev;
ACPIPM1EVT pm1a;
ACPIPM1CNT pm1_cnt;
ACPIREGS ar;
APMState apm;
ACPIPMTimer tmr;
PMSMBus smb;
uint32_t smb_io_base;
} VT686PMState;
@ -179,21 +177,21 @@ static void pm_update_sci(VT686PMState *s)
{
int sci_level, pmsts;
pmsts = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
sci_level = (((pmsts & s->pm1a.en) &
pmsts = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
sci_level = (((pmsts & s->ar.pm1.evt.en) &
(ACPI_BITMASK_RT_CLOCK_ENABLE |
ACPI_BITMASK_POWER_BUTTON_ENABLE |
ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
ACPI_BITMASK_TIMER_ENABLE)) != 0);
qemu_set_irq(s->dev.irq[0], sci_level);
/* schedule a timer interruption if needed */
acpi_pm_tmr_update(&s->tmr, (s->pm1a.en & ACPI_BITMASK_TIMER_ENABLE) &&
acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
!(pmsts & ACPI_BITMASK_TIMER_STATUS));
}
static void pm_tmr_timer(ACPIPMTimer *tmr)
static void pm_tmr_timer(ACPIREGS *ar)
{
VT686PMState *s = container_of(tmr, VT686PMState, tmr);
VT686PMState *s = container_of(ar, VT686PMState, ar);
pm_update_sci(s);
}
@ -204,15 +202,15 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
addr &= 0x0f;
switch (addr) {
case 0x00:
acpi_pm1_evt_write_sts(&s->pm1a, &s->tmr, val);
acpi_pm1_evt_write_sts(&s->ar, val);
pm_update_sci(s);
break;
case 0x02:
s->pm1a.en = val;
s->ar.pm1.evt.en = val;
pm_update_sci(s);
break;
case 0x04:
acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val);
acpi_pm1_cnt_write(&s->ar, val);
break;
default:
break;
@ -228,13 +226,13 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
addr &= 0x0f;
switch (addr) {
case 0x00:
val = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
val = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
break;
case 0x02:
val = s->pm1a.en;
val = s->ar.pm1.evt.en;
break;
case 0x04:
val = s->pm1_cnt.cnt;
val = s->ar.pm1.cnt.cnt;
break;
default:
val = 0;
@ -258,7 +256,7 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
addr &= 0x0f;
switch (addr) {
case 0x08:
val = acpi_pm_tmr_get(&s->tmr);
val = acpi_pm_tmr_get(&s->ar);
break;
default:
val = 0;
@ -309,12 +307,12 @@ static const VMStateDescription vmstate_acpi = {
.post_load = vmstate_acpi_post_load,
.fields = (VMStateField []) {
VMSTATE_PCI_DEVICE(dev, VT686PMState),
VMSTATE_UINT16(pm1a.sts, VT686PMState),
VMSTATE_UINT16(pm1a.en, VT686PMState),
VMSTATE_UINT16(pm1_cnt.cnt, VT686PMState),
VMSTATE_UINT16(ar.pm1.evt.sts, VT686PMState),
VMSTATE_UINT16(ar.pm1.evt.en, VT686PMState),
VMSTATE_UINT16(ar.pm1.cnt.cnt, VT686PMState),
VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState),
VMSTATE_TIMER(tmr.timer, VT686PMState),
VMSTATE_INT64(tmr.overflow_time, VT686PMState),
VMSTATE_TIMER(ar.tmr.timer, VT686PMState),
VMSTATE_INT64(ar.tmr.overflow_time, VT686PMState),
VMSTATE_END_OF_LIST()
}
};
@ -431,8 +429,8 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
apm_init(&s->apm, NULL, s);
acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
acpi_pm1_cnt_init(&s->pm1_cnt, NULL);
acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
acpi_pm1_cnt_init(&s->ar, NULL);
pm_smbus_init(&s->dev.qdev, &s->smb);