1 /* $NetBSD: acpi_timer.c,v 1.13 2009/03/15 15:42:55 cegger Exp $ */
4 __KERNEL_RCSID(0, "$NetBSD: acpi_timer.c,v 1.13 2009/03/15 15:42:55 cegger Exp $");
9 #include <sys/timetc.h>
10 #include <dev/acpi/acpica.h>
11 #include <dev/acpi/acpi_timer.h>
12 #include <machine/acpi_machdep.h>
14 static int acpitimer_test(void);
15 static uint32_t acpitimer_delta(uint32_t, uint32_t);
16 static u_int
acpitimer_read_safe(struct timecounter
*);
17 static u_int
acpitimer_read_fast(struct timecounter
*);
19 static struct timecounter acpi_timecounter
= {
37 res
= AcpiGetTimerResolution(&bits
);
42 acpi_timecounter
.tc_counter_mask
= 0xffffffff;
45 for (i
= 0; i
< 10; i
++)
46 j
+= acpitimer_test();
49 acpi_timecounter
.tc_name
= "ACPI-Fast";
50 acpi_timecounter
.tc_get_timecount
= acpitimer_read_fast
;
51 acpi_timecounter
.tc_quality
= 1000;
54 tc_init(&acpi_timecounter
);
55 aprint_verbose("%s %d-bit timer\n", acpi_timecounter
.tc_name
, bits
);
61 acpitimer_detach(void)
63 return tc_detach(&acpi_timecounter
);
67 acpitimer_read_fast(struct timecounter
*tc
)
76 * Some chipsets (PIIX4 variants) do not latch correctly; there
77 * is a chance that a transition is hit.
80 acpitimer_read_safe(struct timecounter
*tc
)
90 } while ((t1
> t2
) || (t2
> t3
));
95 acpitimer_delta(uint32_t end
, uint32_t start
)
98 u_int mask
= acpi_timecounter
.tc_counter_mask
;
103 delta
= ((mask
- start
) + end
+ 1) & mask
;
112 uint32_t last
, this, delta
;
118 acpi_md_OsDisableInterrupt();
120 for (n
= 0; n
< N
; n
++) {
122 delta
= acpitimer_delta(this, last
);
125 else if (delta
< minl
)
129 acpi_md_OsEnableInterrupt();
131 if (maxl
- minl
> 2 )
133 else if (minl
< 0 || maxl
== 0)