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:
parent
067866d61c
commit
355bf2e5ba
130
hw/acpi.c
130
hw/acpi.c
@ -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;
|
||||
|
48
hw/acpi.h
48
hw/acpi.h
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user