acpi_timer.c revision 1.1 1 1.1 drochner /* $NetBSD: acpi_timer.c,v 1.1 2006/06/21 17:47:23 drochner Exp $ */
2 1.1 drochner
3 1.1 drochner #include <sys/types.h>
4 1.1 drochner
5 1.1 drochner #ifdef __HAVE_TIMECOUNTER
6 1.1 drochner
7 1.1 drochner #include <sys/systm.h>
8 1.1 drochner #include <sys/time.h>
9 1.1 drochner #include <sys/timetc.h>
10 1.1 drochner #include <dev/acpi/acpica.h>
11 1.1 drochner #include <dev/acpi/acpi_timer.h>
12 1.1 drochner
13 1.1 drochner static u_int acpitimer_read(struct timecounter *);
14 1.1 drochner
15 1.1 drochner static struct timecounter acpi_timecounter = {
16 1.1 drochner acpitimer_read,
17 1.1 drochner 0,
18 1.1 drochner 0x00ffffff,
19 1.1 drochner PM_TIMER_FREQUENCY,
20 1.1 drochner "ACPI_PM_TMR",
21 1.1 drochner 900
22 1.1 drochner };
23 1.1 drochner
24 1.1 drochner int
25 1.1 drochner acpitimer_init()
26 1.1 drochner {
27 1.1 drochner uint32_t bits;
28 1.1 drochner ACPI_STATUS res;
29 1.1 drochner
30 1.1 drochner res = AcpiGetTimerResolution(&bits);
31 1.1 drochner if (res != AE_OK)
32 1.1 drochner return (-1);
33 1.1 drochner
34 1.1 drochner if (bits == 32)
35 1.1 drochner acpi_timecounter.tc_counter_mask = 0xffffffff;
36 1.1 drochner tc_init(&acpi_timecounter);
37 1.1 drochner
38 1.1 drochner printf("acpitimer: %d bits\n", bits);
39 1.1 drochner
40 1.1 drochner return (0);
41 1.1 drochner }
42 1.1 drochner
43 1.1 drochner /*
44 1.1 drochner * Some chipsets (PIIX4 variants) do not latch correctly; there
45 1.1 drochner * is a chance that a transition is hit.
46 1.1 drochner * For now, just be conservative. We might detect the situation later
47 1.1 drochner * (by testing, or chipset quirks).
48 1.1 drochner */
49 1.1 drochner static u_int
50 1.1 drochner acpitimer_read(struct timecounter *tc)
51 1.1 drochner {
52 1.1 drochner uint32_t t1, t2, t3;
53 1.1 drochner
54 1.1 drochner AcpiGetTimer(&t2);
55 1.1 drochner AcpiGetTimer(&t3);
56 1.1 drochner do {
57 1.1 drochner t1 = t2;
58 1.1 drochner t2 = t3;
59 1.1 drochner AcpiGetTimer(&t3);
60 1.1 drochner } while ((t1 > t2) || (t2 > t3));
61 1.1 drochner return (t2);
62 1.1 drochner }
63 1.1 drochner
64 1.1 drochner #else
65 1.1 drochner
66 1.1 drochner int
67 1.1 drochner acpitimer_init()
68 1.1 drochner {
69 1.1 drochner
70 1.1 drochner return (0);
71 1.1 drochner }
72 1.1 drochner
73 1.1 drochner #endif
74