* [PATCH] add acpi pmtimer support
@ 2012-08-13 13:04 Gerd Hoffmann
2012-08-13 22:31 ` [PATCH] add acpi pmtimer support\ Marcelo Tosatti
2012-08-13 22:47 ` [PATCH] add acpi pmtimer support Kevin O'Connor
0 siblings, 2 replies; 3+ messages in thread
From: Gerd Hoffmann @ 2012-08-13 13:04 UTC (permalink / raw)
To: seabios; +Cc: kvm, Gerd Hoffmann
This patch makes seabios use the acpi pmtimer instead of tsc for
timekeeping. The pmtimer has a fixed frequency and doesn't need
calibration, thus it doesn't suffer from calibration errors due to a
loaded host machine.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
src/clock.c | 29 +++++++++++++++++++++++++++++
src/pciinit.c | 5 +++++
src/util.h | 1 +
3 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/src/clock.c b/src/clock.c
index 69e9f17..59f269b 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -129,11 +129,40 @@ emulate_tsc(void)
return ret;
}
+u16 pmtimer_ioport VAR16VISIBLE;
+u32 pmtimer_wraps VARLOW;
+u32 pmtimer_last VARLOW;
+
+void pmtimer_init(u16 ioport, u32 khz)
+{
+ dprintf(1, "Using pmtimer, ioport 0x%x, freq %d kHz\n", ioport, khz);
+ SET_GLOBAL(pmtimer_ioport, ioport);
+ SET_GLOBAL(cpu_khz, khz);
+}
+
+static u64 pmtimer_get(void)
+{
+ u16 ioport = GET_GLOBAL(pmtimer_ioport);
+ u32 wraps = GET_LOW(pmtimer_wraps);
+ u32 pmtimer = inl(ioport);
+
+ if (pmtimer < GET_LOW(pmtimer_last)) {
+ wraps++;
+ SET_LOW(pmtimer_wraps, wraps);
+ }
+ SET_LOW(pmtimer_last, pmtimer);
+
+ dprintf(9, "pmtimer: %u:%u\n", wraps, pmtimer);
+ return (u64)wraps << 24 | pmtimer;
+}
+
static u64
get_tsc(void)
{
if (unlikely(GET_GLOBAL(no_tsc)))
return emulate_tsc();
+ if (GET_GLOBAL(pmtimer_ioport))
+ return pmtimer_get();
return rdtscll();
}
diff --git a/src/pciinit.c b/src/pciinit.c
index 68f302a..31115ee 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -180,6 +180,9 @@ static const struct pci_device_id pci_class_tbl[] = {
PCI_DEVICE_END,
};
+/* PM Timer ticks per second (HZ) */
+#define PM_TIMER_FREQUENCY 3579545
+
/* PIIX4 Power Management device (for ACPI) */
static void piix4_pm_init(struct pci_device *pci, void *arg)
{
@@ -191,6 +194,8 @@ static void piix4_pm_init(struct pci_device *pci, void *arg)
pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */
pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
+
+ pmtimer_init(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000);
}
static const struct pci_device_id pci_device_tbl[] = {
diff --git a/src/util.h b/src/util.h
index 89e928c..1603a57 100644
--- a/src/util.h
+++ b/src/util.h
@@ -312,6 +312,7 @@ void lpt_setup(void);
// clock.c
#define PIT_TICK_RATE 1193180 // Underlying HZ of PIT
#define PIT_TICK_INTERVAL 65536 // Default interval for 18.2Hz timer
+void pmtimer_init(u16 ioport, u32 khz);
int check_tsc(u64 end);
void timer_setup(void);
void ndelay(u32 count);
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] add acpi pmtimer support\
2012-08-13 13:04 [PATCH] add acpi pmtimer support Gerd Hoffmann
@ 2012-08-13 22:31 ` Marcelo Tosatti
2012-08-13 22:47 ` [PATCH] add acpi pmtimer support Kevin O'Connor
1 sibling, 0 replies; 3+ messages in thread
From: Marcelo Tosatti @ 2012-08-13 22:31 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: seabios, kvm
On Mon, Aug 13, 2012 at 03:04:10PM +0200, Gerd Hoffmann wrote:
> This patch makes seabios use the acpi pmtimer instead of tsc for
> timekeeping. The pmtimer has a fixed frequency and doesn't need
> calibration, thus it doesn't suffer from calibration errors due to a
> loaded host machine.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> src/clock.c | 29 +++++++++++++++++++++++++++++
> src/pciinit.c | 5 +++++
> src/util.h | 1 +
> 3 files changed, 35 insertions(+), 0 deletions(-)
>
> diff --git a/src/clock.c b/src/clock.c
> index 69e9f17..59f269b 100644
> --- a/src/clock.c
> +++ b/src/clock.c
> @@ -129,11 +129,40 @@ emulate_tsc(void)
> return ret;
> }
>
> +u16 pmtimer_ioport VAR16VISIBLE;
> +u32 pmtimer_wraps VARLOW;
> +u32 pmtimer_last VARLOW;
> +
> +void pmtimer_init(u16 ioport, u32 khz)
> +{
> + dprintf(1, "Using pmtimer, ioport 0x%x, freq %d kHz\n", ioport, khz);
> + SET_GLOBAL(pmtimer_ioport, ioport);
> + SET_GLOBAL(cpu_khz, khz);
> +}
> +
> +static u64 pmtimer_get(void)
> +{
> + u16 ioport = GET_GLOBAL(pmtimer_ioport);
> + u32 wraps = GET_LOW(pmtimer_wraps);
> + u32 pmtimer = inl(ioport);
> +
> + if (pmtimer < GET_LOW(pmtimer_last)) {
> + wraps++;
> + SET_LOW(pmtimer_wraps, wraps);
> + }
> + SET_LOW(pmtimer_last, pmtimer);
> +
> + dprintf(9, "pmtimer: %u:%u\n", wraps, pmtimer);
> + return (u64)wraps << 24 | pmtimer;
> +}
> +
> static u64
> get_tsc(void)
> {
> if (unlikely(GET_GLOBAL(no_tsc)))
> return emulate_tsc();
> + if (GET_GLOBAL(pmtimer_ioport))
> + return pmtimer_get();
> return rdtscll();
> }
>
> diff --git a/src/pciinit.c b/src/pciinit.c
> index 68f302a..31115ee 100644
> --- a/src/pciinit.c
> +++ b/src/pciinit.c
> @@ -180,6 +180,9 @@ static const struct pci_device_id pci_class_tbl[] = {
> PCI_DEVICE_END,
> };
>
> +/* PM Timer ticks per second (HZ) */
> +#define PM_TIMER_FREQUENCY 3579545
> +
> /* PIIX4 Power Management device (for ACPI) */
> static void piix4_pm_init(struct pci_device *pci, void *arg)
> {
> @@ -191,6 +194,8 @@ static void piix4_pm_init(struct pci_device *pci, void *arg)
> pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */
> pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
> pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
> +
> + pmtimer_init(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000);
> }
>
> static const struct pci_device_id pci_device_tbl[] = {
> diff --git a/src/util.h b/src/util.h
> index 89e928c..1603a57 100644
> --- a/src/util.h
> +++ b/src/util.h
> @@ -312,6 +312,7 @@ void lpt_setup(void);
> // clock.c
> #define PIT_TICK_RATE 1193180 // Underlying HZ of PIT
> #define PIT_TICK_INTERVAL 65536 // Default interval for 18.2Hz timer
> +void pmtimer_init(u16 ioport, u32 khz);
> int check_tsc(u64 end);
> void timer_setup(void);
> void ndelay(u32 count);
Looks good.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] add acpi pmtimer support
2012-08-13 13:04 [PATCH] add acpi pmtimer support Gerd Hoffmann
2012-08-13 22:31 ` [PATCH] add acpi pmtimer support\ Marcelo Tosatti
@ 2012-08-13 22:47 ` Kevin O'Connor
1 sibling, 0 replies; 3+ messages in thread
From: Kevin O'Connor @ 2012-08-13 22:47 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: seabios, kvm
On Mon, Aug 13, 2012 at 03:04:10PM +0200, Gerd Hoffmann wrote:
> This patch makes seabios use the acpi pmtimer instead of tsc for
> timekeeping. The pmtimer has a fixed frequency and doesn't need
> calibration, thus it doesn't suffer from calibration errors due to a
> loaded host machine.
It looks okay to me. It'd be nice to have a CONFIG_PMTIMER for it,
but it can be added on top.
-Kevin
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-08-13 22:47 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-13 13:04 [PATCH] add acpi pmtimer support Gerd Hoffmann
2012-08-13 22:31 ` [PATCH] add acpi pmtimer support\ Marcelo Tosatti
2012-08-13 22:47 ` [PATCH] add acpi pmtimer support Kevin O'Connor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).