[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 21/26] acpi, acpi_piix: factor out PM_TMR logic
From: |
Isaku Yamahata |
Subject: |
[Qemu-devel] [PATCH 21/26] acpi, acpi_piix: factor out PM_TMR logic |
Date: |
Wed, 16 Mar 2011 18:29:32 +0900 |
factor out PM_TMR logic. Later This will be used by ich9 acpi.
Signed-off-by: Isaku Yamahata <address@hidden>
---
hw/acpi.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
hw/acpi.h | 24 ++++++++++++++++++++++++
hw/acpi_piix4.c | 45 ++++++++++++---------------------------------
3 files changed, 81 insertions(+), 33 deletions(-)
diff --git a/hw/acpi.c b/hw/acpi.c
index e9bcf18..bd987e0 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -217,3 +217,48 @@ out:
}
return -1;
}
+
+/* ACPI PM_TMR */
+void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable)
+{
+ int64_t expire_time;
+
+ /* schedule a timer interruption if needed */
+ if (enable) {
+ expire_time = muldiv64(tmr->overflow_time, get_ticks_per_sec(),
+ PM_TIMER_FREQUENCY);
+ qemu_mod_timer(tmr->timer, expire_time);
+ } else {
+ qemu_del_timer(tmr->timer);
+ }
+}
+
+void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr)
+{
+ int64_t d = acpi_pm_tmr_get_clock();
+ tmr->overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
+}
+
+uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr)
+{
+ uint32_t d = acpi_pm_tmr_get_clock();;
+ return d & 0xffffff;
+}
+
+static void acpi_pm_tmr_timer(void *opaque)
+{
+ ACPIPMTimer *tmr = opaque;
+ tmr->update_sci(tmr);
+}
+
+void acpi_pm_tmr_init(ACPIPMTimer *tmr, acpi_update_sci_fn update_sci)
+{
+ tmr->update_sci = update_sci;
+ tmr->timer = qemu_new_timer(vm_clock, acpi_pm_tmr_timer, tmr);
+}
+
+void acpi_pm_tmr_reset(ACPIPMTimer *tmr)
+{
+ tmr->overflow_time = 0;
+ qemu_del_timer(tmr->timer);
+}
diff --git a/hw/acpi.h b/hw/acpi.h
index 5949958..1f9132f 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -74,5 +74,29 @@
#define ACPI_BITMASK_ARB_DISABLE 0x0001
/* PM_TMR */
+struct ACPIPMTimer;
+typedef struct ACPIPMTimer ACPIPMTimer;
+
+typedef void (*acpi_update_sci_fn)(ACPIPMTimer *tmr);
+
+struct ACPIPMTimer {
+ QEMUTimer *timer;
+ int64_t overflow_time;
+
+ acpi_update_sci_fn update_sci;
+};
+
+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);
+
+#include "qemu-timer.h"
+static inline int64_t acpi_pm_tmr_get_clock(void)
+{
+ return muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
+ get_ticks_per_sec());
+}
#endif /* !QEMU_HW_ACPI_H */
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 5bbc2b5..d5f631a 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -60,8 +60,7 @@ typedef struct PIIX4PMState {
APMState apm;
- QEMUTimer *tmr_timer;
- int64_t tmr_overflow_time;
+ ACPIPMTimer tmr;
PMSMBus smb;
uint32_t smb_io_base;
@@ -82,20 +81,10 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus,
PIIX4PMState *s);
#define ACPI_ENABLE 0xf1
#define ACPI_DISABLE 0xf0
-static uint32_t get_pmtmr(PIIX4PMState *s)
-{
- uint32_t d;
- d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
get_ticks_per_sec());
- return d & 0xffffff;
-}
-
static int get_pmsts(PIIX4PMState *s)
{
- int64_t d;
-
- d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
- get_ticks_per_sec());
- if (d >= s->tmr_overflow_time)
+ int64_t d = acpi_pm_tmr_get_clock();
+ if (d >= s->tmr.overflow_time)
s->pmsts |= ACPI_BITMASK_TIMER_STATUS;
return s->pmsts;
}
@@ -103,7 +92,6 @@ static int get_pmsts(PIIX4PMState *s)
static void pm_update_sci(PIIX4PMState *s)
{
int sci_level, pmsts;
- int64_t expire_time;
pmsts = get_pmsts(s);
sci_level = (((pmsts & s->pmen) &
@@ -115,19 +103,13 @@ static void pm_update_sci(PIIX4PMState *s)
qemu_set_irq(s->irq, sci_level);
/* schedule a timer interruption if needed */
- if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
- !(pmsts & ACPI_BITMASK_TIMER_STATUS)) {
- expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(),
- PM_TIMER_FREQUENCY);
- qemu_mod_timer(s->tmr_timer, expire_time);
- } else {
- qemu_del_timer(s->tmr_timer);
- }
+ acpi_pm_tmr_update(&s->tmr, (s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
+ !(pmsts & ACPI_BITMASK_TIMER_STATUS));
}
-static void pm_tmr_timer(void *opaque)
+static void pm_tmr_timer(ACPIPMTimer *tmr)
{
- PIIX4PMState *s = opaque;
+ PIIX4PMState *s = container_of(tmr, PIIX4PMState, tmr);
pm_update_sci(s);
}
@@ -144,14 +126,11 @@ static void pm_ioport_write(IORange *ioport, uint64_t
addr, unsigned width,
switch(addr) {
case 0x00:
{
- int64_t d;
int pmsts;
pmsts = get_pmsts(s);
if (pmsts & val & ACPI_BITMASK_TIMER_STATUS) {
/* if TMRSTS is reset, then compute the new overflow time */
- d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
- get_ticks_per_sec());
- s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
+ acpi_pm_tmr_calc_overflow_time(&s->tmr);
}
s->pmsts &= ~val;
pm_update_sci(s);
@@ -210,7 +189,7 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr,
unsigned width,
val = s->pmcntrl;
break;
case 0x08:
- val = get_pmtmr(s);
+ val = acpi_pm_tmr_get(&s->tmr);
break;
default:
val = 0;
@@ -315,8 +294,8 @@ static const VMStateDescription vmstate_acpi = {
VMSTATE_UINT16(pmen, PIIX4PMState),
VMSTATE_UINT16(pmcntrl, PIIX4PMState),
VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
- VMSTATE_TIMER(tmr_timer, PIIX4PMState),
- VMSTATE_INT64(tmr_overflow_time, PIIX4PMState),
+ VMSTATE_TIMER(tmr.timer, PIIX4PMState),
+ VMSTATE_INT64(tmr.overflow_time, PIIX4PMState),
VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, struct gpe_regs),
VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status,
struct pci_status),
@@ -413,7 +392,7 @@ 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);
- s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
+ acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
--
1.7.1.1
- [Qemu-devel] [PATCH 16/26] pc, pc_piix: split out allocating isa irqs, (continued)
- [Qemu-devel] [PATCH 16/26] pc, pc_piix: split out allocating isa irqs, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 14/26] ide: consolidate drive_get(IF_IDE), Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 11/26] ahci: add ide device initialization helper, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 18/26] ioapic: move ioapic_init() from pc_piix.c to pc.c, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 02/26] pci: add opaque argument to pci_map_irq_fn, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 03/26] pci: introduce pci_swizzle_map_irq_fn() for standardized interrupt pin swizzle, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 20/26] pc, i440fx: simply i440fx initialization, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 21/26] acpi, acpi_piix: factor out PM_TMR logic,
Isaku Yamahata <=
- [Qemu-devel] [PATCH 24/26] acpi, acpi_piix: factor out GPE logic, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 09/26] dec_pci: simplify dec_pci.c by using pci_p2pbr, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 22/26] acpi, acpi_piix: factor out PM1a EVT logic, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 08/26] apb_pci: simplify apb_pci.c by using pci_p2pbr, Isaku Yamahata, 2011/03/16
- [Qemu-devel] [PATCH 04/26] pci: add accessor function to get irq levels, Isaku Yamahata, 2011/03/16